commit e763638f91c3a9c4a9d346ea01f0d67d64a714da Author: CentOS Sources Date: Tue Mar 28 09:00:57 2023 +0000 import glibc-2.34-60.el9 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..930f2f5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/glibc-2.34.tar.xz diff --git a/.glibc.metadata b/.glibc.metadata new file mode 100644 index 0000000..8570979 --- /dev/null +++ b/.glibc.metadata @@ -0,0 +1 @@ +7c3b8890a6346793b6334cc5f2fea5d437d307b8 SOURCES/glibc-2.34.tar.xz diff --git a/SOURCES/ChangeLog.old b/SOURCES/ChangeLog.old new file mode 100644 index 0000000..a0b9a7f --- /dev/null +++ b/SOURCES/ChangeLog.old @@ -0,0 +1,10288 @@ +* Fri Jul 30 2021 Siddhesh Poyarekar - 2.33.9000-56 +- Port post scripts for gconv-extra to lua and drop dependency across + architectures for x86 multilib (#1988344). + +* Thu Jul 29 2021 Florian Weimer - 2.33.9000-55 +- Auto-sync with upstream branch master, + commit c37fc3ebf0607ce1953c565ffe56d56555eeb25e: +- Update libc.pot for 2.34 release. +- x86-64: Add Avoid_Short_Distance_REP_MOVSB +- Typo: Rename HAVE_CLONE3_WAPPER to HAVE_CLONE3_WRAPPER +- build-many-glibcs.py: Add x86_64-linux-gnu-minimal configuration +- tests: use xmalloc to allocate implementation array +- xmalloc: Fix warnings with gcc analyzer +- __cxa_thread_atexit_impl: Abort on allocation failure [BZ #18524] +- manual: Drop the .so suffix in libc_malloc_debug description +- hurd: _Fork: unlock malloc before calling fork child hooks + +* Tue Jul 27 2021 Florian Weimer - 2.33.9000-54 +- Revert to old C.UTF-8 locale + +* Mon Jul 26 2021 Siddhesh Poyarekar - 2.33.9000-53 +- Loosen dependency on glibc-gconv-extra (#1812191). + +* Mon Jul 26 2021 Florian Weimer - 2.33.9000-52 +- Switch to new version of C.UTF-8 locale + +* Mon Jul 26 2021 Florian Weimer - 2.33.9000-51 +- Auto-sync with upstream branch master, + commit ddcc612ce923038b867083a0c55d6e034951155a: +- Exclude static tests for mcheck and malloc-check +- i386: Regenerate ulps + +* Sat Jul 24 2021 Florian Weimer - 2.33.9000-50 +- Auto-sync with upstream branch master, + commit d34ed66f96fa9316654d7adb2afcce4be1d1c4f5: +- manual: Document unsupported cases for interposition +- x86: Install [BZ #27958] +- Fix build and tests with --disable-tunables + +* Sat Jul 24 2021 Florian Weimer - 2.33.9000-49 +- Remove both old and new library names in glibc-hwcaps removal (#1983677) + +* Fri Jul 23 2021 Florian Weimer - 2.33.9000-48 +- Auto-sync with upstream branch master, + commit 9a7ab0769b295cbf5232140401742a8f34bda3de: +- hurd: Fix glob lstat compatibility +- socket: Add time64 alias for setsockopt +- socket: Add time64 alias for getsockopt +- mcheck Fix malloc_usable_size [BZ #22057] +- Remove malloc hooks [BZ #23328] +- Move malloc_{g,s}et_state to libc_malloc_debug +- glibc.malloc.check: Wean away from malloc hooks +- mtrace: Wean away from malloc hooks +- Simplify __malloc_initialized +- mcheck: Wean away from malloc hooks [BZ #23489] +- Move malloc hooks into a compat DSO +- Remove __morecore and __default_morecore +- Remove __after_morecore_hook +- Make mcheck tests conditional on GLIBC_2.23 or earlier +- posix: Add sysconf(_SC_{MIN,}SIGSTKSZ) support +- malloc: Fix tst-mallocfork3-malloc-check link +- ARC: elf: make type safe +- ARC: fp: (micro)optimize FPU_STATUS read by eliding FWE bit clearing + +* Thu Jul 22 2021 Fedora Release Engineering - 2.33.9000-47 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Wed Jul 21 2021 Florian Weimer - 2.33.9000-46 +- Auto-sync with upstream branch master, + commit 77ede5f010f1b144e067ec035e422a13bb57c55d: +- socket: Add time64 alias for sendmsg +- socket: Add time64 alias for recvmsg +- socket: Add time64 alias for sendmmsg +- Linux: Add time64 alias for prctl +- io: Add time64 alias for fcntl +- misc: Add time64 alias for ioctl +- RISC-V: Update rv64 ULPs +- resolv: Do not install libnss_dns.a, libnss_dns.so +- hurd: Add support for spawn_do_closefrom +- elf: Fix tst-cpu-features-cpuinfo on some AMD systems (BZ #28090) +- i386: Add the clone3 wrapper + +* Mon Jul 19 2021 Florian Weimer - 2.33.9000-45 +- Remove glibc-hwcaps multilibs on upgrade (#1983677) + +* Mon Jul 19 2021 Florian Weimer - 2.33.9000-44 +- Auto-sync with upstream branch master, + commit ee5ed99922ca90bcea4a2f9a48a0c9ae4b534ece: +- nss: Directly load nss_dns, without going through dlsym/dlopen +- resolv: Move nss_dns into libc +- resolv: Move res_query functions into libc +- resolv: Move res_mkquery, res_nmkquery into libc +- resolv: Move res_send, res_nsend into libc +- resolv: Move res_hostalias into its own file, along with hostalias +- resolv: Move __res_context_hostalias into its own file and into libc +- resolv: Move res_queriesmatch to its own file and into libc +- resolv: Move res_nameinquery to its own file and into libc +- resolv: Move ns_samename into its own file, and into libc +- resolv: Move ns_makecanon into its own file, and into libc +- resolv: Move res_isourserver to its own file and reformat to GNU style +- resolv: Move __res_get_nsaddr to its own file and into libc +- resolv: Rename res_comp.c to res-name-checking.c and move into libc +- resolv: Move dn_skipname to its own file and into libc +- resolv: Move dn_comp to its own file and into libc +- resolv: Move _getlong, _getshort, __putlong, __putshort to res-putget +- resolv: Move dn_expand to its own file and into libc +- resolv: Move ns_name_compress into its own file and into libc +- resolv: Move ns_name_pack into its own file and into libc +- resolv: Move ns_name_pton into its own file and into libc +- resolv: Move ns_name_uncompress into its own file and into libc +- resolv: Move ns_name_skip to its own file and into libc (bug 28091) +- resolv: Deprecate legacy interfaces in libresolv +- tst-safe-linking: make false positives even more improbable +- htl: Do not expose pthread hidden proto outside libpthread +- elf: Fix a wrong array access on tst-tls20 +- elf: Add -Wl,--no-as-needed for tst-tls-manydynamic*mod-dep-bad.so (BZ #28089) +- resolv: Move ns_name_unpack to its own file and into libc +- resolv: Remove unnecessary res_isourserver_p call from send_dg +- resolv: Move ns_name_ntop to its own file and into libc +- nss_dns: Do not use deprecated packet parsing functions +- resolv: Sort Makefile routines and Versions lexicographically +- socket: Add hidden prototype for setsockopt +- elf: Fix DTV gap reuse logic (BZ #27135) +- Fix linknamespace errors and local-plt-usages in nss_files. +- Add static tests for __clone_internal +- x86-64: Add the clone3 wrapper +- Add an internal wrapper for clone, clone2 and clone3 +- nss: Fix build error with --disable-nscd +- htl: Fix linking static examples against libpthread +- htl: Let libc call __pthread_mutex_{,try,un}lock +- posix: Ignore non opened files on tst-spawn5 +- mcheck: Align struct hdr to MALLOC_ALIGNMENT bytes [BZ #28068] + +* Thu Jul 15 2021 Siddhesh Poyarekar - 2.33.9000-43 +- Run postun only if the main gconv-modules configuration file exists. + (#1981013) +- Own %{libdir}/gconv/gconv-modules.d +- Rearrange file list command so that gconv-modules.cache is no longer + marked as %config + +* Tue Jul 13 2021 Florian Weimer - 2.33.9000-42 +- Perform systemd re-exec even if glibc.i686 is installed + +* Tue Jul 13 2021 Florian Weimer - 2.33.9000-41 +- Re-exec systemd on upgrades + +* Mon Jul 12 2021 Florian Weimer - 2.33.9000-40 +- Merge files NSS service module into libc. +- Restore vDSO acceleration for time functions on older kernels for i686. +- Auto-sync with upstream branch master, + commit 72e84d1db22203e01a43268de71ea8669eca2863: +- Linux: Use 32-bit vDSO for clock_gettime, gettimeofday, time (BZ# 28071) +- Reduce pollution due to dynamic PTHREAD_STACK_MIN +- Fix failing nss/tst-nss-files-hosts-long. +- nis: nis_local_group may read from __nisgroup[-1] (bug 28075) +- hurd _Fork: Drop duplicate malloc_fork_lock calls +- support: Replace _SC_MINSIGSTKSZ with _SC_SIGSTKSZ +- support: Replace MINSIGSTKSZ with sysconf (_SC_MINSIGSTKSZ) +- Define PTHREAD_STACK_MIN to sysconf(_SC_THREAD_STACK_MIN) +- Force building with -fno-common +- Add a generic malloc test for MALLOC_ALIGNMENT +- Properly run tst-spawn5 directly [BZ #28067] +- build-many-glibcs.py: Add glibcs-arm-linux-gnueabihf-thumb +- nptl: Use out-of-line wake function in __libc_lock_unlock slow path +- powerpc64le: Fix typo in configure +- powerpc64: Remove strcspn ifunc from the loader +- x86: Remove wcsnlen-sse4_1 from wcslen ifunc-impl-list [BZ #28064] +- x86-64: Test strlen and wcslen with 0 in the RSI register [BZ #28064] +- x86_64: Remove unneeded static PIE check for undefined weak diagnostic +- Add NT_ARM_PAC_ENABLED_KEYS to elf.h +- posix: Add posix_spawn_file_actions_addclosefrom_np +- io: Add closefrom [BZ #10353] +- linux: Add close_range +- support: Add support_stack_alloc +- _int_realloc is static +- Move mcheck symbol from stdlib to malloc +- nss: Do not install static linker input files for libnss_files +- elf/tests: Make thrlock and noload depend on libm +- Harden tcache double-free check +- nss: Access nss_files through direct references +- nss_files: Move into libc +- nss_files: Add generic code for set*ent, end*ent and file open +- nss_files: Allocate nscd file registration data on the heap +- libio: Replace internal _IO_getdelim symbol with __getdelim +- libio: Add hidden prototype for ungetc +- inet: Add hidden prototype for __inet_network +- Update MIPS libm-test-ulps +- Update powerpc-nofpu libm-test-ulps +- soft-fp: Add __extendhfsf2/__extendhfdf2, __truncsfhf2/__truncdfhf2, + __eqhf2/__nehf2 +- Update kernel version to 5.13 in tst-mman-consts.py +- tests-exclude-mcheck: Fix typo + +* Wed Jul 07 2021 Florian Weimer - 2.33.9000-39 +- Auto-sync with upstream branch master, + commit 7a5db2e82fbb6c3a6e3fdae02b7166c5d0e8c7a8: +- elf: Clean up GLIBC_PRIVATE exports of internal libdl symbols +- nptl: Reduce the GLIBC_PRIVATE ABI +- nptl: Remove GLIBC_2.34 versions of __pthread_mutex_lock, + __pthread_mutex_unlock +- nptl: Use internal low-level lock type for !IS_IN (libc) +- glibc.malloc.check: Fix nit in documentation +- Exclude tst-realloc from tests-mcheck +- linux: Fix setsockopt fallback +- linux: Use the expected size for SO_TIMESTAMP{NS} convertion +- linux: Consolidate Linux setsockopt implementation +- linux: Consolidate Linux getsockopt implementation +- manual: fix description for preadv() + +* Tue Jul 06 2021 Florian Weimer - 2.33.9000-38 +- Auto-sync with upstream branch master, + commit 832f50be6c9c010e46180d14126bbb81f35e808c: +- linux: Check for null value msghdr struct before use +- elf: Call free from base namespace on error in dl-libc.c [BZ #27646] + +* Mon Jul 05 2021 Florian Weimer - 2.33.9000-37 +- Move libanl.a into glibc-devel. +- Auto-sync with upstream branch master, + commit 91fb0f17a5779da6e7877eb74119a83dbe8bf167: +- hooks.c: Remove incorrect comment +- mtrace: Add attribute nocommon to mallwatch +- Move glibc.malloc.check implementation into its own file +- mtrace: Deprecate mallwatch and tr_break +- Drop source dependencies on hooks.c and arena.c +- malloc: Initiate tcache shutdown even without allocations [BZ #28028] +- Add mcheck tests to malloc +- iconvconfig: Use the public feof_unlocked +- resolv: Move libanl into libc (if libpthread is in libc) +- powerpc: optimize strcpy/stpcpy for POWER9/10 +- soft-fp: Add __extendhfxf2 and __truncxfhf2 +- x86: Check RTM_ALWAYS_ABORT for RTM [BZ #28033] +- Update syscall lists for Linux 5.13 +- s390: Fix MEMCHR_Z900_G5 ifunc-variant if n>=0x80000000 [BZ #28024] +- Fix extra PLT reference in libc.so due to __glob64_time64 if build with gcc 7.5 on 32bit. +- AArch64: Add hp-timing.h +- AArch64: Improve strnlen performance + +* Wed Jun 30 2021 Florian Weimer - 2.33.9000-36 +- Auto-sync with upstream branch master, + commit eb68d7d23cc411acdf68a60f194343a6774d6194: +- Linux: Avoid calling malloc indirectly from __get_nprocs (#1975693) +- Use Linux 5.13 in build-many-glibcs.py + +* Wed Jun 30 2021 Florian Weimer - 2.33.9000-35 +- Drop glibc-s390x-roundeven.patch, applied upstream. +- Move libutil.a into glibc-devel. +- Auto-sync with upstream branch master, + commit 734c60ebb607086ad6d67b2544d6b7baba72a652: +- login: Move libutil into libc +- login: Rework hidden prototypes for __setutent, __utmpname, __endutent +- login: Hidden prototypes for _getpt, __ptsname_r, grantpt, unlockpt +- nptl_db: Re-use the ELF-to-abilist converter for ABI checking +- Add RFC 8335 Definitions from Linux 5.13 +- nss: Fix NSS_DECLARE_MODULE_FUNCTIONS handling of _nss_*_endnetgrent +- s390x: Update math: redirect roundeven function +- posix: Add _Fork [BZ #4737] + +* Mon Jun 28 2021 Florian Weimer - 2.33.9000-34 +- Move librt.a to glibc-devel (#1977058) + +* Mon Jun 28 2021 Florian Weimer - 2.33.9000-33 +- Dropped patches glibc-nosymlink-*.patch, glibc-iconvconfig-corruption.patch, + glibc-libthread_db-dynsym-*.patch; applied upstream. +- Auto-sync with upstream branch master, + commit dd45734e322a03287d34d8af9b7da7b35cfddb8e: +- nptl: Add glibc.pthread.stack_cache_size tunable +- nptl: Export libthread_db-used symbols under GLIBC_PRIVATE +- nptl: Rename nptl_version to __nptl_version +- nptl_db: Clean up main/rtld variable handling +- arm: align stack in clone [BZ 28020] +- Linux: Cleanups after librt move +- Linux: Move timer_settime, __timer_settime64 from librt to libc +- Linux: Move timer_gettime, __timer_gettime64 from librt to libc +- Linux: Move timer_getoverrun from librt to libc +- Linux: Move timer_create, timer_delete from librt to libc +- Linux: Define TIMER_T_WAS_INT_COMPAT in kernel-posix-timers.h +- Install shared objects under their ABI names +- elf: Generalize name-based DSO recognition in ldconfig +- Makerules: Remove lib-version, $(subdir-version) +- nptl_db: Install libthread_db under a regular implementation name +- iconvconfig: Fix multiple issues +- wordexp: handle overflow in positional parameter number (bug 28011) +- Update math: redirect roundeven function +- Use GCC builtins for roundeven functions if desired. +- x86_64: roundeven with sse4.1 support +- math: redirect roundeven function + +* Mon Jun 28 2021 Florian Weimer - 2.33.9000-32 +- Switch to new version of libthread_db .dynsym patch + +* Mon Jun 28 2021 Florian Weimer - 2.33.9000-31 +- Further .symtab adjustment: Keep all __GI_* symbols (#1975895) + +* Mon Jun 28 2021 Florian Weimer - 2.33.9000-30 +- Keep most of .symtab in libc.so.6 (#1975895) + +* Sun Jun 27 2021 Florian Weimer - 2.33.9000-29 +- Apply emergency patch to fix iconvconfig corruption + +* Sun Jun 27 2021 Florian Weimer - 2.33.9000-28 +- Adjust glibc.req so that egrep does not cause eu-readelf to fail + +* Sun Jun 27 2021 Florian Weimer - 2.33.9000-27 +- Drop glibc-revert-dtv-gap-reuse.patch, applied upstream. +- Auto-sync with upstream branch master, + commit 2c16cb88a6e5ace0fb7cedca86860ea7bde522a7: +- Linux: Move timer helper routines from librt to libc +- Linux: Move mq_unlink from librt to libc +- Linux: Move mq_send, mq_timedsend, __mq_timedsend_time64 to libc +- Linux: Move mq_receive, mq_timedreceive, __mq_timedreceive_time64 to libc +- Linux: Move mq_open, __mq_open_2 from librt to libc +- Linux: Move mq_notify from librt to libc +- Linux: Move mq_getattr from librt to libc +- Linux: Move mq_setattr from librt to libc +- Linux: Move mq_close from librt to libc +- Linux: Move lio_listio, lio_listio64 from librt to libc +- rt: Rework lio_listio implementation +- Linux: Move aio_write, aio_write64 into libc +- Linux: Move aio_suspend, aio_suspend64, __aio_suspend_time64 to libc +- Linux: Move aio_return, aio_return64 into libc +- Linux: Move aio_read, aio_read64 into libc +- Linux: Move aio_fsync, aio_fsync64 into libc +- Linux: Move aio_error, aio_error64 into libc +- Linux: Move aio_cancel, aio_cancel64 into libc +- Linux: Move aio_init from librt into libc +- support: Fix xclone build failures on ia64 and hppa +- elf: Disable most of TLS modid gaps processing [BZ #27135] +- elf: Fix glibc-hwcaps priorities with cache flags mismatches [BZ #27046] +- * NEWS: Clarify _TIME_BITS change. +- x86: Remove unnecessary overflow check from wcsnlen-sse4_1.S +- String: Add three more overflow tests cases to test-strnlen.c +- Consolidate pthread_atfork +- posix: Do not clobber errno by atfork handlers +- posix: Consolidate fork implementation +- support: Add xclone +- x86: Fix tst-cpu-features-cpuinfo on Ryzen 9 (BZ #27873) +- x86: Copy IBT and SHSTK usable only if CET is enabled +- x86: Fix overflow bug in wcsnlen-sse4_1 and wcsnlen-avx2 [BZ #27974] +- x86: Fix overflow bug with wmemchr-sse2 and wmemchr-avx2 [BZ #27974] +- String: Add overflow tests for strnlen, memchr, and strncat [BZ #27974] +- x86-64: Add wcslen optimize for sse4.1 +- x86-64: Move strlen.S to multiarch/strlen-vec.S +- hurd: Fix build after 52a5fe70a2 +- nptl: Use SA_RESTART for SIGCANCEL handler +- doc: _TIME_BITS defaults may change +- More mcheck -> malloc-check refactoring +- Add NEWS item for gconv-modules.d change +- Handle DT_UNKNOWN in gconv-modules.d +- iconvconfig: Use common gconv module parsing function +- gconv_conf: Split out configuration file processing +- gconv_conf: Remove unused variables +- iconv: Remove alloca use in gconv-modules configuration parsing +- Remove unsused symbols from nptl/Versions +- linux: Only use 64-bit syscall if required for clock_nanosleep +- linux: Only use 64-bit syscall if required for internal futex +- linux: Only use 64-bit syscall if required for utimensat family +- linux: Only use 64-bit syscall if required for sigtimedwait +- linux: Only use 64-bit syscall if required for mq_timedsend +- linux: Only use 64-bit syscall if required for mq_timedreceive +- linux: Only use 64-bit syscall if required for timerfd_settime +- linux: Only use 64-bit syscall if required for semtimedop +- linux: timerfd_gettime minor cleanup +- linux: Remove time64-support +- linux: Remove supports_time64 () from clock_gettime +- linux: Remove supports_time64 () from clock_getres +- linux: Only use 64-bit syscall if required for select +- linux: Only use 64-bit syscall if required for pselect +- linux: Only use 64-bit syscall if required for ppoll +- support: Add support_create_timer +- Use 64 bit time_t stat internally +- malloc: Drop __malloc_initialized from Versions +- tst-mcheck: Rename to tst-malloc-check +- Add hidden prototypes for fsync, fdatasync +- nptl: Move pthreadP.h into sysdeps directory +- rt: Move generic implementation from sysdeps/pthread to rt +- rt: Move shm_unlink into libc +- rt: Move shm_open into libc +- rt: Replace generic stub of shm_unlink with the posix version +- rt: Replace generic stub of shm_open with the posix version +- Fix librt-routines-var issues for !PTHREAD_IN_LIBC +- rt: Lexicographically sort Versions file; librt-routines in Makefile +- elf: Use _dl_catch_error from base namespace in dl-libc.c [BZ #27646] +- Makeconfig: Fix time64-compat.mk target + +* Sun Jun 27 2021 Florian Weimer - 2.33.9000-26 +- Add automatic requires if building against glibc development snapshots + +* Thu Jun 24 2021 Carlos O'Donell - 2.33.9000-25 +- Fix thread local storage corruption (#1974970) + +* Tue Jun 22 2021 Siddhesh Poyarekar - 2.33.9000-24 +- Strengthen dependency on glibc-gconv-extra. + +* Fri Jun 18 2021 Florian Weimer - 2.33.9000-23 +- Make glibc-all-langpacks require glibc-gconv-extra in buildroots (#1973663) + +* Thu Jun 17 2021 Florian Weimer - 2.33.9000-22 +- Export libthread_db symbols under GLBIC_PRIVATE (#1965374) + +* Thu Jun 17 2021 Florian Weimer - 2.33.9000-21 +- Redo the crafted libc.so.6 symbol table for valgrind (#1965374) + +* Thu Jun 17 2021 Florian Weimer - 2.33.9000-20 +- Remove .symtab from libc.so.6 again (#1965374) + +* Thu Jun 17 2021 Florian Weimer - 2.33.9000-19 +- Drop glibc-rh697421.patch: The ISO-10646-UCS-2// alias for UTF-8 is incorrect + (#1972520) + +* Wed Jun 16 2021 Florian Weimer - 2.33.9000-18 +- Rebuild against rawhide gcc + +* Tue Jun 15 2021 Florian Weimer - 2.33.9000-17 +- Dropped glibc-gconv-modules-revert.patch, applied upstream. +- Auto-sync with upstream branch master, + commit aa9a7f629632c9180de89632d4f2c1e6039f7781: +- nptl: Export _pthread_cleanup_push, _pthread_cleanup_pop again +- s390x: Align child stack while clone. [BZ #27968] +- y2038: Add test coverage +- libsupport: Add 64-bit time_t support for stat functions +- libsupport: Add 64-bit time_t support for time functions +- io: Add ftw64 with 64-bit time_t support +- io: Add fts64 with 64-bit time_t support +- posix: Add glob64 with 64-bit time_t support +- y2038: Add support for 64-bit time on legacy ABIs +- time: Add 64-bit time support for getdate +- y2038: Add __USE_TIME_BITS64 support for socket-constants.h +- y2038: Use a common definition for shmid_ds +- y2038: Use a common definition for semid_ds +- y2038: Use a common definition for msqid_ds +- y2038: Use a common definition for stat +- y2038: linux: Add __USE_TIME_BITS64 support for struct timex +- y2038: Add __USE_TIME_BITS64 support for struct utimbuf +- y2038: Add __USE_TIME_BITS64 support for struct timespec +- y2038: Add __USE_TIME_BITS64 support for struct timeval +- y2038: Add __USE_TIME_BITS64 support for time_t +- linux: Add recvvmsg fallback for 64-bit time_t SO_TIMESTAMP{NS} +- linux: Add fallback for 64-bit time_t SO_TIMESTAMP{NS} +- linux: Add fallback for 64-bit time_t SO_{RCV,SND}TIMEO +- linux: s390: Add libanl.abilist in s390 and s390x +- linux: mips: Split libanl.abilist in n32 and n64 +- linux: mips: Split librt.abilist in n32 and n64 +- Reinstate gconv-modules as the default configuration file + +* Tue Jun 15 2021 Florian Weimer - 2.33.9000-16 +- Preserve some symbols in libc.so.6's symtab (#1965374) + +* Tue Jun 15 2021 Florian Weimer - 2.33.9000-15 +- Install shared objects under their ABI names, avoiding symlinks (#1652867) + +* Mon Jun 14 2021 Siddhesh Poyarekar - 2.33.9000-14 +- Add a conditional dependency for glibc-gconv-extra.i686 in x86_64. + +* Mon Jun 14 2021 Siddhesh Poyarekar - 2.33.9000-13 +- Auto-sync with upstream branch master, + commit ebae2f5a6f971a8f0b6c99e00f9c45ef7433924a. +- Revert gconv configuration file name to gconv-modules. + +* Thu Jun 03 2021 Florian Weimer - 2.33.9000-12 +- libdl is no longer a separate shared object. +- CVE-2021-33574: Use-after-free via mq_notify (#1965410) +- Auto-sync with upstream branch master, + commit 466c1ea15f461edb8e3ffaf5d86d708876343bbf: +- dlfcn: Rework static dlopen hooks +- dlfcn: Eliminate GLIBC_PRIVATE dependency from tststatic2 +- dlfcn: Cleanups after -ldl is no longer required +- dlfcn: Move dlopen into libc +- dlfcn: Move dlvsym into libc +- dlfcn: Move dlinfo into libc +- dlfcn: Move dladdr1 into libc +- dlfcn: Move dlmopen into libc +- dlfcn: Move dlsym into libc +- dlfcn: Move dladdr into libc +- dlfcn: Move dlclose into libc +- Improve test coverage of strlen function +- fix typo +- dlfcn: Move dlerror into libc +- Add libc ABI extension kludge for baseline-violating libdl symbols +- scripts/versions.awk: Add local: * to all version nodes +- Add missing symbols to Version files +- Fix use of __pthread_attr_copy in mq_notify (bug 27896) +- Use __pthread_attr_copy in mq_notify (bug 27896) +- Update floating-point feature test macro handling for C2X +- stdio-common: Remove _IO_vfwscanf +- aarch64: align stack in clone [BZ #27939] +- powerpc: Optimized memcmp for power10 +- x86-64: Align child stack to 16 bytes [BZ #27902] + +* Mon May 31 2021 Florian Weimer - 2.33.9000-11 +- glibc-sigsetxid-sa_onstack.patch was applied upstream +- Auto-sync with upstream branch master, + commit 271ec55d0ae795f03d92e3aa61bff69a31a19e3a: +- support: Do not build xpthread_attr_setaffinity_np for hurd +- nptl: Add pthread_attr_setaffinity_np failure test +- support: Add xpthread_attr_setaffinity_np wrapper +- nptl: Move createthread to pthread_create +- nptl: Move Linux createthread to nptl +- nptl: Install SIGSETXID handler with SA_ONSTACK [BZ #27914] +- aarch64: Added optimized memset for A64FX +- aarch64: Added optimized memcpy and memmove for A64FX +- benchtests: Fixed bench-memcpy-random: buf1: mprotect failed +- aarch64: Added Vector Length Set test helper script +- aarch64: define BTI_C and BTI_J macros as NOP unless HAVE_AARCH64_BTI +- config: Added HAVE_AARCH64_SVE_ASM for aarch64 +- tst-mallinfo2.c: Use correct multiple for total variable + +* Wed May 26 2021 Florian Weimer - 2.33.9000-10 +- nptl: Install SIGSETXID handler with SA_ONSTACK [BZ #27914] + +* Tue May 25 2021 Florian Weimer - 2.33.9000-9 +- Auto-sync with upstream branch master, + commit ac0353af81a23535f517586a5d04427120a157ac. +- This removes libpthread as a separate shared object. New programs + will depend on the GLIBC_2.34 symbol version. Upstream development + brings in the following noteworthy bug fixes: +- ppc64le: scv ABI error handling fails to check IS_ERR_VALUE (#1962971) +- CVE-2021-27645 glibc: Use-after-free in addgetnetgrentX function in + netgroupcache.c (#1932590) +- Linking the main program with jemalloc causes sysconf to deadlock in + audit mode (#1909920) + +* Fri May 21 2021 Florian Weimer - 2.33.9000-8 +- Switch back to a unified glibc-headers package for downstream (#1940686) + +* Fri May 21 2021 Florian Weimer - 2.33.9000-7 +- aarch64: Enable optional memory tagging support + +* Tue May 11 2021 Florian Weimer - 2.33.9000-6 +- Use distribution mechanism for debuginfo (#1661510, #1886295, #1905611) + +* Thu May 6 2021 Florian Weimer - 2.33.9000-5 +- Build locales in parallel again + +* Tue May 4 2021 Florian Weimer - 2.33.9000-4 +- Various changes to get glibc building again, using selected upstream + backports. +- Re-enable -Werror by default. +- This release introduces __libc_start_main@@GLIBC_2.34, so binaries + are not compatible with glibc 2.33. Building binaries against this + glibc version is not recommended because of the partial libpthread + transition. +- glibc-upstream-amx-detection.patch: Fix build failure after GCC 11.1 update. +- glibc-upstream-malloc-test-hang.patch: Avoid test hang due to + annobin/binutils bug (#1951492) + +* Wed Mar 03 2021 Arjun Shankar - 2.33.9000-3 +- Drop glibc-rh819430.patch; fixed upstream. +- Auto-sync with upstream branch master, + commit f01a61e13872109b3b233158ab664364bd1879bc: +- i386: Regenerate ulps +- x86: Add CPU-specific diagnostics to ld.so --list-diagnostics +- x86: Automate generation of PREFERRED_FEATURE_INDEX_1 bitfield +- ld.so: Implement the --list-diagnostics option +- powerpc: Update libm-test-ulps +- tst: Add test for utimes +- tst: Add test for utime +- tst: Add test for futimens +- nptl: __libc_cleanup_push/__libc_cleanup_pop require -fexceptions +- elf: Build __dl_iterate_phdr with unwinding support [BZ #27498] +- nptl: Use for accessing the libgcc_s unwinder +- Implement _Unwind_Resume in libc on top of +- Move sysdeps/gnu/unwind-resume.c to sysdeps/generic/unwind-resume.c +- __frame_state_for: Use for unwinder access +- sparc: Implement backtrace on top +- m68k: Implement backtrace on top of +- i386: Implement backtrace on top of +- arm: Implement backtrace on top of +- backtrace: Implement on top of +- Implement for dynamically loading the libgcc_s unwinder +- Correct buffer end pointer in IO_wdefault_doallocate (BZ #26874) +- aarch64: update ulps. +- Add inputs that generate larger error bounds +- Reduce the statically linked startup code [BZ #23323] +- posix: Falling back to non wide mode in case of encoding error [BZ #14185] +- nptl: Move elision implementations into libc +- NEWS: Add missing bug closures +- added rt to malloc/Depend [BZ #27132] +- x86: Use x86/nptl/pthreaddef.h +- nptl: Move futex-internal into libc +- nptl: Move lowlevellock into libc [BZ #15648] +- nptl: Move futex-internal.c into main nptl directory +- nptl: Reformat Versions +- nptl: Split libpthread-routines into one routine per line +- x86: Remove unused variables for raw cache sizes from cacheinfo.h +- Use Linux 5.11 in build-many-glibcs.py. +- : Correct x86_cpu_TBM +- x86_64/clone.S: Upate comments +- i386/clone.S: Remove redundant EBX load +- aarch64: Remove the unused __read_tp symbol +- build-many-glibcs.py: Use make -O for more consistent log output + +* Sun Feb 21 2021 Carlos O'Donell - 2.33.9000-2 +- Auto-sync with upstream branch master, + commit e9e7f24543e6d1b0a31641f144697e261df6ccd7: +- configure: Replace obsolete AC_TRY_LINK with AC_LINK_IFELSE +- configure: Remove obsolete AC_CHECK_TOOL_PREFIX +- configure: Replace obsoleted AC_HELP_STRING with AS_HELP_STRING +- Update syscall lists for Linux 5.11. +- Correct hppa EFD_NONBLOCK, IN_NONBLOCK, SFD_NONBLOCK and TFD_NONBLOCK defines. +- string: Work around GCC PR 98512 in rawmemchr +- tst: time: Provide Y2038 tests for mktime (tst-mktime4.c) +- tst: Provide test for difftime +- tst: Provide test for ctime +- tst: Provide test for sched_rr_get_interval +- S390: Add new hwcap values. +- aarch64: Fix sys/ptrace.h if linux headers are included +- elf: Do not copy vDSO soname when setting up link map +- x86: Remove the extra space between "# endif" +- hurd: Fix fstatfs build failure +- linux: Remove stat-check.c +- linux: Remove overflow.h +- linux: Consolidate internal_statvfs +- linux: Consolidate statvfs implementations +- linux: Consolidate fstatvfs implementations +- linux: Consolidate statfs implementations +- linux: Consolidate fstatfs implementations +- linux: Set LFS statfs as default +- linux: Set default kernel_stat.h to LFS +- linux: Fix STATFS_IS_STATFS64 definition + +* Fri Feb 12 2021 Florian Weimer - 2.33.9000-1 +- Auto-sync with upstream branch master, + commit 228f30ab4724d4087d5f52018873fde22efea6e2: +- tunables: Disallow negative values for some tunables +- x86: Use SIZE_MAX instead of (long int)-1 for tunable range value +- tunables: Simplify TUNABLE_SET interface +- setrlimit/getrlimit: Use __nonnull to avoid null pointer +- benchtests: Updated json bench-variant attribute +- regex: stop using alloca +- regexec: remove alloca usage in build_trtable +- regex: remove alloca usage on regex set_regs +- malloc: Sync dynarray with gnulib +- misc: Sync cdefs.h with gnulib +- linux: Fix __sem_check_add_mapping search_sem +- linux: Fix __sem_check_add_mapping name length +- Add more ptrace constants for AArch64 and PowerPC. +- strchr: Add additional benchmarks and tests +- x86-64: Refactor and improve performance of strchr-avx2.S +- pthread: Remove alloca usage from __sem_check_add_mapping +- pthread: Refactor semaphore code +- linux: Require /dev/shm as the shared memory file system +- sunrpc: Fix typo in xdr_string comment +- tst: Provide test for ppoll +- tst: Provide test for timerfd related functions +- x86: Add PTWRITE feature detection [BZ #27346] +- nsswitch: return result when nss database is locked [BZ #27343] +- printf: Add smoke tests for long double +- Add NT_ARM_TAGGED_ADDR_CTRL from Linux 5.10 to elf.h. +- argp: Avoid undefined behaviour when invoking qsort(). +- argp: Improve comments. +- argp: Don't pass invalid arguments to isspace, isalnum, isalpha, isdigit. +- argp: Don't rely on undefined behaviour of _tolower(). +- argp: fix pointer-subtraction bug +- Use binutils 2.36 branch in build-many-glibcs.py. +- manual: Correct description of ENTRY [BZ #17183] +- nptl: Remove private futex optimization [BZ #27304] +- stdio-common: Add a few double formatting tests [BZ #27245] +- posix/tst-rfc3484: Fix compile failure linking to local __stat64 +- i686: Regenerate ULPs +- tst-rtld-list-tunables.sh: Unset glibc tunables +- linux: Remove shmmax check from tst-sysvshm-linux +- x86: Adding an upper bound for Enhanced REP MOVSB. +- Fix version.h for glibc 2.34 development +- Add MS_NOSYMFOLLOW from Linux 5.10 to . +- Move _SC_MINSIGSTKSZ/_SC_SIGSTKSZ entry in NEWS +- libSegFault: Fix printing signal number [BZ #27249] +- hurd TIOCFLUSH: fix fixing argument +- sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305] +- hurd TIOCFLUSH: Cope BSD 4.1 semantic +- tst-mallinfo2.c: Remove useless trailing semicolon for macro +- elf: Replace a --defsym trick with an object file to be compatible with LLD +- Open master branch for glibc 2.34 development +- Prepare for glibc 2.33 release +- Update NEWS with bugs +- Update translations +- NEWS: Fix typo in CVE-2021-3326 entry +- elf: Fix tests that rely on ld.so.cache for cross-compiling +- NEWS: Mention CVE-2021-3326 (iconv assertion with ISO-20220-JP-3) +- NEWS: Add entry for glibc-hwcaps and deprecate legacy hwcaps +- x86: Properly set usable CET feature bits [BZ #26625] +- Update translations +- Update libc.pot for 2.33 release +- Update ia64 libm-test-ulps +- sh: Update libm-tests-ulps +- ia64: Fix brk call on statup +- Update sparc libm-test-ulps +- Update alpha libm-test-ulps +- powerpc64: Workaround sigtramp vdso return call +- Fix nss/tst-reload2 for systems without PATH_MAX +- nsswitch: do not reload if "/" changes +- elf: Limit tst-prelink-cmp target archs +- CVE-2021-3326: gconv: Fix assertion failure in ISO-2022-JP-3 module (#1921917) + +* Wed Jan 27 2021 Arjun Shankar - 2.32.9000-29 +- Auto-sync with upstream branch master, + commit df359a25ba6f6bda06104229fbfe284c1fb30915: +- Revert "Make libc symbols hidden in static PIE" [BZ #27237] +- benchtests: Do not build bench-timing-type with MODULE_NAME=libc +- aarch64: Fix the list of tested IFUNC variants [BZ #26818] +- Update INSTALL with package versions that are known to work +- aarch64: Move and update the definition of MTE_ENABLED +- Fix misplaced const +- Update C-SKY libm-test-ulps +- manual: Correct argument order in mount examples [BZ #27207] +- linux: mips: Fix getdents64 fallback on mips64-n32 +- x86: Properly match CPU features in /proc/cpuinfo [BZ #27222] +- x86-64: Update tst-glibc-hwcaps-2.c for x86-64 baseline +- powerpc64: Select POWER9 machine for the scv instruction +- x86: Check ifunc resolver with CPU_FEATURE_USABLE [BZ #27072] +- Revert "linux: Move {f}xstat{at} to compat symbols" for static build +- aarch64: revert memcpy optimze for kunpeng to avoid performance degradation +- Make libc symbols hidden in static PIE +- csu: Move static pie self relocation later [BZ #27072] +- Use hidden visibility for early static PIE code +- csu: Avoid weak ref for __ehdr_start in static PIE +- configure: Check for static PIE support +- elf: Avoid RELATIVE relocs in __tunables_init +- elf: Make the tunable struct definition internal only +- : Remove the C preprocessor magic +- posix: Fix fnmatch.c on bootstrap +- stdlib: Add testcase for BZ #26241 +- posix: Fix regex_internal.h on bootstrap +- Use in __libc_init_secure +- elf: Avoid RELATIVE relocation for _dl_sysinfo +- libmvec: Add extra-test-objs to test-extras +- Hurd: Add rtld-strncpy-c.c +- Update MIPS libm-test-ulps. +- Update arm libm-test-ulps. +- Update powerpc-nofpu libm-test-ulps. +- Update hppa libm-test-ulps +- ARC: nofpu: Regenerate ulps +- ld.so: Add --list-tunables to print tunable values +- math/test-tgmath2: Fix fabs failure when no long double +- x86: Move x86 processor cache info to cpu_features +- Fix x86 build with --enable-tunable=no +- ifuncmain6pie: Remove the circular IFUNC dependency [BZ #20019] + +* Tue Jan 26 2021 Fedora Release Engineering - 2.32.9000-28 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Sat Jan 23 2021 Arjun Shankar - 2.32.9000-27 +- Introduce new glibc-doc.noarch subpackage (#1346925) +- Move the reference manual info pages from glibc-devel to glibc-doc +- Move debugger interface documentation from glibc to glibc-doc +- Remove unnecessary README, INSTALL, NEWS files from glibc +- Remove unnecessary README.timezone and gai.conf files from glibc-common + +* Thu Jan 14 2021 Arjun Shankar - 2.32.9000-26 +- Deprecate nscd (#1905135) +- https://fedoraproject.org/wiki/Changes/DeprecateNSCD + +* Wed Jan 13 2021 Carlos O'Donell - 2.32.9000-25 +- Auto-sync with upstream branch master, + commit cf1290064598def8dfeddec3d86d98495aee1fba: +- Use the right argument code in unnormal tests +- ldconfig/x86: Store ISA level in cache and aux cache +- elf: work around a gcc bug in elf_get_dynamic_info +- x86: Set header.feature_1 in TCB for always-on CET [BZ #27177] +- posix: consume less entropy on tempname +- Makerules: Do not require startup files for format.lds probe object +- install: Replace scripts/output-format.sed with objdump -f [BZ #26559] +- math: Add BZ#18980 fix back on dbl-64 cosh +- posix: Sync tempname with gnulib [BZ #26648] +- posix: Fix return value of system if shell can not be executed [BZ #27053] +- support: Add xchmod wrapper +- Update STATX_ATTR_DAX value from Linux 5.10. +- riscv: Initialize $gp before resolving the IRELATIVE relocation +- riscv: support GNU indirect function +- posix: Correct attribute access mode on readlinkat [BZ #27024]. +- Add xfchmod to libsupport +- Add xchdir to libsupport. +- POSIX locale: Fix typo in comment +- ARC: Regenerate ulps +- mntent: Use __putc_unlocked instead of fputc_unlocked +- aarch64: define PI_STATIC_AND_HIDDEN +- Update NEWS for CVE-2019-25013. +- x86: Support GNU_PROPERTY_X86_ISA_1_V[234] marker [BZ #26717] +- Remove dbl-64/wordsize-64 (part 2) +- Remove dbl-64/wordsize-64 +- Add SEGV_MTEAERR and SEGV_MTESERR from Linux 5.10. +- support: Add support_small_thread_stack_size +- stdlib: Sync canonicalize with gnulib [BZ #10635] [BZ #26592] [BZ #26341] [BZ #24970] +- malloc: Add scratch_buffer_dupfree +- Import filename.h from gnulib +- Import idx.h from gnulib +- alpha: Provide wait4 for static library [BZ #27150] +- aarch64: push the set of rules before falling into slow path +- nptl: Fix comment typo in pthread_cond_wait.c +- x86: Check IFUNC definition in unrelocated executable [BZ #20019] +- hurd: Fix mmap(!MAP_FIXED) on bogus address + +* Mon Jan 04 2021 Florian Weimer - 2.32.9000-24 +- Drop glibc-fedora-__libc_multiple_libcs.patch. Replaced by upstream's + __libc_initial flag. +- Adjust glibc-rh819430.patch to upstream's gnulib merge of fnmatch. +- Disable -Werror again due to GCC PR98512. +- Auto-sync with upstream branch master, + commit 3ec5d83d2a237d39e7fd6ef7a0bc8ac4c171a4a5: +- x86-64: Avoid rep movsb with short distance [BZ #27130] +- aarch64: fix stack missing after sp is updated +- nptl: Remove set*id, set*gid files which are not built +- Drop nan-pseudo-number.h usage from tests +- posix: Sync fnmatch with gnulib +- Sync flexmember.h with gnulib +- Sync intprops.h with gnulib +- posix: Sync glob code with gnulib +- posix: Sync regex code with gnulib +- Move generic nan-pseudo-number.h to ldbl-96 +- Sync FDL from https://www.gnu.org/licenses/fdl-1.3.texi +- Sync move-if-change from Gnulib +- Update automatically-generated copyright dates +- Update copyright dates not handled by scripts/update-copyrights. +- Update copyright dates with scripts/update-copyrights +- aarch64: use PTR_ARG and SIZE_ARG instead of DELOUSE +- nonstring: Enable __FORTIFY_LEVEL=3 +- string: Enable __FORTIFY_LEVEL=3 +- Introduce _FORTIFY_SOURCE=3 +- Warn on unsupported fortification levels +- powerpc: Use scv instruction on clone when available +- powerpc: Runtime selection between sc and scv for syscalls +- malloc: preserve errno on mcheck hooks [BZ #17924] +- x86 long double: Add tests for pseudo normal numbers +- x86 long double: Consider pseudo numbers as signaling +- io: Remove xmknod{at} implementations +- io: Remove xstat implementations +- free: preserve errno [BZ#17924] +- hurd: Accept including hurd/version.h +- hurd: Add WSTOPPED/WCONTINUED/WEXITED/WNOWAIT support [BZ #23091] +- support: Make support_process_state_wait wait less +- hurd: set sigaction for signal preemptors in arch-independent file +- hurd: Fix spawni SPAWN_XFLAGS_TRY_SHELL with empty argv +- hurd: Try shell in posix_spawn* only in compat mode +- Remove _ISOMAC check from +- x86: Remove the duplicated CPU_FEATURE_CPU_P +- Partially revert 681900d29683722b1cb0a8e565a0585846ec5a61 +- x86 long double: Support pseudo numbers in isnanl +- x86 long double: Support pseudo numbers in fpclassifyl +- MTE: Do not pad size in realloc_check +- tests-mcheck: New variable to run tests with MALLOC_CHECK_=3 +- elf: Account for glibc-hwcaps/ prefix in _dl_important_hwcaps +- misc: Use __ferror_unlocked instead of ferror +- s390x: Regenerate ulps +- powerpc: Regenerate ulps +- addmntent: Remove unbounded alloca usage from getmntent [BZ#27083] +- : Add Intel LAM support +- i386: Regenerate ulps +- aarch64: update ulps. +- aarch64: Add aarch64-specific files for memory tagging support +- aarch64: Add sysv specific enabling code for memory tagging +- linux: Add compatibility definitions to sys/prctl.h for MTE +- malloc: Basic support for memory tagging in the malloc() family +- elf: Add a tunable to control use of tagged memory +- config: Allow memory tagging to be enabled when configuring glibc +- alpha: Remove anonymous union in struct stat [BZ #27042] +- add inputs to auto-libm-test-in yielding larger errors (binary64, x86_64) +- m68k: fix clobbering a5 in setjmp() [BZ #24202] +- iconv add iconv_close before the function returned with bad value. +- iconv: use iconv_close after iconv_open +- Fix buffer overrun in EUC-KR conversion module (bz #24973) +- hurd: Make trampoline fill siginfo ss_sp from sc_uesp +- Hurd: make sigstates hold a reference on thread ports +- profil-counter: Add missing SIGINFO case +- hurd: implement SA_SIGINFO signal handlers. +- hurd: Fix ELF_MACHINE_USER_ADDRESS_MASK value +- hurd: Note when the vm_map kernel bug was fixed +- hurd: Also turn KERN_INVALID_ADDRESS to EINVAL +- ieee754: Remove unused __sin32 and __cos32 +- ieee754: Remove slow paths from asin and acos +- getenv: Move call to strlen to the branch it's used in. +- Update kernel version to 5.10 in tst-mman-consts.py. +- s390x: Require GCC 7.1 or later to build glibc. +- malloc: Use __libc_initial to detect an inner libc +- Replace __libc_multiple_libcs with __libc_initial flag +- {nptl,htl}/semaphoreP.h: clean up +- htl: Get sem_open/sem_close/sem_unlink support [BZ #25524] +- pthread: Move semaphore initialization for open to semaphoreP.h +- Mark __libc_freeres_fn as used [BZ #27002] +- Update syscall lists for Linux 5.10. +- htl: Add pshared semaphore support +- hurd: Add LLL_PRIVATE and LLL_SHARED +- hurd: Add __libc_open and __libc_close +- htl: Add futex-internal.h +- hurd: Add __lll_abstimed_wait_intr +- hurd: make lll_* take a variable instead of a ptr +- hurd: Rename LLL_INITIALIZER to LLL_LOCK_INITIALIZER +- Use Linux 5.10 in build-many-glibcs.py. + +* Wed Dec 16 2020 DJ Delorie - 2.32.9000-23 +- Fix conditionals for _enable_debug_packages and benchtests [BZ #1902514] + +* Tue Dec 15 2020 Patsy Griffin - 2.32.9000-22 +- Auto-sync with upstream branch master, + commit 4d0985543f479a6f421d4d8a9e0d1dc71c9c2c53. +- elf: Record libc.so link map when it is the main program (bug 20972) +- Use GMP 6.2.1 in build-many-glibcs.py. +- aarch64: remove the strlen_asimd symbol +- aarch64: fix static PIE start code for BTI [BZ #27068] +- elf: Fix failure handling in _dl_map_object_from_fd +- elf: inline lose for error handling +- Remove strtoimax, strtoumax, wcstoimax, wcstoumax inlines +- nsswitch: handle missing actions properly +- x86: Remove the default REP MOVSB threshold tunable value [BZ #27061] +- elf.h: Remove SHF_GNU_BUILD_NOTE. +- elf.h: fix spelling typos in comments +- Fix spelling and grammar in several comments +- malloc: Detect infinite-loop in _int_free when freeing tcache [BZ#27052] +- elf: Fix dl-load.c +- elf: Include libc.so.6 as main program in dependency sort (bug 20972) +- support: Add support_slibdir_prefix variable +- aarch64: Use mmap to add PROT_BTI instead of mprotect [BZ #26831] +- elf: Pass the fd to note processing +- elf: Move note processing after l_phdr is updated +- aarch64: align address for BTI protection [BZ #26988] +- aarch64: Fix missing BTI protection from dependencies [BZ #26926] +- Fix linknamespace errors in nss_database.c if build with -Os. +- treewide: fix incorrect spelling of indices in comments +- linux: Consolidate brk implementation +- elf: Include in cache.c +- s390x: Add glibc-hwcaps support +- elf: Fix run-time dependencies of tst-dlopen-fail-2 +- Handle out-of-memory case in svc_tcp.c/svc_unix.c:rendezvous_request. +- elf: Fix incorrect comparison in sort_priorities_by_name +- S390: Derive float_t from FLT_EVAL_METHOD +- Fix parsing of /sys/devices/system/cpu/online (bug 25859) +- Make strtoimax, strtoumax, wcstoimax, wcstoumax into aliases +- Fixed typos in "NEWS for version 2.32" +- Add NEWS entry for CVE-2020-29562 (BZ #26923) +- iconv: Fix incorrect UCS4 inner loop bounds (BZ#26923) +- Drop glibc-rh1906066 and glibc-rh741105 patches fixed by sync. + +* Mon Dec 14 2020 Florian Weimer - 2.32.9000-21 +- Re-enable -Werror everywhere (#1888246) + +* Wed Dec 09 2020 DJ Delorie - 2.32.9000-20 +- nsswitch: handle missing actions properly (temporary fix for 1906066) + +* Mon Dec 07 2020 Arjun Shankar - 2.32.9000-19 +- Auto-sync with upstream branch master, + commit 088e9625378f25607acff3daf7a79cbdee497043: +- x86: Rename readelflib.c +- nsswitch: use new internal API (callers) +- nsswitch: user new internal API (tests) +- nsswitch: use new internal API (core) +- nss: Implement +- : New abstraction for combining NSS modules and NSS actions +- nss: Introduce +- Add scripts/move-symbol-to-libc.py + +* Fri Dec 04 2020 Arjun Shankar - 2.32.9000-18 +- Drop glibc-revert-fxstat-compat.patch; applied upstream. +- Drop glibc-revert-mknod-compat.patch; applied upstream. +- Auto-sync with upstream branch master, + commit 4c38c1a229bc3628269ad98bd7e8d31d118d91f6: +- powerpc64le: Add glibc-hwcaps support +- x86: Adjust tst-cpu-features-supports.c for GCC 11 +- x86: Set RDRAND usable if CPU supports RDRAND +- elf: Add missing header to elf/dl-hwcaps.h +- lowlevellock-futex: Remove not used macros +- futex: Remove not used futex_reltimed_wait{_cancelable} +- y2038: Convert gai_suspend to support 64 bit time +- symbols: Add defines for libanl's libanl_hidden_{def|proto} +- x86_64: Add glibc-hwcaps support +- elf: Add glibc-hwcaps subdirectory support to ld.so cache processing +- elf: Process glibc-hwcaps subdirectories in ldconfig +- elf: Implement tail merging of strings in ldconfig +- elf: Implement a string table for ldconfig, with tail merging +- elf: Add extension mechanism to ld.so.cache +- elf: Add endianness markup to ld.so.cache (bug 27008) +- elf: Add glibc-hwcaps support for LD_LIBRARY_PATH +- elf: Synchronize section header flags with binutils +- x86: Fix THREAD_SELF definition to avoid ld.so crash (bug 27004) +- htl: Add hidden def for __pthread_create/detach +- manual: Clarify File Access Modes section and add O_PATH +- htl: Add missing symbols +- Revert "linux: Move xmknod{at} to compat symbols" +- Revert "linux: Move {f}xstat{at} to compat symbols" +- elf.h: Fix spelling of EM_TILE64 comment +- nptl: Fix __futex_clocklock64 return error check [BZ #26964] +- powerpc64le: ifunc select *f128 routines in multiarch mode +- y2038: Convert aio_suspend to support 64 bit time +- Fix typo in NEWS file +- nptl: Add EOVERFLOW checks for futex calls +- nptl: Fix PTHREAD_PRIO_PROTECT timed lock +- sh: Add sh4 fpu Implies folder +- io: nftw/ftw: Fix stack overflow with large nopenfd [BZ #26353] +- elf: Introduce enum opt_format in the ldconfig implementation +- support: Add support_copy_file +- NEWS entry for commit b4f020c9b408fb3d1d3d4901c4a71839145f8791 +- timezone: Change zdump installation to bin directory +- nptl: Return EINVAL for invalid clock for pthread_clockjoin_np +- nptl: Return EINVAL for pthread_mutex_clocklock/PI with CLOCK_MONOTONIC [BZ #26801] +- nptl: Replace lll_futex_wake with futex-internal.h +- nptl: Replace lll_futex_supported_clockid with futex-internal.h +- nptl: Replace lll_futex_{timed_}wait by futex-internal.h +- nptl: Replace lll_timedwait with __futex_abstimed_wait64 +- nptl: Replace __futex_clocklock_wait64 with __futex_abstimed_wait64 +- nptl: Remove _futex_clock_wait_bitset64 +- nptl: Consolidate __futex_abstimed_wait_{cancelable}64 +- nptl: Extend __futex_abstimed_wait_cancelable64 comment +- nptl: Remove clockwait_tid +- nptl: Remove futex_wait_cancelable +- nptl: Remove unused internal futex functions +- Mark mtrace tests UNSUPPORTED if bug-ga2.mtrace or tst-leaks2.mtrace are missing +- elf: Fix uninitialized variable for _dl_write +- powerpc: Make PT_THREAD_POINTER available to assembly code +- Use libnss_files.so for tests posix/bug-ga2 and resolv/tst-leaks2 [BZ #26821] +- hurd report-wait: Fix stpcpy usage +- hurd S_msg_report_wait: Fix detecting fd ports +- hurd S_msg_report_wait: Fix reporting ports +- hurd: Fix strcpy calls +- hurd: Fix _S_msg_get/set_env_variable prototype +- hurd: Enable using ifunc +- Add {,sysdep-}ld-library-path make variable +- nptl: Move stack list variables into _rtld_global +- hurd: let _dl_argv and __libc_stack_end be relro +- hurd: Remove some remnants of cthreads +- nanosleep: Pass NULL when rem == NULL on ports with __TIMESIZE != 64 +- y2038: Convert thrd_sleep to support 64 bit time +- y2038: Convert mtx_timedlock to support 64 bit time +- y2038: Convert cnd_timedwait to support 64 bit time +- hurd: Drop CLOCK_MONOTONIC change which slipped in +- hurd: make ptsname fail with ENOTTY on non-master-pty +- mach: Add missing assert.h include +- hurd: break relocation loop between libc.so and lib{mach,hurd}user.so +- Remove obsolete defines for HPUX support from fcntl.h and update O_NONBLOCK. +- Remove tls.h inclusion from internal errno.h +- nptl: Eliminate and __is_smp +- powerpc: Eliminate UP macro conditionals +- x86: Remove UP macro. Define LOCK_PREFIX unconditionally. +- alpha: Remove UP preprocessor conditionals +- hurd: Make sure signals get started +- hurd: initialize libpthread before starting the signal thread +- hurd: Make _hurd_libc_proc_init idempotent +- powerpc: Add optimized stpncpy for POWER9 +- powerpc: Add optimized strncpy for POWER9 +- Don't use nested function in test-ffs +- Use __builtin___stpncpy_chk when available +- tests: Remove NULL check for an array +- hurd: Move {,f,l}xstat{,at} and xmknod{at} to compat symbols +- hurd: Notify the proc server later during initialization +- htl: Initialize later +- htl: Keep thread signals blocked during its initialization +- htl: Fix spurious symbols in namespaces +- Use O_CLOEXEC in sysconf [BZ #26791] +- struct _Unwind_Exception alignment should not depend on compiler flags +- hurd: keep only required PLTs in ld.so +- hurd: Add missing startup calls +- riscv: Get cache information through sysconf +- RISC-V: Add _dl_start_user. + +* Thu Nov 26 2020 Florian Weimer - 2.32.9000-17 +- s390x: Do not rewrite program interpreter symlink (make install is enough) + +* Tue Nov 10 2020 Carlos O'Donell - 2.32.9000-16 +- Remove the work around for systemd-nspawn (#1869030). + +* Mon Nov 09 2020 DJ Delorie - 2.32.9000-15 +- Auto-sync with upstream branch master, + commit 75a193b7611bade31a150dfcc528b973e3d46231. +- linux: Allow adjtime with NULL argument [BZ #26833] +- aarch64: Add unwind information to _start (bug 26853) +- bsd unlockpt: unlockpt needs to fail with EINVAL, not ENOTTY +- Rearrange bsd_getpt vs bsd_openpt and implement posix_openpt on BSD +- Remove __warndecl +- Remove __warn_memset_zero_len [BZ #25399] +- iconv: Accept redundant shift sequences in IBM1364 [BZ #26224] +- msg: Remove redundant #include header +- tst-setuid1-static-ENV: Add $(common-objpfx)nss [BZ #26820] + +* Tue Nov 03 2020 Patsy Griffin - 2.32.9000-14 +- Auto-sync with upstream branch master, + commit e156dabc766d6f6f99ce9402999eae380a3ec1f2. +- aarch64: Add variant PCS lazy binding test [BZ #26798] +- aarch64: Fix DT_AARCH64_VARIANT_PCS handling [BZ #26798] +- hurd: Correct 'ethenet' spelling +- Avoid -Wstringop-overflow warning in pthread_cleanup_push macros +- Disable spurious -Warray-bounds for ypclnt.c (bug 26687) +- Do not use array parameter to new_composite_name (bug 26726) +- Disable spurious -Wstringop-overflow for setjmp/longjmp (bug 26647) +- malloc debug: fix compile error when enable macro MALLOC_DEBUG > 1 +- tst-tcfree2: adjust coding style. +- elf: In ldconfig, extract the new_sub_entry function from search_dir +- Use MPC 1.2.1 in build-many-glibcs.py. +- Argument Syntax: Use "option", @option, and @command. +- elf: Unify old and new format cache handling code in ld.so +- x86: Restore processing of cache size tunables in init_cacheinfo +- Make elf.h header self contained. +- x86: Optimizing memcpy for AMD Zen architecture. +- Hurd: Fix ftime build +- Add IP_RECVERR_RFC4884 and IPV6_RECVERR_RFC4884 from Linux 5.9. +- misc: Add internal __getauxval2 function +- Remove NEWS entry about ftime removal +- time: Add 64-bit time_t support for ftime +- Reinstate ftime and add deprecate message on ftime usage +- Update kernel version to 5.9 in tst-mman-consts.py. +- Amend grammar and add a description +- Fix typo in NEWS file +- Remove timing related checks of time/tst-cpuclock1 +- Update syscall lists for Linux 5.9. +- Use Linux 5.9 in build-many-glibcs.py. +- Reword description of SXID_* tunable properties +- New benchtest: pthread locks +- y2038: nptl: Provide __futex_clock_wait_bitset64 to support 64 bit bitset +- C-SKY: Make dynamic linker's name compitable with the older gcc. +- Revert "C-SKY:Fix dynamic linker's name when mfloat-abi=softfp." +- Move vtimes to a compatibility symbol +- y2038: linux: Provide __time64 implementation +- rt: Fix typos in comments in +- C-SKY:Fix dynamic linker's name when mfloat-abi=softfp. +- Drop the glibc-revert-ftime-compat.patch. + +* Thu Oct 29 2020 DJ Delorie - 2.32.9000-13 +- Add BuildRequires for perl (malloc/mtrace) if running the testsuite. + +* Wed Oct 21 2020 Siddhesh Poyarekar - 2.32.9000-12 +- Revert __xstat64 symbol removal. +- Revert xmknod* symbol removal. +- Revert ftime symbol removal. + +* Sun Oct 18 2020 Patsy Griffin - 2.32.9000-11 +- Auto-sync with upstream branch master, + commit 0f09154c64005e78b61484ae87b5ea2028051ea0. +- x86: Initialize CPU info via IFUNC relocation [BZ 26203] +- Add NEWS entry for ftime compatibility move +- support: Add create_temp_file_in_dir +- linux: Add __readdir_unlocked +- linux: Simplify opendir buffer allocation +- linux: Move posix dir implementations to Linux +- linux: Add 64-bit time_t support for wait3 +- Move ftime to a compatibility symbol +- linux: Fix time64 support for futimesat +- linux: Use INTERNAL_SYSCALL on fstatat{64} +- shm tests: Append PID to names passed to shm_open [BZ #26737] +- sysvipc: Fix tst-sysvshm-linux on x32 +- x86/CET: Update vfork to prevent child return +- resolv: Serialize processing in resolv/tst-resolv-txnid-collision +- statfs: add missing f_flags assignment +- y2038: Remove not used __fstatat_time64 define +- y2038: nptl: Convert pthread_mutex_{clock|timed}lock to support 64 bit +- sysvipc: Return EINVAL for invalid shmctl commands +- sysvipc: Fix IPC_INFO and SHM_INFO handling [BZ #26636] +- AArch64: Use __memcpy_simd on Neoverse N2/V1 +- resolv: Handle transaction ID collisions in parallel queries (bug 26600) +- support: Provide a way to clear the RA bit in DNS server responses +- support: Provide a way to reorder responses within the DNS test server +- Add missing stat/mknod symbol on libc.abilist some ABIs +- manual: correct the spelling of "MALLOC_PERTURB_" [BZ #23015] +- manual: replace an obsolete collation example with a valid one +- rtld: fix typo in comment +- elf: Add missing header to elf/dl-usage.c +- hurd: support clock_gettime(CLOCK_PROCESS/THREAD_CPUTIME_ID) +- linux: Move xmknod{at} to compat symbols +- linux: Add {f}stat{at} y2038 support +- linux: Move {f}xstat{at} to compat symbols +- linux: Disentangle fstatat from fxstatat +- linux: Implement {l}fstat{at} in terms of fstatat +- linux: Move the struct stat{64} to struct_stat.h +- Remove mknod wrapper functions, move them to symbols +- Remove stat wrapper functions, move them to exported symbols +- : Add FSRCS/FSRS/FZLRM support +- : Add Intel HRESET support +- : Add AVX-VNNI support +- : Add AVX512_FP16 support +- : Add Intel UINTR support +- elf: Do not pass GLRO(dl_platform), GLRO(dl_platformlen) to _dl_important_hwcaps +- elf: Enhance ld.so --help to print HWCAP subdirectories +- elf: Add library search path information to ld.so --help +- sunrpc: Adjust RPC function declarations to match Sun's (bug 26686] +- Avoid GCC 11 -Warray-parameter warnings [BZ #26686]. +- elf: Make __rtld_env_path_list and __rtld_search_dirs global variables +- elf: Print the full name of the dynamic loader in the ld.so help message +- elf: Use the term "program interpreter" in the ld.so help message +- scripts/update-copyrights: Update csu/version.c, elf/dl-usage.c +- elf: Implement ld.so --version +- nptl: Add missing cancellation flags on lockf +- Update mips64 libm-test-ulps +- Update alpha libm-test-ulps +- elf: Implement ld.so --help +- elf: Record whether paths come from LD_LIBRARY_PATH or --library-path +- elf: Move ld.so error/help output to _dl_usage +- elf: Extract command-line/environment variables state from rtld.c + +* Wed Oct 14 2020 Florian Weimer - 2.32.9000-10 +- Disable -Werror on ELN (#1888246) + +* Wed Oct 14 2020 Florian Weimer - 2.32.9000-9 +- Make glibc.spec self-contained (#1887097) + +* Thu Oct 08 2020 Arjun Shankar - 2.32.9000-8 +- Drop glibc-fix-float128-benchtests.patch; applied upstream. +- Auto-sync with upstream branch master, + commit 72d36ffd7db55ae599f4c77feb0eae25a0f3714e: +- elf: Implement __rtld_malloc_is_complete +- __vfscanf_internal: fix aliasing violation (bug 26690) +- Revert "Fix missing redirects in testsuite targets" +- nptl: Add missing cancellation flags on futex_internal and pselect32 +- elf: Implement _dl_write +- elf: Do not search HWCAP subdirectories in statically linked binaries +- Linux: Require properly configured /dev/pts for PTYs +- Linux: unlockpt needs to fail with EINVAL, not ENOTTY (bug 26053) +- login/tst-grantpt: Convert to support framework, more error checking +- posix: Fix -Warray-bounds instances building timer_create [BZ #26687] +- Replace Minumum/minumum with Minimum/minimum +- Optimize scripts/merge-test-results.sh +- Fix GCC 11 -Warray-parameter warning for __sigsetjmp (bug 26647) +- manual: Fix typo +- y2038: nptl: Convert pthread_rwlock_{clock|timed}{rd|wr}lock to support 64 + bit time +- Y2038: nptl: Provide futex_abstimed_wait64 supporting 64 bit time +- sysvipc: Return EINVAL for invalid msgctl commands +- sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639] +- sysvipc: Return EINVAL for invalid semctl commands +- sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] +- aarch64: enforce >=64K guard size [BZ #26691] +- sysvipc: Fix semtimedop for Linux < 5.1 for 64-bit ABI +- nptl: futex: Move __NR_futex_time64 alias to beginning of futex-internal.h +- nptl: Provide proper spelling for 32 bit version of futex_abstimed_wait +- string: Fix strerrorname_np return value [BZ #26555] +- Set tunable value as well as min/max values +- ld.so: add an --argv0 option [BZ #16124] +- Reversing calculation of __x86_shared_non_temporal_threshold +- linux: Add time64 recvmmsg support +- linux: Add time64 support for nanosleep +- linux: Consolidate utimes +- linux: Use 64-bit time_t syscall on clock_getcputclockid +- linux: Add time64 sigtimedwait support +- linux: Add time64 select support +- nptl: Fix __futex_abstimed_wait_cancellable32 +- sysvipc: Fix semtimeop for !__ASSUME_DIRECT_SYSVIPC_SYSCALLS +- hurd: add ST_RELATIME +- intl: Handle translation output codesets with suffixes [BZ #26383] +- bench-strcmp.c: Add workloads on page boundary +- bench-strncmp.c: Add workloads on page boundary +- strcmp: Add a testcase for page boundary +- strncmp: Add a testcase for page boundary [BZ #25933] +- Set locale related environment variables in debugglibc.sh +- benchtests: Run _Float128 tests only on architectures that support it +- powerpc: Protect dl_powerpc_cpu_features on INIT_ARCH() [BZ #26615] +- x86: Harden printf against non-normal long double values (bug 26649) +- x86: Use one ldbl2mpn.c file for both i386 and x86_64 +- Define __THROW to noexcept for C++11 and later + +* Mon Sep 21 2020 Arjun Shankar - 2.32.9000-7 +- Adjust glibc-rh741105.patch. +- Add glibc-fix-float128-benchtests.patch to allow building on armv7hl. +- Auto-sync with upstream branch master, + commit cdf645427d176197b82f44308a5e131d69fb53ad: +- Update mallinfo2 ABI, and test +- Allow memset local PLT reference for RISC-V. +- powerpc: fix ifunc implementation list for POWER9 strlen and stpcpy +- nscd: bump GC cycle during cache pruning (bug 26130) +- x86: Use HAS_CPU_FEATURE with IBT and SHSTK [BZ #26625] +- : Add Intel Key Locker support +- Fix handling of collating symbols in fnmatch (bug 26620) +- pselect.c: Pass a pointer to SYSCALL_CANCEL [BZ #26606] +- y2038: nptl: Convert sem_{clock|timed}wait to support 64 bit time +- hurd: Add __x86_get_cpu_features to ld.abilist +- x86: Install [BZ #26124] +- linux: Add time64 pselect support +- linux: Add time64 semtimedop support +- linux: Add ppoll time64 optimization +- linux: Simplify clock_getres +- Update sparc libm-test-ulps +- Remove internal usage of extensible stat functions +- Linux: Consolidate xmknod +- linux: Consolidate fxstatat{64} +- linux: Consolidate fxstat{64} +- linux: Consolidate lxstat{64} +- linux: Consolidate xstat{64} +- linux: Define STAT64_IS_KERNEL_STAT64 +- linux: Always define STAT_IS_KERNEL_STAT +- Update powerpc libm-test-ulps +- benchtests: Add "workload" traces for sinf128 +- benchtests: Add "workload" traces for sinf +- benchtests: Add "workload" traces for sin +- benchtests: Add "workload" traces for powf128 +- benchtests: Add "workload" traces for pow +- benchtests: Add "workload" traces for expf128 +- benchtests: Add "workload" traces for exp +- nptl: futex: Provide correct indentation for part of + __futex_abstimed_wait_cancelable64 + +* Tue Sep 08 2020 DJ Delorie - 2.32.9000-6 +- Auto-sync with upstream branch master, + commit e74b61c09a2a2ab52153e731225ccba5078659b1. +- Disable -Wstringop-overread for some string tests +- string: Fix GCC 11 `-Werror=stringop-overread' error +- C11 threads: Fix inaccuracies in testsuite +- elf.h: Add aarch64 bti/pac dynamic tag constants +- x86: Set CPU usable feature bits conservatively [BZ #26552] + +* Wed Sep 02 2020 Patsy Griffin - 2.32.9000-5 +- Auto-sync with upstream branch master, + commit 86a912c8634f581ea42ec6973553dde7f058cfbf. +- Update i686 ulps. +- Use LFS readdir in generic POSIX getcwd [BZ# 22899] +- linux: Remove __ASSUME_ATFCTS +- Sync getcwd with gnulib +- x86-64: Fix FMA4 detection in ifunc [BZ #26534] +- y2038: nptl: Convert pthread_cond_{clock|timed}wait to support 64 bit time +- malloc: Fix mallinfo deprecation declaration +- x32: Add and regenerate arch-syscall.h +- Add mallinfo2 function that support sizes >= 4GB. +- Remove obsolete default/nss code +- AArch64: Improve backwards memmove performance +- Add RISC-V 32-bit target to build-many-glibcs.py +- Documentation for the RISC-V 32-bit port +- RISC-V: Build infrastructure for 32-bit port +- RISC-V: Add rv32 path to RTLDLIST in ldd +- riscv32: Specify the arch_minimum_kernel as 5.4 +- RISC-V: Fix llrint and llround missing exceptions on RV32 +- RISC-V: Add the RV32 libm-test-ulps +- RISC-V: Add 32-bit ABI lists +- RISC-V: Add hard float support for 32-bit CPUs +- RISC-V: Support the 32-bit ABI implementation +- RISC-V: Add arch-syscall.h for RV32 +- RISC-V: Add path of library directories for the 32-bit +- RISC-V: Support dynamic loader for the 32-bit +- RISC-V: Add support for 32-bit vDSO calls +- RISC-V: Use 64-bit-time syscall numbers with the 32-bit port +- RISC-V: Cleanup some of the sysdep.h code +- RISC-V: Use 64-bit time_t and off_t for RV32 and RV64 +- io/lockf: Include bits/types.h before __OFF_T_MATCHES_OFF64_T check +- elf/tst-libc_dlvsym: Add a TEST_COMPAT around some symbol tests +- hurd: define BSD 4.3 ioctls only under __USE_MISC +- string: test strncasecmp and strncpy near page boundaries +- linux: Simplify utimensat +- linux: Simplify timerfd_settime +- linux: Simplify timer_gettime +- linux: Simplify sched_rr_get_interval +- linux: Simplify ppoll +- linux: Simplify mq_timedsend +- linux: Simplify mq_timedreceive +- linux: Simplify clock_settime +- linux: Simplify clock_nanosleep +- linux: Simplify clock_gettime +- linux: Simplify clock_adjtime +- linux: Add helper function to optimize 64-bit time_t fallback support +- S390: Sync HWCAP names with kernel by adding aliases [BZ #25971] +- [vcstocl] Import ProjectQuirks from its own file +- build-many-glibcs.py: Add a s390x -O3 glibc variant. +- Fix namespace violation in stdio.h and sys/stat.h if build with optimization. [BZ #26376] +- Add C2x BOOL_MAX and BOOL_WIDTH to limits.h. +- Use MPC 1.2.0 in build-many-glibcs.py. +- Add new STATX_* constants from Linux 5.8 to bits/statx-generic.h. +- Correct locking and cancellation cleanup in syslog functions (bug 26100) + +* Thu Aug 20 2020 Carlos O'Donell - 2.32.9000-4 +- Support building glibc in a mock chroot using older systemd-nspawn (#1869030). + +* Tue Aug 18 2020 Carlos O'Donell - 2.32.9000-3 +- Suggest installing minimal localization e.g. C, POSIX, C.UTF-8. + +* Mon Aug 17 2020 DJ Delorie - 2.32.9000-2 +- Auto-sync with upstream branch master, + commit cb7e7a5ca1d6d25d59bc038bdc09630e507c41e5. +- nptl: Handle NULL abstime [BZ #26394] +- Update build-many-glibcs.py for binutils ia64 obsoletion. +- Update kernel version to 5.8 in tst-mman-consts.py. +- y2038: nptl: Convert pthread_{clock|timed}join_np to support 64 bit time +- aarch64: update ulps. + +* Wed Aug 12 2020 Patsy Griffin - 2.32.9000-1 +- Auto-sync with upstream branch master, + commit 0be0845b7a674dbfb996f66cd03d675f0f6028dc: +- S390: Regenerate ULPs. +- manual: Fix sigdescr_np and sigabbrev_np return type (BZ #26343) +- math: Update x86_64 ulps +- math: Regenerate auto-libm-test-out-j0 +- manual: Put the istrerrorname_np and strerrordesc_np return type in braces +- Linux: Use faccessat2 to implement faccessat (bug 18683) +- manual: Fix strerrorname_np and strerrordesc_np return type (BZ #26343) +- math: Fix inaccuracy of j0f for x >= 2^127 when sin(x)+cos(x) is tiny +- Update syscall lists for Linux 5.8. +- Use Linux 5.8 in build-many-glibcs.py. +- htl: Enable tst-cancelx?[45] +- tst-cancel4: Make blocking on write more portable +- hurd: Add missing hidden def +- hurd: Rework sbrk +- hurd: Implement basic sched_get/setscheduler +- x86: Rename Intel CPU feature names +- manual: Fix some @code/@var formatting glitches chapter Date And Time +- Copy regex_internal.h from Gnulib +- Copy regex BITSET_WORD_BITS porting from Gnulib +- Sync regex.h from Gnulib +- Sync mktime.c from Gnulib +- Sync intprops.h from Gnulib +- Open master branch for glibc 2.33 development. + +* Thu Aug 06 2020 Arjun Shankar - 2.32-1 +- Auto-sync with upstream branch release/2.32/master, + commit 3de512be7ea6053255afed6154db9ee31d4e557a: +- Prepare for glibc 2.32 release. +- Regenerate configure scripts. +- Update NEWS with bugs. +- Update translations. +- Don't mix linker error messages into edited scripts +- benchtests/README update. +- RISC-V: Update lp64d libm-test-ulps according to HiFive Unleashed +- aarch64: update NEWS about branch protection +- Add NEWS entry for CVE-2016-10228 (bug 19519) +- powerpc: Fix incorrect cache line size load in memset (bug 26332) +- Update Nios II libm-test-ulps file. + +* Fri Jul 31 2020 Patsy Griffin - 2.31.9000-24 +- Auto-sync with upstream branch master, + commit 7f1a08cff82255cd4252a2c75fd65b80a6a170bf. +- Move NEWS entry for CVE-2020-1751 to the 2.31 section +- NEWS: Deprecate weak libpthread symbols for single-threaded checks +- NEWS: Deprecate nss_hesiod +- nptl: Zero-extend arguments to SETXID syscalls [BZ #26248] +- Use binutils 2.35 branch in build-many-glibcs.py. +- aarch64: Use future HWCAP2_MTE in ifunc resolver +- Update x86-64 libm-test-ulps +- aarch64: Respect p_flags when protecting code with PROT_BTI +- Disable warnings due to deprecated libselinux symbols used by nss and nscd +- Regenerate INSTALL for ARC port updates. +- Update libc.pot for 2.32 release. +- powerpc: Fix POWER10 selection +- powerpc64le: guarantee a .gnu.attributes section [BZ #26220] + +* Wed Jul 29 2020 Florian Weimer - 2.31.9000-23 +- Inherit -mbranch-protection=standard from redhat-rpm-config (for aarch64) + +* Mon Jul 27 2020 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Wed Jul 22 2020 Carlos O'Donell - 2.31.9000-21 +- Use make macros +- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro + +* Tue Jul 21 2020 Arjun Shankar - 2.31.9000-20 +- Add glibc-deprecated-selinux-makedb.patch and + glibc-deprecated-selinux-nscd.patch to work around libselinux API + deprecations. +- Drop glibc-rseq-disable.patch; rseq support removed upstream. (#1855729) +- Auto-sync with upstream branch master, + commit ec2f1fddf29053957d061dfe310f106388472a4f: +- libio: Remove __libc_readline_unlocked +- shadow: Implement fgetspent_r using __nss_fgetent_r +- pwd: Implement fgetpwent_r using __nss_fgetent_r +- gshadow: Implement fgetsgent_r using __nss_fgetent_r (bug 20338) +- grp: Implement fgetgrent_r using __nss_fgetent_r +- nss: Add __nss_fgetent_r +- libio: Add fseterr_unlocked for internal use +- nss_files: Use generic result pointer in parse_line +- nss_files: Consolidate line parse declarations in +- nss_compat: Do not use mmap to read database files (bug 26258) +- nss_files: Consolidate file opening in __nss_files_fopen +- Update powerpc-nofpu libm-test-ulps. +- Use MPFR 4.1.0 in build-many-glibcs.py. +- elf: Change TLS static surplus default back to 1664 +- hurd: Fix longjmp check for sigstate +- hurd: Fix longjmp early in initialization +- manual: New signal and errno string functions are AS-safe +- AArch64: Improve strlen_asimd performance (bug 25824) +- Move from sunrpc to inet +- en_US: Minimize changes to date_fmt (Bug 25923) +- Linux: Remove rseq support +- manual: Use Unicode instead HTML entities for characters (bug 19737) +- Add NEWS entry for CVE-2020-6096 (bug 25620) +- arm: remove string/tst-memmove-overflow XFAIL +- AArch64: Rename IS_ARES to IS_NEOVERSE_N1 +- AArch64: Add optimized Q-register memcpy +- AArch64: Align ENTRY to a cacheline +- Correct timespec implementation [BZ #26232] +- Remove --enable-obsolete-rpc configure flag +- hurd: Fix build-many-glibcs.py +- x86: Support usable check for all CPU features +- string: Make tst-strerror/tst-strsignal unsupported if msgfmt is not installed +- malloc: Deprecate more hook-related functionality +- elf: Support at least 32-byte alignment in static dlopen +- x86: Remove __ASSEMBLER__ check in init-arch.h +- x86: Remove the unused __x86_prefetchw +- Documentation for ARC port +- build-many-glibcs.py: Enable ARC builds +- ARC: Build Infrastructure +- ARC: ABI lists +- ARC: Linux Startup and Dynamic Loading +- ARC: Linux ABI +- ARC: Linux Syscall Interface +- ARC: hardware floating point support +- ARC: math soft float support +- ARC: Atomics and Locking primitives +- ARC: Thread Local Storage support +- ARC: startup and dynamic linking code +- ARC: ABI Implementation +- Fix time/tst-cpuclock1 intermitent failures +- powerpc64: Fix calls when r2 is not used [BZ #26173] +- Add NEWS entry for Update to Unicode 13.0.0 [BZ #25819] +- Update i686 libm-test-ulps +- Fix memory leak in __printf_fp_l (bug 26215). +- Fix double free in __printf_fp_l (bug 26214). +- linux: Fix syscall list generation instructions +- sysv: linux: Add 64-bit time_t variant for shmctl +- sysvipc: Remove the linux shm-pad.h file +- sysvipc: Split out linux struct shmid_ds +- sysv: linux: Add 64-bit time_t variant for msgctl +- sysvipc: Remove the linux msq-pad.h file +- sysvipc: Split out linux struct semid_ds +- sysv: linux: Add 64-bit time_t variant for semctl + +* Fri Jul 10 2020 Florian Weimer - 2.31.9000-19 +- Disable rseq registration by default to help Firefox (#1855729) + +* Thu Jul 09 2020 Florian Weimer - 2.31.9000-18 +- Auto-sync with upstream branch master, + commit ffb17e7ba3a5ba9632cee97330b325072fbe41dd: +- rtld: Avoid using up static TLS surplus for optimizations [BZ #25051] +- rtld: Account static TLS surplus for audit modules +- rtld: Add rtld.nns tunable for the number of supported namespaces +- Remove --enable-obsolete-nsl configure flag +- Move non-deprecated RPC-related functions from sunrpc to inet +- aarch64: add NEWS entry about branch protection support +- aarch64: redefine RETURN_ADDRESS to strip PAC +- aarch64: fix pac-ret support in _mcount +- aarch64: Add pac-ret support to assembly files +- aarch64: configure check for pac-ret code generation +- aarch64: ensure objects are BTI compatible +- aarch64: enable BTI at runtime +- aarch64: fix RTLD_START for BTI +- aarch64: fix swapcontext for BTI +- aarch64: Add BTI support to assembly files +- aarch64: Rename place holder .S files to .c +- aarch64: configure test for BTI support +- Rewrite abi-note.S in C. +- rtld: Clean up PT_NOTE and add PT_GNU_PROPERTY handling +- string: Move tst-strsignal tst-strerror to tests-container +- string: Fix prototype mismatch in sigabbrev_np, __sigdescr_np +- arm: CVE-2020-6096: Fix multiarch memcpy for negative length (#1820332) +- arm: CVE-2020-6096: fix memcpy and memmove for negative length (#1820332) +- sunrpc: Remove hidden aliases for global data symbols (bug 26210) +- hurd: Fix strerror not setting errno +- tst-strsignal: fix checking for RT signals support +- hurd: Evaluate fd before entering the critical section +- CVE-2016-10228: Rewrite iconv option parsing (#1428292) +- nss: Remove cryptographic key support from nss_files, nss_nis, nss_nisplus +- sunrpc: Do not export getrpcport by default +- sunrpc: Do not export key handling hooks by default +- sunrpc: Turn clnt_sperrno into a libc_hidden_nolink_sunrpc symbol +- string: Add strerrorname_np and strerrordesc_np +- string: Add sigabbrev_np and sigdescr_np +- string: Add strerror_l on test-strerror-errno +- string: Add strerror, strerror_r, and strerror_l test +- string: Add strsignal test +- string: Simplify strerror_r +- string: Use tls-internal on strerror_l +- string: Implement strerror in terms of strerror_l +- string: Remove old TLS usage on strsignal +- linux: Fix __NSIG_WORDS and add __NSIG_BYTES +- signal: Move sys_errlist to a compat symbol +- signal: Move sys_siglist to a compat symbol +- signal: Add signum-{generic,arch}.h +- Remove most vfprintf width/precision-dependent allocations (bug 14231, bug 26211). +- elf: Do not signal LA_ACT_CONSISTENT for an empty namespace [BZ #26076] +- Fix stringop-overflow errors from gcc 10 in iconv. +- x86: Add thresholds for "rep movsb/stosb" to tunables +- Use C2x return value from getpayload of non-NaN (bug 26073). +- x86: Detect Extended Feature Disable (XFD) +- x86: Correct bit_cpu_CLFSH [BZ #26208] +- manual: Document __libc_single_threaded +- Add the __libc_single_threaded variable +- Linux: rseq registration tests +- Linux: Use rseq in sched_getcpu if available +- Linux: Perform rseq registration at C startup and thread creation +- tst-cancel4: deal with ENOSYS errors +- manual: Show copyright information not just in the printed manual + + +* Thu Jul 02 2020 Carlos O'Donell - 2.31.9000-17 +- Auto-sync with upstream branch master, + commit c6aac3bf3663709cdefde5f5d5e9e875d607be5e. +- Fix typo in comment in bug 26137 fix. +- Fix strtod multiple-precision division bug (bug 26137). +- Linux: Fix UTC offset setting in settimeofday for __TIMESIZE != 64 +- random: range is not portably RAND_MAX [BZ #7003] +- Update kernel version to 5.7 in tst-mman-consts.py. +- powerpc: Add support for POWER10 +- hurd: Simplify usleep timeout computation +- htl: Enable cancel*16 an cancel*20 tests +- hurd: Add remaining cancelation points +- hurd: fix usleep(ULONG_MAX) +- hurd: Make fcntl(F_SETLKW*) cancellation points +- hurd: make wait4 a cancellation point +- hurd: Fix port definition in HURD_PORT_USE_CANCEL +- hurd: make close a cancellation point +- hurd: make open and openat cancellation points +- hurd: clean fd and port on thread cancel +- htl: Move cleanup handling to non-private libc-lock +- htl: Fix includes for lockfile +- htl: avoid cancelling threads inside critical sections +- tst-cancel4-common.c: fix calling socketpair +- x86: Detect Intel Advanced Matrix Extensions +- Set width of JUNGSEONG/JONGSEONG characters from UD7B0 to UD7FB to 0 [BZ #26120] +- S390: Optimize __memset_z196. +- S390: Optimize __memcpy_z196. +- elf: Include (for size_t), in +- nptl: Don't madvise user provided stack +- S390: Regenerate ULPs. +- htl: Add wrapper header for with hidden __sem_post +- elf: Include in because bool is used +- htl: Fix case when sem_*wait is canceled while holding a token +- htl: Make sem_*wait cancellations points +- htl: Simplify non-cancel path of __pthread_cond_timedwait_internal +- htl: Enable tst-cancel25 test +- powerpc: Add new hwcap values +- aarch64: MTE compatible strncmp +- aarch64: MTE compatible strcmp +- aarch64: MTE compatible strrchr +- aarch64: MTE compatible memrchr +- aarch64: MTE compatible memchr +- aarch64: MTE compatible strcpy +- Add MREMAP_DONTUNMAP from Linux 5.7 +- x86: Update CPU feature detection [BZ #26149] + +* Mon Jun 22 2020 DJ Delorie - 2.31.9000-16 +- Auto-sync with upstream branch master, + commit ea04f0213135b13d80f568ca2c4127c2ec112537. +- aarch64: Remove fpu Makefile +- m68k: Use sqrt{f} builtin for coldfire +- arm: Use sqrt{f} builtin +- riscv: Use sqrt{f} builtin +- s390: Use sqrt{f} builtin +- sparc: Use sqrt{f} builtin +- mips: Use sqrt{f} builtin +- alpha: Use builtin sqrt{f} +- i386: Use builtin sqrtl +- x86_64: Use builtin sqrt{f,l} +- powerpc: Use sqrt{f} builtin +- s390x: Use fma{f} builtin +- aarch64: Use math-use-builtins for ceil{f} +- math: Decompose math-use-builtins.h +- hurd: Add mremap +- ia64: Use generic exp10f +- New exp10f version without SVID compat wrapper +- i386: Use generic exp10f +- math: Optimized generic exp10f with wrappers +- benchtests: Add exp10f benchmark + +* Fri Jun 19 2020 Patsy Franklin - 2.31.9000-15 +- Auto-sync with upstream branch master, + commit 27f8864bd41f0f1b61e8e947d9a030b1a0d23df9. +- x86: Update F16C detection [BZ #26133] +- Fix avx2 strncmp offset compare condition check [BZ #25933] +- nptl: Remove now-spurious tst-cancelx9 references +- x86_64: Use %xmmN with vpxor to clear a vector register +- x86: Correct bit_cpu_CLFLUSHOPT [BZ #26128] +- powerpc64le: refactor e_sqrtf128.c +- Update syscall-names.list for Linux 5.7. +- ieee754/dbl-64: Reduce the scope of temporary storage variables +- manual: Add pthread_attr_setsigmask_np, pthread_attr_getsigmask_np +- ld.so: Check for new cache format first and enhance corruption check +- hurd: Fix __writev_nocancel_nostatus +- hurd: Make send* cancellation points +- htl: Enable more cancellation tests +- hurd: Make write and pwrite64 cancellation points +- htl: Fix cleanup support for IO locking +- htl: Move cleanup stack to variable shared between libc and pthread +- htl: initialize first and prevent from unloading +- htl: Add noreturn attribute on __pthread_exit forward +- hurd: Make recv* cancellation points +- powerpc: Automatic CPU detection in preconfigure +- Use Linux 5.7 in build-many-glibcs.py. +- htl: Enable more cancel tests +- htl: Fix linking static tests by factorizing the symbols list +- Add "%d" support to _dl_debug_vdprintf +- aarch64: MTE compatible strlen +- aarch64: MTE compatible strchr +- aarch64: MTE compatible strchrnul +- AArch64: Merge Falkor memcpy and memmove implementations +- hurd: document that gcc&gdb look at the trampoline code +- pthread: Move back linking rules to nptl and htl +- htl: Enable more tests +- htl: Fix registration of atfork handlers in modules +- htl: Fix tls initialization for already-created threads +- hurd: Make read and pread64 cancellable +- hurd: Fix unwinding over interruptible RPC +- htl: Enable but XFAIL tst-flock2, tst-signal1, tst-signal2 +- hurd: XFAIL more tests that require setpshared support +- hurd: Briefly document in xfails the topics of the bugzilla entries +- htl: Enable more tests +- htl: Add sem_clockwait support +- htl: fix register-atfork ordering +- hurd: Fix hang in _hurd_raise_signal from pthread_kill +- hurd: Reject raising invalid signals +- hurd: fix clearing SS_ONSTACK when longjmp-ing from sighandler +- hurd: Add pointer guard support +- hurd: Add stack guard support +- dl-runtime: reloc_{offset,index} now functions arch overide'able +- powerpc64le: add optimized strlen for P9 +- powerpc64le: use common fmaf128 implementation + +* Fri Jun 05 2020 Patsy Griffin - 2.31.9000-14 +- Auto-sync with upstream branch master, + commit e52434a2e4d1105272daaef87678da950fbec73f. +- benchtests: Restore the clock_gettime option +- Update HP_TIMING_NOW for _ISOMAC in sysdeps/generic/hp-timing.h +- Replace val with __val in TUNABLE_SET_VAL_IF_VALID_RANGE +- support: Fix detecting hole support on >2KB-block filesystems +- powerpc: Fix powerpc64le due a7a3435c9a +- manual/jobs.texi: remove unused var from example code +- powerpc/fpu: use generic fma functions +- aarch/fpu: use generic builtins based math functions +- ieee754: provide gcc builtins based generic fma functions +- ieee754: provide gcc builtins based generic sqrt functions +- Linux: Use __pthread_attr_setsigmask_internal for timer helper thread +- nptl: Add pthread_attr_setsigmask_np, pthread_attr_getsigmask_np +- nptl: Make pthread_attr_t dynamically extensible +- nptl: Destroy the default thread attribute as part of freeres +- nptl: Change type of __default_pthread_attr +- nptl: Use __pthread_attr_setaffinity_np in pthread_getattr_np +- nptl: Use __pthread_getattr_default_np in pthread_create +- nptl: Add internal alias __pthread_getattr_default_np +- htl: Fix gsync_wait symbol exposition +- htl: Make pthread_cond_destroy wait for threads to be woken +- htl: Enable more cond tests +- tst-cond11: Fix build with _SC_MONOTONIC_CLOCK > 0 +- mbstowcs: Document, test, and fix null pointer dst semantics (Bug 25219) +- build: Use FAIL_EXIT1 () on failure to exec child [BZ #23990] +- manual: Fix backtraces code example [BZ #10441] +- hurd: Fix fexecve +- i386: Remove unused file sysdeps/unix/i386/sysdep.S +- hurd: fix ptsname error when called on a non-tty +- hurd: Fix fdopendir checking for directory type +- i386: Remove NO_TLS_DIRECT_SEG_REFS handling +- Hurd: Move internals into wrapper header +- Hurd: Use __sigmask in favor of deprecated sigmask +- hurd: Fix pselect atomicity +- elf: Remove extra hwcap mechanism from ldconfig +- elf: Do not read hwcaps from the vDSO in ld.so +- linux: Use internal DIR locks when accessing filepos on telldir +- Update i386 libm-test-ulps +- htl: Add clock variants +- signal: Deprecate additional legacy signal handling functions +- elf: Turn _dl_printf, _dl_error_printf, _dl_fatal_printf into functions +- x86: Update Intel Atom processor family optimization +- elf.h: add aarch64 property definitions +- elf.h: Add PT_GNU_PROPERTY +- : Add libpthread hidden alias support +- nptl: Use __pthread_attr_copy in pthread_setattr_default_np +- nptl: Use __pthread_attr_copy in pthread_getattr_default_np (bug 25999) +- nptl: Add __pthread_attr_copy for copying pthread_attr_t objects +- nptl: Make __pthread_attr_init, __pthread_attr_destroy available internally +- nptl: Move pthread_gettattr_np into libc +- nptl: Move pthread_getaffinity_np into libc +- nptl: Move pthread_attr_setaffinity_np into libc +- nptl: Replace some stubs with the Linux implementation +- Linux: Add missing handling of tai field to __ntp_gettime64 +- Mention GCC 10 attribute access. +- y2038: Replace __clock_gettime with __clock_gettime64 +- manual: Add missing section and node for clockid_t wait functions +- y2038: linux: Provide __ntp_gettimex64 implementation +- y2038: linux: Provide __ntp_gettime64 implementation +- y2038: Provide conversion helpers for struct __ntptimeval64 +- y2038: Introduce struct __ntptimeval64 - new internal glibc type +- y2038: linux: Provide __adjtime64 implementation +- y2038: linux: Provide ___adjtimex64 implementation +- y2038: linux: Provide __clock_adjtime64 implementation +- ldconfig: Default to the new format for ld.so.cache +- nss_compat: internal_end*ent may clobber errno, hiding ERANGE [BZ #25976] +- powerpc: Optimized rawmemchr for POWER9 +- x86: Add --enable-cet=permissive +- Remove NO_CTORS_DTORS_SECTIONS macro +- elf: Assert that objects are relocated before their constructors run +- powerpc: Optimized stpcpy for POWER9 +- powerpc: Optimized strcpy for POWER9 +- x86: Move CET control to _dl_x86_feature_control [BZ #25887] +- sunrpc/tst-udp-*: Fix timeout value +- Linux: Remove remnants of the getcpu cache +- Update timezone code from tzcode 2020a +- aarch64: fix strcpy and strnlen for big-endian [BZ #25824] +- locale: Add transliteration for Geresh, Gershayim (U+05F3, U+05F4) +- string: Fix string/tst-memmove-overflow to compile with GCC 7 +- Add arch-syscall.h dependency for generating sysd-syscalls file +- arm: XFAIL string/tst-memmove-overflow due to bug 25620 +- elf: Remove redundant add_to_global_resize_failure call from dl_open_args +- string: Add string/tst-memmove-overflow, a test case for bug 25620 +- support: Add support_blob_repeat_allocate_shared +- nptl: wait for pending setxid request also in detached thread (bug 25942) +- aarch64: Accept PLT calls to __getauxval within libc.so +- Use unsigned constants for ICMP6 filters [BZ #22489] +- Linux: Enhance glibcsyscalls.py to support listing system calls + +* Mon May 11 2020 DJ Delorie - 2.31.9000-13 +- Auto-sync with upstream branch master, + commit 978e8ac39f8ba2d694031e521511da1ae803ccfc. +- Suppress GCC 10 true positive warnings [BZ #25967] +- POWER: Add context-synchronizing instructions to pkey_write [BZ #25954] +- hurd: Add missing sigstate members initialization +- x86-64: Use RDX_LP on __x86_shared_non_temporal_threshold [BZ #25966] +- linux: Remove assembly umount2 implementation +- signal: Use for sigemptyset, sigfillset +- ckb_IQ, or_IN locales: Add missing reorder-end keywords +- semaphore: consolidate arch headers into a generic one +- Use GCC 10 branch in build-many-glibcs.py. +- Document the internal _ and N_ macros +- y2038: Provide conversion helpers for struct __timex64 +- y2038: Introduce struct __timex64 - new internal glibc type +- y2038: include: Move struct __timeval64 definition to a separate file +- y2038: nscd: Modify nscd_helper to use __clock_gettime64 +- y2038: inet: Convert inet deadline to support 64 bit time +- y2038: hurd: Provide __clock_gettime64 function +- y2038: Export __clock_gettime64 to be usable in other libraries +- manual: Document the O_NOFOLLOW open flag +- powerpc64le/power9: guard power9 strcmp against rtld usage [BZ# 25905] +- float128: use builtin_signbitf128 always +- improve out-of-bounds checking with GCC 10 attribute access [BZ #25219] +- nios2: delete sysdeps/unix/sysv/linux/nios2/kernel-features.h +- powerpc: Rename argN to _argN in LOADARGS_N [BZ #25902] +- locale/tst-localedef-path-norm: Don't create $(complocaledir) +- support: Set errno before testing it. +- localedef: Add tests-container test for --no-hard-links. +- test-container: Support $(complocaledir) and mkdirp. +- i386: Remove unused variable in sysdeps/x86/cacheinfo.c +- Add a C wrapper for prctl [BZ #25896] +- powerpc64le: Enable support for IEEE long double +- powerpc64le: blacklist broken GCC compilers (e.g GCC 7.5.0) +- powerpc64le: bump binutils version requirement to >= 2.26 +- powerpc64le: raise GCC requirement to 7.4 for long double transition +- Rename __LONG_DOUBLE_USES_FLOAT128 to __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI +- ldbl-128ibm-compat: workaround GCC 9 C++ PR90731 +- x86: Add the test case of __get_cpu_features support for Zhaoxin processors +- x86: Add cache information support for Zhaoxin processors +- x86: Add CPU Vendor ID detection support for Zhaoxin processors +- Update translations +- Add C wrappers for process_vm_readv/process_vm_writev [BZ #25810] +- generic/typesizes.h: Add support for 32-bit arches with 64-bit types +- semctl: Remove the sem-pad.h file +- bits/sem.h: Split out struct semid_ds +- Mark unsigned long arguments with U in more syscalls [BZ #25810] +- elf: Add initial flag argument to __libc_early_init +- Add SYSCALL_ULONG_ARG_[12] to pass long to syscall [BZ #25810] +- Makeconfig: Use $(error ...) to output error message +- manual: Fix typos in the fexecve description +- misc: Remove sstk from the autogenerated system call list +- Remove unused floating-point configuration from gmp-impl.h. +- support: Implement key create/delete +- nptl/tst-setuid1-static: Improve isolation from system objects +- Increase the timeout of locale/tst-localedef-path-norm +- Use 2020 as copyright year. +- misc: Turn sstk into a compat symbol +- manual: Document the fexecve function +- nptl: Start new threads with all signals blocked [BZ #25098] +- localedef: Add verbose messages for failure paths. +- Remove most gmp-mparam.h headers. +- elf: Implement __libc_early_init +- elf: Introduce +- Add a syscall test for [BZ #25810] +- elf: Support lld-style link map for librtld.map +- signal: Only handle on NSIG signals on signal functions (BZ #25657) +- linux: Use pthread_sigmask on sigprocmask +- ia64: Remove sigprocmask/sigblock objects from libpthread +- nptl: Move pthread_sigmask implementation to libc +- Bug 25819: Update to Unicode 13.0.0 + +* Wed Apr 29 2020 Florian Weimer - 2.31.9000-12 +- nss_db.x86_64 should install nss_db.i686 if glibc.i686 is installed (#1807821) +- Likewise for nss_hesiod. + +* Mon Apr 27 2020 Florian Weimer - 2.31.9000-11 +- Introduce glibc-headers-x86, glibc-headers-s390 packages (#1828332) +- Remove the glibc-headers package + +* Mon Apr 20 2020 DJ Delorie - 2.31.9000-10 +- Auto-sync with upstream branch master, + commit 0798b8ecc8da8667362496c1217d18635106c609. +- ARC: Update syscall-names.list for ARC specific syscalls +- Revert "x86_64: Add SSE sfp-exceptions" +- provide y2038 safe socket constants for default/asm-generic ABI +- x86_64: Add SSE sfp-exceptions +- Remove __NO_MATH_INLINES +- i686: Add INTERNAL_SYSCALL_NCS 6 argument support +- Reset converter state after second wchar_t output (Bug 25734) +- Fix typo in posix/tst-fnmatch.input (Bug 25790) + +* Wed Apr 15 2020 Patsy Griffin - 2.31.9000-9 +- Auto-sync with upstream branch master, + commit 076f09afbac1aa57756faa7a8feadb7936a724e4. +- Linux: Remove and the sysctl function +- posix: Add wait4 test case +- linux: wait4: Fix incorrect return value comparison +- hurd: add mach_print function +- x32: Properly pass long to syscall [BZ #25810] +- Add GRND_INSECURE from Linux 5.6 to sys/random.h +- Update kernel version to 5.6 in tst-mman-consts.py. + +* Wed Apr 15 2020 Florian Weimer - 2.31.9000-8 +- nsswitch.conf: don't add sss to shadow line + +* Wed Apr 08 2020 Carlos O'Donell - 2.31.9000-7 +- Auto-sync with upstream branch master, + commit b1caa144c74678097cada5a54eda2996bb459d8f. +- Update mips libm-test-ulps +- Update alpha libm-test-ulps +- Update ia64 libm-test-ulps +- Update sparc libm-test-ulps +- Update arm libm-test-ulps +- Update aarch64 libm-test-ulps +- Updates to the shn_MM locale [BZ #25532] +- powerpc: Update ULPs and xfail more ibm128 outputs +- i386: Remove build support for GCC older than GCC 6 +- oc_FR locale: Fix spelling of April (bug 25639) +- Update hppa libm-test-ulps +- y2038: linux: Provide __mq_timedreceive_time64 implementation +- y2038: linux: Provide __mq_timedsend_time64 implementation +- y2038: include: Move struct __timespec64 definition to a separate file +- malloc: ensure set_max_fast never stores zero [BZ #25733] +- powerpc64le: enforce non-specific long double in .gnu.attributes section +- powerpc64le: workaround ieee long double / _Float128 stdc++ bug +- powerpc64le: Enforce -mabi=ibmlongdouble when -mfloat128 used +- powerpc64le/multiarch: don't generate strong aliases for fmaf128-ppc64 +- ldbl-128ibm: simplify iscanonical.h +- i386: Disable check_consistency for GCC 5 and above [BZ #25788] +- Add IPPROTO_ETHERNET and IPPROTO_MPTCP from Linux 5.6 to netinet/in.h. +- Update syscall lists for Linux 5.6. +- elf: Implement DT_AUDIT, DT_DEPAUDIT support [BZ #24943] +- elf: Simplify handling of lists of audit strings +- support: Change xgetline to return 0 on EOF +- nptl: Remove x86_64 cancellation assembly implementations [BZ #25765] +- aarch64: update bits/hwcap.h +- Add tests for Safe-Linking +- S390: Regenerate ULPs. +- sysv/alpha: Use generic __timeval32 and helpers +- linux: Use long time_t for wait4/getrusage +- resource: Add a __rusage64 struct +- linux: Use long time_t __getitimer/__setitimer +- sysv: Define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 +- math: Add inputs that yield larger errors for float type (x86_64) + +* Tue Mar 31 2020 DJ Delorie - 2.31.9000-6 +- Auto-sync with upstream branch master, + commit 49c3c37651e2d2ec4ff8ce21252bbbc08a9d6639. +- Fix alignment bug in Safe-Linking +- Typo fixes and CR cleanup in Safe-Linking +- Use Linux 5.6 and GMP 6.2.0 in build-many-glibcs.py. +- Add new file missed in previous hppa commit. +- powerpc: Add support for fmaf128() in hardware +- Fix data race in setting function descriptors during lazy binding on hppa. +- sparc: Move __fenv_{ld,st}fsr to fenv-private.h +- x86: Remove feraiseexcept optimization +- math: Remove fenvinline.h +- hurd: Make O_TRUNC update mtime/ctime +- Add Safe-Linking to fastbins and tcache +- Add benchtests for roundeven and roundevenf. +- time: Add a __itimerval64 struct +- time: Add a timeval with a 32-bit tv_sec and tv_usec +- sysv/linux: Rename alpha functions to be alpha specific +- ARC: add definitions to elf/elf.h +- powerpc64: apply -mabi=ibmlongdouble to special files +- powerpc64le: add -mno-gnu-attribute to *f128 objects and difftime +- Makeconfig: sandwich gnulib-tests between libc/ld linking of tests +- powerpc64le: Ensure correct ldouble compiler flags are used +- Fix tests which expose ldbl -> _Float128 redirects +- ldbl-128ibm-compat: PLT redirects for using ldbl redirects internally + +* Wed Mar 25 2020 Patsy Franklin - 2.31.9000-5 +- Auto-sync with upstream branch master, + commit 4eda036f5b897fa8bc20ddd2099b5a6ed4239dc9. +- stdlib: Move tst-system to tests-container +- support/shell-container.c: Add builtin kill +- support/shell-container.c: Add builtin exit +- support/shell-container.c: Return 127 if execve fails +- Add NEWS entry for CVE-2020-1751 (bug 25423) +- posix: Fix system error return value [BZ #25715] +- y2038: fix: Add missing libc_hidden_def attribute for some syscall wrappers +- Extended Char Intro: Use getwc in example (Bug 25626) +- stdio: Add tests for printf multibyte convertion leak [BZ#25691] +- stdio: Remove memory leak from multibyte convertion [BZ#25691] +- Add NEWS entry for CVE-2020-1752 (bug 25414) +- math: Remove inline math tests +- Remove __LIBC_INTERNAL_MATH_INLINES +- math: Remove mathinline +- m68k: Remove mathinline.h +- oc_FR locale: Fix spelling of Thursday (bug 25639) +- x86: Remove ARCH_CET_LEGACY_BITMAP [BZ #25397] +- Fix build with GCC 10 when long double = double. +- nscd/cachedumper.c : fix whitespace +- Fix nscd/cachedumper.c compile errors +- manual: Fix inconsistent declaration of wcsrchr [BZ #24655] +- nscd: add cache dumper + +* Fri Mar 13 2020 Patsy Franklin - 2.31.9000-4 +- Auto-sync with upstream branch master, + commit 2de7fe62534b7a6461c633114f03e9dff394f5f7. +- parse_tunables: Fix typo in comment +- ldconfig: trace origin paths with -v +- test-container: print errno when execvp fails +- [AArch64] Improve integer memcpy +- Add NEWS entry for CVE-2020-10029 (bug 25487) +- gcc PR 89877: miscompilation due to missing cc clobber in longlong.h macros +- mips: Fix wrong INTERNAL_SYSCALL_ERROR_P check from bc2eb9321e +- elf: Fix wrong indentation from commit eb447b7b4b +- y2038: linux: Provide __futimesat64 implementation +- y2038: linux: Provide __lutimes64 implementation +- y2038: linux: Provide __futimes64 implementation +- y2038: fix: Add missing libc_hidden_def for __futimens64 +- sparc: Move sigreturn stub to assembly +- ldbl-128ibm: Let long double files have specific compiler flags +- ldbl-128ibm-compat: Add tests for IBM long double functions +- powerpc: Fix feraiseexcept and feclearexcept macros +- arm: Fix softp-fp Implies (BZ #25635) +- Remove reference of --without-fp on configure +- linux/sysipc: Include linux/posix_types.h for __kernel_mode_t +- Improve IFUNC check [BZ #25506] +- linux: Clear mode_t padding bits (BZ#25623) +- linux: Remove aarch64 ipc_priv.h +- Linux: Use __fstatat64 in fchmodat implementation +- Linux: Use AT_FDCWD in utime, utimes when calling utimensat +- S390: Remove backchain-based fallback and use generic backtrace.c. +- manual: Fix wrong declaration of wcschr [BZ #24654] +- manual: Fix typo in parse_printf_format example [BZ #24638] + +* Thu Mar 5 2020 Florian Weimer - 2.31.9000-3 +- Emergency patch for broken utimes/utime functions + +* Tue Mar 03 2020 Patsy Franklin - 2.31.9000-2 +- Auto-sync with upstream branch master, + commit 78c9d0c6efabe2067ef7f93cd36325f54c60adc2. +- Update translations +- Convert Python scripts to Python 3 +- alpha: Do not build with -fpic +- y2038: linux: Provide __utime64 implementation +- y2038: linux: Provide __utimes64 implementation +- y2038: Introduce struct __utimbuf64 - new internal glibc type +- microblaze: vfork is always available +- m68k: getpagesize syscall number is always available +- Linux: epoll_pwait syscall number is always available +- x86_64: Do not define __NR_semtimedop in +- ia64: Do not define __NR_semtimedop in +- Linux: open_by_handle_at syscall number is always available +- Linux: set_robust_list syscall number is always available +- Linux: pciconfig_iobase syscall number is always available on alpha +- Linux: getdents64 syscall number is always available on MIPS +- Linux: Clean up preadv2, pwritev2 system call names +- Linux: exit_group syscall number is always available +- Linux: set_tid_address syscall number is always available +- Linux: pkey_mprotect syscall number is always available +- Linux: rt_sigqueueinfo syscall number is always available +- Linux: getrandom syscall number is always available +- Linux: Clean up preadv, pwritev system call names +- Linux: Clean up pread64/pwrite64 system call names +- Linux: sigaltstack syscall number is always available +- Linux: sched_getaffinity syscall number is always available +- Linux: sched_setaffinity syscall number is always available +- Linux: statx syscall number is always available +- Linux: mq_* syscall numbers are always available +- Linux: mlock2 syscall number is always available +- Linux: copy_file_range syscall number is always available +- Linux: renameat2 syscall number is always available +- build-many-glibcs.py: Add list-compilers, list-glibcs commands +- build-many-glibcs.py: Add --shallow option +- Fixed typo in run_command_array() in support/shell-container.c +- Add missing libc_hidden_def for __utimensat64 +- elf: Add elf/check-wx-segment, a test for the presence of WX segments +- i386: Use comdat instead of .gnu.linkonce for i386 setup pic register (BZ #20543) +- ldbl-128ibm-compat: link tst-ldbl-efgcvt against loader too +- ldbl-128ibm-compat: enforce ibm128 on compat tests +- ldbl-128ibm-compat: Provide nexttoward functions +- ldbl-128ibm-compat: Provide a significand implementation +- ldbl-128ibm-compat: Redirect complex math functions +- ldbl-128ibm-compat: Redirect long double functions to f128/ieee128 functions +- posix: Remove posix waitid +- posix: Refactor tst-waitid (BZ #14666) +- support: Add support_process_state_wait +- malloc/tst-mallocfork2: Kill lingering process for unexpected failures + +* Wed Feb 26 2020 Patsy Franklin - 2.31.9000-1 +- Auto-sync with upstream branch master, + commit 758599bc9dcc5764e862bd9e1613c5d1e6efc5d3. +- elf: Apply attribute_relro to pointers in elf/dl-minimal.c +- powerpc: Refactor fenvinline.h +- nss_nis: Use NSS_DECLARE_MODULE_FUNCTIONS +- csu: Use ELF constructor instead of _init in libc.so +- ldbl-128ibm: make ieee754.h work with IEEE 128 long double +- ldbl-128ibm-compat: fixup subdir location of several funcs +- ldbl-128ibm-compat: enforce correct abi flags on internal file +- ldbl-128ibm-compat: Provide ieee128 symbols to narrow functions +- Undefine redirections after long double definition on __LDBL_COMPAT [BZ #23294] +- nios2: Fix Linux kABI for syscall return +- Fix use-after-free in glob when expanding ~user (bug 25414) +- nptl: Move pthread_setschedparam implementation into libc +- nptl: Move pthread_getschedparam implementation into libc +- Add hidden prototypes for __sched_getparam, __sched_getscheduler +- nptl: Move pthread_cond_init implementation into libc +- nptl: Move pthread_cond_destroy implementation into libc +- nptl: Move pthread_condattr_init implementation into libc +- nptl: Move pthread_condattr_destroy implementation into libc +- nptl: Move pthread_attr_setscope implementation into libc +- nptl: Move pthread_attr_getscope implementation into libc +- nptl: Move pthread_attr_setschedpolicy implementation into libc +- nptl: Move pthread_attr_getschedpolicy implementation into libc +- nptl: Sort routines list in Makefile alphabetically +- nptl: Use .NOTPARALLEL in Makefile only if actually running tests +- Block all signals on timer_create thread (BZ#10815) +- Fix tst-pkey expectations on pkey_get [BZ #23202] +- y2038: linux: Provide __gettimeofday64 implementation +- Linux: Work around kernel bugs in chmod on /proc/self/fd paths [BZ #14578] +- Introduce and ELF_INITFINI for all architectures +- mips: Fix bracktrace result for signal frames +- Move implementation of into a C file +- : Add type safety and port to Hurd +- Prepare redirections for IEEE long double on powerpc64le +- conform/conformtest.py: Extend tokenizer to cover character constants +- stdlib: Reduce namespace pollution in +- x86: Avoid single-argument _Static_assert in +- x86 tls: Use _Static_assert for TLS access size assertion +- htl: Link internal htl tests against libpthread +- pthread: Fix building tst-robust8 with nptl +- pthread: Move robust mutex tests from nptl to sysdeps/pthread +- htl: Remove stub warning for pthread_mutexattr_setpshared +- htl: Add missing functions and defines for robust mutexes +- htl: Only check pthread_self coherency when DEBUG is set +- hurd: Add THREAD_GET/SETMEM/_NC +- hurd tls: update comment about fields at the end of tcbhead +- ld.so: Do not export free/calloc/malloc/realloc functions [BZ #25486] +- Remove weak declaration of free from +- elf: Extract _dl_sym_post, _dl_sym_find_caller_map from elf/dl-sym.c +- elf: Introduce the rtld-stubbed-symbols makefile variable +- arm: fix use of INTERNAL_SYSCALL_CALL +- linux: Remove INTERNAL_SYSCALL_DECL +- nptl: Remove ununsed pthread-errnos.h rule +- linux: Consolidate INLINE_SYSCALL +- s390: Consolidate Linux syscall definition +- riscv: Avoid clobbering register parameters in syscall +- microblaze: Avoid clobbering register parameters in syscall +- nios2: Use Linux kABI for syscall return +- mips: Use Linux kABI for syscall return +- mips64: Consolidate Linux sysdep.h +- ia64: Use Linux kABI for syscall return +- alpha: Refactor syscall and Use Linux kABI for syscall return +- sparc: Avoid clobbering register parameters in syscall +- sparc: Use Linux kABI for syscall return +- powerpc: Use Linux kABI for syscall return +- powerpc: Consolidate Linux syscall definition +- i386: Enable CET support in ucontext functions +- tst-clone3: Use __NR_futex_time64 if we don't have __NR_futex +- powerpc64: Add memory protection key support [BZ #23202] +- ldbl-128ibm-compat: Provide a scalb implementation +- Add a generic scalb implementation +- Adjust thresholds in Bessel function implementations (bug 14469). +- resolv: Fix ABA race in /etc/resolv.conf change detection [BZ #25420] +- resolv: Enhance __resolv_conf_load to capture file change data +- resolv: Fix file handle leak in __resolv_conf_load [BZ #25429] +- resolv: Use in __resolv_conf_get_current +- Add STATX_ATTR_VERITY from Linux 5.5 to bits/statx-generic.h. +- Use gcc -finput-charset=ascii for check-installed-headers. +- math/test-sinl-pseudo: Use stack protector only if available +- alpha: Fix static gettimeofday symbol +- nss_nisplus: Use NSS_DECLARE_MODULE_FUNCTIONS +- nss_dns: Use NSS_DECLARE_MODULE_FUNCTIONS +- nss_files: Use NSS_DECLARE_MODULE_FUNCTIONS +- nss_db: Use NSS_DECLARE_MODULE_FUNCTIONS +- nss_compat: Use NSS_DECLARE_MODULE_FUNCTIONS +- nss_hesiod: Use NSS_DECLARE_MODULE_FUNCTIONS +- nss: Add function types and NSS_DECLARE_MODULE_FUNCTIONS macro to +- nss_compat: Do not use nss_* names for function pointers +- Avoid ldbl-96 stack corruption from range reduction of pseudo-zero (bug 25487). +- mips: Fix argument passing for inlined syscalls on Linux [BZ #25523] +- mips: Use 'long int' and 'long long int' in linux syscall code +- alpha: Use generic gettimeofday implementation +- sunrpc: Properly clean up if tst-udp-timeout fails +- elf: avoid stack allocation in dl_open_worker +- elf: avoid redundant sort in dlopen +- elf: Allow dlopen of filter object to work [BZ #16272] +- Update translations +- Rename RWF_WRITE_LIFE_NOT_SET to RWH_WRITE_LIFE_NOT_SET following Linux 5.5. +- S390: Fix non-ascii character in fenv.h. +- io: Add io/tst-lchmod covering lchmod and fchmodat +- Linux: Emulate fchmodat with AT_SYMLINK_NOFOLLOW using O_PATH [BZ #14578] +- io: Implement lchmod using fchmodat [BZ #14578] +- Add internal header file +- elf.h: Add R_RISCV_IRELATIVE +- Fix typo in the name for Wednesday in Kurdish [BZ #9809] +- debug: Add missing locale dependencies of fortify tests +- htl C11 threads: Avoid pthread_ symbols visibility in static library +- hurd: Add __pthread_spin_wait and use it +- ldbl-128ibm-compat: set PRINTF_CHK flag in {,v}sprintf_chk +- Use --disable-gdbserver in build-many-glibcs.py. +- Improve random memcpy benchmark +- nptl: update default pthread-offsets.h +- nptl: add missing pthread-offsets.h +- htl: Avoid a local plt for pthread_self +- pthread: Move some join tests from nptl to sysdeps/pthread +- htl: Make joining self return EDEADLK +- pthread: Move most barrier tests from nptl to sysdeps/pthread +- htl: Fix barrier_wait with one thread +- pthread: Move most sem tests from nptl to sysdeps/pthread +- htl: Make sem_wait/sem_timedwait interruptible +- htl: Make sem_open return ENOSYS +- htl: Add support for semaphore maximum value +- pthread: Move key tests from nptl to sysdeps/pthread +- hurd: Make nanosleep a cancellation point +- htl: Add support for libc cancellation points +- htl: clean __pthread_get_cleanup_stack hidden proto +- htl: XFAIL rwlock tests which need pshared support +- pthread: Move some rwlock tests from nptl to sysdeps/pthread +- pthread: Move most once tests from nptl to sysdeps/pthread +- htl: support cancellation during pthread_once +- pthread: Move most cond tests from nptl to sysdeps/pthread +- htl: make pthread_cond_destroy return EBUSY on waiters +- htl: Report missing mutex lock on pthread_cond_*wait +- htl: Fix linking static testcases +- htl: Move __register_atfork from forward to own file +- pthread: Move some attr tests from nptl to sysdeps/pthread +- htl: Fix default guard size +- pthread: Move most mutex tests from nptl to sysdeps/pthread +- pthread: Move spin tests from nptl to sysdeps/pthread +- htl: make pthread_spin_lock really spin +- htl: Avoid check-installed-headers looking at inlines +- htl: Do not put spin_lock inlines in public headers +- pthread: Move basic tests from nptl to sysdeps/pthread +- htl: Fix calling pthread_exit in the child of a fork +- x86: Remove and use the generic version +- C11 threads: Move implementation to sysdeps/pthread +- htl: Add C11 threads types definitions +- C11 threads: make thrd_join more portable +- C11 threads: Fix thrd_t / pthread_t compatibility assertion +- C11 threads: do not require PTHREAD_DESTRUCTOR_ITERATIONS +- nptl: Move nptl-specific types to separate header +- htl: Make __PTHREAD_ONCE_INIT more flexible +- htl: Add support for C11 threads behavior +- htl: Add missing internal functions declarations +- htl: Rename _pthread_mutex_init/destroy to __pthread_mutex_init/destroy +- htl: Move internal mutex/rwlock symbols to GLIBC_PRIVATE +- Linux: Add io/tst-o_path-locks test +- support: Add the xlstat function +- htl: Remove duplicate files +- htl: Remove unused files +- resolv: Fix CNAME chaining in resolv/tst-resolv-ai_idn-common.c +- Remove a comment claiming that sin/cos round correctly. +- y2038: linux: Provide __settimeofday64 implementation +- y2038: Provide conversion helpers for struct __timeval64 +- y2038: alpha: Rename valid_timeval64_to_timeval to valid_timeval_to_timeval32 +- y2038: alpha: Rename valid_timeval_to_timeval64 to valid_timeval32_to_timeval +- y2038: Introduce struct __timeval64 - new internal glibc type +- y2038: Define __suseconds64_t type to be used with struct __timeval64 +- Update kernel version to 5.5 in tst-mman-consts.py. +- Update syscall lists for Linux 5.5. +- NEWS: Set fill-column hint to 72 +- y2038: linux: Provide __timespec_get64 implementation +- Use binutils 2.34 branch in build-many-glibcs.py. +- Run nptl/tst-pthread-getattr in a container +- test-container: add exec, cwd +- Use Linux 5.5 in build-many-glibcs.py. +- rt: avoid PLT setup in timer_[sg]ettime +- Update or_IN collation [BZ #22525] +- Fix ckb_IQ [BZ #9809] +- Add new locale: ckb_IQ (Kurdish/Sorani spoken in Iraq) [BZ #9809] +- list-fixed-bugs.py: Wrap at 72 chars +- y2038: linux: Provide __sched_rr_get_interval64 implementation +- y2038: linux: Provide __timerfd_settime64 implementation +- y2038: linux: Provide __timerfd_gettime64 implementation +- i386: Remove _exit.S +- i386: Use ENTRY/END in assembly codes +- i386-mcount.S: Add _CET_ENDBR to _mcount and __fentry__ +- i386/sub_n.S: Add a missing _CET_ENDBR to indirect jump target +- i386: Don't unnecessarily save and restore EAX, ECX and EDX [BZ# 25262] +- x86: Don't make 2 calls to dlerror () in a row +- Open master for 2.32 development + +* Mon Feb 03 2020 DJ Delorie - 2.31-1 +- Auto-sync with upstream branch release/2.31/master, + commit 9ea3686266dca3f004ba874745a4087a89682617. +- glibc 2.31 release +- Generate ChangeLog.old/ChangeLog.20 for 2.31 +- Add bugs fixed in 2.31 in NEWS +- Update newest tested versions of dependencies in install.texi +- Add more contributors to the manual +- Add note to NEWS about kernel headers dependency on risc-v +- Add Portuguese (Portugal) translation +- Add NEWS entry about 64-bit time_t syscall use on 32-bit targets +- nptl: Avoid using PTHREAD_MUTEX_DEFAULT in macro definition [BZ #25271] + +* Thu Jan 30 2020 Patsy Franklin - 2.30.9000-33 +- Auto-sync with upstream branch master, + commit 352bb99754ae7c83ff1b974f9c52244e974c9410. +- Build raise with -fasynchronous-unwind-tables. +- Fix locale/tst-locale-locpath cross-testing when sshd sets LANG. +- Fix elf/tst-rtld-preload cross-testing. +- Fix cross-testing of tst-ifunc-fault-* tests. +- gitlog-to-changelog: Drop scripts in favour of gnulib version +- Add NEWS entry about the change in handling of PT_GNU_STACK on MIPS +- Fix array overflow in backtrace on PowerPC (bug 25423) +- getaddrinfo: Fix resource leak after strdup failure in gethosts (swbz#25425) + +* Tue Jan 28 2020 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Mon Jan 20 2020 Patsy Franklin - 2.30.9000-31 +- Auto-sync with upstream branch master, + commit 92ce43eef7ac844782d50a8015d977d216fbadec. +- Run bench-timing-type with newly built libc. +- Get rid of Werror=maybe-uninitialized in res_send.c. +- translations: Update translations +- translations: Trim po files using msgattrib +- Update translations +- translations: Run msgmerge when downloading translations +- Fix maybe-uninitialized error on powerpc +- powerpc32: Fix syntax error in __GLRO macro +- Remove incorrect alloc_size attribute from pvalloc (swbz#25401) + +* Fri Jan 17 2020 Florian Weimer - 2.30.9000-30 +- Auto-sync with upstream branch master, + commit 70ba28f7ab2923d4e36ffc9d5d2e32357353b25c: +- Fix tst-pkey.c pkey_alloc return checks and manual +- powerpc: Move cache line size to rtld_global_ro +- powerpc: Initialize rtld_global_ro for static dlopen (swbz#20802) +- Revert outdated translations +- vcs-to-changelog: Add quirk for __nonnull +- elf: Add elf/tst-dlopenfail-2 (swbz#25396, #1395758) +- Clear GL(dl_initfirst) when freeing its link_map (swbz#25396, #1395758) +- Update Translations +- Fix "elf: Add tst-ldconfig-ld_so_conf-update test" on 32bit. +- elf: Add tst-ldconfig-ld_so_conf-update test +- sl_SI locale: Use "." as the thousands separator (swbz#25233) + +* Mon Jan 06 2020 Arjun Shankar - 2.30.9000-29 +- Auto-sync with upstream branch master, + commit cbce69e70dc4b04fefcc7257e593733b8b03856c: +- Multiple locales: Add date_fmt (bug 24054) +- Update libc.pot for 2.31 release +- Add libm_alias_finite for _finite symbols +- Linux: Fix clock_nanosleep time64 check +- linux: Fix vDSO macros build with time64 interfaces +- x86: Make x32 use x86 time implementation +- Remove vDSO support from make-syscall.sh +- linux: Update x86 vDSO symbols +- linux: Update mips vDSO symbols +- linux: Consolidate Linux gettimeofday +- linux: Consolidate time implementation +- elf: Enable relro for static build +- elf: Move vDSO setup to rtld (BZ#24967) +- linux: Add support for clock_gettime64 vDSO +- linux: Optimize fallback 32-bit clock_gettime +- linux: Enable vDSO clock_gettime64 for i386 +- linux: Enable vDSO clock_gettime64 for arm +- linux: Enable vDSO clock_gettime64 for mips +- linux: Add support for clock_getres64 vDSO +- linux: Optimize fallback 32-bit clock_getres +- htl: Use dso_handle.h +- htl: Drop common tcbhead_t definition +- htl: Move pthread_atfork to libc_nonshared.a +- htl: Add __errno_location and __h_errno_location +- hurd: Fix message reception for timer_thread + +* Thu Jan 02 2020 Florian Weimer - 2.30.9000-28 +- Auto-sync with upstream branch master, + commit cc47d5c5f53f6d845ac54698ae8929af15662c44: +- Linux: Use built-in system call tables +- lv_LV locale: Correct the time part of d_t_fmt (swbz#25324) +- km_KH locale: Use "%M" instead of "m" in d_t_fmt (swbz#25323) +- ldbl-128ibm-compat: Do not mix -mabi=*longdouble and -mlong-double-128 +- ldbl-128ibm-compat: Compiler flags for stdio functions +- Do not redirect calls to __GI_* symbols, when redirecting to *ieee128 +- aarch64: add default memcpy version for kunpeng920 +- aarch64: ifunc rename for kunpeng +- aarch64: Modify error-shown comments for strcpy +- linux: Consolidate sigprocmask +- Fix return code for __libc_signal_* functions +- nptl: Remove duplicate internal __SIZEOF_PTHREAD_MUTEX_T (swbz#25241) + +* Thu Dec 26 2019 Carlos O'Donell - 2.30.9000-27 +- Auto-sync with upstream branch master, + commit b8c210bcc74840d24c61d39bde15bea9daf3e271. +- mnw_MM, my_MM, and shn_MM locales: Do not use %Op +- Avoid compat symbols for totalorder in powerpc64le IEEE long double +- ldbl-128ibm-compat: Add *cvt functions +- Refactor *cvt functions implementation (2/2) +- Refactor *cvt functions implementation (1/2) +- Add exception-based flags for wait4 +- aarch64: Optimized memset for Kunpeng processor. +- aarch64: Optimized strlen for strlen_asimd +- aarch64: Add Huawei Kunpeng to tunable cpu list +- aarch64: Optimized implementation of memrchr +- aarch64: Optimized implementation of strnlen +- aarch64: Optimized implementation of strcpy +- aarch64: Optimized implementation of memcmp +- Consolidate wait3 implementations +- Implement waitpid in terms of wait4 +- linux: Use waitid on wait4 if __NR_wait4 is not defined +- Implement wait in terms of waitpid +- nptl: Move waitpid implementation to libc +- nptl: Move wait implementation to libc +- Remove __waitpid_nocancel +- Fix test isolation for elf/tst-ifunc-fault-lazy, elf/tst-ifunc-fault-bindnow +- Fix __libc_signal_block_all on sparc64 +- powerpc: Do not run IFUNC resolvers for LD_DEBUG=unused [BZ #24214] + +* Thu Dec 19 2019 Patsy Franklin - 2.30.9000-26 +- Auto-sync with upstream branch master, + commit 3dcad8158f43d71d5b8f6f317f82952ddf3468f3. +- hurd: Do not make sigprocmask available in ld.so +- build-many-glibcs.py: Do not build C++ PCHs by default +- hurd: Make getrandom honour GRND_NONBLOCK +- tunables: report sbrk() failure +- build-many-glibcs.py: Add mipsisa64r6el-linux-gnu target +- mips: Do not include hi and lo in __SYSCALL_CLOBBERS for R6 +- ldbl-128ibm-compat: Add ISO C99 versions of scanf functions +- ldbl-128ibm-compat: Fix selection of GNU and ISO C99 scanf +- hurd: Fix local PLT +- dlopen: Do not block signals +- dlopen: Rework handling of pending NODELETE status +- dlopen: Fix issues related to NODELETE handling and relocations +- hurd: Fix __close_nocancel_nostatus availability +- hurd: add getrandom and getentropy implementations +- hurd: Implement __close_nocancel_nostatus +- manual: clarify fopen with the x flag +- S390: Use sysdeps/ieee754/dbl-64/wordsize-64 on s390x. +- S390: Implement roundtoint and converttoint and define TOINT_INTRINSICS. +- S390: Implement math-barriers math_opt_barrier and math_force_eval. +- S390: Use libc_fe* macros in fe* functions. +- S390: Implement libc_fe* macros. +- S390: Use convert-to-fixed instruction for llround functions. +- S390: Use convert-to-fixed instruction for lround functions. +- S390: Use convert-to-fixed instruction for llrint functions. +- S390: Use convert-to-fixed instruction for lrint functions. +- S390: Use load-fp-integer instruction for roundeven functions. +- Adjust s_copysignl.c regarding code style. +- Adjust s_ceilf.c and s_ceill.c regarding code style. +- Adjust s_floorf.c and s_floorl.c regarding code style. +- Adjust s_rintf.c and s_rintl.c regarding code style. +- Adjust s_nearbyintf.c and s_nearbyintl.c regarding code style. +- Use GCC builtins for copysign functions if desired. +- Use GCC builtins for round functions if desired. +- Use GCC builtins for trunc functions if desired. +- Use GCC builtins for ceil functions if desired. +- Use GCC builtins for floor functions if desired. +- Use GCC builtins for rint functions if desired. +- Use GCC builtins for nearbyint functions if desired. +- Always use wordsize-64 version of s_round.c. +- Always use wordsize-64 version of s_trunc.c. +- Always use wordsize-64 version of s_ceil.c. +- Always use wordsize-64 version of s_floor.c. +- Always use wordsize-64 version of s_rint.c. +- Always use wordsize-64 version of s_nearbyint.c. +- ldconfig: Do not print a warning for a missing ld.so.conf file +- hurd: Fix using altstack while in an RPC call to be aborted +- Fix failure when CFLAGS contains -DNDEBUG (Bug 25251) + +* Mon Dec 09 2019 DJ Delorie - 2.30.9000-25 +- Auto-sync with upstream branch master, + commit 0487ebed2278b20971af4cabf186fd3681adccf0. +- nptl: Add more missing placeholder abi symbol from nanosleep move +- sysdeps/riscv/start.S: rename .Lload_gp to load_gp (bug 24376) +- y2038: linux: Provide __timer_settime64 implementation +- y2038: linux: Provide __timer_gettime64 implementation +- timer: Decouple x86_64 specific timer_settime from generic Linux implementation +- timer: Decouple x86_64 specific timer_gettime from generic Linux implementation +- time: Introduce glibc's internal struct __itimerspec64 +- Correct range checking in mallopt/mxfast/tcache [BZ #25194] +- misc/test-errno-linux: Handle EINVAL from quotactl +- : Define __CORRECT_ISO_CPP_STRING_H_PROTO for Clang [BZ #25232] +- build-many-glibcs.py: Move sparcv8 to extra_glibcs + +* Thu Dec 5 2019 Florian Weimer - 2.30.9000-24 +- Upstream patches for fallout from dlopen NODELETE changes (#1778344, #1778366) + +* Wed Dec 04 2019 Patsy Franklin - 2.30.9000-23 +- Auto-sync with upstream branch master, + commit ec138c67cbda8b5826a0a2a7ba456408117996dc. +- sysdeps: Add clock_gettime64 vDSO +- Do not use ld.so to open statically linked programs in debugglibc.sh +- Attach to test in container from debugglibc.sh +- Expand $(as-needed) and $(no-as-needed) throughout the build system +- x86: Assume --enable-cet if GCC defaults to CET [BZ #25225] +- ldbl-128ibm-compat: Add tests for strfroml, strtold, and wcstold +- ldbl-128ibm-compat: Add tests for strfmon and strfmon_l +- ldbl-128ibm-compat: Add strfmon_l with IEEE long double format +- ldbl-128ibm-compat: Replace http with https in new files +- elf: Do not run IFUNC resolvers for LD_DEBUG=unused [BZ #24214] +- elf/tst-dlopenfail: Disable --no-as-needed for tst-dlopenfailmod1.so +- hurd: Fix ld.so __access override from libc +- hurd: Fix ld.so __getcwd override from libc +- hurd: Make __sigprocmask GLIBC_PRIVATE +- hurd: Fix renameat2 error +- hurd: make strerror(0) coherent with other ports +- hurd: Fix ld.so link +- Update kernel version to 5.4 in tst-mman-consts.py. +- Update SOMAXCONN value from Linux 5.4. +- Update syscall-names.list for Linux 5.4. +- Fix syntax error in build-many-glibcs.py. +- Define MADV_COLD and MADV_PAGEOUT from Linux 5.4. + +* Mon Dec 2 2019 Florian Weimer - 2.30.9000-22 +- dlopen: Remove incorrect assert in activate_nodelete (#1778344) + +* Thu Nov 28 2019 Florian Weimer - 2.30.9000-21 +- Auto-sync with upstream branch master, + commit e37c2cf299b61ce18f62852f6c5624c27829b610: +- Move _dl_open_check to its original place in dl_open_worker +- Block signals during the initial part of dlopen +- Remove all loaded objects if dlopen fails, ignoring NODELETE (#1395758) +- Avoid late dlopen failure due to scope, TLS slotinfo updates (swbz#25112) +- Avoid late failure in dlopen in global scope update (swbz#25112) +- Lazy binding failures during dlopen/dlclose must be fatal (swbz#24304) +- resolv: Implement trust-ad option for /etc/resolv.conf (#1164339) +- dlsym: Do not determine caller link map if not needed +- libio: Disable vtable validation for pre-2.1 interposed handles (swbz#25203) +- ldbl-128ibm-compat: Add syslog functions +- ldbl-128ibm-compat: Add obstack printing functions +- ldbl-128ibm-compat: Reuse tests for err.h and error.h functions +- ldbl-128ibm-compat: Add error.h functions +- ldbl-128ibm-compat: Add err.h functions +- ldbl-128ibm-compat: Add argp_error and argp_failure +- sparc: Use atomic compiler builtins on sparc +- Remove 32 bit sparc v7 support + +* Wed Nov 27 2019 Arjun Shankar - 2.30.9000-20 +- Auto-sync with upstream branch master, + commit bfdb731438206b0f70fe7afa890681155c30b419: +- rtld: Check __libc_enable_secure for LD_PREFER_MAP_32BIT_EXEC (CVE-2019-19126) +- Introduce DL_LOOKUP_FOR_RELOCATE flag for _dl_lookup_symbol_x +- Enable inlining issignalingf within glibc +- Don't use a custom wrapper macro around __has_include (bug 25189). +- Remove duplicate inline implementation of issignalingf +- misc: Set generic pselect as ENOSYS +- Use DEPRECATED_SCANF macro for remaining C99-compliant scanf functions +- ldbl-128ibm-compat: Add regular/wide character printing printing functions +- ldbl-128ibm-compat: Test double values and positional arguments +- ldbl-128ibm-compat: Add regular/wide character scanning functions +- arm: Fix armv7 selection after 'Split BE/LE abilist' +- Use Linux 5.4 in build-many-glibcs.py. +- sysdeps/posix: Simplify if expression in getaddrinfo +- sysdeps/posix/getaddrinfo: Return early on invalid address family +- ru_UA locale: use copy "ru_RU" in LC_TIME (bug 25044) +- locale: Greek -> ASCII transliteration table [BZ #12031] +- nptl: Cleanup mutex internal offset tests +- nptl: Add tests for internal pthread_rwlock_t offsets +- nptl: Remove rwlock elision definitions +- nptl: Add struct_mutex.h and struct_rwlock.h +- nptl: Add default pthreadtypes-arch.h and pthread-offsets.h +- Compile elf/rtld.c with -fno-tree-loop-distribute-patterns. +- nptl: Fix __PTHREAD_MUTEX_INITIALIZER for !__PTHREAD_MUTEX_HAVE_PREV +- S390: Fix handling of needles crossing a page in strstr z15 ifunc [BZ #25226] + +* Mon Nov 18 2019 Patsy Griffin - 2.30.9000-19 +- Auto-sync with upstream branch master, + commit 2a764c6ee848dfe92cb2921ed3b14085f15d9e79. +- Enhance _dl_catch_exception to allow disabling exception handling +- hurd: Suppress GCC 10 -Warray-bounds warning in init-first.c [BZ #25097] +- linux: Add comment on affinity set sizes to tst-skeleton-affinity.c +- Avoid zero-length array at the end of struct link_map [BZ #25097] +- Introduce link_map_audit_state accessor function +- Properly initialize audit cookie for the dynamic loader [BZ #25157] +- nios2: Work around backend bug triggered by csu/libc-tls.c (GCC PR 92499) +- Redefine _IO_iconv_t to store a single gconv step pointer [BZ #25097] +- Add new script for plotting string benchmark JSON output +- support: Fix support_set_small_thread_stack_size to build on Hurd +- login: Use pread64 in utmp implementation +- Clarify purpose of assert in _dl_lookup_symbol_x +- aarch64: Increase small and medium cases for __memcpy_generic +- login: Introduce matches_last_entry to utmp processing + +* Tue Nov 12 2019 Arjun Shankar - 2.30.9000-18 +- Auto-sync with upstream branch master, + commit cba932a5a9e91cffd7f4172d7e91f9b2efb1f84b: +- nptl: Move nanosleep implementation to libc +- Refactor nanosleep in terms of clock_nanosleep +- nptl: Refactor thrd_sleep in terms of clock_nanosleep +- math: enhance the endloop condition of function handle_input_flag +- hurd: Remove lingering references to the time function +- hurd: Use __clock_gettime in _hurd_select +- login: Remove double-assignment of fl.l_whence in try_file_lock +- nptl: Add missing placeholder abi symbol from nanosleep move +- login: Acquire write lock early in pututline [BZ #24882] +- Remove hppa pthreadP.h +- sysdeps/clock_nanosleep: Use clock_nanosleep_time64 if avaliable +- Fix array bounds violation in regex matcher (bug 25149) +- support: Add support_set_small_thread_stack_size +- linux: Reduce stack size for nptl/tst-thread-affinity-pthread +- y2038: linux: Provide __ppoll64 implementation +- Declare asctime_r, ctime_r, gmtime_r, localtime_r for C2X. +- support: Add xsetlocale function +- libio/tst-fopenloc: Use xsetlocale, xfopen, and xfclose +- Fix clock_nanosleep when interrupted by a signal +- slotinfo in struct dtv_slotinfo_list should be flexible array [BZ #25097] + +* Wed Nov 06 2019 Patsy Franklin - 2.30.9000-17 +- Auto-sync with upstream branch master, + commit 2a0356e1191804d57005e1cfe2a72f019b7a8cce. +- posix: Sync regex with gnulib +- Add mnw language code [BZ #25139] +- Add new locale: mnw_MM (Mon language spoken in Myanmar) [BZ #25139] +- S390: Fp comparison are now raising FE_INVALID with gcc 10. +- linux: pselect: Remove CALL_PSELECT6 macro +- Fix run-one-test so that it runs elf tests +- nptl: Fix niggles with pthread_clockjoin_np +- hppa: Align __clone stack argument to 8 bytes (Bug 25066) +- y2038: linux: Provide __futimens64 implementation +- y2038: linux: Provide __utimensat64 implementation +- nptl: Add pthread_timedjoin_np, pthread_clockjoin_np NULL timeout test +- nptl: Add pthread_clockjoin_np +- manual: Add documentation for pthread_tryjoin_np and pthread_timedjoin_np +- nptl: Convert tst-join3 to use libsupport +- Sync time/mktime.c with gnulib +- Sync timespec-{add,sub} with gnulib +- Sync intprops.h with gnulib +- Refactor adjtimex based on clock_adjtime +- Refactor PI mutexes internal definitions +- Remove pause and nanosleep not cancel wrappers +- nptl: Replace non cancellable pause/nanosleep with futex +- Consolidate lowlevellock-futex.h +- Consolidate futex-internal.h +- Base max_fast on alignment, not width, of bins (Bug 24903) +- Revise the documentation of simple calendar time. +- Make second argument of gettimeofday as 'void *' +- Use clock_gettime to implement gettimeofday. +- Use clock_gettime to implement timespec_get. +- Consolidate and deprecate ftime +- Change most internal uses of time to __clock_gettime. +- Use clock_gettime to implement time. +- Use clock_settime to implement settimeofday. +- Use clock_settime to implement stime; withdraw stime. +- Change most internal uses of __gettimeofday to __clock_gettime. +- Linux/Alpha: don't use timeval32 system calls. +- resolv/tst-idna_name_classify: Isolate from system libraries +- hurd: Support for file record locking +- Comment out initgroups from example nsswitch.conf (Bug 25146) + +* Mon Oct 28 2019 DJ Delorie - 2.30.9000-16 +- Auto-sync with upstream branch master, + commit 177a3d48a1c74d7b2cd6bfd48901519d25a5ecad. +- y2038: linux: Provide __clock_getres64 implementation +- time: Introduce function to check correctness of nanoseconds value +- Add Transliterations for Unicode Misc. Mathematical Symbols-A/B [BZ #23132] +- Install charmaps uncompressed in testroot +- Add wait-for-debugger test harness hooks +- Define __STATFS_MATCHES_STATFS64 +- hurd: Fix build after __pread64 usage in the dynamic loader +- sysdeps/stat: Handle 64-bit ino_t types on 32-bit hosts +- S390: Remove not needed stack frame in syscall function. + +* Fri Oct 25 2019 DJ Delorie - 2.30.9000-15 +- Add *.mo files to all-langpacks (#1624528) + +* Thu Oct 24 2019 DJ Delorie - 2.30.9000-14 +- Add Requires on basesystem for main package (#1757267) +- Add Requires on coreutils for glibc-headers (uses rm) + +* Wed Oct 23 2019 Arjun Shankar - 2.30.9000-13 +- Auto-sync with upstream branch master, + commit 7db1fe38de21831d53ceab9ae83493d8d1aec601: +- Include explicitly in Linux clock_settime.c +- Remove math-finite.h +- Remove finite-math tests +- Remove x64 _finite tests and references +- Fix testroot.pristine creation copying dynamic linker + +* Fri Oct 18 2019 Patsy Franklin - 2.30.9000-12 +- Auto-sync with upstream branch master, + commit ef21bd2d8c6805c0c186a01f7c5039189f51b8c4. +- loadarchive: guard against locale-archive corruption (Bug #25115) +- Undo accidental commit to ChangeLog.19. +- nptl: Document AS-safe functions in cancellation.c. +- elf: Use nocancel pread64() instead of lseek()+read() +- Add nocancel version of pread64() +- Add run-one-test convenience target and makefile help text +- Update sysvipc kernel-features.h files for Linux 5.1 +- S390: Add new s390 platform z15. +- nptl: SIGCANCEL, SIGTIMER, SIGSETXID are always defined +- nptl/tst-cancel25 needs to be an internal test +- Remove libc_hidden_def from __semtimedop stub +- sysvipc: Implement semop based on semtimedop +- ipc: Refactor sysvipc internal definitions +- Rename and split elf/tst-dlopen-aout collection of tests +- dlfcn: Remove remnants of caller sensitivity from dlinfo +- ldconfig: handle .dynstr located in separate segment (bug 25087) +- ldd: Print "not a dynamic executable" on standard error [BZ #24150] +- Add PTRACE_GET_SYSCALL_INFO from Linux 5.3 to sys/ptrace.h. +- Move ChangeLog to ChangeLog.old/ChangeLog.19 +- manual: Remove warning in the documentation of the abort function +- sysvipc: Set ipc_perm mode as mode_t (BZ#18231) +- Simplify note processing +- syscall-names.list: fix typos in comment +- y2038: linux: Provide __clock_settime64 implementation +- posix: Use posix_spawn for wordexp +- mips: Do not malloc on getdents64 fallback +- sparc: Assume GOTDATA support in the toolchain +- : Remove wrong comment about getdents64 declaration +- ChangeLog: Remove leading spaces before tabs and trailing whitespace +- Make tst-strftime2 and tst-strftime3 depend on locale generation +- posix/tst-wordexp-nocmd: Fix diagnostics output in test +- wordexp: Split out command execution tests from posix/wordexp-test + +* Tue Oct 08 2019 Arjun Shankar - 2.30.9000-11 +- Adjust glibc-rh741105.patch. +- Auto-sync with upstream branch master, + commit ca602c1536ce2777f95c07525f3c42d78812e665: +- Add TCP_TX_DELAY from Linux 5.3 to netinet/tcp.h +- [powerpc] fenv_private.h clean up +- [powerpc] libc_feupdateenv_test: optimize FPSCR access +- [powerpc] __fesetround_inline optimizations +- [powerpc] Rename fegetenv_status to fegetenv_control +- [powerpc] libc_feholdsetround_noex_ppc_ctx: optimize FPSCR write +- [powerpc] Rename fesetenv_mode to fesetenv_control +- Add helper script for glibc debugging +- Update bits/mman.h constants and tst-mman-consts.py for Linux 5.3. +- y2038: Provide conversion helpers for struct __timespec64 +- Use binutils 2.33 branch in build-many-glibcs.py. +- Sync "language", "lang_name", "territory", "country_name" with CLDR/langtable +- Split up endian.h to minimize exposure of BYTE_ORDER. +- time: Add padding for the timespec if required +- Enable passing arguments to the inferior in debugglibc.sh +- [powerpc] No need to enter "Ignore Exceptions Mode" +- Y2038: Include proper header to provide support for struct timeval on HURD +- Disable warnings in string/tester.c at top level. +- string/endian.h: Restore the __USE_MISC conditionals +- Disable -Wmaybe-uninitialized for total_deadline in sunrpc/clnt_udp.c. +- ChangeLog update from my last commit +- nptl: Move pthread_attr_setinheritsched implementation into libc. +- elf: Never use the file ID of the main executable [BZ #24900] +- elf: Assign TLS modid later during dlopen [BZ #24930] +- nptl: Move pthread_attr_getschedparam implementation into libc +- riscv: Remove support for variable page sizes +- nptl: Move pthread_attr_setschedparam implementation into libc + +* Fri Sep 27 2019 Zbigniew JÄ™drzejewski-Szmek - 2.30.9000-10 +- Use full locale names in langpack descriptions (#1651375) + +* Thu Sep 26 2019 Patsy Franklin - 2.30.9000-9 +- Auto-sync with upstream branch master, + commit 464cd3a9d5f505d92bae9a941bb75b0d91ac14ee. +- y2038: Introduce struct __timespec64 - new internal glibc type +- auto-changelog: Remove latin1 from codecs +- Set the expects flags to clock_nanosleep +- Fix tst-sigcontext-get_pc rule name from a43565ac447b1 +- inet/net-internal.h: Fix uninitalised clntudp_call() variable +- Fix vDSO initialization on arm and mips +- Script to generate ChangeLog-like output from git log +- [powerpc] SET_RESTORE_ROUND optimizations and bug fix +- Fix building support_ptrace.c on i686-gnu. +- S390: Use _HP_TIMING_S390_H instead of _HP_TIMING_H. +- Update syscall-names.list for Linux 5.3. +- Use Linux 5.3 in build-many-glibcs.py. +- S390: Add support for HP_TIMING_NOW. +- Fix RISC-V vfork build with Linux 5.3 kernel headers. +- Add UNSUPPORTED check in elf/tst-pldd. +- sparc64: Use linux generic time implementation +- mips: Consolidate INTERNAL_VSYSCALL_CALL +- powerpc: Simplify vsyscall internal macros +- Refactor vDSO initialization code +- Remove PREPARE_VERSION and PREPARE_VERSION_KNOW +- Fix small error in HP_TIMING_PRINT trailing null char setting + +* Mon Sep 16 2019 Parag Nemade - 2.30.9000-8 +- Change Supplements "langpacks-" to "langpacks-core-" (#1729992) + +* Mon Sep 16 2019 DJ Delorie - 2.30.9000-7 +- Auto-sync with upstream branch master, + commit 1a6566094d3097f4a3037ab5555cddc6cb11c3a3. +- alpha: force old OSF1 syscalls for getegid, geteuid and getppid [BZ #24986] +- Fix http: URL in 'configure' +- Regenerate charmap-kw.h, locfile-kw.h +- Fix three GNU license URLs, along with trailing-newline issues. +- Prefer https to http for gnu.org and fsf.org URLs + +* Fri Sep 06 2019 Patsy Franklin - 2.30.9000-6 +- Auto-sync with upstream branch master, + commit 1b7f04070bd94f259e2ed24d6fb76309d64fb164. +- locale: Avoid zero-length array in _nl_category_names [BZ #24962] +- math: Replace const attribute with pure in totalorder* functions +- y2038: Introduce the __ASSUME_TIME64_SYSCALLS define +- Finish move of clock_* functions to libc. [BZ #24959] +- Update Alpha libm-test-ulps +- localedef: Use initializer for flexible array member [BZ #24950] +- Add misc/tst-mntent-autofs, testing autofs "ignore" filtering +- Use autofs "ignore" mount hint in getmntent_r/getmntent +- hurd: Fix build +- Use generic memset/memcpy/memmove in benchtests +- nptl: Move pthread_attr_getinheritsched implementation into libc +- hurd: Fix SS_ONSTACK support +- hurd: Remove optimizing anonymous maps as __vm_allocate. +- hurd: Fix poll and select POSIX compliancy details about errors +- hurd: Fix timeout handling in _hurd_select +- hurd getcwd: Allow unknown root directory +- hurd: Fix implementation of setitimer. +- hurd: Fix _hurd_select for single fd sets +- MIPS support for GNU hash +- sh: Split BE/LE abilist +- microblaze: Split BE/LE abilist +- arm: Split BE/LE abilist +- Correct the spelling of more contributors +- Fix posix/tst-regex by using UTF-8 and own test input +- [powerpc] fegetenv_status: simplify instruction generation +- [powerpc] fesetenv: optimize FPSCR access +- [powerpc] SET_RESTORE_ROUND improvements +- [powerpc] fe{en,dis}ableexcept, fesetmode: optimize FPSCR accesses +- [powerpc] fe{en,dis}ableexcept optimize bit translations +- misc: Use allocate_once in getmntent +- nptl: Move pthread_attr_setdetachstate implementation into libc +- login: pututxline could fail to overwrite existing entries [BZ #24902] +- Fix posix/tst-regex by using a dedicated input-file. + +* Tue Aug 27 2019 DJ Delorie - 2.30.9000-5 +- Move makedb from glibc-common to nss_db (#1704334) + +* Mon Aug 26 2019 DJ Delorie - 2.30.9000-4 +- Auto-sync with upstream branch master, + commit 1bced8cadc82077f0201801239e89eb24b68e9aa. +- Don't put non-ASCII into installed headers +- Fix spellings of contributor names in comments and doc +- [MIPS] Raise highest supported EI_ABIVERSION value [SWBZ #24916] +- mips: Force RWX stack for hard-float builds that can run on pre-4.8 kernels +- linux: Make profil_counter a compat_symbol (SWBZ#17726) +- Refactor sigcontextinfo.h +- Add RTLD_SINGLE_THREAD_P on generic single-thread.h +- Chinese locales: Set first_weekday to 2 (swbug 24682). +- powerpc: Fix typos and field name in comments +- Mark IDN tests unsupported with libidn2 before 2.0.5. +- Document strftime %Ob and %OB as C2X features. +- Remove dead regex code +- Fix bad pointer / leak in regex code +- Don't use the argument to time. +- Add tgmath.h macros for narrowing functions. +- Update i386 libm-test-ulps + +* Mon Aug 19 2019 Carlos O'Donell - 2.30.9000-3 +- Drop glibc-fedora-nscd-warnings.patch; applied upstream. +- Drop Source7: nsswitch.conf; applying patch to upstream. +- Add glibc-fedora-nsswitch.patch for Fedora customizations. +- Auto-sync with upstream branch master, + commit d34d4c80226b3f5a1b51a8e5b005a52fba07d7ba: +- Do not print backtraces on fatal glibc errors. +- elf: Self-dlopen failure with explict loader invocation (swbz#24900) +- login: Add nonstring attributes to struct utmp, struct utmpx (swbz#24899) +- login: Use struct flock64 in utmp (swbz#24880) +- login: Disarm timer after utmp lock acquisition (swbz#24879) + +* Fri Aug 16 2019 Carlos O'Donell - 2.30.9000-2 +- Fix C.UTF-8 to use full code ranges. + +* Thu Aug 15 2019 Florian Weimer - 2.30.9000-1 +- Auto-sync with upstream branch master, + commit 341da5b4b6253de9a7581a066f33f89cacb44dec. + +* Fri Aug 02 2019 Florian Weimer - 2.30-1 +- Drop glibc-rh1734680.patch, applied upstream. +- Auto-sync with upstream branch release/2.30/master, + commit be9a328c93834648e0bec106a1f86357d1a8c7e1: +- malloc: Remove unwanted leading whitespace in malloc_info (swbz#24867) +- glibc 2.30 release +- iconv: Revert steps array reference counting changes (#1734680) +- Restore r31 setting in powerpc32 swapcontext + +* Wed Jul 31 2019 Florian Weimer - 2.29.9000-37 +- Fix memory leak in iconv_open (#1734680) + +* Tue Jul 30 2019 Florian Weimer - 2.29.9000-36 +- Drop glibc-rh1732406.patch, fix for the regression applied upstream. +- Auto-sync with upstream branch master, + commit 8a814e20d443adc460a1030fa1a66aa9ae817483: +- nptl: Use uintptr_t for address diagnostic in nptl/tst-pthread-getattr +- Linux: Move getdents64 to +- test-container: Install with $(sorted-subdirs) (swbz#24794) +- gconv: Check reference count in __gconv_release_cache (#1732406) +- x86-64: Compile branred.c with -mprefer-vector-width=128 (swbz#24603) +- build-many-glibcs.py: Use Linux 5.2 by default +- Linux: Use in-tree copy of SO_ constants for !__USE_MISC (swbz#24532) +- test-container: Avoid copying unintended system libraries + +* Thu Jul 25 2019 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Tue Jul 23 2019 Florian Weimer - 2.29.9000-34 +- Revert libio change that causes crashes (#1732406) + +* Mon Jul 22 2019 DJ Delorie - 2.29.9000-33 +- Auto-sync with upstream branch master, + commit dcf36bcad3f283f77893d3b157ef7bb2c99419f2. +- Add NEWS entry about the new AArch64 IFUNC resolver call ABI +- locale/C-translit.h.in: Cyrillic -> ASCII transliteration [BZ #2872] +- Linux: Update syscall-names.list to Linux 5.2 + +* Thu Jul 18 2019 DJ Delorie - 2.29.9000-32 +- Auto-sync with upstream branch master, + commit 3556658c5b8765480711b265abc901c67d5fc060. +- Regenerate po/libc.pot for 2.30 release. +- nptl: Add POSIX-proposed _clock functions to hppa pthread.h +- nptl: Remove unnecessary forwarding of pthread_cond_clockwait from libc +- Afar locales: Months and days updated from CLDR (bug 21897). +- nl_BE locale: Use "copy "nl_NL"" in LC_NAME (bug 23996). +- nl_BE and nl_NL locales: Dutch salutations (bug 23996). +- ga_IE and en_IE locales: Revert first_weekday removal (bug 24200). +- nptl: Remove futex_supports_exact_relative_timeouts +- Update NEWS for new _clockwait and _clocklock functions +- nptl: Add POSIX-proposed pthread_mutex_clocklock +- nptl: Rename lll_timedlock to lll_clocklock and add clockid parameter +- nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock +- nptl: pthread_rwlock: Move timeout validation into _full functions +- nptl: Add POSIX-proposed pthread_cond_clockwait +- nptl: Add POSIX-proposed sem_clockwait +- nptl: Add clockid parameter to futex timed wait calls +- posix: Fix large mmap64 offset for mips64n32 (BZ#24699) +- nss_db: fix endent wrt NULL mappings [BZ #24695] [BZ #24696] + +* Wed Jul 10 2019 Carlos O'Donell - 2.29.9000-31 +- Auto-sync with upstream branch master, + commit 30ba0375464f34e4bf8129f3d3dc14d0c09add17. +- Don't declare __malloc_check_init in (bug 23352) +- nftw: fill in stat buf for dangling links [BZ #23501] +- dl-vdso: Add LINUX_4 HASH CODE to support nds32 vdso mechanism +- riscv: restore ABI compatibility (bug 24484) +- aarch64: new ifunc resolver ABI +- nptl: Remove vfork IFUNC-based forwarder from libpthread [BZ #20188] +- malloc: Add nptl, htl dependency for the subdirectory [BZ #24757] +- Call _dl_open_check after relocation [BZ #24259] +- Linux: Use mmap instead of malloc in dirent/tst-getdents64 +- ld.so: Support moving versioned symbols between sonames [BZ #24741] +- io: Remove copy_file_range emulation [BZ #24744] +- Linux: Adjust gedents64 buffer size to int range [BZ #24740] +- powerpc: Use generic e_expf +- Linux: Add nds32 specific syscalls to syscall-names.list +- szl_PL locale: Fix a typo in the previous commit (bug 24652). + +* Mon Jun 24 2019 DJ Delorie - 2.29.9000-30 +- Auto-sync with upstream branch master, + commit 2bd81b60d6ffdf7e0d22006d69f4b812b1c80513. +- szl_PL locale: Spelling corrections (swbz 24652). +- nl_{AW,NL}: Correct the thousands separator and grouping (swbz 23831). +- Add missing VDSO_{NAME,HASH}_* macros and use them for PREPARE_VERSION_KNOWN +- nptl: Convert various tests to use libsupport +- support: Invent verbose_printf macro +- support: Add xclock_now helper function. + +* Fri Jun 21 2019 Florian Weimer - 2.29.9000-29 +- Auto-sync with upstream branch master, + commit 21cc130b78a4db9113fb6695e2b951e697662440: +- During exit, skip wide buffer handling for legacy stdio handles (#1722216) +- powerpc: add 'volatile' to asm +- powerpc: Fix static-linked version of __ppc_get_timebase_freq (swbz#24640) +- nl_AW locale: Correct the negative monetary format (swb#z24614) +- Fix gcc 9 build errors for make xcheck. (swbz#24556) +- dlfcn: Avoid one-element flexible array in Dl_serinfo (swbz#24166) +- elf: Refuse to dlopen PIE objects (swbz#24323) +- nl_NL locale: Correct the negative monetary format (swbz#24614) +- powerpc: Refactor powerpc64 lround/lroundf/llround/llroundf +- powerpc: refactor powerpc64 lrint/lrintf/llrint/llrintf + +* Mon Jun 17 2019 Florian Weimer - 2.29.9000-28 +- Auto-sync with upstream branch master, + commit 48c3c1238925410b4e777dc94e2fde4cc9132d44. +- Linux: Fix __glibc_has_include use for and statx (#1721129) +- : Inhibit macro expansion for __glibc_has_include +- Add IPV6_ROUTER_ALERT_ISOLATE from Linux 5.1 to bits/in.h +- aarch64: handle STO_AARCH64_VARIANT_PCS +- aarch64: add STO_AARCH64_VARIANT_PCS and DT_AARCH64_VARIANT_PCS +- powerpc: Remove optimized finite +- math: Use wordsize-64 version for finite +- powerpc: Remove optimized isinf +- math: Use wordsize-64 version for isinf +- powerpc: Remove optimized isnan +- math: Use wordsize-64 version for isnan +- benchtests: Add isnan/isinf/isfinite benchmark +- powerpc: copysign cleanup +- powerpc: consolidate rint +- libio: freopen of default streams crashes in old programs (swbz#24632) +- Linux: Deprecate and sysctl +- : Use Linux UAPI header for statx if available and useful + (#1721129) +- : Add __glibc_has_include macro +- Improve performance of memmem +- Improve performance of strstr +- Benchmark strstr hard needles +- Fix malloc tests build with GCC 10 + +* Mon Jun 10 2019 Patsy Franklin - 2.29.9000-27 +- Auto-sync with upstream branch master, + commit 51ea67d54882318c4fa5394c386f4816ddc22408. +- powerpc: get_rounding_mode: utilize faster method to get rounding mode +- riscv: Do not use __has_include__ +- powerpc: fegetexcept: utilize function instead of duplicating code +- iconv: Use __twalk_r in __gconv_release_shlib +- Fix iconv buffer handling with IGNORE error handler (swbz#18830) + +* Wed Jun 5 2019 Florian Weimer - 2.29.9000-26 +- Restore /usr/lib/locale/locale-archive under its original name (#1716710) + +* Tue Jun 4 2019 Florian Weimer - 2.29.9000-25 +- Add glibc version to locale-archive name (#1716710) + +* Mon Jun 03 2019 Carlos O'Donell - 2.29.9000-24 +- Auto-sync with upstream branch master, + commit dc91a19e6f71e1523f4ac179191a29b2131d74bb: +- Linux: Add oddly-named arm syscalls to syscall-names.list. +- arm: Remove ioperm/iopl/inb/inw/inl/outb/outw/outl support. +- Add INADDR_ALLSNOOPERS_GROUP from Linux 5.1 to netinet/in.h. + +* Sat Jun 01 2019 Carlos O'Donell - 2.29.9000-23 +- Convert glibc_post_upgrade to lua. + +* Sat Jun 01 2019 Florian Weimer - 2.29.9000-22 +- Remove support for filtering glibc-all-langpacks (#1715891) +- Auto-sync with upstream branch master, + commit 9250e6610fdb0f3a6f238d2813e319a41fb7a810: +- powerpc: Fix build failures with current GCC +- Remove unused get_clockfreq files +- powerpc: generic nearbyint/nearbyintf +- tt_RU: Add lang_name (swbz#24370) +- tt_RU: Fix orthographic mistakes in mon and abmon sections (swbz#24369) +- Add IGMP_MRDISC_ADV from Linux 5.1 to netinet/igmp.h. + +* Mon May 27 2019 Arjun Shankar - 2.29.9000-21 +- Auto-sync with upstream branch master, + commit 85188d8211698d1a255f0aec6529546db5c56de3: +- Remove support for PowerPC SPE extension +- elf: Add tst-ldconfig-bad-aux-cache test +- Add F_SEAL_FUTURE_WRITE from Linux 5.1 to bits/fcntl-linux.h +- nss_dns: Check for proper A/AAAA address alignment + +* Tue May 21 2019 DJ Delorie - 2.29.9000-20 +- Auto-sync with upstream branch master, + commit 46ae07324b1cd50fbf8f37a076d6babcfca7c510. +- Improve string benchtest timing +- sysvipc: Add missing bit of semtimedop s390 consolidation +- wcsmbs: Fix data race in __wcsmbs_clone_conv [swbz #24584] +- libio: Fix gconv-related memory leak [swbz #24583] +- libio: Remove codecvt vtable [swbz #24588] +- support: Expose sbindir as support_sbindir_prefix +- support: Add missing EOL terminators on timespec +- support: Correct confusing comment +- sysvipc: Consolidate semtimedop s390 +- sysvipc: Fix compat msgctl (swbz#24570) +- Add NT_ARM_PACA_KEYS and NT_ARM_PACG_KEYS from Linux 5.1 to elf.h. +- Small tcache improvements +- manual: Document O_DIRECTORY +- Update kernel-features.h files for Linux 5.1. +- nss_nis, nss_nisplus: Remove RES_USE_INET6 handling +- nss_files: Remove RES_USE_INET6 from hosts processing +- support: Report NULL blobs explicitly in TEST_COMPARE +- dlfcn: Guard __dlerror_main_freeres with __libc_once_get (once) [swbz# 24476] +- Add missing Changelog entry + +* Wed May 15 2019 Florian Weimer - 2.29.9000-19 +- Auto-sync with upstream branch master, + commit 32ff397533715988c19cbf3675dcbd727ec13e18: +- Fix crash in _IO_wfile_sync (#1710460) +- nss: Turn __nss_database_lookup into a compatibility symbol +- support: Add support_install_rootsbindir +- iconv: Remove public declaration of __gconv_transliterate +- Linux: Add the tgkill function +- manual: Adjust twalk_r documentation. +- elf: Fix tst-pldd for non-default --prefix and/or --bindir (swbz#24544) +- support: Export bindir path on support_path +- configure: Make --bindir effective +- x86: Remove arch-specific low level lock implementation +- nptl: Assume LLL_LOCK_INITIALIZER is 0 +- nptl: Small optimization for lowlevellock +- Add single-thread.h header +- locale: Update to Unicode 12.1.0 (swbz#24535) +- malloc: Fix tcache count maximum (swbz#24531) +- sem_close: Use __twalk_r +- support: Fix timespec printf +- nptl/tst-abstime: Use libsupport +- nptl: Convert some rwlock tests to use libsupport +- nptl: Use recent additions to libsupport in tst-sem5 +- nptl: Convert tst-cond11.c to use libsupport +- support: Add timespec.h +- Move nptl/tst-eintr1 to xtests (swbz#24537) +- powerpc: trunc/truncf refactor +- powerpc: round/roundf refactor +- powerpc: floor/floorf refactor +- support: Add xclock_gettime +- malloc/tst-mallocfork2: Use process-shared barriers +- Update syscall-names.list for Linux 5.1 +- Use GCC 9 in build-many-glibcs.py +- aarch64: thunderx2 memmove performance improvements +- misc/tst-tsearch: Additional explicit error checking +- elf: Fix elf/tst-pldd with --enable-hardcoded-path-in-tests (swbz#24506) +- misc: Add twalk_r function + +* Thu May 02 2019 Arjun Shankar - 2.29.9000-18 +- Auto-sync with upstream branch master, + commit 20aa5819586ac7ad11f711bab64feda307965191: +- semaphore.h: Add nonnull attributes +- powerpc: Remove power4 mpa optimization +- powerpc: Refactor ceil/ceilf +- Fix -O1 compilation errors with `__ddivl' and `__fdivl' [BZ #19444] +- Make mktime etc. compatible with __time64_t + +* Fri Apr 26 2019 Florian Weimer - 2.29.9000-17 +- Auto-sync with upstream branch master, + commit c57afec0a9b318bb691e0f5fa4e9681cf30df7a4: +- Increase BIND_NOW coverage (#1702671) +- Fix pldd hang (#1361689) +- riscv: remove DL_RO_DYN_SECTION (swbz#24484) +- locale: Add LOCPATH diagnostics to the locale program +- Reduce benchtests time + +* Mon Apr 22 2019 DJ Delorie - 2.29.9000-16 +- Auto-sync with upstream branch master, + commit 25f7a3c96116a9102df8bf7b04ef160faa32416d. +- malloc: make malloc fail with requests larger than PTRDIFF_MAX (BZ#23741) +- powerpc: Fix format issue from 3a16dd780eeba602 +- powerpc: fma using builtins +- powerpc: Use generic fabs{f} implementations +- mips: Remove rt_sigreturn usage on context function +- powerpc: Remove rt_sigreturn usage on context function +- support: Add support_capture_subprogram +- stdlib/tst-secure-getenv: handle >64 groups + +* Mon Apr 15 2019 Florian Weimer - 2.29.9000-15 +- Auto-sync with upstream branch master, + commit e3f454bac0f968216699ca405c127c858f0657c7: +- nss_dns: Do not replace root domain with empty string +- alloc_buffer: Return unqualified pointer type in alloc_buffer_next +- malloc: Set and reset all hooks for tracing (swbz#16573) + +* Thu Apr 11 2019 Florian Weimer - 2.29.9000-14 +- Run valgrind smoke test against the install tree + +* Thu Apr 11 2019 Florian Weimer - 2.29.9000-13 +- Do not use --g-libs with find-debuginfo.sh; it breaks valgrind (#1698824) + +* Wed Apr 10 2019 Florian Weimer - 2.29.9000-12 +- Strip debugging information from installed programs again (#1661510) + +* Tue Apr 09 2019 Carlos O'Donell - 2.29.9000-11 +- Drop glibc-warning-fix.patch. Microbenchmark code fixed upstream. +- Auto-sync with upstream branch master, + commit 648279f4af423c4783ec1dfa63cb7b46a7640217: +- powerpc: Use generic wcscpy optimization +- powerpc: Use generic wcschr optimization +- powerpc: Use generic wcsrchr optimization +- aarch64: thunderx2 memcpy implementation cleanup and streamlining +- resolv: Remove support for RES_USE_INET6 and the inet6 option +- resolv: Remove RES_INSECURE1, RES_INSECURE2 + +* Thu Apr 04 2019 Arjun Shankar - 2.29.9000-10 +- Auto-sync with upstream branch master, + commit 8260f23616c1a2a4e609f989a195fba7690a42ca: +- Fix strptime era handling, add more strftime tests [BZ #24394] +- time/tst-strftime2.c: Make the file easier to maintain +- time: Add tests for Minguo calendar [BZ #24293] +- ja_JP locale: Add entry for the new Japanese era [BZ #22964] +- Add Reiwa era tests to time/tst-strftime3.c + +* Mon Apr 01 2019 Arjun Shankar - 2.29.9000-9 +- Auto-sync with upstream branch master, + commit 993e3107af67edefcfc79a62ae55f7b98aa5151e: +- Add AArch64 HWCAPs from Linux 5.0 +- tt_RU: Fix orthographic mistakes in day and abday sections [BZ #24296] +- iconv, localedef: avoid floating point rounding differences [BZ #24372] +- Fix parentheses error in iconvconfig.c and ld-collate.c [BZ #24372] +- S390: New configure check and hwcap values for new CPU architecture arch13 +- S390: Add memmove, strstr, and memmem ifunc variants for arch13 +- nptl: Remove pthread_clock_gettime pthread_clock_settime +- linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID +- Remove __get_clockfreq +- Do not use HP_TIMING_NOW for random bits +- hp-timing: Refactor rtld usage, add generic support +- Add NT_ARM_PAC_MASK and NT_MIPS_MSA from Linux 5.0 to elf.h +- Add UDP_GRO from Linux 5.0 to netinet/udp.h +- nptl: Convert tst-sem5 & tst-sem13 to use libsupport +- nptl/tst-rwlock14: Test pthread_rwlock_timedwrlock correctly +- nss/tst-nss-files-alias-leak: add missing opening quote in printf +- math: Enable some math builtins for clang +- powerpc: Use __builtin_{mffs,mtfsf} +- RISC-V: Fix `test' operand error with soft-float ABI being configured + +* Wed Mar 20 2019 Carlos O'Donell - 2.29.9000-8 +- Add warnings and notes to /etc/nsswitch.conf and /etc/nscd.conf. + +* Mon Mar 18 2019 DJ Delorie - 2.29.9000-7 +- Auto-sync with upstream branch master, + commit 78919d3886c9543279ec755a701e279c62b44164. + +* Thu Mar 14 2019 Florian Weimer - 2.29.9000-6 +- Drop glibc-fedora-streams-rh436349.patch. STREAMS was removed upstream. +- Auto-sync with upstream branch master, + commit a0a0dc83173ce11ff45105fd32e5d14356cdfb9c: +- Remove obsolete, never-implemented XSI STREAMS declarations +- nss: Fix tst-nss-files-alias-truncated for default --as-needed linking +- scripts/check-obsolete-constructs.py: Process all headers as UTF-8. +- Use Linux 5.0 in build-many-glibcs.py. +- hurd: Add no-op version of __res_enable_icmp [BZ #24047] +- Move inttypes.h and stdint.h to stdlib. +- Use a proper C tokenizer to implement the obsolete typedefs test. +- Fix output of LD_SHOW_AUXV=1. + +* Wed Mar 13 2019 Florian Weimer - 2.29.9000-5 +- Drop glibc-rh1670028.patch, applied upstream +- Auto-sync with upstream branch master, + commit 38b52865d4ccfee3647f27e969e539a4396a73b1: +- elf: Add DF_1_KMOD, DF_1_WEAKFILTER, DF_1_NOCOMMON to +- resolv: Enable full ICMP errors for UDP DNS sockets [BZ #24047] +- C-SKY: add elf header definition for elfutils +- C-SKY: mark lr as undefined to stop unwinding +- C-SKY: remove user_regs definition +- C-SKY: fix sigcontext miss match +- Bug 24307: Update to Unicode 12.0.0 +- Break lines before not after operators, batch 4. +- check-wrapper-headers test: Adjust Fortran include file directory +- Fix location where math-vector-fortran.h is installed. + +* Wed Mar 06 2019 DJ Delorie - 2.29.9000-4 +- Auto-sync with upstream branch master, + commit 0ddb7ea842abf63516b74d4b057c052afc6ba863. +- nptl: Assume __ASSUME_FUTEX_CLOCK_REALTIME support +- powerpc: Fix build of wcscpy with --disable-multi-arch +- elf: Remove remnants of MAP_ANON emulation +- S390: Increase function alignment to 16 bytes. +- ja_JP: Change the offset for Taisho gan-nen from 2 to 1 [BZ #24162] +- ldbl-opt: Reuse test cases from misc/ that check long double +- ldbl-opt: Add error and error_at_line (bug 23984) +- ldbl-opt: Add err, errx, verr, verrx, warn, warnx, vwarn, and vwarnx (bug 23984) +- ldbl-opt: Reuse argp tests that print long double +- ldbl-opt: Add argp_error and argp_failure (bug 23983) +- elf/tst-big-note: Improve accuracy of test [BZ #20419] +- S390: Fix introduction of __wcscpy and weak wcscpy symbols. +- __netlink_assert_response: Add more __libc_fatal newlines [BZ #20271] +- Add more spaces before '('. +- elf: Add tests with a local IFUNC resolver [BZ #23937] +- elf/Makefile: Run IFUNC tests if binutils supports IFUNC +- powerpc: Fix linknamespace introduced by 4d8015639a75 +- hurd: Add renameat2 support for RENAME_NOREPLACE +- Fix -Wempty-body warnings in Hurd-specific code. +- Add some spaces before '('. +- wcsmbs: optimize wcsnlen +- wcsmbs: optimize wcsncpy +- wcsmbs: optimize wcsncat +- wcsmbs: optimize wcscpy +- wcsmbs: optimize wcscat +- wcsmbs: optimize wcpncpy +- wcsmbs: optimize wcpcpy +- Break further lines before not after operators. +- Add and move fall-through comments in system-specific code. + +* Fri Mar 1 2019 DJ Delorie - 2.29.9000-3 +- Add .gdb_index to debug information (rhbz#1680765) + +* Wed Feb 27 2019 Carlos O'Donell - 2.29.9000-2 +- Fix build failure related to microbenchmarks. + +* Tue Feb 26 2019 Carlos O'Donell - 2.29.9000-1 +- Auto-sync with upstream branch master, + commit e0cb7b6131ee5f2dca2938069b8b9590304e6f6b: +- nss_files: Fix /etc/aliases null pointer dereference (swbz#24059) +- regex: fix read overrun (swbz#24114) +- libio: use stdout in puts and putchar, etc (swbz#24051) +- aarch64: Add AmpereComputing emag to tunable cpu list +- aarch64: Optimized memset specific to AmpereComputing emag +- aarch64: Optimized memchr specific to AmpereComputing emag +- Require GCC 6.2 or later to build glibc +- manual: Document lack of conformance of sched_* functions (swbz#14829) +- libio: Use stdin consistently for input functions (swbz#24153) +- x86-64 memcmp: Use unsigned Jcc instructions on size (swbz#24155) +- Fix handling of collating elements in fnmatch (swbz#17396,swbz#16976) +- arm: Use "nr" constraint for Systemtap probes (swbz#24164) +- Fix alignment of TLS variables for tls variant TLS_TCB_AT_TP (swbz#23403) +- Add compiler barriers for pthread_mutex_trylock (swbz#24180) +- rt: Turn forwards from librt to libc into compat symbols (swbz#24194) +- Linux: Add gettid system call wrapper (swbz#6399) +- nptl: Avoid fork handler lock for async-signal-safe fork (swbz#24161) +- elf: Ignore LD_AUDIT interfaces if la_version returns 0 (swbz#24122) +- nptl: Reinstate pthread_timedjoin_np as a cancellation point (swbz#24215) +- nptl: Fix invalid Systemtap probe in pthread_join (swbz#24211) + +* Tue Feb 19 2019 Florian Weimer - 2.29-8 +- Drop glibc-rh1674280.patch. Different fix applied upstream. (#1674280) +- Auto-sync with upstream branch release/2.29/master, + commit 067fc32968b601493f4b247a3ac00caeea3f3d61: +- nptl: Fix invalid Systemtap probe in pthread_join (#1674280) + +* Mon Feb 11 2019 Florian Weimer - 2.29-7 +- Hotfix for invalid Systemtap probe in pthread_join (#1674280) + +* Mon Feb 11 2019 Florian Weimer - 2.29-6 +- Remove LRA bug on POWER workaround, fixed in gcc-9.0.1-0.4.fc30 (#1673018) + +* Mon Feb 11 2019 Florian Weimer - 2.29-5 +- Auto-sync with upstream branch release/2.29/master, + commit c096b008d2671028c21ac8cf01f18a2083e73c44: +- nptl: Avoid fork handler lock for async-signal-safe fork (swbz#24161) +- nptl: Add compiler barriers in pthread_mutex_trylock (swbz#24180) + +* Thu Feb 7 2019 Florian Weimer - 2.29-4 +- Work around LRA hang on ppc64le (#1673018) + +* Wed Feb 06 2019 Florian Weimer - 2.29-3 +- Auto-sync with upstream branch release/2.29/master, + commit 2de15ac95713a238dc258eb8977ecdfca811fc19: +- arm: Use "nr" constraint for Systemtap probes (#1196181) + +* Fri Feb 1 2019 Florian Weimer - 2.29-2 +- Eliminate %%glibcrelease macro. +- Switch to regular Release: pattern. + +* Thu Jan 31 2019 Carlos O'Donell - 2.29-1 +- Auto-sync with upstream branch release/2.29/master, + commit 86013ef5cea322b8f4b9c22f230c22cce369e947. +- nptl: Fix pthread_rwlock_try*lock stalls (swbz#23844) + +* Thu Jan 31 2019 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Jan 28 2019 DJ Delorie - 2.28.9000-37 +- Auto-sync with upstream branch master, + commit e1e47c912a8e557508362715f7468091def3ec4f. +- Update translations. +* Mon Jan 28 2019 Florian Weimer - 2.28.9000-36 +- resolv: Enable full ICMP error reporting in stub resolver (#1670028) + +* Mon Jan 28 2019 Florian Weimer - 2.28.9000-35 +- Remove obsolete scriptlets + +* Fri Jan 25 2019 Florian Weimer - 2.28.9000-34 +- Auto-sync with upstream branch master, + commit 83e6b59625f45db1eee93e5684091f740c52a083: +- elf: Revert LD_AUDIT fix for modules with invalid version (swbz#24122) +- strftime: Pass the additional flags from "%EY" to "%Ey" (swbz#24096) +- strftime: Set the default width of "%Ey" to 2 (swbz#23758) + +* Thu Jan 24 2019 Florian Weimer - 2.28.9000-33 +- Auto-sync with upstream branch master, + commit 3367acdb344a1d7fcf8f53748d301d652c8911dd: +- elf: Fix LD_AUDIT for modules with invalid version (swbz#24122) +- CVE-2016-10739: getaddrinfo: Fully parse IPv4 address strings (#1331390) +- resolv: Do not send queries for non-host-names in nss_dns (swbz#24112) +- malloc: Revert fastbins to old-style atomics + +* Wed Jan 23 2019 Florian Weimer - 2.28.9000-32 +- Use assembler to produce annobin notes for nonshared libraries (#1668822) + +* Wed Jan 16 2019 Carlos O'Donell - 2.28.9000-31 +- Auto-sync with upstream branch master, + commit 008b598e2a495024f9777006716cfd8668f3db33. +- x86-64: Optimize strcat/strncat, strcpy/strncpy and stpcpy/stpncpy with AVX2 +- powerpc: Fix VSCR position in ucontext (swbz#24088) +- AArch64: Add ifunc support for Ares +- soft-fp: Properly check _FP_W_TYPE_SIZE (swbz#24066) + +* Thu Jan 10 2019 Florian Weimer - 2.28.9000-30 +- Inherit -march=haswell flag from redhat-rpm-config + +* Mon Jan 07 2019 Arjun Shankar - 2.28.9000-29 +- Auto-sync with upstream branch master, + commit 2ef427168818ce04b03cecb7b739f9db0156e3e4. +- Require GCC 5 or later to build glibc (swbz#23993) +- Only build libm with -fno-math-errno (swbz#24024) +- sysdeps/ieee754: prevent maybe-uninitialized errors with -O (swbz#19444) +- Multiple locales: Use the correct 12-hour time formats (swbz#10496) +- sq_AL: Use the correct date and time formats (swbz#10496, swbz#23724) +- en_US: define date_fmt (swbz#24046) +- Remove executable bit from localedata/locales/bi_VU (swbz#23995) +- malloc: Always call memcpy in _int_realloc (swbz#24027) +- ARM: fix kernel assisted atomics with GCC 8 (swbz#24034) +- S390: Unify 31/64bit mem{set,cmp,cpy,pcpy}, bzero with ifunc handling +- S390: Refactor ifunc handling for several str* and wc* functions +- posix: Clear close-on-exec for posix_spawn adddup2 (swbz#23640) +- termios: Define TIOCSER_TEMT with __USE_MISC (swbz#17783) +- termios: Consolidate Baud Rate Selection definitions (swbz#23783) +- Y2038: add __{localtime64,gmttime64,ctime64}[_r] functions +- Y2038: make __difftime compatible with 64-bit time + +* Mon Dec 17 2018 DJ Delorie - 2.28.9000-28 +- Auto-sync with upstream branch master, + commit 6bbfc5c09fc5b5e3d4a0cddbbd4e2e457767dae7. +- Add statx conditionals for wordsize-32 *xstat.c +- regex: fix storage-exhaustion error (swbz#18040) +- regex: fix heap-use-after-free error (swbz#18040) +- manual: Document thread/task IDs for Linux + +* Thu Dec 13 2018 Carlos O'Donell - 2.28.9000-27 +- Auto-sync with upstream branch master, + commit ade8b817fead73b302d08c88cd44ea2ea56793d4. +- powerpc: missing CFI register information in __mpn_* functions (swbz#23614) +- rdlock stalls indefinitely on an unlocked pthread rwlock (swbz#23861) + +* Tue Dec 11 2018 Carlos O'Donell - 2.28.9000-26 +- Auto-sync with upstream branch master, + commit 505b5b292293a5d6bd4046a6bc7f8c2381a33da4. +- Fix powf overflow handling in non-nearest rounding mode (swbz#23961) +- test-container: move postclean outside of namespace changes (swbz#23948) +- Enable VDSO for static linking on mips (swbz#19767) + +* Mon Dec 10 2018 Florian Weimer - 2.28.9000-25 +- Auto-sync with upstream branch master, + commit 8d20a2f414fa52aceef8a0e3675415df54a840db: +- compat getdents64: Use correct offset for retry (swbz#23972) +- x86: Fix static analysis warning in tst-cet-property-2 (swbz#23490) +- malloc: Add another test for tcache double free check (swbz#23907) +- getcpu: New system call wrapper +- posix_spawn_file_actions_addfchdir_np: New function (swbz#17405) +- Preparations for the IBM long double transition +- Preparations for 64-bit time_t on 32-bit architectures +- Enable VDSO for static linking on arm (swbz#19767) + +* Mon Dec 03 2018 Florian Weimer - 2.28.9000-24 +- Auto-sync with upstream branch master, + commit 7b36d26b22d147ffc347f427f9fd584700578a94: +- CVE-2018-19591: if_nametoindex: Fix descriptor for overlong name (#1654000) +- Mutex: Add pthread mutex tunables +- stdlib: assert on NULL function pointer in atexit etc. (swbz#20544) +- Enable VDSO on i386 statically linked programs +- posix: Use posix_spawn on system +- posix: Use posix_spawn on popen (swbz#17490, swbz#22834) +- Fix _dl_profile_fixup data-dependency issue (swbz#23690) +- Enable VDSO for static linking on aarch64 + +* Thu Nov 29 2018 Carlos O'Donell - 2.28.9000-23 +- Move requirement on libgcc from glibc-devel to glibc (#1352973) + +* Tue Nov 27 2018 Carlos O'Donell - 2.28.9000-22 +- Add requires on explicit glibc version for glibc-nss-devel (#1651260) + +* Tue Nov 27 2018 Arjun Shankar - 2.28.9000-21 +- Drop glibc-rh1652495.patch. Applied upstream. (#1652495) +- Auto-sync with upstream branch master, + commit ce035c6e909ad20ef2fe13c92eab4e69f6495b61. + +* Mon Nov 26 2018 Florian Weimer - 2.28.9000-20 +- Do not use parallel make for building locales (#1652228) + +* Thu Nov 22 2018 Florian Weimer - 2.28.9000-19 +- malloc: Revert tcache double-free check (#1652495) + +* Tue Nov 20 2018 DJ Delorie - 2.28.9000-18 +- Auto-sync with upstream branch master, + commit bcdaad21d4635931d1bd3b54a7894276925d081d. +- malloc: tcache double free check +- [AArch64] Adjust writeback in non-zero memset +- Update config.guess and config.sub to current versions. +- support: Print timestamps in timeout handler +- Use STRFMON_LDBL_IS_DBL instead of __ldbl_is_dbl. + +* Fri Nov 16 2018 Florian Weimer - 2.28.9000-17 +- Auto-sync with upstream branch master, + commit 346ef23f197a0c8ba807c344bd39101b711050ee. + +* Fri Nov 09 2018 Florian Weimer - 2.28.9000-16 +- Auto-sync with upstream branch master, + commit 43257c335ad6b9e05fb882975e1776ff763164ee: +- Disable CET for binaries created by older link editors (#1648297) + +* Wed Nov 07 2018 Florian Weimer - 2.28.9000-15 +- Auto-sync with upstream branch master, + commit 00c86a37d1b63044e3169d1f2ebec23447c73f79. + +* Wed Nov 07 2018 Florian Weimer - 2.28.9000-14 +- Auto-sync with upstream branch master, + commit 1df872fd74f730bcae3df201a229195445d2e18a: +- libanl: Fix crash if first helper thread creation failed (#1646381) + +* Thu Nov 1 2018 Mike FABIAN - 2.28.9000-13 +- Include Esperanto (eo) in glibc-all-langpacks (#1643756) + +* Mon Oct 29 2018 DJ Delorie - 2.28.9000-12 +- Auto-sync with upstream branch master, + commit c6982f7efc1c70fe2d6160a87ee44d871ac85ab0. + +* Fri Oct 26 2018 Arjun Shankar - 2.28.9000-11 +- Auto-sync with upstream branch master, + commit fe61f17cfc18f17befca3280e828bb40e8c772b0. + +* Wed Oct 24 2018 Florian Weimer - 2.28.9000-10 +- Auto-sync with upstream branch master, + commit a27a4f4721837a5fb36ace833764b06a64c5af1c. + +* Thu Oct 18 2018 Florian Weimer - 2.28.9000-9 +- Auto-sync with upstream branch master, + commit 72771e53753647111d31c5c4bf43d8901e6baf7e. + +* Thu Sep 27 2018 Florian Weimer - 2.28.9000-8 +- Auto-sync with upstream branch master, + commit f841c97e515a1673485a2b12b3c280073d737890: +- stdlib/tst-setcontext9 test suite failure on ppc64le (#1623519) + +* Thu Sep 20 2018 Florian Weimer - 2.28.9000-7 +- Auto-sync with upstream branch master, + commit db9a8ad4ff3fc58e3773a9a4d0cabe3c1bc9c94c: +- gethostid: Missing NULL check for gethostbyname_r result (#1631338) +- stdlib/tst-setcontext9 test suite failure (#1623519) + +* Wed Sep 5 2018 Florian Weimer - 2.28.9000-6 +- Add python3-devel build dependency for downstream benefit + +* Wed Sep 05 2018 Carlos O'Donell - 2.28.9000-5 +- Provide compatibility support for linking against libpthread_nonshared.a + (#1625507) + +* Wed Aug 29 2018 Florian Weimer - 2.28.9000-4 +- Remove workaround for valgrind bug (#1600034) + +* Wed Aug 29 2018 Florian Weimer - 2.28.9000-3 +- Auto-sync with upstream branch master, + commit ff6b24501f70da7d6375d6f5929262b9509db39e. + +* Mon Aug 27 2018 Florian Weimer - 2.28.9000-2 +- Auto-sync with upstream branch master, + commit 99ea93ca31795469d2a1f1570f17a5c39c2eb7e2: +- nptl: Fix waiters-after-spinning case in pthread_cond_broadcast (#1622669) +- regex: Fix memory corruption when pattern and input contain NUL (#1622674) + +* Tue Aug 21 2018 Carlos O'Donell - 2.28.9000-1 +- Drop glibc-asflags.patch. Applied upstream. +- Drop glibc-rh1614705.patch. Applied upstream. +- Drop glibc-with-nonshared-cflags.patch. Applied upstream. +- Auto-sync with upstream branch master, + commit aa42b3dbcb0326badf377fec2c7fb2f34fdabecd. + +* Mon Aug 13 2018 Carlos O'Donell - 2.28-5 +- Remove abort() warning in manual (#1615608) + +* Fri Aug 10 2018 Florian Weimer - 2.28-4 +- Fix regression in readdir64@GLIBC_2.1 compat symbol (#1614705) + +* 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) + +* 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/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/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-1.patch b/SOURCES/glibc-c-utf8-locale-1.patch new file mode 100644 index 0000000..3b80064 --- /dev/null +++ b/SOURCES/glibc-c-utf8-locale-1.patch @@ -0,0 +1,980 @@ +commit f5117c6504888fab5423282a4607c552b90fd3f9 +Author: Carlos O'Donell +Date: Thu Jul 29 22:45:39 2021 -0400 + + Add 'codepoint_collation' support for LC_COLLATE. + + Support a new directive 'codepoint_collation' in the LC_COLLATE + section of a locale source file. This new directive causes all + collation rules to be dropped and instead STRCMP (strcmp or + wcscmp) is used for collation of the input character set. This + is required to allow for a C.UTF-8 that contains zero collation + rules (minimal size) and sorts using code point sorting. + + To date the only implementation of a locale with zero collation + rules is the C/POSIX locale. The C/POSIX locale provides + identity tables for _NL_COLLATE_COLLSEQMB and + _NL_COLLATE_COLLSEQWC that map to ASCII even though it has zero + rules. This has lead to existing fnmatch, regexec, and regcomp + implementations that require these tables. It is not correct + to use these tables when nrules == 0, but the conservative fix + is to provide these tables when nrules == 0. This assures that + existing static applications using a new C.UTF-8 locale with + 'codepoint_collation' at least have functional range expressions + with ASCII e.g. [0-9] or [a-z]. Such static applications would + not have the fixes to fnmatch, regexec and regcomp that avoid + the use of the tables when nrules == 0. Future fixes to fnmatch, + regexec, and regcomp would allow range expressions to use the + full set of code points for such ranges. + + Tested on x86_64 and i686 without regression. + + Reviewed-by: Florian Weimer + +diff --git a/locale/C-collate-seq.c b/locale/C-collate-seq.c +new file mode 100644 +index 0000000000000000..4fb82cb8357936b6 +--- /dev/null ++++ b/locale/C-collate-seq.c +@@ -0,0 +1,100 @@ ++/* Copyright (C) 1995-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++static const char collseqmb[] = ++{ ++ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', ++ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', ++ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', ++ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', ++ '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', ++ '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f', ++ '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', ++ '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f', ++ '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', ++ '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f', ++ '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', ++ '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f', ++ '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', ++ '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', ++ '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', ++ '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f', ++ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', ++ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', ++ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', ++ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', ++ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', ++ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', ++ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', ++ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', ++ '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', ++ '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', ++ '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', ++ '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', ++ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', ++ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', ++ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', ++ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' ++}; ++ ++/* This table must be 256 bytes in size. We index bytes into the ++ table to find the collation sequence. */ ++_Static_assert (sizeof (collseqmb) == 256); ++ ++static const uint32_t collseqwc[] = ++{ ++ 8, 1, 8, 0x0, 0xff, ++ /* 1st-level table */ ++ 6 * sizeof (uint32_t), ++ /* 2nd-level table */ ++ 7 * sizeof (uint32_t), ++ /* 3rd-level table */ ++ L'\x00', L'\x01', L'\x02', L'\x03', L'\x04', L'\x05', L'\x06', L'\x07', ++ L'\x08', L'\x09', L'\x0a', L'\x0b', L'\x0c', L'\x0d', L'\x0e', L'\x0f', ++ L'\x10', L'\x11', L'\x12', L'\x13', L'\x14', L'\x15', L'\x16', L'\x17', ++ L'\x18', L'\x19', L'\x1a', L'\x1b', L'\x1c', L'\x1d', L'\x1e', L'\x1f', ++ L'\x20', L'\x21', L'\x22', L'\x23', L'\x24', L'\x25', L'\x26', L'\x27', ++ L'\x28', L'\x29', L'\x2a', L'\x2b', L'\x2c', L'\x2d', L'\x2e', L'\x2f', ++ L'\x30', L'\x31', L'\x32', L'\x33', L'\x34', L'\x35', L'\x36', L'\x37', ++ L'\x38', L'\x39', L'\x3a', L'\x3b', L'\x3c', L'\x3d', L'\x3e', L'\x3f', ++ L'\x40', L'\x41', L'\x42', L'\x43', L'\x44', L'\x45', L'\x46', L'\x47', ++ L'\x48', L'\x49', L'\x4a', L'\x4b', L'\x4c', L'\x4d', L'\x4e', L'\x4f', ++ L'\x50', L'\x51', L'\x52', L'\x53', L'\x54', L'\x55', L'\x56', L'\x57', ++ L'\x58', L'\x59', L'\x5a', L'\x5b', L'\x5c', L'\x5d', L'\x5e', L'\x5f', ++ L'\x60', L'\x61', L'\x62', L'\x63', L'\x64', L'\x65', L'\x66', L'\x67', ++ L'\x68', L'\x69', L'\x6a', L'\x6b', L'\x6c', L'\x6d', L'\x6e', L'\x6f', ++ L'\x70', L'\x71', L'\x72', L'\x73', L'\x74', L'\x75', L'\x76', L'\x77', ++ L'\x78', L'\x79', L'\x7a', L'\x7b', L'\x7c', L'\x7d', L'\x7e', L'\x7f', ++ L'\x80', L'\x81', L'\x82', L'\x83', L'\x84', L'\x85', L'\x86', L'\x87', ++ L'\x88', L'\x89', L'\x8a', L'\x8b', L'\x8c', L'\x8d', L'\x8e', L'\x8f', ++ L'\x90', L'\x91', L'\x92', L'\x93', L'\x94', L'\x95', L'\x96', L'\x97', ++ L'\x98', L'\x99', L'\x9a', L'\x9b', L'\x9c', L'\x9d', L'\x9e', L'\x9f', ++ L'\xa0', L'\xa1', L'\xa2', L'\xa3', L'\xa4', L'\xa5', L'\xa6', L'\xa7', ++ L'\xa8', L'\xa9', L'\xaa', L'\xab', L'\xac', L'\xad', L'\xae', L'\xaf', ++ L'\xb0', L'\xb1', L'\xb2', L'\xb3', L'\xb4', L'\xb5', L'\xb6', L'\xb7', ++ L'\xb8', L'\xb9', L'\xba', L'\xbb', L'\xbc', L'\xbd', L'\xbe', L'\xbf', ++ L'\xc0', L'\xc1', L'\xc2', L'\xc3', L'\xc4', L'\xc5', L'\xc6', L'\xc7', ++ L'\xc8', L'\xc9', L'\xca', L'\xcb', L'\xcc', L'\xcd', L'\xce', L'\xcf', ++ L'\xd0', L'\xd1', L'\xd2', L'\xd3', L'\xd4', L'\xd5', L'\xd6', L'\xd7', ++ L'\xd8', L'\xd9', L'\xda', L'\xdb', L'\xdc', L'\xdd', L'\xde', L'\xdf', ++ L'\xe0', L'\xe1', L'\xe2', L'\xe3', L'\xe4', L'\xe5', L'\xe6', L'\xe7', ++ L'\xe8', L'\xe9', L'\xea', L'\xeb', L'\xec', L'\xed', L'\xee', L'\xef', ++ L'\xf0', L'\xf1', L'\xf2', L'\xf3', L'\xf4', L'\xf5', L'\xf6', L'\xf7', ++ L'\xf8', L'\xf9', L'\xfa', L'\xfb', L'\xfc', L'\xfd', L'\xfe', L'\xff' ++}; +diff --git a/locale/C-collate.c b/locale/C-collate.c +index 76d9373683314943..120ce0a40aeb9a0f 100644 +--- a/locale/C-collate.c ++++ b/locale/C-collate.c +@@ -20,83 +20,7 @@ + #include + #include "localeinfo.h" + +-static const char collseqmb[] = +-{ +- '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', +- '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', +- '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', +- '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', +- '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', +- '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f', +- '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', +- '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f', +- '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', +- '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f', +- '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', +- '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f', +- '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', +- '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', +- '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', +- '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f', +- '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', +- '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', +- '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', +- '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', +- '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', +- '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', +- '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', +- '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', +- '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', +- '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', +- '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', +- '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', +- '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', +- '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', +- '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', +- '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' +-}; +- +-static const uint32_t collseqwc[] = +-{ +- 8, 1, 8, 0x0, 0xff, +- /* 1st-level table */ +- 6 * sizeof (uint32_t), +- /* 2nd-level table */ +- 7 * sizeof (uint32_t), +- /* 3rd-level table */ +- L'\x00', L'\x01', L'\x02', L'\x03', L'\x04', L'\x05', L'\x06', L'\x07', +- L'\x08', L'\x09', L'\x0a', L'\x0b', L'\x0c', L'\x0d', L'\x0e', L'\x0f', +- L'\x10', L'\x11', L'\x12', L'\x13', L'\x14', L'\x15', L'\x16', L'\x17', +- L'\x18', L'\x19', L'\x1a', L'\x1b', L'\x1c', L'\x1d', L'\x1e', L'\x1f', +- L'\x20', L'\x21', L'\x22', L'\x23', L'\x24', L'\x25', L'\x26', L'\x27', +- L'\x28', L'\x29', L'\x2a', L'\x2b', L'\x2c', L'\x2d', L'\x2e', L'\x2f', +- L'\x30', L'\x31', L'\x32', L'\x33', L'\x34', L'\x35', L'\x36', L'\x37', +- L'\x38', L'\x39', L'\x3a', L'\x3b', L'\x3c', L'\x3d', L'\x3e', L'\x3f', +- L'\x40', L'\x41', L'\x42', L'\x43', L'\x44', L'\x45', L'\x46', L'\x47', +- L'\x48', L'\x49', L'\x4a', L'\x4b', L'\x4c', L'\x4d', L'\x4e', L'\x4f', +- L'\x50', L'\x51', L'\x52', L'\x53', L'\x54', L'\x55', L'\x56', L'\x57', +- L'\x58', L'\x59', L'\x5a', L'\x5b', L'\x5c', L'\x5d', L'\x5e', L'\x5f', +- L'\x60', L'\x61', L'\x62', L'\x63', L'\x64', L'\x65', L'\x66', L'\x67', +- L'\x68', L'\x69', L'\x6a', L'\x6b', L'\x6c', L'\x6d', L'\x6e', L'\x6f', +- L'\x70', L'\x71', L'\x72', L'\x73', L'\x74', L'\x75', L'\x76', L'\x77', +- L'\x78', L'\x79', L'\x7a', L'\x7b', L'\x7c', L'\x7d', L'\x7e', L'\x7f', +- L'\x80', L'\x81', L'\x82', L'\x83', L'\x84', L'\x85', L'\x86', L'\x87', +- L'\x88', L'\x89', L'\x8a', L'\x8b', L'\x8c', L'\x8d', L'\x8e', L'\x8f', +- L'\x90', L'\x91', L'\x92', L'\x93', L'\x94', L'\x95', L'\x96', L'\x97', +- L'\x98', L'\x99', L'\x9a', L'\x9b', L'\x9c', L'\x9d', L'\x9e', L'\x9f', +- L'\xa0', L'\xa1', L'\xa2', L'\xa3', L'\xa4', L'\xa5', L'\xa6', L'\xa7', +- L'\xa8', L'\xa9', L'\xaa', L'\xab', L'\xac', L'\xad', L'\xae', L'\xaf', +- L'\xb0', L'\xb1', L'\xb2', L'\xb3', L'\xb4', L'\xb5', L'\xb6', L'\xb7', +- L'\xb8', L'\xb9', L'\xba', L'\xbb', L'\xbc', L'\xbd', L'\xbe', L'\xbf', +- L'\xc0', L'\xc1', L'\xc2', L'\xc3', L'\xc4', L'\xc5', L'\xc6', L'\xc7', +- L'\xc8', L'\xc9', L'\xca', L'\xcb', L'\xcc', L'\xcd', L'\xce', L'\xcf', +- L'\xd0', L'\xd1', L'\xd2', L'\xd3', L'\xd4', L'\xd5', L'\xd6', L'\xd7', +- L'\xd8', L'\xd9', L'\xda', L'\xdb', L'\xdc', L'\xdd', L'\xde', L'\xdf', +- L'\xe0', L'\xe1', L'\xe2', L'\xe3', L'\xe4', L'\xe5', L'\xe6', L'\xe7', +- L'\xe8', L'\xe9', L'\xea', L'\xeb', L'\xec', L'\xed', L'\xee', L'\xef', +- L'\xf0', L'\xf1', L'\xf2', L'\xf3', L'\xf4', L'\xf5', L'\xf6', L'\xf7', +- L'\xf8', L'\xf9', L'\xfa', L'\xfb', L'\xfc', L'\xfd', L'\xfe', L'\xff' +-}; ++#include "C-collate-seq.c" + + const struct __locale_data _nl_C_LC_COLLATE attribute_hidden = + { +diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c +index b6406b775d3a81ad..0f314e40c4305dea 100644 +--- a/locale/programs/ld-collate.c ++++ b/locale/programs/ld-collate.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include "localedef.h" + #include "charmap.h" +@@ -195,6 +196,9 @@ struct name_list + /* The real definition of the struct for the LC_COLLATE locale. */ + struct locale_collate_t + { ++ /* Does the locale use code points to compare the encoding? */ ++ bool codepoint_collation; ++ + int col_weight_max; + int cur_weight_max; + +@@ -1510,6 +1514,7 @@ collate_startup (struct linereader *ldfile, struct localedef_t *locale, + obstack_init (&collate->mempool); + + collate->col_weight_max = -1; ++ collate->codepoint_collation = false; + } + else + /* Reuse the copy_locale's data structures. */ +@@ -1568,6 +1573,10 @@ collate_finish (struct localedef_t *locale, const struct charmap_t *charmap) + return; + } + ++ /* No data required. */ ++ if (collate->codepoint_collation) ++ return; ++ + /* If this assertion is hit change the type in `element_t'. */ + assert (nrules <= sizeof (runp->used_in_level) * 8); + +@@ -2092,6 +2101,10 @@ add_to_tablewc (uint32_t ch, struct element_t *runp) + } + } + ++/* Include the C locale identity tables for _NL_COLLATE_COLLSEQMB and ++ _NL_COLLATE_COLLSEQWC. */ ++#include "C-collate-seq.c" ++ + void + collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + const char *output_path) +@@ -2115,7 +2128,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + add_locale_uint32 (&file, nrules); + + /* If we have no LC_COLLATE data emit only the number of rules as zero. */ +- if (collate == NULL) ++ if (collate == NULL || collate->codepoint_collation) + { + size_t idx; + for (idx = 1; idx < nelems; idx++) +@@ -2123,6 +2136,17 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + /* The words have to be handled specially. */ + if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB)) + add_locale_uint32 (&file, 0); ++ else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_CODESET) ++ && collate != NULL) ++ /* A valid LC_COLLATE must have a code set name. */ ++ add_locale_string (&file, charmap->code_set_name); ++ else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQMB) ++ && collate != NULL) ++ add_locale_raw_data (&file, collseqmb, sizeof (collseqmb)); ++ else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQWC) ++ && collate != NULL) ++ add_locale_uint32_array (&file, collseqwc, ++ array_length (collseqwc)); + else + add_locale_empty (&file); + } +@@ -2672,6 +2696,10 @@ collate_read (struct linereader *ldfile, struct localedef_t *result, + + switch (nowtok) + { ++ case tok_codepoint_collation: ++ collate->codepoint_collation = true; ++ break; ++ + case tok_copy: + /* Allow copying other locales. */ + now = lr_token (ldfile, charmap, result, NULL, verbose); +@@ -3742,9 +3770,11 @@ error while adding equivalent collating symbol")); + /* Next we assume `LC_COLLATE'. */ + if (!ignore_content) + { +- if (state == 0 && copy_locale == NULL) ++ if (state == 0 ++ && copy_locale == NULL ++ && !collate->codepoint_collation) + /* We must either see a copy statement or have +- ordering values. */ ++ ordering values, or codepoint_collation. */ + lr_error (ldfile, + _("%s: empty category description not allowed"), + "LC_COLLATE"); +diff --git a/locale/programs/locfile-kw.gperf b/locale/programs/locfile-kw.gperf +index bcded15ddb4c44bb..2e59eb9ac014134b 100644 +--- a/locale/programs/locfile-kw.gperf ++++ b/locale/programs/locfile-kw.gperf +@@ -54,6 +54,7 @@ translit_end, tok_translit_end, 0 + translit_ignore, tok_translit_ignore, 0 + default_missing, tok_default_missing, 0 + LC_COLLATE, tok_lc_collate, 0 ++codepoint_collation, tok_codepoint_collation, 0 + coll_weight_max, tok_coll_weight_max, 0 + section-symbol, tok_section_symbol, 0 + collating-element, tok_collating_element, 0 +diff --git a/locale/programs/locfile-kw.h b/locale/programs/locfile-kw.h +index bc1cb8f0845852ad..fe6335692bd422cd 100644 +--- a/locale/programs/locfile-kw.h ++++ b/locale/programs/locfile-kw.h +@@ -54,7 +54,7 @@ + #line 24 "locfile-kw.gperf" + struct keyword_t ; + +-#define TOTAL_KEYWORDS 178 ++#define TOTAL_KEYWORDS 179 + #define MIN_WORD_LENGTH 3 + #define MAX_WORD_LENGTH 22 + #define MIN_HASH_VALUE 3 +@@ -134,92 +134,92 @@ locfile_hash (register const char *str, register size_t len) + #line 31 "locfile-kw.gperf" + {"END", tok_end, 0}, + {""}, {""}, +-#line 70 "locfile-kw.gperf" ++#line 71 "locfile-kw.gperf" + {"IGNORE", tok_ignore, 0}, +-#line 129 "locfile-kw.gperf" ++#line 130 "locfile-kw.gperf" + {"LC_TIME", tok_lc_time, 0}, + #line 30 "locfile-kw.gperf" + {"LC_CTYPE", tok_lc_ctype, 0}, + {""}, +-#line 168 "locfile-kw.gperf" ++#line 169 "locfile-kw.gperf" + {"LC_ADDRESS", tok_lc_address, 0}, +-#line 153 "locfile-kw.gperf" ++#line 154 "locfile-kw.gperf" + {"LC_MESSAGES", tok_lc_messages, 0}, +-#line 161 "locfile-kw.gperf" ++#line 162 "locfile-kw.gperf" + {"LC_NAME", tok_lc_name, 0}, +-#line 158 "locfile-kw.gperf" ++#line 159 "locfile-kw.gperf" + {"LC_PAPER", tok_lc_paper, 0}, +-#line 186 "locfile-kw.gperf" ++#line 187 "locfile-kw.gperf" + {"LC_MEASUREMENT", tok_lc_measurement, 0}, + #line 56 "locfile-kw.gperf" + {"LC_COLLATE", tok_lc_collate, 0}, + {""}, +-#line 188 "locfile-kw.gperf" ++#line 189 "locfile-kw.gperf" + {"LC_IDENTIFICATION", tok_lc_identification, 0}, +-#line 201 "locfile-kw.gperf" ++#line 202 "locfile-kw.gperf" + {"revision", tok_revision, 0}, +-#line 69 "locfile-kw.gperf" ++#line 70 "locfile-kw.gperf" + {"UNDEFINED", tok_undefined, 0}, +-#line 125 "locfile-kw.gperf" ++#line 126 "locfile-kw.gperf" + {"LC_NUMERIC", tok_lc_numeric, 0}, +-#line 82 "locfile-kw.gperf" ++#line 83 "locfile-kw.gperf" + {"LC_MONETARY", tok_lc_monetary, 0}, +-#line 181 "locfile-kw.gperf" ++#line 182 "locfile-kw.gperf" + {"LC_TELEPHONE", tok_lc_telephone, 0}, + {""}, {""}, {""}, +-#line 75 "locfile-kw.gperf" ++#line 76 "locfile-kw.gperf" + {"define", tok_define, 0}, +-#line 154 "locfile-kw.gperf" ++#line 155 "locfile-kw.gperf" + {"yesexpr", tok_yesexpr, 0}, +-#line 141 "locfile-kw.gperf" ++#line 142 "locfile-kw.gperf" + {"era_year", tok_era_year, 0}, + {""}, + #line 54 "locfile-kw.gperf" + {"translit_ignore", tok_translit_ignore, 0}, +-#line 156 "locfile-kw.gperf" ++#line 157 "locfile-kw.gperf" + {"yesstr", tok_yesstr, 0}, + {""}, +-#line 89 "locfile-kw.gperf" ++#line 90 "locfile-kw.gperf" + {"negative_sign", tok_negative_sign, 0}, + {""}, +-#line 137 "locfile-kw.gperf" ++#line 138 "locfile-kw.gperf" + {"t_fmt", tok_t_fmt, 0}, +-#line 159 "locfile-kw.gperf" ++#line 160 "locfile-kw.gperf" + {"height", tok_height, 0}, + {""}, {""}, + #line 52 "locfile-kw.gperf" + {"translit_start", tok_translit_start, 0}, +-#line 136 "locfile-kw.gperf" ++#line 137 "locfile-kw.gperf" + {"d_fmt", tok_d_fmt, 0}, + {""}, + #line 53 "locfile-kw.gperf" + {"translit_end", tok_translit_end, 0}, +-#line 94 "locfile-kw.gperf" ++#line 95 "locfile-kw.gperf" + {"n_cs_precedes", tok_n_cs_precedes, 0}, +-#line 144 "locfile-kw.gperf" ++#line 145 "locfile-kw.gperf" + {"era_t_fmt", tok_era_t_fmt, 0}, + #line 39 "locfile-kw.gperf" + {"space", tok_space, 0}, +-#line 72 "locfile-kw.gperf" +- {"reorder-end", tok_reorder_end, 0}, + #line 73 "locfile-kw.gperf" ++ {"reorder-end", tok_reorder_end, 0}, ++#line 74 "locfile-kw.gperf" + {"reorder-sections-after", tok_reorder_sections_after, 0}, + {""}, +-#line 142 "locfile-kw.gperf" ++#line 143 "locfile-kw.gperf" + {"era_d_fmt", tok_era_d_fmt, 0}, +-#line 189 "locfile-kw.gperf" ++#line 190 "locfile-kw.gperf" + {"title", tok_title, 0}, + {""}, {""}, +-#line 149 "locfile-kw.gperf" ++#line 150 "locfile-kw.gperf" + {"timezone", tok_timezone, 0}, + {""}, +-#line 74 "locfile-kw.gperf" ++#line 75 "locfile-kw.gperf" + {"reorder-sections-end", tok_reorder_sections_end, 0}, + {""}, {""}, {""}, +-#line 95 "locfile-kw.gperf" ++#line 96 "locfile-kw.gperf" + {"n_sep_by_space", tok_n_sep_by_space, 0}, + {""}, {""}, +-#line 100 "locfile-kw.gperf" ++#line 101 "locfile-kw.gperf" + {"int_n_cs_precedes", tok_int_n_cs_precedes, 0}, + {""}, {""}, {""}, + #line 26 "locfile-kw.gperf" +@@ -233,147 +233,147 @@ locfile_hash (register const char *str, register size_t len) + {"print", tok_print, 0}, + #line 44 "locfile-kw.gperf" + {"xdigit", tok_xdigit, 0}, +-#line 110 "locfile-kw.gperf" ++#line 111 "locfile-kw.gperf" + {"duo_n_cs_precedes", tok_duo_n_cs_precedes, 0}, +-#line 127 "locfile-kw.gperf" ++#line 128 "locfile-kw.gperf" + {"thousands_sep", tok_thousands_sep, 0}, +-#line 197 "locfile-kw.gperf" ++#line 198 "locfile-kw.gperf" + {"territory", tok_territory, 0}, + #line 36 "locfile-kw.gperf" + {"digit", tok_digit, 0}, + {""}, {""}, +-#line 92 "locfile-kw.gperf" ++#line 93 "locfile-kw.gperf" + {"p_cs_precedes", tok_p_cs_precedes, 0}, + {""}, {""}, +-#line 62 "locfile-kw.gperf" ++#line 63 "locfile-kw.gperf" + {"script", tok_script, 0}, + #line 29 "locfile-kw.gperf" + {"include", tok_include, 0}, + {""}, +-#line 78 "locfile-kw.gperf" ++#line 79 "locfile-kw.gperf" + {"else", tok_else, 0}, +-#line 184 "locfile-kw.gperf" ++#line 185 "locfile-kw.gperf" + {"int_select", tok_int_select, 0}, + {""}, {""}, {""}, +-#line 132 "locfile-kw.gperf" ++#line 133 "locfile-kw.gperf" + {"week", tok_week, 0}, + #line 33 "locfile-kw.gperf" + {"upper", tok_upper, 0}, + {""}, {""}, +-#line 194 "locfile-kw.gperf" ++#line 195 "locfile-kw.gperf" + {"tel", tok_tel, 0}, +-#line 93 "locfile-kw.gperf" ++#line 94 "locfile-kw.gperf" + {"p_sep_by_space", tok_p_sep_by_space, 0}, +-#line 160 "locfile-kw.gperf" ++#line 161 "locfile-kw.gperf" + {"width", tok_width, 0}, + {""}, +-#line 98 "locfile-kw.gperf" ++#line 99 "locfile-kw.gperf" + {"int_p_cs_precedes", tok_int_p_cs_precedes, 0}, + {""}, {""}, + #line 41 "locfile-kw.gperf" + {"punct", tok_punct, 0}, + {""}, {""}, +-#line 101 "locfile-kw.gperf" ++#line 102 "locfile-kw.gperf" + {"int_n_sep_by_space", tok_int_n_sep_by_space, 0}, + {""}, {""}, {""}, +-#line 108 "locfile-kw.gperf" ++#line 109 "locfile-kw.gperf" + {"duo_p_cs_precedes", tok_duo_p_cs_precedes, 0}, + #line 48 "locfile-kw.gperf" + {"charconv", tok_charconv, 0}, + {""}, + #line 47 "locfile-kw.gperf" + {"class", tok_class, 0}, +-#line 114 "locfile-kw.gperf" +- {"duo_int_n_cs_precedes", tok_duo_int_n_cs_precedes, 0}, + #line 115 "locfile-kw.gperf" ++ {"duo_int_n_cs_precedes", tok_duo_int_n_cs_precedes, 0}, ++#line 116 "locfile-kw.gperf" + {"duo_int_n_sep_by_space", tok_duo_int_n_sep_by_space, 0}, +-#line 111 "locfile-kw.gperf" ++#line 112 "locfile-kw.gperf" + {"duo_n_sep_by_space", tok_duo_n_sep_by_space, 0}, +-#line 119 "locfile-kw.gperf" ++#line 120 "locfile-kw.gperf" + {"duo_int_n_sign_posn", tok_duo_int_n_sign_posn, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, +-#line 58 "locfile-kw.gperf" ++#line 59 "locfile-kw.gperf" + {"section-symbol", tok_section_symbol, 0}, +-#line 185 "locfile-kw.gperf" ++#line 186 "locfile-kw.gperf" + {"int_prefix", tok_int_prefix, 0}, + {""}, {""}, {""}, {""}, + #line 42 "locfile-kw.gperf" + {"graph", tok_graph, 0}, + {""}, {""}, +-#line 99 "locfile-kw.gperf" ++#line 100 "locfile-kw.gperf" + {"int_p_sep_by_space", tok_int_p_sep_by_space, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 112 "locfile-kw.gperf" +- {"duo_int_p_cs_precedes", tok_duo_int_p_cs_precedes, 0}, + #line 113 "locfile-kw.gperf" ++ {"duo_int_p_cs_precedes", tok_duo_int_p_cs_precedes, 0}, ++#line 114 "locfile-kw.gperf" + {"duo_int_p_sep_by_space", tok_duo_int_p_sep_by_space, 0}, +-#line 109 "locfile-kw.gperf" ++#line 110 "locfile-kw.gperf" + {"duo_p_sep_by_space", tok_duo_p_sep_by_space, 0}, +-#line 118 "locfile-kw.gperf" ++#line 119 "locfile-kw.gperf" + {"duo_int_p_sign_posn", tok_duo_int_p_sign_posn, 0}, +-#line 157 "locfile-kw.gperf" ++#line 158 "locfile-kw.gperf" + {"nostr", tok_nostr, 0}, + {""}, {""}, +-#line 140 "locfile-kw.gperf" ++#line 141 "locfile-kw.gperf" + {"era", tok_era, 0}, + {""}, +-#line 84 "locfile-kw.gperf" ++#line 85 "locfile-kw.gperf" + {"currency_symbol", tok_currency_symbol, 0}, + {""}, +-#line 167 "locfile-kw.gperf" ++#line 168 "locfile-kw.gperf" + {"name_ms", tok_name_ms, 0}, +-#line 165 "locfile-kw.gperf" +- {"name_mrs", tok_name_mrs, 0}, + #line 166 "locfile-kw.gperf" ++ {"name_mrs", tok_name_mrs, 0}, ++#line 167 "locfile-kw.gperf" + {"name_miss", tok_name_miss, 0}, +-#line 83 "locfile-kw.gperf" ++#line 84 "locfile-kw.gperf" + {"int_curr_symbol", tok_int_curr_symbol, 0}, +-#line 190 "locfile-kw.gperf" ++#line 191 "locfile-kw.gperf" + {"source", tok_source, 0}, +-#line 164 "locfile-kw.gperf" ++#line 165 "locfile-kw.gperf" + {"name_mr", tok_name_mr, 0}, +-#line 163 "locfile-kw.gperf" ++#line 164 "locfile-kw.gperf" + {"name_gen", tok_name_gen, 0}, +-#line 202 "locfile-kw.gperf" ++#line 203 "locfile-kw.gperf" + {"date", tok_date, 0}, + {""}, {""}, +-#line 191 "locfile-kw.gperf" ++#line 192 "locfile-kw.gperf" + {"address", tok_address, 0}, +-#line 162 "locfile-kw.gperf" ++#line 163 "locfile-kw.gperf" + {"name_fmt", tok_name_fmt, 0}, + #line 32 "locfile-kw.gperf" + {"copy", tok_copy, 0}, +-#line 103 "locfile-kw.gperf" ++#line 104 "locfile-kw.gperf" + {"int_n_sign_posn", tok_int_n_sign_posn, 0}, + {""}, {""}, +-#line 131 "locfile-kw.gperf" ++#line 132 "locfile-kw.gperf" + {"day", tok_day, 0}, +-#line 105 "locfile-kw.gperf" ++#line 106 "locfile-kw.gperf" + {"duo_currency_symbol", tok_duo_currency_symbol, 0}, + {""}, {""}, {""}, +-#line 150 "locfile-kw.gperf" ++#line 151 "locfile-kw.gperf" + {"date_fmt", tok_date_fmt, 0}, +-#line 64 "locfile-kw.gperf" ++#line 65 "locfile-kw.gperf" + {"order_end", tok_order_end, 0}, +-#line 117 "locfile-kw.gperf" ++#line 118 "locfile-kw.gperf" + {"duo_n_sign_posn", tok_duo_n_sign_posn, 0}, + {""}, +-#line 170 "locfile-kw.gperf" ++#line 171 "locfile-kw.gperf" + {"country_name", tok_country_name, 0}, +-#line 71 "locfile-kw.gperf" ++#line 72 "locfile-kw.gperf" + {"reorder-after", tok_reorder_after, 0}, + {""}, {""}, +-#line 155 "locfile-kw.gperf" ++#line 156 "locfile-kw.gperf" + {"noexpr", tok_noexpr, 0}, + #line 50 "locfile-kw.gperf" + {"tolower", tok_tolower, 0}, +-#line 198 "locfile-kw.gperf" ++#line 199 "locfile-kw.gperf" + {"audience", tok_audience, 0}, + {""}, {""}, {""}, + #line 49 "locfile-kw.gperf" + {"toupper", tok_toupper, 0}, +-#line 68 "locfile-kw.gperf" ++#line 69 "locfile-kw.gperf" + {"position", tok_position, 0}, + {""}, + #line 40 "locfile-kw.gperf" +@@ -381,196 +381,197 @@ locfile_hash (register const char *str, register size_t len) + {""}, + #line 27 "locfile-kw.gperf" + {"comment_char", tok_comment_char, 0}, +-#line 88 "locfile-kw.gperf" ++#line 89 "locfile-kw.gperf" + {"positive_sign", tok_positive_sign, 0}, + {""}, {""}, {""}, {""}, +-#line 61 "locfile-kw.gperf" ++#line 62 "locfile-kw.gperf" + {"symbol-equivalence", tok_symbol_equivalence, 0}, + {""}, +-#line 102 "locfile-kw.gperf" ++#line 103 "locfile-kw.gperf" + {"int_p_sign_posn", tok_int_p_sign_posn, 0}, +-#line 175 "locfile-kw.gperf" ++#line 176 "locfile-kw.gperf" + {"country_car", tok_country_car, 0}, + {""}, {""}, +-#line 104 "locfile-kw.gperf" ++#line 105 "locfile-kw.gperf" + {"duo_int_curr_symbol", tok_duo_int_curr_symbol, 0}, + {""}, {""}, +-#line 135 "locfile-kw.gperf" ++#line 136 "locfile-kw.gperf" + {"d_t_fmt", tok_d_t_fmt, 0}, + {""}, {""}, +-#line 116 "locfile-kw.gperf" ++#line 117 "locfile-kw.gperf" + {"duo_p_sign_posn", tok_duo_p_sign_posn, 0}, +-#line 187 "locfile-kw.gperf" ++#line 188 "locfile-kw.gperf" + {"measurement", tok_measurement, 0}, +-#line 176 "locfile-kw.gperf" ++#line 177 "locfile-kw.gperf" + {"country_isbn", tok_country_isbn, 0}, + #line 37 "locfile-kw.gperf" + {"outdigit", tok_outdigit, 0}, + {""}, {""}, +-#line 143 "locfile-kw.gperf" ++#line 144 "locfile-kw.gperf" + {"era_d_t_fmt", tok_era_d_t_fmt, 0}, + {""}, {""}, {""}, + #line 34 "locfile-kw.gperf" + {"lower", tok_lower, 0}, +-#line 183 "locfile-kw.gperf" ++#line 184 "locfile-kw.gperf" + {"tel_dom_fmt", tok_tel_dom_fmt, 0}, +-#line 171 "locfile-kw.gperf" ++#line 172 "locfile-kw.gperf" + {"country_post", tok_country_post, 0}, +-#line 148 "locfile-kw.gperf" ++#line 149 "locfile-kw.gperf" + {"cal_direction", tok_cal_direction, 0}, +- {""}, +-#line 139 "locfile-kw.gperf" ++#line 57 "locfile-kw.gperf" ++ {"codepoint_collation", tok_codepoint_collation, 0}, ++#line 140 "locfile-kw.gperf" + {"t_fmt_ampm", tok_t_fmt_ampm, 0}, +-#line 91 "locfile-kw.gperf" ++#line 92 "locfile-kw.gperf" + {"frac_digits", tok_frac_digits, 0}, + {""}, {""}, +-#line 177 "locfile-kw.gperf" ++#line 178 "locfile-kw.gperf" + {"lang_name", tok_lang_name, 0}, +-#line 90 "locfile-kw.gperf" ++#line 91 "locfile-kw.gperf" + {"int_frac_digits", tok_int_frac_digits, 0}, + {""}, +-#line 121 "locfile-kw.gperf" ++#line 122 "locfile-kw.gperf" + {"uno_valid_to", tok_uno_valid_to, 0}, +-#line 126 "locfile-kw.gperf" ++#line 127 "locfile-kw.gperf" + {"decimal_point", tok_decimal_point, 0}, + {""}, +-#line 133 "locfile-kw.gperf" ++#line 134 "locfile-kw.gperf" + {"abmon", tok_abmon, 0}, + {""}, {""}, {""}, {""}, +-#line 107 "locfile-kw.gperf" ++#line 108 "locfile-kw.gperf" + {"duo_frac_digits", tok_duo_frac_digits, 0}, +-#line 182 "locfile-kw.gperf" ++#line 183 "locfile-kw.gperf" + {"tel_int_fmt", tok_tel_int_fmt, 0}, +-#line 123 "locfile-kw.gperf" ++#line 124 "locfile-kw.gperf" + {"duo_valid_to", tok_duo_valid_to, 0}, +-#line 146 "locfile-kw.gperf" ++#line 147 "locfile-kw.gperf" + {"first_weekday", tok_first_weekday, 0}, + {""}, +-#line 130 "locfile-kw.gperf" ++#line 131 "locfile-kw.gperf" + {"abday", tok_abday, 0}, + {""}, +-#line 200 "locfile-kw.gperf" ++#line 201 "locfile-kw.gperf" + {"abbreviation", tok_abbreviation, 0}, +-#line 147 "locfile-kw.gperf" ++#line 148 "locfile-kw.gperf" + {"first_workday", tok_first_workday, 0}, + {""}, {""}, +-#line 97 "locfile-kw.gperf" ++#line 98 "locfile-kw.gperf" + {"n_sign_posn", tok_n_sign_posn, 0}, + {""}, {""}, {""}, +-#line 145 "locfile-kw.gperf" ++#line 146 "locfile-kw.gperf" + {"alt_digits", tok_alt_digits, 0}, + {""}, {""}, +-#line 128 "locfile-kw.gperf" ++#line 129 "locfile-kw.gperf" + {"grouping", tok_grouping, 0}, + {""}, + #line 45 "locfile-kw.gperf" + {"blank", tok_blank, 0}, + {""}, {""}, +-#line 196 "locfile-kw.gperf" ++#line 197 "locfile-kw.gperf" + {"language", tok_language, 0}, +-#line 120 "locfile-kw.gperf" ++#line 121 "locfile-kw.gperf" + {"uno_valid_from", tok_uno_valid_from, 0}, + {""}, +-#line 199 "locfile-kw.gperf" ++#line 200 "locfile-kw.gperf" + {"application", tok_application, 0}, + {""}, +-#line 80 "locfile-kw.gperf" ++#line 81 "locfile-kw.gperf" + {"elifndef", tok_elifndef, 0}, + {""}, {""}, {""}, {""}, {""}, +-#line 122 "locfile-kw.gperf" ++#line 123 "locfile-kw.gperf" + {"duo_valid_from", tok_duo_valid_from, 0}, +-#line 57 "locfile-kw.gperf" ++#line 58 "locfile-kw.gperf" + {"coll_weight_max", tok_coll_weight_max, 0}, + {""}, +-#line 79 "locfile-kw.gperf" ++#line 80 "locfile-kw.gperf" + {"elifdef", tok_elifdef, 0}, +-#line 67 "locfile-kw.gperf" ++#line 68 "locfile-kw.gperf" + {"backward", tok_backward, 0}, +-#line 106 "locfile-kw.gperf" ++#line 107 "locfile-kw.gperf" + {"duo_int_frac_digits", tok_duo_int_frac_digits, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, +-#line 96 "locfile-kw.gperf" ++#line 97 "locfile-kw.gperf" + {"p_sign_posn", tok_p_sign_posn, 0}, + {""}, +-#line 203 "locfile-kw.gperf" ++#line 204 "locfile-kw.gperf" + {"category", tok_category, 0}, + {""}, {""}, {""}, {""}, +-#line 134 "locfile-kw.gperf" ++#line 135 "locfile-kw.gperf" + {"mon", tok_mon, 0}, + {""}, +-#line 124 "locfile-kw.gperf" ++#line 125 "locfile-kw.gperf" + {"conversion_rate", tok_conversion_rate, 0}, + {""}, {""}, {""}, {""}, {""}, +-#line 63 "locfile-kw.gperf" ++#line 64 "locfile-kw.gperf" + {"order_start", tok_order_start, 0}, + {""}, {""}, {""}, {""}, {""}, +-#line 178 "locfile-kw.gperf" ++#line 179 "locfile-kw.gperf" + {"lang_ab", tok_lang_ab, 0}, +-#line 180 "locfile-kw.gperf" ++#line 181 "locfile-kw.gperf" + {"lang_lib", tok_lang_lib, 0}, + {""}, {""}, {""}, +-#line 192 "locfile-kw.gperf" ++#line 193 "locfile-kw.gperf" + {"contact", tok_contact, 0}, + {""}, {""}, {""}, +-#line 173 "locfile-kw.gperf" ++#line 174 "locfile-kw.gperf" + {"country_ab3", tok_country_ab3, 0}, + {""}, {""}, {""}, +-#line 193 "locfile-kw.gperf" ++#line 194 "locfile-kw.gperf" + {"email", tok_email, 0}, +-#line 172 "locfile-kw.gperf" ++#line 173 "locfile-kw.gperf" + {"country_ab2", tok_country_ab2, 0}, + {""}, {""}, {""}, + #line 55 "locfile-kw.gperf" + {"default_missing", tok_default_missing, 0}, + {""}, {""}, +-#line 195 "locfile-kw.gperf" ++#line 196 "locfile-kw.gperf" + {"fax", tok_fax, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 174 "locfile-kw.gperf" ++#line 175 "locfile-kw.gperf" + {"country_num", tok_country_num, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, + #line 51 "locfile-kw.gperf" + {"map", tok_map, 0}, +-#line 65 "locfile-kw.gperf" ++#line 66 "locfile-kw.gperf" + {"from", tok_from, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 86 "locfile-kw.gperf" ++#line 87 "locfile-kw.gperf" + {"mon_thousands_sep", tok_mon_thousands_sep, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, +-#line 81 "locfile-kw.gperf" ++#line 82 "locfile-kw.gperf" + {"endif", tok_endif, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 151 "locfile-kw.gperf" ++#line 152 "locfile-kw.gperf" + {"alt_mon", tok_alt_mon, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 76 "locfile-kw.gperf" ++#line 77 "locfile-kw.gperf" + {"undef", tok_undef, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 59 "locfile-kw.gperf" ++#line 60 "locfile-kw.gperf" + {"collating-element", tok_collating_element, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 152 "locfile-kw.gperf" ++#line 153 "locfile-kw.gperf" + {"ab_alt_mon", tok_ab_alt_mon, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 66 "locfile-kw.gperf" ++#line 67 "locfile-kw.gperf" + {"forward", tok_forward, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, +-#line 85 "locfile-kw.gperf" ++#line 86 "locfile-kw.gperf" + {"mon_decimal_point", tok_mon_decimal_point, 0}, + {""}, {""}, +-#line 169 "locfile-kw.gperf" ++#line 170 "locfile-kw.gperf" + {"postal_fmt", tok_postal_fmt, 0}, + {""}, {""}, {""}, {""}, {""}, +-#line 60 "locfile-kw.gperf" ++#line 61 "locfile-kw.gperf" + {"collating-symbol", tok_collating_symbol, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +@@ -583,15 +584,15 @@ locfile_hash (register const char *str, register size_t len) + #line 38 "locfile-kw.gperf" + {"alnum", tok_alnum, 0}, + {""}, +-#line 87 "locfile-kw.gperf" ++#line 88 "locfile-kw.gperf" + {"mon_grouping", tok_mon_grouping, 0}, + {""}, +-#line 179 "locfile-kw.gperf" ++#line 180 "locfile-kw.gperf" + {"lang_term", tok_lang_term, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 77 "locfile-kw.gperf" ++#line 78 "locfile-kw.gperf" + {"ifdef", tok_ifdef, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +@@ -599,7 +600,7 @@ locfile_hash (register const char *str, register size_t len) + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +-#line 138 "locfile-kw.gperf" ++#line 139 "locfile-kw.gperf" + {"am_pm", tok_am_pm, 0} + }; + +diff --git a/locale/programs/locfile-token.h b/locale/programs/locfile-token.h +index 414ad3076223e971..f57d594e8d25c06f 100644 +--- a/locale/programs/locfile-token.h ++++ b/locale/programs/locfile-token.h +@@ -91,6 +91,7 @@ enum token_t + tok_translit_ignore, + tok_default_missing, + tok_lc_collate, ++ tok_codepoint_collation, + tok_coll_weight_max, + tok_section_symbol, + tok_collating_element, diff --git a/SOURCES/glibc-c-utf8-locale-2.patch b/SOURCES/glibc-c-utf8-locale-2.patch new file mode 100644 index 0000000..7064b8e --- /dev/null +++ b/SOURCES/glibc-c-utf8-locale-2.patch @@ -0,0 +1,1437 @@ +commit 466f2be6c08070e9113ae2fdc7acd5d8828cba50 +Author: Carlos O'Donell +Date: Wed Sep 1 15:19:19 2021 -0400 + + Add generic C.UTF-8 locale (Bug 17318) + + We add a new C.UTF-8 locale. This locale is not builtin to glibc, but + is provided as a distinct locale. The locale provides full support for + UTF-8 and this includes full code point sorting via STRCMP-based + collation (strcmp or wcscmp). + + The collation uses a new keyword 'codepoint_collation' which drops all + collation rules and generates an empty zero rules collation to enable + STRCMP usage in collation. This ensures that we get full code point + sorting for C.UTF-8 with a minimal 1406 bytes of overhead (LC_COLLATE + structure information and ASCII collating tables). + + The new locale is added to SUPPORTED. Minimal test data for specific + code points (minus those not supported by collate-test) is provided in + C.UTF-8.in, and this verifies code point sorting is working reasonably + across the range. The locale was tested manually with the full set of + code points without failure. + + The locale is harmonized with locales already shipping in various + downstream distributions. A new tst-iconv9 test is added which verifies + the C.UTF-8 locale is generally usable. + + Testing for fnmatch, regexec, and recomp is provided by extending + bug-regex1, bugregex19, bug-regex4, bug-regex6, transbug, tst-fnmatch, + tst-regcomp-truncated, and tst-regex to use C.UTF-8. + + Tested on x86_64 or i686 without regression. + + Reviewed-by: Florian Weimer + +diff --git a/iconv/Makefile b/iconv/Makefile +index 07d77c9ecaafba1f..9993f2d3f3cd7498 100644 +--- a/iconv/Makefile ++++ b/iconv/Makefile +@@ -43,8 +43,19 @@ CFLAGS-charmap.c += -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \ + CFLAGS-linereader.c += -DNO_TRANSLITERATION + CFLAGS-simple-hash.c += -I../locale + +-tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6 \ +- tst-iconv7 tst-iconv8 tst-iconv-mt tst-iconv-opt ++tests = \ ++ tst-iconv1 \ ++ tst-iconv2 \ ++ tst-iconv3 \ ++ tst-iconv4 \ ++ tst-iconv5 \ ++ tst-iconv6 \ ++ tst-iconv7 \ ++ tst-iconv8 \ ++ tst-iconv9 \ ++ tst-iconv-mt \ ++ tst-iconv-opt \ ++ # tests + + others = iconv_prog iconvconfig + install-others-programs = $(inst_bindir)/iconv +@@ -83,10 +94,15 @@ endif + include ../Rules + + ifeq ($(run-built-tests),yes) +-LOCALES := en_US.UTF-8 ++# We have to generate locales (list sorted alphabetically) ++LOCALES := \ ++ C.UTF-8 \ ++ en_US.UTF-8 \ ++ # LOCALES + include ../gen-locales.mk + + $(objpfx)tst-iconv-opt.out: $(gen-locales) ++$(objpfx)tst-iconv9.out: $(gen-locales) + endif + + $(inst_bindir)/iconv: $(objpfx)iconv_prog $(+force) +diff --git a/iconv/tst-iconv9.c b/iconv/tst-iconv9.c +new file mode 100644 +index 0000000000000000..c46b1833d87b8e55 +--- /dev/null ++++ b/iconv/tst-iconv9.c +@@ -0,0 +1,87 @@ ++/* Verify that using C.UTF-8 works. ++ ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* This test does two things: ++ (1) Verify that we have likely included translit_combining in C.UTF-8. ++ (2) Verify default_missing is '?' as expected. */ ++ ++/* ISO-8859-1 encoding of "für". */ ++char iso88591_in[] = { 0x66, 0xfc, 0x72, 0x0 }; ++/* ASCII transliteration is "fur" with C.UTF-8 translit_combining. */ ++char ascii_exp[] = { 0x66, 0x75, 0x72, 0x0 }; ++ ++/* First 3-byte UTF-8 code point. */ ++char utf8_in[] = { 0xe0, 0xa0, 0x80, 0x0 }; ++/* There is no ASCII transliteration for SAMARITAN LETTER ALAF ++ so we get default_missing used which is '?'. */ ++char default_missing_exp[] = { 0x3f, 0x0 }; ++ ++static int ++do_test (void) ++{ ++ char ascii_out[5]; ++ iconv_t cd; ++ char *inbuf; ++ char *outbuf; ++ size_t inbytes; ++ size_t outbytes; ++ size_t n; ++ ++ /* The C.UTF-8 locale should include translit_combining, which provides ++ the transliteration for "LATIN SMALL LETTER U WITH DIAERESIS" which ++ is not provided by locale/C-translit.h.in. */ ++ xsetlocale (LC_ALL, "C.UTF-8"); ++ ++ /* From ISO-8859-1 to ASCII. */ ++ cd = iconv_open ("ASCII//TRANSLIT,IGNORE", "ISO-8859-1"); ++ TEST_VERIFY (cd != (iconv_t) -1); ++ inbuf = iso88591_in; ++ inbytes = 3; ++ outbuf = ascii_out; ++ outbytes = 3; ++ n = iconv (cd, &inbuf, &inbytes, &outbuf, &outbytes); ++ TEST_VERIFY (n != -1); ++ *outbuf = '\0'; ++ TEST_COMPARE_BLOB (ascii_out, 3, ascii_exp, 3); ++ TEST_VERIFY (iconv_close (cd) == 0); ++ ++ /* From UTF-8 to ASCII. */ ++ cd = iconv_open ("ASCII//TRANSLIT,IGNORE", "UTF-8"); ++ TEST_VERIFY (cd != (iconv_t) -1); ++ inbuf = utf8_in; ++ inbytes = 3; ++ outbuf = ascii_out; ++ outbytes = 3; ++ n = iconv (cd, &inbuf, &inbytes, &outbuf, &outbytes); ++ TEST_VERIFY (n != -1); ++ *outbuf = '\0'; ++ TEST_COMPARE_BLOB (ascii_out, 1, default_missing_exp, 1); ++ TEST_VERIFY (iconv_close (cd) == 0); ++ ++ return 0; ++} ++ ++#include +diff --git a/localedata/C.UTF-8.in b/localedata/C.UTF-8.in +new file mode 100644 +index 0000000000000000..c31dcc2aa045ee61 +--- /dev/null ++++ b/localedata/C.UTF-8.in +@@ -0,0 +1,157 @@ ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++! ; ++" ; ++# ; ++$ ; ++% ; ++& ; ++' ; ++) ; ++* ; +++ ; ++, ; ++- ; ++. ; ++/ ; ++0 ; ++1 ; ++2 ; ++3 ; ++4 ; ++5 ; ++6 ; ++7 ; ++8 ; ++9 ; ++< ; ++= ; ++> ; ++? ; ++@ ; ++A ; ++B ; ++C ; ++D ; ++E ; ++F ; ++G ; ++H ; ++I ; ++J ; ++K ; ++L ; ++M ; ++N ; ++O ; ++P ; ++Q ; ++R ; ++S ; ++T ; ++U ; ++V ; ++W ; ++X ; ++Y ; ++Z ; ++[ ; ++\ ; ++] ; ++^ ; ++_ ; ++` ; ++a ; ++b ; ++c ; ++d ; ++e ; ++f ; ++g ; ++h ; ++i ; ++j ; ++k ; ++l ; ++m ; ++n ; ++o ; ++p ; ++q ; ++r ; ++s ; ++t ; ++u ; ++v ; ++w ; ++x ; ++y ; ++z ; ++{ ; ++| ; ++} ; ++~ ; ++ ; ++€ ; ++ÿ ; ++Ä€ ; ++à¿¿ ; ++က ; ++� ; ++ï¿¿ ; ++ð€€ ; ++🿿 ; ++ð €€ ; ++𯿿 ; ++ð°€€ ; ++ð¿¿¾ ; ++ñ€€€ ; ++ñ¿¿ ; ++ñ€€ ; ++ñŸ¿¿ ; ++ñ €€ ; ++ñ¯¿¿ ; ++ñ°€€ ; ++ñ¿¿¿ ; ++ò€€€ ; ++ò¿¿ ; ++ò€€ ; ++òŸ¿¿ ; ++ò €€ ; ++ò¯¿¿ ; ++ò°€€ ; ++ò¿¿¿ ; ++ó€€ ; ++ó¿Œ ; ++ó€Ž ; ++óŸ¿¿ ; ++ó € ; ++󯿿 ; ++ó°€ ; ++ó¿¿¿ ; ++ô€€ ; ++ô¿¿ ; +diff --git a/localedata/Makefile b/localedata/Makefile +index 0341528b0407ae3b..c9dd5a954e8194cc 100644 +--- a/localedata/Makefile ++++ b/localedata/Makefile +@@ -47,6 +47,7 @@ test-input := \ + bg_BG.UTF-8 \ + br_FR.UTF-8 \ + bs_BA.UTF-8 \ ++ C.UTF-8 \ + ckb_IQ.UTF-8 \ + cmn_TW.UTF-8 \ + crh_UA.UTF-8 \ +@@ -206,6 +207,7 @@ LOCALES := \ + bg_BG.UTF-8 \ + br_FR.UTF-8 \ + bs_BA.UTF-8 \ ++ C.UTF-8 \ + ckb_IQ.UTF-8 \ + cmn_TW.UTF-8 \ + crh_UA.UTF-8 \ +diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED +index 34f7a7c3fe2b6526..546ce6cea16a8fdb 100644 +--- a/localedata/SUPPORTED ++++ b/localedata/SUPPORTED +@@ -79,6 +79,7 @@ brx_IN/UTF-8 \ + bs_BA.UTF-8/UTF-8 \ + bs_BA/ISO-8859-2 \ + byn_ER/UTF-8 \ ++C.UTF-8/UTF-8 \ + ca_AD.UTF-8/UTF-8 \ + ca_AD/ISO-8859-15 \ + ca_ES.UTF-8/UTF-8 \ +diff --git a/localedata/locales/C b/localedata/locales/C +new file mode 100644 +index 0000000000000000..ca801c79cf7e953e +--- /dev/null ++++ b/localedata/locales/C +@@ -0,0 +1,194 @@ ++escape_char / ++comment_char % ++% Locale for C locale in UTF-8 ++ ++LC_IDENTIFICATION ++title "C locale" ++source "" ++address "" ++contact "" ++email "bug-glibc-locales@gnu.org" ++tel "" ++fax "" ++language "" ++territory "" ++revision "2.0" ++date "2020-06-28" ++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 ++% Include only the i18n character type classes without any of the ++% transliteration that i18n uses by default. ++copy "i18n_ctype" ++ ++% Include the neutral transliterations. The builtin C and ++% POSIX locales have +1600 transliterations that are built into ++% the locales, and these are a superset of those. ++translit_start ++include "translit_neutral";"" ++% We must use '?' for default_missing because the transliteration ++% framework includes it directly into the output and so it must ++% be compatible with ASCII if that is the target character set. ++default_missing ++translit_end ++ ++% Include the transliterations that can convert combined characters. ++% These are generally expected by users. ++translit_start ++include "translit_combining";"" ++translit_end ++ ++END LC_CTYPE ++ ++LC_COLLATE ++% The keyword 'codepoint_collation' in any part of any LC_COLLATE ++% immediately discards all collation information and causes the ++% locale to use strcmp/wcscmp for collation comparison. This is ++% exactly what is needed for C (ASCII) or C.UTF-8. ++codepoint_collation ++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.). ++int_curr_symbol "" ++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 with the ++% exception that time is per ISO 8601 and 24-hour. ++% ++% Abbreviated weekday names (%a) ++abday "Sun";"Mon";"Tue";"Wed";"Thu";"Fri";"Sat" ++ ++% Full weekday names (%A) ++day "Sunday";"Monday";"Tuesday";"Wednesday";"Thursday";/ ++ "Friday";"Saturday" ++ ++% Abbreviated month names (%b) ++abmon "Jan";"Feb";"Mar";"Apr";"May";"Jun";"Jul";"Aug";"Sep";/ ++ "Oct";"Nov";"Dec" ++ ++% Full month names (%B) ++mon "January";"February";"March";"April";"May";"June";"July";/ ++ "August";"September";"October";"November";"December" ++ ++% 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 2 ++ ++% Appropriate date and time representation (%c) ++d_t_fmt "%a %b %e %H:%M:%S %Y" ++ ++% Appropriate date representation (%x) ++d_fmt "%m/%d/%y" ++ ++% Appropriate time representation (%X) ++t_fmt "%H:%M:%S" ++ ++% Appropriate AM/PM time representation (%r) ++t_fmt_ampm "%I:%M:%S %p" ++ ++% Equivalent of AM/PM (%p) ++am_pm "AM";"PM" ++ ++% Appropriate date representation (date(1)) ++date_fmt "%a %b %e %H:%M:%S %Z %Y" ++END LC_TIME ++ ++LC_MESSAGES ++% This is the POSIX Locale definition for ++% the LC_NUMERIC category. ++% ++yesexpr "^[yY]" ++noexpr "^[nN]" ++yesstr "Yes" ++nostr "No" ++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. ++% (also used in the built in C/POSIX locale in glibc/locale/C-name.c) ++name_fmt "%p%t%g%t%m%t%f" ++END LC_NAME ++ ++LC_ADDRESS ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_ADDRESS category. ++% (also used in the built in C/POSIX locale in glibc/locale/C-address.c) ++postal_fmt "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" ++END LC_ADDRESS ++ ++LC_TELEPHONE ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_TELEPHONE category. ++% "+%c %a %l" ++tel_int_fmt "+%c %a %l" ++% (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 +diff --git a/posix/Makefile b/posix/Makefile +index 059efb3cd2706cbe..a5229777eeb0e067 100644 +--- a/posix/Makefile ++++ b/posix/Makefile +@@ -190,9 +190,19 @@ $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test + $(evaluate-test) + endif + +-LOCALES := cs_CZ.UTF-8 da_DK.ISO-8859-1 de_DE.ISO-8859-1 de_DE.UTF-8 \ +- en_US.UTF-8 es_US.ISO-8859-1 es_US.UTF-8 ja_JP.EUC-JP tr_TR.UTF-8 \ +- cs_CZ.ISO-8859-2 ++LOCALES := \ ++ cs_CZ.ISO-8859-2 \ ++ cs_CZ.UTF-8 \ ++ C.UTF-8 \ ++ da_DK.ISO-8859-1 \ ++ de_DE.ISO-8859-1 \ ++ de_DE.UTF-8 \ ++ en_US.UTF-8 \ ++ es_US.ISO-8859-1 \ ++ es_US.UTF-8 \ ++ ja_JP.EUC-JP \ ++ tr_TR.UTF-8 \ ++ # LOCALES + include ../gen-locales.mk + + $(objpfx)bug-regex1.out: $(gen-locales) +diff --git a/posix/bug-regex1.c b/posix/bug-regex1.c +index 38eb543951862492..7e9f4ec430a95631 100644 +--- a/posix/bug-regex1.c ++++ b/posix/bug-regex1.c +@@ -41,6 +41,26 @@ main (void) + puts (" -> OK"); + } + ++ puts ("in C.UTF-8 locale"); ++ setlocale (LC_ALL, "C.UTF-8"); ++ s = re_compile_pattern ("[an\371]*n", 7, ®ex); ++ if (s != NULL) ++ { ++ puts ("re_compile_pattern return non-NULL value"); ++ result = 1; ++ } ++ else ++ { ++ match = re_match (®ex, "an", 2, 0, ®s); ++ if (match != 2) ++ { ++ printf ("re_match returned %d, expected 2\n", match); ++ result = 1; ++ } ++ else ++ puts (" -> OK"); ++ } ++ + puts ("in de_DE.ISO-8859-1 locale"); + setlocale (LC_ALL, "de_DE.ISO-8859-1"); + s = re_compile_pattern ("[anù]*n", 7, ®ex); +diff --git a/posix/bug-regex19.c b/posix/bug-regex19.c +index b3fee0a7302c3263..e00ff60a14f994bf 100644 +--- a/posix/bug-regex19.c ++++ b/posix/bug-regex19.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #define BRE RE_SYNTAX_POSIX_BASIC + #define ERE RE_SYNTAX_POSIX_EXTENDED +@@ -407,8 +408,8 @@ do_mb_tests (const struct test_s *test) + return 0; + } + +-int +-main (void) ++static int ++do_test (void) + { + size_t i; + int ret = 0; +@@ -417,20 +418,17 @@ main (void) + + for (i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i) + { +- if (setlocale (LC_ALL, "de_DE.ISO-8859-1") == NULL) +- { +- puts ("setlocale de_DE.ISO-8859-1 failed"); +- ret = 1; +- } ++ xsetlocale (LC_ALL, "de_DE.ISO-8859-1"); + ret |= do_one_test (&tests[i], ""); +- if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) +- { +- puts ("setlocale de_DE.UTF-8 failed"); +- ret = 1; +- } ++ xsetlocale (LC_ALL, "de_DE.UTF-8"); ++ ret |= do_one_test (&tests[i], "UTF-8 "); ++ ret |= do_mb_tests (&tests[i]); ++ xsetlocale (LC_ALL, "C.UTF-8"); + ret |= do_one_test (&tests[i], "UTF-8 "); + ret |= do_mb_tests (&tests[i]); + } + + return ret; + } ++ ++#include +diff --git a/posix/bug-regex4.c b/posix/bug-regex4.c +index 8d5ae11567889301..6475833c525176b2 100644 +--- a/posix/bug-regex4.c ++++ b/posix/bug-regex4.c +@@ -32,8 +32,33 @@ main (void) + + memset (®ex, '\0', sizeof (regex)); + ++ printf ("INFO: Checking C.\n"); + setlocale (LC_ALL, "C"); + ++ s = re_compile_pattern ("ab[cde]", 7, ®ex); ++ if (s != NULL) ++ { ++ puts ("re_compile_pattern returned non-NULL value"); ++ result = 1; ++ } ++ else ++ { ++ match[0] = re_search_2 (®ex, "xyabez", 6, "", 0, 1, 5, NULL, 6); ++ match[1] = re_search_2 (®ex, NULL, 0, "abc", 3, 0, 3, NULL, 3); ++ match[2] = re_search_2 (®ex, "xya", 3, "bd", 2, 2, 3, NULL, 5); ++ if (match[0] != 2 || match[1] != 0 || match[2] != 2) ++ { ++ printf ("re_search_2 returned %d,%d,%d, expected 2,0,2\n", ++ match[0], match[1], match[2]); ++ result = 1; ++ } ++ else ++ puts (" -> OK"); ++ } ++ ++ printf ("INFO: Checking C.UTF-8.\n"); ++ setlocale (LC_ALL, "C.UTF-8"); ++ + s = re_compile_pattern ("ab[cde]", 7, ®ex); + if (s != NULL) + { +diff --git a/posix/bug-regex6.c b/posix/bug-regex6.c +index 2bdf2126a49ee99b..0929b69b83c91e5e 100644 +--- a/posix/bug-regex6.c ++++ b/posix/bug-regex6.c +@@ -30,7 +30,7 @@ main (int argc, char *argv[]) + regex_t re; + regmatch_t mat[10]; + int i, j, ret = 0; +- const char *locales[] = { "C", "de_DE.UTF-8" }; ++ const char *locales[] = { "C", "C.UTF-8", "de_DE.UTF-8" }; + const char *string = "http://www.regex.com/pattern/matching.html#intro"; + regmatch_t expect[10] = { + { 0, 48 }, { 0, 5 }, { 0, 4 }, { 5, 20 }, { 7, 20 }, { 20, 42 }, +diff --git a/posix/transbug.c b/posix/transbug.c +index d0983b4d44d04fd2..b240177cf72326ff 100644 +--- a/posix/transbug.c ++++ b/posix/transbug.c +@@ -116,16 +116,32 @@ do_test (void) + static const char lower[] = "[[:lower:]]+"; + static const char upper[] = "[[:upper:]]+"; + struct re_registers regs[4]; ++ int result = 0; + ++#define CHECK(exp) \ ++ if (exp) { puts (#exp); result = 1; } ++ ++ printf ("INFO: Checking C.\n"); + setlocale (LC_ALL, "C"); + + (void) re_set_syntax (RE_SYNTAX_GNU_AWK); + +- int result; +-#define CHECK(exp) \ +- if (exp) { puts (#exp); result = 1; } ++ result |= run_test (lower, regs); ++ result |= run_test (upper, ®s[2]); ++ if (! result) ++ { ++ CHECK (regs[0].start[0] != regs[2].start[0]); ++ CHECK (regs[0].end[0] != regs[2].end[0]); ++ CHECK (regs[1].start[0] != regs[3].start[0]); ++ CHECK (regs[1].end[0] != regs[3].end[0]); ++ } ++ ++ printf ("INFO: Checking C.UTF-8.\n"); ++ setlocale (LC_ALL, "C.UTF-8"); ++ ++ (void) re_set_syntax (RE_SYNTAX_GNU_AWK); + +- result = run_test (lower, regs); ++ result |= run_test (lower, regs); + result |= run_test (upper, ®s[2]); + if (! result) + { +diff --git a/posix/tst-fnmatch.input b/posix/tst-fnmatch.input +index 67aac5aadafd8aeb..6ff5318032e0afb2 100644 +--- a/posix/tst-fnmatch.input ++++ b/posix/tst-fnmatch.input +@@ -472,6 +472,397 @@ C "\\" "[Z-\\]]" 0 + C "]" "[Z-\\]]" 0 + C "-" "[Z-\\]]" NOMATCH + ++# B.6 004(C) ++C.UTF-8 "!#%+,-./01234567889" "!#%+,-./01234567889" 0 ++C.UTF-8 ":;=@ABCDEFGHIJKLMNO" ":;=@ABCDEFGHIJKLMNO" 0 ++C.UTF-8 "PQRSTUVWXYZ]abcdefg" "PQRSTUVWXYZ]abcdefg" 0 ++C.UTF-8 "hijklmnopqrstuvwxyz" "hijklmnopqrstuvwxyz" 0 ++C.UTF-8 "^_{}~" "^_{}~" 0 ++ ++# B.6 005(C) ++C.UTF-8 "\"$&'()" "\\\"\\$\\&\\'\\(\\)" 0 ++C.UTF-8 "*?[\\`|" "\\*\\?\\[\\\\\\`\\|" 0 ++C.UTF-8 "<>" "\\<\\>" 0 ++ ++# B.6 006(C) ++C.UTF-8 "?*[" "[?*[][?*[][?*[]" 0 ++C.UTF-8 "a/b" "?/b" 0 ++ ++# B.6 007(C) ++C.UTF-8 "a/b" "a?b" 0 ++C.UTF-8 "a/b" "a/?" 0 ++C.UTF-8 "aa/b" "?/b" NOMATCH ++C.UTF-8 "aa/b" "a?b" NOMATCH ++C.UTF-8 "a/bb" "a/?" NOMATCH ++ ++# B.6 009(C) ++C.UTF-8 "abc" "[abc]" NOMATCH ++C.UTF-8 "x" "[abc]" NOMATCH ++C.UTF-8 "a" "[abc]" 0 ++C.UTF-8 "[" "[[abc]" 0 ++C.UTF-8 "a" "[][abc]" 0 ++C.UTF-8 "a]" "[]a]]" 0 ++ ++# B.6 010(C) ++C.UTF-8 "xyz" "[!abc]" NOMATCH ++C.UTF-8 "x" "[!abc]" 0 ++C.UTF-8 "a" "[!abc]" NOMATCH ++ ++# B.6 011(C) ++C.UTF-8 "]" "[][abc]" 0 ++C.UTF-8 "abc]" "[][abc]" NOMATCH ++C.UTF-8 "[]abc" "[][]abc" NOMATCH ++C.UTF-8 "]" "[!]]" NOMATCH ++C.UTF-8 "aa]" "[!]a]" NOMATCH ++C.UTF-8 "]" "[!a]" 0 ++C.UTF-8 "]]" "[!a]]" 0 ++ ++# B.6 012(C) ++C.UTF-8 "a" "[[.a.]]" 0 ++C.UTF-8 "-" "[[.-.]]" 0 ++C.UTF-8 "-" "[[.-.][.].]]" 0 ++C.UTF-8 "-" "[[.].][.-.]]" 0 ++C.UTF-8 "-" "[[.-.][=u=]]" 0 ++C.UTF-8 "-" "[[.-.][:alpha:]]" 0 ++C.UTF-8 "a" "[![.a.]]" NOMATCH ++ ++# B.6 013(C) ++C.UTF-8 "a" "[[.b.]]" NOMATCH ++C.UTF-8 "a" "[[.b.][.c.]]" NOMATCH ++C.UTF-8 "a" "[[.b.][=b=]]" NOMATCH ++ ++ ++# B.6 015(C) ++C.UTF-8 "a" "[[=a=]]" 0 ++C.UTF-8 "b" "[[=a=]b]" 0 ++C.UTF-8 "b" "[[=a=][=b=]]" 0 ++C.UTF-8 "a" "[[=a=][=b=]]" 0 ++C.UTF-8 "a" "[[=a=][.b.]]" 0 ++C.UTF-8 "a" "[[=a=][:digit:]]" 0 ++ ++# B.6 016(C) ++C.UTF-8 "=" "[[=a=]b]" NOMATCH ++C.UTF-8 "]" "[[=a=]b]" NOMATCH ++C.UTF-8 "a" "[[=b=][=c=]]" NOMATCH ++C.UTF-8 "a" "[[=b=][.].]]" NOMATCH ++C.UTF-8 "a" "[[=b=][:digit:]]" NOMATCH ++ ++# B.6 017(C) ++C.UTF-8 "a" "[[:alnum:]]" 0 ++C.UTF-8 "a" "[![:alnum:]]" NOMATCH ++C.UTF-8 "-" "[[:alnum:]]" NOMATCH ++C.UTF-8 "a]a" "[[:alnum:]]a" NOMATCH ++C.UTF-8 "-" "[[:alnum:]-]" 0 ++C.UTF-8 "aa" "[[:alnum:]]a" 0 ++C.UTF-8 "-" "[![:alnum:]]" 0 ++C.UTF-8 "]" "[!][:alnum:]]" NOMATCH ++C.UTF-8 "[" "[![:alnum:][]" NOMATCH ++C.UTF-8 "a" "[[:alnum:]]" 0 ++C.UTF-8 "b" "[[:alnum:]]" 0 ++C.UTF-8 "c" "[[:alnum:]]" 0 ++C.UTF-8 "d" "[[:alnum:]]" 0 ++C.UTF-8 "e" "[[:alnum:]]" 0 ++C.UTF-8 "f" "[[:alnum:]]" 0 ++C.UTF-8 "g" "[[:alnum:]]" 0 ++C.UTF-8 "h" "[[:alnum:]]" 0 ++C.UTF-8 "i" "[[:alnum:]]" 0 ++C.UTF-8 "j" "[[:alnum:]]" 0 ++C.UTF-8 "k" "[[:alnum:]]" 0 ++C.UTF-8 "l" "[[:alnum:]]" 0 ++C.UTF-8 "m" "[[:alnum:]]" 0 ++C.UTF-8 "n" "[[:alnum:]]" 0 ++C.UTF-8 "o" "[[:alnum:]]" 0 ++C.UTF-8 "p" "[[:alnum:]]" 0 ++C.UTF-8 "q" "[[:alnum:]]" 0 ++C.UTF-8 "r" "[[:alnum:]]" 0 ++C.UTF-8 "s" "[[:alnum:]]" 0 ++C.UTF-8 "t" "[[:alnum:]]" 0 ++C.UTF-8 "u" "[[:alnum:]]" 0 ++C.UTF-8 "v" "[[:alnum:]]" 0 ++C.UTF-8 "w" "[[:alnum:]]" 0 ++C.UTF-8 "x" "[[:alnum:]]" 0 ++C.UTF-8 "y" "[[:alnum:]]" 0 ++C.UTF-8 "z" "[[:alnum:]]" 0 ++C.UTF-8 "A" "[[:alnum:]]" 0 ++C.UTF-8 "B" "[[:alnum:]]" 0 ++C.UTF-8 "C" "[[:alnum:]]" 0 ++C.UTF-8 "D" "[[:alnum:]]" 0 ++C.UTF-8 "E" "[[:alnum:]]" 0 ++C.UTF-8 "F" "[[:alnum:]]" 0 ++C.UTF-8 "G" "[[:alnum:]]" 0 ++C.UTF-8 "H" "[[:alnum:]]" 0 ++C.UTF-8 "I" "[[:alnum:]]" 0 ++C.UTF-8 "J" "[[:alnum:]]" 0 ++C.UTF-8 "K" "[[:alnum:]]" 0 ++C.UTF-8 "L" "[[:alnum:]]" 0 ++C.UTF-8 "M" "[[:alnum:]]" 0 ++C.UTF-8 "N" "[[:alnum:]]" 0 ++C.UTF-8 "O" "[[:alnum:]]" 0 ++C.UTF-8 "P" "[[:alnum:]]" 0 ++C.UTF-8 "Q" "[[:alnum:]]" 0 ++C.UTF-8 "R" "[[:alnum:]]" 0 ++C.UTF-8 "S" "[[:alnum:]]" 0 ++C.UTF-8 "T" "[[:alnum:]]" 0 ++C.UTF-8 "U" "[[:alnum:]]" 0 ++C.UTF-8 "V" "[[:alnum:]]" 0 ++C.UTF-8 "W" "[[:alnum:]]" 0 ++C.UTF-8 "X" "[[:alnum:]]" 0 ++C.UTF-8 "Y" "[[:alnum:]]" 0 ++C.UTF-8 "Z" "[[:alnum:]]" 0 ++C.UTF-8 "0" "[[:alnum:]]" 0 ++C.UTF-8 "1" "[[:alnum:]]" 0 ++C.UTF-8 "2" "[[:alnum:]]" 0 ++C.UTF-8 "3" "[[:alnum:]]" 0 ++C.UTF-8 "4" "[[:alnum:]]" 0 ++C.UTF-8 "5" "[[:alnum:]]" 0 ++C.UTF-8 "6" "[[:alnum:]]" 0 ++C.UTF-8 "7" "[[:alnum:]]" 0 ++C.UTF-8 "8" "[[:alnum:]]" 0 ++C.UTF-8 "9" "[[:alnum:]]" 0 ++C.UTF-8 "!" "[[:alnum:]]" NOMATCH ++C.UTF-8 "#" "[[:alnum:]]" NOMATCH ++C.UTF-8 "%" "[[:alnum:]]" NOMATCH ++C.UTF-8 "+" "[[:alnum:]]" NOMATCH ++C.UTF-8 "," "[[:alnum:]]" NOMATCH ++C.UTF-8 "-" "[[:alnum:]]" NOMATCH ++C.UTF-8 "." "[[:alnum:]]" NOMATCH ++C.UTF-8 "/" "[[:alnum:]]" NOMATCH ++C.UTF-8 ":" "[[:alnum:]]" NOMATCH ++C.UTF-8 ";" "[[:alnum:]]" NOMATCH ++C.UTF-8 "=" "[[:alnum:]]" NOMATCH ++C.UTF-8 "@" "[[:alnum:]]" NOMATCH ++C.UTF-8 "[" "[[:alnum:]]" NOMATCH ++C.UTF-8 "\\" "[[:alnum:]]" NOMATCH ++C.UTF-8 "]" "[[:alnum:]]" NOMATCH ++C.UTF-8 "^" "[[:alnum:]]" NOMATCH ++C.UTF-8 "_" "[[:alnum:]]" NOMATCH ++C.UTF-8 "{" "[[:alnum:]]" NOMATCH ++C.UTF-8 "}" "[[:alnum:]]" NOMATCH ++C.UTF-8 "~" "[[:alnum:]]" NOMATCH ++C.UTF-8 "\"" "[[:alnum:]]" NOMATCH ++C.UTF-8 "$" "[[:alnum:]]" NOMATCH ++C.UTF-8 "&" "[[:alnum:]]" NOMATCH ++C.UTF-8 "'" "[[:alnum:]]" NOMATCH ++C.UTF-8 "(" "[[:alnum:]]" NOMATCH ++C.UTF-8 ")" "[[:alnum:]]" NOMATCH ++C.UTF-8 "*" "[[:alnum:]]" NOMATCH ++C.UTF-8 "?" "[[:alnum:]]" NOMATCH ++C.UTF-8 "`" "[[:alnum:]]" NOMATCH ++C.UTF-8 "|" "[[:alnum:]]" NOMATCH ++C.UTF-8 "<" "[[:alnum:]]" NOMATCH ++C.UTF-8 ">" "[[:alnum:]]" NOMATCH ++C.UTF-8 "\t" "[[:cntrl:]]" 0 ++C.UTF-8 "t" "[[:cntrl:]]" NOMATCH ++C.UTF-8 "t" "[[:lower:]]" 0 ++C.UTF-8 "\t" "[[:lower:]]" NOMATCH ++C.UTF-8 "T" "[[:lower:]]" NOMATCH ++C.UTF-8 "\t" "[[:space:]]" 0 ++C.UTF-8 "t" "[[:space:]]" NOMATCH ++C.UTF-8 "t" "[[:alpha:]]" 0 ++C.UTF-8 "\t" "[[:alpha:]]" NOMATCH ++C.UTF-8 "0" "[[:digit:]]" 0 ++C.UTF-8 "\t" "[[:digit:]]" NOMATCH ++C.UTF-8 "t" "[[:digit:]]" NOMATCH ++C.UTF-8 "\t" "[[:print:]]" NOMATCH ++C.UTF-8 "t" "[[:print:]]" 0 ++C.UTF-8 "T" "[[:upper:]]" 0 ++C.UTF-8 "\t" "[[:upper:]]" NOMATCH ++C.UTF-8 "t" "[[:upper:]]" NOMATCH ++C.UTF-8 "\t" "[[:blank:]]" 0 ++C.UTF-8 "t" "[[:blank:]]" NOMATCH ++C.UTF-8 "\t" "[[:graph:]]" NOMATCH ++C.UTF-8 "t" "[[:graph:]]" 0 ++C.UTF-8 "." "[[:punct:]]" 0 ++C.UTF-8 "t" "[[:punct:]]" NOMATCH ++C.UTF-8 "\t" "[[:punct:]]" NOMATCH ++C.UTF-8 "0" "[[:xdigit:]]" 0 ++C.UTF-8 "\t" "[[:xdigit:]]" NOMATCH ++C.UTF-8 "a" "[[:xdigit:]]" 0 ++C.UTF-8 "A" "[[:xdigit:]]" 0 ++C.UTF-8 "t" "[[:xdigit:]]" NOMATCH ++C.UTF-8 "a" "[[alpha]]" NOMATCH ++C.UTF-8 "a" "[[alpha:]]" NOMATCH ++C.UTF-8 "a]" "[[alpha]]" 0 ++C.UTF-8 "a]" "[[alpha:]]" 0 ++C.UTF-8 "a" "[[:alpha:][.b.]]" 0 ++C.UTF-8 "a" "[[:alpha:][=b=]]" 0 ++C.UTF-8 "a" "[[:alpha:][:digit:]]" 0 ++C.UTF-8 "a" "[[:digit:][:alpha:]]" 0 ++ ++# B.6 018(C) ++C.UTF-8 "a" "[a-c]" 0 ++C.UTF-8 "b" "[a-c]" 0 ++C.UTF-8 "c" "[a-c]" 0 ++C.UTF-8 "a" "[b-c]" NOMATCH ++C.UTF-8 "d" "[b-c]" NOMATCH ++C.UTF-8 "B" "[a-c]" NOMATCH ++C.UTF-8 "b" "[A-C]" NOMATCH ++C.UTF-8 "" "[a-c]" NOMATCH ++C.UTF-8 "as" "[a-ca-z]" NOMATCH ++C.UTF-8 "a" "[[.a.]-c]" 0 ++C.UTF-8 "a" "[a-[.c.]]" 0 ++C.UTF-8 "a" "[[.a.]-[.c.]]" 0 ++C.UTF-8 "b" "[[.a.]-c]" 0 ++C.UTF-8 "b" "[a-[.c.]]" 0 ++C.UTF-8 "b" "[[.a.]-[.c.]]" 0 ++C.UTF-8 "c" "[[.a.]-c]" 0 ++C.UTF-8 "c" "[a-[.c.]]" 0 ++C.UTF-8 "c" "[[.a.]-[.c.]]" 0 ++C.UTF-8 "d" "[[.a.]-c]" NOMATCH ++C.UTF-8 "d" "[a-[.c.]]" NOMATCH ++C.UTF-8 "d" "[[.a.]-[.c.]]" NOMATCH ++ ++# B.6 019(C) ++C.UTF-8 "a" "[c-a]" NOMATCH ++C.UTF-8 "a" "[[.c.]-a]" NOMATCH ++C.UTF-8 "a" "[c-[.a.]]" NOMATCH ++C.UTF-8 "a" "[[.c.]-[.a.]]" NOMATCH ++C.UTF-8 "c" "[c-a]" NOMATCH ++C.UTF-8 "c" "[[.c.]-a]" NOMATCH ++C.UTF-8 "c" "[c-[.a.]]" NOMATCH ++C.UTF-8 "c" "[[.c.]-[.a.]]" NOMATCH ++ ++# B.6 020(C) ++C.UTF-8 "a" "[a-c0-9]" 0 ++C.UTF-8 "d" "[a-c0-9]" NOMATCH ++C.UTF-8 "B" "[a-c0-9]" NOMATCH ++ ++# B.6 021(C) ++C.UTF-8 "-" "[-a]" 0 ++C.UTF-8 "a" "[-b]" NOMATCH ++C.UTF-8 "-" "[!-a]" NOMATCH ++C.UTF-8 "a" "[!-b]" 0 ++C.UTF-8 "-" "[a-c-0-9]" 0 ++C.UTF-8 "b" "[a-c-0-9]" 0 ++C.UTF-8 "a:" "a[0-9-a]" NOMATCH ++C.UTF-8 "a:" "a[09-a]" 0 ++ ++# B.6 024(C) ++C.UTF-8 "" "*" 0 ++C.UTF-8 "asd/sdf" "*" 0 ++ ++# B.6 025(C) ++C.UTF-8 "as" "[a-c][a-z]" 0 ++C.UTF-8 "as" "??" 0 ++ ++# B.6 026(C) ++C.UTF-8 "asd/sdf" "as*df" 0 ++C.UTF-8 "asd/sdf" "as*" 0 ++C.UTF-8 "asd/sdf" "*df" 0 ++C.UTF-8 "asd/sdf" "as*dg" NOMATCH ++C.UTF-8 "asdf" "as*df" 0 ++C.UTF-8 "asdf" "as*df?" NOMATCH ++C.UTF-8 "asdf" "as*??" 0 ++C.UTF-8 "asdf" "a*???" 0 ++C.UTF-8 "asdf" "*????" 0 ++C.UTF-8 "asdf" "????*" 0 ++C.UTF-8 "asdf" "??*?" 0 ++ ++# B.6 027(C) ++C.UTF-8 "/" "/" 0 ++C.UTF-8 "/" "/*" 0 ++C.UTF-8 "/" "*/" 0 ++C.UTF-8 "/" "/?" NOMATCH ++C.UTF-8 "/" "?/" NOMATCH ++C.UTF-8 "/" "?" 0 ++C.UTF-8 "." "?" 0 ++C.UTF-8 "/." "??" 0 ++C.UTF-8 "/" "[!a-c]" 0 ++C.UTF-8 "." "[!a-c]" 0 ++ ++# B.6 029(C) ++C.UTF-8 "/" "/" 0 PATHNAME ++C.UTF-8 "//" "//" 0 PATHNAME ++C.UTF-8 "/.a" "/*" 0 PATHNAME ++C.UTF-8 "/.a" "/?a" 0 PATHNAME ++C.UTF-8 "/.a" "/[!a-z]a" 0 PATHNAME ++C.UTF-8 "/.a/.b" "/*/?b" 0 PATHNAME ++ ++# B.6 030(C) ++C.UTF-8 "/" "?" NOMATCH PATHNAME ++C.UTF-8 "/" "*" NOMATCH PATHNAME ++C.UTF-8 "a/b" "a?b" NOMATCH PATHNAME ++C.UTF-8 "/.a/.b" "/*b" NOMATCH PATHNAME ++ ++# B.6 031(C) ++C.UTF-8 "/$" "\\/\\$" 0 ++C.UTF-8 "/[" "\\/\\[" 0 ++C.UTF-8 "/[" "\\/[" 0 ++C.UTF-8 "/[]" "\\/\\[]" 0 ++ ++# B.6 032(C) ++C.UTF-8 "/$" "\\/\\$" NOMATCH NOESCAPE ++C.UTF-8 "/\\$" "\\/\\$" NOMATCH NOESCAPE ++C.UTF-8 "\\/\\$" "\\/\\$" 0 NOESCAPE ++ ++# B.6 033(C) ++C.UTF-8 ".asd" ".*" 0 PERIOD ++C.UTF-8 "/.asd" "*" 0 PERIOD ++C.UTF-8 "/as/.df" "*/?*f" 0 PERIOD ++C.UTF-8 "..asd" ".[!a-z]*" 0 PERIOD ++ ++# B.6 034(C) ++C.UTF-8 ".asd" "*" NOMATCH PERIOD ++C.UTF-8 ".asd" "?asd" NOMATCH PERIOD ++C.UTF-8 ".asd" "[!a-z]*" NOMATCH PERIOD ++ ++# B.6 035(C) ++C.UTF-8 "/." "/." 0 PATHNAME|PERIOD ++C.UTF-8 "/.a./.b." "/.*/.*" 0 PATHNAME|PERIOD ++C.UTF-8 "/.a./.b." "/.??/.??" 0 PATHNAME|PERIOD ++ ++# B.6 036(C) ++C.UTF-8 "/." "*" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/." "/*" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/." "/?" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/." "/[!a-z]" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/a./.b." "/*/*" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/a./.b." "/??/???" NOMATCH PATHNAME|PERIOD ++ ++# Some home-grown tests. ++C.UTF-8 "foobar" "foo*[abc]z" NOMATCH ++C.UTF-8 "foobaz" "foo*[abc][xyz]" 0 ++C.UTF-8 "foobaz" "foo?*[abc][xyz]" 0 ++C.UTF-8 "foobaz" "foo?*[abc][x/yz]" 0 ++C.UTF-8 "foobaz" "foo?*[abc]/[xyz]" NOMATCH PATHNAME ++C.UTF-8 "a" "a/" NOMATCH PATHNAME ++C.UTF-8 "a/" "a" NOMATCH PATHNAME ++C.UTF-8 "//a" "/a" NOMATCH PATHNAME ++C.UTF-8 "/a" "//a" NOMATCH PATHNAME ++C.UTF-8 "az" "[a-]z" 0 ++C.UTF-8 "bz" "[ab-]z" 0 ++C.UTF-8 "cz" "[ab-]z" NOMATCH ++C.UTF-8 "-z" "[ab-]z" 0 ++C.UTF-8 "az" "[-a]z" 0 ++C.UTF-8 "bz" "[-ab]z" 0 ++C.UTF-8 "cz" "[-ab]z" NOMATCH ++C.UTF-8 "-z" "[-ab]z" 0 ++C.UTF-8 "\\" "[\\\\-a]" 0 ++C.UTF-8 "_" "[\\\\-a]" 0 ++C.UTF-8 "a" "[\\\\-a]" 0 ++C.UTF-8 "-" "[\\\\-a]" NOMATCH ++C.UTF-8 "\\" "[\\]-a]" NOMATCH ++C.UTF-8 "_" "[\\]-a]" 0 ++C.UTF-8 "a" "[\\]-a]" 0 ++C.UTF-8 "]" "[\\]-a]" 0 ++C.UTF-8 "-" "[\\]-a]" NOMATCH ++C.UTF-8 "\\" "[!\\\\-a]" NOMATCH ++C.UTF-8 "_" "[!\\\\-a]" NOMATCH ++C.UTF-8 "a" "[!\\\\-a]" NOMATCH ++C.UTF-8 "-" "[!\\\\-a]" 0 ++C.UTF-8 "!" "[\\!-]" 0 ++C.UTF-8 "-" "[\\!-]" 0 ++C.UTF-8 "\\" "[\\!-]" NOMATCH ++C.UTF-8 "Z" "[Z-\\\\]" 0 ++C.UTF-8 "[" "[Z-\\\\]" 0 ++C.UTF-8 "\\" "[Z-\\\\]" 0 ++C.UTF-8 "-" "[Z-\\\\]" NOMATCH ++C.UTF-8 "Z" "[Z-\\]]" 0 ++C.UTF-8 "[" "[Z-\\]]" 0 ++C.UTF-8 "\\" "[Z-\\]]" 0 ++C.UTF-8 "]" "[Z-\\]]" 0 ++C.UTF-8 "-" "[Z-\\]]" NOMATCH ++ + # Following are tests outside the scope of IEEE 2003.2 since they are using + # locales other than the C locale. The main focus of the tests is on the + # handling of ranges and the recognition of character (vs bytes). +@@ -677,7 +1068,6 @@ C "x/y" "*" 0 PATHNAME|LEADING_DIR + C "x/y/z" "*" 0 PATHNAME|LEADING_DIR + C "x" "*x" 0 PATHNAME|LEADING_DIR + +-en_US.UTF-8 "\366.csv" "*.csv" 0 + C "x/y" "*x" 0 PATHNAME|LEADING_DIR + C "x/y/z" "*x" 0 PATHNAME|LEADING_DIR + C "x" "x*" 0 PATHNAME|LEADING_DIR +@@ -693,6 +1083,33 @@ C "x" "x?y" NOMATCH PATHNAME|LEADING_DIR + C "x/y" "x?y" NOMATCH PATHNAME|LEADING_DIR + C "x/y/z" "x?y" NOMATCH PATHNAME|LEADING_DIR + ++# Duplicate the "Test of GNU extensions." tests but for C.UTF-8. ++C.UTF-8 "x" "x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "*x" 0 PATHNAME|LEADING_DIR ++ ++C.UTF-8 "x/y" "*x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "*x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "x*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "x*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "x*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "a" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "a" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "a" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x" "x/y" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "x/y" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "x/y" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "x?y" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "x?y" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "x?y" NOMATCH PATHNAME|LEADING_DIR ++ ++# Bug 14185 ++en_US.UTF-8 "\366.csv" "*.csv" 0 ++ + # ksh style matching. + C "abcd" "?@(a|b)*@(c)d" 0 EXTMATCH + C "/dev/udp/129.22.8.102/45" "/dev/@(tcp|udp)/*/*" 0 PATHNAME|EXTMATCH +@@ -822,3 +1239,133 @@ C "" "" 0 + C "" "" 0 EXTMATCH + C "" "*([abc])" 0 EXTMATCH + C "" "?([abc])" 0 EXTMATCH ++ ++# Duplicate the "ksh style matching." for C.UTF-8. ++C.UTF-8 "abcd" "?@(a|b)*@(c)d" 0 EXTMATCH ++C.UTF-8 "/dev/udp/129.22.8.102/45" "/dev/@(tcp|udp)/*/*" 0 PATHNAME|EXTMATCH ++C.UTF-8 "12" "[1-9]*([0-9])" 0 EXTMATCH ++C.UTF-8 "12abc" "[1-9]*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "1" "[1-9]*([0-9])" 0 EXTMATCH ++C.UTF-8 "07" "+([0-7])" 0 EXTMATCH ++C.UTF-8 "0377" "+([0-7])" 0 EXTMATCH ++C.UTF-8 "09" "+([0-7])" NOMATCH EXTMATCH ++C.UTF-8 "paragraph" "para@(chute|graph)" 0 EXTMATCH ++C.UTF-8 "paramour" "para@(chute|graph)" NOMATCH EXTMATCH ++C.UTF-8 "para991" "para?([345]|99)1" 0 EXTMATCH ++C.UTF-8 "para381" "para?([345]|99)1" NOMATCH EXTMATCH ++C.UTF-8 "paragraph" "para*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "para" "para*([0-9])" 0 EXTMATCH ++C.UTF-8 "para13829383746592" "para*([0-9])" 0 EXTMATCH ++C.UTF-8 "paragraph" "para+([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "para" "para+([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "para987346523" "para+([0-9])" 0 EXTMATCH ++C.UTF-8 "paragraph" "para!(*.[0-9])" 0 EXTMATCH ++C.UTF-8 "para.38" "para!(*.[0-9])" 0 EXTMATCH ++C.UTF-8 "para.graph" "para!(*.[0-9])" 0 EXTMATCH ++C.UTF-8 "para39" "para!(*.[0-9])" 0 EXTMATCH ++C.UTF-8 "" "*(0|1|3|5|7|9)" 0 EXTMATCH ++C.UTF-8 "137577991" "*(0|1|3|5|7|9)" 0 EXTMATCH ++C.UTF-8 "2468" "*(0|1|3|5|7|9)" NOMATCH EXTMATCH ++C.UTF-8 "1358" "*(0|1|3|5|7|9)" NOMATCH EXTMATCH ++C.UTF-8 "file.c" "*.c?(c)" 0 EXTMATCH ++C.UTF-8 "file.C" "*.c?(c)" NOMATCH EXTMATCH ++C.UTF-8 "file.cc" "*.c?(c)" 0 EXTMATCH ++C.UTF-8 "file.ccc" "*.c?(c)" NOMATCH EXTMATCH ++C.UTF-8 "parse.y" "!(*.c|*.h|Makefile.in|config*|README)" 0 EXTMATCH ++C.UTF-8 "shell.c" "!(*.c|*.h|Makefile.in|config*|README)" NOMATCH EXTMATCH ++C.UTF-8 "Makefile" "!(*.c|*.h|Makefile.in|config*|README)" 0 EXTMATCH ++C.UTF-8 "VMS.FILE;1" "*\;[1-9]*([0-9])" 0 EXTMATCH ++C.UTF-8 "VMS.FILE;0" "*\;[1-9]*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "VMS.FILE;" "*\;[1-9]*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "VMS.FILE;139" "*\;[1-9]*([0-9])" 0 EXTMATCH ++C.UTF-8 "VMS.FILE;1N" "*\;[1-9]*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "abcfefg" "ab**(e|f)" 0 EXTMATCH ++C.UTF-8 "abcfefg" "ab**(e|f)g" 0 EXTMATCH ++C.UTF-8 "ab" "ab*+(e|f)" NOMATCH EXTMATCH ++C.UTF-8 "abef" "ab***ef" 0 EXTMATCH ++C.UTF-8 "abef" "ab**" 0 EXTMATCH ++C.UTF-8 "fofo" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "ffo" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "foooofo" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "foooofof" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "fooofoofofooo" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "foooofof" "*(f+(o))" NOMATCH EXTMATCH ++C.UTF-8 "xfoooofof" "*(f*(o))" NOMATCH EXTMATCH ++C.UTF-8 "foooofofx" "*(f*(o))" NOMATCH EXTMATCH ++C.UTF-8 "ofxoofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofooofoofofooo" "*(f*(o))" NOMATCH EXTMATCH ++C.UTF-8 "foooxfooxfoxfooox" "*(f*(o)x)" 0 EXTMATCH ++C.UTF-8 "foooxfooxofoxfooox" "*(f*(o)x)" NOMATCH EXTMATCH ++C.UTF-8 "foooxfooxfxfooox" "*(f*(o)x)" 0 EXTMATCH ++C.UTF-8 "ofxoofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofoooxoofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofoooxoofxoofoooxoofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofoooxoofxoofoooxoofxoo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofoooxoofxoofoooxoofxofo" "*(*(of*(o)x)o)" NOMATCH EXTMATCH ++C.UTF-8 "ofoooxoofxoofoooxoofxooofxofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "aac" "*(@(a))a@(c)" 0 EXTMATCH ++C.UTF-8 "ac" "*(@(a))a@(c)" 0 EXTMATCH ++C.UTF-8 "c" "*(@(a))a@(c)" NOMATCH EXTMATCH ++C.UTF-8 "aaac" "*(@(a))a@(c)" 0 EXTMATCH ++C.UTF-8 "baaac" "*(@(a))a@(c)" NOMATCH EXTMATCH ++C.UTF-8 "abcd" "?@(a|b)*@(c)d" 0 EXTMATCH ++C.UTF-8 "abcd" "@(ab|a*@(b))*(c)d" 0 EXTMATCH ++C.UTF-8 "acd" "@(ab|a*(b))*(c)d" 0 EXTMATCH ++C.UTF-8 "abbcd" "@(ab|a*(b))*(c)d" 0 EXTMATCH ++C.UTF-8 "effgz" "@(b+(c)d|e*(f)g?|?(h)i@(j|k))" 0 EXTMATCH ++C.UTF-8 "efgz" "@(b+(c)d|e*(f)g?|?(h)i@(j|k))" 0 EXTMATCH ++C.UTF-8 "egz" "@(b+(c)d|e*(f)g?|?(h)i@(j|k))" 0 EXTMATCH ++C.UTF-8 "egzefffgzbcdij" "*(b+(c)d|e*(f)g?|?(h)i@(j|k))" 0 EXTMATCH ++C.UTF-8 "egz" "@(b+(c)d|e+(f)g?|?(h)i@(j|k))" NOMATCH EXTMATCH ++C.UTF-8 "ofoofo" "*(of+(o))" 0 EXTMATCH ++C.UTF-8 "oxfoxoxfox" "*(oxf+(ox))" 0 EXTMATCH ++C.UTF-8 "oxfoxfox" "*(oxf+(ox))" NOMATCH EXTMATCH ++C.UTF-8 "ofoofo" "*(of+(o)|f)" 0 EXTMATCH ++C.UTF-8 "foofoofo" "@(foo|f|fo)*(f|of+(o))" 0 EXTMATCH ++C.UTF-8 "oofooofo" "*(of|oof+(o))" 0 EXTMATCH ++C.UTF-8 "fffooofoooooffoofffooofff" "*(*(f)*(o))" 0 EXTMATCH ++C.UTF-8 "fofoofoofofoo" "*(fo|foo)" 0 EXTMATCH ++C.UTF-8 "foo" "!(x)" 0 EXTMATCH ++C.UTF-8 "foo" "!(x)*" 0 EXTMATCH ++C.UTF-8 "foo" "!(foo)" NOMATCH EXTMATCH ++C.UTF-8 "foo" "!(foo)*" 0 EXTMATCH ++C.UTF-8 "foobar" "!(foo)" 0 EXTMATCH ++C.UTF-8 "foobar" "!(foo)*" 0 EXTMATCH ++C.UTF-8 "moo.cow" "!(*.*).!(*.*)" 0 EXTMATCH ++C.UTF-8 "mad.moo.cow" "!(*.*).!(*.*)" NOMATCH EXTMATCH ++C.UTF-8 "mucca.pazza" "mu!(*(c))?.pa!(*(z))?" NOMATCH EXTMATCH ++C.UTF-8 "fff" "!(f)" 0 EXTMATCH ++C.UTF-8 "fff" "*(!(f))" 0 EXTMATCH ++C.UTF-8 "fff" "+(!(f))" 0 EXTMATCH ++C.UTF-8 "ooo" "!(f)" 0 EXTMATCH ++C.UTF-8 "ooo" "*(!(f))" 0 EXTMATCH ++C.UTF-8 "ooo" "+(!(f))" 0 EXTMATCH ++C.UTF-8 "foo" "!(f)" 0 EXTMATCH ++C.UTF-8 "foo" "*(!(f))" 0 EXTMATCH ++C.UTF-8 "foo" "+(!(f))" 0 EXTMATCH ++C.UTF-8 "f" "!(f)" NOMATCH EXTMATCH ++C.UTF-8 "f" "*(!(f))" NOMATCH EXTMATCH ++C.UTF-8 "f" "+(!(f))" NOMATCH EXTMATCH ++C.UTF-8 "foot" "@(!(z*)|*x)" 0 EXTMATCH ++C.UTF-8 "zoot" "@(!(z*)|*x)" NOMATCH EXTMATCH ++C.UTF-8 "foox" "@(!(z*)|*x)" 0 EXTMATCH ++C.UTF-8 "zoox" "@(!(z*)|*x)" 0 EXTMATCH ++C.UTF-8 "foo" "*(!(foo))" 0 EXTMATCH ++C.UTF-8 "foob" "!(foo)b*" NOMATCH EXTMATCH ++C.UTF-8 "foobb" "!(foo)b*" 0 EXTMATCH ++C.UTF-8 "[" "*([a[])" 0 EXTMATCH ++C.UTF-8 "]" "*([]a[])" 0 EXTMATCH ++C.UTF-8 "a" "*([]a[])" 0 EXTMATCH ++C.UTF-8 "b" "*([!]a[])" 0 EXTMATCH ++C.UTF-8 "[" "*([!]a[]|[[])" 0 EXTMATCH ++C.UTF-8 "]" "*([!]a[]|[]])" 0 EXTMATCH ++C.UTF-8 "[" "!([!]a[])" 0 EXTMATCH ++C.UTF-8 "]" "!([!]a[])" 0 EXTMATCH ++C.UTF-8 ")" "*([)])" 0 EXTMATCH ++C.UTF-8 "*" "*([*(])" 0 EXTMATCH ++C.UTF-8 "abcd" "*!(|a)cd" 0 EXTMATCH ++C.UTF-8 "ab/.a" "+([abc])/*" NOMATCH EXTMATCH|PATHNAME|PERIOD ++C.UTF-8 "" "" 0 ++C.UTF-8 "" "" 0 EXTMATCH ++C.UTF-8 "" "*([abc])" 0 EXTMATCH ++C.UTF-8 "" "?([abc])" 0 EXTMATCH +diff --git a/posix/tst-regcomp-truncated.c b/posix/tst-regcomp-truncated.c +index 84195fcd2ec153b8..da3f97799e37c607 100644 +--- a/posix/tst-regcomp-truncated.c ++++ b/posix/tst-regcomp-truncated.c +@@ -37,6 +37,7 @@ + static const char locales[][17] = + { + "C", ++ "C.UTF-8", + "en_US.UTF-8", + "de_DE.ISO-8859-1", + }; +diff --git a/posix/tst-regex.c b/posix/tst-regex.c +index e7c2b05e8666a16e..531128de2a9176fa 100644 +--- a/posix/tst-regex.c ++++ b/posix/tst-regex.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + + #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0 +@@ -58,7 +59,7 @@ do_test (void) + const char *file; + int fd; + struct stat st; +- int result; ++ int result = 0; + char *inmem; + char *outmem; + size_t inlen; +@@ -123,7 +124,7 @@ do_test (void) + + /* Run the actual tests. All tests are run in a single-byte and a + multi-byte locale. */ +- result = test_expr ("[äáàâéèêíìîñöóòôüúùû]", 4, 4); ++ result |= test_expr ("[äáàâéèêíìîñöóòôüúùû]", 4, 4); + result |= test_expr ("G.ran", 2, 3); + result |= test_expr ("G.\\{1\\}ran", 2, 3); + result |= test_expr ("G.*ran", 3, 44); +@@ -143,19 +144,33 @@ do_test (void) + static int + test_expr (const char *expr, int expected, int expectedicase) + { +- int result; ++ int result = 0; + char *inmem; + char *outmem; + size_t inlen; + size_t outlen; + char *uexpr; + +- /* First test: search with an UTF-8 locale. */ +- if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) +- error (EXIT_FAILURE, 0, "cannot set locale de_DE.UTF-8"); ++ /* First test: search with basic C.UTF-8 locale. */ ++ printf ("INFO: Testing C.UTF-8.\n"); ++ xsetlocale (LC_ALL, "C.UTF-8"); + + printf ("\nTest \"%s\" with multi-byte locale\n", expr); +- result = run_test (expr, mem, memlen, 0, expected); ++ result |= run_test (expr, mem, memlen, 0, expected); ++ printf ("\nTest \"%s\" with multi-byte locale, case insensitive\n", expr); ++ result |= run_test (expr, mem, memlen, 1, expectedicase); ++ printf ("\nTest \"%s\" backwards with multi-byte locale\n", expr); ++ result |= run_test_backwards (expr, mem, memlen, 0, expected); ++ printf ("\nTest \"%s\" backwards with multi-byte locale, case insensitive\n", ++ expr); ++ result |= run_test_backwards (expr, mem, memlen, 1, expectedicase); ++ ++ /* Second test: search with an UTF-8 locale. */ ++ printf ("INFO: Testing de_DE.UTF-8.\n"); ++ xsetlocale (LC_ALL, "de_DE.UTF-8"); ++ ++ printf ("\nTest \"%s\" with multi-byte locale\n", expr); ++ result |= run_test (expr, mem, memlen, 0, expected); + printf ("\nTest \"%s\" with multi-byte locale, case insensitive\n", expr); + result |= run_test (expr, mem, memlen, 1, expectedicase); + printf ("\nTest \"%s\" backwards with multi-byte locale\n", expr); +@@ -165,8 +180,8 @@ test_expr (const char *expr, int expected, int expectedicase) + result |= run_test_backwards (expr, mem, memlen, 1, expectedicase); + + /* Second test: search with an ISO-8859-1 locale. */ +- if (setlocale (LC_ALL, "de_DE.ISO-8859-1") == NULL) +- error (EXIT_FAILURE, 0, "cannot set locale de_DE.ISO-8859-1"); ++ printf ("INFO: Testing de_DE.ISO-8859-1.\n"); ++ xsetlocale (LC_ALL, "de_DE.ISO-8859-1"); + + inmem = (char *) expr; + inlen = strlen (expr); diff --git a/SOURCES/glibc-c-utf8-locale-3.patch b/SOURCES/glibc-c-utf8-locale-3.patch new file mode 100644 index 0000000..3a90a47 --- /dev/null +++ b/SOURCES/glibc-c-utf8-locale-3.patch @@ -0,0 +1,65 @@ +commit 1d8e3a2c6636cf0b1b8fa2f869cef6ec10726933 +Author: Carlos O'Donell +Date: Mon Jan 31 00:34:41 2022 -0500 + + localedef: Fix handling of empty mon_decimal_point (Bug 28847) + + The handling of mon_decimal_point is incorrect when it comes to + handling the empty "" value. The existing parser in monetary_read() + will correctly handle setting the non-wide-character value and the + wide-character value e.g. STR_ELEM_WC(mon_decimal_point) if they are + set in the locale definition. However, in monetary_finish() we have + conflicting TEST_ELEM() which sets a default value (if the locale + definition doesn't include one), and subsequent code which looks for + mon_decimal_point to be NULL to issue a specific error message and set + the defaults. The latter is unused because TEST_ELEM() always sets a + default. The simplest solution is to remove the TEST_ELEM() check, + and allow the existing check to look to see if mon_decimal_point is + NULL and set an appropriate default. The final fix is to move the + setting of mon_decimal_point_wc so it occurs only when + mon_decimal_point is being set to a default, keeping both values + consistent. There is no way to tell the difference between + mon_decimal_point_wc having been set to the empty string and not + having been defined at all, for that distinction we must use + mon_decimal_point being NULL or "", and so we must logically set + the default together with mon_decimal_point. + + Lastly, there are more fixes similar to this that could be made to + ld-monetary.c, but we avoid that in order to fix just the code + required for mon_decimal_point, which impacts the ability for C.UTF-8 + to set mon_decimal_point to "", since without this fix we end up with + an inconsistent setting of mon_decimal_point set to "", but + mon_decimal_point_wc set to "." which is incorrect. + + Tested on x86_64 and i686 without regression. + Reviewed-by: Florian Weimer + +diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c +index e1e45a3409123bf4..9b9a55bb4766dfcf 100644 +--- a/locale/programs/ld-monetary.c ++++ b/locale/programs/ld-monetary.c +@@ -208,7 +208,6 @@ No definition for %s category found"), "LC_MONETARY"); + + TEST_ELEM (int_curr_symbol, ""); + TEST_ELEM (currency_symbol, ""); +- TEST_ELEM (mon_decimal_point, "."); + TEST_ELEM (mon_thousands_sep, ""); + TEST_ELEM (positive_sign, ""); + TEST_ELEM (negative_sign, ""); +@@ -258,6 +257,7 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"), + record_error (0, 0, _("%s: field `%s' not defined"), + "LC_MONETARY", "mon_decimal_point"); + monetary->mon_decimal_point = "."; ++ monetary->mon_decimal_point_wc = L'.'; + } + else if (monetary->mon_decimal_point[0] == '\0' && ! be_quiet && ! nothing) + { +@@ -265,8 +265,6 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"), + %s: value for field `%s' must not be an empty string"), + "LC_MONETARY", "mon_decimal_point"); + } +- if (monetary->mon_decimal_point_wc == L'\0') +- monetary->mon_decimal_point_wc = L'.'; + + if (monetary->mon_grouping_len == 0) + { diff --git a/SOURCES/glibc-c-utf8-locale-4.patch b/SOURCES/glibc-c-utf8-locale-4.patch new file mode 100644 index 0000000..8e9ec4c --- /dev/null +++ b/SOURCES/glibc-c-utf8-locale-4.patch @@ -0,0 +1,734 @@ +commit de82cb0da4b8fa5b3d56c457438d2568c67ab1b1 +Author: Joseph Myers +Date: Tue Oct 12 13:48:39 2021 +0000 + + Add TEST_COMPARE_STRING_WIDE to support/check.h + + I'd like to be able to test narrow and wide string interfaces, with + the narrow string tests using TEST_COMPARE_STRING and the wide string + tests using something analogous (possibly generated using macros from + a common test template for both the narrow and wide string tests where + appropriate). + + Add such a TEST_COMPARE_STRING_WIDE, along with functions + support_quote_blob_wide and support_test_compare_string_wide that it + builds on. Those functions are built using macros from common + templates shared by the narrow and wide string implementations, though + I didn't do that for the tests of test functions. In + support_quote_blob_wide, I chose to use the \x{} delimited escape + sequence syntax proposed for C2X in N2785, rather than e.g. trying to + generate the end of a string and the start of a new string when + ambiguity would result from undelimited \x (when the next character + after such an escape sequence is valid hex) or forcing an escape + sequence to be used for the next character in the case of such + ambiguity. + + Tested for x86_64. + +diff --git a/support/Makefile b/support/Makefile +index 75bad6715ac3d08c..3c941e1ba9e29aa4 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -70,6 +70,7 @@ libsupport-routines = \ + support_openpty \ + support_paths \ + support_quote_blob \ ++ support_quote_blob_wide \ + support_quote_string \ + support_record_failure \ + support_run_diff \ +@@ -83,6 +84,7 @@ libsupport-routines = \ + support_test_compare_blob \ + support_test_compare_failure \ + support_test_compare_string \ ++ support_test_compare_string_wide \ + support_test_main \ + support_test_verify_impl \ + support_wait_for_thread_exit \ +@@ -275,11 +277,13 @@ tests = \ + tst-support-open-dev-null-range \ + tst-support-process_state \ + tst-support_quote_blob \ ++ tst-support_quote_blob_wide \ + tst-support_quote_string \ + tst-support_record_failure \ + tst-test_compare \ + tst-test_compare_blob \ + tst-test_compare_string \ ++ tst-test_compare_string_wide \ + tst-timespec \ + tst-xreadlink \ + tst-xsigstack \ +diff --git a/support/check.h b/support/check.h +index 83662b2d10c8cf58..9b1844352f32513a 100644 +--- a/support/check.h ++++ b/support/check.h +@@ -20,6 +20,7 @@ + #define SUPPORT_CHECK_H + + #include ++#include + + __BEGIN_DECLS + +@@ -171,11 +172,25 @@ void support_test_compare_blob (const void *left, + (support_test_compare_string (left, right, __FILE__, __LINE__, \ + #left, #right)) + ++/* Compare the wide 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_WIDE(left, right) \ ++ (support_test_compare_string_wide (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); + ++void support_test_compare_string_wide (const wchar_t *left, ++ const wchar_t *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/support.h b/support/support.h +index c219e0d9d1aef046..29d56c7c891ee34b 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -73,6 +73,12 @@ 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 wide character array starting at BLOB, of ++ LENGTH wide characters, in such a way that the result string can be ++ included in a C wide string literal (in single/double quotes, ++ without putting the quotes into the result). */ ++char *support_quote_blob_wide (const void *blob, size_t length); ++ + /* 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). */ +diff --git a/support/support_quote_blob.c b/support/support_quote_blob.c +index b5e70125f13eb081..611980c9a2108670 100644 +--- a/support/support_quote_blob.c ++++ b/support/support_quote_blob.c +@@ -1,4 +1,4 @@ +-/* Quote a blob so that it can be used in C literals. ++/* Quote a narrow string blob so that it can be used in C literals. + Copyright (C) 2018-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -16,68 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include ++#define CHAR unsigned char ++#define L_(C) C ++#define SUPPORT_QUOTE_BLOB support_quote_blob ++#define WIDE 0 + +-char * +-support_quote_blob (const void *blob, size_t length) +-{ +- struct xmemstream out; +- xopen_memstream (&out); +- +- const unsigned char *p = blob; +- for (size_t i = 0; i < length; ++i) +- { +- unsigned char ch = p[i]; +- +- /* Use C backslash escapes for those control characters for +- which they are defined. */ +- switch (ch) +- { +- case '\a': +- putc_unlocked ('\\', out.out); +- putc_unlocked ('a', out.out); +- break; +- case '\b': +- putc_unlocked ('\\', out.out); +- putc_unlocked ('b', out.out); +- break; +- case '\f': +- putc_unlocked ('\\', out.out); +- putc_unlocked ('f', out.out); +- break; +- case '\n': +- putc_unlocked ('\\', out.out); +- putc_unlocked ('n', out.out); +- break; +- case '\r': +- putc_unlocked ('\\', out.out); +- putc_unlocked ('r', out.out); +- break; +- case '\t': +- putc_unlocked ('\\', out.out); +- putc_unlocked ('t', out.out); +- break; +- case '\v': +- putc_unlocked ('\\', out.out); +- putc_unlocked ('v', out.out); +- break; +- case '\\': +- case '\'': +- case '\"': +- putc_unlocked ('\\', out.out); +- putc_unlocked (ch, out.out); +- break; +- default: +- if (ch < ' ' || ch > '~') +- /* Use octal sequences because they are fixed width, +- unlike hexadecimal sequences. */ +- fprintf (out.out, "\\%03o", ch); +- else +- putc_unlocked (ch, out.out); +- } +- } +- +- xfclose_memstream (&out); +- return out.buffer; +-} ++#include "support_quote_blob_main.c" +diff --git a/support/support_quote_blob_main.c b/support/support_quote_blob_main.c +new file mode 100644 +index 0000000000000000..19ccfad59311bfee +--- /dev/null ++++ b/support/support_quote_blob_main.c +@@ -0,0 +1,88 @@ ++/* Quote a blob so that it can be used in C literals. ++ Copyright (C) 2018-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++char * ++SUPPORT_QUOTE_BLOB (const void *blob, size_t length) ++{ ++ struct xmemstream out; ++ xopen_memstream (&out); ++ ++ const CHAR *p = blob; ++ for (size_t i = 0; i < length; ++i) ++ { ++ CHAR ch = p[i]; ++ ++ /* Use C backslash escapes for those control characters for ++ which they are defined. */ ++ switch (ch) ++ { ++ case L_('\a'): ++ putc_unlocked ('\\', out.out); ++ putc_unlocked ('a', out.out); ++ break; ++ case L_('\b'): ++ putc_unlocked ('\\', out.out); ++ putc_unlocked ('b', out.out); ++ break; ++ case L_('\f'): ++ putc_unlocked ('\\', out.out); ++ putc_unlocked ('f', out.out); ++ break; ++ case L_('\n'): ++ putc_unlocked ('\\', out.out); ++ putc_unlocked ('n', out.out); ++ break; ++ case L_('\r'): ++ putc_unlocked ('\\', out.out); ++ putc_unlocked ('r', out.out); ++ break; ++ case L_('\t'): ++ putc_unlocked ('\\', out.out); ++ putc_unlocked ('t', out.out); ++ break; ++ case L_('\v'): ++ putc_unlocked ('\\', out.out); ++ putc_unlocked ('v', out.out); ++ break; ++ case L_('\\'): ++ case L_('\''): ++ case L_('\"'): ++ putc_unlocked ('\\', out.out); ++ putc_unlocked (ch, out.out); ++ break; ++ default: ++ if (ch < L_(' ') || ch > L_('~')) ++ /* For narrow characters, use octal sequences because they ++ are fixed width, unlike hexadecimal sequences. For ++ wide characters, use N2785 delimited escape ++ sequences. */ ++ if (WIDE) ++ fprintf (out.out, "\\x{%x}", (unsigned int) ch); ++ else ++ fprintf (out.out, "\\%03o", (unsigned int) ch); ++ else ++ putc_unlocked (ch, out.out); ++ } ++ } ++ ++ xfclose_memstream (&out); ++ return out.buffer; ++} +diff --git a/support/support_quote_blob_wide.c b/support/support_quote_blob_wide.c +new file mode 100644 +index 0000000000000000..c451ed889c21c626 +--- /dev/null ++++ b/support/support_quote_blob_wide.c +@@ -0,0 +1,24 @@ ++/* Quote a wide string blob so that it can be used in C literals. ++ Copyright (C) 2018-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define CHAR wchar_t ++#define L_(C) L ## C ++#define SUPPORT_QUOTE_BLOB support_quote_blob_wide ++#define WIDE 1 ++ ++#include "support_quote_blob_main.c" +diff --git a/support/support_test_compare_string.c b/support/support_test_compare_string.c +index cbeaf7b1eeea8ca8..12bafe43d44ae3d7 100644 +--- a/support/support_test_compare_string.c ++++ b/support/support_test_compare_string.c +@@ -16,76 +16,13 @@ + 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: string 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); +- } +-} ++#define CHAR char ++#define UCHAR unsigned char ++#define LPREFIX "" ++#define STRLEN strlen ++#define MEMCMP memcmp ++#define SUPPORT_QUOTE_BLOB support_quote_blob ++#define SUPPORT_TEST_COMPARE_STRING support_test_compare_string ++#define WIDE 0 ++ ++#include "support_test_compare_string_main.c" +diff --git a/support/support_test_compare_string_main.c b/support/support_test_compare_string_main.c +new file mode 100644 +index 0000000000000000..0edc0ca97d79d71e +--- /dev/null ++++ b/support/support_test_compare_string_main.c +@@ -0,0 +1,94 @@ ++/* Check two strings for equality. ++ Copyright (C) 2018-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 %s\n", what, length, ++ WIDE ? "wide characters" : "bytes"); ++} ++ ++static void ++report_string (const char *what, const UCHAR *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\"%s\"\n", LPREFIX, quoted); ++ free (quoted); ++ ++ fputs (" ", stdout); ++ for (size_t i = 0; i < length; ++i) ++ printf (" %02X", (unsigned int) 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: string comparison failed\n", file, line); ++ if (left_length == right_length && right != NULL && left != NULL) ++ printf (" string length: %zu %s\n", left_length, ++ WIDE ? "wide characters" : "bytes"); ++ else ++ { ++ report_length ("left", left, left_length); ++ report_length ("right", right, right_length); ++ } ++ report_string ("left", (const UCHAR *) left, ++ left_length, left_expr); ++ report_string ("right", (const UCHAR *) right, ++ right_length, right_expr); ++ } ++} +diff --git a/support/support_test_compare_string_wide.c b/support/support_test_compare_string_wide.c +new file mode 100644 +index 0000000000000000..88b560b142a3c356 +--- /dev/null ++++ b/support/support_test_compare_string_wide.c +@@ -0,0 +1,28 @@ ++/* Check two wide strings for equality. ++ Copyright (C) 2018-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define CHAR wchar_t ++#define UCHAR wchar_t ++#define LPREFIX "L" ++#define STRLEN wcslen ++#define MEMCMP wmemcmp ++#define SUPPORT_QUOTE_BLOB support_quote_blob_wide ++#define SUPPORT_TEST_COMPARE_STRING support_test_compare_string_wide ++#define WIDE 1 ++ ++#include "support_test_compare_string_main.c" +diff --git a/support/tst-support_quote_blob_wide.c b/support/tst-support_quote_blob_wide.c +new file mode 100644 +index 0000000000000000..ea71a1f7f873b23a +--- /dev/null ++++ b/support/tst-support_quote_blob_wide.c +@@ -0,0 +1,66 @@ ++/* Test the support_quote_blob_wide function. ++ Copyright (C) 2018-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ /* Check handling of the empty blob, both with and without trailing ++ NUL byte. */ ++ char *p = support_quote_blob_wide (L"", 0); ++ TEST_COMPARE (strlen (p), 0); ++ free (p); ++ p = support_quote_blob_wide (L"X", 0); ++ TEST_COMPARE (strlen (p), 0); ++ free (p); ++ ++ /* Check escaping of backslash-escaped characters, and lack of ++ escaping for other shell meta-characters. */ ++ p = support_quote_blob_wide (L"$()*?`@[]{}~\'\"X", 14); ++ TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\""), 0); ++ free (p); ++ ++ /* Check lack of escaping for letters and digits. */ ++#define LETTERS_AND_DIGTS \ ++ "abcdefghijklmnopqrstuvwxyz" \ ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ ++ "0123456789" ++#define CONCATX(X, Y) X ## Y ++#define CONCAT(X, Y) CONCATX (X, Y) ++#define WLETTERS_AND_DIGTS CONCAT (L, LETTERS_AND_DIGTS) ++ p = support_quote_blob_wide (WLETTERS_AND_DIGTS "@", 2 * 26 + 10); ++ TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS), 0); ++ free (p); ++ ++ /* Check escaping of control characters and other non-printable ++ characters. */ ++ p = support_quote_blob_wide (L"\r\n\t\a\b\f\v\1\177\200\377" ++ "\x123\x76543210\xfedcba98\0@", 17); ++ TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\x{1}" ++ "\\x{7f}\\x{80}\\x{ff}\\x{123}\\x{76543210}" ++ "\\x{fedcba98}\\x{0}@\\x{0}"), 0); ++ free (p); ++ ++ return 0; ++} ++ ++#include +diff --git a/support/tst-test_compare_string_wide.c b/support/tst-test_compare_string_wide.c +new file mode 100644 +index 0000000000000000..548f7dcdc60b82d8 +--- /dev/null ++++ b/support/tst-test_compare_string_wide.c +@@ -0,0 +1,107 @@ ++/* Basic test for the TEST_COMPARE_STRING_WIDE macro. ++ Copyright (C) 2018-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++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_WIDE (L"", NULL); /* Line 29. */ ++ TEST_COMPARE_STRING_WIDE (L"X", L""); /* Line 30. */ ++ TEST_COMPARE_STRING_WIDE (NULL, L"X"); /* Line 31. */ ++ TEST_COMPARE_STRING_WIDE (L"abcd", L"abcD"); /* Line 32. */ ++ TEST_COMPARE_STRING_WIDE (L"abcd", NULL); /* Line 33. */ ++ TEST_COMPARE_STRING_WIDE (NULL, L"abcd"); /* Line 34. */ ++} ++ ++/* Same contents, different addresses. */ ++wchar_t buffer_abc_1[] = L"abc"; ++wchar_t buffer_abc_2[] = L"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_WIDE (NULL, NULL); ++ TEST_COMPARE_STRING_WIDE (L"", L""); ++ TEST_COMPARE_STRING_WIDE (buffer_abc_1, buffer_abc_2); ++ TEST_COMPARE_STRING_WIDE (buffer_abc_1, L"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_wide.c:29: error: string comparison failed\n" ++" left string: 0 wide characters\n" ++" right string: NULL\n" ++"tst-test_compare_string_wide.c:30: error: string comparison failed\n" ++" left string: 1 wide characters\n" ++" right string: 0 wide characters\n" ++" left (evaluated from L\"X\"):\n" ++" L\"X\"\n" ++" 58\n" ++"tst-test_compare_string_wide.c:31: error: string comparison failed\n" ++" left string: NULL\n" ++" right string: 1 wide characters\n" ++" right (evaluated from L\"X\"):\n" ++" L\"X\"\n" ++" 58\n" ++"tst-test_compare_string_wide.c:32: error: string comparison failed\n" ++" string length: 4 wide characters\n" ++" left (evaluated from L\"abcd\"):\n" ++" L\"abcd\"\n" ++" 61 62 63 64\n" ++" right (evaluated from L\"abcD\"):\n" ++" L\"abcD\"\n" ++" 61 62 63 44\n" ++"tst-test_compare_string_wide.c:33: error: string comparison failed\n" ++" left string: 4 wide characters\n" ++" right string: NULL\n" ++" left (evaluated from L\"abcd\"):\n" ++" L\"abcd\"\n" ++" 61 62 63 64\n" ++"tst-test_compare_string_wide.c:34: error: string comparison failed\n" ++" left string: NULL\n" ++" right string: 4 wide characters\n" ++" right (evaluated from L\"abcd\"):\n" ++" L\"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_WIDE", ++ 0, sc_allow_stdout); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-c-utf8-locale-5.patch b/SOURCES/glibc-c-utf8-locale-5.patch new file mode 100644 index 0000000..06144a4 --- /dev/null +++ b/SOURCES/glibc-c-utf8-locale-5.patch @@ -0,0 +1,691 @@ +commit 7e0ad15c0fbfe25435c1acd0ed3e9cedfbff2488 +Author: Carlos O'Donell +Date: Mon Jan 31 00:34:42 2022 -0500 + + localedata: Adjust C.UTF-8 to align with C/POSIX. + + We have had one downstream report from Canonical [1] that + an rrdtool test was broken by the differences in LC_TIME + that we had in the non-builtin C locale (C.UTF-8). If one + application has an issue there are going to be others, and + so with this commit we review and fix all the issues that + cause the builtin C locale to be different from C.UTF-8, + which includes: + * mon_decimal_point should be empty e.g. "" + - Depends on mon_decimal_point_wc fix. + * negative_sign should be empty e.g. "" + * week should be aligned with the builtin C/POSIX locale + * d_fmt corrected with escaped slashes e.g. "%m//%d//%y" + * yesstr and nostr should be empty e.g. "" + * country_ab2 and country_ab3 should be empty e.g. "" + + We bump LC_IDENTIFICATION version and adjust the date to + indicate the change in the locale. + + A new tst-c-utf8-consistency test is added to ensure + consistency between C/POSIX and C.UTF-8. + + Tested on x86_64 and i686 without regression. + + [1] https://sourceware.org/pipermail/libc-alpha/2022-January/135703.html + + Co-authored-by: Florian Weimer + Reviewed-by: Florian Weimer + +diff --git a/localedata/Makefile b/localedata/Makefile +index c9dd5a954e8194cc..5830b9d05141cccd 100644 +--- a/localedata/Makefile ++++ b/localedata/Makefile +@@ -155,11 +155,31 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl \ + tst_wcsxfrm tst_wctob tst_wctomb tst_wctrans \ + tst_wctype tst_wcwidth + +-tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ +- tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \ +- tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \ +- tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \ +- tst-wctype tst-iconv-math-trans ++tests = \ ++ $(locale_test_suite) \ ++ bug-iconv-trans \ ++ bug-setlocale1 \ ++ bug-usesetlocale \ ++ tst-c-utf8-consistency \ ++ tst-digits \ ++ tst-iconv-math-trans \ ++ tst-leaks \ ++ tst-mbswcs1 \ ++ tst-mbswcs2 \ ++ tst-mbswcs3 \ ++ tst-mbswcs4 \ ++ tst-mbswcs5 \ ++ tst-mbswcs6 \ ++ tst-setlocale \ ++ tst-setlocale2 \ ++ tst-setlocale3 \ ++ tst-sscanf \ ++ tst-strfmon1 \ ++ tst-wctype \ ++ tst-xlocale1 \ ++ tst-xlocale2 \ ++ # tests ++ + tests-static = bug-setlocale1-static + tests += $(tests-static) + ifeq (yes,$(build-shared)) +diff --git a/localedata/locales/C b/localedata/locales/C +index ca801c79cf7e953e..fc0614e551519c6b 100644 +--- a/localedata/locales/C ++++ b/localedata/locales/C +@@ -12,8 +12,8 @@ tel "" + fax "" + language "" + territory "" +-revision "2.0" +-date "2020-06-28" ++revision "2.1" ++date "2022-01-30" + category "i18n:2012";LC_IDENTIFICATION + category "i18n:2012";LC_CTYPE + category "i18n:2012";LC_COLLATE +@@ -68,11 +68,11 @@ LC_MONETARY + % glibc/locale/C-monetary.c.). + int_curr_symbol "" + currency_symbol "" +-mon_decimal_point "." ++mon_decimal_point "" + mon_thousands_sep "" + mon_grouping -1 + positive_sign "" +-negative_sign "-" ++negative_sign "" + int_frac_digits -1 + frac_digits -1 + p_cs_precedes -1 +@@ -121,7 +121,9 @@ mon "January";"February";"March";"April";"May";"June";"July";/ + % + % ISO 8601 conforming applications should use the values 7, 19971201 (a + % Monday), and 4 (Thursday), respectively. +-week 7;19971201;4 ++% ++% This field is consciously aligned with the builtin C/POSIX locale. ++week 7;19971130;4 + first_weekday 1 + first_workday 2 + +@@ -129,7 +131,7 @@ first_workday 2 + d_t_fmt "%a %b %e %H:%M:%S %Y" + + % Appropriate date representation (%x) +-d_fmt "%m/%d/%y" ++d_fmt "%m//%d//%y" + + % Appropriate time representation (%X) + t_fmt "%H:%M:%S" +@@ -150,8 +152,8 @@ LC_MESSAGES + % + yesexpr "^[yY]" + noexpr "^[nN]" +-yesstr "Yes" +-nostr "No" ++yesstr "" ++nostr "" + END LC_MESSAGES + + LC_PAPER +@@ -175,6 +177,10 @@ LC_ADDRESS + % the LC_ADDRESS category. + % (also used in the built in C/POSIX locale in glibc/locale/C-address.c) + postal_fmt "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" ++% The abbreviated 2 char and 3 char should be set to empty strings to ++% match the C/POSIX locale. ++country_ab2 "" ++country_ab3 "" + END LC_ADDRESS + + LC_TELEPHONE +diff --git a/localedata/tst-c-utf8-consistency.c b/localedata/tst-c-utf8-consistency.c +new file mode 100644 +index 0000000000000000..50feed3090df0ff1 +--- /dev/null ++++ b/localedata/tst-c-utf8-consistency.c +@@ -0,0 +1,539 @@ ++/* Test that C/POSIX and C.UTF-8 are consistent. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Initialized by do_test using newlocale. */ ++static locale_t c_utf8; ++ ++/* Set to true for second pass. */ ++static bool use_nl_langinfo_l; ++ ++static void ++switch_to_c (void) ++{ ++ if (setlocale (LC_ALL, "C") == NULL) ++ FAIL_EXIT1 ("setlocale (LC_ALL, \"C\")"); ++} ++ ++static void ++switch_to_c_utf8 (void) ++{ ++ if (setlocale (LC_ALL, "C.UTF-8") == NULL) ++ FAIL_EXIT1 ("setlocale (LC_ALL, \"C.UTF-8\")"); ++} ++ ++static char * ++str (nl_item item) ++{ ++ if (!use_nl_langinfo_l) ++ switch_to_c (); ++ return nl_langinfo (item); ++} ++ ++static char * ++str_utf8 (nl_item item) ++{ ++ if (use_nl_langinfo_l) ++ return nl_langinfo_l (item, c_utf8); ++ else ++ { ++ switch_to_c_utf8 (); ++ return nl_langinfo (item); ++ } ++} ++ ++static wchar_t * ++wstr (nl_item item) ++{ ++ return (wchar_t *) str (item); ++} ++ ++static wchar_t * ++wstr_utf8 (nl_item item) ++{ ++ return (wchar_t *) str_utf8 (item); ++} ++ ++static int ++byte (nl_item item) ++{ ++ return (signed char) *str (item); ++} ++ ++static int ++byte_utf8 (nl_item item) ++{ ++ return (signed char) *str_utf8 (item); ++} ++ ++static int ++word (nl_item item) ++{ ++ union ++ { ++ char *ptr; ++ int word; ++ } u; ++ u.ptr = str (item); ++ return u.word; ++} ++ ++static int ++word_utf8 (nl_item item) ++{ ++ union ++ { ++ char *ptr; ++ int word; ++ } u; ++ u.ptr = str_utf8 (item); ++ return u.word; ++} ++ ++static void ++one_pass (void) ++{ ++ /* LC_TIME. */ ++ TEST_COMPARE_STRING (str (ABDAY_1), str_utf8 (ABDAY_1)); ++ TEST_COMPARE_STRING (str (ABDAY_2), str_utf8 (ABDAY_2)); ++ TEST_COMPARE_STRING (str (ABDAY_3), str_utf8 (ABDAY_3)); ++ TEST_COMPARE_STRING (str (ABDAY_4), str_utf8 (ABDAY_4)); ++ TEST_COMPARE_STRING (str (ABDAY_5), str_utf8 (ABDAY_5)); ++ TEST_COMPARE_STRING (str (ABDAY_6), str_utf8 (ABDAY_6)); ++ TEST_COMPARE_STRING (str (ABDAY_7), str_utf8 (ABDAY_7)); ++ ++ TEST_COMPARE_STRING (str (DAY_1), str_utf8 (DAY_1)); ++ TEST_COMPARE_STRING (str (DAY_2), str_utf8 (DAY_2)); ++ TEST_COMPARE_STRING (str (DAY_3), str_utf8 (DAY_3)); ++ TEST_COMPARE_STRING (str (DAY_4), str_utf8 (DAY_4)); ++ TEST_COMPARE_STRING (str (DAY_5), str_utf8 (DAY_5)); ++ TEST_COMPARE_STRING (str (DAY_6), str_utf8 (DAY_6)); ++ TEST_COMPARE_STRING (str (DAY_7), str_utf8 (DAY_7)); ++ ++ TEST_COMPARE_STRING (str (ABMON_1), str_utf8 (ABMON_1)); ++ TEST_COMPARE_STRING (str (ABMON_2), str_utf8 (ABMON_2)); ++ TEST_COMPARE_STRING (str (ABMON_3), str_utf8 (ABMON_3)); ++ TEST_COMPARE_STRING (str (ABMON_4), str_utf8 (ABMON_4)); ++ TEST_COMPARE_STRING (str (ABMON_5), str_utf8 (ABMON_5)); ++ TEST_COMPARE_STRING (str (ABMON_6), str_utf8 (ABMON_6)); ++ TEST_COMPARE_STRING (str (ABMON_7), str_utf8 (ABMON_7)); ++ TEST_COMPARE_STRING (str (ABMON_8), str_utf8 (ABMON_8)); ++ TEST_COMPARE_STRING (str (ABMON_9), str_utf8 (ABMON_9)); ++ TEST_COMPARE_STRING (str (ABMON_10), str_utf8 (ABMON_10)); ++ TEST_COMPARE_STRING (str (ABMON_11), str_utf8 (ABMON_11)); ++ TEST_COMPARE_STRING (str (ABMON_12), str_utf8 (ABMON_12)); ++ ++ TEST_COMPARE_STRING (str (MON_1), str_utf8 (MON_1)); ++ TEST_COMPARE_STRING (str (MON_2), str_utf8 (MON_2)); ++ TEST_COMPARE_STRING (str (MON_3), str_utf8 (MON_3)); ++ TEST_COMPARE_STRING (str (MON_4), str_utf8 (MON_4)); ++ TEST_COMPARE_STRING (str (MON_5), str_utf8 (MON_5)); ++ TEST_COMPARE_STRING (str (MON_6), str_utf8 (MON_6)); ++ TEST_COMPARE_STRING (str (MON_7), str_utf8 (MON_7)); ++ TEST_COMPARE_STRING (str (MON_8), str_utf8 (MON_8)); ++ TEST_COMPARE_STRING (str (MON_9), str_utf8 (MON_9)); ++ TEST_COMPARE_STRING (str (MON_10), str_utf8 (MON_10)); ++ TEST_COMPARE_STRING (str (MON_11), str_utf8 (MON_11)); ++ TEST_COMPARE_STRING (str (MON_12), str_utf8 (MON_12)); ++ ++ TEST_COMPARE_STRING (str (AM_STR), str_utf8 (AM_STR)); ++ TEST_COMPARE_STRING (str (PM_STR), str_utf8 (PM_STR)); ++ ++ TEST_COMPARE_STRING (str (D_T_FMT), str_utf8 (D_T_FMT)); ++ TEST_COMPARE_STRING (str (D_FMT), str_utf8 (D_FMT)); ++ TEST_COMPARE_STRING (str (T_FMT), str_utf8 (T_FMT)); ++ TEST_COMPARE_STRING (str (T_FMT_AMPM), ++ str_utf8 (T_FMT_AMPM)); ++ ++ TEST_COMPARE_STRING (str (ERA), str_utf8 (ERA)); ++ TEST_COMPARE_STRING (str (ERA_YEAR), str_utf8 (ERA_YEAR)); ++ TEST_COMPARE_STRING (str (ERA_D_FMT), str_utf8 (ERA_D_FMT)); ++ TEST_COMPARE_STRING (str (ALT_DIGITS), str_utf8 (ALT_DIGITS)); ++ TEST_COMPARE_STRING (str (ERA_D_T_FMT), str_utf8 (ERA_D_T_FMT)); ++ TEST_COMPARE_STRING (str (ERA_T_FMT), str_utf8 (ERA_T_FMT)); ++ TEST_COMPARE (word (_NL_TIME_ERA_NUM_ENTRIES), ++ word_utf8 (_NL_TIME_ERA_NUM_ENTRIES)); ++ /* No array elements, so nothing to compare for _NL_TIME_ERA_ENTRIES. */ ++ TEST_COMPARE (word (_NL_TIME_ERA_NUM_ENTRIES), 0); ++ ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_1), wstr_utf8 (_NL_WABDAY_1)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_2), wstr_utf8 (_NL_WABDAY_2)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_3), wstr_utf8 (_NL_WABDAY_3)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_4), wstr_utf8 (_NL_WABDAY_4)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_5), wstr_utf8 (_NL_WABDAY_5)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_6), wstr_utf8 (_NL_WABDAY_6)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_7), wstr_utf8 (_NL_WABDAY_7)); ++ ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_1), wstr_utf8 (_NL_WDAY_1)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_2), wstr_utf8 (_NL_WDAY_2)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_3), wstr_utf8 (_NL_WDAY_3)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_4), wstr_utf8 (_NL_WDAY_4)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_5), wstr_utf8 (_NL_WDAY_5)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_6), wstr_utf8 (_NL_WDAY_6)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_7), wstr_utf8 (_NL_WDAY_7)); ++ ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_1), wstr_utf8 (_NL_WABMON_1)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_2), wstr_utf8 (_NL_WABMON_2)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_3), wstr_utf8 (_NL_WABMON_3)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_4), wstr_utf8 (_NL_WABMON_4)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_5), wstr_utf8 (_NL_WABMON_5)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_6), wstr_utf8 (_NL_WABMON_6)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_7), wstr_utf8 (_NL_WABMON_7)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_8), wstr_utf8 (_NL_WABMON_8)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_9), wstr_utf8 (_NL_WABMON_9)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_10), wstr_utf8 (_NL_WABMON_10)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_11), wstr_utf8 (_NL_WABMON_11)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_12), wstr_utf8 (_NL_WABMON_12)); ++ ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_1), wstr_utf8 (_NL_WMON_1)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_2), wstr_utf8 (_NL_WMON_2)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_3), wstr_utf8 (_NL_WMON_3)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_4), wstr_utf8 (_NL_WMON_4)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_5), wstr_utf8 (_NL_WMON_5)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_6), wstr_utf8 (_NL_WMON_6)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_7), wstr_utf8 (_NL_WMON_7)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_8), wstr_utf8 (_NL_WMON_8)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_9), wstr_utf8 (_NL_WMON_9)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_10), wstr_utf8 (_NL_WMON_10)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_11), wstr_utf8 (_NL_WMON_11)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_12), wstr_utf8 (_NL_WMON_12)); ++ ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WAM_STR), wstr_utf8 (_NL_WAM_STR)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WPM_STR), wstr_utf8 (_NL_WPM_STR)); ++ ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WD_T_FMT), wstr_utf8 (_NL_WD_T_FMT)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WD_FMT), wstr_utf8 (_NL_WD_FMT)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WT_FMT), wstr_utf8 (_NL_WT_FMT)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WT_FMT_AMPM), ++ wstr_utf8 (_NL_WT_FMT_AMPM)); ++ ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_YEAR), wstr_utf8 (_NL_WERA_YEAR)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_D_FMT), wstr_utf8 (_NL_WERA_D_FMT)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALT_DIGITS), ++ wstr_utf8 (_NL_WALT_DIGITS)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_D_T_FMT), ++ wstr_utf8 (_NL_WERA_D_T_FMT)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_T_FMT), wstr_utf8 (_NL_WERA_T_FMT)); ++ ++ /* This is somewhat inconsistent, but see locale/categories.def. */ ++ TEST_COMPARE (byte (_NL_TIME_WEEK_NDAYS), byte_utf8 (_NL_TIME_WEEK_NDAYS)); ++ TEST_COMPARE (word (_NL_TIME_WEEK_1STDAY), ++ word_utf8 (_NL_TIME_WEEK_1STDAY)); ++ TEST_COMPARE (byte (_NL_TIME_WEEK_1STWEEK), ++ byte_utf8 (_NL_TIME_WEEK_1STWEEK)); ++ TEST_COMPARE (byte (_NL_TIME_FIRST_WEEKDAY), ++ byte_utf8 (_NL_TIME_FIRST_WEEKDAY)); ++ TEST_COMPARE (byte (_NL_TIME_FIRST_WORKDAY), ++ byte_utf8 (_NL_TIME_FIRST_WORKDAY)); ++ TEST_COMPARE (byte (_NL_TIME_CAL_DIRECTION), ++ byte_utf8 (_NL_TIME_CAL_DIRECTION)); ++ TEST_COMPARE_STRING (str (_NL_TIME_TIMEZONE), str_utf8 (_NL_TIME_TIMEZONE)); ++ ++ TEST_COMPARE_STRING (str (_DATE_FMT), str_utf8 (_DATE_FMT)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_W_DATE_FMT), wstr_utf8 (_NL_W_DATE_FMT)); ++ ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_TIME_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_TIME_CODESET), "UTF-8"); ++ ++ TEST_COMPARE_STRING (str (ALTMON_1), str_utf8 (ALTMON_1)); ++ TEST_COMPARE_STRING (str (ALTMON_2), str_utf8 (ALTMON_2)); ++ TEST_COMPARE_STRING (str (ALTMON_3), str_utf8 (ALTMON_3)); ++ TEST_COMPARE_STRING (str (ALTMON_4), str_utf8 (ALTMON_4)); ++ TEST_COMPARE_STRING (str (ALTMON_5), str_utf8 (ALTMON_5)); ++ TEST_COMPARE_STRING (str (ALTMON_6), str_utf8 (ALTMON_6)); ++ TEST_COMPARE_STRING (str (ALTMON_7), str_utf8 (ALTMON_7)); ++ TEST_COMPARE_STRING (str (ALTMON_8), str_utf8 (ALTMON_8)); ++ TEST_COMPARE_STRING (str (ALTMON_9), str_utf8 (ALTMON_9)); ++ TEST_COMPARE_STRING (str (ALTMON_10), str_utf8 (ALTMON_10)); ++ TEST_COMPARE_STRING (str (ALTMON_11), str_utf8 (ALTMON_11)); ++ TEST_COMPARE_STRING (str (ALTMON_12), str_utf8 (ALTMON_12)); ++ ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_1), wstr_utf8 (_NL_WALTMON_1)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_2), wstr_utf8 (_NL_WALTMON_2)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_3), wstr_utf8 (_NL_WALTMON_3)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_4), wstr_utf8 (_NL_WALTMON_4)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_5), wstr_utf8 (_NL_WALTMON_5)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_6), wstr_utf8 (_NL_WALTMON_6)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_7), wstr_utf8 (_NL_WALTMON_7)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_8), wstr_utf8 (_NL_WALTMON_8)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_9), wstr_utf8 (_NL_WALTMON_9)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_10), wstr_utf8 (_NL_WALTMON_10)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_11), wstr_utf8 (_NL_WALTMON_11)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_12), wstr_utf8 (_NL_WALTMON_12)); ++ ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_1), str_utf8 (_NL_ABALTMON_1)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_2), str_utf8 (_NL_ABALTMON_2)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_3), str_utf8 (_NL_ABALTMON_3)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_4), str_utf8 (_NL_ABALTMON_4)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_5), str_utf8 (_NL_ABALTMON_5)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_6), str_utf8 (_NL_ABALTMON_6)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_7), str_utf8 (_NL_ABALTMON_7)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_8), str_utf8 (_NL_ABALTMON_8)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_9), str_utf8 (_NL_ABALTMON_9)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_10), str_utf8 (_NL_ABALTMON_10)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_11), str_utf8 (_NL_ABALTMON_11)); ++ TEST_COMPARE_STRING (str (_NL_ABALTMON_12), str_utf8 (_NL_ABALTMON_12)); ++ ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_1), ++ wstr_utf8 (_NL_WABALTMON_1)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_2), ++ wstr_utf8 (_NL_WABALTMON_2)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_3), ++ wstr_utf8 (_NL_WABALTMON_3)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_4), ++ wstr_utf8 (_NL_WABALTMON_4)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_5), ++ wstr_utf8 (_NL_WABALTMON_5)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_6), ++ wstr_utf8 (_NL_WABALTMON_6)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_7), ++ wstr_utf8 (_NL_WABALTMON_7)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_8), ++ wstr_utf8 (_NL_WABALTMON_8)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_9), ++ wstr_utf8 (_NL_WABALTMON_9)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_10), ++ wstr_utf8 (_NL_WABALTMON_10)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_11), ++ wstr_utf8 (_NL_WABALTMON_11)); ++ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_12), ++ wstr_utf8 (_NL_WABALTMON_12)); ++ ++ /* LC_COLLATE. Mostly untested, only expected differences. */ ++ TEST_COMPARE_STRING (str (_NL_COLLATE_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_COLLATE_CODESET), "UTF-8"); ++ ++ /* LC_CTYPE. Mostly untested, only expected differences. */ ++ TEST_COMPARE_STRING (str (CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (CODESET), "UTF-8"); ++ ++ /* LC_MONETARY. */ ++ TEST_COMPARE_STRING (str (INT_CURR_SYMBOL), str_utf8 (INT_CURR_SYMBOL)); ++ TEST_COMPARE_STRING (str (CURRENCY_SYMBOL), str_utf8 (CURRENCY_SYMBOL)); ++ TEST_COMPARE_STRING (str (MON_DECIMAL_POINT), str_utf8 (MON_DECIMAL_POINT)); ++ TEST_COMPARE_STRING (str (MON_THOUSANDS_SEP), str_utf8 (MON_THOUSANDS_SEP)); ++ TEST_COMPARE_STRING (str (MON_GROUPING), str_utf8 (MON_GROUPING)); ++ TEST_COMPARE_STRING (str (POSITIVE_SIGN), str_utf8 (POSITIVE_SIGN)); ++ TEST_COMPARE_STRING (str (NEGATIVE_SIGN), str_utf8 (NEGATIVE_SIGN)); ++ TEST_COMPARE (byte (INT_FRAC_DIGITS), byte_utf8 (INT_FRAC_DIGITS)); ++ TEST_COMPARE (byte (FRAC_DIGITS), byte_utf8 (FRAC_DIGITS)); ++ TEST_COMPARE (byte (P_CS_PRECEDES), byte_utf8 (P_CS_PRECEDES)); ++ TEST_COMPARE (byte (P_SEP_BY_SPACE), byte_utf8 (P_SEP_BY_SPACE)); ++ TEST_COMPARE (byte (N_CS_PRECEDES), byte_utf8 (N_CS_PRECEDES)); ++ TEST_COMPARE (byte (N_SEP_BY_SPACE), byte_utf8 (N_SEP_BY_SPACE)); ++ TEST_COMPARE (byte (P_SIGN_POSN), byte_utf8 (P_SIGN_POSN)); ++ TEST_COMPARE (byte (N_SIGN_POSN), byte_utf8 (N_SIGN_POSN)); ++ TEST_COMPARE_STRING (str (CRNCYSTR), str_utf8 (CRNCYSTR)); ++ TEST_COMPARE (byte (INT_P_CS_PRECEDES), byte_utf8 (INT_P_CS_PRECEDES)); ++ TEST_COMPARE (byte (INT_P_SEP_BY_SPACE), byte_utf8 (INT_P_SEP_BY_SPACE)); ++ TEST_COMPARE (byte (INT_N_CS_PRECEDES), byte_utf8 (INT_N_CS_PRECEDES)); ++ TEST_COMPARE (byte (INT_N_SEP_BY_SPACE), byte_utf8 (INT_N_SEP_BY_SPACE)); ++ TEST_COMPARE (byte (INT_P_SIGN_POSN), byte_utf8 (INT_P_SIGN_POSN)); ++ TEST_COMPARE (byte (INT_N_SIGN_POSN), byte_utf8 (INT_N_SIGN_POSN)); ++ TEST_COMPARE_STRING (str (_NL_MONETARY_DUO_INT_CURR_SYMBOL), ++ str_utf8 (_NL_MONETARY_DUO_INT_CURR_SYMBOL)); ++ TEST_COMPARE_STRING (str (_NL_MONETARY_DUO_CURRENCY_SYMBOL), ++ str_utf8 (_NL_MONETARY_DUO_CURRENCY_SYMBOL)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_FRAC_DIGITS), ++ byte_utf8 (_NL_MONETARY_DUO_INT_FRAC_DIGITS)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_FRAC_DIGITS), ++ byte_utf8 (_NL_MONETARY_DUO_FRAC_DIGITS)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_P_CS_PRECEDES), ++ byte_utf8 (_NL_MONETARY_DUO_P_CS_PRECEDES)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_P_SEP_BY_SPACE), ++ byte_utf8 (_NL_MONETARY_DUO_P_SEP_BY_SPACE)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_N_CS_PRECEDES), ++ byte_utf8 (_NL_MONETARY_DUO_N_CS_PRECEDES)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_N_SEP_BY_SPACE), ++ byte_utf8 (_NL_MONETARY_DUO_N_SEP_BY_SPACE)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_CS_PRECEDES), ++ byte_utf8 (_NL_MONETARY_DUO_INT_P_CS_PRECEDES)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_SEP_BY_SPACE), ++ byte_utf8 (_NL_MONETARY_DUO_INT_P_SEP_BY_SPACE)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_CS_PRECEDES), ++ byte_utf8 (_NL_MONETARY_DUO_INT_N_CS_PRECEDES)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_SEP_BY_SPACE), ++ byte_utf8 (_NL_MONETARY_DUO_INT_N_SEP_BY_SPACE)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_SIGN_POSN), ++ byte_utf8 (_NL_MONETARY_DUO_INT_P_SIGN_POSN)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_SIGN_POSN), ++ byte_utf8 (_NL_MONETARY_DUO_INT_N_SIGN_POSN)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_P_SIGN_POSN), ++ byte_utf8 (_NL_MONETARY_DUO_P_SIGN_POSN)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_N_SIGN_POSN), ++ byte_utf8 (_NL_MONETARY_DUO_N_SIGN_POSN)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_SIGN_POSN), ++ byte_utf8 (_NL_MONETARY_DUO_INT_P_SIGN_POSN)); ++ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_SIGN_POSN), ++ byte_utf8 (_NL_MONETARY_DUO_INT_N_SIGN_POSN)); ++ TEST_COMPARE (word (_NL_MONETARY_UNO_VALID_FROM), ++ word_utf8 (_NL_MONETARY_UNO_VALID_FROM)); ++ TEST_COMPARE (word (_NL_MONETARY_UNO_VALID_TO), ++ word_utf8 (_NL_MONETARY_UNO_VALID_TO)); ++ TEST_COMPARE (word (_NL_MONETARY_DUO_VALID_FROM), ++ word_utf8 (_NL_MONETARY_DUO_VALID_FROM)); ++ TEST_COMPARE (word (_NL_MONETARY_DUO_VALID_TO), ++ word_utf8 (_NL_MONETARY_DUO_VALID_TO)); ++ /* _NL_MONETARY_CONVERSION_RATE cannot be tested (word array). */ ++ TEST_COMPARE (word (_NL_MONETARY_DECIMAL_POINT_WC), ++ word_utf8 (_NL_MONETARY_DECIMAL_POINT_WC)); ++ TEST_COMPARE (word (_NL_MONETARY_THOUSANDS_SEP_WC), ++ word_utf8 (_NL_MONETARY_THOUSANDS_SEP_WC)); ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_MONETARY_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_MONETARY_CODESET), "UTF-8"); ++ ++ /* LC_NUMERIC. */ ++ ++ TEST_COMPARE_STRING (str (DECIMAL_POINT), str_utf8 (DECIMAL_POINT)); ++ TEST_COMPARE_STRING (str (RADIXCHAR), str_utf8 (RADIXCHAR)); ++ TEST_COMPARE_STRING (str (THOUSANDS_SEP), str_utf8 (THOUSANDS_SEP)); ++ TEST_COMPARE_STRING (str (THOUSEP), str_utf8 (THOUSEP)); ++ TEST_COMPARE_STRING (str (GROUPING), str_utf8 (GROUPING)); ++ TEST_COMPARE (word (_NL_NUMERIC_DECIMAL_POINT_WC), ++ word_utf8 (_NL_NUMERIC_DECIMAL_POINT_WC)); ++ TEST_COMPARE (word (_NL_NUMERIC_THOUSANDS_SEP_WC), ++ word_utf8 (_NL_NUMERIC_THOUSANDS_SEP_WC)); ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_NUMERIC_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_NUMERIC_CODESET), "UTF-8"); ++ ++ /* LC_MESSAGES. */ ++ ++ TEST_COMPARE_STRING (str (YESEXPR), str_utf8 (YESEXPR)); ++ TEST_COMPARE_STRING (str (NOEXPR), str_utf8 (NOEXPR)); ++ TEST_COMPARE_STRING (str (YESSTR), str_utf8 (YESSTR)); ++ TEST_COMPARE_STRING (str (NOSTR), str_utf8 (NOSTR)); ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_MESSAGES_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_MESSAGES_CODESET), "UTF-8"); ++ ++ /* LC_PAPER. */ ++ ++ TEST_COMPARE (word (_NL_PAPER_HEIGHT), word_utf8 (_NL_PAPER_HEIGHT)); ++ TEST_COMPARE (word (_NL_PAPER_WIDTH), word_utf8 (_NL_PAPER_WIDTH)); ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_PAPER_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_PAPER_CODESET), "UTF-8"); ++ ++ /* LC_NAME. */ ++ ++ TEST_COMPARE_STRING (str (_NL_NAME_NAME_FMT), ++ str_utf8 (_NL_NAME_NAME_FMT)); ++ TEST_COMPARE_STRING (str (_NL_NAME_NAME_GEN), ++ str_utf8 (_NL_NAME_NAME_GEN)); ++ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MR), ++ str_utf8 (_NL_NAME_NAME_MR)); ++ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MRS), ++ str_utf8 (_NL_NAME_NAME_MRS)); ++ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MISS), ++ str_utf8 (_NL_NAME_NAME_MISS)); ++ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MS), ++ str_utf8 (_NL_NAME_NAME_MS)); ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_NAME_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_NAME_CODESET), "UTF-8"); ++ ++ /* LC_ADDRESS. */ ++ ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_POSTAL_FMT), ++ str_utf8 (_NL_ADDRESS_POSTAL_FMT)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_NAME), ++ str_utf8 (_NL_ADDRESS_COUNTRY_NAME)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_POST), ++ str_utf8 (_NL_ADDRESS_COUNTRY_POST)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_AB2), ++ str_utf8 (_NL_ADDRESS_COUNTRY_AB2)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_AB3), ++ str_utf8 (_NL_ADDRESS_COUNTRY_AB3)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_CAR), ++ str_utf8 (_NL_ADDRESS_COUNTRY_CAR)); ++ TEST_COMPARE (word (_NL_ADDRESS_COUNTRY_NUM), ++ word_utf8 (_NL_ADDRESS_COUNTRY_NUM)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_ISBN), ++ str_utf8 (_NL_ADDRESS_COUNTRY_ISBN)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_NAME), ++ str_utf8 (_NL_ADDRESS_LANG_NAME)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_AB), ++ str_utf8 (_NL_ADDRESS_LANG_AB)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_TERM), ++ str_utf8 (_NL_ADDRESS_LANG_TERM)); ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_LIB), ++ str_utf8 (_NL_ADDRESS_LANG_LIB)); ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_ADDRESS_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_ADDRESS_CODESET), "UTF-8"); ++ ++ /* LC_TELEPHONE. */ ++ ++ TEST_COMPARE_STRING (str (_NL_TELEPHONE_TEL_INT_FMT), ++ str_utf8 (_NL_TELEPHONE_TEL_INT_FMT)); ++ TEST_COMPARE_STRING (str (_NL_TELEPHONE_TEL_DOM_FMT), ++ str_utf8 (_NL_TELEPHONE_TEL_DOM_FMT)); ++ TEST_COMPARE_STRING (str (_NL_TELEPHONE_INT_SELECT), ++ str_utf8 (_NL_TELEPHONE_INT_SELECT)); ++ TEST_COMPARE_STRING (str (_NL_TELEPHONE_INT_PREFIX), ++ str_utf8 (_NL_TELEPHONE_INT_PREFIX)); ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_TELEPHONE_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_TELEPHONE_CODESET), "UTF-8"); ++ ++ /* LC_MEASUREMENT. */ ++ ++ TEST_COMPARE (byte (_NL_MEASUREMENT_MEASUREMENT), ++ byte_utf8 (_NL_MEASUREMENT_MEASUREMENT)); ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_MEASUREMENT_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_MEASUREMENT_CODESET), "UTF-8"); ++ ++ /* LC_IDENTIFICATION is skipped since C.UTF-8 is distinct from C. */ ++ ++ /* _NL_IDENTIFICATION_CATEGORY cannot be tested because it is a ++ string array. */ ++ /* Expected difference. */ ++ TEST_COMPARE_STRING (str (_NL_IDENTIFICATION_CODESET), "ANSI_X3.4-1968"); ++ TEST_COMPARE_STRING (str_utf8 (_NL_IDENTIFICATION_CODESET), "UTF-8"); ++} ++ ++static int ++do_test (void) ++{ ++ puts ("info: using setlocale and nl_langinfo"); ++ one_pass (); ++ ++ puts ("info: using nl_langinfo_l"); ++ ++ c_utf8 = newlocale (LC_ALL_MASK, "C.UTF-8", (locale_t) 0); ++ TEST_VERIFY_EXIT (c_utf8 != (locale_t) 0); ++ ++ switch_to_c (); ++ use_nl_langinfo_l = true; ++ one_pass (); ++ ++ freelocale (c_utf8); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-cs-path.patch b/SOURCES/glibc-cs-path.patch new file mode 100644 index 0000000..40835d2 --- /dev/null +++ b/SOURCES/glibc-cs-path.patch @@ -0,0 +1,44 @@ +Short description: Adjust CS_PATH and the test container layout. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: not-needed + +In Fedora we should return only /usr/bin as CS_PATH because /bin is just +a symlink to /usr/bin after MoveToUsr transition (which glibc has not +really completed). + +We also create /{bin,lib,lib64,sbin} in the test container as symbolic +links. This brings the test container in line with Fedora's filesystem +layout and avoids some test failures. For example, because Fedora's +CS_PATH is /usr/bin, tst-vfork3 will try to execute /usr/bin/echo in the +container. Without this change the container installs `echo' in /bin +not /usr/bin, causing the test to fail. + +diff --git a/Makefile b/Makefile +index a49870d3d1e636a9..feb2599203b10098 100644 +--- a/Makefile ++++ b/Makefile +@@ -598,9 +598,13 @@ $(tests-container) $(addsuffix /tests,$(subdirs)) : \ + $(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 ++ # Set up symlinks to directories whose contents got moved to /usr ++ for moved in bin lib lib64 sbin; do \ ++ test -d $(objpfx)testroot.pristine/usr/$$moved || \ ++ mkdir -p $(objpfx)testroot.pristine/usr/$$moved ;\ ++ test -e $(objpfx)testroot.pristine/$$moved || \ ++ ln -s usr/$$moved $(objpfx)testroot.pristine/$$moved ;\ ++ done + # We need the compiled locale dir for localedef tests. + test -d $(objpfx)testroot.pristine/$(complocaledir) || \ + mkdir -p $(objpfx)testroot.pristine/$(complocaledir) +diff --git a/sysdeps/unix/confstr.h b/sysdeps/unix/confstr.h +index 15859c3b2759878e..9b63b7f8069866fd 100644 +--- a/sysdeps/unix/confstr.h ++++ b/sysdeps/unix/confstr.h +@@ -1 +1 @@ +-#define CS_PATH "/bin:/usr/bin" ++#define CS_PATH "/usr/bin" diff --git a/SOURCES/glibc-deprecated-selinux-makedb.patch b/SOURCES/glibc-deprecated-selinux-makedb.patch new file mode 100644 index 0000000..c762d02 --- /dev/null +++ b/SOURCES/glibc-deprecated-selinux-makedb.patch @@ -0,0 +1,20 @@ +This is necessary to get things building again after libselinux changes. +A proper fix is under discussion upstream: + + + +diff --git a/nss/makedb.c b/nss/makedb.c +index 8e389a1683747cf1..9d81aed57d384a22 100644 +--- a/nss/makedb.c ++++ b/nss/makedb.c +@@ -17,6 +17,10 @@ + License along with the GNU C Library; if not, see + . */ + ++/* This file uses deprecated declarations from libselinux. */ ++#include ++DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations"); ++ + #include + #include + #include diff --git a/SOURCES/glibc-deprecated-selinux-nscd.patch b/SOURCES/glibc-deprecated-selinux-nscd.patch new file mode 100644 index 0000000..315b6cd --- /dev/null +++ b/SOURCES/glibc-deprecated-selinux-nscd.patch @@ -0,0 +1,17 @@ +This patch works around deprecated libselinux features used by nscd. + +diff --git a/nscd/selinux.c b/nscd/selinux.c +index a4ea8008e201b939..0acca4639202a75a 100644 +--- a/nscd/selinux.c ++++ b/nscd/selinux.c +@@ -17,6 +17,10 @@ + License along with the GNU C Library; if not, see + . */ + ++/* This file uses deprecated declarations from libselinux. */ ++#include ++DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations"); ++ + #include "config.h" + #include + #include 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-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-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-nsswitch.patch b/SOURCES/glibc-fedora-nsswitch.patch new file mode 100644 index 0000000..61f0311 --- /dev/null +++ b/SOURCES/glibc-fedora-nsswitch.patch @@ -0,0 +1,46 @@ +The Fedora /etc/nsswitch.conf is based largely on the upstream +version with minor downstream distribution modifications for +use with SSSD and systemd. + +diff --git a/nss/nsswitch.conf b/nss/nsswitch.conf +index 4a6bcb1f7bc0b1f4..980a68e32e6a04b8 100644 +--- a/nss/nsswitch.conf ++++ b/nss/nsswitch.conf +@@ -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,19 +52,21 @@ + # 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 ++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 + # Allow initgroups to default to the setting for group. + # initgroups: files +-netgroup: files + networks: files dns +-passwd: files + protocols: files + publickey: files + rpc: files +-shadow: files +-services: files 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..aaf45cc --- /dev/null +++ b/SOURCES/glibc-python3.patch @@ -0,0 +1,30 @@ +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 6fcbd0803808e5ca..d43db393d63433bc 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-2021 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 a799b4e1b7dc6f30..3286e267168e83bf 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-2021 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-rh1988382.patch b/SOURCES/glibc-rh1988382.patch new file mode 100644 index 0000000..37c3774 --- /dev/null +++ b/SOURCES/glibc-rh1988382.patch @@ -0,0 +1,619 @@ +commit 23645707f12f2dd9d80b51effb2d9618a7b65565 +Author: Siddhesh Poyarekar +Date: Wed Dec 8 11:21:26 2021 +0530 + + Replace --enable-static-pie with --disable-default-pie + + Build glibc programs and tests as PIE by default and enable static-pie + automatically if the architecture and toolchain supports it. + + Also add a new configuration option --disable-default-pie to prevent + building programs as PIE. + + Only the following architectures now have PIE disabled by default + because they do not work at the moment. hppa, ia64, alpha and csky + don't work because the linker is unable to handle a pcrel relocation + generated from PIE objects. The microblaze compiler is currently + failing with an ICE. GNU hurd tries to enable static-pie, which does + not work and hence fails. All these targets have default PIE disabled + at the moment and I have left it to the target maintainers to enable PIE + on their targets. + + build-many-glibcs runs clean for all targets. I also tested x86_64 on + Fedora and Ubuntu, to verify that the default build as well as + --disable-default-pie work as expected with both system toolchains. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + +diff --git a/INSTALL b/INSTALL +index 02dcf6b1ca3a4c43..d6d93ec9be4262d7 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -111,16 +111,14 @@ if 'CFLAGS' is specified it must enable optimization. For example: + systems support shared libraries; you need ELF support and + (currently) the GNU linker. + +-'--enable-static-pie' +- Enable static position independent executable (static PIE) support. +- Static PIE is similar to static executable, but can be loaded at +- any address without help from a dynamic linker. All static +- programs as well as static tests are built as static PIE, except +- for those marked with no-pie. The resulting glibc can be used with +- the GCC option, -static-pie, which is available with GCC 8 or +- above, to create static PIE. This option also implies that glibc +- programs and tests are created as dynamic position independent +- executables (PIE) by default. ++'--disable-default-pie' ++ Don't build glibc programs and the testsuite as position ++ independent executables (PIE). By default, glibc programs and tests ++ are created as position independent executables on targets that ++ support it. If the toolchain and architecture support it, static ++ executables are built as static PIE and the resulting glibc can be ++ used with the GCC option, -static-pie, which is available with GCC ++ 8 or above, to create static PIE. + + '--enable-cet' + '--enable-cet=permissive' +diff --git a/Makeconfig b/Makeconfig +index 2fa0884b4eee5e53..8bc5540292c7b6fa 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -1,4 +1,5 @@ + # Copyright (C) 1991-2021 Free Software Foundation, Inc. ++# Copyright (C) The GNU Toolchain Authors. + # This file is part of the GNU C Library. + + # The GNU C Library is free software; you can redistribute it and/or +@@ -376,19 +377,24 @@ LDFLAGS.so += $(hashstyle-LDFLAGS) + LDFLAGS-rtld += $(hashstyle-LDFLAGS) + endif + +-ifeq (yes,$(enable-static-pie)) ++ifeq (no,$(build-pie-default)) ++pie-default = $(no-pie-ccflag) ++else # build-pie-default + pic-default = -DPIC + # Compile libc.a and libc_p.a with -fPIE/-fpie for static PIE. + pie-default = $(pie-ccflag) ++ ++ifeq (yes,$(enable-static-pie)) + ifeq (yes,$(have-static-pie)) +-default-pie-ldflag = -static-pie ++static-pie-ldflag = -static-pie + else + # Static PIE can't have dynamic relocations in read-only segments since + # static PIE is mapped into memory by kernel. --eh-frame-hdr is needed + # for PIE to support exception. +-default-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text +-endif +-endif ++static-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text ++endif # have-static-pie ++endif # enable-static-pie ++endif # build-pie-default + + # If lazy relocations are disabled, add the -z now flag. Use + # LDFLAGS-lib.so instead of LDFLAGS.so, to avoid adding the flag to +@@ -444,7 +450,7 @@ endif + # Command for statically linking programs with the C library. + ifndef +link-static + +link-static-before-inputs = -nostdlib -nostartfiles -static \ +- $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \ ++ $(if $($(@F)-no-pie),$(no-pie-ldflag),$(static-pie-ldflag)) \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \ + $(+preinit) $(+prectorT) +@@ -479,7 +485,7 @@ ifeq (yes,$(build-pie-default)) + +link-tests-after-inputs = $(link-libc-tests) $(+link-pie-after-libc) + +link-printers-tests = $(+link-pie-printers-tests) + else # not build-pie-default +-+link-before-inputs = -nostdlib -nostartfiles \ +++link-before-inputs = -nostdlib -nostartfiles $(no-pie-ldflag) \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \ +@@ -1047,6 +1053,7 @@ PIC-ccflag = -fPIC + endif + # This can be changed by a sysdep makefile + pie-ccflag = -fpie ++no-pie-ccflag = -fno-pie + # This one should always stay like this unless there is a very good reason. + PIE-ccflag = -fPIE + ifeq (yes,$(build-profile)) +diff --git a/config.h.in b/config.h.in +index 8b45a3a61d774714..458342887e4e9380 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -277,6 +277,9 @@ + /* Build glibc with tunables support. */ + #define HAVE_TUNABLES 0 + ++/* Define if PIE is unsupported. */ ++#undef PIE_UNSUPPORTED ++ + /* Define if static PIE is supported. */ + #undef SUPPORT_STATIC_PIE + +diff --git a/config.make.in b/config.make.in +index cbf59114b0b9ae4f..e8630a8d0ccf874d 100644 +--- a/config.make.in ++++ b/config.make.in +@@ -90,9 +90,6 @@ static-nss-crypt = @libc_cv_static_nss_crypt@ + + # Configuration options. + build-shared = @shared@ +-build-pic-default= @libc_cv_pic_default@ +-build-pie-default= @libc_cv_pie_default@ +-cc-pie-default= @libc_cv_cc_pie_default@ + build-profile = @profile@ + build-static-nss = @static_nss@ + cross-compiling = @cross_compiling@ +diff --git a/configure b/configure +index 9619c10991d04362..e9d2b1f398c4dba0 100755 +--- a/configure ++++ b/configure +@@ -596,9 +596,6 @@ DEFINES + static_nss + profile + libc_cv_multidir +-libc_cv_pie_default +-libc_cv_cc_pie_default +-libc_cv_pic_default + shared + static + ldd_rewrite_script +@@ -767,7 +764,7 @@ with_nonshared_cflags + enable_sanity_checks + enable_shared + enable_profile +-enable_static_pie ++enable_default_pie + enable_timezone_tools + enable_hardcoded_path_in_tests + enable_hidden_plt +@@ -1423,8 +1420,8 @@ Optional Features: + in special situations) [default=yes] + --enable-shared build shared library [default=yes if GNU ld] + --enable-profile build profiled library [default=no] +- --enable-static-pie enable static PIE support and use it in the +- testsuite [default=no] ++ --disable-default-pie Do not build glibc programs and the testsuite as PIE ++ [default=no] + --disable-timezone-tools + do not install timezone tools [default=install] + --enable-hardcoded-path-in-tests +@@ -3408,11 +3405,11 @@ else + profile=no + fi + +-# Check whether --enable-static-pie was given. +-if test "${enable_static_pie+set}" = set; then : +- enableval=$enable_static_pie; static_pie=$enableval ++# Check whether --enable-default-pie was given. ++if test "${enable_default_pie+set}" = set; then : ++ enableval=$enable_default_pie; default_pie=$enableval + else +- static_pie=no ++ default_pie=yes + fi + + # Check whether --enable-timezone-tools was given. +@@ -6912,7 +6909,8 @@ rm -f conftest.* + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_pic_default" >&5 + $as_echo "$libc_cv_pic_default" >&6; } +- ++config_vars="$config_vars ++build-pic-default = $libc_cv_pic_default" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fPIE is default" >&5 + $as_echo_n "checking whether -fPIE is default... " >&6; } +@@ -6932,17 +6930,37 @@ rm -f conftest.* + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_pie_default" >&5 + $as_echo "$libc_cv_cc_pie_default" >&6; } +-libc_cv_pie_default=$libc_cv_cc_pie_default +- +- +- +-# Set the `multidir' variable by grabbing the variable from the compiler. +-# We do it once and save the result in a generated makefile. +-libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` +- ++config_vars="$config_vars ++cc-pie-default = $libc_cv_cc_pie_default" + +-if test "$static_pie" = yes; then +- # Check target support for static PIE ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can build programs as PIE" >&5 ++$as_echo_n "checking if we can build programs as PIE... " >&6; } ++if test "x$default_pie" != xno; then ++ # Disable build-pie-default if target does not support it. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef PIE_UNSUPPORTED ++# error PIE is not supported ++#endif ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ libc_cv_pie_default=yes ++else ++ libc_cv_pie_default=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_pie_default" >&5 ++$as_echo "$libc_cv_pie_default" >&6; } ++config_vars="$config_vars ++build-pie-default = $libc_cv_pie_default" ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can build static PIE programs" >&5 ++$as_echo_n "checking if we can build static PIE programs... " >&6; } ++libc_cv_static_pie=$libc_cv_pie_default ++if test "x$libc_cv_pie_default" != xno \ ++ -a "$libc_cv_no_dynamic_linker" = yes; then ++ # Enable static-pie if available + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + #ifndef SUPPORT_STATIC_PIE +@@ -6950,22 +6968,25 @@ if test "$static_pie" = yes; then + #endif + _ACEOF + if ac_fn_c_try_compile "$LINENO"; then : +- ++ libc_cv_static_pie=yes + else +- as_fn_error $? "the architecture does not support static PIE" "$LINENO" 5 ++ libc_cv_static_pie=no + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- # The linker must support --no-dynamic-linker. +- if test "$libc_cv_no_dynamic_linker" != yes; then +- as_fn_error $? "linker support for --no-dynamic-linker needed" "$LINENO" 5 +- fi +- # Default to PIE. +- libc_cv_pie_default=yes +- $as_echo "#define ENABLE_STATIC_PIE 1" >>confdefs.h ++ if test "$libc_cv_static_pie" = "yes"; then ++ $as_echo "#define ENABLE_STATIC_PIE 1" >>confdefs.h + ++ fi + fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie" >&5 ++$as_echo "$libc_cv_static_pie" >&6; } + config_vars="$config_vars +-enable-static-pie = $static_pie" ++enable-static-pie = $libc_cv_static_pie" ++ ++# Set the `multidir' variable by grabbing the variable from the compiler. ++# We do it once and save the result in a generated makefile. ++libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` ++ + + + +diff --git a/configure.ac b/configure.ac +index 34ecbba540546337..79f6822d29ce21cf 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -179,11 +179,11 @@ AC_ARG_ENABLE([profile], + [build profiled library @<:@default=no@:>@]), + [profile=$enableval], + [profile=no]) +-AC_ARG_ENABLE([static-pie], +- AS_HELP_STRING([--enable-static-pie], +- [enable static PIE support and use it in the testsuite @<:@default=no@:>@]), +- [static_pie=$enableval], +- [static_pie=no]) ++AC_ARG_ENABLE([default-pie], ++ AS_HELP_STRING([--disable-default-pie], ++ [Do not build glibc programs and the testsuite as PIE @<:@default=no@:>@]), ++ [default_pie=$enableval], ++ [default_pie=yes]) + AC_ARG_ENABLE([timezone-tools], + AS_HELP_STRING([--disable-timezone-tools], + [do not install timezone tools @<:@default=install@:>@]), +@@ -1856,7 +1856,7 @@ if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then + libc_cv_pic_default=no + fi + rm -f conftest.*]) +-AC_SUBST(libc_cv_pic_default) ++LIBC_CONFIG_VAR([build-pic-default], [$libc_cv_pic_default]) + + AC_CACHE_CHECK([whether -fPIE is default], libc_cv_cc_pie_default, + [libc_cv_cc_pie_default=yes +@@ -1869,30 +1869,38 @@ if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then + libc_cv_cc_pie_default=no + fi + rm -f conftest.*]) +-libc_cv_pie_default=$libc_cv_cc_pie_default +-AC_SUBST(libc_cv_cc_pie_default) +-AC_SUBST(libc_cv_pie_default) ++LIBC_CONFIG_VAR([cc-pie-default], [$libc_cv_cc_pie_default]) ++ ++AC_MSG_CHECKING(if we can build programs as PIE) ++if test "x$default_pie" != xno; then ++ # Disable build-pie-default if target does not support it. ++ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifdef PIE_UNSUPPORTED ++# error PIE is not supported ++#endif]])], [libc_cv_pie_default=yes], [libc_cv_pie_default=no]) ++fi ++AC_MSG_RESULT($libc_cv_pie_default) ++LIBC_CONFIG_VAR([build-pie-default], [$libc_cv_pie_default]) ++ ++AC_MSG_CHECKING(if we can build static PIE programs) ++libc_cv_static_pie=$libc_cv_pie_default ++if test "x$libc_cv_pie_default" != xno \ ++ -a "$libc_cv_no_dynamic_linker" = yes; then ++ # Enable static-pie if available ++ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifndef SUPPORT_STATIC_PIE ++# error static PIE is not supported ++#endif]])], [libc_cv_static_pie=yes], [libc_cv_static_pie=no]) ++ if test "$libc_cv_static_pie" = "yes"; then ++ AC_DEFINE(ENABLE_STATIC_PIE) ++ fi ++fi ++AC_MSG_RESULT($libc_cv_static_pie) ++LIBC_CONFIG_VAR([enable-static-pie], [$libc_cv_static_pie]) + + # Set the `multidir' variable by grabbing the variable from the compiler. + # We do it once and save the result in a generated makefile. + libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` + AC_SUBST(libc_cv_multidir) + +-if test "$static_pie" = yes; then +- # Check target support for static PIE +- AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifndef SUPPORT_STATIC_PIE +-# error static PIE is not supported +-#endif]])], , AC_MSG_ERROR([the architecture does not support static PIE])) +- # The linker must support --no-dynamic-linker. +- if test "$libc_cv_no_dynamic_linker" != yes; then +- AC_MSG_ERROR([linker support for --no-dynamic-linker needed]) +- fi +- # Default to PIE. +- libc_cv_pie_default=yes +- AC_DEFINE(ENABLE_STATIC_PIE) +-fi +-LIBC_CONFIG_VAR([enable-static-pie], [$static_pie]) +- + AC_SUBST(profile) + AC_SUBST(static_nss) + +diff --git a/manual/install.texi b/manual/install.texi +index 46f73b538d3fee6f..1320ac69b3c645f2 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -141,15 +141,13 @@ Don't build shared libraries even if it is possible. Not all systems + support shared libraries; you need ELF support and (currently) the GNU + linker. + +-@item --enable-static-pie +-Enable static position independent executable (static PIE) support. +-Static PIE is similar to static executable, but can be loaded at any +-address without help from a dynamic linker. All static programs as +-well as static tests are built as static PIE, except for those marked +-with no-pie. The resulting glibc can be used with the GCC option, +--static-pie, which is available with GCC 8 or above, to create static +-PIE. This option also implies that glibc programs and tests are created +-as dynamic position independent executables (PIE) by default. ++@item --disable-default-pie ++Don't build glibc programs and the testsuite as position independent ++executables (PIE). By default, glibc programs and tests are created as ++position independent executables on targets that support it. If the toolchain ++and architecture support it, static executables are built as static PIE and the ++resulting glibc can be used with the GCC option, -static-pie, which is ++available with GCC 8 or above, to create static PIE. + + @item --enable-cet + @itemx --enable-cet=permissive +diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py +index 86537fa8005cfd3d..2fd82a5d054c51ca 100755 +--- a/scripts/build-many-glibcs.py ++++ b/scripts/build-many-glibcs.py +@@ -1,6 +1,7 @@ + #!/usr/bin/python3 + # Build many configurations of glibc. + # Copyright (C) 2016-2021 Free Software Foundation, Inc. ++# Copyright (C) The GNU Toolchain Authors. + # This file is part of the GNU C Library. + # + # The GNU C Library is free software; you can redistribute it and/or +@@ -435,15 +436,15 @@ class Context(object): + '--disable-experimental-malloc', + '--disable-build-nscd', + '--disable-nscd']}, +- {'variant': 'static-pie', +- 'cfg': ['--enable-static-pie']}, +- {'variant': 'x32-static-pie', ++ {'variant': 'no-pie', ++ 'cfg': ['--disable-default-pie']}, ++ {'variant': 'x32-no-pie', + 'ccopts': '-mx32', +- 'cfg': ['--enable-static-pie']}, +- {'variant': 'static-pie', ++ 'cfg': ['--disable-default-pie']}, ++ {'variant': 'no-pie', + 'arch': 'i686', + 'ccopts': '-m32 -march=i686', +- 'cfg': ['--enable-static-pie']}, ++ 'cfg': ['--disable-default-pie']}, + {'variant': 'disable-multi-arch', + 'arch': 'i686', + 'ccopts': '-m32 -march=i686', +diff --git a/sysdeps/alpha/configure b/sysdeps/alpha/configure +index 464b5965276dca19..3d665d96f2b40c4e 100644 +--- a/sysdeps/alpha/configure ++++ b/sysdeps/alpha/configure +@@ -5,4 +5,9 @@ + # symbols in a position independent way. + $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + ++ ++# PIE builds fail on binutils 2.37 and earlier, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28672 ++$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h ++ + # work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/alpha/configure.ac b/sysdeps/alpha/configure.ac +index 38e52e71ac2a5bc0..8f9a39ed2e4a29cb 100644 +--- a/sysdeps/alpha/configure.ac ++++ b/sysdeps/alpha/configure.ac +@@ -4,4 +4,8 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + # With required gcc+binutils, we can always access static and hidden + # symbols in a position independent way. + AC_DEFINE(PI_STATIC_AND_HIDDEN) ++ ++# PIE builds fail on binutils 2.37 and earlier, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28672 ++AC_DEFINE(PIE_UNSUPPORTED) + # work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/csky/configure b/sysdeps/csky/configure +index 19acb084fb43d9ea..27464eb707ebd6c6 100644 +--- a/sysdeps/csky/configure ++++ b/sysdeps/csky/configure +@@ -2,3 +2,10 @@ + # Local configure fragment for sysdeps/csky. + + $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h ++ ++ ++# PIE builds fail on binutils 2.37 and earlier, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28672 ++$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h ++ ++# work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/csky/configure.ac b/sysdeps/csky/configure.ac +index 5656b665da698d05..8e008249094d9e5a 100644 +--- a/sysdeps/csky/configure.ac ++++ b/sysdeps/csky/configure.ac +@@ -2,3 +2,8 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + # Local configure fragment for sysdeps/csky. + + AC_DEFINE(PI_STATIC_AND_HIDDEN) ++ ++# PIE builds fail on binutils 2.37 and earlier, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28672 ++AC_DEFINE(PIE_UNSUPPORTED) ++# work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/hppa/configure b/sysdeps/hppa/configure +index 2cfe6cbea14549d0..cf5acf966dad67ba 100644 +--- a/sysdeps/hppa/configure ++++ b/sysdeps/hppa/configure +@@ -30,3 +30,10 @@ $as_echo "$libc_cv_asm_line_sep" >&6; } + cat >>confdefs.h <<_ACEOF + #define ASM_LINE_SEP $libc_cv_asm_line_sep + _ACEOF ++ ++ ++# PIE builds fail on binutils 2.37 and earlier, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28672 ++$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h ++ ++# work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/hppa/configure.ac b/sysdeps/hppa/configure.ac +index 1ec417b9474c3382..3e1c35bbd992f548 100644 +--- a/sysdeps/hppa/configure.ac ++++ b/sysdeps/hppa/configure.ac +@@ -19,3 +19,8 @@ else + fi + rm -f conftest*]) + AC_DEFINE_UNQUOTED(ASM_LINE_SEP, $libc_cv_asm_line_sep) ++ ++# PIE builds fail on binutils 2.37 and earlier, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28672 ++AC_DEFINE(PIE_UNSUPPORTED) ++# work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/ia64/configure b/sysdeps/ia64/configure +index 1ef70921bc5266db..748cb526012adeb8 100644 +--- a/sysdeps/ia64/configure ++++ b/sysdeps/ia64/configure +@@ -3,4 +3,9 @@ + + $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + ++ ++# PIE builds fail on binutils 2.37 and earlier, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28672 ++$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h ++ + # work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/ia64/configure.ac b/sysdeps/ia64/configure.ac +index 3bae9fc5e1a3ff45..8e5fba32c3ec8bfc 100644 +--- a/sysdeps/ia64/configure.ac ++++ b/sysdeps/ia64/configure.ac +@@ -4,4 +4,8 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + dnl It is always possible to access static and hidden symbols in an + dnl position independent way. + AC_DEFINE(PI_STATIC_AND_HIDDEN) ++ ++# PIE builds fail on binutils 2.37 and earlier, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28672 ++AC_DEFINE(PIE_UNSUPPORTED) + # work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/mach/hurd/configure b/sysdeps/mach/hurd/configure +index 8d0702ad438d1c0a..3303e5dff8ef5ecf 100644 +--- a/sysdeps/mach/hurd/configure ++++ b/sysdeps/mach/hurd/configure +@@ -49,3 +49,9 @@ fi + + # Hurd has libpthread as a separate library. + pthread_in_libc=no ++ ++# Hurd build needs to be updated to support static pie, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28671 ++$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h ++ ++# work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/mach/hurd/configure.ac b/sysdeps/mach/hurd/configure.ac +index 82d085af33701aa2..022c2eff79fc0d08 100644 +--- a/sysdeps/mach/hurd/configure.ac ++++ b/sysdeps/mach/hurd/configure.ac +@@ -29,3 +29,8 @@ fi + + # Hurd has libpthread as a separate library. + pthread_in_libc=no ++ ++# Hurd build needs to be updated to support static pie, see: ++# https://sourceware.org/bugzilla/show_bug.cgi?id=28671 ++AC_DEFINE(PIE_UNSUPPORTED) ++# work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/microblaze/configure b/sysdeps/microblaze/configure +new file mode 100755 +index 0000000000000000..e6652562d212b688 +--- /dev/null ++++ b/sysdeps/microblaze/configure +@@ -0,0 +1,8 @@ ++# This file is generated from configure.ac by Autoconf. DO NOT EDIT! ++ # Local configure fragment for sysdeps/microblaze. ++ ++# gcc 11.2.1 and earlier crash with an internal compiler error, see: ++# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103613 ++$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h ++ ++# work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/microblaze/configure.ac b/sysdeps/microblaze/configure.ac +new file mode 100644 +index 0000000000000000..1c58f70a7bdfebcb +--- /dev/null ++++ b/sysdeps/microblaze/configure.ac +@@ -0,0 +1,7 @@ ++GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. ++# Local configure fragment for sysdeps/microblaze. ++ ++# gcc 11.2.1 and earlier crash with an internal compiler error, see: ++# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103613 ++AC_DEFINE(PIE_UNSUPPORTED) ++# work around problem with autoconf and empty lines at the end of files +diff --git a/sysdeps/sparc/Makefile b/sysdeps/sparc/Makefile +index 1be9a3db2ca12216..12c2c1b085fd4ae2 100644 +--- a/sysdeps/sparc/Makefile ++++ b/sysdeps/sparc/Makefile +@@ -2,6 +2,7 @@ + long-double-fcts = yes + + pie-ccflag = -fPIE ++no-pie-ccflag = -fno-PIE + + ifeq ($(subdir),gmon) + sysdep_routines += sparc-mcount diff --git a/SOURCES/glibc-rh2023422-1.patch b/SOURCES/glibc-rh2023422-1.patch new file mode 100644 index 0000000..c3ba08e --- /dev/null +++ b/SOURCES/glibc-rh2023422-1.patch @@ -0,0 +1,250 @@ +commit c1cb2deeca1a85c6fc5bd41b90816d48a95bc434 +Author: Florian Weimer +Date: Sun Dec 5 11:28:34 2021 +0100 + + elf: execve statically linked programs instead of crashing [BZ #28648] + + Programs without dynamic dependencies and without a program + interpreter are now run via execve. + + Previously, the dynamic linker either crashed while attempting to + read a non-existing dynamic segment (looking for DT_AUDIT/DT_DEPAUDIT + data), or the self-relocated in the static PIE executable crashed + because the outer dynamic linker had already applied RELRO protection. + + is needed because execve is not available in the + dynamic loader on Hurd. + + Reviewed-by: H.J. Lu + +Conflicts: + elf/Makefile + (usual test differences) + elf/rtld.c + (missing ld.so self-relocation cleanup downstream) + +diff --git a/elf/Makefile b/elf/Makefile +index 118d579c42c38110..7696aa1324919a80 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -224,7 +224,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-tls-ie tst-tls-ie-dlmopen argv0test \ + tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \ + tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \ +- tst-dl-is_dso tst-ro-dynamic ++ tst-dl-is_dso tst-ro-dynamic \ ++ tst-rtld-run-static \ + # reldep9 + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ +@@ -1914,3 +1915,5 @@ $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \ + $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \ + -Wl,--script=tst-ro-dynamic-mod.map \ + $(objpfx)tst-ro-dynamic-mod.os ++ ++$(objpfx)tst-rtld-run-static.out: $(objpfx)/ldconfig +diff --git a/elf/rtld.c b/elf/rtld.c +index d83ac1bdc40a6081..6b0d6107801b2f44 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + + #include + +@@ -1106,6 +1107,45 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list) + } + } + ++/* Check if the executable is not actualy dynamically linked, and ++ invoke it directly in that case. */ ++static void ++rtld_chain_load (struct link_map *main_map, char *argv0) ++{ ++ /* The dynamic loader run against itself. */ ++ const char *rtld_soname ++ = ((const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB]) ++ + GL(dl_rtld_map).l_info[DT_SONAME]->d_un.d_val); ++ if (main_map->l_info[DT_SONAME] != NULL ++ && strcmp (rtld_soname, ++ ((const char *) D_PTR (main_map, l_info[DT_STRTAB]) ++ + main_map->l_info[DT_SONAME]->d_un.d_val)) == 0) ++ _dl_fatal_printf ("%s: loader cannot load itself\n", rtld_soname); ++ ++ /* With DT_NEEDED dependencies, the executable is dynamically ++ linked. */ ++ if (__glibc_unlikely (main_map->l_info[DT_NEEDED] != NULL)) ++ return; ++ ++ /* If the executable has program interpreter, it is dynamically ++ linked. */ ++ for (size_t i = 0; i < main_map->l_phnum; ++i) ++ if (main_map->l_phdr[i].p_type == PT_INTERP) ++ return; ++ ++ const char *pathname = _dl_argv[0]; ++ if (argv0 != NULL) ++ _dl_argv[0] = argv0; ++ int errcode = __rtld_execve (pathname, _dl_argv, _environ); ++ const char *errname = strerrorname_np (errcode); ++ if (errname != NULL) ++ _dl_fatal_printf("%s: cannot execute %s: %s\n", ++ rtld_soname, pathname, errname); ++ else ++ _dl_fatal_printf("%s: cannot execute %s: %d\n", ++ rtld_soname, pathname, errno); ++} ++ + static void + dl_main (const ElfW(Phdr) *phdr, + ElfW(Word) phnum, +@@ -1374,14 +1414,8 @@ dl_main (const ElfW(Phdr) *phdr, + /* Now the map for the main executable is available. */ + main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; + +- if (__glibc_likely (state.mode == rtld_mode_normal) +- && GL(dl_rtld_map).l_info[DT_SONAME] != NULL +- && main_map->l_info[DT_SONAME] != NULL +- && strcmp ((const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB]) +- + GL(dl_rtld_map).l_info[DT_SONAME]->d_un.d_val, +- (const char *) D_PTR (main_map, l_info[DT_STRTAB]) +- + main_map->l_info[DT_SONAME]->d_un.d_val) == 0) +- _dl_fatal_printf ("loader cannot load itself\n"); ++ if (__glibc_likely (state.mode == rtld_mode_normal)) ++ rtld_chain_load (main_map, argv0); + + phdr = main_map->l_phdr; + phnum = main_map->l_phnum; +diff --git a/elf/tst-rtld-run-static.c b/elf/tst-rtld-run-static.c +new file mode 100644 +index 0000000000000000..7281093504b675c4 +--- /dev/null ++++ b/elf/tst-rtld-run-static.c +@@ -0,0 +1,62 @@ ++/* Test running statically linked programs using ld.so. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ char *ldconfig_path = xasprintf ("%s/elf/ldconfig", support_objdir_root); ++ ++ { ++ char *argv[] = { (char *) "ld.so", ldconfig_path, (char *) "--help", NULL }; ++ struct support_capture_subprocess cap ++ = support_capture_subprogram (support_objdir_elf_ldso, argv); ++ support_capture_subprocess_check (&cap, "no --argv0", 0, sc_allow_stdout); ++ puts ("info: output without --argv0:"); ++ puts (cap.out.buffer); ++ TEST_VERIFY (strstr (cap.out.buffer, "Usage: ldconfig [OPTION...]\n") ++ == cap.out.buffer); ++ support_capture_subprocess_free (&cap); ++ } ++ ++ { ++ char *argv[] = ++ { ++ (char *) "ld.so", (char *) "--argv0", (char *) "ldconfig-argv0", ++ ldconfig_path, (char *) "--help", NULL ++ }; ++ struct support_capture_subprocess cap ++ = support_capture_subprogram (support_objdir_elf_ldso, argv); ++ support_capture_subprocess_check (&cap, "with --argv0", 0, sc_allow_stdout); ++ puts ("info: output with --argv0:"); ++ puts (cap.out.buffer); ++ TEST_VERIFY (strstr (cap.out.buffer, "Usage: ldconfig-argv0 [OPTION...]\n") ++ == cap.out.buffer); ++ support_capture_subprocess_free (&cap); ++ } ++ ++ free (ldconfig_path); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/generic/dl-execve.h b/sysdeps/generic/dl-execve.h +new file mode 100644 +index 0000000000000000..5fd097df69e1770c +--- /dev/null ++++ b/sysdeps/generic/dl-execve.h +@@ -0,0 +1,25 @@ ++/* execve for the dynamic linker. Generic stub version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++static int ++__rtld_execve (const char *path, char *const *argv, char *const *envp) ++{ ++ return ENOSYS; ++} +diff --git a/sysdeps/unix/sysv/linux/dl-execve.h b/sysdeps/unix/sysv/linux/dl-execve.h +new file mode 100644 +index 0000000000000000..ead3e1c28da34363 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/dl-execve.h +@@ -0,0 +1,25 @@ ++/* execve for the dynamic linker. Linux version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++static inline int ++__rtld_execve (const char *path, char *const *argv, char *const *envp) ++{ ++ return -INTERNAL_SYSCALL_CALL (execve, path, argv, envp); ++} diff --git a/SOURCES/glibc-rh2023422-2.patch b/SOURCES/glibc-rh2023422-2.patch new file mode 100644 index 0000000..c6d87df --- /dev/null +++ b/SOURCES/glibc-rh2023422-2.patch @@ -0,0 +1,37 @@ +commit 2e75604f8337fa4332977f72a8f6726309679edf +Author: Florian Weimer +Date: Fri Dec 10 16:06:36 2021 +0100 + + elf: Install a symbolic link to ld.so as /usr/bin/ld.so + + This makes ld.so features such as --preload, --audit, + and --list-diagnostics more accessible to end users because they + do not need to know the ABI name of the dynamic loader. + + Reviewed-by: Carlos O'Donell + +diff --git a/elf/Makefile b/elf/Makefile +index 7696aa1324919a80..3e7debdd81baafe0 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -104,7 +104,7 @@ endif + ifeq (yes,$(build-shared)) + extra-objs = $(all-rtld-routines:%=%.os) sofini.os interp.os + generated += librtld.os dl-allobjs.os ld.so ldd +-install-others = $(inst_rtlddir)/$(rtld-installed-name) ++install-others = $(inst_rtlddir)/$(rtld-installed-name) $(inst_bindir)/ld.so + install-bin-script = ldd + endif + +@@ -645,6 +645,11 @@ $(inst_rtlddir)/$(rtld-installed-name): $(objpfx)ld.so $(+force) + $(make-target-directory) + $(do-install-program) + ++# Creates the relative /usr/bin/ld.so symbolic link. ++$(inst_bindir)/ld.so: $(inst_rtlddir)/$(rtld-installed-name) ++ $(make-target-directory) ++ $(make-link) ++ + # Special target called by parent to install just the dynamic linker. + .PHONY: ldso_install + ldso_install: $(inst_rtlddir)/$(rtld-installed-name) diff --git a/SOURCES/glibc-rh2023422-3.patch b/SOURCES/glibc-rh2023422-3.patch new file mode 100644 index 0000000..36f8949 --- /dev/null +++ b/SOURCES/glibc-rh2023422-3.patch @@ -0,0 +1,19 @@ +commit f1eeef945d49c72eb13654bd30b5904e89b4626f +Author: Florian Weimer +Date: Fri Dec 10 21:34:30 2021 +0100 + + elf: Use errcode instead of (unset) errno in rtld_chain_load + +diff --git a/elf/rtld.c b/elf/rtld.c +index 6b0d6107801b2f44..6bbb373c5743cb99 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1143,7 +1143,7 @@ rtld_chain_load (struct link_map *main_map, char *argv0) + rtld_soname, pathname, errname); + else + _dl_fatal_printf("%s: cannot execute %s: %d\n", +- rtld_soname, pathname, errno); ++ rtld_soname, pathname, errcode); + } + + static void diff --git a/SOURCES/glibc-rh2024347-1.patch b/SOURCES/glibc-rh2024347-1.patch new file mode 100644 index 0000000..1c18bfa --- /dev/null +++ b/SOURCES/glibc-rh2024347-1.patch @@ -0,0 +1,98 @@ +commit 84a7eb1f87c1d01b58ad887a0ab5d87abbc1c772 +Author: H.J. Lu +Date: Fri Jul 30 19:07:30 2021 -0700 + + Use __executable_start as the lowest address for profiling [BZ #28153] + + Glibc assumes that ENTRY_POINT is the lowest address for which we need + to keep profiling records and BFD linker uses a linker script to place + the input sections. + + Starting from GCC 4.6, the main function is placed in .text.startup + section and starting from binutils 2.22, BFD linker with + + commit add44f8d5c5c05e08b11e033127a744d61c26aee + Author: Alan Modra + Date: Thu Nov 25 03:03:02 2010 +0000 + + * scripttempl/elf.sc: Group .text.exit, text.startup and .text.hot + sections. + + places .text.startup section before .text section, which leave the main + function out of profiling records. + + Starting from binutils 2.15, linker provides __executable_start to mark + the lowest address of the executable. Use __executable_start as the + lowest address to keep the main function in profiling records. This fixes + [BZ #28153]. + + Tested on Linux/x86-64, Linux/x32 and Linux/i686 as well as with + build-many-glibcs.py. + +diff --git a/csu/gmon-start.c b/csu/gmon-start.c +index b3432885b39071cc..344606a676c188d4 100644 +--- a/csu/gmon-start.c ++++ b/csu/gmon-start.c +@@ -52,6 +52,11 @@ extern char ENTRY_POINT[]; + #endif + extern char etext[]; + ++/* Use __executable_start as the lowest address to keep profiling records ++ if it provided by the linker. */ ++extern const char executable_start[] asm ("__executable_start") ++ __attribute__ ((weak, visibility ("hidden"))); ++ + #ifndef TEXT_START + # ifdef ENTRY_POINT_DECL + # define TEXT_START ENTRY_POINT +@@ -92,7 +97,10 @@ __gmon_start__ (void) + called = 1; + + /* Start keeping profiling records. */ +- __monstartup ((u_long) TEXT_START, (u_long) &etext); ++ if (&executable_start != NULL) ++ __monstartup ((u_long) &executable_start, (u_long) &etext); ++ else ++ __monstartup ((u_long) TEXT_START, (u_long) &etext); + + /* Call _mcleanup before exiting; it will write out gmon.out from the + collected data. */ +diff --git a/gmon/tst-gmon-gprof.sh b/gmon/tst-gmon-gprof.sh +index 9d371582b99677fa..dc0be021104f725d 100644 +--- a/gmon/tst-gmon-gprof.sh ++++ b/gmon/tst-gmon-gprof.sh +@@ -39,12 +39,14 @@ trap cleanup 0 + cat > "$expected" < "$expected_dot" < "$expected" < "$expected_dot" < +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: rseq failure after registration on main thread is fatal + + This simplifies the application programming model. + + Browser sandboxes have already been fixed: + + Sandbox is incompatible with rseq registration + + + Allow rseq in the Linux sandboxes. r=gcp + + + Sandbox needs to support rseq system call + + + Linux sandbox: Allow rseq(2) + + + Reviewed-by: Szabolcs Nagy + +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index f405fa356c2955ce..109c5e3dc78c9aa2 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -371,7 +371,8 @@ start_thread (void *arg) + /* Register rseq TLS to the kernel. */ + { + bool do_rseq = THREAD_GETMEM (pd, flags) & ATTR_FLAG_DO_RSEQ; +- rseq_register_current_thread (pd, do_rseq); ++ if (!rseq_register_current_thread (pd, do_rseq) && do_rseq) ++ __libc_fatal ("Fatal glibc error: rseq registration failed\n"); + } + + #ifndef __ASSUME_SET_ROBUST_LIST +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index 15bc7ffd6eda632d..6a3441f2cc49e7c4 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -26,7 +26,7 @@ + #include + + #ifdef RSEQ_SIG +-static inline void ++static inline bool + rseq_register_current_thread (struct pthread *self, bool do_rseq) + { + if (do_rseq) +@@ -35,15 +35,17 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq) + sizeof (self->rseq_area), + 0, RSEQ_SIG); + if (!INTERNAL_SYSCALL_ERROR_P (ret)) +- return; ++ return true; + } + THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++ return false; + } + #else /* RSEQ_SIG */ + static inline void + rseq_register_current_thread (struct pthread *self, bool do_rseq) + { + THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++ return false; + } + #endif /* RSEQ_SIG */ + diff --git a/SOURCES/glibc-rh2024347-11.patch b/SOURCES/glibc-rh2024347-11.patch new file mode 100644 index 0000000..3060a51 --- /dev/null +++ b/SOURCES/glibc-rh2024347-11.patch @@ -0,0 +1,592 @@ +commit 627f5ede70d70c77bdaf857db07404e8bf7f60af +Author: Florian Weimer +Date: Thu Dec 9 17:57:11 2021 +0100 + + Remove TLS_TCB_ALIGN and TLS_INIT_TCB_ALIGN + + TLS_INIT_TCB_ALIGN is not actually used. TLS_TCB_ALIGN was likely + introduced to support a configuration where the thread pointer + has not the same alignment as THREAD_SELF. Only ia64 seems to use + that, but for the stack/pointer guard, not for storing tcbhead_t. + Some ports use TLS_TCB_OFFSET and TLS_PRE_TCB_SIZE to shift + the thread pointer, potentially landing in a different residue class + modulo the alignment, but the changes should not impact that. + + In general, given that TLS variables have their own alignment + requirements, having different alignment for the (unshifted) thread + pointer and struct pthread would potentially result in dynamic + offsets, leading to more complexity. + + hppa had different values before: __alignof__ (tcbhead_t), which + seems to be 4, and __alignof__ (struct pthread), which was 8 + (old default) and is now 32. However, it defines THREAD_SELF as: + + /* Return the thread descriptor for the current thread. */ + # define THREAD_SELF \ + ({ struct pthread *__self; \ + __self = __get_cr27(); \ + __self - 1; \ + }) + + So the thread pointer points after struct pthread (hence __self - 1), + and they have to have the same alignment on hppa as well. + + Similarly, on ia64, the definitions were different. We have: + + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ + + (PTHREAD_STRUCT_END_PADDING < 2 * sizeof (uintptr_t) \ + ? ((2 * sizeof (uintptr_t) + __alignof__ (struct pthread) - 1) \ + & ~(__alignof__ (struct pthread) - 1)) \ + : 0)) + # define THREAD_SELF \ + ((struct pthread *) ((char *) __thread_self - TLS_PRE_TCB_SIZE)) + + And TLS_PRE_TCB_SIZE is a multiple of the struct pthread alignment + (confirmed by the new _Static_assert in sysdeps/ia64/libc-tls.c). + + On m68k, we have a larger gap between tcbhead_t and struct pthread. + But as far as I can tell, the port is fine with that. The definition + of TCB_OFFSET is sufficient to handle the shifted TCB scenario. + + This fixes commit 23c77f60181eb549f11ec2f913b4270af29eee38 + ("nptl: Increase default TCB alignment to 32"). + + Reviewed-by: H.J. Lu + +diff --git a/csu/libc-tls.c b/csu/libc-tls.c +index 5515204863218163..d83e69f6257ae981 100644 +--- a/csu/libc-tls.c ++++ b/csu/libc-tls.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #ifdef SHARED + #error makefile bug, this file is for static only +@@ -89,7 +90,7 @@ init_static_tls (size_t memsz, size_t align) + { + /* That is the size of the TLS memory for this object. */ + GL(dl_tls_static_size) = roundup (memsz + GLRO(dl_tls_static_surplus), +- TLS_TCB_ALIGN); ++ TCB_ALIGNMENT); + #if TLS_TCB_AT_TP + GL(dl_tls_static_size) += TLS_TCB_SIZE; + #endif +@@ -214,5 +215,5 @@ __libc_setup_tls (void) + memsz += tcb_offset; + #endif + +- init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align)); ++ init_static_tls (memsz, MAX (TCB_ALIGNMENT, max_align)); + } +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index 40263cf586e74c64..e2012d0cd515103b 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -219,7 +219,7 @@ _dl_count_modids (void) + void + _dl_determine_tlsoffset (void) + { +- size_t max_align = TLS_TCB_ALIGN; ++ size_t max_align = TCB_ALIGNMENT; + size_t freetop = 0; + size_t freebottom = 0; + +@@ -350,7 +350,7 @@ _dl_determine_tlsoffset (void) + + GL(dl_tls_static_used) = offset; + GLRO (dl_tls_static_size) = roundup (offset + GLRO(dl_tls_static_surplus), +- TLS_TCB_ALIGN); ++ TCB_ALIGNMENT); + #else + # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" + #endif +diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h +index cd9abb5d1d073593..75c469d51b532a89 100644 +--- a/sysdeps/aarch64/nptl/tls.h ++++ b/sysdeps/aarch64/nptl/tls.h +@@ -52,18 +52,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(tcbp, dtvp) \ +diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h +index 5f4843b28e7f1ad1..c0b6c93891546480 100644 +--- a/sysdeps/alpha/nptl/tls.h ++++ b/sysdeps/alpha/nptl/tls.h +@@ -46,18 +46,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN 16 +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN 16 +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(tcbp, dtvp) \ +diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h +index d9ada2f38089e6cd..d5d282297d12ec98 100644 +--- a/sysdeps/arc/nptl/tls.h ++++ b/sysdeps/arc/nptl/tls.h +@@ -48,17 +48,11 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + #ifndef TLS_TCB_SIZE + # define TLS_TCB_SIZE sizeof (tcbhead_t) + #endif + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h +index 354aae3318291395..8475c66588f99cae 100644 +--- a/sysdeps/arm/nptl/tls.h ++++ b/sysdeps/arm/nptl/tls.h +@@ -50,18 +50,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN 16 +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN 16 +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(tcbp, dtvp) \ +diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h +index f3fa3fcb02748776..e81d4552d27e0378 100644 +--- a/sysdeps/csky/nptl/tls.h ++++ b/sysdeps/csky/nptl/tls.h +@@ -61,15 +61,9 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN 8 +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN 8 +- + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +diff --git a/sysdeps/generic/tls.h b/sysdeps/generic/tls.h +index e86d70e6cebba5c8..9214ed39b6383e8c 100644 +--- a/sysdeps/generic/tls.h ++++ b/sysdeps/generic/tls.h +@@ -19,6 +19,11 @@ + /* An architecture-specific version of this file has to defined a + number of symbols: + ++ TCB_ALIGNMENT ++ ++ Alignment of THREAD_SELF (struct pthread *) and the thread ++ pointer. ++ + TLS_TCB_AT_TP or TLS_DTV_AT_TP + + The presence of one of these symbols signals which variant of +@@ -43,15 +48,6 @@ + dynamic linker itself. There are no threads in use at that time. + + +- TLS_TCB_ALIGN +- +- Alignment requirements for the TCB structure. +- +- TLS_INIT_TCB_ALIGN +- +- Similarly, but for the structure used at startup time. +- +- + INSTALL_DTV(tcb, init_dtv) + + This macro must install the given initial DTV into the thread control +diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h +index f0e274c45fb5e91e..88a6b902c0b7e2fd 100644 +--- a/sysdeps/hppa/nptl/tls.h ++++ b/sysdeps/hppa/nptl/tls.h +@@ -52,15 +52,9 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h +index 111c9ee59df30bc3..06ab9784a5358b0b 100644 +--- a/sysdeps/i386/nptl/tls.h ++++ b/sysdeps/i386/nptl/tls.h +@@ -102,15 +102,9 @@ union user_desc_init + struct pthread even when not linked with -lpthread. */ + # define TLS_INIT_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ + # define TLS_TCB_AT_TP 1 +diff --git a/sysdeps/ia64/libc-tls.c b/sysdeps/ia64/libc-tls.c +index a01edceab36d375e..ede1e8f463b135b4 100644 +--- a/sysdeps/ia64/libc-tls.c ++++ b/sysdeps/ia64/libc-tls.c +@@ -18,6 +18,9 @@ + + #include + ++_Static_assert (TLS_PRE_TCB_SIZE % __alignof (struct pthread) == 0, ++ "__thread_self and THREAD_SELF have same alignment"); ++ + /* On IA-64, as it lacks linker optimizations, __tls_get_addr can be + called even in statically linked binaries. + In this case module must be always 1 and PT_TLS segment +diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h +index 26fe555cb4b5e164..ca8f1280aeeed3d5 100644 +--- a/sysdeps/ia64/nptl/tls.h ++++ b/sysdeps/ia64/nptl/tls.h +@@ -53,9 +53,6 @@ register struct pthread *__thread_self __asm__("r13"); + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + +@@ -70,9 +67,6 @@ register struct pthread *__thread_self __asm__("r13"); + & ~(__alignof__ (struct pthread) - 1)) \ + : 0)) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The DTV is allocated at the TP; the TCB is placed elsewhere. */ + # define TLS_DTV_AT_TP 1 + # define TLS_TCB_AT_TP 0 +diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h +index 9f562c38288df200..b88ef0c9c74ae0b0 100644 +--- a/sysdeps/m68k/nptl/tls.h ++++ b/sysdeps/m68k/nptl/tls.h +@@ -54,20 +54,15 @@ typedef struct + pointer, we don't need this. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB - actually, it includes the TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The thread pointer (TP) points to the end of the + TCB + 0x7000, as for PowerPC and MIPS. This implies that TCB address is +diff --git a/sysdeps/mach/hurd/tls.h b/sysdeps/mach/hurd/tls.h +index f83956d3d7ca4f9f..773a2a0c36d5d57d 100644 +--- a/sysdeps/mach/hurd/tls.h ++++ b/sysdeps/mach/hurd/tls.h +@@ -29,20 +29,12 @@ + # include + # include + +- + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE TLS_INIT_TCB_SIZE /* XXX */ + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN TLS_INIT_TCB_ALIGN /* XXX */ +- +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(descr, dtvp) \ +diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h +index bfa6efa78049bb2d..b69d7b4f28f3b757 100644 +--- a/sysdeps/microblaze/nptl/tls.h ++++ b/sysdeps/microblaze/nptl/tls.h +@@ -56,18 +56,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(tcbp, dtvp) \ +diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h +index ef99aa646c898e76..6ccaf9804a68634a 100644 +--- a/sysdeps/mips/nptl/tls.h ++++ b/sysdeps/mips/nptl/tls.h +@@ -83,20 +83,15 @@ typedef struct + pointer, we don't need this. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB - actually, it includes the TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The thread pointer (in hardware register $29) points to the end of + the TCB + 0x7000, as for PowerPC. The pthread_descr structure is +diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h +index 7110cfccad7131f4..6ab6bd27b00a70ee 100644 +--- a/sysdeps/nios2/nptl/tls.h ++++ b/sysdeps/nios2/nptl/tls.h +@@ -59,20 +59,15 @@ register struct pthread *__thread_self __asm__("r23"); + pointer, we don't need this. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB - actually, it includes the TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The thread pointer (in hardware register r23) points to the end of + the TCB + 0x7000, as for PowerPC and MIPS. */ +diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h +index 110d085d30c86302..e194b334216eaa02 100644 +--- a/sysdeps/powerpc/nptl/tls.h ++++ b/sysdeps/powerpc/nptl/tls.h +@@ -108,19 +108,14 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The following assumes that TP (R2 or R13) points to the end of the + TCB + 0x7000 (per the ABI). This implies that TCB address is +diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h +index bdc0a3a6f91b51e8..8c12d8f971adeddb 100644 +--- a/sysdeps/riscv/nptl/tls.h ++++ b/sysdeps/riscv/nptl/tls.h +@@ -50,20 +50,15 @@ typedef struct + pointer, we don't need this. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB - actually, it includes the TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The thread pointer tp points to the end of the TCB. + The pthread_descr structure is immediately in front of the TCB. */ +diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h +index 2cdd18eb2907c060..3b4c0ab32a9439a3 100644 +--- a/sysdeps/s390/nptl/tls.h ++++ b/sysdeps/s390/nptl/tls.h +@@ -66,15 +66,9 @@ typedef struct + struct pthread even when not linked with -lpthread. */ + # define TLS_INIT_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ + # define TLS_TCB_AT_TP 1 +diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h +index 390640020e45f716..3e4d480b35951253 100644 +--- a/sysdeps/sh/nptl/tls.h ++++ b/sysdeps/sh/nptl/tls.h +@@ -51,18 +51,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TLS blocks start right after the TCB. */ + # define TLS_DTV_AT_TP 1 + # define TLS_TCB_AT_TP 0 +diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h +index 376d729989e35660..3fb4ce6e6dacf28c 100644 +--- a/sysdeps/sparc/nptl/tls.h ++++ b/sysdeps/sparc/nptl/tls.h +@@ -63,15 +63,9 @@ register struct pthread *__thread_self __asm__("%g7"); + struct pthread even when not linked with -lpthread. */ + # define TLS_INIT_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ + # define TLS_TCB_AT_TP 1 +diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h +index 3af1836e28b26fdb..50f7e8b544f9e6fc 100644 +--- a/sysdeps/x86_64/nptl/tls.h ++++ b/sysdeps/x86_64/nptl/tls.h +@@ -106,15 +106,9 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80, + struct pthread even when not linked with -lpthread. */ + # define TLS_INIT_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ + # define TLS_TCB_AT_TP 1 diff --git a/SOURCES/glibc-rh2024347-12.patch b/SOURCES/glibc-rh2024347-12.patch new file mode 100644 index 0000000..02a9cea --- /dev/null +++ b/SOURCES/glibc-rh2024347-12.patch @@ -0,0 +1,73 @@ +commit cb976fba4c51ede7bf8cee5035888527c308dfbc +Author: Florian Weimer +Date: Wed Dec 15 16:06:25 2021 +0100 + + powerpc: Use global register variable in + + A local register variable is merely a compiler hint, and so not + appropriate in this context. Move the global register variable into + and include it from , as there can only + be one global definition for one particular register. + + Fixes commit 8dbeb0561eeb876f557ac9eef5721912ec074ea5 + ("nptl: Add for defining __thread_pointer"). + + Reported-by: Mathieu Desnoyers + Reviewed-by: Raphael M Zinsly + +diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h +index 8fd5ba671f6f5e64..4feba5961062cfaf 100644 +--- a/sysdeps/powerpc/nptl/thread_pointer.h ++++ b/sysdeps/powerpc/nptl/thread_pointer.h +@@ -19,15 +19,16 @@ + #ifndef _SYS_THREAD_POINTER_H + #define _SYS_THREAD_POINTER_H + +-static inline void * +-__thread_pointer (void) +-{ + #ifdef __powerpc64__ +- register void *__result asm ("r13"); ++register void *__thread_register asm ("r13"); + #else +- register void *__result asm ("r2"); ++register void *__thread_register asm ("r2"); + #endif +- return __result; ++ ++static inline void * ++__thread_pointer (void) ++{ ++ return __thread_register; + } + + #endif /* _SYS_THREAD_POINTER_H */ +diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h +index e194b334216eaa02..050beb06a8f7de65 100644 +--- a/sysdeps/powerpc/nptl/tls.h ++++ b/sysdeps/powerpc/nptl/tls.h +@@ -26,6 +26,7 @@ + # include + # include + # include ++# include + + #else /* __ASSEMBLER__ */ + # include +@@ -36,16 +37,10 @@ + #ifndef __powerpc64__ + /* Register r2 (tp) is reserved by the ABI as "thread pointer". */ + # define PT_THREAD_POINTER PT_R2 +-# ifndef __ASSEMBLER__ +-register void *__thread_register __asm__ ("r2"); +-# endif + + #else /* __powerpc64__ */ + /* Register r13 (tp) is reserved by the ABI as "thread pointer". */ + # define PT_THREAD_POINTER PT_R13 +-# ifndef __ASSEMBLER__ +-register void *__thread_register __asm__ ("r13"); +-# endif + #endif /* __powerpc64__ */ + + #ifndef __ASSEMBLER__ diff --git a/SOURCES/glibc-rh2024347-13.patch b/SOURCES/glibc-rh2024347-13.patch new file mode 100644 index 0000000..f002a78 --- /dev/null +++ b/SOURCES/glibc-rh2024347-13.patch @@ -0,0 +1,42 @@ +Downstream-only patch to disable rseq by default. This is necessary +because CRIU does not yet support rseq: + + criu: Implement rseq support + + +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 28ff502990c2a10f..f559c44dcec4624b 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -425,11 +425,13 @@ The value is measured in bytes. The default is @samp{41943040} + @end deftp + + @deftp Tunable glibc.pthread.rseq +-The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable +-restartable sequences support in @theglibc{}. This enables applications +-to perform direct restartable sequence registration with the kernel. +-The default is @samp{1}, which means that @theglibc{} performs +-registration on behalf of the application. ++The @code{glibc.pthread.rseq} tunable can be set to @samp{1}, to enable ++restartable sequences support. @Theglibc{} uses this to optimize the ++@code{sched_getcpu} function. ++ ++The default is @samp{0}, which means that applications can perform ++restartable sequences registration, but @code{sched_getcpu} is not ++accelerated. + + Restartable sequences are a Linux-specific extension. + @end deftp +diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list +index d24f4be0d08ba407..df2a39ce01858d3b 100644 +--- a/sysdeps/nptl/dl-tunables.list ++++ b/sysdeps/nptl/dl-tunables.list +@@ -31,7 +31,7 @@ glibc { + type: INT_32 + minval: 0 + maxval: 1 +- default: 1 ++ default: 0 + } + } + } diff --git a/SOURCES/glibc-rh2024347-2.patch b/SOURCES/glibc-rh2024347-2.patch new file mode 100644 index 0000000..71613f3 --- /dev/null +++ b/SOURCES/glibc-rh2024347-2.patch @@ -0,0 +1,259 @@ +commit 23c77f60181eb549f11ec2f913b4270af29eee38 +Author: Florian Weimer +Date: Fri Dec 3 16:28:07 2021 +0100 + + nptl: Increase default TCB alignment to 32 + + rseq support will use a 32-byte aligned field in struct pthread, + so the whole struct needs to have at least that alignment. + + nptl/tst-tls3mod.c uses TCB_ALIGNMENT, therefore include + to obtain the fallback definition. + + Reviewed-by: H.J. Lu + +diff --git a/nptl/descr.h b/nptl/descr.h +index 4de84138fb960fa4..57be5b4fef564b36 100644 +--- a/nptl/descr.h ++++ b/nptl/descr.h +@@ -37,7 +37,9 @@ + #include + + #ifndef TCB_ALIGNMENT +-# define TCB_ALIGNMENT sizeof (double) ++# define TCB_ALIGNMENT 32 ++#elif TCB_ALIGNMENT < 32 ++# error TCB_ALIGNMENT must be at least 32 + #endif + + +diff --git a/nptl/tst-tls3mod.c b/nptl/tst-tls3mod.c +index cfd13aace1affcd5..77dcc550fc3b5017 100644 +--- a/nptl/tst-tls3mod.c ++++ b/nptl/tst-tls3mod.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + + extern pthread_barrier_t b; +diff --git a/sysdeps/aarch64/nptl/pthreaddef.h b/sysdeps/aarch64/nptl/pthreaddef.h +index 4d5ecf6661fd0fe6..8d9a10622d132a7a 100644 +--- a/sysdeps/aarch64/nptl/pthreaddef.h ++++ b/sysdeps/aarch64/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/alpha/nptl/pthreaddef.h b/sysdeps/alpha/nptl/pthreaddef.h +index 25edb5093e095548..660e5694a25ec60f 100644 +--- a/sysdeps/alpha/nptl/pthreaddef.h ++++ b/sysdeps/alpha/nptl/pthreaddef.h +@@ -27,8 +27,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 4096 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/arc/nptl/pthreaddef.h b/sysdeps/arc/nptl/pthreaddef.h +index 873b9d149ac46a62..d4dbe9e079445353 100644 +--- a/sysdeps/arc/nptl/pthreaddef.h ++++ b/sysdeps/arc/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 4 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/arm/nptl/pthreaddef.h b/sysdeps/arm/nptl/pthreaddef.h +index 332f4079c4c3f2bf..13769f5ae270b0ca 100644 +--- a/sysdeps/arm/nptl/pthreaddef.h ++++ b/sysdeps/arm/nptl/pthreaddef.h +@@ -28,9 +28,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. + +diff --git a/sysdeps/csky/nptl/pthreaddef.h b/sysdeps/csky/nptl/pthreaddef.h +index e78bc0016b43b450..7dde9131b9b1a6b0 100644 +--- a/sysdeps/csky/nptl/pthreaddef.h ++++ b/sysdeps/csky/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 8 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/ia64/nptl/pthreaddef.h b/sysdeps/ia64/nptl/pthreaddef.h +index 3a0f6daf9ad871aa..c7420fd1e4ee6081 100644 +--- a/sysdeps/ia64/nptl/pthreaddef.h ++++ b/sysdeps/ia64/nptl/pthreaddef.h +@@ -30,9 +30,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 16384 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __stack_pointer +diff --git a/sysdeps/m68k/nptl/pthreaddef.h b/sysdeps/m68k/nptl/pthreaddef.h +index 13e785a86bbf47b4..ce9511cb02da69fd 100644 +--- a/sysdeps/m68k/nptl/pthreaddef.h ++++ b/sysdeps/m68k/nptl/pthreaddef.h +@@ -28,9 +28,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/microblaze/nptl/pthreaddef.h b/sysdeps/microblaze/nptl/pthreaddef.h +index 517157444da556ad..19d7235782afde53 100644 +--- a/sysdeps/microblaze/nptl/pthreaddef.h ++++ b/sysdeps/microblaze/nptl/pthreaddef.h +@@ -31,8 +31,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/mips/nptl/pthreaddef.h b/sysdeps/mips/nptl/pthreaddef.h +index a7bccef6e512438f..322591c293ce5e15 100644 +--- a/sysdeps/mips/nptl/pthreaddef.h ++++ b/sysdeps/mips/nptl/pthreaddef.h +@@ -27,9 +27,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/nios2/nptl/pthreaddef.h b/sysdeps/nios2/nptl/pthreaddef.h +index e01a0e6df72c089a..aa0709d0dc69f251 100644 +--- a/sysdeps/nios2/nptl/pthreaddef.h ++++ b/sysdeps/nios2/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 4 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/powerpc/nptl/pthreaddef.h b/sysdeps/powerpc/nptl/pthreaddef.h +index ef5310e6315fde2c..117c35229ea68f48 100644 +--- a/sysdeps/powerpc/nptl/pthreaddef.h ++++ b/sysdeps/powerpc/nptl/pthreaddef.h +@@ -28,9 +28,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 4096 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/riscv/nptl/pthreaddef.h b/sysdeps/riscv/nptl/pthreaddef.h +index 7bf93d6a63fdecd2..0f33cc48fe4fc728 100644 +--- a/sysdeps/riscv/nptl/pthreaddef.h ++++ b/sysdeps/riscv/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/s390/nptl/pthreaddef.h b/sysdeps/s390/nptl/pthreaddef.h +index 091f82df24a4024c..0e32bd862f7fea48 100644 +--- a/sysdeps/s390/nptl/pthreaddef.h ++++ b/sysdeps/s390/nptl/pthreaddef.h +@@ -28,9 +28,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/sh/nptl/pthreaddef.h b/sysdeps/sh/nptl/pthreaddef.h +index 3fa3d189ef969c90..f4e3a290df4ee6e6 100644 +--- a/sysdeps/sh/nptl/pthreaddef.h ++++ b/sysdeps/sh/nptl/pthreaddef.h +@@ -29,9 +29,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 8 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/sparc/sparc32/pthreaddef.h b/sysdeps/sparc/sparc32/pthreaddef.h +index 6526fb3d6e7e1448..7a0a04789dac478e 100644 +--- a/sysdeps/sparc/sparc32/pthreaddef.h ++++ b/sysdeps/sparc/sparc32/pthreaddef.h +@@ -27,9 +27,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME (stack_pointer + (2 * 64)) +diff --git a/sysdeps/sparc/sparc64/pthreaddef.h b/sysdeps/sparc/sparc64/pthreaddef.h +index 3da9d7afc8054598..103842856d40432b 100644 +--- a/sysdeps/sparc/sparc64/pthreaddef.h ++++ b/sysdeps/sparc/sparc64/pthreaddef.h +@@ -27,10 +27,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 4096 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME (stack_pointer + (2 * 128)) + register char *stack_pointer __asm__("%sp"); diff --git a/SOURCES/glibc-rh2024347-3.patch b/SOURCES/glibc-rh2024347-3.patch new file mode 100644 index 0000000..08e30f7 --- /dev/null +++ b/SOURCES/glibc-rh2024347-3.patch @@ -0,0 +1,150 @@ +commit 4fb4e7e821e36180835bf88e363f9f13b5797e3a +Author: Florian Weimer +Date: Sun Dec 5 13:50:17 2021 +0100 + + csu: Always use __executable_start in gmon-start.c + + Current binutils defines __executable_start as the lowest text + address, so using the entry point address as a fallback is no + longer necessary. As a result, overriding is only + necessary if the entry point is not called _start. + + The previous approach to define __ASSEMBLY__ to suppress the + declaration breaks if headers included by are not + compatible with __ASSEMBLY__. This happens with rseq integration + because it is necessary to include kernel headers in more places. + + Reviewed-by: H.J. Lu + +diff --git a/csu/gmon-start.c b/csu/gmon-start.c +index 344606a676c188d4..260c7613e291a32d 100644 +--- a/csu/gmon-start.c ++++ b/csu/gmon-start.c +@@ -38,32 +38,12 @@ + #include + #include + #include +-#define __ASSEMBLY__ +-#include +- +-/* Beginning and end of our code segment. We cannot declare them +- as the external functions since we want the addresses of those +- labels. Taking the address of a function may have different +- meanings on different platforms. */ +-#ifdef ENTRY_POINT_DECL +-ENTRY_POINT_DECL(extern) +-#else +-extern char ENTRY_POINT[]; +-#endif +-extern char etext[]; + + /* Use __executable_start as the lowest address to keep profiling records + if it provided by the linker. */ +-extern const char executable_start[] asm ("__executable_start") +- __attribute__ ((weak, visibility ("hidden"))); ++extern const char __executable_start[] __attribute__ ((visibility ("hidden"))); + +-#ifndef TEXT_START +-# ifdef ENTRY_POINT_DECL +-# define TEXT_START ENTRY_POINT +-# else +-# define TEXT_START &ENTRY_POINT +-# endif +-#endif ++extern char etext[]; + + #if !ELF_INITFINI + /* Instead of defining __gmon_start__ globally in gcrt1.o, we make it +@@ -97,10 +77,7 @@ __gmon_start__ (void) + called = 1; + + /* Start keeping profiling records. */ +- if (&executable_start != NULL) +- __monstartup ((u_long) &executable_start, (u_long) &etext); +- else +- __monstartup ((u_long) TEXT_START, (u_long) &etext); ++ __monstartup ((u_long) &__executable_start, (u_long) &etext); + + /* Call _mcleanup before exiting; it will write out gmon.out from the + collected data. */ +diff --git a/sysdeps/hppa/entry.h b/sysdeps/hppa/entry.h +deleted file mode 100644 +index 5ea5b47448ceb2e7..0000000000000000 +--- a/sysdeps/hppa/entry.h ++++ /dev/null +@@ -1,13 +0,0 @@ +-#ifndef __ASSEMBLY__ +-extern void _start (void); +-#endif +- +-/* Lives in libgcc.so and canonicalizes function pointers for comparison. */ +-extern unsigned int __canonicalize_funcptr_for_compare (unsigned int fptr); +- +-/* The function's entry point is stored in the first word of the +- function descriptor (plabel) of _start(). */ +-#define ENTRY_POINT __canonicalize_funcptr_for_compare((unsigned int)_start) +- +-/* We have to provide a special declaration. */ +-#define ENTRY_POINT_DECL(class) class void _start (void); +diff --git a/sysdeps/ia64/entry.h b/sysdeps/ia64/entry.h +deleted file mode 100644 +index e11b49fc53602eb8..0000000000000000 +--- a/sysdeps/ia64/entry.h ++++ /dev/null +@@ -1,13 +0,0 @@ +-#include +-#include +- +-#ifndef __ASSEMBLY__ +-extern void _start (void); +-#endif +- +-/* The function's entry point is stored in the first word of the +- function descriptor (plabel) of _start(). */ +-#define ENTRY_POINT ELF_PTR_TO_FDESC (_start)->ip +- +-/* We have to provide a special declaration. */ +-#define ENTRY_POINT_DECL(class) class void _start (void); +diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h +deleted file mode 100644 +index 99c81cb9820d188d..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/entry.h ++++ /dev/null +@@ -1,37 +0,0 @@ +-/* Finding the entry point and start of text. PowerPC64 version. +- Copyright (C) 2002-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#ifndef __ASSEMBLY__ +-extern void _start (void); +-#endif +- +-#define ENTRY_POINT _start +- +-#if _CALL_ELF != 2 +-/* We have to provide a special declaration. */ +-#define ENTRY_POINT_DECL(class) class void _start (void); +- +-/* Use the address of ._start as the lowest address for which we need +- to keep profiling records. We can't copy the ia64 scheme as our +- entry poiny address is really the address of the function +- descriptor, not the actual function entry. */ +-#define TEXT_START \ +- ({ extern unsigned long int _start_as_data[] asm ("_start"); \ +- _start_as_data[0]; }) +-#endif diff --git a/SOURCES/glibc-rh2024347-4.patch b/SOURCES/glibc-rh2024347-4.patch new file mode 100644 index 0000000..a49f626 --- /dev/null +++ b/SOURCES/glibc-rh2024347-4.patch @@ -0,0 +1,130 @@ +commit 8dbeb0561eeb876f557ac9eef5721912ec074ea5 +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Add for defining __thread_pointer + + already contains a definition that is quite similar, + but it is not consistent across architectures. + + Only architectures for which rseq support is added are covered. + + Reviewed-by: Szabolcs Nagy + +diff --git a/sysdeps/nptl/thread_pointer.h b/sysdeps/nptl/thread_pointer.h +new file mode 100644 +index 0000000000000000..92f2f3093eba55bb +--- /dev/null ++++ b/sysdeps/nptl/thread_pointer.h +@@ -0,0 +1,28 @@ ++/* __thread_pointer definition. Generic version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _SYS_THREAD_POINTER_H ++#define _SYS_THREAD_POINTER_H ++ ++static inline void * ++__thread_pointer (void) ++{ ++ return __builtin_thread_pointer (); ++} ++ ++#endif /* _SYS_THREAD_POINTER_H */ +diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h +new file mode 100644 +index 0000000000000000..8fd5ba671f6f5e64 +--- /dev/null ++++ b/sysdeps/powerpc/nptl/thread_pointer.h +@@ -0,0 +1,33 @@ ++/* __thread_pointer definition. powerpc version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _SYS_THREAD_POINTER_H ++#define _SYS_THREAD_POINTER_H ++ ++static inline void * ++__thread_pointer (void) ++{ ++#ifdef __powerpc64__ ++ register void *__result asm ("r13"); ++#else ++ register void *__result asm ("r2"); ++#endif ++ return __result; ++} ++ ++#endif /* _SYS_THREAD_POINTER_H */ +diff --git a/sysdeps/x86/nptl/thread_pointer.h b/sysdeps/x86/nptl/thread_pointer.h +new file mode 100644 +index 0000000000000000..6b71b6f7e1401e4c +--- /dev/null ++++ b/sysdeps/x86/nptl/thread_pointer.h +@@ -0,0 +1,38 @@ ++/* __thread_pointer definition. x86 version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _SYS_THREAD_POINTER_H ++#define _SYS_THREAD_POINTER_H ++ ++static inline void * ++__thread_pointer (void) ++{ ++#if __GNUC_PREREQ (11, 1) ++ return __builtin_thread_pointer (); ++#else ++ void *__result; ++# ifdef __x86_64__ ++ __asm__ ("mov %%fs:0, %0" : "=r" (__result)); ++# else ++ __asm__ ("mov %%gs:0, %0" : "=r" (__result)); ++# endif ++ return __result; ++#endif /* !GCC 11 */ ++} ++ ++#endif /* _SYS_THREAD_POINTER_H */ diff --git a/SOURCES/glibc-rh2024347-5.patch b/SOURCES/glibc-rh2024347-5.patch new file mode 100644 index 0000000..36b1db1 --- /dev/null +++ b/SOURCES/glibc-rh2024347-5.patch @@ -0,0 +1,904 @@ +commit ce2248ab91b2ea09a378f85012f251f31ac65e31 +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Introduce for THREAD_* accessors + + These are common between most architectures. Only the x86 targets + are outliers. + + Reviewed-by: Szabolcs Nagy + +diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h +index 6e896207a659514f..cd9abb5d1d073593 100644 +--- a/sysdeps/aarch64/nptl/tls.h ++++ b/sysdeps/aarch64/nptl/tls.h +@@ -98,15 +98,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (64, sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + # define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h +index 4dbccc5249539325..5f4843b28e7f1ad1 100644 +--- a/sysdeps/alpha/nptl/tls.h ++++ b/sysdeps/alpha/nptl/tls.h +@@ -92,15 +92,7 @@ typedef struct + # define DB_THREAD_SELF \ + REGISTER (64, 64, 32 * 8, -sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + #define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h +index 95300fdd2159dc53..d9ada2f38089e6cd 100644 +--- a/sysdeps/arc/nptl/tls.h ++++ b/sysdeps/arc/nptl/tls.h +@@ -100,15 +100,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + #define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h +index 1bd11307ce0a7f0a..354aae3318291395 100644 +--- a/sysdeps/arm/nptl/tls.h ++++ b/sysdeps/arm/nptl/tls.h +@@ -89,15 +89,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + #define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h +index 7a234041ed0bff39..f3fa3fcb02748776 100644 +--- a/sysdeps/csky/nptl/tls.h ++++ b/sysdeps/csky/nptl/tls.h +@@ -116,15 +116,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + # define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h +index 857003a7d35073eb..f0e274c45fb5e91e 100644 +--- a/sysdeps/hppa/nptl/tls.h ++++ b/sysdeps/hppa/nptl/tls.h +@@ -107,15 +107,7 @@ typedef struct + # define DB_THREAD_SELF \ + REGISTER (32, 32, 53 * 4, -sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + static inline struct pthread *__get_cr27(void) + { +diff --git a/sysdeps/i386/nptl/tcb-access.h b/sysdeps/i386/nptl/tcb-access.h +new file mode 100644 +index 0000000000000000..6c6d561e394817c7 +--- /dev/null ++++ b/sysdeps/i386/nptl/tcb-access.h +@@ -0,0 +1,123 @@ ++/* THREAD_* accessors. i386 version. ++ Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Read member of the thread descriptor directly. */ ++#define THREAD_GETMEM(descr, member) \ ++ ({ __typeof (descr->member) __value; \ ++ _Static_assert (sizeof (__value) == 1 \ ++ || sizeof (__value) == 4 \ ++ || sizeof (__value) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (__value) == 1) \ ++ asm volatile ("movb %%gs:%P2,%b0" \ ++ : "=q" (__value) \ ++ : "0" (0), "i" (offsetof (struct pthread, member))); \ ++ else if (sizeof (__value) == 4) \ ++ asm volatile ("movl %%gs:%P1,%0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member))); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movl %%gs:%P1,%%eax\n\t" \ ++ "movl %%gs:%P2,%%edx" \ ++ : "=A" (__value) \ ++ : "i" (offsetof (struct pthread, member)), \ ++ "i" (offsetof (struct pthread, member) + 4)); \ ++ } \ ++ __value; }) ++ ++ ++/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ ++#define THREAD_GETMEM_NC(descr, member, idx) \ ++ ({ __typeof (descr->member[0]) __value; \ ++ _Static_assert (sizeof (__value) == 1 \ ++ || sizeof (__value) == 4 \ ++ || sizeof (__value) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (__value) == 1) \ ++ asm volatile ("movb %%gs:%P2(%3),%b0" \ ++ : "=q" (__value) \ ++ : "0" (0), "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else if (sizeof (__value) == 4) \ ++ asm volatile ("movl %%gs:%P1(,%2,4),%0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \ ++ "movl %%gs:4+%P1(,%2,8),%%edx" \ ++ : "=&A" (__value) \ ++ : "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ } \ ++ __value; }) ++ ++ ++ ++/* Set member of the thread descriptor directly. */ ++#define THREAD_SETMEM(descr, member, value) \ ++ ({ \ ++ _Static_assert (sizeof (descr->member) == 1 \ ++ || sizeof (descr->member) == 4 \ ++ || sizeof (descr->member) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (descr->member) == 1) \ ++ asm volatile ("movb %b0,%%gs:%P1" : \ ++ : "iq" (value), \ ++ "i" (offsetof (struct pthread, member))); \ ++ else if (sizeof (descr->member) == 4) \ ++ asm volatile ("movl %0,%%gs:%P1" : \ ++ : "ir" (value), \ ++ "i" (offsetof (struct pthread, member))); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movl %%eax,%%gs:%P1\n\t" \ ++ "movl %%edx,%%gs:%P2" : \ ++ : "A" ((uint64_t) cast_to_integer (value)), \ ++ "i" (offsetof (struct pthread, member)), \ ++ "i" (offsetof (struct pthread, member) + 4)); \ ++ }}) ++ ++ ++/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ ++#define THREAD_SETMEM_NC(descr, member, idx, value) \ ++ ({ \ ++ _Static_assert (sizeof (descr->member[0]) == 1 \ ++ || sizeof (descr->member[0]) == 4 \ ++ || sizeof (descr->member[0]) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (descr->member[0]) == 1) \ ++ asm volatile ("movb %b0,%%gs:%P1(%2)" : \ ++ : "iq" (value), \ ++ "i" (offsetof (struct pthread, member)), \ ++ "r" (idx)); \ ++ else if (sizeof (descr->member[0]) == 4) \ ++ asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \ ++ : "ir" (value), \ ++ "i" (offsetof (struct pthread, member)), \ ++ "r" (idx)); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \ ++ "movl %%edx,%%gs:4+%P1(,%2,8)" : \ ++ : "A" ((uint64_t) cast_to_integer (value)), \ ++ "i" (offsetof (struct pthread, member)), \ ++ "r" (idx)); \ ++ }}) +diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h +index 86ee1ef30270f960..111c9ee59df30bc3 100644 +--- a/sysdeps/i386/nptl/tls.h ++++ b/sysdeps/i386/nptl/tls.h +@@ -250,113 +250,7 @@ tls_fill_user_desc (union user_desc_init *desc, + REGISTER_THREAD_AREA (32, offsetof (struct user_regs_struct, xgs), 3) \ + REGISTER_THREAD_AREA (64, 26 * 8, 3) /* x86-64's user_regs_struct->gs */ + +- +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) \ +- ({ __typeof (descr->member) __value; \ +- _Static_assert (sizeof (__value) == 1 \ +- || sizeof (__value) == 4 \ +- || sizeof (__value) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (__value) == 1) \ +- asm volatile ("movb %%gs:%P2,%b0" \ +- : "=q" (__value) \ +- : "0" (0), "i" (offsetof (struct pthread, member))); \ +- else if (sizeof (__value) == 4) \ +- asm volatile ("movl %%gs:%P1,%0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member))); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movl %%gs:%P1,%%eax\n\t" \ +- "movl %%gs:%P2,%%edx" \ +- : "=A" (__value) \ +- : "i" (offsetof (struct pthread, member)), \ +- "i" (offsetof (struct pthread, member) + 4)); \ +- } \ +- __value; }) +- +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- ({ __typeof (descr->member[0]) __value; \ +- _Static_assert (sizeof (__value) == 1 \ +- || sizeof (__value) == 4 \ +- || sizeof (__value) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (__value) == 1) \ +- asm volatile ("movb %%gs:%P2(%3),%b0" \ +- : "=q" (__value) \ +- : "0" (0), "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else if (sizeof (__value) == 4) \ +- asm volatile ("movl %%gs:%P1(,%2,4),%0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \ +- "movl %%gs:4+%P1(,%2,8),%%edx" \ +- : "=&A" (__value) \ +- : "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- } \ +- __value; }) +- +- +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- ({ \ +- _Static_assert (sizeof (descr->member) == 1 \ +- || sizeof (descr->member) == 4 \ +- || sizeof (descr->member) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (descr->member) == 1) \ +- asm volatile ("movb %b0,%%gs:%P1" : \ +- : "iq" (value), \ +- "i" (offsetof (struct pthread, member))); \ +- else if (sizeof (descr->member) == 4) \ +- asm volatile ("movl %0,%%gs:%P1" : \ +- : "ir" (value), \ +- "i" (offsetof (struct pthread, member))); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movl %%eax,%%gs:%P1\n\t" \ +- "movl %%edx,%%gs:%P2" : \ +- : "A" ((uint64_t) cast_to_integer (value)), \ +- "i" (offsetof (struct pthread, member)), \ +- "i" (offsetof (struct pthread, member) + 4)); \ +- }}) +- +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- ({ \ +- _Static_assert (sizeof (descr->member[0]) == 1 \ +- || sizeof (descr->member[0]) == 4 \ +- || sizeof (descr->member[0]) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (descr->member[0]) == 1) \ +- asm volatile ("movb %b0,%%gs:%P1(%2)" : \ +- : "iq" (value), \ +- "i" (offsetof (struct pthread, member)), \ +- "r" (idx)); \ +- else if (sizeof (descr->member[0]) == 4) \ +- asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \ +- : "ir" (value), \ +- "i" (offsetof (struct pthread, member)), \ +- "r" (idx)); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \ +- "movl %%edx,%%gs:4+%P1(,%2,8)" : \ +- : "A" ((uint64_t) cast_to_integer (value)), \ +- "i" (offsetof (struct pthread, member)), \ +- "r" (idx)); \ +- }}) +- ++# include + + /* Set the stack guard field in TCB head. */ + #define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h +index 66d9bf3189f0b727..26fe555cb4b5e164 100644 +--- a/sysdeps/ia64/nptl/tls.h ++++ b/sysdeps/ia64/nptl/tls.h +@@ -128,15 +128,7 @@ register struct pthread *__thread_self __asm__("r13"); + /* Magic for libthread_db to know how to do THREAD_SELF. */ + # define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -TLS_PRE_TCB_SIZE) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Set the stack guard field in TCB head. */ + #define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h +index cfcd6d2b7b59321c..9f562c38288df200 100644 +--- a/sysdeps/m68k/nptl/tls.h ++++ b/sysdeps/m68k/nptl/tls.h +@@ -118,15 +118,7 @@ extern void * __m68k_read_tp (void); + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* l_tls_offset == 0 is perfectly valid on M68K, so we have to use some + different value to mean unset l_tls_offset. */ +diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h +index c93d90b11bfe4c74..bfa6efa78049bb2d 100644 +--- a/sysdeps/microblaze/nptl/tls.h ++++ b/sysdeps/microblaze/nptl/tls.h +@@ -100,20 +100,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, sizeof (struct pthread)) + +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) (descr->member) +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- (descr->member[idx]) +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- (descr->member = (value)) +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- (descr->member[idx] = (value)) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + # define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h +index c09f49071cf3b5b9..ef99aa646c898e76 100644 +--- a/sysdeps/mips/nptl/tls.h ++++ b/sysdeps/mips/nptl/tls.h +@@ -144,14 +144,7 @@ typedef struct + CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE) + + /* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* l_tls_offset == 0 is perfectly valid on MIPS, so we have to use some + different value to mean unset l_tls_offset. */ +diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h +index 02a05b4e741092bf..7110cfccad7131f4 100644 +--- a/sysdeps/nios2/nptl/tls.h ++++ b/sysdeps/nios2/nptl/tls.h +@@ -112,15 +112,7 @@ register struct pthread *__thread_self __asm__("r23"); + # define DB_THREAD_SELF \ + REGISTER (32, 32, 23 * 4, -TLS_PRE_TCB_SIZE - TLS_TCB_OFFSET) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + # define THREAD_GET_POINTER_GUARD() \ + (((tcbhead_t *) (READ_THREAD_POINTER () \ +diff --git a/sysdeps/nptl/tcb-access.h b/sysdeps/nptl/tcb-access.h +new file mode 100644 +index 0000000000000000..b4137b8ab8067915 +--- /dev/null ++++ b/sysdeps/nptl/tcb-access.h +@@ -0,0 +1,30 @@ ++/* THREAD_* accessors. Generic version based on struct pthread pointers. ++ Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Note: These are for accessing the TCB of the *current* thread. ++ descr can be disregarded on some targets as an optimization. See ++ i386 for an example. */ ++ ++#define THREAD_GETMEM(descr, member) \ ++ descr->member ++#define THREAD_GETMEM_NC(descr, member, idx) \ ++ descr->member[idx] ++#define THREAD_SETMEM(descr, member, value) \ ++ descr->member = (value) ++#define THREAD_SETMEM_NC(descr, member, idx, value) \ ++ descr->member[idx] = (value) +diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h +index 6c779b6609147d54..110d085d30c86302 100644 +--- a/sysdeps/powerpc/nptl/tls.h ++++ b/sysdeps/powerpc/nptl/tls.h +@@ -176,20 +176,7 @@ typedef struct + REGISTER (64, 64, PT_THREAD_POINTER * 8, \ + - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) + +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member) +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- ((void)(descr), (THREAD_SELF)->member[idx]) +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- ((void)(descr), (THREAD_SELF)->member = (value)) +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- ((void)(descr), (THREAD_SELF)->member[idx] = (value)) ++# include + + /* Set the stack guard field in TCB head. */ + # define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h +index 5350bcc0498bab69..bdc0a3a6f91b51e8 100644 +--- a/sysdeps/riscv/nptl/tls.h ++++ b/sysdeps/riscv/nptl/tls.h +@@ -105,14 +105,7 @@ typedef struct + REGISTER (64, 64, 4 * 8, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) + + /* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* l_tls_offset == 0 is perfectly valid, so we have to use some different + value to mean unset l_tls_offset. */ +diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h +index efb52515e05c06a9..2cdd18eb2907c060 100644 +--- a/sysdeps/s390/nptl/tls.h ++++ b/sysdeps/s390/nptl/tls.h +@@ -135,15 +135,7 @@ typedef struct + # define DB_THREAD_SELF REGISTER (32, 32, 18 * 4, 0) \ + REGISTER (64, __WORDSIZE, 18 * 8, 0) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Set the stack guard field in TCB head. */ + #define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h +index ac3c9a9e856ee686..390640020e45f716 100644 +--- a/sysdeps/sh/nptl/tls.h ++++ b/sysdeps/sh/nptl/tls.h +@@ -113,19 +113,7 @@ typedef struct + # define DB_THREAD_SELF \ + REGISTER (32, 32, REG_GBR * 4, -sizeof (struct pthread)) + +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) (descr->member) +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) (descr->member[idx]) +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + #define THREAD_GET_POINTER_GUARD() \ + ({ tcbhead_t *__tcbp; \ +diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h +index dd1eb82a595619a9..376d729989e35660 100644 +--- a/sysdeps/sparc/nptl/tls.h ++++ b/sysdeps/sparc/nptl/tls.h +@@ -112,15 +112,7 @@ register struct pthread *__thread_self __asm__("%g7"); + REGISTER (32, 32, 10 * 4, 0) \ + REGISTER (64, __WORDSIZE, (6 * 8) + (__WORDSIZE==64?0:4), 0) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Set the stack guard field in TCB head. */ + #define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/x86_64/nptl/tcb-access.h b/sysdeps/x86_64/nptl/tcb-access.h +new file mode 100644 +index 0000000000000000..18848a729d16a4f5 +--- /dev/null ++++ b/sysdeps/x86_64/nptl/tcb-access.h +@@ -0,0 +1,130 @@ ++/* THREAD_* accessors. x86_64 version. ++ Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Read member of the thread descriptor directly. */ ++# define THREAD_GETMEM(descr, member) \ ++ ({ __typeof (descr->member) __value; \ ++ _Static_assert (sizeof (__value) == 1 \ ++ || sizeof (__value) == 4 \ ++ || sizeof (__value) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (__value) == 1) \ ++ asm volatile ("movb %%fs:%P2,%b0" \ ++ : "=q" (__value) \ ++ : "0" (0), "i" (offsetof (struct pthread, member))); \ ++ else if (sizeof (__value) == 4) \ ++ asm volatile ("movl %%fs:%P1,%0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member))); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movq %%fs:%P1,%q0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member))); \ ++ } \ ++ __value; }) ++ ++ ++/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ ++# define THREAD_GETMEM_NC(descr, member, idx) \ ++ ({ __typeof (descr->member[0]) __value; \ ++ _Static_assert (sizeof (__value) == 1 \ ++ || sizeof (__value) == 4 \ ++ || sizeof (__value) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (__value) == 1) \ ++ asm volatile ("movb %%fs:%P2(%q3),%b0" \ ++ : "=q" (__value) \ ++ : "0" (0), "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else if (sizeof (__value) == 4) \ ++ asm volatile ("movl %%fs:%P1(,%q2,4),%0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member[0])), "r" (idx));\ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ } \ ++ __value; }) ++ ++ ++/* Loading addresses of objects on x86-64 needs to be treated special ++ when generating PIC code. */ ++#ifdef __pic__ ++# define IMM_MODE "nr" ++#else ++# define IMM_MODE "ir" ++#endif ++ ++ ++/* Set member of the thread descriptor directly. */ ++# define THREAD_SETMEM(descr, member, value) \ ++ ({ \ ++ _Static_assert (sizeof (descr->member) == 1 \ ++ || sizeof (descr->member) == 4 \ ++ || sizeof (descr->member) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (descr->member) == 1) \ ++ asm volatile ("movb %b0,%%fs:%P1" : \ ++ : "iq" (value), \ ++ "i" (offsetof (struct pthread, member))); \ ++ else if (sizeof (descr->member) == 4) \ ++ asm volatile ("movl %0,%%fs:%P1" : \ ++ : IMM_MODE (value), \ ++ "i" (offsetof (struct pthread, member))); \ ++ else /* 8 */ \ ++ { \ ++ /* Since movq takes a signed 32-bit immediate or a register source \ ++ operand, use "er" constraint for 32-bit signed integer constant \ ++ or register. */ \ ++ asm volatile ("movq %q0,%%fs:%P1" : \ ++ : "er" ((uint64_t) cast_to_integer (value)), \ ++ "i" (offsetof (struct pthread, member))); \ ++ }}) ++ ++ ++/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ ++# define THREAD_SETMEM_NC(descr, member, idx, value) \ ++ ({ \ ++ _Static_assert (sizeof (descr->member[0]) == 1 \ ++ || sizeof (descr->member[0]) == 4 \ ++ || sizeof (descr->member[0]) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (descr->member[0]) == 1) \ ++ asm volatile ("movb %b0,%%fs:%P1(%q2)" : \ ++ : "iq" (value), \ ++ "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else if (sizeof (descr->member[0]) == 4) \ ++ asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \ ++ : IMM_MODE (value), \ ++ "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else /* 8 */ \ ++ { \ ++ /* Since movq takes a signed 32-bit immediate or a register source \ ++ operand, use "er" constraint for 32-bit signed integer constant \ ++ or register. */ \ ++ asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \ ++ : "er" ((uint64_t) cast_to_integer (value)), \ ++ "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ }}) +diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h +index a78c4f4d016002fa..3af1836e28b26fdb 100644 +--- a/sysdeps/x86_64/nptl/tls.h ++++ b/sysdeps/x86_64/nptl/tls.h +@@ -195,119 +195,7 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80, + # define DB_THREAD_SELF_INCLUDE /* For the FS constant. */ + # define DB_THREAD_SELF CONST_THREAD_AREA (64, FS) + +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) \ +- ({ __typeof (descr->member) __value; \ +- _Static_assert (sizeof (__value) == 1 \ +- || sizeof (__value) == 4 \ +- || sizeof (__value) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (__value) == 1) \ +- asm volatile ("movb %%fs:%P2,%b0" \ +- : "=q" (__value) \ +- : "0" (0), "i" (offsetof (struct pthread, member))); \ +- else if (sizeof (__value) == 4) \ +- asm volatile ("movl %%fs:%P1,%0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member))); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movq %%fs:%P1,%q0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member))); \ +- } \ +- __value; }) +- +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- ({ __typeof (descr->member[0]) __value; \ +- _Static_assert (sizeof (__value) == 1 \ +- || sizeof (__value) == 4 \ +- || sizeof (__value) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (__value) == 1) \ +- asm volatile ("movb %%fs:%P2(%q3),%b0" \ +- : "=q" (__value) \ +- : "0" (0), "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else if (sizeof (__value) == 4) \ +- asm volatile ("movl %%fs:%P1(,%q2,4),%0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member[0])), "r" (idx));\ +- else /* 8 */ \ +- { \ +- asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- } \ +- __value; }) +- +- +-/* Loading addresses of objects on x86-64 needs to be treated special +- when generating PIC code. */ +-#ifdef __pic__ +-# define IMM_MODE "nr" +-#else +-# define IMM_MODE "ir" +-#endif +- +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- ({ \ +- _Static_assert (sizeof (descr->member) == 1 \ +- || sizeof (descr->member) == 4 \ +- || sizeof (descr->member) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (descr->member) == 1) \ +- asm volatile ("movb %b0,%%fs:%P1" : \ +- : "iq" (value), \ +- "i" (offsetof (struct pthread, member))); \ +- else if (sizeof (descr->member) == 4) \ +- asm volatile ("movl %0,%%fs:%P1" : \ +- : IMM_MODE (value), \ +- "i" (offsetof (struct pthread, member))); \ +- else /* 8 */ \ +- { \ +- /* Since movq takes a signed 32-bit immediate or a register source \ +- operand, use "er" constraint for 32-bit signed integer constant \ +- or register. */ \ +- asm volatile ("movq %q0,%%fs:%P1" : \ +- : "er" ((uint64_t) cast_to_integer (value)), \ +- "i" (offsetof (struct pthread, member))); \ +- }}) +- +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- ({ \ +- _Static_assert (sizeof (descr->member[0]) == 1 \ +- || sizeof (descr->member[0]) == 4 \ +- || sizeof (descr->member[0]) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (descr->member[0]) == 1) \ +- asm volatile ("movb %b0,%%fs:%P1(%q2)" : \ +- : "iq" (value), \ +- "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else if (sizeof (descr->member[0]) == 4) \ +- asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \ +- : IMM_MODE (value), \ +- "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else /* 8 */ \ +- { \ +- /* Since movq takes a signed 32-bit immediate or a register source \ +- operand, use "er" constraint for 32-bit signed integer constant \ +- or register. */ \ +- asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \ +- : "er" ((uint64_t) cast_to_integer (value)), \ +- "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- }}) +- ++# include + + /* Set the stack guard field in TCB head. */ + # define THREAD_SET_STACK_GUARD(value) \ diff --git a/SOURCES/glibc-rh2024347-6.patch b/SOURCES/glibc-rh2024347-6.patch new file mode 100644 index 0000000..4782cdf --- /dev/null +++ b/SOURCES/glibc-rh2024347-6.patch @@ -0,0 +1,49 @@ +commit 8d1927d8dc5aad0f01c929123086be3a5b799d18 +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Introduce THREAD_GETMEM_VOLATILE + + This will be needed for rseq TCB access. + + Reviewed-by: Szabolcs Nagy + +diff --git a/sysdeps/i386/nptl/tcb-access.h b/sysdeps/i386/nptl/tcb-access.h +index 6c6d561e394817c7..5ddd83224bc8eb77 100644 +--- a/sysdeps/i386/nptl/tcb-access.h ++++ b/sysdeps/i386/nptl/tcb-access.h +@@ -41,6 +41,8 @@ + } \ + __value; }) + ++/* THREAD_GETMEM already forces a read. */ ++#define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member) + + /* Same as THREAD_GETMEM, but the member offset can be non-constant. */ + #define THREAD_GETMEM_NC(descr, member, idx) \ +diff --git a/sysdeps/nptl/tcb-access.h b/sysdeps/nptl/tcb-access.h +index b4137b8ab8067915..bbe20b7225b060fd 100644 +--- a/sysdeps/nptl/tcb-access.h ++++ b/sysdeps/nptl/tcb-access.h +@@ -22,6 +22,8 @@ + + #define THREAD_GETMEM(descr, member) \ + descr->member ++#define THREAD_GETMEM_VOLATILE(descr, member) \ ++ (*(volatile __typeof (descr->member) *)&descr->member) + #define THREAD_GETMEM_NC(descr, member, idx) \ + descr->member[idx] + #define THREAD_SETMEM(descr, member, value) \ +diff --git a/sysdeps/x86_64/nptl/tcb-access.h b/sysdeps/x86_64/nptl/tcb-access.h +index 18848a729d16a4f5..e4d2d07a9b218025 100644 +--- a/sysdeps/x86_64/nptl/tcb-access.h ++++ b/sysdeps/x86_64/nptl/tcb-access.h +@@ -39,6 +39,8 @@ + } \ + __value; }) + ++/* THREAD_GETMEM already forces a read. */ ++#define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member) + + /* Same as THREAD_GETMEM, but the member offset can be non-constant. */ + # define THREAD_GETMEM_NC(descr, member, idx) \ diff --git a/SOURCES/glibc-rh2024347-7.patch b/SOURCES/glibc-rh2024347-7.patch new file mode 100644 index 0000000..b0d158b --- /dev/null +++ b/SOURCES/glibc-rh2024347-7.patch @@ -0,0 +1,1130 @@ +commit 95e114a0919d844d8fe07839cb6538b7f5ee920e +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Add rseq registration + + The rseq area is placed directly into struct pthread. rseq + registration failure is not treated as an error, so it is possible + that threads run with inconsistent registration status. + + is not yet installed as a public header. + + Co-Authored-By: Mathieu Desnoyers + Reviewed-by: Szabolcs Nagy + Reviewed-by: Siddhesh Poyarekar + +diff --git a/nptl/descr.h b/nptl/descr.h +index 57be5b4fef564b36..dabf980e29615db3 100644 +--- a/nptl/descr.h ++++ b/nptl/descr.h +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + #ifndef TCB_ALIGNMENT + # define TCB_ALIGNMENT 32 +@@ -407,6 +408,9 @@ struct pthread + /* Used on strsignal. */ + struct tls_internal_t tls_state; + ++ /* rseq area registered with the kernel. */ ++ struct rseq rseq_area; ++ + /* This member must be last. */ + char end_padding[]; + +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index 3db0c9fdf40ae2bf..d2b40924dafad316 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include "libioP.h" + #include + #include +@@ -367,6 +368,9 @@ start_thread (void *arg) + /* Initialize pointers to locale data. */ + __ctype_init (); + ++ /* Register rseq TLS to the kernel. */ ++ rseq_register_current_thread (pd); ++ + #ifndef __ASSUME_SET_ROBUST_LIST + if (__nptl_set_robust_list_avail) + #endif +@@ -572,6 +576,15 @@ out: + process is really dead since 'clone' got passed the CLONE_CHILD_CLEARTID + flag. The 'tid' field in the TCB will be set to zero. + ++ rseq TLS is still registered at this point. Rely on implicit ++ unregistration performed by the kernel on thread teardown. This is not a ++ problem because the rseq TLS lives on the stack, and the stack outlives ++ the thread. If TCB allocation is ever changed, additional steps may be ++ required, such as performing explicit rseq unregistration before ++ reclaiming the rseq TLS area memory. It is NOT sufficient to block ++ signals because the kernel may write to the rseq area even without ++ signals. ++ + The exit code is zero since in case all threads exit by calling + 'pthread_exit' the exit status must be 0 (zero). */ + while (1) +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index ca494dd3a52c4ebf..fedb876fdb2642d2 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #ifndef __ASSUME_SET_ROBUST_LIST + bool __nptl_set_robust_list_avail; +@@ -57,11 +58,12 @@ __tls_pre_init_tp (void) + void + __tls_init_tp (void) + { ++ struct pthread *pd = THREAD_SELF; ++ + /* Set up thread stack list management. */ +- list_add (&THREAD_SELF->list, &GL (dl_stack_user)); ++ list_add (&pd->list, &GL (dl_stack_user)); + + /* Early initialization of the TCB. */ +- struct pthread *pd = THREAD_SELF; + pd->tid = INTERNAL_SYSCALL_CALL (set_tid_address, &pd->tid); + THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]); + THREAD_SETMEM (pd, user_stack, true); +@@ -90,6 +92,8 @@ __tls_init_tp (void) + } + } + ++ rseq_register_current_thread (pd); ++ + /* Set initial thread's stack block from 0 up to __libc_stack_end. + It will be bigger than it actually is, but for unwind.c/pt-longjmp.c + purposes this is good enough. */ +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 76ad06361c4323d7..f84ccd6bbb3b16ad 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -130,7 +130,10 @@ ifeq ($(have-GLIBC_2.27)$(build-shared),yesyes) + tests += tst-ofdlocks-compat + endif + +-tests-internal += tst-sigcontext-get_pc ++tests-internal += \ ++ tst-rseq \ ++ tst-sigcontext-get_pc \ ++ # tests-internal + + tests-time64 += \ + tst-adjtimex-time64 \ +@@ -356,4 +359,8 @@ endif + + ifeq ($(subdir),nptl) + tests += tst-align-clone tst-getpid1 ++ ++# tst-rseq-nptl is an internal test because it requires a definition of ++# __NR_rseq from the internal system call list. ++tests-internal += tst-rseq-nptl + endif +diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/rseq.h b/sysdeps/unix/sysv/linux/aarch64/bits/rseq.h +new file mode 100644 +index 0000000000000000..9ba92725c76b9d4f +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/aarch64/bits/rseq.h +@@ -0,0 +1,43 @@ ++/* Restartable Sequences Linux aarch64 architecture header. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ aarch64 -mbig-endian generates mixed endianness code vs data: ++ little-endian code and big-endian data. Ensure the RSEQ_SIG signature ++ matches code endianness. */ ++ ++#define RSEQ_SIG_CODE 0xd428bc00 /* BRK #0x45E0. */ ++ ++#ifdef __AARCH64EB__ ++# define RSEQ_SIG_DATA 0x00bc28d4 /* BRK #0x45E0. */ ++#else ++# define RSEQ_SIG_DATA RSEQ_SIG_CODE ++#endif ++ ++#define RSEQ_SIG RSEQ_SIG_DATA +diff --git a/sysdeps/unix/sysv/linux/arm/bits/rseq.h b/sysdeps/unix/sysv/linux/arm/bits/rseq.h +new file mode 100644 +index 0000000000000000..0542b26f6a023dec +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/arm/bits/rseq.h +@@ -0,0 +1,83 @@ ++/* Restartable Sequences Linux arm architecture header. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* ++ RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ - ARM little endian ++ ++ RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand ++ value 0x5de3. This traps if user-space reaches this instruction by mistake, ++ and the uncommon operand ensures the kernel does not move the instruction ++ pointer to attacker-controlled code on rseq abort. ++ ++ The instruction pattern in the A32 instruction set is: ++ ++ e7f5def3 udf #24035 ; 0x5de3 ++ ++ This translates to the following instruction pattern in the T16 instruction ++ set: ++ ++ little endian: ++ def3 udf #243 ; 0xf3 ++ e7f5 b.n <7f5> ++ ++ - ARMv6+ big endian (BE8): ++ ++ ARMv6+ -mbig-endian generates mixed endianness code vs data: little-endian ++ code and big-endian data. The data value of the signature needs to have its ++ byte order reversed to generate the trap instruction: ++ ++ Data: 0xf3def5e7 ++ ++ Translates to this A32 instruction pattern: ++ ++ e7f5def3 udf #24035 ; 0x5de3 ++ ++ Translates to this T16 instruction pattern: ++ ++ def3 udf #243 ; 0xf3 ++ e7f5 b.n <7f5> ++ ++ - Prior to ARMv6 big endian (BE32): ++ ++ Prior to ARMv6, -mbig-endian generates big-endian code and data ++ (which match), so the endianness of the data representation of the ++ signature should not be reversed. However, the choice between BE32 ++ and BE8 is done by the linker, so we cannot know whether code and ++ data endianness will be mixed before the linker is invoked. So rather ++ than try to play tricks with the linker, the rseq signature is simply ++ data (not a trap instruction) prior to ARMv6 on big endian. This is ++ why the signature is expressed as data (.word) rather than as ++ instruction (.inst) in assembler. */ ++ ++#ifdef __ARMEB__ ++# define RSEQ_SIG 0xf3def5e7 /* udf #24035 ; 0x5de3 (ARMv6+) */ ++#else ++# define RSEQ_SIG 0xe7f5def3 /* udf #24035 ; 0x5de3 */ ++#endif +diff --git a/sysdeps/unix/sysv/linux/bits/rseq.h b/sysdeps/unix/sysv/linux/bits/rseq.h +new file mode 100644 +index 0000000000000000..46cf5d1c743f25eb +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/bits/rseq.h +@@ -0,0 +1,29 @@ ++/* Restartable Sequences architecture header. Stub version. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. */ +diff --git a/sysdeps/unix/sysv/linux/mips/bits/rseq.h b/sysdeps/unix/sysv/linux/mips/bits/rseq.h +new file mode 100644 +index 0000000000000000..a9defee568ae04a5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/mips/bits/rseq.h +@@ -0,0 +1,62 @@ ++/* Restartable Sequences Linux mips architecture header. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ RSEQ_SIG uses the break instruction. The instruction pattern is: ++ ++ On MIPS: ++ 0350000d break 0x350 ++ ++ On nanoMIPS: ++ 00100350 break 0x350 ++ ++ On microMIPS: ++ 0000d407 break 0x350 ++ ++ For nanoMIPS32 and microMIPS, the instruction stream is encoded as ++ 16-bit halfwords, so the signature halfwords need to be swapped ++ accordingly for little-endian. */ ++ ++#if defined (__nanomips__) ++# ifdef __MIPSEL__ ++# define RSEQ_SIG 0x03500010 ++# else ++# define RSEQ_SIG 0x00100350 ++# endif ++#elif defined (__mips_micromips) ++# ifdef __MIPSEL__ ++# define RSEQ_SIG 0xd4070000 ++# else ++# define RSEQ_SIG 0x0000d407 ++# endif ++#elif defined (__mips__) ++# define RSEQ_SIG 0x0350000d ++#else ++/* Unknown MIPS architecture. */ ++#endif +diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/rseq.h b/sysdeps/unix/sysv/linux/powerpc/bits/rseq.h +new file mode 100644 +index 0000000000000000..05b3cf7b8fe75b92 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/powerpc/bits/rseq.h +@@ -0,0 +1,37 @@ ++/* Restartable Sequences Linux powerpc architecture header. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ RSEQ_SIG uses the following trap instruction: ++ ++ powerpc-be: 0f e5 00 0b twui r5,11 ++ powerpc64-le: 0b 00 e5 0f twui r5,11 ++ powerpc64-be: 0f e5 00 0b twui r5,11 */ ++ ++#define RSEQ_SIG 0x0fe5000b +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +new file mode 100644 +index 0000000000000000..909f5478251d3d13 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -0,0 +1,45 @@ ++/* Restartable Sequences internal API. Linux implementation. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef RSEQ_INTERNAL_H ++#define RSEQ_INTERNAL_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef RSEQ_SIG ++static inline void ++rseq_register_current_thread (struct pthread *self) ++{ ++ int ret = INTERNAL_SYSCALL_CALL (rseq, ++ &self->rseq_area, sizeof (self->rseq_area), ++ 0, RSEQ_SIG); ++ if (INTERNAL_SYSCALL_ERROR_P (ret)) ++ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++} ++#else /* RSEQ_SIG */ ++static inline void ++rseq_register_current_thread (struct pthread *self) ++{ ++ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++} ++#endif /* RSEQ_SIG */ ++ ++#endif /* rseq-internal.h */ +diff --git a/sysdeps/unix/sysv/linux/s390/bits/rseq.h b/sysdeps/unix/sysv/linux/s390/bits/rseq.h +new file mode 100644 +index 0000000000000000..3030e38f403784b3 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/s390/bits/rseq.h +@@ -0,0 +1,37 @@ ++/* Restartable Sequences Linux s390 architecture header. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ RSEQ_SIG uses the trap4 instruction. As Linux does not make use of the ++ access-register mode nor the linkage stack this instruction will always ++ cause a special-operation exception (the trap-enabled bit in the DUCT ++ is and will stay 0). The instruction pattern is ++ b2 ff 0f ff trap4 4095(%r0) */ ++ ++#define RSEQ_SIG 0xB2FF0FFF +diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h +new file mode 100644 +index 0000000000000000..c8edff50d40e29b6 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sys/rseq.h +@@ -0,0 +1,174 @@ ++/* Restartable Sequences exported symbols. Linux header. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++#define _SYS_RSEQ_H 1 ++ ++/* Architecture-specific rseq signature. */ ++#include ++ ++#include ++#include ++#include ++ ++#ifdef __has_include ++# if __has_include ("linux/rseq.h") ++# define __GLIBC_HAVE_KERNEL_RSEQ ++# endif ++#else ++# include ++# if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 18, 0) ++# define __GLIBC_HAVE_KERNEL_RSEQ ++# endif ++#endif ++ ++#ifdef __GLIBC_HAVE_KERNEL_RSEQ ++/* We use the structures declarations from the kernel headers. */ ++# include ++#else /* __GLIBC_HAVE_KERNEL_RSEQ */ ++/* We use a copy of the include/uapi/linux/rseq.h kernel header. */ ++ ++enum rseq_cpu_id_state ++ { ++ RSEQ_CPU_ID_UNINITIALIZED = -1, ++ RSEQ_CPU_ID_REGISTRATION_FAILED = -2, ++ }; ++ ++enum rseq_flags ++ { ++ RSEQ_FLAG_UNREGISTER = (1 << 0), ++ }; ++ ++enum rseq_cs_flags_bit ++ { ++ RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0, ++ RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1, ++ RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2, ++ }; ++ ++enum rseq_cs_flags ++ { ++ RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = ++ (1U << RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT), ++ RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = ++ (1U << RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT), ++ RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = ++ (1U << RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT), ++ }; ++ ++/* struct rseq_cs is aligned on 32 bytes to ensure it is always ++ contained within a single cache-line. It is usually declared as ++ link-time constant data. */ ++struct rseq_cs ++ { ++ /* Version of this structure. */ ++ uint32_t version; ++ /* enum rseq_cs_flags. */ ++ uint32_t flags; ++ uint64_t start_ip; ++ /* Offset from start_ip. */ ++ uint64_t post_commit_offset; ++ uint64_t abort_ip; ++ } __attribute__ ((__aligned__ (32))); ++ ++/* struct rseq is aligned on 32 bytes to ensure it is always ++ contained within a single cache-line. ++ ++ A single struct rseq per thread is allowed. */ ++struct rseq ++ { ++ /* Restartable sequences cpu_id_start field. Updated by the ++ kernel. Read by user-space with single-copy atomicity ++ semantics. This field should only be read by the thread which ++ registered this data structure. Aligned on 32-bit. Always ++ contains a value in the range of possible CPUs, although the ++ value may not be the actual current CPU (e.g. if rseq is not ++ initialized). This CPU number value should always be compared ++ against the value of the cpu_id field before performing a rseq ++ commit or returning a value read from a data structure indexed ++ using the cpu_id_start value. */ ++ uint32_t cpu_id_start; ++ /* Restartable sequences cpu_id field. Updated by the kernel. ++ Read by user-space with single-copy atomicity semantics. This ++ field should only be read by the thread which registered this ++ data structure. Aligned on 32-bit. Values ++ RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED ++ have a special semantic: the former means "rseq uninitialized", ++ and latter means "rseq initialization failed". This value is ++ meant to be read within rseq critical sections and compared ++ with the cpu_id_start value previously read, before performing ++ the commit instruction, or read and compared with the ++ cpu_id_start value before returning a value loaded from a data ++ structure indexed using the cpu_id_start value. */ ++ uint32_t cpu_id; ++ /* Restartable sequences rseq_cs field. ++ ++ Contains NULL when no critical section is active for the current ++ thread, or holds a pointer to the currently active struct rseq_cs. ++ ++ Updated by user-space, which sets the address of the currently ++ active rseq_cs at the beginning of assembly instruction sequence ++ block, and set to NULL by the kernel when it restarts an assembly ++ instruction sequence block, as well as when the kernel detects that ++ it is preempting or delivering a signal outside of the range ++ targeted by the rseq_cs. Also needs to be set to NULL by user-space ++ before reclaiming memory that contains the targeted struct rseq_cs. ++ ++ Read and set by the kernel. Set by user-space with single-copy ++ atomicity semantics. This field should only be updated by the ++ thread which registered this data structure. Aligned on 64-bit. */ ++ union ++ { ++ uint64_t ptr64; ++# ifdef __LP64__ ++ uint64_t ptr; ++# else /* __LP64__ */ ++ struct ++ { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ uint32_t padding; /* Initialized to zero. */ ++ uint32_t ptr32; ++# else /* LITTLE */ ++ uint32_t ptr32; ++ uint32_t padding; /* Initialized to zero. */ ++# endif /* ENDIAN */ ++ } ptr; ++# endif /* __LP64__ */ ++ } rseq_cs; ++ ++ /* Restartable sequences flags field. ++ ++ This field should only be updated by the thread which ++ registered this data structure. Read by the kernel. ++ Mainly used for single-stepping through rseq critical sections ++ with debuggers. ++ ++ - RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT ++ Inhibit instruction sequence block restart on preemption ++ for this thread. ++ - RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL ++ Inhibit instruction sequence block restart on signal ++ delivery for this thread. ++ - RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE ++ Inhibit instruction sequence block restart on migration for ++ this thread. */ ++ uint32_t flags; ++ } __attribute__ ((__aligned__ (32))); ++ ++#endif /* __GLIBC_HAVE_KERNEL_RSEQ */ ++ ++#endif /* sys/rseq.h */ +diff --git a/sysdeps/unix/sysv/linux/tst-rseq-nptl.c b/sysdeps/unix/sysv/linux/tst-rseq-nptl.c +new file mode 100644 +index 0000000000000000..d31d94445caa9ee3 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-rseq-nptl.c +@@ -0,0 +1,260 @@ ++/* Restartable Sequences NPTL test. ++ Copyright (C) 2021 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 ++ . */ ++ ++/* These tests validate that rseq is registered from various execution ++ contexts (main thread, destructor, other threads, other threads created ++ from destructor, forked process (without exec), pthread_atfork handlers, ++ pthread setspecific destructors, signal handlers, atexit handlers). ++ ++ See the Linux kernel selftests for extensive rseq stress-tests. */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef RSEQ_SIG ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include "tst-rseq.h" ++ ++static pthread_key_t rseq_test_key; ++ ++static void ++atfork_prepare (void) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in pthread atfork prepare\n"); ++ support_record_failure (); ++ } ++} ++ ++static void ++atfork_parent (void) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in pthread atfork parent\n"); ++ support_record_failure (); ++ } ++} ++ ++static void ++atfork_child (void) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in pthread atfork child\n"); ++ support_record_failure (); ++ } ++} ++ ++static void ++rseq_key_destructor (void *arg) ++{ ++ /* Cannot use deferred failure reporting after main returns. */ ++ if (!rseq_thread_registered ()) ++ FAIL_EXIT1 ("rseq not registered in pthread key destructor"); ++} ++ ++static void ++atexit_handler (void) ++{ ++ /* Cannot use deferred failure reporting after main returns. */ ++ if (!rseq_thread_registered ()) ++ FAIL_EXIT1 ("rseq not registered in atexit handler"); ++} ++ ++/* Used to avoid -Werror=stringop-overread warning with ++ pthread_setspecific and GCC 11. */ ++static char one = 1; ++ ++static void ++do_rseq_main_test (void) ++{ ++ TEST_COMPARE (atexit (atexit_handler), 0); ++ rseq_test_key = xpthread_key_create (rseq_key_destructor); ++ TEST_COMPARE (pthread_atfork (atfork_prepare, atfork_parent, atfork_child), 0); ++ xraise (SIGUSR1); ++ TEST_COMPARE (pthread_setspecific (rseq_test_key, &one), 0); ++ TEST_VERIFY_EXIT (rseq_thread_registered ()); ++} ++ ++static void ++cancel_routine (void *arg) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in cancel routine\n"); ++ support_record_failure (); ++ } ++} ++ ++static pthread_barrier_t cancel_thread_barrier; ++static pthread_cond_t cancel_thread_cond = PTHREAD_COND_INITIALIZER; ++static pthread_mutex_t cancel_thread_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++static void ++test_cancel_thread (void) ++{ ++ pthread_cleanup_push (cancel_routine, NULL); ++ (void) xpthread_barrier_wait (&cancel_thread_barrier); ++ /* Wait forever until cancellation. */ ++ xpthread_cond_wait (&cancel_thread_cond, &cancel_thread_mutex); ++ pthread_cleanup_pop (0); ++} ++ ++static void * ++thread_function (void * arg) ++{ ++ int i = (int) (intptr_t) arg; ++ ++ xraise (SIGUSR1); ++ if (i == 0) ++ test_cancel_thread (); ++ TEST_COMPARE (pthread_setspecific (rseq_test_key, &one), 0); ++ return rseq_thread_registered () ? NULL : (void *) 1l; ++} ++ ++static void ++sighandler (int sig) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in signal handler\n"); ++ support_record_failure (); ++ } ++} ++ ++static void ++setup_signals (void) ++{ ++ struct sigaction sa; ++ ++ sigemptyset (&sa.sa_mask); ++ sigaddset (&sa.sa_mask, SIGUSR1); ++ sa.sa_flags = 0; ++ sa.sa_handler = sighandler; ++ xsigaction (SIGUSR1, &sa, NULL); ++} ++ ++static int ++do_rseq_threads_test (int nr_threads) ++{ ++ pthread_t th[nr_threads]; ++ int i; ++ int result = 0; ++ ++ xpthread_barrier_init (&cancel_thread_barrier, NULL, 2); ++ ++ for (i = 0; i < nr_threads; ++i) ++ th[i] = xpthread_create (NULL, thread_function, ++ (void *) (intptr_t) i); ++ ++ (void) xpthread_barrier_wait (&cancel_thread_barrier); ++ ++ xpthread_cancel (th[0]); ++ ++ for (i = 0; i < nr_threads; ++i) ++ { ++ void *v; ++ ++ v = xpthread_join (th[i]); ++ if (i != 0 && v != NULL) ++ { ++ printf ("error: join %d successful, but child failed\n", i); ++ result = 1; ++ } ++ else if (i == 0 && v == NULL) ++ { ++ printf ("error: join %d successful, child did not fail as expected\n", i); ++ result = 1; ++ } ++ } ++ ++ xpthread_barrier_destroy (&cancel_thread_barrier); ++ ++ return result; ++} ++ ++static void ++subprocess_callback (void *closure) ++{ ++ do_rseq_main_test (); ++} ++ ++static void ++do_rseq_fork_test (void) ++{ ++ support_isolate_in_subprocess (subprocess_callback, NULL); ++} ++ ++static int ++do_rseq_test (void) ++{ ++ int t[] = { 1, 2, 6, 5, 4, 3, 50 }; ++ int i, result = 0; ++ ++ if (!rseq_available ()) ++ FAIL_UNSUPPORTED ("kernel does not support rseq, skipping test"); ++ setup_signals (); ++ xraise (SIGUSR1); ++ do_rseq_main_test (); ++ for (i = 0; i < array_length (t); i++) ++ if (do_rseq_threads_test (t[i])) ++ result = 1; ++ do_rseq_fork_test (); ++ return result; ++} ++ ++static void __attribute__ ((destructor)) ++do_rseq_destructor_test (void) ++{ ++ /* Cannot use deferred failure reporting after main returns. */ ++ if (do_rseq_test ()) ++ FAIL_EXIT1 ("rseq not registered within destructor"); ++ xpthread_key_delete (rseq_test_key); ++} ++ ++#else /* RSEQ_SIG */ ++static int ++do_rseq_test (void) ++{ ++ FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test"); ++ return 0; ++} ++#endif /* RSEQ_SIG */ ++ ++static int ++do_test (void) ++{ ++ return do_rseq_test (); ++} ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c +new file mode 100644 +index 0000000000000000..926376b6a5446ece +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-rseq.c +@@ -0,0 +1,64 @@ ++/* Restartable Sequences single-threaded tests. ++ Copyright (C) 2021 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 ++ . */ ++ ++/* These tests validate that rseq is registered from main in an executable ++ not linked against libpthread. */ ++ ++#include ++#include ++#include ++#include ++ ++#ifdef RSEQ_SIG ++# include ++# include ++# include ++# include ++# include ++# include "tst-rseq.h" ++ ++static void ++do_rseq_main_test (void) ++{ ++ TEST_VERIFY_EXIT (rseq_thread_registered ()); ++} ++ ++static void ++do_rseq_test (void) ++{ ++ if (!rseq_available ()) ++ { ++ FAIL_UNSUPPORTED ("kernel does not support rseq, skipping test"); ++ } ++ do_rseq_main_test (); ++} ++#else /* RSEQ_SIG */ ++static void ++do_rseq_test (void) ++{ ++ FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test"); ++} ++#endif /* RSEQ_SIG */ ++ ++static int ++do_test (void) ++{ ++ do_rseq_test (); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.h b/sysdeps/unix/sysv/linux/tst-rseq.h +new file mode 100644 +index 0000000000000000..a476c316fc2671a0 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-rseq.h +@@ -0,0 +1,57 @@ ++/* Restartable Sequences tests header. ++ Copyright (C) 2021 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static inline bool ++rseq_thread_registered (void) ++{ ++ return THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id) >= 0; ++} ++ ++static inline int ++sys_rseq (struct rseq *rseq_abi, uint32_t rseq_len, int flags, uint32_t sig) ++{ ++ return syscall (__NR_rseq, rseq_abi, rseq_len, flags, sig); ++} ++ ++static inline bool ++rseq_available (void) ++{ ++ int rc; ++ ++ rc = sys_rseq (NULL, 0, 0, 0); ++ if (rc != -1) ++ FAIL_EXIT1 ("Unexpected rseq return value %d", rc); ++ switch (errno) ++ { ++ case ENOSYS: ++ return false; ++ case EINVAL: ++ /* rseq is implemented, but detected an invalid rseq_len parameter. */ ++ return true; ++ default: ++ FAIL_EXIT1 ("Unexpected rseq error %s", strerror (errno)); ++ } ++} +diff --git a/sysdeps/unix/sysv/linux/x86/bits/rseq.h b/sysdeps/unix/sysv/linux/x86/bits/rseq.h +new file mode 100644 +index 0000000000000000..9fc909e7c8a25bbb +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86/bits/rseq.h +@@ -0,0 +1,30 @@ ++/* Restartable Sequences Linux x86 architecture header. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ RSEQ_SIG is used with the following reserved undefined instructions, which ++ trap in user-space: ++ ++ x86-32: 0f b9 3d 53 30 05 53 ud1 0x53053053,%edi ++ x86-64: 0f b9 3d 53 30 05 53 ud1 0x53053053(%rip),%edi */ ++ ++#define RSEQ_SIG 0x53053053 diff --git a/SOURCES/glibc-rh2024347-8.patch b/SOURCES/glibc-rh2024347-8.patch new file mode 100644 index 0000000..1436fe1 --- /dev/null +++ b/SOURCES/glibc-rh2024347-8.patch @@ -0,0 +1,43 @@ +commit 1d350aa06091211863e41169729cee1bca39f72f +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + Linux: Use rseq to accelerate sched_getcpu + + Co-Authored-By: Mathieu Desnoyers + Reviewed-by: Szabolcs Nagy + +diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c +index c41e986f2cab5e42..6f78edaea1495342 100644 +--- a/sysdeps/unix/sysv/linux/sched_getcpu.c ++++ b/sysdeps/unix/sysv/linux/sched_getcpu.c +@@ -20,8 +20,8 @@ + #include + #include + +-int +-sched_getcpu (void) ++static int ++vsyscall_sched_getcpu (void) + { + unsigned int cpu; + int r = -1; +@@ -32,3 +32,18 @@ sched_getcpu (void) + #endif + return r == -1 ? r : cpu; + } ++ ++#ifdef RSEQ_SIG ++int ++sched_getcpu (void) ++{ ++ int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id); ++ return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu (); ++} ++#else /* RSEQ_SIG */ ++int ++sched_getcpu (void) ++{ ++ return vsyscall_sched_getcpu (); ++} ++#endif /* RSEQ_SIG */ diff --git a/SOURCES/glibc-rh2024347-9.patch b/SOURCES/glibc-rh2024347-9.patch new file mode 100644 index 0000000..af25983 --- /dev/null +++ b/SOURCES/glibc-rh2024347-9.patch @@ -0,0 +1,278 @@ +commit e3e589829d16af9f7e73c7b70f74f3c5d5003e45 +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Add glibc.pthread.rseq tunable to control rseq registration + + This tunable allows applications to register the rseq area instead + of glibc. + + Reviewed-by: Szabolcs Nagy + Reviewed-by: Siddhesh Poyarekar + +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 658547c6137bf177..1f5c410288eeecec 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -413,6 +413,16 @@ The value is measured in bytes. The default is @samp{41943040} + (fourty mibibytes). + @end deftp + ++@deftp Tunable glibc.pthread.rseq ++The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable ++restartable sequences support in @theglibc{}. This enables applications ++to perform direct restartable sequence registration with the kernel. ++The default is @samp{1}, which means that @theglibc{} performs ++registration on behalf of the application. ++ ++Restartable sequences are a Linux-specific extension. ++@end deftp ++ + @node Hardware Capability Tunables + @section Hardware Capability Tunables + @cindex hardware capability tunables +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index d2b40924dafad316..f405fa356c2955ce 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -369,7 +369,10 @@ start_thread (void *arg) + __ctype_init (); + + /* Register rseq TLS to the kernel. */ +- rseq_register_current_thread (pd); ++ { ++ bool do_rseq = THREAD_GETMEM (pd, flags) & ATTR_FLAG_DO_RSEQ; ++ rseq_register_current_thread (pd, do_rseq); ++ } + + #ifndef __ASSUME_SET_ROBUST_LIST + if (__nptl_set_robust_list_avail) +@@ -678,6 +681,11 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr, + pd->flags = ((iattr->flags & ~(ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)) + | (self->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))); + ++ /* Inherit rseq registration state. Without seccomp filters, rseq ++ registration will either always fail or always succeed. */ ++ if ((int) THREAD_GETMEM_VOLATILE (self, rseq_area.cpu_id) >= 0) ++ pd->flags |= ATTR_FLAG_DO_RSEQ; ++ + /* Initialize the field for the ID of the thread which is waiting + for us. This is a self-reference in case the thread is created + detached. */ +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index fedb876fdb2642d2..b39dfbff2c6678d5 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -23,6 +23,9 @@ + #include + #include + ++#define TUNABLE_NAMESPACE pthread ++#include ++ + #ifndef __ASSUME_SET_ROBUST_LIST + bool __nptl_set_robust_list_avail; + rtld_hidden_data_def (__nptl_set_robust_list_avail) +@@ -92,7 +95,13 @@ __tls_init_tp (void) + } + } + +- rseq_register_current_thread (pd); ++ { ++ bool do_rseq = true; ++#if HAVE_TUNABLES ++ do_rseq = TUNABLE_GET (rseq, int, NULL); ++#endif ++ rseq_register_current_thread (pd, do_rseq); ++ } + + /* Set initial thread's stack block from 0 up to __libc_stack_end. + It will be bigger than it actually is, but for unwind.c/pt-longjmp.c +diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list +index ac5d053298725468..d24f4be0d08ba407 100644 +--- a/sysdeps/nptl/dl-tunables.list ++++ b/sysdeps/nptl/dl-tunables.list +@@ -27,5 +27,11 @@ glibc { + type: SIZE_T + default: 41943040 + } ++ rseq { ++ type: INT_32 ++ minval: 0 ++ maxval: 1 ++ default: 1 ++ } + } + } +diff --git a/sysdeps/nptl/internaltypes.h b/sysdeps/nptl/internaltypes.h +index 50a2ad19ae7210ae..8205c6d15a918952 100644 +--- a/sysdeps/nptl/internaltypes.h ++++ b/sysdeps/nptl/internaltypes.h +@@ -49,6 +49,7 @@ struct pthread_attr + #define ATTR_FLAG_OLDATTR 0x0010 + #define ATTR_FLAG_SCHED_SET 0x0020 + #define ATTR_FLAG_POLICY_SET 0x0040 ++#define ATTR_FLAG_DO_RSEQ 0x0080 + + /* Used to allocate a pthread_attr_t object which is also accessed + internally. */ +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index f84ccd6bbb3b16ad..d30d21898b402d1e 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -135,6 +135,12 @@ tests-internal += \ + tst-sigcontext-get_pc \ + # tests-internal + ++ifneq (no,$(have-tunables)) ++tests-internal += \ ++ tst-rseq-disable \ ++ # tests-internal $(have-tunables) ++endif ++ + tests-time64 += \ + tst-adjtimex-time64 \ + tst-clock_adjtime-time64 \ +@@ -226,6 +232,8 @@ $(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-consts.py + < /dev/null > $@ 2>&1; $(evaluate-test) + $(objpfx)tst-mman-consts.out: $(sysdeps-linux-python-deps) + ++tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0 ++ + endif # $(subdir) == misc + + ifeq ($(subdir),time) +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index 909f5478251d3d13..15bc7ffd6eda632d 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -21,22 +21,27 @@ + #include + #include + #include ++#include + #include + #include + + #ifdef RSEQ_SIG + static inline void +-rseq_register_current_thread (struct pthread *self) ++rseq_register_current_thread (struct pthread *self, bool do_rseq) + { +- int ret = INTERNAL_SYSCALL_CALL (rseq, +- &self->rseq_area, sizeof (self->rseq_area), +- 0, RSEQ_SIG); +- if (INTERNAL_SYSCALL_ERROR_P (ret)) +- THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++ if (do_rseq) ++ { ++ int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area, ++ sizeof (self->rseq_area), ++ 0, RSEQ_SIG); ++ if (!INTERNAL_SYSCALL_ERROR_P (ret)) ++ return; ++ } ++ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); + } + #else /* RSEQ_SIG */ + static inline void +-rseq_register_current_thread (struct pthread *self) ++rseq_register_current_thread (struct pthread *self, bool do_rseq) + { + THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); + } +diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c +new file mode 100644 +index 0000000000000000..000e351872fc2f76 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c +@@ -0,0 +1,89 @@ ++/* Test disabling of rseq registration via tunable. ++ Copyright (C) 2021 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef RSEQ_SIG ++ ++/* Check that rseq can be registered and has not been taken by glibc. */ ++static void ++check_rseq_disabled (void) ++{ ++ struct pthread *pd = THREAD_SELF; ++ TEST_COMPARE ((int) pd->rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++ ++ int ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area), ++ 0, RSEQ_SIG); ++ if (ret == 0) ++ { ++ ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area), ++ RSEQ_FLAG_UNREGISTER, RSEQ_SIG); ++ TEST_COMPARE (ret, 0); ++ pd->rseq_area.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; ++ } ++ else ++ { ++ TEST_VERIFY (errno != -EINVAL); ++ TEST_VERIFY (errno != -EBUSY); ++ } ++} ++ ++static void * ++thread_func (void *ignored) ++{ ++ check_rseq_disabled (); ++ return NULL; ++} ++ ++static void ++proc_func (void *ignored) ++{ ++ check_rseq_disabled (); ++} ++ ++static int ++do_test (void) ++{ ++ puts ("info: checking main thread"); ++ check_rseq_disabled (); ++ ++ puts ("info: checking main thread (2)"); ++ check_rseq_disabled (); ++ ++ puts ("info: checking new thread"); ++ xpthread_join (xpthread_create (NULL, thread_func, NULL)); ++ ++ puts ("info: checking subprocess"); ++ support_isolate_in_subprocess (proc_func, NULL); ++ ++ return 0; ++} ++#else /* !RSEQ_SIG */ ++static int ++do_test (void) ++{ ++ FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test"); ++} ++#endif ++ ++#include diff --git a/SOURCES/glibc-rh2027789.patch b/SOURCES/glibc-rh2027789.patch new file mode 100644 index 0000000..798d496 --- /dev/null +++ b/SOURCES/glibc-rh2027789.patch @@ -0,0 +1,23 @@ +Downstream-only patch from Mark Wielaard to avoid a +crash in backtrace if the vDSO is not available. + +Upstream, this code was removed in commit 82fd7314c7df8c5555dce02 +("powerpc: Remove backtrace implementation"), so patch is not needed +there. + +diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c +index 37de9b5bdd73c316..0ffa7509dfa4862a 100644 +--- a/sysdeps/powerpc/powerpc64/backtrace.c ++++ b/sysdeps/powerpc/powerpc64/backtrace.c +@@ -68,8 +68,9 @@ static inline bool + is_sigtramp_address (void *nip) + { + #ifdef HAVE_SIGTRAMP_RT64 +- if (nip == GLRO (dl_vdso_sigtramp_rt64) || +- nip == GLRO (dl_vdso_sigtramp_rt64) + 4) ++ if ((nip == GLRO (dl_vdso_sigtramp_rt64) || ++ nip == GLRO (dl_vdso_sigtramp_rt64) + 4) ++ && nip != NULL) + return true; + #endif + return false; diff --git a/SOURCES/glibc-rh2029410.patch b/SOURCES/glibc-rh2029410.patch new file mode 100644 index 0000000..256380a --- /dev/null +++ b/SOURCES/glibc-rh2029410.patch @@ -0,0 +1,143 @@ +commit ea5814467a02c9d2d7608b6445c5d60e2a81d3ee +Author: H.J. Lu +Date: Fri Dec 10 13:00:09 2021 -0800 + + x86-64: Remove LD_PREFER_MAP_32BIT_EXEC support [BZ #28656] + + Remove the LD_PREFER_MAP_32BIT_EXEC environment variable support since + the first PT_LOAD segment is no longer executable due to defaulting to + -z separate-code. + + This fixes [BZ #28656]. + + Reviewed-by: Florian Weimer + +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h +deleted file mode 100644 +index 5b9696e2de8e5482..0000000000000000 +--- a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h ++++ /dev/null +@@ -1,45 +0,0 @@ +-/* Optional code to distinguish library flavours. x86-64 version. +- Copyright (C) 2015-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#ifndef _DL_LIBRECON_H +- +-#include +- +-/* Recognizing extra environment variables. For 64-bit applications, +- branch prediction performance may be negatively impacted when the +- target of a branch is more than 4GB away from the branch. Add the +- Prefer_MAP_32BIT_EXEC bit so that mmap will try to map executable +- pages with MAP_32BIT first. NB: MAP_32BIT will map to lower 2GB, +- not lower 4GB, address. Prefer_MAP_32BIT_EXEC reduces bits available +- for address space layout randomization (ASLR). Prefer_MAP_32BIT_EXEC +- is always disabled for SUID programs and can be enabled by setting +- environment variable, LD_PREFER_MAP_32BIT_EXEC. */ +-#define EXTRA_LD_ENVVARS \ +- case 21: \ +- if (!__libc_enable_secure \ +- && memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \ +- GLRO(dl_x86_cpu_features).preferred[index_arch_Prefer_MAP_32BIT_EXEC] \ +- |= bit_arch_Prefer_MAP_32BIT_EXEC; \ +- break; +- +-/* Extra unsecure variables. The names are all stuffed in a single +- string which means they have to be terminated with a '\0' explicitly. */ +-#define EXTRA_UNSECURE_ENVVARS \ +- "LD_PREFER_MAP_32BIT_EXEC\0" +- +-#endif /* dl-librecon.h */ +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h b/sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h +deleted file mode 100644 +index 18177d2cb3ae645f..0000000000000000 +--- a/sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h ++++ /dev/null +@@ -1,42 +0,0 @@ +-/* Linux mmap system call. x86-64 version. +- Copyright (C) 2015-2021 Free Software Foundation, Inc. +- +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public License as +- published by the Free Software Foundation; either version 2.1 of the +- License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#ifndef MMAP_X86_64_INTERNAL_H +-#define MMAP_X86_64_INTERNAL_H +- +-#include +- +-/* If the Prefer_MAP_32BIT_EXEC bit is set, try to map executable pages +- with MAP_32BIT first. */ +-#define MMAP_PREPARE(addr, len, prot, flags, fd, offset) \ +- if ((addr) == NULL \ +- && ((prot) & PROT_EXEC) != 0 \ +- && HAS_ARCH_FEATURE (Prefer_MAP_32BIT_EXEC)) \ +- { \ +- void *ret = (void*) INLINE_SYSCALL_CALL (mmap, (addr), (len), \ +- (prot), \ +- (flags) | MAP_32BIT, \ +- (fd), (offset)); \ +- if (ret != MAP_FAILED) \ +- return ret; \ +- } +- +-#include_next +- +-#endif +diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c +index 00fe5045eb56eb07..58f2fad4323d5d91 100644 +--- a/sysdeps/x86/cpu-tunables.c ++++ b/sysdeps/x86/cpu-tunables.c +@@ -260,13 +260,6 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + 20); + } + break; +- case 21: +- { +- CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features, +- Prefer_MAP_32BIT_EXEC, +- disable, 21); +- } +- break; + case 23: + { + CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH +diff --git a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def +index d7c93f00c5928a30..3bdc76cf71007948 100644 +--- a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def ++++ b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def +@@ -26,7 +26,6 @@ BIT (I586) + BIT (I686) + BIT (Slow_SSE4_2) + BIT (AVX_Fast_Unaligned_Load) +-BIT (Prefer_MAP_32BIT_EXEC) + BIT (Prefer_No_VZEROUPPER) + BIT (Prefer_ERMS) + BIT (Prefer_No_AVX512) diff --git a/SOURCES/glibc-rh2032647-1.patch b/SOURCES/glibc-rh2032647-1.patch new file mode 100644 index 0000000..ebc11b1 --- /dev/null +++ b/SOURCES/glibc-rh2032647-1.patch @@ -0,0 +1,2024 @@ +commit e6fd79f3795d46dfb583e124be49fc063bc3d58b +Author: Chung-Lin Tang +Date: Thu Oct 21 21:41:21 2021 +0800 + + elf: Testing infrastructure for ld.so DSO sorting (BZ #17645) + + This is the first of a 2-part patch set that fixes slow DSO sorting behavior in + the dynamic loader, as reported in BZ #17645. In order to facilitate such a + large modification to the dynamic loader, this first patch implements a testing + framework for validating shared object sorting behavior, to enable comparison + between old/new sorting algorithms, and any later enhancements. + + This testing infrastructure consists of a Python script + scripts/dso-ordering-test.py' which takes in a description language, consisting + of strings that describe a set of link dependency relations between DSOs, and + generates testcase programs and Makefile fragments to automatically test the + described situation, for example: + + a->b->c->d # four objects linked one after another + + a->[bc]->d;b->c # a depends on b and c, which both depend on d, + # b depends on c (b,c linked to object a in fixed order) + + a->b->c;{+a;%a;-a} # a, b, c serially dependent, main program uses + # dlopen/dlsym/dlclose on object a + + a->b->c;{}!->[abc] # a, b, c serially dependent; multiple tests generated + # to test all permutations of a, b, c ordering linked + # to main program + + (Above is just a short description of what the script can do, more + documentation is in the script comments.) + + Two files containing several new tests, elf/dso-sort-tests-[12].def are added, + including test scenarios for BZ #15311 and Redhat issue #1162810 [1]. + + Due to the nature of dynamic loader tests, where the sorting behavior and test + output occurs before/after main(), generating testcases to use + support/test-driver.c does not suffice to control meaningful timeout for ld.so. + Therefore a new utility program 'support/test-run-command', based on + test-driver.c/support_test_main.c has been added. This does the same testcase + control, but for a program specified through a command-line rather than at the + source code level. This utility is used to run the dynamic loader testcases + generated by dso-ordering-test.py. + + [1] https://bugzilla.redhat.com/show_bug.cgi?id=1162810 + + Signed-off-by: Chung-Lin Tang + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/Makefile b/elf/Makefile +index 3e7debdd81baafe0..8dd2b24328113536 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -471,6 +471,21 @@ tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \ + $(objpfx)tst-unused-dep-cmp.out + endif + ++# DSO sorting tests: ++# The dso-ordering-test.py script generates testcase source files in $(objpfx), ++# creating a $(objpfx)-dir for each testcase, and creates a ++# Makefile fragment to be included. ++define include_dsosort_tests ++$(objpfx)$(1).generated-makefile: $(1) ++ $(PYTHON) $(..)scripts/dso-ordering-test.py \ ++ --description-file $$< --objpfx $(objpfx) --output-makefile $$@ ++include $(objpfx)$(1).generated-makefile ++endef ++ ++# Generate from each testcase description file ++$(eval $(call include_dsosort_tests,dso-sort-tests-1.def)) ++$(eval $(call include_dsosort_tests,dso-sort-tests-2.def)) ++ + check-abi: $(objpfx)check-abi-ld.out + tests-special += $(objpfx)check-abi-ld.out + update-abi: update-abi-ld +diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def +new file mode 100644 +index 0000000000000000..873ddf55d91155c6 +--- /dev/null ++++ b/elf/dso-sort-tests-1.def +@@ -0,0 +1,66 @@ ++# DSO sorting test descriptions. ++# This file is to be processed by ../scripts/dso-ordering-test.py, see usage ++# in elf/Makefile for how it is executed. ++ ++# We test both dynamic loader sorting algorithms ++tunable_option: glibc.rtld.dynamic_sort=1 ++tunable_option: glibc.rtld.dynamic_sort=2 ++ ++# Sequence of single dependencies with no cycles. ++tst-dso-ordering1: a->b->c ++output: c>b>a>{}b->[cd]->e ++output: e>d>c>b>a>{}[bc]->[def]->[gh]->i ++output: i>h>g>f>e>d>c>b>a>{}b->[de];a->c->d->e ++output: e>d>c>b>a>{}c cross link is respected correctly ++tst-dso-ordering5: a!->[bc]->d;b->c ++output: d>c>b>a>{}[bcde]->f ++output: f>e>d>c>b>a>{}[bc];b->[cde];e->f ++output: f>e>d>c>b>a>{}b->c=>a;{}->[ba] ++output: c>b>a>{}b->c->d->e;{}!->[abcde] ++output: e>d>c>b>a>{}a->b->c;soname({})=c ++output: b>a>{}b->c->d order). ++# The older dynamic_sort=1 algorithm does not achieve this, while the DFS-based ++# dynamic_sort=2 algorithm does, although it is still arguable whether going ++# beyond spec to do this is the right thing to do. ++# The below expected outputs are what the two algorithms currently produce ++# respectively, for regression testing purposes. ++tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c ++xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[A101 ++{}->* ++A101->(B101 B163 B122 B181) ++A102->(B102 B140 B199 B158) ++A103->(B103 B117 B176 B135) ++A104->(B104 B194 B153 B112) ++A105->(B105 B171 B130 B189) ++A106->(B106 B148 B107 B166) ++A107->(B107 B125 B184 B143) ++A108->(B108 B102 B161 B120) ++A109->(B109 B179 B138 B197) ++A110->(B110 B156 B115 B174) ++A111->(B111 B133 B192 B151) ++A112->(B112 B110 B169 B128) ++A113->(B113 B187 B146 B105) ++A114->(B114 B164 B123 B182) ++A115->(B115 B141 B200 B159) ++A116->(B116 B118 B177 B136) ++A117->(B117 B195 B154 B113) ++A118->(B118 B172 B131 B190) ++A119->(B119 B149 B108 B167) ++A120->(B120 B126 B185 B144) ++A121->(B121 B103 B162) ++A122->(B122 B180 B139 B198) ++A123->(B123 B157 B116 B175) ++A124->(B124 B134 B193 B152) ++A125->(B125 B111 B170 B129) ++A126->(B126 B188 B147 B106) ++A127->(B127 B165 B124 B183) ++A128->(B128 B142 B101 B160) ++A129->(B129 B119 B178 B137) ++A130->(B130 B196 B155 B114) ++A131->(B131 B173 B132 B191) ++A132->(B132 B150 B109 B168) ++A133->(B133 B127 B186 B145) ++A134->(B134 B104 B163 B122) ++A135->(B135 B181 B140 B199) ++A136->(B136 B158 B117 B176) ++A137->(B137 B135 B194 B153) ++A138->(B138 B112 B171 B130) ++A139->(B139 B189 B148 B107) ++A140->(B140 B166 B125 B184) ++A141->(B141 B143 B102 B161) ++A142->(B142 B120 B179 B138) ++A143->(B143 B197 B156 B115) ++A144->(B144 B174 B133 B192) ++A145->(B145 B151 B110 B169) ++A146->(B146 B128 B187) ++A147->(B147 B105 B164 B123) ++A148->(B148 B182 B141 B200) ++A149->(B149 B159 B118 B177) ++A150->(B150 B136 B195 B154) ++A151->(B151 B113 B172 B131) ++A152->(B152 B190 B149 B108) ++A153->(B153 B167 B126 B185) ++A154->(B154 B144 B103 B162) ++A155->(B155 B121 B180 B139) ++A156->(B156 B198 B157 B116) ++A157->(B157 B175 B134 B193) ++A158->(B158 B152 B111 B170) ++A159->(B159 B129 B188 B147) ++A160->(B160 B106 B165 B124) ++A161->(B161 B183 B142 B101) ++A162->(B162 B160 B119 B178) ++A163->(B163 B137 B196 B155) ++A164->(B164 B114 B173 B132) ++A165->(B165 B191 B150 B109) ++A166->(B166 B168 B127 B186) ++A167->(B167 B145 B104 B163) ++A168->(B168 B122 B181 B140) ++A169->(B169 B199 B158 B117) ++A170->(B170 B176 B135 B194) ++A171->(B171 B153 B112) ++A172->(B172 B130 B189 B148) ++A173->(B173 B107 B166 B125) ++A174->(B174 B184 B143 B102) ++A175->(B175 B161 B120 B179) ++A176->(B176 B138 B197 B156) ++A177->(B177 B115 B174 B133) ++A178->(B178 B192 B151 B110) ++A179->(B179 B169 B128 B187) ++A180->(B180 B146 B105 B164) ++A181->(B181 B123 B182 B141) ++A182->(B182 B200 B159 B118) ++A183->(B183 B177 B136 B195) ++A184->(B184 B154 B113 B172) ++A185->(B185 B131 B190 B149) ++A186->(B186 B108 B167 B126) ++A187->(B187 B185 B144 B103) ++A188->(B188 B162 B121 B180) ++A189->(B189 B139 B198 B157) ++A190->(B190 B116 B175 B134) ++A191->(B191 B193 B152 B111) ++A192->(B192 B170 B129 B188) ++A193->(B193 B147 B106 B165) ++A194->(B194 B124 B183 B142) ++A195->(B195 B101 B160 B119) ++A196->(B196 B178 B137) ++A197->(B197 B155 B114 B173) ++A198->(B198 B132 B191 B150) ++A199->(B199 B109 B168 B127) ++A200->(B200 B186 B145 B104) ++B101->(C101 C164 C123 C182) ++B102->(C102 C141 C200 C159) ++B103->(C103 C118 C177 C136) ++B104->(C104 C195 C154 C113) ++B105->(C105 C172 C131 C190) ++B106->(C106 C149 C108 C167) ++B107->(C107 C126 C185 C144) ++B108->(C108 C103 C162 C121) ++B109->(C109 C180 C139 C198) ++B110->(C110 C157 C116 C175) ++B111->(C111 C134 C193 C152) ++B112->(C112 C111 C170 C129) ++B113->(C113 C188 C147 C106) ++B114->(C114 C165 C124 C183) ++B115->(C115 C142 C101 C160) ++B116->(C116 C119 C178 C137) ++B117->(C117 C196 C155 C114) ++B118->(C118 C173 C132 C191) ++B119->(C119 C150 C109 C168) ++B120->(C120 C127 C186 C145) ++B121->(C121 C104 C163 C122) ++B122->(C122 C181 C140 C199) ++B123->(C123 C158 C117 C176) ++B124->(C124 C135 C194 C153) ++B125->(C125 C112 C171 C130) ++B126->(C126 C189 C148 C107) ++B127->(C127 C166 C125 C184) ++B128->(C128 C143 C102 C161) ++B129->(C129 C120 C179 C138) ++B130->(C130 C197 C156 C115) ++B131->(C131 C174 C133 C192) ++B132->(C132 C151 C110 C169) ++B133->(C133 C128 C187 C146) ++B134->(C134 C105 C164 C123) ++B135->(C135 C182 C141 C200) ++B136->(C136 C159 C118 C177) ++B137->(C137 C136 C195 C154) ++B138->(C138 C113 C172 C131) ++B139->(C139 C190 C149 C108) ++B140->(C140 C167 C126 C185) ++B141->(C141 C144 C103 C162) ++B142->(C142 C121 C180 C139) ++B143->(C143 C198 C157 C116) ++B144->(C144 C175 C134 C193) ++B145->(C145 C152 C111 C170) ++B146->(C146 C129 C188 C147) ++B147->(C147 C106 C165 C124) ++B148->(C148 C183 C142 C101) ++B149->(C149 C160 C119 C178) ++B150->(C150 C137 C196 C155) ++B151->(C151 C114 C173 C132) ++B152->(C152 C191 C150 C109) ++B153->(C153 C168 C127 C186) ++B154->(C154 C145 C104 C163) ++B155->(C155 C122 C181 C140) ++B156->(C156 C199 C158 C117) ++B157->(C157 C176 C135 C194) ++B158->(C158 C153 C112 C171) ++B159->(C159 C130 C189 C148) ++B160->(C160 C107 C166 C125) ++B161->(C161 C184 C143 C102) ++B162->(C162 C161 C120 C179) ++B163->(C163 C138 C197 C156) ++B164->(C164 C115 C174 C133) ++B165->(C165 C192 C151 C110) ++B166->(C166 C169 C128 C187) ++B167->(C167 C146 C105 C164) ++B168->(C168 C123 C182 C141) ++B169->(C169 C200 C159 C118) ++B170->(C170 C177 C136 C195) ++B171->(C171 C154 C113 C172) ++B172->(C172 C131 C190 C149) ++B173->(C173 C108 C167 C126) ++B174->(C174 C185 C144 C103) ++B175->(C175 C162 C121 C180) ++B176->(C176 C139 C198 C157) ++B177->(C177 C116 C175 C134) ++B178->(C178 C193 C152 C111) ++B179->(C179 C170 C129 C188) ++B180->(C180 C147 C106 C165) ++B181->(C181 C124 C183 C142) ++B182->(C182 C101 C160 C119) ++B183->(C183 C178 C137 C196) ++B184->(C184 C155 C114 C173) ++B185->(C185 C132 C191 C150) ++B186->(C186 C109 C168 C127) ++B187->(C187 C186 C145 C104) ++B188->(C188 C163 C122 C181) ++B189->(C189 C140 C199 C158) ++B190->(C190 C117 C176 C135) ++B191->(C191 C194 C153 C112) ++B192->(C192 C171 C130 C189) ++B193->(C193 C148 C107 C166) ++B194->(C194 C125 C184 C143) ++B195->(C195 C102 C161 C120) ++B196->(C196 C179 C138 C197) ++B197->(C197 C156 C115 C174) ++B198->(C198 C133 C192 C151) ++B199->(C199 C110 C169 C128) ++B200->(C200 C187 C146 C105) ++C101->(A165 A124) ++C102->(A183 A142) ++C103->(A101 A160) ++C104->(A119 A178) ++C105->(A137 A196) ++C106->(A155 A114) ++C107->(A173 A132) ++C108->(A191 A150) ++C109->(A109 A168) ++C110->(A127 A186) ++C111->(A145 A104) ++C112->(A163 A122) ++C113->(A181 A140) ++C114->(A199 A158) ++C115->(A117 A176) ++C116->(A135 A194) ++C117->(A153 A112) ++C118->(A171 A130) ++C119->(A189 A148) ++C120->(A107 A166) ++C121->(A125 A184) ++C122->(A143 A102) ++C123->(A161 A120) ++C124->(A179 A138) ++C125->(A197 A156) ++C126->(A115 A174) ++C127->(A133 A192) ++C128->(A151 A110) ++C129->(A169 A128) ++C130->(A187 A146) ++C131->(A105 A164) ++C132->(A123 A182) ++C133->(A141 A200) ++C134->(A159 A118) ++C135->(A177 A136) ++C136->(A195 A154) ++C137->(A113 A172) ++C138->(A131 A190) ++C139->(A149 A108) ++C140->(A167 A126) ++C141->(A185 A144) ++C142->(A103 A162) ++C143->(A121 A180) ++C144->(A139 A198) ++C145->(A157 A116) ++C146->(A175 A134) ++C147->(A193 A152) ++C148->(A111 A170) ++C149->(A129 A188) ++C150->(A147 A106) ++C151->(A165 A124) ++C152->(A183 A142) ++C153->(A101 A160) ++C154->(A119 A178) ++C155->(A137 A196) ++C156->(A155 A114) ++C157->(A173 A132) ++C158->(A191 A150) ++C159->(A109 A168) ++C160->(A127 A186) ++C161->(A145 A104) ++C162->(A163 A122) ++C163->(A181 A140) ++C164->(A199 A158) ++C165->(A117 A176) ++C166->(A135 A194) ++C167->(A153 A112) ++C168->(A171 A130) ++C169->(A189 A148) ++C170->(A107 A166) ++C171->(A125 A184) ++C172->(A143 A102) ++C173->(A161 A120) ++C174->(A179 A138) ++C175->(A197 A156) ++C176->(A115 A174) ++C177->(A133 A192) ++C178->(A151 A110) ++C179->(A169 A128) ++C180->(A187 A146) ++C181->(A105 A164) ++C182->(A123 A182) ++C183->(A141 A200) ++C184->(A159 A118) ++C185->(A177 A136) ++C186->(A195 A154) ++C187->(A113 A172) ++C188->(A131 A190) ++C189->(A149 A108) ++C190->(A167 A126) ++C191->(A185 A144) ++C192->(A103 A162) ++C193->(A121 A180) ++C194->(A139 A198) ++C195->(A157 A116) ++C196->(A175 A134) ++C197->(A193 A152) ++C198->(A111 A170) ++C199->(A129 A188) ++C200->(A147 A106) ++M11X11->(M13X14 M12X13 M12X12 M12X11) ++M11X12->(M13X25 M12X24 M12X23 M12X22) ++M11X13->(M13X21 M12X20 M12X19 M12X18) ++M11X14->(M13X17 M12X16 M12X15 M12X14) ++M11X15->(M13X13 M12X12 M12X11 M12X25) ++M11X16->(M13X24 M12X23 M12X22 M12X21) ++M11X17->(M13X20 M12X19 M12X18 M12X17) ++M11X18->(M13X16 M12X15 M12X14 M12X13) ++M11X19->(M13X12 M12X11 M12X25 M12X24) ++M11X20->(M13X23 M12X22 M12X21 M12X20) ++M11X21->(M13X19 M12X18 M12X17 M12X16) ++M11X22->(M13X15 M12X14 M12X13 M12X12) ++M11X23->(M13X11 M12X25 M12X24 M12X23) ++M11X24->(M13X22 M12X21 M12X20 M12X19) ++M11X25->(M13X18 M12X17 M12X16 M12X15) ++M12X11->(M14X14 M13X13 M13X12 M13X11) ++M12X12->(M14X25 M13X24 M13X23 M13X22) ++M12X13->(M14X21 M13X20 M13X19 M13X18) ++M12X14->(M14X17 M13X16 M13X15 M13X14) ++M12X15->(M14X13 M13X12 M13X11 M13X25) ++M12X16->(M14X24 M13X23 M13X22 M13X21) ++M12X17->(M14X20 M13X19 M13X18 M13X17) ++M12X18->(M14X16 M13X15 M13X14 M13X13) ++M12X19->(M14X12 M13X11 M13X25 M13X24) ++M12X20->(M14X23 M13X22 M13X21 M13X20) ++M12X21->(M14X19 M13X18 M13X17 M13X16) ++M12X22->(M14X15 M13X14 M13X13 M13X12) ++M12X23->(M14X11 M13X25 M13X24 M13X23) ++M12X24->(M14X22 M13X21 M13X20 M13X19) ++M12X25->(M14X18 M13X17 M13X16 M13X15) ++M13X11->(M15X14 M14X13 M14X12 M14X11) ++M13X12->(M15X25 M14X24 M14X23 M14X22) ++M13X13->(M15X21 M14X20 M14X19 M14X18) ++M13X14->(M15X17 M14X16 M14X15 M14X14) ++M13X15->(M15X13 M14X12 M14X11 M14X25) ++M13X16->(M15X24 M14X23 M14X22 M14X21) ++M13X17->(M15X20 M14X19 M14X18 M14X17) ++M13X18->(M15X16 M14X15 M14X14 M14X13) ++M13X19->(M15X12 M14X11 M14X25 M14X24) ++M13X20->(M15X23 M14X22 M14X21 M14X20) ++M13X21->(M15X19 M14X18 M14X17 M14X16) ++M13X22->(M15X15 M14X14 M14X13 M14X12) ++M13X23->(M15X11 M14X25 M14X24 M14X23) ++M13X24->(M15X22 M14X21 M14X20 M14X19) ++M13X25->(M15X18 M14X17 M14X16 M14X15) ++M14X11->(M16X14 M15X13 M15X12 M15X11) ++M14X12->(M16X25 M15X24 M15X23 M15X22) ++M14X13->(M16X21 M15X20 M15X19 M15X18) ++M14X14->(M16X17 M15X16 M15X15 M15X14) ++M14X15->(M16X13 M15X12 M15X11 M15X25) ++M14X16->(M16X24 M15X23 M15X22 M15X21) ++M14X17->(M16X20 M15X19 M15X18 M15X17) ++M14X18->(M16X16 M15X15 M15X14 M15X13) ++M14X19->(M16X12 M15X11 M15X25 M15X24) ++M14X20->(M16X23 M15X22 M15X21 M15X20) ++M14X21->(M16X19 M15X18 M15X17 M15X16) ++M14X22->(M16X15 M15X14 M15X13 M15X12) ++M14X23->(M16X11 M15X25 M15X24 M15X23) ++M14X24->(M16X22 M15X21 M15X20 M15X19) ++M14X25->(M16X18 M15X17 M15X16 M15X15) ++M15X11->(M17X14 M16X13 M16X12 M16X11) ++M15X12->(M17X25 M16X24 M16X23 M16X22) ++M15X13->(M17X21 M16X20 M16X19 M16X18) ++M15X14->(M17X17 M16X16 M16X15 M16X14) ++M15X15->(M17X13 M16X12 M16X11 M16X25) ++M15X16->(M17X24 M16X23 M16X22 M16X21) ++M15X17->(M17X20 M16X19 M16X18 M16X17) ++M15X18->(M17X16 M16X15 M16X14 M16X13) ++M15X19->(M17X12 M16X11 M16X25 M16X24) ++M15X20->(M17X23 M16X22 M16X21 M16X20) ++M15X21->(M17X19 M16X18 M16X17 M16X16) ++M15X22->(M17X15 M16X14 M16X13 M16X12) ++M15X23->(M17X11 M16X25 M16X24 M16X23) ++M15X24->(M17X22 M16X21 M16X20 M16X19) ++M15X25->(M17X18 M16X17 M16X16 M16X15) ++M16X11->(M18X14 M17X13 M17X12 M17X11) ++M16X12->(M18X25 M17X24 M17X23 M17X22) ++M16X13->(M18X21 M17X20 M17X19 M17X18) ++M16X14->(M18X17 M17X16 M17X15 M17X14) ++M16X15->(M18X13 M17X12 M17X11 M17X25) ++M16X16->(M18X24 M17X23 M17X22 M17X21) ++M16X17->(M18X20 M17X19 M17X18 M17X17) ++M16X18->(M18X16 M17X15 M17X14 M17X13) ++M16X19->(M18X12 M17X11 M17X25 M17X24) ++M16X20->(M18X23 M17X22 M17X21 M17X20) ++M16X21->(M18X19 M17X18 M17X17 M17X16) ++M16X22->(M18X15 M17X14 M17X13 M17X12) ++M16X23->(M18X11 M17X25 M17X24 M17X23) ++M16X24->(M18X22 M17X21 M17X20 M17X19) ++M16X25->(M18X18 M17X17 M17X16 M17X15) ++M17X11->(M19X14 M18X13 M18X12 M18X11) ++M17X12->(M19X25 M18X24 M18X23 M18X22) ++M17X13->(M19X21 M18X20 M18X19 M18X18) ++M17X14->(M19X17 M18X16 M18X15 M18X14) ++M17X15->(M19X13 M18X12 M18X11 M18X25) ++M17X16->(M19X24 M18X23 M18X22 M18X21) ++M17X17->(M19X20 M18X19 M18X18 M18X17) ++M17X18->(M19X16 M18X15 M18X14 M18X13) ++M17X19->(M19X12 M18X11 M18X25 M18X24) ++M17X20->(M19X23 M18X22 M18X21 M18X20) ++M17X21->(M19X19 M18X18 M18X17 M18X16) ++M17X22->(M19X15 M18X14 M18X13 M18X12) ++M17X23->(M19X11 M18X25 M18X24 M18X23) ++M17X24->(M19X22 M18X21 M18X20 M18X19) ++M17X25->(M19X18 M18X17 M18X16 M18X15) ++M18X11->(M20X14 M19X13 M19X12 M19X11) ++M18X12->(M20X25 M19X24 M19X23 M19X22) ++M18X13->(M20X21 M19X20 M19X19 M19X18) ++M18X14->(M20X17 M19X16 M19X15 M19X14) ++M18X15->(M20X13 M19X12 M19X11 M19X25) ++M18X16->(M20X24 M19X23 M19X22 M19X21) ++M18X17->(M20X20 M19X19 M19X18 M19X17) ++M18X18->(M20X16 M19X15 M19X14 M19X13) ++M18X19->(M20X12 M19X11 M19X25 M19X24) ++M18X20->(M20X23 M19X22 M19X21 M19X20) ++M18X21->(M20X19 M19X18 M19X17 M19X16) ++M18X22->(M20X15 M19X14 M19X13 M19X12) ++M18X23->(M20X11 M19X25 M19X24 M19X23) ++M18X24->(M20X22 M19X21 M19X20 M19X19) ++M18X25->(M20X18 M19X17 M19X16 M19X15) ++M19X11->(M21X14 M20X13 M20X12 M20X11) ++M19X12->(M21X25 M20X24 M20X23 M20X22) ++M19X13->(M21X21 M20X20 M20X19 M20X18) ++M19X14->(M21X17 M20X16 M20X15 M20X14) ++M19X15->(M21X13 M20X12 M20X11 M20X25) ++M19X16->(M21X24 M20X23 M20X22 M20X21) ++M19X17->(M21X20 M20X19 M20X18 M20X17) ++M19X18->(M21X16 M20X15 M20X14 M20X13) ++M19X19->(M21X12 M20X11 M20X25 M20X24) ++M19X20->(M21X23 M20X22 M20X21 M20X20) ++M19X21->(M21X19 M20X18 M20X17 M20X16) ++M19X22->(M21X15 M20X14 M20X13 M20X12) ++M19X23->(M21X11 M20X25 M20X24 M20X23) ++M19X24->(M21X22 M20X21 M20X20 M20X19) ++M19X25->(M21X18 M20X17 M20X16 M20X15) ++M20X11->(M22X14 M21X13 M21X12 M21X11) ++M20X12->(M22X25 M21X24 M21X23 M21X22) ++M20X13->(M22X21 M21X20 M21X19 M21X18) ++M20X14->(M22X17 M21X16 M21X15 M21X14) ++M20X15->(M22X13 M21X12 M21X11 M21X25) ++M20X16->(M22X24 M21X23 M21X22 M21X21) ++M20X17->(M22X20 M21X19 M21X18 M21X17) ++M20X18->(M22X16 M21X15 M21X14 M21X13) ++M20X19->(M22X12 M21X11 M21X25 M21X24) ++M20X20->(M22X23 M21X22 M21X21 M21X20) ++M20X21->(M22X19 M21X18 M21X17 M21X16) ++M20X22->(M22X15 M21X14 M21X13 M21X12) ++M20X23->(M22X11 M21X25 M21X24 M21X23) ++M20X24->(M22X22 M21X21 M21X20 M21X19) ++M20X25->(M22X18 M21X17 M21X16 M21X15) ++M21X11->(M23X15 M22X14 M22X13 M22X12) ++M21X12->(M11X11 M23X25 M22X24 M22X23 M22X22) ++M21X13->(M23X21 M22X20 M22X19 M22X18) ++M21X14->(M23X17 M22X16 M22X15 M22X14) ++M21X15->(M23X13 M22X12 M22X11 M22X25) ++M21X16->(M23X24 M22X23 M22X22 M22X21) ++M21X17->(M23X20 M22X19 M22X18 M22X17) ++M21X18->(M23X16 M22X15 M22X14 M22X13) ++M21X19->(M23X12 M22X11 M22X25 M22X24) ++M21X20->(M23X23 M22X22 M22X21 M22X20) ++M21X21->(M23X19 M22X18 M22X17 M22X16) ++M21X22->(M23X15 M22X14 M22X13 M22X12) ++M21X23->(M23X11 M22X25 M22X24 M22X23) ++M21X24->(M23X22 M22X21 M22X20 M22X19) ++M21X25->(M23X18 M22X17 M22X16 M22X15) ++M22X11->(M24X16 M23X15 M23X14 M23X13) ++M22X12->(M12X12 M24X11 M23X25 M23X24 M23X23) ++M22X13->(M24X22 M23X21 M23X20 M23X19) ++M22X14->(M24X18 M23X17 M23X16 M23X15) ++M22X15->(M24X14 M23X13 M23X12 M23X11) ++M22X16->(M24X25 M23X24 M23X23 M23X22) ++M22X17->(M24X21 M23X20 M23X19 M23X18) ++M22X18->(M24X17 M23X16 M23X15 M23X14) ++M22X19->(M24X13 M23X12 M23X11 M23X25) ++M22X20->(M24X24 M23X23 M23X22 M23X21) ++M22X21->(M24X20 M23X19 M23X18 M23X17) ++M22X22->(M24X16 M23X15 M23X14 M23X13) ++M22X23->(M24X12 M23X11 M23X25 M23X24) ++M22X24->(M24X23 M23X22 M23X21 M23X20) ++M22X25->(M24X19 M23X18 M23X17 M23X16) ++M23X11->(M25X17 M24X16 M24X15 M24X14) ++M23X12->(M13X13 M25X12 M24X11 M24X25 M24X24) ++M23X13->(M25X23 M24X22 M24X21 M24X20) ++M23X14->(M25X19 M24X18 M24X17 M24X16) ++M23X15->(M25X15 M24X14 M24X13 M24X12) ++M23X16->(M25X11 M24X25 M24X24 M24X23) ++M23X17->(M25X22 M24X21 M24X20 M24X19) ++M23X18->(M25X18 M24X17 M24X16 M24X15) ++M23X19->(M25X14 M24X13 M24X12 M24X11) ++M23X20->(M25X25 M24X24 M24X23 M24X22) ++M23X21->(M25X21 M24X20 M24X19 M24X18) ++M23X22->(M25X17 M24X16 M24X15 M24X14) ++M23X23->(M25X13 M24X12 M24X11 M24X25) ++M23X24->(M25X24 M24X23 M24X22 M24X21) ++M23X25->(M25X20 M24X19 M24X18 M24X17) ++M24X11->(M26X18 M25X17 M25X16 M25X15) ++M24X12->(M14X14 M26X13 M25X12 M25X11 M25X25) ++M24X13->(M26X24 M25X23 M25X22 M25X21) ++M24X14->(M26X20 M25X19 M25X18 M25X17) ++M24X15->(M26X16 M25X15 M25X14 M25X13) ++M24X16->(M26X12 M25X11 M25X25 M25X24) ++M24X17->(M26X23 M25X22 M25X21 M25X20) ++M24X18->(M26X19 M25X18 M25X17 M25X16) ++M24X19->(M26X15 M25X14 M25X13 M25X12) ++M24X20->(M26X11 M25X25 M25X24 M25X23) ++M24X21->(M26X22 M25X21 M25X20 M25X19) ++M24X22->(M26X18 M25X17 M25X16 M25X15) ++M24X23->(M26X14 M25X13 M25X12 M25X11) ++M24X24->(M26X25 M25X24 M25X23 M25X22) ++M24X25->(M26X21 M25X20 M25X19 M25X18) ++M25X11->(M27X19 M26X18 M26X17 M26X16) ++M25X12->(M15X15 M27X14 M26X13 M26X12 M26X11) ++M25X13->(M27X25 M26X24 M26X23 M26X22) ++M25X14->(M27X21 M26X20 M26X19 M26X18) ++M25X15->(M27X17 M26X16 M26X15 M26X14) ++M25X16->(M27X13 M26X12 M26X11 M26X25) ++M25X17->(M27X24 M26X23 M26X22 M26X21) ++M25X18->(M27X20 M26X19 M26X18 M26X17) ++M25X19->(M27X16 M26X15 M26X14 M26X13) ++M25X20->(M27X12 M26X11 M26X25 M26X24) ++M25X21->(M27X23 M26X22 M26X21 M26X20) ++M25X22->(M27X19 M26X18 M26X17 M26X16) ++M25X23->(M27X15 M26X14 M26X13 M26X12) ++M25X24->(M27X11 M26X25 M26X24 M26X23) ++M25X25->(M27X22 M26X21 M26X20 M26X19) ++M26X11->(M28X20 M27X19 M27X18 M27X17) ++M26X12->(M16X16 M28X15 M27X14 M27X13 M27X12) ++M26X13->(M28X11 M27X25 M27X24 M27X23) ++M26X14->(M28X22 M27X21 M27X20 M27X19) ++M26X15->(M28X18 M27X17 M27X16 M27X15) ++M26X16->(M28X14 M27X13 M27X12 M27X11) ++M26X17->(M28X25 M27X24 M27X23 M27X22) ++M26X18->(M28X21 M27X20 M27X19 M27X18) ++M26X19->(M28X17 M27X16 M27X15 M27X14) ++M26X20->(M28X13 M27X12 M27X11 M27X25) ++M26X21->(M28X24 M27X23 M27X22 M27X21) ++M26X22->(M28X20 M27X19 M27X18 M27X17) ++M26X23->(M28X16 M27X15 M27X14 M27X13) ++M26X24->(M28X12 M27X11 M27X25 M27X24) ++M26X25->(M28X23 M27X22 M27X21 M27X20) ++M27X11->(M29X21 M28X20 M28X19 M28X18) ++M27X12->(M17X17 M29X16 M28X15 M28X14 M28X13) ++M27X13->(M29X12 M28X11 M28X25 M28X24) ++M27X14->(M29X23 M28X22 M28X21 M28X20) ++M27X15->(M29X19 M28X18 M28X17 M28X16) ++M27X16->(M29X15 M28X14 M28X13 M28X12) ++M27X17->(M29X11 M28X25 M28X24 M28X23) ++M27X18->(M29X22 M28X21 M28X20 M28X19) ++M27X19->(M29X18 M28X17 M28X16 M28X15) ++M27X20->(M29X14 M28X13 M28X12 M28X11) ++M27X21->(M29X25 M28X24 M28X23 M28X22) ++M27X22->(M29X21 M28X20 M28X19 M28X18) ++M27X23->(M29X17 M28X16 M28X15 M28X14) ++M27X24->(M29X13 M28X12 M28X11 M28X25) ++M27X25->(M29X24 M28X23 M28X22 M28X21) ++M28X11->(M30X22 M29X21 M29X20 M29X19) ++M28X12->(M18X18 M30X17 M29X16 M29X15 M29X14) ++M28X13->(M30X13 M29X12 M29X11 M29X25) ++M28X14->(M30X24 M29X23 M29X22 M29X21) ++M28X15->(M30X20 M29X19 M29X18 M29X17) ++M28X16->(M30X16 M29X15 M29X14 M29X13) ++M28X17->(M30X12 M29X11 M29X25 M29X24) ++M28X18->(M30X23 M29X22 M29X21 M29X20) ++M28X19->(M30X19 M29X18 M29X17 M29X16) ++M28X20->(M30X15 M29X14 M29X13 M29X12) ++M28X21->(M30X11 M29X25 M29X24 M29X23) ++M28X22->(M30X22 M29X21 M29X20 M29X19) ++M28X23->(M30X18 M29X17 M29X16 M29X15) ++M28X24->(M30X14 M29X13 M29X12 M29X11) ++M28X25->(M30X25 M29X24 M29X23 M29X22) ++M29X11->(M30X22 M30X21 M30X20) ++M29X12->(M30X17 M30X16 M30X15) ++M29X13->(M30X13 M30X12 M30X11) ++M29X14->(M30X24 M30X23 M30X22) ++M29X15->(M30X20 M30X19 M30X18) ++M29X16->(M30X16 M30X15 M30X14) ++M29X17->(M30X12 M30X11 M30X25) ++M29X18->(M30X23 M30X22 M30X21) ++M29X19->(M30X19 M30X18 M30X17) ++M29X20->(M30X15 M30X14 M30X13) ++M29X21->(M30X11 M30X25 M30X24) ++M29X22->(M30X22 M30X21 M30X20) ++M29X23->(M30X18 M30X17 M30X16) ++M29X24->(M30X14 M30X13 M30X12) ++M29X25->(M30X25 M30X24 M30X23) ++M30X11 ++M30X12 ++M30X13 ++M30X14 ++M30X15 ++M30X16 ++M30X17 ++M30X18 ++M30X19 ++M30X20 ++M30X21 ++M30X22 ++M30X23 ++M30X24 ++M30X25 ++xfail_output(glibc.rtld.dynamic_sort=1): M30X19>M30X15>M30X16>M30X11>M30X12>M30X17>M30X13>M30X14>M29X20>M30X23>M30X24>M30X20>M30X18>M29X15>M29X12>M30X22>M30X21>M29X22>M30X25>M29X19>M29X23>M29X16>M29X24>M29X13>M29X17>M29X18>M28X19>M29X21>M29X25>M29X14>M28X20>M28X15>M28X16>M28X21>M27X18>M29X11>M28X17>M28X11>M28X22>M27X14>M28X18>M27X15>M28X13>M27X11>M28X23>M27X25>M28X14>M28X25>M27X23>M27X22>M28X24>M27X21>M27X13>M27X19>M27X17>M26X11>M26X23>M26X21>M26X22>M26X20>M26X16>M25X21>M17X22>M15X15>M20X14>M20X16>M18X18>M28X12>M27X24>M25X17>M27X20>M26X18>M26X17>M27X16>M26X19>M25X18>M26X24>M25X20>M24X17>M23X18>M25X13>M26X13>M17X23>M16X16>M26X12>M25X12>M26X15>M24X19>M25X23>M25X24>M25X25>M24X20>M25X19>M24X21>M23X17>M22X21>M24X14>M23X22>M24X24>M22X20>M24X13>M25X11>M24X12>M25X15>M23X15>M25X16>M24X22>M23X13>M24X18>M23X14>M22X22>M21X20>M24X25>M23X16>M22X25>M21X19>M22X14>M23X11>M22X15>M21X18>M22X19>M21X17>M20X17>M19X17>M21X24>M21X12>M20X22>M19X16>M18X25>M19X21>M19X20>M18X24>M20X12>M19X11>M23X20>M22X24>M22X16>M21X21>M25X14>M23X19>M23X24>M20X24>M19X12>M18X15>M17X14>M16X18>M14X25>M16X22>M16X20>M17X17>M22X12>M21X11>M20X15>M18X22>M19X24>M19X18>M18X21>M17X16>M17X18>M16X21>M15X20>M19X22>M18X20>M18X11>M17X19>M16X17>M15X21>M16X14>M16X13>M15X22>M14X20>M17X25>M16X19>M14X21>M13X24>M12X12>M16X24>M15X23>M14X16>M16X15>M15X25>M15X11>M15X12>M14X15>M13X14>M14X22>M13X20>M12X13>M11X11>M22X23>M21X15>M21X16>M20X21>M20X20>M18X17>M19X25>M18X23>M21X13>M15X17>M15X18>M18X19>M17X24>M16X12>M17X13>M20X25>M19X23>M15X19>M14X13>M13X18>M15X13>M17X12>M16X11>M18X13>M18X12>M14X11>M14X24>M13X19>M15X14>M17X20>M20X11>M20X13>M21X14>M15X24>M14X12>M13X22>M14X23>M13X23>M14X19>M17X15>M16X25>M17X11>M18X14>M19X19>M21X25>M13X12>M13X11>M14X18>M13X13>M12X11>M15X16>M14X14>M27X12>M17X21>M20X23>M22X13>M21X22>M24X16>M24X15>M26X25>M23X25>M26X14>M23X12>M22X18>M24X11>M16X23>M19X14>M19X13>M21X23>M22X17>M23X23>M23X21>M25X22>M18X16>M19X15>M20X18>M20X19>M22X11>M24X23>C156>C118>C143>C137>C147>C106>C168>C113>C163>C155>C105>C146>C187>A150>C139>C180>C164>C193>C157>A191>C158>B188>A159>C184>C121>C154>B171>A105>C131>C104>B104>C161>C111>B145>C160>B155>A163>C112>C142>B148>C133>B198>A198>A115>C114>B157>A156>C175>B144>A120>C173>B184>A174>C126>B107>A139>C194>B194>A194>C116>B116>C166>B160>B110>A110>C128>B128>A128>C179>B162>A154>C186>B187>A179>C124>B181>A101>C153>B158>A136>C135>C176>A192>B133>A133>C177>B177>A177>C185>C103>B141>A141>C183>A162>C192>C129>B179>C144>B124>B183>C127>B127>A127>B108>A112>B153>A153>C167>B167>A186>A122>C162>A144>B149>C174>B131>A185>C141>B106>A126>A167>C140>B122>A170>C198>B143>C117>C123>B123>A147>A106>C200>B169>C191>B175>A123>B118>A182>C132>B151>A145>A104>A109>C159>C150>B119>A119>A178>B164>B114>A164>C181>A102>C122>B134>A157>A116>C195>B191>B111>C172>B172>A118>B129>A129>C149>A107>C170>B197>A197>A173>B168>A132>C107>B165>A160>A131>C188>A168>B109>C178>A189>A148>C119>C190>C120>B166>B176>C108>B135>B139>A103>B178>A169>B132>C125>C138>B163>A111>B170>C110>A165>C151>C169>C199>A138>C182>A135>B101>B142>C101>C148>B193>B152>A158>A199>C136>B137>A161>B120>A108>A149>A125>B113>A184>C171>A134>A175>A124>B150>B161>B102>A146>A187>C130>B192>B200>A200>A142>A183>C102>B105>B156>A176>C165>B147>A137>A196>B190>A190>B125>C134>C189>B126>B186>A166>B136>B195>A195>B154>B138>B112>B173>A117>B159>B182>A181>A140>C145>B117>A152>A193>C197>B130>A172>A113>A151>B115>A143>B140>B185>B103>A121>A180>A130>A171>B199>C196>B146>B180>C115>B174>B121>A188>B196>B189>C152>C109>A155>A114>M14X17>M13X15>M13X16>M13X17>M12X17>M12X21>M12X25>M12X14>M13X25>M12X15>M13X21>M12X16>M12X18>M12X19>M12X20>M12X22>M12X23>M12X24>M11X25>M11X24>M11X23>M11X22>M11X21>M11X20>M11X19>M11X18>M11X17>M11X16>M11X15>M11X14>M11X13>M11X12>{}M30X15>M30X16>M30X11>M30X12>M30X17>M30X13>M30X14>M29X20>M30X23>M30X24>M30X20>M30X18>M29X15>M29X12>M30X22>M30X21>M29X22>M30X25>M29X19>M29X23>M29X16>M29X24>M29X13>M29X17>M29X18>M28X19>M29X21>M29X25>M29X14>M28X20>M28X15>M28X16>M28X21>M27X18>M29X11>M28X17>M28X11>M28X22>M28X24>M28X23>M27X21>M28X13>M27X20>M27X19>M26X14>M27X25>M28X18>M27X11>M28X25>M27X24>M26X24>M27X15>M27X14>M27X13>M26X23>M27X17>M26X22>M25X13>M28X14>M27X16>M26X19>M26X18>M27X23>M27X22>M26X17>M25X18>M26X21>M25X17>M26X20>M26X15>M26X13>M25X19>M24X14>M25X23>M26X11>M26X25>M25X16>M25X15>M24X22>M25X21>M25X20>M24X21>M25X25>M25X24>M24X20>M23X13>M22X15>M25X14>M24X19>M23X17>M24X25>M23X24>M24X13>M23X15>M24X18>M23X14>M22X11>M24X15>M23X22>M24X11>M23X19>M22X21>M24X24>M23X21>M22X20>M23X25>M22X19>M21X24>M20X23>M22X22>M25X11>M23X16>M22X18>M23X20>M22X17>M21X21>M21X20>M20X24>M22X14>M22X13>M21X11>M21X17>M22X23>M21X16>M20X25>M19X23>M18X16>M21X22>M20X20>M20X19>M21X13>M20X18>M19X13>M21X18>M20X21>M19X24>M18X12>M20X14>M20X13>M22X25>M20X12>M20X15>M19X14>M18X22>M19X18>M20X17>M19X17>M19X16>M18X21>M17X20>M19X19>M18X13>M17X11>M18X17>M19X25>M18X15>M17X25>M18X19>M17X24>M16X19>M15X17>M17X21>M16X24>M18X23>M17X16>M16X25>M19X15>M18X25>M17X23>M16X23>M15X23>M18X14>M17X14>M16X14>M17X18>M16X13>M17X22>M16X12>M15X22>M14X16>M17X12>M16X22>M15X12>M16X11>M15X11>M16X15>M15X25>M14X15>M13X14>M15X18>M16X21>M15X16>M14X21>M15X14>M16X20>M15X13>M14X22>M15X20>M14X20>M13X20>M14X11>M15X19>M14X24>M13X19>M14X13>M13X18>M12X13>M15X24>M14X23>M13X12>M14X12>M13X11>M12X11>M11X11>M21X12>M20X11>M19X11>M18X11>M17X15>M16X18>M14X25>M14X19>M13X24>M13X23>M13X22>M12X12>M22X12>M21X15>M19X22>M18X20>M16X17>M14X14>M24X12>M23X23>M22X16>M21X14>M20X22>M18X24>M16X16>M26X12>M24X16>M23X11>M21X23>M19X20>M17X17>M27X12>M26X16>M25X22>M24X17>M23X18>M21X25>M19X12>M17X19>M15X21>M14X18>M13X13>M23X12>M21X19>M19X21>M17X13>M15X15>M25X12>M24X23>M22X24>M20X16>M18X18>M28X12>A150>C158>B112>A112>C167>B146>A146>C180>B180>A180>C143>B143>A115>C126>B126>A126>C190>B190>A190>C138>B138>A138>C174>B174>A102>C122>B122>A122>C162>B162>A162>C142>B142>A142>C102>B102>A174>C176>B176>A176>C115>B115>A143>C172>B172>A172>C187>B187>A187>C130>B130>A130>C118>B118>A118>C184>B184>A184>C171>B171>A171>C168>B182>A182>C182>B168>A168>C109>B109>A109>C159>B159>A159>C134>B134>A134>C146>B167>A167>C140>B140>A140>C163>B163>A163>C112>B158>A158>C164>B164>A164>C131>B131>A131>C188>B188>A188>C199>B199>A199>C114>B114>A114>C106>B106>A106>C200>B200>A200>C183>B183>A183>C152>B152>A152>C147>B147>A147>C150>B150>A198>C144>B144>A144>C191>B191>A191>C108>B108>A108>C139>B139>A139>C194>B194>A194>C166>B166>A166>C120>B120>A120>C123>B123>A123>C132>B132>A132>C107>B107>A107>C170>B170>A170>C198>B198>A156>C125>B125>A125>C121>B121>A121>C193>B193>A193>C197>B197>A197>C175>B175>A175>C196>B196>A196>C105>B105>A105>C181>B181>A181>C113>B113>A113>C137>B137>A137>C155>B155>A155>C156>B156>A110>C128>B128>A128>C179>B179>A179>C124>B124>A124>C151>B151>A151>C178>B178>A178>C104>B104>A104>C111>B111>A111>C148>B148>A148>C169>B169>A169>C129>B129>A129>C149>B149>A149>C189>B189>A189>C119>B119>A119>C154>B154>A154>C136>B136>A136>C135>B135>A135>C116>B116>A116>C145>B145>A145>C161>B161>A161>C173>B173>A173>C157>B157>A157>C195>B195>A195>C186>B186>A186>C160>B160>A160>C153>B153>A153>C117>B117>A117>C165>B165>A165>C101>B101>A101>C103>B103>A103>C192>B192>A192>C177>B177>A177>C185>B185>A185>C141>B141>A141>C133>B133>A133>C127>B127>A127>C110>B110>M14X17>M13X15>M13X16>M13X17>M12X17>M12X21>M12X25>M12X14>M13X25>M12X15>M13X21>M12X16>M12X18>M12X19>M12X20>M12X22>M12X23>M12X24>M11X25>M11X24>M11X23>M11X22>M11X21>M11X20>M11X19>M11X18>M11X17>M11X16>M11X15>M11X14>M11X13>M11X12>{}. ++ ++"""Generate testcase files and Makefile fragments for DSO sorting test ++ ++This script takes a small description string language, and generates ++testcases for displaying the ELF dynamic linker's dependency sorting ++behavior, allowing verification. ++ ++Testcase descriptions are semicolon-separated description strings, and ++this tool generates a testcase from the description, including main program, ++associated modules, and Makefile fragments for including into elf/Makefile. ++ ++This allows automation of what otherwise would be very laborous manual ++construction of complex dependency cases, however it must be noted that this ++is only a tool to speed up testcase construction, and thus the generation ++features are largely mechanical in nature; inconsistencies or errors may occur ++if the input description was itself erroneous or have unforeseen interactions. ++ ++The format of the input test description files are: ++ ++ # Each test description has a name, lines of description, ++ # and an expected output specification. Comments use '#'. ++ testname1: ++ output: ++ ++ # Tests can be marked to be XFAIL by using 'xfail_output' instead ++ testname2: ++ xfail_output: ++ ++ # A default set of GLIBC_TUNABLES tunables can be specified, for which ++ # all following tests will run multiple times, once for each of the ++ # GLIBC_TUNABLES=... strings set by the 'tunable_option' command. ++ tunable_option: ++ tunable_option: ++ ++ # Test descriptions can use multiple lines, which will all be merged ++ # together, so order is not important. ++ testname3: ++ ++ ++ ... ++ output: ++ ++ # 'testname3' will be run and compared two times, for both ++ # GLIBC_TUNABLES= and ++ # GLIBC_TUNABLES=. This can be cleared and reset by the ++ # 'clear_tunables' command: ++ clear_tunables ++ ++ # Multiple expected outputs can also be specified, with an associated ++ # tunable option in (), which multiple tests will be run with each ++ # GLIBC_TUNABLES=... option tried. ++ testname4: ++ ++ ... ++ output(): ++ output(): ++ # Individual tunable output cases can be XFAILed, though note that ++ # this will have the effect of XFAILing the entire 'testname4' test ++ # in the final top-level tests.sum summary. ++ xfail_output(): ++ ++ # When multiple outputs (with specific tunable strings) are specified, ++ # these take priority over any active 'tunable_option' settings. ++ ++ # When a test is meant to be placed under 'xtests' (not run under ++ # "make check", but only when "make xtests" is used), the testcase name can be ++ # declared using 'xtest()': ++ ... ++ xtest(test-too-big1): ++ output: ++ ... ++ ++ # Do note that under current elf/Makefile organization, for such a xtest case, ++ # while the test execution is only run under 'make xtests', the associated ++ # DSOs are always built even under 'make check'. ++ ++On the description language used, an example description line string: ++ ++ a->b!->[cdef];c=>g=>h;{+c;%c;-c}->a ++ ++Each identifier represents a shared object module, currently sequences of ++letters/digits are allowed, case-sensitive. ++ ++All such shared objects have a constructor/destructor generated for them ++that emits its name followed by a '>' for constructors, and '<' followed by ++its name for destructors, e.g. if the name is 'obj1', then "obj1>" and " operator specifies a link time dependency, these can be chained for ++convenience (e.g. a->b->c->d). ++ ++The => operator creates a call-reference, e.g. for a=>b, an fn_a() function ++is created inside module 'a', which calls fn_b() in module 'b'. ++These module functions emit 'name()' output in nested form, ++e.g. a=>b emits 'a(b())' ++ ++For single character object names, square brackets [] in the description ++allows specifying multiple objects; e.g. a->[bcd]->e is equivalent to ++ a->b->e;a->c->e;a->d->e ++ ++The () parenthesis construct with space separated names is also allowed for ++specifying objects. For names with integer suffixes a range can also be used, ++e.g. (foo1 bar2-5), specifies DSOs foo1, bar2, bar2, bar3, bar4, bar5. ++ ++A {} construct specifies the main test program, and its link dependencies ++are also specified using ->. Inside {}, a few ;-separated constructs are ++allowed: ++ +a Loads module a using dlopen(RTLD_LAZY|RTLD_GLOBAL) ++ ^a Loads module a using dlopen(RTLD_LAZY) ++ %a Use dlsym() to load and call fn_a() ++ @a Calls fn_a() directly. ++ -a Unloads module a using dlclose() ++ ++The generated main program outputs '{' '}' with all output from above ++constructs in between. The other output before/after {} are the ordered ++constructor/destructor output. ++ ++If no {} construct is present, a default empty main program is linked ++against all objects which have no dependency linked to it. e.g. for ++'[ab]->c;d->e', the default main program is equivalent to '{}->[abd]' ++ ++Sometimes for very complex or large testcases, besides specifying a ++few explicit dependencies from main{}, the above default dependency ++behavior is still useful to automatically have, but is turned off ++upon specifying a single explicit {}->dso_name. ++In this case, add {}->* to explicitly add this generation behavior: ++ ++ # Main program links to 'foo', and all other objects which have no ++ # dependency linked to it. ++ {}->foo,{}->* ++ ++Note that '*' works not only on main{}, but can be used as the ++dependency target of any object. Note that it only works as a target, ++not a dependency source. ++ ++The '!' operator after object names turns on permutation of its ++dependencies, e.g. while a->[bcd] only generates one set of objects, ++with 'a.so' built with a link line of "b.so c.so d.so", for a!->[bcd] ++permutations of a's dependencies creates multiple testcases with ++different link line orders: "b.so c.so d.so", "c.so b.so d.so", ++"b.so d.so c.so", etc. Note that for a specified on ++the script command-line, multiple , , etc. ++tests will be generated (e.g. for a!->[bc]!->[de], eight tests with ++different link orders for a, b, and c will be generated) ++ ++It is possible to specify the ELF soname field for an object or the ++main program: ++ # DSO 'a' will be linked with the appropriate -Wl,-soname=x setting ++ a->b->c;soname(a)=x ++ # The the main program can also have a soname specified ++ soname({})=y ++ ++This can be used to test how ld.so behaves when objects and/or the ++main program have such a field set. ++ ++ ++Strings Output by Generated Testcase Programs ++ ++The text output produced by a generated testcase consists of three main ++parts: ++ 1. The constructors' output ++ 2. Output from the main program ++ 3. Destructors' output ++ ++To see by example, a simple test description "a->b->c" generates a testcase ++that when run, outputs: "c>b>a>{}' character, ++and the "c>b>a" part above is the full constructor output by all DSOs, the ++order indicating that DSO 'c', which does not depend on any other DSO, has ++its constructor run first, followed by 'b' and then 'a'. ++ ++Destructor output for each DSO is a '<' character followed by its name, ++reflecting its reverse nature of constructors. In the above example, the ++destructor output part is "g=>h;{+c;%c;-c}->a->h ++ ++This produces a testcase, that when executed outputs: ++ h>a>{+c[g>c>];%c();-c[h dependency as expected. ++Inside the main program, the "+c" action triggers a dlopen() of DSO 'c', ++causing another chain of constructors "g>c>" to be triggered. Here it is ++displayed inside [] brackets for each dlopen call. The same is done for "-c", ++a dlclose() of 'c'. ++ ++The "%c" output is due to calling to fn_c() inside DSO 'c', this comprises ++of two parts: the '%' character is printed by the caller, here it is the main ++program. The 'c' character is printed from inside fn_c(). The '%' character ++indicates that this is called by a dlsym() of "fn_c". A '@' character would ++mean a direct call (with a symbol reference). These can all be controlled ++by the main test program constructs documented earlier. ++ ++The output strings described here is the exact same form placed in ++test description files' "output: " line. ++""" ++ ++import sys ++import re ++import os ++import subprocess ++import argparse ++from collections import OrderedDict ++import itertools ++ ++# BUILD_GCC is only used under the --build option, ++# which builds the generated testcase, including DSOs using BUILD_GCC. ++# Mainly for testing purposes, especially debugging of this script, ++# and can be changed here to another toolchain path if needed. ++build_gcc = "gcc" ++ ++def get_parser(): ++ parser = argparse.ArgumentParser("") ++ parser.add_argument("description", ++ help="Description string of DSO dependency test to be " ++ "generated (see script source for documentation of " ++ "description language), either specified here as " ++ "command line argument, or by input file using " ++ "-f/--description-file option", ++ nargs="?", default="") ++ parser.add_argument("test_name", ++ help="Identifier for testcase being generated", ++ nargs="?", default="") ++ parser.add_argument("--objpfx", ++ help="Path to place generated files, defaults to " ++ "current directory if none specified", ++ nargs="?", default="./") ++ parser.add_argument("-m", "--output-makefile", ++ help="File to write Makefile fragment to, defaults to " ++ "stdout when option not present", ++ nargs="?", default="") ++ parser.add_argument("-f", "--description-file", ++ help="Input file containing testcase descriptions", ++ nargs="?", default="") ++ parser.add_argument("--build", help="After C testcase generated, build it " ++ "using gcc (for manual testing purposes)", ++ action="store_true") ++ parser.add_argument("--debug-output", ++ help="Prints some internal data " ++ "structures; used for debugging of this script", ++ action="store_true") ++ return parser ++ ++# Main script starts here. ++cmdlineargs = get_parser().parse_args() ++test_name = cmdlineargs.test_name ++description = cmdlineargs.description ++objpfx = cmdlineargs.objpfx ++description_file = cmdlineargs.description_file ++output_makefile = cmdlineargs.output_makefile ++makefile = "" ++default_tunable_options = [] ++ ++current_input_lineno = 0 ++def error(msg): ++ global current_input_lineno ++ print("Error: %s%s" % ((("Line %d, " % current_input_lineno) ++ if current_input_lineno != 0 else ""), ++ msg)) ++ exit(1) ++ ++if(test_name or description) and description_file: ++ error("both command-line testcase and input file specified") ++if test_name and not description: ++ error("command-line testcase name without description string") ++ ++# Main class type describing a testcase. ++class TestDescr: ++ def __init__(self): ++ self.objs = [] # list of all DSO objects ++ self.deps = OrderedDict() # map of DSO object -> list of dependencies ++ ++ # map of DSO object -> list of call refs ++ self.callrefs = OrderedDict() ++ ++ # map of DSO object -> list of permutations of dependencies ++ self.dep_permutations = OrderedDict() ++ ++ # map of DSO object -> SONAME of object (if one is specified) ++ self.soname_map = OrderedDict() ++ ++ # list of main program operations ++ self.main_program = [] ++ # set if default dependencies added to main ++ self.main_program_default_deps = True ++ ++ self.test_name = "" # name of testcase ++ self.expected_outputs = OrderedDict() # expected outputs of testcase ++ self.xfail = False # set if this is a XFAIL testcase ++ self.xtest = False # set if this is put under 'xtests' ++ ++ # Add 'object -> [object, object, ...]' relations to CURR_MAP ++ def __add_deps_internal(self, src_objs, dst_objs, curr_map): ++ for src in src_objs: ++ for dst in dst_objs: ++ if not src in curr_map: ++ curr_map[src] = [] ++ if not dst in curr_map[src]: ++ curr_map[src].append(dst) ++ def add_deps(self, src_objs, dst_objs): ++ self.__add_deps_internal(src_objs, dst_objs, self.deps) ++ def add_callrefs(self, src_objs, dst_objs): ++ self.__add_deps_internal(src_objs, dst_objs, self.callrefs) ++ ++# Process commands inside the {} construct. ++# Note that throughout this script, the main program object is represented ++# by the '#' string. ++def process_main_program(test_descr, mainprog_str): ++ if mainprog_str: ++ test_descr.main_program = mainprog_str.split(';') ++ for s in test_descr.main_program: ++ m = re.match(r"^([+\-%^@])([0-9a-zA-Z]+)$", s) ++ if not m: ++ error("'%s' is not recognized main program operation" % (s)) ++ opr = m.group(1) ++ obj = m.group(2) ++ if not obj in test_descr.objs: ++ test_descr.objs.append(obj) ++ if opr == '%' or opr == '@': ++ test_descr.add_callrefs(['#'], [obj]) ++ # We have a main program specified, turn this off ++ test_descr.main_program_default_deps = False ++ ++# For(a1 a2 b1-12) object set descriptions, expand into an object list ++def expand_object_set_string(descr_str): ++ obj_list = [] ++ descr_list = descr_str.split() ++ for descr in descr_list: ++ m = re.match(r"^([a-zA-Z][0-9a-zA-Z]*)(-[0-9]+)?$", descr) ++ if not m: ++ error("'%s' is not a valid object set description" % (descr)) ++ obj = m.group(1) ++ idx_end = m.group(2) ++ if not idx_end: ++ if not obj in obj_list: ++ obj_list.append(obj) ++ else: ++ idx_end = int(idx_end[1:]) ++ m = re.match(r"^([0-9a-zA-Z][a-zA-Z]*)([0-9]+)$", obj) ++ if not m: ++ error("object description '%s' is malformed" % (obj)) ++ obj_name = m.group(1) ++ idx_start = int(m.group (2)) ++ if idx_start > idx_end: ++ error("index range %s-%s invalid" % (idx_start, idx_end)) ++ for i in range(idx_start, idx_end + 1): ++ o = obj_name + str(i) ++ if not o in obj_list: ++ obj_list.append(o) ++ return obj_list ++ ++# Lexer for tokens ++tokenspec = [ ("SONAME", r"soname\(([0-9a-zA-Z{}]+)\)=([0-9a-zA-Z]+)"), ++ ("OBJ", r"([0-9a-zA-Z]+)"), ++ ("DEP", r"->"), ++ ("CALLREF", r"=>"), ++ ("OBJSET", r"\[([0-9a-zA-Z]+)\]"), ++ ("OBJSET2", r"\(([0-9a-zA-Z \-]+)\)"), ++ ("OBJSET3", r"\*"), ++ ("PROG", r"{([0-9a-zA-Z;+^\-%@]*)}"), ++ ("PERMUTE", r"!"), ++ ("SEMICOL", r";"), ++ ("ERROR", r".") ] ++tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tokenspec) ++ ++# Main line parser of description language ++def parse_description_string(t, descr_str): ++ # State used when parsing dependencies ++ curr_objs = [] ++ in_dep = False ++ in_callref = False ++ def clear_dep_state(): ++ nonlocal in_dep, in_callref ++ in_dep = in_callref = False ++ ++ for m in re.finditer(tok_re, descr_str): ++ kind = m.lastgroup ++ value = m.group() ++ if kind == "SONAME": ++ s = re.match(r"soname\(([0-9a-zA-Z{}]+)\)=([0-9a-zA-Z]+)", value) ++ obj = s.group(1) ++ val = s.group(2) ++ if obj == "{}": ++ if '#' in t.soname_map: ++ error("soname of main program already set") ++ # Adjust to internal name ++ obj = '#' ++ else: ++ if re.match(r"[{}]", obj): ++ error("invalid object name '%s'" % (obj)) ++ if not obj in t.objs: ++ error("'%s' is not name of already defined object" % (obj)) ++ if obj in t.soname_map: ++ error("'%s' already has soname of '%s' set" ++ % (obj, t.soname_map[obj])) ++ t.soname_map[obj] = val ++ ++ elif kind == "OBJ": ++ if in_dep: ++ t.add_deps(curr_objs, [value]) ++ elif in_callref: ++ t.add_callrefs(curr_objs, [value]) ++ clear_dep_state() ++ curr_objs = [value] ++ if not value in t.objs: ++ t.objs.append(value) ++ ++ elif kind == "OBJSET": ++ objset = value[1:len(value)-1] ++ if in_dep: ++ t.add_deps(curr_objs, list (objset)) ++ elif in_callref: ++ t.add_callrefs(curr_objs, list (objset)) ++ clear_dep_state() ++ curr_objs = list(objset) ++ for o in list(objset): ++ if not o in t.objs: ++ t.objs.append(o) ++ ++ elif kind == "OBJSET2": ++ descr_str = value[1:len(value)-1] ++ descr_str.strip() ++ objs = expand_object_set_string(descr_str) ++ if not objs: ++ error("empty object set '%s'" % (value)) ++ if in_dep: ++ t.add_deps(curr_objs, objs) ++ elif in_callref: ++ t.add_callrefs(curr_objs, objs) ++ clear_dep_state() ++ curr_objs = objs ++ for o in objs: ++ if not o in t.objs: ++ t.objs.append(o) ++ ++ elif kind == "OBJSET3": ++ if in_dep: ++ t.add_deps(curr_objs, ['*']) ++ elif in_callref: ++ t.add_callrefs(curr_objs, ['*']) ++ else: ++ error("non-dependence target set '*' can only be used " ++ "as target of ->/=> operations") ++ clear_dep_state() ++ curr_objs = ['*'] ++ ++ elif kind == "PERMUTE": ++ if in_dep or in_callref: ++ error("syntax error, permute operation invalid here") ++ if not curr_objs: ++ error("syntax error, no objects to permute here") ++ ++ for obj in curr_objs: ++ if not obj in t.dep_permutations: ++ # Signal this object has permuted dependencies ++ t.dep_permutations[obj] = [] ++ ++ elif kind == "PROG": ++ if t.main_program: ++ error("cannot have more than one main program") ++ if in_dep: ++ error("objects cannot have dependency on main program") ++ if in_callref: ++ # TODO: A DSO can resolve to a symbol in the main binary, ++ # which we syntactically allow here, but haven't yet ++ # implemented. ++ t.add_callrefs(curr_objs, ["#"]) ++ process_main_program(t, value[1:len(value)-1]) ++ clear_dep_state() ++ curr_objs = ["#"] ++ ++ elif kind == "DEP": ++ if in_dep or in_callref: ++ error("syntax error, multiple contiguous ->,=> operations") ++ if '*' in curr_objs: ++ error("non-dependence target set '*' can only be used " ++ "as target of ->/=> operations") ++ in_dep = True ++ ++ elif kind == "CALLREF": ++ if in_dep or in_callref: ++ error("syntax error, multiple contiguous ->,=> operations") ++ if '*' in curr_objs: ++ error("non-dependence target set '*' can only be used " ++ "as target of ->/=> operations") ++ in_callref = True ++ ++ elif kind == "SEMICOL": ++ curr_objs = [] ++ clear_dep_state() ++ ++ else: ++ error("unknown token '%s'" % (value)) ++ return t ++ ++# Main routine to process each testcase description ++def process_testcase(t): ++ global objpfx ++ assert t.test_name ++ ++ base_test_name = t.test_name ++ test_subdir = base_test_name + "-dir" ++ testpfx = objpfx + test_subdir + "/" ++ ++ if not os.path.exists(testpfx): ++ os.mkdir(testpfx) ++ ++ def find_objs_not_depended_on(t): ++ objs_not_depended_on = [] ++ for obj in t.objs: ++ skip = False ++ for r in t.deps.items(): ++ if obj in r[1]: ++ skip = True ++ break ++ if not skip: ++ objs_not_depended_on.append(obj) ++ return objs_not_depended_on ++ ++ non_dep_tgt_objs = find_objs_not_depended_on(t) ++ for obj in t.objs: ++ if obj in t.deps: ++ deps = t.deps[obj] ++ if '*' in deps: ++ t.deps[obj].remove('*') ++ t.add_deps([obj], non_dep_tgt_objs) ++ if obj in t.callrefs: ++ deps = t.callrefs[obj] ++ if '*' in deps: ++ t.deps[obj].remove('*') ++ t.add_callrefs([obj], non_dep_tgt_objs) ++ if "#" in t.deps: ++ deps = t.deps["#"] ++ if '*' in deps: ++ t.deps["#"].remove('*') ++ t.add_deps(["#"], non_dep_tgt_objs) ++ ++ # If no main program was specified in dependency description, make a ++ # default main program with deps pointing to all DSOs which are not ++ # depended by another DSO. ++ if t.main_program_default_deps: ++ main_deps = non_dep_tgt_objs ++ if not main_deps: ++ error("no objects for default main program to point " ++ "dependency to(all objects strongly connected?)") ++ t.add_deps(["#"], main_deps) ++ ++ # Some debug output ++ if cmdlineargs.debug_output: ++ print("Testcase: %s" % (t.test_name)) ++ print("All objects: %s" % (t.objs)) ++ print("--- Static link dependencies ---") ++ for r in t.deps.items(): ++ print("%s -> %s" % (r[0], r[1])) ++ print("--- Objects whose dependencies are to be permuted ---") ++ for r in t.dep_permutations.items(): ++ print("%s" % (r[0])) ++ print("--- Call reference dependencies ---") ++ for r in t.callrefs.items(): ++ print("%s => %s" % (r[0], r[1])) ++ print("--- main program ---") ++ print(t.main_program) ++ ++ # Main testcase generation routine, does Makefile fragment generation, ++ # testcase source generation, and if --build specified builds testcase. ++ def generate_testcase(test_descr, test_suffix): ++ ++ test_name = test_descr.test_name + test_suffix ++ ++ # Print out needed Makefile fragments for use in glibc/elf/Makefile. ++ module_names = "" ++ for o in test_descr.objs: ++ module_names += " " + test_subdir + "/" + test_name + "-" + o ++ makefile.write("modules-names +=%s\n" % (module_names)) ++ ++ # Depth-first traversal, executing FN(OBJ) in post-order ++ def dfs(t, fn): ++ def dfs_rec(obj, fn, obj_visited): ++ if obj in obj_visited: ++ return ++ obj_visited[obj] = True ++ if obj in t.deps: ++ for dep in t.deps[obj]: ++ dfs_rec(dep, fn, obj_visited) ++ fn(obj) ++ ++ obj_visited = {} ++ for obj in t.objs: ++ dfs_rec(obj, fn, obj_visited) ++ ++ # Generate link dependencies for all DSOs, done in a DFS fashion. ++ # Usually this doesn't need to be this complex, just listing the direct ++ # dependencies is enough. However to support creating circular ++ # dependency situations, traversing it by DFS and tracking processing ++ # status is the natural way to do it. ++ obj_processed = {} ++ fake_created = {} ++ def gen_link_deps(obj): ++ if obj in test_descr.deps: ++ dso = test_subdir + "/" + test_name + "-" + obj + ".so" ++ dependencies = "" ++ for dep in test_descr.deps[obj]: ++ if dep in obj_processed: ++ depstr = (" $(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".so") ++ else: ++ # A circular dependency is satisfied by making a ++ # fake DSO tagged with the correct SONAME ++ depstr = (" $(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".FAKE.so") ++ # Create empty C file and Makefile fragments for fake ++ # object. This only needs to be done at most once for ++ # an object name. ++ if not dep in fake_created: ++ f = open(testpfx + test_name + "-" + dep ++ + ".FAKE.c", "w") ++ f.write(" \n") ++ f.close() ++ # Generate rule to create fake object ++ makefile.write \ ++ ("LDFLAGS-%s = -Wl,--no-as-needed " ++ "-Wl,-soname=%s\n" ++ % (test_name + "-" + dep + ".FAKE.so", ++ ("$(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".so"))) ++ makefile.write \ ++ ("modules-names += %s\n" ++ % (test_subdir + "/" ++ + test_name + "-" + dep + ".FAKE")) ++ fake_created[dep] = True ++ dependencies += depstr ++ makefile.write("$(objpfx)%s:%s\n" % (dso, dependencies)) ++ # Mark obj as processed ++ obj_processed[obj] = True ++ ++ dfs(test_descr, gen_link_deps) ++ ++ # Print LDFLAGS-* and *-no-z-defs ++ for o in test_descr.objs: ++ dso = test_name + "-" + o + ".so" ++ ldflags = "-Wl,--no-as-needed" ++ if o in test_descr.soname_map: ++ soname = ("$(objpfx)" + test_subdir + "/" ++ + test_name + "-" ++ + test_descr.soname_map[o] + ".so") ++ ldflags += (" -Wl,-soname=" + soname) ++ makefile.write("LDFLAGS-%s = %s\n" % (dso, ldflags)) ++ if o in test_descr.callrefs: ++ makefile.write("%s-no-z-defs = yes\n" % (dso)) ++ ++ # Print dependencies for main test program. ++ depstr = "" ++ if '#' in test_descr.deps: ++ for o in test_descr.deps['#']: ++ depstr += (" $(objpfx)" + test_subdir + "/" ++ + test_name + "-" + o + ".so") ++ makefile.write("$(objpfx)%s/%s:%s\n" % (test_subdir, test_name, depstr)) ++ ldflags = "-Wl,--no-as-needed" ++ if '#' in test_descr.soname_map: ++ soname = ("$(objpfx)" + test_subdir + "/" ++ + test_name + "-" ++ + test_descr.soname_map['#'] + ".so") ++ ldflags += (" -Wl,-soname=" + soname) ++ makefile.write("LDFLAGS-%s = %s\n" % (test_name, ldflags)) ++ ++ not_depended_objs = find_objs_not_depended_on(test_descr) ++ if not_depended_objs: ++ depstr = "" ++ for dep in not_depended_objs: ++ depstr += (" $(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".so") ++ makefile.write("$(objpfx)%s.out:%s\n" % (base_test_name, depstr)) ++ ++ # Add main executable to test-srcs ++ makefile.write("test-srcs += %s/%s\n" % (test_subdir, test_name)) ++ # Add dependency on main executable of test ++ makefile.write("$(objpfx)%s.out: $(objpfx)%s/%s\n" ++ % (base_test_name, test_subdir, test_name)) ++ ++ for r in test_descr.expected_outputs.items(): ++ tunable_options = [] ++ specific_tunable = r[0] ++ xfail = r[1][1] ++ if specific_tunable != "": ++ tunable_options = [specific_tunable] ++ else: ++ tunable_options = default_tunable_options ++ if not tunable_options: ++ tunable_options = [""] ++ ++ for tunable in tunable_options: ++ tunable_env = "" ++ tunable_sfx = "" ++ exp_tunable_sfx = "" ++ if tunable: ++ tunable_env = "GLIBC_TUNABLES=%s " % tunable ++ tunable_sfx = "-" + tunable.replace("=","_") ++ if specific_tunable: ++ tunable_sfx = "-" + specific_tunable.replace("=","_") ++ exp_tunable_sfx = tunable_sfx ++ tunable_descr = ("(%s)" % tunable_env.strip() ++ if tunable_env else "") ++ # Write out fragment of shell script for this single test. ++ test_descr.sh.write \ ++ ("%s${test_wrapper_env} ${run_program_env} \\\n" ++ "${common_objpfx}support/test-run-command \\\n" ++ "${common_objpfx}elf/ld.so \\\n" ++ "--library-path ${common_objpfx}elf/%s:" ++ "${common_objpfx}elf:${common_objpfx}.:" ++ "${common_objpfx}dlfcn \\\n" ++ "${common_objpfx}elf/%s/%s > \\\n" ++ " ${common_objpfx}elf/%s/%s%s.output\n" ++ % (tunable_env ,test_subdir, ++ test_subdir, test_name, test_subdir, test_name, ++ tunable_sfx)) ++ # Generate a run of each test and compare with expected out ++ test_descr.sh.write \ ++ ("if [ $? -ne 0 ]; then\n" ++ " echo '%sFAIL: %s%s execution test'\n" ++ " something_failed=true\n" ++ "else\n" ++ " diff -wu ${common_objpfx}elf/%s/%s%s.output \\\n" ++ " ${common_objpfx}elf/%s/%s%s.exp\n" ++ " if [ $? -ne 0 ]; then\n" ++ " echo '%sFAIL: %s%s expected output comparison'\n" ++ " something_failed=true\n" ++ " fi\n" ++ "fi\n" ++ % (("X" if xfail else ""), test_name, tunable_descr, ++ test_subdir, test_name, tunable_sfx, ++ test_subdir, base_test_name, exp_tunable_sfx, ++ ("X" if xfail else ""), test_name, tunable_descr)) ++ ++ # Generate C files according to dependency and calling relations from ++ # description string. ++ for obj in test_descr.objs: ++ src_name = test_name + "-" + obj + ".c" ++ f = open(testpfx + src_name, "w") ++ if obj in test_descr.callrefs: ++ called_objs = test_descr.callrefs[obj] ++ for callee in called_objs: ++ f.write("extern void fn_%s (void);\n" % (callee)) ++ if len(obj) == 1: ++ f.write("extern int putchar(int);\n") ++ f.write("static void __attribute__((constructor)) " + ++ "init(void){putchar('%s');putchar('>');}\n" % (obj)) ++ f.write("static void __attribute__((destructor)) " + ++ "fini(void){putchar('<');putchar('%s');}\n" % (obj)) ++ else: ++ f.write('extern int printf(const char *, ...);\n') ++ f.write('static void __attribute__((constructor)) ' + ++ 'init(void){printf("%s>");}\n' % (obj)) ++ f.write('static void __attribute__((destructor)) ' + ++ 'fini(void){printf("<%s");}\n' % (obj)) ++ if obj in test_descr.callrefs: ++ called_objs = test_descr.callrefs[obj] ++ if len(obj) != 1: ++ f.write("extern int putchar(int);\n") ++ f.write("void fn_%s (void) {\n" % (obj)) ++ if len(obj) == 1: ++ f.write(" putchar ('%s');\n" % (obj)); ++ f.write(" putchar ('(');\n"); ++ else: ++ f.write(' printf ("%s(");\n' % (obj)); ++ for callee in called_objs: ++ f.write(" fn_%s ();\n" % (callee)) ++ f.write(" putchar (')');\n"); ++ f.write("}\n") ++ else: ++ for callref in test_descr.callrefs.items(): ++ if obj in callref[1]: ++ if len(obj) == 1: ++ # We need to declare printf here in this case. ++ f.write('extern int printf(const char *, ...);\n') ++ f.write("void fn_%s (void) {\n" % (obj)) ++ f.write(' printf ("%s()");\n' % (obj)) ++ f.write("}\n") ++ break ++ f.close() ++ ++ # Open C file for writing main program ++ f = open(testpfx + test_name + ".c", "w") ++ ++ # if there are some operations in main(), it means we need -ldl ++ f.write("#include \n") ++ f.write("#include \n") ++ f.write("#include \n") ++ for s in test_descr.main_program: ++ if s[0] == '@': ++ f.write("extern void fn_%s (void);\n" % (s[1:])); ++ f.write("int main (void) {\n") ++ f.write(" putchar('{');\n") ++ ++ # Helper routine for generating sanity checking code. ++ def put_fail_check(fail_cond, action_desc): ++ f.write(' if (%s) { printf ("\\n%s failed: %%s\\n", ' ++ 'dlerror()); exit (1);}\n' % (fail_cond, action_desc)) ++ i = 0 ++ while i < len(test_descr.main_program): ++ s = test_descr.main_program[i] ++ obj = s[1:] ++ dso = test_name + "-" + obj ++ if s[0] == '+' or s[0] == '^': ++ if s[0] == '+': ++ dlopen_flags = "RTLD_LAZY|RTLD_GLOBAL" ++ f.write(" putchar('+');\n"); ++ else: ++ dlopen_flags = "RTLD_LAZY" ++ f.write(" putchar(':');\n"); ++ if len(obj) == 1: ++ f.write(" putchar('%s');\n" % (obj)); ++ else: ++ f.write(' printf("%s");\n' % (obj)); ++ f.write(" putchar('[');\n"); ++ f.write(' void *%s = dlopen ("%s.so", %s);\n' ++ % (obj, dso, dlopen_flags)) ++ put_fail_check("!%s" % (obj), ++ "%s.so dlopen" % (dso)) ++ f.write(" putchar(']');\n"); ++ elif s[0] == '-': ++ f.write(" putchar('-');\n"); ++ if len(obj) == 1: ++ f.write(" putchar('%s');\n" % (obj)); ++ else: ++ f.write(' printf("%s");\n' % (obj)); ++ f.write(" putchar('[');\n"); ++ put_fail_check("dlclose (%s) != 0" % (obj), ++ "%s.so dlclose" % (dso)) ++ f.write(" putchar(']');\n"); ++ elif s[0] == '%': ++ f.write(" putchar('%');\n"); ++ f.write(' void (*fn_%s)(void) = dlsym (%s, "fn_%s");\n' ++ % (obj, obj, obj)) ++ put_fail_check("!fn_%s" % (obj), ++ "dlsym(fn_%s) from %s.so" % (obj, dso)) ++ f.write(" fn_%s ();\n" % (obj)) ++ elif s[0] == '@': ++ f.write(" putchar('@');\n"); ++ f.write(" fn_%s ();\n" % (obj)) ++ f.write(" putchar(';');\n"); ++ i += 1 ++ f.write(" putchar('}');\n") ++ f.write(" return 0;\n") ++ f.write("}\n") ++ f.close() ++ ++ # --build option processing: build generated sources using 'build_gcc' ++ if cmdlineargs.build: ++ # Helper routine to run a shell command, for running GCC below ++ def run_cmd(args): ++ cmd = str.join(' ', args) ++ if cmdlineargs.debug_output: ++ print(cmd) ++ p = subprocess.Popen(args) ++ p.wait() ++ if p.returncode != 0: ++ error("error running command: %s" % (cmd)) ++ ++ # Compile individual .os files ++ for obj in test_descr.objs: ++ src_name = test_name + "-" + obj + ".c" ++ obj_name = test_name + "-" + obj + ".os" ++ run_cmd([build_gcc, "-c", "-fPIC", testpfx + src_name, ++ "-o", testpfx + obj_name]) ++ ++ obj_processed = {} ++ fake_created = {} ++ # Function to create -.so ++ def build_dso(obj): ++ obj_name = test_name + "-" + obj + ".os" ++ dso_name = test_name + "-" + obj + ".so" ++ deps = [] ++ if obj in test_descr.deps: ++ for dep in test_descr.deps[obj]: ++ if dep in obj_processed: ++ deps.append(dep) ++ else: ++ deps.append(dep + ".FAKE") ++ if not dep in fake_created: ++ base_name = testpfx + test_name + "-" + dep ++ cmd = [build_gcc, "-Wl,--no-as-needed", ++ ("-Wl,-soname=" + base_name + ".so"), ++ "-shared", base_name + ".FAKE.c", ++ "-o", base_name + ".FAKE.so"] ++ run_cmd(cmd) ++ fake_created[dep] = True ++ dso_deps = map(lambda d: testpfx + test_name + "-" + d + ".so", ++ deps) ++ cmd = [build_gcc, "-shared", "-o", testpfx + dso_name, ++ testpfx + obj_name, "-Wl,--no-as-needed"] ++ if obj in test_descr.soname_map: ++ soname = ("-Wl,-soname=" + testpfx + test_name + "-" ++ + test_descr.soname_map[obj] + ".so") ++ cmd += [soname] ++ cmd += list(dso_deps) ++ run_cmd(cmd) ++ obj_processed[obj] = True ++ ++ # Build all DSOs, this needs to be in topological dependency order, ++ # or link will fail ++ dfs(test_descr, build_dso) ++ ++ # Build main program ++ deps = [] ++ if '#' in test_descr.deps: ++ deps = test_descr.deps['#'] ++ main_deps = map(lambda d: testpfx + test_name + "-" + d + ".so", ++ deps) ++ cmd = [build_gcc, "-Wl,--no-as-needed", "-o", testpfx + test_name, ++ testpfx + test_name + ".c", "-L%s" % (os.getcwd()), ++ "-Wl,-rpath-link=%s" % (os.getcwd())] ++ if '#' in test_descr.soname_map: ++ soname = ("-Wl,-soname=" + testpfx + test_name + "-" ++ + test_descr.soname_map['#'] + ".so") ++ cmd += [soname] ++ cmd += list(main_deps) ++ run_cmd(cmd) ++ ++ # Check if we need to enumerate permutations of dependencies ++ need_permutation_processing = False ++ if t.dep_permutations: ++ # Adjust dep_permutations into map of object -> dependency permutations ++ for r in t.dep_permutations.items(): ++ obj = r[0] ++ if obj in t.deps and len(t.deps[obj]) > 1: ++ deps = t.deps[obj] ++ t.dep_permutations[obj] = list(itertools.permutations (deps)) ++ need_permutation_processing = True ++ ++ def enum_permutations(t, perm_list): ++ test_subindex = 1 ++ curr_perms = [] ++ def enum_permutations_rec(t, perm_list): ++ nonlocal test_subindex, curr_perms ++ if len(perm_list) >= 1: ++ curr = perm_list[0] ++ obj = curr[0] ++ perms = curr[1] ++ if not perms: ++ # This may be an empty list if no multiple dependencies to ++ # permute were found, skip to next in this case ++ enum_permutations_rec(t, perm_list[1:]) ++ else: ++ for deps in perms: ++ t.deps[obj] = deps ++ permstr = "" if obj == "#" else obj + "_" ++ permstr += str.join('', deps) ++ curr_perms.append(permstr) ++ enum_permutations_rec(t, perm_list[1:]) ++ curr_perms = curr_perms[0:len(curr_perms)-1] ++ else: ++ # t.deps is now instantiated with one dependency order ++ # permutation(across all objects that have multiple ++ # permutations), now process a testcase ++ generate_testcase(t, ("_" + str (test_subindex) ++ + "-" + str.join('-', curr_perms))) ++ test_subindex += 1 ++ enum_permutations_rec(t, perm_list) ++ ++ # Create *.exp files with expected outputs ++ for r in t.expected_outputs.items(): ++ sfx = "" ++ if r[0] != "": ++ sfx = "-" + r[0].replace("=","_") ++ f = open(testpfx + t.test_name + sfx + ".exp", "w") ++ (output, xfail) = r[1] ++ f.write('%s' % output) ++ f.close() ++ ++ # Create header part of top-level testcase shell script, to wrap execution ++ # and output comparison together. ++ t.sh = open(testpfx + t.test_name + ".sh", "w") ++ t.sh.write("#!/bin/sh\n") ++ t.sh.write("# Test driver for %s, generated by " ++ "dso-ordering-test.py\n" % (t.test_name)) ++ t.sh.write("common_objpfx=$1\n") ++ t.sh.write("test_wrapper_env=$2\n") ++ t.sh.write("run_program_env=$3\n") ++ t.sh.write("something_failed=false\n") ++ ++ # Starting part of Makefile fragment ++ makefile.write("ifeq (yes,$(build-shared))\n") ++ ++ if need_permutation_processing: ++ enum_permutations(t, list (t.dep_permutations.items())) ++ else: ++ # We have no permutations to enumerate, just process testcase normally ++ generate_testcase(t, "") ++ ++ # If testcase is XFAIL, indicate so ++ if t.xfail: ++ makefile.write("test-xfail-%s = yes\n" % t.test_name) ++ ++ # Output end part of Makefile fragment ++ expected_output_files = "" ++ for r in t.expected_outputs.items(): ++ sfx = "" ++ if r[0] != "": ++ sfx = "-" + r[0].replace("=","_") ++ expected_output_files += " $(objpfx)%s/%s%s.exp" % (test_subdir, ++ t.test_name, sfx) ++ makefile.write \ ++ ("$(objpfx)%s.out: $(objpfx)%s/%s.sh%s " ++ "$(common-objpfx)support/test-run-command\n" ++ % (t.test_name, test_subdir, t.test_name, ++ expected_output_files)) ++ makefile.write("\t$(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' " ++ "'$(run-program-env)' > $@; $(evaluate-test)\n") ++ makefile.write("ifeq ($(run-built-tests),yes)\n") ++ if t.xtest: ++ makefile.write("xtests-special += $(objpfx)%s.out\n" % (t.test_name)) ++ else: ++ makefile.write("tests-special += $(objpfx)%s.out\n" % (t.test_name)) ++ makefile.write("endif\n") ++ makefile.write("endif\n") ++ ++ # Write ending part of shell script generation ++ t.sh.write("if $something_failed; then\n" ++ " exit 1\n" ++ "else\n" ++ " echo '%sPASS: all tests for %s succeeded'\n" ++ " exit 0\n" ++ "fi\n" % (("X" if t.xfail else ""), ++ t.test_name)) ++ t.sh.close() ++ ++# Decription file parsing ++def parse_description_file(filename): ++ global default_tunable_options ++ global current_input_lineno ++ f = open(filename) ++ if not f: ++ error("cannot open description file %s" % (filename)) ++ descrfile_lines = f.readlines() ++ t = None ++ for line in descrfile_lines: ++ p = re.compile(r"#.*$") ++ line = p.sub("", line) # Filter out comments ++ line = line.strip() # Remove excess whitespace ++ current_input_lineno += 1 ++ ++ m = re.match(r"^tunable_option:\s*(.*)$", line) ++ if m: ++ if m.group(1) == "": ++ error("tunable option cannot be empty") ++ default_tunable_options.append(m.group (1)) ++ continue ++ ++ m = re.match(r"^clear_tunables$", line) ++ if m: ++ default_tunable_options = [] ++ continue ++ ++ m = re.match(r"^([^:]+):\s*(.*)$", line) ++ if m: ++ lhs = m.group(1) ++ o = re.match(r"^output(.*)$", lhs) ++ xfail = False ++ if not o: ++ o = re.match(r"^xfail_output(.*)$", lhs) ++ if o: ++ xfail = True; ++ if o: ++ if not t: ++ error("output specification without testcase description") ++ tsstr = "" ++ if o.group(1): ++ ts = re.match(r"^\(([a-zA-Z0-9_.=]*)\)$", o.group (1)) ++ if not ts: ++ error("tunable option malformed '%s'" % o.group(1)) ++ tsstr = ts.group(1) ++ t.expected_outputs[tsstr] = (m.group(2), xfail) ++ # Any tunable option XFAILed means entire testcase ++ # is XFAIL/XPASS ++ t.xfail |= xfail ++ else: ++ if t: ++ # Starting a new test description, end and process ++ # current one. ++ process_testcase(t) ++ t = TestDescr() ++ x = re.match(r"^xtest\((.*)\)$", lhs) ++ if x: ++ t.xtest = True ++ t.test_name = x.group(1) ++ else: ++ t.test_name = lhs ++ descr_string = m.group(2) ++ parse_description_string(t, descr_string) ++ continue ++ else: ++ if line: ++ if not t: ++ error("no active testcase description") ++ parse_description_string(t, line) ++ # Process last completed test description ++ if t: ++ process_testcase(t) ++ ++# Setup Makefile output to file or stdout as selected ++if output_makefile: ++ output_makefile_dir = os.path.dirname(output_makefile) ++ if output_makefile_dir: ++ os.makedirs(output_makefile_dir, exist_ok = True) ++ makefile = open(output_makefile, "w") ++else: ++ makefile = open(sys.stdout.fileno (), "w") ++ ++# Finally, the main top-level calling of above parsing routines. ++if description_file: ++ parse_description_file(description_file) ++else: ++ t = TestDescr() ++ t.test_name = test_name ++ parse_description_string(t, description) ++ process_testcase(t) ++ ++# Close Makefile fragment output ++makefile.close() +diff --git a/support/Depend b/support/Depend +new file mode 100644 +index 0000000000000000..7e7d5dc67c13e669 +--- /dev/null ++++ b/support/Depend +@@ -0,0 +1 @@ ++elf +diff --git a/support/Makefile b/support/Makefile +index 2a0731796fdb3f2d..75bad6715ac3d08c 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -254,10 +254,16 @@ others-noinstall += shell-container echo-container true-container + others += $(LINKS_DSO_PROGRAM) + others-noinstall += $(LINKS_DSO_PROGRAM) + ++others += test-run-command ++others-static += test-run-command ++others-noinstall += test-run-command ++LDLIBS-test-run-command = $(libsupport) ++ + $(objpfx)test-container : $(libsupport) + $(objpfx)shell-container : $(libsupport) + $(objpfx)echo-container : $(libsupport) + $(objpfx)true-container : $(libsupport) ++$(objpfx)test-run-command : $(libsupport) $(common-objpfx)elf/static-stubs.o + + tests = \ + README-testing \ +diff --git a/support/support_test_main.c b/support/support_test_main.c +index 07e3cdd173cecfc0..66a754b84fbb79ad 100644 +--- a/support/support_test_main.c ++++ b/support/support_test_main.c +@@ -228,6 +228,18 @@ run_test_function (int argc, char **argv, const struct test_config *config) + while (wait_for_debugger) + usleep (1000); + ++ if (config->run_command_mode) ++ { ++ /* In run-command-mode, the child process executes the command line ++ arguments as a new program. */ ++ char **argv_ = xmalloc (sizeof (char *) * argc); ++ memcpy (argv_, &argv[1], sizeof (char *) * (argc - 1)); ++ argv_[argc - 1] = NULL; ++ execv (argv_[0], argv_); ++ printf ("error: should not return here\n"); ++ exit (1); ++ } ++ + if (config->test_function != NULL) + return config->test_function (); + else if (config->test_function_argv != NULL) +diff --git a/support/test-driver.c b/support/test-driver.c +index b0bea46deeb41b3b..1552f62c9b5d0f7b 100644 +--- a/support/test-driver.c ++++ b/support/test-driver.c +@@ -116,7 +116,9 @@ main (int argc, char **argv) + #if defined (TEST_FUNCTION) && defined (TEST_FUNCTON_ARGV) + # error TEST_FUNCTION and TEST_FUNCTION_ARGV cannot be defined at the same time + #endif +-#if defined (TEST_FUNCTION) ++#ifdef RUN_COMMAND_MODE ++ test_config.run_command_mode = 1; ++#elif defined (TEST_FUNCTION) + test_config.test_function = TEST_FUNCTION; + #elif defined (TEST_FUNCTION_ARGV) + test_config.test_function_argv = TEST_FUNCTION_ARGV; +diff --git a/support/test-driver.h b/support/test-driver.h +index 8d4f38275d219de0..b44c0ff03326fca4 100644 +--- a/support/test-driver.h ++++ b/support/test-driver.h +@@ -36,6 +36,7 @@ struct test_config + int expected_signal; /* If non-zero, expect termination by signal. */ + char no_mallopt; /* Boolean flag to disable mallopt. */ + char no_setvbuf; /* Boolean flag to disable setvbuf. */ ++ char run_command_mode; /* Boolean flag to indicate run-command-mode. */ + const char *optstring; /* Short command line options. */ + }; + +diff --git a/support/test-run-command.c b/support/test-run-command.c +new file mode 100644 +index 0000000000000000..61560d7bfb1686a8 +--- /dev/null ++++ b/support/test-run-command.c +@@ -0,0 +1,22 @@ ++/* Main program for test-run-command support utility. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This is basically a configuration of test-driver.c into a general ++ command-line program runner. */ ++#define RUN_COMMAND_MODE ++#include diff --git a/SOURCES/glibc-rh2032647-2.patch b/SOURCES/glibc-rh2032647-2.patch new file mode 100644 index 0000000..4ac1d1a --- /dev/null +++ b/SOURCES/glibc-rh2032647-2.patch @@ -0,0 +1,585 @@ +commit 15a0c5730d1d5aeb95f50c9ec7470640084feae8 +Author: Chung-Lin Tang +Date: Thu Oct 21 21:41:22 2021 +0800 + + elf: Fix slow DSO sorting behavior in dynamic loader (BZ #17645) + + This second patch contains the actual implementation of a new sorting algorithm + for shared objects in the dynamic loader, which solves the slow behavior that + the current "old" algorithm falls into when the DSO set contains circular + dependencies. + + The new algorithm implemented here is simply depth-first search (DFS) to obtain + the Reverse-Post Order (RPO) sequence, a topological sort. A new l_visited:1 + bitfield is added to struct link_map to more elegantly facilitate such a search. + + The DFS algorithm is applied to the input maps[nmap-1] backwards towards + maps[0]. This has the effect of a more "shallow" recursion depth in general + since the input is in BFS. Also, when combined with the natural order of + processing l_initfini[] at each node, this creates a resulting output sorting + closer to the intuitive "left-to-right" order in most cases. + + Another notable implementation adjustment related to this _dl_sort_maps change + is the removing of two char arrays 'used' and 'done' in _dl_close_worker to + represent two per-map attributes. This has been changed to simply use two new + bit-fields l_map_used:1, l_map_done:1 added to struct link_map. This also allows + discarding the clunky 'used' array sorting that _dl_sort_maps had to sometimes + do along the way. + + Tunable support for switching between different sorting algorithms at runtime is + also added. A new tunable 'glibc.rtld.dynamic_sort' with current valid values 1 + (old algorithm) and 2 (new DFS algorithm) has been added. At time of commit + of this patch, the default setting is 1 (old algorithm). + + Signed-off-by: Chung-Lin Tang + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/dl-close.c b/elf/dl-close.c +index cd7b9c9fe83a1a44..f6fbf9de7d78555b 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -167,8 +167,6 @@ _dl_close_worker (struct link_map *map, bool force) + + bool any_tls = false; + const unsigned int nloaded = ns->_ns_nloaded; +- char used[nloaded]; +- char done[nloaded]; + struct link_map *maps[nloaded]; + + /* Run over the list and assign indexes to the link maps and enter +@@ -176,24 +174,21 @@ _dl_close_worker (struct link_map *map, bool force) + int idx = 0; + for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next) + { ++ l->l_map_used = 0; ++ l->l_map_done = 0; + l->l_idx = idx; + maps[idx] = l; + ++idx; +- + } + assert (idx == nloaded); + +- /* Prepare the bitmaps. */ +- memset (used, '\0', sizeof (used)); +- memset (done, '\0', sizeof (done)); +- + /* Keep track of the lowest index link map we have covered already. */ + int done_index = -1; + while (++done_index < nloaded) + { + struct link_map *l = maps[done_index]; + +- if (done[done_index]) ++ if (l->l_map_done) + /* Already handled. */ + continue; + +@@ -204,12 +199,12 @@ _dl_close_worker (struct link_map *map, bool force) + /* 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 +- && !used[done_index]) ++ && !l->l_map_used) + continue; + + /* We need this object and we handle it now. */ +- done[done_index] = 1; +- used[done_index] = 1; ++ l->l_map_used = 1; ++ l->l_map_done = 1; + /* Signal the object is still needed. */ + l->l_idx = IDX_STILL_USED; + +@@ -225,9 +220,9 @@ _dl_close_worker (struct link_map *map, bool force) + { + assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded); + +- if (!used[(*lp)->l_idx]) ++ if (!(*lp)->l_map_used) + { +- used[(*lp)->l_idx] = 1; ++ (*lp)->l_map_used = 1; + /* If we marked a new object as used, and we've + already processed it, then we need to go back + and process again from that point forward to +@@ -250,9 +245,9 @@ _dl_close_worker (struct link_map *map, bool force) + { + assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded); + +- if (!used[jmap->l_idx]) ++ if (!jmap->l_map_used) + { +- used[jmap->l_idx] = 1; ++ jmap->l_map_used = 1; + if (jmap->l_idx - 1 < done_index) + done_index = jmap->l_idx - 1; + } +@@ -262,8 +257,7 @@ _dl_close_worker (struct link_map *map, bool force) + + /* Sort the entries. We can skip looking for the binary itself which is + at the front of the search list for the main namespace. */ +- _dl_sort_maps (maps + (nsid == LM_ID_BASE), nloaded - (nsid == LM_ID_BASE), +- used + (nsid == LM_ID_BASE), true); ++ _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true); + + /* Call all termination functions at once. */ + #ifdef SHARED +@@ -280,7 +274,7 @@ _dl_close_worker (struct link_map *map, bool force) + /* All elements must be in the same namespace. */ + assert (imap->l_ns == nsid); + +- if (!used[i]) ++ if (!imap->l_map_used) + { + assert (imap->l_type == lt_loaded && !imap->l_nodelete_active); + +@@ -333,7 +327,7 @@ _dl_close_worker (struct link_map *map, bool force) + if (i < first_loaded) + first_loaded = i; + } +- /* Else used[i]. */ ++ /* Else imap->l_map_used. */ + else if (imap->l_type == lt_loaded) + { + struct r_scope_elem *new_list = NULL; +@@ -560,7 +554,7 @@ _dl_close_worker (struct link_map *map, bool force) + for (unsigned int i = first_loaded; i < nloaded; ++i) + { + struct link_map *imap = maps[i]; +- if (!used[i]) ++ if (!imap->l_map_used) + { + assert (imap->l_type == lt_loaded); + +diff --git a/elf/dl-deps.c b/elf/dl-deps.c +index 087a49b212a96920..237d9636c5be780c 100644 +--- a/elf/dl-deps.c ++++ b/elf/dl-deps.c +@@ -613,10 +613,9 @@ Filters not supported with LD_TRACE_PRELINKING")); + + /* If libc.so.6 is the main map, it participates in the sort, so + that the relocation order is correct regarding libc.so.6. */ +- if (l_initfini[0] == GL (dl_ns)[l_initfini[0]->l_ns].libc_map) +- _dl_sort_maps (l_initfini, nlist, NULL, false); +- else +- _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false); ++ _dl_sort_maps (l_initfini, nlist, ++ (l_initfini[0] != GL (dl_ns)[l_initfini[0]->l_ns].libc_map), ++ false); + + /* Terminate the list of dependencies. */ + l_initfini[nlist] = NULL; +diff --git a/elf/dl-fini.c b/elf/dl-fini.c +index 6dbdfe4b3ebbeb89..c683884c355dfd52 100644 +--- a/elf/dl-fini.c ++++ b/elf/dl-fini.c +@@ -92,8 +92,7 @@ _dl_fini (void) + /* Now we have to do the sorting. We can skip looking for the + binary itself which is at the front of the search list for + the main namespace. */ +- _dl_sort_maps (maps + (ns == LM_ID_BASE), nmaps - (ns == LM_ID_BASE), +- NULL, true); ++ _dl_sort_maps (maps, nmaps, (ns == LM_ID_BASE), true); + + /* We do not rely on the linked list of loaded object anymore + from this point on. We have our own list here (maps). The +diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c +index d21770267a37e128..a274ed66cc987735 100644 +--- a/elf/dl-sort-maps.c ++++ b/elf/dl-sort-maps.c +@@ -16,16 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include ++#include + ++/* Note: this is the older, "original" sorting algorithm, being used as ++ default up to 2.35. + +-/* Sort array MAPS according to dependencies of the contained objects. +- Array USED, if non-NULL, is permutated along MAPS. If FOR_FINI this is +- called for finishing an object. */ +-void +-_dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, +- bool for_fini) ++ Sort array MAPS according to dependencies of the contained objects. ++ If FOR_FINI is true, this is called for finishing an object. */ ++static void ++_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps, ++ unsigned int skip, bool for_fini) + { ++ /* Allows caller to do the common optimization of skipping the first map, ++ usually the main binary. */ ++ maps += skip; ++ nmaps -= skip; ++ + /* A list of one element need not be sorted. */ + if (nmaps <= 1) + return; +@@ -66,14 +74,6 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, + (k - i) * sizeof (maps[0])); + maps[k] = thisp; + +- if (used != NULL) +- { +- char here_used = used[i]; +- memmove (&used[i], &used[i + 1], +- (k - i) * sizeof (used[0])); +- used[k] = here_used; +- } +- + if (seen[i + 1] > nmaps - i) + { + ++i; +@@ -120,3 +120,183 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, + next:; + } + } ++ ++#if !HAVE_TUNABLES ++/* In this case, just default to the original algorithm. */ ++strong_alias (_dl_sort_maps_original, _dl_sort_maps); ++#else ++ ++/* We use a recursive function due to its better clarity and ease of ++ implementation, as well as faster execution speed. We already use ++ alloca() for list allocation during the breadth-first search of ++ dependencies in _dl_map_object_deps(), and this should be on the ++ same order of worst-case stack usage. ++ ++ Note: the '*rpo' parameter is supposed to point to one past the ++ last element of the array where we save the sort results, and is ++ decremented before storing the current map at each level. */ ++ ++static void ++dfs_traversal (struct link_map ***rpo, struct link_map *map, ++ bool *do_reldeps) ++{ ++ if (map->l_visited) ++ return; ++ ++ map->l_visited = 1; ++ ++ if (map->l_initfini) ++ { ++ for (int i = 0; map->l_initfini[i] != NULL; i++) ++ { ++ struct link_map *dep = map->l_initfini[i]; ++ if (dep->l_visited == 0 ++ && dep->l_main_map == 0) ++ dfs_traversal (rpo, dep, do_reldeps); ++ } ++ } ++ ++ if (__glibc_unlikely (do_reldeps != NULL && map->l_reldeps != NULL)) ++ { ++ /* Indicate that we encountered relocation dependencies during ++ traversal. */ ++ *do_reldeps = true; ++ ++ for (int m = map->l_reldeps->act - 1; m >= 0; m--) ++ { ++ struct link_map *dep = map->l_reldeps->list[m]; ++ if (dep->l_visited == 0 ++ && dep->l_main_map == 0) ++ dfs_traversal (rpo, dep, do_reldeps); ++ } ++ } ++ ++ *rpo -= 1; ++ **rpo = map; ++} ++ ++/* Topologically sort array MAPS according to dependencies of the contained ++ objects. */ ++ ++static void ++_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps, ++ unsigned int skip __attribute__ ((unused)), bool for_fini) ++{ ++ for (int i = nmaps - 1; i >= 0; i--) ++ maps[i]->l_visited = 0; ++ ++ /* We apply DFS traversal for each of maps[i] until the whole total order ++ is found and we're at the start of the Reverse-Postorder (RPO) sequence, ++ which is a topological sort. ++ ++ We go from maps[nmaps - 1] backwards towards maps[0] at this level. ++ Due to the breadth-first search (BFS) ordering we receive, going ++ backwards usually gives a more shallow depth-first recursion depth, ++ adding more stack usage safety. Also, combined with the natural ++ processing order of l_initfini[] at each node during DFS, this maintains ++ an ordering closer to the original link ordering in the sorting results ++ under most simpler cases. ++ ++ Another reason we order the top level backwards, it that maps[0] is ++ usually exactly the main object of which we're in the midst of ++ _dl_map_object_deps() processing, and maps[0]->l_initfini[] is still ++ blank. If we start the traversal from maps[0], since having no ++ dependencies yet filled in, maps[0] will always be immediately ++ incorrectly placed at the last place in the order (first in reverse). ++ Adjusting the order so that maps[0] is last traversed naturally avoids ++ this problem. ++ ++ Further, the old "optimization" of skipping the main object at maps[0] ++ from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general ++ no longer valid, since traversing along object dependency-links ++ may "find" the main object even when it is not included in the initial ++ order (e.g. a dlopen()'ed shared object can have circular dependencies ++ linked back to itself). In such a case, traversing N-1 objects will ++ create a N-object result, and raise problems. ++ ++ To summarize, just passing in the full list, and iterating from back ++ to front makes things much more straightforward. */ ++ ++ /* Array to hold RPO sorting results, before we copy back to maps[]. */ ++ struct link_map *rpo[nmaps]; ++ ++ /* The 'head' position during each DFS iteration. Note that we start at ++ one past the last element due to first-decrement-then-store (see the ++ bottom of above dfs_traversal() routine). */ ++ struct link_map **rpo_head = &rpo[nmaps]; ++ ++ bool do_reldeps = false; ++ bool *do_reldeps_ref = (for_fini ? &do_reldeps : NULL); ++ ++ for (int i = nmaps - 1; i >= 0; i--) ++ { ++ dfs_traversal (&rpo_head, maps[i], do_reldeps_ref); ++ ++ /* We can break early if all objects are already placed. */ ++ if (rpo_head == rpo) ++ goto end; ++ } ++ assert (rpo_head == rpo); ++ ++ end: ++ /* Here we may do a second pass of sorting, using only l_initfini[] ++ static dependency links. This is avoided if !FOR_FINI or if we didn't ++ find any reldeps in the first DFS traversal. ++ ++ The reason we do this is: while it is unspecified how circular ++ dependencies should be handled, the presumed reasonable behavior is to ++ have destructors to respect static dependency links as much as possible, ++ overriding reldeps if needed. And the first sorting pass, which takes ++ l_initfini/l_reldeps links equally, may not preserve this priority. ++ ++ Hence we do a 2nd sorting pass, taking only DT_NEEDED links into account ++ (see how the do_reldeps argument to dfs_traversal() is NULL below). */ ++ if (do_reldeps) ++ { ++ for (int i = nmaps - 1; i >= 0; i--) ++ rpo[i]->l_visited = 0; ++ ++ struct link_map **maps_head = &maps[nmaps]; ++ for (int i = nmaps - 1; i >= 0; i--) ++ { ++ dfs_traversal (&maps_head, rpo[i], NULL); ++ ++ /* We can break early if all objects are already placed. ++ The below memcpy is not needed in the do_reldeps case here, ++ since we wrote back to maps[] during DFS traversal. */ ++ if (maps_head == maps) ++ return; ++ } ++ assert (maps_head == maps); ++ return; ++ } ++ ++ memcpy (maps, rpo, sizeof (struct link_map *) * nmaps); ++} ++ ++void ++_dl_sort_maps_init (void) ++{ ++ int32_t algorithm = TUNABLE_GET (glibc, rtld, dynamic_sort, int32_t, NULL); ++ GLRO(dl_dso_sort_algo) = algorithm == 1 ? dso_sort_algorithm_original ++ : dso_sort_algorithm_dfs; ++} ++ ++void ++_dl_sort_maps (struct link_map **maps, unsigned int nmaps, ++ unsigned int skip, bool for_fini) ++{ ++ /* It can be tempting to use a static function pointer to store and call ++ the current selected sorting algorithm routine, but experimentation ++ shows that current processors still do not handle indirect branches ++ that efficiently, plus a static function pointer will involve ++ PTR_MANGLE/DEMANGLE, further impairing performance of small, common ++ input cases. A simple if-case with direct function calls appears to ++ be the fastest. */ ++ if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original)) ++ _dl_sort_maps_original (maps, nmaps, skip, for_fini); ++ else ++ _dl_sort_maps_dfs (maps, nmaps, skip, for_fini); ++} ++ ++#endif /* HAVE_TUNABLES. */ +diff --git a/elf/dl-support.c b/elf/dl-support.c +index d8c06ba7eb4c76ea..c5ee5d33aa7e1d65 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -166,6 +166,8 @@ size_t _dl_phnum; + uint64_t _dl_hwcap; + uint64_t _dl_hwcap2; + ++enum dso_sort_algorithm _dl_dso_sort_algo; ++ + /* The value of the FPU control word the kernel will preset in hardware. */ + fpu_control_t _dl_fpu_control = _FPU_DEFAULT; + +diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c +index 2c684c2db2a1f59b..4dc366eea445e974 100644 +--- a/elf/dl-sysdep.c ++++ b/elf/dl-sysdep.c +@@ -231,6 +231,9 @@ _dl_sysdep_start (void **start_argptr, + + __tunables_init (_environ); + ++ /* Initialize DSO sorting algorithm after tunables. */ ++ _dl_sort_maps_init (); ++ + #ifdef DL_SYSDEP_INIT + DL_SYSDEP_INIT; + #endif +diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list +index 8ddd4a23142a941b..46ffb2378416f90f 100644 +--- a/elf/dl-tunables.list ++++ b/elf/dl-tunables.list +@@ -156,4 +156,13 @@ glibc { + security_level: SXID_IGNORE + } + } ++ ++ rtld { ++ dynamic_sort { ++ type: INT_32 ++ minval: 1 ++ maxval: 2 ++ default: 1 ++ } ++ } + } +diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def +index 873ddf55d91155c6..5f7f18ef270bc12d 100644 +--- a/elf/dso-sort-tests-1.def ++++ b/elf/dso-sort-tests-1.def +@@ -62,5 +62,5 @@ output: b>a>{}b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c +-xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[l_name = (char *) ""; + *user_entry = main_map->l_entry; + ++ /* Set bit indicating this is the main program map. */ ++ main_map->l_main_map = 1; ++ + #ifdef HAVE_AUX_VECTOR + /* Adjust the on-stack auxiliary vector so that it looks like the + binary was executed directly. */ +diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp +index 9f66c528855fb21d..9bf572715f996ca6 100644 +--- a/elf/tst-rtld-list-tunables.exp ++++ b/elf/tst-rtld-list-tunables.exp +@@ -10,5 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+) ++glibc.rtld.dynamic_sort: 1 (min: 1, max: 2) + glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10) + glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+) +diff --git a/include/link.h b/include/link.h +index c46aced9f7b43ba0..4dcf01d8aea90bc2 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -181,6 +181,11 @@ struct link_map + unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ + unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */ + unsigned int l_reserved:2; /* Reserved for internal use. */ ++ unsigned int l_main_map:1; /* Nonzero for the map of the main program. */ ++ unsigned int l_visited:1; /* Used internally for map dependency ++ graph traversal. */ ++ unsigned int l_map_used:1; /* These two bits are used during traversal */ ++ unsigned int l_map_done:1; /* of maps in _dl_close_worker. */ + unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed + to by `l_phdr' is allocated. */ + unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 658547c6137bf177..10f4d75993f9940f 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -309,6 +309,17 @@ changed once allocated at process startup. The default allocation of + optional static TLS is 512 bytes and is allocated in every thread. + @end deftp + ++@deftp Tunable glibc.rtld.dynamic_sort ++Sets the algorithm to use for DSO sorting, valid values are @samp{1} and ++@samp{2}. For value of @samp{1}, an older O(n^3) algorithm is used, which is ++long time tested, but may have performance issues when dependencies between ++shared objects contain cycles due to circular dependencies. When set to the ++value of @samp{2}, a different algorithm is used, which implements a ++topological sort through depth-first search, and does not exhibit the ++performance issues of @samp{1}. ++ ++The default value of this tunable is @samp{1}. ++@end deftp + + @node Elision Tunables + @section Elision Tunables +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index fcbbf6974827cdf1..bcf1f199c5985c65 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -245,6 +245,13 @@ enum allowmask + }; + + ++/* DSO sort algorithm to use (check dl-sort-maps.c). */ ++enum dso_sort_algorithm ++ { ++ dso_sort_algorithm_original, ++ dso_sort_algorithm_dfs ++ }; ++ + struct audit_ifaces + { + void (*activity) (uintptr_t *, unsigned int); +@@ -672,6 +679,8 @@ struct rtld_global_ro + platforms. */ + EXTERN uint64_t _dl_hwcap2; + ++ EXTERN enum dso_sort_algorithm _dl_dso_sort_algo; ++ + #ifdef SHARED + /* We add a function table to _rtld_global which is then used to + call the function instead of going through the PLT. The result +@@ -1098,7 +1107,7 @@ extern void _dl_fini (void) attribute_hidden; + + /* Sort array MAPS according to dependencies of the contained objects. */ + extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps, +- char *used, bool for_fini) attribute_hidden; ++ unsigned int skip, bool for_fini) attribute_hidden; + + /* The dynamic linker calls this function before and having changing + any shared object mappings. The `r_state' member of `struct r_debug' +@@ -1225,6 +1234,9 @@ extern struct link_map * _dl_get_dl_main_map (void) + # endif + #endif + ++/* Initialize the DSO sort algorithm to use. */ ++extern void _dl_sort_maps_init (void) attribute_hidden; ++ + /* Initialization of libpthread for statically linked applications. + If libpthread is not linked in, this is an empty function. */ + void __pthread_initialize_minimal (void) weak_function; diff --git a/SOURCES/glibc-rh2032647-3.patch b/SOURCES/glibc-rh2032647-3.patch new file mode 100644 index 0000000..789e644 --- /dev/null +++ b/SOURCES/glibc-rh2032647-3.patch @@ -0,0 +1,25 @@ +commit d3bf2f5927d51258a51ac7fde04f4805f8ee294a +Author: Adhemerval Zanella +Date: Wed Nov 3 09:19:30 2021 -0300 + + elf: Do not run DSO sorting if tunables is not enabled + + Since the argorithm selection requires tunables. + + Checked on x86_64-linux-gnu with --enable-tunables=no. + +diff --git a/elf/Makefile b/elf/Makefile +index 8dd2b24328113536..02ee834fdaf00a26 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -483,8 +483,10 @@ include $(objpfx)$(1).generated-makefile + endef + + # Generate from each testcase description file ++ifeq (yes,$(have-tunables)) + $(eval $(call include_dsosort_tests,dso-sort-tests-1.def)) + $(eval $(call include_dsosort_tests,dso-sort-tests-2.def)) ++endif + + check-abi: $(objpfx)check-abi-ld.out + tests-special += $(objpfx)check-abi-ld.out diff --git a/SOURCES/glibc-rh2032647-4.patch b/SOURCES/glibc-rh2032647-4.patch new file mode 100644 index 0000000..1c415d4 --- /dev/null +++ b/SOURCES/glibc-rh2032647-4.patch @@ -0,0 +1,189 @@ +commit b4bbedb1e75737a80bcc3d53d6eef1fbe0b5f4d5 +Author: H.J. Lu +Date: Sat Nov 6 14:13:27 2021 -0700 + + dso-ordering-test.py: Put all sources in one directory [BZ #28550] + + Put all sources for DSO sorting tests in the dso-sort-tests-src directory + and compile test relocatable objects with + + $(objpfx)tst-dso-ordering1-dir/tst-dso-ordering1-a.os: $(objpfx)dso-sort-tests-src/tst-dso-ordering1-a.c + $(compile.c) $(OUTPUT_OPTION) + + to avoid random $< values from $(before-compile) when compiling test + relocatable objects with + + $(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c) + compile-command.c = $(compile.c) $(OUTPUT_OPTION) $(compile-mkdep-flags) + compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS) + + for 3 "make -j 28" parallel builds on a machine with 112 cores at the + same time. + + This partially fixes BZ #28550. + + Reviewed-by: Adhemerval Zanella + +diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py +index 944ee740527d60fd..bde0406be9da14fc 100644 +--- a/scripts/dso-ordering-test.py ++++ b/scripts/dso-ordering-test.py +@@ -526,9 +526,13 @@ def process_testcase(t): + base_test_name = t.test_name + test_subdir = base_test_name + "-dir" + testpfx = objpfx + test_subdir + "/" ++ test_srcdir = "dso-sort-tests-src/" ++ testpfx_src = objpfx + test_srcdir + + if not os.path.exists(testpfx): + os.mkdir(testpfx) ++ if not os.path.exists(testpfx_src): ++ os.mkdir(testpfx_src) + + def find_objs_not_depended_on(t): + objs_not_depended_on = [] +@@ -595,6 +599,11 @@ def process_testcase(t): + # Print out needed Makefile fragments for use in glibc/elf/Makefile. + module_names = "" + for o in test_descr.objs: ++ rule = ("$(objpfx)" + test_subdir + "/" + test_name ++ + "-" + o + ".os: $(objpfx)" + test_srcdir ++ + test_name + "-" + o + ".c\n" ++ "\t$(compile.c) $(OUTPUT_OPTION)\n") ++ makefile.write (rule) + module_names += " " + test_subdir + "/" + test_name + "-" + o + makefile.write("modules-names +=%s\n" % (module_names)) + +@@ -637,7 +646,7 @@ def process_testcase(t): + # object. This only needs to be done at most once for + # an object name. + if not dep in fake_created: +- f = open(testpfx + test_name + "-" + dep ++ f = open(testpfx_src + test_name + "-" + dep + + ".FAKE.c", "w") + f.write(" \n") + f.close() +@@ -648,6 +657,12 @@ def process_testcase(t): + % (test_name + "-" + dep + ".FAKE.so", + ("$(objpfx)" + test_subdir + "/" + + test_name + "-" + dep + ".so"))) ++ rule = ("$(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".FAKE.os: " ++ "$(objpfx)" + test_srcdir ++ + test_name + "-" + dep + ".FAKE.c\n" ++ "\t$(compile.c) $(OUTPUT_OPTION)\n") ++ makefile.write (rule) + makefile.write \ + ("modules-names += %s\n" + % (test_subdir + "/" +@@ -687,6 +702,10 @@ def process_testcase(t): + + test_descr.soname_map['#'] + ".so") + ldflags += (" -Wl,-soname=" + soname) + makefile.write("LDFLAGS-%s = %s\n" % (test_name, ldflags)) ++ rule = ("$(objpfx)" + test_subdir + "/" + test_name + ".o: " ++ "$(objpfx)" + test_srcdir + test_name + ".c\n" ++ "\t$(compile.c) $(OUTPUT_OPTION)\n") ++ makefile.write (rule) + + not_depended_objs = find_objs_not_depended_on(test_descr) + if not_depended_objs: +@@ -745,7 +764,7 @@ def process_testcase(t): + " something_failed=true\n" + "else\n" + " diff -wu ${common_objpfx}elf/%s/%s%s.output \\\n" +- " ${common_objpfx}elf/%s/%s%s.exp\n" ++ " ${common_objpfx}elf/%s%s%s.exp\n" + " if [ $? -ne 0 ]; then\n" + " echo '%sFAIL: %s%s expected output comparison'\n" + " something_failed=true\n" +@@ -753,14 +772,14 @@ def process_testcase(t): + "fi\n" + % (("X" if xfail else ""), test_name, tunable_descr, + test_subdir, test_name, tunable_sfx, +- test_subdir, base_test_name, exp_tunable_sfx, ++ test_srcdir, base_test_name, exp_tunable_sfx, + ("X" if xfail else ""), test_name, tunable_descr)) + + # Generate C files according to dependency and calling relations from + # description string. + for obj in test_descr.objs: + src_name = test_name + "-" + obj + ".c" +- f = open(testpfx + src_name, "w") ++ f = open(testpfx_src + src_name, "w") + if obj in test_descr.callrefs: + called_objs = test_descr.callrefs[obj] + for callee in called_objs: +@@ -804,7 +823,7 @@ def process_testcase(t): + f.close() + + # Open C file for writing main program +- f = open(testpfx + test_name + ".c", "w") ++ f = open(testpfx_src + test_name + ".c", "w") + + # if there are some operations in main(), it means we need -ldl + f.write("#include \n") +@@ -885,7 +904,7 @@ def process_testcase(t): + for obj in test_descr.objs: + src_name = test_name + "-" + obj + ".c" + obj_name = test_name + "-" + obj + ".os" +- run_cmd([build_gcc, "-c", "-fPIC", testpfx + src_name, ++ run_cmd([build_gcc, "-c", "-fPIC", testpfx_src + src_name, + "-o", testpfx + obj_name]) + + obj_processed = {} +@@ -903,10 +922,12 @@ def process_testcase(t): + deps.append(dep + ".FAKE") + if not dep in fake_created: + base_name = testpfx + test_name + "-" + dep ++ src_base_name = (testpfx_src + test_name ++ + "-" + dep) + cmd = [build_gcc, "-Wl,--no-as-needed", + ("-Wl,-soname=" + base_name + ".so"), + "-shared", base_name + ".FAKE.c", +- "-o", base_name + ".FAKE.so"] ++ "-o", src_base_name + ".FAKE.so"] + run_cmd(cmd) + fake_created[dep] = True + dso_deps = map(lambda d: testpfx + test_name + "-" + d + ".so", +@@ -932,7 +953,7 @@ def process_testcase(t): + main_deps = map(lambda d: testpfx + test_name + "-" + d + ".so", + deps) + cmd = [build_gcc, "-Wl,--no-as-needed", "-o", testpfx + test_name, +- testpfx + test_name + ".c", "-L%s" % (os.getcwd()), ++ testpfx_src + test_name + ".c", "-L%s" % (os.getcwd()), + "-Wl,-rpath-link=%s" % (os.getcwd())] + if '#' in test_descr.soname_map: + soname = ("-Wl,-soname=" + testpfx + test_name + "-" +@@ -987,14 +1008,14 @@ def process_testcase(t): + sfx = "" + if r[0] != "": + sfx = "-" + r[0].replace("=","_") +- f = open(testpfx + t.test_name + sfx + ".exp", "w") ++ f = open(testpfx_src + t.test_name + sfx + ".exp", "w") + (output, xfail) = r[1] + f.write('%s' % output) + f.close() + + # Create header part of top-level testcase shell script, to wrap execution + # and output comparison together. +- t.sh = open(testpfx + t.test_name + ".sh", "w") ++ t.sh = open(testpfx_src + t.test_name + ".sh", "w") + t.sh.write("#!/bin/sh\n") + t.sh.write("# Test driver for %s, generated by " + "dso-ordering-test.py\n" % (t.test_name)) +@@ -1022,12 +1043,12 @@ def process_testcase(t): + sfx = "" + if r[0] != "": + sfx = "-" + r[0].replace("=","_") +- expected_output_files += " $(objpfx)%s/%s%s.exp" % (test_subdir, ++ expected_output_files += " $(objpfx)%s%s%s.exp" % (test_srcdir, + t.test_name, sfx) + makefile.write \ +- ("$(objpfx)%s.out: $(objpfx)%s/%s.sh%s " ++ ("$(objpfx)%s.out: $(objpfx)%s%s.sh%s " + "$(common-objpfx)support/test-run-command\n" +- % (t.test_name, test_subdir, t.test_name, ++ % (t.test_name, test_srcdir, t.test_name, + expected_output_files)) + makefile.write("\t$(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' " + "'$(run-program-env)' > $@; $(evaluate-test)\n") diff --git a/SOURCES/glibc-rh2032647-5.patch b/SOURCES/glibc-rh2032647-5.patch new file mode 100644 index 0000000..308d831 --- /dev/null +++ b/SOURCES/glibc-rh2032647-5.patch @@ -0,0 +1,45 @@ +commit 1f67d8286b5da9266a138198ef1f15c27cbb0010 +Author: H.J. Lu +Date: Mon Nov 15 16:28:39 2021 -0800 + + elf: Use a temporary file to generate Makefile fragments [BZ #28550] + + 1. Use a temporary file to generate Makefile fragments for DSO sorting + tests and use -include on them. + 2. Add Makefile fragments to postclean-generated so that a "make clean" + removes the autogenerated fragments and a subsequent "make" regenerates + them. + + This partially fixes BZ #28550. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/Makefile b/elf/Makefile +index 02ee834fdaf00a26..535ba4260fb98e64 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -471,6 +471,7 @@ tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \ + $(objpfx)tst-unused-dep-cmp.out + endif + ++ifndef avoid-generated + # DSO sorting tests: + # The dso-ordering-test.py script generates testcase source files in $(objpfx), + # creating a $(objpfx)-dir for each testcase, and creates a +@@ -478,9 +479,14 @@ endif + define include_dsosort_tests + $(objpfx)$(1).generated-makefile: $(1) + $(PYTHON) $(..)scripts/dso-ordering-test.py \ +- --description-file $$< --objpfx $(objpfx) --output-makefile $$@ +-include $(objpfx)$(1).generated-makefile ++ --description-file $$< --objpfx $(objpfx) --output-makefile $$@T ++ mv $$@T $$@ ++-include $(objpfx)$(1).generated-makefile + endef ++endif ++ ++postclean-generated += $(objpfx)/dso-sort-tests-2.generated-makefile \ ++ $(objpfx)/dso-sort-tests-2.generated-makefile + + # Generate from each testcase description file + ifeq (yes,$(have-tunables)) diff --git a/SOURCES/glibc-rh2032647-6.patch b/SOURCES/glibc-rh2032647-6.patch new file mode 100644 index 0000000..6dcaccd --- /dev/null +++ b/SOURCES/glibc-rh2032647-6.patch @@ -0,0 +1,49 @@ +commit 0884724a95b60452ad483dbe086d237d02ba624d +Author: Florian Weimer +Date: Tue Dec 14 12:37:44 2021 +0100 + + elf: Use new dependency sorting algorithm by default + + The default has to change eventually, and there are no known failures + that require a delay. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list +index 46ffb2378416f90f..ffcd7f18d4fafb91 100644 +--- a/elf/dl-tunables.list ++++ b/elf/dl-tunables.list +@@ -162,7 +162,7 @@ glibc { + type: INT_32 + minval: 1 + maxval: 2 +- default: 1 ++ default: 2 + } + } + } +diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp +index 9bf572715f996ca6..44e4834cfb431633 100644 +--- a/elf/tst-rtld-list-tunables.exp ++++ b/elf/tst-rtld-list-tunables.exp +@@ -10,6 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+) +-glibc.rtld.dynamic_sort: 1 (min: 1, max: 2) ++glibc.rtld.dynamic_sort: 2 (min: 1, max: 2) + glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10) + glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+) +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 10f4d75993f9940f..7c3b28d029410a6f 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -318,7 +318,7 @@ value of @samp{2}, a different algorithm is used, which implements a + topological sort through depth-first search, and does not exhibit the + performance issues of @samp{1}. + +-The default value of this tunable is @samp{1}. ++The default value of this tunable is @samp{2}. + @end deftp + + @node Elision Tunables diff --git a/SOURCES/glibc-rh2040657-1.patch b/SOURCES/glibc-rh2040657-1.patch new file mode 100644 index 0000000..4a25277 --- /dev/null +++ b/SOURCES/glibc-rh2040657-1.patch @@ -0,0 +1,547 @@ +commit 28713c06129f8f64f88c423266e6ff2880216509 +Author: H.J. Lu +Date: Mon Dec 13 09:43:52 2021 -0800 + + elf: Sort tests and modules-names + + Sort tests and modules-names to reduce future conflicts. + +Conflicts: + elf/Makefile + (Usual backport differences. Recreated tests and module-names + from scratch. Note that the upstream sort order is difficult + to fathom.) + +diff --git a/elf/Makefile b/elf/Makefile +index 535ba4260fb98e64..33df5b4714176adc 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -193,40 +193,134 @@ static-dlopen-environment = \ + tst-tls9-static-ENV = $(static-dlopen-environment) + tst-single_threaded-static-dlopen-ENV = $(static-dlopen-environment) + +-tests += restest1 preloadtest loadfail multiload origtest resolvfail \ +- constload1 order noload filter \ +- reldep reldep2 reldep3 reldep4 nodelete nodelete2 \ +- nodlopen nodlopen2 lateglobal initfirst global \ +- restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ +- tst-tls4 tst-tls5 \ +- tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \ +- tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \ +- tst-align tst-align2 \ +- tst-dlmodcount tst-dlopenrpath tst-deep1 \ +- tst-dlmopen1 tst-dlmopen3 \ +- unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \ +- 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-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 \ +- tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ +- tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ +- tst-unwind-ctor tst-unwind-main tst-audit13 \ +- tst-sonamemove-link tst-sonamemove-dlopen tst-dlopen-tlsmodid \ +- tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail \ +- tst-dlopenfail-2 \ +- tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen \ +- tst-audit14 tst-audit15 tst-audit16 tst-audit17 \ +- tst-single_threaded tst-single_threaded-pthread \ +- tst-tls-ie tst-tls-ie-dlmopen argv0test \ +- tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \ +- tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \ +- tst-dl-is_dso tst-ro-dynamic \ +- tst-rtld-run-static \ ++tests += \ ++ argv0test \ ++ constload1 \ ++ dblload \ ++ dblunload \ ++ filter \ ++ global \ ++ initfirst \ ++ lateglobal \ ++ loadfail \ ++ multiload \ ++ next \ ++ nodelete \ ++ nodelete2 \ ++ nodlopen \ ++ nodlopen2 \ ++ noload \ ++ order \ ++ order2 \ ++ origtest \ ++ preloadtest \ ++ reldep \ ++ reldep2 \ ++ reldep3 \ ++ reldep4 \ ++ reldep5 \ ++ reldep6 \ ++ reldep7 \ ++ reldep8 \ ++ resolvfail \ ++ restest1 \ ++ restest2 \ ++ tst-absolute-sym \ ++ tst-absolute-zero \ ++ tst-addr1 \ ++ tst-align \ ++ tst-align2 \ ++ tst-audit1 \ ++ tst-audit2 \ ++ tst-audit8 \ ++ tst-audit9 \ ++ tst-audit11 \ ++ tst-audit12 \ ++ tst-audit13 \ ++ tst-audit14 \ ++ tst-audit15 \ ++ tst-audit16 \ ++ tst-audit17 \ ++ tst-auditmany \ ++ tst-auxobj \ ++ tst-auxobj-dlopen \ ++ tst-big-note \ ++ tst-debug1 \ ++ tst-deep1 \ ++ tst-dl-is_dso \ ++ tst-dlmodcount \ ++ tst-dlmopen1 \ ++ tst-dlmopen3 \ ++ tst-dlmopen-dlerror \ ++ tst-dlmopen-gethostbyname \ ++ tst-dlopenfail \ ++ tst-dlopenfail-2 \ ++ tst-dlopenrpath \ ++ tst-dlopen-self \ ++ tst-dlopen-tlsmodid \ ++ tst-dlsym-error \ ++ tst-filterobj \ ++ tst-filterobj-dlopen \ ++ tst-glibc-hwcaps \ ++ tst-glibc-hwcaps-mask \ ++ tst-glibc-hwcaps-prepend \ ++ tst-global1 \ ++ tst-initfinilazyfail \ ++ tst-initorder \ ++ tst-initorder2 \ ++ tst-latepthread \ ++ tst-main1 \ ++ tst-nodelete2 \ ++ tst-nodelete-dlclose \ ++ tst-nodelete-opened \ ++ tst-noload \ ++ tst-null-argv \ ++ tst-relsort1 \ ++ tst-ro-dynamic \ ++ tst-rtld-run-static \ ++ tst-single_threaded \ ++ tst-single_threaded-pthread \ ++ tst-sonamemove-dlopen \ ++ tst-sonamemove-link \ ++ tst-thrlock \ ++ tst-tls10 \ ++ tst-tls11 \ ++ tst-tls12 \ ++ tst-tls13 \ ++ tst-tls14 \ ++ tst-tls15 \ ++ tst-tls16 \ ++ tst-tls17 \ ++ tst-tls18 \ ++ tst-tls19 \ ++ tst-tls20 \ ++ tst-tls21 \ ++ tst-tls4 \ ++ tst-tls5 \ ++ tst-tlsalign \ ++ tst-tlsalign-extern \ ++ tst-tls-dlinfo \ ++ tst-tls-ie \ ++ tst-tls-ie-dlmopen \ ++ tst-tls-manydynamic \ ++ tst-unique1 \ ++ tst-unique2 \ ++ tst-unwind-ctor \ ++ tst-unwind-main \ ++ unload3 \ ++ unload4 \ ++ unload5 \ ++ unload6 \ ++ unload7 \ ++ unload8 \ + # reldep9 ++tests-cxx = \ ++ tst-dlopen-nodelete-reloc \ ++ tst-nodelete \ ++ tst-unique3 \ ++ tst-unique4 \ ++ ++tests += $(if $(CXX),$(tests-cxx)) + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ + tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \ +@@ -264,101 +358,265 @@ tst-tls-many-dynamic-modules-dep-bad = \ + extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \ + tst-tlsalign-vars.o + test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars +-modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ +- testobj1_1 failobj constload2 constload3 unloadmod \ +- dep1 dep2 dep3 dep4 vismod1 vismod2 vismod3 \ +- nodelmod1 nodelmod2 nodelmod3 nodelmod4 \ +- nodel2mod1 nodel2mod2 nodel2mod3 \ +- nodlopenmod nodlopenmod2 filtmod1 filtmod2 \ +- reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \ +- reldep4mod1 reldep4mod2 reldep4mod3 reldep4mod4 \ +- neededobj1 neededobj2 neededobj3 neededobj4 \ +- neededobj5 neededobj6 firstobj globalmod1 \ +- unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \ +- dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \ +- reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \ +- reldep7mod1 reldep7mod2 \ +- tst-tlsmod1 tst-tlsmod2 tst-tlsmod3 tst-tlsmod4 \ +- tst-tlsmod5 tst-tlsmod6 tst-tlsmod7 tst-tlsmod8 \ +- tst-tlsmod9 tst-tlsmod10 tst-tlsmod11 tst-tlsmod12 \ +- tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \ +- tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \ +- $(tlsmod17a-modules) tst-tlsmod17b $(tlsmod18a-modules) \ +- tst-tls19mod1 tst-tls19mod2 tst-tls19mod3 \ +- circlemod1 circlemod1a circlemod2 circlemod2a \ +- circlemod3 circlemod3a \ +- reldep8mod1 reldep8mod2 reldep8mod3 \ +- reldep9mod1 reldep9mod2 reldep9mod3 \ +- tst-alignmod tst-alignmod2 \ +- $(modules-execstack-$(have-z-execstack)) \ +- tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \ +- tst-dlmopen1mod tst-auditmod1 \ +- unload3mod1 unload3mod2 unload3mod3 unload3mod4 \ +- unload4mod1 unload4mod2 unload4mod3 unload4mod4 \ +- unload6mod1 unload6mod2 unload6mod3 \ +- unload7mod1 unload7mod2 \ +- unload8mod1 unload8mod1x unload8mod2 unload8mod3 \ +- order2mod1 order2mod2 order2mod3 order2mod4 \ +- tst-unique1mod1 tst-unique1mod2 \ +- tst-unique2mod1 tst-unique2mod2 \ +- tst-auditmod9a tst-auditmod9b \ +- $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ +- tst-nodelete-uniquemod tst-nodelete-rtldmod \ +- 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 \ +- tst-initorder2a tst-initorder2b tst-initorder2c \ +- tst-initorder2d \ +- tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \ +- tst-array5dep tst-null-argv-lib \ +- tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \ +- tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \ +- tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \ +- tst-latepthreadmod $(tst-tls-many-dynamic-modules) \ +- $(tst-tls-many-dynamic-modules-dep) \ +- $(tst-tls-many-dynamic-modules-dep-bad) \ +- tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \ +- tst-main1mod tst-absolute-sym-lib \ +- tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib \ +- tst-audit13mod1 tst-sonamemove-linkmod1 \ +- tst-sonamemove-runmod1 tst-sonamemove-runmod2 \ +- tst-auditmanymod1 tst-auditmanymod2 tst-auditmanymod3 \ +- tst-auditmanymod4 tst-auditmanymod5 tst-auditmanymod6 \ +- tst-auditmanymod7 tst-auditmanymod8 tst-auditmanymod9 \ +- tst-initlazyfailmod tst-finilazyfailmod \ +- tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \ +- tst-dlopenfailmod3 tst-dlopenfailnodelmod tst-ldconfig-ld-mod \ +- tst-filterobj-flt tst-filterobj-aux tst-filterobj-filtee \ +- tst-auditlogmod-1 tst-auditlogmod-2 tst-auditlogmod-3 \ +- tst-single_threaded-mod1 tst-single_threaded-mod2 \ +- tst-single_threaded-mod3 tst-single_threaded-mod4 \ +- tst-tls-ie-mod0 tst-tls-ie-mod1 tst-tls-ie-mod2 \ +- tst-tls-ie-mod3 tst-tls-ie-mod4 tst-tls-ie-mod5 \ +- tst-tls-ie-mod6 libmarkermod1-1 libmarkermod1-2 libmarkermod1-3 \ +- libmarkermod2-1 libmarkermod2-2 \ +- libmarkermod3-1 libmarkermod3-2 libmarkermod3-3 \ +- libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \ +- tst-tls20mod-bad tst-tls21mod tst-dlmopen-dlerror-mod \ +- tst-auxvalmod \ +- tst-dlmopen-gethostbyname-mod tst-ro-dynamic-mod \ ++modules-names = \ ++ circlemod1 \ ++ circlemod1a \ ++ circlemod2 \ ++ circlemod2a \ ++ circlemod3 \ ++ circlemod3a \ ++ constload2 \ ++ constload3 \ ++ dblloadmod1 \ ++ dblloadmod2 \ ++ dblloadmod3 \ ++ dep1 \ ++ dep2 \ ++ dep3 \ ++ dep4 \ ++ failobj \ ++ filtmod1 \ ++ filtmod2 \ ++ firstobj \ ++ globalmod1 \ ++ libmarkermod1-1 \ ++ libmarkermod1-2 \ ++ libmarkermod1-3 \ ++ libmarkermod2-1 \ ++ libmarkermod2-2 \ ++ libmarkermod3-1 \ ++ libmarkermod3-2 \ ++ libmarkermod3-3 \ ++ libmarkermod4-1 \ ++ libmarkermod4-2 \ ++ libmarkermod4-3 \ ++ libmarkermod4-4 \ ++ ltglobmod1 \ ++ ltglobmod2 \ ++ neededobj1 \ ++ neededobj2 \ ++ neededobj3 \ ++ neededobj4 \ ++ neededobj5 \ ++ neededobj6 \ ++ nextmod1 \ ++ nextmod2 \ ++ nodel2mod1 \ ++ nodel2mod2 \ ++ nodel2mod3 \ ++ nodelmod1 \ ++ nodelmod2 \ ++ nodelmod3 \ ++ nodelmod4 \ ++ nodlopenmod \ ++ nodlopenmod2 \ ++ order2mod1 \ ++ order2mod2 \ ++ order2mod3 \ ++ order2mod4 \ ++ pathoptobj \ ++ reldep4mod1 \ ++ reldep4mod2 \ ++ reldep4mod3 \ ++ reldep4mod4 \ ++ reldep6mod0 \ ++ reldep6mod1 \ ++ reldep6mod2 \ ++ reldep6mod3 \ ++ reldep6mod4 \ ++ reldep7mod1 \ ++ reldep7mod2 \ ++ reldep8mod1 \ ++ reldep8mod2 \ ++ reldep8mod3 \ ++ reldep9mod1 \ ++ reldep9mod2 \ ++ reldep9mod3 \ ++ reldepmod1 \ ++ reldepmod2 \ ++ reldepmod3 \ ++ reldepmod4 \ ++ reldepmod5 \ ++ reldepmod6 \ ++ testobj1 \ ++ testobj1_1 \ ++ testobj2 \ ++ testobj3 \ ++ testobj4 \ ++ testobj5 \ ++ testobj6 \ ++ tst-absolute-sym-lib \ ++ tst-absolute-zero-lib \ ++ tst-alignmod \ ++ tst-alignmod2 \ ++ tst-array2dep \ ++ tst-array5dep \ ++ tst-audit11mod1 \ ++ tst-audit11mod2 \ ++ tst-audit12mod1 \ ++ tst-audit12mod2 \ ++ tst-audit12mod3 \ ++ tst-audit13mod1 \ ++ tst-auditlogmod-1 \ ++ tst-auditlogmod-2 \ ++ tst-auditlogmod-3 \ ++ tst-auditmanymod1 \ ++ tst-auditmanymod2 \ ++ tst-auditmanymod3 \ ++ tst-auditmanymod4 \ ++ tst-auditmanymod5 \ ++ tst-auditmanymod6 \ ++ tst-auditmanymod7 \ ++ tst-auditmanymod8 \ ++ tst-auditmanymod9 \ ++ tst-auditmod1 \ ++ tst-auditmod9a \ ++ tst-auditmod9b \ ++ tst-auditmod11 \ ++ tst-auditmod12 \ ++ tst-auxvalmod \ ++ tst-big-note-lib \ ++ tst-deep1mod1 \ ++ tst-deep1mod2 \ ++ tst-deep1mod3 \ ++ tst-dlmopen1mod \ ++ tst-dlmopen-dlerror-mod \ ++ tst-dlmopen-gethostbyname-mod \ ++ tst-dlopenfaillinkmod \ ++ tst-dlopenfailmod1 \ ++ tst-dlopenfailmod2 \ ++ tst-dlopenfailmod3 \ ++ tst-dlopenfailnodelmod \ ++ tst-dlopenrpathmod \ ++ tst-filterobj-aux \ ++ tst-filterobj-filtee \ ++ tst-filterobj-flt \ ++ tst-finilazyfailmod \ ++ tst-initlazyfailmod \ ++ tst-initorder2a \ ++ tst-initorder2b \ ++ tst-initorder2c \ ++ tst-initorder2d \ ++ tst-initordera1 \ ++ tst-initordera2 \ ++ tst-initordera3 \ ++ tst-initordera4 \ ++ tst-initorderb1 \ ++ tst-initorderb2 \ ++ tst-latepthreadmod \ ++ tst-ldconfig-ld-mod \ ++ tst-main1mod \ ++ tst-nodelete2mod \ ++ tst-nodelete-dlclose-dso \ ++ tst-nodelete-dlclose-plugin \ ++ tst-nodelete-opened-lib \ ++ tst-null-argv-lib \ ++ tst-relsort1mod1 \ ++ tst-relsort1mod2 \ ++ tst-ro-dynamic-mod \ ++ tst-single_threaded-mod1 \ ++ tst-single_threaded-mod2 \ ++ tst-single_threaded-mod3 \ ++ tst-single_threaded-mod4 \ ++ tst-sonamemove-linkmod1 \ ++ tst-sonamemove-runmod1 \ ++ tst-sonamemove-runmod2 \ ++ tst-tls19mod1 \ ++ tst-tls19mod2 \ ++ tst-tls19mod3 \ ++ tst-tls20mod-bad \ ++ tst-tls21mod \ ++ tst-tlsalign-lib \ ++ tst-tls-ie-mod0 \ ++ tst-tls-ie-mod1 \ ++ tst-tls-ie-mod2 \ ++ tst-tls-ie-mod3 \ ++ tst-tls-ie-mod4 \ ++ tst-tls-ie-mod5 \ ++ tst-tls-ie-mod6 \ ++ tst-tlsmod1 \ ++ tst-tlsmod10 \ ++ tst-tlsmod11 \ ++ tst-tlsmod12 \ ++ tst-tlsmod13 \ ++ tst-tlsmod13a \ ++ tst-tlsmod14a \ ++ tst-tlsmod14b \ ++ tst-tlsmod15a \ ++ tst-tlsmod15b \ ++ tst-tlsmod16a \ ++ tst-tlsmod16b \ ++ tst-tlsmod17b \ ++ tst-tlsmod2 \ ++ tst-tlsmod3 \ ++ tst-tlsmod4 \ ++ tst-tlsmod5 \ ++ tst-tlsmod6 \ ++ tst-tlsmod7 \ ++ tst-tlsmod8 \ ++ tst-tlsmod9 \ ++ tst-unique1mod1 \ ++ tst-unique1mod2 \ ++ tst-unique2mod1 \ ++ tst-unique2mod2 \ ++ tst-unwind-ctor-lib \ ++ unload2dep \ ++ unload2mod \ ++ unload3mod1 \ ++ unload3mod2 \ ++ unload3mod3 \ ++ unload3mod4 \ ++ unload4mod1 \ ++ unload4mod2 \ ++ unload4mod3 \ ++ unload4mod4 \ ++ unload6mod1 \ ++ unload6mod2 \ ++ unload6mod3 \ ++ unload7mod1 \ ++ unload7mod2 \ ++ unload8mod1 \ ++ unload8mod1x \ ++ unload8mod2 \ ++ unload8mod3 \ ++ unloadmod \ ++ vismod1 \ ++ vismod2 \ ++ vismod3 \ ++ ++modules-names-cxx = \ ++ tst-dlopen-nodelete-reloc-mod1 \ ++ 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-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-nodelete-rtldmod \ ++ tst-nodelete-uniquemod \ ++ tst-nodelete-zmod \ ++ tst-unique3lib \ ++ tst-unique3lib2 \ ++ tst-unique4lib \ ++ ++modules-names += \ ++ $(if $(CXX),$(modules-names-cxx)) \ ++ $(modules-execstack-$(have-z-execstack)) \ ++ $(tst-tls-many-dynamic-modules) \ ++ $(tst-tls-many-dynamic-modules-dep) \ ++ $(tst-tls-many-dynamic-modules-dep-bad) \ ++ $(tlsmod17a-modules) \ ++ $(tlsmod18a-modules) \ + + # Most modules build with _ISOMAC defined, but those filtered out + # depend on internal headers. diff --git a/SOURCES/glibc-rh2040657-10.patch b/SOURCES/glibc-rh2040657-10.patch new file mode 100644 index 0000000..cff581f --- /dev/null +++ b/SOURCES/glibc-rh2040657-10.patch @@ -0,0 +1,73 @@ +commit 990c953bce06d77360d2e933faa9a008e2c55405 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + x86: Add x86-64-vN check to early startup + + This ISA level covers the glibc build itself. + cannot be used because this check (by design) happens before + DL_PLATFORM_INIT and the x86 CPU flags initialization. + + Reviewed-by: H.J. Lu + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 5ee06f94735e5189..36ca1a7126047b86 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -7,6 +7,7 @@ sysdep_routines += get-cpuid-feature-leaf + sysdep-dl-routines += dl-get-cpu-features + sysdep_headers += sys/platform/x86.h bits/platform/x86.h + ++CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags) + CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector) + + tests += tst-get-cpu-features tst-get-cpu-features-static \ +diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c +index 839803c746f408ed..6ccde4404b13a725 100644 +--- a/sysdeps/x86/dl-get-cpu-features.c ++++ b/sysdeps/x86/dl-get-cpu-features.c +@@ -20,6 +20,7 @@ + + #ifdef SHARED + # include ++# include + + /* NB: Normally, DL_PLATFORM_INIT calls init_cpu_features to initialize + CPU features in dynamic executable. But when loading ld.so inside of +@@ -36,7 +37,35 @@ _dl_x86_init_cpu_features (void) + { + struct cpu_features *cpu_features = __get_cpu_features (); + if (cpu_features->basic.kind == arch_kind_unknown) +- init_cpu_features (cpu_features); ++ { ++ init_cpu_features (cpu_features); ++ ++# if IS_IN (rtld) ++ /* See isa-level.c. */ ++# if defined GCCMACRO__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \ ++ && defined HAVE_X86_LAHF_SAHF && defined GCCMACRO__POPCNT__ \ ++ && defined GCCMACRO__SSE3__ && defined GCCMACRO__SSSE3__ \ ++ && defined GCCMACRO__SSE4_1__ && defined GCCMACRO__SSE4_2__ ++ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V2)) ++ _dl_fatal_printf ("\ ++Fatal glibc error: CPU does not support x86-64-v%d\n", 2); ++# if defined GCCMACRO__AVX__ && defined GCCMACRO__AVX2__ \ ++ && defined GCCMACRO__F16C__ && defined GCCMACRO__FMA__ \ ++ && defined GCCMACRO__LZCNT__ && defined HAVE_X86_MOVBE ++ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V3)) ++ _dl_fatal_printf ("\ ++Fatal glibc error: CPU does not support x86-64-v%d\n", 3); ++# if defined GCCMACRO__AVX512F__ && defined GCCMACRO__AVX512BW__ \ ++ && defined GCCMACRO__AVX512CD__ && defined GCCMACRO__AVX512DQ__ \ ++ && defined GCCMACRO__AVX512VL__ ++ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V4)) ++ _dl_fatal_printf ("\ ++Fatal glibc error: CPU does not support x86-64-v%d\n", 4); ++# endif /* ISA level 4 */ ++# endif /* ISA level 3 */ ++# endif /* ISA level 2 */ ++# endif /* IS_IN (rtld) */ ++ } + } + + __ifunc (__x86_cpu_features, __x86_cpu_features, NULL, void, diff --git a/SOURCES/glibc-rh2040657-11.patch b/SOURCES/glibc-rh2040657-11.patch new file mode 100644 index 0000000..1ca3409 --- /dev/null +++ b/SOURCES/glibc-rh2040657-11.patch @@ -0,0 +1,37 @@ +commit f01d482f0355a7029d0715ace0ccf3323e7e94bc +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + s390x: Use in early HWCAP check + + This is required so that the checks still work if $(early-cflags) + selects a different ISA level. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + +diff --git a/sysdeps/s390/s390-64/dl-hwcap-check.h b/sysdeps/s390/s390-64/dl-hwcap-check.h +index 87e18be6bd0c512b..27f7e245b1d1a9e9 100644 +--- a/sysdeps/s390/s390-64/dl-hwcap-check.h ++++ b/sysdeps/s390/s390-64/dl-hwcap-check.h +@@ -19,17 +19,18 @@ + #ifndef _DL_HWCAP_CHECK_H + #define _DL_HWCAP_CHECK_H + ++#include + #include + + static inline void + dl_hwcap_check (void) + { + #if defined __ARCH__ +-# if __ARCH__ >= 13 ++# if GCCMACRO__ARCH__ >= 13 + if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_EXT2)) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks VXRS_EXT2 support (z15 or later required)\n"); +-# elif __ARCH__ >= 12 ++# elif GCCMACRO__ARCH__ >= 12 + if (!(GLRO(dl_hwcap) & HWCAP_S390_VXE)) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks VXE support (z14 or later required)\n"); diff --git a/SOURCES/glibc-rh2040657-12.patch b/SOURCES/glibc-rh2040657-12.patch new file mode 100644 index 0000000..592c08c --- /dev/null +++ b/SOURCES/glibc-rh2040657-12.patch @@ -0,0 +1,158 @@ +commit c90363403b57b3b7919061851cb3e6d9c85e784a +Author: Florian Weimer +Date: Tue Jan 18 13:53:11 2022 +0100 + + elf: Move _dl_setup_hash to its own file + + And compile it with the early CFLAGS. _dl_setup_hash is called + very early for the ld.so link map, so it should be compiled + differently. + + Reviewed-by: Stefan Liebler + Tested-by: Stefan Liebler + +diff --git a/elf/Makefile b/elf/Makefile +index 778e393395fc5248..948296dc2437e9a1 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -69,6 +69,7 @@ dl-routines = \ + dl-reloc \ + dl-runtime \ + dl-scope \ ++ dl-setup_hash \ + dl-sort-maps \ + dl-thread_gscope_wait \ + dl-tls \ +@@ -154,6 +155,7 @@ CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines)) + + # Add the requested compiler flags to the early startup code. + CFLAGS-dl-printf.os += $(rtld-early-cflags) ++CFLAGS-dl-setup_hash.os += $(rtld-early-cflags) + CFLAGS-dl-sysdep.os += $(rtld-early-cflags) + CFLAGS-dl-tunables.os += $(rtld-early-cflags) + CFLAGS-dl-write.os += $(rtld-early-cflags) +diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c +index eea217eb2833164c..3391a990c8d288e5 100644 +--- a/elf/dl-lookup.c ++++ b/elf/dl-lookup.c +@@ -948,51 +948,6 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, + } + + +-/* Cache the location of MAP's hash table. */ +- +-void +-_dl_setup_hash (struct link_map *map) +-{ +- Elf_Symndx *hash; +- +- if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL)) +- { +- Elf32_Word *hash32 +- = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]); +- map->l_nbuckets = *hash32++; +- Elf32_Word symbias = *hash32++; +- Elf32_Word bitmask_nwords = *hash32++; +- /* Must be a power of two. */ +- assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0); +- map->l_gnu_bitmask_idxbits = bitmask_nwords - 1; +- map->l_gnu_shift = *hash32++; +- +- map->l_gnu_bitmask = (ElfW(Addr) *) hash32; +- hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords; +- +- map->l_gnu_buckets = hash32; +- hash32 += map->l_nbuckets; +- map->l_gnu_chain_zero = hash32 - symbias; +- +- /* Initialize MIPS xhash translation table. */ +- ELF_MACHINE_XHASH_SETUP (hash32, symbias, map); +- +- return; +- } +- +- if (!map->l_info[DT_HASH]) +- return; +- hash = (void *) D_PTR (map, l_info[DT_HASH]); +- +- map->l_nbuckets = *hash++; +- /* Skip nchain. */ +- hash++; +- map->l_buckets = hash; +- hash += map->l_nbuckets; +- map->l_chain = hash; +-} +- +- + static void + _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, + const ElfW(Sym) **ref, struct sym_val *value, +diff --git a/elf/dl-setup_hash.c b/elf/dl-setup_hash.c +new file mode 100644 +index 0000000000000000..6dd57c5c94e541c2 +--- /dev/null ++++ b/elf/dl-setup_hash.c +@@ -0,0 +1,63 @@ ++/* Cache the location of a link map hash table. ++ Copyright (C) 1995-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void ++_dl_setup_hash (struct link_map *map) ++{ ++ Elf_Symndx *hash; ++ ++ if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL)) ++ { ++ Elf32_Word *hash32 ++ = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]); ++ map->l_nbuckets = *hash32++; ++ Elf32_Word symbias = *hash32++; ++ Elf32_Word bitmask_nwords = *hash32++; ++ /* Must be a power of two. */ ++ assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0); ++ map->l_gnu_bitmask_idxbits = bitmask_nwords - 1; ++ map->l_gnu_shift = *hash32++; ++ ++ map->l_gnu_bitmask = (ElfW(Addr) *) hash32; ++ hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords; ++ ++ map->l_gnu_buckets = hash32; ++ hash32 += map->l_nbuckets; ++ map->l_gnu_chain_zero = hash32 - symbias; ++ ++ /* Initialize MIPS xhash translation table. */ ++ ELF_MACHINE_XHASH_SETUP (hash32, symbias, map); ++ ++ return; ++ } ++ ++ if (!map->l_info[DT_HASH]) ++ return; ++ hash = (void *) D_PTR (map, l_info[DT_HASH]); ++ ++ map->l_nbuckets = *hash++; ++ /* Skip nchain. */ ++ hash++; ++ map->l_buckets = hash; ++ hash += map->l_nbuckets; ++ map->l_chain = hash; ++} diff --git a/SOURCES/glibc-rh2040657-2.patch b/SOURCES/glibc-rh2040657-2.patch new file mode 100644 index 0000000..02b8953 --- /dev/null +++ b/SOURCES/glibc-rh2040657-2.patch @@ -0,0 +1,42 @@ +commit f4f70c2895e3d325188a42c10eb7bb4335be6773 +Author: H.J. Lu +Date: Tue Jan 4 06:58:34 2022 -0800 + + elf: Add a comment after trailing backslashes + +diff --git a/elf/Makefile b/elf/Makefile +index 0cfcf0a61a442c9f..5b9c36bc6f0a3ee5 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -319,6 +319,7 @@ tests-cxx = \ + tst-nodelete \ + tst-unique3 \ + tst-unique4 \ ++# tests-cxx + + tests += $(if $(CXX),$(tests-cxx)) + tests-internal += loadtest unload unload2 circleload1 \ +@@ -583,6 +584,7 @@ modules-names = \ + vismod1 \ + vismod2 \ + vismod3 \ ++# modules-names + + modules-names-cxx = \ + tst-dlopen-nodelete-reloc-mod1 \ +@@ -608,6 +610,7 @@ modules-names-cxx = \ + tst-unique3lib \ + tst-unique3lib2 \ + tst-unique4lib \ ++# modules-names-cxx + + modules-names += \ + $(if $(CXX),$(modules-names-cxx)) \ +@@ -617,6 +620,7 @@ modules-names += \ + $(tst-tls-many-dynamic-modules-dep-bad) \ + $(tlsmod17a-modules) \ + $(tlsmod18a-modules) \ ++# modules-names + + # Most modules build with _ISOMAC defined, but those filtered out + # depend on internal headers. diff --git a/SOURCES/glibc-rh2040657-3.patch b/SOURCES/glibc-rh2040657-3.patch new file mode 100644 index 0000000..5c63516 --- /dev/null +++ b/SOURCES/glibc-rh2040657-3.patch @@ -0,0 +1,171 @@ +commit 0835c0f0bad351117154b815f34f8af19ea7e325 +Author: Matt Whitlock +Date: Wed Jun 16 23:40:47 2021 -0400 + + x86: fix Autoconf caching of instruction support checks [BZ #27991] + + The Autoconf documentation for the AC_CACHE_CHECK macro states: + + The commands-to-set-it must have no side effects except for setting + the variable cache-id, see below. + + However, the tests for support of -msahf and -mmovbe were embedded in + the commands-to-set-it for lib_cv_include_x86_isa_level. This had the + consequence that libc_cv_have_x86_lahf_sahf and libc_cv_have_x86_movbe + were not defined whenever lib_cv_include_x86_isa_level was read from + cache. These variables' being undefined meant that their unquoted use + in later test expressions led to the 'test' built-in's misparsing its + arguments and emitting errors like "test: =: unexpected operator" or + "test: =: unary operator expected", depending on the particular shell. + + This commit refactors the tests for LAHF/SAHF and MOVBE instruction + support into their own AC_CACHE_CHECK macro invocations to obey the + rule that the commands-to-set-it must have no side effects other than + setting the variable named by cache-id. + + Signed-off-by: Matt Whitlock + Reviewed-by: Adhemerval Zanella + +diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure +index ead1295c38cf5f4e..62676bb686850938 100644 +--- a/sysdeps/x86/configure ++++ b/sysdeps/x86/configure +@@ -126,8 +126,6 @@ cat > conftest2.S <&5 + (eval $ac_try) 2>&5 +@@ -137,9 +135,22 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest c + count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l` + if test "$count" = 1; then + libc_cv_include_x86_isa_level=yes +- cat > conftest.c <&5 ++$as_echo "$libc_cv_include_x86_isa_level" >&6; } ++if test $libc_cv_include_x86_isa_level = yes; then ++ $as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LAHF/SAHF instruction support" >&5 ++$as_echo_n "checking for LAHF/SAHF instruction support... " >&6; } ++if ${libc_cv_have_x86_lahf_sahf+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ libc_cv_have_x86_lahf_sahf=no ++ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -147,7 +158,20 @@ EOF + test $ac_status = 0; }; } | grep -q "\-msahf"; then + libc_cv_have_x86_lahf_sahf=yes + fi +- if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c' ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_lahf_sahf" >&5 ++$as_echo "$libc_cv_have_x86_lahf_sahf" >&6; } ++ if test $libc_cv_have_x86_lahf_sahf = yes; then ++ $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h ++ ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MOVBE instruction support" >&5 ++$as_echo_n "checking for MOVBE instruction support... " >&6; } ++if ${libc_cv_have_x86_movbe+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ libc_cv_have_x86_movbe=no ++ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -155,23 +179,13 @@ EOF + test $ac_status = 0; }; } | grep -q "\-mmovbe"; then + libc_cv_have_x86_movbe=yes + fi +- fi +-fi +-rm -f conftest* +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_include_x86_isa_level" >&5 +-$as_echo "$libc_cv_include_x86_isa_level" >&6; } +-if test $libc_cv_include_x86_isa_level = yes; then +- $as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h +- + fi +-if test $libc_cv_have_x86_lahf_sahf = yes; then +- $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h +- +-fi +-if test $libc_cv_have_x86_movbe = yes; then +- $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_movbe" >&5 ++$as_echo "$libc_cv_have_x86_movbe" >&6; } ++ if test $libc_cv_have_x86_movbe = yes; then ++ $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h + ++ fi + fi + config_vars="$config_vars + enable-x86-isa-level = $libc_cv_include_x86_isa_level" +diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac +index bca97fdc2f1ac1a7..04a12ab68048cd66 100644 +--- a/sysdeps/x86/configure.ac ++++ b/sysdeps/x86/configure.ac +@@ -98,30 +98,32 @@ cat > conftest2.S < conftest.c < +Date: Fri Jan 14 16:09:20 2022 +0100 + + x86: HAVE_X86_LAHF_SAHF, HAVE_X86_MOVBE and -march=x86-64-vN (bug 28782) + + HAVE_X86_LAHF_SAHF is implied by x86-64-v2, and HAVE_X86_MOVBE by + x86-64-v3. + + The individual flag does not appear in -fverbose-asm flag output + even if the ISA level implies it. + + Reviewed-by: H.J. Lu + +diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure +index 62676bb686850938..7bdbfdc6dc2ad38f 100644 +--- a/sysdeps/x86/configure ++++ b/sysdeps/x86/configure +@@ -155,7 +155,7 @@ else + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; } | grep -q "\-msahf"; then ++ test $ac_status = 0; }; } | grep -qE '(-msahf\b|-march=x86-64-v)'; then + libc_cv_have_x86_lahf_sahf=yes + fi + fi +@@ -176,7 +176,7 @@ else + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; } | grep -q "\-mmovbe"; then ++ test $ac_status = 0; }; } | grep -qE '(-mmovbe\b|-march=x86-64-v([3-9]|[1-9][0-9]))'; then + libc_cv_have_x86_movbe=yes + fi + fi +diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac +index 04a12ab68048cd66..10d5c2e0e555fc79 100644 +--- a/sysdeps/x86/configure.ac ++++ b/sysdeps/x86/configure.ac +@@ -110,7 +110,7 @@ if test $libc_cv_include_x86_isa_level = yes; then + AC_CACHE_CHECK([for LAHF/SAHF instruction support], + libc_cv_have_x86_lahf_sahf, [dnl + libc_cv_have_x86_lahf_sahf=no +- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-msahf"; then ++ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -qE '(-msahf\b|-march=x86-64-v)'; then + libc_cv_have_x86_lahf_sahf=yes + fi]) + if test $libc_cv_have_x86_lahf_sahf = yes; then +@@ -119,7 +119,7 @@ if test $libc_cv_include_x86_isa_level = yes; then + AC_CACHE_CHECK([for MOVBE instruction support], + libc_cv_have_x86_movbe, [dnl + libc_cv_have_x86_movbe=no +- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-mmovbe"; then ++ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -qE '(-mmovbe\b|-march=x86-64-v(@<:@3-9@:>@|@<:@1-9@:>@@<:@0-9@:>@))'; then + libc_cv_have_x86_movbe=yes + fi]) + if test $libc_cv_have_x86_movbe = yes; then diff --git a/SOURCES/glibc-rh2040657-5.patch b/SOURCES/glibc-rh2040657-5.patch new file mode 100644 index 0000000..bf5343e --- /dev/null +++ b/SOURCES/glibc-rh2040657-5.patch @@ -0,0 +1,32 @@ +commit ef7c6d42fe163a5e49a478c43e655ce4633fa5ba +Author: Florian Weimer +Date: Fri Jan 14 16:09:20 2022 +0100 + + Generate gcc-macros.h + + The file can be used to check the effect of the default compiler + flags on code generation even in areas of the build that uses + non-default compiler flags. + + Reviewed-by: H.J. Lu + +diff --git a/Makeconfig b/Makeconfig +index 8bc5540292c7b6fa..99898a632a64be91 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -1202,6 +1202,15 @@ $(common-objpfx)dl-tunable-list.stmp: \ + touch $@ + endif + ++# Dump the GCC macros used by the default compiler flags to a header ++# file, so that they can be inspected when using different compiler ++# flags. Add the GCCMACRO prefix to make these macro names unique. ++$(common-objpfx)gcc-macros.h.in: $(common-objpfx)config.status ++ $(CC) $(CFLAGS) $(CPPFLAGS) -E -dM -x c -o $@ /dev/null ++$(common-objpfx)gcc-macros.h: $(common-objpfx)gcc-macros.h.in ++ sed 's/^#define /#define GCCMACRO/' < $< > $@ ++before-compile += $(common-objpfx)gcc-macros.h ++ + # Generate version maps, but wait until sysdep-subdirs is known + ifeq ($(sysd-sorted-done),t) + ifeq ($(build-shared),yes) diff --git a/SOURCES/glibc-rh2040657-6.patch b/SOURCES/glibc-rh2040657-6.patch new file mode 100644 index 0000000..15caf1d --- /dev/null +++ b/SOURCES/glibc-rh2040657-6.patch @@ -0,0 +1,549 @@ +commit 7de01e60c200c431d3469deb784da8fd4508fc15 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + elf/Makefile: Reflow and sort most variable assignments + + Reviewed-by: H.J. Lu + +Conflicts: + elf/Makefile + (Usual backporting differences. LLD support is missing + downstream.) + +diff --git a/elf/Makefile b/elf/Makefile +index 5b9c36bc6f0a3ee5..124905f96c88ab53 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -21,21 +21,62 @@ subdir := elf + + include ../Makeconfig + +-headers = elf.h bits/elfclass.h link.h bits/link.h +-routines = $(all-dl-routines) dl-support dl-iteratephdr \ +- dl-addr dl-addr-obj enbl-secure dl-profstub \ +- dl-origin dl-libc dl-sym dl-sysdep dl-error \ +- dl-reloc-static-pie libc_early_init rtld_static_init ++headers = \ ++ bits/elfclass.h \ ++ bits/link.h \ ++ elf.h \ ++ link.h \ ++ # headers ++ ++routines = \ ++ $(all-dl-routines) \ ++ dl-addr \ ++ dl-addr-obj \ ++ dl-error \ ++ dl-iteratephdr \ ++ dl-libc \ ++ dl-origin \ ++ dl-profstub \ ++ dl-reloc-static-pie \ ++ dl-support \ ++ dl-sym \ ++ dl-sysdep \ ++ enbl-secure \ ++ libc_early_init \ ++ rtld_static_init \ ++ # routines + + # The core dynamic linking functions are in libc for the static and + # profiled libraries. +-dl-routines = $(addprefix dl-,load lookup object reloc deps \ +- runtime init fini debug misc \ +- version profile tls origin scope \ +- execstack open close trampoline \ +- exception sort-maps lookup-direct \ +- call-libc-early-init write \ +- thread_gscope_wait tls_init_tp) ++dl-routines = \ ++ dl-call-libc-early-init \ ++ dl-close \ ++ dl-debug \ ++ dl-deps \ ++ dl-exception \ ++ dl-execstack \ ++ dl-fini \ ++ dl-init \ ++ dl-load \ ++ dl-lookup \ ++ dl-lookup-direct \ ++ dl-misc \ ++ dl-object \ ++ dl-open \ ++ dl-origin \ ++ dl-profile \ ++ dl-reloc \ ++ dl-runtime \ ++ dl-scope \ ++ dl-sort-maps \ ++ dl-thread_gscope_wait \ ++ dl-tls \ ++ dl-tls_init_tp \ ++ dl-trampoline \ ++ dl-version \ ++ dl-write \ ++ # dl-routines ++ + ifeq (yes,$(use-ldconfig)) + dl-routines += dl-cache + endif +@@ -58,16 +99,38 @@ endif + + all-dl-routines = $(dl-routines) $(sysdep-dl-routines) + # But they are absent from the shared libc, because that code is in ld.so. +-elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \ +- dl-sysdep dl-exception dl-reloc-static-pie \ +- thread_gscope_wait rtld_static_init ++elide-routines.os = \ ++ $(all-dl-routines) \ ++ dl-exception \ ++ dl-origin \ ++ dl-reloc-static-pie \ ++ dl-support \ ++ dl-sysdep \ ++ enbl-secure \ ++ rtld_static_init \ ++ thread_gscope_wait \ ++ # elide-routines.os + + # ld.so uses those routines, plus some special stuff for being the program + # interpreter and operating independent of libc. +-rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal \ +- dl-error-minimal dl-conflict dl-hwcaps dl-hwcaps_split dl-hwcaps-subdirs \ +- dl-usage dl-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu \ +- dl-mutex ++rtld-routines = \ ++ $(all-dl-routines) \ ++ dl-conflict \ ++ dl-diagnostics \ ++ dl-diagnostics-cpu \ ++ dl-diagnostics-kernel \ ++ dl-environ \ ++ dl-error-minimal \ ++ dl-hwcaps \ ++ dl-hwcaps-subdirs \ ++ dl-hwcaps_split \ ++ dl-minimal \ ++ dl-mutex \ ++ dl-sysdep \ ++ dl-usage \ ++ rtld \ ++ # rtld-routines ++ + all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines) + + CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables +@@ -102,8 +165,16 @@ ld-map = $(common-objpfx)ld.map + endif + + ifeq (yes,$(build-shared)) +-extra-objs = $(all-rtld-routines:%=%.os) sofini.os interp.os +-generated += librtld.os dl-allobjs.os ld.so ldd ++extra-objs = \ ++ $(all-rtld-routines:%=%.os) \ ++ sofini.os \ ++ interp.os \ ++ # extra-objs ++generated += \ ++ dl-allobjs.os \ ++ ld.so ldd \ ++ librtld.os \ ++ # generated + install-others = $(inst_rtlddir)/$(rtld-installed-name) $(inst_bindir)/ld.so + install-bin-script = ldd + endif +@@ -121,8 +192,15 @@ others-static += ldconfig + others += ldconfig + install-rootsbin += ldconfig + +-ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon static-stubs \ +- stringtable ++ldconfig-modules := \ ++ cache \ ++ chroot_canon \ ++ readlib \ ++ static-stubs \ ++ stringtable \ ++ xmalloc \ ++ xstrdup \ ++ # ldconfig-modules + extra-objs += $(ldconfig-modules:=.o) + others-extras = $(ldconfig-modules) + endif +@@ -156,23 +234,36 @@ $(inst_auditdir)/sotruss-lib.so: $(objpfx)sotruss-lib.so $(+force) + $(do-install-program) + endif + +-tests-static-normal := tst-array1-static tst-array5-static \ +- tst-dl-iter-static \ +- tst-tlsalign-static tst-tlsalign-extern-static \ +- tst-linkall-static tst-env-setuid tst-env-setuid-tunables \ +- tst-single_threaded-static tst-single_threaded-pthread-static \ +- tst-dst-static tst-getauxval-static +- +-tests-static-internal := tst-tls1-static tst-tls2-static \ +- tst-ptrguard1-static tst-stackguard1-static \ +- tst-tls1-static-non-pie ++tests-static-normal := \ ++ tst-array1-static \ ++ tst-array5-static \ ++ tst-dl-iter-static \ ++ tst-dst-static \ ++ tst-env-setuid \ ++ tst-env-setuid-tunables \ ++ tst-getauxval-static \ ++ tst-linkall-static \ ++ tst-single_threaded-pthread-static \ ++ tst-single_threaded-static \ ++ tst-tlsalign-extern-static \ ++ tst-tlsalign-static \ ++ # tests-static-normal ++ ++tests-static-internal := \ ++ tst-ptrguard1-static \ ++ tst-stackguard1-static \ ++ tst-tls1-static \ ++ tst-tls2-static \ ++ tst-tls1-static-non-pie \ ++ # tests-static-internal + + 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 \ +- tst-ldconfig-ld_so_conf-update ++ tst-ldconfig-bad-aux-cache \ ++ tst-ldconfig-ld_so_conf-update \ ++ # tests-container + + ifeq (no,$(build-hardcoded-path-in-tests)) + # This is an ld.so.cache test, and RPATH/RUNPATH in the executable +@@ -180,14 +271,32 @@ ifeq (no,$(build-hardcoded-path-in-tests)) + tests-container += tst-glibc-hwcaps-prepend-cache + endif + +-tests := tst-tls9 tst-leaks1 \ +- tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \ +- tst-auxv tst-stringtable +-tests-internal := tst-tls1 tst-tls2 $(tests-static-internal) ++tests := \ ++ tst-array1 \ ++ tst-array2 \ ++ tst-array3 \ ++ tst-array4 \ ++ tst-array5 \ ++ tst-auxv \ ++ tst-leaks1 \ ++ tst-stringtable \ ++ tst-tls9 \ ++ # tests ++ ++tests-internal := \ ++ $(tests-static-internal) \ ++ tst-tls1 \ ++ tst-tls2 \ ++ # tests-internal ++ + tests-static := $(tests-static-normal) $(tests-static-internal) + + ifeq (yes,$(build-shared)) +-tests-static += tst-tls9-static tst-single_threaded-static-dlopen ++tests-static += \ ++ tst-single_threaded-static-dlopen \ ++ tst-tls9-static \ ++ # tests-static ++ + static-dlopen-environment = \ + LD_LIBRARY_PATH=$(ld-library-path):$(common-objpfx)dlfcn + tst-tls9-static-ENV = $(static-dlopen-environment) +@@ -313,33 +422,69 @@ tests += \ + unload6 \ + unload7 \ + unload8 \ +-# reldep9 ++ # tests + tests-cxx = \ + tst-dlopen-nodelete-reloc \ + tst-nodelete \ + tst-unique3 \ + tst-unique4 \ +-# tests-cxx ++ # tests-cxx + + tests += $(if $(CXX),$(tests-cxx)) +-tests-internal += loadtest unload unload2 circleload1 \ +- neededtest neededtest2 neededtest3 neededtest4 \ +- tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \ +- tst-ptrguard1 tst-stackguard1 \ +- tst-create_format1 tst-tls-surplus tst-dl-hwcaps_split +-tests-container += tst-pldd tst-dlopen-tlsmodid-container \ +- tst-dlopen-self-container tst-preload-pthread-libc +-test-srcs = tst-pathopt ++ ++tests-internal += \ ++ circleload1 \ ++ loadtest \ ++ neededtest \ ++ neededtest2 \ ++ neededtest3 \ ++ neededtest4 \ ++ tst-create_format1 \ ++ tst-dl-hwcaps_split \ ++ tst-dlmopen2 \ ++ tst-ptrguard1 \ ++ tst-stackguard1 \ ++ tst-tls-surplus \ ++ tst-tls3 \ ++ tst-tls6 \ ++ tst-tls7 \ ++ tst-tls8 \ ++ unload \ ++ unload2 \ ++ # tests-internal ++ ++tests-container += \ ++ tst-dlopen-self-container \ ++ tst-dlopen-tlsmodid-container \ ++ tst-pldd \ ++ tst-preload-pthread-libc \ ++ # tests-container ++ ++test-srcs = \ ++ tst-pathopt \ ++ # tests-srcs ++ ++ifeq (yes,$(have-fpie)) ++tests-pie += tst-align3 ++endif + selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) ++ + ifneq ($(selinux-enabled),1) +-tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog ++tests-execstack-yes = \ ++ tst-execstack \ ++ tst-execstack-needed \ ++ tst-execstack-prog \ ++ # tests-execstack-yes + endif + endif + tests += $(tests-execstack-$(have-z-execstack)) + ifeq ($(run-built-tests),yes) +-tests-special += $(objpfx)tst-leaks1-mem.out \ +- $(objpfx)noload-mem.out \ +- $(objpfx)tst-ldconfig-X.out $(objpfx)tst-rtld-help.out ++tests-special += \ ++ $(objpfx)noload-mem.out \ ++ $(objpfx)tst-ldconfig-X.out \ ++ $(objpfx)tst-leaks1-mem.out \ ++ $(objpfx)tst-rtld-help.out \ ++ # tests-special + endif + tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 + tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 +@@ -356,9 +501,16 @@ tst-tls-many-dynamic-modules-dep = \ + tst-tls-many-dynamic-modules-dep-bad-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + tst-tls-many-dynamic-modules-dep-bad = \ + $(foreach n,$(tst-tls-many-dynamic-modules-dep-bad-suffixes),tst-tls-manydynamic$(n)mod-dep-bad) +-extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \ +- tst-tlsalign-vars.o +-test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars ++extra-test-objs += \ ++ $(tlsmod17a-modules:=.os) \ ++ $(tlsmod18a-modules:=.os) \ ++ tst-tlsalign-vars.o \ ++ # extra-test-objs ++test-extras += \ ++ tst-tlsalign-vars \ ++ tst-tlsmod17a \ ++ tst-tlsmod18a \ ++ # test-extras + modules-names = \ + circlemod1 \ + circlemod1a \ +@@ -610,17 +762,17 @@ modules-names-cxx = \ + tst-unique3lib \ + tst-unique3lib2 \ + tst-unique4lib \ +-# modules-names-cxx ++ # modules-names-cxx + + modules-names += \ + $(if $(CXX),$(modules-names-cxx)) \ + $(modules-execstack-$(have-z-execstack)) \ ++ $(tlsmod17a-modules) \ ++ $(tlsmod18a-modules) \ + $(tst-tls-many-dynamic-modules) \ + $(tst-tls-many-dynamic-modules-dep) \ + $(tst-tls-many-dynamic-modules-dep-bad) \ +- $(tlsmod17a-modules) \ +- $(tlsmod18a-modules) \ +-# modules-names ++ # modules-names + + # Most modules build with _ISOMAC defined, but those filtered out + # depend on internal headers. +@@ -669,35 +821,70 @@ modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod + tests += $(tests-static) + + ifeq (yes,$(have-ifunc)) +-tests-ifuncstatic := ifuncmain1static ifuncmain1picstatic \ +- ifuncmain2static ifuncmain2picstatic \ +- ifuncmain4static ifuncmain4picstatic \ +- ifuncmain5static ifuncmain5picstatic \ +- ifuncmain7static ifuncmain7picstatic ++tests-ifuncstatic := \ ++ ifuncmain1static \ ++ ifuncmain1picstatic \ ++ ifuncmain2static \ ++ ifuncmain2picstatic \ ++ ifuncmain4static \ ++ ifuncmain4picstatic \ ++ ifuncmain5static \ ++ ifuncmain5picstatic \ ++ ifuncmain7static \ ++ ifuncmain7picstatic \ ++ # tests-ifuncstatic + ifeq (yes,$(have-gcc-ifunc)) + tests-ifuncstatic += ifuncmain9static ifuncmain9picstatic + endif + tests-static += $(tests-ifuncstatic) + tests-internal += $(tests-ifuncstatic) + ifeq (yes,$(build-shared)) +-tests += tst-ifunc-fault-lazy tst-ifunc-fault-bindnow ++tests += \ ++ tst-ifunc-fault-bindnow \ ++ tst-ifunc-fault-lazy \ ++ # tests + # Note: sysdeps/x86_64/ifuncmain8.c uses ifuncmain8. + tests-internal += \ +- ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \ +- ifuncmain1staticpic \ +- ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \ +- ifuncmain5 ifuncmain5pic ifuncmain5staticpic \ +- ifuncmain7 ifuncmain7pic ++ ifuncmain1 \ ++ ifuncmain1pic \ ++ ifuncmain1staticpic \ ++ ifuncmain1vis \ ++ ifuncmain1vispic \ ++ ifuncmain2 \ ++ ifuncmain2pic \ ++ ifuncmain3 \ ++ ifuncmain4 \ ++ ifuncmain5 \ ++ ifuncmain5pic \ ++ ifuncmain5staticpic \ ++ ifuncmain7 \ ++ ifuncmain7pic \ ++ # tests-internal + ifeq (yes,$(have-gcc-ifunc)) +-tests-internal += ifuncmain9 ifuncmain9pic ++tests-internal += \ ++ ifuncmain9 \ ++ ifuncmain9pic \ ++ # tests-internal + endif +-ifunc-test-modules = ifuncdep1 ifuncdep1pic ifuncdep2 ifuncdep2pic \ +- ifuncdep5 ifuncdep5pic ++ifunc-test-modules = \ ++ ifuncdep1 \ ++ ifuncdep1pic \ ++ ifuncdep2 \ ++ ifuncdep2pic \ ++ ifuncdep5 \ ++ ifuncdep5pic \ ++ # ifunc-test-modules + extra-test-objs += $(ifunc-test-modules:=.o) + test-internal-extras += $(ifunc-test-modules) + ifeq (yes,$(have-fpie)) +-ifunc-pie-tests = ifuncmain1pie ifuncmain1vispie ifuncmain1staticpie \ +- ifuncmain5pie ifuncmain6pie ifuncmain7pie ++ifunc-pie-tests = \ ++ ifuncmain1pie \ ++ ifuncmain1staticpie \ ++ ifuncmain1vispie \ ++ ifuncmain5pie \ ++ ifuncmain6pie \ ++ ifuncmain7pie \ ++ # ifunc-pie-tests + ifeq (yes,$(have-gcc-ifunc)) + ifunc-pie-tests += ifuncmain9pie + endif +@@ -707,30 +894,50 @@ endif + tests-internal += $(ifunc-pie-tests) + tests-pie += $(ifunc-pie-tests) + endif +-modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6 ++modules-names += \ ++ ifuncmod1 \ ++ ifuncmod3 \ ++ ifuncmod5 \ ++ ifuncmod6 \ ++ # module-names + endif + endif + + ifeq (yes,$(build-shared)) + ifeq ($(run-built-tests),yes) +-tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \ +- $(objpfx)tst-rtld-preload.out $(objpfx)argv0test.out \ +- $(objpfx)tst-rtld-help.out ++tests-special += \ ++ $(objpfx)argv0test.out \ ++ $(objpfx)tst-pathopt.out \ ++ $(objpfx)tst-rtld-help.out \ ++ $(objpfx)tst-rtld-load-self.out \ ++ $(objpfx)tst-rtld-preload.out \ ++ # tests-special + endif +-tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \ +- $(objpfx)check-wx-segment.out \ +- $(objpfx)check-localplt.out $(objpfx)check-initfini.out ++tests-special += \ ++ $(objpfx)check-execstack.out \ ++ $(objpfx)check-initfini.out \ ++ $(objpfx)check-localplt.out \ ++ $(objpfx)check-textrel.out \ ++ $(objpfx)check-wx-segment.out \ ++ # tests-special + endif + + ifeq ($(run-built-tests),yes) +-tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \ +- $(objpfx)tst-array1-static-cmp.out \ +- $(objpfx)tst-array2-cmp.out $(objpfx)tst-array3-cmp.out \ +- $(objpfx)tst-array4-cmp.out $(objpfx)tst-array5-cmp.out \ +- $(objpfx)tst-array5-static-cmp.out $(objpfx)order2-cmp.out \ +- $(objpfx)tst-initorder-cmp.out \ +- $(objpfx)tst-initorder2-cmp.out $(objpfx)tst-unused-dep.out \ +- $(objpfx)tst-unused-dep-cmp.out ++tests-special += \ ++ $(objpfx)order-cmp.out \ ++ $(objpfx)order2-cmp.out \ ++ $(objpfx)tst-array1-cmp.out \ ++ $(objpfx)tst-array1-static-cmp.out \ ++ $(objpfx)tst-array2-cmp.out \ ++ $(objpfx)tst-array3-cmp.out \ ++ $(objpfx)tst-array4-cmp.out \ ++ $(objpfx)tst-array5-cmp.out \ ++ $(objpfx)tst-array5-static-cmp.out \ ++ $(objpfx)tst-initorder-cmp.out \ ++ $(objpfx)tst-initorder2-cmp.out \ ++ $(objpfx)tst-unused-dep-cmp.out \ ++ $(objpfx)tst-unused-dep.out \ ++ # tests-special + endif + + ifndef avoid-generated +@@ -835,6 +1042,7 @@ rtld-stubbed-symbols = \ + free \ + malloc \ + realloc \ ++ # rtld-stubbed-symbols + + ifeq ($(have-ssp),yes) + # rtld is not built with the stack protector, so these references will diff --git a/SOURCES/glibc-rh2040657-7.patch b/SOURCES/glibc-rh2040657-7.patch new file mode 100644 index 0000000..1189326 --- /dev/null +++ b/SOURCES/glibc-rh2040657-7.patch @@ -0,0 +1,633 @@ +commit b693d75f0c611bce9b0ad984bad306121d42c535 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + elf: Split dl-printf.c from dl-misc.c + + This allows to use different compiler flags for the diagnostics + code. + + Reviewed-by: H.J. Lu + +diff --git a/elf/Makefile b/elf/Makefile +index 124905f96c88ab53..52aafc89cec835ab 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -64,6 +64,7 @@ dl-routines = \ + dl-object \ + dl-open \ + dl-origin \ ++ dl-printf \ + dl-profile \ + dl-reloc \ + dl-runtime \ +diff --git a/elf/dl-misc.c b/elf/dl-misc.c +index b256d792c6198683..f17140b129343f7b 100644 +--- a/elf/dl-misc.c ++++ b/elf/dl-misc.c +@@ -16,24 +16,16 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#include <_itoa.h> + #include + #include +-#include + #include +-#include +-#include +-#include +-#include ++#include + #include ++#include + #include +-#include + #include +-#include +-#include +-#include <_itoa.h> +-#include +-#include ++#include + + /* Read the whole contents of FILE into new mmap'd space with given + protections. *SIZEP gets the size of the file. On error MAP_FAILED +@@ -70,270 +62,6 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) + return result; + } + +- +-/* Bare-bones printf implementation. This function only knows about +- the formats and flags needed and can handle only up to 64 stripes in +- the output. */ +-static void +-_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg) +-{ +-# define NIOVMAX 64 +- struct iovec iov[NIOVMAX]; +- int niov = 0; +- pid_t pid = 0; +- char pidbuf[12]; +- +- while (*fmt != '\0') +- { +- const char *startp = fmt; +- +- if (tag_p > 0) +- { +- /* Generate the tag line once. It consists of the PID and a +- colon followed by a tab. */ +- if (pid == 0) +- { +- char *p; +- pid = __getpid (); +- assert (pid >= 0 && sizeof (pid_t) <= 4); +- p = _itoa (pid, &pidbuf[10], 10, 0); +- while (p > pidbuf) +- *--p = ' '; +- pidbuf[10] = ':'; +- pidbuf[11] = '\t'; +- } +- +- /* Append to the output. */ +- assert (niov < NIOVMAX); +- iov[niov].iov_len = 12; +- iov[niov++].iov_base = pidbuf; +- +- /* No more tags until we see the next newline. */ +- tag_p = -1; +- } +- +- /* Skip everything except % and \n (if tags are needed). */ +- while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n')) +- ++fmt; +- +- /* Append constant string. */ +- assert (niov < NIOVMAX); +- if ((iov[niov].iov_len = fmt - startp) != 0) +- iov[niov++].iov_base = (char *) startp; +- +- if (*fmt == '%') +- { +- /* It is a format specifier. */ +- char fill = ' '; +- int width = -1; +- int prec = -1; +-#if LONG_MAX != INT_MAX +- int long_mod = 0; +-#endif +- +- /* Recognize zero-digit fill flag. */ +- if (*++fmt == '0') +- { +- fill = '0'; +- ++fmt; +- } +- +- /* See whether with comes from a parameter. Note that no other +- way to specify the width is implemented. */ +- if (*fmt == '*') +- { +- width = va_arg (arg, int); +- ++fmt; +- } +- +- /* Handle precision. */ +- if (*fmt == '.' && fmt[1] == '*') +- { +- prec = va_arg (arg, int); +- fmt += 2; +- } +- +- /* Recognize the l modifier. It is only important on some +- platforms where long and int have a different size. We +- can use the same code for size_t. */ +- if (*fmt == 'l' || *fmt == 'Z') +- { +-#if LONG_MAX != INT_MAX +- long_mod = 1; +-#endif +- ++fmt; +- } +- +- switch (*fmt) +- { +- /* Integer formatting. */ +- case 'd': +- case 'u': +- case 'x': +- { +- /* We have to make a difference if long and int have a +- different size. */ +-#if LONG_MAX != INT_MAX +- unsigned long int num = (long_mod +- ? va_arg (arg, unsigned long int) +- : va_arg (arg, unsigned int)); +-#else +- unsigned long int num = va_arg (arg, unsigned int); +-#endif +- bool negative = false; +- if (*fmt == 'd') +- { +-#if LONG_MAX != INT_MAX +- if (long_mod) +- { +- if ((long int) num < 0) +- negative = true; +- } +- else +- { +- if ((int) num < 0) +- { +- num = (unsigned int) num; +- negative = true; +- } +- } +-#else +- if ((int) num < 0) +- negative = true; +-#endif +- } +- +- /* We use alloca() to allocate the buffer with the most +- pessimistic guess for the size. Using alloca() allows +- having more than one integer formatting in a call. */ +- char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int)); +- char *endp = &buf[1 + 3 * sizeof (unsigned long int)]; +- char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0); +- +- /* Pad to the width the user specified. */ +- if (width != -1) +- while (endp - cp < width) +- *--cp = fill; +- +- if (negative) +- *--cp = '-'; +- +- iov[niov].iov_base = cp; +- iov[niov].iov_len = endp - cp; +- ++niov; +- } +- break; +- +- case 's': +- /* Get the string argument. */ +- iov[niov].iov_base = va_arg (arg, char *); +- iov[niov].iov_len = strlen (iov[niov].iov_base); +- if (prec != -1) +- iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len); +- ++niov; +- break; +- +- case '%': +- iov[niov].iov_base = (void *) fmt; +- iov[niov].iov_len = 1; +- ++niov; +- break; +- +- default: +- assert (! "invalid format specifier"); +- } +- ++fmt; +- } +- else if (*fmt == '\n') +- { +- /* See whether we have to print a single newline character. */ +- if (fmt == startp) +- { +- iov[niov].iov_base = (char *) startp; +- iov[niov++].iov_len = 1; +- } +- else +- /* No, just add it to the rest of the string. */ +- ++iov[niov - 1].iov_len; +- +- /* Next line, print a tag again. */ +- tag_p = 1; +- ++fmt; +- } +- } +- +- /* Finally write the result. */ +- _dl_writev (fd, iov, niov); +-} +- +- +-/* Write to debug file. */ +-void +-_dl_debug_printf (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg); +- va_end (arg); +-} +- +- +-/* Write to debug file but don't start with a tag. */ +-void +-_dl_debug_printf_c (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg); +- va_end (arg); +-} +- +- +-/* Write the given file descriptor. */ +-void +-_dl_dprintf (int fd, const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (fd, 0, fmt, arg); +- va_end (arg); +-} +- +-void +-_dl_printf (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg); +- va_end (arg); +-} +- +-void +-_dl_error_printf (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg); +- va_end (arg); +-} +- +-void +-_dl_fatal_printf (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg); +- va_end (arg); +- _exit (127); +-} +-rtld_hidden_def (_dl_fatal_printf) +- + /* Test whether given NAME matches any of the names of the given object. */ + int + _dl_name_match_p (const char *name, const struct link_map *map) +@@ -354,7 +82,6 @@ _dl_name_match_p (const char *name, const struct link_map *map) + return 0; + } + +- + unsigned long int + _dl_higher_prime_number (unsigned long int n) + { +diff --git a/elf/dl-printf.c b/elf/dl-printf.c +new file mode 100644 +index 0000000000000000..d3264ba96cd959bf +--- /dev/null ++++ b/elf/dl-printf.c +@@ -0,0 +1,292 @@ ++/* printf implementation for the dynamic loader. ++ Copyright (C) 1997-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include <_itoa.h> ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Bare-bones printf implementation. This function only knows about ++ the formats and flags needed and can handle only up to 64 stripes in ++ the output. */ ++static void ++_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg) ++{ ++# define NIOVMAX 64 ++ struct iovec iov[NIOVMAX]; ++ int niov = 0; ++ pid_t pid = 0; ++ char pidbuf[12]; ++ ++ while (*fmt != '\0') ++ { ++ const char *startp = fmt; ++ ++ if (tag_p > 0) ++ { ++ /* Generate the tag line once. It consists of the PID and a ++ colon followed by a tab. */ ++ if (pid == 0) ++ { ++ char *p; ++ pid = __getpid (); ++ assert (pid >= 0 && sizeof (pid_t) <= 4); ++ p = _itoa (pid, &pidbuf[10], 10, 0); ++ while (p > pidbuf) ++ *--p = ' '; ++ pidbuf[10] = ':'; ++ pidbuf[11] = '\t'; ++ } ++ ++ /* Append to the output. */ ++ assert (niov < NIOVMAX); ++ iov[niov].iov_len = 12; ++ iov[niov++].iov_base = pidbuf; ++ ++ /* No more tags until we see the next newline. */ ++ tag_p = -1; ++ } ++ ++ /* Skip everything except % and \n (if tags are needed). */ ++ while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n')) ++ ++fmt; ++ ++ /* Append constant string. */ ++ assert (niov < NIOVMAX); ++ if ((iov[niov].iov_len = fmt - startp) != 0) ++ iov[niov++].iov_base = (char *) startp; ++ ++ if (*fmt == '%') ++ { ++ /* It is a format specifier. */ ++ char fill = ' '; ++ int width = -1; ++ int prec = -1; ++#if LONG_MAX != INT_MAX ++ int long_mod = 0; ++#endif ++ ++ /* Recognize zero-digit fill flag. */ ++ if (*++fmt == '0') ++ { ++ fill = '0'; ++ ++fmt; ++ } ++ ++ /* See whether with comes from a parameter. Note that no other ++ way to specify the width is implemented. */ ++ if (*fmt == '*') ++ { ++ width = va_arg (arg, int); ++ ++fmt; ++ } ++ ++ /* Handle precision. */ ++ if (*fmt == '.' && fmt[1] == '*') ++ { ++ prec = va_arg (arg, int); ++ fmt += 2; ++ } ++ ++ /* Recognize the l modifier. It is only important on some ++ platforms where long and int have a different size. We ++ can use the same code for size_t. */ ++ if (*fmt == 'l' || *fmt == 'Z') ++ { ++#if LONG_MAX != INT_MAX ++ long_mod = 1; ++#endif ++ ++fmt; ++ } ++ ++ switch (*fmt) ++ { ++ /* Integer formatting. */ ++ case 'd': ++ case 'u': ++ case 'x': ++ { ++ /* We have to make a difference if long and int have a ++ different size. */ ++#if LONG_MAX != INT_MAX ++ unsigned long int num = (long_mod ++ ? va_arg (arg, unsigned long int) ++ : va_arg (arg, unsigned int)); ++#else ++ unsigned long int num = va_arg (arg, unsigned int); ++#endif ++ bool negative = false; ++ if (*fmt == 'd') ++ { ++#if LONG_MAX != INT_MAX ++ if (long_mod) ++ { ++ if ((long int) num < 0) ++ negative = true; ++ } ++ else ++ { ++ if ((int) num < 0) ++ { ++ num = (unsigned int) num; ++ negative = true; ++ } ++ } ++#else ++ if ((int) num < 0) ++ negative = true; ++#endif ++ } ++ ++ /* We use alloca() to allocate the buffer with the most ++ pessimistic guess for the size. Using alloca() allows ++ having more than one integer formatting in a call. */ ++ char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int)); ++ char *endp = &buf[1 + 3 * sizeof (unsigned long int)]; ++ char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0); ++ ++ /* Pad to the width the user specified. */ ++ if (width != -1) ++ while (endp - cp < width) ++ *--cp = fill; ++ ++ if (negative) ++ *--cp = '-'; ++ ++ iov[niov].iov_base = cp; ++ iov[niov].iov_len = endp - cp; ++ ++niov; ++ } ++ break; ++ ++ case 's': ++ /* Get the string argument. */ ++ iov[niov].iov_base = va_arg (arg, char *); ++ iov[niov].iov_len = strlen (iov[niov].iov_base); ++ if (prec != -1) ++ iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len); ++ ++niov; ++ break; ++ ++ case '%': ++ iov[niov].iov_base = (void *) fmt; ++ iov[niov].iov_len = 1; ++ ++niov; ++ break; ++ ++ default: ++ assert (! "invalid format specifier"); ++ } ++ ++fmt; ++ } ++ else if (*fmt == '\n') ++ { ++ /* See whether we have to print a single newline character. */ ++ if (fmt == startp) ++ { ++ iov[niov].iov_base = (char *) startp; ++ iov[niov++].iov_len = 1; ++ } ++ else ++ /* No, just add it to the rest of the string. */ ++ ++iov[niov - 1].iov_len; ++ ++ /* Next line, print a tag again. */ ++ tag_p = 1; ++ ++fmt; ++ } ++ } ++ ++ /* Finally write the result. */ ++ _dl_writev (fd, iov, niov); ++} ++ ++ ++/* Write to debug file. */ ++void ++_dl_debug_printf (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg); ++ va_end (arg); ++} ++ ++ ++/* Write to debug file but don't start with a tag. */ ++void ++_dl_debug_printf_c (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg); ++ va_end (arg); ++} ++ ++ ++/* Write the given file descriptor. */ ++void ++_dl_dprintf (int fd, const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (fd, 0, fmt, arg); ++ va_end (arg); ++} ++ ++void ++_dl_printf (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg); ++ va_end (arg); ++} ++ ++void ++_dl_error_printf (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg); ++ va_end (arg); ++} ++ ++void ++_dl_fatal_printf (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg); ++ va_end (arg); ++ _exit (127); ++} ++rtld_hidden_def (_dl_fatal_printf) diff --git a/SOURCES/glibc-rh2040657-8.patch b/SOURCES/glibc-rh2040657-8.patch new file mode 100644 index 0000000..7eabbc4 --- /dev/null +++ b/SOURCES/glibc-rh2040657-8.patch @@ -0,0 +1,146 @@ +commit 9ba202c78f0aa39f49929eee63c367847da72ee4 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + Add --with-rtld-early-cflags configure option + + Reviewed-by: H.J. Lu + Reviewed-by: Carlos O'Donell + +Conflicts: + INSTALL + configure + manual/install.texi + (Missing --with-timeout-factor downstream.) + +diff --git a/INSTALL b/INSTALL +index d6d93ec9be4262d7..d8d4e9f155f56616 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -106,6 +106,14 @@ if 'CFLAGS' is specified it must enable optimization. For example: + particular case and potentially change debugging information and + metadata only). + ++'--with-rtld-early-cflags=CFLAGS' ++ Use additional compiler flags CFLAGS to build the early startup ++ code of the dynamic linker. These flags can be used to enable ++ early dynamic linker diagnostics to run on CPUs which are not ++ compatible with the rest of the GNU C Library, for example, due to ++ compiler flags which target a later instruction set architecture ++ (ISA). ++ + '--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/config.make.in b/config.make.in +index e8630a8d0ccf874d..6d43e691f7823262 100644 +--- a/config.make.in ++++ b/config.make.in +@@ -110,6 +110,7 @@ CFLAGS = @CFLAGS@ + CPPFLAGS-config = @CPPFLAGS@ + CPPUNDEFS = @CPPUNDEFS@ + extra-nonshared-cflags = @extra_nonshared_cflags@ ++rtld-early-cflags = @rtld_early_cflags@ + ASFLAGS-config = @ASFLAGS_config@ + AR = @AR@ + NM = @NM@ +diff --git a/configure b/configure +index e9d2b1f398c4dba0..03f4e59e754b5463 100755 +--- a/configure ++++ b/configure +@@ -681,6 +681,7 @@ force_install + bindnow + hardcoded_path_in_tests + enable_timezone_tools ++rtld_early_cflags + extra_nonshared_cflags + use_default_link + sysheaders +@@ -761,6 +762,7 @@ with_selinux + with_headers + with_default_link + with_nonshared_cflags ++with_rtld_early_cflags + enable_sanity_checks + enable_shared + enable_profile +@@ -1479,6 +1481,8 @@ Optional Packages: + --with-default-link do not use explicit linker scripts + --with-nonshared-cflags=CFLAGS + build nonshared libraries with additional CFLAGS ++ --with-rtld-early-cflags=CFLAGS ++ build early initialization with additional CFLAGS + --with-cpu=CPU select code for CPU variant + + Some influential environment variables: +@@ -3383,6 +3387,16 @@ fi + + + ++# Check whether --with-rtld-early-cflags was given. ++if test "${with_rtld_early_cflags+set}" = set; then : ++ withval=$with_rtld_early_cflags; rtld_early_cflags=$withval ++else ++ rtld_early_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 79f6822d29ce21cf..eb9431875fae1b0e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -162,6 +162,12 @@ AC_ARG_WITH([nonshared-cflags], + [extra_nonshared_cflags=$withval], + [extra_nonshared_cflags=]) + AC_SUBST(extra_nonshared_cflags) ++AC_ARG_WITH([rtld-early-cflags], ++ AS_HELP_STRING([--with-rtld-early-cflags=CFLAGS], ++ [build early initialization with additional CFLAGS]), ++ [rtld_early_cflags=$withval], ++ [rtld_early_cflags=]) ++AC_SUBST(rtld_early_cflags) + + AC_ARG_ENABLE([sanity-checks], + AS_HELP_STRING([--disable-sanity-checks], +diff --git a/elf/Makefile b/elf/Makefile +index 52aafc89cec835ab..778e393395fc5248 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -152,6 +152,14 @@ CFLAGS-.o += $(call elide-stack-protector,.o,$(elide-routines.os)) + CFLAGS-.op += $(call elide-stack-protector,.op,$(elide-routines.os)) + CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines)) + ++# Add the requested compiler flags to the early startup code. ++CFLAGS-dl-printf.os += $(rtld-early-cflags) ++CFLAGS-dl-sysdep.os += $(rtld-early-cflags) ++CFLAGS-dl-tunables.os += $(rtld-early-cflags) ++CFLAGS-dl-write.os += $(rtld-early-cflags) ++CFLAGS-dl-writev.os += $(rtld-early-cflags) ++CFLAGS-rtld.os += $(rtld-early-cflags) ++ + ifeq ($(unwind-find-fde),yes) + routines += unwind-dw2-fde-glibc + shared-only-routines += unwind-dw2-fde-glibc +diff --git a/manual/install.texi b/manual/install.texi +index 1320ac69b3c645f2..816b77a0a25a88a7 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -131,6 +131,13 @@ that the objects in @file{libc_nonshared.a} are compiled with this flag + (although this will not affect the generated code in this particular + case and potentially change debugging information and metadata only). + ++@item --with-rtld-early-cflags=@var{cflags} ++Use additional compiler flags @var{cflags} to build the early startup ++code of the dynamic linker. These flags can be used to enable early ++dynamic linker diagnostics to run on CPUs which are not compatible with ++the rest of @theglibc{}, for example, due to compiler flags which target ++a later instruction set architecture (ISA). ++ + @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/glibc-rh2040657-9.patch b/SOURCES/glibc-rh2040657-9.patch new file mode 100644 index 0000000..1908c6f --- /dev/null +++ b/SOURCES/glibc-rh2040657-9.patch @@ -0,0 +1,52 @@ +commit 550116486692efc394d03befee19f7e9c17d5044 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + powerpc64le: Use in early HWCAP check + + This is required so that the checks still work if $(early-cflags) + selects a different ISA level. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + +diff --git a/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h +index 0437ae4d522fb36d..899c74f880e6f5f0 100644 +--- a/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h ++++ b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h +@@ -19,17 +19,18 @@ + #ifndef _DL_HWCAP_CHECK_H + #define _DL_HWCAP_CHECK_H + ++#include + #include + + static inline void + dl_hwcap_check (void) + { +-#ifdef _ARCH_PWR9 ++#ifdef GCCMACRO_ARCH_PWR9 + if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_00) == 0) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks ISA 3.00 support (POWER9 or later required)\n"); + #endif +-#ifdef __FLOAT128_HARDWARE__ ++#ifdef GCCMACRO__FLOAT128_HARDWARE__ + if ((GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_IEEE128) == 0) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks float128 support (POWER 9 or later required)\n"); +@@ -37,12 +38,12 @@ Fatal glibc error: CPU lacks float128 support (POWER 9 or later required)\n"); + /* This check is not actually reached when building for POWER10 and + running on POWER9 because there are faulting PCREL instructions + before this point. */ +-#if defined _ARCH_PWR10 || defined __PCREL__ ++#if defined GCCMACRO_ARCH_PWR10 || defined GCCMACRO__PCREL__ + if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_1) == 0) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks ISA 3.10 support (POWER10 or later required)\n"); + #endif +-#ifdef __MMA__ ++#ifdef GCCMACRO__MMA__ + if ((GLRO (dl_hwcap2) & PPC_FEATURE2_MMA) == 0) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks MMA support (POWER10 or later required)\n"); diff --git a/SOURCES/glibc-rh2054789.patch b/SOURCES/glibc-rh2054789.patch new file mode 100644 index 0000000..68fff2f --- /dev/null +++ b/SOURCES/glibc-rh2054789.patch @@ -0,0 +1,27 @@ +commit ea89d5bbd9e5e514b606045d909e6ab87d851c88 +Author: Arjun Shankar +Date: Thu Feb 24 21:43:09 2022 +0100 + + localedef: Handle symbolic links when generating locale-archive + + Whenever locale data for any locale included symbolic links, localedef + would throw the error "incomplete set of locale files" and exclude it + from the generated locale archive. This commit fixes that. + + Co-authored-by: Florian Weimer + + Reviewed-by: Carlos O'Donell + +diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c +index f38e835c52e4a967..d79278b6ed7340bf 100644 +--- a/locale/programs/locarchive.c ++++ b/locale/programs/locarchive.c +@@ -1391,7 +1391,7 @@ add_locales_to_archive (size_t nlist, char *list[], bool replace) + { + char fullname[fnamelen + 2 * strlen (d->d_name) + 7]; + +- if (d_type == DT_UNKNOWN) ++ if (d_type == DT_UNKNOWN || d_type == DT_LNK) + { + strcpy (stpcpy (stpcpy (fullname, fname), "/"), + d->d_name); diff --git a/SOURCES/glibc-rh2058224-1.patch b/SOURCES/glibc-rh2058224-1.patch new file mode 100644 index 0000000..fd6cacc --- /dev/null +++ b/SOURCES/glibc-rh2058224-1.patch @@ -0,0 +1,296 @@ +commit 2ab8b74567dc0a9a3c98696e6444881997dd6c49 +Author: Carlos O'Donell +Date: Thu Feb 3 16:51:59 2022 -0500 + + localedef: Update LC_MONETARY handling (Bug 28845) + + ISO C17, POSIX Issue 7, and ISO 30112 all allow the char* + types to be empty strings i.e. "", integer or char values to + be -1 or CHAR_MAX respectively, with the exception of + decimal_point which must be non-empty in ISO C. Note that + the defaults for mon_grouping vary, but are functionaly + equivalent e.g. "\177" (no further grouping reuqired) vs. + "" (no grouping defined for all groups). + + We include a broad comment talking about harmonizing ISO C, + POSIX, ISO 30112, and the default C/POSIX locale for glibc. + + We reorder all setting based on locale/categories.def order. + + We soften all missing definitions from errors to warnings when + defaults exist. + + Given that ISO C, POSIX and ISO 30112 allow the empty string + we change LC_MONETARY handling of mon_decimal_point to allow + the empty string. If mon_decimal_point is not defined at all + then we pick the existing legacy glibc default value of + i.e. ".". + + We also set the default for mon_thousands_sep_wc at the + same time as mon_thousands_sep, but this is not a change in + behaviour, it is always either a matching value or L'\0', + but if in the future we change the default to a non-empty + string we would need to update both at the same time. + + Tested on x86_64 and i686 without regressions. + Tested with install-locale-archive target. + Tested with install-locale-files target. + + Reviewed-by: DJ Delorie + +diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c +index 9b9a55bb4766dfcf..17a972e1a7516aa5 100644 +--- a/locale/programs/ld-monetary.c ++++ b/locale/programs/ld-monetary.c +@@ -197,21 +197,105 @@ No definition for %s category found"), "LC_MONETARY"); + } + } + ++ /* Generally speaking there are 3 standards the define the default, ++ warning, and error behaviour of LC_MONETARY. They are ISO/IEC TR 30112, ++ ISO/IEC 9899:2018 (ISO C17), and POSIX.1-2017. Within 30112 we have the ++ definition of a standard i18n FDCC-set, which for LC_MONETARY has the ++ following default values: ++ int_curr_symbol "" ++ currency_symbol "" ++ mon_decimal_point "" i.e. "," ++ mon_thousand_sep "" ++ mon_grouping "\177" i.e. CHAR_MAX ++ positive_sign "" ++ negative_sign "" i.e. "." ++ int_frac_digits -1 ++ frac_digits -1 ++ p_cs_precedes -1 ++ p_sep_by_space -1 ++ n_cs_precedes -1 ++ n_sep_by_space -1 ++ p_sign_posn -1 ++ n_sign_posn -1 ++ Under 30112 a keyword that is not provided implies an empty string "" ++ for string values or a -1 for integer values, and indicates the value ++ is unspecified with no default implied. No errors are considered. ++ The exception is mon_grouping which is a string with a terminating ++ CHAR_MAX. ++ For POSIX Issue 7 we have: ++ https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html ++ and again values not provided default to "" or -1, and indicate the value ++ is not available to the locale. The exception is mon_grouping which is ++ a string with a terminating CHAR_MAX. For the POSIX locale the values of ++ LC_MONETARY should be: ++ int_curr_symbol "" ++ currency_symbol "" ++ mon_decimal_point "" ++ mon_thousands_sep "" ++ mon_grouping "\177" i.e. CHAR_MAX ++ positive_sign "" ++ negative_sign "" ++ int_frac_digits -1 ++ frac_digits -1 ++ p_cs_precedes -1 ++ p_sep_by_space -1 ++ n_cs_precedes -1 ++ n_sep_by_space -1 ++ p_sign_posn -1 ++ n_sign_posn -1 ++ int_p_cs_precedes -1 ++ int_p_sep_by_space -1 ++ int_n_cs_precedes -1 ++ int_n_sep_by_space -1 ++ int_p_sign_posn -1 ++ int_n_sign_posn -1 ++ Like with 30112, POSIX also considers no error if the keywords are ++ missing, only that if the cateory as a whole is missing the referencing ++ of the category results in unspecified behaviour. ++ For ISO C17 there is no default value provided, but the localeconv ++ specification in 7.11.2.1 admits that members of char * type may point ++ to "" to indicate a value is not available or is of length zero. ++ The exception is decimal_point (not mon_decimal_point) which must be a ++ defined non-empty string. The values of char, which are generally ++ mapped to integer values in 30112 and POSIX, must be non-negative ++ numbers that map to CHAR_MAX when a value is not available in the ++ locale. ++ In ISO C17 for the "C" locale all values are empty strings "", or ++ CHAR_MAX, with the exception of decimal_point which is "." (defined ++ in LC_NUMERIC). ISO C17 makes no exception for mon_grouping like ++ 30112 and POSIX, but a value of "" is functionally equivalent to ++ "\177" since neither defines a grouping (though the latter terminates ++ the grouping). ++ ++ Lastly, we must consider the legacy C/POSIX locale that implemented ++ as a builtin in glibc and wether a default value mapping to the ++ C/POSIX locale may benefit the user from a compatibility perspective. ++ ++ Thus given 30112, POSIX, ISO C, and the builtin C/POSIX locale we ++ need to pick appropriate defaults below. */ ++ ++ /* The members of LC_MONETARY are handled in the order of their definition ++ in locale/categories.def. Please keep them in that order. */ ++ ++ /* The purpose of TEST_ELEM is to define a default value for the fields ++ in the category if the field was not defined in the cateory. If the ++ category was present but we didn't see a definition for the field then ++ we also issue a warning, otherwise the only warning you get is the one ++ earlier when a default category is created (completely missing category). ++ This missing field warning is glibc-specific since no standard requires ++ this warning, but we consider it valuable to print a warning for all ++ missing fields in the category. */ + #define TEST_ELEM(cat, initval) \ + if (monetary->cat == NULL) \ + { \ + if (! nothing) \ +- record_error (0, 0, _("%s: field `%s' not defined"), \ +- "LC_MONETARY", #cat); \ ++ record_warning (_("%s: field `%s' not defined"), \ ++ "LC_MONETARY", #cat); \ + monetary->cat = initval; \ + } + ++ /* Keyword: int_curr_symbol. */ + TEST_ELEM (int_curr_symbol, ""); +- TEST_ELEM (currency_symbol, ""); +- TEST_ELEM (mon_thousands_sep, ""); +- TEST_ELEM (positive_sign, ""); +- TEST_ELEM (negative_sign, ""); +- + /* The international currency symbol must come from ISO 4217. */ + if (monetary->int_curr_symbol != NULL) + { +@@ -248,41 +332,63 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"), + } + } + +- /* The decimal point must not be empty. This is not said explicitly +- in POSIX but ANSI C (ISO/IEC 9899) says in 4.4.2.1 it has to be +- != "". */ ++ /* Keyword: currency_symbol */ ++ TEST_ELEM (currency_symbol, ""); ++ ++ /* Keyword: mon_decimal_point */ ++ /* ISO C17 7.11.2.1.3 explicitly allows mon_decimal_point to be the ++ empty string e.g. "". This indicates the value is not available in the ++ current locale or is of zero length. However, if the value was never ++ defined then we issue a warning and use a glibc-specific default. ISO ++ 30112 in the i18n FDCC-Set uses ",", and POSIX Issue 7 in the ++ POSIX locale uses "". It is specific to glibc that the default is ++ "."; we retain this existing behaviour for backwards compatibility. */ + if (monetary->mon_decimal_point == NULL) + { + if (! nothing) +- record_error (0, 0, _("%s: field `%s' not defined"), +- "LC_MONETARY", "mon_decimal_point"); ++ record_warning (_("%s: field `%s' not defined, using defaults"), ++ "LC_MONETARY", "mon_decimal_point"); + monetary->mon_decimal_point = "."; + monetary->mon_decimal_point_wc = L'.'; + } +- else if (monetary->mon_decimal_point[0] == '\0' && ! be_quiet && ! nothing) ++ ++ /* Keyword: mon_thousands_sep */ ++ if (monetary->mon_thousands_sep == NULL) + { +- record_error (0, 0, _("\ +-%s: value for field `%s' must not be an empty string"), +- "LC_MONETARY", "mon_decimal_point"); ++ if (! nothing) ++ record_warning (_("%s: field `%s' not defined, using defaults"), ++ "LC_MONETARY", "mon_thousands_sep"); ++ monetary->mon_thousands_sep = ""; ++ monetary->mon_thousands_sep_wc = L'\0'; + } + ++ /* Keyword: mon_grouping */ + if (monetary->mon_grouping_len == 0) + { + if (! nothing) +- record_error (0, 0, _("%s: field `%s' not defined"), +- "LC_MONETARY", "mon_grouping"); +- ++ record_warning (_("%s: field `%s' not defined"), ++ "LC_MONETARY", "mon_grouping"); ++ /* Missing entries are given 1 element in their bytearray with ++ a value of CHAR_MAX which indicates that "No further grouping ++ is to be performed" (functionally equivalent to ISO C's "C" ++ locale default of ""). */ + monetary->mon_grouping = (char *) "\177"; + monetary->mon_grouping_len = 1; + } + ++ /* Keyword: positive_sign */ ++ TEST_ELEM (positive_sign, ""); ++ ++ /* Keyword: negative_sign */ ++ TEST_ELEM (negative_sign, ""); ++ + #undef TEST_ELEM + #define TEST_ELEM(cat, min, max, initval) \ + if (monetary->cat == -2) \ + { \ + if (! nothing) \ +- record_error (0, 0, _("%s: field `%s' not defined"), \ +- "LC_MONETARY", #cat); \ ++ record_warning (_("%s: field `%s' not defined"), \ ++ "LC_MONETARY", #cat); \ + monetary->cat = initval; \ + } \ + else if ((monetary->cat < min || monetary->cat > max) \ +@@ -301,16 +407,11 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"), + TEST_ELEM (p_sign_posn, -1, 4, -1); + TEST_ELEM (n_sign_posn, -1, 4, -1); + +- /* The non-POSIX.2 extensions are optional. */ +- if (monetary->duo_int_curr_symbol == NULL) +- monetary->duo_int_curr_symbol = monetary->int_curr_symbol; +- if (monetary->duo_currency_symbol == NULL) +- monetary->duo_currency_symbol = monetary->currency_symbol; +- +- if (monetary->duo_int_frac_digits == -2) +- monetary->duo_int_frac_digits = monetary->int_frac_digits; +- if (monetary->duo_frac_digits == -2) +- monetary->duo_frac_digits = monetary->frac_digits; ++ /* Keyword: crncystr */ ++ monetary->crncystr = (char *) xmalloc (strlen (monetary->currency_symbol) ++ + 2); ++ monetary->crncystr[0] = monetary->p_cs_precedes ? '-' : '+'; ++ strcpy (&monetary->crncystr[1], monetary->currency_symbol); + + #undef TEST_ELEM + #define TEST_ELEM(cat, alt, min, max) \ +@@ -328,6 +429,17 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"), + TEST_ELEM (int_p_sign_posn, p_sign_posn, -1, 4); + TEST_ELEM (int_n_sign_posn, n_sign_posn, -1, 4); + ++ /* The non-POSIX.2 extensions are optional. */ ++ if (monetary->duo_int_curr_symbol == NULL) ++ monetary->duo_int_curr_symbol = monetary->int_curr_symbol; ++ if (monetary->duo_currency_symbol == NULL) ++ monetary->duo_currency_symbol = monetary->currency_symbol; ++ ++ if (monetary->duo_int_frac_digits == -2) ++ monetary->duo_int_frac_digits = monetary->int_frac_digits; ++ if (monetary->duo_frac_digits == -2) ++ monetary->duo_frac_digits = monetary->frac_digits; ++ + TEST_ELEM (duo_p_cs_precedes, p_cs_precedes, -1, 1); + TEST_ELEM (duo_p_sep_by_space, p_sep_by_space, -1, 2); + TEST_ELEM (duo_n_cs_precedes, n_cs_precedes, -1, 1); +@@ -350,17 +462,15 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"), + if (monetary->duo_valid_to == 0) + monetary->duo_valid_to = 99991231; + ++ /* Keyword: conversion_rate */ + if (monetary->conversion_rate[0] == 0) + { + monetary->conversion_rate[0] = 1; + monetary->conversion_rate[1] = 1; + } + +- /* Create the crncystr entry. */ +- monetary->crncystr = (char *) xmalloc (strlen (monetary->currency_symbol) +- + 2); +- monetary->crncystr[0] = monetary->p_cs_precedes ? '-' : '+'; +- strcpy (&monetary->crncystr[1], monetary->currency_symbol); ++ /* A value for monetary-decimal-point-wc was set when ++ monetary_decimal_point was set, likewise for monetary-thousands-sep-wc. */ + } + + diff --git a/SOURCES/glibc-rh2058224-2.patch b/SOURCES/glibc-rh2058224-2.patch new file mode 100644 index 0000000..ee6e4cc --- /dev/null +++ b/SOURCES/glibc-rh2058224-2.patch @@ -0,0 +1,62 @@ +commit 1c7a34567d21fbd3b706c77cd794956b43daefe7 +Author: Carlos O'Donell +Date: Thu Feb 3 16:01:52 2022 -0500 + + localedata: Do not generate output if warnings were present. + + With LC_MONETARY parsing fixed we can now generate locales + without forcing output with '-c'. + + Removing '-c' from localedef invocation is the equivalent of + using -Werror for localedef. The glibc locale sources should + always be clean and free from warnings. + + We remove '-c' from both test locale generation and the targets + used for installing locales e.g. install-locale-archive, and + install-locale-files. + + Tested on x86_64 and i686 without regressions. + Tested with install-locale-archive target. + Tested with install-locale-files target. + + Reviewed-by: DJ Delorie + +diff --git a/localedata/Makefile b/localedata/Makefile +index 5830b9d05141cccd..a46da8a9311b00b0 100644 +--- a/localedata/Makefile ++++ b/localedata/Makefile +@@ -469,11 +469,11 @@ define build-one-locale + endef + + $(INSTALL-SUPPORTED-LOCALE-ARCHIVE): install-locales-dir +- @flags="-c"; \ ++ @flags=""; \ + $(build-one-locale) + + $(INSTALL-SUPPORTED-LOCALE-FILES): install-locales-dir +- @flags="-c --no-archive --no-hard-links"; \ ++ @flags="--no-archive --no-hard-links"; \ + $(build-one-locale) + + tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP +diff --git a/localedata/gen-locale.sh b/localedata/gen-locale.sh +index c7e2e160ae1506f8..a25d27f3e6986675 100644 +--- a/localedata/gen-locale.sh ++++ b/localedata/gen-locale.sh +@@ -54,8 +54,14 @@ modifier=`echo $locfile|sed 's|[^.]*[.]\([^@ ]*\)\(@[^ ]*\)\?/LC_CTYPE|\2|'` + + echo "Generating locale $locale.$charmap: this might take a while..." + +-# Run quietly and force output. +-flags="--quiet -c" ++# Do not force output with '-c', all locales should compile without ++# warning or errors. There is likewise no need to run quietly with ++# '--quiet' since all locales should compile without additional ++# diagnostics. If there are messages printed then we want to see ++# them, fix them, and the associated error or warning. During ++# development it may be beneficialy to put '--quiet -c' here to allow ++# you to develop in-progress locales. ++flags="" + + # For SJIS the charmap is SHIFT_JIS. We just want the locale to have + # a slightly nicer name instead of using "*.SHIFT_SJIS", but that diff --git a/SOURCES/glibc-rh2058230.patch b/SOURCES/glibc-rh2058230.patch new file mode 100644 index 0000000..5d7ab3f --- /dev/null +++ b/SOURCES/glibc-rh2058230.patch @@ -0,0 +1,37 @@ +Early backport of upstream patch under discussion: + + [PATCH v3] elf: Fix DFS sorting algorithm for LD_TRACE_LOADED_OBJECTS + with missing libraries (BZ #28868) + + +The tests are still being discussed upstream and are not backported +here. + +diff --git a/elf/dl-deps.c b/elf/dl-deps.c +index 237d9636c5be780c..9e30c6c3f6c58783 100644 +--- a/elf/dl-deps.c ++++ b/elf/dl-deps.c +@@ -489,6 +489,8 @@ _dl_map_object_deps (struct link_map *map, + + for (nlist = 0, runp = known; runp; runp = runp->next) + { ++ /* _dl_sort_maps ignores l_faked object, so it is save to not considere ++ them for nlist. */ + if (__builtin_expect (trace_mode, 0) && runp->map->l_faked) + /* This can happen when we trace the loading. */ + --map->l_searchlist.r_nlist; +diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c +index a274ed66cc987735..72f4ff0e6eda3377 100644 +--- a/elf/dl-sort-maps.c ++++ b/elf/dl-sort-maps.c +@@ -140,7 +140,9 @@ static void + dfs_traversal (struct link_map ***rpo, struct link_map *map, + bool *do_reldeps) + { +- if (map->l_visited) ++ /* _dl_map_object_deps filter l_faked objects when calculating the ++ number of maps before calling _dl_sort_maps, ignore them as well. */ ++ if (map->l_visited || map->l_faked) + return; + + map->l_visited = 1; diff --git a/SOURCES/glibc-rh2085529-1.patch b/SOURCES/glibc-rh2085529-1.patch new file mode 100644 index 0000000..5e49605 --- /dev/null +++ b/SOURCES/glibc-rh2085529-1.patch @@ -0,0 +1,605 @@ +commit c901c3e764d7c7079f006b4e21e877d5036eb4f5 +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Add public rseq symbols and + + The relationship between the thread pointer and the rseq area + is made explicit. The constant offset can be used by JIT compilers + to optimize rseq access (e.g., for really fast sched_getcpu). + + Extensibility is provided through __rseq_size and __rseq_flags. + (In the future, the kernel could request a different rseq size + via the auxiliary vector.) + + Co-Authored-By: Mathieu Desnoyers + Reviewed-by: Szabolcs Nagy + +diff --git a/manual/threads.texi b/manual/threads.texi +index 7f166bfa87e88c36..4869f69d2ceed255 100644 +--- a/manual/threads.texi ++++ b/manual/threads.texi +@@ -629,6 +629,8 @@ the standard. + * Waiting with Explicit Clocks:: Functions for waiting with an + explicit clock specification. + * Single-Threaded:: Detecting single-threaded execution. ++* Restartable Sequences:: Linux-specific restartable sequences ++ integration. + @end menu + + @node Default Thread Attributes +@@ -958,6 +960,85 @@ application-created thread because future versions of @theglibc{} may + create background threads after the first thread has been created, and + the application has no way of knowning that these threads are present. + ++@node Restartable Sequences ++@subsubsection Restartable Sequences ++ ++This section describes restartable sequences integration for ++@theglibc{}. This functionality is only available on Linux. ++ ++@deftp {Data Type} {struct rseq} ++@standards{Linux, sys/rseq.h} ++The type of the restartable sequences area. Future versions ++of Linux may add additional fields to the end of this structure. ++ ++ ++Users need to obtain the address of the restartable sequences area using ++the thread pointer and the @code{__rseq_offset} variable, described ++below. ++ ++One use of the restartable sequences area is to read the current CPU ++number from its @code{cpu_id} field, as an inline version of ++@code{sched_getcpu}. @Theglibc{} sets the @code{cpu_id} field to ++@code{RSEQ_CPU_ID_REGISTRATION_FAILED} if registration failed or was ++explicitly disabled. ++ ++Furthermore, users can store the address of a @code{struct rseq_cs} ++object into the @code{rseq_cs} field of @code{struct rseq}, thus ++informing the kernel that the thread enters a restartable sequence ++critical section. This pointer and the code areas it itself points to ++must not be left pointing to memory areas which are freed or re-used. ++Several approaches can guarantee this. If the application or library ++can guarantee that the memory used to hold the @code{struct rseq_cs} and ++the code areas it refers to are never freed or re-used, no special ++action must be taken. Else, before that memory is re-used of freed, the ++application is responsible for setting the @code{rseq_cs} field to ++@code{NULL} in each thread's restartable sequence area to guarantee that ++it does not leak dangling references. Because the application does not ++typically have knowledge of libraries' use of restartable sequences, it ++is recommended that libraries using restartable sequences which may end ++up freeing or re-using their memory set the @code{rseq_cs} field to ++@code{NULL} before returning from library functions which use ++restartable sequences. ++ ++The manual for the @code{rseq} system call can be found ++at @uref{https://git.kernel.org/pub/scm/libs/librseq/librseq.git/tree/doc/man/rseq.2}. ++@end deftp ++ ++@deftypevar {int} __rseq_offset ++@standards{Linux, sys/rseq.h} ++This variable contains the offset between the thread pointer (as defined ++by @code{__builtin_thread_pointer} or the thread pointer register for ++the architecture) and the restartable sequences area. This value is the ++same for all threads in the process. If the restartable sequences area ++is located at a lower address than the location to which the thread ++pointer points, the value is negative. ++@end deftypevar ++ ++@deftypevar {unsigned int} __rseq_size ++@standards{Linux, sys/rseq.h} ++This variable is either zero (if restartable sequence registration ++failed or has been disabled) or the size of the restartable sequence ++registration. This can be different from the size of @code{struct rseq} ++if the kernel has extended the size of the registration. If ++registration is successful, @code{__rseq_size} is at least 32 (the ++initial size of @code{struct rseq}). ++@end deftypevar ++ ++@deftypevar {unsigned int} __rseq_flags ++@standards{Linux, sys/rseq.h} ++The flags used during restartable sequence registration with the kernel. ++Currently zero. ++@end deftypevar ++ ++@deftypevr Macro int RSEQ_SIG ++@standards{Linux, sys/rseq.h} ++Each supported architecture provides a @code{RSEQ_SIG} macro in ++@file{sys/rseq.h} which contains a signature. That signature is ++expected to be present in the code before each restartable sequences ++abort handler. Failure to provide the expected signature may terminate ++the process with a segmentation fault. ++@end deftypevr ++ + @c FIXME these are undocumented: + @c pthread_atfork + @c pthread_attr_destroy +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index 23aa4cfc0b784dfc..0f5280a75d546d2f 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #define TUNABLE_NAMESPACE pthread + #include +@@ -43,6 +44,10 @@ rtld_mutex_dummy (pthread_mutex_t *lock) + } + #endif + ++const unsigned int __rseq_flags; ++const unsigned int __rseq_size attribute_relro; ++const int __rseq_offset attribute_relro; ++ + void + __tls_pre_init_tp (void) + { +@@ -100,7 +105,23 @@ __tls_init_tp (void) + #if HAVE_TUNABLES + do_rseq = TUNABLE_GET (rseq, int, NULL); + #endif +- rseq_register_current_thread (pd, do_rseq); ++ if (rseq_register_current_thread (pd, do_rseq)) ++ { ++ /* We need a writable view of the variables. They are in ++ .data.relro and are not yet write-protected. */ ++ extern unsigned int size __asm__ ("__rseq_size"); ++ size = sizeof (pd->rseq_area); ++ } ++ ++#ifdef RSEQ_SIG ++ /* This should be a compile-time constant, but the current ++ infrastructure makes it difficult to determine its value. Not ++ all targets support __thread_pointer, so set __rseq_offset only ++ if thre rseq registration may have happened because RSEQ_SIG is ++ defined. */ ++ extern int offset __asm__ ("__rseq_offset"); ++ offset = (char *) &pd->rseq_area - (char *) __thread_pointer (); ++#endif + } + + /* Set initial thread's stack block from 0 up to __libc_stack_end. +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 5c772f69d1b1f1f1..9b7e214219943531 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -110,7 +110,8 @@ sysdep_headers += sys/mount.h sys/acct.h \ + bits/types/struct_semid64_ds_helper.h \ + bits/types/struct_shmid64_ds.h \ + bits/types/struct_shmid64_ds_helper.h \ +- bits/pthread_stack_min.h bits/pthread_stack_min-dynamic.h ++ bits/pthread_stack_min.h bits/pthread_stack_min-dynamic.h \ ++ sys/rseq.h bits/rseq.h + + tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ + tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ +diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions +index 26452f3f17b5421d..3f8809a1581f27d0 100644 +--- a/sysdeps/unix/sysv/linux/Versions ++++ b/sysdeps/unix/sysv/linux/Versions +@@ -316,6 +316,11 @@ librt { + } + + ld { ++ GLIBC_2.35 { ++ __rseq_flags; ++ __rseq_offset; ++ __rseq_size; ++ } + GLIBC_PRIVATE { + __nptl_change_stack_perm; + } +diff --git a/sysdeps/unix/sysv/linux/aarch64/ld.abilist b/sysdeps/unix/sysv/linux/aarch64/ld.abilist +index b7196a80e2df8efc..bf4d4f9b6f2ddf97 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/aarch64/ld.abilist +@@ -4,3 +4,6 @@ GLIBC_2.17 __tls_get_addr F + GLIBC_2.17 _dl_mcount F + GLIBC_2.17 _r_debug D 0x28 + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/alpha/ld.abilist b/sysdeps/unix/sysv/linux/alpha/ld.abilist +index 13f7fc74af62941d..a23325a566419b41 100644 +--- a/sysdeps/unix/sysv/linux/alpha/ld.abilist ++++ b/sysdeps/unix/sysv/linux/alpha/ld.abilist +@@ -3,4 +3,7 @@ GLIBC_2.1 __libc_stack_end D 0x8 + GLIBC_2.1 _dl_mcount F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x8 +diff --git a/sysdeps/unix/sysv/linux/arc/ld.abilist b/sysdeps/unix/sysv/linux/arc/ld.abilist +index 7284383a6bea8e64..55f0c2ab9c6f7d91 100644 +--- a/sysdeps/unix/sysv/linux/arc/ld.abilist ++++ b/sysdeps/unix/sysv/linux/arc/ld.abilist +@@ -4,3 +4,6 @@ GLIBC_2.32 __tls_get_addr F + GLIBC_2.32 _dl_mcount F + GLIBC_2.32 _r_debug D 0x14 + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/arm/be/ld.abilist b/sysdeps/unix/sysv/linux/arm/be/ld.abilist +index 7987bbae1112aa3d..f1da2c636ddb359d 100644 +--- a/sysdeps/unix/sysv/linux/arm/be/ld.abilist ++++ b/sysdeps/unix/sysv/linux/arm/be/ld.abilist +@@ -1,4 +1,7 @@ + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __libc_stack_end D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 + GLIBC_2.4 __tls_get_addr F +diff --git a/sysdeps/unix/sysv/linux/arm/le/ld.abilist b/sysdeps/unix/sysv/linux/arm/le/ld.abilist +index 7987bbae1112aa3d..f1da2c636ddb359d 100644 +--- a/sysdeps/unix/sysv/linux/arm/le/ld.abilist ++++ b/sysdeps/unix/sysv/linux/arm/le/ld.abilist +@@ -1,4 +1,7 @@ + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __libc_stack_end D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 + GLIBC_2.4 __tls_get_addr F +diff --git a/sysdeps/unix/sysv/linux/csky/ld.abilist b/sysdeps/unix/sysv/linux/csky/ld.abilist +index 4939b20631dc6c54..7f482276ed8df1d5 100644 +--- a/sysdeps/unix/sysv/linux/csky/ld.abilist ++++ b/sysdeps/unix/sysv/linux/csky/ld.abilist +@@ -4,3 +4,6 @@ GLIBC_2.29 __tls_get_addr F + GLIBC_2.29 _dl_mcount F + GLIBC_2.29 _r_debug D 0x14 + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/hppa/ld.abilist b/sysdeps/unix/sysv/linux/hppa/ld.abilist +index 7cc9ebd792c2aadc..7f5527fb301b913c 100644 +--- a/sysdeps/unix/sysv/linux/hppa/ld.abilist ++++ b/sysdeps/unix/sysv/linux/hppa/ld.abilist +@@ -3,4 +3,7 @@ GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x14 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist +index e8d187b14d722a64..9c4a45d8dc525e52 100644 +--- a/sysdeps/unix/sysv/linux/i386/ld.abilist ++++ b/sysdeps/unix/sysv/linux/i386/ld.abilist +@@ -4,3 +4,6 @@ GLIBC_2.1 _dl_mcount F + GLIBC_2.3 ___tls_get_addr F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/ia64/ld.abilist b/sysdeps/unix/sysv/linux/ia64/ld.abilist +index be5122650ae2b327..8ccb5be911e0e9a2 100644 +--- a/sysdeps/unix/sysv/linux/ia64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/ia64/ld.abilist +@@ -3,3 +3,6 @@ GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x28 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist +index 7987bbae1112aa3d..f1da2c636ddb359d 100644 +--- a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist +@@ -1,4 +1,7 @@ + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __libc_stack_end D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 + GLIBC_2.4 __tls_get_addr F +diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist +index 4f2854edf7746958..dadbf852d0522e77 100644 +--- a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist +@@ -3,4 +3,7 @@ GLIBC_2.1 __libc_stack_end D 0x4 + GLIBC_2.1 _dl_mcount F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/microblaze/ld.abilist b/sysdeps/unix/sysv/linux/microblaze/ld.abilist +index 9f0fdeca38890a34..89a0b7e4fd5a95fa 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/ld.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/ld.abilist +@@ -4,3 +4,6 @@ GLIBC_2.18 __tls_get_addr F + GLIBC_2.18 _dl_mcount F + GLIBC_2.18 _r_debug D 0x14 + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist +index f750067d5c34bf42..e304d1bb464b28f4 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist +@@ -3,4 +3,7 @@ GLIBC_2.2 __libc_stack_end D 0x4 + GLIBC_2.2 _dl_mcount F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist +index f750067d5c34bf42..e304d1bb464b28f4 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist +@@ -3,4 +3,7 @@ GLIBC_2.2 __libc_stack_end D 0x4 + GLIBC_2.2 _dl_mcount F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist +index 2fba6a9b6ec92e47..37a47ebc0a0d16c8 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist +@@ -3,4 +3,7 @@ GLIBC_2.2 __libc_stack_end D 0x8 + GLIBC_2.2 _dl_mcount F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x8 +diff --git a/sysdeps/unix/sysv/linux/nios2/ld.abilist b/sysdeps/unix/sysv/linux/nios2/ld.abilist +index 57dfad5a53b739e8..811ae9da2fa85399 100644 +--- a/sysdeps/unix/sysv/linux/nios2/ld.abilist ++++ b/sysdeps/unix/sysv/linux/nios2/ld.abilist +@@ -4,3 +4,6 @@ GLIBC_2.21 __tls_get_addr F + GLIBC_2.21 _dl_mcount F + GLIBC_2.21 _r_debug D 0x14 + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist +index e89660739262c6ab..5a68aeb9eed33844 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist +@@ -5,3 +5,6 @@ GLIBC_2.22 __tls_get_addr_opt F + GLIBC_2.23 __parse_hwcap_and_convert_at_platform F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist +index ce0bc639597c4bd9..da24dc7fb52ad2d4 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist +@@ -5,3 +5,6 @@ GLIBC_2.3 __tls_get_addr F + GLIBC_2.3 _dl_mcount F + GLIBC_2.3 _r_debug D 0x28 + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist +index 65b22674d2462e96..b9ae89ae8d90ed9e 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist +@@ -5,3 +5,6 @@ GLIBC_2.17 _r_debug D 0x28 + GLIBC_2.22 __tls_get_addr_opt F + GLIBC_2.23 __parse_hwcap_and_convert_at_platform F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist +index 5ad4c81d12d7a612..068368878eb2406e 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist +@@ -4,3 +4,6 @@ GLIBC_2.33 __tls_get_addr F + GLIBC_2.33 _dl_mcount F + GLIBC_2.33 _r_debug D 0x14 + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist +index 479efdea9bb654bb..48431c91a9fd16b0 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist +@@ -4,3 +4,6 @@ GLIBC_2.27 __tls_get_addr F + GLIBC_2.27 _dl_mcount F + GLIBC_2.27 _r_debug D 0x28 + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index 6a3441f2cc49e7c4..9e8f99fd51a063b1 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -41,7 +41,7 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq) + return false; + } + #else /* RSEQ_SIG */ +-static inline void ++static inline bool + rseq_register_current_thread (struct pthread *self, bool do_rseq) + { + THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist +index d5ecb636bb792bdf..c15288394a232a8c 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist +@@ -3,3 +3,6 @@ GLIBC_2.1 __libc_stack_end D 0x4 + GLIBC_2.1 _dl_mcount F + GLIBC_2.3 __tls_get_offset F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist +index 62a5e1d99a2e6f42..117d1430a4c6272e 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist +@@ -3,3 +3,6 @@ GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x28 + GLIBC_2.3 __tls_get_offset F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/sh/be/ld.abilist b/sysdeps/unix/sysv/linux/sh/be/ld.abilist +index 7cc9ebd792c2aadc..7f5527fb301b913c 100644 +--- a/sysdeps/unix/sysv/linux/sh/be/ld.abilist ++++ b/sysdeps/unix/sysv/linux/sh/be/ld.abilist +@@ -3,4 +3,7 @@ GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x14 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/sh/le/ld.abilist b/sysdeps/unix/sysv/linux/sh/le/ld.abilist +index 7cc9ebd792c2aadc..7f5527fb301b913c 100644 +--- a/sysdeps/unix/sysv/linux/sh/le/ld.abilist ++++ b/sysdeps/unix/sysv/linux/sh/le/ld.abilist +@@ -3,4 +3,7 @@ GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x14 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist +index 2e6054349871e7d5..3aac73f3df646cb6 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist +@@ -3,3 +3,6 @@ GLIBC_2.1 __libc_stack_end D 0x4 + GLIBC_2.1 _dl_mcount F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist +index be5122650ae2b327..8ccb5be911e0e9a2 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist +@@ -3,3 +3,6 @@ GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x28 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h +index c8edff50d40e29b6..1215b5d086b8852b 100644 +--- a/sysdeps/unix/sysv/linux/sys/rseq.h ++++ b/sysdeps/unix/sysv/linux/sys/rseq.h +@@ -171,4 +171,14 @@ struct rseq + + #endif /* __GLIBC_HAVE_KERNEL_RSEQ */ + ++/* Offset from the thread pointer to the rseq area. */ ++extern const int __rseq_offset; ++ ++/* Size of the registered rseq area. 0 if the registration was ++ unsuccessful. */ ++extern const unsigned int __rseq_size; ++ ++/* Flags used during rseq registration. */ ++extern const unsigned int __rseq_flags; ++ + #endif /* sys/rseq.h */ +diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c +index 000e351872fc2f76..6d73f77e9621da42 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq-disable.c ++++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + + #ifdef RSEQ_SIG +@@ -30,6 +31,11 @@ static void + check_rseq_disabled (void) + { + struct pthread *pd = THREAD_SELF; ++ ++ TEST_COMPARE (__rseq_flags, 0); ++ TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset ++ == (char *) &pd->rseq_area); ++ TEST_COMPARE (__rseq_size, 0); + TEST_COMPARE ((int) pd->rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); + + int ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area), +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c +index 926376b6a5446ece..572c11166f8b6533 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq.c ++++ b/sysdeps/unix/sysv/linux/tst-rseq.c +@@ -29,12 +29,20 @@ + # include + # include + # include ++# include ++# include + # include "tst-rseq.h" + + static void + do_rseq_main_test (void) + { ++ struct pthread *pd = THREAD_SELF; ++ + TEST_VERIFY_EXIT (rseq_thread_registered ()); ++ TEST_COMPARE (__rseq_flags, 0); ++ TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset ++ == (char *) &pd->rseq_area); ++ TEST_COMPARE (__rseq_size, sizeof (pd->rseq_area)); + } + + static void +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist +index afddaec57c11f837..ae622bdf9710bdbd 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist +@@ -3,3 +3,6 @@ GLIBC_2.2.5 _dl_mcount F + GLIBC_2.2.5 _r_debug D 0x28 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist +index defc488d137c61c3..e17496d124b0c7b7 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist +@@ -3,3 +3,6 @@ GLIBC_2.16 __tls_get_addr F + GLIBC_2.16 _dl_mcount F + GLIBC_2.16 _r_debug D 0x14 + GLIBC_2.34 __rtld_version_placeholder F ++GLIBC_2.35 __rseq_flags D 0x4 ++GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_size D 0x4 diff --git a/SOURCES/glibc-rh2085529-2.patch b/SOURCES/glibc-rh2085529-2.patch new file mode 100644 index 0000000..2203635 --- /dev/null +++ b/SOURCES/glibc-rh2085529-2.patch @@ -0,0 +1,180 @@ +commit 6c33b018438ee799c29486f21d43d8100bdbd597 +Author: Florian Weimer +Date: Wed Feb 2 22:37:20 2022 +0100 + + Linux: Use ptrdiff_t for __rseq_offset + + This matches the data size initial-exec relocations use on most + targets. + + Reviewed-by: Mathieu Desnoyers + Reviewed-by: Carlos O'Donell + +diff --git a/manual/threads.texi b/manual/threads.texi +index 4869f69d2ceed255..48fd562923800b34 100644 +--- a/manual/threads.texi ++++ b/manual/threads.texi +@@ -1004,7 +1004,7 @@ The manual for the @code{rseq} system call can be found + at @uref{https://git.kernel.org/pub/scm/libs/librseq/librseq.git/tree/doc/man/rseq.2}. + @end deftp + +-@deftypevar {int} __rseq_offset ++@deftypevar {ptrdiff_t} __rseq_offset + @standards{Linux, sys/rseq.h} + This variable contains the offset between the thread pointer (as defined + by @code{__builtin_thread_pointer} or the thread pointer register for +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index 0f5280a75d546d2f..d5f2587f1348441c 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -46,7 +46,7 @@ rtld_mutex_dummy (pthread_mutex_t *lock) + + const unsigned int __rseq_flags; + const unsigned int __rseq_size attribute_relro; +-const int __rseq_offset attribute_relro; ++const ptrdiff_t __rseq_offset attribute_relro; + + void + __tls_pre_init_tp (void) +@@ -119,7 +119,7 @@ __tls_init_tp (void) + all targets support __thread_pointer, so set __rseq_offset only + if thre rseq registration may have happened because RSEQ_SIG is + defined. */ +- extern int offset __asm__ ("__rseq_offset"); ++ extern ptrdiff_t offset __asm__ ("__rseq_offset"); + offset = (char *) &pd->rseq_area - (char *) __thread_pointer (); + #endif + } +diff --git a/sysdeps/unix/sysv/linux/aarch64/ld.abilist b/sysdeps/unix/sysv/linux/aarch64/ld.abilist +index bf4d4f9b6f2ddf97..5151c0781de01bf1 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/aarch64/ld.abilist +@@ -5,5 +5,5 @@ GLIBC_2.17 _dl_mcount F + GLIBC_2.17 _r_debug D 0x28 + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/alpha/ld.abilist b/sysdeps/unix/sysv/linux/alpha/ld.abilist +index a23325a566419b41..3e296c547314f6c2 100644 +--- a/sysdeps/unix/sysv/linux/alpha/ld.abilist ++++ b/sysdeps/unix/sysv/linux/alpha/ld.abilist +@@ -4,6 +4,6 @@ GLIBC_2.1 _dl_mcount F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x8 +diff --git a/sysdeps/unix/sysv/linux/ia64/ld.abilist b/sysdeps/unix/sysv/linux/ia64/ld.abilist +index 8ccb5be911e0e9a2..5471b24d59a7527a 100644 +--- a/sysdeps/unix/sysv/linux/ia64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/ia64/ld.abilist +@@ -4,5 +4,5 @@ GLIBC_2.2 _r_debug D 0x28 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist +index 37a47ebc0a0d16c8..f26e594a139f0058 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist +@@ -4,6 +4,6 @@ GLIBC_2.2 _dl_mcount F + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x8 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist +index da24dc7fb52ad2d4..21f472e674299ab7 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist +@@ -6,5 +6,5 @@ GLIBC_2.3 _dl_mcount F + GLIBC_2.3 _r_debug D 0x28 + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist +index b9ae89ae8d90ed9e..9c9c40450d651880 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist +@@ -6,5 +6,5 @@ GLIBC_2.22 __tls_get_addr_opt F + GLIBC_2.23 __parse_hwcap_and_convert_at_platform F + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist +index 48431c91a9fd16b0..a7758a0e52fc8cc8 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist +@@ -5,5 +5,5 @@ GLIBC_2.27 _dl_mcount F + GLIBC_2.27 _r_debug D 0x28 + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist +index 117d1430a4c6272e..78d071600b1f3431 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist +@@ -4,5 +4,5 @@ GLIBC_2.2 _r_debug D 0x28 + GLIBC_2.3 __tls_get_offset F + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist +index 8ccb5be911e0e9a2..5471b24d59a7527a 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist +@@ -4,5 +4,5 @@ GLIBC_2.2 _r_debug D 0x28 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 +diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h +index 1215b5d086b8852b..791ed83176b61fe4 100644 +--- a/sysdeps/unix/sysv/linux/sys/rseq.h ++++ b/sysdeps/unix/sysv/linux/sys/rseq.h +@@ -21,6 +21,7 @@ + /* Architecture-specific rseq signature. */ + #include + ++#include + #include + #include + #include +@@ -172,7 +173,7 @@ struct rseq + #endif /* __GLIBC_HAVE_KERNEL_RSEQ */ + + /* Offset from the thread pointer to the rseq area. */ +-extern const int __rseq_offset; ++extern const ptrdiff_t __rseq_offset; + + /* Size of the registered rseq area. 0 if the registration was + unsuccessful. */ +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist +index ae622bdf9710bdbd..5a8bd322cdc95d5b 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist +@@ -4,5 +4,5 @@ GLIBC_2.2.5 _r_debug D 0x28 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.35 __rseq_flags D 0x4 +-GLIBC_2.35 __rseq_offset D 0x4 ++GLIBC_2.35 __rseq_offset D 0x8 + GLIBC_2.35 __rseq_size D 0x4 diff --git a/SOURCES/glibc-rh2085529-3.patch b/SOURCES/glibc-rh2085529-3.patch new file mode 100644 index 0000000..496a5d3 --- /dev/null +++ b/SOURCES/glibc-rh2085529-3.patch @@ -0,0 +1,59 @@ +commit 4b527650e0d559a5f693275c598667e06cd6455c +Author: Florian Weimer +Date: Thu Jun 2 16:29:55 2022 +0200 + + Linux: Adjust struct rseq definition to current kernel version + + This definition is only used as a fallback with old kernel headers. + The change follows kernel commit bfdf4e6208051ed7165b2e92035b4bf11 + ("rseq: Remove broken uapi field layout on 32-bit little endian"). + + Reviewed-by: Carlos O'Donell + +diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h +index 791ed83176b61fe4..56550329db962cc8 100644 +--- a/sysdeps/unix/sysv/linux/sys/rseq.h ++++ b/sysdeps/unix/sysv/linux/sys/rseq.h +@@ -24,7 +24,6 @@ + #include + #include + #include +-#include + + #ifdef __has_include + # if __has_include ("linux/rseq.h") +@@ -129,28 +128,13 @@ struct rseq + targeted by the rseq_cs. Also needs to be set to NULL by user-space + before reclaiming memory that contains the targeted struct rseq_cs. + +- Read and set by the kernel. Set by user-space with single-copy +- atomicity semantics. This field should only be updated by the +- thread which registered this data structure. Aligned on 64-bit. */ +- union +- { +- uint64_t ptr64; +-# ifdef __LP64__ +- uint64_t ptr; +-# else /* __LP64__ */ +- struct +- { +-#if __BYTE_ORDER == __BIG_ENDIAN +- uint32_t padding; /* Initialized to zero. */ +- uint32_t ptr32; +-# else /* LITTLE */ +- uint32_t ptr32; +- uint32_t padding; /* Initialized to zero. */ +-# endif /* ENDIAN */ +- } ptr; +-# endif /* __LP64__ */ +- } rseq_cs; ++ Read and set by the kernel. Set by user-space with single-copy ++ atomicity semantics. This field should only be updated by the ++ thread which registered this data structure. Aligned on 64-bit. + ++ 32-bit architectures should update the low order bits of the ++ rseq_cs field, leaving the high order bits initialized to 0. */ ++ uint64_t rseq_cs; + /* Restartable sequences flags field. + + This field should only be updated by the thread which diff --git a/SOURCES/glibc-rh2085529-4.patch b/SOURCES/glibc-rh2085529-4.patch new file mode 100644 index 0000000..54c97e9 --- /dev/null +++ b/SOURCES/glibc-rh2085529-4.patch @@ -0,0 +1,38 @@ +Revert glibc-rh2024347-13.patch. Enable rseq by default. + +diff --git a/manual/tunables.texi b/manual/tunables.texi +index f559c44dcec4624b..28ff502990c2a10f 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -425,13 +425,11 @@ The value is measured in bytes. The default is @samp{41943040} + @end deftp + + @deftp Tunable glibc.pthread.rseq +-The @code{glibc.pthread.rseq} tunable can be set to @samp{1}, to enable +-restartable sequences support. @Theglibc{} uses this to optimize the +-@code{sched_getcpu} function. +- +-The default is @samp{0}, which means that applications can perform +-restartable sequences registration, but @code{sched_getcpu} is not +-accelerated. ++The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable ++restartable sequences support in @theglibc{}. This enables applications ++to perform direct restartable sequence registration with the kernel. ++The default is @samp{1}, which means that @theglibc{} performs ++registration on behalf of the application. + + Restartable sequences are a Linux-specific extension. + @end deftp +diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list +index df2a39ce01858d3b..d24f4be0d08ba407 100644 +--- a/sysdeps/nptl/dl-tunables.list ++++ b/sysdeps/nptl/dl-tunables.list +@@ -31,7 +31,7 @@ glibc { + type: INT_32 + minval: 0 + maxval: 1 +- default: 0 ++ default: 1 + } + } + } diff --git a/SOURCES/glibc-rh2096191-1.patch b/SOURCES/glibc-rh2096191-1.patch new file mode 100644 index 0000000..b1341ef --- /dev/null +++ b/SOURCES/glibc-rh2096191-1.patch @@ -0,0 +1,67 @@ +commit 62a321b12d0e397af88fa422db65079332f971dc +Author: Florian Weimer +Date: Fri Jun 24 18:16:41 2022 +0200 + + support: Change non-address output format of support_format_dns_packet + + It makes sense to include the owner name (LHS) and record type in the + output, so that they can be checked for correctness. + + Reviewed-by: Carlos O'Donell + +diff --git a/support/support_format_dns_packet.c b/support/support_format_dns_packet.c +index 1f8e9ca172a06f4f..c3dff0e019801904 100644 +--- a/support/support_format_dns_packet.c ++++ b/support/support_format_dns_packet.c +@@ -101,6 +101,17 @@ extract_name (struct in_buffer full, struct in_buffer *in, struct dname *value) + return true; + } + ++static void ++extract_name_data (struct in_buffer full, struct in_buffer *rdata, ++ const struct dname *owner, const char *typename, FILE *out) ++{ ++ struct dname name; ++ if (extract_name (full, rdata, &name)) ++ fprintf (out, "data: %s %s %s\n", owner->name, typename, name.name); ++ else ++ fprintf (out, "error: malformed CNAME/PTR record\n"); ++} ++ + char * + support_format_dns_packet (const unsigned char *buffer, size_t length) + { +@@ -206,14 +217,11 @@ support_format_dns_packet (const unsigned char *buffer, size_t length) + } + break; + case T_CNAME: ++ extract_name_data (full, &rdata, &rname, "CNAME", mem.out); ++ break; + case T_PTR: +- { +- struct dname name; +- if (extract_name (full, &rdata, &name)) +- fprintf (mem.out, "name: %s\n", name.name); +- else +- fprintf (mem.out, "error: malformed CNAME/PTR record\n"); +- } ++ extract_name_data (full, &rdata, &rname, "PTR", mem.out); ++ break; + } + } + +diff --git a/support/tst-support_format_dns_packet.c b/support/tst-support_format_dns_packet.c +index 03ff59457e3bdde8..5596db1785009557 100644 +--- a/support/tst-support_format_dns_packet.c ++++ b/support/tst-support_format_dns_packet.c +@@ -85,8 +85,8 @@ test_multiple_cnames (void) + "\xc0\x00\x02\x01"; + check_packet (packet, sizeof (packet) - 1, __func__, + "name: www.example\n" +- "name: www1.example\n" +- "name: www2.example\n" ++ "data: www.example CNAME www1.example\n" ++ "data: www1.example CNAME www2.example\n" + "address: 192.0.2.1\n"); + } + diff --git a/SOURCES/glibc-rh2096191-2.patch b/SOURCES/glibc-rh2096191-2.patch new file mode 100644 index 0000000..1cbd0a4 --- /dev/null +++ b/SOURCES/glibc-rh2096191-2.patch @@ -0,0 +1,941 @@ +commit f282cdbe7f436c75864e5640a409a10485e9abb2 +Author: Florian Weimer +Date: Fri Jun 24 18:16:41 2022 +0200 + + resolv: Implement no-aaaa stub resolver option + + Reviewed-by: Carlos O'Donell + +diff --git a/resolv/Makefile b/resolv/Makefile +index 59e599535c7aa6eb..e8269dcb5bcf216b 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -51,6 +51,7 @@ routines := \ + nss_dns_functions \ + res-close \ + res-name-checking \ ++ res-noaaaa \ + res-state \ + res_context_hostalias \ + res_enable_icmp \ +@@ -93,6 +94,7 @@ tests += \ + tst-resolv-binary \ + tst-resolv-edns \ + tst-resolv-network \ ++ tst-resolv-noaaaa \ + tst-resolv-nondecimal \ + tst-resolv-res_init-multi \ + tst-resolv-search \ +@@ -256,6 +258,7 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \ + $(shared-thread-library) + $(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \ + $(shared-thread-library) ++$(objpfx)tst-resolv-noaaaa: $(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) +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 7248ade18db5ba47..6e83fca1c5b1f98c 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -125,6 +125,14 @@ static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1, + char *buffer, size_t buflen, + int *errnop, int *h_errnop, + int32_t *ttlp); ++static enum nss_status gaih_getanswer_noaaaa (const querybuf *answer1, ++ int anslen1, ++ const char *qname, ++ struct gaih_addrtuple **pat, ++ char *buffer, size_t buflen, ++ int *errnop, int *h_errnop, ++ int32_t *ttlp); ++ + + static enum nss_status gethostbyname3_context (struct resolv_context *ctx, + const char *name, int af, +@@ -370,17 +378,31 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + int resplen2 = 0; + int ans2p_malloced = 0; + ++ + int olderr = errno; +- int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA, ++ int n; ++ ++ if ((ctx->resp->options & RES_NOAAAA) == 0) ++ { ++ 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); +- if (n >= 0) +- { +- status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p, +- resplen2, name, pat, buffer, buflen, +- errnop, herrnop, ttlp); ++ if (n >= 0) ++ status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p, ++ resplen2, name, pat, buffer, buflen, ++ errnop, herrnop, ttlp); + } + else ++ { ++ n = __res_context_search (ctx, name, C_IN, T_A, ++ host_buffer.buf->buf, 2048, NULL, ++ NULL, NULL, NULL, NULL); ++ if (n >= 0) ++ status = gaih_getanswer_noaaaa (host_buffer.buf, n, ++ name, pat, buffer, buflen, ++ errnop, herrnop, ttlp); ++ } ++ if (n < 0) + { + switch (errno) + { +@@ -1388,3 +1410,21 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, + + return status; + } ++ ++/* Variant of gaih_getanswer without a second (AAAA) response. */ ++static enum nss_status ++gaih_getanswer_noaaaa (const querybuf *answer1, int anslen1, const char *qname, ++ struct gaih_addrtuple **pat, ++ char *buffer, size_t buflen, ++ int *errnop, int *h_errnop, int32_t *ttlp) ++{ ++ int first = 1; ++ ++ enum nss_status status = NSS_STATUS_NOTFOUND; ++ if (anslen1 > 0) ++ status = gaih_getanswer_slice (answer1, anslen1, qname, ++ &pat, &buffer, &buflen, ++ errnop, h_errnop, ttlp, ++ &first); ++ return status; ++} +diff --git a/resolv/res-noaaaa.c b/resolv/res-noaaaa.c +new file mode 100644 +index 0000000000000000..4ba197664a86aed7 +--- /dev/null ++++ b/resolv/res-noaaaa.c +@@ -0,0 +1,143 @@ ++/* Implement suppression of AAAA queries. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Returns true if the question type at P matches EXPECTED, and the ++ class is IN. */ ++static bool ++qtype_matches (const unsigned char *p, int expected) ++{ ++ /* This assumes that T_A/C_IN constants are less than 256, which ++ they are. */ ++ return p[0] == 0 && p[1] == expected && p[2] == 0 && p[3] == C_IN; ++} ++ ++/* Handle RES_NOAAAA translation of AAAA queries. To produce a Name ++ Error (NXDOMAIN) repsonse for domain names that do not exist, it is ++ still necessary to send a query. Using question type A is a ++ conservative choice. In the returned answer, it is necessary to ++ switch back the question type to AAAA. */ ++bool ++__res_handle_no_aaaa (struct resolv_context *ctx, ++ const unsigned char *buf, int buflen, ++ unsigned char *ans, int anssiz, int *result) ++{ ++ /* AAAA mode is not active, or the query looks invalid (will not be ++ able to be parsed). */ ++ if ((ctx->resp->options & RES_NOAAAA) == 0 ++ || buflen <= sizeof (HEADER)) ++ return false; ++ ++ /* The replacement A query is produced here. */ ++ struct ++ { ++ HEADER header; ++ unsigned char question[NS_MAXCDNAME + 4]; ++ } replacement; ++ memcpy (&replacement.header, buf, sizeof (replacement.header)); ++ ++ if (replacement.header.qr ++ || replacement.header.opcode != 0 ++ || replacement.header.rcode != 0 ++ || ntohs (replacement.header.qdcount) != 1 ++ || ntohs (replacement.header.ancount) != 0 ++ || ntohs (replacement.header.nscount) != 0) ++ /* Not a well-formed question. Let the core resolver code produce ++ the proper error. */ ++ return false; ++ ++ /* Disable EDNS0. */ ++ replacement.header.arcount = htons (0); ++ ++ /* Extract the QNAME. */ ++ int ret = __ns_name_unpack (buf, buf + buflen, buf + sizeof (HEADER), ++ replacement.question, NS_MAXCDNAME); ++ if (ret < 0) ++ /* Format error. */ ++ return false; ++ ++ /* Compute the end of the question name. */ ++ const unsigned char *after_question = buf + sizeof (HEADER) + ret; ++ ++ /* Check that we are dealing with an AAAA query. */ ++ if (buf + buflen - after_question < 4 ++ || !qtype_matches (after_question, T_AAAA)) ++ return false; ++ ++ /* Find the place to store the type/class data in the replacement ++ query. */ ++ after_question = replacement.question; ++ /* This cannot fail because __ns_name_unpack above produced a valid ++ domain name. */ ++ (void) __ns_name_skip (&after_question, &replacement.question[NS_MAXCDNAME]); ++ unsigned char *start_of_query = (unsigned char *) &replacement; ++ const unsigned char *end_of_query = after_question + 4; ++ ++ /* Produce an A/IN query. */ ++ { ++ unsigned char *p = (unsigned char *) after_question; ++ p[0] = 0; ++ p[1] = T_A; ++ p[2] = 0; ++ p[3] = C_IN; ++ } ++ ++ /* Clear the output buffer, to avoid reading undefined data when ++ rewriting the result from A to AAAA. */ ++ memset (ans, 0, anssiz); ++ ++ /* Always perform the message translation, independent of the error ++ code. */ ++ ret = __res_context_send (ctx, ++ start_of_query, end_of_query - start_of_query, ++ NULL, 0, ans, anssiz, ++ NULL, NULL, NULL, NULL, NULL); ++ ++ /* Patch in the AAAA question type if there is room and the A query ++ type was received. */ ++ after_question = ans + sizeof (HEADER); ++ if (__ns_name_skip (&after_question, ans + anssiz) == 0 ++ && ans + anssiz - after_question >= 4 ++ && qtype_matches (after_question, T_A)) ++ { ++ ((unsigned char *) after_question)[1] = T_AAAA; ++ ++ /* Create an aligned copy of the header. Hide all data except ++ the question from the response. Put back the header. There is ++ no need to change the response code. The zero answer count turns ++ a positive response with data into a no-data response. */ ++ memcpy (&replacement.header, ans, sizeof (replacement.header)); ++ replacement.header.ancount = htons (0); ++ replacement.header.nscount = htons (0); ++ replacement.header.arcount = htons (0); ++ memcpy (ans, &replacement.header, sizeof (replacement.header)); ++ ++ /* Truncate the reply. */ ++ if (ret <= 0) ++ *result = ret; ++ else ++ *result = after_question - ans + 4; ++ } ++ ++ return true; ++} +diff --git a/resolv/res_debug.c b/resolv/res_debug.c +index 030df0aa90c9f34f..b0fe69b1aa5186a0 100644 +--- a/resolv/res_debug.c ++++ b/resolv/res_debug.c +@@ -613,6 +613,7 @@ p_option(u_long option) { + case RES_NOTLDQUERY: return "no-tld-query"; + case RES_NORELOAD: return "no-reload"; + case RES_TRUSTAD: return "trust-ad"; ++ case RES_NOAAAA: return "no-aaaa"; + /* XXX nonreentrant */ + default: sprintf(nbuf, "?0x%lx?", (u_long)option); + return (nbuf); +diff --git a/resolv/res_init.c b/resolv/res_init.c +index 6b2936eda9618ac9..8bde915903565f60 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -695,6 +695,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options) + { STRnLEN ("no-reload"), 0, RES_NORELOAD }, + { STRnLEN ("use-vc"), 0, RES_USEVC }, + { STRnLEN ("trust-ad"), 0, RES_TRUSTAD }, ++ { STRnLEN ("no-aaaa"), 0, RES_NOAAAA }, + }; + #define noptions (sizeof (options) / sizeof (options[0])) + for (int i = 0; i < noptions; ++i) +diff --git a/resolv/res_query.c b/resolv/res_query.c +index 75b0e5f2f7b51eb2..2f3c28cfc8c0d832 100644 +--- a/resolv/res_query.c ++++ b/resolv/res_query.c +@@ -204,10 +204,26 @@ __res_context_query (struct resolv_context *ctx, const char *name, + free (buf); + return (n); + } +- assert (answerp == NULL || (void *) *answerp == (void *) answer); +- n = __res_context_send (ctx, query1, nquery1, query2, nquery2, answer, +- anslen, answerp, answerp2, nanswerp2, resplen2, +- answerp2_malloced); ++ ++ /* Suppress AAAA lookups if required. __res_handle_no_aaaa ++ checks RES_NOAAAA first, so avoids parsing the ++ just-generated query packet in most cases. nss_dns avoids ++ using T_QUERY_A_AND_AAAA in RES_NOAAAA mode, so there is no ++ need to handle it here. */ ++ if (type == T_AAAA && __res_handle_no_aaaa (ctx, query1, nquery1, ++ answer, anslen, &n)) ++ /* There must be no second query for AAAA queries. The code ++ below is still needed to translate NODATA responses. */ ++ assert (query2 == NULL); ++ else ++ { ++ assert (answerp == NULL || (void *) *answerp == (void *) answer); ++ n = __res_context_send (ctx, query1, nquery1, query2, nquery2, ++ answer, anslen, ++ answerp, answerp2, nanswerp2, resplen2, ++ answerp2_malloced); ++ } ++ + if (use_malloc) + free (buf); + if (n < 0) { +diff --git a/resolv/res_send.c b/resolv/res_send.c +index 9f86f5fe47194887..8ac6a307b40fa2ca 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -438,8 +438,13 @@ context_send_common (struct resolv_context *ctx, + RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); + return -1; + } +- int result = __res_context_send (ctx, buf, buflen, NULL, 0, ans, anssiz, +- NULL, NULL, NULL, NULL, NULL); ++ ++ int result; ++ if (__res_handle_no_aaaa (ctx, buf, buflen, ans, anssiz, &result)) ++ return result; ++ ++ result = __res_context_send (ctx, buf, buflen, NULL, 0, ans, anssiz, ++ NULL, NULL, NULL, NULL, NULL); + __resolv_context_put (ctx); + return result; + } +diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h +index 216e47ed42076b72..8ab02fc9e648d30f 100644 +--- a/resolv/resolv-internal.h ++++ b/resolv/resolv-internal.h +@@ -78,6 +78,14 @@ int __res_context_send (struct resolv_context *, const unsigned char *, int, + int *, int *, int *); + libc_hidden_proto (__res_context_send) + ++/* Return true if the query has been handled in RES_NOAAAA mode. For ++ that, RES_NOAAAA must be active, and the question type must be AAAA. ++ The caller is expected to return *RESULT as the return value. */ ++bool __res_handle_no_aaaa (struct resolv_context *ctx, ++ const unsigned char *buf, int buflen, ++ unsigned char *ans, int anssiz, int *result) ++ attribute_hidden; ++ + /* Internal function similar to res_hostalias. */ + const char *__res_context_hostalias (struct resolv_context *, + const char *, char *, size_t); +diff --git a/resolv/resolv.h b/resolv/resolv.h +index e7c8d44645912ddf..3a79ffea57a6916f 100644 +--- a/resolv/resolv.h ++++ b/resolv/resolv.h +@@ -132,6 +132,7 @@ struct res_sym { + as a TLD. */ + #define RES_NORELOAD 0x02000000 /* No automatic configuration reload. */ + #define RES_TRUSTAD 0x04000000 /* Request AD bit, keep it in responses. */ ++#define RES_NOAAAA 0x08000000 /* Suppress AAAA queries. */ + + #define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH) + +diff --git a/resolv/tst-resolv-noaaaa.c b/resolv/tst-resolv-noaaaa.c +new file mode 100644 +index 0000000000000000..56b25f88a58ad286 +--- /dev/null ++++ b/resolv/tst-resolv-noaaaa.c +@@ -0,0 +1,533 @@ ++/* Test the RES_NOAAAA resolver option. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Used to keep track of the number of queries. */ ++static volatile unsigned int queries; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ /* Each test should only send one query. */ ++ ++queries; ++ TEST_COMPARE (queries, 1); ++ ++ /* AAAA queries are supposed to be disabled. */ ++ TEST_VERIFY (qtype != T_AAAA); ++ TEST_COMPARE (qclass, C_IN); ++ ++ /* The only other query type besides A is PTR. */ ++ if (qtype != T_A) ++ TEST_COMPARE (qtype, T_PTR); ++ ++ int an, ns, ar; ++ char *tail; ++ if (sscanf (qname, "an%d.ns%d.ar%d.%ms", &an, &ns, &ar, &tail) != 4) ++ FAIL_EXIT1 ("invalid QNAME: %s\n", qname); ++ TEST_COMPARE_STRING (tail, "example"); ++ free (tail); ++ ++ if (an < 0 || ns < 0 || ar < 0) ++ { ++ struct resolv_response_flags flags = { .rcode = NXDOMAIN, }; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ return; ++ } ++ ++ struct resolv_response_flags flags = {}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ ++ resolv_response_section (b, ns_s_an); ++ for (int i = 0; i < an; ++i) ++ { ++ resolv_response_open_record (b, qname, qclass, qtype, 60); ++ switch (qtype) ++ { ++ case T_A: ++ char ipv4[4] = {192, 0, 2, i + 1}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ break; ++ ++ case T_PTR: ++ char *name = xasprintf ("ptr-%d", i); ++ resolv_response_add_name (b, name); ++ free (name); ++ break; ++ } ++ resolv_response_close_record (b); ++ } ++ ++ resolv_response_section (b, ns_s_ns); ++ for (int i = 0; i < ns; ++i) ++ { ++ resolv_response_open_record (b, qname, qclass, T_NS, 60); ++ char *name = xasprintf ("ns%d.example.net", i); ++ resolv_response_add_name (b, name); ++ free (name); ++ resolv_response_close_record (b); ++ } ++ ++ resolv_response_section (b, ns_s_ar); ++ int addr = 1; ++ for (int i = 0; i < ns; ++i) ++ { ++ char *name = xasprintf ("ns%d.example.net", i); ++ for (int j = 0; j < ar; ++j) ++ { ++ resolv_response_open_record (b, name, qclass, T_A, 60); ++ char ipv4[4] = {192, 0, 2, addr}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ resolv_response_close_record (b); ++ ++ resolv_response_open_record (b, name, qclass, T_AAAA, 60); ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, addr}; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ resolv_response_close_record (b); ++ ++ ++addr; ++ } ++ free (name); ++ } ++} ++ ++/* Number of modes. Lowest bit encodes *n* function vs implicit _res ++ argument. The mode numbers themselves are arbitrary. */ ++enum { mode_count = 8 }; ++ ++/* res_send-like modes do not perform error translation. */ ++enum { first_send_mode = 6 }; ++ ++static int ++libresolv_query (unsigned int mode, const char *qname, uint16_t qtype, ++ unsigned char *buf, size_t buflen) ++{ ++ int saved_errno = errno; ++ ++ TEST_VERIFY_EXIT (mode < mode_count); ++ ++ switch (mode) ++ { ++ case 0: ++ return res_query (qname, C_IN, qtype, buf, buflen); ++ case 1: ++ return res_nquery (&_res, qname, C_IN, qtype, buf, buflen); ++ case 2: ++ return res_search (qname, C_IN, qtype, buf, buflen); ++ case 3: ++ return res_nsearch (&_res, qname, C_IN, qtype, buf, buflen); ++ case 4: ++ return res_querydomain (qname, "", C_IN, qtype, buf, buflen); ++ case 5: ++ return res_nquerydomain (&_res, qname, "", C_IN, qtype, buf, buflen); ++ case 6: ++ { ++ unsigned char querybuf[512]; ++ int ret = res_mkquery (QUERY, qname, C_IN, qtype, ++ NULL, 0, NULL, querybuf, sizeof (querybuf)); ++ TEST_VERIFY_EXIT (ret > 0); ++ errno = saved_errno; ++ return res_send (querybuf, ret, buf, buflen); ++ } ++ case 7: ++ { ++ unsigned char querybuf[512]; ++ int ret = res_nmkquery (&_res, QUERY, qname, C_IN, qtype, ++ NULL, 0, NULL, querybuf, sizeof (querybuf)); ++ TEST_VERIFY_EXIT (ret > 0); ++ errno = saved_errno; ++ return res_nsend (&_res, querybuf, ret, buf, buflen); ++ } ++ } ++ __builtin_unreachable (); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response ++ }); ++ ++ _res.options |= RES_NOAAAA; ++ ++ check_hostent ("an1.ns2.ar1.example", ++ gethostbyname ("an1.ns2.ar1.example"), ++ "name: an1.ns2.ar1.example\n" ++ "address: 192.0.2.1\n"); ++ queries = 0; ++ check_hostent ("an0.ns2.ar1.example", ++ gethostbyname ("an0.ns2.ar1.example"), ++ "error: NO_ADDRESS\n"); ++ queries = 0; ++ check_hostent ("an-1.ns2.ar1.example", ++ gethostbyname ("an-1.ns2.ar1.example"), ++ "error: HOST_NOT_FOUND\n"); ++ queries = 0; ++ ++ check_hostent ("an1.ns2.ar1.example AF_INET", ++ gethostbyname2 ("an1.ns2.ar1.example", AF_INET), ++ "name: an1.ns2.ar1.example\n" ++ "address: 192.0.2.1\n"); ++ queries = 0; ++ check_hostent ("an0.ns2.ar1.example AF_INET", ++ gethostbyname2 ("an0.ns2.ar1.example", AF_INET), ++ "error: NO_ADDRESS\n"); ++ queries = 0; ++ check_hostent ("an-1.ns2.ar1.example AF_INET", ++ gethostbyname2 ("an-1.ns2.ar1.example", AF_INET), ++ "error: HOST_NOT_FOUND\n"); ++ queries = 0; ++ ++ check_hostent ("an1.ns2.ar1.example AF_INET6", ++ gethostbyname2 ("an1.ns2.ar1.example", AF_INET6), ++ "error: NO_ADDRESS\n"); ++ queries = 0; ++ check_hostent ("an0.ns2.ar1.example AF_INET6", ++ gethostbyname2 ("an0.ns2.ar1.example", AF_INET6), ++ "error: NO_ADDRESS\n"); ++ queries = 0; ++ check_hostent ("an-1.ns2.ar1.example AF_INET6", ++ gethostbyname2 ("an-1.ns2.ar1.example", AF_INET6), ++ "error: HOST_NOT_FOUND\n"); ++ queries = 0; ++ ++ /* Multiple addresses. */ ++ check_hostent ("an2.ns0.ar0.example", ++ gethostbyname ("an2.ns0.ar0.example"), ++ "name: an2.ns0.ar0.example\n" ++ "address: 192.0.2.1\n" ++ "address: 192.0.2.2\n"); ++ queries = 0; ++ check_hostent ("an2.ns0.ar0.example AF_INET6", ++ gethostbyname2 ("an2.ns0.ar0.example", AF_INET6), ++ "error: NO_ADDRESS\n"); ++ queries = 0; ++ ++ /* getaddrinfo checks with one address. */ ++ struct addrinfo *ai; ++ int ret; ++ ret = getaddrinfo ("an1.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_INET, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an1.ns2.ar1.example (AF_INET)", ai, ret, ++ "address: STREAM/TCP 192.0.2.1 80\n"); ++ freeaddrinfo (ai); ++ queries = 0; ++ ret = getaddrinfo ("an1.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_INET6, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an1.ns2.ar1.example (AF_INET6)", ai, ret, ++ "error: No address associated with hostname\n"); ++ queries = 0; ++ ret = getaddrinfo ("an1.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an1.ns2.ar1.example (AF_UNSPEC)", ai, ret, ++ "address: STREAM/TCP 192.0.2.1 80\n"); ++ freeaddrinfo (ai); ++ queries = 0; ++ ++ /* getaddrinfo checks with three addresses. */ ++ ret = getaddrinfo ("an3.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_INET, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an3.ns2.ar1.example (AF_INET)", ai, ret, ++ "address: STREAM/TCP 192.0.2.1 80\n" ++ "address: STREAM/TCP 192.0.2.2 80\n" ++ "address: STREAM/TCP 192.0.2.3 80\n"); ++ freeaddrinfo (ai); ++ queries = 0; ++ ret = getaddrinfo ("an3.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_INET6, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an3.ns2.ar1.example (AF_INET6)", ai, ret, ++ "error: No address associated with hostname\n"); ++ queries = 0; ++ ret = getaddrinfo ("an3.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an3.ns2.ar1.example (AF_UNSPEC)", ai, ret, ++ "address: STREAM/TCP 192.0.2.1 80\n" ++ "address: STREAM/TCP 192.0.2.2 80\n" ++ "address: STREAM/TCP 192.0.2.3 80\n"); ++ freeaddrinfo (ai); ++ queries = 0; ++ ++ /* getaddrinfo checks with no address. */ ++ ret = getaddrinfo ("an0.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_INET, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an0.ns2.ar1.example (AF_INET)", ai, ret, ++ "error: No address associated with hostname\n"); ++ queries = 0; ++ ret = getaddrinfo ("an0.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_INET6, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an0.ns2.ar1.example (AF_INET6)", ai, ret, ++ "error: No address associated with hostname\n"); ++ queries = 0; ++ ret = getaddrinfo ("an0.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an-1.ns2.ar1.example (AF_UNSPEC)", ai, ret, ++ "error: No address associated with hostname\n"); ++ queries = 0; ++ ++ /* getaddrinfo checks with NXDOMAIN. */ ++ ret = getaddrinfo ("an-1.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_INET, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an-1.ns2.ar1.example (AF_INET)", ai, ret, ++ "error: Name or service not known\n"); ++ queries = 0; ++ ret = getaddrinfo ("an-1.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_INET6, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an-1.ns2.ar1.example (AF_INET6)", ai, ret, ++ "error: Name or service not known\n"); ++ queries = 0; ++ ret = getaddrinfo ("an-1.ns2.ar1.example", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ check_addrinfo ("an-1.ns2.ar1.example (AF_UNSPEC)", ai, ret, ++ "error: Name or service not known\n"); ++ queries = 0; ++ ++ for (unsigned int mode = 0; mode < mode_count; ++mode) ++ { ++ unsigned char *buf; ++ int ret; ++ ++ /* Response for A. */ ++ buf = malloc (512); ++ ret = libresolv_query (mode, "an1.ns2.ar1.example", T_A, buf, 512); ++ TEST_VERIFY_EXIT (ret > 0); ++ check_dns_packet ("an1.ns2.ar1.example A", buf, ret, ++ "name: an1.ns2.ar1.example\n" ++ "address: 192.0.2.1\n"); ++ free (buf); ++ queries = 0; ++ ++ /* NODATA response for A. */ ++ buf = malloc (512); ++ errno = 0; ++ ret = libresolv_query (mode, "an0.ns2.ar1.example", T_A, buf, 512); ++ if (mode < first_send_mode) ++ { ++ TEST_COMPARE (ret, -1); ++ TEST_COMPARE (errno, 0); ++ TEST_COMPARE (h_errno, NO_ADDRESS); ++ } ++ else ++ { ++ TEST_VERIFY_EXIT (ret > 0); ++ TEST_COMPARE (((HEADER *)buf)->rcode, 0); ++ check_dns_packet ("an1.ns2.ar1.example A", buf, ret, ++ "name: an0.ns2.ar1.example\n"); ++ } ++ free (buf); ++ queries = 0; ++ ++ /* NXDOMAIN response for A. */ ++ buf = malloc (512); ++ errno = 0; ++ ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_A, buf, 512); ++ if (mode < first_send_mode) ++ { ++ TEST_COMPARE (ret, -1); ++ TEST_COMPARE (errno, 0); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ } ++ else ++ { ++ TEST_VERIFY_EXIT (ret > 0); ++ TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN); ++ check_dns_packet ("an1.ns2.ar1.example A", buf, ret, ++ "name: an-1.ns2.ar1.example\n"); ++ } ++ free (buf); ++ queries = 0; ++ ++ /* Response for PTR. */ ++ buf = malloc (512); ++ ret = libresolv_query (mode, "an1.ns2.ar1.example", T_PTR, buf, 512); ++ TEST_VERIFY_EXIT (ret > 0); ++ check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret, ++ "name: an1.ns2.ar1.example\n" ++ "data: an1.ns2.ar1.example PTR ptr-0\n"); ++ free (buf); ++ queries = 0; ++ ++ /* NODATA response for PTR. */ ++ buf = malloc (512); ++ errno = 0; ++ ret = libresolv_query (mode, "an0.ns2.ar1.example", T_PTR, buf, 512); ++ if (mode < first_send_mode) ++ { ++ TEST_COMPARE (ret, -1); ++ TEST_COMPARE (errno, 0); ++ TEST_COMPARE (h_errno, NO_ADDRESS); ++ } ++ else ++ { ++ TEST_VERIFY_EXIT (ret > 0); ++ TEST_COMPARE (((HEADER *)buf)->rcode, 0); ++ check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret, ++ "name: an0.ns2.ar1.example\n"); ++ } ++ free (buf); ++ queries = 0; ++ ++ /* NXDOMAIN response for PTR. */ ++ buf = malloc (512); ++ errno = 0; ++ ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_PTR, buf, 512); ++ if (mode < first_send_mode) ++ { ++ TEST_COMPARE (ret, -1); ++ TEST_COMPARE (errno, 0); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ } ++ else ++ { ++ TEST_VERIFY_EXIT (ret > 0); ++ TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN); ++ check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret, ++ "name: an-1.ns2.ar1.example\n"); ++ } ++ free (buf); ++ queries = 0; ++ ++ /* NODATA response for AAAA. */ ++ buf = malloc (512); ++ errno = 0; ++ ret = libresolv_query (mode, "an1.ns2.ar1.example", T_AAAA, buf, 512); ++ if (mode < first_send_mode) ++ { ++ TEST_COMPARE (ret, -1); ++ TEST_COMPARE (errno, 0); ++ TEST_COMPARE (h_errno, NO_ADDRESS); ++ } ++ else ++ { ++ TEST_VERIFY_EXIT (ret > 0); ++ TEST_COMPARE (((HEADER *)buf)->rcode, 0); ++ check_dns_packet ("an1.ns2.ar1.example A", buf, ret, ++ "name: an1.ns2.ar1.example\n"); ++ } ++ free (buf); ++ queries = 0; ++ ++ /* NODATA response for AAAA (original is already NODATA). */ ++ buf = malloc (512); ++ errno = 0; ++ ret = libresolv_query (mode, "an0.ns2.ar1.example", T_AAAA, buf, 512); ++ if (mode < first_send_mode) ++ { ++ TEST_COMPARE (ret, -1); ++ TEST_COMPARE (errno, 0); ++ TEST_COMPARE (h_errno, NO_ADDRESS); ++ } ++ else ++ { ++ TEST_VERIFY_EXIT (ret > 0); ++ TEST_COMPARE (((HEADER *)buf)->rcode, 0); ++ check_dns_packet ("an0.ns2.ar1.example A", buf, ret, ++ "name: an0.ns2.ar1.example\n"); ++ } ++ free (buf); ++ queries = 0; ++ ++ /* NXDOMAIN response. */ ++ buf = malloc (512); ++ errno = 0; ++ ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_AAAA, buf, 512); ++ if (mode < first_send_mode) ++ { ++ TEST_COMPARE (ret, -1); ++ TEST_COMPARE (errno, 0); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ } ++ else ++ { ++ TEST_VERIFY_EXIT (ret > 0); ++ TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN); ++ check_dns_packet ("an-1.ns2.ar1.example A", buf, ret, ++ "name: an-1.ns2.ar1.example\n"); ++ } ++ free (buf); ++ queries = 0; ++ } ++ ++ resolv_test_end (obj); ++ ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c +index c87596762fcb23b1..28ed9c2eb150532d 100644 +--- a/resolv/tst-resolv-res_init-skeleton.c ++++ b/resolv/tst-resolv-res_init-skeleton.c +@@ -128,6 +128,7 @@ print_resp (FILE *fp, res_state resp) + print_option_flag (fp, &options, RES_NOTLDQUERY, "no-tld-query"); + print_option_flag (fp, &options, RES_NORELOAD, "no-reload"); + print_option_flag (fp, &options, RES_TRUSTAD, "trust-ad"); ++ print_option_flag (fp, &options, RES_NOAAAA, "no-aaaa"); + fputc ('\n', fp); + if (options != 0) + fprintf (fp, "; error: unresolved option bits: 0x%x\n", options); +@@ -721,6 +722,15 @@ struct test_case test_cases[] = + "nameserver 192.0.2.1\n" + "; nameserver[0]: [192.0.2.1]:53\n" + }, ++ {.name = "no-aaaa flag", ++ .conf = "options no-aaaa\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "options no-aaaa\n" ++ "search example.com\n" ++ "; search[0]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, + { NULL } + }; + diff --git a/SOURCES/glibc-rh2117712-1.patch b/SOURCES/glibc-rh2117712-1.patch new file mode 100644 index 0000000..e154365 --- /dev/null +++ b/SOURCES/glibc-rh2117712-1.patch @@ -0,0 +1,154 @@ +commit cca9684f2d7a74fc0b28bfb1859955e0e28d7b4b +Author: Florian Weimer +Date: Wed Aug 3 11:41:53 2022 +0200 + + stdio: Clean up __libc_message after unconditional abort + + Since commit ec2c1fcefb200c6cb7e09553f3c6af8815013d83 ("malloc: + Abort on heap corruption, without a backtrace [BZ #21754]"), + __libc_message always terminates the process. Since commit + a289ea09ea843ced6e5277c2f2e63c357bc7f9a3 ("Do not print backtraces + on fatal glibc errors"), the backtrace facility has been removed. + Therefore, remove enum __libc_message_action and the action + argument of __libc_message, and mark __libc_message as _No_return. + + Reviewed-by: Adhemerval Zanella + +diff --git a/debug/fortify_fail.c b/debug/fortify_fail.c +index 9fa07af4867c2bd1..1b490d9da78b8d0d 100644 +--- a/debug/fortify_fail.c ++++ b/debug/fortify_fail.c +@@ -21,8 +21,6 @@ void + __attribute__ ((noreturn)) + __fortify_fail (const char *msg) + { +- /* The loop is added only to keep gcc happy. */ +- while (1) +- __libc_message (do_abort, "*** %s ***: terminated\n", msg); ++ __libc_message ("*** %s ***: terminated\n", msg); + } + libc_hidden_def (__fortify_fail) +diff --git a/include/stdio.h b/include/stdio.h +index 23b7fd288cdaba66..3d4544575318a934 100644 +--- a/include/stdio.h ++++ b/include/stdio.h +@@ -143,18 +143,11 @@ extern int __gen_tempname (char *__tmpl, int __suffixlen, int __flags, + # define __GT_DIR 1 /* create a directory */ + # define __GT_NOCREATE 2 /* just find a name not currently in use */ + +-enum __libc_message_action +-{ +- do_message = 0, /* Print message. */ +- do_abort = 1 << 0, /* 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, +- const char *__fnt, ...) attribute_hidden; ++_Noreturn void __libc_message (const char *__fnt, ...) attribute_hidden; + extern void __fortify_fail (const char *msg) __attribute__ ((__noreturn__)); + libc_hidden_proto (__fortify_fail) + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index d31e985ecce968fe..918e7936f1983437 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -298,8 +298,7 @@ _Noreturn static void + __malloc_assert (const char *assertion, const char *file, unsigned int line, + const char *function) + { +- __libc_message (do_abort, "\ +-Fatal glibc error: malloc assertion failure in %s: %s\n", ++ __libc_message ("Fatal glibc error: malloc assertion failure in %s: %s\n", + function, assertion); + __builtin_unreachable (); + } +@@ -5528,7 +5527,7 @@ static void + malloc_printerr (const char *str) + { + #if IS_IN (libc) +- __libc_message (do_abort, "%s\n", str); ++ __libc_message ("%s\n", str); + #else + __libc_fatal (str); + #endif +diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c +index 6d24bee6134856d1..1feacfbeba765035 100644 +--- a/sysdeps/posix/libc_fatal.c ++++ b/sysdeps/posix/libc_fatal.c +@@ -54,7 +54,7 @@ struct str_list + + /* Abort with an error message. */ + void +-__libc_message (enum __libc_message_action action, const char *fmt, ...) ++__libc_message (const char *fmt, ...) + { + va_list ap; + int fd = -1; +@@ -123,36 +123,31 @@ __libc_message (enum __libc_message_action action, const char *fmt, ...) + + WRITEV_FOR_FATAL (fd, iov, nlist, total); + +- if ((action & do_abort)) ++ total = (total + 1 + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1); ++ struct abort_msg_s *buf = __mmap (NULL, total, ++ PROT_READ | PROT_WRITE, ++ MAP_ANON | MAP_PRIVATE, -1, 0); ++ if (__glibc_likely (buf != MAP_FAILED)) + { +- total = ((total + 1 + GLRO(dl_pagesize) - 1) +- & ~(GLRO(dl_pagesize) - 1)); +- struct abort_msg_s *buf = __mmap (NULL, total, +- PROT_READ | PROT_WRITE, +- MAP_ANON | MAP_PRIVATE, -1, 0); +- if (__glibc_likely (buf != MAP_FAILED)) +- { +- buf->size = total; +- char *wp = buf->msg; +- for (int cnt = 0; cnt < nlist; ++cnt) +- wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len); +- *wp = '\0'; +- +- /* We have to free the old buffer since the application might +- catch the SIGABRT signal. */ +- struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg, +- buf); +- if (old != NULL) +- __munmap (old, old->size); +- } ++ buf->size = total; ++ char *wp = buf->msg; ++ for (int cnt = 0; cnt < nlist; ++cnt) ++ wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len); ++ *wp = '\0'; ++ ++ /* We have to free the old buffer since the application might ++ catch the SIGABRT signal. */ ++ struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg, ++ buf); ++ if (old != NULL) ++ __munmap (old, old->size); + } + } + + va_end (ap); + +- if ((action & do_abort)) +- /* Kill the application. */ +- abort (); ++ /* Kill the application. */ ++ abort (); + } + + +@@ -161,6 +156,6 @@ __libc_fatal (const char *message) + { + /* The loop is added only to keep gcc happy. */ + while (1) +- __libc_message (do_abort, "%s", message); ++ __libc_message ("%s", message); + } + libc_hidden_def (__libc_fatal) diff --git a/SOURCES/glibc-rh2117712-2.patch b/SOURCES/glibc-rh2117712-2.patch new file mode 100644 index 0000000..0a55182 --- /dev/null +++ b/SOURCES/glibc-rh2117712-2.patch @@ -0,0 +1,45 @@ +commit 68e036f27f31c3378201702e182246504fb00f87 +Author: Florian Weimer +Date: Wed Aug 3 11:41:53 2022 +0200 + + nptl: Remove uses of assert_perror + + __pthread_sigmask cannot actually fail with valid pointer arguments + (it would need a really broken seccomp filter), and we do not check + for errors elsewhere. + + Reviewed-by: Adhemerval Zanella + +diff --git a/sysdeps/nptl/gai_misc.h b/sysdeps/nptl/gai_misc.h +index 261e24dae62d7871..700fd5c46b4b7c82 100644 +--- a/sysdeps/nptl/gai_misc.h ++++ b/sysdeps/nptl/gai_misc.h +@@ -81,9 +81,7 @@ __gai_start_notify_thread (void) + { + sigset_t ss; + sigemptyset (&ss); +- int sigerr __attribute__ ((unused)); +- sigerr = __pthread_sigmask (SIG_SETMASK, &ss, NULL); +- assert_perror (sigerr); ++ (void) __pthread_sigmask (SIG_SETMASK, &ss, NULL); + } + + extern inline int +@@ -106,15 +104,12 @@ __gai_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), + sigset_t ss; + sigset_t oss; + sigfillset (&ss); +- int sigerr __attribute__ ((unused)); +- sigerr = __pthread_sigmask (SIG_SETMASK, &ss, &oss); +- assert_perror (sigerr); ++ (void) __pthread_sigmask (SIG_SETMASK, &ss, &oss); + + int ret = __pthread_create (threadp, &attr, tf, arg); + + /* Restore the signal mask. */ +- sigerr = __pthread_sigmask (SIG_SETMASK, &oss, NULL); +- assert_perror (sigerr); ++ (void) __pthread_sigmask (SIG_SETMASK, &oss, NULL); + + (void) __pthread_attr_destroy (&attr); + return ret; diff --git a/SOURCES/glibc-rh2117712-3.patch b/SOURCES/glibc-rh2117712-3.patch new file mode 100644 index 0000000..e3cf26e --- /dev/null +++ b/SOURCES/glibc-rh2117712-3.patch @@ -0,0 +1,164 @@ +commit 9001cb1102cddba54f0e84e147dfbb0356067356 +Author: Florian Weimer +Date: Wed Aug 3 11:41:53 2022 +0200 + + assert: Do not use stderr in libc-internal assert + + Redirect internal assertion failures to __libc_assert_fail, based on + based on __libc_message, which writes directly to STDERR_FILENO + and calls abort. Also disable message translation and reword the + error message slightly (adjusting stdlib/tst-bz20544 accordingly). + + As a result of these changes, malloc no longer needs its own + redefinition of __assert_fail. + + __libc_assert_fail needs to be stubbed out during rtld dependency + analysis because the rtld rebuilds turn __libc_assert_fail into + __assert_fail, which is unconditionally provided by elf/dl-minimal.c. + + This change is not possible for the public assert macro and its + __assert_fail function because POSIX requires that the diagnostic + is written to stderr. + + Reviewed-by: Adhemerval Zanella + +diff --git a/assert/Makefile b/assert/Makefile +index 0008de34cb484a13..2bc9e2214e3e9a8b 100644 +--- a/assert/Makefile ++++ b/assert/Makefile +@@ -24,7 +24,12 @@ include ../Makeconfig + + headers := assert.h + +-routines := assert assert-perr __assert ++routines := \ ++ __assert \ ++ __libc_assert_fail \ ++ assert \ ++ assert-perr \ ++ # routines + tests := test-assert test-assert-perr tst-assert-c++ tst-assert-g++ + + ifeq ($(have-cxx-thread_local),yes) +diff --git a/assert/__libc_assert_fail.c b/assert/__libc_assert_fail.c +new file mode 100644 +index 0000000000000000..149d5feae12f4af8 +--- /dev/null ++++ b/assert/__libc_assert_fail.c +@@ -0,0 +1,33 @@ ++/* libc-internal assert that calls __libc_message. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include <_itoa.h> ++#include ++#include ++#include ++ ++void ++__libc_assert_fail (const char *assertion, const char *file, unsigned int line, ++ const char *function) ++{ ++ char linebuf[INT_BUFSIZE_BOUND (unsigned int)]; ++ array_end (linebuf)[-1] = '\0'; ++ char *linestr = _itoa_word (line, array_end (linebuf) - 1, 10, 0); ++ __libc_message ("Fatal glibc error: %s:%s (%s): assertion failed: %s\n", ++ file, linestr, function, assertion); ++} +diff --git a/assert/assert.c b/assert/assert.c +index 8a277dce008b3495..989126c7e5b6b265 100644 +--- a/assert/assert.c ++++ b/assert/assert.c +@@ -101,4 +101,3 @@ __assert_fail (const char *assertion, const char *file, unsigned int line, + __assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n%n"), + assertion, file, line, function); + } +-hidden_def(__assert_fail) +diff --git a/elf/Makefile b/elf/Makefile +index 613d244e7781d479..2b547d5b58f1759b 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -1158,6 +1158,7 @@ $(objpfx)dl-allobjs.os: $(all-rtld-routines:%=$(objpfx)%.os) + rtld-stubbed-symbols = \ + __GI___pthread_disable_asynccancel \ + __GI___pthread_enable_asynccancel \ ++ __libc_assert_fail \ + __pthread_disable_asynccancel \ + __pthread_enable_asynccancel \ + calloc \ +diff --git a/include/assert.h b/include/assert.h +index 61cc8aa22ff4b913..c812808f9b767964 100644 +--- a/include/assert.h ++++ b/include/assert.h +@@ -20,8 +20,14 @@ extern void __assert_fail_base (const char *fmt, const char *assertion, + const char *function) + __THROW __attribute__ ((__noreturn__)) attribute_hidden; + +-# if IS_IN (libc) || (IS_IN (rtld) && !defined NO_RTLD_HIDDEN) +-hidden_proto (__assert_fail) +-hidden_proto (__assert_perror_fail) ++rtld_hidden_proto (__assert_fail) ++rtld_hidden_proto (__assert_perror_fail) ++libc_hidden_proto (__assert_perror_fail) ++ ++ ++# if IS_IN (libc) ++/* Redirect to the internal version which does not use stderr. */ ++extern _Noreturn __typeof (__assert_fail) __libc_assert_fail attribute_hidden; ++# define __assert_fail __libc_assert_fail + # endif + #endif +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 918e7936f1983437..2edb469d5dbf1203 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -289,22 +289,6 @@ + #define MALLOC_DEBUG 0 + #endif + +-#if IS_IN (libc) +-#ifndef NDEBUG +-# define __assert_fail(assertion, file, line, function) \ +- __malloc_assert(assertion, file, line, function) +- +-_Noreturn static void +-__malloc_assert (const char *assertion, const char *file, unsigned int line, +- const char *function) +-{ +- __libc_message ("Fatal glibc error: malloc assertion failure in %s: %s\n", +- function, assertion); +- __builtin_unreachable (); +-} +-#endif +-#endif +- + #if USE_TCACHE + /* We want 64 entries. This is an arbitrary limit, which tunables can reduce. */ + # define TCACHE_MAX_BINS 64 +diff --git a/stdlib/tst-bz20544.c b/stdlib/tst-bz20544.c +index 4aa5793b8994d1f6..1337a3952c30e517 100644 +--- a/stdlib/tst-bz20544.c ++++ b/stdlib/tst-bz20544.c +@@ -78,7 +78,7 @@ test_bz20544_cxa_at_quick_exit (void *closure) + static void + test_one_fn (void (*test_fn) (void *)) + { +- const char expected_error[] = "Assertion `func != NULL' failed.\n"; ++ const char expected_error[] = "assertion failed: func != NULL\n"; + struct support_capture_subprocess result; + result = support_capture_subprocess (test_fn, NULL); + support_capture_subprocess_check (&result, "bz20544", -SIGABRT, diff --git a/SOURCES/glibc-rh2117712-4.patch b/SOURCES/glibc-rh2117712-4.patch new file mode 100644 index 0000000..1d0a420 --- /dev/null +++ b/SOURCES/glibc-rh2117712-4.patch @@ -0,0 +1,22 @@ +commit 8fabe0e632bd441c760f878d1022c378f04f8497 +Author: Florian Weimer +Date: Thu Aug 4 06:17:50 2022 +0200 + + Linux: Remove exit system call from _exit + + exit only terminates the current thread, not the whole process, so it + is the wrong fallback system call in this context. All supported + Linux versions implement the exit_group system call anyway. + +diff --git a/sysdeps/unix/sysv/linux/_exit.c b/sysdeps/unix/sysv/linux/_exit.c +index 2f0ec35459f25314..cd1270ac9b2b5b2b 100644 +--- a/sysdeps/unix/sysv/linux/_exit.c ++++ b/sysdeps/unix/sysv/linux/_exit.c +@@ -28,7 +28,6 @@ _exit (int status) + while (1) + { + INLINE_SYSCALL (exit_group, 1, status); +- INLINE_SYSCALL (exit, 1, status); + + #ifdef ABORT_INSTRUCTION + ABORT_INSTRUCTION; diff --git a/SOURCES/glibc-rh2117712-5.patch b/SOURCES/glibc-rh2117712-5.patch new file mode 100644 index 0000000..e147fa2 --- /dev/null +++ b/SOURCES/glibc-rh2117712-5.patch @@ -0,0 +1,69 @@ +Very limited backport of the following upstream commit, to obtain +the definition of __getrandom_nocancel. + +commit 6f4e0fcfa2d2b0915816a3a3a1d48b4763a7dee2 +Author: Adhemerval Zanella Netto +Date: Thu Jul 21 10:04:59 2022 -0300 + + stdlib: Add arc4random, arc4random_buf, and arc4random_uniform (BZ #4417) + +With the INTERNAL_SYSCALL_CALL change from this patch already applied: + +commit 609c9d0951da387cd523b5db42a82d38dabc37c4 +Author: Adhemerval Zanella +Date: Thu Sep 29 16:18:06 2022 -0300 + + malloc: Do not clobber errno on __getrandom_nocancel (BZ #29624) + + Use INTERNAL_SYSCALL_CALL instead of INLINE_SYSCALL_CALL. This + requires emulate the semantic for hurd call (so __arc4random_buf + uses the fallback). + + Checked on x86_64-linux-gnu. + + Reviewed-by: Wilco Dijkstra + +diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h +index 8a3772a1fe66271e..14188041c2c0ad57 100644 +--- a/sysdeps/generic/not-cancel.h ++++ b/sysdeps/generic/not-cancel.h +@@ -49,5 +49,7 @@ + (void) __writev (fd, iov, n) + #define __fcntl64_nocancel(fd, cmd, ...) \ + __fcntl64 (fd, cmd, __VA_ARGS__) ++#define __getrandom_nocancel(buf, size, flags) \ ++ __getrandom (buf, size, flags) + + #endif /* NOT_CANCEL_H */ +diff --git a/sysdeps/mach/hurd/not-cancel.h b/sysdeps/mach/hurd/not-cancel.h +index cd320cb721e6ff7e..7a3d2cc3532cf866 100644 +--- a/sysdeps/mach/hurd/not-cancel.h ++++ b/sysdeps/mach/hurd/not-cancel.h +@@ -75,6 +75,9 @@ __typeof (__fcntl) __fcntl_nocancel; + #define __fcntl64_nocancel(...) \ + __fcntl_nocancel (__VA_ARGS__) + ++#define __getrandom_nocancel(buf, size, flags) \ ++ __getrandom (buf, size, flags) ++ + #if IS_IN (libc) + hidden_proto (__close_nocancel) + hidden_proto (__close_nocancel_nostatus) +diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h +index f06d57426a40227e..d2bb59acddbcfee0 100644 +--- a/sysdeps/unix/sysv/linux/not-cancel.h ++++ b/sysdeps/unix/sysv/linux/not-cancel.h +@@ -68,6 +68,13 @@ __writev_nocancel_nostatus (int fd, const struct iovec *iov, int iovcnt) + INTERNAL_SYSCALL_CALL (writev, fd, iov, iovcnt); + } + ++static inline int ++__getrandom_nocancel (void *buf, size_t buflen, unsigned int flags) ++{ ++ return INTERNAL_SYSCALL_CALL (getrandom, buf, buflen, flags); ++} ++ ++ + /* Uncancelable fcntl. */ + __typeof (__fcntl) __fcntl64_nocancel; + diff --git a/SOURCES/glibc-rh2117712-6.patch b/SOURCES/glibc-rh2117712-6.patch new file mode 100644 index 0000000..33766ff --- /dev/null +++ b/SOURCES/glibc-rh2117712-6.patch @@ -0,0 +1,35 @@ +commit 7187efd0aa270c83c428ea6cd0e1cffc34b41a74 +Author: Florian Weimer +Date: Mon Aug 1 15:49:07 2022 +0200 + + malloc: Use __getrandom_nocancel during tcache initiailization + + Cancellation currently cannot happen at this point because dlopen + as used by the unwind link always performs additional allocations + for libgcc_s.so.1, even if it has been loaded already as a dependency + of the main executable. But it seems prudent not to rely on this + quirk. + + Reviewed-by: Adhemerval Zanella + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 2edb469d5dbf1203..375f50f5db13e234 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -256,6 +256,7 @@ + /* For tcache double-free check. */ + #include + #include ++#include + + /* + Debugging: +@@ -3025,7 +3026,7 @@ static uintptr_t tcache_key; + static void + tcache_key_initialize (void) + { +- if (__getrandom (&tcache_key, sizeof(tcache_key), GRND_NONBLOCK) ++ if (__getrandom_nocancel (&tcache_key, sizeof(tcache_key), GRND_NONBLOCK) + != sizeof (tcache_key)) + { + tcache_key = random_bits (); diff --git a/SOURCES/glibc-rh2118666.patch b/SOURCES/glibc-rh2118666.patch new file mode 100644 index 0000000..86750f6 --- /dev/null +++ b/SOURCES/glibc-rh2118666.patch @@ -0,0 +1,94 @@ +commit dd2315a866a4ac2b838ea1cb10c5ea1c35d51a2f +Author: Florian Weimer +Date: Tue Aug 16 08:27:50 2022 +0200 + + elf: Run tst-audit-tlsdesc, tst-audit-tlsdesc-dlopen everywhere + + The test is valid for all TLS models, but we want to make a reasonable + effort to test the GNU2 model specifically. For example, aarch64 + defaults to GNU2, but does not have -mtls-dialect=gnu2, and the test + was not run there. + + Suggested-by: Martin Coufal + +Conflicts: + elf/Makefile + (missing tst-align3 test downstream) + +diff --git a/elf/Makefile b/elf/Makefile +index ea1512549be3f628..613d244e7781d479 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -361,6 +361,8 @@ tests += \ + tst-addr1 \ + tst-align \ + tst-align2 \ ++ tst-audit-tlsdesc \ ++ tst-audit-tlsdesc-dlopen \ + tst-audit1 \ + tst-audit2 \ + tst-audit8 \ +@@ -679,6 +681,8 @@ modules-names = \ + tst-alignmod2 \ + tst-array2dep \ + tst-array5dep \ ++ tst-audit-tlsdesc-mod1 \ ++ tst-audit-tlsdesc-mod2 \ + tst-audit11mod1 \ + tst-audit11mod2 \ + tst-audit12mod1 \ +@@ -712,6 +716,7 @@ modules-names = \ + tst-auditmanymod7 \ + tst-auditmanymod8 \ + tst-auditmanymod9 \ ++ tst-auditmod-tlsdesc \ + tst-auditmod1 \ + tst-auditmod9a \ + tst-auditmod9b \ +@@ -889,23 +894,8 @@ modules-names += tst-gnu2-tls1mod + $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so + tst-gnu2-tls1mod.so-no-z-defs = yes + CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 ++endif # $(have-mtls-dialect-gnu2) + +-tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen +-modules-names += tst-audit-tlsdesc-mod1 tst-audit-tlsdesc-mod2 tst-auditmod-tlsdesc +-$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \ +- $(objpfx)tst-audit-tlsdesc-mod2.so \ +- $(shared-thread-library) +-CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2 +-CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2 +-$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library) +-$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \ +- $(objpfx)tst-audit-tlsdesc-mod2.so +-$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so +-$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so +-tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so +-$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so +-tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so +-endif + ifeq (yes,$(have-protected-data)) + modules-names += tst-protected1moda tst-protected1modb + tests += tst-protected1a tst-protected1b +@@ -2656,3 +2646,21 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: \ + grep -q '^Fatal glibc error: Cannot allocate TLS block$$' $@ \ + && grep -q '^status: 127$$' $@; \ + $(evaluate-test) ++ ++$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \ ++ $(objpfx)tst-audit-tlsdesc-mod2.so \ ++ $(shared-thread-library) ++ifeq (yes,$(have-mtls-dialect-gnu2)) ++# The test is valid for all TLS types, but we want to exercise GNU2 ++# TLS if possible. ++CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2 ++CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2 ++endif ++$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library) ++$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \ ++ $(objpfx)tst-audit-tlsdesc-mod2.so ++$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so ++$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so ++tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so ++$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so ++tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so diff --git a/SOURCES/glibc-rh2128615-1.patch b/SOURCES/glibc-rh2128615-1.patch new file mode 100644 index 0000000..b4783d8 --- /dev/null +++ b/SOURCES/glibc-rh2128615-1.patch @@ -0,0 +1,37 @@ +commit 183d99737298bb3200f0610fdcd1c7549c8ed560 +Author: Florian Weimer +Date: Tue Sep 6 07:38:10 2022 +0200 + + scripts/dso-ordering-test.py: Generate program run-time dependencies + + The main program needs to depend on all shared objects, even objects + that have link-time dependencies among shared objects. Filtering + out shared objects that already have an link-time dependencies is not + necessary here; make will do this automatically. + + Reviewed-by: Adhemerval Zanella + +diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py +index bde0406be9da14fc..4ffcff6136145ef1 100644 +--- a/scripts/dso-ordering-test.py ++++ b/scripts/dso-ordering-test.py +@@ -707,13 +707,12 @@ def process_testcase(t): + "\t$(compile.c) $(OUTPUT_OPTION)\n") + makefile.write (rule) + +- not_depended_objs = find_objs_not_depended_on(test_descr) +- if not_depended_objs: +- depstr = "" +- for dep in not_depended_objs: +- depstr += (" $(objpfx)" + test_subdir + "/" +- + test_name + "-" + dep + ".so") +- makefile.write("$(objpfx)%s.out:%s\n" % (base_test_name, depstr)) ++ # Ensure that all shared objects are built before running the ++ # test, whether there link-time dependencies or not. ++ depobjs = ["$(objpfx){}/{}-{}.so".format(test_subdir, test_name, dep) ++ for dep in test_descr.objs] ++ makefile.write("$(objpfx){}.out: {}\n".format( ++ base_test_name, " ".join(depobjs))) + + # Add main executable to test-srcs + makefile.write("test-srcs += %s/%s\n" % (test_subdir, test_name)) diff --git a/SOURCES/glibc-rh2128615-2.patch b/SOURCES/glibc-rh2128615-2.patch new file mode 100644 index 0000000..2d8d4ac --- /dev/null +++ b/SOURCES/glibc-rh2128615-2.patch @@ -0,0 +1,79 @@ +commit dbb75513f5cf9285c77c9e55777c5c35b653f890 +Author: Florian Weimer +Date: Tue Sep 6 07:38:10 2022 +0200 + + elf: Rename _dl_sort_maps parameter from skip to force_first + + The new implementation will not be able to skip an arbitrary number + of objects. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c +index 72f4ff0e6eda3377..7c614bca5d8115c6 100644 +--- a/elf/dl-sort-maps.c ++++ b/elf/dl-sort-maps.c +@@ -27,12 +27,12 @@ + If FOR_FINI is true, this is called for finishing an object. */ + static void + _dl_sort_maps_original (struct link_map **maps, unsigned int nmaps, +- unsigned int skip, bool for_fini) ++ bool force_first, bool for_fini) + { + /* Allows caller to do the common optimization of skipping the first map, + usually the main binary. */ +- maps += skip; +- nmaps -= skip; ++ maps += force_first; ++ nmaps -= force_first; + + /* A list of one element need not be sorted. */ + if (nmaps <= 1) +@@ -182,7 +182,7 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map, + + static void + _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps, +- unsigned int skip __attribute__ ((unused)), bool for_fini) ++ bool force_first __attribute__ ((unused)), bool for_fini) + { + for (int i = nmaps - 1; i >= 0; i--) + maps[i]->l_visited = 0; +@@ -286,7 +286,7 @@ _dl_sort_maps_init (void) + + void + _dl_sort_maps (struct link_map **maps, unsigned int nmaps, +- unsigned int skip, bool for_fini) ++ bool force_first, bool for_fini) + { + /* It can be tempting to use a static function pointer to store and call + the current selected sorting algorithm routine, but experimentation +@@ -296,9 +296,9 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, + input cases. A simple if-case with direct function calls appears to + be the fastest. */ + if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original)) +- _dl_sort_maps_original (maps, nmaps, skip, for_fini); ++ _dl_sort_maps_original (maps, nmaps, force_first, for_fini); + else +- _dl_sort_maps_dfs (maps, nmaps, skip, for_fini); ++ _dl_sort_maps_dfs (maps, nmaps, force_first, for_fini); + } + + #endif /* HAVE_TUNABLES. */ +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 87ad2f3f4d89eb7d..8c0fe98f69a88f1e 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1106,9 +1106,11 @@ extern void _dl_init (struct link_map *main_map, int argc, char **argv, + initializer functions have completed. */ + extern void _dl_fini (void) attribute_hidden; + +-/* Sort array MAPS according to dependencies of the contained objects. */ ++/* Sort array MAPS according to dependencies of the contained objects. ++ If FORCE_FIRST, MAPS[0] keeps its place even if the dependencies ++ say otherwise. */ + extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps, +- unsigned int skip, bool for_fini) attribute_hidden; ++ bool force_first, bool for_fini) attribute_hidden; + + /* The dynamic linker calls this function before and having changing + any shared object mappings. The `r_state' member of `struct r_debug' diff --git a/SOURCES/glibc-rh2128615-3.patch b/SOURCES/glibc-rh2128615-3.patch new file mode 100644 index 0000000..bf8a9a4 --- /dev/null +++ b/SOURCES/glibc-rh2128615-3.patch @@ -0,0 +1,90 @@ +commit 1df71d32fe5f5905ffd5d100e5e9ca8ad6210891 +Author: Florian Weimer +Date: Tue Sep 20 11:00:42 2022 +0200 + + elf: Implement force_first handling in _dl_sort_maps_dfs (bug 28937) + + The implementation in _dl_close_worker requires that the first + element of l_initfini is always this very map (“We are always the + zeroth entry, and since we don't include ourselves in the + dependency analysis start at 1.â€). Rather than fixing that + assumption, this commit adds an implementation of the force_first + argument to the new dependency sorting algorithm. This also means + that the directly dlopen'ed shared object is always initialized last, + which is the least surprising behavior in the presence of cycles. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c +index 7c614bca5d8115c6..e8ef5e8b3588ab53 100644 +--- a/elf/dl-sort-maps.c ++++ b/elf/dl-sort-maps.c +@@ -182,8 +182,9 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map, + + static void + _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps, +- bool force_first __attribute__ ((unused)), bool for_fini) ++ bool force_first, bool for_fini) + { ++ struct link_map *first_map = maps[0]; + for (int i = nmaps - 1; i >= 0; i--) + maps[i]->l_visited = 0; + +@@ -208,14 +209,6 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps, + Adjusting the order so that maps[0] is last traversed naturally avoids + this problem. + +- Further, the old "optimization" of skipping the main object at maps[0] +- from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general +- no longer valid, since traversing along object dependency-links +- may "find" the main object even when it is not included in the initial +- order (e.g. a dlopen()'ed shared object can have circular dependencies +- linked back to itself). In such a case, traversing N-1 objects will +- create a N-object result, and raise problems. +- + To summarize, just passing in the full list, and iterating from back + to front makes things much more straightforward. */ + +@@ -274,6 +267,27 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps, + } + + memcpy (maps, rpo, sizeof (struct link_map *) * nmaps); ++ ++ /* Skipping the first object at maps[0] is not valid in general, ++ since traversing along object dependency-links may "find" that ++ first object even when it is not included in the initial order ++ (e.g., a dlopen'ed shared object can have circular dependencies ++ linked back to itself). In such a case, traversing N-1 objects ++ will create a N-object result, and raise problems. Instead, ++ force the object back into first place after sorting. This naive ++ approach may introduce further dependency ordering violations ++ compared to rotating the cycle until the first map is again in ++ the first position, but as there is a cycle, at least one ++ violation is already present. */ ++ if (force_first && maps[0] != first_map) ++ { ++ int i; ++ for (i = 0; maps[i] != first_map; ++i) ++ ; ++ assert (i < nmaps); ++ memmove (&maps[1], maps, i * sizeof (maps[0])); ++ maps[0] = first_map; ++ } + } + + void +diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def +index 5f7f18ef270bc12d..4bf9052db16fb352 100644 +--- a/elf/dso-sort-tests-1.def ++++ b/elf/dso-sort-tests-1.def +@@ -64,3 +64,10 @@ output: b>a>{}b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c + output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[a1;a->a2;a2->a;b->b1;c->a1;c=>a1 ++output(glibc.rtld.dynamic_sort=1): {+a[a2>a1>a>];+b[b1>b>];-b[];%c(a1());}a1>a>];+b[b1>b>];-b[];%c(a1());} +Date: Tue Aug 30 10:02:49 2022 +0200 + + nss_dns: Rewrite _nss_dns_gethostbyname4_r using current interfaces + + Introduce struct alloc_buffer to this function, and use it and + struct ns_rr_cursor in gaih_getanswer_slice. Adjust gaih_getanswer + and gaih_getanswer_noaaaa accordingly. + + Reviewed-by: Siddhesh Poyarekar + +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 1cb3be71f04d98eb..36789965c06757d0 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -101,13 +101,6 @@ + #endif + #define MAXHOSTNAMELEN 256 + +-/* We need this time later. */ +-typedef union querybuf +-{ +- HEADER hdr; +- u_char buf[MAXPACKET]; +-} querybuf; +- + /* For historic reasons, pointers to IP addresses are char *, so use a + single list type for addresses and host names. */ + #define DYNARRAY_STRUCT ptrlist +@@ -126,18 +119,18 @@ static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen, + char **hnamep, int *errnop, + int *h_errnop, int32_t *ttlp); + +-static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1, +- const querybuf *answer2, int anslen2, +- const char *qname, ++static enum nss_status gaih_getanswer (unsigned char *packet1, ++ size_t packet1len, ++ unsigned char *packet2, ++ size_t packet2len, ++ struct alloc_buffer *abuf, + struct gaih_addrtuple **pat, +- char *buffer, size_t buflen, + int *errnop, int *h_errnop, + int32_t *ttlp); +-static enum nss_status gaih_getanswer_noaaaa (const querybuf *answer1, +- int anslen1, +- const char *qname, ++static enum nss_status gaih_getanswer_noaaaa (unsigned char *packet, ++ size_t packetlen, ++ struct alloc_buffer *abuf, + struct gaih_addrtuple **pat, +- char *buffer, size_t buflen, + int *errnop, int *h_errnop, + int32_t *ttlp); + +@@ -409,17 +402,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + name = cp; + } + +- union +- { +- querybuf *buf; +- u_char *ptr; +- } host_buffer; +- querybuf *orig_host_buffer; +- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048); ++ unsigned char dns_packet_buffer[2048]; ++ unsigned char *alt_dns_packet_buffer = dns_packet_buffer; + u_char *ans2p = NULL; + int nans2p = 0; + int resplen2 = 0; + int ans2p_malloced = 0; ++ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen); + + + int olderr = errno; +@@ -428,22 +417,21 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + if ((ctx->resp->options & RES_NOAAAA) == 0) + { + 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); ++ dns_packet_buffer, sizeof (dns_packet_buffer), ++ &alt_dns_packet_buffer, &ans2p, &nans2p, ++ &resplen2, &ans2p_malloced); + if (n >= 0) +- status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p, +- resplen2, name, pat, buffer, buflen, +- errnop, herrnop, ttlp); ++ status = gaih_getanswer (alt_dns_packet_buffer, n, ans2p, resplen2, ++ &abuf, pat, errnop, herrnop, ttlp); + } + else + { + n = __res_context_search (ctx, name, C_IN, T_A, +- host_buffer.buf->buf, 2048, NULL, +- NULL, NULL, NULL, NULL); ++ dns_packet_buffer, sizeof (dns_packet_buffer), ++ NULL, NULL, NULL, NULL, NULL); + if (n >= 0) +- status = gaih_getanswer_noaaaa (host_buffer.buf, n, +- name, pat, buffer, buflen, +- errnop, herrnop, ttlp); ++ status = gaih_getanswer_noaaaa (alt_dns_packet_buffer, n, ++ &abuf, pat, errnop, herrnop, ttlp); + } + if (n < 0) + { +@@ -474,12 +462,20 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + __set_errno (olderr); + } + ++ /* Implement the buffer resizing protocol. */ ++ if (alloc_buffer_has_failed (&abuf)) ++ { ++ *errnop = ERANGE; ++ *herrnop = NETDB_INTERNAL; ++ status = NSS_STATUS_TRYAGAIN; ++ } ++ + /* Check whether ans2p was separately allocated. */ + if (ans2p_malloced) + free (ans2p); + +- if (host_buffer.buf != orig_host_buffer) +- free (host_buffer.buf); ++ if (alt_dns_packet_buffer != dns_packet_buffer) ++ free (alt_dns_packet_buffer); + + __resolv_context_put (ctx); + return status; +@@ -893,259 +889,152 @@ getanswer_ptr (unsigned char *packet, size_t packetlen, + return NSS_STATUS_TRYAGAIN; + } + ++/* Parses DNS data found in PACKETLEN bytes at PACKET in struct ++ gaih_addrtuple address tuples. The new address tuples are linked ++ from **TAILP, with backing store allocated from ABUF, and *TAILP is ++ updated to point where the next tuple pointer should be stored. If ++ TTLP is not null, *TTLP is updated to reflect the minimum TTL. If ++ STORE_CANON is true, the canonical name is stored as part of the ++ first address tuple being written. */ + static enum nss_status +-gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, +- struct gaih_addrtuple ***patp, +- char **bufferp, size_t *buflenp, +- int *errnop, int *h_errnop, int32_t *ttlp, int *firstp) ++gaih_getanswer_slice (unsigned char *packet, size_t packetlen, ++ struct alloc_buffer *abuf, ++ struct gaih_addrtuple ***tailp, ++ int *errnop, int *h_errnop, int32_t *ttlp, ++ bool store_canon) + { +- char *buffer = *bufferp; +- size_t buflen = *buflenp; +- +- struct gaih_addrtuple **pat = *patp; +- const HEADER *hp = &answer->hdr; +- int ancount = ntohs (hp->ancount); +- int qdcount = ntohs (hp->qdcount); +- const u_char *cp = answer->buf + HFIXEDSZ; +- const u_char *end_of_message = answer->buf + anslen; +- if (__glibc_unlikely (qdcount != 1)) +- { +- *h_errnop = NO_RECOVERY; +- return NSS_STATUS_UNAVAIL; +- } +- +- u_char packtmp[NS_MAXCDNAME]; +- int n = __ns_name_unpack (answer->buf, end_of_message, cp, +- packtmp, sizeof packtmp); +- /* We unpack the name to check it for validity. But we do not need +- it later. */ +- if (n != -1 && __ns_name_ntop (packtmp, buffer, buflen) == -1) +- { +- if (__glibc_unlikely (errno == EMSGSIZE)) +- { +- too_small: +- *errnop = ERANGE; +- *h_errnop = NETDB_INTERNAL; +- return NSS_STATUS_TRYAGAIN; +- } +- +- n = -1; +- } +- +- if (__glibc_unlikely (n < 0)) +- { +- *errnop = errno; +- *h_errnop = NO_RECOVERY; +- return NSS_STATUS_UNAVAIL; +- } +- if (__glibc_unlikely (__libc_res_hnok (buffer) == 0)) ++ struct ns_rr_cursor c; ++ if (!__ns_rr_cursor_init (&c, packet, packetlen)) + { +- errno = EBADMSG; +- *errnop = EBADMSG; ++ /* This should not happen because __res_context_query already ++ perfroms response validation. */ + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; + } +- cp += n + QFIXEDSZ; ++ bool haveanswer = false; /* Set to true if at least one address. */ ++ uint16_t qtype = ns_rr_cursor_qtype (&c); ++ int ancount = ns_rr_cursor_ancount (&c); ++ const unsigned char *expected_name = ns_rr_cursor_qname (&c); ++ /* expected_name may be updated to point into this buffer. */ ++ unsigned char name_buffer[NS_MAXCDNAME]; + +- int haveanswer = 0; +- int had_error = 0; +- char *canon = NULL; +- char *h_name = NULL; +- int h_namelen = 0; ++ /* This is a pointer to a possibly-compressed name in the packet. ++ Eventually it is equivalent to the canonical name. If needed, it ++ is uncompressed and translated to text form when the first ++ address tuple is encountered. */ ++ const unsigned char *compressed_alias_name = expected_name; + +- if (ancount == 0) ++ if (ancount == 0 || !__res_binary_hnok (compressed_alias_name)) + { + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } + +- while (ancount-- > 0 && cp < end_of_message && had_error == 0) ++ for (; ancount > -0; --ancount) + { +- n = __ns_name_unpack (answer->buf, end_of_message, cp, +- packtmp, sizeof packtmp); +- if (n != -1 && +- (h_namelen = __ns_name_ntop (packtmp, buffer, buflen)) == -1) +- { +- if (__glibc_unlikely (errno == EMSGSIZE)) +- goto too_small; +- +- n = -1; +- } +- if (__glibc_unlikely (n < 0)) +- { +- ++had_error; +- continue; +- } +- if (*firstp && canon == NULL && __libc_res_hnok (buffer)) +- { +- h_name = buffer; +- buffer += h_namelen; +- buflen -= h_namelen; +- } +- +- cp += n; /* name */ +- +- if (__glibc_unlikely (cp + 10 > end_of_message)) +- { +- ++had_error; +- continue; +- } +- +- uint16_t type; +- NS_GET16 (type, cp); +- uint16_t class; +- NS_GET16 (class, cp); +- int32_t ttl; +- NS_GET32 (ttl, cp); +- NS_GET16 (n, cp); /* RDATA length. */ +- +- if (end_of_message - cp < n) ++ struct ns_rr_wire rr; ++ if (!__ns_rr_cursor_next (&c, &rr)) + { +- /* RDATA extends beyond the end of the packet. */ +- ++had_error; +- continue; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; + } + +- if (class != C_IN) +- { +- cp += n; +- continue; +- } ++ /* Update TTL for known record types. */ ++ if ((rr.rtype == T_CNAME || rr.rtype == qtype) ++ && ttlp != NULL && *ttlp > rr.ttl) ++ *ttlp = rr.ttl; + +- if (type == T_CNAME) ++ if (rr.rtype == T_CNAME) + { +- char tbuf[MAXDNAME]; +- +- /* A CNAME could also have a TTL entry. */ +- if (ttlp != NULL && ttl < *ttlp) +- *ttlp = ttl; +- +- n = __libc_dn_expand (answer->buf, end_of_message, cp, +- tbuf, sizeof tbuf); +- if (__glibc_unlikely (n < 0)) +- { +- ++had_error; +- continue; +- } +- cp += n; +- +- if (*firstp && __libc_res_hnok (tbuf)) ++ /* NB: No check for owner name match, based on historic ++ precedent. Record the CNAME target as the new expected ++ name. */ ++ int n = __ns_name_unpack (c.begin, c.end, rr.rdata, ++ name_buffer, sizeof (name_buffer)); ++ if (n < 0) + { +- /* Reclaim buffer space. */ +- if (h_name + h_namelen == buffer) +- { +- buffer = h_name; +- buflen += h_namelen; +- } +- +- n = strlen (tbuf) + 1; +- if (__glibc_unlikely (n > buflen)) +- goto too_small; +- if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) +- { +- ++had_error; +- continue; +- } +- +- canon = buffer; +- buffer = __mempcpy (buffer, tbuf, n); +- buflen -= n; +- h_namelen = 0; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; + } +- continue; ++ expected_name = name_buffer; ++ if (store_canon && __res_binary_hnok (name_buffer)) ++ /* This name can be used as a canonical name. Do not ++ translate to text form here to conserve buffer space. ++ Point to the compressed name because name_buffer can be ++ overwritten with an unusable name later. */ ++ compressed_alias_name = rr.rdata; + } +- +- /* Stop parsing if we encounter a record with incorrect RDATA +- length. */ +- if (type == T_A || type == T_AAAA) ++ else if (rr.rtype == qtype ++ && __ns_samebinaryname (rr.rname, expected_name) ++ && rr.rdlength == rrtype_to_rdata_length (qtype)) + { +- if (n != rrtype_to_rdata_length (type)) ++ struct gaih_addrtuple *ntup ++ = alloc_buffer_alloc (abuf, struct gaih_addrtuple); ++ /* Delay error reporting to the callers (they implement the ++ ERANGE buffer resizing handshake). */ ++ if (ntup != NULL) + { +- ++had_error; +- continue; ++ ntup->next = NULL; ++ if (store_canon && compressed_alias_name != NULL) ++ { ++ /* This assumes that all the CNAME records come ++ first. Use MAXHOSTNAMELEN instead of ++ NS_MAXCDNAME for additional length checking. ++ However, these checks are not expected to fail ++ because all size NS_MAXCDNAME names should into ++ the hname buffer because no escaping is ++ needed. */ ++ char unsigned nbuf[NS_MAXCDNAME]; ++ char hname[MAXHOSTNAMELEN + 1]; ++ if (__ns_name_unpack (c.begin, c.end, ++ compressed_alias_name, ++ nbuf, sizeof (nbuf)) >= 0 ++ && __ns_name_ntop (nbuf, hname, sizeof (hname)) >= 0) ++ /* Space checking is performed by the callers. */ ++ ntup->name = alloc_buffer_copy_string (abuf, hname); ++ store_canon = false; ++ } ++ else ++ ntup->name = NULL; ++ if (rr.rdlength == 4) ++ ntup->family = AF_INET; ++ else ++ ntup->family = AF_INET6; ++ memcpy (ntup->addr, rr.rdata, rr.rdlength); ++ ntup->scopeid = 0; ++ ++ /* Link in the new tuple, and update the tail pointer to ++ point to its next field. */ ++ **tailp = ntup; ++ *tailp = &ntup->next; ++ ++ haveanswer = true; + } + } +- else +- { +- /* Skip unknown records. */ +- cp += n; +- continue; +- } +- +- assert (type == T_A || type == T_AAAA); +- if (*pat == NULL) +- { +- uintptr_t pad = (-(uintptr_t) buffer +- % __alignof__ (struct gaih_addrtuple)); +- buffer += pad; +- buflen = buflen > pad ? buflen - pad : 0; +- +- if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple))) +- goto too_small; +- +- *pat = (struct gaih_addrtuple *) buffer; +- buffer += sizeof (struct gaih_addrtuple); +- buflen -= sizeof (struct gaih_addrtuple); +- } +- +- (*pat)->name = NULL; +- (*pat)->next = NULL; +- +- if (*firstp) +- { +- /* We compose a single hostent out of the entire chain of +- entries, so the TTL of the hostent is essentially the lowest +- TTL in the chain. */ +- if (ttlp != NULL && ttl < *ttlp) +- *ttlp = ttl; +- +- (*pat)->name = canon ?: h_name; +- +- *firstp = 0; +- } +- +- (*pat)->family = type == T_A ? AF_INET : AF_INET6; +- memcpy ((*pat)->addr, cp, n); +- cp += n; +- (*pat)->scopeid = 0; +- +- pat = &((*pat)->next); +- +- haveanswer = 1; + } + + if (haveanswer) + { +- *patp = pat; +- *bufferp = buffer; +- *buflenp = buflen; +- + *h_errnop = NETDB_SUCCESS; + return NSS_STATUS_SUCCESS; + } +- +- /* Special case here: if the resolver sent a result but it only +- contains a CNAME while we are looking for a T_A or T_AAAA record, +- we fail with NOTFOUND instead of TRYAGAIN. */ +- if (canon != NULL) ++ else + { ++ /* Special case here: if the resolver sent a result but it only ++ contains a CNAME while we are looking for a T_A or T_AAAA ++ record, we fail with NOTFOUND. */ + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } +- +- *h_errnop = NETDB_INTERNAL; +- return NSS_STATUS_TRYAGAIN; + } + + + static enum nss_status +-gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, +- int anslen2, const char *qname, +- struct gaih_addrtuple **pat, char *buffer, size_t buflen, ++gaih_getanswer (unsigned char *packet1, size_t packet1len, ++ unsigned char *packet2, size_t packet2len, ++ struct alloc_buffer *abuf, struct gaih_addrtuple **pat, + int *errnop, int *h_errnop, int32_t *ttlp) + { +- int first = 1; +- + enum nss_status status = NSS_STATUS_NOTFOUND; + + /* Combining the NSS status of two distinct queries requires some +@@ -1157,7 +1046,10 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, + between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable). + A recoverable TRYAGAIN is almost always due to buffer size issues + and returns ERANGE in errno and the caller is expected to retry +- with a larger buffer. ++ with a larger buffer. (The caller, _nss_dns_gethostbyname4_r, ++ ignores the return status if it detects that the result buffer ++ has been exhausted and generates a TRYAGAIN failure with an ++ ERANGE code.) + + Lastly, you may be tempted to make significant changes to the + conditions in this code to bring about symmetry between responses. +@@ -1237,36 +1129,30 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, + is a recoverable error we now return TRYAGIN even if the first + response was SUCCESS. */ + +- if (anslen1 > 0) +- status = gaih_getanswer_slice(answer1, anslen1, qname, +- &pat, &buffer, &buflen, +- errnop, h_errnop, ttlp, +- &first); +- +- if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND +- || (status == NSS_STATUS_TRYAGAIN +- /* We want to look at the second answer in case of an +- NSS_STATUS_TRYAGAIN only if the error is non-recoverable, i.e. +- *h_errnop is NO_RECOVERY. If not, and if the failure was due to +- an insufficient buffer (ERANGE), then we need to drop the results +- and pass on the NSS_STATUS_TRYAGAIN to the caller so that it can +- repeat the query with a larger buffer. */ +- && (*errnop != ERANGE || *h_errnop == NO_RECOVERY))) +- && answer2 != NULL && anslen2 > 0) ++ if (packet1len > 0) + { +- enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname, +- &pat, &buffer, &buflen, +- errnop, h_errnop, ttlp, +- &first); ++ status = gaih_getanswer_slice (packet1, packet1len, ++ abuf, &pat, errnop, h_errnop, ttlp, true); ++ if (alloc_buffer_has_failed (abuf)) ++ /* Do not try parsing the second packet if a larger result ++ buffer is needed. The caller implements the resizing ++ protocol because *abuf has been exhausted. */ ++ return NSS_STATUS_TRYAGAIN; /* Ignored by the caller. */ ++ } ++ ++ if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND) ++ && packet2 != NULL && packet2len > 0) ++ { ++ enum nss_status status2 ++ = gaih_getanswer_slice (packet2, packet2len, ++ abuf, &pat, errnop, h_errnop, ttlp, ++ /* Success means that data with a ++ canonical name has already been ++ stored. Do not store the name again. */ ++ status != NSS_STATUS_SUCCESS); + /* Use the second response status in some cases. */ + if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND) + status = status2; +- /* Do not return a truncated second response (unless it was +- unavoidable e.g. unrecoverable TRYAGAIN). */ +- if (status == NSS_STATUS_SUCCESS +- && (status2 == NSS_STATUS_TRYAGAIN +- && *errnop == ERANGE && *h_errnop != NO_RECOVERY)) +- status = NSS_STATUS_TRYAGAIN; + } + + return status; +@@ -1274,18 +1160,13 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, + + /* Variant of gaih_getanswer without a second (AAAA) response. */ + static enum nss_status +-gaih_getanswer_noaaaa (const querybuf *answer1, int anslen1, const char *qname, +- struct gaih_addrtuple **pat, +- char *buffer, size_t buflen, ++gaih_getanswer_noaaaa (unsigned char *packet, size_t packetlen, ++ struct alloc_buffer *abuf, struct gaih_addrtuple **pat, + int *errnop, int *h_errnop, int32_t *ttlp) + { +- int first = 1; +- + enum nss_status status = NSS_STATUS_NOTFOUND; +- if (anslen1 > 0) +- status = gaih_getanswer_slice (answer1, anslen1, qname, +- &pat, &buffer, &buflen, +- errnop, h_errnop, ttlp, +- &first); ++ if (packetlen > 0) ++ status = gaih_getanswer_slice (packet, packetlen, ++ abuf, &pat, errnop, h_errnop, ttlp, true); + return status; + } diff --git a/SOURCES/glibc-rh2149102.patch b/SOURCES/glibc-rh2149102.patch new file mode 100644 index 0000000..6516cc0 --- /dev/null +++ b/SOURCES/glibc-rh2149102.patch @@ -0,0 +1,19 @@ +commit b8c6166b1b75036ab3e4127a1c0aacf52ca93651 +Author: Florian Weimer +Date: Mon Sep 6 19:43:37 2021 +0200 + + locale: Add missing second argument to _Static_assert in C-collate-seq.c + +diff --git a/locale/C-collate-seq.c b/locale/C-collate-seq.c +index 4fb82cb8357936b6..40b17f4f90313144 100644 +--- a/locale/C-collate-seq.c ++++ b/locale/C-collate-seq.c +@@ -55,7 +55,7 @@ static const char collseqmb[] = + + /* This table must be 256 bytes in size. We index bytes into the + table to find the collation sequence. */ +-_Static_assert (sizeof (collseqmb) == 256); ++_Static_assert (sizeof (collseqmb) == 256, "sizeof (collseqmb)"); + + static const uint32_t collseqwc[] = + { diff --git a/SOURCES/glibc-rh2162962.patch b/SOURCES/glibc-rh2162962.patch new file mode 100644 index 0000000..718d38c --- /dev/null +++ b/SOURCES/glibc-rh2162962.patch @@ -0,0 +1,306 @@ +Maintain an explicit order of tunables, so that the tunable_list +array and the tunable_id_t constant can remain consistent over time. + +Related to this upstream bug: + + Internal tunables ABI depends on awk array iteration order + + +The new dl-tunables.list files are already on the sysdeps search +path, which is why the existing Makeconfig rule picks them up. +The files for RHEL 9.1z were created by applying the gen-tunables.awk +part of this patch to RHEL 9.1.0 (glibc-2.34-40.el9_2.1, to be +precise). The sysdeps/unix/sysv/linux/**/dl-tunables.list files were +created based on the generated error message during the RHEL 9.1.z +build. + +Going forward, new tunables will have to be added manually to the end +of those files. Existing tunables should not be deleted. For +deletion, the script would have to be extended to be able to create +gaps in the tunable_list array. + +diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk +index fa63e86d1a51fe61..c5445e95f9fc36e7 100644 +--- a/scripts/gen-tunables.awk ++++ b/scripts/gen-tunables.awk +@@ -14,6 +14,7 @@ BEGIN { + top_ns="" + max_name_len=0 + max_alias_len=0 ++ tunable_order_count = 0 + } + + # Skip over blank lines and comments. +@@ -83,6 +84,37 @@ $1 == "}" { + next + } + ++$1 == "@order" { ++ if (top_ns != "") { ++ printf("%s:%d: error: invalid @order directive inside namespace %s\n", ++ FILENAME, FNR, top_ns) > "/dev/stderr" ++ exit 1 ++ } ++ if (NF != 2) { ++ printf("%s:%d: error: invalid argument count in @order directive\n", ++ FILENAME, FNR) > "/dev/stderr" ++ exit 1 ++ } ++ order_arg = $2 ++ if (split(order_arg, indices, /\./) != 3) { ++ printf("%s:%d: error: invalid tunable syntax in @order directive\n", ++ FILENAME, FNR) > "/dev/stderr" ++ exit 1 ++ } ++ t = indices[1] ++ n = indices[2] ++ m = indices[3] ++ if ((t, n, m) in tunable_order) { ++ printf("%s:%d: error: duplicate\"@order %s\"\n" \ ++ FILENAME, FNR, order_arg) > "/dev/stderr" ++ exit 1 ++ } ++ ++tunable_order_count ++ tunable_order[t,n,m] = tunable_order_count ++ tunable_order_list[tunable_order_count] = t SUBSEP n SUBSEP m ++ next ++} ++ + # Everything else, which could either be a tunable without any attributes or a + # tunable attribute. + { +@@ -145,6 +177,31 @@ END { + exit 1 + } + ++ missing_order = 0 ++ for (tnm in types) { ++ if (!(tnm in tunable_order)) { ++ if (!missing_order) { ++ print "error: Missing @order directives:" > "/dev/stderr" ++ missing_order = 1 ++ } ++ split(tnm, indices, SUBSEP) ++ printf("@order %s.%s.%s\n", indices[1], indices[2], indices[3]) \ ++ > "/dev/stderr" ++ } ++ } ++ for (i = 1; i <= tunable_order_count; ++i) { ++ tnm = tunable_order_list[i] ++ if (!(tnm in types)) { ++ split(tnm, indices, SUBSEP) ++ printf("error: tunable in \"@order %s.%s.%s\" not known\n", \ ++ indices[1], indices[2], indices[3]) > "/dev/stderr" ++ missing_order = 1 ++ } ++ } ++ if (missing_order) { ++ exit 1 ++ } ++ + print "/* AUTOGENERATED by gen-tunables.awk. */" + print "#ifndef _TUNABLES_H_" + print "# error \"Do not include this file directly.\"" +@@ -155,7 +212,8 @@ END { + # Now, the enum names + print "\ntypedef enum" + print "{" +- for (tnm in types) { ++ for (i = 1; i <= tunable_order_count; ++i) { ++ tnm = tunable_order_list[i] + split (tnm, indices, SUBSEP); + t = indices[1]; + n = indices[2]; +@@ -171,7 +229,8 @@ END { + print "# include \"dl-tunable-types.h\"" + # Finally, the tunable list. + print "static tunable_t tunable_list[] attribute_relro = {" +- for (tnm in types) { ++ for (i = 1; i <= tunable_order_count; ++i) { ++ tnm = tunable_order_list[i] + split (tnm, indices, SUBSEP); + t = indices[1]; + n = indices[2]; +diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list +new file mode 100644 +index 0000000000000000..d9d62499be4d67cb +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list +@@ -0,0 +1,28 @@ ++# Order of tunables in RHEL 9.1.z. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.pthread.rseq ++@order glibc.cpu.name ++@order glibc.mem.tagging ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.malloc.mxfast ++@order glibc.rtld.dynamic_sort ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.pthread.stack_cache_size ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.pthread.mutex_spin_count ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check +diff --git a/sysdeps/unix/sysv/linux/i386/dl-tunables.list b/sysdeps/unix/sysv/linux/i386/dl-tunables.list +new file mode 100644 +index 0000000000000000..e83962ec3af11691 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/i386/dl-tunables.list +@@ -0,0 +1,35 @@ ++# Order of tunables in RHEL 9.1.z. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.cpu.x86_shared_cache_size ++@order glibc.pthread.rseq ++@order glibc.mem.tagging ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.cpu.x86_rep_movsb_threshold ++@order glibc.malloc.mxfast ++@order glibc.rtld.dynamic_sort ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.cpu.x86_rep_stosb_threshold ++@order glibc.cpu.x86_non_temporal_threshold ++@order glibc.cpu.x86_shstk ++@order glibc.pthread.stack_cache_size ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.cpu.x86_ibt ++@order glibc.cpu.hwcaps ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.cpu.x86_data_cache_size ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.pthread.mutex_spin_count ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list +new file mode 100644 +index 0000000000000000..8f01840ef57874e7 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list +@@ -0,0 +1,28 @@ ++# Order of tunables in RHEL 9.1.z. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.pthread.rseq ++@order glibc.mem.tagging ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.malloc.mxfast ++@order glibc.rtld.dynamic_sort ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.pthread.stack_cache_size ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.cpu.cached_memopt ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.pthread.mutex_spin_count ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list +new file mode 100644 +index 0000000000000000..c3bc83f33910af22 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list +@@ -0,0 +1,27 @@ ++# Order of tunables in RHEL 9.1.z. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.pthread.rseq ++@order glibc.mem.tagging ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.malloc.mxfast ++@order glibc.rtld.dynamic_sort ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.pthread.stack_cache_size ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.pthread.mutex_spin_count ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list +new file mode 100644 +index 0000000000000000..e83962ec3af11691 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list +@@ -0,0 +1,35 @@ ++# Order of tunables in RHEL 9.1.z. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.cpu.x86_shared_cache_size ++@order glibc.pthread.rseq ++@order glibc.mem.tagging ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.cpu.x86_rep_movsb_threshold ++@order glibc.malloc.mxfast ++@order glibc.rtld.dynamic_sort ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.cpu.x86_rep_stosb_threshold ++@order glibc.cpu.x86_non_temporal_threshold ++@order glibc.cpu.x86_shstk ++@order glibc.pthread.stack_cache_size ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.cpu.x86_ibt ++@order glibc.cpu.hwcaps ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.cpu.x86_data_cache_size ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.pthread.mutex_spin_count ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check 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-upstream-2.34-1.patch b/SOURCES/glibc-upstream-2.34-1.patch new file mode 100644 index 0000000..c161318 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-1.patch @@ -0,0 +1,26 @@ +commit 0b03996304f86d6dba8f0d4b7048b9bb7186f17d +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:10:10 2021 +0530 + + ldconfig: avoid leak on empty paths in config file + + Reviewed-by: Arjun Shankar + (cherry picked from commit b0234d79e7d82475d1666f25326ec045c045b3ed) + +diff --git a/elf/ldconfig.c b/elf/ldconfig.c +index 1037e8d0cf8d28b6..b8893637f8aaea8d 100644 +--- a/elf/ldconfig.c ++++ b/elf/ldconfig.c +@@ -503,7 +503,11 @@ add_dir_1 (const char *line, const char *from_file, int from_line) + entry->path[--i] = '\0'; + + if (i == 0) +- return; ++ { ++ free (entry->path); ++ free (entry); ++ return; ++ } + + char *path = entry->path; + if (opt_chroot != NULL) diff --git a/SOURCES/glibc-upstream-2.34-10.patch b/SOURCES/glibc-upstream-2.34-10.patch new file mode 100644 index 0000000..023ea30 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-10.patch @@ -0,0 +1,34 @@ +commit f2413f2710d5d5cc884b413b83fcf8198e3717fa +Author: H.J. Lu +Date: Sat Aug 28 06:10:38 2021 -0700 + + x86-64: Use testl to check __x86_string_control + + Use testl, instead of andl, to check __x86_string_control to avoid + updating __x86_string_control. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit 3c8b9879cab6d41787bc5b14c1748f62fd6d0e5f) + +diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +index 9f02624375c07b26..abde8438d41f2320 100644 +--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +@@ -325,7 +325,7 @@ L(movsb): + /* Avoid slow backward REP MOVSB. */ + jb L(more_8x_vec_backward) + # if AVOID_SHORT_DISTANCE_REP_MOVSB +- andl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) ++ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) + jz 3f + movq %rdi, %rcx + subq %rsi, %rcx +@@ -333,7 +333,7 @@ L(movsb): + # endif + 1: + # if AVOID_SHORT_DISTANCE_REP_MOVSB +- andl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) ++ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) + jz 3f + movq %rsi, %rcx + subq %rdi, %rcx diff --git a/SOURCES/glibc-upstream-2.34-100.patch b/SOURCES/glibc-upstream-2.34-100.patch new file mode 100644 index 0000000..d797f77 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-100.patch @@ -0,0 +1,95 @@ +commit e09e7b1492b2d5c2f68ddf81f8f58e093dd4df6d +Author: Adhemerval Zanella +Date: Mon Dec 13 11:36:42 2021 -0300 + + support: Add support_socket_so_timestamp_time64 + + Check if the socket support 64-bit network packages timestamps + (SO_TIMESTAMP and SO_TIMESTAMPNS). This will be used on recvmsg + and recvmmsg tests to check if the timestamp should be generated. + + Reviewed-by: Florian Weimer + + (cherry picked from 38bc0f4e78934aab455b31af05cefcbf3c22bece) + +diff --git a/support/Makefile b/support/Makefile +index 3c941e1ba9e29aa4..6a5fc9faf2ca2e2d 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -79,6 +79,7 @@ libsupport-routines = \ + support_set_small_thread_stack_size \ + support_shared_allocate \ + support_small_stack_thread_attribute \ ++ support_socket_so_timestamp_time64 \ + support_stat_nanoseconds \ + support_subprocess \ + support_test_compare_blob \ +diff --git a/support/support.h b/support/support.h +index 29d56c7c891ee34b..ecfc9a336d272a30 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -170,6 +170,10 @@ extern bool support_select_modifies_timeout (void); + tv_usec larger than 1000000. */ + extern bool support_select_normalizes_timeout (void); + ++/* Return true if socket FD supports 64-bit timestamps with the SOL_SOCKET ++ and SO_TIMESTAMP/SO_TIMESTAMPNS. */ ++extern bool support_socket_so_timestamp_time64 (int fd); ++ + /* Create a timer that trigger after SEC seconds and NSEC nanoseconds. If + REPEAT is true the timer will repeat indefinitely. If CALLBACK is not + NULL, the function will be called when the timer expires; otherwise a +diff --git a/support/support_socket_so_timestamp_time64.c b/support/support_socket_so_timestamp_time64.c +new file mode 100644 +index 0000000000000000..54bf3f42724566f5 +--- /dev/null ++++ b/support/support_socket_so_timestamp_time64.c +@@ -0,0 +1,48 @@ ++/* Return whether socket supports 64-bit timestamps. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#ifdef __linux__ ++# include ++#endif ++ ++bool ++support_socket_so_timestamp_time64 (int fd) ++{ ++#ifdef __linux__ ++# if __LINUX_KERNEL_VERSION >= 0x050100 \ ++ || __WORDSIZE == 64 \ ++ || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) ++ return true; ++# else ++ int level = SOL_SOCKET; ++ int optname = COMPAT_SO_TIMESTAMP_NEW; ++ int optval; ++ socklen_t len = sizeof (optval); ++ ++ int r = syscall (__NR_getsockopt, fd, level, optname, &optval, &len); ++ return r != -1; ++# endif ++#else ++ return false; ++#endif ++} diff --git a/SOURCES/glibc-upstream-2.34-101.patch b/SOURCES/glibc-upstream-2.34-101.patch new file mode 100644 index 0000000..b318a81 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-101.patch @@ -0,0 +1,431 @@ +commit e098446037da532d4a250efac9a813bc22f3669f +Author: Adhemerval Zanella +Date: Mon Jan 24 08:55:53 2022 -0300 + + linux: Fix ancillary 64-bit time timestamp conversion (BZ #28349, BZ#28350) + + The __convert_scm_timestamps only updates the control message last + pointer for SOL_SOCKET type, so if the message control buffer contains + multiple ancillary message types the converted timestamp one might + overwrite a valid message. + + The test checks if the extra ancillary space is correctly handled + by recvmsg/recvmmsg, where if there is no extra space for the 64-bit + time_t converted message the control buffer should be marked with + MSG_TRUNC. It also check if recvmsg/recvmmsg handle correctly multiple + ancillary data. + + Checked on x86_64-linux and on i686-linux-gnu on both 5.11 and + 4.15 kernel. + + Co-authored-by: Fabian Vogt + + Reviewed-by: Florian Weimer + + (cherry picked from commit 8fba672472ae0055387e9315fc2eddfa6775ca79) + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index cdc01a3f023ec09a..7c75e22c6d0e9ff5 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -273,6 +273,9 @@ sysdep_routines += cmsg_nxthdr + CFLAGS-recvmmsg.c = -fexceptions -fasynchronous-unwind-tables + CFLAGS-sendmmsg.c = -fexceptions -fasynchronous-unwind-tables + ++tests += tst-socket-timestamp ++tests-time64 += tst-socket-timestamp-time64 ++ + tests-special += $(objpfx)tst-socket-consts.out + $(objpfx)tst-socket-consts.out: ../sysdeps/unix/sysv/linux/tst-socket-consts.py + PYTHONPATH=../scripts \ +diff --git a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c +index 00c934c4135f0d42..5d3c4199e0b32944 100644 +--- a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c ++++ b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c +@@ -54,6 +54,8 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize) + cmsg != NULL; + cmsg = CMSG_NXTHDR (msg, cmsg)) + { ++ last = cmsg; ++ + if (cmsg->cmsg_level != SOL_SOCKET) + continue; + +@@ -75,11 +77,9 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize) + tvts[1] = tmp[1]; + break; + } +- +- last = cmsg; + } + +- if (last == NULL || type == 0) ++ if (type == 0) + return; + + if (CMSG_SPACE (sizeof tvts) > msgsize - msg->msg_controllen) +@@ -88,10 +88,12 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize) + return; + } + ++ /* Zero memory for the new cmsghdr, so reading cmsg_len field ++ by CMSG_NXTHDR does not trigger UB. */ ++ memset (msg->msg_control + msg->msg_controllen, 0, ++ CMSG_SPACE (sizeof tvts)); + msg->msg_controllen += CMSG_SPACE (sizeof tvts); +- cmsg = CMSG_NXTHDR(msg, last); +- if (cmsg == NULL) +- return; ++ cmsg = CMSG_NXTHDR (msg, last); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = type; + cmsg->cmsg_len = CMSG_LEN (sizeof tvts); +diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-time64.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-time64.c +new file mode 100644 +index 0000000000000000..ae424c2a70026cf5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-time64.c +@@ -0,0 +1 @@ ++#include "tst-socket-timestamp.c" +diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp.c +new file mode 100644 +index 0000000000000000..9c2e76f7e27bd312 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp.c +@@ -0,0 +1,336 @@ ++/* Check recvmsg/recvmmsg 64-bit timestamp support. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Some extra space added for ancillary data, it might be used to convert ++ 32-bit timestamp to 64-bit for _TIME_BITS=64. */ ++enum { slack_max_size = 64 }; ++static const int slack[] = { 0, 4, 8, 16, 32, slack_max_size }; ++ ++static bool support_64_timestamp; ++/* AF_INET socket and address used to receive data. */ ++static int srv; ++static struct sockaddr_in srv_addr; ++ ++static int ++do_sendto (const struct sockaddr_in *addr, int nmsgs) ++{ ++ int s = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); ++ xconnect (s, (const struct sockaddr *) addr, sizeof (*addr)); ++ ++ for (int i = 0; i < nmsgs; i++) ++ xsendto (s, &i, sizeof (i), 0, (const struct sockaddr *) addr, ++ sizeof (*addr)); ++ ++ xclose (s); ++ ++ return 0; ++} ++ ++static void ++do_recvmsg_slack_ancillary (bool use_multi_call, int s, void *cmsg, ++ size_t slack, size_t tsize, int exp_payload) ++{ ++ int payload; ++ struct iovec iov = ++ { ++ .iov_base = &payload, ++ .iov_len = sizeof (payload) ++ }; ++ size_t msg_controllen = CMSG_SPACE (tsize) + slack; ++ char *msg_control = cmsg - msg_controllen; ++ memset (msg_control, 0x55, msg_controllen); ++ struct mmsghdr mmhdr = ++ { ++ .msg_hdr = ++ { ++ .msg_name = NULL, ++ .msg_namelen = 0, ++ .msg_iov = &iov, ++ .msg_iovlen = 1, ++ .msg_control = msg_control, ++ .msg_controllen = msg_controllen ++ }, ++ }; ++ ++ int r; ++ if (use_multi_call) ++ { ++ r = recvmmsg (s, &mmhdr, 1, 0, NULL); ++ if (r >= 0) ++ r = mmhdr.msg_len; ++ } ++ else ++ r = recvmsg (s, &mmhdr.msg_hdr, 0); ++ TEST_COMPARE (r, sizeof (int)); ++ TEST_COMPARE (payload, exp_payload); ++ ++ if (cmsg == NULL) ++ return; ++ ++ /* A timestamp is expected if 32-bit timestamp are used (support in every ++ configuration) or if underlying kernel support 64-bit timestamps. ++ Otherwise recvmsg will need extra space do add the 64-bit timestamp. */ ++ bool exp_timestamp; ++ if (sizeof (time_t) == 4 || support_64_timestamp) ++ exp_timestamp = true; ++ else ++ exp_timestamp = slack >= CMSG_SPACE (tsize); ++ ++ bool timestamp = false; ++ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr); ++ cmsg != NULL; ++ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg)) ++ { ++ if (cmsg->cmsg_level != SOL_SOCKET) ++ continue; ++ if (cmsg->cmsg_type == SCM_TIMESTAMP ++ && cmsg->cmsg_len == CMSG_LEN (sizeof (struct timeval))) ++ { ++ struct timeval tv; ++ memcpy (&tv, CMSG_DATA (cmsg), sizeof (tv)); ++ if (test_verbose) ++ printf ("SCM_TIMESTAMP: {%jd, %jd}\n", (intmax_t)tv.tv_sec, ++ (intmax_t)tv.tv_usec); ++ timestamp = true; ++ } ++ else if (cmsg->cmsg_type == SCM_TIMESTAMPNS ++ && cmsg->cmsg_len == CMSG_LEN (sizeof (struct timespec))) ++ { ++ struct timespec ts; ++ memcpy (&ts, CMSG_DATA (cmsg), sizeof (ts)); ++ if (test_verbose) ++ printf ("SCM_TIMESTAMPNS: {%jd, %jd}\n", (intmax_t)ts.tv_sec, ++ (intmax_t)ts.tv_nsec); ++ timestamp = true; ++ } ++ } ++ ++ TEST_COMPARE (timestamp, exp_timestamp); ++} ++ ++/* Check if the extra ancillary space is correctly handled by recvmsg and ++ recvmmsg with different extra space for the ancillaty buffer. */ ++static void ++do_test_slack_space (void) ++{ ++ /* Setup the ancillary data buffer with an extra page with PROT_NONE to ++ check the possible timestamp conversion on some systems. */ ++ struct support_next_to_fault nf = ++ support_next_to_fault_allocate (slack_max_size); ++ void *msgbuf = nf.buffer + slack_max_size; ++ ++ /* Enable the timestamp using struct timeval precision. */ ++ { ++ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP, &(int){1}, ++ sizeof (int)); ++ TEST_VERIFY_EXIT (r != -1); ++ } ++ /* Check recvmsg. */ ++ do_sendto (&srv_addr, array_length (slack)); ++ for (int s = 0; s < array_length (slack); s++) ++ { ++ memset (nf.buffer, 0x55, nf.length); ++ do_recvmsg_slack_ancillary (false, srv, msgbuf, slack[s], ++ sizeof (struct timeval), s); ++ } ++ /* Check recvmmsg. */ ++ do_sendto (&srv_addr, array_length (slack)); ++ for (int s = 0; s < array_length (slack); s++) ++ { ++ memset (nf.buffer, 0x55, nf.length); ++ do_recvmsg_slack_ancillary (true, srv, msgbuf, slack[s], ++ sizeof (struct timeval), s); ++ } ++ ++ /* Now enable timestamp using a higher precision, it overwrites the previous ++ precision. */ ++ { ++ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMPNS, &(int){1}, ++ sizeof (int)); ++ TEST_VERIFY_EXIT (r != -1); ++ } ++ /* Check recvmsg. */ ++ do_sendto (&srv_addr, array_length (slack)); ++ for (int s = 0; s < array_length (slack); s++) ++ do_recvmsg_slack_ancillary (false, srv, msgbuf, slack[s], ++ sizeof (struct timespec), s); ++ /* Check recvmmsg. */ ++ do_sendto (&srv_addr, array_length (slack)); ++ for (int s = 0; s < array_length (slack); s++) ++ do_recvmsg_slack_ancillary (true, srv, msgbuf, slack[s], ++ sizeof (struct timespec), s); ++ ++ support_next_to_fault_free (&nf); ++} ++ ++/* Check if the converted 64-bit timestamp is correctly appended when there ++ are multiple ancillary messages. */ ++static void ++do_recvmsg_multiple_ancillary (bool use_multi_call, int s, void *cmsg, ++ size_t cmsgsize, int exp_msg) ++{ ++ int msg; ++ struct iovec iov = ++ { ++ .iov_base = &msg, ++ .iov_len = sizeof (msg) ++ }; ++ size_t msgs = cmsgsize; ++ struct mmsghdr mmhdr = ++ { ++ .msg_hdr = ++ { ++ .msg_name = NULL, ++ .msg_namelen = 0, ++ .msg_iov = &iov, ++ .msg_iovlen = 1, ++ .msg_controllen = msgs, ++ .msg_control = cmsg, ++ }, ++ }; ++ ++ int r; ++ if (use_multi_call) ++ { ++ r = recvmmsg (s, &mmhdr, 1, 0, NULL); ++ if (r >= 0) ++ r = mmhdr.msg_len; ++ } ++ else ++ r = recvmsg (s, &mmhdr.msg_hdr, 0); ++ TEST_COMPARE (r, sizeof (int)); ++ TEST_COMPARE (msg, exp_msg); ++ ++ if (cmsg == NULL) ++ return; ++ ++ bool timestamp = false; ++ bool origdstaddr = false; ++ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr); ++ cmsg != NULL; ++ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg)) ++ { ++ if (cmsg->cmsg_level == SOL_IP ++ && cmsg->cmsg_type == IP_ORIGDSTADDR ++ && cmsg->cmsg_len >= CMSG_LEN (sizeof (struct sockaddr_in))) ++ { ++ struct sockaddr_in sa; ++ memcpy (&sa, CMSG_DATA (cmsg), sizeof (sa)); ++ if (test_verbose) ++ { ++ char str[INET_ADDRSTRLEN]; ++ inet_ntop (AF_INET, &sa.sin_addr, str, INET_ADDRSTRLEN); ++ printf ("IP_ORIGDSTADDR: %s:%d\n", str, ntohs (sa.sin_port)); ++ } ++ origdstaddr = sa.sin_addr.s_addr == srv_addr.sin_addr.s_addr ++ && sa.sin_port == srv_addr.sin_port; ++ } ++ if (cmsg->cmsg_level == SOL_SOCKET ++ && cmsg->cmsg_type == SCM_TIMESTAMP ++ && cmsg->cmsg_len >= CMSG_LEN (sizeof (struct timeval))) ++ { ++ struct timeval tv; ++ memcpy (&tv, CMSG_DATA (cmsg), sizeof (tv)); ++ if (test_verbose) ++ printf ("SCM_TIMESTAMP: {%jd, %jd}\n", (intmax_t)tv.tv_sec, ++ (intmax_t)tv.tv_usec); ++ timestamp = true; ++ } ++ } ++ ++ TEST_COMPARE (timestamp, true); ++ TEST_COMPARE (origdstaddr, true); ++} ++ ++static void ++do_test_multiple_ancillary (void) ++{ ++ { ++ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP, &(int){1}, ++ sizeof (int)); ++ TEST_VERIFY_EXIT (r != -1); ++ } ++ { ++ int r = setsockopt (srv, IPPROTO_IP, IP_RECVORIGDSTADDR, &(int){1}, ++ sizeof (int)); ++ TEST_VERIFY_EXIT (r != -1); ++ } ++ ++ /* Enougth data for default SO_TIMESTAMP, the IP_RECVORIGDSTADDR, and the ++ extra 64-bit SO_TIMESTAMP. */ ++ enum { msgbuflen = CMSG_SPACE (2 * sizeof (uint64_t)) ++ + CMSG_SPACE (sizeof (struct sockaddr_in)) ++ + CMSG_SPACE (2 * sizeof (uint64_t)) }; ++ char msgbuf[msgbuflen]; ++ ++ enum { nmsgs = 8 }; ++ /* Check recvmsg. */ ++ do_sendto (&srv_addr, nmsgs); ++ for (int s = 0; s < nmsgs; s++) ++ do_recvmsg_multiple_ancillary (false, srv, msgbuf, msgbuflen, s); ++ /* Check recvmmsg. */ ++ do_sendto (&srv_addr, nmsgs); ++ for (int s = 0; s < nmsgs; s++) ++ do_recvmsg_multiple_ancillary (true, srv, msgbuf, msgbuflen, s); ++} ++ ++static int ++do_test (void) ++{ ++ srv = xsocket (AF_INET, SOCK_DGRAM, 0); ++ srv_addr = (struct sockaddr_in) { ++ .sin_family = AF_INET, ++ .sin_addr = {.s_addr = htonl (INADDR_LOOPBACK) }, ++ }; ++ xbind (srv, (struct sockaddr *) &srv_addr, sizeof (srv_addr)); ++ { ++ socklen_t sa_len = sizeof (srv_addr); ++ xgetsockname (srv, (struct sockaddr *) &srv_addr, &sa_len); ++ TEST_VERIFY (sa_len == sizeof (srv_addr)); ++ } ++ ++ TEST_COMPARE (recvmsg (-1, NULL, 0), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (recvmmsg (-1, NULL, 0, 0, NULL), -1); ++ TEST_COMPARE (errno, EBADF); ++ ++ /* If underlying kernel does not support */ ++ support_64_timestamp = support_socket_so_timestamp_time64 (srv); ++ ++ do_test_slack_space (); ++ do_test_multiple_ancillary (); ++ ++ xclose (srv); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-102.patch b/SOURCES/glibc-upstream-2.34-102.patch new file mode 100644 index 0000000..928856e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-102.patch @@ -0,0 +1,485 @@ +commit 489d0b8b32548bc569cd3067aebf98b030720753 +Author: Adhemerval Zanella +Date: Thu Jan 27 16:45:18 2022 -0300 + + Linux: Only generate 64 bit timestamps for 64 bit time_t recvmsg/recvmmsg + + The timestamps created by __convert_scm_timestamps only make sense for + 64 bit time_t programs, 32 bit time_t programs will ignore 64 bit time_t + timestamps since SO_TIMESTAMP will be defined to old values (either by + glibc or kernel headers). + + Worse, if the buffer is not suffice MSG_CTRUNC is set to indicate it + (which breaks some programs [1]). + + This patch makes only 64 bit time_t recvmsg and recvmmsg to call + __convert_scm_timestamps. Also, the assumption to called it is changed + from __ASSUME_TIME64_SYSCALLS to __TIMESIZE != 64 since the setsockopt + might be called by libraries built without __TIME_BITS=64. The + MSG_CTRUNC is only set for the 64 bit symbols, it should happen only + if 64 bit time_t programs run older kernels. + + Checked on x86_64-linux-gnu and i686-linux-gnu. + + [1] https://github.com/systemd/systemd/pull/20567 + + Reviewed-by: Florian Weimer + + (cherry picked from commit 948ce73b31fdb0860bcec4b8e62b14e88234f98a) + +diff --git a/include/sys/socket.h b/include/sys/socket.h +index a1d749f9fa7b9257..6e4cf5077fb885a9 100644 +--- a/include/sys/socket.h ++++ b/include/sys/socket.h +@@ -98,15 +98,21 @@ extern int __sendmmsg (int __fd, struct mmsghdr *__vmessages, + libc_hidden_proto (__sendmmsg) + #endif + +-/* Receive a message as described by MESSAGE from socket FD. +- Returns the number of bytes read or -1 for errors. */ + extern ssize_t __libc_recvmsg (int __fd, struct msghdr *__message, + int __flags); + extern ssize_t __recvmsg (int __fd, struct msghdr *__message, + int __flags) attribute_hidden; + #if __TIMESIZE == 64 ++# define __libc_recvmsg64 __libc_recvmsg ++# define __recvmsg64 __recvmsg + # define __recvmmsg64 __recvmmsg + #else ++extern ssize_t __libc_recvmsg64 (int __fd, struct msghdr *__message, ++ int __flags); ++extern ssize_t __recvmsg64 (int __fd, struct msghdr *__message, ++ int __flags); ++/* Receive a message as described by MESSAGE from socket FD. ++ Returns the number of bytes read or -1 for errors. */ + extern int __recvmmsg64 (int __fd, struct mmsghdr *vmessages, + unsigned int vlen, int flags, + struct __timespec64 *timeout); +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 7c75e22c6d0e9ff5..0657f4003e7116c6 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -273,8 +273,14 @@ sysdep_routines += cmsg_nxthdr + CFLAGS-recvmmsg.c = -fexceptions -fasynchronous-unwind-tables + CFLAGS-sendmmsg.c = -fexceptions -fasynchronous-unwind-tables + +-tests += tst-socket-timestamp +-tests-time64 += tst-socket-timestamp-time64 ++tests += \ ++ tst-socket-timestamp \ ++ tst-socket-timestamp-compat \ ++ # tests ++tests-time64 += \ ++ tst-socket-timestamp-time64 \ ++ tst-socket-timestamp-compat-time64 ++ # tests-time64 + + tests-special += $(objpfx)tst-socket-consts.out + $(objpfx)tst-socket-consts.out: ../sysdeps/unix/sysv/linux/tst-socket-consts.py +diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c +index 5cd107ffa9be0699..fca9f6582db67fd7 100644 +--- a/sysdeps/unix/sysv/linux/recvmmsg.c ++++ b/sysdeps/unix/sysv/linux/recvmmsg.c +@@ -20,9 +20,9 @@ + #include + #include + +-int +-__recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, +- struct __timespec64 *timeout) ++static int ++recvmmsg_syscall (int fd, struct mmsghdr *vmessages, unsigned int vlen, ++ int flags, struct __timespec64 *timeout) + { + #ifndef __NR_recvmmsg_time64 + # define __NR_recvmmsg_time64 __NR_recvmmsg +@@ -45,12 +45,6 @@ __recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, + pts32 = &ts32; + } + +- socklen_t csize[IOV_MAX]; +- if (vlen > IOV_MAX) +- vlen = IOV_MAX; +- for (int i = 0; i < vlen; i++) +- csize[i] = vmessages[i].msg_hdr.msg_controllen; +- + # ifdef __ASSUME_RECVMMSG_SYSCALL + r = SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32); + # else +@@ -60,11 +54,31 @@ __recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, + { + if (timeout != NULL) + *timeout = valid_timespec_to_timespec64 (ts32); ++ } ++#endif ++ return r; ++} ++ ++int ++__recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, ++ struct __timespec64 *timeout) ++{ ++#if __TIMESIZE != 64 ++ socklen_t csize[IOV_MAX]; ++ if (vlen > IOV_MAX) ++ vlen = IOV_MAX; ++ for (int i = 0; i < vlen; i++) ++ csize[i] = vmessages[i].msg_hdr.msg_controllen; ++#endif + ++ int r = recvmmsg_syscall (fd, vmessages, vlen, flags, timeout); ++#if __TIMESIZE != 64 ++ if (r > 0) ++ { + for (int i=0; i < r; i++) + __convert_scm_timestamps (&vmessages[i].msg_hdr, csize[i]); + } +-#endif /* __ASSUME_TIME64_SYSCALLS */ ++#endif + return r; + } + #if __TIMESIZE != 64 +@@ -80,7 +94,7 @@ __recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, + ts64 = valid_timespec_to_timespec64 (*timeout); + pts64 = &ts64; + } +- int r = __recvmmsg64 (fd, vmessages, vlen, flags, pts64); ++ int r = recvmmsg_syscall (fd, vmessages, vlen, flags, pts64); + if (r >= 0 && timeout != NULL) + /* The remanining timeout will be always less the input TIMEOUT. */ + *timeout = valid_timespec64_to_timespec (ts64); +diff --git a/sysdeps/unix/sysv/linux/recvmsg.c b/sysdeps/unix/sysv/linux/recvmsg.c +index 07212f7c8641a921..c4b4704fd65d80c1 100644 +--- a/sysdeps/unix/sysv/linux/recvmsg.c ++++ b/sysdeps/unix/sysv/linux/recvmsg.c +@@ -20,29 +20,41 @@ + #include + #include + ++static int ++__recvmsg_syscall (int fd, struct msghdr *msg, int flags) ++{ ++#ifdef __ASSUME_RECVMSG_SYSCALL ++ return SYSCALL_CANCEL (recvmsg, fd, msg, flags); ++#else ++ return SOCKETCALL_CANCEL (recvmsg, fd, msg, flags); ++#endif ++} ++ + ssize_t +-__libc_recvmsg (int fd, struct msghdr *msg, int flags) ++__libc_recvmsg64 (int fd, struct msghdr *msg, int flags) + { + ssize_t r; +-#ifndef __ASSUME_TIME64_SYSCALLS ++#if __TIMESIZE != 64 + socklen_t orig_controllen = msg != NULL ? msg->msg_controllen : 0; + #endif + +-#ifdef __ASSUME_RECVMSG_SYSCALL +- r = SYSCALL_CANCEL (recvmsg, fd, msg, flags); +-#else +- r = SOCKETCALL_CANCEL (recvmsg, fd, msg, flags); +-#endif ++ r = __recvmsg_syscall (fd, msg, flags); + +-#ifndef __ASSUME_TIME64_SYSCALLS ++#if __TIMESIZE != 64 + if (r >= 0 && orig_controllen != 0) + __convert_scm_timestamps (msg, orig_controllen); + #endif + + return r; + } +-weak_alias (__libc_recvmsg, recvmsg) +-weak_alias (__libc_recvmsg, __recvmsg) + #if __TIMESIZE != 64 +-weak_alias (__recvmsg, __recvmsg64) ++weak_alias (__libc_recvmsg64, __recvmsg64) ++ ++ssize_t ++__libc_recvmsg (int fd, struct msghdr *msg, int flags) ++{ ++ return __recvmsg_syscall (fd, msg, flags); ++} + #endif ++weak_alias (__libc_recvmsg, recvmsg) ++weak_alias (__libc_recvmsg, __recvmsg) +diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat-time64.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat-time64.c +new file mode 100644 +index 0000000000000000..96a0bef0bf4a908b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat-time64.c +@@ -0,0 +1 @@ ++#include "tst-socket-timestamp-compat.c" +diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c +new file mode 100644 +index 0000000000000000..de261dae5a6385cf +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c +@@ -0,0 +1,265 @@ ++/* Check recvmsg/recvmmsg 64-bit timestamp support. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* AF_INET socket and address used to receive data. */ ++static int srv; ++static struct sockaddr_in srv_addr; ++ ++static int ++do_sendto (const struct sockaddr_in *addr, int payload) ++{ ++ int s = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); ++ xconnect (s, (const struct sockaddr *) addr, sizeof (*addr)); ++ ++ xsendto (s, &payload, sizeof (payload), 0, (const struct sockaddr *) addr, ++ sizeof (*addr)); ++ ++ xclose (s); ++ ++ return 0; ++} ++ ++static void ++do_recvmsg_ancillary (bool use_multi_call, struct mmsghdr *mmhdr, ++ void *msgbuf, size_t msgbuflen, int exp_payload) ++{ ++ int payload; ++ struct iovec iov = ++ { ++ .iov_base = &payload, ++ .iov_len = sizeof (payload) ++ }; ++ mmhdr->msg_hdr.msg_name = NULL; ++ mmhdr->msg_hdr.msg_iov = &iov; ++ mmhdr->msg_hdr.msg_iovlen = 1; ++ mmhdr->msg_hdr.msg_control = msgbuf; ++ mmhdr->msg_hdr.msg_controllen = msgbuflen; ++ ++ int r; ++ if (use_multi_call) ++ { ++ r = recvmmsg (srv, mmhdr, 1, 0, NULL); ++ if (r >= 0) ++ r = mmhdr->msg_len; ++ } ++ else ++ r = recvmsg (srv, &mmhdr->msg_hdr, 0); ++ TEST_COMPARE (r, sizeof (int)); ++ TEST_COMPARE (payload, exp_payload); ++} ++ ++/* Check if recvmsg create the additional 64 bit timestamp if only 32 bit ++ is enabled for 64 bit recvmsg symbol. */ ++static void ++do_test_large_buffer (bool mc) ++{ ++ struct mmsghdr mmhdr = { 0 }; ++ /* It should be large enought for either timeval/timespec and the ++ 64 time type as well. */ ++ ++ union ++ { ++ struct cmsghdr cmsghdr; ++ char msgbuf[512]; ++ } control; ++ ++ /* Enable 32 bit timeval precision and check if no 64 bit timeval stamp ++ is created. */ ++ { ++ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP_OLD, &(int){1}, ++ sizeof (int)); ++ TEST_VERIFY_EXIT (r != -1); ++ ++ do_sendto (&srv_addr, 42); ++ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42); ++ ++ bool found_timestamp = false; ++ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr); ++ cmsg != NULL; ++ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg)) ++ { ++ if (cmsg->cmsg_level != SOL_SOCKET) ++ continue; ++ ++ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMP_NEW) ++ found_timestamp = true; ++ else ++ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMP_NEW); ++ } ++ ++ TEST_COMPARE (found_timestamp, sizeof (time_t) > 4); ++ } ++ ++ /* Same as before, but for timespec. */ ++ { ++ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMPNS_OLD, &(int){1}, ++ sizeof (int)); ++ TEST_VERIFY_EXIT (r != -1); ++ ++ do_sendto (&srv_addr, 42); ++ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42); ++ ++ bool found_timestamp = false; ++ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr); ++ cmsg != NULL; ++ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg)) ++ { ++ if (cmsg->cmsg_level != SOL_SOCKET) ++ continue; ++ ++ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMPNS_NEW) ++ found_timestamp = true; ++ else ++ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMPNS_NEW); ++ } ++ ++ TEST_COMPARE (found_timestamp, sizeof (time_t) > 4); ++ } ++} ++ ++/* Check if recvmsg does not create the additional 64 bit timestamp if ++ only 32 bit timestamp is enabled if the ancillary buffer is not large ++ enought. Also checks if MSG_CTRUNC is set iff for 64 bit recvmsg ++ symbol. */ ++static void ++do_test_small_buffer (bool mc) ++{ ++ struct mmsghdr mmhdr = { 0 }; ++ ++ /* Enable 32 bit timeval precision and check if no 64 bit timeval stamp ++ is created. */ ++ { ++ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP_OLD, &(int){1}, ++ sizeof (int)); ++ TEST_VERIFY_EXIT (r != -1); ++ ++ union ++ { ++ struct cmsghdr cmsghdr; ++ char msgbuf[CMSG_SPACE (sizeof (struct timeval))]; ++ } control; ++ ++ do_sendto (&srv_addr, 42); ++ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42); ++ ++ bool found_timestamp = false; ++ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr); ++ cmsg != NULL; ++ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg)) ++ { ++ if (cmsg->cmsg_level != SOL_SOCKET) ++ continue; ++ ++ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMP_NEW) ++ found_timestamp = true; ++ else ++ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMP_NEW); ++ } ++ ++ if (sizeof (time_t) > 4) ++ { ++ TEST_VERIFY ((mmhdr.msg_hdr.msg_flags & MSG_CTRUNC)); ++ TEST_COMPARE (found_timestamp, 0); ++ } ++ else ++ { ++ TEST_VERIFY (!(mmhdr.msg_hdr.msg_flags & MSG_CTRUNC)); ++ TEST_COMPARE (found_timestamp, 0); ++ } ++ } ++ ++ /* Same as before, but for timespec. */ ++ { ++ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMPNS_OLD, &(int){1}, ++ sizeof (int)); ++ TEST_VERIFY_EXIT (r != -1); ++ ++ union ++ { ++ struct cmsghdr cmsghdr; ++ char msgbuf[CMSG_SPACE (sizeof (struct timespec))]; ++ } control; ++ ++ do_sendto (&srv_addr, 42); ++ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42); ++ ++ bool found_timestamp = false; ++ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr); ++ cmsg != NULL; ++ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg)) ++ { ++ if (cmsg->cmsg_level != SOL_SOCKET) ++ continue; ++ ++ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMPNS_NEW) ++ found_timestamp = true; ++ else ++ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMPNS_NEW); ++ } ++ ++ if (sizeof (time_t) > 4) ++ { ++ TEST_VERIFY ((mmhdr.msg_hdr.msg_flags & MSG_CTRUNC)); ++ TEST_COMPARE (found_timestamp, 0); ++ } ++ else ++ { ++ TEST_VERIFY ((mmhdr.msg_hdr.msg_flags & MSG_CTRUNC) == 0); ++ TEST_COMPARE (found_timestamp, 0); ++ } ++ } ++} ++ ++static int ++do_test (void) ++{ ++ /* This test only make sense for ABIs that support 32 bit time_t socket ++ timestampss. */ ++ if (sizeof (time_t) > 4 && __WORDSIZE == 64) ++ return 0; ++ ++ srv = xsocket (AF_INET, SOCK_DGRAM, 0); ++ srv_addr = (struct sockaddr_in) { ++ .sin_family = AF_INET, ++ .sin_addr = {.s_addr = htonl (INADDR_LOOPBACK) }, ++ }; ++ xbind (srv, (struct sockaddr *) &srv_addr, sizeof (srv_addr)); ++ { ++ socklen_t sa_len = sizeof (srv_addr); ++ xgetsockname (srv, (struct sockaddr *) &srv_addr, &sa_len); ++ TEST_VERIFY (sa_len == sizeof (srv_addr)); ++ } ++ ++ /* Check recvmsg; */ ++ do_test_large_buffer (false); ++ do_test_small_buffer (false); ++ /* Check recvmmsg. */ ++ do_test_large_buffer (true); ++ do_test_small_buffer (true); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-103.patch b/SOURCES/glibc-upstream-2.34-103.patch new file mode 100644 index 0000000..1605e95 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-103.patch @@ -0,0 +1,24 @@ +commit 008003dc6e83439c5e04a744b7fd8197df19096e +Author: H.J. Lu +Date: Sat Jan 29 05:22:31 2022 -0800 + + tst-socket-timestamp-compat.c: Check __TIMESIZE [BZ #28837] + + time_t size is defined by __TIMESIZE, not __WORDSIZE. Check __TIMESIZE, + instead of __WORDSIZE, for time_t size. This fixes BZ #28837. + + (cherry pick from commit 77a602ebb0769e7ccc5f9f8e06f7fffe66f69dfc) + +diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c +index de261dae5a6385cf..0ff1a214e605105b 100644 +--- a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c ++++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c +@@ -237,7 +237,7 @@ do_test (void) + { + /* This test only make sense for ABIs that support 32 bit time_t socket + timestampss. */ +- if (sizeof (time_t) > 4 && __WORDSIZE == 64) ++ if (sizeof (time_t) > 4 && __TIMESIZE == 64) + return 0; + + srv = xsocket (AF_INET, SOCK_DGRAM, 0); diff --git a/SOURCES/glibc-upstream-2.34-104.patch b/SOURCES/glibc-upstream-2.34-104.patch new file mode 100644 index 0000000..4ae7486 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-104.patch @@ -0,0 +1,26 @@ +commit 05c83ccaf50aef2dd30d92cbb814383f6bddea2c +Author: Gleb Fotengauer-Malinovskiy +Date: Tue Feb 1 22:39:02 2022 +0000 + + linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage [BZ #28850] + + Pass the actual number of bytes returned by the kernel. + + Fixes: 33099d72e41c ("linux: Simplify get_nprocs") + Reviewed-by: Dmitry V. Levin + + (cherry picked from commit 97ba273b505763325efd802dc3a9562dbba79579) + +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index 7fc6521942e87293..7babd947aa902e77 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -45,7 +45,7 @@ __get_nprocs_sched (void) + int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size, + cpu_bits); + if (r > 0) +- return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits); ++ return CPU_COUNT_S (r, (cpu_set_t*) cpu_bits); + else if (r == -EINVAL) + /* The input buffer is still not enough to store the number of cpus. This + is an arbitrary values assuming such systems should be rare and there diff --git a/SOURCES/glibc-upstream-2.34-105.patch b/SOURCES/glibc-upstream-2.34-105.patch new file mode 100644 index 0000000..423f65f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-105.patch @@ -0,0 +1,234 @@ +commit ad615b59c78d6d37fee921fb2b2ae6b72c930625 +Author: Florian Weimer +Date: Tue Sep 28 18:55:49 2021 +0200 + + Linux: Simplify __opensock and fix race condition [BZ #28353] + + AF_NETLINK support is not quite optional on modern Linux systems + anymore, so it is likely that the first attempt will always succeed. + Consequently, there is no need to cache the result. Keep AF_UNIX + and the Internet address families as a fallback, for the rare case + that AF_NETLINK is missing. The other address families previously + probed are totally obsolete be now, so remove them. + + Use this simplified version as the generic implementation, disabling + Netlink support as needed. + + (cherry picked from commit 5bf07e1b3a74232bfb8332275110be1a5da50f83) + +diff --git a/socket/opensock.c b/socket/opensock.c +index 37148d4743343ff4..ff94d27a61bd3889 100644 +--- a/socket/opensock.c ++++ b/socket/opensock.c +@@ -1,4 +1,5 @@ +-/* Copyright (C) 1999-2021 Free Software Foundation, Inc. ++/* Create socket with an unspecified address family for use with ioctl. ++ Copyright (C) 1999-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -15,56 +16,34 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#include + #include +-#include + + /* Return a socket of any type. The socket can be used in subsequent + ioctl calls to talk to the kernel. */ + int + __opensock (void) + { +- /* Cache the last AF that worked, to avoid many redundant calls to +- socket(). */ +- static int sock_af = -1; +- int fd = -1; +- __libc_lock_define_initialized (static, lock); +- +- if (sock_af != -1) +- { +- fd = __socket (sock_af, SOCK_DGRAM, 0); +- if (fd != -1) +- return fd; +- } +- +- __libc_lock_lock (lock); +- +- if (sock_af != -1) +- fd = __socket (sock_af, SOCK_DGRAM, 0); +- +- if (fd == -1) +- { +-#ifdef AF_INET +- fd = __socket (sock_af = AF_INET, SOCK_DGRAM, 0); +-#endif +-#ifdef AF_INET6 +- if (fd < 0) +- fd = __socket (sock_af = AF_INET6, SOCK_DGRAM, 0); +-#endif +-#ifdef AF_IPX +- if (fd < 0) +- fd = __socket (sock_af = AF_IPX, SOCK_DGRAM, 0); +-#endif +-#ifdef AF_AX25 +- if (fd < 0) +- fd = __socket (sock_af = AF_AX25, SOCK_DGRAM, 0); +-#endif +-#ifdef AF_APPLETALK +- if (fd < 0) +- fd = __socket (sock_af = AF_APPLETALK, SOCK_DGRAM, 0); ++ /* SOCK_DGRAM is supported by all address families. (Netlink does ++ not support SOCK_STREAM.) */ ++ int type = SOCK_DGRAM | SOCK_CLOEXEC; ++ int fd; ++ ++#ifdef AF_NETLINK ++ fd = __socket (AF_NETLINK, type, 0); ++ if (fd >= 0) ++ return fd; + #endif +- } + +- __libc_lock_unlock (lock); ++ fd = __socket (AF_UNIX, type, 0); ++ if (fd >= 0) ++ return fd; ++ fd = __socket (AF_INET, type, 0); ++ if (fd >= 0) ++ return fd; ++ fd = __socket (AF_INET6, type, 0); ++ if (fd >= 0) ++ return fd; ++ __set_errno (ENOENT); + return fd; + } +diff --git a/sysdeps/unix/sysv/linux/opensock.c b/sysdeps/unix/sysv/linux/opensock.c +deleted file mode 100644 +index e87d6e58b0b84f82..0000000000000000 +--- a/sysdeps/unix/sysv/linux/opensock.c ++++ /dev/null +@@ -1,114 +0,0 @@ +-/* Copyright (C) 1999-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* Return a socket of any type. The socket can be used in subsequent +- ioctl calls to talk to the kernel. */ +-int +-__opensock (void) +-{ +- static int last_family; /* Available socket family we will use. */ +- static int last_type; +- static const struct +- { +- int family; +- const char procname[15]; +- } afs[] = +- { +- { AF_UNIX, "net/unix" }, +- { AF_INET, "" }, +- { AF_INET6, "net/if_inet6" }, +- { AF_AX25, "net/ax25" }, +- { AF_NETROM, "net/nr" }, +- { AF_ROSE, "net/rose" }, +- { AF_IPX, "net/ipx" }, +- { AF_APPLETALK, "net/appletalk" }, +- { AF_ECONET, "sys/net/econet" }, +- { AF_ASH, "sys/net/ash" }, +- { AF_X25, "net/x25" }, +-#ifdef NEED_AF_IUCV +- { AF_IUCV, "net/iucv" } +-#endif +- }; +-#define nafs (sizeof (afs) / sizeof (afs[0])) +- char fname[sizeof "/proc/" + 14]; +- int result; +- int has_proc; +- size_t cnt; +- +- /* We already know which family to use from the last call. Use it +- again. */ +- if (last_family != 0) +- { +- assert (last_type != 0); +- +- result = __socket (last_family, last_type | SOCK_CLOEXEC, 0); +- if (result != -1 || errno != EAFNOSUPPORT) +- /* Maybe the socket type isn't supported anymore (module is +- unloaded). In this case again try to find the type. */ +- return result; +- +- /* Reset the values. They seem not valid anymore. */ +- last_family = 0; +- last_type = 0; +- } +- +- /* Check whether the /proc filesystem is available. */ +- has_proc = __access ("/proc/net", R_OK) != -1; +- strcpy (fname, "/proc/"); +- +- /* Iterate over the interface families and find one which is +- available. */ +- for (cnt = 0; cnt < nafs; ++cnt) +- { +- int type = SOCK_DGRAM; +- +- if (has_proc && afs[cnt].procname[0] != '\0') +- { +- strcpy (fname + 6, afs[cnt].procname); +- if (__access (fname, R_OK) == -1) +- /* The /proc entry is not available. I.e., we cannot +- create a socket of this type (without loading the +- module). Don't look for it since this might trigger +- loading the module. */ +- continue; +- } +- +- if (afs[cnt].family == AF_NETROM || afs[cnt].family == AF_X25) +- type = SOCK_SEQPACKET; +- +- result = __socket (afs[cnt].family, type | SOCK_CLOEXEC, 0); +- if (result != -1) +- { +- /* Found an available family. */ +- last_type = type; +- last_family = afs[cnt].family; +- return result; +- } +- } +- +- /* None of the protocol families is available. It is unclear what kind +- of error is returned. ENOENT seems like a reasonable choice. */ +- __set_errno (ENOENT); +- return -1; +-} +diff --git a/sysdeps/unix/sysv/linux/s390/opensock.c b/sysdeps/unix/sysv/linux/s390/opensock.c +deleted file mode 100644 +index f099d651ff04d211..0000000000000000 +--- a/sysdeps/unix/sysv/linux/s390/opensock.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define NEED_AF_IUCV 1 +-#include "../opensock.c" diff --git a/SOURCES/glibc-upstream-2.34-106.patch b/SOURCES/glibc-upstream-2.34-106.patch new file mode 100644 index 0000000..296f32a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-106.patch @@ -0,0 +1,44 @@ +commit d8302ba2da1e5ac59a1c4dc1c1207a10fdafdb08 +Author: Samuel Thibault +Date: Mon Oct 18 01:39:02 2021 +0200 + + hurd if_index: Explicitly use AF_INET for if index discovery + + 5bf07e1b3a74 ("Linux: Simplify __opensock and fix race condition [BZ #28353]") + made __opensock try NETLINK then UNIX then INET. On the Hurd, only INET + knows about network interfaces, so better actually specify that in + if_index. + + (cherry picked from commit 1d3decee997ba2fc24af81803299b2f4f3c47063) + +diff --git a/sysdeps/mach/hurd/if_index.c b/sysdeps/mach/hurd/if_index.c +index 0eab510453c9e861..e785ac15aa6a1002 100644 +--- a/sysdeps/mach/hurd/if_index.c ++++ b/sysdeps/mach/hurd/if_index.c +@@ -32,7 +32,7 @@ unsigned int + __if_nametoindex (const char *ifname) + { + struct ifreq ifr; +- int fd = __opensock (); ++ int fd = __socket (AF_INET, SOCK_DGRAM, 0); + + if (fd < 0) + return 0; +@@ -84,7 +84,7 @@ __if_nameindex (void) + error_t err = 0; + char data[2048]; + file_t server; +- int fd = __opensock (); ++ int fd = __socket (AF_INET, SOCK_DGRAM, 0); + struct ifconf ifc; + unsigned int nifs, i; + struct if_nameindex *idx = NULL; +@@ -169,7 +169,7 @@ char * + __if_indextoname (unsigned int ifindex, char ifname[IF_NAMESIZE]) + { + struct ifreq ifr; +- int fd = __opensock (); ++ int fd = __socket (AF_INET, SOCK_DGRAM, 0); + + if (fd < 0) + return NULL; diff --git a/SOURCES/glibc-upstream-2.34-107.patch b/SOURCES/glibc-upstream-2.34-107.patch new file mode 100644 index 0000000..650aa2b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-107.patch @@ -0,0 +1,35 @@ +commit 6eaf10cbb78d22eae7999d9de55f6b93999e0860 +Author: Florian Weimer +Date: Mon Nov 22 14:41:14 2021 +0100 + + socket: Do not use AF_NETLINK in __opensock + + It is not possible to use interface ioctls with netlink sockets + on all Linux kernels. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 3d981795cd00cc9b73c3ee5087c308361acd62e5) + +diff --git a/socket/opensock.c b/socket/opensock.c +index ff94d27a61bd3889..3e35821f91643456 100644 +--- a/socket/opensock.c ++++ b/socket/opensock.c +@@ -24,17 +24,10 @@ + int + __opensock (void) + { +- /* SOCK_DGRAM is supported by all address families. (Netlink does +- not support SOCK_STREAM.) */ ++ /* SOCK_DGRAM is supported by all address families. */ + int type = SOCK_DGRAM | SOCK_CLOEXEC; + int fd; + +-#ifdef AF_NETLINK +- fd = __socket (AF_NETLINK, type, 0); +- if (fd >= 0) +- return fd; +-#endif +- + fd = __socket (AF_UNIX, type, 0); + if (fd >= 0) + return fd; diff --git a/SOURCES/glibc-upstream-2.34-108.patch b/SOURCES/glibc-upstream-2.34-108.patch new file mode 100644 index 0000000..e4186ee --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-108.patch @@ -0,0 +1,32 @@ +commit 0351c75c5f94134fcec0e778e8cf86d149f8bbfb +Author: Adhemerval Zanella +Date: Thu Feb 3 16:52:52 2022 -0300 + + linux: Fix missing __convert_scm_timestamps (BZ #28860) + + Commit 948ce73b31 made recvmsg/recvmmsg to always call + __convert_scm_timestamps for 64 bit time_t symbol, so adjust it to + always build it for __TIMESIZE != 64. + + It fixes build for architecture with 32 bit time_t support when + configured with minimum kernel of 5.1. + + (cherry-picked from 798d716df71fb23dc89d1d5dba1fc26a1b5c0024) + +diff --git a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c +index 5d3c4199e0b32944..953ce97bd2e03849 100644 +--- a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c ++++ b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c +@@ -16,9 +16,10 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#include ++#include + +-#ifndef __ASSUME_TIME64_SYSCALLS ++#if __TIMESIZE != 64 + # include + # include + # include diff --git a/SOURCES/glibc-upstream-2.34-11.patch b/SOURCES/glibc-upstream-2.34-11.patch new file mode 100644 index 0000000..47849fb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-11.patch @@ -0,0 +1,62 @@ +commit 52d0119743180164d1664b6773ac5d873f224608 +Author: Jiaxun Yang +Date: Tue Sep 7 13:31:42 2021 +0800 + + MIPS: Setup errno for {f,l,}xstat + + {f,l,}xstat stub for MIPS is using INTERNAL_SYSCALL + to do xstat syscall for glibc ver, However it leaves + errno untouched and thus giving bad errno output. + + Setup errno properly when syscall returns non-zero. + + Signed-off-by: Jiaxun Yang + Reviewed-by: Adhemerval Zanella + + (cherry picked from commit 66016ec8aeefd40e016d7040d966484c764b0e9c) + +diff --git a/sysdeps/unix/sysv/linux/mips/fxstat.c b/sysdeps/unix/sysv/linux/mips/fxstat.c +index 11511d30b38708ce..4a6016ff123e8dd9 100644 +--- a/sysdeps/unix/sysv/linux/mips/fxstat.c ++++ b/sysdeps/unix/sysv/linux/mips/fxstat.c +@@ -35,7 +35,9 @@ __fxstat (int vers, int fd, struct stat *buf) + { + struct kernel_stat kbuf; + int r = INTERNAL_SYSCALL_CALL (fstat, fd, &kbuf); +- return r ?: __xstat_conv (vers, &kbuf, buf); ++ if (r == 0) ++ return __xstat_conv (vers, &kbuf, buf); ++ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r); + } + } + } +diff --git a/sysdeps/unix/sysv/linux/mips/lxstat.c b/sysdeps/unix/sysv/linux/mips/lxstat.c +index 871fb6c6c5886665..54f990a250677091 100644 +--- a/sysdeps/unix/sysv/linux/mips/lxstat.c ++++ b/sysdeps/unix/sysv/linux/mips/lxstat.c +@@ -35,7 +35,9 @@ __lxstat (int vers, const char *name, struct stat *buf) + { + struct kernel_stat kbuf; + int r = INTERNAL_SYSCALL_CALL (lstat, name, &kbuf); +- return r ?: __xstat_conv (vers, &kbuf, buf); ++ if (r == 0) ++ return __xstat_conv (vers, &kbuf, buf); ++ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r); + } + } + } +diff --git a/sysdeps/unix/sysv/linux/mips/xstat.c b/sysdeps/unix/sysv/linux/mips/xstat.c +index 9d810b6f653b964b..86f4dc31a82ff1bb 100644 +--- a/sysdeps/unix/sysv/linux/mips/xstat.c ++++ b/sysdeps/unix/sysv/linux/mips/xstat.c +@@ -35,7 +35,9 @@ __xstat (int vers, const char *name, struct stat *buf) + { + struct kernel_stat kbuf; + int r = INTERNAL_SYSCALL_CALL (stat, name, &kbuf); +- return r ?: __xstat_conv (vers, &kbuf, buf); ++ if (r == 0) ++ return __xstat_conv (vers, &kbuf, buf); ++ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r); + } + } + } diff --git a/SOURCES/glibc-upstream-2.34-110.patch b/SOURCES/glibc-upstream-2.34-110.patch new file mode 100644 index 0000000..cd9bc09 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-110.patch @@ -0,0 +1,192 @@ +commit 007e054d786be340699c634e3a3b30ab1fde1a7a +Author: Dmitry V. Levin +Date: Sat Feb 5 08:00:00 2022 +0000 + + linux: fix accuracy of get_nprocs and get_nprocs_conf [BZ #28865] + + get_nprocs() and get_nprocs_conf() use various methods to obtain an + accurate number of processors. Re-introduce __get_nprocs_sched() as + a source of information, and fix the order in which these methods are + used to return the most accurate information. The primary source of + information used in both functions remains unchanged. + + This also changes __get_nprocs_sched() error return value from 2 to 0, + but all its users are already prepared to handle that. + + Old fallback order: + get_nprocs: + /sys/devices/system/cpu/online -> /proc/stat -> 2 + get_nprocs_conf: + /sys/devices/system/cpu/ -> /proc/stat -> 2 + + New fallback order: + get_nprocs: + /sys/devices/system/cpu/online -> /proc/stat -> sched_getaffinity -> 2 + get_nprocs_conf: + /sys/devices/system/cpu/ -> /proc/stat -> sched_getaffinity -> 2 + + Fixes: 342298278e ("linux: Revert the use of sched_getaffinity on get_nproc") + Closes: BZ #28865 + Reviewed-by: Adhemerval Zanella + + (cherry picked from commit e1d32b836410767270a3adf1f82b1a47e6e4cd51) + +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index 7babd947aa902e77..327802b14c7326a3 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -51,9 +51,8 @@ __get_nprocs_sched (void) + is an arbitrary values assuming such systems should be rare and there + is no offline cpus. */ + return max_num_cpus; +- /* Some other error. 2 is conservative (not a uniprocessor system, so +- atomics are needed). */ +- return 2; ++ /* Some other error. */ ++ return 0; + } + + static char * +@@ -109,22 +108,19 @@ next_line (int fd, char *const buffer, char **cp, char **re, + } + + static int +-get_nproc_stat (char *buffer, size_t buffer_size) ++get_nproc_stat (void) + { ++ enum { buffer_size = 1024 }; ++ char buffer[buffer_size]; + char *buffer_end = buffer + buffer_size; + char *cp = buffer_end; + char *re = buffer_end; +- +- /* Default to an SMP system in case we cannot obtain an accurate +- number. */ +- int result = 2; ++ int result = 0; + + const int flags = O_RDONLY | O_CLOEXEC; + int fd = __open_nocancel ("/proc/stat", flags); + if (fd != -1) + { +- result = 0; +- + char *l; + while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL) + /* The current format of /proc/stat has all the cpu* entries +@@ -140,8 +136,8 @@ get_nproc_stat (char *buffer, size_t buffer_size) + return result; + } + +-int +-__get_nprocs (void) ++static int ++get_nprocs_cpu_online (void) + { + enum { buffer_size = 1024 }; + char buffer[buffer_size]; +@@ -180,7 +176,8 @@ __get_nprocs (void) + } + } + +- result += m - n + 1; ++ if (m >= n) ++ result += m - n + 1; + + l = endp; + if (l < re && *l == ',') +@@ -189,28 +186,18 @@ __get_nprocs (void) + while (l < re && *l != '\n'); + + __close_nocancel_nostatus (fd); +- +- if (result > 0) +- return result; + } + +- return get_nproc_stat (buffer, buffer_size); ++ return result; + } +-libc_hidden_def (__get_nprocs) +-weak_alias (__get_nprocs, get_nprocs) +- + +-/* On some architectures it is possible to distinguish between configured +- and active cpus. */ +-int +-__get_nprocs_conf (void) ++static int ++get_nprocs_cpu (void) + { +- /* Try to use the sysfs filesystem. It has actual information about +- online processors. */ ++ int count = 0; + DIR *dir = __opendir ("/sys/devices/system/cpu"); + if (dir != NULL) + { +- int count = 0; + struct dirent64 *d; + + while ((d = __readdir64 (dir)) != NULL) +@@ -225,12 +212,57 @@ __get_nprocs_conf (void) + + __closedir (dir); + +- return count; + } ++ return count; ++} + +- enum { buffer_size = 1024 }; +- char buffer[buffer_size]; +- return get_nproc_stat (buffer, buffer_size); ++static int ++get_nprocs_fallback (void) ++{ ++ int result; ++ ++ /* Try /proc/stat first. */ ++ result = get_nproc_stat (); ++ if (result != 0) ++ return result; ++ ++ /* Try sched_getaffinity. */ ++ result = __get_nprocs_sched (); ++ if (result != 0) ++ return result; ++ ++ /* We failed to obtain an accurate number. Be conservative: return ++ the smallest number meaning that this is not a uniprocessor system, ++ so atomics are needed. */ ++ return 2; ++} ++ ++int ++__get_nprocs (void) ++{ ++ /* Try /sys/devices/system/cpu/online first. */ ++ int result = get_nprocs_cpu_online (); ++ if (result != 0) ++ return result; ++ ++ /* Fall back to /proc/stat and sched_getaffinity. */ ++ return get_nprocs_fallback (); ++} ++libc_hidden_def (__get_nprocs) ++weak_alias (__get_nprocs, get_nprocs) ++ ++/* On some architectures it is possible to distinguish between configured ++ and active cpus. */ ++int ++__get_nprocs_conf (void) ++{ ++ /* Try /sys/devices/system/cpu/ first. */ ++ int result = get_nprocs_cpu (); ++ if (result != 0) ++ return result; ++ ++ /* Fall back to /proc/stat and sched_getaffinity. */ ++ return get_nprocs_fallback (); + } + libc_hidden_def (__get_nprocs_conf) + weak_alias (__get_nprocs_conf, get_nprocs_conf) diff --git a/SOURCES/glibc-upstream-2.34-111.patch b/SOURCES/glibc-upstream-2.34-111.patch new file mode 100644 index 0000000..cf08e56 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-111.patch @@ -0,0 +1,60 @@ +commit 04d60ce0f21ffe2a4add148cb37a1942dbad64e2 +Author: H.J. Lu +Date: Thu Feb 17 08:10:35 2022 -0800 + + string: Add a testcase for wcsncmp with SIZE_MAX [BZ #28755] + + Verify that wcsncmp (L("abc"), L("abd"), SIZE_MAX) == 0. The new test + fails without + + commit ddf0992cf57a93200e0c782e2a94d0733a5a0b87 + Author: Noah Goldstein + Date: Sun Jan 9 16:02:21 2022 -0600 + + x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755] + + and + + commit 7e08db3359c86c94918feb33a1182cd0ff3bb10b + Author: Noah Goldstein + Date: Sun Jan 9 16:02:28 2022 -0600 + + x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755] + + This is for BZ #28755. + + Reviewed-by: Sunil K Pandey + + (cherry picked from commit aa5a720056d37cf24924c138a3dbe6dace98e97c) + +diff --git a/string/test-strncmp.c b/string/test-strncmp.c +index 10b34de8d2acb2a1..97e831d88fd24316 100644 +--- a/string/test-strncmp.c ++++ b/string/test-strncmp.c +@@ -435,6 +435,18 @@ check3 (void) + } + } + ++static void ++check4 (void) ++{ ++ const CHAR *s1 = L ("abc"); ++ CHAR *s2 = STRDUP (s1); ++ ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, s1, s2, SIZE_MAX, 0); ++ ++ free (s2); ++} ++ + int + test_main (void) + { +@@ -445,6 +457,7 @@ test_main (void) + check1 (); + check2 (); + check3 (); ++ check4 (); + + printf ("%23s", ""); + FOR_EACH_IMPL (impl, 0) diff --git a/SOURCES/glibc-upstream-2.34-112.patch b/SOURCES/glibc-upstream-2.34-112.patch new file mode 100644 index 0000000..d6a677a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-112.patch @@ -0,0 +1,120 @@ +commit 38e0d2479413ccdbc02b4c9e9e246eca31e956c9 +Author: Noah Goldstein +Date: Tue Feb 15 08:18:15 2022 -0600 + + x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #28896] + + In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would + call strcmp-avx2 and wcscmp-avx2 respectively. This would have + not checks around vzeroupper and would trigger spurious + aborts. This commit fixes that. + + test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on + AVX2 machines with and without RTM. + + Co-authored-by: H.J. Lu + + (cherry picked from commit c6272098323153db373f2986c67786ea8c85f1cf) + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 36ca1a7126047b86..af934d6ccf1fa337 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -105,7 +105,7 @@ CFLAGS-tst-memset-rtm.c += -mrtm + CFLAGS-tst-strchr-rtm.c += -mrtm + CFLAGS-tst-strcpy-rtm.c += -mrtm + CFLAGS-tst-strlen-rtm.c += -mrtm +-CFLAGS-tst-strncmp-rtm.c += -mrtm ++CFLAGS-tst-strncmp-rtm.c += -mrtm -Wno-error + CFLAGS-tst-strrchr-rtm.c += -mrtm + endif + +diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c +index 236ad951b5b59cd1..4d0004b58aae428d 100644 +--- a/sysdeps/x86/tst-strncmp-rtm.c ++++ b/sysdeps/x86/tst-strncmp-rtm.c +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + + #define LOOP 3000 +@@ -45,8 +46,22 @@ function (void) + return 1; + } + ++__attribute__ ((noinline, noclone)) ++static int ++function_overflow (void) ++{ ++ if (strncmp (string1, string2, SIZE_MAX) == 0) ++ return 0; ++ else ++ return 1; ++} ++ + static int + do_test (void) + { +- return do_test_1 ("strncmp", LOOP, prepare, function); ++ int status = do_test_1 ("strncmp", LOOP, prepare, function); ++ if (status != EXIT_SUCCESS) ++ return status; ++ status = do_test_1 ("strncmp", LOOP, prepare, function_overflow); ++ return status; + } +diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S +index 3dfcb1bf803cf9ec..fa70c994fc25dfd8 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S +@@ -95,7 +95,7 @@ ENTRY (STRCMP) + length to bound a valid memory region. In these cases just use + 'wcscmp'. */ + shrq $56, %rcx +- jnz __wcscmp_avx2 ++ jnz OVERFLOW_STRCMP + # endif + /* Convert units: from wide to byte char. */ + shl $2, %RDX_LP +diff --git a/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S b/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S +index 37d1224bb9b7056b..68bad365ba728eec 100644 +--- a/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S ++++ b/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S +@@ -1,3 +1,4 @@ + #define STRCMP __strncmp_avx2_rtm + #define USE_AS_STRNCMP 1 ++#define OVERFLOW_STRCMP __strcmp_avx2_rtm + #include "strcmp-avx2-rtm.S" +diff --git a/sysdeps/x86_64/multiarch/strncmp-avx2.S b/sysdeps/x86_64/multiarch/strncmp-avx2.S +index 1678bcc235a4bc6a..f138e9f1fdcf277c 100644 +--- a/sysdeps/x86_64/multiarch/strncmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/strncmp-avx2.S +@@ -1,3 +1,4 @@ + #define STRCMP __strncmp_avx2 + #define USE_AS_STRNCMP 1 ++#define OVERFLOW_STRCMP __strcmp_avx2 + #include "strcmp-avx2.S" +diff --git a/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S b/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S +index 4e88c70cc696b82d..f467582cbedd4535 100644 +--- a/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S ++++ b/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S +@@ -1,5 +1,5 @@ + #define STRCMP __wcsncmp_avx2_rtm + #define USE_AS_STRNCMP 1 + #define USE_AS_WCSCMP 1 +- ++#define OVERFLOW_STRCMP __wcscmp_avx2_rtm + #include "strcmp-avx2-rtm.S" +diff --git a/sysdeps/x86_64/multiarch/wcsncmp-avx2.S b/sysdeps/x86_64/multiarch/wcsncmp-avx2.S +index 4fa1de4d3f1f97ff..e9ede522b8bde27d 100644 +--- a/sysdeps/x86_64/multiarch/wcsncmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/wcsncmp-avx2.S +@@ -1,5 +1,5 @@ + #define STRCMP __wcsncmp_avx2 + #define USE_AS_STRNCMP 1 + #define USE_AS_WCSCMP 1 +- ++#define OVERFLOW_STRCMP __wcscmp_avx2 + #include "strcmp-avx2.S" diff --git a/SOURCES/glibc-upstream-2.34-113.patch b/SOURCES/glibc-upstream-2.34-113.patch new file mode 100644 index 0000000..e83d23c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-113.patch @@ -0,0 +1,139 @@ +commit d093b677c36ef4b360bf30483b68b95d9f0ad1d2 +Author: Noah Goldstein +Date: Fri Feb 18 14:19:15 2022 -0600 + + x86: Test wcscmp RTM in the wcsncmp overflow case [BZ #28896] + + In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would + call strcmp-avx2 and wcscmp-avx2 respectively. This would have + not checks around vzeroupper and would trigger spurious + aborts. This commit fixes that. + + test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on + AVX2 machines with and without RTM. + Reviewed-by: H.J. Lu + + (cherry picked from commit 7835d611af0854e69a0c71e3806f8fe379282d6f) + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index af934d6ccf1fa337..cd94e683afd5b4a4 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -95,7 +95,9 @@ tests += \ + tst-strcpy-rtm \ + tst-strlen-rtm \ + tst-strncmp-rtm \ +- tst-strrchr-rtm ++ tst-strrchr-rtm \ ++ tst-wcsncmp-rtm \ ++# tests + + CFLAGS-tst-memchr-rtm.c += -mrtm + CFLAGS-tst-memcmp-rtm.c += -mrtm +@@ -107,6 +109,7 @@ CFLAGS-tst-strcpy-rtm.c += -mrtm + CFLAGS-tst-strlen-rtm.c += -mrtm + CFLAGS-tst-strncmp-rtm.c += -mrtm -Wno-error + CFLAGS-tst-strrchr-rtm.c += -mrtm ++CFLAGS-tst-wcsncmp-rtm.c += -mrtm -Wno-error + endif + + ifneq ($(enable-cet),no) +diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c +index 4d0004b58aae428d..4e9f094f39c72f67 100644 +--- a/sysdeps/x86/tst-strncmp-rtm.c ++++ b/sysdeps/x86/tst-strncmp-rtm.c +@@ -19,18 +19,32 @@ + #include + #include + ++#ifdef WIDE ++# define CHAR wchar_t ++# define MEMSET wmemset ++# define STRNCMP wcsncmp ++# define TEST_NAME wcsncmp ++#else /* !WIDE */ ++# define CHAR char ++# define MEMSET memset ++# define STRNCMP strncmp ++# define TEST_NAME strncmp ++#endif /* !WIDE */ ++ ++ ++ + #define LOOP 3000 + #define STRING_SIZE 1024 +-char string1[STRING_SIZE]; +-char string2[STRING_SIZE]; ++CHAR string1[STRING_SIZE]; ++CHAR string2[STRING_SIZE]; + + __attribute__ ((noinline, noclone)) + static int + prepare (void) + { +- memset (string1, 'a', STRING_SIZE - 1); +- memset (string2, 'a', STRING_SIZE - 1); +- if (strncmp (string1, string2, STRING_SIZE) == 0) ++ MEMSET (string1, 'a', STRING_SIZE - 1); ++ MEMSET (string2, 'a', STRING_SIZE - 1); ++ if (STRNCMP (string1, string2, STRING_SIZE) == 0) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +@@ -40,7 +54,7 @@ __attribute__ ((noinline, noclone)) + static int + function (void) + { +- if (strncmp (string1, string2, STRING_SIZE) == 0) ++ if (STRNCMP (string1, string2, STRING_SIZE) == 0) + return 0; + else + return 1; +@@ -50,7 +64,7 @@ __attribute__ ((noinline, noclone)) + static int + function_overflow (void) + { +- if (strncmp (string1, string2, SIZE_MAX) == 0) ++ if (STRNCMP (string1, string2, SIZE_MAX) == 0) + return 0; + else + return 1; +@@ -59,9 +73,9 @@ function_overflow (void) + static int + do_test (void) + { +- int status = do_test_1 ("strncmp", LOOP, prepare, function); ++ int status = do_test_1 (TEST_NAME, LOOP, prepare, function); + if (status != EXIT_SUCCESS) + return status; +- status = do_test_1 ("strncmp", LOOP, prepare, function_overflow); ++ status = do_test_1 (TEST_NAME, LOOP, prepare, function_overflow); + return status; + } +diff --git a/sysdeps/x86/tst-wcsncmp-rtm.c b/sysdeps/x86/tst-wcsncmp-rtm.c +new file mode 100644 +index 0000000000000000..bad3b863782c5e56 +--- /dev/null ++++ b/sysdeps/x86/tst-wcsncmp-rtm.c +@@ -0,0 +1,21 @@ ++/* Test case for wcsncmp inside a transactionally executing RTM region. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include ++#include "tst-strncmp-rtm.c" diff --git a/SOURCES/glibc-upstream-2.34-114.patch b/SOURCES/glibc-upstream-2.34-114.patch new file mode 100644 index 0000000..863b88c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-114.patch @@ -0,0 +1,32 @@ +commit 15b00d2af0e56dcc8c244a36d6872d301b0c7185 +Author: Noah Goldstein +Date: Fri Feb 18 17:00:25 2022 -0600 + + x86: Fix TEST_NAME to make it a string in tst-strncmp-rtm.c + + Previously TEST_NAME was passing a function pointer. This didn't fail + because of the -Wno-error flag (to allow for overflow sizes passed + to strncmp/wcsncmp) + + Reviewed-by: H.J. Lu + (cherry picked from commit b98d0bbf747f39770e0caba7e984ce9f8f900330) + +diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c +index 4e9f094f39c72f67..aef9866cf2fbe774 100644 +--- a/sysdeps/x86/tst-strncmp-rtm.c ++++ b/sysdeps/x86/tst-strncmp-rtm.c +@@ -23,12 +23,12 @@ + # define CHAR wchar_t + # define MEMSET wmemset + # define STRNCMP wcsncmp +-# define TEST_NAME wcsncmp ++# define TEST_NAME "wcsncmp" + #else /* !WIDE */ + # define CHAR char + # define MEMSET memset + # define STRNCMP strncmp +-# define TEST_NAME strncmp ++# define TEST_NAME "strncmp" + #endif /* !WIDE */ + + diff --git a/SOURCES/glibc-upstream-2.34-117.patch b/SOURCES/glibc-upstream-2.34-117.patch new file mode 100644 index 0000000..62b8f3b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-117.patch @@ -0,0 +1,104 @@ +commit 3be79b72d556e3ac37075ad6b99eb5eac18e1402 +Author: John David Anglin +Date: Sun Mar 6 15:56:57 2022 +0000 + + Fix elf/tst-audit2 on hppa + + The test elf/tst-audit2 fails on hppa with a segmentation fault in the + long branch stub used to call malloc from calloc. This occurs because + the test is not a PIC executable and calloc is called from the dynamic + linker before the dp register is initialized in _dl_start_user. + + The fix is to move the dp register initialization into + elf_machine_runtime_setup. Since the address of $global$ can't be + loaded directly, we continue to use the DT_PLTGOT value from the + the main_map to initialize dp. Since l_main_map is not available + in v2.34 and earlier, we use a new function, elf_machine_main_map, + to find the main map. + +diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h +index f048fd20728ccde6..24f0f47d8f1e25cd 100644 +--- a/sysdeps/hppa/dl-machine.h ++++ b/sysdeps/hppa/dl-machine.h +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -159,6 +160,24 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + return (struct fdesc) { value.ip + reloc->r_addend, value.gp }; + } + ++static inline struct link_map * ++elf_machine_main_map (void) ++{ ++ struct link_map *main_map; ++ ++#if defined SHARED && IS_IN (rtld) ++ asm ( ++" bl 1f,%0\n" ++" addil L'_rtld_local - ($PIC_pcrel$0 - 1),%0\n" ++"1: ldw R'_rtld_local - ($PIC_pcrel$0 - 5)(%%r1),%0\n" ++ : "=r" (main_map) : : "r1"); ++#else ++ main_map = NULL; ++#endif ++ ++ return main_map; ++} ++ + /* Set up the loaded object described by L so its unrelocated PLT + entries will jump to the on-demand fixup code in dl-runtime.c. */ + +@@ -174,6 +193,15 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + Elf32_Addr i[2]; + } sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}}; + ++ /* Initialize dp register for main executable. */ ++ if (l == elf_machine_main_map ()) ++ { ++ register Elf32_Addr dp asm ("%r27"); ++ ++ dp = D_PTR (l, l_info[DT_PLTGOT]); ++ asm volatile ("" : : "r" (dp)); ++ } ++ + /* If we don't have a PLT we can just skip all this... */ + if (__builtin_expect (l->l_info[DT_JMPREL] == NULL,0)) + return lazy; +@@ -336,16 +364,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + its return value is the user program's entry point. */ + + #define RTLD_START \ +-/* Set up dp for any non-PIC lib constructors that may be called. */ \ +-static struct link_map * __attribute__((used)) \ +-set_dp (struct link_map *map) \ +-{ \ +- register Elf32_Addr dp asm ("%r27"); \ +- dp = D_PTR (map, l_info[DT_PLTGOT]); \ +- asm volatile ("" : : "r" (dp)); \ +- return map; \ +-} \ +- \ + asm ( \ + " .text\n" \ + " .globl _start\n" \ +@@ -445,14 +463,11 @@ asm ( \ + " stw %r24,-44(%sp)\n" \ + \ + ".Lnofix:\n" \ ++ /* Call _dl_init(main_map, argc, argv, envp). */ \ + " addil LT'_rtld_local,%r19\n" \ + " ldw RT'_rtld_local(%r1),%r26\n" \ +-" bl set_dp, %r2\n" \ + " ldw 0(%r26),%r26\n" \ + \ +- /* Call _dl_init(_dl_loaded, argc, argv, envp). */ \ +-" copy %r28,%r26\n" \ +- \ + /* envp = argv + argc + 1 */ \ + " sh2add %r25,%r24,%r23\n" \ + " bl _dl_init,%r2\n" \ diff --git a/SOURCES/glibc-upstream-2.34-118.patch b/SOURCES/glibc-upstream-2.34-118.patch new file mode 100644 index 0000000..b2b028e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-118.patch @@ -0,0 +1,146 @@ +commit c6f9085ee4e913a0b8260340ac7b75c426b780ce +Author: John David Anglin +Date: Fri Feb 18 20:38:25 2022 +0000 + + hppa: Fix swapcontext + + This change fixes the failure of stdlib/tst-setcontext2 and + stdlib/tst-setcontext7 on hppa. The implementation of swapcontext + in C is broken. C saves the return pointer (rp) and any non + call-clobbered registers (in this case r3, r4 and r5) on the + stack. However, the setcontext call in swapcontext pops the + stack and subsequent calls clobber the saved registers. When + the context in oucp is restored, both tests fault. + + Here we rewrite swapcontext in assembly code to avoid using + the stack for register values that need to be used after + restoration. The getcontext and setcontext routines are + revised to save and restore register ret1 for normal returns. + We copy the oucp pointer to ret1. This allows access to + the old context after calling getcontext and setcontext. + + (cherry picked from commit 71b108d7eb33b2bf3e61d5e92d2a47f74c1f7d96) + +diff --git a/sysdeps/unix/sysv/linux/hppa/getcontext.S b/sysdeps/unix/sysv/linux/hppa/getcontext.S +index 1405b42819c38993..c8b690aab8ecc47c 100644 +--- a/sysdeps/unix/sysv/linux/hppa/getcontext.S ++++ b/sysdeps/unix/sysv/linux/hppa/getcontext.S +@@ -138,6 +138,8 @@ ENTRY(__getcontext) + stw %r19, -32(%sp) + .cfi_offset 19, 32 + #endif ++ stw %ret1, -60(%sp) ++ .cfi_offset 29, 4 + + /* Set up the trampoline registers. + r20, r23, r24, r25, r26 and r2 are clobbered +@@ -168,6 +170,7 @@ ENTRY(__getcontext) + #ifdef PIC + ldw -32(%sp), %r19 + #endif ++ ldw -60(%sp), %ret1 + bv %r0(%r2) + ldwm -64(%sp), %r4 + END(__getcontext) +diff --git a/sysdeps/unix/sysv/linux/hppa/setcontext.S b/sysdeps/unix/sysv/linux/hppa/setcontext.S +index 8fc5f5e56cb31f51..e1ae3aefcaac198d 100644 +--- a/sysdeps/unix/sysv/linux/hppa/setcontext.S ++++ b/sysdeps/unix/sysv/linux/hppa/setcontext.S +@@ -34,6 +34,8 @@ ENTRY(__setcontext) + stw %r19, -32(%sp) + .cfi_offset 19, 32 + #endif ++ stw %ret1, -60(%sp) ++ .cfi_offset 29, 4 + + /* Save ucp. */ + copy %r26, %r3 +@@ -155,6 +157,7 @@ ENTRY(__setcontext) + #ifdef PIC + ldw -32(%r30), %r19 + #endif ++ ldw -60(%r30), %ret1 + bv %r0(%r2) + ldwm -64(%r30), %r3 + L(pseudo_end): +diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.c b/sysdeps/unix/sysv/linux/hppa/swapcontext.c +index f9a8207543c164cb..562f00ff0546177d 100644 +--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.c ++++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.c +@@ -18,6 +18,7 @@ + . */ + + #include ++#include "ucontext_i.h" + + extern int __getcontext (ucontext_t *ucp); + extern int __setcontext (const ucontext_t *ucp); +@@ -25,17 +26,61 @@ extern int __setcontext (const ucontext_t *ucp); + int + __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) + { ++ /* Save ucp in stack argument slot. */ ++ asm ("stw %r25,-40(%sp)"); ++ asm (".cfi_offset 25, -40"); ++ ++ /* Save rp for debugger. */ ++ asm ("stw %rp,-20(%sp)"); ++ asm (".cfi_offset 2, -20"); ++ ++ /* Copy rp to ret0 (r28). */ ++ asm ("copy %rp,%ret0"); ++ ++ /* Create a frame. */ ++ asm ("ldo 64(%sp),%sp"); ++ asm (".cfi_def_cfa_offset -64"); ++ + /* Save the current machine context to oucp. */ +- __getcontext (oucp); ++ asm ("bl __getcontext,%rp"); ++ ++ /* Copy oucp to register ret1 (r29). __getcontext saves and restores it ++ on a normal return. It is restored from oR29 on reactivation. */ ++ asm ("copy %r26,%ret1"); ++ ++ /* Pop frame. */ ++ asm ("ldo -64(%sp),%sp"); ++ asm (".cfi_def_cfa_offset 0"); ++ ++ /* Load return pointer from oR28. */ ++ asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28)); ++ ++ /* Return if error. */ ++ asm ("or,= %r0,%ret0,%r0"); ++ asm ("bv,n %r0(%rp)"); ++ ++ /* Load sc_sar flag. */ ++ asm ("ldw %0(%%ret1),%%r20" : : "i" (oSAR)); ++ ++ /* Return if oucp context has been reactivated. */ ++ asm ("or,= %r0,%r20,%r0"); ++ asm ("bv,n %r0(%rp)"); ++ ++ /* Mark sc_sar flag. */ ++ asm ("1: ldi 1,%r20"); ++ asm ("stw %%r20,%0(%%ret1)" : : "i" (oSAR)); ++ ++ /* Activate the machine context in ucp. */ ++ asm ("bl __setcontext,%rp"); ++ asm ("ldw -40(%sp),%r26"); + +- /* mark sc_sar flag to skip the setcontext call on reactivation. */ +- if (oucp->uc_mcontext.sc_sar == 0) { +- oucp->uc_mcontext.sc_sar++; ++ /* Load return pointer. */ ++ asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28)); + +- /* Restore the machine context in ucp. */ +- __setcontext (ucp); +- } ++ /* A successful call to setcontext does not return. */ ++ asm ("bv,n %r0(%rp)"); + ++ /* Make gcc happy. */ + return 0; + } + diff --git a/SOURCES/glibc-upstream-2.34-119.patch b/SOURCES/glibc-upstream-2.34-119.patch new file mode 100644 index 0000000..cc25de7 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-119.patch @@ -0,0 +1,177 @@ +commit f610d2935f041c5f41ddcb96924ea42ca2fb5ea5 +Author: John David Anglin +Date: Tue Feb 22 17:28:46 2022 +0000 + + hppa: Revise gettext trampoline design + + The current getcontext return trampoline is overly complex and it + unnecessarily clobbers several registers. By saving the context + pointer (r26) in the context, __getcontext_ret can restore any + registers not restored by setcontext. This allows getcontext to + save and restore the entire register context present when getcontext + is entered. We use the unused oR0 context slot for the return + from __getcontext_ret. + + While this is not directly useful in C, it can be exploited in + assembly code. Registers r20, r23, r24 and r25 are not clobbered + in the call path to getcontext. This allows a small simplification + of swapcontext. + + It also allows saving and restoring the 6-bit SAR register in the + LSB of the oSAR context slot. The getcontext flag value can be + stored in the MSB of the oSAR slot. + + (cherry picked from commit 9e7e5fda38471e00d1190479ea91d7b08ae3e304) + +diff --git a/sysdeps/unix/sysv/linux/hppa/getcontext.S b/sysdeps/unix/sysv/linux/hppa/getcontext.S +index c8b690aab8ecc47c..4f2e2587d60effc8 100644 +--- a/sysdeps/unix/sysv/linux/hppa/getcontext.S ++++ b/sysdeps/unix/sysv/linux/hppa/getcontext.S +@@ -22,22 +22,28 @@ + #include "ucontext_i.h" + + +- /* Trampoline function. Non-standard calling ABI. */ ++ /* Trampoline function. Non-standard calling ABI. */ + /* Can not use ENTRY(__getcontext_ret) here. */ + .type __getcontext_ret, @function + .hidden __getcontext_ret + __getcontext_ret: + .proc + .callinfo FRAME=0,NO_CALLS +- /* r26-r23 contain original r3-r6, but because setcontext +- does not reload r3-r6 (it's using them as temporaries) +- we must save them elsewhere and swap them back in. */ +- copy %r23, %r3 +- copy %r24, %r4 +- copy %r25, %r5 +- copy %r26, %r6 +- /* r20 contains original return pointer. */ +- bv 0(%r20) ++ /* Because setcontext does not reload r3-r6 (it's using them ++ as temporaries), we must load them ourself. */ ++ ldw oR3(%r26), %r3 ++ ldw oR4(%r26), %r4 ++ ldw oR5(%r26), %r5 ++ ldw oR6(%r26), %r6 ++ ++ /* Also reload registers clobbered by $$dyncall. */ ++ ldw oR21(%r26), %r21 ++ ldw oR22(%r26), %r22 ++ ldw oR31(%r26), %r31 ++ ++ /* oR0 contains original return pointer. */ ++ ldw oR0(%r26), %rp ++ bv 0(%rp) + copy %r0, %ret0 + .procend + .size __getcontext_ret, .-__getcontext_ret +@@ -65,13 +71,13 @@ ENTRY(__getcontext) + stw %r17, oR17(%r26) + stw %r18, oR18(%r26) + stw %r19, oR19(%r26) +- /* stw %r20, oR20(%r26) - used for trampoline. */ ++ stw %r20, oR20(%r26) + stw %r21, oR21(%r26) + stw %r22, oR22(%r26) +- /* stw %r23, oR23(%r26) - used for trampoline. */ +- /* stw %r24, oR24(%r26) - used for trampoline. */ +- /* stw %r25, oR25(%r26) - used for trampoline. */ +- /* stw %r26, oR26(%r26) - used for trampoline. */ ++ stw %r23, oR23(%r26) ++ stw %r24, oR24(%r26) ++ stw %r25, oR25(%r26) ++ stw %r26, oR26(%r26) + stw %r27, oR27(%r26) + stw %r28, oR28(%r26) + stw %r29, oR29(%r26) +@@ -90,7 +96,10 @@ ENTRY(__getcontext) + stw %r0, oIASQ1(%r26) + stw %r0, oIAOQ0(%r26) + stw %r0, oIAOQ1(%r26) +- stw %r0, oSAR(%r26) /* used as flag in swapcontext(). */ ++ ++ /* Save SAR register. */ ++ mfctl %sar, %r1 ++ stw %r1, oSAR(%r26) /* MSB used as flag in swapcontext(). */ + + + /* Store floating-point regs. */ +@@ -142,13 +151,8 @@ ENTRY(__getcontext) + .cfi_offset 29, 4 + + /* Set up the trampoline registers. +- r20, r23, r24, r25, r26 and r2 are clobbered +- by call to getcontext() anyway. Reuse them. */ +- stw %r2, oR20(%r26) +- stw %r3, oR23(%r26) +- stw %r4, oR24(%r26) +- stw %r5, oR25(%r26) +- stw %r6, oR26(%r26) ++ Use oR0 context slot to save return value. */ ++ stw %r2, oR0(%r26) + #ifdef PIC + addil LT%__getcontext_ret, %r19 + ldw RT%__getcontext_ret(%r1), %r1 +diff --git a/sysdeps/unix/sysv/linux/hppa/setcontext.S b/sysdeps/unix/sysv/linux/hppa/setcontext.S +index e1ae3aefcaac198d..616405b80c61d531 100644 +--- a/sysdeps/unix/sysv/linux/hppa/setcontext.S ++++ b/sysdeps/unix/sysv/linux/hppa/setcontext.S +@@ -76,7 +76,7 @@ ENTRY(__setcontext) + ldw oR18(%r3), %r18 + ldw oR19(%r3), %r19 + ldw oR20(%r3), %r20 +- ldw oR21(%r3), %r21 ++ ldw oR21(%r3), %r21 /* maybe clobbered by dyncall */ + /* ldw oR22(%r3), %r22 - dyncall arg. */ + ldw oR23(%r3), %r23 + ldw oR24(%r3), %r24 +@@ -88,6 +88,10 @@ ENTRY(__setcontext) + ldw oR30(%r3), %sp + /* ldw oR31(%r3), %r31 - dyncall scratch register */ + ++ /* Restore SAR register. */ ++ ldw oSAR(%r3), %r22 ++ mtsar %r22 ++ + /* Restore floating-point registers. */ + ldo oFPREGS31(%r3), %r22 + fldds 0(%r22), %fr31 +diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.c b/sysdeps/unix/sysv/linux/hppa/swapcontext.c +index 562f00ff0546177d..1664f68c7b9982e8 100644 +--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.c ++++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.c +@@ -26,10 +26,6 @@ extern int __setcontext (const ucontext_t *ucp); + int + __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) + { +- /* Save ucp in stack argument slot. */ +- asm ("stw %r25,-40(%sp)"); +- asm (".cfi_offset 25, -40"); +- + /* Save rp for debugger. */ + asm ("stw %rp,-20(%sp)"); + asm (".cfi_offset 2, -20"); +@@ -60,7 +56,7 @@ __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) + asm ("bv,n %r0(%rp)"); + + /* Load sc_sar flag. */ +- asm ("ldw %0(%%ret1),%%r20" : : "i" (oSAR)); ++ asm ("ldb %0(%%ret1),%%r20" : : "i" (oSAR)); + + /* Return if oucp context has been reactivated. */ + asm ("or,= %r0,%r20,%r0"); +@@ -68,11 +64,11 @@ __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) + + /* Mark sc_sar flag. */ + asm ("1: ldi 1,%r20"); +- asm ("stw %%r20,%0(%%ret1)" : : "i" (oSAR)); ++ asm ("stb %%r20,%0(%%ret1)" : : "i" (oSAR)); + + /* Activate the machine context in ucp. */ + asm ("bl __setcontext,%rp"); +- asm ("ldw -40(%sp),%r26"); ++ asm ("ldw %0(%%ret1),%%r26" : : "i" (oR25)); + + /* Load return pointer. */ + asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28)); diff --git a/SOURCES/glibc-upstream-2.34-12.patch b/SOURCES/glibc-upstream-2.34-12.patch new file mode 100644 index 0000000..ef0ec20 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-12.patch @@ -0,0 +1,117 @@ +commit addc9d62d61eea790a35328cbfce53333a07bd3e +Author: Florian Weimer +Date: Mon Aug 30 13:43:56 2021 +0200 + + support: Add support_wait_for_thread_exit + + (cherry picked from commit 032d74eaf6179100048a5bf0ce942e97dc8b9a60) + +diff --git a/support/Makefile b/support/Makefile +index a462781718426d35..ef2b1a980a407f8f 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -82,9 +82,10 @@ libsupport-routines = \ + support_test_compare_blob \ + support_test_compare_failure \ + support_test_compare_string \ +- support_write_file_string \ + support_test_main \ + support_test_verify_impl \ ++ support_wait_for_thread_exit \ ++ support_write_file_string \ + temp_file \ + timespec \ + timespec-time64 \ +diff --git a/support/support.h b/support/support.h +index 834dba909770a992..a5978b939af2fb41 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -174,6 +174,10 @@ timer_t support_create_timer (uint64_t sec, long int nsec, bool repeat, + /* Disable the timer TIMER. */ + void support_delete_timer (timer_t timer); + ++/* Wait until all threads except the current thread have exited (as ++ far as the kernel is concerned). */ ++void support_wait_for_thread_exit (void); ++ + struct support_stack + { + void *stack; +diff --git a/support/support_wait_for_thread_exit.c b/support/support_wait_for_thread_exit.c +new file mode 100644 +index 0000000000000000..658a81381006ea62 +--- /dev/null ++++ b/support/support_wait_for_thread_exit.c +@@ -0,0 +1,72 @@ ++/* Wait until all threads except the current thread has exited. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void ++support_wait_for_thread_exit (void) ++{ ++#ifdef __linux__ ++ DIR *proc_self_task = opendir ("/proc/self/task"); ++ TEST_VERIFY_EXIT (proc_self_task != NULL); ++ ++ while (true) ++ { ++ errno = 0; ++ struct dirent *e = readdir (proc_self_task); ++ if (e == NULL && errno != 0) ++ FAIL_EXIT1 ("readdir: %m"); ++ if (e == NULL) ++ { ++ /* Only the main thread remains. Testing may continue. */ ++ closedir (proc_self_task); ++ return; ++ } ++ ++ if (strcmp (e->d_name, ".") == 0 || strcmp (e->d_name, "..") == 0) ++ continue; ++ ++ int task_tid = atoi (e->d_name); ++ if (task_tid <= 0) ++ FAIL_EXIT1 ("Invalid /proc/self/task entry: %s", e->d_name); ++ ++ if (task_tid == gettid ()) ++ /* The current thread. Keep scanning for other ++ threads. */ ++ continue; ++ ++ /* task_tid does not refer to this thread here, i.e., there is ++ another running thread. */ ++ ++ /* Small timeout to give the thread a chance to exit. */ ++ usleep (50 * 1000); ++ ++ /* Start scanning the directory from the start. */ ++ rewinddir (proc_self_task); ++ } ++#else ++ /* Use a large timeout because we cannot verify that the thread has ++ exited. */ ++ usleep (5 * 1000 * 1000); ++#endif ++} diff --git a/SOURCES/glibc-upstream-2.34-120.patch b/SOURCES/glibc-upstream-2.34-120.patch new file mode 100644 index 0000000..2fe0c55 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-120.patch @@ -0,0 +1,27 @@ +commit 40fc6a74ee3dd600c84d311d91cbb16962f11a71 +Author: John David Anglin +Date: Mon Feb 28 15:47:38 2022 +0000 + + nptl: Fix cleanups for stack grows up [BZ# 28899] + + _STACK_GROWS_DOWN is defined to 0 when the stack grows up. The + code in unwind.c used `#ifdef _STACK_GROWS_DOWN' to selct the + stack grows down define for FRAME_LEFT. As a result, the + _STACK_GROWS_DOWN define was always selected and cleanups were + incorrectly sequenced when the stack grows up. + + (cherry picked from commit 2bbc694df279020a6620096d31c1e05c93966f9b) + +diff --git a/nptl/unwind.c b/nptl/unwind.c +index f50997f728ccde0d..404fab46d00e9f10 100644 +--- a/nptl/unwind.c ++++ b/nptl/unwind.c +@@ -27,7 +27,7 @@ + #include + #include + +-#ifdef _STACK_GROWS_DOWN ++#if _STACK_GROWS_DOWN + # define FRAME_LEFT(frame, other, adj) \ + ((uintptr_t) frame - adj >= (uintptr_t) other - adj) + #elif _STACK_GROWS_UP diff --git a/SOURCES/glibc-upstream-2.34-121.patch b/SOURCES/glibc-upstream-2.34-121.patch new file mode 100644 index 0000000..3f74efd --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-121.patch @@ -0,0 +1,122 @@ +commit 6c9c2307657529e52c5fa7037618835f2a50b916 +Author: John David Anglin +Date: Sun Mar 6 16:04:32 2022 +0000 + + hppa: Fix warnings from _dl_lookup_address + + This change fixes two warnings from _dl_lookup_address. + + The first warning comes from dropping the volatile keyword from + desc in the call to _dl_read_access_allowed. We now have a full + atomic barrier between loading desc[0] and the access check, so + desc no longer needs to be declared as volatile. + + The second warning comes from the implicit declaration of + _dl_fix_reloc_arg. This is fixed by including dl-runtime.h and + declaring _dl_fix_reloc_arg in dl-runtime.h. + +diff --git a/sysdeps/hppa/dl-fptr.c b/sysdeps/hppa/dl-fptr.c +index 62ef68b62bd601f4..cd4f77c0ecfd376f 100644 +--- a/sysdeps/hppa/dl-fptr.c ++++ b/sysdeps/hppa/dl-fptr.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -351,21 +352,20 @@ _dl_lookup_address (const void *address) + { + ElfW(Addr) addr = (ElfW(Addr)) address; + ElfW(Word) reloc_arg; +- volatile unsigned int *desc; +- unsigned int *gptr; ++ unsigned int *desc, *gptr; + + /* Return ADDR if the least-significant two bits of ADDR are not consistent + with ADDR being a linker defined function pointer. The normal value for + a code address in a backtrace is 3. */ +- if (((unsigned int) addr & 3) != 2) ++ if (((uintptr_t) addr & 3) != 2) + return addr; + + /* Handle special case where ADDR points to page 0. */ +- if ((unsigned int) addr < 4096) ++ if ((uintptr_t) addr < 4096) + return addr; + + /* Clear least-significant two bits from descriptor address. */ +- desc = (unsigned int *) ((unsigned int) addr & ~3); ++ desc = (unsigned int *) ((uintptr_t) addr & ~3); + if (!_dl_read_access_allowed (desc)) + return addr; + +@@ -376,7 +376,7 @@ _dl_lookup_address (const void *address) + /* Then load first word of candidate descriptor. It should be a pointer + with word alignment and point to memory that can be read. */ + gptr = (unsigned int *) desc[0]; +- if (((unsigned int) gptr & 3) != 0 ++ if (((uintptr_t) gptr & 3) != 0 + || !_dl_read_access_allowed (gptr)) + return addr; + +@@ -400,10 +400,11 @@ _dl_lookup_address (const void *address) + + /* If gp has been resolved, we need to hunt for relocation offset. */ + if (!(reloc_arg & PA_GP_RELOC)) +- reloc_arg = _dl_fix_reloc_arg (addr, l); ++ reloc_arg = _dl_fix_reloc_arg ((struct fdesc *) addr, l); + + _dl_fixup (l, reloc_arg); + } + + return (ElfW(Addr)) desc[0]; + } ++rtld_hidden_def (_dl_lookup_address) +diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h +index a9a927f26c6fec09..2f6991aa16e87a00 100644 +--- a/sysdeps/hppa/dl-lookupcfg.h ++++ b/sysdeps/hppa/dl-lookupcfg.h +@@ -30,6 +30,7 @@ rtld_hidden_proto (_dl_symbol_address) + #define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref) + + Elf32_Addr _dl_lookup_address (const void *address); ++rtld_hidden_proto (_dl_lookup_address) + + #define DL_LOOKUP_ADDRESS(addr) _dl_lookup_address ((const void *) addr) + +diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c +index e7fbb7417d866bb0..a71b5b2013abf723 100644 +--- a/sysdeps/hppa/dl-runtime.c ++++ b/sysdeps/hppa/dl-runtime.c +@@ -25,8 +25,7 @@ + return that to the caller. The caller will continue on to call + _dl_fixup with the relocation offset. */ + +-ElfW(Word) +-attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE ++ElfW(Word) __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE + _dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l) + { + Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type; +@@ -52,3 +51,4 @@ _dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l) + ABORT_INSTRUCTION; + return 0; + } ++rtld_hidden_def (_dl_fix_reloc_arg) +diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h +index 5d6ee53b076d5e0e..9913539b5f0e7435 100644 +--- a/sysdeps/hppa/dl-runtime.h ++++ b/sysdeps/hppa/dl-runtime.h +@@ -17,6 +17,9 @@ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + ++ElfW(Word) _dl_fix_reloc_arg (struct fdesc *, struct link_map *); ++rtld_hidden_proto (_dl_fix_reloc_arg) ++ + /* Clear PA_GP_RELOC bit in relocation offset. */ + static inline uintptr_t + reloc_offset (uintptr_t plt0, uintptr_t pltn) diff --git a/SOURCES/glibc-upstream-2.34-122.patch b/SOURCES/glibc-upstream-2.34-122.patch new file mode 100644 index 0000000..e628384 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-122.patch @@ -0,0 +1,26 @@ +commit b5032c3d37aa614644c7afbad33bb8226a52e6da +Author: Florian Weimer +Date: Mon Feb 28 11:50:41 2022 +0100 + + io: Add fsync call in tst-stat + + io/tst-stat and io/tst-stat-lfs fail sporadically on the Fedora + builders, and this change hopefully helps to avoid the issue. + + (cherry picked from commit ae132284092edc5885315b44cd17d5ea91177e49) + +diff --git a/io/tst-stat.c b/io/tst-stat.c +index 82e965de6ad87f61..be20cf16d70d05cc 100644 +--- a/io/tst-stat.c ++++ b/io/tst-stat.c +@@ -69,6 +69,10 @@ do_test (void) + TEST_VERIFY_EXIT (fd >= 0); + support_write_file_string (path, "abc"); + ++ /* This should help to prevent delayed allocation, which may result ++ in a spurious stx_blocks/st_blocks difference. */ ++ fsync (fd); ++ + bool check_ns = support_stat_nanoseconds (path); + if (!check_ns) + printf ("warning: timestamp with nanoseconds not supported\n"); diff --git a/SOURCES/glibc-upstream-2.34-123.patch b/SOURCES/glibc-upstream-2.34-123.patch new file mode 100644 index 0000000..22b1d2a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-123.patch @@ -0,0 +1,56 @@ +commit b53f0c11de409b04560a70570178d1a9d03d5860 +Author: Florian Weimer +Date: Fri Mar 11 08:23:56 2022 +0100 + + nss: Do not mention NSS test modules in + + They are not actually installed. Use the nss_files version instead + in nss/Makefile, similar to how __nss_shlib_revision is derived + from LIBNSS_FILES_SO. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit aefc79ab5ad4bb9feea2876720cec70dca7cd8ed) + +diff --git a/nss/Makefile b/nss/Makefile +index bccf9f2806c15651..e223243d9d62041c 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -171,17 +171,14 @@ $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) + $(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps) + $(build-module) + $(objpfx)nss_test2.os : nss_test1.c +-ifdef libnss_test1.so-version +-$(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so ++# Use the nss_files suffix for these objects as well. ++$(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so + $(make-link) +-endif +-ifdef libnss_test2.so-version +-$(objpfx)/libnss_test2.so$(libnss_test2.so-version): $(objpfx)/libnss_test2.so ++$(objpfx)/libnss_test2.so$(libnss_files.so-version): $(objpfx)/libnss_test2.so + $(make-link) +-endif + $(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \ +- $(objpfx)/libnss_test1.so$(libnss_test1.so-version) \ +- $(objpfx)/libnss_test2.so$(libnss_test2.so-version) ++ $(objpfx)/libnss_test1.so$(libnss_files.so-version) \ ++ $(objpfx)/libnss_test2.so$(libnss_files.so-version) + + ifeq (yes,$(have-thread-library)) + $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library) +diff --git a/shlib-versions b/shlib-versions +index df6603e6992b8382..b87ab50c59af1bfd 100644 +--- a/shlib-versions ++++ b/shlib-versions +@@ -47,11 +47,6 @@ libnss_ldap=2 + libnss_hesiod=2 + libnss_db=2 + +-# Tests for NSS. They must have the same NSS_SHLIB_REVISION number as +-# the rest. +-libnss_test1=2 +-libnss_test2=2 +- + # Version for libnsl with YP and NIS+ functions. + libnsl=1 + diff --git a/SOURCES/glibc-upstream-2.34-124.patch b/SOURCES/glibc-upstream-2.34-124.patch new file mode 100644 index 0000000..0ee2830 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-124.patch @@ -0,0 +1,224 @@ +commit 54b12733959238204d7b0e46e69fc7f7d8890b20 +Author: Florian Weimer +Date: Fri Mar 11 08:23:56 2022 +0100 + + nss: Protect against errno changes in function lookup (bug 28953) + + dlopen may clobber errno. The nss_test_errno module uses an ELF + constructor to achieve that, but there could be internal errors + during dlopen that cause this, too. Therefore, the NSS framework + has to guard against such errno clobbers. + + __nss_module_get_function is currently the only function that calls + __nss_module_load, so it is sufficient to save and restore errno + around this call. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit 9bdf92c79d63b42f931101bb6df87129c408b0c4) + +diff --git a/nss/Makefile b/nss/Makefile +index e223243d9d62041c..716bc8f6ef5276b0 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -60,7 +60,8 @@ tests = test-netdb test-digits-dots tst-nss-getpwent bug17079 \ + tst-nss-test1 \ + tst-nss-test2 \ + tst-nss-test4 \ +- tst-nss-test5 ++ tst-nss-test5 \ ++ tst-nss-test_errno + xtests = bug-erange + + tests-container = \ +@@ -132,7 +133,7 @@ libnss_compat-inhibit-o = $(filter-out .os,$(object-suffixes)) + ifeq ($(build-static-nss),yes) + tests-static += tst-nss-static + endif +-extra-test-objs += nss_test1.os nss_test2.os ++extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os + + include ../Rules + +@@ -166,19 +167,26 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver + + libof-nss_test1 = extramodules + libof-nss_test2 = extramodules ++libof-nss_test_errno = extramodules + $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) + $(build-module) + $(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps) + $(build-module) ++$(objpfx)/libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps) ++ $(build-module) + $(objpfx)nss_test2.os : nss_test1.c + # Use the nss_files suffix for these objects as well. + $(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so + $(make-link) + $(objpfx)/libnss_test2.so$(libnss_files.so-version): $(objpfx)/libnss_test2.so + $(make-link) ++$(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \ ++ $(objpfx)/libnss_test_errno.so ++ $(make-link) + $(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \ + $(objpfx)/libnss_test1.so$(libnss_files.so-version) \ +- $(objpfx)/libnss_test2.so$(libnss_files.so-version) ++ $(objpfx)/libnss_test2.so$(libnss_files.so-version) \ ++ $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) + + ifeq (yes,$(have-thread-library)) + $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library) +diff --git a/nss/nss_module.c b/nss/nss_module.c +index b28cb94a6a0aeb41..3a4a464256121e41 100644 +--- a/nss/nss_module.c ++++ b/nss/nss_module.c +@@ -330,8 +330,18 @@ name_search (const void *left, const void *right) + void * + __nss_module_get_function (struct nss_module *module, const char *name) + { ++ /* A successful dlopen might clobber errno. */ ++ int saved_errno = errno; ++ + if (!__nss_module_load (module)) +- return NULL; ++ { ++ /* Reporting module load failure is currently inaccurate. See ++ bug 22041. Not changing errno is the conservative choice. */ ++ __set_errno (saved_errno); ++ return NULL; ++ } ++ ++ __set_errno (saved_errno); + + function_name *name_entry = bsearch (name, nss_function_name_array, + array_length (nss_function_name_array), +diff --git a/nss/nss_test_errno.c b/nss/nss_test_errno.c +new file mode 100644 +index 0000000000000000..680f8a07b97fe263 +--- /dev/null ++++ b/nss/nss_test_errno.c +@@ -0,0 +1,58 @@ ++/* NSS service provider with errno clobber. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* Catch misnamed and functions. */ ++#pragma GCC diagnostic error "-Wmissing-prototypes" ++NSS_DECLARE_MODULE_FUNCTIONS (test_errno) ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ /* An arbitrary error code which is otherwise not used. */ ++ errno = ELIBBAD; ++} ++ ++/* Lookup functions for pwd follow that do not return any data. */ ++ ++/* Catch misnamed function definitions. */ ++ ++enum nss_status ++_nss_test_errno_setpwent (int stayopen) ++{ ++ setenv ("_nss_test_errno_setpwent", "yes", 1); ++ return NSS_STATUS_SUCCESS; ++} ++ ++enum nss_status ++_nss_test_errno_getpwent_r (struct passwd *result, ++ char *buffer, size_t size, int *errnop) ++{ ++ setenv ("_nss_test_errno_getpwent_r", "yes", 1); ++ return NSS_STATUS_NOTFOUND; ++} ++ ++enum nss_status ++_nss_test_errno_endpwent (void) ++{ ++ setenv ("_nss_test_errno_endpwent", "yes", 1); ++ return NSS_STATUS_SUCCESS; ++} +diff --git a/nss/tst-nss-test_errno.c b/nss/tst-nss-test_errno.c +new file mode 100644 +index 0000000000000000..d2c42dd363a38b0e +--- /dev/null ++++ b/nss/tst-nss-test_errno.c +@@ -0,0 +1,61 @@ ++/* getpwent failure when dlopen clobbers errno (bug 28953). ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ __nss_configure_lookup ("passwd", "files test_errno"); ++ ++ errno = 0; ++ setpwent (); ++ TEST_COMPARE (errno, 0); ++ ++ bool root_seen = false; ++ while (true) ++ { ++ errno = 0; ++ struct passwd *e = getpwent (); ++ if (e == NULL) ++ break; ++ if (strcmp (e->pw_name, "root")) ++ root_seen = true; ++ } ++ ++ TEST_COMPARE (errno, 0); ++ TEST_VERIFY (root_seen); ++ ++ errno = 0; ++ endpwent (); ++ TEST_COMPARE (errno, 0); ++ ++ TEST_COMPARE_STRING (getenv ("_nss_test_errno_setpwent"), "yes"); ++ TEST_COMPARE_STRING (getenv ("_nss_test_errno_getpwent_r"), "yes"); ++ TEST_COMPARE_STRING (getenv ("_nss_test_errno_endpwent"), "yes"); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-125.patch b/SOURCES/glibc-upstream-2.34-125.patch new file mode 100644 index 0000000..208da9b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-125.patch @@ -0,0 +1,345 @@ +commit c82bdf033f93a710044e25f721340c26e89a3769 +Author: Siddhesh Poyarekar +Date: Tue Oct 12 12:29:13 2021 +0530 + + Don't add access size hints to fortifiable functions + + In the context of a function definition, the size hints imply that the + size of an object pointed to by one parameter is another parameter. + This doesn't make sense for the fortified versions of the functions + since that's the bit it's trying to validate. + + This is harmless with __builtin_object_size since it has fairly simple + semantics when it comes to objects passed as function parameters. + With __builtin_dynamic_object_size we could (as my patchset for gcc[1] + already does) use the access attribute to determine the object size in + the general case but it misleads the fortified functions. + + Basically the problem occurs when access attributes are present on + regular functions that have inline fortified definitions to generate + _chk variants; the attributes get inherited by these definitions, + causing problems when analyzing them. For example with poll(fds, nfds, + timeout), nfds is hinted using the __attr_access as being the size of + fds. + + Now, when analyzing the inline function definition in bits/poll2.h, the + compiler sees that nfds is the size of fds and tries to use that + information in the function body. In _FORTIFY_SOURCE=3 case, where the + object size could be a non-constant expression, this information results + in the conclusion that nfds is the size of fds, which defeats the + purpose of the implementation because we're trying to check here if nfds + does indeed represent the size of fds. Hence for this case, it is best + to not have the access attribute. + + With the attributes gone, the expression evaluation should get delayed + until the function is actually inlined into its destinations. + + Disable the access attribute for fortified function inline functions + when building at _FORTIFY_SOURCE=3 to make this work better. The + access attributes remain for the _chk variants since they can be used + by the compiler to warn when the caller is passing invalid arguments. + + [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581125.html + + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit e938c02748402c50f60ba0eb983273e7b52937d1) + +diff --git a/io/bits/poll2.h b/io/bits/poll2.h +index a623678c09f9f04f..be74d020f2e0e434 100644 +--- a/io/bits/poll2.h ++++ b/io/bits/poll2.h +@@ -33,7 +33,7 @@ extern int __REDIRECT (__poll_chk_warn, (struct pollfd *__fds, nfds_t __nfds, + __poll_chk) + __warnattr ("poll called with fds buffer too small file nfds entries"); + +-__fortify_function __attr_access ((__write_only__, 1, 2)) int ++__fortify_function __fortified_attr_access (__write_only__, 1, 2) int + poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) + { + if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1) +@@ -64,7 +64,7 @@ extern int __REDIRECT (__ppoll_chk_warn, (struct pollfd *__fds, nfds_t __nfds, + __ppoll_chk) + __warnattr ("ppoll called with fds buffer too small file nfds entries"); + +-__fortify_function __attr_access ((__write_only__, 1, 2)) int ++__fortify_function __fortified_attr_access (__write_only__, 1, 2) int + ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout, + const __sigset_t *__ss) + { +diff --git a/io/sys/poll.h b/io/sys/poll.h +index e640efb2bce7ea67..751c7f5f72db8be2 100644 +--- a/io/sys/poll.h ++++ b/io/sys/poll.h +@@ -52,7 +52,7 @@ __BEGIN_DECLS + This function is a cancellation point and therefore not marked with + __THROW. */ + extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) +- __attr_access ((__write_only__, 1, 2)); ++ __fortified_attr_access (__write_only__, 1, 2); + + #ifdef __USE_GNU + /* Like poll, but before waiting the threads signal mask is replaced +@@ -64,7 +64,7 @@ extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) + extern int ppoll (struct pollfd *__fds, nfds_t __nfds, + const struct timespec *__timeout, + const __sigset_t *__ss) +- __attr_access ((__write_only__, 1, 2)); ++ __fortified_attr_access (__write_only__, 1, 2); + + # ifdef __USE_TIME_BITS64 + # ifdef __REDIRECT +@@ -72,7 +72,7 @@ extern int __REDIRECT (ppoll, (struct pollfd *__fds, nfds_t __nfds, + const struct timespec *__timeout, + const __sigset_t *__ss), + __ppoll64) +- __attr_access ((__write_only__, 1, 2)); ++ __fortified_attr_access (__write_only__, 1, 2); + # else + # define ppoll __ppoll64 + # endif +diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h +index 3f0cab1254b02c43..4f016a563857a137 100644 +--- a/libio/bits/stdio2.h ++++ b/libio/bits/stdio2.h +@@ -258,7 +258,7 @@ extern char *__REDIRECT (__fgets_chk_warn, + __wur __warnattr ("fgets called with bigger size than length " + "of destination buffer"); + +-__fortify_function __wur __attr_access ((__write_only__, 1, 2)) char * ++__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char * + fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + { + if (__glibc_objsize (__s) != (size_t) -1) +@@ -320,7 +320,7 @@ extern char *__REDIRECT (__fgets_unlocked_chk_warn, + __wur __warnattr ("fgets_unlocked called with bigger size than length " + "of destination buffer"); + +-__fortify_function __wur __attr_access ((__write_only__, 1, 2)) char * ++__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char * + fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) + { + if (__glibc_objsize (__s) != (size_t) -1) +diff --git a/libio/stdio.h b/libio/stdio.h +index 497da016ffa2e230..abefe640e52d18d5 100644 +--- a/libio/stdio.h ++++ b/libio/stdio.h +@@ -584,7 +584,7 @@ extern int putw (int __w, FILE *__stream); + This function is a possible cancellation point and therefore not + marked with __THROW. */ + extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) +- __wur __attr_access ((__write_only__, 1, 2)); ++ __wur __fortified_attr_access (__write_only__, 1, 2); + + #if __GLIBC_USE (DEPRECATED_GETS) + /* Get a newline-terminated string from stdin, removing the newline. +@@ -608,7 +608,7 @@ extern char *gets (char *__s) __wur __attribute_deprecated__; + therefore not marked with __THROW. */ + extern char *fgets_unlocked (char *__restrict __s, int __n, + FILE *__restrict __stream) __wur +- __attr_access ((__write_only__, 1, 2)); ++ __fortified_attr_access (__write_only__, 1, 2); + #endif + + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index e490fc1aebeadc3d..cd836441a9807d6a 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -603,12 +603,22 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf + size-index is not provided: + access (access-mode, [, ]) */ + # define __attr_access(x) __attribute__ ((__access__ x)) ++/* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may ++ use the access attribute to get object sizes from function definition ++ arguments, so we can't use them on functions we fortify. Drop the object ++ size hints for such functions. */ ++# if __USE_FORTIFY_LEVEL == 3 ++# define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, o))) ++# else ++# define __fortified_attr_access(a, o, s) __attr_access ((a, o, s)) ++# endif + # if __GNUC_PREREQ (11, 0) + # define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno))) + # else + # define __attr_access_none(argno) + # endif + #else ++# define __fortified_attr_access(a, o, s) + # define __attr_access(x) + # define __attr_access_none(argno) + #endif +diff --git a/posix/unistd.h b/posix/unistd.h +index 8224c5fbc956306f..7a61ff5e868c3456 100644 +--- a/posix/unistd.h ++++ b/posix/unistd.h +@@ -369,7 +369,7 @@ extern void closefrom (int __lowfd) __THROW; + This function is a cancellation point and therefore not marked with + __THROW. */ + extern ssize_t read (int __fd, void *__buf, size_t __nbytes) __wur +- __attr_access ((__write_only__, 2, 3)); ++ __fortified_attr_access (__write_only__, 2, 3); + + /* Write N bytes of BUF to FD. Return the number written, or -1. + +@@ -388,7 +388,7 @@ extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur + __THROW. */ + extern ssize_t pread (int __fd, void *__buf, size_t __nbytes, + __off_t __offset) __wur +- __attr_access ((__write_only__, 2, 3)); ++ __fortified_attr_access (__write_only__, 2, 3); + + /* Write N bytes of BUF to FD at the given position OFFSET without + changing the file pointer. Return the number written, or -1. +@@ -404,7 +404,7 @@ extern ssize_t pwrite (int __fd, const void *__buf, size_t __n, + extern ssize_t __REDIRECT (pread, (int __fd, void *__buf, size_t __nbytes, + __off64_t __offset), + pread64) __wur +- __attr_access ((__write_only__, 2, 3)); ++ __fortified_attr_access (__write_only__, 2, 3); + extern ssize_t __REDIRECT (pwrite, (int __fd, const void *__buf, + size_t __nbytes, __off64_t __offset), + pwrite64) __wur +@@ -421,7 +421,7 @@ extern ssize_t __REDIRECT (pwrite, (int __fd, const void *__buf, + or 0 for EOF. */ + extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes, + __off64_t __offset) __wur +- __attr_access ((__write_only__, 2, 3)); ++ __fortified_attr_access (__write_only__, 2, 3); + /* Write N bytes of BUF to FD at the given position OFFSET without + changing the file pointer. Return the number written, or -1. */ + extern ssize_t pwrite64 (int __fd, const void *__buf, size_t __n, +@@ -642,7 +642,7 @@ extern long int sysconf (int __name) __THROW; + #ifdef __USE_POSIX2 + /* Get the value of the string-valued system variable NAME. */ + extern size_t confstr (int __name, char *__buf, size_t __len) __THROW +- __attr_access ((__write_only__, 2, 3)); ++ __fortified_attr_access (__write_only__, 2, 3); + #endif + + +@@ -709,7 +709,7 @@ extern __gid_t getegid (void) __THROW; + the calling process is in. Otherwise, fill in the group IDs + of its supplementary groups in LIST and return the number written. */ + extern int getgroups (int __size, __gid_t __list[]) __THROW __wur +- __attr_access ((__write_only__, 2, 1)); ++ __fortified_attr_access (__write_only__, 2, 1); + #ifdef __USE_GNU + /* Return nonzero iff the calling process is in group GID. */ + extern int group_member (__gid_t __gid) __THROW; +@@ -801,7 +801,8 @@ extern char *ttyname (int __fd) __THROW; + /* Store at most BUFLEN characters of the pathname of the terminal FD is + open on in BUF. Return 0 on success, otherwise an error number. */ + extern int ttyname_r (int __fd, char *__buf, size_t __buflen) +- __THROW __nonnull ((2)) __wur __attr_access ((__write_only__, 2, 3)); ++ __THROW __nonnull ((2)) __wur ++ __fortified_attr_access (__write_only__, 2, 3); + + /* Return 1 if FD is a valid descriptor associated + with a terminal, zero if not. */ +@@ -836,7 +837,8 @@ extern int symlink (const char *__from, const char *__to) + Returns the number of characters read, or -1 for errors. */ + extern ssize_t readlink (const char *__restrict __path, + char *__restrict __buf, size_t __len) +- __THROW __nonnull ((1, 2)) __wur __attr_access ((__write_only__, 2, 3)); ++ __THROW __nonnull ((1, 2)) __wur ++ __fortified_attr_access (__write_only__, 2, 3); + + #endif /* Use POSIX.1-2001. */ + +@@ -848,7 +850,8 @@ extern int symlinkat (const char *__from, int __tofd, + /* Like readlink but a relative PATH is interpreted relative to FD. */ + extern ssize_t readlinkat (int __fd, const char *__restrict __path, + char *__restrict __buf, size_t __len) +- __THROW __nonnull ((2, 3)) __wur __attr_access ((__write_only__, 3, 4)); ++ __THROW __nonnull ((2, 3)) __wur ++ __fortified_attr_access (__write_only__, 3, 4); + #endif + + /* Remove the link NAME. */ +@@ -884,7 +887,7 @@ extern char *getlogin (void); + This function is a possible cancellation point and therefore not + marked with __THROW. */ + extern int getlogin_r (char *__name, size_t __name_len) __nonnull ((1)) +- __attr_access ((__write_only__, 1, 2)); ++ __fortified_attr_access (__write_only__, 1, 2); + #endif + + #ifdef __USE_MISC +@@ -906,7 +909,7 @@ extern int setlogin (const char *__name) __THROW __nonnull ((1)); + The result is null-terminated if LEN is large enough for the full + name and the terminator. */ + extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1)) +- __attr_access ((__write_only__, 1, 2)); ++ __fortified_attr_access (__write_only__, 1, 2); + #endif + + +@@ -925,7 +928,8 @@ extern int sethostid (long int __id) __THROW __wur; + Called just like `gethostname' and `sethostname'. + The NIS domain name is usually the empty string when not using NIS. */ + extern int getdomainname (char *__name, size_t __len) +- __THROW __nonnull ((1)) __wur __attr_access ((__write_only__, 1, 2)); ++ __THROW __nonnull ((1)) __wur ++ __fortified_attr_access (__write_only__, 1, 2); + extern int setdomainname (const char *__name, size_t __len) + __THROW __nonnull ((1)) __wur __attr_access ((__read_only__, 1, 2)); + +diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h +index 0481c1235514f6e7..74c00eee73e4009d 100644 +--- a/stdlib/stdlib.h ++++ b/stdlib/stdlib.h +@@ -943,7 +943,8 @@ extern size_t mbstowcs (wchar_t *__restrict __pwcs, + extern size_t wcstombs (char *__restrict __s, + const wchar_t *__restrict __pwcs, size_t __n) + __THROW +- __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2)); ++ __fortified_attr_access (__write_only__, 1, 3) ++ __attr_access ((__read_only__, 2)); + + #ifdef __USE_MISC + /* Determine whether the string value of RESPONSE matches the affirmation +@@ -997,7 +998,7 @@ extern char *ptsname (int __fd) __THROW __wur; + terminal associated with the master FD is open on in BUF. + Return 0 on success, otherwise an error number. */ + extern int ptsname_r (int __fd, char *__buf, size_t __buflen) +- __THROW __nonnull ((2)) __attr_access ((__write_only__, 2, 3)); ++ __THROW __nonnull ((2)) __fortified_attr_access (__write_only__, 2, 3); + + /* Open a master pseudo terminal and return its file descriptor. */ + extern int getpt (void); +diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h +index 67ae2c6b50435368..5731274848260ad2 100644 +--- a/string/bits/string_fortified.h ++++ b/string/bits/string_fortified.h +@@ -64,7 +64,7 @@ __NTH (memset (void *__dest, int __ch, size_t __len)) + # include + + void __explicit_bzero_chk (void *__dest, size_t __len, size_t __destlen) +- __THROW __nonnull ((1)) __attr_access ((__write_only__, 1, 2)); ++ __THROW __nonnull ((1)) __fortified_attr_access (__write_only__, 1, 2); + + __fortify_function void + __NTH (explicit_bzero (void *__dest, size_t __len)) +@@ -106,7 +106,8 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) + #else + extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n, + size_t __destlen) __THROW +- __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2)); ++ __fortified_attr_access ((__write_only__, 1, 3)) ++ __attr_access ((__read_only__, 2)); + extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src, + size_t __n), stpncpy); + +diff --git a/string/string.h b/string/string.h +index 04e1b7067dc31d3c..8dcafb4ac4952853 100644 +--- a/string/string.h ++++ b/string/string.h +@@ -448,7 +448,7 @@ extern char *strerror_l (int __errnum, locale_t __l) __THROW; + /* Set N bytes of S to 0. The compiler will not delete a call to this + function, even if S is dead after the call. */ + extern void explicit_bzero (void *__s, size_t __n) __THROW __nonnull ((1)) +- __attr_access ((__write_only__, 1, 2)); ++ __fortified_attr_access (__write_only__, 1, 2); + + /* Return the next DELIM-delimited token from *STRINGP, + terminating it with a '\0', and update *STRINGP to point past it. */ diff --git a/SOURCES/glibc-upstream-2.34-126.patch b/SOURCES/glibc-upstream-2.34-126.patch new file mode 100644 index 0000000..93d236d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-126.patch @@ -0,0 +1,1038 @@ +commit 0e6ebf06e43e879d9efa2a1c79b2a55f81653663 +Author: Siddhesh Poyarekar +Date: Wed Oct 20 18:12:41 2021 +0530 + + Make sure that the fortified function conditionals are constant + + In _FORTIFY_SOURCE=3, the size expression may be non-constant, + resulting in branches in the inline functions remaining intact and + causing a tiny overhead. Clang (and in future, gcc) make sure that + the -1 case is always safe, i.e. any comparison of the generated + expression with (size_t)-1 is always false so that bit is taken care + of. The rest is avoidable since we want the _chk variant whenever we + have a size expression and it's not -1. + + Rework the conditionals in a uniform way to clearly indicate two + conditions at compile time: + + - Either the size is unknown (-1) or we know at compile time that the + operation length is less than the object size. We can call the + original function in this case. It could be that either the length, + object size or both are non-constant, but the compiler, through + range analysis, is able to fold the *comparison* to a constant. + + - The size and length are known and the compiler can see at compile + time that operation length > object size. This is valid grounds for + a warning at compile time, followed by emitting the _chk variant. + + For everything else, emit the _chk variant. + + This simplifies most of the fortified function implementations and at + the same time, ensures that only one call from _chk or the regular + function is emitted. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + (cherry picked from commit a643f60c53876be0d57b4b7373770e6cb356fd13) + +diff --git a/io/bits/poll2.h b/io/bits/poll2.h +index be74d020f2e0e434..91cdcaf66a427cea 100644 +--- a/io/bits/poll2.h ++++ b/io/bits/poll2.h +@@ -36,16 +36,9 @@ extern int __REDIRECT (__poll_chk_warn, (struct pollfd *__fds, nfds_t __nfds, + __fortify_function __fortified_attr_access (__write_only__, 1, 2) int + poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) + { +- if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1) +- { +- if (! __builtin_constant_p (__nfds)) +- return __poll_chk (__fds, __nfds, __timeout, __glibc_objsize (__fds)); +- else if (__glibc_objsize (__fds) / sizeof (*__fds) < __nfds) +- return __poll_chk_warn (__fds, __nfds, __timeout, +- __glibc_objsize (__fds)); +- } +- +- return __poll_alias (__fds, __nfds, __timeout); ++ return __glibc_fortify (poll, __nfds, sizeof (*__fds), ++ __glibc_objsize (__fds), ++ __fds, __nfds, __timeout); + } + + +@@ -68,17 +61,9 @@ __fortify_function __fortified_attr_access (__write_only__, 1, 2) int + ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout, + const __sigset_t *__ss) + { +- if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1) +- { +- if (! __builtin_constant_p (__nfds)) +- return __ppoll_chk (__fds, __nfds, __timeout, __ss, +- __glibc_objsize (__fds)); +- else if (__glibc_objsize (__fds) / sizeof (*__fds) < __nfds) +- return __ppoll_chk_warn (__fds, __nfds, __timeout, __ss, +- __glibc_objsize (__fds)); +- } +- +- return __ppoll_alias (__fds, __nfds, __timeout, __ss); ++ return __glibc_fortify (ppoll, __nfds, sizeof (*__fds), ++ __glibc_objsize (__fds), ++ __fds, __nfds, __timeout, __ss); + } + #endif + +diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h +index 4f016a563857a137..40ff16b01b4f4876 100644 +--- a/libio/bits/stdio2.h ++++ b/libio/bits/stdio2.h +@@ -261,15 +261,12 @@ extern char *__REDIRECT (__fgets_chk_warn, + __fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char * + fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + { +- if (__glibc_objsize (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgets_chk (__s, __glibc_objsize (__s), __n, __stream); +- +- if ((size_t) __n > __glibc_objsize (__s)) +- return __fgets_chk_warn (__s, __glibc_objsize (__s), __n, __stream); +- } +- return __fgets_alias (__s, __n, __stream); ++ size_t sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ return __fgets_alias (__s, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (char), sz)) ++ return __fgets_chk_warn (__s, sz, __n, __stream); ++ return __fgets_chk (__s, sz, __n, __stream); + } + + extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, +@@ -291,19 +288,12 @@ __fortify_function __wur size_t + fread (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) + { +- if (__glibc_objsize0 (__ptr) != (size_t) -1) +- { +- if (!__builtin_constant_p (__size) +- || !__builtin_constant_p (__n) +- || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) +- return __fread_chk (__ptr, __glibc_objsize0 (__ptr), __size, __n, +- __stream); +- +- if (__size * __n > __glibc_objsize0 (__ptr)) +- return __fread_chk_warn (__ptr, __glibc_objsize0 (__ptr), __size, __n, +- __stream); +- } +- return __fread_alias (__ptr, __size, __n, __stream); ++ size_t sz = __glibc_objsize0 (__ptr); ++ if (__glibc_safe_or_unknown_len (__n, __size, sz)) ++ return __fread_alias (__ptr, __size, __n, __stream); ++ if (__glibc_unsafe_len (__n, __size, sz)) ++ return __fread_chk_warn (__ptr, sz, __size, __n, __stream); ++ return __fread_chk (__ptr, sz, __size, __n, __stream); + } + + #ifdef __USE_GNU +@@ -323,17 +313,12 @@ extern char *__REDIRECT (__fgets_unlocked_chk_warn, + __fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char * + fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) + { +- if (__glibc_objsize (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgets_unlocked_chk (__s, __glibc_objsize (__s), __n, +- __stream); +- +- if ((size_t) __n > __glibc_objsize (__s)) +- return __fgets_unlocked_chk_warn (__s, __glibc_objsize (__s), __n, +- __stream); +- } +- return __fgets_unlocked_alias (__s, __n, __stream); ++ size_t sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ return __fgets_unlocked_alias (__s, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (char), sz)) ++ return __fgets_unlocked_chk_warn (__s, sz, __n, __stream); ++ return __fgets_unlocked_chk (__s, sz, __n, __stream); + } + #endif + +@@ -358,41 +343,36 @@ __fortify_function __wur size_t + fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) + { +- if (__glibc_objsize0 (__ptr) != (size_t) -1) ++ size_t sz = __glibc_objsize0 (__ptr); ++ if (__glibc_safe_or_unknown_len (__n, __size, sz)) + { +- if (!__builtin_constant_p (__size) +- || !__builtin_constant_p (__n) +- || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) +- return __fread_unlocked_chk (__ptr, __glibc_objsize0 (__ptr), __size, +- __n, __stream); +- +- if (__size * __n > __glibc_objsize0 (__ptr)) +- return __fread_unlocked_chk_warn (__ptr, __glibc_objsize0 (__ptr), +- __size, __n, __stream); +- } +- + # ifdef __USE_EXTERN_INLINES +- if (__builtin_constant_p (__size) +- && __builtin_constant_p (__n) +- && (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2)) +- && __size * __n <= 8) +- { +- size_t __cnt = __size * __n; +- char *__cptr = (char *) __ptr; +- if (__cnt == 0) +- return 0; +- +- for (; __cnt > 0; --__cnt) ++ if (__builtin_constant_p (__size) ++ && __builtin_constant_p (__n) ++ && (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2)) ++ && __size * __n <= 8) + { +- int __c = getc_unlocked (__stream); +- if (__c == EOF) +- break; +- *__cptr++ = __c; ++ size_t __cnt = __size * __n; ++ char *__cptr = (char *) __ptr; ++ if (__cnt == 0) ++ return 0; ++ ++ for (; __cnt > 0; --__cnt) ++ { ++ int __c = getc_unlocked (__stream); ++ if (__c == EOF) ++ break; ++ *__cptr++ = __c; ++ } ++ return (__cptr - (char *) __ptr) / __size; + } +- return (__cptr - (char *) __ptr) / __size; +- } + # endif +- return __fread_unlocked_alias (__ptr, __size, __n, __stream); ++ return __fread_unlocked_alias (__ptr, __size, __n, __stream); ++ } ++ if (__glibc_unsafe_len (__n, __size, sz)) ++ return __fread_unlocked_chk_warn (__ptr, sz, __size, __n, __stream); ++ return __fread_unlocked_chk (__ptr, sz, __size, __n, __stream); ++ + } + #endif + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index cd836441a9807d6a..4825ff0351c1e5d4 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -150,6 +150,53 @@ + # define __glibc_objsize(__o) __bos (__o) + #endif + ++/* Compile time conditions to choose between the regular, _chk and _chk_warn ++ variants. These conditions should get evaluated to constant and optimized ++ away. */ ++ ++#define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s)) ++#define __glibc_unsigned_or_positive(__l) \ ++ ((__typeof (__l)) 0 < (__typeof (__l)) -1 \ ++ || (__builtin_constant_p (__l) && (__l) > 0)) ++ ++/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ ++ condition can be folded to a constant and if it is true. The -1 check is ++ redundant because since it implies that __glibc_safe_len_cond is true. */ ++#define __glibc_safe_or_unknown_len(__l, __s, __osz) \ ++ (__glibc_unsigned_or_positive (__l) \ ++ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ ++ __s, __osz)) \ ++ && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) ++ ++/* Conversely, we know at compile time that the length is safe if the ++ __L * __S <= __OBJSZ condition can be folded to a constant and if it is ++ false. */ ++#define __glibc_unsafe_len(__l, __s, __osz) \ ++ (__glibc_unsigned_or_positive (__l) \ ++ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ ++ __s, __osz)) \ ++ && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) ++ ++/* Fortify function f. __f_alias, __f_chk and __f_chk_warn must be ++ declared. */ ++ ++#define __glibc_fortify(f, __l, __s, __osz, ...) \ ++ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ++ ? __ ## f ## _alias (__VA_ARGS__) \ ++ : (__glibc_unsafe_len (__l, __s, __osz) \ ++ ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ ++ : __ ## f ## _chk (__VA_ARGS__, __osz))) \ ++ ++/* Fortify function f, where object size argument passed to f is the number of ++ elements and not total size. */ ++ ++#define __glibc_fortify_n(f, __l, __s, __osz, ...) \ ++ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ++ ? __ ## f ## _alias (__VA_ARGS__) \ ++ : (__glibc_unsafe_len (__l, __s, __osz) \ ++ ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ ++ : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) \ ++ + #if __GNUC_PREREQ (4,3) + # define __warnattr(msg) __attribute__((__warning__ (msg))) + # define __errordecl(name, msg) \ +diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h +index 622adeb2b28ed298..697dcbbf7b4b26f6 100644 +--- a/posix/bits/unistd.h ++++ b/posix/bits/unistd.h +@@ -35,16 +35,9 @@ extern ssize_t __REDIRECT (__read_chk_warn, + __fortify_function __wur ssize_t + read (int __fd, void *__buf, size_t __nbytes) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__nbytes)) +- return __read_chk (__fd, __buf, __nbytes, __glibc_objsize0 (__buf)); +- +- if (__nbytes > __glibc_objsize0 (__buf)) +- return __read_chk_warn (__fd, __buf, __nbytes, +- __glibc_objsize0 (__buf)); +- } +- return __read_alias (__fd, __buf, __nbytes); ++ return __glibc_fortify (read, __nbytes, sizeof (char), ++ __glibc_objsize0 (__buf), ++ __fd, __buf, __nbytes); + } + + #ifdef __USE_UNIX98 +@@ -78,34 +71,17 @@ extern ssize_t __REDIRECT (__pread64_chk_warn, + __fortify_function __wur ssize_t + pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__nbytes)) +- return __pread_chk (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- +- if ( __nbytes > __glibc_objsize0 (__buf)) +- return __pread_chk_warn (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- } +- return __pread_alias (__fd, __buf, __nbytes, __offset); ++ return __glibc_fortify (pread, __nbytes, sizeof (char), ++ __glibc_objsize0 (__buf), ++ __fd, __buf, __nbytes, __offset); + } + # else + __fortify_function __wur ssize_t + pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__nbytes)) +- return __pread64_chk (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- +- if ( __nbytes > __glibc_objsize0 (__buf)) +- return __pread64_chk_warn (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- } +- +- return __pread64_alias (__fd, __buf, __nbytes, __offset); ++ return __glibc_fortify (pread64, __nbytes, sizeof (char), ++ __glibc_objsize0 (__buf), ++ __fd, __buf, __nbytes, __offset); + } + # endif + +@@ -113,18 +89,9 @@ pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) + __fortify_function __wur ssize_t + pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__nbytes)) +- return __pread64_chk (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- +- if ( __nbytes > __glibc_objsize0 (__buf)) +- return __pread64_chk_warn (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- } +- +- return __pread64_alias (__fd, __buf, __nbytes, __offset); ++ return __glibc_fortify (pread64, __nbytes, sizeof (char), ++ __glibc_objsize0 (__buf), ++ __fd, __buf, __nbytes, __offset); + } + # endif + #endif +@@ -149,16 +116,9 @@ __fortify_function __nonnull ((1, 2)) __wur ssize_t + __NTH (readlink (const char *__restrict __path, char *__restrict __buf, + size_t __len)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __readlink_chk (__path, __buf, __len, __glibc_objsize (__buf)); +- +- if ( __len > __glibc_objsize (__buf)) +- return __readlink_chk_warn (__path, __buf, __len, +- __glibc_objsize (__buf)); +- } +- return __readlink_alias (__path, __buf, __len); ++ return __glibc_fortify (readlink, __len, sizeof (char), ++ __glibc_objsize (__buf), ++ __path, __buf, __len); + } + #endif + +@@ -184,17 +144,9 @@ __fortify_function __nonnull ((2, 3)) __wur ssize_t + __NTH (readlinkat (int __fd, const char *__restrict __path, + char *__restrict __buf, size_t __len)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __readlinkat_chk (__fd, __path, __buf, __len, +- __glibc_objsize (__buf)); +- +- if (__len > __glibc_objsize (__buf)) +- return __readlinkat_chk_warn (__fd, __path, __buf, __len, +- __glibc_objsize (__buf)); +- } +- return __readlinkat_alias (__fd, __path, __buf, __len); ++ return __glibc_fortify (readlinkat, __len, sizeof (char), ++ __glibc_objsize (__buf), ++ __fd, __path, __buf, __len); + } + #endif + +@@ -211,15 +163,9 @@ extern char *__REDIRECT_NTH (__getcwd_chk_warn, + __fortify_function __wur char * + __NTH (getcwd (char *__buf, size_t __size)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__size)) +- return __getcwd_chk (__buf, __size, __glibc_objsize (__buf)); +- +- if (__size > __glibc_objsize (__buf)) +- return __getcwd_chk_warn (__buf, __size, __glibc_objsize (__buf)); +- } +- return __getcwd_alias (__buf, __size); ++ return __glibc_fortify (getcwd, __size, sizeof (char), ++ __glibc_objsize (__buf), ++ __buf, __size); + } + + #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED +@@ -253,16 +199,9 @@ extern size_t __REDIRECT_NTH (__confstr_chk_warn, + __fortify_function size_t + __NTH (confstr (int __name, char *__buf, size_t __len)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __confstr_chk (__name, __buf, __len, __glibc_objsize (__buf)); +- +- if (__glibc_objsize (__buf) < __len) +- return __confstr_chk_warn (__name, __buf, __len, +- __glibc_objsize (__buf)); +- } +- return __confstr_alias (__name, __buf, __len); ++ return __glibc_fortify (confstr, __len, sizeof (char), ++ __glibc_objsize (__buf), ++ __name, __buf, __len); + } + + +@@ -279,15 +218,9 @@ extern int __REDIRECT_NTH (__getgroups_chk_warn, + __fortify_function int + __NTH (getgroups (int __size, __gid_t __list[])) + { +- if (__glibc_objsize (__list) != (size_t) -1) +- { +- if (!__builtin_constant_p (__size) || __size < 0) +- return __getgroups_chk (__size, __list, __glibc_objsize (__list)); +- +- if (__size * sizeof (__gid_t) > __glibc_objsize (__list)) +- return __getgroups_chk_warn (__size, __list, __glibc_objsize (__list)); +- } +- return __getgroups_alias (__size, __list); ++ return __glibc_fortify (getgroups, __size, sizeof (__gid_t), ++ __glibc_objsize (__list), ++ __size, __list); + } + + +@@ -306,17 +239,9 @@ extern int __REDIRECT_NTH (__ttyname_r_chk_warn, + __fortify_function int + __NTH (ttyname_r (int __fd, char *__buf, size_t __buflen)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __ttyname_r_chk (__fd, __buf, __buflen, +- __glibc_objsize (__buf)); +- +- if (__buflen > __glibc_objsize (__buf)) +- return __ttyname_r_chk_warn (__fd, __buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __ttyname_r_alias (__fd, __buf, __buflen); ++ return __glibc_fortify (ttyname_r, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __fd, __buf, __buflen); + } + + +@@ -334,16 +259,9 @@ extern int __REDIRECT (__getlogin_r_chk_warn, + __fortify_function int + getlogin_r (char *__buf, size_t __buflen) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __getlogin_r_chk (__buf, __buflen, __glibc_objsize (__buf)); +- +- if (__buflen > __glibc_objsize (__buf)) +- return __getlogin_r_chk_warn (__buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __getlogin_r_alias (__buf, __buflen); ++ return __glibc_fortify (getlogin_r, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __buf, __buflen); + } + #endif + +@@ -363,16 +281,9 @@ extern int __REDIRECT_NTH (__gethostname_chk_warn, + __fortify_function int + __NTH (gethostname (char *__buf, size_t __buflen)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __gethostname_chk (__buf, __buflen, __glibc_objsize (__buf)); +- +- if (__buflen > __glibc_objsize (__buf)) +- return __gethostname_chk_warn (__buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __gethostname_alias (__buf, __buflen); ++ return __glibc_fortify (gethostname, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __buf, __buflen); + } + #endif + +@@ -394,15 +305,8 @@ extern int __REDIRECT_NTH (__getdomainname_chk_warn, + __fortify_function int + __NTH (getdomainname (char *__buf, size_t __buflen)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __getdomainname_chk (__buf, __buflen, __glibc_objsize (__buf)); +- +- if (__buflen > __glibc_objsize (__buf)) +- return __getdomainname_chk_warn (__buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __getdomainname_alias (__buf, __buflen); ++ return __glibc_fortify (getdomainname, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __buf, __buflen); + } + #endif +diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h +index 9c8ac69624ea4f78..b28cde55f3fd9c16 100644 +--- a/socket/bits/socket2.h ++++ b/socket/bits/socket2.h +@@ -33,17 +33,12 @@ extern ssize_t __REDIRECT (__recv_chk_warn, + __fortify_function ssize_t + recv (int __fd, void *__buf, size_t __n, int __flags) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __recv_chk (__fd, __buf, __n, __glibc_objsize0 (__buf), +- __flags); +- +- if (__n > __glibc_objsize0 (__buf)) +- return __recv_chk_warn (__fd, __buf, __n, __glibc_objsize0 (__buf), +- __flags); +- } +- return __recv_alias (__fd, __buf, __n, __flags); ++ size_t sz = __glibc_objsize0 (__buf); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ return __recv_alias (__fd, __buf, __n, __flags); ++ if (__glibc_unsafe_len (__n, sizeof (char), sz)) ++ return __recv_chk_warn (__fd, __buf, __n, sz, __flags); ++ return __recv_chk (__fd, __buf, __n, sz, __flags); + } + + extern ssize_t __recvfrom_chk (int __fd, void *__restrict __buf, size_t __n, +@@ -66,14 +61,11 @@ __fortify_function ssize_t + recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags, + __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __recvfrom_chk (__fd, __buf, __n, __glibc_objsize0 (__buf), +- __flags, __addr, __addr_len); +- if (__n > __glibc_objsize0 (__buf)) +- return __recvfrom_chk_warn (__fd, __buf, __n, __glibc_objsize0 (__buf), +- __flags, __addr, __addr_len); +- } +- return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len); ++ size_t sz = __glibc_objsize0 (__buf); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len); ++ if (__glibc_unsafe_len (__n, sizeof (char), sz)) ++ return __recvfrom_chk_warn (__fd, __buf, __n, sz, __flags, __addr, ++ __addr_len); ++ return __recvfrom_chk (__fd, __buf, __n, sz, __flags, __addr, __addr_len); + } +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index eae31b38f0475c2e..067115eeca123c6d 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -36,17 +36,16 @@ extern char *__REDIRECT_NTH (__realpath_chk_warn, + __fortify_function __wur char * + __NTH (realpath (const char *__restrict __name, char *__restrict __resolved)) + { +- if (__glibc_objsize (__resolved) != (size_t) -1) +- { ++ size_t sz = __glibc_objsize (__resolved); ++ ++ if (sz == (size_t) -1) ++ return __realpath_alias (__name, __resolved); ++ + #if defined _LIBC_LIMITS_H_ && defined PATH_MAX +- if (__glibc_objsize (__resolved) < PATH_MAX) +- return __realpath_chk_warn (__name, __resolved, +- __glibc_objsize (__resolved)); ++ if (__glibc_unsafe_len (sz, sizeof (char), PATH_MAX)) ++ return __realpath_chk_warn (__name, __resolved, sz); + #endif +- return __realpath_chk (__name, __resolved, __glibc_objsize (__resolved)); +- } +- +- return __realpath_alias (__name, __resolved); ++ return __realpath_chk (__name, __resolved, sz); + } + + +@@ -65,16 +64,9 @@ extern int __REDIRECT_NTH (__ptsname_r_chk_warn, + __fortify_function int + __NTH (ptsname_r (int __fd, char *__buf, size_t __buflen)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __ptsname_r_chk (__fd, __buf, __buflen, +- __glibc_objsize (__buf)); +- if (__buflen > __glibc_objsize (__buf)) +- return __ptsname_r_chk_warn (__fd, __buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __ptsname_r_alias (__fd, __buf, __buflen); ++ return __glibc_fortify (ptsname_r, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __fd, __buf, __buflen); + } + + +@@ -120,18 +112,9 @@ __fortify_function size_t + __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src, + size_t __len)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __mbstowcs_chk (__dst, __src, __len, +- __glibc_objsize (__dst) / sizeof (wchar_t)); +- +- if (__len > __glibc_objsize (__dst) / sizeof (wchar_t)) +- return __mbstowcs_chk_warn (__dst, __src, __len, +- (__glibc_objsize (__dst) +- / sizeof (wchar_t))); +- } +- return __mbstowcs_alias (__dst, __src, __len); ++ return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t), ++ __glibc_objsize (__dst), ++ __dst, __src, __len); + } + + +@@ -154,13 +137,7 @@ __fortify_function size_t + __NTH (wcstombs (char *__restrict __dst, const wchar_t *__restrict __src, + size_t __len)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __wcstombs_chk (__dst, __src, __len, __glibc_objsize (__dst)); +- if (__len > __glibc_objsize (__dst)) +- return __wcstombs_chk_warn (__dst, __src, __len, +- __glibc_objsize (__dst)); +- } +- return __wcstombs_alias (__dst, __src, __len); ++ return __glibc_fortify (wcstombs, __len, sizeof (char), ++ __glibc_objsize (__dst), ++ __dst, __src, __len); + } +diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h +index ea2518dc726aae52..26012ef9366c0b88 100644 +--- a/wcsmbs/bits/wchar2.h ++++ b/wcsmbs/bits/wchar2.h +@@ -39,17 +39,9 @@ __fortify_function wchar_t * + __NTH (wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, + size_t __n)) + { +- if (__glibc_objsize0 (__s1) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wmemcpy_chk (__s1, __s2, __n, +- __glibc_objsize0 (__s1) / sizeof (wchar_t)); +- +- if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t)) +- return __wmemcpy_chk_warn (__s1, __s2, __n, +- __glibc_objsize0 (__s1) / sizeof (wchar_t)); +- } +- return __wmemcpy_alias (__s1, __s2, __n); ++ return __glibc_fortify_n (wmemcpy, __n, sizeof (wchar_t), ++ __glibc_objsize0 (__s1), ++ __s1, __s2, __n); + } + + +@@ -67,18 +59,9 @@ extern wchar_t *__REDIRECT_NTH (__wmemmove_chk_warn, + __fortify_function wchar_t * + __NTH (wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n)) + { +- if (__glibc_objsize0 (__s1) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wmemmove_chk (__s1, __s2, __n, +- __glibc_objsize0 (__s1) / sizeof (wchar_t)); +- +- if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t)) +- return __wmemmove_chk_warn (__s1, __s2, __n, +- (__glibc_objsize0 (__s1) +- / sizeof (wchar_t))); +- } +- return __wmemmove_alias (__s1, __s2, __n); ++ return __glibc_fortify_n (wmemmove, __n, sizeof (wchar_t), ++ __glibc_objsize0 (__s1), ++ __s1, __s2, __n); + } + + +@@ -101,18 +84,9 @@ __fortify_function wchar_t * + __NTH (wmempcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, + size_t __n)) + { +- if (__glibc_objsize0 (__s1) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wmempcpy_chk (__s1, __s2, __n, +- __glibc_objsize0 (__s1) / sizeof (wchar_t)); +- +- if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t)) +- return __wmempcpy_chk_warn (__s1, __s2, __n, +- (__glibc_objsize0 (__s1) +- / sizeof (wchar_t))); +- } +- return __wmempcpy_alias (__s1, __s2, __n); ++ return __glibc_fortify_n (wmempcpy, __n, sizeof (wchar_t), ++ __glibc_objsize0 (__s1), ++ __s1, __s2, __n); + } + #endif + +@@ -130,17 +104,9 @@ extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn, + __fortify_function wchar_t * + __NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n)) + { +- if (__glibc_objsize0 (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wmemset_chk (__s, __c, __n, +- __glibc_objsize0 (__s) / sizeof (wchar_t)); +- +- if (__n > __glibc_objsize0 (__s) / sizeof (wchar_t)) +- return __wmemset_chk_warn (__s, __c, __n, +- __glibc_objsize0 (__s) / sizeof (wchar_t)); +- } +- return __wmemset_alias (__s, __c, __n); ++ return __glibc_fortify_n (wmemset, __n, sizeof (wchar_t), ++ __glibc_objsize0 (__s), ++ __s, __c, __n); + } + + +@@ -154,9 +120,9 @@ extern wchar_t *__REDIRECT_NTH (__wcscpy_alias, + __fortify_function wchar_t * + __NTH (wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- return __wcscpy_chk (__dest, __src, +- __glibc_objsize (__dest) / sizeof (wchar_t)); ++ size_t sz = __glibc_objsize (__dest); ++ if (sz != (size_t) -1) ++ return __wcscpy_chk (__dest, __src, sz / sizeof (wchar_t)); + return __wcscpy_alias (__dest, __src); + } + +@@ -171,9 +137,9 @@ extern wchar_t *__REDIRECT_NTH (__wcpcpy_alias, + __fortify_function wchar_t * + __NTH (wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- return __wcpcpy_chk (__dest, __src, +- __glibc_objsize (__dest) / sizeof (wchar_t)); ++ size_t sz = __glibc_objsize (__dest); ++ if (sz != (size_t) -1) ++ return __wcpcpy_chk (__dest, __src, sz / sizeof (wchar_t)); + return __wcpcpy_alias (__dest, __src); + } + +@@ -196,17 +162,9 @@ __fortify_function wchar_t * + __NTH (wcsncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + size_t __n)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wcsncpy_chk (__dest, __src, __n, +- __glibc_objsize (__dest) / sizeof (wchar_t)); +- if (__n > __glibc_objsize (__dest) / sizeof (wchar_t)) +- return __wcsncpy_chk_warn (__dest, __src, __n, +- (__glibc_objsize (__dest) +- / sizeof (wchar_t))); +- } +- return __wcsncpy_alias (__dest, __src, __n); ++ return __glibc_fortify_n (wcsncpy, __n, sizeof (wchar_t), ++ __glibc_objsize (__dest), ++ __dest, __src, __n); + } + + +@@ -228,17 +186,9 @@ __fortify_function wchar_t * + __NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + size_t __n)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wcpncpy_chk (__dest, __src, __n, +- __glibc_objsize (__dest) / sizeof (wchar_t)); +- if (__n > __glibc_objsize (__dest) / sizeof (wchar_t)) +- return __wcpncpy_chk_warn (__dest, __src, __n, +- (__glibc_objsize (__dest) +- / sizeof (wchar_t))); +- } +- return __wcpncpy_alias (__dest, __src, __n); ++ return __glibc_fortify_n (wcpncpy, __n, sizeof (wchar_t), ++ __glibc_objsize (__dest), ++ __dest, __src, __n); + } + + +@@ -252,9 +202,9 @@ extern wchar_t *__REDIRECT_NTH (__wcscat_alias, + __fortify_function wchar_t * + __NTH (wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- return __wcscat_chk (__dest, __src, +- __glibc_objsize (__dest) / sizeof (wchar_t)); ++ size_t sz = __glibc_objsize (__dest); ++ if (sz != (size_t) -1) ++ return __wcscat_chk (__dest, __src, sz / sizeof (wchar_t)); + return __wcscat_alias (__dest, __src); + } + +@@ -271,9 +221,9 @@ __fortify_function wchar_t * + __NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + size_t __n)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- return __wcsncat_chk (__dest, __src, __n, +- __glibc_objsize (__dest) / sizeof (wchar_t)); ++ size_t sz = __glibc_objsize (__dest); ++ if (sz != (size_t) -1) ++ return __wcsncat_chk (__dest, __src, __n, sz / sizeof (wchar_t)); + return __wcsncat_alias (__dest, __src, __n); + } + +@@ -293,10 +243,10 @@ __fortify_function int + __NTH (swprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __fmt, ...)) + { +- if (__glibc_objsize (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) ++ size_t sz = __glibc_objsize (__s); ++ if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) + return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- __glibc_objsize (__s) / sizeof (wchar_t), +- __fmt, __va_arg_pack ()); ++ sz / sizeof (wchar_t), __fmt, __va_arg_pack ()); + return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ()); + } + #elif !defined __cplusplus +@@ -323,10 +273,10 @@ __fortify_function int + __NTH (vswprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __fmt, __gnuc_va_list __ap)) + { +- if (__glibc_objsize (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) ++ size_t sz = __glibc_objsize (__s); ++ if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) + return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- __glibc_objsize (__s) / sizeof (wchar_t), __fmt, +- __ap); ++ sz / sizeof (wchar_t), __fmt, __ap); + return __vswprintf_alias (__s, __n, __fmt, __ap); + } + +@@ -392,18 +342,12 @@ extern wchar_t *__REDIRECT (__fgetws_chk_warn, + __fortify_function __wur wchar_t * + fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + { +- if (__glibc_objsize (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgetws_chk (__s, __glibc_objsize (__s) / sizeof (wchar_t), +- __n, __stream); +- +- if ((size_t) __n > __glibc_objsize (__s) / sizeof (wchar_t)) +- return __fgetws_chk_warn (__s, +- __glibc_objsize (__s) / sizeof (wchar_t), +- __n, __stream); +- } +- return __fgetws_alias (__s, __n, __stream); ++ size_t sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz)) ++ return __fgetws_alias (__s, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz)) ++ return __fgetws_chk_warn (__s, sz / sizeof (wchar_t), __n, __stream); ++ return __fgetws_chk (__s, sz / sizeof (wchar_t), __n, __stream); + } + + #ifdef __USE_GNU +@@ -424,20 +368,13 @@ extern wchar_t *__REDIRECT (__fgetws_unlocked_chk_warn, + __fortify_function __wur wchar_t * + fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + { +- if (__glibc_objsize (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgetws_unlocked_chk (__s, +- __glibc_objsize (__s) / sizeof (wchar_t), +- __n, __stream); +- +- if ((size_t) __n > __glibc_objsize (__s) / sizeof (wchar_t)) +- return __fgetws_unlocked_chk_warn (__s, +- (__glibc_objsize (__s) +- / sizeof (wchar_t)), +- __n, __stream); +- } +- return __fgetws_unlocked_alias (__s, __n, __stream); ++ size_t sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz)) ++ return __fgetws_unlocked_alias (__s, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz)) ++ return __fgetws_unlocked_chk_warn (__s, sz / sizeof (wchar_t), __n, ++ __stream); ++ return __fgetws_unlocked_chk (__s, sz / sizeof (wchar_t), __n, __stream); + } + #endif + +@@ -488,18 +425,9 @@ __fortify_function size_t + __NTH (mbsrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, + size_t __len, mbstate_t *__restrict __ps)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __mbsrtowcs_chk (__dst, __src, __len, __ps, +- __glibc_objsize (__dst) / sizeof (wchar_t)); +- +- if (__len > __glibc_objsize (__dst) / sizeof (wchar_t)) +- return __mbsrtowcs_chk_warn (__dst, __src, __len, __ps, +- (__glibc_objsize (__dst) +- / sizeof (wchar_t))); +- } +- return __mbsrtowcs_alias (__dst, __src, __len, __ps); ++ return __glibc_fortify_n (mbsrtowcs, __len, sizeof (wchar_t), ++ __glibc_objsize (__dst), ++ __dst, __src, __len, __ps); + } + + +@@ -523,17 +451,9 @@ __fortify_function size_t + __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src, + size_t __len, mbstate_t *__restrict __ps)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __wcsrtombs_chk (__dst, __src, __len, __ps, +- __glibc_objsize (__dst)); +- +- if (__len > __glibc_objsize (__dst)) +- return __wcsrtombs_chk_warn (__dst, __src, __len, __ps, +- __glibc_objsize (__dst)); +- } +- return __wcsrtombs_alias (__dst, __src, __len, __ps); ++ return __glibc_fortify (wcsrtombs, __len, sizeof (char), ++ __glibc_objsize (__dst), ++ __dst, __src, __len, __ps); + } + + +@@ -559,18 +479,9 @@ __fortify_function size_t + __NTH (mbsnrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, + size_t __nmc, size_t __len, mbstate_t *__restrict __ps)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps, +- __glibc_objsize (__dst) / sizeof (wchar_t)); +- +- if (__len > __glibc_objsize (__dst) / sizeof (wchar_t)) +- return __mbsnrtowcs_chk_warn (__dst, __src, __nmc, __len, __ps, +- (__glibc_objsize (__dst) +- / sizeof (wchar_t))); +- } +- return __mbsnrtowcs_alias (__dst, __src, __nmc, __len, __ps); ++ return __glibc_fortify_n (mbsnrtowcs, __len, sizeof (wchar_t), ++ __glibc_objsize (__dst), ++ __dst, __src, __nmc, __len, __ps); + } + + +@@ -596,16 +507,8 @@ __fortify_function size_t + __NTH (wcsnrtombs (char *__restrict __dst, const wchar_t **__restrict __src, + size_t __nwc, size_t __len, mbstate_t *__restrict __ps)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps, +- __glibc_objsize (__dst)); +- +- if (__len > __glibc_objsize (__dst)) +- return __wcsnrtombs_chk_warn (__dst, __src, __nwc, __len, __ps, +- __glibc_objsize (__dst)); +- } +- return __wcsnrtombs_alias (__dst, __src, __nwc, __len, __ps); ++ return __glibc_fortify (wcsnrtombs, __len, sizeof (char), ++ __glibc_objsize (__dst), ++ __dst, __src, __nwc, __len, __ps); + } + #endif diff --git a/SOURCES/glibc-upstream-2.34-127.patch b/SOURCES/glibc-upstream-2.34-127.patch new file mode 100644 index 0000000..488cc63 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-127.patch @@ -0,0 +1,358 @@ +commit 536910724d30a38eeecd14cdbe2c93c78ea67646 +Author: Siddhesh Poyarekar +Date: Wed Oct 20 18:13:05 2021 +0530 + + debug: Add tests for _FORTIFY_SOURCE=3 + + Add some testing coverage for _FORTIFY_SOURCE=3. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + (cherry picked from commit ad6f2a010c2ce759936de4747f6e0d53991912f8) + +diff --git a/debug/Makefile b/debug/Makefile +index 6893111cbfaa0900..357f888246061e15 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -120,6 +120,8 @@ CFLAGS-tst-chk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-chk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-chk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-chk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error ++CFLAGS-tst-chk7.c += -Wno-format -Wno-deprecated-declarations -Wno-error ++CFLAGS-tst-chk8.cc += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-lfschk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-lfschk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-lfschk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error +@@ -129,6 +131,7 @@ CFLAGS-tst-lfschk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error + LDLIBS-tst-chk4 = -lstdc++ + LDLIBS-tst-chk5 = -lstdc++ + LDLIBS-tst-chk6 = -lstdc++ ++LDLIBS-tst-chk8 = -lstdc++ + LDLIBS-tst-lfschk4 = -lstdc++ + LDLIBS-tst-lfschk5 = -lstdc++ + LDLIBS-tst-lfschk6 = -lstdc++ +@@ -150,16 +153,16 @@ CFLAGS-tst-ssp-1.c += -fstack-protector-all + + tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \ + tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \ +- tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \ +- tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \ +- tst-backtrace5 tst-backtrace6 ++ tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \ ++ tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \ ++ tst-backtrace4 tst-backtrace5 tst-backtrace6 + + ifeq ($(have-ssp),yes) + tests += tst-ssp-1 + endif + + ifeq (,$(CXX)) +-tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \ ++tests-unsupported = tst-chk4 tst-chk5 tst-chk6 tst-chk8 \ + tst-lfschk4 tst-lfschk5 tst-lfschk6 + endif + +@@ -193,6 +196,8 @@ $(objpfx)tst-chk3.out: $(gen-locales) + $(objpfx)tst-chk4.out: $(gen-locales) + $(objpfx)tst-chk5.out: $(gen-locales) + $(objpfx)tst-chk6.out: $(gen-locales) ++$(objpfx)tst-chk7.out: $(gen-locales) ++$(objpfx)tst-chk8.out: $(gen-locales) + $(objpfx)tst-lfschk1.out: $(gen-locales) + $(objpfx)tst-lfschk2.out: $(gen-locales) + $(objpfx)tst-lfschk3.out: $(gen-locales) +diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c +index 6c1d32cc62c3a964..68ac00d1808382b8 100644 +--- a/debug/tst-chk1.c ++++ b/debug/tst-chk1.c +@@ -83,8 +83,14 @@ handler (int sig) + _exit (127); + } + ++#if __USE_FORTIFY_LEVEL == 3 ++volatile size_t buf_size = 10; ++#else + char buf[10]; + wchar_t wbuf[10]; ++#define buf_size sizeof (buf) ++#endif ++ + volatile size_t l0; + volatile char *p; + volatile wchar_t *wp; +@@ -123,6 +129,10 @@ int num2 = 987654; + static int + do_test (void) + { ++#if __USE_FORTIFY_LEVEL == 3 ++ char *buf = (char *) malloc (buf_size); ++ wchar_t *wbuf = (wchar_t *) malloc (buf_size * sizeof (wchar_t)); ++#endif + set_fortify_handler (handler); + + struct A { char buf1[9]; char buf2[1]; } a; +@@ -947,93 +957,93 @@ do_test (void) + + rewind (stdin); + +- if (fgets (buf, sizeof (buf), stdin) != buf ++ if (fgets (buf, buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); +- if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10)) ++ if (fgets (buf, buf_size, stdin) != buf || memcmp (buf, "ABCDEFGHI", 10)) + FAIL (); + + rewind (stdin); + +- if (fgets (buf, l0 + sizeof (buf), stdin) != buf ++ if (fgets (buf, l0 + buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (fgets (buf, sizeof (buf) + 1, stdin) != buf) ++ if (fgets (buf, buf_size + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf) ++ if (fgets (buf, l0 + buf_size + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + #endif + + rewind (stdin); + +- if (fgets_unlocked (buf, sizeof (buf), stdin) != buf ++ if (fgets_unlocked (buf, buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); +- if (fgets_unlocked (buf, sizeof (buf), stdin) != buf ++ if (fgets_unlocked (buf, buf_size, stdin) != buf + || memcmp (buf, "ABCDEFGHI", 10)) + FAIL (); + + rewind (stdin); + +- if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf ++ if (fgets_unlocked (buf, l0 + buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf) ++ if (fgets_unlocked (buf, buf_size + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf) ++ if (fgets_unlocked (buf, l0 + buf_size + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + #endif + + rewind (stdin); + +- if (fread (buf, 1, sizeof (buf), stdin) != sizeof (buf) ++ if (fread (buf, 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); +- if (fread (buf, sizeof (buf), 1, stdin) != 1 ++ if (fread (buf, buf_size, 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + rewind (stdin); + +- if (fread (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf) ++ if (fread (buf, l0 + 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); +- if (fread (buf, sizeof (buf), l0 + 1, stdin) != 1 ++ if (fread (buf, buf_size, l0 + 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (fread (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1) ++ if (fread (buf, 1, buf_size + 1, stdin) != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (fread (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1) ++ if (fread (buf, buf_size + 1, l0 + 1, stdin) != 1) + FAIL (); + CHK_FAIL_END + #endif + + rewind (stdin); + +- if (fread_unlocked (buf, 1, sizeof (buf), stdin) != sizeof (buf) ++ if (fread_unlocked (buf, 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); +- if (fread_unlocked (buf, sizeof (buf), 1, stdin) != 1 ++ if (fread_unlocked (buf, buf_size, 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + +@@ -1048,100 +1058,100 @@ do_test (void) + + rewind (stdin); + +- if (fread_unlocked (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf) ++ if (fread_unlocked (buf, l0 + 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); +- if (fread_unlocked (buf, sizeof (buf), l0 + 1, stdin) != 1 ++ if (fread_unlocked (buf, buf_size, l0 + 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (fread_unlocked (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1) ++ if (fread_unlocked (buf, 1, buf_size + 1, stdin) != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (fread_unlocked (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1) ++ if (fread_unlocked (buf, buf_size + 1, l0 + 1, stdin) != 1) + FAIL (); + CHK_FAIL_END + #endif + + lseek (fileno (stdin), 0, SEEK_SET); + +- if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1 ++ if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); +- if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1 ++ if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1 + || memcmp (buf, "ABCDEFGHI", 9)) + FAIL (); + + lseek (fileno (stdin), 0, SEEK_SET); + +- if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1 ++ if (read (fileno (stdin), buf, l0 + buf_size - 1) != buf_size - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1) ++ if (read (fileno (stdin), buf, buf_size + 1) != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (read (fileno (stdin), buf, l0 + sizeof (buf) + 1) != sizeof (buf) + 1) ++ if (read (fileno (stdin), buf, l0 + buf_size + 1) != buf_size + 1) + FAIL (); + CHK_FAIL_END + #endif + +- if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2) +- != sizeof (buf) - 1 ++ if (pread (fileno (stdin), buf, buf_size - 1, buf_size - 2) ++ != buf_size - 1 + || memcmp (buf, "\nABCDEFGH", 9)) + FAIL (); +- if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 ++ if (pread (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); +- if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3) +- != sizeof (buf) - 1 ++ if (pread (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3) ++ != buf_size - 1 + || memcmp (buf, "h\nABCDEFG", 9)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf)) +- != sizeof (buf) + 1) ++ if (pread (fileno (stdin), buf, buf_size + 1, 2 * buf_size) ++ != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (pread (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf)) +- != sizeof (buf) + 1) ++ if (pread (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size) ++ != buf_size + 1) + FAIL (); + CHK_FAIL_END + #endif + +- if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2) +- != sizeof (buf) - 1 ++ if (pread64 (fileno (stdin), buf, buf_size - 1, buf_size - 2) ++ != buf_size - 1 + || memcmp (buf, "\nABCDEFGH", 9)) + FAIL (); +- if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 ++ if (pread64 (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); +- if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3) +- != sizeof (buf) - 1 ++ if (pread64 (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3) ++ != buf_size - 1 + || memcmp (buf, "h\nABCDEFG", 9)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf)) +- != sizeof (buf) + 1) ++ if (pread64 (fileno (stdin), buf, buf_size + 1, 2 * buf_size) ++ != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf)) +- != sizeof (buf) + 1) ++ if (pread64 (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size) ++ != buf_size + 1) + FAIL (); + CHK_FAIL_END + #endif +@@ -1179,7 +1189,7 @@ do_test (void) + CHK_FAIL2_END + + CHK_FAIL2_START +- snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4); ++ snprintf (buf, buf_size, "%3$d\n", 1, 2, 3, 4); + CHK_FAIL2_END + + int sp[2]; +diff --git a/debug/tst-chk7.c b/debug/tst-chk7.c +new file mode 100644 +index 0000000000000000..2a7b32381268135c +--- /dev/null ++++ b/debug/tst-chk7.c +@@ -0,0 +1,2 @@ ++#define _FORTIFY_SOURCE 3 ++#include "tst-chk1.c" +diff --git a/debug/tst-chk8.cc b/debug/tst-chk8.cc +new file mode 100644 +index 0000000000000000..2a7b32381268135c +--- /dev/null ++++ b/debug/tst-chk8.cc +@@ -0,0 +1,2 @@ ++#define _FORTIFY_SOURCE 3 ++#include "tst-chk1.c" diff --git a/SOURCES/glibc-upstream-2.34-128.patch b/SOURCES/glibc-upstream-2.34-128.patch new file mode 100644 index 0000000..f08fa75 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-128.patch @@ -0,0 +1,24 @@ +commit 98ea9372cc8d60b12aa33e007fdd5f5fb042a651 +Author: Siddhesh Poyarekar +Date: Thu Dec 16 07:19:14 2021 +0530 + + __glibc_unsafe_len: Fix comment + + We know that the length is *unsafe*. + + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit ae23fa3e5fe24daf94fc7f8e5268bb8ceeda7477) + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 4825ff0351c1e5d4..3bb9f38916e30295 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -168,7 +168,7 @@ + __s, __osz)) \ + && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) + +-/* Conversely, we know at compile time that the length is safe if the ++/* Conversely, we know at compile time that the length is unsafe if the + __L * __S <= __OBJSZ condition can be folded to a constant and if it is + false. */ + #define __glibc_unsafe_len(__l, __s, __osz) \ diff --git a/SOURCES/glibc-upstream-2.34-129.patch b/SOURCES/glibc-upstream-2.34-129.patch new file mode 100644 index 0000000..507a5a5 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-129.patch @@ -0,0 +1,91 @@ +commit 10f7bdebe570e42d1f7a43de4f90eda8ccb4f0da +Author: Siddhesh Poyarekar +Date: Fri Dec 17 18:35:44 2021 +0530 + + fortify: Fix spurious warning with realpath + + The length and object size arguments were swapped around for realpath. + Also add a smoke test so that any changes in this area get caught in + future. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 2bbd07c715275eb6c616988925738a0517180d57) + +diff --git a/debug/Makefile b/debug/Makefile +index 357f888246061e15..bc37e466eed490fa 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -108,6 +108,7 @@ CFLAGS-tst-longjmp_chk2.c += -fexceptions -fasynchronous-unwind-tables + CPPFLAGS-tst-longjmp_chk2.c += -D_FORTIFY_SOURCE=1 + CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables + CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1 ++CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2 + + # We know these tests have problems with format strings, this is what + # we are testing. Disable that warning. They are also testing +@@ -155,7 +156,7 @@ tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \ + tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \ + tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \ + tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \ +- tst-backtrace4 tst-backtrace5 tst-backtrace6 ++ tst-backtrace4 tst-backtrace5 tst-backtrace6 tst-realpath-chk + + ifeq ($(have-ssp),yes) + tests += tst-ssp-1 +diff --git a/debug/tst-realpath-chk.c b/debug/tst-realpath-chk.c +new file mode 100644 +index 0000000000000000..a8fcb327c43fb34d +--- /dev/null ++++ b/debug/tst-realpath-chk.c +@@ -0,0 +1,37 @@ ++/* Smoke test to verify that realpath does not cause spurious warnings. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#include ++#include ++ ++static int ++do_test (void) ++{ ++#ifdef PATH_MAX ++ char buf[PATH_MAX + 1]; ++ char *res = realpath (".", buf); ++ TEST_VERIFY (res == buf); ++#endif ++ ++ return 0; ++} ++ ++#include +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index 067115eeca123c6d..ccacbdf76a08225a 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -42,7 +42,7 @@ __NTH (realpath (const char *__restrict __name, char *__restrict __resolved)) + return __realpath_alias (__name, __resolved); + + #if defined _LIBC_LIMITS_H_ && defined PATH_MAX +- if (__glibc_unsafe_len (sz, sizeof (char), PATH_MAX)) ++ if (__glibc_unsafe_len (PATH_MAX, sizeof (char), sz)) + return __realpath_chk_warn (__name, __resolved, sz); + #endif + return __realpath_chk (__name, __resolved, sz); diff --git a/SOURCES/glibc-upstream-2.34-13.patch b/SOURCES/glibc-upstream-2.34-13.patch new file mode 100644 index 0000000..8f0acc6 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-13.patch @@ -0,0 +1,279 @@ +commit 3abf3bd4edc86fb28c099cc85203cb46a811e0b8 +Author: Florian Weimer +Date: Mon Sep 13 11:06:08 2021 +0200 + + nptl: pthread_kill, pthread_cancel should not fail after exit (bug 19193) + + This closes one remaining race condition related to bug 12889: if + the thread already exited on the kernel side, returning ESRCH + is not correct because that error is reserved for the thread IDs + (pthread_t values) whose lifetime has ended. In case of a + kernel-side exit and a valid thread ID, no signal needs to be sent + and cancellation does not have an effect, so just return 0. + + sysdeps/pthread/tst-kill4.c triggers undefined behavior and is + removed with this commit. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 8af8456004edbab71f8903a60a3cae442cf6fe69) + +diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c +index cc25ff21f364e8a4..9bac6e3b76a20312 100644 +--- a/nptl/pthread_cancel.c ++++ b/nptl/pthread_cancel.c +@@ -62,10 +62,11 @@ __pthread_cancel (pthread_t th) + { + volatile struct pthread *pd = (volatile struct pthread *) th; + +- /* Make sure the descriptor is valid. */ +- if (INVALID_TD_P (pd)) +- /* Not a valid thread handle. */ +- return ESRCH; ++ if (pd->tid == 0) ++ /* The thread has already exited on the kernel side. Its outcome ++ (regular exit, other cancelation) has already been ++ determined. */ ++ return 0; + + static int init_sigcancel = 0; + if (atomic_load_relaxed (&init_sigcancel) == 0) +diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c +index f79a2b26fc7f72e5..5d4c86f9205a6fb5 100644 +--- a/nptl/pthread_kill.c ++++ b/nptl/pthread_kill.c +@@ -46,7 +46,12 @@ __pthread_kill_internal (pthread_t threadid, int signo) + ? INTERNAL_SYSCALL_ERRNO (val) : 0); + } + else +- val = ESRCH; ++ /* The kernel reports that the thread has exited. POSIX specifies ++ the ESRCH error only for the case when the lifetime of a thread ++ ID has ended, but calling pthread_kill on such a thread ID is ++ undefined in glibc. Therefore, do not treat kernel thread exit ++ as an error. */ ++ val = 0; + + return val; + } +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index 42f9fc507263657d..dedfa0d290da4949 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -89,7 +89,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-join8 tst-join9 tst-join10 tst-join11 tst-join12 tst-join13 \ + tst-join14 tst-join15 \ + tst-key1 tst-key2 tst-key3 tst-key4 \ +- tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \ ++ tst-kill1 tst-kill2 tst-kill3 tst-kill5 tst-kill6 \ + tst-locale1 tst-locale2 \ + tst-memstream \ + tst-mutex-errorcheck tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 \ +@@ -118,6 +118,9 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-unload \ + tst-unwind-thread \ + tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ ++ tst-pthread_cancel-exited \ ++ tst-pthread_kill-exited \ ++ # tests + + tests-time64 := \ + tst-abstime-time64 \ +diff --git a/sysdeps/pthread/tst-kill4.c b/sysdeps/pthread/tst-kill4.c +deleted file mode 100644 +index 9563939792b96ebd..0000000000000000 +--- a/sysdeps/pthread/tst-kill4.c ++++ /dev/null +@@ -1,90 +0,0 @@ +-/* Copyright (C) 2003-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for 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 * +-tf (void *a) +-{ +- return NULL; +-} +- +- +-int +-do_test (void) +-{ +- pthread_attr_t at; +- if (pthread_attr_init (&at) != 0) +- { +- puts ("attr_create failed"); +- exit (1); +- } +- +- /* Limit thread stack size, because if it is too large, pthread_join +- will free it immediately rather than put it into stack cache. */ +- if (pthread_attr_setstacksize (&at, 2 * 1024 * 1024) != 0) +- { +- puts ("setstacksize failed"); +- exit (1); +- } +- +- pthread_t th; +- if (pthread_create (&th, &at, tf, NULL) != 0) +- { +- puts ("create failed"); +- exit (1); +- } +- +- pthread_attr_destroy (&at); +- +- if (pthread_join (th, NULL) != 0) +- { +- puts ("join failed"); +- exit (1); +- } +- +- /* The following only works because we assume here something about +- the implementation. Namely, that the memory allocated for the +- thread descriptor is not going away, that the TID field is +- cleared and therefore the signal is sent to process 0, and that +- we can savely assume there is no other process with this ID at +- that time. */ +- int e = pthread_kill (th, 0); +- if (e == 0) +- { +- puts ("pthread_kill succeeded"); +- exit (1); +- } +- if (e != ESRCH) +- { +- puts ("pthread_kill didn't return ESRCH"); +- exit (1); +- } +- +- return 0; +-} +- +- +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" +diff --git a/sysdeps/pthread/tst-pthread_cancel-exited.c b/sysdeps/pthread/tst-pthread_cancel-exited.c +new file mode 100644 +index 0000000000000000..811c9bee07ab2638 +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread_cancel-exited.c +@@ -0,0 +1,45 @@ ++/* Test that pthread_kill succeeds for an exited thread. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test verifies that pthread_kill returns 0 (and not ESRCH) for ++ a thread that has exited on the kernel side. */ ++ ++#include ++#include ++#include ++ ++static void * ++noop_thread (void *closure) ++{ ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ pthread_t thr = xpthread_create (NULL, noop_thread, NULL); ++ ++ support_wait_for_thread_exit (); ++ ++ xpthread_cancel (thr); ++ xpthread_join (thr); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/pthread/tst-pthread_kill-exited.c b/sysdeps/pthread/tst-pthread_kill-exited.c +new file mode 100644 +index 0000000000000000..7575fb6d58cae99c +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread_kill-exited.c +@@ -0,0 +1,46 @@ ++/* Test that pthread_kill succeeds for an exited thread. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test verifies that pthread_kill returns 0 (and not ESRCH) for ++ a thread that has exited on the kernel side. */ ++ ++#include ++#include ++#include ++#include ++ ++static void * ++noop_thread (void *closure) ++{ ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ pthread_t thr = xpthread_create (NULL, noop_thread, NULL); ++ ++ support_wait_for_thread_exit (); ++ ++ xpthread_kill (thr, SIGUSR1); ++ xpthread_join (thr); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-130.patch b/SOURCES/glibc-upstream-2.34-130.patch new file mode 100644 index 0000000..e114c75 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-130.patch @@ -0,0 +1,42 @@ +commit d6a58bd81d07322ff5da8f419d8620ef037b6a36 +Author: Siddhesh Poyarekar +Date: Wed Jan 12 18:46:28 2022 +0530 + + Enable _FORTIFY_SOURCE=3 for gcc 12 and above + + gcc 12 now has support for the __builtin_dynamic_object_size builtin. + Adapt the macro checks to enable _FORTIFY_SOURCE=3 on gcc 12 and above. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 86bf0feb0e3ec8e37872f72499d6ae33406561d7) + +diff --git a/include/features.h b/include/features.h +index d974eabfafc24ffb..933499bcff8f1449 100644 +--- a/include/features.h ++++ b/include/features.h +@@ -412,7 +412,9 @@ + # warning _FORTIFY_SOURCE requires compiling with optimization (-O) + # elif !__GNUC_PREREQ (4, 1) + # warning _FORTIFY_SOURCE requires GCC 4.1 or later +-# elif _FORTIFY_SOURCE > 2 && __glibc_clang_prereq (9, 0) ++# elif _FORTIFY_SOURCE > 2 && (__glibc_clang_prereq (9, 0) \ ++ || __GNUC_PREREQ (12, 0)) ++ + # if _FORTIFY_SOURCE > 3 + # warning _FORTIFY_SOURCE > 3 is treated like 3 on this platform + # endif +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 3bb9f38916e30295..515fb681a0547217 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -142,7 +142,8 @@ + #define __bos0(ptr) __builtin_object_size (ptr, 0) + + /* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */ +-#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0) ++#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \ ++ || __GNUC_PREREQ (12, 0)) + # define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) + # define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) + #else diff --git a/SOURCES/glibc-upstream-2.34-131.patch b/SOURCES/glibc-upstream-2.34-131.patch new file mode 100644 index 0000000..d2b1af9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-131.patch @@ -0,0 +1,293 @@ +commit f8c2f620f1929ad78cb0a247601bec972f140c51 +Author: Siddhesh Poyarekar +Date: Wed Jan 12 23:34:23 2022 +0530 + + debug: Autogenerate _FORTIFY_SOURCE tests + + Rename debug/tst-chk1.c to debug/tst-fortify.c and add make hackery to + autogenerate tests with different macros enabled to build and run the + same test with different configurations as well as different + fortification levels. + + The change also ends up expanding the -lfs tests to include + _FORTIFY_SOURCE=3. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + (cherry picked from commit db27f1251b008280a29d540b4f8ab2a38a0d80af) + +diff --git a/Makerules b/Makerules +index 596fa68376f45298..7fbe85719aacc230 100644 +--- a/Makerules ++++ b/Makerules +@@ -424,6 +424,12 @@ $(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c) + endef + object-suffixes-left := $(all-object-suffixes) + include $(o-iterator) ++ ++define o-iterator-doit ++$(objpfx)%$o: $(objpfx)%.cc $(before-compile); $$(compile-command.cc) ++endef ++object-suffixes-left := $(all-object-suffixes) ++include $(o-iterator) + endif + + # Generate .dT files as we compile. +diff --git a/debug/Makefile b/debug/Makefile +index bc37e466eed490fa..acc1b8f6ad029c62 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -1,4 +1,5 @@ +-# Copyright (C) 1998-2021 Free Software Foundation, Inc. ++# Copyright (C) 1998-2022 Free Software Foundation, Inc. ++# Copyright The GNU Toolchain Authors. + # This file is part of the GNU C Library. + + # The GNU C Library is free software; you can redistribute it and/or +@@ -110,32 +111,60 @@ CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables + CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1 + CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2 + ++# _FORTIFY_SOURCE tests. ++# Auto-generate tests for _FORTIFY_SOURCE for different levels, compilers and ++# preprocessor conditions based on tst-fortify.c. ++# ++# To add a new test condition, define a cflags-$(cond) make variable to set ++# CFLAGS for the file. ++ ++tests-all-chk = tst-fortify ++tests-c-chk = ++tests-cc-chk = ++ ++CFLAGS-tst-fortify.c += -Wno-format -Wno-deprecated-declarations -Wno-error ++ ++# No additional flags for the default tests. ++define cflags-default ++endef ++ ++define cflags-lfs ++CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64 ++endef ++ + # We know these tests have problems with format strings, this is what + # we are testing. Disable that warning. They are also testing + # deprecated functions (notably gets) so disable that warning as well. + # And they also generate warnings from warning attributes, which + # cannot be disabled via pragmas, so require -Wno-error to be used. +-CFLAGS-tst-chk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk7.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk8.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-LDLIBS-tst-chk4 = -lstdc++ +-LDLIBS-tst-chk5 = -lstdc++ +-LDLIBS-tst-chk6 = -lstdc++ +-LDLIBS-tst-chk8 = -lstdc++ +-LDLIBS-tst-lfschk4 = -lstdc++ +-LDLIBS-tst-lfschk5 = -lstdc++ +-LDLIBS-tst-lfschk6 = -lstdc++ ++define gen-chk-test ++tests-$(1)-chk += tst-fortify-$(1)-$(2)-$(3) ++CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \ ++ -Wno-deprecated-declarations \ ++ -Wno-error ++$(eval $(call cflags-$(2),$(1),$(3))) ++$(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile ++ ( echo "/* Autogenerated from Makefile. */"; \ ++ echo ""; \ ++ echo "#include \"tst-fortify.c\"" ) > $$@.tmp ++ mv $$@.tmp $$@ ++endef ++ ++chk-extensions = c cc ++chk-types = default lfs ++chk-levels = 1 2 3 ++ ++$(foreach e,$(chk-extensions), \ ++ $(foreach t,$(chk-types), \ ++ $(foreach l,$(chk-levels), \ ++ $(eval $(call gen-chk-test,$(e),$(t),$(l)))))) ++ ++tests-all-chk += $(tests-c-chk) $(tests-cc-chk) ++ ++define link-cc ++LDLIBS-$(1) = -lstdc++ ++endef ++$(foreach t,$(tests-cc-chk), $(eval $(call link-cc,$(t)))) + + # backtrace_symbols only works if we link with -rdynamic. backtrace + # requires unwind tables on most architectures. +@@ -152,19 +181,25 @@ LDFLAGS-tst-backtrace6 = -rdynamic + + CFLAGS-tst-ssp-1.c += -fstack-protector-all + +-tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \ +- tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \ +- tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \ +- tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \ +- tst-backtrace4 tst-backtrace5 tst-backtrace6 tst-realpath-chk ++tests = backtrace-tst \ ++ tst-longjmp_chk \ ++ test-strcpy_chk \ ++ test-stpcpy_chk \ ++ tst-longjmp_chk2 \ ++ tst-backtrace2 \ ++ tst-backtrace3 \ ++ tst-backtrace4 \ ++ tst-backtrace5 \ ++ tst-backtrace6 \ ++ tst-realpath-chk \ ++ $(tests-all-chk) + + ifeq ($(have-ssp),yes) + tests += tst-ssp-1 + endif + + ifeq (,$(CXX)) +-tests-unsupported = tst-chk4 tst-chk5 tst-chk6 tst-chk8 \ +- tst-lfschk4 tst-lfschk5 tst-lfschk6 ++tests-unsupported = $(tests-cc-chk) + endif + + extra-libs = libSegFault libpcprofile +@@ -191,20 +226,10 @@ ifeq ($(run-built-tests),yes) + LOCALES := de_DE.UTF-8 + include ../gen-locales.mk + +-$(objpfx)tst-chk1.out: $(gen-locales) +-$(objpfx)tst-chk2.out: $(gen-locales) +-$(objpfx)tst-chk3.out: $(gen-locales) +-$(objpfx)tst-chk4.out: $(gen-locales) +-$(objpfx)tst-chk5.out: $(gen-locales) +-$(objpfx)tst-chk6.out: $(gen-locales) +-$(objpfx)tst-chk7.out: $(gen-locales) +-$(objpfx)tst-chk8.out: $(gen-locales) +-$(objpfx)tst-lfschk1.out: $(gen-locales) +-$(objpfx)tst-lfschk2.out: $(gen-locales) +-$(objpfx)tst-lfschk3.out: $(gen-locales) +-$(objpfx)tst-lfschk4.out: $(gen-locales) +-$(objpfx)tst-lfschk5.out: $(gen-locales) +-$(objpfx)tst-lfschk6.out: $(gen-locales) ++define chk-gen-locales ++$(objpfx)$(1).out: $(gen-locales) ++endef ++$(foreach t, $(tests-all-chk), $(eval $(call chk-gen-locales,$(t)))) + endif + + sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,') +diff --git a/debug/tst-chk2.c b/debug/tst-chk2.c +deleted file mode 100644 +index be37ce2d22f0760a..0000000000000000 +--- a/debug/tst-chk2.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 1 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk3.c b/debug/tst-chk3.c +deleted file mode 100644 +index 38b8e4fb360ba722..0000000000000000 +--- a/debug/tst-chk3.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 2 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk4.cc b/debug/tst-chk4.cc +deleted file mode 100644 +index c82e6aac86038791..0000000000000000 +--- a/debug/tst-chk4.cc ++++ /dev/null +@@ -1 +0,0 @@ +-#include "tst-chk1.c" +diff --git a/debug/tst-chk5.cc b/debug/tst-chk5.cc +deleted file mode 100644 +index be37ce2d22f0760a..0000000000000000 +--- a/debug/tst-chk5.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 1 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk6.cc b/debug/tst-chk6.cc +deleted file mode 100644 +index 38b8e4fb360ba722..0000000000000000 +--- a/debug/tst-chk6.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 2 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk7.c b/debug/tst-chk7.c +deleted file mode 100644 +index 2a7b32381268135c..0000000000000000 +--- a/debug/tst-chk7.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 3 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk8.cc b/debug/tst-chk8.cc +deleted file mode 100644 +index 2a7b32381268135c..0000000000000000 +--- a/debug/tst-chk8.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 3 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk1.c b/debug/tst-fortify.c +similarity index 100% +rename from debug/tst-chk1.c +rename to debug/tst-fortify.c +diff --git a/debug/tst-lfschk1.c b/debug/tst-lfschk1.c +deleted file mode 100644 +index f3e6d47d5e4484c3..0000000000000000 +--- a/debug/tst-lfschk1.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk1.c" +diff --git a/debug/tst-lfschk2.c b/debug/tst-lfschk2.c +deleted file mode 100644 +index 95d4db1d32d2eeb3..0000000000000000 +--- a/debug/tst-lfschk2.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk2.c" +diff --git a/debug/tst-lfschk3.c b/debug/tst-lfschk3.c +deleted file mode 100644 +index 50a1ae1258f1553d..0000000000000000 +--- a/debug/tst-lfschk3.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk3.c" +diff --git a/debug/tst-lfschk4.cc b/debug/tst-lfschk4.cc +deleted file mode 100644 +index f3e6d47d5e4484c3..0000000000000000 +--- a/debug/tst-lfschk4.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk1.c" +diff --git a/debug/tst-lfschk5.cc b/debug/tst-lfschk5.cc +deleted file mode 100644 +index 95d4db1d32d2eeb3..0000000000000000 +--- a/debug/tst-lfschk5.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk2.c" +diff --git a/debug/tst-lfschk6.cc b/debug/tst-lfschk6.cc +deleted file mode 100644 +index 50a1ae1258f1553d..0000000000000000 +--- a/debug/tst-lfschk6.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk3.c" diff --git a/SOURCES/glibc-upstream-2.34-132.patch b/SOURCES/glibc-upstream-2.34-132.patch new file mode 100644 index 0000000..9da05ba --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-132.patch @@ -0,0 +1,356 @@ +commit 224d8c1890b6c57c7e4e8ddbb792dd9552086704 +Author: Siddhesh Poyarekar +Date: Wed Jan 12 23:34:48 2022 +0530 + + debug: Synchronize feature guards in fortified functions [BZ #28746] + + Some functions (e.g. stpcpy, pread64, etc.) had moved to POSIX in the + main headers as they got incorporated into the standard, but their + fortified variants remained under __USE_GNU. As a result, these + functions did not get fortified when _GNU_SOURCE was not defined. + + Add test wrappers that check all functions tested in tst-chk0 at all + levels with _GNU_SOURCE undefined and then use the failures to (1) + exclude checks for _GNU_SOURCE functions in these tests and (2) Fix + feature macro guards in the fortified function headers so that they're + the same as the ones in the main headers. + + This fixes BZ #28746. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + (cherry picked from commit fcfc9086815bf0d277ad47a90ee3fda4c37acca8) + +diff --git a/debug/Makefile b/debug/Makefile +index acc1b8f6ad029c62..71248e0d457a5b12 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -132,6 +132,12 @@ define cflags-lfs + CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64 + endef + ++define cflags-nongnu ++CFLAGS-tst-fortify-$(1)-nongnu-$(2).$(1) += -D_LARGEFILE64_SOURCE=1 ++endef ++ ++src-chk-nongnu = \#undef _GNU_SOURCE ++ + # We know these tests have problems with format strings, this is what + # we are testing. Disable that warning. They are also testing + # deprecated functions (notably gets) so disable that warning as well. +@@ -145,13 +151,13 @@ CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \ + $(eval $(call cflags-$(2),$(1),$(3))) + $(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile + ( echo "/* Autogenerated from Makefile. */"; \ +- echo ""; \ ++ echo "$(src-chk-$(2))"; \ + echo "#include \"tst-fortify.c\"" ) > $$@.tmp + mv $$@.tmp $$@ + endef + + chk-extensions = c cc +-chk-types = default lfs ++chk-types = default lfs nongnu + chk-levels = 1 2 3 + + $(foreach e,$(chk-extensions), \ +diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c +index 68ac00d1808382b8..8b5902423cf0ad88 100644 +--- a/debug/tst-fortify.c ++++ b/debug/tst-fortify.c +@@ -1,4 +1,5 @@ +-/* Copyright (C) 2004-2021 Free Software Foundation, Inc. ++/* Copyright (C) 2004-2022 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2004. + +@@ -37,6 +38,17 @@ + #include + #include + ++#ifndef _GNU_SOURCE ++# define MEMPCPY memcpy ++# define WMEMPCPY wmemcpy ++# define MEMPCPY_RET(x) 0 ++# define WMEMPCPY_RET(x) 0 ++#else ++# define MEMPCPY mempcpy ++# define WMEMPCPY wmempcpy ++# define MEMPCPY_RET(x) __builtin_strlen (x) ++# define WMEMPCPY_RET(x) wcslen (x) ++#endif + + #define obstack_chunk_alloc malloc + #define obstack_chunk_free free +@@ -163,7 +175,7 @@ do_test (void) + if (memcmp (buf, "aabcdefghi", 10)) + FAIL (); + +- if (mempcpy (buf + 5, "abcde", 5) != buf + 10 ++ if (MEMPCPY (buf + 5, "abcde", 5) != buf + 5 + MEMPCPY_RET ("abcde") + || memcmp (buf, "aabcdabcde", 10)) + FAIL (); + +@@ -208,7 +220,7 @@ do_test (void) + if (memcmp (buf, "aabcdefghi", 10)) + FAIL (); + +- if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 ++ if (MEMPCPY (buf + 5, "abcde", l0 + 5) != buf + 5 + MEMPCPY_RET ("abcde") + || memcmp (buf, "aabcdabcde", 10)) + FAIL (); + +@@ -267,7 +279,8 @@ do_test (void) + if (memcmp (a.buf1, "aabcdefghi", 10)) + FAIL (); + +- if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10 ++ if (MEMPCPY (a.buf1 + 5, "abcde", l0 + 5) ++ != a.buf1 + 5 + MEMPCPY_RET ("abcde") + || memcmp (a.buf1, "aabcdabcde", 10)) + FAIL (); + +@@ -348,6 +361,7 @@ do_test (void) + bcopy (buf + 1, buf + 2, l0 + 9); + CHK_FAIL_END + ++#ifdef _GNU_SOURCE + CHK_FAIL_START + p = (char *) mempcpy (buf + 6, "abcde", 5); + CHK_FAIL_END +@@ -355,6 +369,7 @@ do_test (void) + CHK_FAIL_START + p = (char *) mempcpy (buf + 6, "abcde", l0 + 5); + CHK_FAIL_END ++#endif + + CHK_FAIL_START + memset (buf + 9, 'j', 2); +@@ -465,6 +480,7 @@ do_test (void) + bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9); + CHK_FAIL_END + ++#ifdef _GNU_SOURCE + CHK_FAIL_START + p = (char *) mempcpy (a.buf1 + 6, "abcde", 5); + CHK_FAIL_END +@@ -472,6 +488,7 @@ do_test (void) + CHK_FAIL_START + p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5); + CHK_FAIL_END ++#endif + + CHK_FAIL_START + memset (a.buf1 + 9, 'j', 2); +@@ -551,7 +568,7 @@ do_test (void) + if (wmemcmp (wbuf, L"aabcdefghi", 10)) + FAIL (); + +- if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10 ++ if (WMEMPCPY (wbuf + 5, L"abcde", 5) != wbuf + 5 + WMEMPCPY_RET (L"abcde") + || wmemcmp (wbuf, L"aabcdabcde", 10)) + FAIL (); + +@@ -584,7 +601,8 @@ do_test (void) + if (wmemcmp (wbuf, L"aabcdefghi", 10)) + FAIL (); + +- if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10 ++ if (WMEMPCPY (wbuf + 5, L"abcde", l0 + 5) ++ != wbuf + 5 + WMEMPCPY_RET (L"abcde") + || wmemcmp (wbuf, L"aabcdabcde", 10)) + FAIL (); + +@@ -626,7 +644,8 @@ do_test (void) + if (wmemcmp (wa.buf1, L"aabcdefghi", 10)) + FAIL (); + +- if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10 ++ if (WMEMPCPY (wa.buf1 + 5, L"abcde", l0 + 5) ++ != wa.buf1 + 5 + WMEMPCPY_RET (L"abcde") + || wmemcmp (wa.buf1, L"aabcdabcde", 10)) + FAIL (); + +@@ -695,6 +714,7 @@ do_test (void) + wmemmove (wbuf + 2, wbuf + 1, l0 + 9); + CHK_FAIL_END + ++#ifdef _GNU_SOURCE + CHK_FAIL_START + wp = wmempcpy (wbuf + 6, L"abcde", 5); + CHK_FAIL_END +@@ -702,6 +722,7 @@ do_test (void) + CHK_FAIL_START + wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5); + CHK_FAIL_END ++#endif + + CHK_FAIL_START + wmemset (wbuf + 9, L'j', 2); +@@ -769,6 +790,7 @@ do_test (void) + wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9); + CHK_FAIL_END + ++#ifdef _GNU_SOURCE + CHK_FAIL_START + wp = wmempcpy (wa.buf1 + 6, L"abcde", 5); + CHK_FAIL_END +@@ -776,6 +798,7 @@ do_test (void) + CHK_FAIL_START + wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5); + CHK_FAIL_END ++#endif + + CHK_FAIL_START + wmemset (wa.buf1 + 9, L'j', 2); +@@ -907,6 +930,7 @@ do_test (void) + if (fprintf (fp, buf2 + 4, str5) != 7) + FAIL (); + ++#ifdef _GNU_SOURCE + char *my_ptr = NULL; + strcpy (buf2 + 2, "%n%s%n"); + /* When the format string is writable and contains %n, +@@ -936,6 +960,7 @@ do_test (void) + if (obstack_printf (&obs, "%s%n%s%n", str4, &n1, str5, &n1) != 14) + FAIL (); + obstack_free (&obs, NULL); ++#endif + + if (freopen (temp_filename, "r", stdin) == NULL) + { +@@ -983,6 +1008,7 @@ do_test (void) + + rewind (stdin); + ++#ifdef _GNU_SOURCE + if (fgets_unlocked (buf, buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); +@@ -1009,6 +1035,7 @@ do_test (void) + #endif + + rewind (stdin); ++#endif + + if (fread (buf, 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) +@@ -1579,7 +1606,10 @@ do_test (void) + ret = 1; + } + +- int fd = posix_openpt (O_RDWR); ++ int fd; ++ ++#ifdef _GNU_SOURCE ++ fd = posix_openpt (O_RDWR); + if (fd != -1) + { + char enough[1000]; +@@ -1595,6 +1625,7 @@ do_test (void) + #endif + close (fd); + } ++#endif + + #if PATH_MAX > 0 + confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf)); +@@ -1712,8 +1743,9 @@ do_test (void) + poll (fds, l0 + 2, 0); + CHK_FAIL_END + #endif ++#ifdef _GNU_SOURCE + ppoll (fds, 1, NULL, NULL); +-#if __USE_FORTIFY_LEVEL >= 1 ++# if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + ppoll (fds, 2, NULL, NULL); + CHK_FAIL_END +@@ -1721,6 +1753,7 @@ do_test (void) + CHK_FAIL_START + ppoll (fds, l0 + 2, NULL, NULL); + CHK_FAIL_END ++# endif + #endif + + return ret; +diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h +index 697dcbbf7b4b26f6..1df7e5ceef3e1fd4 100644 +--- a/posix/bits/unistd.h ++++ b/posix/bits/unistd.h +@@ -40,7 +40,7 @@ read (int __fd, void *__buf, size_t __nbytes) + __fd, __buf, __nbytes); + } + +-#ifdef __USE_UNIX98 ++#if defined __USE_UNIX98 || defined __USE_XOPEN2K8 + extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes, + __off_t __offset, size_t __bufsize) + __wur __attr_access ((__write_only__, 2, 3)); +diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h +index 5731274848260ad2..218006c9ba882d9c 100644 +--- a/string/bits/string_fortified.h ++++ b/string/bits/string_fortified.h +@@ -79,7 +79,7 @@ __NTH (strcpy (char *__restrict __dest, const char *__restrict __src)) + return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest)); + } + +-#ifdef __USE_GNU ++#ifdef __USE_XOPEN2K8 + __fortify_function char * + __NTH (stpcpy (char *__restrict __dest, const char *__restrict __src)) + { +@@ -96,14 +96,15 @@ __NTH (strncpy (char *__restrict __dest, const char *__restrict __src, + __glibc_objsize (__dest)); + } + +-#if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6) ++#ifdef __USE_XOPEN2K8 ++# if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6) + __fortify_function char * + __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) + { + return __builtin___stpncpy_chk (__dest, __src, __n, + __glibc_objsize (__dest)); + } +-#else ++# else + extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n, + size_t __destlen) __THROW + __fortified_attr_access ((__write_only__, 1, 3)) +@@ -119,6 +120,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) + return __stpncpy_chk (__dest, __src, __n, __bos (__dest)); + return __stpncpy_alias (__dest, __src, __n); + } ++# endif + #endif + + +diff --git a/support/xsignal.h b/support/xsignal.h +index 8ee1fa6b4dceeadf..692e0f2c4242d848 100644 +--- a/support/xsignal.h ++++ b/support/xsignal.h +@@ -28,7 +28,9 @@ __BEGIN_DECLS + terminate the process on error. */ + + void xraise (int sig); ++#ifdef _GNU_SOURCE + sighandler_t xsignal (int sig, sighandler_t handler); ++#endif + void xsigaction (int sig, const struct sigaction *newact, + struct sigaction *oldact); + +diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h +index 26012ef9366c0b88..88c1fdfcd34292f4 100644 +--- a/wcsmbs/bits/wchar2.h ++++ b/wcsmbs/bits/wchar2.h +@@ -457,7 +457,7 @@ __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src, + } + + +-#ifdef __USE_GNU ++#ifdef __USE_XOPEN2K8 + extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst, + const char **__restrict __src, size_t __nmc, + size_t __len, mbstate_t *__restrict __ps, diff --git a/SOURCES/glibc-upstream-2.34-133.patch b/SOURCES/glibc-upstream-2.34-133.patch new file mode 100644 index 0000000..a0c4478 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-133.patch @@ -0,0 +1,178 @@ +commit 738ee53f0ce5e39b9b7a6777f5d3057afbaac498 +Author: John David Anglin +Date: Tue Mar 15 23:12:37 2022 +0000 + + hppa: Implement swapcontext in assembler (bug 28960) + + When swapcontext.c is compiled without -g, the following error occurs: + Error: CFI instruction used without previous .cfi_startproc + + Fix by converting swapcontext routine to assembler. + +diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.S b/sysdeps/unix/sysv/linux/hppa/swapcontext.S +new file mode 100644 +index 0000000000000000..94b164dc6375563e +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.S +@@ -0,0 +1,72 @@ ++/* Swap to new context. ++ Copyright (C) 2008-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include "ucontext_i.h" ++ ++ .text ++ENTRY(__swapcontext) ++ ++ /* Copy rp to ret0 (r28). */ ++ copy %rp,%ret0 ++ ++ /* Create a frame. */ ++ ldo 64(%sp),%sp ++ .cfi_def_cfa_offset -64 ++ ++ /* Save the current machine context to oucp. */ ++ bl __getcontext,%rp ++ ++ /* Copy oucp to register ret1 (r29). __getcontext saves and ++ restores it on a normal return. It is restored from oR29 ++ on reactivation. */ ++ copy %r26,%ret1 ++ ++ /* Pop frame. */ ++ ldo -64(%sp),%sp ++ .cfi_def_cfa_offset 0 ++ ++ /* Load return pointer from oR28. */ ++ ldw oR28(%ret1),%rp ++ ++ /* Return if error. */ ++ or,= %r0,%ret0,%r0 ++ bv,n %r0(%rp) ++ ++ /* Load sc_sar flag. */ ++ ldb oSAR(%ret1),%r20 ++ ++ /* Return if oucp context has been reactivated. */ ++ or,= %r0,%r20,%r0 ++ bv,n %r0(%rp) ++ ++ /* Mark sc_sar flag. */ ++ ldi 1,%r20 ++ stb %r20,oSAR(%ret1) ++ ++ /* Activate the machine context in ucp. */ ++ bl __setcontext,%rp ++ ldw oR25(%ret1),%r26 ++ ++ /* Load return pointer. */ ++ ldw oR28(%ret1),%rp ++ bv,n %r0(%rp) ++ ++PSEUDO_END(__swapcontext) ++ ++weak_alias (__swapcontext, swapcontext) +diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.c b/sysdeps/unix/sysv/linux/hppa/swapcontext.c +deleted file mode 100644 +index 1664f68c7b9982e8..0000000000000000 +--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.c ++++ /dev/null +@@ -1,83 +0,0 @@ +-/* Swap to new context. +- Copyright (C) 2008-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Helge Deller , 2008. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for 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 "ucontext_i.h" +- +-extern int __getcontext (ucontext_t *ucp); +-extern int __setcontext (const ucontext_t *ucp); +- +-int +-__swapcontext (ucontext_t *oucp, const ucontext_t *ucp) +-{ +- /* Save rp for debugger. */ +- asm ("stw %rp,-20(%sp)"); +- asm (".cfi_offset 2, -20"); +- +- /* Copy rp to ret0 (r28). */ +- asm ("copy %rp,%ret0"); +- +- /* Create a frame. */ +- asm ("ldo 64(%sp),%sp"); +- asm (".cfi_def_cfa_offset -64"); +- +- /* Save the current machine context to oucp. */ +- asm ("bl __getcontext,%rp"); +- +- /* Copy oucp to register ret1 (r29). __getcontext saves and restores it +- on a normal return. It is restored from oR29 on reactivation. */ +- asm ("copy %r26,%ret1"); +- +- /* Pop frame. */ +- asm ("ldo -64(%sp),%sp"); +- asm (".cfi_def_cfa_offset 0"); +- +- /* Load return pointer from oR28. */ +- asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28)); +- +- /* Return if error. */ +- asm ("or,= %r0,%ret0,%r0"); +- asm ("bv,n %r0(%rp)"); +- +- /* Load sc_sar flag. */ +- asm ("ldb %0(%%ret1),%%r20" : : "i" (oSAR)); +- +- /* Return if oucp context has been reactivated. */ +- asm ("or,= %r0,%r20,%r0"); +- asm ("bv,n %r0(%rp)"); +- +- /* Mark sc_sar flag. */ +- asm ("1: ldi 1,%r20"); +- asm ("stb %%r20,%0(%%ret1)" : : "i" (oSAR)); +- +- /* Activate the machine context in ucp. */ +- asm ("bl __setcontext,%rp"); +- asm ("ldw %0(%%ret1),%%r26" : : "i" (oR25)); +- +- /* Load return pointer. */ +- asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28)); +- +- /* A successful call to setcontext does not return. */ +- asm ("bv,n %r0(%rp)"); +- +- /* Make gcc happy. */ +- return 0; +-} +- +-weak_alias (__swapcontext, swapcontext) diff --git a/SOURCES/glibc-upstream-2.34-134.patch b/SOURCES/glibc-upstream-2.34-134.patch new file mode 100644 index 0000000..79d45ee --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-134.patch @@ -0,0 +1,20 @@ +commit d53b9cc391c72a1011ea8fe7a9f70dc5060a0db2 +Author: John David Anglin +Date: Tue Mar 15 23:04:39 2022 +0000 + + hppa: Use END instead of PSEUDO_END in swapcontext.S + + (cherry picked from commit 7a5c440102d4ec7fafd9bbd98eca9bd90ecaaafd) + +diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.S b/sysdeps/unix/sysv/linux/hppa/swapcontext.S +index 94b164dc6375563e..fbc22586d1195a0d 100644 +--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.S ++++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.S +@@ -67,6 +67,6 @@ ENTRY(__swapcontext) + ldw oR28(%ret1),%rp + bv,n %r0(%rp) + +-PSEUDO_END(__swapcontext) ++END(__swapcontext) + + weak_alias (__swapcontext, swapcontext) diff --git a/SOURCES/glibc-upstream-2.34-135.patch b/SOURCES/glibc-upstream-2.34-135.patch new file mode 100644 index 0000000..e5b3840 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-135.patch @@ -0,0 +1,35 @@ +commit 4b5b8a1cdf39bed02b8b973717796eccde455ed6 +Author: Fangrui Song +Date: Mon Sep 27 10:12:50 2021 -0700 + + powerpc: Delete unneeded ELF_MACHINE_BEFORE_RTLD_RELOC + + Reviewed-by: Raphael M Zinsly + (cherry picked from commit 8e2557a2b85b2eb0ed50a9016a4ffc6b859b97e6) + +diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h +index ced3a7b659cfcff1..b93cf486b6cda5fd 100644 +--- a/sysdeps/powerpc/powerpc32/dl-machine.h ++++ b/sysdeps/powerpc/powerpc32/dl-machine.h +@@ -109,8 +109,6 @@ elf_machine_load_address (void) + return runtime_dynamic - elf_machine_dynamic (); + } + +-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */ +- + /* The PLT uses Elf32_Rela relocs. */ + #define elf_machine_relplt elf_machine_rela + +diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h +index b90f407119efd431..b3f3352bcf5a52b0 100644 +--- a/sysdeps/powerpc/powerpc64/dl-machine.h ++++ b/sysdeps/powerpc/powerpc64/dl-machine.h +@@ -116,8 +116,6 @@ elf_machine_dynamic (void) + return runtime_dynamic - elf_machine_load_address() ; + } + +-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */ +- + /* The PLT uses Elf64_Rela relocs. */ + #define elf_machine_relplt elf_machine_rela + diff --git a/SOURCES/glibc-upstream-2.34-136.patch b/SOURCES/glibc-upstream-2.34-136.patch new file mode 100644 index 0000000..0906c1c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-136.patch @@ -0,0 +1,2020 @@ +commit b19de59d620b3a9e6adf937f322f4281b67fc712 +Author: Fangrui Song +Date: Thu Oct 7 11:55:02 2021 -0700 + + elf: Avoid nested functions in the loader [BZ #27220] + + dynamic-link.h is included more than once in some elf/ files (rtld.c, + dl-conflict.c, dl-reloc.c, dl-reloc-static-pie.c) and uses GCC nested + functions. This harms readability and the nested functions usage + is the biggest obstacle prevents Clang build (Clang doesn't support GCC + nested functions). + + The key idea for unnesting is to add extra parameters (struct link_map + *and struct r_scope_elm *[]) to RESOLVE_MAP, + ELF_MACHINE_BEFORE_RTLD_RELOC, ELF_DYNAMIC_RELOCATE, elf_machine_rel[a], + elf_machine_lazy_rel, and elf_machine_runtime_setup. (This is inspired + by Stan Shebs' ppc64/x86-64 implementation in the + google/grte/v5-2.27/master which uses mixed extra parameters and static + variables.) + + Future simplification: + * If mips elf_machine_runtime_setup no longer needs RESOLVE_GOTSYM, + elf_machine_runtime_setup can drop the `scope` parameter. + * If TLSDESC no longer need to be in elf_machine_lazy_rel, + elf_machine_lazy_rel can drop the `scope` parameter. + + Tested on aarch64, i386, x86-64, powerpc64le, powerpc64, powerpc32, + sparc64, sparcv9, s390x, s390, hppa, ia64, armhf, alpha, and mips64. + In addition, tested build-many-glibcs.py with {arc,csky,microblaze,nios2}-linux-gnu + and riscv64-linux-gnu-rv64imafdc-lp64d. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 490e6c62aa31a8aa5c4a059f6e646ede121edf0a) + +diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c +index 31a2f90770ce2a55..5c8e51d19ae095d6 100644 +--- a/elf/dl-conflict.c ++++ b/elf/dl-conflict.c +@@ -27,20 +27,12 @@ + #include + #include "dynamic-link.h" + +-void +-_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, +- ElfW(Rela) *conflictend) +-{ +-#if ! ELF_MACHINE_NO_RELA +- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) +- _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name)); +- +- { +- /* Do the conflict relocation of the object and library GOT and other +- data. */ ++/* Used at loading time solely for prelink executable. It is not called ++ concurrently so it is be safe to defined as static. */ ++static struct link_map *resolve_conflict_map __attribute__ ((__unused__)); + + /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ +-#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL) ++#define RESOLVE_MAP(map, scope, ref, version, flags) (*ref = NULL, NULL) + #define RESOLVE(ref, version, flags) (*ref = NULL, 0) + #define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \ + do { \ +@@ -51,12 +43,23 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, + (map) = resolve_conflict_map; \ + } while (0) + ++#include "dynamic-link.h" ++ ++void ++_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, ++ ElfW(Rela) *conflictend) ++{ ++#if ! ELF_MACHINE_NO_RELA ++ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) ++ _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name)); ++ ++ { ++ /* Do the conflict relocation of the object and library GOT and other ++ data. */ ++ + /* Prelinking makes no sense for anything but the main namespace. */ + assert (l->l_ns == LM_ID_BASE); +- struct link_map *resolve_conflict_map __attribute__ ((__unused__)) +- = GL(dl_ns)[LM_ID_BASE]._ns_loaded; +- +-#include "dynamic-link.h" ++ resolve_conflict_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; + + /* Override these, defined in dynamic-link.h. */ + #undef CHECK_STATIC_TLS +@@ -67,8 +70,8 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, + GL(dl_num_cache_relocations) += conflictend - conflict; + + for (; conflict < conflictend; ++conflict) +- elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset, +- 0); ++ elf_machine_rela (l, NULL, conflict, NULL, NULL, ++ (void *) conflict->r_offset, 0); + } + #endif + } +diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c +index 2fb02d727654c87d..a52ba8aeb8b573cb 100644 +--- a/elf/dl-reloc-static-pie.c ++++ b/elf/dl-reloc-static-pie.c +@@ -19,8 +19,14 @@ + #if ENABLE_STATIC_PIE + /* Mark symbols hidden in static PIE for early self relocation to work. */ + # pragma GCC visibility push(hidden) ++#include + #include + #include ++ ++#include ++ ++#define STATIC_PIE_BOOTSTRAP ++#define RESOLVE_MAP(map, scope, sym, version, flags) map + #include "dynamic-link.h" + + /* Relocate static executable with PIE. */ +@@ -30,11 +36,6 @@ _dl_relocate_static_pie (void) + { + struct link_map *main_map = _dl_get_dl_main_map (); + +-# define STATIC_PIE_BOOTSTRAP +-# define BOOTSTRAP_MAP (main_map) +-# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP +-# include "dynamic-link.h" +- + /* Figure out the run-time load address of static PIE. */ + main_map->l_addr = elf_machine_load_address (); + +@@ -53,12 +54,12 @@ _dl_relocate_static_pie (void) + elf_get_dynamic_info (main_map); + + # ifdef ELF_MACHINE_BEFORE_RTLD_RELOC +- ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info); ++ ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info); + # endif + + /* Relocate ourselves so we can do normal function calls and + data access using the global offset table. */ +- ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0); ++ ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0); + main_map->l_relocated = 1; + + /* Initialize _r_debug. */ +diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c +index e13a672ade6d7a28..3447de7f3536cd70 100644 +--- a/elf/dl-reloc.c ++++ b/elf/dl-reloc.c +@@ -162,6 +162,32 @@ _dl_nothread_init_static_tls (struct link_map *map) + } + #endif /* !THREAD_GSCOPE_IN_TCB */ + ++/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ ++#define RESOLVE_MAP(l, scope, ref, version, r_type) \ ++ ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \ ++ && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \ ++ ? ((__glibc_unlikely ((*ref) == l->l_lookup_cache.sym) \ ++ && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class) \ ++ ? (bump_num_cache_relocations (), \ ++ (*ref) = l->l_lookup_cache.ret, \ ++ l->l_lookup_cache.value) \ ++ : ({ lookup_t _lr; \ ++ int _tc = elf_machine_type_class (r_type); \ ++ l->l_lookup_cache.type_class = _tc; \ ++ l->l_lookup_cache.sym = (*ref); \ ++ const struct r_found_version *v = NULL; \ ++ if ((version) != NULL && (version)->hash != 0) \ ++ v = (version); \ ++ _lr = _dl_lookup_symbol_x ((const char *) D_PTR (l, l_info[DT_STRTAB]) + (*ref)->st_name, \ ++ l, (ref), scope, v, _tc, \ ++ DL_LOOKUP_ADD_DEPENDENCY \ ++ | DL_LOOKUP_FOR_RELOCATE, NULL); \ ++ l->l_lookup_cache.ret = (*ref); \ ++ l->l_lookup_cache.value = _lr; })) \ ++ : l) ++ ++#include "dynamic-link.h" ++ + void + _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + int reloc_mode, int consider_profiling) +@@ -243,36 +269,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + { + /* Do the actual relocation of the object's GOT and other data. */ + +- /* String table object symbols. */ +- const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); +- +- /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ +-#define RESOLVE_MAP(ref, version, r_type) \ +- ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \ +- && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \ +- ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0) \ +- && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class) \ +- ? (bump_num_cache_relocations (), \ +- (*ref) = l->l_lookup_cache.ret, \ +- l->l_lookup_cache.value) \ +- : ({ lookup_t _lr; \ +- int _tc = elf_machine_type_class (r_type); \ +- l->l_lookup_cache.type_class = _tc; \ +- l->l_lookup_cache.sym = (*ref); \ +- const struct r_found_version *v = NULL; \ +- if ((version) != NULL && (version)->hash != 0) \ +- v = (version); \ +- _lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref), \ +- scope, v, _tc, \ +- DL_LOOKUP_ADD_DEPENDENCY \ +- | DL_LOOKUP_FOR_RELOCATE, NULL); \ +- l->l_lookup_cache.ret = (*ref); \ +- l->l_lookup_cache.value = _lr; })) \ +- : l) +- +-#include "dynamic-link.h" +- +- ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc); ++ ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc); + + #ifndef PROF + if (__glibc_unlikely (consider_profiling) +diff --git a/elf/do-rel.h b/elf/do-rel.h +index 321ac2b359c1028c..f441b749190c2641 100644 +--- a/elf/do-rel.h ++++ b/elf/do-rel.h +@@ -37,8 +37,8 @@ + relocations; they should be set up to call _dl_runtime_resolve, rather + than fully resolved now. */ + +-auto inline void __attribute__ ((always_inline)) +-elf_dynamic_do_Rel (struct link_map *map, ++static inline void __attribute__ ((always_inline)) ++elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], + ElfW(Addr) reladdr, ElfW(Addr) relsize, + __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative, + int lazy, int skip_ifunc) +@@ -68,13 +68,13 @@ elf_dynamic_do_Rel (struct link_map *map, + } + else + # endif +- elf_machine_lazy_rel (map, l_addr, r, skip_ifunc); ++ elf_machine_lazy_rel (map, scope, l_addr, r, skip_ifunc); + + # ifdef ELF_MACHINE_IRELATIVE + if (r2 != NULL) + for (; r2 <= end2; ++r2) + if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE) +- elf_machine_lazy_rel (map, l_addr, r2, skip_ifunc); ++ elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc); + # endif + } + else +@@ -134,7 +134,7 @@ elf_dynamic_do_Rel (struct link_map *map, + #endif + + ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; +- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], ++ elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], + &map->l_versions[ndx], + (void *) (l_addr + r->r_offset), skip_ifunc); + } +@@ -146,7 +146,7 @@ elf_dynamic_do_Rel (struct link_map *map, + { + ElfW(Half) ndx + = version[ELFW(R_SYM) (r2->r_info)] & 0x7fff; +- elf_machine_rel (map, r2, ++ elf_machine_rel (map, scope, r2, + &symtab[ELFW(R_SYM) (r2->r_info)], + &map->l_versions[ndx], + (void *) (l_addr + r2->r_offset), +@@ -167,14 +167,14 @@ elf_dynamic_do_Rel (struct link_map *map, + } + else + # endif +- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, ++ elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, + (void *) (l_addr + r->r_offset), skip_ifunc); + + # ifdef ELF_MACHINE_IRELATIVE + if (r2 != NULL) + for (; r2 <= end2; ++r2) + if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE) +- elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)], ++ elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)], + NULL, (void *) (l_addr + r2->r_offset), + skip_ifunc); + # endif +diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h +index 3eb24ba3a6cee40b..7cc30211649d3820 100644 +--- a/elf/dynamic-link.h ++++ b/elf/dynamic-link.h +@@ -59,31 +59,33 @@ int _dl_try_allocate_static_tls (struct link_map *map, bool optional) + copying memory, breaking the very code written to handle the + unaligned cases. */ + # if ! ELF_MACHINE_NO_REL +-auto inline void __attribute__((always_inline)) +-elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc, +- const ElfW(Sym) *sym, const struct r_found_version *version, ++static inline void __attribute__((always_inline)) ++elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[], ++ const ElfW(Rel) *reloc, const ElfW(Sym) *sym, ++ const struct r_found_version *version, + void *const reloc_addr, int skip_ifunc); +-auto inline void __attribute__((always_inline)) ++static inline void __attribute__((always_inline)) + elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc, + void *const reloc_addr); + # endif + # if ! ELF_MACHINE_NO_RELA +-auto inline void __attribute__((always_inline)) +-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, +- const ElfW(Sym) *sym, const struct r_found_version *version, +- void *const reloc_addr, int skip_ifunc); +-auto inline void __attribute__((always_inline)) ++static inline void __attribute__((always_inline)) ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const ElfW(Rela) *reloc, const ElfW(Sym) *sym, ++ const struct r_found_version *version, void *const reloc_addr, ++ int skip_ifunc); ++static inline void __attribute__((always_inline)) + elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + void *const reloc_addr); + # endif + # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL +-auto inline void __attribute__((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++static inline void __attribute__((always_inline)) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + ElfW(Addr) l_addr, const ElfW(Rel) *reloc, + int skip_ifunc); + # else +-auto inline void __attribute__((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++static inline void __attribute__((always_inline)) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + int skip_ifunc); + # endif +@@ -114,7 +116,7 @@ elf_machine_lazy_rel (struct link_map *map, + consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL* + are completely separate and there is a gap between them. */ + +-# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \ ++# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, skip_ifunc, test_rel) \ + do { \ + struct { ElfW(Addr) start, size; \ + __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \ +@@ -152,18 +154,18 @@ elf_machine_lazy_rel (struct link_map *map, + } \ + \ + if (ELF_DURING_STARTUP) \ +- elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \ +- ranges[0].nrelative, 0, skip_ifunc); \ ++ elf_dynamic_do_##reloc ((map), scope, ranges[0].start, ranges[0].size, \ ++ ranges[0].nrelative, 0, skip_ifunc); \ + else \ + { \ + int ranges_index; \ + for (ranges_index = 0; ranges_index < 2; ++ranges_index) \ +- elf_dynamic_do_##reloc ((map), \ ++ elf_dynamic_do_##reloc ((map), scope, \ + ranges[ranges_index].start, \ + ranges[ranges_index].size, \ + ranges[ranges_index].nrelative, \ + ranges[ranges_index].lazy, \ +- skip_ifunc); \ ++ skip_ifunc); \ + } \ + } while (0) + +@@ -175,29 +177,29 @@ elf_machine_lazy_rel (struct link_map *map, + + # if ! ELF_MACHINE_NO_REL + # include "do-rel.h" +-# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \ +- _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL) ++# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) \ ++ _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL) + # else +-# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do. */ ++# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) /* Nothing to do. */ + # endif + + # if ! ELF_MACHINE_NO_RELA + # define DO_RELA + # include "do-rel.h" +-# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \ +- _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL) ++# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) \ ++ _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL) + # else +-# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */ ++# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do. */ + # endif + + /* This can't just be an inline function because GCC is too dumb + to inline functions containing inlines themselves. */ +-# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \ ++# define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \ + do { \ +- int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \ ++ int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy), \ + (consider_profile)); \ +- ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \ +- ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \ ++ ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \ ++ ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \ + } while (0) + + #endif +diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h +index 4aa2058abf6443c9..15c316b38c05a90c 100644 +--- a/elf/get-dynamic-info.h ++++ b/elf/get-dynamic-info.h +@@ -16,18 +16,15 @@ + License along with the GNU C Library; if not, see + . */ + +-/* This file is included multiple times and therefore lacks a header +- file inclusion guard. */ ++/* Populate dynamic tags in l_info. */ ++ ++#ifndef _GET_DYNAMIC_INFO_H ++#define _GET_DYNAMIC_INFO_H + + #include + #include + +-#ifndef RESOLVE_MAP +-static +-#else +-auto +-#endif +-inline void __attribute__ ((unused, always_inline)) ++static inline void __attribute__ ((unused, always_inline)) + elf_get_dynamic_info (struct link_map *l) + { + #if __ELF_NATIVE_CLASS == 32 +@@ -165,3 +162,5 @@ elf_get_dynamic_info (struct link_map *l) + info[DT_RPATH] = NULL; + #endif + } ++ ++#endif +diff --git a/elf/rtld.c b/elf/rtld.c +index 84eac9a8df7125a6..ee45657aeac14f3c 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -502,13 +502,9 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) + return start_addr; + } + +-static ElfW(Addr) __attribute_used__ +-_dl_start (void *arg) +-{ + #ifdef DONT_USE_BOOTSTRAP_MAP + # define bootstrap_map GL(dl_rtld_map) + #else +- struct dl_start_final_info info; + # define bootstrap_map info.l + #endif + +@@ -517,13 +513,16 @@ _dl_start (void *arg) + Since ld.so must not have any undefined symbols the result + is trivial: always the map of ld.so itself. */ + #define RTLD_BOOTSTRAP +-#define BOOTSTRAP_MAP (&bootstrap_map) +-#define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP ++#define RESOLVE_MAP(map, scope, sym, version, flags) map + #include "dynamic-link.h" + ++static ElfW(Addr) __attribute_used__ ++_dl_start (void *arg) ++{ + #ifdef DONT_USE_BOOTSTRAP_MAP + rtld_timer_start (&start_time); + #else ++ struct dl_start_final_info info; + rtld_timer_start (&info.start_time); + #endif + +@@ -557,7 +556,7 @@ _dl_start (void *arg) + #endif + + #ifdef ELF_MACHINE_BEFORE_RTLD_RELOC +- ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info); ++ ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info); + #endif + + if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)]) +@@ -565,7 +564,7 @@ _dl_start (void *arg) + /* Relocate ourselves so we can do normal function calls and + data access using the global offset table. */ + +- ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0); ++ ELF_DYNAMIC_RELOCATE (&bootstrap_map, NULL, 0, 0, 0); + } + bootstrap_map.l_relocated = 1; + +diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h +index d29d827ab32a78ee..34c0790b893a529b 100644 +--- a/sysdeps/aarch64/dl-machine.h ++++ b/sysdeps/aarch64/dl-machine.h +@@ -65,7 +65,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((unused)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + if (l->l_info[DT_JMPREL] && lazy) + { +@@ -243,10 +244,11 @@ elf_machine_plt_value (struct link_map *map, + + #ifdef RESOLVE_MAP + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, +- const ElfW(Sym) *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const ElfW(Rela) *reloc, const ElfW(Sym) *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + ElfW(Addr) *const reloc_addr = reloc_addr_arg; +@@ -259,7 +261,8 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + else + { + const ElfW(Sym) *const refsym = sym; +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true); + + if (sym != NULL +@@ -383,9 +386,9 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, + *reloc_addr = l_addr + reloc->r_addend; + } + +-inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + ElfW(Addr) l_addr, + const ElfW(Rela) *reloc, + int skip_ifunc) +@@ -412,7 +415,7 @@ elf_machine_lazy_rel (struct link_map *map, + (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, ++ elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, + skip_ifunc); + return; + } +@@ -439,7 +442,8 @@ elf_machine_lazy_rel (struct link_map *map, + + /* Always initialize TLS descriptors completely, because lazy + initialization requires synchronization at every TLS access. */ +- elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc); ++ elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, ++ skip_ifunc); + } + else if (__glibc_unlikely (r_type == AARCH64_R(IRELATIVE))) + { +diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h +index 2cd2213d9ab25287..66e1db524bb378f6 100644 +--- a/sysdeps/alpha/dl-machine.h ++++ b/sysdeps/alpha/dl-machine.h +@@ -70,7 +70,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int +-elf_machine_runtime_setup (struct link_map *map, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + extern char _dl_runtime_resolve_new[] attribute_hidden; + extern char _dl_runtime_profile_new[] attribute_hidden; +@@ -361,9 +362,9 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, + + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], + const Elf64_Rela *reloc, + const Elf64_Sym *sym, + const struct r_found_version *version, +@@ -411,7 +412,8 @@ elf_machine_rela (struct link_map *map, + return; + else + { +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + Elf64_Addr sym_value; + Elf64_Addr sym_raw_value; + +@@ -489,7 +491,7 @@ elf_machine_rela (struct link_map *map, + can be skipped. */ + #define ELF_MACHINE_REL_RELATIVE 1 + +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + void *const reloc_addr_arg) +@@ -506,9 +508,9 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + memcpy (reloc_addr_arg, &reloc_addr_val, 8); + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf64_Addr l_addr, const Elf64_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/arc/dl-machine.h b/sysdeps/arc/dl-machine.h +index e6ce7f0ff6d9ac34..4b64ffec256b7f3b 100644 +--- a/sysdeps/arc/dl-machine.h ++++ b/sysdeps/arc/dl-machine.h +@@ -122,7 +122,8 @@ elf_machine_load_address (void) + + static inline int + __attribute__ ((always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + extern void _dl_runtime_resolve (void); + +@@ -228,10 +229,11 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t, + + #ifdef RESOLVE_MAP + +-inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, +- const ElfW(Sym) *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const ElfW(Rela) *reloc, const ElfW(Sym) *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + ElfW(Addr) r_info = reloc->r_info; +@@ -245,7 +247,8 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + else + { + const ElfW(Sym) *const refsym = sym; +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true); + + switch (r_type) +@@ -326,8 +329,9 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + + inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr, +- const ElfW(Rela) *reloc, int skip_ifunc) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ++ ElfW(Addr) l_addr, const ElfW(Rela) *reloc, ++ int skip_ifunc) + { + ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info); +diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h +index ff5e09e207f7986b..7e6761bbe87540d5 100644 +--- a/sysdeps/arm/dl-machine.h ++++ b/sysdeps/arm/dl-machine.h +@@ -84,7 +84,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((unused)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + Elf32_Addr *got; + extern void _dl_runtime_resolve (Elf32_Word); +@@ -303,7 +304,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc, + + #ifdef RESOLVE_MAP + /* Handle a PC24 reloc, including the out-of-range case. */ +-auto void ++static void + relocate_pc24 (struct link_map *map, Elf32_Addr value, + Elf32_Addr *const reloc_addr, Elf32_Sword addend) + { +@@ -357,10 +358,11 @@ relocate_pc24 (struct link_map *map, Elf32_Addr value, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rel *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -391,7 +393,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, + #endif + { + const Elf32_Sym *const refsym = sym; +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); + + if (sym != NULL +@@ -535,10 +538,11 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, + } + + # ifndef RTLD_BOOTSTRAP +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rela *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -553,7 +557,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + # ifndef RESOLVE_CONFLICT_FIND_MAP + const Elf32_Sym *const refsym = sym; + # endif +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); + Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); + + if (sym != NULL +@@ -628,7 +632,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + # endif + +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc, + void *const reloc_addr_arg) +@@ -638,7 +642,7 @@ elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc, + } + + # ifndef RTLD_BOOTSTRAP +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) +@@ -648,9 +652,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + } + # endif + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rel *reloc, + int skip_ifunc) + { +@@ -680,7 +684,7 @@ elf_machine_lazy_rel (struct link_map *map, + + /* Always initialize TLS descriptors completely, because lazy + initialization requires synchronization at every TLS access. */ +- elf_machine_rel (map, reloc, sym, version, reloc_addr, skip_ifunc); ++ elf_machine_rel (map, scope, reloc, sym, version, reloc_addr, skip_ifunc); + } + else + _dl_reloc_bad_type (map, r_type, 1); +diff --git a/sysdeps/csky/dl-machine.h b/sysdeps/csky/dl-machine.h +index b08f06d74ca6f8d1..ec22f875772b1291 100644 +--- a/sysdeps/csky/dl-machine.h ++++ b/sysdeps/csky/dl-machine.h +@@ -58,7 +58,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + Elf32_Addr *got; + extern void _dl_runtime_resolve (Elf32_Word); +@@ -215,9 +216,10 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void __attribute__ ((unused, always_inline)) +-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++static inline void __attribute__ ((unused, always_inline)) ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rela *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -230,7 +232,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + else + { + const Elf32_Sym *const refsym = sym; +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true); + opcode16_addr = (unsigned short *)reloc_addr; + +@@ -331,7 +334,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + } + +-auto inline void __attribute__ ((unused, always_inline)) ++static inline void __attribute__ ((unused, always_inline)) + elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) + { +@@ -339,8 +342,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + *reloc_addr = l_addr + reloc->r_addend; + } + +-auto inline void __attribute__ ((unused, always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++static inline void __attribute__ ((unused, always_inline)) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h +index 24f0f47d8f1e25cd..088931f67065250c 100644 +--- a/sysdeps/hppa/dl-machine.h ++++ b/sysdeps/hppa/dl-machine.h +@@ -70,8 +70,8 @@ __hppa_init_bootstrap_fdesc_table (struct link_map *map) + map->l_mach.fptr_table = boot_table; + } + +-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \ +- __hppa_init_bootstrap_fdesc_table (BOOTSTRAP_MAP); \ ++#define ELF_MACHINE_BEFORE_RTLD_RELOC(map, dynamic_info) \ ++ __hppa_init_bootstrap_fdesc_table (map); \ + _dl_fptr_init(); + + /* Return nonzero iff ELF header is compatible with the running host. */ +@@ -182,7 +182,8 @@ elf_machine_main_map (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + Elf32_Addr *got = NULL; + Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type, r_sym; +@@ -564,8 +565,8 @@ dl_platform_init (void) + ( (((as14) & 0x1fff) << 1) \ + | (((as14) & 0x2000) >> 13)) + +-auto void __attribute__((always_inline)) +-elf_machine_rela (struct link_map *map, ++static void __attribute__((always_inline)) ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], + const Elf32_Rela *reloc, + const Elf32_Sym *sym, + const struct r_found_version *version, +@@ -594,11 +595,9 @@ elf_machine_rela (struct link_map *map, + zeros, and an all zero Elf32_Sym has a binding of STB_LOCAL.) + See RESOLVE_MAP definition in elf/dl-reloc.c */ + # ifdef RTLD_BOOTSTRAP +- /* RESOLVE_MAP in rtld.c doesn't have the local sym test. */ +- sym_map = (ELF32_ST_BIND (sym->st_info) != STB_LOCAL +- ? RESOLVE_MAP (&sym, version, r_type) : map); ++ sym_map = map; + # else +- sym_map = RESOLVE_MAP (&sym, version, r_type); ++ sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); + # endif + + if (sym_map) +@@ -756,7 +755,7 @@ elf_machine_rela (struct link_map *map, + + /* hppa doesn't have an R_PARISC_RELATIVE reloc, but uses relocs with + ELF32_R_SYM (info) == 0 for a similar purpose. */ +-auto void __attribute__((always_inline)) ++static void __attribute__((always_inline)) + elf_machine_rela_relative (Elf32_Addr l_addr, + const Elf32_Rela *reloc, + void *const reloc_addr_arg) +@@ -809,8 +808,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, + *reloc_addr = value; + } + +-auto void __attribute__((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++static void __attribute__((always_inline)) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h +index 590b41d8d7e35005..78ce890c0ff333ca 100644 +--- a/sysdeps/i386/dl-machine.h ++++ b/sysdeps/i386/dl-machine.h +@@ -61,7 +61,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((unused, always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + Elf32_Addr *got; + extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; +@@ -291,9 +292,10 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute ((always_inline)) +-elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, ++elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rel *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { +@@ -327,7 +329,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, + # ifndef RTLD_BOOTSTRAP + const Elf32_Sym *const refsym = sym; + # endif +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); + + if (sym != NULL +@@ -498,10 +501,11 @@ and creates an unsatisfiable circular dependency.\n", + } + + # ifndef RTLD_BOOTSTRAP +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rela *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -514,7 +518,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + # ifndef RESOLVE_CONFLICT_FIND_MAP + const Elf32_Sym *const refsym = sym; + # endif +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); + + if (sym != NULL +@@ -647,7 +652,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + # endif /* !RTLD_BOOTSTRAP */ + +-auto inline void ++static inline void + __attribute ((always_inline)) + elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc, + void *const reloc_addr_arg) +@@ -658,7 +663,7 @@ elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc, + } + + # ifndef RTLD_BOOTSTRAP +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) +@@ -668,9 +673,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + } + # endif /* !RTLD_BOOTSTRAP */ + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rel *reloc, + int skip_ifunc) + { +@@ -705,13 +710,13 @@ elf_machine_lazy_rel (struct link_map *map, + const ElfW(Half) *const version = + (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); + ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; +- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], ++ elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], + &map->l_versions[ndx], + (void *) (l_addr + r->r_offset), skip_ifunc); + } + # ifndef RTLD_BOOTSTRAP + else +- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, ++ elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, + (void *) (l_addr + r->r_offset), skip_ifunc); + # endif + } +@@ -728,9 +733,9 @@ elf_machine_lazy_rel (struct link_map *map, + + # ifndef RTLD_BOOTSTRAP + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rela (struct link_map *map, ++elf_machine_lazy_rela (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) + { +@@ -754,7 +759,8 @@ elf_machine_lazy_rela (struct link_map *map, + + /* Always initialize TLS descriptors completely at load time, in + case static TLS is allocated for it that requires locking. */ +- elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc); ++ elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, ++ skip_ifunc); + } + else if (__glibc_unlikely (r_type == R_386_IRELATIVE)) + { +diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h +index 4403e7767af83546..2217d0b556c17683 100644 +--- a/sysdeps/ia64/dl-machine.h ++++ b/sysdeps/ia64/dl-machine.h +@@ -44,8 +44,8 @@ __ia64_init_bootstrap_fdesc_table (struct link_map *map) + map->l_mach.fptr_table = boot_table; + } + +-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \ +- __ia64_init_bootstrap_fdesc_table (BOOTSTRAP_MAP); ++#define ELF_MACHINE_BEFORE_RTLD_RELOC(map, dynamic_info) \ ++ __ia64_init_bootstrap_fdesc_table (map); + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute__ ((unused)) +@@ -98,7 +98,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((unused, always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + extern void _dl_runtime_resolve (void); + extern void _dl_runtime_profile (void); +@@ -371,9 +372,9 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, + + /* Perform the relocation specified by RELOC and SYM (which is fully + resolved). MAP is the object containing the reloc. */ +-auto inline void ++static inline void + __attribute ((always_inline)) +-elf_machine_rela (struct link_map *map, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], + const Elf64_Rela *reloc, + const Elf64_Sym *sym, + const struct r_found_version *version, +@@ -414,10 +415,11 @@ elf_machine_rela (struct link_map *map, + return; + else + { +- struct link_map *sym_map; ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + + /* RESOLVE_MAP() will return NULL if it fail to locate the symbol. */ +- if ((sym_map = RESOLVE_MAP (&sym, version, r_type))) ++ if (sym_map != NULL) + { + value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend; + +@@ -476,7 +478,7 @@ elf_machine_rela (struct link_map *map, + can be skipped. */ + #define ELF_MACHINE_REL_RELATIVE 1 + +-auto inline void ++static inline void + __attribute ((always_inline)) + elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + void *const reloc_addr_arg) +@@ -489,9 +491,9 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + } + + /* Perform a RELATIVE reloc on the .got entry that transfers to the .plt. */ +-auto inline void ++static inline void + __attribute ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf64_Addr l_addr, const Elf64_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h +index 86a8c67e2a1b9f77..5e34c4784e348b19 100644 +--- a/sysdeps/m68k/dl-machine.h ++++ b/sysdeps/m68k/dl-machine.h +@@ -68,7 +68,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + Elf32_Addr *got; + extern void _dl_runtime_resolve (Elf32_Word); +@@ -215,9 +216,10 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void __attribute__ ((unused, always_inline)) +-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++static inline void __attribute__ ((unused, always_inline)) ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rela *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -228,7 +230,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + else + { + const Elf32_Sym *const refsym = sym; +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); + + switch (r_type) +@@ -303,7 +306,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + } + +-auto inline void __attribute__ ((unused, always_inline)) ++static inline void __attribute__ ((unused, always_inline)) + elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) + { +@@ -311,8 +314,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + *reloc_addr = l_addr + reloc->r_addend; + } + +-auto inline void __attribute__ ((unused, always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++static inline void __attribute__ ((unused, always_inline)) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h +index e460f6f195561da1..3fd4988e6093be1c 100644 +--- a/sysdeps/microblaze/dl-machine.h ++++ b/sysdeps/microblaze/dl-machine.h +@@ -69,7 +69,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + extern void _dl_runtime_resolve (Elf32_Word); + extern void _dl_runtime_profile (Elf32_Word); +@@ -207,9 +208,10 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + ((unsigned short *)(rel_addr))[3] = (val) & 0xffff; \ + } while (0) + +-auto inline void __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++static inline void __attribute__ ((always_inline)) ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rela *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -222,7 +224,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + else + { + const Elf32_Sym *const refsym = sym; +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); + + value += reloc->r_addend; +@@ -277,7 +280,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + } + +-auto inline void ++static inline void + elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) + { +@@ -285,8 +288,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + PUT_REL_64 (reloc_addr, l_addr + reloc->r_addend); + } + +-auto inline void +-elf_machine_lazy_rel (struct link_map *map, ++static inline void ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h +index d9c6d33d0cbf1f50..7a821ceb8e518cef 100644 +--- a/sysdeps/mips/dl-machine.h ++++ b/sysdeps/mips/dl-machine.h +@@ -188,9 +188,9 @@ elf_machine_load_address (void) + + /* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope + fiddles with global data. */ +-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \ ++#define ELF_MACHINE_BEFORE_RTLD_RELOC(bootstrap_map, dynamic_info) \ + do { \ +- struct link_map *map = BOOTSTRAP_MAP; \ ++ struct link_map *map = bootstrap_map; \ + ElfW(Sym) *sym; \ + ElfW(Addr) *got; \ + int i, n; \ +@@ -475,11 +475,12 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rel) *reloc, + by RELOC_ADDR. SYM is the relocation symbol specified by R_INFO and + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info, +- const ElfW(Sym) *sym, const struct r_found_version *version, +- void *reloc_addr, ElfW(Addr) r_addend, int inplace_p) ++elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[], ++ ElfW(Addr) r_info, const ElfW(Sym) *sym, ++ const struct r_found_version *version, void *reloc_addr, ++ ElfW(Addr) r_addend, int inplace_p) + { + const unsigned long int r_type = ELFW(R_TYPE) (r_info); + ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr; +@@ -507,7 +508,8 @@ elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info, + case R_MIPS_TLS_TPREL32: + # endif + { +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + + switch (r_type) + { +@@ -647,7 +649,7 @@ elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info, + _dl_signal_error (0, map->l_name, NULL, + "found jump slot relocation with non-zero addend"); + +- sym_map = RESOLVE_MAP (&sym, version, r_type); ++ sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); + value = SYMBOL_ADDRESS (sym_map, sym, true); + *addr_field = value; + +@@ -661,7 +663,7 @@ elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info, + ElfW(Addr) value; + + /* Calculate the address of the symbol. */ +- sym_map = RESOLVE_MAP (&sym, version, r_type); ++ sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); + value = SYMBOL_ADDRESS (sym_map, sym, true); + + if (__builtin_expect (sym == NULL, 0)) +@@ -708,16 +710,17 @@ elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc, +- const ElfW(Sym) *sym, const struct r_found_version *version, +- void *const reloc_addr, int skip_ifunc) ++elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[], ++ const ElfW(Rel) *reloc, const ElfW(Sym) *sym, ++ const struct r_found_version *version, void *const reloc_addr, ++ int skip_ifunc) + { +- elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr, 0, 1); ++ elf_machine_reloc (map, scope, reloc->r_info, sym, version, reloc_addr, 0, 1); + } + +-auto inline void ++static inline void + __attribute__((always_inline)) + elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc, + void *const reloc_addr) +@@ -725,9 +728,9 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc, + /* XXX Nothing to do. There is no relative relocation, right? */ + } + +-auto inline void ++static inline void + __attribute__((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + ElfW(Addr) l_addr, const ElfW(Rel) *reloc, + int skip_ifunc) + { +@@ -748,17 +751,17 @@ elf_machine_lazy_rel (struct link_map *map, + _dl_reloc_bad_type (map, r_type, 1); + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], const ElfW(Rela) *reloc, + const ElfW(Sym) *sym, const struct r_found_version *version, + void *const reloc_addr, int skip_ifunc) + { +- elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr, ++ elf_machine_reloc (map, scope, reloc->r_info, sym, version, reloc_addr, + reloc->r_addend, 0); + } + +-auto inline void ++static inline void + __attribute__((always_inline)) + elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + void *const reloc_addr) +@@ -767,9 +770,9 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + + #ifndef RTLD_BOOTSTRAP + /* Relocate GOT. */ +-auto inline void ++static inline void + __attribute__((always_inline)) +-elf_machine_got_rel (struct link_map *map, int lazy) ++elf_machine_got_rel (struct link_map *map, struct r_scope_elem *scope[], int lazy) + { + ElfW(Addr) *got; + ElfW(Sym) *sym; +@@ -782,7 +785,7 @@ elf_machine_got_rel (struct link_map *map, int lazy) + const struct r_found_version *version __attribute__ ((unused)) \ + = vernum ? &map->l_versions[vernum[sym_index] & 0x7fff] : NULL; \ + struct link_map *sym_map; \ +- sym_map = RESOLVE_MAP (&ref, version, reloc); \ ++ sym_map = RESOLVE_MAP (map, scope, &ref, version, reloc); \ + SYMBOL_ADDRESS (sym_map, ref, true); \ + }) + +@@ -868,9 +871,10 @@ elf_machine_got_rel (struct link_map *map, int lazy) + /* Set up the loaded object described by L so its stub function + will jump to the on-demand fixup code __dl_runtime_resolve. */ + +-auto inline int ++static inline int + __attribute__((always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + # ifndef RTLD_BOOTSTRAP + ElfW(Addr) *got; +@@ -900,7 +904,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + } + + /* Relocate global offset table. */ +- elf_machine_got_rel (l, lazy); ++ elf_machine_got_rel (l, scope, lazy); + + /* If using PLTs, fill in the first two entries of .got.plt. */ + if (l->l_info[DT_JMPREL] && lazy) +diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h +index e000cd081f18a12b..4de602b13d5500f6 100644 +--- a/sysdeps/nios2/dl-machine.h ++++ b/sysdeps/nios2/dl-machine.h +@@ -67,7 +67,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + extern void _dl_runtime_resolve (Elf32_Word); + +@@ -234,10 +235,11 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + LOADADDR is the load address of the object; INFO is an array indexed + by DT_* of the .dynamic section info. */ + +-auto inline void __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, +- const ElfW(Sym) *sym, const struct r_found_version *version, +- void *const reloc_addr_arg, int skip_ifunc) ++static inline void __attribute__ ((always_inline)) ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const ElfW(Rela) *reloc, const ElfW(Sym) *sym, ++ const struct r_found_version *version, ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +@@ -249,7 +251,8 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + else + { + const Elf32_Sym *const refsym = sym; +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); + + switch (r_type) +@@ -314,7 +317,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + } + } + +-auto inline void __attribute__((always_inline)) ++static inline void __attribute__((always_inline)) + elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + void *const reloc_addr_arg) + { +@@ -322,8 +325,8 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + *reloc_addr = l_addr + reloc->r_addend; + } + +-auto inline void __attribute__((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++static inline void __attribute__((always_inline)) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h +index b93cf486b6cda5fd..cda012dc1b822254 100644 +--- a/sysdeps/powerpc/powerpc32/dl-machine.h ++++ b/sysdeps/powerpc/powerpc32/dl-machine.h +@@ -170,7 +170,7 @@ extern int __elf_machine_runtime_setup (struct link_map *map, + int lazy, int profile); + + static inline int +-elf_machine_runtime_setup (struct link_map *map, ++elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[], + int lazy, int profile) + { + if (map->l_info[DT_JMPREL] == 0) +@@ -284,9 +284,10 @@ extern void _dl_reloc_overflow (struct link_map *map, + LOADADDR is the load address of the object; INFO is an array indexed + by DT_* of the .dynamic section info. */ + +-auto inline void __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++static inline void __attribute__ ((always_inline)) ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rela *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -315,7 +316,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + else + { +- sym_map = RESOLVE_MAP (&sym, version, r_type); ++ sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); + value = SYMBOL_ADDRESS (sym_map, sym, true); + } + value += reloc->r_addend; +@@ -439,7 +440,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + } + +-auto inline void __attribute__ ((always_inline)) ++static inline void __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) + { +@@ -447,8 +448,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + *reloc_addr = l_addr + reloc->r_addend; + } + +-auto inline void __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++static inline void __attribute__ ((always_inline)) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h +index b3f3352bcf5a52b0..3f92fbb369eb5023 100644 +--- a/sysdeps/powerpc/powerpc64/dl-machine.h ++++ b/sysdeps/powerpc/powerpc64/dl-machine.h +@@ -343,7 +343,8 @@ dl_platform_init (void) + /* Set up the loaded object described by MAP so its unrelocated PLT + entries will jump to the on-demand fixup code in dl-runtime.c. */ + static inline int __attribute__ ((always_inline)) +-elf_machine_runtime_setup (struct link_map *map, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + if (map->l_info[DT_JMPREL]) + { +@@ -618,7 +619,7 @@ extern void attribute_hidden _dl_reloc_overflow (struct link_map *map, + Elf64_Addr *const reloc_addr, + const Elf64_Sym *refsym); + +-auto inline void __attribute__ ((always_inline)) ++static inline void __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + void *const reloc_addr_arg) + { +@@ -627,7 +628,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + } + + /* This computes the value used by TPREL* relocs. */ +-auto inline Elf64_Addr __attribute__ ((always_inline, const)) ++static inline Elf64_Addr __attribute__ ((always_inline, const)) + elf_machine_tprel (struct link_map *map, + struct link_map *sym_map, + const Elf64_Sym *sym, +@@ -646,7 +647,7 @@ elf_machine_tprel (struct link_map *map, + } + + /* Call function at address VALUE (an OPD entry) to resolve ifunc relocs. */ +-auto inline Elf64_Addr __attribute__ ((always_inline)) ++static inline Elf64_Addr __attribute__ ((always_inline)) + resolve_ifunc (Elf64_Addr value, + const struct link_map *map, const struct link_map *sym_map) + { +@@ -676,8 +677,8 @@ resolve_ifunc (Elf64_Addr value, + + /* Perform the relocation specified by RELOC and SYM (which is fully + resolved). MAP is the object containing the reloc. */ +-auto inline void __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, ++static inline void __attribute__ ((always_inline)) ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], + const Elf64_Rela *reloc, + const Elf64_Sym *sym, + const struct r_found_version *version, +@@ -705,7 +706,7 @@ elf_machine_rela (struct link_map *map, + + /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt + and STT_GNU_IFUNC. */ +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); + Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend; + + if (sym != NULL +@@ -1035,8 +1036,8 @@ elf_machine_rela (struct link_map *map, + MODIFIED_CODE_NOQUEUE (reloc_addr); + } + +-auto inline void __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++static inline void __attribute__ ((always_inline)) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf64_Addr l_addr, const Elf64_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h +index 951268923da26a37..343c0feb6b437001 100644 +--- a/sysdeps/riscv/dl-machine.h ++++ b/sysdeps/riscv/dl-machine.h +@@ -168,17 +168,18 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t, + by RELOC_ADDR. SYM is the relocation symbol specified by R_INFO and + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, +- const ElfW(Sym) *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const ElfW(Rela) *reloc, const ElfW(Sym) *sym, ++ const struct r_found_version *version, + void *const reloc_addr, int skip_ifunc) + { + ElfW(Addr) r_info = reloc->r_info; + const unsigned long int r_type = ELFW (R_TYPE) (r_info); + ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr; + const ElfW(Sym) *const __attribute__ ((unused)) refsym = sym; +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); + ElfW(Addr) value = 0; + if (sym_map != NULL) + value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend; +@@ -286,7 +287,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + } + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + void *const reloc_addr) +@@ -294,10 +295,11 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + *(ElfW(Addr) *) reloc_addr = l_addr + reloc->r_addend; + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr, +- const ElfW(Rela) *reloc, int skip_ifunc) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ++ ElfW(Addr) l_addr, const ElfW(Rela) *reloc, ++ int skip_ifunc) + { + ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info); +@@ -327,9 +329,10 @@ elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr, + /* Set up the loaded object described by L so its stub function + will jump to the on-demand fixup code __dl_runtime_resolve. */ + +-auto inline int ++static inline int + __attribute__ ((always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + #ifndef RTLD_BOOTSTRAP + /* If using PLTs, fill in the first two entries of .got.plt. */ +diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h +index d0ccd69261c8f55b..96a5e80c846c816a 100644 +--- a/sysdeps/s390/s390-32/dl-machine.h ++++ b/sysdeps/s390/s390-32/dl-machine.h +@@ -85,7 +85,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((unused)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + extern void _dl_runtime_resolve (Elf32_Word); + extern void _dl_runtime_profile (Elf32_Word); +@@ -321,10 +322,11 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rela *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -357,7 +359,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + /* Only needed for R_390_COPY below. */ + const Elf32_Sym *const refsym = sym; + #endif +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); + + if (sym != NULL +@@ -484,7 +487,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) +@@ -493,9 +496,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + *reloc_addr = l_addr + reloc->r_addend; + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h +index 543361c83637c071..c94d09b9c8512738 100644 +--- a/sysdeps/s390/s390-64/dl-machine.h ++++ b/sysdeps/s390/s390-64/dl-machine.h +@@ -75,7 +75,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((unused)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + extern void _dl_runtime_resolve (Elf64_Word); + extern void _dl_runtime_profile (Elf64_Word); +@@ -268,10 +269,11 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, +- const Elf64_Sym *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf64_Rela *reloc, const Elf64_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf64_Addr *const reloc_addr = reloc_addr_arg; +@@ -304,7 +306,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + /* Only needed for R_390_COPY below. */ + const Elf64_Sym *const refsym = sym; + #endif +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); + + if (sym != NULL +@@ -438,7 +441,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + } + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + void *const reloc_addr_arg) +@@ -447,9 +450,9 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + *reloc_addr = l_addr + reloc->r_addend; + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf64_Addr l_addr, const Elf64_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h +index 122b417a17e2ef9b..0c22dfd8487a516e 100644 +--- a/sysdeps/sh/dl-machine.h ++++ b/sysdeps/sh/dl-machine.h +@@ -69,7 +69,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((unused, always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + Elf32_Addr *got; + extern void _dl_runtime_resolve (Elf32_Word); +@@ -259,10 +260,11 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute ((always_inline)) +-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rela *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -318,7 +320,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + else + { + const Elf32_Sym *const refsym = sym; +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + + value = SYMBOL_ADDRESS (sym_map, sym, true); + value += reloc->r_addend; +@@ -424,7 +427,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) +@@ -443,9 +446,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + #undef COPY_UNALIGNED_WORD + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h +index 0269e458ea2b3bca..6361cfae9eb8fa58 100644 +--- a/sysdeps/sparc/sparc32/dl-machine.h ++++ b/sysdeps/sparc/sparc32/dl-machine.h +@@ -97,7 +97,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + Elf32_Addr *plt; + extern void _dl_runtime_resolve (Elf32_Word); +@@ -327,10 +328,11 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, +- const Elf32_Sym *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf32_Rela *reloc, const Elf32_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; +@@ -381,7 +383,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + else + { +- sym_map = RESOLVE_MAP (&sym, version, r_type); ++ sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); + value = SYMBOL_ADDRESS (sym_map, sym, true); + } + #else +@@ -536,7 +538,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + } + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) +@@ -545,9 +547,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + *reloc_addr += l_addr + reloc->r_addend; + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h +index bbd4566d8a595f93..3fd18c6e5ef21e38 100644 +--- a/sysdeps/sparc/sparc64/dl-machine.h ++++ b/sysdeps/sparc/sparc64/dl-machine.h +@@ -126,7 +126,8 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + if (l->l_info[DT_JMPREL] && lazy) + { +@@ -354,10 +355,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, +- const Elf64_Sym *sym, const struct r_found_version *version, ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf64_Rela *reloc, const Elf64_Sym *sym, ++ const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) + { + Elf64_Addr *const reloc_addr = reloc_addr_arg; +@@ -408,7 +410,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + } + else + { +- sym_map = RESOLVE_MAP (&sym, version, r_type); ++ sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); + value = SYMBOL_ADDRESS (sym_map, sym, true); + } + #else +@@ -646,7 +648,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + } + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + void *const reloc_addr_arg) +@@ -655,9 +657,9 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + *reloc_addr = l_addr + reloc->r_addend; + } + +-auto inline void ++static inline void + __attribute__ ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + Elf64_Addr l_addr, const Elf64_Rela *reloc, + int skip_ifunc) + { +diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h +index a8596aa3fa489eff..d3fcbb37bf1f4f7c 100644 +--- a/sysdeps/x86_64/dl-machine.h ++++ b/sysdeps/x86_64/dl-machine.h +@@ -62,7 +62,8 @@ elf_machine_load_address (void) + entries will jump to the on-demand fixup code in dl-runtime.c. */ + + static inline int __attribute__ ((unused, always_inline)) +-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ++ int lazy, int profile) + { + Elf64_Addr *got; + extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden; +@@ -258,12 +259,11 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc, + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +-auto inline void +-__attribute__ ((always_inline)) +-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, +- const ElfW(Sym) *sym, const struct r_found_version *version, +- void *const reloc_addr_arg, int skip_ifunc) +-{ ++static inline void __attribute__((always_inline)) ++elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[], ++ const ElfW(Rela) *reloc, const ElfW(Sym) *sym, ++ const struct r_found_version *version, ++ void *const reloc_addr_arg, int skip_ifunc) { + ElfW(Addr) *const reloc_addr = reloc_addr_arg; + const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); + +@@ -300,7 +300,8 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + # ifndef RTLD_BOOTSTRAP + const ElfW(Sym) *const refsym = sym; + # endif +- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, ++ r_type); + ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true); + + if (sym != NULL +@@ -525,7 +526,7 @@ and creates an unsatisfiable circular dependency.\n", + } + } + +-auto inline void ++static inline void + __attribute ((always_inline)) + elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + void *const reloc_addr_arg) +@@ -544,9 +545,9 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + } + } + +-auto inline void ++static inline void + __attribute ((always_inline)) +-elf_machine_lazy_rel (struct link_map *map, ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + int skip_ifunc) + { +@@ -580,7 +581,7 @@ elf_machine_lazy_rel (struct link_map *map, + + /* Always initialize TLS descriptors completely at load time, in + case static TLS is allocated for it that requires locking. */ +- elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc); ++ elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, skip_ifunc); + } + else if (__glibc_unlikely (r_type == R_X86_64_IRELATIVE)) + { diff --git a/SOURCES/glibc-upstream-2.34-137.patch b/SOURCES/glibc-upstream-2.34-137.patch new file mode 100644 index 0000000..06aaa91 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-137.patch @@ -0,0 +1,241 @@ +commit c6df39a0bd2aafd2a4280a0000ef201f30273bee +Author: Adhemerval Zanella +Date: Mon Oct 11 16:01:49 2021 -0300 + + elf: Fix elf_get_dynamic_info definition + + Before to 490e6c62aa31a8a ('elf: Avoid nested functions in the loader + [BZ #27220]'), elf_get_dynamic_info() was defined twice on rtld.c: on + the first dynamic-link.h include and later within _dl_start(). The + former definition did not define DONT_USE_BOOTSTRAP_MAP and it is used + on setup_vdso() (since it is a global definition), while the former does + define DONT_USE_BOOTSTRAP_MAP and it is used on loader self-relocation. + + With the commit change, the function is now included and defined once + instead of defined as a nested function. So rtld.c defines without + defining RTLD_BOOTSTRAP and it brokes at least powerpc32. + + This patch fixes by moving the get-dynamic-info.h include out of + dynamic-link.h, which then the caller can corirectly set the expected + semantic by defining STATIC_PIE_BOOTSTRAP, RTLD_BOOTSTRAP, and/or + RESOLVE_MAP. + + It also required to enable some asserts only for the loader bootstrap + to avoid issues when called from setup_vdso(). + + As a side note, this is another issues with nested functions: it is + not clear from pre-processed output (-E -dD) how the function will + be build and its semantic (since nested function will be local and + extra C defines may change it). + + I checked on x86_64-linux-gnu (w/o --enable-static-pie), + i686-linux-gnu, powerpc64-linux-gnu, powerpc-linux-gnu-power4, + aarch64-linux-gnu, arm-linux-gnu, sparc64-linux-gnu, and + s390x-linux-gnu. + + Reviewed-by: Fangrui Song + (cherry picked from commit 4af6982e4c9fc465ffb7a54b794aaaa134241f05) + + Resolved conflicts: + elf/rtld.c + +diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c +index 5c8e51d19ae095d6..d54356dee3f86ae0 100644 +--- a/elf/dl-conflict.c ++++ b/elf/dl-conflict.c +@@ -17,6 +17,7 @@ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see . */ + ++#include + #include + #include + #include +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 0976977fbdf21902..eea06629a978aaf3 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -58,6 +58,7 @@ struct filebuf + }; + + #include "dynamic-link.h" ++#include "get-dynamic-info.h" + #include + #include + #include +@@ -1295,7 +1296,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + if (l->l_ld != 0) + l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr); + +- elf_get_dynamic_info (l); ++ elf_get_dynamic_info (l, false); + + /* Make sure we are not dlopen'ing an object that has the + DF_1_NOOPEN flag set, or a PIE object. */ +diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c +index a52ba8aeb8b573cb..f323b4dd0d5ba279 100644 +--- a/elf/dl-reloc-static-pie.c ++++ b/elf/dl-reloc-static-pie.c +@@ -28,6 +28,7 @@ + #define STATIC_PIE_BOOTSTRAP + #define RESOLVE_MAP(map, scope, sym, version, flags) map + #include "dynamic-link.h" ++#include "get-dynamic-info.h" + + /* Relocate static executable with PIE. */ + +@@ -51,7 +52,7 @@ _dl_relocate_static_pie (void) + break; + } + +- elf_get_dynamic_info (main_map); ++ elf_get_dynamic_info (main_map, false); + + # ifdef ELF_MACHINE_BEFORE_RTLD_RELOC + ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info); +diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c +index 9d0d941000f6114f..61c260ddb81b586c 100644 +--- a/elf/dl-runtime.c ++++ b/elf/dl-runtime.c +@@ -19,6 +19,7 @@ + #define IN_DL_RUNTIME 1 /* This can be tested in dl-machine.h. */ + + #include ++#include + #include + #include + #include +diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h +index 7cc30211649d3820..21cdfc88bbfb89ea 100644 +--- a/elf/dynamic-link.h ++++ b/elf/dynamic-link.h +@@ -93,7 +93,6 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + + #include + +-#include "get-dynamic-info.h" + + #ifdef RESOLVE_MAP + +diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h +index 15c316b38c05a90c..d169099fbc9897cf 100644 +--- a/elf/get-dynamic-info.h ++++ b/elf/get-dynamic-info.h +@@ -25,7 +25,7 @@ + #include + + static inline void __attribute__ ((unused, always_inline)) +-elf_get_dynamic_info (struct link_map *l) ++elf_get_dynamic_info (struct link_map *l, bool check) + { + #if __ELF_NATIVE_CLASS == 32 + typedef Elf32_Word d_tag_utype; +@@ -112,16 +112,19 @@ elf_get_dynamic_info (struct link_map *l) + assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); + #endif + #ifdef RTLD_BOOTSTRAP +- /* Only the bind now flags are allowed. */ +- assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL +- || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0); +- /* Flags must not be set for ld.so. */ +- assert (info[DT_FLAGS] == NULL +- || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0); +-#endif +-#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP +- assert (info[DT_RUNPATH] == NULL); +- assert (info[DT_RPATH] == NULL); ++ if (check) ++ { ++ /* Only the bind now flags are allowed. */ ++ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL ++ || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0); ++ /* Flags must not be set for ld.so. */ ++ assert (info[DT_FLAGS] == NULL ++ || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0); ++# ifdef STATIC_PIE_BOOTSTRAP ++ assert (info[DT_RUNPATH] == NULL); ++ assert (info[DT_RPATH] == NULL); ++# endif ++ } + #else + if (info[DT_FLAGS] != NULL) + { +diff --git a/elf/rtld.c b/elf/rtld.c +index ee45657aeac14f3c..352d596dedb42e79 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -514,6 +514,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) + is trivial: always the map of ld.so itself. */ + #define RTLD_BOOTSTRAP + #define RESOLVE_MAP(map, scope, sym, version, flags) map ++#include "get-dynamic-info.h" + #include "dynamic-link.h" + + static ElfW(Addr) __attribute_used__ +@@ -549,7 +550,7 @@ _dl_start (void *arg) + /* Read our own dynamic section and fill in the info array. */ + bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); + bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION; +- elf_get_dynamic_info (&bootstrap_map); ++ elf_get_dynamic_info (&bootstrap_map, true); + + #if NO_TLS_OFFSET != 0 + bootstrap_map.l_tls_offset = NO_TLS_OFFSET; +@@ -1653,7 +1654,7 @@ dl_main (const ElfW(Phdr) *phdr, + if (! rtld_is_main) + { + /* Extract the contents of the dynamic section for easy access. */ +- elf_get_dynamic_info (main_map); ++ elf_get_dynamic_info (main_map, false); + + /* If the main map is libc.so, update the base namespace to + refer to this map. If libc.so is loaded later, this happens +diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h +index f44748bc9858e5fd..6fdffafcca5e9916 100644 +--- a/elf/setup-vdso.h ++++ b/elf/setup-vdso.h +@@ -64,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)), + l->l_map_end += l->l_addr; + l->l_text_end += l->l_addr; + l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr); +- elf_get_dynamic_info (l); ++ elf_get_dynamic_info (l, false); + _dl_setup_hash (l); + l->l_relocated = 1; + +diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h +index 7e6761bbe87540d5..86f866ca7c17bd9b 100644 +--- a/sysdeps/arm/dl-machine.h ++++ b/sysdeps/arm/dl-machine.h +@@ -21,6 +21,7 @@ + + #define ELF_MACHINE_NAME "ARM" + ++#include + #include + #include + #include +diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h +index 78ce890c0ff333ca..fa902612ca8557f9 100644 +--- a/sysdeps/i386/dl-machine.h ++++ b/sysdeps/i386/dl-machine.h +@@ -21,6 +21,7 @@ + + #define ELF_MACHINE_NAME "i386" + ++#include + #include + #include + #include +diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h +index d3fcbb37bf1f4f7c..90c77cfea1de8d63 100644 +--- a/sysdeps/x86_64/dl-machine.h ++++ b/sysdeps/x86_64/dl-machine.h +@@ -22,6 +22,7 @@ + + #define ELF_MACHINE_NAME "x86_64" + ++#include + #include + #include + #include diff --git a/SOURCES/glibc-upstream-2.34-138.patch b/SOURCES/glibc-upstream-2.34-138.patch new file mode 100644 index 0000000..778ada9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-138.patch @@ -0,0 +1,1115 @@ +commit b868b45f6763a4adc4aa93248be9f84480768fcf +Author: Adhemerval Zanella +Date: Wed Oct 13 09:49:34 2021 -0300 + + elf: Fix dynamic-link.h usage on rtld.c + + The 4af6982e4c fix does not fully handle RTLD_BOOTSTRAP usage on + rtld.c due two issues: + + 1. RTLD_BOOTSTRAP is also used on dl-machine.h on various + architectures and it changes the semantics of various machine + relocation functions. + + 2. The elf_get_dynamic_info() change was done sideways, previously + to 490e6c62aa get-dynamic-info.h was included by the first + dynamic-link.h include *without* RTLD_BOOTSTRAP being defined. + It means that the code within elf_get_dynamic_info() that uses + RTLD_BOOTSTRAP is in fact unused. + + To fix 1. this patch now includes dynamic-link.h only once with + RTLD_BOOTSTRAP defined. The ELF_DYNAMIC_RELOCATE call will now have + the relocation fnctions with the expected semantics for the loader. + + And to fix 2. part of 4af6982e4c is reverted (the check argument + elf_get_dynamic_info() is not required) and the RTLD_BOOTSTRAP + pieces are removed. + + To reorganize the includes the static TLS definition is moved to + its own header to avoid a circular dependency (it is defined on + dynamic-link.h and dl-machine.h requires it at same time other + dynamic-link.h definition requires dl-machine.h defitions). + + Also ELF_MACHINE_NO_REL, ELF_MACHINE_NO_RELA, and ELF_MACHINE_PLT_REL + are moved to its own header. Only ancient ABIs need special values + (arm, i386, and mips), so a generic one is used as default. + + The powerpc Elf64_FuncDesc is also moved to its own header, since + csu code required its definition (which would require either include + elf/ folder or add a full path with elf/). + + Checked on x86_64, i686, aarch64, armhf, powerpc64, powerpc32, + and powerpc64le. + + Reviewed-by: Szabolcs Nagy + (cherry picked from commit d6d89608ac8cf2b37c75debad1fff653f6939f90) + + Resolved conflicts: + elf/rtld.c + +Conflicts: + elf/rtld.c - Manual merge around dl-execve.h include. + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index eea06629a978aaf3..fb3da5aa565908a6 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1296,7 +1296,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + if (l->l_ld != 0) + l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr); + +- elf_get_dynamic_info (l, false); ++ elf_get_dynamic_info (l); + + /* Make sure we are not dlopen'ing an object that has the + DF_1_NOOPEN flag set, or a PIE object. */ +diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c +index f323b4dd0d5ba279..ababafcf98f9945d 100644 +--- a/elf/dl-reloc-static-pie.c ++++ b/elf/dl-reloc-static-pie.c +@@ -52,7 +52,7 @@ _dl_relocate_static_pie (void) + break; + } + +- elf_get_dynamic_info (main_map, false); ++ elf_get_dynamic_info (main_map); + + # ifdef ELF_MACHINE_BEFORE_RTLD_RELOC + ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info); +diff --git a/elf/dl-static-tls.h b/elf/dl-static-tls.h +new file mode 100644 +index 0000000000000000..730924fc0155acb7 +--- /dev/null ++++ b/elf/dl-static-tls.h +@@ -0,0 +1,51 @@ ++/* Inline functions for dynamic linking. ++ Copyright (C) 1995-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_STATIC_TLS_H ++#define _DL_STATIC_TLS_H ++ ++/* This macro is used as a callback from elf_machine_rel{a,} when a ++ static TLS reloc is about to be performed. Since (in dl-load.c) we ++ permit dynamic loading of objects that might use such relocs, we ++ have to check whether each use is actually doable. If the object ++ whose TLS segment the reference resolves to was allocated space in ++ the static TLS block at startup, then it's ok. Otherwise, we make ++ an attempt to allocate it in surplus space on the fly. If that ++ can't be done, we fall back to the error that DF_STATIC_TLS is ++ intended to produce. */ ++#define HAVE_STATIC_TLS(map, sym_map) \ ++ (__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET \ ++ && ((sym_map)->l_tls_offset \ ++ != FORCED_DYNAMIC_TLS_OFFSET), 1)) ++ ++#define CHECK_STATIC_TLS(map, sym_map) \ ++ do { \ ++ if (!HAVE_STATIC_TLS (map, sym_map)) \ ++ _dl_allocate_static_tls (sym_map); \ ++ } while (0) ++ ++#define TRY_STATIC_TLS(map, sym_map) \ ++ (__builtin_expect ((sym_map)->l_tls_offset \ ++ != FORCED_DYNAMIC_TLS_OFFSET, 1) \ ++ && (__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET, 1) \ ++ || _dl_try_allocate_static_tls (sym_map, true) == 0)) ++ ++int _dl_try_allocate_static_tls (struct link_map *map, bool optional) ++ attribute_hidden; ++ ++#endif +diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h +index 21cdfc88bbfb89ea..ac4cc70dea3da763 100644 +--- a/elf/dynamic-link.h ++++ b/elf/dynamic-link.h +@@ -16,35 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-/* This macro is used as a callback from elf_machine_rel{a,} when a +- static TLS reloc is about to be performed. Since (in dl-load.c) we +- permit dynamic loading of objects that might use such relocs, we +- have to check whether each use is actually doable. If the object +- whose TLS segment the reference resolves to was allocated space in +- the static TLS block at startup, then it's ok. Otherwise, we make +- an attempt to allocate it in surplus space on the fly. If that +- can't be done, we fall back to the error that DF_STATIC_TLS is +- intended to produce. */ +-#define HAVE_STATIC_TLS(map, sym_map) \ +- (__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET \ +- && ((sym_map)->l_tls_offset \ +- != FORCED_DYNAMIC_TLS_OFFSET), 1)) +- +-#define CHECK_STATIC_TLS(map, sym_map) \ +- do { \ +- if (!HAVE_STATIC_TLS (map, sym_map)) \ +- _dl_allocate_static_tls (sym_map); \ +- } while (0) +- +-#define TRY_STATIC_TLS(map, sym_map) \ +- (__builtin_expect ((sym_map)->l_tls_offset \ +- != FORCED_DYNAMIC_TLS_OFFSET, 1) \ +- && (__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET, 1) \ +- || _dl_try_allocate_static_tls (sym_map, true) == 0)) +- +-int _dl_try_allocate_static_tls (struct link_map *map, bool optional) +- attribute_hidden; +- ++#include + #include + + #ifdef RESOLVE_MAP +@@ -91,9 +63,6 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + # endif + #endif + +-#include +- +- + #ifdef RESOLVE_MAP + + # if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP +diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h +index d169099fbc9897cf..1ac0663d1ff5de24 100644 +--- a/elf/get-dynamic-info.h ++++ b/elf/get-dynamic-info.h +@@ -22,10 +22,11 @@ + #define _GET_DYNAMIC_INFO_H + + #include ++#include + #include + + static inline void __attribute__ ((unused, always_inline)) +-elf_get_dynamic_info (struct link_map *l, bool check) ++elf_get_dynamic_info (struct link_map *l) + { + #if __ELF_NATIVE_CLASS == 32 + typedef Elf32_Word d_tag_utype; +@@ -33,7 +34,7 @@ elf_get_dynamic_info (struct link_map *l, bool check) + typedef Elf64_Xword d_tag_utype; + #endif + +-#if !defined RTLD_BOOTSTRAP && !defined STATIC_PIE_BOOTSTRAP ++#ifndef STATIC_PIE_BOOTSTRAP + if (l->l_ld == NULL) + return; + #endif +@@ -111,21 +112,10 @@ elf_get_dynamic_info (struct link_map *l, bool check) + if (info[DT_REL] != NULL) + assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); + #endif +-#ifdef RTLD_BOOTSTRAP +- if (check) +- { +- /* Only the bind now flags are allowed. */ +- assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL +- || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0); +- /* Flags must not be set for ld.so. */ +- assert (info[DT_FLAGS] == NULL +- || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0); +-# ifdef STATIC_PIE_BOOTSTRAP +- assert (info[DT_RUNPATH] == NULL); +- assert (info[DT_RPATH] == NULL); +-# endif +- } +-#else ++#ifdef STATIC_PIE_BOOTSTRAP ++ assert (info[DT_RUNPATH] == NULL); ++ assert (info[DT_RPATH] == NULL); ++#endif + if (info[DT_FLAGS] != NULL) + { + /* Flags are used. Translate to the old form where available. +@@ -163,7 +153,6 @@ elf_get_dynamic_info (struct link_map *l, bool check) + if (info[DT_RUNPATH] != NULL) + /* If both RUNPATH and RPATH are given, the latter is ignored. */ + info[DT_RPATH] = NULL; +-#endif + } + + #endif +diff --git a/elf/rtld.c b/elf/rtld.c +index 352d596dedb42e79..37d28d5a66d7b5d6 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -32,7 +32,6 @@ + #include + #include + #include +-#include "dynamic-link.h" + #include + #include + #include +@@ -51,9 +50,18 @@ + #include + #include + #include ++#include + + #include + ++/* This #define produces dynamic linking inline functions for ++ bootstrap relocation instead of general-purpose relocation. ++ Since ld.so must not have any undefined symbols the result ++ is trivial: always the map of ld.so itself. */ ++#define RTLD_BOOTSTRAP ++#define RESOLVE_MAP(map, scope, sym, version, flags) map ++#include "dynamic-link.h" ++ + /* Only enables rtld profiling for architectures which provides non generic + hp-timing support. The generic support requires either syscall + (clock_gettime), which will incur in extra overhead on loading time. +@@ -508,15 +516,6 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) + # define bootstrap_map info.l + #endif + +- /* This #define produces dynamic linking inline functions for +- bootstrap relocation instead of general-purpose relocation. +- Since ld.so must not have any undefined symbols the result +- is trivial: always the map of ld.so itself. */ +-#define RTLD_BOOTSTRAP +-#define RESOLVE_MAP(map, scope, sym, version, flags) map +-#include "get-dynamic-info.h" +-#include "dynamic-link.h" +- + static ElfW(Addr) __attribute_used__ + _dl_start (void *arg) + { +@@ -550,7 +549,7 @@ _dl_start (void *arg) + /* Read our own dynamic section and fill in the info array. */ + bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); + bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION; +- elf_get_dynamic_info (&bootstrap_map, true); ++ elf_get_dynamic_info (&bootstrap_map); + + #if NO_TLS_OFFSET != 0 + bootstrap_map.l_tls_offset = NO_TLS_OFFSET; +@@ -1654,7 +1653,7 @@ dl_main (const ElfW(Phdr) *phdr, + if (! rtld_is_main) + { + /* Extract the contents of the dynamic section for easy access. */ +- elf_get_dynamic_info (main_map, false); ++ elf_get_dynamic_info (main_map); + + /* If the main map is libc.so, update the base namespace to + refer to this map. If libc.so is loaded later, this happens +diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h +index 6fdffafcca5e9916..f44748bc9858e5fd 100644 +--- a/elf/setup-vdso.h ++++ b/elf/setup-vdso.h +@@ -64,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)), + l->l_map_end += l->l_addr; + l->l_text_end += l->l_addr; + l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr); +- elf_get_dynamic_info (l, false); ++ elf_get_dynamic_info (l); + _dl_setup_hash (l); + l->l_relocated = 1; + +diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h +index 34c0790b893a529b..07af183e711b50f2 100644 +--- a/sysdeps/aarch64/dl-machine.h ++++ b/sysdeps/aarch64/dl-machine.h +@@ -24,7 +24,9 @@ + #include + #include + #include ++#include + #include ++#include + #include + + /* Translate a processor specific dynamic tag to the index in l_info array. */ +@@ -196,10 +198,6 @@ _dl_start_user: \n\ + + #define ELF_MACHINE_JMP_SLOT AARCH64_R(JUMP_SLOT) + +-/* AArch64 uses RELA not REL */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + #define DL_PLATFORM_INIT dl_platform_init () + + static inline void __attribute__ ((unused)) +@@ -376,7 +374,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], + } + } + +-inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (ElfW(Addr) l_addr, + const ElfW(Rela) *reloc, +diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h +index 66e1db524bb378f6..e948e54fb7223a18 100644 +--- a/sysdeps/alpha/dl-machine.h ++++ b/sysdeps/alpha/dl-machine.h +@@ -26,6 +26,8 @@ + #define ELF_MACHINE_NAME "alpha" + + #include ++#include ++#include + + + /* Mask identifying addresses reserved for the user program, +@@ -241,10 +243,6 @@ $fixup_stack: \n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_ALPHA_JMP_SLOT + +-/* The alpha never uses Elf64_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* We define an initialization functions. This is called very early in + * _dl_sysdep_start. */ + #define DL_PLATFORM_INIT dl_platform_init () +diff --git a/sysdeps/arc/dl-machine.h b/sysdeps/arc/dl-machine.h +index 4b64ffec256b7f3b..f843ed9bd6ff5fc2 100644 +--- a/sysdeps/arc/dl-machine.h ++++ b/sysdeps/arc/dl-machine.h +@@ -30,6 +30,8 @@ + #include + #include + #include ++#include ++#include + + /* Dynamic Linking ABI for ARCv2 ISA. + +@@ -203,10 +205,6 @@ __start: \n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_ARC_JUMP_SLOT + +-/* ARC uses Rela relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* Fixup a PLT entry to bounce directly to the function at VALUE. */ + + static inline ElfW(Addr) +@@ -318,7 +316,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], + } + } + +-inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + void *const reloc_addr_arg) +@@ -327,7 +325,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + *reloc_addr += l_addr; + } + +-inline void ++static inline void + __attribute__ ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], + ElfW(Addr) l_addr, const ElfW(Rela) *reloc, +diff --git a/sysdeps/arm/dl-machine-rel.h b/sysdeps/arm/dl-machine-rel.h +new file mode 100644 +index 0000000000000000..bec114706cd027a4 +--- /dev/null ++++ b/sysdeps/arm/dl-machine-rel.h +@@ -0,0 +1,31 @@ ++/* ELF dynamic relocation type supported by the architecture. ARM version. ++ Copyright (C) 2001-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_MACHINE_REL_H ++#define _DL_MACHINE_REL_H ++ ++/* ARM never uses Elf32_Rela relocations for the dynamic linker. ++ Prelinked libraries may use Elf32_Rela though. */ ++#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP ++#define ELF_MACHINE_NO_REL 0 ++ ++/* ARM never uses Elf32_Rela relocations for the dynamic linker. ++ Prelinked libraries may use Elf32_Rela though. */ ++#define ELF_MACHINE_PLT_REL 1 ++ ++#endif +diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h +index 86f866ca7c17bd9b..3239841eb5b36623 100644 +--- a/sysdeps/arm/dl-machine.h ++++ b/sysdeps/arm/dl-machine.h +@@ -26,6 +26,8 @@ + #include + #include + #include ++#include ++#include + + #ifndef CLEAR_CACHE + # error CLEAR_CACHE definition required to handle TEXTREL +@@ -258,10 +260,6 @@ _dl_start_user:\n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_ARM_JUMP_SLOT + +-/* ARM never uses Elf32_Rela relocations for the dynamic linker. +- Prelinked libraries may use Elf32_Rela though. */ +-#define ELF_MACHINE_PLT_REL 1 +- + /* We define an initialization functions. This is called very early in + _dl_sysdep_start. */ + #define DL_PLATFORM_INIT dl_platform_init () +@@ -294,11 +292,6 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc, + #endif /* !dl_machine_h */ + + +-/* ARM never uses Elf32_Rela relocations for the dynamic linker. +- Prelinked libraries may use Elf32_Rela though. */ +-#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP +-#define ELF_MACHINE_NO_REL 0 +- + /* Names of the architecture-specific auditing callback functions. */ + #define ARCH_LA_PLTENTER arm_gnu_pltenter + #define ARCH_LA_PLTEXIT arm_gnu_pltexit +diff --git a/sysdeps/csky/dl-machine.h b/sysdeps/csky/dl-machine.h +index ec22f875772b1291..4dfd9578773f1c8e 100644 +--- a/sysdeps/csky/dl-machine.h ++++ b/sysdeps/csky/dl-machine.h +@@ -24,6 +24,8 @@ + #include + #include + #include ++#include ++#include + + /* Return nonzero if ELF header is compatible with the running host. */ + static inline int +@@ -172,10 +174,6 @@ _dl_start_user:\n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_CKCORE_JUMP_SLOT + +-/* C-SKY never uses Elf32_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* We define an initialization functions. This is called very early in + _dl_sysdep_start. */ + #define DL_PLATFORM_INIT dl_platform_init () +diff --git a/sysdeps/generic/dl-machine-rel.h b/sysdeps/generic/dl-machine-rel.h +new file mode 100644 +index 0000000000000000..9167a1dffc715704 +--- /dev/null ++++ b/sysdeps/generic/dl-machine-rel.h +@@ -0,0 +1,27 @@ ++/* ELF dynamic relocation type supported by the architecture. ++ Copyright (C) 2001-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_MACHINE_REL_H ++#define _DL_MACHINE_REL_H ++ ++/* Defined if the architecture supports Elf{32,64}_Rel relocations. */ ++#define ELF_MACHINE_NO_REL 1 ++/* Defined if the architecture supports Elf{32,64}_Rela relocations. */ ++#define ELF_MACHINE_NO_RELA 0 ++ ++#endif +diff --git a/sysdeps/generic/dl-machine.h b/sysdeps/generic/dl-machine.h +index 4a4ab4fc70ff1cf1..7da695d9030b000e 100644 +--- a/sysdeps/generic/dl-machine.h ++++ b/sysdeps/generic/dl-machine.h +@@ -20,6 +20,8 @@ + + #include + #include ++#include ++#include + + + /* Return nonzero iff ELF header is compatible with the running host. */ +diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h +index 088931f67065250c..ac66f044189edd18 100644 +--- a/sysdeps/hppa/dl-machine.h ++++ b/sysdeps/hppa/dl-machine.h +@@ -31,6 +31,8 @@ + #include + #include + #include ++#include ++#include + + /* These two definitions must match the definition of the stub in + bfd/elf32-hppa.c (see plt_stub[]). +@@ -525,10 +527,6 @@ asm ( \ + #define ELF_MACHINE_JMP_SLOT R_PARISC_IPLT + #define ELF_MACHINE_SIZEOF_JMP_SLOT PLT_ENTRY_SIZE + +-/* We only use RELA. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* Return the address of the entry point. */ + #define ELF_MACHINE_START_ADDRESS(map, start) \ + ({ \ +diff --git a/sysdeps/i386/dl-machine-rel.h b/sysdeps/i386/dl-machine-rel.h +new file mode 100644 +index 0000000000000000..7ac46f78a69fbf98 +--- /dev/null ++++ b/sysdeps/i386/dl-machine-rel.h +@@ -0,0 +1,31 @@ ++/* ELF dynamic relocation type supported by the architecture. ARM version. ++ Copyright (C) 2001-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_MACHINE_REL_H ++#define _DL_MACHINE_REL_H ++ ++/* The i386 never uses Elf32_Rela relocations for the dynamic linker. ++ Prelinked libraries may use Elf32_Rela though. */ ++#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP ++#define ELF_MACHINE_NO_REL 0 ++ ++/* The i386 never uses Elf32_Rela relocations for the dynamic linker. ++ Prelinked libraries may use Elf32_Rela though. */ ++#define ELF_MACHINE_PLT_REL 1 ++ ++#endif +diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h +index fa902612ca8557f9..c55c9a3d64bed1f2 100644 +--- a/sysdeps/i386/dl-machine.h ++++ b/sysdeps/i386/dl-machine.h +@@ -26,6 +26,8 @@ + #include + #include + #include ++#include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute__ ((unused)) +@@ -237,10 +239,6 @@ _dl_start_user:\n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_386_JMP_SLOT + +-/* The i386 never uses Elf32_Rela relocations for the dynamic linker. +- Prelinked libraries may use Elf32_Rela though. */ +-#define ELF_MACHINE_PLT_REL 1 +- + /* We define an initialization functions. This is called very early in + _dl_sysdep_start. */ + #define DL_PLATFORM_INIT dl_platform_init () +@@ -283,11 +281,6 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc, + + #endif /* !dl_machine_h */ + +-/* The i386 never uses Elf32_Rela relocations for the dynamic linker. +- Prelinked libraries may use Elf32_Rela though. */ +-#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP +-#define ELF_MACHINE_NO_REL 0 +- + #ifdef RESOLVE_MAP + + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). +diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h +index 2217d0b556c17683..c9608a51b0291164 100644 +--- a/sysdeps/ia64/dl-machine.h ++++ b/sysdeps/ia64/dl-machine.h +@@ -27,6 +27,8 @@ + #include + #include + #include ++#include ++#include + + /* Translate a processor specific dynamic tag to the index + in l_info array. */ +@@ -319,10 +321,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_IA64_IPLTLSB + +-/* According to the IA-64 specific documentation, Rela is always used. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* Return the address of the entry point. */ + #define ELF_MACHINE_START_ADDRESS(map, start) \ + ({ \ +diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h +index 5e34c4784e348b19..30323d62d443645a 100644 +--- a/sysdeps/m68k/dl-machine.h ++++ b/sysdeps/m68k/dl-machine.h +@@ -24,6 +24,8 @@ + #include + #include + #include ++#include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int +@@ -183,10 +185,6 @@ _dl_start_user:\n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_68K_JMP_SLOT + +-/* The m68k never uses Elf32_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + static inline Elf32_Addr + elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const ElfW(Sym) *refsym, const ElfW(Sym) *sym, +diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h +index 3fd4988e6093be1c..b8cc5a7fe65af90a 100644 +--- a/sysdeps/microblaze/dl-machine.h ++++ b/sysdeps/microblaze/dl-machine.h +@@ -23,6 +23,8 @@ + + #include + #include ++#include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int +@@ -169,10 +171,6 @@ _dl_start_user:\n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_MICROBLAZE_JUMP_SLOT + +-/* The microblaze never uses Elf32_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + static inline Elf32_Addr + elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const ElfW(Sym) *refsym, const ElfW(Sym) *sym, +diff --git a/sysdeps/mips/dl-machine-rel.h b/sysdeps/mips/dl-machine-rel.h +new file mode 100644 +index 0000000000000000..ed396180412bc723 +--- /dev/null ++++ b/sysdeps/mips/dl-machine-rel.h +@@ -0,0 +1,26 @@ ++/* ELF dynamic relocation type supported by the architecture. ARM version. ++ Copyright (C) 2001-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_MACHINE_REL_H ++#define _DL_MACHINE_REL_H ++ ++#define ELF_MACHINE_PLT_REL 1 ++#define ELF_MACHINE_NO_REL 0 ++#define ELF_MACHINE_NO_RELA 0 ++ ++#endif +diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h +index 7a821ceb8e518cef..45a394907a98be32 100644 +--- a/sysdeps/mips/dl-machine.h ++++ b/sysdeps/mips/dl-machine.h +@@ -33,6 +33,8 @@ + #include + #include + #include ++#include ++#include + + /* The offset of gp from GOT might be system-dependent. It's set by + ld. The same value is also */ +@@ -60,10 +62,6 @@ + ((((type) == ELF_MACHINE_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_MIPS_COPY) * ELF_RTYPE_CLASS_COPY)) + +-#define ELF_MACHINE_PLT_REL 1 +-#define ELF_MACHINE_NO_REL 0 +-#define ELF_MACHINE_NO_RELA 0 +- + /* Translate a processor specific dynamic tag to the index + in l_info array. */ + #define DT_MIPS(x) (DT_MIPS_##x - DT_LOPROC + DT_NUM) +diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h +index 4de602b13d5500f6..430ca5d7ae1e0372 100644 +--- a/sysdeps/nios2/dl-machine.h ++++ b/sysdeps/nios2/dl-machine.h +@@ -24,6 +24,8 @@ + #include + #include + #include ++#include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int +@@ -200,10 +202,6 @@ _start:\n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_NIOS2_JUMP_SLOT + +-/* The Nios II never uses Elf32_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* Fixup a PLT entry to bounce directly to the function at VALUE. */ + + static inline Elf32_Addr +diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h +index cda012dc1b822254..8d062951ce0abd69 100644 +--- a/sysdeps/powerpc/powerpc32/dl-machine.h ++++ b/sysdeps/powerpc/powerpc32/dl-machine.h +@@ -25,6 +25,8 @@ + #include + #include + #include ++#include ++#include + + /* Translate a processor specific dynamic tag to the index + in l_info array. */ +@@ -145,10 +147,6 @@ __elf_preferred_address(struct link_map *loader, size_t maplength, + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_PPC_JMP_SLOT + +-/* The PowerPC never uses REL relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* We define an initialization function to initialize HWCAP/HWCAP2 and + platform data so it can be copied into the TCB later. This is called + very early in _dl_sysdep_start for dynamically linked binaries. */ +diff --git a/sysdeps/powerpc/powerpc64/dl-funcdesc.h b/sysdeps/powerpc/powerpc64/dl-funcdesc.h +new file mode 100644 +index 0000000000000000..b2d1f76ce02d629e +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/dl-funcdesc.h +@@ -0,0 +1,34 @@ ++/* PowerPC ELFv1 function descriptor definition. ++ Copyright (C) 2009-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_FUNCDESC_H ++#define _DL_FUNCDESC_H ++ ++#if _CALL_ELF != 2 ++/* A PowerPC64 function descriptor. The .plt (procedure linkage ++ table) and .opd (official procedure descriptor) sections are ++ arrays of these. */ ++typedef struct ++{ ++ Elf64_Addr fd_func; ++ Elf64_Addr fd_toc; ++ Elf64_Addr fd_aux; ++} Elf64_FuncDesc; ++#endif ++ ++#endif +diff --git a/sysdeps/powerpc/powerpc64/dl-irel.h b/sysdeps/powerpc/powerpc64/dl-irel.h +index 0e11b7ff647c19d5..aa9a2dca71c3b05f 100644 +--- a/sysdeps/powerpc/powerpc64/dl-irel.h ++++ b/sysdeps/powerpc/powerpc64/dl-irel.h +@@ -23,7 +23,7 @@ + #include + #include + #include +-#include ++#include + + #define ELF_MACHINE_IRELA 1 + +diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h +index 3f92fbb369eb5023..3a4a21a4124dc72a 100644 +--- a/sysdeps/powerpc/powerpc64/dl-machine.h ++++ b/sysdeps/powerpc/powerpc64/dl-machine.h +@@ -28,23 +28,14 @@ + #include + #include + #include ++#include ++#include ++#include + + /* Translate a processor specific dynamic tag to the index + in l_info array. */ + #define DT_PPC64(x) (DT_PPC64_##x - DT_LOPROC + DT_NUM) + +-#if _CALL_ELF != 2 +-/* A PowerPC64 function descriptor. The .plt (procedure linkage +- table) and .opd (official procedure descriptor) sections are +- arrays of these. */ +-typedef struct +-{ +- Elf64_Addr fd_func; +- Elf64_Addr fd_toc; +- Elf64_Addr fd_aux; +-} Elf64_FuncDesc; +-#endif +- + #define ELF_MULT_MACHINES_SUPPORTED + + /* Return nonzero iff ELF header is compatible with the running host. */ +@@ -292,10 +283,6 @@ BODY_PREFIX "_dl_start_user:\n" \ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_PPC64_JMP_SLOT + +-/* The PowerPC never uses REL relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* We define an initialization function to initialize HWCAP/HWCAP2 and + platform data so it can be copied into the TCB later. This is called + very early in _dl_sysdep_start for dynamically linked binaries. */ +diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h +index 343c0feb6b437001..a9a3f63cb4d91f26 100644 +--- a/sysdeps/riscv/dl-machine.h ++++ b/sysdeps/riscv/dl-machine.h +@@ -26,6 +26,8 @@ + #include + #include + #include ++#include ++#include + + #ifndef _RTLD_PROLOGUE + # define _RTLD_PROLOGUE(entry) \ +@@ -51,9 +53,6 @@ + || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_TPREL64))) \ + | (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY))) + +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute_used__ + elf_machine_matches_host (const ElfW(Ehdr) *ehdr) +diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h +index 96a5e80c846c816a..ba681d1eac7bda53 100644 +--- a/sysdeps/s390/s390-32/dl-machine.h ++++ b/sysdeps/s390/s390-32/dl-machine.h +@@ -27,6 +27,8 @@ + #include + #include + #include ++#include ++#include + + /* This is an older, now obsolete value. */ + #define EM_S390_OLD 0xA390 +@@ -277,10 +279,6 @@ _dl_start_user:\n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT + +-/* The S390 never uses Elf32_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* We define an initialization functions. This is called very early in + _dl_sysdep_start. */ + #define DL_PLATFORM_INIT dl_platform_init () +diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h +index c94d09b9c8512738..af2cffd9f904274e 100644 +--- a/sysdeps/s390/s390-64/dl-machine.h ++++ b/sysdeps/s390/s390-64/dl-machine.h +@@ -28,6 +28,8 @@ + #include + #include + #include ++#include ++#include + + #define ELF_MACHINE_IRELATIVE R_390_IRELATIVE + +@@ -225,10 +227,6 @@ _dl_start_user:\n\ + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT + +-/* The 64 bit S/390 never uses Elf64_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* We define an initialization functions. This is called very early in + _dl_sysdep_start. */ + #define DL_PLATFORM_INIT dl_platform_init () +diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h +index 0c22dfd8487a516e..d14023e7492f64e9 100644 +--- a/sysdeps/sh/dl-machine.h ++++ b/sysdeps/sh/dl-machine.h +@@ -24,6 +24,8 @@ + #include + #include + #include ++#include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute__ ((unused)) +@@ -251,10 +253,6 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + + #endif /* !dl_machine_h */ + +-/* SH never uses Elf32_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + #ifdef RESOLVE_MAP + + /* Perform the relocation specified by RELOC and SYM (which is fully resolved). +diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h +index 6361cfae9eb8fa58..78f53bc49920fa46 100644 +--- a/sysdeps/sparc/sparc32/dl-machine.h ++++ b/sysdeps/sparc/sparc32/dl-machine.h +@@ -28,6 +28,8 @@ + #include + #include + #include ++#include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int +@@ -196,10 +198,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT + +-/* The SPARC never uses Elf32_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* Undo the sub %sp, 6*4, %sp; add %sp, 22*4, %o0 below to get at the + value we want in __libc_stack_end. */ + #define DL_STACK_END(cookie) \ +diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h +index 3fd18c6e5ef21e38..3fa79d038fd38976 100644 +--- a/sysdeps/sparc/sparc64/dl-machine.h ++++ b/sysdeps/sparc/sparc64/dl-machine.h +@@ -26,6 +26,8 @@ + #include + #include + #include ++#include ++#include + + #define ELF64_R_TYPE_ID(info) ((info) & 0xff) + #define ELF64_R_TYPE_DATA(info) ((info) >> 8) +@@ -118,10 +120,6 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT + +-/* The SPARC never uses Elf64_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* Set up the loaded object described by L so its unrelocated PLT + entries will jump to the on-demand fixup code in dl-runtime.c. */ + +diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h +index db388a022d552b8c..72b75d3bebfed0b5 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h ++++ b/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h +@@ -24,7 +24,7 @@ + #include + + #if (defined(__PPC64__) || defined(__powerpc64__)) && _CALL_ELF != 2 +-# include ++# include + /* The correct solution is for _dl_vdso_vsym to return the address of the OPD + for the kernel VDSO function. That address would then be stored in the + __vdso_* variables and returned as the result of the IFUNC resolver function. +diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h +index 90c77cfea1de8d63..94296719d4d9fb82 100644 +--- a/sysdeps/x86_64/dl-machine.h ++++ b/sysdeps/x86_64/dl-machine.h +@@ -27,6 +27,8 @@ + #include + #include + #include ++#include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute__ ((unused)) +@@ -208,10 +210,6 @@ _dl_start_user:\n\ + // XXX This is a work-around for a broken linker. Remove! + #define ELF_MACHINE_IRELATIVE R_X86_64_IRELATIVE + +-/* The x86-64 never uses Elf64_Rel/Elf32_Rel relocations. */ +-#define ELF_MACHINE_NO_REL 1 +-#define ELF_MACHINE_NO_RELA 0 +- + /* We define an initialization function. This is called very early in + _dl_sysdep_start. */ + #define DL_PLATFORM_INIT dl_platform_init () diff --git a/SOURCES/glibc-upstream-2.34-139.patch b/SOURCES/glibc-upstream-2.34-139.patch new file mode 100644 index 0000000..8633732 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-139.patch @@ -0,0 +1,221 @@ +commit f6a54a304223666ea4af73260c99c830d7726eca +Author: Adhemerval Zanella +Date: Fri Oct 15 14:35:31 2021 -0300 + + elf: Fix elf_get_dynamic_info() for bootstrap + + THe d6d89608ac8c broke powerpc for --enable-bind-now because it turned + out that different than patch assumption rtld elf_get_dynamic_info() + does require to handle RTLD_BOOTSTRAP to avoid DT_FLAGS and + DT_RUNPATH (more specially the GLRO usage which is not reallocate + yet). + + This patch fixes by passing two arguments to elf_get_dynamic_info() + to inform that by rtld (bootstrap) or static pie initialization + (static_pie_bootstrap). I think using explicit argument is way more + clear and burried C preprocessor, and compiler should remove the + dead code. + + I checked on x86_64 and i686 with default options, --enable-bind-now, + and --enable-bind-now and --enable--static-pie. I also check on + aarch64, armhf, powerpc64, and powerpc with default and + --enable-bind-now. + + (cherry picked from commit 5118dcac68c4eadfd6304bb33adde63d062dc07f) + + Resolved conflicts: + elf/rtld.c - Manual merge. + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index fb3da5aa565908a6..a920b12a906a9dec 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1296,7 +1296,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + if (l->l_ld != 0) + l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr); + +- elf_get_dynamic_info (l); ++ elf_get_dynamic_info (l, false, false); + + /* Make sure we are not dlopen'ing an object that has the + DF_1_NOOPEN flag set, or a PIE object. */ +diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c +index ababafcf98f9945d..757205affe65d9e1 100644 +--- a/elf/dl-reloc-static-pie.c ++++ b/elf/dl-reloc-static-pie.c +@@ -25,7 +25,6 @@ + + #include + +-#define STATIC_PIE_BOOTSTRAP + #define RESOLVE_MAP(map, scope, sym, version, flags) map + #include "dynamic-link.h" + #include "get-dynamic-info.h" +@@ -52,7 +51,7 @@ _dl_relocate_static_pie (void) + break; + } + +- elf_get_dynamic_info (main_map); ++ elf_get_dynamic_info (main_map, false, true); + + # ifdef ELF_MACHINE_BEFORE_RTLD_RELOC + ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info); +diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h +index 1ac0663d1ff5de24..f63e07dc6d2cd5e6 100644 +--- a/elf/get-dynamic-info.h ++++ b/elf/get-dynamic-info.h +@@ -26,7 +26,8 @@ + #include + + static inline void __attribute__ ((unused, always_inline)) +-elf_get_dynamic_info (struct link_map *l) ++elf_get_dynamic_info (struct link_map *l, bool bootstrap, ++ bool static_pie_bootstrap) + { + #if __ELF_NATIVE_CLASS == 32 + typedef Elf32_Word d_tag_utype; +@@ -35,7 +36,7 @@ elf_get_dynamic_info (struct link_map *l) + #endif + + #ifndef STATIC_PIE_BOOTSTRAP +- if (l->l_ld == NULL) ++ if (!bootstrap && l->l_ld == NULL) + return; + #endif + +@@ -112,47 +113,63 @@ elf_get_dynamic_info (struct link_map *l) + if (info[DT_REL] != NULL) + assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); + #endif +-#ifdef STATIC_PIE_BOOTSTRAP +- assert (info[DT_RUNPATH] == NULL); +- assert (info[DT_RPATH] == NULL); +-#endif +- if (info[DT_FLAGS] != NULL) ++ if (bootstrap || static_pie_bootstrap) + { +- /* Flags are used. Translate to the old form where available. +- Since these l_info entries are only tested for NULL pointers it +- is ok if they point to the DT_FLAGS entry. */ +- l->l_flags = info[DT_FLAGS]->d_un.d_val; +- +- if (l->l_flags & DF_SYMBOLIC) +- info[DT_SYMBOLIC] = info[DT_FLAGS]; +- if (l->l_flags & DF_TEXTREL) +- info[DT_TEXTREL] = info[DT_FLAGS]; +- if (l->l_flags & DF_BIND_NOW) +- info[DT_BIND_NOW] = info[DT_FLAGS]; ++ assert (info[DT_RUNPATH] == NULL); ++ assert (info[DT_RPATH] == NULL); + } +- if (info[VERSYMIDX (DT_FLAGS_1)] != NULL) ++ if (bootstrap) + { +- l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val; +- if (l->l_flags_1 & DF_1_NODELETE) +- 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 +- unsupported DF_1_* flags for a long time and glibc has ignored +- them. Therefore to avoid breaking existing applications the +- best we can do is add a warning during debugging with the +- intent of notifying the user of the problem. */ +- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0) +- && l->l_flags_1 & ~DT_1_SUPPORTED_MASK) +- _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.\n", +- l->l_flags_1 & ~DT_1_SUPPORTED_MASK); +- +- if (l->l_flags_1 & DF_1_NOW) +- info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)]; ++ /* Only the bind now flags are allowed. */ ++ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL ++ || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0); ++ /* Flags must not be set for ld.so. */ ++ assert (info[DT_FLAGS] == NULL ++ || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0); + } +- if (info[DT_RUNPATH] != NULL) +- /* If both RUNPATH and RPATH are given, the latter is ignored. */ +- info[DT_RPATH] = NULL; ++ else ++ { ++ if (info[DT_FLAGS] != NULL) ++ { ++ /* Flags are used. Translate to the old form where available. ++ Since these l_info entries are only tested for NULL pointers it ++ is ok if they point to the DT_FLAGS entry. */ ++ l->l_flags = info[DT_FLAGS]->d_un.d_val; ++ ++ if (l->l_flags & DF_SYMBOLIC) ++ info[DT_SYMBOLIC] = info[DT_FLAGS]; ++ if (l->l_flags & DF_TEXTREL) ++ info[DT_TEXTREL] = info[DT_FLAGS]; ++ if (l->l_flags & DF_BIND_NOW) ++ info[DT_BIND_NOW] = info[DT_FLAGS]; ++ } ++ ++ 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_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 ++ unsupported DF_1_* flags for a long time and glibc has ignored ++ them. Therefore to avoid breaking existing applications the ++ best we can do is add a warning during debugging with the ++ intent of notifying the user of the problem. */ ++ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0) ++ && l->l_flags_1 & ~DT_1_SUPPORTED_MASK) ++ _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x " ++ "in DT_FLAGS_1.\n", ++ l->l_flags_1 & ~DT_1_SUPPORTED_MASK); ++ ++ if (l->l_flags_1 & DF_1_NOW) ++ info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)]; ++ } ++ ++ if (info[DT_RUNPATH] != NULL) ++ /* If both RUNPATH and RPATH are given, the latter is ignored. */ ++ info[DT_RPATH] = NULL; ++ } + } + + #endif +diff --git a/elf/rtld.c b/elf/rtld.c +index 37d28d5a66d7b5d6..ad5ddb2a0ab94e7f 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -549,7 +549,7 @@ _dl_start (void *arg) + /* Read our own dynamic section and fill in the info array. */ + bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); + bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION; +- elf_get_dynamic_info (&bootstrap_map); ++ elf_get_dynamic_info (&bootstrap_map, true, false); + + #if NO_TLS_OFFSET != 0 + bootstrap_map.l_tls_offset = NO_TLS_OFFSET; +@@ -1653,7 +1653,7 @@ dl_main (const ElfW(Phdr) *phdr, + if (! rtld_is_main) + { + /* Extract the contents of the dynamic section for easy access. */ +- elf_get_dynamic_info (main_map); ++ elf_get_dynamic_info (main_map, false, false); + + /* If the main map is libc.so, update the base namespace to + refer to this map. If libc.so is loaded later, this happens +diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h +index f44748bc9858e5fd..3f20578046de76ed 100644 +--- a/elf/setup-vdso.h ++++ b/elf/setup-vdso.h +@@ -64,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)), + l->l_map_end += l->l_addr; + l->l_text_end += l->l_addr; + l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr); +- elf_get_dynamic_info (l); ++ elf_get_dynamic_info (l, false, false); + _dl_setup_hash (l); + l->l_relocated = 1; + diff --git a/SOURCES/glibc-upstream-2.34-14.patch b/SOURCES/glibc-upstream-2.34-14.patch new file mode 100644 index 0000000..9d9c1c5 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-14.patch @@ -0,0 +1,411 @@ +commit a8ac8c4725ddb1119764126a8674a04c9dd5aea8 +Author: Florian Weimer +Date: Mon Sep 13 11:06:08 2021 +0200 + + nptl: Fix race between pthread_kill and thread exit (bug 12889) + + A new thread exit lock and flag are introduced. They are used to + detect that the thread is about to exit or has exited in + __pthread_kill_internal, and the signal is not sent in this case. + + The test sysdeps/pthread/tst-pthread_cancel-select-loop.c is derived + from a downstream test originally written by Marek Polacek. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 526c3cf11ee9367344b6b15d669e4c3cb461a2be) + +diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c +index cfe37a3443b69454..50065bc9bd8a28e5 100644 +--- a/nptl/allocatestack.c ++++ b/nptl/allocatestack.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + /* Default alignment of stack. */ + #ifndef STACK_ALIGN +@@ -127,6 +128,8 @@ get_cached_stack (size_t *sizep, void **memp) + /* No pending event. */ + result->nextevent = NULL; + ++ result->exiting = false; ++ __libc_lock_init (result->exit_lock); + result->tls_state = (struct tls_internal_t) { 0 }; + + /* Clear the DTV. */ +diff --git a/nptl/descr.h b/nptl/descr.h +index c85778d44941a42f..4de84138fb960fa4 100644 +--- a/nptl/descr.h ++++ b/nptl/descr.h +@@ -396,6 +396,12 @@ struct pthread + PTHREAD_CANCEL_ASYNCHRONOUS). */ + unsigned char canceltype; + ++ /* Used in __pthread_kill_internal to detected a thread that has ++ exited or is about to exit. exit_lock must only be acquired ++ after blocking signals. */ ++ bool exiting; ++ int exit_lock; /* A low-level lock (for use with __libc_lock_init etc). */ ++ + /* Used on strsignal. */ + struct tls_internal_t tls_state; + +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index d8ec299cb1661e82..33b426fc682300dc 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include + +@@ -485,6 +486,19 @@ start_thread (void *arg) + /* This was the last thread. */ + exit (0); + ++ /* This prevents sending a signal from this thread to itself during ++ its final stages. This must come after the exit call above ++ because atexit handlers must not run with signals blocked. */ ++ __libc_signal_block_all (NULL); ++ ++ /* Tell __pthread_kill_internal that this thread is about to exit. ++ If there is a __pthread_kill_internal in progress, this delays ++ the thread exit until the signal has been queued by the kernel ++ (so that the TID used to send it remains valid). */ ++ __libc_lock_lock (pd->exit_lock); ++ pd->exiting = true; ++ __libc_lock_unlock (pd->exit_lock); ++ + #ifndef __ASSUME_SET_ROBUST_LIST + /* If this thread has any robust mutexes locked, handle them now. */ + # if __PTHREAD_MUTEX_HAVE_PREV +diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c +index 5d4c86f9205a6fb5..fb7862eff787a94f 100644 +--- a/nptl/pthread_kill.c ++++ b/nptl/pthread_kill.c +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + #include + #include +@@ -23,37 +24,51 @@ + int + __pthread_kill_internal (pthread_t threadid, int signo) + { +- pid_t tid; + struct pthread *pd = (struct pthread *) threadid; +- + if (pd == THREAD_SELF) +- /* It is a special case to handle raise() implementation after a vfork +- call (which does not update the PD tid field). */ +- tid = INLINE_SYSCALL_CALL (gettid); +- else +- /* Force load of pd->tid into local variable or register. Otherwise +- if a thread exits between ESRCH test and tgkill, we might return +- EINVAL, because pd->tid would be cleared by the kernel. */ +- tid = atomic_forced_read (pd->tid); +- +- int val; +- if (__glibc_likely (tid > 0)) + { +- pid_t pid = __getpid (); +- +- val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo); +- val = (INTERNAL_SYSCALL_ERROR_P (val) +- ? INTERNAL_SYSCALL_ERRNO (val) : 0); ++ /* Use the actual TID from the kernel, so that it refers to the ++ current thread even if called after vfork. There is no ++ signal blocking in this case, so that the signal is delivered ++ immediately, before __pthread_kill_internal returns: a signal ++ sent to the thread itself needs to be delivered ++ synchronously. (It is unclear if Linux guarantees the ++ delivery of all pending signals after unblocking in the code ++ below. POSIX only guarantees delivery of a single signal, ++ which may not be the right one.) */ ++ pid_t tid = INTERNAL_SYSCALL_CALL (gettid); ++ int ret = INTERNAL_SYSCALL_CALL (kill, tid, signo); ++ return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; + } ++ ++ /* Block all signals, as required by pd->exit_lock. */ ++ sigset_t old_mask; ++ __libc_signal_block_all (&old_mask); ++ __libc_lock_lock (pd->exit_lock); ++ ++ int ret; ++ if (pd->exiting) ++ /* The thread is about to exit (or has exited). Sending the ++ signal is either not observable (the target thread has already ++ blocked signals at this point), or it will fail, or it might be ++ delivered to a new, unrelated thread that has reused the TID. ++ So do not actually send the signal. Do not report an error ++ because the threadid argument is still valid (the thread ID ++ lifetime has not ended), and ESRCH (for example) would be ++ misleading. */ ++ ret = 0; + else +- /* The kernel reports that the thread has exited. POSIX specifies +- the ESRCH error only for the case when the lifetime of a thread +- ID has ended, but calling pthread_kill on such a thread ID is +- undefined in glibc. Therefore, do not treat kernel thread exit +- as an error. */ +- val = 0; ++ { ++ /* Using tgkill is a safety measure. pd->exit_lock ensures that ++ the target thread cannot exit. */ ++ ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), pd->tid, signo); ++ ret = INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; ++ } ++ ++ __libc_lock_unlock (pd->exit_lock); ++ __libc_signal_restore_set (&old_mask); + +- return val; ++ return ret; + } + + int +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index dedfa0d290da4949..48dba717a1cdc20a 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -119,7 +119,9 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-unwind-thread \ + tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ + tst-pthread_cancel-exited \ ++ tst-pthread_cancel-select-loop \ + tst-pthread_kill-exited \ ++ tst-pthread_kill-exiting \ + # tests + + tests-time64 := \ +diff --git a/sysdeps/pthread/tst-pthread_cancel-select-loop.c b/sysdeps/pthread/tst-pthread_cancel-select-loop.c +new file mode 100644 +index 0000000000000000..a62087589cee24b5 +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread_cancel-select-loop.c +@@ -0,0 +1,87 @@ ++/* Test that pthread_cancel succeeds during thread exit. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test tries to trigger an internal race condition in ++ pthread_cancel, where the cancellation signal is sent after the ++ thread has begun the cancellation process. This can result in a ++ spurious ESRCH error. For the original bug 12889, the window is ++ quite small, so the bug was not reproduced in every run. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Set to true by timeout_thread_function when the test should ++ terminate. */ ++static bool timeout; ++ ++static void * ++timeout_thread_function (void *unused) ++{ ++ usleep (5 * 1000 * 1000); ++ __atomic_store_n (&timeout, true, __ATOMIC_RELAXED); ++ return NULL; ++} ++ ++/* Used for blocking the select function below. */ ++static int pipe_fds[2]; ++ ++static void * ++canceled_thread_function (void *unused) ++{ ++ while (true) ++ { ++ fd_set rfs; ++ fd_set wfs; ++ fd_set efs; ++ FD_ZERO (&rfs); ++ FD_ZERO (&wfs); ++ FD_ZERO (&efs); ++ FD_SET (pipe_fds[0], &rfs); ++ ++ /* If the cancellation request is recognized early, the thread ++ begins exiting while the cancellation signal arrives. */ ++ select (FD_SETSIZE, &rfs, &wfs, &efs, NULL); ++ } ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ xpipe (pipe_fds); ++ pthread_t thr_timeout = xpthread_create (NULL, timeout_thread_function, NULL); ++ ++ while (!__atomic_load_n (&timeout, __ATOMIC_RELAXED)) ++ { ++ pthread_t thr = xpthread_create (NULL, canceled_thread_function, NULL); ++ xpthread_cancel (thr); ++ TEST_VERIFY (xpthread_join (thr) == PTHREAD_CANCELED); ++ } ++ ++ xpthread_join (thr_timeout); ++ xclose (pipe_fds[0]); ++ xclose (pipe_fds[1]); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/pthread/tst-pthread_kill-exiting.c b/sysdeps/pthread/tst-pthread_kill-exiting.c +new file mode 100644 +index 0000000000000000..f803e94f1195f204 +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread_kill-exiting.c +@@ -0,0 +1,123 @@ ++/* Test that pthread_kill succeeds during thread exit. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test verifies that pthread_kill for a thread that is exiting ++ succeeds (with or without actually delivering the signal). */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Set to true by timeout_thread_function when the test should ++ terminate. */ ++static bool timeout; ++ ++static void * ++timeout_thread_function (void *unused) ++{ ++ usleep (1000 * 1000); ++ __atomic_store_n (&timeout, true, __ATOMIC_RELAXED); ++ return NULL; ++} ++ ++/* Used to synchronize the sending threads with the target thread and ++ main thread. */ ++static pthread_barrier_t barrier_1; ++static pthread_barrier_t barrier_2; ++ ++/* The target thread to which signals are to be sent. */ ++static pthread_t target_thread; ++ ++/* Set by the main thread to true after timeout has been set to ++ true. */ ++static bool exiting; ++ ++static void * ++sender_thread_function (void *unused) ++{ ++ while (true) ++ { ++ /* Wait until target_thread has been initialized. The target ++ thread and main thread participate in this barrier. */ ++ xpthread_barrier_wait (&barrier_1); ++ ++ if (exiting) ++ break; ++ ++ xpthread_kill (target_thread, SIGUSR1); ++ ++ /* Communicate that the signal has been sent. The main thread ++ participates in this barrier. */ ++ xpthread_barrier_wait (&barrier_2); ++ } ++ return NULL; ++} ++ ++static void * ++target_thread_function (void *unused) ++{ ++ target_thread = pthread_self (); ++ xpthread_barrier_wait (&barrier_1); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ xsignal (SIGUSR1, SIG_IGN); ++ ++ pthread_t thr_timeout = xpthread_create (NULL, timeout_thread_function, NULL); ++ ++ pthread_t threads[4]; ++ xpthread_barrier_init (&barrier_1, NULL, array_length (threads) + 2); ++ xpthread_barrier_init (&barrier_2, NULL, array_length (threads) + 1); ++ ++ for (int i = 0; i < array_length (threads); ++i) ++ threads[i] = xpthread_create (NULL, sender_thread_function, NULL); ++ ++ while (!__atomic_load_n (&timeout, __ATOMIC_RELAXED)) ++ { ++ xpthread_create (NULL, target_thread_function, NULL); ++ ++ /* Wait for the target thread to be set up and signal sending to ++ start. */ ++ xpthread_barrier_wait (&barrier_1); ++ ++ /* Wait for signal sending to complete. */ ++ xpthread_barrier_wait (&barrier_2); ++ ++ xpthread_join (target_thread); ++ } ++ ++ exiting = true; ++ ++ /* Signal the sending threads to exit. */ ++ xpthread_create (NULL, target_thread_function, NULL); ++ xpthread_barrier_wait (&barrier_1); ++ ++ for (int i = 0; i < array_length (threads); ++i) ++ xpthread_join (threads[i]); ++ xpthread_join (thr_timeout); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-140.patch b/SOURCES/glibc-upstream-2.34-140.patch new file mode 100644 index 0000000..69ab10b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-140.patch @@ -0,0 +1,69 @@ +commit a31bbe3242266aaea423e5879f38aed69aea1d5e +Author: Adhemerval Zanella +Date: Thu Jul 29 11:13:57 2021 -0300 + + elf: Move LAV_CURRENT to link_lavcurrent.h + + No functional change. + + (cherry picked from commit 54816ae98d57930b7c945f17485714a5574bfe47) + + Resolved conflicts: + elf/Makefile + +diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h +new file mode 100644 +index 0000000000000000..44fbea1e8060997f +--- /dev/null ++++ b/bits/link_lavcurrent.h +@@ -0,0 +1,25 @@ ++/* Data structure for communication from the run-time dynamic linker for ++ loaded ELF shared objects. LAV_CURRENT definition. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _LINK_H ++# error "Never include directly; use instead." ++#endif ++ ++/* Version numbers for la_version handshake interface. */ ++#define LAV_CURRENT 1 +diff --git a/elf/Makefile b/elf/Makefile +index cd8725c76f4cfb48..7fa80946ff3aae42 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -24,6 +24,7 @@ include ../Makeconfig + headers = \ + bits/elfclass.h \ + bits/link.h \ ++ bits/link_lavcurrent.h \ + elf.h \ + link.h \ + # headers +diff --git a/elf/link.h b/elf/link.h +index ff3a85c847930b9b..21a351686b9bf7c8 100644 +--- a/elf/link.h ++++ b/elf/link.h +@@ -96,7 +96,7 @@ struct link_map + #ifdef __USE_GNU + + /* Version numbers for la_version handshake interface. */ +-#define LAV_CURRENT 1 ++#include + + /* Activity types signaled through la_activity. */ + enum diff --git a/SOURCES/glibc-upstream-2.34-141.patch b/SOURCES/glibc-upstream-2.34-141.patch new file mode 100644 index 0000000..2856c96 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-141.patch @@ -0,0 +1,390 @@ +commit e25fe992132c460fecc1ab9fade185d5dd3f91ff +Author: Adhemerval Zanella +Date: Thu Nov 11 09:28:21 2021 -0300 + + elf: Move la_activity (LA_ACT_ADD) after _dl_add_to_namespace_list() (BZ #28062) + + It ensures that the the namespace is guaranteed to not be empty. + + Checked on x86_64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit ed3ce71f5c64c5f07cbde0ef03554ea8950d8f2c) + + Resolved conflicts: + elf/Makefile + +diff --git a/elf/Makefile b/elf/Makefile +index 7fa80946ff3aae42..bf6da98bdd15a18d 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -363,6 +363,7 @@ tests += \ + tst-audit15 \ + tst-audit16 \ + tst-audit17 \ ++ tst-audit18 \ + tst-auditmany \ + tst-auxobj \ + tst-auxobj-dlopen \ +@@ -623,6 +624,7 @@ modules-names = \ + tst-audit12mod2 \ + tst-audit12mod3 \ + tst-audit13mod1 \ ++ tst-audit18mod \ + tst-auditlogmod-1 \ + tst-auditlogmod-2 \ + tst-auditlogmod-3 \ +@@ -640,6 +642,7 @@ modules-names = \ + tst-auditmod9b \ + tst-auditmod11 \ + tst-auditmod12 \ ++ tst-auditmod18 \ + tst-auxvalmod \ + tst-big-note-lib \ + tst-deep1mod1 \ +@@ -1999,6 +2002,10 @@ $(objpfx)tst-auditmod17.so: $(objpfx)tst-auditmod17.os + CFLAGS-.os += $(call elide-stack-protector,.os,tst-auditmod17) + tst-audit17-ENV = LD_AUDIT=$(objpfx)tst-auditmod17.so + ++$(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \ ++ $(objpfx)tst-audit18mod.so ++tst-audit18-ARGS = -- $(host-test-program-cmd) ++ + # tst-sonamemove links against an older implementation of the library. + LDFLAGS-tst-sonamemove-linkmod1.so = \ + -Wl,--version-script=tst-sonamemove-linkmod1.map \ +diff --git a/elf/dl-load.c b/elf/dl-load.c +index a920b12a906a9dec..a8c6df3959f2b331 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1054,42 +1054,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + /* This is the ELF header. We read it in `open_verify'. */ + header = (void *) fbp->buf; + +- /* Signal that we are going to add new objects. */ +- if (r->r_state == RT_CONSISTENT) +- { +-#ifdef SHARED +- /* Auditing checkpoint: we are going to add new objects. */ +- if ((mode & __RTLD_AUDIT) == 0 +- && __glibc_unlikely (GLRO(dl_naudit) > 0)) +- { +- struct link_map *head = GL(dl_ns)[nsid]._ns_loaded; +- /* Do not call the functions for any auditing object. */ +- if (head->l_auditing == 0) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->activity != NULL) +- afct->activity (&link_map_audit_state (head, cnt)->cookie, +- LA_ACT_ADD); +- +- afct = afct->next; +- } +- } +- } +-#endif +- +- /* Notify the debugger we have added some objects. We need to +- call _dl_debug_initialize in a static program in case dynamic +- linking has not been used before. */ +- r->r_state = RT_ADD; +- _dl_debug_state (); +- LIBC_PROBE (map_start, 2, nsid, r); +- make_consistent = true; +- } +- else +- assert (r->r_state == RT_ADD); +- + /* Enter the new object in the list of loaded objects. */ + l = _dl_new_object (realname, name, l_type, loader, mode, nsid); + if (__glibc_unlikely (l == NULL)) +@@ -1511,6 +1475,44 @@ cannot enable executable stack as shared object requires"); + /* Now that the object is fully initialized add it to the object list. */ + _dl_add_to_namespace_list (l, nsid); + ++ /* Signal that we are going to add new objects. */ ++ if (r->r_state == RT_CONSISTENT) ++ { ++#ifdef SHARED ++ /* Auditing checkpoint: we are going to add new objects. Since this ++ is called after _dl_add_to_namespace_list the namespace is guaranteed ++ to not be empty. */ ++ if ((mode & __RTLD_AUDIT) == 0 ++ && __glibc_unlikely (GLRO(dl_naudit) > 0)) ++ { ++ struct link_map *head = GL(dl_ns)[nsid]._ns_loaded; ++ /* Do not call the functions for any auditing object. */ ++ if (head->l_auditing == 0) ++ { ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ if (afct->activity != NULL) ++ afct->activity (&link_map_audit_state (head, cnt)->cookie, ++ LA_ACT_ADD); ++ ++ afct = afct->next; ++ } ++ } ++ } ++#endif ++ ++ /* Notify the debugger we have added some objects. We need to ++ call _dl_debug_initialize in a static program in case dynamic ++ linking has not been used before. */ ++ r->r_state = RT_ADD; ++ _dl_debug_state (); ++ LIBC_PROBE (map_start, 2, nsid, r); ++ make_consistent = true; ++ } ++ else ++ assert (r->r_state == RT_ADD); ++ + #ifdef SHARED + /* Auditing checkpoint: we have a new object. */ + if (__glibc_unlikely (GLRO(dl_naudit) > 0) +diff --git a/elf/tst-audit18.c b/elf/tst-audit18.c +new file mode 100644 +index 0000000000000000..ef784908f60d50aa +--- /dev/null ++++ b/elf/tst-audit18.c +@@ -0,0 +1,129 @@ ++/* Check DT_AUDIT with dlmopen. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int restart; ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++ ++static int ++handle_restart (void) ++{ ++ { ++ void *h = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); ++ ++ pid_t (*s) (void) = xdlsym (h, "getpid"); ++ TEST_COMPARE (s (), getpid ()); ++ ++ xdlclose (h); ++ } ++ ++ { ++ void *h = xdlmopen (LM_ID_NEWLM, "tst-audit18mod.so", RTLD_NOW); ++ ++ int (*foo) (void) = xdlsym (h, "foo"); ++ TEST_COMPARE (foo (), 10); ++ ++ xdlclose (h); ++ } ++ ++ return 0; ++} ++ ++static int ++do_test (int argc, char *argv[]) ++{ ++ /* We must have either: ++ - One our fource parameters left if called initially: ++ + path to ld.so optional ++ + "--library-path" optional ++ + the library path optional ++ + the application name */ ++ ++ if (restart) ++ return handle_restart (); ++ ++ char *spargv[9]; ++ int i = 0; ++ for (; i < argc - 1; i++) ++ spargv[i] = argv[i + 1]; ++ spargv[i++] = (char *) "--direct"; ++ spargv[i++] = (char *) "--restart"; ++ spargv[i] = NULL; ++ ++ setenv ("LD_AUDIT", "tst-auditmod18.so", 0); ++ struct support_capture_subprocess result ++ = support_capture_subprogram (spargv[0], spargv); ++ support_capture_subprocess_check (&result, "tst-audit18", 0, sc_allow_stderr); ++ ++ struct ++ { ++ const char *name; ++ bool found; ++ } audit_iface[] = ++ { ++ { "la_version", false }, ++ { "la_objsearch", false }, ++ { "la_activity", false }, ++ { "la_objopen", false }, ++ { "la_objclose", false }, ++ { "la_preinit", false }, ++#if __WORDSIZE == 32 ++ { "la_symbind32", false }, ++#elif __WORDSIZE == 64 ++ { "la_symbind64", false }, ++#endif ++ }; ++ ++ /* Some hooks are called more than once but the test only check if any ++ is called at least once. */ ++ FILE *out = fmemopen (result.err.buffer, result.err.length, "r"); ++ TEST_VERIFY (out != NULL); ++ char *buffer = NULL; ++ size_t buffer_length = 0; ++ while (xgetline (&buffer, &buffer_length, out)) ++ { ++ for (int i = 0; i < array_length (audit_iface); i++) ++ if (strncmp (buffer, audit_iface[i].name, ++ strlen (audit_iface[i].name)) == 0) ++ audit_iface[i].found = true; ++ } ++ free (buffer); ++ xfclose (out); ++ ++ for (int i = 0; i < array_length (audit_iface); i++) ++ TEST_COMPARE (audit_iface[i].found, true); ++ ++ support_capture_subprocess_free (&result); ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION_ARGV do_test ++#include +diff --git a/elf/tst-audit18mod.c b/elf/tst-audit18mod.c +new file mode 100644 +index 0000000000000000..096a9167c9f8353f +--- /dev/null ++++ b/elf/tst-audit18mod.c +@@ -0,0 +1,23 @@ ++/* Check DT_AUDIT with dlmopen. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++int ++foo (void) ++{ ++ return 10; ++} +diff --git a/elf/tst-auditmod18.c b/elf/tst-auditmod18.c +new file mode 100644 +index 0000000000000000..182992e9fdb1620c +--- /dev/null ++++ b/elf/tst-auditmod18.c +@@ -0,0 +1,73 @@ ++/* Check DT_AUDIT with dlmopen. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ fprintf (stderr, "%s\n", __func__); ++ return LAV_CURRENT; ++} ++ ++char * ++la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) ++{ ++ fprintf (stderr, "%s\n", __func__); ++ return (char *) name; ++} ++ ++void ++la_activity (uintptr_t *cookie, unsigned int flag) ++{ ++ fprintf (stderr, "%s\n", __func__); ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ fprintf (stderr, "%s\n", __func__); ++ return LA_FLG_BINDTO | LA_FLG_BINDFROM; ++} ++ ++unsigned int ++la_objclose (uintptr_t *cookie) ++{ ++ fprintf (stderr, "%s\n", __func__); ++ return 0; ++} ++ ++void ++la_preinit (uintptr_t *cookie) ++{ ++ fprintf (stderr, "%s\n", __func__); ++} ++ ++uintptr_t ++#if __ELF_NATIVE_CLASS == 32 ++la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, unsigned int *flags, const char *symname) ++#else ++la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, unsigned int *flags, const char *symname) ++#endif ++{ ++ fprintf (stderr, "%s\n", __func__); ++ return sym->st_value; ++} diff --git a/SOURCES/glibc-upstream-2.34-142.patch b/SOURCES/glibc-upstream-2.34-142.patch new file mode 100644 index 0000000..20e72f1 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-142.patch @@ -0,0 +1,159 @@ +commit ce0cb6d1d2daac2d58006a41c3d19c551b86f255 +Author: Adhemerval Zanella +Date: Mon Jul 19 15:47:51 2021 -0300 + + elf: Add _dl_audit_objopen + + It consolidates the code required to call la_objopen audit callback. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit aee6e90f93e285016b6cd9c8bd00402c19ba271b) + + Resolved conflicts: + elf/Makefile + +diff --git a/elf/Makefile b/elf/Makefile +index bf6da98bdd15a18d..85165c0591412a45 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -118,6 +118,7 @@ elide-routines.os = \ + # interpreter and operating independent of libc. + rtld-routines = \ + $(all-dl-routines) \ ++ dl-audit \ + dl-compat \ + dl-conflict \ + dl-diagnostics \ +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +new file mode 100644 +index 0000000000000000..4066dfe85146b9d4 +--- /dev/null ++++ b/elf/dl-audit.c +@@ -0,0 +1,39 @@ ++/* Audit common functions. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++_dl_audit_objopen (struct link_map *l, Lmid_t nsid) ++{ ++ if (__glibc_likely (GLRO(dl_naudit) == 0)) ++ return; ++ ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ if (afct->objopen != NULL) ++ { ++ struct auditstate *state = link_map_audit_state (l, cnt); ++ state->bindflags = afct->objopen (l, nsid, &state->cookie); ++ l->l_audit_any_plt |= state->bindflags != 0; ++ } ++ ++ afct = afct->next; ++ } ++} +diff --git a/elf/dl-load.c b/elf/dl-load.c +index a8c6df3959f2b331..a2d73d025c65cd79 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1515,22 +1515,8 @@ cannot enable executable stack as shared object requires"); + + #ifdef SHARED + /* Auditing checkpoint: we have a new object. */ +- if (__glibc_unlikely (GLRO(dl_naudit) > 0) +- && !GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->objopen != NULL) +- { +- struct auditstate *state = link_map_audit_state (l, cnt); +- state->bindflags = afct->objopen (l, nsid, &state->cookie); +- l->l_audit_any_plt |= state->bindflags != 0; +- } +- +- afct = afct->next; +- } +- } ++ if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing) ++ _dl_audit_objopen (l, nsid); + #endif + + return l; +diff --git a/elf/rtld.c b/elf/rtld.c +index ad5ddb2a0ab94e7f..45fec0df3043b90a 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1064,25 +1064,6 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d); + dlmargs.map->l_auditing = 1; + } + +-/* Notify the the audit modules that the object MAP has already been +- loaded. */ +-static void +-notify_audit_modules_of_loaded_object (struct link_map *map) +-{ +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->objopen != NULL) +- { +- struct auditstate *state = link_map_audit_state (map, cnt); +- state->bindflags = afct->objopen (map, LM_ID_BASE, &state->cookie); +- map->l_audit_any_plt |= state->bindflags != 0; +- } +- +- afct = afct->next; +- } +-} +- + /* Load all audit modules. */ + static void + load_audit_modules (struct link_map *main_map, struct audit_list *audit_list) +@@ -1101,8 +1082,8 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list) + program and the dynamic linker itself). */ + if (GLRO(dl_naudit) > 0) + { +- notify_audit_modules_of_loaded_object (main_map); +- notify_audit_modules_of_loaded_object (&GL(dl_rtld_map)); ++ _dl_audit_objopen (main_map, LM_ID_BASE); ++ _dl_audit_objopen (&GL(dl_rtld_map), LM_ID_BASE); + } + } + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index bcf1f199c5985c65..5709e4e48dff4355 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1372,6 +1372,11 @@ link_map_audit_state (struct link_map *l, size_t index) + return &base[index]; + } + } ++ ++/* Call the la_objopen from the audit modules for the link_map L on the ++ namespace identification NSID. */ ++void _dl_audit_objopen (struct link_map *l, Lmid_t nsid) ++ attribute_hidden; + #endif /* SHARED */ + + #if PTHREAD_IN_LIBC && defined SHARED diff --git a/SOURCES/glibc-upstream-2.34-143.patch b/SOURCES/glibc-upstream-2.34-143.patch new file mode 100644 index 0000000..d93c0cb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-143.patch @@ -0,0 +1,254 @@ +commit 66e9d27a090874ab93030a908eb86fc29f856151 +Author: Adhemerval Zanella +Date: Tue Jul 20 11:03:34 2021 -0300 + + elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid + + It consolidates the code required to call la_activity audit + callback. + + Also for a new Lmid_t the namespace link_map list are empty, so it + requires to check if before using it. This can happen for when audit + module is used along with dlmopen. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit 3dac3959a5cb585b065cef2cb8a8d909c907e202) + +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +index 4066dfe85146b9d4..74b87f4b39be75e1 100644 +--- a/elf/dl-audit.c ++++ b/elf/dl-audit.c +@@ -18,6 +18,32 @@ + + #include + ++void ++_dl_audit_activity_map (struct link_map *l, int action) ++{ ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ if (afct->activity != NULL) ++ afct->activity (&link_map_audit_state (l, cnt)->cookie, action); ++ afct = afct->next; ++ } ++} ++ ++void ++_dl_audit_activity_nsid (Lmid_t nsid, int action) ++{ ++ /* If head is NULL, the namespace has become empty, and the audit interface ++ does not give us a way to signal LA_ACT_CONSISTENT for it because the ++ first loaded module is used to identify the namespace. */ ++ struct link_map *head = GL(dl_ns)[nsid]._ns_loaded; ++ if (__glibc_likely (GLRO(dl_naudit) == 0) ++ || head == NULL || head->l_auditing) ++ return; ++ ++ _dl_audit_activity_map (head, action); ++} ++ + void + _dl_audit_objopen (struct link_map *l, Lmid_t nsid) + { +diff --git a/elf/dl-close.c b/elf/dl-close.c +index f6fbf9de7d78555b..5a8cc9e7cb5186cc 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -472,25 +472,7 @@ _dl_close_worker (struct link_map *map, bool force) + + #ifdef SHARED + /* Auditing checkpoint: we will start deleting objects. */ +- if (__glibc_unlikely (do_audit)) +- { +- struct link_map *head = ns->_ns_loaded; +- struct audit_ifaces *afct = GLRO(dl_audit); +- /* Do not call the functions for any auditing object. */ +- if (head->l_auditing == 0) +- { +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->activity != NULL) +- { +- struct auditstate *state = link_map_audit_state (head, cnt); +- afct->activity (&state->cookie, LA_ACT_DELETE); +- } +- +- afct = afct->next; +- } +- } +- } ++ _dl_audit_activity_nsid (nsid, LA_ACT_DELETE); + #endif + + /* Notify the debugger we are about to remove some loaded objects. */ +@@ -785,32 +767,9 @@ _dl_close_worker (struct link_map *map, bool force) + __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); + + #ifdef SHARED +- /* Auditing checkpoint: we have deleted all objects. */ +- if (__glibc_unlikely (do_audit)) +- { +- struct link_map *head = ns->_ns_loaded; +- /* If head is NULL, the namespace has become empty, and the +- audit interface does not give us a way to signal +- LA_ACT_CONSISTENT for it because the first loaded module is +- used to identify the namespace. +- +- Furthermore, do not notify auditors of the cleanup of a +- failed audit module loading attempt. */ +- if (head != NULL && head->l_auditing == 0) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->activity != NULL) +- { +- struct auditstate *state = link_map_audit_state (head, cnt); +- afct->activity (&state->cookie, LA_ACT_CONSISTENT); +- } +- +- afct = afct->next; +- } +- } +- } ++ /* Auditing checkpoint: we have deleted all objects. Also, do not notify ++ auditors of the cleanup of a failed audit module loading attempt. */ ++ _dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT); + #endif + + if (__builtin_expect (ns->_ns_loaded == NULL, 0) +diff --git a/elf/dl-load.c b/elf/dl-load.c +index a2d73d025c65cd79..baf0a926053deaed 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1482,24 +1482,8 @@ cannot enable executable stack as shared object requires"); + /* Auditing checkpoint: we are going to add new objects. Since this + is called after _dl_add_to_namespace_list the namespace is guaranteed + to not be empty. */ +- if ((mode & __RTLD_AUDIT) == 0 +- && __glibc_unlikely (GLRO(dl_naudit) > 0)) +- { +- struct link_map *head = GL(dl_ns)[nsid]._ns_loaded; +- /* Do not call the functions for any auditing object. */ +- if (head->l_auditing == 0) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->activity != NULL) +- afct->activity (&link_map_audit_state (head, cnt)->cookie, +- LA_ACT_ADD); +- +- afct = afct->next; +- } +- } +- } ++ if ((mode & __RTLD_AUDIT) == 0) ++ _dl_audit_activity_nsid (nsid, LA_ACT_ADD); + #endif + + /* Notify the debugger we have added some objects. We need to +diff --git a/elf/dl-open.c b/elf/dl-open.c +index bc68e2c376debd71..3f01aa480730da13 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -611,25 +611,7 @@ dl_open_worker_begin (void *a) + + #ifdef SHARED + /* Auditing checkpoint: we have added all objects. */ +- if (__glibc_unlikely (GLRO(dl_naudit) > 0)) +- { +- struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded; +- /* Do not call the functions for any auditing object. */ +- if (head->l_auditing == 0) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->activity != NULL) +- { +- struct auditstate *state = link_map_audit_state (head, cnt); +- afct->activity (&state->cookie, LA_ACT_CONSISTENT); +- } +- +- afct = afct->next; +- } +- } +- } ++ _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT); + #endif + + /* Notify the debugger all new objects are now ready to go. */ +diff --git a/elf/rtld.c b/elf/rtld.c +index 45fec0df3043b90a..b6bb46ca97b7972f 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1804,18 +1804,7 @@ dl_main (const ElfW(Phdr) *phdr, + + /* Auditing checkpoint: we are ready to signal that the initial map + is being constructed. */ +- if (__glibc_unlikely (GLRO(dl_naudit) > 0)) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->activity != NULL) +- afct->activity (&link_map_audit_state (main_map, cnt)->cookie, +- LA_ACT_ADD); +- +- afct = afct->next; +- } +- } ++ _dl_audit_activity_map (main_map, LA_ACT_ADD); + + /* We have two ways to specify objects to preload: via environment + variable and via the file /etc/ld.so.preload. The latter can also +@@ -2496,23 +2485,7 @@ dl_main (const ElfW(Phdr) *phdr, + + #ifdef SHARED + /* Auditing checkpoint: we have added all objects. */ +- if (__glibc_unlikely (GLRO(dl_naudit) > 0)) +- { +- struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded; +- /* Do not call the functions for any auditing object. */ +- if (head->l_auditing == 0) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->activity != NULL) +- afct->activity (&link_map_audit_state (head, cnt)->cookie, +- LA_ACT_CONSISTENT); +- +- afct = afct->next; +- } +- } +- } ++ _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT); + #endif + + /* Notify the debugger all new objects are now ready to go. We must re-get +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 5709e4e48dff4355..7384abcf5e0e8e24 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1373,6 +1373,16 @@ link_map_audit_state (struct link_map *l, size_t index) + } + } + ++/* Call the la_activity from the audit modules from the link map L and issues ++ the ACTION argument. */ ++void _dl_audit_activity_map (struct link_map *l, int action) ++ attribute_hidden; ++ ++/* Call the la_activity from the audit modules from the link map from the ++ namespace NSID and issues the ACTION argument. */ ++void _dl_audit_activity_nsid (Lmid_t nsid, int action) ++ attribute_hidden; ++ + /* Call the la_objopen from the audit modules for the link_map L on the + namespace identification NSID. */ + void _dl_audit_objopen (struct link_map *l, Lmid_t nsid) diff --git a/SOURCES/glibc-upstream-2.34-144.patch b/SOURCES/glibc-upstream-2.34-144.patch new file mode 100644 index 0000000..62ab51c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-144.patch @@ -0,0 +1,157 @@ +commit ec0fc2a15358dc5f7191f9994f04b1385d14377d +Author: Adhemerval Zanella +Date: Tue Jul 20 13:47:36 2021 -0300 + + elf: Add _dl_audit_objsearch + + It consolidates the code required to call la_objsearch audit + callback. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit c91008d3490e4e3ce29520068405f081f0d368ca) + +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +index 74b87f4b39be75e1..5682427220569d90 100644 +--- a/elf/dl-audit.c ++++ b/elf/dl-audit.c +@@ -44,6 +44,28 @@ _dl_audit_activity_nsid (Lmid_t nsid, int action) + _dl_audit_activity_map (head, action); + } + ++const char * ++_dl_audit_objsearch (const char *name, struct link_map *l, unsigned int code) ++{ ++ if (l == NULL || l->l_auditing || code == 0) ++ return name; ++ ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ if (afct->objsearch != NULL) ++ { ++ struct auditstate *state = link_map_audit_state (l, cnt); ++ name = afct->objsearch (name, &state->cookie, code); ++ if (name == NULL) ++ return NULL; ++ } ++ afct = afct->next; ++ } ++ ++ return name; ++} ++ + void + _dl_audit_objopen (struct link_map *l, Lmid_t nsid) + { +diff --git a/elf/dl-load.c b/elf/dl-load.c +index baf0a926053deaed..eb6b658b698f5694 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1596,32 +1596,20 @@ open_verify (const char *name, int fd, + + #ifdef SHARED + /* Give the auditing libraries a chance. */ +- if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0 +- && loader->l_auditing == 0) ++ if (__glibc_unlikely (GLRO(dl_naudit) > 0)) + { + const char *original_name = name; +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->objsearch != NULL) +- { +- struct auditstate *state = link_map_audit_state (loader, cnt); +- name = afct->objsearch (name, &state->cookie, whatcode); +- if (name == NULL) +- /* Ignore the path. */ +- return -1; +- } +- +- afct = afct->next; +- } ++ name = _dl_audit_objsearch (name, loader, whatcode); ++ if (name == NULL) ++ return -1; + + if (fd != -1 && name != original_name && strcmp (name, original_name)) +- { +- /* An audit library changed what we're supposed to open, +- so FD no longer matches it. */ +- __close_nocancel (fd); +- fd = -1; +- } ++ { ++ /* An audit library changed what we're supposed to open, ++ so FD no longer matches it. */ ++ __close_nocancel (fd); ++ fd = -1; ++ } + } + #endif + +@@ -2060,36 +2048,17 @@ _dl_map_object (struct link_map *loader, const char *name, + #ifdef SHARED + /* Give the auditing libraries a chance to change the name before we + try anything. */ +- if (__glibc_unlikely (GLRO(dl_naudit) > 0) +- && (loader == NULL || loader->l_auditing == 0)) ++ if (__glibc_unlikely (GLRO(dl_naudit) > 0)) + { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ const char *before = name; ++ name = _dl_audit_objsearch (name, loader, LA_SER_ORIG); ++ if (name == NULL) + { +- if (afct->objsearch != NULL) +- { +- const char *before = name; +- struct auditstate *state = link_map_audit_state (loader, cnt); +- name = afct->objsearch (name, &state->cookie, LA_SER_ORIG); +- if (name == NULL) +- { +- /* Do not try anything further. */ +- fd = -1; +- goto no_file; +- } +- if (before != name && strcmp (before, name) != 0) +- { +- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) +- _dl_debug_printf ("audit changed filename %s -> %s\n", +- before, name); +- +- if (origname == NULL) +- origname = before; +- } +- } +- +- afct = afct->next; ++ fd = -1; ++ goto no_file; + } ++ if (before != name && strcmp (before, name) != 0) ++ origname = before; + } + #endif + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 7384abcf5e0e8e24..1f212a18d7bfc440 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1373,6 +1373,13 @@ link_map_audit_state (struct link_map *l, size_t index) + } + } + ++/* Call the la_objsearch from the audit modules from the link map L. If ++ ORIGNAME is non NULL, it is updated with the revious name prior calling ++ la_objsearch. */ ++const char *_dl_audit_objsearch (const char *name, struct link_map *l, ++ unsigned int code) ++ attribute_hidden; ++ + /* Call the la_activity from the audit modules from the link map L and issues + the ACTION argument. */ + void _dl_audit_activity_map (struct link_map *l, int action) diff --git a/SOURCES/glibc-upstream-2.34-145.patch b/SOURCES/glibc-upstream-2.34-145.patch new file mode 100644 index 0000000..f429360 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-145.patch @@ -0,0 +1,123 @@ +commit 198660741b23ec9defb19e22951d4a721de603c8 +Author: Adhemerval Zanella +Date: Tue Jul 20 14:04:51 2021 -0300 + + elf: Add _dl_audit_objclose + + It consolidates the code required to call la_objclose audit + callback. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit 311c9ee54ea963ff69bd3a2e6981c37e893b4c3e) + +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +index 5682427220569d90..cb1c3de93cba447b 100644 +--- a/elf/dl-audit.c ++++ b/elf/dl-audit.c +@@ -85,3 +85,24 @@ _dl_audit_objopen (struct link_map *l, Lmid_t nsid) + afct = afct->next; + } + } ++ ++void ++_dl_audit_objclose (struct link_map *l) ++{ ++ if (__glibc_likely (GLRO(dl_naudit) == 0) ++ || GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing) ++ return; ++ ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ if (afct->objclose != NULL) ++ { ++ struct auditstate *state= link_map_audit_state (l, cnt); ++ /* Return value is ignored. */ ++ afct->objclose (&state->cookie); ++ } ++ ++ afct = afct->next; ++ } ++} +diff --git a/elf/dl-close.c b/elf/dl-close.c +index 5a8cc9e7cb5186cc..985cd4e2821436af 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -260,9 +260,6 @@ _dl_close_worker (struct link_map *map, bool force) + _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true); + + /* Call all termination functions at once. */ +-#ifdef SHARED +- bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing; +-#endif + bool unload_any = false; + bool scope_mem_left = false; + unsigned int unload_global = 0; +@@ -296,22 +293,7 @@ _dl_close_worker (struct link_map *map, bool force) + + #ifdef SHARED + /* Auditing checkpoint: we remove an object. */ +- if (__glibc_unlikely (do_audit)) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->objclose != NULL) +- { +- struct auditstate *state +- = link_map_audit_state (imap, cnt); +- /* Return value is ignored. */ +- (void) afct->objclose (&state->cookie); +- } +- +- afct = afct->next; +- } +- } ++ _dl_audit_objclose (imap); + #endif + + /* This object must not be used anymore. */ +diff --git a/elf/dl-fini.c b/elf/dl-fini.c +index c683884c355dfd52..b789cfb9f2ac6c85 100644 +--- a/elf/dl-fini.c ++++ b/elf/dl-fini.c +@@ -146,21 +146,7 @@ _dl_fini (void) + + #ifdef SHARED + /* Auditing checkpoint: another object closed. */ +- if (!do_audit && __builtin_expect (GLRO(dl_naudit) > 0, 0)) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->objclose != NULL) +- { +- struct auditstate *state +- = link_map_audit_state (l, cnt); +- /* Return value is ignored. */ +- (void) afct->objclose (&state->cookie); +- } +- afct = afct->next; +- } +- } ++ _dl_audit_objclose (l); + #endif + } + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 1f212a18d7bfc440..982f23c0287955fe 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1394,6 +1394,10 @@ void _dl_audit_activity_nsid (Lmid_t nsid, int action) + namespace identification NSID. */ + void _dl_audit_objopen (struct link_map *l, Lmid_t nsid) + attribute_hidden; ++ ++/* Call the la_objclose from the audit modules for the link_map L. */ ++void _dl_audit_objclose (struct link_map *l) ++ attribute_hidden; + #endif /* SHARED */ + + #if PTHREAD_IN_LIBC && defined SHARED diff --git a/SOURCES/glibc-upstream-2.34-146.patch b/SOURCES/glibc-upstream-2.34-146.patch new file mode 100644 index 0000000..4024ad2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-146.patch @@ -0,0 +1,334 @@ +commit b2d99731b6d27c719a30b8ffa931e91c73a6bb4b +Author: Adhemerval Zanella +Date: Tue Jul 20 15:58:35 2021 -0300 + + elf: Add _dl_audit_symbind_alt and _dl_audit_symbind + + It consolidates the code required to call la_symbind{32,64} audit + callback. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit cda4f265c65fb6c4ce38ca1cf0a7e527c5e77cd5) + +diff --git a/elf/Versions b/elf/Versions +index 2af210b8f771c950..164682eaeaa9a1da 100644 +--- a/elf/Versions ++++ b/elf/Versions +@@ -58,6 +58,7 @@ ld { + _dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info; + _dl_deallocate_tls; _dl_make_stack_executable; + _dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf; ++ _dl_audit_symbind_alt; + _rtld_global; _rtld_global_ro; + + # Only here for gdb while a better method is developed. +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +index cb1c3de93cba447b..a21530f30bc5524b 100644 +--- a/elf/dl-audit.c ++++ b/elf/dl-audit.c +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + + void +@@ -106,3 +107,124 @@ _dl_audit_objclose (struct link_map *l) + afct = afct->next; + } + } ++ ++void ++_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value, ++ lookup_t result) ++{ ++ if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0) ++ return; ++ ++ const char *strtab = (const char *) D_PTR (result, l_info[DT_STRTAB]); ++ /* Compute index of the symbol entry in the symbol table of the DSO with ++ the definition. */ ++ unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, l_info[DT_SYMTAB])); ++ ++ unsigned int altvalue = 0; ++ /* Synthesize a symbol record where the st_value field is the result. */ ++ ElfW(Sym) sym = *ref; ++ sym.st_value = (ElfW(Addr)) *value; ++ ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ struct auditstate *match_audit = link_map_audit_state (l, cnt); ++ struct auditstate *result_audit = link_map_audit_state (result, cnt); ++ if (afct->symbind != NULL ++ && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0 ++ || ((result_audit->bindflags & LA_FLG_BINDTO) ++ != 0))) ++ { ++ unsigned int flags = altvalue | LA_SYMB_DLSYM; ++ uintptr_t new_value = afct->symbind (&sym, ndx, ++ &match_audit->cookie, ++ &result_audit->cookie, ++ &flags, strtab + ref->st_name); ++ if (new_value != (uintptr_t) sym.st_value) ++ { ++ altvalue = LA_SYMB_ALTVALUE; ++ sym.st_value = new_value; ++ } ++ ++ afct = afct->next; ++ } ++ ++ *value = (void *) sym.st_value; ++ } ++} ++rtld_hidden_def (_dl_audit_symbind_alt) ++ ++void ++_dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, ++ const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, ++ lookup_t result) ++{ ++ reloc_result->bound = result; ++ /* Compute index of the symbol entry in the symbol table of the DSO with the ++ definition. */ ++ reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result, ++ l_info[DT_SYMTAB])); ++ ++ if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0) ++ { ++ /* Set all bits since this symbol binding is not interesting. */ ++ reloc_result->enterexit = (1u << DL_NNS) - 1; ++ return; ++ } ++ ++ /* Synthesize a symbol record where the st_value field is the result. */ ++ ElfW(Sym) sym = *defsym; ++ sym.st_value = DL_FIXUP_VALUE_ADDR (*value); ++ ++ /* Keep track whether there is any interest in tracing the call in the lower ++ two bits. */ ++ assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8); ++ assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3); ++ reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; ++ ++ const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); ++ ++ unsigned int flags = 0; ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ /* XXX Check whether both DSOs must request action or only one */ ++ struct auditstate *l_state = link_map_audit_state (l, cnt); ++ struct auditstate *result_state = link_map_audit_state (result, cnt); ++ if ((l_state->bindflags & LA_FLG_BINDFROM) != 0 ++ && (result_state->bindflags & LA_FLG_BINDTO) != 0) ++ { ++ if (afct->symbind != NULL) ++ { ++ uintptr_t new_value = afct->symbind (&sym, ++ reloc_result->boundndx, ++ &l_state->cookie, ++ &result_state->cookie, ++ &flags, ++ strtab2 + defsym->st_name); ++ if (new_value != (uintptr_t) sym.st_value) ++ { ++ flags |= LA_SYMB_ALTVALUE; ++ sym.st_value = new_value; ++ } ++ } ++ ++ /* Remember the results for every audit library and store a summary ++ in the first two bits. */ ++ reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER ++ | LA_SYMB_NOPLTEXIT); ++ reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER ++ | LA_SYMB_NOPLTEXIT)) ++ << ((cnt + 1) * 2)); ++ } ++ else ++ /* If the bind flags say this auditor is not interested, set the bits ++ manually. */ ++ reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ++ << ((cnt + 1) * 2)); ++ afct = afct->next; ++ } ++ ++ reloc_result->flags = flags; ++ *value = DL_FIXUP_ADDR_VALUE (sym.st_value); ++} +diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c +index 61c260ddb81b586c..c4413c9165cec8cb 100644 +--- a/elf/dl-runtime.c ++++ b/elf/dl-runtime.c +@@ -297,84 +297,7 @@ _dl_profile_fixup ( + auditing libraries the possibility to change the value and + tell us whether further auditing is wanted. */ + if (defsym != NULL && GLRO(dl_naudit) > 0) +- { +- reloc_result->bound = result; +- /* Compute index of the symbol entry in the symbol table of +- the DSO with the definition. */ +- reloc_result->boundndx = (defsym +- - (ElfW(Sym) *) D_PTR (result, +- l_info[DT_SYMTAB])); +- +- /* Determine whether any of the two participating DSOs is +- interested in auditing. */ +- if ((l->l_audit_any_plt | result->l_audit_any_plt) != 0) +- { +- unsigned int flags = 0; +- struct audit_ifaces *afct = GLRO(dl_audit); +- /* Synthesize a symbol record where the st_value field is +- the result. */ +- ElfW(Sym) sym = *defsym; +- sym.st_value = DL_FIXUP_VALUE_ADDR (value); +- +- /* Keep track whether there is any interest in tracing +- the call in the lower two bits. */ +- assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8); +- assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3); +- reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; +- +- const char *strtab2 = (const void *) D_PTR (result, +- l_info[DT_STRTAB]); +- +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- /* XXX Check whether both DSOs must request action or +- only one */ +- struct auditstate *l_state = link_map_audit_state (l, cnt); +- struct auditstate *result_state +- = link_map_audit_state (result, cnt); +- if ((l_state->bindflags & LA_FLG_BINDFROM) != 0 +- && (result_state->bindflags & LA_FLG_BINDTO) != 0) +- { +- if (afct->symbind != NULL) +- { +- uintptr_t new_value +- = afct->symbind (&sym, reloc_result->boundndx, +- &l_state->cookie, +- &result_state->cookie, +- &flags, +- strtab2 + defsym->st_name); +- if (new_value != (uintptr_t) sym.st_value) +- { +- flags |= LA_SYMB_ALTVALUE; +- sym.st_value = new_value; +- } +- } +- +- /* Remember the results for every audit library and +- store a summary in the first two bits. */ +- reloc_result->enterexit +- &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT); +- reloc_result->enterexit +- |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) +- << ((cnt + 1) * 2)); +- } +- else +- /* If the bind flags say this auditor is not interested, +- set the bits manually. */ +- reloc_result->enterexit +- |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) +- << ((cnt + 1) * 2)); +- +- afct = afct->next; +- } +- +- reloc_result->flags = flags; +- value = DL_FIXUP_ADDR_VALUE (sym.st_value); +- } +- else +- /* Set all bits since this symbol binding is not interesting. */ +- reloc_result->enterexit = (1u << DL_NNS) - 1; +- } ++ _dl_audit_symbind (l, reloc_result, defsym, &value, result); + #endif + + /* Store the result for later runs. */ +diff --git a/elf/dl-sym-post.h b/elf/dl-sym-post.h +index d68c2d2b1cd43c9b..a11095d3e8c3c937 100644 +--- a/elf/dl-sym-post.h ++++ b/elf/dl-sym-post.h +@@ -52,54 +52,9 @@ _dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value, + tell us whether further auditing is wanted. */ + if (__glibc_unlikely (GLRO(dl_naudit) > 0)) + { +- const char *strtab = (const char *) D_PTR (result, +- l_info[DT_STRTAB]); +- /* Compute index of the symbol entry in the symbol table of +- the DSO with the definition. */ +- unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, +- l_info[DT_SYMTAB])); +- + if (match == NULL) + match = _dl_sym_find_caller_link_map (caller); +- +- if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0) +- { +- unsigned int altvalue = 0; +- struct audit_ifaces *afct = GLRO(dl_audit); +- /* Synthesize a symbol record where the st_value field is +- the result. */ +- ElfW(Sym) sym = *ref; +- sym.st_value = (ElfW(Addr)) value; +- +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- struct auditstate *match_audit +- = link_map_audit_state (match, cnt); +- struct auditstate *result_audit +- = link_map_audit_state (result, cnt); +- if (afct->symbind != NULL +- && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0 +- || ((result_audit->bindflags & LA_FLG_BINDTO) +- != 0))) +- { +- unsigned int flags = altvalue | LA_SYMB_DLSYM; +- uintptr_t new_value +- = afct->symbind (&sym, ndx, +- &match_audit->cookie, +- &result_audit->cookie, +- &flags, strtab + ref->st_name); +- if (new_value != (uintptr_t) sym.st_value) +- { +- altvalue = LA_SYMB_ALTVALUE; +- sym.st_value = new_value; +- } +- } +- +- afct = afct->next; +- } +- +- value = (void *) sym.st_value; +- } ++ _dl_audit_symbind_alt (match, ref, &value, result); + } + #endif + return value; +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 982f23c0287955fe..61f1dfb3f79a613a 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1398,6 +1398,16 @@ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid) + /* Call the la_objclose from the audit modules for the link_map L. */ + void _dl_audit_objclose (struct link_map *l) + attribute_hidden; ++ ++/* Call the la_symbind{32,64} from the audit modules for the link_map L. */ ++void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, ++ const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, ++ lookup_t result) ++ attribute_hidden; ++/* Same as _dl_audit_symbind, but also sets LA_SYMB_DLSYM flag. */ ++void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, ++ void **value, lookup_t result); ++rtld_hidden_proto (_dl_audit_symbind_alt) + #endif /* SHARED */ + + #if PTHREAD_IN_LIBC && defined SHARED diff --git a/SOURCES/glibc-upstream-2.34-147.patch b/SOURCES/glibc-upstream-2.34-147.patch new file mode 100644 index 0000000..5c93ad3 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-147.patch @@ -0,0 +1,107 @@ +commit 31473c273be14270f8eef68e35c03fd2305eb2c3 +Author: Adhemerval Zanella +Date: Thu Jul 22 17:10:57 2021 -0300 + + elf: Add _dl_audit_preinit + + It consolidates the code required to call la_preinit audit + callback. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit 0b98a8748759e88b58927882a8714109abe0a2d6) + +diff --git a/csu/libc-start.c b/csu/libc-start.c +index 0350b006fdcc22d2..d01e57ea59ceb880 100644 +--- a/csu/libc-start.c ++++ b/csu/libc-start.c +@@ -377,32 +377,15 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), + /* This is a current program. Use the dynamic segment to find + constructors. */ + call_init (argc, argv, __environ); +-#else /* !SHARED */ +- call_init (argc, argv, __environ); +-#endif /* SHARED */ + +-#ifdef SHARED + /* Auditing checkpoint: we have a new object. */ +- if (__glibc_unlikely (GLRO(dl_naudit) > 0)) +- { +- struct audit_ifaces *afct = GLRO(dl_audit); +- struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded; +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->preinit != NULL) +- afct->preinit (&link_map_audit_state (head, cnt)->cookie); +- +- afct = afct->next; +- } +- } +-#endif ++ _dl_audit_preinit (GL(dl_ns)[LM_ID_BASE]._ns_loaded); + +-#ifdef SHARED + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) + GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]); +-#endif ++#else /* !SHARED */ ++ call_init (argc, argv, __environ); + +-#ifndef SHARED + _dl_debug_initialize (0, LM_ID_BASE); + #endif + +diff --git a/elf/Versions b/elf/Versions +index 164682eaeaa9a1da..bb6697647b397772 100644 +--- a/elf/Versions ++++ b/elf/Versions +@@ -58,7 +58,7 @@ ld { + _dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info; + _dl_deallocate_tls; _dl_make_stack_executable; + _dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf; +- _dl_audit_symbind_alt; ++ _dl_audit_symbind_alt; _dl_audit_preinit; + _rtld_global; _rtld_global_ro; + + # Only here for gdb while a better method is developed. +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +index a21530f30bc5524b..0b6fac8e48877c93 100644 +--- a/elf/dl-audit.c ++++ b/elf/dl-audit.c +@@ -108,6 +108,21 @@ _dl_audit_objclose (struct link_map *l) + } + } + ++void ++_dl_audit_preinit (struct link_map *l) ++{ ++ if (__glibc_likely (GLRO(dl_naudit) == 0)) ++ return; ++ ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ if (afct->preinit != NULL) ++ afct->preinit (&link_map_audit_state (l, cnt)->cookie); ++ afct = afct->next; ++ } ++} ++ + void + _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value, + lookup_t result) +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 61f1dfb3f79a613a..91193a036fc5c6ef 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1399,6 +1399,9 @@ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid) + void _dl_audit_objclose (struct link_map *l) + attribute_hidden; + ++/* Call the la_preinit from the audit modules for the link_map L. */ ++void _dl_audit_preinit (struct link_map *l); ++ + /* Call the la_symbind{32,64} from the audit modules for the link_map L. */ + void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, + const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, diff --git a/SOURCES/glibc-upstream-2.34-148.patch b/SOURCES/glibc-upstream-2.34-148.patch new file mode 100644 index 0000000..11ffb9f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-148.patch @@ -0,0 +1,206 @@ +commit fd9c4e8a1b72fa1372855051217f9480680d882a +Author: Adhemerval Zanella +Date: Thu Jul 22 17:45:33 2021 -0300 + + elf: Add _dl_audit_pltenter + + It consolidates the code required to call la_pltenter audit + callback. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit eff687e8462b0eaf65992a6031b54a4b1cd16796) + +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +index 0b6fac8e48877c93..15250c67e8ac1658 100644 +--- a/elf/dl-audit.c ++++ b/elf/dl-audit.c +@@ -17,7 +17,9 @@ + . */ + + #include ++#include + #include ++#include + + void + _dl_audit_activity_map (struct link_map *l, int action) +@@ -243,3 +245,78 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, + reloc_result->flags = flags; + *value = DL_FIXUP_ADDR_VALUE (sym.st_value); + } ++ ++void ++_dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result, ++ DL_FIXUP_VALUE_TYPE *value, void *regs, long int *framesize) ++{ ++ /* Don't do anything if no auditor wants to intercept this call. */ ++ if (GLRO(dl_naudit) == 0 ++ || (reloc_result->enterexit & LA_SYMB_NOPLTENTER)) ++ return; ++ ++ /* 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); ++ ++ /* Set up the sym parameter. */ ++ ElfW(Sym) sym = *defsym; ++ sym.st_value = DL_FIXUP_VALUE_ADDR (*value); ++ ++ /* Get the symbol name. */ ++ const char *strtab = (const void *) D_PTR (reloc_result->bound, ++ l_info[DT_STRTAB]); ++ const char *symname = strtab + sym.st_name; ++ ++ /* Keep track of overwritten addresses. */ ++ unsigned int flags = reloc_result->flags; ++ ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ if (afct->ARCH_LA_PLTENTER != NULL ++ && (reloc_result->enterexit ++ & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0) ++ { ++ long int new_framesize = -1; ++ struct auditstate *l_state = link_map_audit_state (l, cnt); ++ struct auditstate *bound_state ++ = link_map_audit_state (reloc_result->bound, cnt); ++ uintptr_t new_value ++ = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx, ++ &l_state->cookie, &bound_state->cookie, ++ regs, &flags, symname, &new_framesize); ++ if (new_value != (uintptr_t) sym.st_value) ++ { ++ flags |= LA_SYMB_ALTVALUE; ++ sym.st_value = new_value; ++ } ++ ++ /* Remember the results for every audit library and store a summary ++ in the first two bits. */ ++ reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER ++ | LA_SYMB_NOPLTEXIT)) ++ << (2 * (cnt + 1))); ++ ++ if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT ++ << (2 * (cnt + 1)))) ++ == 0 && new_framesize != -1 && *framesize != -2) ++ { ++ /* If this is the first call providing information, use it. */ ++ if (*framesize == -1) ++ *framesize = new_framesize; ++ /* If two pltenter calls provide conflicting information, use ++ the larger value. */ ++ else if (new_framesize != *framesize) ++ *framesize = MAX (new_framesize, *framesize); ++ } ++ } ++ ++ afct = afct->next; ++ } ++ ++ *value = DL_FIXUP_ADDR_VALUE (sym.st_value); ++} +diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c +index c4413c9165cec8cb..dfedeaf2dd1c7253 100644 +--- a/elf/dl-runtime.c ++++ b/elf/dl-runtime.c +@@ -320,78 +320,7 @@ _dl_profile_fixup ( + #ifdef SHARED + /* Auditing checkpoint: report the PLT entering and allow the + auditors to change the value. */ +- 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); +- +- /* Set up the sym parameter. */ +- ElfW(Sym) sym = *defsym; +- sym.st_value = DL_FIXUP_VALUE_ADDR (value); +- +- /* Get the symbol name. */ +- const char *strtab = (const void *) D_PTR (reloc_result->bound, +- l_info[DT_STRTAB]); +- const char *symname = strtab + sym.st_name; +- +- /* Keep track of overwritten addresses. */ +- unsigned int flags = reloc_result->flags; +- +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->ARCH_LA_PLTENTER != NULL +- && (reloc_result->enterexit +- & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0) +- { +- long int new_framesize = -1; +- struct auditstate *l_state = link_map_audit_state (l, cnt); +- struct auditstate *bound_state +- = link_map_audit_state (reloc_result->bound, cnt); +- uintptr_t new_value +- = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx, +- &l_state->cookie, +- &bound_state->cookie, +- regs, &flags, symname, +- &new_framesize); +- if (new_value != (uintptr_t) sym.st_value) +- { +- flags |= LA_SYMB_ALTVALUE; +- sym.st_value = new_value; +- } +- +- /* Remember the results for every audit library and +- store a summary in the first two bits. */ +- reloc_result->enterexit +- |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) +- << (2 * (cnt + 1))); +- +- if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT +- << (2 * (cnt + 1)))) +- == 0 && new_framesize != -1 && framesize != -2) +- { +- /* If this is the first call providing information, +- use it. */ +- if (framesize == -1) +- framesize = new_framesize; +- /* If two pltenter calls provide conflicting information, +- use the larger value. */ +- else if (new_framesize != framesize) +- framesize = MAX (new_framesize, framesize); +- } +- } +- +- afct = afct->next; +- } +- +- value = DL_FIXUP_ADDR_VALUE (sym.st_value); +- } ++ _dl_audit_pltenter (l, reloc_result, &value, regs, &framesize); + #endif + + /* Store the frame size information. */ +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 91193a036fc5c6ef..ea187dd266f14e06 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1411,6 +1411,10 @@ void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, + void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, + void **value, lookup_t result); + rtld_hidden_proto (_dl_audit_symbind_alt) ++void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result, ++ DL_FIXUP_VALUE_TYPE *value, void *regs, ++ long int *framesize) ++ attribute_hidden; + #endif /* SHARED */ + + #if PTHREAD_IN_LIBC && defined SHARED diff --git a/SOURCES/glibc-upstream-2.34-149.patch b/SOURCES/glibc-upstream-2.34-149.patch new file mode 100644 index 0000000..927d0e7 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-149.patch @@ -0,0 +1,715 @@ +commit a8e211daea6bdb505b10319ed3492e7d871c1e75 +Author: Adhemerval Zanella +Date: Thu Jul 22 18:02:42 2021 -0300 + + elf: Add _dl_audit_pltexit + + It consolidates the code required to call la_pltexit audit + callback. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit 8c0664e2b861fd3789602cc0b0b1922b0e20cb3a) + + Resolved conflicts: + sysdeps/hppa/dl-runtime.c + +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +index 15250c67e8ac1658..152712b12fed6de2 100644 +--- a/elf/dl-audit.c ++++ b/elf/dl-audit.c +@@ -20,6 +20,8 @@ + #include + #include + #include ++#include ++#include + + void + _dl_audit_activity_map (struct link_map *l, int action) +@@ -320,3 +322,48 @@ _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result, + + *value = DL_FIXUP_ADDR_VALUE (sym.st_value); + } ++ ++void ++DL_ARCH_FIXUP_ATTRIBUTE ++_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg, ++ const void *inregs, void *outregs) ++{ ++ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]); ++ ++ /* This is the address in the array where we store the result of previous ++ relocations. */ ++ // XXX Maybe the bound information must be stored on the stack since ++ // XXX with bind_not a new value could have been stored in the meantime. ++ struct reloc_result *reloc_result = ++ &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))]; ++ ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, ++ l_info[DT_SYMTAB]) ++ + reloc_result->boundndx); ++ ++ /* Set up the sym parameter. */ ++ ElfW(Sym) sym = *defsym; ++ sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr); ++ ++ /* Get the symbol name. */ ++ const char *strtab = (const void *) D_PTR (reloc_result->bound, ++ l_info[DT_STRTAB]); ++ const char *symname = strtab + sym.st_name; ++ ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ if (afct->ARCH_LA_PLTEXIT != NULL ++ && (reloc_result->enterexit ++ & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0) ++ { ++ struct auditstate *l_state = link_map_audit_state (l, cnt); ++ struct auditstate *bound_state ++ = link_map_audit_state (reloc_result->bound, cnt); ++ afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx, ++ &l_state->cookie, &bound_state->cookie, ++ inregs, outregs, symname); ++ } ++ ++ afct = afct->next; ++ } ++} +diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c +index dfedeaf2dd1c7253..e42f6e8b8dfca08e 100644 +--- a/elf/dl-runtime.c ++++ b/elf/dl-runtime.c +@@ -16,8 +16,6 @@ + License along with the GNU C Library; if not, see + . */ + +-#define IN_DL_RUNTIME 1 /* This can be tested in dl-machine.h. */ +- + #include + #include + #include +@@ -31,19 +29,6 @@ + #include + + +-#if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \ +- || ELF_MACHINE_NO_REL +-# define PLTREL ElfW(Rela) +-#else +-# define PLTREL ElfW(Rel) +-#endif +- +-/* The fixup functions might have need special attributes. If none +- are provided define the macro as empty. */ +-#ifndef ARCH_FIXUP_ATTRIBUTE +-# define ARCH_FIXUP_ATTRIBUTE +-#endif +- + /* This function is called through a special trampoline from the PLT the + first time each PLT entry is called. We must perform the relocation + specified in the PLT of the given shared object, and return the resolved +@@ -52,7 +37,7 @@ + function. */ + + DL_FIXUP_VALUE_TYPE +-attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE ++attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE + _dl_fixup ( + # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS + ELF_MACHINE_RUNTIME_FIXUP_ARGS, +@@ -148,7 +133,8 @@ _dl_fixup ( + + #ifndef PROF + DL_FIXUP_VALUE_TYPE +-__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE ++__attribute ((noinline)) ++DL_ARCH_FIXUP_ATTRIBUTE + _dl_profile_fixup ( + #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS + ELF_MACHINE_RUNTIME_FIXUP_ARGS, +@@ -332,52 +318,3 @@ _dl_profile_fixup ( + } + + #endif /* PROF */ +- +- +-#include +-void +-ARCH_FIXUP_ATTRIBUTE +-_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg, +- const void *inregs, void *outregs) +-{ +-#ifdef SHARED +- const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]); +- +- /* This is the address in the array where we store the result of previous +- relocations. */ +- // XXX Maybe the bound information must be stored on the stack since +- // XXX with bind_not a new value could have been stored in the meantime. +- struct reloc_result *reloc_result = +- &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))]; +- ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, +- l_info[DT_SYMTAB]) +- + reloc_result->boundndx); +- +- /* Set up the sym parameter. */ +- ElfW(Sym) sym = *defsym; +- sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr); +- +- /* Get the symbol name. */ +- const char *strtab = (const void *) D_PTR (reloc_result->bound, +- l_info[DT_STRTAB]); +- const char *symname = strtab + sym.st_name; +- +- struct audit_ifaces *afct = GLRO(dl_audit); +- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) +- { +- if (afct->ARCH_LA_PLTEXIT != NULL +- && (reloc_result->enterexit +- & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0) +- { +- struct auditstate *l_state = link_map_audit_state (l, cnt); +- struct auditstate *bound_state +- = link_map_audit_state (reloc_result->bound, cnt); +- afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx, +- &l_state->cookie, &bound_state->cookie, +- inregs, outregs, symname); +- } +- +- afct = afct->next; +- } +-#endif +-} +diff --git a/elf/dl-support.c b/elf/dl-support.c +index c5ee5d33aa7e1d65..f29dc965f4d10648 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -437,3 +437,11 @@ _dl_get_dl_main_map (void) + return &_dl_main_map; + } + #endif ++ ++/* This is used by _dl_runtime_profile, not used on static code. */ ++void ++DL_ARCH_FIXUP_ATTRIBUTE ++_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg, ++ const void *inregs, void *outregs) ++{ ++} +diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S +index a7e9267c1c6a4863..9b352b1d0f7d62e7 100644 +--- a/sysdeps/aarch64/dl-trampoline.S ++++ b/sysdeps/aarch64/dl-trampoline.S +@@ -293,7 +293,7 @@ _dl_runtime_profile: + ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0] + add x2, x29, #OFFSET_RG + add x3, x29, #OFFSET_RV +- bl _dl_call_pltexit ++ bl _dl_audit_pltexit + + ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0] + ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0] +diff --git a/sysdeps/alpha/dl-trampoline.S b/sysdeps/alpha/dl-trampoline.S +index 9dfce5b0839dc122..55380d48ad8536ee 100644 +--- a/sysdeps/alpha/dl-trampoline.S ++++ b/sysdeps/alpha/dl-trampoline.S +@@ -187,7 +187,7 @@ _dl_runtime_profile_new: + jsr $26, ($27), 0 + ldgp $29, 0($26) + +- /* Set up for call to _dl_call_pltexit. */ ++ /* Set up for call to _dl_audit_pltexit. */ + ldq $16, 16*8($15) + ldq $17, 17*8($15) + stq $0, 16*8($15) +@@ -196,7 +196,7 @@ _dl_runtime_profile_new: + lda $19, 16*8($15) + stt $f0, 18*8($15) + stt $f1, 19*8($15) +- bsr $26, _dl_call_pltexit !samegp ++ bsr $26, _dl_audit_pltexit !samegp + + mov $15, $30 + cfi_def_cfa_register (30) +@@ -518,7 +518,7 @@ _dl_runtime_profile_old: + jsr $26, ($27), 0 + ldgp $29, 0($26) + +- /* Set up for call to _dl_call_pltexit. */ ++ /* Set up for call to _dl_audit_pltexit. */ + ldq $16, 48*8($15) + ldq $17, 49*8($15) + stq $0, 46*8($15) +@@ -527,7 +527,7 @@ _dl_runtime_profile_old: + lda $19, 46*8($15) + stt $f0, 48*8($15) + stt $f1, 49*8($15) +- bsr $26, _dl_call_pltexit !samegp ++ bsr $26, _dl_audit_pltexit !samegp + + mov $15, $30 + cfi_def_cfa_register (30) +diff --git a/sysdeps/arm/dl-machine-rel.h b/sysdeps/arm/dl-machine-rel.h +index bec114706cd027a4..a9ee25a6b1d381ac 100644 +--- a/sysdeps/arm/dl-machine-rel.h ++++ b/sysdeps/arm/dl-machine-rel.h +@@ -28,4 +28,6 @@ + Prelinked libraries may use Elf32_Rela though. */ + #define ELF_MACHINE_PLT_REL 1 + ++#define PLTREL ElfW(Rel) ++ + #endif +diff --git a/sysdeps/arm/dl-trampoline.S b/sysdeps/arm/dl-trampoline.S +index 70105308ca7df934..a2d322706db77981 100644 +--- a/sysdeps/arm/dl-trampoline.S ++++ b/sysdeps/arm/dl-trampoline.S +@@ -194,7 +194,7 @@ _dl_runtime_profile: + ldmia ip, {r0,r1} + add r2, r7, #72 + add r3, r7, #0 +- bl _dl_call_pltexit ++ bl _dl_audit_pltexit + + @ Return to caller. + ldmia r7, {r0-r3} +diff --git a/sysdeps/generic/dl-fixup-attribute.h b/sysdeps/generic/dl-fixup-attribute.h +new file mode 100644 +index 0000000000000000..aa92169b709b3fea +--- /dev/null ++++ b/sysdeps/generic/dl-fixup-attribute.h +@@ -0,0 +1,24 @@ ++/* ABI specifics for lazy resolution functions. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_FIXUP_ATTRIBUTE_H ++#define _DL_FIXUP_ATTRIBUTE_H ++ ++#define DL_ARCH_FIXUP_ATTRIBUTE ++ ++#endif +diff --git a/sysdeps/generic/dl-machine-rel.h b/sysdeps/generic/dl-machine-rel.h +index 9167a1dffc715704..9d5b7bb749e69e63 100644 +--- a/sysdeps/generic/dl-machine-rel.h ++++ b/sysdeps/generic/dl-machine-rel.h +@@ -23,5 +23,7 @@ + #define ELF_MACHINE_NO_REL 1 + /* Defined if the architecture supports Elf{32,64}_Rela relocations. */ + #define ELF_MACHINE_NO_RELA 0 ++/* Used to calculate the index of link_map l_reloc_result. */ ++#define PLTREL ElfW(Rela) + + #endif +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index ea187dd266f14e06..686f0a7b9709eb10 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1415,6 +1416,11 @@ void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result, + DL_FIXUP_VALUE_TYPE *value, void *regs, + long int *framesize) + attribute_hidden; ++void DL_ARCH_FIXUP_ATTRIBUTE _dl_audit_pltexit (struct link_map *l, ++ ElfW(Word) reloc_arg, ++ const void *inregs, ++ void *outregs) ++ attribute_hidden; + #endif /* SHARED */ + + #if PTHREAD_IN_LIBC && defined SHARED +diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c +index a71b5b2013abf723..8699171930f51489 100644 +--- a/sysdeps/hppa/dl-runtime.c ++++ b/sysdeps/hppa/dl-runtime.c +@@ -25,7 +25,7 @@ + return that to the caller. The caller will continue on to call + _dl_fixup with the relocation offset. */ + +-ElfW(Word) __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE ++ElfW(Word) __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE + _dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l) + { + Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type; +diff --git a/sysdeps/hppa/dl-trampoline.S b/sysdeps/hppa/dl-trampoline.S +index cb18ea7eabba41ed..c54879bae0148012 100644 +--- a/sysdeps/hppa/dl-trampoline.S ++++ b/sysdeps/hppa/dl-trampoline.S +@@ -300,7 +300,7 @@ L(cont): + ldw -4(%sp),%r1 + copy %r1, %sp + +- /* Arguments to _dl_call_pltexit */ ++ /* Arguments to _dl_audit_pltexit */ + ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */ + ldw -120(%sp), %r25 /* (2) reloc offsets */ + ldo -56(%sp), %r24 /* (3) *La_hppa_regs */ +@@ -312,8 +312,8 @@ L(cont): + ldo -128(%sp), %r1 + fstd %fr4,0(%r1) + +- /* Call _dl_call_pltexit */ +- bl _dl_call_pltexit,%rp ++ /* Call _dl_audit_pltexit */ ++ bl _dl_audit_pltexit,%rp + nop + + /* Restore *La_hppa_retval */ +diff --git a/sysdeps/i386/dl-fixup-attribute.h b/sysdeps/i386/dl-fixup-attribute.h +new file mode 100644 +index 0000000000000000..c10e9936f4db7254 +--- /dev/null ++++ b/sysdeps/i386/dl-fixup-attribute.h +@@ -0,0 +1,30 @@ ++/* ABI specifics for lazy resolution functions. i386 version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_FIXUP_ATTRIBUTE_H ++#define _DL_FIXUP_ATTRIBUTE_H ++ ++/* We cannot use this scheme for profiling because the _mcount call destroys ++ the passed register information. */ ++#ifndef PROF ++# define DL_ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused)) ++#else ++# define DL_ARCH_FIXUP_ATTRIBUTE ++#endif ++ ++#endif +diff --git a/sysdeps/i386/dl-machine-rel.h b/sysdeps/i386/dl-machine-rel.h +index 7ac46f78a69fbf98..bb3480d45415d761 100644 +--- a/sysdeps/i386/dl-machine-rel.h ++++ b/sysdeps/i386/dl-machine-rel.h +@@ -28,4 +28,6 @@ + Prelinked libraries may use Elf32_Rela though. */ + #define ELF_MACHINE_PLT_REL 1 + ++#define PLTREL ElfW(Rel) ++ + #endif +diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h +index c55c9a3d64bed1f2..5483e903d81e85c6 100644 +--- a/sysdeps/i386/dl-machine.h ++++ b/sysdeps/i386/dl-machine.h +@@ -122,29 +122,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + return lazy; + } + +-#ifdef IN_DL_RUNTIME +- +-# ifndef PROF +-/* We add a declaration of this function here so that in dl-runtime.c +- the ELF_MACHINE_RUNTIME_TRAMPOLINE macro really can pass the parameters +- in registers. +- +- We cannot use this scheme for profiling because the _mcount call +- destroys the passed register information. */ +-#define ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused)) +- +-extern ElfW(Addr) _dl_fixup (struct link_map *l, +- ElfW(Word) reloc_offset) +- ARCH_FIXUP_ATTRIBUTE; +-extern ElfW(Addr) _dl_profile_fixup (struct link_map *l, +- ElfW(Word) reloc_offset, +- ElfW(Addr) retaddr, void *regs, +- long int *framesizep) +- ARCH_FIXUP_ATTRIBUTE; +-# endif +- +-#endif +- + /* Mask identifying addresses reserved for the user program, + where the dynamic linker should not map anything. */ + #define ELF_MACHINE_USER_ADDRESS_MASK 0xf0000000UL +diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S +index b5ec0326df94f0fd..3a33051c52da9cde 100644 +--- a/sysdeps/i386/dl-trampoline.S ++++ b/sysdeps/i386/dl-trampoline.S +@@ -265,7 +265,7 @@ _dl_runtime_profile: + movl (LRV_SIZE + 4 + LR_SIZE)(%esp), %eax + # PLT1 + movl (LRV_SIZE + 4 + LR_SIZE + 4)(%esp), %edx +- call _dl_call_pltexit ++ call _dl_audit_pltexit + movl LRV_EAX_OFFSET(%esp), %eax + movl LRV_EDX_OFFSET(%esp), %edx + fldt LRV_ST1_OFFSET(%esp) +diff --git a/sysdeps/ia64/dl-trampoline.S b/sysdeps/ia64/dl-trampoline.S +index 3053405a3a21d62e..11e86932c75d5b6b 100644 +--- a/sysdeps/ia64/dl-trampoline.S ++++ b/sysdeps/ia64/dl-trampoline.S +@@ -133,7 +133,7 @@ END(_dl_runtime_resolve) + + + /* The fourth argument to _dl_profile_fixup and the third one to +- _dl_call_pltexit are a pointer to La_ia64_regs: ++ _dl_audit_pltexit are a pointer to La_ia64_regs: + + 8byte r8 + 8byte r9 +@@ -159,7 +159,7 @@ END(_dl_runtime_resolve) + 8byte sp + + The fifth argument to _dl_profile_fixup is a pointer to long int. +- The fourth argument to _dl_call_pltexit is a pointer to ++ The fourth argument to _dl_audit_pltexit is a pointer to + La_ia64_retval: + + 8byte r8 +@@ -261,7 +261,7 @@ ENTRY(_dl_runtime_profile) + } + { .mii + mov r18 = ar.unat /* save it in La_ia64_regs */ +- mov loc7 = out3 /* save it for _dl_call_pltexit */ ++ mov loc7 = out3 /* save it for _dl_audit_pltexit */ + mov loc5 = r11 /* preserve language specific register */ + } + { .mmi +@@ -272,7 +272,7 @@ ENTRY(_dl_runtime_profile) + } + { .mii + mov ar.unat = r17 /* restore it for function call */ +- mov loc8 = r16 /* save it for _dl_call_pltexit */ ++ mov loc8 = r16 /* save it for _dl_audit_pltexit */ + nop.i 0x0 + } + { .mmi +@@ -291,7 +291,7 @@ ENTRY(_dl_runtime_profile) + { .mmi + stf.spill [r2] = f14, 32 + stf.spill [r3] = f15, 24 +- mov loc9 = out1 /* save it for _dl_call_pltexit */ ++ mov loc9 = out1 /* save it for _dl_audit_pltexit */ + ;; + } + { .mmb +@@ -426,7 +426,7 @@ ENTRY(_dl_runtime_profile) + br.call.sptk.many b0 = b6 + } + { .mii +- /* Prepare stack for _dl_call_pltexit. Loc10 has the original ++ /* Prepare stack for _dl_audit_pltexit. Loc10 has the original + stack pointer. */ + adds r12 = -PLTEXIT_FRAME_SIZE, loc10 + adds r2 = -(PLTEXIT_FRAME_SIZE - 16), loc10 +@@ -461,14 +461,14 @@ ENTRY(_dl_runtime_profile) + { .mmi + stf.spill [r2] = f12, 32 + stf.spill [r3] = f13, 32 +- /* We need to restore gp for _dl_call_pltexit. */ ++ /* We need to restore gp for _dl_audit_pltexit. */ + mov gp = loc11 + ;; + } + { .mmb + stf.spill [r2] = f14 + stf.spill [r3] = f15 +- br.call.sptk.many b0 = _dl_call_pltexit ++ br.call.sptk.many b0 = _dl_audit_pltexit + } + { .mmi + /* Load all the non-floating and floating return values. Skip +diff --git a/sysdeps/m68k/dl-trampoline.S b/sysdeps/m68k/dl-trampoline.S +index a51a5f7f573c6330..72bde664c31c4256 100644 +--- a/sysdeps/m68k/dl-trampoline.S ++++ b/sysdeps/m68k/dl-trampoline.S +@@ -202,7 +202,7 @@ _dl_runtime_profile: + cfi_adjust_cfa_offset (4) + move.l (32+FPSPACE)(%sp), -(%sp) + cfi_adjust_cfa_offset (4) +- jbsr _dl_call_pltexit ++ jbsr _dl_audit_pltexit + lea 16(%sp), %sp + cfi_adjust_cfa_offset (-16) + move.l (%sp)+, %d0 +diff --git a/sysdeps/mips/dl-machine-rel.h b/sysdeps/mips/dl-machine-rel.h +index ed396180412bc723..3d0dfec01f6b193e 100644 +--- a/sysdeps/mips/dl-machine-rel.h ++++ b/sysdeps/mips/dl-machine-rel.h +@@ -22,5 +22,6 @@ + #define ELF_MACHINE_PLT_REL 1 + #define ELF_MACHINE_NO_REL 0 + #define ELF_MACHINE_NO_RELA 0 ++#define PLTREL ElfW(Rel) + + #endif +diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S +index 61bd8571fcc93caa..97f0105ce780514e 100644 +--- a/sysdeps/powerpc/powerpc64/dl-trampoline.S ++++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S +@@ -197,7 +197,7 @@ END(_dl_runtime_resolve) + #ifndef PROF + ENTRY (_dl_profile_resolve, 4) + /* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we +- need to call _dl_call_pltexit. */ ++ need to call _dl_audit_pltexit. */ + std r31,-8(r1) + std r30,-16(r1) + /* We need to save the registers used to pass parameters, ie. r3 thru +@@ -452,7 +452,7 @@ L(restoreFXR2): + L(callpltexit): + addi r5,r1,INT_PARMS + addi r6,r1,INT_RTN +- bl JUMPTARGET(_dl_call_pltexit) ++ bl JUMPTARGET(_dl_audit_pltexit) + #ifndef SHARED + nop + #endif +diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h +index c224a2b92832af9b..9e4cd1055fe6ab20 100644 +--- a/sysdeps/s390/s390-32/dl-trampoline.h ++++ b/sysdeps/s390/s390-32/dl-trampoline.h +@@ -282,7 +282,7 @@ _dl_runtime_profile: + basr %r1,0 + 5: l %r14,7f-5b(%r1) + la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_32_retval * +- bas %r14,0(%r14,%r1) # call _dl_call_pltexit ++ bas %r14,0(%r14,%r1) # call _dl_audit_pltexit + + lr %r15,%r12 # remove stack frame + # undef FRAME_SIZE +@@ -301,7 +301,7 @@ _dl_runtime_profile: + br %r14 + + 6: .long _dl_profile_fixup - 0b +-7: .long _dl_call_pltexit - 5b ++7: .long _dl_audit_pltexit - 5b + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile + # undef SIZEOF_STRUCT_LA_S390_32_REGS +diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h +index ae741a3bad5ec77e..6e5bad40459ec765 100644 +--- a/sysdeps/s390/s390-64/dl-trampoline.h ++++ b/sysdeps/s390/s390-64/dl-trampoline.h +@@ -284,7 +284,7 @@ _dl_runtime_profile: + lmg %r2,%r4,CFA_OFF+PLT1_OFF(%r12) # r2, r3: args saved by PLT + # r4: struct La_s390_64_regs * + la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_64_retval * +- brasl %r14,_dl_call_pltexit ++ brasl %r14,_dl_audit_pltexit + + lgr %r15,%r12 # remove stack frame + # undef FRAME_SIZE +diff --git a/sysdeps/sh/dl-trampoline.S b/sysdeps/sh/dl-trampoline.S +index 824ac84ba1830ce5..f9038cd10ed5286f 100644 +--- a/sysdeps/sh/dl-trampoline.S ++++ b/sysdeps/sh/dl-trampoline.S +@@ -423,8 +423,8 @@ _dl_runtime_profile: + .align 2 + #ifdef SHARED + 7: .long _GLOBAL_OFFSET_TABLE_ +-8: .long _dl_call_pltexit@GOTOFF ++8: .long _dl_audit_pltexit@GOTOFF + #else +-8: .long _dl_call_pltexit ++8: .long _dl_audit_pltexit + #endif + .size _dl_runtime_profile, .-_dl_runtime_profile +diff --git a/sysdeps/sparc/sparc32/dl-trampoline.S b/sysdeps/sparc/sparc32/dl-trampoline.S +index 426f90c99a7ed369..2f64809731c865a2 100644 +--- a/sysdeps/sparc/sparc32/dl-trampoline.S ++++ b/sysdeps/sparc/sparc32/dl-trampoline.S +@@ -127,7 +127,7 @@ _dl_profile_invoke: + mov %l5, %o0 + mov %l6, %o1 + add %sp, (11 * 8), %o2 +- call _dl_call_pltexit ++ call _dl_audit_pltexit + add %sp, ( 9 * 8), %o3 + + ldd [%sp + ( 9 * 8)], %i0 +diff --git a/sysdeps/sparc/sparc64/dl-trampoline.S b/sysdeps/sparc/sparc64/dl-trampoline.S +index 8d59fa67209cd8ab..86605e37acd929fd 100644 +--- a/sysdeps/sparc/sparc64/dl-trampoline.S ++++ b/sysdeps/sparc/sparc64/dl-trampoline.S +@@ -196,7 +196,7 @@ _dl_profile_invoke: + mov %l5, %o0 + mov %l6, %o1 + add %sp, STACK_BIAS + (24 * 8), %o2 +- call _dl_call_pltexit ++ call _dl_audit_pltexit + add %sp, STACK_BIAS + (16 * 8), %o3 + + ldx [%sp + STACK_BIAS + (16 * 8)], %i0 +diff --git a/sysdeps/x86_64/dl-runtime.h b/sysdeps/x86_64/dl-runtime.h +index 9c8d3977eee27069..19ba33ef30970c20 100644 +--- a/sysdeps/x86_64/dl-runtime.h ++++ b/sysdeps/x86_64/dl-runtime.h +@@ -18,7 +18,7 @@ + 02111-1307 USA. */ + + /* The ABI calls for the PLT stubs to pass the index of the relocation +- and not its offset. In _dl_profile_fixup and _dl_call_pltexit we ++ and not its offset. In _dl_profile_fixup and _dl_audit_pltexit we + also use the index. Therefore it is wasteful to compute the offset + in the trampoline just to reverse the operation immediately + afterwards. */ +diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h +index b9a12970cd6206ee..b5de7efff778559e 100644 +--- a/sysdeps/x86_64/dl-trampoline.h ++++ b/sysdeps/x86_64/dl-trampoline.h +@@ -388,7 +388,7 @@ _dl_runtime_profile: + jns 3f + + /* There's nothing in the frame size, so there +- will be no call to the _dl_call_pltexit. */ ++ will be no call to the _dl_audit_pltexit. */ + + /* Get back registers content. */ + movq LR_RCX_OFFSET(%rsp), %rcx +@@ -436,7 +436,7 @@ _dl_runtime_profile: + mov 24(%rbx), %RSP_LP # Drop the copied stack content + + /* Now we have to prepare the La_x86_64_retval structure for the +- _dl_call_pltexit. The La_x86_64_regs is being pointed by rsp now, ++ _dl_audit_pltexit. The La_x86_64_regs is being pointed by rsp now, + so we just need to allocate the sizeof(La_x86_64_retval) space on + the stack, since the alignment has already been taken care of. */ + # ifdef RESTORE_AVX +@@ -491,7 +491,7 @@ _dl_runtime_profile: + movq 24(%rbx), %rdx # La_x86_64_regs argument to %rdx. + movq 40(%rbx), %rsi # Copy args pushed by PLT in register. + movq 32(%rbx), %rdi # %rdi: link_map, %rsi: reloc_index +- call _dl_call_pltexit ++ call _dl_audit_pltexit + + /* Restore return registers. */ + movq LRV_RAX_OFFSET(%rsp), %rax diff --git a/SOURCES/glibc-upstream-2.34-15.patch b/SOURCES/glibc-upstream-2.34-15.patch new file mode 100644 index 0000000..a2275fb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-15.patch @@ -0,0 +1,117 @@ +commit 3fc51f35b4f32e1bb99d85c1578e930e725ff929 +Author: Siddhesh Poyarekar +Date: Mon Sep 13 20:48:35 2021 +0530 + + iconvconfig: Fix behaviour with --prefix [BZ #28199] + + The consolidation of configuration parsing broke behaviour with + --prefix, where the prefix bled into the modules cache. Accept a + prefix which, when non-NULL, is prepended to the path when looking for + configuration files but only the original directory is added to the + modules cache. + + This has no effect on the codegen of gconv_conf since it passes NULL. + + Reported-by: Patrick McCarty + Reported-by: Michael Hudson-Doyle + Reviewed-by: Andreas Schwab + (cherry picked from commit 43cea6d5652b6b9e61ac6ecc69419c909b504f47) + +diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c +index 62bee28769deb979..cc391d8f936687f3 100644 +--- a/iconv/gconv_conf.c ++++ b/iconv/gconv_conf.c +@@ -478,7 +478,7 @@ __gconv_read_conf (void) + __gconv_get_path (); + + for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt) +- gconv_parseconfdir (__gconv_path_elem[cnt].name, ++ gconv_parseconfdir (NULL, __gconv_path_elem[cnt].name, + __gconv_path_elem[cnt].len); + #endif + +diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h +index 2f062689ecc72749..a586268abc103abd 100644 +--- a/iconv/gconv_parseconfdir.h ++++ b/iconv/gconv_parseconfdir.h +@@ -39,7 +39,6 @@ + /* Name of the file containing the module information in the directories + along the path. */ + static const char gconv_conf_filename[] = "gconv-modules"; +-static const char gconv_conf_dirname[] = "gconv-modules.d"; + + static void add_alias (char *); + static void add_module (char *, const char *, size_t, int); +@@ -110,19 +109,28 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len) + return true; + } + ++/* Prefix DIR (with length DIR_LEN) with PREFIX if the latter is non-NULL and ++ parse configuration in it. */ ++ + static __always_inline bool +-gconv_parseconfdir (const char *dir, size_t dir_len) ++gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len) + { +- /* No slash needs to be inserted between dir and gconv_conf_filename; +- dir already ends in a slash. */ +- char *buf = malloc (dir_len + sizeof (gconv_conf_dirname)); ++ /* No slash needs to be inserted between dir and gconv_conf_filename; dir ++ already ends in a slash. The additional 2 is to accommodate the ".d" ++ when looking for configuration files in gconv-modules.d. */ ++ size_t buflen = dir_len + sizeof (gconv_conf_filename) + 2; ++ char *buf = malloc (buflen + (prefix != NULL ? strlen (prefix) : 0)); ++ char *cp = buf; + bool found = false; + + if (buf == NULL) + return false; + +- char *cp = mempcpy (mempcpy (buf, dir, dir_len), gconv_conf_filename, +- sizeof (gconv_conf_filename)); ++ if (prefix != NULL) ++ cp = stpcpy (cp, prefix); ++ ++ cp = mempcpy (mempcpy (cp, dir, dir_len), gconv_conf_filename, ++ sizeof (gconv_conf_filename)); + + /* Read the gconv-modules configuration file first. */ + found = read_conf_file (buf, dir, dir_len); +diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c +index 783b2bbdbb684ac6..273a71f67315f670 100644 +--- a/iconv/iconvconfig.c ++++ b/iconv/iconvconfig.c +@@ -653,13 +653,21 @@ add_module (char *rp, const char *directory, + static int + handle_dir (const char *dir) + { ++ char *newp = NULL; + size_t dirlen = strlen (dir); + bool found = false; + +- char *fulldir = xasprintf ("%s%s%s", dir[0] == '/' ? prefix : "", +- dir, dir[dirlen - 1] != '/' ? "/" : ""); ++ /* End directory path with a '/' if it doesn't already. */ ++ if (dir[dirlen - 1] != '/') ++ { ++ newp = xmalloc (dirlen + 2); ++ memcpy (newp, dir, dirlen); ++ newp[dirlen++] = '/'; ++ newp[dirlen] = '\0'; ++ dir = newp; ++ } + +- found = gconv_parseconfdir (fulldir, strlen (fulldir)); ++ found = gconv_parseconfdir (dir[0] == '/' ? prefix : NULL, dir, dirlen); + + if (!found) + { +@@ -671,7 +679,7 @@ handle_dir (const char *dir) + "configuration files with names ending in .conf."); + } + +- free (fulldir); ++ free (newp); + + return found ? 0 : 1; + } diff --git a/SOURCES/glibc-upstream-2.34-150.patch b/SOURCES/glibc-upstream-2.34-150.patch new file mode 100644 index 0000000..40829fd --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-150.patch @@ -0,0 +1,454 @@ +commit 29496b3103ff13aa3c1d8b62552a98f39da0fe59 +Author: Adhemerval Zanella +Date: Wed Jun 30 10:24:09 2021 -0300 + + elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533) + + The rtld-audit interfaces introduces a slowdown due to enabling + profiling instrumentation (as if LD_AUDIT implied LD_PROFILE). + However, instrumenting is only necessary if one of audit libraries + provides PLT callbacks (la_pltenter or la_pltexit symbols). Otherwise, + the slowdown can be avoided. + + The following patch adjusts the logic that enables profiling to iterate + over all audit modules and check if any of those provides a PLT hook. + To keep la_symbind to work even without PLT callbacks, _dl_fixup now + calls the audit callback if the modules implements it. + + Co-authored-by: Alexander Monakov + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit 063f9ba220f434c7f30dd65c4cff17c0c458a7cf) + + Resolved conflicts: + NEWS + elf/Makefile + +diff --git a/elf/Makefile b/elf/Makefile +index 85165c0591412a45..eab9d46b6165e6be 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -365,6 +365,7 @@ tests += \ + tst-audit16 \ + tst-audit17 \ + tst-audit18 \ ++ tst-audit19b \ + tst-auditmany \ + tst-auxobj \ + tst-auxobj-dlopen \ +@@ -454,6 +455,7 @@ tests-internal += \ + neededtest2 \ + neededtest3 \ + neededtest4 \ ++ tst-audit19a \ + tst-create_format1 \ + tst-dl-hwcaps_split \ + tst-dlmopen2 \ +@@ -626,6 +628,7 @@ modules-names = \ + tst-audit12mod3 \ + tst-audit13mod1 \ + tst-audit18mod \ ++ tst-audit19bmod \ + tst-auditlogmod-1 \ + tst-auditlogmod-2 \ + tst-auditlogmod-3 \ +@@ -644,6 +647,8 @@ modules-names = \ + tst-auditmod11 \ + tst-auditmod12 \ + tst-auditmod18 \ ++ tst-auditmod19a \ ++ tst-auditmod19b \ + tst-auxvalmod \ + tst-big-note-lib \ + tst-deep1mod1 \ +@@ -2007,6 +2012,13 @@ $(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \ + $(objpfx)tst-audit18mod.so + tst-audit18-ARGS = -- $(host-test-program-cmd) + ++$(objpfx)tst-audit19a.out: $(objpfx)tst-auditmod19a.so ++tst-audit19a-ENV = LD_AUDIT=$(objpfx)tst-auditmod19a.so ++ ++$(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so ++$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so ++tst-audit19b-ARGS = -- $(host-test-program-cmd) ++ + # tst-sonamemove links against an older implementation of the library. + LDFLAGS-tst-sonamemove-linkmod1.so = \ + -Wl,--version-script=tst-sonamemove-linkmod1.map \ +diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c +index 3447de7f3536cd70..5b69321bda1f2b27 100644 +--- a/elf/dl-reloc.c ++++ b/elf/dl-reloc.c +@@ -205,12 +205,28 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + int skip_ifunc = reloc_mode & __RTLD_NOIFUNC; + + #ifdef SHARED ++ bool consider_symbind = false; + /* If we are auditing, install the same handlers we need for profiling. */ + if ((reloc_mode & __RTLD_AUDIT) == 0) +- consider_profiling |= GLRO(dl_audit) != NULL; ++ { ++ struct audit_ifaces *afct = GLRO(dl_audit); ++ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) ++ { ++ /* Profiling is needed only if PLT hooks are provided. */ ++ if (afct->ARCH_LA_PLTENTER != NULL ++ || afct->ARCH_LA_PLTEXIT != NULL) ++ consider_profiling = 1; ++ if (afct->symbind != NULL) ++ consider_symbind = true; ++ ++ afct = afct->next; ++ } ++ } + #elif defined PROF + /* Never use dynamic linker profiling for gprof profiling code. */ + # define consider_profiling 0 ++#else ++# define consider_symbind 0 + #endif + + if (l->l_relocated) +@@ -272,7 +288,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc); + + #ifndef PROF +- if (__glibc_unlikely (consider_profiling) ++ if ((consider_profiling || consider_symbind) + && l->l_info[DT_PLTRELSZ] != NULL) + { + /* Allocate the array which will contain the already found +diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c +index e42f6e8b8dfca08e..77a5cccdcbcb9293 100644 +--- a/elf/dl-runtime.c ++++ b/elf/dl-runtime.c +@@ -124,6 +124,37 @@ _dl_fixup ( + && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) + value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value)); + ++#ifdef SHARED ++ /* Auditing checkpoint: we have a new binding. Provide the auditing ++ libraries the possibility to change the value and tell us whether further ++ auditing is wanted. ++ The l_reloc_result is only allocated if there is an audit module which ++ provides a la_symbind. */ ++ if (l->l_reloc_result != NULL) ++ { ++ /* 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 (pltgot, reloc_arg, sizeof (PLTREL))]; ++ unsigned int init = atomic_load_acquire (&reloc_result->init); ++ if (init == 0) ++ { ++ _dl_audit_symbind (l, reloc_result, sym, &value, result); ++ ++ /* Store the result for later runs. */ ++ if (__glibc_likely (! GLRO(dl_bind_not))) ++ { ++ reloc_result->addr = value; ++ /* Guarantee all previous writes complete before init is ++ updated. See CONCURRENCY NOTES below. */ ++ atomic_store_release (&reloc_result->init, 1); ++ } ++ } ++ else ++ value = reloc_result->addr; ++ } ++#endif ++ + /* Finally, fix up the plt itself. */ + if (__glibc_unlikely (GLRO(dl_bind_not))) + return value; +diff --git a/elf/rtld.c b/elf/rtld.c +index b6bb46ca97b7972f..f632a767d7a269ef 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1016,13 +1016,7 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d); + "la_objsearch\0" + "la_objopen\0" + "la_preinit\0" +-#if __ELF_NATIVE_CLASS == 32 +- "la_symbind32\0" +-#elif __ELF_NATIVE_CLASS == 64 +- "la_symbind64\0" +-#else +-# error "__ELF_NATIVE_CLASS must be defined" +-#endif ++ LA_SYMBIND "\0" + #define STRING(s) __STRING (s) + "la_" STRING (ARCH_LA_PLTENTER) "\0" + "la_" STRING (ARCH_LA_PLTEXIT) "\0" +diff --git a/elf/tst-audit19a.c b/elf/tst-audit19a.c +new file mode 100644 +index 0000000000000000..035cde9351c2711b +--- /dev/null ++++ b/elf/tst-audit19a.c +@@ -0,0 +1,38 @@ ++/* Check if DT_AUDIT a module without la_plt{enter,exit} symbols does not incur ++ in profiling (BZ#15533). ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ void *h = xdlopen ("tst-auditmod19a.so", RTLD_NOW); ++ ++ struct link_map *lmap; ++ TEST_VERIFY_EXIT (dlinfo (h, RTLD_DI_LINKMAP, &lmap) == 0); ++ ++ /* The internal array is only allocated if profiling is enabled. */ ++ TEST_VERIFY (lmap->l_reloc_result == NULL); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-audit19b.c b/elf/tst-audit19b.c +new file mode 100644 +index 0000000000000000..da015734f24e0d79 +--- /dev/null ++++ b/elf/tst-audit19b.c +@@ -0,0 +1,94 @@ ++/* Check if DT_AUDIT a module with la_plt{enter,exit} call la_symbind ++ for lazy resolution. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int restart; ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++ ++int tst_audit18bmod1_func (void); ++ ++static int ++handle_restart (void) ++{ ++ TEST_COMPARE (tst_audit18bmod1_func (), 10); ++ return 0; ++} ++ ++static inline bool ++startswith (const char *str, const char *pre) ++{ ++ size_t lenpre = strlen (pre); ++ size_t lenstr = strlen (str); ++ return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0; ++} ++ ++static int ++do_test (int argc, char *argv[]) ++{ ++ /* We must have either: ++ - One our fource parameters left if called initially: ++ + path to ld.so optional ++ + "--library-path" optional ++ + the library path optional ++ + the application name */ ++ ++ if (restart) ++ return handle_restart (); ++ ++ char *spargv[9]; ++ int i = 0; ++ for (; i < argc - 1; i++) ++ spargv[i] = argv[i + 1]; ++ spargv[i++] = (char *) "--direct"; ++ spargv[i++] = (char *) "--restart"; ++ spargv[i] = NULL; ++ ++ setenv ("LD_AUDIT", "tst-auditmod18b.so", 0); ++ struct support_capture_subprocess result ++ = support_capture_subprogram (spargv[0], spargv); ++ support_capture_subprocess_check (&result, "tst-audit18b", 0, sc_allow_stderr); ++ ++ bool find_symbind = false; ++ ++ FILE *out = fmemopen (result.err.buffer, result.err.length, "r"); ++ TEST_VERIFY (out != NULL); ++ char *buffer = NULL; ++ size_t buffer_length = 0; ++ while (xgetline (&buffer, &buffer_length, out)) ++ if (startswith (buffer, "la_symbind: tst_audit18bmod1_func") == 0) ++ find_symbind = true; ++ ++ TEST_COMPARE (find_symbind, true); ++ ++ free (buffer); ++ xfclose (out); ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION_ARGV do_test ++#include +diff --git a/elf/tst-audit19bmod.c b/elf/tst-audit19bmod.c +new file mode 100644 +index 0000000000000000..9ffdcd8f3ffbc38e +--- /dev/null ++++ b/elf/tst-audit19bmod.c +@@ -0,0 +1,23 @@ ++/* Extra module for tst-audit18b. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++int ++tst_audit18bmod1_func (void) ++{ ++ return 10; ++} +diff --git a/elf/tst-auditmod19a.c b/elf/tst-auditmod19a.c +new file mode 100644 +index 0000000000000000..f58204099457743d +--- /dev/null ++++ b/elf/tst-auditmod19a.c +@@ -0,0 +1,25 @@ ++/* Audit module for tst-audit18a. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return LAV_CURRENT; ++} +diff --git a/elf/tst-auditmod19b.c b/elf/tst-auditmod19b.c +new file mode 100644 +index 0000000000000000..e2248b2a75946746 +--- /dev/null ++++ b/elf/tst-auditmod19b.c +@@ -0,0 +1,46 @@ ++/* Audit module for tst-audit18b. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return LAV_CURRENT; ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ return LA_FLG_BINDTO | LA_FLG_BINDFROM; ++} ++ ++uintptr_t ++#if __ELF_NATIVE_CLASS == 32 ++la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, unsigned int *flags, const char *symname) ++#else ++la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, unsigned int *flags, const char *symname) ++#endif ++{ ++ fprintf (stderr, "la_symbind: %s\n", symname); ++ return sym->st_value; ++} +diff --git a/include/link.h b/include/link.h +index 4dcf01d8aea90bc2..b3f160c278222b3c 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -363,8 +363,10 @@ struct auditstate + + #if __ELF_NATIVE_CLASS == 32 + # define symbind symbind32 ++# define LA_SYMBIND "la_symbind32" + #elif __ELF_NATIVE_CLASS == 64 + # define symbind symbind64 ++# define LA_SYMBIND "la_symbind64" + #else + # error "__ELF_NATIVE_CLASS must be defined" + #endif diff --git a/SOURCES/glibc-upstream-2.34-151.patch b/SOURCES/glibc-upstream-2.34-151.patch new file mode 100644 index 0000000..21e804b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-151.patch @@ -0,0 +1,294 @@ +commit 02c6a3d35316d360ae08623f617b1873d2f6159a +Author: Adhemerval Zanella +Date: Wed Jun 30 15:51:31 2021 -0300 + + elf: Add audit tests for modules with TLSDESC + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit d1b38173c9255b1a4ae00018ad9b35404a7c74d0) + +diff --git a/elf/Makefile b/elf/Makefile +index eab9d46b6165e6be..29f545d2272bf6e2 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -807,6 +807,22 @@ modules-names += tst-gnu2-tls1mod + $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so + tst-gnu2-tls1mod.so-no-z-defs = yes + CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 ++ ++tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen ++modules-names += tst-audit-tlsdesc-mod1 tst-audit-tlsdesc-mod2 tst-auditmod-tlsdesc ++$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \ ++ $(objpfx)tst-audit-tlsdesc-mod2.so \ ++ $(shared-thread-library) ++CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2 ++CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2 ++$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library) ++$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \ ++ $(objpfx)tst-audit-tlsdesc-mod2.so ++$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so ++$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so ++tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so ++$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so ++tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so + endif + ifeq (yes,$(have-protected-data)) + modules-names += tst-protected1moda tst-protected1modb +diff --git a/elf/tst-audit-tlsdesc-dlopen.c b/elf/tst-audit-tlsdesc-dlopen.c +new file mode 100644 +index 0000000000000000..9c16bb087aca1b77 +--- /dev/null ++++ b/elf/tst-audit-tlsdesc-dlopen.c +@@ -0,0 +1,67 @@ ++/* DT_AUDIT with modules with TLSDESC. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static void * ++thr_func (void *mod) ++{ ++ int* (*get_global1)(void) = xdlsym (mod, "get_global1"); ++ int* (*get_global2)(void) = xdlsym (mod, "get_global2"); ++ void (*set_global2)(int) = xdlsym (mod, "set_global2"); ++ int* (*get_local1)(void) = xdlsym (mod, "get_local1"); ++ int* (*get_local2)(void) = xdlsym (mod, "get_local2"); ++ ++ int *global1 = get_global1 (); ++ TEST_COMPARE (*global1, 0); ++ ++*global1; ++ ++ int *global2 = get_global2 (); ++ TEST_COMPARE (*global2, 0); ++ ++*global2; ++ TEST_COMPARE (*global2, 1); ++ ++ set_global2 (10); ++ TEST_COMPARE (*global2, 10); ++ ++ int *local1 = get_local1 (); ++ TEST_COMPARE (*local1, 0); ++ ++*local1; ++ ++ int *local2 = get_local2 (); ++ TEST_COMPARE (*local2, 0); ++ ++*local2; ++ ++ return 0; ++} ++ ++static int ++do_test (void) ++{ ++ void *mod = xdlopen ("tst-audit-tlsdesc-mod1.so", RTLD_LAZY); ++ ++ pthread_t thr = xpthread_create (NULL, thr_func, mod); ++ void *r = xpthread_join (thr); ++ TEST_VERIFY (r == NULL); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-audit-tlsdesc-mod1.c b/elf/tst-audit-tlsdesc-mod1.c +new file mode 100644 +index 0000000000000000..61c7dd99a2fb5e28 +--- /dev/null ++++ b/elf/tst-audit-tlsdesc-mod1.c +@@ -0,0 +1,41 @@ ++/* DT_AUDIT with modules with TLSDESC. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++__thread int global1; ++ ++int * ++get_global1 (void) ++{ ++ return &global1; ++} ++ ++static __thread int local1; ++ ++void * ++get_local1 (void) ++{ ++ return &local1; ++} ++ ++extern __thread int global2; ++ ++void ++set_global2 (int v) ++{ ++ global2 = v; ++} +diff --git a/elf/tst-audit-tlsdesc-mod2.c b/elf/tst-audit-tlsdesc-mod2.c +new file mode 100644 +index 0000000000000000..28aef635f688ee03 +--- /dev/null ++++ b/elf/tst-audit-tlsdesc-mod2.c +@@ -0,0 +1,33 @@ ++/* DT_AUDIT with modules with TLSDESC. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++__thread int global2; ++ ++int * ++get_global2 (void) ++{ ++ return &global2; ++} ++ ++static __thread int local2; ++ ++void * ++get_local2 (void) ++{ ++ return &local2; ++} +diff --git a/elf/tst-audit-tlsdesc.c b/elf/tst-audit-tlsdesc.c +new file mode 100644 +index 0000000000000000..3c8be81c95528f47 +--- /dev/null ++++ b/elf/tst-audit-tlsdesc.c +@@ -0,0 +1,60 @@ ++/* DT_AUDIT with modules with TLSDESC. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++extern __thread int global1; ++extern __thread int global2; ++void *get_local1 (void); ++void set_global2 (int v); ++void *get_local2 (void); ++ ++static void * ++thr_func (void *clousure) ++{ ++ TEST_COMPARE (global1, 0); ++ ++global1; ++ TEST_COMPARE (global2, 0); ++ ++global2; ++ TEST_COMPARE (global2, 1); ++ ++ set_global2 (10); ++ TEST_COMPARE (global2, 10); ++ ++ int *local1 = get_local1 (); ++ TEST_COMPARE (*local1, 0); ++ ++*local1; ++ ++ int *local2 = get_local2 (); ++ TEST_COMPARE (*local2, 0); ++ ++*local2; ++ ++ return 0; ++} ++ ++static int ++do_test (void) ++{ ++ pthread_t thr = xpthread_create (NULL, thr_func, NULL); ++ void *r = xpthread_join (thr); ++ TEST_VERIFY (r == NULL); ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-auditmod-tlsdesc.c b/elf/tst-auditmod-tlsdesc.c +new file mode 100644 +index 0000000000000000..e4b835d1f1fb6f73 +--- /dev/null ++++ b/elf/tst-auditmod-tlsdesc.c +@@ -0,0 +1,25 @@ ++/* DT_AUDIT with modules with TLSDESC. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return LAV_CURRENT; ++} diff --git a/SOURCES/glibc-upstream-2.34-152.patch b/SOURCES/glibc-upstream-2.34-152.patch new file mode 100644 index 0000000..e2c8172 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-152.patch @@ -0,0 +1,314 @@ +commit d1b9bee29a1c4e0b80db53f228e22550c3604894 +Author: Adhemerval Zanella +Date: Mon Jul 19 18:42:26 2021 -0300 + + elf: Issue audit la_objopen for vDSO + + The vDSO is is listed in the link_map chain, but is never the subject of + an la_objopen call. A new internal flag __RTLD_VDSO is added that + acts as __RTLD_OPENEXEC to allocate the required 'struct auditstate' + extra space for the 'struct link_map'. + + The return value from the callback is currently ignored, since there + is no PLT call involved by glibc when using the vDSO, neither the vDSO + are exported directly. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit f0e23d34a7bdf6b90fba954ee741419171ac41b2) + + Resolved conflicts: + elf/Makefile + +diff --git a/elf/Makefile b/elf/Makefile +index 29f545d2272bf6e2..465442bf59fa9794 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -366,6 +366,7 @@ tests += \ + tst-audit17 \ + tst-audit18 \ + tst-audit19b \ ++ tst-audit22 \ + tst-auditmany \ + tst-auxobj \ + tst-auxobj-dlopen \ +@@ -649,6 +650,7 @@ modules-names = \ + tst-auditmod18 \ + tst-auditmod19a \ + tst-auditmod19b \ ++ tst-auditmod22 \ + tst-auxvalmod \ + tst-big-note-lib \ + tst-deep1mod1 \ +@@ -2035,6 +2037,9 @@ $(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so + $(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so + tst-audit19b-ARGS = -- $(host-test-program-cmd) + ++$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so ++tst-audit22-ARGS = -- $(host-test-program-cmd) ++ + # tst-sonamemove links against an older implementation of the library. + LDFLAGS-tst-sonamemove-linkmod1.so = \ + -Wl,--version-script=tst-sonamemove-linkmod1.map \ +diff --git a/elf/dl-object.c b/elf/dl-object.c +index 1875599eb274dc35..dee49a32d4fdf07d 100644 +--- a/elf/dl-object.c ++++ b/elf/dl-object.c +@@ -59,16 +59,19 @@ _dl_new_object (char *realname, const char *libname, int type, + { + #ifdef SHARED + unsigned int naudit; +- if (__glibc_unlikely ((mode & __RTLD_OPENEXEC) != 0)) ++ if (__glibc_unlikely ((mode & (__RTLD_OPENEXEC | __RTLD_VDSO)) != 0)) + { +- assert (type == lt_executable); +- assert (nsid == LM_ID_BASE); ++ if (mode & __RTLD_OPENEXEC) ++ { ++ assert (type == lt_executable); ++ assert (nsid == LM_ID_BASE); + +- /* Ignore the specified libname for the main executable. It is +- only known with an explicit loader invocation. */ +- libname = ""; ++ /* Ignore the specified libname for the main executable. It is ++ only known with an explicit loader invocation. */ ++ libname = ""; ++ } + +- /* We create the map for the executable before we know whether ++ /* We create the map for the executable and vDSO before we know whether + we have auditing libraries and if yes, how many. Assume the + worst. */ + naudit = DL_NNS; +diff --git a/elf/rtld.c b/elf/rtld.c +index f632a767d7a269ef..b089e5cf4740443e 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1922,6 +1922,12 @@ dl_main (const ElfW(Phdr) *phdr, + assert (i == npreloads); + } + ++#ifdef NEED_DL_SYSINFO_DSO ++ /* Now that the audit modules are opened, call la_objopen for the vDSO. */ ++ if (GLRO(dl_sysinfo_map) != NULL) ++ _dl_audit_objopen (GLRO(dl_sysinfo_map), LM_ID_BASE); ++#endif ++ + /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD + specified some libraries to load, these are inserted before the actual + dependencies in the executable's searchlist for symbol resolution. */ +diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h +index 3f20578046de76ed..2b013d974a377a83 100644 +--- a/elf/setup-vdso.h ++++ b/elf/setup-vdso.h +@@ -30,7 +30,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)), + We just want our data structures to describe it as if we had just + mapped and relocated it normally. */ + struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL, +- 0, LM_ID_BASE); ++ __RTLD_VDSO, LM_ID_BASE); + if (__glibc_likely (l != NULL)) + { + l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso) +diff --git a/elf/tst-audit22.c b/elf/tst-audit22.c +new file mode 100644 +index 0000000000000000..18fd22a760ddc3d8 +--- /dev/null ++++ b/elf/tst-audit22.c +@@ -0,0 +1,124 @@ ++/* Check DTAUDIT and vDSO interaction. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int restart; ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++ ++static uintptr_t vdso_addr; ++ ++static int ++handle_restart (void) ++{ ++ fprintf (stderr, "vdso: %p\n", (void*) vdso_addr); ++ return 0; ++} ++ ++static uintptr_t ++parse_address (const char *str) ++{ ++ void *r; ++ TEST_COMPARE (sscanf (str, "%p\n", &r), 1); ++ return (uintptr_t) r; ++} ++ ++static inline bool ++startswith (const char *str, const char *pre) ++{ ++ size_t lenpre = strlen (pre); ++ size_t lenstr = strlen (str); ++ return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0; ++} ++ ++static int ++do_test (int argc, char *argv[]) ++{ ++ vdso_addr = getauxval (AT_SYSINFO_EHDR); ++ if (vdso_addr == 0) ++ FAIL_UNSUPPORTED ("getauxval (AT_SYSINFO_EHDR) returned 0"); ++ ++ /* We must have either: ++ - One our fource parameters left if called initially: ++ + path to ld.so optional ++ + "--library-path" optional ++ + the library path optional ++ + the application name */ ++ if (restart) ++ return handle_restart (); ++ ++ char *spargv[9]; ++ int i = 0; ++ for (; i < argc - 1; i++) ++ spargv[i] = argv[i + 1]; ++ spargv[i++] = (char *) "--direct"; ++ spargv[i++] = (char *) "--restart"; ++ spargv[i] = NULL; ++ ++ setenv ("LD_AUDIT", "tst-auditmod22.so", 0); ++ struct support_capture_subprocess result ++ = support_capture_subprogram (spargv[0], spargv); ++ support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr); ++ ++ /* The respawned process should always print the vDSO address (otherwise it ++ will fails as unsupported). However, on some architectures the audit ++ module might see the vDSO with l_addr being 0, meaning a fixed mapping ++ (linux-gate.so). In this case we don't check its value against ++ AT_SYSINFO_EHDR one. */ ++ uintptr_t vdso_process = 0; ++ bool vdso_audit_found = false; ++ uintptr_t vdso_audit = 0; ++ ++ FILE *out = fmemopen (result.err.buffer, result.err.length, "r"); ++ TEST_VERIFY (out != NULL); ++ char *buffer = NULL; ++ size_t buffer_length = 0; ++ while (xgetline (&buffer, &buffer_length, out)) ++ { ++ if (startswith (buffer, "vdso: ")) ++ vdso_process = parse_address (buffer + strlen ("vdso: ")); ++ else if (startswith (buffer, "vdso found: ")) ++ { ++ vdso_audit = parse_address (buffer + strlen ("vdso found: ")); ++ vdso_audit_found = true; ++ } ++ } ++ ++ TEST_COMPARE (vdso_audit_found, true); ++ if (vdso_audit != 0) ++ TEST_COMPARE (vdso_process, vdso_audit); ++ ++ free (buffer); ++ xfclose (out); ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION_ARGV do_test ++#include +diff --git a/elf/tst-auditmod22.c b/elf/tst-auditmod22.c +new file mode 100644 +index 0000000000000000..8e05ce8cbb215dd5 +--- /dev/null ++++ b/elf/tst-auditmod22.c +@@ -0,0 +1,51 @@ ++/* Check DTAUDIT and vDSO interaction. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static inline bool ++startswith (const char *str, const char *pre) ++{ ++ size_t lenpre = strlen (pre); ++ size_t lenstr = strlen (str); ++ return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0; ++} ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return LAV_CURRENT; ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ /* The linux-gate.so is placed at a fixed address, thus l_addr being 0, ++ and it might be the value reported as the AT_SYSINFO_EHDR. */ ++ if (map->l_addr == 0 && startswith (map->l_name, "linux-gate.so")) ++ fprintf (stderr, "vdso found: %p\n", NULL); ++ else if (map->l_addr == getauxval (AT_SYSINFO_EHDR)) ++ fprintf (stderr, "vdso found: %p\n", (void*) map->l_addr); ++ ++ return 0; ++} +diff --git a/include/dlfcn.h b/include/dlfcn.h +index a4c283728f94deb4..e73294b0af587913 100644 +--- a/include/dlfcn.h ++++ b/include/dlfcn.h +@@ -12,6 +12,8 @@ + #define __RTLD_AUDIT 0x08000000 + #define __RTLD_SECURE 0x04000000 /* Apply additional security checks. */ + #define __RTLD_NOIFUNC 0x02000000 /* Suppress calling ifunc functions. */ ++#define __RTLD_VDSO 0x01000000 /* Tell _dl_new_object the object is ++ system-loaded. */ + + #define __LM_ID_CALLER -2 + diff --git a/SOURCES/glibc-upstream-2.34-153.patch b/SOURCES/glibc-upstream-2.34-153.patch new file mode 100644 index 0000000..2dba7b1 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-153.patch @@ -0,0 +1,167 @@ +commit 2255621f0e2cd07f7a6147928ce644e13526ffb6 +Author: Adhemerval Zanella +Date: Wed Jun 30 17:33:57 2021 -0300 + + elf: Do not fail for failed dlmopen on audit modules (BZ #28061) + + The dl_main sets the LM_ID_BASE to RT_ADD just before starting to + add load new shared objects. The state is set to RT_CONSISTENT just + after all objects are loaded. + + However if a audit modules tries to dlmopen an inexistent module, + the _dl_open will assert that the namespace is in an inconsistent + state. + + This is different than dlopen, since first it will not use + LM_ID_BASE and second _dl_map_object_from_fd is the sole responsible + to set and reset the r_state value. + + So the assert on _dl_open can not really be seen if the state is + consistent, since _dt_main resets it. This patch removes the assert. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit 484e672ddabe0a919a692520e6ac8f2580866235) + + Resolved conflicts: + elf/Makefile + elf/dl-open.c + +diff --git a/elf/Makefile b/elf/Makefile +index 465442bf59fa9794..91b2269257523a64 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -366,6 +366,7 @@ tests += \ + tst-audit17 \ + tst-audit18 \ + tst-audit19b \ ++ tst-audit20 \ + tst-audit22 \ + tst-auditmany \ + tst-auxobj \ +@@ -650,6 +651,7 @@ modules-names = \ + tst-auditmod18 \ + tst-auditmod19a \ + tst-auditmod19b \ ++ tst-auditmod20 \ + tst-auditmod22 \ + tst-auxvalmod \ + tst-big-note-lib \ +@@ -2037,6 +2039,9 @@ $(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so + $(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so + tst-audit19b-ARGS = -- $(host-test-program-cmd) + ++$(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so ++tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so ++ + $(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so + tst-audit22-ARGS = -- $(host-test-program-cmd) + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 3f01aa480730da13..bc6872632880634e 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -914,8 +914,6 @@ no more namespaces available for dlmopen()")); + the flag here. */ + } + +- assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); +- + /* Release the lock. */ + __rtld_lock_unlock_recursive (GL(dl_load_lock)); + +diff --git a/elf/tst-audit20.c b/elf/tst-audit20.c +new file mode 100644 +index 0000000000000000..6f39ccee865b012b +--- /dev/null ++++ b/elf/tst-audit20.c +@@ -0,0 +1,25 @@ ++/* Check dlopen failure on audit modules. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++static int ++do_test (void) ++{ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-auditmod20.c b/elf/tst-auditmod20.c +new file mode 100644 +index 0000000000000000..c57e50ee4e88dd6b +--- /dev/null ++++ b/elf/tst-auditmod20.c +@@ -0,0 +1,57 @@ ++/* Check dlopen failure on audit modules. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++unsigned int ++la_version (unsigned int v) ++{ ++ return LAV_CURRENT; ++} ++ ++static void ++check (void) ++{ ++ { ++ void *mod = dlopen ("nonexistent.so", RTLD_NOW); ++ if (mod != NULL) ++ abort (); ++ } ++ ++ { ++ void *mod = dlmopen (LM_ID_BASE, "nonexistent.so", RTLD_NOW); ++ if (mod != NULL) ++ abort (); ++ } ++} ++ ++void ++la_activity (uintptr_t *cookie, unsigned int flag) ++{ ++ if (flag != LA_ACT_CONSISTENT) ++ return; ++ check (); ++} ++ ++void ++la_preinit (uintptr_t *cookie) ++{ ++ check (); ++} diff --git a/SOURCES/glibc-upstream-2.34-154.patch b/SOURCES/glibc-upstream-2.34-154.patch new file mode 100644 index 0000000..15b64cf --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-154.patch @@ -0,0 +1,434 @@ +commit 98047ba95caf9ed596908ca73a22070c5e27597b +Author: Adhemerval Zanella +Date: Mon Jan 24 10:46:15 2022 -0300 + + elf: Add la_activity during application exit + + la_activity is not called during application exit, even though + la_objclose is. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 5fa11a2bc94c912c3b25860065086902674537ba) + +diff --git a/elf/Makefile b/elf/Makefile +index 91b2269257523a64..407aaeaeb8c84020 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -368,6 +368,7 @@ tests += \ + tst-audit19b \ + tst-audit20 \ + tst-audit22 \ ++ tst-audit23 \ + tst-auditmany \ + tst-auxobj \ + tst-auxobj-dlopen \ +@@ -631,6 +632,7 @@ modules-names = \ + tst-audit13mod1 \ + tst-audit18mod \ + tst-audit19bmod \ ++ tst-audit23mod \ + tst-auditlogmod-1 \ + tst-auditlogmod-2 \ + tst-auditlogmod-3 \ +@@ -653,6 +655,7 @@ modules-names = \ + tst-auditmod19b \ + tst-auditmod20 \ + tst-auditmod22 \ ++ tst-auditmod23 \ + tst-auxvalmod \ + tst-big-note-lib \ + tst-deep1mod1 \ +@@ -2045,6 +2048,10 @@ tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so + $(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so + tst-audit22-ARGS = -- $(host-test-program-cmd) + ++$(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \ ++ $(objpfx)tst-audit23mod.so ++tst-audit23-ARGS = -- $(host-test-program-cmd) ++ + # tst-sonamemove links against an older implementation of the library. + LDFLAGS-tst-sonamemove-linkmod1.so = \ + -Wl,--version-script=tst-sonamemove-linkmod1.map \ +diff --git a/elf/dl-fini.c b/elf/dl-fini.c +index b789cfb9f2ac6c85..fa876da0ffa1cf97 100644 +--- a/elf/dl-fini.c ++++ b/elf/dl-fini.c +@@ -64,6 +64,10 @@ _dl_fini (void) + __rtld_lock_unlock_recursive (GL(dl_load_lock)); + else + { ++#ifdef SHARED ++ _dl_audit_activity_nsid (ns, LA_ACT_DELETE); ++#endif ++ + /* Now we can allocate an array to hold all the pointers and + copy the pointers in. */ + struct link_map *maps[nloaded]; +@@ -153,6 +157,10 @@ _dl_fini (void) + /* Correct the previous increment. */ + --l->l_direct_opencount; + } ++ ++#ifdef SHARED ++ _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT); ++#endif + } + } + +diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c +new file mode 100644 +index 0000000000000000..4904cf1340a97ee1 +--- /dev/null ++++ b/elf/tst-audit23.c +@@ -0,0 +1,239 @@ ++/* Check for expected la_objopen and la_objeclose for all objects. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int restart; ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++ ++static int ++handle_restart (void) ++{ ++ xdlopen ("tst-audit23mod.so", RTLD_NOW); ++ xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); ++ ++ return 0; ++} ++ ++static inline bool ++startswith (const char *str, const char *pre) ++{ ++ size_t lenpre = strlen (pre); ++ size_t lenstr = strlen (str); ++ return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0; ++} ++ ++static inline bool ++is_vdso (const char *str) ++{ ++ return startswith (str, "linux-gate") ++ || startswith (str, "linux-vdso"); ++} ++ ++static int ++do_test (int argc, char *argv[]) ++{ ++ /* We must have either: ++ - One or four parameters left if called initially: ++ + path to ld.so optional ++ + "--library-path" optional ++ + the library path optional ++ + the application name */ ++ if (restart) ++ return handle_restart (); ++ ++ char *spargv[9]; ++ TEST_VERIFY_EXIT (((argc - 1) + 3) < array_length (spargv)); ++ int i = 0; ++ for (; i < argc - 1; i++) ++ spargv[i] = argv[i + 1]; ++ spargv[i++] = (char *) "--direct"; ++ spargv[i++] = (char *) "--restart"; ++ spargv[i] = NULL; ++ ++ setenv ("LD_AUDIT", "tst-auditmod23.so", 0); ++ struct support_capture_subprocess result ++ = support_capture_subprogram (spargv[0], spargv); ++ support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr); ++ ++ /* The expected la_objopen/la_objclose: ++ 1. executable ++ 2. loader ++ 3. libc.so ++ 4. tst-audit23mod.so ++ 5. libc.so (LM_ID_NEWLM). ++ 6. vdso (optional and ignored). */ ++ enum { max_objs = 6 }; ++ struct la_obj_t ++ { ++ char *lname; ++ uintptr_t laddr; ++ Lmid_t lmid; ++ bool closed; ++ } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } }; ++ size_t nobjs = 0; ++ ++ /* The expected namespaces are one for the audit module, one for the ++ application, and another for the dlmopen on handle_restart. */ ++ enum { max_ns = 3 }; ++ uintptr_t acts[max_ns] = { 0 }; ++ size_t nacts = 0; ++ int last_act = -1; ++ uintptr_t last_act_cookie = -1; ++ bool seen_first_objclose = false; ++ ++ FILE *out = fmemopen (result.err.buffer, result.err.length, "r"); ++ TEST_VERIFY (out != NULL); ++ char *buffer = NULL; ++ size_t buffer_length = 0; ++ while (xgetline (&buffer, &buffer_length, out)) ++ { ++ if (startswith (buffer, "la_activity: ")) ++ { ++ uintptr_t cookie; ++ int this_act; ++ int r = sscanf (buffer, "la_activity: %d %"SCNxPTR"", &this_act, ++ &cookie); ++ TEST_COMPARE (r, 2); ++ ++ /* The cookie identifies the object at the head of the link map, ++ so we only add a new namespace if it changes from the previous ++ one. This works since dlmopen is the last in the test body. */ ++ if (cookie != last_act_cookie && last_act_cookie != -1) ++ TEST_COMPARE (last_act, LA_ACT_CONSISTENT); ++ ++ if (this_act == LA_ACT_ADD && acts[nacts] != cookie) ++ { ++ acts[nacts++] = cookie; ++ last_act_cookie = cookie; ++ } ++ /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD ++ at program termination (if the tests adds a dlclose or a library ++ with extra dependencies this will need to be adapted). */ ++ else if (this_act == LA_ACT_DELETE) ++ { ++ last_act_cookie = acts[--nacts]; ++ TEST_COMPARE (acts[nacts], cookie); ++ acts[nacts] = 0; ++ } ++ else if (this_act == LA_ACT_CONSISTENT) ++ { ++ TEST_COMPARE (cookie, last_act_cookie); ++ ++ /* LA_ACT_DELETE must always be followed by an la_objclose. */ ++ if (last_act == LA_ACT_DELETE) ++ TEST_COMPARE (seen_first_objclose, true); ++ else ++ TEST_COMPARE (last_act, LA_ACT_ADD); ++ } ++ ++ last_act = this_act; ++ seen_first_objclose = false; ++ } ++ else if (startswith (buffer, "la_objopen: ")) ++ { ++ char *lname; ++ uintptr_t laddr; ++ Lmid_t lmid; ++ uintptr_t cookie; ++ int r = sscanf (buffer, "la_objopen: %"SCNxPTR" %ms %"SCNxPTR" %ld", ++ &cookie, &lname, &laddr, &lmid); ++ TEST_COMPARE (r, 4); ++ ++ /* la_objclose is not triggered by vDSO because glibc does not ++ unload it. */ ++ if (is_vdso (lname)) ++ continue; ++ if (nobjs == max_objs) ++ FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld", ++ lname, laddr, lmid); ++ objs[nobjs].lname = lname; ++ objs[nobjs].laddr = laddr; ++ objs[nobjs].lmid = lmid; ++ objs[nobjs].closed = false; ++ nobjs++; ++ ++ /* This indirectly checks that la_objopen always comes before ++ la_objclose btween la_activity calls. */ ++ seen_first_objclose = false; ++ } ++ else if (startswith (buffer, "la_objclose: ")) ++ { ++ char *lname; ++ uintptr_t laddr; ++ Lmid_t lmid; ++ uintptr_t cookie; ++ int r = sscanf (buffer, "la_objclose: %"SCNxPTR" %ms %"SCNxPTR" %ld", ++ &cookie, &lname, &laddr, &lmid); ++ TEST_COMPARE (r, 4); ++ ++ for (size_t i = 0; i < nobjs; i++) ++ { ++ if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid) ++ { ++ TEST_COMPARE (objs[i].closed, false); ++ objs[i].closed = true; ++ break; ++ } ++ } ++ ++ /* la_objclose should be called after la_activity(LA_ACT_DELETE) for ++ the closed object's namespace. */ ++ TEST_COMPARE (last_act, LA_ACT_DELETE); ++ if (!seen_first_objclose) ++ { ++ TEST_COMPARE (last_act_cookie, cookie); ++ seen_first_objclose = true; ++ } ++ } ++ } ++ ++ for (size_t i = 0; i < nobjs; i++) ++ { ++ TEST_COMPARE (objs[i].closed, true); ++ free (objs[i].lname); ++ } ++ ++ /* la_activity(LA_ACT_CONSISTENT) should be the last callback received. ++ Since only one link map may be not-CONSISTENT at a time, this also ++ ensures la_activity(LA_ACT_CONSISTENT) is the last callback received ++ for every namespace. */ ++ TEST_COMPARE (last_act, LA_ACT_CONSISTENT); ++ ++ free (buffer); ++ xfclose (out); ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION_ARGV do_test ++#include +diff --git a/elf/tst-audit23mod.c b/elf/tst-audit23mod.c +new file mode 100644 +index 0000000000000000..30315687037d25e8 +--- /dev/null ++++ b/elf/tst-audit23mod.c +@@ -0,0 +1,23 @@ ++/* Extra module for tst-audit23 ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++int ++foo (void) ++{ ++ return 0; ++} +diff --git a/elf/tst-auditmod23.c b/elf/tst-auditmod23.c +new file mode 100644 +index 0000000000000000..d7c60d7a5cbc4f8a +--- /dev/null ++++ b/elf/tst-auditmod23.c +@@ -0,0 +1,74 @@ ++/* Audit module loaded by tst-audit23. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return LAV_CURRENT; ++} ++ ++struct map_desc_t ++{ ++ char *lname; ++ uintptr_t laddr; ++ Lmid_t lmid; ++}; ++ ++void ++la_activity (uintptr_t *cookie, unsigned int flag) ++{ ++ fprintf (stderr, "%s: %d %"PRIxPTR"\n", __func__, flag, (uintptr_t) cookie); ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ const char *l_name = map->l_name[0] == '\0' ? "mainapp" : map->l_name; ++ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__, ++ (uintptr_t) cookie, l_name, map->l_addr, lmid); ++ ++ struct map_desc_t *map_desc = malloc (sizeof (struct map_desc_t)); ++ if (map_desc == NULL) ++ abort (); ++ ++ map_desc->lname = strdup (l_name); ++ map_desc->laddr = map->l_addr; ++ map_desc->lmid = lmid; ++ ++ *cookie = (uintptr_t) map_desc; ++ ++ return 0; ++} ++ ++unsigned int ++la_objclose (uintptr_t *cookie) ++{ ++ struct map_desc_t *map_desc = (struct map_desc_t *) *cookie; ++ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__, ++ (uintptr_t) cookie, map_desc->lname, map_desc->laddr, ++ map_desc->lmid); ++ ++ return 0; ++} diff --git a/SOURCES/glibc-upstream-2.34-155.patch b/SOURCES/glibc-upstream-2.34-155.patch new file mode 100644 index 0000000..bb24edf --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-155.patch @@ -0,0 +1,299 @@ +commit efb21b5fb27fbad447d9f242436fb591870f0045 +Author: Adhemerval Zanella +Date: Mon Jan 24 10:46:16 2022 -0300 + + elf: Fix initial-exec TLS access on audit modules (BZ #28096) + + For audit modules and dependencies with initial-exec TLS, we can not + set the initial TLS image on default loader initialization because it + would already be set by the audit setup. However, subsequent thread + creation would need to follow the default behaviour. + + This patch fixes it by setting l_auditing link_map field not only + for the audit modules, but also for all its dependencies. This is + used on _dl_allocate_tls_init to avoid the static TLS initialization + at load time. + + Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 254d3d5aef2fd8430c469e1938209ac100ebf132) + +diff --git a/elf/Makefile b/elf/Makefile +index 407aaeaeb8c84020..3ccf78f62985e2d0 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -367,6 +367,7 @@ tests += \ + tst-audit18 \ + tst-audit19b \ + tst-audit20 \ ++ tst-audit21 \ + tst-audit22 \ + tst-audit23 \ + tst-auditmany \ +@@ -654,6 +655,8 @@ modules-names = \ + tst-auditmod19a \ + tst-auditmod19b \ + tst-auditmod20 \ ++ tst-auditmod21a \ ++ tst-auditmod21b \ + tst-auditmod22 \ + tst-auditmod23 \ + tst-auxvalmod \ +@@ -2045,6 +2048,11 @@ tst-audit19b-ARGS = -- $(host-test-program-cmd) + $(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so + tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so + ++$(objpfx)tst-audit21: $(shared-thread-library) ++$(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21a.so ++$(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so ++tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.so ++ + $(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so + tst-audit22-ARGS = -- $(host-test-program-cmd) + +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index e2012d0cd515103b..fab6546e2d31edd4 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -519,8 +519,12 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid) + } + + ++/* Allocate initial TLS. RESULT should be a non-NULL pointer to storage ++ for the TLS space. The DTV may be resized, and so this function may ++ call malloc to allocate that space. The loader's GL(dl_load_tls_lock) ++ is taken when manipulating global TLS-related data in the loader. */ + void * +-_dl_allocate_tls_init (void *result) ++_dl_allocate_tls_init (void *result, bool init_tls) + { + if (result == NULL) + /* The memory allocation failed. */ +@@ -593,7 +597,14 @@ _dl_allocate_tls_init (void *result) + some platforms use in static programs requires it. */ + dtv[map->l_tls_modid].pointer.val = dest; + +- /* Copy the initialization image and clear the BSS part. */ ++ /* Copy the initialization image and clear the BSS part. For ++ audit modules or dependencies with initial-exec TLS, we can not ++ set the initial TLS image on default loader initialization ++ because it would already be set by the audit setup. However, ++ subsequent thread creation would need to follow the default ++ behaviour. */ ++ if (map->l_ns != LM_ID_BASE && !init_tls) ++ continue; + memset (__mempcpy (dest, map->l_tls_initimage, + map->l_tls_initimage_size), '\0', + map->l_tls_blocksize - map->l_tls_initimage_size); +@@ -620,7 +631,7 @@ _dl_allocate_tls (void *mem) + { + return _dl_allocate_tls_init (mem == NULL + ? _dl_allocate_tls_storage () +- : allocate_dtv (mem)); ++ : allocate_dtv (mem), true); + } + rtld_hidden_def (_dl_allocate_tls) + +diff --git a/elf/rtld.c b/elf/rtld.c +index b089e5cf4740443e..26c6fb6479c9008c 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2429,7 +2429,7 @@ dl_main (const ElfW(Phdr) *phdr, + into the main thread's TLS area, which we allocated above. + Note: thread-local variables must only be accessed after completing + the next step. */ +- _dl_allocate_tls_init (tcbp); ++ _dl_allocate_tls_init (tcbp, false); + + /* And finally install it for the main thread. */ + if (! tls_init_tp_called) +diff --git a/elf/tst-audit21.c b/elf/tst-audit21.c +new file mode 100644 +index 0000000000000000..3a47ab64d44421ee +--- /dev/null ++++ b/elf/tst-audit21.c +@@ -0,0 +1,42 @@ ++/* Check LD_AUDIT with static TLS. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static volatile __thread int out __attribute__ ((tls_model ("initial-exec"))); ++ ++static void * ++tf (void *arg) ++{ ++ TEST_COMPARE (out, 0); ++ out = isspace (' '); ++ return NULL; ++} ++ ++int main (int argc, char *argv[]) ++{ ++ TEST_COMPARE (out, 0); ++ out = isspace (' '); ++ ++ pthread_t t = xpthread_create (NULL, tf, NULL); ++ xpthread_join (t); ++ ++ return 0; ++} +diff --git a/elf/tst-auditmod21a.c b/elf/tst-auditmod21a.c +new file mode 100644 +index 0000000000000000..f6d51b5c0531c49d +--- /dev/null ++++ b/elf/tst-auditmod21a.c +@@ -0,0 +1,80 @@ ++/* Check LD_AUDIT with static TLS. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#define tls_ie __attribute__ ((tls_model ("initial-exec"))) ++ ++__thread int tls_var0 tls_ie; ++__thread int tls_var1 tls_ie = 0x10; ++ ++/* Defined at tst-auditmod21b.so */ ++extern __thread int tls_var2; ++extern __thread int tls_var3; ++ ++static volatile int out; ++ ++static void ++call_libc (void) ++{ ++ /* isspace accesses the initial-exec glibc TLS variables, which are ++ setup in glibc initialization. */ ++ out = isspace (' '); ++} ++ ++unsigned int ++la_version (unsigned int v) ++{ ++ tls_var0 = 0x1; ++ if (tls_var1 != 0x10) ++ abort (); ++ tls_var1 = 0x20; ++ ++ tls_var2 = 0x2; ++ if (tls_var3 != 0x20) ++ abort (); ++ tls_var3 = 0x40; ++ ++ call_libc (); ++ ++ return LAV_CURRENT; ++} ++ ++unsigned int ++la_objopen (struct link_map* map, Lmid_t lmid, uintptr_t* cookie) ++{ ++ call_libc (); ++ *cookie = (uintptr_t) map; ++ return 0; ++} ++ ++void ++la_activity (uintptr_t* cookie, unsigned int flag) ++{ ++ if (tls_var0 != 0x1 || tls_var1 != 0x20) ++ abort (); ++ call_libc (); ++} ++ ++void ++la_preinit (uintptr_t* cookie) ++{ ++ call_libc (); ++} +diff --git a/elf/tst-auditmod21b.c b/elf/tst-auditmod21b.c +new file mode 100644 +index 0000000000000000..6ba5335b7514c674 +--- /dev/null ++++ b/elf/tst-auditmod21b.c +@@ -0,0 +1,22 @@ ++/* Check LD_AUDIT with static TLS. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define tls_ie __attribute__ ((tls_model ("initial-exec"))) ++ ++__thread int tls_var2 tls_ie; ++__thread int tls_var3 tls_ie = 0x20; +diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c +index 50065bc9bd8a28e5..554a721f814b53c4 100644 +--- a/nptl/allocatestack.c ++++ b/nptl/allocatestack.c +@@ -139,7 +139,7 @@ get_cached_stack (size_t *sizep, void **memp) + memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t)); + + /* Re-initialize the TLS. */ +- _dl_allocate_tls_init (TLS_TPADJ (result)); ++ _dl_allocate_tls_init (TLS_TPADJ (result), true); + + return result; + } +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 686f0a7b9709eb10..a56060d0204cc453 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1254,7 +1254,7 @@ extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden; + /* These are internal entry points to the two halves of _dl_allocate_tls, + only used within rtld.c itself at startup time. */ + extern void *_dl_allocate_tls_storage (void) attribute_hidden; +-extern void *_dl_allocate_tls_init (void *); ++extern void *_dl_allocate_tls_init (void *, bool); + rtld_hidden_proto (_dl_allocate_tls_init) + + /* Deallocate memory allocated with _dl_allocate_tls. */ diff --git a/SOURCES/glibc-upstream-2.34-156.patch b/SOURCES/glibc-upstream-2.34-156.patch new file mode 100644 index 0000000..528b157 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-156.patch @@ -0,0 +1,1778 @@ +commit 056fc1c0e367b9682d89f60fd5c249f80074ff30 +Author: Adhemerval Zanella +Date: Mon Jan 24 10:46:17 2022 -0300 + + elf: Issue la_symbind for bind-now (BZ #23734) + + The audit symbind callback is not called for binaries built with + -Wl,-z,now or when LD_BIND_NOW=1 is used, nor the PLT tracking callbacks + (plt_enter and plt_exit) since this would change the expected + program semantics (where no PLT is expected) and would have performance + implications (such as for BZ#15533). + + LAV_CURRENT is also bumped to indicate the audit ABI change (where + la_symbind flags are set by the loader to indicate no possible PLT + trace). + + To handle powerpc64 ELFv1 function descriptor, _dl_audit_symbind + requires to know whether bind-now is used so the symbol value is + updated to function text segment instead of the OPD (for lazy binding + this is done by PPC64_LOAD_FUNCPTR on _dl_runtime_resolve). + + Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, + powerpc64-linux-gnu. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 32612615c58b394c3eb09f020f31310797ad3854) + + Resolved conflicts: + NEWS - Manual merge. + +diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h +index 44fbea1e8060997f..c48835d12b512355 100644 +--- a/bits/link_lavcurrent.h ++++ b/bits/link_lavcurrent.h +@@ -22,4 +22,4 @@ + #endif + + /* Version numbers for la_version handshake interface. */ +-#define LAV_CURRENT 1 ++#define LAV_CURRENT 2 +diff --git a/elf/Makefile b/elf/Makefile +index 3ccf78f62985e2d0..0ab3e885f5e35671 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -370,6 +370,12 @@ tests += \ + tst-audit21 \ + tst-audit22 \ + tst-audit23 \ ++ tst-audit24a \ ++ tst-audit24b \ ++ tst-audit24c \ ++ tst-audit24d \ ++ tst-audit25a \ ++ tst-audit25b \ + tst-auditmany \ + tst-auxobj \ + tst-auxobj-dlopen \ +@@ -634,6 +640,18 @@ modules-names = \ + tst-audit18mod \ + tst-audit19bmod \ + tst-audit23mod \ ++ tst-audit24amod1 \ ++ tst-audit24amod2 \ ++ tst-audit24bmod1 \ ++ tst-audit24bmod2 \ ++ tst-audit24dmod1 \ ++ tst-audit24dmod2 \ ++ tst-audit24dmod3 \ ++ tst-audit24dmod4 \ ++ tst-audit25mod1 \ ++ tst-audit25mod2 \ ++ tst-audit25mod3 \ ++ tst-audit25mod4 \ + tst-auditlogmod-1 \ + tst-auditlogmod-2 \ + tst-auditlogmod-3 \ +@@ -659,6 +677,11 @@ modules-names = \ + tst-auditmod21b \ + tst-auditmod22 \ + tst-auditmod23 \ ++ tst-auditmod24a \ ++ tst-auditmod24b \ ++ tst-auditmod24c \ ++ tst-auditmod24d \ ++ tst-auditmod25 \ + tst-auxvalmod \ + tst-big-note-lib \ + tst-deep1mod1 \ +@@ -864,7 +887,8 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) + + # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special + # rules. +-modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod ++modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \ ++ tst-audit24bmod1 tst-audit24bmod2.so + + tests += $(tests-static) + +@@ -2060,6 +2084,69 @@ $(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \ + $(objpfx)tst-audit23mod.so + tst-audit23-ARGS = -- $(host-test-program-cmd) + ++$(objpfx)tst-audit24a.out: $(objpfx)tst-auditmod24a.so ++$(objpfx)tst-audit24a: $(objpfx)tst-audit24amod1.so \ ++ $(objpfx)tst-audit24amod2.so ++tst-audit24a-ENV = LD_AUDIT=$(objpfx)tst-auditmod24a.so ++LDFLAGS-tst-audit24a = -Wl,-z,now ++ ++$(objpfx)tst-audit24b.out: $(objpfx)tst-auditmod24b.so ++$(objpfx)tst-audit24b: $(objpfx)tst-audit24bmod1.so \ ++ $(objpfx)tst-audit24bmod2.so ++$(objpfx)tst-audit24bmod1: $(objpfx)tst-audit24bmod2.so ++# The test checks if a library without .gnu.version correctly calls the ++# audit callbacks. So it uses an explicit link rule to avoid linking ++# against libc.so. ++$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os ++ $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \ ++ -Wl,-z,now ++ $(call after-link,$@.new) ++ mv -f $@.new $@ ++CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod1) ++$(objpfx)tst-audit24bmod2.so: $(objpfx)tst-audit24bmod2.os ++ $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os ++ $(call after-link,$@.new) ++ mv -f $@.new $@ ++CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod2) ++tst-audit24b-ENV = LD_AUDIT=$(objpfx)tst-auditmod24b.so ++LDFLAGS-tst-audit24b = -Wl,-z,now ++ ++# Same as tst-audit24a, but tests LD_BIND_NOW ++$(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so ++$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \ ++ $(objpfx)tst-audit24amod2.so ++tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so ++LDFLAGS-tst-audit24b = -Wl,-z,lazy ++ ++$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so ++$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \ ++ $(objpfx)tst-audit24dmod2.so ++$(objpfx)tst-audit24dmod1.so: $(objpfx)tst-audit24dmod3.so ++LDFLAGS-tst-audit24dmod1.so = -Wl,-z,now ++$(objpfx)tst-audit24dmod2.so: $(objpfx)tst-audit24dmod4.so ++LDFLAGS-tst-audit24dmod2.so = -Wl,-z,lazy ++tst-audit24d-ENV = LD_AUDIT=$(objpfx)tst-auditmod24d.so ++LDFLAGS-tst-audit24d = -Wl,-z,lazy ++ ++$(objpfx)tst-audit25a.out: $(objpfx)tst-auditmod25.so ++$(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \ ++ $(objpfx)tst-audit25mod2.so \ ++ $(objpfx)tst-audit25mod3.so \ ++ $(objpfx)tst-audit25mod4.so ++$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so ++LDFLAGS-tst-audit25mod1.so = -Wl,-z,now ++$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so ++LDFLAGS-tst-audit25mod2.so = -Wl,-z,lazy ++tst-audit25a-ARGS = -- $(host-test-program-cmd) ++ ++$(objpfx)tst-audit25b.out: $(objpfx)tst-auditmod25.so ++$(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \ ++ $(objpfx)tst-audit25mod2.so \ ++ $(objpfx)tst-audit25mod3.so \ ++ $(objpfx)tst-audit25mod4.so ++LDFLAGS-tst-audit25b = -Wl,-z,now ++tst-audit25b-ARGS = -- $(host-test-program-cmd) ++ + # tst-sonamemove links against an older implementation of the library. + LDFLAGS-tst-sonamemove-linkmod1.so = \ + -Wl,--version-script=tst-sonamemove-linkmod1.map \ +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +index 152712b12fed6de2..72a50717ef60a357 100644 +--- a/elf/dl-audit.c ++++ b/elf/dl-audit.c +@@ -178,16 +178,23 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, + const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, + lookup_t result) + { +- reloc_result->bound = result; +- /* Compute index of the symbol entry in the symbol table of the DSO with the +- definition. */ +- reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result, +- l_info[DT_SYMTAB])); ++ bool for_jmp_slot = reloc_result == NULL; ++ ++ /* Compute index of the symbol entry in the symbol table of the DSO ++ with the definition. */ ++ unsigned int boundndx = defsym - (ElfW(Sym) *) D_PTR (result, ++ l_info[DT_SYMTAB]); ++ if (!for_jmp_slot) ++ { ++ reloc_result->bound = result; ++ reloc_result->boundndx = boundndx; ++ } + + if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0) + { + /* Set all bits since this symbol binding is not interesting. */ +- reloc_result->enterexit = (1u << DL_NNS) - 1; ++ if (!for_jmp_slot) ++ reloc_result->enterexit = (1u << DL_NNS) - 1; + return; + } + +@@ -199,12 +206,13 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, + two bits. */ + assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8); + assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3); +- reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; ++ uint32_t enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; + + const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); + + unsigned int flags = 0; + struct audit_ifaces *afct = GLRO(dl_audit); ++ uintptr_t new_value = (uintptr_t) sym.st_value; + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + /* XXX Check whether both DSOs must request action or only one */ +@@ -215,37 +223,41 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, + { + if (afct->symbind != NULL) + { +- uintptr_t new_value = afct->symbind (&sym, +- reloc_result->boundndx, +- &l_state->cookie, +- &result_state->cookie, +- &flags, +- strtab2 + defsym->st_name); ++ flags |= for_jmp_slot ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT ++ : 0; ++ new_value = afct->symbind (&sym, boundndx, ++ &l_state->cookie, ++ &result_state->cookie, &flags, ++ strtab2 + defsym->st_name); + if (new_value != (uintptr_t) sym.st_value) + { + flags |= LA_SYMB_ALTVALUE; +- sym.st_value = new_value; ++ sym.st_value = for_jmp_slot ++ ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value; + } + } + + /* Remember the results for every audit library and store a summary + in the first two bits. */ +- reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER +- | LA_SYMB_NOPLTEXIT); +- reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER +- | LA_SYMB_NOPLTEXIT)) +- << ((cnt + 1) * 2)); ++ enterexit &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT); ++ enterexit |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) ++ << ((cnt + 1) * 2)); + } + else + /* If the bind flags say this auditor is not interested, set the bits + manually. */ +- reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) +- << ((cnt + 1) * 2)); ++ enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ++ << ((cnt + 1) * 2)); + afct = afct->next; + } + +- reloc_result->flags = flags; +- *value = DL_FIXUP_ADDR_VALUE (sym.st_value); ++ if (!for_jmp_slot) ++ { ++ reloc_result->enterexit = enterexit; ++ reloc_result->flags = flags; ++ } ++ ++ DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value); + } + + void +diff --git a/elf/do-rel.h b/elf/do-rel.h +index f441b749190c2641..4b7fc14f74cb5d09 100644 +--- a/elf/do-rel.h ++++ b/elf/do-rel.h +@@ -16,6 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + ++#include ++ + /* This file may be included twice, to define both + `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */ + +@@ -123,6 +125,10 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], + + for (; r < end; ++r) + { ++ ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; ++ const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; ++ void *const r_addr_arg = (void *) (l_addr + r->r_offset); ++ const struct r_found_version *rversion = &map->l_versions[ndx]; + #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) + { +@@ -133,10 +139,19 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], + } + #endif + +- ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; +- elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], +- &map->l_versions[ndx], +- (void *) (l_addr + r->r_offset), skip_ifunc); ++ elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg, ++ skip_ifunc); ++#if defined SHARED && !defined RTLD_BOOTSTRAP ++ if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT ++ && GLRO(dl_naudit) > 0) ++ { ++ struct link_map *sym_map ++ = RESOLVE_MAP (map, scope, &sym, rversion, ++ ELF_MACHINE_JMP_SLOT); ++ if (sym != NULL) ++ _dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map); ++ } ++#endif + } + + #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP +@@ -158,17 +173,33 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], + else + { + for (; r < end; ++r) ++ { ++ const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; ++ void *const r_addr_arg = (void *) (l_addr + r->r_offset); + # ifdef ELF_MACHINE_IRELATIVE +- if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) +- { +- if (r2 == NULL) +- r2 = r; +- end2 = r; +- } +- else ++ if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) ++ { ++ if (r2 == NULL) ++ r2 = r; ++ end2 = r; ++ continue; ++ } + # endif +- elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, +- (void *) (l_addr + r->r_offset), skip_ifunc); ++ elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg, ++ skip_ifunc); ++# if defined SHARED && !defined RTLD_BOOTSTRAP ++ if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT ++ && GLRO(dl_naudit) > 0) ++ { ++ struct link_map *sym_map ++ = RESOLVE_MAP (map, scope, &sym, ++ (struct r_found_version *) NULL, ++ ELF_MACHINE_JMP_SLOT); ++ if (sym != NULL) ++ _dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map); ++ } ++# endif ++ } + + # ifdef ELF_MACHINE_IRELATIVE + if (r2 != NULL) +diff --git a/elf/sotruss-lib.c b/elf/sotruss-lib.c +index b711f7b0c892a972..e4ebc8dbc697df3f 100644 +--- a/elf/sotruss-lib.c ++++ b/elf/sotruss-lib.c +@@ -17,6 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + #include + #include +@@ -232,6 +233,12 @@ uintptr_t + la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) + { ++ if (*flags & LA_SYMB_NOPLTENTER) ++ warnx ("cannot trace PLT enter (bind-now enabled)"); ++ ++ if (do_exit && *flags & LA_SYMB_NOPLTEXIT) ++ warnx ("cannot trace PLT exit (bind-now enabled)"); ++ + if (!do_exit) + *flags = LA_SYMB_NOPLTEXIT; + +diff --git a/elf/tst-audit24a.c b/elf/tst-audit24a.c +new file mode 100644 +index 0000000000000000..a1781c9b45f18fa0 +--- /dev/null ++++ b/elf/tst-audit24a.c +@@ -0,0 +1,36 @@ ++/* LD_AUDIT test for la_symbind and bind-now. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int tst_audit24amod1_func1 (void); ++int tst_audit24amod1_func2 (void); ++int tst_audit24amod2_func1 (void); ++ ++int ++do_test (void) ++{ ++ TEST_COMPARE (tst_audit24amod1_func1 (), 1); ++ TEST_COMPARE (tst_audit24amod1_func2 (), 2); ++ TEST_COMPARE (tst_audit24amod2_func1 (), 10); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-audit24amod1.c b/elf/tst-audit24amod1.c +new file mode 100644 +index 0000000000000000..0289a4abefbc7bbb +--- /dev/null ++++ b/elf/tst-audit24amod1.c +@@ -0,0 +1,31 @@ ++/* Module used by tst-audit24a. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++_Noreturn int ++tst_audit24amod1_func1 (void) ++{ ++ abort (); ++} ++ ++int ++tst_audit24amod1_func2 (void) ++{ ++ return 2; ++} +diff --git a/elf/tst-audit24amod2.c b/elf/tst-audit24amod2.c +new file mode 100644 +index 0000000000000000..1562afc9dfc1b9b3 +--- /dev/null ++++ b/elf/tst-audit24amod2.c +@@ -0,0 +1,25 @@ ++/* Module used by tst-audit24a. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++_Noreturn int ++tst_audit24amod2_func1 (void) ++{ ++ abort (); ++} +diff --git a/elf/tst-audit24b.c b/elf/tst-audit24b.c +new file mode 100644 +index 0000000000000000..567bee52c27f4361 +--- /dev/null ++++ b/elf/tst-audit24b.c +@@ -0,0 +1,37 @@ ++/* LD_AUDIT test for la_symbind and bind-now. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This is similar to tst-audit24a, with the difference this modules ++ does not have the .gnu.version section header. */ ++ ++#include ++#include ++ ++int tst_audit24bmod1_func1 (void); ++int tst_audit24bmod1_func2 (void); ++ ++int ++do_test (void) ++{ ++ TEST_COMPARE (tst_audit24bmod1_func1 (), 1); ++ TEST_COMPARE (tst_audit24bmod1_func2 (), 2); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-audit24bmod1.c b/elf/tst-audit24bmod1.c +new file mode 100644 +index 0000000000000000..57ce14a01bf72fb6 +--- /dev/null ++++ b/elf/tst-audit24bmod1.c +@@ -0,0 +1,31 @@ ++/* Module used by tst-audit24c. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++int tst_audit24bmod2_func1 (void); ++ ++int ++tst_audit24bmod1_func1 (void) ++{ ++ return -1; ++} ++ ++int ++tst_audit24bmod1_func2 (void) ++{ ++ return tst_audit24bmod2_func1 (); ++} +diff --git a/elf/tst-audit24bmod2.c b/elf/tst-audit24bmod2.c +new file mode 100644 +index 0000000000000000..b298ce0a05bf2db2 +--- /dev/null ++++ b/elf/tst-audit24bmod2.c +@@ -0,0 +1,23 @@ ++/* Module used by tst-audit24b. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++int ++tst_audit24bmod2_func1 (void) ++{ ++ return -1; ++} +diff --git a/elf/tst-audit24c.c b/elf/tst-audit24c.c +new file mode 100644 +index 0000000000000000..46ed328756067276 +--- /dev/null ++++ b/elf/tst-audit24c.c +@@ -0,0 +1,2 @@ ++/* It tests LD_BIND_NOW=1 instead of linking with -Wl,-z,now */ ++#include "tst-audit24a.c" +diff --git a/elf/tst-audit24d.c b/elf/tst-audit24d.c +new file mode 100644 +index 0000000000000000..543f3b86a6bbdead +--- /dev/null ++++ b/elf/tst-audit24d.c +@@ -0,0 +1,36 @@ ++/* LD_AUDIT test for la_symbind and bind-now. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int tst_audit24dmod1_func1 (void); ++int tst_audit24dmod1_func2 (void); ++int tst_audit24dmod2_func1 (void); ++ ++int ++do_test (void) ++{ ++ TEST_COMPARE (tst_audit24dmod1_func1 (), 1); ++ TEST_COMPARE (tst_audit24dmod1_func2 (), 32); ++ TEST_COMPARE (tst_audit24dmod2_func1 (), 10); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-audit24dmod1.c b/elf/tst-audit24dmod1.c +new file mode 100644 +index 0000000000000000..e563f69d638ac3f5 +--- /dev/null ++++ b/elf/tst-audit24dmod1.c +@@ -0,0 +1,33 @@ ++/* Module used by tst-audit24d. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++int tst_audit24dmod3_func1 (void); ++ ++_Noreturn int ++tst_audit24dmod1_func1 (void) ++{ ++ abort (); ++} ++ ++int ++tst_audit24dmod1_func2 (void) ++{ ++ return 2 + tst_audit24dmod3_func1 ();; ++} +diff --git a/elf/tst-audit24dmod2.c b/elf/tst-audit24dmod2.c +new file mode 100644 +index 0000000000000000..03fe9381281e5790 +--- /dev/null ++++ b/elf/tst-audit24dmod2.c +@@ -0,0 +1,28 @@ ++/* Module for tst-audit24d. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++int tst_audit24dmod4_func1 (void); ++ ++_Noreturn int ++tst_audit24dmod2_func1 (void) ++{ ++ tst_audit24dmod4_func1 (); ++ abort (); ++} +diff --git a/elf/tst-audit24dmod3.c b/elf/tst-audit24dmod3.c +new file mode 100644 +index 0000000000000000..106d517d2887d76c +--- /dev/null ++++ b/elf/tst-audit24dmod3.c +@@ -0,0 +1,31 @@ ++/* Module for tst-audit24d. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++_Noreturn int ++tst_audit24dmod3_func1 (void) ++{ ++ abort (); ++} ++ ++int ++tst_audit24dmod3_func2 (void) ++{ ++ return 4; ++} +diff --git a/elf/tst-audit24dmod4.c b/elf/tst-audit24dmod4.c +new file mode 100644 +index 0000000000000000..1da3b46917ba1083 +--- /dev/null ++++ b/elf/tst-audit24dmod4.c +@@ -0,0 +1,25 @@ ++/* Module for tst-audit24d. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++_Noreturn int ++tst_audit24dmod4_func1 (void) ++{ ++ abort (); ++} +diff --git a/elf/tst-audit25a.c b/elf/tst-audit25a.c +new file mode 100644 +index 0000000000000000..49173e862516e876 +--- /dev/null ++++ b/elf/tst-audit25a.c +@@ -0,0 +1,129 @@ ++/* Check LD_AUDIT and LD_BIND_NOW. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int restart; ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++ ++void tst_audit25mod1_func1 (void); ++void tst_audit25mod1_func2 (void); ++void tst_audit25mod2_func1 (void); ++void tst_audit25mod2_func2 (void); ++ ++static int ++handle_restart (void) ++{ ++ tst_audit25mod1_func1 (); ++ tst_audit25mod1_func2 (); ++ tst_audit25mod2_func1 (); ++ tst_audit25mod2_func2 (); ++ ++ return 0; ++} ++ ++static inline bool ++startswith (const char *str, const char *pre) ++{ ++ size_t lenpre = strlen (pre); ++ size_t lenstr = strlen (str); ++ return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0; ++} ++ ++static int ++do_test (int argc, char *argv[]) ++{ ++ /* We must have either: ++ - One or four parameters left if called initially: ++ + path to ld.so optional ++ + "--library-path" optional ++ + the library path optional ++ + the application name */ ++ ++ if (restart) ++ return handle_restart (); ++ ++ setenv ("LD_AUDIT", "tst-auditmod25.so", 0); ++ ++ char *spargv[9]; ++ int i = 0; ++ for (; i < argc - 1; i++) ++ spargv[i] = argv[i + 1]; ++ spargv[i++] = (char *) "--direct"; ++ spargv[i++] = (char *) "--restart"; ++ spargv[i] = NULL; ++ TEST_VERIFY_EXIT (i < array_length (spargv)); ++ ++ { ++ struct support_capture_subprocess result ++ = support_capture_subprogram (spargv[0], spargv); ++ support_capture_subprocess_check (&result, "tst-audit25a", 0, ++ sc_allow_stderr); ++ ++ /* tst-audit25a is build with -Wl,-z,lazy and tst-audit25mod1 with ++ -Wl,-z,now; so only tst_audit25mod3_func1 should be expected to ++ have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ ++ TEST_COMPARE_STRING (result.err.buffer, ++ "la_symbind: tst_audit25mod3_func1 1\n" ++ "la_symbind: tst_audit25mod1_func1 0\n" ++ "la_symbind: tst_audit25mod1_func2 0\n" ++ "la_symbind: tst_audit25mod2_func1 0\n" ++ "la_symbind: tst_audit25mod4_func1 0\n" ++ "la_symbind: tst_audit25mod2_func2 0\n"); ++ ++ support_capture_subprocess_free (&result); ++ } ++ ++ { ++ setenv ("LD_BIND_NOW", "1", 0); ++ struct support_capture_subprocess result ++ = support_capture_subprogram (spargv[0], spargv); ++ support_capture_subprocess_check (&result, "tst-audit25a", 0, ++ sc_allow_stderr); ++ ++ /* With LD_BIND_NOW all symbols are expected to have ++ LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution ++ order is done in breadth-first order. */ ++ TEST_COMPARE_STRING (result.err.buffer, ++ "la_symbind: tst_audit25mod4_func1 1\n" ++ "la_symbind: tst_audit25mod3_func1 1\n" ++ "la_symbind: tst_audit25mod1_func1 1\n" ++ "la_symbind: tst_audit25mod2_func1 1\n" ++ "la_symbind: tst_audit25mod1_func2 1\n" ++ "la_symbind: tst_audit25mod2_func2 1\n"); ++ ++ support_capture_subprocess_free (&result); ++ } ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION_ARGV do_test ++#include +diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c +new file mode 100644 +index 0000000000000000..a56638d501f9bff5 +--- /dev/null ++++ b/elf/tst-audit25b.c +@@ -0,0 +1,128 @@ ++/* Check LD_AUDIT and LD_BIND_NOW. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int restart; ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++ ++void tst_audit25mod1_func1 (void); ++void tst_audit25mod1_func2 (void); ++void tst_audit25mod2_func1 (void); ++void tst_audit25mod2_func2 (void); ++ ++static int ++handle_restart (void) ++{ ++ tst_audit25mod1_func1 (); ++ tst_audit25mod1_func2 (); ++ tst_audit25mod2_func1 (); ++ tst_audit25mod2_func2 (); ++ ++ return 0; ++} ++ ++static inline bool ++startswith (const char *str, const char *pre) ++{ ++ size_t lenpre = strlen (pre); ++ size_t lenstr = strlen (str); ++ return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0; ++} ++ ++static int ++do_test (int argc, char *argv[]) ++{ ++ /* We must have either: ++ - One or four parameters left if called initially: ++ + path to ld.so optional ++ + "--library-path" optional ++ + the library path optional ++ + the application name */ ++ ++ if (restart) ++ return handle_restart (); ++ ++ setenv ("LD_AUDIT", "tst-auditmod25.so", 0); ++ ++ char *spargv[9]; ++ int i = 0; ++ for (; i < argc - 1; i++) ++ spargv[i] = argv[i + 1]; ++ spargv[i++] = (char *) "--direct"; ++ spargv[i++] = (char *) "--restart"; ++ spargv[i] = NULL; ++ ++ { ++ struct support_capture_subprocess result ++ = support_capture_subprogram (spargv[0], spargv); ++ support_capture_subprocess_check (&result, "tst-audit25a", 0, ++ sc_allow_stderr); ++ ++ /* tst-audit25a and tst-audit25mod1 are built with -Wl,-z,now, but ++ tst-audit25mod2 is built with -Wl,-z,lazy. So only ++ tst_audit25mod4_func1 (called by tst_audit25mod2_func1) should not ++ have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ ++ TEST_COMPARE_STRING (result.err.buffer, ++ "la_symbind: tst_audit25mod3_func1 1\n" ++ "la_symbind: tst_audit25mod1_func1 1\n" ++ "la_symbind: tst_audit25mod2_func1 1\n" ++ "la_symbind: tst_audit25mod1_func2 1\n" ++ "la_symbind: tst_audit25mod2_func2 1\n" ++ "la_symbind: tst_audit25mod4_func1 0\n"); ++ ++ support_capture_subprocess_free (&result); ++ } ++ ++ { ++ setenv ("LD_BIND_NOW", "1", 0); ++ struct support_capture_subprocess result ++ = support_capture_subprogram (spargv[0], spargv); ++ support_capture_subprocess_check (&result, "tst-audit25a", 0, ++ sc_allow_stderr); ++ ++ /* With LD_BIND_NOW all symbols are expected to have ++ LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution ++ order is done in breadth-first order. */ ++ TEST_COMPARE_STRING (result.err.buffer, ++ "la_symbind: tst_audit25mod4_func1 1\n" ++ "la_symbind: tst_audit25mod3_func1 1\n" ++ "la_symbind: tst_audit25mod1_func1 1\n" ++ "la_symbind: tst_audit25mod2_func1 1\n" ++ "la_symbind: tst_audit25mod1_func2 1\n" ++ "la_symbind: tst_audit25mod2_func2 1\n"); ++ ++ support_capture_subprocess_free (&result); ++ } ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION_ARGV do_test ++#include +diff --git a/elf/tst-audit25mod1.c b/elf/tst-audit25mod1.c +new file mode 100644 +index 0000000000000000..a132e34a9b2cf51f +--- /dev/null ++++ b/elf/tst-audit25mod1.c +@@ -0,0 +1,30 @@ ++/* Module used by tst-audit25. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++void tst_audit25mod3_func1 (void); ++ ++void ++tst_audit25mod1_func1 (void) ++{ ++ tst_audit25mod3_func1 (); ++} ++ ++void ++tst_audit25mod1_func2 (void) ++{ ++} +diff --git a/elf/tst-audit25mod2.c b/elf/tst-audit25mod2.c +new file mode 100644 +index 0000000000000000..92da26fa80b202c2 +--- /dev/null ++++ b/elf/tst-audit25mod2.c +@@ -0,0 +1,30 @@ ++/* Module used by tst-audit25. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++void tst_audit25mod4_func1 (void); ++ ++void ++tst_audit25mod2_func1 (void) ++{ ++ tst_audit25mod4_func1 (); ++} ++ ++void ++tst_audit25mod2_func2 (void) ++{ ++} +diff --git a/elf/tst-audit25mod3.c b/elf/tst-audit25mod3.c +new file mode 100644 +index 0000000000000000..af83e8919083adef +--- /dev/null ++++ b/elf/tst-audit25mod3.c +@@ -0,0 +1,22 @@ ++/* Module used by tst-audit25. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++void ++tst_audit25mod3_func1 (void) ++{ ++} +diff --git a/elf/tst-audit25mod4.c b/elf/tst-audit25mod4.c +new file mode 100644 +index 0000000000000000..6cdf34357582da16 +--- /dev/null ++++ b/elf/tst-audit25mod4.c +@@ -0,0 +1,22 @@ ++/* Module used by tst-audit25. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++void ++tst_audit25mod4_func1 (void) ++{ ++} +diff --git a/elf/tst-auditmod24.h b/elf/tst-auditmod24.h +new file mode 100644 +index 0000000000000000..5fdbfef12dac2b2a +--- /dev/null ++++ b/elf/tst-auditmod24.h +@@ -0,0 +1,29 @@ ++/* Auxiliary functions for tst-audit24x. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _TST_AUDITMOD24_H ++#define _TST_AUDITMOD24_H ++ ++static void ++test_symbind_flags (unsigned int flags) ++{ ++ if ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 0) ++ abort (); ++} ++ ++#endif +diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c +new file mode 100644 +index 0000000000000000..d8e88f3984af1707 +--- /dev/null ++++ b/elf/tst-auditmod24a.c +@@ -0,0 +1,114 @@ ++/* Audit modules for tst-audit24a. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define AUDIT24_COOKIE 0x1 ++#define AUDIT24MOD1_COOKIE 0x2 ++#define AUDIT24MOD2_COOKIE 0x3 ++ ++#ifndef TEST_NAME ++# define TEST_NAME "tst-audit24a" ++#endif ++#ifndef TEST_MOD ++# define TEST_MOD TEST_NAME ++#endif ++#ifndef TEST_FUNC ++# define TEST_FUNC "tst_audit24a" ++#endif ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return LAV_CURRENT; ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ const char *p = strrchr (map->l_name, '/'); ++ const char *l_name = p == NULL ? TEST_NAME : p + 1; ++ ++ uintptr_t ck = -1; ++ if (strcmp (l_name, TEST_MOD "mod1.so") == 0) ++ ck = AUDIT24MOD1_COOKIE; ++ else if (strcmp (l_name, TEST_MOD "mod2.so") == 0) ++ ck = AUDIT24MOD2_COOKIE; ++ else if (strcmp (l_name, TEST_NAME) == 0) ++ ck = AUDIT24_COOKIE; ++ ++ *cookie = ck; ++ return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; ++} ++ ++static int ++tst_func1 (void) ++{ ++ return 1; ++} ++ ++static int ++tst_func2 (void) ++{ ++ return 10; ++} ++ ++#if __ELF_NATIVE_CLASS == 64 ++uintptr_t ++la_symbind64 (Elf64_Sym *sym, unsigned int ndx, ++ uintptr_t *refcook, uintptr_t *defcook, ++ unsigned int *flags, const char *symname) ++#else ++uintptr_t ++la_symbind32 (Elf32_Sym *sym, unsigned int ndx, ++ uintptr_t *refcook, uintptr_t *defcook, ++ unsigned int *flags, const char *symname) ++#endif ++{ ++ if (*refcook == AUDIT24_COOKIE) ++ { ++ if (*defcook == AUDIT24MOD1_COOKIE) ++ { ++ /* Check if bind-now symbols are advertised to not call the PLT ++ hooks. */ ++ test_symbind_flags (*flags); ++ ++ if (strcmp (symname, TEST_FUNC "mod1_func1") == 0) ++ return (uintptr_t) tst_func1; ++ else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0) ++ return sym->st_value; ++ abort (); ++ } ++ if (*defcook == AUDIT24MOD2_COOKIE ++ && (strcmp (symname, TEST_FUNC "mod2_func1") == 0)) ++ { ++ test_symbind_flags (*flags); ++ ++ return (uintptr_t) tst_func2; ++ } ++ ++ /* malloc functions. */ ++ return sym->st_value; ++ } ++ ++ abort (); ++} +diff --git a/elf/tst-auditmod24b.c b/elf/tst-auditmod24b.c +new file mode 100644 +index 0000000000000000..e98f6d5ec528fe03 +--- /dev/null ++++ b/elf/tst-auditmod24b.c +@@ -0,0 +1,104 @@ ++/* Audit modules for tst-audit24b. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define TEST_NAME "tst-audit24b" ++#define TEST_FUNC "tst_audit24b" ++ ++#define AUDIT24_COOKIE 0x1 ++#define AUDIT24MOD1_COOKIE 0x2 ++#define AUDIT24MOD2_COOKIE 0x3 ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return LAV_CURRENT; ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ const char *p = strrchr (map->l_name, '/'); ++ const char *l_name = p == NULL ? TEST_NAME : p + 1; ++ ++ uintptr_t ck = -1; ++ if (strcmp (l_name, TEST_NAME "mod1.so") == 0) ++ ck = AUDIT24MOD1_COOKIE; ++ else if (strcmp (l_name, TEST_NAME "mod2.so") == 0) ++ ck = AUDIT24MOD2_COOKIE; ++ else if (strcmp (l_name, TEST_NAME) == 0) ++ ck = AUDIT24_COOKIE; ++ ++ *cookie = ck; ++ return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; ++} ++ ++static int ++tst_func1 (void) ++{ ++ return 1; ++} ++ ++static int ++tst_func2 (void) ++{ ++ return 2; ++} ++ ++#if __ELF_NATIVE_CLASS == 64 ++uintptr_t ++la_symbind64 (Elf64_Sym *sym, unsigned int ndx, ++ uintptr_t *refcook, uintptr_t *defcook, ++ unsigned int *flags, const char *symname) ++#else ++uintptr_t ++la_symbind32 (Elf32_Sym *sym, unsigned int ndx, ++ uintptr_t *refcook, uintptr_t *defcook, ++ unsigned int *flags, const char *symname) ++#endif ++{ ++ if (*refcook == AUDIT24_COOKIE) ++ { ++ if (*defcook == AUDIT24MOD1_COOKIE) ++ { ++ if (strcmp (symname, TEST_FUNC "mod1_func1") == 0) ++ return (uintptr_t) tst_func1; ++ else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0) ++ return sym->st_value; ++ abort (); ++ } ++ /* malloc functions. */ ++ return sym->st_value; ++ } ++ else if (*refcook == AUDIT24MOD1_COOKIE) ++ { ++ if (*defcook == AUDIT24MOD2_COOKIE ++ && (strcmp (symname, TEST_FUNC "mod2_func1") == 0)) ++ { ++ test_symbind_flags (*flags); ++ return (uintptr_t) tst_func2; ++ } ++ } ++ ++ abort (); ++} +diff --git a/elf/tst-auditmod24c.c b/elf/tst-auditmod24c.c +new file mode 100644 +index 0000000000000000..67e62c9d332f48a7 +--- /dev/null ++++ b/elf/tst-auditmod24c.c +@@ -0,0 +1,3 @@ ++#define TEST_NAME "tst-audit24c" ++#define TEST_MOD "tst-audit24a" ++#include "tst-auditmod24a.c" +diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c +new file mode 100644 +index 0000000000000000..8c803ecc0a48f21b +--- /dev/null ++++ b/elf/tst-auditmod24d.c +@@ -0,0 +1,120 @@ ++/* Audit module for tst-audit24d. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define AUDIT24_COOKIE 0x0 ++#define AUDIT24MOD1_COOKIE 0x1 ++#define AUDIT24MOD2_COOKIE 0x2 ++#define AUDIT24MOD3_COOKIE 0x3 ++#define AUDIT24MOD4_COOKIE 0x4 ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return LAV_CURRENT; ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ const char *p = strrchr (map->l_name, '/'); ++ const char *l_name = p == NULL ? "tst-audit24d" : p + 1; ++ ++ uintptr_t ck = -1; ++ if (strcmp (l_name, "tst-audit24dmod1.so") == 0) ++ ck = AUDIT24MOD1_COOKIE; ++ else if (strcmp (l_name, "tst-audit24dmod2.so") == 0) ++ ck = AUDIT24MOD2_COOKIE; ++ else if (strcmp (l_name, "tst-audit24dmod3.so") == 0) ++ ck = AUDIT24MOD3_COOKIE; ++ else if (strcmp (l_name, "tst-audit24dmod.so") == 0) ++ ck = AUDIT24MOD4_COOKIE; ++ else if (strcmp (l_name, "tst-audit24d") == 0) ++ ck = AUDIT24_COOKIE; ++ ++ *cookie = ck; ++ return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; ++} ++ ++static int ++tst_audit24dmod1_func1 (void) ++{ ++ return 1; ++} ++ ++static int ++tst_audit24dmod2_func1 (void) ++{ ++ return 10; ++} ++ ++static int ++tst_audit24dmod3_func1 (void) ++{ ++ return 30; ++} ++ ++#include ++ ++#if __ELF_NATIVE_CLASS == 64 ++uintptr_t ++la_symbind64 (Elf64_Sym *sym, unsigned int ndx, ++ uintptr_t *refcook, uintptr_t *defcook, ++ unsigned int *flags, const char *symname) ++#else ++uintptr_t ++la_symbind32 (Elf32_Sym *sym, unsigned int ndx, ++ uintptr_t *refcook, uintptr_t *defcook, ++ unsigned int *flags, const char *symname) ++#endif ++{ ++ if (*refcook == AUDIT24_COOKIE) ++ { ++ if (*defcook == AUDIT24MOD1_COOKIE) ++ { ++ if (strcmp (symname, "tst_audit24dmod1_func1") == 0) ++ return (uintptr_t) tst_audit24dmod1_func1; ++ else if (strcmp (symname, "tst_audit24dmod1_func2") == 0) ++ return sym->st_value; ++ abort (); ++ } ++ if (*defcook == AUDIT24MOD2_COOKIE ++ && (strcmp (symname, "tst_audit24dmod2_func1") == 0)) ++ return (uintptr_t) tst_audit24dmod2_func1; ++ ++ /* malloc functions. */ ++ return sym->st_value; ++ } ++ else if (*refcook == AUDIT24MOD1_COOKIE) ++ { ++ if (*defcook == AUDIT24MOD3_COOKIE ++ && strcmp (symname, "tst_audit24dmod3_func1") == 0) ++ { ++ test_symbind_flags (*flags); ++ ++ return (uintptr_t) tst_audit24dmod3_func1; ++ } ++ } ++ ++ abort (); ++} +diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c +new file mode 100644 +index 0000000000000000..526f5c54bc2c3b8c +--- /dev/null ++++ b/elf/tst-auditmod25.c +@@ -0,0 +1,79 @@ ++/* Audit modules for tst-audit25a. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define AUDIT25_COOKIE 0x1 ++#define AUDIT25MOD1_COOKIE 0x2 ++#define AUDIT25MOD2_COOKIE 0x3 ++#define AUDIT25MOD3_COOKIE 0x2 ++#define AUDIT25MOD4_COOKIE 0x3 ++ ++#define TEST_NAME "tst-audit25" ++#define TEST_MOD "tst-audit25" ++#define TEST_FUNC "tst_audit25" ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return LAV_CURRENT; ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ const char *p = strrchr (map->l_name, '/'); ++ const char *l_name = p == NULL ? TEST_NAME : p + 1; ++ ++ uintptr_t ck = -1; ++ if (strcmp (l_name, TEST_MOD "mod1.so") == 0) ++ ck = AUDIT25MOD1_COOKIE; ++ else if (strcmp (l_name, TEST_MOD "mod2.so") == 0) ++ ck = AUDIT25MOD2_COOKIE; ++ else if (strcmp (l_name, TEST_MOD "mod3.so") == 0) ++ ck = AUDIT25MOD3_COOKIE; ++ else if (strcmp (l_name, TEST_MOD "mod4.so") == 0) ++ ck = AUDIT25MOD4_COOKIE; ++ else if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0) ++ ck = AUDIT25_COOKIE; ++ ++ *cookie = ck; ++ return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; ++} ++ ++#if __ELF_NATIVE_CLASS == 64 ++uintptr_t ++la_symbind64 (Elf64_Sym *sym, unsigned int ndx, ++ uintptr_t *refcook, uintptr_t *defcook, ++ unsigned int *flags, const char *symname) ++#else ++uintptr_t ++la_symbind32 (Elf32_Sym *sym, unsigned int ndx, ++ uintptr_t *refcook, uintptr_t *defcook, ++ unsigned int *flags, const char *symname) ++#endif ++{ ++ if (*refcook != -1 && *defcook != -1) ++ fprintf (stderr, "la_symbind: %s %u\n", symname, ++ *flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0); ++ return sym->st_value; ++} +diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h +index c038c31ce6550059..a15fd32771d42f2a 100644 +--- a/sysdeps/generic/dl-lookupcfg.h ++++ b/sysdeps/generic/dl-lookupcfg.h +@@ -26,3 +26,6 @@ + #define DL_FIXUP_VALUE_CODE_ADDR(value) (value) + #define DL_FIXUP_VALUE_ADDR(value) (value) + #define DL_FIXUP_ADDR_VALUE(addr) (addr) ++#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) ++#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ ++ (*value) = st_value; +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index a56060d0204cc453..a38de94bf7ea8e93 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1403,7 +1403,10 @@ void _dl_audit_objclose (struct link_map *l) + /* Call the la_preinit from the audit modules for the link_map L. */ + void _dl_audit_preinit (struct link_map *l); + +-/* Call the la_symbind{32,64} from the audit modules for the link_map L. */ ++/* Call the la_symbind{32,64} from the audit modules for the link_map L. If ++ RELOC_RESULT is NULL it assumes the symbol to be bind-now and will set ++ the flags with LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT prior calling ++ la_symbind{32,64}. */ + void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, + const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, + lookup_t result) +diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h +index 2f6991aa16e87a00..f4f00714fa158e18 100644 +--- a/sysdeps/hppa/dl-lookupcfg.h ++++ b/sysdeps/hppa/dl-lookupcfg.h +@@ -81,3 +81,6 @@ void attribute_hidden _dl_unmap (struct link_map *map); + #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip) + #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) + #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) ++#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) ++#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ ++ (*value) = *(struct fdesc *) (st_value) +diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h +index 58ca32424b08aaf4..2b8b2fa5db9d7093 100644 +--- a/sysdeps/ia64/dl-lookupcfg.h ++++ b/sysdeps/ia64/dl-lookupcfg.h +@@ -74,3 +74,6 @@ extern void attribute_hidden _dl_unmap (struct link_map *map); + + #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) + #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) ++#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) ++#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ ++ (*value) = *(struct fdesc *) (st_value) +diff --git a/sysdeps/powerpc/dl-lookupcfg.h b/sysdeps/powerpc/dl-lookupcfg.h +new file mode 100644 +index 0000000000000000..25abcc1d12b15bfc +--- /dev/null ++++ b/sysdeps/powerpc/dl-lookupcfg.h +@@ -0,0 +1,39 @@ ++/* Configuration of lookup functions. PowerPC version. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define DL_FIXUP_VALUE_TYPE ElfW(Addr) ++#define DL_FIXUP_MAKE_VALUE(map, addr) (addr) ++#define DL_FIXUP_VALUE_CODE_ADDR(value) (value) ++#define DL_FIXUP_VALUE_ADDR(value) (value) ++#define DL_FIXUP_ADDR_VALUE(addr) (addr) ++#if __WORDSIZE == 64 && _CALL_ELF == 1 ++/* We need to correctly set the audit modules value for bind-now. */ ++# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) \ ++ (((Elf64_FuncDesc *)(addr))->fd_func) ++# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ ++ ({ \ ++ Elf64_FuncDesc *opd = (Elf64_FuncDesc *) (value); \ ++ opd->fd_func = (st_value); \ ++ if ((new_value) != (uintptr_t) (st_value)) \ ++ opd->fd_toc = ((Elf64_FuncDesc *)(new_value))->fd_toc; \ ++ }) ++#else ++# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) ++# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ ++ (*value) = st_value; ++#endif diff --git a/SOURCES/glibc-upstream-2.34-157.patch b/SOURCES/glibc-upstream-2.34-157.patch new file mode 100644 index 0000000..0f5fd3c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-157.patch @@ -0,0 +1,1042 @@ +commit b118bce87a7c581cb2d6d7698eb582e45aed3481 +Author: Ben Woodard +Date: Mon Jan 24 10:46:18 2022 -0300 + + elf: Fix runtime linker auditing on aarch64 (BZ #26643) + + The rtld audit support show two problems on aarch64: + + 1. _dl_runtime_resolve does not preserve x8, the indirect result + location register, which might generate wrong result calls + depending of the function signature. + + 2. The NEON Q registers pushed onto the stack by _dl_runtime_resolve + were twice the size of D registers extracted from the stack frame by + _dl_runtime_profile. + + While 2. might result in wrong information passed on the PLT tracing, + 1. generates wrong runtime behaviour. + + The aarch64 rtld audit support is changed to: + + * Both La_aarch64_regs and La_aarch64_retval are expanded to include + both x8 and the full sized NEON V registers, as defined by the + ABI. + + * dl_runtime_profile needed to extract registers saved by + _dl_runtime_resolve and put them into the new correctly sized + La_aarch64_regs structure. + + * The LAV_CURRENT check is change to only accept new audit modules + to avoid the undefined behavior of not save/restore x8. + + * Different than other architectures, audit modules older than + LAV_CURRENT are rejected (both La_aarch64_regs and La_aarch64_retval + changed their layout and there are no requirements to support multiple + audit interface with the inherent aarch64 issues). + + * A new field is also reserved on both La_aarch64_regs and + La_aarch64_retval to support variant pcs symbols. + + Similar to x86, a new La_aarch64_vector type to represent the NEON + register is added on the La_aarch64_regs (so each type can be accessed + directly). + + Since LAV_CURRENT was already bumped to support bind-now, there is + no need to increase it again. + + Checked on aarch64-linux-gnu. + + Co-authored-by: Adhemerval Zanella + Reviewed-by: Szabolcs Nagy + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit ce9a68c57c260c8417afc93972849ac9ad243ec4) + + Resolved conflicts: + NEWS + elf/rtld.c + +diff --git a/elf/rtld.c b/elf/rtld.c +index 26c6fb6479c9008c..434fbeddd5cce74d 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + + #include + +@@ -991,7 +992,7 @@ file=%s [%lu]; audit interface function la_version returned zero; ignored.\n", + return; + } + +- if (lav > LAV_CURRENT) ++ if (!_dl_audit_check_version (lav)) + { + _dl_debug_printf ("\ + ERROR: audit interface '%s' requires version %d (maximum supported version %d); ignored.\n", +diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile +index 7c66fb97aa065f99..7183895d04ea8d42 100644 +--- a/sysdeps/aarch64/Makefile ++++ b/sysdeps/aarch64/Makefile +@@ -10,6 +10,26 @@ endif + + ifeq ($(subdir),elf) + sysdep-dl-routines += dl-bti ++ ++tests += tst-audit26 \ ++ tst-audit27 ++ ++modules-names += \ ++ tst-audit26mod \ ++ tst-auditmod26 \ ++ tst-audit27mod \ ++ tst-auditmod27 ++ ++$(objpfx)tst-audit26: $(objpfx)tst-audit26mod.so \ ++ $(objpfx)tst-auditmod26.so ++LDFLAGS-tst-audit26 += -Wl,-z,lazy ++tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so ++ ++$(objpfx)tst-audit27: $(objpfx)tst-audit27mod.so \ ++ $(objpfx)tst-auditmod27.so ++$(objpfx)tst-audit27mod.so: $(libsupport) ++LDFLAGS-tst-audit27 += -Wl,-z,lazy ++tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so + endif + + ifeq ($(subdir),elf) +diff --git a/sysdeps/aarch64/bits/link.h b/sysdeps/aarch64/bits/link.h +index 774bbe5f4544f559..c64726947c9addea 100644 +--- a/sysdeps/aarch64/bits/link.h ++++ b/sysdeps/aarch64/bits/link.h +@@ -20,23 +20,31 @@ + # error "Never include directly; use instead." + #endif + ++typedef union ++{ ++ float s; ++ double d; ++ long double q; ++} La_aarch64_vector; ++ + /* Registers for entry into PLT on AArch64. */ + typedef struct La_aarch64_regs + { +- uint64_t lr_xreg[8]; +- uint64_t lr_dreg[8]; +- uint64_t lr_sp; +- uint64_t lr_lr; ++ uint64_t lr_xreg[9]; ++ La_aarch64_vector lr_vreg[8]; ++ uint64_t lr_sp; ++ uint64_t lr_lr; ++ void *lr_vpcs; + } La_aarch64_regs; + + /* Return values for calls from PLT on AArch64. */ + typedef struct La_aarch64_retval + { +- /* Up to two integer registers can be used for a return value. */ +- uint64_t lrv_xreg[2]; +- /* Up to four D registers can be used for a return value. */ +- uint64_t lrv_dreg[4]; +- ++ /* Up to eight integer registers can be used for a return value. */ ++ uint64_t lrv_xreg[8]; ++ /* Up to eight V registers can be used for a return value. */ ++ La_aarch64_vector lrv_vreg[8]; ++ void *lrv_vpcs; + } La_aarch64_retval; + __BEGIN_DECLS + +diff --git a/sysdeps/aarch64/dl-audit-check.h b/sysdeps/aarch64/dl-audit-check.h +new file mode 100644 +index 0000000000000000..e324339a1d4abec3 +--- /dev/null ++++ b/sysdeps/aarch64/dl-audit-check.h +@@ -0,0 +1,28 @@ ++/* rtld-audit version check. AArch64 version. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++static inline bool ++_dl_audit_check_version (unsigned int lav) ++{ ++ /* Audit version 1 do not save x8 or NEON registers, which required ++ changing La_aarch64_regs and La_aarch64_retval layout (BZ#26643). The ++ missing indirect result save/restore makes _dl_runtime_profile ++ potentially trigger undefined behavior if the function returns a large ++ struct (even when PLT trace is not requested). */ ++ return lav == LAV_CURRENT; ++} +diff --git a/sysdeps/aarch64/dl-link.sym b/sysdeps/aarch64/dl-link.sym +index d67d28b40ce7d4ff..cb4dcdcbed0db492 100644 +--- a/sysdeps/aarch64/dl-link.sym ++++ b/sysdeps/aarch64/dl-link.sym +@@ -7,9 +7,11 @@ DL_SIZEOF_RG sizeof(struct La_aarch64_regs) + DL_SIZEOF_RV sizeof(struct La_aarch64_retval) + + DL_OFFSET_RG_X0 offsetof(struct La_aarch64_regs, lr_xreg) +-DL_OFFSET_RG_D0 offsetof(struct La_aarch64_regs, lr_dreg) ++DL_OFFSET_RG_V0 offsetof(struct La_aarch64_regs, lr_vreg) + DL_OFFSET_RG_SP offsetof(struct La_aarch64_regs, lr_sp) + DL_OFFSET_RG_LR offsetof(struct La_aarch64_regs, lr_lr) ++DL_OFFSET_RG_VPCS offsetof(struct La_aarch64_regs, lr_vpcs) + + DL_OFFSET_RV_X0 offsetof(struct La_aarch64_retval, lrv_xreg) +-DL_OFFSET_RV_D0 offsetof(struct La_aarch64_retval, lrv_dreg) ++DL_OFFSET_RV_V0 offsetof(struct La_aarch64_retval, lrv_vreg) ++DL_OFFSET_RV_VPCS offsetof(struct La_aarch64_retval, lrv_vpcs) +diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S +index 9b352b1d0f7d62e7..457570e7df5148c0 100644 +--- a/sysdeps/aarch64/dl-trampoline.S ++++ b/sysdeps/aarch64/dl-trampoline.S +@@ -45,7 +45,8 @@ _dl_runtime_resolve: + + cfi_rel_offset (lr, 8) + +- /* Save arguments. */ ++ /* Note: Saving x9 is not required by the ABI but the assembler requires ++ the immediate values of operand 3 to be a multiple of 16 */ + stp x8, x9, [sp, #-(80+8*16)]! + cfi_adjust_cfa_offset (80+8*16) + cfi_rel_offset (x8, 0) +@@ -142,7 +143,7 @@ _dl_runtime_profile: + Stack frame layout: + [sp, #...] lr + [sp, #...] &PLTGOT[n] +- [sp, #96] La_aarch64_regs ++ [sp, #256] La_aarch64_regs + [sp, #48] La_aarch64_retval + [sp, #40] frame size return from pltenter + [sp, #32] dl_profile_call saved x1 +@@ -183,19 +184,25 @@ _dl_runtime_profile: + stp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3] + cfi_rel_offset (x6, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 0) + cfi_rel_offset (x7, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 8) +- +- stp d0, d1, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0] +- cfi_rel_offset (d0, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0) +- cfi_rel_offset (d1, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0 + 8) +- stp d2, d3, [X29, #OFFSET_RG+ DL_OFFSET_RG_D0 + 16*1] +- cfi_rel_offset (d2, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 0) +- cfi_rel_offset (d3, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 8) +- stp d4, d5, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2] +- cfi_rel_offset (d4, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 0) +- cfi_rel_offset (d5, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 8) +- stp d6, d7, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3] +- cfi_rel_offset (d6, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 0) +- cfi_rel_offset (d7, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 8) ++ str x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0] ++ cfi_rel_offset (x8, OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0) ++ /* Note 8 bytes of padding is in the stack frame for alignment */ ++ ++ stp q0, q1, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0] ++ cfi_rel_offset (q0, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0) ++ cfi_rel_offset (q1, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0 + 16) ++ stp q2, q3, [X29, #OFFSET_RG+ DL_OFFSET_RG_V0 + 32*1] ++ cfi_rel_offset (q2, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 0) ++ cfi_rel_offset (q3, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 16) ++ stp q4, q5, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2] ++ cfi_rel_offset (q4, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 0) ++ cfi_rel_offset (q5, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 16) ++ stp q6, q7, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3] ++ cfi_rel_offset (q6, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 0) ++ cfi_rel_offset (q7, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 16) ++ ++ /* No APCS extension supported. */ ++ str xzr, [X29, #OFFSET_RG + DL_OFFSET_RG_VPCS] + + add x0, x29, #SF_SIZE + 16 + ldr x1, [x29, #OFFSET_LR] +@@ -234,10 +241,11 @@ _dl_runtime_profile: + ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1] + ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2] + ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3] +- ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0] +- ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1] +- ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2] +- ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3] ++ ldr x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4] ++ ldp q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0] ++ ldp q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1] ++ ldp q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2] ++ ldp q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3] + + cfi_def_cfa_register (sp) + ldp x29, x30, [x29, #0] +@@ -280,14 +288,22 @@ _dl_runtime_profile: + ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1] + ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2] + ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3] +- ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0] +- ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1] +- ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2] +- ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3] ++ ldr x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4] ++ ldp q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0] ++ ldp q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1] ++ ldp q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2] ++ ldp q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3] + blr ip0 +- stp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0] +- stp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0] +- stp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1] ++ stp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0] ++ stp x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1] ++ stp x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2] ++ stp x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3] ++ str x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4] ++ stp q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0] ++ stp q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1] ++ stp q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2] ++ stp q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3] ++ str xzr, [X29, #OFFSET_RV + DL_OFFSET_RG_VPCS] + + /* Setup call to pltexit */ + ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0] +@@ -295,9 +311,16 @@ _dl_runtime_profile: + add x3, x29, #OFFSET_RV + bl _dl_audit_pltexit + +- ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0] +- ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0] +- ldp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1] ++ ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0] ++ ldp x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1] ++ ldp x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2] ++ ldp x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3] ++ ldr x8, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*4] ++ ldp q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0] ++ ldp q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1] ++ ldp q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2] ++ ldp q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3] ++ + /* LR from within La_aarch64_reg */ + ldr lr, [x29, #OFFSET_RG + DL_OFFSET_RG_LR] + cfi_restore(lr) +diff --git a/sysdeps/aarch64/tst-audit26.c b/sysdeps/aarch64/tst-audit26.c +new file mode 100644 +index 0000000000000000..46de8acd219cb8bc +--- /dev/null ++++ b/sysdeps/aarch64/tst-audit26.c +@@ -0,0 +1,37 @@ ++/* Check LD_AUDIT for aarch64 ABI specifics. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "tst-audit26mod.h" ++ ++int ++do_test (void) ++{ ++ /* Returning a large struct uses 'x8' as indirect result location. */ ++ struct large_struct r = tst_audit26_func (ARG1, ARG2, ARG3); ++ ++ struct large_struct e = set_large_struct (ARG1, ARG2, ARG3); ++ ++ TEST_COMPARE_BLOB (r.a, sizeof (r.a), e.a, sizeof (e.a)); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/aarch64/tst-audit26mod.c b/sysdeps/aarch64/tst-audit26mod.c +new file mode 100644 +index 0000000000000000..67d5ffce7288b34c +--- /dev/null ++++ b/sysdeps/aarch64/tst-audit26mod.c +@@ -0,0 +1,33 @@ ++/* Check LD_AUDIT for aarch64 ABI specifics. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include "tst-audit26mod.h" ++ ++struct large_struct ++tst_audit26_func (char a, short b, long int c) ++{ ++ if (a != ARG1) ++ abort (); ++ if (b != ARG2) ++ abort (); ++ if (c != ARG3) ++ abort (); ++ ++ return set_large_struct (a, b, c); ++} +diff --git a/sysdeps/aarch64/tst-audit26mod.h b/sysdeps/aarch64/tst-audit26mod.h +new file mode 100644 +index 0000000000000000..f80409f96bae6c82 +--- /dev/null ++++ b/sysdeps/aarch64/tst-audit26mod.h +@@ -0,0 +1,50 @@ ++/* Check LD_AUDIT for aarch64 specific ABI. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _TST_AUDIT27MOD_H ++#define _TST_AUDIT27MOD_H 1 ++ ++#include ++ ++struct large_struct ++{ ++ char a[16]; ++ short b[8]; ++ long int c[4]; ++}; ++ ++static inline struct large_struct ++set_large_struct (char a, short b, long int c) ++{ ++ struct large_struct r; ++ for (int i = 0; i < array_length (r.a); i++) ++ r.a[i] = a; ++ for (int i = 0; i < array_length (r.b); i++) ++ r.b[i] = b; ++ for (int i = 0; i < array_length (r.c); i++) ++ r.c[i] = c; ++ return r; ++} ++ ++#define ARG1 0x12 ++#define ARG2 0x1234 ++#define ARG3 0x12345678 ++ ++struct large_struct tst_audit26_func (char a, short b, long int c); ++ ++#endif +diff --git a/sysdeps/aarch64/tst-audit27.c b/sysdeps/aarch64/tst-audit27.c +new file mode 100644 +index 0000000000000000..5ebc09771f845af0 +--- /dev/null ++++ b/sysdeps/aarch64/tst-audit27.c +@@ -0,0 +1,64 @@ ++/* Check LD_AUDIT for aarch64 ABI specifics. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "tst-audit27mod.h" ++ ++int ++do_test (void) ++{ ++ { ++ float r = tst_audit27_func_float (FUNC_FLOAT_ARG0, FUNC_FLOAT_ARG1, ++ FUNC_FLOAT_ARG2, FUNC_FLOAT_ARG3, ++ FUNC_FLOAT_ARG4, FUNC_FLOAT_ARG5, ++ FUNC_FLOAT_ARG6, FUNC_FLOAT_ARG7); ++ if (r != FUNC_FLOAT_RET) ++ FAIL_EXIT1 ("tst_audit27_func_float() returned %a, expected %a", ++ r, FUNC_FLOAT_RET); ++ } ++ ++ { ++ double r = tst_audit27_func_double (FUNC_DOUBLE_ARG0, FUNC_DOUBLE_ARG1, ++ FUNC_DOUBLE_ARG2, FUNC_DOUBLE_ARG3, ++ FUNC_DOUBLE_ARG4, FUNC_DOUBLE_ARG5, ++ FUNC_DOUBLE_ARG6, FUNC_DOUBLE_ARG7); ++ if (r != FUNC_DOUBLE_RET) ++ FAIL_EXIT1 ("tst_audit27_func_double() returned %la, expected %la", ++ r, FUNC_DOUBLE_RET); ++ } ++ ++ { ++ long double r = tst_audit27_func_ldouble (FUNC_LDOUBLE_ARG0, ++ FUNC_LDOUBLE_ARG1, ++ FUNC_LDOUBLE_ARG2, ++ FUNC_LDOUBLE_ARG3, ++ FUNC_LDOUBLE_ARG4, ++ FUNC_LDOUBLE_ARG5, ++ FUNC_LDOUBLE_ARG6, ++ FUNC_LDOUBLE_ARG7); ++ if (r != FUNC_LDOUBLE_RET) ++ FAIL_EXIT1 ("tst_audit27_func_ldouble() returned %La, expected %La", ++ r, FUNC_LDOUBLE_RET); ++ } ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/aarch64/tst-audit27mod.c b/sysdeps/aarch64/tst-audit27mod.c +new file mode 100644 +index 0000000000000000..922b518f0af4b97b +--- /dev/null ++++ b/sysdeps/aarch64/tst-audit27mod.c +@@ -0,0 +1,95 @@ ++/* Check LD_AUDIT for aarch64 ABI specifics. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "tst-audit27mod.h" ++ ++float ++tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4, ++ float a5, float a6, float a7) ++{ ++ if (a0 != FUNC_FLOAT_ARG0) ++ FAIL_EXIT1 ("a0: %a != %a", a0, FUNC_FLOAT_ARG0); ++ if (a1 != FUNC_FLOAT_ARG1) ++ FAIL_EXIT1 ("a1: %a != %a", a1, FUNC_FLOAT_ARG1); ++ if (a2 != FUNC_FLOAT_ARG2) ++ FAIL_EXIT1 ("a2: %a != %a", a2, FUNC_FLOAT_ARG2); ++ if (a3 != FUNC_FLOAT_ARG3) ++ FAIL_EXIT1 ("a3: %a != %a", a3, FUNC_FLOAT_ARG3); ++ if (a4 != FUNC_FLOAT_ARG4) ++ FAIL_EXIT1 ("a4: %a != %a", a4, FUNC_FLOAT_ARG4); ++ if (a5 != FUNC_FLOAT_ARG5) ++ FAIL_EXIT1 ("a5: %a != %a", a5, FUNC_FLOAT_ARG5); ++ if (a6 != FUNC_FLOAT_ARG6) ++ FAIL_EXIT1 ("a6: %a != %a", a6, FUNC_FLOAT_ARG6); ++ if (a7 != FUNC_FLOAT_ARG7) ++ FAIL_EXIT1 ("a7: %a != %a", a7, FUNC_FLOAT_ARG7); ++ ++ return FUNC_FLOAT_RET; ++} ++ ++double ++tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4, ++ double a5, double a6, double a7) ++{ ++ if (a0 != FUNC_DOUBLE_ARG0) ++ FAIL_EXIT1 ("a0: %la != %la", a0, FUNC_DOUBLE_ARG0); ++ if (a1 != FUNC_DOUBLE_ARG1) ++ FAIL_EXIT1 ("a1: %la != %la", a1, FUNC_DOUBLE_ARG1); ++ if (a2 != FUNC_DOUBLE_ARG2) ++ FAIL_EXIT1 ("a2: %la != %la", a2, FUNC_DOUBLE_ARG2); ++ if (a3 != FUNC_DOUBLE_ARG3) ++ FAIL_EXIT1 ("a3: %la != %la", a3, FUNC_DOUBLE_ARG3); ++ if (a4 != FUNC_DOUBLE_ARG4) ++ FAIL_EXIT1 ("a4: %la != %la", a4, FUNC_DOUBLE_ARG4); ++ if (a5 != FUNC_DOUBLE_ARG5) ++ FAIL_EXIT1 ("a5: %la != %la", a5, FUNC_DOUBLE_ARG5); ++ if (a6 != FUNC_DOUBLE_ARG6) ++ FAIL_EXIT1 ("a6: %la != %la", a6, FUNC_DOUBLE_ARG6); ++ if (a7 != FUNC_DOUBLE_ARG7) ++ FAIL_EXIT1 ("a7: %la != %la", a7, FUNC_DOUBLE_ARG7); ++ ++ return FUNC_DOUBLE_RET; ++} ++ ++long double ++tst_audit27_func_ldouble (long double a0, long double a1, long double a2, ++ long double a3, long double a4, long double a5, ++ long double a6, long double a7) ++{ ++ if (a0 != FUNC_LDOUBLE_ARG0) ++ FAIL_EXIT1 ("a0: %La != %La", a0, FUNC_LDOUBLE_ARG0); ++ if (a1 != FUNC_LDOUBLE_ARG1) ++ FAIL_EXIT1 ("a1: %La != %La", a1, FUNC_LDOUBLE_ARG1); ++ if (a2 != FUNC_LDOUBLE_ARG2) ++ FAIL_EXIT1 ("a2: %La != %La", a2, FUNC_LDOUBLE_ARG2); ++ if (a3 != FUNC_LDOUBLE_ARG3) ++ FAIL_EXIT1 ("a3: %La != %La", a3, FUNC_LDOUBLE_ARG3); ++ if (a4 != FUNC_LDOUBLE_ARG4) ++ FAIL_EXIT1 ("a4: %La != %La", a4, FUNC_LDOUBLE_ARG4); ++ if (a5 != FUNC_LDOUBLE_ARG5) ++ FAIL_EXIT1 ("a5: %La != %La", a5, FUNC_LDOUBLE_ARG5); ++ if (a6 != FUNC_LDOUBLE_ARG6) ++ FAIL_EXIT1 ("a6: %La != %La", a6, FUNC_LDOUBLE_ARG6); ++ if (a7 != FUNC_LDOUBLE_ARG7) ++ FAIL_EXIT1 ("a7: %La != %La", a7, FUNC_LDOUBLE_ARG7); ++ ++ return FUNC_LDOUBLE_RET; ++} +diff --git a/sysdeps/aarch64/tst-audit27mod.h b/sysdeps/aarch64/tst-audit27mod.h +new file mode 100644 +index 0000000000000000..1709d222ca251e3b +--- /dev/null ++++ b/sysdeps/aarch64/tst-audit27mod.h +@@ -0,0 +1,67 @@ ++/* Check LD_AUDIT for aarch64 specific ABI. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _TST_AUDIT27MOD_H ++#define _TST_AUDIT27MOD_H 1 ++ ++#include ++ ++#define FUNC_FLOAT_ARG0 FLT_MIN ++#define FUNC_FLOAT_ARG1 FLT_MAX ++#define FUNC_FLOAT_ARG2 FLT_EPSILON ++#define FUNC_FLOAT_ARG3 FLT_TRUE_MIN ++#define FUNC_FLOAT_ARG4 0.0f ++#define FUNC_FLOAT_ARG5 1.0f ++#define FUNC_FLOAT_ARG6 2.0f ++#define FUNC_FLOAT_ARG7 3.0f ++#define FUNC_FLOAT_RET 4.0f ++ ++float ++tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4, ++ float a5, float a6, float a7); ++ ++#define FUNC_DOUBLE_ARG0 DBL_MIN ++#define FUNC_DOUBLE_ARG1 DBL_MAX ++#define FUNC_DOUBLE_ARG2 DBL_EPSILON ++#define FUNC_DOUBLE_ARG3 DBL_TRUE_MIN ++#define FUNC_DOUBLE_ARG4 0.0 ++#define FUNC_DOUBLE_ARG5 1.0 ++#define FUNC_DOUBLE_ARG6 2.0 ++#define FUNC_DOUBLE_ARG7 3.0 ++#define FUNC_DOUBLE_RET 0x1.fffffe0000001p+127 ++ ++double ++tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4, ++ double a5, double a6, double a7); ++ ++#define FUNC_LDOUBLE_ARG0 DBL_MAX + 1.0L ++#define FUNC_LDOUBLE_ARG1 DBL_MAX + 2.0L ++#define FUNC_LDOUBLE_ARG2 DBL_MAX + 3.0L ++#define FUNC_LDOUBLE_ARG3 DBL_MAX + 4.0L ++#define FUNC_LDOUBLE_ARG4 DBL_MAX + 5.0L ++#define FUNC_LDOUBLE_ARG5 DBL_MAX + 6.0L ++#define FUNC_LDOUBLE_ARG6 DBL_MAX + 7.0L ++#define FUNC_LDOUBLE_ARG7 DBL_MAX + 8.0L ++#define FUNC_LDOUBLE_RET 0x1.fffffffffffff000000000000001p+1023L ++ ++long double ++tst_audit27_func_ldouble (long double a0, long double a1, long double a2, ++ long double a3, long double a4, long double a5, ++ long double a6, long double a7); ++ ++#endif +diff --git a/sysdeps/aarch64/tst-auditmod26.c b/sysdeps/aarch64/tst-auditmod26.c +new file mode 100644 +index 0000000000000000..b03b6baed9aeb528 +--- /dev/null ++++ b/sysdeps/aarch64/tst-auditmod26.c +@@ -0,0 +1,103 @@ ++/* Check LD_AUDIT for aarch64 specific ABI. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "tst-audit26mod.h" ++ ++#define TEST_NAME "tst-audit26" ++ ++#define AUDIT26_COOKIE 0 ++ ++unsigned int ++la_version (unsigned int v) ++{ ++ return v; ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ const char *p = strrchr (map->l_name, '/'); ++ const char *l_name = p == NULL ? map->l_name : p + 1; ++ uintptr_t ck = -1; ++ if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0) ++ ck = AUDIT26_COOKIE; ++ *cookie = ck; ++ printf ("objopen: %ld, %s [cookie=%ld]\n", lmid, l_name, ck); ++ return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; ++} ++ ++ElfW(Addr) ++la_aarch64_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)), ++ unsigned int ndx __attribute__ ((unused)), ++ uintptr_t *refcook, uintptr_t *defcook, ++ La_aarch64_regs *regs, unsigned int *flags, ++ const char *symname, long int *framesizep) ++{ ++ printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", ++ symname, (long int) sym->st_value, ndx, *flags); ++ ++ if (strcmp (symname, "tst_audit26_func") == 0) ++ { ++ assert (regs->lr_xreg[0] == ARG1); ++ assert (regs->lr_xreg[1] == ARG2); ++ assert (regs->lr_xreg[2] == ARG3); ++ } ++ else ++ abort (); ++ ++ assert (regs->lr_vpcs == 0); ++ ++ /* Clobber 'x8'. */ ++ asm volatile ("mov x8, -1" : : : "x8"); ++ ++ *framesizep = 1024; ++ ++ return sym->st_value; ++} ++ ++unsigned int ++la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, ++ const struct La_aarch64_regs *inregs, ++ struct La_aarch64_retval *outregs, const char *symname) ++{ ++ printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n", ++ symname, (long int) sym->st_value, ndx); ++ ++ if (strcmp (symname, "tst_audit26_func") == 0) ++ { ++ assert (inregs->lr_xreg[0] == ARG1); ++ assert (inregs->lr_xreg[1] == ARG2); ++ assert (inregs->lr_xreg[2] == ARG3); ++ } ++ else ++ abort (); ++ ++ assert (inregs->lr_vpcs == 0); ++ assert (outregs->lrv_vpcs == 0); ++ ++ /* Clobber 'x8'. */ ++ asm volatile ("mov x8, -1" : : : "x8"); ++ ++ return 0; ++} +diff --git a/sysdeps/aarch64/tst-auditmod27.c b/sysdeps/aarch64/tst-auditmod27.c +new file mode 100644 +index 0000000000000000..21132c2985dab7b2 +--- /dev/null ++++ b/sysdeps/aarch64/tst-auditmod27.c +@@ -0,0 +1,180 @@ ++/* Check LD_AUDIT for aarch64 specific ABI. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "tst-audit27mod.h" ++ ++#define TEST_NAME "tst-audit27" ++ ++#define AUDIT27_COOKIE 0 ++ ++unsigned int ++la_version (unsigned int v) ++{ ++ return v; ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ const char *p = strrchr (map->l_name, '/'); ++ const char *l_name = p == NULL ? map->l_name : p + 1; ++ uintptr_t ck = -1; ++ if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0) ++ ck = AUDIT27_COOKIE; ++ *cookie = ck; ++ printf ("objopen: %ld, %s [%ld]\n", lmid, l_name, ck); ++ return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; ++} ++ ++ElfW(Addr) ++la_aarch64_gnu_pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, La_aarch64_regs *regs, ++ unsigned int *flags, const char *symname, ++ long int *framesizep) ++{ ++ printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", ++ symname, (long int) sym->st_value, ndx, *flags); ++ ++ if (strcmp (symname, "tst_audit27_func_float") == 0) ++ { ++ assert (regs->lr_vreg[0].s == FUNC_FLOAT_ARG0); ++ assert (regs->lr_vreg[1].s == FUNC_FLOAT_ARG1); ++ assert (regs->lr_vreg[2].s == FUNC_FLOAT_ARG2); ++ assert (regs->lr_vreg[3].s == FUNC_FLOAT_ARG3); ++ assert (regs->lr_vreg[4].s == FUNC_FLOAT_ARG4); ++ assert (regs->lr_vreg[5].s == FUNC_FLOAT_ARG5); ++ assert (regs->lr_vreg[6].s == FUNC_FLOAT_ARG6); ++ assert (regs->lr_vreg[7].s == FUNC_FLOAT_ARG7); ++ } ++ else if (strcmp (symname, "tst_audit27_func_double") == 0) ++ { ++ assert (regs->lr_vreg[0].d == FUNC_DOUBLE_ARG0); ++ assert (regs->lr_vreg[1].d == FUNC_DOUBLE_ARG1); ++ assert (regs->lr_vreg[2].d == FUNC_DOUBLE_ARG2); ++ assert (regs->lr_vreg[3].d == FUNC_DOUBLE_ARG3); ++ assert (regs->lr_vreg[4].d == FUNC_DOUBLE_ARG4); ++ assert (regs->lr_vreg[5].d == FUNC_DOUBLE_ARG5); ++ assert (regs->lr_vreg[6].d == FUNC_DOUBLE_ARG6); ++ assert (regs->lr_vreg[7].d == FUNC_DOUBLE_ARG7); ++ } ++ else if (strcmp (symname, "tst_audit27_func_ldouble") == 0) ++ { ++ assert (regs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0); ++ assert (regs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1); ++ assert (regs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2); ++ assert (regs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3); ++ assert (regs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4); ++ assert (regs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5); ++ assert (regs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6); ++ assert (regs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7); ++ } ++ else ++ abort (); ++ ++ assert (regs->lr_vpcs == 0); ++ ++ /* Clobber the q registers on exit. */ ++ uint8_t v = 0xff; ++ asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0"); ++ asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v1"); ++ asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2"); ++ asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3"); ++ asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4"); ++ asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5"); ++ asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6"); ++ asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7"); ++ ++ *framesizep = 1024; ++ ++ return sym->st_value; ++} ++ ++unsigned int ++la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, ++ const struct La_aarch64_regs *inregs, ++ struct La_aarch64_retval *outregs, ++ const char *symname) ++{ ++ printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n", ++ symname, (long int) sym->st_value, ndx); ++ ++ if (strcmp (symname, "tst_audit27_func_float") == 0) ++ { ++ assert (inregs->lr_vreg[0].s == FUNC_FLOAT_ARG0); ++ assert (inregs->lr_vreg[1].s == FUNC_FLOAT_ARG1); ++ assert (inregs->lr_vreg[2].s == FUNC_FLOAT_ARG2); ++ assert (inregs->lr_vreg[3].s == FUNC_FLOAT_ARG3); ++ assert (inregs->lr_vreg[4].s == FUNC_FLOAT_ARG4); ++ assert (inregs->lr_vreg[5].s == FUNC_FLOAT_ARG5); ++ assert (inregs->lr_vreg[6].s == FUNC_FLOAT_ARG6); ++ assert (inregs->lr_vreg[7].s == FUNC_FLOAT_ARG7); ++ ++ assert (outregs->lrv_vreg[0].s == FUNC_FLOAT_RET); ++ } ++ else if (strcmp (symname, "tst_audit27_func_double") == 0) ++ { ++ assert (inregs->lr_vreg[0].d == FUNC_DOUBLE_ARG0); ++ assert (inregs->lr_vreg[1].d == FUNC_DOUBLE_ARG1); ++ assert (inregs->lr_vreg[2].d == FUNC_DOUBLE_ARG2); ++ assert (inregs->lr_vreg[3].d == FUNC_DOUBLE_ARG3); ++ assert (inregs->lr_vreg[4].d == FUNC_DOUBLE_ARG4); ++ assert (inregs->lr_vreg[5].d == FUNC_DOUBLE_ARG5); ++ assert (inregs->lr_vreg[6].d == FUNC_DOUBLE_ARG6); ++ assert (inregs->lr_vreg[7].d == FUNC_DOUBLE_ARG7); ++ ++ assert (outregs->lrv_vreg[0].d == FUNC_DOUBLE_RET); ++ } ++ else if (strcmp (symname, "tst_audit27_func_ldouble") == 0) ++ { ++ assert (inregs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0); ++ assert (inregs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1); ++ assert (inregs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2); ++ assert (inregs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3); ++ assert (inregs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4); ++ assert (inregs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5); ++ assert (inregs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6); ++ assert (inregs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7); ++ ++ assert (outregs->lrv_vreg[0].q == FUNC_LDOUBLE_RET); ++ } ++ else ++ abort (); ++ ++ assert (inregs->lr_vpcs == 0); ++ assert (outregs->lrv_vpcs == 0); ++ ++ /* Clobber the q registers on exit. */ ++ uint8_t v = 0xff; ++ asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0"); ++ asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v1"); ++ asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2"); ++ asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3"); ++ asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4"); ++ asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5"); ++ asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6"); ++ asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7"); ++ ++ return 0; ++} +diff --git a/sysdeps/generic/dl-audit-check.h b/sysdeps/generic/dl-audit-check.h +new file mode 100644 +index 0000000000000000..3ab76532868b5895 +--- /dev/null ++++ b/sysdeps/generic/dl-audit-check.h +@@ -0,0 +1,23 @@ ++/* rtld-audit version check. Generic version. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++static inline bool ++_dl_audit_check_version (unsigned int lav) ++{ ++ return lav <= LAV_CURRENT; ++} diff --git a/SOURCES/glibc-upstream-2.34-158.patch b/SOURCES/glibc-upstream-2.34-158.patch new file mode 100644 index 0000000..1cb44e2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-158.patch @@ -0,0 +1,23 @@ +commit 165e7ad459fbba2f89708fba04a55bb3981e884c +Author: Szabolcs Nagy +Date: Wed Feb 2 14:03:58 2022 +0000 + + Fix elf/tst-audit25a with default bind now toolchains + + This test relies on lazy binding for the executable so request that + explicitly in case the toolchain defaults to bind now. + + (cherry picked from commit 80a08d0faa9b224019f895800c4d97de4e23e1aa) + +diff --git a/elf/Makefile b/elf/Makefile +index 0ab3e885f5e35671..9e4e056938a75ddb 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -2133,6 +2133,7 @@ $(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \ + $(objpfx)tst-audit25mod2.so \ + $(objpfx)tst-audit25mod3.so \ + $(objpfx)tst-audit25mod4.so ++LDFLAGS-tst-audit25a = -Wl,-z,lazy + $(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so + LDFLAGS-tst-audit25mod1.so = -Wl,-z,now + $(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so diff --git a/SOURCES/glibc-upstream-2.34-159.patch b/SOURCES/glibc-upstream-2.34-159.patch new file mode 100644 index 0000000..e45d205 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-159.patch @@ -0,0 +1,27 @@ +commit aabdad371f44defc6046aabdc96af7782a2e94be +Author: H.J. Lu +Date: Sun Feb 6 11:12:24 2022 -0800 + + elf: Replace tst-audit24bmod2.so with tst-audit24bmod2 + + Replace tst-audit24bmod2.so with tst-audit24bmod2 to silence: + + make[2]: Entering directory '/export/gnu/import/git/gitlab/x86-glibc/elf' + Makefile:2201: warning: overriding recipe for target '/export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/elf/tst-audit24bmod2.so' + ../Makerules:765: warning: ignoring old recipe for target '/export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/elf/tst-audit24bmod2.so' + + (cherry picked from commit fa7ad1df1915c8a62f50e3a5b7e10f9c7118cd7f) + +diff --git a/elf/Makefile b/elf/Makefile +index 9e4e056938a75ddb..57059293d0bc86cb 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -888,7 +888,7 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) + # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special + # rules. + modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \ +- tst-audit24bmod1 tst-audit24bmod2.so ++ tst-audit24bmod1 tst-audit24bmod2 + + tests += $(tests-static) + diff --git a/SOURCES/glibc-upstream-2.34-16.patch b/SOURCES/glibc-upstream-2.34-16.patch new file mode 100644 index 0000000..3d8a568 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-16.patch @@ -0,0 +1,31 @@ +commit ae925404a10bf0ea63d6e8d41e3821f68b4d776c +Author: Aurelien Jarno +Date: Fri Sep 3 00:28:14 2021 +0200 + + Fix failing nss/tst-nss-files-hosts-long with local resolver + + When a local resolver like unbound is listening on the IPv4 loopback + address 127.0.0.1, the nss/tst-nss-files-hosts-long test fails. This is + due to: + - the default resolver in the absence of resolv.conf being 127.0.0.1 + - the default DNS NSS database configuration in the absence of + nsswitch.conf being 'hosts: dns [!UNAVAIL=return] file' + + This causes the requests for 'test4' and 'test6' to first be sent to the + local resolver, which responds with NXDOMAIN in the likely case those + records do no exist. In turn that causes the access to /etc/hosts to be + skipped, which is the purpose of that test. + + Fix that by providing a simple nsswitch.conf file forcing access to + /etc/hosts for that test. I have tested that the only changed result in + the testsuite is that test. + + (cherry picked from commit 2738480a4b0866723fb8c633f36bdd34a8767581) + +diff --git a/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf +new file mode 100644 +index 0000000000000000..5b0c6a419937a013 +--- /dev/null ++++ b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf +@@ -0,0 +1 @@ ++hosts: files diff --git a/SOURCES/glibc-upstream-2.34-160.patch b/SOURCES/glibc-upstream-2.34-160.patch new file mode 100644 index 0000000..2ce930a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-160.patch @@ -0,0 +1,114 @@ +commit 4dca2d3a7b43bf99bd6a567870a3144af4e763ef +Author: Adhemerval Zanella +Date: Fri Feb 4 15:54:59 2022 -0300 + + hppa: Fix bind-now audit (BZ #28857) + + On hppa, a function pointer returned by la_symbind is actually a function + descriptor has the plabel bit set (bit 30). This must be cleared to get + the actual address of the descriptor. If the descriptor has been bound, + the first word of the descriptor is the physical address of theA function, + otherwise, the first word of the descriptor points to a trampoline in the + PLT. + + This patch also adds a workaround on tests because on hppa (and it seems + to be the only ABI I have see it), some shared library adds a dynamic PLT + relocation to am empty symbol name: + + $ readelf -r elf/tst-audit25mod1.so + [...] + Relocation section '.rela.plt' at offset 0x464 contains 6 entries: + Offset Info Type Sym.Value Sym. Name + Addend + 00002008 00000081 R_PARISC_IPLT 508 + [...] + + It breaks some assumptions on the test, where a symbol with an empty + name ("") is passed on la_symbind. + + Checked on x86_64-linux-gnu and hppa-linux-gnu. + + (cherry picked from commit 9e94f57484a2aba0fe67ea2059b5843f651887c2) + +diff --git a/elf/Makefile b/elf/Makefile +index 57059293d0bc86cb..3e17a0706f5ec2df 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -2116,7 +2116,7 @@ $(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so + $(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \ + $(objpfx)tst-audit24amod2.so + tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so +-LDFLAGS-tst-audit24b = -Wl,-z,lazy ++LDFLAGS-tst-audit24c = -Wl,-z,lazy + + $(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so + $(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \ +diff --git a/elf/dl-audit.c b/elf/dl-audit.c +index 72a50717ef60a357..ec9b032eae37c103 100644 +--- a/elf/dl-audit.c ++++ b/elf/dl-audit.c +@@ -257,7 +257,8 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, + reloc_result->flags = flags; + } + +- DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value); ++ if (flags & LA_SYMB_ALTVALUE) ++ DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value); + } + + void +diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c +index d8e88f3984af1707..3075dfae2fd3d288 100644 +--- a/elf/tst-auditmod24a.c ++++ b/elf/tst-auditmod24a.c +@@ -110,5 +110,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx, + return sym->st_value; + } + +- abort (); ++ if (symname[0] != '\0') ++ abort (); ++ return sym->st_value; + } +diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c +index 8c803ecc0a48f21b..badc6be451ee0357 100644 +--- a/elf/tst-auditmod24d.c ++++ b/elf/tst-auditmod24d.c +@@ -116,5 +116,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx, + } + } + +- abort (); ++ if (symname[0] != '\0') ++ abort (); ++ return sym->st_value; + } +diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c +index 526f5c54bc2c3b8c..20640a8daf346b5f 100644 +--- a/elf/tst-auditmod25.c ++++ b/elf/tst-auditmod25.c +@@ -72,7 +72,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx, + unsigned int *flags, const char *symname) + #endif + { +- if (*refcook != -1 && *defcook != -1) ++ if (*refcook != -1 && *defcook != -1 && symname[0] != '\0') + fprintf (stderr, "la_symbind: %s %u\n", symname, + *flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0); + return sym->st_value; +diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h +index f4f00714fa158e18..92fd0b7c844713ce 100644 +--- a/sysdeps/hppa/dl-lookupcfg.h ++++ b/sysdeps/hppa/dl-lookupcfg.h +@@ -80,7 +80,9 @@ void attribute_hidden _dl_unmap (struct link_map *map); + /* Extract the code address from a fixup value */ + #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip) + #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) +-#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) ++/* Clear the plabel bit to get the actual address of the descriptor. */ ++#define DL_FIXUP_ADDR_VALUE(addr) \ ++ (*(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (addr) & ~2)) + #define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +-#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ +- (*value) = *(struct fdesc *) (st_value) ++#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ ++ *(value) = *(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (new_value) & ~2) diff --git a/SOURCES/glibc-upstream-2.34-162.patch b/SOURCES/glibc-upstream-2.34-162.patch new file mode 100644 index 0000000..d409366 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-162.patch @@ -0,0 +1,242 @@ +commit 0c03cb54c808173d8e7ba96f6152dfcf627ac496 +Author: Stefan Liebler +Date: Wed Apr 13 14:36:09 2022 +0200 + + S390: Add new s390 platform z16. + + The new IBM z16 is added to platform string array. + The macro _DL_PLATFORMS_COUNT is incremented. + + _dl_hwcaps_subdir is extended by "z16" if HWCAP_S390_VXRS_PDE2 + is set. HWCAP_S390_NNPA is not tested in _dl_hwcaps_subdirs_active + as those instructions may be replaced or removed in future. + + tst-glibc-hwcaps.c is extended in order to test z16 via new marker5. + + A fatal glibc error is dumped if glibc was build with architecture + level set for z16, but run on an older machine. (See dl-hwcap-check.h) + + (cherry picked from commit 2376944b9e5c0364b9fb473e4d8dabca31b57167) + +Conflicts: + sysdeps/s390/s390-64/dl-hwcap-check.h - Use GCCMACRO__ARCH__. + - Backported f01d482f0355a7029d0715ace0ccf3323e7e94bc requires it. + +diff --git a/elf/Makefile b/elf/Makefile +index 3e17a0706f5ec2df..8e2dd91c583f9a62 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -571,6 +571,11 @@ modules-names = \ + libmarkermod4-2 \ + libmarkermod4-3 \ + libmarkermod4-4 \ ++ libmarkermod5-1 \ ++ libmarkermod5-2 \ ++ libmarkermod5-3 \ ++ libmarkermod5-4 \ ++ libmarkermod5-5 \ + ltglobmod1 \ + ltglobmod2 \ + neededobj1 \ +@@ -2412,6 +2417,7 @@ LDFLAGS-libmarkermod1-1.so += -Wl,-soname,libmarkermod1.so + LDFLAGS-libmarkermod2-1.so += -Wl,-soname,libmarkermod2.so + LDFLAGS-libmarkermod3-1.so += -Wl,-soname,libmarkermod3.so + LDFLAGS-libmarkermod4-1.so += -Wl,-soname,libmarkermod4.so ++LDFLAGS-libmarkermod5-1.so += -Wl,-soname,libmarkermod5.so + $(objpfx)libmarkermod%.os : markermodMARKER-VALUE.c + $(compile-command.c) \ + -DMARKER=marker$(firstword $(subst -, ,$*)) \ +@@ -2424,6 +2430,8 @@ $(objpfx)libmarkermod3.so: $(objpfx)libmarkermod3-1.so + cp $< $@ + $(objpfx)libmarkermod4.so: $(objpfx)libmarkermod4-1.so + cp $< $@ ++$(objpfx)libmarkermod5.so: $(objpfx)libmarkermod5-1.so ++ cp $< $@ + + # tst-glibc-hwcaps-prepend checks that --glibc-hwcaps-prepend is + # preferred over auto-detected subdirectories. +diff --git a/elf/tst-glibc-hwcaps-cache.script b/elf/tst-glibc-hwcaps-cache.script +index c3271f61f9e50f2e..d58fc8c5de3c5198 100644 +--- a/elf/tst-glibc-hwcaps-cache.script ++++ b/elf/tst-glibc-hwcaps-cache.script +@@ -4,6 +4,7 @@ + cp $B/elf/libmarkermod2-1.so $L/libmarkermod2.so + cp $B/elf/libmarkermod3-1.so $L/libmarkermod3.so + cp $B/elf/libmarkermod4-1.so $L/libmarkermod4.so ++cp $B/elf/libmarkermod5-1.so $L/libmarkermod5.so + + mkdirp 0770 $L/glibc-hwcaps/power9 + cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/power9/libmarkermod2.so +@@ -20,6 +21,11 @@ mkdirp 0770 $L/glibc-hwcaps/z15 + cp $B/elf/libmarkermod4-2.so $L/glibc-hwcaps/z13/libmarkermod4.so + cp $B/elf/libmarkermod4-3.so $L/glibc-hwcaps/z14/libmarkermod4.so + cp $B/elf/libmarkermod4-4.so $L/glibc-hwcaps/z15/libmarkermod4.so ++mkdirp 0770 $L/glibc-hwcaps/z16 ++cp $B/elf/libmarkermod5-2.so $L/glibc-hwcaps/z13/libmarkermod5.so ++cp $B/elf/libmarkermod5-3.so $L/glibc-hwcaps/z14/libmarkermod5.so ++cp $B/elf/libmarkermod5-4.so $L/glibc-hwcaps/z15/libmarkermod5.so ++cp $B/elf/libmarkermod5-5.so $L/glibc-hwcaps/z16/libmarkermod5.so + + mkdirp 0770 $L/glibc-hwcaps/x86-64-v2 + cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/x86-64-v2/libmarkermod2.so +diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c +index 155f0bd99eccb3f9..755b54ff13a0fa2f 100644 +--- a/sysdeps/s390/dl-procinfo.c ++++ b/sysdeps/s390/dl-procinfo.c +@@ -64,11 +64,12 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[23][9] + #if !defined PROCINFO_DECL && defined SHARED + ._dl_s390_platforms + #else +-PROCINFO_CLASS const char _dl_s390_platforms[10][7] ++PROCINFO_CLASS const char _dl_s390_platforms[11][7] + #endif + #ifndef PROCINFO_DECL + = { +- "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15" ++ "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15", ++ "z16" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index e4e3e334a5b3d47c..d44e1dd97441bd90 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -23,7 +23,7 @@ + + #define _DL_HWCAP_COUNT 23 + +-#define _DL_PLATFORMS_COUNT 10 ++#define _DL_PLATFORMS_COUNT 11 + + /* The kernel provides up to 32 capability bits with elf_hwcap. */ + #define _DL_FIRST_PLATFORM 32 +diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile +index e5da26871c862e63..66ed844e68df5159 100644 +--- a/sysdeps/s390/s390-64/Makefile ++++ b/sysdeps/s390/s390-64/Makefile +@@ -7,8 +7,11 @@ CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused + CFLAGS-dl-load.c += -Wno-unused + CFLAGS-dl-reloc.c += -Wno-unused + +-$(objpfx)tst-glibc-hwcaps: $(objpfx)libmarkermod2-1.so \ +- $(objpfx)libmarkermod3-1.so $(objpfx)libmarkermod4-1.so ++$(objpfx)tst-glibc-hwcaps: \ ++ $(objpfx)libmarkermod2-1.so \ ++ $(objpfx)libmarkermod3-1.so \ ++ $(objpfx)libmarkermod4-1.so \ ++ $(objpfx)libmarkermod5-1.so + $(objpfx)tst-glibc-hwcaps.out: \ + $(objpfx)libmarkermod2.so \ + $(objpfx)glibc-hwcaps/z13/libmarkermod2.so \ +@@ -19,6 +22,11 @@ $(objpfx)tst-glibc-hwcaps.out: \ + $(objpfx)glibc-hwcaps/z13/libmarkermod4.so \ + $(objpfx)glibc-hwcaps/z14/libmarkermod4.so \ + $(objpfx)glibc-hwcaps/z15/libmarkermod4.so \ ++ $(objpfx)libmarkermod5.so \ ++ $(objpfx)glibc-hwcaps/z13/libmarkermod5.so \ ++ $(objpfx)glibc-hwcaps/z14/libmarkermod5.so \ ++ $(objpfx)glibc-hwcaps/z15/libmarkermod5.so \ ++ $(objpfx)glibc-hwcaps/z16/libmarkermod5.so + + $(objpfx)glibc-hwcaps/z13/libmarkermod2.so: $(objpfx)libmarkermod2-2.so + $(make-target-directory) +@@ -38,6 +46,19 @@ $(objpfx)glibc-hwcaps/z14/libmarkermod4.so: $(objpfx)libmarkermod4-3.so + $(objpfx)glibc-hwcaps/z15/libmarkermod4.so: $(objpfx)libmarkermod4-4.so + $(make-target-directory) + cp $< $@ ++$(objpfx)glibc-hwcaps/z13/libmarkermod5.so: $(objpfx)libmarkermod5-2.so ++ $(make-target-directory) ++ cp $< $@ ++$(objpfx)glibc-hwcaps/z14/libmarkermod5.so: $(objpfx)libmarkermod5-3.so ++ $(make-target-directory) ++ cp $< $@ ++$(objpfx)glibc-hwcaps/z15/libmarkermod5.so: $(objpfx)libmarkermod5-4.so ++ $(make-target-directory) ++ cp $< $@ ++$(objpfx)glibc-hwcaps/z16/libmarkermod5.so: $(objpfx)libmarkermod5-5.so ++ $(make-target-directory) ++ cp $< $@ ++ + + ifeq (no,$(build-hardcoded-path-in-tests)) + # This is an ld.so.cache test, and RPATH/RUNPATH in the executable +diff --git a/sysdeps/s390/s390-64/dl-hwcap-check.h b/sysdeps/s390/s390-64/dl-hwcap-check.h +index 27f7e245b1d1a9e9..52c609571b32f4ab 100644 +--- a/sysdeps/s390/s390-64/dl-hwcap-check.h ++++ b/sysdeps/s390/s390-64/dl-hwcap-check.h +@@ -26,7 +26,11 @@ static inline void + dl_hwcap_check (void) + { + #if defined __ARCH__ +-# if GCCMACRO__ARCH__ >= 13 ++# if GCCMACRO__ARCH__ >= 14 ++ if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_PDE2)) ++ _dl_fatal_printf ("\ ++Fatal glibc error: CPU lacks VXRS_PDE2 support (z16 or later required)\n"); ++# elif GCCMACRO__ARCH__ >= 13 + if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_EXT2)) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks VXRS_EXT2 support (z15 or later required)\n"); +diff --git a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c +index b9d094f3d73c2d7a..187d732d560c4a62 100644 +--- a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c ++++ b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c +@@ -19,8 +19,8 @@ + #include + #include + +-const char _dl_hwcaps_subdirs[] = "z15:z14:z13"; +-enum { subdirs_count = 3 }; /* Number of components in _dl_hwcaps_subdirs. */ ++const char _dl_hwcaps_subdirs[] = "z16:z15:z14:z13"; ++enum { subdirs_count = 4 }; /* Number of components in _dl_hwcaps_subdirs. */ + + uint32_t + _dl_hwcaps_subdirs_active (void) +@@ -50,5 +50,12 @@ _dl_hwcaps_subdirs_active (void) + return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); + ++active; + ++ /* z16. ++ Note: We do not list HWCAP_S390_NNPA here as, according to the Principles of ++ Operation, those instructions may be replaced or removed in future. */ ++ if (!(GLRO (dl_hwcap) & HWCAP_S390_VXRS_PDE2)) ++ return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); ++ ++active; ++ + return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); + } +diff --git a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c +index 02397a478c552516..f3b8ef3dec80d2d1 100644 +--- a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c ++++ b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c +@@ -25,6 +25,7 @@ + extern int marker2 (void); + extern int marker3 (void); + extern int marker4 (void); ++extern int marker5 (void); + + /* Return the arch level, 10 for the baseline libmarkermod*.so's. */ + static int +@@ -63,9 +64,11 @@ compute_level (void) + return 12; + if (strcmp (platform, "z15") == 0) + return 13; ++ if (strcmp (platform, "z16") == 0) ++ return 14; + printf ("warning: unrecognized AT_PLATFORM value: %s\n", platform); +- /* Assume that the new platform supports z15. */ +- return 13; ++ /* Assume that the new platform supports z16. */ ++ return 14; + } + + static int +@@ -76,6 +79,7 @@ do_test (void) + TEST_COMPARE (marker2 (), MIN (level - 9, 2)); + TEST_COMPARE (marker3 (), MIN (level - 9, 3)); + TEST_COMPARE (marker4 (), MIN (level - 9, 4)); ++ TEST_COMPARE (marker5 (), MIN (level - 9, 5)); + return 0; + } + diff --git a/SOURCES/glibc-upstream-2.34-163.patch b/SOURCES/glibc-upstream-2.34-163.patch new file mode 100644 index 0000000..251939d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-163.patch @@ -0,0 +1,834 @@ +commit 290db09546b260a30137d03ce97a857e6f15b648 +Author: Adhemerval Zanella +Date: Wed Apr 6 12:24:42 2022 -0300 + + nptl: Handle spurious EINTR when thread cancellation is disabled (BZ#29029) + + Some Linux interfaces never restart after being interrupted by a signal + handler, regardless of the use of SA_RESTART [1]. It means that for + pthread cancellation, if the target thread disables cancellation with + pthread_setcancelstate and calls such interfaces (like poll or select), + it should not see spurious EINTR failures due the internal SIGCANCEL. + + However recent changes made pthread_cancel to always sent the internal + signal, regardless of the target thread cancellation status or type. + To fix it, the previous semantic is restored, where the cancel signal + is only sent if the target thread has cancelation enabled in + asynchronous mode. + + The cancel state and cancel type is moved back to cancelhandling + and atomic operation are used to synchronize between threads. The + patch essentially revert the following commits: + + 8c1c0aae20 nptl: Move cancel type out of cancelhandling + 2b51742531 nptl: Move cancel state out of cancelhandling + 26cfbb7162 nptl: Remove CANCELING_BITMASK + + However I changed the atomic operation to follow the internal C11 + semantic and removed the MACRO usage, it simplifies a bit the + resulting code (and removes another usage of the old atomic macros). + + Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, + and powerpc64-linux-gnu. + + [1] https://man7.org/linux/man-pages/man7/signal.7.html + + Reviewed-by: Florian Weimer + Tested-by: Aurelien Jarno + + (cherry-picked from commit 404656009b459658138ed1bd18f3c6cf3863e6a6) + +diff --git a/manual/process.texi b/manual/process.texi +index 28c9531f4294f56e..9307379194c6f666 100644 +--- a/manual/process.texi ++++ b/manual/process.texi +@@ -68,8 +68,7 @@ until the subprogram terminates before you can do anything else. + @c CLEANUP_HANDLER @ascuplugin @ascuheap @acsmem + @c libc_cleanup_region_start @ascuplugin @ascuheap @acsmem + @c pthread_cleanup_push_defer @ascuplugin @ascuheap @acsmem +-@c __pthread_testcancel @ascuplugin @ascuheap @acsmem +-@c CANCEL_ENABLED_AND_CANCELED ok ++@c cancel_enabled_and_canceled @ascuplugin @ascuheap @acsmem + @c do_cancel @ascuplugin @ascuheap @acsmem + @c cancel_handler ok + @c kill syscall ok +diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c +index 554a721f814b53c4..96101753ec2f4323 100644 +--- a/nptl/allocatestack.c ++++ b/nptl/allocatestack.c +@@ -120,8 +120,6 @@ get_cached_stack (size_t *sizep, void **memp) + + /* Cancellation handling is back to the default. */ + result->cancelhandling = 0; +- result->cancelstate = PTHREAD_CANCEL_ENABLE; +- result->canceltype = PTHREAD_CANCEL_DEFERRED; + result->cleanup = NULL; + result->setup_failed = 0; + +diff --git a/nptl/cancellation.c b/nptl/cancellation.c +index 05962784d51fb98b..e97d56f97d7a5698 100644 +--- a/nptl/cancellation.c ++++ b/nptl/cancellation.c +@@ -31,19 +31,26 @@ int + __pthread_enable_asynccancel (void) + { + struct pthread *self = THREAD_SELF; ++ int oldval = atomic_load_relaxed (&self->cancelhandling); + +- int oldval = THREAD_GETMEM (self, canceltype); +- THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_ASYNCHRONOUS); ++ while (1) ++ { ++ int newval = oldval | CANCELTYPE_BITMASK; + +- int ch = THREAD_GETMEM (self, cancelhandling); ++ if (newval == oldval) ++ break; + +- if (self->cancelstate == PTHREAD_CANCEL_ENABLE +- && (ch & CANCELED_BITMASK) +- && !(ch & EXITING_BITMASK) +- && !(ch & TERMINATED_BITMASK)) +- { +- THREAD_SETMEM (self, result, PTHREAD_CANCELED); +- __do_cancel (); ++ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling, ++ &oldval, newval)) ++ { ++ if (cancel_enabled_and_canceled_and_async (newval)) ++ { ++ self->result = PTHREAD_CANCELED; ++ __do_cancel (); ++ } ++ ++ break; ++ } + } + + return oldval; +@@ -57,10 +64,29 @@ __pthread_disable_asynccancel (int oldtype) + { + /* If asynchronous cancellation was enabled before we do not have + anything to do. */ +- if (oldtype == PTHREAD_CANCEL_ASYNCHRONOUS) ++ if (oldtype & CANCELTYPE_BITMASK) + return; + + struct pthread *self = THREAD_SELF; +- self->canceltype = PTHREAD_CANCEL_DEFERRED; ++ int newval; ++ int oldval = atomic_load_relaxed (&self->cancelhandling); ++ do ++ { ++ newval = oldval & ~CANCELTYPE_BITMASK; ++ } ++ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling, ++ &oldval, newval)); ++ ++ /* We cannot return when we are being canceled. Upon return the ++ thread might be things which would have to be undone. The ++ following loop should loop until the cancellation signal is ++ delivered. */ ++ while (__glibc_unlikely ((newval & (CANCELING_BITMASK | CANCELED_BITMASK)) ++ == CANCELING_BITMASK)) ++ { ++ futex_wait_simple ((unsigned int *) &self->cancelhandling, newval, ++ FUTEX_PRIVATE); ++ newval = atomic_load_relaxed (&self->cancelhandling); ++ } + } + libc_hidden_def (__pthread_disable_asynccancel) +diff --git a/nptl/cleanup_defer.c b/nptl/cleanup_defer.c +index 7e858d0df068276b..35ba40fb0247c7cc 100644 +--- a/nptl/cleanup_defer.c ++++ b/nptl/cleanup_defer.c +@@ -31,9 +31,22 @@ ___pthread_register_cancel_defer (__pthread_unwind_buf_t *buf) + ibuf->priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf); + ibuf->priv.data.cleanup = THREAD_GETMEM (self, cleanup); + +- /* Disable asynchronous cancellation for now. */ +- ibuf->priv.data.canceltype = THREAD_GETMEM (self, canceltype); +- THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_DEFERRED); ++ int cancelhandling = atomic_load_relaxed (&self->cancelhandling); ++ if (__glibc_unlikely (cancelhandling & CANCELTYPE_BITMASK)) ++ { ++ int newval; ++ do ++ { ++ newval = cancelhandling & ~CANCELTYPE_BITMASK; ++ } ++ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling, ++ &cancelhandling, ++ newval)); ++ } ++ ++ ibuf->priv.data.canceltype = (cancelhandling & CANCELTYPE_BITMASK ++ ? PTHREAD_CANCEL_ASYNCHRONOUS ++ : PTHREAD_CANCEL_DEFERRED); + + /* Store the new cleanup handler info. */ + THREAD_SETMEM (self, cleanup_jmp_buf, (struct pthread_unwind_buf *) buf); +@@ -55,9 +68,26 @@ ___pthread_unregister_cancel_restore (__pthread_unwind_buf_t *buf) + + THREAD_SETMEM (self, cleanup_jmp_buf, ibuf->priv.data.prev); + +- THREAD_SETMEM (self, canceltype, ibuf->priv.data.canceltype); +- if (ibuf->priv.data.canceltype == PTHREAD_CANCEL_ASYNCHRONOUS) +- __pthread_testcancel (); ++ if (ibuf->priv.data.canceltype == PTHREAD_CANCEL_DEFERRED) ++ return; ++ ++ int cancelhandling = atomic_load_relaxed (&self->cancelhandling); ++ if (cancelhandling & CANCELTYPE_BITMASK) ++ { ++ int newval; ++ do ++ { ++ newval = cancelhandling | CANCELTYPE_BITMASK; ++ } ++ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling, ++ &cancelhandling, newval)); ++ ++ if (cancel_enabled_and_canceled (cancelhandling)) ++ { ++ self->result = PTHREAD_CANCELED; ++ __do_cancel (); ++ } ++ } + } + versioned_symbol (libc, ___pthread_unregister_cancel_restore, + __pthread_unregister_cancel_restore, GLIBC_2_34); +diff --git a/nptl/descr.h b/nptl/descr.h +index dabf980e29615db3..dfef9c4bda075d13 100644 +--- a/nptl/descr.h ++++ b/nptl/descr.h +@@ -280,18 +280,27 @@ struct pthread + + /* Flags determining processing of cancellation. */ + int cancelhandling; ++ /* Bit set if cancellation is disabled. */ ++#define CANCELSTATE_BIT 0 ++#define CANCELSTATE_BITMASK (1 << CANCELSTATE_BIT) ++ /* Bit set if asynchronous cancellation mode is selected. */ ++#define CANCELTYPE_BIT 1 ++#define CANCELTYPE_BITMASK (1 << CANCELTYPE_BIT) ++ /* Bit set if canceling has been initiated. */ ++#define CANCELING_BIT 2 ++#define CANCELING_BITMASK (1 << CANCELING_BIT) + /* Bit set if canceled. */ + #define CANCELED_BIT 3 +-#define CANCELED_BITMASK (0x01 << CANCELED_BIT) ++#define CANCELED_BITMASK (1 << CANCELED_BIT) + /* Bit set if thread is exiting. */ + #define EXITING_BIT 4 +-#define EXITING_BITMASK (0x01 << EXITING_BIT) ++#define EXITING_BITMASK (1 << EXITING_BIT) + /* Bit set if thread terminated and TCB is freed. */ + #define TERMINATED_BIT 5 +-#define TERMINATED_BITMASK (0x01 << TERMINATED_BIT) ++#define TERMINATED_BITMASK (1 << TERMINATED_BIT) + /* Bit set if thread is supposed to change XID. */ + #define SETXID_BIT 6 +-#define SETXID_BITMASK (0x01 << SETXID_BIT) ++#define SETXID_BITMASK (1 << SETXID_BIT) + + /* Flags. Including those copied from the thread attribute. */ + int flags; +@@ -391,14 +400,6 @@ struct pthread + /* Indicates whether is a C11 thread created by thrd_creat. */ + bool c11; + +- /* Thread cancel state (PTHREAD_CANCEL_ENABLE or +- PTHREAD_CANCEL_DISABLE). */ +- unsigned char cancelstate; +- +- /* Thread cancel type (PTHREAD_CANCEL_DEFERRED or +- PTHREAD_CANCEL_ASYNCHRONOUS). */ +- unsigned char canceltype; +- + /* Used in __pthread_kill_internal to detected a thread that has + exited or is about to exit. exit_lock must only be acquired + after blocking signals. */ +@@ -418,6 +419,22 @@ struct pthread + (sizeof (struct pthread) - offsetof (struct pthread, end_padding)) + } __attribute ((aligned (TCB_ALIGNMENT))); + ++static inline bool ++cancel_enabled_and_canceled (int value) ++{ ++ return (value & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK ++ | TERMINATED_BITMASK)) ++ == CANCELED_BITMASK; ++} ++ ++static inline bool ++cancel_enabled_and_canceled_and_async (int value) ++{ ++ return ((value) & (CANCELSTATE_BITMASK | CANCELTYPE_BITMASK | CANCELED_BITMASK ++ | EXITING_BITMASK | TERMINATED_BITMASK)) ++ == (CANCELTYPE_BITMASK | CANCELED_BITMASK); ++} ++ + /* This yields the pointer that TLS support code calls the thread pointer. */ + #if TLS_TCB_AT_TP + # define TLS_TPADJ(pd) (pd) +diff --git a/nptl/libc-cleanup.c b/nptl/libc-cleanup.c +index 180d15bc9e9a8368..fccb1abe69aa693c 100644 +--- a/nptl/libc-cleanup.c ++++ b/nptl/libc-cleanup.c +@@ -27,9 +27,24 @@ __libc_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer) + + buffer->__prev = THREAD_GETMEM (self, cleanup); + ++ int cancelhandling = atomic_load_relaxed (&self->cancelhandling); ++ + /* Disable asynchronous cancellation for now. */ +- buffer->__canceltype = THREAD_GETMEM (self, canceltype); +- THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_DEFERRED); ++ if (__glibc_unlikely (cancelhandling & CANCELTYPE_BITMASK)) ++ { ++ int newval; ++ do ++ { ++ newval = cancelhandling & ~CANCELTYPE_BITMASK; ++ } ++ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling, ++ &cancelhandling, ++ newval)); ++ } ++ ++ buffer->__canceltype = (cancelhandling & CANCELTYPE_BITMASK ++ ? PTHREAD_CANCEL_ASYNCHRONOUS ++ : PTHREAD_CANCEL_DEFERRED); + + THREAD_SETMEM (self, cleanup, buffer); + } +@@ -42,8 +57,22 @@ __libc_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer) + + THREAD_SETMEM (self, cleanup, buffer->__prev); + +- THREAD_SETMEM (self, canceltype, buffer->__canceltype); +- if (buffer->__canceltype == PTHREAD_CANCEL_ASYNCHRONOUS) +- __pthread_testcancel (); ++ int cancelhandling = atomic_load_relaxed (&self->cancelhandling); ++ if (cancelhandling & CANCELTYPE_BITMASK) ++ { ++ int newval; ++ do ++ { ++ newval = cancelhandling | CANCELTYPE_BITMASK; ++ } ++ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling, ++ &cancelhandling, newval)); ++ ++ if (cancel_enabled_and_canceled (cancelhandling)) ++ { ++ self->result = PTHREAD_CANCELED; ++ __do_cancel (); ++ } ++ } + } + libc_hidden_def (__libc_cleanup_pop_restore) +diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c +index 9bac6e3b76a20312..2680b55586e035fe 100644 +--- a/nptl/pthread_cancel.c ++++ b/nptl/pthread_cancel.c +@@ -43,18 +43,29 @@ sigcancel_handler (int sig, siginfo_t *si, void *ctx) + + struct pthread *self = THREAD_SELF; + +- int ch = atomic_load_relaxed (&self->cancelhandling); +- /* Cancelation not enabled, not cancelled, or already exitting. */ +- if (self->cancelstate == PTHREAD_CANCEL_DISABLE +- || (ch & CANCELED_BITMASK) == 0 +- || (ch & EXITING_BITMASK) != 0) +- return; +- +- /* Set the return value. */ +- THREAD_SETMEM (self, result, PTHREAD_CANCELED); +- /* Make sure asynchronous cancellation is still enabled. */ +- if (self->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS) +- __do_cancel (); ++ int oldval = atomic_load_relaxed (&self->cancelhandling); ++ while (1) ++ { ++ /* We are canceled now. When canceled by another thread this flag ++ is already set but if the signal is directly send (internally or ++ from another process) is has to be done here. */ ++ int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK; ++ ++ if (oldval == newval || (oldval & EXITING_BITMASK) != 0) ++ /* Already canceled or exiting. */ ++ break; ++ ++ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling, ++ &oldval, newval)) ++ { ++ self->result = PTHREAD_CANCELED; ++ ++ /* Make sure asynchronous cancellation is still enabled. */ ++ if ((oldval & CANCELTYPE_BITMASK) != 0) ++ /* Run the registered destructors and terminate the thread. */ ++ __do_cancel (); ++ } ++ } + } + + int +@@ -93,29 +104,70 @@ __pthread_cancel (pthread_t th) + } + #endif + +- int oldch = atomic_fetch_or_acquire (&pd->cancelhandling, CANCELED_BITMASK); +- if ((oldch & CANCELED_BITMASK) != 0) +- return 0; +- +- if (pd == THREAD_SELF) ++ /* Some syscalls are never restarted after being interrupted by a signal ++ handler, regardless of the use of SA_RESTART (they always fail with ++ EINTR). So pthread_cancel cannot send SIGCANCEL unless the cancellation ++ is enabled and set as asynchronous (in this case the cancellation will ++ be acted in the cancellation handler instead by the syscall wrapper). ++ Otherwise the target thread is set as 'cancelling' (CANCELING_BITMASK) ++ by atomically setting 'cancelhandling' and the cancelation will be acted ++ upon on next cancellation entrypoing in the target thread. ++ ++ It also requires to atomically check if cancellation is enabled and ++ asynchronous, so both cancellation state and type are tracked on ++ 'cancelhandling'. */ ++ ++ int result = 0; ++ int oldval = atomic_load_relaxed (&pd->cancelhandling); ++ int newval; ++ do + { +- /* A single-threaded process should be able to kill itself, since there +- is nothing in the POSIX specification that says that it cannot. So +- we set multiple_threads to true so that cancellation points get +- executed. */ +- THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1); ++ newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK; ++ if (oldval == newval) ++ break; ++ ++ /* If the cancellation is handled asynchronously just send a ++ signal. We avoid this if possible since it's more ++ expensive. */ ++ if (cancel_enabled_and_canceled_and_async (newval)) ++ { ++ /* Mark the cancellation as "in progress". */ ++ int newval2 = oldval | CANCELING_BITMASK; ++ if (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling, ++ &oldval, newval2)) ++ continue; ++ ++ if (pd == THREAD_SELF) ++ /* This is not merely an optimization: An application may ++ call pthread_cancel (pthread_self ()) without calling ++ pthread_create, so the signal handler may not have been ++ set up for a self-cancel. */ ++ { ++ pd->result = PTHREAD_CANCELED; ++ if ((newval & CANCELTYPE_BITMASK) != 0) ++ __do_cancel (); ++ } ++ else ++ /* The cancellation handler will take care of marking the ++ thread as canceled. */ ++ result = __pthread_kill_internal (th, SIGCANCEL); ++ ++ break; ++ } ++ ++ /* A single-threaded process should be able to kill itself, since ++ there is nothing in the POSIX specification that says that it ++ cannot. So we set multiple_threads to true so that cancellation ++ points get executed. */ ++ THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1); + #ifndef TLS_MULTIPLE_THREADS_IN_TCB + __libc_multiple_threads = 1; + #endif +- +- THREAD_SETMEM (pd, result, PTHREAD_CANCELED); +- if (pd->cancelstate == PTHREAD_CANCEL_ENABLE +- && pd->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS) +- __do_cancel (); +- return 0; + } ++ while (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling, &oldval, ++ newval)); + +- return __pthread_kill_internal (th, SIGCANCEL); ++ return result; + } + versioned_symbol (libc, __pthread_cancel, pthread_cancel, GLIBC_2_34); + +diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c +index 7303069316caef13..617056ef10671607 100644 +--- a/nptl/pthread_join_common.c ++++ b/nptl/pthread_join_common.c +@@ -57,12 +57,9 @@ __pthread_clockjoin_ex (pthread_t threadid, void **thread_return, + if ((pd == self + || (self->joinid == pd + && (pd->cancelhandling +- & (CANCELED_BITMASK | EXITING_BITMASK ++ & (CANCELING_BITMASK | CANCELED_BITMASK | EXITING_BITMASK + | TERMINATED_BITMASK)) == 0)) +- && !(self->cancelstate == PTHREAD_CANCEL_ENABLE +- && (pd->cancelhandling & (CANCELED_BITMASK | EXITING_BITMASK +- | TERMINATED_BITMASK)) +- == CANCELED_BITMASK)) ++ && !cancel_enabled_and_canceled (self->cancelhandling)) + /* This is a deadlock situation. The threads are waiting for each + other to finish. Note that this is a "may" error. To be 100% + sure we catch this error we would have to lock the data +diff --git a/nptl/pthread_setcancelstate.c b/nptl/pthread_setcancelstate.c +index 7e2b6e4974bd58bd..cb567be5926816f1 100644 +--- a/nptl/pthread_setcancelstate.c ++++ b/nptl/pthread_setcancelstate.c +@@ -31,9 +31,29 @@ __pthread_setcancelstate (int state, int *oldstate) + + self = THREAD_SELF; + +- if (oldstate != NULL) +- *oldstate = self->cancelstate; +- self->cancelstate = state; ++ int oldval = atomic_load_relaxed (&self->cancelhandling); ++ while (1) ++ { ++ int newval = (state == PTHREAD_CANCEL_DISABLE ++ ? oldval | CANCELSTATE_BITMASK ++ : oldval & ~CANCELSTATE_BITMASK); ++ ++ if (oldstate != NULL) ++ *oldstate = ((oldval & CANCELSTATE_BITMASK) ++ ? PTHREAD_CANCEL_DISABLE : PTHREAD_CANCEL_ENABLE); ++ ++ if (oldval == newval) ++ break; ++ ++ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling, ++ &oldval, newval)) ++ { ++ if (cancel_enabled_and_canceled_and_async (newval)) ++ __do_cancel (); ++ ++ break; ++ } ++ } + + return 0; + } +diff --git a/nptl/pthread_setcanceltype.c b/nptl/pthread_setcanceltype.c +index e7b24ae733dcc0f2..e08ff7b141f904f1 100644 +--- a/nptl/pthread_setcanceltype.c ++++ b/nptl/pthread_setcanceltype.c +@@ -29,11 +29,32 @@ __pthread_setcanceltype (int type, int *oldtype) + + volatile struct pthread *self = THREAD_SELF; + +- if (oldtype != NULL) +- *oldtype = self->canceltype; +- self->canceltype = type; +- if (type == PTHREAD_CANCEL_ASYNCHRONOUS) +- __pthread_testcancel (); ++ int oldval = atomic_load_relaxed (&self->cancelhandling); ++ while (1) ++ { ++ int newval = (type == PTHREAD_CANCEL_ASYNCHRONOUS ++ ? oldval | CANCELTYPE_BITMASK ++ : oldval & ~CANCELTYPE_BITMASK); ++ ++ if (oldtype != NULL) ++ *oldtype = ((oldval & CANCELTYPE_BITMASK) ++ ? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED); ++ ++ if (oldval == newval) ++ break; ++ ++ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling, ++ &oldval, newval)) ++ { ++ if (cancel_enabled_and_canceled_and_async (newval)) ++ { ++ THREAD_SETMEM (self, result, PTHREAD_CANCELED); ++ __do_cancel (); ++ } ++ ++ break; ++ } ++ } + + return 0; + } +diff --git a/nptl/pthread_testcancel.c b/nptl/pthread_testcancel.c +index 31185d89f2ab84c6..25230215fd607e8b 100644 +--- a/nptl/pthread_testcancel.c ++++ b/nptl/pthread_testcancel.c +@@ -24,13 +24,10 @@ void + ___pthread_testcancel (void) + { + struct pthread *self = THREAD_SELF; +- int cancelhandling = THREAD_GETMEM (self, cancelhandling); +- if (self->cancelstate == PTHREAD_CANCEL_ENABLE +- && (cancelhandling & CANCELED_BITMASK) +- && !(cancelhandling & EXITING_BITMASK) +- && !(cancelhandling & TERMINATED_BITMASK)) ++ int cancelhandling = atomic_load_relaxed (&self->cancelhandling); ++ if (cancel_enabled_and_canceled (cancelhandling)) + { +- THREAD_SETMEM (self, result, PTHREAD_CANCELED); ++ self->result = PTHREAD_CANCELED; + __do_cancel (); + } + } +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index b39dfbff2c6678d5..23aa4cfc0b784dfc 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -107,7 +107,4 @@ __tls_init_tp (void) + It will be bigger than it actually is, but for unwind.c/pt-longjmp.c + purposes this is good enough. */ + THREAD_SETMEM (pd, stackblock_size, (size_t) __libc_stack_end); +- +- THREAD_SETMEM (pd, cancelstate, PTHREAD_CANCEL_ENABLE); +- THREAD_SETMEM (pd, canceltype, PTHREAD_CANCEL_DEFERRED); + } +diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h +index 374657a2fd0ee19a..b968afc4c6b61b92 100644 +--- a/sysdeps/nptl/pthreadP.h ++++ b/sysdeps/nptl/pthreadP.h +@@ -276,7 +276,7 @@ __do_cancel (void) + struct pthread *self = THREAD_SELF; + + /* Make sure we get no more cancellations. */ +- THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT); ++ atomic_bit_set (&self->cancelhandling, EXITING_BIT); + + __pthread_unwind ((__pthread_unwind_buf_t *) + THREAD_GETMEM (self, cleanup_jmp_buf)); +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index c65710169697ad95..00419c4d199df912 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -69,6 +69,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 tst-cancel16 \ + tst-cancel18 tst-cancel19 tst-cancel20 tst-cancel21 \ + tst-cancel22 tst-cancel23 tst-cancel26 tst-cancel27 tst-cancel28 \ ++ tst-cancel29 \ + tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 \ + tst-clock1 \ + tst-cond-except \ +diff --git a/sysdeps/pthread/tst-cancel29.c b/sysdeps/pthread/tst-cancel29.c +new file mode 100644 +index 0000000000000000..4f0d99e002883be4 +--- /dev/null ++++ b/sysdeps/pthread/tst-cancel29.c +@@ -0,0 +1,207 @@ ++/* Check if a thread that disables cancellation and which call functions ++ that might be interrupted by a signal do not see the internal SIGCANCEL. ++ ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* On Linux some interfaces are never restarted after being interrupted by ++ a signal handler, regardless of the use of SA_RESTART. It means that ++ if asynchronous cancellation is not enabled, the pthread_cancel can not ++ set the internal SIGCANCEL otherwise the interface might see a spurious ++ EINTR failure. */ ++ ++static pthread_barrier_t b; ++ ++/* Cleanup handling test. */ ++static int cl_called; ++static void ++cl (void *arg) ++{ ++ ++cl_called; ++} ++ ++static void * ++tf_sigtimedwait (void *arg) ++{ ++ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); ++ xpthread_barrier_wait (&b); ++ ++ int r; ++ pthread_cleanup_push (cl, NULL); ++ ++ sigset_t mask; ++ sigemptyset (&mask); ++ r = sigtimedwait (&mask, NULL, &(struct timespec) { 0, 250000000 }); ++ if (r != -1) ++ return (void*) -1; ++ if (errno != EAGAIN) ++ return (void*) -2; ++ ++ pthread_cleanup_pop (0); ++ return NULL; ++} ++ ++static void * ++tf_poll (void *arg) ++{ ++ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); ++ xpthread_barrier_wait (&b); ++ ++ int r; ++ pthread_cleanup_push (cl, NULL); ++ ++ r = poll (NULL, 0, 250); ++ if (r != 0) ++ return (void*) -1; ++ ++ pthread_cleanup_pop (0); ++ return NULL; ++} ++ ++static void * ++tf_ppoll (void *arg) ++{ ++ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); ++ ++ xpthread_barrier_wait (&b); ++ ++ int r; ++ pthread_cleanup_push (cl, NULL); ++ ++ r = ppoll (NULL, 0, &(struct timespec) { 0, 250000000 }, NULL); ++ if (r != 0) ++ return (void*) -1; ++ ++ pthread_cleanup_pop (0); ++ return NULL; ++} ++ ++static void * ++tf_select (void *arg) ++{ ++ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); ++ xpthread_barrier_wait (&b); ++ ++ int r; ++ pthread_cleanup_push (cl, NULL); ++ ++ r = select (0, NULL, NULL, NULL, &(struct timeval) { 0, 250000 }); ++ if (r != 0) ++ return (void*) -1; ++ ++ pthread_cleanup_pop (0); ++ return NULL; ++} ++ ++static void * ++tf_pselect (void *arg) ++{ ++ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); ++ xpthread_barrier_wait (&b); ++ ++ int r; ++ pthread_cleanup_push (cl, NULL); ++ ++ r = pselect (0, NULL, NULL, NULL, &(struct timespec) { 0, 250000000 }, NULL); ++ if (r != 0) ++ return (void*) -1; ++ ++ pthread_cleanup_pop (0); ++ return NULL; ++} ++ ++static void * ++tf_clock_nanosleep (void *arg) ++{ ++ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); ++ xpthread_barrier_wait (&b); ++ ++ int r; ++ pthread_cleanup_push (cl, NULL); ++ ++ r = clock_nanosleep (CLOCK_REALTIME, 0, &(struct timespec) { 0, 250000000 }, ++ NULL); ++ if (r != 0) ++ return (void*) -1; ++ ++ pthread_cleanup_pop (0); ++ return NULL; ++} ++ ++struct cancel_test_t ++{ ++ const char *name; ++ void * (*cf) (void *); ++} tests[] = ++{ ++ { "sigtimedwait", tf_sigtimedwait, }, ++ { "poll", tf_poll, }, ++ { "ppoll", tf_ppoll, }, ++ { "select", tf_select, }, ++ { "pselect", tf_pselect , }, ++ { "clock_nanosleep", tf_clock_nanosleep, }, ++}; ++ ++static int ++do_test (void) ++{ ++ for (int i = 0; i < array_length (tests); i++) ++ { ++ xpthread_barrier_init (&b, NULL, 2); ++ ++ cl_called = 0; ++ ++ pthread_t th = xpthread_create (NULL, tests[i].cf, NULL); ++ ++ xpthread_barrier_wait (&b); ++ ++ struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 }; ++ while (nanosleep (&ts, &ts) != 0) ++ continue; ++ ++ xpthread_cancel (th); ++ ++ void *status = xpthread_join (th); ++ if (status != NULL) ++ printf ("test '%s' failed: %" PRIdPTR "\n", tests[i].name, ++ (intptr_t) status); ++ TEST_VERIFY (status == NULL); ++ ++ xpthread_barrier_destroy (&b); ++ ++ TEST_COMPARE (cl_called, 0); ++ ++ printf ("in-time cancel test of '%s' successful\n", tests[i].name); ++ } ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-164.patch b/SOURCES/glibc-upstream-2.34-164.patch new file mode 100644 index 0000000..dbe230b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-164.patch @@ -0,0 +1,23 @@ +commit 5d8c7776343b3f1b96ef7777e4504378f23c041a +Author: Samuel Thibault +Date: Tue Apr 12 22:14:34 2022 +0200 + + hurd: Fix arbitrary error code + + ELIBBAD is Linux-specific. + + (cherry picked from commit 67ab66541dc1164540abda284645e38be90b5119) + +diff --git a/nss/nss_test_errno.c b/nss/nss_test_errno.c +index 680f8a07b97fe263..59a5c717bebd296f 100644 +--- a/nss/nss_test_errno.c ++++ b/nss/nss_test_errno.c +@@ -28,7 +28,7 @@ static void __attribute__ ((constructor)) + init (void) + { + /* An arbitrary error code which is otherwise not used. */ +- errno = ELIBBAD; ++ errno = -1009; + } + + /* Lookup functions for pwd follow that do not return any data. */ diff --git a/SOURCES/glibc-upstream-2.34-165.patch b/SOURCES/glibc-upstream-2.34-165.patch new file mode 100644 index 0000000..1bab4fc --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-165.patch @@ -0,0 +1,104 @@ +commit b87b697f15d6bf7e576a2eeadc1f740172f9d013 +Author: =Joshua Kinard +Date: Mon Apr 18 09:55:08 2022 -0300 + + mips: Fix mips64n32 64 bit time_t stat support (BZ#29069) + + Add missing support initially added by 4e8521333bea6e89fcef1020 + (which missed n32 stat). + + (cherry picked from commit 78fb88827362fbd2cc8aa32892ae5b015106e25c) + +diff --git a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h +index ab9f474cbc271b7c..ed5b1bc00ba52406 100644 +--- a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h +@@ -131,27 +131,30 @@ struct stat64 + + struct stat + { ++# ifdef __USE_TIME_BITS64 ++# include ++# else + __dev_t st_dev; + int st_pad1[3]; /* Reserved for st_dev expansion */ +-# ifndef __USE_FILE_OFFSET64 ++# ifndef __USE_FILE_OFFSET64 + __ino_t st_ino; +-# else ++# else + __ino64_t st_ino; +-# endif ++# endif + __mode_t st_mode; + __nlink_t st_nlink; + __uid_t st_uid; + __gid_t st_gid; + __dev_t st_rdev; +-# if !defined __USE_FILE_OFFSET64 ++# if !defined __USE_FILE_OFFSET64 + unsigned int st_pad2[2]; /* Reserved for st_rdev expansion */ + __off_t st_size; + int st_pad3; +-# else ++# else + unsigned int st_pad2[3]; /* Reserved for st_rdev expansion */ + __off64_t st_size; +-# endif +-# ifdef __USE_XOPEN2K8 ++# endif ++# ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -161,30 +164,34 @@ struct stat + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-# define st_atime st_atim.tv_sec /* Backward compatibility. */ +-# define st_mtime st_mtim.tv_sec +-# define st_ctime st_ctim.tv_sec +-# else ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-# endif ++# endif + __blksize_t st_blksize; + unsigned int st_pad4; +-# ifndef __USE_FILE_OFFSET64 ++# ifndef __USE_FILE_OFFSET64 + __blkcnt_t st_blocks; +-# else ++# else + __blkcnt64_t st_blocks; +-# endif ++# endif + int st_pad5[14]; ++# endif + }; + + #ifdef __USE_LARGEFILE64 + struct stat64 + { ++# ifdef __USE_TIME_BITS64 ++# include ++# else + __dev_t st_dev; + unsigned int st_pad1[3]; /* Reserved for st_dev expansion */ + __ino64_t st_ino; +@@ -217,6 +224,7 @@ struct stat64 + unsigned int st_pad3; + __blkcnt64_t st_blocks; + int st_pad4[14]; ++# endif /* __USE_TIME_BITS64 */ + }; + #endif + diff --git a/SOURCES/glibc-upstream-2.34-166.patch b/SOURCES/glibc-upstream-2.34-166.patch new file mode 100644 index 0000000..c2db463 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-166.patch @@ -0,0 +1,35 @@ +commit 71326f1f2fd09dafb9c34404765fb88129e94237 +Author: Adhemerval Zanella +Date: Wed Apr 20 12:01:43 2022 -0300 + + nptl: Fix pthread_cancel cancelhandling atomic operations + + The 404656009b reversion did not setup the atomic loop to set the + cancel bits correctly. The fix is essentially what pthread_cancel + did prior 26cfbb7162ad. + + Checked on x86_64-linux-gnu and aarch64-linux-gnu. + + (cherry picked from commit 62be9681677e7ce820db721c126909979382d379) + +diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c +index 2680b55586e035fe..64fd183fde59907b 100644 +--- a/nptl/pthread_cancel.c ++++ b/nptl/pthread_cancel.c +@@ -122,6 +122,7 @@ __pthread_cancel (pthread_t th) + int newval; + do + { ++ again: + newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK; + if (oldval == newval) + break; +@@ -135,7 +136,7 @@ __pthread_cancel (pthread_t th) + int newval2 = oldval | CANCELING_BITMASK; + if (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling, + &oldval, newval2)) +- continue; ++ goto again; + + if (pd == THREAD_SELF) + /* This is not merely an optimization: An application may diff --git a/SOURCES/glibc-upstream-2.34-167.patch b/SOURCES/glibc-upstream-2.34-167.patch new file mode 100644 index 0000000..e00042d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-167.patch @@ -0,0 +1,1446 @@ +commit 3e0a91b79b409a6a4113a0fdb08221c0bb29cfce +Author: Florian Weimer +Date: Mon Apr 11 11:28:08 2022 +0200 + + scripts: Add glibcelf.py module + + Hopefully, this will lead to tests that are easier to maintain. The + current approach of parsing readelf -W output using regular expressions + is not necessarily easier than parsing the ELF data directly. + + This module is still somewhat incomplete (e.g., coverage of relocation + types and versioning information is missing), but it is sufficient to + perform basic symbol analysis or program header analysis. + + The EM_* mapping for architecture-specific constant classes (e.g., + SttX86_64) is not yet implemented. The classes are defined for the + benefit of elf/tst-glibcelf.py. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 30035d67728a846fa39749cd162afd278ac654c4) + +diff --git a/elf/Makefile b/elf/Makefile +index 8e2dd91c583f9a62..8afbe3f6ab259331 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -1053,6 +1053,13 @@ CFLAGS-tst-prelink.c += -fno-pie + tst-prelink-no-pie = yes + endif + ++tests-special += $(objpfx)tst-glibcelf.out ++$(objpfx)tst-glibcelf.out: tst-glibcelf.py elf.h $(..)/scripts/glibcelf.py \ ++ $(..)/scripts/glibcextract.py ++ PYTHONPATH=$(..)scripts $(PYTHON) tst-glibcelf.py \ ++ --cc="$(CC) $(patsubst -DMODULE_NAME=%,-DMODULE_NAME=testsuite,$(CPPFLAGS))" \ ++ < /dev/null > $@ 2>&1; $(evaluate-test) ++ + # The test requires shared _and_ PIE because the executable + # unit test driver must be able to link with the shared object + # that is going to eventually go into an installed DSO. +diff --git a/elf/tst-glibcelf.py b/elf/tst-glibcelf.py +new file mode 100644 +index 0000000000000000..bf15a3bad4479e08 +--- /dev/null ++++ b/elf/tst-glibcelf.py +@@ -0,0 +1,260 @@ ++#!/usr/bin/python3 ++# Verify scripts/glibcelf.py contents against elf/elf.h. ++# Copyright (C) 2022 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++import argparse ++import enum ++import sys ++ ++import glibcelf ++import glibcextract ++ ++errors_encountered = 0 ++ ++def error(message): ++ global errors_encountered ++ sys.stdout.write('error: {}\n'.format(message)) ++ errors_encountered += 1 ++ ++# The enum constants in glibcelf are expected to have exactly these ++# prefixes. ++expected_constant_prefixes = tuple( ++ 'ELFCLASS ELFDATA EM_ ET_ DT_ PF_ PT_ SHF_ SHN_ SHT_ STB_ STT_'.split()) ++ ++def find_constant_prefix(name): ++ """Returns a matching prefix from expected_constant_prefixes or None.""" ++ for prefix in expected_constant_prefixes: ++ if name.startswith(prefix): ++ return prefix ++ return None ++ ++def find_enum_types(): ++ """A generator for OpenIntEnum and IntFlag classes in glibcelf.""" ++ for obj in vars(glibcelf).values(): ++ if isinstance(obj, type) and obj.__bases__[0] in ( ++ glibcelf._OpenIntEnum, enum.Enum, enum.IntFlag): ++ yield obj ++ ++def check_duplicates(): ++ """Verifies that enum types do not have duplicate values. ++ ++ Different types must have different member names, too. ++ ++ """ ++ global_seen = {} ++ for typ in find_enum_types(): ++ seen = {} ++ last = None ++ for (name, e) in typ.__members__.items(): ++ if e.value in seen: ++ error('{} has {}={} and {}={}'.format( ++ typ, seen[e.value], e.value, name, e.value)) ++ last = e ++ else: ++ seen[e.value] = name ++ if last is not None and last.value > e.value: ++ error('{} has {}={} after {}={}'.format( ++ typ, name, e.value, last.name, last.value)) ++ if name in global_seen: ++ error('{} used in {} and {}'.format( ++ name, global_seen[name], typ)) ++ else: ++ global_seen[name] = typ ++ ++def check_constant_prefixes(): ++ """Check that the constant prefixes match expected_constant_prefixes.""" ++ seen = set() ++ for typ in find_enum_types(): ++ typ_prefix = None ++ for val in typ: ++ prefix = find_constant_prefix(val.name) ++ if prefix is None: ++ error('constant {!r} for {} has unknown prefix'.format( ++ val, typ)) ++ break ++ elif typ_prefix is None: ++ typ_prefix = prefix ++ seen.add(typ_prefix) ++ elif prefix != typ_prefix: ++ error('prefix {!r} for constant {!r}, expected {!r}'.format( ++ prefix, val, typ_prefix)) ++ if typ_prefix is None: ++ error('empty enum type {}'.format(typ)) ++ ++ for prefix in sorted(set(expected_constant_prefixes) - seen): ++ error('missing constant prefix {!r}'.format(prefix)) ++ # Reverse difference is already covered inside the loop. ++ ++def find_elf_h_constants(cc): ++ """Returns a dictionary of relevant constants from .""" ++ return glibcextract.compute_macro_consts( ++ source_text='#include ', ++ cc=cc, ++ macro_re='|'.join( ++ prefix + '.*' for prefix in expected_constant_prefixes)) ++ ++# The first part of the pair is a name of an constant that is ++# dropped from glibcelf. The second part is the constant as it is ++# used in . ++glibcelf_skipped_aliases = ( ++ ('EM_ARC_A5', 'EM_ARC_COMPACT'), ++ ('PF_PARISC_SBP', 'PF_HP_SBP') ++) ++ ++# Constants that provide little value and are not included in ++# glibcelf: *LO*/*HI* range constants, *NUM constants counting the ++# number of constants. Also includes the alias names from ++# glibcelf_skipped_aliases. ++glibcelf_skipped_constants = frozenset( ++ [e[0] for e in glibcelf_skipped_aliases]) | frozenset(""" ++DT_AARCH64_NUM ++DT_ADDRNUM ++DT_ADDRRNGHI ++DT_ADDRRNGLO ++DT_ALPHA_NUM ++DT_ENCODING ++DT_EXTRANUM ++DT_HIOS ++DT_HIPROC ++DT_IA_64_NUM ++DT_LOOS ++DT_LOPROC ++DT_MIPS_NUM ++DT_NUM ++DT_PPC64_NUM ++DT_PPC_NUM ++DT_PROCNUM ++DT_SPARC_NUM ++DT_VALNUM ++DT_VALRNGHI ++DT_VALRNGLO ++DT_VERSIONTAGNUM ++ELFCLASSNUM ++ELFDATANUM ++ET_HIOS ++ET_HIPROC ++ET_LOOS ++ET_LOPROC ++ET_NUM ++PF_MASKOS ++PF_MASKPROC ++PT_HIOS ++PT_HIPROC ++PT_HISUNW ++PT_LOOS ++PT_LOPROC ++PT_LOSUNW ++SHF_MASKOS ++SHF_MASKPROC ++SHN_HIOS ++SHN_HIPROC ++SHN_HIRESERVE ++SHN_LOOS ++SHN_LOPROC ++SHN_LORESERVE ++SHT_HIOS ++SHT_HIPROC ++SHT_HIPROC ++SHT_HISUNW ++SHT_HIUSER ++SHT_LOOS ++SHT_LOPROC ++SHT_LOSUNW ++SHT_LOUSER ++SHT_NUM ++STB_HIOS ++STB_HIPROC ++STB_LOOS ++STB_LOPROC ++STB_NUM ++STT_HIOS ++STT_HIPROC ++STT_LOOS ++STT_LOPROC ++STT_NUM ++""".strip().split()) ++ ++def check_constant_values(cc): ++ """Checks the values of constants against glibcelf.""" ++ ++ glibcelf_constants = { ++ e.name: e for typ in find_enum_types() for e in typ} ++ elf_h_constants = find_elf_h_constants(cc=cc) ++ ++ missing_in_glibcelf = (set(elf_h_constants) - set(glibcelf_constants) ++ - glibcelf_skipped_constants) ++ for name in sorted(missing_in_glibcelf): ++ error('constant {} is missing from glibcelf'.format(name)) ++ ++ unexpected_in_glibcelf = \ ++ set(glibcelf_constants) & glibcelf_skipped_constants ++ for name in sorted(unexpected_in_glibcelf): ++ error('constant {} is supposed to be filtered from glibcelf'.format( ++ name)) ++ ++ missing_in_elf_h = set(glibcelf_constants) - set(elf_h_constants) ++ for name in sorted(missing_in_elf_h): ++ error('constant {} is missing from '.format(name)) ++ ++ expected_in_elf_h = glibcelf_skipped_constants - set(elf_h_constants) ++ for name in expected_in_elf_h: ++ error('filtered constant {} is missing from '.format(name)) ++ ++ for alias_name, name_in_glibcelf in glibcelf_skipped_aliases: ++ if name_in_glibcelf not in glibcelf_constants: ++ error('alias value {} for {} not in glibcelf'.format( ++ name_in_glibcelf, alias_name)) ++ elif (int(elf_h_constants[alias_name]) ++ != glibcelf_constants[name_in_glibcelf].value): ++ error(' has {}={}, glibcelf has {}={}'.format( ++ alias_name, elf_h_constants[alias_name], ++ name_in_glibcelf, glibcelf_constants[name_in_glibcelf])) ++ ++ # Check for value mismatches: ++ for name in sorted(set(glibcelf_constants) & set(elf_h_constants)): ++ glibcelf_value = glibcelf_constants[name].value ++ elf_h_value = int(elf_h_constants[name]) ++ # On 32-bit architectures as some constants that are ++ # parsed as signed, while they are unsigned in glibcelf. So ++ # far, this only affects some flag constants, so special-case ++ # them here. ++ if (glibcelf_value != elf_h_value ++ and not (isinstance(glibcelf_constants[name], enum.IntFlag) ++ and glibcelf_value == 1 << 31 ++ and elf_h_value == -(1 << 31))): ++ error('{}: glibcelf has {!r}, has {!r}'.format( ++ name, glibcelf_value, elf_h_value)) ++ ++def main(): ++ """The main entry point.""" ++ parser = argparse.ArgumentParser( ++ description="Check glibcelf.py and elf.h against each other.") ++ parser.add_argument('--cc', metavar='CC', ++ help='C compiler (including options) to use') ++ args = parser.parse_args() ++ ++ check_duplicates() ++ check_constant_prefixes() ++ check_constant_values(cc=args.cc) ++ ++ if errors_encountered > 0: ++ print("note: errors encountered:", errors_encountered) ++ sys.exit(1) ++ ++if __name__ == '__main__': ++ main() +diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py +new file mode 100644 +index 0000000000000000..8f7d0ca184845714 +--- /dev/null ++++ b/scripts/glibcelf.py +@@ -0,0 +1,1135 @@ ++#!/usr/bin/python3 ++# ELF support functionality for Python. ++# Copyright (C) 2022 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++"""Basic ELF parser. ++ ++Use Image.readfile(path) to read an ELF file into memory and begin ++parsing it. ++ ++""" ++ ++import collections ++import enum ++import struct ++ ++class _OpenIntEnum(enum.IntEnum): ++ """Integer enumeration that supports arbitrary int values.""" ++ @classmethod ++ def _missing_(cls, value): ++ # See enum.IntFlag._create_pseudo_member_. This allows ++ # creating of enum constants with arbitrary integer values. ++ pseudo_member = int.__new__(cls, value) ++ pseudo_member._name_ = None ++ pseudo_member._value_ = value ++ return pseudo_member ++ ++ def __repr__(self): ++ name = self._name_ ++ if name is not None: ++ # The names have prefixes like SHT_, implying their type. ++ return name ++ return '{}({})'.format(self.__class__.__name__, self._value_) ++ ++ def __str__(self): ++ name = self._name_ ++ if name is not None: ++ return name ++ return str(self._value_) ++ ++class ElfClass(_OpenIntEnum): ++ """ELF word size. Type of EI_CLASS values.""" ++ ELFCLASSNONE = 0 ++ ELFCLASS32 = 1 ++ ELFCLASS64 = 2 ++ ++class ElfData(_OpenIntEnum): ++ """ELF endianess. Type of EI_DATA values.""" ++ ELFDATANONE = 0 ++ ELFDATA2LSB = 1 ++ ELFDATA2MSB = 2 ++ ++class Machine(_OpenIntEnum): ++ """ELF machine type. Type of values in Ehdr.e_machine field.""" ++ EM_NONE = 0 ++ EM_M32 = 1 ++ EM_SPARC = 2 ++ EM_386 = 3 ++ EM_68K = 4 ++ EM_88K = 5 ++ EM_IAMCU = 6 ++ EM_860 = 7 ++ EM_MIPS = 8 ++ EM_S370 = 9 ++ EM_MIPS_RS3_LE = 10 ++ EM_PARISC = 15 ++ EM_VPP500 = 17 ++ EM_SPARC32PLUS = 18 ++ EM_960 = 19 ++ EM_PPC = 20 ++ EM_PPC64 = 21 ++ EM_S390 = 22 ++ EM_SPU = 23 ++ EM_V800 = 36 ++ EM_FR20 = 37 ++ EM_RH32 = 38 ++ EM_RCE = 39 ++ EM_ARM = 40 ++ EM_FAKE_ALPHA = 41 ++ EM_SH = 42 ++ EM_SPARCV9 = 43 ++ EM_TRICORE = 44 ++ EM_ARC = 45 ++ EM_H8_300 = 46 ++ EM_H8_300H = 47 ++ EM_H8S = 48 ++ EM_H8_500 = 49 ++ EM_IA_64 = 50 ++ EM_MIPS_X = 51 ++ EM_COLDFIRE = 52 ++ EM_68HC12 = 53 ++ EM_MMA = 54 ++ EM_PCP = 55 ++ EM_NCPU = 56 ++ EM_NDR1 = 57 ++ EM_STARCORE = 58 ++ EM_ME16 = 59 ++ EM_ST100 = 60 ++ EM_TINYJ = 61 ++ EM_X86_64 = 62 ++ EM_PDSP = 63 ++ EM_PDP10 = 64 ++ EM_PDP11 = 65 ++ EM_FX66 = 66 ++ EM_ST9PLUS = 67 ++ EM_ST7 = 68 ++ EM_68HC16 = 69 ++ EM_68HC11 = 70 ++ EM_68HC08 = 71 ++ EM_68HC05 = 72 ++ EM_SVX = 73 ++ EM_ST19 = 74 ++ EM_VAX = 75 ++ EM_CRIS = 76 ++ EM_JAVELIN = 77 ++ EM_FIREPATH = 78 ++ EM_ZSP = 79 ++ EM_MMIX = 80 ++ EM_HUANY = 81 ++ EM_PRISM = 82 ++ EM_AVR = 83 ++ EM_FR30 = 84 ++ EM_D10V = 85 ++ EM_D30V = 86 ++ EM_V850 = 87 ++ EM_M32R = 88 ++ EM_MN10300 = 89 ++ EM_MN10200 = 90 ++ EM_PJ = 91 ++ EM_OPENRISC = 92 ++ EM_ARC_COMPACT = 93 ++ EM_XTENSA = 94 ++ EM_VIDEOCORE = 95 ++ EM_TMM_GPP = 96 ++ EM_NS32K = 97 ++ EM_TPC = 98 ++ EM_SNP1K = 99 ++ EM_ST200 = 100 ++ EM_IP2K = 101 ++ EM_MAX = 102 ++ EM_CR = 103 ++ EM_F2MC16 = 104 ++ EM_MSP430 = 105 ++ EM_BLACKFIN = 106 ++ EM_SE_C33 = 107 ++ EM_SEP = 108 ++ EM_ARCA = 109 ++ EM_UNICORE = 110 ++ EM_EXCESS = 111 ++ EM_DXP = 112 ++ EM_ALTERA_NIOS2 = 113 ++ EM_CRX = 114 ++ EM_XGATE = 115 ++ EM_C166 = 116 ++ EM_M16C = 117 ++ EM_DSPIC30F = 118 ++ EM_CE = 119 ++ EM_M32C = 120 ++ EM_TSK3000 = 131 ++ EM_RS08 = 132 ++ EM_SHARC = 133 ++ EM_ECOG2 = 134 ++ EM_SCORE7 = 135 ++ EM_DSP24 = 136 ++ EM_VIDEOCORE3 = 137 ++ EM_LATTICEMICO32 = 138 ++ EM_SE_C17 = 139 ++ EM_TI_C6000 = 140 ++ EM_TI_C2000 = 141 ++ EM_TI_C5500 = 142 ++ EM_TI_ARP32 = 143 ++ EM_TI_PRU = 144 ++ EM_MMDSP_PLUS = 160 ++ EM_CYPRESS_M8C = 161 ++ EM_R32C = 162 ++ EM_TRIMEDIA = 163 ++ EM_QDSP6 = 164 ++ EM_8051 = 165 ++ EM_STXP7X = 166 ++ EM_NDS32 = 167 ++ EM_ECOG1X = 168 ++ EM_MAXQ30 = 169 ++ EM_XIMO16 = 170 ++ EM_MANIK = 171 ++ EM_CRAYNV2 = 172 ++ EM_RX = 173 ++ EM_METAG = 174 ++ EM_MCST_ELBRUS = 175 ++ EM_ECOG16 = 176 ++ EM_CR16 = 177 ++ EM_ETPU = 178 ++ EM_SLE9X = 179 ++ EM_L10M = 180 ++ EM_K10M = 181 ++ EM_AARCH64 = 183 ++ EM_AVR32 = 185 ++ EM_STM8 = 186 ++ EM_TILE64 = 187 ++ EM_TILEPRO = 188 ++ EM_MICROBLAZE = 189 ++ EM_CUDA = 190 ++ EM_TILEGX = 191 ++ EM_CLOUDSHIELD = 192 ++ EM_COREA_1ST = 193 ++ EM_COREA_2ND = 194 ++ EM_ARCV2 = 195 ++ EM_OPEN8 = 196 ++ EM_RL78 = 197 ++ EM_VIDEOCORE5 = 198 ++ EM_78KOR = 199 ++ EM_56800EX = 200 ++ EM_BA1 = 201 ++ EM_BA2 = 202 ++ EM_XCORE = 203 ++ EM_MCHP_PIC = 204 ++ EM_INTELGT = 205 ++ EM_KM32 = 210 ++ EM_KMX32 = 211 ++ EM_EMX16 = 212 ++ EM_EMX8 = 213 ++ EM_KVARC = 214 ++ EM_CDP = 215 ++ EM_COGE = 216 ++ EM_COOL = 217 ++ EM_NORC = 218 ++ EM_CSR_KALIMBA = 219 ++ EM_Z80 = 220 ++ EM_VISIUM = 221 ++ EM_FT32 = 222 ++ EM_MOXIE = 223 ++ EM_AMDGPU = 224 ++ EM_RISCV = 243 ++ EM_BPF = 247 ++ EM_CSKY = 252 ++ EM_NUM = 253 ++ EM_ALPHA = 0x9026 ++ ++class Et(_OpenIntEnum): ++ """ELF file type. Type of ET_* values and the Ehdr.e_type field.""" ++ ET_NONE = 0 ++ ET_REL = 1 ++ ET_EXEC = 2 ++ ET_DYN = 3 ++ ET_CORE = 4 ++ ++class Shn(_OpenIntEnum): ++ """ELF reserved section indices.""" ++ SHN_UNDEF = 0 ++ SHN_BEFORE = 0xff00 ++ SHN_AFTER = 0xff01 ++ SHN_ABS = 0xfff1 ++ SHN_COMMON = 0xfff2 ++ SHN_XINDEX = 0xffff ++ ++class ShnMIPS(enum.Enum): ++ """Supplemental SHN_* constants for EM_MIPS.""" ++ SHN_MIPS_ACOMMON = 0xff00 ++ SHN_MIPS_TEXT = 0xff01 ++ SHN_MIPS_DATA = 0xff02 ++ SHN_MIPS_SCOMMON = 0xff03 ++ SHN_MIPS_SUNDEFINED = 0xff04 ++ ++class ShnPARISC(enum.Enum): ++ """Supplemental SHN_* constants for EM_PARISC.""" ++ SHN_PARISC_ANSI_COMMON = 0xff00 ++ SHN_PARISC_HUGE_COMMON = 0xff01 ++ ++class Sht(_OpenIntEnum): ++ """ELF section types. Type of SHT_* values.""" ++ SHT_NULL = 0 ++ SHT_PROGBITS = 1 ++ SHT_SYMTAB = 2 ++ SHT_STRTAB = 3 ++ SHT_RELA = 4 ++ SHT_HASH = 5 ++ SHT_DYNAMIC = 6 ++ SHT_NOTE = 7 ++ SHT_NOBITS = 8 ++ SHT_REL = 9 ++ SHT_SHLIB = 10 ++ SHT_DYNSYM = 11 ++ SHT_INIT_ARRAY = 14 ++ SHT_FINI_ARRAY = 15 ++ SHT_PREINIT_ARRAY = 16 ++ SHT_GROUP = 17 ++ SHT_SYMTAB_SHNDX = 18 ++ SHT_GNU_ATTRIBUTES = 0x6ffffff5 ++ SHT_GNU_HASH = 0x6ffffff6 ++ SHT_GNU_LIBLIST = 0x6ffffff7 ++ SHT_CHECKSUM = 0x6ffffff8 ++ SHT_SUNW_move = 0x6ffffffa ++ SHT_SUNW_COMDAT = 0x6ffffffb ++ SHT_SUNW_syminfo = 0x6ffffffc ++ SHT_GNU_verdef = 0x6ffffffd ++ SHT_GNU_verneed = 0x6ffffffe ++ SHT_GNU_versym = 0x6fffffff ++ ++class ShtALPHA(enum.Enum): ++ """Supplemental SHT_* constants for EM_ALPHA.""" ++ SHT_ALPHA_DEBUG = 0x70000001 ++ SHT_ALPHA_REGINFO = 0x70000002 ++ ++class ShtARM(enum.Enum): ++ """Supplemental SHT_* constants for EM_ARM.""" ++ SHT_ARM_EXIDX = 0x70000001 ++ SHT_ARM_PREEMPTMAP = 0x70000002 ++ SHT_ARM_ATTRIBUTES = 0x70000003 ++ ++class ShtCSKY(enum.Enum): ++ """Supplemental SHT_* constants for EM_CSKY.""" ++ SHT_CSKY_ATTRIBUTES = 0x70000001 ++ ++class ShtIA_64(enum.Enum): ++ """Supplemental SHT_* constants for EM_IA_64.""" ++ SHT_IA_64_EXT = 0x70000000 ++ SHT_IA_64_UNWIND = 0x70000001 ++ ++class ShtMIPS(enum.Enum): ++ """Supplemental SHT_* constants for EM_MIPS.""" ++ SHT_MIPS_LIBLIST = 0x70000000 ++ SHT_MIPS_MSYM = 0x70000001 ++ SHT_MIPS_CONFLICT = 0x70000002 ++ SHT_MIPS_GPTAB = 0x70000003 ++ SHT_MIPS_UCODE = 0x70000004 ++ SHT_MIPS_DEBUG = 0x70000005 ++ SHT_MIPS_REGINFO = 0x70000006 ++ SHT_MIPS_PACKAGE = 0x70000007 ++ SHT_MIPS_PACKSYM = 0x70000008 ++ SHT_MIPS_RELD = 0x70000009 ++ SHT_MIPS_IFACE = 0x7000000b ++ SHT_MIPS_CONTENT = 0x7000000c ++ SHT_MIPS_OPTIONS = 0x7000000d ++ SHT_MIPS_SHDR = 0x70000010 ++ SHT_MIPS_FDESC = 0x70000011 ++ SHT_MIPS_EXTSYM = 0x70000012 ++ SHT_MIPS_DENSE = 0x70000013 ++ SHT_MIPS_PDESC = 0x70000014 ++ SHT_MIPS_LOCSYM = 0x70000015 ++ SHT_MIPS_AUXSYM = 0x70000016 ++ SHT_MIPS_OPTSYM = 0x70000017 ++ SHT_MIPS_LOCSTR = 0x70000018 ++ SHT_MIPS_LINE = 0x70000019 ++ SHT_MIPS_RFDESC = 0x7000001a ++ SHT_MIPS_DELTASYM = 0x7000001b ++ SHT_MIPS_DELTAINST = 0x7000001c ++ SHT_MIPS_DELTACLASS = 0x7000001d ++ SHT_MIPS_DWARF = 0x7000001e ++ SHT_MIPS_DELTADECL = 0x7000001f ++ SHT_MIPS_SYMBOL_LIB = 0x70000020 ++ SHT_MIPS_EVENTS = 0x70000021 ++ SHT_MIPS_TRANSLATE = 0x70000022 ++ SHT_MIPS_PIXIE = 0x70000023 ++ SHT_MIPS_XLATE = 0x70000024 ++ SHT_MIPS_XLATE_DEBUG = 0x70000025 ++ SHT_MIPS_WHIRL = 0x70000026 ++ SHT_MIPS_EH_REGION = 0x70000027 ++ SHT_MIPS_XLATE_OLD = 0x70000028 ++ SHT_MIPS_PDR_EXCEPTION = 0x70000029 ++ SHT_MIPS_XHASH = 0x7000002b ++ ++class ShtPARISC(enum.Enum): ++ """Supplemental SHT_* constants for EM_PARISC.""" ++ SHT_PARISC_EXT = 0x70000000 ++ SHT_PARISC_UNWIND = 0x70000001 ++ SHT_PARISC_DOC = 0x70000002 ++ ++class Pf(enum.IntFlag): ++ """Program header flags. Type of Phdr.p_flags values.""" ++ PF_X = 1 ++ PF_W = 2 ++ PF_R = 4 ++ ++class PfARM(enum.IntFlag): ++ """Supplemental PF_* flags for EM_ARM.""" ++ PF_ARM_SB = 0x10000000 ++ PF_ARM_PI = 0x20000000 ++ PF_ARM_ABS = 0x40000000 ++ ++class PfPARISC(enum.IntFlag): ++ """Supplemental PF_* flags for EM_PARISC.""" ++ PF_HP_PAGE_SIZE = 0x00100000 ++ PF_HP_FAR_SHARED = 0x00200000 ++ PF_HP_NEAR_SHARED = 0x00400000 ++ PF_HP_CODE = 0x01000000 ++ PF_HP_MODIFY = 0x02000000 ++ PF_HP_LAZYSWAP = 0x04000000 ++ PF_HP_SBP = 0x08000000 ++ ++class PfIA_64(enum.IntFlag): ++ """Supplemental PF_* flags for EM_IA_64.""" ++ PF_IA_64_NORECOV = 0x80000000 ++ ++class PfMIPS(enum.IntFlag): ++ """Supplemental PF_* flags for EM_MIPS.""" ++ PF_MIPS_LOCAL = 0x10000000 ++ ++class Shf(enum.IntFlag): ++ """Section flags. Type of Shdr.sh_type values.""" ++ SHF_WRITE = 1 << 0 ++ SHF_ALLOC = 1 << 1 ++ SHF_EXECINSTR = 1 << 2 ++ SHF_MERGE = 1 << 4 ++ SHF_STRINGS = 1 << 5 ++ SHF_INFO_LINK = 1 << 6 ++ SHF_LINK_ORDER = 1 << 7 ++ SHF_OS_NONCONFORMING = 256 ++ SHF_GROUP = 1 << 9 ++ SHF_TLS = 1 << 10 ++ SHF_COMPRESSED = 1 << 11 ++ SHF_GNU_RETAIN = 1 << 21 ++ SHF_ORDERED = 1 << 30 ++ SHF_EXCLUDE = 1 << 31 ++ ++class ShfALPHA(enum.IntFlag): ++ """Supplemental SHF_* constants for EM_ALPHA.""" ++ SHF_ALPHA_GPREL = 0x10000000 ++ ++class ShfARM(enum.IntFlag): ++ """Supplemental SHF_* constants for EM_ARM.""" ++ SHF_ARM_ENTRYSECT = 0x10000000 ++ SHF_ARM_COMDEF = 0x80000000 ++ ++class ShfIA_64(enum.IntFlag): ++ """Supplemental SHF_* constants for EM_IA_64.""" ++ SHF_IA_64_SHORT = 0x10000000 ++ SHF_IA_64_NORECOV = 0x20000000 ++ ++class ShfMIPS(enum.IntFlag): ++ """Supplemental SHF_* constants for EM_MIPS.""" ++ SHF_MIPS_GPREL = 0x10000000 ++ SHF_MIPS_MERGE = 0x20000000 ++ SHF_MIPS_ADDR = 0x40000000 ++ SHF_MIPS_STRINGS = 0x80000000 ++ SHF_MIPS_NOSTRIP = 0x08000000 ++ SHF_MIPS_LOCAL = 0x04000000 ++ SHF_MIPS_NAMES = 0x02000000 ++ SHF_MIPS_NODUPE = 0x01000000 ++ ++class ShfPARISC(enum.IntFlag): ++ """Supplemental SHF_* constants for EM_PARISC.""" ++ SHF_PARISC_SHORT = 0x20000000 ++ SHF_PARISC_HUGE = 0x40000000 ++ SHF_PARISC_SBP = 0x80000000 ++ ++class Stb(_OpenIntEnum): ++ """ELF symbol binding type.""" ++ STB_LOCAL = 0 ++ STB_GLOBAL = 1 ++ STB_WEAK = 2 ++ STB_GNU_UNIQUE = 10 ++ STB_MIPS_SPLIT_COMMON = 13 ++ ++class Stt(_OpenIntEnum): ++ """ELF symbol type.""" ++ STT_NOTYPE = 0 ++ STT_OBJECT = 1 ++ STT_FUNC = 2 ++ STT_SECTION = 3 ++ STT_FILE = 4 ++ STT_COMMON = 5 ++ STT_TLS = 6 ++ STT_GNU_IFUNC = 10 ++ ++class SttARM(enum.Enum): ++ """Supplemental STT_* constants for EM_ARM.""" ++ STT_ARM_TFUNC = 13 ++ STT_ARM_16BIT = 15 ++ ++class SttPARISC(enum.Enum): ++ """Supplemental STT_* constants for EM_PARISC.""" ++ STT_HP_OPAQUE = 11 ++ STT_HP_STUB = 12 ++ STT_PARISC_MILLICODE = 13 ++ ++class SttSPARC(enum.Enum): ++ """Supplemental STT_* constants for EM_SPARC.""" ++ STT_SPARC_REGISTER = 13 ++ ++class SttX86_64(enum.Enum): ++ """Supplemental STT_* constants for EM_X86_64.""" ++ SHT_X86_64_UNWIND = 0x70000001 ++ ++class Pt(_OpenIntEnum): ++ """ELF program header types. Type of Phdr.p_type.""" ++ PT_NULL = 0 ++ PT_LOAD = 1 ++ PT_DYNAMIC = 2 ++ PT_INTERP = 3 ++ PT_NOTE = 4 ++ PT_SHLIB = 5 ++ PT_PHDR = 6 ++ PT_TLS = 7 ++ PT_NUM = 8 ++ PT_GNU_EH_FRAME = 0x6474e550 ++ PT_GNU_STACK = 0x6474e551 ++ PT_GNU_RELRO = 0x6474e552 ++ PT_GNU_PROPERTY = 0x6474e553 ++ PT_SUNWBSS = 0x6ffffffa ++ PT_SUNWSTACK = 0x6ffffffb ++ ++class PtARM(enum.Enum): ++ """Supplemental PT_* constants for EM_ARM.""" ++ PT_ARM_EXIDX = 0x70000001 ++ ++class PtIA_64(enum.Enum): ++ """Supplemental PT_* constants for EM_IA_64.""" ++ PT_IA_64_HP_OPT_ANOT = 0x60000012 ++ PT_IA_64_HP_HSL_ANOT = 0x60000013 ++ PT_IA_64_HP_STACK = 0x60000014 ++ PT_IA_64_ARCHEXT = 0x70000000 ++ PT_IA_64_UNWIND = 0x70000001 ++ ++class PtMIPS(enum.Enum): ++ """Supplemental PT_* constants for EM_MIPS.""" ++ PT_MIPS_REGINFO = 0x70000000 ++ PT_MIPS_RTPROC = 0x70000001 ++ PT_MIPS_OPTIONS = 0x70000002 ++ PT_MIPS_ABIFLAGS = 0x70000003 ++ ++class PtPARISC(enum.Enum): ++ """Supplemental PT_* constants for EM_PARISC.""" ++ PT_HP_TLS = 0x60000000 ++ PT_HP_CORE_NONE = 0x60000001 ++ PT_HP_CORE_VERSION = 0x60000002 ++ PT_HP_CORE_KERNEL = 0x60000003 ++ PT_HP_CORE_COMM = 0x60000004 ++ PT_HP_CORE_PROC = 0x60000005 ++ PT_HP_CORE_LOADABLE = 0x60000006 ++ PT_HP_CORE_STACK = 0x60000007 ++ PT_HP_CORE_SHM = 0x60000008 ++ PT_HP_CORE_MMF = 0x60000009 ++ PT_HP_PARALLEL = 0x60000010 ++ PT_HP_FASTBIND = 0x60000011 ++ PT_HP_OPT_ANNOT = 0x60000012 ++ PT_HP_HSL_ANNOT = 0x60000013 ++ PT_HP_STACK = 0x60000014 ++ PT_PARISC_ARCHEXT = 0x70000000 ++ PT_PARISC_UNWIND = 0x70000001 ++ ++class Dt(_OpenIntEnum): ++ """ELF dynamic segment tags. Type of Dyn.d_val.""" ++ DT_NULL = 0 ++ DT_NEEDED = 1 ++ DT_PLTRELSZ = 2 ++ DT_PLTGOT = 3 ++ DT_HASH = 4 ++ DT_STRTAB = 5 ++ DT_SYMTAB = 6 ++ DT_RELA = 7 ++ DT_RELASZ = 8 ++ DT_RELAENT = 9 ++ DT_STRSZ = 10 ++ DT_SYMENT = 11 ++ DT_INIT = 12 ++ DT_FINI = 13 ++ DT_SONAME = 14 ++ DT_RPATH = 15 ++ DT_SYMBOLIC = 16 ++ DT_REL = 17 ++ DT_RELSZ = 18 ++ DT_RELENT = 19 ++ DT_PLTREL = 20 ++ DT_DEBUG = 21 ++ DT_TEXTREL = 22 ++ DT_JMPREL = 23 ++ DT_BIND_NOW = 24 ++ DT_INIT_ARRAY = 25 ++ DT_FINI_ARRAY = 26 ++ DT_INIT_ARRAYSZ = 27 ++ DT_FINI_ARRAYSZ = 28 ++ DT_RUNPATH = 29 ++ DT_FLAGS = 30 ++ DT_PREINIT_ARRAY = 32 ++ DT_PREINIT_ARRAYSZ = 33 ++ DT_SYMTAB_SHNDX = 34 ++ DT_GNU_PRELINKED = 0x6ffffdf5 ++ DT_GNU_CONFLICTSZ = 0x6ffffdf6 ++ DT_GNU_LIBLISTSZ = 0x6ffffdf7 ++ DT_CHECKSUM = 0x6ffffdf8 ++ DT_PLTPADSZ = 0x6ffffdf9 ++ DT_MOVEENT = 0x6ffffdfa ++ DT_MOVESZ = 0x6ffffdfb ++ DT_FEATURE_1 = 0x6ffffdfc ++ DT_POSFLAG_1 = 0x6ffffdfd ++ DT_SYMINSZ = 0x6ffffdfe ++ DT_SYMINENT = 0x6ffffdff ++ DT_GNU_HASH = 0x6ffffef5 ++ DT_TLSDESC_PLT = 0x6ffffef6 ++ DT_TLSDESC_GOT = 0x6ffffef7 ++ DT_GNU_CONFLICT = 0x6ffffef8 ++ DT_GNU_LIBLIST = 0x6ffffef9 ++ DT_CONFIG = 0x6ffffefa ++ DT_DEPAUDIT = 0x6ffffefb ++ DT_AUDIT = 0x6ffffefc ++ DT_PLTPAD = 0x6ffffefd ++ DT_MOVETAB = 0x6ffffefe ++ DT_SYMINFO = 0x6ffffeff ++ DT_VERSYM = 0x6ffffff0 ++ DT_RELACOUNT = 0x6ffffff9 ++ DT_RELCOUNT = 0x6ffffffa ++ DT_FLAGS_1 = 0x6ffffffb ++ DT_VERDEF = 0x6ffffffc ++ DT_VERDEFNUM = 0x6ffffffd ++ DT_VERNEED = 0x6ffffffe ++ DT_VERNEEDNUM = 0x6fffffff ++ DT_AUXILIARY = 0x7ffffffd ++ DT_FILTER = 0x7fffffff ++ ++class DtAARCH64(enum.Enum): ++ """Supplemental DT_* constants for EM_AARCH64.""" ++ DT_AARCH64_BTI_PLT = 0x70000001 ++ DT_AARCH64_PAC_PLT = 0x70000003 ++ DT_AARCH64_VARIANT_PCS = 0x70000005 ++ ++class DtALPHA(enum.Enum): ++ """Supplemental DT_* constants for EM_ALPHA.""" ++ DT_ALPHA_PLTRO = 0x70000000 ++ ++class DtALTERA_NIOS2(enum.Enum): ++ """Supplemental DT_* constants for EM_ALTERA_NIOS2.""" ++ DT_NIOS2_GP = 0x70000002 ++ ++class DtIA_64(enum.Enum): ++ """Supplemental DT_* constants for EM_IA_64.""" ++ DT_IA_64_PLT_RESERVE = 0x70000000 ++ ++class DtMIPS(enum.Enum): ++ """Supplemental DT_* constants for EM_MIPS.""" ++ DT_MIPS_RLD_VERSION = 0x70000001 ++ DT_MIPS_TIME_STAMP = 0x70000002 ++ DT_MIPS_ICHECKSUM = 0x70000003 ++ DT_MIPS_IVERSION = 0x70000004 ++ DT_MIPS_FLAGS = 0x70000005 ++ DT_MIPS_BASE_ADDRESS = 0x70000006 ++ DT_MIPS_MSYM = 0x70000007 ++ DT_MIPS_CONFLICT = 0x70000008 ++ DT_MIPS_LIBLIST = 0x70000009 ++ DT_MIPS_LOCAL_GOTNO = 0x7000000a ++ DT_MIPS_CONFLICTNO = 0x7000000b ++ DT_MIPS_LIBLISTNO = 0x70000010 ++ DT_MIPS_SYMTABNO = 0x70000011 ++ DT_MIPS_UNREFEXTNO = 0x70000012 ++ DT_MIPS_GOTSYM = 0x70000013 ++ DT_MIPS_HIPAGENO = 0x70000014 ++ DT_MIPS_RLD_MAP = 0x70000016 ++ DT_MIPS_DELTA_CLASS = 0x70000017 ++ DT_MIPS_DELTA_CLASS_NO = 0x70000018 ++ DT_MIPS_DELTA_INSTANCE = 0x70000019 ++ DT_MIPS_DELTA_INSTANCE_NO = 0x7000001a ++ DT_MIPS_DELTA_RELOC = 0x7000001b ++ DT_MIPS_DELTA_RELOC_NO = 0x7000001c ++ DT_MIPS_DELTA_SYM = 0x7000001d ++ DT_MIPS_DELTA_SYM_NO = 0x7000001e ++ DT_MIPS_DELTA_CLASSSYM = 0x70000020 ++ DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021 ++ DT_MIPS_CXX_FLAGS = 0x70000022 ++ DT_MIPS_PIXIE_INIT = 0x70000023 ++ DT_MIPS_SYMBOL_LIB = 0x70000024 ++ DT_MIPS_LOCALPAGE_GOTIDX = 0x70000025 ++ DT_MIPS_LOCAL_GOTIDX = 0x70000026 ++ DT_MIPS_HIDDEN_GOTIDX = 0x70000027 ++ DT_MIPS_PROTECTED_GOTIDX = 0x70000028 ++ DT_MIPS_OPTIONS = 0x70000029 ++ DT_MIPS_INTERFACE = 0x7000002a ++ DT_MIPS_DYNSTR_ALIGN = 0x7000002b ++ DT_MIPS_INTERFACE_SIZE = 0x7000002c ++ DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002d ++ DT_MIPS_PERF_SUFFIX = 0x7000002e ++ DT_MIPS_COMPACT_SIZE = 0x7000002f ++ DT_MIPS_GP_VALUE = 0x70000030 ++ DT_MIPS_AUX_DYNAMIC = 0x70000031 ++ DT_MIPS_PLTGOT = 0x70000032 ++ DT_MIPS_RWPLT = 0x70000034 ++ DT_MIPS_RLD_MAP_REL = 0x70000035 ++ DT_MIPS_XHASH = 0x70000036 ++ ++class DtPPC(enum.Enum): ++ """Supplemental DT_* constants for EM_PPC.""" ++ DT_PPC_GOT = 0x70000000 ++ DT_PPC_OPT = 0x70000001 ++ ++class DtPPC64(enum.Enum): ++ """Supplemental DT_* constants for EM_PPC64.""" ++ DT_PPC64_GLINK = 0x70000000 ++ DT_PPC64_OPD = 0x70000001 ++ DT_PPC64_OPDSZ = 0x70000002 ++ DT_PPC64_OPT = 0x70000003 ++ ++class DtSPARC(enum.Enum): ++ """Supplemental DT_* constants for EM_SPARC.""" ++ DT_SPARC_REGISTER = 0x70000001 ++ ++class StInfo: ++ """ELF symbol binding and type. Type of the Sym.st_info field.""" ++ def __init__(self, arg0, arg1=None): ++ if isinstance(arg0, int) and arg1 is None: ++ self.bind = Stb(arg0 >> 4) ++ self.type = Stt(arg0 & 15) ++ else: ++ self.bind = Stb(arg0) ++ self.type = Stt(arg1) ++ ++ def value(self): ++ """Returns the raw value for the bind/type combination.""" ++ return (self.bind.value() << 4) | (self.type.value()) ++ ++# Type in an ELF file. Used for deserialization. ++_Layout = collections.namedtuple('_Layout', 'unpack size') ++ ++def _define_layouts(baseclass: type, layout32: str, layout64: str, ++ types=None, fields32=None): ++ """Assign variants dict to baseclass. ++ ++ The variants dict is indexed by (ElfClass, ElfData) pairs, and its ++ values are _Layout instances. ++ ++ """ ++ struct32 = struct.Struct(layout32) ++ struct64 = struct.Struct(layout64) ++ ++ # Check that the struct formats yield the right number of components. ++ for s in (struct32, struct64): ++ example = s.unpack(b' ' * s.size) ++ if len(example) != len(baseclass._fields): ++ raise ValueError('{!r} yields wrong field count: {} != {}'.format( ++ s.format, len(example), len(baseclass._fields))) ++ ++ # Check that field names in types are correct. ++ if types is None: ++ types = () ++ for n in types: ++ if n not in baseclass._fields: ++ raise ValueError('{} does not have field {!r}'.format( ++ baseclass.__name__, n)) ++ ++ if fields32 is not None \ ++ and set(fields32) != set(baseclass._fields): ++ raise ValueError('{!r} is not a permutation of the fields {!r}'.format( ++ fields32, baseclass._fields)) ++ ++ def unique_name(name, used_names = (set((baseclass.__name__,)) ++ | set(baseclass._fields) ++ | {n.__name__ ++ for n in (types or {}).values()})): ++ """Find a name that is not used for a class or field name.""" ++ candidate = name ++ n = 0 ++ while candidate in used_names: ++ n += 1 ++ candidate = '{}{}'.format(name, n) ++ used_names.add(candidate) ++ return candidate ++ ++ blob_name = unique_name('blob') ++ struct_unpack_name = unique_name('struct_unpack') ++ comps_name = unique_name('comps') ++ ++ layouts = {} ++ for (bits, elfclass, layout, fields) in ( ++ (32, ElfClass.ELFCLASS32, layout32, fields32), ++ (64, ElfClass.ELFCLASS64, layout64, None), ++ ): ++ for (elfdata, structprefix, funcsuffix) in ( ++ (ElfData.ELFDATA2LSB, '<', 'LE'), ++ (ElfData.ELFDATA2MSB, '>', 'BE'), ++ ): ++ env = { ++ baseclass.__name__: baseclass, ++ struct_unpack_name: struct.unpack, ++ } ++ ++ # Add the type converters. ++ if types: ++ for cls in types.values(): ++ env[cls.__name__] = cls ++ ++ funcname = ''.join( ++ ('unpack_', baseclass.__name__, str(bits), funcsuffix)) ++ ++ code = ''' ++def {funcname}({blob_name}): ++'''.format(funcname=funcname, blob_name=blob_name) ++ ++ indent = ' ' * 4 ++ unpack_call = '{}({!r}, {})'.format( ++ struct_unpack_name, structprefix + layout, blob_name) ++ field_names = ', '.join(baseclass._fields) ++ if types is None and fields is None: ++ code += '{}return {}({})\n'.format( ++ indent, baseclass.__name__, unpack_call) ++ else: ++ # Destructuring tuple assignment. ++ if fields is None: ++ code += '{}{} = {}\n'.format( ++ indent, field_names, unpack_call) ++ else: ++ # Use custom field order. ++ code += '{}{} = {}\n'.format( ++ indent, ', '.join(fields), unpack_call) ++ ++ # Perform the type conversions. ++ for n in baseclass._fields: ++ if n in types: ++ code += '{}{} = {}({})\n'.format( ++ indent, n, types[n].__name__, n) ++ # Create the named tuple. ++ code += '{}return {}({})\n'.format( ++ indent, baseclass.__name__, field_names) ++ ++ exec(code, env) ++ layouts[(elfclass, elfdata)] = _Layout( ++ env[funcname], struct.calcsize(layout)) ++ baseclass.layouts = layouts ++ ++ ++# Corresponds to EI_* indices into Elf*_Ehdr.e_indent. ++class Ident(collections.namedtuple('Ident', ++ 'ei_mag ei_class ei_data ei_version ei_osabi ei_abiversion ei_pad')): ++ ++ def __new__(cls, *args): ++ """Construct an object from a blob or its constituent fields.""" ++ if len(args) == 1: ++ return cls.unpack(args[0]) ++ return cls.__base__.__new__(cls, *args) ++ ++ @staticmethod ++ def unpack(blob: memoryview) -> 'Ident': ++ """Parse raws data into a tuple.""" ++ ei_mag, ei_class, ei_data, ei_version, ei_osabi, ei_abiversion, \ ++ ei_pad = struct.unpack('4s5B7s', blob) ++ return Ident(ei_mag, ElfClass(ei_class), ElfData(ei_data), ++ ei_version, ei_osabi, ei_abiversion, ei_pad) ++ size = 16 ++ ++# Corresponds to Elf32_Ehdr and Elf64_Ehdr. ++Ehdr = collections.namedtuple('Ehdr', ++ 'e_ident e_type e_machine e_version e_entry e_phoff e_shoff e_flags' ++ + ' e_ehsize e_phentsize e_phnum e_shentsize e_shnum e_shstrndx') ++_define_layouts(Ehdr, ++ layout32='16s2H5I6H', ++ layout64='16s2HI3QI6H', ++ types=dict(e_ident=Ident, ++ e_machine=Machine, ++ e_type=Et, ++ e_shstrndx=Shn)) ++ ++# Corresponds to Elf32_Phdr and Elf64_Pdhr. Order follows the latter. ++Phdr = collections.namedtuple('Phdr', ++ 'p_type p_flags p_offset p_vaddr p_paddr p_filesz p_memsz p_align') ++_define_layouts(Phdr, ++ layout32='8I', ++ fields32=('p_type', 'p_offset', 'p_vaddr', 'p_paddr', ++ 'p_filesz', 'p_memsz', 'p_flags', 'p_align'), ++ layout64='2I6Q', ++ types=dict(p_type=Pt, p_flags=Pf)) ++ ++ ++# Corresponds to Elf32_Shdr and Elf64_Shdr. ++class Shdr(collections.namedtuple('Shdr', ++ 'sh_name sh_type sh_flags sh_addr sh_offset sh_size sh_link sh_info' ++ + ' sh_addralign sh_entsize')): ++ def resolve(self, strtab: 'StringTable') -> 'Shdr': ++ """Resolve sh_name using a string table.""" ++ return self.__class__(strtab.get(self[0]), *self[1:]) ++_define_layouts(Shdr, ++ layout32='10I', ++ layout64='2I4Q2I2Q', ++ types=dict(sh_type=Sht, ++ sh_flags=Shf, ++ sh_link=Shn)) ++ ++# Corresponds to Elf32_Dyn and Elf64_Dyn. The nesting through the ++# d_un union is skipped, and d_ptr is missing (its representation in ++# Python would be identical to d_val). ++Dyn = collections.namedtuple('Dyn', 'd_tag d_val') ++_define_layouts(Dyn, ++ layout32='2i', ++ layout64='2q', ++ types=dict(d_tag=Dt)) ++ ++# Corresponds to Elf32_Sym and Elf64_Sym. ++class Sym(collections.namedtuple('Sym', ++ 'st_name st_info st_other st_shndx st_value st_size')): ++ def resolve(self, strtab: 'StringTable') -> 'Sym': ++ """Resolve st_name using a string table.""" ++ return self.__class__(strtab.get(self[0]), *self[1:]) ++_define_layouts(Sym, ++ layout32='3I2BH', ++ layout64='I2BH2Q', ++ fields32=('st_name', 'st_value', 'st_size', 'st_info', ++ 'st_other', 'st_shndx'), ++ types=dict(st_shndx=Shn, ++ st_info=StInfo)) ++ ++# Corresponds to Elf32_Rel and Elf64_Rel. ++Rel = collections.namedtuple('Rel', 'r_offset r_info') ++_define_layouts(Rel, ++ layout32='2I', ++ layout64='2Q') ++ ++# Corresponds to Elf32_Rel and Elf64_Rel. ++Rela = collections.namedtuple('Rela', 'r_offset r_info r_addend') ++_define_layouts(Rela, ++ layout32='3I', ++ layout64='3Q') ++ ++class StringTable: ++ """ELF string table.""" ++ def __init__(self, blob): ++ """Create a new string table backed by the data in the blob. ++ ++ blob: a memoryview-like object ++ ++ """ ++ self.blob = blob ++ ++ def get(self, index) -> bytes: ++ """Returns the null-terminated byte string at the index.""" ++ blob = self.blob ++ endindex = index ++ while True: ++ if blob[endindex] == 0: ++ return bytes(blob[index:endindex]) ++ endindex += 1 ++ ++class Image: ++ """ELF image parser.""" ++ def __init__(self, image): ++ """Create an ELF image from binary image data. ++ ++ image: a memoryview-like object that supports efficient range ++ subscripting. ++ ++ """ ++ self.image = image ++ ident = self.read(Ident, 0) ++ classdata = (ident.ei_class, ident.ei_data) ++ # Set self.Ehdr etc. to the subtypes with the right parsers. ++ for typ in (Ehdr, Phdr, Shdr, Dyn, Sym, Rel, Rela): ++ setattr(self, typ.__name__, typ.layouts.get(classdata, None)) ++ ++ if self.Ehdr is not None: ++ self.ehdr = self.read(self.Ehdr, 0) ++ self._shdr_num = self._compute_shdr_num() ++ else: ++ self.ehdr = None ++ self._shdr_num = 0 ++ ++ self._section = {} ++ self._stringtab = {} ++ ++ if self._shdr_num > 0: ++ self._shdr_strtab = self._find_shdr_strtab() ++ else: ++ self._shdr_strtab = None ++ ++ @staticmethod ++ def readfile(path: str) -> 'Image': ++ """Reads the ELF file at the specified path.""" ++ with open(path, 'rb') as inp: ++ return Image(memoryview(inp.read())) ++ ++ def _compute_shdr_num(self) -> int: ++ """Computes the actual number of section headers.""" ++ shnum = self.ehdr.e_shnum ++ if shnum == 0: ++ if self.ehdr.e_shoff == 0 or self.ehdr.e_shentsize == 0: ++ # No section headers. ++ return 0 ++ # Otherwise the extension mechanism is used (which may be ++ # needed because e_shnum is just 16 bits). ++ return self.read(self.Shdr, self.ehdr.e_shoff).sh_size ++ return shnum ++ ++ def _find_shdr_strtab(self) -> StringTable: ++ """Finds the section header string table (maybe via extensions).""" ++ shstrndx = self.ehdr.e_shstrndx ++ if shstrndx == Shn.SHN_XINDEX: ++ shstrndx = self.read(self.Shdr, self.ehdr.e_shoff).sh_link ++ return self._find_stringtab(shstrndx) ++ ++ def read(self, typ: type, offset:int ): ++ """Reads an object at a specific offset. ++ ++ The type must have been enhanced using _define_variants. ++ ++ """ ++ return typ.unpack(self.image[offset: offset + typ.size]) ++ ++ def phdrs(self) -> Phdr: ++ """Generator iterating over the program headers.""" ++ if self.ehdr is None: ++ return ++ size = self.ehdr.e_phentsize ++ if size != self.Phdr.size: ++ raise ValueError('Unexpected Phdr size in ELF header: {} != {}' ++ .format(size, self.Phdr.size)) ++ ++ offset = self.ehdr.e_phoff ++ for _ in range(self.ehdr.e_phnum): ++ yield self.read(self.Phdr, offset) ++ offset += size ++ ++ def shdrs(self, resolve: bool=True) -> Shdr: ++ """Generator iterating over the section headers. ++ ++ If resolve, section names are automatically translated ++ using the section header string table. ++ ++ """ ++ if self._shdr_num == 0: ++ return ++ ++ size = self.ehdr.e_shentsize ++ if size != self.Shdr.size: ++ raise ValueError('Unexpected Shdr size in ELF header: {} != {}' ++ .format(size, self.Shdr.size)) ++ ++ offset = self.ehdr.e_shoff ++ for _ in range(self._shdr_num): ++ shdr = self.read(self.Shdr, offset) ++ if resolve: ++ shdr = shdr.resolve(self._shdr_strtab) ++ yield shdr ++ offset += size ++ ++ def dynamic(self) -> Dyn: ++ """Generator iterating over the dynamic segment.""" ++ for phdr in self.phdrs(): ++ if phdr.p_type == Pt.PT_DYNAMIC: ++ # Pick the first dynamic segment, like the loader. ++ if phdr.p_filesz == 0: ++ # Probably separated debuginfo. ++ return ++ offset = phdr.p_offset ++ end = offset + phdr.p_memsz ++ size = self.Dyn.size ++ while True: ++ next_offset = offset + size ++ if next_offset > end: ++ raise ValueError( ++ 'Dynamic segment size {} is not a multiple of Dyn size {}'.format( ++ phdr.p_memsz, size)) ++ yield self.read(self.Dyn, offset) ++ if next_offset == end: ++ return ++ offset = next_offset ++ ++ def syms(self, shdr: Shdr, resolve: bool=True) -> Sym: ++ """A generator iterating over a symbol table. ++ ++ If resolve, symbol names are automatically translated using ++ the string table for the symbol table. ++ ++ """ ++ assert shdr.sh_type == Sht.SHT_SYMTAB ++ size = shdr.sh_entsize ++ if size != self.Sym.size: ++ raise ValueError('Invalid symbol table entry size {}'.format(size)) ++ offset = shdr.sh_offset ++ end = shdr.sh_offset + shdr.sh_size ++ if resolve: ++ strtab = self._find_stringtab(shdr.sh_link) ++ while offset < end: ++ sym = self.read(self.Sym, offset) ++ if resolve: ++ sym = sym.resolve(strtab) ++ yield sym ++ offset += size ++ if offset != end: ++ raise ValueError('Symbol table is not a multiple of entry size') ++ ++ def lookup_string(self, strtab_index: int, strtab_offset: int) -> bytes: ++ """Looks up a string in a string table identified by its link index.""" ++ try: ++ strtab = self._stringtab[strtab_index] ++ except KeyError: ++ strtab = self._find_stringtab(strtab_index) ++ return strtab.get(strtab_offset) ++ ++ def find_section(self, shndx: Shn) -> Shdr: ++ """Returns the section header for the indexed section. ++ ++ The section name is not resolved. ++ """ ++ try: ++ return self._section[shndx] ++ except KeyError: ++ pass ++ if shndx in Shn: ++ raise ValueError('Reserved section index {}'.format(shndx)) ++ idx = shndx.value ++ if idx < 0 or idx > self._shdr_num: ++ raise ValueError('Section index {} out of range [0, {})'.format( ++ idx, self._shdr_num)) ++ shdr = self.read( ++ self.Shdr, self.ehdr.e_shoff + idx * self.Shdr.size) ++ self._section[shndx] = shdr ++ return shdr ++ ++ def _find_stringtab(self, sh_link: int) -> StringTable: ++ if sh_link in self._stringtab: ++ return self._stringtab ++ if sh_link < 0 or sh_link >= self._shdr_num: ++ raise ValueError('Section index {} out of range [0, {})'.format( ++ sh_link, self._shdr_num)) ++ shdr = self.read( ++ self.Shdr, self.ehdr.e_shoff + sh_link * self.Shdr.size) ++ if shdr.sh_type != Sht.SHT_STRTAB: ++ raise ValueError( ++ 'Section {} is not a string table: {}'.format( ++ sh_link, shdr.sh_type)) ++ strtab = StringTable( ++ self.image[shdr.sh_offset:shdr.sh_offset + shdr.sh_size]) ++ # This could retrain essentially arbitrary amounts of data, ++ # but caching string tables seems important for performance. ++ self._stringtab[sh_link] = strtab ++ return strtab ++ ++ ++__all__ = [name for name in dir() if name[0].isupper()] diff --git a/SOURCES/glibc-upstream-2.34-168.patch b/SOURCES/glibc-upstream-2.34-168.patch new file mode 100644 index 0000000..49e07b7 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-168.patch @@ -0,0 +1,407 @@ +commit f0c71b34f96c816292c49122d50da3a511b67bf2 +Author: Florian Weimer +Date: Mon Apr 11 11:30:31 2022 +0200 + + Default to --with-default-link=no (bug 25812) + + This is necessary to place the libio vtables into the RELRO segment. + New tests elf/tst-relro-ldso and elf/tst-relro-libc are added to + verify that this is what actually happens. + + The new tests fail on ia64 due to lack of (default) RELRO support + inbutils, so they are XFAILed there. + + (cherry picked from commit 198abcbb94618730dae1b3f4393efaa49e0ec8c7) + +diff --git a/INSTALL b/INSTALL +index d8d4e9f155f56616..60d01568d77645c7 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -90,6 +90,12 @@ 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-default-link=FLAG' ++ With '--with-default-link=yes', the build system does not use a ++ custom linker script for linking shared objects. The default for ++ FLAG is the opposite, 'no', because the custom linker script is ++ needed for full RELRO protection. ++ + '--with-nonshared-cflags=CFLAGS' + Use additional compiler flags CFLAGS to build the parts of the + library which are always statically linked into applications and +diff --git a/configure b/configure +index 03f4e59e754b5463..34c64f8de44e3086 100755 +--- a/configure ++++ b/configure +@@ -3373,7 +3373,7 @@ fi + if test "${with_default_link+set}" = set; then : + withval=$with_default_link; use_default_link=$withval + else +- use_default_link=default ++ use_default_link=no + fi + + +@@ -6085,69 +6085,6 @@ fi + $as_echo "$libc_cv_hashstyle" >&6; } + + +-# The linker's default -shared behavior is good enough if it +-# does these things that our custom linker scripts ensure that +-# all allocated NOTE sections come first. +-if test "$use_default_link" = default; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sufficient default -shared layout" >&5 +-$as_echo_n "checking for sufficient default -shared layout... " >&6; } +-if ${libc_cv_use_default_link+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- libc_cv_use_default_link=no +- cat > conftest.s <<\EOF +- .section .note.a,"a",%note +- .balign 4 +- .long 4,4,9 +- .string "GNU" +- .string "foo" +- .section .note.b,"a",%note +- .balign 4 +- .long 4,4,9 +- .string "GNU" +- .string "bar" +-EOF +- if { ac_try=' ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&5' +- { { 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; }; } && +- ac_try=`$READELF -S conftest.so | sed -n \ +- '${x;p;} +- s/^ *\[ *[1-9][0-9]*\] *\([^ ][^ ]*\) *\([^ ][^ ]*\) .*$/\2 \1/ +- t a +- b +- : a +- H'` +- then +- libc_seen_a=no libc_seen_b=no +- set -- $ac_try +- while test $# -ge 2 -a "$1" = NOTE; do +- case "$2" in +- .note.a) libc_seen_a=yes ;; +- .note.b) libc_seen_b=yes ;; +- esac +- shift 2 +- done +- case "$libc_seen_a$libc_seen_b" in +- yesyes) +- libc_cv_use_default_link=yes +- ;; +- *) +- echo >&5 "\ +-$libc_seen_a$libc_seen_b from: +-$ac_try" +- ;; +- esac +- fi +- rm -f conftest* +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_use_default_link" >&5 +-$as_echo "$libc_cv_use_default_link" >&6; } +- use_default_link=$libc_cv_use_default_link +-fi +- + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_DAT reloc" >&5 + $as_echo_n "checking for GLOB_DAT reloc... " >&6; } + if ${libc_cv_has_glob_dat+:} false; then : +diff --git a/configure.ac b/configure.ac +index eb9431875fae1b0e..2c69af0807266e7e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -153,7 +153,7 @@ AC_ARG_WITH([default-link], + AS_HELP_STRING([--with-default-link], + [do not use explicit linker scripts]), + [use_default_link=$withval], +- [use_default_link=default]) ++ [use_default_link=no]) + + dnl Additional build flags injection. + AC_ARG_WITH([nonshared-cflags], +@@ -1378,59 +1378,6 @@ fi + rm -f conftest*]) + AC_SUBST(libc_cv_hashstyle) + +-# The linker's default -shared behavior is good enough if it +-# does these things that our custom linker scripts ensure that +-# all allocated NOTE sections come first. +-if test "$use_default_link" = default; then +- AC_CACHE_CHECK([for sufficient default -shared layout], +- libc_cv_use_default_link, [dnl +- libc_cv_use_default_link=no +- cat > conftest.s <<\EOF +- .section .note.a,"a",%note +- .balign 4 +- .long 4,4,9 +- .string "GNU" +- .string "foo" +- .section .note.b,"a",%note +- .balign 4 +- .long 4,4,9 +- .string "GNU" +- .string "bar" +-EOF +- if AC_TRY_COMMAND([dnl +- ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&AS_MESSAGE_LOG_FD]) && +- ac_try=`$READELF -S conftest.so | sed -n \ +- ['${x;p;} +- s/^ *\[ *[1-9][0-9]*\] *\([^ ][^ ]*\) *\([^ ][^ ]*\) .*$/\2 \1/ +- t a +- b +- : a +- H']` +- then +- libc_seen_a=no libc_seen_b=no +- set -- $ac_try +- while test $# -ge 2 -a "$1" = NOTE; do +- case "$2" in +- .note.a) libc_seen_a=yes ;; +- .note.b) libc_seen_b=yes ;; +- esac +- shift 2 +- done +- case "$libc_seen_a$libc_seen_b" in +- yesyes) +- libc_cv_use_default_link=yes +- ;; +- *) +- echo >&AS_MESSAGE_LOG_FD "\ +-$libc_seen_a$libc_seen_b from: +-$ac_try" +- ;; +- esac +- fi +- rm -f conftest*]) +- use_default_link=$libc_cv_use_default_link +-fi +- + AC_CACHE_CHECK(for GLOB_DAT reloc, + libc_cv_has_glob_dat, [dnl + cat > conftest.c < $@ 2>&1; $(evaluate-test) ++# The optional symbols are present in libc only if the architecture has ++# the GLIBC_2.0 symbol set in libc. ++$(objpfx)tst-relro-libc.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \ ++ $(common-objpfx)libc.so ++ $(PYTHON) tst-relro-symbols.py $(common-objpfx)libc.so \ ++ --required=_IO_cookie_jumps \ ++ --required=_IO_file_jumps \ ++ --required=_IO_file_jumps_maybe_mmap \ ++ --required=_IO_file_jumps_mmap \ ++ --required=_IO_helper_jumps \ ++ --required=_IO_mem_jumps \ ++ --required=_IO_obstack_jumps \ ++ --required=_IO_proc_jumps \ ++ --required=_IO_str_chk_jumps \ ++ --required=_IO_str_jumps \ ++ --required=_IO_strn_jumps \ ++ --required=_IO_wfile_jumps \ ++ --required=_IO_wfile_jumps_maybe_mmap \ ++ --required=_IO_wfile_jumps_mmap \ ++ --required=_IO_wmem_jumps \ ++ --required=_IO_wstr_jumps \ ++ --required=_IO_wstrn_jumps \ ++ --optional=_IO_old_cookie_jumps \ ++ --optional=_IO_old_file_jumps \ ++ --optional=_IO_old_proc_jumps \ ++ > $@ 2>&1; $(evaluate-test) ++ + tests += $(tests-execstack-$(have-z-execstack)) + ifeq ($(run-built-tests),yes) + tests-special += \ +diff --git a/elf/tst-relro-symbols.py b/elf/tst-relro-symbols.py +new file mode 100644 +index 0000000000000000..368ea3349f86bd81 +--- /dev/null ++++ b/elf/tst-relro-symbols.py +@@ -0,0 +1,137 @@ ++#!/usr/bin/python3 ++# Verify that certain symbols are covered by RELRO. ++# Copyright (C) 2022 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++"""Analyze a (shared) object to verify that certain symbols are ++present and covered by the PT_GNU_RELRO segment. ++ ++""" ++ ++import argparse ++import os.path ++import sys ++ ++# Make available glibc Python modules. ++sys.path.append(os.path.join( ++ os.path.dirname(os.path.realpath(__file__)), os.path.pardir, 'scripts')) ++ ++import glibcelf ++ ++def find_relro(path: str, img: glibcelf.Image) -> (int, int): ++ """Discover the address range of the PT_GNU_RELRO segment.""" ++ for phdr in img.phdrs(): ++ if phdr.p_type == glibcelf.Pt.PT_GNU_RELRO: ++ # The computation is not entirely accurate because ++ # _dl_protect_relro in elf/dl-reloc.c rounds both the ++ # start end and downwards using the run-time page size. ++ return phdr.p_vaddr, phdr.p_vaddr + phdr.p_memsz ++ sys.stdout.write('{}: error: no PT_GNU_RELRO segment\n'.format(path)) ++ sys.exit(1) ++ ++def check_in_relro(kind, relro_begin, relro_end, name, start, size, error): ++ """Check if a section or symbol falls within in the RELRO segment.""" ++ end = start + size - 1 ++ if not (relro_begin <= start < end < relro_end): ++ error( ++ '{} {!r} of size {} at 0x{:x} is not in RELRO range [0x{:x}, 0x{:x})'.format( ++ kind, name.decode('UTF-8'), start, size, ++ relro_begin, relro_end)) ++ ++def get_parser(): ++ """Return an argument parser for this script.""" ++ parser = argparse.ArgumentParser(description=__doc__) ++ parser.add_argument('object', help='path to object file to check') ++ parser.add_argument('--required', metavar='NAME', default=(), ++ help='required symbol names', nargs='*') ++ parser.add_argument('--optional', metavar='NAME', default=(), ++ help='required symbol names', nargs='*') ++ return parser ++ ++def main(argv): ++ """The main entry point.""" ++ parser = get_parser() ++ opts = parser.parse_args(argv) ++ img = glibcelf.Image.readfile(opts.object) ++ ++ required_symbols = frozenset([sym.encode('UTF-8') ++ for sym in opts.required]) ++ optional_symbols = frozenset([sym.encode('UTF-8') ++ for sym in opts.optional]) ++ check_symbols = required_symbols | optional_symbols ++ ++ # Tracks the symbols in check_symbols that have been found. ++ symbols_found = set() ++ ++ # Discover the extent of the RELRO segment. ++ relro_begin, relro_end = find_relro(opts.object, img) ++ symbol_table_found = False ++ ++ errors = False ++ def error(msg: str) -> None: ++ """Record an error condition and write a message to standard output.""" ++ nonlocal errors ++ errors = True ++ sys.stdout.write('{}: error: {}\n'.format(opts.object, msg)) ++ ++ # Iterate over section headers to find the symbol table. ++ for shdr in img.shdrs(): ++ if shdr.sh_type == glibcelf.Sht.SHT_SYMTAB: ++ symbol_table_found = True ++ for sym in img.syms(shdr): ++ if sym.st_name in check_symbols: ++ symbols_found.add(sym.st_name) ++ ++ # Validate symbol type, section, and size. ++ if sym.st_info.type != glibcelf.Stt.STT_OBJECT: ++ error('symbol {!r} has wrong type {}'.format( ++ sym.st_name.decode('UTF-8'), sym.st_info.type)) ++ if sym.st_shndx in glibcelf.Shn: ++ error('symbol {!r} has reserved section {}'.format( ++ sym.st_name.decode('UTF-8'), sym.st_shndx)) ++ continue ++ if sym.st_size == 0: ++ error('symbol {!r} has size zero'.format( ++ sym.st_name.decode('UTF-8'))) ++ continue ++ ++ check_in_relro('symbol', relro_begin, relro_end, ++ sym.st_name, sym.st_value, sym.st_size, ++ error) ++ continue # SHT_SYMTAB ++ if shdr.sh_name == b'.data.rel.ro' \ ++ or shdr.sh_name.startswith(b'.data.rel.ro.'): ++ check_in_relro('section', relro_begin, relro_end, ++ shdr.sh_name, shdr.sh_addr, shdr.sh_size, ++ error) ++ continue ++ ++ if required_symbols - symbols_found: ++ for sym in sorted(required_symbols - symbols_found): ++ error('symbol {!r} not found'.format(sym.decode('UTF-8'))) ++ ++ if errors: ++ sys.exit(1) ++ ++ if not symbol_table_found: ++ sys.stdout.write( ++ '{}: warning: no symbol table found (stripped object)\n'.format( ++ opts.object)) ++ sys.exit(77) ++ ++if __name__ == '__main__': ++ main(sys.argv[1:]) +diff --git a/manual/install.texi b/manual/install.texi +index 816b77a0a25a88a7..36a5af62bc5722b0 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -117,6 +117,12 @@ 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-default-link=@var{FLAG} ++With @code{--with-default-link=yes}, the build system does not use a ++custom linker script for linking shared objects. The default for ++@var{FLAG} is the opposite, @samp{no}, because the custom linker script ++is needed for full RELRO protection. ++ + @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 +diff --git a/sysdeps/unix/sysv/linux/ia64/Makefile b/sysdeps/unix/sysv/linux/ia64/Makefile +index da85ba43e2d0ddef..c5cc41b3677d4a2a 100644 +--- a/sysdeps/unix/sysv/linux/ia64/Makefile ++++ b/sysdeps/unix/sysv/linux/ia64/Makefile +@@ -1,3 +1,9 @@ ++ifeq ($(subdir),elf) ++# ia64 does not support PT_GNU_RELRO. ++test-xfail-tst-relro-ldso = yes ++test-xfail-tst-relro-libc = yes ++endif ++ + ifeq ($(subdir),misc) + sysdep_headers += sys/rse.h + endif diff --git a/SOURCES/glibc-upstream-2.34-169.patch b/SOURCES/glibc-upstream-2.34-169.patch new file mode 100644 index 0000000..63cb452 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-169.patch @@ -0,0 +1,87 @@ +commit ca0faa140ff8cebe4c041d935f0f5eb480873d99 +Author: Joan Bruguera +Date: Mon Apr 11 19:49:56 2022 +0200 + + misc: Fix rare fortify crash on wchar funcs. [BZ 29030] + + If `__glibc_objsize (__o) == (size_t) -1` (i.e. `__o` is unknown size), fortify + checks should pass, and `__whatever_alias` should be called. + + Previously, `__glibc_objsize (__o) == (size_t) -1` was explicitly checked, but + on commit a643f60c53876b, this was moved into `__glibc_safe_or_unknown_len`. + + A comment says the -1 case should work as: "The -1 check is redundant because + since it implies that __glibc_safe_len_cond is true.". But this fails when: + * `__s > 1` + * `__osz == -1` (i.e. unknown size at compile time) + * `__l` is big enough + * `__l * __s <= __osz` can be folded to a constant + (I only found this to be true for `mbsrtowcs` and other functions in wchar2.h) + + In this case `__l * __s <= __osz` is false, and `__whatever_chk_warn` will be + called by `__glibc_fortify` or `__glibc_fortify_n` and crash the program. + + This commit adds the explicit `__osz == -1` check again. + moc crashes on startup due to this, see: https://bugs.archlinux.org/task/74041 + + Minimal test case (test.c): + #include + + int main (void) + { + const char *hw = "HelloWorld"; + mbsrtowcs (NULL, &hw, (size_t)-1, NULL); + return 0; + } + + Build with: + gcc -O2 -Wp,-D_FORTIFY_SOURCE=2 test.c -o test && ./test + + Output: + *** buffer overflow detected ***: terminated + + Fixes: BZ #29030 + Signed-off-by: Joan Bruguera + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 33e03f9cd2be4f2cd62f93fda539cc07d9c8130e) + +diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c +index 8b5902423cf0ad88..fb02452f5993c594 100644 +--- a/debug/tst-fortify.c ++++ b/debug/tst-fortify.c +@@ -1505,6 +1505,11 @@ do_test (void) + CHK_FAIL_END + #endif + ++ /* Bug 29030 regresion check */ ++ cp = "HelloWorld"; ++ if (mbsrtowcs (NULL, &cp, (size_t)-1, &s) != 10) ++ FAIL (); ++ + cp = "A"; + if (mbstowcs (wenough, cp, 10) != 1 + || wcscmp (wenough, L"A") != 0) +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 515fb681a0547217..b36013b9a6b4d9c3 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -161,13 +161,13 @@ + || (__builtin_constant_p (__l) && (__l) > 0)) + + /* Length is known to be safe at compile time if the __L * __S <= __OBJSZ +- condition can be folded to a constant and if it is true. The -1 check is +- redundant because since it implies that __glibc_safe_len_cond is true. */ ++ condition can be folded to a constant and if it is true, or unknown (-1) */ + #define __glibc_safe_or_unknown_len(__l, __s, __osz) \ +- (__glibc_unsigned_or_positive (__l) \ +- && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ +- __s, __osz)) \ +- && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) ++ ((__osz) == (__SIZE_TYPE__) -1 \ ++ || (__glibc_unsigned_or_positive (__l) \ ++ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ ++ (__s), (__osz))) \ ++ && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz)))) + + /* Conversely, we know at compile time that the length is unsafe if the + __L * __S <= __OBJSZ condition can be folded to a constant and if it is diff --git a/SOURCES/glibc-upstream-2.34-17.patch b/SOURCES/glibc-upstream-2.34-17.patch new file mode 100644 index 0000000..ca37faa --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-17.patch @@ -0,0 +1,26 @@ +commit 007d699d0e0d0957eead78ad252ad592656284de +Author: Joseph Myers +Date: Tue Sep 7 13:08:38 2021 +0000 + + Use Linux 5.14 in build-many-glibcs.py + + This patch makes build-many-glibcs.py use Linux 5.14. + + Tested with build-many-glibcs.py (host-libraries, compilers and glibcs + builds). + + (cherry picked from commit 4e04a47208e1712fcf202a6d9831f0900d575225) + +diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py +index 5a77af90a6b49909..86537fa8005cfd3d 100755 +--- a/scripts/build-many-glibcs.py ++++ b/scripts/build-many-glibcs.py +@@ -782,7 +782,7 @@ class Context(object): + 'gcc': 'vcs-11', + 'glibc': 'vcs-mainline', + 'gmp': '6.2.1', +- 'linux': '5.13', ++ 'linux': '5.14', + 'mpc': '1.2.1', + 'mpfr': '4.1.0', + 'mig': 'vcs-mainline', diff --git a/SOURCES/glibc-upstream-2.34-170.patch b/SOURCES/glibc-upstream-2.34-170.patch new file mode 100644 index 0000000..11aa68c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-170.patch @@ -0,0 +1,49 @@ +commit 0d477e92c49db2906b32e44135b98746ccc73c7b +Author: Florian Weimer +Date: Tue Apr 26 14:22:10 2022 +0200 + + INSTALL: Rephrase -with-default-link documentation + + Reviewed-by: Carlos O'Donell + (cherry picked from commit c935789bdf40ba22b5698da869d3a4789797e09f) + +diff --git a/INSTALL b/INSTALL +index 60d01568d77645c7..10a3dcdc0a8db665 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -90,10 +90,10 @@ 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-default-link=FLAG' +- With '--with-default-link=yes', the build system does not use a +- custom linker script for linking shared objects. The default for +- FLAG is the opposite, 'no', because the custom linker script is ++'--with-default-link' ++ With '--with-default-link', the build system does not use a custom ++ linker script for linking shared objects. The default is ++ '--without-default-link', because the custom linker script is + needed for full RELRO protection. + + '--with-nonshared-cflags=CFLAGS' +diff --git a/manual/install.texi b/manual/install.texi +index 36a5af62bc5722b0..8e34ff7e1847f3ae 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -117,11 +117,11 @@ 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-default-link=@var{FLAG} +-With @code{--with-default-link=yes}, the build system does not use a +-custom linker script for linking shared objects. The default for +-@var{FLAG} is the opposite, @samp{no}, because the custom linker script +-is needed for full RELRO protection. ++@item --with-default-link ++With @code{--with-default-link}, the build system does not use a custom ++linker script for linking shared objects. The default is ++@code{--without-default-link}, because the custom linker script is ++needed for full RELRO protection. + + @item --with-nonshared-cflags=@var{cflags} + Use additional compiler flags @var{cflags} to build the parts of the diff --git a/SOURCES/glibc-upstream-2.34-171.patch b/SOURCES/glibc-upstream-2.34-171.patch new file mode 100644 index 0000000..04e6898 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-171.patch @@ -0,0 +1,377 @@ +commit bc56ab1f4aa937665034373d3e320d0779a839aa +Author: Florian Weimer +Date: Tue Apr 26 14:23:02 2022 +0200 + + dlfcn: Do not use rtld_active () to determine ld.so state (bug 29078) + + When audit modules are loaded, ld.so initialization is not yet + complete, and rtld_active () returns false even though ld.so is + mostly working. Instead, the static dlopen hook is used, but that + does not work at all because this is not a static dlopen situation. + + Commit 466c1ea15f461edb8e3ffaf5d86d708876343bbf ("dlfcn: Rework + static dlopen hooks") moved the hook pointer into _rtld_global_ro, + which means that separate protection is not needed anymore and the + hook pointer can be checked directly. + + The guard for disabling libio vtable hardening in _IO_vtable_check + should stay for now. + + Fixes commit 8e1472d2c1e25e6eabc2059170731365f6d5b3d1 ("ld.so: + Examine GLRO to detect inactive loader [BZ #20204]"). + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 8dcb6d0af07fda3607b541857e4f3970a74ed55b) + +diff --git a/dlfcn/dladdr.c b/dlfcn/dladdr.c +index 1cc305f0c46e7c3b..0d07ae1cd4dbb7a2 100644 +--- a/dlfcn/dladdr.c ++++ b/dlfcn/dladdr.c +@@ -24,7 +24,7 @@ int + __dladdr (const void *address, Dl_info *info) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dladdr (address, info); + #endif + return _dl_addr (address, info, NULL, NULL); +diff --git a/dlfcn/dladdr1.c b/dlfcn/dladdr1.c +index 78560dbac208c316..93ce68c1d6067fe2 100644 +--- a/dlfcn/dladdr1.c ++++ b/dlfcn/dladdr1.c +@@ -24,7 +24,7 @@ int + __dladdr1 (const void *address, Dl_info *info, void **extra, int flags) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dladdr1 (address, info, extra, flags); + #endif + +diff --git a/dlfcn/dlclose.c b/dlfcn/dlclose.c +index 6a013a81bb648191..07ecb21bf7d43be4 100644 +--- a/dlfcn/dlclose.c ++++ b/dlfcn/dlclose.c +@@ -24,7 +24,7 @@ int + __dlclose (void *handle) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlclose (handle); + #endif + +diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c +index 5047b140662bc33e..63da79c63000eef0 100644 +--- a/dlfcn/dlerror.c ++++ b/dlfcn/dlerror.c +@@ -32,7 +32,7 @@ char * + __dlerror (void) + { + # ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlerror (); + # endif + +diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c +index c6f9a1da09ff8622..47d2daa96fa5986f 100644 +--- a/dlfcn/dlinfo.c ++++ b/dlfcn/dlinfo.c +@@ -89,7 +89,7 @@ dlinfo_implementation (void *handle, int request, void *arg) + int + ___dlinfo (void *handle, int request, void *arg) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlinfo (handle, request, arg); + else + return dlinfo_implementation (handle, request, arg); +diff --git a/dlfcn/dlmopen.c b/dlfcn/dlmopen.c +index c171c8953da20fc7..2309224eb8484b1a 100644 +--- a/dlfcn/dlmopen.c ++++ b/dlfcn/dlmopen.c +@@ -80,7 +80,7 @@ dlmopen_implementation (Lmid_t nsid, const char *file, int mode, + void * + ___dlmopen (Lmid_t nsid, const char *file, int mode) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlmopen (nsid, file, mode, RETURN_ADDRESS (0)); + else + return dlmopen_implementation (nsid, file, mode, RETURN_ADDRESS (0)); +diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c +index e04b374b82b04337..9c59c751c4eaf7a7 100644 +--- a/dlfcn/dlopen.c ++++ b/dlfcn/dlopen.c +@@ -75,7 +75,7 @@ dlopen_implementation (const char *file, int mode, void *dl_caller) + void * + ___dlopen (const char *file, int mode) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0)); + else + return dlopen_implementation (file, mode, RETURN_ADDRESS (0)); +diff --git a/dlfcn/dlopenold.c b/dlfcn/dlopenold.c +index 9115501ac121eeca..c2f2a42194d50953 100644 +--- a/dlfcn/dlopenold.c ++++ b/dlfcn/dlopenold.c +@@ -70,7 +70,7 @@ __dlopen_nocheck (const char *file, int mode) + mode |= RTLD_LAZY; + args.mode = mode; + +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0)); + + return _dlerror_run (dlopen_doit, &args) ? NULL : args.new; +diff --git a/dlfcn/dlsym.c b/dlfcn/dlsym.c +index 43044cf7bb95801e..d3861170a7631d01 100644 +--- a/dlfcn/dlsym.c ++++ b/dlfcn/dlsym.c +@@ -62,7 +62,7 @@ dlsym_implementation (void *handle, const char *name, void *dl_caller) + void * + ___dlsym (void *handle, const char *name) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlsym (handle, name, RETURN_ADDRESS (0)); + else + return dlsym_implementation (handle, name, RETURN_ADDRESS (0)); +diff --git a/dlfcn/dlvsym.c b/dlfcn/dlvsym.c +index 9b76f9afa513e11f..3af02109c306b800 100644 +--- a/dlfcn/dlvsym.c ++++ b/dlfcn/dlvsym.c +@@ -65,7 +65,7 @@ dlvsym_implementation (void *handle, const char *name, const char *version, + void * + ___dlvsym (void *handle, const char *name, const char *version) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlvsym (handle, name, version, + RETURN_ADDRESS (0)); + else +diff --git a/elf/Makefile b/elf/Makefile +index fec6e23b5b625e3b..c89a6a58690646ee 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -376,6 +376,7 @@ tests += \ + tst-audit24d \ + tst-audit25a \ + tst-audit25b \ ++ tst-audit26 \ + tst-auditmany \ + tst-auxobj \ + tst-auxobj-dlopen \ +@@ -721,6 +722,7 @@ modules-names = \ + tst-auditmod24c \ + tst-auditmod24d \ + tst-auditmod25 \ ++ tst-auditmod26 \ + tst-auxvalmod \ + tst-big-note-lib \ + tst-deep1mod1 \ +@@ -2194,6 +2196,10 @@ $(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \ + LDFLAGS-tst-audit25b = -Wl,-z,now + tst-audit25b-ARGS = -- $(host-test-program-cmd) + ++$(objpfx)tst-audit26.out: $(objpfx)tst-auditmod26.so ++$(objpfx)tst-auditmod26.so: $(libsupport) ++tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so ++ + # tst-sonamemove links against an older implementation of the library. + LDFLAGS-tst-sonamemove-linkmod1.so = \ + -Wl,--version-script=tst-sonamemove-linkmod1.map \ +diff --git a/elf/dl-libc.c b/elf/dl-libc.c +index d5bc4a277f4c6ef3..db4342a3256921f0 100644 +--- a/elf/dl-libc.c ++++ b/elf/dl-libc.c +@@ -157,7 +157,7 @@ __libc_dlopen_mode (const char *name, int mode) + args.caller_dlopen = RETURN_ADDRESS (0); + + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->libc_dlopen_mode (name, mode); + #endif + return dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map; +@@ -185,7 +185,7 @@ __libc_dlsym (void *map, const char *name) + args.name = name; + + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->libc_dlsym (map, name); + #endif + return (dlerror_run (do_dlsym, &args) ? NULL +@@ -199,7 +199,7 @@ void * + __libc_dlvsym (void *map, const char *name, const char *version) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->libc_dlvsym (map, name, version); + #endif + +@@ -222,7 +222,7 @@ int + __libc_dlclose (void *map) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->libc_dlclose (map); + #endif + return dlerror_run (do_dlclose, map); +diff --git a/elf/tst-audit26.c b/elf/tst-audit26.c +new file mode 100644 +index 0000000000000000..3f920e83bac247a5 +--- /dev/null ++++ b/elf/tst-audit26.c +@@ -0,0 +1,35 @@ ++/* Check the usability of functions in audit modules. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ /* Check that the audit module has been loaded. */ ++ void *handle = xdlopen ("mapped to libc", RTLD_LOCAL | RTLD_NOW); ++ TEST_VERIFY (handle ++ == xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD)); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-auditmod26.c b/elf/tst-auditmod26.c +new file mode 100644 +index 0000000000000000..db7ba95abec20f53 +--- /dev/null ++++ b/elf/tst-auditmod26.c +@@ -0,0 +1,104 @@ ++/* Check the usability of functions in audit modules. Audit module. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++unsigned int ++la_version (unsigned int current) ++{ ++ /* Exercise various functions. */ ++ ++ /* Check dlopen, dlsym, dlclose. */ ++ void *handle = xdlopen (LIBM_SO, RTLD_LOCAL | RTLD_NOW); ++ void *ptr = xdlsym (handle, "sincos"); ++ TEST_VERIFY (ptr != NULL); ++ ptr = dlsym (handle, "SINCOS"); ++ TEST_VERIFY (ptr == NULL); ++ const char *message = dlerror (); ++ TEST_VERIFY (strstr (message, ": undefined symbol: SINCOS") != NULL); ++ ptr = dlsym (handle, "SINCOS"); ++ TEST_VERIFY (ptr == NULL); ++ xdlclose (handle); ++ TEST_COMPARE_STRING (dlerror (), NULL); ++ ++ handle = xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD); ++ ++ /* Check dlvsym. _exit is unlikely to gain another symbol ++ version. */ ++ TEST_VERIFY (xdlsym (handle, "_exit") ++ == xdlvsym (handle, "_exit", FIRST_VERSION_libc__exit_STRING)); ++ ++ /* Check dlinfo. */ ++ { ++ void *handle2 = NULL; ++ TEST_COMPARE (dlinfo (handle, RTLD_DI_LINKMAP, &handle2), 0); ++ TEST_VERIFY (handle2 == handle); ++ } ++ ++ /* Check dladdr and dladdr1. */ ++ Dl_info info = { }; ++ TEST_VERIFY (dladdr (&_exit, &info) != 0); ++ if (strcmp (info.dli_sname, "_Exit") != 0) /* _Exit is an alias. */ ++ TEST_COMPARE_STRING (info.dli_sname, "_exit"); ++ TEST_VERIFY (info.dli_saddr == &_exit); ++ TEST_VERIFY (strstr (info.dli_fname, LIBC_SO)); ++ void *extra_info; ++ memset (&info, 0, sizeof (info)); ++ TEST_VERIFY (dladdr1 (&_exit, &info, &extra_info, RTLD_DL_LINKMAP) != 0); ++ TEST_VERIFY (extra_info == handle); ++ ++ /* Verify that dlmopen creates a new namespace. */ ++ void *dlmopen_handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); ++ TEST_VERIFY (dlmopen_handle != handle); ++ memset (&info, 0, sizeof (info)); ++ extra_info = NULL; ++ ptr = xdlsym (dlmopen_handle, "_exit"); ++ TEST_VERIFY (dladdr1 (ptr, &info, &extra_info, RTLD_DL_LINKMAP) != 0); ++ TEST_VERIFY (extra_info == dlmopen_handle); ++ xdlclose (dlmopen_handle); ++ ++ /* Terminate the process with an error state. This does not happen ++ automatically because the audit module state is not shared with ++ the main program. */ ++ if (support_record_failure_is_failed ()) ++ { ++ fflush (stdout); ++ fflush (stderr); ++ _exit (1); ++ } ++ ++ return LAV_CURRENT; ++} ++ ++char * ++la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) ++{ ++ if (strcmp (name, "mapped to libc") == 0) ++ return (char *) LIBC_SO; ++ else ++ return (char *) name; ++} diff --git a/SOURCES/glibc-upstream-2.34-172.patch b/SOURCES/glibc-upstream-2.34-172.patch new file mode 100644 index 0000000..06dc695 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-172.patch @@ -0,0 +1,28 @@ +commit 83cc145830bdbefdabe03787ed884d548bea9c99 +Author: Florian Weimer +Date: Fri Apr 22 19:34:52 2022 +0200 + + scripts/glibcelf.py: Mark as UNSUPPORTED on Python 3.5 and earlier + + enum.IntFlag and enum.EnumMeta._missing_ support are not part of + earlier Python versions. + + (cherry picked from commit b571f3adffdcbed23f35ea39b0ca43809dbb4f5b) + +diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py +index 8f7d0ca184845714..da0d5380f33a195e 100644 +--- a/scripts/glibcelf.py ++++ b/scripts/glibcelf.py +@@ -28,6 +28,12 @@ import collections + import enum + import struct + ++if not hasattr(enum, 'IntFlag'): ++ import sys ++ sys.stdout.write( ++ 'warning: glibcelf.py needs Python 3.6 for enum support\n') ++ sys.exit(77) ++ + class _OpenIntEnum(enum.IntEnum): + """Integer enumeration that supports arbitrary int values.""" + @classmethod diff --git a/SOURCES/glibc-upstream-2.34-173.patch b/SOURCES/glibc-upstream-2.34-173.patch new file mode 100644 index 0000000..69a92b8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-173.patch @@ -0,0 +1,254 @@ +commit 16245986fb9bfe396113fc7dfd1929f69a9e748e +Author: H.J. Lu +Date: Fri Aug 20 06:42:24 2021 -0700 + + x86-64: Optimize load of all bits set into ZMM register [BZ #28252] + + Optimize loads of all bits set into ZMM register in AVX512 SVML codes + by replacing + + vpbroadcastq .L_2il0floatpacket.16(%rip), %zmmX + + and + + vmovups .L_2il0floatpacket.13(%rip), %zmmX + + with + vpternlogd $0xff, %zmmX, %zmmX, %zmmX + + This fixes BZ #28252. + + (cherry picked from commit 78c9ec9000f873abe7a15a91b87080a2e4308260) + +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S +index e68fcdbb16a79f36..58e588a3d42a8bc9 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S +@@ -265,7 +265,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_cos + vmovaps %zmm0, %zmm8 + + /* Check for large arguments path */ +- vpbroadcastq .L_2il0floatpacket.16(%rip), %zmm2 ++ vpternlogd $0xff, %zmm2, %zmm2, %zmm2 + + /* + ARGUMENT RANGE REDUCTION: +@@ -456,8 +456,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_cos + jmp .LBL_2_7 + #endif + END (_ZGVeN8v_cos_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.16: +- .long 0xffffffff,0xffffffff +- .type .L_2il0floatpacket.16,@object +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S +index dfa2acafc486b56b..f5f117d474f66176 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S +@@ -274,7 +274,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_log + + /* preserve mantissa, set input exponent to 2^(-10) */ + vpternlogq $248, _ExpMask(%rax), %zmm3, %zmm2 +- vpbroadcastq .L_2il0floatpacket.12(%rip), %zmm1 ++ vpternlogd $0xff, %zmm1, %zmm1, %zmm1 + vpsrlq $32, %zmm4, %zmm6 + + /* reciprocal approximation good to at least 11 bits */ +@@ -461,8 +461,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_log + jmp .LBL_2_7 + #endif + END (_ZGVeN8v_log_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.12: +- .long 0xffffffff,0xffffffff +- .type .L_2il0floatpacket.12,@object +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S +index be8ab7c6e0e33819..48d251db16ccab9d 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S +@@ -261,7 +261,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_sin + andq $-64, %rsp + subq $1280, %rsp + movq __svml_d_trig_data@GOTPCREL(%rip), %rax +- vpbroadcastq .L_2il0floatpacket.14(%rip), %zmm14 ++ vpternlogd $0xff, %zmm1, %zmm1, %zmm14 + vmovups __dAbsMask(%rax), %zmm7 + vmovups __dInvPI(%rax), %zmm2 + vmovups __dRShifter(%rax), %zmm1 +@@ -458,8 +458,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_sin + jmp .LBL_2_7 + #endif + END (_ZGVeN8v_sin_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.14: +- .long 0xffffffff,0xffffffff +- .type .L_2il0floatpacket.14,@object +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S +index 611887082a545854..a4944a4feef6aa98 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S +@@ -430,7 +430,7 @@ WRAPPER_IMPL_AVX512_fFF _ZGVdN4vl8l8_sincos + + /* SinPoly = SinR*SinPoly */ + vfmadd213pd %zmm5, %zmm5, %zmm4 +- vpbroadcastq .L_2il0floatpacket.15(%rip), %zmm3 ++ vpternlogd $0xff, %zmm3, %zmm3, %zmm3 + + /* Update Cos result's sign */ + vxorpd %zmm2, %zmm1, %zmm1 +@@ -741,8 +741,3 @@ END (_ZGVeN8vvv_sincos_knl) + ENTRY (_ZGVeN8vvv_sincos_skx) + WRAPPER_AVX512_vvv_vl8l8 _ZGVeN8vl8l8_sincos_skx + END (_ZGVeN8vvv_sincos_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.15: +- .long 0xffffffff,0xffffffff +- .type .L_2il0floatpacket.15,@object +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S +index f671d60d5dab5a0e..fe8474fed943e8ad 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S +@@ -278,7 +278,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_cosf + X = X - Y*PI1 - Y*PI2 - Y*PI3 + */ + vmovaps %zmm0, %zmm6 +- vmovups .L_2il0floatpacket.13(%rip), %zmm12 ++ vpternlogd $0xff, %zmm12, %zmm12, %zmm12 + vmovups __sRShifter(%rax), %zmm3 + vmovups __sPI1_FMA(%rax), %zmm5 + vmovups __sA9_FMA(%rax), %zmm9 +@@ -453,8 +453,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_cosf + jmp .LBL_2_7 + #endif + END (_ZGVeN16v_cosf_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.13: +- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +- .type .L_2il0floatpacket.13,@object +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S +index 637bfe3c06ab9ad4..229b7828cde04db2 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S +@@ -264,7 +264,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_expf + vmovaps %zmm0, %zmm7 + + /* compare against threshold */ +- vmovups .L_2il0floatpacket.13(%rip), %zmm3 ++ vpternlogd $0xff, %zmm3, %zmm3, %zmm3 + vmovups __sInvLn2(%rax), %zmm4 + vmovups __sShifter(%rax), %zmm1 + vmovups __sLn2hi(%rax), %zmm6 +@@ -440,8 +440,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_expf + + #endif + END (_ZGVeN16v_expf_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.13: +- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +- .type .L_2il0floatpacket.13,@object +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S +index 9d790fbf0ad6c8ec..fa2aae986f543582 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S +@@ -235,7 +235,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_logf + andq $-64, %rsp + subq $1280, %rsp + movq __svml_slog_data@GOTPCREL(%rip), %rax +- vmovups .L_2il0floatpacket.7(%rip), %zmm6 ++ vpternlogd $0xff, %zmm6, %zmm6, %zmm6 + vmovups _iBrkValue(%rax), %zmm4 + vmovups _sPoly_7(%rax), %zmm8 + +@@ -409,8 +409,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_logf + + #endif + END (_ZGVeN16v_logf_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.7: +- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +- .type .L_2il0floatpacket.7,@object +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S +index c5c43c46ff7af5a3..6aea2a4f11d1f85f 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S +@@ -385,7 +385,7 @@ WRAPPER_IMPL_AVX512_ff _ZGVdN8vv_powf + vpsrlq $32, %zmm3, %zmm2 + vpmovqd %zmm2, %ymm11 + vcvtps2pd %ymm14, %zmm13 +- vmovups .L_2il0floatpacket.23(%rip), %zmm14 ++ vpternlogd $0xff, %zmm14, %zmm14, %zmm14 + vmovaps %zmm14, %zmm26 + vpandd _ABSMASK(%rax), %zmm1, %zmm8 + vpcmpd $1, _INF(%rax), %zmm8, %k2 +@@ -427,7 +427,7 @@ WRAPPER_IMPL_AVX512_ff _ZGVdN8vv_powf + vpmovqd %zmm11, %ymm5 + vpxord %zmm10, %zmm10, %zmm10 + vgatherdpd _Log2Rcp_lookup(%rax,%ymm4), %zmm10{%k3} +- vpbroadcastq .L_2il0floatpacket.24(%rip), %zmm4 ++ vpternlogd $0xff, %zmm4, %zmm4, %zmm4 + vpxord %zmm11, %zmm11, %zmm11 + vcvtdq2pd %ymm7, %zmm7 + vgatherdpd _Log2Rcp_lookup(%rax,%ymm5), %zmm11{%k1} +@@ -643,11 +643,3 @@ WRAPPER_IMPL_AVX512_ff _ZGVdN8vv_powf + jmp .LBL_2_7 + #endif + END (_ZGVeN16vv_powf_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.23: +- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +- .type .L_2il0floatpacket.23,@object +-.L_2il0floatpacket.24: +- .long 0xffffffff,0xffffffff +- .type .L_2il0floatpacket.24,@object +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S +index 9cf359c86ff9bd70..a446c504f63c9399 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S +@@ -317,7 +317,7 @@ WRAPPER_IMPL_AVX512_fFF _ZGVdN8vvv_sincosf + + /* Result sign calculations */ + vpternlogd $150, %zmm0, %zmm14, %zmm1 +- vmovups .L_2il0floatpacket.13(%rip), %zmm14 ++ vpternlogd $0xff, %zmm14, %zmm14, %zmm14 + + /* Add correction term 0.5 for cos() part */ + vaddps %zmm8, %zmm5, %zmm15 +@@ -748,8 +748,3 @@ END (_ZGVeN16vvv_sincosf_knl) + ENTRY (_ZGVeN16vvv_sincosf_skx) + WRAPPER_AVX512_vvv_vl4l4 _ZGVeN16vl4l4_sincosf_skx + END (_ZGVeN16vvv_sincosf_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.13: +- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +- .type .L_2il0floatpacket.13,@object +diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S +index bd05109a62181f22..c1b352d0ad1992cd 100644 +--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S ++++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S +@@ -280,7 +280,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_sinf + movq __svml_s_trig_data@GOTPCREL(%rip), %rax + + /* Check for large and special values */ +- vmovups .L_2il0floatpacket.11(%rip), %zmm14 ++ vpternlogd $0xff, %zmm14, %zmm14, %zmm14 + vmovups __sAbsMask(%rax), %zmm5 + vmovups __sInvPI(%rax), %zmm1 + vmovups __sRShifter(%rax), %zmm2 +@@ -472,8 +472,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_sinf + jmp .LBL_2_7 + #endif + END (_ZGVeN16v_sinf_skx) +- +- .section .rodata, "a" +-.L_2il0floatpacket.11: +- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +- .type .L_2il0floatpacket.11,@object diff --git a/SOURCES/glibc-upstream-2.34-174.patch b/SOURCES/glibc-upstream-2.34-174.patch new file mode 100644 index 0000000..3bf44a8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-174.patch @@ -0,0 +1,42 @@ +commit b5a44a6a471aafd3677659a610f32468c40a666b +Author: Noah Goldstein +Date: Tue Sep 21 18:31:49 2021 -0500 + + x86: Modify ENTRY in sysdep.h so that p2align can be specified + + No bug. + + This change adds a new macro ENTRY_P2ALIGN which takes a second + argument, log2 of the desired function alignment. + + The old ENTRY(name) macro is just ENTRY_P2ALIGN(name, 4) so this + doesn't affect any existing functionality. + + Signed-off-by: Noah Goldstein + (cherry picked from commit fc5bd179ef3a953dff8d1655bd530d0e230ffe71) + +diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h +index cac1d762fb3f99d0..937180c1bd791570 100644 +--- a/sysdeps/x86/sysdep.h ++++ b/sysdeps/x86/sysdep.h +@@ -78,15 +78,18 @@ enum cf_protection_level + #define ASM_SIZE_DIRECTIVE(name) .size name,.-name; + + /* Define an entry point visible from C. */ +-#define ENTRY(name) \ ++#define ENTRY_P2ALIGN(name, alignment) \ + .globl C_SYMBOL_NAME(name); \ + .type C_SYMBOL_NAME(name),@function; \ +- .align ALIGNARG(4); \ ++ .align ALIGNARG(alignment); \ + C_LABEL(name) \ + cfi_startproc; \ + _CET_ENDBR; \ + CALL_MCOUNT + ++/* Common entry 16 byte aligns. */ ++#define ENTRY(name) ENTRY_P2ALIGN (name, 4) ++ + #undef END + #define END(name) \ + cfi_endproc; \ diff --git a/SOURCES/glibc-upstream-2.34-175.patch b/SOURCES/glibc-upstream-2.34-175.patch new file mode 100644 index 0000000..5ebf0b7 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-175.patch @@ -0,0 +1,653 @@ +commit 5ec3416853c4150c4d13312e05f93a053586d528 +Author: Noah Goldstein +Date: Tue Sep 21 18:45:03 2021 -0500 + + x86: Optimize memcmp-evex-movbe.S for frontend behavior and size + + No bug. + + The frontend optimizations are to: + 1. Reorganize logically connected basic blocks so they are either in + the same cache line or adjacent cache lines. + 2. Avoid cases when basic blocks unnecissarily cross cache lines. + 3. Try and 32 byte align any basic blocks possible without sacrificing + code size. Smaller / Less hot basic blocks are used for this. + + Overall code size shrunk by 168 bytes. This should make up for any + extra costs due to aligning to 64 bytes. + + In general performance before deviated a great deal dependending on + whether entry alignment % 64 was 0, 16, 32, or 48. These changes + essentially make it so that the current implementation is at least + equal to the best alignment of the original for any arguments. + + The only additional optimization is in the page cross case. Branch on + equals case was removed from the size == [4, 7] case. As well the [4, + 7] and [2, 3] case where swapped as [4, 7] is likely a more hot + argument size. + + test-memcmp and test-wmemcmp are both passing. + + (cherry picked from commit 1bd8b8d58fc9967cc073d2c13bfb6befefca2faa) + +diff --git a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S +index 654dc7ac8ccb9445..2761b54f2e7dea9f 100644 +--- a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S ++++ b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S +@@ -34,7 +34,24 @@ + area. + 7. Use 2 vector compares when size is 2 * CHAR_PER_VEC or less. + 8. Use 4 vector compares when size is 4 * CHAR_PER_VEC or less. +- 9. Use 8 vector compares when size is 8 * CHAR_PER_VEC or less. */ ++ 9. Use 8 vector compares when size is 8 * CHAR_PER_VEC or less. ++ ++When possible the implementation tries to optimize for frontend in the ++following ways: ++Throughput: ++ 1. All code sections that fit are able to run optimally out of the ++ LSD. ++ 2. All code sections that fit are able to run optimally out of the ++ DSB ++ 3. Basic blocks are contained in minimum number of fetch blocks ++ necessary. ++ ++Latency: ++ 1. Logically connected basic blocks are put in the same ++ cache-line. ++ 2. Logically connected basic blocks that do not fit in the same ++ cache-line are put in adjacent lines. This can get beneficial ++ L2 spatial prefetching and L1 next-line prefetching. */ + + # include + +@@ -47,9 +64,11 @@ + # ifdef USE_AS_WMEMCMP + # define CHAR_SIZE 4 + # define VPCMP vpcmpd ++# define VPTEST vptestmd + # else + # define CHAR_SIZE 1 + # define VPCMP vpcmpub ++# define VPTEST vptestmb + # endif + + # define VEC_SIZE 32 +@@ -75,7 +94,9 @@ + */ + + .section .text.evex,"ax",@progbits +-ENTRY (MEMCMP) ++/* Cache align memcmp entry. This allows for much more thorough ++ frontend optimization. */ ++ENTRY_P2ALIGN (MEMCMP, 6) + # ifdef __ILP32__ + /* Clear the upper 32 bits. */ + movl %edx, %edx +@@ -89,7 +110,7 @@ ENTRY (MEMCMP) + VPCMP $4, (%rdi), %YMM1, %k1 + kmovd %k1, %eax + /* NB: eax must be destination register if going to +- L(return_vec_[0,2]). For L(return_vec_3 destination register ++ L(return_vec_[0,2]). For L(return_vec_3) destination register + must be ecx. */ + testl %eax, %eax + jnz L(return_vec_0) +@@ -121,10 +142,6 @@ ENTRY (MEMCMP) + testl %ecx, %ecx + jnz L(return_vec_3) + +- /* Zero YMM0. 4x VEC reduction is done with vpxor + vtern so +- compare with zero to get a mask is needed. */ +- vpxorq %XMM0, %XMM0, %XMM0 +- + /* Go to 4x VEC loop. */ + cmpq $(CHAR_PER_VEC * 8), %rdx + ja L(more_8x_vec) +@@ -148,47 +165,61 @@ ENTRY (MEMCMP) + + VMOVU (VEC_SIZE * 2)(%rsi), %YMM3 + vpxorq (VEC_SIZE * 2)(%rdi), %YMM3, %YMM3 +- /* Or together YMM1, YMM2, and YMM3 into YMM3. */ +- vpternlogd $0xfe, %YMM1, %YMM2, %YMM3 + + VMOVU (VEC_SIZE * 3)(%rsi), %YMM4 + /* Ternary logic to xor (VEC_SIZE * 3)(%rdi) with YMM4 while +- oring with YMM3. Result is stored in YMM4. */ +- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM3, %YMM4 +- /* Compare YMM4 with 0. If any 1s s1 and s2 don't match. */ +- VPCMP $4, %YMM4, %YMM0, %k1 ++ oring with YMM1. Result is stored in YMM4. */ ++ vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4 ++ ++ /* Or together YMM2, YMM3, and YMM4 into YMM4. */ ++ vpternlogd $0xfe, %YMM2, %YMM3, %YMM4 ++ ++ /* Test YMM4 against itself. Store any CHAR mismatches in k1. ++ */ ++ VPTEST %YMM4, %YMM4, %k1 ++ /* k1 must go to ecx for L(return_vec_0_1_2_3). */ + kmovd %k1, %ecx + testl %ecx, %ecx + jnz L(return_vec_0_1_2_3) + /* NB: eax must be zero to reach here. */ + ret + +- /* NB: aligning 32 here allows for the rest of the jump targets +- to be tuned for 32 byte alignment. Most important this ensures +- the L(more_8x_vec) loop is 32 byte aligned. */ +- .p2align 5 +-L(less_vec): +- /* Check if one or less CHAR. This is necessary for size = 0 but +- is also faster for size = CHAR_SIZE. */ +- cmpl $1, %edx +- jbe L(one_or_less) ++ .p2align 4 ++L(8x_end_return_vec_0_1_2_3): ++ movq %rdx, %rdi ++L(8x_return_vec_0_1_2_3): ++ addq %rdi, %rsi ++L(return_vec_0_1_2_3): ++ VPTEST %YMM1, %YMM1, %k0 ++ kmovd %k0, %eax ++ testl %eax, %eax ++ jnz L(return_vec_0) + +- /* Check if loading one VEC from either s1 or s2 could cause a +- page cross. This can have false positives but is by far the +- fastest method. */ +- movl %edi, %eax +- orl %esi, %eax +- andl $(PAGE_SIZE - 1), %eax +- cmpl $(PAGE_SIZE - VEC_SIZE), %eax +- jg L(page_cross_less_vec) ++ VPTEST %YMM2, %YMM2, %k0 ++ kmovd %k0, %eax ++ testl %eax, %eax ++ jnz L(return_vec_1) + +- /* No page cross possible. */ +- VMOVU (%rsi), %YMM2 +- VPCMP $4, (%rdi), %YMM2, %k1 +- kmovd %k1, %eax +- /* Create mask in ecx for potentially in bound matches. */ +- bzhil %edx, %eax, %eax +- jnz L(return_vec_0) ++ VPTEST %YMM3, %YMM3, %k0 ++ kmovd %k0, %eax ++ testl %eax, %eax ++ jnz L(return_vec_2) ++L(return_vec_3): ++ /* bsf saves 1 byte from tzcnt. This keep L(return_vec_3) in one ++ fetch block and the entire L(*return_vec_0_1_2_3) in 1 cache ++ line. */ ++ bsfl %ecx, %ecx ++# ifdef USE_AS_WMEMCMP ++ movl (VEC_SIZE * 3)(%rdi, %rcx, CHAR_SIZE), %eax ++ xorl %edx, %edx ++ cmpl (VEC_SIZE * 3)(%rsi, %rcx, CHAR_SIZE), %eax ++ setg %dl ++ leal -1(%rdx, %rdx), %eax ++# else ++ movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax ++ movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx ++ subl %ecx, %eax ++# endif + ret + + .p2align 4 +@@ -209,10 +240,11 @@ L(return_vec_0): + # endif + ret + +- /* NB: No p2align necessary. Alignment % 16 is naturally 1 +- which is good enough for a target not in a loop. */ ++ .p2align 4 + L(return_vec_1): +- tzcntl %eax, %eax ++ /* bsf saves 1 byte over tzcnt and keeps L(return_vec_1) in one ++ fetch block. */ ++ bsfl %eax, %eax + # ifdef USE_AS_WMEMCMP + movl VEC_SIZE(%rdi, %rax, CHAR_SIZE), %ecx + xorl %edx, %edx +@@ -226,10 +258,11 @@ L(return_vec_1): + # endif + ret + +- /* NB: No p2align necessary. Alignment % 16 is naturally 2 +- which is good enough for a target not in a loop. */ ++ .p2align 4,, 10 + L(return_vec_2): +- tzcntl %eax, %eax ++ /* bsf saves 1 byte over tzcnt and keeps L(return_vec_2) in one ++ fetch block. */ ++ bsfl %eax, %eax + # ifdef USE_AS_WMEMCMP + movl (VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %ecx + xorl %edx, %edx +@@ -243,40 +276,6 @@ L(return_vec_2): + # endif + ret + +- .p2align 4 +-L(8x_return_vec_0_1_2_3): +- /* Returning from L(more_8x_vec) requires restoring rsi. */ +- addq %rdi, %rsi +-L(return_vec_0_1_2_3): +- VPCMP $4, %YMM1, %YMM0, %k0 +- kmovd %k0, %eax +- testl %eax, %eax +- jnz L(return_vec_0) +- +- VPCMP $4, %YMM2, %YMM0, %k0 +- kmovd %k0, %eax +- testl %eax, %eax +- jnz L(return_vec_1) +- +- VPCMP $4, %YMM3, %YMM0, %k0 +- kmovd %k0, %eax +- testl %eax, %eax +- jnz L(return_vec_2) +-L(return_vec_3): +- tzcntl %ecx, %ecx +-# ifdef USE_AS_WMEMCMP +- movl (VEC_SIZE * 3)(%rdi, %rcx, CHAR_SIZE), %eax +- xorl %edx, %edx +- cmpl (VEC_SIZE * 3)(%rsi, %rcx, CHAR_SIZE), %eax +- setg %dl +- leal -1(%rdx, %rdx), %eax +-# else +- movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax +- movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx +- subl %ecx, %eax +-# endif +- ret +- + .p2align 4 + L(more_8x_vec): + /* Set end of s1 in rdx. */ +@@ -288,21 +287,19 @@ L(more_8x_vec): + andq $-VEC_SIZE, %rdi + /* Adjust because first 4x vec where check already. */ + subq $-(VEC_SIZE * 4), %rdi ++ + .p2align 4 + L(loop_4x_vec): + VMOVU (%rsi, %rdi), %YMM1 + vpxorq (%rdi), %YMM1, %YMM1 +- + VMOVU VEC_SIZE(%rsi, %rdi), %YMM2 + vpxorq VEC_SIZE(%rdi), %YMM2, %YMM2 +- + VMOVU (VEC_SIZE * 2)(%rsi, %rdi), %YMM3 + vpxorq (VEC_SIZE * 2)(%rdi), %YMM3, %YMM3 +- vpternlogd $0xfe, %YMM1, %YMM2, %YMM3 +- + VMOVU (VEC_SIZE * 3)(%rsi, %rdi), %YMM4 +- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM3, %YMM4 +- VPCMP $4, %YMM4, %YMM0, %k1 ++ vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4 ++ vpternlogd $0xfe, %YMM2, %YMM3, %YMM4 ++ VPTEST %YMM4, %YMM4, %k1 + kmovd %k1, %ecx + testl %ecx, %ecx + jnz L(8x_return_vec_0_1_2_3) +@@ -319,28 +316,25 @@ L(loop_4x_vec): + cmpl $(VEC_SIZE * 2), %edi + jae L(8x_last_2x_vec) + ++ vpxorq (VEC_SIZE * 2)(%rdx), %YMM3, %YMM3 ++ + VMOVU (%rsi, %rdx), %YMM1 + vpxorq (%rdx), %YMM1, %YMM1 + + VMOVU VEC_SIZE(%rsi, %rdx), %YMM2 + vpxorq VEC_SIZE(%rdx), %YMM2, %YMM2 +- +- vpxorq (VEC_SIZE * 2)(%rdx), %YMM3, %YMM3 +- vpternlogd $0xfe, %YMM1, %YMM2, %YMM3 +- + VMOVU (VEC_SIZE * 3)(%rsi, %rdx), %YMM4 +- vpternlogd $0xde, (VEC_SIZE * 3)(%rdx), %YMM3, %YMM4 +- VPCMP $4, %YMM4, %YMM0, %k1 ++ vpternlogd $0xde, (VEC_SIZE * 3)(%rdx), %YMM1, %YMM4 ++ vpternlogd $0xfe, %YMM2, %YMM3, %YMM4 ++ VPTEST %YMM4, %YMM4, %k1 + kmovd %k1, %ecx +- /* Restore s1 pointer to rdi. */ +- movq %rdx, %rdi + testl %ecx, %ecx +- jnz L(8x_return_vec_0_1_2_3) ++ jnz L(8x_end_return_vec_0_1_2_3) + /* NB: eax must be zero to reach here. */ + ret + + /* Only entry is from L(more_8x_vec). */ +- .p2align 4 ++ .p2align 4,, 10 + L(8x_last_2x_vec): + VPCMP $4, (VEC_SIZE * 2)(%rdx), %YMM3, %k1 + kmovd %k1, %eax +@@ -355,7 +349,31 @@ L(8x_last_1x_vec): + jnz L(8x_return_vec_3) + ret + +- .p2align 4 ++ /* Not ideally aligned (at offset +9 bytes in fetch block) but ++ not aligning keeps it in the same cache line as ++ L(8x_last_1x/2x_vec) so likely worth it. As well, saves code ++ size. */ ++ .p2align 4,, 4 ++L(8x_return_vec_2): ++ subq $VEC_SIZE, %rdx ++L(8x_return_vec_3): ++ bsfl %eax, %eax ++# ifdef USE_AS_WMEMCMP ++ leaq (%rdx, %rax, CHAR_SIZE), %rax ++ movl (VEC_SIZE * 3)(%rax), %ecx ++ xorl %edx, %edx ++ cmpl (VEC_SIZE * 3)(%rsi, %rax), %ecx ++ setg %dl ++ leal -1(%rdx, %rdx), %eax ++# else ++ addq %rdx, %rax ++ movzbl (VEC_SIZE * 3)(%rsi, %rax), %ecx ++ movzbl (VEC_SIZE * 3)(%rax), %eax ++ subl %ecx, %eax ++# endif ++ ret ++ ++ .p2align 4,, 10 + L(last_2x_vec): + /* Check second to last VEC. */ + VMOVU -(VEC_SIZE * 2)(%rsi, %rdx, CHAR_SIZE), %YMM1 +@@ -374,26 +392,49 @@ L(last_1x_vec): + jnz L(return_vec_0_end) + ret + +- .p2align 4 +-L(8x_return_vec_2): +- subq $VEC_SIZE, %rdx +-L(8x_return_vec_3): +- tzcntl %eax, %eax ++ .p2align 4,, 10 ++L(return_vec_1_end): ++ /* Use bsf to save code size. This is necessary to have ++ L(one_or_less) fit in aligning bytes between. */ ++ bsfl %eax, %eax ++ addl %edx, %eax + # ifdef USE_AS_WMEMCMP +- leaq (%rdx, %rax, CHAR_SIZE), %rax +- movl (VEC_SIZE * 3)(%rax), %ecx ++ movl -(VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %ecx + xorl %edx, %edx +- cmpl (VEC_SIZE * 3)(%rsi, %rax), %ecx ++ cmpl -(VEC_SIZE * 2)(%rsi, %rax, CHAR_SIZE), %ecx + setg %dl + leal -1(%rdx, %rdx), %eax + # else +- addq %rdx, %rax +- movzbl (VEC_SIZE * 3)(%rsi, %rax), %ecx +- movzbl (VEC_SIZE * 3)(%rax), %eax ++ movzbl -(VEC_SIZE * 2)(%rsi, %rax), %ecx ++ movzbl -(VEC_SIZE * 2)(%rdi, %rax), %eax + subl %ecx, %eax + # endif + ret + ++ /* NB: L(one_or_less) fits in alignment padding between ++ L(return_vec_1_end) and L(return_vec_0_end). */ ++# ifdef USE_AS_WMEMCMP ++L(one_or_less): ++ jb L(zero) ++ movl (%rdi), %ecx ++ xorl %edx, %edx ++ cmpl (%rsi), %ecx ++ je L(zero) ++ setg %dl ++ leal -1(%rdx, %rdx), %eax ++ ret ++# else ++L(one_or_less): ++ jb L(zero) ++ movzbl (%rsi), %ecx ++ movzbl (%rdi), %eax ++ subl %ecx, %eax ++ ret ++# endif ++L(zero): ++ xorl %eax, %eax ++ ret ++ + .p2align 4 + L(return_vec_0_end): + tzcntl %eax, %eax +@@ -412,23 +453,56 @@ L(return_vec_0_end): + ret + + .p2align 4 +-L(return_vec_1_end): ++L(less_vec): ++ /* Check if one or less CHAR. This is necessary for size == 0 ++ but is also faster for size == CHAR_SIZE. */ ++ cmpl $1, %edx ++ jbe L(one_or_less) ++ ++ /* Check if loading one VEC from either s1 or s2 could cause a ++ page cross. This can have false positives but is by far the ++ fastest method. */ ++ movl %edi, %eax ++ orl %esi, %eax ++ andl $(PAGE_SIZE - 1), %eax ++ cmpl $(PAGE_SIZE - VEC_SIZE), %eax ++ jg L(page_cross_less_vec) ++ ++ /* No page cross possible. */ ++ VMOVU (%rsi), %YMM2 ++ VPCMP $4, (%rdi), %YMM2, %k1 ++ kmovd %k1, %eax ++ /* Check if any matches where in bounds. Intentionally not ++ storing result in eax to limit dependency chain if it goes to ++ L(return_vec_0_lv). */ ++ bzhil %edx, %eax, %edx ++ jnz L(return_vec_0_lv) ++ xorl %eax, %eax ++ ret ++ ++ /* Essentially duplicate of L(return_vec_0). Ends up not costing ++ any code as shrinks L(less_vec) by allowing 2-byte encoding of ++ the jump and ends up fitting in aligning bytes. As well fits on ++ same cache line as L(less_vec) so also saves a line from having ++ to be fetched on cold calls to memcmp. */ ++ .p2align 4,, 4 ++L(return_vec_0_lv): + tzcntl %eax, %eax +- addl %edx, %eax + # ifdef USE_AS_WMEMCMP +- movl -(VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %ecx ++ movl (%rdi, %rax, CHAR_SIZE), %ecx + xorl %edx, %edx +- cmpl -(VEC_SIZE * 2)(%rsi, %rax, CHAR_SIZE), %ecx ++ cmpl (%rsi, %rax, CHAR_SIZE), %ecx ++ /* NB: no partial register stall here because xorl zero idiom ++ above. */ + setg %dl + leal -1(%rdx, %rdx), %eax + # else +- movzbl -(VEC_SIZE * 2)(%rsi, %rax), %ecx +- movzbl -(VEC_SIZE * 2)(%rdi, %rax), %eax ++ movzbl (%rsi, %rax), %ecx ++ movzbl (%rdi, %rax), %eax + subl %ecx, %eax + # endif + ret + +- + .p2align 4 + L(page_cross_less_vec): + /* if USE_AS_WMEMCMP it can only be 0, 4, 8, 12, 16, 20, 24, 28 +@@ -439,108 +513,84 @@ L(page_cross_less_vec): + cmpl $8, %edx + jae L(between_8_15) + cmpl $4, %edx +- jae L(between_4_7) +-L(between_2_3): +- /* Load as big endian to avoid branches. */ +- movzwl (%rdi), %eax +- movzwl (%rsi), %ecx +- shll $8, %eax +- shll $8, %ecx +- bswap %eax +- bswap %ecx +- movzbl -1(%rdi, %rdx), %edi +- movzbl -1(%rsi, %rdx), %esi +- orl %edi, %eax +- orl %esi, %ecx +- /* Subtraction is okay because the upper 8 bits are zero. */ +- subl %ecx, %eax +- ret +- .p2align 4 +-L(one_or_less): +- jb L(zero) +- movzbl (%rsi), %ecx +- movzbl (%rdi), %eax +- subl %ecx, %eax ++ jb L(between_2_3) ++ ++ /* Load as big endian with overlapping movbe to avoid branches. ++ */ ++ movbe (%rdi), %eax ++ movbe (%rsi), %ecx ++ shlq $32, %rax ++ shlq $32, %rcx ++ movbe -4(%rdi, %rdx), %edi ++ movbe -4(%rsi, %rdx), %esi ++ orq %rdi, %rax ++ orq %rsi, %rcx ++ subq %rcx, %rax ++ /* edx is guranteed to be positive int32 in range [4, 7]. */ ++ cmovne %edx, %eax ++ /* ecx is -1 if rcx > rax. Otherwise 0. */ ++ sbbl %ecx, %ecx ++ /* If rcx > rax, then ecx is 0 and eax is positive. If rcx == ++ rax then eax and ecx are zero. If rax < rax then ecx is -1 so ++ eax doesn't matter. */ ++ orl %ecx, %eax + ret + +- .p2align 4 ++ .p2align 4,, 8 + L(between_8_15): + # endif + /* If USE_AS_WMEMCMP fall through into 8-15 byte case. */ +- vmovq (%rdi), %XMM1 +- vmovq (%rsi), %XMM2 +- VPCMP $4, %XMM1, %XMM2, %k1 ++ vmovq (%rdi), %xmm1 ++ vmovq (%rsi), %xmm2 ++ VPCMP $4, %xmm1, %xmm2, %k1 + kmovd %k1, %eax + testl %eax, %eax +- jnz L(return_vec_0) ++ jnz L(return_vec_0_lv) + /* Use overlapping loads to avoid branches. */ +- leaq -8(%rdi, %rdx, CHAR_SIZE), %rdi +- leaq -8(%rsi, %rdx, CHAR_SIZE), %rsi +- vmovq (%rdi), %XMM1 +- vmovq (%rsi), %XMM2 +- VPCMP $4, %XMM1, %XMM2, %k1 ++ vmovq -8(%rdi, %rdx, CHAR_SIZE), %xmm1 ++ vmovq -8(%rsi, %rdx, CHAR_SIZE), %xmm2 ++ VPCMP $4, %xmm1, %xmm2, %k1 ++ addl $(CHAR_PER_VEC - (8 / CHAR_SIZE)), %edx + kmovd %k1, %eax + testl %eax, %eax +- jnz L(return_vec_0) +- ret +- +- .p2align 4 +-L(zero): +- xorl %eax, %eax ++ jnz L(return_vec_0_end) + ret + +- .p2align 4 ++ .p2align 4,, 8 + L(between_16_31): + /* From 16 to 31 bytes. No branch when size == 16. */ +- VMOVU (%rsi), %XMM2 +- VPCMP $4, (%rdi), %XMM2, %k1 ++ ++ /* Use movups to save code size. */ ++ movups (%rsi), %xmm2 ++ VPCMP $4, (%rdi), %xmm2, %k1 + kmovd %k1, %eax + testl %eax, %eax +- jnz L(return_vec_0) +- ++ jnz L(return_vec_0_lv) + /* Use overlapping loads to avoid branches. */ +- +- VMOVU -16(%rsi, %rdx, CHAR_SIZE), %XMM2 +- leaq -16(%rdi, %rdx, CHAR_SIZE), %rdi +- leaq -16(%rsi, %rdx, CHAR_SIZE), %rsi +- VPCMP $4, (%rdi), %XMM2, %k1 ++ movups -16(%rsi, %rdx, CHAR_SIZE), %xmm2 ++ VPCMP $4, -16(%rdi, %rdx, CHAR_SIZE), %xmm2, %k1 ++ addl $(CHAR_PER_VEC - (16 / CHAR_SIZE)), %edx + kmovd %k1, %eax + testl %eax, %eax +- jnz L(return_vec_0) +- ret +- +-# ifdef USE_AS_WMEMCMP +- .p2align 4 +-L(one_or_less): +- jb L(zero) +- movl (%rdi), %ecx +- xorl %edx, %edx +- cmpl (%rsi), %ecx +- je L(zero) +- setg %dl +- leal -1(%rdx, %rdx), %eax ++ jnz L(return_vec_0_end) + ret +-# else + +- .p2align 4 +-L(between_4_7): +- /* Load as big endian with overlapping movbe to avoid branches. +- */ +- movbe (%rdi), %eax +- movbe (%rsi), %ecx +- shlq $32, %rax +- shlq $32, %rcx +- movbe -4(%rdi, %rdx), %edi +- movbe -4(%rsi, %rdx), %esi +- orq %rdi, %rax +- orq %rsi, %rcx +- subq %rcx, %rax +- jz L(zero_4_7) +- sbbl %eax, %eax +- orl $1, %eax +-L(zero_4_7): ++# ifndef USE_AS_WMEMCMP ++L(between_2_3): ++ /* Load as big endian to avoid branches. */ ++ movzwl (%rdi), %eax ++ movzwl (%rsi), %ecx ++ shll $8, %eax ++ shll $8, %ecx ++ bswap %eax ++ bswap %ecx ++ movzbl -1(%rdi, %rdx), %edi ++ movzbl -1(%rsi, %rdx), %esi ++ orl %edi, %eax ++ orl %esi, %ecx ++ /* Subtraction is okay because the upper 8 bits are zero. */ ++ subl %ecx, %eax + ret + # endif +- + END (MEMCMP) + #endif diff --git a/SOURCES/glibc-upstream-2.34-176.patch b/SOURCES/glibc-upstream-2.34-176.patch new file mode 100644 index 0000000..74b18ab --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-176.patch @@ -0,0 +1,497 @@ +commit 6d18a93dbbde2958001d65dff3080beed7ae675a +Author: Noah Goldstein +Date: Mon Sep 20 16:20:15 2021 -0500 + + x86: Optimize memset-vec-unaligned-erms.S + + No bug. + + Optimization are + + 1. change control flow for L(more_2x_vec) to fall through to loop and + jump for L(less_4x_vec) and L(less_8x_vec). This uses less code + size and saves jumps for length > 4x VEC_SIZE. + + 2. For EVEX/AVX512 move L(less_vec) closer to entry. + + 3. Avoid complex address mode for length > 2x VEC_SIZE + + 4. Slightly better aligning code for the loop from the perspective of + code size and uops. + + 5. Align targets so they make full use of their fetch block and if + possible cache line. + + 6. Try and reduce total number of icache lines that will need to be + pulled in for a given length. + + 7. Include "local" version of stosb target. For AVX2/EVEX/AVX512 + jumping to the stosb target in the sse2 code section will almost + certainly be to a new page. The new version does increase code size + marginally by duplicating the target but should get better iTLB + behavior as a result. + + test-memset, test-wmemset, and test-bzero are all passing. + + Signed-off-by: Noah Goldstein + Reviewed-by: H.J. Lu + (cherry picked from commit e59ced238482fd71f3e493717f14f6507346741e) + +diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S +index 7d4a327eba29ecb4..0137eba4cdd9f830 100644 +--- a/sysdeps/x86_64/memset.S ++++ b/sysdeps/x86_64/memset.S +@@ -18,13 +18,15 @@ + . */ + + #include ++#define USE_WITH_SSE2 1 + + #define VEC_SIZE 16 ++#define MOV_SIZE 3 ++#define RET_SIZE 1 ++ + #define VEC(i) xmm##i +-/* Don't use movups and movaps since it will get larger nop paddings for +- alignment. */ +-#define VMOVU movdqu +-#define VMOVA movdqa ++#define VMOVU movups ++#define VMOVA movaps + + #define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ + movd d, %xmm0; \ +diff --git a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S +index ae0860f36a47d594..1af668af0aeda59e 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S +@@ -1,8 +1,14 @@ + #if IS_IN (libc) ++# define USE_WITH_AVX2 1 ++ + # define VEC_SIZE 32 ++# define MOV_SIZE 4 ++# define RET_SIZE 4 ++ + # define VEC(i) ymm##i +-# define VMOVU vmovdqu +-# define VMOVA vmovdqa ++ ++# define VMOVU vmovdqu ++# define VMOVA vmovdqa + + # define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ + vmovd d, %xmm0; \ +diff --git a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S +index 8ad842fc2f140527..f14d6f8493c21a36 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S +@@ -1,11 +1,18 @@ + #if IS_IN (libc) ++# define USE_WITH_AVX512 1 ++ + # define VEC_SIZE 64 ++# define MOV_SIZE 6 ++# define RET_SIZE 1 ++ + # define XMM0 xmm16 + # define YMM0 ymm16 + # define VEC0 zmm16 + # define VEC(i) VEC##i +-# define VMOVU vmovdqu64 +-# define VMOVA vmovdqa64 ++ ++# define VMOVU vmovdqu64 ++# define VMOVA vmovdqa64 ++ + # define VZEROUPPER + + # define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ +diff --git a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S +index 640f092903302ad0..64b09e77cc20cc42 100644 +--- a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S +@@ -1,11 +1,18 @@ + #if IS_IN (libc) ++# define USE_WITH_EVEX 1 ++ + # define VEC_SIZE 32 ++# define MOV_SIZE 6 ++# define RET_SIZE 1 ++ + # define XMM0 xmm16 + # define YMM0 ymm16 + # define VEC0 ymm16 + # define VEC(i) VEC##i +-# define VMOVU vmovdqu64 +-# define VMOVA vmovdqa64 ++ ++# define VMOVU vmovdqu64 ++# define VMOVA vmovdqa64 ++ + # define VZEROUPPER + + # define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ +diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +index ff196844a093dc3b..e723413a664c088f 100644 +--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +@@ -63,8 +63,27 @@ + # endif + #endif + ++#if VEC_SIZE == 64 ++# define LOOP_4X_OFFSET (VEC_SIZE * 4) ++#else ++# define LOOP_4X_OFFSET (0) ++#endif ++ ++#if defined USE_WITH_EVEX || defined USE_WITH_AVX512 ++# define END_REG rcx ++# define LOOP_REG rdi ++#else ++# define END_REG rdi ++# define LOOP_REG rdx ++#endif ++ + #define PAGE_SIZE 4096 + ++/* Macro to calculate size of small memset block for aligning ++ purposes. */ ++#define SMALL_MEMSET_ALIGN(mov_sz, ret_sz) (2 * (mov_sz) + (ret_sz) + 1) ++ ++ + #ifndef SECTION + # error SECTION is not defined! + #endif +@@ -74,6 +93,7 @@ + ENTRY (__bzero) + mov %RDI_LP, %RAX_LP /* Set return value. */ + mov %RSI_LP, %RDX_LP /* Set n. */ ++ xorl %esi, %esi + pxor %XMM0, %XMM0 + jmp L(entry_from_bzero) + END (__bzero) +@@ -158,7 +178,7 @@ ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms)) + END_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms)) + # endif + +-ENTRY (MEMSET_SYMBOL (__memset, unaligned_erms)) ++ENTRY_P2ALIGN (MEMSET_SYMBOL (__memset, unaligned_erms), 6) + MEMSET_VDUP_TO_VEC0_AND_SET_RETURN (%esi, %rdi) + # ifdef __ILP32__ + /* Clear the upper 32 bits. */ +@@ -168,75 +188,43 @@ ENTRY (MEMSET_SYMBOL (__memset, unaligned_erms)) + jb L(less_vec) + cmp $(VEC_SIZE * 2), %RDX_LP + ja L(stosb_more_2x_vec) +- /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */ +- VMOVU %VEC(0), -VEC_SIZE(%rdi,%rdx) +- VMOVU %VEC(0), (%rdi) ++ /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. ++ */ ++ VMOVU %VEC(0), (%rax) ++ VMOVU %VEC(0), -VEC_SIZE(%rax, %rdx) + VZEROUPPER_RETURN +- +- .p2align 4 +-L(stosb_more_2x_vec): +- cmp __x86_rep_stosb_threshold(%rip), %RDX_LP +- ja L(stosb) +-#else +- .p2align 4 + #endif +-L(more_2x_vec): +- /* Stores to first 2x VEC before cmp as any path forward will +- require it. */ +- VMOVU %VEC(0), (%rdi) +- VMOVU %VEC(0), VEC_SIZE(%rdi) +- cmpq $(VEC_SIZE * 4), %rdx +- ja L(loop_start) +- VMOVU %VEC(0), -(VEC_SIZE * 2)(%rdi,%rdx) +- VMOVU %VEC(0), -VEC_SIZE(%rdi,%rdx) +-L(return): +-#if VEC_SIZE > 16 +- ZERO_UPPER_VEC_REGISTERS_RETURN ++ ++ .p2align 4,, 10 ++L(last_2x_vec): ++#ifdef USE_LESS_VEC_MASK_STORE ++ VMOVU %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%rcx) ++ VMOVU %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%rcx) + #else +- ret ++ VMOVU %VEC(0), (VEC_SIZE * -2)(%rdi) ++ VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi) + #endif ++ VZEROUPPER_RETURN + +-L(loop_start): +- VMOVU %VEC(0), (VEC_SIZE * 2)(%rdi) +- VMOVU %VEC(0), (VEC_SIZE * 3)(%rdi) +- cmpq $(VEC_SIZE * 8), %rdx +- jbe L(loop_end) +- andq $-(VEC_SIZE * 2), %rdi +- subq $-(VEC_SIZE * 4), %rdi +- leaq -(VEC_SIZE * 4)(%rax, %rdx), %rcx +- .p2align 4 +-L(loop): +- VMOVA %VEC(0), (%rdi) +- VMOVA %VEC(0), VEC_SIZE(%rdi) +- VMOVA %VEC(0), (VEC_SIZE * 2)(%rdi) +- VMOVA %VEC(0), (VEC_SIZE * 3)(%rdi) +- subq $-(VEC_SIZE * 4), %rdi +- cmpq %rcx, %rdi +- jb L(loop) +-L(loop_end): +- /* NB: rax is set as ptr in MEMSET_VDUP_TO_VEC0_AND_SET_RETURN. +- rdx as length is also unchanged. */ +- VMOVU %VEC(0), -(VEC_SIZE * 4)(%rax, %rdx) +- VMOVU %VEC(0), -(VEC_SIZE * 3)(%rax, %rdx) +- VMOVU %VEC(0), -(VEC_SIZE * 2)(%rax, %rdx) +- VMOVU %VEC(0), -VEC_SIZE(%rax, %rdx) +- VZEROUPPER_SHORT_RETURN +- +- .p2align 4 ++ /* If have AVX512 mask instructions put L(less_vec) close to ++ entry as it doesn't take much space and is likely a hot target. ++ */ ++#ifdef USE_LESS_VEC_MASK_STORE ++ .p2align 4,, 10 + L(less_vec): + /* Less than 1 VEC. */ + # if VEC_SIZE != 16 && VEC_SIZE != 32 && VEC_SIZE != 64 + # error Unsupported VEC_SIZE! + # endif +-# ifdef USE_LESS_VEC_MASK_STORE + /* Clear high bits from edi. Only keeping bits relevant to page + cross check. Note that we are using rax which is set in +- MEMSET_VDUP_TO_VEC0_AND_SET_RETURN as ptr from here on out. +- */ ++ MEMSET_VDUP_TO_VEC0_AND_SET_RETURN as ptr from here on out. */ + andl $(PAGE_SIZE - 1), %edi +- /* Check if VEC_SIZE store cross page. Mask stores suffer serious +- performance degradation when it has to fault supress. */ ++ /* Check if VEC_SIZE store cross page. Mask stores suffer ++ serious performance degradation when it has to fault supress. ++ */ + cmpl $(PAGE_SIZE - VEC_SIZE), %edi ++ /* This is generally considered a cold target. */ + ja L(cross_page) + # if VEC_SIZE > 32 + movq $-1, %rcx +@@ -247,58 +235,185 @@ L(less_vec): + bzhil %edx, %ecx, %ecx + kmovd %ecx, %k1 + # endif +- vmovdqu8 %VEC(0), (%rax) {%k1} ++ vmovdqu8 %VEC(0), (%rax){%k1} + VZEROUPPER_RETURN + ++# if defined USE_MULTIARCH && IS_IN (libc) ++ /* Include L(stosb_local) here if including L(less_vec) between ++ L(stosb_more_2x_vec) and ENTRY. This is to cache align the ++ L(stosb_more_2x_vec) target. */ ++ .p2align 4,, 10 ++L(stosb_local): ++ movzbl %sil, %eax ++ mov %RDX_LP, %RCX_LP ++ mov %RDI_LP, %RDX_LP ++ rep stosb ++ mov %RDX_LP, %RAX_LP ++ VZEROUPPER_RETURN ++# endif ++#endif ++ ++#if defined USE_MULTIARCH && IS_IN (libc) + .p2align 4 +-L(cross_page): ++L(stosb_more_2x_vec): ++ cmp __x86_rep_stosb_threshold(%rip), %RDX_LP ++ ja L(stosb_local) ++#endif ++ /* Fallthrough goes to L(loop_4x_vec). Tests for memset (2x, 4x] ++ and (4x, 8x] jump to target. */ ++L(more_2x_vec): ++ ++ /* Two different methods of setting up pointers / compare. The ++ two methods are based on the fact that EVEX/AVX512 mov ++ instructions take more bytes then AVX2/SSE2 mov instructions. As ++ well that EVEX/AVX512 machines also have fast LEA_BID. Both ++ setup and END_REG to avoid complex address mode. For EVEX/AVX512 ++ this saves code size and keeps a few targets in one fetch block. ++ For AVX2/SSE2 this helps prevent AGU bottlenecks. */ ++#if defined USE_WITH_EVEX || defined USE_WITH_AVX512 ++ /* If EVEX/AVX512 compute END_REG - (VEC_SIZE * 4 + ++ LOOP_4X_OFFSET) with LEA_BID. */ ++ ++ /* END_REG is rcx for EVEX/AVX512. */ ++ leaq -(VEC_SIZE * 4 + LOOP_4X_OFFSET)(%rdi, %rdx), %END_REG ++#endif ++ ++ /* Stores to first 2x VEC before cmp as any path forward will ++ require it. */ ++ VMOVU %VEC(0), (%rax) ++ VMOVU %VEC(0), VEC_SIZE(%rax) ++ ++ ++#if !(defined USE_WITH_EVEX || defined USE_WITH_AVX512) ++ /* If AVX2/SSE2 compute END_REG (rdi) with ALU. */ ++ addq %rdx, %END_REG ++#endif ++ ++ cmpq $(VEC_SIZE * 4), %rdx ++ jbe L(last_2x_vec) ++ ++ /* Store next 2x vec regardless. */ ++ VMOVU %VEC(0), (VEC_SIZE * 2)(%rax) ++ VMOVU %VEC(0), (VEC_SIZE * 3)(%rax) ++ ++ ++#if defined USE_WITH_EVEX || defined USE_WITH_AVX512 ++ /* If LOOP_4X_OFFSET don't readjust LOOP_REG (rdi), just add ++ extra offset to addresses in loop. Used for AVX512 to save space ++ as no way to get (VEC_SIZE * 4) in imm8. */ ++# if LOOP_4X_OFFSET == 0 ++ subq $-(VEC_SIZE * 4), %LOOP_REG + # endif +-# if VEC_SIZE > 32 +- cmpb $32, %dl +- jae L(between_32_63) ++ /* Avoid imm32 compare here to save code size. */ ++ cmpq %rdi, %rcx ++#else ++ addq $-(VEC_SIZE * 4), %END_REG ++ cmpq $(VEC_SIZE * 8), %rdx ++#endif ++ jbe L(last_4x_vec) ++#if !(defined USE_WITH_EVEX || defined USE_WITH_AVX512) ++ /* Set LOOP_REG (rdx). */ ++ leaq (VEC_SIZE * 4)(%rax), %LOOP_REG ++#endif ++ /* Align dst for loop. */ ++ andq $(VEC_SIZE * -2), %LOOP_REG ++ .p2align 4 ++L(loop): ++ VMOVA %VEC(0), LOOP_4X_OFFSET(%LOOP_REG) ++ VMOVA %VEC(0), (VEC_SIZE + LOOP_4X_OFFSET)(%LOOP_REG) ++ VMOVA %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%LOOP_REG) ++ VMOVA %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%LOOP_REG) ++ subq $-(VEC_SIZE * 4), %LOOP_REG ++ cmpq %END_REG, %LOOP_REG ++ jb L(loop) ++ .p2align 4,, MOV_SIZE ++L(last_4x_vec): ++ VMOVU %VEC(0), LOOP_4X_OFFSET(%END_REG) ++ VMOVU %VEC(0), (VEC_SIZE + LOOP_4X_OFFSET)(%END_REG) ++ VMOVU %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%END_REG) ++ VMOVU %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%END_REG) ++L(return): ++#if VEC_SIZE > 16 ++ ZERO_UPPER_VEC_REGISTERS_RETURN ++#else ++ ret ++#endif ++ ++ .p2align 4,, 10 ++#ifndef USE_LESS_VEC_MASK_STORE ++# if defined USE_MULTIARCH && IS_IN (libc) ++ /* If no USE_LESS_VEC_MASK put L(stosb_local) here. Will be in ++ range for 2-byte jump encoding. */ ++L(stosb_local): ++ movzbl %sil, %eax ++ mov %RDX_LP, %RCX_LP ++ mov %RDI_LP, %RDX_LP ++ rep stosb ++ mov %RDX_LP, %RAX_LP ++ VZEROUPPER_RETURN + # endif +-# if VEC_SIZE > 16 +- cmpb $16, %dl ++ /* Define L(less_vec) only if not otherwise defined. */ ++ .p2align 4 ++L(less_vec): ++#endif ++L(cross_page): ++#if VEC_SIZE > 32 ++ cmpl $32, %edx ++ jae L(between_32_63) ++#endif ++#if VEC_SIZE > 16 ++ cmpl $16, %edx + jae L(between_16_31) +-# endif +- MOVQ %XMM0, %rcx +- cmpb $8, %dl ++#endif ++ MOVQ %XMM0, %rdi ++ cmpl $8, %edx + jae L(between_8_15) +- cmpb $4, %dl ++ cmpl $4, %edx + jae L(between_4_7) +- cmpb $1, %dl ++ cmpl $1, %edx + ja L(between_2_3) +- jb 1f +- movb %cl, (%rax) +-1: ++ jb L(return) ++ movb %sil, (%rax) + VZEROUPPER_RETURN +-# if VEC_SIZE > 32 ++ ++ /* Align small targets only if not doing so would cross a fetch ++ line. */ ++#if VEC_SIZE > 32 ++ .p2align 4,, SMALL_MEMSET_ALIGN(MOV_SIZE, RET_SIZE) + /* From 32 to 63. No branch when size == 32. */ + L(between_32_63): +- VMOVU %YMM0, -32(%rax,%rdx) + VMOVU %YMM0, (%rax) ++ VMOVU %YMM0, -32(%rax, %rdx) + VZEROUPPER_RETURN +-# endif +-# if VEC_SIZE > 16 +- /* From 16 to 31. No branch when size == 16. */ ++#endif ++ ++#if VEC_SIZE >= 32 ++ .p2align 4,, SMALL_MEMSET_ALIGN(MOV_SIZE, RET_SIZE) + L(between_16_31): +- VMOVU %XMM0, -16(%rax,%rdx) ++ /* From 16 to 31. No branch when size == 16. */ + VMOVU %XMM0, (%rax) ++ VMOVU %XMM0, -16(%rax, %rdx) + VZEROUPPER_RETURN +-# endif +- /* From 8 to 15. No branch when size == 8. */ ++#endif ++ ++ .p2align 4,, SMALL_MEMSET_ALIGN(3, RET_SIZE) + L(between_8_15): +- movq %rcx, -8(%rax,%rdx) +- movq %rcx, (%rax) ++ /* From 8 to 15. No branch when size == 8. */ ++ movq %rdi, (%rax) ++ movq %rdi, -8(%rax, %rdx) + VZEROUPPER_RETURN ++ ++ .p2align 4,, SMALL_MEMSET_ALIGN(2, RET_SIZE) + L(between_4_7): + /* From 4 to 7. No branch when size == 4. */ +- movl %ecx, -4(%rax,%rdx) +- movl %ecx, (%rax) ++ movl %edi, (%rax) ++ movl %edi, -4(%rax, %rdx) + VZEROUPPER_RETURN ++ ++ .p2align 4,, SMALL_MEMSET_ALIGN(3, RET_SIZE) + L(between_2_3): + /* From 2 to 3. No branch when size == 2. */ +- movw %cx, -2(%rax,%rdx) +- movw %cx, (%rax) ++ movw %di, (%rax) ++ movb %dil, -1(%rax, %rdx) + VZEROUPPER_RETURN + END (MEMSET_SYMBOL (__memset, unaligned_erms)) diff --git a/SOURCES/glibc-upstream-2.34-177.patch b/SOURCES/glibc-upstream-2.34-177.patch new file mode 100644 index 0000000..112bcad --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-177.patch @@ -0,0 +1,40 @@ +commit baf3ece63453adac59c5688930324a78ced5b2e4 +Author: Noah Goldstein +Date: Sat Oct 23 01:26:47 2021 -0400 + + x86: Replace sse2 instructions with avx in memcmp-evex-movbe.S + + This commit replaces two usages of SSE2 'movups' with AVX 'vmovdqu'. + + it could potentially be dangerous to use SSE2 if this function is ever + called without using 'vzeroupper' beforehand. While compilers appear + to use 'vzeroupper' before function calls if AVX2 has been used, using + SSE2 here is more brittle. Since it is not absolutely necessary it + should be avoided. + + It costs 2-extra bytes but the extra bytes should only eat into + alignment padding. + Reviewed-by: H.J. Lu + + (cherry picked from commit bad852b61b79503fcb3c5fc379c70f768df3e1fb) + +diff --git a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S +index 2761b54f2e7dea9f..640f6757fac8a356 100644 +--- a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S ++++ b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S +@@ -561,13 +561,13 @@ L(between_16_31): + /* From 16 to 31 bytes. No branch when size == 16. */ + + /* Use movups to save code size. */ +- movups (%rsi), %xmm2 ++ vmovdqu (%rsi), %xmm2 + VPCMP $4, (%rdi), %xmm2, %k1 + kmovd %k1, %eax + testl %eax, %eax + jnz L(return_vec_0_lv) + /* Use overlapping loads to avoid branches. */ +- movups -16(%rsi, %rdx, CHAR_SIZE), %xmm2 ++ vmovdqu -16(%rsi, %rdx, CHAR_SIZE), %xmm2 + VPCMP $4, -16(%rdi, %rdx, CHAR_SIZE), %xmm2, %k1 + addl $(CHAR_PER_VEC - (16 / CHAR_SIZE)), %edx + kmovd %k1, %eax diff --git a/SOURCES/glibc-upstream-2.34-178.patch b/SOURCES/glibc-upstream-2.34-178.patch new file mode 100644 index 0000000..1540e2f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-178.patch @@ -0,0 +1,690 @@ +commit f35ad30da4880a1574996df0674986ecf82fa7ae +Author: H.J. Lu +Date: Fri Oct 29 12:40:20 2021 -0700 + + x86-64: Improve EVEX strcmp with masked load + + In strcmp-evex.S, to compare 2 32-byte strings, replace + + VMOVU (%rdi, %rdx), %YMM0 + VMOVU (%rsi, %rdx), %YMM1 + /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */ + VPCMP $4, %YMM0, %YMM1, %k0 + VPCMP $0, %YMMZERO, %YMM0, %k1 + VPCMP $0, %YMMZERO, %YMM1, %k2 + /* Each bit in K1 represents a NULL in YMM0 or YMM1. */ + kord %k1, %k2, %k1 + /* Each bit in K1 represents a NULL or a mismatch. */ + kord %k0, %k1, %k1 + kmovd %k1, %ecx + testl %ecx, %ecx + jne L(last_vector) + + with + + VMOVU (%rdi, %rdx), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 + /* Each bit cleared in K1 represents a mismatch or a null CHAR + in YMM0 and 32 bytes at (%rsi, %rdx). */ + VPCMP $0, (%rsi, %rdx), %YMM0, %k1{%k2} + kmovd %k1, %ecx + incl %ecx + jne L(last_vector) + + It makes EVEX strcmp faster than AVX2 strcmp by up to 40% on Tiger Lake + and Ice Lake. + + Co-Authored-By: Noah Goldstein + (cherry picked from commit c46e9afb2df5fc9e39ff4d13777e4b4c26e04e55) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S +index d5aa6daa46c7ed25..82f12ac89bcae20b 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-evex.S ++++ b/sysdeps/x86_64/multiarch/strcmp-evex.S +@@ -41,6 +41,8 @@ + # ifdef USE_AS_WCSCMP + /* Compare packed dwords. */ + # define VPCMP vpcmpd ++# define VPMINU vpminud ++# define VPTESTM vptestmd + # define SHIFT_REG32 r8d + # define SHIFT_REG64 r8 + /* 1 dword char == 4 bytes. */ +@@ -48,6 +50,8 @@ + # else + /* Compare packed bytes. */ + # define VPCMP vpcmpb ++# define VPMINU vpminub ++# define VPTESTM vptestmb + # define SHIFT_REG32 ecx + # define SHIFT_REG64 rcx + /* 1 byte char == 1 byte. */ +@@ -67,6 +71,9 @@ + # define YMM5 ymm22 + # define YMM6 ymm23 + # define YMM7 ymm24 ++# define YMM8 ymm25 ++# define YMM9 ymm26 ++# define YMM10 ymm27 + + /* Warning! + wcscmp/wcsncmp have to use SIGNED comparison for elements. +@@ -76,7 +83,7 @@ + /* The main idea of the string comparison (byte or dword) using 256-bit + EVEX instructions consists of comparing (VPCMP) two ymm vectors. The + latter can be on either packed bytes or dwords depending on +- USE_AS_WCSCMP. In order to check the null char, algorithm keeps the ++ USE_AS_WCSCMP. In order to check the null CHAR, algorithm keeps the + matched bytes/dwords, requiring 5 EVEX instructions (3 VPCMP and 2 + KORD). In general, the costs of comparing VEC_SIZE bytes (32-bytes) + are 3 VPCMP and 2 KORD instructions, together with VMOVU and ktestd +@@ -123,27 +130,21 @@ ENTRY (STRCMP) + jg L(cross_page) + /* Start comparing 4 vectors. */ + VMOVU (%rdi), %YMM0 +- VMOVU (%rsi), %YMM1 + +- /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */ +- VPCMP $4, %YMM0, %YMM1, %k0 ++ /* Each bit set in K2 represents a non-null CHAR in YMM0. */ ++ VPTESTM %YMM0, %YMM0, %k2 + +- /* Check for NULL in YMM0. */ +- VPCMP $0, %YMMZERO, %YMM0, %k1 +- /* Check for NULL in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM1, %k2 +- /* Each bit in K1 represents a NULL in YMM0 or YMM1. */ +- kord %k1, %k2, %k1 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in YMM0 and 32 bytes at (%rsi). */ ++ VPCMP $0, (%rsi), %YMM0, %k1{%k2} + +- /* Each bit in K1 represents: +- 1. A mismatch in YMM0 and YMM1. Or +- 2. A NULL in YMM0 or YMM1. +- */ +- kord %k0, %k1, %k1 +- +- ktestd %k1, %k1 +- je L(next_3_vectors) + kmovd %k1, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif ++ je L(next_3_vectors) + tzcntl %ecx, %edx + # ifdef USE_AS_WCSCMP + /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +@@ -172,9 +173,7 @@ L(return): + # endif + ret + +- .p2align 4 + L(return_vec_size): +- kmovd %k1, %ecx + tzcntl %ecx, %edx + # ifdef USE_AS_WCSCMP + /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +@@ -210,9 +209,7 @@ L(return_vec_size): + # endif + ret + +- .p2align 4 + L(return_2_vec_size): +- kmovd %k1, %ecx + tzcntl %ecx, %edx + # ifdef USE_AS_WCSCMP + /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +@@ -248,9 +245,7 @@ L(return_2_vec_size): + # endif + ret + +- .p2align 4 + L(return_3_vec_size): +- kmovd %k1, %ecx + tzcntl %ecx, %edx + # ifdef USE_AS_WCSCMP + /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +@@ -289,43 +284,45 @@ L(return_3_vec_size): + .p2align 4 + L(next_3_vectors): + VMOVU VEC_SIZE(%rdi), %YMM0 +- VMOVU VEC_SIZE(%rsi), %YMM1 +- /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */ +- VPCMP $4, %YMM0, %YMM1, %k0 +- VPCMP $0, %YMMZERO, %YMM0, %k1 +- VPCMP $0, %YMMZERO, %YMM1, %k2 +- /* Each bit in K1 represents a NULL in YMM0 or YMM1. */ +- kord %k1, %k2, %k1 +- /* Each bit in K1 represents a NULL or a mismatch. */ +- kord %k0, %k1, %k1 +- ktestd %k1, %k1 ++ /* Each bit set in K2 represents a non-null CHAR in YMM0. */ ++ VPTESTM %YMM0, %YMM0, %k2 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in YMM0 and 32 bytes at VEC_SIZE(%rsi). */ ++ VPCMP $0, VEC_SIZE(%rsi), %YMM0, %k1{%k2} ++ kmovd %k1, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif + jne L(return_vec_size) + +- VMOVU (VEC_SIZE * 2)(%rdi), %YMM2 +- VMOVU (VEC_SIZE * 3)(%rdi), %YMM3 +- VMOVU (VEC_SIZE * 2)(%rsi), %YMM4 +- VMOVU (VEC_SIZE * 3)(%rsi), %YMM5 +- +- /* Each bit in K0 represents a mismatch in YMM2 and YMM4. */ +- VPCMP $4, %YMM2, %YMM4, %k0 +- VPCMP $0, %YMMZERO, %YMM2, %k1 +- VPCMP $0, %YMMZERO, %YMM4, %k2 +- /* Each bit in K1 represents a NULL in YMM2 or YMM4. */ +- kord %k1, %k2, %k1 +- /* Each bit in K1 represents a NULL or a mismatch. */ +- kord %k0, %k1, %k1 +- ktestd %k1, %k1 ++ VMOVU (VEC_SIZE * 2)(%rdi), %YMM0 ++ /* Each bit set in K2 represents a non-null CHAR in YMM0. */ ++ VPTESTM %YMM0, %YMM0, %k2 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rsi). */ ++ VPCMP $0, (VEC_SIZE * 2)(%rsi), %YMM0, %k1{%k2} ++ kmovd %k1, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif + jne L(return_2_vec_size) + +- /* Each bit in K0 represents a mismatch in YMM3 and YMM5. */ +- VPCMP $4, %YMM3, %YMM5, %k0 +- VPCMP $0, %YMMZERO, %YMM3, %k1 +- VPCMP $0, %YMMZERO, %YMM5, %k2 +- /* Each bit in K1 represents a NULL in YMM3 or YMM5. */ +- kord %k1, %k2, %k1 +- /* Each bit in K1 represents a NULL or a mismatch. */ +- kord %k0, %k1, %k1 +- ktestd %k1, %k1 ++ VMOVU (VEC_SIZE * 3)(%rdi), %YMM0 ++ /* Each bit set in K2 represents a non-null CHAR in YMM0. */ ++ VPTESTM %YMM0, %YMM0, %k2 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rsi). */ ++ VPCMP $0, (VEC_SIZE * 3)(%rsi), %YMM0, %k1{%k2} ++ kmovd %k1, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif + jne L(return_3_vec_size) + L(main_loop_header): + leaq (VEC_SIZE * 4)(%rdi), %rdx +@@ -375,56 +372,51 @@ L(back_to_loop): + VMOVA VEC_SIZE(%rax), %YMM2 + VMOVA (VEC_SIZE * 2)(%rax), %YMM4 + VMOVA (VEC_SIZE * 3)(%rax), %YMM6 +- VMOVU (%rdx), %YMM1 +- VMOVU VEC_SIZE(%rdx), %YMM3 +- VMOVU (VEC_SIZE * 2)(%rdx), %YMM5 +- VMOVU (VEC_SIZE * 3)(%rdx), %YMM7 +- +- VPCMP $4, %YMM0, %YMM1, %k0 +- VPCMP $0, %YMMZERO, %YMM0, %k1 +- VPCMP $0, %YMMZERO, %YMM1, %k2 +- kord %k1, %k2, %k1 +- /* Each bit in K4 represents a NULL or a mismatch in YMM0 and +- YMM1. */ +- kord %k0, %k1, %k4 +- +- VPCMP $4, %YMM2, %YMM3, %k0 +- VPCMP $0, %YMMZERO, %YMM2, %k1 +- VPCMP $0, %YMMZERO, %YMM3, %k2 +- kord %k1, %k2, %k1 +- /* Each bit in K5 represents a NULL or a mismatch in YMM2 and +- YMM3. */ +- kord %k0, %k1, %k5 +- +- VPCMP $4, %YMM4, %YMM5, %k0 +- VPCMP $0, %YMMZERO, %YMM4, %k1 +- VPCMP $0, %YMMZERO, %YMM5, %k2 +- kord %k1, %k2, %k1 +- /* Each bit in K6 represents a NULL or a mismatch in YMM4 and +- YMM5. */ +- kord %k0, %k1, %k6 +- +- VPCMP $4, %YMM6, %YMM7, %k0 +- VPCMP $0, %YMMZERO, %YMM6, %k1 +- VPCMP $0, %YMMZERO, %YMM7, %k2 +- kord %k1, %k2, %k1 +- /* Each bit in K7 represents a NULL or a mismatch in YMM6 and +- YMM7. */ +- kord %k0, %k1, %k7 +- +- kord %k4, %k5, %k0 +- kord %k6, %k7, %k1 +- +- /* Test each mask (32 bits) individually because for VEC_SIZE +- == 32 is not possible to OR the four masks and keep all bits +- in a 64-bit integer register, differing from SSE2 strcmp +- where ORing is possible. */ +- kortestd %k0, %k1 +- je L(loop) +- ktestd %k4, %k4 ++ ++ VPMINU %YMM0, %YMM2, %YMM8 ++ VPMINU %YMM4, %YMM6, %YMM9 ++ ++ /* A zero CHAR in YMM8 means that there is a null CHAR. */ ++ VPMINU %YMM8, %YMM9, %YMM8 ++ ++ /* Each bit set in K1 represents a non-null CHAR in YMM8. */ ++ VPTESTM %YMM8, %YMM8, %k1 ++ ++ /* (YMM ^ YMM): A non-zero CHAR represents a mismatch. */ ++ vpxorq (%rdx), %YMM0, %YMM1 ++ vpxorq VEC_SIZE(%rdx), %YMM2, %YMM3 ++ vpxorq (VEC_SIZE * 2)(%rdx), %YMM4, %YMM5 ++ vpxorq (VEC_SIZE * 3)(%rdx), %YMM6, %YMM7 ++ ++ vporq %YMM1, %YMM3, %YMM9 ++ vporq %YMM5, %YMM7, %YMM10 ++ ++ /* A non-zero CHAR in YMM9 represents a mismatch. */ ++ vporq %YMM9, %YMM10, %YMM9 ++ ++ /* Each bit cleared in K0 represents a mismatch or a null CHAR. */ ++ VPCMP $0, %YMMZERO, %YMM9, %k0{%k1} ++ kmovd %k0, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif ++ je L(loop) ++ ++ /* Each bit set in K1 represents a non-null CHAR in YMM0. */ ++ VPTESTM %YMM0, %YMM0, %k1 ++ /* Each bit cleared in K0 represents a mismatch or a null CHAR ++ in YMM0 and (%rdx). */ ++ VPCMP $0, %YMMZERO, %YMM1, %k0{%k1} ++ kmovd %k0, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif + je L(test_vec) +- kmovd %k4, %edi +- tzcntl %edi, %ecx ++ tzcntl %ecx, %ecx + # ifdef USE_AS_WCSCMP + /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ + sall $2, %ecx +@@ -466,9 +458,18 @@ L(test_vec): + cmpq $VEC_SIZE, %r11 + jbe L(zero) + # endif +- ktestd %k5, %k5 ++ /* Each bit set in K1 represents a non-null CHAR in YMM2. */ ++ VPTESTM %YMM2, %YMM2, %k1 ++ /* Each bit cleared in K0 represents a mismatch or a null CHAR ++ in YMM2 and VEC_SIZE(%rdx). */ ++ VPCMP $0, %YMMZERO, %YMM3, %k0{%k1} ++ kmovd %k0, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif + je L(test_2_vec) +- kmovd %k5, %ecx + tzcntl %ecx, %edi + # ifdef USE_AS_WCSCMP + /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +@@ -512,9 +513,18 @@ L(test_2_vec): + cmpq $(VEC_SIZE * 2), %r11 + jbe L(zero) + # endif +- ktestd %k6, %k6 ++ /* Each bit set in K1 represents a non-null CHAR in YMM4. */ ++ VPTESTM %YMM4, %YMM4, %k1 ++ /* Each bit cleared in K0 represents a mismatch or a null CHAR ++ in YMM4 and (VEC_SIZE * 2)(%rdx). */ ++ VPCMP $0, %YMMZERO, %YMM5, %k0{%k1} ++ kmovd %k0, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif + je L(test_3_vec) +- kmovd %k6, %ecx + tzcntl %ecx, %edi + # ifdef USE_AS_WCSCMP + /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +@@ -558,8 +568,18 @@ L(test_3_vec): + cmpq $(VEC_SIZE * 3), %r11 + jbe L(zero) + # endif +- kmovd %k7, %esi +- tzcntl %esi, %ecx ++ /* Each bit set in K1 represents a non-null CHAR in YMM6. */ ++ VPTESTM %YMM6, %YMM6, %k1 ++ /* Each bit cleared in K0 represents a mismatch or a null CHAR ++ in YMM6 and (VEC_SIZE * 3)(%rdx). */ ++ VPCMP $0, %YMMZERO, %YMM7, %k0{%k1} ++ kmovd %k0, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif ++ tzcntl %ecx, %ecx + # ifdef USE_AS_WCSCMP + /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ + sall $2, %ecx +@@ -615,39 +635,51 @@ L(loop_cross_page): + + VMOVU (%rax, %r10), %YMM2 + VMOVU VEC_SIZE(%rax, %r10), %YMM3 +- VMOVU (%rdx, %r10), %YMM4 +- VMOVU VEC_SIZE(%rdx, %r10), %YMM5 +- +- VPCMP $4, %YMM4, %YMM2, %k0 +- VPCMP $0, %YMMZERO, %YMM2, %k1 +- VPCMP $0, %YMMZERO, %YMM4, %k2 +- kord %k1, %k2, %k1 +- /* Each bit in K1 represents a NULL or a mismatch in YMM2 and +- YMM4. */ +- kord %k0, %k1, %k1 +- +- VPCMP $4, %YMM5, %YMM3, %k3 +- VPCMP $0, %YMMZERO, %YMM3, %k4 +- VPCMP $0, %YMMZERO, %YMM5, %k5 +- kord %k4, %k5, %k4 +- /* Each bit in K3 represents a NULL or a mismatch in YMM3 and +- YMM5. */ +- kord %k3, %k4, %k3 ++ ++ /* Each bit set in K2 represents a non-null CHAR in YMM2. */ ++ VPTESTM %YMM2, %YMM2, %k2 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in YMM2 and 32 bytes at (%rdx, %r10). */ ++ VPCMP $0, (%rdx, %r10), %YMM2, %k1{%k2} ++ kmovd %k1, %r9d ++ /* Don't use subl since it is the lower 16/32 bits of RDI ++ below. */ ++ notl %r9d ++# ifdef USE_AS_WCSCMP ++ /* Only last 8 bits are valid. */ ++ andl $0xff, %r9d ++# endif ++ ++ /* Each bit set in K4 represents a non-null CHAR in YMM3. */ ++ VPTESTM %YMM3, %YMM3, %k4 ++ /* Each bit cleared in K3 represents a mismatch or a null CHAR ++ in YMM3 and 32 bytes at VEC_SIZE(%rdx, %r10). */ ++ VPCMP $0, VEC_SIZE(%rdx, %r10), %YMM3, %k3{%k4} ++ kmovd %k3, %edi ++# ifdef USE_AS_WCSCMP ++ /* Don't use subl since it is the upper 8 bits of EDI below. */ ++ notl %edi ++ andl $0xff, %edi ++# else ++ incl %edi ++# endif + + # ifdef USE_AS_WCSCMP +- /* NB: Each bit in K1/K3 represents 4-byte element. */ +- kshiftlw $8, %k3, %k2 ++ /* NB: Each bit in EDI/R9D represents 4-byte element. */ ++ sall $8, %edi + /* NB: Divide shift count by 4 since each bit in K1 represent 4 + bytes. */ + movl %ecx, %SHIFT_REG32 + sarl $2, %SHIFT_REG32 ++ ++ /* Each bit in EDI represents a null CHAR or a mismatch. */ ++ orl %r9d, %edi + # else +- kshiftlq $32, %k3, %k2 +-# endif ++ salq $32, %rdi + +- /* Each bit in K1 represents a NULL or a mismatch. */ +- korq %k1, %k2, %k1 +- kmovq %k1, %rdi ++ /* Each bit in RDI represents a null CHAR or a mismatch. */ ++ orq %r9, %rdi ++# endif + + /* Since ECX < VEC_SIZE * 2, simply skip the first ECX bytes. */ + shrxq %SHIFT_REG64, %rdi, %rdi +@@ -692,35 +724,45 @@ L(loop_cross_page_2_vec): + /* The first VEC_SIZE * 2 bytes match or are ignored. */ + VMOVU (VEC_SIZE * 2)(%rax, %r10), %YMM0 + VMOVU (VEC_SIZE * 3)(%rax, %r10), %YMM1 +- VMOVU (VEC_SIZE * 2)(%rdx, %r10), %YMM2 +- VMOVU (VEC_SIZE * 3)(%rdx, %r10), %YMM3 +- +- VPCMP $4, %YMM0, %YMM2, %k0 +- VPCMP $0, %YMMZERO, %YMM0, %k1 +- VPCMP $0, %YMMZERO, %YMM2, %k2 +- kord %k1, %k2, %k1 +- /* Each bit in K1 represents a NULL or a mismatch in YMM0 and +- YMM2. */ +- kord %k0, %k1, %k1 +- +- VPCMP $4, %YMM1, %YMM3, %k3 +- VPCMP $0, %YMMZERO, %YMM1, %k4 +- VPCMP $0, %YMMZERO, %YMM3, %k5 +- kord %k4, %k5, %k4 +- /* Each bit in K3 represents a NULL or a mismatch in YMM1 and +- YMM3. */ +- kord %k3, %k4, %k3 + ++ VPTESTM %YMM0, %YMM0, %k2 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rdx, %r10). */ ++ VPCMP $0, (VEC_SIZE * 2)(%rdx, %r10), %YMM0, %k1{%k2} ++ kmovd %k1, %r9d ++ /* Don't use subl since it is the lower 16/32 bits of RDI ++ below. */ ++ notl %r9d + # ifdef USE_AS_WCSCMP +- /* NB: Each bit in K1/K3 represents 4-byte element. */ +- kshiftlw $8, %k3, %k2 ++ /* Only last 8 bits are valid. */ ++ andl $0xff, %r9d ++# endif ++ ++ VPTESTM %YMM1, %YMM1, %k4 ++ /* Each bit cleared in K3 represents a mismatch or a null CHAR ++ in YMM1 and 32 bytes at (VEC_SIZE * 3)(%rdx, %r10). */ ++ VPCMP $0, (VEC_SIZE * 3)(%rdx, %r10), %YMM1, %k3{%k4} ++ kmovd %k3, %edi ++# ifdef USE_AS_WCSCMP ++ /* Don't use subl since it is the upper 8 bits of EDI below. */ ++ notl %edi ++ andl $0xff, %edi + # else +- kshiftlq $32, %k3, %k2 ++ incl %edi + # endif + +- /* Each bit in K1 represents a NULL or a mismatch. */ +- korq %k1, %k2, %k1 +- kmovq %k1, %rdi ++# ifdef USE_AS_WCSCMP ++ /* NB: Each bit in EDI/R9D represents 4-byte element. */ ++ sall $8, %edi ++ ++ /* Each bit in EDI represents a null CHAR or a mismatch. */ ++ orl %r9d, %edi ++# else ++ salq $32, %rdi ++ ++ /* Each bit in RDI represents a null CHAR or a mismatch. */ ++ orq %r9, %rdi ++# endif + + xorl %r8d, %r8d + /* If ECX > VEC_SIZE * 2, skip ECX - (VEC_SIZE * 2) bytes. */ +@@ -729,12 +771,15 @@ L(loop_cross_page_2_vec): + /* R8 has number of bytes skipped. */ + movl %ecx, %r8d + # ifdef USE_AS_WCSCMP +- /* NB: Divide shift count by 4 since each bit in K1 represent 4 ++ /* NB: Divide shift count by 4 since each bit in RDI represent 4 + bytes. */ + sarl $2, %ecx +-# endif ++ /* Skip ECX bytes. */ ++ shrl %cl, %edi ++# else + /* Skip ECX bytes. */ + shrq %cl, %rdi ++# endif + 1: + /* Before jumping back to the loop, set ESI to the number of + VEC_SIZE * 4 blocks before page crossing. */ +@@ -818,7 +863,7 @@ L(cross_page_loop): + movzbl (%rdi, %rdx), %eax + movzbl (%rsi, %rdx), %ecx + # endif +- /* Check null char. */ ++ /* Check null CHAR. */ + testl %eax, %eax + jne L(cross_page_loop) + /* Since %eax == 0, subtract is OK for both SIGNED and UNSIGNED +@@ -901,18 +946,17 @@ L(cross_page): + jg L(cross_page_1_vector) + L(loop_1_vector): + VMOVU (%rdi, %rdx), %YMM0 +- VMOVU (%rsi, %rdx), %YMM1 +- +- /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */ +- VPCMP $4, %YMM0, %YMM1, %k0 +- VPCMP $0, %YMMZERO, %YMM0, %k1 +- VPCMP $0, %YMMZERO, %YMM1, %k2 +- /* Each bit in K1 represents a NULL in YMM0 or YMM1. */ +- kord %k1, %k2, %k1 +- /* Each bit in K1 represents a NULL or a mismatch. */ +- kord %k0, %k1, %k1 ++ ++ VPTESTM %YMM0, %YMM0, %k2 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in YMM0 and 32 bytes at (%rsi, %rdx). */ ++ VPCMP $0, (%rsi, %rdx), %YMM0, %k1{%k2} + kmovd %k1, %ecx +- testl %ecx, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xff, %ecx ++# else ++ incl %ecx ++# endif + jne L(last_vector) + + addl $VEC_SIZE, %edx +@@ -931,18 +975,17 @@ L(cross_page_1_vector): + cmpl $(PAGE_SIZE - 16), %eax + jg L(cross_page_1_xmm) + VMOVU (%rdi, %rdx), %XMM0 +- VMOVU (%rsi, %rdx), %XMM1 +- +- /* Each bit in K0 represents a mismatch in XMM0 and XMM1. */ +- VPCMP $4, %XMM0, %XMM1, %k0 +- VPCMP $0, %XMMZERO, %XMM0, %k1 +- VPCMP $0, %XMMZERO, %XMM1, %k2 +- /* Each bit in K1 represents a NULL in XMM0 or XMM1. */ +- korw %k1, %k2, %k1 +- /* Each bit in K1 represents a NULL or a mismatch. */ +- korw %k0, %k1, %k1 +- kmovw %k1, %ecx +- testl %ecx, %ecx ++ ++ VPTESTM %YMM0, %YMM0, %k2 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in XMM0 and 16 bytes at (%rsi, %rdx). */ ++ VPCMP $0, (%rsi, %rdx), %XMM0, %k1{%k2} ++ kmovd %k1, %ecx ++# ifdef USE_AS_WCSCMP ++ subl $0xf, %ecx ++# else ++ subl $0xffff, %ecx ++# endif + jne L(last_vector) + + addl $16, %edx +@@ -965,25 +1008,16 @@ L(cross_page_1_xmm): + vmovq (%rdi, %rdx), %XMM0 + vmovq (%rsi, %rdx), %XMM1 + +- /* Each bit in K0 represents a mismatch in XMM0 and XMM1. */ +- VPCMP $4, %XMM0, %XMM1, %k0 +- VPCMP $0, %XMMZERO, %XMM0, %k1 +- VPCMP $0, %XMMZERO, %XMM1, %k2 +- /* Each bit in K1 represents a NULL in XMM0 or XMM1. */ +- kord %k1, %k2, %k1 +- /* Each bit in K1 represents a NULL or a mismatch. */ +- kord %k0, %k1, %k1 +- kmovd %k1, %ecx +- ++ VPTESTM %YMM0, %YMM0, %k2 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in XMM0 and XMM1. */ ++ VPCMP $0, %XMM1, %XMM0, %k1{%k2} ++ kmovb %k1, %ecx + # ifdef USE_AS_WCSCMP +- /* Only last 2 bits are valid. */ +- andl $0x3, %ecx ++ subl $0x3, %ecx + # else +- /* Only last 8 bits are valid. */ +- andl $0xff, %ecx ++ subl $0xff, %ecx + # endif +- +- testl %ecx, %ecx + jne L(last_vector) + + addl $8, %edx +@@ -1002,25 +1036,16 @@ L(cross_page_8bytes): + vmovd (%rdi, %rdx), %XMM0 + vmovd (%rsi, %rdx), %XMM1 + +- /* Each bit in K0 represents a mismatch in XMM0 and XMM1. */ +- VPCMP $4, %XMM0, %XMM1, %k0 +- VPCMP $0, %XMMZERO, %XMM0, %k1 +- VPCMP $0, %XMMZERO, %XMM1, %k2 +- /* Each bit in K1 represents a NULL in XMM0 or XMM1. */ +- kord %k1, %k2, %k1 +- /* Each bit in K1 represents a NULL or a mismatch. */ +- kord %k0, %k1, %k1 ++ VPTESTM %YMM0, %YMM0, %k2 ++ /* Each bit cleared in K1 represents a mismatch or a null CHAR ++ in XMM0 and XMM1. */ ++ VPCMP $0, %XMM1, %XMM0, %k1{%k2} + kmovd %k1, %ecx +- + # ifdef USE_AS_WCSCMP +- /* Only the last bit is valid. */ +- andl $0x1, %ecx ++ subl $0x1, %ecx + # else +- /* Only last 4 bits are valid. */ +- andl $0xf, %ecx ++ subl $0xf, %ecx + # endif +- +- testl %ecx, %ecx + jne L(last_vector) + + addl $4, %edx diff --git a/SOURCES/glibc-upstream-2.34-179.patch b/SOURCES/glibc-upstream-2.34-179.patch new file mode 100644 index 0000000..e9a4329 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-179.patch @@ -0,0 +1,85 @@ +commit a182bb7a3922404f79def09d79ef89678b4049f0 +Author: H.J. Lu +Date: Fri Oct 29 12:56:53 2021 -0700 + + x86-64: Remove Prefer_AVX2_STRCMP + + Remove Prefer_AVX2_STRCMP to enable EVEX strcmp. When comparing 2 32-byte + strings, EVEX strcmp has been improved to require 1 load, 1 VPTESTM, 1 + VPCMP, 1 KMOVD and 1 INCL instead of 2 loads, 3 VPCMPs, 2 KORDs, 1 KMOVD + and 1 TESTL while AVX2 strcmp requires 1 load, 2 VPCMPEQs, 1 VPMINU, 1 + VPMOVMSKB and 1 TESTL. EVEX strcmp is now faster than AVX2 strcmp by up + to 40% on Tiger Lake and Ice Lake. + + (cherry picked from commit 14dbbf46a007ae5df36646b51ad0c9e5f5259f30) + +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index de4e3c3b7258120d..f4d4049e391cbabd 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -574,14 +574,6 @@ disable_tsx: + if (CPU_FEATURE_USABLE_P (cpu_features, RTM)) + cpu_features->preferred[index_arch_Prefer_No_VZEROUPPER] + |= bit_arch_Prefer_No_VZEROUPPER; +- +- /* Since to compare 2 32-byte strings, 256-bit EVEX strcmp +- requires 2 loads, 3 VPCMPs and 2 KORDs while AVX2 strcmp +- requires 1 load, 2 VPCMPEQs, 1 VPMINU and 1 VPMOVMSKB, +- AVX2 strcmp is faster than EVEX strcmp. */ +- if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)) +- cpu_features->preferred[index_arch_Prefer_AVX2_STRCMP] +- |= bit_arch_Prefer_AVX2_STRCMP; + } + + /* Avoid avoid short distance REP MOVSB on processor with FSRM. */ +diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c +index 58f2fad4323d5d91..957db3ad229ba39f 100644 +--- a/sysdeps/x86/cpu-tunables.c ++++ b/sysdeps/x86/cpu-tunables.c +@@ -239,8 +239,6 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features, + Fast_Copy_Backward, + disable, 18); +- CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH +- (n, cpu_features, Prefer_AVX2_STRCMP, AVX2, disable, 18); + } + break; + case 19: +diff --git a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def +index 3bdc76cf71007948..8250bfcbecd29a9f 100644 +--- a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def ++++ b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def +@@ -31,5 +31,4 @@ BIT (Prefer_ERMS) + BIT (Prefer_No_AVX512) + BIT (MathVec_Prefer_No_AVX512) + BIT (Prefer_FSRM) +-BIT (Prefer_AVX2_STRCMP) + BIT (Avoid_Short_Distance_REP_MOVSB) +diff --git a/sysdeps/x86_64/multiarch/strcmp.c b/sysdeps/x86_64/multiarch/strcmp.c +index 62b7abeeee646ab4..7c2901bf44456259 100644 +--- a/sysdeps/x86_64/multiarch/strcmp.c ++++ b/sysdeps/x86_64/multiarch/strcmp.c +@@ -43,8 +43,7 @@ IFUNC_SELECTOR (void) + { + if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) + && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) +- && CPU_FEATURE_USABLE_P (cpu_features, BMI2) +- && !CPU_FEATURES_ARCH_P (cpu_features, Prefer_AVX2_STRCMP)) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI2)) + return OPTIMIZE (evex); + + if (CPU_FEATURE_USABLE_P (cpu_features, RTM)) +diff --git a/sysdeps/x86_64/multiarch/strncmp.c b/sysdeps/x86_64/multiarch/strncmp.c +index 60ba0fe356b31779..f94a421784bfe923 100644 +--- a/sysdeps/x86_64/multiarch/strncmp.c ++++ b/sysdeps/x86_64/multiarch/strncmp.c +@@ -43,8 +43,7 @@ IFUNC_SELECTOR (void) + { + if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) + && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) +- && CPU_FEATURE_USABLE_P (cpu_features, BMI2) +- && !CPU_FEATURES_ARCH_P (cpu_features, Prefer_AVX2_STRCMP)) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI2)) + return OPTIMIZE (evex); + + if (CPU_FEATURE_USABLE_P (cpu_features, RTM)) diff --git a/SOURCES/glibc-upstream-2.34-18.patch b/SOURCES/glibc-upstream-2.34-18.patch new file mode 100644 index 0000000..017225a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-18.patch @@ -0,0 +1,377 @@ +commit 005bafcf5b8a85d4c82831401f052747e160a7e8 +Author: Joseph Myers +Date: Wed Sep 8 12:42:06 2021 +0000 + + Update syscall lists for Linux 5.14 + + Linux 5.14 has two new syscalls, memfd_secret (on some architectures + only) and quotactl_fd. Update syscall-names.list and regenerate the + arch-syscall.h headers with build-many-glibcs.py update-syscalls. + + Tested with build-many-glibcs.py. + + (cherry picked from commit 89dc0372a9055e7ef86fe19be6201fa0b16b2f0e) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +index e9eb707d0ac022ed..bedab1abbac7f6c1 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +@@ -126,6 +126,7 @@ + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 ++#define __NR_memfd_secret 447 + #define __NR_migrate_pages 238 + #define __NR_mincore 232 + #define __NR_mkdirat 34 +@@ -187,6 +188,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +index bd6b7d4003a252be..91354ed9e29b8d15 100644 +--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +@@ -337,6 +337,7 @@ + #define __NR_pwritev2 521 + #define __NR_query_module 347 + #define __NR_quotactl 148 ++#define __NR_quotactl_fd 553 + #define __NR_read 3 + #define __NR_readahead 379 + #define __NR_readlink 58 +diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +index 10650549c1dcd100..ff5c7eb36db89494 100644 +--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +@@ -190,6 +190,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +index 85c9b236ce7862b6..5772333ceef6ce59 100644 +--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +@@ -244,6 +244,7 @@ + #define __NR_pwritev 362 + #define __NR_pwritev2 393 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 225 + #define __NR_readlink 85 +diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +index 24b0d1f94e5f99da..4af6d6202f6df7ae 100644 +--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +@@ -199,6 +199,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +index feb70abc3e1eb486..b07fc8549de34157 100644 +--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +@@ -231,6 +231,7 @@ + #define __NR_pwritev 316 + #define __NR_pwritev2 348 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 207 + #define __NR_readlink 85 +diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +index 3b1894a79b6fcfaf..6e4264698b5ce480 100644 +--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +@@ -183,6 +183,7 @@ + #define __NR_mbind 274 + #define __NR_membarrier 375 + #define __NR_memfd_create 356 ++#define __NR_memfd_secret 447 + #define __NR_migrate_pages 294 + #define __NR_mincore 218 + #define __NR_mkdir 39 +@@ -266,6 +267,7 @@ + #define __NR_pwritev2 379 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 225 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +index fb388a5fa4e9b28e..1ca706d7216a3902 100644 +--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +@@ -218,6 +218,7 @@ + #define __NR_pwritev 1320 + #define __NR_pwritev2 1349 + #define __NR_quotactl 1137 ++#define __NR_quotactl_fd 1467 + #define __NR_read 1026 + #define __NR_readahead 1216 + #define __NR_readlink 1092 +diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +index 7bc8c4af92cf2bd3..2f10f71f90d225ff 100644 +--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +@@ -254,6 +254,7 @@ + #define __NR_pwritev2 378 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 240 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +index cf560d3af47f19c5..0607a4dfa6adaa23 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +@@ -266,6 +266,7 @@ + #define __NR_pwritev2 394 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 225 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +index f346460f4880f10e..0055eec0b169ba96 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +@@ -251,6 +251,7 @@ + #define __NR_pwritev2 4362 + #define __NR_query_module 4187 + #define __NR_quotactl 4131 ++#define __NR_quotactl_fd 4443 + #define __NR_read 4003 + #define __NR_readahead 4223 + #define __NR_readdir 4089 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +index 38ed84997a2fa3d1..8e8e9f91ccfebfab 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +@@ -232,6 +232,7 @@ + #define __NR_pwritev2 6326 + #define __NR_query_module 6171 + #define __NR_quotactl 6172 ++#define __NR_quotactl_fd 6443 + #define __NR_read 6000 + #define __NR_readahead 6179 + #define __NR_readlink 6087 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +index e6a10c842178168c..ebd1545f806564bb 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +@@ -219,6 +219,7 @@ + #define __NR_pwritev2 5322 + #define __NR_query_module 5171 + #define __NR_quotactl 5172 ++#define __NR_quotactl_fd 5443 + #define __NR_read 5000 + #define __NR_readahead 5179 + #define __NR_readlink 5087 +diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +index 5314890289a1723f..2b530b1f88e4c52a 100644 +--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +@@ -198,6 +198,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +index b5b075853297cf2e..a32984a9c17315ee 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +@@ -260,6 +260,7 @@ + #define __NR_pwritev2 381 + #define __NR_query_module 166 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 191 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +index c77435ca61aba109..b01e464fb906d632 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +@@ -243,6 +243,7 @@ + #define __NR_pwritev2 381 + #define __NR_query_module 166 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 191 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index 70854bb9e360b40a..24d0a2c455caa630 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -179,6 +179,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index 83b9f31abaee9d52..e526c89ae7b285cc 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -187,6 +187,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +index b224c4aad4c9b1b1..d4c7b101b64c010f 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +@@ -251,6 +251,7 @@ + #define __NR_pwritev2 377 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 222 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +index 59864af125b437e4..bd8c78d7059a0f31 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +@@ -221,6 +221,7 @@ + #define __NR_pwritev2 377 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 222 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +index 23612c9092b9c2ee..3b6ac3d084d74638 100644 +--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +@@ -246,6 +246,7 @@ + #define __NR_pwritev 334 + #define __NR_pwritev2 382 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 225 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +index 380cddb2d8f9f443..35221a707e4d4a7c 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +@@ -252,6 +252,7 @@ + #define __NR_pwritev2 359 + #define __NR_query_module 184 + #define __NR_quotactl 165 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 205 + #define __NR_readdir 204 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +index 2175eeb6edcf7c34..5ba2b2050924df1c 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +@@ -231,6 +231,7 @@ + #define __NR_pwritev2 359 + #define __NR_query_module 184 + #define __NR_quotactl 165 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 205 + #define __NR_readdir 204 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 89c5895b9b6845ff..fd98893b0e44a606 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.13. +-kernel 5.13 ++# The list of system calls is current as of Linux 5.14. ++kernel 5.14 + + FAST_atomic_update + FAST_cmpxchg +@@ -247,6 +247,7 @@ madvise + mbind + membarrier + memfd_create ++memfd_secret + memory_ordering + migrate_pages + mincore +@@ -452,6 +453,7 @@ pwritev + pwritev2 + query_module + quotactl ++quotactl_fd + read + readahead + readdir +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +index 8e028eb62be2041d..26d6ac68a651ec98 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +@@ -154,6 +154,7 @@ + #define __NR_mbind 237 + #define __NR_membarrier 324 + #define __NR_memfd_create 319 ++#define __NR_memfd_secret 447 + #define __NR_migrate_pages 256 + #define __NR_mincore 27 + #define __NR_mkdir 83 +@@ -224,6 +225,7 @@ + #define __NR_pwritev2 328 + #define __NR_query_module 178 + #define __NR_quotactl 179 ++#define __NR_quotactl_fd 443 + #define __NR_read 0 + #define __NR_readahead 187 + #define __NR_readlink 89 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index 004feb53f1f38ced..36847783f6b91d5e 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -148,6 +148,7 @@ + #define __NR_mbind 1073742061 + #define __NR_membarrier 1073742148 + #define __NR_memfd_create 1073742143 ++#define __NR_memfd_secret 1073742271 + #define __NR_migrate_pages 1073742080 + #define __NR_mincore 1073741851 + #define __NR_mkdir 1073741907 +@@ -216,6 +217,7 @@ + #define __NR_pwritev 1073742359 + #define __NR_pwritev2 1073742371 + #define __NR_quotactl 1073742003 ++#define __NR_quotactl_fd 1073742267 + #define __NR_read 1073741824 + #define __NR_readahead 1073742011 + #define __NR_readlink 1073741913 diff --git a/SOURCES/glibc-upstream-2.34-180.patch b/SOURCES/glibc-upstream-2.34-180.patch new file mode 100644 index 0000000..9707cf2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-180.patch @@ -0,0 +1,48 @@ +commit 2e64237a8744dd50f9222293275fa52e7248ff76 +Author: Fangrui Song +Date: Tue Nov 2 20:59:52 2021 -0700 + + x86-64: Replace movzx with movzbl + + Clang cannot assemble movzx in the AT&T dialect mode. + + ../sysdeps/x86_64/strcmp.S:2232:16: error: invalid operand for instruction + movzx (%rsi), %ecx + ^~~~ + + Change movzx to movzbl, which follows the AT&T dialect and is used + elsewhere in the file. + + Reviewed-by: H.J. Lu + (cherry picked from commit 6720d36b6623c5e48c070d86acf61198b33e144e) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-sse42.S b/sysdeps/x86_64/multiarch/strcmp-sse42.S +index bc19547b09639071..6197a723b9e0606e 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-sse42.S ++++ b/sysdeps/x86_64/multiarch/strcmp-sse42.S +@@ -1771,8 +1771,8 @@ LABEL(strcmp_exitz): + .p2align 4 + // XXX Same as code above + LABEL(Byte0): +- movzx (%rsi), %ecx +- movzx (%rdi), %eax ++ movzbl (%rsi), %ecx ++ movzbl (%rdi), %eax + + #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L + leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx +diff --git a/sysdeps/x86_64/strcmp.S b/sysdeps/x86_64/strcmp.S +index 824e648230a15739..7f8a1bc756f86aee 100644 +--- a/sysdeps/x86_64/strcmp.S ++++ b/sysdeps/x86_64/strcmp.S +@@ -2232,8 +2232,8 @@ LABEL(strcmp_exitz): + + .p2align 4 + LABEL(Byte0): +- movzx (%rsi), %ecx +- movzx (%rdi), %eax ++ movzbl (%rsi), %ecx ++ movzbl (%rdi), %eax + + #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L + leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx diff --git a/SOURCES/glibc-upstream-2.34-181.patch b/SOURCES/glibc-upstream-2.34-181.patch new file mode 100644 index 0000000..36a401f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-181.patch @@ -0,0 +1,843 @@ +commit a7392db2ff2b9dd906500941ac6361dbe2211b0d +Author: Noah Goldstein +Date: Mon Nov 1 00:49:51 2021 -0500 + + x86: Optimize memmove-vec-unaligned-erms.S + + No bug. + + The optimizations are as follows: + + 1) Always align entry to 64 bytes. This makes behavior more + predictable and makes other frontend optimizations easier. + + 2) Make the L(more_8x_vec) cases 4k aliasing aware. This can have + significant benefits in the case that: + 0 < (dst - src) < [256, 512] + + 3) Align before `rep movsb`. For ERMS this is roughly a [0, 30%] + improvement and for FSRM [-10%, 25%]. + + In addition to these primary changes there is general cleanup + throughout to optimize the aligning routines and control flow logic. + + Signed-off-by: Noah Goldstein + Reviewed-by: H.J. Lu + (cherry picked from commit a6b7502ec0c2da89a7437f43171f160d713e39c6) + +diff --git a/sysdeps/x86_64/memmove.S b/sysdeps/x86_64/memmove.S +index db106a7a1f23f268..b2b318084823dceb 100644 +--- a/sysdeps/x86_64/memmove.S ++++ b/sysdeps/x86_64/memmove.S +@@ -25,7 +25,7 @@ + /* Use movups and movaps for smaller code sizes. */ + #define VMOVU movups + #define VMOVA movaps +- ++#define MOV_SIZE 3 + #define SECTION(p) p + + #ifdef USE_MULTIARCH +diff --git a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S +index 1ec1962e861dbf63..67a55f0c85af841c 100644 +--- a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S ++++ b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S +@@ -4,7 +4,7 @@ + # define VMOVNT vmovntdq + # define VMOVU vmovdqu + # define VMOVA vmovdqa +- ++# define MOV_SIZE 4 + # define ZERO_UPPER_VEC_REGISTERS_RETURN \ + ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST + +diff --git a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S +index e195e93f153c9512..975ae6c0515b83cb 100644 +--- a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S +@@ -4,7 +4,7 @@ + # define VMOVNT vmovntdq + # define VMOVU vmovdqu + # define VMOVA vmovdqa +- ++# define MOV_SIZE 4 + # define SECTION(p) p##.avx + # define MEMMOVE_SYMBOL(p,s) p##_avx_##s + +diff --git a/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S +index 848848ab39ff9326..0fa7126830af7acb 100644 +--- a/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S +@@ -25,7 +25,7 @@ + # define VMOVU vmovdqu64 + # define VMOVA vmovdqa64 + # define VZEROUPPER +- ++# define MOV_SIZE 6 + # define SECTION(p) p##.evex512 + # define MEMMOVE_SYMBOL(p,s) p##_avx512_##s + +diff --git a/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S +index 0cbce8f944da51a0..88715441feaaccf5 100644 +--- a/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S +@@ -25,7 +25,7 @@ + # define VMOVU vmovdqu64 + # define VMOVA vmovdqa64 + # define VZEROUPPER +- ++# define MOV_SIZE 6 + # define SECTION(p) p##.evex + # define MEMMOVE_SYMBOL(p,s) p##_evex_##s + +diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +index abde8438d41f2320..7b27cbdda5fb99f7 100644 +--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +@@ -76,6 +76,25 @@ + # endif + #endif + ++/* Whether to align before movsb. Ultimately we want 64 byte ++ align and not worth it to load 4x VEC for VEC_SIZE == 16. */ ++#define ALIGN_MOVSB (VEC_SIZE > 16) ++/* Number of bytes to align movsb to. */ ++#define MOVSB_ALIGN_TO 64 ++ ++#define SMALL_MOV_SIZE (MOV_SIZE <= 4) ++#define LARGE_MOV_SIZE (MOV_SIZE > 4) ++ ++#if SMALL_MOV_SIZE + LARGE_MOV_SIZE != 1 ++# error MOV_SIZE Unknown ++#endif ++ ++#if LARGE_MOV_SIZE ++# define SMALL_SIZE_OFFSET (4) ++#else ++# define SMALL_SIZE_OFFSET (0) ++#endif ++ + #ifndef PAGE_SIZE + # define PAGE_SIZE 4096 + #endif +@@ -199,25 +218,21 @@ L(start): + # endif + cmp $VEC_SIZE, %RDX_LP + jb L(less_vec) ++ /* Load regardless. */ ++ VMOVU (%rsi), %VEC(0) + cmp $(VEC_SIZE * 2), %RDX_LP + ja L(more_2x_vec) +-#if !defined USE_MULTIARCH || !IS_IN (libc) +-L(last_2x_vec): +-#endif + /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */ +- VMOVU (%rsi), %VEC(0) + VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(1) + VMOVU %VEC(0), (%rdi) + VMOVU %VEC(1), -VEC_SIZE(%rdi,%rdx) +-#if !defined USE_MULTIARCH || !IS_IN (libc) +-L(nop): +- ret ++#if !(defined USE_MULTIARCH && IS_IN (libc)) ++ ZERO_UPPER_VEC_REGISTERS_RETURN + #else + VZEROUPPER_RETURN + #endif + #if defined USE_MULTIARCH && IS_IN (libc) + END (MEMMOVE_SYMBOL (__memmove, unaligned)) +- + # if VEC_SIZE == 16 + ENTRY (__mempcpy_chk_erms) + cmp %RDX_LP, %RCX_LP +@@ -289,7 +304,7 @@ ENTRY (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned_erms)) + END (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned_erms)) + # endif + +-ENTRY (MEMMOVE_SYMBOL (__memmove, unaligned_erms)) ++ENTRY_P2ALIGN (MEMMOVE_SYMBOL (__memmove, unaligned_erms), 6) + movq %rdi, %rax + L(start_erms): + # ifdef __ILP32__ +@@ -298,310 +313,448 @@ L(start_erms): + # endif + cmp $VEC_SIZE, %RDX_LP + jb L(less_vec) ++ /* Load regardless. */ ++ VMOVU (%rsi), %VEC(0) + cmp $(VEC_SIZE * 2), %RDX_LP + ja L(movsb_more_2x_vec) +-L(last_2x_vec): +- /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */ +- VMOVU (%rsi), %VEC(0) +- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(1) ++ /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. ++ */ ++ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(1) + VMOVU %VEC(0), (%rdi) +- VMOVU %VEC(1), -VEC_SIZE(%rdi,%rdx) ++ VMOVU %VEC(1), -VEC_SIZE(%rdi, %rdx) + L(return): +-#if VEC_SIZE > 16 ++# if VEC_SIZE > 16 + ZERO_UPPER_VEC_REGISTERS_RETURN +-#else ++# else + ret ++# endif + #endif + +-L(movsb): +- cmp __x86_rep_movsb_stop_threshold(%rip), %RDX_LP +- jae L(more_8x_vec) +- cmpq %rsi, %rdi +- jb 1f +- /* Source == destination is less common. */ +- je L(nop) +- leaq (%rsi,%rdx), %r9 +- cmpq %r9, %rdi +- /* Avoid slow backward REP MOVSB. */ +- jb L(more_8x_vec_backward) +-# if AVOID_SHORT_DISTANCE_REP_MOVSB +- testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) +- jz 3f +- movq %rdi, %rcx +- subq %rsi, %rcx +- jmp 2f +-# endif +-1: +-# if AVOID_SHORT_DISTANCE_REP_MOVSB +- testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) +- jz 3f +- movq %rsi, %rcx +- subq %rdi, %rcx +-2: +-/* Avoid "rep movsb" if RCX, the distance between source and destination, +- is N*4GB + [1..63] with N >= 0. */ +- cmpl $63, %ecx +- jbe L(more_2x_vec) /* Avoid "rep movsb" if ECX <= 63. */ +-3: +-# endif +- mov %RDX_LP, %RCX_LP +- rep movsb +-L(nop): ++#if LARGE_MOV_SIZE ++ /* If LARGE_MOV_SIZE this fits in the aligning bytes between the ++ ENTRY block and L(less_vec). */ ++ .p2align 4,, 8 ++L(between_4_7): ++ /* From 4 to 7. No branch when size == 4. */ ++ movl (%rsi), %ecx ++ movl (%rsi, %rdx), %esi ++ movl %ecx, (%rdi) ++ movl %esi, (%rdi, %rdx) + ret + #endif + ++ .p2align 4 + L(less_vec): + /* Less than 1 VEC. */ + #if VEC_SIZE != 16 && VEC_SIZE != 32 && VEC_SIZE != 64 + # error Unsupported VEC_SIZE! + #endif + #if VEC_SIZE > 32 +- cmpb $32, %dl ++ cmpl $32, %edx + jae L(between_32_63) + #endif + #if VEC_SIZE > 16 +- cmpb $16, %dl ++ cmpl $16, %edx + jae L(between_16_31) + #endif +- cmpb $8, %dl ++ cmpl $8, %edx + jae L(between_8_15) +- cmpb $4, %dl ++#if SMALL_MOV_SIZE ++ cmpl $4, %edx ++#else ++ subq $4, %rdx ++#endif + jae L(between_4_7) +- cmpb $1, %dl +- ja L(between_2_3) +- jb 1f +- movzbl (%rsi), %ecx ++ cmpl $(1 - SMALL_SIZE_OFFSET), %edx ++ jl L(copy_0) ++ movb (%rsi), %cl ++ je L(copy_1) ++ movzwl (-2 + SMALL_SIZE_OFFSET)(%rsi, %rdx), %esi ++ movw %si, (-2 + SMALL_SIZE_OFFSET)(%rdi, %rdx) ++L(copy_1): + movb %cl, (%rdi) +-1: ++L(copy_0): + ret ++ ++#if SMALL_MOV_SIZE ++ .p2align 4,, 8 ++L(between_4_7): ++ /* From 4 to 7. No branch when size == 4. */ ++ movl -4(%rsi, %rdx), %ecx ++ movl (%rsi), %esi ++ movl %ecx, -4(%rdi, %rdx) ++ movl %esi, (%rdi) ++ ret ++#endif ++ ++#if VEC_SIZE > 16 ++ /* From 16 to 31. No branch when size == 16. */ ++ .p2align 4,, 8 ++L(between_16_31): ++ vmovdqu (%rsi), %xmm0 ++ vmovdqu -16(%rsi, %rdx), %xmm1 ++ vmovdqu %xmm0, (%rdi) ++ vmovdqu %xmm1, -16(%rdi, %rdx) ++ /* No ymm registers have been touched. */ ++ ret ++#endif ++ + #if VEC_SIZE > 32 ++ .p2align 4,, 10 + L(between_32_63): + /* From 32 to 63. No branch when size == 32. */ + VMOVU (%rsi), %YMM0 +- VMOVU -32(%rsi,%rdx), %YMM1 ++ VMOVU -32(%rsi, %rdx), %YMM1 + VMOVU %YMM0, (%rdi) +- VMOVU %YMM1, -32(%rdi,%rdx) +- VZEROUPPER_RETURN +-#endif +-#if VEC_SIZE > 16 +- /* From 16 to 31. No branch when size == 16. */ +-L(between_16_31): +- VMOVU (%rsi), %XMM0 +- VMOVU -16(%rsi,%rdx), %XMM1 +- VMOVU %XMM0, (%rdi) +- VMOVU %XMM1, -16(%rdi,%rdx) ++ VMOVU %YMM1, -32(%rdi, %rdx) + VZEROUPPER_RETURN + #endif ++ ++ .p2align 4,, 10 + L(between_8_15): + /* From 8 to 15. No branch when size == 8. */ +- movq -8(%rsi,%rdx), %rcx ++ movq -8(%rsi, %rdx), %rcx + movq (%rsi), %rsi +- movq %rcx, -8(%rdi,%rdx) + movq %rsi, (%rdi) ++ movq %rcx, -8(%rdi, %rdx) + ret +-L(between_4_7): +- /* From 4 to 7. No branch when size == 4. */ +- movl -4(%rsi,%rdx), %ecx +- movl (%rsi), %esi +- movl %ecx, -4(%rdi,%rdx) +- movl %esi, (%rdi) +- ret +-L(between_2_3): +- /* From 2 to 3. No branch when size == 2. */ +- movzwl -2(%rsi,%rdx), %ecx +- movzwl (%rsi), %esi +- movw %cx, -2(%rdi,%rdx) +- movw %si, (%rdi) +- ret + ++ .p2align 4,, 10 ++L(last_4x_vec): ++ /* Copy from 2 * VEC + 1 to 4 * VEC, inclusively. */ ++ ++ /* VEC(0) and VEC(1) have already been loaded. */ ++ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(2) ++ VMOVU -(VEC_SIZE * 2)(%rsi, %rdx), %VEC(3) ++ VMOVU %VEC(0), (%rdi) ++ VMOVU %VEC(1), VEC_SIZE(%rdi) ++ VMOVU %VEC(2), -VEC_SIZE(%rdi, %rdx) ++ VMOVU %VEC(3), -(VEC_SIZE * 2)(%rdi, %rdx) ++ VZEROUPPER_RETURN ++ ++ .p2align 4 + #if defined USE_MULTIARCH && IS_IN (libc) + L(movsb_more_2x_vec): + cmp __x86_rep_movsb_threshold(%rip), %RDX_LP + ja L(movsb) + #endif + L(more_2x_vec): +- /* More than 2 * VEC and there may be overlap between destination +- and source. */ ++ /* More than 2 * VEC and there may be overlap between ++ destination and source. */ + cmpq $(VEC_SIZE * 8), %rdx + ja L(more_8x_vec) ++ /* Load VEC(1) regardless. VEC(0) has already been loaded. */ ++ VMOVU VEC_SIZE(%rsi), %VEC(1) + cmpq $(VEC_SIZE * 4), %rdx + jbe L(last_4x_vec) +- /* Copy from 4 * VEC + 1 to 8 * VEC, inclusively. */ +- VMOVU (%rsi), %VEC(0) +- VMOVU VEC_SIZE(%rsi), %VEC(1) ++ /* Copy from 4 * VEC + 1 to 8 * VEC, inclusively. */ + VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2) + VMOVU (VEC_SIZE * 3)(%rsi), %VEC(3) +- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(4) +- VMOVU -(VEC_SIZE * 2)(%rsi,%rdx), %VEC(5) +- VMOVU -(VEC_SIZE * 3)(%rsi,%rdx), %VEC(6) +- VMOVU -(VEC_SIZE * 4)(%rsi,%rdx), %VEC(7) ++ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(4) ++ VMOVU -(VEC_SIZE * 2)(%rsi, %rdx), %VEC(5) ++ VMOVU -(VEC_SIZE * 3)(%rsi, %rdx), %VEC(6) ++ VMOVU -(VEC_SIZE * 4)(%rsi, %rdx), %VEC(7) + VMOVU %VEC(0), (%rdi) + VMOVU %VEC(1), VEC_SIZE(%rdi) + VMOVU %VEC(2), (VEC_SIZE * 2)(%rdi) + VMOVU %VEC(3), (VEC_SIZE * 3)(%rdi) +- VMOVU %VEC(4), -VEC_SIZE(%rdi,%rdx) +- VMOVU %VEC(5), -(VEC_SIZE * 2)(%rdi,%rdx) +- VMOVU %VEC(6), -(VEC_SIZE * 3)(%rdi,%rdx) +- VMOVU %VEC(7), -(VEC_SIZE * 4)(%rdi,%rdx) +- VZEROUPPER_RETURN +-L(last_4x_vec): +- /* Copy from 2 * VEC + 1 to 4 * VEC, inclusively. */ +- VMOVU (%rsi), %VEC(0) +- VMOVU VEC_SIZE(%rsi), %VEC(1) +- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(2) +- VMOVU -(VEC_SIZE * 2)(%rsi,%rdx), %VEC(3) +- VMOVU %VEC(0), (%rdi) +- VMOVU %VEC(1), VEC_SIZE(%rdi) +- VMOVU %VEC(2), -VEC_SIZE(%rdi,%rdx) +- VMOVU %VEC(3), -(VEC_SIZE * 2)(%rdi,%rdx) ++ VMOVU %VEC(4), -VEC_SIZE(%rdi, %rdx) ++ VMOVU %VEC(5), -(VEC_SIZE * 2)(%rdi, %rdx) ++ VMOVU %VEC(6), -(VEC_SIZE * 3)(%rdi, %rdx) ++ VMOVU %VEC(7), -(VEC_SIZE * 4)(%rdi, %rdx) + VZEROUPPER_RETURN + ++ .p2align 4,, 4 + L(more_8x_vec): ++ movq %rdi, %rcx ++ subq %rsi, %rcx ++ /* Go to backwards temporal copy if overlap no matter what as ++ backward REP MOVSB is slow and we don't want to use NT stores if ++ there is overlap. */ ++ cmpq %rdx, %rcx ++ /* L(more_8x_vec_backward_check_nop) checks for src == dst. */ ++ jb L(more_8x_vec_backward_check_nop) + /* Check if non-temporal move candidate. */ + #if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc) + /* Check non-temporal store threshold. */ +- cmp __x86_shared_non_temporal_threshold(%rip), %RDX_LP ++ cmp __x86_shared_non_temporal_threshold(%rip), %RDX_LP + ja L(large_memcpy_2x) + #endif +- /* Entry if rdx is greater than non-temporal threshold but there +- is overlap. */ ++ /* To reach this point there cannot be overlap and dst > src. So ++ check for overlap and src > dst in which case correctness ++ requires forward copy. Otherwise decide between backward/forward ++ copy depending on address aliasing. */ ++ ++ /* Entry if rdx is greater than __x86_rep_movsb_stop_threshold ++ but less than __x86_shared_non_temporal_threshold. */ + L(more_8x_vec_check): +- cmpq %rsi, %rdi +- ja L(more_8x_vec_backward) +- /* Source == destination is less common. */ +- je L(nop) +- /* Load the first VEC and last 4 * VEC to support overlapping +- addresses. */ +- VMOVU (%rsi), %VEC(4) ++ /* rcx contains dst - src. Add back length (rdx). */ ++ leaq (%rcx, %rdx), %r8 ++ /* If r8 has different sign than rcx then there is overlap so we ++ must do forward copy. */ ++ xorq %rcx, %r8 ++ /* Isolate just sign bit of r8. */ ++ shrq $63, %r8 ++ /* Get 4k difference dst - src. */ ++ andl $(PAGE_SIZE - 256), %ecx ++ /* If r8 is non-zero must do foward for correctness. Otherwise ++ if ecx is non-zero there is 4k False Alaising so do backward ++ copy. */ ++ addl %r8d, %ecx ++ jz L(more_8x_vec_backward) ++ ++ /* if rdx is greater than __x86_shared_non_temporal_threshold ++ but there is overlap, or from short distance movsb. */ ++L(more_8x_vec_forward): ++ /* Load first and last 4 * VEC to support overlapping addresses. ++ */ ++ ++ /* First vec was already loaded into VEC(0). */ + VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(5) + VMOVU -(VEC_SIZE * 2)(%rsi, %rdx), %VEC(6) ++ /* Save begining of dst. */ ++ movq %rdi, %rcx ++ /* Align dst to VEC_SIZE - 1. */ ++ orq $(VEC_SIZE - 1), %rdi + VMOVU -(VEC_SIZE * 3)(%rsi, %rdx), %VEC(7) + VMOVU -(VEC_SIZE * 4)(%rsi, %rdx), %VEC(8) +- /* Save start and stop of the destination buffer. */ +- movq %rdi, %r11 +- leaq -VEC_SIZE(%rdi, %rdx), %rcx +- /* Align destination for aligned stores in the loop. Compute +- how much destination is misaligned. */ +- movq %rdi, %r8 +- andq $(VEC_SIZE - 1), %r8 +- /* Get the negative of offset for alignment. */ +- subq $VEC_SIZE, %r8 +- /* Adjust source. */ +- subq %r8, %rsi +- /* Adjust destination which should be aligned now. */ +- subq %r8, %rdi +- /* Adjust length. */ +- addq %r8, %rdx + +- .p2align 4 ++ /* Subtract dst from src. Add back after dst aligned. */ ++ subq %rcx, %rsi ++ /* Finish aligning dst. */ ++ incq %rdi ++ /* Restore src adjusted with new value for aligned dst. */ ++ addq %rdi, %rsi ++ /* Store end of buffer minus tail in rdx. */ ++ leaq (VEC_SIZE * -4)(%rcx, %rdx), %rdx ++ ++ /* Dont use multi-byte nop to align. */ ++ .p2align 4,, 11 + L(loop_4x_vec_forward): + /* Copy 4 * VEC a time forward. */ +- VMOVU (%rsi), %VEC(0) +- VMOVU VEC_SIZE(%rsi), %VEC(1) +- VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2) +- VMOVU (VEC_SIZE * 3)(%rsi), %VEC(3) ++ VMOVU (%rsi), %VEC(1) ++ VMOVU VEC_SIZE(%rsi), %VEC(2) ++ VMOVU (VEC_SIZE * 2)(%rsi), %VEC(3) ++ VMOVU (VEC_SIZE * 3)(%rsi), %VEC(4) + subq $-(VEC_SIZE * 4), %rsi +- addq $-(VEC_SIZE * 4), %rdx +- VMOVA %VEC(0), (%rdi) +- VMOVA %VEC(1), VEC_SIZE(%rdi) +- VMOVA %VEC(2), (VEC_SIZE * 2)(%rdi) +- VMOVA %VEC(3), (VEC_SIZE * 3)(%rdi) ++ VMOVA %VEC(1), (%rdi) ++ VMOVA %VEC(2), VEC_SIZE(%rdi) ++ VMOVA %VEC(3), (VEC_SIZE * 2)(%rdi) ++ VMOVA %VEC(4), (VEC_SIZE * 3)(%rdi) + subq $-(VEC_SIZE * 4), %rdi +- cmpq $(VEC_SIZE * 4), %rdx ++ cmpq %rdi, %rdx + ja L(loop_4x_vec_forward) + /* Store the last 4 * VEC. */ +- VMOVU %VEC(5), (%rcx) +- VMOVU %VEC(6), -VEC_SIZE(%rcx) +- VMOVU %VEC(7), -(VEC_SIZE * 2)(%rcx) +- VMOVU %VEC(8), -(VEC_SIZE * 3)(%rcx) ++ VMOVU %VEC(5), (VEC_SIZE * 3)(%rdx) ++ VMOVU %VEC(6), (VEC_SIZE * 2)(%rdx) ++ VMOVU %VEC(7), VEC_SIZE(%rdx) ++ VMOVU %VEC(8), (%rdx) + /* Store the first VEC. */ +- VMOVU %VEC(4), (%r11) ++ VMOVU %VEC(0), (%rcx) ++ /* Keep L(nop_backward) target close to jmp for 2-byte encoding. ++ */ ++L(nop_backward): + VZEROUPPER_RETURN + ++ .p2align 4,, 8 ++L(more_8x_vec_backward_check_nop): ++ /* rcx contains dst - src. Test for dst == src to skip all of ++ memmove. */ ++ testq %rcx, %rcx ++ jz L(nop_backward) + L(more_8x_vec_backward): + /* Load the first 4 * VEC and last VEC to support overlapping + addresses. */ +- VMOVU (%rsi), %VEC(4) ++ ++ /* First vec was also loaded into VEC(0). */ + VMOVU VEC_SIZE(%rsi), %VEC(5) + VMOVU (VEC_SIZE * 2)(%rsi), %VEC(6) ++ /* Begining of region for 4x backward copy stored in rcx. */ ++ leaq (VEC_SIZE * -4 + -1)(%rdi, %rdx), %rcx + VMOVU (VEC_SIZE * 3)(%rsi), %VEC(7) +- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(8) +- /* Save stop of the destination buffer. */ +- leaq -VEC_SIZE(%rdi, %rdx), %r11 +- /* Align destination end for aligned stores in the loop. Compute +- how much destination end is misaligned. */ +- leaq -VEC_SIZE(%rsi, %rdx), %rcx +- movq %r11, %r9 +- movq %r11, %r8 +- andq $(VEC_SIZE - 1), %r8 +- /* Adjust source. */ +- subq %r8, %rcx +- /* Adjust the end of destination which should be aligned now. */ +- subq %r8, %r9 +- /* Adjust length. */ +- subq %r8, %rdx +- +- .p2align 4 ++ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(8) ++ /* Subtract dst from src. Add back after dst aligned. */ ++ subq %rdi, %rsi ++ /* Align dst. */ ++ andq $-(VEC_SIZE), %rcx ++ /* Restore src. */ ++ addq %rcx, %rsi ++ ++ /* Don't use multi-byte nop to align. */ ++ .p2align 4,, 11 + L(loop_4x_vec_backward): + /* Copy 4 * VEC a time backward. */ +- VMOVU (%rcx), %VEC(0) +- VMOVU -VEC_SIZE(%rcx), %VEC(1) +- VMOVU -(VEC_SIZE * 2)(%rcx), %VEC(2) +- VMOVU -(VEC_SIZE * 3)(%rcx), %VEC(3) +- addq $-(VEC_SIZE * 4), %rcx +- addq $-(VEC_SIZE * 4), %rdx +- VMOVA %VEC(0), (%r9) +- VMOVA %VEC(1), -VEC_SIZE(%r9) +- VMOVA %VEC(2), -(VEC_SIZE * 2)(%r9) +- VMOVA %VEC(3), -(VEC_SIZE * 3)(%r9) +- addq $-(VEC_SIZE * 4), %r9 +- cmpq $(VEC_SIZE * 4), %rdx +- ja L(loop_4x_vec_backward) ++ VMOVU (VEC_SIZE * 3)(%rsi), %VEC(1) ++ VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2) ++ VMOVU (VEC_SIZE * 1)(%rsi), %VEC(3) ++ VMOVU (VEC_SIZE * 0)(%rsi), %VEC(4) ++ addq $(VEC_SIZE * -4), %rsi ++ VMOVA %VEC(1), (VEC_SIZE * 3)(%rcx) ++ VMOVA %VEC(2), (VEC_SIZE * 2)(%rcx) ++ VMOVA %VEC(3), (VEC_SIZE * 1)(%rcx) ++ VMOVA %VEC(4), (VEC_SIZE * 0)(%rcx) ++ addq $(VEC_SIZE * -4), %rcx ++ cmpq %rcx, %rdi ++ jb L(loop_4x_vec_backward) + /* Store the first 4 * VEC. */ +- VMOVU %VEC(4), (%rdi) ++ VMOVU %VEC(0), (%rdi) + VMOVU %VEC(5), VEC_SIZE(%rdi) + VMOVU %VEC(6), (VEC_SIZE * 2)(%rdi) + VMOVU %VEC(7), (VEC_SIZE * 3)(%rdi) + /* Store the last VEC. */ +- VMOVU %VEC(8), (%r11) ++ VMOVU %VEC(8), -VEC_SIZE(%rdx, %rdi) ++ VZEROUPPER_RETURN ++ ++#if defined USE_MULTIARCH && IS_IN (libc) ++ /* L(skip_short_movsb_check) is only used with ERMS. Not for ++ FSRM. */ ++ .p2align 5,, 16 ++# if ALIGN_MOVSB ++L(skip_short_movsb_check): ++# if MOVSB_ALIGN_TO > VEC_SIZE ++ VMOVU VEC_SIZE(%rsi), %VEC(1) ++# endif ++# if MOVSB_ALIGN_TO > (VEC_SIZE * 2) ++# error Unsupported MOVSB_ALIGN_TO ++# endif ++ /* If CPU does not have FSRM two options for aligning. Align src ++ if dst and src 4k alias. Otherwise align dst. */ ++ testl $(PAGE_SIZE - 512), %ecx ++ jnz L(movsb_align_dst) ++ /* Fall through. dst and src 4k alias. It's better to align src ++ here because the bottleneck will be loads dues to the false ++ dependency on dst. */ ++ ++ /* rcx already has dst - src. */ ++ movq %rcx, %r9 ++ /* Add src to len. Subtract back after src aligned. -1 because ++ src is initially aligned to MOVSB_ALIGN_TO - 1. */ ++ leaq -1(%rsi, %rdx), %rcx ++ /* Inclusively align src to MOVSB_ALIGN_TO - 1. */ ++ orq $(MOVSB_ALIGN_TO - 1), %rsi ++ /* Restore dst and len adjusted with new values for aligned dst. ++ */ ++ leaq 1(%rsi, %r9), %rdi ++ subq %rsi, %rcx ++ /* Finish aligning src. */ ++ incq %rsi ++ ++ rep movsb ++ ++ VMOVU %VEC(0), (%r8) ++# if MOVSB_ALIGN_TO > VEC_SIZE ++ VMOVU %VEC(1), VEC_SIZE(%r8) ++# endif + VZEROUPPER_RETURN ++# endif ++ ++ .p2align 4,, 12 ++L(movsb): ++ movq %rdi, %rcx ++ subq %rsi, %rcx ++ /* Go to backwards temporal copy if overlap no matter what as ++ backward REP MOVSB is slow and we don't want to use NT stores if ++ there is overlap. */ ++ cmpq %rdx, %rcx ++ /* L(more_8x_vec_backward_check_nop) checks for src == dst. */ ++ jb L(more_8x_vec_backward_check_nop) ++# if ALIGN_MOVSB ++ /* Save dest for storing aligning VECs later. */ ++ movq %rdi, %r8 ++# endif ++ /* If above __x86_rep_movsb_stop_threshold most likely is ++ candidate for NT moves aswell. */ ++ cmp __x86_rep_movsb_stop_threshold(%rip), %RDX_LP ++ jae L(large_memcpy_2x_check) ++# if AVOID_SHORT_DISTANCE_REP_MOVSB || ALIGN_MOVSB ++ /* Only avoid short movsb if CPU has FSRM. */ ++ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) ++ jz L(skip_short_movsb_check) ++# if AVOID_SHORT_DISTANCE_REP_MOVSB ++ /* Avoid "rep movsb" if RCX, the distance between source and ++ destination, is N*4GB + [1..63] with N >= 0. */ ++ ++ /* ecx contains dst - src. Early check for backward copy ++ conditions means only case of slow movsb with src = dst + [0, ++ 63] is ecx in [-63, 0]. Use unsigned comparison with -64 check ++ for that case. */ ++ cmpl $-64, %ecx ++ ja L(more_8x_vec_forward) ++# endif ++# endif ++# if ALIGN_MOVSB ++# if MOVSB_ALIGN_TO > VEC_SIZE ++ VMOVU VEC_SIZE(%rsi), %VEC(1) ++# endif ++# if MOVSB_ALIGN_TO > (VEC_SIZE * 2) ++# error Unsupported MOVSB_ALIGN_TO ++# endif ++ /* Fall through means cpu has FSRM. In that case exclusively ++ align destination. */ ++L(movsb_align_dst): ++ /* Subtract dst from src. Add back after dst aligned. */ ++ subq %rdi, %rsi ++ /* Exclusively align dst to MOVSB_ALIGN_TO (64). */ ++ addq $(MOVSB_ALIGN_TO - 1), %rdi ++ /* Add dst to len. Subtract back after dst aligned. */ ++ leaq (%r8, %rdx), %rcx ++ /* Finish aligning dst. */ ++ andq $-(MOVSB_ALIGN_TO), %rdi ++ /* Restore src and len adjusted with new values for aligned dst. ++ */ ++ addq %rdi, %rsi ++ subq %rdi, %rcx ++ ++ rep movsb ++ ++ /* Store VECs loaded for aligning. */ ++ VMOVU %VEC(0), (%r8) ++# if MOVSB_ALIGN_TO > VEC_SIZE ++ VMOVU %VEC(1), VEC_SIZE(%r8) ++# endif ++ VZEROUPPER_RETURN ++# else /* !ALIGN_MOVSB. */ ++L(skip_short_movsb_check): ++ mov %RDX_LP, %RCX_LP ++ rep movsb ++ ret ++# endif ++#endif + ++ .p2align 4,, 10 + #if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc) +- .p2align 4 ++L(large_memcpy_2x_check): ++ cmp __x86_rep_movsb_threshold(%rip), %RDX_LP ++ jb L(more_8x_vec_check) + L(large_memcpy_2x): +- /* Compute absolute value of difference between source and +- destination. */ +- movq %rdi, %r9 +- subq %rsi, %r9 +- movq %r9, %r8 +- leaq -1(%r9), %rcx +- sarq $63, %r8 +- xorq %r8, %r9 +- subq %r8, %r9 +- /* Don't use non-temporal store if there is overlap between +- destination and source since destination may be in cache when +- source is loaded. */ +- cmpq %r9, %rdx +- ja L(more_8x_vec_check) ++ /* To reach this point it is impossible for dst > src and ++ overlap. Remaining to check is src > dst and overlap. rcx ++ already contains dst - src. Negate rcx to get src - dst. If ++ length > rcx then there is overlap and forward copy is best. */ ++ negq %rcx ++ cmpq %rcx, %rdx ++ ja L(more_8x_vec_forward) + + /* Cache align destination. First store the first 64 bytes then + adjust alignments. */ +- VMOVU (%rsi), %VEC(8) +-#if VEC_SIZE < 64 +- VMOVU VEC_SIZE(%rsi), %VEC(9) +-#if VEC_SIZE < 32 +- VMOVU (VEC_SIZE * 2)(%rsi), %VEC(10) +- VMOVU (VEC_SIZE * 3)(%rsi), %VEC(11) +-#endif +-#endif +- VMOVU %VEC(8), (%rdi) +-#if VEC_SIZE < 64 +- VMOVU %VEC(9), VEC_SIZE(%rdi) +-#if VEC_SIZE < 32 +- VMOVU %VEC(10), (VEC_SIZE * 2)(%rdi) +- VMOVU %VEC(11), (VEC_SIZE * 3)(%rdi) +-#endif +-#endif ++ ++ /* First vec was also loaded into VEC(0). */ ++# if VEC_SIZE < 64 ++ VMOVU VEC_SIZE(%rsi), %VEC(1) ++# if VEC_SIZE < 32 ++ VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2) ++ VMOVU (VEC_SIZE * 3)(%rsi), %VEC(3) ++# endif ++# endif ++ VMOVU %VEC(0), (%rdi) ++# if VEC_SIZE < 64 ++ VMOVU %VEC(1), VEC_SIZE(%rdi) ++# if VEC_SIZE < 32 ++ VMOVU %VEC(2), (VEC_SIZE * 2)(%rdi) ++ VMOVU %VEC(3), (VEC_SIZE * 3)(%rdi) ++# endif ++# endif ++ + /* Adjust source, destination, and size. */ + movq %rdi, %r8 + andq $63, %r8 +@@ -614,9 +767,13 @@ L(large_memcpy_2x): + /* Adjust length. */ + addq %r8, %rdx + +- /* Test if source and destination addresses will alias. If they do +- the larger pipeline in large_memcpy_4x alleviated the ++ /* Test if source and destination addresses will alias. If they ++ do the larger pipeline in large_memcpy_4x alleviated the + performance drop. */ ++ ++ /* ecx contains -(dst - src). not ecx will return dst - src - 1 ++ which works for testing aliasing. */ ++ notl %ecx + testl $(PAGE_SIZE - VEC_SIZE * 8), %ecx + jz L(large_memcpy_4x) + +@@ -704,8 +861,8 @@ L(loop_large_memcpy_4x_outer): + /* ecx stores inner loop counter. */ + movl $(PAGE_SIZE / LARGE_LOAD_SIZE), %ecx + L(loop_large_memcpy_4x_inner): +- /* Only one prefetch set per page as doing 4 pages give more time +- for prefetcher to keep up. */ ++ /* Only one prefetch set per page as doing 4 pages give more ++ time for prefetcher to keep up. */ + PREFETCH_ONE_SET(1, (%rsi), PREFETCHED_LOAD_SIZE) + PREFETCH_ONE_SET(1, (%rsi), PAGE_SIZE + PREFETCHED_LOAD_SIZE) + PREFETCH_ONE_SET(1, (%rsi), PAGE_SIZE * 2 + PREFETCHED_LOAD_SIZE) diff --git a/SOURCES/glibc-upstream-2.34-182.patch b/SOURCES/glibc-upstream-2.34-182.patch new file mode 100644 index 0000000..563ff9d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-182.patch @@ -0,0 +1,131 @@ +commit cecbac52123456e2fbcff062a4165bf7b9174797 +Author: Noah Goldstein +Date: Mon Nov 1 00:49:52 2021 -0500 + + x86: Double size of ERMS rep_movsb_threshold in dl-cacheinfo.h + + No bug. + + This patch doubles the rep_movsb_threshold when using ERMS. Based on + benchmarks the vector copy loop, especially now that it handles 4k + aliasing, is better for these medium ranged. + + On Skylake with ERMS: + + Size, Align1, Align2, dst>src,(rep movsb) / (vec copy) + 4096, 0, 0, 0, 0.975 + 4096, 0, 0, 1, 0.953 + 4096, 12, 0, 0, 0.969 + 4096, 12, 0, 1, 0.872 + 4096, 44, 0, 0, 0.979 + 4096, 44, 0, 1, 0.83 + 4096, 0, 12, 0, 1.006 + 4096, 0, 12, 1, 0.989 + 4096, 0, 44, 0, 0.739 + 4096, 0, 44, 1, 0.942 + 4096, 12, 12, 0, 1.009 + 4096, 12, 12, 1, 0.973 + 4096, 44, 44, 0, 0.791 + 4096, 44, 44, 1, 0.961 + 4096, 2048, 0, 0, 0.978 + 4096, 2048, 0, 1, 0.951 + 4096, 2060, 0, 0, 0.986 + 4096, 2060, 0, 1, 0.963 + 4096, 2048, 12, 0, 0.971 + 4096, 2048, 12, 1, 0.941 + 4096, 2060, 12, 0, 0.977 + 4096, 2060, 12, 1, 0.949 + 8192, 0, 0, 0, 0.85 + 8192, 0, 0, 1, 0.845 + 8192, 13, 0, 0, 0.937 + 8192, 13, 0, 1, 0.939 + 8192, 45, 0, 0, 0.932 + 8192, 45, 0, 1, 0.927 + 8192, 0, 13, 0, 0.621 + 8192, 0, 13, 1, 0.62 + 8192, 0, 45, 0, 0.53 + 8192, 0, 45, 1, 0.516 + 8192, 13, 13, 0, 0.664 + 8192, 13, 13, 1, 0.659 + 8192, 45, 45, 0, 0.593 + 8192, 45, 45, 1, 0.575 + 8192, 2048, 0, 0, 0.854 + 8192, 2048, 0, 1, 0.834 + 8192, 2061, 0, 0, 0.863 + 8192, 2061, 0, 1, 0.857 + 8192, 2048, 13, 0, 0.63 + 8192, 2048, 13, 1, 0.629 + 8192, 2061, 13, 0, 0.627 + 8192, 2061, 13, 1, 0.62 + + Signed-off-by: Noah Goldstein + Reviewed-by: H.J. Lu + (cherry picked from commit 475b63702ef38b69558fc3d31a0b66776a70f1d3) + +diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h +index e6c94dfd023a25dc..2e43e67e4f4037d3 100644 +--- a/sysdeps/x86/dl-cacheinfo.h ++++ b/sysdeps/x86/dl-cacheinfo.h +@@ -866,12 +866,14 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) + /* NB: The REP MOVSB threshold must be greater than VEC_SIZE * 8. */ + unsigned int minimum_rep_movsb_threshold; + #endif +- /* NB: The default REP MOVSB threshold is 2048 * (VEC_SIZE / 16). */ ++ /* NB: The default REP MOVSB threshold is 4096 * (VEC_SIZE / 16) for ++ VEC_SIZE == 64 or 32. For VEC_SIZE == 16, the default REP MOVSB ++ threshold is 2048 * (VEC_SIZE / 16). */ + unsigned int rep_movsb_threshold; + if (CPU_FEATURE_USABLE_P (cpu_features, AVX512F) + && !CPU_FEATURE_PREFERRED_P (cpu_features, Prefer_No_AVX512)) + { +- rep_movsb_threshold = 2048 * (64 / 16); ++ rep_movsb_threshold = 4096 * (64 / 16); + #if HAVE_TUNABLES + minimum_rep_movsb_threshold = 64 * 8; + #endif +@@ -879,7 +881,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) + else if (CPU_FEATURE_PREFERRED_P (cpu_features, + AVX_Fast_Unaligned_Load)) + { +- rep_movsb_threshold = 2048 * (32 / 16); ++ rep_movsb_threshold = 4096 * (32 / 16); + #if HAVE_TUNABLES + minimum_rep_movsb_threshold = 32 * 8; + #endif +diff --git a/sysdeps/x86/dl-tunables.list b/sysdeps/x86/dl-tunables.list +index dd6e1d65c9490d4f..419313804d49cf65 100644 +--- a/sysdeps/x86/dl-tunables.list ++++ b/sysdeps/x86/dl-tunables.list +@@ -32,17 +32,21 @@ glibc { + } + x86_rep_movsb_threshold { + type: SIZE_T +- # Since there is overhead to set up REP MOVSB operation, REP MOVSB +- # isn't faster on short data. The memcpy micro benchmark in glibc +- # shows that 2KB is the approximate value above which REP MOVSB +- # becomes faster than SSE2 optimization on processors with Enhanced +- # REP MOVSB. Since larger register size can move more data with a +- # single load and store, the threshold is higher with larger register +- # size. Note: Since the REP MOVSB threshold must be greater than 8 +- # times of vector size and the default value is 2048 * (vector size +- # / 16), the default value and the minimum value must be updated at +- # run-time. NB: Don't set the default value since we can't tell if +- # the tunable value is set by user or not [BZ #27069]. ++ # Since there is overhead to set up REP MOVSB operation, REP ++ # MOVSB isn't faster on short data. The memcpy micro benchmark ++ # in glibc shows that 2KB is the approximate value above which ++ # REP MOVSB becomes faster than SSE2 optimization on processors ++ # with Enhanced REP MOVSB. Since larger register size can move ++ # more data with a single load and store, the threshold is ++ # higher with larger register size. Micro benchmarks show AVX ++ # REP MOVSB becomes faster apprximately at 8KB. The AVX512 ++ # threshold is extrapolated to 16KB. For machines with FSRM the ++ # threshold is universally set at 2112 bytes. Note: Since the ++ # REP MOVSB threshold must be greater than 8 times of vector ++ # size and the default value is 4096 * (vector size / 16), the ++ # default value and the minimum value must be updated at ++ # run-time. NB: Don't set the default value since we can't tell ++ # if the tunable value is set by user or not [BZ #27069]. + minval: 1 + } + x86_rep_stosb_threshold { diff --git a/SOURCES/glibc-upstream-2.34-183.patch b/SOURCES/glibc-upstream-2.34-183.patch new file mode 100644 index 0000000..a1a7285 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-183.patch @@ -0,0 +1,2423 @@ +commit 7cb126e7e7febf9dc3e369cc3e4885e34fb9433b +Author: Noah Goldstein +Date: Wed Nov 10 16:18:56 2021 -0600 + + x86: Shrink memcmp-sse4.S code size + + No bug. + + This implementation refactors memcmp-sse4.S primarily with minimizing + code size in mind. It does this by removing the lookup table logic and + removing the unrolled check from (256, 512] bytes. + + memcmp-sse4 code size reduction : -3487 bytes + wmemcmp-sse4 code size reduction: -1472 bytes + + The current memcmp-sse4.S implementation has a large code size + cost. This has serious adverse affects on the ICache / ITLB. While + in micro-benchmarks the implementations appears fast, traces of + real-world code have shown that the speed in micro benchmarks does not + translate when the ICache/ITLB are not primed, and that the cost + of the code size has measurable negative affects on overall + application performance. + + See https://research.google/pubs/pub48320/ for more details. + + Signed-off-by: Noah Goldstein + Reviewed-by: H.J. Lu + (cherry picked from commit 2f9062d7171850451e6044ef78d91ff8c017b9c0) + +diff --git a/sysdeps/x86_64/multiarch/memcmp-sse4.S b/sysdeps/x86_64/multiarch/memcmp-sse4.S +index b7ac034569ec6178..97c102a9c5ab2b91 100644 +--- a/sysdeps/x86_64/multiarch/memcmp-sse4.S ++++ b/sysdeps/x86_64/multiarch/memcmp-sse4.S +@@ -25,14 +25,14 @@ + # define MEMCMP __memcmp_sse4_1 + # endif + +-# define JMPTBL(I, B) (I - B) ++#ifdef USE_AS_WMEMCMP ++# define CMPEQ pcmpeqd ++# define CHAR_SIZE 4 ++#else ++# define CMPEQ pcmpeqb ++# define CHAR_SIZE 1 ++#endif + +-# define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \ +- lea TABLE(%rip), %r11; \ +- movslq (%r11, INDEX, SCALE), %rcx; \ +- add %r11, %rcx; \ +- _CET_NOTRACK jmp *%rcx; \ +- ud2 + + /* Warning! + wmemcmp has to use SIGNED comparison for elements. +@@ -47,33 +47,253 @@ ENTRY (MEMCMP) + /* Clear the upper 32 bits. */ + mov %edx, %edx + # endif +- pxor %xmm0, %xmm0 + cmp $79, %RDX_LP + ja L(79bytesormore) ++ ++ cmp $CHAR_SIZE, %RDX_LP ++ jbe L(firstbyte) ++ ++ /* N in (CHAR_SIZE, 79) bytes. */ ++ cmpl $32, %edx ++ ja L(more_32_bytes) ++ ++ cmpl $16, %edx ++ jae L(16_to_32_bytes) ++ + # ifndef USE_AS_WMEMCMP +- cmp $1, %RDX_LP +- je L(firstbyte) ++ cmpl $8, %edx ++ jae L(8_to_16_bytes) ++ ++ cmpl $4, %edx ++ jb L(2_to_3_bytes) ++ ++ movl (%rdi), %eax ++ movl (%rsi), %ecx ++ ++ bswap %eax ++ bswap %ecx ++ ++ shlq $32, %rax ++ shlq $32, %rcx ++ ++ movl -4(%rdi, %rdx), %edi ++ movl -4(%rsi, %rdx), %esi ++ ++ bswap %edi ++ bswap %esi ++ ++ orq %rdi, %rax ++ orq %rsi, %rcx ++ subq %rcx, %rax ++ cmovne %edx, %eax ++ sbbl %ecx, %ecx ++ orl %ecx, %eax ++ ret ++ ++ .p2align 4,, 8 ++L(2_to_3_bytes): ++ movzwl (%rdi), %eax ++ movzwl (%rsi), %ecx ++ shll $8, %eax ++ shll $8, %ecx ++ bswap %eax ++ bswap %ecx ++ movzbl -1(%rdi, %rdx), %edi ++ movzbl -1(%rsi, %rdx), %esi ++ orl %edi, %eax ++ orl %esi, %ecx ++ subl %ecx, %eax ++ ret ++ ++ .p2align 4,, 8 ++L(8_to_16_bytes): ++ movq (%rdi), %rax ++ movq (%rsi), %rcx ++ ++ bswap %rax ++ bswap %rcx ++ ++ subq %rcx, %rax ++ jne L(8_to_16_bytes_done) ++ ++ movq -8(%rdi, %rdx), %rax ++ movq -8(%rsi, %rdx), %rcx ++ ++ bswap %rax ++ bswap %rcx ++ ++ subq %rcx, %rax ++ ++L(8_to_16_bytes_done): ++ cmovne %edx, %eax ++ sbbl %ecx, %ecx ++ orl %ecx, %eax ++ ret ++# else ++ xorl %eax, %eax ++ movl (%rdi), %ecx ++ cmpl (%rsi), %ecx ++ jne L(8_to_16_bytes_done) ++ movl 4(%rdi), %ecx ++ cmpl 4(%rsi), %ecx ++ jne L(8_to_16_bytes_done) ++ movl -4(%rdi, %rdx), %ecx ++ cmpl -4(%rsi, %rdx), %ecx ++ jne L(8_to_16_bytes_done) ++ ret + # endif +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) + +-# ifndef USE_AS_WMEMCMP +- .p2align 4 ++ .p2align 4,, 3 ++L(ret_zero): ++ xorl %eax, %eax ++L(zero): ++ ret ++ ++ .p2align 4,, 8 + L(firstbyte): ++ jb L(ret_zero) ++# ifdef USE_AS_WMEMCMP ++ xorl %eax, %eax ++ movl (%rdi), %ecx ++ cmpl (%rsi), %ecx ++ je L(zero) ++L(8_to_16_bytes_done): ++ setg %al ++ leal -1(%rax, %rax), %eax ++# else + movzbl (%rdi), %eax + movzbl (%rsi), %ecx + sub %ecx, %eax ++# endif + ret ++ ++ .p2align 4 ++L(vec_return_begin_48): ++ addq $16, %rdi ++ addq $16, %rsi ++L(vec_return_begin_32): ++ bsfl %eax, %eax ++# ifdef USE_AS_WMEMCMP ++ movl 32(%rdi, %rax), %ecx ++ xorl %edx, %edx ++ cmpl 32(%rsi, %rax), %ecx ++ setg %dl ++ leal -1(%rdx, %rdx), %eax ++# else ++ movzbl 32(%rsi, %rax), %ecx ++ movzbl 32(%rdi, %rax), %eax ++ subl %ecx, %eax ++# endif ++ ret ++ ++ .p2align 4 ++L(vec_return_begin_16): ++ addq $16, %rdi ++ addq $16, %rsi ++L(vec_return_begin): ++ bsfl %eax, %eax ++# ifdef USE_AS_WMEMCMP ++ movl (%rdi, %rax), %ecx ++ xorl %edx, %edx ++ cmpl (%rsi, %rax), %ecx ++ setg %dl ++ leal -1(%rdx, %rdx), %eax ++# else ++ movzbl (%rsi, %rax), %ecx ++ movzbl (%rdi, %rax), %eax ++ subl %ecx, %eax ++# endif ++ ret ++ ++ .p2align 4 ++L(vec_return_end_16): ++ subl $16, %edx ++L(vec_return_end): ++ bsfl %eax, %eax ++ addl %edx, %eax ++# ifdef USE_AS_WMEMCMP ++ movl -16(%rdi, %rax), %ecx ++ xorl %edx, %edx ++ cmpl -16(%rsi, %rax), %ecx ++ setg %dl ++ leal -1(%rdx, %rdx), %eax ++# else ++ movzbl -16(%rsi, %rax), %ecx ++ movzbl -16(%rdi, %rax), %eax ++ subl %ecx, %eax + # endif ++ ret ++ ++ .p2align 4,, 8 ++L(more_32_bytes): ++ movdqu (%rdi), %xmm0 ++ movdqu (%rsi), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqu 16(%rdi), %xmm0 ++ movdqu 16(%rsi), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_16) ++ ++ cmpl $64, %edx ++ jbe L(32_to_64_bytes) ++ movdqu 32(%rdi), %xmm0 ++ movdqu 32(%rsi), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_32) ++ ++ .p2align 4,, 6 ++L(32_to_64_bytes): ++ movdqu -32(%rdi, %rdx), %xmm0 ++ movdqu -32(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end_16) ++ ++ movdqu -16(%rdi, %rdx), %xmm0 ++ movdqu -16(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end) ++ ret ++ ++ .p2align 4 ++L(16_to_32_bytes): ++ movdqu (%rdi), %xmm0 ++ movdqu (%rsi), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqu -16(%rdi, %rdx), %xmm0 ++ movdqu -16(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end) ++ ret ++ + + .p2align 4 + L(79bytesormore): ++ movdqu (%rdi), %xmm0 + movdqu (%rsi), %xmm1 +- movdqu (%rdi), %xmm2 +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ + mov %rsi, %rcx + and $-16, %rsi + add $16, %rsi +@@ -86,1694 +306,499 @@ L(79bytesormore): + + cmp $128, %rdx + ja L(128bytesormore) +-L(less128bytes): +- sub $64, %rdx +- +- movdqu (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) + +- movdqu 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- +- movdqu 32(%rdi), %xmm2 +- pxor 32(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(48bytesin256) +- +- movdqu 48(%rdi), %xmm2 +- pxor 48(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(64bytesin256) +- cmp $32, %rdx +- jb L(less32bytesin64) +- +- movdqu 64(%rdi), %xmm2 +- pxor 64(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(80bytesin256) +- +- movdqu 80(%rdi), %xmm2 +- pxor 80(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(96bytesin256) +- sub $32, %rdx +- add $32, %rdi +- add $32, %rsi +-L(less32bytesin64): +- add $64, %rdi +- add $64, %rsi +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) ++ .p2align 4,, 6 ++L(less128bytes): ++ movdqu (%rdi), %xmm1 ++ CMPEQ (%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqu 16(%rdi), %xmm1 ++ CMPEQ 16(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_16) ++ ++ movdqu 32(%rdi), %xmm1 ++ CMPEQ 32(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_32) ++ ++ movdqu 48(%rdi), %xmm1 ++ CMPEQ 48(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_48) ++ ++ cmp $96, %rdx ++ jb L(32_to_64_bytes) ++ ++ addq $64, %rdi ++ addq $64, %rsi ++ subq $64, %rdx ++ ++ .p2align 4,, 6 ++L(last_64_bytes): ++ movdqu (%rdi), %xmm1 ++ CMPEQ (%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqu 16(%rdi), %xmm1 ++ CMPEQ 16(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_16) ++ ++ movdqu -32(%rdi, %rdx), %xmm0 ++ movdqu -32(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end_16) ++ ++ movdqu -16(%rdi, %rdx), %xmm0 ++ movdqu -16(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end) ++ ret + ++ .p2align 4 + L(128bytesormore): +- cmp $512, %rdx +- ja L(512bytesormore) + cmp $256, %rdx +- ja L(less512bytes) ++ ja L(unaligned_loop) + L(less256bytes): +- sub $128, %rdx +- +- movdqu (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) +- +- movdqu 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- +- movdqu 32(%rdi), %xmm2 +- pxor 32(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(48bytesin256) +- +- movdqu 48(%rdi), %xmm2 +- pxor 48(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(64bytesin256) +- +- movdqu 64(%rdi), %xmm2 +- pxor 64(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(80bytesin256) +- +- movdqu 80(%rdi), %xmm2 +- pxor 80(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(96bytesin256) +- +- movdqu 96(%rdi), %xmm2 +- pxor 96(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(112bytesin256) +- +- movdqu 112(%rdi), %xmm2 +- pxor 112(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(128bytesin256) +- +- add $128, %rsi +- add $128, %rdi +- +- cmp $64, %rdx +- jae L(less128bytes) +- +- cmp $32, %rdx +- jb L(less32bytesin128) +- +- movdqu (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) +- +- movdqu 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- sub $32, %rdx +- add $32, %rdi +- add $32, %rsi +-L(less32bytesin128): +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) +- +-L(less512bytes): +- sub $256, %rdx +- movdqu (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) +- +- movdqu 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- +- movdqu 32(%rdi), %xmm2 +- pxor 32(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(48bytesin256) +- +- movdqu 48(%rdi), %xmm2 +- pxor 48(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(64bytesin256) +- +- movdqu 64(%rdi), %xmm2 +- pxor 64(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(80bytesin256) +- +- movdqu 80(%rdi), %xmm2 +- pxor 80(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(96bytesin256) +- +- movdqu 96(%rdi), %xmm2 +- pxor 96(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(112bytesin256) +- +- movdqu 112(%rdi), %xmm2 +- pxor 112(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(128bytesin256) +- +- movdqu 128(%rdi), %xmm2 +- pxor 128(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(144bytesin256) +- +- movdqu 144(%rdi), %xmm2 +- pxor 144(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(160bytesin256) +- +- movdqu 160(%rdi), %xmm2 +- pxor 160(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(176bytesin256) +- +- movdqu 176(%rdi), %xmm2 +- pxor 176(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(192bytesin256) +- +- movdqu 192(%rdi), %xmm2 +- pxor 192(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(208bytesin256) +- +- movdqu 208(%rdi), %xmm2 +- pxor 208(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(224bytesin256) +- +- movdqu 224(%rdi), %xmm2 +- pxor 224(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(240bytesin256) +- +- movdqu 240(%rdi), %xmm2 +- pxor 240(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(256bytesin256) +- +- add $256, %rsi +- add $256, %rdi +- +- cmp $128, %rdx +- jae L(less256bytes) ++ movdqu (%rdi), %xmm1 ++ CMPEQ (%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqu 16(%rdi), %xmm1 ++ CMPEQ 16(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_16) ++ ++ movdqu 32(%rdi), %xmm1 ++ CMPEQ 32(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_32) ++ ++ movdqu 48(%rdi), %xmm1 ++ CMPEQ 48(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_48) ++ ++ addq $64, %rdi ++ addq $64, %rsi ++ ++ movdqu (%rdi), %xmm1 ++ CMPEQ (%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqu 16(%rdi), %xmm1 ++ CMPEQ 16(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_16) ++ ++ movdqu 32(%rdi), %xmm1 ++ CMPEQ 32(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_32) ++ ++ movdqu 48(%rdi), %xmm1 ++ CMPEQ 48(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_48) ++ ++ addq $-128, %rdx ++ subq $-64, %rsi ++ subq $-64, %rdi + + cmp $64, %rdx +- jae L(less128bytes) ++ ja L(less128bytes) + + cmp $32, %rdx +- jb L(less32bytesin256) +- +- movdqu (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) +- +- movdqu 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- sub $32, %rdx +- add $32, %rdi +- add $32, %rsi +-L(less32bytesin256): +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) ++ ja L(last_64_bytes) ++ ++ movdqu -32(%rdi, %rdx), %xmm0 ++ movdqu -32(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end_16) ++ ++ movdqu -16(%rdi, %rdx), %xmm0 ++ movdqu -16(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end) ++ ret + + .p2align 4 +-L(512bytesormore): ++L(unaligned_loop): + # ifdef DATA_CACHE_SIZE_HALF + mov $DATA_CACHE_SIZE_HALF, %R8_LP + # else + mov __x86_data_cache_size_half(%rip), %R8_LP + # endif +- mov %r8, %r9 +- shr $1, %r8 +- add %r9, %r8 +- cmp %r8, %rdx +- ja L(L2_L3_cache_unaglined) ++ movq %r8, %r9 ++ addq %r8, %r8 ++ addq %r9, %r8 ++ cmpq %r8, %rdx ++ ja L(L2_L3_cache_unaligned) + sub $64, %rdx + .p2align 4 + L(64bytesormore_loop): +- movdqu (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- movdqa %xmm2, %xmm1 ++ movdqu (%rdi), %xmm0 ++ movdqu 16(%rdi), %xmm1 ++ movdqu 32(%rdi), %xmm2 ++ movdqu 48(%rdi), %xmm3 + +- movdqu 16(%rdi), %xmm3 +- pxor 16(%rsi), %xmm3 +- por %xmm3, %xmm1 ++ CMPEQ (%rsi), %xmm0 ++ CMPEQ 16(%rsi), %xmm1 ++ CMPEQ 32(%rsi), %xmm2 ++ CMPEQ 48(%rsi), %xmm3 + +- movdqu 32(%rdi), %xmm4 +- pxor 32(%rsi), %xmm4 +- por %xmm4, %xmm1 ++ pand %xmm0, %xmm1 ++ pand %xmm2, %xmm3 ++ pand %xmm1, %xmm3 + +- movdqu 48(%rdi), %xmm5 +- pxor 48(%rsi), %xmm5 +- por %xmm5, %xmm1 ++ pmovmskb %xmm3, %eax ++ incw %ax ++ jnz L(64bytesormore_loop_end) + +- ptest %xmm1, %xmm0 +- jnc L(64bytesormore_loop_end) + add $64, %rsi + add $64, %rdi + sub $64, %rdx +- jae L(64bytesormore_loop) ++ ja L(64bytesormore_loop) + +- add $64, %rdx +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) ++ .p2align 4,, 6 ++L(loop_tail): ++ addq %rdx, %rdi ++ movdqu (%rdi), %xmm0 ++ movdqu 16(%rdi), %xmm1 ++ movdqu 32(%rdi), %xmm2 ++ movdqu 48(%rdi), %xmm3 ++ ++ addq %rdx, %rsi ++ movdqu (%rsi), %xmm4 ++ movdqu 16(%rsi), %xmm5 ++ movdqu 32(%rsi), %xmm6 ++ movdqu 48(%rsi), %xmm7 ++ ++ CMPEQ %xmm4, %xmm0 ++ CMPEQ %xmm5, %xmm1 ++ CMPEQ %xmm6, %xmm2 ++ CMPEQ %xmm7, %xmm3 ++ ++ pand %xmm0, %xmm1 ++ pand %xmm2, %xmm3 ++ pand %xmm1, %xmm3 ++ ++ pmovmskb %xmm3, %eax ++ incw %ax ++ jnz L(64bytesormore_loop_end) ++ ret + +-L(L2_L3_cache_unaglined): +- sub $64, %rdx ++L(L2_L3_cache_unaligned): ++ subq $64, %rdx + .p2align 4 + L(L2_L3_unaligned_128bytes_loop): + prefetchnta 0x1c0(%rdi) + prefetchnta 0x1c0(%rsi) +- movdqu (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- movdqa %xmm2, %xmm1 + +- movdqu 16(%rdi), %xmm3 +- pxor 16(%rsi), %xmm3 +- por %xmm3, %xmm1 ++ movdqu (%rdi), %xmm0 ++ movdqu 16(%rdi), %xmm1 ++ movdqu 32(%rdi), %xmm2 ++ movdqu 48(%rdi), %xmm3 ++ ++ CMPEQ (%rsi), %xmm0 ++ CMPEQ 16(%rsi), %xmm1 ++ CMPEQ 32(%rsi), %xmm2 ++ CMPEQ 48(%rsi), %xmm3 + +- movdqu 32(%rdi), %xmm4 +- pxor 32(%rsi), %xmm4 +- por %xmm4, %xmm1 ++ pand %xmm0, %xmm1 ++ pand %xmm2, %xmm3 ++ pand %xmm1, %xmm3 + +- movdqu 48(%rdi), %xmm5 +- pxor 48(%rsi), %xmm5 +- por %xmm5, %xmm1 ++ pmovmskb %xmm3, %eax ++ incw %ax ++ jnz L(64bytesormore_loop_end) + +- ptest %xmm1, %xmm0 +- jnc L(64bytesormore_loop_end) + add $64, %rsi + add $64, %rdi + sub $64, %rdx +- jae L(L2_L3_unaligned_128bytes_loop) ++ ja L(L2_L3_unaligned_128bytes_loop) ++ jmp L(loop_tail) + +- add $64, %rdx +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) + +-/* +- * This case is for machines which are sensitive for unaligned instructions. +- */ ++ /* This case is for machines which are sensitive for unaligned ++ * instructions. */ + .p2align 4 + L(2aligned): + cmp $128, %rdx + ja L(128bytesormorein2aligned) + L(less128bytesin2aligned): +- sub $64, %rdx +- +- movdqa (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) +- +- movdqa 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- +- movdqa 32(%rdi), %xmm2 +- pxor 32(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(48bytesin256) +- +- movdqa 48(%rdi), %xmm2 +- pxor 48(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(64bytesin256) +- cmp $32, %rdx +- jb L(less32bytesin64in2alinged) +- +- movdqa 64(%rdi), %xmm2 +- pxor 64(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(80bytesin256) +- +- movdqa 80(%rdi), %xmm2 +- pxor 80(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(96bytesin256) +- sub $32, %rdx +- add $32, %rdi +- add $32, %rsi +-L(less32bytesin64in2alinged): +- add $64, %rdi +- add $64, %rsi +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) ++ movdqa (%rdi), %xmm1 ++ CMPEQ (%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqa 16(%rdi), %xmm1 ++ CMPEQ 16(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_16) ++ ++ movdqa 32(%rdi), %xmm1 ++ CMPEQ 32(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_32) ++ ++ movdqa 48(%rdi), %xmm1 ++ CMPEQ 48(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_48) ++ ++ cmp $96, %rdx ++ jb L(32_to_64_bytes) ++ ++ addq $64, %rdi ++ addq $64, %rsi ++ subq $64, %rdx ++ ++ .p2align 4,, 6 ++L(aligned_last_64_bytes): ++ movdqa (%rdi), %xmm1 ++ CMPEQ (%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqa 16(%rdi), %xmm1 ++ CMPEQ 16(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_16) ++ ++ movdqu -32(%rdi, %rdx), %xmm0 ++ movdqu -32(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end_16) ++ ++ movdqu -16(%rdi, %rdx), %xmm0 ++ movdqu -16(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end) ++ ret + + .p2align 4 + L(128bytesormorein2aligned): +- cmp $512, %rdx +- ja L(512bytesormorein2aligned) + cmp $256, %rdx +- ja L(256bytesormorein2aligned) ++ ja L(aligned_loop) + L(less256bytesin2alinged): +- sub $128, %rdx +- +- movdqa (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) +- +- movdqa 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- +- movdqa 32(%rdi), %xmm2 +- pxor 32(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(48bytesin256) +- +- movdqa 48(%rdi), %xmm2 +- pxor 48(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(64bytesin256) +- +- movdqa 64(%rdi), %xmm2 +- pxor 64(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(80bytesin256) +- +- movdqa 80(%rdi), %xmm2 +- pxor 80(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(96bytesin256) +- +- movdqa 96(%rdi), %xmm2 +- pxor 96(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(112bytesin256) +- +- movdqa 112(%rdi), %xmm2 +- pxor 112(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(128bytesin256) +- +- add $128, %rsi +- add $128, %rdi ++ movdqa (%rdi), %xmm1 ++ CMPEQ (%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqa 16(%rdi), %xmm1 ++ CMPEQ 16(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_16) ++ ++ movdqa 32(%rdi), %xmm1 ++ CMPEQ 32(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_32) ++ ++ movdqa 48(%rdi), %xmm1 ++ CMPEQ 48(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_48) ++ ++ addq $64, %rdi ++ addq $64, %rsi ++ ++ movdqa (%rdi), %xmm1 ++ CMPEQ (%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin) ++ ++ movdqa 16(%rdi), %xmm1 ++ CMPEQ 16(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_16) ++ ++ movdqa 32(%rdi), %xmm1 ++ CMPEQ 32(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_32) ++ ++ movdqa 48(%rdi), %xmm1 ++ CMPEQ 48(%rsi), %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_begin_48) ++ ++ addq $-128, %rdx ++ subq $-64, %rsi ++ subq $-64, %rdi + + cmp $64, %rdx +- jae L(less128bytesin2aligned) ++ ja L(less128bytesin2aligned) + + cmp $32, %rdx +- jb L(less32bytesin128in2aligned) +- +- movdqu (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) +- +- movdqu 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- sub $32, %rdx +- add $32, %rdi +- add $32, %rsi +-L(less32bytesin128in2aligned): +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) +- +- .p2align 4 +-L(256bytesormorein2aligned): +- +- sub $256, %rdx +- movdqa (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) +- +- movdqa 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- +- movdqa 32(%rdi), %xmm2 +- pxor 32(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(48bytesin256) +- +- movdqa 48(%rdi), %xmm2 +- pxor 48(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(64bytesin256) +- +- movdqa 64(%rdi), %xmm2 +- pxor 64(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(80bytesin256) +- +- movdqa 80(%rdi), %xmm2 +- pxor 80(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(96bytesin256) +- +- movdqa 96(%rdi), %xmm2 +- pxor 96(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(112bytesin256) +- +- movdqa 112(%rdi), %xmm2 +- pxor 112(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(128bytesin256) +- +- movdqa 128(%rdi), %xmm2 +- pxor 128(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(144bytesin256) +- +- movdqa 144(%rdi), %xmm2 +- pxor 144(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(160bytesin256) +- +- movdqa 160(%rdi), %xmm2 +- pxor 160(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(176bytesin256) +- +- movdqa 176(%rdi), %xmm2 +- pxor 176(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(192bytesin256) +- +- movdqa 192(%rdi), %xmm2 +- pxor 192(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(208bytesin256) +- +- movdqa 208(%rdi), %xmm2 +- pxor 208(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(224bytesin256) +- +- movdqa 224(%rdi), %xmm2 +- pxor 224(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(240bytesin256) +- +- movdqa 240(%rdi), %xmm2 +- pxor 240(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(256bytesin256) +- +- add $256, %rsi +- add $256, %rdi +- +- cmp $128, %rdx +- jae L(less256bytesin2alinged) +- +- cmp $64, %rdx +- jae L(less128bytesin2aligned) +- +- cmp $32, %rdx +- jb L(less32bytesin256in2alinged) +- +- movdqa (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(16bytesin256) +- +- movdqa 16(%rdi), %xmm2 +- pxor 16(%rsi), %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(32bytesin256) +- sub $32, %rdx +- add $32, %rdi +- add $32, %rsi +-L(less32bytesin256in2alinged): +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) ++ ja L(aligned_last_64_bytes) ++ ++ movdqu -32(%rdi, %rdx), %xmm0 ++ movdqu -32(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end_16) ++ ++ movdqu -16(%rdi, %rdx), %xmm0 ++ movdqu -16(%rsi, %rdx), %xmm1 ++ CMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ incw %ax ++ jnz L(vec_return_end) ++ ret + + .p2align 4 +-L(512bytesormorein2aligned): ++L(aligned_loop): + # ifdef DATA_CACHE_SIZE_HALF + mov $DATA_CACHE_SIZE_HALF, %R8_LP + # else + mov __x86_data_cache_size_half(%rip), %R8_LP + # endif +- mov %r8, %r9 +- shr $1, %r8 +- add %r9, %r8 +- cmp %r8, %rdx +- ja L(L2_L3_cache_aglined) ++ movq %r8, %r9 ++ addq %r8, %r8 ++ addq %r9, %r8 ++ cmpq %r8, %rdx ++ ja L(L2_L3_cache_aligned) + + sub $64, %rdx + .p2align 4 + L(64bytesormore_loopin2aligned): +- movdqa (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- movdqa %xmm2, %xmm1 +- +- movdqa 16(%rdi), %xmm3 +- pxor 16(%rsi), %xmm3 +- por %xmm3, %xmm1 ++ movdqa (%rdi), %xmm0 ++ movdqa 16(%rdi), %xmm1 ++ movdqa 32(%rdi), %xmm2 ++ movdqa 48(%rdi), %xmm3 + +- movdqa 32(%rdi), %xmm4 +- pxor 32(%rsi), %xmm4 +- por %xmm4, %xmm1 ++ CMPEQ (%rsi), %xmm0 ++ CMPEQ 16(%rsi), %xmm1 ++ CMPEQ 32(%rsi), %xmm2 ++ CMPEQ 48(%rsi), %xmm3 + +- movdqa 48(%rdi), %xmm5 +- pxor 48(%rsi), %xmm5 +- por %xmm5, %xmm1 ++ pand %xmm0, %xmm1 ++ pand %xmm2, %xmm3 ++ pand %xmm1, %xmm3 + +- ptest %xmm1, %xmm0 +- jnc L(64bytesormore_loop_end) ++ pmovmskb %xmm3, %eax ++ incw %ax ++ jnz L(64bytesormore_loop_end) + add $64, %rsi + add $64, %rdi + sub $64, %rdx +- jae L(64bytesormore_loopin2aligned) +- +- add $64, %rdx +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) +-L(L2_L3_cache_aglined): +- sub $64, %rdx ++ ja L(64bytesormore_loopin2aligned) ++ jmp L(loop_tail) + ++L(L2_L3_cache_aligned): ++ subq $64, %rdx + .p2align 4 + L(L2_L3_aligned_128bytes_loop): + prefetchnta 0x1c0(%rdi) + prefetchnta 0x1c0(%rsi) +- movdqa (%rdi), %xmm2 +- pxor (%rsi), %xmm2 +- movdqa %xmm2, %xmm1 +- +- movdqa 16(%rdi), %xmm3 +- pxor 16(%rsi), %xmm3 +- por %xmm3, %xmm1 ++ movdqa (%rdi), %xmm0 ++ movdqa 16(%rdi), %xmm1 ++ movdqa 32(%rdi), %xmm2 ++ movdqa 48(%rdi), %xmm3 + +- movdqa 32(%rdi), %xmm4 +- pxor 32(%rsi), %xmm4 +- por %xmm4, %xmm1 ++ CMPEQ (%rsi), %xmm0 ++ CMPEQ 16(%rsi), %xmm1 ++ CMPEQ 32(%rsi), %xmm2 ++ CMPEQ 48(%rsi), %xmm3 + +- movdqa 48(%rdi), %xmm5 +- pxor 48(%rsi), %xmm5 +- por %xmm5, %xmm1 ++ pand %xmm0, %xmm1 ++ pand %xmm2, %xmm3 ++ pand %xmm1, %xmm3 + +- ptest %xmm1, %xmm0 +- jnc L(64bytesormore_loop_end) +- add $64, %rsi +- add $64, %rdi +- sub $64, %rdx +- jae L(L2_L3_aligned_128bytes_loop) +- +- add $64, %rdx +- add %rdx, %rsi +- add %rdx, %rdi +- BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4) ++ pmovmskb %xmm3, %eax ++ incw %ax ++ jnz L(64bytesormore_loop_end) + ++ addq $64, %rsi ++ addq $64, %rdi ++ subq $64, %rdx ++ ja L(L2_L3_aligned_128bytes_loop) ++ jmp L(loop_tail) + + .p2align 4 + L(64bytesormore_loop_end): +- add $16, %rdi +- add $16, %rsi +- ptest %xmm2, %xmm0 +- jnc L(16bytes) +- +- add $16, %rdi +- add $16, %rsi +- ptest %xmm3, %xmm0 +- jnc L(16bytes) +- +- add $16, %rdi +- add $16, %rsi +- ptest %xmm4, %xmm0 +- jnc L(16bytes) +- +- add $16, %rdi +- add $16, %rsi +- jmp L(16bytes) +- +-L(256bytesin256): +- add $256, %rdi +- add $256, %rsi +- jmp L(16bytes) +-L(240bytesin256): +- add $240, %rdi +- add $240, %rsi +- jmp L(16bytes) +-L(224bytesin256): +- add $224, %rdi +- add $224, %rsi +- jmp L(16bytes) +-L(208bytesin256): +- add $208, %rdi +- add $208, %rsi +- jmp L(16bytes) +-L(192bytesin256): +- add $192, %rdi +- add $192, %rsi +- jmp L(16bytes) +-L(176bytesin256): +- add $176, %rdi +- add $176, %rsi +- jmp L(16bytes) +-L(160bytesin256): +- add $160, %rdi +- add $160, %rsi +- jmp L(16bytes) +-L(144bytesin256): +- add $144, %rdi +- add $144, %rsi +- jmp L(16bytes) +-L(128bytesin256): +- add $128, %rdi +- add $128, %rsi +- jmp L(16bytes) +-L(112bytesin256): +- add $112, %rdi +- add $112, %rsi +- jmp L(16bytes) +-L(96bytesin256): +- add $96, %rdi +- add $96, %rsi +- jmp L(16bytes) +-L(80bytesin256): +- add $80, %rdi +- add $80, %rsi +- jmp L(16bytes) +-L(64bytesin256): +- add $64, %rdi +- add $64, %rsi +- jmp L(16bytes) +-L(48bytesin256): +- add $16, %rdi +- add $16, %rsi +-L(32bytesin256): +- add $16, %rdi +- add $16, %rsi +-L(16bytesin256): +- add $16, %rdi +- add $16, %rsi +-L(16bytes): +- mov -16(%rdi), %rax +- mov -16(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +-L(8bytes): +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(12bytes): +- mov -12(%rdi), %rax +- mov -12(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +-L(4bytes): +- mov -4(%rsi), %ecx +-# ifndef USE_AS_WMEMCMP +- mov -4(%rdi), %eax +- cmp %eax, %ecx +-# else +- cmp -4(%rdi), %ecx +-# endif +- jne L(diffin4bytes) +-L(0bytes): +- xor %eax, %eax +- ret +- +-# ifndef USE_AS_WMEMCMP +-/* unreal case for wmemcmp */ +- .p2align 4 +-L(65bytes): +- movdqu -65(%rdi), %xmm1 +- movdqu -65(%rsi), %xmm2 +- mov $-65, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(49bytes): +- movdqu -49(%rdi), %xmm1 +- movdqu -49(%rsi), %xmm2 +- mov $-49, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(33bytes): +- movdqu -33(%rdi), %xmm1 +- movdqu -33(%rsi), %xmm2 +- mov $-33, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(17bytes): +- mov -17(%rdi), %rax +- mov -17(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +-L(9bytes): +- mov -9(%rdi), %rax +- mov -9(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- movzbl -1(%rdi), %eax +- movzbl -1(%rsi), %edx +- sub %edx, %eax +- ret +- +- .p2align 4 +-L(13bytes): +- mov -13(%rdi), %rax +- mov -13(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(5bytes): +- mov -5(%rdi), %eax +- mov -5(%rsi), %ecx +- cmp %eax, %ecx +- jne L(diffin4bytes) +- movzbl -1(%rdi), %eax +- movzbl -1(%rsi), %edx +- sub %edx, %eax +- ret +- +- .p2align 4 +-L(66bytes): +- movdqu -66(%rdi), %xmm1 +- movdqu -66(%rsi), %xmm2 +- mov $-66, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(50bytes): +- movdqu -50(%rdi), %xmm1 +- movdqu -50(%rsi), %xmm2 +- mov $-50, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(34bytes): +- movdqu -34(%rdi), %xmm1 +- movdqu -34(%rsi), %xmm2 +- mov $-34, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(18bytes): +- mov -18(%rdi), %rax +- mov -18(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +-L(10bytes): +- mov -10(%rdi), %rax +- mov -10(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- movzwl -2(%rdi), %eax +- movzwl -2(%rsi), %ecx +- cmp %cl, %al +- jne L(end) +- and $0xffff, %eax +- and $0xffff, %ecx +- sub %ecx, %eax +- ret +- +- .p2align 4 +-L(14bytes): +- mov -14(%rdi), %rax +- mov -14(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(6bytes): +- mov -6(%rdi), %eax +- mov -6(%rsi), %ecx +- cmp %eax, %ecx +- jne L(diffin4bytes) +-L(2bytes): +- movzwl -2(%rsi), %ecx +- movzwl -2(%rdi), %eax +- cmp %cl, %al +- jne L(end) +- and $0xffff, %eax +- and $0xffff, %ecx +- sub %ecx, %eax +- ret +- +- .p2align 4 +-L(67bytes): +- movdqu -67(%rdi), %xmm2 +- movdqu -67(%rsi), %xmm1 +- mov $-67, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(51bytes): +- movdqu -51(%rdi), %xmm2 +- movdqu -51(%rsi), %xmm1 +- mov $-51, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(35bytes): +- movdqu -35(%rsi), %xmm1 +- movdqu -35(%rdi), %xmm2 +- mov $-35, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(19bytes): +- mov -19(%rdi), %rax +- mov -19(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +-L(11bytes): +- mov -11(%rdi), %rax +- mov -11(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- mov -4(%rdi), %eax +- mov -4(%rsi), %ecx +- cmp %eax, %ecx +- jne L(diffin4bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(15bytes): +- mov -15(%rdi), %rax +- mov -15(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(7bytes): +- mov -7(%rdi), %eax +- mov -7(%rsi), %ecx +- cmp %eax, %ecx +- jne L(diffin4bytes) +- mov -4(%rdi), %eax +- mov -4(%rsi), %ecx +- cmp %eax, %ecx +- jne L(diffin4bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(3bytes): +- movzwl -3(%rdi), %eax +- movzwl -3(%rsi), %ecx +- cmp %eax, %ecx +- jne L(diffin2bytes) +-L(1bytes): +- movzbl -1(%rdi), %eax +- movzbl -1(%rsi), %ecx +- sub %ecx, %eax +- ret +-# endif +- +- .p2align 4 +-L(68bytes): +- movdqu -68(%rdi), %xmm2 +- movdqu -68(%rsi), %xmm1 +- mov $-68, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(52bytes): +- movdqu -52(%rdi), %xmm2 +- movdqu -52(%rsi), %xmm1 +- mov $-52, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(36bytes): +- movdqu -36(%rdi), %xmm2 +- movdqu -36(%rsi), %xmm1 +- mov $-36, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(20bytes): +- movdqu -20(%rdi), %xmm2 +- movdqu -20(%rsi), %xmm1 +- mov $-20, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -4(%rsi), %ecx +- +-# ifndef USE_AS_WMEMCMP +- mov -4(%rdi), %eax +- cmp %eax, %ecx +-# else +- cmp -4(%rdi), %ecx +-# endif +- jne L(diffin4bytes) +- xor %eax, %eax +- ret +- +-# ifndef USE_AS_WMEMCMP +-/* unreal cases for wmemcmp */ +- .p2align 4 +-L(69bytes): +- movdqu -69(%rsi), %xmm1 +- movdqu -69(%rdi), %xmm2 +- mov $-69, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(53bytes): +- movdqu -53(%rsi), %xmm1 +- movdqu -53(%rdi), %xmm2 +- mov $-53, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(37bytes): +- movdqu -37(%rsi), %xmm1 +- movdqu -37(%rdi), %xmm2 +- mov $-37, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(21bytes): +- movdqu -21(%rsi), %xmm1 +- movdqu -21(%rdi), %xmm2 +- mov $-21, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(70bytes): +- movdqu -70(%rsi), %xmm1 +- movdqu -70(%rdi), %xmm2 +- mov $-70, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(54bytes): +- movdqu -54(%rsi), %xmm1 +- movdqu -54(%rdi), %xmm2 +- mov $-54, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(38bytes): +- movdqu -38(%rsi), %xmm1 +- movdqu -38(%rdi), %xmm2 +- mov $-38, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(22bytes): +- movdqu -22(%rsi), %xmm1 +- movdqu -22(%rdi), %xmm2 +- mov $-22, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(71bytes): +- movdqu -71(%rsi), %xmm1 +- movdqu -71(%rdi), %xmm2 +- mov $-71, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(55bytes): +- movdqu -55(%rdi), %xmm2 +- movdqu -55(%rsi), %xmm1 +- mov $-55, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(39bytes): +- movdqu -39(%rdi), %xmm2 +- movdqu -39(%rsi), %xmm1 +- mov $-39, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(23bytes): +- movdqu -23(%rdi), %xmm2 +- movdqu -23(%rsi), %xmm1 +- mov $-23, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +-# endif +- +- .p2align 4 +-L(72bytes): +- movdqu -72(%rsi), %xmm1 +- movdqu -72(%rdi), %xmm2 +- mov $-72, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(56bytes): +- movdqu -56(%rdi), %xmm2 +- movdqu -56(%rsi), %xmm1 +- mov $-56, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(40bytes): +- movdqu -40(%rdi), %xmm2 +- movdqu -40(%rsi), %xmm1 +- mov $-40, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(24bytes): +- movdqu -24(%rdi), %xmm2 +- movdqu -24(%rsi), %xmm1 +- mov $-24, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- +- mov -8(%rsi), %rcx +- mov -8(%rdi), %rax +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +-# ifndef USE_AS_WMEMCMP +-/* unreal cases for wmemcmp */ +- .p2align 4 +-L(73bytes): +- movdqu -73(%rsi), %xmm1 +- movdqu -73(%rdi), %xmm2 +- mov $-73, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(57bytes): +- movdqu -57(%rdi), %xmm2 +- movdqu -57(%rsi), %xmm1 +- mov $-57, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(41bytes): +- movdqu -41(%rdi), %xmm2 +- movdqu -41(%rsi), %xmm1 +- mov $-41, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(25bytes): +- movdqu -25(%rdi), %xmm2 +- movdqu -25(%rsi), %xmm1 +- mov $-25, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -9(%rdi), %rax +- mov -9(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- movzbl -1(%rdi), %eax +- movzbl -1(%rsi), %ecx +- sub %ecx, %eax +- ret +- +- .p2align 4 +-L(74bytes): +- movdqu -74(%rsi), %xmm1 +- movdqu -74(%rdi), %xmm2 +- mov $-74, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(58bytes): +- movdqu -58(%rdi), %xmm2 +- movdqu -58(%rsi), %xmm1 +- mov $-58, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(42bytes): +- movdqu -42(%rdi), %xmm2 +- movdqu -42(%rsi), %xmm1 +- mov $-42, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(26bytes): +- movdqu -26(%rdi), %xmm2 +- movdqu -26(%rsi), %xmm1 +- mov $-26, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -10(%rdi), %rax +- mov -10(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- movzwl -2(%rdi), %eax +- movzwl -2(%rsi), %ecx +- jmp L(diffin2bytes) +- +- .p2align 4 +-L(75bytes): +- movdqu -75(%rsi), %xmm1 +- movdqu -75(%rdi), %xmm2 +- mov $-75, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(59bytes): +- movdqu -59(%rdi), %xmm2 +- movdqu -59(%rsi), %xmm1 +- mov $-59, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(43bytes): +- movdqu -43(%rdi), %xmm2 +- movdqu -43(%rsi), %xmm1 +- mov $-43, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(27bytes): +- movdqu -27(%rdi), %xmm2 +- movdqu -27(%rsi), %xmm1 +- mov $-27, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -11(%rdi), %rax +- mov -11(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- mov -4(%rdi), %eax +- mov -4(%rsi), %ecx +- cmp %eax, %ecx +- jne L(diffin4bytes) +- xor %eax, %eax +- ret +-# endif +- .p2align 4 +-L(76bytes): +- movdqu -76(%rsi), %xmm1 +- movdqu -76(%rdi), %xmm2 +- mov $-76, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(60bytes): +- movdqu -60(%rdi), %xmm2 +- movdqu -60(%rsi), %xmm1 +- mov $-60, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(44bytes): +- movdqu -44(%rdi), %xmm2 +- movdqu -44(%rsi), %xmm1 +- mov $-44, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(28bytes): +- movdqu -28(%rdi), %xmm2 +- movdqu -28(%rsi), %xmm1 +- mov $-28, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -12(%rdi), %rax +- mov -12(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- mov -4(%rsi), %ecx +-# ifndef USE_AS_WMEMCMP +- mov -4(%rdi), %eax +- cmp %eax, %ecx +-# else +- cmp -4(%rdi), %ecx +-# endif +- jne L(diffin4bytes) +- xor %eax, %eax +- ret +- +-# ifndef USE_AS_WMEMCMP +-/* unreal cases for wmemcmp */ +- .p2align 4 +-L(77bytes): +- movdqu -77(%rsi), %xmm1 +- movdqu -77(%rdi), %xmm2 +- mov $-77, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(61bytes): +- movdqu -61(%rdi), %xmm2 +- movdqu -61(%rsi), %xmm1 +- mov $-61, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(45bytes): +- movdqu -45(%rdi), %xmm2 +- movdqu -45(%rsi), %xmm1 +- mov $-45, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(29bytes): +- movdqu -29(%rdi), %xmm2 +- movdqu -29(%rsi), %xmm1 +- mov $-29, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- +- mov -13(%rdi), %rax +- mov -13(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(78bytes): +- movdqu -78(%rsi), %xmm1 +- movdqu -78(%rdi), %xmm2 +- mov $-78, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(62bytes): +- movdqu -62(%rdi), %xmm2 +- movdqu -62(%rsi), %xmm1 +- mov $-62, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(46bytes): +- movdqu -46(%rdi), %xmm2 +- movdqu -46(%rsi), %xmm1 +- mov $-46, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(30bytes): +- movdqu -30(%rdi), %xmm2 +- movdqu -30(%rsi), %xmm1 +- mov $-30, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -14(%rdi), %rax +- mov -14(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +- .p2align 4 +-L(79bytes): +- movdqu -79(%rsi), %xmm1 +- movdqu -79(%rdi), %xmm2 +- mov $-79, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(63bytes): +- movdqu -63(%rdi), %xmm2 +- movdqu -63(%rsi), %xmm1 +- mov $-63, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(47bytes): +- movdqu -47(%rdi), %xmm2 +- movdqu -47(%rsi), %xmm1 +- mov $-47, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(31bytes): +- movdqu -31(%rdi), %xmm2 +- movdqu -31(%rsi), %xmm1 +- mov $-31, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- mov -15(%rdi), %rax +- mov -15(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +-# endif +- .p2align 4 +-L(64bytes): +- movdqu -64(%rdi), %xmm2 +- movdqu -64(%rsi), %xmm1 +- mov $-64, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(48bytes): +- movdqu -48(%rdi), %xmm2 +- movdqu -48(%rsi), %xmm1 +- mov $-48, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +-L(32bytes): +- movdqu -32(%rdi), %xmm2 +- movdqu -32(%rsi), %xmm1 +- mov $-32, %dl +- pxor %xmm1, %xmm2 +- ptest %xmm2, %xmm0 +- jnc L(less16bytes) +- +- mov -16(%rdi), %rax +- mov -16(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- +- mov -8(%rdi), %rax +- mov -8(%rsi), %rcx +- cmp %rax, %rcx +- jne L(diffin8bytes) +- xor %eax, %eax +- ret +- +-/* +- * Aligned 8 bytes to avoid 2 branch "taken" in one 16 alinged code block. +- */ +- .p2align 3 +-L(less16bytes): +- movsbq %dl, %rdx +- mov (%rsi, %rdx), %rcx +- mov (%rdi, %rdx), %rax +- cmp %rax, %rcx +- jne L(diffin8bytes) +- mov 8(%rsi, %rdx), %rcx +- mov 8(%rdi, %rdx), %rax +-L(diffin8bytes): +- cmp %eax, %ecx +- jne L(diffin4bytes) +- shr $32, %rcx +- shr $32, %rax +- ++ pmovmskb %xmm0, %ecx ++ incw %cx ++ jnz L(loop_end_ret) ++ ++ pmovmskb %xmm1, %ecx ++ notw %cx ++ sall $16, %ecx ++ jnz L(loop_end_ret) ++ ++ pmovmskb %xmm2, %ecx ++ notw %cx ++ shlq $32, %rcx ++ jnz L(loop_end_ret) ++ ++ addq $48, %rdi ++ addq $48, %rsi ++ movq %rax, %rcx ++ ++ .p2align 4,, 6 ++L(loop_end_ret): ++ bsfq %rcx, %rcx + # ifdef USE_AS_WMEMCMP +-/* for wmemcmp */ +- cmp %eax, %ecx +- jne L(diffin4bytes) +- xor %eax, %eax +- ret +-# endif +- +-L(diffin4bytes): +-# ifndef USE_AS_WMEMCMP +- cmp %cx, %ax +- jne L(diffin2bytes) +- shr $16, %ecx +- shr $16, %eax +-L(diffin2bytes): +- cmp %cl, %al +- jne L(end) +- and $0xffff, %eax +- and $0xffff, %ecx +- sub %ecx, %eax +- ret +- +- .p2align 4 +-L(end): +- and $0xff, %eax +- and $0xff, %ecx +- sub %ecx, %eax +- ret ++ movl (%rdi, %rcx), %eax ++ xorl %edx, %edx ++ cmpl (%rsi, %rcx), %eax ++ setg %dl ++ leal -1(%rdx, %rdx), %eax + # else +- +-/* for wmemcmp */ +- mov $1, %eax +- jl L(nequal_bigger) +- neg %eax +- ret +- +- .p2align 4 +-L(nequal_bigger): +- ret +- +-L(unreal_case): +- xor %eax, %eax +- ret ++ movzbl (%rdi, %rcx), %eax ++ movzbl (%rsi, %rcx), %ecx ++ subl %ecx, %eax + # endif +- ++ ret + END (MEMCMP) +- +- .section .rodata.sse4.1,"a",@progbits +- .p2align 3 +-# ifndef USE_AS_WMEMCMP +-L(table_64bytes): +- .int JMPTBL (L(0bytes), L(table_64bytes)) +- .int JMPTBL (L(1bytes), L(table_64bytes)) +- .int JMPTBL (L(2bytes), L(table_64bytes)) +- .int JMPTBL (L(3bytes), L(table_64bytes)) +- .int JMPTBL (L(4bytes), L(table_64bytes)) +- .int JMPTBL (L(5bytes), L(table_64bytes)) +- .int JMPTBL (L(6bytes), L(table_64bytes)) +- .int JMPTBL (L(7bytes), L(table_64bytes)) +- .int JMPTBL (L(8bytes), L(table_64bytes)) +- .int JMPTBL (L(9bytes), L(table_64bytes)) +- .int JMPTBL (L(10bytes), L(table_64bytes)) +- .int JMPTBL (L(11bytes), L(table_64bytes)) +- .int JMPTBL (L(12bytes), L(table_64bytes)) +- .int JMPTBL (L(13bytes), L(table_64bytes)) +- .int JMPTBL (L(14bytes), L(table_64bytes)) +- .int JMPTBL (L(15bytes), L(table_64bytes)) +- .int JMPTBL (L(16bytes), L(table_64bytes)) +- .int JMPTBL (L(17bytes), L(table_64bytes)) +- .int JMPTBL (L(18bytes), L(table_64bytes)) +- .int JMPTBL (L(19bytes), L(table_64bytes)) +- .int JMPTBL (L(20bytes), L(table_64bytes)) +- .int JMPTBL (L(21bytes), L(table_64bytes)) +- .int JMPTBL (L(22bytes), L(table_64bytes)) +- .int JMPTBL (L(23bytes), L(table_64bytes)) +- .int JMPTBL (L(24bytes), L(table_64bytes)) +- .int JMPTBL (L(25bytes), L(table_64bytes)) +- .int JMPTBL (L(26bytes), L(table_64bytes)) +- .int JMPTBL (L(27bytes), L(table_64bytes)) +- .int JMPTBL (L(28bytes), L(table_64bytes)) +- .int JMPTBL (L(29bytes), L(table_64bytes)) +- .int JMPTBL (L(30bytes), L(table_64bytes)) +- .int JMPTBL (L(31bytes), L(table_64bytes)) +- .int JMPTBL (L(32bytes), L(table_64bytes)) +- .int JMPTBL (L(33bytes), L(table_64bytes)) +- .int JMPTBL (L(34bytes), L(table_64bytes)) +- .int JMPTBL (L(35bytes), L(table_64bytes)) +- .int JMPTBL (L(36bytes), L(table_64bytes)) +- .int JMPTBL (L(37bytes), L(table_64bytes)) +- .int JMPTBL (L(38bytes), L(table_64bytes)) +- .int JMPTBL (L(39bytes), L(table_64bytes)) +- .int JMPTBL (L(40bytes), L(table_64bytes)) +- .int JMPTBL (L(41bytes), L(table_64bytes)) +- .int JMPTBL (L(42bytes), L(table_64bytes)) +- .int JMPTBL (L(43bytes), L(table_64bytes)) +- .int JMPTBL (L(44bytes), L(table_64bytes)) +- .int JMPTBL (L(45bytes), L(table_64bytes)) +- .int JMPTBL (L(46bytes), L(table_64bytes)) +- .int JMPTBL (L(47bytes), L(table_64bytes)) +- .int JMPTBL (L(48bytes), L(table_64bytes)) +- .int JMPTBL (L(49bytes), L(table_64bytes)) +- .int JMPTBL (L(50bytes), L(table_64bytes)) +- .int JMPTBL (L(51bytes), L(table_64bytes)) +- .int JMPTBL (L(52bytes), L(table_64bytes)) +- .int JMPTBL (L(53bytes), L(table_64bytes)) +- .int JMPTBL (L(54bytes), L(table_64bytes)) +- .int JMPTBL (L(55bytes), L(table_64bytes)) +- .int JMPTBL (L(56bytes), L(table_64bytes)) +- .int JMPTBL (L(57bytes), L(table_64bytes)) +- .int JMPTBL (L(58bytes), L(table_64bytes)) +- .int JMPTBL (L(59bytes), L(table_64bytes)) +- .int JMPTBL (L(60bytes), L(table_64bytes)) +- .int JMPTBL (L(61bytes), L(table_64bytes)) +- .int JMPTBL (L(62bytes), L(table_64bytes)) +- .int JMPTBL (L(63bytes), L(table_64bytes)) +- .int JMPTBL (L(64bytes), L(table_64bytes)) +- .int JMPTBL (L(65bytes), L(table_64bytes)) +- .int JMPTBL (L(66bytes), L(table_64bytes)) +- .int JMPTBL (L(67bytes), L(table_64bytes)) +- .int JMPTBL (L(68bytes), L(table_64bytes)) +- .int JMPTBL (L(69bytes), L(table_64bytes)) +- .int JMPTBL (L(70bytes), L(table_64bytes)) +- .int JMPTBL (L(71bytes), L(table_64bytes)) +- .int JMPTBL (L(72bytes), L(table_64bytes)) +- .int JMPTBL (L(73bytes), L(table_64bytes)) +- .int JMPTBL (L(74bytes), L(table_64bytes)) +- .int JMPTBL (L(75bytes), L(table_64bytes)) +- .int JMPTBL (L(76bytes), L(table_64bytes)) +- .int JMPTBL (L(77bytes), L(table_64bytes)) +- .int JMPTBL (L(78bytes), L(table_64bytes)) +- .int JMPTBL (L(79bytes), L(table_64bytes)) +-# else +-L(table_64bytes): +- .int JMPTBL (L(0bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(4bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(8bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(12bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(16bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(20bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(24bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(28bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(32bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(36bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(40bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(44bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(48bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(52bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(56bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(60bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(64bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(68bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(72bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(76bytes), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +- .int JMPTBL (L(unreal_case), L(table_64bytes)) +-# endif + #endif diff --git a/SOURCES/glibc-upstream-2.34-184.patch b/SOURCES/glibc-upstream-2.34-184.patch new file mode 100644 index 0000000..805f91e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-184.patch @@ -0,0 +1,104 @@ +commit 4bbd0f866ad0ff197f72346f776ebee9b7e1a706 +Author: Noah Goldstein +Date: Fri Dec 3 15:29:25 2021 -0800 + + x86-64: Use notl in EVEX strcmp [BZ #28646] + + Must use notl %edi here as lower bits are for CHAR comparisons + potentially out of range thus can be 0 without indicating mismatch. + This fixes BZ #28646. + + Co-Authored-By: H.J. Lu + (cherry picked from commit 4df1fa6ddc8925a75f3da644d5da3bb16eb33f02) + +diff --git a/string/test-strcmp.c b/string/test-strcmp.c +index 7feababf4ddc5603..a0255b9625fbcedd 100644 +--- a/string/test-strcmp.c ++++ b/string/test-strcmp.c +@@ -25,6 +25,7 @@ + # define TEST_NAME "strcmp" + #endif + #include "test-string.h" ++#include + + #ifdef WIDE + # include +@@ -392,6 +393,32 @@ check2 (void) + } + } + ++static void ++check3 (void) ++{ ++ size_t size = 0xd000 + 0x4000; ++ CHAR *s1, *s2; ++ CHAR *buffer1 = mmap (NULL, size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANON, -1, 0); ++ CHAR *buffer2 = mmap (NULL, size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANON, -1, 0); ++ if (buffer1 == MAP_FAILED || buffer1 == MAP_FAILED) ++ error (EXIT_UNSUPPORTED, errno, "mmap failed"); ++ ++ s1 = (CHAR *) (buffer1 + 0x8f8 / sizeof (CHAR)); ++ s2 = (CHAR *) (buffer2 + 0xcff3 / sizeof (CHAR)); ++ ++ STRCPY(s1, L("/export/redhat/rpms/BUILD/java-1.8.0-openjdk-1.8.0.312.b07-2.fc35.x86_64/openjdk/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java")); ++ STRCPY(s2, L("/export/redhat/rpms/BUILD/java-1.8.0-openjdk-1.8.0.312.b07-2.fc35.x86_64/openjdk/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java")); ++ ++ int exp_result = SIMPLE_STRCMP (s1, s2); ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, s1, s2, exp_result); ++ ++ munmap ((void *) buffer1, size); ++ munmap ((void *) buffer2, size); ++} ++ + int + test_main (void) + { +@@ -400,6 +427,7 @@ test_main (void) + test_init (); + check(); + check2 (); ++ check3 (); + + printf ("%23s", ""); + FOR_EACH_IMPL (impl, 0) +diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S +index 82f12ac89bcae20b..6f5c4bf984da2b80 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-evex.S ++++ b/sysdeps/x86_64/multiarch/strcmp-evex.S +@@ -656,12 +656,13 @@ L(loop_cross_page): + in YMM3 and 32 bytes at VEC_SIZE(%rdx, %r10). */ + VPCMP $0, VEC_SIZE(%rdx, %r10), %YMM3, %k3{%k4} + kmovd %k3, %edi ++ /* Must use notl %edi here as lower bits are for CHAR ++ comparisons potentially out of range thus can be 0 without ++ indicating mismatch. */ ++ notl %edi + # ifdef USE_AS_WCSCMP + /* Don't use subl since it is the upper 8 bits of EDI below. */ +- notl %edi + andl $0xff, %edi +-# else +- incl %edi + # endif + + # ifdef USE_AS_WCSCMP +@@ -743,12 +744,13 @@ L(loop_cross_page_2_vec): + in YMM1 and 32 bytes at (VEC_SIZE * 3)(%rdx, %r10). */ + VPCMP $0, (VEC_SIZE * 3)(%rdx, %r10), %YMM1, %k3{%k4} + kmovd %k3, %edi ++ /* Must use notl %edi here as lower bits are for CHAR ++ comparisons potentially out of range thus can be 0 without ++ indicating mismatch. */ ++ notl %edi + # ifdef USE_AS_WCSCMP + /* Don't use subl since it is the upper 8 bits of EDI below. */ +- notl %edi + andl $0xff, %edi +-# else +- incl %edi + # endif + + # ifdef USE_AS_WCSCMP diff --git a/SOURCES/glibc-upstream-2.34-185.patch b/SOURCES/glibc-upstream-2.34-185.patch new file mode 100644 index 0000000..f06f86f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-185.patch @@ -0,0 +1,30 @@ +commit f3a99b2216114f89b20329ae7664b764248b4bbd +Author: H.J. Lu +Date: Mon Dec 6 07:14:12 2021 -0800 + + x86: Don't set Prefer_No_AVX512 for processors with AVX512 and AVX-VNNI + + Don't set Prefer_No_AVX512 on processors with AVX512 and AVX-VNNI since + they won't lower CPU frequency when ZMM load and store instructions are + used. + + (cherry picked from commit ceeffe968c01b1202e482f4855cb6baf5c6cb713) + +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index f4d4049e391cbabd..09590d8794b1c6fb 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -566,8 +566,11 @@ disable_tsx: + |= bit_arch_Prefer_No_VZEROUPPER; + else + { +- cpu_features->preferred[index_arch_Prefer_No_AVX512] +- |= bit_arch_Prefer_No_AVX512; ++ /* Processors with AVX512 and AVX-VNNI won't lower CPU frequency ++ when ZMM load and store instructions are used. */ ++ if (!CPU_FEATURES_CPU_P (cpu_features, AVX_VNNI)) ++ cpu_features->preferred[index_arch_Prefer_No_AVX512] ++ |= bit_arch_Prefer_No_AVX512; + + /* Avoid RTM abort triggered by VZEROUPPER inside a + transactionally executing RTM region. */ diff --git a/SOURCES/glibc-upstream-2.34-186.patch b/SOURCES/glibc-upstream-2.34-186.patch new file mode 100644 index 0000000..a046844 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-186.patch @@ -0,0 +1,384 @@ +commit c796418d00f65c8c5fbed477f3ba6da2bee64ece +Author: Noah Goldstein +Date: Fri Dec 24 18:54:41 2021 -0600 + + x86: Optimize L(less_vec) case in memcmp-evex-movbe.S + + No bug. + Optimizations are twofold. + + 1) Replace page cross and 0/1 checks with masked load instructions in + L(less_vec). In applications this reduces branch-misses in the + hot [0, 32] case. + 2) Change controlflow so that L(less_vec) case gets the fall through. + + Change 2) helps copies in the [0, 32] size range but comes at the cost + of copies in the [33, 64] size range. From profiles of GCC and + Python3, 94%+ and 99%+ of calls are in the [0, 32] range so this + appears to the the right tradeoff. + + Signed-off-by: Noah Goldstein + Reviewed-by: H.J. Lu + (cherry picked from commit abddd61de090ae84e380aff68a98bd94ef704667) + +diff --git a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S +index 640f6757fac8a356..d2899e7c7078cd41 100644 +--- a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S ++++ b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S +@@ -62,15 +62,18 @@ Latency: + # define VMOVU vmovdqu64 + + # ifdef USE_AS_WMEMCMP ++# define VMOVU_MASK vmovdqu32 + # define CHAR_SIZE 4 + # define VPCMP vpcmpd + # define VPTEST vptestmd + # else ++# define VMOVU_MASK vmovdqu8 + # define CHAR_SIZE 1 + # define VPCMP vpcmpub + # define VPTEST vptestmb + # endif + ++ + # define VEC_SIZE 32 + # define PAGE_SIZE 4096 + # define CHAR_PER_VEC (VEC_SIZE / CHAR_SIZE) +@@ -102,12 +105,48 @@ ENTRY_P2ALIGN (MEMCMP, 6) + movl %edx, %edx + # endif + cmp $CHAR_PER_VEC, %RDX_LP +- jb L(less_vec) ++ /* Fall through for [0, VEC_SIZE] as its the hottest. */ ++ ja L(more_1x_vec) ++ ++ /* Create mask for CHAR's we want to compare. This allows us to ++ avoid having to include page cross logic. */ ++ movl $-1, %ecx ++ bzhil %edx, %ecx, %ecx ++ kmovd %ecx, %k2 ++ ++ /* Safe to load full ymm with mask. */ ++ VMOVU_MASK (%rsi), %YMM2{%k2} ++ VPCMP $4,(%rdi), %YMM2, %k1{%k2} ++ kmovd %k1, %eax ++ testl %eax, %eax ++ jnz L(return_vec_0) ++ ret + ++ .p2align 4 ++L(return_vec_0): ++ tzcntl %eax, %eax ++# ifdef USE_AS_WMEMCMP ++ movl (%rdi, %rax, CHAR_SIZE), %ecx ++ xorl %edx, %edx ++ cmpl (%rsi, %rax, CHAR_SIZE), %ecx ++ /* NB: no partial register stall here because xorl zero idiom ++ above. */ ++ setg %dl ++ leal -1(%rdx, %rdx), %eax ++# else ++ movzbl (%rsi, %rax), %ecx ++ movzbl (%rdi, %rax), %eax ++ subl %ecx, %eax ++# endif ++ ret ++ ++ ++ .p2align 4 ++L(more_1x_vec): + /* From VEC to 2 * VEC. No branch when size == VEC_SIZE. */ + VMOVU (%rsi), %YMM1 + /* Use compare not equals to directly check for mismatch. */ +- VPCMP $4, (%rdi), %YMM1, %k1 ++ VPCMP $4,(%rdi), %YMM1, %k1 + kmovd %k1, %eax + /* NB: eax must be destination register if going to + L(return_vec_[0,2]). For L(return_vec_3) destination register +@@ -131,13 +170,13 @@ ENTRY_P2ALIGN (MEMCMP, 6) + + /* Check third and fourth VEC no matter what. */ + VMOVU (VEC_SIZE * 2)(%rsi), %YMM3 +- VPCMP $4, (VEC_SIZE * 2)(%rdi), %YMM3, %k1 ++ VPCMP $4,(VEC_SIZE * 2)(%rdi), %YMM3, %k1 + kmovd %k1, %eax + testl %eax, %eax + jnz L(return_vec_2) + + VMOVU (VEC_SIZE * 3)(%rsi), %YMM4 +- VPCMP $4, (VEC_SIZE * 3)(%rdi), %YMM4, %k1 ++ VPCMP $4,(VEC_SIZE * 3)(%rdi), %YMM4, %k1 + kmovd %k1, %ecx + testl %ecx, %ecx + jnz L(return_vec_3) +@@ -169,7 +208,7 @@ ENTRY_P2ALIGN (MEMCMP, 6) + VMOVU (VEC_SIZE * 3)(%rsi), %YMM4 + /* Ternary logic to xor (VEC_SIZE * 3)(%rdi) with YMM4 while + oring with YMM1. Result is stored in YMM4. */ +- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4 ++ vpternlogd $0xde,(VEC_SIZE * 3)(%rdi), %YMM1, %YMM4 + + /* Or together YMM2, YMM3, and YMM4 into YMM4. */ + vpternlogd $0xfe, %YMM2, %YMM3, %YMM4 +@@ -184,7 +223,8 @@ ENTRY_P2ALIGN (MEMCMP, 6) + /* NB: eax must be zero to reach here. */ + ret + +- .p2align 4 ++ ++ .p2align 4,, 8 + L(8x_end_return_vec_0_1_2_3): + movq %rdx, %rdi + L(8x_return_vec_0_1_2_3): +@@ -222,23 +262,6 @@ L(return_vec_3): + # endif + ret + +- .p2align 4 +-L(return_vec_0): +- tzcntl %eax, %eax +-# ifdef USE_AS_WMEMCMP +- movl (%rdi, %rax, CHAR_SIZE), %ecx +- xorl %edx, %edx +- cmpl (%rsi, %rax, CHAR_SIZE), %ecx +- /* NB: no partial register stall here because xorl zero idiom +- above. */ +- setg %dl +- leal -1(%rdx, %rdx), %eax +-# else +- movzbl (%rsi, %rax), %ecx +- movzbl (%rdi, %rax), %eax +- subl %ecx, %eax +-# endif +- ret + + .p2align 4 + L(return_vec_1): +@@ -297,7 +320,7 @@ L(loop_4x_vec): + VMOVU (VEC_SIZE * 2)(%rsi, %rdi), %YMM3 + vpxorq (VEC_SIZE * 2)(%rdi), %YMM3, %YMM3 + VMOVU (VEC_SIZE * 3)(%rsi, %rdi), %YMM4 +- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4 ++ vpternlogd $0xde,(VEC_SIZE * 3)(%rdi), %YMM1, %YMM4 + vpternlogd $0xfe, %YMM2, %YMM3, %YMM4 + VPTEST %YMM4, %YMM4, %k1 + kmovd %k1, %ecx +@@ -324,7 +347,7 @@ L(loop_4x_vec): + VMOVU VEC_SIZE(%rsi, %rdx), %YMM2 + vpxorq VEC_SIZE(%rdx), %YMM2, %YMM2 + VMOVU (VEC_SIZE * 3)(%rsi, %rdx), %YMM4 +- vpternlogd $0xde, (VEC_SIZE * 3)(%rdx), %YMM1, %YMM4 ++ vpternlogd $0xde,(VEC_SIZE * 3)(%rdx), %YMM1, %YMM4 + vpternlogd $0xfe, %YMM2, %YMM3, %YMM4 + VPTEST %YMM4, %YMM4, %k1 + kmovd %k1, %ecx +@@ -336,14 +359,14 @@ L(loop_4x_vec): + /* Only entry is from L(more_8x_vec). */ + .p2align 4,, 10 + L(8x_last_2x_vec): +- VPCMP $4, (VEC_SIZE * 2)(%rdx), %YMM3, %k1 ++ VPCMP $4,(VEC_SIZE * 2)(%rdx), %YMM3, %k1 + kmovd %k1, %eax + testl %eax, %eax + jnz L(8x_return_vec_2) + /* Naturally aligned to 16 bytes. */ + L(8x_last_1x_vec): + VMOVU (VEC_SIZE * 3)(%rsi, %rdx), %YMM1 +- VPCMP $4, (VEC_SIZE * 3)(%rdx), %YMM1, %k1 ++ VPCMP $4,(VEC_SIZE * 3)(%rdx), %YMM1, %k1 + kmovd %k1, %eax + testl %eax, %eax + jnz L(8x_return_vec_3) +@@ -392,7 +415,9 @@ L(last_1x_vec): + jnz L(return_vec_0_end) + ret + +- .p2align 4,, 10 ++ ++ /* Don't align. Takes 2-fetch blocks either way and aligning ++ will cause code to spill into another cacheline. */ + L(return_vec_1_end): + /* Use bsf to save code size. This is necessary to have + L(one_or_less) fit in aligning bytes between. */ +@@ -411,31 +436,8 @@ L(return_vec_1_end): + # endif + ret + +- /* NB: L(one_or_less) fits in alignment padding between +- L(return_vec_1_end) and L(return_vec_0_end). */ +-# ifdef USE_AS_WMEMCMP +-L(one_or_less): +- jb L(zero) +- movl (%rdi), %ecx +- xorl %edx, %edx +- cmpl (%rsi), %ecx +- je L(zero) +- setg %dl +- leal -1(%rdx, %rdx), %eax +- ret +-# else +-L(one_or_less): +- jb L(zero) +- movzbl (%rsi), %ecx +- movzbl (%rdi), %eax +- subl %ecx, %eax +- ret +-# endif +-L(zero): +- xorl %eax, %eax +- ret +- +- .p2align 4 ++ /* Don't align. Takes 2-fetch blocks either way and aligning ++ will cause code to spill into another cacheline. */ + L(return_vec_0_end): + tzcntl %eax, %eax + addl %edx, %eax +@@ -451,146 +453,7 @@ L(return_vec_0_end): + subl %ecx, %eax + # endif + ret ++ /* 1-byte until next cache line. */ + +- .p2align 4 +-L(less_vec): +- /* Check if one or less CHAR. This is necessary for size == 0 +- but is also faster for size == CHAR_SIZE. */ +- cmpl $1, %edx +- jbe L(one_or_less) +- +- /* Check if loading one VEC from either s1 or s2 could cause a +- page cross. This can have false positives but is by far the +- fastest method. */ +- movl %edi, %eax +- orl %esi, %eax +- andl $(PAGE_SIZE - 1), %eax +- cmpl $(PAGE_SIZE - VEC_SIZE), %eax +- jg L(page_cross_less_vec) +- +- /* No page cross possible. */ +- VMOVU (%rsi), %YMM2 +- VPCMP $4, (%rdi), %YMM2, %k1 +- kmovd %k1, %eax +- /* Check if any matches where in bounds. Intentionally not +- storing result in eax to limit dependency chain if it goes to +- L(return_vec_0_lv). */ +- bzhil %edx, %eax, %edx +- jnz L(return_vec_0_lv) +- xorl %eax, %eax +- ret +- +- /* Essentially duplicate of L(return_vec_0). Ends up not costing +- any code as shrinks L(less_vec) by allowing 2-byte encoding of +- the jump and ends up fitting in aligning bytes. As well fits on +- same cache line as L(less_vec) so also saves a line from having +- to be fetched on cold calls to memcmp. */ +- .p2align 4,, 4 +-L(return_vec_0_lv): +- tzcntl %eax, %eax +-# ifdef USE_AS_WMEMCMP +- movl (%rdi, %rax, CHAR_SIZE), %ecx +- xorl %edx, %edx +- cmpl (%rsi, %rax, CHAR_SIZE), %ecx +- /* NB: no partial register stall here because xorl zero idiom +- above. */ +- setg %dl +- leal -1(%rdx, %rdx), %eax +-# else +- movzbl (%rsi, %rax), %ecx +- movzbl (%rdi, %rax), %eax +- subl %ecx, %eax +-# endif +- ret +- +- .p2align 4 +-L(page_cross_less_vec): +- /* if USE_AS_WMEMCMP it can only be 0, 4, 8, 12, 16, 20, 24, 28 +- bytes. */ +- cmpl $(16 / CHAR_SIZE), %edx +- jae L(between_16_31) +-# ifndef USE_AS_WMEMCMP +- cmpl $8, %edx +- jae L(between_8_15) +- cmpl $4, %edx +- jb L(between_2_3) +- +- /* Load as big endian with overlapping movbe to avoid branches. +- */ +- movbe (%rdi), %eax +- movbe (%rsi), %ecx +- shlq $32, %rax +- shlq $32, %rcx +- movbe -4(%rdi, %rdx), %edi +- movbe -4(%rsi, %rdx), %esi +- orq %rdi, %rax +- orq %rsi, %rcx +- subq %rcx, %rax +- /* edx is guranteed to be positive int32 in range [4, 7]. */ +- cmovne %edx, %eax +- /* ecx is -1 if rcx > rax. Otherwise 0. */ +- sbbl %ecx, %ecx +- /* If rcx > rax, then ecx is 0 and eax is positive. If rcx == +- rax then eax and ecx are zero. If rax < rax then ecx is -1 so +- eax doesn't matter. */ +- orl %ecx, %eax +- ret +- +- .p2align 4,, 8 +-L(between_8_15): +-# endif +- /* If USE_AS_WMEMCMP fall through into 8-15 byte case. */ +- vmovq (%rdi), %xmm1 +- vmovq (%rsi), %xmm2 +- VPCMP $4, %xmm1, %xmm2, %k1 +- kmovd %k1, %eax +- testl %eax, %eax +- jnz L(return_vec_0_lv) +- /* Use overlapping loads to avoid branches. */ +- vmovq -8(%rdi, %rdx, CHAR_SIZE), %xmm1 +- vmovq -8(%rsi, %rdx, CHAR_SIZE), %xmm2 +- VPCMP $4, %xmm1, %xmm2, %k1 +- addl $(CHAR_PER_VEC - (8 / CHAR_SIZE)), %edx +- kmovd %k1, %eax +- testl %eax, %eax +- jnz L(return_vec_0_end) +- ret +- +- .p2align 4,, 8 +-L(between_16_31): +- /* From 16 to 31 bytes. No branch when size == 16. */ +- +- /* Use movups to save code size. */ +- vmovdqu (%rsi), %xmm2 +- VPCMP $4, (%rdi), %xmm2, %k1 +- kmovd %k1, %eax +- testl %eax, %eax +- jnz L(return_vec_0_lv) +- /* Use overlapping loads to avoid branches. */ +- vmovdqu -16(%rsi, %rdx, CHAR_SIZE), %xmm2 +- VPCMP $4, -16(%rdi, %rdx, CHAR_SIZE), %xmm2, %k1 +- addl $(CHAR_PER_VEC - (16 / CHAR_SIZE)), %edx +- kmovd %k1, %eax +- testl %eax, %eax +- jnz L(return_vec_0_end) +- ret +- +-# ifndef USE_AS_WMEMCMP +-L(between_2_3): +- /* Load as big endian to avoid branches. */ +- movzwl (%rdi), %eax +- movzwl (%rsi), %ecx +- shll $8, %eax +- shll $8, %ecx +- bswap %eax +- bswap %ecx +- movzbl -1(%rdi, %rdx), %edi +- movzbl -1(%rsi, %rdx), %esi +- orl %edi, %eax +- orl %esi, %ecx +- /* Subtraction is okay because the upper 8 bits are zero. */ +- subl %ecx, %eax +- ret +-# endif + END (MEMCMP) + #endif diff --git a/SOURCES/glibc-upstream-2.34-187.patch b/SOURCES/glibc-upstream-2.34-187.patch new file mode 100644 index 0000000..6186aeb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-187.patch @@ -0,0 +1,42 @@ +commit 9681691402052b727e01ae3375c73e0f76566593 +Author: Adhemerval Zanella +Date: Wed Apr 27 13:59:26 2022 -0300 + + linux: Fix missing internal 64 bit time_t stat usage + + These are two missing spots initially done by 52a5fe70a2c77935. + + Checked on i686-linux-gnu. + + (cherry picked from commit 834ddd0432f68d6dc85b6aac95065721af0d86e9) + +diff --git a/sysdeps/unix/sysv/linux/faccessat.c b/sysdeps/unix/sysv/linux/faccessat.c +index 13160d32499c4e58..00e4ce7f80ee2dfe 100644 +--- a/sysdeps/unix/sysv/linux/faccessat.c ++++ b/sysdeps/unix/sysv/linux/faccessat.c +@@ -39,8 +39,8 @@ __faccessat (int fd, const char *file, int mode, int flag) + if ((flag == 0 || ((flag & ~AT_EACCESS) == 0 && ! __libc_enable_secure))) + return INLINE_SYSCALL (faccessat, 3, fd, file, mode); + +- struct stat64 stats; +- if (__fstatat64 (fd, file, &stats, flag & AT_SYMLINK_NOFOLLOW)) ++ struct __stat64_t64 stats; ++ if (__fstatat64_time64 (fd, file, &stats, flag & AT_SYMLINK_NOFOLLOW)) + return -1; + + mode &= (X_OK | W_OK | R_OK); /* Clear any bogus bits. */ +diff --git a/sysdeps/unix/sysv/linux/pathconf.c b/sysdeps/unix/sysv/linux/pathconf.c +index b599a66c930cad4d..f79930303118ebcd 100644 +--- a/sysdeps/unix/sysv/linux/pathconf.c ++++ b/sysdeps/unix/sysv/linux/pathconf.c +@@ -110,8 +110,8 @@ distinguish_extX (const struct statfs *fsbuf, const char *file, int fd) + && strcmp (mntbuf.mnt_type, "ext4") != 0) + continue; + +- struct stat64 fsst; +- if (__stat64 (mntbuf.mnt_dir, &fsst) >= 0 ++ struct __stat64_t64 fsst; ++ if (__stat64_time64 (mntbuf.mnt_dir, &fsst) >= 0 + && st.st_dev == fsst.st_dev) + { + if (strcmp (mntbuf.mnt_type, "ext4") == 0) diff --git a/SOURCES/glibc-upstream-2.34-188.patch b/SOURCES/glibc-upstream-2.34-188.patch new file mode 100644 index 0000000..8b49369 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-188.patch @@ -0,0 +1,39 @@ +commit 55640ed3fde48360a8e8083be4843bd2dc7cecfe +Author: Carlos O'Donell +Date: Tue Apr 26 10:52:41 2022 -0400 + + i386: Regenerate ulps + + These failures were caught while building glibc master for Fedora + Rawhide which is built with '-mtune=generic -msse2 -mfpmath=sse' + using gcc 11.3 (gcc-11.3.1-2.fc35) on a Cascadelake Intel Xeon + processor. + + (cherry picked from commit e465d97653311c3687aee49de782177353acfe86) + +diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps +index 7601049110789201..84e6686eba5fe79a 100644 +--- a/sysdeps/i386/fpu/libm-test-ulps ++++ b/sysdeps/i386/fpu/libm-test-ulps +@@ -668,7 +668,7 @@ ldouble: 4 + + Function: Imaginary part of "clog10": + double: 2 +-float: 1 ++float: 2 + float128: 2 + ldouble: 2 + +diff --git a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps +index a39c89cec1141935..cc21e6907fe8b6a3 100644 +--- a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps ++++ b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps +@@ -668,7 +668,7 @@ ldouble: 4 + + Function: Imaginary part of "clog10": + double: 2 +-float: 1 ++float: 2 + float128: 2 + ldouble: 2 + diff --git a/SOURCES/glibc-upstream-2.34-189.patch b/SOURCES/glibc-upstream-2.34-189.patch new file mode 100644 index 0000000..3a5889c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-189.patch @@ -0,0 +1,116 @@ +commit 88a8637cb4658cd91a002659db05867716b88b36 +Author: Adhemerval Zanella +Date: Wed Apr 27 13:40:30 2022 -0300 + + linux: Fix fchmodat with AT_SYMLINK_NOFOLLOW for 64 bit time_t (BZ#29097) + + The AT_SYMLINK_NOFOLLOW emulation ues the default 32 bit stat internal + calls, which fails with EOVERFLOW if the file constains timestamps + beyond 2038. + + Checked on i686-linux-gnu. + + (cherry picked from commit 118a2aee07f64d605b6668cbe195c1f44eac6be6) + +diff --git a/io/Makefile b/io/Makefile +index 9871ecbc74020a6d..01968b81042e01e4 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -81,16 +81,17 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ + tst-closefrom \ + + tests-time64 := \ ++ tst-fcntl-time64 \ ++ tst-fts-time64 \ + tst-futimens-time64 \ + tst-futimes-time64\ +- tst-fts-time64 \ ++ tst-futimesat-time64 \ ++ tst-lchmod-time64 \ + tst-lutimes-time64 \ + tst-stat-time64 \ +- tst-futimesat-time64 \ + tst-utime-time64 \ + tst-utimensat-time64 \ + tst-utimes-time64 \ +- tst-fcntl-time64 \ + # tests-time64 + + # Likewise for statx, but we do not need static linking here. +@@ -134,6 +135,7 @@ CFLAGS-close.c += -fexceptions -fasynchronous-unwind-tables + + CFLAGS-test-stat.c += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE + CFLAGS-test-lfs.c += -D_LARGEFILE64_SOURCE ++CFLAGS-tst-lchmod.c += -D_FILE_OFFSET_BITS=64 + + test-stat2-ARGS = Makefile . $(objpfx)test-stat2 + +diff --git a/io/tst-lchmod-time64.c b/io/tst-lchmod-time64.c +new file mode 100644 +index 0000000000000000..f2b7cc9d358f2a77 +--- /dev/null ++++ b/io/tst-lchmod-time64.c +@@ -0,0 +1,2 @@ ++#define CHECK_TIME64 ++#include "tst-lchmod.c" +diff --git a/io/tst-lchmod.c b/io/tst-lchmod.c +index 0fe98e01b74b713d..472766b186975922 100644 +--- a/io/tst-lchmod.c ++++ b/io/tst-lchmod.c +@@ -66,10 +66,27 @@ select_path (bool do_relative_path, const char *full_path, const char *relative_ + return full_path; + } + ++static void ++update_file_time_to_y2038 (const char *fname, int flags) ++{ ++#ifdef CHECK_TIME64 ++ /* Y2038 threshold plus 1 second. */ ++ const struct timespec ts[] = { { 0x80000001LL, 0}, { 0x80000001LL } }; ++ TEST_VERIFY_EXIT (utimensat (AT_FDCWD, fname, ts, flags) == 0); ++#endif ++} ++ + static void + test_1 (bool do_relative_path, int (*chmod_func) (int fd, const char *, mode_t, int)) + { + char *tempdir = support_create_temp_directory ("tst-lchmod-"); ++#ifdef CHECK_TIME64 ++ if (!support_path_support_time64 (tempdir)) ++ { ++ puts ("info: test skipped, filesystem does not support 64 bit time_t"); ++ return; ++ } ++#endif + + char *path_dangling = xasprintf ("%s/dangling", tempdir); + char *path_file = xasprintf ("%s/file", tempdir); +@@ -93,9 +110,12 @@ test_1 (bool do_relative_path, int (*chmod_func) (int fd, const char *, mode_t, + xsymlink ("loop", path_loop); + xsymlink ("target-does-not-exist", path_dangling); + ++ update_file_time_to_y2038 (path_file, 0); ++ update_file_time_to_y2038 (path_to_file, AT_SYMLINK_NOFOLLOW); ++ + /* Check that the modes do not collide with what we will use in the + test. */ +- struct stat64 st; ++ struct stat st; + xstat (path_file, &st); + TEST_VERIFY ((st.st_mode & 0777) != 1); + xlstat (path_to_file, &st); +diff --git a/sysdeps/unix/sysv/linux/fchmodat.c b/sysdeps/unix/sysv/linux/fchmodat.c +index 5bd1eb96a5d78130..b0cf61949a9302d9 100644 +--- a/sysdeps/unix/sysv/linux/fchmodat.c ++++ b/sysdeps/unix/sysv/linux/fchmodat.c +@@ -48,8 +48,8 @@ fchmodat (int fd, const char *file, mode_t mode, int flag) + + /* Use fstatat because fstat does not work on O_PATH descriptors + before Linux 3.6. */ +- struct stat64 st; +- if (__fstatat64 (pathfd, "", &st, AT_EMPTY_PATH) != 0) ++ struct __stat64_t64 st; ++ if (__fstatat64_time64 (pathfd, "", &st, AT_EMPTY_PATH) != 0) + { + __close_nocancel (pathfd); + return -1; diff --git a/SOURCES/glibc-upstream-2.34-19.patch b/SOURCES/glibc-upstream-2.34-19.patch new file mode 100644 index 0000000..b0f0b9a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-19.patch @@ -0,0 +1,27 @@ +commit 114581bf53864aaee562ee237461fc394bc61963 +Author: Joseph Myers +Date: Tue Sep 14 13:51:58 2021 +0000 + + Update kernel version to 5.14 in tst-mman-consts.py + + This patch updates the kernel version in the test tst-mman-consts.py + to 5.14. (There are no new MAP_* constants covered by this test in + 5.14 that need any other header changes.) + + Tested with build-many-glibcs.py. + + (cherry picked from commit 4b39e3498324d1aea802fea8d4b8764f5ddb4fd1) + +diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py +index ee5b13ee1232fdf5..810433c238f31c25 100644 +--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py ++++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py +@@ -33,7 +33,7 @@ def main(): + help='C compiler (including options) to use') + args = parser.parse_args() + linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) +- linux_version_glibc = (5, 13) ++ linux_version_glibc = (5, 14) + sys.exit(glibcextract.compare_macro_consts( + '#define _GNU_SOURCE 1\n' + '#include \n', diff --git a/SOURCES/glibc-upstream-2.34-190.patch b/SOURCES/glibc-upstream-2.34-190.patch new file mode 100644 index 0000000..f21a4bf --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-190.patch @@ -0,0 +1,189 @@ +commit c66c92181ddbd82306537a608e8c0282587131de +Author: DJ Delorie +Date: Wed Mar 30 17:44:02 2022 -0400 + + posix/glob.c: update from gnulib + + Copied from gnulib/lib/glob.c in order to fix rhbz 1982608 + Also fixes swbz 25659 + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 7c477b57a31487eda516db02b9e04f22d1a6e6af) + +diff --git a/posix/glob.c b/posix/glob.c +index 593a4c358f3d42e5..6af310a1aa31401a 100644 +--- a/posix/glob.c ++++ b/posix/glob.c +@@ -21,13 +21,14 @@ + optimizes away the pattern == NULL test below. */ + # define _GL_ARG_NONNULL(params) + +-# include ++# include + + #endif + + #include + + #include ++#include + #include + #include + #include +@@ -56,6 +57,8 @@ + # define sysconf(id) __sysconf (id) + # define closedir(dir) __closedir (dir) + # define opendir(name) __opendir (name) ++# undef dirfd ++# define dirfd(str) __dirfd (str) + # define readdir(str) __readdir64 (str) + # define getpwnam_r(name, bufp, buf, len, res) \ + __getpwnam_r (name, bufp, buf, len, res) +@@ -69,11 +72,8 @@ + # ifndef GLOB_LSTAT + # define GLOB_LSTAT gl_lstat + # endif +-# ifndef GLOB_STAT64 +-# define GLOB_STAT64 __stat64 +-# endif +-# ifndef GLOB_LSTAT64 +-# define GLOB_LSTAT64 __lstat64 ++# ifndef GLOB_FSTATAT64 ++# define GLOB_FSTATAT64 __fstatat64 + # endif + # include + #else /* !_LIBC */ +@@ -88,8 +88,7 @@ + # define struct_stat struct stat + # define struct_stat64 struct stat + # define GLOB_LSTAT gl_lstat +-# define GLOB_STAT64 stat +-# define GLOB_LSTAT64 lstat ++# define GLOB_FSTATAT64 fstatat + #endif /* _LIBC */ + + #include +@@ -215,7 +214,8 @@ glob_lstat (glob_t *pglob, int flags, const char *fullname) + } ust; + return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC) + ? pglob->GLOB_LSTAT (fullname, &ust.st) +- : GLOB_LSTAT64 (fullname, &ust.st64)); ++ : GLOB_FSTATAT64 (AT_FDCWD, fullname, &ust.st64, ++ AT_SYMLINK_NOFOLLOW)); + } + + /* Set *R = A + B. Return true if the answer is mathematically +@@ -257,7 +257,8 @@ is_dir (char const *filename, int flags, glob_t const *pglob) + struct_stat64 st64; + return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC) + ? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode) +- : GLOB_STAT64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode)); ++ : (GLOB_FSTATAT64 (AT_FDCWD, filename, &st64, 0) == 0 ++ && S_ISDIR (st64.st_mode))); + } + + /* Find the end of the sub-pattern in a brace expression. */ +@@ -747,6 +748,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + else + { + #ifndef WINDOWS32 ++ /* Recognize ~user as a shorthand for the specified user's home ++ directory. */ + char *end_name = strchr (dirname, '/'); + char *user_name; + int malloc_user_name = 0; +@@ -885,7 +888,22 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + } + scratch_buffer_free (&pwtmpbuf); + } +-#endif /* !WINDOWS32 */ ++#else /* WINDOWS32 */ ++ /* On native Windows, access to a user's home directory ++ (via GetUserProfileDirectory) or to a user's environment ++ variables (via ExpandEnvironmentStringsForUser) requires ++ the credentials of the user. Therefore we cannot support ++ the ~user syntax on this platform. ++ Handling ~user specially (and treat it like plain ~) if ++ user is getenv ("USERNAME") would not be a good idea, ++ since it would make people think that ~user is supported ++ in general. */ ++ if (flags & GLOB_TILDE_CHECK) ++ { ++ retval = GLOB_NOMATCH; ++ goto out; ++ } ++#endif /* WINDOWS32 */ + } + } + +@@ -1266,6 +1284,8 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + { + size_t dirlen = strlen (directory); + void *stream = NULL; ++ struct scratch_buffer s; ++ scratch_buffer_init (&s); + # define GLOBNAMES_MEMBERS(nnames) \ + struct globnames *next; size_t count; char *name[nnames]; + struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) }; +@@ -1337,6 +1357,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + } + else + { ++ int dfd = dirfd (stream); + int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) + | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)); + flags |= GLOB_MAGCHAR; +@@ -1364,8 +1385,32 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + if (flags & GLOB_ONLYDIR) + switch (readdir_result_type (d)) + { +- case DT_DIR: case DT_LNK: case DT_UNKNOWN: break; + default: continue; ++ case DT_DIR: break; ++ case DT_LNK: case DT_UNKNOWN: ++ /* The filesystem was too lazy to give us a hint, ++ so we have to do it the hard way. */ ++ if (__glibc_unlikely (dfd < 0 || flags & GLOB_ALTDIRFUNC)) ++ { ++ size_t namelen = strlen (d.name); ++ size_t need = dirlen + 1 + namelen + 1; ++ if (s.length < need ++ && !scratch_buffer_set_array_size (&s, need, 1)) ++ goto memory_error; ++ char *p = mempcpy (s.data, directory, dirlen); ++ *p = '/'; ++ p += p[-1] != '/'; ++ memcpy (p, d.name, namelen + 1); ++ if (! is_dir (s.data, flags, pglob)) ++ continue; ++ } ++ else ++ { ++ struct_stat64 st64; ++ if (! (GLOB_FSTATAT64 (dfd, d.name, &st64, 0) == 0 ++ && S_ISDIR (st64.st_mode))) ++ continue; ++ } + } + + if (fnmatch (pattern, d.name, fnm_flags) == 0) +@@ -1497,5 +1542,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + __set_errno (save); + } + ++ scratch_buffer_free (&s); + return result; + } +diff --git a/sysdeps/unix/sysv/linux/glob64-time64.c b/sysdeps/unix/sysv/linux/glob64-time64.c +index a465f70905e5a8a3..95efe4c4f4624967 100644 +--- a/sysdeps/unix/sysv/linux/glob64-time64.c ++++ b/sysdeps/unix/sysv/linux/glob64-time64.c +@@ -37,6 +37,7 @@ + # define GLOB_LSTAT gl_lstat + # define GLOB_STAT64 __stat64_time64 + # define GLOB_LSTAT64 __lstat64_time64 ++# define GLOB_FSTATAT64 __fstatat64_time64 + + # define COMPILE_GLOB64 1 + diff --git a/SOURCES/glibc-upstream-2.34-191.patch b/SOURCES/glibc-upstream-2.34-191.patch new file mode 100644 index 0000000..55b6a81 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-191.patch @@ -0,0 +1,35 @@ +commit bc6fba3c8048b11c9f73db03339c97a2fec3f0cf +Author: Joseph Myers +Date: Wed Nov 17 14:25:16 2021 +0000 + + Add PF_MCTP, AF_MCTP from Linux 5.15 to bits/socket.h + + Linux 5.15 adds a new address / protocol family PF_MCTP / AF_MCTP; add + these constants to bits/socket.h. + + Tested for x86_64. + + (cherry picked from commit bdeb7a8fa9989d18dab6310753d04d908125dc1d) + +diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h +index a011a8c0959b9970..7bb9e863d7329da9 100644 +--- a/sysdeps/unix/sysv/linux/bits/socket.h ++++ b/sysdeps/unix/sysv/linux/bits/socket.h +@@ -86,7 +86,8 @@ typedef __socklen_t socklen_t; + #define PF_QIPCRTR 42 /* Qualcomm IPC Router. */ + #define PF_SMC 43 /* SMC sockets. */ + #define PF_XDP 44 /* XDP sockets. */ +-#define PF_MAX 45 /* For now.. */ ++#define PF_MCTP 45 /* Management component transport protocol. */ ++#define PF_MAX 46 /* For now.. */ + + /* Address families. */ + #define AF_UNSPEC PF_UNSPEC +@@ -137,6 +138,7 @@ typedef __socklen_t socklen_t; + #define AF_QIPCRTR PF_QIPCRTR + #define AF_SMC PF_SMC + #define AF_XDP PF_XDP ++#define AF_MCTP PF_MCTP + #define AF_MAX PF_MAX + + /* Socket level values. Others are defined in the appropriate headers. diff --git a/SOURCES/glibc-upstream-2.34-192.patch b/SOURCES/glibc-upstream-2.34-192.patch new file mode 100644 index 0000000..5a89460 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-192.patch @@ -0,0 +1,27 @@ +commit fd5dbfd1cd98cb2f12f9e9f7004a4d25ab0c977f +Author: Joseph Myers +Date: Mon Nov 22 15:30:12 2021 +0000 + + Update kernel version to 5.15 in tst-mman-consts.py + + This patch updates the kernel version in the test tst-mman-consts.py + to 5.15. (There are no new MAP_* constants covered by this test in + 5.15 that need any other header changes.) + + Tested with build-many-glibcs.py. + + (cherry picked from commit 5c3ece451d46a7d8721311609bfcb6faafacb39e) + +diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py +index 810433c238f31c25..eeccdfd04dae57ab 100644 +--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py ++++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py +@@ -33,7 +33,7 @@ def main(): + help='C compiler (including options) to use') + args = parser.parse_args() + linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) +- linux_version_glibc = (5, 14) ++ linux_version_glibc = (5, 15) + sys.exit(glibcextract.compare_macro_consts( + '#define _GNU_SOURCE 1\n' + '#include \n', diff --git a/SOURCES/glibc-upstream-2.34-193.patch b/SOURCES/glibc-upstream-2.34-193.patch new file mode 100644 index 0000000..d056d36 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-193.patch @@ -0,0 +1,28 @@ +commit 5146b73d72ced9bab125e986aa99ef5fe2f88475 +Author: Joseph Myers +Date: Mon Dec 20 15:38:32 2021 +0000 + + Add ARPHRD_CAN, ARPHRD_MCTP to net/if_arp.h + + Add the constant ARPHRD_MCTP, from Linux 5.15, to net/if_arp.h, along + with ARPHRD_CAN which was added to Linux in version 2.6.25 (commit + cd05acfe65ed2cf2db683fa9a6adb8d35635263b, "[CAN]: Allocate protocol + numbers for PF_CAN") but apparently missed for glibc at the time. + + Tested for x86_64. + + (cherry picked from commit a94d9659cd69dbc70d3494b1cbbbb5a1551675c5) + +diff --git a/sysdeps/unix/sysv/linux/net/if_arp.h b/sysdeps/unix/sysv/linux/net/if_arp.h +index 2a8933cde7cf236d..42910b776660def1 100644 +--- a/sysdeps/unix/sysv/linux/net/if_arp.h ++++ b/sysdeps/unix/sysv/linux/net/if_arp.h +@@ -95,6 +95,8 @@ struct arphdr + #define ARPHRD_ROSE 270 + #define ARPHRD_X25 271 /* CCITT X.25. */ + #define ARPHRD_HWX25 272 /* Boards with X.25 in firmware. */ ++#define ARPHRD_CAN 280 /* Controller Area Network. */ ++#define ARPHRD_MCTP 290 + #define ARPHRD_PPP 512 + #define ARPHRD_CISCO 513 /* Cisco HDLC. */ + #define ARPHRD_HDLC ARPHRD_CISCO diff --git a/SOURCES/glibc-upstream-2.34-194.patch b/SOURCES/glibc-upstream-2.34-194.patch new file mode 100644 index 0000000..0437f53 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-194.patch @@ -0,0 +1,337 @@ +commit 6af165658d0999ac2c4e9ce88bee020fbc2ee49f +Author: Joseph Myers +Date: Wed Mar 23 17:11:56 2022 +0000 + + Update syscall lists for Linux 5.17 + + Linux 5.17 has one new syscall, set_mempolicy_home_node. Update + syscall-names.list and regenerate the arch-syscall.h headers with + build-many-glibcs.py update-syscalls. + + Tested with build-many-glibcs.py. + + (cherry picked from commit 8ef9196b26793830515402ea95aca2629f7721ec) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +index 9905ebedf298954c..4fcb6da80af37e9e 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +@@ -236,6 +236,7 @@ + #define __NR_sendmsg 211 + #define __NR_sendto 206 + #define __NR_set_mempolicy 237 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 99 + #define __NR_set_tid_address 96 + #define __NR_setdomainname 162 +diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +index ee8085be69958b25..0cf74c1a96bb1235 100644 +--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +@@ -391,6 +391,7 @@ + #define __NR_sendmsg 114 + #define __NR_sendto 133 + #define __NR_set_mempolicy 431 ++#define __NR_set_mempolicy_home_node 560 + #define __NR_set_robust_list 466 + #define __NR_set_tid_address 411 + #define __NR_setdomainname 166 +diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +index 1b626d97705d545a..c1207aaa12be6a51 100644 +--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +@@ -238,6 +238,7 @@ + #define __NR_sendmsg 211 + #define __NR_sendto 206 + #define __NR_set_mempolicy 237 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 99 + #define __NR_set_tid_address 96 + #define __NR_setdomainname 162 +diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +index 96ef8db9368e7de4..e7ba04c106d8af7d 100644 +--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +@@ -302,6 +302,7 @@ + #define __NR_sendmsg 296 + #define __NR_sendto 290 + #define __NR_set_mempolicy 321 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 338 + #define __NR_set_tid_address 256 + #define __NR_set_tls 983045 +diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +index 96910154ed6a5c1b..dc9383758ebc641b 100644 +--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +@@ -250,6 +250,7 @@ + #define __NR_sendmsg 211 + #define __NR_sendto 206 + #define __NR_set_mempolicy 237 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 99 + #define __NR_set_thread_area 244 + #define __NR_set_tid_address 96 +diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +index 36675fd48e6f50c5..767f1287a30b473e 100644 +--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +@@ -289,6 +289,7 @@ + #define __NR_sendmsg 183 + #define __NR_sendto 82 + #define __NR_set_mempolicy 262 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 289 + #define __NR_set_tid_address 237 + #define __NR_setdomainname 121 +diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +index c86ccbda4681066c..1998f0d76a444cac 100644 +--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +@@ -323,6 +323,7 @@ + #define __NR_sendmsg 370 + #define __NR_sendto 369 + #define __NR_set_mempolicy 276 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 311 + #define __NR_set_thread_area 243 + #define __NR_set_tid_address 258 +diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +index d898bce404955ef0..b2eab1b93d70b9de 100644 +--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +@@ -272,6 +272,7 @@ + #define __NR_sendmsg 1205 + #define __NR_sendto 1199 + #define __NR_set_mempolicy 1261 ++#define __NR_set_mempolicy_home_node 1474 + #define __NR_set_robust_list 1298 + #define __NR_set_tid_address 1233 + #define __NR_setdomainname 1129 +diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +index fe721b809076abeb..5fc3723772f92516 100644 +--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +@@ -310,6 +310,7 @@ + #define __NR_sendmsg 367 + #define __NR_sendto 366 + #define __NR_set_mempolicy 270 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 304 + #define __NR_set_thread_area 334 + #define __NR_set_tid_address 253 +diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +index 6e10c3661db96a1e..b6e9b007e496cd80 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +@@ -326,6 +326,7 @@ + #define __NR_sendmsg 360 + #define __NR_sendto 353 + #define __NR_set_mempolicy 276 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 311 + #define __NR_set_thread_area 243 + #define __NR_set_tid_address 258 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +index 26a6d594a2222f15..b3a3871f8ab8a23e 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +@@ -308,6 +308,7 @@ + #define __NR_sendmsg 4179 + #define __NR_sendto 4180 + #define __NR_set_mempolicy 4270 ++#define __NR_set_mempolicy_home_node 4450 + #define __NR_set_robust_list 4309 + #define __NR_set_thread_area 4283 + #define __NR_set_tid_address 4252 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +index 83e0d49c5e3ca1bc..b462182723aff286 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +@@ -288,6 +288,7 @@ + #define __NR_sendmsg 6045 + #define __NR_sendto 6043 + #define __NR_set_mempolicy 6233 ++#define __NR_set_mempolicy_home_node 6450 + #define __NR_set_robust_list 6272 + #define __NR_set_thread_area 6246 + #define __NR_set_tid_address 6213 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +index d6747c542f63202b..a9d6b94572e93001 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +@@ -270,6 +270,7 @@ + #define __NR_sendmsg 5045 + #define __NR_sendto 5043 + #define __NR_set_mempolicy 5229 ++#define __NR_set_mempolicy_home_node 5450 + #define __NR_set_robust_list 5268 + #define __NR_set_thread_area 5242 + #define __NR_set_tid_address 5212 +diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +index 4ee209bc4475ea7d..809a219ef32a45ef 100644 +--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +@@ -250,6 +250,7 @@ + #define __NR_sendmsg 211 + #define __NR_sendto 206 + #define __NR_set_mempolicy 237 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 99 + #define __NR_set_tid_address 96 + #define __NR_setdomainname 162 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +index 497299fbc47a708c..627831ebae1b9e90 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +@@ -319,6 +319,7 @@ + #define __NR_sendmsg 341 + #define __NR_sendto 335 + #define __NR_set_mempolicy 261 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 300 + #define __NR_set_tid_address 232 + #define __NR_setdomainname 121 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +index e840279f171b10b9..bae597199d79eaad 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +@@ -298,6 +298,7 @@ + #define __NR_sendmsg 341 + #define __NR_sendto 335 + #define __NR_set_mempolicy 261 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 300 + #define __NR_set_tid_address 232 + #define __NR_setdomainname 121 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index 73ef74c005e5a2bb..bf4be80f8d380963 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -228,6 +228,7 @@ + #define __NR_sendmsg 211 + #define __NR_sendto 206 + #define __NR_set_mempolicy 237 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 99 + #define __NR_set_tid_address 96 + #define __NR_setdomainname 162 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index 919a79ee91177459..d656aedcc2be6009 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -235,6 +235,7 @@ + #define __NR_sendmsg 211 + #define __NR_sendto 206 + #define __NR_set_mempolicy 237 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 99 + #define __NR_set_tid_address 96 + #define __NR_setdomainname 162 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +index 005c0ada7aab85a1..57025107e82c9439 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +@@ -311,6 +311,7 @@ + #define __NR_sendmsg 370 + #define __NR_sendto 369 + #define __NR_set_mempolicy 270 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 304 + #define __NR_set_tid_address 252 + #define __NR_setdomainname 121 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +index 9131fddcc16116e4..72e19c6d569fbf9b 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +@@ -278,6 +278,7 @@ + #define __NR_sendmsg 370 + #define __NR_sendto 369 + #define __NR_set_mempolicy 270 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 304 + #define __NR_set_tid_address 252 + #define __NR_setdomainname 121 +diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +index d8fb041568ecb4da..d52b522d9cac87ef 100644 +--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +@@ -303,6 +303,7 @@ + #define __NR_sendmsg 355 + #define __NR_sendto 349 + #define __NR_set_mempolicy 276 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 311 + #define __NR_set_tid_address 258 + #define __NR_setdomainname 121 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +index 2bc014fe6a1a1f4a..d3f4d8aa3edb4795 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +@@ -310,6 +310,7 @@ + #define __NR_sendmsg 114 + #define __NR_sendto 133 + #define __NR_set_mempolicy 305 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 300 + #define __NR_set_tid_address 166 + #define __NR_setdomainname 163 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +index 76dbbe595ffe868f..2cc03d7a24453335 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +@@ -286,6 +286,7 @@ + #define __NR_sendmsg 114 + #define __NR_sendto 133 + #define __NR_set_mempolicy 305 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 300 + #define __NR_set_tid_address 166 + #define __NR_setdomainname 163 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 0bc2af37dfa1eeb5..e2743c649586d97a 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.16. +-kernel 5.16 ++# The list of system calls is current as of Linux 5.17. ++kernel 5.17 + + FAST_atomic_update + FAST_cmpxchg +@@ -523,6 +523,7 @@ sendmmsg + sendmsg + sendto + set_mempolicy ++set_mempolicy_home_node + set_robust_list + set_thread_area + set_tid_address +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +index 28558279b48a1ef4..b4ab892ec183e32d 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +@@ -278,6 +278,7 @@ + #define __NR_sendmsg 46 + #define __NR_sendto 44 + #define __NR_set_mempolicy 238 ++#define __NR_set_mempolicy_home_node 450 + #define __NR_set_robust_list 273 + #define __NR_set_thread_area 205 + #define __NR_set_tid_address 218 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index c1ab8ec45e8b8fd3..772559c87b3625b8 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -270,6 +270,7 @@ + #define __NR_sendmsg 1073742342 + #define __NR_sendto 1073741868 + #define __NR_set_mempolicy 1073742062 ++#define __NR_set_mempolicy_home_node 1073742274 + #define __NR_set_robust_list 1073742354 + #define __NR_set_thread_area 1073742029 + #define __NR_set_tid_address 1073742042 diff --git a/SOURCES/glibc-upstream-2.34-195.patch b/SOURCES/glibc-upstream-2.34-195.patch new file mode 100644 index 0000000..d2b7afb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-195.patch @@ -0,0 +1,27 @@ +commit 81181ba5d916fc49bd737f603e28a3c2dc8430b4 +Author: Joseph Myers +Date: Wed Feb 16 14:19:24 2022 +0000 + + Update kernel version to 5.16 in tst-mman-consts.py + + This patch updates the kernel version in the test tst-mman-consts.py + to 5.16. (There are no new MAP_* constants covered by this test in + 5.16 that need any other header changes.) + + Tested with build-many-glibcs.py. + + (cherry picked from commit 790a607e234aa10d4b977a1b80aebe8a2acac970) + +diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py +index eeccdfd04dae57ab..8102d80b6660e523 100644 +--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py ++++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py +@@ -33,7 +33,7 @@ def main(): + help='C compiler (including options) to use') + args = parser.parse_args() + linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) +- linux_version_glibc = (5, 15) ++ linux_version_glibc = (5, 16) + sys.exit(glibcextract.compare_macro_consts( + '#define _GNU_SOURCE 1\n' + '#include \n', diff --git a/SOURCES/glibc-upstream-2.34-196.patch b/SOURCES/glibc-upstream-2.34-196.patch new file mode 100644 index 0000000..5294eea --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-196.patch @@ -0,0 +1,27 @@ +commit 0499c3a95fb864284fef36d3e9c5a54f6646b2db +Author: Joseph Myers +Date: Thu Mar 24 15:35:27 2022 +0000 + + Update kernel version to 5.17 in tst-mman-consts.py + + This patch updates the kernel version in the test tst-mman-consts.py + to 5.17. (There are no new MAP_* constants covered by this test in + 5.17 that need any other header changes.) + + Tested with build-many-glibcs.py. + + (cherry picked from commit 23808a422e6036accaba7236fd3b9a0d7ab7e8ee) + +diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py +index 8102d80b6660e523..724c7375c3a1623b 100644 +--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py ++++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py +@@ -33,7 +33,7 @@ def main(): + help='C compiler (including options) to use') + args = parser.parse_args() + linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) +- linux_version_glibc = (5, 16) ++ linux_version_glibc = (5, 17) + sys.exit(glibcextract.compare_macro_consts( + '#define _GNU_SOURCE 1\n' + '#include \n', diff --git a/SOURCES/glibc-upstream-2.34-197.patch b/SOURCES/glibc-upstream-2.34-197.patch new file mode 100644 index 0000000..afe47ec --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-197.patch @@ -0,0 +1,26 @@ +commit f858bc309315a03ff6b1a048f59405c159d23430 +Author: Joseph Myers +Date: Mon Feb 21 22:49:36 2022 +0000 + + Add SOL_MPTCP, SOL_MCTP from Linux 5.16 to bits/socket.h + + Linux 5.16 adds constants SOL_MPTCP and SOL_MCTP to the getsockopt / + setsockopt levels; add these constants to bits/socket.h. + + Tested for x86_64. + + (cherry picked from commit fdc1ae67fef27eea1445bab4bdfe2f0fb3bc7aa1) + +diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h +index 7bb9e863d7329da9..c81fab840918924e 100644 +--- a/sysdeps/unix/sysv/linux/bits/socket.h ++++ b/sysdeps/unix/sysv/linux/bits/socket.h +@@ -169,6 +169,8 @@ typedef __socklen_t socklen_t; + #define SOL_KCM 281 + #define SOL_TLS 282 + #define SOL_XDP 283 ++#define SOL_MPTCP 284 ++#define SOL_MCTP 285 + + /* Maximum queue length specifiable by listen. */ + #define SOMAXCONN 4096 diff --git a/SOURCES/glibc-upstream-2.34-198.patch b/SOURCES/glibc-upstream-2.34-198.patch new file mode 100644 index 0000000..67ab10c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-198.patch @@ -0,0 +1,21 @@ +commit c108e87026d61d6744e3e55704e0bea937243f5a +Author: Szabolcs Nagy +Date: Tue Dec 14 11:15:07 2021 +0000 + + aarch64: Add HWCAP2_ECV from Linux 5.16 + + Indicates the availability of enhanced counter virtualization extension + of armv8.6-a with self-synchronized virtual counter CNTVCTSS_EL0 usable + in userspace. + + (cherry picked from commit 5a1be8ebdf6f02d4efec6e5f12ad06db17511f90) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h +index 30fda0a4a347695e..04cc762015a7230a 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h ++++ b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h +@@ -74,3 +74,4 @@ + #define HWCAP2_RNG (1 << 16) + #define HWCAP2_BTI (1 << 17) + #define HWCAP2_MTE (1 << 18) ++#define HWCAP2_ECV (1 << 19) diff --git a/SOURCES/glibc-upstream-2.34-199.patch b/SOURCES/glibc-upstream-2.34-199.patch new file mode 100644 index 0000000..02675fc --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-199.patch @@ -0,0 +1,21 @@ +commit 97cb8227b864b8ea0d99a4a50e4163baad3e1c72 +Author: Joseph Myers +Date: Mon Mar 28 13:16:48 2022 +0000 + + Add HWCAP2_AFP, HWCAP2_RPRES from Linux 5.17 to AArch64 bits/hwcap.h + + Add the new HWCAP2_AFP and HWCAP2_RPRES constants from Linux 5.17. + Tested with build-many-glibcs.py for aarch64-linux-gnu. + + (cherry picked from commit 866c599182e87f116440b5d854f9e99533c48eb3) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h +index 04cc762015a7230a..9a5c4116b3fe9903 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h ++++ b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h +@@ -75,3 +75,5 @@ + #define HWCAP2_BTI (1 << 17) + #define HWCAP2_MTE (1 << 18) + #define HWCAP2_ECV (1 << 19) ++#define HWCAP2_AFP (1 << 20) ++#define HWCAP2_RPRES (1 << 21) diff --git a/SOURCES/glibc-upstream-2.34-2.patch b/SOURCES/glibc-upstream-2.34-2.patch new file mode 100644 index 0000000..fbddab3 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-2.patch @@ -0,0 +1,33 @@ +commit 3a48da47a91ccc6f5de260574809e7a44551b876 +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:10:20 2021 +0530 + + gconv_parseconfdir: Fix memory leak + + The allocated `conf` would leak if we have to skip over the file due + to the underlying filesystem not supporting dt_type. + + Reviewed-by: Arjun Shankar + (cherry picked from commit 5f9b78fe35d08739b6da1e5b356786d41116c108) + +diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h +index a4153e54c6d43797..2f062689ecc72749 100644 +--- a/iconv/gconv_parseconfdir.h ++++ b/iconv/gconv_parseconfdir.h +@@ -153,12 +153,11 @@ gconv_parseconfdir (const char *dir, size_t dir_len) + struct stat64 st; + if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0) + continue; +- if (ent->d_type == DT_UNKNOWN +- && (lstat64 (conf, &st) == -1 +- || !S_ISREG (st.st_mode))) +- continue; + +- found |= read_conf_file (conf, dir, dir_len); ++ if (ent->d_type != DT_UNKNOWN ++ || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode))) ++ found |= read_conf_file (conf, dir, dir_len); ++ + free (conf); + } + } diff --git a/SOURCES/glibc-upstream-2.34-20.patch b/SOURCES/glibc-upstream-2.34-20.patch new file mode 100644 index 0000000..f4b1aed --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-20.patch @@ -0,0 +1,29 @@ +commit 4ed990e5b97a61f29f929bdeb36c5b2abb547a64 +Author: Joseph Myers +Date: Tue Sep 14 14:19:24 2021 +0000 + + Add MADV_POPULATE_READ and MADV_POPULATE_WRITE from Linux 5.14 to bits/mman-linux.h + + Linux 5.14 adds constants MADV_POPULATE_READ and MADV_POPULATE_WRITE + (with the same values on all architectures). Add these to glibc's + bits/mman-linux.h. + + Tested for x86_64. + + (cherry picked from commit 3561106278cddd2f007bd27fd4c3e90caaf14b43) + +diff --git a/sysdeps/unix/sysv/linux/bits/mman-linux.h b/sysdeps/unix/sysv/linux/bits/mman-linux.h +index 3b1ae418e073c122..31451c28d93f9f72 100644 +--- a/sysdeps/unix/sysv/linux/bits/mman-linux.h ++++ b/sysdeps/unix/sysv/linux/bits/mman-linux.h +@@ -89,6 +89,10 @@ + # define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK. */ + # define MADV_COLD 20 /* Deactivate these pages. */ + # define MADV_PAGEOUT 21 /* Reclaim these pages. */ ++# define MADV_POPULATE_READ 22 /* Populate (prefault) page tables ++ readable. */ ++# define MADV_POPULATE_WRITE 23 /* Populate (prefault) page tables ++ writable. */ + # define MADV_HWPOISON 100 /* Poison a page for testing. */ + #endif + diff --git a/SOURCES/glibc-upstream-2.34-200.patch b/SOURCES/glibc-upstream-2.34-200.patch new file mode 100644 index 0000000..7ad14c9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-200.patch @@ -0,0 +1,29 @@ +commit 31af92b9c8cf753992d45c801a855a02060afc08 +Author: Siddhesh Poyarekar +Date: Wed May 4 15:56:47 2022 +0530 + + manual: Clarify that abbreviations of long options are allowed + + The man page and code comments clearly state that abbreviations of long + option names are recognized correctly as long as they are unique. + Document this fact in the glibc manual as well. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Florian Weimer + Reviewed-by: Andreas Schwab + (cherry picked from commit db1efe02c9f15affc3908d6ae73875b82898a489) + +diff --git a/manual/getopt.texi b/manual/getopt.texi +index 5485fc46946631f7..b4c0b15ac2060560 100644 +--- a/manual/getopt.texi ++++ b/manual/getopt.texi +@@ -250,7 +250,8 @@ option, and stores the option's argument (if it has one) in @code{optarg}. + + When @code{getopt_long} encounters a long option, it takes actions based + on the @code{flag} and @code{val} fields of the definition of that +-option. ++option. The option name may be abbreviated as long as the abbreviation is ++unique. + + If @code{flag} is a null pointer, then @code{getopt_long} returns the + contents of @code{val} to indicate which option it found. You should diff --git a/SOURCES/glibc-upstream-2.34-201.patch b/SOURCES/glibc-upstream-2.34-201.patch new file mode 100644 index 0000000..68ca969 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-201.patch @@ -0,0 +1,1789 @@ +commit 0d5b36c8cc15f064e302d29692853f8a760e1547 +Author: Noah Goldstein +Date: Mon Jan 10 15:35:38 2022 -0600 + + x86: Optimize strcmp-avx2.S + + Optimization are primarily to the loop logic and how the page cross + logic interacts with the loop. + + The page cross logic is at times more expensive for short strings near + the end of a page but not crossing the page. This is done to retest + the page cross conditions with a non-faulty check and to improve the + logic for entering the loop afterwards. This is only particular cases, + however, and is general made up for by more than 10x improvements on + the transition from the page cross -> loop case. + + The non-page cross cases are improved most for smaller sizes [0, 128] + and go about even for (128, 4096]. The loop page cross logic is + improved so some more significant speedup is seen there as well. + + test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass. + + Signed-off-by: Noah Goldstein + (cherry picked from commit b77b06e0e296f1a2276c27a67e1d44f2cfa38d45) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S +index fa70c994fc25dfd8..a0d1c65db11028bc 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S +@@ -26,35 +26,57 @@ + + # define PAGE_SIZE 4096 + +-/* VEC_SIZE = Number of bytes in a ymm register */ ++ /* VEC_SIZE = Number of bytes in a ymm register. */ + # define VEC_SIZE 32 + +-/* Shift for dividing by (VEC_SIZE * 4). */ +-# define DIVIDE_BY_VEC_4_SHIFT 7 +-# if (VEC_SIZE * 4) != (1 << DIVIDE_BY_VEC_4_SHIFT) +-# error (VEC_SIZE * 4) != (1 << DIVIDE_BY_VEC_4_SHIFT) +-# endif ++# define VMOVU vmovdqu ++# define VMOVA vmovdqa + + # ifdef USE_AS_WCSCMP +-/* Compare packed dwords. */ ++ /* Compare packed dwords. */ + # define VPCMPEQ vpcmpeqd +-/* Compare packed dwords and store minimum. */ ++ /* Compare packed dwords and store minimum. */ + # define VPMINU vpminud +-/* 1 dword char == 4 bytes. */ ++ /* 1 dword char == 4 bytes. */ + # define SIZE_OF_CHAR 4 + # else +-/* Compare packed bytes. */ ++ /* Compare packed bytes. */ + # define VPCMPEQ vpcmpeqb +-/* Compare packed bytes and store minimum. */ ++ /* Compare packed bytes and store minimum. */ + # define VPMINU vpminub +-/* 1 byte char == 1 byte. */ ++ /* 1 byte char == 1 byte. */ + # define SIZE_OF_CHAR 1 + # endif + ++# ifdef USE_AS_STRNCMP ++# define LOOP_REG r9d ++# define LOOP_REG64 r9 ++ ++# define OFFSET_REG8 r9b ++# define OFFSET_REG r9d ++# define OFFSET_REG64 r9 ++# else ++# define LOOP_REG edx ++# define LOOP_REG64 rdx ++ ++# define OFFSET_REG8 dl ++# define OFFSET_REG edx ++# define OFFSET_REG64 rdx ++# endif ++ + # ifndef VZEROUPPER + # define VZEROUPPER vzeroupper + # endif + ++# if defined USE_AS_STRNCMP ++# define VEC_OFFSET 0 ++# else ++# define VEC_OFFSET (-VEC_SIZE) ++# endif ++ ++# define xmmZERO xmm15 ++# define ymmZERO ymm15 ++ + # ifndef SECTION + # define SECTION(p) p##.avx + # endif +@@ -79,783 +101,1049 @@ + the maximum offset is reached before a difference is found, zero is + returned. */ + +- .section SECTION(.text),"ax",@progbits +-ENTRY (STRCMP) ++ .section SECTION(.text), "ax", @progbits ++ENTRY(STRCMP) + # ifdef USE_AS_STRNCMP +- /* Check for simple cases (0 or 1) in offset. */ ++# ifdef __ILP32__ ++ /* Clear the upper 32 bits. */ ++ movl %edx, %rdx ++# endif + cmp $1, %RDX_LP +- je L(char0) +- jb L(zero) ++ /* Signed comparison intentional. We use this branch to also ++ test cases where length >= 2^63. These very large sizes can be ++ handled with strcmp as there is no way for that length to ++ actually bound the buffer. */ ++ jle L(one_or_less) + # ifdef USE_AS_WCSCMP +-# ifndef __ILP32__ + movq %rdx, %rcx +- /* Check if length could overflow when multiplied by +- sizeof(wchar_t). Checking top 8 bits will cover all potential +- overflow cases as well as redirect cases where its impossible to +- length to bound a valid memory region. In these cases just use +- 'wcscmp'. */ ++ ++ /* Multiplying length by sizeof(wchar_t) can result in overflow. ++ Check if that is possible. All cases where overflow are possible ++ are cases where length is large enough that it can never be a ++ bound on valid memory so just use wcscmp. */ + shrq $56, %rcx +- jnz OVERFLOW_STRCMP +-# endif +- /* Convert units: from wide to byte char. */ +- shl $2, %RDX_LP ++ jnz __wcscmp_avx2 ++ ++ leaq (, %rdx, 4), %rdx + # endif +- /* Register %r11 tracks the maximum offset. */ +- mov %RDX_LP, %R11_LP + # endif ++ vpxor %xmmZERO, %xmmZERO, %xmmZERO + movl %edi, %eax +- xorl %edx, %edx +- /* Make %xmm7 (%ymm7) all zeros in this function. */ +- vpxor %xmm7, %xmm7, %xmm7 + orl %esi, %eax +- andl $(PAGE_SIZE - 1), %eax +- cmpl $(PAGE_SIZE - (VEC_SIZE * 4)), %eax +- jg L(cross_page) +- /* Start comparing 4 vectors. */ +- vmovdqu (%rdi), %ymm1 +- VPCMPEQ (%rsi), %ymm1, %ymm0 +- VPMINU %ymm1, %ymm0, %ymm0 +- VPCMPEQ %ymm7, %ymm0, %ymm0 +- vpmovmskb %ymm0, %ecx +- testl %ecx, %ecx +- je L(next_3_vectors) +- tzcntl %ecx, %edx ++ sall $20, %eax ++ /* Check if s1 or s2 may cross a page in next 4x VEC loads. */ ++ cmpl $((PAGE_SIZE -(VEC_SIZE * 4)) << 20), %eax ++ ja L(page_cross) ++ ++L(no_page_cross): ++ /* Safe to compare 4x vectors. */ ++ VMOVU (%rdi), %ymm0 ++ /* 1s where s1 and s2 equal. */ ++ VPCMPEQ (%rsi), %ymm0, %ymm1 ++ /* 1s at null CHAR. */ ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ /* 1s where s1 and s2 equal AND not null CHAR. */ ++ vpandn %ymm1, %ymm2, %ymm1 ++ ++ /* All 1s -> keep going, any 0s -> return. */ ++ vpmovmskb %ymm1, %ecx + # ifdef USE_AS_STRNCMP +- /* Return 0 if the mismatched index (%rdx) is after the maximum +- offset (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) ++ cmpq $VEC_SIZE, %rdx ++ jbe L(vec_0_test_len) + # endif ++ ++ /* All 1s represents all equals. incl will overflow to zero in ++ all equals case. Otherwise 1s will carry until position of first ++ mismatch. */ ++ incl %ecx ++ jz L(more_3x_vec) ++ ++ .p2align 4,, 4 ++L(return_vec_0): ++ tzcntl %ecx, %ecx + # ifdef USE_AS_WCSCMP ++ movl (%rdi, %rcx), %edx + xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- je L(return) +-L(wcscmp_return): ++ cmpl (%rsi, %rcx), %edx ++ je L(ret0) + setl %al + negl %eax + orl $1, %eax +-L(return): + # else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax ++ movzbl (%rdi, %rcx), %eax ++ movzbl (%rsi, %rcx), %ecx ++ subl %ecx, %eax + # endif ++L(ret0): + L(return_vzeroupper): + ZERO_UPPER_VEC_REGISTERS_RETURN + +- .p2align 4 +-L(return_vec_size): +- tzcntl %ecx, %edx + # ifdef USE_AS_STRNCMP +- /* Return 0 if the mismatched index (%rdx + VEC_SIZE) is after +- the maximum offset (%r11). */ +- addq $VEC_SIZE, %rdx +- cmpq %r11, %rdx +- jae L(zero) +-# ifdef USE_AS_WCSCMP ++ .p2align 4,, 8 ++L(vec_0_test_len): ++ notl %ecx ++ bzhil %edx, %ecx, %eax ++ jnz L(return_vec_0) ++ /* Align if will cross fetch block. */ ++ .p2align 4,, 2 ++L(ret_zero): + xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax +-# endif +-# else ++ VZEROUPPER_RETURN ++ ++ .p2align 4,, 5 ++L(one_or_less): ++ jb L(ret_zero) + # ifdef USE_AS_WCSCMP ++ /* 'nbe' covers the case where length is negative (large ++ unsigned). */ ++ jnbe __wcscmp_avx2 ++ movl (%rdi), %edx + xorl %eax, %eax +- movl VEC_SIZE(%rdi, %rdx), %ecx +- cmpl VEC_SIZE(%rsi, %rdx), %ecx +- jne L(wcscmp_return) ++ cmpl (%rsi), %edx ++ je L(ret1) ++ setl %al ++ negl %eax ++ orl $1, %eax + # else +- movzbl VEC_SIZE(%rdi, %rdx), %eax +- movzbl VEC_SIZE(%rsi, %rdx), %edx +- subl %edx, %eax ++ /* 'nbe' covers the case where length is negative (large ++ unsigned). */ ++ ++ jnbe __strcmp_avx2 ++ movzbl (%rdi), %eax ++ movzbl (%rsi), %ecx ++ subl %ecx, %eax + # endif ++L(ret1): ++ ret + # endif +- VZEROUPPER_RETURN + +- .p2align 4 +-L(return_2_vec_size): +- tzcntl %ecx, %edx ++ .p2align 4,, 10 ++L(return_vec_1): ++ tzcntl %ecx, %ecx + # ifdef USE_AS_STRNCMP +- /* Return 0 if the mismatched index (%rdx + 2 * VEC_SIZE) is +- after the maximum offset (%r11). */ +- addq $(VEC_SIZE * 2), %rdx +- cmpq %r11, %rdx +- jae L(zero) +-# ifdef USE_AS_WCSCMP ++ /* rdx must be > CHAR_PER_VEC so save to subtract w.o fear of ++ overflow. */ ++ addq $-VEC_SIZE, %rdx ++ cmpq %rcx, %rdx ++ jbe L(ret_zero) ++# endif ++# ifdef USE_AS_WCSCMP ++ movl VEC_SIZE(%rdi, %rcx), %edx + xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax +-# endif ++ cmpl VEC_SIZE(%rsi, %rcx), %edx ++ je L(ret2) ++ setl %al ++ negl %eax ++ orl $1, %eax + # else +-# ifdef USE_AS_WCSCMP +- xorl %eax, %eax +- movl (VEC_SIZE * 2)(%rdi, %rdx), %ecx +- cmpl (VEC_SIZE * 2)(%rsi, %rdx), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (VEC_SIZE * 2)(%rdi, %rdx), %eax +- movzbl (VEC_SIZE * 2)(%rsi, %rdx), %edx +- subl %edx, %eax +-# endif ++ movzbl VEC_SIZE(%rdi, %rcx), %eax ++ movzbl VEC_SIZE(%rsi, %rcx), %ecx ++ subl %ecx, %eax + # endif ++L(ret2): + VZEROUPPER_RETURN + +- .p2align 4 +-L(return_3_vec_size): +- tzcntl %ecx, %edx ++ .p2align 4,, 10 + # ifdef USE_AS_STRNCMP +- /* Return 0 if the mismatched index (%rdx + 3 * VEC_SIZE) is +- after the maximum offset (%r11). */ +- addq $(VEC_SIZE * 3), %rdx +- cmpq %r11, %rdx +- jae L(zero) +-# ifdef USE_AS_WCSCMP ++L(return_vec_3): ++ salq $32, %rcx ++# endif ++ ++L(return_vec_2): ++# ifndef USE_AS_STRNCMP ++ tzcntl %ecx, %ecx ++# else ++ tzcntq %rcx, %rcx ++ cmpq %rcx, %rdx ++ jbe L(ret_zero) ++# endif ++ ++# ifdef USE_AS_WCSCMP ++ movl (VEC_SIZE * 2)(%rdi, %rcx), %edx + xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax +-# endif ++ cmpl (VEC_SIZE * 2)(%rsi, %rcx), %edx ++ je L(ret3) ++ setl %al ++ negl %eax ++ orl $1, %eax + # else ++ movzbl (VEC_SIZE * 2)(%rdi, %rcx), %eax ++ movzbl (VEC_SIZE * 2)(%rsi, %rcx), %ecx ++ subl %ecx, %eax ++# endif ++L(ret3): ++ VZEROUPPER_RETURN ++ ++# ifndef USE_AS_STRNCMP ++ .p2align 4,, 10 ++L(return_vec_3): ++ tzcntl %ecx, %ecx + # ifdef USE_AS_WCSCMP ++ movl (VEC_SIZE * 3)(%rdi, %rcx), %edx + xorl %eax, %eax +- movl (VEC_SIZE * 3)(%rdi, %rdx), %ecx +- cmpl (VEC_SIZE * 3)(%rsi, %rdx), %ecx +- jne L(wcscmp_return) ++ cmpl (VEC_SIZE * 3)(%rsi, %rcx), %edx ++ je L(ret4) ++ setl %al ++ negl %eax ++ orl $1, %eax + # else +- movzbl (VEC_SIZE * 3)(%rdi, %rdx), %eax +- movzbl (VEC_SIZE * 3)(%rsi, %rdx), %edx +- subl %edx, %eax ++ movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax ++ movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx ++ subl %ecx, %eax + # endif +-# endif ++L(ret4): + VZEROUPPER_RETURN ++# endif ++ ++ .p2align 4,, 10 ++L(more_3x_vec): ++ /* Safe to compare 4x vectors. */ ++ VMOVU VEC_SIZE(%rdi), %ymm0 ++ VPCMPEQ VEC_SIZE(%rsi), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ incl %ecx ++ jnz L(return_vec_1) ++ ++# ifdef USE_AS_STRNCMP ++ subq $(VEC_SIZE * 2), %rdx ++ jbe L(ret_zero) ++# endif ++ ++ VMOVU (VEC_SIZE * 2)(%rdi), %ymm0 ++ VPCMPEQ (VEC_SIZE * 2)(%rsi), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ incl %ecx ++ jnz L(return_vec_2) ++ ++ VMOVU (VEC_SIZE * 3)(%rdi), %ymm0 ++ VPCMPEQ (VEC_SIZE * 3)(%rsi), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ incl %ecx ++ jnz L(return_vec_3) + +- .p2align 4 +-L(next_3_vectors): +- vmovdqu VEC_SIZE(%rdi), %ymm6 +- VPCMPEQ VEC_SIZE(%rsi), %ymm6, %ymm3 +- VPMINU %ymm6, %ymm3, %ymm3 +- VPCMPEQ %ymm7, %ymm3, %ymm3 +- vpmovmskb %ymm3, %ecx +- testl %ecx, %ecx +- jne L(return_vec_size) +- vmovdqu (VEC_SIZE * 2)(%rdi), %ymm5 +- vmovdqu (VEC_SIZE * 3)(%rdi), %ymm4 +- vmovdqu (VEC_SIZE * 3)(%rsi), %ymm0 +- VPCMPEQ (VEC_SIZE * 2)(%rsi), %ymm5, %ymm2 +- VPMINU %ymm5, %ymm2, %ymm2 +- VPCMPEQ %ymm4, %ymm0, %ymm0 +- VPCMPEQ %ymm7, %ymm2, %ymm2 +- vpmovmskb %ymm2, %ecx +- testl %ecx, %ecx +- jne L(return_2_vec_size) +- VPMINU %ymm4, %ymm0, %ymm0 +- VPCMPEQ %ymm7, %ymm0, %ymm0 +- vpmovmskb %ymm0, %ecx +- testl %ecx, %ecx +- jne L(return_3_vec_size) +-L(main_loop_header): +- leaq (VEC_SIZE * 4)(%rdi), %rdx +- movl $PAGE_SIZE, %ecx +- /* Align load via RAX. */ +- andq $-(VEC_SIZE * 4), %rdx +- subq %rdi, %rdx +- leaq (%rdi, %rdx), %rax + # ifdef USE_AS_STRNCMP +- /* Starting from this point, the maximum offset, or simply the +- 'offset', DECREASES by the same amount when base pointers are +- moved forward. Return 0 when: +- 1) On match: offset <= the matched vector index. +- 2) On mistmach, offset is before the mistmatched index. ++ cmpq $(VEC_SIZE * 2), %rdx ++ jbe L(ret_zero) ++# endif ++ ++# ifdef USE_AS_WCSCMP ++ /* any non-zero positive value that doesn't inference with 0x1. + */ +- subq %rdx, %r11 +- jbe L(zero) +-# endif +- addq %rsi, %rdx +- movq %rdx, %rsi +- andl $(PAGE_SIZE - 1), %esi +- /* Number of bytes before page crossing. */ +- subq %rsi, %rcx +- /* Number of VEC_SIZE * 4 blocks before page crossing. */ +- shrq $DIVIDE_BY_VEC_4_SHIFT, %rcx +- /* ESI: Number of VEC_SIZE * 4 blocks before page crossing. */ +- movl %ecx, %esi +- jmp L(loop_start) ++ movl $2, %r8d + ++# else ++ xorl %r8d, %r8d ++# endif ++ ++ /* The prepare labels are various entry points from the page ++ cross logic. */ ++L(prepare_loop): ++ ++# ifdef USE_AS_STRNCMP ++ /* Store N + (VEC_SIZE * 4) and place check at the begining of ++ the loop. */ ++ leaq (VEC_SIZE * 2)(%rdi, %rdx), %rdx ++# endif ++L(prepare_loop_no_len): ++ ++ /* Align s1 and adjust s2 accordingly. */ ++ subq %rdi, %rsi ++ andq $-(VEC_SIZE * 4), %rdi ++ addq %rdi, %rsi ++ ++# ifdef USE_AS_STRNCMP ++ subq %rdi, %rdx ++# endif ++ ++L(prepare_loop_aligned): ++ /* eax stores distance from rsi to next page cross. These cases ++ need to be handled specially as the 4x loop could potentially ++ read memory past the length of s1 or s2 and across a page ++ boundary. */ ++ movl $-(VEC_SIZE * 4), %eax ++ subl %esi, %eax ++ andl $(PAGE_SIZE - 1), %eax ++ ++ /* Loop 4x comparisons at a time. */ + .p2align 4 + L(loop): ++ ++ /* End condition for strncmp. */ + # ifdef USE_AS_STRNCMP +- /* Base pointers are moved forward by 4 * VEC_SIZE. Decrease +- the maximum offset (%r11) by the same amount. */ +- subq $(VEC_SIZE * 4), %r11 +- jbe L(zero) +-# endif +- addq $(VEC_SIZE * 4), %rax +- addq $(VEC_SIZE * 4), %rdx +-L(loop_start): +- testl %esi, %esi +- leal -1(%esi), %esi +- je L(loop_cross_page) +-L(back_to_loop): +- /* Main loop, comparing 4 vectors are a time. */ +- vmovdqa (%rax), %ymm0 +- vmovdqa VEC_SIZE(%rax), %ymm3 +- VPCMPEQ (%rdx), %ymm0, %ymm4 +- VPCMPEQ VEC_SIZE(%rdx), %ymm3, %ymm1 +- VPMINU %ymm0, %ymm4, %ymm4 +- VPMINU %ymm3, %ymm1, %ymm1 +- vmovdqa (VEC_SIZE * 2)(%rax), %ymm2 +- VPMINU %ymm1, %ymm4, %ymm0 +- vmovdqa (VEC_SIZE * 3)(%rax), %ymm3 +- VPCMPEQ (VEC_SIZE * 2)(%rdx), %ymm2, %ymm5 +- VPCMPEQ (VEC_SIZE * 3)(%rdx), %ymm3, %ymm6 +- VPMINU %ymm2, %ymm5, %ymm5 +- VPMINU %ymm3, %ymm6, %ymm6 +- VPMINU %ymm5, %ymm0, %ymm0 +- VPMINU %ymm6, %ymm0, %ymm0 +- VPCMPEQ %ymm7, %ymm0, %ymm0 +- +- /* Test each mask (32 bits) individually because for VEC_SIZE +- == 32 is not possible to OR the four masks and keep all bits +- in a 64-bit integer register, differing from SSE2 strcmp +- where ORing is possible. */ +- vpmovmskb %ymm0, %ecx ++ subq $(VEC_SIZE * 4), %rdx ++ jbe L(ret_zero) ++# endif ++ ++ subq $-(VEC_SIZE * 4), %rdi ++ subq $-(VEC_SIZE * 4), %rsi ++ ++ /* Check if rsi loads will cross a page boundary. */ ++ addl $-(VEC_SIZE * 4), %eax ++ jnb L(page_cross_during_loop) ++ ++ /* Loop entry after handling page cross during loop. */ ++L(loop_skip_page_cross_check): ++ VMOVA (VEC_SIZE * 0)(%rdi), %ymm0 ++ VMOVA (VEC_SIZE * 1)(%rdi), %ymm2 ++ VMOVA (VEC_SIZE * 2)(%rdi), %ymm4 ++ VMOVA (VEC_SIZE * 3)(%rdi), %ymm6 ++ ++ /* ymm1 all 1s where s1 and s2 equal. All 0s otherwise. */ ++ VPCMPEQ (VEC_SIZE * 0)(%rsi), %ymm0, %ymm1 ++ ++ VPCMPEQ (VEC_SIZE * 1)(%rsi), %ymm2, %ymm3 ++ VPCMPEQ (VEC_SIZE * 2)(%rsi), %ymm4, %ymm5 ++ VPCMPEQ (VEC_SIZE * 3)(%rsi), %ymm6, %ymm7 ++ ++ ++ /* If any mismatches or null CHAR then 0 CHAR, otherwise non- ++ zero. */ ++ vpand %ymm0, %ymm1, %ymm1 ++ ++ ++ vpand %ymm2, %ymm3, %ymm3 ++ vpand %ymm4, %ymm5, %ymm5 ++ vpand %ymm6, %ymm7, %ymm7 ++ ++ VPMINU %ymm1, %ymm3, %ymm3 ++ VPMINU %ymm5, %ymm7, %ymm7 ++ ++ /* Reduce all 0 CHARs for the 4x VEC into ymm7. */ ++ VPMINU %ymm3, %ymm7, %ymm7 ++ ++ /* If any 0 CHAR then done. */ ++ VPCMPEQ %ymm7, %ymmZERO, %ymm7 ++ vpmovmskb %ymm7, %LOOP_REG ++ testl %LOOP_REG, %LOOP_REG ++ jz L(loop) ++ ++ /* Find which VEC has the mismatch of end of string. */ ++ VPCMPEQ %ymm1, %ymmZERO, %ymm1 ++ vpmovmskb %ymm1, %ecx + testl %ecx, %ecx +- je L(loop) +- VPCMPEQ %ymm7, %ymm4, %ymm0 +- vpmovmskb %ymm0, %edi +- testl %edi, %edi +- je L(test_vec) +- tzcntl %edi, %ecx ++ jnz L(return_vec_0_end) ++ ++ ++ VPCMPEQ %ymm3, %ymmZERO, %ymm3 ++ vpmovmskb %ymm3, %ecx ++ testl %ecx, %ecx ++ jnz L(return_vec_1_end) ++ ++L(return_vec_2_3_end): + # ifdef USE_AS_STRNCMP +- cmpq %rcx, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++ subq $(VEC_SIZE * 2), %rdx ++ jbe L(ret_zero_end) ++# endif ++ ++ VPCMPEQ %ymm5, %ymmZERO, %ymm5 ++ vpmovmskb %ymm5, %ecx ++ testl %ecx, %ecx ++ jnz L(return_vec_2_end) ++ ++ /* LOOP_REG contains matches for null/mismatch from the loop. If ++ VEC 0,1,and 2 all have no null and no mismatches then mismatch ++ must entirely be from VEC 3 which is fully represented by ++ LOOP_REG. */ ++ tzcntl %LOOP_REG, %LOOP_REG ++ ++# ifdef USE_AS_STRNCMP ++ subl $-(VEC_SIZE), %LOOP_REG ++ cmpq %LOOP_REG64, %rdx ++ jbe L(ret_zero_end) ++# endif ++ ++# ifdef USE_AS_WCSCMP ++ movl (VEC_SIZE * 2 - VEC_OFFSET)(%rdi, %LOOP_REG64), %ecx + xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif ++ cmpl (VEC_SIZE * 2 - VEC_OFFSET)(%rsi, %LOOP_REG64), %ecx ++ je L(ret5) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax + # else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif ++ movzbl (VEC_SIZE * 2 - VEC_OFFSET)(%rdi, %LOOP_REG64), %eax ++ movzbl (VEC_SIZE * 2 - VEC_OFFSET)(%rsi, %LOOP_REG64), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif ++L(ret5): + VZEROUPPER_RETURN + +- .p2align 4 +-L(test_vec): + # ifdef USE_AS_STRNCMP +- /* The first vector matched. Return 0 if the maximum offset +- (%r11) <= VEC_SIZE. */ +- cmpq $VEC_SIZE, %r11 +- jbe L(zero) ++ .p2align 4,, 2 ++L(ret_zero_end): ++ xorl %eax, %eax ++ VZEROUPPER_RETURN + # endif +- VPCMPEQ %ymm7, %ymm1, %ymm1 +- vpmovmskb %ymm1, %ecx +- testl %ecx, %ecx +- je L(test_2_vec) +- tzcntl %ecx, %edi ++ ++ ++ /* The L(return_vec_N_end) differ from L(return_vec_N) in that ++ they use the value of `r8` to negate the return value. This is ++ because the page cross logic can swap `rdi` and `rsi`. */ ++ .p2align 4,, 10 + # ifdef USE_AS_STRNCMP +- addq $VEC_SIZE, %rdi +- cmpq %rdi, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++L(return_vec_1_end): ++ salq $32, %rcx ++# endif ++L(return_vec_0_end): ++# ifndef USE_AS_STRNCMP ++ tzcntl %ecx, %ecx ++# else ++ tzcntq %rcx, %rcx ++ cmpq %rcx, %rdx ++ jbe L(ret_zero_end) ++# endif ++ ++# ifdef USE_AS_WCSCMP ++ movl (%rdi, %rcx), %edx + xorl %eax, %eax +- movl (%rsi, %rdi), %ecx +- cmpl (%rdx, %rdi), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rdi), %eax +- movzbl (%rdx, %rdi), %edx +- subl %edx, %eax +-# endif ++ cmpl (%rsi, %rcx), %edx ++ je L(ret6) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax + # else ++ movzbl (%rdi, %rcx), %eax ++ movzbl (%rsi, %rcx), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax ++# endif ++L(ret6): ++ VZEROUPPER_RETURN ++ ++# ifndef USE_AS_STRNCMP ++ .p2align 4,, 10 ++L(return_vec_1_end): ++ tzcntl %ecx, %ecx + # ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++ movl VEC_SIZE(%rdi, %rcx), %edx + xorl %eax, %eax +- movl VEC_SIZE(%rsi, %rdi), %ecx +- cmpl VEC_SIZE(%rdx, %rdi), %ecx +- jne L(wcscmp_return) ++ cmpl VEC_SIZE(%rsi, %rcx), %edx ++ je L(ret7) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax + # else +- movzbl VEC_SIZE(%rax, %rdi), %eax +- movzbl VEC_SIZE(%rdx, %rdi), %edx +- subl %edx, %eax ++ movzbl VEC_SIZE(%rdi, %rcx), %eax ++ movzbl VEC_SIZE(%rsi, %rcx), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif +-# endif ++L(ret7): + VZEROUPPER_RETURN ++# endif + +- .p2align 4 +-L(test_2_vec): ++ .p2align 4,, 10 ++L(return_vec_2_end): ++ tzcntl %ecx, %ecx + # ifdef USE_AS_STRNCMP +- /* The first 2 vectors matched. Return 0 if the maximum offset +- (%r11) <= 2 * VEC_SIZE. */ +- cmpq $(VEC_SIZE * 2), %r11 +- jbe L(zero) ++ cmpq %rcx, %rdx ++ jbe L(ret_zero_page_cross) + # endif +- VPCMPEQ %ymm7, %ymm5, %ymm5 +- vpmovmskb %ymm5, %ecx +- testl %ecx, %ecx +- je L(test_3_vec) +- tzcntl %ecx, %edi +-# ifdef USE_AS_STRNCMP +- addq $(VEC_SIZE * 2), %rdi +- cmpq %rdi, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++# ifdef USE_AS_WCSCMP ++ movl (VEC_SIZE * 2)(%rdi, %rcx), %edx + xorl %eax, %eax +- movl (%rsi, %rdi), %ecx +- cmpl (%rdx, %rdi), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rdi), %eax +- movzbl (%rdx, %rdi), %edx +- subl %edx, %eax +-# endif ++ cmpl (VEC_SIZE * 2)(%rsi, %rcx), %edx ++ je L(ret11) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax + # else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (VEC_SIZE * 2)(%rsi, %rdi), %ecx +- cmpl (VEC_SIZE * 2)(%rdx, %rdi), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (VEC_SIZE * 2)(%rax, %rdi), %eax +- movzbl (VEC_SIZE * 2)(%rdx, %rdi), %edx +- subl %edx, %eax +-# endif ++ movzbl (VEC_SIZE * 2)(%rdi, %rcx), %eax ++ movzbl (VEC_SIZE * 2)(%rsi, %rcx), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif ++L(ret11): + VZEROUPPER_RETURN + +- .p2align 4 +-L(test_3_vec): ++ ++ /* Page cross in rsi in next 4x VEC. */ ++ ++ /* TODO: Improve logic here. */ ++ .p2align 4,, 10 ++L(page_cross_during_loop): ++ /* eax contains [distance_from_page - (VEC_SIZE * 4)]. */ ++ ++ /* Optimistically rsi and rdi and both aligned inwhich case we ++ don't need any logic here. */ ++ cmpl $-(VEC_SIZE * 4), %eax ++ /* Don't adjust eax before jumping back to loop and we will ++ never hit page cross case again. */ ++ je L(loop_skip_page_cross_check) ++ ++ /* Check if we can safely load a VEC. */ ++ cmpl $-(VEC_SIZE * 3), %eax ++ jle L(less_1x_vec_till_page_cross) ++ ++ VMOVA (%rdi), %ymm0 ++ VPCMPEQ (%rsi), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ incl %ecx ++ jnz L(return_vec_0_end) ++ ++ /* if distance >= 2x VEC then eax > -(VEC_SIZE * 2). */ ++ cmpl $-(VEC_SIZE * 2), %eax ++ jg L(more_2x_vec_till_page_cross) ++ ++ .p2align 4,, 4 ++L(less_1x_vec_till_page_cross): ++ subl $-(VEC_SIZE * 4), %eax ++ /* Guranteed safe to read from rdi - VEC_SIZE here. The only ++ concerning case is first iteration if incoming s1 was near start ++ of a page and s2 near end. If s1 was near the start of the page ++ we already aligned up to nearest VEC_SIZE * 4 so gurnateed safe ++ to read back -VEC_SIZE. If rdi is truly at the start of a page ++ here, it means the previous page (rdi - VEC_SIZE) has already ++ been loaded earlier so must be valid. */ ++ VMOVU -VEC_SIZE(%rdi, %rax), %ymm0 ++ VPCMPEQ -VEC_SIZE(%rsi, %rax), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ ++ /* Mask of potentially valid bits. The lower bits can be out of ++ range comparisons (but safe regarding page crosses). */ ++ movl $-1, %r10d ++ shlxl %esi, %r10d, %r10d ++ notl %ecx ++ + # ifdef USE_AS_STRNCMP +- /* The first 3 vectors matched. Return 0 if the maximum offset +- (%r11) <= 3 * VEC_SIZE. */ +- cmpq $(VEC_SIZE * 3), %r11 +- jbe L(zero) +-# endif +- VPCMPEQ %ymm7, %ymm6, %ymm6 +- vpmovmskb %ymm6, %esi +- tzcntl %esi, %ecx ++ cmpq %rax, %rdx ++ jbe L(return_page_cross_end_check) ++# endif ++ movl %eax, %OFFSET_REG ++ addl $(PAGE_SIZE - VEC_SIZE * 4), %eax ++ ++ andl %r10d, %ecx ++ jz L(loop_skip_page_cross_check) ++ ++ .p2align 4,, 3 ++L(return_page_cross_end): ++ tzcntl %ecx, %ecx ++ + # ifdef USE_AS_STRNCMP +- addq $(VEC_SIZE * 3), %rcx +- cmpq %rcx, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (%rsi, %rcx), %esi +- cmpl (%rdx, %rcx), %esi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif ++ leal -VEC_SIZE(%OFFSET_REG64, %rcx), %ecx ++L(return_page_cross_cmp_mem): + # else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++ addl %OFFSET_REG, %ecx ++# endif ++# ifdef USE_AS_WCSCMP ++ movl VEC_OFFSET(%rdi, %rcx), %edx + xorl %eax, %eax +- movl (VEC_SIZE * 3)(%rsi, %rcx), %esi +- cmpl (VEC_SIZE * 3)(%rdx, %rcx), %esi +- jne L(wcscmp_return) +-# else +- movzbl (VEC_SIZE * 3)(%rax, %rcx), %eax +- movzbl (VEC_SIZE * 3)(%rdx, %rcx), %edx +- subl %edx, %eax +-# endif ++ cmpl VEC_OFFSET(%rsi, %rcx), %edx ++ je L(ret8) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax ++# else ++ movzbl VEC_OFFSET(%rdi, %rcx), %eax ++ movzbl VEC_OFFSET(%rsi, %rcx), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif ++L(ret8): + VZEROUPPER_RETURN + +- .p2align 4 +-L(loop_cross_page): +- xorl %r10d, %r10d +- movq %rdx, %rcx +- /* Align load via RDX. We load the extra ECX bytes which should +- be ignored. */ +- andl $((VEC_SIZE * 4) - 1), %ecx +- /* R10 is -RCX. */ +- subq %rcx, %r10 +- +- /* This works only if VEC_SIZE * 2 == 64. */ +-# if (VEC_SIZE * 2) != 64 +-# error (VEC_SIZE * 2) != 64 +-# endif +- +- /* Check if the first VEC_SIZE * 2 bytes should be ignored. */ +- cmpl $(VEC_SIZE * 2), %ecx +- jge L(loop_cross_page_2_vec) +- +- vmovdqu (%rax, %r10), %ymm2 +- vmovdqu VEC_SIZE(%rax, %r10), %ymm3 +- VPCMPEQ (%rdx, %r10), %ymm2, %ymm0 +- VPCMPEQ VEC_SIZE(%rdx, %r10), %ymm3, %ymm1 +- VPMINU %ymm2, %ymm0, %ymm0 +- VPMINU %ymm3, %ymm1, %ymm1 +- VPCMPEQ %ymm7, %ymm0, %ymm0 +- VPCMPEQ %ymm7, %ymm1, %ymm1 +- +- vpmovmskb %ymm0, %edi +- vpmovmskb %ymm1, %esi +- +- salq $32, %rsi +- xorq %rsi, %rdi +- +- /* Since ECX < VEC_SIZE * 2, simply skip the first ECX bytes. */ +- shrq %cl, %rdi +- +- testq %rdi, %rdi +- je L(loop_cross_page_2_vec) +- tzcntq %rdi, %rcx + # ifdef USE_AS_STRNCMP +- cmpq %rcx, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++ .p2align 4,, 10 ++L(return_page_cross_end_check): ++ tzcntl %ecx, %ecx ++ leal -VEC_SIZE(%rax, %rcx), %ecx ++ cmpl %ecx, %edx ++ ja L(return_page_cross_cmp_mem) + xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif +-# else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif +-# endif + VZEROUPPER_RETURN ++# endif + +- .p2align 4 +-L(loop_cross_page_2_vec): +- /* The first VEC_SIZE * 2 bytes match or are ignored. */ +- vmovdqu (VEC_SIZE * 2)(%rax, %r10), %ymm2 +- vmovdqu (VEC_SIZE * 3)(%rax, %r10), %ymm3 +- VPCMPEQ (VEC_SIZE * 2)(%rdx, %r10), %ymm2, %ymm5 +- VPMINU %ymm2, %ymm5, %ymm5 +- VPCMPEQ (VEC_SIZE * 3)(%rdx, %r10), %ymm3, %ymm6 +- VPCMPEQ %ymm7, %ymm5, %ymm5 +- VPMINU %ymm3, %ymm6, %ymm6 +- VPCMPEQ %ymm7, %ymm6, %ymm6 +- +- vpmovmskb %ymm5, %edi +- vpmovmskb %ymm6, %esi +- +- salq $32, %rsi +- xorq %rsi, %rdi + +- xorl %r8d, %r8d +- /* If ECX > VEC_SIZE * 2, skip ECX - (VEC_SIZE * 2) bytes. */ +- subl $(VEC_SIZE * 2), %ecx +- jle 1f +- /* Skip ECX bytes. */ +- shrq %cl, %rdi +- /* R8 has number of bytes skipped. */ +- movl %ecx, %r8d +-1: +- /* Before jumping back to the loop, set ESI to the number of +- VEC_SIZE * 4 blocks before page crossing. */ +- movl $(PAGE_SIZE / (VEC_SIZE * 4) - 1), %esi +- +- testq %rdi, %rdi ++ .p2align 4,, 10 ++L(more_2x_vec_till_page_cross): ++ /* If more 2x vec till cross we will complete a full loop ++ iteration here. */ ++ ++ VMOVU VEC_SIZE(%rdi), %ymm0 ++ VPCMPEQ VEC_SIZE(%rsi), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ incl %ecx ++ jnz L(return_vec_1_end) ++ + # ifdef USE_AS_STRNCMP +- /* At this point, if %rdi value is 0, it already tested +- VEC_SIZE*4+%r10 byte starting from %rax. This label +- checks whether strncmp maximum offset reached or not. */ +- je L(string_nbyte_offset_check) +-# else +- je L(back_to_loop) ++ cmpq $(VEC_SIZE * 2), %rdx ++ jbe L(ret_zero_in_loop_page_cross) + # endif +- tzcntq %rdi, %rcx +- addq %r10, %rcx +- /* Adjust for number of bytes skipped. */ +- addq %r8, %rcx ++ ++ subl $-(VEC_SIZE * 4), %eax ++ ++ /* Safe to include comparisons from lower bytes. */ ++ VMOVU -(VEC_SIZE * 2)(%rdi, %rax), %ymm0 ++ VPCMPEQ -(VEC_SIZE * 2)(%rsi, %rax), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ incl %ecx ++ jnz L(return_vec_page_cross_0) ++ ++ VMOVU -(VEC_SIZE * 1)(%rdi, %rax), %ymm0 ++ VPCMPEQ -(VEC_SIZE * 1)(%rsi, %rax), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ incl %ecx ++ jnz L(return_vec_page_cross_1) ++ + # ifdef USE_AS_STRNCMP +- addq $(VEC_SIZE * 2), %rcx +- subq %rcx, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++ /* Must check length here as length might proclude reading next ++ page. */ ++ cmpq %rax, %rdx ++ jbe L(ret_zero_in_loop_page_cross) ++# endif ++ ++ /* Finish the loop. */ ++ VMOVA (VEC_SIZE * 2)(%rdi), %ymm4 ++ VMOVA (VEC_SIZE * 3)(%rdi), %ymm6 ++ ++ VPCMPEQ (VEC_SIZE * 2)(%rsi), %ymm4, %ymm5 ++ VPCMPEQ (VEC_SIZE * 3)(%rsi), %ymm6, %ymm7 ++ vpand %ymm4, %ymm5, %ymm5 ++ vpand %ymm6, %ymm7, %ymm7 ++ VPMINU %ymm5, %ymm7, %ymm7 ++ VPCMPEQ %ymm7, %ymmZERO, %ymm7 ++ vpmovmskb %ymm7, %LOOP_REG ++ testl %LOOP_REG, %LOOP_REG ++ jnz L(return_vec_2_3_end) ++ ++ /* Best for code size to include ucond-jmp here. Would be faster ++ if this case is hot to duplicate the L(return_vec_2_3_end) code ++ as fall-through and have jump back to loop on mismatch ++ comparison. */ ++ subq $-(VEC_SIZE * 4), %rdi ++ subq $-(VEC_SIZE * 4), %rsi ++ addl $(PAGE_SIZE - VEC_SIZE * 8), %eax ++# ifdef USE_AS_STRNCMP ++ subq $(VEC_SIZE * 4), %rdx ++ ja L(loop_skip_page_cross_check) ++L(ret_zero_in_loop_page_cross): + xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif ++ VZEROUPPER_RETURN + # else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (VEC_SIZE * 2)(%rsi, %rcx), %edi +- cmpl (VEC_SIZE * 2)(%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (VEC_SIZE * 2)(%rax, %rcx), %eax +- movzbl (VEC_SIZE * 2)(%rdx, %rcx), %edx +- subl %edx, %eax +-# endif ++ jmp L(loop_skip_page_cross_check) + # endif +- VZEROUPPER_RETURN + ++ ++ .p2align 4,, 10 ++L(return_vec_page_cross_0): ++ addl $-VEC_SIZE, %eax ++L(return_vec_page_cross_1): ++ tzcntl %ecx, %ecx + # ifdef USE_AS_STRNCMP +-L(string_nbyte_offset_check): +- leaq (VEC_SIZE * 4)(%r10), %r10 +- cmpq %r10, %r11 +- jbe L(zero) +- jmp L(back_to_loop) ++ leal -VEC_SIZE(%rax, %rcx), %ecx ++ cmpq %rcx, %rdx ++ jbe L(ret_zero_in_loop_page_cross) ++# else ++ addl %eax, %ecx + # endif + +- .p2align 4 +-L(cross_page_loop): +- /* Check one byte/dword at a time. */ + # ifdef USE_AS_WCSCMP +- cmpl %ecx, %eax ++ movl VEC_OFFSET(%rdi, %rcx), %edx ++ xorl %eax, %eax ++ cmpl VEC_OFFSET(%rsi, %rcx), %edx ++ je L(ret9) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax + # else ++ movzbl VEC_OFFSET(%rdi, %rcx), %eax ++ movzbl VEC_OFFSET(%rsi, %rcx), %ecx + subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif +- jne L(different) +- addl $SIZE_OF_CHAR, %edx +- cmpl $(VEC_SIZE * 4), %edx +- je L(main_loop_header) +-# ifdef USE_AS_STRNCMP +- cmpq %r11, %rdx +- jae L(zero) ++L(ret9): ++ VZEROUPPER_RETURN ++ ++ ++ .p2align 4,, 10 ++L(page_cross): ++# ifndef USE_AS_STRNCMP ++ /* If both are VEC aligned we don't need any special logic here. ++ Only valid for strcmp where stop condition is guranteed to be ++ reachable by just reading memory. */ ++ testl $((VEC_SIZE - 1) << 20), %eax ++ jz L(no_page_cross) + # endif ++ ++ movl %edi, %eax ++ movl %esi, %ecx ++ andl $(PAGE_SIZE - 1), %eax ++ andl $(PAGE_SIZE - 1), %ecx ++ ++ xorl %OFFSET_REG, %OFFSET_REG ++ ++ /* Check which is closer to page cross, s1 or s2. */ ++ cmpl %eax, %ecx ++ jg L(page_cross_s2) ++ ++ /* The previous page cross check has false positives. Check for ++ true positive as page cross logic is very expensive. */ ++ subl $(PAGE_SIZE - VEC_SIZE * 4), %eax ++ jbe L(no_page_cross) ++ ++ /* Set r8 to not interfere with normal return value (rdi and rsi ++ did not swap). */ + # ifdef USE_AS_WCSCMP +- movl (%rdi, %rdx), %eax +- movl (%rsi, %rdx), %ecx ++ /* any non-zero positive value that doesn't inference with 0x1. ++ */ ++ movl $2, %r8d + # else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %ecx ++ xorl %r8d, %r8d + # endif +- /* Check null char. */ +- testl %eax, %eax +- jne L(cross_page_loop) +- /* Since %eax == 0, subtract is OK for both SIGNED and UNSIGNED +- comparisons. */ +- subl %ecx, %eax +-# ifndef USE_AS_WCSCMP +-L(different): ++ ++ /* Check if less than 1x VEC till page cross. */ ++ subl $(VEC_SIZE * 3), %eax ++ jg L(less_1x_vec_till_page) ++ ++ /* If more than 1x VEC till page cross, loop throuh safely ++ loadable memory until within 1x VEC of page cross. */ ++ ++ .p2align 4,, 10 ++L(page_cross_loop): ++ ++ VMOVU (%rdi, %OFFSET_REG64), %ymm0 ++ VPCMPEQ (%rsi, %OFFSET_REG64), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ incl %ecx ++ ++ jnz L(check_ret_vec_page_cross) ++ addl $VEC_SIZE, %OFFSET_REG ++# ifdef USE_AS_STRNCMP ++ cmpq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross) + # endif +- VZEROUPPER_RETURN ++ addl $VEC_SIZE, %eax ++ jl L(page_cross_loop) ++ ++ subl %eax, %OFFSET_REG ++ /* OFFSET_REG has distance to page cross - VEC_SIZE. Guranteed ++ to not cross page so is safe to load. Since we have already ++ loaded at least 1 VEC from rsi it is also guranteed to be safe. ++ */ ++ ++ VMOVU (%rdi, %OFFSET_REG64), %ymm0 ++ VPCMPEQ (%rsi, %OFFSET_REG64), %ymm0, %ymm1 ++ VPCMPEQ %ymm0, %ymmZERO, %ymm2 ++ vpandn %ymm1, %ymm2, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ ++# ifdef USE_AS_STRNCMP ++ leal VEC_SIZE(%OFFSET_REG64), %eax ++ cmpq %rax, %rdx ++ jbe L(check_ret_vec_page_cross2) ++ addq %rdi, %rdx ++# endif ++ incl %ecx ++ jz L(prepare_loop_no_len) + ++ .p2align 4,, 4 ++L(ret_vec_page_cross): ++# ifndef USE_AS_STRNCMP ++L(check_ret_vec_page_cross): ++# endif ++ tzcntl %ecx, %ecx ++ addl %OFFSET_REG, %ecx ++L(ret_vec_page_cross_cont): + # ifdef USE_AS_WCSCMP +- .p2align 4 +-L(different): +- /* Use movl to avoid modifying EFLAGS. */ +- movl $0, %eax ++ movl (%rdi, %rcx), %edx ++ xorl %eax, %eax ++ cmpl (%rsi, %rcx), %edx ++ je L(ret12) + setl %al + negl %eax +- orl $1, %eax +- VZEROUPPER_RETURN ++ xorl %r8d, %eax ++# else ++ movzbl (%rdi, %rcx), %eax ++ movzbl (%rsi, %rcx), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif ++L(ret12): ++ VZEROUPPER_RETURN + + # ifdef USE_AS_STRNCMP +- .p2align 4 +-L(zero): ++ .p2align 4,, 10 ++L(check_ret_vec_page_cross2): ++ incl %ecx ++L(check_ret_vec_page_cross): ++ tzcntl %ecx, %ecx ++ addl %OFFSET_REG, %ecx ++ cmpq %rcx, %rdx ++ ja L(ret_vec_page_cross_cont) ++ .p2align 4,, 2 ++L(ret_zero_page_cross): + xorl %eax, %eax + VZEROUPPER_RETURN ++# endif + +- .p2align 4 +-L(char0): +-# ifdef USE_AS_WCSCMP +- xorl %eax, %eax +- movl (%rdi), %ecx +- cmpl (%rsi), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rsi), %ecx +- movzbl (%rdi), %eax +- subl %ecx, %eax +-# endif +- VZEROUPPER_RETURN ++ .p2align 4,, 4 ++L(page_cross_s2): ++ /* Ensure this is a true page cross. */ ++ subl $(PAGE_SIZE - VEC_SIZE * 4), %ecx ++ jbe L(no_page_cross) ++ ++ ++ movl %ecx, %eax ++ movq %rdi, %rcx ++ movq %rsi, %rdi ++ movq %rcx, %rsi ++ ++ /* set r8 to negate return value as rdi and rsi swapped. */ ++# ifdef USE_AS_WCSCMP ++ movl $-4, %r8d ++# else ++ movl $-1, %r8d + # endif ++ xorl %OFFSET_REG, %OFFSET_REG + +- .p2align 4 +-L(last_vector): +- addq %rdx, %rdi +- addq %rdx, %rsi ++ /* Check if more than 1x VEC till page cross. */ ++ subl $(VEC_SIZE * 3), %eax ++ jle L(page_cross_loop) ++ ++ .p2align 4,, 6 ++L(less_1x_vec_till_page): ++ /* Find largest load size we can use. */ ++ cmpl $16, %eax ++ ja L(less_16_till_page) ++ ++ VMOVU (%rdi), %xmm0 ++ VPCMPEQ (%rsi), %xmm0, %xmm1 ++ VPCMPEQ %xmm0, %xmmZERO, %xmm2 ++ vpandn %xmm1, %xmm2, %xmm1 ++ vpmovmskb %ymm1, %ecx ++ incw %cx ++ jnz L(check_ret_vec_page_cross) ++ movl $16, %OFFSET_REG + # ifdef USE_AS_STRNCMP +- subq %rdx, %r11 ++ cmpq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross_slow_case0) ++ subl %eax, %OFFSET_REG ++# else ++ /* Explicit check for 16 byte alignment. */ ++ subl %eax, %OFFSET_REG ++ jz L(prepare_loop) + # endif +- tzcntl %ecx, %edx ++ ++ VMOVU (%rdi, %OFFSET_REG64), %xmm0 ++ VPCMPEQ (%rsi, %OFFSET_REG64), %xmm0, %xmm1 ++ VPCMPEQ %xmm0, %xmmZERO, %xmm2 ++ vpandn %xmm1, %xmm2, %xmm1 ++ vpmovmskb %ymm1, %ecx ++ incw %cx ++ jnz L(check_ret_vec_page_cross) ++ + # ifdef USE_AS_STRNCMP +- cmpq %r11, %rdx +- jae L(zero) ++ addl $16, %OFFSET_REG ++ subq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross_slow_case0) ++ subq $-(VEC_SIZE * 4), %rdx ++ ++ leaq -(VEC_SIZE * 4)(%rdi, %OFFSET_REG64), %rdi ++ leaq -(VEC_SIZE * 4)(%rsi, %OFFSET_REG64), %rsi ++# else ++ leaq (16 - VEC_SIZE * 4)(%rdi, %OFFSET_REG64), %rdi ++ leaq (16 - VEC_SIZE * 4)(%rsi, %OFFSET_REG64), %rsi + # endif +-# ifdef USE_AS_WCSCMP ++ jmp L(prepare_loop_aligned) ++ ++# ifdef USE_AS_STRNCMP ++ .p2align 4,, 2 ++L(ret_zero_page_cross_slow_case0): + xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax ++ ret + # endif +- VZEROUPPER_RETURN + +- /* Comparing on page boundary region requires special treatment: +- It must done one vector at the time, starting with the wider +- ymm vector if possible, if not, with xmm. If fetching 16 bytes +- (xmm) still passes the boundary, byte comparison must be done. +- */ +- .p2align 4 +-L(cross_page): +- /* Try one ymm vector at a time. */ +- cmpl $(PAGE_SIZE - VEC_SIZE), %eax +- jg L(cross_page_1_vector) +-L(loop_1_vector): +- vmovdqu (%rdi, %rdx), %ymm1 +- VPCMPEQ (%rsi, %rdx), %ymm1, %ymm0 +- VPMINU %ymm1, %ymm0, %ymm0 +- VPCMPEQ %ymm7, %ymm0, %ymm0 +- vpmovmskb %ymm0, %ecx +- testl %ecx, %ecx +- jne L(last_vector) + +- addl $VEC_SIZE, %edx ++ .p2align 4,, 10 ++L(less_16_till_page): ++ /* Find largest load size we can use. */ ++ cmpl $24, %eax ++ ja L(less_8_till_page) + +- addl $VEC_SIZE, %eax +-# ifdef USE_AS_STRNCMP +- /* Return 0 if the current offset (%rdx) >= the maximum offset +- (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) +-# endif +- cmpl $(PAGE_SIZE - VEC_SIZE), %eax +- jle L(loop_1_vector) +-L(cross_page_1_vector): +- /* Less than 32 bytes to check, try one xmm vector. */ +- cmpl $(PAGE_SIZE - 16), %eax +- jg L(cross_page_1_xmm) +- vmovdqu (%rdi, %rdx), %xmm1 +- VPCMPEQ (%rsi, %rdx), %xmm1, %xmm0 +- VPMINU %xmm1, %xmm0, %xmm0 +- VPCMPEQ %xmm7, %xmm0, %xmm0 +- vpmovmskb %xmm0, %ecx +- testl %ecx, %ecx +- jne L(last_vector) ++ vmovq (%rdi), %xmm0 ++ vmovq (%rsi), %xmm1 ++ VPCMPEQ %xmm0, %xmmZERO, %xmm2 ++ VPCMPEQ %xmm1, %xmm0, %xmm1 ++ vpandn %xmm1, %xmm2, %xmm1 ++ vpmovmskb %ymm1, %ecx ++ incb %cl ++ jnz L(check_ret_vec_page_cross) + +- addl $16, %edx +-# ifndef USE_AS_WCSCMP +- addl $16, %eax ++ ++# ifdef USE_AS_STRNCMP ++ cmpq $8, %rdx ++ jbe L(ret_zero_page_cross_slow_case0) + # endif ++ movl $24, %OFFSET_REG ++ /* Explicit check for 16 byte alignment. */ ++ subl %eax, %OFFSET_REG ++ ++ ++ ++ vmovq (%rdi, %OFFSET_REG64), %xmm0 ++ vmovq (%rsi, %OFFSET_REG64), %xmm1 ++ VPCMPEQ %xmm0, %xmmZERO, %xmm2 ++ VPCMPEQ %xmm1, %xmm0, %xmm1 ++ vpandn %xmm1, %xmm2, %xmm1 ++ vpmovmskb %ymm1, %ecx ++ incb %cl ++ jnz L(check_ret_vec_page_cross) ++ + # ifdef USE_AS_STRNCMP +- /* Return 0 if the current offset (%rdx) >= the maximum offset +- (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) +-# endif +- +-L(cross_page_1_xmm): +-# ifndef USE_AS_WCSCMP +- /* Less than 16 bytes to check, try 8 byte vector. NB: No need +- for wcscmp nor wcsncmp since wide char is 4 bytes. */ +- cmpl $(PAGE_SIZE - 8), %eax +- jg L(cross_page_8bytes) +- vmovq (%rdi, %rdx), %xmm1 +- vmovq (%rsi, %rdx), %xmm0 +- VPCMPEQ %xmm0, %xmm1, %xmm0 +- VPMINU %xmm1, %xmm0, %xmm0 +- VPCMPEQ %xmm7, %xmm0, %xmm0 +- vpmovmskb %xmm0, %ecx +- /* Only last 8 bits are valid. */ +- andl $0xff, %ecx +- testl %ecx, %ecx +- jne L(last_vector) ++ addl $8, %OFFSET_REG ++ subq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross_slow_case0) ++ subq $-(VEC_SIZE * 4), %rdx + +- addl $8, %edx +- addl $8, %eax ++ leaq -(VEC_SIZE * 4)(%rdi, %OFFSET_REG64), %rdi ++ leaq -(VEC_SIZE * 4)(%rsi, %OFFSET_REG64), %rsi ++# else ++ leaq (8 - VEC_SIZE * 4)(%rdi, %OFFSET_REG64), %rdi ++ leaq (8 - VEC_SIZE * 4)(%rsi, %OFFSET_REG64), %rsi ++# endif ++ jmp L(prepare_loop_aligned) ++ ++ ++ .p2align 4,, 10 ++L(less_8_till_page): ++# ifdef USE_AS_WCSCMP ++ /* If using wchar then this is the only check before we reach ++ the page boundary. */ ++ movl (%rdi), %eax ++ movl (%rsi), %ecx ++ cmpl %ecx, %eax ++ jnz L(ret_less_8_wcs) + # ifdef USE_AS_STRNCMP +- /* Return 0 if the current offset (%rdx) >= the maximum offset +- (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) ++ addq %rdi, %rdx ++ /* We already checked for len <= 1 so cannot hit that case here. ++ */ + # endif ++ testl %eax, %eax ++ jnz L(prepare_loop_no_len) ++ ret + +-L(cross_page_8bytes): +- /* Less than 8 bytes to check, try 4 byte vector. */ +- cmpl $(PAGE_SIZE - 4), %eax +- jg L(cross_page_4bytes) +- vmovd (%rdi, %rdx), %xmm1 +- vmovd (%rsi, %rdx), %xmm0 +- VPCMPEQ %xmm0, %xmm1, %xmm0 +- VPMINU %xmm1, %xmm0, %xmm0 +- VPCMPEQ %xmm7, %xmm0, %xmm0 +- vpmovmskb %xmm0, %ecx +- /* Only last 4 bits are valid. */ +- andl $0xf, %ecx +- testl %ecx, %ecx +- jne L(last_vector) ++ .p2align 4,, 8 ++L(ret_less_8_wcs): ++ setl %OFFSET_REG8 ++ negl %OFFSET_REG ++ movl %OFFSET_REG, %eax ++ xorl %r8d, %eax ++ ret ++ ++# else ++ ++ /* Find largest load size we can use. */ ++ cmpl $28, %eax ++ ja L(less_4_till_page) ++ ++ vmovd (%rdi), %xmm0 ++ vmovd (%rsi), %xmm1 ++ VPCMPEQ %xmm0, %xmmZERO, %xmm2 ++ VPCMPEQ %xmm1, %xmm0, %xmm1 ++ vpandn %xmm1, %xmm2, %xmm1 ++ vpmovmskb %ymm1, %ecx ++ subl $0xf, %ecx ++ jnz L(check_ret_vec_page_cross) + +- addl $4, %edx + # ifdef USE_AS_STRNCMP +- /* Return 0 if the current offset (%rdx) >= the maximum offset +- (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) ++ cmpq $4, %rdx ++ jbe L(ret_zero_page_cross_slow_case1) + # endif ++ movl $28, %OFFSET_REG ++ /* Explicit check for 16 byte alignment. */ ++ subl %eax, %OFFSET_REG + +-L(cross_page_4bytes): +-# endif +- /* Less than 4 bytes to check, try one byte/dword at a time. */ +-# ifdef USE_AS_STRNCMP +- cmpq %r11, %rdx +- jae L(zero) +-# endif +-# ifdef USE_AS_WCSCMP +- movl (%rdi, %rdx), %eax +- movl (%rsi, %rdx), %ecx +-# else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %ecx +-# endif +- testl %eax, %eax +- jne L(cross_page_loop) ++ ++ ++ vmovd (%rdi, %OFFSET_REG64), %xmm0 ++ vmovd (%rsi, %OFFSET_REG64), %xmm1 ++ VPCMPEQ %xmm0, %xmmZERO, %xmm2 ++ VPCMPEQ %xmm1, %xmm0, %xmm1 ++ vpandn %xmm1, %xmm2, %xmm1 ++ vpmovmskb %ymm1, %ecx ++ subl $0xf, %ecx ++ jnz L(check_ret_vec_page_cross) ++ ++# ifdef USE_AS_STRNCMP ++ addl $4, %OFFSET_REG ++ subq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross_slow_case1) ++ subq $-(VEC_SIZE * 4), %rdx ++ ++ leaq -(VEC_SIZE * 4)(%rdi, %OFFSET_REG64), %rdi ++ leaq -(VEC_SIZE * 4)(%rsi, %OFFSET_REG64), %rsi ++# else ++ leaq (4 - VEC_SIZE * 4)(%rdi, %OFFSET_REG64), %rdi ++ leaq (4 - VEC_SIZE * 4)(%rsi, %OFFSET_REG64), %rsi ++# endif ++ jmp L(prepare_loop_aligned) ++ ++# ifdef USE_AS_STRNCMP ++ .p2align 4,, 2 ++L(ret_zero_page_cross_slow_case1): ++ xorl %eax, %eax ++ ret ++# endif ++ ++ .p2align 4,, 10 ++L(less_4_till_page): ++ subq %rdi, %rsi ++ /* Extremely slow byte comparison loop. */ ++L(less_4_loop): ++ movzbl (%rdi), %eax ++ movzbl (%rsi, %rdi), %ecx + subl %ecx, %eax +- VZEROUPPER_RETURN +-END (STRCMP) ++ jnz L(ret_less_4_loop) ++ testl %ecx, %ecx ++ jz L(ret_zero_4_loop) ++# ifdef USE_AS_STRNCMP ++ decq %rdx ++ jz L(ret_zero_4_loop) ++# endif ++ incq %rdi ++ /* end condition is reach page boundary (rdi is aligned). */ ++ testl $31, %edi ++ jnz L(less_4_loop) ++ leaq -(VEC_SIZE * 4)(%rdi, %rsi), %rsi ++ addq $-(VEC_SIZE * 4), %rdi ++# ifdef USE_AS_STRNCMP ++ subq $-(VEC_SIZE * 4), %rdx ++# endif ++ jmp L(prepare_loop_aligned) ++ ++L(ret_zero_4_loop): ++ xorl %eax, %eax ++ ret ++L(ret_less_4_loop): ++ xorl %r8d, %eax ++ subl %r8d, %eax ++ ret ++# endif ++END(STRCMP) + #endif diff --git a/SOURCES/glibc-upstream-2.34-202.patch b/SOURCES/glibc-upstream-2.34-202.patch new file mode 100644 index 0000000..9357b6f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-202.patch @@ -0,0 +1,1987 @@ +commit c41a66767d23b7f219fb943be6fab5ddf822d7da +Author: Noah Goldstein +Date: Mon Jan 10 15:35:39 2022 -0600 + + x86: Optimize strcmp-evex.S + + Optimization are primarily to the loop logic and how the page cross + logic interacts with the loop. + + The page cross logic is at times more expensive for short strings near + the end of a page but not crossing the page. This is done to retest + the page cross conditions with a non-faulty check and to improve the + logic for entering the loop afterwards. This is only particular cases, + however, and is general made up for by more than 10x improvements on + the transition from the page cross -> loop case. + + The non-page cross cases as well are nearly universally improved. + + test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass. + + Signed-off-by: Noah Goldstein + (cherry picked from commit 8418eb3ff4b781d31c4ed5dc6c0bd7356bc45db9) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S +index 6f5c4bf984da2b80..99d8409af27327ad 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-evex.S ++++ b/sysdeps/x86_64/multiarch/strcmp-evex.S +@@ -26,54 +26,69 @@ + + # define PAGE_SIZE 4096 + +-/* VEC_SIZE = Number of bytes in a ymm register */ ++ /* VEC_SIZE = Number of bytes in a ymm register. */ + # define VEC_SIZE 32 ++# define CHAR_PER_VEC (VEC_SIZE / SIZE_OF_CHAR) + +-/* Shift for dividing by (VEC_SIZE * 4). */ +-# define DIVIDE_BY_VEC_4_SHIFT 7 +-# if (VEC_SIZE * 4) != (1 << DIVIDE_BY_VEC_4_SHIFT) +-# error (VEC_SIZE * 4) != (1 << DIVIDE_BY_VEC_4_SHIFT) +-# endif +- +-# define VMOVU vmovdqu64 +-# define VMOVA vmovdqa64 ++# define VMOVU vmovdqu64 ++# define VMOVA vmovdqa64 + + # ifdef USE_AS_WCSCMP +-/* Compare packed dwords. */ +-# define VPCMP vpcmpd ++# define TESTEQ subl $0xff, ++ /* Compare packed dwords. */ ++# define VPCMP vpcmpd + # define VPMINU vpminud + # define VPTESTM vptestmd +-# define SHIFT_REG32 r8d +-# define SHIFT_REG64 r8 +-/* 1 dword char == 4 bytes. */ ++ /* 1 dword char == 4 bytes. */ + # define SIZE_OF_CHAR 4 + # else +-/* Compare packed bytes. */ +-# define VPCMP vpcmpb ++# define TESTEQ incl ++ /* Compare packed bytes. */ ++# define VPCMP vpcmpb + # define VPMINU vpminub + # define VPTESTM vptestmb +-# define SHIFT_REG32 ecx +-# define SHIFT_REG64 rcx +-/* 1 byte char == 1 byte. */ ++ /* 1 byte char == 1 byte. */ + # define SIZE_OF_CHAR 1 + # endif + ++# ifdef USE_AS_STRNCMP ++# define LOOP_REG r9d ++# define LOOP_REG64 r9 ++ ++# define OFFSET_REG8 r9b ++# define OFFSET_REG r9d ++# define OFFSET_REG64 r9 ++# else ++# define LOOP_REG edx ++# define LOOP_REG64 rdx ++ ++# define OFFSET_REG8 dl ++# define OFFSET_REG edx ++# define OFFSET_REG64 rdx ++# endif ++ ++# if defined USE_AS_STRNCMP || defined USE_AS_WCSCMP ++# define VEC_OFFSET 0 ++# else ++# define VEC_OFFSET (-VEC_SIZE) ++# endif ++ + # define XMMZERO xmm16 +-# define XMM0 xmm17 +-# define XMM1 xmm18 ++# define XMM0 xmm17 ++# define XMM1 xmm18 + + # define YMMZERO ymm16 +-# define YMM0 ymm17 +-# define YMM1 ymm18 +-# define YMM2 ymm19 +-# define YMM3 ymm20 +-# define YMM4 ymm21 +-# define YMM5 ymm22 +-# define YMM6 ymm23 +-# define YMM7 ymm24 +-# define YMM8 ymm25 +-# define YMM9 ymm26 +-# define YMM10 ymm27 ++# define YMM0 ymm17 ++# define YMM1 ymm18 ++# define YMM2 ymm19 ++# define YMM3 ymm20 ++# define YMM4 ymm21 ++# define YMM5 ymm22 ++# define YMM6 ymm23 ++# define YMM7 ymm24 ++# define YMM8 ymm25 ++# define YMM9 ymm26 ++# define YMM10 ymm27 + + /* Warning! + wcscmp/wcsncmp have to use SIGNED comparison for elements. +@@ -96,985 +111,1096 @@ + the maximum offset is reached before a difference is found, zero is + returned. */ + +- .section .text.evex,"ax",@progbits +-ENTRY (STRCMP) ++ .section .text.evex, "ax", @progbits ++ENTRY(STRCMP) + # ifdef USE_AS_STRNCMP +- /* Check for simple cases (0 or 1) in offset. */ +- cmp $1, %RDX_LP +- je L(char0) +- jb L(zero) +-# ifdef USE_AS_WCSCMP +-# ifndef __ILP32__ +- movq %rdx, %rcx +- /* Check if length could overflow when multiplied by +- sizeof(wchar_t). Checking top 8 bits will cover all potential +- overflow cases as well as redirect cases where its impossible to +- length to bound a valid memory region. In these cases just use +- 'wcscmp'. */ +- shrq $56, %rcx +- jnz __wcscmp_evex +-# endif +- /* Convert units: from wide to byte char. */ +- shl $2, %RDX_LP ++# ifdef __ILP32__ ++ /* Clear the upper 32 bits. */ ++ movl %edx, %rdx + # endif +- /* Register %r11 tracks the maximum offset. */ +- mov %RDX_LP, %R11_LP ++ cmp $1, %RDX_LP ++ /* Signed comparison intentional. We use this branch to also ++ test cases where length >= 2^63. These very large sizes can be ++ handled with strcmp as there is no way for that length to ++ actually bound the buffer. */ ++ jle L(one_or_less) + # endif + movl %edi, %eax +- xorl %edx, %edx +- /* Make %XMMZERO (%YMMZERO) all zeros in this function. */ +- vpxorq %XMMZERO, %XMMZERO, %XMMZERO + orl %esi, %eax +- andl $(PAGE_SIZE - 1), %eax +- cmpl $(PAGE_SIZE - (VEC_SIZE * 4)), %eax +- jg L(cross_page) +- /* Start comparing 4 vectors. */ ++ /* Shift out the bits irrelivant to page boundary ([63:12]). */ ++ sall $20, %eax ++ /* Check if s1 or s2 may cross a page in next 4x VEC loads. */ ++ cmpl $((PAGE_SIZE -(VEC_SIZE * 4)) << 20), %eax ++ ja L(page_cross) ++ ++L(no_page_cross): ++ /* Safe to compare 4x vectors. */ + VMOVU (%rdi), %YMM0 +- +- /* Each bit set in K2 represents a non-null CHAR in YMM0. */ + VPTESTM %YMM0, %YMM0, %k2 +- + /* Each bit cleared in K1 represents a mismatch or a null CHAR + in YMM0 and 32 bytes at (%rsi). */ + VPCMP $0, (%rsi), %YMM0, %k1{%k2} +- + kmovd %k1, %ecx +-# ifdef USE_AS_WCSCMP +- subl $0xff, %ecx +-# else +- incl %ecx +-# endif +- je L(next_3_vectors) +- tzcntl %ecx, %edx +-# ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %edx +-# endif + # ifdef USE_AS_STRNCMP +- /* Return 0 if the mismatched index (%rdx) is after the maximum +- offset (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) ++ cmpq $CHAR_PER_VEC, %rdx ++ jbe L(vec_0_test_len) + # endif ++ ++ /* TESTEQ is `incl` for strcmp/strncmp and `subl $0xff` for ++ wcscmp/wcsncmp. */ ++ ++ /* All 1s represents all equals. TESTEQ will overflow to zero in ++ all equals case. Otherwise 1s will carry until position of first ++ mismatch. */ ++ TESTEQ %ecx ++ jz L(more_3x_vec) ++ ++ .p2align 4,, 4 ++L(return_vec_0): ++ tzcntl %ecx, %ecx + # ifdef USE_AS_WCSCMP ++ movl (%rdi, %rcx, SIZE_OF_CHAR), %edx + xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- je L(return) +-L(wcscmp_return): ++ cmpl (%rsi, %rcx, SIZE_OF_CHAR), %edx ++ je L(ret0) + setl %al + negl %eax + orl $1, %eax +-L(return): + # else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax ++ movzbl (%rdi, %rcx), %eax ++ movzbl (%rsi, %rcx), %ecx ++ subl %ecx, %eax + # endif ++L(ret0): + ret + +-L(return_vec_size): +- tzcntl %ecx, %edx +-# ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %edx +-# endif + # ifdef USE_AS_STRNCMP +- /* Return 0 if the mismatched index (%rdx + VEC_SIZE) is after +- the maximum offset (%r11). */ +- addq $VEC_SIZE, %rdx +- cmpq %r11, %rdx +- jae L(zero) +-# ifdef USE_AS_WCSCMP ++ .p2align 4,, 4 ++L(vec_0_test_len): ++ notl %ecx ++ bzhil %edx, %ecx, %eax ++ jnz L(return_vec_0) ++ /* Align if will cross fetch block. */ ++ .p2align 4,, 2 ++L(ret_zero): + xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax +-# endif +-# else ++ ret ++ ++ .p2align 4,, 5 ++L(one_or_less): ++ jb L(ret_zero) + # ifdef USE_AS_WCSCMP ++ /* 'nbe' covers the case where length is negative (large ++ unsigned). */ ++ jnbe __wcscmp_evex ++ movl (%rdi), %edx + xorl %eax, %eax +- movl VEC_SIZE(%rdi, %rdx), %ecx +- cmpl VEC_SIZE(%rsi, %rdx), %ecx +- jne L(wcscmp_return) ++ cmpl (%rsi), %edx ++ je L(ret1) ++ setl %al ++ negl %eax ++ orl $1, %eax + # else +- movzbl VEC_SIZE(%rdi, %rdx), %eax +- movzbl VEC_SIZE(%rsi, %rdx), %edx +- subl %edx, %eax ++ /* 'nbe' covers the case where length is negative (large ++ unsigned). */ ++ jnbe __strcmp_evex ++ movzbl (%rdi), %eax ++ movzbl (%rsi), %ecx ++ subl %ecx, %eax + # endif +-# endif ++L(ret1): + ret ++# endif + +-L(return_2_vec_size): +- tzcntl %ecx, %edx ++ .p2align 4,, 10 ++L(return_vec_1): ++ tzcntl %ecx, %ecx ++# ifdef USE_AS_STRNCMP ++ /* rdx must be > CHAR_PER_VEC so its safe to subtract without ++ worrying about underflow. */ ++ addq $-CHAR_PER_VEC, %rdx ++ cmpq %rcx, %rdx ++ jbe L(ret_zero) ++# endif + # ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %edx ++ movl VEC_SIZE(%rdi, %rcx, SIZE_OF_CHAR), %edx ++ xorl %eax, %eax ++ cmpl VEC_SIZE(%rsi, %rcx, SIZE_OF_CHAR), %edx ++ je L(ret2) ++ setl %al ++ negl %eax ++ orl $1, %eax ++# else ++ movzbl VEC_SIZE(%rdi, %rcx), %eax ++ movzbl VEC_SIZE(%rsi, %rcx), %ecx ++ subl %ecx, %eax + # endif ++L(ret2): ++ ret ++ ++ .p2align 4,, 10 + # ifdef USE_AS_STRNCMP +- /* Return 0 if the mismatched index (%rdx + 2 * VEC_SIZE) is +- after the maximum offset (%r11). */ +- addq $(VEC_SIZE * 2), %rdx +- cmpq %r11, %rdx +- jae L(zero) +-# ifdef USE_AS_WCSCMP +- xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- jne L(wcscmp_return) ++L(return_vec_3): ++# if CHAR_PER_VEC <= 16 ++ sall $CHAR_PER_VEC, %ecx + # else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax ++ salq $CHAR_PER_VEC, %rcx + # endif ++# endif ++L(return_vec_2): ++# if (CHAR_PER_VEC <= 16) || !(defined USE_AS_STRNCMP) ++ tzcntl %ecx, %ecx + # else +-# ifdef USE_AS_WCSCMP +- xorl %eax, %eax +- movl (VEC_SIZE * 2)(%rdi, %rdx), %ecx +- cmpl (VEC_SIZE * 2)(%rsi, %rdx), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (VEC_SIZE * 2)(%rdi, %rdx), %eax +- movzbl (VEC_SIZE * 2)(%rsi, %rdx), %edx +- subl %edx, %eax +-# endif ++ tzcntq %rcx, %rcx + # endif +- ret + +-L(return_3_vec_size): +- tzcntl %ecx, %edx +-# ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %edx +-# endif + # ifdef USE_AS_STRNCMP +- /* Return 0 if the mismatched index (%rdx + 3 * VEC_SIZE) is +- after the maximum offset (%r11). */ +- addq $(VEC_SIZE * 3), %rdx +- cmpq %r11, %rdx +- jae L(zero) +-# ifdef USE_AS_WCSCMP ++ cmpq %rcx, %rdx ++ jbe L(ret_zero) ++# endif ++ ++# ifdef USE_AS_WCSCMP ++ movl (VEC_SIZE * 2)(%rdi, %rcx, SIZE_OF_CHAR), %edx + xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax +-# endif ++ cmpl (VEC_SIZE * 2)(%rsi, %rcx, SIZE_OF_CHAR), %edx ++ je L(ret3) ++ setl %al ++ negl %eax ++ orl $1, %eax + # else ++ movzbl (VEC_SIZE * 2)(%rdi, %rcx), %eax ++ movzbl (VEC_SIZE * 2)(%rsi, %rcx), %ecx ++ subl %ecx, %eax ++# endif ++L(ret3): ++ ret ++ ++# ifndef USE_AS_STRNCMP ++ .p2align 4,, 10 ++L(return_vec_3): ++ tzcntl %ecx, %ecx + # ifdef USE_AS_WCSCMP ++ movl (VEC_SIZE * 3)(%rdi, %rcx, SIZE_OF_CHAR), %edx + xorl %eax, %eax +- movl (VEC_SIZE * 3)(%rdi, %rdx), %ecx +- cmpl (VEC_SIZE * 3)(%rsi, %rdx), %ecx +- jne L(wcscmp_return) ++ cmpl (VEC_SIZE * 3)(%rsi, %rcx, SIZE_OF_CHAR), %edx ++ je L(ret4) ++ setl %al ++ negl %eax ++ orl $1, %eax + # else +- movzbl (VEC_SIZE * 3)(%rdi, %rdx), %eax +- movzbl (VEC_SIZE * 3)(%rsi, %rdx), %edx +- subl %edx, %eax ++ movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax ++ movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx ++ subl %ecx, %eax + # endif +-# endif ++L(ret4): + ret ++# endif + +- .p2align 4 +-L(next_3_vectors): +- VMOVU VEC_SIZE(%rdi), %YMM0 +- /* Each bit set in K2 represents a non-null CHAR in YMM0. */ ++ /* 32 byte align here ensures the main loop is ideally aligned ++ for DSB. */ ++ .p2align 5 ++L(more_3x_vec): ++ /* Safe to compare 4x vectors. */ ++ VMOVU (VEC_SIZE)(%rdi), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- /* Each bit cleared in K1 represents a mismatch or a null CHAR +- in YMM0 and 32 bytes at VEC_SIZE(%rsi). */ +- VPCMP $0, VEC_SIZE(%rsi), %YMM0, %k1{%k2} ++ VPCMP $0, (VEC_SIZE)(%rsi), %YMM0, %k1{%k2} + kmovd %k1, %ecx +-# ifdef USE_AS_WCSCMP +- subl $0xff, %ecx +-# else +- incl %ecx ++ TESTEQ %ecx ++ jnz L(return_vec_1) ++ ++# ifdef USE_AS_STRNCMP ++ subq $(CHAR_PER_VEC * 2), %rdx ++ jbe L(ret_zero) + # endif +- jne L(return_vec_size) + + VMOVU (VEC_SIZE * 2)(%rdi), %YMM0 +- /* Each bit set in K2 represents a non-null CHAR in YMM0. */ + VPTESTM %YMM0, %YMM0, %k2 +- /* Each bit cleared in K1 represents a mismatch or a null CHAR +- in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rsi). */ + VPCMP $0, (VEC_SIZE * 2)(%rsi), %YMM0, %k1{%k2} + kmovd %k1, %ecx +-# ifdef USE_AS_WCSCMP +- subl $0xff, %ecx +-# else +- incl %ecx +-# endif +- jne L(return_2_vec_size) ++ TESTEQ %ecx ++ jnz L(return_vec_2) + + VMOVU (VEC_SIZE * 3)(%rdi), %YMM0 +- /* Each bit set in K2 represents a non-null CHAR in YMM0. */ + VPTESTM %YMM0, %YMM0, %k2 +- /* Each bit cleared in K1 represents a mismatch or a null CHAR +- in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rsi). */ + VPCMP $0, (VEC_SIZE * 3)(%rsi), %YMM0, %k1{%k2} + kmovd %k1, %ecx ++ TESTEQ %ecx ++ jnz L(return_vec_3) ++ ++# ifdef USE_AS_STRNCMP ++ cmpq $(CHAR_PER_VEC * 2), %rdx ++ jbe L(ret_zero) ++# endif ++ ++ + # ifdef USE_AS_WCSCMP +- subl $0xff, %ecx ++ /* any non-zero positive value that doesn't inference with 0x1. ++ */ ++ movl $2, %r8d ++ + # else +- incl %ecx ++ xorl %r8d, %r8d + # endif +- jne L(return_3_vec_size) +-L(main_loop_header): +- leaq (VEC_SIZE * 4)(%rdi), %rdx +- movl $PAGE_SIZE, %ecx +- /* Align load via RAX. */ +- andq $-(VEC_SIZE * 4), %rdx +- subq %rdi, %rdx +- leaq (%rdi, %rdx), %rax ++ ++ /* The prepare labels are various entry points from the page ++ cross logic. */ ++L(prepare_loop): ++ + # ifdef USE_AS_STRNCMP +- /* Starting from this point, the maximum offset, or simply the +- 'offset', DECREASES by the same amount when base pointers are +- moved forward. Return 0 when: +- 1) On match: offset <= the matched vector index. +- 2) On mistmach, offset is before the mistmatched index. +- */ +- subq %rdx, %r11 +- jbe L(zero) ++# ifdef USE_AS_WCSCMP ++L(prepare_loop_no_len): ++ movl %edi, %ecx ++ andl $(VEC_SIZE * 4 - 1), %ecx ++ shrl $2, %ecx ++ leaq (CHAR_PER_VEC * 2)(%rdx, %rcx), %rdx ++# else ++ /* Store N + (VEC_SIZE * 4) and place check at the begining of ++ the loop. */ ++ leaq (VEC_SIZE * 2)(%rdi, %rdx), %rdx ++L(prepare_loop_no_len): ++# endif ++# else ++L(prepare_loop_no_len): + # endif +- addq %rsi, %rdx +- movq %rdx, %rsi +- andl $(PAGE_SIZE - 1), %esi +- /* Number of bytes before page crossing. */ +- subq %rsi, %rcx +- /* Number of VEC_SIZE * 4 blocks before page crossing. */ +- shrq $DIVIDE_BY_VEC_4_SHIFT, %rcx +- /* ESI: Number of VEC_SIZE * 4 blocks before page crossing. */ +- movl %ecx, %esi +- jmp L(loop_start) + ++ /* Align s1 and adjust s2 accordingly. */ ++ subq %rdi, %rsi ++ andq $-(VEC_SIZE * 4), %rdi ++L(prepare_loop_readj): ++ addq %rdi, %rsi ++# if (defined USE_AS_STRNCMP) && !(defined USE_AS_WCSCMP) ++ subq %rdi, %rdx ++# endif ++ ++L(prepare_loop_aligned): ++ /* eax stores distance from rsi to next page cross. These cases ++ need to be handled specially as the 4x loop could potentially ++ read memory past the length of s1 or s2 and across a page ++ boundary. */ ++ movl $-(VEC_SIZE * 4), %eax ++ subl %esi, %eax ++ andl $(PAGE_SIZE - 1), %eax ++ ++ vpxorq %YMMZERO, %YMMZERO, %YMMZERO ++ ++ /* Loop 4x comparisons at a time. */ + .p2align 4 + L(loop): ++ ++ /* End condition for strncmp. */ + # ifdef USE_AS_STRNCMP +- /* Base pointers are moved forward by 4 * VEC_SIZE. Decrease +- the maximum offset (%r11) by the same amount. */ +- subq $(VEC_SIZE * 4), %r11 +- jbe L(zero) ++ subq $(CHAR_PER_VEC * 4), %rdx ++ jbe L(ret_zero) + # endif +- addq $(VEC_SIZE * 4), %rax +- addq $(VEC_SIZE * 4), %rdx +-L(loop_start): +- testl %esi, %esi +- leal -1(%esi), %esi +- je L(loop_cross_page) +-L(back_to_loop): +- /* Main loop, comparing 4 vectors are a time. */ +- VMOVA (%rax), %YMM0 +- VMOVA VEC_SIZE(%rax), %YMM2 +- VMOVA (VEC_SIZE * 2)(%rax), %YMM4 +- VMOVA (VEC_SIZE * 3)(%rax), %YMM6 ++ ++ subq $-(VEC_SIZE * 4), %rdi ++ subq $-(VEC_SIZE * 4), %rsi ++ ++ /* Check if rsi loads will cross a page boundary. */ ++ addl $-(VEC_SIZE * 4), %eax ++ jnb L(page_cross_during_loop) ++ ++ /* Loop entry after handling page cross during loop. */ ++L(loop_skip_page_cross_check): ++ VMOVA (VEC_SIZE * 0)(%rdi), %YMM0 ++ VMOVA (VEC_SIZE * 1)(%rdi), %YMM2 ++ VMOVA (VEC_SIZE * 2)(%rdi), %YMM4 ++ VMOVA (VEC_SIZE * 3)(%rdi), %YMM6 + + VPMINU %YMM0, %YMM2, %YMM8 + VPMINU %YMM4, %YMM6, %YMM9 + +- /* A zero CHAR in YMM8 means that there is a null CHAR. */ +- VPMINU %YMM8, %YMM9, %YMM8 ++ /* A zero CHAR in YMM9 means that there is a null CHAR. */ ++ VPMINU %YMM8, %YMM9, %YMM9 + + /* Each bit set in K1 represents a non-null CHAR in YMM8. */ +- VPTESTM %YMM8, %YMM8, %k1 ++ VPTESTM %YMM9, %YMM9, %k1 + +- /* (YMM ^ YMM): A non-zero CHAR represents a mismatch. */ +- vpxorq (%rdx), %YMM0, %YMM1 +- vpxorq VEC_SIZE(%rdx), %YMM2, %YMM3 +- vpxorq (VEC_SIZE * 2)(%rdx), %YMM4, %YMM5 +- vpxorq (VEC_SIZE * 3)(%rdx), %YMM6, %YMM7 ++ vpxorq (VEC_SIZE * 0)(%rsi), %YMM0, %YMM1 ++ vpxorq (VEC_SIZE * 1)(%rsi), %YMM2, %YMM3 ++ vpxorq (VEC_SIZE * 2)(%rsi), %YMM4, %YMM5 ++ /* Ternary logic to xor (VEC_SIZE * 3)(%rsi) with YMM6 while ++ oring with YMM1. Result is stored in YMM6. */ ++ vpternlogd $0xde, (VEC_SIZE * 3)(%rsi), %YMM1, %YMM6 + +- vporq %YMM1, %YMM3, %YMM9 +- vporq %YMM5, %YMM7, %YMM10 ++ /* Or together YMM3, YMM5, and YMM6. */ ++ vpternlogd $0xfe, %YMM3, %YMM5, %YMM6 + +- /* A non-zero CHAR in YMM9 represents a mismatch. */ +- vporq %YMM9, %YMM10, %YMM9 + +- /* Each bit cleared in K0 represents a mismatch or a null CHAR. */ +- VPCMP $0, %YMMZERO, %YMM9, %k0{%k1} +- kmovd %k0, %ecx +-# ifdef USE_AS_WCSCMP +- subl $0xff, %ecx +-# else +- incl %ecx +-# endif +- je L(loop) ++ /* A non-zero CHAR in YMM6 represents a mismatch. */ ++ VPCMP $0, %YMMZERO, %YMM6, %k0{%k1} ++ kmovd %k0, %LOOP_REG + +- /* Each bit set in K1 represents a non-null CHAR in YMM0. */ ++ TESTEQ %LOOP_REG ++ jz L(loop) ++ ++ ++ /* Find which VEC has the mismatch of end of string. */ + VPTESTM %YMM0, %YMM0, %k1 +- /* Each bit cleared in K0 represents a mismatch or a null CHAR +- in YMM0 and (%rdx). */ + VPCMP $0, %YMMZERO, %YMM1, %k0{%k1} + kmovd %k0, %ecx +-# ifdef USE_AS_WCSCMP +- subl $0xff, %ecx +-# else +- incl %ecx +-# endif +- je L(test_vec) +- tzcntl %ecx, %ecx +-# ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %ecx +-# endif +-# ifdef USE_AS_STRNCMP +- cmpq %rcx, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif +-# else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif +-# endif +- ret ++ TESTEQ %ecx ++ jnz L(return_vec_0_end) + +- .p2align 4 +-L(test_vec): +-# ifdef USE_AS_STRNCMP +- /* The first vector matched. Return 0 if the maximum offset +- (%r11) <= VEC_SIZE. */ +- cmpq $VEC_SIZE, %r11 +- jbe L(zero) +-# endif +- /* Each bit set in K1 represents a non-null CHAR in YMM2. */ + VPTESTM %YMM2, %YMM2, %k1 +- /* Each bit cleared in K0 represents a mismatch or a null CHAR +- in YMM2 and VEC_SIZE(%rdx). */ + VPCMP $0, %YMMZERO, %YMM3, %k0{%k1} + kmovd %k0, %ecx +-# ifdef USE_AS_WCSCMP +- subl $0xff, %ecx +-# else +- incl %ecx +-# endif +- je L(test_2_vec) +- tzcntl %ecx, %edi +-# ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %edi +-# endif +-# ifdef USE_AS_STRNCMP +- addq $VEC_SIZE, %rdi +- cmpq %rdi, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (%rsi, %rdi), %ecx +- cmpl (%rdx, %rdi), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rdi), %eax +- movzbl (%rdx, %rdi), %edx +- subl %edx, %eax +-# endif +-# else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl VEC_SIZE(%rsi, %rdi), %ecx +- cmpl VEC_SIZE(%rdx, %rdi), %ecx +- jne L(wcscmp_return) +-# else +- movzbl VEC_SIZE(%rax, %rdi), %eax +- movzbl VEC_SIZE(%rdx, %rdi), %edx +- subl %edx, %eax +-# endif +-# endif +- ret ++ TESTEQ %ecx ++ jnz L(return_vec_1_end) + +- .p2align 4 +-L(test_2_vec): ++ ++ /* Handle VEC 2 and 3 without branches. */ ++L(return_vec_2_3_end): + # ifdef USE_AS_STRNCMP +- /* The first 2 vectors matched. Return 0 if the maximum offset +- (%r11) <= 2 * VEC_SIZE. */ +- cmpq $(VEC_SIZE * 2), %r11 +- jbe L(zero) ++ subq $(CHAR_PER_VEC * 2), %rdx ++ jbe L(ret_zero_end) + # endif +- /* Each bit set in K1 represents a non-null CHAR in YMM4. */ ++ + VPTESTM %YMM4, %YMM4, %k1 +- /* Each bit cleared in K0 represents a mismatch or a null CHAR +- in YMM4 and (VEC_SIZE * 2)(%rdx). */ + VPCMP $0, %YMMZERO, %YMM5, %k0{%k1} + kmovd %k0, %ecx +-# ifdef USE_AS_WCSCMP +- subl $0xff, %ecx ++ TESTEQ %ecx ++# if CHAR_PER_VEC <= 16 ++ sall $CHAR_PER_VEC, %LOOP_REG ++ orl %ecx, %LOOP_REG + # else +- incl %ecx ++ salq $CHAR_PER_VEC, %LOOP_REG64 ++ orq %rcx, %LOOP_REG64 ++# endif ++L(return_vec_3_end): ++ /* LOOP_REG contains matches for null/mismatch from the loop. If ++ VEC 0,1,and 2 all have no null and no mismatches then mismatch ++ must entirely be from VEC 3 which is fully represented by ++ LOOP_REG. */ ++# if CHAR_PER_VEC <= 16 ++ tzcntl %LOOP_REG, %LOOP_REG ++# else ++ tzcntq %LOOP_REG64, %LOOP_REG64 ++# endif ++# ifdef USE_AS_STRNCMP ++ cmpq %LOOP_REG64, %rdx ++ jbe L(ret_zero_end) + # endif +- je L(test_3_vec) +- tzcntl %ecx, %edi ++ + # ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %edi ++ movl (VEC_SIZE * 2)(%rdi, %LOOP_REG64, SIZE_OF_CHAR), %ecx ++ xorl %eax, %eax ++ cmpl (VEC_SIZE * 2)(%rsi, %LOOP_REG64, SIZE_OF_CHAR), %ecx ++ je L(ret5) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax ++# else ++ movzbl (VEC_SIZE * 2)(%rdi, %LOOP_REG64), %eax ++ movzbl (VEC_SIZE * 2)(%rsi, %LOOP_REG64), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif ++L(ret5): ++ ret ++ + # ifdef USE_AS_STRNCMP +- addq $(VEC_SIZE * 2), %rdi +- cmpq %rdi, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++ .p2align 4,, 2 ++L(ret_zero_end): + xorl %eax, %eax +- movl (%rsi, %rdi), %ecx +- cmpl (%rdx, %rdi), %ecx +- jne L(wcscmp_return) ++ ret ++# endif ++ ++ ++ /* The L(return_vec_N_end) differ from L(return_vec_N) in that ++ they use the value of `r8` to negate the return value. This is ++ because the page cross logic can swap `rdi` and `rsi`. */ ++ .p2align 4,, 10 ++# ifdef USE_AS_STRNCMP ++L(return_vec_1_end): ++# if CHAR_PER_VEC <= 16 ++ sall $CHAR_PER_VEC, %ecx + # else +- movzbl (%rax, %rdi), %eax +- movzbl (%rdx, %rdi), %edx +- subl %edx, %eax ++ salq $CHAR_PER_VEC, %rcx + # endif ++# endif ++L(return_vec_0_end): ++# if (CHAR_PER_VEC <= 16) || !(defined USE_AS_STRNCMP) ++ tzcntl %ecx, %ecx + # else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (VEC_SIZE * 2)(%rsi, %rdi), %ecx +- cmpl (VEC_SIZE * 2)(%rdx, %rdi), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (VEC_SIZE * 2)(%rax, %rdi), %eax +- movzbl (VEC_SIZE * 2)(%rdx, %rdi), %edx +- subl %edx, %eax +-# endif ++ tzcntq %rcx, %rcx + # endif +- ret + +- .p2align 4 +-L(test_3_vec): + # ifdef USE_AS_STRNCMP +- /* The first 3 vectors matched. Return 0 if the maximum offset +- (%r11) <= 3 * VEC_SIZE. */ +- cmpq $(VEC_SIZE * 3), %r11 +- jbe L(zero) ++ cmpq %rcx, %rdx ++ jbe L(ret_zero_end) + # endif +- /* Each bit set in K1 represents a non-null CHAR in YMM6. */ +- VPTESTM %YMM6, %YMM6, %k1 +- /* Each bit cleared in K0 represents a mismatch or a null CHAR +- in YMM6 and (VEC_SIZE * 3)(%rdx). */ +- VPCMP $0, %YMMZERO, %YMM7, %k0{%k1} +- kmovd %k0, %ecx ++ + # ifdef USE_AS_WCSCMP +- subl $0xff, %ecx ++ movl (%rdi, %rcx, SIZE_OF_CHAR), %edx ++ xorl %eax, %eax ++ cmpl (%rsi, %rcx, SIZE_OF_CHAR), %edx ++ je L(ret6) ++ setl %al ++ negl %eax ++ /* This is the non-zero case for `eax` so just xorl with `r8d` ++ flip is `rdi` and `rsi` where swapped. */ ++ xorl %r8d, %eax + # else +- incl %ecx ++ movzbl (%rdi, %rcx), %eax ++ movzbl (%rsi, %rcx), %ecx ++ subl %ecx, %eax ++ /* Flip `eax` if `rdi` and `rsi` where swapped in page cross ++ logic. Subtract `r8d` after xor for zero case. */ ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif ++L(ret6): ++ ret ++ ++# ifndef USE_AS_STRNCMP ++ .p2align 4,, 10 ++L(return_vec_1_end): + tzcntl %ecx, %ecx +-# ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %ecx +-# endif +-# ifdef USE_AS_STRNCMP +- addq $(VEC_SIZE * 3), %rcx +- cmpq %rcx, %r11 +- jbe L(zero) + # ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++ movl VEC_SIZE(%rdi, %rcx, SIZE_OF_CHAR), %edx + xorl %eax, %eax +- movl (%rsi, %rcx), %esi +- cmpl (%rdx, %rcx), %esi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif +-# else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (VEC_SIZE * 3)(%rsi, %rcx), %esi +- cmpl (VEC_SIZE * 3)(%rdx, %rcx), %esi +- jne L(wcscmp_return) ++ cmpl VEC_SIZE(%rsi, %rcx, SIZE_OF_CHAR), %edx ++ je L(ret7) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax + # else +- movzbl (VEC_SIZE * 3)(%rax, %rcx), %eax +- movzbl (VEC_SIZE * 3)(%rdx, %rcx), %edx +- subl %edx, %eax ++ movzbl VEC_SIZE(%rdi, %rcx), %eax ++ movzbl VEC_SIZE(%rsi, %rcx), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif +-# endif ++L(ret7): + ret +- +- .p2align 4 +-L(loop_cross_page): +- xorl %r10d, %r10d +- movq %rdx, %rcx +- /* Align load via RDX. We load the extra ECX bytes which should +- be ignored. */ +- andl $((VEC_SIZE * 4) - 1), %ecx +- /* R10 is -RCX. */ +- subq %rcx, %r10 +- +- /* This works only if VEC_SIZE * 2 == 64. */ +-# if (VEC_SIZE * 2) != 64 +-# error (VEC_SIZE * 2) != 64 + # endif + +- /* Check if the first VEC_SIZE * 2 bytes should be ignored. */ +- cmpl $(VEC_SIZE * 2), %ecx +- jge L(loop_cross_page_2_vec) + +- VMOVU (%rax, %r10), %YMM2 +- VMOVU VEC_SIZE(%rax, %r10), %YMM3 ++ /* Page cross in rsi in next 4x VEC. */ + +- /* Each bit set in K2 represents a non-null CHAR in YMM2. */ +- VPTESTM %YMM2, %YMM2, %k2 +- /* Each bit cleared in K1 represents a mismatch or a null CHAR +- in YMM2 and 32 bytes at (%rdx, %r10). */ +- VPCMP $0, (%rdx, %r10), %YMM2, %k1{%k2} +- kmovd %k1, %r9d +- /* Don't use subl since it is the lower 16/32 bits of RDI +- below. */ +- notl %r9d +-# ifdef USE_AS_WCSCMP +- /* Only last 8 bits are valid. */ +- andl $0xff, %r9d +-# endif ++ /* TODO: Improve logic here. */ ++ .p2align 4,, 10 ++L(page_cross_during_loop): ++ /* eax contains [distance_from_page - (VEC_SIZE * 4)]. */ + +- /* Each bit set in K4 represents a non-null CHAR in YMM3. */ +- VPTESTM %YMM3, %YMM3, %k4 +- /* Each bit cleared in K3 represents a mismatch or a null CHAR +- in YMM3 and 32 bytes at VEC_SIZE(%rdx, %r10). */ +- VPCMP $0, VEC_SIZE(%rdx, %r10), %YMM3, %k3{%k4} +- kmovd %k3, %edi +- /* Must use notl %edi here as lower bits are for CHAR +- comparisons potentially out of range thus can be 0 without +- indicating mismatch. */ +- notl %edi +-# ifdef USE_AS_WCSCMP +- /* Don't use subl since it is the upper 8 bits of EDI below. */ +- andl $0xff, %edi +-# endif ++ /* Optimistically rsi and rdi and both aligned in which case we ++ don't need any logic here. */ ++ cmpl $-(VEC_SIZE * 4), %eax ++ /* Don't adjust eax before jumping back to loop and we will ++ never hit page cross case again. */ ++ je L(loop_skip_page_cross_check) + +-# ifdef USE_AS_WCSCMP +- /* NB: Each bit in EDI/R9D represents 4-byte element. */ +- sall $8, %edi +- /* NB: Divide shift count by 4 since each bit in K1 represent 4 +- bytes. */ +- movl %ecx, %SHIFT_REG32 +- sarl $2, %SHIFT_REG32 +- +- /* Each bit in EDI represents a null CHAR or a mismatch. */ +- orl %r9d, %edi +-# else +- salq $32, %rdi ++ /* Check if we can safely load a VEC. */ ++ cmpl $-(VEC_SIZE * 3), %eax ++ jle L(less_1x_vec_till_page_cross) + +- /* Each bit in RDI represents a null CHAR or a mismatch. */ +- orq %r9, %rdi +-# endif ++ VMOVA (%rdi), %YMM0 ++ VPTESTM %YMM0, %YMM0, %k2 ++ VPCMP $0, (%rsi), %YMM0, %k1{%k2} ++ kmovd %k1, %ecx ++ TESTEQ %ecx ++ jnz L(return_vec_0_end) ++ ++ /* if distance >= 2x VEC then eax > -(VEC_SIZE * 2). */ ++ cmpl $-(VEC_SIZE * 2), %eax ++ jg L(more_2x_vec_till_page_cross) ++ ++ .p2align 4,, 4 ++L(less_1x_vec_till_page_cross): ++ subl $-(VEC_SIZE * 4), %eax ++ /* Guranteed safe to read from rdi - VEC_SIZE here. The only ++ concerning case is first iteration if incoming s1 was near start ++ of a page and s2 near end. If s1 was near the start of the page ++ we already aligned up to nearest VEC_SIZE * 4 so gurnateed safe ++ to read back -VEC_SIZE. If rdi is truly at the start of a page ++ here, it means the previous page (rdi - VEC_SIZE) has already ++ been loaded earlier so must be valid. */ ++ VMOVU -VEC_SIZE(%rdi, %rax), %YMM0 ++ VPTESTM %YMM0, %YMM0, %k2 ++ VPCMP $0, -VEC_SIZE(%rsi, %rax), %YMM0, %k1{%k2} ++ ++ /* Mask of potentially valid bits. The lower bits can be out of ++ range comparisons (but safe regarding page crosses). */ + +- /* Since ECX < VEC_SIZE * 2, simply skip the first ECX bytes. */ +- shrxq %SHIFT_REG64, %rdi, %rdi +- testq %rdi, %rdi +- je L(loop_cross_page_2_vec) +- tzcntq %rdi, %rcx + # ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %ecx ++ movl $-1, %r10d ++ movl %esi, %ecx ++ andl $(VEC_SIZE - 1), %ecx ++ shrl $2, %ecx ++ shlxl %ecx, %r10d, %ecx ++ movzbl %cl, %r10d ++# else ++ movl $-1, %ecx ++ shlxl %esi, %ecx, %r10d + # endif ++ ++ kmovd %k1, %ecx ++ notl %ecx ++ ++ + # ifdef USE_AS_STRNCMP +- cmpq %rcx, %r11 +- jbe L(zero) + # ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) ++ movl %eax, %r11d ++ shrl $2, %r11d ++ cmpq %r11, %rdx + # else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax ++ cmpq %rax, %rdx + # endif ++ jbe L(return_page_cross_end_check) ++# endif ++ movl %eax, %OFFSET_REG ++ ++ /* Readjust eax before potentially returning to the loop. */ ++ addl $(PAGE_SIZE - VEC_SIZE * 4), %eax ++ ++ andl %r10d, %ecx ++ jz L(loop_skip_page_cross_check) ++ ++ .p2align 4,, 3 ++L(return_page_cross_end): ++ tzcntl %ecx, %ecx ++ ++# if (defined USE_AS_STRNCMP) || (defined USE_AS_WCSCMP) ++ leal -VEC_SIZE(%OFFSET_REG64, %rcx, SIZE_OF_CHAR), %ecx ++L(return_page_cross_cmp_mem): + # else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++ addl %OFFSET_REG, %ecx ++# endif ++# ifdef USE_AS_WCSCMP ++ movl VEC_OFFSET(%rdi, %rcx), %edx + xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif ++ cmpl VEC_OFFSET(%rsi, %rcx), %edx ++ je L(ret8) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax ++# else ++ movzbl VEC_OFFSET(%rdi, %rcx), %eax ++ movzbl VEC_OFFSET(%rsi, %rcx), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif ++L(ret8): + ret + +- .p2align 4 +-L(loop_cross_page_2_vec): +- /* The first VEC_SIZE * 2 bytes match or are ignored. */ +- VMOVU (VEC_SIZE * 2)(%rax, %r10), %YMM0 +- VMOVU (VEC_SIZE * 3)(%rax, %r10), %YMM1 ++# ifdef USE_AS_STRNCMP ++ .p2align 4,, 10 ++L(return_page_cross_end_check): ++ tzcntl %ecx, %ecx ++ leal -VEC_SIZE(%rax, %rcx, SIZE_OF_CHAR), %ecx ++# ifdef USE_AS_WCSCMP ++ sall $2, %edx ++# endif ++ cmpl %ecx, %edx ++ ja L(return_page_cross_cmp_mem) ++ xorl %eax, %eax ++ ret ++# endif ++ + ++ .p2align 4,, 10 ++L(more_2x_vec_till_page_cross): ++ /* If more 2x vec till cross we will complete a full loop ++ iteration here. */ ++ ++ VMOVA VEC_SIZE(%rdi), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- /* Each bit cleared in K1 represents a mismatch or a null CHAR +- in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rdx, %r10). */ +- VPCMP $0, (VEC_SIZE * 2)(%rdx, %r10), %YMM0, %k1{%k2} +- kmovd %k1, %r9d +- /* Don't use subl since it is the lower 16/32 bits of RDI +- below. */ +- notl %r9d +-# ifdef USE_AS_WCSCMP +- /* Only last 8 bits are valid. */ +- andl $0xff, %r9d +-# endif ++ VPCMP $0, VEC_SIZE(%rsi), %YMM0, %k1{%k2} ++ kmovd %k1, %ecx ++ TESTEQ %ecx ++ jnz L(return_vec_1_end) + +- VPTESTM %YMM1, %YMM1, %k4 +- /* Each bit cleared in K3 represents a mismatch or a null CHAR +- in YMM1 and 32 bytes at (VEC_SIZE * 3)(%rdx, %r10). */ +- VPCMP $0, (VEC_SIZE * 3)(%rdx, %r10), %YMM1, %k3{%k4} +- kmovd %k3, %edi +- /* Must use notl %edi here as lower bits are for CHAR +- comparisons potentially out of range thus can be 0 without +- indicating mismatch. */ +- notl %edi +-# ifdef USE_AS_WCSCMP +- /* Don't use subl since it is the upper 8 bits of EDI below. */ +- andl $0xff, %edi ++# ifdef USE_AS_STRNCMP ++ cmpq $(CHAR_PER_VEC * 2), %rdx ++ jbe L(ret_zero_in_loop_page_cross) + # endif + +-# ifdef USE_AS_WCSCMP +- /* NB: Each bit in EDI/R9D represents 4-byte element. */ +- sall $8, %edi ++ subl $-(VEC_SIZE * 4), %eax + +- /* Each bit in EDI represents a null CHAR or a mismatch. */ +- orl %r9d, %edi +-# else +- salq $32, %rdi ++ /* Safe to include comparisons from lower bytes. */ ++ VMOVU -(VEC_SIZE * 2)(%rdi, %rax), %YMM0 ++ VPTESTM %YMM0, %YMM0, %k2 ++ VPCMP $0, -(VEC_SIZE * 2)(%rsi, %rax), %YMM0, %k1{%k2} ++ kmovd %k1, %ecx ++ TESTEQ %ecx ++ jnz L(return_vec_page_cross_0) ++ ++ VMOVU -(VEC_SIZE * 1)(%rdi, %rax), %YMM0 ++ VPTESTM %YMM0, %YMM0, %k2 ++ VPCMP $0, -(VEC_SIZE * 1)(%rsi, %rax), %YMM0, %k1{%k2} ++ kmovd %k1, %ecx ++ TESTEQ %ecx ++ jnz L(return_vec_page_cross_1) + +- /* Each bit in RDI represents a null CHAR or a mismatch. */ +- orq %r9, %rdi ++# ifdef USE_AS_STRNCMP ++ /* Must check length here as length might proclude reading next ++ page. */ ++# ifdef USE_AS_WCSCMP ++ movl %eax, %r11d ++ shrl $2, %r11d ++ cmpq %r11, %rdx ++# else ++ cmpq %rax, %rdx ++# endif ++ jbe L(ret_zero_in_loop_page_cross) + # endif + +- xorl %r8d, %r8d +- /* If ECX > VEC_SIZE * 2, skip ECX - (VEC_SIZE * 2) bytes. */ +- subl $(VEC_SIZE * 2), %ecx +- jle 1f +- /* R8 has number of bytes skipped. */ +- movl %ecx, %r8d +-# ifdef USE_AS_WCSCMP +- /* NB: Divide shift count by 4 since each bit in RDI represent 4 +- bytes. */ +- sarl $2, %ecx +- /* Skip ECX bytes. */ +- shrl %cl, %edi ++ /* Finish the loop. */ ++ VMOVA (VEC_SIZE * 2)(%rdi), %YMM4 ++ VMOVA (VEC_SIZE * 3)(%rdi), %YMM6 ++ VPMINU %YMM4, %YMM6, %YMM9 ++ VPTESTM %YMM9, %YMM9, %k1 ++ ++ vpxorq (VEC_SIZE * 2)(%rsi), %YMM4, %YMM5 ++ /* YMM6 = YMM5 | ((VEC_SIZE * 3)(%rsi) ^ YMM6). */ ++ vpternlogd $0xde, (VEC_SIZE * 3)(%rsi), %YMM5, %YMM6 ++ ++ VPCMP $0, %YMMZERO, %YMM6, %k0{%k1} ++ kmovd %k0, %LOOP_REG ++ TESTEQ %LOOP_REG ++ jnz L(return_vec_2_3_end) ++ ++ /* Best for code size to include ucond-jmp here. Would be faster ++ if this case is hot to duplicate the L(return_vec_2_3_end) code ++ as fall-through and have jump back to loop on mismatch ++ comparison. */ ++ subq $-(VEC_SIZE * 4), %rdi ++ subq $-(VEC_SIZE * 4), %rsi ++ addl $(PAGE_SIZE - VEC_SIZE * 8), %eax ++# ifdef USE_AS_STRNCMP ++ subq $(CHAR_PER_VEC * 4), %rdx ++ ja L(loop_skip_page_cross_check) ++L(ret_zero_in_loop_page_cross): ++ xorl %eax, %eax ++ ret + # else +- /* Skip ECX bytes. */ +- shrq %cl, %rdi ++ jmp L(loop_skip_page_cross_check) + # endif +-1: +- /* Before jumping back to the loop, set ESI to the number of +- VEC_SIZE * 4 blocks before page crossing. */ +- movl $(PAGE_SIZE / (VEC_SIZE * 4) - 1), %esi + +- testq %rdi, %rdi +-# ifdef USE_AS_STRNCMP +- /* At this point, if %rdi value is 0, it already tested +- VEC_SIZE*4+%r10 byte starting from %rax. This label +- checks whether strncmp maximum offset reached or not. */ +- je L(string_nbyte_offset_check) ++ ++ .p2align 4,, 10 ++L(return_vec_page_cross_0): ++ addl $-VEC_SIZE, %eax ++L(return_vec_page_cross_1): ++ tzcntl %ecx, %ecx ++# if defined USE_AS_STRNCMP || defined USE_AS_WCSCMP ++ leal -VEC_SIZE(%rax, %rcx, SIZE_OF_CHAR), %ecx ++# ifdef USE_AS_STRNCMP ++# ifdef USE_AS_WCSCMP ++ /* Must divide ecx instead of multiply rdx due to overflow. */ ++ movl %ecx, %eax ++ shrl $2, %eax ++ cmpq %rax, %rdx ++# else ++ cmpq %rcx, %rdx ++# endif ++ jbe L(ret_zero_in_loop_page_cross) ++# endif + # else +- je L(back_to_loop) ++ addl %eax, %ecx + # endif +- tzcntq %rdi, %rcx ++ + # ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %ecx +-# endif +- addq %r10, %rcx +- /* Adjust for number of bytes skipped. */ +- addq %r8, %rcx +-# ifdef USE_AS_STRNCMP +- addq $(VEC_SIZE * 2), %rcx +- subq %rcx, %r11 +- jbe L(zero) +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi ++ movl VEC_OFFSET(%rdi, %rcx), %edx + xorl %eax, %eax +- movl (%rsi, %rcx), %edi +- cmpl (%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (%rax, %rcx), %eax +- movzbl (%rdx, %rcx), %edx +- subl %edx, %eax +-# endif ++ cmpl VEC_OFFSET(%rsi, %rcx), %edx ++ je L(ret9) ++ setl %al ++ negl %eax ++ xorl %r8d, %eax + # else +-# ifdef USE_AS_WCSCMP +- movq %rax, %rsi +- xorl %eax, %eax +- movl (VEC_SIZE * 2)(%rsi, %rcx), %edi +- cmpl (VEC_SIZE * 2)(%rdx, %rcx), %edi +- jne L(wcscmp_return) +-# else +- movzbl (VEC_SIZE * 2)(%rax, %rcx), %eax +- movzbl (VEC_SIZE * 2)(%rdx, %rcx), %edx +- subl %edx, %eax +-# endif ++ movzbl VEC_OFFSET(%rdi, %rcx), %eax ++ movzbl VEC_OFFSET(%rsi, %rcx), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif ++L(ret9): + ret + +-# ifdef USE_AS_STRNCMP +-L(string_nbyte_offset_check): +- leaq (VEC_SIZE * 4)(%r10), %r10 +- cmpq %r10, %r11 +- jbe L(zero) +- jmp L(back_to_loop) ++ ++ .p2align 4,, 10 ++L(page_cross): ++# ifndef USE_AS_STRNCMP ++ /* If both are VEC aligned we don't need any special logic here. ++ Only valid for strcmp where stop condition is guranteed to be ++ reachable by just reading memory. */ ++ testl $((VEC_SIZE - 1) << 20), %eax ++ jz L(no_page_cross) + # endif + +- .p2align 4 +-L(cross_page_loop): +- /* Check one byte/dword at a time. */ ++ movl %edi, %eax ++ movl %esi, %ecx ++ andl $(PAGE_SIZE - 1), %eax ++ andl $(PAGE_SIZE - 1), %ecx ++ ++ xorl %OFFSET_REG, %OFFSET_REG ++ ++ /* Check which is closer to page cross, s1 or s2. */ ++ cmpl %eax, %ecx ++ jg L(page_cross_s2) ++ ++ /* The previous page cross check has false positives. Check for ++ true positive as page cross logic is very expensive. */ ++ subl $(PAGE_SIZE - VEC_SIZE * 4), %eax ++ jbe L(no_page_cross) ++ ++ ++ /* Set r8 to not interfere with normal return value (rdi and rsi ++ did not swap). */ + # ifdef USE_AS_WCSCMP +- cmpl %ecx, %eax ++ /* any non-zero positive value that doesn't inference with 0x1. ++ */ ++ movl $2, %r8d + # else +- subl %ecx, %eax ++ xorl %r8d, %r8d + # endif +- jne L(different) +- addl $SIZE_OF_CHAR, %edx +- cmpl $(VEC_SIZE * 4), %edx +- je L(main_loop_header) ++ ++ /* Check if less than 1x VEC till page cross. */ ++ subl $(VEC_SIZE * 3), %eax ++ jg L(less_1x_vec_till_page) ++ ++ ++ /* If more than 1x VEC till page cross, loop throuh safely ++ loadable memory until within 1x VEC of page cross. */ ++ .p2align 4,, 8 ++L(page_cross_loop): ++ VMOVU (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM0 ++ VPTESTM %YMM0, %YMM0, %k2 ++ VPCMP $0, (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM0, %k1{%k2} ++ kmovd %k1, %ecx ++ TESTEQ %ecx ++ jnz L(check_ret_vec_page_cross) ++ addl $CHAR_PER_VEC, %OFFSET_REG + # ifdef USE_AS_STRNCMP +- cmpq %r11, %rdx +- jae L(zero) ++ cmpq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross) + # endif ++ addl $VEC_SIZE, %eax ++ jl L(page_cross_loop) ++ + # ifdef USE_AS_WCSCMP +- movl (%rdi, %rdx), %eax +- movl (%rsi, %rdx), %ecx +-# else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %ecx ++ shrl $2, %eax + # endif +- /* Check null CHAR. */ +- testl %eax, %eax +- jne L(cross_page_loop) +- /* Since %eax == 0, subtract is OK for both SIGNED and UNSIGNED +- comparisons. */ +- subl %ecx, %eax +-# ifndef USE_AS_WCSCMP +-L(different): ++ ++ ++ subl %eax, %OFFSET_REG ++ /* OFFSET_REG has distance to page cross - VEC_SIZE. Guranteed ++ to not cross page so is safe to load. Since we have already ++ loaded at least 1 VEC from rsi it is also guranteed to be safe. ++ */ ++ VMOVU (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM0 ++ VPTESTM %YMM0, %YMM0, %k2 ++ VPCMP $0, (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM0, %k1{%k2} ++ ++ kmovd %k1, %ecx ++# ifdef USE_AS_STRNCMP ++ leal CHAR_PER_VEC(%OFFSET_REG64), %eax ++ cmpq %rax, %rdx ++ jbe L(check_ret_vec_page_cross2) ++# ifdef USE_AS_WCSCMP ++ addq $-(CHAR_PER_VEC * 2), %rdx ++# else ++ addq %rdi, %rdx ++# endif + # endif +- ret ++ TESTEQ %ecx ++ jz L(prepare_loop_no_len) + ++ .p2align 4,, 4 ++L(ret_vec_page_cross): ++# ifndef USE_AS_STRNCMP ++L(check_ret_vec_page_cross): ++# endif ++ tzcntl %ecx, %ecx ++ addl %OFFSET_REG, %ecx ++L(ret_vec_page_cross_cont): + # ifdef USE_AS_WCSCMP +- .p2align 4 +-L(different): +- /* Use movl to avoid modifying EFLAGS. */ +- movl $0, %eax ++ movl (%rdi, %rcx, SIZE_OF_CHAR), %edx ++ xorl %eax, %eax ++ cmpl (%rsi, %rcx, SIZE_OF_CHAR), %edx ++ je L(ret12) + setl %al + negl %eax +- orl $1, %eax +- ret ++ xorl %r8d, %eax ++# else ++ movzbl (%rdi, %rcx, SIZE_OF_CHAR), %eax ++ movzbl (%rsi, %rcx, SIZE_OF_CHAR), %ecx ++ subl %ecx, %eax ++ xorl %r8d, %eax ++ subl %r8d, %eax + # endif ++L(ret12): ++ ret ++ + + # ifdef USE_AS_STRNCMP +- .p2align 4 +-L(zero): ++ .p2align 4,, 10 ++L(check_ret_vec_page_cross2): ++ TESTEQ %ecx ++L(check_ret_vec_page_cross): ++ tzcntl %ecx, %ecx ++ addl %OFFSET_REG, %ecx ++ cmpq %rcx, %rdx ++ ja L(ret_vec_page_cross_cont) ++ .p2align 4,, 2 ++L(ret_zero_page_cross): + xorl %eax, %eax + ret ++# endif + +- .p2align 4 +-L(char0): +-# ifdef USE_AS_WCSCMP +- xorl %eax, %eax +- movl (%rdi), %ecx +- cmpl (%rsi), %ecx +- jne L(wcscmp_return) +-# else +- movzbl (%rsi), %ecx +- movzbl (%rdi), %eax +- subl %ecx, %eax +-# endif +- ret ++ .p2align 4,, 4 ++L(page_cross_s2): ++ /* Ensure this is a true page cross. */ ++ subl $(PAGE_SIZE - VEC_SIZE * 4), %ecx ++ jbe L(no_page_cross) ++ ++ ++ movl %ecx, %eax ++ movq %rdi, %rcx ++ movq %rsi, %rdi ++ movq %rcx, %rsi ++ ++ /* set r8 to negate return value as rdi and rsi swapped. */ ++# ifdef USE_AS_WCSCMP ++ movl $-4, %r8d ++# else ++ movl $-1, %r8d + # endif ++ xorl %OFFSET_REG, %OFFSET_REG + +- .p2align 4 +-L(last_vector): +- addq %rdx, %rdi +- addq %rdx, %rsi +-# ifdef USE_AS_STRNCMP +- subq %rdx, %r11 ++ /* Check if more than 1x VEC till page cross. */ ++ subl $(VEC_SIZE * 3), %eax ++ jle L(page_cross_loop) ++ ++ .p2align 4,, 6 ++L(less_1x_vec_till_page): ++# ifdef USE_AS_WCSCMP ++ shrl $2, %eax + # endif +- tzcntl %ecx, %edx ++ /* Find largest load size we can use. */ ++ cmpl $(16 / SIZE_OF_CHAR), %eax ++ ja L(less_16_till_page) ++ ++ /* Use 16 byte comparison. */ ++ vmovdqu (%rdi), %xmm0 ++ VPTESTM %xmm0, %xmm0, %k2 ++ VPCMP $0, (%rsi), %xmm0, %k1{%k2} ++ kmovd %k1, %ecx + # ifdef USE_AS_WCSCMP +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- sall $2, %edx ++ subl $0xf, %ecx ++# else ++ incw %cx + # endif ++ jnz L(check_ret_vec_page_cross) ++ movl $(16 / SIZE_OF_CHAR), %OFFSET_REG + # ifdef USE_AS_STRNCMP +- cmpq %r11, %rdx +- jae L(zero) ++ cmpq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross_slow_case0) ++ subl %eax, %OFFSET_REG ++# else ++ /* Explicit check for 16 byte alignment. */ ++ subl %eax, %OFFSET_REG ++ jz L(prepare_loop) + # endif ++ vmovdqu (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm0 ++ VPTESTM %xmm0, %xmm0, %k2 ++ VPCMP $0, (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm0, %k1{%k2} ++ kmovd %k1, %ecx + # ifdef USE_AS_WCSCMP +- xorl %eax, %eax +- movl (%rdi, %rdx), %ecx +- cmpl (%rsi, %rdx), %ecx +- jne L(wcscmp_return) ++ subl $0xf, %ecx + # else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %edx +- subl %edx, %eax ++ incw %cx + # endif ++ jnz L(check_ret_vec_page_cross) ++# ifdef USE_AS_STRNCMP ++ addl $(16 / SIZE_OF_CHAR), %OFFSET_REG ++ subq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross_slow_case0) ++ subq $-(CHAR_PER_VEC * 4), %rdx ++ ++ leaq -(VEC_SIZE * 4)(%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %rdi ++ leaq -(VEC_SIZE * 4)(%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %rsi ++# else ++ leaq (16 - VEC_SIZE * 4)(%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %rdi ++ leaq (16 - VEC_SIZE * 4)(%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %rsi ++# endif ++ jmp L(prepare_loop_aligned) ++ ++# ifdef USE_AS_STRNCMP ++ .p2align 4,, 2 ++L(ret_zero_page_cross_slow_case0): ++ xorl %eax, %eax + ret ++# endif + +- /* Comparing on page boundary region requires special treatment: +- It must done one vector at the time, starting with the wider +- ymm vector if possible, if not, with xmm. If fetching 16 bytes +- (xmm) still passes the boundary, byte comparison must be done. +- */ +- .p2align 4 +-L(cross_page): +- /* Try one ymm vector at a time. */ +- cmpl $(PAGE_SIZE - VEC_SIZE), %eax +- jg L(cross_page_1_vector) +-L(loop_1_vector): +- VMOVU (%rdi, %rdx), %YMM0 + +- VPTESTM %YMM0, %YMM0, %k2 +- /* Each bit cleared in K1 represents a mismatch or a null CHAR +- in YMM0 and 32 bytes at (%rsi, %rdx). */ +- VPCMP $0, (%rsi, %rdx), %YMM0, %k1{%k2} ++ .p2align 4,, 10 ++L(less_16_till_page): ++ cmpl $(24 / SIZE_OF_CHAR), %eax ++ ja L(less_8_till_page) ++ ++ /* Use 8 byte comparison. */ ++ vmovq (%rdi), %xmm0 ++ vmovq (%rsi), %xmm1 ++ VPTESTM %xmm0, %xmm0, %k2 ++ VPCMP $0, %xmm1, %xmm0, %k1{%k2} + kmovd %k1, %ecx + # ifdef USE_AS_WCSCMP +- subl $0xff, %ecx ++ subl $0x3, %ecx + # else +- incl %ecx ++ incb %cl + # endif +- jne L(last_vector) ++ jnz L(check_ret_vec_page_cross) + +- addl $VEC_SIZE, %edx + +- addl $VEC_SIZE, %eax + # ifdef USE_AS_STRNCMP +- /* Return 0 if the current offset (%rdx) >= the maximum offset +- (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) ++ cmpq $(8 / SIZE_OF_CHAR), %rdx ++ jbe L(ret_zero_page_cross_slow_case0) + # endif +- cmpl $(PAGE_SIZE - VEC_SIZE), %eax +- jle L(loop_1_vector) +-L(cross_page_1_vector): +- /* Less than 32 bytes to check, try one xmm vector. */ +- cmpl $(PAGE_SIZE - 16), %eax +- jg L(cross_page_1_xmm) +- VMOVU (%rdi, %rdx), %XMM0 ++ movl $(24 / SIZE_OF_CHAR), %OFFSET_REG ++ subl %eax, %OFFSET_REG + +- VPTESTM %YMM0, %YMM0, %k2 +- /* Each bit cleared in K1 represents a mismatch or a null CHAR +- in XMM0 and 16 bytes at (%rsi, %rdx). */ +- VPCMP $0, (%rsi, %rdx), %XMM0, %k1{%k2} ++ vmovq (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm0 ++ vmovq (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm1 ++ VPTESTM %xmm0, %xmm0, %k2 ++ VPCMP $0, %xmm1, %xmm0, %k1{%k2} + kmovd %k1, %ecx + # ifdef USE_AS_WCSCMP +- subl $0xf, %ecx ++ subl $0x3, %ecx + # else +- subl $0xffff, %ecx ++ incb %cl + # endif +- jne L(last_vector) ++ jnz L(check_ret_vec_page_cross) ++ + +- addl $16, %edx +-# ifndef USE_AS_WCSCMP +- addl $16, %eax +-# endif + # ifdef USE_AS_STRNCMP +- /* Return 0 if the current offset (%rdx) >= the maximum offset +- (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) ++ addl $(8 / SIZE_OF_CHAR), %OFFSET_REG ++ subq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross_slow_case0) ++ subq $-(CHAR_PER_VEC * 4), %rdx ++ ++ leaq -(VEC_SIZE * 4)(%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %rdi ++ leaq -(VEC_SIZE * 4)(%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %rsi ++# else ++ leaq (8 - VEC_SIZE * 4)(%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %rdi ++ leaq (8 - VEC_SIZE * 4)(%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %rsi + # endif ++ jmp L(prepare_loop_aligned) + +-L(cross_page_1_xmm): +-# ifndef USE_AS_WCSCMP +- /* Less than 16 bytes to check, try 8 byte vector. NB: No need +- for wcscmp nor wcsncmp since wide char is 4 bytes. */ +- cmpl $(PAGE_SIZE - 8), %eax +- jg L(cross_page_8bytes) +- vmovq (%rdi, %rdx), %XMM0 +- vmovq (%rsi, %rdx), %XMM1 + +- VPTESTM %YMM0, %YMM0, %k2 +- /* Each bit cleared in K1 represents a mismatch or a null CHAR +- in XMM0 and XMM1. */ +- VPCMP $0, %XMM1, %XMM0, %k1{%k2} +- kmovb %k1, %ecx ++ ++ ++ .p2align 4,, 10 ++L(less_8_till_page): + # ifdef USE_AS_WCSCMP +- subl $0x3, %ecx ++ /* If using wchar then this is the only check before we reach ++ the page boundary. */ ++ movl (%rdi), %eax ++ movl (%rsi), %ecx ++ cmpl %ecx, %eax ++ jnz L(ret_less_8_wcs) ++# ifdef USE_AS_STRNCMP ++ addq $-(CHAR_PER_VEC * 2), %rdx ++ /* We already checked for len <= 1 so cannot hit that case here. ++ */ ++# endif ++ testl %eax, %eax ++ jnz L(prepare_loop) ++ ret ++ ++ .p2align 4,, 8 ++L(ret_less_8_wcs): ++ setl %OFFSET_REG8 ++ negl %OFFSET_REG ++ movl %OFFSET_REG, %eax ++ xorl %r8d, %eax ++ ret ++ + # else +- subl $0xff, %ecx +-# endif +- jne L(last_vector) ++ cmpl $28, %eax ++ ja L(less_4_till_page) ++ ++ vmovd (%rdi), %xmm0 ++ vmovd (%rsi), %xmm1 ++ VPTESTM %xmm0, %xmm0, %k2 ++ VPCMP $0, %xmm1, %xmm0, %k1{%k2} ++ kmovd %k1, %ecx ++ subl $0xf, %ecx ++ jnz L(check_ret_vec_page_cross) + +- addl $8, %edx +- addl $8, %eax + # ifdef USE_AS_STRNCMP +- /* Return 0 if the current offset (%rdx) >= the maximum offset +- (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) ++ cmpq $4, %rdx ++ jbe L(ret_zero_page_cross_slow_case1) + # endif ++ movl $(28 / SIZE_OF_CHAR), %OFFSET_REG ++ subl %eax, %OFFSET_REG + +-L(cross_page_8bytes): +- /* Less than 8 bytes to check, try 4 byte vector. */ +- cmpl $(PAGE_SIZE - 4), %eax +- jg L(cross_page_4bytes) +- vmovd (%rdi, %rdx), %XMM0 +- vmovd (%rsi, %rdx), %XMM1 +- +- VPTESTM %YMM0, %YMM0, %k2 +- /* Each bit cleared in K1 represents a mismatch or a null CHAR +- in XMM0 and XMM1. */ +- VPCMP $0, %XMM1, %XMM0, %k1{%k2} ++ vmovd (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm0 ++ vmovd (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm1 ++ VPTESTM %xmm0, %xmm0, %k2 ++ VPCMP $0, %xmm1, %xmm0, %k1{%k2} + kmovd %k1, %ecx +-# ifdef USE_AS_WCSCMP +- subl $0x1, %ecx +-# else + subl $0xf, %ecx +-# endif +- jne L(last_vector) ++ jnz L(check_ret_vec_page_cross) ++# ifdef USE_AS_STRNCMP ++ addl $(4 / SIZE_OF_CHAR), %OFFSET_REG ++ subq %OFFSET_REG64, %rdx ++ jbe L(ret_zero_page_cross_slow_case1) ++ subq $-(CHAR_PER_VEC * 4), %rdx ++ ++ leaq -(VEC_SIZE * 4)(%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %rdi ++ leaq -(VEC_SIZE * 4)(%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %rsi ++# else ++ leaq (4 - VEC_SIZE * 4)(%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %rdi ++ leaq (4 - VEC_SIZE * 4)(%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %rsi ++# endif ++ jmp L(prepare_loop_aligned) ++ + +- addl $4, %edx + # ifdef USE_AS_STRNCMP +- /* Return 0 if the current offset (%rdx) >= the maximum offset +- (%r11). */ +- cmpq %r11, %rdx +- jae L(zero) ++ .p2align 4,, 2 ++L(ret_zero_page_cross_slow_case1): ++ xorl %eax, %eax ++ ret + # endif + +-L(cross_page_4bytes): +-# endif +- /* Less than 4 bytes to check, try one byte/dword at a time. */ +-# ifdef USE_AS_STRNCMP +- cmpq %r11, %rdx +- jae L(zero) +-# endif +-# ifdef USE_AS_WCSCMP +- movl (%rdi, %rdx), %eax +- movl (%rsi, %rdx), %ecx +-# else +- movzbl (%rdi, %rdx), %eax +- movzbl (%rsi, %rdx), %ecx +-# endif +- testl %eax, %eax +- jne L(cross_page_loop) ++ .p2align 4,, 10 ++L(less_4_till_page): ++ subq %rdi, %rsi ++ /* Extremely slow byte comparison loop. */ ++L(less_4_loop): ++ movzbl (%rdi), %eax ++ movzbl (%rsi, %rdi), %ecx + subl %ecx, %eax ++ jnz L(ret_less_4_loop) ++ testl %ecx, %ecx ++ jz L(ret_zero_4_loop) ++# ifdef USE_AS_STRNCMP ++ decq %rdx ++ jz L(ret_zero_4_loop) ++# endif ++ incq %rdi ++ /* end condition is reach page boundary (rdi is aligned). */ ++ testl $31, %edi ++ jnz L(less_4_loop) ++ leaq -(VEC_SIZE * 4)(%rdi, %rsi), %rsi ++ addq $-(VEC_SIZE * 4), %rdi ++# ifdef USE_AS_STRNCMP ++ subq $-(CHAR_PER_VEC * 4), %rdx ++# endif ++ jmp L(prepare_loop_aligned) ++ ++L(ret_zero_4_loop): ++ xorl %eax, %eax ++ ret ++L(ret_less_4_loop): ++ xorl %r8d, %eax ++ subl %r8d, %eax + ret +-END (STRCMP) ++# endif ++END(STRCMP) + #endif diff --git a/SOURCES/glibc-upstream-2.34-203.patch b/SOURCES/glibc-upstream-2.34-203.patch new file mode 100644 index 0000000..e45b588 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-203.patch @@ -0,0 +1,29 @@ +commit d299032743e05571ef326c838a5ecf6ef5b3e9c3 +Author: H.J. Lu +Date: Fri Feb 4 11:09:10 2022 -0800 + + x86-64: Fix strcmp-avx2.S + + Change "movl %edx, %rdx" to "movl %edx, %edx" in: + + commit b77b06e0e296f1a2276c27a67e1d44f2cfa38d45 + Author: Noah Goldstein + Date: Mon Jan 10 15:35:38 2022 -0600 + + x86: Optimize strcmp-avx2.S + + (cherry picked from commit c15efd011cea3d8f0494269eb539583215a1feed) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S +index a0d1c65db11028bc..cdded412a70bad10 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S +@@ -106,7 +106,7 @@ ENTRY(STRCMP) + # ifdef USE_AS_STRNCMP + # ifdef __ILP32__ + /* Clear the upper 32 bits. */ +- movl %edx, %rdx ++ movl %edx, %edx + # endif + cmp $1, %RDX_LP + /* Signed comparison intentional. We use this branch to also diff --git a/SOURCES/glibc-upstream-2.34-204.patch b/SOURCES/glibc-upstream-2.34-204.patch new file mode 100644 index 0000000..4250493 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-204.patch @@ -0,0 +1,29 @@ +commit 53ddafe917a8af17b16beb794c29e5b09b86d534 +Author: H.J. Lu +Date: Fri Feb 4 11:11:08 2022 -0800 + + x86-64: Fix strcmp-evex.S + + Change "movl %edx, %rdx" to "movl %edx, %edx" in: + + commit 8418eb3ff4b781d31c4ed5dc6c0bd7356bc45db9 + Author: Noah Goldstein + Date: Mon Jan 10 15:35:39 2022 -0600 + + x86: Optimize strcmp-evex.S + + (cherry picked from commit 0e0199a9e02ebe42e2b36958964d63f03573c382) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S +index 99d8409af27327ad..ed56af8ecdad48b2 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-evex.S ++++ b/sysdeps/x86_64/multiarch/strcmp-evex.S +@@ -116,7 +116,7 @@ ENTRY(STRCMP) + # ifdef USE_AS_STRNCMP + # ifdef __ILP32__ + /* Clear the upper 32 bits. */ +- movl %edx, %rdx ++ movl %edx, %edx + # endif + cmp $1, %RDX_LP + /* Signed comparison intentional. We use this branch to also diff --git a/SOURCES/glibc-upstream-2.34-205.patch b/SOURCES/glibc-upstream-2.34-205.patch new file mode 100644 index 0000000..6cf18b8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-205.patch @@ -0,0 +1,451 @@ +commit ea19c490a3f5628d55ded271cbb753e66b2f05e8 +Author: Noah Goldstein +Date: Sun Feb 6 00:54:18 2022 -0600 + + x86: Improve vec generation in memset-vec-unaligned-erms.S + + No bug. + + Split vec generation into multiple steps. This allows the + broadcast in AVX2 to use 'xmm' registers for the L(less_vec) + case. This saves an expensive lane-cross instruction and removes + the need for 'vzeroupper'. + + For SSE2 replace 2x 'punpck' instructions with zero-idiom 'pxor' for + byte broadcast. + + Results for memset-avx2 small (geomean of N = 20 benchset runs). + + size, New Time, Old Time, New / Old + 0, 4.100, 3.831, 0.934 + 1, 5.074, 4.399, 0.867 + 2, 4.433, 4.411, 0.995 + 4, 4.487, 4.415, 0.984 + 8, 4.454, 4.396, 0.987 + 16, 4.502, 4.443, 0.987 + + All relevant string/wcsmbs tests are passing. + Reviewed-by: H.J. Lu + + (cherry picked from commit b62ace2740a106222e124cc86956448fa07abf4d) + +diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S +index 0137eba4cdd9f830..34ee0bfdcb81fb39 100644 +--- a/sysdeps/x86_64/memset.S ++++ b/sysdeps/x86_64/memset.S +@@ -28,17 +28,22 @@ + #define VMOVU movups + #define VMOVA movaps + +-#define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ ++# define MEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + movd d, %xmm0; \ +- movq r, %rax; \ +- punpcklbw %xmm0, %xmm0; \ +- punpcklwd %xmm0, %xmm0; \ +- pshufd $0, %xmm0, %xmm0 ++ pxor %xmm1, %xmm1; \ ++ pshufb %xmm1, %xmm0; \ ++ movq r, %rax + +-#define WMEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ ++# define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + movd d, %xmm0; \ +- movq r, %rax; \ +- pshufd $0, %xmm0, %xmm0 ++ pshufd $0, %xmm0, %xmm0; \ ++ movq r, %rax ++ ++# define MEMSET_VDUP_TO_VEC0_HIGH() ++# define MEMSET_VDUP_TO_VEC0_LOW() ++ ++# define WMEMSET_VDUP_TO_VEC0_HIGH() ++# define WMEMSET_VDUP_TO_VEC0_LOW() + + #define SECTION(p) p + +diff --git a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S +index 1af668af0aeda59e..c0bf2875d03d51ab 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S +@@ -10,15 +10,18 @@ + # define VMOVU vmovdqu + # define VMOVA vmovdqa + +-# define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ ++# define MEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + vmovd d, %xmm0; \ +- movq r, %rax; \ +- vpbroadcastb %xmm0, %ymm0 ++ movq r, %rax; + +-# define WMEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ +- vmovd d, %xmm0; \ +- movq r, %rax; \ +- vpbroadcastd %xmm0, %ymm0 ++# define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ ++ MEMSET_SET_VEC0_AND_SET_RETURN(d, r) ++ ++# define MEMSET_VDUP_TO_VEC0_HIGH() vpbroadcastb %xmm0, %ymm0 ++# define MEMSET_VDUP_TO_VEC0_LOW() vpbroadcastb %xmm0, %xmm0 ++ ++# define WMEMSET_VDUP_TO_VEC0_HIGH() vpbroadcastd %xmm0, %ymm0 ++# define WMEMSET_VDUP_TO_VEC0_LOW() vpbroadcastd %xmm0, %xmm0 + + # ifndef SECTION + # define SECTION(p) p##.avx +@@ -30,5 +33,6 @@ + # define WMEMSET_SYMBOL(p,s) p##_avx2_##s + # endif + ++# define USE_XMM_LESS_VEC + # include "memset-vec-unaligned-erms.S" + #endif +diff --git a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S +index f14d6f8493c21a36..5241216a77bf72b7 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S +@@ -15,13 +15,19 @@ + + # define VZEROUPPER + +-# define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ +- movq r, %rax; \ +- vpbroadcastb d, %VEC0 ++# define MEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ ++ vpbroadcastb d, %VEC0; \ ++ movq r, %rax + +-# define WMEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ +- movq r, %rax; \ +- vpbroadcastd d, %VEC0 ++# define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ ++ vpbroadcastd d, %VEC0; \ ++ movq r, %rax ++ ++# define MEMSET_VDUP_TO_VEC0_HIGH() ++# define MEMSET_VDUP_TO_VEC0_LOW() ++ ++# define WMEMSET_VDUP_TO_VEC0_HIGH() ++# define WMEMSET_VDUP_TO_VEC0_LOW() + + # define SECTION(p) p##.evex512 + # define MEMSET_SYMBOL(p,s) p##_avx512_##s +diff --git a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S +index 64b09e77cc20cc42..637002150659123c 100644 +--- a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S +@@ -15,13 +15,19 @@ + + # define VZEROUPPER + +-# define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ +- movq r, %rax; \ +- vpbroadcastb d, %VEC0 ++# define MEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ ++ vpbroadcastb d, %VEC0; \ ++ movq r, %rax + +-# define WMEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \ +- movq r, %rax; \ +- vpbroadcastd d, %VEC0 ++# define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ ++ vpbroadcastd d, %VEC0; \ ++ movq r, %rax ++ ++# define MEMSET_VDUP_TO_VEC0_HIGH() ++# define MEMSET_VDUP_TO_VEC0_LOW() ++ ++# define WMEMSET_VDUP_TO_VEC0_HIGH() ++# define WMEMSET_VDUP_TO_VEC0_LOW() + + # define SECTION(p) p##.evex + # define MEMSET_SYMBOL(p,s) p##_evex_##s +diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +index e723413a664c088f..c8db87dcbf69f0d8 100644 +--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +@@ -58,8 +58,10 @@ + #ifndef MOVQ + # if VEC_SIZE > 16 + # define MOVQ vmovq ++# define MOVD vmovd + # else + # define MOVQ movq ++# define MOVD movd + # endif + #endif + +@@ -72,9 +74,17 @@ + #if defined USE_WITH_EVEX || defined USE_WITH_AVX512 + # define END_REG rcx + # define LOOP_REG rdi ++# define LESS_VEC_REG rax + #else + # define END_REG rdi + # define LOOP_REG rdx ++# define LESS_VEC_REG rdi ++#endif ++ ++#ifdef USE_XMM_LESS_VEC ++# define XMM_SMALL 1 ++#else ++# define XMM_SMALL 0 + #endif + + #define PAGE_SIZE 4096 +@@ -110,8 +120,12 @@ END_CHK (WMEMSET_CHK_SYMBOL (__wmemset_chk, unaligned)) + + ENTRY (WMEMSET_SYMBOL (__wmemset, unaligned)) + shl $2, %RDX_LP +- WMEMSET_VDUP_TO_VEC0_AND_SET_RETURN (%esi, %rdi) +- jmp L(entry_from_bzero) ++ WMEMSET_SET_VEC0_AND_SET_RETURN (%esi, %rdi) ++ WMEMSET_VDUP_TO_VEC0_LOW() ++ cmpq $VEC_SIZE, %rdx ++ jb L(less_vec_no_vdup) ++ WMEMSET_VDUP_TO_VEC0_HIGH() ++ jmp L(entry_from_wmemset) + END (WMEMSET_SYMBOL (__wmemset, unaligned)) + #endif + +@@ -123,7 +137,7 @@ END_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned)) + #endif + + ENTRY (MEMSET_SYMBOL (__memset, unaligned)) +- MEMSET_VDUP_TO_VEC0_AND_SET_RETURN (%esi, %rdi) ++ MEMSET_SET_VEC0_AND_SET_RETURN (%esi, %rdi) + # ifdef __ILP32__ + /* Clear the upper 32 bits. */ + mov %edx, %edx +@@ -131,6 +145,8 @@ ENTRY (MEMSET_SYMBOL (__memset, unaligned)) + L(entry_from_bzero): + cmpq $VEC_SIZE, %rdx + jb L(less_vec) ++ MEMSET_VDUP_TO_VEC0_HIGH() ++L(entry_from_wmemset): + cmpq $(VEC_SIZE * 2), %rdx + ja L(more_2x_vec) + /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */ +@@ -179,27 +195,27 @@ END_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms)) + # endif + + ENTRY_P2ALIGN (MEMSET_SYMBOL (__memset, unaligned_erms), 6) +- MEMSET_VDUP_TO_VEC0_AND_SET_RETURN (%esi, %rdi) ++ MEMSET_SET_VEC0_AND_SET_RETURN (%esi, %rdi) + # ifdef __ILP32__ + /* Clear the upper 32 bits. */ + mov %edx, %edx + # endif + cmp $VEC_SIZE, %RDX_LP + jb L(less_vec) ++ MEMSET_VDUP_TO_VEC0_HIGH () + cmp $(VEC_SIZE * 2), %RDX_LP + ja L(stosb_more_2x_vec) +- /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. +- */ +- VMOVU %VEC(0), (%rax) +- VMOVU %VEC(0), -VEC_SIZE(%rax, %rdx) ++ /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */ ++ VMOVU %VEC(0), (%rdi) ++ VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi, %rdx) + VZEROUPPER_RETURN + #endif + +- .p2align 4,, 10 ++ .p2align 4,, 4 + L(last_2x_vec): + #ifdef USE_LESS_VEC_MASK_STORE +- VMOVU %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%rcx) +- VMOVU %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%rcx) ++ VMOVU %VEC(0), (VEC_SIZE * -2)(%rdi, %rdx) ++ VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi, %rdx) + #else + VMOVU %VEC(0), (VEC_SIZE * -2)(%rdi) + VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi) +@@ -212,6 +228,7 @@ L(last_2x_vec): + #ifdef USE_LESS_VEC_MASK_STORE + .p2align 4,, 10 + L(less_vec): ++L(less_vec_no_vdup): + /* Less than 1 VEC. */ + # if VEC_SIZE != 16 && VEC_SIZE != 32 && VEC_SIZE != 64 + # error Unsupported VEC_SIZE! +@@ -262,28 +279,18 @@ L(stosb_more_2x_vec): + /* Fallthrough goes to L(loop_4x_vec). Tests for memset (2x, 4x] + and (4x, 8x] jump to target. */ + L(more_2x_vec): +- +- /* Two different methods of setting up pointers / compare. The +- two methods are based on the fact that EVEX/AVX512 mov +- instructions take more bytes then AVX2/SSE2 mov instructions. As +- well that EVEX/AVX512 machines also have fast LEA_BID. Both +- setup and END_REG to avoid complex address mode. For EVEX/AVX512 +- this saves code size and keeps a few targets in one fetch block. +- For AVX2/SSE2 this helps prevent AGU bottlenecks. */ +-#if defined USE_WITH_EVEX || defined USE_WITH_AVX512 +- /* If EVEX/AVX512 compute END_REG - (VEC_SIZE * 4 + +- LOOP_4X_OFFSET) with LEA_BID. */ +- +- /* END_REG is rcx for EVEX/AVX512. */ +- leaq -(VEC_SIZE * 4 + LOOP_4X_OFFSET)(%rdi, %rdx), %END_REG +-#endif +- +- /* Stores to first 2x VEC before cmp as any path forward will +- require it. */ +- VMOVU %VEC(0), (%rax) +- VMOVU %VEC(0), VEC_SIZE(%rax) ++ /* Store next 2x vec regardless. */ ++ VMOVU %VEC(0), (%rdi) ++ VMOVU %VEC(0), (VEC_SIZE * 1)(%rdi) + + ++ /* Two different methods of setting up pointers / compare. The two ++ methods are based on the fact that EVEX/AVX512 mov instructions take ++ more bytes then AVX2/SSE2 mov instructions. As well that EVEX/AVX512 ++ machines also have fast LEA_BID. Both setup and END_REG to avoid complex ++ address mode. For EVEX/AVX512 this saves code size and keeps a few ++ targets in one fetch block. For AVX2/SSE2 this helps prevent AGU ++ bottlenecks. */ + #if !(defined USE_WITH_EVEX || defined USE_WITH_AVX512) + /* If AVX2/SSE2 compute END_REG (rdi) with ALU. */ + addq %rdx, %END_REG +@@ -292,6 +299,15 @@ L(more_2x_vec): + cmpq $(VEC_SIZE * 4), %rdx + jbe L(last_2x_vec) + ++ ++#if defined USE_WITH_EVEX || defined USE_WITH_AVX512 ++ /* If EVEX/AVX512 compute END_REG - (VEC_SIZE * 4 + LOOP_4X_OFFSET) with ++ LEA_BID. */ ++ ++ /* END_REG is rcx for EVEX/AVX512. */ ++ leaq -(VEC_SIZE * 4 + LOOP_4X_OFFSET)(%rdi, %rdx), %END_REG ++#endif ++ + /* Store next 2x vec regardless. */ + VMOVU %VEC(0), (VEC_SIZE * 2)(%rax) + VMOVU %VEC(0), (VEC_SIZE * 3)(%rax) +@@ -355,65 +371,93 @@ L(stosb_local): + /* Define L(less_vec) only if not otherwise defined. */ + .p2align 4 + L(less_vec): ++ /* Broadcast esi to partial register (i.e VEC_SIZE == 32 broadcast to ++ xmm). This is only does anything for AVX2. */ ++ MEMSET_VDUP_TO_VEC0_LOW () ++L(less_vec_no_vdup): + #endif + L(cross_page): + #if VEC_SIZE > 32 + cmpl $32, %edx +- jae L(between_32_63) ++ jge L(between_32_63) + #endif + #if VEC_SIZE > 16 + cmpl $16, %edx +- jae L(between_16_31) ++ jge L(between_16_31) ++#endif ++#ifndef USE_XMM_LESS_VEC ++ MOVQ %XMM0, %rcx + #endif +- MOVQ %XMM0, %rdi + cmpl $8, %edx +- jae L(between_8_15) ++ jge L(between_8_15) + cmpl $4, %edx +- jae L(between_4_7) ++ jge L(between_4_7) + cmpl $1, %edx +- ja L(between_2_3) +- jb L(return) +- movb %sil, (%rax) +- VZEROUPPER_RETURN ++ jg L(between_2_3) ++ jl L(between_0_0) ++ movb %sil, (%LESS_VEC_REG) ++L(between_0_0): ++ ret + +- /* Align small targets only if not doing so would cross a fetch +- line. */ ++ /* Align small targets only if not doing so would cross a fetch line. ++ */ + #if VEC_SIZE > 32 + .p2align 4,, SMALL_MEMSET_ALIGN(MOV_SIZE, RET_SIZE) + /* From 32 to 63. No branch when size == 32. */ + L(between_32_63): +- VMOVU %YMM0, (%rax) +- VMOVU %YMM0, -32(%rax, %rdx) ++ VMOVU %YMM0, (%LESS_VEC_REG) ++ VMOVU %YMM0, -32(%LESS_VEC_REG, %rdx) + VZEROUPPER_RETURN + #endif + + #if VEC_SIZE >= 32 +- .p2align 4,, SMALL_MEMSET_ALIGN(MOV_SIZE, RET_SIZE) ++ .p2align 4,, SMALL_MEMSET_ALIGN(MOV_SIZE, 1) + L(between_16_31): + /* From 16 to 31. No branch when size == 16. */ +- VMOVU %XMM0, (%rax) +- VMOVU %XMM0, -16(%rax, %rdx) +- VZEROUPPER_RETURN ++ VMOVU %XMM0, (%LESS_VEC_REG) ++ VMOVU %XMM0, -16(%LESS_VEC_REG, %rdx) ++ ret + #endif + +- .p2align 4,, SMALL_MEMSET_ALIGN(3, RET_SIZE) ++ /* Move size is 3 for SSE2, EVEX, and AVX512. Move size is 4 for AVX2. ++ */ ++ .p2align 4,, SMALL_MEMSET_ALIGN(3 + XMM_SMALL, 1) + L(between_8_15): + /* From 8 to 15. No branch when size == 8. */ +- movq %rdi, (%rax) +- movq %rdi, -8(%rax, %rdx) +- VZEROUPPER_RETURN ++#ifdef USE_XMM_LESS_VEC ++ MOVQ %XMM0, (%rdi) ++ MOVQ %XMM0, -8(%rdi, %rdx) ++#else ++ movq %rcx, (%LESS_VEC_REG) ++ movq %rcx, -8(%LESS_VEC_REG, %rdx) ++#endif ++ ret + +- .p2align 4,, SMALL_MEMSET_ALIGN(2, RET_SIZE) ++ /* Move size is 2 for SSE2, EVEX, and AVX512. Move size is 4 for AVX2. ++ */ ++ .p2align 4,, SMALL_MEMSET_ALIGN(2 << XMM_SMALL, 1) + L(between_4_7): + /* From 4 to 7. No branch when size == 4. */ +- movl %edi, (%rax) +- movl %edi, -4(%rax, %rdx) +- VZEROUPPER_RETURN ++#ifdef USE_XMM_LESS_VEC ++ MOVD %XMM0, (%rdi) ++ MOVD %XMM0, -4(%rdi, %rdx) ++#else ++ movl %ecx, (%LESS_VEC_REG) ++ movl %ecx, -4(%LESS_VEC_REG, %rdx) ++#endif ++ ret + +- .p2align 4,, SMALL_MEMSET_ALIGN(3, RET_SIZE) ++ /* 4 * XMM_SMALL for the third mov for AVX2. */ ++ .p2align 4,, 4 * XMM_SMALL + SMALL_MEMSET_ALIGN(3, 1) + L(between_2_3): + /* From 2 to 3. No branch when size == 2. */ +- movw %di, (%rax) +- movb %dil, -1(%rax, %rdx) +- VZEROUPPER_RETURN ++#ifdef USE_XMM_LESS_VEC ++ movb %sil, (%rdi) ++ movb %sil, 1(%rdi) ++ movb %sil, -1(%rdi, %rdx) ++#else ++ movw %cx, (%LESS_VEC_REG) ++ movb %sil, -1(%LESS_VEC_REG, %rdx) ++#endif ++ ret + END (MEMSET_SYMBOL (__memset, unaligned_erms)) diff --git a/SOURCES/glibc-upstream-2.34-206.patch b/SOURCES/glibc-upstream-2.34-206.patch new file mode 100644 index 0000000..ed9f37b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-206.patch @@ -0,0 +1,35 @@ +commit 190ea5f7e4e7e98b9b6e3f29835ae8b1f6a5442e +Author: Noah Goldstein +Date: Mon Feb 7 00:32:23 2022 -0600 + + x86: Remove SSSE3 instruction for broadcast in memset.S (SSE2 Only) + + commit b62ace2740a106222e124cc86956448fa07abf4d + Author: Noah Goldstein + Date: Sun Feb 6 00:54:18 2022 -0600 + + x86: Improve vec generation in memset-vec-unaligned-erms.S + + Revert usage of 'pshufb' in broadcast logic as it is an SSSE3 + instruction and memset.S is restricted to only SSE2 instructions. + + (cherry picked from commit 1b0c60f95bbe2eded80b2bb5be75c0e45b11cde1) + +diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S +index 34ee0bfdcb81fb39..954471e5a5bf225b 100644 +--- a/sysdeps/x86_64/memset.S ++++ b/sysdeps/x86_64/memset.S +@@ -30,9 +30,10 @@ + + # define MEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + movd d, %xmm0; \ +- pxor %xmm1, %xmm1; \ +- pshufb %xmm1, %xmm0; \ +- movq r, %rax ++ movq r, %rax; \ ++ punpcklbw %xmm0, %xmm0; \ ++ punpcklwd %xmm0, %xmm0; \ ++ pshufd $0, %xmm0, %xmm0 + + # define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + movd d, %xmm0; \ diff --git a/SOURCES/glibc-upstream-2.34-207.patch b/SOURCES/glibc-upstream-2.34-207.patch new file mode 100644 index 0000000..9818f5d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-207.patch @@ -0,0 +1,719 @@ +commit 5cb6329652696e79d6d576165ea87e332c9de106 +Author: H.J. Lu +Date: Mon Feb 7 05:55:15 2022 -0800 + + x86-64: Optimize bzero + + memset with zero as the value to set is by far the majority value (99%+ + for Python3 and GCC). + + bzero can be slightly more optimized for this case by using a zero-idiom + xor for broadcasting the set value to a register (vector or GPR). + + Co-developed-by: Noah Goldstein + (cherry picked from commit 3d9f171bfb5325bd5f427e9fc386453358c6e840) + +diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S +index 954471e5a5bf225b..0358210c7ff3a976 100644 +--- a/sysdeps/x86_64/memset.S ++++ b/sysdeps/x86_64/memset.S +@@ -35,6 +35,9 @@ + punpcklwd %xmm0, %xmm0; \ + pshufd $0, %xmm0, %xmm0 + ++# define BZERO_ZERO_VEC0() \ ++ pxor %xmm0, %xmm0 ++ + # define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + movd d, %xmm0; \ + pshufd $0, %xmm0, %xmm0; \ +@@ -53,6 +56,10 @@ + # define MEMSET_SYMBOL(p,s) memset + #endif + ++#ifndef BZERO_SYMBOL ++# define BZERO_SYMBOL(p,s) __bzero ++#endif ++ + #ifndef WMEMSET_SYMBOL + # define WMEMSET_CHK_SYMBOL(p,s) p + # define WMEMSET_SYMBOL(p,s) __wmemset +@@ -63,6 +70,7 @@ + libc_hidden_builtin_def (memset) + + #if IS_IN (libc) ++weak_alias (__bzero, bzero) + libc_hidden_def (__wmemset) + weak_alias (__wmemset, wmemset) + libc_hidden_weak (wmemset) +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index 26be40959ce62895..37d8d6f0bd2d10cc 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -1,85 +1,130 @@ + ifeq ($(subdir),string) + +-sysdep_routines += strncat-c stpncpy-c strncpy-c \ +- strcmp-sse2 strcmp-sse2-unaligned strcmp-ssse3 \ +- strcmp-sse4_2 strcmp-avx2 \ +- strncmp-sse2 strncmp-ssse3 strncmp-sse4_2 strncmp-avx2 \ +- memchr-sse2 rawmemchr-sse2 memchr-avx2 rawmemchr-avx2 \ +- memrchr-sse2 memrchr-avx2 \ +- memcmp-sse2 \ +- memcmp-avx2-movbe \ +- memcmp-sse4 memcpy-ssse3 \ +- memmove-ssse3 \ +- memcpy-ssse3-back \ +- memmove-ssse3-back \ +- memmove-avx512-no-vzeroupper \ +- strcasecmp_l-sse2 strcasecmp_l-ssse3 \ +- strcasecmp_l-sse4_2 strcasecmp_l-avx \ +- strncase_l-sse2 strncase_l-ssse3 \ +- strncase_l-sse4_2 strncase_l-avx \ +- strchr-sse2 strchrnul-sse2 strchr-avx2 strchrnul-avx2 \ +- strrchr-sse2 strrchr-avx2 \ +- strlen-sse2 strnlen-sse2 strlen-avx2 strnlen-avx2 \ +- strcat-avx2 strncat-avx2 \ +- strcat-ssse3 strncat-ssse3\ +- strcpy-avx2 strncpy-avx2 \ +- strcpy-sse2 stpcpy-sse2 \ +- strcpy-ssse3 strncpy-ssse3 stpcpy-ssse3 stpncpy-ssse3 \ +- strcpy-sse2-unaligned strncpy-sse2-unaligned \ +- stpcpy-sse2-unaligned stpncpy-sse2-unaligned \ +- stpcpy-avx2 stpncpy-avx2 \ +- strcat-sse2 \ +- strcat-sse2-unaligned strncat-sse2-unaligned \ +- strchr-sse2-no-bsf memcmp-ssse3 strstr-sse2-unaligned \ +- strcspn-sse2 strpbrk-sse2 strspn-sse2 \ +- strcspn-c strpbrk-c strspn-c varshift \ +- memset-avx512-no-vzeroupper \ +- memmove-sse2-unaligned-erms \ +- memmove-avx-unaligned-erms \ +- memmove-avx512-unaligned-erms \ +- memset-sse2-unaligned-erms \ +- memset-avx2-unaligned-erms \ +- memset-avx512-unaligned-erms \ +- memchr-avx2-rtm \ +- memcmp-avx2-movbe-rtm \ +- memmove-avx-unaligned-erms-rtm \ +- memrchr-avx2-rtm \ +- memset-avx2-unaligned-erms-rtm \ +- rawmemchr-avx2-rtm \ +- strchr-avx2-rtm \ +- strcmp-avx2-rtm \ +- strchrnul-avx2-rtm \ +- stpcpy-avx2-rtm \ +- stpncpy-avx2-rtm \ +- strcat-avx2-rtm \ +- strcpy-avx2-rtm \ +- strlen-avx2-rtm \ +- strncat-avx2-rtm \ +- strncmp-avx2-rtm \ +- strncpy-avx2-rtm \ +- strnlen-avx2-rtm \ +- strrchr-avx2-rtm \ +- memchr-evex \ +- memcmp-evex-movbe \ +- memmove-evex-unaligned-erms \ +- memrchr-evex \ +- memset-evex-unaligned-erms \ +- rawmemchr-evex \ +- stpcpy-evex \ +- stpncpy-evex \ +- strcat-evex \ +- strchr-evex \ +- strchrnul-evex \ +- strcmp-evex \ +- strcpy-evex \ +- strlen-evex \ +- strncat-evex \ +- strncmp-evex \ +- strncpy-evex \ +- strnlen-evex \ +- strrchr-evex \ +- memchr-evex-rtm \ +- rawmemchr-evex-rtm ++sysdep_routines += \ ++ bzero \ ++ memchr-avx2 \ ++ memchr-avx2-rtm \ ++ memchr-evex \ ++ memchr-evex-rtm \ ++ memchr-sse2 \ ++ memcmp-avx2-movbe \ ++ memcmp-avx2-movbe-rtm \ ++ memcmp-evex-movbe \ ++ memcmp-sse2 \ ++ memcmp-sse4 \ ++ memcmp-ssse3 \ ++ memcpy-ssse3 \ ++ memcpy-ssse3-back \ ++ memmove-avx-unaligned-erms \ ++ memmove-avx-unaligned-erms-rtm \ ++ memmove-avx512-no-vzeroupper \ ++ memmove-avx512-unaligned-erms \ ++ memmove-evex-unaligned-erms \ ++ memmove-sse2-unaligned-erms \ ++ memmove-ssse3 \ ++ memmove-ssse3-back \ ++ memrchr-avx2 \ ++ memrchr-avx2-rtm \ ++ memrchr-evex \ ++ memrchr-sse2 \ ++ memset-avx2-unaligned-erms \ ++ memset-avx2-unaligned-erms-rtm \ ++ memset-avx512-no-vzeroupper \ ++ memset-avx512-unaligned-erms \ ++ memset-evex-unaligned-erms \ ++ memset-sse2-unaligned-erms \ ++ rawmemchr-avx2 \ ++ rawmemchr-avx2-rtm \ ++ rawmemchr-evex \ ++ rawmemchr-evex-rtm \ ++ rawmemchr-sse2 \ ++ stpcpy-avx2 \ ++ stpcpy-avx2-rtm \ ++ stpcpy-evex \ ++ stpcpy-sse2 \ ++ stpcpy-sse2-unaligned \ ++ stpcpy-ssse3 \ ++ stpncpy-avx2 \ ++ stpncpy-avx2-rtm \ ++ stpncpy-c \ ++ stpncpy-evex \ ++ stpncpy-sse2-unaligned \ ++ stpncpy-ssse3 \ ++ strcasecmp_l-avx \ ++ strcasecmp_l-sse2 \ ++ strcasecmp_l-sse4_2 \ ++ strcasecmp_l-ssse3 \ ++ strcat-avx2 \ ++ strcat-avx2-rtm \ ++ strcat-evex \ ++ strcat-sse2 \ ++ strcat-sse2-unaligned \ ++ strcat-ssse3 \ ++ strchr-avx2 \ ++ strchr-avx2-rtm \ ++ strchr-evex \ ++ strchr-sse2 \ ++ strchr-sse2-no-bsf \ ++ strchrnul-avx2 \ ++ strchrnul-avx2-rtm \ ++ strchrnul-evex \ ++ strchrnul-sse2 \ ++ strcmp-avx2 \ ++ strcmp-avx2-rtm \ ++ strcmp-evex \ ++ strcmp-sse2 \ ++ strcmp-sse2-unaligned \ ++ strcmp-sse4_2 \ ++ strcmp-ssse3 \ ++ strcpy-avx2 \ ++ strcpy-avx2-rtm \ ++ strcpy-evex \ ++ strcpy-sse2 \ ++ strcpy-sse2-unaligned \ ++ strcpy-ssse3 \ ++ strcspn-c \ ++ strcspn-sse2 \ ++ strlen-avx2 \ ++ strlen-avx2-rtm \ ++ strlen-evex \ ++ strlen-sse2 \ ++ strncase_l-avx \ ++ strncase_l-sse2 \ ++ strncase_l-sse4_2 \ ++ strncase_l-ssse3 \ ++ strncat-avx2 \ ++ strncat-avx2-rtm \ ++ strncat-c \ ++ strncat-evex \ ++ strncat-sse2-unaligned \ ++ strncat-ssse3 \ ++ strncmp-avx2 \ ++ strncmp-avx2-rtm \ ++ strncmp-evex \ ++ strncmp-sse2 \ ++ strncmp-sse4_2 \ ++ strncmp-ssse3 \ ++ strncpy-avx2 \ ++ strncpy-avx2-rtm \ ++ strncpy-c \ ++ strncpy-evex \ ++ strncpy-sse2-unaligned \ ++ strncpy-ssse3 \ ++ strnlen-avx2 \ ++ strnlen-avx2-rtm \ ++ strnlen-evex \ ++ strnlen-sse2 \ ++ strpbrk-c \ ++ strpbrk-sse2 \ ++ strrchr-avx2 \ ++ strrchr-avx2-rtm \ ++ strrchr-evex \ ++ strrchr-sse2 \ ++ strspn-c \ ++ strspn-sse2 \ ++ strstr-sse2-unaligned \ ++ varshift \ ++# sysdep_routines + CFLAGS-varshift.c += -msse4 + CFLAGS-strcspn-c.c += -msse4 + CFLAGS-strpbrk-c.c += -msse4 +diff --git a/sysdeps/x86_64/multiarch/bzero.c b/sysdeps/x86_64/multiarch/bzero.c +new file mode 100644 +index 0000000000000000..13e399a9a1fbdeb2 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/bzero.c +@@ -0,0 +1,108 @@ ++/* Multiple versions of bzero. ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Define multiple versions only for the definition in libc. */ ++#if IS_IN (libc) ++# define __bzero __redirect___bzero ++# include ++# undef __bzero ++ ++/* OPTIMIZE1 definition required for bzero patch. */ ++# define OPTIMIZE1(name) EVALUATOR1 (SYMBOL_NAME, name) ++# define SYMBOL_NAME __bzero ++# include ++ ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (sse2_unaligned) ++ attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (sse2_unaligned_erms) ++ attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx2_unaligned) attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx2_unaligned_erms) ++ attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx2_unaligned_rtm) ++ attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx2_unaligned_erms_rtm) ++ attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (evex_unaligned) ++ attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (evex_unaligned_erms) ++ attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx512_unaligned) ++ attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx512_unaligned_erms) ++ attribute_hidden; ++ ++static inline void * ++IFUNC_SELECTOR (void) ++{ ++ const struct cpu_features* cpu_features = __get_cpu_features (); ++ ++ if (CPU_FEATURE_USABLE_P (cpu_features, AVX512F) ++ && !CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_AVX512)) ++ { ++ if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) ++ && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI2)) ++ { ++ if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) ++ return OPTIMIZE1 (avx512_unaligned_erms); ++ ++ return OPTIMIZE1 (avx512_unaligned); ++ } ++ } ++ ++ if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)) ++ { ++ if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) ++ && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI2)) ++ { ++ if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) ++ return OPTIMIZE1 (evex_unaligned_erms); ++ ++ return OPTIMIZE1 (evex_unaligned); ++ } ++ ++ if (CPU_FEATURE_USABLE_P (cpu_features, RTM)) ++ { ++ if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) ++ return OPTIMIZE1 (avx2_unaligned_erms_rtm); ++ ++ return OPTIMIZE1 (avx2_unaligned_rtm); ++ } ++ ++ if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_VZEROUPPER)) ++ { ++ if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) ++ return OPTIMIZE1 (avx2_unaligned_erms); ++ ++ return OPTIMIZE1 (avx2_unaligned); ++ } ++ } ++ ++ if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) ++ return OPTIMIZE1 (sse2_unaligned_erms); ++ ++ return OPTIMIZE1 (sse2_unaligned); ++} ++ ++libc_ifunc_redirected (__redirect___bzero, __bzero, IFUNC_SELECTOR ()); ++ ++weak_alias (__bzero, bzero) ++#endif +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index 39ab10613bb0ffea..4992d7bd3206a7c0 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -282,6 +282,48 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __memset_avx512_no_vzeroupper) + ) + ++ /* Support sysdeps/x86_64/multiarch/bzero.c. */ ++ IFUNC_IMPL (i, name, bzero, ++ IFUNC_IMPL_ADD (array, i, bzero, 1, ++ __bzero_sse2_unaligned) ++ IFUNC_IMPL_ADD (array, i, bzero, 1, ++ __bzero_sse2_unaligned_erms) ++ IFUNC_IMPL_ADD (array, i, bzero, ++ CPU_FEATURE_USABLE (AVX2), ++ __bzero_avx2_unaligned) ++ IFUNC_IMPL_ADD (array, i, bzero, ++ CPU_FEATURE_USABLE (AVX2), ++ __bzero_avx2_unaligned_erms) ++ IFUNC_IMPL_ADD (array, i, bzero, ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (RTM)), ++ __bzero_avx2_unaligned_rtm) ++ IFUNC_IMPL_ADD (array, i, bzero, ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (RTM)), ++ __bzero_avx2_unaligned_erms_rtm) ++ IFUNC_IMPL_ADD (array, i, bzero, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), ++ __bzero_evex_unaligned) ++ IFUNC_IMPL_ADD (array, i, bzero, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), ++ __bzero_evex_unaligned_erms) ++ IFUNC_IMPL_ADD (array, i, bzero, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), ++ __bzero_avx512_unaligned_erms) ++ IFUNC_IMPL_ADD (array, i, bzero, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), ++ __bzero_avx512_unaligned) ++ ) ++ + /* Support sysdeps/x86_64/multiarch/rawmemchr.c. */ + IFUNC_IMPL (i, name, rawmemchr, + IFUNC_IMPL_ADD (array, i, rawmemchr, +diff --git a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms-rtm.S b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms-rtm.S +index 8ac3e479bba488be..5a5ee6f67299400b 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms-rtm.S ++++ b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms-rtm.S +@@ -5,6 +5,7 @@ + + #define SECTION(p) p##.avx.rtm + #define MEMSET_SYMBOL(p,s) p##_avx2_##s##_rtm ++#define BZERO_SYMBOL(p,s) p##_avx2_##s##_rtm + #define WMEMSET_SYMBOL(p,s) p##_avx2_##s##_rtm + + #include "memset-avx2-unaligned-erms.S" +diff --git a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S +index c0bf2875d03d51ab..a093a2831f3dfa0d 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S +@@ -14,6 +14,9 @@ + vmovd d, %xmm0; \ + movq r, %rax; + ++# define BZERO_ZERO_VEC0() \ ++ vpxor %xmm0, %xmm0, %xmm0 ++ + # define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + MEMSET_SET_VEC0_AND_SET_RETURN(d, r) + +@@ -29,6 +32,9 @@ + # ifndef MEMSET_SYMBOL + # define MEMSET_SYMBOL(p,s) p##_avx2_##s + # endif ++# ifndef BZERO_SYMBOL ++# define BZERO_SYMBOL(p,s) p##_avx2_##s ++# endif + # ifndef WMEMSET_SYMBOL + # define WMEMSET_SYMBOL(p,s) p##_avx2_##s + # endif +diff --git a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S +index 5241216a77bf72b7..727c92133a15900f 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S +@@ -19,6 +19,9 @@ + vpbroadcastb d, %VEC0; \ + movq r, %rax + ++# define BZERO_ZERO_VEC0() \ ++ vpxorq %XMM0, %XMM0, %XMM0 ++ + # define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + vpbroadcastd d, %VEC0; \ + movq r, %rax +diff --git a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S +index 637002150659123c..5d8fa78f05476b10 100644 +--- a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S +@@ -19,6 +19,9 @@ + vpbroadcastb d, %VEC0; \ + movq r, %rax + ++# define BZERO_ZERO_VEC0() \ ++ vpxorq %XMM0, %XMM0, %XMM0 ++ + # define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + vpbroadcastd d, %VEC0; \ + movq r, %rax +diff --git a/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S +index e4e95fc19fe48d2d..bac74ac37fd3c144 100644 +--- a/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S +@@ -22,6 +22,7 @@ + + #if IS_IN (libc) + # define MEMSET_SYMBOL(p,s) p##_sse2_##s ++# define BZERO_SYMBOL(p,s) MEMSET_SYMBOL (p, s) + # define WMEMSET_SYMBOL(p,s) p##_sse2_##s + + # ifdef SHARED +diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +index c8db87dcbf69f0d8..39a096a594ccb5b6 100644 +--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +@@ -26,6 +26,10 @@ + + #include + ++#ifndef BZERO_SYMBOL ++# define BZERO_SYMBOL(p,s) MEMSET_SYMBOL (p, s) ++#endif ++ + #ifndef MEMSET_CHK_SYMBOL + # define MEMSET_CHK_SYMBOL(p,s) MEMSET_SYMBOL(p, s) + #endif +@@ -87,6 +91,18 @@ + # define XMM_SMALL 0 + #endif + ++#ifdef USE_LESS_VEC_MASK_STORE ++# define SET_REG64 rcx ++# define SET_REG32 ecx ++# define SET_REG16 cx ++# define SET_REG8 cl ++#else ++# define SET_REG64 rsi ++# define SET_REG32 esi ++# define SET_REG16 si ++# define SET_REG8 sil ++#endif ++ + #define PAGE_SIZE 4096 + + /* Macro to calculate size of small memset block for aligning +@@ -96,18 +112,6 @@ + + #ifndef SECTION + # error SECTION is not defined! +-#endif +- +- .section SECTION(.text),"ax",@progbits +-#if VEC_SIZE == 16 && IS_IN (libc) +-ENTRY (__bzero) +- mov %RDI_LP, %RAX_LP /* Set return value. */ +- mov %RSI_LP, %RDX_LP /* Set n. */ +- xorl %esi, %esi +- pxor %XMM0, %XMM0 +- jmp L(entry_from_bzero) +-END (__bzero) +-weak_alias (__bzero, bzero) + #endif + + #if IS_IN (libc) +@@ -123,12 +127,37 @@ ENTRY (WMEMSET_SYMBOL (__wmemset, unaligned)) + WMEMSET_SET_VEC0_AND_SET_RETURN (%esi, %rdi) + WMEMSET_VDUP_TO_VEC0_LOW() + cmpq $VEC_SIZE, %rdx +- jb L(less_vec_no_vdup) ++ jb L(less_vec_from_wmemset) + WMEMSET_VDUP_TO_VEC0_HIGH() + jmp L(entry_from_wmemset) + END (WMEMSET_SYMBOL (__wmemset, unaligned)) + #endif + ++ENTRY (BZERO_SYMBOL(__bzero, unaligned)) ++#if VEC_SIZE > 16 ++ BZERO_ZERO_VEC0 () ++#endif ++ mov %RDI_LP, %RAX_LP ++ mov %RSI_LP, %RDX_LP ++#ifndef USE_LESS_VEC_MASK_STORE ++ xorl %esi, %esi ++#endif ++ cmp $VEC_SIZE, %RDX_LP ++ jb L(less_vec_no_vdup) ++#ifdef USE_LESS_VEC_MASK_STORE ++ xorl %esi, %esi ++#endif ++#if VEC_SIZE <= 16 ++ BZERO_ZERO_VEC0 () ++#endif ++ cmp $(VEC_SIZE * 2), %RDX_LP ++ ja L(more_2x_vec) ++ /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */ ++ VMOVU %VEC(0), (%rdi) ++ VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi, %rdx) ++ VZEROUPPER_RETURN ++END (BZERO_SYMBOL(__bzero, unaligned)) ++ + #if defined SHARED && IS_IN (libc) + ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned)) + cmp %RDX_LP, %RCX_LP +@@ -142,7 +171,6 @@ ENTRY (MEMSET_SYMBOL (__memset, unaligned)) + /* Clear the upper 32 bits. */ + mov %edx, %edx + # endif +-L(entry_from_bzero): + cmpq $VEC_SIZE, %rdx + jb L(less_vec) + MEMSET_VDUP_TO_VEC0_HIGH() +@@ -187,6 +215,31 @@ END (__memset_erms) + END (MEMSET_SYMBOL (__memset, erms)) + # endif + ++ENTRY_P2ALIGN (BZERO_SYMBOL(__bzero, unaligned_erms), 6) ++# if VEC_SIZE > 16 ++ BZERO_ZERO_VEC0 () ++# endif ++ mov %RDI_LP, %RAX_LP ++ mov %RSI_LP, %RDX_LP ++# ifndef USE_LESS_VEC_MASK_STORE ++ xorl %esi, %esi ++# endif ++ cmp $VEC_SIZE, %RDX_LP ++ jb L(less_vec_no_vdup) ++# ifdef USE_LESS_VEC_MASK_STORE ++ xorl %esi, %esi ++# endif ++# if VEC_SIZE <= 16 ++ BZERO_ZERO_VEC0 () ++# endif ++ cmp $(VEC_SIZE * 2), %RDX_LP ++ ja L(stosb_more_2x_vec) ++ /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */ ++ VMOVU %VEC(0), (%rdi) ++ VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi, %rdx) ++ VZEROUPPER_RETURN ++END (BZERO_SYMBOL(__bzero, unaligned_erms)) ++ + # if defined SHARED && IS_IN (libc) + ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms)) + cmp %RDX_LP, %RCX_LP +@@ -229,6 +282,7 @@ L(last_2x_vec): + .p2align 4,, 10 + L(less_vec): + L(less_vec_no_vdup): ++L(less_vec_from_wmemset): + /* Less than 1 VEC. */ + # if VEC_SIZE != 16 && VEC_SIZE != 32 && VEC_SIZE != 64 + # error Unsupported VEC_SIZE! +@@ -374,8 +428,11 @@ L(less_vec): + /* Broadcast esi to partial register (i.e VEC_SIZE == 32 broadcast to + xmm). This is only does anything for AVX2. */ + MEMSET_VDUP_TO_VEC0_LOW () ++L(less_vec_from_wmemset): ++#if VEC_SIZE > 16 + L(less_vec_no_vdup): + #endif ++#endif + L(cross_page): + #if VEC_SIZE > 32 + cmpl $32, %edx +@@ -386,7 +443,10 @@ L(cross_page): + jge L(between_16_31) + #endif + #ifndef USE_XMM_LESS_VEC +- MOVQ %XMM0, %rcx ++ MOVQ %XMM0, %SET_REG64 ++#endif ++#if VEC_SIZE <= 16 ++L(less_vec_no_vdup): + #endif + cmpl $8, %edx + jge L(between_8_15) +@@ -395,7 +455,7 @@ L(cross_page): + cmpl $1, %edx + jg L(between_2_3) + jl L(between_0_0) +- movb %sil, (%LESS_VEC_REG) ++ movb %SET_REG8, (%LESS_VEC_REG) + L(between_0_0): + ret + +@@ -428,8 +488,8 @@ L(between_8_15): + MOVQ %XMM0, (%rdi) + MOVQ %XMM0, -8(%rdi, %rdx) + #else +- movq %rcx, (%LESS_VEC_REG) +- movq %rcx, -8(%LESS_VEC_REG, %rdx) ++ movq %SET_REG64, (%LESS_VEC_REG) ++ movq %SET_REG64, -8(%LESS_VEC_REG, %rdx) + #endif + ret + +@@ -442,8 +502,8 @@ L(between_4_7): + MOVD %XMM0, (%rdi) + MOVD %XMM0, -4(%rdi, %rdx) + #else +- movl %ecx, (%LESS_VEC_REG) +- movl %ecx, -4(%LESS_VEC_REG, %rdx) ++ movl %SET_REG32, (%LESS_VEC_REG) ++ movl %SET_REG32, -4(%LESS_VEC_REG, %rdx) + #endif + ret + +@@ -452,12 +512,12 @@ L(between_4_7): + L(between_2_3): + /* From 2 to 3. No branch when size == 2. */ + #ifdef USE_XMM_LESS_VEC +- movb %sil, (%rdi) +- movb %sil, 1(%rdi) +- movb %sil, -1(%rdi, %rdx) ++ movb %SET_REG8, (%rdi) ++ movb %SET_REG8, 1(%rdi) ++ movb %SET_REG8, -1(%rdi, %rdx) + #else +- movw %cx, (%LESS_VEC_REG) +- movb %sil, -1(%LESS_VEC_REG, %rdx) ++ movw %SET_REG16, (%LESS_VEC_REG) ++ movb %SET_REG8, -1(%LESS_VEC_REG, %rdx) + #endif + ret + END (MEMSET_SYMBOL (__memset, unaligned_erms)) diff --git a/SOURCES/glibc-upstream-2.34-208.patch b/SOURCES/glibc-upstream-2.34-208.patch new file mode 100644 index 0000000..d4d9b52 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-208.patch @@ -0,0 +1,29 @@ +commit 70509f9b4807295b2b4b43bffe110580fc0381ef +Author: Noah Goldstein +Date: Sat Feb 12 00:45:00 2022 -0600 + + x86: Set .text section in memset-vec-unaligned-erms + + commit 3d9f171bfb5325bd5f427e9fc386453358c6e840 + Author: H.J. Lu + Date: Mon Feb 7 05:55:15 2022 -0800 + + x86-64: Optimize bzero + + Remove setting the .text section for the code. This commit + adds that back. + + (cherry picked from commit 7912236f4a597deb092650ca79f33504ddb4af28) + +diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +index 39a096a594ccb5b6..d9c577fb5ff9700f 100644 +--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +@@ -114,6 +114,7 @@ + # error SECTION is not defined! + #endif + ++ .section SECTION(.text), "ax", @progbits + #if IS_IN (libc) + # if defined SHARED + ENTRY_CHK (WMEMSET_CHK_SYMBOL (__wmemset_chk, unaligned)) diff --git a/SOURCES/glibc-upstream-2.34-209.patch b/SOURCES/glibc-upstream-2.34-209.patch new file mode 100644 index 0000000..4874143 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-209.patch @@ -0,0 +1,76 @@ +commit 5373c90f2ea3c3fa9931a684c9b81c648dfbe8d7 +Author: Noah Goldstein +Date: Tue Feb 15 20:27:21 2022 -0600 + + x86: Fix bug in strncmp-evex and strncmp-avx2 [BZ #28895] + + Logic can read before the start of `s1` / `s2` if both `s1` and `s2` + are near the start of a page. To avoid having the result contimated by + these comparisons the `strcmp` variants would mask off these + comparisons. This was missing in the `strncmp` variants causing + the bug. This commit adds the masking to `strncmp` so that out of + range comparisons don't affect the result. + + test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass as + well a full xcheck on x86_64 linux. + Reviewed-by: H.J. Lu + + (cherry picked from commit e108c02a5e23c8c88ce66d8705d4a24bb6b9a8bf) + +diff --git a/string/test-strncmp.c b/string/test-strncmp.c +index 97e831d88fd24316..56e23670ae7f90e4 100644 +--- a/string/test-strncmp.c ++++ b/string/test-strncmp.c +@@ -438,13 +438,23 @@ check3 (void) + static void + check4 (void) + { +- const CHAR *s1 = L ("abc"); +- CHAR *s2 = STRDUP (s1); ++ /* To trigger bug 28895; We need 1) both s1 and s2 to be within 32 bytes of ++ the end of the page. 2) For there to be no mismatch/null byte before the ++ first page cross. 3) For length (`n`) to be large enough for one string to ++ cross the page. And 4) for there to be either mismatch/null bytes before ++ the start of the strings. */ ++ ++ size_t size = 10; ++ size_t addr_mask = (getpagesize () - 1) ^ (sizeof (CHAR) - 1); ++ CHAR *s1 = (CHAR *)(buf1 + (addr_mask & 0xffa)); ++ CHAR *s2 = (CHAR *)(buf2 + (addr_mask & 0xfed)); ++ int exp_result; + ++ STRCPY (s1, L ("tst-tlsmod%")); ++ STRCPY (s2, L ("tst-tls-manydynamic73mod")); ++ exp_result = SIMPLE_STRNCMP (s1, s2, size); + FOR_EACH_IMPL (impl, 0) +- check_result (impl, s1, s2, SIZE_MAX, 0); +- +- free (s2); ++ check_result (impl, s1, s2, size, exp_result); + } + + int +diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S +index cdded412a70bad10..f9bdc5ccd03aa1f9 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S +@@ -661,6 +661,7 @@ L(ret8): + # ifdef USE_AS_STRNCMP + .p2align 4,, 10 + L(return_page_cross_end_check): ++ andl %r10d, %ecx + tzcntl %ecx, %ecx + leal -VEC_SIZE(%rax, %rcx), %ecx + cmpl %ecx, %edx +diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S +index ed56af8ecdad48b2..0dfa62bd149c02b4 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-evex.S ++++ b/sysdeps/x86_64/multiarch/strcmp-evex.S +@@ -689,6 +689,7 @@ L(ret8): + # ifdef USE_AS_STRNCMP + .p2align 4,, 10 + L(return_page_cross_end_check): ++ andl %r10d, %ecx + tzcntl %ecx, %ecx + leal -VEC_SIZE(%rax, %rcx, SIZE_OF_CHAR), %ecx + # ifdef USE_AS_WCSCMP diff --git a/SOURCES/glibc-upstream-2.34-21.patch b/SOURCES/glibc-upstream-2.34-21.patch new file mode 100644 index 0000000..16ddaef --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-21.patch @@ -0,0 +1,44 @@ +commit 433ec4f14a5753c7689c83c20c9972915c53c204 +Author: Aurelien Jarno +Date: Fri Sep 10 19:39:35 2021 +0200 + + posix: Fix attribute access mode on getcwd [BZ #27476] + + There is a GNU extension that allows to call getcwd(NULL, >0). It is + described in the documentation, but also directly in the unistd.h + header, just above the declaration. + + Therefore the attribute access mode added in commit 06febd8c6705 + is not correct. Drop it. + +diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h +index f0831386c7ddb574..622adeb2b28ed298 100644 +--- a/posix/bits/unistd.h ++++ b/posix/bits/unistd.h +@@ -199,10 +199,9 @@ __NTH (readlinkat (int __fd, const char *__restrict __path, + #endif + + extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen) +- __THROW __wur __attr_access ((__write_only__, 1, 2)); ++ __THROW __wur; + extern char *__REDIRECT_NTH (__getcwd_alias, +- (char *__buf, size_t __size), getcwd) +- __wur __attr_access ((__write_only__, 1, 2)); ++ (char *__buf, size_t __size), getcwd) __wur; + extern char *__REDIRECT_NTH (__getcwd_chk_warn, + (char *__buf, size_t __size, size_t __buflen), + __getcwd_chk) +diff --git a/posix/unistd.h b/posix/unistd.h +index 3dca65732fdde52f..8224c5fbc956306f 100644 +--- a/posix/unistd.h ++++ b/posix/unistd.h +@@ -528,8 +528,7 @@ extern int fchdir (int __fd) __THROW __wur; + an array is allocated with `malloc'; the array is SIZE + bytes long, unless SIZE == 0, in which case it is as + big as necessary. */ +-extern char *getcwd (char *__buf, size_t __size) __THROW __wur +- __attr_access ((__write_only__, 1, 2)); ++extern char *getcwd (char *__buf, size_t __size) __THROW __wur; + + #ifdef __USE_GNU + /* Return a malloc'd string containing the current directory name. diff --git a/SOURCES/glibc-upstream-2.34-210.patch b/SOURCES/glibc-upstream-2.34-210.patch new file mode 100644 index 0000000..4898d45 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-210.patch @@ -0,0 +1,71 @@ +commit e123f08ad5ea4691bc37430ce536988c221332d6 +Author: Noah Goldstein +Date: Thu Mar 24 15:50:33 2022 -0500 + + x86: Fix fallback for wcsncmp_avx2 in strcmp-avx2.S [BZ #28896] + + Overflow case for __wcsncmp_avx2_rtm should be __wcscmp_avx2_rtm not + __wcscmp_avx2. + + commit ddf0992cf57a93200e0c782e2a94d0733a5a0b87 + Author: Noah Goldstein + Date: Sun Jan 9 16:02:21 2022 -0600 + + x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755] + + Set the wrong fallback function for `__wcsncmp_avx2_rtm`. It was set + to fallback on to `__wcscmp_avx2` instead of `__wcscmp_avx2_rtm` which + can cause spurious aborts. + + This change will need to be backported. + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit 9fef7039a7d04947bc89296ee0d187bc8d89b772) + +diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c +index aef9866cf2fbe774..ba6543be8ce13927 100644 +--- a/sysdeps/x86/tst-strncmp-rtm.c ++++ b/sysdeps/x86/tst-strncmp-rtm.c +@@ -70,6 +70,16 @@ function_overflow (void) + return 1; + } + ++__attribute__ ((noinline, noclone)) ++static int ++function_overflow2 (void) ++{ ++ if (STRNCMP (string1, string2, SIZE_MAX >> 4) == 0) ++ return 0; ++ else ++ return 1; ++} ++ + static int + do_test (void) + { +@@ -77,5 +87,10 @@ do_test (void) + if (status != EXIT_SUCCESS) + return status; + status = do_test_1 (TEST_NAME, LOOP, prepare, function_overflow); ++ if (status != EXIT_SUCCESS) ++ return status; ++ status = do_test_1 (TEST_NAME, LOOP, prepare, function_overflow2); ++ if (status != EXIT_SUCCESS) ++ return status; + return status; + } +diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S +index f9bdc5ccd03aa1f9..09a73942086f9c9f 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S +@@ -122,7 +122,7 @@ ENTRY(STRCMP) + are cases where length is large enough that it can never be a + bound on valid memory so just use wcscmp. */ + shrq $56, %rcx +- jnz __wcscmp_avx2 ++ jnz OVERFLOW_STRCMP + + leaq (, %rdx, 4), %rdx + # endif diff --git a/SOURCES/glibc-upstream-2.34-211.patch b/SOURCES/glibc-upstream-2.34-211.patch new file mode 100644 index 0000000..1221458 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-211.patch @@ -0,0 +1,170 @@ +commit e4a2fb76efb45210c541ee3f8ef32f317783c3a8 +Author: Florian Weimer +Date: Wed May 11 20:30:49 2022 +0200 + + manual: Document the dlinfo function + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 93804a1ee084d4bdc620b2b9f91615c7da0fabe1) + + Also includes partial backport of commit 5d28a8962dcb6ec056b81d730e + (the addition of manual/dynlink.texi). + +diff --git a/manual/Makefile b/manual/Makefile +index e83444341e282916..31678681ef059e0f 100644 +--- a/manual/Makefile ++++ b/manual/Makefile +@@ -39,7 +39,7 @@ chapters = $(addsuffix .texi, \ + pipe socket terminal syslog math arith time \ + resource setjmp signal startup process ipc job \ + nss users sysinfo conf crypt debug threads \ +- probes tunables) ++ dynlink probes tunables) + appendices = lang.texi header.texi install.texi maint.texi platform.texi \ + contrib.texi + licenses = freemanuals.texi lgpl-2.1.texi fdl-1.3.texi +diff --git a/manual/dynlink.texi b/manual/dynlink.texi +new file mode 100644 +index 0000000000000000..dbf3de11769d8e57 +--- /dev/null ++++ b/manual/dynlink.texi +@@ -0,0 +1,100 @@ ++@node Dynamic Linker ++@c @node Dynamic Linker, Internal Probes, Threads, Top ++@c %MENU% Loading programs and shared objects. ++@chapter Dynamic Linker ++@cindex dynamic linker ++@cindex dynamic loader ++ ++The @dfn{dynamic linker} is responsible for loading dynamically linked ++programs and their dependencies (in the form of shared objects). The ++dynamic linker in @theglibc{} also supports loading shared objects (such ++as plugins) later at run time. ++ ++Dynamic linkers are sometimes called @dfn{dynamic loaders}. ++ ++@menu ++* Dynamic Linker Introspection:: Interfaces for querying mapping information. ++@end menu ++ ++@node Dynamic Linker Introspection ++@section Dynamic Linker Introspection ++ ++@Theglibc{} provides various functions for querying information from the ++dynamic linker. ++ ++@deftypefun {int} dlinfo (void *@var{handle}, int @var{request}, void *@var{arg}) ++@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++@standards{GNU, dlfcn.h} ++This function returns information about @var{handle} in the memory ++location @var{arg}, based on @var{request}. The @var{handle} argument ++must be a pointer returned by @code{dlopen} or @code{dlmopen}; it must ++not have been closed by @code{dlclose}. ++ ++On success, @code{dlinfo} returns 0. If there is an error, the function ++returns @math{-1}, and @code{dlerror} can be used to obtain a ++corresponding error message. ++ ++The following operations are defined for use with @var{request}: ++ ++@vtable @code ++@item RTLD_DI_LINKMAP ++The corresponding @code{struct link_map} pointer for @var{handle} is ++written to @code{*@var{arg}}. The @var{arg} argument must be the ++address of an object of type @code{struct link_map *}. ++ ++@item RTLD_DI_LMID ++The namespace identifier of @var{handle} is written to ++@code{*@var{arg}}. The @var{arg} argument must be the address of an ++object of type @code{Lmid_t}. ++ ++@item RTLD_DI_ORIGIN ++The value of the @code{$ORIGIN} dynamic string token for @var{handle} is ++written to the character array starting at @var{arg} as a ++null-terminated string. ++ ++This request type should not be used because it is prone to buffer ++overflows. ++ ++@item RTLD_DI_SERINFO ++@itemx RTLD_DI_SERINFOSIZE ++These requests can be used to obtain search path information for ++@var{handle}. For both requests, @var{arg} must point to a ++@code{Dl_serinfo} object. The @code{RTLD_DI_SERINFOSIZE} request must ++be made first; it updates the @code{dls_size} and @code{dls_cnt} members ++of the @code{Dl_serinfo} object. The caller should then allocate memory ++to store at least @code{dls_size} bytes and pass that buffer to a ++@code{RTLD_DI_SERINFO} request. This second request fills the ++@code{dls_serpath} array. The number of array elements was returned in ++the @code{dls_cnt} member in the initial @code{RTLD_DI_SERINFOSIZE} ++request. The caller is responsible for freeing the allocated buffer. ++ ++This interface is prone to buffer overflows in multi-threaded processes ++because the required size can change between the ++@code{RTLD_DI_SERINFOSIZE} and @code{RTLD_DI_SERINFO} requests. ++ ++@item RTLD_DI_TLS_DATA ++This request writes the address of the TLS block (in the current thread) ++for the shared object identified by @var{handle} to @code{*@var{arg}}. ++The argument @var{arg} must be the address of an object of type ++@code{void *}. A null pointer is written if the object does not have ++any associated TLS block. ++ ++@item RTLD_DI_TLS_MODID ++This request writes the TLS module ID for the shared object @var{handle} ++to @code{*@var{arg}}. The argument @var{arg} must be the address of an ++object of type @code{size_t}. The module ID is zero if the object ++does not have an associated TLS block. ++@end vtable ++ ++The @code{dlinfo} function is a GNU extension. ++@end deftypefun ++ ++@c FIXME these are undocumented: ++@c dladdr ++@c dladdr1 ++@c dlclose ++@c dlerror ++@c dlmopen ++@c dlopen ++@c dlsym ++@c dlvsym +diff --git a/manual/libdl.texi b/manual/libdl.texi +deleted file mode 100644 +index e3fe0452d9f41d47..0000000000000000 +--- a/manual/libdl.texi ++++ /dev/null +@@ -1,10 +0,0 @@ +-@c FIXME these are undocumented: +-@c dladdr +-@c dladdr1 +-@c dlclose +-@c dlerror +-@c dlinfo +-@c dlmopen +-@c dlopen +-@c dlsym +-@c dlvsym +diff --git a/manual/probes.texi b/manual/probes.texi +index 4aae76b81921f347..ee019e651706f492 100644 +--- a/manual/probes.texi ++++ b/manual/probes.texi +@@ -1,5 +1,5 @@ + @node Internal Probes +-@c @node Internal Probes, Tunables, Threads, Top ++@c @node Internal Probes, Tunables, Dynamic Linker, Top + @c %MENU% Probes to monitor libc internal behavior + @chapter Internal probes + +diff --git a/manual/threads.texi b/manual/threads.texi +index 06b6b277a1228af1..7f166bfa87e88c36 100644 +--- a/manual/threads.texi ++++ b/manual/threads.texi +@@ -1,5 +1,5 @@ + @node Threads +-@c @node Threads, Internal Probes, Debugging Support, Top ++@c @node Threads, Dynamic Linker, Debugging Support, Top + @c %MENU% Functions, constants, and data types for working with threads + @chapter Threads + @cindex threads diff --git a/SOURCES/glibc-upstream-2.34-212.patch b/SOURCES/glibc-upstream-2.34-212.patch new file mode 100644 index 0000000..000023f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-212.patch @@ -0,0 +1,256 @@ +commit 91c2e6c3db44297bf4cb3a2e3c40236c5b6a0b23 +Author: Florian Weimer +Date: Fri Apr 29 17:00:53 2022 +0200 + + dlfcn: Implement the RTLD_DI_PHDR request type for dlinfo + + The information is theoretically available via dl_iterate_phdr as + well, but that approach is very slow if there are many shared + objects. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit d056c212130280c0a54d9a4f72170ec621b70ce5) + +diff --git a/dlfcn/Makefile b/dlfcn/Makefile +index 6bbfbb8344da05cb..d3965427dabed898 100644 +--- a/dlfcn/Makefile ++++ b/dlfcn/Makefile +@@ -73,6 +73,10 @@ tststatic3-ENV = $(tststatic-ENV) + tststatic4-ENV = $(tststatic-ENV) + tststatic5-ENV = $(tststatic-ENV) + ++tests-internal += \ ++ tst-dlinfo-phdr \ ++ # tests-internal ++ + ifneq (,$(CXX)) + modules-names += bug-atexit3-lib + else +diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h +index 4a3b870a487ea789..24388cfedae4dd67 100644 +--- a/dlfcn/dlfcn.h ++++ b/dlfcn/dlfcn.h +@@ -162,7 +162,12 @@ enum + segment, or if the calling thread has not allocated a block for it. */ + RTLD_DI_TLS_DATA = 10, + +- RTLD_DI_MAX = 10 ++ /* Treat ARG as const ElfW(Phdr) **, and store the address of the ++ program header array at that location. The dlinfo call returns ++ the number of program headers in the array. */ ++ RTLD_DI_PHDR = 11, ++ ++ RTLD_DI_MAX = 11 + }; + + +diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c +index 47d2daa96fa5986f..1842925fb7c594dd 100644 +--- a/dlfcn/dlinfo.c ++++ b/dlfcn/dlinfo.c +@@ -28,6 +28,10 @@ struct dlinfo_args + void *handle; + int request; + void *arg; ++ ++ /* This is the value that is returned from dlinfo if no error is ++ signaled. */ ++ int result; + }; + + static void +@@ -40,6 +44,7 @@ dlinfo_doit (void *argsblock) + { + case RTLD_DI_CONFIGADDR: + default: ++ args->result = -1; + _dl_signal_error (0, NULL, NULL, N_("unsupported dlinfo request")); + break; + +@@ -75,6 +80,11 @@ dlinfo_doit (void *argsblock) + *(void **) args->arg = data; + break; + } ++ ++ case RTLD_DI_PHDR: ++ *(const ElfW(Phdr) **) args->arg = l->l_phdr; ++ args->result = l->l_phnum; ++ break; + } + } + +@@ -82,7 +92,8 @@ static int + dlinfo_implementation (void *handle, int request, void *arg) + { + struct dlinfo_args args = { handle, request, arg }; +- return _dlerror_run (&dlinfo_doit, &args) ? -1 : 0; ++ _dlerror_run (&dlinfo_doit, &args); ++ return args.result; + } + + #ifdef SHARED +diff --git a/dlfcn/tst-dlinfo-phdr.c b/dlfcn/tst-dlinfo-phdr.c +new file mode 100644 +index 0000000000000000..a15a7d48ebd3b976 +--- /dev/null ++++ b/dlfcn/tst-dlinfo-phdr.c +@@ -0,0 +1,125 @@ ++/* Test for dlinfo (RTLD_DI_PHDR). ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* Used to verify that the program header array appears as expected ++ among the dl_iterate_phdr callback invocations. */ ++ ++struct dlip_callback_args ++{ ++ struct link_map *l; /* l->l_addr is used to find the object. */ ++ const ElfW(Phdr) *phdr; /* Expected program header pointed. */ ++ int phnum; /* Expected program header count. */ ++ bool found; /* True if l->l_addr has been found. */ ++}; ++ ++static int ++dlip_callback (struct dl_phdr_info *dlpi, size_t size, void *closure) ++{ ++ TEST_COMPARE (sizeof (*dlpi), size); ++ struct dlip_callback_args *args = closure; ++ ++ if (dlpi->dlpi_addr == args->l->l_addr) ++ { ++ TEST_VERIFY (!args->found); ++ args->found = true; ++ TEST_VERIFY (args->phdr == dlpi->dlpi_phdr); ++ TEST_COMPARE (args->phnum, dlpi->dlpi_phnum); ++ } ++ ++ return 0; ++} ++ ++static int ++do_test (void) ++{ ++ /* Avoid a copy relocation. */ ++ struct r_debug *debug = xdlsym (RTLD_DEFAULT, "_r_debug"); ++ struct link_map *l = (struct link_map *) debug->r_map; ++ TEST_VERIFY_EXIT (l != NULL); ++ ++ do ++ { ++ printf ("info: checking link map %p (%p) for \"%s\"\n", ++ l, l->l_phdr, l->l_name); ++ ++ /* Cause dlerror () to return an error message. */ ++ dlsym (RTLD_DEFAULT, "does-not-exist"); ++ ++ /* Use the extension that link maps are valid dlopen handles. */ ++ const ElfW(Phdr) *phdr; ++ int phnum = dlinfo (l, RTLD_DI_PHDR, &phdr); ++ TEST_VERIFY (phnum >= 0); ++ /* Verify that the error message has been cleared. */ ++ TEST_COMPARE_STRING (dlerror (), NULL); ++ ++ TEST_VERIFY (phdr == l->l_phdr); ++ TEST_COMPARE (phnum, l->l_phnum); ++ ++ /* Check that we can find PT_DYNAMIC among the array. */ ++ { ++ bool dynamic_found = false; ++ for (int i = 0; i < phnum; ++i) ++ if (phdr[i].p_type == PT_DYNAMIC) ++ { ++ dynamic_found = true; ++ TEST_COMPARE ((ElfW(Addr)) l->l_ld, l->l_addr + phdr[i].p_vaddr); ++ } ++ TEST_VERIFY (dynamic_found); ++ } ++ ++ /* Check that dl_iterate_phdr finds the link map with the same ++ program headers. */ ++ { ++ struct dlip_callback_args args = ++ { ++ .l = l, ++ .phdr = phdr, ++ .phnum = phnum, ++ .found = false, ++ }; ++ TEST_COMPARE (dl_iterate_phdr (dlip_callback, &args), 0); ++ TEST_VERIFY (args.found); ++ } ++ ++ if (l->l_prev == NULL) ++ { ++ /* This is the executable, so the information is also ++ available via getauxval. */ ++ TEST_COMPARE_STRING (l->l_name, ""); ++ TEST_VERIFY (phdr == (const ElfW(Phdr) *) getauxval (AT_PHDR)); ++ TEST_COMPARE (phnum, getauxval (AT_PHNUM)); ++ } ++ ++ l = l->l_next; ++ } ++ while (l != NULL); ++ ++ return 0; ++} ++ ++#include +diff --git a/manual/dynlink.texi b/manual/dynlink.texi +index dbf3de11769d8e57..7dcac64889e389fd 100644 +--- a/manual/dynlink.texi ++++ b/manual/dynlink.texi +@@ -30,9 +30,9 @@ location @var{arg}, based on @var{request}. The @var{handle} argument + must be a pointer returned by @code{dlopen} or @code{dlmopen}; it must + not have been closed by @code{dlclose}. + +-On success, @code{dlinfo} returns 0. If there is an error, the function +-returns @math{-1}, and @code{dlerror} can be used to obtain a +-corresponding error message. ++On success, @code{dlinfo} returns 0 for most request types; exceptions ++are noted below. If there is an error, the function returns @math{-1}, ++and @code{dlerror} can be used to obtain a corresponding error message. + + The following operations are defined for use with @var{request}: + +@@ -84,6 +84,15 @@ This request writes the TLS module ID for the shared object @var{handle} + to @code{*@var{arg}}. The argument @var{arg} must be the address of an + object of type @code{size_t}. The module ID is zero if the object + does not have an associated TLS block. ++ ++@item RTLD_DI_PHDR ++This request writes the address of the program header array to ++@code{*@var{arg}}. The argument @var{arg} must be the address of an ++object of type @code{const ElfW(Phdr) *} (that is, ++@code{const Elf32_Phdr *} or @code{const Elf64_Phdr *}, as appropriate ++for the current architecture). For this request, the value returned by ++@code{dlinfo} is the number of program headers in the program header ++array. + @end vtable + + The @code{dlinfo} function is a GNU extension. diff --git a/SOURCES/glibc-upstream-2.34-213.patch b/SOURCES/glibc-upstream-2.34-213.patch new file mode 100644 index 0000000..544f599 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-213.patch @@ -0,0 +1,31 @@ +commit b72bbba23687ed67887d1d18c51cce5cc9c575ca +Author: Siddhesh Poyarekar +Date: Fri May 13 10:01:47 2022 +0530 + + fortify: Ensure that __glibc_fortify condition is a constant [BZ #29141] + + The fix c8ee1c85 introduced a -1 check for object size without also + checking that object size is a constant. Because of this, the tree + optimizer passes in gcc fail to fold away one of the branches in + __glibc_fortify and trips on a spurious Wstringop-overflow. The warning + itself is incorrect and the branch does go away eventually in DCE in the + rtl passes in gcc, but the constant check is a helpful hint to simplify + code early, so add it in. + + Resolves: BZ #29141 + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 61a87530108ec9181e1b18a9b727ec3cc3ba7532) + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index b36013b9a6b4d9c3..e0ecd9147ee3ce48 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -163,7 +163,7 @@ + /* Length is known to be safe at compile time if the __L * __S <= __OBJSZ + condition can be folded to a constant and if it is true, or unknown (-1) */ + #define __glibc_safe_or_unknown_len(__l, __s, __osz) \ +- ((__osz) == (__SIZE_TYPE__) -1 \ ++ ((__builtin_constant_p (__osz) && (__osz) == (__SIZE_TYPE__) -1) \ + || (__glibc_unsigned_or_positive (__l) \ + && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ + (__s), (__osz))) \ diff --git a/SOURCES/glibc-upstream-2.34-214.patch b/SOURCES/glibc-upstream-2.34-214.patch new file mode 100644 index 0000000..d51a006 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-214.patch @@ -0,0 +1,22 @@ +commit 8de6e4a199ba6cc8aaeb43924b974eed67164bd6 +Author: H.J. Lu +Date: Sat Feb 5 11:06:01 2022 -0800 + + x86: Improve L to support L(XXX_SYMBOL (YYY, ZZZ)) + + (cherry picked from commit 1283948f236f209b7d3f44b69a42b96806fa6da0) + +diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h +index 937180c1bd791570..deda1c4e492f6176 100644 +--- a/sysdeps/x86/sysdep.h ++++ b/sysdeps/x86/sysdep.h +@@ -111,7 +111,8 @@ enum cf_protection_level + /* Local label name for asm code. */ + #ifndef L + /* ELF-like local names start with `.L'. */ +-# define L(name) .L##name ++# define LOCAL_LABEL(name) .L##name ++# define L(name) LOCAL_LABEL(name) + #endif + + #define atom_text_section .section ".text.atom", "ax" diff --git a/SOURCES/glibc-upstream-2.34-215.patch b/SOURCES/glibc-upstream-2.34-215.patch new file mode 100644 index 0000000..d33cace --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-215.patch @@ -0,0 +1,98 @@ +commit 6cba46c85804988f4fd41ef03e8a170a4c987a86 +Author: H.J. Lu +Date: Sat Feb 5 11:52:33 2022 -0800 + + x86_64/multiarch: Sort sysdep_routines and put one entry per line + + (cherry picked from commit c328d0152d4b14cca58407ec68143894c8863004) + +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index 37d8d6f0bd2d10cc..8c9e7812c6af10b8 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -132,37 +132,55 @@ CFLAGS-strspn-c.c += -msse4 + endif + + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c \ +- wmemcmp-avx2-movbe \ +- wmemchr-sse2 wmemchr-avx2 \ +- wcscmp-sse2 wcscmp-avx2 \ +- wcsncmp-sse2 wcsncmp-avx2 \ +- wcscpy-ssse3 wcscpy-c \ +- wcschr-sse2 wcschr-avx2 \ +- wcsrchr-sse2 wcsrchr-avx2 \ +- wcslen-sse2 wcslen-sse4_1 wcslen-avx2 \ +- wcsnlen-c wcsnlen-sse4_1 wcsnlen-avx2 \ +- wcschr-avx2-rtm \ +- wcscmp-avx2-rtm \ +- wcslen-avx2-rtm \ +- wcsncmp-avx2-rtm \ +- wcsnlen-avx2-rtm \ +- wcsrchr-avx2-rtm \ +- wmemchr-avx2-rtm \ +- wmemcmp-avx2-movbe-rtm \ +- wcschr-evex \ +- wcscmp-evex \ +- wcslen-evex \ +- wcsncmp-evex \ +- wcsnlen-evex \ +- wcsrchr-evex \ +- wmemchr-evex \ +- wmemcmp-evex-movbe \ +- wmemchr-evex-rtm ++sysdep_routines += \ ++ wcschr-avx2 \ ++ wcschr-avx2-rtm \ ++ wcschr-evex \ ++ wcschr-sse2 \ ++ wcscmp-avx2 \ ++ wcscmp-avx2-rtm \ ++ wcscmp-evex \ ++ wcscmp-sse2 \ ++ wcscpy-c \ ++ wcscpy-ssse3 \ ++ wcslen-avx2 \ ++ wcslen-avx2-rtm \ ++ wcslen-evex \ ++ wcslen-sse2 \ ++ wcslen-sse4_1 \ ++ wcsncmp-avx2 \ ++ wcsncmp-avx2-rtm \ ++ wcsncmp-evex \ ++ wcsncmp-sse2 \ ++ wcsnlen-avx2 \ ++ wcsnlen-avx2-rtm \ ++ wcsnlen-c \ ++ wcsnlen-evex \ ++ wcsnlen-sse4_1 \ ++ wcsrchr-avx2 \ ++ wcsrchr-avx2-rtm \ ++ wcsrchr-evex \ ++ wcsrchr-sse2 \ ++ wmemchr-avx2 \ ++ wmemchr-avx2-rtm \ ++ wmemchr-evex \ ++ wmemchr-evex-rtm \ ++ wmemchr-sse2 \ ++ wmemcmp-avx2-movbe \ ++ wmemcmp-avx2-movbe-rtm \ ++ wmemcmp-c \ ++ wmemcmp-evex-movbe \ ++ wmemcmp-sse4 \ ++ wmemcmp-ssse3 \ ++# sysdep_routines + endif + + ifeq ($(subdir),debug) +-sysdep_routines += memcpy_chk-nonshared mempcpy_chk-nonshared \ +- memmove_chk-nonshared memset_chk-nonshared \ +- wmemset_chk-nonshared ++sysdep_routines += \ ++ memcpy_chk-nonshared \ ++ memmove_chk-nonshared \ ++ mempcpy_chk-nonshared \ ++ memset_chk-nonshared \ ++ wmemset_chk-nonshared \ ++# sysdep_routines + endif diff --git a/SOURCES/glibc-upstream-2.34-216.patch b/SOURCES/glibc-upstream-2.34-216.patch new file mode 100644 index 0000000..b1e36ab --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-216.patch @@ -0,0 +1,32 @@ +commit 37f373e33496ea437cc7e375cc835c20d4b35fb2 +Author: H.J. Lu +Date: Thu Feb 10 11:52:50 2022 -0800 + + x86-64: Remove bzero weak alias in SS2 memset + + commit 3d9f171bfb5325bd5f427e9fc386453358c6e840 + Author: H.J. Lu + Date: Mon Feb 7 05:55:15 2022 -0800 + + x86-64: Optimize bzero + + added the optimized bzero. Remove bzero weak alias in SS2 memset to + avoid undefined __bzero in memset-sse2-unaligned-erms. + + (cherry picked from commit 0fb8800029d230b3711bf722b2a47db92d0e273f) + +diff --git a/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S +index bac74ac37fd3c144..2951f7f5f70e274a 100644 +--- a/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S +@@ -31,9 +31,7 @@ + # endif + + # undef weak_alias +-# define weak_alias(original, alias) \ +- .weak bzero; bzero = __bzero +- ++# define weak_alias(original, alias) + # undef strong_alias + # define strong_alias(ignored1, ignored2) + #endif diff --git a/SOURCES/glibc-upstream-2.34-217.patch b/SOURCES/glibc-upstream-2.34-217.patch new file mode 100644 index 0000000..8f92420 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-217.patch @@ -0,0 +1,24 @@ +commit dd457606ca4583b4a5e83d4e8956e6f9db61df6d +Author: Adhemerval Zanella +Date: Thu Feb 10 11:23:24 2022 -0300 + + x86_64: Remove bcopy optimizations + + The symbols is not present in current POSIX specification and compiler + already generates memmove call. + + (cherry picked from commit bf92893a14ebc161b08b28acc24fa06ae6be19cb) + +diff --git a/sysdeps/x86_64/multiarch/bcopy.S b/sysdeps/x86_64/multiarch/bcopy.S +deleted file mode 100644 +index 639f02bde3ac3ed1..0000000000000000 +--- a/sysdeps/x86_64/multiarch/bcopy.S ++++ /dev/null +@@ -1,7 +0,0 @@ +-#include +- +- .text +-ENTRY(bcopy) +- xchg %rdi, %rsi +- jmp __libc_memmove /* Branch to IFUNC memmove. */ +-END(bcopy) diff --git a/SOURCES/glibc-upstream-2.34-218.patch b/SOURCES/glibc-upstream-2.34-218.patch new file mode 100644 index 0000000..312016b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-218.patch @@ -0,0 +1,367 @@ +commit 3c55c207564c0ae30d78d01689b4ae16bf38dd63 +Author: Noah Goldstein +Date: Wed Mar 23 16:57:16 2022 -0500 + + x86: Code cleanup in strchr-avx2 and comment justifying branch + + Small code cleanup for size: -53 bytes. + + Add comment justifying using a branch to do NULL/non-null return. + + All string/memory tests pass and no regressions in benchtests. + + geometric_mean(N=20) of all benchmarks Original / New: 1.00 + Reviewed-by: H.J. Lu + + (cherry picked from commit a6fbf4d51e9ba8063c4f8331564892ead9c67344) + +diff --git a/sysdeps/x86_64/multiarch/strchr-avx2.S b/sysdeps/x86_64/multiarch/strchr-avx2.S +index 413942b96a835c4a..ef4ce0f3677e30c8 100644 +--- a/sysdeps/x86_64/multiarch/strchr-avx2.S ++++ b/sysdeps/x86_64/multiarch/strchr-avx2.S +@@ -48,13 +48,13 @@ + # define PAGE_SIZE 4096 + + .section SECTION(.text),"ax",@progbits +-ENTRY (STRCHR) ++ENTRY_P2ALIGN (STRCHR, 5) + /* Broadcast CHAR to YMM0. */ + vmovd %esi, %xmm0 + movl %edi, %eax + andl $(PAGE_SIZE - 1), %eax + VPBROADCAST %xmm0, %ymm0 +- vpxor %xmm9, %xmm9, %xmm9 ++ vpxor %xmm1, %xmm1, %xmm1 + + /* Check if we cross page boundary with one vector load. */ + cmpl $(PAGE_SIZE - VEC_SIZE), %eax +@@ -62,37 +62,29 @@ ENTRY (STRCHR) + + /* Check the first VEC_SIZE bytes. Search for both CHAR and the + null byte. */ +- vmovdqu (%rdi), %ymm8 +- VPCMPEQ %ymm8, %ymm0, %ymm1 +- VPCMPEQ %ymm8, %ymm9, %ymm2 +- vpor %ymm1, %ymm2, %ymm1 +- vpmovmskb %ymm1, %eax ++ vmovdqu (%rdi), %ymm2 ++ VPCMPEQ %ymm2, %ymm0, %ymm3 ++ VPCMPEQ %ymm2, %ymm1, %ymm2 ++ vpor %ymm3, %ymm2, %ymm3 ++ vpmovmskb %ymm3, %eax + testl %eax, %eax + jz L(aligned_more) + tzcntl %eax, %eax + # ifndef USE_AS_STRCHRNUL +- /* Found CHAR or the null byte. */ +- cmp (%rdi, %rax), %CHAR_REG +- jne L(zero) +-# endif +- addq %rdi, %rax +- VZEROUPPER_RETURN +- +- /* .p2align 5 helps keep performance more consistent if ENTRY() +- alignment % 32 was either 16 or 0. As well this makes the +- alignment % 32 of the loop_4x_vec fixed which makes tuning it +- easier. */ +- .p2align 5 +-L(first_vec_x4): +- tzcntl %eax, %eax +- addq $(VEC_SIZE * 3 + 1), %rdi +-# ifndef USE_AS_STRCHRNUL +- /* Found CHAR or the null byte. */ ++ /* Found CHAR or the null byte. */ + cmp (%rdi, %rax), %CHAR_REG ++ /* NB: Use a branch instead of cmovcc here. The expectation is ++ that with strchr the user will branch based on input being ++ null. Since this branch will be 100% predictive of the user ++ branch a branch miss here should save what otherwise would ++ be branch miss in the user code. Otherwise using a branch 1) ++ saves code size and 2) is faster in highly predictable ++ environments. */ + jne L(zero) + # endif + addq %rdi, %rax +- VZEROUPPER_RETURN ++L(return_vzeroupper): ++ ZERO_UPPER_VEC_REGISTERS_RETURN + + # ifndef USE_AS_STRCHRNUL + L(zero): +@@ -103,7 +95,8 @@ L(zero): + + .p2align 4 + L(first_vec_x1): +- tzcntl %eax, %eax ++ /* Use bsf to save code size. */ ++ bsfl %eax, %eax + incq %rdi + # ifndef USE_AS_STRCHRNUL + /* Found CHAR or the null byte. */ +@@ -113,9 +106,10 @@ L(first_vec_x1): + addq %rdi, %rax + VZEROUPPER_RETURN + +- .p2align 4 ++ .p2align 4,, 10 + L(first_vec_x2): +- tzcntl %eax, %eax ++ /* Use bsf to save code size. */ ++ bsfl %eax, %eax + addq $(VEC_SIZE + 1), %rdi + # ifndef USE_AS_STRCHRNUL + /* Found CHAR or the null byte. */ +@@ -125,9 +119,10 @@ L(first_vec_x2): + addq %rdi, %rax + VZEROUPPER_RETURN + +- .p2align 4 ++ .p2align 4,, 8 + L(first_vec_x3): +- tzcntl %eax, %eax ++ /* Use bsf to save code size. */ ++ bsfl %eax, %eax + addq $(VEC_SIZE * 2 + 1), %rdi + # ifndef USE_AS_STRCHRNUL + /* Found CHAR or the null byte. */ +@@ -137,6 +132,21 @@ L(first_vec_x3): + addq %rdi, %rax + VZEROUPPER_RETURN + ++ .p2align 4,, 10 ++L(first_vec_x4): ++ /* Use bsf to save code size. */ ++ bsfl %eax, %eax ++ addq $(VEC_SIZE * 3 + 1), %rdi ++# ifndef USE_AS_STRCHRNUL ++ /* Found CHAR or the null byte. */ ++ cmp (%rdi, %rax), %CHAR_REG ++ jne L(zero) ++# endif ++ addq %rdi, %rax ++ VZEROUPPER_RETURN ++ ++ ++ + .p2align 4 + L(aligned_more): + /* Align data to VEC_SIZE - 1. This is the same number of +@@ -146,90 +156,92 @@ L(aligned_more): + L(cross_page_continue): + /* Check the next 4 * VEC_SIZE. Only one VEC_SIZE at a time + since data is only aligned to VEC_SIZE. */ +- vmovdqa 1(%rdi), %ymm8 +- VPCMPEQ %ymm8, %ymm0, %ymm1 +- VPCMPEQ %ymm8, %ymm9, %ymm2 +- vpor %ymm1, %ymm2, %ymm1 +- vpmovmskb %ymm1, %eax ++ vmovdqa 1(%rdi), %ymm2 ++ VPCMPEQ %ymm2, %ymm0, %ymm3 ++ VPCMPEQ %ymm2, %ymm1, %ymm2 ++ vpor %ymm3, %ymm2, %ymm3 ++ vpmovmskb %ymm3, %eax + testl %eax, %eax + jnz L(first_vec_x1) + +- vmovdqa (VEC_SIZE + 1)(%rdi), %ymm8 +- VPCMPEQ %ymm8, %ymm0, %ymm1 +- VPCMPEQ %ymm8, %ymm9, %ymm2 +- vpor %ymm1, %ymm2, %ymm1 +- vpmovmskb %ymm1, %eax ++ vmovdqa (VEC_SIZE + 1)(%rdi), %ymm2 ++ VPCMPEQ %ymm2, %ymm0, %ymm3 ++ VPCMPEQ %ymm2, %ymm1, %ymm2 ++ vpor %ymm3, %ymm2, %ymm3 ++ vpmovmskb %ymm3, %eax + testl %eax, %eax + jnz L(first_vec_x2) + +- vmovdqa (VEC_SIZE * 2 + 1)(%rdi), %ymm8 +- VPCMPEQ %ymm8, %ymm0, %ymm1 +- VPCMPEQ %ymm8, %ymm9, %ymm2 +- vpor %ymm1, %ymm2, %ymm1 +- vpmovmskb %ymm1, %eax ++ vmovdqa (VEC_SIZE * 2 + 1)(%rdi), %ymm2 ++ VPCMPEQ %ymm2, %ymm0, %ymm3 ++ VPCMPEQ %ymm2, %ymm1, %ymm2 ++ vpor %ymm3, %ymm2, %ymm3 ++ vpmovmskb %ymm3, %eax + testl %eax, %eax + jnz L(first_vec_x3) + +- vmovdqa (VEC_SIZE * 3 + 1)(%rdi), %ymm8 +- VPCMPEQ %ymm8, %ymm0, %ymm1 +- VPCMPEQ %ymm8, %ymm9, %ymm2 +- vpor %ymm1, %ymm2, %ymm1 +- vpmovmskb %ymm1, %eax ++ vmovdqa (VEC_SIZE * 3 + 1)(%rdi), %ymm2 ++ VPCMPEQ %ymm2, %ymm0, %ymm3 ++ VPCMPEQ %ymm2, %ymm1, %ymm2 ++ vpor %ymm3, %ymm2, %ymm3 ++ vpmovmskb %ymm3, %eax + testl %eax, %eax + jnz L(first_vec_x4) +- /* Align data to VEC_SIZE * 4 - 1. */ +- addq $(VEC_SIZE * 4 + 1), %rdi +- andq $-(VEC_SIZE * 4), %rdi ++ /* Align data to VEC_SIZE * 4 - 1. */ ++ incq %rdi ++ orq $(VEC_SIZE * 4 - 1), %rdi + .p2align 4 + L(loop_4x_vec): + /* Compare 4 * VEC at a time forward. */ +- vmovdqa (%rdi), %ymm5 +- vmovdqa (VEC_SIZE)(%rdi), %ymm6 +- vmovdqa (VEC_SIZE * 2)(%rdi), %ymm7 +- vmovdqa (VEC_SIZE * 3)(%rdi), %ymm8 ++ vmovdqa 1(%rdi), %ymm6 ++ vmovdqa (VEC_SIZE + 1)(%rdi), %ymm7 + + /* Leaves only CHARS matching esi as 0. */ +- vpxor %ymm5, %ymm0, %ymm1 + vpxor %ymm6, %ymm0, %ymm2 + vpxor %ymm7, %ymm0, %ymm3 +- vpxor %ymm8, %ymm0, %ymm4 + +- VPMINU %ymm1, %ymm5, %ymm1 + VPMINU %ymm2, %ymm6, %ymm2 + VPMINU %ymm3, %ymm7, %ymm3 +- VPMINU %ymm4, %ymm8, %ymm4 + +- VPMINU %ymm1, %ymm2, %ymm5 +- VPMINU %ymm3, %ymm4, %ymm6 ++ vmovdqa (VEC_SIZE * 2 + 1)(%rdi), %ymm6 ++ vmovdqa (VEC_SIZE * 3 + 1)(%rdi), %ymm7 ++ ++ vpxor %ymm6, %ymm0, %ymm4 ++ vpxor %ymm7, %ymm0, %ymm5 ++ ++ VPMINU %ymm4, %ymm6, %ymm4 ++ VPMINU %ymm5, %ymm7, %ymm5 + +- VPMINU %ymm5, %ymm6, %ymm6 ++ VPMINU %ymm2, %ymm3, %ymm6 ++ VPMINU %ymm4, %ymm5, %ymm7 + +- VPCMPEQ %ymm6, %ymm9, %ymm6 +- vpmovmskb %ymm6, %ecx ++ VPMINU %ymm6, %ymm7, %ymm7 ++ ++ VPCMPEQ %ymm7, %ymm1, %ymm7 ++ vpmovmskb %ymm7, %ecx + subq $-(VEC_SIZE * 4), %rdi + testl %ecx, %ecx + jz L(loop_4x_vec) + +- +- VPCMPEQ %ymm1, %ymm9, %ymm1 +- vpmovmskb %ymm1, %eax ++ VPCMPEQ %ymm2, %ymm1, %ymm2 ++ vpmovmskb %ymm2, %eax + testl %eax, %eax + jnz L(last_vec_x0) + + +- VPCMPEQ %ymm5, %ymm9, %ymm2 +- vpmovmskb %ymm2, %eax ++ VPCMPEQ %ymm3, %ymm1, %ymm3 ++ vpmovmskb %ymm3, %eax + testl %eax, %eax + jnz L(last_vec_x1) + +- VPCMPEQ %ymm3, %ymm9, %ymm3 +- vpmovmskb %ymm3, %eax ++ VPCMPEQ %ymm4, %ymm1, %ymm4 ++ vpmovmskb %ymm4, %eax + /* rcx has combined result from all 4 VEC. It will only be used + if the first 3 other VEC all did not contain a match. */ + salq $32, %rcx + orq %rcx, %rax + tzcntq %rax, %rax +- subq $(VEC_SIZE * 2), %rdi ++ subq $(VEC_SIZE * 2 - 1), %rdi + # ifndef USE_AS_STRCHRNUL + /* Found CHAR or the null byte. */ + cmp (%rdi, %rax), %CHAR_REG +@@ -239,10 +251,11 @@ L(loop_4x_vec): + VZEROUPPER_RETURN + + +- .p2align 4 ++ .p2align 4,, 10 + L(last_vec_x0): +- tzcntl %eax, %eax +- addq $-(VEC_SIZE * 4), %rdi ++ /* Use bsf to save code size. */ ++ bsfl %eax, %eax ++ addq $-(VEC_SIZE * 4 - 1), %rdi + # ifndef USE_AS_STRCHRNUL + /* Found CHAR or the null byte. */ + cmp (%rdi, %rax), %CHAR_REG +@@ -251,16 +264,11 @@ L(last_vec_x0): + addq %rdi, %rax + VZEROUPPER_RETURN + +-# ifndef USE_AS_STRCHRNUL +-L(zero_end): +- xorl %eax, %eax +- VZEROUPPER_RETURN +-# endif + +- .p2align 4 ++ .p2align 4,, 10 + L(last_vec_x1): + tzcntl %eax, %eax +- subq $(VEC_SIZE * 3), %rdi ++ subq $(VEC_SIZE * 3 - 1), %rdi + # ifndef USE_AS_STRCHRNUL + /* Found CHAR or the null byte. */ + cmp (%rdi, %rax), %CHAR_REG +@@ -269,18 +277,23 @@ L(last_vec_x1): + addq %rdi, %rax + VZEROUPPER_RETURN + ++# ifndef USE_AS_STRCHRNUL ++L(zero_end): ++ xorl %eax, %eax ++ VZEROUPPER_RETURN ++# endif + + /* Cold case for crossing page with first load. */ +- .p2align 4 ++ .p2align 4,, 8 + L(cross_page_boundary): + movq %rdi, %rdx + /* Align rdi to VEC_SIZE - 1. */ + orq $(VEC_SIZE - 1), %rdi +- vmovdqa -(VEC_SIZE - 1)(%rdi), %ymm8 +- VPCMPEQ %ymm8, %ymm0, %ymm1 +- VPCMPEQ %ymm8, %ymm9, %ymm2 +- vpor %ymm1, %ymm2, %ymm1 +- vpmovmskb %ymm1, %eax ++ vmovdqa -(VEC_SIZE - 1)(%rdi), %ymm2 ++ VPCMPEQ %ymm2, %ymm0, %ymm3 ++ VPCMPEQ %ymm2, %ymm1, %ymm2 ++ vpor %ymm3, %ymm2, %ymm3 ++ vpmovmskb %ymm3, %eax + /* Remove the leading bytes. sarxl only uses bits [5:0] of COUNT + so no need to manually mod edx. */ + sarxl %edx, %eax, %eax +@@ -291,13 +304,10 @@ L(cross_page_boundary): + xorl %ecx, %ecx + /* Found CHAR or the null byte. */ + cmp (%rdx, %rax), %CHAR_REG +- leaq (%rdx, %rax), %rax +- cmovne %rcx, %rax +-# else +- addq %rdx, %rax ++ jne L(zero_end) + # endif +-L(return_vzeroupper): +- ZERO_UPPER_VEC_REGISTERS_RETURN ++ addq %rdx, %rax ++ VZEROUPPER_RETURN + + END (STRCHR) +-# endif ++#endif diff --git a/SOURCES/glibc-upstream-2.34-219.patch b/SOURCES/glibc-upstream-2.34-219.patch new file mode 100644 index 0000000..654fb28 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-219.patch @@ -0,0 +1,338 @@ +commit dd6d3a0bbcc67cb2b50b0add0c599f9f99491d8b +Author: Noah Goldstein +Date: Wed Mar 23 16:57:18 2022 -0500 + + x86: Code cleanup in strchr-evex and comment justifying branch + + Small code cleanup for size: -81 bytes. + + Add comment justifying using a branch to do NULL/non-null return. + + All string/memory tests pass and no regressions in benchtests. + + geometric_mean(N=20) of all benchmarks New / Original: .985 + Reviewed-by: H.J. Lu + + (cherry picked from commit ec285ea90415458225623ddc0492ae3f705af043) + +diff --git a/sysdeps/x86_64/multiarch/strchr-evex.S b/sysdeps/x86_64/multiarch/strchr-evex.S +index 7f9d4ee48ddaa998..0b49e0ac54e7b0dd 100644 +--- a/sysdeps/x86_64/multiarch/strchr-evex.S ++++ b/sysdeps/x86_64/multiarch/strchr-evex.S +@@ -30,6 +30,7 @@ + # ifdef USE_AS_WCSCHR + # define VPBROADCAST vpbroadcastd + # define VPCMP vpcmpd ++# define VPTESTN vptestnmd + # define VPMINU vpminud + # define CHAR_REG esi + # define SHIFT_REG ecx +@@ -37,6 +38,7 @@ + # else + # define VPBROADCAST vpbroadcastb + # define VPCMP vpcmpb ++# define VPTESTN vptestnmb + # define VPMINU vpminub + # define CHAR_REG sil + # define SHIFT_REG edx +@@ -61,13 +63,11 @@ + # define CHAR_PER_VEC (VEC_SIZE / CHAR_SIZE) + + .section .text.evex,"ax",@progbits +-ENTRY (STRCHR) ++ENTRY_P2ALIGN (STRCHR, 5) + /* Broadcast CHAR to YMM0. */ + VPBROADCAST %esi, %YMM0 + movl %edi, %eax + andl $(PAGE_SIZE - 1), %eax +- vpxorq %XMMZERO, %XMMZERO, %XMMZERO +- + /* Check if we cross page boundary with one vector load. + Otherwise it is safe to use an unaligned load. */ + cmpl $(PAGE_SIZE - VEC_SIZE), %eax +@@ -81,49 +81,35 @@ ENTRY (STRCHR) + vpxorq %YMM1, %YMM0, %YMM2 + VPMINU %YMM2, %YMM1, %YMM2 + /* Each bit in K0 represents a CHAR or a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM2, %k0 ++ VPTESTN %YMM2, %YMM2, %k0 + kmovd %k0, %eax + testl %eax, %eax + jz L(aligned_more) + tzcntl %eax, %eax ++# ifndef USE_AS_STRCHRNUL ++ /* Found CHAR or the null byte. */ ++ cmp (%rdi, %rax, CHAR_SIZE), %CHAR_REG ++ /* NB: Use a branch instead of cmovcc here. The expectation is ++ that with strchr the user will branch based on input being ++ null. Since this branch will be 100% predictive of the user ++ branch a branch miss here should save what otherwise would ++ be branch miss in the user code. Otherwise using a branch 1) ++ saves code size and 2) is faster in highly predictable ++ environments. */ ++ jne L(zero) ++# endif + # ifdef USE_AS_WCSCHR + /* NB: Multiply wchar_t count by 4 to get the number of bytes. + */ + leaq (%rdi, %rax, CHAR_SIZE), %rax + # else + addq %rdi, %rax +-# endif +-# ifndef USE_AS_STRCHRNUL +- /* Found CHAR or the null byte. */ +- cmp (%rax), %CHAR_REG +- jne L(zero) + # endif + ret + +- /* .p2align 5 helps keep performance more consistent if ENTRY() +- alignment % 32 was either 16 or 0. As well this makes the +- alignment % 32 of the loop_4x_vec fixed which makes tuning it +- easier. */ +- .p2align 5 +-L(first_vec_x3): +- tzcntl %eax, %eax +-# ifndef USE_AS_STRCHRNUL +- /* Found CHAR or the null byte. */ +- cmp (VEC_SIZE * 3)(%rdi, %rax, CHAR_SIZE), %CHAR_REG +- jne L(zero) +-# endif +- /* NB: Multiply sizeof char type (1 or 4) to get the number of +- bytes. */ +- leaq (VEC_SIZE * 3)(%rdi, %rax, CHAR_SIZE), %rax +- ret + +-# ifndef USE_AS_STRCHRNUL +-L(zero): +- xorl %eax, %eax +- ret +-# endif + +- .p2align 4 ++ .p2align 4,, 10 + L(first_vec_x4): + # ifndef USE_AS_STRCHRNUL + /* Check to see if first match was CHAR (k0) or null (k1). */ +@@ -144,9 +130,18 @@ L(first_vec_x4): + leaq (VEC_SIZE * 4)(%rdi, %rax, CHAR_SIZE), %rax + ret + ++# ifndef USE_AS_STRCHRNUL ++L(zero): ++ xorl %eax, %eax ++ ret ++# endif ++ ++ + .p2align 4 + L(first_vec_x1): +- tzcntl %eax, %eax ++ /* Use bsf here to save 1-byte keeping keeping the block in 1x ++ fetch block. eax guranteed non-zero. */ ++ bsfl %eax, %eax + # ifndef USE_AS_STRCHRNUL + /* Found CHAR or the null byte. */ + cmp (VEC_SIZE)(%rdi, %rax, CHAR_SIZE), %CHAR_REG +@@ -158,7 +153,7 @@ L(first_vec_x1): + leaq (VEC_SIZE)(%rdi, %rax, CHAR_SIZE), %rax + ret + +- .p2align 4 ++ .p2align 4,, 10 + L(first_vec_x2): + # ifndef USE_AS_STRCHRNUL + /* Check to see if first match was CHAR (k0) or null (k1). */ +@@ -179,6 +174,21 @@ L(first_vec_x2): + leaq (VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %rax + ret + ++ .p2align 4,, 10 ++L(first_vec_x3): ++ /* Use bsf here to save 1-byte keeping keeping the block in 1x ++ fetch block. eax guranteed non-zero. */ ++ bsfl %eax, %eax ++# ifndef USE_AS_STRCHRNUL ++ /* Found CHAR or the null byte. */ ++ cmp (VEC_SIZE * 3)(%rdi, %rax, CHAR_SIZE), %CHAR_REG ++ jne L(zero) ++# endif ++ /* NB: Multiply sizeof char type (1 or 4) to get the number of ++ bytes. */ ++ leaq (VEC_SIZE * 3)(%rdi, %rax, CHAR_SIZE), %rax ++ ret ++ + .p2align 4 + L(aligned_more): + /* Align data to VEC_SIZE. */ +@@ -195,7 +205,7 @@ L(cross_page_continue): + vpxorq %YMM1, %YMM0, %YMM2 + VPMINU %YMM2, %YMM1, %YMM2 + /* Each bit in K0 represents a CHAR or a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM2, %k0 ++ VPTESTN %YMM2, %YMM2, %k0 + kmovd %k0, %eax + testl %eax, %eax + jnz L(first_vec_x1) +@@ -206,7 +216,7 @@ L(cross_page_continue): + /* Each bit in K0 represents a CHAR in YMM1. */ + VPCMP $0, %YMM1, %YMM0, %k0 + /* Each bit in K1 represents a CHAR in YMM1. */ +- VPCMP $0, %YMM1, %YMMZERO, %k1 ++ VPTESTN %YMM1, %YMM1, %k1 + kortestd %k0, %k1 + jnz L(first_vec_x2) + +@@ -215,7 +225,7 @@ L(cross_page_continue): + vpxorq %YMM1, %YMM0, %YMM2 + VPMINU %YMM2, %YMM1, %YMM2 + /* Each bit in K0 represents a CHAR or a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM2, %k0 ++ VPTESTN %YMM2, %YMM2, %k0 + kmovd %k0, %eax + testl %eax, %eax + jnz L(first_vec_x3) +@@ -224,7 +234,7 @@ L(cross_page_continue): + /* Each bit in K0 represents a CHAR in YMM1. */ + VPCMP $0, %YMM1, %YMM0, %k0 + /* Each bit in K1 represents a CHAR in YMM1. */ +- VPCMP $0, %YMM1, %YMMZERO, %k1 ++ VPTESTN %YMM1, %YMM1, %k1 + kortestd %k0, %k1 + jnz L(first_vec_x4) + +@@ -265,33 +275,33 @@ L(loop_4x_vec): + VPMINU %YMM3, %YMM4, %YMM4 + VPMINU %YMM2, %YMM4, %YMM4{%k4}{z} + +- VPCMP $0, %YMMZERO, %YMM4, %k1 ++ VPTESTN %YMM4, %YMM4, %k1 + kmovd %k1, %ecx + subq $-(VEC_SIZE * 4), %rdi + testl %ecx, %ecx + jz L(loop_4x_vec) + +- VPCMP $0, %YMMZERO, %YMM1, %k0 ++ VPTESTN %YMM1, %YMM1, %k0 + kmovd %k0, %eax + testl %eax, %eax + jnz L(last_vec_x1) + +- VPCMP $0, %YMMZERO, %YMM2, %k0 ++ VPTESTN %YMM2, %YMM2, %k0 + kmovd %k0, %eax + testl %eax, %eax + jnz L(last_vec_x2) + +- VPCMP $0, %YMMZERO, %YMM3, %k0 ++ VPTESTN %YMM3, %YMM3, %k0 + kmovd %k0, %eax + /* Combine YMM3 matches (eax) with YMM4 matches (ecx). */ + # ifdef USE_AS_WCSCHR + sall $8, %ecx + orl %ecx, %eax +- tzcntl %eax, %eax ++ bsfl %eax, %eax + # else + salq $32, %rcx + orq %rcx, %rax +- tzcntq %rax, %rax ++ bsfq %rax, %rax + # endif + # ifndef USE_AS_STRCHRNUL + /* Check if match was CHAR or null. */ +@@ -303,28 +313,28 @@ L(loop_4x_vec): + leaq (VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %rax + ret + +-# ifndef USE_AS_STRCHRNUL +-L(zero_end): +- xorl %eax, %eax +- ret ++ .p2align 4,, 8 ++L(last_vec_x1): ++ bsfl %eax, %eax ++# ifdef USE_AS_WCSCHR ++ /* NB: Multiply wchar_t count by 4 to get the number of bytes. ++ */ ++ leaq (%rdi, %rax, CHAR_SIZE), %rax ++# else ++ addq %rdi, %rax + # endif + +- .p2align 4 +-L(last_vec_x1): +- tzcntl %eax, %eax + # ifndef USE_AS_STRCHRNUL + /* Check if match was null. */ +- cmp (%rdi, %rax, CHAR_SIZE), %CHAR_REG ++ cmp (%rax), %CHAR_REG + jne L(zero_end) + # endif +- /* NB: Multiply sizeof char type (1 or 4) to get the number of +- bytes. */ +- leaq (%rdi, %rax, CHAR_SIZE), %rax ++ + ret + +- .p2align 4 ++ .p2align 4,, 8 + L(last_vec_x2): +- tzcntl %eax, %eax ++ bsfl %eax, %eax + # ifndef USE_AS_STRCHRNUL + /* Check if match was null. */ + cmp (VEC_SIZE)(%rdi, %rax, CHAR_SIZE), %CHAR_REG +@@ -336,7 +346,7 @@ L(last_vec_x2): + ret + + /* Cold case for crossing page with first load. */ +- .p2align 4 ++ .p2align 4,, 8 + L(cross_page_boundary): + movq %rdi, %rdx + /* Align rdi. */ +@@ -346,9 +356,9 @@ L(cross_page_boundary): + vpxorq %YMM1, %YMM0, %YMM2 + VPMINU %YMM2, %YMM1, %YMM2 + /* Each bit in K0 represents a CHAR or a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM2, %k0 ++ VPTESTN %YMM2, %YMM2, %k0 + kmovd %k0, %eax +- /* Remove the leading bits. */ ++ /* Remove the leading bits. */ + # ifdef USE_AS_WCSCHR + movl %edx, %SHIFT_REG + /* NB: Divide shift count by 4 since each bit in K1 represent 4 +@@ -360,20 +370,24 @@ L(cross_page_boundary): + /* If eax is zero continue. */ + testl %eax, %eax + jz L(cross_page_continue) +- tzcntl %eax, %eax +-# ifndef USE_AS_STRCHRNUL +- /* Check to see if match was CHAR or null. */ +- cmp (%rdx, %rax, CHAR_SIZE), %CHAR_REG +- jne L(zero_end) +-# endif ++ bsfl %eax, %eax ++ + # ifdef USE_AS_WCSCHR + /* NB: Multiply wchar_t count by 4 to get the number of + bytes. */ + leaq (%rdx, %rax, CHAR_SIZE), %rax + # else + addq %rdx, %rax ++# endif ++# ifndef USE_AS_STRCHRNUL ++ /* Check to see if match was CHAR or null. */ ++ cmp (%rax), %CHAR_REG ++ je L(cross_page_ret) ++L(zero_end): ++ xorl %eax, %eax ++L(cross_page_ret): + # endif + ret + + END (STRCHR) +-# endif ++#endif diff --git a/SOURCES/glibc-upstream-2.34-22.patch b/SOURCES/glibc-upstream-2.34-22.patch new file mode 100644 index 0000000..bdcd19c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-22.patch @@ -0,0 +1,137 @@ +commit 73c7f5a87971de2797f261e1a447f68dce09284b +Author: Florian Weimer +Date: Mon Sep 20 14:56:08 2021 +0200 + + nptl: pthread_kill needs to return ESRCH for old programs (bug 19193) + + The fix for bug 19193 breaks some old applications which appear + to use pthread_kill to probe if a thread is still running, something + that is not supported by POSIX. + + (cherry picked from commit 95dba35bf05e4a5d69dfae5e9c9d4df3646a7f93) + +diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c +index fb7862eff787a94f..a44dc8f2d9baa925 100644 +--- a/nptl/pthread_kill.c ++++ b/nptl/pthread_kill.c +@@ -21,8 +21,11 @@ + #include + #include + +-int +-__pthread_kill_internal (pthread_t threadid, int signo) ++/* Sends SIGNO to THREADID. If the thread is about to exit or has ++ already exited on the kernel side, return NO_TID. Otherwise return ++ 0 or an error code. */ ++static int ++__pthread_kill_implementation (pthread_t threadid, int signo, int no_tid) + { + struct pthread *pd = (struct pthread *) threadid; + if (pd == THREAD_SELF) +@@ -52,11 +55,8 @@ __pthread_kill_internal (pthread_t threadid, int signo) + signal is either not observable (the target thread has already + blocked signals at this point), or it will fail, or it might be + delivered to a new, unrelated thread that has reused the TID. +- So do not actually send the signal. Do not report an error +- because the threadid argument is still valid (the thread ID +- lifetime has not ended), and ESRCH (for example) would be +- misleading. */ +- ret = 0; ++ So do not actually send the signal. */ ++ ret = no_tid; + else + { + /* Using tgkill is a safety measure. pd->exit_lock ensures that +@@ -71,6 +71,15 @@ __pthread_kill_internal (pthread_t threadid, int signo) + return ret; + } + ++int ++__pthread_kill_internal (pthread_t threadid, int signo) ++{ ++ /* Do not report an error in the no-tid case because the threadid ++ argument is still valid (the thread ID lifetime has not ended), ++ and ESRCH (for example) would be misleading. */ ++ return __pthread_kill_implementation (threadid, signo, 0); ++} ++ + int + __pthread_kill (pthread_t threadid, int signo) + { +@@ -81,6 +90,7 @@ __pthread_kill (pthread_t threadid, int signo) + + return __pthread_kill_internal (threadid, signo); + } ++ + /* Some architectures (for instance arm) might pull raise through libgcc, so + avoid the symbol version if it ends up being used on ld.so. */ + #if !IS_IN(rtld) +@@ -88,6 +98,17 @@ libc_hidden_def (__pthread_kill) + versioned_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_34); + + # if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) +-compat_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_0); ++/* Variant which returns ESRCH in the no-TID case, for backwards ++ compatibility. */ ++int ++attribute_compat_text_section ++__pthread_kill_esrch (pthread_t threadid, int signo) ++{ ++ if (__is_internal_signal (signo)) ++ return EINVAL; ++ ++ return __pthread_kill_implementation (threadid, signo, ESRCH); ++} ++compat_symbol (libc, __pthread_kill_esrch, pthread_kill, GLIBC_2_0); + # endif + #endif +diff --git a/sysdeps/pthread/tst-pthread_kill-exited.c b/sysdeps/pthread/tst-pthread_kill-exited.c +index 7575fb6d58cae99c..a2fddad526666c8c 100644 +--- a/sysdeps/pthread/tst-pthread_kill-exited.c ++++ b/sysdeps/pthread/tst-pthread_kill-exited.c +@@ -16,11 +16,15 @@ + License along with the GNU C Library; if not, see + . */ + +-/* This test verifies that pthread_kill returns 0 (and not ESRCH) for +- a thread that has exited on the kernel side. */ ++/* This test verifies that the default pthread_kill returns 0 (and not ++ ESRCH) for a thread that has exited on the kernel side. */ + ++#include ++#include ++#include + #include + #include ++#include + #include + #include + +@@ -30,6 +34,12 @@ noop_thread (void *closure) + return NULL; + } + ++#if TEST_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) && PTHREAD_IN_LIBC ++extern __typeof (pthread_kill) compat_pthread_kill; ++compat_symbol_reference (libpthread, compat_pthread_kill, pthread_kill, ++ GLIBC_2_0); ++#endif ++ + static int + do_test (void) + { +@@ -37,7 +47,14 @@ do_test (void) + + support_wait_for_thread_exit (); + ++ /* NB: Always uses the default symbol due to separate compilation. */ + xpthread_kill (thr, SIGUSR1); ++ ++#if TEST_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) && PTHREAD_IN_LIBC ++ /* Old binaries need the non-conforming ESRCH error code. */ ++ TEST_COMPARE (compat_pthread_kill (thr, SIGUSR1), ESRCH); ++#endif ++ + xpthread_join (thr); + + return 0; diff --git a/SOURCES/glibc-upstream-2.34-220.patch b/SOURCES/glibc-upstream-2.34-220.patch new file mode 100644 index 0000000..5f77e5c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-220.patch @@ -0,0 +1,143 @@ +commit 0ae1006967eef11909fbed0f6ecef2f260b133d3 +Author: Noah Goldstein +Date: Wed Mar 23 16:57:22 2022 -0500 + + x86: Optimize strcspn and strpbrk in strcspn-c.c + + Use _mm_cmpeq_epi8 and _mm_movemask_epi8 to get strlen instead of + _mm_cmpistri. Also change offset to unsigned to avoid unnecessary + sign extensions. + + geometric_mean(N=20) of all benchmarks that dont fallback on + sse2/strlen; New / Original: .928 + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit 30d627d477d7255345a4b713cf352ac32d644d61) + +diff --git a/sysdeps/x86_64/multiarch/strcspn-c.c b/sysdeps/x86_64/multiarch/strcspn-c.c +index c56ddbd22f014653..2436b6dcd90d8efe 100644 +--- a/sysdeps/x86_64/multiarch/strcspn-c.c ++++ b/sysdeps/x86_64/multiarch/strcspn-c.c +@@ -85,83 +85,74 @@ STRCSPN_SSE42 (const char *s, const char *a) + RETURN (NULL, strlen (s)); + + const char *aligned; +- __m128i mask; +- int offset = (int) ((size_t) a & 15); ++ __m128i mask, maskz, zero; ++ unsigned int maskz_bits; ++ unsigned int offset = (unsigned int) ((size_t) a & 15); ++ zero = _mm_set1_epi8 (0); + if (offset != 0) + { + /* Load masks. */ + aligned = (const char *) ((size_t) a & -16L); + __m128i mask0 = _mm_load_si128 ((__m128i *) aligned); +- +- mask = __m128i_shift_right (mask0, offset); ++ maskz = _mm_cmpeq_epi8 (mask0, zero); + + /* Find where the NULL terminator is. */ +- int length = _mm_cmpistri (mask, mask, 0x3a); +- if (length == 16 - offset) +- { +- /* There is no NULL terminator. */ +- __m128i mask1 = _mm_load_si128 ((__m128i *) (aligned + 16)); +- int index = _mm_cmpistri (mask1, mask1, 0x3a); +- length += index; +- +- /* Don't use SSE4.2 if the length of A > 16. */ +- if (length > 16) +- return STRCSPN_SSE2 (s, a); +- +- if (index != 0) +- { +- /* Combine mask0 and mask1. We could play games with +- palignr, but frankly this data should be in L1 now +- so do the merge via an unaligned load. */ +- mask = _mm_loadu_si128 ((__m128i *) a); +- } +- } ++ maskz_bits = _mm_movemask_epi8 (maskz) >> offset; ++ if (maskz_bits != 0) ++ { ++ mask = __m128i_shift_right (mask0, offset); ++ offset = (unsigned int) ((size_t) s & 15); ++ if (offset) ++ goto start_unaligned; ++ ++ aligned = s; ++ goto start_loop; ++ } + } +- else +- { +- /* A is aligned. */ +- mask = _mm_load_si128 ((__m128i *) a); + +- /* Find where the NULL terminator is. */ +- int length = _mm_cmpistri (mask, mask, 0x3a); +- if (length == 16) +- { +- /* There is no NULL terminator. Don't use SSE4.2 if the length +- of A > 16. */ +- if (a[16] != 0) +- return STRCSPN_SSE2 (s, a); +- } ++ /* A is aligned. */ ++ mask = _mm_loadu_si128 ((__m128i *) a); ++ /* Find where the NULL terminator is. */ ++ maskz = _mm_cmpeq_epi8 (mask, zero); ++ maskz_bits = _mm_movemask_epi8 (maskz); ++ if (maskz_bits == 0) ++ { ++ /* There is no NULL terminator. Don't use SSE4.2 if the length ++ of A > 16. */ ++ if (a[16] != 0) ++ return STRCSPN_SSE2 (s, a); + } + +- offset = (int) ((size_t) s & 15); ++ aligned = s; ++ offset = (unsigned int) ((size_t) s & 15); + if (offset != 0) + { ++ start_unaligned: + /* Check partial string. */ + aligned = (const char *) ((size_t) s & -16L); + __m128i value = _mm_load_si128 ((__m128i *) aligned); + + value = __m128i_shift_right (value, offset); + +- int length = _mm_cmpistri (mask, value, 0x2); ++ unsigned int length = _mm_cmpistri (mask, value, 0x2); + /* No need to check ZFlag since ZFlag is always 1. */ +- int cflag = _mm_cmpistrc (mask, value, 0x2); ++ unsigned int cflag = _mm_cmpistrc (mask, value, 0x2); + if (cflag) + RETURN ((char *) (s + length), length); + /* Find where the NULL terminator is. */ +- int index = _mm_cmpistri (value, value, 0x3a); ++ unsigned int index = _mm_cmpistri (value, value, 0x3a); + if (index < 16 - offset) + RETURN (NULL, index); + aligned += 16; + } +- else +- aligned = s; + ++start_loop: + while (1) + { + __m128i value = _mm_load_si128 ((__m128i *) aligned); +- int index = _mm_cmpistri (mask, value, 0x2); +- int cflag = _mm_cmpistrc (mask, value, 0x2); +- int zflag = _mm_cmpistrz (mask, value, 0x2); ++ unsigned int index = _mm_cmpistri (mask, value, 0x2); ++ unsigned int cflag = _mm_cmpistrc (mask, value, 0x2); ++ unsigned int zflag = _mm_cmpistrz (mask, value, 0x2); + if (cflag) + RETURN ((char *) (aligned + index), (size_t) (aligned + index - s)); + if (zflag) diff --git a/SOURCES/glibc-upstream-2.34-221.patch b/SOURCES/glibc-upstream-2.34-221.patch new file mode 100644 index 0000000..c4b411b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-221.patch @@ -0,0 +1,143 @@ +commit 0a2da0111037b1cc214f8f40ca5bdebf36f35cbd +Author: Noah Goldstein +Date: Wed Mar 23 16:57:24 2022 -0500 + + x86: Optimize strspn in strspn-c.c + + Use _mm_cmpeq_epi8 and _mm_movemask_epi8 to get strlen instead of + _mm_cmpistri. Also change offset to unsigned to avoid unnecessary + sign extensions. + + geometric_mean(N=20) of all benchmarks that dont fallback on + sse2; New / Original: .901 + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit 412d10343168b05b8cf6c3683457cf9711d28046) + +diff --git a/sysdeps/x86_64/multiarch/strspn-c.c b/sysdeps/x86_64/multiarch/strspn-c.c +index a17196296b9ebe52..3bcc479f1b52ff6a 100644 +--- a/sysdeps/x86_64/multiarch/strspn-c.c ++++ b/sysdeps/x86_64/multiarch/strspn-c.c +@@ -63,81 +63,73 @@ __strspn_sse42 (const char *s, const char *a) + return 0; + + const char *aligned; +- __m128i mask; +- int offset = (int) ((size_t) a & 15); ++ __m128i mask, maskz, zero; ++ unsigned int maskz_bits; ++ unsigned int offset = (int) ((size_t) a & 15); ++ zero = _mm_set1_epi8 (0); + if (offset != 0) + { + /* Load masks. */ + aligned = (const char *) ((size_t) a & -16L); + __m128i mask0 = _mm_load_si128 ((__m128i *) aligned); +- +- mask = __m128i_shift_right (mask0, offset); ++ maskz = _mm_cmpeq_epi8 (mask0, zero); + + /* Find where the NULL terminator is. */ +- int length = _mm_cmpistri (mask, mask, 0x3a); +- if (length == 16 - offset) +- { +- /* There is no NULL terminator. */ +- __m128i mask1 = _mm_load_si128 ((__m128i *) (aligned + 16)); +- int index = _mm_cmpistri (mask1, mask1, 0x3a); +- length += index; +- +- /* Don't use SSE4.2 if the length of A > 16. */ +- if (length > 16) +- return __strspn_sse2 (s, a); +- +- if (index != 0) +- { +- /* Combine mask0 and mask1. We could play games with +- palignr, but frankly this data should be in L1 now +- so do the merge via an unaligned load. */ +- mask = _mm_loadu_si128 ((__m128i *) a); +- } +- } ++ maskz_bits = _mm_movemask_epi8 (maskz) >> offset; ++ if (maskz_bits != 0) ++ { ++ mask = __m128i_shift_right (mask0, offset); ++ offset = (unsigned int) ((size_t) s & 15); ++ if (offset) ++ goto start_unaligned; ++ ++ aligned = s; ++ goto start_loop; ++ } + } +- else +- { +- /* A is aligned. */ +- mask = _mm_load_si128 ((__m128i *) a); + +- /* Find where the NULL terminator is. */ +- int length = _mm_cmpistri (mask, mask, 0x3a); +- if (length == 16) +- { +- /* There is no NULL terminator. Don't use SSE4.2 if the length +- of A > 16. */ +- if (a[16] != 0) +- return __strspn_sse2 (s, a); +- } ++ /* A is aligned. */ ++ mask = _mm_loadu_si128 ((__m128i *) a); ++ ++ /* Find where the NULL terminator is. */ ++ maskz = _mm_cmpeq_epi8 (mask, zero); ++ maskz_bits = _mm_movemask_epi8 (maskz); ++ if (maskz_bits == 0) ++ { ++ /* There is no NULL terminator. Don't use SSE4.2 if the length ++ of A > 16. */ ++ if (a[16] != 0) ++ return __strspn_sse2 (s, a); + } ++ aligned = s; ++ offset = (unsigned int) ((size_t) s & 15); + +- offset = (int) ((size_t) s & 15); + if (offset != 0) + { ++ start_unaligned: + /* Check partial string. */ + aligned = (const char *) ((size_t) s & -16L); + __m128i value = _mm_load_si128 ((__m128i *) aligned); ++ __m128i adj_value = __m128i_shift_right (value, offset); + +- value = __m128i_shift_right (value, offset); +- +- int length = _mm_cmpistri (mask, value, 0x12); ++ unsigned int length = _mm_cmpistri (mask, adj_value, 0x12); + /* No need to check CFlag since it is always 1. */ + if (length < 16 - offset) + return length; + /* Find where the NULL terminator is. */ +- int index = _mm_cmpistri (value, value, 0x3a); +- if (index < 16 - offset) ++ maskz = _mm_cmpeq_epi8 (value, zero); ++ maskz_bits = _mm_movemask_epi8 (maskz) >> offset; ++ if (maskz_bits != 0) + return length; + aligned += 16; + } +- else +- aligned = s; + ++start_loop: + while (1) + { + __m128i value = _mm_load_si128 ((__m128i *) aligned); +- int index = _mm_cmpistri (mask, value, 0x12); +- int cflag = _mm_cmpistrc (mask, value, 0x12); ++ unsigned int index = _mm_cmpistri (mask, value, 0x12); ++ unsigned int cflag = _mm_cmpistrc (mask, value, 0x12); + if (cflag) + return (size_t) (aligned + index - s); + aligned += 16; diff --git a/SOURCES/glibc-upstream-2.34-222.patch b/SOURCES/glibc-upstream-2.34-222.patch new file mode 100644 index 0000000..4b54799 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-222.patch @@ -0,0 +1,164 @@ +commit 0dafa75e3c42994d0f23db62651d1802577272f2 +Author: Noah Goldstein +Date: Wed Mar 23 16:57:26 2022 -0500 + + x86: Remove strcspn-sse2.S and use the generic implementation + + The generic implementation is faster. + + geometric_mean(N=20) of all benchmarks New / Original: .678 + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit fe28e7d9d9535ebab4081d195c553b4fbf39d9ae) + +diff --git a/sysdeps/x86_64/multiarch/strcspn-sse2.S b/sysdeps/x86_64/multiarch/strcspn-sse2.c +similarity index 89% +rename from sysdeps/x86_64/multiarch/strcspn-sse2.S +rename to sysdeps/x86_64/multiarch/strcspn-sse2.c +index 63b260a9ed265230..9bd3dac82d90b3a5 100644 +--- a/sysdeps/x86_64/multiarch/strcspn-sse2.S ++++ b/sysdeps/x86_64/multiarch/strcspn-sse2.c +@@ -19,10 +19,10 @@ + #if IS_IN (libc) + + # include +-# define strcspn __strcspn_sse2 ++# define STRCSPN __strcspn_sse2 + + # undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(strcspn) ++# define libc_hidden_builtin_def(STRCSPN) + #endif + +-#include ++#include +diff --git a/sysdeps/x86_64/strcspn.S b/sysdeps/x86_64/strcspn.S +deleted file mode 100644 +index 6035a274c87bafb0..0000000000000000 +--- a/sysdeps/x86_64/strcspn.S ++++ /dev/null +@@ -1,122 +0,0 @@ +-/* strcspn (str, ss) -- Return the length of the initial segment of STR +- which contains no characters from SS. +- For AMD x86-64. +- Copyright (C) 1994-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper . +- Bug fixes by Alan Modra . +- Adopted for x86-64 by Andreas Jaeger . +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for 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" +- +- .text +-ENTRY (strcspn) +- +- movq %rdi, %rdx /* Save SRC. */ +- +- /* First we create a table with flags for all possible characters. +- For the ASCII (7bit/8bit) or ISO-8859-X character sets which are +- supported by the C string functions we have 256 characters. +- Before inserting marks for the stop characters we clear the whole +- table. */ +- movq %rdi, %r8 /* Save value. */ +- subq $256, %rsp /* Make space for 256 bytes. */ +- cfi_adjust_cfa_offset(256) +- movl $32, %ecx /* 32*8 bytes = 256 bytes. */ +- movq %rsp, %rdi +- xorl %eax, %eax /* We store 0s. */ +- cld +- rep +- stosq +- +- movq %rsi, %rax /* Setup skipset. */ +- +-/* For understanding the following code remember that %rcx == 0 now. +- Although all the following instruction only modify %cl we always +- have a correct zero-extended 64-bit value in %rcx. */ +- +- .p2align 4 +-L(2): movb (%rax), %cl /* get byte from skipset */ +- testb %cl, %cl /* is NUL char? */ +- jz L(1) /* yes => start compare loop */ +- movb %cl, (%rsp,%rcx) /* set corresponding byte in skipset table */ +- +- movb 1(%rax), %cl /* get byte from skipset */ +- testb $0xff, %cl /* is NUL char? */ +- jz L(1) /* yes => start compare loop */ +- movb %cl, (%rsp,%rcx) /* set corresponding byte in skipset table */ +- +- movb 2(%rax), %cl /* get byte from skipset */ +- testb $0xff, %cl /* is NUL char? */ +- jz L(1) /* yes => start compare loop */ +- movb %cl, (%rsp,%rcx) /* set corresponding byte in skipset table */ +- +- movb 3(%rax), %cl /* get byte from skipset */ +- addq $4, %rax /* increment skipset pointer */ +- movb %cl, (%rsp,%rcx) /* set corresponding byte in skipset table */ +- testb $0xff, %cl /* is NUL char? */ +- jnz L(2) /* no => process next dword from skipset */ +- +-L(1): leaq -4(%rdx), %rax /* prepare loop */ +- +- /* We use a neat trick for the following loop. Normally we would +- have to test for two termination conditions +- 1. a character in the skipset was found +- and +- 2. the end of the string was found +- But as a sign that the character is in the skipset we store its +- value in the table. But the value of NUL is NUL so the loop +- terminates for NUL in every case. */ +- +- .p2align 4 +-L(3): addq $4, %rax /* adjust pointer for full loop round */ +- +- movb (%rax), %cl /* get byte from string */ +- cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */ +- je L(4) /* yes => return */ +- +- movb 1(%rax), %cl /* get byte from string */ +- cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */ +- je L(5) /* yes => return */ +- +- movb 2(%rax), %cl /* get byte from string */ +- cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */ +- jz L(6) /* yes => return */ +- +- movb 3(%rax), %cl /* get byte from string */ +- cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */ +- jne L(3) /* no => start loop again */ +- +- incq %rax /* adjust pointer */ +-L(6): incq %rax +-L(5): incq %rax +- +-L(4): addq $256, %rsp /* remove skipset */ +- cfi_adjust_cfa_offset(-256) +-#ifdef USE_AS_STRPBRK +- xorl %edx,%edx +- orb %cl, %cl /* was last character NUL? */ +- cmovzq %rdx, %rax /* Yes: return NULL */ +-#else +- subq %rdx, %rax /* we have to return the number of valid +- characters, so compute distance to first +- non-valid character */ +-#endif +- ret +-END (strcspn) +-libc_hidden_builtin_def (strcspn) diff --git a/SOURCES/glibc-upstream-2.34-223.patch b/SOURCES/glibc-upstream-2.34-223.patch new file mode 100644 index 0000000..42accca --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-223.patch @@ -0,0 +1,44 @@ +commit 38115446558e6d0976299eb592ba7266681c27d5 +Author: Noah Goldstein +Date: Wed Mar 23 16:57:27 2022 -0500 + + x86: Remove strpbrk-sse2.S and use the generic implementation + + The generic implementation is faster (see strcspn commit). + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit 653358535280a599382cb6c77538a187dac6a87f) + +diff --git a/sysdeps/x86_64/multiarch/strpbrk-sse2.S b/sysdeps/x86_64/multiarch/strpbrk-sse2.c +similarity index 87% +rename from sysdeps/x86_64/multiarch/strpbrk-sse2.S +rename to sysdeps/x86_64/multiarch/strpbrk-sse2.c +index c5b95d08ff09cb27..8a58f051c35163dd 100644 +--- a/sysdeps/x86_64/multiarch/strpbrk-sse2.S ++++ b/sysdeps/x86_64/multiarch/strpbrk-sse2.c +@@ -19,11 +19,10 @@ + #if IS_IN (libc) + + # include +-# define strcspn __strpbrk_sse2 ++# define STRPBRK __strpbrk_sse2 + + # undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(strpbrk) ++# define libc_hidden_builtin_def(STRPBRK) + #endif + +-#define USE_AS_STRPBRK +-#include ++#include +diff --git a/sysdeps/x86_64/strpbrk.S b/sysdeps/x86_64/strpbrk.S +deleted file mode 100644 +index 21888a5b923974f9..0000000000000000 +--- a/sysdeps/x86_64/strpbrk.S ++++ /dev/null +@@ -1,3 +0,0 @@ +-#define strcspn strpbrk +-#define USE_AS_STRPBRK +-#include diff --git a/SOURCES/glibc-upstream-2.34-224.patch b/SOURCES/glibc-upstream-2.34-224.patch new file mode 100644 index 0000000..764dd6d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-224.patch @@ -0,0 +1,157 @@ +commit a4b1cae068d4d6e3117dd49e7d0599e4c62ac39f +Author: Noah Goldstein +Date: Wed Mar 23 16:57:29 2022 -0500 + + x86: Remove strspn-sse2.S and use the generic implementation + + The generic implementation is faster. + + geometric_mean(N=20) of all benchmarks New / Original: .710 + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit 9c8a6ad620b49a27120ecdd7049c26bf05900397) + +diff --git a/sysdeps/x86_64/multiarch/strspn-sse2.S b/sysdeps/x86_64/multiarch/strspn-sse2.c +similarity index 89% +rename from sysdeps/x86_64/multiarch/strspn-sse2.S +rename to sysdeps/x86_64/multiarch/strspn-sse2.c +index e919fe492cc15151..f5e5686db1037740 100644 +--- a/sysdeps/x86_64/multiarch/strspn-sse2.S ++++ b/sysdeps/x86_64/multiarch/strspn-sse2.c +@@ -19,10 +19,10 @@ + #if IS_IN (libc) + + # include +-# define strspn __strspn_sse2 ++# define STRSPN __strspn_sse2 + + # undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(strspn) ++# define libc_hidden_builtin_def(STRSPN) + #endif + +-#include ++#include +diff --git a/sysdeps/x86_64/strspn.S b/sysdeps/x86_64/strspn.S +deleted file mode 100644 +index e878f328852792db..0000000000000000 +--- a/sysdeps/x86_64/strspn.S ++++ /dev/null +@@ -1,115 +0,0 @@ +-/* strspn (str, ss) -- Return the length of the initial segment of STR +- which contains only characters from SS. +- For AMD x86-64. +- Copyright (C) 1994-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper . +- Bug fixes by Alan Modra . +- Adopted for x86-64 by Andreas Jaeger . +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for 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 +- +- .text +-ENTRY (strspn) +- +- movq %rdi, %rdx /* Save SRC. */ +- +- /* First we create a table with flags for all possible characters. +- For the ASCII (7bit/8bit) or ISO-8859-X character sets which are +- supported by the C string functions we have 256 characters. +- Before inserting marks for the stop characters we clear the whole +- table. */ +- movq %rdi, %r8 /* Save value. */ +- subq $256, %rsp /* Make space for 256 bytes. */ +- cfi_adjust_cfa_offset(256) +- movl $32, %ecx /* 32*8 bytes = 256 bytes. */ +- movq %rsp, %rdi +- xorl %eax, %eax /* We store 0s. */ +- cld +- rep +- stosq +- +- movq %rsi, %rax /* Setup stopset. */ +- +-/* For understanding the following code remember that %rcx == 0 now. +- Although all the following instruction only modify %cl we always +- have a correct zero-extended 64-bit value in %rcx. */ +- +- .p2align 4 +-L(2): movb (%rax), %cl /* get byte from stopset */ +- testb %cl, %cl /* is NUL char? */ +- jz L(1) /* yes => start compare loop */ +- movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */ +- +- movb 1(%rax), %cl /* get byte from stopset */ +- testb $0xff, %cl /* is NUL char? */ +- jz L(1) /* yes => start compare loop */ +- movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */ +- +- movb 2(%rax), %cl /* get byte from stopset */ +- testb $0xff, %cl /* is NUL char? */ +- jz L(1) /* yes => start compare loop */ +- movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */ +- +- movb 3(%rax), %cl /* get byte from stopset */ +- addq $4, %rax /* increment stopset pointer */ +- movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */ +- testb $0xff, %cl /* is NUL char? */ +- jnz L(2) /* no => process next dword from stopset */ +- +-L(1): leaq -4(%rdx), %rax /* prepare loop */ +- +- /* We use a neat trick for the following loop. Normally we would +- have to test for two termination conditions +- 1. a character in the stopset was found +- and +- 2. the end of the string was found +- But as a sign that the character is in the stopset we store its +- value in the table. But the value of NUL is NUL so the loop +- terminates for NUL in every case. */ +- +- .p2align 4 +-L(3): addq $4, %rax /* adjust pointer for full loop round */ +- +- movb (%rax), %cl /* get byte from string */ +- testb %cl, (%rsp,%rcx) /* is it contained in skipset? */ +- jz L(4) /* no => return */ +- +- movb 1(%rax), %cl /* get byte from string */ +- testb %cl, (%rsp,%rcx) /* is it contained in skipset? */ +- jz L(5) /* no => return */ +- +- movb 2(%rax), %cl /* get byte from string */ +- testb %cl, (%rsp,%rcx) /* is it contained in skipset? */ +- jz L(6) /* no => return */ +- +- movb 3(%rax), %cl /* get byte from string */ +- testb %cl, (%rsp,%rcx) /* is it contained in skipset? */ +- jnz L(3) /* yes => start loop again */ +- +- incq %rax /* adjust pointer */ +-L(6): incq %rax +-L(5): incq %rax +- +-L(4): addq $256, %rsp /* remove stopset */ +- cfi_adjust_cfa_offset(-256) +- subq %rdx, %rax /* we have to return the number of valid +- characters, so compute distance to first +- non-valid character */ +- ret +-END (strspn) +-libc_hidden_builtin_def (strspn) diff --git a/SOURCES/glibc-upstream-2.34-225.patch b/SOURCES/glibc-upstream-2.34-225.patch new file mode 100644 index 0000000..61ccb20 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-225.patch @@ -0,0 +1,118 @@ +commit 5997011826b7bbb7015f56bf143a6e4fd0f5a7df +Author: Noah Goldstein +Date: Wed Mar 23 16:57:36 2022 -0500 + + x86: Optimize str{n}casecmp TOLOWER logic in strcmp.S + + Slightly faster method of doing TOLOWER that saves an + instruction. + + Also replace the hard coded 5-byte no with .p2align 4. On builds with + CET enabled this misaligned entry to strcasecmp. + + geometric_mean(N=40) of all benchmarks New / Original: .894 + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit 670b54bc585ea4a94f3b2e9272ba44aa6b730b73) + +diff --git a/sysdeps/x86_64/strcmp.S b/sysdeps/x86_64/strcmp.S +index 7f8a1bc756f86aee..ca70b540eb2dd190 100644 +--- a/sysdeps/x86_64/strcmp.S ++++ b/sysdeps/x86_64/strcmp.S +@@ -78,9 +78,8 @@ ENTRY2 (__strcasecmp) + movq __libc_tsd_LOCALE@gottpoff(%rip),%rax + mov %fs:(%rax),%RDX_LP + +- // XXX 5 byte should be before the function +- /* 5-byte NOP. */ +- .byte 0x0f,0x1f,0x44,0x00,0x00 ++ /* Either 1 or 5 bytes (dependeing if CET is enabled). */ ++ .p2align 4 + END2 (__strcasecmp) + # ifndef NO_NOLOCALE_ALIAS + weak_alias (__strcasecmp, strcasecmp) +@@ -97,9 +96,8 @@ ENTRY2 (__strncasecmp) + movq __libc_tsd_LOCALE@gottpoff(%rip),%rax + mov %fs:(%rax),%RCX_LP + +- // XXX 5 byte should be before the function +- /* 5-byte NOP. */ +- .byte 0x0f,0x1f,0x44,0x00,0x00 ++ /* Either 1 or 5 bytes (dependeing if CET is enabled). */ ++ .p2align 4 + END2 (__strncasecmp) + # ifndef NO_NOLOCALE_ALIAS + weak_alias (__strncasecmp, strncasecmp) +@@ -149,22 +147,22 @@ ENTRY (STRCMP) + #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L + .section .rodata.cst16,"aM",@progbits,16 + .align 16 +-.Lbelowupper: +- .quad 0x4040404040404040 +- .quad 0x4040404040404040 +-.Ltopupper: +- .quad 0x5b5b5b5b5b5b5b5b +- .quad 0x5b5b5b5b5b5b5b5b +-.Ltouppermask: ++.Llcase_min: ++ .quad 0x3f3f3f3f3f3f3f3f ++ .quad 0x3f3f3f3f3f3f3f3f ++.Llcase_max: ++ .quad 0x9999999999999999 ++ .quad 0x9999999999999999 ++.Lcase_add: + .quad 0x2020202020202020 + .quad 0x2020202020202020 + .previous +- movdqa .Lbelowupper(%rip), %xmm5 +-# define UCLOW_reg %xmm5 +- movdqa .Ltopupper(%rip), %xmm6 +-# define UCHIGH_reg %xmm6 +- movdqa .Ltouppermask(%rip), %xmm7 +-# define LCQWORD_reg %xmm7 ++ movdqa .Llcase_min(%rip), %xmm5 ++# define LCASE_MIN_reg %xmm5 ++ movdqa .Llcase_max(%rip), %xmm6 ++# define LCASE_MAX_reg %xmm6 ++ movdqa .Lcase_add(%rip), %xmm7 ++# define CASE_ADD_reg %xmm7 + #endif + cmp $0x30, %ecx + ja LABEL(crosscache) /* rsi: 16-byte load will cross cache line */ +@@ -175,22 +173,18 @@ ENTRY (STRCMP) + movhpd 8(%rdi), %xmm1 + movhpd 8(%rsi), %xmm2 + #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L +-# define TOLOWER(reg1, reg2) \ +- movdqa reg1, %xmm8; \ +- movdqa UCHIGH_reg, %xmm9; \ +- movdqa reg2, %xmm10; \ +- movdqa UCHIGH_reg, %xmm11; \ +- pcmpgtb UCLOW_reg, %xmm8; \ +- pcmpgtb reg1, %xmm9; \ +- pcmpgtb UCLOW_reg, %xmm10; \ +- pcmpgtb reg2, %xmm11; \ +- pand %xmm9, %xmm8; \ +- pand %xmm11, %xmm10; \ +- pand LCQWORD_reg, %xmm8; \ +- pand LCQWORD_reg, %xmm10; \ +- por %xmm8, reg1; \ +- por %xmm10, reg2 +- TOLOWER (%xmm1, %xmm2) ++# define TOLOWER(reg1, reg2) \ ++ movdqa LCASE_MIN_reg, %xmm8; \ ++ movdqa LCASE_MIN_reg, %xmm9; \ ++ paddb reg1, %xmm8; \ ++ paddb reg2, %xmm9; \ ++ pcmpgtb LCASE_MAX_reg, %xmm8; \ ++ pcmpgtb LCASE_MAX_reg, %xmm9; \ ++ pandn CASE_ADD_reg, %xmm8; \ ++ pandn CASE_ADD_reg, %xmm9; \ ++ paddb %xmm8, reg1; \ ++ paddb %xmm9, reg2 ++ TOLOWER (%xmm1, %xmm2) + #else + # define TOLOWER(reg1, reg2) + #endif diff --git a/SOURCES/glibc-upstream-2.34-226.patch b/SOURCES/glibc-upstream-2.34-226.patch new file mode 100644 index 0000000..fcadc66 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-226.patch @@ -0,0 +1,139 @@ +commit 3605c744078bb048d876298aaf12a2869e8071b8 +Author: Noah Goldstein +Date: Wed Mar 23 16:57:38 2022 -0500 + + x86: Optimize str{n}casecmp TOLOWER logic in strcmp-sse42.S + + Slightly faster method of doing TOLOWER that saves an + instruction. + + Also replace the hard coded 5-byte no with .p2align 4. On builds with + CET enabled this misaligned entry to strcasecmp. + + geometric_mean(N=40) of all benchmarks New / Original: .920 + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit d154758e618ec9324f5d339c46db0aa27e8b1226) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-sse42.S b/sysdeps/x86_64/multiarch/strcmp-sse42.S +index 6197a723b9e0606e..a6825de8195ad8c6 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-sse42.S ++++ b/sysdeps/x86_64/multiarch/strcmp-sse42.S +@@ -89,9 +89,8 @@ ENTRY (GLABEL(__strcasecmp)) + movq __libc_tsd_LOCALE@gottpoff(%rip),%rax + mov %fs:(%rax),%RDX_LP + +- // XXX 5 byte should be before the function +- /* 5-byte NOP. */ +- .byte 0x0f,0x1f,0x44,0x00,0x00 ++ /* Either 1 or 5 bytes (dependeing if CET is enabled). */ ++ .p2align 4 + END (GLABEL(__strcasecmp)) + /* FALLTHROUGH to strcasecmp_l. */ + #endif +@@ -100,9 +99,8 @@ ENTRY (GLABEL(__strncasecmp)) + movq __libc_tsd_LOCALE@gottpoff(%rip),%rax + mov %fs:(%rax),%RCX_LP + +- // XXX 5 byte should be before the function +- /* 5-byte NOP. */ +- .byte 0x0f,0x1f,0x44,0x00,0x00 ++ /* Either 1 or 5 bytes (dependeing if CET is enabled). */ ++ .p2align 4 + END (GLABEL(__strncasecmp)) + /* FALLTHROUGH to strncasecmp_l. */ + #endif +@@ -170,27 +168,22 @@ STRCMP_SSE42: + #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L + .section .rodata.cst16,"aM",@progbits,16 + .align 16 +-LABEL(belowupper): +- .quad 0x4040404040404040 +- .quad 0x4040404040404040 +-LABEL(topupper): +-# ifdef USE_AVX +- .quad 0x5a5a5a5a5a5a5a5a +- .quad 0x5a5a5a5a5a5a5a5a +-# else +- .quad 0x5b5b5b5b5b5b5b5b +- .quad 0x5b5b5b5b5b5b5b5b +-# endif +-LABEL(touppermask): ++LABEL(lcase_min): ++ .quad 0x3f3f3f3f3f3f3f3f ++ .quad 0x3f3f3f3f3f3f3f3f ++LABEL(lcase_max): ++ .quad 0x9999999999999999 ++ .quad 0x9999999999999999 ++LABEL(case_add): + .quad 0x2020202020202020 + .quad 0x2020202020202020 + .previous +- movdqa LABEL(belowupper)(%rip), %xmm4 +-# define UCLOW_reg %xmm4 +- movdqa LABEL(topupper)(%rip), %xmm5 +-# define UCHIGH_reg %xmm5 +- movdqa LABEL(touppermask)(%rip), %xmm6 +-# define LCQWORD_reg %xmm6 ++ movdqa LABEL(lcase_min)(%rip), %xmm4 ++# define LCASE_MIN_reg %xmm4 ++ movdqa LABEL(lcase_max)(%rip), %xmm5 ++# define LCASE_MAX_reg %xmm5 ++ movdqa LABEL(case_add)(%rip), %xmm6 ++# define CASE_ADD_reg %xmm6 + #endif + cmp $0x30, %ecx + ja LABEL(crosscache)/* rsi: 16-byte load will cross cache line */ +@@ -201,32 +194,26 @@ LABEL(touppermask): + #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L + # ifdef USE_AVX + # define TOLOWER(reg1, reg2) \ +- vpcmpgtb UCLOW_reg, reg1, %xmm7; \ +- vpcmpgtb UCHIGH_reg, reg1, %xmm8; \ +- vpcmpgtb UCLOW_reg, reg2, %xmm9; \ +- vpcmpgtb UCHIGH_reg, reg2, %xmm10; \ +- vpandn %xmm7, %xmm8, %xmm8; \ +- vpandn %xmm9, %xmm10, %xmm10; \ +- vpand LCQWORD_reg, %xmm8, %xmm8; \ +- vpand LCQWORD_reg, %xmm10, %xmm10; \ +- vpor reg1, %xmm8, reg1; \ +- vpor reg2, %xmm10, reg2 ++ vpaddb LCASE_MIN_reg, reg1, %xmm7; \ ++ vpaddb LCASE_MIN_reg, reg2, %xmm8; \ ++ vpcmpgtb LCASE_MAX_reg, %xmm7, %xmm7; \ ++ vpcmpgtb LCASE_MAX_reg, %xmm8, %xmm8; \ ++ vpandn CASE_ADD_reg, %xmm7, %xmm7; \ ++ vpandn CASE_ADD_reg, %xmm8, %xmm8; \ ++ vpaddb %xmm7, reg1, reg1; \ ++ vpaddb %xmm8, reg2, reg2 + # else + # define TOLOWER(reg1, reg2) \ +- movdqa reg1, %xmm7; \ +- movdqa UCHIGH_reg, %xmm8; \ +- movdqa reg2, %xmm9; \ +- movdqa UCHIGH_reg, %xmm10; \ +- pcmpgtb UCLOW_reg, %xmm7; \ +- pcmpgtb reg1, %xmm8; \ +- pcmpgtb UCLOW_reg, %xmm9; \ +- pcmpgtb reg2, %xmm10; \ +- pand %xmm8, %xmm7; \ +- pand %xmm10, %xmm9; \ +- pand LCQWORD_reg, %xmm7; \ +- pand LCQWORD_reg, %xmm9; \ +- por %xmm7, reg1; \ +- por %xmm9, reg2 ++ movdqa LCASE_MIN_reg, %xmm7; \ ++ movdqa LCASE_MIN_reg, %xmm8; \ ++ paddb reg1, %xmm7; \ ++ paddb reg2, %xmm8; \ ++ pcmpgtb LCASE_MAX_reg, %xmm7; \ ++ pcmpgtb LCASE_MAX_reg, %xmm8; \ ++ pandn CASE_ADD_reg, %xmm7; \ ++ pandn CASE_ADD_reg, %xmm8; \ ++ paddb %xmm7, reg1; \ ++ paddb %xmm8, reg2 + # endif + TOLOWER (%xmm1, %xmm2) + #else diff --git a/SOURCES/glibc-upstream-2.34-227.patch b/SOURCES/glibc-upstream-2.34-227.patch new file mode 100644 index 0000000..9dd23aa --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-227.patch @@ -0,0 +1,744 @@ +commit 3051cf3e745015a9106cf71be7f7adbb2f83fcac +Author: Noah Goldstein +Date: Thu Mar 24 18:56:12 2022 -0500 + + x86: Add AVX2 optimized str{n}casecmp + + geometric_mean(N=40) of all benchmarks AVX2 / SSE42: .702 + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit bbf81222343fed5cd704001a2ae0d86c71544151) + +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index 8c9e7812c6af10b8..711ecf2ee45d61b9 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -51,6 +51,8 @@ sysdep_routines += \ + stpncpy-sse2-unaligned \ + stpncpy-ssse3 \ + strcasecmp_l-avx \ ++ strcasecmp_l-avx2 \ ++ strcasecmp_l-avx2-rtm \ + strcasecmp_l-sse2 \ + strcasecmp_l-sse4_2 \ + strcasecmp_l-ssse3 \ +@@ -89,6 +91,8 @@ sysdep_routines += \ + strlen-evex \ + strlen-sse2 \ + strncase_l-avx \ ++ strncase_l-avx2 \ ++ strncase_l-avx2-rtm \ + strncase_l-sse2 \ + strncase_l-sse4_2 \ + strncase_l-ssse3 \ +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index 4992d7bd3206a7c0..a687b387c91aa9ae 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -418,6 +418,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/x86_64/multiarch/strcasecmp_l.c. */ + IFUNC_IMPL (i, name, strcasecmp, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ CPU_FEATURE_USABLE (AVX2), ++ __strcasecmp_avx2) ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (RTM)), ++ __strcasecmp_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strcasecmp, + CPU_FEATURE_USABLE (AVX), + __strcasecmp_avx) +@@ -431,6 +438,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/x86_64/multiarch/strcasecmp_l.c. */ + IFUNC_IMPL (i, name, strcasecmp_l, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ CPU_FEATURE_USABLE (AVX2), ++ __strcasecmp_l_avx2) ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (RTM)), ++ __strcasecmp_l_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strcasecmp_l, + CPU_FEATURE_USABLE (AVX), + __strcasecmp_l_avx) +@@ -558,6 +572,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/x86_64/multiarch/strncase_l.c. */ + IFUNC_IMPL (i, name, strncasecmp, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, ++ CPU_FEATURE_USABLE (AVX2), ++ __strncasecmp_avx2) ++ IFUNC_IMPL_ADD (array, i, strncasecmp, ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (RTM)), ++ __strncasecmp_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strncasecmp, + CPU_FEATURE_USABLE (AVX), + __strncasecmp_avx) +@@ -572,6 +593,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/x86_64/multiarch/strncase_l.c. */ + IFUNC_IMPL (i, name, strncasecmp_l, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, ++ CPU_FEATURE_USABLE (AVX2), ++ __strncasecmp_l_avx2) ++ IFUNC_IMPL_ADD (array, i, strncasecmp, ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (RTM)), ++ __strncasecmp_l_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strncasecmp_l, + CPU_FEATURE_USABLE (AVX), + __strncasecmp_l_avx) +diff --git a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h +index 931770e079fcc69f..64d0cd6ef25f73c0 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h ++++ b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h +@@ -23,12 +23,24 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx) attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden; + + static inline void * + IFUNC_SELECTOR (void) + { + const struct cpu_features* cpu_features = __get_cpu_features (); + ++ if (CPU_FEATURE_USABLE_P (cpu_features, AVX2) ++ && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load)) ++ { ++ if (CPU_FEATURE_USABLE_P (cpu_features, RTM)) ++ return OPTIMIZE (avx2_rtm); ++ ++ if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_VZEROUPPER)) ++ return OPTIMIZE (avx2); ++ } ++ + if (CPU_FEATURE_USABLE_P (cpu_features, AVX)) + return OPTIMIZE (avx); + +diff --git a/sysdeps/x86_64/multiarch/strcasecmp_l-avx2-rtm.S b/sysdeps/x86_64/multiarch/strcasecmp_l-avx2-rtm.S +new file mode 100644 +index 0000000000000000..09957fc3c543b40c +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strcasecmp_l-avx2-rtm.S +@@ -0,0 +1,15 @@ ++#ifndef STRCMP ++# define STRCMP __strcasecmp_l_avx2_rtm ++#endif ++ ++#define _GLABEL(x) x ## _rtm ++#define GLABEL(x) _GLABEL(x) ++ ++#define ZERO_UPPER_VEC_REGISTERS_RETURN \ ++ ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST ++ ++#define VZEROUPPER_RETURN jmp L(return_vzeroupper) ++ ++#define SECTION(p) p##.avx.rtm ++ ++#include "strcasecmp_l-avx2.S" +diff --git a/sysdeps/x86_64/multiarch/strcasecmp_l-avx2.S b/sysdeps/x86_64/multiarch/strcasecmp_l-avx2.S +new file mode 100644 +index 0000000000000000..e2762f2a222b2a65 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strcasecmp_l-avx2.S +@@ -0,0 +1,23 @@ ++/* strcasecmp_l optimized with AVX2. ++ Copyright (C) 2017-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef STRCMP ++# define STRCMP __strcasecmp_l_avx2 ++#endif ++#define USE_AS_STRCASECMP_L ++#include "strcmp-avx2.S" +diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S +index 09a73942086f9c9f..aa91f6e48a0e1ce5 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S +@@ -20,6 +20,10 @@ + + # include + ++# if defined USE_AS_STRCASECMP_L ++# include "locale-defines.h" ++# endif ++ + # ifndef STRCMP + # define STRCMP __strcmp_avx2 + # endif +@@ -74,13 +78,88 @@ + # define VEC_OFFSET (-VEC_SIZE) + # endif + ++# ifdef USE_AS_STRCASECMP_L ++# define BYTE_LOOP_REG OFFSET_REG ++# else ++# define BYTE_LOOP_REG ecx ++# endif ++ ++# ifdef USE_AS_STRCASECMP_L ++# ifdef USE_AS_STRNCMP ++# define STRCASECMP __strncasecmp_avx2 ++# define LOCALE_REG rcx ++# define LOCALE_REG_LP RCX_LP ++# define STRCASECMP_NONASCII __strncasecmp_l_nonascii ++# else ++# define STRCASECMP __strcasecmp_avx2 ++# define LOCALE_REG rdx ++# define LOCALE_REG_LP RDX_LP ++# define STRCASECMP_NONASCII __strcasecmp_l_nonascii ++# endif ++# endif ++ + # define xmmZERO xmm15 + # define ymmZERO ymm15 + ++# define LCASE_MIN_ymm %ymm10 ++# define LCASE_MAX_ymm %ymm11 ++# define CASE_ADD_ymm %ymm12 ++ ++# define LCASE_MIN_xmm %xmm10 ++# define LCASE_MAX_xmm %xmm11 ++# define CASE_ADD_xmm %xmm12 ++ ++ /* r11 is never use elsewhere so this is safe to maintain. */ ++# define TOLOWER_BASE %r11 ++ + # ifndef SECTION + # define SECTION(p) p##.avx + # endif + ++# ifdef USE_AS_STRCASECMP_L ++# define REG(x, y) x ## y ++# define TOLOWER(reg1_in, reg1_out, reg2_in, reg2_out, ext) \ ++ vpaddb REG(LCASE_MIN_, ext), reg1_in, REG(%ext, 8); \ ++ vpaddb REG(LCASE_MIN_, ext), reg2_in, REG(%ext, 9); \ ++ vpcmpgtb REG(LCASE_MAX_, ext), REG(%ext, 8), REG(%ext, 8); \ ++ vpcmpgtb REG(LCASE_MAX_, ext), REG(%ext, 9), REG(%ext, 9); \ ++ vpandn REG(CASE_ADD_, ext), REG(%ext, 8), REG(%ext, 8); \ ++ vpandn REG(CASE_ADD_, ext), REG(%ext, 9), REG(%ext, 9); \ ++ vpaddb REG(%ext, 8), reg1_in, reg1_out; \ ++ vpaddb REG(%ext, 9), reg2_in, reg2_out ++ ++# define TOLOWER_gpr(src, dst) movl (TOLOWER_BASE, src, 4), dst ++# define TOLOWER_ymm(...) TOLOWER(__VA_ARGS__, ymm) ++# define TOLOWER_xmm(...) TOLOWER(__VA_ARGS__, xmm) ++ ++# define CMP_R1_R2(s1_reg, s2_reg, scratch_reg, reg_out, ext) \ ++ TOLOWER (s1_reg, scratch_reg, s2_reg, s2_reg, ext); \ ++ VPCMPEQ scratch_reg, s2_reg, reg_out ++ ++# define CMP_R1_S2(s1_reg, s2_mem, scratch_reg, reg_out, ext) \ ++ VMOVU s2_mem, reg_out; \ ++ CMP_R1_R2(s1_reg, reg_out, scratch_reg, reg_out, ext) ++ ++# define CMP_R1_R2_ymm(...) CMP_R1_R2(__VA_ARGS__, ymm) ++# define CMP_R1_R2_xmm(...) CMP_R1_R2(__VA_ARGS__, xmm) ++ ++# define CMP_R1_S2_ymm(...) CMP_R1_S2(__VA_ARGS__, ymm) ++# define CMP_R1_S2_xmm(...) CMP_R1_S2(__VA_ARGS__, xmm) ++ ++# else ++# define TOLOWER_gpr(...) ++# define TOLOWER_ymm(...) ++# define TOLOWER_xmm(...) ++ ++# define CMP_R1_R2_ymm(s1_reg, s2_reg, scratch_reg, reg_out) \ ++ VPCMPEQ s2_reg, s1_reg, reg_out ++ ++# define CMP_R1_R2_xmm(...) CMP_R1_R2_ymm(__VA_ARGS__) ++ ++# define CMP_R1_S2_ymm(...) CMP_R1_R2_ymm(__VA_ARGS__) ++# define CMP_R1_S2_xmm(...) CMP_R1_R2_xmm(__VA_ARGS__) ++# endif ++ + /* Warning! + wcscmp/wcsncmp have to use SIGNED comparison for elements. + strcmp/strncmp have to use UNSIGNED comparison for elements. +@@ -102,8 +181,49 @@ + returned. */ + + .section SECTION(.text), "ax", @progbits +-ENTRY(STRCMP) ++ .align 16 ++ .type STRCMP, @function ++ .globl STRCMP ++ .hidden STRCMP ++ ++# ifndef GLABEL ++# define GLABEL(...) __VA_ARGS__ ++# endif ++ ++# ifdef USE_AS_STRCASECMP_L ++ENTRY (GLABEL(STRCASECMP)) ++ movq __libc_tsd_LOCALE@gottpoff(%rip), %rax ++ mov %fs:(%rax), %LOCALE_REG_LP ++ ++ /* Either 1 or 5 bytes (dependeing if CET is enabled). */ ++ .p2align 4 ++END (GLABEL(STRCASECMP)) ++ /* FALLTHROUGH to strcasecmp/strncasecmp_l. */ ++# endif ++ ++ .p2align 4 ++STRCMP: ++ cfi_startproc ++ _CET_ENDBR ++ CALL_MCOUNT ++ ++# if defined USE_AS_STRCASECMP_L ++ /* We have to fall back on the C implementation for locales with ++ encodings not matching ASCII for single bytes. */ ++# if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0 ++ mov LOCALE_T___LOCALES + LC_CTYPE * LP_SIZE(%LOCALE_REG), %RAX_LP ++# else ++ mov (%LOCALE_REG), %RAX_LP ++# endif ++ testl $1, LOCALE_DATA_VALUES + _NL_CTYPE_NONASCII_CASE * SIZEOF_VALUES(%rax) ++ jne STRCASECMP_NONASCII ++ leaq _nl_C_LC_CTYPE_tolower + 128 * 4(%rip), TOLOWER_BASE ++# endif ++ + # ifdef USE_AS_STRNCMP ++ /* Don't overwrite LOCALE_REG (rcx) until we have pass ++ L(one_or_less). Otherwise we might use the wrong locale in ++ the OVERFLOW_STRCMP (strcasecmp_l). */ + # ifdef __ILP32__ + /* Clear the upper 32 bits. */ + movl %edx, %edx +@@ -128,6 +248,30 @@ ENTRY(STRCMP) + # endif + # endif + vpxor %xmmZERO, %xmmZERO, %xmmZERO ++# if defined USE_AS_STRCASECMP_L ++ .section .rodata.cst32, "aM", @progbits, 32 ++ .align 32 ++L(lcase_min): ++ .quad 0x3f3f3f3f3f3f3f3f ++ .quad 0x3f3f3f3f3f3f3f3f ++ .quad 0x3f3f3f3f3f3f3f3f ++ .quad 0x3f3f3f3f3f3f3f3f ++L(lcase_max): ++ .quad 0x9999999999999999 ++ .quad 0x9999999999999999 ++ .quad 0x9999999999999999 ++ .quad 0x9999999999999999 ++L(case_add): ++ .quad 0x2020202020202020 ++ .quad 0x2020202020202020 ++ .quad 0x2020202020202020 ++ .quad 0x2020202020202020 ++ .previous ++ ++ vmovdqa L(lcase_min)(%rip), LCASE_MIN_ymm ++ vmovdqa L(lcase_max)(%rip), LCASE_MAX_ymm ++ vmovdqa L(case_add)(%rip), CASE_ADD_ymm ++# endif + movl %edi, %eax + orl %esi, %eax + sall $20, %eax +@@ -138,8 +282,10 @@ ENTRY(STRCMP) + L(no_page_cross): + /* Safe to compare 4x vectors. */ + VMOVU (%rdi), %ymm0 +- /* 1s where s1 and s2 equal. */ +- VPCMPEQ (%rsi), %ymm0, %ymm1 ++ /* 1s where s1 and s2 equal. Just VPCMPEQ if its not strcasecmp. ++ Otherwise converts ymm0 and load from rsi to lower. ymm2 is ++ scratch and ymm1 is the return. */ ++ CMP_R1_S2_ymm (%ymm0, (%rsi), %ymm2, %ymm1) + /* 1s at null CHAR. */ + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + /* 1s where s1 and s2 equal AND not null CHAR. */ +@@ -172,6 +318,8 @@ L(return_vec_0): + # else + movzbl (%rdi, %rcx), %eax + movzbl (%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret0): +@@ -192,6 +340,10 @@ L(ret_zero): + + .p2align 4,, 5 + L(one_or_less): ++# ifdef USE_AS_STRCASECMP_L ++ /* Set locale argument for strcasecmp. */ ++ movq %LOCALE_REG, %rdx ++# endif + jb L(ret_zero) + # ifdef USE_AS_WCSCMP + /* 'nbe' covers the case where length is negative (large +@@ -211,6 +363,8 @@ L(one_or_less): + jnbe __strcmp_avx2 + movzbl (%rdi), %eax + movzbl (%rsi), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret1): +@@ -238,6 +392,8 @@ L(return_vec_1): + # else + movzbl VEC_SIZE(%rdi, %rcx), %eax + movzbl VEC_SIZE(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret2): +@@ -269,6 +425,8 @@ L(return_vec_2): + # else + movzbl (VEC_SIZE * 2)(%rdi, %rcx), %eax + movzbl (VEC_SIZE * 2)(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret3): +@@ -289,6 +447,8 @@ L(return_vec_3): + # else + movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax + movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret4): +@@ -299,7 +459,7 @@ L(ret4): + L(more_3x_vec): + /* Safe to compare 4x vectors. */ + VMOVU VEC_SIZE(%rdi), %ymm0 +- VPCMPEQ VEC_SIZE(%rsi), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, VEC_SIZE(%rsi), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -312,7 +472,7 @@ L(more_3x_vec): + # endif + + VMOVU (VEC_SIZE * 2)(%rdi), %ymm0 +- VPCMPEQ (VEC_SIZE * 2)(%rsi), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, (VEC_SIZE * 2)(%rsi), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -320,7 +480,7 @@ L(more_3x_vec): + jnz L(return_vec_2) + + VMOVU (VEC_SIZE * 3)(%rdi), %ymm0 +- VPCMPEQ (VEC_SIZE * 3)(%rsi), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, (VEC_SIZE * 3)(%rsi), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -395,12 +555,10 @@ L(loop_skip_page_cross_check): + VMOVA (VEC_SIZE * 3)(%rdi), %ymm6 + + /* ymm1 all 1s where s1 and s2 equal. All 0s otherwise. */ +- VPCMPEQ (VEC_SIZE * 0)(%rsi), %ymm0, %ymm1 +- +- VPCMPEQ (VEC_SIZE * 1)(%rsi), %ymm2, %ymm3 +- VPCMPEQ (VEC_SIZE * 2)(%rsi), %ymm4, %ymm5 +- VPCMPEQ (VEC_SIZE * 3)(%rsi), %ymm6, %ymm7 +- ++ CMP_R1_S2_ymm (%ymm0, (VEC_SIZE * 0)(%rsi), %ymm3, %ymm1) ++ CMP_R1_S2_ymm (%ymm2, (VEC_SIZE * 1)(%rsi), %ymm5, %ymm3) ++ CMP_R1_S2_ymm (%ymm4, (VEC_SIZE * 2)(%rsi), %ymm7, %ymm5) ++ CMP_R1_S2_ymm (%ymm6, (VEC_SIZE * 3)(%rsi), %ymm13, %ymm7) + + /* If any mismatches or null CHAR then 0 CHAR, otherwise non- + zero. */ +@@ -469,6 +627,8 @@ L(return_vec_2_3_end): + # else + movzbl (VEC_SIZE * 2 - VEC_OFFSET)(%rdi, %LOOP_REG64), %eax + movzbl (VEC_SIZE * 2 - VEC_OFFSET)(%rsi, %LOOP_REG64), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -512,6 +672,8 @@ L(return_vec_0_end): + # else + movzbl (%rdi, %rcx), %eax + movzbl (%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -534,6 +696,8 @@ L(return_vec_1_end): + # else + movzbl VEC_SIZE(%rdi, %rcx), %eax + movzbl VEC_SIZE(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -560,6 +724,8 @@ L(return_vec_2_end): + # else + movzbl (VEC_SIZE * 2)(%rdi, %rcx), %eax + movzbl (VEC_SIZE * 2)(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -587,7 +753,7 @@ L(page_cross_during_loop): + jle L(less_1x_vec_till_page_cross) + + VMOVA (%rdi), %ymm0 +- VPCMPEQ (%rsi), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, (%rsi), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -609,7 +775,7 @@ L(less_1x_vec_till_page_cross): + here, it means the previous page (rdi - VEC_SIZE) has already + been loaded earlier so must be valid. */ + VMOVU -VEC_SIZE(%rdi, %rax), %ymm0 +- VPCMPEQ -VEC_SIZE(%rsi, %rax), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, -VEC_SIZE(%rsi, %rax), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -651,6 +817,8 @@ L(return_page_cross_cmp_mem): + # else + movzbl VEC_OFFSET(%rdi, %rcx), %eax + movzbl VEC_OFFSET(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -677,7 +845,7 @@ L(more_2x_vec_till_page_cross): + iteration here. */ + + VMOVU VEC_SIZE(%rdi), %ymm0 +- VPCMPEQ VEC_SIZE(%rsi), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, VEC_SIZE(%rsi), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -693,7 +861,7 @@ L(more_2x_vec_till_page_cross): + + /* Safe to include comparisons from lower bytes. */ + VMOVU -(VEC_SIZE * 2)(%rdi, %rax), %ymm0 +- VPCMPEQ -(VEC_SIZE * 2)(%rsi, %rax), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, -(VEC_SIZE * 2)(%rsi, %rax), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -701,7 +869,7 @@ L(more_2x_vec_till_page_cross): + jnz L(return_vec_page_cross_0) + + VMOVU -(VEC_SIZE * 1)(%rdi, %rax), %ymm0 +- VPCMPEQ -(VEC_SIZE * 1)(%rsi, %rax), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, -(VEC_SIZE * 1)(%rsi, %rax), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -719,8 +887,8 @@ L(more_2x_vec_till_page_cross): + VMOVA (VEC_SIZE * 2)(%rdi), %ymm4 + VMOVA (VEC_SIZE * 3)(%rdi), %ymm6 + +- VPCMPEQ (VEC_SIZE * 2)(%rsi), %ymm4, %ymm5 +- VPCMPEQ (VEC_SIZE * 3)(%rsi), %ymm6, %ymm7 ++ CMP_R1_S2_ymm (%ymm4, (VEC_SIZE * 2)(%rsi), %ymm7, %ymm5) ++ CMP_R1_S2_ymm (%ymm6, (VEC_SIZE * 3)(%rsi), %ymm13, %ymm7) + vpand %ymm4, %ymm5, %ymm5 + vpand %ymm6, %ymm7, %ymm7 + VPMINU %ymm5, %ymm7, %ymm7 +@@ -771,6 +939,8 @@ L(return_vec_page_cross_1): + # else + movzbl VEC_OFFSET(%rdi, %rcx), %eax + movzbl VEC_OFFSET(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -826,7 +996,7 @@ L(page_cross): + L(page_cross_loop): + + VMOVU (%rdi, %OFFSET_REG64), %ymm0 +- VPCMPEQ (%rsi, %OFFSET_REG64), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, (%rsi, %OFFSET_REG64), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -844,11 +1014,11 @@ L(page_cross_loop): + subl %eax, %OFFSET_REG + /* OFFSET_REG has distance to page cross - VEC_SIZE. Guranteed + to not cross page so is safe to load. Since we have already +- loaded at least 1 VEC from rsi it is also guranteed to be safe. +- */ ++ loaded at least 1 VEC from rsi it is also guranteed to be ++ safe. */ + + VMOVU (%rdi, %OFFSET_REG64), %ymm0 +- VPCMPEQ (%rsi, %OFFSET_REG64), %ymm0, %ymm1 ++ CMP_R1_S2_ymm (%ymm0, (%rsi, %OFFSET_REG64), %ymm2, %ymm1) + VPCMPEQ %ymm0, %ymmZERO, %ymm2 + vpandn %ymm1, %ymm2, %ymm1 + vpmovmskb %ymm1, %ecx +@@ -881,6 +1051,8 @@ L(ret_vec_page_cross_cont): + # else + movzbl (%rdi, %rcx), %eax + movzbl (%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -934,7 +1106,7 @@ L(less_1x_vec_till_page): + ja L(less_16_till_page) + + VMOVU (%rdi), %xmm0 +- VPCMPEQ (%rsi), %xmm0, %xmm1 ++ CMP_R1_S2_xmm (%xmm0, (%rsi), %xmm2, %xmm1) + VPCMPEQ %xmm0, %xmmZERO, %xmm2 + vpandn %xmm1, %xmm2, %xmm1 + vpmovmskb %ymm1, %ecx +@@ -952,7 +1124,7 @@ L(less_1x_vec_till_page): + # endif + + VMOVU (%rdi, %OFFSET_REG64), %xmm0 +- VPCMPEQ (%rsi, %OFFSET_REG64), %xmm0, %xmm1 ++ CMP_R1_S2_xmm (%xmm0, (%rsi, %OFFSET_REG64), %xmm2, %xmm1) + VPCMPEQ %xmm0, %xmmZERO, %xmm2 + vpandn %xmm1, %xmm2, %xmm1 + vpmovmskb %ymm1, %ecx +@@ -990,7 +1162,7 @@ L(less_16_till_page): + vmovq (%rdi), %xmm0 + vmovq (%rsi), %xmm1 + VPCMPEQ %xmm0, %xmmZERO, %xmm2 +- VPCMPEQ %xmm1, %xmm0, %xmm1 ++ CMP_R1_R2_xmm (%xmm0, %xmm1, %xmm3, %xmm1) + vpandn %xmm1, %xmm2, %xmm1 + vpmovmskb %ymm1, %ecx + incb %cl +@@ -1010,7 +1182,7 @@ L(less_16_till_page): + vmovq (%rdi, %OFFSET_REG64), %xmm0 + vmovq (%rsi, %OFFSET_REG64), %xmm1 + VPCMPEQ %xmm0, %xmmZERO, %xmm2 +- VPCMPEQ %xmm1, %xmm0, %xmm1 ++ CMP_R1_R2_xmm (%xmm0, %xmm1, %xmm3, %xmm1) + vpandn %xmm1, %xmm2, %xmm1 + vpmovmskb %ymm1, %ecx + incb %cl +@@ -1066,7 +1238,7 @@ L(ret_less_8_wcs): + vmovd (%rdi), %xmm0 + vmovd (%rsi), %xmm1 + VPCMPEQ %xmm0, %xmmZERO, %xmm2 +- VPCMPEQ %xmm1, %xmm0, %xmm1 ++ CMP_R1_R2_xmm (%xmm0, %xmm1, %xmm3, %xmm1) + vpandn %xmm1, %xmm2, %xmm1 + vpmovmskb %ymm1, %ecx + subl $0xf, %ecx +@@ -1085,7 +1257,7 @@ L(ret_less_8_wcs): + vmovd (%rdi, %OFFSET_REG64), %xmm0 + vmovd (%rsi, %OFFSET_REG64), %xmm1 + VPCMPEQ %xmm0, %xmmZERO, %xmm2 +- VPCMPEQ %xmm1, %xmm0, %xmm1 ++ CMP_R1_R2_xmm (%xmm0, %xmm1, %xmm3, %xmm1) + vpandn %xmm1, %xmm2, %xmm1 + vpmovmskb %ymm1, %ecx + subl $0xf, %ecx +@@ -1119,7 +1291,9 @@ L(less_4_till_page): + L(less_4_loop): + movzbl (%rdi), %eax + movzbl (%rsi, %rdi), %ecx +- subl %ecx, %eax ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %BYTE_LOOP_REG) ++ subl %BYTE_LOOP_REG, %eax + jnz L(ret_less_4_loop) + testl %ecx, %ecx + jz L(ret_zero_4_loop) +@@ -1146,5 +1320,6 @@ L(ret_less_4_loop): + subl %r8d, %eax + ret + # endif +-END(STRCMP) ++ cfi_endproc ++ .size STRCMP, .-STRCMP + #endif +diff --git a/sysdeps/x86_64/multiarch/strncase_l-avx2-rtm.S b/sysdeps/x86_64/multiarch/strncase_l-avx2-rtm.S +new file mode 100644 +index 0000000000000000..58c05dcfb8643791 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strncase_l-avx2-rtm.S +@@ -0,0 +1,16 @@ ++#ifndef STRCMP ++# define STRCMP __strncasecmp_l_avx2_rtm ++#endif ++ ++#define _GLABEL(x) x ## _rtm ++#define GLABEL(x) _GLABEL(x) ++ ++#define ZERO_UPPER_VEC_REGISTERS_RETURN \ ++ ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST ++ ++#define VZEROUPPER_RETURN jmp L(return_vzeroupper) ++ ++#define SECTION(p) p##.avx.rtm ++#define OVERFLOW_STRCMP __strcasecmp_l_avx2_rtm ++ ++#include "strncase_l-avx2.S" +diff --git a/sysdeps/x86_64/multiarch/strncase_l-avx2.S b/sysdeps/x86_64/multiarch/strncase_l-avx2.S +new file mode 100644 +index 0000000000000000..48c0aa21f84ad32c +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strncase_l-avx2.S +@@ -0,0 +1,27 @@ ++/* strncasecmp_l optimized with AVX2. ++ Copyright (C) 2017-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef STRCMP ++# define STRCMP __strncasecmp_l_avx2 ++#endif ++#define USE_AS_STRCASECMP_L ++#define USE_AS_STRNCMP ++#ifndef OVERFLOW_STRCMP ++# define OVERFLOW_STRCMP __strcasecmp_l_avx2 ++#endif ++#include "strcmp-avx2.S" diff --git a/SOURCES/glibc-upstream-2.34-228.patch b/SOURCES/glibc-upstream-2.34-228.patch new file mode 100644 index 0000000..dee6598 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-228.patch @@ -0,0 +1,803 @@ +commit b13a2e68eb3b84f2a7b587132ec2ea813815febf +Author: Noah Goldstein +Date: Thu Mar 24 18:56:13 2022 -0500 + + x86: Add EVEX optimized str{n}casecmp + + geometric_mean(N=40) of all benchmarks EVEX / SSE42: .621 + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit 84e7c46df4086873eae28a1fb87d2cf5388b1e16) + +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index 711ecf2ee45d61b9..359712c1491a2431 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -53,6 +53,7 @@ sysdep_routines += \ + strcasecmp_l-avx \ + strcasecmp_l-avx2 \ + strcasecmp_l-avx2-rtm \ ++ strcasecmp_l-evex \ + strcasecmp_l-sse2 \ + strcasecmp_l-sse4_2 \ + strcasecmp_l-ssse3 \ +@@ -93,6 +94,7 @@ sysdep_routines += \ + strncase_l-avx \ + strncase_l-avx2 \ + strncase_l-avx2-rtm \ ++ strncase_l-evex \ + strncase_l-sse2 \ + strncase_l-sse4_2 \ + strncase_l-ssse3 \ +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index a687b387c91aa9ae..f6994e5406933d53 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -418,6 +418,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/x86_64/multiarch/strcasecmp_l.c. */ + IFUNC_IMPL (i, name, strcasecmp, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW)), ++ __strcasecmp_evex) + IFUNC_IMPL_ADD (array, i, strcasecmp, + CPU_FEATURE_USABLE (AVX2), + __strcasecmp_avx2) +@@ -438,6 +442,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/x86_64/multiarch/strcasecmp_l.c. */ + IFUNC_IMPL (i, name, strcasecmp_l, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW)), ++ __strcasecmp_l_evex) + IFUNC_IMPL_ADD (array, i, strcasecmp, + CPU_FEATURE_USABLE (AVX2), + __strcasecmp_l_avx2) +@@ -572,6 +580,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/x86_64/multiarch/strncase_l.c. */ + IFUNC_IMPL (i, name, strncasecmp, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW)), ++ __strncasecmp_evex) + IFUNC_IMPL_ADD (array, i, strncasecmp, + CPU_FEATURE_USABLE (AVX2), + __strncasecmp_avx2) +@@ -593,6 +605,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/x86_64/multiarch/strncase_l.c. */ + IFUNC_IMPL (i, name, strncasecmp_l, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW)), ++ __strncasecmp_l_evex) + IFUNC_IMPL_ADD (array, i, strncasecmp, + CPU_FEATURE_USABLE (AVX2), + __strncasecmp_l_avx2) +diff --git a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h +index 64d0cd6ef25f73c0..488e99e4997f379b 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h ++++ b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h +@@ -25,6 +25,7 @@ extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden; + + static inline void * + IFUNC_SELECTOR (void) +@@ -34,6 +35,10 @@ IFUNC_SELECTOR (void) + if (CPU_FEATURE_USABLE_P (cpu_features, AVX2) + && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load)) + { ++ if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) ++ && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)) ++ return OPTIMIZE (evex); ++ + if (CPU_FEATURE_USABLE_P (cpu_features, RTM)) + return OPTIMIZE (avx2_rtm); + +diff --git a/sysdeps/x86_64/multiarch/strcasecmp_l-evex.S b/sysdeps/x86_64/multiarch/strcasecmp_l-evex.S +new file mode 100644 +index 0000000000000000..58642db748e3db71 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strcasecmp_l-evex.S +@@ -0,0 +1,23 @@ ++/* strcasecmp_l optimized with EVEX. ++ Copyright (C) 2017-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef STRCMP ++# define STRCMP __strcasecmp_l_evex ++#endif ++#define USE_AS_STRCASECMP_L ++#include "strcmp-evex.S" +diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S +index 0dfa62bd149c02b4..b81b57753c38db1f 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-evex.S ++++ b/sysdeps/x86_64/multiarch/strcmp-evex.S +@@ -19,6 +19,9 @@ + #if IS_IN (libc) + + # include ++# if defined USE_AS_STRCASECMP_L ++# include "locale-defines.h" ++# endif + + # ifndef STRCMP + # define STRCMP __strcmp_evex +@@ -34,19 +37,29 @@ + # define VMOVA vmovdqa64 + + # ifdef USE_AS_WCSCMP +-# define TESTEQ subl $0xff, ++# ifndef OVERFLOW_STRCMP ++# define OVERFLOW_STRCMP __wcscmp_evex ++# endif ++ ++# define TESTEQ subl $0xff, + /* Compare packed dwords. */ + # define VPCMP vpcmpd + # define VPMINU vpminud + # define VPTESTM vptestmd ++# define VPTESTNM vptestnmd + /* 1 dword char == 4 bytes. */ + # define SIZE_OF_CHAR 4 + # else ++# ifndef OVERFLOW_STRCMP ++# define OVERFLOW_STRCMP __strcmp_evex ++# endif ++ + # define TESTEQ incl + /* Compare packed bytes. */ + # define VPCMP vpcmpb + # define VPMINU vpminub + # define VPTESTM vptestmb ++# define VPTESTNM vptestnmb + /* 1 byte char == 1 byte. */ + # define SIZE_OF_CHAR 1 + # endif +@@ -73,11 +86,16 @@ + # define VEC_OFFSET (-VEC_SIZE) + # endif + +-# define XMMZERO xmm16 + # define XMM0 xmm17 + # define XMM1 xmm18 + +-# define YMMZERO ymm16 ++# define XMM10 xmm27 ++# define XMM11 xmm28 ++# define XMM12 xmm29 ++# define XMM13 xmm30 ++# define XMM14 xmm31 ++ ++ + # define YMM0 ymm17 + # define YMM1 ymm18 + # define YMM2 ymm19 +@@ -89,6 +107,87 @@ + # define YMM8 ymm25 + # define YMM9 ymm26 + # define YMM10 ymm27 ++# define YMM11 ymm28 ++# define YMM12 ymm29 ++# define YMM13 ymm30 ++# define YMM14 ymm31 ++ ++# ifdef USE_AS_STRCASECMP_L ++# define BYTE_LOOP_REG OFFSET_REG ++# else ++# define BYTE_LOOP_REG ecx ++# endif ++ ++# ifdef USE_AS_STRCASECMP_L ++# ifdef USE_AS_STRNCMP ++# define STRCASECMP __strncasecmp_evex ++# define LOCALE_REG rcx ++# define LOCALE_REG_LP RCX_LP ++# define STRCASECMP_NONASCII __strncasecmp_l_nonascii ++# else ++# define STRCASECMP __strcasecmp_evex ++# define LOCALE_REG rdx ++# define LOCALE_REG_LP RDX_LP ++# define STRCASECMP_NONASCII __strcasecmp_l_nonascii ++# endif ++# endif ++ ++# define LCASE_MIN_YMM %YMM12 ++# define LCASE_MAX_YMM %YMM13 ++# define CASE_ADD_YMM %YMM14 ++ ++# define LCASE_MIN_XMM %XMM12 ++# define LCASE_MAX_XMM %XMM13 ++# define CASE_ADD_XMM %XMM14 ++ ++ /* NB: wcsncmp uses r11 but strcasecmp is never used in ++ conjunction with wcscmp. */ ++# define TOLOWER_BASE %r11 ++ ++# ifdef USE_AS_STRCASECMP_L ++# define _REG(x, y) x ## y ++# define REG(x, y) _REG(x, y) ++# define TOLOWER(reg1, reg2, ext) \ ++ vpsubb REG(LCASE_MIN_, ext), reg1, REG(%ext, 10); \ ++ vpsubb REG(LCASE_MIN_, ext), reg2, REG(%ext, 11); \ ++ vpcmpub $1, REG(LCASE_MAX_, ext), REG(%ext, 10), %k5; \ ++ vpcmpub $1, REG(LCASE_MAX_, ext), REG(%ext, 11), %k6; \ ++ vpaddb reg1, REG(CASE_ADD_, ext), reg1{%k5}; \ ++ vpaddb reg2, REG(CASE_ADD_, ext), reg2{%k6} ++ ++# define TOLOWER_gpr(src, dst) movl (TOLOWER_BASE, src, 4), dst ++# define TOLOWER_YMM(...) TOLOWER(__VA_ARGS__, YMM) ++# define TOLOWER_XMM(...) TOLOWER(__VA_ARGS__, XMM) ++ ++# define CMP_R1_R2(s1_reg, s2_reg, reg_out, ext) \ ++ TOLOWER (s1_reg, s2_reg, ext); \ ++ VPCMP $0, s1_reg, s2_reg, reg_out ++ ++# define CMP_R1_S2(s1_reg, s2_mem, s2_reg, reg_out, ext) \ ++ VMOVU s2_mem, s2_reg; \ ++ CMP_R1_R2(s1_reg, s2_reg, reg_out, ext) ++ ++# define CMP_R1_R2_YMM(...) CMP_R1_R2(__VA_ARGS__, YMM) ++# define CMP_R1_R2_XMM(...) CMP_R1_R2(__VA_ARGS__, XMM) ++ ++# define CMP_R1_S2_YMM(...) CMP_R1_S2(__VA_ARGS__, YMM) ++# define CMP_R1_S2_XMM(...) CMP_R1_S2(__VA_ARGS__, XMM) ++ ++# else ++# define TOLOWER_gpr(...) ++# define TOLOWER_YMM(...) ++# define TOLOWER_XMM(...) ++ ++# define CMP_R1_R2_YMM(s1_reg, s2_reg, reg_out) \ ++ VPCMP $0, s2_reg, s1_reg, reg_out ++ ++# define CMP_R1_R2_XMM(...) CMP_R1_R2_YMM(__VA_ARGS__) ++ ++# define CMP_R1_S2_YMM(s1_reg, s2_mem, unused, reg_out) \ ++ VPCMP $0, s2_mem, s1_reg, reg_out ++ ++# define CMP_R1_S2_XMM(...) CMP_R1_S2_YMM(__VA_ARGS__) ++# endif + + /* Warning! + wcscmp/wcsncmp have to use SIGNED comparison for elements. +@@ -112,8 +211,45 @@ + returned. */ + + .section .text.evex, "ax", @progbits +-ENTRY(STRCMP) ++ .align 16 ++ .type STRCMP, @function ++ .globl STRCMP ++ .hidden STRCMP ++ ++# ifdef USE_AS_STRCASECMP_L ++ENTRY (STRCASECMP) ++ movq __libc_tsd_LOCALE@gottpoff(%rip), %rax ++ mov %fs:(%rax), %LOCALE_REG_LP ++ ++ /* Either 1 or 5 bytes (dependeing if CET is enabled). */ ++ .p2align 4 ++END (STRCASECMP) ++ /* FALLTHROUGH to strcasecmp/strncasecmp_l. */ ++# endif ++ ++ .p2align 4 ++STRCMP: ++ cfi_startproc ++ _CET_ENDBR ++ CALL_MCOUNT ++ ++# if defined USE_AS_STRCASECMP_L ++ /* We have to fall back on the C implementation for locales with ++ encodings not matching ASCII for single bytes. */ ++# if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0 ++ mov LOCALE_T___LOCALES + LC_CTYPE * LP_SIZE(%LOCALE_REG), %RAX_LP ++# else ++ mov (%LOCALE_REG), %RAX_LP ++# endif ++ testl $1, LOCALE_DATA_VALUES + _NL_CTYPE_NONASCII_CASE * SIZEOF_VALUES(%rax) ++ jne STRCASECMP_NONASCII ++ leaq _nl_C_LC_CTYPE_tolower + 128 * 4(%rip), TOLOWER_BASE ++# endif ++ + # ifdef USE_AS_STRNCMP ++ /* Don't overwrite LOCALE_REG (rcx) until we have pass ++ L(one_or_less). Otherwise we might use the wrong locale in ++ the OVERFLOW_STRCMP (strcasecmp_l). */ + # ifdef __ILP32__ + /* Clear the upper 32 bits. */ + movl %edx, %edx +@@ -125,6 +261,32 @@ ENTRY(STRCMP) + actually bound the buffer. */ + jle L(one_or_less) + # endif ++ ++# if defined USE_AS_STRCASECMP_L ++ .section .rodata.cst32, "aM", @progbits, 32 ++ .align 32 ++L(lcase_min): ++ .quad 0x4141414141414141 ++ .quad 0x4141414141414141 ++ .quad 0x4141414141414141 ++ .quad 0x4141414141414141 ++L(lcase_max): ++ .quad 0x1a1a1a1a1a1a1a1a ++ .quad 0x1a1a1a1a1a1a1a1a ++ .quad 0x1a1a1a1a1a1a1a1a ++ .quad 0x1a1a1a1a1a1a1a1a ++L(case_add): ++ .quad 0x2020202020202020 ++ .quad 0x2020202020202020 ++ .quad 0x2020202020202020 ++ .quad 0x2020202020202020 ++ .previous ++ ++ vmovdqa64 L(lcase_min)(%rip), LCASE_MIN_YMM ++ vmovdqa64 L(lcase_max)(%rip), LCASE_MAX_YMM ++ vmovdqa64 L(case_add)(%rip), CASE_ADD_YMM ++# endif ++ + movl %edi, %eax + orl %esi, %eax + /* Shift out the bits irrelivant to page boundary ([63:12]). */ +@@ -139,7 +301,7 @@ L(no_page_cross): + VPTESTM %YMM0, %YMM0, %k2 + /* Each bit cleared in K1 represents a mismatch or a null CHAR + in YMM0 and 32 bytes at (%rsi). */ +- VPCMP $0, (%rsi), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, (%rsi), %YMM1, %k1){%k2} + kmovd %k1, %ecx + # ifdef USE_AS_STRNCMP + cmpq $CHAR_PER_VEC, %rdx +@@ -169,6 +331,8 @@ L(return_vec_0): + # else + movzbl (%rdi, %rcx), %eax + movzbl (%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret0): +@@ -188,11 +352,15 @@ L(ret_zero): + + .p2align 4,, 5 + L(one_or_less): ++# ifdef USE_AS_STRCASECMP_L ++ /* Set locale argument for strcasecmp. */ ++ movq %LOCALE_REG, %rdx ++# endif + jb L(ret_zero) +-# ifdef USE_AS_WCSCMP + /* 'nbe' covers the case where length is negative (large + unsigned). */ +- jnbe __wcscmp_evex ++ jnbe OVERFLOW_STRCMP ++# ifdef USE_AS_WCSCMP + movl (%rdi), %edx + xorl %eax, %eax + cmpl (%rsi), %edx +@@ -201,11 +369,10 @@ L(one_or_less): + negl %eax + orl $1, %eax + # else +- /* 'nbe' covers the case where length is negative (large +- unsigned). */ +- jnbe __strcmp_evex + movzbl (%rdi), %eax + movzbl (%rsi), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret1): +@@ -233,6 +400,8 @@ L(return_vec_1): + # else + movzbl VEC_SIZE(%rdi, %rcx), %eax + movzbl VEC_SIZE(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret2): +@@ -270,6 +439,8 @@ L(return_vec_2): + # else + movzbl (VEC_SIZE * 2)(%rdi, %rcx), %eax + movzbl (VEC_SIZE * 2)(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret3): +@@ -290,6 +461,8 @@ L(return_vec_3): + # else + movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax + movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + # endif + L(ret4): +@@ -303,7 +476,7 @@ L(more_3x_vec): + /* Safe to compare 4x vectors. */ + VMOVU (VEC_SIZE)(%rdi), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, (VEC_SIZE)(%rsi), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, VEC_SIZE(%rsi), %YMM1, %k1){%k2} + kmovd %k1, %ecx + TESTEQ %ecx + jnz L(return_vec_1) +@@ -315,14 +488,14 @@ L(more_3x_vec): + + VMOVU (VEC_SIZE * 2)(%rdi), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, (VEC_SIZE * 2)(%rsi), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, (VEC_SIZE * 2)(%rsi), %YMM1, %k1){%k2} + kmovd %k1, %ecx + TESTEQ %ecx + jnz L(return_vec_2) + + VMOVU (VEC_SIZE * 3)(%rdi), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, (VEC_SIZE * 3)(%rsi), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, (VEC_SIZE * 3)(%rsi), %YMM1, %k1){%k2} + kmovd %k1, %ecx + TESTEQ %ecx + jnz L(return_vec_3) +@@ -381,7 +554,6 @@ L(prepare_loop_aligned): + subl %esi, %eax + andl $(PAGE_SIZE - 1), %eax + +- vpxorq %YMMZERO, %YMMZERO, %YMMZERO + + /* Loop 4x comparisons at a time. */ + .p2align 4 +@@ -413,22 +585,35 @@ L(loop_skip_page_cross_check): + /* A zero CHAR in YMM9 means that there is a null CHAR. */ + VPMINU %YMM8, %YMM9, %YMM9 + +- /* Each bit set in K1 represents a non-null CHAR in YMM8. */ ++ /* Each bit set in K1 represents a non-null CHAR in YMM9. */ + VPTESTM %YMM9, %YMM9, %k1 +- ++# ifndef USE_AS_STRCASECMP_L + vpxorq (VEC_SIZE * 0)(%rsi), %YMM0, %YMM1 + vpxorq (VEC_SIZE * 1)(%rsi), %YMM2, %YMM3 + vpxorq (VEC_SIZE * 2)(%rsi), %YMM4, %YMM5 + /* Ternary logic to xor (VEC_SIZE * 3)(%rsi) with YMM6 while + oring with YMM1. Result is stored in YMM6. */ + vpternlogd $0xde, (VEC_SIZE * 3)(%rsi), %YMM1, %YMM6 +- ++# else ++ VMOVU (VEC_SIZE * 0)(%rsi), %YMM1 ++ TOLOWER_YMM (%YMM0, %YMM1) ++ VMOVU (VEC_SIZE * 1)(%rsi), %YMM3 ++ TOLOWER_YMM (%YMM2, %YMM3) ++ VMOVU (VEC_SIZE * 2)(%rsi), %YMM5 ++ TOLOWER_YMM (%YMM4, %YMM5) ++ VMOVU (VEC_SIZE * 3)(%rsi), %YMM7 ++ TOLOWER_YMM (%YMM6, %YMM7) ++ vpxorq %YMM0, %YMM1, %YMM1 ++ vpxorq %YMM2, %YMM3, %YMM3 ++ vpxorq %YMM4, %YMM5, %YMM5 ++ vpternlogd $0xde, %YMM7, %YMM1, %YMM6 ++# endif + /* Or together YMM3, YMM5, and YMM6. */ + vpternlogd $0xfe, %YMM3, %YMM5, %YMM6 + + + /* A non-zero CHAR in YMM6 represents a mismatch. */ +- VPCMP $0, %YMMZERO, %YMM6, %k0{%k1} ++ VPTESTNM %YMM6, %YMM6, %k0{%k1} + kmovd %k0, %LOOP_REG + + TESTEQ %LOOP_REG +@@ -437,13 +622,13 @@ L(loop_skip_page_cross_check): + + /* Find which VEC has the mismatch of end of string. */ + VPTESTM %YMM0, %YMM0, %k1 +- VPCMP $0, %YMMZERO, %YMM1, %k0{%k1} ++ VPTESTNM %YMM1, %YMM1, %k0{%k1} + kmovd %k0, %ecx + TESTEQ %ecx + jnz L(return_vec_0_end) + + VPTESTM %YMM2, %YMM2, %k1 +- VPCMP $0, %YMMZERO, %YMM3, %k0{%k1} ++ VPTESTNM %YMM3, %YMM3, %k0{%k1} + kmovd %k0, %ecx + TESTEQ %ecx + jnz L(return_vec_1_end) +@@ -457,7 +642,7 @@ L(return_vec_2_3_end): + # endif + + VPTESTM %YMM4, %YMM4, %k1 +- VPCMP $0, %YMMZERO, %YMM5, %k0{%k1} ++ VPTESTNM %YMM5, %YMM5, %k0{%k1} + kmovd %k0, %ecx + TESTEQ %ecx + # if CHAR_PER_VEC <= 16 +@@ -493,6 +678,8 @@ L(return_vec_3_end): + # else + movzbl (VEC_SIZE * 2)(%rdi, %LOOP_REG64), %eax + movzbl (VEC_SIZE * 2)(%rsi, %LOOP_REG64), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -545,6 +732,8 @@ L(return_vec_0_end): + # else + movzbl (%rdi, %rcx), %eax + movzbl (%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + /* Flip `eax` if `rdi` and `rsi` where swapped in page cross + logic. Subtract `r8d` after xor for zero case. */ +@@ -569,6 +758,8 @@ L(return_vec_1_end): + # else + movzbl VEC_SIZE(%rdi, %rcx), %eax + movzbl VEC_SIZE(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -598,7 +789,7 @@ L(page_cross_during_loop): + + VMOVA (%rdi), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, (%rsi), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, (%rsi), %YMM1, %k1){%k2} + kmovd %k1, %ecx + TESTEQ %ecx + jnz L(return_vec_0_end) +@@ -619,8 +810,7 @@ L(less_1x_vec_till_page_cross): + been loaded earlier so must be valid. */ + VMOVU -VEC_SIZE(%rdi, %rax), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, -VEC_SIZE(%rsi, %rax), %YMM0, %k1{%k2} +- ++ CMP_R1_S2_YMM (%YMM0, -VEC_SIZE(%rsi, %rax), %YMM1, %k1){%k2} + /* Mask of potentially valid bits. The lower bits can be out of + range comparisons (but safe regarding page crosses). */ + +@@ -642,6 +832,8 @@ L(less_1x_vec_till_page_cross): + + # ifdef USE_AS_STRNCMP + # ifdef USE_AS_WCSCMP ++ /* NB: strcasecmp not used with WCSCMP so this access to r11 is ++ safe. */ + movl %eax, %r11d + shrl $2, %r11d + cmpq %r11, %rdx +@@ -679,6 +871,8 @@ L(return_page_cross_cmp_mem): + # else + movzbl VEC_OFFSET(%rdi, %rcx), %eax + movzbl VEC_OFFSET(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -709,7 +903,7 @@ L(more_2x_vec_till_page_cross): + + VMOVA VEC_SIZE(%rdi), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, VEC_SIZE(%rsi), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, VEC_SIZE(%rsi), %YMM1, %k1){%k2} + kmovd %k1, %ecx + TESTEQ %ecx + jnz L(return_vec_1_end) +@@ -724,14 +918,14 @@ L(more_2x_vec_till_page_cross): + /* Safe to include comparisons from lower bytes. */ + VMOVU -(VEC_SIZE * 2)(%rdi, %rax), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, -(VEC_SIZE * 2)(%rsi, %rax), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, -(VEC_SIZE * 2)(%rsi, %rax), %YMM1, %k1){%k2} + kmovd %k1, %ecx + TESTEQ %ecx + jnz L(return_vec_page_cross_0) + + VMOVU -(VEC_SIZE * 1)(%rdi, %rax), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, -(VEC_SIZE * 1)(%rsi, %rax), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, -(VEC_SIZE * 1)(%rsi, %rax), %YMM1, %k1){%k2} + kmovd %k1, %ecx + TESTEQ %ecx + jnz L(return_vec_page_cross_1) +@@ -740,6 +934,8 @@ L(more_2x_vec_till_page_cross): + /* Must check length here as length might proclude reading next + page. */ + # ifdef USE_AS_WCSCMP ++ /* NB: strcasecmp not used with WCSCMP so this access to r11 is ++ safe. */ + movl %eax, %r11d + shrl $2, %r11d + cmpq %r11, %rdx +@@ -754,12 +950,19 @@ L(more_2x_vec_till_page_cross): + VMOVA (VEC_SIZE * 3)(%rdi), %YMM6 + VPMINU %YMM4, %YMM6, %YMM9 + VPTESTM %YMM9, %YMM9, %k1 +- ++# ifndef USE_AS_STRCASECMP_L + vpxorq (VEC_SIZE * 2)(%rsi), %YMM4, %YMM5 + /* YMM6 = YMM5 | ((VEC_SIZE * 3)(%rsi) ^ YMM6). */ + vpternlogd $0xde, (VEC_SIZE * 3)(%rsi), %YMM5, %YMM6 +- +- VPCMP $0, %YMMZERO, %YMM6, %k0{%k1} ++# else ++ VMOVU (VEC_SIZE * 2)(%rsi), %YMM5 ++ TOLOWER_YMM (%YMM4, %YMM5) ++ VMOVU (VEC_SIZE * 3)(%rsi), %YMM7 ++ TOLOWER_YMM (%YMM6, %YMM7) ++ vpxorq %YMM4, %YMM5, %YMM5 ++ vpternlogd $0xde, %YMM7, %YMM5, %YMM6 ++# endif ++ VPTESTNM %YMM6, %YMM6, %k0{%k1} + kmovd %k0, %LOOP_REG + TESTEQ %LOOP_REG + jnz L(return_vec_2_3_end) +@@ -815,6 +1018,8 @@ L(return_vec_page_cross_1): + # else + movzbl VEC_OFFSET(%rdi, %rcx), %eax + movzbl VEC_OFFSET(%rsi, %rcx), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -871,7 +1076,7 @@ L(page_cross): + L(page_cross_loop): + VMOVU (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM1, %k1){%k2} + kmovd %k1, %ecx + TESTEQ %ecx + jnz L(check_ret_vec_page_cross) +@@ -895,7 +1100,7 @@ L(page_cross_loop): + */ + VMOVU (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM0 + VPTESTM %YMM0, %YMM0, %k2 +- VPCMP $0, (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM0, %k1{%k2} ++ CMP_R1_S2_YMM (%YMM0, (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %YMM1, %k1){%k2} + + kmovd %k1, %ecx + # ifdef USE_AS_STRNCMP +@@ -930,6 +1135,8 @@ L(ret_vec_page_cross_cont): + # else + movzbl (%rdi, %rcx, SIZE_OF_CHAR), %eax + movzbl (%rsi, %rcx, SIZE_OF_CHAR), %ecx ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %ecx) + subl %ecx, %eax + xorl %r8d, %eax + subl %r8d, %eax +@@ -989,7 +1196,7 @@ L(less_1x_vec_till_page): + /* Use 16 byte comparison. */ + vmovdqu (%rdi), %xmm0 + VPTESTM %xmm0, %xmm0, %k2 +- VPCMP $0, (%rsi), %xmm0, %k1{%k2} ++ CMP_R1_S2_XMM (%xmm0, (%rsi), %xmm1, %k1){%k2} + kmovd %k1, %ecx + # ifdef USE_AS_WCSCMP + subl $0xf, %ecx +@@ -1009,7 +1216,7 @@ L(less_1x_vec_till_page): + # endif + vmovdqu (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm0 + VPTESTM %xmm0, %xmm0, %k2 +- VPCMP $0, (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm0, %k1{%k2} ++ CMP_R1_S2_XMM (%xmm0, (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm1, %k1){%k2} + kmovd %k1, %ecx + # ifdef USE_AS_WCSCMP + subl $0xf, %ecx +@@ -1048,7 +1255,7 @@ L(less_16_till_page): + vmovq (%rdi), %xmm0 + vmovq (%rsi), %xmm1 + VPTESTM %xmm0, %xmm0, %k2 +- VPCMP $0, %xmm1, %xmm0, %k1{%k2} ++ CMP_R1_R2_XMM (%xmm0, %xmm1, %k1){%k2} + kmovd %k1, %ecx + # ifdef USE_AS_WCSCMP + subl $0x3, %ecx +@@ -1068,7 +1275,7 @@ L(less_16_till_page): + vmovq (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm0 + vmovq (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm1 + VPTESTM %xmm0, %xmm0, %k2 +- VPCMP $0, %xmm1, %xmm0, %k1{%k2} ++ CMP_R1_R2_XMM (%xmm0, %xmm1, %k1){%k2} + kmovd %k1, %ecx + # ifdef USE_AS_WCSCMP + subl $0x3, %ecx +@@ -1128,7 +1335,7 @@ L(ret_less_8_wcs): + vmovd (%rdi), %xmm0 + vmovd (%rsi), %xmm1 + VPTESTM %xmm0, %xmm0, %k2 +- VPCMP $0, %xmm1, %xmm0, %k1{%k2} ++ CMP_R1_R2_XMM (%xmm0, %xmm1, %k1){%k2} + kmovd %k1, %ecx + subl $0xf, %ecx + jnz L(check_ret_vec_page_cross) +@@ -1143,7 +1350,7 @@ L(ret_less_8_wcs): + vmovd (%rdi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm0 + vmovd (%rsi, %OFFSET_REG64, SIZE_OF_CHAR), %xmm1 + VPTESTM %xmm0, %xmm0, %k2 +- VPCMP $0, %xmm1, %xmm0, %k1{%k2} ++ CMP_R1_R2_XMM (%xmm0, %xmm1, %k1){%k2} + kmovd %k1, %ecx + subl $0xf, %ecx + jnz L(check_ret_vec_page_cross) +@@ -1176,7 +1383,9 @@ L(less_4_till_page): + L(less_4_loop): + movzbl (%rdi), %eax + movzbl (%rsi, %rdi), %ecx +- subl %ecx, %eax ++ TOLOWER_gpr (%rax, %eax) ++ TOLOWER_gpr (%rcx, %BYTE_LOOP_REG) ++ subl %BYTE_LOOP_REG, %eax + jnz L(ret_less_4_loop) + testl %ecx, %ecx + jz L(ret_zero_4_loop) +@@ -1203,5 +1412,6 @@ L(ret_less_4_loop): + subl %r8d, %eax + ret + # endif +-END(STRCMP) ++ cfi_endproc ++ .size STRCMP, .-STRCMP + #endif +diff --git a/sysdeps/x86_64/multiarch/strncase_l-evex.S b/sysdeps/x86_64/multiarch/strncase_l-evex.S +new file mode 100644 +index 0000000000000000..8a5af3695cb8cfff +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strncase_l-evex.S +@@ -0,0 +1,25 @@ ++/* strncasecmp_l optimized with EVEX. ++ Copyright (C) 2017-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef STRCMP ++# define STRCMP __strncasecmp_l_evex ++#endif ++#define OVERFLOW_STRCMP __strcasecmp_l_evex ++#define USE_AS_STRCASECMP_L ++#define USE_AS_STRNCMP ++#include "strcmp-evex.S" diff --git a/SOURCES/glibc-upstream-2.34-229.patch b/SOURCES/glibc-upstream-2.34-229.patch new file mode 100644 index 0000000..97f6bbd --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-229.patch @@ -0,0 +1,902 @@ +commit 80883f43545f4f9afcb26beef9358dfdcd021bd6 +Author: Noah Goldstein +Date: Wed Mar 23 16:57:46 2022 -0500 + + x86: Remove AVX str{n}casecmp + + The rational is: + + 1. SSE42 has nearly identical logic so any benefit is minimal (3.4% + regression on Tigerlake using SSE42 versus AVX across the + benchtest suite). + 2. AVX2 version covers the majority of targets that previously + prefered it. + 3. The targets where AVX would still be best (SnB and IVB) are + becoming outdated. + + All in all the saving the code size is worth it. + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit 305769b2a15c2e96f9e1b5195d3c4e0d6f0f4b68) + +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index 359712c1491a2431..bca82e38d86cc440 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -50,7 +50,6 @@ sysdep_routines += \ + stpncpy-evex \ + stpncpy-sse2-unaligned \ + stpncpy-ssse3 \ +- strcasecmp_l-avx \ + strcasecmp_l-avx2 \ + strcasecmp_l-avx2-rtm \ + strcasecmp_l-evex \ +@@ -91,7 +90,6 @@ sysdep_routines += \ + strlen-avx2-rtm \ + strlen-evex \ + strlen-sse2 \ +- strncase_l-avx \ + strncase_l-avx2 \ + strncase_l-avx2-rtm \ + strncase_l-evex \ +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index f6994e5406933d53..4c7834dd0b951fa4 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -429,9 +429,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + (CPU_FEATURE_USABLE (AVX2) + && CPU_FEATURE_USABLE (RTM)), + __strcasecmp_avx2_rtm) +- IFUNC_IMPL_ADD (array, i, strcasecmp, +- CPU_FEATURE_USABLE (AVX), +- __strcasecmp_avx) + IFUNC_IMPL_ADD (array, i, strcasecmp, + CPU_FEATURE_USABLE (SSE4_2), + __strcasecmp_sse42) +@@ -453,9 +450,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + (CPU_FEATURE_USABLE (AVX2) + && CPU_FEATURE_USABLE (RTM)), + __strcasecmp_l_avx2_rtm) +- IFUNC_IMPL_ADD (array, i, strcasecmp_l, +- CPU_FEATURE_USABLE (AVX), +- __strcasecmp_l_avx) + IFUNC_IMPL_ADD (array, i, strcasecmp_l, + CPU_FEATURE_USABLE (SSE4_2), + __strcasecmp_l_sse42) +@@ -591,9 +585,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + (CPU_FEATURE_USABLE (AVX2) + && CPU_FEATURE_USABLE (RTM)), + __strncasecmp_avx2_rtm) +- IFUNC_IMPL_ADD (array, i, strncasecmp, +- CPU_FEATURE_USABLE (AVX), +- __strncasecmp_avx) + IFUNC_IMPL_ADD (array, i, strncasecmp, + CPU_FEATURE_USABLE (SSE4_2), + __strncasecmp_sse42) +@@ -616,9 +607,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + (CPU_FEATURE_USABLE (AVX2) + && CPU_FEATURE_USABLE (RTM)), + __strncasecmp_l_avx2_rtm) +- IFUNC_IMPL_ADD (array, i, strncasecmp_l, +- CPU_FEATURE_USABLE (AVX), +- __strncasecmp_l_avx) + IFUNC_IMPL_ADD (array, i, strncasecmp_l, + CPU_FEATURE_USABLE (SSE4_2), + __strncasecmp_l_sse42) +diff --git a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h +index 488e99e4997f379b..40819caf5ab10337 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h ++++ b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h +@@ -22,7 +22,6 @@ + extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE (avx) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden; +@@ -46,9 +45,6 @@ IFUNC_SELECTOR (void) + return OPTIMIZE (avx2); + } + +- if (CPU_FEATURE_USABLE_P (cpu_features, AVX)) +- return OPTIMIZE (avx); +- + if (CPU_FEATURE_USABLE_P (cpu_features, SSE4_2) + && !CPU_FEATURES_ARCH_P (cpu_features, Slow_SSE4_2)) + return OPTIMIZE (sse42); +diff --git a/sysdeps/x86_64/multiarch/strcasecmp_l-avx.S b/sysdeps/x86_64/multiarch/strcasecmp_l-avx.S +deleted file mode 100644 +index 647aa05714d7a36c..0000000000000000 +--- a/sysdeps/x86_64/multiarch/strcasecmp_l-avx.S ++++ /dev/null +@@ -1,22 +0,0 @@ +-/* strcasecmp_l optimized with AVX. +- Copyright (C) 2017-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#define STRCMP_SSE42 __strcasecmp_l_avx +-#define USE_AVX 1 +-#define USE_AS_STRCASECMP_L +-#include "strcmp-sse42.S" +diff --git a/sysdeps/x86_64/multiarch/strcmp-sse42.S b/sysdeps/x86_64/multiarch/strcmp-sse42.S +index a6825de8195ad8c6..466c6a92a612ebcb 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-sse42.S ++++ b/sysdeps/x86_64/multiarch/strcmp-sse42.S +@@ -42,13 +42,8 @@ + # define UPDATE_STRNCMP_COUNTER + #endif + +-#ifdef USE_AVX +-# define SECTION avx +-# define GLABEL(l) l##_avx +-#else +-# define SECTION sse4.2 +-# define GLABEL(l) l##_sse42 +-#endif ++#define SECTION sse4.2 ++#define GLABEL(l) l##_sse42 + + #define LABEL(l) .L##l + +@@ -106,21 +101,7 @@ END (GLABEL(__strncasecmp)) + #endif + + +-#ifdef USE_AVX +-# define movdqa vmovdqa +-# define movdqu vmovdqu +-# define pmovmskb vpmovmskb +-# define pcmpistri vpcmpistri +-# define psubb vpsubb +-# define pcmpeqb vpcmpeqb +-# define psrldq vpsrldq +-# define pslldq vpslldq +-# define palignr vpalignr +-# define pxor vpxor +-# define D(arg) arg, arg +-#else +-# define D(arg) arg +-#endif ++#define arg arg + + STRCMP_SSE42: + cfi_startproc +@@ -192,18 +173,7 @@ LABEL(case_add): + movdqu (%rdi), %xmm1 + movdqu (%rsi), %xmm2 + #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L +-# ifdef USE_AVX +-# define TOLOWER(reg1, reg2) \ +- vpaddb LCASE_MIN_reg, reg1, %xmm7; \ +- vpaddb LCASE_MIN_reg, reg2, %xmm8; \ +- vpcmpgtb LCASE_MAX_reg, %xmm7, %xmm7; \ +- vpcmpgtb LCASE_MAX_reg, %xmm8, %xmm8; \ +- vpandn CASE_ADD_reg, %xmm7, %xmm7; \ +- vpandn CASE_ADD_reg, %xmm8, %xmm8; \ +- vpaddb %xmm7, reg1, reg1; \ +- vpaddb %xmm8, reg2, reg2 +-# else +-# define TOLOWER(reg1, reg2) \ ++# define TOLOWER(reg1, reg2) \ + movdqa LCASE_MIN_reg, %xmm7; \ + movdqa LCASE_MIN_reg, %xmm8; \ + paddb reg1, %xmm7; \ +@@ -214,15 +184,15 @@ LABEL(case_add): + pandn CASE_ADD_reg, %xmm8; \ + paddb %xmm7, reg1; \ + paddb %xmm8, reg2 +-# endif ++ + TOLOWER (%xmm1, %xmm2) + #else + # define TOLOWER(reg1, reg2) + #endif +- pxor %xmm0, D(%xmm0) /* clear %xmm0 for null char checks */ +- pcmpeqb %xmm1, D(%xmm0) /* Any null chars? */ +- pcmpeqb %xmm2, D(%xmm1) /* compare first 16 bytes for equality */ +- psubb %xmm0, D(%xmm1) /* packed sub of comparison results*/ ++ pxor %xmm0, %xmm0 /* clear %xmm0 for null char checks */ ++ pcmpeqb %xmm1, %xmm0 /* Any null chars? */ ++ pcmpeqb %xmm2, %xmm1 /* compare first 16 bytes for equality */ ++ psubb %xmm0, %xmm1 /* packed sub of comparison results*/ + pmovmskb %xmm1, %edx + sub $0xffff, %edx /* if first 16 bytes are same, edx == 0xffff */ + jnz LABEL(less16bytes)/* If not, find different value or null char */ +@@ -246,7 +216,7 @@ LABEL(crosscache): + xor %r8d, %r8d + and $0xf, %ecx /* offset of rsi */ + and $0xf, %eax /* offset of rdi */ +- pxor %xmm0, D(%xmm0) /* clear %xmm0 for null char check */ ++ pxor %xmm0, %xmm0 /* clear %xmm0 for null char check */ + cmp %eax, %ecx + je LABEL(ashr_0) /* rsi and rdi relative offset same */ + ja LABEL(bigger) +@@ -260,7 +230,7 @@ LABEL(bigger): + sub %rcx, %r9 + lea LABEL(unaligned_table)(%rip), %r10 + movslq (%r10, %r9,4), %r9 +- pcmpeqb %xmm1, D(%xmm0) /* Any null chars? */ ++ pcmpeqb %xmm1, %xmm0 /* Any null chars? */ + lea (%r10, %r9), %r10 + _CET_NOTRACK jmp *%r10 /* jump to corresponding case */ + +@@ -273,15 +243,15 @@ LABEL(bigger): + LABEL(ashr_0): + + movdqa (%rsi), %xmm1 +- pcmpeqb %xmm1, D(%xmm0) /* Any null chars? */ ++ pcmpeqb %xmm1, %xmm0 /* Any null chars? */ + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L +- pcmpeqb (%rdi), D(%xmm1) /* compare 16 bytes for equality */ ++ pcmpeqb (%rdi), %xmm1 /* compare 16 bytes for equality */ + #else + movdqa (%rdi), %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm2, D(%xmm1) /* compare 16 bytes for equality */ ++ pcmpeqb %xmm2, %xmm1 /* compare 16 bytes for equality */ + #endif +- psubb %xmm0, D(%xmm1) /* packed sub of comparison results*/ ++ psubb %xmm0, %xmm1 /* packed sub of comparison results*/ + pmovmskb %xmm1, %r9d + shr %cl, %edx /* adjust 0xffff for offset */ + shr %cl, %r9d /* adjust for 16-byte offset */ +@@ -361,10 +331,10 @@ LABEL(ashr_0_exit_use): + */ + .p2align 4 + LABEL(ashr_1): +- pslldq $15, D(%xmm2) /* shift first string to align with second */ ++ pslldq $15, %xmm2 /* shift first string to align with second */ + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) /* compare 16 bytes for equality */ +- psubb %xmm0, D(%xmm2) /* packed sub of comparison results*/ ++ pcmpeqb %xmm1, %xmm2 /* compare 16 bytes for equality */ ++ psubb %xmm0, %xmm2 /* packed sub of comparison results*/ + pmovmskb %xmm2, %r9d + shr %cl, %edx /* adjust 0xffff for offset */ + shr %cl, %r9d /* adjust for 16-byte offset */ +@@ -392,7 +362,7 @@ LABEL(loop_ashr_1_use): + + LABEL(nibble_ashr_1_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $1, -16(%rdi, %rdx), D(%xmm0) ++ palignr $1, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -411,7 +381,7 @@ LABEL(nibble_ashr_1_restart_use): + jg LABEL(nibble_ashr_1_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $1, -16(%rdi, %rdx), D(%xmm0) ++ palignr $1, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -431,7 +401,7 @@ LABEL(nibble_ashr_1_restart_use): + LABEL(nibble_ashr_1_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $1, D(%xmm0) ++ psrldq $1, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -449,10 +419,10 @@ LABEL(nibble_ashr_1_use): + */ + .p2align 4 + LABEL(ashr_2): +- pslldq $14, D(%xmm2) ++ pslldq $14, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -480,7 +450,7 @@ LABEL(loop_ashr_2_use): + + LABEL(nibble_ashr_2_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $2, -16(%rdi, %rdx), D(%xmm0) ++ palignr $2, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -499,7 +469,7 @@ LABEL(nibble_ashr_2_restart_use): + jg LABEL(nibble_ashr_2_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $2, -16(%rdi, %rdx), D(%xmm0) ++ palignr $2, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -519,7 +489,7 @@ LABEL(nibble_ashr_2_restart_use): + LABEL(nibble_ashr_2_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $2, D(%xmm0) ++ psrldq $2, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -537,10 +507,10 @@ LABEL(nibble_ashr_2_use): + */ + .p2align 4 + LABEL(ashr_3): +- pslldq $13, D(%xmm2) ++ pslldq $13, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -568,7 +538,7 @@ LABEL(loop_ashr_3_use): + + LABEL(nibble_ashr_3_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $3, -16(%rdi, %rdx), D(%xmm0) ++ palignr $3, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -587,7 +557,7 @@ LABEL(nibble_ashr_3_restart_use): + jg LABEL(nibble_ashr_3_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $3, -16(%rdi, %rdx), D(%xmm0) ++ palignr $3, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -607,7 +577,7 @@ LABEL(nibble_ashr_3_restart_use): + LABEL(nibble_ashr_3_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $3, D(%xmm0) ++ psrldq $3, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -625,10 +595,10 @@ LABEL(nibble_ashr_3_use): + */ + .p2align 4 + LABEL(ashr_4): +- pslldq $12, D(%xmm2) ++ pslldq $12, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -657,7 +627,7 @@ LABEL(loop_ashr_4_use): + + LABEL(nibble_ashr_4_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $4, -16(%rdi, %rdx), D(%xmm0) ++ palignr $4, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -676,7 +646,7 @@ LABEL(nibble_ashr_4_restart_use): + jg LABEL(nibble_ashr_4_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $4, -16(%rdi, %rdx), D(%xmm0) ++ palignr $4, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -696,7 +666,7 @@ LABEL(nibble_ashr_4_restart_use): + LABEL(nibble_ashr_4_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $4, D(%xmm0) ++ psrldq $4, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -714,10 +684,10 @@ LABEL(nibble_ashr_4_use): + */ + .p2align 4 + LABEL(ashr_5): +- pslldq $11, D(%xmm2) ++ pslldq $11, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -746,7 +716,7 @@ LABEL(loop_ashr_5_use): + + LABEL(nibble_ashr_5_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $5, -16(%rdi, %rdx), D(%xmm0) ++ palignr $5, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -766,7 +736,7 @@ LABEL(nibble_ashr_5_restart_use): + + movdqa (%rdi, %rdx), %xmm0 + +- palignr $5, -16(%rdi, %rdx), D(%xmm0) ++ palignr $5, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -786,7 +756,7 @@ LABEL(nibble_ashr_5_restart_use): + LABEL(nibble_ashr_5_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $5, D(%xmm0) ++ psrldq $5, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -804,10 +774,10 @@ LABEL(nibble_ashr_5_use): + */ + .p2align 4 + LABEL(ashr_6): +- pslldq $10, D(%xmm2) ++ pslldq $10, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -836,7 +806,7 @@ LABEL(loop_ashr_6_use): + + LABEL(nibble_ashr_6_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $6, -16(%rdi, %rdx), D(%xmm0) ++ palignr $6, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -855,7 +825,7 @@ LABEL(nibble_ashr_6_restart_use): + jg LABEL(nibble_ashr_6_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $6, -16(%rdi, %rdx), D(%xmm0) ++ palignr $6, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -875,7 +845,7 @@ LABEL(nibble_ashr_6_restart_use): + LABEL(nibble_ashr_6_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $6, D(%xmm0) ++ psrldq $6, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -893,10 +863,10 @@ LABEL(nibble_ashr_6_use): + */ + .p2align 4 + LABEL(ashr_7): +- pslldq $9, D(%xmm2) ++ pslldq $9, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -925,7 +895,7 @@ LABEL(loop_ashr_7_use): + + LABEL(nibble_ashr_7_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $7, -16(%rdi, %rdx), D(%xmm0) ++ palignr $7, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -944,7 +914,7 @@ LABEL(nibble_ashr_7_restart_use): + jg LABEL(nibble_ashr_7_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $7, -16(%rdi, %rdx), D(%xmm0) ++ palignr $7, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a,(%rsi,%rdx), %xmm0 + #else +@@ -964,7 +934,7 @@ LABEL(nibble_ashr_7_restart_use): + LABEL(nibble_ashr_7_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $7, D(%xmm0) ++ psrldq $7, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -982,10 +952,10 @@ LABEL(nibble_ashr_7_use): + */ + .p2align 4 + LABEL(ashr_8): +- pslldq $8, D(%xmm2) ++ pslldq $8, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -1014,7 +984,7 @@ LABEL(loop_ashr_8_use): + + LABEL(nibble_ashr_8_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $8, -16(%rdi, %rdx), D(%xmm0) ++ palignr $8, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1033,7 +1003,7 @@ LABEL(nibble_ashr_8_restart_use): + jg LABEL(nibble_ashr_8_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $8, -16(%rdi, %rdx), D(%xmm0) ++ palignr $8, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1053,7 +1023,7 @@ LABEL(nibble_ashr_8_restart_use): + LABEL(nibble_ashr_8_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $8, D(%xmm0) ++ psrldq $8, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -1071,10 +1041,10 @@ LABEL(nibble_ashr_8_use): + */ + .p2align 4 + LABEL(ashr_9): +- pslldq $7, D(%xmm2) ++ pslldq $7, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -1104,7 +1074,7 @@ LABEL(loop_ashr_9_use): + LABEL(nibble_ashr_9_restart_use): + movdqa (%rdi, %rdx), %xmm0 + +- palignr $9, -16(%rdi, %rdx), D(%xmm0) ++ palignr $9, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1123,7 +1093,7 @@ LABEL(nibble_ashr_9_restart_use): + jg LABEL(nibble_ashr_9_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $9, -16(%rdi, %rdx), D(%xmm0) ++ palignr $9, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1143,7 +1113,7 @@ LABEL(nibble_ashr_9_restart_use): + LABEL(nibble_ashr_9_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $9, D(%xmm0) ++ psrldq $9, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -1161,10 +1131,10 @@ LABEL(nibble_ashr_9_use): + */ + .p2align 4 + LABEL(ashr_10): +- pslldq $6, D(%xmm2) ++ pslldq $6, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -1193,7 +1163,7 @@ LABEL(loop_ashr_10_use): + + LABEL(nibble_ashr_10_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $10, -16(%rdi, %rdx), D(%xmm0) ++ palignr $10, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1212,7 +1182,7 @@ LABEL(nibble_ashr_10_restart_use): + jg LABEL(nibble_ashr_10_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $10, -16(%rdi, %rdx), D(%xmm0) ++ palignr $10, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1232,7 +1202,7 @@ LABEL(nibble_ashr_10_restart_use): + LABEL(nibble_ashr_10_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $10, D(%xmm0) ++ psrldq $10, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -1250,10 +1220,10 @@ LABEL(nibble_ashr_10_use): + */ + .p2align 4 + LABEL(ashr_11): +- pslldq $5, D(%xmm2) ++ pslldq $5, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -1282,7 +1252,7 @@ LABEL(loop_ashr_11_use): + + LABEL(nibble_ashr_11_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $11, -16(%rdi, %rdx), D(%xmm0) ++ palignr $11, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1301,7 +1271,7 @@ LABEL(nibble_ashr_11_restart_use): + jg LABEL(nibble_ashr_11_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $11, -16(%rdi, %rdx), D(%xmm0) ++ palignr $11, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1321,7 +1291,7 @@ LABEL(nibble_ashr_11_restart_use): + LABEL(nibble_ashr_11_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $11, D(%xmm0) ++ psrldq $11, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -1339,10 +1309,10 @@ LABEL(nibble_ashr_11_use): + */ + .p2align 4 + LABEL(ashr_12): +- pslldq $4, D(%xmm2) ++ pslldq $4, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -1371,7 +1341,7 @@ LABEL(loop_ashr_12_use): + + LABEL(nibble_ashr_12_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $12, -16(%rdi, %rdx), D(%xmm0) ++ palignr $12, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1390,7 +1360,7 @@ LABEL(nibble_ashr_12_restart_use): + jg LABEL(nibble_ashr_12_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $12, -16(%rdi, %rdx), D(%xmm0) ++ palignr $12, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1410,7 +1380,7 @@ LABEL(nibble_ashr_12_restart_use): + LABEL(nibble_ashr_12_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $12, D(%xmm0) ++ psrldq $12, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -1428,10 +1398,10 @@ LABEL(nibble_ashr_12_use): + */ + .p2align 4 + LABEL(ashr_13): +- pslldq $3, D(%xmm2) ++ pslldq $3, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -1461,7 +1431,7 @@ LABEL(loop_ashr_13_use): + + LABEL(nibble_ashr_13_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $13, -16(%rdi, %rdx), D(%xmm0) ++ palignr $13, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1480,7 +1450,7 @@ LABEL(nibble_ashr_13_restart_use): + jg LABEL(nibble_ashr_13_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $13, -16(%rdi, %rdx), D(%xmm0) ++ palignr $13, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1500,7 +1470,7 @@ LABEL(nibble_ashr_13_restart_use): + LABEL(nibble_ashr_13_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $13, D(%xmm0) ++ psrldq $13, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -1518,10 +1488,10 @@ LABEL(nibble_ashr_13_use): + */ + .p2align 4 + LABEL(ashr_14): +- pslldq $2, D(%xmm2) ++ pslldq $2, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -1551,7 +1521,7 @@ LABEL(loop_ashr_14_use): + + LABEL(nibble_ashr_14_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $14, -16(%rdi, %rdx), D(%xmm0) ++ palignr $14, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1570,7 +1540,7 @@ LABEL(nibble_ashr_14_restart_use): + jg LABEL(nibble_ashr_14_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $14, -16(%rdi, %rdx), D(%xmm0) ++ palignr $14, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1590,7 +1560,7 @@ LABEL(nibble_ashr_14_restart_use): + LABEL(nibble_ashr_14_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $14, D(%xmm0) ++ psrldq $14, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +@@ -1608,10 +1578,10 @@ LABEL(nibble_ashr_14_use): + */ + .p2align 4 + LABEL(ashr_15): +- pslldq $1, D(%xmm2) ++ pslldq $1, %xmm2 + TOLOWER (%xmm1, %xmm2) +- pcmpeqb %xmm1, D(%xmm2) +- psubb %xmm0, D(%xmm2) ++ pcmpeqb %xmm1, %xmm2 ++ psubb %xmm0, %xmm2 + pmovmskb %xmm2, %r9d + shr %cl, %edx + shr %cl, %r9d +@@ -1643,7 +1613,7 @@ LABEL(loop_ashr_15_use): + + LABEL(nibble_ashr_15_restart_use): + movdqa (%rdi, %rdx), %xmm0 +- palignr $15, -16(%rdi, %rdx), D(%xmm0) ++ palignr $15, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1662,7 +1632,7 @@ LABEL(nibble_ashr_15_restart_use): + jg LABEL(nibble_ashr_15_use) + + movdqa (%rdi, %rdx), %xmm0 +- palignr $15, -16(%rdi, %rdx), D(%xmm0) ++ palignr $15, -16(%rdi, %rdx), %xmm0 + #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L + pcmpistri $0x1a, (%rsi,%rdx), %xmm0 + #else +@@ -1682,7 +1652,7 @@ LABEL(nibble_ashr_15_restart_use): + LABEL(nibble_ashr_15_use): + sub $0x1000, %r10 + movdqa -16(%rdi, %rdx), %xmm0 +- psrldq $15, D(%xmm0) ++ psrldq $15, %xmm0 + pcmpistri $0x3a,%xmm0, %xmm0 + #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L + cmp %r11, %rcx +diff --git a/sysdeps/x86_64/multiarch/strncase_l-avx.S b/sysdeps/x86_64/multiarch/strncase_l-avx.S +deleted file mode 100644 +index f1d3fefdd94674b8..0000000000000000 +--- a/sysdeps/x86_64/multiarch/strncase_l-avx.S ++++ /dev/null +@@ -1,22 +0,0 @@ +-/* strncasecmp_l optimized with AVX. +- Copyright (C) 2017-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#define STRCMP_SSE42 __strncasecmp_l_avx +-#define USE_AVX 1 +-#define USE_AS_STRNCASECMP_L +-#include "strcmp-sse42.S" diff --git a/SOURCES/glibc-upstream-2.34-23.patch b/SOURCES/glibc-upstream-2.34-23.patch new file mode 100644 index 0000000..67d7d88 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-23.patch @@ -0,0 +1,32 @@ +commit 8b8a1d0b7375c547ae905917a03743ed6759c5bc +Author: Florian Weimer +Date: Tue Sep 21 07:12:56 2021 +0200 + + nptl: Fix type of pthread_mutexattr_getrobust_np, pthread_mutexattr_setrobust_np (bug 28036) + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit f3e664563361dc17530113b3205998d1f19dc4d9) + +diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h +index f1b7f2bdc6062c3e..43146e91c9d9579b 100644 +--- a/sysdeps/nptl/pthread.h ++++ b/sysdeps/nptl/pthread.h +@@ -933,7 +933,7 @@ extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr, + # ifdef __USE_GNU + # ifdef __REDIRECT_NTH + extern int __REDIRECT_NTH (pthread_mutexattr_getrobust_np, +- (pthread_mutex_t *, int *), ++ (pthread_mutexattr_t *, int *), + pthread_mutexattr_getrobust) __nonnull ((1)) + __attribute_deprecated_msg__ ("\ + pthread_mutexattr_getrobust_np is deprecated, use pthread_mutexattr_getrobust"); +@@ -949,7 +949,7 @@ extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr, + # ifdef __USE_GNU + # ifdef __REDIRECT_NTH + extern int __REDIRECT_NTH (pthread_mutexattr_setrobust_np, +- (pthread_mutex_t *, int), ++ (pthread_mutexattr_t *, int), + pthread_mutexattr_setrobust) __nonnull ((1)) + __attribute_deprecated_msg__ ("\ + pthread_mutexattr_setrobust_np is deprecated, use pthread_mutexattr_setrobust"); diff --git a/SOURCES/glibc-upstream-2.34-230.patch b/SOURCES/glibc-upstream-2.34-230.patch new file mode 100644 index 0000000..b7eb594 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-230.patch @@ -0,0 +1,253 @@ +commit 4ff6ae069b7caacd5f99088abd755717b994f660 +Author: Noah Goldstein +Date: Fri Mar 25 17:13:33 2022 -0500 + + x86: Small improvements for wcslen + + Just a few QOL changes. + 1. Prefer `add` > `lea` as it has high execution units it can run + on. + 2. Don't break macro-fusion between `test` and `jcc` + 3. Reduce code size by removing gratuitous padding bytes (-90 + bytes). + + geometric_mean(N=20) of all benchmarks New / Original: 0.959 + + All string/memory tests pass. + Reviewed-by: H.J. Lu + + (cherry picked from commit 244b415d386487521882debb845a040a4758cb18) + +diff --git a/sysdeps/x86_64/wcslen.S b/sysdeps/x86_64/wcslen.S +index 61edea1d14d454c6..ad066863a44ea0a5 100644 +--- a/sysdeps/x86_64/wcslen.S ++++ b/sysdeps/x86_64/wcslen.S +@@ -41,82 +41,82 @@ ENTRY (__wcslen) + pxor %xmm0, %xmm0 + + lea 32(%rdi), %rax +- lea 16(%rdi), %rcx ++ addq $16, %rdi + and $-16, %rax + + pcmpeqd (%rax), %xmm0 + pmovmskb %xmm0, %edx + pxor %xmm1, %xmm1 ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm1 + pmovmskb %xmm1, %edx + pxor %xmm2, %xmm2 ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm2 + pmovmskb %xmm2, %edx + pxor %xmm3, %xmm3 ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm3 + pmovmskb %xmm3, %edx ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm0 + pmovmskb %xmm0, %edx ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm1 + pmovmskb %xmm1, %edx ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm2 + pmovmskb %xmm2, %edx ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm3 + pmovmskb %xmm3, %edx ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm0 + pmovmskb %xmm0, %edx ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm1 + pmovmskb %xmm1, %edx ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm2 + pmovmskb %xmm2, %edx ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + pcmpeqd (%rax), %xmm3 + pmovmskb %xmm3, %edx ++ addq $16, %rax + test %edx, %edx +- lea 16(%rax), %rax + jnz L(exit) + + and $-0x40, %rax +@@ -133,104 +133,100 @@ L(aligned_64_loop): + pminub %xmm0, %xmm2 + pcmpeqd %xmm3, %xmm2 + pmovmskb %xmm2, %edx ++ addq $64, %rax + test %edx, %edx +- lea 64(%rax), %rax + jz L(aligned_64_loop) + + pcmpeqd -64(%rax), %xmm3 + pmovmskb %xmm3, %edx ++ addq $48, %rdi + test %edx, %edx +- lea 48(%rcx), %rcx + jnz L(exit) + + pcmpeqd %xmm1, %xmm3 + pmovmskb %xmm3, %edx ++ addq $-16, %rdi + test %edx, %edx +- lea -16(%rcx), %rcx + jnz L(exit) + + pcmpeqd -32(%rax), %xmm3 + pmovmskb %xmm3, %edx ++ addq $-16, %rdi + test %edx, %edx +- lea -16(%rcx), %rcx + jnz L(exit) + + pcmpeqd %xmm6, %xmm3 + pmovmskb %xmm3, %edx ++ addq $-16, %rdi + test %edx, %edx +- lea -16(%rcx), %rcx +- jnz L(exit) +- +- jmp L(aligned_64_loop) ++ jz L(aligned_64_loop) + + .p2align 4 + L(exit): +- sub %rcx, %rax ++ sub %rdi, %rax + shr $2, %rax + test %dl, %dl + jz L(exit_high) + +- mov %dl, %cl +- and $15, %cl ++ andl $15, %edx + jz L(exit_1) + ret + +- .p2align 4 ++ /* No align here. Naturally aligned % 16 == 1. */ + L(exit_high): +- mov %dh, %ch +- and $15, %ch ++ andl $(15 << 8), %edx + jz L(exit_3) + add $2, %rax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_1): + add $1, %rax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_3): + add $3, %rax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_tail0): +- xor %rax, %rax ++ xorl %eax, %eax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_tail1): +- mov $1, %rax ++ movl $1, %eax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_tail2): +- mov $2, %rax ++ movl $2, %eax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_tail3): +- mov $3, %rax ++ movl $3, %eax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_tail4): +- mov $4, %rax ++ movl $4, %eax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_tail5): +- mov $5, %rax ++ movl $5, %eax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_tail6): +- mov $6, %rax ++ movl $6, %eax + ret + +- .p2align 4 ++ .p2align 3 + L(exit_tail7): +- mov $7, %rax ++ movl $7, %eax + ret + + END (__wcslen) diff --git a/SOURCES/glibc-upstream-2.34-231.patch b/SOURCES/glibc-upstream-2.34-231.patch new file mode 100644 index 0000000..3c928b8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-231.patch @@ -0,0 +1,956 @@ +commit ffe75982cc0bb2d25d55ed566a3731b9c3017e6f +Author: Noah Goldstein +Date: Fri Apr 15 12:28:00 2022 -0500 + + x86: Remove memcmp-sse4.S + + Code didn't actually use any sse4 instructions since `ptest` was + removed in: + + commit 2f9062d7171850451e6044ef78d91ff8c017b9c0 + Author: Noah Goldstein + Date: Wed Nov 10 16:18:56 2021 -0600 + + x86: Shrink memcmp-sse4.S code size + + The new memcmp-sse2 implementation is also faster. + + geometric_mean(N=20) of page cross cases SSE2 / SSE4: 0.905 + + Note there are two regressions preferring SSE2 for Size = 1 and Size = + 65. + + Size = 1: + size, align0, align1, ret, New Time/Old Time + 1, 1, 1, 0, 1.2 + 1, 1, 1, 1, 1.197 + 1, 1, 1, -1, 1.2 + + This is intentional. Size == 1 is significantly less hot based on + profiles of GCC11 and Python3 than sizes [4, 8] (which is made + hotter). + + Python3 Size = 1 -> 13.64% + Python3 Size = [4, 8] -> 60.92% + + GCC11 Size = 1 -> 1.29% + GCC11 Size = [4, 8] -> 33.86% + + size, align0, align1, ret, New Time/Old Time + 4, 4, 4, 0, 0.622 + 4, 4, 4, 1, 0.797 + 4, 4, 4, -1, 0.805 + 5, 5, 5, 0, 0.623 + 5, 5, 5, 1, 0.777 + 5, 5, 5, -1, 0.802 + 6, 6, 6, 0, 0.625 + 6, 6, 6, 1, 0.813 + 6, 6, 6, -1, 0.788 + 7, 7, 7, 0, 0.625 + 7, 7, 7, 1, 0.799 + 7, 7, 7, -1, 0.795 + 8, 8, 8, 0, 0.625 + 8, 8, 8, 1, 0.848 + 8, 8, 8, -1, 0.914 + 9, 9, 9, 0, 0.625 + + Size = 65: + size, align0, align1, ret, New Time/Old Time + 65, 0, 0, 0, 1.103 + 65, 0, 0, 1, 1.216 + 65, 0, 0, -1, 1.227 + 65, 65, 0, 0, 1.091 + 65, 0, 65, 1, 1.19 + 65, 65, 65, -1, 1.215 + + This is because A) the checks in range [65, 96] are now unrolled 2x + and B) because smaller values <= 16 are now given a hotter path. By + contrast the SSE4 version has a branch for Size = 80. The unrolled + version has get better performance for returns which need both + comparisons. + + size, align0, align1, ret, New Time/Old Time + 128, 4, 8, 0, 0.858 + 128, 4, 8, 1, 0.879 + 128, 4, 8, -1, 0.888 + + As well, out of microbenchmark environments that are not full + predictable the branch will have a real-cost. + Reviewed-by: H.J. Lu + + (cherry picked from commit 7cbc03d03091d5664060924789afe46d30a5477e) + +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index bca82e38d86cc440..b503e4b81e92a11c 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -11,7 +11,6 @@ sysdep_routines += \ + memcmp-avx2-movbe-rtm \ + memcmp-evex-movbe \ + memcmp-sse2 \ +- memcmp-sse4 \ + memcmp-ssse3 \ + memcpy-ssse3 \ + memcpy-ssse3-back \ +@@ -174,7 +173,6 @@ sysdep_routines += \ + wmemcmp-avx2-movbe-rtm \ + wmemcmp-c \ + wmemcmp-evex-movbe \ +- wmemcmp-sse4 \ + wmemcmp-ssse3 \ + # sysdep_routines + endif +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index 4c7834dd0b951fa4..e5e48b36c3175e68 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -78,8 +78,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (MOVBE)), + __memcmp_evex_movbe) +- IFUNC_IMPL_ADD (array, i, memcmp, CPU_FEATURE_USABLE (SSE4_1), +- __memcmp_sse4_1) + IFUNC_IMPL_ADD (array, i, memcmp, CPU_FEATURE_USABLE (SSSE3), + __memcmp_ssse3) + IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_sse2)) +@@ -824,8 +822,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (MOVBE)), + __wmemcmp_evex_movbe) +- IFUNC_IMPL_ADD (array, i, wmemcmp, CPU_FEATURE_USABLE (SSE4_1), +- __wmemcmp_sse4_1) + IFUNC_IMPL_ADD (array, i, wmemcmp, CPU_FEATURE_USABLE (SSSE3), + __wmemcmp_ssse3) + IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_sse2)) +diff --git a/sysdeps/x86_64/multiarch/ifunc-memcmp.h b/sysdeps/x86_64/multiarch/ifunc-memcmp.h +index 89e2129968e1e49c..5b92594093c1e0bb 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-memcmp.h ++++ b/sysdeps/x86_64/multiarch/ifunc-memcmp.h +@@ -21,7 +21,6 @@ + + extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse4_1) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_movbe) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_movbe_rtm) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (evex_movbe) attribute_hidden; +@@ -47,9 +46,6 @@ IFUNC_SELECTOR (void) + return OPTIMIZE (avx2_movbe); + } + +- if (CPU_FEATURE_USABLE_P (cpu_features, SSE4_1)) +- return OPTIMIZE (sse4_1); +- + if (CPU_FEATURE_USABLE_P (cpu_features, SSSE3)) + return OPTIMIZE (ssse3); + +diff --git a/sysdeps/x86_64/multiarch/memcmp-sse4.S b/sysdeps/x86_64/multiarch/memcmp-sse4.S +deleted file mode 100644 +index 97c102a9c5ab2b91..0000000000000000 +--- a/sysdeps/x86_64/multiarch/memcmp-sse4.S ++++ /dev/null +@@ -1,804 +0,0 @@ +-/* memcmp with SSE4.1, wmemcmp with SSE4.1 +- Copyright (C) 2010-2021 Free Software Foundation, Inc. +- Contributed by Intel Corporation. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for 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) +- +-# include +- +-# ifndef MEMCMP +-# define MEMCMP __memcmp_sse4_1 +-# endif +- +-#ifdef USE_AS_WMEMCMP +-# define CMPEQ pcmpeqd +-# define CHAR_SIZE 4 +-#else +-# define CMPEQ pcmpeqb +-# define CHAR_SIZE 1 +-#endif +- +- +-/* Warning! +- wmemcmp has to use SIGNED comparison for elements. +- memcmp has to use UNSIGNED comparison for elemnts. +-*/ +- +- .section .text.sse4.1,"ax",@progbits +-ENTRY (MEMCMP) +-# ifdef USE_AS_WMEMCMP +- shl $2, %RDX_LP +-# elif defined __ILP32__ +- /* Clear the upper 32 bits. */ +- mov %edx, %edx +-# endif +- cmp $79, %RDX_LP +- ja L(79bytesormore) +- +- cmp $CHAR_SIZE, %RDX_LP +- jbe L(firstbyte) +- +- /* N in (CHAR_SIZE, 79) bytes. */ +- cmpl $32, %edx +- ja L(more_32_bytes) +- +- cmpl $16, %edx +- jae L(16_to_32_bytes) +- +-# ifndef USE_AS_WMEMCMP +- cmpl $8, %edx +- jae L(8_to_16_bytes) +- +- cmpl $4, %edx +- jb L(2_to_3_bytes) +- +- movl (%rdi), %eax +- movl (%rsi), %ecx +- +- bswap %eax +- bswap %ecx +- +- shlq $32, %rax +- shlq $32, %rcx +- +- movl -4(%rdi, %rdx), %edi +- movl -4(%rsi, %rdx), %esi +- +- bswap %edi +- bswap %esi +- +- orq %rdi, %rax +- orq %rsi, %rcx +- subq %rcx, %rax +- cmovne %edx, %eax +- sbbl %ecx, %ecx +- orl %ecx, %eax +- ret +- +- .p2align 4,, 8 +-L(2_to_3_bytes): +- movzwl (%rdi), %eax +- movzwl (%rsi), %ecx +- shll $8, %eax +- shll $8, %ecx +- bswap %eax +- bswap %ecx +- movzbl -1(%rdi, %rdx), %edi +- movzbl -1(%rsi, %rdx), %esi +- orl %edi, %eax +- orl %esi, %ecx +- subl %ecx, %eax +- ret +- +- .p2align 4,, 8 +-L(8_to_16_bytes): +- movq (%rdi), %rax +- movq (%rsi), %rcx +- +- bswap %rax +- bswap %rcx +- +- subq %rcx, %rax +- jne L(8_to_16_bytes_done) +- +- movq -8(%rdi, %rdx), %rax +- movq -8(%rsi, %rdx), %rcx +- +- bswap %rax +- bswap %rcx +- +- subq %rcx, %rax +- +-L(8_to_16_bytes_done): +- cmovne %edx, %eax +- sbbl %ecx, %ecx +- orl %ecx, %eax +- ret +-# else +- xorl %eax, %eax +- movl (%rdi), %ecx +- cmpl (%rsi), %ecx +- jne L(8_to_16_bytes_done) +- movl 4(%rdi), %ecx +- cmpl 4(%rsi), %ecx +- jne L(8_to_16_bytes_done) +- movl -4(%rdi, %rdx), %ecx +- cmpl -4(%rsi, %rdx), %ecx +- jne L(8_to_16_bytes_done) +- ret +-# endif +- +- .p2align 4,, 3 +-L(ret_zero): +- xorl %eax, %eax +-L(zero): +- ret +- +- .p2align 4,, 8 +-L(firstbyte): +- jb L(ret_zero) +-# ifdef USE_AS_WMEMCMP +- xorl %eax, %eax +- movl (%rdi), %ecx +- cmpl (%rsi), %ecx +- je L(zero) +-L(8_to_16_bytes_done): +- setg %al +- leal -1(%rax, %rax), %eax +-# else +- movzbl (%rdi), %eax +- movzbl (%rsi), %ecx +- sub %ecx, %eax +-# endif +- ret +- +- .p2align 4 +-L(vec_return_begin_48): +- addq $16, %rdi +- addq $16, %rsi +-L(vec_return_begin_32): +- bsfl %eax, %eax +-# ifdef USE_AS_WMEMCMP +- movl 32(%rdi, %rax), %ecx +- xorl %edx, %edx +- cmpl 32(%rsi, %rax), %ecx +- setg %dl +- leal -1(%rdx, %rdx), %eax +-# else +- movzbl 32(%rsi, %rax), %ecx +- movzbl 32(%rdi, %rax), %eax +- subl %ecx, %eax +-# endif +- ret +- +- .p2align 4 +-L(vec_return_begin_16): +- addq $16, %rdi +- addq $16, %rsi +-L(vec_return_begin): +- bsfl %eax, %eax +-# ifdef USE_AS_WMEMCMP +- movl (%rdi, %rax), %ecx +- xorl %edx, %edx +- cmpl (%rsi, %rax), %ecx +- setg %dl +- leal -1(%rdx, %rdx), %eax +-# else +- movzbl (%rsi, %rax), %ecx +- movzbl (%rdi, %rax), %eax +- subl %ecx, %eax +-# endif +- ret +- +- .p2align 4 +-L(vec_return_end_16): +- subl $16, %edx +-L(vec_return_end): +- bsfl %eax, %eax +- addl %edx, %eax +-# ifdef USE_AS_WMEMCMP +- movl -16(%rdi, %rax), %ecx +- xorl %edx, %edx +- cmpl -16(%rsi, %rax), %ecx +- setg %dl +- leal -1(%rdx, %rdx), %eax +-# else +- movzbl -16(%rsi, %rax), %ecx +- movzbl -16(%rdi, %rax), %eax +- subl %ecx, %eax +-# endif +- ret +- +- .p2align 4,, 8 +-L(more_32_bytes): +- movdqu (%rdi), %xmm0 +- movdqu (%rsi), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqu 16(%rdi), %xmm0 +- movdqu 16(%rsi), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_16) +- +- cmpl $64, %edx +- jbe L(32_to_64_bytes) +- movdqu 32(%rdi), %xmm0 +- movdqu 32(%rsi), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_32) +- +- .p2align 4,, 6 +-L(32_to_64_bytes): +- movdqu -32(%rdi, %rdx), %xmm0 +- movdqu -32(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end_16) +- +- movdqu -16(%rdi, %rdx), %xmm0 +- movdqu -16(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end) +- ret +- +- .p2align 4 +-L(16_to_32_bytes): +- movdqu (%rdi), %xmm0 +- movdqu (%rsi), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqu -16(%rdi, %rdx), %xmm0 +- movdqu -16(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end) +- ret +- +- +- .p2align 4 +-L(79bytesormore): +- movdqu (%rdi), %xmm0 +- movdqu (%rsi), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- +- mov %rsi, %rcx +- and $-16, %rsi +- add $16, %rsi +- sub %rsi, %rcx +- +- sub %rcx, %rdi +- add %rcx, %rdx +- test $0xf, %rdi +- jz L(2aligned) +- +- cmp $128, %rdx +- ja L(128bytesormore) +- +- .p2align 4,, 6 +-L(less128bytes): +- movdqu (%rdi), %xmm1 +- CMPEQ (%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqu 16(%rdi), %xmm1 +- CMPEQ 16(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_16) +- +- movdqu 32(%rdi), %xmm1 +- CMPEQ 32(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_32) +- +- movdqu 48(%rdi), %xmm1 +- CMPEQ 48(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_48) +- +- cmp $96, %rdx +- jb L(32_to_64_bytes) +- +- addq $64, %rdi +- addq $64, %rsi +- subq $64, %rdx +- +- .p2align 4,, 6 +-L(last_64_bytes): +- movdqu (%rdi), %xmm1 +- CMPEQ (%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqu 16(%rdi), %xmm1 +- CMPEQ 16(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_16) +- +- movdqu -32(%rdi, %rdx), %xmm0 +- movdqu -32(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end_16) +- +- movdqu -16(%rdi, %rdx), %xmm0 +- movdqu -16(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end) +- ret +- +- .p2align 4 +-L(128bytesormore): +- cmp $256, %rdx +- ja L(unaligned_loop) +-L(less256bytes): +- movdqu (%rdi), %xmm1 +- CMPEQ (%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqu 16(%rdi), %xmm1 +- CMPEQ 16(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_16) +- +- movdqu 32(%rdi), %xmm1 +- CMPEQ 32(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_32) +- +- movdqu 48(%rdi), %xmm1 +- CMPEQ 48(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_48) +- +- addq $64, %rdi +- addq $64, %rsi +- +- movdqu (%rdi), %xmm1 +- CMPEQ (%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqu 16(%rdi), %xmm1 +- CMPEQ 16(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_16) +- +- movdqu 32(%rdi), %xmm1 +- CMPEQ 32(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_32) +- +- movdqu 48(%rdi), %xmm1 +- CMPEQ 48(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_48) +- +- addq $-128, %rdx +- subq $-64, %rsi +- subq $-64, %rdi +- +- cmp $64, %rdx +- ja L(less128bytes) +- +- cmp $32, %rdx +- ja L(last_64_bytes) +- +- movdqu -32(%rdi, %rdx), %xmm0 +- movdqu -32(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end_16) +- +- movdqu -16(%rdi, %rdx), %xmm0 +- movdqu -16(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end) +- ret +- +- .p2align 4 +-L(unaligned_loop): +-# ifdef DATA_CACHE_SIZE_HALF +- mov $DATA_CACHE_SIZE_HALF, %R8_LP +-# else +- mov __x86_data_cache_size_half(%rip), %R8_LP +-# endif +- movq %r8, %r9 +- addq %r8, %r8 +- addq %r9, %r8 +- cmpq %r8, %rdx +- ja L(L2_L3_cache_unaligned) +- sub $64, %rdx +- .p2align 4 +-L(64bytesormore_loop): +- movdqu (%rdi), %xmm0 +- movdqu 16(%rdi), %xmm1 +- movdqu 32(%rdi), %xmm2 +- movdqu 48(%rdi), %xmm3 +- +- CMPEQ (%rsi), %xmm0 +- CMPEQ 16(%rsi), %xmm1 +- CMPEQ 32(%rsi), %xmm2 +- CMPEQ 48(%rsi), %xmm3 +- +- pand %xmm0, %xmm1 +- pand %xmm2, %xmm3 +- pand %xmm1, %xmm3 +- +- pmovmskb %xmm3, %eax +- incw %ax +- jnz L(64bytesormore_loop_end) +- +- add $64, %rsi +- add $64, %rdi +- sub $64, %rdx +- ja L(64bytesormore_loop) +- +- .p2align 4,, 6 +-L(loop_tail): +- addq %rdx, %rdi +- movdqu (%rdi), %xmm0 +- movdqu 16(%rdi), %xmm1 +- movdqu 32(%rdi), %xmm2 +- movdqu 48(%rdi), %xmm3 +- +- addq %rdx, %rsi +- movdqu (%rsi), %xmm4 +- movdqu 16(%rsi), %xmm5 +- movdqu 32(%rsi), %xmm6 +- movdqu 48(%rsi), %xmm7 +- +- CMPEQ %xmm4, %xmm0 +- CMPEQ %xmm5, %xmm1 +- CMPEQ %xmm6, %xmm2 +- CMPEQ %xmm7, %xmm3 +- +- pand %xmm0, %xmm1 +- pand %xmm2, %xmm3 +- pand %xmm1, %xmm3 +- +- pmovmskb %xmm3, %eax +- incw %ax +- jnz L(64bytesormore_loop_end) +- ret +- +-L(L2_L3_cache_unaligned): +- subq $64, %rdx +- .p2align 4 +-L(L2_L3_unaligned_128bytes_loop): +- prefetchnta 0x1c0(%rdi) +- prefetchnta 0x1c0(%rsi) +- +- movdqu (%rdi), %xmm0 +- movdqu 16(%rdi), %xmm1 +- movdqu 32(%rdi), %xmm2 +- movdqu 48(%rdi), %xmm3 +- +- CMPEQ (%rsi), %xmm0 +- CMPEQ 16(%rsi), %xmm1 +- CMPEQ 32(%rsi), %xmm2 +- CMPEQ 48(%rsi), %xmm3 +- +- pand %xmm0, %xmm1 +- pand %xmm2, %xmm3 +- pand %xmm1, %xmm3 +- +- pmovmskb %xmm3, %eax +- incw %ax +- jnz L(64bytesormore_loop_end) +- +- add $64, %rsi +- add $64, %rdi +- sub $64, %rdx +- ja L(L2_L3_unaligned_128bytes_loop) +- jmp L(loop_tail) +- +- +- /* This case is for machines which are sensitive for unaligned +- * instructions. */ +- .p2align 4 +-L(2aligned): +- cmp $128, %rdx +- ja L(128bytesormorein2aligned) +-L(less128bytesin2aligned): +- movdqa (%rdi), %xmm1 +- CMPEQ (%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqa 16(%rdi), %xmm1 +- CMPEQ 16(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_16) +- +- movdqa 32(%rdi), %xmm1 +- CMPEQ 32(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_32) +- +- movdqa 48(%rdi), %xmm1 +- CMPEQ 48(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_48) +- +- cmp $96, %rdx +- jb L(32_to_64_bytes) +- +- addq $64, %rdi +- addq $64, %rsi +- subq $64, %rdx +- +- .p2align 4,, 6 +-L(aligned_last_64_bytes): +- movdqa (%rdi), %xmm1 +- CMPEQ (%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqa 16(%rdi), %xmm1 +- CMPEQ 16(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_16) +- +- movdqu -32(%rdi, %rdx), %xmm0 +- movdqu -32(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end_16) +- +- movdqu -16(%rdi, %rdx), %xmm0 +- movdqu -16(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end) +- ret +- +- .p2align 4 +-L(128bytesormorein2aligned): +- cmp $256, %rdx +- ja L(aligned_loop) +-L(less256bytesin2alinged): +- movdqa (%rdi), %xmm1 +- CMPEQ (%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqa 16(%rdi), %xmm1 +- CMPEQ 16(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_16) +- +- movdqa 32(%rdi), %xmm1 +- CMPEQ 32(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_32) +- +- movdqa 48(%rdi), %xmm1 +- CMPEQ 48(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_48) +- +- addq $64, %rdi +- addq $64, %rsi +- +- movdqa (%rdi), %xmm1 +- CMPEQ (%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin) +- +- movdqa 16(%rdi), %xmm1 +- CMPEQ 16(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_16) +- +- movdqa 32(%rdi), %xmm1 +- CMPEQ 32(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_32) +- +- movdqa 48(%rdi), %xmm1 +- CMPEQ 48(%rsi), %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_begin_48) +- +- addq $-128, %rdx +- subq $-64, %rsi +- subq $-64, %rdi +- +- cmp $64, %rdx +- ja L(less128bytesin2aligned) +- +- cmp $32, %rdx +- ja L(aligned_last_64_bytes) +- +- movdqu -32(%rdi, %rdx), %xmm0 +- movdqu -32(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end_16) +- +- movdqu -16(%rdi, %rdx), %xmm0 +- movdqu -16(%rsi, %rdx), %xmm1 +- CMPEQ %xmm0, %xmm1 +- pmovmskb %xmm1, %eax +- incw %ax +- jnz L(vec_return_end) +- ret +- +- .p2align 4 +-L(aligned_loop): +-# ifdef DATA_CACHE_SIZE_HALF +- mov $DATA_CACHE_SIZE_HALF, %R8_LP +-# else +- mov __x86_data_cache_size_half(%rip), %R8_LP +-# endif +- movq %r8, %r9 +- addq %r8, %r8 +- addq %r9, %r8 +- cmpq %r8, %rdx +- ja L(L2_L3_cache_aligned) +- +- sub $64, %rdx +- .p2align 4 +-L(64bytesormore_loopin2aligned): +- movdqa (%rdi), %xmm0 +- movdqa 16(%rdi), %xmm1 +- movdqa 32(%rdi), %xmm2 +- movdqa 48(%rdi), %xmm3 +- +- CMPEQ (%rsi), %xmm0 +- CMPEQ 16(%rsi), %xmm1 +- CMPEQ 32(%rsi), %xmm2 +- CMPEQ 48(%rsi), %xmm3 +- +- pand %xmm0, %xmm1 +- pand %xmm2, %xmm3 +- pand %xmm1, %xmm3 +- +- pmovmskb %xmm3, %eax +- incw %ax +- jnz L(64bytesormore_loop_end) +- add $64, %rsi +- add $64, %rdi +- sub $64, %rdx +- ja L(64bytesormore_loopin2aligned) +- jmp L(loop_tail) +- +-L(L2_L3_cache_aligned): +- subq $64, %rdx +- .p2align 4 +-L(L2_L3_aligned_128bytes_loop): +- prefetchnta 0x1c0(%rdi) +- prefetchnta 0x1c0(%rsi) +- movdqa (%rdi), %xmm0 +- movdqa 16(%rdi), %xmm1 +- movdqa 32(%rdi), %xmm2 +- movdqa 48(%rdi), %xmm3 +- +- CMPEQ (%rsi), %xmm0 +- CMPEQ 16(%rsi), %xmm1 +- CMPEQ 32(%rsi), %xmm2 +- CMPEQ 48(%rsi), %xmm3 +- +- pand %xmm0, %xmm1 +- pand %xmm2, %xmm3 +- pand %xmm1, %xmm3 +- +- pmovmskb %xmm3, %eax +- incw %ax +- jnz L(64bytesormore_loop_end) +- +- addq $64, %rsi +- addq $64, %rdi +- subq $64, %rdx +- ja L(L2_L3_aligned_128bytes_loop) +- jmp L(loop_tail) +- +- .p2align 4 +-L(64bytesormore_loop_end): +- pmovmskb %xmm0, %ecx +- incw %cx +- jnz L(loop_end_ret) +- +- pmovmskb %xmm1, %ecx +- notw %cx +- sall $16, %ecx +- jnz L(loop_end_ret) +- +- pmovmskb %xmm2, %ecx +- notw %cx +- shlq $32, %rcx +- jnz L(loop_end_ret) +- +- addq $48, %rdi +- addq $48, %rsi +- movq %rax, %rcx +- +- .p2align 4,, 6 +-L(loop_end_ret): +- bsfq %rcx, %rcx +-# ifdef USE_AS_WMEMCMP +- movl (%rdi, %rcx), %eax +- xorl %edx, %edx +- cmpl (%rsi, %rcx), %eax +- setg %dl +- leal -1(%rdx, %rdx), %eax +-# else +- movzbl (%rdi, %rcx), %eax +- movzbl (%rsi, %rcx), %ecx +- subl %ecx, %eax +-# endif +- ret +-END (MEMCMP) +-#endif diff --git a/SOURCES/glibc-upstream-2.34-232.patch b/SOURCES/glibc-upstream-2.34-232.patch new file mode 100644 index 0000000..03ca852 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-232.patch @@ -0,0 +1,259 @@ +commit df5de87260dba479873b2850bbe5c0b81c2376f6 +Author: Noah Goldstein +Date: Fri Apr 15 12:28:01 2022 -0500 + + x86: Cleanup page cross code in memcmp-avx2-movbe.S + + Old code was both inefficient and wasted code size. New code (-62 + bytes) and comparable or better performance in the page cross case. + + geometric_mean(N=20) of page cross cases New / Original: 0.960 + + size, align0, align1, ret, New Time/Old Time + 1, 4095, 0, 0, 1.001 + 1, 4095, 0, 1, 0.999 + 1, 4095, 0, -1, 1.0 + 2, 4094, 0, 0, 1.0 + 2, 4094, 0, 1, 1.0 + 2, 4094, 0, -1, 1.0 + 3, 4093, 0, 0, 1.0 + 3, 4093, 0, 1, 1.0 + 3, 4093, 0, -1, 1.0 + 4, 4092, 0, 0, 0.987 + 4, 4092, 0, 1, 1.0 + 4, 4092, 0, -1, 1.0 + 5, 4091, 0, 0, 0.984 + 5, 4091, 0, 1, 1.002 + 5, 4091, 0, -1, 1.005 + 6, 4090, 0, 0, 0.993 + 6, 4090, 0, 1, 1.001 + 6, 4090, 0, -1, 1.003 + 7, 4089, 0, 0, 0.991 + 7, 4089, 0, 1, 1.0 + 7, 4089, 0, -1, 1.001 + 8, 4088, 0, 0, 0.875 + 8, 4088, 0, 1, 0.881 + 8, 4088, 0, -1, 0.888 + 9, 4087, 0, 0, 0.872 + 9, 4087, 0, 1, 0.879 + 9, 4087, 0, -1, 0.883 + 10, 4086, 0, 0, 0.878 + 10, 4086, 0, 1, 0.886 + 10, 4086, 0, -1, 0.873 + 11, 4085, 0, 0, 0.878 + 11, 4085, 0, 1, 0.881 + 11, 4085, 0, -1, 0.879 + 12, 4084, 0, 0, 0.873 + 12, 4084, 0, 1, 0.889 + 12, 4084, 0, -1, 0.875 + 13, 4083, 0, 0, 0.873 + 13, 4083, 0, 1, 0.863 + 13, 4083, 0, -1, 0.863 + 14, 4082, 0, 0, 0.838 + 14, 4082, 0, 1, 0.869 + 14, 4082, 0, -1, 0.877 + 15, 4081, 0, 0, 0.841 + 15, 4081, 0, 1, 0.869 + 15, 4081, 0, -1, 0.876 + 16, 4080, 0, 0, 0.988 + 16, 4080, 0, 1, 0.99 + 16, 4080, 0, -1, 0.989 + 17, 4079, 0, 0, 0.978 + 17, 4079, 0, 1, 0.981 + 17, 4079, 0, -1, 0.98 + 18, 4078, 0, 0, 0.981 + 18, 4078, 0, 1, 0.98 + 18, 4078, 0, -1, 0.985 + 19, 4077, 0, 0, 0.977 + 19, 4077, 0, 1, 0.979 + 19, 4077, 0, -1, 0.986 + 20, 4076, 0, 0, 0.977 + 20, 4076, 0, 1, 0.986 + 20, 4076, 0, -1, 0.984 + 21, 4075, 0, 0, 0.977 + 21, 4075, 0, 1, 0.983 + 21, 4075, 0, -1, 0.988 + 22, 4074, 0, 0, 0.983 + 22, 4074, 0, 1, 0.994 + 22, 4074, 0, -1, 0.993 + 23, 4073, 0, 0, 0.98 + 23, 4073, 0, 1, 0.992 + 23, 4073, 0, -1, 0.995 + 24, 4072, 0, 0, 0.989 + 24, 4072, 0, 1, 0.989 + 24, 4072, 0, -1, 0.991 + 25, 4071, 0, 0, 0.99 + 25, 4071, 0, 1, 0.999 + 25, 4071, 0, -1, 0.996 + 26, 4070, 0, 0, 0.993 + 26, 4070, 0, 1, 0.995 + 26, 4070, 0, -1, 0.998 + 27, 4069, 0, 0, 0.993 + 27, 4069, 0, 1, 0.999 + 27, 4069, 0, -1, 1.0 + 28, 4068, 0, 0, 0.997 + 28, 4068, 0, 1, 1.0 + 28, 4068, 0, -1, 0.999 + 29, 4067, 0, 0, 0.996 + 29, 4067, 0, 1, 0.999 + 29, 4067, 0, -1, 0.999 + 30, 4066, 0, 0, 0.991 + 30, 4066, 0, 1, 1.001 + 30, 4066, 0, -1, 0.999 + 31, 4065, 0, 0, 0.988 + 31, 4065, 0, 1, 0.998 + 31, 4065, 0, -1, 0.998 + Reviewed-by: H.J. Lu + + (cherry picked from commit 23102686ec67b856a2d4fd25ddaa1c0b8d175c4f) + +diff --git a/sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S b/sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S +index 2621ec907aedb781..ec9cf0852edf216d 100644 +--- a/sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S ++++ b/sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S +@@ -429,22 +429,21 @@ L(page_cross_less_vec): + # ifndef USE_AS_WMEMCMP + cmpl $8, %edx + jae L(between_8_15) ++ /* Fall through for [4, 7]. */ + cmpl $4, %edx +- jae L(between_4_7) ++ jb L(between_2_3) + +- /* Load as big endian to avoid branches. */ +- movzwl (%rdi), %eax +- movzwl (%rsi), %ecx +- shll $8, %eax +- shll $8, %ecx +- bswap %eax +- bswap %ecx +- movzbl -1(%rdi, %rdx), %edi +- movzbl -1(%rsi, %rdx), %esi +- orl %edi, %eax +- orl %esi, %ecx +- /* Subtraction is okay because the upper 8 bits are zero. */ +- subl %ecx, %eax ++ movbe (%rdi), %eax ++ movbe (%rsi), %ecx ++ shlq $32, %rax ++ shlq $32, %rcx ++ movbe -4(%rdi, %rdx), %edi ++ movbe -4(%rsi, %rdx), %esi ++ orq %rdi, %rax ++ orq %rsi, %rcx ++ subq %rcx, %rax ++ /* Fast path for return zero. */ ++ jnz L(ret_nonzero) + /* No ymm register was touched. */ + ret + +@@ -457,9 +456,33 @@ L(one_or_less): + /* No ymm register was touched. */ + ret + ++ .p2align 4,, 5 ++L(ret_nonzero): ++ sbbl %eax, %eax ++ orl $1, %eax ++ /* No ymm register was touched. */ ++ ret ++ ++ .p2align 4,, 2 ++L(zero): ++ xorl %eax, %eax ++ /* No ymm register was touched. */ ++ ret ++ + .p2align 4 + L(between_8_15): +-# endif ++ movbe (%rdi), %rax ++ movbe (%rsi), %rcx ++ subq %rcx, %rax ++ jnz L(ret_nonzero) ++ movbe -8(%rdi, %rdx), %rax ++ movbe -8(%rsi, %rdx), %rcx ++ subq %rcx, %rax ++ /* Fast path for return zero. */ ++ jnz L(ret_nonzero) ++ /* No ymm register was touched. */ ++ ret ++# else + /* If USE_AS_WMEMCMP fall through into 8-15 byte case. */ + vmovq (%rdi), %xmm1 + vmovq (%rsi), %xmm2 +@@ -475,16 +498,13 @@ L(between_8_15): + VPCMPEQ %xmm1, %xmm2, %xmm2 + vpmovmskb %xmm2, %eax + subl $0xffff, %eax ++ /* Fast path for return zero. */ + jnz L(return_vec_0) + /* No ymm register was touched. */ + ret ++# endif + +- .p2align 4 +-L(zero): +- xorl %eax, %eax +- ret +- +- .p2align 4 ++ .p2align 4,, 10 + L(between_16_31): + /* From 16 to 31 bytes. No branch when size == 16. */ + vmovdqu (%rsi), %xmm2 +@@ -501,11 +521,17 @@ L(between_16_31): + VPCMPEQ (%rdi), %xmm2, %xmm2 + vpmovmskb %xmm2, %eax + subl $0xffff, %eax ++ /* Fast path for return zero. */ + jnz L(return_vec_0) + /* No ymm register was touched. */ + ret + + # ifdef USE_AS_WMEMCMP ++ .p2align 4,, 2 ++L(zero): ++ xorl %eax, %eax ++ ret ++ + .p2align 4 + L(one_or_less): + jb L(zero) +@@ -520,22 +546,20 @@ L(one_or_less): + # else + + .p2align 4 +-L(between_4_7): +- /* Load as big endian with overlapping movbe to avoid branches. +- */ +- movbe (%rdi), %eax +- movbe (%rsi), %ecx +- shlq $32, %rax +- shlq $32, %rcx +- movbe -4(%rdi, %rdx), %edi +- movbe -4(%rsi, %rdx), %esi +- orq %rdi, %rax +- orq %rsi, %rcx +- subq %rcx, %rax +- jz L(zero_4_7) +- sbbl %eax, %eax +- orl $1, %eax +-L(zero_4_7): ++L(between_2_3): ++ /* Load as big endian to avoid branches. */ ++ movzwl (%rdi), %eax ++ movzwl (%rsi), %ecx ++ bswap %eax ++ bswap %ecx ++ shrl %eax ++ shrl %ecx ++ movzbl -1(%rdi, %rdx), %edi ++ movzbl -1(%rsi, %rdx), %esi ++ orl %edi, %eax ++ orl %esi, %ecx ++ /* Subtraction is okay because the upper bit is zero. */ ++ subl %ecx, %eax + /* No ymm register was touched. */ + ret + # endif diff --git a/SOURCES/glibc-upstream-2.34-233.patch b/SOURCES/glibc-upstream-2.34-233.patch new file mode 100644 index 0000000..30c79de --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-233.patch @@ -0,0 +1,865 @@ +commit 0a11305416e287d85c64f04337cfd64b6b350e0c +Author: Noah Goldstein +Date: Thu Apr 21 20:52:28 2022 -0500 + + x86: Optimize {str|wcs}rchr-sse2 + + The new code unrolls the main loop slightly without adding too much + overhead and minimizes the comparisons for the search CHAR. + + Geometric Mean of all benchmarks New / Old: 0.741 + See email for all results. + + Full xcheck passes on x86_64 with and without multiarch enabled. + Reviewed-by: H.J. Lu + + (cherry picked from commit 5307aa9c1800f36a64c183c091c9af392c1fa75c) + +diff --git a/sysdeps/x86_64/multiarch/strrchr-sse2.S b/sysdeps/x86_64/multiarch/strrchr-sse2.S +index 67c30d0260cef8a3..a56300bc1830dedd 100644 +--- a/sysdeps/x86_64/multiarch/strrchr-sse2.S ++++ b/sysdeps/x86_64/multiarch/strrchr-sse2.S +@@ -17,7 +17,7 @@ + . */ + + #if IS_IN (libc) +-# define strrchr __strrchr_sse2 ++# define STRRCHR __strrchr_sse2 + + # undef weak_alias + # define weak_alias(strrchr, rindex) +diff --git a/sysdeps/x86_64/multiarch/wcsrchr-sse2.S b/sysdeps/x86_64/multiarch/wcsrchr-sse2.S +index a36034b40afe8d3d..00f69f2be77a43a0 100644 +--- a/sysdeps/x86_64/multiarch/wcsrchr-sse2.S ++++ b/sysdeps/x86_64/multiarch/wcsrchr-sse2.S +@@ -17,7 +17,6 @@ + . */ + + #if IS_IN (libc) +-# define wcsrchr __wcsrchr_sse2 ++# define STRRCHR __wcsrchr_sse2 + #endif +- + #include "../wcsrchr.S" +diff --git a/sysdeps/x86_64/strrchr.S b/sysdeps/x86_64/strrchr.S +index dfd09fe9508cb5bc..fc1598bb11417fd5 100644 +--- a/sysdeps/x86_64/strrchr.S ++++ b/sysdeps/x86_64/strrchr.S +@@ -19,210 +19,360 @@ + + #include + ++#ifndef STRRCHR ++# define STRRCHR strrchr ++#endif ++ ++#ifdef USE_AS_WCSRCHR ++# define PCMPEQ pcmpeqd ++# define CHAR_SIZE 4 ++# define PMINU pminud ++#else ++# define PCMPEQ pcmpeqb ++# define CHAR_SIZE 1 ++# define PMINU pminub ++#endif ++ ++#define PAGE_SIZE 4096 ++#define VEC_SIZE 16 ++ + .text +-ENTRY (strrchr) +- movd %esi, %xmm1 ++ENTRY(STRRCHR) ++ movd %esi, %xmm0 + movq %rdi, %rax +- andl $4095, %eax +- punpcklbw %xmm1, %xmm1 +- cmpq $4032, %rax +- punpcklwd %xmm1, %xmm1 +- pshufd $0, %xmm1, %xmm1 ++ andl $(PAGE_SIZE - 1), %eax ++#ifndef USE_AS_WCSRCHR ++ punpcklbw %xmm0, %xmm0 ++ punpcklwd %xmm0, %xmm0 ++#endif ++ pshufd $0, %xmm0, %xmm0 ++ cmpl $(PAGE_SIZE - VEC_SIZE), %eax + ja L(cross_page) +- movdqu (%rdi), %xmm0 ++ ++L(cross_page_continue): ++ movups (%rdi), %xmm1 + pxor %xmm2, %xmm2 +- movdqa %xmm0, %xmm3 +- pcmpeqb %xmm1, %xmm0 +- pcmpeqb %xmm2, %xmm3 +- pmovmskb %xmm0, %ecx +- pmovmskb %xmm3, %edx +- testq %rdx, %rdx +- je L(next_48_bytes) +- leaq -1(%rdx), %rax +- xorq %rdx, %rax +- andq %rcx, %rax +- je L(exit) +- bsrq %rax, %rax ++ PCMPEQ %xmm1, %xmm2 ++ pmovmskb %xmm2, %ecx ++ testl %ecx, %ecx ++ jz L(aligned_more) ++ ++ PCMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ leal -1(%rcx), %edx ++ xorl %edx, %ecx ++ andl %ecx, %eax ++ jz L(ret0) ++ bsrl %eax, %eax + addq %rdi, %rax ++ /* We are off by 3 for wcsrchr if search CHAR is non-zero. If ++ search CHAR is zero we are correct. Either way `andq ++ -CHAR_SIZE, %rax` gets the correct result. */ ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif ++L(ret0): + ret + ++ /* Returns for first vec x1/x2 have hard coded backward search ++ path for earlier matches. */ + .p2align 4 +-L(next_48_bytes): +- movdqu 16(%rdi), %xmm4 +- movdqa %xmm4, %xmm5 +- movdqu 32(%rdi), %xmm3 +- pcmpeqb %xmm1, %xmm4 +- pcmpeqb %xmm2, %xmm5 +- movdqu 48(%rdi), %xmm0 +- pmovmskb %xmm5, %edx +- movdqa %xmm3, %xmm5 +- pcmpeqb %xmm1, %xmm3 +- pcmpeqb %xmm2, %xmm5 +- pcmpeqb %xmm0, %xmm2 +- salq $16, %rdx +- pmovmskb %xmm3, %r8d +- pmovmskb %xmm5, %eax +- pmovmskb %xmm2, %esi +- salq $32, %r8 +- salq $32, %rax +- pcmpeqb %xmm1, %xmm0 +- orq %rdx, %rax +- movq %rsi, %rdx +- pmovmskb %xmm4, %esi +- salq $48, %rdx +- salq $16, %rsi +- orq %r8, %rsi +- orq %rcx, %rsi +- pmovmskb %xmm0, %ecx +- salq $48, %rcx +- orq %rcx, %rsi +- orq %rdx, %rax +- je L(loop_header2) +- leaq -1(%rax), %rcx +- xorq %rax, %rcx +- andq %rcx, %rsi +- je L(exit) +- bsrq %rsi, %rsi +- leaq (%rdi,%rsi), %rax ++L(first_vec_x0_test): ++ PCMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ testl %eax, %eax ++ jz L(ret0) ++ bsrl %eax, %eax ++ addq %r8, %rax ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif + ret + + .p2align 4 +-L(loop_header2): +- testq %rsi, %rsi +- movq %rdi, %rcx +- je L(no_c_found) +-L(loop_header): +- addq $64, %rdi +- pxor %xmm7, %xmm7 +- andq $-64, %rdi +- jmp L(loop_entry) ++L(first_vec_x1): ++ PCMPEQ %xmm0, %xmm2 ++ pmovmskb %xmm2, %eax ++ leal -1(%rcx), %edx ++ xorl %edx, %ecx ++ andl %ecx, %eax ++ jz L(first_vec_x0_test) ++ bsrl %eax, %eax ++ leaq (VEC_SIZE)(%rdi, %rax), %rax ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif ++ ret + + .p2align 4 +-L(loop64): +- testq %rdx, %rdx +- cmovne %rdx, %rsi +- cmovne %rdi, %rcx +- addq $64, %rdi +-L(loop_entry): +- movdqa 32(%rdi), %xmm3 +- pxor %xmm6, %xmm6 +- movdqa 48(%rdi), %xmm2 +- movdqa %xmm3, %xmm0 +- movdqa 16(%rdi), %xmm4 +- pminub %xmm2, %xmm0 +- movdqa (%rdi), %xmm5 +- pminub %xmm4, %xmm0 +- pminub %xmm5, %xmm0 +- pcmpeqb %xmm7, %xmm0 +- pmovmskb %xmm0, %eax +- movdqa %xmm5, %xmm0 +- pcmpeqb %xmm1, %xmm0 +- pmovmskb %xmm0, %r9d +- movdqa %xmm4, %xmm0 +- pcmpeqb %xmm1, %xmm0 +- pmovmskb %xmm0, %edx +- movdqa %xmm3, %xmm0 +- pcmpeqb %xmm1, %xmm0 +- salq $16, %rdx +- pmovmskb %xmm0, %r10d +- movdqa %xmm2, %xmm0 +- pcmpeqb %xmm1, %xmm0 +- salq $32, %r10 +- orq %r10, %rdx +- pmovmskb %xmm0, %r8d +- orq %r9, %rdx +- salq $48, %r8 +- orq %r8, %rdx ++L(first_vec_x1_test): ++ PCMPEQ %xmm0, %xmm2 ++ pmovmskb %xmm2, %eax + testl %eax, %eax +- je L(loop64) +- pcmpeqb %xmm6, %xmm4 +- pcmpeqb %xmm6, %xmm3 +- pcmpeqb %xmm6, %xmm5 +- pmovmskb %xmm4, %eax +- pmovmskb %xmm3, %r10d +- pcmpeqb %xmm6, %xmm2 +- pmovmskb %xmm5, %r9d +- salq $32, %r10 +- salq $16, %rax +- pmovmskb %xmm2, %r8d +- orq %r10, %rax +- orq %r9, %rax +- salq $48, %r8 +- orq %r8, %rax +- leaq -1(%rax), %r8 +- xorq %rax, %r8 +- andq %r8, %rdx +- cmovne %rdi, %rcx +- cmovne %rdx, %rsi +- bsrq %rsi, %rsi +- leaq (%rcx,%rsi), %rax ++ jz L(first_vec_x0_test) ++ bsrl %eax, %eax ++ leaq (VEC_SIZE)(%rdi, %rax), %rax ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif ++ ret ++ ++ .p2align 4 ++L(first_vec_x2): ++ PCMPEQ %xmm0, %xmm3 ++ pmovmskb %xmm3, %eax ++ leal -1(%rcx), %edx ++ xorl %edx, %ecx ++ andl %ecx, %eax ++ jz L(first_vec_x1_test) ++ bsrl %eax, %eax ++ leaq (VEC_SIZE * 2)(%rdi, %rax), %rax ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif ++ ret ++ ++ .p2align 4 ++L(aligned_more): ++ /* Save original pointer if match was in VEC 0. */ ++ movq %rdi, %r8 ++ andq $-VEC_SIZE, %rdi ++ ++ movaps VEC_SIZE(%rdi), %xmm2 ++ pxor %xmm3, %xmm3 ++ PCMPEQ %xmm2, %xmm3 ++ pmovmskb %xmm3, %ecx ++ testl %ecx, %ecx ++ jnz L(first_vec_x1) ++ ++ movaps (VEC_SIZE * 2)(%rdi), %xmm3 ++ pxor %xmm4, %xmm4 ++ PCMPEQ %xmm3, %xmm4 ++ pmovmskb %xmm4, %ecx ++ testl %ecx, %ecx ++ jnz L(first_vec_x2) ++ ++ addq $VEC_SIZE, %rdi ++ /* Save pointer again before realigning. */ ++ movq %rdi, %rsi ++ andq $-(VEC_SIZE * 2), %rdi ++ .p2align 4 ++L(first_loop): ++ /* Do 2x VEC at a time. */ ++ movaps (VEC_SIZE * 2)(%rdi), %xmm4 ++ movaps (VEC_SIZE * 3)(%rdi), %xmm5 ++ /* Since SSE2 no pminud so wcsrchr needs seperate logic for ++ detecting zero. Note if this is found to be a bottleneck it ++ may be worth adding an SSE4.1 wcsrchr implementation. */ ++#ifdef USE_AS_WCSRCHR ++ movaps %xmm5, %xmm6 ++ pxor %xmm8, %xmm8 ++ ++ PCMPEQ %xmm8, %xmm5 ++ PCMPEQ %xmm4, %xmm8 ++ por %xmm5, %xmm8 ++#else ++ movaps %xmm5, %xmm6 ++ PMINU %xmm4, %xmm5 ++#endif ++ ++ movaps %xmm4, %xmm9 ++ PCMPEQ %xmm0, %xmm4 ++ PCMPEQ %xmm0, %xmm6 ++ movaps %xmm6, %xmm7 ++ por %xmm4, %xmm6 ++#ifndef USE_AS_WCSRCHR ++ pxor %xmm8, %xmm8 ++ PCMPEQ %xmm5, %xmm8 ++#endif ++ pmovmskb %xmm8, %ecx ++ pmovmskb %xmm6, %eax ++ ++ addq $(VEC_SIZE * 2), %rdi ++ /* Use `addl` 1) so we can undo it with `subl` and 2) it can ++ macro-fuse with `jz`. */ ++ addl %ecx, %eax ++ jz L(first_loop) ++ ++ /* Check if there is zero match. */ ++ testl %ecx, %ecx ++ jz L(second_loop_match) ++ ++ /* Check if there was a match in last iteration. */ ++ subl %ecx, %eax ++ jnz L(new_match) ++ ++L(first_loop_old_match): ++ PCMPEQ %xmm0, %xmm2 ++ PCMPEQ %xmm0, %xmm3 ++ pmovmskb %xmm2, %ecx ++ pmovmskb %xmm3, %eax ++ addl %eax, %ecx ++ jz L(first_vec_x0_test) ++ /* NB: We could move this shift to before the branch and save a ++ bit of code size / performance on the fall through. The ++ branch leads to the null case which generally seems hotter ++ than char in first 3x VEC. */ ++ sall $16, %eax ++ orl %ecx, %eax ++ ++ bsrl %eax, %eax ++ addq %rsi, %rax ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif ++ ret ++ ++ .p2align 4 ++L(new_match): ++ pxor %xmm6, %xmm6 ++ PCMPEQ %xmm9, %xmm6 ++ pmovmskb %xmm6, %eax ++ sall $16, %ecx ++ orl %eax, %ecx ++ ++ /* We can't reuse either of the old comparisons as since we mask ++ of zeros after first zero (instead of using the full ++ comparison) we can't gurantee no interference between match ++ after end of string and valid match. */ ++ pmovmskb %xmm4, %eax ++ pmovmskb %xmm7, %edx ++ sall $16, %edx ++ orl %edx, %eax ++ ++ leal -1(%ecx), %edx ++ xorl %edx, %ecx ++ andl %ecx, %eax ++ jz L(first_loop_old_match) ++ bsrl %eax, %eax ++ addq %rdi, %rax ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif + ret + ++ /* Save minimum state for getting most recent match. We can ++ throw out all previous work. */ + .p2align 4 +-L(no_c_found): +- movl $1, %esi +- xorl %ecx, %ecx +- jmp L(loop_header) ++L(second_loop_match): ++ movq %rdi, %rsi ++ movaps %xmm4, %xmm2 ++ movaps %xmm7, %xmm3 + + .p2align 4 +-L(exit): +- xorl %eax, %eax ++L(second_loop): ++ movaps (VEC_SIZE * 2)(%rdi), %xmm4 ++ movaps (VEC_SIZE * 3)(%rdi), %xmm5 ++ /* Since SSE2 no pminud so wcsrchr needs seperate logic for ++ detecting zero. Note if this is found to be a bottleneck it ++ may be worth adding an SSE4.1 wcsrchr implementation. */ ++#ifdef USE_AS_WCSRCHR ++ movaps %xmm5, %xmm6 ++ pxor %xmm8, %xmm8 ++ ++ PCMPEQ %xmm8, %xmm5 ++ PCMPEQ %xmm4, %xmm8 ++ por %xmm5, %xmm8 ++#else ++ movaps %xmm5, %xmm6 ++ PMINU %xmm4, %xmm5 ++#endif ++ ++ movaps %xmm4, %xmm9 ++ PCMPEQ %xmm0, %xmm4 ++ PCMPEQ %xmm0, %xmm6 ++ movaps %xmm6, %xmm7 ++ por %xmm4, %xmm6 ++#ifndef USE_AS_WCSRCHR ++ pxor %xmm8, %xmm8 ++ PCMPEQ %xmm5, %xmm8 ++#endif ++ ++ pmovmskb %xmm8, %ecx ++ pmovmskb %xmm6, %eax ++ ++ addq $(VEC_SIZE * 2), %rdi ++ /* Either null term or new occurence of CHAR. */ ++ addl %ecx, %eax ++ jz L(second_loop) ++ ++ /* No null term so much be new occurence of CHAR. */ ++ testl %ecx, %ecx ++ jz L(second_loop_match) ++ ++ ++ subl %ecx, %eax ++ jnz L(second_loop_new_match) ++ ++L(second_loop_old_match): ++ pmovmskb %xmm2, %ecx ++ pmovmskb %xmm3, %eax ++ sall $16, %eax ++ orl %ecx, %eax ++ bsrl %eax, %eax ++ addq %rsi, %rax ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif + ret + + .p2align 4 ++L(second_loop_new_match): ++ pxor %xmm6, %xmm6 ++ PCMPEQ %xmm9, %xmm6 ++ pmovmskb %xmm6, %eax ++ sall $16, %ecx ++ orl %eax, %ecx ++ ++ /* We can't reuse either of the old comparisons as since we mask ++ of zeros after first zero (instead of using the full ++ comparison) we can't gurantee no interference between match ++ after end of string and valid match. */ ++ pmovmskb %xmm4, %eax ++ pmovmskb %xmm7, %edx ++ sall $16, %edx ++ orl %edx, %eax ++ ++ leal -1(%ecx), %edx ++ xorl %edx, %ecx ++ andl %ecx, %eax ++ jz L(second_loop_old_match) ++ bsrl %eax, %eax ++ addq %rdi, %rax ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif ++ ret ++ ++ .p2align 4,, 4 + L(cross_page): +- movq %rdi, %rax +- pxor %xmm0, %xmm0 +- andq $-64, %rax +- movdqu (%rax), %xmm5 +- movdqa %xmm5, %xmm6 +- movdqu 16(%rax), %xmm4 +- pcmpeqb %xmm1, %xmm5 +- pcmpeqb %xmm0, %xmm6 +- movdqu 32(%rax), %xmm3 +- pmovmskb %xmm6, %esi +- movdqa %xmm4, %xmm6 +- movdqu 48(%rax), %xmm2 +- pcmpeqb %xmm1, %xmm4 +- pcmpeqb %xmm0, %xmm6 +- pmovmskb %xmm6, %edx +- movdqa %xmm3, %xmm6 +- pcmpeqb %xmm1, %xmm3 +- pcmpeqb %xmm0, %xmm6 +- pcmpeqb %xmm2, %xmm0 +- salq $16, %rdx +- pmovmskb %xmm3, %r9d +- pmovmskb %xmm6, %r8d +- pmovmskb %xmm0, %ecx +- salq $32, %r9 +- salq $32, %r8 +- pcmpeqb %xmm1, %xmm2 +- orq %r8, %rdx +- salq $48, %rcx +- pmovmskb %xmm5, %r8d +- orq %rsi, %rdx +- pmovmskb %xmm4, %esi +- orq %rcx, %rdx +- pmovmskb %xmm2, %ecx +- salq $16, %rsi +- salq $48, %rcx +- orq %r9, %rsi +- orq %r8, %rsi +- orq %rcx, %rsi ++ movq %rdi, %rsi ++ andq $-VEC_SIZE, %rsi ++ movaps (%rsi), %xmm1 ++ pxor %xmm2, %xmm2 ++ PCMPEQ %xmm1, %xmm2 ++ pmovmskb %xmm2, %edx + movl %edi, %ecx +- subl %eax, %ecx +- shrq %cl, %rdx +- shrq %cl, %rsi +- testq %rdx, %rdx +- je L(loop_header2) +- leaq -1(%rdx), %rax +- xorq %rdx, %rax +- andq %rax, %rsi +- je L(exit) +- bsrq %rsi, %rax ++ andl $(VEC_SIZE - 1), %ecx ++ sarl %cl, %edx ++ jz L(cross_page_continue) ++ PCMPEQ %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ sarl %cl, %eax ++ leal -1(%rdx), %ecx ++ xorl %edx, %ecx ++ andl %ecx, %eax ++ jz L(ret1) ++ bsrl %eax, %eax + addq %rdi, %rax ++#ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++#endif ++L(ret1): + ret +-END (strrchr) ++END(STRRCHR) + +-weak_alias (strrchr, rindex) +-libc_hidden_builtin_def (strrchr) ++#ifndef USE_AS_WCSRCHR ++ weak_alias (STRRCHR, rindex) ++ libc_hidden_builtin_def (STRRCHR) ++#endif +diff --git a/sysdeps/x86_64/wcsrchr.S b/sysdeps/x86_64/wcsrchr.S +index 6b318d3f29de9a9e..9006f2220963d76c 100644 +--- a/sysdeps/x86_64/wcsrchr.S ++++ b/sysdeps/x86_64/wcsrchr.S +@@ -17,266 +17,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#include + +- .text +-ENTRY (wcsrchr) ++#define USE_AS_WCSRCHR 1 ++#define NO_PMINU 1 + +- movd %rsi, %xmm1 +- mov %rdi, %rcx +- punpckldq %xmm1, %xmm1 +- pxor %xmm2, %xmm2 +- punpckldq %xmm1, %xmm1 +- and $63, %rcx +- cmp $48, %rcx +- ja L(crosscache) ++#ifndef STRRCHR ++# define STRRCHR wcsrchr ++#endif + +- movdqu (%rdi), %xmm0 +- pcmpeqd %xmm0, %xmm2 +- pcmpeqd %xmm1, %xmm0 +- pmovmskb %xmm2, %rcx +- pmovmskb %xmm0, %rax +- add $16, %rdi +- +- test %rax, %rax +- jnz L(unaligned_match1) +- +- test %rcx, %rcx +- jnz L(return_null) +- +- and $-16, %rdi +- xor %r8, %r8 +- jmp L(loop) +- +- .p2align 4 +-L(unaligned_match1): +- test %rcx, %rcx +- jnz L(prolog_find_zero_1) +- +- mov %rax, %r8 +- mov %rdi, %rsi +- and $-16, %rdi +- jmp L(loop) +- +- .p2align 4 +-L(crosscache): +- and $15, %rcx +- and $-16, %rdi +- pxor %xmm3, %xmm3 +- movdqa (%rdi), %xmm0 +- pcmpeqd %xmm0, %xmm3 +- pcmpeqd %xmm1, %xmm0 +- pmovmskb %xmm3, %rdx +- pmovmskb %xmm0, %rax +- shr %cl, %rdx +- shr %cl, %rax +- add $16, %rdi +- +- test %rax, %rax +- jnz L(unaligned_match) +- +- test %rdx, %rdx +- jnz L(return_null) +- +- xor %r8, %r8 +- jmp L(loop) +- +- .p2align 4 +-L(unaligned_match): +- test %rdx, %rdx +- jnz L(prolog_find_zero) +- +- mov %rax, %r8 +- lea (%rdi, %rcx), %rsi +- +-/* Loop start on aligned string. */ +- .p2align 4 +-L(loop): +- movdqa (%rdi), %xmm0 +- pcmpeqd %xmm0, %xmm2 +- add $16, %rdi +- pcmpeqd %xmm1, %xmm0 +- pmovmskb %xmm2, %rcx +- pmovmskb %xmm0, %rax +- or %rax, %rcx +- jnz L(matches) +- +- movdqa (%rdi), %xmm3 +- pcmpeqd %xmm3, %xmm2 +- add $16, %rdi +- pcmpeqd %xmm1, %xmm3 +- pmovmskb %xmm2, %rcx +- pmovmskb %xmm3, %rax +- or %rax, %rcx +- jnz L(matches) +- +- movdqa (%rdi), %xmm4 +- pcmpeqd %xmm4, %xmm2 +- add $16, %rdi +- pcmpeqd %xmm1, %xmm4 +- pmovmskb %xmm2, %rcx +- pmovmskb %xmm4, %rax +- or %rax, %rcx +- jnz L(matches) +- +- movdqa (%rdi), %xmm5 +- pcmpeqd %xmm5, %xmm2 +- add $16, %rdi +- pcmpeqd %xmm1, %xmm5 +- pmovmskb %xmm2, %rcx +- pmovmskb %xmm5, %rax +- or %rax, %rcx +- jz L(loop) +- +- .p2align 4 +-L(matches): +- test %rax, %rax +- jnz L(match) +-L(return_value): +- test %r8, %r8 +- jz L(return_null) +- mov %r8, %rax +- mov %rsi, %rdi +- +- test $15 << 4, %ah +- jnz L(match_fourth_wchar) +- test %ah, %ah +- jnz L(match_third_wchar) +- test $15 << 4, %al +- jnz L(match_second_wchar) +- lea -16(%rdi), %rax +- ret +- +- .p2align 4 +-L(match): +- pmovmskb %xmm2, %rcx +- test %rcx, %rcx +- jnz L(find_zero) +- mov %rax, %r8 +- mov %rdi, %rsi +- jmp L(loop) +- +- .p2align 4 +-L(find_zero): +- test $15, %cl +- jnz L(find_zero_in_first_wchar) +- test %cl, %cl +- jnz L(find_zero_in_second_wchar) +- test $15, %ch +- jnz L(find_zero_in_third_wchar) +- +- and $1 << 13 - 1, %rax +- jz L(return_value) +- +- test $15 << 4, %ah +- jnz L(match_fourth_wchar) +- test %ah, %ah +- jnz L(match_third_wchar) +- test $15 << 4, %al +- jnz L(match_second_wchar) +- lea -16(%rdi), %rax +- ret +- +- .p2align 4 +-L(find_zero_in_first_wchar): +- test $1, %rax +- jz L(return_value) +- lea -16(%rdi), %rax +- ret +- +- .p2align 4 +-L(find_zero_in_second_wchar): +- and $1 << 5 - 1, %rax +- jz L(return_value) +- +- test $15 << 4, %al +- jnz L(match_second_wchar) +- lea -16(%rdi), %rax +- ret +- +- .p2align 4 +-L(find_zero_in_third_wchar): +- and $1 << 9 - 1, %rax +- jz L(return_value) +- +- test %ah, %ah +- jnz L(match_third_wchar) +- test $15 << 4, %al +- jnz L(match_second_wchar) +- lea -16(%rdi), %rax +- ret +- +- .p2align 4 +-L(prolog_find_zero): +- add %rcx, %rdi +- mov %rdx, %rcx +-L(prolog_find_zero_1): +- test $15, %cl +- jnz L(prolog_find_zero_in_first_wchar) +- test %cl, %cl +- jnz L(prolog_find_zero_in_second_wchar) +- test $15, %ch +- jnz L(prolog_find_zero_in_third_wchar) +- +- and $1 << 13 - 1, %rax +- jz L(return_null) +- +- test $15 << 4, %ah +- jnz L(match_fourth_wchar) +- test %ah, %ah +- jnz L(match_third_wchar) +- test $15 << 4, %al +- jnz L(match_second_wchar) +- lea -16(%rdi), %rax +- ret +- +- .p2align 4 +-L(prolog_find_zero_in_first_wchar): +- test $1, %rax +- jz L(return_null) +- lea -16(%rdi), %rax +- ret +- +- .p2align 4 +-L(prolog_find_zero_in_second_wchar): +- and $1 << 5 - 1, %rax +- jz L(return_null) +- +- test $15 << 4, %al +- jnz L(match_second_wchar) +- lea -16(%rdi), %rax +- ret +- +- .p2align 4 +-L(prolog_find_zero_in_third_wchar): +- and $1 << 9 - 1, %rax +- jz L(return_null) +- +- test %ah, %ah +- jnz L(match_third_wchar) +- test $15 << 4, %al +- jnz L(match_second_wchar) +- lea -16(%rdi), %rax +- ret +- +- .p2align 4 +-L(match_second_wchar): +- lea -12(%rdi), %rax +- ret +- +- .p2align 4 +-L(match_third_wchar): +- lea -8(%rdi), %rax +- ret +- +- .p2align 4 +-L(match_fourth_wchar): +- lea -4(%rdi), %rax +- ret +- +- .p2align 4 +-L(return_null): +- xor %rax, %rax +- ret +- +-END (wcsrchr) ++#include "../strrchr.S" diff --git a/SOURCES/glibc-upstream-2.34-234.patch b/SOURCES/glibc-upstream-2.34-234.patch new file mode 100644 index 0000000..4b8b07d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-234.patch @@ -0,0 +1,497 @@ +commit 00f09a14d2818f438959e764834abb3913f2b20a +Author: Noah Goldstein +Date: Thu Apr 21 20:52:29 2022 -0500 + + x86: Optimize {str|wcs}rchr-avx2 + + The new code unrolls the main loop slightly without adding too much + overhead and minimizes the comparisons for the search CHAR. + + Geometric Mean of all benchmarks New / Old: 0.832 + See email for all results. + + Full xcheck passes on x86_64 with and without multiarch enabled. + Reviewed-by: H.J. Lu + + (cherry picked from commit df7e295d18ffa34f629578c0017a9881af7620f6) + +diff --git a/sysdeps/x86_64/multiarch/strrchr-avx2.S b/sysdeps/x86_64/multiarch/strrchr-avx2.S +index 0deba97114d3b83d..b8dec737d5213b25 100644 +--- a/sysdeps/x86_64/multiarch/strrchr-avx2.S ++++ b/sysdeps/x86_64/multiarch/strrchr-avx2.S +@@ -27,9 +27,13 @@ + # ifdef USE_AS_WCSRCHR + # define VPBROADCAST vpbroadcastd + # define VPCMPEQ vpcmpeqd ++# define VPMIN vpminud ++# define CHAR_SIZE 4 + # else + # define VPBROADCAST vpbroadcastb + # define VPCMPEQ vpcmpeqb ++# define VPMIN vpminub ++# define CHAR_SIZE 1 + # endif + + # ifndef VZEROUPPER +@@ -41,196 +45,304 @@ + # endif + + # define VEC_SIZE 32 ++# define PAGE_SIZE 4096 + +- .section SECTION(.text),"ax",@progbits +-ENTRY (STRRCHR) +- movd %esi, %xmm4 +- movl %edi, %ecx ++ .section SECTION(.text), "ax", @progbits ++ENTRY(STRRCHR) ++ movd %esi, %xmm7 ++ movl %edi, %eax + /* Broadcast CHAR to YMM4. */ +- VPBROADCAST %xmm4, %ymm4 ++ VPBROADCAST %xmm7, %ymm7 + vpxor %xmm0, %xmm0, %xmm0 + +- /* Check if we may cross page boundary with one vector load. */ +- andl $(2 * VEC_SIZE - 1), %ecx +- cmpl $VEC_SIZE, %ecx +- ja L(cros_page_boundary) ++ /* Shift here instead of `andl` to save code size (saves a fetch ++ block). */ ++ sall $20, %eax ++ cmpl $((PAGE_SIZE - VEC_SIZE) << 20), %eax ++ ja L(cross_page) + ++L(page_cross_continue): + vmovdqu (%rdi), %ymm1 +- VPCMPEQ %ymm1, %ymm0, %ymm2 +- VPCMPEQ %ymm1, %ymm4, %ymm3 +- vpmovmskb %ymm2, %ecx +- vpmovmskb %ymm3, %eax +- addq $VEC_SIZE, %rdi ++ /* Check end of string match. */ ++ VPCMPEQ %ymm1, %ymm0, %ymm6 ++ vpmovmskb %ymm6, %ecx ++ testl %ecx, %ecx ++ jz L(aligned_more) ++ ++ /* Only check match with search CHAR if needed. */ ++ VPCMPEQ %ymm1, %ymm7, %ymm1 ++ vpmovmskb %ymm1, %eax ++ /* Check if match before first zero. */ ++ blsmskl %ecx, %ecx ++ andl %ecx, %eax ++ jz L(ret0) ++ bsrl %eax, %eax ++ addq %rdi, %rax ++ /* We are off by 3 for wcsrchr if search CHAR is non-zero. If ++ search CHAR is zero we are correct. Either way `andq ++ -CHAR_SIZE, %rax` gets the correct result. */ ++# ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++# endif ++L(ret0): ++L(return_vzeroupper): ++ ZERO_UPPER_VEC_REGISTERS_RETURN ++ ++ /* Returns for first vec x1/x2 have hard coded backward search ++ path for earlier matches. */ ++ .p2align 4,, 10 ++L(first_vec_x1): ++ VPCMPEQ %ymm2, %ymm7, %ymm6 ++ vpmovmskb %ymm6, %eax ++ blsmskl %ecx, %ecx ++ andl %ecx, %eax ++ jnz L(first_vec_x1_return) ++ ++ .p2align 4,, 4 ++L(first_vec_x0_test): ++ VPCMPEQ %ymm1, %ymm7, %ymm6 ++ vpmovmskb %ymm6, %eax ++ testl %eax, %eax ++ jz L(ret1) ++ bsrl %eax, %eax ++ addq %r8, %rax ++# ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++# endif ++L(ret1): ++ VZEROUPPER_RETURN + ++ .p2align 4,, 10 ++L(first_vec_x0_x1_test): ++ VPCMPEQ %ymm2, %ymm7, %ymm6 ++ vpmovmskb %ymm6, %eax ++ /* Check ymm2 for search CHAR match. If no match then check ymm1 ++ before returning. */ + testl %eax, %eax +- jnz L(first_vec) ++ jz L(first_vec_x0_test) ++ .p2align 4,, 4 ++L(first_vec_x1_return): ++ bsrl %eax, %eax ++ leaq 1(%rdi, %rax), %rax ++# ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++# endif ++ VZEROUPPER_RETURN + +- testl %ecx, %ecx +- jnz L(return_null) + +- andq $-VEC_SIZE, %rdi +- xorl %edx, %edx +- jmp L(aligned_loop) ++ .p2align 4,, 10 ++L(first_vec_x2): ++ VPCMPEQ %ymm3, %ymm7, %ymm6 ++ vpmovmskb %ymm6, %eax ++ blsmskl %ecx, %ecx ++ /* If no in-range search CHAR match in ymm3 then need to check ++ ymm1/ymm2 for an earlier match (we delay checking search ++ CHAR matches until needed). */ ++ andl %ecx, %eax ++ jz L(first_vec_x0_x1_test) ++ bsrl %eax, %eax ++ leaq (VEC_SIZE + 1)(%rdi, %rax), %rax ++# ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++# endif ++ VZEROUPPER_RETURN ++ + + .p2align 4 +-L(first_vec): +- /* Check if there is a nul CHAR. */ ++L(aligned_more): ++ /* Save original pointer if match was in VEC 0. */ ++ movq %rdi, %r8 ++ ++ /* Align src. */ ++ orq $(VEC_SIZE - 1), %rdi ++ vmovdqu 1(%rdi), %ymm2 ++ VPCMPEQ %ymm2, %ymm0, %ymm6 ++ vpmovmskb %ymm6, %ecx + testl %ecx, %ecx +- jnz L(char_and_nul_in_first_vec) ++ jnz L(first_vec_x1) + +- /* Remember the match and keep searching. */ +- movl %eax, %edx +- movq %rdi, %rsi +- andq $-VEC_SIZE, %rdi +- jmp L(aligned_loop) ++ vmovdqu (VEC_SIZE + 1)(%rdi), %ymm3 ++ VPCMPEQ %ymm3, %ymm0, %ymm6 ++ vpmovmskb %ymm6, %ecx ++ testl %ecx, %ecx ++ jnz L(first_vec_x2) + ++ /* Save pointer again before realigning. */ ++ movq %rdi, %rsi ++ addq $(VEC_SIZE + 1), %rdi ++ andq $-(VEC_SIZE * 2), %rdi + .p2align 4 +-L(cros_page_boundary): +- andl $(VEC_SIZE - 1), %ecx +- andq $-VEC_SIZE, %rdi +- vmovdqa (%rdi), %ymm1 +- VPCMPEQ %ymm1, %ymm0, %ymm2 +- VPCMPEQ %ymm1, %ymm4, %ymm3 +- vpmovmskb %ymm2, %edx +- vpmovmskb %ymm3, %eax +- shrl %cl, %edx +- shrl %cl, %eax +- addq $VEC_SIZE, %rdi +- +- /* Check if there is a CHAR. */ ++L(first_aligned_loop): ++ /* Do 2x VEC at a time. Any more and the cost of finding the ++ match outweights loop benefit. */ ++ vmovdqa (VEC_SIZE * 0)(%rdi), %ymm4 ++ vmovdqa (VEC_SIZE * 1)(%rdi), %ymm5 ++ ++ VPCMPEQ %ymm4, %ymm7, %ymm6 ++ VPMIN %ymm4, %ymm5, %ymm8 ++ VPCMPEQ %ymm5, %ymm7, %ymm10 ++ vpor %ymm6, %ymm10, %ymm5 ++ VPCMPEQ %ymm8, %ymm0, %ymm8 ++ vpor %ymm5, %ymm8, %ymm9 ++ ++ vpmovmskb %ymm9, %eax ++ addq $(VEC_SIZE * 2), %rdi ++ /* No zero or search CHAR. */ + testl %eax, %eax +- jnz L(found_char) +- +- testl %edx, %edx +- jnz L(return_null) ++ jz L(first_aligned_loop) + +- jmp L(aligned_loop) +- +- .p2align 4 +-L(found_char): +- testl %edx, %edx +- jnz L(char_and_nul) ++ /* If no zero CHAR then go to second loop (this allows us to ++ throw away all prior work). */ ++ vpmovmskb %ymm8, %ecx ++ testl %ecx, %ecx ++ jz L(second_aligned_loop_prep) + +- /* Remember the match and keep searching. */ +- movl %eax, %edx +- leaq (%rdi, %rcx), %rsi ++ /* Search char could be zero so we need to get the true match. ++ */ ++ vpmovmskb %ymm5, %eax ++ testl %eax, %eax ++ jnz L(first_aligned_loop_return) + +- .p2align 4 +-L(aligned_loop): +- vmovdqa (%rdi), %ymm1 +- VPCMPEQ %ymm1, %ymm0, %ymm2 +- addq $VEC_SIZE, %rdi +- VPCMPEQ %ymm1, %ymm4, %ymm3 +- vpmovmskb %ymm2, %ecx +- vpmovmskb %ymm3, %eax +- orl %eax, %ecx +- jnz L(char_nor_null) +- +- vmovdqa (%rdi), %ymm1 +- VPCMPEQ %ymm1, %ymm0, %ymm2 +- add $VEC_SIZE, %rdi +- VPCMPEQ %ymm1, %ymm4, %ymm3 +- vpmovmskb %ymm2, %ecx ++ .p2align 4,, 4 ++L(first_vec_x1_or_x2): ++ VPCMPEQ %ymm3, %ymm7, %ymm3 ++ VPCMPEQ %ymm2, %ymm7, %ymm2 + vpmovmskb %ymm3, %eax +- orl %eax, %ecx +- jnz L(char_nor_null) +- +- vmovdqa (%rdi), %ymm1 +- VPCMPEQ %ymm1, %ymm0, %ymm2 +- addq $VEC_SIZE, %rdi +- VPCMPEQ %ymm1, %ymm4, %ymm3 +- vpmovmskb %ymm2, %ecx +- vpmovmskb %ymm3, %eax +- orl %eax, %ecx +- jnz L(char_nor_null) +- +- vmovdqa (%rdi), %ymm1 +- VPCMPEQ %ymm1, %ymm0, %ymm2 +- addq $VEC_SIZE, %rdi +- VPCMPEQ %ymm1, %ymm4, %ymm3 +- vpmovmskb %ymm2, %ecx +- vpmovmskb %ymm3, %eax +- orl %eax, %ecx +- jz L(aligned_loop) +- +- .p2align 4 +-L(char_nor_null): +- /* Find a CHAR or a nul CHAR in a loop. */ +- testl %eax, %eax +- jnz L(match) +-L(return_value): +- testl %edx, %edx +- jz L(return_null) +- movl %edx, %eax +- movq %rsi, %rdi ++ vpmovmskb %ymm2, %edx ++ /* Use add for macro-fusion. */ ++ addq %rax, %rdx ++ jz L(first_vec_x0_test) ++ /* NB: We could move this shift to before the branch and save a ++ bit of code size / performance on the fall through. The ++ branch leads to the null case which generally seems hotter ++ than char in first 3x VEC. */ ++ salq $32, %rax ++ addq %rdx, %rax ++ bsrq %rax, %rax ++ leaq 1(%rsi, %rax), %rax ++# ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++# endif ++ VZEROUPPER_RETURN + ++ .p2align 4,, 8 ++L(first_aligned_loop_return): ++ VPCMPEQ %ymm4, %ymm0, %ymm4 ++ vpmovmskb %ymm4, %edx ++ salq $32, %rcx ++ orq %rdx, %rcx ++ ++ vpmovmskb %ymm10, %eax ++ vpmovmskb %ymm6, %edx ++ salq $32, %rax ++ orq %rdx, %rax ++ blsmskq %rcx, %rcx ++ andq %rcx, %rax ++ jz L(first_vec_x1_or_x2) ++ ++ bsrq %rax, %rax ++ leaq -(VEC_SIZE * 2)(%rdi, %rax), %rax + # ifdef USE_AS_WCSRCHR +- /* Keep the first bit for each matching CHAR for bsr. */ +- andl $0x11111111, %eax ++ andq $-CHAR_SIZE, %rax + # endif +- bsrl %eax, %eax +- leaq -VEC_SIZE(%rdi, %rax), %rax +-L(return_vzeroupper): +- ZERO_UPPER_VEC_REGISTERS_RETURN ++ VZEROUPPER_RETURN + ++ /* Search char cannot be zero. */ + .p2align 4 +-L(match): +- /* Find a CHAR. Check if there is a nul CHAR. */ +- vpmovmskb %ymm2, %ecx +- testl %ecx, %ecx +- jnz L(find_nul) +- +- /* Remember the match and keep searching. */ +- movl %eax, %edx ++L(second_aligned_loop_set_furthest_match): ++ /* Save VEC and pointer from most recent match. */ ++L(second_aligned_loop_prep): + movq %rdi, %rsi +- jmp L(aligned_loop) ++ vmovdqu %ymm6, %ymm2 ++ vmovdqu %ymm10, %ymm3 + + .p2align 4 +-L(find_nul): +-# ifdef USE_AS_WCSRCHR +- /* Keep the first bit for each matching CHAR for bsr. */ +- andl $0x11111111, %ecx +- andl $0x11111111, %eax +-# endif +- /* Mask out any matching bits after the nul CHAR. */ +- movl %ecx, %r8d +- subl $1, %r8d +- xorl %ecx, %r8d +- andl %r8d, %eax ++L(second_aligned_loop): ++ /* Search 2x at at time. */ ++ vmovdqa (VEC_SIZE * 0)(%rdi), %ymm4 ++ vmovdqa (VEC_SIZE * 1)(%rdi), %ymm5 ++ ++ VPCMPEQ %ymm4, %ymm7, %ymm6 ++ VPMIN %ymm4, %ymm5, %ymm1 ++ VPCMPEQ %ymm5, %ymm7, %ymm10 ++ vpor %ymm6, %ymm10, %ymm5 ++ VPCMPEQ %ymm1, %ymm0, %ymm1 ++ vpor %ymm5, %ymm1, %ymm9 ++ ++ vpmovmskb %ymm9, %eax ++ addq $(VEC_SIZE * 2), %rdi + testl %eax, %eax +- /* If there is no CHAR here, return the remembered one. */ +- jz L(return_value) +- bsrl %eax, %eax +- leaq -VEC_SIZE(%rdi, %rax), %rax +- VZEROUPPER_RETURN +- +- .p2align 4 +-L(char_and_nul): +- /* Find both a CHAR and a nul CHAR. */ +- addq %rcx, %rdi +- movl %edx, %ecx +-L(char_and_nul_in_first_vec): +-# ifdef USE_AS_WCSRCHR +- /* Keep the first bit for each matching CHAR for bsr. */ +- andl $0x11111111, %ecx +- andl $0x11111111, %eax +-# endif +- /* Mask out any matching bits after the nul CHAR. */ +- movl %ecx, %r8d +- subl $1, %r8d +- xorl %ecx, %r8d +- andl %r8d, %eax ++ jz L(second_aligned_loop) ++ vpmovmskb %ymm1, %ecx ++ testl %ecx, %ecx ++ jz L(second_aligned_loop_set_furthest_match) ++ vpmovmskb %ymm5, %eax + testl %eax, %eax +- /* Return null pointer if the nul CHAR comes first. */ +- jz L(return_null) +- bsrl %eax, %eax +- leaq -VEC_SIZE(%rdi, %rax), %rax ++ jnz L(return_new_match) ++ ++ /* This is the hot patch. We know CHAR is inbounds and that ++ ymm3/ymm2 have latest match. */ ++ .p2align 4,, 4 ++L(return_old_match): ++ vpmovmskb %ymm3, %eax ++ vpmovmskb %ymm2, %edx ++ salq $32, %rax ++ orq %rdx, %rax ++ bsrq %rax, %rax ++ /* Search char cannot be zero so safe to just use lea for ++ wcsrchr. */ ++ leaq (VEC_SIZE * -2 -(CHAR_SIZE - 1))(%rsi, %rax), %rax + VZEROUPPER_RETURN + +- .p2align 4 +-L(return_null): +- xorl %eax, %eax ++ /* Last iteration also potentially has a match. */ ++ .p2align 4,, 8 ++L(return_new_match): ++ VPCMPEQ %ymm4, %ymm0, %ymm4 ++ vpmovmskb %ymm4, %edx ++ salq $32, %rcx ++ orq %rdx, %rcx ++ ++ vpmovmskb %ymm10, %eax ++ vpmovmskb %ymm6, %edx ++ salq $32, %rax ++ orq %rdx, %rax ++ blsmskq %rcx, %rcx ++ andq %rcx, %rax ++ jz L(return_old_match) ++ bsrq %rax, %rax ++ /* Search char cannot be zero so safe to just use lea for ++ wcsrchr. */ ++ leaq (VEC_SIZE * -2 -(CHAR_SIZE - 1))(%rdi, %rax), %rax + VZEROUPPER_RETURN + +-END (STRRCHR) ++ .p2align 4,, 4 ++L(cross_page): ++ movq %rdi, %rsi ++ andq $-VEC_SIZE, %rsi ++ vmovdqu (%rsi), %ymm1 ++ VPCMPEQ %ymm1, %ymm0, %ymm6 ++ vpmovmskb %ymm6, %ecx ++ /* Shift out zero CHAR matches that are before the begining of ++ src (rdi). */ ++ shrxl %edi, %ecx, %ecx ++ testl %ecx, %ecx ++ jz L(page_cross_continue) ++ VPCMPEQ %ymm1, %ymm7, %ymm1 ++ vpmovmskb %ymm1, %eax ++ ++ /* Shift out search CHAR matches that are before the begining of ++ src (rdi). */ ++ shrxl %edi, %eax, %eax ++ blsmskl %ecx, %ecx ++ /* Check if any search CHAR match in range. */ ++ andl %ecx, %eax ++ jz L(ret2) ++ bsrl %eax, %eax ++ addq %rdi, %rax ++# ifdef USE_AS_WCSRCHR ++ andq $-CHAR_SIZE, %rax ++# endif ++L(ret2): ++ VZEROUPPER_RETURN ++END(STRRCHR) + #endif diff --git a/SOURCES/glibc-upstream-2.34-235.patch b/SOURCES/glibc-upstream-2.34-235.patch new file mode 100644 index 0000000..c3ca959 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-235.patch @@ -0,0 +1,554 @@ +commit 596c9a32cc5d5eb82587e92d1e66c9ecb7668456 +Author: Noah Goldstein +Date: Thu Apr 21 20:52:30 2022 -0500 + + x86: Optimize {str|wcs}rchr-evex + + The new code unrolls the main loop slightly without adding too much + overhead and minimizes the comparisons for the search CHAR. + + Geometric Mean of all benchmarks New / Old: 0.755 + See email for all results. + + Full xcheck passes on x86_64 with and without multiarch enabled. + Reviewed-by: H.J. Lu + + (cherry picked from commit c966099cdc3e0fdf92f63eac09b22fa7e5f5f02d) + +diff --git a/sysdeps/x86_64/multiarch/strrchr-evex.S b/sysdeps/x86_64/multiarch/strrchr-evex.S +index f920b5a584edd293..f5b6d755ceb85ae2 100644 +--- a/sysdeps/x86_64/multiarch/strrchr-evex.S ++++ b/sysdeps/x86_64/multiarch/strrchr-evex.S +@@ -24,242 +24,351 @@ + # define STRRCHR __strrchr_evex + # endif + +-# define VMOVU vmovdqu64 +-# define VMOVA vmovdqa64 ++# define VMOVU vmovdqu64 ++# define VMOVA vmovdqa64 + + # ifdef USE_AS_WCSRCHR ++# define SHIFT_REG esi ++ ++# define kunpck kunpckbw ++# define kmov_2x kmovd ++# define maskz_2x ecx ++# define maskm_2x eax ++# define CHAR_SIZE 4 ++# define VPMIN vpminud ++# define VPTESTN vptestnmd + # define VPBROADCAST vpbroadcastd +-# define VPCMP vpcmpd +-# define SHIFT_REG r8d ++# define VPCMP vpcmpd + # else ++# define SHIFT_REG edi ++ ++# define kunpck kunpckdq ++# define kmov_2x kmovq ++# define maskz_2x rcx ++# define maskm_2x rax ++ ++# define CHAR_SIZE 1 ++# define VPMIN vpminub ++# define VPTESTN vptestnmb + # define VPBROADCAST vpbroadcastb +-# define VPCMP vpcmpb +-# define SHIFT_REG ecx ++# define VPCMP vpcmpb + # endif + + # define XMMZERO xmm16 + # define YMMZERO ymm16 + # define YMMMATCH ymm17 +-# define YMM1 ymm18 ++# define YMMSAVE ymm18 ++ ++# define YMM1 ymm19 ++# define YMM2 ymm20 ++# define YMM3 ymm21 ++# define YMM4 ymm22 ++# define YMM5 ymm23 ++# define YMM6 ymm24 ++# define YMM7 ymm25 ++# define YMM8 ymm26 + +-# define VEC_SIZE 32 + +- .section .text.evex,"ax",@progbits +-ENTRY (STRRCHR) +- movl %edi, %ecx ++# define VEC_SIZE 32 ++# define PAGE_SIZE 4096 ++ .section .text.evex, "ax", @progbits ++ENTRY(STRRCHR) ++ movl %edi, %eax + /* Broadcast CHAR to YMMMATCH. */ + VPBROADCAST %esi, %YMMMATCH + +- vpxorq %XMMZERO, %XMMZERO, %XMMZERO +- +- /* Check if we may cross page boundary with one vector load. */ +- andl $(2 * VEC_SIZE - 1), %ecx +- cmpl $VEC_SIZE, %ecx +- ja L(cros_page_boundary) ++ andl $(PAGE_SIZE - 1), %eax ++ cmpl $(PAGE_SIZE - VEC_SIZE), %eax ++ jg L(cross_page_boundary) + ++L(page_cross_continue): + VMOVU (%rdi), %YMM1 +- +- /* Each bit in K0 represents a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM1, %k0 +- /* Each bit in K1 represents a CHAR in YMM1. */ +- VPCMP $0, %YMMMATCH, %YMM1, %k1 ++ /* k0 has a 1 for each zero CHAR in YMM1. */ ++ VPTESTN %YMM1, %YMM1, %k0 + kmovd %k0, %ecx +- kmovd %k1, %eax +- +- addq $VEC_SIZE, %rdi +- +- testl %eax, %eax +- jnz L(first_vec) +- + testl %ecx, %ecx +- jnz L(return_null) +- +- andq $-VEC_SIZE, %rdi +- xorl %edx, %edx +- jmp L(aligned_loop) +- +- .p2align 4 +-L(first_vec): +- /* Check if there is a null byte. */ +- testl %ecx, %ecx +- jnz L(char_and_nul_in_first_vec) +- +- /* Remember the match and keep searching. */ +- movl %eax, %edx +- movq %rdi, %rsi +- andq $-VEC_SIZE, %rdi +- jmp L(aligned_loop) +- +- .p2align 4 +-L(cros_page_boundary): +- andl $(VEC_SIZE - 1), %ecx +- andq $-VEC_SIZE, %rdi ++ jz L(aligned_more) ++ /* fallthrough: zero CHAR in first VEC. */ + ++ /* K1 has a 1 for each search CHAR match in YMM1. */ ++ VPCMP $0, %YMMMATCH, %YMM1, %k1 ++ kmovd %k1, %eax ++ /* Build mask up until first zero CHAR (used to mask of ++ potential search CHAR matches past the end of the string). ++ */ ++ blsmskl %ecx, %ecx ++ andl %ecx, %eax ++ jz L(ret0) ++ /* Get last match (the `andl` removed any out of bounds ++ matches). */ ++ bsrl %eax, %eax + # ifdef USE_AS_WCSRCHR +- /* NB: Divide shift count by 4 since each bit in K1 represent 4 +- bytes. */ +- movl %ecx, %SHIFT_REG +- sarl $2, %SHIFT_REG ++ leaq (%rdi, %rax, CHAR_SIZE), %rax ++# else ++ addq %rdi, %rax + # endif ++L(ret0): ++ ret + +- VMOVA (%rdi), %YMM1 +- +- /* Each bit in K0 represents a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM1, %k0 +- /* Each bit in K1 represents a CHAR in YMM1. */ ++ /* Returns for first vec x1/x2/x3 have hard coded backward ++ search path for earlier matches. */ ++ .p2align 4,, 6 ++L(first_vec_x1): ++ VPCMP $0, %YMMMATCH, %YMM2, %k1 ++ kmovd %k1, %eax ++ blsmskl %ecx, %ecx ++ /* eax non-zero if search CHAR in range. */ ++ andl %ecx, %eax ++ jnz L(first_vec_x1_return) ++ ++ /* fallthrough: no match in YMM2 then need to check for earlier ++ matches (in YMM1). */ ++ .p2align 4,, 4 ++L(first_vec_x0_test): + VPCMP $0, %YMMMATCH, %YMM1, %k1 +- kmovd %k0, %edx + kmovd %k1, %eax +- +- shrxl %SHIFT_REG, %edx, %edx +- shrxl %SHIFT_REG, %eax, %eax +- addq $VEC_SIZE, %rdi +- +- /* Check if there is a CHAR. */ + testl %eax, %eax +- jnz L(found_char) +- +- testl %edx, %edx +- jnz L(return_null) +- +- jmp L(aligned_loop) +- +- .p2align 4 +-L(found_char): +- testl %edx, %edx +- jnz L(char_and_nul) +- +- /* Remember the match and keep searching. */ +- movl %eax, %edx +- leaq (%rdi, %rcx), %rsi ++ jz L(ret1) ++ bsrl %eax, %eax ++# ifdef USE_AS_WCSRCHR ++ leaq (%rsi, %rax, CHAR_SIZE), %rax ++# else ++ addq %rsi, %rax ++# endif ++L(ret1): ++ ret + +- .p2align 4 +-L(aligned_loop): +- VMOVA (%rdi), %YMM1 +- addq $VEC_SIZE, %rdi ++ .p2align 4,, 10 ++L(first_vec_x1_or_x2): ++ VPCMP $0, %YMM3, %YMMMATCH, %k3 ++ VPCMP $0, %YMM2, %YMMMATCH, %k2 ++ /* K2 and K3 have 1 for any search CHAR match. Test if any ++ matches between either of them. Otherwise check YMM1. */ ++ kortestd %k2, %k3 ++ jz L(first_vec_x0_test) ++ ++ /* Guranteed that YMM2 and YMM3 are within range so merge the ++ two bitmasks then get last result. */ ++ kunpck %k2, %k3, %k3 ++ kmovq %k3, %rax ++ bsrq %rax, %rax ++ leaq (VEC_SIZE)(%r8, %rax, CHAR_SIZE), %rax ++ ret + +- /* Each bit in K0 represents a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM1, %k0 +- /* Each bit in K1 represents a CHAR in YMM1. */ +- VPCMP $0, %YMMMATCH, %YMM1, %k1 +- kmovd %k0, %ecx ++ .p2align 4,, 6 ++L(first_vec_x3): ++ VPCMP $0, %YMMMATCH, %YMM4, %k1 + kmovd %k1, %eax +- orl %eax, %ecx +- jnz L(char_nor_null) ++ blsmskl %ecx, %ecx ++ /* If no search CHAR match in range check YMM1/YMM2/YMM3. */ ++ andl %ecx, %eax ++ jz L(first_vec_x1_or_x2) ++ bsrl %eax, %eax ++ leaq (VEC_SIZE * 3)(%rdi, %rax, CHAR_SIZE), %rax ++ ret + +- VMOVA (%rdi), %YMM1 +- add $VEC_SIZE, %rdi ++ .p2align 4,, 6 ++L(first_vec_x0_x1_test): ++ VPCMP $0, %YMMMATCH, %YMM2, %k1 ++ kmovd %k1, %eax ++ /* Check YMM2 for last match first. If no match try YMM1. */ ++ testl %eax, %eax ++ jz L(first_vec_x0_test) ++ .p2align 4,, 4 ++L(first_vec_x1_return): ++ bsrl %eax, %eax ++ leaq (VEC_SIZE)(%rdi, %rax, CHAR_SIZE), %rax ++ ret + +- /* Each bit in K0 represents a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM1, %k0 +- /* Each bit in K1 represents a CHAR in YMM1. */ +- VPCMP $0, %YMMMATCH, %YMM1, %k1 +- kmovd %k0, %ecx ++ .p2align 4,, 10 ++L(first_vec_x2): ++ VPCMP $0, %YMMMATCH, %YMM3, %k1 + kmovd %k1, %eax +- orl %eax, %ecx +- jnz L(char_nor_null) ++ blsmskl %ecx, %ecx ++ /* Check YMM3 for last match first. If no match try YMM2/YMM1. ++ */ ++ andl %ecx, %eax ++ jz L(first_vec_x0_x1_test) ++ bsrl %eax, %eax ++ leaq (VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %rax ++ ret + +- VMOVA (%rdi), %YMM1 +- addq $VEC_SIZE, %rdi + +- /* Each bit in K0 represents a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM1, %k0 +- /* Each bit in K1 represents a CHAR in YMM1. */ +- VPCMP $0, %YMMMATCH, %YMM1, %k1 ++ .p2align 4 ++L(aligned_more): ++ /* Need to keep original pointer incase YMM1 has last match. */ ++ movq %rdi, %rsi ++ andq $-VEC_SIZE, %rdi ++ VMOVU VEC_SIZE(%rdi), %YMM2 ++ VPTESTN %YMM2, %YMM2, %k0 + kmovd %k0, %ecx +- kmovd %k1, %eax +- orl %eax, %ecx +- jnz L(char_nor_null) ++ testl %ecx, %ecx ++ jnz L(first_vec_x1) + +- VMOVA (%rdi), %YMM1 +- addq $VEC_SIZE, %rdi ++ VMOVU (VEC_SIZE * 2)(%rdi), %YMM3 ++ VPTESTN %YMM3, %YMM3, %k0 ++ kmovd %k0, %ecx ++ testl %ecx, %ecx ++ jnz L(first_vec_x2) + +- /* Each bit in K0 represents a null byte in YMM1. */ +- VPCMP $0, %YMMZERO, %YMM1, %k0 +- /* Each bit in K1 represents a CHAR in YMM1. */ +- VPCMP $0, %YMMMATCH, %YMM1, %k1 ++ VMOVU (VEC_SIZE * 3)(%rdi), %YMM4 ++ VPTESTN %YMM4, %YMM4, %k0 + kmovd %k0, %ecx +- kmovd %k1, %eax +- orl %eax, %ecx +- jz L(aligned_loop) ++ movq %rdi, %r8 ++ testl %ecx, %ecx ++ jnz L(first_vec_x3) + ++ andq $-(VEC_SIZE * 2), %rdi + .p2align 4 +-L(char_nor_null): +- /* Find a CHAR or a null byte in a loop. */ ++L(first_aligned_loop): ++ /* Preserve YMM1, YMM2, YMM3, and YMM4 until we can gurantee ++ they don't store a match. */ ++ VMOVA (VEC_SIZE * 4)(%rdi), %YMM5 ++ VMOVA (VEC_SIZE * 5)(%rdi), %YMM6 ++ ++ VPCMP $0, %YMM5, %YMMMATCH, %k2 ++ vpxord %YMM6, %YMMMATCH, %YMM7 ++ ++ VPMIN %YMM5, %YMM6, %YMM8 ++ VPMIN %YMM8, %YMM7, %YMM7 ++ ++ VPTESTN %YMM7, %YMM7, %k1 ++ subq $(VEC_SIZE * -2), %rdi ++ kortestd %k1, %k2 ++ jz L(first_aligned_loop) ++ ++ VPCMP $0, %YMM6, %YMMMATCH, %k3 ++ VPTESTN %YMM8, %YMM8, %k1 ++ ktestd %k1, %k1 ++ jz L(second_aligned_loop_prep) ++ ++ kortestd %k2, %k3 ++ jnz L(return_first_aligned_loop) ++ ++ .p2align 4,, 6 ++L(first_vec_x1_or_x2_or_x3): ++ VPCMP $0, %YMM4, %YMMMATCH, %k4 ++ kmovd %k4, %eax + testl %eax, %eax +- jnz L(match) +-L(return_value): +- testl %edx, %edx +- jz L(return_null) +- movl %edx, %eax +- movq %rsi, %rdi ++ jz L(first_vec_x1_or_x2) + bsrl %eax, %eax +-# ifdef USE_AS_WCSRCHR +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- leaq -VEC_SIZE(%rdi, %rax, 4), %rax +-# else +- leaq -VEC_SIZE(%rdi, %rax), %rax +-# endif ++ leaq (VEC_SIZE * 3)(%r8, %rax, CHAR_SIZE), %rax + ret + +- .p2align 4 +-L(match): +- /* Find a CHAR. Check if there is a null byte. */ +- kmovd %k0, %ecx +- testl %ecx, %ecx +- jnz L(find_nul) ++ .p2align 4,, 8 ++L(return_first_aligned_loop): ++ VPTESTN %YMM5, %YMM5, %k0 ++ kunpck %k0, %k1, %k0 ++ kmov_2x %k0, %maskz_2x ++ ++ blsmsk %maskz_2x, %maskz_2x ++ kunpck %k2, %k3, %k3 ++ kmov_2x %k3, %maskm_2x ++ and %maskz_2x, %maskm_2x ++ jz L(first_vec_x1_or_x2_or_x3) + +- /* Remember the match and keep searching. */ +- movl %eax, %edx ++ bsr %maskm_2x, %maskm_2x ++ leaq (VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %rax ++ ret ++ ++ .p2align 4 ++ /* We can throw away the work done for the first 4x checks here ++ as we have a later match. This is the 'fast' path persay. ++ */ ++L(second_aligned_loop_prep): ++L(second_aligned_loop_set_furthest_match): + movq %rdi, %rsi +- jmp L(aligned_loop) ++ kunpck %k2, %k3, %k4 + + .p2align 4 +-L(find_nul): +- /* Mask out any matching bits after the null byte. */ +- movl %ecx, %r8d +- subl $1, %r8d +- xorl %ecx, %r8d +- andl %r8d, %eax +- testl %eax, %eax +- /* If there is no CHAR here, return the remembered one. */ +- jz L(return_value) +- bsrl %eax, %eax ++L(second_aligned_loop): ++ VMOVU (VEC_SIZE * 4)(%rdi), %YMM1 ++ VMOVU (VEC_SIZE * 5)(%rdi), %YMM2 ++ ++ VPCMP $0, %YMM1, %YMMMATCH, %k2 ++ vpxord %YMM2, %YMMMATCH, %YMM3 ++ ++ VPMIN %YMM1, %YMM2, %YMM4 ++ VPMIN %YMM3, %YMM4, %YMM3 ++ ++ VPTESTN %YMM3, %YMM3, %k1 ++ subq $(VEC_SIZE * -2), %rdi ++ kortestd %k1, %k2 ++ jz L(second_aligned_loop) ++ ++ VPCMP $0, %YMM2, %YMMMATCH, %k3 ++ VPTESTN %YMM4, %YMM4, %k1 ++ ktestd %k1, %k1 ++ jz L(second_aligned_loop_set_furthest_match) ++ ++ kortestd %k2, %k3 ++ /* branch here because there is a significant advantage interms ++ of output dependency chance in using edx. */ ++ jnz L(return_new_match) ++L(return_old_match): ++ kmovq %k4, %rax ++ bsrq %rax, %rax ++ leaq (VEC_SIZE * 2)(%rsi, %rax, CHAR_SIZE), %rax ++ ret ++ ++L(return_new_match): ++ VPTESTN %YMM1, %YMM1, %k0 ++ kunpck %k0, %k1, %k0 ++ kmov_2x %k0, %maskz_2x ++ ++ blsmsk %maskz_2x, %maskz_2x ++ kunpck %k2, %k3, %k3 ++ kmov_2x %k3, %maskm_2x ++ and %maskz_2x, %maskm_2x ++ jz L(return_old_match) ++ ++ bsr %maskm_2x, %maskm_2x ++ leaq (VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %rax ++ ret ++ ++L(cross_page_boundary): ++ /* eax contains all the page offset bits of src (rdi). `xor rdi, ++ rax` sets pointer will all page offset bits cleared so ++ offset of (PAGE_SIZE - VEC_SIZE) will get last aligned VEC ++ before page cross (guranteed to be safe to read). Doing this ++ as opposed to `movq %rdi, %rax; andq $-VEC_SIZE, %rax` saves ++ a bit of code size. */ ++ xorq %rdi, %rax ++ VMOVU (PAGE_SIZE - VEC_SIZE)(%rax), %YMM1 ++ VPTESTN %YMM1, %YMM1, %k0 ++ kmovd %k0, %ecx ++ ++ /* Shift out zero CHAR matches that are before the begining of ++ src (rdi). */ + # ifdef USE_AS_WCSRCHR +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- leaq -VEC_SIZE(%rdi, %rax, 4), %rax +-# else +- leaq -VEC_SIZE(%rdi, %rax), %rax ++ movl %edi, %esi ++ andl $(VEC_SIZE - 1), %esi ++ shrl $2, %esi + # endif +- ret ++ shrxl %SHIFT_REG, %ecx, %ecx + +- .p2align 4 +-L(char_and_nul): +- /* Find both a CHAR and a null byte. */ +- addq %rcx, %rdi +- movl %edx, %ecx +-L(char_and_nul_in_first_vec): +- /* Mask out any matching bits after the null byte. */ +- movl %ecx, %r8d +- subl $1, %r8d +- xorl %ecx, %r8d +- andl %r8d, %eax +- testl %eax, %eax +- /* Return null pointer if the null byte comes first. */ +- jz L(return_null) ++ testl %ecx, %ecx ++ jz L(page_cross_continue) ++ ++ /* Found zero CHAR so need to test for search CHAR. */ ++ VPCMP $0, %YMMMATCH, %YMM1, %k1 ++ kmovd %k1, %eax ++ /* Shift out search CHAR matches that are before the begining of ++ src (rdi). */ ++ shrxl %SHIFT_REG, %eax, %eax ++ ++ /* Check if any search CHAR match in range. */ ++ blsmskl %ecx, %ecx ++ andl %ecx, %eax ++ jz L(ret3) + bsrl %eax, %eax + # ifdef USE_AS_WCSRCHR +- /* NB: Multiply wchar_t count by 4 to get the number of bytes. */ +- leaq -VEC_SIZE(%rdi, %rax, 4), %rax ++ leaq (%rdi, %rax, CHAR_SIZE), %rax + # else +- leaq -VEC_SIZE(%rdi, %rax), %rax ++ addq %rdi, %rax + # endif ++L(ret3): + ret + +- .p2align 4 +-L(return_null): +- xorl %eax, %eax +- ret +- +-END (STRRCHR) ++END(STRRCHR) + #endif diff --git a/SOURCES/glibc-upstream-2.34-236.patch b/SOURCES/glibc-upstream-2.34-236.patch new file mode 100644 index 0000000..46f4449 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-236.patch @@ -0,0 +1,35 @@ +commit 1f83d40dfab15a6888759552f24d1b5c0907408b +Author: Florian Weimer +Date: Thu Dec 23 12:24:30 2021 +0100 + + elf: Remove unused NEED_DL_BASE_ADDR and _dl_base_addr + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit cd0c333d2ea82d0ae14719bdbef86d99615bdb00) + +diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c +index 4dc366eea445e974..1c78dc89c9cbe54d 100644 +--- a/elf/dl-sysdep.c ++++ b/elf/dl-sysdep.c +@@ -54,9 +54,6 @@ extern char _end[] attribute_hidden; + /* Protect SUID program against misuse of file descriptors. */ + extern void __libc_check_standard_fds (void); + +-#ifdef NEED_DL_BASE_ADDR +-ElfW(Addr) _dl_base_addr; +-#endif + int __libc_enable_secure attribute_relro = 0; + rtld_hidden_data_def (__libc_enable_secure) + /* This variable contains the lowest stack address ever used. */ +@@ -136,11 +133,6 @@ _dl_sysdep_start (void **start_argptr, + case AT_ENTRY: + user_entry = av->a_un.a_val; + break; +-#ifdef NEED_DL_BASE_ADDR +- case AT_BASE: +- _dl_base_addr = av->a_un.a_val; +- break; +-#endif + #ifndef HAVE_AUX_SECURE + case AT_UID: + case AT_EUID: diff --git a/SOURCES/glibc-upstream-2.34-237.patch b/SOURCES/glibc-upstream-2.34-237.patch new file mode 100644 index 0000000..1ea756f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-237.patch @@ -0,0 +1,751 @@ +commit b0bd6a1323c3eccd16c45bae359a76877fa75639 +Author: Florian Weimer +Date: Thu May 19 11:43:53 2022 +0200 + + elf: Merge dl-sysdep.c into the Linux version + + The generic version is the de-facto Linux implementation. It + requires an auxiliary vector, so Hurd does not use it. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 91c0a47ffb66e7cd802de870686465db3b3976a0) + +Conflicts: + elf/dl-sysdep.c + (missing ld.so dependency sorting optimization upstream) + +diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c +index 1c78dc89c9cbe54d..7aa90ad6eeb35cad 100644 +--- a/elf/dl-sysdep.c ++++ b/elf/dl-sysdep.c +@@ -1,5 +1,5 @@ +-/* Operating system support for run-time dynamic linker. Generic Unix version. +- Copyright (C) 1995-2021 Free Software Foundation, Inc. ++/* Operating system support for run-time dynamic linker. Stub version. ++ Copyright (C) 1995-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -16,352 +16,4 @@ + License along with the GNU C Library; if not, see + . */ + +-/* We conditionalize the whole of this file rather than simply eliding it +- from the static build, because other sysdeps/ versions of this file +- might define things needed by a static build. */ +- +-#ifdef SHARED +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include <_itoa.h> +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-extern char **_environ attribute_hidden; +-extern char _end[] attribute_hidden; +- +-/* Protect SUID program against misuse of file descriptors. */ +-extern void __libc_check_standard_fds (void); +- +-int __libc_enable_secure attribute_relro = 0; +-rtld_hidden_data_def (__libc_enable_secure) +-/* This variable contains the lowest stack address ever used. */ +-void *__libc_stack_end attribute_relro = NULL; +-rtld_hidden_data_def(__libc_stack_end) +-void *_dl_random attribute_relro = NULL; +- +-#ifndef DL_FIND_ARG_COMPONENTS +-# define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp) \ +- do { \ +- void **_tmp; \ +- (argc) = *(long int *) cookie; \ +- (argv) = (char **) ((long int *) cookie + 1); \ +- (envp) = (argv) + (argc) + 1; \ +- for (_tmp = (void **) (envp); *_tmp; ++_tmp) \ +- continue; \ +- (auxp) = (void *) ++_tmp; \ +- } while (0) +-#endif +- +-#ifndef DL_STACK_END +-# define DL_STACK_END(cookie) ((void *) (cookie)) +-#endif +- +-ElfW(Addr) +-_dl_sysdep_start (void **start_argptr, +- void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, +- ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) +-{ +- const ElfW(Phdr) *phdr = NULL; +- ElfW(Word) phnum = 0; +- ElfW(Addr) user_entry; +- ElfW(auxv_t) *av; +-#ifdef HAVE_AUX_SECURE +-# define set_seen(tag) (tag) /* Evaluate for the side effects. */ +-# define set_seen_secure() ((void) 0) +-#else +- uid_t uid = 0; +- gid_t gid = 0; +- unsigned int seen = 0; +-# define set_seen_secure() (seen = -1) +-# ifdef HAVE_AUX_XID +-# define set_seen(tag) (tag) /* Evaluate for the side effects. */ +-# else +-# define M(type) (1 << (type)) +-# define set_seen(tag) seen |= M ((tag)->a_type) +-# endif +-#endif +-#ifdef NEED_DL_SYSINFO +- uintptr_t new_sysinfo = 0; +-#endif +- +- __libc_stack_end = DL_STACK_END (start_argptr); +- DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, _dl_argv, _environ, +- GLRO(dl_auxv)); +- +- user_entry = (ElfW(Addr)) ENTRY_POINT; +- GLRO(dl_platform) = NULL; /* Default to nothing known about the platform. */ +- +- /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ +- _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), +- "CONSTANT_MINSIGSTKSZ is constant"); +- GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ; +- +- for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++)) +- switch (av->a_type) +- { +- case AT_PHDR: +- phdr = (void *) av->a_un.a_val; +- break; +- case AT_PHNUM: +- phnum = av->a_un.a_val; +- break; +- case AT_PAGESZ: +- GLRO(dl_pagesize) = av->a_un.a_val; +- break; +- case AT_ENTRY: +- user_entry = av->a_un.a_val; +- break; +-#ifndef HAVE_AUX_SECURE +- case AT_UID: +- case AT_EUID: +- uid ^= av->a_un.a_val; +- break; +- case AT_GID: +- case AT_EGID: +- gid ^= av->a_un.a_val; +- break; +-#endif +- case AT_SECURE: +-#ifndef HAVE_AUX_SECURE +- seen = -1; +-#endif +- __libc_enable_secure = av->a_un.a_val; +- break; +- case AT_PLATFORM: +- GLRO(dl_platform) = (void *) av->a_un.a_val; +- break; +- case AT_HWCAP: +- GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_HWCAP2: +- GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_CLKTCK: +- GLRO(dl_clktck) = av->a_un.a_val; +- break; +- case AT_FPUCW: +- GLRO(dl_fpu_control) = av->a_un.a_val; +- break; +-#ifdef NEED_DL_SYSINFO +- case AT_SYSINFO: +- new_sysinfo = av->a_un.a_val; +- break; +-#endif +-#ifdef NEED_DL_SYSINFO_DSO +- case AT_SYSINFO_EHDR: +- GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val; +- break; +-#endif +- case AT_RANDOM: +- _dl_random = (void *) av->a_un.a_val; +- break; +- case AT_MINSIGSTKSZ: +- GLRO(dl_minsigstacksize) = av->a_un.a_val; +- break; +- DL_PLATFORM_AUXV +- } +- +- dl_hwcap_check (); +- +-#ifndef HAVE_AUX_SECURE +- if (seen != -1) +- { +- /* Fill in the values we have not gotten from the kernel through the +- auxiliary vector. */ +-# ifndef HAVE_AUX_XID +-# define SEE(UID, var, uid) \ +- if ((seen & M (AT_##UID)) == 0) var ^= __get##uid () +- SEE (UID, uid, uid); +- SEE (EUID, uid, euid); +- SEE (GID, gid, gid); +- SEE (EGID, gid, egid); +-# endif +- +- /* If one of the two pairs of IDs does not match this is a setuid +- or setgid run. */ +- __libc_enable_secure = uid | gid; +- } +-#endif +- +-#ifndef HAVE_AUX_PAGESIZE +- if (GLRO(dl_pagesize) == 0) +- GLRO(dl_pagesize) = __getpagesize (); +-#endif +- +-#ifdef NEED_DL_SYSINFO +- if (new_sysinfo != 0) +- { +-# ifdef NEED_DL_SYSINFO_DSO +- /* Only set the sysinfo value if we also have the vsyscall DSO. */ +- if (GLRO(dl_sysinfo_dso) != 0) +-# endif +- GLRO(dl_sysinfo) = new_sysinfo; +- } +-#endif +- +- __tunables_init (_environ); +- +- /* Initialize DSO sorting algorithm after tunables. */ +- _dl_sort_maps_init (); +- +-#ifdef DL_SYSDEP_INIT +- DL_SYSDEP_INIT; +-#endif +- +-#ifdef DL_PLATFORM_INIT +- DL_PLATFORM_INIT; +-#endif +- +- /* Determine the length of the platform name. */ +- if (GLRO(dl_platform) != NULL) +- GLRO(dl_platformlen) = strlen (GLRO(dl_platform)); +- +- if (__sbrk (0) == _end) +- /* The dynamic linker was run as a program, and so the initial break +- starts just after our bss, at &_end. The malloc in dl-minimal.c +- will consume the rest of this page, so tell the kernel to move the +- break up that far. When the user program examines its break, it +- will see this new value and not clobber our data. */ +- __sbrk (GLRO(dl_pagesize) +- - ((_end - (char *) 0) & (GLRO(dl_pagesize) - 1))); +- +- /* If this is a SUID program we make sure that FDs 0, 1, and 2 are +- allocated. If necessary we are doing it ourself. If it is not +- possible we stop the program. */ +- if (__builtin_expect (__libc_enable_secure, 0)) +- __libc_check_standard_fds (); +- +- (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv)); +- return user_entry; +-} +- +-void +-_dl_sysdep_start_cleanup (void) +-{ +-} +- +-void +-_dl_show_auxv (void) +-{ +- char buf[64]; +- ElfW(auxv_t) *av; +- +- /* Terminate string. */ +- buf[63] = '\0'; +- +- /* The following code assumes that the AT_* values are encoded +- starting from 0 with AT_NULL, 1 for AT_IGNORE, and all other values +- close by (otherwise the array will be too large). In case we have +- to support a platform where these requirements are not fulfilled +- some alternative implementation has to be used. */ +- for (av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av) +- { +- static const struct +- { +- const char label[22]; +- enum { unknown = 0, dec, hex, str, ignore } form : 8; +- } auxvars[] = +- { +- [AT_EXECFD - 2] = { "EXECFD: ", dec }, +- [AT_EXECFN - 2] = { "EXECFN: ", str }, +- [AT_PHDR - 2] = { "PHDR: 0x", hex }, +- [AT_PHENT - 2] = { "PHENT: ", dec }, +- [AT_PHNUM - 2] = { "PHNUM: ", dec }, +- [AT_PAGESZ - 2] = { "PAGESZ: ", dec }, +- [AT_BASE - 2] = { "BASE: 0x", hex }, +- [AT_FLAGS - 2] = { "FLAGS: 0x", hex }, +- [AT_ENTRY - 2] = { "ENTRY: 0x", hex }, +- [AT_NOTELF - 2] = { "NOTELF: ", hex }, +- [AT_UID - 2] = { "UID: ", dec }, +- [AT_EUID - 2] = { "EUID: ", dec }, +- [AT_GID - 2] = { "GID: ", dec }, +- [AT_EGID - 2] = { "EGID: ", dec }, +- [AT_PLATFORM - 2] = { "PLATFORM: ", str }, +- [AT_HWCAP - 2] = { "HWCAP: ", hex }, +- [AT_CLKTCK - 2] = { "CLKTCK: ", dec }, +- [AT_FPUCW - 2] = { "FPUCW: ", hex }, +- [AT_DCACHEBSIZE - 2] = { "DCACHEBSIZE: 0x", hex }, +- [AT_ICACHEBSIZE - 2] = { "ICACHEBSIZE: 0x", hex }, +- [AT_UCACHEBSIZE - 2] = { "UCACHEBSIZE: 0x", hex }, +- [AT_IGNOREPPC - 2] = { "IGNOREPPC", ignore }, +- [AT_SECURE - 2] = { "SECURE: ", dec }, +- [AT_BASE_PLATFORM - 2] = { "BASE_PLATFORM: ", str }, +- [AT_SYSINFO - 2] = { "SYSINFO: 0x", hex }, +- [AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex }, +- [AT_RANDOM - 2] = { "RANDOM: 0x", hex }, +- [AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex }, +- [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ: ", dec }, +- [AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec }, +- [AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex }, +- [AT_L1D_CACHESIZE - 2] = { "L1D_CACHESIZE: ", dec }, +- [AT_L1D_CACHEGEOMETRY - 2] = { "L1D_CACHEGEOMETRY: 0x", hex }, +- [AT_L2_CACHESIZE - 2] = { "L2_CACHESIZE: ", dec }, +- [AT_L2_CACHEGEOMETRY - 2] = { "L2_CACHEGEOMETRY: 0x", hex }, +- [AT_L3_CACHESIZE - 2] = { "L3_CACHESIZE: ", dec }, +- [AT_L3_CACHEGEOMETRY - 2] = { "L3_CACHEGEOMETRY: 0x", hex }, +- }; +- unsigned int idx = (unsigned int) (av->a_type - 2); +- +- if ((unsigned int) av->a_type < 2u +- || (idx < sizeof (auxvars) / sizeof (auxvars[0]) +- && auxvars[idx].form == ignore)) +- continue; +- +- assert (AT_NULL == 0); +- assert (AT_IGNORE == 1); +- +- /* Some entries are handled in a special way per platform. */ +- if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0) +- continue; +- +- if (idx < sizeof (auxvars) / sizeof (auxvars[0]) +- && auxvars[idx].form != unknown) +- { +- const char *val = (char *) av->a_un.a_val; +- +- if (__builtin_expect (auxvars[idx].form, dec) == dec) +- val = _itoa ((unsigned long int) av->a_un.a_val, +- buf + sizeof buf - 1, 10, 0); +- else if (__builtin_expect (auxvars[idx].form, hex) == hex) +- val = _itoa ((unsigned long int) av->a_un.a_val, +- buf + sizeof buf - 1, 16, 0); +- +- _dl_printf ("AT_%s%s\n", auxvars[idx].label, val); +- +- continue; +- } +- +- /* Unknown value: print a generic line. */ +- char buf2[17]; +- buf2[sizeof (buf2) - 1] = '\0'; +- const char *val2 = _itoa ((unsigned long int) av->a_un.a_val, +- buf2 + sizeof buf2 - 1, 16, 0); +- const char *val = _itoa ((unsigned long int) av->a_type, +- buf + sizeof buf - 1, 16, 0); +- _dl_printf ("AT_??? (0x%s): 0x%s\n", val, val2); +- } +-} +- +-#endif ++#error dl-sysdep support missing. +diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c +index 144dc5ce5a1bba17..3e41469bcc395179 100644 +--- a/sysdeps/unix/sysv/linux/dl-sysdep.c ++++ b/sysdeps/unix/sysv/linux/dl-sysdep.c +@@ -16,29 +16,352 @@ + License along with the GNU C Library; if not, see + . */ + +-/* Linux needs some special initialization, but otherwise uses +- the generic dynamic linker system interface code. */ +- +-#include ++#include <_itoa.h> ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + #include +-#include +-#include +-#include ++#include + #include ++#include ++#include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include + + #ifdef SHARED +-# define DL_SYSDEP_INIT frob_brk () ++extern char **_environ attribute_hidden; ++extern char _end[] attribute_hidden; ++ ++/* Protect SUID program against misuse of file descriptors. */ ++extern void __libc_check_standard_fds (void); + +-static inline void +-frob_brk (void) ++int __libc_enable_secure attribute_relro = 0; ++rtld_hidden_data_def (__libc_enable_secure) ++/* This variable contains the lowest stack address ever used. */ ++void *__libc_stack_end attribute_relro = NULL; ++rtld_hidden_data_def(__libc_stack_end) ++void *_dl_random attribute_relro = NULL; ++ ++#ifndef DL_FIND_ARG_COMPONENTS ++# define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp) \ ++ do { \ ++ void **_tmp; \ ++ (argc) = *(long int *) cookie; \ ++ (argv) = (char **) ((long int *) cookie + 1); \ ++ (envp) = (argv) + (argc) + 1; \ ++ for (_tmp = (void **) (envp); *_tmp; ++_tmp) \ ++ continue; \ ++ (auxp) = (void *) ++_tmp; \ ++ } while (0) ++#endif ++ ++#ifndef DL_STACK_END ++# define DL_STACK_END(cookie) ((void *) (cookie)) ++#endif ++ ++ElfW(Addr) ++_dl_sysdep_start (void **start_argptr, ++ void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, ++ ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) + { ++ const ElfW(Phdr) *phdr = NULL; ++ ElfW(Word) phnum = 0; ++ ElfW(Addr) user_entry; ++ ElfW(auxv_t) *av; ++#ifdef HAVE_AUX_SECURE ++# define set_seen(tag) (tag) /* Evaluate for the side effects. */ ++# define set_seen_secure() ((void) 0) ++#else ++ uid_t uid = 0; ++ gid_t gid = 0; ++ unsigned int seen = 0; ++# define set_seen_secure() (seen = -1) ++# ifdef HAVE_AUX_XID ++# define set_seen(tag) (tag) /* Evaluate for the side effects. */ ++# else ++# define M(type) (1 << (type)) ++# define set_seen(tag) seen |= M ((tag)->a_type) ++# endif ++#endif ++#ifdef NEED_DL_SYSINFO ++ uintptr_t new_sysinfo = 0; ++#endif ++ ++ __libc_stack_end = DL_STACK_END (start_argptr); ++ DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, _dl_argv, _environ, ++ GLRO(dl_auxv)); ++ ++ user_entry = (ElfW(Addr)) ENTRY_POINT; ++ GLRO(dl_platform) = NULL; /* Default to nothing known about the platform. */ ++ ++ /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ ++ _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), ++ "CONSTANT_MINSIGSTKSZ is constant"); ++ GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ; ++ ++ for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++)) ++ switch (av->a_type) ++ { ++ case AT_PHDR: ++ phdr = (void *) av->a_un.a_val; ++ break; ++ case AT_PHNUM: ++ phnum = av->a_un.a_val; ++ break; ++ case AT_PAGESZ: ++ GLRO(dl_pagesize) = av->a_un.a_val; ++ break; ++ case AT_ENTRY: ++ user_entry = av->a_un.a_val; ++ break; ++#ifndef HAVE_AUX_SECURE ++ case AT_UID: ++ case AT_EUID: ++ uid ^= av->a_un.a_val; ++ break; ++ case AT_GID: ++ case AT_EGID: ++ gid ^= av->a_un.a_val; ++ break; ++#endif ++ case AT_SECURE: ++#ifndef HAVE_AUX_SECURE ++ seen = -1; ++#endif ++ __libc_enable_secure = av->a_un.a_val; ++ break; ++ case AT_PLATFORM: ++ GLRO(dl_platform) = (void *) av->a_un.a_val; ++ break; ++ case AT_HWCAP: ++ GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; ++ break; ++ case AT_HWCAP2: ++ GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; ++ break; ++ case AT_CLKTCK: ++ GLRO(dl_clktck) = av->a_un.a_val; ++ break; ++ case AT_FPUCW: ++ GLRO(dl_fpu_control) = av->a_un.a_val; ++ break; ++#ifdef NEED_DL_SYSINFO ++ case AT_SYSINFO: ++ new_sysinfo = av->a_un.a_val; ++ break; ++#endif ++#ifdef NEED_DL_SYSINFO_DSO ++ case AT_SYSINFO_EHDR: ++ GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val; ++ break; ++#endif ++ case AT_RANDOM: ++ _dl_random = (void *) av->a_un.a_val; ++ break; ++ case AT_MINSIGSTKSZ: ++ GLRO(dl_minsigstacksize) = av->a_un.a_val; ++ break; ++ DL_PLATFORM_AUXV ++ } ++ ++ dl_hwcap_check (); ++ ++#ifndef HAVE_AUX_SECURE ++ if (seen != -1) ++ { ++ /* Fill in the values we have not gotten from the kernel through the ++ auxiliary vector. */ ++# ifndef HAVE_AUX_XID ++# define SEE(UID, var, uid) \ ++ if ((seen & M (AT_##UID)) == 0) var ^= __get##uid () ++ SEE (UID, uid, uid); ++ SEE (EUID, uid, euid); ++ SEE (GID, gid, gid); ++ SEE (EGID, gid, egid); ++# endif ++ ++ /* If one of the two pairs of IDs does not match this is a setuid ++ or setgid run. */ ++ __libc_enable_secure = uid | gid; ++ } ++#endif ++ ++#ifndef HAVE_AUX_PAGESIZE ++ if (GLRO(dl_pagesize) == 0) ++ GLRO(dl_pagesize) = __getpagesize (); ++#endif ++ ++#ifdef NEED_DL_SYSINFO ++ if (new_sysinfo != 0) ++ { ++# ifdef NEED_DL_SYSINFO_DSO ++ /* Only set the sysinfo value if we also have the vsyscall DSO. */ ++ if (GLRO(dl_sysinfo_dso) != 0) ++# endif ++ GLRO(dl_sysinfo) = new_sysinfo; ++ } ++#endif ++ ++ __tunables_init (_environ); ++ ++ /* Initialize DSO sorting algorithm after tunables. */ ++ _dl_sort_maps_init (); ++ + __brk (0); /* Initialize the break. */ +-} + +-# include ++#ifdef DL_PLATFORM_INIT ++ DL_PLATFORM_INIT; + #endif + ++ /* Determine the length of the platform name. */ ++ if (GLRO(dl_platform) != NULL) ++ GLRO(dl_platformlen) = strlen (GLRO(dl_platform)); ++ ++ if (__sbrk (0) == _end) ++ /* The dynamic linker was run as a program, and so the initial break ++ starts just after our bss, at &_end. The malloc in dl-minimal.c ++ will consume the rest of this page, so tell the kernel to move the ++ break up that far. When the user program examines its break, it ++ will see this new value and not clobber our data. */ ++ __sbrk (GLRO(dl_pagesize) ++ - ((_end - (char *) 0) & (GLRO(dl_pagesize) - 1))); ++ ++ /* If this is a SUID program we make sure that FDs 0, 1, and 2 are ++ allocated. If necessary we are doing it ourself. If it is not ++ possible we stop the program. */ ++ if (__builtin_expect (__libc_enable_secure, 0)) ++ __libc_check_standard_fds (); ++ ++ (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv)); ++ return user_entry; ++} ++ ++void ++_dl_sysdep_start_cleanup (void) ++{ ++} ++ ++void ++_dl_show_auxv (void) ++{ ++ char buf[64]; ++ ElfW(auxv_t) *av; ++ ++ /* Terminate string. */ ++ buf[63] = '\0'; ++ ++ /* The following code assumes that the AT_* values are encoded ++ starting from 0 with AT_NULL, 1 for AT_IGNORE, and all other values ++ close by (otherwise the array will be too large). In case we have ++ to support a platform where these requirements are not fulfilled ++ some alternative implementation has to be used. */ ++ for (av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av) ++ { ++ static const struct ++ { ++ const char label[22]; ++ enum { unknown = 0, dec, hex, str, ignore } form : 8; ++ } auxvars[] = ++ { ++ [AT_EXECFD - 2] = { "EXECFD: ", dec }, ++ [AT_EXECFN - 2] = { "EXECFN: ", str }, ++ [AT_PHDR - 2] = { "PHDR: 0x", hex }, ++ [AT_PHENT - 2] = { "PHENT: ", dec }, ++ [AT_PHNUM - 2] = { "PHNUM: ", dec }, ++ [AT_PAGESZ - 2] = { "PAGESZ: ", dec }, ++ [AT_BASE - 2] = { "BASE: 0x", hex }, ++ [AT_FLAGS - 2] = { "FLAGS: 0x", hex }, ++ [AT_ENTRY - 2] = { "ENTRY: 0x", hex }, ++ [AT_NOTELF - 2] = { "NOTELF: ", hex }, ++ [AT_UID - 2] = { "UID: ", dec }, ++ [AT_EUID - 2] = { "EUID: ", dec }, ++ [AT_GID - 2] = { "GID: ", dec }, ++ [AT_EGID - 2] = { "EGID: ", dec }, ++ [AT_PLATFORM - 2] = { "PLATFORM: ", str }, ++ [AT_HWCAP - 2] = { "HWCAP: ", hex }, ++ [AT_CLKTCK - 2] = { "CLKTCK: ", dec }, ++ [AT_FPUCW - 2] = { "FPUCW: ", hex }, ++ [AT_DCACHEBSIZE - 2] = { "DCACHEBSIZE: 0x", hex }, ++ [AT_ICACHEBSIZE - 2] = { "ICACHEBSIZE: 0x", hex }, ++ [AT_UCACHEBSIZE - 2] = { "UCACHEBSIZE: 0x", hex }, ++ [AT_IGNOREPPC - 2] = { "IGNOREPPC", ignore }, ++ [AT_SECURE - 2] = { "SECURE: ", dec }, ++ [AT_BASE_PLATFORM - 2] = { "BASE_PLATFORM: ", str }, ++ [AT_SYSINFO - 2] = { "SYSINFO: 0x", hex }, ++ [AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex }, ++ [AT_RANDOM - 2] = { "RANDOM: 0x", hex }, ++ [AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex }, ++ [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ: ", dec }, ++ [AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec }, ++ [AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex }, ++ [AT_L1D_CACHESIZE - 2] = { "L1D_CACHESIZE: ", dec }, ++ [AT_L1D_CACHEGEOMETRY - 2] = { "L1D_CACHEGEOMETRY: 0x", hex }, ++ [AT_L2_CACHESIZE - 2] = { "L2_CACHESIZE: ", dec }, ++ [AT_L2_CACHEGEOMETRY - 2] = { "L2_CACHEGEOMETRY: 0x", hex }, ++ [AT_L3_CACHESIZE - 2] = { "L3_CACHESIZE: ", dec }, ++ [AT_L3_CACHEGEOMETRY - 2] = { "L3_CACHEGEOMETRY: 0x", hex }, ++ }; ++ unsigned int idx = (unsigned int) (av->a_type - 2); ++ ++ if ((unsigned int) av->a_type < 2u ++ || (idx < sizeof (auxvars) / sizeof (auxvars[0]) ++ && auxvars[idx].form == ignore)) ++ continue; ++ ++ assert (AT_NULL == 0); ++ assert (AT_IGNORE == 1); ++ ++ /* Some entries are handled in a special way per platform. */ ++ if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0) ++ continue; ++ ++ if (idx < sizeof (auxvars) / sizeof (auxvars[0]) ++ && auxvars[idx].form != unknown) ++ { ++ const char *val = (char *) av->a_un.a_val; ++ ++ if (__builtin_expect (auxvars[idx].form, dec) == dec) ++ val = _itoa ((unsigned long int) av->a_un.a_val, ++ buf + sizeof buf - 1, 10, 0); ++ else if (__builtin_expect (auxvars[idx].form, hex) == hex) ++ val = _itoa ((unsigned long int) av->a_un.a_val, ++ buf + sizeof buf - 1, 16, 0); ++ ++ _dl_printf ("AT_%s%s\n", auxvars[idx].label, val); ++ ++ continue; ++ } ++ ++ /* Unknown value: print a generic line. */ ++ char buf2[17]; ++ buf2[sizeof (buf2) - 1] = '\0'; ++ const char *val2 = _itoa ((unsigned long int) av->a_un.a_val, ++ buf2 + sizeof buf2 - 1, 16, 0); ++ const char *val = _itoa ((unsigned long int) av->a_type, ++ buf + sizeof buf - 1, 16, 0); ++ _dl_printf ("AT_??? (0x%s): 0x%s\n", val, val2); ++ } ++} ++ ++#endif /* SHARED */ ++ + + int + attribute_hidden diff --git a/SOURCES/glibc-upstream-2.34-238.patch b/SOURCES/glibc-upstream-2.34-238.patch new file mode 100644 index 0000000..4d07a8a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-238.patch @@ -0,0 +1,120 @@ +commit 2139b1848e3e0a960ccc615fe1fd78b5d10b1411 +Author: Florian Weimer +Date: Thu Feb 3 10:58:59 2022 +0100 + + Linux: Remove HAVE_AUX_SECURE, HAVE_AUX_XID, HAVE_AUX_PAGESIZE + + They are always defined. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit b9c3d3382f6f50e9723002deb2dc8127de720fa6) + +diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c +index 3e41469bcc395179..aae983777ba15fae 100644 +--- a/sysdeps/unix/sysv/linux/dl-sysdep.c ++++ b/sysdeps/unix/sysv/linux/dl-sysdep.c +@@ -85,21 +85,6 @@ _dl_sysdep_start (void **start_argptr, + ElfW(Word) phnum = 0; + ElfW(Addr) user_entry; + ElfW(auxv_t) *av; +-#ifdef HAVE_AUX_SECURE +-# define set_seen(tag) (tag) /* Evaluate for the side effects. */ +-# define set_seen_secure() ((void) 0) +-#else +- uid_t uid = 0; +- gid_t gid = 0; +- unsigned int seen = 0; +-# define set_seen_secure() (seen = -1) +-# ifdef HAVE_AUX_XID +-# define set_seen(tag) (tag) /* Evaluate for the side effects. */ +-# else +-# define M(type) (1 << (type)) +-# define set_seen(tag) seen |= M ((tag)->a_type) +-# endif +-#endif + #ifdef NEED_DL_SYSINFO + uintptr_t new_sysinfo = 0; + #endif +@@ -116,7 +101,7 @@ _dl_sysdep_start (void **start_argptr, + "CONSTANT_MINSIGSTKSZ is constant"); + GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ; + +- for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++)) ++ for (av = GLRO(dl_auxv); av->a_type != AT_NULL; av++) + switch (av->a_type) + { + case AT_PHDR: +@@ -131,20 +116,7 @@ _dl_sysdep_start (void **start_argptr, + case AT_ENTRY: + user_entry = av->a_un.a_val; + break; +-#ifndef HAVE_AUX_SECURE +- case AT_UID: +- case AT_EUID: +- uid ^= av->a_un.a_val; +- break; +- case AT_GID: +- case AT_EGID: +- gid ^= av->a_un.a_val; +- break; +-#endif + case AT_SECURE: +-#ifndef HAVE_AUX_SECURE +- seen = -1; +-#endif + __libc_enable_secure = av->a_un.a_val; + break; + case AT_PLATFORM: +@@ -183,31 +155,6 @@ _dl_sysdep_start (void **start_argptr, + + dl_hwcap_check (); + +-#ifndef HAVE_AUX_SECURE +- if (seen != -1) +- { +- /* Fill in the values we have not gotten from the kernel through the +- auxiliary vector. */ +-# ifndef HAVE_AUX_XID +-# define SEE(UID, var, uid) \ +- if ((seen & M (AT_##UID)) == 0) var ^= __get##uid () +- SEE (UID, uid, uid); +- SEE (EUID, uid, euid); +- SEE (GID, gid, gid); +- SEE (EGID, gid, egid); +-# endif +- +- /* If one of the two pairs of IDs does not match this is a setuid +- or setgid run. */ +- __libc_enable_secure = uid | gid; +- } +-#endif +- +-#ifndef HAVE_AUX_PAGESIZE +- if (GLRO(dl_pagesize) == 0) +- GLRO(dl_pagesize) = __getpagesize (); +-#endif +- + #ifdef NEED_DL_SYSINFO + if (new_sysinfo != 0) + { +diff --git a/sysdeps/unix/sysv/linux/ldsodefs.h b/sysdeps/unix/sysv/linux/ldsodefs.h +index 7e01f685b03b984d..0f152c592c2a9b04 100644 +--- a/sysdeps/unix/sysv/linux/ldsodefs.h ++++ b/sysdeps/unix/sysv/linux/ldsodefs.h +@@ -24,16 +24,4 @@ + /* Get the real definitions. */ + #include_next + +-/* We can assume that the kernel always provides the AT_UID, AT_EUID, +- AT_GID, and AT_EGID values in the auxiliary vector from 2.4.0 or so on. */ +-#define HAVE_AUX_XID +- +-/* We can assume that the kernel always provides the AT_SECURE value +- in the auxiliary vector from 2.5.74 or so on. */ +-#define HAVE_AUX_SECURE +- +-/* Starting with one of the 2.4.0 pre-releases the Linux kernel passes +- up the page size information. */ +-#define HAVE_AUX_PAGESIZE +- + #endif /* ldsodefs.h */ diff --git a/SOURCES/glibc-upstream-2.34-239.patch b/SOURCES/glibc-upstream-2.34-239.patch new file mode 100644 index 0000000..ef06d23 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-239.patch @@ -0,0 +1,55 @@ +commit 458733fffe2c410418b5f633ffd6ed65efd2aac0 +Author: Florian Weimer +Date: Thu Feb 3 10:58:59 2022 +0100 + + Linux: Remove DL_FIND_ARG_COMPONENTS + + The generic definition is always used since the Native Client + port has been removed. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 2d47fa68628e831a692cba8fc9050cef435afc5e) + +diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c +index aae983777ba15fae..e36b3e6b63b1aa7e 100644 +--- a/sysdeps/unix/sysv/linux/dl-sysdep.c ++++ b/sysdeps/unix/sysv/linux/dl-sysdep.c +@@ -59,19 +59,6 @@ void *__libc_stack_end attribute_relro = NULL; + rtld_hidden_data_def(__libc_stack_end) + void *_dl_random attribute_relro = NULL; + +-#ifndef DL_FIND_ARG_COMPONENTS +-# define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp) \ +- do { \ +- void **_tmp; \ +- (argc) = *(long int *) cookie; \ +- (argv) = (char **) ((long int *) cookie + 1); \ +- (envp) = (argv) + (argc) + 1; \ +- for (_tmp = (void **) (envp); *_tmp; ++_tmp) \ +- continue; \ +- (auxp) = (void *) ++_tmp; \ +- } while (0) +-#endif +- + #ifndef DL_STACK_END + # define DL_STACK_END(cookie) ((void *) (cookie)) + #endif +@@ -90,8 +77,16 @@ _dl_sysdep_start (void **start_argptr, + #endif + + __libc_stack_end = DL_STACK_END (start_argptr); +- DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, _dl_argv, _environ, +- GLRO(dl_auxv)); ++ _dl_argc = (intptr_t) *start_argptr; ++ _dl_argv = (char **) (start_argptr + 1); /* Necessary aliasing violation. */ ++ _environ = _dl_argv + _dl_argc + 1; ++ for (char **tmp = _environ + 1; ; ++tmp) ++ if (*tmp == NULL) ++ { ++ /* Another necessary aliasing violation. */ ++ GLRO(dl_auxv) = (ElfW(auxv_t) *) (tmp + 1); ++ break; ++ } + + user_entry = (ElfW(Addr)) ENTRY_POINT; + GLRO(dl_platform) = NULL; /* Default to nothing known about the platform. */ diff --git a/SOURCES/glibc-upstream-2.34-24.patch b/SOURCES/glibc-upstream-2.34-24.patch new file mode 100644 index 0000000..4c4a4c0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-24.patch @@ -0,0 +1,355 @@ +commit 5ad589d63bc2d9b1fc3d9f32144acaebb85e0803 +Author: Adhemerval Zanella +Date: Tue Aug 24 16:12:24 2021 -0300 + + support: Add support_open_dev_null_range + + It returns a range of file descriptor referring to the '/dev/null' + pathname. The function takes care of restarting the open range + if a file descriptor is found within the specified range and + also increases RLIMIT_NOFILE if required. + + Checked on x86_64-linux-gnu. + + (cherry picked from commit e814f4b04ee413a7bb3dfa43e74c8fb4abf58359) + +diff --git a/support/Makefile b/support/Makefile +index ef2b1a980a407f8f..2a0731796fdb3f2d 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -66,6 +66,7 @@ libsupport-routines = \ + support_path_support_time64 \ + support_process_state \ + support_ptrace \ ++ support-open-dev-null-range \ + support_openpty \ + support_paths \ + support_quote_blob \ +@@ -265,6 +266,7 @@ tests = \ + tst-support_capture_subprocess \ + tst-support_descriptors \ + tst-support_format_dns_packet \ ++ tst-support-open-dev-null-range \ + tst-support-process_state \ + tst-support_quote_blob \ + tst-support_quote_string \ +diff --git a/support/support-open-dev-null-range.c b/support/support-open-dev-null-range.c +new file mode 100644 +index 0000000000000000..80d9dba50402ce12 +--- /dev/null ++++ b/support/support-open-dev-null-range.c +@@ -0,0 +1,134 @@ ++/* Return a range of open file descriptors. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++increase_nofile (void) ++{ ++ struct rlimit rl; ++ if (getrlimit (RLIMIT_NOFILE, &rl) == -1) ++ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m"); ++ ++ rl.rlim_cur += 128; ++ ++ if (setrlimit (RLIMIT_NOFILE, &rl) == 1) ++ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m"); ++} ++ ++static int ++open_dev_null (int flags, mode_t mode) ++{ ++ int fd = open64 ("/dev/null", flags, mode); ++ if (fd > 0) ++ return fd; ++ ++ if (fd < 0 && errno != EMFILE) ++ FAIL_EXIT1 ("open64 (\"/dev/null\", 0x%x, 0%o): %m", flags, mode); ++ ++ increase_nofile (); ++ ++ return xopen ("/dev/null", flags, mode); ++} ++ ++struct range ++{ ++ int lowfd; ++ size_t len; ++}; ++ ++struct range_list ++{ ++ size_t total; ++ size_t used; ++ struct range *ranges; ++}; ++ ++static void ++range_init (struct range_list *r) ++{ ++ r->total = 8; ++ r->used = 0; ++ r->ranges = xmalloc (r->total * sizeof (struct range)); ++} ++ ++static void ++range_add (struct range_list *r, int lowfd, size_t len) ++{ ++ if (r->used == r->total) ++ { ++ r->total *= 2; ++ r->ranges = xrealloc (r->ranges, r->total * sizeof (struct range)); ++ } ++ r->ranges[r->used].lowfd = lowfd; ++ r->ranges[r->used].len = len; ++ r->used++; ++} ++ ++static void ++range_close (struct range_list *r) ++{ ++ for (size_t i = 0; i < r->used; i++) ++ { ++ int minfd = r->ranges[i].lowfd; ++ int maxfd = r->ranges[i].lowfd + r->ranges[i].len; ++ for (int fd = minfd; fd < maxfd; fd++) ++ xclose (fd); ++ } ++ free (r->ranges); ++} ++ ++int ++support_open_dev_null_range (int num, int flags, mode_t mode) ++{ ++ /* We keep track of the ranges that hit an already opened descriptor, so ++ we close them after we get a working range. */ ++ struct range_list rl; ++ range_init (&rl); ++ ++ int lowfd = open_dev_null (flags, mode); ++ int prevfd = lowfd; ++ while (true) ++ { ++ int i = 1; ++ for (; i < num; i++) ++ { ++ int fd = open_dev_null (flags, mode); ++ if (fd != lowfd + i) ++ { ++ range_add (&rl, lowfd, prevfd - lowfd + 1); ++ ++ prevfd = lowfd = fd; ++ break; ++ } ++ prevfd = fd; ++ } ++ if (i == num) ++ break; ++ } ++ ++ range_close (&rl); ++ ++ return lowfd; ++} +diff --git a/support/support.h b/support/support.h +index a5978b939af2fb41..c219e0d9d1aef046 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -197,6 +197,14 @@ struct support_stack support_stack_alloc (size_t size); + /* Deallocate the STACK. */ + void support_stack_free (struct support_stack *stack); + ++ ++/* Create a range of NUM opened '/dev/null' file descriptors using FLAGS and ++ MODE. The function takes care of restarting the open range if a file ++ descriptor is found within the specified range and also increases ++ RLIMIT_NOFILE if required. ++ The returned value is the lowest file descriptor number. */ ++int support_open_dev_null_range (int num, int flags, mode_t mode); ++ + __END_DECLS + + #endif /* SUPPORT_H */ +diff --git a/support/tst-support-open-dev-null-range.c b/support/tst-support-open-dev-null-range.c +new file mode 100644 +index 0000000000000000..8e29def1ce780629 +--- /dev/null ++++ b/support/tst-support-open-dev-null-range.c +@@ -0,0 +1,155 @@ ++/* Tests for support_open_dev_null_range. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef PATH_MAX ++# define PATH_MAX 1024 ++#endif ++ ++#include ++ ++static void ++check_path (int fd) ++{ ++ char *proc_fd_path = xasprintf ("/proc/self/fd/%d", fd); ++ char file_path[PATH_MAX]; ++ ssize_t file_path_length ++ = readlink (proc_fd_path, file_path, sizeof (file_path)); ++ free (proc_fd_path); ++ if (file_path_length < 0) ++ FAIL_EXIT1 ("readlink (%s, %p, %zu)", proc_fd_path, file_path, ++ sizeof (file_path)); ++ file_path[file_path_length] = '\0'; ++ TEST_COMPARE_STRING (file_path, "/dev/null"); ++} ++ ++static int ++number_of_opened_files (void) ++{ ++ DIR *fds = opendir ("/proc/self/fd"); ++ if (fds == NULL) ++ FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m"); ++ ++ int r = 0; ++ 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; ++ ++ r = r + 1; ++ } ++ ++ closedir (fds); ++ ++ return r; ++} ++ ++static int ++do_test (void) ++{ ++ const int nfds1 = 8; ++ int lowfd = support_open_dev_null_range (nfds1, O_RDONLY, 0600); ++ for (int i = 0; i < nfds1; i++) ++ { ++ TEST_VERIFY (fcntl (lowfd + i, F_GETFL) > -1); ++ check_path (lowfd + i); ++ } ++ ++ /* create some gaps. */ ++ xclose (lowfd + 1); ++ xclose (lowfd + 5); ++ xclose (lowfd + 6); ++ ++ const int nfds2 = 16; ++ int lowfd2 = support_open_dev_null_range (nfds2, O_RDONLY, 0600); ++ for (int i = 0; i < nfds2; i++) ++ { ++ TEST_VERIFY (fcntl (lowfd2 + i, F_GETFL) > -1); ++ check_path (lowfd2 + i); ++ } ++ ++ /* Decrease the maximum number of files. */ ++ { ++ struct rlimit rl; ++ if (getrlimit (RLIMIT_NOFILE, &rl) == -1) ++ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m"); ++ ++ rl.rlim_cur = number_of_opened_files (); ++ ++ if (setrlimit (RLIMIT_NOFILE, &rl) == 1) ++ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m"); ++ } ++ ++ const int nfds3 = 16; ++ int lowfd3 = support_open_dev_null_range (nfds3, O_RDONLY, 0600); ++ for (int i = 0; i < nfds3; i++) ++ { ++ TEST_VERIFY (fcntl (lowfd3 + i, F_GETFL) > -1); ++ check_path (lowfd3 + i); ++ } ++ ++ /* create a lot of gaps to trigger the range extension. */ ++ xclose (lowfd3 + 1); ++ xclose (lowfd3 + 3); ++ xclose (lowfd3 + 5); ++ xclose (lowfd3 + 7); ++ xclose (lowfd3 + 9); ++ xclose (lowfd3 + 11); ++ xclose (lowfd3 + 13); ++ ++ const int nfds4 = 16; ++ int lowfd4 = support_open_dev_null_range (nfds4, O_RDONLY, 0600); ++ for (int i = 0; i < nfds4; i++) ++ { ++ TEST_VERIFY (fcntl (lowfd4 + i, F_GETFL) > -1); ++ check_path (lowfd4 + i); ++ } ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-240.patch b/SOURCES/glibc-upstream-2.34-240.patch new file mode 100644 index 0000000..d5cec58 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-240.patch @@ -0,0 +1,70 @@ +commit 08728256faf69b159b9ecd64f7f8b734f5f456e4 +Author: Florian Weimer +Date: Thu Feb 3 10:58:59 2022 +0100 + + Linux: Assume that NEED_DL_SYSINFO_DSO is always defined + + The definition itself is still needed for generic code. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit f19fc997a5754a6c0bb9e43618f0597e878061f7) + +diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c +index e36b3e6b63b1aa7e..1829dab4f38b560c 100644 +--- a/sysdeps/unix/sysv/linux/dl-sysdep.c ++++ b/sysdeps/unix/sysv/linux/dl-sysdep.c +@@ -134,11 +134,9 @@ _dl_sysdep_start (void **start_argptr, + new_sysinfo = av->a_un.a_val; + break; + #endif +-#ifdef NEED_DL_SYSINFO_DSO + case AT_SYSINFO_EHDR: + GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val; + break; +-#endif + case AT_RANDOM: + _dl_random = (void *) av->a_un.a_val; + break; +@@ -153,10 +151,8 @@ _dl_sysdep_start (void **start_argptr, + #ifdef NEED_DL_SYSINFO + if (new_sysinfo != 0) + { +-# ifdef NEED_DL_SYSINFO_DSO + /* Only set the sysinfo value if we also have the vsyscall DSO. */ + if (GLRO(dl_sysinfo_dso) != 0) +-# endif + GLRO(dl_sysinfo) = new_sysinfo; + } + #endif +@@ -309,7 +305,7 @@ int + attribute_hidden + _dl_discover_osversion (void) + { +-#if defined NEED_DL_SYSINFO_DSO && defined SHARED ++#ifdef SHARED + if (GLRO(dl_sysinfo_map) != NULL) + { + /* If the kernel-supplied DSO contains a note indicating the kernel's +@@ -340,7 +336,7 @@ _dl_discover_osversion (void) + } + } + } +-#endif ++#endif /* SHARED */ + + char bufmem[64]; + char *buf = bufmem; +diff --git a/sysdeps/unix/sysv/linux/m68k/sysdep.h b/sysdeps/unix/sysv/linux/m68k/sysdep.h +index b29986339a7e6cc0..11b93f2fa0af0e71 100644 +--- a/sysdeps/unix/sysv/linux/m68k/sysdep.h ++++ b/sysdeps/unix/sysv/linux/m68k/sysdep.h +@@ -301,8 +301,6 @@ SYSCALL_ERROR_LABEL: \ + #define PTR_MANGLE(var) (void) (var) + #define PTR_DEMANGLE(var) (void) (var) + +-#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO + /* M68K needs system-supplied DSO to access TLS helpers + even when statically linked. */ +-# define NEED_STATIC_SYSINFO_DSO 1 +-#endif ++#define NEED_STATIC_SYSINFO_DSO 1 diff --git a/SOURCES/glibc-upstream-2.34-241.patch b/SOURCES/glibc-upstream-2.34-241.patch new file mode 100644 index 0000000..0d67f1c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-241.patch @@ -0,0 +1,410 @@ +commit 4b9cd5465d5158dad7b4f0762bc70a3a1209b481 +Author: Florian Weimer +Date: Thu Feb 3 10:58:59 2022 +0100 + + Linux: Consolidate auxiliary vector parsing + + And optimize it slightly. + + The large switch statement in _dl_sysdep_start can be replaced with + a large array. This reduces source code and binary size. On + i686-linux-gnu: + + Before: + + text data bss dec hex filename + 7791 12 0 7803 1e7b elf/dl-sysdep.os + + After: + + text data bss dec hex filename + 7135 12 0 7147 1beb elf/dl-sysdep.os + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 8c8510ab2790039e58995ef3a22309582413d3ff) + +diff --git a/elf/dl-support.c b/elf/dl-support.c +index f29dc965f4d10648..40ef07521336857d 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -241,93 +241,21 @@ __rtld_lock_define_initialized_recursive (, _dl_load_tls_lock) + + + #ifdef HAVE_AUX_VECTOR ++#include ++ + int _dl_clktck; + + void + _dl_aux_init (ElfW(auxv_t) *av) + { +- int seen = 0; +- uid_t uid = 0; +- gid_t gid = 0; +- + #ifdef NEED_DL_SYSINFO + /* NB: Avoid RELATIVE relocation in static PIE. */ + GL(dl_sysinfo) = DL_SYSINFO_DEFAULT; + #endif + + _dl_auxv = av; +- for (; av->a_type != AT_NULL; ++av) +- switch (av->a_type) +- { +- case AT_PAGESZ: +- if (av->a_un.a_val != 0) +- GLRO(dl_pagesize) = av->a_un.a_val; +- break; +- case AT_CLKTCK: +- GLRO(dl_clktck) = av->a_un.a_val; +- break; +- case AT_PHDR: +- GL(dl_phdr) = (const void *) av->a_un.a_val; +- break; +- case AT_PHNUM: +- GL(dl_phnum) = av->a_un.a_val; +- break; +- case AT_PLATFORM: +- GLRO(dl_platform) = (void *) av->a_un.a_val; +- break; +- case AT_HWCAP: +- GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_HWCAP2: +- GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_FPUCW: +- GLRO(dl_fpu_control) = av->a_un.a_val; +- break; +-#ifdef NEED_DL_SYSINFO +- case AT_SYSINFO: +- GL(dl_sysinfo) = av->a_un.a_val; +- break; +-#endif +-#ifdef NEED_DL_SYSINFO_DSO +- case AT_SYSINFO_EHDR: +- GL(dl_sysinfo_dso) = (void *) av->a_un.a_val; +- break; +-#endif +- case AT_UID: +- uid ^= av->a_un.a_val; +- seen |= 1; +- break; +- case AT_EUID: +- uid ^= av->a_un.a_val; +- seen |= 2; +- break; +- case AT_GID: +- gid ^= av->a_un.a_val; +- seen |= 4; +- break; +- case AT_EGID: +- gid ^= av->a_un.a_val; +- seen |= 8; +- break; +- case AT_SECURE: +- seen = -1; +- __libc_enable_secure = av->a_un.a_val; +- __libc_enable_secure_decided = 1; +- break; +- case AT_RANDOM: +- _dl_random = (void *) av->a_un.a_val; +- break; +- case AT_MINSIGSTKSZ: +- _dl_minsigstacksize = av->a_un.a_val; +- break; +- DL_PLATFORM_AUXV +- } +- if (seen == 0xf) +- { +- __libc_enable_secure = uid != 0 || gid != 0; +- __libc_enable_secure_decided = 1; +- } ++ dl_parse_auxv_t auxv_values = { 0, }; ++ _dl_parse_auxv (av, auxv_values); + } + #endif + +diff --git a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h +index 1aa9dca80d189ebe..8c99e776a0af9cef 100644 +--- a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h ++++ b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h +@@ -20,16 +20,8 @@ + + extern long __libc_alpha_cache_shape[4]; + +-#define DL_PLATFORM_AUXV \ +- case AT_L1I_CACHESHAPE: \ +- __libc_alpha_cache_shape[0] = av->a_un.a_val; \ +- break; \ +- case AT_L1D_CACHESHAPE: \ +- __libc_alpha_cache_shape[1] = av->a_un.a_val; \ +- break; \ +- case AT_L2_CACHESHAPE: \ +- __libc_alpha_cache_shape[2] = av->a_un.a_val; \ +- break; \ +- case AT_L3_CACHESHAPE: \ +- __libc_alpha_cache_shape[3] = av->a_un.a_val; \ +- break; ++#define DL_PLATFORM_AUXV \ ++ __libc_alpha_cache_shape[0] = auxv_values[AT_L1I_CACHESHAPE]; \ ++ __libc_alpha_cache_shape[1] = auxv_values[AT_L1D_CACHESHAPE]; \ ++ __libc_alpha_cache_shape[2] = auxv_values[AT_L2_CACHESHAPE]; \ ++ __libc_alpha_cache_shape[3] = auxv_values[AT_L3_CACHESHAPE]; +diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +new file mode 100644 +index 0000000000000000..b3d82f69946d6d2c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +@@ -0,0 +1,61 @@ ++/* Parse the Linux auxiliary vector. ++ Copyright (C) 1995-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1]; ++ ++/* Copy the auxiliary vector into AUX_VALUES and set up GLRO ++ variables. */ ++static inline ++void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) ++{ ++ auxv_values[AT_ENTRY] = (ElfW(Addr)) ENTRY_POINT; ++ auxv_values[AT_PAGESZ] = EXEC_PAGESIZE; ++ auxv_values[AT_FPUCW] = _FPU_DEFAULT; ++ ++ /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ ++ _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), ++ "CONSTANT_MINSIGSTKSZ is constant"); ++ auxv_values[AT_MINSIGSTKSZ] = CONSTANT_MINSIGSTKSZ; ++ ++ for (; av->a_type != AT_NULL; av++) ++ if (av->a_type <= AT_MINSIGSTKSZ) ++ auxv_values[av->a_type] = av->a_un.a_val; ++ ++ GLRO(dl_pagesize) = auxv_values[AT_PAGESZ]; ++ __libc_enable_secure = auxv_values[AT_SECURE]; ++ GLRO(dl_platform) = (void *) auxv_values[AT_PLATFORM]; ++ GLRO(dl_hwcap) = auxv_values[AT_HWCAP]; ++ GLRO(dl_hwcap2) = auxv_values[AT_HWCAP2]; ++ GLRO(dl_clktck) = auxv_values[AT_CLKTCK]; ++ GLRO(dl_fpu_control) = auxv_values[AT_FPUCW]; ++ _dl_random = (void *) auxv_values[AT_RANDOM]; ++ GLRO(dl_minsigstacksize) = auxv_values[AT_MINSIGSTKSZ]; ++ GLRO(dl_sysinfo_dso) = (void *) auxv_values[AT_SYSINFO_EHDR]; ++#ifdef NEED_DL_SYSINFO ++ if (GLRO(dl_sysinfo_dso) != NULL) ++ GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO]; ++#endif ++ ++ DL_PLATFORM_AUXV ++} +diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c +index 1829dab4f38b560c..80aa9f6f4acb7e3c 100644 +--- a/sysdeps/unix/sysv/linux/dl-sysdep.c ++++ b/sysdeps/unix/sysv/linux/dl-sysdep.c +@@ -21,13 +21,12 @@ + #include + #include + #include ++#include + #include + #include + #include +-#include + #include + #include +-#include + #include + #include + #include +@@ -63,24 +62,24 @@ void *_dl_random attribute_relro = NULL; + # define DL_STACK_END(cookie) ((void *) (cookie)) + #endif + +-ElfW(Addr) +-_dl_sysdep_start (void **start_argptr, +- void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, +- ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) ++/* Arguments passed to dl_main. */ ++struct dl_main_arguments + { +- const ElfW(Phdr) *phdr = NULL; +- ElfW(Word) phnum = 0; ++ const ElfW(Phdr) *phdr; ++ ElfW(Word) phnum; + ElfW(Addr) user_entry; +- ElfW(auxv_t) *av; +-#ifdef NEED_DL_SYSINFO +- uintptr_t new_sysinfo = 0; +-#endif ++}; + +- __libc_stack_end = DL_STACK_END (start_argptr); ++/* Separate function, so that dl_main can be called without the large ++ array on the stack. */ ++static void ++_dl_sysdep_parse_arguments (void **start_argptr, ++ struct dl_main_arguments *args) ++{ + _dl_argc = (intptr_t) *start_argptr; + _dl_argv = (char **) (start_argptr + 1); /* Necessary aliasing violation. */ + _environ = _dl_argv + _dl_argc + 1; +- for (char **tmp = _environ + 1; ; ++tmp) ++ for (char **tmp = _environ; ; ++tmp) + if (*tmp == NULL) + { + /* Another necessary aliasing violation. */ +@@ -88,74 +87,25 @@ _dl_sysdep_start (void **start_argptr, + break; + } + +- user_entry = (ElfW(Addr)) ENTRY_POINT; +- GLRO(dl_platform) = NULL; /* Default to nothing known about the platform. */ ++ dl_parse_auxv_t auxv_values = { 0, }; ++ _dl_parse_auxv (GLRO(dl_auxv), auxv_values); + +- /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ +- _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), +- "CONSTANT_MINSIGSTKSZ is constant"); +- GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ; ++ args->phdr = (const ElfW(Phdr) *) auxv_values[AT_PHDR]; ++ args->phnum = auxv_values[AT_PHNUM]; ++ args->user_entry = auxv_values[AT_ENTRY]; ++} + +- for (av = GLRO(dl_auxv); av->a_type != AT_NULL; av++) +- switch (av->a_type) +- { +- case AT_PHDR: +- phdr = (void *) av->a_un.a_val; +- break; +- case AT_PHNUM: +- phnum = av->a_un.a_val; +- break; +- case AT_PAGESZ: +- GLRO(dl_pagesize) = av->a_un.a_val; +- break; +- case AT_ENTRY: +- user_entry = av->a_un.a_val; +- break; +- case AT_SECURE: +- __libc_enable_secure = av->a_un.a_val; +- break; +- case AT_PLATFORM: +- GLRO(dl_platform) = (void *) av->a_un.a_val; +- break; +- case AT_HWCAP: +- GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_HWCAP2: +- GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_CLKTCK: +- GLRO(dl_clktck) = av->a_un.a_val; +- break; +- case AT_FPUCW: +- GLRO(dl_fpu_control) = av->a_un.a_val; +- break; +-#ifdef NEED_DL_SYSINFO +- case AT_SYSINFO: +- new_sysinfo = av->a_un.a_val; +- break; +-#endif +- case AT_SYSINFO_EHDR: +- GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val; +- break; +- case AT_RANDOM: +- _dl_random = (void *) av->a_un.a_val; +- break; +- case AT_MINSIGSTKSZ: +- GLRO(dl_minsigstacksize) = av->a_un.a_val; +- break; +- DL_PLATFORM_AUXV +- } ++ElfW(Addr) ++_dl_sysdep_start (void **start_argptr, ++ void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, ++ ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) ++{ ++ __libc_stack_end = DL_STACK_END (start_argptr); + +- dl_hwcap_check (); ++ struct dl_main_arguments dl_main_args; ++ _dl_sysdep_parse_arguments (start_argptr, &dl_main_args); + +-#ifdef NEED_DL_SYSINFO +- if (new_sysinfo != 0) +- { +- /* Only set the sysinfo value if we also have the vsyscall DSO. */ +- if (GLRO(dl_sysinfo_dso) != 0) +- GLRO(dl_sysinfo) = new_sysinfo; +- } +-#endif ++ dl_hwcap_check (); + + __tunables_init (_environ); + +@@ -187,8 +137,9 @@ _dl_sysdep_start (void **start_argptr, + if (__builtin_expect (__libc_enable_secure, 0)) + __libc_check_standard_fds (); + +- (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv)); +- return user_entry; ++ (*dl_main) (dl_main_args.phdr, dl_main_args.phnum, ++ &dl_main_args.user_entry, GLRO(dl_auxv)); ++ return dl_main_args.user_entry; + } + + void +diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h +index 36ba0f3e9e45f3e2..7f35fb531ba22098 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h ++++ b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h +@@ -16,15 +16,5 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +- +-#if IS_IN (libc) && !defined SHARED +-int GLRO(dl_cache_line_size); +-#endif +- +-/* Scan the Aux Vector for the "Data Cache Block Size" entry and assign it +- to dl_cache_line_size. */ +-#define DL_PLATFORM_AUXV \ +- case AT_DCACHEBSIZE: \ +- GLRO(dl_cache_line_size) = av->a_un.a_val; \ +- break; ++#define DL_PLATFORM_AUXV \ ++ GLRO(dl_cache_line_size) = auxv_values[AT_DCACHEBSIZE]; +diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-support.c b/sysdeps/unix/sysv/linux/powerpc/dl-support.c +new file mode 100644 +index 0000000000000000..abe68a704946b90f +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/powerpc/dl-support.c +@@ -0,0 +1,4 @@ ++#include ++ ++/* Populated from the auxiliary vector. */ ++int _dl_cache_line_size; diff --git a/SOURCES/glibc-upstream-2.34-242.patch b/SOURCES/glibc-upstream-2.34-242.patch new file mode 100644 index 0000000..a120d5c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-242.patch @@ -0,0 +1,399 @@ +commit 1cc4ddfeebdb68e0b6de7e4878eef94d3438706f +Author: Florian Weimer +Date: Fri Feb 11 16:01:19 2022 +0100 + + Revert "Linux: Consolidate auxiliary vector parsing" + + This reverts commit 8c8510ab2790039e58995ef3a22309582413d3ff. The + revert is not perfect because the commit included a bug fix for + _dl_sysdep_start with an empty argv, introduced in commit + 2d47fa68628e831a692cba8fc9050cef435afc5e ("Linux: Remove + DL_FIND_ARG_COMPONENTS"), and this bug fix is kept. + + The revert is necessary because the reverted commit introduced an + early memset call on aarch64, which leads to crash due to lack of TCB + initialization. + + (cherry picked from commit d96d2995c1121d3310102afda2deb1f35761b5e6) + +diff --git a/elf/dl-support.c b/elf/dl-support.c +index 40ef07521336857d..f29dc965f4d10648 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -241,21 +241,93 @@ __rtld_lock_define_initialized_recursive (, _dl_load_tls_lock) + + + #ifdef HAVE_AUX_VECTOR +-#include +- + int _dl_clktck; + + void + _dl_aux_init (ElfW(auxv_t) *av) + { ++ int seen = 0; ++ uid_t uid = 0; ++ gid_t gid = 0; ++ + #ifdef NEED_DL_SYSINFO + /* NB: Avoid RELATIVE relocation in static PIE. */ + GL(dl_sysinfo) = DL_SYSINFO_DEFAULT; + #endif + + _dl_auxv = av; +- dl_parse_auxv_t auxv_values = { 0, }; +- _dl_parse_auxv (av, auxv_values); ++ for (; av->a_type != AT_NULL; ++av) ++ switch (av->a_type) ++ { ++ case AT_PAGESZ: ++ if (av->a_un.a_val != 0) ++ GLRO(dl_pagesize) = av->a_un.a_val; ++ break; ++ case AT_CLKTCK: ++ GLRO(dl_clktck) = av->a_un.a_val; ++ break; ++ case AT_PHDR: ++ GL(dl_phdr) = (const void *) av->a_un.a_val; ++ break; ++ case AT_PHNUM: ++ GL(dl_phnum) = av->a_un.a_val; ++ break; ++ case AT_PLATFORM: ++ GLRO(dl_platform) = (void *) av->a_un.a_val; ++ break; ++ case AT_HWCAP: ++ GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; ++ break; ++ case AT_HWCAP2: ++ GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; ++ break; ++ case AT_FPUCW: ++ GLRO(dl_fpu_control) = av->a_un.a_val; ++ break; ++#ifdef NEED_DL_SYSINFO ++ case AT_SYSINFO: ++ GL(dl_sysinfo) = av->a_un.a_val; ++ break; ++#endif ++#ifdef NEED_DL_SYSINFO_DSO ++ case AT_SYSINFO_EHDR: ++ GL(dl_sysinfo_dso) = (void *) av->a_un.a_val; ++ break; ++#endif ++ case AT_UID: ++ uid ^= av->a_un.a_val; ++ seen |= 1; ++ break; ++ case AT_EUID: ++ uid ^= av->a_un.a_val; ++ seen |= 2; ++ break; ++ case AT_GID: ++ gid ^= av->a_un.a_val; ++ seen |= 4; ++ break; ++ case AT_EGID: ++ gid ^= av->a_un.a_val; ++ seen |= 8; ++ break; ++ case AT_SECURE: ++ seen = -1; ++ __libc_enable_secure = av->a_un.a_val; ++ __libc_enable_secure_decided = 1; ++ break; ++ case AT_RANDOM: ++ _dl_random = (void *) av->a_un.a_val; ++ break; ++ case AT_MINSIGSTKSZ: ++ _dl_minsigstacksize = av->a_un.a_val; ++ break; ++ DL_PLATFORM_AUXV ++ } ++ if (seen == 0xf) ++ { ++ __libc_enable_secure = uid != 0 || gid != 0; ++ __libc_enable_secure_decided = 1; ++ } + } + #endif + +diff --git a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h +index 8c99e776a0af9cef..1aa9dca80d189ebe 100644 +--- a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h ++++ b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h +@@ -20,8 +20,16 @@ + + extern long __libc_alpha_cache_shape[4]; + +-#define DL_PLATFORM_AUXV \ +- __libc_alpha_cache_shape[0] = auxv_values[AT_L1I_CACHESHAPE]; \ +- __libc_alpha_cache_shape[1] = auxv_values[AT_L1D_CACHESHAPE]; \ +- __libc_alpha_cache_shape[2] = auxv_values[AT_L2_CACHESHAPE]; \ +- __libc_alpha_cache_shape[3] = auxv_values[AT_L3_CACHESHAPE]; ++#define DL_PLATFORM_AUXV \ ++ case AT_L1I_CACHESHAPE: \ ++ __libc_alpha_cache_shape[0] = av->a_un.a_val; \ ++ break; \ ++ case AT_L1D_CACHESHAPE: \ ++ __libc_alpha_cache_shape[1] = av->a_un.a_val; \ ++ break; \ ++ case AT_L2_CACHESHAPE: \ ++ __libc_alpha_cache_shape[2] = av->a_un.a_val; \ ++ break; \ ++ case AT_L3_CACHESHAPE: \ ++ __libc_alpha_cache_shape[3] = av->a_un.a_val; \ ++ break; +diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +deleted file mode 100644 +index b3d82f69946d6d2c..0000000000000000 +--- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h ++++ /dev/null +@@ -1,61 +0,0 @@ +-/* Parse the Linux auxiliary vector. +- Copyright (C) 1995-2022 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +-typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1]; +- +-/* Copy the auxiliary vector into AUX_VALUES and set up GLRO +- variables. */ +-static inline +-void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) +-{ +- auxv_values[AT_ENTRY] = (ElfW(Addr)) ENTRY_POINT; +- auxv_values[AT_PAGESZ] = EXEC_PAGESIZE; +- auxv_values[AT_FPUCW] = _FPU_DEFAULT; +- +- /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ +- _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), +- "CONSTANT_MINSIGSTKSZ is constant"); +- auxv_values[AT_MINSIGSTKSZ] = CONSTANT_MINSIGSTKSZ; +- +- for (; av->a_type != AT_NULL; av++) +- if (av->a_type <= AT_MINSIGSTKSZ) +- auxv_values[av->a_type] = av->a_un.a_val; +- +- GLRO(dl_pagesize) = auxv_values[AT_PAGESZ]; +- __libc_enable_secure = auxv_values[AT_SECURE]; +- GLRO(dl_platform) = (void *) auxv_values[AT_PLATFORM]; +- GLRO(dl_hwcap) = auxv_values[AT_HWCAP]; +- GLRO(dl_hwcap2) = auxv_values[AT_HWCAP2]; +- GLRO(dl_clktck) = auxv_values[AT_CLKTCK]; +- GLRO(dl_fpu_control) = auxv_values[AT_FPUCW]; +- _dl_random = (void *) auxv_values[AT_RANDOM]; +- GLRO(dl_minsigstacksize) = auxv_values[AT_MINSIGSTKSZ]; +- GLRO(dl_sysinfo_dso) = (void *) auxv_values[AT_SYSINFO_EHDR]; +-#ifdef NEED_DL_SYSINFO +- if (GLRO(dl_sysinfo_dso) != NULL) +- GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO]; +-#endif +- +- DL_PLATFORM_AUXV +-} +diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c +index 80aa9f6f4acb7e3c..facaaba3b9d091b3 100644 +--- a/sysdeps/unix/sysv/linux/dl-sysdep.c ++++ b/sysdeps/unix/sysv/linux/dl-sysdep.c +@@ -21,12 +21,13 @@ + #include + #include + #include +-#include + #include + #include + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -62,20 +63,20 @@ void *_dl_random attribute_relro = NULL; + # define DL_STACK_END(cookie) ((void *) (cookie)) + #endif + +-/* Arguments passed to dl_main. */ +-struct dl_main_arguments ++ElfW(Addr) ++_dl_sysdep_start (void **start_argptr, ++ void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, ++ ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) + { +- const ElfW(Phdr) *phdr; +- ElfW(Word) phnum; ++ const ElfW(Phdr) *phdr = NULL; ++ ElfW(Word) phnum = 0; + ElfW(Addr) user_entry; +-}; ++ ElfW(auxv_t) *av; ++#ifdef NEED_DL_SYSINFO ++ uintptr_t new_sysinfo = 0; ++#endif + +-/* Separate function, so that dl_main can be called without the large +- array on the stack. */ +-static void +-_dl_sysdep_parse_arguments (void **start_argptr, +- struct dl_main_arguments *args) +-{ ++ __libc_stack_end = DL_STACK_END (start_argptr); + _dl_argc = (intptr_t) *start_argptr; + _dl_argv = (char **) (start_argptr + 1); /* Necessary aliasing violation. */ + _environ = _dl_argv + _dl_argc + 1; +@@ -87,26 +88,75 @@ _dl_sysdep_parse_arguments (void **start_argptr, + break; + } + +- dl_parse_auxv_t auxv_values = { 0, }; +- _dl_parse_auxv (GLRO(dl_auxv), auxv_values); ++ user_entry = (ElfW(Addr)) ENTRY_POINT; ++ GLRO(dl_platform) = NULL; /* Default to nothing known about the platform. */ + +- args->phdr = (const ElfW(Phdr) *) auxv_values[AT_PHDR]; +- args->phnum = auxv_values[AT_PHNUM]; +- args->user_entry = auxv_values[AT_ENTRY]; +-} ++ /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ ++ _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), ++ "CONSTANT_MINSIGSTKSZ is constant"); ++ GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ; + +-ElfW(Addr) +-_dl_sysdep_start (void **start_argptr, +- void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, +- ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) +-{ +- __libc_stack_end = DL_STACK_END (start_argptr); +- +- struct dl_main_arguments dl_main_args; +- _dl_sysdep_parse_arguments (start_argptr, &dl_main_args); ++ for (av = GLRO(dl_auxv); av->a_type != AT_NULL; av++) ++ switch (av->a_type) ++ { ++ case AT_PHDR: ++ phdr = (void *) av->a_un.a_val; ++ break; ++ case AT_PHNUM: ++ phnum = av->a_un.a_val; ++ break; ++ case AT_PAGESZ: ++ GLRO(dl_pagesize) = av->a_un.a_val; ++ break; ++ case AT_ENTRY: ++ user_entry = av->a_un.a_val; ++ break; ++ case AT_SECURE: ++ __libc_enable_secure = av->a_un.a_val; ++ break; ++ case AT_PLATFORM: ++ GLRO(dl_platform) = (void *) av->a_un.a_val; ++ break; ++ case AT_HWCAP: ++ GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; ++ break; ++ case AT_HWCAP2: ++ GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; ++ break; ++ case AT_CLKTCK: ++ GLRO(dl_clktck) = av->a_un.a_val; ++ break; ++ case AT_FPUCW: ++ GLRO(dl_fpu_control) = av->a_un.a_val; ++ break; ++#ifdef NEED_DL_SYSINFO ++ case AT_SYSINFO: ++ new_sysinfo = av->a_un.a_val; ++ break; ++#endif ++ case AT_SYSINFO_EHDR: ++ GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val; ++ break; ++ case AT_RANDOM: ++ _dl_random = (void *) av->a_un.a_val; ++ break; ++ case AT_MINSIGSTKSZ: ++ GLRO(dl_minsigstacksize) = av->a_un.a_val; ++ break; ++ DL_PLATFORM_AUXV ++ } + + dl_hwcap_check (); + ++#ifdef NEED_DL_SYSINFO ++ if (new_sysinfo != 0) ++ { ++ /* Only set the sysinfo value if we also have the vsyscall DSO. */ ++ if (GLRO(dl_sysinfo_dso) != 0) ++ GLRO(dl_sysinfo) = new_sysinfo; ++ } ++#endif ++ + __tunables_init (_environ); + + /* Initialize DSO sorting algorithm after tunables. */ +@@ -137,9 +187,8 @@ _dl_sysdep_start (void **start_argptr, + if (__builtin_expect (__libc_enable_secure, 0)) + __libc_check_standard_fds (); + +- (*dl_main) (dl_main_args.phdr, dl_main_args.phnum, +- &dl_main_args.user_entry, GLRO(dl_auxv)); +- return dl_main_args.user_entry; ++ (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv)); ++ return user_entry; + } + + void +diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h +index 7f35fb531ba22098..36ba0f3e9e45f3e2 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h ++++ b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h +@@ -16,5 +16,15 @@ + License along with the GNU C Library; if not, see + . */ + +-#define DL_PLATFORM_AUXV \ +- GLRO(dl_cache_line_size) = auxv_values[AT_DCACHEBSIZE]; ++#include ++ ++#if IS_IN (libc) && !defined SHARED ++int GLRO(dl_cache_line_size); ++#endif ++ ++/* Scan the Aux Vector for the "Data Cache Block Size" entry and assign it ++ to dl_cache_line_size. */ ++#define DL_PLATFORM_AUXV \ ++ case AT_DCACHEBSIZE: \ ++ GLRO(dl_cache_line_size) = av->a_un.a_val; \ ++ break; +diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-support.c b/sysdeps/unix/sysv/linux/powerpc/dl-support.c +deleted file mode 100644 +index abe68a704946b90f..0000000000000000 +--- a/sysdeps/unix/sysv/linux/powerpc/dl-support.c ++++ /dev/null +@@ -1,4 +0,0 @@ +-#include +- +-/* Populated from the auxiliary vector. */ +-int _dl_cache_line_size; diff --git a/SOURCES/glibc-upstream-2.34-243.patch b/SOURCES/glibc-upstream-2.34-243.patch new file mode 100644 index 0000000..a9ae285 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-243.patch @@ -0,0 +1,36 @@ +commit 28bdb03b1b2bdb2d2dc62a9beeaa7d9bd2b10679 +Author: Florian Weimer +Date: Fri Feb 11 19:03:04 2022 +0100 + + Linux: Include in dl-sysdep.c only for SHARED + + Otherwise, on POWER ends up being included twice, + once in dl-sysdep.c, once in dl-support.c. That leads to a linker + failure due to multiple definitions of _dl_cache_line_size. + + Fixes commit d96d2995c1121d3310102afda2deb1f35761b5e6 + ("Revert "Linux: Consolidate auxiliary vector parsing"). + + (cherry picked from commit 098c795e85fbd05c5ef59c2d0ce59529331bea27) + +diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c +index facaaba3b9d091b3..3487976b06ad7f58 100644 +--- a/sysdeps/unix/sysv/linux/dl-sysdep.c ++++ b/sysdeps/unix/sysv/linux/dl-sysdep.c +@@ -18,7 +18,6 @@ + + #include <_itoa.h> + #include +-#include + #include + #include + #include +@@ -46,6 +45,8 @@ + #include + + #ifdef SHARED ++# include ++ + extern char **_environ attribute_hidden; + extern char _end[] attribute_hidden; + diff --git a/SOURCES/glibc-upstream-2.34-244.patch b/SOURCES/glibc-upstream-2.34-244.patch new file mode 100644 index 0000000..0a4325f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-244.patch @@ -0,0 +1,439 @@ +commit ff900fad89df7fa12750c018993a12cc02474646 +Author: Florian Weimer +Date: Mon Feb 28 11:50:41 2022 +0100 + + Linux: Consolidate auxiliary vector parsing (redo) + + And optimize it slightly. + + This is commit 8c8510ab2790039e58995ef3a22309582413d3ff revised. + + In _dl_aux_init in elf/dl-support.c, use an explicit loop + and -fno-tree-loop-distribute-patterns to avoid memset. + + Reviewed-by: Szabolcs Nagy + (cherry picked from commit 73fc4e28b9464f0e13edc719a5372839970e7ddb) + +diff --git a/elf/Makefile b/elf/Makefile +index c89a6a58690646ee..6423ebbdd7708a14 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -148,6 +148,11 @@ ifeq (yes,$(have-loop-to-function)) + CFLAGS-rtld.c += -fno-tree-loop-distribute-patterns + endif + ++ifeq (yes,$(have-loop-to-function)) ++# Likewise, during static library startup, memset is not yet available. ++CFLAGS-dl-support.c = -fno-tree-loop-distribute-patterns ++endif ++ + # Compile rtld itself without stack protection. + # Also compile all routines in the static library that are elided from + # the shared libc because they are in libc.a in the same way. +diff --git a/elf/dl-support.c b/elf/dl-support.c +index f29dc965f4d10648..a2e45e7b14e3a6b9 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + extern char *__progname; + char **_dl_argv = &__progname; /* This is checked for some error messages. */ +@@ -241,93 +242,25 @@ __rtld_lock_define_initialized_recursive (, _dl_load_tls_lock) + + + #ifdef HAVE_AUX_VECTOR ++#include ++ + int _dl_clktck; + + void + _dl_aux_init (ElfW(auxv_t) *av) + { +- int seen = 0; +- uid_t uid = 0; +- gid_t gid = 0; +- + #ifdef NEED_DL_SYSINFO + /* NB: Avoid RELATIVE relocation in static PIE. */ + GL(dl_sysinfo) = DL_SYSINFO_DEFAULT; + #endif + + _dl_auxv = av; +- for (; av->a_type != AT_NULL; ++av) +- switch (av->a_type) +- { +- case AT_PAGESZ: +- if (av->a_un.a_val != 0) +- GLRO(dl_pagesize) = av->a_un.a_val; +- break; +- case AT_CLKTCK: +- GLRO(dl_clktck) = av->a_un.a_val; +- break; +- case AT_PHDR: +- GL(dl_phdr) = (const void *) av->a_un.a_val; +- break; +- case AT_PHNUM: +- GL(dl_phnum) = av->a_un.a_val; +- break; +- case AT_PLATFORM: +- GLRO(dl_platform) = (void *) av->a_un.a_val; +- break; +- case AT_HWCAP: +- GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_HWCAP2: +- GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_FPUCW: +- GLRO(dl_fpu_control) = av->a_un.a_val; +- break; +-#ifdef NEED_DL_SYSINFO +- case AT_SYSINFO: +- GL(dl_sysinfo) = av->a_un.a_val; +- break; +-#endif +-#ifdef NEED_DL_SYSINFO_DSO +- case AT_SYSINFO_EHDR: +- GL(dl_sysinfo_dso) = (void *) av->a_un.a_val; +- break; +-#endif +- case AT_UID: +- uid ^= av->a_un.a_val; +- seen |= 1; +- break; +- case AT_EUID: +- uid ^= av->a_un.a_val; +- seen |= 2; +- break; +- case AT_GID: +- gid ^= av->a_un.a_val; +- seen |= 4; +- break; +- case AT_EGID: +- gid ^= av->a_un.a_val; +- seen |= 8; +- break; +- case AT_SECURE: +- seen = -1; +- __libc_enable_secure = av->a_un.a_val; +- __libc_enable_secure_decided = 1; +- break; +- case AT_RANDOM: +- _dl_random = (void *) av->a_un.a_val; +- break; +- case AT_MINSIGSTKSZ: +- _dl_minsigstacksize = av->a_un.a_val; +- break; +- DL_PLATFORM_AUXV +- } +- if (seen == 0xf) +- { +- __libc_enable_secure = uid != 0 || gid != 0; +- __libc_enable_secure_decided = 1; +- } ++ dl_parse_auxv_t auxv_values; ++ /* Use an explicit initialization loop here because memset may not ++ be available yet. */ ++ for (int i = 0; i < array_length (auxv_values); ++i) ++ auxv_values[i] = 0; ++ _dl_parse_auxv (av, auxv_values); + } + #endif + +diff --git a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h +index 1aa9dca80d189ebe..8c99e776a0af9cef 100644 +--- a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h ++++ b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h +@@ -20,16 +20,8 @@ + + extern long __libc_alpha_cache_shape[4]; + +-#define DL_PLATFORM_AUXV \ +- case AT_L1I_CACHESHAPE: \ +- __libc_alpha_cache_shape[0] = av->a_un.a_val; \ +- break; \ +- case AT_L1D_CACHESHAPE: \ +- __libc_alpha_cache_shape[1] = av->a_un.a_val; \ +- break; \ +- case AT_L2_CACHESHAPE: \ +- __libc_alpha_cache_shape[2] = av->a_un.a_val; \ +- break; \ +- case AT_L3_CACHESHAPE: \ +- __libc_alpha_cache_shape[3] = av->a_un.a_val; \ +- break; ++#define DL_PLATFORM_AUXV \ ++ __libc_alpha_cache_shape[0] = auxv_values[AT_L1I_CACHESHAPE]; \ ++ __libc_alpha_cache_shape[1] = auxv_values[AT_L1D_CACHESHAPE]; \ ++ __libc_alpha_cache_shape[2] = auxv_values[AT_L2_CACHESHAPE]; \ ++ __libc_alpha_cache_shape[3] = auxv_values[AT_L3_CACHESHAPE]; +diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +new file mode 100644 +index 0000000000000000..bf9374371eb217fc +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +@@ -0,0 +1,61 @@ ++/* Parse the Linux auxiliary vector. ++ Copyright (C) 1995-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1]; ++ ++/* Copy the auxiliary vector into AUXV_VALUES and set up GLRO ++ variables. */ ++static inline ++void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) ++{ ++ auxv_values[AT_ENTRY] = (ElfW(Addr)) ENTRY_POINT; ++ auxv_values[AT_PAGESZ] = EXEC_PAGESIZE; ++ auxv_values[AT_FPUCW] = _FPU_DEFAULT; ++ ++ /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ ++ _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), ++ "CONSTANT_MINSIGSTKSZ is constant"); ++ auxv_values[AT_MINSIGSTKSZ] = CONSTANT_MINSIGSTKSZ; ++ ++ for (; av->a_type != AT_NULL; av++) ++ if (av->a_type <= AT_MINSIGSTKSZ) ++ auxv_values[av->a_type] = av->a_un.a_val; ++ ++ GLRO(dl_pagesize) = auxv_values[AT_PAGESZ]; ++ __libc_enable_secure = auxv_values[AT_SECURE]; ++ GLRO(dl_platform) = (void *) auxv_values[AT_PLATFORM]; ++ GLRO(dl_hwcap) = auxv_values[AT_HWCAP]; ++ GLRO(dl_hwcap2) = auxv_values[AT_HWCAP2]; ++ GLRO(dl_clktck) = auxv_values[AT_CLKTCK]; ++ GLRO(dl_fpu_control) = auxv_values[AT_FPUCW]; ++ _dl_random = (void *) auxv_values[AT_RANDOM]; ++ GLRO(dl_minsigstacksize) = auxv_values[AT_MINSIGSTKSZ]; ++ GLRO(dl_sysinfo_dso) = (void *) auxv_values[AT_SYSINFO_EHDR]; ++#ifdef NEED_DL_SYSINFO ++ if (GLRO(dl_sysinfo_dso) != NULL) ++ GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO]; ++#endif ++ ++ DL_PLATFORM_AUXV ++} +diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c +index 3487976b06ad7f58..56db828fc6985de6 100644 +--- a/sysdeps/unix/sysv/linux/dl-sysdep.c ++++ b/sysdeps/unix/sysv/linux/dl-sysdep.c +@@ -18,15 +18,14 @@ + + #include <_itoa.h> + #include +-#include ++#include + #include ++#include + #include + #include + #include +-#include + #include + #include +-#include + #include + #include + #include +@@ -43,10 +42,9 @@ + #include + + #include ++#include + + #ifdef SHARED +-# include +- + extern char **_environ attribute_hidden; + extern char _end[] attribute_hidden; + +@@ -64,20 +62,20 @@ void *_dl_random attribute_relro = NULL; + # define DL_STACK_END(cookie) ((void *) (cookie)) + #endif + +-ElfW(Addr) +-_dl_sysdep_start (void **start_argptr, +- void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, +- ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) ++/* Arguments passed to dl_main. */ ++struct dl_main_arguments + { +- const ElfW(Phdr) *phdr = NULL; +- ElfW(Word) phnum = 0; ++ const ElfW(Phdr) *phdr; ++ ElfW(Word) phnum; + ElfW(Addr) user_entry; +- ElfW(auxv_t) *av; +-#ifdef NEED_DL_SYSINFO +- uintptr_t new_sysinfo = 0; +-#endif ++}; + +- __libc_stack_end = DL_STACK_END (start_argptr); ++/* Separate function, so that dl_main can be called without the large ++ array on the stack. */ ++static void ++_dl_sysdep_parse_arguments (void **start_argptr, ++ struct dl_main_arguments *args) ++{ + _dl_argc = (intptr_t) *start_argptr; + _dl_argv = (char **) (start_argptr + 1); /* Necessary aliasing violation. */ + _environ = _dl_argv + _dl_argc + 1; +@@ -89,74 +87,25 @@ _dl_sysdep_start (void **start_argptr, + break; + } + +- user_entry = (ElfW(Addr)) ENTRY_POINT; +- GLRO(dl_platform) = NULL; /* Default to nothing known about the platform. */ ++ dl_parse_auxv_t auxv_values = { 0, }; ++ _dl_parse_auxv (GLRO(dl_auxv), auxv_values); + +- /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ +- _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), +- "CONSTANT_MINSIGSTKSZ is constant"); +- GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ; ++ args->phdr = (const ElfW(Phdr) *) auxv_values[AT_PHDR]; ++ args->phnum = auxv_values[AT_PHNUM]; ++ args->user_entry = auxv_values[AT_ENTRY]; ++} + +- for (av = GLRO(dl_auxv); av->a_type != AT_NULL; av++) +- switch (av->a_type) +- { +- case AT_PHDR: +- phdr = (void *) av->a_un.a_val; +- break; +- case AT_PHNUM: +- phnum = av->a_un.a_val; +- break; +- case AT_PAGESZ: +- GLRO(dl_pagesize) = av->a_un.a_val; +- break; +- case AT_ENTRY: +- user_entry = av->a_un.a_val; +- break; +- case AT_SECURE: +- __libc_enable_secure = av->a_un.a_val; +- break; +- case AT_PLATFORM: +- GLRO(dl_platform) = (void *) av->a_un.a_val; +- break; +- case AT_HWCAP: +- GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_HWCAP2: +- GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; +- break; +- case AT_CLKTCK: +- GLRO(dl_clktck) = av->a_un.a_val; +- break; +- case AT_FPUCW: +- GLRO(dl_fpu_control) = av->a_un.a_val; +- break; +-#ifdef NEED_DL_SYSINFO +- case AT_SYSINFO: +- new_sysinfo = av->a_un.a_val; +- break; +-#endif +- case AT_SYSINFO_EHDR: +- GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val; +- break; +- case AT_RANDOM: +- _dl_random = (void *) av->a_un.a_val; +- break; +- case AT_MINSIGSTKSZ: +- GLRO(dl_minsigstacksize) = av->a_un.a_val; +- break; +- DL_PLATFORM_AUXV +- } ++ElfW(Addr) ++_dl_sysdep_start (void **start_argptr, ++ void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, ++ ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) ++{ ++ __libc_stack_end = DL_STACK_END (start_argptr); + +- dl_hwcap_check (); ++ struct dl_main_arguments dl_main_args; ++ _dl_sysdep_parse_arguments (start_argptr, &dl_main_args); + +-#ifdef NEED_DL_SYSINFO +- if (new_sysinfo != 0) +- { +- /* Only set the sysinfo value if we also have the vsyscall DSO. */ +- if (GLRO(dl_sysinfo_dso) != 0) +- GLRO(dl_sysinfo) = new_sysinfo; +- } +-#endif ++ dl_hwcap_check (); + + __tunables_init (_environ); + +@@ -188,8 +137,9 @@ _dl_sysdep_start (void **start_argptr, + if (__builtin_expect (__libc_enable_secure, 0)) + __libc_check_standard_fds (); + +- (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv)); +- return user_entry; ++ (*dl_main) (dl_main_args.phdr, dl_main_args.phnum, ++ &dl_main_args.user_entry, GLRO(dl_auxv)); ++ return dl_main_args.user_entry; + } + + void +diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h +index 36ba0f3e9e45f3e2..7f35fb531ba22098 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h ++++ b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h +@@ -16,15 +16,5 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +- +-#if IS_IN (libc) && !defined SHARED +-int GLRO(dl_cache_line_size); +-#endif +- +-/* Scan the Aux Vector for the "Data Cache Block Size" entry and assign it +- to dl_cache_line_size. */ +-#define DL_PLATFORM_AUXV \ +- case AT_DCACHEBSIZE: \ +- GLRO(dl_cache_line_size) = av->a_un.a_val; \ +- break; ++#define DL_PLATFORM_AUXV \ ++ GLRO(dl_cache_line_size) = auxv_values[AT_DCACHEBSIZE]; +diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-support.c b/sysdeps/unix/sysv/linux/powerpc/dl-support.c +new file mode 100644 +index 0000000000000000..abe68a704946b90f +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/powerpc/dl-support.c +@@ -0,0 +1,4 @@ ++#include ++ ++/* Populated from the auxiliary vector. */ ++int _dl_cache_line_size; diff --git a/SOURCES/glibc-upstream-2.34-245.patch b/SOURCES/glibc-upstream-2.34-245.patch new file mode 100644 index 0000000..5ba00fd --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-245.patch @@ -0,0 +1,197 @@ +commit be9240c84c67de44959905a829141576965a0588 +Author: Fangrui Song +Date: Tue Apr 19 15:52:27 2022 -0700 + + elf: Remove __libc_init_secure + + After 73fc4e28b9464f0e13edc719a5372839970e7ddb, + __libc_enable_secure_decided is always 0 and a statically linked + executable may overwrite __libc_enable_secure without considering + AT_SECURE. + + The __libc_enable_secure has been correctly initialized in _dl_aux_init, + so just remove __libc_enable_secure_decided and __libc_init_secure. + This allows us to remove some startup_get*id functions from + 22b79ed7f413cd980a7af0cf258da5bf82b6d5e5. + + Reviewed-by: Florian Weimer + (cherry picked from commit 3e9acce8c50883b6cd8a3fb653363d9fa21e1608) + +diff --git a/csu/libc-start.c b/csu/libc-start.c +index d01e57ea59ceb880..a2fc2f6f9665a48f 100644 +--- a/csu/libc-start.c ++++ b/csu/libc-start.c +@@ -285,9 +285,6 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), + } + } + +- /* Initialize very early so that tunables can use it. */ +- __libc_init_secure (); +- + __tunables_init (__environ); + + ARCH_INIT_CPU_FEATURES (); +diff --git a/elf/enbl-secure.c b/elf/enbl-secure.c +index 9e47526bd3e444e1..1208610bd0670c74 100644 +--- a/elf/enbl-secure.c ++++ b/elf/enbl-secure.c +@@ -26,15 +26,5 @@ + #include + #include + +-/* If nonzero __libc_enable_secure is already set. */ +-int __libc_enable_secure_decided; + /* Safest assumption, if somehow the initializer isn't run. */ + int __libc_enable_secure = 1; +- +-void +-__libc_init_secure (void) +-{ +- if (__libc_enable_secure_decided == 0) +- __libc_enable_secure = (startup_geteuid () != startup_getuid () +- || startup_getegid () != startup_getgid ()); +-} +diff --git a/include/libc-internal.h b/include/libc-internal.h +index 749dfb919ce4a62d..44fcb6bdf8751c1c 100644 +--- a/include/libc-internal.h ++++ b/include/libc-internal.h +@@ -21,9 +21,6 @@ + + #include + +-/* Initialize the `__libc_enable_secure' flag. */ +-extern void __libc_init_secure (void); +- + /* Discover the tick frequency of the machine if something goes wrong, + we return 0, an impossible hertz. */ + extern int __profile_frequency (void); +diff --git a/include/unistd.h b/include/unistd.h +index 7849562c4272e2c9..5824485629793ccb 100644 +--- a/include/unistd.h ++++ b/include/unistd.h +@@ -180,7 +180,6 @@ libc_hidden_proto (__sbrk) + and some functions contained in the C library ignore various + environment variables that normally affect them. */ + extern int __libc_enable_secure attribute_relro; +-extern int __libc_enable_secure_decided; + rtld_hidden_proto (__libc_enable_secure) + + +diff --git a/sysdeps/generic/startup.h b/sysdeps/generic/startup.h +index 04f20cde474cea89..c3be5430bd8bbaa6 100644 +--- a/sysdeps/generic/startup.h ++++ b/sysdeps/generic/startup.h +@@ -23,27 +23,3 @@ + + /* Use macro instead of inline function to avoid including . */ + #define _startup_fatal(message) __libc_fatal ((message)) +- +-static inline uid_t +-startup_getuid (void) +-{ +- return __getuid (); +-} +- +-static inline uid_t +-startup_geteuid (void) +-{ +- return __geteuid (); +-} +- +-static inline gid_t +-startup_getgid (void) +-{ +- return __getgid (); +-} +- +-static inline gid_t +-startup_getegid (void) +-{ +- return __getegid (); +-} +diff --git a/sysdeps/mach/hurd/enbl-secure.c b/sysdeps/mach/hurd/enbl-secure.c +deleted file mode 100644 +index 3e9a6b888d56754b..0000000000000000 +--- a/sysdeps/mach/hurd/enbl-secure.c ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* Define and initialize the `__libc_enable_secure' flag. Hurd version. +- Copyright (C) 1998-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* There is no need for this file in the Hurd; it is just a placeholder +- to prevent inclusion of the sysdeps/generic version. +- In the shared library, the `__libc_enable_secure' variable is defined +- by the dynamic linker in dl-sysdep.c and set there. +- In the static library, it is defined in init-first.c and set there. */ +- +-#include +- +-void +-__libc_init_secure (void) +-{ +-} +diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c +index a430aae085527163..4dc9017ec8754a1a 100644 +--- a/sysdeps/mach/hurd/i386/init-first.c ++++ b/sysdeps/mach/hurd/i386/init-first.c +@@ -38,10 +38,6 @@ extern void __init_misc (int, char **, char **); + unsigned long int __hurd_threadvar_stack_offset; + unsigned long int __hurd_threadvar_stack_mask; + +-#ifndef SHARED +-int __libc_enable_secure; +-#endif +- + extern int __libc_argc attribute_hidden; + extern char **__libc_argv attribute_hidden; + extern char **_dl_argv; +diff --git a/sysdeps/unix/sysv/linux/i386/startup.h b/sysdeps/unix/sysv/linux/i386/startup.h +index dee7a4f1d3d420be..192c765361c17ed1 100644 +--- a/sysdeps/unix/sysv/linux/i386/startup.h ++++ b/sysdeps/unix/sysv/linux/i386/startup.h +@@ -32,30 +32,6 @@ _startup_fatal (const char *message __attribute__ ((unused))) + ABORT_INSTRUCTION; + __builtin_unreachable (); + } +- +-static inline uid_t +-startup_getuid (void) +-{ +- return (uid_t) INTERNAL_SYSCALL_CALL (getuid32); +-} +- +-static inline uid_t +-startup_geteuid (void) +-{ +- return (uid_t) INTERNAL_SYSCALL_CALL (geteuid32); +-} +- +-static inline gid_t +-startup_getgid (void) +-{ +- return (gid_t) INTERNAL_SYSCALL_CALL (getgid32); +-} +- +-static inline gid_t +-startup_getegid (void) +-{ +- return (gid_t) INTERNAL_SYSCALL_CALL (getegid32); +-} + #else + # include_next + #endif diff --git a/SOURCES/glibc-upstream-2.34-246.patch b/SOURCES/glibc-upstream-2.34-246.patch new file mode 100644 index 0000000..76c7b68 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-246.patch @@ -0,0 +1,31 @@ +commit 1e7b011f87c653ad109b34e675f64e7a5cc3805a +Author: Florian Weimer +Date: Wed May 4 15:37:21 2022 +0200 + + i386: Remove OPTIMIZE_FOR_GCC_5 from Linux libc-do-syscall.S + + After commit a78e6a10d0b50d0ca80309775980fc99944b1727 + ("i386: Remove broken CAN_USE_REGISTER_ASM_EBP (bug 28771)"), + it is never defined. + + Reviewed-by: H.J. Lu + (cherry picked from commit 6e5c7a1e262961adb52443ab91bd2c9b72316402) + +diff --git a/sysdeps/unix/sysv/linux/i386/libc-do-syscall.S b/sysdeps/unix/sysv/linux/i386/libc-do-syscall.S +index c95f297d6f0217ef..404435f0123b23b3 100644 +--- a/sysdeps/unix/sysv/linux/i386/libc-do-syscall.S ++++ b/sysdeps/unix/sysv/linux/i386/libc-do-syscall.S +@@ -18,8 +18,6 @@ + + #include + +-#ifndef OPTIMIZE_FOR_GCC_5 +- + /* %eax, %ecx, %edx and %esi contain the values expected by the kernel. + %edi points to a structure with the values of %ebx, %edi and %ebp. */ + +@@ -50,4 +48,3 @@ ENTRY (__libc_do_syscall) + cfi_restore (ebx) + ret + END (__libc_do_syscall) +-#endif diff --git a/SOURCES/glibc-upstream-2.34-247.patch b/SOURCES/glibc-upstream-2.34-247.patch new file mode 100644 index 0000000..c6b2961 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-247.patch @@ -0,0 +1,94 @@ +commit 1a5b9d1a231ae788aac3520dab07dc856e404c69 +Author: Florian Weimer +Date: Wed May 4 15:37:21 2022 +0200 + + i386: Honor I386_USE_SYSENTER for 6-argument Linux system calls + + Introduce an int-80h-based version of __libc_do_syscall and use + it if I386_USE_SYSENTER is defined as 0. + + Reviewed-by: H.J. Lu + (cherry picked from commit 60f0f2130d30cfd008ca39743027f1e200592dff) + +diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile +index abd0009d58f06303..e379a2e767d96322 100644 +--- a/sysdeps/unix/sysv/linux/i386/Makefile ++++ b/sysdeps/unix/sysv/linux/i386/Makefile +@@ -14,7 +14,7 @@ install-bin += lddlibc4 + endif + + ifeq ($(subdir),io) +-sysdep_routines += libc-do-syscall ++sysdep_routines += libc-do-syscall libc-do-syscall-int80 + endif + + ifeq ($(subdir),stdlib) +diff --git a/sysdeps/unix/sysv/linux/i386/libc-do-syscall-int80.S b/sysdeps/unix/sysv/linux/i386/libc-do-syscall-int80.S +new file mode 100644 +index 0000000000000000..2c472f255734b357 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/i386/libc-do-syscall-int80.S +@@ -0,0 +1,25 @@ ++/* Out-of-line syscall stub for six-argument syscalls from C. For static PIE. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SHARED ++# define I386_USE_SYSENTER 0 ++# include ++ ++# define __libc_do_syscall __libc_do_syscall_int80 ++# include "libc-do-syscall.S" ++#endif +diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h +index 39d6a3c13427abb5..4c6358c7fe43fe0b 100644 +--- a/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ b/sysdeps/unix/sysv/linux/i386/sysdep.h +@@ -43,6 +43,15 @@ + # endif + #endif + ++#if !I386_USE_SYSENTER && IS_IN (libc) && !defined SHARED ++/* Inside static libc, we have two versions. For compilation units ++ with !I386_USE_SYSENTER, the vDSO entry mechanism cannot be ++ used. */ ++# define I386_DO_SYSCALL_STRING "__libc_do_syscall_int80" ++#else ++# define I386_DO_SYSCALL_STRING "__libc_do_syscall" ++#endif ++ + #ifdef __ASSEMBLER__ + + /* Linux uses a negative return value to indicate syscall errors, +@@ -302,7 +311,7 @@ struct libc_do_syscall_args + }; \ + asm volatile ( \ + "movl %1, %%eax\n\t" \ +- "call __libc_do_syscall" \ ++ "call " I386_DO_SYSCALL_STRING \ + : "=a" (resultvar) \ + : "i" (__NR_##name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \ + : "memory", "cc") +@@ -316,7 +325,7 @@ struct libc_do_syscall_args + }; \ + asm volatile ( \ + "movl %1, %%eax\n\t" \ +- "call __libc_do_syscall" \ ++ "call " I386_DO_SYSCALL_STRING \ + : "=a" (resultvar) \ + : "a" (name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \ + : "memory", "cc") diff --git a/SOURCES/glibc-upstream-2.34-248.patch b/SOURCES/glibc-upstream-2.34-248.patch new file mode 100644 index 0000000..dda3e73 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-248.patch @@ -0,0 +1,93 @@ +commit b38c9cdb58061d357cdf9bca4f6967d487becb82 +Author: Florian Weimer +Date: Wed May 4 15:37:21 2022 +0200 + + Linux: Define MMAP_CALL_INTERNAL + + Unlike MMAP_CALL, this avoids a TCB dependency for an errno update + on failure. + + cannot be included as is on several architectures + due to the definition of page_unit, so introduce a separate header + file for the definition of MMAP_CALL and MMAP_CALL_INTERNAL, + . + + Reviewed-by: Stefan Liebler + (cherry picked from commit c1b68685d438373efe64e5f076f4215723004dfb) + +diff --git a/sysdeps/unix/sysv/linux/mmap_call.h b/sysdeps/unix/sysv/linux/mmap_call.h +new file mode 100644 +index 0000000000000000..3547c99e149e5064 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/mmap_call.h +@@ -0,0 +1,22 @@ ++/* Generic definition of MMAP_CALL and MMAP_CALL_INTERNAL. ++ Copyright (C) 2017-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define MMAP_CALL(__nr, __addr, __len, __prot, __flags, __fd, __offset) \ ++ INLINE_SYSCALL_CALL (__nr, __addr, __len, __prot, __flags, __fd, __offset) ++#define MMAP_CALL_INTERNAL(__nr, __addr, __len, __prot, __flags, __fd, __offset) \ ++ INTERNAL_SYSCALL_CALL (__nr, __addr, __len, __prot, __flags, __fd, __offset) +diff --git a/sysdeps/unix/sysv/linux/mmap_internal.h b/sysdeps/unix/sysv/linux/mmap_internal.h +index 5ca6976191137f95..989eb0c7c6b57dc1 100644 +--- a/sysdeps/unix/sysv/linux/mmap_internal.h ++++ b/sysdeps/unix/sysv/linux/mmap_internal.h +@@ -40,10 +40,6 @@ static uint64_t page_unit; + /* Do not accept offset not multiple of page size. */ + #define MMAP_OFF_LOW_MASK (MMAP2_PAGE_UNIT - 1) + +-/* An architecture may override this. */ +-#ifndef MMAP_CALL +-# define MMAP_CALL(__nr, __addr, __len, __prot, __flags, __fd, __offset) \ +- INLINE_SYSCALL_CALL (__nr, __addr, __len, __prot, __flags, __fd, __offset) +-#endif ++#include + + #endif /* MMAP_INTERNAL_LINUX_H */ +diff --git a/sysdeps/unix/sysv/linux/s390/mmap_internal.h b/sysdeps/unix/sysv/linux/s390/mmap_call.h +similarity index 78% +rename from sysdeps/unix/sysv/linux/s390/mmap_internal.h +rename to sysdeps/unix/sysv/linux/s390/mmap_call.h +index 46f1c3769d6b586a..bdd30cc83764c2c1 100644 +--- a/sysdeps/unix/sysv/linux/s390/mmap_internal.h ++++ b/sysdeps/unix/sysv/linux/s390/mmap_call.h +@@ -16,9 +16,6 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef MMAP_S390_INTERNAL_H +-# define MMAP_S390_INTERNAL_H +- + #define MMAP_CALL(__nr, __addr, __len, __prot, __flags, __fd, __offset) \ + ({ \ + long int __args[6] = { (long int) (__addr), (long int) (__len), \ +@@ -26,7 +23,10 @@ + (long int) (__fd), (long int) (__offset) }; \ + INLINE_SYSCALL_CALL (__nr, __args); \ + }) +- +-#include_next +- +-#endif ++#define MMAP_CALL_INTERNAL(__nr, __addr, __len, __prot, __flags, __fd, __offset) \ ++ ({ \ ++ long int __args[6] = { (long int) (__addr), (long int) (__len), \ ++ (long int) (__prot), (long int) (__flags), \ ++ (long int) (__fd), (long int) (__offset) }; \ ++ INTERNAL_SYSCALL_CALL (__nr, __args); \ ++ }) diff --git a/SOURCES/glibc-upstream-2.34-249.patch b/SOURCES/glibc-upstream-2.34-249.patch new file mode 100644 index 0000000..7b48d3f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-249.patch @@ -0,0 +1,88 @@ +commit b2387bea84560d286613257139aba6787f414594 +Author: Florian Weimer +Date: Mon May 9 18:15:16 2022 +0200 + + ia64: Always define IA64_USE_NEW_STUB as a flag macro + + And keep the previous definition if it exists. This allows + disabling IA64_USE_NEW_STUB while keeping USE_DL_SYSINFO defined. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 18bd9c3d3b1b6a9182698c85354578d1d58e9d64) + +diff --git a/sysdeps/unix/sysv/linux/ia64/brk.c b/sysdeps/unix/sysv/linux/ia64/brk.c +index cf2c5bd667fb4432..61d8fa260eb59d1e 100644 +--- a/sysdeps/unix/sysv/linux/ia64/brk.c ++++ b/sysdeps/unix/sysv/linux/ia64/brk.c +@@ -16,7 +16,6 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-/* brk is used by statup before TCB is properly set. */ +-#undef USE_DL_SYSINFO ++/* brk is used by startup before TCB is properly set up. */ ++#define IA64_USE_NEW_STUB 0 + #include +diff --git a/sysdeps/unix/sysv/linux/ia64/sysdep.h b/sysdeps/unix/sysv/linux/ia64/sysdep.h +index 7198c192a03b7676..f1c81a66833941cc 100644 +--- a/sysdeps/unix/sysv/linux/ia64/sysdep.h ++++ b/sysdeps/unix/sysv/linux/ia64/sysdep.h +@@ -46,12 +46,15 @@ + #undef SYS_ify + #define SYS_ify(syscall_name) __NR_##syscall_name + +-#if defined USE_DL_SYSINFO \ +- && (IS_IN (libc) \ +- || IS_IN (libpthread) || IS_IN (librt)) +-# define IA64_USE_NEW_STUB +-#else +-# undef IA64_USE_NEW_STUB ++#ifndef IA64_USE_NEW_STUB ++# if defined USE_DL_SYSINFO && IS_IN (libc) ++# define IA64_USE_NEW_STUB 1 ++# else ++# define IA64_USE_NEW_STUB 0 ++# endif ++#endif ++#if IA64_USE_NEW_STUB && !USE_DL_SYSINFO ++# error IA64_USE_NEW_STUB needs USE_DL_SYSINFO + #endif + + #ifdef __ASSEMBLER__ +@@ -103,7 +106,7 @@ + mov r15=num; \ + break __IA64_BREAK_SYSCALL + +-#ifdef IA64_USE_NEW_STUB ++#if IA64_USE_NEW_STUB + # ifdef SHARED + # define DO_CALL(num) \ + .prologue; \ +@@ -187,7 +190,7 @@ + (non-negative) errno on error or the return value on success. + */ + +-#ifdef IA64_USE_NEW_STUB ++#if IA64_USE_NEW_STUB + + # define INTERNAL_SYSCALL_NCS(name, nr, args...) \ + ({ \ +@@ -279,7 +282,7 @@ + #define ASM_OUTARGS_5 ASM_OUTARGS_4, "=r" (_out4) + #define ASM_OUTARGS_6 ASM_OUTARGS_5, "=r" (_out5) + +-#ifdef IA64_USE_NEW_STUB ++#if IA64_USE_NEW_STUB + #define ASM_ARGS_0 + #define ASM_ARGS_1 ASM_ARGS_0, "4" (_out0) + #define ASM_ARGS_2 ASM_ARGS_1, "5" (_out1) +@@ -315,7 +318,7 @@ + /* Branch registers. */ \ + "b6" + +-#ifdef IA64_USE_NEW_STUB ++#if IA64_USE_NEW_STUB + # define ASM_CLOBBERS_6 ASM_CLOBBERS_6_COMMON + #else + # define ASM_CLOBBERS_6 ASM_CLOBBERS_6_COMMON , "b7" diff --git a/SOURCES/glibc-upstream-2.34-25.patch b/SOURCES/glibc-upstream-2.34-25.patch new file mode 100644 index 0000000..8899335 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-25.patch @@ -0,0 +1,204 @@ +commit 772e33411bc730f832f415f93eb3e7c67e4d5488 +Author: Adhemerval Zanella +Date: Tue Aug 24 16:15:50 2021 -0300 + + Use support_open_dev_null_range io/tst-closefrom, misc/tst-close_range, and posix/tst-spawn5 (BZ #28260) + + It ensures a continuous range of file descriptor and avoid hitting + the RLIMIT_NOFILE. + + Checked on x86_64-linux-gnu. + + (cherry picked from commit 6b20880b22d1d0fce7e9f506baa6fe2d5c7fcfdc) + +diff --git a/io/tst-closefrom.c b/io/tst-closefrom.c +index d4c187073c7280e9..395ec0d894101a47 100644 +--- a/io/tst-closefrom.c ++++ b/io/tst-closefrom.c +@@ -24,31 +24,22 @@ + #include + #include + #include ++#include + + #include + + #define NFDS 100 + +-static int +-open_multiple_temp_files (void) +-{ +- /* Check if the temporary file descriptor has no no gaps. */ +- int lowfd = xopen ("/dev/null", O_RDONLY, 0600); +- for (int i = 1; i <= NFDS; i++) +- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), lowfd + i); +- return lowfd; +-} +- + static int + closefrom_test (void) + { + struct support_descriptors *descrs = support_descriptors_list (); + +- int lowfd = open_multiple_temp_files (); ++ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); + +- const int maximum_fd = lowfd + NFDS; ++ const int maximum_fd = lowfd + NFDS - 1; + const int half_fd = lowfd + NFDS / 2; +- const int gap = maximum_fd / 4; ++ const int gap = lowfd + NFDS / 4; + + /* Close half of the descriptors and check result. */ + closefrom (half_fd); +@@ -58,7 +49,7 @@ closefrom_test (void) + TEST_COMPARE (fcntl (i, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + } +- for (int i = 0; i < half_fd; i++) ++ for (int i = lowfd; i < half_fd; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + /* Create some gaps, close up to a threshold, and check result. */ +@@ -74,7 +65,7 @@ closefrom_test (void) + TEST_COMPARE (fcntl (i, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + } +- for (int i = 0; i < gap; i++) ++ for (int i = lowfd; i < gap; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + /* Close the remmaining but the last one. */ +diff --git a/posix/tst-spawn5.c b/posix/tst-spawn5.c +index ac6673800464ce72..a95199af6b3b7c9a 100644 +--- a/posix/tst-spawn5.c ++++ b/posix/tst-spawn5.c +@@ -47,17 +47,6 @@ static int initial_argv_count; + + #define NFDS 100 + +-static int +-open_multiple_temp_files (void) +-{ +- /* Check if the temporary file descriptor has no no gaps. */ +- int lowfd = xopen ("/dev/null", O_RDONLY, 0600); +- for (int i = 1; i <= NFDS; i++) +- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), +- lowfd + i); +- return lowfd; +-} +- + static int + parse_fd (const char *str) + { +@@ -185,7 +174,7 @@ spawn_closefrom_test (posix_spawn_file_actions_t *fa, int lowfd, int highfd, + static void + do_test_closefrom (void) + { +- int lowfd = open_multiple_temp_files (); ++ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); + const int half_fd = lowfd + NFDS / 2; + + /* Close half of the descriptors and check result. */ +diff --git a/sysdeps/unix/sysv/linux/tst-close_range.c b/sysdeps/unix/sysv/linux/tst-close_range.c +index dccb6189c53fcb90..f5069d1b8a067241 100644 +--- a/sysdeps/unix/sysv/linux/tst-close_range.c ++++ b/sysdeps/unix/sysv/linux/tst-close_range.c +@@ -36,23 +36,12 @@ + + #define NFDS 100 + +-static int +-open_multiple_temp_files (void) +-{ +- /* Check if the temporary file descriptor has no no gaps. */ +- int lowfd = xopen ("/dev/null", O_RDONLY, 0600); +- for (int i = 1; i <= NFDS; i++) +- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), +- lowfd + i); +- return lowfd; +-} +- + static void + close_range_test_max_upper_limit (void) + { + struct support_descriptors *descrs = support_descriptors_list (); + +- int lowfd = open_multiple_temp_files (); ++ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); + + { + int r = close_range (lowfd, ~0U, 0); +@@ -68,7 +57,7 @@ close_range_test_max_upper_limit (void) + static void + close_range_test_common (int lowfd, unsigned int flags) + { +- const int maximum_fd = lowfd + NFDS; ++ const int maximum_fd = lowfd + NFDS - 1; + const int half_fd = lowfd + NFDS / 2; + const int gap_1 = maximum_fd - 8; + +@@ -121,7 +110,7 @@ close_range_test (void) + struct support_descriptors *descrs = support_descriptors_list (); + + /* Check if the temporary file descriptor has no no gaps. */ +- int lowfd = open_multiple_temp_files (); ++ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); + + close_range_test_common (lowfd, 0); + +@@ -146,7 +135,7 @@ close_range_test_subprocess (void) + struct support_descriptors *descrs = support_descriptors_list (); + + /* Check if the temporary file descriptor has no no gaps. */ +- int lowfd = open_multiple_temp_files (); ++ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); + + struct support_stack stack = support_stack_alloc (4096); + +@@ -184,7 +173,7 @@ close_range_unshare_test (void) + struct support_descriptors *descrs1 = support_descriptors_list (); + + /* Check if the temporary file descriptor has no no gaps. */ +- int lowfd = open_multiple_temp_files (); ++ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); + + struct support_descriptors *descrs2 = support_descriptors_list (); + +@@ -200,7 +189,7 @@ close_range_unshare_test (void) + + support_stack_free (&stack); + +- for (int i = 0; i < NFDS; i++) ++ for (int i = lowfd; i < lowfd + NFDS; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + support_descriptors_check (descrs2); +@@ -226,9 +215,9 @@ static void + close_range_cloexec_test (void) + { + /* Check if the temporary file descriptor has no no gaps. */ +- const int lowfd = open_multiple_temp_files (); ++ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); + +- const int maximum_fd = lowfd + NFDS; ++ const int maximum_fd = lowfd + NFDS - 1; + const int half_fd = lowfd + NFDS / 2; + const int gap_1 = maximum_fd - 8; + +@@ -251,13 +240,13 @@ close_range_cloexec_test (void) + /* Create some gaps, close up to a threshold, and check result. */ + static int gap_close[] = { 57, 78, 81, 82, 84, 90 }; + for (int i = 0; i < array_length (gap_close); i++) +- xclose (gap_close[i]); ++ xclose (lowfd + gap_close[i]); + + TEST_COMPARE (close_range (half_fd + 1, gap_1, CLOSE_RANGE_CLOEXEC), 0); + for (int i = half_fd + 1; i < gap_1; i++) + { + int flags = fcntl (i, F_GETFD); +- if (is_in_array (gap_close, array_length (gap_close), i)) ++ if (is_in_array (gap_close, array_length (gap_close), i - lowfd)) + TEST_COMPARE (flags, -1); + else + { diff --git a/SOURCES/glibc-upstream-2.34-250.patch b/SOURCES/glibc-upstream-2.34-250.patch new file mode 100644 index 0000000..f552acc --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-250.patch @@ -0,0 +1,121 @@ +commit e7ca2a475cf2e7ffc987b8d08e1a40337840b500 +Author: Florian Weimer +Date: Mon May 9 18:15:16 2022 +0200 + + Linux: Implement a useful version of _startup_fatal + + On i386 and ia64, the TCB is not available at this point. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit a2a6bce7d7e52c1c34369a7da62c501cc350bc31) + +diff --git a/sysdeps/unix/sysv/linux/i386/startup.h b/sysdeps/unix/sysv/linux/i386/startup.h +index 192c765361c17ed1..213805d7d2d459be 100644 +--- a/sysdeps/unix/sysv/linux/i386/startup.h ++++ b/sysdeps/unix/sysv/linux/i386/startup.h +@@ -1,5 +1,5 @@ + /* Linux/i386 definitions of functions used by static libc main startup. +- Copyright (C) 2017-2021 Free Software Foundation, Inc. ++ Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -16,22 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if BUILD_PIE_DEFAULT +-/* Can't use "call *%gs:SYSINFO_OFFSET" during statup in static PIE. */ +-# define I386_USE_SYSENTER 0 ++/* Can't use "call *%gs:SYSINFO_OFFSET" during startup. */ ++#define I386_USE_SYSENTER 0 + +-# include +-# include +- +-__attribute__ ((__noreturn__)) +-static inline void +-_startup_fatal (const char *message __attribute__ ((unused))) +-{ +- /* This is only called very early during startup in static PIE. +- FIXME: How can it be improved? */ +- ABORT_INSTRUCTION; +- __builtin_unreachable (); +-} +-#else +-# include_next +-#endif ++#include_next +diff --git a/sysdeps/unix/sysv/linux/ia64/startup.h b/sysdeps/unix/sysv/linux/ia64/startup.h +new file mode 100644 +index 0000000000000000..77f29f15a2103ed5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/ia64/startup.h +@@ -0,0 +1,22 @@ ++/* Linux/ia64 definitions of functions used by static libc main startup. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This code is used before the TCB is set up. */ ++#define IA64_USE_NEW_STUB 0 ++ ++#include_next +diff --git a/sysdeps/unix/sysv/linux/startup.h b/sysdeps/unix/sysv/linux/startup.h +new file mode 100644 +index 0000000000000000..39859b404a84798b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/startup.h +@@ -0,0 +1,39 @@ ++/* Linux definitions of functions used by static libc main startup. ++ Copyright (C) 2017-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef SHARED ++# include_next ++#else ++# include ++ ++/* Avoid a run-time invocation of strlen. */ ++#define _startup_fatal(message) \ ++ do \ ++ { \ ++ size_t __message_length = __builtin_strlen (message); \ ++ if (! __builtin_constant_p (__message_length)) \ ++ { \ ++ extern void _startup_fatal_not_constant (void); \ ++ _startup_fatal_not_constant (); \ ++ } \ ++ INTERNAL_SYSCALL_CALL (write, STDERR_FILENO, (message), \ ++ __message_length); \ ++ INTERNAL_SYSCALL_CALL (exit_group, 127); \ ++ } \ ++ while (0) ++#endif /* !SHARED */ diff --git a/SOURCES/glibc-upstream-2.34-251.patch b/SOURCES/glibc-upstream-2.34-251.patch new file mode 100644 index 0000000..9f5a590 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-251.patch @@ -0,0 +1,150 @@ +commit 43d77ef9b87533221890423e491eed1b8ca81f0c +Author: Florian Weimer +Date: Mon May 16 18:41:43 2022 +0200 + + Linux: Introduce __brk_call for invoking the brk system call + + Alpha and sparc can now use the generic implementation. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit b57ab258c1140bc45464b4b9908713e3e0ee35aa) + +diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h b/sysdeps/unix/sysv/linux/alpha/brk_call.h +new file mode 100644 +index 0000000000000000..b8088cf13f938c88 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/alpha/brk_call.h +@@ -0,0 +1,28 @@ ++/* Invoke the brk system call. Alpha version. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++static inline void * ++__brk_call (void *addr) ++{ ++ unsigned long int result = INTERNAL_SYSCALL_CALL (brk, addr); ++ if (result == -ENOMEM) ++ /* Mimic the default error reporting behavior. */ ++ return addr; ++ else ++ return (void *) result; ++} +diff --git a/sysdeps/unix/sysv/linux/brk.c b/sysdeps/unix/sysv/linux/brk.c +index 2d70d824fc72d32d..20b11c15caae148d 100644 +--- a/sysdeps/unix/sysv/linux/brk.c ++++ b/sysdeps/unix/sysv/linux/brk.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + /* This must be initialized data because commons can't have aliases. */ + void *__curbrk = 0; +@@ -33,7 +34,7 @@ weak_alias (__curbrk, ___brk_addr) + int + __brk (void *addr) + { +- __curbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr); ++ __curbrk = __brk_call (addr); + if (__curbrk < addr) + { + __set_errno (ENOMEM); +diff --git a/sysdeps/unix/sysv/linux/brk_call.h b/sysdeps/unix/sysv/linux/brk_call.h +new file mode 100644 +index 0000000000000000..72370c25d785a9ab +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/brk_call.h +@@ -0,0 +1,25 @@ ++/* Invoke the brk system call. Generic Linux version. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++static inline void * ++__brk_call (void *addr) ++{ ++ /* The default implementation reports errors through an unchanged ++ break. */ ++ return (void *) INTERNAL_SYSCALL_CALL (brk, addr); ++} +diff --git a/sysdeps/unix/sysv/linux/alpha/brk.c b/sysdeps/unix/sysv/linux/sparc/brk_call.h +similarity index 61% +rename from sysdeps/unix/sysv/linux/alpha/brk.c +rename to sysdeps/unix/sysv/linux/sparc/brk_call.h +index 074c47e054bfeb11..59ce5216601143fb 100644 +--- a/sysdeps/unix/sysv/linux/alpha/brk.c ++++ b/sysdeps/unix/sysv/linux/sparc/brk_call.h +@@ -1,5 +1,5 @@ +-/* Change data segment size. Linux/Alpha. +- Copyright (C) 2020-2021 Free Software Foundation, Inc. ++/* Invoke the brk system call. Sparc version. ++ Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -16,23 +16,20 @@ + License along with the GNU C Library. If not, see + . */ + +-#include +-#include +-#include ++#ifdef __arch64__ ++# define SYSCALL_NUM "0x6d" ++#else ++# define SYSCALL_NUM "0x10" ++#endif + +-void *__curbrk = 0; +- +-int +-__brk (void *addr) ++static inline void * ++__brk_call (void *addr) + { +- /* Alpha brk returns -ENOMEM in case of failure. */ +- __curbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr); +- if ((unsigned long) __curbrk == -ENOMEM) +- { +- __set_errno (ENOMEM); +- return -1; +- } +- +- return 0; ++ register long int g1 asm ("g1") = __NR_brk; ++ register long int o0 asm ("o0") = (long int) addr; ++ asm volatile ("ta " SYSCALL_NUM ++ : "=r"(o0) ++ : "r"(g1), "0"(o0) ++ : "cc"); ++ return (void *) o0; + } +-weak_alias (__brk, brk) diff --git a/SOURCES/glibc-upstream-2.34-252.patch b/SOURCES/glibc-upstream-2.34-252.patch new file mode 100644 index 0000000..b607fcc --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-252.patch @@ -0,0 +1,510 @@ +commit ede8d94d154157d269b18f3601440ac576c1f96a +Author: Florian Weimer +Date: Mon May 16 18:41:43 2022 +0200 + + csu: Implement and use _dl_early_allocate during static startup + + This implements mmap fallback for a brk failure during TLS + allocation. + + scripts/tls-elf-edit.py is updated to support the new patching method. + The script no longer requires that in the input object is of ET_DYN + type. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit f787e138aa0bf677bf74fa2a08595c446292f3d7) + +Conflicts: + elf/Makefile + (missing ld.so static execve backport upstream) + sysdeps/generic/ldsodefs.h + (missing ld.so dependency sorting optimization upstream) + +diff --git a/csu/libc-tls.c b/csu/libc-tls.c +index d83e69f6257ae981..738f59f46b62c31c 100644 +--- a/csu/libc-tls.c ++++ b/csu/libc-tls.c +@@ -145,11 +145,16 @@ __libc_setup_tls (void) + _dl_allocate_tls_storage (in elf/dl-tls.c) does using __libc_memalign + and dl_tls_static_align. */ + tcb_offset = roundup (memsz + GLRO(dl_tls_static_surplus), max_align); +- tlsblock = __sbrk (tcb_offset + TLS_INIT_TCB_SIZE + max_align); ++ tlsblock = _dl_early_allocate (tcb_offset + TLS_INIT_TCB_SIZE + max_align); ++ if (tlsblock == NULL) ++ _startup_fatal ("Fatal glibc error: Cannot allocate TLS block\n"); + #elif TLS_DTV_AT_TP + tcb_offset = roundup (TLS_INIT_TCB_SIZE, align ?: 1); +- tlsblock = __sbrk (tcb_offset + memsz + max_align +- + TLS_PRE_TCB_SIZE + GLRO(dl_tls_static_surplus)); ++ tlsblock = _dl_early_allocate (tcb_offset + memsz + max_align ++ + TLS_PRE_TCB_SIZE ++ + GLRO(dl_tls_static_surplus)); ++ if (tlsblock == NULL) ++ _startup_fatal ("Fatal glibc error: Cannot allocate TLS block\n"); + tlsblock += TLS_PRE_TCB_SIZE; + #else + /* In case a model with a different layout for the TCB and DTV +diff --git a/elf/Makefile b/elf/Makefile +index 6423ebbdd7708a14..ea1512549be3f628 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -33,6 +33,7 @@ routines = \ + $(all-dl-routines) \ + dl-addr \ + dl-addr-obj \ ++ dl-early_allocate \ + dl-error \ + dl-iteratephdr \ + dl-libc \ +@@ -104,6 +105,7 @@ all-dl-routines = $(dl-routines) $(sysdep-dl-routines) + # But they are absent from the shared libc, because that code is in ld.so. + elide-routines.os = \ + $(all-dl-routines) \ ++ dl-early_allocate \ + dl-exception \ + dl-origin \ + dl-reloc-static-pie \ +@@ -264,6 +266,7 @@ tests-static-normal := \ + tst-linkall-static \ + tst-single_threaded-pthread-static \ + tst-single_threaded-static \ ++ tst-tls-allocation-failure-static \ + tst-tlsalign-extern-static \ + tst-tlsalign-static \ + # tests-static-normal +@@ -1101,6 +1104,10 @@ $(objpfx)tst-glibcelf.out: tst-glibcelf.py elf.h $(..)/scripts/glibcelf.py \ + --cc="$(CC) $(patsubst -DMODULE_NAME=%,-DMODULE_NAME=testsuite,$(CPPFLAGS))" \ + < /dev/null > $@ 2>&1; $(evaluate-test) + ++ifeq ($(run-built-tests),yes) ++tests-special += $(objpfx)tst-tls-allocation-failure-static-patched.out ++endif ++ + # The test requires shared _and_ PIE because the executable + # unit test driver must be able to link with the shared object + # that is going to eventually go into an installed DSO. +@@ -2637,3 +2644,15 @@ $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \ + $(objpfx)tst-ro-dynamic-mod.os + + $(objpfx)tst-rtld-run-static.out: $(objpfx)/ldconfig ++ ++$(objpfx)tst-tls-allocation-failure-static-patched: \ ++ $(objpfx)tst-tls-allocation-failure-static $(..)scripts/tst-elf-edit.py ++ cp $< $@ ++ $(PYTHON) $(..)scripts/tst-elf-edit.py --maximize-tls-size $@ ++ ++$(objpfx)tst-tls-allocation-failure-static-patched.out: \ ++ $(objpfx)tst-tls-allocation-failure-static-patched ++ $< > $@ 2>&1; echo "status: $$?" >> $@ ++ grep -q '^Fatal glibc error: Cannot allocate TLS block$$' $@ \ ++ && grep -q '^status: 127$$' $@; \ ++ $(evaluate-test) +diff --git a/elf/dl-early_allocate.c b/elf/dl-early_allocate.c +new file mode 100644 +index 0000000000000000..61677aaa0364c209 +--- /dev/null ++++ b/elf/dl-early_allocate.c +@@ -0,0 +1,30 @@ ++/* Early memory allocation for the dynamic loader. Generic version. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void * ++_dl_early_allocate (size_t size) ++{ ++ void *result = __sbrk (size); ++ if (result == (void *) -1) ++ result = NULL; ++ return result; ++} +diff --git a/elf/tst-tls-allocation-failure-static.c b/elf/tst-tls-allocation-failure-static.c +new file mode 100644 +index 0000000000000000..8de831b2469ba390 +--- /dev/null ++++ b/elf/tst-tls-allocation-failure-static.c +@@ -0,0 +1,31 @@ ++/* Base for test program with impossiblyh large PT_TLS segment. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* The test actual binary is patched using scripts/tst-elf-edit.py ++ --maximize-tls-size, and this introduces the expected test ++ allocation failure due to an excessive PT_LS p_memsz value. ++ ++ Patching the binary is required because on some 64-bit targets, TLS ++ relocations can only cover a 32-bit range, and glibc-internal TLS ++ variables such as errno end up outside that range. */ ++ ++int ++main (void) ++{ ++ return 0; ++} +diff --git a/scripts/tst-elf-edit.py b/scripts/tst-elf-edit.py +new file mode 100644 +index 0000000000000000..0e19ce1e7392f3ca +--- /dev/null ++++ b/scripts/tst-elf-edit.py +@@ -0,0 +1,226 @@ ++#!/usr/bin/python3 ++# ELF editor for load align tests. ++# Copyright (C) 2022 Free Software Foundation, Inc. ++# Copyright The GNU Toolchain Authors. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++import argparse ++import os ++import sys ++import struct ++ ++EI_NIDENT=16 ++ ++EI_MAG0=0 ++ELFMAG0=b'\x7f' ++EI_MAG1=1 ++ELFMAG1=b'E' ++EI_MAG2=2 ++ELFMAG2=b'L' ++EI_MAG3=3 ++ELFMAG3=b'F' ++ ++EI_CLASS=4 ++ELFCLASSNONE=b'0' ++ELFCLASS32=b'\x01' ++ELFCLASS64=b'\x02' ++ ++EI_DATA=5 ++ELFDATA2LSB=b'\x01' ++ELFDATA2MSB=b'\x02' ++ ++ET_EXEC=2 ++ET_DYN=3 ++ ++PT_LOAD=1 ++PT_TLS=7 ++ ++def elf_types_fmts(e_ident): ++ endian = '<' if e_ident[EI_DATA] == ELFDATA2LSB else '>' ++ addr = 'I' if e_ident[EI_CLASS] == ELFCLASS32 else 'Q' ++ off = 'I' if e_ident[EI_CLASS] == ELFCLASS32 else 'Q' ++ return (endian, addr, off) ++ ++class Elf_Ehdr: ++ def __init__(self, e_ident): ++ endian, addr, off = elf_types_fmts(e_ident) ++ self.fmt = '{0}HHI{1}{2}{2}IHHHHHH'.format(endian, addr, off) ++ self.len = struct.calcsize(self.fmt) ++ ++ def read(self, f): ++ buf = f.read(self.len) ++ if not buf: ++ error('{}: header too small'.format(f.name)) ++ data = struct.unpack(self.fmt, buf) ++ self.e_type = data[0] ++ self.e_machine = data[1] ++ self.e_version = data[2] ++ self.e_entry = data[3] ++ self.e_phoff = data[4] ++ self.e_shoff = data[5] ++ self.e_flags = data[6] ++ self.e_ehsize = data[7] ++ self.e_phentsize= data[8] ++ self.e_phnum = data[9] ++ self.e_shstrndx = data[10] ++ ++ ++class Elf_Phdr: ++ def __init__(self, e_ident): ++ endian, addr, off = elf_types_fmts(e_ident) ++ self.ei_class = e_ident[EI_CLASS] ++ if self.ei_class == ELFCLASS32: ++ self.fmt = '{0}I{2}{1}{1}IIII'.format(endian, addr, off) ++ else: ++ self.fmt = '{0}II{2}{1}{1}QQQ'.format(endian, addr, off) ++ self.len = struct.calcsize(self.fmt) ++ ++ def read(self, f): ++ buf = f.read(self.len) ++ if len(buf) < self.len: ++ error('{}: program header too small'.format(f.name)) ++ data = struct.unpack(self.fmt, buf) ++ if self.ei_class == ELFCLASS32: ++ self.p_type = data[0] ++ self.p_offset = data[1] ++ self.p_vaddr = data[2] ++ self.p_paddr = data[3] ++ self.p_filesz = data[4] ++ self.p_memsz = data[5] ++ self.p_flags = data[6] ++ self.p_align = data[7] ++ else: ++ self.p_type = data[0] ++ self.p_flags = data[1] ++ self.p_offset = data[2] ++ self.p_vaddr = data[3] ++ self.p_paddr = data[4] ++ self.p_filesz = data[5] ++ self.p_memsz = data[6] ++ self.p_align = data[7] ++ ++ def write(self, f): ++ if self.ei_class == ELFCLASS32: ++ data = struct.pack(self.fmt, ++ self.p_type, ++ self.p_offset, ++ self.p_vaddr, ++ self.p_paddr, ++ self.p_filesz, ++ self.p_memsz, ++ self.p_flags, ++ self.p_align) ++ else: ++ data = struct.pack(self.fmt, ++ self.p_type, ++ self.p_flags, ++ self.p_offset, ++ self.p_vaddr, ++ self.p_paddr, ++ self.p_filesz, ++ self.p_memsz, ++ self.p_align) ++ f.write(data) ++ ++ ++def error(msg): ++ print(msg, file=sys.stderr) ++ sys.exit(1) ++ ++ ++def elf_edit_align(phdr, align): ++ if align == 'half': ++ phdr.p_align = phdr.p_align >> 1 ++ else: ++ phdr.p_align = int(align) ++ ++def elf_edit_maximize_tls_size(phdr, elfclass): ++ if elfclass == ELFCLASS32: ++ # It is possible that the kernel can allocate half of the ++ # address space, so use something larger. ++ phdr.p_memsz = 0xfff00000 ++ else: ++ phdr.p_memsz = 1 << 63 ++ ++def elf_edit(f, opts): ++ ei_nident_fmt = 'c' * EI_NIDENT ++ ei_nident_len = struct.calcsize(ei_nident_fmt) ++ ++ data = f.read(ei_nident_len) ++ if len(data) < ei_nident_len: ++ error('{}: e_nident too small'.format(f.name)) ++ e_ident = struct.unpack(ei_nident_fmt, data) ++ ++ if e_ident[EI_MAG0] != ELFMAG0 \ ++ or e_ident[EI_MAG1] != ELFMAG1 \ ++ or e_ident[EI_MAG2] != ELFMAG2 \ ++ or e_ident[EI_MAG3] != ELFMAG3: ++ error('{}: bad ELF header'.format(f.name)) ++ ++ if e_ident[EI_CLASS] != ELFCLASS32 \ ++ and e_ident[EI_CLASS] != ELFCLASS64: ++ error('{}: unsupported ELF class: {}'.format(f.name, e_ident[EI_CLASS])) ++ ++ if e_ident[EI_DATA] != ELFDATA2LSB \ ++ and e_ident[EI_DATA] != ELFDATA2MSB: \ ++ error('{}: unsupported ELF data: {}'.format(f.name, e_ident[EI_DATA])) ++ ++ ehdr = Elf_Ehdr(e_ident) ++ ehdr.read(f) ++ if ehdr.e_type not in (ET_EXEC, ET_DYN): ++ error('{}: not an executable or shared library'.format(f.name)) ++ ++ phdr = Elf_Phdr(e_ident) ++ maximize_tls_size_done = False ++ for i in range(0, ehdr.e_phnum): ++ f.seek(ehdr.e_phoff + i * phdr.len) ++ phdr.read(f) ++ if phdr.p_type == PT_LOAD and opts.align is not None: ++ elf_edit_align(phdr, opts.align) ++ f.seek(ehdr.e_phoff + i * phdr.len) ++ phdr.write(f) ++ break ++ if phdr.p_type == PT_TLS and opts.maximize_tls_size: ++ elf_edit_maximize_tls_size(phdr, e_ident[EI_CLASS]) ++ f.seek(ehdr.e_phoff + i * phdr.len) ++ phdr.write(f) ++ maximize_tls_size_done = True ++ break ++ ++ if opts.maximize_tls_size and not maximize_tls_size_done: ++ error('{}: TLS maximum size was not updated'.format(f.name)) ++ ++def get_parser(): ++ parser = argparse.ArgumentParser(description=__doc__) ++ parser.add_argument('-a', dest='align', ++ help='How to set the LOAD alignment') ++ parser.add_argument('--maximize-tls-size', action='store_true', ++ help='Set maximum PT_TLS size') ++ parser.add_argument('output', ++ help='ELF file to edit') ++ return parser ++ ++ ++def main(argv): ++ parser = get_parser() ++ opts = parser.parse_args(argv) ++ with open(opts.output, 'r+b') as fout: ++ elf_edit(fout, opts) ++ ++ ++if __name__ == '__main__': ++ main(sys.argv[1:]) +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index a38de94bf7ea8e93..87ad2f3f4d89eb7d 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1238,6 +1238,11 @@ extern struct link_map * _dl_get_dl_main_map (void) + /* Initialize the DSO sort algorithm to use. */ + extern void _dl_sort_maps_init (void) attribute_hidden; + ++/* Perform early memory allocation, avoding a TCB dependency. ++ Terminate the process if allocation fails. May attempt to use ++ brk. */ ++void *_dl_early_allocate (size_t size) attribute_hidden; ++ + /* Initialization of libpthread for statically linked applications. + If libpthread is not linked in, this is an empty function. */ + void __pthread_initialize_minimal (void) weak_function; +diff --git a/sysdeps/unix/sysv/linux/dl-early_allocate.c b/sysdeps/unix/sysv/linux/dl-early_allocate.c +new file mode 100644 +index 0000000000000000..52c538e85afa8522 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/dl-early_allocate.c +@@ -0,0 +1,82 @@ ++/* Early memory allocation for the dynamic loader. Generic version. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Mark symbols hidden in static PIE for early self relocation to work. */ ++#if BUILD_PIE_DEFAULT ++# pragma GCC visibility push(hidden) ++#endif ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* Defined in brk.c. */ ++extern void *__curbrk; ++ ++void * ++_dl_early_allocate (size_t size) ++{ ++ void *result; ++ ++ if (__curbrk != NULL) ++ /* If the break has been initialized, brk must have run before, ++ so just call it once more. */ ++ { ++ result = __sbrk (size); ++ if (result == (void *) -1) ++ result = NULL; ++ } ++ else ++ { ++ /* If brk has not been invoked, there is no need to update ++ __curbrk. The first call to brk will take care of that. */ ++ void *previous = __brk_call (0); ++ result = __brk_call (previous + size); ++ if (result == previous) ++ result = NULL; ++ else ++ result = previous; ++ } ++ ++ /* If brk fails, fall back to mmap. This can happen due to ++ unfortunate ASLR layout decisions and kernel bugs, particularly ++ for static PIE. */ ++ if (result == NULL) ++ { ++ long int ret; ++ int prot = PROT_READ | PROT_WRITE; ++ int flags = MAP_PRIVATE | MAP_ANONYMOUS; ++#ifdef __NR_mmap2 ++ ret = MMAP_CALL_INTERNAL (mmap2, 0, size, prot, flags, -1, 0); ++#else ++ ret = MMAP_CALL_INTERNAL (mmap, 0, size, prot, flags, -1, 0); ++#endif ++ if (INTERNAL_SYSCALL_ERROR_P (ret)) ++ result = NULL; ++ else ++ result = (void *) ret; ++ } ++ ++ return result; ++} diff --git a/SOURCES/glibc-upstream-2.34-253.patch b/SOURCES/glibc-upstream-2.34-253.patch new file mode 100644 index 0000000..2be9efc --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-253.patch @@ -0,0 +1,350 @@ +commit 89b638f48ac5c9af5b1fe9caa6287d70127b66a5 +Author: Stefan Liebler +Date: Tue May 17 16:12:18 2022 +0200 + + S390: Enable static PIE + + This commit enables static PIE on 64bit. On 31bit, static PIE is + not supported. + + A new configure check in sysdeps/s390/s390-64/configure.ac also performs + a minimal test for requirements in ld: + Ensure you also have those patches for: + - binutils (ld) + - "[PR ld/22263] s390: Avoid dynamic TLS relocs in PIE" + https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=26b1426577b5dcb32d149c64cca3e603b81948a9 + (Tested by configure check above) + Otherwise there will be a R_390_TLS_TPOFF relocation, which fails to + be processed in _dl_relocate_static_pie() as static TLS map is not setup. + - "s390: Add DT_JMPREL pointing to .rela.[i]plt with static-pie" + https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d942d8db12adf4c9e5c7d9ed6496a779ece7149e + (We can't test it in configure as we are not able to link a static PIE + executable if the system glibc lacks static PIE support) + Otherwise there won't be DT_JMPREL, DT_PLTRELA, DT_PLTRELASZ entries + and the IFUNC symbols are not processed, which leads to crashes. + + - kernel (the mentioned links to the commits belong to 5.19 merge window): + - "s390/mmap: increase stack/mmap gap to 128MB" + https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2 + - "s390/vdso: move vdso mapping to its own function" + https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8 + - "s390/vdso: map vdso above stack" + https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033 + - "s390/vdso: add vdso randomization" + https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25 + (We can't test the kernel of the target system) + Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0), + static PIE executables like ldconfig will crash. While startup sbrk is + used to enlarge the HEAP. Unfortunately the underlying brk syscall fails + as there is not enough space after the HEAP. Then the address of the TLS + image is invalid and the following memcpy in __libc_setup_tls() leads + to a segfault. + If /proc/sys/kernel/randomize_va_space is activated (default: 2), there + is enough space after HEAP. + + - glibc + - "Linux: Define MMAP_CALL_INTERNAL" + https://sourceware.org/git/?p=glibc.git;a=commit;h=c1b68685d438373efe64e5f076f4215723004dfb + - "i386: Remove OPTIMIZE_FOR_GCC_5 from Linux libc-do-syscall.S" + https://sourceware.org/git/?p=glibc.git;a=commit;h=6e5c7a1e262961adb52443ab91bd2c9b72316402 + - "i386: Honor I386_USE_SYSENTER for 6-argument Linux system calls" + https://sourceware.org/git/?p=glibc.git;a=commit;h=60f0f2130d30cfd008ca39743027f1e200592dff + - "ia64: Always define IA64_USE_NEW_STUB as a flag macro" + https://sourceware.org/git/?p=glibc.git;a=commit;h=18bd9c3d3b1b6a9182698c85354578d1d58e9d64 + - "Linux: Implement a useful version of _startup_fatal" + https://sourceware.org/git/?p=glibc.git;a=commit;h=a2a6bce7d7e52c1c34369a7da62c501cc350bc31 + - "Linux: Introduce __brk_call for invoking the brk system call" + https://sourceware.org/git/?p=glibc.git;a=commit;h=b57ab258c1140bc45464b4b9908713e3e0ee35aa + - "csu: Implement and use _dl_early_allocate during static startup" + https://sourceware.org/git/?p=glibc.git;a=commit;h=f787e138aa0bf677bf74fa2a08595c446292f3d7 + The mentioned patch series by Florian Weimer avoids the mentioned failing + sbrk syscall by falling back to mmap. + + This commit also adjusts startup code in start.S to be ready for static PIE. + We have to add a wrapper function for main as we are not allowed to use + GOT relocations before __libc_start_main is called. + (Compare also to: + - commit 14d886edbd3d80b771e1c42fbd9217f9074de9c6 + "aarch64: fix start code for static pie" + - commit 3d1d79283e6de4f7c434cb67fb53a4fd28359669 + "aarch64: fix static pie enabled libc when main is in a shared library" + ) + + (cherry picked from commit 728894dba4a19578bd803906de184a8dd51ed13c) + +diff --git a/sysdeps/s390/s390-64/configure b/sysdeps/s390/s390-64/configure +new file mode 100644 +index 0000000000000000..101c570d2e62da25 +--- /dev/null ++++ b/sysdeps/s390/s390-64/configure +@@ -0,0 +1,122 @@ ++# This file is generated from configure.ac by Autoconf. DO NOT EDIT! ++ # Local configure fragment for sysdeps/s390/s390-64. ++ ++# Minimal checking for static PIE support in ld. ++# Compare to ld testcase/bugzilla: ++# /ld/testsuite/ld-elf/pr22263-1.rd ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for s390-specific static PIE requirements" >&5 ++$as_echo_n "checking for s390-specific static PIE requirements... " >&6; } ++if { as_var=\ ++libc_cv_s390x_staticpie_req; eval \${$as_var+:} false; }; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest1.c < conftest2.c <&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } \ ++ && { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIE -c conftest2.c -o conftest2.o' ++ { { 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; }; } \ ++ && { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -pie -o conftest conftest1.o conftest2.o' ++ { { 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; }; } \ ++ && { ac_try='! readelf -Wr conftest | grep R_390_TLS_TPOFF' ++ { { 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_s390x_staticpie_req=yes ++ fi ++ rm -rf conftest.* ++fi ++eval ac_res=\$\ ++libc_cv_s390x_staticpie_req ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++if test $libc_cv_s390x_staticpie_req = yes; then ++ # Static PIE is supported only on 64bit. ++ # Ensure you also have those patches for: ++ # - binutils (ld) ++ # - "[PR ld/22263] s390: Avoid dynamic TLS relocs in PIE" ++ # https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=26b1426577b5dcb32d149c64cca3e603b81948a9 ++ # (Tested by configure check above) ++ # Otherwise there will be a R_390_TLS_TPOFF relocation, which fails to ++ # be processed in _dl_relocate_static_pie() as static TLS map is not setup. ++ # - "s390: Add DT_JMPREL pointing to .rela.[i]plt with static-pie" ++ # https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d942d8db12adf4c9e5c7d9ed6496a779ece7149e ++ # (We can't test it in configure as we are not able to link a static PIE ++ # executable if the system glibc lacks static PIE support) ++ # Otherwise there won't be DT_JMPREL, DT_PLTRELA, DT_PLTRELASZ entries ++ # and the IFUNC symbols are not processed, which leads to crashes. ++ # ++ # - kernel (the mentioned links to the commits belong to 5.19 merge window): ++ # - "s390/mmap: increase stack/mmap gap to 128MB" ++ # https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2 ++ # - "s390/vdso: move vdso mapping to its own function" ++ # https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8 ++ # - "s390/vdso: map vdso above stack" ++ # https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033 ++ # - "s390/vdso: add vdso randomization" ++ # https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25 ++ # (We can't test the kernel of the target system) ++ # Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0), ++ # static PIE executables like ldconfig will crash. While startup sbrk is ++ # used to enlarge the HEAP. Unfortunately the underlying brk syscall fails ++ # as there is not enough space after the HEAP. Then the address of the TLS ++ # image is invalid and the following memcpy in __libc_setup_tls() leads ++ # to a segfault. ++ # If /proc/sys/kernel/randomize_va_space is activated (default: 2), there ++ # is enough space after HEAP. ++ # ++ # - glibc ++ # - "Linux: Define MMAP_CALL_INTERNAL" ++ # https://sourceware.org/git/?p=glibc.git;a=commit;h=c1b68685d438373efe64e5f076f4215723004dfb ++ # - "i386: Remove OPTIMIZE_FOR_GCC_5 from Linux libc-do-syscall.S" ++ # https://sourceware.org/git/?p=glibc.git;a=commit;h=6e5c7a1e262961adb52443ab91bd2c9b72316402 ++ # - "i386: Honor I386_USE_SYSENTER for 6-argument Linux system calls" ++ # https://sourceware.org/git/?p=glibc.git;a=commit;h=60f0f2130d30cfd008ca39743027f1e200592dff ++ # - "ia64: Always define IA64_USE_NEW_STUB as a flag macro" ++ # https://sourceware.org/git/?p=glibc.git;a=commit;h=18bd9c3d3b1b6a9182698c85354578d1d58e9d64 ++ # - "Linux: Implement a useful version of _startup_fatal" ++ # https://sourceware.org/git/?p=glibc.git;a=commit;h=a2a6bce7d7e52c1c34369a7da62c501cc350bc31 ++ # - "Linux: Introduce __brk_call for invoking the brk system call" ++ # https://sourceware.org/git/?p=glibc.git;a=commit;h=b57ab258c1140bc45464b4b9908713e3e0ee35aa ++ # - "csu: Implement and use _dl_early_allocate during static startup" ++ # https://sourceware.org/git/?p=glibc.git;a=commit;h=f787e138aa0bf677bf74fa2a08595c446292f3d7 ++ # The mentioned patch series by Florian Weimer avoids the mentioned failing ++ # sbrk syscall by falling back to mmap. ++ $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h ++ ++fi +diff --git a/sysdeps/s390/s390-64/configure.ac b/sysdeps/s390/s390-64/configure.ac +new file mode 100644 +index 0000000000000000..2583a4a3350ac11f +--- /dev/null ++++ b/sysdeps/s390/s390-64/configure.ac +@@ -0,0 +1,92 @@ ++GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. ++# Local configure fragment for sysdeps/s390/s390-64. ++ ++# Minimal checking for static PIE support in ld. ++# Compare to ld testcase/bugzilla: ++# /ld/testsuite/ld-elf/pr22263-1.rd ++AC_CACHE_CHECK([for s390-specific static PIE requirements], \ ++[libc_cv_s390x_staticpie_req], [dnl ++ cat > conftest1.c < conftest2.c < Scrt1.o */ + larl %r2,main@GOTENT # load pointer to main + lg %r2,0(%r2) ++# else ++ /* Used for dynamic linked position dependent executable. ++ => crt1.o (glibc configured without --disable-default-pie: ++ PIC is defined) ++ Or for static linked position independent executable. ++ => rcrt1.o (only available if glibc configured without ++ --disable-default-pie: PIC is defined) */ ++ larl %r2,__wrap_main ++# endif + brasl %r14,__libc_start_main@plt + #else ++ /* Used for dynamic/static linked position dependent executable. ++ => crt1.o (glibc configured with --disable-default-pie: ++ PIC and SHARED are not defined) */ + larl %r2,main # load pointer to main + brasl %r14,__libc_start_main + #endif +@@ -98,6 +113,19 @@ _start: + + cfi_endproc + ++#if defined PIC && !defined SHARED ++ /* When main is not defined in the executable but in a shared library ++ then a wrapper is needed in crt1.o of the static-pie enabled libc, ++ because crt1.o and rcrt1.o share code and the later must avoid the ++ use of GOT relocations before __libc_start_main is called. */ ++__wrap_main: ++ cfi_startproc ++ larl %r1,main@GOTENT # load pointer to main ++ lg %r1,0(%r1) ++ br %r1 ++ cfi_endproc ++#endif ++ + /* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start diff --git a/SOURCES/glibc-upstream-2.34-254.patch b/SOURCES/glibc-upstream-2.34-254.patch new file mode 100644 index 0000000..be69b2f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-254.patch @@ -0,0 +1,301 @@ +commit c73c79af7d6f1124fbfa5d935b4f620217d6a2ec +Author: Szabolcs Nagy +Date: Fri Jun 15 16:14:58 2018 +0100 + + rtld: Use generic argv adjustment in ld.so [BZ #23293] + + When an executable is invoked as + + ./ld.so [ld.so-args] ./exe [exe-args] + + then the argv is adujusted in ld.so before calling the entry point of + the executable so ld.so args are not visible to it. On most targets + this requires moving argv, env and auxv on the stack to ensure correct + stack alignment at the entry point. This had several issues: + + - The code for this adjustment on the stack is written in asm as part + of the target specific ld.so _start code which is hard to maintain. + + - The adjustment is done after _dl_start returns, where it's too late + to update GLRO(dl_auxv), as it is already readonly, so it points to + memory that was clobbered by the adjustment. This is bug 23293. + + - _environ is also wrong in ld.so after the adjustment, but it is + likely not used after _dl_start returns so this is not user visible. + + - _dl_argv was updated, but for this it was moved out of relro, which + changes security properties across targets unnecessarily. + + This patch introduces a generic _dl_start_args_adjust function that + handles the argument adjustments after ld.so processed its own args + and before relro protection is applied. + + The same algorithm is used on all targets, _dl_skip_args is now 0, so + existing target specific adjustment code is no longer used. The bug + affects aarch64, alpha, arc, arm, csky, ia64, nios2, s390-32 and sparc, + other targets don't need the change in principle, only for consistency. + + The GNU Hurd start code relied on _dl_skip_args after dl_main returned, + now it checks directly if args were adjusted and fixes the Hurd startup + data accordingly. + + Follow up patches can remove _dl_skip_args and DL_ARGV_NOT_RELRO. + + Tested on aarch64-linux-gnu and cross tested on i686-gnu. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit ad43cac44a6860eaefcadadfb2acb349921e96bf) + +Conflicts: + elf/rtld.c + (Downstream-only backport of glibc-rh2023422-1.patch) + +diff --git a/elf/rtld.c b/elf/rtld.c +index 434fbeddd5cce74d..9de53ccaed420a57 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1121,6 +1121,62 @@ rtld_chain_load (struct link_map *main_map, char *argv0) + rtld_soname, pathname, errcode); + } + ++/* Adjusts the contents of the stack and related globals for the user ++ entry point. The ld.so processed skip_args arguments and bumped ++ _dl_argv and _dl_argc accordingly. Those arguments are removed from ++ argv here. */ ++static void ++_dl_start_args_adjust (int skip_args) ++{ ++ void **sp = (void **) (_dl_argv - skip_args - 1); ++ void **p = sp + skip_args; ++ ++ if (skip_args == 0) ++ return; ++ ++ /* Sanity check. */ ++ intptr_t argc = (intptr_t) sp[0] - skip_args; ++ assert (argc == _dl_argc); ++ ++ /* Adjust argc on stack. */ ++ sp[0] = (void *) (intptr_t) _dl_argc; ++ ++ /* Update globals in rtld. */ ++ _dl_argv -= skip_args; ++ _environ -= skip_args; ++ ++ /* Shuffle argv down. */ ++ do ++ *++sp = *++p; ++ while (*p != NULL); ++ ++ assert (_environ == (char **) (sp + 1)); ++ ++ /* Shuffle envp down. */ ++ do ++ *++sp = *++p; ++ while (*p != NULL); ++ ++#ifdef HAVE_AUX_VECTOR ++ void **auxv = (void **) GLRO(dl_auxv) - skip_args; ++ GLRO(dl_auxv) = (ElfW(auxv_t) *) auxv; /* Aliasing violation. */ ++ assert (auxv == sp + 1); ++ ++ /* Shuffle auxv down. */ ++ ElfW(auxv_t) ax; ++ char *oldp = (char *) (p + 1); ++ char *newp = (char *) (sp + 1); ++ do ++ { ++ memcpy (&ax, oldp, sizeof (ax)); ++ memcpy (newp, &ax, sizeof (ax)); ++ oldp += sizeof (ax); ++ newp += sizeof (ax); ++ } ++ while (ax.a_type != AT_NULL); ++#endif ++} ++ + static void + dl_main (const ElfW(Phdr) *phdr, + ElfW(Word) phnum, +@@ -1177,6 +1233,7 @@ dl_main (const ElfW(Phdr) *phdr, + rtld_is_main = true; + + char *argv0 = NULL; ++ char **orig_argv = _dl_argv; + + /* Note the place where the dynamic linker actually came from. */ + GL(dl_rtld_map).l_name = rtld_progname; +@@ -1191,7 +1248,6 @@ dl_main (const ElfW(Phdr) *phdr, + GLRO(dl_lazy) = -1; + } + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } +@@ -1200,14 +1256,12 @@ dl_main (const ElfW(Phdr) *phdr, + if (state.mode != rtld_mode_help) + state.mode = rtld_mode_verify; + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } + else if (! strcmp (_dl_argv[1], "--inhibit-cache")) + { + GLRO(dl_inhibit_cache) = 1; +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } +@@ -1217,7 +1271,6 @@ dl_main (const ElfW(Phdr) *phdr, + state.library_path = _dl_argv[2]; + state.library_path_source = "--library-path"; + +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1226,7 +1279,6 @@ dl_main (const ElfW(Phdr) *phdr, + { + GLRO(dl_inhibit_rpath) = _dl_argv[2]; + +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1234,14 +1286,12 @@ dl_main (const ElfW(Phdr) *phdr, + { + audit_list_add_string (&state.audit_list, _dl_argv[2]); + +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } + else if (! strcmp (_dl_argv[1], "--preload") && _dl_argc > 2) + { + state.preloadarg = _dl_argv[2]; +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1249,7 +1299,6 @@ dl_main (const ElfW(Phdr) *phdr, + { + argv0 = _dl_argv[2]; + +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1257,7 +1306,6 @@ dl_main (const ElfW(Phdr) *phdr, + && _dl_argc > 2) + { + state.glibc_hwcaps_prepend = _dl_argv[2]; +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1265,7 +1313,6 @@ dl_main (const ElfW(Phdr) *phdr, + && _dl_argc > 2) + { + state.glibc_hwcaps_mask = _dl_argv[2]; +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1274,7 +1321,6 @@ dl_main (const ElfW(Phdr) *phdr, + { + state.mode = rtld_mode_list_tunables; + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } +@@ -1283,7 +1329,6 @@ dl_main (const ElfW(Phdr) *phdr, + { + state.mode = rtld_mode_list_diagnostics; + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } +@@ -1329,7 +1374,6 @@ dl_main (const ElfW(Phdr) *phdr, + _dl_usage (ld_so_name, NULL); + } + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + +@@ -1428,6 +1472,9 @@ dl_main (const ElfW(Phdr) *phdr, + /* Set the argv[0] string now that we've processed the executable. */ + if (argv0 != NULL) + _dl_argv[0] = argv0; ++ ++ /* Adjust arguments for the application entry point. */ ++ _dl_start_args_adjust (_dl_argv - orig_argv); + } + else + { +diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c +index 4b2072e5d5e3bfd2..5c0f8e46bfbd4753 100644 +--- a/sysdeps/mach/hurd/dl-sysdep.c ++++ b/sysdeps/mach/hurd/dl-sysdep.c +@@ -106,6 +106,7 @@ _dl_sysdep_start (void **start_argptr, + { + void go (intptr_t *argdata) + { ++ char *orig_argv0; + char **p; + + /* Cache the information in various global variables. */ +@@ -114,6 +115,8 @@ _dl_sysdep_start (void **start_argptr, + _environ = &_dl_argv[_dl_argc + 1]; + for (p = _environ; *p++;); /* Skip environ pointers and terminator. */ + ++ orig_argv0 = _dl_argv[0]; ++ + if ((void *) p == _dl_argv[0]) + { + static struct hurd_startup_data nodata; +@@ -204,30 +207,23 @@ unfmh(); /* XXX */ + + /* The call above might screw a few things up. + +- First of all, if _dl_skip_args is nonzero, we are ignoring +- the first few arguments. However, if we have no Hurd startup +- data, it is the magical convention that ARGV[0] == P. The ++ P is the location after the terminating NULL of the list of ++ environment variables. It has to point to the Hurd startup ++ data or if that's missing then P == ARGV[0] must hold. The + startup code in init-first.c will get confused if this is not + the case, so we must rearrange things to make it so. We'll +- overwrite the origional ARGV[0] at P with ARGV[_dl_skip_args]. ++ recompute P and move the Hurd data or the new ARGV[0] there. + +- Secondly, if we need to be secure, it removes some dangerous +- environment variables. If we have no Hurd startup date this +- changes P (since that's the location after the terminating +- NULL in the list of environment variables). We do the same +- thing as in the first case but make sure we recalculate P. +- If we do have Hurd startup data, we have to move the data +- such that it starts just after the terminating NULL in the +- environment list. ++ Note: directly invoked ld.so can move arguments and env vars. + + We use memmove, since the locations might overlap. */ +- if (__libc_enable_secure || _dl_skip_args) +- { +- char **newp; + +- for (newp = _environ; *newp++;); ++ char **newp; ++ for (newp = _environ; *newp++;); + +- if (_dl_argv[-_dl_skip_args] == (char *) p) ++ if (newp != p || _dl_argv[0] != orig_argv0) ++ { ++ if (orig_argv0 == (char *) p) + { + if ((char *) newp != _dl_argv[0]) + { diff --git a/SOURCES/glibc-upstream-2.34-255.patch b/SOURCES/glibc-upstream-2.34-255.patch new file mode 100644 index 0000000..aa679f3 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-255.patch @@ -0,0 +1,105 @@ +commit b2585cae2854d7d2868fb2e51e2796042c5e0679 +Author: Szabolcs Nagy +Date: Tue May 3 13:18:04 2022 +0100 + + linux: Add a getauxval test [BZ #23293] + + This is for bug 23293 and it relies on the glibc test system running + tests via explicit ld.so invokation by default. + + Reviewed-by: Florian Weimer + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 9faf5262c77487c96da8a3e961b88c0b1879e186) + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 0657f4003e7116c6..5c772f69d1b1f1f1 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -123,6 +123,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ + tst-close_range \ + tst-prctl \ + tst-scm_rights \ ++ tst-getauxval \ + # tests + + # Test for the symbol version of fcntl that was replaced in glibc 2.28. +diff --git a/sysdeps/unix/sysv/linux/tst-getauxval.c b/sysdeps/unix/sysv/linux/tst-getauxval.c +new file mode 100644 +index 0000000000000000..c4b619574369f4c5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-getauxval.c +@@ -0,0 +1,74 @@ ++/* Basic test for getauxval. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int missing; ++static int mismatch; ++ ++static void ++check_nonzero (unsigned long t, const char *s) ++{ ++ unsigned long v = getauxval (t); ++ printf ("%s: %lu (0x%lx)\n", s, v, v); ++ if (v == 0) ++ missing++; ++} ++ ++static void ++check_eq (unsigned long t, const char *s, unsigned long want) ++{ ++ unsigned long v = getauxval (t); ++ printf ("%s: %lu want: %lu\n", s, v, want); ++ if (v != want) ++ mismatch++; ++} ++ ++#define NZ(x) check_nonzero (x, #x) ++#define EQ(x, want) check_eq (x, #x, want) ++ ++static int ++do_test (void) ++{ ++ /* These auxv entries should be non-zero on Linux. */ ++ NZ (AT_PHDR); ++ NZ (AT_PHENT); ++ NZ (AT_PHNUM); ++ NZ (AT_PAGESZ); ++ NZ (AT_ENTRY); ++ NZ (AT_CLKTCK); ++ NZ (AT_RANDOM); ++ NZ (AT_EXECFN); ++ if (missing) ++ FAIL_EXIT1 ("Found %d missing auxv entries.\n", missing); ++ ++ /* Check against syscalls. */ ++ EQ (AT_UID, getuid ()); ++ EQ (AT_EUID, geteuid ()); ++ EQ (AT_GID, getgid ()); ++ EQ (AT_EGID, getegid ()); ++ if (mismatch) ++ FAIL_EXIT1 ("Found %d mismatching auxv entries.\n", mismatch); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-256.patch b/SOURCES/glibc-upstream-2.34-256.patch new file mode 100644 index 0000000..d92a5d0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-256.patch @@ -0,0 +1,39 @@ +commit 14770f3e0462721b317f138197e1fbf4db542c94 +Author: Sergei Trofimovich +Date: Mon May 23 13:56:43 2022 +0530 + + string.h: fix __fortified_attr_access macro call [BZ #29162] + + commit e938c0274 "Don't add access size hints to fortifiable functions" + converted a few '__attr_access ((...))' into '__fortified_attr_access (...)' + calls. + + But one of conversions had double parentheses of '__fortified_attr_access (...)'. + + Noticed as a gnat6 build failure: + + /<>-glibc-2.34-210-dev/include/bits/string_fortified.h:110:50: error: macro "__fortified_attr_access" requires 3 arguments, but only 1 given + + The change fixes parentheses. + + This is seen when using compilers that do not support + __builtin___stpncpy_chk, e.g. gcc older than 4.7, clang older than 2.6 + or some compiler not derived from gcc or clang. + + Signed-off-by: Sergei Trofimovich + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 5a5f94af0542f9a35aaa7992c18eb4e2403a29b9) + +diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h +index 218006c9ba882d9c..4e66e0bd1ebb572a 100644 +--- a/string/bits/string_fortified.h ++++ b/string/bits/string_fortified.h +@@ -107,7 +107,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) + # else + extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n, + size_t __destlen) __THROW +- __fortified_attr_access ((__write_only__, 1, 3)) ++ __fortified_attr_access (__write_only__, 1, 3) + __attr_access ((__read_only__, 2)); + extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src, + size_t __n), stpncpy); diff --git a/SOURCES/glibc-upstream-2.34-257.patch b/SOURCES/glibc-upstream-2.34-257.patch new file mode 100644 index 0000000..c9e1cd5 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-257.patch @@ -0,0 +1,51 @@ +commit 83ae8287c1c3009459ff29241b647ff61363b22c +Author: Noah Goldstein +Date: Tue Feb 15 08:18:15 2022 -0600 + + x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #29127] + + Re-cherry-pick commit c627209832 for strcmp-avx2.S change which was + omitted in intial cherry pick because at the time this bug was not + present on release branch. + + Fixes BZ #29127. + + In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would + call strcmp-avx2 and wcscmp-avx2 respectively. This would have + not checks around vzeroupper and would trigger spurious + aborts. This commit fixes that. + + test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on + AVX2 machines with and without RTM. + + Co-authored-by: H.J. Lu + (cherry picked from commit c6272098323153db373f2986c67786ea8c85f1cf) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S +index aa91f6e48a0e1ce5..a9806daadbbfd18b 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S +@@ -345,10 +345,10 @@ L(one_or_less): + movq %LOCALE_REG, %rdx + # endif + jb L(ret_zero) +-# ifdef USE_AS_WCSCMP + /* 'nbe' covers the case where length is negative (large + unsigned). */ +- jnbe __wcscmp_avx2 ++ jnbe OVERFLOW_STRCMP ++# ifdef USE_AS_WCSCMP + movl (%rdi), %edx + xorl %eax, %eax + cmpl (%rsi), %edx +@@ -357,10 +357,6 @@ L(one_or_less): + negl %eax + orl $1, %eax + # else +- /* 'nbe' covers the case where length is negative (large +- unsigned). */ +- +- jnbe __strcmp_avx2 + movzbl (%rdi), %eax + movzbl (%rsi), %ecx + TOLOWER_gpr (%rax, %eax) diff --git a/SOURCES/glibc-upstream-2.34-258.patch b/SOURCES/glibc-upstream-2.34-258.patch new file mode 100644 index 0000000..1f04c21 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-258.patch @@ -0,0 +1,737 @@ +commit ff450cdbdee0b8cb6b9d653d6d2fa892de29be31 +Author: Arjun Shankar +Date: Tue May 24 17:57:36 2022 +0200 + + Fix deadlock when pthread_atfork handler calls pthread_atfork or dlclose + + In multi-threaded programs, registering via pthread_atfork, + de-registering implicitly via dlclose, or running pthread_atfork + handlers during fork was protected by an internal lock. This meant + that a pthread_atfork handler attempting to register another handler or + dlclose a dynamically loaded library would lead to a deadlock. + + This commit fixes the deadlock in the following way: + + During the execution of handlers at fork time, the atfork lock is + released prior to the execution of each handler and taken again upon its + return. Any handler registrations or de-registrations that occurred + during the execution of the handler are accounted for before proceeding + with further handler execution. + + If a handler that hasn't been executed yet gets de-registered by another + handler during fork, it will not be executed. If a handler gets + registered by another handler during fork, it will not be executed + during that particular fork. + + The possibility that handlers may now be registered or deregistered + during handler execution means that identifying the next handler to be + run after a given handler may register/de-register others requires some + bookkeeping. The fork_handler struct has an additional field, 'id', + which is assigned sequentially during registration. Thus, handlers are + executed in ascending order of 'id' during 'prepare', and descending + order of 'id' during parent/child handler execution after the fork. + + Two tests are included: + + * tst-atfork3: Adhemerval Zanella + This test exercises calling dlclose from prepare, parent, and child + handlers. + + * tst-atfork4: This test exercises calling pthread_atfork and dlclose + from the prepare handler. + + [BZ #24595, BZ #27054] + + Co-authored-by: Adhemerval Zanella + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 52a103e237329b9f88a28513fe7506ffc3bd8ced) + +diff --git a/include/register-atfork.h b/include/register-atfork.h +index fadde14700947ac6..6d7bfd87688d6530 100644 +--- a/include/register-atfork.h ++++ b/include/register-atfork.h +@@ -26,6 +26,7 @@ struct fork_handler + void (*parent_handler) (void); + void (*child_handler) (void); + void *dso_handle; ++ uint64_t id; + }; + + /* Function to call to unregister fork handlers. */ +@@ -39,19 +40,18 @@ enum __run_fork_handler_type + atfork_run_parent + }; + +-/* Run the atfork handlers and lock/unlock the internal lock depending +- of the WHO argument: +- +- - atfork_run_prepare: run all the PREPARE_HANDLER in reverse order of +- insertion and locks the internal lock. +- - 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. +- +- Perform locking only if DO_LOCKING. */ +-extern void __run_fork_handlers (enum __run_fork_handler_type who, +- _Bool do_locking) attribute_hidden; ++/* Run the atfork prepare handlers in the reverse order of registration and ++ return the ID of the last registered handler. If DO_LOCKING is true, the ++ internal lock is held locked upon return. */ ++extern uint64_t __run_prefork_handlers (_Bool do_locking) attribute_hidden; ++ ++/* Given a handler type (parent or child), run all the atfork handlers in ++ the order of registration up to and including the handler with id equal ++ to LASTRUN. If DO_LOCKING is true, the internal lock is unlocked prior ++ to return. */ ++extern void __run_postfork_handlers (enum __run_fork_handler_type who, ++ _Bool do_locking, ++ uint64_t lastrun) attribute_hidden; + + /* C library side function to register new fork handlers. */ + extern int __register_atfork (void (*__prepare) (void), +diff --git a/posix/fork.c b/posix/fork.c +index 021691b9b7441f15..890b806eb48cb75a 100644 +--- a/posix/fork.c ++++ b/posix/fork.c +@@ -46,8 +46,9 @@ __libc_fork (void) + best effort to make is async-signal-safe at least for single-thread + case. */ + bool multiple_threads = __libc_single_threaded == 0; ++ uint64_t lastrun; + +- __run_fork_handlers (atfork_run_prepare, multiple_threads); ++ lastrun = __run_prefork_handlers (multiple_threads); + + struct nss_database_data nss_database_data; + +@@ -105,7 +106,7 @@ __libc_fork (void) + reclaim_stacks (); + + /* Run the handlers registered for the child. */ +- __run_fork_handlers (atfork_run_child, multiple_threads); ++ __run_postfork_handlers (atfork_run_child, multiple_threads, lastrun); + } + else + { +@@ -123,7 +124,7 @@ __libc_fork (void) + } + + /* Run the handlers registered for the parent. */ +- __run_fork_handlers (atfork_run_parent, multiple_threads); ++ __run_postfork_handlers (atfork_run_parent, multiple_threads, lastrun); + + if (pid < 0) + __set_errno (save_errno); +diff --git a/posix/register-atfork.c b/posix/register-atfork.c +index 6fd9e4c56aafd7cc..6370437aa68e039e 100644 +--- a/posix/register-atfork.c ++++ b/posix/register-atfork.c +@@ -19,6 +19,8 @@ + #include + #include + #include ++#include ++#include + + #define DYNARRAY_ELEMENT struct fork_handler + #define DYNARRAY_STRUCT fork_handler_list +@@ -27,7 +29,7 @@ + #include + + static struct fork_handler_list fork_handlers; +-static bool fork_handler_init = false; ++static uint64_t fork_handler_counter; + + static int atfork_lock = LLL_LOCK_INITIALIZER; + +@@ -37,11 +39,8 @@ __register_atfork (void (*prepare) (void), void (*parent) (void), + { + lll_lock (atfork_lock, LLL_PRIVATE); + +- if (!fork_handler_init) +- { +- fork_handler_list_init (&fork_handlers); +- fork_handler_init = true; +- } ++ if (fork_handler_counter == 0) ++ fork_handler_list_init (&fork_handlers); + + struct fork_handler *newp = fork_handler_list_emplace (&fork_handlers); + if (newp != NULL) +@@ -50,6 +49,13 @@ __register_atfork (void (*prepare) (void), void (*parent) (void), + newp->parent_handler = parent; + newp->child_handler = child; + newp->dso_handle = dso_handle; ++ ++ /* IDs assigned to handlers start at 1 and increment with handler ++ registration. Un-registering a handlers discards the corresponding ++ ID. It is not reused in future registrations. */ ++ if (INT_ADD_OVERFLOW (fork_handler_counter, 1)) ++ __libc_fatal ("fork handler counter overflow"); ++ newp->id = ++fork_handler_counter; + } + + /* Release the lock. */ +@@ -104,37 +110,111 @@ __unregister_atfork (void *dso_handle) + lll_unlock (atfork_lock, LLL_PRIVATE); + } + +-void +-__run_fork_handlers (enum __run_fork_handler_type who, _Bool do_locking) ++uint64_t ++__run_prefork_handlers (_Bool do_locking) + { +- struct fork_handler *runp; ++ uint64_t lastrun; + +- if (who == atfork_run_prepare) ++ if (do_locking) ++ lll_lock (atfork_lock, LLL_PRIVATE); ++ ++ /* We run prepare handlers from last to first. After fork, only ++ handlers up to the last handler found here (pre-fork) will be run. ++ Handlers registered during __run_prefork_handlers or ++ __run_postfork_handlers will be positioned after this last handler, and ++ since their prepare handlers won't be run now, their parent/child ++ handlers should also be ignored. */ ++ lastrun = fork_handler_counter; ++ ++ size_t sl = fork_handler_list_size (&fork_handlers); ++ for (size_t i = sl; i > 0;) + { +- 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--) +- { +- runp = fork_handler_list_at (&fork_handlers, i - 1); +- if (runp->prepare_handler != NULL) +- runp->prepare_handler (); +- } ++ struct fork_handler *runp ++ = fork_handler_list_at (&fork_handlers, i - 1); ++ ++ uint64_t id = runp->id; ++ ++ if (runp->prepare_handler != NULL) ++ { ++ if (do_locking) ++ lll_unlock (atfork_lock, LLL_PRIVATE); ++ ++ runp->prepare_handler (); ++ ++ if (do_locking) ++ lll_lock (atfork_lock, LLL_PRIVATE); ++ } ++ ++ /* We unlocked, ran the handler, and locked again. In the ++ meanwhile, one or more deregistrations could have occurred leading ++ to the current (just run) handler being moved up the list or even ++ removed from the list itself. Since handler IDs are guaranteed to ++ to be in increasing order, the next handler has to have: */ ++ ++ /* A. An earlier position than the current one has. */ ++ i--; ++ ++ /* B. A lower ID than the current one does. The code below skips ++ any newly added handlers with higher IDs. */ ++ while (i > 0 ++ && fork_handler_list_at (&fork_handlers, i - 1)->id >= id) ++ i--; + } +- else ++ ++ return lastrun; ++} ++ ++void ++__run_postfork_handlers (enum __run_fork_handler_type who, _Bool do_locking, ++ uint64_t lastrun) ++{ ++ size_t sl = fork_handler_list_size (&fork_handlers); ++ for (size_t i = 0; i < sl;) + { +- size_t sl = fork_handler_list_size (&fork_handlers); +- for (size_t i = 0; i < sl; i++) +- { +- runp = fork_handler_list_at (&fork_handlers, i); +- if (who == atfork_run_child && runp->child_handler) +- runp->child_handler (); +- else if (who == atfork_run_parent && runp->parent_handler) +- runp->parent_handler (); +- } ++ struct fork_handler *runp = fork_handler_list_at (&fork_handlers, i); ++ uint64_t id = runp->id; ++ ++ /* prepare handlers were not run for handlers with ID > LASTRUN. ++ Thus, parent/child handlers will also not be run. */ ++ if (id > lastrun) ++ break; ++ + if (do_locking) +- lll_unlock (atfork_lock, LLL_PRIVATE); ++ lll_unlock (atfork_lock, LLL_PRIVATE); ++ ++ if (who == atfork_run_child && runp->child_handler) ++ runp->child_handler (); ++ else if (who == atfork_run_parent && runp->parent_handler) ++ runp->parent_handler (); ++ ++ if (do_locking) ++ lll_lock (atfork_lock, LLL_PRIVATE); ++ ++ /* We unlocked, ran the handler, and locked again. In the meanwhile, ++ one or more [de]registrations could have occurred. Due to this, ++ the list size must be updated. */ ++ sl = fork_handler_list_size (&fork_handlers); ++ ++ /* The just-run handler could also have moved up the list. */ ++ ++ if (sl > i && fork_handler_list_at (&fork_handlers, i)->id == id) ++ /* The position of the recently run handler hasn't changed. The ++ next handler to be run is an easy increment away. */ ++ i++; ++ else ++ { ++ /* The next handler to be run is the first handler in the list ++ to have an ID higher than the current one. */ ++ for (i = 0; i < sl; i++) ++ { ++ if (fork_handler_list_at (&fork_handlers, i)->id > id) ++ break; ++ } ++ } + } ++ ++ if (do_locking) ++ lll_unlock (atfork_lock, LLL_PRIVATE); + } + + +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index 00419c4d199df912..5147588c130c9415 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -154,16 +154,36 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx6 tst-cancelx8 tst-cancelx9 \ + tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 + + ifeq ($(build-shared),yes) +-tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1 tst-create1 ++tests += \ ++ tst-atfork2 \ ++ tst-pt-tls4 \ ++ tst-_res1 \ ++ tst-fini1 \ ++ tst-create1 \ ++ tst-atfork3 \ ++ tst-atfork4 \ ++# tests ++ + tests-nolibpthread += tst-fini1 + endif + +-modules-names += tst-atfork2mod tst-tls4moda tst-tls4modb \ +- tst-_res1mod1 tst-_res1mod2 tst-fini1mod \ +- tst-create1mod ++modules-names += \ ++ tst-atfork2mod \ ++ tst-tls4moda \ ++ tst-tls4modb \ ++ tst-_res1mod1 \ ++ tst-_res1mod2 \ ++ tst-fini1mod \ ++ tst-create1mod \ ++ tst-atfork3mod \ ++ tst-atfork4mod \ ++# module-names ++ + test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names))) + + tst-atfork2mod.so-no-z-defs = yes ++tst-atfork3mod.so-no-z-defs = yes ++tst-atfork4mod.so-no-z-defs = yes + tst-create1mod.so-no-z-defs = yes + + ifeq ($(build-shared),yes) +@@ -226,8 +246,18 @@ tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace \ + LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so + $(objpfx)tst-atfork2mod.so: $(shared-thread-library) + ++$(objpfx)tst-atfork3: $(shared-thread-library) ++LDFLAGS-tst-atfork3 = -rdynamic ++$(objpfx)tst-atfork3mod.so: $(shared-thread-library) ++ ++$(objpfx)tst-atfork4: $(shared-thread-library) ++LDFLAGS-tst-atfork4 = -rdynamic ++$(objpfx)tst-atfork4mod.so: $(shared-thread-library) ++ + ifeq ($(build-shared),yes) + $(objpfx)tst-atfork2.out: $(objpfx)tst-atfork2mod.so ++$(objpfx)tst-atfork3.out: $(objpfx)tst-atfork3mod.so ++$(objpfx)tst-atfork4.out: $(objpfx)tst-atfork4mod.so + endif + + ifeq ($(build-shared),yes) +diff --git a/sysdeps/pthread/tst-atfork3.c b/sysdeps/pthread/tst-atfork3.c +new file mode 100644 +index 0000000000000000..bb2250e432ab79ad +--- /dev/null ++++ b/sysdeps/pthread/tst-atfork3.c +@@ -0,0 +1,118 @@ ++/* Check if pthread_atfork handler can call dlclose (BZ#24595). ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* Check if pthread_atfork handlers do not deadlock when calling a function ++ that might alter the internal fork handle list, such as dlclose. ++ ++ The test registers a callback set with pthread_atfork(), dlopen() a shared ++ library (nptl/tst-atfork3mod.c), calls an exported symbol from the library ++ (which in turn also registers atfork handlers), and calls fork to trigger ++ the callbacks. */ ++ ++static void *handler; ++static bool run_dlclose_prepare; ++static bool run_dlclose_parent; ++static bool run_dlclose_child; ++ ++static void ++prepare (void) ++{ ++ if (run_dlclose_prepare) ++ xdlclose (handler); ++} ++ ++static void ++parent (void) ++{ ++ if (run_dlclose_parent) ++ xdlclose (handler); ++} ++ ++static void ++child (void) ++{ ++ if (run_dlclose_child) ++ xdlclose (handler); ++} ++ ++static void ++proc_func (void *closure) ++{ ++} ++ ++static void ++do_test_generic (bool dlclose_prepare, bool dlclose_parent, bool dlclose_child) ++{ ++ run_dlclose_prepare = dlclose_prepare; ++ run_dlclose_parent = dlclose_parent; ++ run_dlclose_child = dlclose_child; ++ ++ handler = xdlopen ("tst-atfork3mod.so", RTLD_NOW); ++ ++ int (*atfork3mod_func)(void); ++ atfork3mod_func = xdlsym (handler, "atfork3mod_func"); ++ ++ atfork3mod_func (); ++ ++ struct support_capture_subprocess proc ++ = support_capture_subprocess (proc_func, NULL); ++ support_capture_subprocess_check (&proc, "tst-atfork3", 0, sc_allow_none); ++ ++ handler = atfork3mod_func = NULL; ++ ++ support_capture_subprocess_free (&proc); ++} ++ ++static void * ++thread_func (void *closure) ++{ ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ { ++ /* Make the process acts as multithread. */ ++ pthread_attr_t attr; ++ xpthread_attr_init (&attr); ++ xpthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); ++ xpthread_create (&attr, thread_func, NULL); ++ } ++ ++ TEST_COMPARE (pthread_atfork (prepare, parent, child), 0); ++ ++ do_test_generic (true /* prepare */, false /* parent */, false /* child */); ++ do_test_generic (false /* prepare */, true /* parent */, false /* child */); ++ do_test_generic (false /* prepare */, false /* parent */, true /* child */); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/pthread/tst-atfork3mod.c b/sysdeps/pthread/tst-atfork3mod.c +new file mode 100644 +index 0000000000000000..6d0658cb9efdecbc +--- /dev/null ++++ b/sysdeps/pthread/tst-atfork3mod.c +@@ -0,0 +1,44 @@ ++/* Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++ ++static void ++mod_prepare (void) ++{ ++} ++ ++static void ++mod_parent (void) ++{ ++} ++ ++static void ++mod_child (void) ++{ ++} ++ ++int atfork3mod_func (void) ++{ ++ TEST_COMPARE (pthread_atfork (mod_prepare, mod_parent, mod_child), 0); ++ ++ return 0; ++} +diff --git a/sysdeps/pthread/tst-atfork4.c b/sysdeps/pthread/tst-atfork4.c +new file mode 100644 +index 0000000000000000..52dc87e73b846ab9 +--- /dev/null ++++ b/sysdeps/pthread/tst-atfork4.c +@@ -0,0 +1,128 @@ ++/* pthread_atfork supports handlers that call pthread_atfork or dlclose. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void * ++thread_func (void *x) ++{ ++ return NULL; ++} ++ ++static unsigned int second_atfork_handler_runcount = 0; ++ ++static void ++second_atfork_handler (void) ++{ ++ second_atfork_handler_runcount++; ++} ++ ++static void *h = NULL; ++ ++static unsigned int atfork_handler_runcount = 0; ++ ++static void ++prepare (void) ++{ ++ /* These atfork handlers are registered while atfork handlers are being ++ executed and thus will not be executed during the corresponding ++ fork. */ ++ TEST_VERIFY_EXIT (pthread_atfork (second_atfork_handler, ++ second_atfork_handler, ++ second_atfork_handler) == 0); ++ ++ /* This will de-register the atfork handlers registered by the dlopen'd ++ library and so they will not be executed. */ ++ if (h != NULL) ++ { ++ xdlclose (h); ++ h = NULL; ++ } ++ ++ atfork_handler_runcount++; ++} ++ ++static void ++after (void) ++{ ++ atfork_handler_runcount++; ++} ++ ++static int ++do_test (void) ++{ ++ /* Make sure __libc_single_threaded is 0. */ ++ pthread_attr_t attr; ++ xpthread_attr_init (&attr); ++ xpthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); ++ xpthread_create (&attr, thread_func, NULL); ++ ++ void (*reg_atfork_handlers) (void); ++ ++ h = xdlopen ("tst-atfork4mod.so", RTLD_LAZY); ++ ++ reg_atfork_handlers = xdlsym (h, "reg_atfork_handlers"); ++ ++ reg_atfork_handlers (); ++ ++ /* We register our atfork handlers *after* loading the module so that our ++ prepare handler is called first at fork, where we then dlclose the ++ module before its prepare handler has a chance to be called. */ ++ TEST_VERIFY_EXIT (pthread_atfork (prepare, after, after) == 0); ++ ++ pid_t pid = xfork (); ++ ++ /* Both the parent and the child processes should observe this. */ ++ TEST_VERIFY_EXIT (atfork_handler_runcount == 2); ++ TEST_VERIFY_EXIT (second_atfork_handler_runcount == 0); ++ ++ if (pid > 0) ++ { ++ int childstat; ++ ++ xwaitpid (-1, &childstat, 0); ++ TEST_VERIFY_EXIT (WIFEXITED (childstat) ++ && WEXITSTATUS (childstat) == 0); ++ ++ /* This time, the second set of atfork handlers should also be called ++ since the handlers are already in place before fork is called. */ ++ ++ pid = xfork (); ++ ++ TEST_VERIFY_EXIT (atfork_handler_runcount == 4); ++ TEST_VERIFY_EXIT (second_atfork_handler_runcount == 2); ++ ++ if (pid > 0) ++ { ++ xwaitpid (-1, &childstat, 0); ++ TEST_VERIFY_EXIT (WIFEXITED (childstat) ++ && WEXITSTATUS (childstat) == 0); ++ } ++ } ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/pthread/tst-atfork4mod.c b/sysdeps/pthread/tst-atfork4mod.c +new file mode 100644 +index 0000000000000000..e111efeb185916e0 +--- /dev/null ++++ b/sysdeps/pthread/tst-atfork4mod.c +@@ -0,0 +1,48 @@ ++/* pthread_atfork supports handlers that call pthread_atfork or dlclose. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++/* This dynamically loaded library simply registers its atfork handlers when ++ asked to. The atfork handlers should never be executed because the ++ library is unloaded before fork is called by the test program. */ ++ ++static void ++prepare (void) ++{ ++ abort (); ++} ++ ++static void ++parent (void) ++{ ++ abort (); ++} ++ ++static void ++child (void) ++{ ++ abort (); ++} ++ ++void ++reg_atfork_handlers (void) ++{ ++ pthread_atfork (prepare, parent, child); ++} diff --git a/SOURCES/glibc-upstream-2.34-259.patch b/SOURCES/glibc-upstream-2.34-259.patch new file mode 100644 index 0000000..d0501b8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-259.patch @@ -0,0 +1,30 @@ +commit b349fe072275bfc5763110a49fe6ef1b44d60289 +Author: Adhemerval Zanella +Date: Tue May 31 11:46:59 2022 -0300 + + misc: Use 64 bit stat for daemon (BZ# 29203) + + This is a missing spot initially from 52a5fe70a2c77935. + + Checked on i686-linux-gnu. + + (cherry picked from commit 3fbc33010c76721d34f676d8efb45bcc54e0d575) + +diff --git a/misc/daemon.c b/misc/daemon.c +index 0e688f4d7482e335..3c73ac2ab8709812 100644 +--- a/misc/daemon.c ++++ b/misc/daemon.c +@@ -61,11 +61,10 @@ daemon (int nochdir, int noclose) + (void)__chdir("/"); + + if (!noclose) { +- struct stat64 st; ++ struct __stat64_t64 st; + + if ((fd = __open_nocancel(_PATH_DEVNULL, O_RDWR, 0)) != -1 +- && (__builtin_expect (__fstat64 (fd, &st), 0) +- == 0)) { ++ && __glibc_likely (__fstat64_time64 (fd, &st) == 0)) { + if (__builtin_expect (S_ISCHR (st.st_mode), 1) != 0 + #if defined DEV_NULL_MAJOR && defined DEV_NULL_MINOR + && (st.st_rdev diff --git a/SOURCES/glibc-upstream-2.34-26.patch b/SOURCES/glibc-upstream-2.34-26.patch new file mode 100644 index 0000000..4366808 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-26.patch @@ -0,0 +1,129 @@ +commit 33adeaa3e2b9143c38884bc5aa65ded222ed274e +Author: Florian Weimer +Date: Thu Sep 23 09:55:54 2021 +0200 + + nptl: Avoid setxid deadlock with blocked signals in thread exit [BZ #28361] + + As part of the fix for bug 12889, signals are blocked during + thread exit, so that application code cannot run on the thread that + is about to exit. This would cause problems if the application + expected signals to be delivered after the signal handler revealed + the thread to still exist, despite pthread_kill can no longer be used + to send signals to it. However, glibc internally uses the SIGSETXID + signal in a way that is incompatible with signal blocking, due to the + way the setxid handshake delays thread exit until the setxid operation + has completed. With a blocked SIGSETXID, the handshake can never + complete, causing a deadlock. + + As a band-aid, restore the previous handshake protocol by not blocking + SIGSETXID during thread exit. + + The new test sysdeps/pthread/tst-pthread-setuid-loop.c is based on + a downstream test by Martin Osvald. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 2849e2f53311b66853cb5159b64cba2bddbfb854) + +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index 33b426fc682300dc..bc213f0bc4e948bd 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -488,8 +488,16 @@ start_thread (void *arg) + + /* This prevents sending a signal from this thread to itself during + its final stages. This must come after the exit call above +- because atexit handlers must not run with signals blocked. */ +- __libc_signal_block_all (NULL); ++ because atexit handlers must not run with signals blocked. ++ ++ Do not block SIGSETXID. The setxid handshake below expects the ++ signal to be delivered. (SIGSETXID cannot run application code, ++ nor does it use pthread_kill.) Reuse the pd->sigmask space for ++ computing the signal mask, to save stack space. */ ++ __sigfillset (&pd->sigmask); ++ __sigdelset (&pd->sigmask, SIGSETXID); ++ INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_BLOCK, &pd->sigmask, NULL, ++ __NSIG_BYTES); + + /* Tell __pthread_kill_internal that this thread is about to exit. + If there is a __pthread_kill_internal in progress, this delays +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index 48dba717a1cdc20a..d4bd2d4e3ee6a496 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -118,6 +118,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-unload \ + tst-unwind-thread \ + tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ ++ tst-pthread-setuid-loop \ + tst-pthread_cancel-exited \ + tst-pthread_cancel-select-loop \ + tst-pthread_kill-exited \ +diff --git a/sysdeps/pthread/tst-pthread-setuid-loop.c b/sysdeps/pthread/tst-pthread-setuid-loop.c +new file mode 100644 +index 0000000000000000..fda2a49b7f0ccf81 +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread-setuid-loop.c +@@ -0,0 +1,61 @@ ++/* Test that setuid, pthread_create, thread exit do not deadlock (bug 28361). ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* How many threads to launch during each iteration. */ ++enum { threads = 4 }; ++ ++/* How many iterations to perform. This value seems to reproduce ++ bug 28361 in a bout one in three runs. */ ++enum { iterations = 5000 }; ++ ++/* Cache of the real user ID used by setuid_thread. */ ++static uid_t uid; ++ ++/* Start routine for the threads. */ ++static void * ++setuid_thread (void *closure) ++{ ++ TEST_COMPARE (setuid (uid), 0); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ /* The setxid machinery is still invoked even if the UID is ++ unchanged. (The kernel might reset other credentials as part of ++ the system call.) */ ++ uid = getuid (); ++ ++ for (int i = 0; i < iterations; ++i) ++ { ++ pthread_t thread_ids[threads]; ++ for (int j = 0; j < threads; ++j) ++ thread_ids[j] = xpthread_create (NULL, setuid_thread, NULL); ++ for (int j = 0; j < threads; ++j) ++ xpthread_join (thread_ids[j]); ++ } ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-260.patch b/SOURCES/glibc-upstream-2.34-260.patch new file mode 100644 index 0000000..95264aa --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-260.patch @@ -0,0 +1,34 @@ +commit aa8a87f51d7a1fb86ff75d3e3870316b6bc70dfe +Author: Adhemerval Zanella +Date: Tue May 31 11:51:46 2022 -0300 + + misc: Use 64 bit stat for getusershell (BZ# 29204) + + This is a missing spot initially from 52a5fe70a2c77935. + + Checked on i686-linux-gnu. + + (cherry picked from commit ec995fb2152f160f02bf695ff83c45df4a6cd868) + +diff --git a/misc/getusershell.c b/misc/getusershell.c +index 11f5aa83f888a114..4221095dca743dfa 100644 +--- a/misc/getusershell.c ++++ b/misc/getusershell.c +@@ -97,7 +97,7 @@ initshells (void) + { + char **sp, *cp; + FILE *fp; +- struct stat64 statb; ++ struct __stat64_t64 statb; + size_t flen; + + free(shells); +@@ -106,7 +106,7 @@ initshells (void) + strings = NULL; + if ((fp = fopen(_PATH_SHELLS, "rce")) == NULL) + goto init_okshells_noclose; +- if (__fstat64(fileno(fp), &statb) == -1) { ++ if (__fstat64_time64(fileno(fp), &statb) == -1) { + init_okshells: + (void)fclose(fp); + init_okshells_noclose: diff --git a/SOURCES/glibc-upstream-2.34-261.patch b/SOURCES/glibc-upstream-2.34-261.patch new file mode 100644 index 0000000..349d50d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-261.patch @@ -0,0 +1,56 @@ +commit 9db6a597ef950737d3cd7af0d4211291197b82dd +Author: Adhemerval Zanella +Date: Tue May 31 12:17:20 2022 -0300 + + posix: Use 64 bit stat for posix_fallocate fallback (BZ# 29207) + + This is a missing spot initially from 52a5fe70a2c77935. + + Checked on i686-linux-gnu. + + (cherry picked from commit 574ba60fc8a7fb35e6216e2fdecc521acab7ffd2) + +diff --git a/sysdeps/posix/posix_fallocate.c b/sysdeps/posix/posix_fallocate.c +index 0bb379c94d7cf779..4381033d6e16c2e3 100644 +--- a/sysdeps/posix/posix_fallocate.c ++++ b/sysdeps/posix/posix_fallocate.c +@@ -30,7 +30,7 @@ + int + posix_fallocate (int fd, __off_t offset, __off_t len) + { +- struct stat64 st; ++ struct __stat64_t64 st; + + if (offset < 0 || len < 0) + return EINVAL; +@@ -48,7 +48,7 @@ posix_fallocate (int fd, __off_t offset, __off_t len) + } + + /* We have to make sure that this is really a regular file. */ +- if (__fstat64 (fd, &st) != 0) ++ if (__fstat64_time64 (fd, &st) != 0) + return EBADF; + if (S_ISFIFO (st.st_mode)) + return ESPIPE; +diff --git a/sysdeps/posix/posix_fallocate64.c b/sysdeps/posix/posix_fallocate64.c +index c1e233b49c8d7f37..d45b0c17489fbbbb 100644 +--- a/sysdeps/posix/posix_fallocate64.c ++++ b/sysdeps/posix/posix_fallocate64.c +@@ -30,7 +30,7 @@ + int + __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len) + { +- struct stat64 st; ++ struct __stat64_t64 st; + + if (offset < 0 || len < 0) + return EINVAL; +@@ -48,7 +48,7 @@ __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len) + } + + /* We have to make sure that this is really a regular file. */ +- if (__fstat64 (fd, &st) != 0) ++ if (__fstat64_time64 (fd, &st) != 0) + return EBADF; + if (S_ISFIFO (st.st_mode)) + return ESPIPE; diff --git a/SOURCES/glibc-upstream-2.34-262.patch b/SOURCES/glibc-upstream-2.34-262.patch new file mode 100644 index 0000000..013d55c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-262.patch @@ -0,0 +1,28 @@ +commit f9c3e57ac25511db78f3d51a38f6a715be220479 +Author: Adhemerval Zanella +Date: Tue May 31 12:22:13 2022 -0300 + + posix: Use 64 bit stat for fpathconf (_PC_ASYNC_IO) (BZ# 29208) + + This is a missing spot initially from 52a5fe70a2c77935. + + Checked on i686-linux-gnu. + + (cherry picked from commit 6e7137f28c9d743d66b5a1cb8fa0d1717b96f853) + +diff --git a/sysdeps/posix/fpathconf.c b/sysdeps/posix/fpathconf.c +index ec0e780466756e00..e673f2016136679e 100644 +--- a/sysdeps/posix/fpathconf.c ++++ b/sysdeps/posix/fpathconf.c +@@ -131,9 +131,9 @@ __fpathconf (int fd, int name) + #ifdef _POSIX_ASYNC_IO + { + /* AIO is only allowed on regular files and block devices. */ +- struct stat64 st; ++ struct __stat64_t64 st; + +- if (__fstat64 (fd, &st) < 0 ++ if (__fstat64_time64 (fd, &st) < 0 + || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode))) + return -1; + else diff --git a/SOURCES/glibc-upstream-2.34-263.patch b/SOURCES/glibc-upstream-2.34-263.patch new file mode 100644 index 0000000..b2e79e1 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-263.patch @@ -0,0 +1,31 @@ +commit 61fd3e0e7495f597b41e90d3e045b8c3b182a23d +Author: Adhemerval Zanella +Date: Tue May 31 12:28:20 2022 -0300 + + socket: Use 64 bit stat for isfdtype (BZ# 29209) + + This is a missing spot initially from 52a5fe70a2c77935. + + Checked on i686-linux-gnu. + + (cherry picked from commit 87f1ec12e79a3895b33801fa816884f0d24ae7ef) + +diff --git a/sysdeps/posix/isfdtype.c b/sysdeps/posix/isfdtype.c +index 06b5386c4379063d..f18bcfef224ebac6 100644 +--- a/sysdeps/posix/isfdtype.c ++++ b/sysdeps/posix/isfdtype.c +@@ -24,12 +24,12 @@ + int + isfdtype (int fildes, int fdtype) + { +- struct stat64 st; ++ struct __stat64_t64 st; + int result; + + { + int save_error = errno; +- result = __fstat64 (fildes, &st); ++ result = __fstat64_time64 (fildes, &st); + __set_errno (save_error); + } + diff --git a/SOURCES/glibc-upstream-2.34-264.patch b/SOURCES/glibc-upstream-2.34-264.patch new file mode 100644 index 0000000..b8e9768 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-264.patch @@ -0,0 +1,34 @@ +commit 34422108f4e0b8fc0d950b8c00b87193a7884ee5 +Author: Adhemerval Zanella +Date: Tue May 31 12:34:48 2022 -0300 + + inet: Use 64 bit stat for ruserpass (BZ# 29210) + + This is a missing spot initially from 52a5fe70a2c77935. + + Checked on i686-linux-gnu. + + (cherry picked from commit 3cd4785ea02cc3878bf21996cf9b61b3a306447e) + +diff --git a/inet/ruserpass.c b/inet/ruserpass.c +index d61a72877d20b7e5..75e2a065524aa1d5 100644 +--- a/inet/ruserpass.c ++++ b/inet/ruserpass.c +@@ -95,7 +95,7 @@ ruserpass (const char *host, const char **aname, const char **apass) + char *hdir, *buf, *tmp; + char myname[1024], *mydomain; + int t, usedefault = 0; +- struct stat64 stb; ++ struct __stat64_t64 stb; + + hdir = __libc_secure_getenv("HOME"); + if (hdir == NULL) { +@@ -174,7 +174,7 @@ next: + break; + case PASSWD: + if (strcmp(*aname, "anonymous") && +- __fstat64(fileno(cfile), &stb) >= 0 && ++ __fstat64_time64(fileno(cfile), &stb) >= 0 && + (stb.st_mode & 077) != 0) { + warnx(_("Error: .netrc file is readable by others.")); + warnx(_("Remove 'password' line or make file unreadable by others.")); diff --git a/SOURCES/glibc-upstream-2.34-265.patch b/SOURCES/glibc-upstream-2.34-265.patch new file mode 100644 index 0000000..0bd0c81 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-265.patch @@ -0,0 +1,34 @@ +commit 52431199b5cef8f56c71c66f5859b097804aebe8 +Author: Adhemerval Zanella +Date: Tue May 31 12:38:55 2022 -0300 + + catgets: Use 64 bit stat for __open_catalog (BZ# 29211) + + This is a missing spot initially from 52a5fe70a2c77935. + + Checked on i686-linux-gnu. + + (cherry picked from commit c86631de6fa2fb5fa293810c66e53898537a4ddc) + +diff --git a/catgets/open_catalog.c b/catgets/open_catalog.c +index 7f67cc056445b5e2..75703b2cadd1764c 100644 +--- a/catgets/open_catalog.c ++++ b/catgets/open_catalog.c +@@ -40,7 +40,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var, + __nl_catd catalog) + { + int fd = -1; +- struct stat64 st; ++ struct __stat64_t64 st; + int swapping; + size_t cnt; + size_t max_offset; +@@ -194,7 +194,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var, + return -1; + } + +- if (__builtin_expect (__fstat64 (fd, &st), 0) < 0) ++ if (__glibc_unlikely (__fstat64_time64 (fd, &st) < 0)) + goto close_unlock_return; + + if (__builtin_expect (!S_ISREG (st.st_mode), 0) diff --git a/SOURCES/glibc-upstream-2.34-266.patch b/SOURCES/glibc-upstream-2.34-266.patch new file mode 100644 index 0000000..7bf98d2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-266.patch @@ -0,0 +1,47 @@ +commit b3f935940ebcdf553b64e74fdf65dfd4858821ad +Author: Adhemerval Zanella +Date: Tue May 31 12:51:43 2022 -0300 + + iconv: Use 64 bit stat for gconv_parseconfdir (BZ# 29213) + + The issue is only when used within libc.so (iconvconfig already builds + with _TIME_SIZE=64). + + This is a missing spot initially from 52a5fe70a2c77935. + + Checked on i686-linux-gnu. + + (cherry picked from commit c789e6e40974e2b67bd33a17f29b20dce6ae8822) + +diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h +index a586268abc103abd..79398a980cde84e3 100644 +--- a/iconv/gconv_parseconfdir.h ++++ b/iconv/gconv_parseconfdir.h +@@ -32,8 +32,11 @@ + # define readdir __readdir + # define closedir __closedir + # define mempcpy __mempcpy +-# define lstat64 __lstat64 ++# define struct_stat struct __stat64_t64 ++# define lstat __lstat64_time64 + # define feof_unlocked __feof_unlocked ++#else ++# define struct_stat struct stat + #endif + + /* Name of the file containing the module information in the directories +@@ -158,12 +161,12 @@ gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len) + && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0) + { + char *conf; +- struct stat64 st; ++ struct_stat st; + if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0) + continue; + + if (ent->d_type != DT_UNKNOWN +- || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode))) ++ || (lstat (conf, &st) != -1 && S_ISREG (st.st_mode))) + found |= read_conf_file (conf, dir, dir_len); + + free (conf); diff --git a/SOURCES/glibc-upstream-2.34-267.patch b/SOURCES/glibc-upstream-2.34-267.patch new file mode 100644 index 0000000..1511b1e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-267.patch @@ -0,0 +1,21 @@ +commit 9947f2df19a6c5b5706ed3b002199dbb9fef17b1 +Author: Dmitriy Fedchenko +Date: Mon Jun 6 12:46:14 2022 -0300 + + socket: Fix mistyped define statement in socket/sys/socket.h (BZ #29225) + + (cherry picked from commit 999835533bc60fbd0b0b65d2412a6742e5a54b9d) + +diff --git a/socket/sys/socket.h b/socket/sys/socket.h +index bd14e7e3a5008ec5..5765dc1f0dedd380 100644 +--- a/socket/sys/socket.h ++++ b/socket/sys/socket.h +@@ -181,7 +181,7 @@ extern ssize_t __REDIRECT (sendmsg, (int __fd, const struct msghdr *__message, + # else + extern ssize_t __sendmsg64 (int __fd, const struct msghdr *__message, + int __flags); +-# defien sendmsg __sendmsg64 ++# define sendmsg __sendmsg64 + # endif + #endif + diff --git a/SOURCES/glibc-upstream-2.34-268.patch b/SOURCES/glibc-upstream-2.34-268.patch new file mode 100644 index 0000000..2878763 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-268.patch @@ -0,0 +1,42 @@ +commit 4c92a1041257c0155c6aa7a182fe5f78e477b0e6 +Author: Matheus Castanho +Date: Tue Jun 7 10:27:26 2022 -0300 + + powerpc: Fix VSX register number on __strncpy_power9 [BZ #29197] + + __strncpy_power9 initializes VR 18 with zeroes to be used throughout the + code, including when zero-padding the destination string. However, the + v18 reference was mistakenly being used for stxv and stxvl, which take a + VSX vector as operand. The code ended up using the uninitialized VSR 18 + register by mistake. + + Both occurrences have been changed to use the proper VSX number for VR 18 + (i.e. VSR 50). + + Tested on powerpc, powerpc64 and powerpc64le. + + Signed-off-by: Kewen Lin + (cherry picked from commit 0218463dd8265ed937622f88ac68c7d984fe0cfc) + +diff --git a/sysdeps/powerpc/powerpc64/le/power9/strncpy.S b/sysdeps/powerpc/powerpc64/le/power9/strncpy.S +index 291941c1e5c0eb4b..5421525acee3ebfe 100644 +--- a/sysdeps/powerpc/powerpc64/le/power9/strncpy.S ++++ b/sysdeps/powerpc/powerpc64/le/power9/strncpy.S +@@ -352,7 +352,7 @@ L(zero_padding_loop): + cmpldi cr6,r5,16 /* Check if length was reached. */ + ble cr6,L(zero_padding_end) + +- stxv v18,0(r11) ++ stxv 32+v18,0(r11) + addi r11,r11,16 + addi r5,r5,-16 + +@@ -360,7 +360,7 @@ L(zero_padding_loop): + + L(zero_padding_end): + sldi r10,r5,56 /* stxvl wants size in top 8 bits */ +- stxvl v18,r11,r10 /* Partial store */ ++ stxvl 32+v18,r11,r10 /* Partial store */ + blr + + .align 4 diff --git a/SOURCES/glibc-upstream-2.34-269.patch b/SOURCES/glibc-upstream-2.34-269.patch new file mode 100644 index 0000000..35c6ab2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-269.patch @@ -0,0 +1,126 @@ +commit a7ec6363a3a8fd7a2014fd7398bcdcab42919ec1 +Author: Adhemerval Zanella +Date: Tue May 31 17:13:35 2022 -0300 + + nptl: Fix __libc_cleanup_pop_restore asynchronous restore (BZ#29214) + + This was due a wrong revert done on 404656009b459658. + + Checked on x86_64-linux-gnu. + + (cherry picked from commit c7d36dcecc08a29825175f65c4ee873ff3177a23) + +diff --git a/nptl/libc-cleanup.c b/nptl/libc-cleanup.c +index fccb1abe69aa693c..a37c48ff876d613a 100644 +--- a/nptl/libc-cleanup.c ++++ b/nptl/libc-cleanup.c +@@ -58,7 +58,8 @@ __libc_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer) + THREAD_SETMEM (self, cleanup, buffer->__prev); + + int cancelhandling = atomic_load_relaxed (&self->cancelhandling); +- if (cancelhandling & CANCELTYPE_BITMASK) ++ if (buffer->__canceltype != PTHREAD_CANCEL_DEFERRED ++ && (cancelhandling & CANCELTYPE_BITMASK) == 0) + { + int newval; + do +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index 5147588c130c9415..d99c161c827ef4b8 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -126,6 +126,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-pthread-raise-blocked-self \ + tst-pthread_kill-exited \ + tst-pthread_kill-exiting \ ++ tst-cancel30 \ + # tests + + tests-time64 := \ +diff --git a/sysdeps/pthread/tst-cancel30.c b/sysdeps/pthread/tst-cancel30.c +new file mode 100644 +index 0000000000000000..e08392f96874de5f +--- /dev/null ++++ b/sysdeps/pthread/tst-cancel30.c +@@ -0,0 +1,82 @@ ++/* Check if printf like functions does not disable asynchronous cancellation ++ mode (BZ#29214). ++ ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static pthread_barrier_t b; ++ ++static void * ++tf (void *arg) ++{ ++ int old; ++ ++ TEST_COMPARE (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL), 0); ++ ++ TEST_COMPARE (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &old), 0); ++ TEST_COMPARE (old, PTHREAD_CANCEL_ASYNCHRONOUS); ++ ++ /* Check if internal lock cleanup routines restore the cancellation type ++ correctly. */ ++ printf ("...\n"); ++ TEST_COMPARE (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &old), 0); ++ TEST_COMPARE (old, PTHREAD_CANCEL_ASYNCHRONOUS); ++ ++ xpthread_barrier_wait (&b); ++ ++ /* Wait indefinitely for cancellation, which only works if asynchronous ++ cancellation is enabled. */ ++#ifdef SYS_pause ++ syscall (SYS_pause); ++#elif defined SYS_ppoll || defined SYS_ppoll_time64 ++# ifndef SYS_ppoll_time64 ++# define SYS_ppoll_time64 SYS_ppoll ++# endif ++ syscall (SYS_ppoll_time64, NULL, 0, NULL, NULL); ++#else ++ for (;;); ++#endif ++ ++ return 0; ++} ++ ++static int ++do_test (void) ++{ ++ xpthread_barrier_init (&b, NULL, 2); ++ ++ pthread_t th = xpthread_create (NULL, tf, NULL); ++ ++ xpthread_barrier_wait (&b); ++ ++ xpthread_cancel (th); ++ ++ void *status = xpthread_join (th); ++ TEST_VERIFY (status == PTHREAD_CANCELED); ++ ++ return 0; ++} ++ ++/* There is no need to wait full TIMEOUT if asynchronous is not working. */ ++#define TIMEOUT 3 ++#include diff --git a/SOURCES/glibc-upstream-2.34-27.patch b/SOURCES/glibc-upstream-2.34-27.patch new file mode 100644 index 0000000..e166aa2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-27.patch @@ -0,0 +1,37 @@ +commit 4bf72519987ebc2be4a2058c670379040fae90ea +Author: Florian Weimer +Date: Fri Oct 1 18:16:41 2021 +0200 + + support: Add check for TID zero in support_wait_for_thread_exit + + Some kernel versions (observed with kernel 5.14 and earlier) can list + "0" entries in /proc/self/task. This happens when a thread exits + while the task list is being constructed. Treat this entry as not + present, like the proposed kernel patch does: + + [PATCH] procfs: Do not list TID 0 in /proc//task + + + Fixes commit 032d74eaf6179100048a5bf0ce942e97dc8b9a60 ("support: Add + support_wait_for_thread_exit"). + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 176c88f5214d8107d330971cbbfbbba5186a111f) + +diff --git a/support/support_wait_for_thread_exit.c b/support/support_wait_for_thread_exit.c +index 658a81381006ea62..5e3be421a78a4c78 100644 +--- a/support/support_wait_for_thread_exit.c ++++ b/support/support_wait_for_thread_exit.c +@@ -43,7 +43,10 @@ support_wait_for_thread_exit (void) + return; + } + +- if (strcmp (e->d_name, ".") == 0 || strcmp (e->d_name, "..") == 0) ++ /* In some kernels, "0" entries denote a thread that has just ++ exited. */ ++ if (strcmp (e->d_name, ".") == 0 || strcmp (e->d_name, "..") == 0 ++ || strcmp (e->d_name, "0") == 0) + continue; + + int task_tid = atoi (e->d_name); diff --git a/SOURCES/glibc-upstream-2.34-270.patch b/SOURCES/glibc-upstream-2.34-270.patch new file mode 100644 index 0000000..07ab4c9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-270.patch @@ -0,0 +1,83 @@ +commit 96944f0f81870b733f518950a108c7ad6b078da6 +Author: Adhemerval Zanella +Date: Wed May 25 08:58:38 2022 -0300 + + hppa: Remove _dl_skip_args usage (BZ# 29165) + + Different than other architectures, hppa creates an unrelated stack + frame where ld.so argc/argv adjustments done by ad43cac44a6860eaefc + is not done on the argc/argv saved/restore by _dl_start_user. + + Instead load _dl_argc and _dl_argv directlty instead of adjust them + using _dl_skip_args value. + + Checked on hppa-linux-gnu. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit 6242602273feb8d68cd51cff0ad21b3c8ee11fc6) + +diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h +index ac66f044189edd18..df6269209f3268b7 100644 +--- a/sysdeps/hppa/dl-machine.h ++++ b/sysdeps/hppa/dl-machine.h +@@ -374,10 +374,6 @@ asm ( \ + "_start:\n" \ + /* The kernel does not give us an initial stack frame. */ \ + " ldo 64(%sp),%sp\n" \ +- /* Save the relevant arguments (yes, those are the correct \ +- registers, the kernel is weird) in their stack slots. */ \ +-" stw %r25,-40(%sp)\n" /* argc */ \ +-" stw %r24,-44(%sp)\n" /* argv */ \ + \ + /* We need the LTP, and we need it now. \ + $PIC_pcrel$0 points 8 bytes past the current instruction, \ +@@ -435,12 +431,7 @@ asm ( \ + So, obviously, we can't just pass %sp to _dl_start. That's \ + okay, argv-4 will do just fine. \ + \ +- The pleasant part of this is that if we need to skip \ +- arguments we can just decrement argc and move argv, because \ +- the stack pointer is utterly unrelated to the location of \ +- the environment and argument vectors. */ \ +- \ +- /* This is always within range so we'll be okay. */ \ ++ This is always within range so we'll be okay. */ \ + " bl _dl_start,%rp\n" \ + " ldo -4(%r24),%r26\n" \ + \ +@@ -450,22 +441,23 @@ asm ( \ + /* Save the entry point in %r3. */ \ + " copy %ret0,%r3\n" \ + \ +- /* See if we were called as a command with the executable file \ +- name as an extra leading argument. */ \ +-" addil LT'_dl_skip_args,%r19\n" \ +-" ldw RT'_dl_skip_args(%r1),%r20\n" \ +-" ldw 0(%r20),%r20\n" \ +- \ +-" ldw -40(%sp),%r25\n" /* argc */ \ +-" comib,= 0,%r20,.Lnofix\n" /* FIXME: Mispredicted branch */\ +-" ldw -44(%sp),%r24\n" /* argv (delay slot) */ \ ++ /* The loader adjusts argc, argv, env, and the aux vectors \ ++ directly on the stack to remove any arguments used for \ ++ direct loader invocation. Thus, argc and argv must be \ ++ reloaded from from _dl_argc and _dl_argv. */ \ + \ +-" sub %r25,%r20,%r25\n" \ ++ /* Load argc from _dl_argc. */ \ ++" addil LT'_dl_argc,%r19\n" \ ++" ldw RT'_dl_argc(%r1),%r20\n" \ ++" ldw 0(%r20),%r25\n" \ + " stw %r25,-40(%sp)\n" \ +-" sh2add %r20,%r24,%r24\n" \ ++ \ ++ /* Same for argv with _dl_argv. */ \ ++" addil LT'_dl_argv,%r19\n" \ ++" ldw RT'_dl_argv(%r1),%r20\n" \ ++" ldw 0(%r20),%r24\n" \ + " stw %r24,-44(%sp)\n" \ + \ +-".Lnofix:\n" \ + /* Call _dl_init(main_map, argc, argv, envp). */ \ + " addil LT'_rtld_local,%r19\n" \ + " ldw RT'_rtld_local(%r1),%r26\n" \ diff --git a/SOURCES/glibc-upstream-2.34-271.patch b/SOURCES/glibc-upstream-2.34-271.patch new file mode 100644 index 0000000..d5f6144 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-271.patch @@ -0,0 +1,84 @@ +commit bb4148283fa7c52fbc7efe19e81cd129adc7fd61 +Author: Adhemerval Zanella +Date: Thu May 26 13:12:21 2022 -0300 + + nios2: Remove _dl_skip_args usage (BZ# 29187) + + Since ad43cac44a the generic code already shuffles the argv/envp/auxv + on the stack to remove the ld.so own arguments and thus _dl_skip_args + is always 0. So there is no need to adjust the argc or argv. + + Checked with qemu-user that arguments are correctly passed on both + constructors and main program. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit 4868ba5d257a7fb415674e79c4ae5a3af2827f55) + +diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h +index 430ca5d7ae1e0372..47b3f6acd7624bcb 100644 +--- a/sysdeps/nios2/dl-machine.h ++++ b/sysdeps/nios2/dl-machine.h +@@ -128,53 +128,23 @@ _start:\n\ + ldw r8, %call(_dl_nios2_get_gp_value)(r22)\n\ + callr r8\n\ + mov gp, r2\n\ +-\n\ +- /* Find the number of arguments to skip. */\n\ +- ldw r8, %got(_dl_skip_args)(r22)\n\ +- ldw r8, 0(r8)\n\ + \n\ + /* Find the main_map from the GOT. */\n\ + ldw r4, %got(_rtld_local)(r22)\n\ + ldw r4, 0(r4)\n\ + \n\ +- /* Find argc. */\n\ +- ldw r5, 0(sp)\n\ +- sub r5, r5, r8\n\ +- stw r5, 0(sp)\n\ +-\n\ +- /* Find the first unskipped argument. */\n\ +- slli r8, r8, 2\n\ +- addi r6, sp, 4\n\ +- add r9, r6, r8\n\ +- mov r10, r6\n\ +-\n\ +- /* Shuffle argv down. */\n\ +-3: ldw r11, 0(r9)\n\ +- stw r11, 0(r10)\n\ +- addi r9, r9, 4\n\ +- addi r10, r10, 4\n\ +- bne r11, zero, 3b\n\ ++ /* Load adjusted argc. */\n\ ++ ldw r2, %got(_dl_argc)(r22)\n\ ++ ldw r5, 0(r2)\n\ + \n\ +- /* Shuffle envp down. */\n\ +- mov r7, r10\n\ +-4: ldw r11, 0(r9)\n\ +- stw r11, 0(r10)\n\ +- addi r9, r9, 4\n\ +- addi r10, r10, 4\n\ +- bne r11, zero, 4b\n\ +-\n\ +- /* Shuffle auxv down. */\n\ +-5: ldw r11, 4(r9)\n\ +- stw r11, 4(r10)\n\ +- ldw r11, 0(r9)\n\ +- stw r11, 0(r10)\n\ +- addi r9, r9, 8\n\ +- addi r10, r10, 8\n\ +- bne r11, zero, 5b\n\ +-\n\ +- /* Update _dl_argv. */\n\ ++ /* Load adjsuted argv. */\n\ + ldw r2, %got(_dl_argv)(r22)\n\ +- stw r6, 0(r2)\n\ ++ ldw r6, 0(r2)\n\ ++\n\ ++ /* envp = argv + argc + 1 */\n\ ++ addi r7, r5, 1\n\ ++ slli r7, r7, 2\n\ ++ add r7, r7, r6\n\ + \n\ + /* Call _dl_init through the PLT. */\n\ + ldw r8, %call(_dl_init)(r22)\n\ diff --git a/SOURCES/glibc-upstream-2.34-272.patch b/SOURCES/glibc-upstream-2.34-272.patch new file mode 100644 index 0000000..289b763 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-272.patch @@ -0,0 +1,37 @@ +commit 368c5c3e001a37571b61ab342f2b654c3d23643d +Author: Sam James +Date: Sun Jun 5 04:57:09 2022 +0100 + + nss: add assert to DB_LOOKUP_FCT (BZ #28752) + + It's interesting if we have a null action list, + so an assert is worthwhile. + + Suggested-by: DJ Delorie + Signed-off-by: Sam James + Reviewed-by: DJ Delorie + (cherry picked from commit 3fdf0a205b622e40fa7e3c4ed1e4ed4d5c6c5380) + +diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c +index dbc87868dd408d9f..343fd9869bd12714 100644 +--- a/nss/XXX-lookup.c ++++ b/nss/XXX-lookup.c +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include "nsswitch.h" + + /*******************************************************************\ +@@ -55,6 +56,10 @@ DB_LOOKUP_FCT (nss_action_list *ni, const char *fct_name, const char *fct2_name, + + *ni = DATABASE_NAME_SYMBOL; + ++ /* We want to know about it if we've somehow got a NULL action list; ++ in the past, we had bad state if seccomp interfered with setup. */ ++ assert(*ni != NULL); ++ + return __nss_lookup (ni, fct_name, fct2_name, fctp); + } + libc_hidden_def (DB_LOOKUP_FCT) diff --git a/SOURCES/glibc-upstream-2.34-273.patch b/SOURCES/glibc-upstream-2.34-273.patch new file mode 100644 index 0000000..698b3e5 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-273.patch @@ -0,0 +1,74 @@ +commit 94ab2088c37d8e4285354af120b7ed6b887b9e53 +Author: Sam James +Date: Sun Jun 5 04:57:10 2022 +0100 + + nss: handle stat failure in check_reload_and_get (BZ #28752) + + Skip the chroot test if the database isn't loaded + correctly (because the chroot test uses some + existing DB state). + + The __stat64_time64 -> fstatat call can fail if + running under an (aggressive) seccomp filter, + like Firefox seems to use. + + This manifested in a crash when using glib built + with FAM support with such a Firefox build. + + Suggested-by: DJ Delorie + Signed-off-by: Sam James + Reviewed-by: DJ Delorie + (cherry picked from commit ace9e3edbca62d978b1e8f392d8a5d78500272d9) + +diff --git a/nss/nss_database.c b/nss/nss_database.c +index 54561f03287db2e4..e807e9d84ca03680 100644 +--- a/nss/nss_database.c ++++ b/nss/nss_database.c +@@ -420,23 +420,32 @@ nss_database_check_reload_and_get (struct nss_database_state *local, + return true; + } + +- /* Before we reload, verify that "/" hasn't changed. We assume that +- errors here are very unlikely, but the chance that we're entering +- a container is also very unlikely, so we err on the side of both +- very unlikely things not happening at the same time. */ +- if (__stat64_time64 ("/", &str) != 0 +- || (local->root_ino != 0 +- && (str.st_ino != local->root_ino +- || str.st_dev != local->root_dev))) ++ int stat_rv = __stat64_time64 ("/", &str); ++ ++ if (local->data.services[database_index] != NULL) + { +- /* Change detected; disable reloading and return current state. */ +- atomic_store_release (&local->data.reload_disabled, 1); +- *result = local->data.services[database_index]; +- __libc_lock_unlock (local->lock); +- return true; ++ /* Before we reload, verify that "/" hasn't changed. We assume that ++ errors here are very unlikely, but the chance that we're entering ++ a container is also very unlikely, so we err on the side of both ++ very unlikely things not happening at the same time. */ ++ if (stat_rv != 0 ++ || (local->root_ino != 0 ++ && (str.st_ino != local->root_ino ++ || str.st_dev != local->root_dev))) ++ { ++ /* Change detected; disable reloading and return current state. */ ++ atomic_store_release (&local->data.reload_disabled, 1); ++ *result = local->data.services[database_index]; ++ __libc_lock_unlock (local->lock); ++ return true; ++ } ++ } ++ if (stat_rv == 0) ++ { ++ local->root_ino = str.st_ino; ++ local->root_dev = str.st_dev; + } +- local->root_ino = str.st_ino; +- local->root_dev = str.st_dev; ++ + __libc_lock_unlock (local->lock); + + /* Avoid overwriting the global configuration until we have loaded diff --git a/SOURCES/glibc-upstream-2.34-274.patch b/SOURCES/glibc-upstream-2.34-274.patch new file mode 100644 index 0000000..c56ed93 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-274.patch @@ -0,0 +1,27 @@ +commit 4b246b2bbd1d5a77035bb990d6097b7337c34bbb +Author: Adhemerval Zanella +Date: Thu Jun 30 09:08:31 2022 -0300 + + linux: Fix mq_timereceive check for 32 bit fallback code (BZ 29304) + + On success, mq_receive() and mq_timedreceive() return the number of + bytes in the received message, so it requires to check if the value + is larger than 0. + + Checked on i686-linux-gnu. + + (cherry picked from commit 71d87d85bf54f6522813aec97c19bdd24997341e) + +diff --git a/sysdeps/unix/sysv/linux/mq_timedreceive.c b/sysdeps/unix/sysv/linux/mq_timedreceive.c +index 7f3a112d7f2cbbe7..1fc98752e7d6d506 100644 +--- a/sysdeps/unix/sysv/linux/mq_timedreceive.c ++++ b/sysdeps/unix/sysv/linux/mq_timedreceive.c +@@ -41,7 +41,7 @@ ___mq_timedreceive_time64 (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len + { + int r = SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len, + msg_prio, abs_timeout); +- if (r == 0 || errno != ENOSYS) ++ if (r >= 0 || errno != ENOSYS) + return r; + __set_errno (EOVERFLOW); + return -1; diff --git a/SOURCES/glibc-upstream-2.34-275.patch b/SOURCES/glibc-upstream-2.34-275.patch new file mode 100644 index 0000000..155d9e1 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-275.patch @@ -0,0 +1,25 @@ +commit 7789a849234f8b303a571134abe72691ce8c2540 +Author: Adhemerval Zanella +Date: Wed Jul 13 10:37:32 2022 -0300 + + nptl: Fix ___pthread_unregister_cancel_restore asynchronous restore + + This was due a wrong revert done on 404656009b459658. + + Checked on x86_64-linux-gnu and i686-linux-gnu. + + (cherry picked from commit f27e5e21787abc9f719879af47687221aa1027b3) + +diff --git a/nptl/cleanup_defer.c b/nptl/cleanup_defer.c +index 35ba40fb0247c7cc..59571229d8ccf481 100644 +--- a/nptl/cleanup_defer.c ++++ b/nptl/cleanup_defer.c +@@ -72,7 +72,7 @@ ___pthread_unregister_cancel_restore (__pthread_unwind_buf_t *buf) + return; + + int cancelhandling = atomic_load_relaxed (&self->cancelhandling); +- if (cancelhandling & CANCELTYPE_BITMASK) ++ if ((cancelhandling & CANCELTYPE_BITMASK) == 0) + { + int newval; + do diff --git a/SOURCES/glibc-upstream-2.34-276.patch b/SOURCES/glibc-upstream-2.34-276.patch new file mode 100644 index 0000000..5e9bb63 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-276.patch @@ -0,0 +1,29 @@ +commit 8d324019e69203f5998f223d0e905de1395330ea +Author: Sunil K Pandey +Date: Mon Jul 18 18:38:48 2022 -0700 + + x86_64: Remove end of line trailing spaces + + This commit remove trailing space introduced by following commit. + + commit a775a7a3eb1e85b54af0b4ee5ff4dcf66772a1fb + Author: Noah Goldstein + Date: Wed Jun 23 01:56:29 2021 -0400 + + x86: Fix overflow bug in wcsnlen-sse4_1 and wcsnlen-avx2 [BZ #27974] + +diff --git a/sysdeps/x86_64/multiarch/strlen-vec.S b/sysdeps/x86_64/multiarch/strlen-vec.S +index b7657282bd2e6fa5..031753a91763b351 100644 +--- a/sysdeps/x86_64/multiarch/strlen-vec.S ++++ b/sysdeps/x86_64/multiarch/strlen-vec.S +@@ -66,8 +66,8 @@ ENTRY(strlen) + L(n_nonzero): + # ifdef AS_WCSLEN + /* Check for overflow from maxlen * sizeof(wchar_t). If it would +- overflow the only way this program doesn't have undefined behavior +- is if there is a null terminator in valid memory so wcslen will ++ overflow the only way this program doesn't have undefined behavior ++ is if there is a null terminator in valid memory so wcslen will + suffice. */ + mov %RSI_LP, %R10_LP + sar $62, %R10_LP diff --git a/SOURCES/glibc-upstream-2.34-277.patch b/SOURCES/glibc-upstream-2.34-277.patch new file mode 100644 index 0000000..3f15409 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-277.patch @@ -0,0 +1,457 @@ +commit eb9aa96facc5231e208de0946870f10c21aee9f3 +Author: Adhemerval Zanella +Date: Fri May 13 09:33:30 2022 -0300 + + x86_64: Remove bzero optimization + + Both symbols are marked as legacy in POSIX.1-2001 and removed on + POSIX.1-2008, although the prototypes are defined for _GNU_SOURCE + or _DEFAULT_SOURCE. + + GCC also replaces bcopy with a memmove and bzero with memset on default + configuration (to actually get a bzero libc call the code requires + to omit string.h inclusion and built with -fno-builtin), so it is + highly unlikely programs are actually calling libc bzero symbol. + + On a recent Linux distro (Ubuntu 22.04), there is no bzero calls + by the installed binaries. + + $ cat count_bstring.sh + #!/bin/bash + + files=`IFS=':';for i in $PATH; do test -d "$i" && find "$i" -maxdepth 1 -executable -type f; done` + total=0 + for file in $files; do + symbols=`objdump -R $file 2>&1` + if [ $? -eq 0 ]; then + ncalls=`echo $symbols | grep -w $1 | wc -l` + ((total=total+ncalls)) + if [ $ncalls -gt 0 ]; then + echo "$file: $ncalls" + fi + fi + done + echo "TOTAL=$total" + $ ./count_bstring.sh bzero + TOTAL=0 + + Checked on x86_64-linux-gnu. + + (cherry picked from commit 9403b71ae97e3f1a91c796ddcbb4e6f044434734) + +diff --git a/sysdeps/x86_64/bzero.S b/sysdeps/x86_64/bzero.S +deleted file mode 100644 +index f96d567fd87696af..0000000000000000 +--- a/sysdeps/x86_64/bzero.S ++++ /dev/null +@@ -1 +0,0 @@ +-/* Implemented in memset.S. */ +diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S +index 0358210c7ff3a976..2b64741fd10a8ec2 100644 +--- a/sysdeps/x86_64/memset.S ++++ b/sysdeps/x86_64/memset.S +@@ -1,4 +1,4 @@ +-/* memset/bzero -- set memory area to CH/0 ++/* memset -- set memory area to CH/0 + Optimized version for x86-64. + Copyright (C) 2002-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. +@@ -35,9 +35,6 @@ + punpcklwd %xmm0, %xmm0; \ + pshufd $0, %xmm0, %xmm0 + +-# define BZERO_ZERO_VEC0() \ +- pxor %xmm0, %xmm0 +- + # define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + movd d, %xmm0; \ + pshufd $0, %xmm0, %xmm0; \ +@@ -56,10 +53,6 @@ + # define MEMSET_SYMBOL(p,s) memset + #endif + +-#ifndef BZERO_SYMBOL +-# define BZERO_SYMBOL(p,s) __bzero +-#endif +- + #ifndef WMEMSET_SYMBOL + # define WMEMSET_CHK_SYMBOL(p,s) p + # define WMEMSET_SYMBOL(p,s) __wmemset +@@ -70,7 +63,6 @@ + libc_hidden_builtin_def (memset) + + #if IS_IN (libc) +-weak_alias (__bzero, bzero) + libc_hidden_def (__wmemset) + weak_alias (__wmemset, wmemset) + libc_hidden_weak (wmemset) +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index b503e4b81e92a11c..67401162d526f664 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -1,7 +1,6 @@ + ifeq ($(subdir),string) + + sysdep_routines += \ +- bzero \ + memchr-avx2 \ + memchr-avx2-rtm \ + memchr-evex \ +diff --git a/sysdeps/x86_64/multiarch/bzero.c b/sysdeps/x86_64/multiarch/bzero.c +deleted file mode 100644 +index 13e399a9a1fbdeb2..0000000000000000 +--- a/sysdeps/x86_64/multiarch/bzero.c ++++ /dev/null +@@ -1,108 +0,0 @@ +-/* Multiple versions of bzero. +- All versions must be listed in ifunc-impl-list.c. +- Copyright (C) 2022 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* Define multiple versions only for the definition in libc. */ +-#if IS_IN (libc) +-# define __bzero __redirect___bzero +-# include +-# undef __bzero +- +-/* OPTIMIZE1 definition required for bzero patch. */ +-# define OPTIMIZE1(name) EVALUATOR1 (SYMBOL_NAME, name) +-# define SYMBOL_NAME __bzero +-# include +- +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (sse2_unaligned) +- attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (sse2_unaligned_erms) +- attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx2_unaligned) attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx2_unaligned_erms) +- attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx2_unaligned_rtm) +- attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx2_unaligned_erms_rtm) +- attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (evex_unaligned) +- attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (evex_unaligned_erms) +- attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx512_unaligned) +- attribute_hidden; +-extern __typeof (REDIRECT_NAME) OPTIMIZE1 (avx512_unaligned_erms) +- attribute_hidden; +- +-static inline void * +-IFUNC_SELECTOR (void) +-{ +- const struct cpu_features* cpu_features = __get_cpu_features (); +- +- if (CPU_FEATURE_USABLE_P (cpu_features, AVX512F) +- && !CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_AVX512)) +- { +- if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) +- && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) +- && CPU_FEATURE_USABLE_P (cpu_features, BMI2)) +- { +- if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) +- return OPTIMIZE1 (avx512_unaligned_erms); +- +- return OPTIMIZE1 (avx512_unaligned); +- } +- } +- +- if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)) +- { +- if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) +- && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) +- && CPU_FEATURE_USABLE_P (cpu_features, BMI2)) +- { +- if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) +- return OPTIMIZE1 (evex_unaligned_erms); +- +- return OPTIMIZE1 (evex_unaligned); +- } +- +- if (CPU_FEATURE_USABLE_P (cpu_features, RTM)) +- { +- if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) +- return OPTIMIZE1 (avx2_unaligned_erms_rtm); +- +- return OPTIMIZE1 (avx2_unaligned_rtm); +- } +- +- if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_VZEROUPPER)) +- { +- if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) +- return OPTIMIZE1 (avx2_unaligned_erms); +- +- return OPTIMIZE1 (avx2_unaligned); +- } +- } +- +- if (CPU_FEATURE_USABLE_P (cpu_features, ERMS)) +- return OPTIMIZE1 (sse2_unaligned_erms); +- +- return OPTIMIZE1 (sse2_unaligned); +-} +- +-libc_ifunc_redirected (__redirect___bzero, __bzero, IFUNC_SELECTOR ()); +- +-weak_alias (__bzero, bzero) +-#endif +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index e5e48b36c3175e68..d990a7149489efd9 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -280,48 +280,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __memset_avx512_no_vzeroupper) + ) + +- /* Support sysdeps/x86_64/multiarch/bzero.c. */ +- IFUNC_IMPL (i, name, bzero, +- IFUNC_IMPL_ADD (array, i, bzero, 1, +- __bzero_sse2_unaligned) +- IFUNC_IMPL_ADD (array, i, bzero, 1, +- __bzero_sse2_unaligned_erms) +- IFUNC_IMPL_ADD (array, i, bzero, +- CPU_FEATURE_USABLE (AVX2), +- __bzero_avx2_unaligned) +- IFUNC_IMPL_ADD (array, i, bzero, +- CPU_FEATURE_USABLE (AVX2), +- __bzero_avx2_unaligned_erms) +- IFUNC_IMPL_ADD (array, i, bzero, +- (CPU_FEATURE_USABLE (AVX2) +- && CPU_FEATURE_USABLE (RTM)), +- __bzero_avx2_unaligned_rtm) +- IFUNC_IMPL_ADD (array, i, bzero, +- (CPU_FEATURE_USABLE (AVX2) +- && CPU_FEATURE_USABLE (RTM)), +- __bzero_avx2_unaligned_erms_rtm) +- IFUNC_IMPL_ADD (array, i, bzero, +- (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW) +- && CPU_FEATURE_USABLE (BMI2)), +- __bzero_evex_unaligned) +- IFUNC_IMPL_ADD (array, i, bzero, +- (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW) +- && CPU_FEATURE_USABLE (BMI2)), +- __bzero_evex_unaligned_erms) +- IFUNC_IMPL_ADD (array, i, bzero, +- (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW) +- && CPU_FEATURE_USABLE (BMI2)), +- __bzero_avx512_unaligned_erms) +- IFUNC_IMPL_ADD (array, i, bzero, +- (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW) +- && CPU_FEATURE_USABLE (BMI2)), +- __bzero_avx512_unaligned) +- ) +- + /* Support sysdeps/x86_64/multiarch/rawmemchr.c. */ + IFUNC_IMPL (i, name, rawmemchr, + IFUNC_IMPL_ADD (array, i, rawmemchr, +diff --git a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms-rtm.S b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms-rtm.S +index 5a5ee6f67299400b..8ac3e479bba488be 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms-rtm.S ++++ b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms-rtm.S +@@ -5,7 +5,6 @@ + + #define SECTION(p) p##.avx.rtm + #define MEMSET_SYMBOL(p,s) p##_avx2_##s##_rtm +-#define BZERO_SYMBOL(p,s) p##_avx2_##s##_rtm + #define WMEMSET_SYMBOL(p,s) p##_avx2_##s##_rtm + + #include "memset-avx2-unaligned-erms.S" +diff --git a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S +index a093a2831f3dfa0d..c0bf2875d03d51ab 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S +@@ -14,9 +14,6 @@ + vmovd d, %xmm0; \ + movq r, %rax; + +-# define BZERO_ZERO_VEC0() \ +- vpxor %xmm0, %xmm0, %xmm0 +- + # define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + MEMSET_SET_VEC0_AND_SET_RETURN(d, r) + +@@ -32,9 +29,6 @@ + # ifndef MEMSET_SYMBOL + # define MEMSET_SYMBOL(p,s) p##_avx2_##s + # endif +-# ifndef BZERO_SYMBOL +-# define BZERO_SYMBOL(p,s) p##_avx2_##s +-# endif + # ifndef WMEMSET_SYMBOL + # define WMEMSET_SYMBOL(p,s) p##_avx2_##s + # endif +diff --git a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S +index 727c92133a15900f..5241216a77bf72b7 100644 +--- a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S +@@ -19,9 +19,6 @@ + vpbroadcastb d, %VEC0; \ + movq r, %rax + +-# define BZERO_ZERO_VEC0() \ +- vpxorq %XMM0, %XMM0, %XMM0 +- + # define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + vpbroadcastd d, %VEC0; \ + movq r, %rax +diff --git a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S +index 5d8fa78f05476b10..637002150659123c 100644 +--- a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S +@@ -19,9 +19,6 @@ + vpbroadcastb d, %VEC0; \ + movq r, %rax + +-# define BZERO_ZERO_VEC0() \ +- vpxorq %XMM0, %XMM0, %XMM0 +- + # define WMEMSET_SET_VEC0_AND_SET_RETURN(d, r) \ + vpbroadcastd d, %VEC0; \ + movq r, %rax +diff --git a/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S +index 2951f7f5f70e274a..c47f3a9c955508a2 100644 +--- a/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-sse2-unaligned-erms.S +@@ -22,7 +22,6 @@ + + #if IS_IN (libc) + # define MEMSET_SYMBOL(p,s) p##_sse2_##s +-# define BZERO_SYMBOL(p,s) MEMSET_SYMBOL (p, s) + # define WMEMSET_SYMBOL(p,s) p##_sse2_##s + + # ifdef SHARED +diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +index d9c577fb5ff9700f..abc12d9cda1b3843 100644 +--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +@@ -1,5 +1,5 @@ +-/* memset/bzero with unaligned store and rep stosb +- Copyright (C) 2016-2021 Free Software Foundation, Inc. ++/* memset with unaligned store and rep stosb ++ Copyright (C) 2016-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -26,10 +26,6 @@ + + #include + +-#ifndef BZERO_SYMBOL +-# define BZERO_SYMBOL(p,s) MEMSET_SYMBOL (p, s) +-#endif +- + #ifndef MEMSET_CHK_SYMBOL + # define MEMSET_CHK_SYMBOL(p,s) MEMSET_SYMBOL(p, s) + #endif +@@ -134,31 +130,6 @@ ENTRY (WMEMSET_SYMBOL (__wmemset, unaligned)) + END (WMEMSET_SYMBOL (__wmemset, unaligned)) + #endif + +-ENTRY (BZERO_SYMBOL(__bzero, unaligned)) +-#if VEC_SIZE > 16 +- BZERO_ZERO_VEC0 () +-#endif +- mov %RDI_LP, %RAX_LP +- mov %RSI_LP, %RDX_LP +-#ifndef USE_LESS_VEC_MASK_STORE +- xorl %esi, %esi +-#endif +- cmp $VEC_SIZE, %RDX_LP +- jb L(less_vec_no_vdup) +-#ifdef USE_LESS_VEC_MASK_STORE +- xorl %esi, %esi +-#endif +-#if VEC_SIZE <= 16 +- BZERO_ZERO_VEC0 () +-#endif +- cmp $(VEC_SIZE * 2), %RDX_LP +- ja L(more_2x_vec) +- /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */ +- VMOVU %VEC(0), (%rdi) +- VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi, %rdx) +- VZEROUPPER_RETURN +-END (BZERO_SYMBOL(__bzero, unaligned)) +- + #if defined SHARED && IS_IN (libc) + ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned)) + cmp %RDX_LP, %RCX_LP +@@ -216,31 +187,6 @@ END (__memset_erms) + END (MEMSET_SYMBOL (__memset, erms)) + # endif + +-ENTRY_P2ALIGN (BZERO_SYMBOL(__bzero, unaligned_erms), 6) +-# if VEC_SIZE > 16 +- BZERO_ZERO_VEC0 () +-# endif +- mov %RDI_LP, %RAX_LP +- mov %RSI_LP, %RDX_LP +-# ifndef USE_LESS_VEC_MASK_STORE +- xorl %esi, %esi +-# endif +- cmp $VEC_SIZE, %RDX_LP +- jb L(less_vec_no_vdup) +-# ifdef USE_LESS_VEC_MASK_STORE +- xorl %esi, %esi +-# endif +-# if VEC_SIZE <= 16 +- BZERO_ZERO_VEC0 () +-# endif +- cmp $(VEC_SIZE * 2), %RDX_LP +- ja L(stosb_more_2x_vec) +- /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */ +- VMOVU %VEC(0), (%rdi) +- VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi, %rdx) +- VZEROUPPER_RETURN +-END (BZERO_SYMBOL(__bzero, unaligned_erms)) +- + # if defined SHARED && IS_IN (libc) + ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms)) + cmp %RDX_LP, %RCX_LP +@@ -282,7 +228,6 @@ L(last_2x_vec): + #ifdef USE_LESS_VEC_MASK_STORE + .p2align 4,, 10 + L(less_vec): +-L(less_vec_no_vdup): + L(less_vec_from_wmemset): + /* Less than 1 VEC. */ + # if VEC_SIZE != 16 && VEC_SIZE != 32 && VEC_SIZE != 64 +@@ -430,9 +375,6 @@ L(less_vec): + xmm). This is only does anything for AVX2. */ + MEMSET_VDUP_TO_VEC0_LOW () + L(less_vec_from_wmemset): +-#if VEC_SIZE > 16 +-L(less_vec_no_vdup): +-#endif + #endif + L(cross_page): + #if VEC_SIZE > 32 +@@ -445,9 +387,6 @@ L(cross_page): + #endif + #ifndef USE_XMM_LESS_VEC + MOVQ %XMM0, %SET_REG64 +-#endif +-#if VEC_SIZE <= 16 +-L(less_vec_no_vdup): + #endif + cmpl $8, %edx + jge L(between_8_15) diff --git a/SOURCES/glibc-upstream-2.34-278.patch b/SOURCES/glibc-upstream-2.34-278.patch new file mode 100644 index 0000000..26b047f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-278.patch @@ -0,0 +1,460 @@ +commit 8ab861d295b90177b89288a2bc95c5de5e4e5bc6 +Author: Sunil K Pandey +Date: Sun Feb 27 16:39:47 2022 -0800 + + x86_64: Implement evex512 version of strlen, strnlen, wcslen and wcsnlen + + This patch implements following evex512 version of string functions. + Perf gain for evex512 version is up to 50% as compared to evex, + depending on length and alignment. + + Placeholder function, not used by any processor at the moment. + + - String length function using 512 bit vectors. + - String N length using 512 bit vectors. + - Wide string length using 512 bit vectors. + - Wide string N length using 512 bit vectors. + + Reviewed-by: Noah Goldstein + (cherry picked from commit 9c66efb86fe384f77435f7e326333fb2e4e10676) + +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index 67401162d526f664..4d4ad2a3686b5bc3 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -87,6 +87,7 @@ sysdep_routines += \ + strlen-avx2 \ + strlen-avx2-rtm \ + strlen-evex \ ++ strlen-evex512 \ + strlen-sse2 \ + strncase_l-avx2 \ + strncase_l-avx2-rtm \ +@@ -115,6 +116,7 @@ sysdep_routines += \ + strnlen-avx2 \ + strnlen-avx2-rtm \ + strnlen-evex \ ++ strnlen-evex512 \ + strnlen-sse2 \ + strpbrk-c \ + strpbrk-sse2 \ +@@ -148,6 +150,7 @@ sysdep_routines += \ + wcslen-avx2 \ + wcslen-avx2-rtm \ + wcslen-evex \ ++ wcslen-evex512 \ + wcslen-sse2 \ + wcslen-sse4_1 \ + wcsncmp-avx2 \ +@@ -158,6 +161,7 @@ sysdep_routines += \ + wcsnlen-avx2-rtm \ + wcsnlen-c \ + wcsnlen-evex \ ++ wcsnlen-evex512 \ + wcsnlen-sse4_1 \ + wcsrchr-avx2 \ + wcsrchr-avx2-rtm \ +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index d990a7149489efd9..6b75a7106e174bce 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -317,6 +317,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && CPU_FEATURE_USABLE (AVX512BW) + && CPU_FEATURE_USABLE (BMI2)), + __strlen_evex) ++ IFUNC_IMPL_ADD (array, i, strlen, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), ++ __strlen_evex512) + IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_sse2)) + + /* Support sysdeps/x86_64/multiarch/strnlen.c. */ +@@ -335,6 +340,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && CPU_FEATURE_USABLE (AVX512BW) + && CPU_FEATURE_USABLE (BMI2)), + __strnlen_evex) ++ IFUNC_IMPL_ADD (array, i, strnlen, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), ++ __strnlen_evex512) + IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_sse2)) + + /* Support sysdeps/x86_64/multiarch/stpncpy.c. */ +@@ -714,6 +724,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && CPU_FEATURE_USABLE (AVX512BW) + && CPU_FEATURE_USABLE (BMI2)), + __wcslen_evex) ++ IFUNC_IMPL_ADD (array, i, wcslen, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), ++ __wcslen_evex512) + IFUNC_IMPL_ADD (array, i, wcslen, + CPU_FEATURE_USABLE (SSE4_1), + __wcslen_sse4_1) +@@ -735,6 +750,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && CPU_FEATURE_USABLE (AVX512BW) + && CPU_FEATURE_USABLE (BMI2)), + __wcsnlen_evex) ++ IFUNC_IMPL_ADD (array, i, wcsnlen, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), ++ __wcsnlen_evex512) + IFUNC_IMPL_ADD (array, i, wcsnlen, + CPU_FEATURE_USABLE (SSE4_1), + __wcsnlen_sse4_1) +diff --git a/sysdeps/x86_64/multiarch/strlen-evex-base.S b/sysdeps/x86_64/multiarch/strlen-evex-base.S +new file mode 100644 +index 0000000000000000..278c899691d89ba7 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strlen-evex-base.S +@@ -0,0 +1,302 @@ ++/* Placeholder function, not used by any processor at the moment. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if IS_IN (libc) ++ ++# include ++ ++# ifdef USE_AS_WCSLEN ++# define VPCMP vpcmpd ++# define VPTESTN vptestnmd ++# define VPMINU vpminud ++# define CHAR_SIZE 4 ++# else ++# define VPCMP vpcmpb ++# define VPTESTN vptestnmb ++# define VPMINU vpminub ++# define CHAR_SIZE 1 ++# endif ++ ++# define XMM0 xmm16 ++# define PAGE_SIZE 4096 ++# define CHAR_PER_VEC (VEC_SIZE / CHAR_SIZE) ++ ++# if VEC_SIZE == 64 ++# define KMOV kmovq ++# define KORTEST kortestq ++# define RAX rax ++# define RCX rcx ++# define RDX rdx ++# define SHR shrq ++# define TEXTSUFFIX evex512 ++# define VMM0 zmm16 ++# define VMM1 zmm17 ++# define VMM2 zmm18 ++# define VMM3 zmm19 ++# define VMM4 zmm20 ++# define VMOVA vmovdqa64 ++# elif VEC_SIZE == 32 ++/* Currently Unused. */ ++# define KMOV kmovd ++# define KORTEST kortestd ++# define RAX eax ++# define RCX ecx ++# define RDX edx ++# define SHR shrl ++# define TEXTSUFFIX evex256 ++# define VMM0 ymm16 ++# define VMM1 ymm17 ++# define VMM2 ymm18 ++# define VMM3 ymm19 ++# define VMM4 ymm20 ++# define VMOVA vmovdqa32 ++# endif ++ ++ .section .text.TEXTSUFFIX, "ax", @progbits ++/* Aligning entry point to 64 byte, provides better performance for ++ one vector length string. */ ++ENTRY_P2ALIGN (STRLEN, 6) ++# ifdef USE_AS_STRNLEN ++ /* Check zero length. */ ++ test %RSI_LP, %RSI_LP ++ jz L(ret_max) ++# ifdef __ILP32__ ++ /* Clear the upper 32 bits. */ ++ movl %esi, %esi ++# endif ++# endif ++ ++ movl %edi, %eax ++ vpxorq %XMM0, %XMM0, %XMM0 ++ andl $(PAGE_SIZE - 1), %eax ++ cmpl $(PAGE_SIZE - VEC_SIZE), %eax ++ ja L(page_cross) ++ ++ /* Compare [w]char for null, mask bit will be set for match. */ ++ VPCMP $0, (%rdi), %VMM0, %k0 ++ KMOV %k0, %RAX ++ test %RAX, %RAX ++ jz L(align_more) ++ ++ bsf %RAX, %RAX ++# ifdef USE_AS_STRNLEN ++ cmpq %rsi, %rax ++ cmovnb %rsi, %rax ++# endif ++ ret ++ ++ /* At this point vector max length reached. */ ++# ifdef USE_AS_STRNLEN ++ .p2align 4,,3 ++L(ret_max): ++ movq %rsi, %rax ++ ret ++# endif ++ ++L(align_more): ++ leaq VEC_SIZE(%rdi), %rax ++ /* Align rax to VEC_SIZE. */ ++ andq $-VEC_SIZE, %rax ++# ifdef USE_AS_STRNLEN ++ movq %rax, %rdx ++ subq %rdi, %rdx ++# ifdef USE_AS_WCSLEN ++ SHR $2, %RDX ++# endif ++ /* At this point rdx contains [w]chars already compared. */ ++ subq %rsi, %rdx ++ jae L(ret_max) ++ negq %rdx ++ /* At this point rdx contains number of w[char] needs to go. ++ Now onwards rdx will keep decrementing with each compare. */ ++# endif ++ ++ /* Loop unroll 4 times for 4 vector loop. */ ++ VPCMP $0, (%rax), %VMM0, %k0 ++ KMOV %k0, %RCX ++ test %RCX, %RCX ++ jnz L(ret_vec_x1) ++ ++# ifdef USE_AS_STRNLEN ++ subq $CHAR_PER_VEC, %rdx ++ jbe L(ret_max) ++# endif ++ ++ VPCMP $0, VEC_SIZE(%rax), %VMM0, %k0 ++ KMOV %k0, %RCX ++ test %RCX, %RCX ++ jnz L(ret_vec_x2) ++ ++# ifdef USE_AS_STRNLEN ++ subq $CHAR_PER_VEC, %rdx ++ jbe L(ret_max) ++# endif ++ ++ VPCMP $0, (VEC_SIZE * 2)(%rax), %VMM0, %k0 ++ KMOV %k0, %RCX ++ test %RCX, %RCX ++ jnz L(ret_vec_x3) ++ ++# ifdef USE_AS_STRNLEN ++ subq $CHAR_PER_VEC, %rdx ++ jbe L(ret_max) ++# endif ++ ++ VPCMP $0, (VEC_SIZE * 3)(%rax), %VMM0, %k0 ++ KMOV %k0, %RCX ++ test %RCX, %RCX ++ jnz L(ret_vec_x4) ++ ++# ifdef USE_AS_STRNLEN ++ subq $CHAR_PER_VEC, %rdx ++ jbe L(ret_max) ++ /* Save pointer before 4 x VEC_SIZE alignment. */ ++ movq %rax, %rcx ++# endif ++ ++ /* Align address to VEC_SIZE * 4 for loop. */ ++ andq $-(VEC_SIZE * 4), %rax ++ ++# ifdef USE_AS_STRNLEN ++ subq %rax, %rcx ++# ifdef USE_AS_WCSLEN ++ SHR $2, %RCX ++# endif ++ /* rcx contains number of [w]char will be recompared due to ++ alignment fixes. rdx must be incremented by rcx to offset ++ alignment adjustment. */ ++ addq %rcx, %rdx ++ /* Need jump as we don't want to add/subtract rdx for first ++ iteration of 4 x VEC_SIZE aligned loop. */ ++ jmp L(loop_entry) ++# endif ++ ++ .p2align 4,,11 ++L(loop): ++# ifdef USE_AS_STRNLEN ++ subq $(CHAR_PER_VEC * 4), %rdx ++ jbe L(ret_max) ++L(loop_entry): ++# endif ++ /* VPMINU and VPCMP combination provide better performance as ++ compared to alternative combinations. */ ++ VMOVA (VEC_SIZE * 4)(%rax), %VMM1 ++ VPMINU (VEC_SIZE * 5)(%rax), %VMM1, %VMM2 ++ VMOVA (VEC_SIZE * 6)(%rax), %VMM3 ++ VPMINU (VEC_SIZE * 7)(%rax), %VMM3, %VMM4 ++ ++ VPTESTN %VMM2, %VMM2, %k0 ++ VPTESTN %VMM4, %VMM4, %k1 ++ ++ subq $-(VEC_SIZE * 4), %rax ++ KORTEST %k0, %k1 ++ jz L(loop) ++ ++ VPTESTN %VMM1, %VMM1, %k2 ++ KMOV %k2, %RCX ++ test %RCX, %RCX ++ jnz L(ret_vec_x1) ++ ++ KMOV %k0, %RCX ++ /* At this point, if k0 is non zero, null char must be in the ++ second vector. */ ++ test %RCX, %RCX ++ jnz L(ret_vec_x2) ++ ++ VPTESTN %VMM3, %VMM3, %k3 ++ KMOV %k3, %RCX ++ test %RCX, %RCX ++ jnz L(ret_vec_x3) ++ /* At this point null [w]char must be in the fourth vector so no ++ need to check. */ ++ KMOV %k1, %RCX ++ ++ /* Fourth, third, second vector terminating are pretty much ++ same, implemented this way to avoid branching and reuse code ++ from pre loop exit condition. */ ++L(ret_vec_x4): ++ bsf %RCX, %RCX ++ subq %rdi, %rax ++# ifdef USE_AS_WCSLEN ++ subq $-(VEC_SIZE * 3), %rax ++ shrq $2, %rax ++ addq %rcx, %rax ++# else ++ leaq (VEC_SIZE * 3)(%rcx, %rax), %rax ++# endif ++# ifdef USE_AS_STRNLEN ++ cmpq %rsi, %rax ++ cmovnb %rsi, %rax ++# endif ++ ret ++ ++L(ret_vec_x3): ++ bsf %RCX, %RCX ++ subq %rdi, %rax ++# ifdef USE_AS_WCSLEN ++ subq $-(VEC_SIZE * 2), %rax ++ shrq $2, %rax ++ addq %rcx, %rax ++# else ++ leaq (VEC_SIZE * 2)(%rcx, %rax), %rax ++# endif ++# ifdef USE_AS_STRNLEN ++ cmpq %rsi, %rax ++ cmovnb %rsi, %rax ++# endif ++ ret ++ ++L(ret_vec_x2): ++ subq $-VEC_SIZE, %rax ++L(ret_vec_x1): ++ bsf %RCX, %RCX ++ subq %rdi, %rax ++# ifdef USE_AS_WCSLEN ++ shrq $2, %rax ++# endif ++ addq %rcx, %rax ++# ifdef USE_AS_STRNLEN ++ cmpq %rsi, %rax ++ cmovnb %rsi, %rax ++# endif ++ ret ++ ++L(page_cross): ++ movl %eax, %ecx ++# ifdef USE_AS_WCSLEN ++ andl $(VEC_SIZE - 1), %ecx ++ sarl $2, %ecx ++# endif ++ /* ecx contains number of w[char] to be skipped as a result ++ of address alignment. */ ++ xorq %rdi, %rax ++ VPCMP $0, (PAGE_SIZE - VEC_SIZE)(%rax), %VMM0, %k0 ++ KMOV %k0, %RAX ++ /* Ignore number of character for alignment adjustment. */ ++ SHR %cl, %RAX ++ jz L(align_more) ++ ++ bsf %RAX, %RAX ++# ifdef USE_AS_STRNLEN ++ cmpq %rsi, %rax ++ cmovnb %rsi, %rax ++# endif ++ ret ++ ++END (STRLEN) ++#endif +diff --git a/sysdeps/x86_64/multiarch/strlen-evex512.S b/sysdeps/x86_64/multiarch/strlen-evex512.S +new file mode 100644 +index 0000000000000000..116f8981c8954e2e +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strlen-evex512.S +@@ -0,0 +1,7 @@ ++#ifndef STRLEN ++# define STRLEN __strlen_evex512 ++#endif ++ ++#define VEC_SIZE 64 ++ ++#include "strlen-evex-base.S" +diff --git a/sysdeps/x86_64/multiarch/strnlen-evex512.S b/sysdeps/x86_64/multiarch/strnlen-evex512.S +new file mode 100644 +index 0000000000000000..0b7f220214a7c33c +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strnlen-evex512.S +@@ -0,0 +1,4 @@ ++#define STRLEN __strnlen_evex512 ++#define USE_AS_STRNLEN 1 ++ ++#include "strlen-evex512.S" +diff --git a/sysdeps/x86_64/multiarch/wcslen-evex512.S b/sysdeps/x86_64/multiarch/wcslen-evex512.S +new file mode 100644 +index 0000000000000000..f59c372b78b4fb8c +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/wcslen-evex512.S +@@ -0,0 +1,4 @@ ++#define STRLEN __wcslen_evex512 ++#define USE_AS_WCSLEN 1 ++ ++#include "strlen-evex512.S" +diff --git a/sysdeps/x86_64/multiarch/wcsnlen-evex512.S b/sysdeps/x86_64/multiarch/wcsnlen-evex512.S +new file mode 100644 +index 0000000000000000..73dcf2f210a85aac +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/wcsnlen-evex512.S +@@ -0,0 +1,5 @@ ++#define STRLEN __wcsnlen_evex512 ++#define USE_AS_WCSLEN 1 ++#define USE_AS_STRNLEN 1 ++ ++#include "strlen-evex512.S" diff --git a/SOURCES/glibc-upstream-2.34-279.patch b/SOURCES/glibc-upstream-2.34-279.patch new file mode 100644 index 0000000..21c99ad --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-279.patch @@ -0,0 +1,33 @@ +commit f6bc52f080e4a0195c707c01f54e2eae0ff89010 +Author: H.J. Lu +Date: Fri May 20 19:21:48 2022 -0700 + + x86-64: Ignore r_addend for R_X86_64_GLOB_DAT/R_X86_64_JUMP_SLOT + + According to x86-64 psABI, r_addend should be ignored for R_X86_64_GLOB_DAT + and R_X86_64_JUMP_SLOT. Since linkers always set their r_addends to 0, we + can ignore their r_addends. + + Reviewed-by: Fangrui Song + (cherry picked from commit f8587a61892cbafd98ce599131bf4f103466f084) + +diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h +index 94296719d4d9fb82..742682517179fab5 100644 +--- a/sysdeps/x86_64/dl-machine.h ++++ b/sysdeps/x86_64/dl-machine.h +@@ -347,11 +347,13 @@ and creates an unsatisfiable circular dependency.\n", + # endif + /* Set to symbol size plus addend. */ + value = sym->st_size; ++ *reloc_addr = value + reloc->r_addend; ++ break; + # endif +- /* Fall through. */ ++ + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: +- *reloc_addr = value + reloc->r_addend; ++ *reloc_addr = value; + break; + + # ifndef RESOLVE_CONFLICT_FIND_MAP diff --git a/SOURCES/glibc-upstream-2.34-28.patch b/SOURCES/glibc-upstream-2.34-28.patch new file mode 100644 index 0000000..7becfe9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-28.patch @@ -0,0 +1,154 @@ +commit 40bade26d5bcbda3d21fb598c5063d9df62de966 +Author: Florian Weimer +Date: Fri Oct 1 18:16:41 2021 +0200 + + nptl: pthread_kill must send signals to a specific thread [BZ #28407] + + The choice between the kill vs tgkill system calls is not just about + the TID reuse race, but also about whether the signal is sent to the + whole process (and any thread in it) or to a specific thread. + + This was caught by the openposix test suite: + + LTP: openposix test suite - FAIL: SIGUSR1 is member of new thread pendingset. + + + Fixes commit 526c3cf11ee9367344b6b15d669e4c3cb461a2be ("nptl: Fix race + between pthread_kill and thread exit (bug 12889)"). + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit eae81d70574e923ce3c59078b8df857ae192efa6) + +diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c +index a44dc8f2d9baa925..35bf1f973eaeda90 100644 +--- a/nptl/pthread_kill.c ++++ b/nptl/pthread_kill.c +@@ -40,7 +40,7 @@ __pthread_kill_implementation (pthread_t threadid, int signo, int no_tid) + below. POSIX only guarantees delivery of a single signal, + which may not be the right one.) */ + pid_t tid = INTERNAL_SYSCALL_CALL (gettid); +- int ret = INTERNAL_SYSCALL_CALL (kill, tid, signo); ++ int ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), tid, signo); + return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; + } + +@@ -59,8 +59,6 @@ __pthread_kill_implementation (pthread_t threadid, int signo, int no_tid) + ret = no_tid; + else + { +- /* Using tgkill is a safety measure. pd->exit_lock ensures that +- the target thread cannot exit. */ + ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), pd->tid, signo); + ret = INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; + } +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index d4bd2d4e3ee6a496..0af9c59b425aefb1 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -121,6 +121,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-pthread-setuid-loop \ + tst-pthread_cancel-exited \ + tst-pthread_cancel-select-loop \ ++ tst-pthread-raise-blocked-self \ + tst-pthread_kill-exited \ + tst-pthread_kill-exiting \ + # tests +diff --git a/sysdeps/pthread/tst-pthread-raise-blocked-self.c b/sysdeps/pthread/tst-pthread-raise-blocked-self.c +new file mode 100644 +index 0000000000000000..128e1a6071c0b15f +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread-raise-blocked-self.c +@@ -0,0 +1,92 @@ ++/* Test that raise sends signal to current thread even if blocked. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Used to create a dummy thread ID distinct from all other thread ++ IDs. */ ++static void * ++noop (void *ignored) ++{ ++ return NULL; ++} ++ ++static volatile pthread_t signal_thread; ++ ++static void ++signal_handler (int signo) ++{ ++ signal_thread = pthread_self (); ++} ++ ++/* Used to ensure that waiting_thread has launched and can accept ++ signals. */ ++static pthread_barrier_t barrier; ++ ++static void * ++waiting_thread (void *ignored) ++{ ++ xpthread_barrier_wait (&barrier); ++ pause (); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ xsignal (SIGUSR1, signal_handler); ++ xpthread_barrier_init (&barrier, NULL, 2); ++ ++ /* Distinct thread ID value to */ ++ pthread_t dummy = xpthread_create (NULL, noop, NULL); ++ signal_thread = dummy; ++ ++ pthread_t helper = xpthread_create (NULL, waiting_thread, NULL); ++ ++ /* Make sure that the thread is running. */ ++ xpthread_barrier_wait (&barrier); ++ ++ /* Block signals on this thread. */ ++ sigset_t set; ++ sigfillset (&set); ++ xpthread_sigmask (SIG_BLOCK, &set, NULL); ++ ++ /* Send the signal to this thread. It must not be delivered. */ ++ raise (SIGUSR1); ++ TEST_VERIFY (signal_thread == dummy); ++ ++ /* Wait a bit to give a chance for signal delivery (increases ++ chances of failure with bug 28407). */ ++ usleep (50 * 1000); ++ ++ /* Unblocking should cause synchronous delivery of the signal. */ ++ xpthread_sigmask (SIG_UNBLOCK, &set, NULL); ++ TEST_VERIFY (signal_thread == pthread_self ()); ++ ++ xpthread_cancel (helper); ++ xpthread_join (helper); ++ xpthread_join (dummy); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-280.patch b/SOURCES/glibc-upstream-2.34-280.patch new file mode 100644 index 0000000..95a58fe --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-280.patch @@ -0,0 +1,356 @@ +commit 82a707aeb74f23bb1783af0f9e93790a2038ff7e +Author: Raghuveer Devulapalli +Date: Mon Jun 6 12:17:43 2022 -0700 + + x86_64: Add strstr function with 512-bit EVEX + + Adding a 512-bit EVEX version of strstr. The algorithm works as follows: + + (1) We spend a few cycles at the begining to peek into the needle. We + locate an edge in the needle (first occurance of 2 consequent distinct + characters) and also store the first 64-bytes into a zmm register. + + (2) We search for the edge in the haystack by looking into one cache + line of the haystack at a time. This avoids having to read past a page + boundary which can cause a seg fault. + + (3) If an edge is found in the haystack we first compare the first + 64-bytes of the needle (already stored in a zmm register) before we + proceed with a full string compare performed byte by byte. + + Benchmarking results: (old = strstr_sse2_unaligned, new = strstr_avx512) + + Geometric mean of all benchmarks: new / old = 0.66 + + Difficult skiptable(0) : new / old = 0.02 + Difficult skiptable(1) : new / old = 0.01 + Difficult 2-way : new / old = 0.25 + Difficult testing first 2 : new / old = 1.26 + Difficult skiptable(0) : new / old = 0.05 + Difficult skiptable(1) : new / old = 0.06 + Difficult 2-way : new / old = 0.26 + Difficult testing first 2 : new / old = 1.05 + Difficult skiptable(0) : new / old = 0.42 + Difficult skiptable(1) : new / old = 0.24 + Difficult 2-way : new / old = 0.21 + Difficult testing first 2 : new / old = 1.04 + Reviewed-by: H.J. Lu + + (cherry picked from commit 5082a287d5e9a1f9cb98b7c982a708a3684f1d5c) + + x86: Remove __mmask intrinsics in strstr-avx512.c + + The intrinsics are not available before GCC7 and using standard + operators generates code of equivalent or better quality. + + Removed: + _cvtmask64_u64 + _kshiftri_mask64 + _kand_mask64 + + Geometric Mean of 5 Runs of Full Benchmark Suite New / Old: 0.958 + + (cherry picked from commit f2698954ff9c2f9626d4bcb5a30eb5729714e0b0) + +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index 4d4ad2a3686b5bc3..0e39e63ef6be6a86 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -126,6 +126,7 @@ sysdep_routines += \ + strrchr-sse2 \ + strspn-c \ + strspn-sse2 \ ++ strstr-avx512 \ + strstr-sse2-unaligned \ + varshift \ + # sysdep_routines +@@ -133,6 +134,7 @@ CFLAGS-varshift.c += -msse4 + CFLAGS-strcspn-c.c += -msse4 + CFLAGS-strpbrk-c.c += -msse4 + CFLAGS-strspn-c.c += -msse4 ++CFLAGS-strstr-avx512.c += -mavx512f -mavx512vl -mavx512dq -mavx512bw -mbmi -mbmi2 -O3 + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index 6b75a7106e174bce..043821278fdb6d8f 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -633,6 +633,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/x86_64/multiarch/strstr.c. */ + IFUNC_IMPL (i, name, strstr, ++ IFUNC_IMPL_ADD (array, i, strstr, ++ (CPU_FEATURE_USABLE (AVX512VL) ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (AVX512DQ) ++ && CPU_FEATURE_USABLE (BMI2)), ++ __strstr_avx512) + IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_sse2)) + +diff --git a/sysdeps/x86_64/multiarch/strstr-avx512.c b/sysdeps/x86_64/multiarch/strstr-avx512.c +new file mode 100644 +index 0000000000000000..e44c1a05dc0007e5 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/strstr-avx512.c +@@ -0,0 +1,218 @@ ++/* strstr optimized with 512-bit AVX-512 instructions ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#define FULL_MMASK64 0xffffffffffffffff ++#define ONE_64BIT 0x1ull ++#define ZMM_SIZE_IN_BYTES 64 ++#define PAGESIZE 4096 ++ ++#define cvtmask64_u64(...) (uint64_t) (__VA_ARGS__) ++#define kshiftri_mask64(x, y) ((x) >> (y)) ++#define kand_mask64(x, y) ((x) & (y)) ++ ++/* ++ Returns the index of the first edge within the needle, returns 0 if no edge ++ is found. Example: 'ab' is the first edge in 'aaaaaaaaaabaarddg' ++ */ ++static inline size_t ++find_edge_in_needle (const char *ned) ++{ ++ size_t ind = 0; ++ while (ned[ind + 1] != '\0') ++ { ++ if (ned[ind] != ned[ind + 1]) ++ return ind; ++ else ++ ind = ind + 1; ++ } ++ return 0; ++} ++ ++/* ++ Compare needle with haystack byte by byte at specified location ++ */ ++static inline bool ++verify_string_match (const char *hay, const size_t hay_index, const char *ned, ++ size_t ind) ++{ ++ while (ned[ind] != '\0') ++ { ++ if (ned[ind] != hay[hay_index + ind]) ++ return false; ++ ind = ind + 1; ++ } ++ return true; ++} ++ ++/* ++ Compare needle with haystack at specified location. The first 64 bytes are ++ compared using a ZMM register. ++ */ ++static inline bool ++verify_string_match_avx512 (const char *hay, const size_t hay_index, ++ const char *ned, const __mmask64 ned_mask, ++ const __m512i ned_zmm) ++{ ++ /* check first 64 bytes using zmm and then scalar */ ++ __m512i hay_zmm = _mm512_loadu_si512 (hay + hay_index); // safe to do so ++ __mmask64 match = _mm512_mask_cmpneq_epi8_mask (ned_mask, hay_zmm, ned_zmm); ++ if (match != 0x0) // failed the first few chars ++ return false; ++ else if (ned_mask == FULL_MMASK64) ++ return verify_string_match (hay, hay_index, ned, ZMM_SIZE_IN_BYTES); ++ return true; ++} ++ ++char * ++__strstr_avx512 (const char *haystack, const char *ned) ++{ ++ char first = ned[0]; ++ if (first == '\0') ++ return (char *)haystack; ++ if (ned[1] == '\0') ++ return (char *)strchr (haystack, ned[0]); ++ ++ size_t edge = find_edge_in_needle (ned); ++ ++ /* ensure haystack is as long as the pos of edge in needle */ ++ for (int ii = 0; ii < edge; ++ii) ++ { ++ if (haystack[ii] == '\0') ++ return NULL; ++ } ++ ++ /* ++ Load 64 bytes of the needle and save it to a zmm register ++ Read one cache line at a time to avoid loading across a page boundary ++ */ ++ __mmask64 ned_load_mask = _bzhi_u64 ( ++ FULL_MMASK64, 64 - ((uintptr_t) (ned) & 63)); ++ __m512i ned_zmm = _mm512_maskz_loadu_epi8 (ned_load_mask, ned); ++ __mmask64 ned_nullmask ++ = _mm512_mask_testn_epi8_mask (ned_load_mask, ned_zmm, ned_zmm); ++ ++ if (__glibc_unlikely (ned_nullmask == 0x0)) ++ { ++ ned_zmm = _mm512_loadu_si512 (ned); ++ ned_nullmask = _mm512_testn_epi8_mask (ned_zmm, ned_zmm); ++ ned_load_mask = ned_nullmask ^ (ned_nullmask - ONE_64BIT); ++ if (ned_nullmask != 0x0) ++ ned_load_mask = ned_load_mask >> 1; ++ } ++ else ++ { ++ ned_load_mask = ned_nullmask ^ (ned_nullmask - ONE_64BIT); ++ ned_load_mask = ned_load_mask >> 1; ++ } ++ const __m512i ned0 = _mm512_set1_epi8 (ned[edge]); ++ const __m512i ned1 = _mm512_set1_epi8 (ned[edge + 1]); ++ ++ /* ++ Read the bytes of haystack in the current cache line ++ */ ++ size_t hay_index = edge; ++ __mmask64 loadmask = _bzhi_u64 ( ++ FULL_MMASK64, 64 - ((uintptr_t) (haystack + hay_index) & 63)); ++ /* First load is a partial cache line */ ++ __m512i hay0 = _mm512_maskz_loadu_epi8 (loadmask, haystack + hay_index); ++ /* Search for NULL and compare only till null char */ ++ uint64_t nullmask ++ = cvtmask64_u64 (_mm512_mask_testn_epi8_mask (loadmask, hay0, hay0)); ++ uint64_t cmpmask = nullmask ^ (nullmask - ONE_64BIT); ++ cmpmask = cmpmask & cvtmask64_u64 (loadmask); ++ /* Search for the 2 charaters of needle */ ++ __mmask64 k0 = _mm512_cmpeq_epi8_mask (hay0, ned0); ++ __mmask64 k1 = _mm512_cmpeq_epi8_mask (hay0, ned1); ++ k1 = kshiftri_mask64 (k1, 1); ++ /* k2 masks tell us if both chars from needle match */ ++ uint64_t k2 = cvtmask64_u64 (kand_mask64 (k0, k1)) & cmpmask; ++ /* For every match, search for the entire needle for a full match */ ++ while (k2) ++ { ++ uint64_t bitcount = _tzcnt_u64 (k2); ++ k2 = _blsr_u64 (k2); ++ size_t match_pos = hay_index + bitcount - edge; ++ if (((uintptr_t) (haystack + match_pos) & (PAGESIZE - 1)) ++ < PAGESIZE - 1 - ZMM_SIZE_IN_BYTES) ++ { ++ /* ++ * Use vector compare as long as you are not crossing a page ++ */ ++ if (verify_string_match_avx512 (haystack, match_pos, ned, ++ ned_load_mask, ned_zmm)) ++ return (char *)haystack + match_pos; ++ } ++ else ++ { ++ if (verify_string_match (haystack, match_pos, ned, 0)) ++ return (char *)haystack + match_pos; ++ } ++ } ++ /* We haven't checked for potential match at the last char yet */ ++ haystack = (const char *)(((uintptr_t) (haystack + hay_index) | 63)); ++ hay_index = 0; ++ ++ /* ++ Loop over one cache line at a time to prevent reading over page ++ boundary ++ */ ++ __m512i hay1; ++ while (nullmask == 0) ++ { ++ hay0 = _mm512_loadu_si512 (haystack + hay_index); ++ hay1 = _mm512_load_si512 (haystack + hay_index ++ + 1); // Always 64 byte aligned ++ nullmask = cvtmask64_u64 (_mm512_testn_epi8_mask (hay1, hay1)); ++ /* Compare only till null char */ ++ cmpmask = nullmask ^ (nullmask - ONE_64BIT); ++ k0 = _mm512_cmpeq_epi8_mask (hay0, ned0); ++ k1 = _mm512_cmpeq_epi8_mask (hay1, ned1); ++ /* k2 masks tell us if both chars from needle match */ ++ k2 = cvtmask64_u64 (kand_mask64 (k0, k1)) & cmpmask; ++ /* For every match, compare full strings for potential match */ ++ while (k2) ++ { ++ uint64_t bitcount = _tzcnt_u64 (k2); ++ k2 = _blsr_u64 (k2); ++ size_t match_pos = hay_index + bitcount - edge; ++ if (((uintptr_t) (haystack + match_pos) & (PAGESIZE - 1)) ++ < PAGESIZE - 1 - ZMM_SIZE_IN_BYTES) ++ { ++ /* ++ * Use vector compare as long as you are not crossing a page ++ */ ++ if (verify_string_match_avx512 (haystack, match_pos, ned, ++ ned_load_mask, ned_zmm)) ++ return (char *)haystack + match_pos; ++ } ++ else ++ { ++ /* Compare byte by byte */ ++ if (verify_string_match (haystack, match_pos, ned, 0)) ++ return (char *)haystack + match_pos; ++ } ++ } ++ hay_index += ZMM_SIZE_IN_BYTES; ++ } ++ return NULL; ++} +diff --git a/sysdeps/x86_64/multiarch/strstr.c b/sysdeps/x86_64/multiarch/strstr.c +index 848601bde7583ca3..9474d6234e9b62d3 100644 +--- a/sysdeps/x86_64/multiarch/strstr.c ++++ b/sysdeps/x86_64/multiarch/strstr.c +@@ -35,16 +35,32 @@ + + extern __typeof (__redirect_strstr) __strstr_sse2_unaligned attribute_hidden; + extern __typeof (__redirect_strstr) __strstr_sse2 attribute_hidden; ++extern __typeof (__redirect_strstr) __strstr_avx512 attribute_hidden; + + #include "init-arch.h" + + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + extern __typeof (__redirect_strstr) __libc_strstr; +-libc_ifunc (__libc_strstr, +- HAS_ARCH_FEATURE (Fast_Unaligned_Load) +- ? __strstr_sse2_unaligned +- : __strstr_sse2) + ++static inline void * ++IFUNC_SELECTOR (void) ++{ ++ const struct cpu_features *cpu_features = __get_cpu_features (); ++ ++ if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_AVX512) ++ && CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) ++ && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) ++ && CPU_FEATURE_USABLE_P (cpu_features, AVX512DQ) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI2)) ++ return __strstr_avx512; ++ ++ if (CPU_FEATURES_ARCH_P (cpu_features, Fast_Unaligned_Load)) ++ return __strstr_sse2_unaligned; ++ ++ return __strstr_sse2; ++} ++ ++libc_ifunc_redirected (__redirect_strstr, __libc_strstr, IFUNC_SELECTOR ()); + #undef strstr + strong_alias (__libc_strstr, strstr) diff --git a/SOURCES/glibc-upstream-2.34-281.patch b/SOURCES/glibc-upstream-2.34-281.patch new file mode 100644 index 0000000..3a32378 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-281.patch @@ -0,0 +1,385 @@ +commit 70be93d1c58916d289a5e6e7c7d9b989707a9e41 +Author: Noah Goldstein +Date: Mon Jun 6 21:11:27 2022 -0700 + + x86: Create header for VEC classes in x86 strings library + + This patch does not touch any existing code and is only meant to be a + tool for future patches so that simple source files can more easily be + maintained to target multiple VEC classes. + + There is no difference in the objdump of libc.so before and after this + patch. + Reviewed-by: H.J. Lu + + (cherry picked from commit 8a780a6b910023e71f3173f37f0793834c047554) + +diff --git a/sysdeps/x86_64/multiarch/avx-rtm-vecs.h b/sysdeps/x86_64/multiarch/avx-rtm-vecs.h +new file mode 100644 +index 0000000000000000..3f531dd47fceefe9 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/avx-rtm-vecs.h +@@ -0,0 +1,34 @@ ++/* Common config for AVX-RTM VECs ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _AVX_RTM_VECS_H ++#define _AVX_RTM_VECS_H 1 ++ ++#define ZERO_UPPER_VEC_REGISTERS_RETURN \ ++ ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST ++ ++#define VZEROUPPER_RETURN jmp L(return_vzeroupper) ++ ++#define USE_WITH_RTM 1 ++#include "avx-vecs.h" ++ ++#undef SECTION ++#define SECTION(p) p##.avx.rtm ++ ++#endif +diff --git a/sysdeps/x86_64/multiarch/avx-vecs.h b/sysdeps/x86_64/multiarch/avx-vecs.h +new file mode 100644 +index 0000000000000000..89680f5db827c332 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/avx-vecs.h +@@ -0,0 +1,47 @@ ++/* Common config for AVX VECs ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _AVX_VECS_H ++#define _AVX_VECS_H 1 ++ ++#ifdef VEC_SIZE ++# error "Multiple VEC configs included!" ++#endif ++ ++#define VEC_SIZE 32 ++#include "vec-macros.h" ++ ++#define USE_WITH_AVX 1 ++#define SECTION(p) p##.avx ++ ++/* 4-byte mov instructions with AVX2. */ ++#define MOV_SIZE 4 ++/* 1 (ret) + 3 (vzeroupper). */ ++#define RET_SIZE 4 ++#define VZEROUPPER vzeroupper ++ ++#define VMOVU vmovdqu ++#define VMOVA vmovdqa ++#define VMOVNT vmovntdq ++ ++/* Often need to access xmm portion. */ ++#define VEC_xmm VEC_any_xmm ++#define VEC VEC_any_ymm ++ ++#endif +diff --git a/sysdeps/x86_64/multiarch/evex-vecs-common.h b/sysdeps/x86_64/multiarch/evex-vecs-common.h +new file mode 100644 +index 0000000000000000..99806ebcd7bde53d +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/evex-vecs-common.h +@@ -0,0 +1,39 @@ ++/* Common config for EVEX256 and EVEX512 VECs ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _EVEX_VECS_COMMON_H ++#define _EVEX_VECS_COMMON_H 1 ++ ++#include "vec-macros.h" ++ ++/* 6-byte mov instructions with EVEX. */ ++#define MOV_SIZE 6 ++/* No vzeroupper needed. */ ++#define RET_SIZE 1 ++#define VZEROUPPER ++ ++#define VMOVU vmovdqu64 ++#define VMOVA vmovdqa64 ++#define VMOVNT vmovntdq ++ ++#define VEC_xmm VEC_hi_xmm ++#define VEC_ymm VEC_hi_ymm ++#define VEC_zmm VEC_hi_zmm ++ ++#endif +diff --git a/sysdeps/x86_64/multiarch/evex256-vecs.h b/sysdeps/x86_64/multiarch/evex256-vecs.h +new file mode 100644 +index 0000000000000000..222ba46dc74cfcbd +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/evex256-vecs.h +@@ -0,0 +1,35 @@ ++/* Common config for EVEX256 VECs ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _EVEX256_VECS_H ++#define _EVEX256_VECS_H 1 ++ ++#ifdef VEC_SIZE ++# error "Multiple VEC configs included!" ++#endif ++ ++#define VEC_SIZE 32 ++#include "evex-vecs-common.h" ++ ++#define USE_WITH_EVEX256 1 ++#define SECTION(p) p##.evex ++ ++#define VEC VEC_ymm ++ ++#endif +diff --git a/sysdeps/x86_64/multiarch/evex512-vecs.h b/sysdeps/x86_64/multiarch/evex512-vecs.h +new file mode 100644 +index 0000000000000000..d1784d5368d8cebe +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/evex512-vecs.h +@@ -0,0 +1,35 @@ ++/* Common config for EVEX512 VECs ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _EVEX512_VECS_H ++#define _EVEX512_VECS_H 1 ++ ++#ifdef VEC_SIZE ++# error "Multiple VEC configs included!" ++#endif ++ ++#define VEC_SIZE 64 ++#include "evex-vecs-common.h" ++ ++#define USE_WITH_EVEX512 1 ++#define SECTION(p) p##.evex512 ++ ++#define VEC VEC_zmm ++ ++#endif +diff --git a/sysdeps/x86_64/multiarch/sse2-vecs.h b/sysdeps/x86_64/multiarch/sse2-vecs.h +new file mode 100644 +index 0000000000000000..2b77a59d56ff2660 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/sse2-vecs.h +@@ -0,0 +1,47 @@ ++/* Common config for SSE2 VECs ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SSE2_VECS_H ++#define _SSE2_VECS_H 1 ++ ++#ifdef VEC_SIZE ++# error "Multiple VEC configs included!" ++#endif ++ ++#define VEC_SIZE 16 ++#include "vec-macros.h" ++ ++#define USE_WITH_SSE2 1 ++#define SECTION(p) p ++ ++/* 3-byte mov instructions with SSE2. */ ++#define MOV_SIZE 3 ++/* No vzeroupper needed. */ ++#define RET_SIZE 1 ++#define VZEROUPPER ++ ++#define VMOVU movups ++#define VMOVA movaps ++#define VMOVNT movntdq ++ ++#define VEC_xmm VEC_any_xmm ++#define VEC VEC_any_xmm ++ ++ ++#endif +diff --git a/sysdeps/x86_64/multiarch/vec-macros.h b/sysdeps/x86_64/multiarch/vec-macros.h +new file mode 100644 +index 0000000000000000..9f3ffecede9feb26 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/vec-macros.h +@@ -0,0 +1,90 @@ ++/* Macro helpers for VEC_{type}({vec_num}) ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _VEC_MACROS_H ++#define _VEC_MACROS_H 1 ++ ++#ifndef VEC_SIZE ++# error "Never include this file directly. Always include a vector config." ++#endif ++ ++/* Defines so we can use SSE2 / AVX2 / EVEX / EVEX512 encoding with same ++ VEC(N) values. */ ++#define VEC_hi_xmm0 xmm16 ++#define VEC_hi_xmm1 xmm17 ++#define VEC_hi_xmm2 xmm18 ++#define VEC_hi_xmm3 xmm19 ++#define VEC_hi_xmm4 xmm20 ++#define VEC_hi_xmm5 xmm21 ++#define VEC_hi_xmm6 xmm22 ++#define VEC_hi_xmm7 xmm23 ++#define VEC_hi_xmm8 xmm24 ++#define VEC_hi_xmm9 xmm25 ++#define VEC_hi_xmm10 xmm26 ++#define VEC_hi_xmm11 xmm27 ++#define VEC_hi_xmm12 xmm28 ++#define VEC_hi_xmm13 xmm29 ++#define VEC_hi_xmm14 xmm30 ++#define VEC_hi_xmm15 xmm31 ++ ++#define VEC_hi_ymm0 ymm16 ++#define VEC_hi_ymm1 ymm17 ++#define VEC_hi_ymm2 ymm18 ++#define VEC_hi_ymm3 ymm19 ++#define VEC_hi_ymm4 ymm20 ++#define VEC_hi_ymm5 ymm21 ++#define VEC_hi_ymm6 ymm22 ++#define VEC_hi_ymm7 ymm23 ++#define VEC_hi_ymm8 ymm24 ++#define VEC_hi_ymm9 ymm25 ++#define VEC_hi_ymm10 ymm26 ++#define VEC_hi_ymm11 ymm27 ++#define VEC_hi_ymm12 ymm28 ++#define VEC_hi_ymm13 ymm29 ++#define VEC_hi_ymm14 ymm30 ++#define VEC_hi_ymm15 ymm31 ++ ++#define VEC_hi_zmm0 zmm16 ++#define VEC_hi_zmm1 zmm17 ++#define VEC_hi_zmm2 zmm18 ++#define VEC_hi_zmm3 zmm19 ++#define VEC_hi_zmm4 zmm20 ++#define VEC_hi_zmm5 zmm21 ++#define VEC_hi_zmm6 zmm22 ++#define VEC_hi_zmm7 zmm23 ++#define VEC_hi_zmm8 zmm24 ++#define VEC_hi_zmm9 zmm25 ++#define VEC_hi_zmm10 zmm26 ++#define VEC_hi_zmm11 zmm27 ++#define VEC_hi_zmm12 zmm28 ++#define VEC_hi_zmm13 zmm29 ++#define VEC_hi_zmm14 zmm30 ++#define VEC_hi_zmm15 zmm31 ++ ++#define PRIMITIVE_VEC(vec, num) vec##num ++ ++#define VEC_any_xmm(i) PRIMITIVE_VEC(xmm, i) ++#define VEC_any_ymm(i) PRIMITIVE_VEC(ymm, i) ++#define VEC_any_zmm(i) PRIMITIVE_VEC(zmm, i) ++ ++#define VEC_hi_xmm(i) PRIMITIVE_VEC(VEC_hi_xmm, i) ++#define VEC_hi_ymm(i) PRIMITIVE_VEC(VEC_hi_ymm, i) ++#define VEC_hi_zmm(i) PRIMITIVE_VEC(VEC_hi_zmm, i) ++ ++#endif diff --git a/SOURCES/glibc-upstream-2.34-282.patch b/SOURCES/glibc-upstream-2.34-282.patch new file mode 100644 index 0000000..b1c9c0d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-282.patch @@ -0,0 +1,90 @@ +commit e805606193e1a39956ca5ef73cb44a8796730686 +Author: Noah Goldstein +Date: Mon Jun 6 21:11:28 2022 -0700 + + x86: Add COND_VZEROUPPER that can replace vzeroupper if no `ret` + + The RTM vzeroupper mitigation has no way of replacing inline + vzeroupper not before a return. + + This can be useful when hoisting a vzeroupper to save code size + for example: + + ``` + L(foo): + cmpl %eax, %edx + jz L(bar) + tzcntl %eax, %eax + addq %rdi, %rax + VZEROUPPER_RETURN + + L(bar): + xorl %eax, %eax + VZEROUPPER_RETURN + ``` + + Can become: + + ``` + L(foo): + COND_VZEROUPPER + cmpl %eax, %edx + jz L(bar) + tzcntl %eax, %eax + addq %rdi, %rax + ret + + L(bar): + xorl %eax, %eax + ret + ``` + + This code does not change any existing functionality. + + There is no difference in the objdump of libc.so before and after this + patch. + Reviewed-by: H.J. Lu + + (cherry picked from commit dd5c483b2598f411428df4d8864c15c4b8a3cd68) + +diff --git a/sysdeps/x86_64/multiarch/avx-rtm-vecs.h b/sysdeps/x86_64/multiarch/avx-rtm-vecs.h +index 3f531dd47fceefe9..6ca9f5e6bae7ba72 100644 +--- a/sysdeps/x86_64/multiarch/avx-rtm-vecs.h ++++ b/sysdeps/x86_64/multiarch/avx-rtm-vecs.h +@@ -20,6 +20,7 @@ + #ifndef _AVX_RTM_VECS_H + #define _AVX_RTM_VECS_H 1 + ++#define COND_VZEROUPPER COND_VZEROUPPER_XTEST + #define ZERO_UPPER_VEC_REGISTERS_RETURN \ + ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST + +diff --git a/sysdeps/x86_64/sysdep.h b/sysdeps/x86_64/sysdep.h +index 7bebdeb21095eda0..93e44be22e2275f1 100644 +--- a/sysdeps/x86_64/sysdep.h ++++ b/sysdeps/x86_64/sysdep.h +@@ -106,6 +106,24 @@ lose: \ + vzeroupper; \ + ret + ++/* Can be used to replace vzeroupper that is not directly before a ++ return. This is useful when hoisting a vzeroupper from multiple ++ return paths to decrease the total number of vzerouppers and code ++ size. */ ++#define COND_VZEROUPPER_XTEST \ ++ xtest; \ ++ jz 1f; \ ++ vzeroall; \ ++ jmp 2f; \ ++1: \ ++ vzeroupper; \ ++2: ++ ++/* In RTM define this as COND_VZEROUPPER_XTEST. */ ++#ifndef COND_VZEROUPPER ++# define COND_VZEROUPPER vzeroupper ++#endif ++ + /* Zero upper vector registers and return. */ + #ifndef ZERO_UPPER_VEC_REGISTERS_RETURN + # define ZERO_UPPER_VEC_REGISTERS_RETURN \ diff --git a/SOURCES/glibc-upstream-2.34-283.patch b/SOURCES/glibc-upstream-2.34-283.patch new file mode 100644 index 0000000..7745fef --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-283.patch @@ -0,0 +1,696 @@ +commit 4901009dad8b3ab141ac6e0caebe99e03a67f5eb +Author: Noah Goldstein +Date: Mon Jun 6 21:11:30 2022 -0700 + + x86: Optimize memrchr-sse2.S + + The new code: + 1. prioritizes smaller lengths more. + 2. optimizes target placement more carefully. + 3. reuses logic more. + 4. fixes up various inefficiencies in the logic. + + The total code size saving is: 394 bytes + Geometric Mean of all benchmarks New / Old: 0.874 + + Regressions: + 1. The page cross case is now colder, especially re-entry from the + page cross case if a match is not found in the first VEC + (roughly 50%). My general opinion with this patch is this is + acceptable given the "coldness" of this case (less than 4%) and + generally performance improvement in the other far more common + cases. + + 2. There are some regressions 5-15% for medium/large user-arg + lengths that have a match in the first VEC. This is because the + logic was rewritten to optimize finds in the first VEC if the + user-arg length is shorter (where we see roughly 20-50% + performance improvements). It is not always the case this is a + regression. My intuition is some frontend quirk is partially + explaining the data although I haven't been able to find the + root cause. + + Full xcheck passes on x86_64. + Reviewed-by: H.J. Lu + + (cherry picked from commit 731feee3869550e93177e604604c1765d81de571) + +diff --git a/sysdeps/x86_64/memrchr.S b/sysdeps/x86_64/memrchr.S +index cc2001167d77c83c..c2a5902bf9385c67 100644 +--- a/sysdeps/x86_64/memrchr.S ++++ b/sysdeps/x86_64/memrchr.S +@@ -19,362 +19,333 @@ + . */ + + #include ++#define VEC_SIZE 16 ++#define PAGE_SIZE 4096 + + .text +-ENTRY (__memrchr) +- movd %esi, %xmm1 +- +- sub $16, %RDX_LP +- jbe L(length_less16) +- +- punpcklbw %xmm1, %xmm1 +- punpcklbw %xmm1, %xmm1 +- +- add %RDX_LP, %RDI_LP +- pshufd $0, %xmm1, %xmm1 +- +- movdqu (%rdi), %xmm0 +- pcmpeqb %xmm1, %xmm0 +- +-/* Check if there is a match. */ +- pmovmskb %xmm0, %eax +- test %eax, %eax +- jnz L(matches0) +- +- sub $64, %rdi +- mov %edi, %ecx +- and $15, %ecx +- jz L(loop_prolog) +- +- add $16, %rdi +- add $16, %rdx +- and $-16, %rdi +- sub %rcx, %rdx +- +- .p2align 4 +-L(loop_prolog): +- sub $64, %rdx +- jbe L(exit_loop) +- +- movdqa 48(%rdi), %xmm0 +- pcmpeqb %xmm1, %xmm0 +- pmovmskb %xmm0, %eax +- test %eax, %eax +- jnz L(matches48) +- +- movdqa 32(%rdi), %xmm2 +- pcmpeqb %xmm1, %xmm2 +- pmovmskb %xmm2, %eax +- test %eax, %eax +- jnz L(matches32) +- +- movdqa 16(%rdi), %xmm3 +- pcmpeqb %xmm1, %xmm3 +- pmovmskb %xmm3, %eax +- test %eax, %eax +- jnz L(matches16) +- +- movdqa (%rdi), %xmm4 +- pcmpeqb %xmm1, %xmm4 +- pmovmskb %xmm4, %eax +- test %eax, %eax +- jnz L(matches0) +- +- sub $64, %rdi +- sub $64, %rdx +- jbe L(exit_loop) +- +- movdqa 48(%rdi), %xmm0 +- pcmpeqb %xmm1, %xmm0 +- pmovmskb %xmm0, %eax +- test %eax, %eax +- jnz L(matches48) +- +- movdqa 32(%rdi), %xmm2 +- pcmpeqb %xmm1, %xmm2 +- pmovmskb %xmm2, %eax +- test %eax, %eax +- jnz L(matches32) +- +- movdqa 16(%rdi), %xmm3 +- pcmpeqb %xmm1, %xmm3 +- pmovmskb %xmm3, %eax +- test %eax, %eax +- jnz L(matches16) +- +- movdqa (%rdi), %xmm3 +- pcmpeqb %xmm1, %xmm3 +- pmovmskb %xmm3, %eax +- test %eax, %eax +- jnz L(matches0) +- +- mov %edi, %ecx +- and $63, %ecx +- jz L(align64_loop) +- +- add $64, %rdi +- add $64, %rdx +- and $-64, %rdi +- sub %rcx, %rdx +- +- .p2align 4 +-L(align64_loop): +- sub $64, %rdi +- sub $64, %rdx +- jbe L(exit_loop) +- +- movdqa (%rdi), %xmm0 +- movdqa 16(%rdi), %xmm2 +- movdqa 32(%rdi), %xmm3 +- movdqa 48(%rdi), %xmm4 +- +- pcmpeqb %xmm1, %xmm0 +- pcmpeqb %xmm1, %xmm2 +- pcmpeqb %xmm1, %xmm3 +- pcmpeqb %xmm1, %xmm4 +- +- pmaxub %xmm3, %xmm0 +- pmaxub %xmm4, %xmm2 +- pmaxub %xmm0, %xmm2 +- pmovmskb %xmm2, %eax +- +- test %eax, %eax +- jz L(align64_loop) +- +- pmovmskb %xmm4, %eax +- test %eax, %eax +- jnz L(matches48) +- +- pmovmskb %xmm3, %eax +- test %eax, %eax +- jnz L(matches32) +- +- movdqa 16(%rdi), %xmm2 +- +- pcmpeqb %xmm1, %xmm2 +- pcmpeqb (%rdi), %xmm1 +- +- pmovmskb %xmm2, %eax +- test %eax, %eax +- jnz L(matches16) +- +- pmovmskb %xmm1, %eax +- bsr %eax, %eax +- +- add %rdi, %rax ++ENTRY_P2ALIGN(__memrchr, 6) ++#ifdef __ILP32__ ++ /* Clear upper bits. */ ++ mov %RDX_LP, %RDX_LP ++#endif ++ movd %esi, %xmm0 ++ ++ /* Get end pointer. */ ++ leaq (%rdx, %rdi), %rcx ++ ++ punpcklbw %xmm0, %xmm0 ++ punpcklwd %xmm0, %xmm0 ++ pshufd $0, %xmm0, %xmm0 ++ ++ /* Check if we can load 1x VEC without cross a page. */ ++ testl $(PAGE_SIZE - VEC_SIZE), %ecx ++ jz L(page_cross) ++ ++ /* NB: This load happens regardless of whether rdx (len) is zero. Since ++ it doesn't cross a page and the standard gurantees any pointer have ++ at least one-valid byte this load must be safe. For the entire ++ history of the x86 memrchr implementation this has been possible so ++ no code "should" be relying on a zero-length check before this load. ++ The zero-length check is moved to the page cross case because it is ++ 1) pretty cold and including it pushes the hot case len <= VEC_SIZE ++ into 2-cache lines. */ ++ movups -(VEC_SIZE)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ ++ subq $VEC_SIZE, %rdx ++ ja L(more_1x_vec) ++L(ret_vec_x0_test): ++ /* Zero-flag set if eax (src) is zero. Destination unchanged if src is ++ zero. */ ++ bsrl %eax, %eax ++ jz L(ret_0) ++ /* Check if the CHAR match is in bounds. Need to truly zero `eax` here ++ if out of bounds. */ ++ addl %edx, %eax ++ jl L(zero_0) ++ /* Since we subtracted VEC_SIZE from rdx earlier we can just add to base ++ ptr. */ ++ addq %rdi, %rax ++L(ret_0): + ret + +- .p2align 4 +-L(exit_loop): +- add $64, %edx +- cmp $32, %edx +- jbe L(exit_loop_32) +- +- movdqa 48(%rdi), %xmm0 +- pcmpeqb %xmm1, %xmm0 +- pmovmskb %xmm0, %eax +- test %eax, %eax +- jnz L(matches48) +- +- movdqa 32(%rdi), %xmm2 +- pcmpeqb %xmm1, %xmm2 +- pmovmskb %xmm2, %eax +- test %eax, %eax +- jnz L(matches32) +- +- movdqa 16(%rdi), %xmm3 +- pcmpeqb %xmm1, %xmm3 +- pmovmskb %xmm3, %eax +- test %eax, %eax +- jnz L(matches16_1) +- cmp $48, %edx +- jbe L(return_null) +- +- pcmpeqb (%rdi), %xmm1 +- pmovmskb %xmm1, %eax +- test %eax, %eax +- jnz L(matches0_1) +- xor %eax, %eax ++ .p2align 4,, 5 ++L(ret_vec_x0): ++ bsrl %eax, %eax ++ leaq -(VEC_SIZE)(%rcx, %rax), %rax + ret + +- .p2align 4 +-L(exit_loop_32): +- movdqa 48(%rdi), %xmm0 +- pcmpeqb %xmm1, %xmm0 +- pmovmskb %xmm0, %eax +- test %eax, %eax +- jnz L(matches48_1) +- cmp $16, %edx +- jbe L(return_null) +- +- pcmpeqb 32(%rdi), %xmm1 +- pmovmskb %xmm1, %eax +- test %eax, %eax +- jnz L(matches32_1) +- xor %eax, %eax ++ .p2align 4,, 2 ++L(zero_0): ++ xorl %eax, %eax + ret + +- .p2align 4 +-L(matches0): +- bsr %eax, %eax +- add %rdi, %rax +- ret +- +- .p2align 4 +-L(matches16): +- bsr %eax, %eax +- lea 16(%rax, %rdi), %rax +- ret + +- .p2align 4 +-L(matches32): +- bsr %eax, %eax +- lea 32(%rax, %rdi), %rax ++ .p2align 4,, 8 ++L(more_1x_vec): ++ testl %eax, %eax ++ jnz L(ret_vec_x0) ++ ++ /* Align rcx (pointer to string). */ ++ decq %rcx ++ andq $-VEC_SIZE, %rcx ++ ++ movq %rcx, %rdx ++ /* NB: We could consistenyl save 1-byte in this pattern with `movaps ++ %xmm0, %xmm1; pcmpeq IMM8(r), %xmm1; ...`. The reason against it is ++ it adds more frontend uops (even if the moves can be eliminated) and ++ some percentage of the time actual backend uops. */ ++ movaps -(VEC_SIZE)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ subq %rdi, %rdx ++ pmovmskb %xmm1, %eax ++ ++ cmpq $(VEC_SIZE * 2), %rdx ++ ja L(more_2x_vec) ++L(last_2x_vec): ++ subl $VEC_SIZE, %edx ++ jbe L(ret_vec_x0_test) ++ ++ testl %eax, %eax ++ jnz L(ret_vec_x0) ++ ++ movaps -(VEC_SIZE * 2)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ ++ subl $VEC_SIZE, %edx ++ bsrl %eax, %eax ++ jz L(ret_1) ++ addl %edx, %eax ++ jl L(zero_0) ++ addq %rdi, %rax ++L(ret_1): + ret + +- .p2align 4 +-L(matches48): +- bsr %eax, %eax +- lea 48(%rax, %rdi), %rax ++ /* Don't align. Otherwise lose 2-byte encoding in jump to L(page_cross) ++ causes the hot pause (length <= VEC_SIZE) to span multiple cache ++ lines. Naturally aligned % 16 to 8-bytes. */ ++L(page_cross): ++ /* Zero length check. */ ++ testq %rdx, %rdx ++ jz L(zero_0) ++ ++ leaq -1(%rcx), %r8 ++ andq $-(VEC_SIZE), %r8 ++ ++ movaps (%r8), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %esi ++ /* Shift out negative alignment (because we are starting from endptr and ++ working backwards). */ ++ negl %ecx ++ /* 32-bit shift but VEC_SIZE=16 so need to mask the shift count ++ explicitly. */ ++ andl $(VEC_SIZE - 1), %ecx ++ shl %cl, %esi ++ movzwl %si, %eax ++ leaq (%rdi, %rdx), %rcx ++ cmpq %rdi, %r8 ++ ja L(more_1x_vec) ++ subl $VEC_SIZE, %edx ++ bsrl %eax, %eax ++ jz L(ret_2) ++ addl %edx, %eax ++ jl L(zero_1) ++ addq %rdi, %rax ++L(ret_2): + ret + +- .p2align 4 +-L(matches0_1): +- bsr %eax, %eax +- sub $64, %rdx +- add %rax, %rdx +- jl L(return_null) +- add %rdi, %rax ++ /* Fits in aliging bytes. */ ++L(zero_1): ++ xorl %eax, %eax + ret + +- .p2align 4 +-L(matches16_1): +- bsr %eax, %eax +- sub $48, %rdx +- add %rax, %rdx +- jl L(return_null) +- lea 16(%rdi, %rax), %rax ++ .p2align 4,, 5 ++L(ret_vec_x1): ++ bsrl %eax, %eax ++ leaq -(VEC_SIZE * 2)(%rcx, %rax), %rax + ret + +- .p2align 4 +-L(matches32_1): +- bsr %eax, %eax +- sub $32, %rdx +- add %rax, %rdx +- jl L(return_null) +- lea 32(%rdi, %rax), %rax +- ret ++ .p2align 4,, 8 ++L(more_2x_vec): ++ testl %eax, %eax ++ jnz L(ret_vec_x0) + +- .p2align 4 +-L(matches48_1): +- bsr %eax, %eax +- sub $16, %rdx +- add %rax, %rdx +- jl L(return_null) +- lea 48(%rdi, %rax), %rax +- ret ++ movaps -(VEC_SIZE * 2)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ testl %eax, %eax ++ jnz L(ret_vec_x1) + +- .p2align 4 +-L(return_null): +- xor %eax, %eax +- ret + +- .p2align 4 +-L(length_less16_offset0): +- test %edx, %edx +- jz L(return_null) ++ movaps -(VEC_SIZE * 3)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax + +- mov %dl, %cl +- pcmpeqb (%rdi), %xmm1 ++ subq $(VEC_SIZE * 4), %rdx ++ ja L(more_4x_vec) + +- mov $1, %edx +- sal %cl, %edx +- sub $1, %edx ++ addl $(VEC_SIZE), %edx ++ jle L(ret_vec_x2_test) + +- pmovmskb %xmm1, %eax ++L(last_vec): ++ testl %eax, %eax ++ jnz L(ret_vec_x2) + +- and %edx, %eax +- test %eax, %eax +- jz L(return_null) ++ movaps -(VEC_SIZE * 4)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax + +- bsr %eax, %eax +- add %rdi, %rax ++ subl $(VEC_SIZE), %edx ++ bsrl %eax, %eax ++ jz L(ret_3) ++ addl %edx, %eax ++ jl L(zero_2) ++ addq %rdi, %rax ++L(ret_3): + ret + +- .p2align 4 +-L(length_less16): +- punpcklbw %xmm1, %xmm1 +- punpcklbw %xmm1, %xmm1 +- +- add $16, %edx +- +- pshufd $0, %xmm1, %xmm1 +- +- mov %edi, %ecx +- and $15, %ecx +- jz L(length_less16_offset0) +- +- mov %cl, %dh +- mov %ecx, %esi +- add %dl, %dh +- and $-16, %rdi +- +- sub $16, %dh +- ja L(length_less16_part2) +- +- pcmpeqb (%rdi), %xmm1 +- pmovmskb %xmm1, %eax +- +- sar %cl, %eax +- mov %dl, %cl +- +- mov $1, %edx +- sal %cl, %edx +- sub $1, %edx +- +- and %edx, %eax +- test %eax, %eax +- jz L(return_null) +- +- bsr %eax, %eax +- add %rdi, %rax +- add %rsi, %rax ++ .p2align 4,, 6 ++L(ret_vec_x2_test): ++ bsrl %eax, %eax ++ jz L(zero_2) ++ addl %edx, %eax ++ jl L(zero_2) ++ addq %rdi, %rax + ret + +- .p2align 4 +-L(length_less16_part2): +- movdqa 16(%rdi), %xmm2 +- pcmpeqb %xmm1, %xmm2 +- pmovmskb %xmm2, %eax +- +- mov %dh, %cl +- mov $1, %edx +- sal %cl, %edx +- sub $1, %edx +- +- and %edx, %eax ++L(zero_2): ++ xorl %eax, %eax ++ ret + +- test %eax, %eax +- jnz L(length_less16_part2_return) + +- pcmpeqb (%rdi), %xmm1 +- pmovmskb %xmm1, %eax ++ .p2align 4,, 5 ++L(ret_vec_x2): ++ bsrl %eax, %eax ++ leaq -(VEC_SIZE * 3)(%rcx, %rax), %rax ++ ret + +- mov %esi, %ecx +- sar %cl, %eax +- test %eax, %eax +- jz L(return_null) ++ .p2align 4,, 5 ++L(ret_vec_x3): ++ bsrl %eax, %eax ++ leaq -(VEC_SIZE * 4)(%rcx, %rax), %rax ++ ret + +- bsr %eax, %eax +- add %rdi, %rax +- add %rsi, %rax ++ .p2align 4,, 8 ++L(more_4x_vec): ++ testl %eax, %eax ++ jnz L(ret_vec_x2) ++ ++ movaps -(VEC_SIZE * 4)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ ++ testl %eax, %eax ++ jnz L(ret_vec_x3) ++ ++ addq $-(VEC_SIZE * 4), %rcx ++ cmpq $(VEC_SIZE * 4), %rdx ++ jbe L(last_4x_vec) ++ ++ /* Offset everything by 4x VEC_SIZE here to save a few bytes at the end ++ keeping the code from spilling to the next cache line. */ ++ addq $(VEC_SIZE * 4 - 1), %rcx ++ andq $-(VEC_SIZE * 4), %rcx ++ leaq (VEC_SIZE * 4)(%rdi), %rdx ++ andq $-(VEC_SIZE * 4), %rdx ++ ++ .p2align 4,, 11 ++L(loop_4x_vec): ++ movaps (VEC_SIZE * -1)(%rcx), %xmm1 ++ movaps (VEC_SIZE * -2)(%rcx), %xmm2 ++ movaps (VEC_SIZE * -3)(%rcx), %xmm3 ++ movaps (VEC_SIZE * -4)(%rcx), %xmm4 ++ pcmpeqb %xmm0, %xmm1 ++ pcmpeqb %xmm0, %xmm2 ++ pcmpeqb %xmm0, %xmm3 ++ pcmpeqb %xmm0, %xmm4 ++ ++ por %xmm1, %xmm2 ++ por %xmm3, %xmm4 ++ por %xmm2, %xmm4 ++ ++ pmovmskb %xmm4, %esi ++ testl %esi, %esi ++ jnz L(loop_end) ++ ++ addq $-(VEC_SIZE * 4), %rcx ++ cmpq %rdx, %rcx ++ jne L(loop_4x_vec) ++ ++ subl %edi, %edx ++ ++ /* Ends up being 1-byte nop. */ ++ .p2align 4,, 2 ++L(last_4x_vec): ++ movaps -(VEC_SIZE)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ ++ cmpl $(VEC_SIZE * 2), %edx ++ jbe L(last_2x_vec) ++ ++ testl %eax, %eax ++ jnz L(ret_vec_x0) ++ ++ ++ movaps -(VEC_SIZE * 2)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ ++ testl %eax, %eax ++ jnz L(ret_vec_end) ++ ++ movaps -(VEC_SIZE * 3)(%rcx), %xmm1 ++ pcmpeqb %xmm0, %xmm1 ++ pmovmskb %xmm1, %eax ++ ++ subl $(VEC_SIZE * 3), %edx ++ ja L(last_vec) ++ bsrl %eax, %eax ++ jz L(ret_4) ++ addl %edx, %eax ++ jl L(zero_3) ++ addq %rdi, %rax ++L(ret_4): + ret + +- .p2align 4 +-L(length_less16_part2_return): +- bsr %eax, %eax +- lea 16(%rax, %rdi), %rax ++ /* Ends up being 1-byte nop. */ ++ .p2align 4,, 3 ++L(loop_end): ++ pmovmskb %xmm1, %eax ++ sall $16, %eax ++ jnz L(ret_vec_end) ++ ++ pmovmskb %xmm2, %eax ++ testl %eax, %eax ++ jnz L(ret_vec_end) ++ ++ pmovmskb %xmm3, %eax ++ /* Combine last 2 VEC matches. If ecx (VEC3) is zero (no CHAR in VEC3) ++ then it won't affect the result in esi (VEC4). If ecx is non-zero ++ then CHAR in VEC3 and bsrq will use that position. */ ++ sall $16, %eax ++ orl %esi, %eax ++ bsrl %eax, %eax ++ leaq -(VEC_SIZE * 4)(%rcx, %rax), %rax + ret + +-END (__memrchr) ++L(ret_vec_end): ++ bsrl %eax, %eax ++ leaq (VEC_SIZE * -2)(%rax, %rcx), %rax ++ ret ++ /* Use in L(last_4x_vec). In the same cache line. This is just a spare ++ aligning bytes. */ ++L(zero_3): ++ xorl %eax, %eax ++ ret ++ /* 2-bytes from next cache line. */ ++END(__memrchr) + weak_alias (__memrchr, memrchr) diff --git a/SOURCES/glibc-upstream-2.34-284.patch b/SOURCES/glibc-upstream-2.34-284.patch new file mode 100644 index 0000000..846f807 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-284.patch @@ -0,0 +1,624 @@ +commit 83a986e9fbc301e6056dbc9d9ec6888621b60f67 +Author: Noah Goldstein +Date: Mon Jun 6 21:11:31 2022 -0700 + + x86: Optimize memrchr-evex.S + + The new code: + 1. prioritizes smaller user-arg lengths more. + 2. optimizes target placement more carefully + 3. reuses logic more + 4. fixes up various inefficiencies in the logic. The biggest + case here is the `lzcnt` logic for checking returns which + saves either a branch or multiple instructions. + + The total code size saving is: 263 bytes + Geometric Mean of all benchmarks New / Old: 0.755 + + Regressions: + There are some regressions. Particularly where the length (user arg + length) is large but the position of the match char is near the + beginning of the string (in first VEC). This case has roughly a + 20% regression. + + This is because the new logic gives the hot path for immediate matches + to shorter lengths (the more common input). This case has roughly + a 35% speedup. + + Full xcheck passes on x86_64. + Reviewed-by: H.J. Lu + + (cherry picked from commit b4209615a06b01c974f47b4998b00e4c7b1aa5d9) + +diff --git a/sysdeps/x86_64/multiarch/memrchr-evex.S b/sysdeps/x86_64/multiarch/memrchr-evex.S +index 16bf8e02b1e80c84..bddc89c3754894ed 100644 +--- a/sysdeps/x86_64/multiarch/memrchr-evex.S ++++ b/sysdeps/x86_64/multiarch/memrchr-evex.S +@@ -19,319 +19,316 @@ + #if IS_IN (libc) + + # include ++# include "evex256-vecs.h" ++# if VEC_SIZE != 32 ++# error "VEC_SIZE != 32 unimplemented" ++# endif ++ ++# ifndef MEMRCHR ++# define MEMRCHR __memrchr_evex ++# endif ++ ++# define PAGE_SIZE 4096 ++# define VECMATCH VEC(0) ++ ++ .section SECTION(.text), "ax", @progbits ++ENTRY_P2ALIGN(MEMRCHR, 6) ++# ifdef __ILP32__ ++ /* Clear upper bits. */ ++ and %RDX_LP, %RDX_LP ++# else ++ test %RDX_LP, %RDX_LP ++# endif ++ jz L(zero_0) ++ ++ /* Get end pointer. Minus one for two reasons. 1) It is necessary for a ++ correct page cross check and 2) it correctly sets up end ptr to be ++ subtract by lzcnt aligned. */ ++ leaq -1(%rdi, %rdx), %rax ++ vpbroadcastb %esi, %VECMATCH ++ ++ /* Check if we can load 1x VEC without cross a page. */ ++ testl $(PAGE_SIZE - VEC_SIZE), %eax ++ jz L(page_cross) ++ ++ /* Don't use rax for pointer here because EVEX has better encoding with ++ offset % VEC_SIZE == 0. */ ++ vpcmpb $0, -(VEC_SIZE)(%rdi, %rdx), %VECMATCH, %k0 ++ kmovd %k0, %ecx ++ ++ /* Fall through for rdx (len) <= VEC_SIZE (expect small sizes). */ ++ cmpq $VEC_SIZE, %rdx ++ ja L(more_1x_vec) ++L(ret_vec_x0_test): ++ ++ /* If ecx is zero (no matches) lzcnt will set it 32 (VEC_SIZE) which ++ will guarantee edx (len) is less than it. */ ++ lzcntl %ecx, %ecx ++ cmpl %ecx, %edx ++ jle L(zero_0) ++ subq %rcx, %rax ++ ret + +-# define VMOVA vmovdqa64 +- +-# define YMMMATCH ymm16 +- +-# define VEC_SIZE 32 +- +- .section .text.evex,"ax",@progbits +-ENTRY (__memrchr_evex) +- /* Broadcast CHAR to YMMMATCH. */ +- vpbroadcastb %esi, %YMMMATCH +- +- sub $VEC_SIZE, %RDX_LP +- jbe L(last_vec_or_less) +- +- add %RDX_LP, %RDI_LP +- +- /* Check the last VEC_SIZE bytes. */ +- vpcmpb $0, (%rdi), %YMMMATCH, %k1 +- kmovd %k1, %eax +- testl %eax, %eax +- jnz L(last_vec_x0) +- +- subq $(VEC_SIZE * 4), %rdi +- movl %edi, %ecx +- andl $(VEC_SIZE - 1), %ecx +- jz L(aligned_more) +- +- /* Align data for aligned loads in the loop. */ +- addq $VEC_SIZE, %rdi +- addq $VEC_SIZE, %rdx +- andq $-VEC_SIZE, %rdi +- subq %rcx, %rdx +- +- .p2align 4 +-L(aligned_more): +- subq $(VEC_SIZE * 4), %rdx +- jbe L(last_4x_vec_or_less) +- +- /* Check the last 4 * VEC_SIZE. Only one VEC_SIZE at a time +- since data is only aligned to VEC_SIZE. */ +- vpcmpb $0, (VEC_SIZE * 3)(%rdi), %YMMMATCH, %k1 +- kmovd %k1, %eax +- testl %eax, %eax +- jnz L(last_vec_x3) +- +- vpcmpb $0, (VEC_SIZE * 2)(%rdi), %YMMMATCH, %k2 +- kmovd %k2, %eax +- testl %eax, %eax +- jnz L(last_vec_x2) +- +- vpcmpb $0, VEC_SIZE(%rdi), %YMMMATCH, %k3 +- kmovd %k3, %eax +- testl %eax, %eax +- jnz L(last_vec_x1) +- +- vpcmpb $0, (%rdi), %YMMMATCH, %k4 +- kmovd %k4, %eax +- testl %eax, %eax +- jnz L(last_vec_x0) +- +- /* Align data to 4 * VEC_SIZE for loop with fewer branches. +- There are some overlaps with above if data isn't aligned +- to 4 * VEC_SIZE. */ +- movl %edi, %ecx +- andl $(VEC_SIZE * 4 - 1), %ecx +- jz L(loop_4x_vec) +- +- addq $(VEC_SIZE * 4), %rdi +- addq $(VEC_SIZE * 4), %rdx +- andq $-(VEC_SIZE * 4), %rdi +- subq %rcx, %rdx ++ /* Fits in aligning bytes of first cache line. */ ++L(zero_0): ++ xorl %eax, %eax ++ ret + +- .p2align 4 +-L(loop_4x_vec): +- /* Compare 4 * VEC at a time forward. */ +- subq $(VEC_SIZE * 4), %rdi +- subq $(VEC_SIZE * 4), %rdx +- jbe L(last_4x_vec_or_less) +- +- vpcmpb $0, (%rdi), %YMMMATCH, %k1 +- vpcmpb $0, VEC_SIZE(%rdi), %YMMMATCH, %k2 +- kord %k1, %k2, %k5 +- vpcmpb $0, (VEC_SIZE * 2)(%rdi), %YMMMATCH, %k3 +- vpcmpb $0, (VEC_SIZE * 3)(%rdi), %YMMMATCH, %k4 +- +- kord %k3, %k4, %k6 +- kortestd %k5, %k6 +- jz L(loop_4x_vec) +- +- /* There is a match. */ +- kmovd %k4, %eax +- testl %eax, %eax +- jnz L(last_vec_x3) +- +- kmovd %k3, %eax +- testl %eax, %eax +- jnz L(last_vec_x2) +- +- kmovd %k2, %eax +- testl %eax, %eax +- jnz L(last_vec_x1) +- +- kmovd %k1, %eax +- bsrl %eax, %eax +- addq %rdi, %rax ++ .p2align 4,, 9 ++L(ret_vec_x0_dec): ++ decq %rax ++L(ret_vec_x0): ++ lzcntl %ecx, %ecx ++ subq %rcx, %rax + ret + +- .p2align 4 +-L(last_4x_vec_or_less): +- addl $(VEC_SIZE * 4), %edx +- cmpl $(VEC_SIZE * 2), %edx +- jbe L(last_2x_vec) ++ .p2align 4,, 10 ++L(more_1x_vec): ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0) + +- vpcmpb $0, (VEC_SIZE * 3)(%rdi), %YMMMATCH, %k1 +- kmovd %k1, %eax +- testl %eax, %eax +- jnz L(last_vec_x3) ++ /* Align rax (pointer to string). */ ++ andq $-VEC_SIZE, %rax + +- vpcmpb $0, (VEC_SIZE * 2)(%rdi), %YMMMATCH, %k2 +- kmovd %k2, %eax +- testl %eax, %eax +- jnz L(last_vec_x2) ++ /* Recompute length after aligning. */ ++ movq %rax, %rdx + +- vpcmpb $0, VEC_SIZE(%rdi), %YMMMATCH, %k3 +- kmovd %k3, %eax +- testl %eax, %eax +- jnz L(last_vec_x1_check) +- cmpl $(VEC_SIZE * 3), %edx +- jbe L(zero) ++ /* Need no matter what. */ ++ vpcmpb $0, -(VEC_SIZE)(%rax), %VECMATCH, %k0 ++ kmovd %k0, %ecx + +- vpcmpb $0, (%rdi), %YMMMATCH, %k4 +- kmovd %k4, %eax +- testl %eax, %eax +- jz L(zero) +- bsrl %eax, %eax +- subq $(VEC_SIZE * 4), %rdx +- addq %rax, %rdx +- jl L(zero) +- addq %rdi, %rax +- ret ++ subq %rdi, %rdx + +- .p2align 4 ++ cmpq $(VEC_SIZE * 2), %rdx ++ ja L(more_2x_vec) + L(last_2x_vec): +- vpcmpb $0, (VEC_SIZE * 3)(%rdi), %YMMMATCH, %k1 +- kmovd %k1, %eax +- testl %eax, %eax +- jnz L(last_vec_x3_check) ++ ++ /* Must dec rax because L(ret_vec_x0_test) expects it. */ ++ decq %rax + cmpl $VEC_SIZE, %edx +- jbe L(zero) +- +- vpcmpb $0, (VEC_SIZE * 2)(%rdi), %YMMMATCH, %k1 +- kmovd %k1, %eax +- testl %eax, %eax +- jz L(zero) +- bsrl %eax, %eax +- subq $(VEC_SIZE * 2), %rdx +- addq %rax, %rdx +- jl L(zero) +- addl $(VEC_SIZE * 2), %eax +- addq %rdi, %rax ++ jbe L(ret_vec_x0_test) ++ ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0) ++ ++ /* Don't use rax for pointer here because EVEX has better encoding with ++ offset % VEC_SIZE == 0. */ ++ vpcmpb $0, -(VEC_SIZE * 2)(%rdi, %rdx), %VECMATCH, %k0 ++ kmovd %k0, %ecx ++ /* NB: 64-bit lzcnt. This will naturally add 32 to position. */ ++ lzcntq %rcx, %rcx ++ cmpl %ecx, %edx ++ jle L(zero_0) ++ subq %rcx, %rax + ret + +- .p2align 4 +-L(last_vec_x0): +- bsrl %eax, %eax +- addq %rdi, %rax ++ /* Inexpensive place to put this regarding code size / target alignments ++ / ICache NLP. Necessary for 2-byte encoding of jump to page cross ++ case which in turn is necessary for hot path (len <= VEC_SIZE) to fit ++ in first cache line. */ ++L(page_cross): ++ movq %rax, %rsi ++ andq $-VEC_SIZE, %rsi ++ vpcmpb $0, (%rsi), %VECMATCH, %k0 ++ kmovd %k0, %r8d ++ /* Shift out negative alignment (because we are starting from endptr and ++ working backwards). */ ++ movl %eax, %ecx ++ /* notl because eax already has endptr - 1. (-x = ~(x - 1)). */ ++ notl %ecx ++ shlxl %ecx, %r8d, %ecx ++ cmpq %rdi, %rsi ++ ja L(more_1x_vec) ++ lzcntl %ecx, %ecx ++ cmpl %ecx, %edx ++ jle L(zero_1) ++ subq %rcx, %rax + ret + +- .p2align 4 +-L(last_vec_x1): +- bsrl %eax, %eax +- addl $VEC_SIZE, %eax +- addq %rdi, %rax ++ /* Continue creating zero labels that fit in aligning bytes and get ++ 2-byte encoding / are in the same cache line as condition. */ ++L(zero_1): ++ xorl %eax, %eax + ret + +- .p2align 4 +-L(last_vec_x2): +- bsrl %eax, %eax +- addl $(VEC_SIZE * 2), %eax +- addq %rdi, %rax ++ .p2align 4,, 8 ++L(ret_vec_x1): ++ /* This will naturally add 32 to position. */ ++ bsrl %ecx, %ecx ++ leaq -(VEC_SIZE * 2)(%rcx, %rax), %rax + ret + +- .p2align 4 +-L(last_vec_x3): +- bsrl %eax, %eax +- addl $(VEC_SIZE * 3), %eax +- addq %rdi, %rax +- ret ++ .p2align 4,, 8 ++L(more_2x_vec): ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0_dec) + +- .p2align 4 +-L(last_vec_x1_check): +- bsrl %eax, %eax +- subq $(VEC_SIZE * 3), %rdx +- addq %rax, %rdx +- jl L(zero) +- addl $VEC_SIZE, %eax +- addq %rdi, %rax +- ret ++ vpcmpb $0, -(VEC_SIZE * 2)(%rax), %VECMATCH, %k0 ++ kmovd %k0, %ecx ++ testl %ecx, %ecx ++ jnz L(ret_vec_x1) + +- .p2align 4 +-L(last_vec_x3_check): +- bsrl %eax, %eax +- subq $VEC_SIZE, %rdx +- addq %rax, %rdx +- jl L(zero) +- addl $(VEC_SIZE * 3), %eax +- addq %rdi, %rax +- ret ++ /* Need no matter what. */ ++ vpcmpb $0, -(VEC_SIZE * 3)(%rax), %VECMATCH, %k0 ++ kmovd %k0, %ecx + +- .p2align 4 +-L(zero): +- xorl %eax, %eax ++ subq $(VEC_SIZE * 4), %rdx ++ ja L(more_4x_vec) ++ ++ cmpl $(VEC_SIZE * -1), %edx ++ jle L(ret_vec_x2_test) ++L(last_vec): ++ testl %ecx, %ecx ++ jnz L(ret_vec_x2) ++ ++ ++ /* Need no matter what. */ ++ vpcmpb $0, -(VEC_SIZE * 4)(%rax), %VECMATCH, %k0 ++ kmovd %k0, %ecx ++ lzcntl %ecx, %ecx ++ subq $(VEC_SIZE * 3 + 1), %rax ++ subq %rcx, %rax ++ cmpq %rax, %rdi ++ ja L(zero_1) + ret + +- .p2align 4 +-L(last_vec_or_less_aligned): +- movl %edx, %ecx +- +- vpcmpb $0, (%rdi), %YMMMATCH, %k1 +- +- movl $1, %edx +- /* Support rdx << 32. */ +- salq %cl, %rdx +- subq $1, %rdx +- +- kmovd %k1, %eax +- +- /* Remove the trailing bytes. */ +- andl %edx, %eax +- testl %eax, %eax +- jz L(zero) +- +- bsrl %eax, %eax +- addq %rdi, %rax ++ .p2align 4,, 8 ++L(ret_vec_x2_test): ++ lzcntl %ecx, %ecx ++ subq $(VEC_SIZE * 2 + 1), %rax ++ subq %rcx, %rax ++ cmpq %rax, %rdi ++ ja L(zero_1) + ret + +- .p2align 4 +-L(last_vec_or_less): +- addl $VEC_SIZE, %edx +- +- /* Check for zero length. */ +- testl %edx, %edx +- jz L(zero) +- +- movl %edi, %ecx +- andl $(VEC_SIZE - 1), %ecx +- jz L(last_vec_or_less_aligned) +- +- movl %ecx, %esi +- movl %ecx, %r8d +- addl %edx, %esi +- andq $-VEC_SIZE, %rdi ++ .p2align 4,, 8 ++L(ret_vec_x2): ++ bsrl %ecx, %ecx ++ leaq -(VEC_SIZE * 3)(%rcx, %rax), %rax ++ ret + +- subl $VEC_SIZE, %esi +- ja L(last_vec_2x_aligned) ++ .p2align 4,, 8 ++L(ret_vec_x3): ++ bsrl %ecx, %ecx ++ leaq -(VEC_SIZE * 4)(%rcx, %rax), %rax ++ ret + +- /* Check the last VEC. */ +- vpcmpb $0, (%rdi), %YMMMATCH, %k1 +- kmovd %k1, %eax ++ .p2align 4,, 8 ++L(more_4x_vec): ++ testl %ecx, %ecx ++ jnz L(ret_vec_x2) + +- /* Remove the leading and trailing bytes. */ +- sarl %cl, %eax +- movl %edx, %ecx ++ vpcmpb $0, -(VEC_SIZE * 4)(%rax), %VECMATCH, %k0 ++ kmovd %k0, %ecx + +- movl $1, %edx +- sall %cl, %edx +- subl $1, %edx ++ testl %ecx, %ecx ++ jnz L(ret_vec_x3) + +- andl %edx, %eax +- testl %eax, %eax +- jz L(zero) ++ /* Check if near end before re-aligning (otherwise might do an ++ unnecessary loop iteration). */ ++ addq $-(VEC_SIZE * 4), %rax ++ cmpq $(VEC_SIZE * 4), %rdx ++ jbe L(last_4x_vec) + +- bsrl %eax, %eax +- addq %rdi, %rax +- addq %r8, %rax +- ret ++ decq %rax ++ andq $-(VEC_SIZE * 4), %rax ++ movq %rdi, %rdx ++ /* Get endptr for loop in rdx. NB: Can't just do while rax > rdi because ++ lengths that overflow can be valid and break the comparison. */ ++ andq $-(VEC_SIZE * 4), %rdx + + .p2align 4 +-L(last_vec_2x_aligned): +- movl %esi, %ecx +- +- /* Check the last VEC. */ +- vpcmpb $0, VEC_SIZE(%rdi), %YMMMATCH, %k1 ++L(loop_4x_vec): ++ /* Store 1 were not-equals and 0 where equals in k1 (used to mask later ++ on). */ ++ vpcmpb $4, (VEC_SIZE * 3)(%rax), %VECMATCH, %k1 ++ ++ /* VEC(2/3) will have zero-byte where we found a CHAR. */ ++ vpxorq (VEC_SIZE * 2)(%rax), %VECMATCH, %VEC(2) ++ vpxorq (VEC_SIZE * 1)(%rax), %VECMATCH, %VEC(3) ++ vpcmpb $0, (VEC_SIZE * 0)(%rax), %VECMATCH, %k4 ++ ++ /* Combine VEC(2/3) with min and maskz with k1 (k1 has zero bit where ++ CHAR is found and VEC(2/3) have zero-byte where CHAR is found. */ ++ vpminub %VEC(2), %VEC(3), %VEC(3){%k1}{z} ++ vptestnmb %VEC(3), %VEC(3), %k2 ++ ++ /* Any 1s and we found CHAR. */ ++ kortestd %k2, %k4 ++ jnz L(loop_end) ++ ++ addq $-(VEC_SIZE * 4), %rax ++ cmpq %rdx, %rax ++ jne L(loop_4x_vec) ++ ++ /* Need to re-adjust rdx / rax for L(last_4x_vec). */ ++ subq $-(VEC_SIZE * 4), %rdx ++ movq %rdx, %rax ++ subl %edi, %edx ++L(last_4x_vec): ++ ++ /* Used no matter what. */ ++ vpcmpb $0, (VEC_SIZE * -1)(%rax), %VECMATCH, %k0 ++ kmovd %k0, %ecx + +- movl $1, %edx +- sall %cl, %edx +- subl $1, %edx ++ cmpl $(VEC_SIZE * 2), %edx ++ jbe L(last_2x_vec) + +- kmovd %k1, %eax ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0_dec) + +- /* Remove the trailing bytes. */ +- andl %edx, %eax + +- testl %eax, %eax +- jnz L(last_vec_x1) ++ vpcmpb $0, (VEC_SIZE * -2)(%rax), %VECMATCH, %k0 ++ kmovd %k0, %ecx + +- /* Check the second last VEC. */ +- vpcmpb $0, (%rdi), %YMMMATCH, %k1 ++ testl %ecx, %ecx ++ jnz L(ret_vec_x1) + +- movl %r8d, %ecx ++ /* Used no matter what. */ ++ vpcmpb $0, (VEC_SIZE * -3)(%rax), %VECMATCH, %k0 ++ kmovd %k0, %ecx + +- kmovd %k1, %eax ++ cmpl $(VEC_SIZE * 3), %edx ++ ja L(last_vec) + +- /* Remove the leading bytes. Must use unsigned right shift for +- bsrl below. */ +- shrl %cl, %eax +- testl %eax, %eax +- jz L(zero) ++ lzcntl %ecx, %ecx ++ subq $(VEC_SIZE * 2 + 1), %rax ++ subq %rcx, %rax ++ cmpq %rax, %rdi ++ jbe L(ret_1) ++ xorl %eax, %eax ++L(ret_1): ++ ret + +- bsrl %eax, %eax +- addq %rdi, %rax +- addq %r8, %rax ++ .p2align 4,, 6 ++L(loop_end): ++ kmovd %k1, %ecx ++ notl %ecx ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0_end) ++ ++ vptestnmb %VEC(2), %VEC(2), %k0 ++ kmovd %k0, %ecx ++ testl %ecx, %ecx ++ jnz L(ret_vec_x1_end) ++ ++ kmovd %k2, %ecx ++ kmovd %k4, %esi ++ /* Combine last 2 VEC matches. If ecx (VEC3) is zero (no CHAR in VEC3) ++ then it won't affect the result in esi (VEC4). If ecx is non-zero ++ then CHAR in VEC3 and bsrq will use that position. */ ++ salq $32, %rcx ++ orq %rsi, %rcx ++ bsrq %rcx, %rcx ++ addq %rcx, %rax ++ ret ++ .p2align 4,, 4 ++L(ret_vec_x0_end): ++ addq $(VEC_SIZE), %rax ++L(ret_vec_x1_end): ++ bsrl %ecx, %ecx ++ leaq (VEC_SIZE * 2)(%rax, %rcx), %rax + ret +-END (__memrchr_evex) ++ ++END(MEMRCHR) + #endif diff --git a/SOURCES/glibc-upstream-2.34-285.patch b/SOURCES/glibc-upstream-2.34-285.patch new file mode 100644 index 0000000..c3b0837 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-285.patch @@ -0,0 +1,645 @@ +commit b05bd59823bcedee281d3fd5bd4928698ea9d69d +Author: Noah Goldstein +Date: Mon Jun 6 21:11:32 2022 -0700 + + x86: Optimize memrchr-avx2.S + + The new code: + 1. prioritizes smaller user-arg lengths more. + 2. optimizes target placement more carefully + 3. reuses logic more + 4. fixes up various inefficiencies in the logic. The biggest + case here is the `lzcnt` logic for checking returns which + saves either a branch or multiple instructions. + + The total code size saving is: 306 bytes + Geometric Mean of all benchmarks New / Old: 0.760 + + Regressions: + There are some regressions. Particularly where the length (user arg + length) is large but the position of the match char is near the + beginning of the string (in first VEC). This case has roughly a + 10-20% regression. + + This is because the new logic gives the hot path for immediate matches + to shorter lengths (the more common input). This case has roughly + a 15-45% speedup. + + Full xcheck passes on x86_64. + Reviewed-by: H.J. Lu + + (cherry picked from commit af5306a735eb0966fdc2f8ccdafa8888e2df0c87) + +diff --git a/sysdeps/x86_64/multiarch/memrchr-avx2-rtm.S b/sysdeps/x86_64/multiarch/memrchr-avx2-rtm.S +index cea2d2a72db7406a..5e9beeeef2677c9f 100644 +--- a/sysdeps/x86_64/multiarch/memrchr-avx2-rtm.S ++++ b/sysdeps/x86_64/multiarch/memrchr-avx2-rtm.S +@@ -2,6 +2,7 @@ + # define MEMRCHR __memrchr_avx2_rtm + #endif + ++#define COND_VZEROUPPER COND_VZEROUPPER_XTEST + #define ZERO_UPPER_VEC_REGISTERS_RETURN \ + ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST + +diff --git a/sysdeps/x86_64/multiarch/memrchr-avx2.S b/sysdeps/x86_64/multiarch/memrchr-avx2.S +index ac7370cb06e9a0fd..5f8e0be18cfe4fad 100644 +--- a/sysdeps/x86_64/multiarch/memrchr-avx2.S ++++ b/sysdeps/x86_64/multiarch/memrchr-avx2.S +@@ -21,340 +21,318 @@ + # include + + # ifndef MEMRCHR +-# define MEMRCHR __memrchr_avx2 ++# define MEMRCHR __memrchr_avx2 + # endif + + # ifndef VZEROUPPER +-# define VZEROUPPER vzeroupper ++# define VZEROUPPER vzeroupper + # endif + + # ifndef SECTION + # define SECTION(p) p##.avx + # endif + +-# define VEC_SIZE 32 ++# define VEC_SIZE 32 ++# define PAGE_SIZE 4096 ++ .section SECTION(.text), "ax", @progbits ++ENTRY(MEMRCHR) ++# ifdef __ILP32__ ++ /* Clear upper bits. */ ++ and %RDX_LP, %RDX_LP ++# else ++ test %RDX_LP, %RDX_LP ++# endif ++ jz L(zero_0) + +- .section SECTION(.text),"ax",@progbits +-ENTRY (MEMRCHR) +- /* Broadcast CHAR to YMM0. */ + vmovd %esi, %xmm0 +- vpbroadcastb %xmm0, %ymm0 +- +- sub $VEC_SIZE, %RDX_LP +- jbe L(last_vec_or_less) +- +- add %RDX_LP, %RDI_LP +- +- /* Check the last VEC_SIZE bytes. */ +- vpcmpeqb (%rdi), %ymm0, %ymm1 +- vpmovmskb %ymm1, %eax +- testl %eax, %eax +- jnz L(last_vec_x0) ++ /* Get end pointer. Minus one for two reasons. 1) It is necessary for a ++ correct page cross check and 2) it correctly sets up end ptr to be ++ subtract by lzcnt aligned. */ ++ leaq -1(%rdx, %rdi), %rax + +- subq $(VEC_SIZE * 4), %rdi +- movl %edi, %ecx +- andl $(VEC_SIZE - 1), %ecx +- jz L(aligned_more) ++ vpbroadcastb %xmm0, %ymm0 + +- /* Align data for aligned loads in the loop. */ +- addq $VEC_SIZE, %rdi +- addq $VEC_SIZE, %rdx +- andq $-VEC_SIZE, %rdi +- subq %rcx, %rdx ++ /* Check if we can load 1x VEC without cross a page. */ ++ testl $(PAGE_SIZE - VEC_SIZE), %eax ++ jz L(page_cross) ++ ++ vpcmpeqb -(VEC_SIZE - 1)(%rax), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ cmpq $VEC_SIZE, %rdx ++ ja L(more_1x_vec) ++ ++L(ret_vec_x0_test): ++ /* If ecx is zero (no matches) lzcnt will set it 32 (VEC_SIZE) which ++ will gurantee edx (len) is less than it. */ ++ lzcntl %ecx, %ecx ++ ++ /* Hoist vzeroupper (not great for RTM) to save code size. This allows ++ all logic for edx (len) <= VEC_SIZE to fit in first cache line. */ ++ COND_VZEROUPPER ++ cmpl %ecx, %edx ++ jle L(zero_0) ++ subq %rcx, %rax ++ ret + +- .p2align 4 +-L(aligned_more): +- subq $(VEC_SIZE * 4), %rdx +- jbe L(last_4x_vec_or_less) +- +- /* Check the last 4 * VEC_SIZE. Only one VEC_SIZE at a time +- since data is only aligned to VEC_SIZE. */ +- vpcmpeqb (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 +- vpmovmskb %ymm1, %eax +- testl %eax, %eax +- jnz L(last_vec_x3) +- +- vpcmpeqb (VEC_SIZE * 2)(%rdi), %ymm0, %ymm2 +- vpmovmskb %ymm2, %eax +- testl %eax, %eax +- jnz L(last_vec_x2) +- +- vpcmpeqb VEC_SIZE(%rdi), %ymm0, %ymm3 +- vpmovmskb %ymm3, %eax +- testl %eax, %eax +- jnz L(last_vec_x1) +- +- vpcmpeqb (%rdi), %ymm0, %ymm4 +- vpmovmskb %ymm4, %eax +- testl %eax, %eax +- jnz L(last_vec_x0) +- +- /* Align data to 4 * VEC_SIZE for loop with fewer branches. +- There are some overlaps with above if data isn't aligned +- to 4 * VEC_SIZE. */ +- movl %edi, %ecx +- andl $(VEC_SIZE * 4 - 1), %ecx +- jz L(loop_4x_vec) +- +- addq $(VEC_SIZE * 4), %rdi +- addq $(VEC_SIZE * 4), %rdx +- andq $-(VEC_SIZE * 4), %rdi +- subq %rcx, %rdx ++ /* Fits in aligning bytes of first cache line. */ ++L(zero_0): ++ xorl %eax, %eax ++ ret + +- .p2align 4 +-L(loop_4x_vec): +- /* Compare 4 * VEC at a time forward. */ +- subq $(VEC_SIZE * 4), %rdi +- subq $(VEC_SIZE * 4), %rdx +- jbe L(last_4x_vec_or_less) +- +- vmovdqa (%rdi), %ymm1 +- vmovdqa VEC_SIZE(%rdi), %ymm2 +- vmovdqa (VEC_SIZE * 2)(%rdi), %ymm3 +- vmovdqa (VEC_SIZE * 3)(%rdi), %ymm4 +- +- vpcmpeqb %ymm1, %ymm0, %ymm1 +- vpcmpeqb %ymm2, %ymm0, %ymm2 +- vpcmpeqb %ymm3, %ymm0, %ymm3 +- vpcmpeqb %ymm4, %ymm0, %ymm4 +- +- vpor %ymm1, %ymm2, %ymm5 +- vpor %ymm3, %ymm4, %ymm6 +- vpor %ymm5, %ymm6, %ymm5 +- +- vpmovmskb %ymm5, %eax +- testl %eax, %eax +- jz L(loop_4x_vec) +- +- /* There is a match. */ +- vpmovmskb %ymm4, %eax +- testl %eax, %eax +- jnz L(last_vec_x3) +- +- vpmovmskb %ymm3, %eax +- testl %eax, %eax +- jnz L(last_vec_x2) +- +- vpmovmskb %ymm2, %eax +- testl %eax, %eax +- jnz L(last_vec_x1) +- +- vpmovmskb %ymm1, %eax +- bsrl %eax, %eax +- addq %rdi, %rax ++ .p2align 4,, 9 ++L(ret_vec_x0): ++ lzcntl %ecx, %ecx ++ subq %rcx, %rax + L(return_vzeroupper): + ZERO_UPPER_VEC_REGISTERS_RETURN + +- .p2align 4 +-L(last_4x_vec_or_less): +- addl $(VEC_SIZE * 4), %edx +- cmpl $(VEC_SIZE * 2), %edx +- jbe L(last_2x_vec) +- +- vpcmpeqb (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 +- vpmovmskb %ymm1, %eax +- testl %eax, %eax +- jnz L(last_vec_x3) +- +- vpcmpeqb (VEC_SIZE * 2)(%rdi), %ymm0, %ymm2 +- vpmovmskb %ymm2, %eax +- testl %eax, %eax +- jnz L(last_vec_x2) +- +- vpcmpeqb VEC_SIZE(%rdi), %ymm0, %ymm3 +- vpmovmskb %ymm3, %eax +- testl %eax, %eax +- jnz L(last_vec_x1_check) +- cmpl $(VEC_SIZE * 3), %edx +- jbe L(zero) +- +- vpcmpeqb (%rdi), %ymm0, %ymm4 +- vpmovmskb %ymm4, %eax +- testl %eax, %eax +- jz L(zero) +- bsrl %eax, %eax +- subq $(VEC_SIZE * 4), %rdx +- addq %rax, %rdx +- jl L(zero) +- addq %rdi, %rax +- VZEROUPPER_RETURN +- +- .p2align 4 ++ .p2align 4,, 10 ++L(more_1x_vec): ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0) ++ ++ /* Align rax (string pointer). */ ++ andq $-VEC_SIZE, %rax ++ ++ /* Recompute remaining length after aligning. */ ++ movq %rax, %rdx ++ /* Need this comparison next no matter what. */ ++ vpcmpeqb -(VEC_SIZE)(%rax), %ymm0, %ymm1 ++ subq %rdi, %rdx ++ decq %rax ++ vpmovmskb %ymm1, %ecx ++ /* Fall through for short (hotter than length). */ ++ cmpq $(VEC_SIZE * 2), %rdx ++ ja L(more_2x_vec) + L(last_2x_vec): +- vpcmpeqb (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 +- vpmovmskb %ymm1, %eax +- testl %eax, %eax +- jnz L(last_vec_x3_check) + cmpl $VEC_SIZE, %edx +- jbe L(zero) +- +- vpcmpeqb (VEC_SIZE * 2)(%rdi), %ymm0, %ymm1 +- vpmovmskb %ymm1, %eax +- testl %eax, %eax +- jz L(zero) +- bsrl %eax, %eax +- subq $(VEC_SIZE * 2), %rdx +- addq %rax, %rdx +- jl L(zero) +- addl $(VEC_SIZE * 2), %eax +- addq %rdi, %rax +- VZEROUPPER_RETURN +- +- .p2align 4 +-L(last_vec_x0): +- bsrl %eax, %eax +- addq %rdi, %rax +- VZEROUPPER_RETURN ++ jbe L(ret_vec_x0_test) ++ ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0) ++ ++ vpcmpeqb -(VEC_SIZE * 2 - 1)(%rax), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ /* 64-bit lzcnt. This will naturally add 32 to position. */ ++ lzcntq %rcx, %rcx ++ COND_VZEROUPPER ++ cmpl %ecx, %edx ++ jle L(zero_0) ++ subq %rcx, %rax ++ ret + +- .p2align 4 +-L(last_vec_x1): +- bsrl %eax, %eax +- addl $VEC_SIZE, %eax +- addq %rdi, %rax +- VZEROUPPER_RETURN + +- .p2align 4 +-L(last_vec_x2): +- bsrl %eax, %eax +- addl $(VEC_SIZE * 2), %eax +- addq %rdi, %rax ++ /* Inexpensive place to put this regarding code size / target alignments ++ / ICache NLP. Necessary for 2-byte encoding of jump to page cross ++ case which in turn is necessary for hot path (len <= VEC_SIZE) to fit ++ in first cache line. */ ++L(page_cross): ++ movq %rax, %rsi ++ andq $-VEC_SIZE, %rsi ++ vpcmpeqb (%rsi), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ /* Shift out negative alignment (because we are starting from endptr and ++ working backwards). */ ++ movl %eax, %r8d ++ /* notl because eax already has endptr - 1. (-x = ~(x - 1)). */ ++ notl %r8d ++ shlxl %r8d, %ecx, %ecx ++ cmpq %rdi, %rsi ++ ja L(more_1x_vec) ++ lzcntl %ecx, %ecx ++ COND_VZEROUPPER ++ cmpl %ecx, %edx ++ jle L(zero_0) ++ subq %rcx, %rax ++ ret ++ .p2align 4,, 11 ++L(ret_vec_x1): ++ /* This will naturally add 32 to position. */ ++ lzcntq %rcx, %rcx ++ subq %rcx, %rax + VZEROUPPER_RETURN ++ .p2align 4,, 10 ++L(more_2x_vec): ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0) + +- .p2align 4 +-L(last_vec_x3): +- bsrl %eax, %eax +- addl $(VEC_SIZE * 3), %eax +- addq %rdi, %rax +- ret ++ vpcmpeqb -(VEC_SIZE * 2 - 1)(%rax), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ testl %ecx, %ecx ++ jnz L(ret_vec_x1) + +- .p2align 4 +-L(last_vec_x1_check): +- bsrl %eax, %eax +- subq $(VEC_SIZE * 3), %rdx +- addq %rax, %rdx +- jl L(zero) +- addl $VEC_SIZE, %eax +- addq %rdi, %rax +- VZEROUPPER_RETURN + +- .p2align 4 +-L(last_vec_x3_check): +- bsrl %eax, %eax +- subq $VEC_SIZE, %rdx +- addq %rax, %rdx +- jl L(zero) +- addl $(VEC_SIZE * 3), %eax +- addq %rdi, %rax +- VZEROUPPER_RETURN ++ /* Needed no matter what. */ ++ vpcmpeqb -(VEC_SIZE * 3 - 1)(%rax), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx + +- .p2align 4 +-L(zero): +- xorl %eax, %eax +- VZEROUPPER_RETURN ++ subq $(VEC_SIZE * 4), %rdx ++ ja L(more_4x_vec) ++ ++ cmpl $(VEC_SIZE * -1), %edx ++ jle L(ret_vec_x2_test) ++ ++L(last_vec): ++ testl %ecx, %ecx ++ jnz L(ret_vec_x2) ++ ++ /* Needed no matter what. */ ++ vpcmpeqb -(VEC_SIZE * 4 - 1)(%rax), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ lzcntl %ecx, %ecx ++ subq $(VEC_SIZE * 3), %rax ++ COND_VZEROUPPER ++ subq %rcx, %rax ++ cmpq %rax, %rdi ++ ja L(zero_2) ++ ret + +- .p2align 4 +-L(null): ++ /* First in aligning bytes. */ ++L(zero_2): + xorl %eax, %eax + ret + +- .p2align 4 +-L(last_vec_or_less_aligned): +- movl %edx, %ecx ++ .p2align 4,, 4 ++L(ret_vec_x2_test): ++ lzcntl %ecx, %ecx ++ subq $(VEC_SIZE * 2), %rax ++ COND_VZEROUPPER ++ subq %rcx, %rax ++ cmpq %rax, %rdi ++ ja L(zero_2) ++ ret + +- vpcmpeqb (%rdi), %ymm0, %ymm1 + +- movl $1, %edx +- /* Support rdx << 32. */ +- salq %cl, %rdx +- subq $1, %rdx ++ .p2align 4,, 11 ++L(ret_vec_x2): ++ /* ecx must be non-zero. */ ++ bsrl %ecx, %ecx ++ leaq (VEC_SIZE * -3 + 1)(%rcx, %rax), %rax ++ VZEROUPPER_RETURN + +- vpmovmskb %ymm1, %eax ++ .p2align 4,, 14 ++L(ret_vec_x3): ++ /* ecx must be non-zero. */ ++ bsrl %ecx, %ecx ++ leaq (VEC_SIZE * -4 + 1)(%rcx, %rax), %rax ++ VZEROUPPER_RETURN + +- /* Remove the trailing bytes. */ +- andl %edx, %eax +- testl %eax, %eax +- jz L(zero) + +- bsrl %eax, %eax +- addq %rdi, %rax +- VZEROUPPER_RETURN + + .p2align 4 +-L(last_vec_or_less): +- addl $VEC_SIZE, %edx ++L(more_4x_vec): ++ testl %ecx, %ecx ++ jnz L(ret_vec_x2) + +- /* Check for zero length. */ +- testl %edx, %edx +- jz L(null) ++ vpcmpeqb -(VEC_SIZE * 4 - 1)(%rax), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx + +- movl %edi, %ecx +- andl $(VEC_SIZE - 1), %ecx +- jz L(last_vec_or_less_aligned) ++ testl %ecx, %ecx ++ jnz L(ret_vec_x3) + +- movl %ecx, %esi +- movl %ecx, %r8d +- addl %edx, %esi +- andq $-VEC_SIZE, %rdi ++ /* Check if near end before re-aligning (otherwise might do an ++ unnecissary loop iteration). */ ++ addq $-(VEC_SIZE * 4), %rax ++ cmpq $(VEC_SIZE * 4), %rdx ++ jbe L(last_4x_vec) + +- subl $VEC_SIZE, %esi +- ja L(last_vec_2x_aligned) ++ /* Align rax to (VEC_SIZE - 1). */ ++ orq $(VEC_SIZE * 4 - 1), %rax ++ movq %rdi, %rdx ++ /* Get endptr for loop in rdx. NB: Can't just do while rax > rdi because ++ lengths that overflow can be valid and break the comparison. */ ++ orq $(VEC_SIZE * 4 - 1), %rdx + +- /* Check the last VEC. */ +- vpcmpeqb (%rdi), %ymm0, %ymm1 +- vpmovmskb %ymm1, %eax +- +- /* Remove the leading and trailing bytes. */ +- sarl %cl, %eax +- movl %edx, %ecx ++ .p2align 4 ++L(loop_4x_vec): ++ /* Need this comparison next no matter what. */ ++ vpcmpeqb -(VEC_SIZE * 1 - 1)(%rax), %ymm0, %ymm1 ++ vpcmpeqb -(VEC_SIZE * 2 - 1)(%rax), %ymm0, %ymm2 ++ vpcmpeqb -(VEC_SIZE * 3 - 1)(%rax), %ymm0, %ymm3 ++ vpcmpeqb -(VEC_SIZE * 4 - 1)(%rax), %ymm0, %ymm4 + +- movl $1, %edx +- sall %cl, %edx +- subl $1, %edx ++ vpor %ymm1, %ymm2, %ymm2 ++ vpor %ymm3, %ymm4, %ymm4 ++ vpor %ymm2, %ymm4, %ymm4 ++ vpmovmskb %ymm4, %esi + +- andl %edx, %eax +- testl %eax, %eax +- jz L(zero) ++ testl %esi, %esi ++ jnz L(loop_end) + +- bsrl %eax, %eax +- addq %rdi, %rax +- addq %r8, %rax +- VZEROUPPER_RETURN ++ addq $(VEC_SIZE * -4), %rax ++ cmpq %rdx, %rax ++ jne L(loop_4x_vec) + +- .p2align 4 +-L(last_vec_2x_aligned): +- movl %esi, %ecx ++ subl %edi, %edx ++ incl %edx + +- /* Check the last VEC. */ +- vpcmpeqb VEC_SIZE(%rdi), %ymm0, %ymm1 ++L(last_4x_vec): ++ /* Used no matter what. */ ++ vpcmpeqb -(VEC_SIZE * 1 - 1)(%rax), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx + +- movl $1, %edx +- sall %cl, %edx +- subl $1, %edx ++ cmpl $(VEC_SIZE * 2), %edx ++ jbe L(last_2x_vec) + +- vpmovmskb %ymm1, %eax ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0_end) + +- /* Remove the trailing bytes. */ +- andl %edx, %eax ++ vpcmpeqb -(VEC_SIZE * 2 - 1)(%rax), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx ++ testl %ecx, %ecx ++ jnz L(ret_vec_x1_end) + +- testl %eax, %eax +- jnz L(last_vec_x1) ++ /* Used no matter what. */ ++ vpcmpeqb -(VEC_SIZE * 3 - 1)(%rax), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %ecx + +- /* Check the second last VEC. */ +- vpcmpeqb (%rdi), %ymm0, %ymm1 ++ cmpl $(VEC_SIZE * 3), %edx ++ ja L(last_vec) ++ ++ lzcntl %ecx, %ecx ++ subq $(VEC_SIZE * 2), %rax ++ COND_VZEROUPPER ++ subq %rcx, %rax ++ cmpq %rax, %rdi ++ jbe L(ret0) ++ xorl %eax, %eax ++L(ret0): ++ ret + +- movl %r8d, %ecx + +- vpmovmskb %ymm1, %eax ++ .p2align 4 ++L(loop_end): ++ vpmovmskb %ymm1, %ecx ++ testl %ecx, %ecx ++ jnz L(ret_vec_x0_end) ++ ++ vpmovmskb %ymm2, %ecx ++ testl %ecx, %ecx ++ jnz L(ret_vec_x1_end) ++ ++ vpmovmskb %ymm3, %ecx ++ /* Combine last 2 VEC matches. If ecx (VEC3) is zero (no CHAR in VEC3) ++ then it won't affect the result in esi (VEC4). If ecx is non-zero ++ then CHAR in VEC3 and bsrq will use that position. */ ++ salq $32, %rcx ++ orq %rsi, %rcx ++ bsrq %rcx, %rcx ++ leaq (VEC_SIZE * -4 + 1)(%rcx, %rax), %rax ++ VZEROUPPER_RETURN + +- /* Remove the leading bytes. Must use unsigned right shift for +- bsrl below. */ +- shrl %cl, %eax +- testl %eax, %eax +- jz L(zero) ++ .p2align 4,, 4 ++L(ret_vec_x1_end): ++ /* 64-bit version will automatically add 32 (VEC_SIZE). */ ++ lzcntq %rcx, %rcx ++ subq %rcx, %rax ++ VZEROUPPER_RETURN + +- bsrl %eax, %eax +- addq %rdi, %rax +- addq %r8, %rax ++ .p2align 4,, 4 ++L(ret_vec_x0_end): ++ lzcntl %ecx, %ecx ++ subq %rcx, %rax + VZEROUPPER_RETURN +-END (MEMRCHR) ++ ++ /* 2 bytes until next cache line. */ ++END(MEMRCHR) + #endif diff --git a/SOURCES/glibc-upstream-2.34-286.patch b/SOURCES/glibc-upstream-2.34-286.patch new file mode 100644 index 0000000..41a0188 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-286.patch @@ -0,0 +1,323 @@ +commit a910d7e164f1d9b8e77bbea35a2d2ab89a5e26cc +Author: Noah Goldstein +Date: Mon Jun 6 21:11:33 2022 -0700 + + x86: Shrink code size of memchr-avx2.S + + This is not meant as a performance optimization. The previous code was + far to liberal in aligning targets and wasted code size unnecissarily. + + The total code size saving is: 59 bytes + + There are no major changes in the benchmarks. + Geometric Mean of all benchmarks New / Old: 0.967 + + Full xcheck passes on x86_64. + Reviewed-by: H.J. Lu + + (cherry picked from commit 6dcbb7d95dded20153b12d76d2f4e0ef0cda4f35) + + x86: Fix page cross case in rawmemchr-avx2 [BZ #29234] + + commit 6dcbb7d95dded20153b12d76d2f4e0ef0cda4f35 + Author: Noah Goldstein + Date: Mon Jun 6 21:11:33 2022 -0700 + + x86: Shrink code size of memchr-avx2.S + + Changed how the page cross case aligned string (rdi) in + rawmemchr. This was incompatible with how + `L(cross_page_continue)` expected the pointer to be aligned and + would cause rawmemchr to read data start started before the + beginning of the string. What it would read was in valid memory + but could count CHAR matches resulting in an incorrect return + value. + + This commit fixes that issue by essentially reverting the changes to + the L(page_cross) case as they didn't really matter. + + Test cases added and all pass with the new code (and where confirmed + to fail with the old code). + Reviewed-by: H.J. Lu + + (cherry picked from commit 2c9af8421d2b4a7fcce163e7bc81a118d22fd346) + +diff --git a/string/test-rawmemchr.c b/string/test-rawmemchr.c +index 085098aba8fdbc13..327c0654e69e7669 100644 +--- a/string/test-rawmemchr.c ++++ b/string/test-rawmemchr.c +@@ -18,6 +18,7 @@ + . */ + + #include ++#include + + #define TEST_MAIN + #define TEST_NAME "rawmemchr" +@@ -51,13 +52,45 @@ do_one_test (impl_t *impl, const char *s, int c, char *exp_res) + } + } + ++static void ++do_test_bz29234 (void) ++{ ++ size_t i, j; ++ char *ptr_start; ++ char *buf = xmmap (0, 8192, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ ++ memset (buf, -1, 8192); ++ ++ ptr_start = buf + 4096 - 8; ++ ++ /* Out of range matches before the start of a page. */ ++ memset (ptr_start - 8, 0x1, 8); ++ ++ for (j = 0; j < 8; ++j) ++ { ++ for (i = 0; i < 128; ++i) ++ { ++ ptr_start[i + j] = 0x1; ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, (char *) (ptr_start + j), 0x1, ++ ptr_start + i + j); ++ ++ ptr_start[i + j] = 0xff; ++ } ++ } ++ ++ xmunmap (buf, 8192); ++} ++ + static void + do_test (size_t align, size_t pos, size_t len, int seek_char) + { + size_t i; + char *result; + +- align &= 7; ++ align &= getpagesize () - 1; + if (align + len >= page_size) + return; + +@@ -115,6 +148,13 @@ do_random_tests (void) + } + } + ++ if (align) ++ { ++ p[align - 1] = seek_char; ++ if (align > 4) ++ p[align - 4] = seek_char; ++ } ++ + assert (pos < len); + size_t r = random (); + if ((r & 31) == 0) +@@ -130,6 +170,13 @@ do_random_tests (void) + result, p); + ret = 1; + } ++ ++ if (align) ++ { ++ p[align - 1] = seek_char; ++ if (align > 4) ++ p[align - 4] = seek_char; ++ } + } + } + +@@ -151,14 +198,22 @@ test_main (void) + do_test (i, 64, 256, 23); + do_test (0, 16 << i, 2048, 0); + do_test (i, 64, 256, 0); ++ ++ do_test (getpagesize () - i, 64, 256, 23); ++ do_test (getpagesize () - i, 64, 256, 0); + } + for (i = 1; i < 32; ++i) + { + do_test (0, i, i + 1, 23); + do_test (0, i, i + 1, 0); ++ ++ do_test (getpagesize () - 7, i, i + 1, 23); ++ do_test (getpagesize () - i / 2, i, i + 1, 23); ++ do_test (getpagesize () - i, i, i + 1, 23); + } + + do_random_tests (); ++ do_test_bz29234 (); + return ret; + } + +diff --git a/sysdeps/x86_64/multiarch/memchr-avx2-rtm.S b/sysdeps/x86_64/multiarch/memchr-avx2-rtm.S +index 87b076c7c403ba85..c4d71938c5a3ed24 100644 +--- a/sysdeps/x86_64/multiarch/memchr-avx2-rtm.S ++++ b/sysdeps/x86_64/multiarch/memchr-avx2-rtm.S +@@ -2,6 +2,7 @@ + # define MEMCHR __memchr_avx2_rtm + #endif + ++#define COND_VZEROUPPER COND_VZEROUPPER_XTEST + #define ZERO_UPPER_VEC_REGISTERS_RETURN \ + ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST + +diff --git a/sysdeps/x86_64/multiarch/memchr-avx2.S b/sysdeps/x86_64/multiarch/memchr-avx2.S +index afdb95650232fdac..9e0b7dd1f4fe9909 100644 +--- a/sysdeps/x86_64/multiarch/memchr-avx2.S ++++ b/sysdeps/x86_64/multiarch/memchr-avx2.S +@@ -57,7 +57,7 @@ + # define CHAR_PER_VEC (VEC_SIZE / CHAR_SIZE) + + .section SECTION(.text),"ax",@progbits +-ENTRY (MEMCHR) ++ENTRY_P2ALIGN (MEMCHR, 5) + # ifndef USE_AS_RAWMEMCHR + /* Check for zero length. */ + # ifdef __ILP32__ +@@ -87,12 +87,14 @@ ENTRY (MEMCHR) + # endif + testl %eax, %eax + jz L(aligned_more) +- tzcntl %eax, %eax ++ bsfl %eax, %eax + addq %rdi, %rax +- VZEROUPPER_RETURN ++L(return_vzeroupper): ++ ZERO_UPPER_VEC_REGISTERS_RETURN ++ + + # ifndef USE_AS_RAWMEMCHR +- .p2align 5 ++ .p2align 4 + L(first_vec_x0): + /* Check if first match was before length. */ + tzcntl %eax, %eax +@@ -100,58 +102,31 @@ L(first_vec_x0): + /* NB: Multiply length by 4 to get byte count. */ + sall $2, %edx + # endif +- xorl %ecx, %ecx ++ COND_VZEROUPPER ++ /* Use branch instead of cmovcc so L(first_vec_x0) fits in one fetch ++ block. branch here as opposed to cmovcc is not that costly. Common ++ usage of memchr is to check if the return was NULL (if string was ++ known to contain CHAR user would use rawmemchr). This branch will be ++ highly correlated with the user branch and can be used by most ++ modern branch predictors to predict the user branch. */ + cmpl %eax, %edx +- leaq (%rdi, %rax), %rax +- cmovle %rcx, %rax +- VZEROUPPER_RETURN +- +-L(null): +- xorl %eax, %eax +- ret +-# endif +- .p2align 4 +-L(cross_page_boundary): +- /* Save pointer before aligning as its original value is +- necessary for computer return address if byte is found or +- adjusting length if it is not and this is memchr. */ +- movq %rdi, %rcx +- /* Align data to VEC_SIZE - 1. ALGN_PTR_REG is rcx for memchr +- and rdi for rawmemchr. */ +- orq $(VEC_SIZE - 1), %ALGN_PTR_REG +- VPCMPEQ -(VEC_SIZE - 1)(%ALGN_PTR_REG), %ymm0, %ymm1 +- vpmovmskb %ymm1, %eax +-# ifndef USE_AS_RAWMEMCHR +- /* Calculate length until end of page (length checked for a +- match). */ +- leaq 1(%ALGN_PTR_REG), %rsi +- subq %RRAW_PTR_REG, %rsi +-# ifdef USE_AS_WMEMCHR +- /* NB: Divide bytes by 4 to get wchar_t count. */ +- shrl $2, %esi +-# endif +-# endif +- /* Remove the leading bytes. */ +- sarxl %ERAW_PTR_REG, %eax, %eax +-# ifndef USE_AS_RAWMEMCHR +- /* Check the end of data. */ +- cmpq %rsi, %rdx +- jbe L(first_vec_x0) ++ jle L(null) ++ addq %rdi, %rax ++ ret + # endif +- testl %eax, %eax +- jz L(cross_page_continue) +- tzcntl %eax, %eax +- addq %RRAW_PTR_REG, %rax +-L(return_vzeroupper): +- ZERO_UPPER_VEC_REGISTERS_RETURN + +- .p2align 4 ++ .p2align 4,, 10 + L(first_vec_x1): +- tzcntl %eax, %eax ++ bsfl %eax, %eax + incq %rdi + addq %rdi, %rax + VZEROUPPER_RETURN +- ++# ifndef USE_AS_RAWMEMCHR ++ /* First in aligning bytes here. */ ++L(null): ++ xorl %eax, %eax ++ ret ++# endif + .p2align 4 + L(first_vec_x2): + tzcntl %eax, %eax +@@ -340,7 +315,7 @@ L(first_vec_x1_check): + incq %rdi + addq %rdi, %rax + VZEROUPPER_RETURN +- .p2align 4 ++ .p2align 4,, 6 + L(set_zero_end): + xorl %eax, %eax + VZEROUPPER_RETURN +@@ -428,5 +403,39 @@ L(last_vec_x3): + VZEROUPPER_RETURN + # endif + ++ .p2align 4 ++L(cross_page_boundary): ++ /* Save pointer before aligning as its original value is necessary for ++ computer return address if byte is found or adjusting length if it ++ is not and this is memchr. */ ++ movq %rdi, %rcx ++ /* Align data to VEC_SIZE - 1. ALGN_PTR_REG is rcx for memchr ++ and rdi for rawmemchr. */ ++ orq $(VEC_SIZE - 1), %ALGN_PTR_REG ++ VPCMPEQ -(VEC_SIZE - 1)(%ALGN_PTR_REG), %ymm0, %ymm1 ++ vpmovmskb %ymm1, %eax ++# ifndef USE_AS_RAWMEMCHR ++ /* Calculate length until end of page (length checked for a match). */ ++ leaq 1(%ALGN_PTR_REG), %rsi ++ subq %RRAW_PTR_REG, %rsi ++# ifdef USE_AS_WMEMCHR ++ /* NB: Divide bytes by 4 to get wchar_t count. */ ++ shrl $2, %esi ++# endif ++# endif ++ /* Remove the leading bytes. */ ++ sarxl %ERAW_PTR_REG, %eax, %eax ++# ifndef USE_AS_RAWMEMCHR ++ /* Check the end of data. */ ++ cmpq %rsi, %rdx ++ jbe L(first_vec_x0) ++# endif ++ testl %eax, %eax ++ jz L(cross_page_continue) ++ bsfl %eax, %eax ++ addq %RRAW_PTR_REG, %rax ++ VZEROUPPER_RETURN ++ ++ + END (MEMCHR) + #endif diff --git a/SOURCES/glibc-upstream-2.34-287.patch b/SOURCES/glibc-upstream-2.34-287.patch new file mode 100644 index 0000000..083be9d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-287.patch @@ -0,0 +1,130 @@ +commit 3c87383a20daff9a230439e31b778716bfed4d8b +Author: Noah Goldstein +Date: Mon Jun 6 21:11:34 2022 -0700 + + x86: Shrink code size of memchr-evex.S + + This is not meant as a performance optimization. The previous code was + far to liberal in aligning targets and wasted code size unnecissarily. + + The total code size saving is: 64 bytes + + There are no non-negligible changes in the benchmarks. + Geometric Mean of all benchmarks New / Old: 1.000 + + Full xcheck passes on x86_64. + Reviewed-by: H.J. Lu + + (cherry picked from commit 56da3fe1dd075285fa8186d44b3c28e68c687e62) + +diff --git a/sysdeps/x86_64/multiarch/memchr-evex.S b/sysdeps/x86_64/multiarch/memchr-evex.S +index 4d0ed6d136f099e1..68381c99a4948134 100644 +--- a/sysdeps/x86_64/multiarch/memchr-evex.S ++++ b/sysdeps/x86_64/multiarch/memchr-evex.S +@@ -88,7 +88,7 @@ + # define PAGE_SIZE 4096 + + .section SECTION(.text),"ax",@progbits +-ENTRY (MEMCHR) ++ENTRY_P2ALIGN (MEMCHR, 6) + # ifndef USE_AS_RAWMEMCHR + /* Check for zero length. */ + test %RDX_LP, %RDX_LP +@@ -131,22 +131,24 @@ L(zero): + xorl %eax, %eax + ret + +- .p2align 5 ++ .p2align 4 + L(first_vec_x0): +- /* Check if first match was before length. */ +- tzcntl %eax, %eax +- xorl %ecx, %ecx +- cmpl %eax, %edx +- leaq (%rdi, %rax, CHAR_SIZE), %rax +- cmovle %rcx, %rax ++ /* Check if first match was before length. NB: tzcnt has false data- ++ dependency on destination. eax already had a data-dependency on esi ++ so this should have no affect here. */ ++ tzcntl %eax, %esi ++# ifdef USE_AS_WMEMCHR ++ leaq (%rdi, %rsi, CHAR_SIZE), %rdi ++# else ++ addq %rsi, %rdi ++# endif ++ xorl %eax, %eax ++ cmpl %esi, %edx ++ cmovg %rdi, %rax + ret +-# else +- /* NB: first_vec_x0 is 17 bytes which will leave +- cross_page_boundary (which is relatively cold) close enough +- to ideal alignment. So only realign L(cross_page_boundary) if +- rawmemchr. */ +- .p2align 4 + # endif ++ ++ .p2align 4 + L(cross_page_boundary): + /* Save pointer before aligning as its original value is + necessary for computer return address if byte is found or +@@ -400,10 +402,14 @@ L(last_2x_vec): + L(zero_end): + ret + ++L(set_zero_end): ++ xorl %eax, %eax ++ ret + + .p2align 4 + L(first_vec_x1_check): +- tzcntl %eax, %eax ++ /* eax must be non-zero. Use bsfl to save code size. */ ++ bsfl %eax, %eax + /* Adjust length. */ + subl $-(CHAR_PER_VEC * 4), %edx + /* Check if match within remaining length. */ +@@ -412,9 +418,6 @@ L(first_vec_x1_check): + /* NB: Multiply bytes by CHAR_SIZE to get the wchar_t count. */ + leaq VEC_SIZE(%rdi, %rax, CHAR_SIZE), %rax + ret +-L(set_zero_end): +- xorl %eax, %eax +- ret + + .p2align 4 + L(loop_4x_vec_end): +@@ -464,7 +467,7 @@ L(loop_4x_vec_end): + # endif + ret + +- .p2align 4 ++ .p2align 4,, 10 + L(last_vec_x1_return): + tzcntl %eax, %eax + # if defined USE_AS_WMEMCHR || RET_OFFSET != 0 +@@ -496,6 +499,7 @@ L(last_vec_x3_return): + # endif + + # ifndef USE_AS_RAWMEMCHR ++ .p2align 4,, 5 + L(last_4x_vec_or_less_cmpeq): + VPCMP $0, (VEC_SIZE * 5)(%rdi), %YMMMATCH, %k0 + kmovd %k0, %eax +@@ -546,7 +550,7 @@ L(last_4x_vec): + # endif + andl %ecx, %eax + jz L(zero_end2) +- tzcntl %eax, %eax ++ bsfl %eax, %eax + leaq (VEC_SIZE * 4)(%rdi, %rax, CHAR_SIZE), %rax + L(zero_end2): + ret +@@ -562,6 +566,6 @@ L(last_vec_x3): + leaq (VEC_SIZE * 3)(%rdi, %rax, CHAR_SIZE), %rax + ret + # endif +- ++ /* 7 bytes from next cache line. */ + END (MEMCHR) + #endif diff --git a/SOURCES/glibc-upstream-2.34-288.patch b/SOURCES/glibc-upstream-2.34-288.patch new file mode 100644 index 0000000..6565455 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-288.patch @@ -0,0 +1,33 @@ +commit 820504e3edd7276bf869d543ad5b57187ff9c9b6 +Author: Noah Goldstein +Date: Fri Jun 3 18:52:37 2022 -0500 + + x86: ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST expect no transactions + + Give fall-through path to `vzeroupper` and taken-path to `vzeroall`. + + Generally even on machines with RTM the expectation is the + string-library functions will not be called in transactions. + Reviewed-by: H.J. Lu + + (cherry picked from commit c28db9cb29a7d6cf3ce08fd8445e6b7dea03f35b) + +diff --git a/sysdeps/x86_64/sysdep.h b/sysdeps/x86_64/sysdep.h +index 93e44be22e2275f1..04478b097cdffe20 100644 +--- a/sysdeps/x86_64/sysdep.h ++++ b/sysdeps/x86_64/sysdep.h +@@ -99,11 +99,11 @@ lose: \ + to avoid RTM abort triggered by VZEROUPPER inside transactionally. */ + #define ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST \ + xtest; \ +- jz 1f; \ +- vzeroall; \ ++ jnz 1f; \ ++ vzeroupper; \ + ret; \ + 1: \ +- vzeroupper; \ ++ vzeroall; \ + ret + + /* Can be used to replace vzeroupper that is not directly before a diff --git a/SOURCES/glibc-upstream-2.34-289.patch b/SOURCES/glibc-upstream-2.34-289.patch new file mode 100644 index 0000000..fe9c335 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-289.patch @@ -0,0 +1,41 @@ +commit fc54e1fae854e6ee6361cd4ddf900c36fce8158e +Author: Noah Goldstein +Date: Wed Jun 8 21:16:51 2022 -0700 + + x86: Align varshift table to 32-bytes + + This ensures the load will never split a cache line. + + (cherry picked from commit 0f91811333f23b61cf681cab2704b35a0a073b97) + +diff --git a/sysdeps/x86_64/multiarch/varshift.c b/sysdeps/x86_64/multiarch/varshift.c +index 45267b0a6823459a..1f563542666bc4f1 100644 +--- a/sysdeps/x86_64/multiarch/varshift.c ++++ b/sysdeps/x86_64/multiarch/varshift.c +@@ -16,9 +16,10 @@ + License along with the GNU C Library; if not, see + . */ + +-#include "varshift.h" ++#include + +-const int8_t ___m128i_shift_right[31] attribute_hidden = ++const int8_t ___m128i_shift_right[31] attribute_hidden ++ __attribute__((aligned(32))) = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +diff --git a/sysdeps/x86_64/multiarch/varshift.h b/sysdeps/x86_64/multiarch/varshift.h +index 32f2173dd2a95b3a..745d48fa7c775136 100644 +--- a/sysdeps/x86_64/multiarch/varshift.h ++++ b/sysdeps/x86_64/multiarch/varshift.h +@@ -19,7 +19,8 @@ + #include + #include + +-extern const int8_t ___m128i_shift_right[31] attribute_hidden; ++extern const int8_t ___m128i_shift_right[31] attribute_hidden ++ __attribute__ ((aligned (32))); + + static __inline__ __m128i + __m128i_shift_right (__m128i value, unsigned long int offset) diff --git a/SOURCES/glibc-upstream-2.34-29.patch b/SOURCES/glibc-upstream-2.34-29.patch new file mode 100644 index 0000000..2a35ad6 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-29.patch @@ -0,0 +1,101 @@ +commit e870aac8974cda746157a5a3c9f452ccd70da29b +Author: Adhemerval Zanella +Date: Mon Sep 6 12:22:54 2021 -0300 + + misc: Add __get_nprocs_sched + + This is an internal function meant to return the number of avaliable + processor where the process can scheduled, different than the + __get_nprocs which returns a the system available online CPU. + + The Linux implementation currently only calls __get_nprocs(), which + in tuns calls sched_getaffinity. + + Reviewed-by: Florian Weimer + (cherry picked from commit 11a02b035b464ab6813676adfd19c4a59c36d907) + +diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h +index 7388356a19269335..c490561581733038 100644 +--- a/include/sys/sysinfo.h ++++ b/include/sys/sysinfo.h +@@ -9,10 +9,15 @@ + extern int __get_nprocs_conf (void); + libc_hidden_proto (__get_nprocs_conf) + +-/* Return number of available processors. */ ++/* Return number of available processors (not all of them will be ++ available to the caller process). */ + extern int __get_nprocs (void); + libc_hidden_proto (__get_nprocs) + ++/* Return the number of available processors which the process can ++ be scheduled. */ ++extern int __get_nprocs_sched (void) attribute_hidden; ++ + /* Return number of physical pages of memory in the system. */ + extern long int __get_phys_pages (void); + libc_hidden_proto (__get_phys_pages) +diff --git a/malloc/arena.c b/malloc/arena.c +index 667484630ed0afa5..f1f0af86489d0063 100644 +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -879,7 +879,7 @@ arena_get2 (size_t size, mstate avoid_arena) + narenas_limit = mp_.arena_max; + else if (narenas > mp_.arena_test) + { +- int n = __get_nprocs (); ++ int n = __get_nprocs_sched (); + + if (n >= 1) + narenas_limit = NARENAS_FROM_NCORES (n); +diff --git a/misc/getsysstats.c b/misc/getsysstats.c +index 0eedface6d2b0f75..57d93601e21265d7 100644 +--- a/misc/getsysstats.c ++++ b/misc/getsysstats.c +@@ -45,6 +45,12 @@ weak_alias (__get_nprocs, get_nprocs) + link_warning (get_nprocs, "warning: get_nprocs will always return 1") + + ++int ++__get_nprocs_sched (void) ++{ ++ return 1; ++} ++ + long int + __get_phys_pages (void) + { +diff --git a/sysdeps/mach/getsysstats.c b/sysdeps/mach/getsysstats.c +index 1267f39da26aee38..cc8023f979bf6f74 100644 +--- a/sysdeps/mach/getsysstats.c ++++ b/sysdeps/mach/getsysstats.c +@@ -62,6 +62,12 @@ __get_nprocs (void) + libc_hidden_def (__get_nprocs) + weak_alias (__get_nprocs, get_nprocs) + ++int ++__get_nprocs_sched (void) ++{ ++ return __get_nprocs (); ++} ++ + /* Return the number of physical pages on the system. */ + long int + __get_phys_pages (void) +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index 1391e360b8f8e86c..120ce1bb756b09cc 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -88,6 +88,12 @@ __get_nprocs (void) + libc_hidden_def (__get_nprocs) + weak_alias (__get_nprocs, get_nprocs) + ++int ++__get_nprocs_sched (void) ++{ ++ return __get_nprocs (); ++} ++ + + /* On some architectures it is possible to distinguish between configured + and active cpus. */ diff --git a/SOURCES/glibc-upstream-2.34-290.patch b/SOURCES/glibc-upstream-2.34-290.patch new file mode 100644 index 0000000..326109c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-290.patch @@ -0,0 +1,56 @@ +commit 6e008c884dad5a25f91085c68d044bb5e2d63761 +Author: Noah Goldstein +Date: Tue Jun 14 13:50:11 2022 -0700 + + x86: Fix misordered logic for setting `rep_movsb_stop_threshold` + + Move the setting of `rep_movsb_stop_threshold` to after the tunables + have been collected so that the `rep_movsb_stop_threshold` (which + is used to redirect control flow to the non_temporal case) will + use any user value for `non_temporal_threshold` (set using + glibc.cpu.x86_non_temporal_threshold) + + (cherry picked from commit 035591551400cfc810b07244a015c9411e8bff7c) + +diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h +index 2e43e67e4f4037d3..560bf260e8fbd7bf 100644 +--- a/sysdeps/x86/dl-cacheinfo.h ++++ b/sysdeps/x86/dl-cacheinfo.h +@@ -898,18 +898,6 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) + if (CPU_FEATURE_USABLE_P (cpu_features, FSRM)) + rep_movsb_threshold = 2112; + +- unsigned long int rep_movsb_stop_threshold; +- /* ERMS feature is implemented from AMD Zen3 architecture and it is +- performing poorly for data above L2 cache size. Henceforth, adding +- an upper bound threshold parameter to limit the usage of Enhanced +- REP MOVSB operations and setting its value to L2 cache size. */ +- if (cpu_features->basic.kind == arch_kind_amd) +- rep_movsb_stop_threshold = core; +- /* Setting the upper bound of ERMS to the computed value of +- non-temporal threshold for architectures other than AMD. */ +- else +- rep_movsb_stop_threshold = non_temporal_threshold; +- + /* The default threshold to use Enhanced REP STOSB. */ + unsigned long int rep_stosb_threshold = 2048; + +@@ -951,6 +939,18 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) + SIZE_MAX); + #endif + ++ unsigned long int rep_movsb_stop_threshold; ++ /* ERMS feature is implemented from AMD Zen3 architecture and it is ++ performing poorly for data above L2 cache size. Henceforth, adding ++ an upper bound threshold parameter to limit the usage of Enhanced ++ REP MOVSB operations and setting its value to L2 cache size. */ ++ if (cpu_features->basic.kind == arch_kind_amd) ++ rep_movsb_stop_threshold = core; ++ /* Setting the upper bound of ERMS to the computed value of ++ non-temporal threshold for architectures other than AMD. */ ++ else ++ rep_movsb_stop_threshold = non_temporal_threshold; ++ + cpu_features->data_cache_size = data; + cpu_features->shared_cache_size = shared; + cpu_features->non_temporal_threshold = non_temporal_threshold; diff --git a/SOURCES/glibc-upstream-2.34-291.patch b/SOURCES/glibc-upstream-2.34-291.patch new file mode 100644 index 0000000..849476f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-291.patch @@ -0,0 +1,38 @@ +commit 9d50e162eef88e1f870a941b0a973060e984e7ca +Author: Noah Goldstein +Date: Tue Jun 14 15:37:28 2022 -0700 + + x86: Add sse42 implementation to strcmp's ifunc + + This has been missing since the the ifuncs where added. + + The performance of SSE4.2 is preferable to to SSE2. + + Measured on Tigerlake with N = 20 runs. + Geometric Mean of all benchmarks SSE4.2 / SSE2: 0.906 + + (cherry picked from commit ff439c47173565fbff4f0f78d07b0f14e4a7db05) + +diff --git a/sysdeps/x86_64/multiarch/strcmp.c b/sysdeps/x86_64/multiarch/strcmp.c +index 7c2901bf44456259..b457fb4c150e4407 100644 +--- a/sysdeps/x86_64/multiarch/strcmp.c ++++ b/sysdeps/x86_64/multiarch/strcmp.c +@@ -29,6 +29,7 @@ + extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_unaligned) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden; + extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden; +@@ -53,6 +54,10 @@ IFUNC_SELECTOR (void) + return OPTIMIZE (avx2); + } + ++ if (CPU_FEATURE_USABLE_P (cpu_features, SSE4_2) ++ && !CPU_FEATURES_ARCH_P (cpu_features, Slow_SSE4_2)) ++ return OPTIMIZE (sse42); ++ + if (CPU_FEATURES_ARCH_P (cpu_features, Fast_Unaligned_Load)) + return OPTIMIZE (sse2_unaligned); + diff --git a/SOURCES/glibc-upstream-2.34-292.patch b/SOURCES/glibc-upstream-2.34-292.patch new file mode 100644 index 0000000..492f541 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-292.patch @@ -0,0 +1,54 @@ +commit 94b0dc9419bd038cb85b364a7556569386c31741 +Author: Noah Goldstein +Date: Wed Jun 15 10:41:29 2022 -0700 + + x86: Add bounds `x86_non_temporal_threshold` + + The lower-bound (16448) and upper-bound (SIZE_MAX / 16) are assumed + by memmove-vec-unaligned-erms. + + The lower-bound is needed because memmove-vec-unaligned-erms unrolls + the loop aggressively in the L(large_memset_4x) case. + + The upper-bound is needed because memmove-vec-unaligned-erms + right-shifts the value of `x86_non_temporal_threshold` by + LOG_4X_MEMCPY_THRESH (4) which without a bound may overflow. + + The lack of lower-bound can be a correctness issue. The lack of + upper-bound cannot. + + (cherry picked from commit b446822b6ae4e8149902a78cdd4a886634ad6321) + +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 28ff502990c2a10f..5ab3212f34e3dc37 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -47,7 +47,7 @@ glibc.malloc.mxfast: 0x0 (min: 0x0, max: 0xffffffffffffffff) + glibc.elision.skip_lock_busy: 3 (min: -2147483648, max: 2147483647) + glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0xffffffffffffffff) + glibc.cpu.x86_rep_stosb_threshold: 0x800 (min: 0x1, max: 0xffffffffffffffff) +-glibc.cpu.x86_non_temporal_threshold: 0xc0000 (min: 0x0, max: 0xffffffffffffffff) ++glibc.cpu.x86_non_temporal_threshold: 0xc0000 (min: 0x4040, max: 0x0fffffffffffffff) + glibc.cpu.x86_shstk: + glibc.cpu.hwcap_mask: 0x6 (min: 0x0, max: 0xffffffffffffffff) + glibc.malloc.mmap_max: 0 (min: -2147483648, max: 2147483647) +diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h +index 560bf260e8fbd7bf..8f85f70858413ebe 100644 +--- a/sysdeps/x86/dl-cacheinfo.h ++++ b/sysdeps/x86/dl-cacheinfo.h +@@ -931,8 +931,14 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) + + TUNABLE_SET_WITH_BOUNDS (x86_data_cache_size, data, 0, SIZE_MAX); + TUNABLE_SET_WITH_BOUNDS (x86_shared_cache_size, shared, 0, SIZE_MAX); ++ /* SIZE_MAX >> 4 because memmove-vec-unaligned-erms right-shifts the value of ++ 'x86_non_temporal_threshold' by `LOG_4X_MEMCPY_THRESH` (4) and it is best ++ if that operation cannot overflow. Minimum of 0x4040 (16448) because the ++ L(large_memset_4x) loops need 64-byte to cache align and enough space for ++ at least 1 iteration of 4x PAGE_SIZE unrolled loop. Both values are ++ reflected in the manual. */ + TUNABLE_SET_WITH_BOUNDS (x86_non_temporal_threshold, non_temporal_threshold, +- 0, SIZE_MAX); ++ 0x4040, SIZE_MAX >> 4); + TUNABLE_SET_WITH_BOUNDS (x86_rep_movsb_threshold, rep_movsb_threshold, + minimum_rep_movsb_threshold, SIZE_MAX); + TUNABLE_SET_WITH_BOUNDS (x86_rep_stosb_threshold, rep_stosb_threshold, 1, diff --git a/SOURCES/glibc-upstream-2.34-293.patch b/SOURCES/glibc-upstream-2.34-293.patch new file mode 100644 index 0000000..81a4e0e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-293.patch @@ -0,0 +1,88 @@ +commit ba1c3f23d9ba63c38333116eec6043c471c378c4 +Author: Noah Goldstein +Date: Wed Jun 15 10:41:28 2022 -0700 + + x86: Cleanup bounds checking in large memcpy case + + 1. Fix incorrect lower-bound threshold in L(large_memcpy_2x). + Previously was using `__x86_rep_movsb_threshold` and should + have been using `__x86_shared_non_temporal_threshold`. + + 2. Avoid reloading __x86_shared_non_temporal_threshold before + the L(large_memcpy_4x) bounds check. + + 3. Document the second bounds check for L(large_memcpy_4x) + more clearly. + + (cherry picked from commit 89a25c6f64746732b87eaf433af0964b564d4a92) + +diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +index 7b27cbdda5fb99f7..618d46d8ce28828c 100644 +--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +@@ -118,7 +118,13 @@ + # define LARGE_LOAD_SIZE (VEC_SIZE * 4) + #endif + +-/* Amount to shift rdx by to compare for memcpy_large_4x. */ ++/* Amount to shift __x86_shared_non_temporal_threshold by for ++ bound for memcpy_large_4x. This is essentially use to to ++ indicate that the copy is far beyond the scope of L3 ++ (assuming no user config x86_non_temporal_threshold) and to ++ use a more aggressively unrolled loop. NB: before ++ increasing the value also update initialization of ++ x86_non_temporal_threshold. */ + #ifndef LOG_4X_MEMCPY_THRESH + # define LOG_4X_MEMCPY_THRESH 4 + #endif +@@ -724,9 +730,14 @@ L(skip_short_movsb_check): + .p2align 4,, 10 + #if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc) + L(large_memcpy_2x_check): +- cmp __x86_rep_movsb_threshold(%rip), %RDX_LP +- jb L(more_8x_vec_check) ++ /* Entry from L(large_memcpy_2x) has a redundant load of ++ __x86_shared_non_temporal_threshold(%rip). L(large_memcpy_2x) ++ is only use for the non-erms memmove which is generally less ++ common. */ + L(large_memcpy_2x): ++ mov __x86_shared_non_temporal_threshold(%rip), %R11_LP ++ cmp %R11_LP, %RDX_LP ++ jb L(more_8x_vec_check) + /* To reach this point it is impossible for dst > src and + overlap. Remaining to check is src > dst and overlap. rcx + already contains dst - src. Negate rcx to get src - dst. If +@@ -774,18 +785,21 @@ L(large_memcpy_2x): + /* ecx contains -(dst - src). not ecx will return dst - src - 1 + which works for testing aliasing. */ + notl %ecx ++ movq %rdx, %r10 + testl $(PAGE_SIZE - VEC_SIZE * 8), %ecx + jz L(large_memcpy_4x) + +- movq %rdx, %r10 +- shrq $LOG_4X_MEMCPY_THRESH, %r10 +- cmp __x86_shared_non_temporal_threshold(%rip), %r10 ++ /* r11 has __x86_shared_non_temporal_threshold. Shift it left ++ by LOG_4X_MEMCPY_THRESH to get L(large_memcpy_4x) threshold. ++ */ ++ shlq $LOG_4X_MEMCPY_THRESH, %r11 ++ cmp %r11, %rdx + jae L(large_memcpy_4x) + + /* edx will store remainder size for copying tail. */ + andl $(PAGE_SIZE * 2 - 1), %edx + /* r10 stores outer loop counter. */ +- shrq $((LOG_PAGE_SIZE + 1) - LOG_4X_MEMCPY_THRESH), %r10 ++ shrq $(LOG_PAGE_SIZE + 1), %r10 + /* Copy 4x VEC at a time from 2 pages. */ + .p2align 4 + L(loop_large_memcpy_2x_outer): +@@ -850,7 +864,6 @@ L(large_memcpy_2x_end): + + .p2align 4 + L(large_memcpy_4x): +- movq %rdx, %r10 + /* edx will store remainder size for copying tail. */ + andl $(PAGE_SIZE * 4 - 1), %edx + /* r10 stores outer loop counter. */ diff --git a/SOURCES/glibc-upstream-2.34-294.patch b/SOURCES/glibc-upstream-2.34-294.patch new file mode 100644 index 0000000..a7bd391 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-294.patch @@ -0,0 +1,27 @@ +commit c51d8d383cfb92142b86d8d1822159f3bea10d16 +Author: Noah Goldstein +Date: Thu Jun 16 15:01:08 2022 -0700 + + x86: Add BMI1/BMI2 checks for ISA_V3 check + + BMI1/BMI2 are part of the ISA V3 requirements: + https://en.wikipedia.org/wiki/X86-64 + + And defined by GCC when building with `-march=x86-64-v3` + + (cherry picked from commit 8da9f346cb2051844348785b8a932ec44489e0b7) + +diff --git a/sysdeps/x86/isa-level.c b/sysdeps/x86/isa-level.c +index 49ef4aa6122072cf..07815381122c94c3 100644 +--- a/sysdeps/x86/isa-level.c ++++ b/sysdeps/x86/isa-level.c +@@ -47,7 +47,8 @@ + # endif + + # if ISA_V2 && defined __AVX__ && defined __AVX2__ && defined __F16C__ \ +- && defined __FMA__ && defined __LZCNT__ && defined HAVE_X86_MOVBE ++ && defined __FMA__ && defined __LZCNT__ && defined HAVE_X86_MOVBE \ ++ && defined __BMI__ && defined __BMI2__ + /* NB: ISAs in x86-64 ISA level v3 are used. */ + # define ISA_V3 GNU_PROPERTY_X86_ISA_1_V3 + # else diff --git a/SOURCES/glibc-upstream-2.34-295.patch b/SOURCES/glibc-upstream-2.34-295.patch new file mode 100644 index 0000000..88d89e8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-295.patch @@ -0,0 +1,28 @@ +commit d201c59177b98946d7f80145e7b4d02991d04805 +Author: Noah Goldstein +Date: Fri Jun 24 09:42:12 2022 -0700 + + x86: Align entry for memrchr to 64-bytes. + + The function was tuned around 64-byte entry alignment and performs + better for all sizes with it. + + As well different code boths where explicitly written to touch the + minimum number of cache line i.e sizes <= 32 touch only the entry + cache line. + + (cherry picked from commit 227afaa67213efcdce6a870ef5086200f1076438) + +diff --git a/sysdeps/x86_64/multiarch/memrchr-avx2.S b/sysdeps/x86_64/multiarch/memrchr-avx2.S +index 5f8e0be18cfe4fad..edd8180ba1ede9a5 100644 +--- a/sysdeps/x86_64/multiarch/memrchr-avx2.S ++++ b/sysdeps/x86_64/multiarch/memrchr-avx2.S +@@ -35,7 +35,7 @@ + # define VEC_SIZE 32 + # define PAGE_SIZE 4096 + .section SECTION(.text), "ax", @progbits +-ENTRY(MEMRCHR) ++ENTRY_P2ALIGN(MEMRCHR, 6) + # ifdef __ILP32__ + /* Clear upper bits. */ + and %RDX_LP, %RDX_LP diff --git a/SOURCES/glibc-upstream-2.34-296.patch b/SOURCES/glibc-upstream-2.34-296.patch new file mode 100644 index 0000000..eecd005 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-296.patch @@ -0,0 +1,56 @@ +commit aadd0a1c7c89d016e1186c81c0efcafa36bf84fc +Author: Noah Goldstein +Date: Fri Jun 24 09:42:15 2022 -0700 + + x86: Put wcs{n}len-sse4.1 in the sse4.1 text section + + Previously was missing but the two implementations shouldn't get in + the sse2 (generic) text section. + + (cherry picked from commit afc6e4328ff80973bde50d5401691b4c4b2e522c) + +diff --git a/sysdeps/x86_64/multiarch/strlen-vec.S b/sysdeps/x86_64/multiarch/strlen-vec.S +index 031753a91763b351..762f4755020c35f9 100644 +--- a/sysdeps/x86_64/multiarch/strlen-vec.S ++++ b/sysdeps/x86_64/multiarch/strlen-vec.S +@@ -28,6 +28,10 @@ + # define SHIFT_RETURN + #endif + ++#ifndef SECTION ++# define SECTION(p) p ++#endif ++ + /* Long lived register in strlen(s), strnlen(s, n) are: + + %xmm3 - zero +@@ -37,7 +41,7 @@ + */ + + +-.text ++ .section SECTION(.text),"ax",@progbits + ENTRY(strlen) + + /* Test 64 bytes from %rax for zero. Save result as bitmask in %rdx. */ +diff --git a/sysdeps/x86_64/multiarch/wcslen-sse4_1.S b/sysdeps/x86_64/multiarch/wcslen-sse4_1.S +index 7e62621afc729492..e306a77f51e650d1 100644 +--- a/sysdeps/x86_64/multiarch/wcslen-sse4_1.S ++++ b/sysdeps/x86_64/multiarch/wcslen-sse4_1.S +@@ -1,4 +1,5 @@ + #define AS_WCSLEN + #define strlen __wcslen_sse4_1 ++#define SECTION(p) p##.sse4.1 + + #include "strlen-vec.S" +diff --git a/sysdeps/x86_64/multiarch/wcsnlen-sse4_1.S b/sysdeps/x86_64/multiarch/wcsnlen-sse4_1.S +index 5fa51fe07cbbdf5c..d2f7dd6e2254736c 100644 +--- a/sysdeps/x86_64/multiarch/wcsnlen-sse4_1.S ++++ b/sysdeps/x86_64/multiarch/wcsnlen-sse4_1.S +@@ -1,5 +1,6 @@ + #define AS_WCSLEN + #define AS_STRNLEN + #define strlen __wcsnlen_sse4_1 ++#define SECTION(p) p##.sse4.1 + + #include "strlen-vec.S" diff --git a/SOURCES/glibc-upstream-2.34-297.patch b/SOURCES/glibc-upstream-2.34-297.patch new file mode 100644 index 0000000..1bc2f3c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-297.patch @@ -0,0 +1,25 @@ +commit f4598f0351559f1a4176d7ce0154423d98bcfb0d +Author: Noah Goldstein +Date: Wed Jun 29 16:07:04 2022 -0700 + + x86: Add definition for __wmemset_chk AVX2 RTM in ifunc impl list + + This was simply missing and meant we weren't testing it properly. + + (cherry picked from commit 2a1099020cdc1e4c9c928156aa85c8cf9d540291) + +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index 043821278fdb6d8f..8d649e263eb24b8a 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -1032,6 +1032,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, __wmemset_chk, + CPU_FEATURE_USABLE (AVX2), + __wmemset_chk_avx2_unaligned) ++ IFUNC_IMPL_ADD (array, i, __wmemset_chk, ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (RTM)), ++ __wmemset_chk_avx2_unaligned_rtm) + IFUNC_IMPL_ADD (array, i, __wmemset_chk, + (CPU_FEATURE_USABLE (AVX512VL) + && CPU_FEATURE_USABLE (AVX512BW) diff --git a/SOURCES/glibc-upstream-2.34-298.patch b/SOURCES/glibc-upstream-2.34-298.patch new file mode 100644 index 0000000..ae07d14 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-298.patch @@ -0,0 +1,124 @@ +commit 7079931c51547854323fe2ed6fdccf2a1b8b04d7 +Author: Noah Goldstein +Date: Wed Jun 29 16:07:05 2022 -0700 + + x86: Move and slightly improve memset_erms + + Implementation wise: + 1. Remove the VZEROUPPER as memset_{impl}_unaligned_erms does not + use the L(stosb) label that was previously defined. + + 2. Don't give the hotpath (fallthrough) to zero size. + + Code positioning wise: + + Move memset_{chk}_erms to its own file. Leaving it in between the + memset_{impl}_unaligned both adds unnecessary complexity to the + file and wastes space in a relatively hot cache section. + + (cherry picked from commit 4a3f29e7e475dd4e7cce2a24c187e6fb7b5b0a05) + +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index 0e39e63ef6be6a86..da9f16286a763556 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -29,6 +29,7 @@ sysdep_routines += \ + memset-avx2-unaligned-erms-rtm \ + memset-avx512-no-vzeroupper \ + memset-avx512-unaligned-erms \ ++ memset-erms \ + memset-evex-unaligned-erms \ + memset-sse2-unaligned-erms \ + rawmemchr-avx2 \ +diff --git a/sysdeps/x86_64/multiarch/memset-erms.S b/sysdeps/x86_64/multiarch/memset-erms.S +new file mode 100644 +index 0000000000000000..e83cccc731f0a7ea +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/memset-erms.S +@@ -0,0 +1,44 @@ ++/* memset implement with rep stosb ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include ++ ++#if defined USE_MULTIARCH && IS_IN (libc) ++ .text ++ENTRY (__memset_chk_erms) ++ cmp %RDX_LP, %RCX_LP ++ jb HIDDEN_JUMPTARGET (__chk_fail) ++END (__memset_chk_erms) ++ ++/* Only used to measure performance of REP STOSB. */ ++ENTRY (__memset_erms) ++ /* Skip zero length. */ ++ test %RDX_LP, %RDX_LP ++ jz L(stosb_return_zero) ++ mov %RDX_LP, %RCX_LP ++ movzbl %sil, %eax ++ mov %RDI_LP, %RDX_LP ++ rep stosb ++ mov %RDX_LP, %RAX_LP ++ ret ++L(stosb_return_zero): ++ movq %rdi, %rax ++ ret ++END (__memset_erms) ++#endif +diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +index abc12d9cda1b3843..905d0fa4643d5768 100644 +--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S +@@ -156,37 +156,6 @@ L(entry_from_wmemset): + #if defined USE_MULTIARCH && IS_IN (libc) + END (MEMSET_SYMBOL (__memset, unaligned)) + +-# if VEC_SIZE == 16 +-ENTRY (__memset_chk_erms) +- cmp %RDX_LP, %RCX_LP +- jb HIDDEN_JUMPTARGET (__chk_fail) +-END (__memset_chk_erms) +- +-/* Only used to measure performance of REP STOSB. */ +-ENTRY (__memset_erms) +- /* Skip zero length. */ +- test %RDX_LP, %RDX_LP +- jnz L(stosb) +- movq %rdi, %rax +- ret +-# else +-/* Provide a hidden symbol to debugger. */ +- .hidden MEMSET_SYMBOL (__memset, erms) +-ENTRY (MEMSET_SYMBOL (__memset, erms)) +-# endif +-L(stosb): +- mov %RDX_LP, %RCX_LP +- movzbl %sil, %eax +- mov %RDI_LP, %RDX_LP +- rep stosb +- mov %RDX_LP, %RAX_LP +- VZEROUPPER_RETURN +-# if VEC_SIZE == 16 +-END (__memset_erms) +-# else +-END (MEMSET_SYMBOL (__memset, erms)) +-# endif +- + # if defined SHARED && IS_IN (libc) + ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms)) + cmp %RDX_LP, %RCX_LP diff --git a/SOURCES/glibc-upstream-2.34-299.patch b/SOURCES/glibc-upstream-2.34-299.patch new file mode 100644 index 0000000..afa05e9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-299.patch @@ -0,0 +1,163 @@ +commit 35f9c72c8bd7bc30deb412e966e2f548241b15d2 +Author: Noah Goldstein +Date: Wed Jun 29 16:07:15 2022 -0700 + + x86: Move mem{p}{mov|cpy}_{chk_}erms to its own file + + The primary memmove_{impl}_unaligned_erms implementations don't + interact with this function. Putting them in same file both + wastes space and unnecessarily bloats a hot code section. + + (cherry picked from commit 21925f64730d52eb7d8b2fb62b412f8ab92b0caf) + +diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile +index da9f16286a763556..b9ea5b60c2be1b0a 100644 +--- a/sysdeps/x86_64/multiarch/Makefile ++++ b/sysdeps/x86_64/multiarch/Makefile +@@ -17,6 +17,7 @@ sysdep_routines += \ + memmove-avx-unaligned-erms-rtm \ + memmove-avx512-no-vzeroupper \ + memmove-avx512-unaligned-erms \ ++ memmove-erms \ + memmove-evex-unaligned-erms \ + memmove-sse2-unaligned-erms \ + memmove-ssse3 \ +diff --git a/sysdeps/x86_64/multiarch/memmove-erms.S b/sysdeps/x86_64/multiarch/memmove-erms.S +new file mode 100644 +index 0000000000000000..2d3a6ccb76d77052 +--- /dev/null ++++ b/sysdeps/x86_64/multiarch/memmove-erms.S +@@ -0,0 +1,72 @@ ++/* memcpy/mempcpy/memmove implement with rep movsb ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include ++ ++#if defined USE_MULTIARCH && IS_IN (libc) ++ .text ++ENTRY (__mempcpy_chk_erms) ++ cmp %RDX_LP, %RCX_LP ++ jb HIDDEN_JUMPTARGET (__chk_fail) ++END (__mempcpy_chk_erms) ++ ++/* Only used to measure performance of REP MOVSB. */ ++ENTRY (__mempcpy_erms) ++ mov %RDI_LP, %RAX_LP ++ /* Skip zero length. */ ++ test %RDX_LP, %RDX_LP ++ jz 2f ++ add %RDX_LP, %RAX_LP ++ jmp L(start_movsb) ++END (__mempcpy_erms) ++ ++ENTRY (__memmove_chk_erms) ++ cmp %RDX_LP, %RCX_LP ++ jb HIDDEN_JUMPTARGET (__chk_fail) ++END (__memmove_chk_erms) ++ ++ENTRY (__memmove_erms) ++ movq %rdi, %rax ++ /* Skip zero length. */ ++ test %RDX_LP, %RDX_LP ++ jz 2f ++L(start_movsb): ++ mov %RDX_LP, %RCX_LP ++ cmp %RSI_LP, %RDI_LP ++ jb 1f ++ /* Source == destination is less common. */ ++ je 2f ++ lea (%rsi,%rcx), %RDX_LP ++ cmp %RDX_LP, %RDI_LP ++ jb L(movsb_backward) ++1: ++ rep movsb ++2: ++ ret ++L(movsb_backward): ++ leaq -1(%rdi,%rcx), %rdi ++ leaq -1(%rsi,%rcx), %rsi ++ std ++ rep movsb ++ cld ++ ret ++END (__memmove_erms) ++strong_alias (__memmove_erms, __memcpy_erms) ++strong_alias (__memmove_chk_erms, __memcpy_chk_erms) ++#endif +diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +index 618d46d8ce28828c..93c7e6883a254434 100644 +--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +@@ -239,56 +239,6 @@ L(start): + #endif + #if defined USE_MULTIARCH && IS_IN (libc) + END (MEMMOVE_SYMBOL (__memmove, unaligned)) +-# if VEC_SIZE == 16 +-ENTRY (__mempcpy_chk_erms) +- cmp %RDX_LP, %RCX_LP +- jb HIDDEN_JUMPTARGET (__chk_fail) +-END (__mempcpy_chk_erms) +- +-/* Only used to measure performance of REP MOVSB. */ +-ENTRY (__mempcpy_erms) +- mov %RDI_LP, %RAX_LP +- /* Skip zero length. */ +- test %RDX_LP, %RDX_LP +- jz 2f +- add %RDX_LP, %RAX_LP +- jmp L(start_movsb) +-END (__mempcpy_erms) +- +-ENTRY (__memmove_chk_erms) +- cmp %RDX_LP, %RCX_LP +- jb HIDDEN_JUMPTARGET (__chk_fail) +-END (__memmove_chk_erms) +- +-ENTRY (__memmove_erms) +- movq %rdi, %rax +- /* Skip zero length. */ +- test %RDX_LP, %RDX_LP +- jz 2f +-L(start_movsb): +- mov %RDX_LP, %RCX_LP +- cmp %RSI_LP, %RDI_LP +- jb 1f +- /* Source == destination is less common. */ +- je 2f +- lea (%rsi,%rcx), %RDX_LP +- cmp %RDX_LP, %RDI_LP +- jb L(movsb_backward) +-1: +- rep movsb +-2: +- ret +-L(movsb_backward): +- leaq -1(%rdi,%rcx), %rdi +- leaq -1(%rsi,%rcx), %rsi +- std +- rep movsb +- cld +- ret +-END (__memmove_erms) +-strong_alias (__memmove_erms, __memcpy_erms) +-strong_alias (__memmove_chk_erms, __memcpy_chk_erms) +-# endif + + # ifdef SHARED + ENTRY (MEMMOVE_CHK_SYMBOL (__mempcpy_chk, unaligned_erms)) diff --git a/SOURCES/glibc-upstream-2.34-3.patch b/SOURCES/glibc-upstream-2.34-3.patch new file mode 100644 index 0000000..136cbf2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-3.patch @@ -0,0 +1,32 @@ +commit a5bd2e10e0c25b80286dc36068e22a4cb4893af0 +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:11:03 2021 +0530 + + gaiconf_init: Avoid double-free in label and precedence lists + + labellist and precedencelist could get freed a second time if there + are allocation failures, so set them to NULL to avoid a double-free. + + Reviewed-by: Arjun Shankar + (cherry picked from commit 77a34079d8f3d63b61543bf3af93043f8674e4c4) + +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 838a68f0229b5aa8..43dfc6739e350a58 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -2008,6 +2008,7 @@ gaiconf_init (void) + l = l->next; + } + free_prefixlist (labellist); ++ labellist = NULL; + + /* Sort the entries so that the most specific ones are at + the beginning. */ +@@ -2046,6 +2047,7 @@ gaiconf_init (void) + l = l->next; + } + free_prefixlist (precedencelist); ++ precedencelist = NULL; + + /* Sort the entries so that the most specific ones are at + the beginning. */ diff --git a/SOURCES/glibc-upstream-2.34-30.patch b/SOURCES/glibc-upstream-2.34-30.patch new file mode 100644 index 0000000..7255a98 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-30.patch @@ -0,0 +1,208 @@ +commit cda99af14e82b4bb6abaecd717ebe3b57c0aa534 +Author: Adhemerval Zanella +Date: Mon Sep 6 12:28:24 2021 -0300 + + linux: Simplify get_nprocs + + This patch simplifies the memory allocation code and uses the sched + routines instead of reimplement it. This still uses a stack + allocation buffer, so it can be used on malloc initialization code. + + Linux currently supports at maximum of 4096 cpus for most architectures: + + $ find -iname Kconfig | xargs git grep -A10 -w NR_CPUS | grep -w range + arch/alpha/Kconfig- range 2 32 + arch/arc/Kconfig- range 2 4096 + arch/arm/Kconfig- range 2 16 if DEBUG_KMAP_LOCAL + arch/arm/Kconfig- range 2 32 if !DEBUG_KMAP_LOCAL + arch/arm64/Kconfig- range 2 4096 + arch/csky/Kconfig- range 2 32 + arch/hexagon/Kconfig- range 2 6 if SMP + arch/ia64/Kconfig- range 2 4096 + arch/mips/Kconfig- range 2 256 + arch/openrisc/Kconfig- range 2 32 + arch/parisc/Kconfig- range 2 32 + arch/riscv/Kconfig- range 2 32 + arch/s390/Kconfig- range 2 512 + arch/sh/Kconfig- range 2 32 + arch/sparc/Kconfig- range 2 32 if SPARC32 + arch/sparc/Kconfig- range 2 4096 if SPARC64 + arch/um/Kconfig- range 1 1 + arch/x86/Kconfig-# [NR_CPUS_RANGE_BEGIN ... NR_CPUS_RANGE_END] range. + arch/x86/Kconfig- range NR_CPUS_RANGE_BEGIN NR_CPUS_RANGE_END + arch/xtensa/Kconfig- range 2 32 + + With x86 supporting 8192: + + arch/x86/Kconfig + 976 config NR_CPUS_RANGE_END + 977 int + 978 depends on X86_64 + 979 default 8192 if SMP && CPUMASK_OFFSTACK + 980 default 512 if SMP && !CPUMASK_OFFSTACK + 981 default 1 if !SMP + + So using a maximum of 32k cpu should cover all cases (and I would + expect once we start to have many more CPUs that Linux would provide + a more straightforward way to query for such information). + + A test is added to check if sched_getaffinity can successfully return + with large buffers. + + Checked on x86_64-linux-gnu and i686-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit 33099d72e41cf8a129b362e9709eb2be9372d844) + +diff --git a/posix/Makefile b/posix/Makefile +index a5229777eeb0e067..61fcdf015b4ec83b 100644 +--- a/posix/Makefile ++++ b/posix/Makefile +@@ -107,7 +107,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \ + tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \ + tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ + bug-regex38 tst-regcomp-truncated tst-spawn-chdir \ +- tst-wordexp-nocmd tst-execveat tst-spawn5 ++ tst-wordexp-nocmd tst-execveat tst-spawn5 \ ++ tst-sched_getaffinity + + # Test for the glob symbol version that was replaced in glibc 2.27. + ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) +diff --git a/posix/tst-sched_getaffinity.c b/posix/tst-sched_getaffinity.c +new file mode 100644 +index 0000000000000000..db9d517a96fdd99e +--- /dev/null ++++ b/posix/tst-sched_getaffinity.c +@@ -0,0 +1,48 @@ ++/* Tests for sched_getaffinity with large buffers. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* NB: this test may fail on system with more than 32k cpus. */ ++ ++static int ++do_test (void) ++{ ++ /* The values are larger than the default cpu_set_t. */ ++ const int bufsize[] = { 1<<11, 1<<12, 1<<13, 1<<14, 1<<15, 1<<16, 1<<17 }; ++ int cpucount[array_length (bufsize)]; ++ ++ for (int i = 0; i < array_length (bufsize); i++) ++ { ++ cpu_set_t *cpuset = CPU_ALLOC (bufsize[i]); ++ TEST_VERIFY (cpuset != NULL); ++ size_t size = CPU_ALLOC_SIZE (bufsize[i]); ++ TEST_COMPARE (sched_getaffinity (0, size, cpuset), 0); ++ cpucount[i] = CPU_COUNT_S (size, cpuset); ++ CPU_FREE (cpuset); ++ } ++ ++ for (int i = 0; i < array_length (cpucount) - 1; i++) ++ TEST_COMPARE (cpucount[i], cpucount[i + 1]); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index 120ce1bb756b09cc..61d20e7bab8640f2 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -29,61 +29,29 @@ + #include + #include + +-/* Compute the population count of the entire array. */ +-static int +-__get_nprocs_count (const unsigned long int *array, size_t length) +-{ +- int count = 0; +- for (size_t i = 0; i < length; ++i) +- if (__builtin_add_overflow (count, __builtin_popcountl (array[i]), +- &count)) +- return INT_MAX; +- return count; +-} +- +-/* __get_nprocs with a large buffer. */ +-static int +-__get_nprocs_large (void) +-{ +- /* This code cannot use scratch_buffer because it is used during +- malloc initialization. */ +- size_t pagesize = GLRO (dl_pagesize); +- unsigned long int *page = __mmap (0, pagesize, PROT_READ | PROT_WRITE, +- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); +- if (page == MAP_FAILED) +- return 2; +- int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, pagesize, page); +- int count; +- if (r > 0) +- count = __get_nprocs_count (page, pagesize / sizeof (unsigned long int)); +- else if (r == -EINVAL) +- /* One page is still not enough to store the bits. A more-or-less +- arbitrary value. This assumes t hat such large systems never +- happen in practice. */ +- count = GLRO (dl_pagesize) * CHAR_BIT; +- else +- count = 2; +- __munmap (page, GLRO (dl_pagesize)); +- return count; +-} +- + int + __get_nprocs (void) + { +- /* Fast path for most systems. The kernel expects a buffer size +- that is a multiple of 8. */ +- unsigned long int small_buffer[1024 / CHAR_BIT / sizeof (unsigned long int)]; +- int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, +- sizeof (small_buffer), small_buffer); ++ enum ++ { ++ max_num_cpus = 32768, ++ cpu_bits_size = CPU_ALLOC_SIZE (32768) ++ }; ++ ++ /* This cannot use malloc because it is used on malloc initialization. */ ++ __cpu_mask cpu_bits[cpu_bits_size / sizeof (__cpu_mask)]; ++ int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size, ++ cpu_bits); + if (r > 0) +- return __get_nprocs_count (small_buffer, r / sizeof (unsigned long int)); ++ return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits); + else if (r == -EINVAL) +- /* The kernel requests a larger buffer to store the data. */ +- return __get_nprocs_large (); +- else +- /* Some other error. 2 is conservative (not a uniprocessor +- system, so atomics are needed). */ +- return 2; ++ /* The input buffer is still not enough to store the number of cpus. This ++ is an arbitrary values assuming such systems should be rare and there ++ is no offline cpus. */ ++ return max_num_cpus; ++ /* Some other error. 2 is conservative (not a uniprocessor system, so ++ atomics are needed). */ ++ return 2; + } + libc_hidden_def (__get_nprocs) + weak_alias (__get_nprocs, get_nprocs) diff --git a/SOURCES/glibc-upstream-2.34-300.patch b/SOURCES/glibc-upstream-2.34-300.patch new file mode 100644 index 0000000..5db8327 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-300.patch @@ -0,0 +1,38 @@ +commit ccc54bd61c768b6a27f9305a0831b76a7b6d706f +Author: Noah Goldstein +Date: Wed Jun 29 18:56:18 2022 -0700 + + x86: Add missing IS_IN (libc) check to strncmp-sse4_2.S + + Was missing to for the multiarch build rtld-strncmp-sse4_2.os was + being built and exporting symbols: + + build/glibc/string/rtld-strncmp-sse4_2.os: + 0000000000000000 T __strncmp_sse42 + + Introduced in: + + commit 11ffcacb64a939c10cfc713746b8ec88837f5c4a + Author: H.J. Lu + Date: Wed Jun 21 12:10:50 2017 -0700 + + x86-64: Implement strcmp family IFUNC selectors in C + + (cherry picked from commit 96ac447d915ea5ecef3f9168cc13f4e731349a3b) + +diff --git a/sysdeps/x86_64/multiarch/strncmp-sse4_2.S b/sysdeps/x86_64/multiarch/strncmp-sse4_2.S +index 22f51a0dfd2770c9..85dc363bf9d6273d 100644 +--- a/sysdeps/x86_64/multiarch/strncmp-sse4_2.S ++++ b/sysdeps/x86_64/multiarch/strncmp-sse4_2.S +@@ -16,6 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#define STRCMP_SSE42 __strncmp_sse42 +-#define USE_AS_STRNCMP +-#include "strcmp-sse42.S" ++#if IS_IN (libc) ++# define STRCMP_SSE42 __strncmp_sse42 ++# define USE_AS_STRNCMP ++# include "strcmp-sse42.S" ++#endif diff --git a/SOURCES/glibc-upstream-2.34-301.patch b/SOURCES/glibc-upstream-2.34-301.patch new file mode 100644 index 0000000..4d8b2fb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-301.patch @@ -0,0 +1,28 @@ +commit b991af50632a2da262b00b2375d9120f23b25525 +Author: Joseph Myers +Date: Wed May 25 14:37:28 2022 +0000 + + Update syscall-names.list for Linux 5.18 + + Linux 5.18 has no new syscalls. Update the version number in + syscall-names.list to reflect that it is still current for 5.18. + + Tested with build-many-glibcs.py. + + (cherry picked from commit 3d9926663cba19f40d26d8a8ab3b2a7cc09ffb13) + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index e2743c649586d97a..95370e2ec5dbc4a7 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.17. +-kernel 5.17 ++# The list of system calls is current as of Linux 5.18. ++kernel 5.18 + + FAST_atomic_update + FAST_cmpxchg diff --git a/SOURCES/glibc-upstream-2.34-302.patch b/SOURCES/glibc-upstream-2.34-302.patch new file mode 100644 index 0000000..3c37bca --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-302.patch @@ -0,0 +1,44 @@ +commit b2f32e746492615a6eb3e66fac1e766e32e8deb1 +Author: Florian Weimer +Date: Thu Jul 21 12:12:08 2022 +0200 + + malloc: Simplify implementation of __malloc_assert + + It is prudent not to run too much code after detecting heap + corruption, and __fxprintf is really complex. The line number + and file name do not carry much information, so it is not included + in the error message. (__libc_message only supports %s formatting.) + The function name and assertion should provide some context. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit ac8047cdf326504f652f7db97ec96c0e0cee052f) + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 7882c70f0a0312d1..d31e985ecce968fe 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -294,19 +294,14 @@ + # define __assert_fail(assertion, file, line, function) \ + __malloc_assert(assertion, file, line, function) + +-extern const char *__progname; +- +-static void ++_Noreturn static void + __malloc_assert (const char *assertion, const char *file, unsigned int line, + const char *function) + { +- (void) __fxprintf (NULL, "%s%s%s:%u: %s%sAssertion `%s' failed.\n", +- __progname, __progname[0] ? ": " : "", +- file, line, +- function ? function : "", function ? ": " : "", +- assertion); +- fflush (stderr); +- abort (); ++ __libc_message (do_abort, "\ ++Fatal glibc error: malloc assertion failure in %s: %s\n", ++ function, assertion); ++ __builtin_unreachable (); + } + #endif + #endif diff --git a/SOURCES/glibc-upstream-2.34-303.patch b/SOURCES/glibc-upstream-2.34-303.patch new file mode 100644 index 0000000..d7c929f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-303.patch @@ -0,0 +1,24 @@ +commit 875b2414cd68df64aeead651a9b05ae9bc3d88ef +Author: Florian Weimer +Date: Thu Aug 4 17:54:48 2022 +0200 + + dlfcn: Pass caller pointer to static dlopen implementation (bug 29446) + + Fixes commit 0c1c3a771eceec46e66ce1183cf988e2303bd373 ("dlfcn: Move + dlopen into libc"). + + (cherry picked from commit ed0185e4129130cbe081c221efb758fb400623ce) + +diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c +index 9c59c751c4eaf7a7..739d17baafe928cc 100644 +--- a/dlfcn/dlopen.c ++++ b/dlfcn/dlopen.c +@@ -90,7 +90,7 @@ compat_symbol (libdl, ___dlopen, dlopen, GLIBC_2_1); + void * + __dlopen (const char *file, int mode, void *dl_caller) + { +- return dlopen_implementation (file, mode, RETURN_ADDRESS (0)); ++ return dlopen_implementation (file, mode, dl_caller); + } + + void * diff --git a/SOURCES/glibc-upstream-2.34-304.patch b/SOURCES/glibc-upstream-2.34-304.patch new file mode 100644 index 0000000..f67a835 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-304.patch @@ -0,0 +1,54 @@ +commit 4ab59ce4e5195f98b01748127248fed2b2b77b21 +Author: Joseph Myers +Date: Tue Aug 2 21:05:07 2022 +0000 + + Update syscall lists for Linux 5.19 + + Linux 5.19 has no new syscalls, but enables memfd_secret in the uapi + headers for RISC-V. Update the version number in syscall-names.list + to reflect that it is still current for 5.19 and regenerate the + arch-syscall.h headers with build-many-glibcs.py update-syscalls. + + Tested with build-many-glibcs.py. + + (cherry picked from commit fccadcdf5bed7ee67a6cef4714e0b477d6c8472c) + +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index bf4be80f8d380963..202520ee254ec02f 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -122,6 +122,7 @@ + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 ++#define __NR_memfd_secret 447 + #define __NR_migrate_pages 238 + #define __NR_mincore 232 + #define __NR_mkdirat 34 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index d656aedcc2be6009..4e65f337d486de1f 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -127,6 +127,7 @@ + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 ++#define __NR_memfd_secret 447 + #define __NR_migrate_pages 238 + #define __NR_mincore 232 + #define __NR_mkdirat 34 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 95370e2ec5dbc4a7..9b285d898db9ab9e 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.18. +-kernel 5.18 ++# The list of system calls is current as of Linux 5.19. ++kernel 5.19 + + FAST_atomic_update + FAST_cmpxchg diff --git a/SOURCES/glibc-upstream-2.34-305.patch b/SOURCES/glibc-upstream-2.34-305.patch new file mode 100644 index 0000000..8a70f75 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-305.patch @@ -0,0 +1,85 @@ +commit a88f07f71f051021339682328103a8c75559fc5f +Author: Noah Goldstein +Date: Wed Jun 22 08:24:21 2022 -0700 + + stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265] + + mbstows is defined if dst is NULL and is defined to special cased if + dst is NULL so the fortify objsize check if incorrect in that case. + + Tested on x86-64 linux. + Reviewed-by: Siddhesh Poyarekar + + (cherry picked from commit 464d189b9622932a75302290625de84931656ec0) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index a4ac30d1f6359561..e13f1ee33c410ae6 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -217,6 +217,9 @@ CFLAGS-tst-qsort.c += $(stack-align-test-flags) + CFLAGS-tst-makecontext.c += -funwind-tables + CFLAGS-tst-makecontext2.c += $(stack-align-test-flags) + ++CFLAGS-testmb.c += -D_FORTIFY_SOURCE=2 -Wall -Werror ++ ++ + # Run a test on the header files we use. + tests-special += $(objpfx)isomac.out + +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index ccacbdf76a08225a..f0918d5d798a6ac4 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -96,6 +96,11 @@ extern size_t __mbstowcs_chk (wchar_t *__restrict __dst, + const char *__restrict __src, + size_t __len, size_t __dstlen) __THROW + __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2)); ++extern size_t __REDIRECT_NTH (__mbstowcs_chk_nulldst, ++ (wchar_t *__restrict __dst, ++ const char *__restrict __src, ++ size_t __len), mbstowcs_chk) ++ __attr_access ((__read_only__, 2)); + extern size_t __REDIRECT_NTH (__mbstowcs_alias, + (wchar_t *__restrict __dst, + const char *__restrict __src, +@@ -108,16 +113,17 @@ extern size_t __REDIRECT_NTH (__mbstowcs_chk_warn, + __warnattr ("mbstowcs called with dst buffer smaller than len " + "* sizeof (wchar_t)"); + +-__fortify_function size_t ++__always_inline __fortify_function size_t + __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src, + size_t __len)) + { +- return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t), +- __glibc_objsize (__dst), +- __dst, __src, __len); ++ if (__builtin_constant_p (__dst == NULL) && __dst == NULL) ++ return __mbstowcs_chk_nulldst (__dst, __src, __len); ++ else ++ return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t), ++ __glibc_objsize (__dst), __dst, __src, __len); + } + +- + extern size_t __wcstombs_chk (char *__restrict __dst, + const wchar_t *__restrict __src, + size_t __len, size_t __dstlen) __THROW +diff --git a/stdlib/testmb.c b/stdlib/testmb.c +index 45dae7db61fb3e7b..6ac4dfd21d2d33b8 100644 +--- a/stdlib/testmb.c ++++ b/stdlib/testmb.c +@@ -16,6 +16,13 @@ main (int argc, char *argv[]) + lose = 1; + } + ++ i = mbstowcs (NULL, "bar", 4); ++ if (!(i == 3 && w[1] == 'a')) ++ { ++ puts ("mbstowcs FAILED2!"); ++ lose = 1; ++ } ++ + mbstowcs (w, "blah", 5); + i = wcstombs (c, w, 10); + if (i != 4) diff --git a/SOURCES/glibc-upstream-2.34-306.patch b/SOURCES/glibc-upstream-2.34-306.patch new file mode 100644 index 0000000..b031a56 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-306.patch @@ -0,0 +1,54 @@ +commit 4bc889c01ce68475ce36f9c67b9a445a6c0218d9 +Author: Noah Goldstein +Date: Wed Jun 22 16:34:42 2022 -0700 + + stdlib: Fixup mbstowcs NULL __dst handling. [BZ #29279] + + commit 464d189b9622932a75302290625de84931656ec0 (origin/master, origin/HEAD) + Author: Noah Goldstein + Date: Wed Jun 22 08:24:21 2022 -0700 + + stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265] + + Incorrectly called `__mbstowcs_chk` in the NULL __dst case which is + incorrect as in the NULL __dst case we are explicitly skipping + the objsize checks. + + As well, remove the `__always_inline` attribute which exists in + `__fortify_function`. + Reviewed-by: Siddhesh Poyarekar + + (cherry picked from commit 220b83d83d32aa9e6f5659e2fa2a63a0024c3e4a) + +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index f0918d5d798a6ac4..ac9badc81f3990c5 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -96,10 +96,10 @@ extern size_t __mbstowcs_chk (wchar_t *__restrict __dst, + const char *__restrict __src, + size_t __len, size_t __dstlen) __THROW + __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2)); +-extern size_t __REDIRECT_NTH (__mbstowcs_chk_nulldst, ++extern size_t __REDIRECT_NTH (__mbstowcs_nulldst, + (wchar_t *__restrict __dst, + const char *__restrict __src, +- size_t __len), mbstowcs_chk) ++ size_t __len), mbstowcs) + __attr_access ((__read_only__, 2)); + extern size_t __REDIRECT_NTH (__mbstowcs_alias, + (wchar_t *__restrict __dst, +@@ -113,12 +113,12 @@ extern size_t __REDIRECT_NTH (__mbstowcs_chk_warn, + __warnattr ("mbstowcs called with dst buffer smaller than len " + "* sizeof (wchar_t)"); + +-__always_inline __fortify_function size_t ++__fortify_function size_t + __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src, + size_t __len)) + { + if (__builtin_constant_p (__dst == NULL) && __dst == NULL) +- return __mbstowcs_chk_nulldst (__dst, __src, __len); ++ return __mbstowcs_nulldst (__dst, __src, __len); + else + return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t), + __glibc_objsize (__dst), __dst, __src, __len); diff --git a/SOURCES/glibc-upstream-2.34-307.patch b/SOURCES/glibc-upstream-2.34-307.patch new file mode 100644 index 0000000..8e5493b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-307.patch @@ -0,0 +1,30 @@ +commit 1fcc7bfee22a07064508b6729cdaa6289851a2b4 +Author: Florian Weimer +Date: Mon Aug 22 11:04:47 2022 +0200 + + alpha: Fix generic brk system call emulation in __brk_call (bug 29490) + + The kernel special-cases the zero argument for alpha brk, and we can + use that to restore the generic Linux error handling behavior. + + Fixes commit b57ab258c1140bc45464b4b9908713e3e0ee35aa ("Linux: + Introduce __brk_call for invoking the brk system call"). + + (cherry picked from commit e7ad26ee3cb74e61d0637c888f24dd478d77af58) + +diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h b/sysdeps/unix/sysv/linux/alpha/brk_call.h +index b8088cf13f938c88..0b851b6c8664e8d5 100644 +--- a/sysdeps/unix/sysv/linux/alpha/brk_call.h ++++ b/sysdeps/unix/sysv/linux/alpha/brk_call.h +@@ -21,8 +21,7 @@ __brk_call (void *addr) + { + unsigned long int result = INTERNAL_SYSCALL_CALL (brk, addr); + if (result == -ENOMEM) +- /* Mimic the default error reporting behavior. */ +- return addr; +- else +- return (void *) result; ++ /* Mimic the generic error reporting behavior. */ ++ result = INTERNAL_SYSCALL_CALL (brk, 0); ++ return (void *) result; + } diff --git a/SOURCES/glibc-upstream-2.34-308.patch b/SOURCES/glibc-upstream-2.34-308.patch new file mode 100644 index 0000000..4726bf0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-308.patch @@ -0,0 +1,435 @@ +commit 68507377f249d165f1f35502d96e9365edb07d9a +Author: Arjun Shankar +Date: Tue Aug 2 11:10:25 2022 +0200 + + socket: Check lengths before advancing pointer in CMSG_NXTHDR + + The inline and library functions that the CMSG_NXTHDR macro may expand + to increment the pointer to the header before checking the stride of + the increment against available space. Since C only allows incrementing + pointers to one past the end of an array, the increment must be done + after a length check. This commit fixes that and includes a regression + test for CMSG_FIRSTHDR and CMSG_NXTHDR. + + The Linux, Hurd, and generic headers are all changed. + + Tested on Linux on armv7hl, i686, x86_64, aarch64, ppc64le, and s390x. + + [BZ #28846] + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 9c443ac4559a47ed99859bd80d14dc4b6dd220a1) + +diff --git a/bits/socket.h b/bits/socket.h +index 05ac0249c7da7218..781b1b2d1e0632a8 100644 +--- a/bits/socket.h ++++ b/bits/socket.h +@@ -245,6 +245,12 @@ struct cmsghdr + + CMSG_ALIGN (sizeof (struct cmsghdr))) + #define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) + ++/* Given a length, return the additional padding necessary such that ++ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */ ++#define __CMSG_PADDING(len) ((sizeof (size_t) \ ++ - ((len) & (sizeof (size_t) - 1))) \ ++ & (sizeof (size_t) - 1)) ++ + extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, + struct cmsghdr *__cmsg) __THROW; + #ifdef __USE_EXTERN_INLINES +@@ -254,18 +260,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, + _EXTERN_INLINE struct cmsghdr * + __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) + { ++ /* We may safely assume that __cmsg lies between __mhdr->msg_control and ++ __mhdr->msg_controllen because the user is required to obtain the first ++ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs ++ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet ++ trust the value of __cmsg->cmsg_len and therefore do not use it in any ++ pointer arithmetic until we check its value. */ ++ ++ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control; ++ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg; ++ ++ size_t __size_needed = sizeof (struct cmsghdr) ++ + __CMSG_PADDING (__cmsg->cmsg_len); ++ ++ /* The current header is malformed, too small to be a full header. */ + if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) +- /* The kernel header does this so there may be a reason. */ + return (struct cmsghdr *) 0; + ++ /* There isn't enough space between __cmsg and the end of the buffer to ++ hold the current cmsg *and* the next one. */ ++ if (((size_t) ++ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr) ++ < __size_needed) ++ || ((size_t) ++ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr ++ - __size_needed) ++ < __cmsg->cmsg_len)) ++ ++ return (struct cmsghdr *) 0; ++ ++ /* Now, we trust cmsg_len and can use it to find the next header. */ + __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg + + CMSG_ALIGN (__cmsg->cmsg_len)); +- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control +- + __mhdr->msg_controllen) +- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) +- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen))) +- /* No more entries. */ +- return (struct cmsghdr *) 0; + return __cmsg; + } + #endif /* Use `extern inline'. */ +diff --git a/socket/Makefile b/socket/Makefile +index c2de11d73ca1e324..2fdf441bb44bf142 100644 +--- a/socket/Makefile ++++ b/socket/Makefile +@@ -34,6 +34,7 @@ routines := accept bind connect getpeername getsockname getsockopt \ + tests := \ + tst-accept4 \ + tst-sockopt \ ++ tst-cmsghdr \ + # tests + + tests-internal := \ +diff --git a/socket/tst-cmsghdr-skeleton.c b/socket/tst-cmsghdr-skeleton.c +new file mode 100644 +index 0000000000000000..7accfa6e54708e2a +--- /dev/null ++++ b/socket/tst-cmsghdr-skeleton.c +@@ -0,0 +1,93 @@ ++/* Test ancillary data header creation. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* We use the preprocessor to generate the function/macro tests instead of ++ using indirection because having all the macro expansions alongside ++ each other lets the compiler warn us about suspicious pointer ++ arithmetic across subsequent CMSG_{FIRST,NXT}HDR expansions. */ ++ ++#include ++#include ++ ++#define RUN_TEST_CONCAT(suffix) run_test_##suffix ++#define RUN_TEST_FUNCNAME(suffix) RUN_TEST_CONCAT (suffix) ++ ++static void ++RUN_TEST_FUNCNAME (CMSG_NXTHDR_IMPL) (void) ++{ ++ struct msghdr m = {0}; ++ struct cmsghdr *cmsg; ++ char cmsgbuf[3 * CMSG_SPACE (sizeof (PAYLOAD))] = {0}; ++ ++ m.msg_control = cmsgbuf; ++ m.msg_controllen = sizeof (cmsgbuf); ++ ++ /* First header should point to the start of the buffer. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ ++ /* If the first header length consumes the entire buffer, there is no ++ space remaining for additional headers. */ ++ cmsg->cmsg_len = sizeof (cmsgbuf); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg == NULL); ++ ++ /* The first header length is so big, using it would cause an overflow. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg->cmsg_len = SIZE_MAX; ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg == NULL); ++ ++ /* The first header leaves just enough space to hold another header. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg->cmsg_len = sizeof (cmsgbuf) - sizeof (struct cmsghdr); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg != NULL); ++ ++ /* The first header leaves space but not enough for another header. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg->cmsg_len ++; ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg == NULL); ++ ++ /* The second header leaves just enough space to hold another header. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg->cmsg_len = CMSG_LEN (sizeof (PAYLOAD)); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg != NULL); ++ cmsg->cmsg_len = sizeof (cmsgbuf) ++ - CMSG_SPACE (sizeof (PAYLOAD)) /* First header. */ ++ - sizeof (struct cmsghdr); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg != NULL); ++ ++ /* The second header leaves space but not enough for another header. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg != NULL); ++ cmsg->cmsg_len ++; ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg == NULL); ++ ++ return; ++} +diff --git a/socket/tst-cmsghdr.c b/socket/tst-cmsghdr.c +new file mode 100644 +index 0000000000000000..68c96d3c9dd2bce8 +--- /dev/null ++++ b/socket/tst-cmsghdr.c +@@ -0,0 +1,56 @@ ++/* Test ancillary data header creation. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#define PAYLOAD "Hello, World!" ++ ++/* CMSG_NXTHDR is a macro that calls an inline function defined in ++ bits/socket.h. In case the function cannot be inlined, libc.so carries ++ a copy. Both versions need to be tested. */ ++ ++#define CMSG_NXTHDR_IMPL CMSG_NXTHDR ++#include "tst-cmsghdr-skeleton.c" ++#undef CMSG_NXTHDR_IMPL ++ ++static struct cmsghdr * (* cmsg_nxthdr) (struct msghdr *, struct cmsghdr *); ++ ++#define CMSG_NXTHDR_IMPL cmsg_nxthdr ++#include "tst-cmsghdr-skeleton.c" ++#undef CMSG_NXTHDR_IMPL ++ ++static int ++do_test (void) ++{ ++ static void *handle; ++ ++ run_test_CMSG_NXTHDR (); ++ ++ handle = xdlopen (LIBC_SO, RTLD_LAZY); ++ cmsg_nxthdr = (struct cmsghdr * (*) (struct msghdr *, struct cmsghdr *)) ++ xdlsym (handle, "__cmsg_nxthdr"); ++ ++ run_test_cmsg_nxthdr (); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h +index 5210a7b44950e957..423eb2df09c3eef9 100644 +--- a/sysdeps/mach/hurd/bits/socket.h ++++ b/sysdeps/mach/hurd/bits/socket.h +@@ -249,6 +249,12 @@ struct cmsghdr + + CMSG_ALIGN (sizeof (struct cmsghdr))) + #define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) + ++/* Given a length, return the additional padding necessary such that ++ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */ ++#define __CMSG_PADDING(len) ((sizeof (size_t) \ ++ - ((len) & (sizeof (size_t) - 1))) \ ++ & (sizeof (size_t) - 1)) ++ + extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, + struct cmsghdr *__cmsg) __THROW; + #ifdef __USE_EXTERN_INLINES +@@ -258,18 +264,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, + _EXTERN_INLINE struct cmsghdr * + __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) + { ++ /* We may safely assume that __cmsg lies between __mhdr->msg_control and ++ __mhdr->msg_controllen because the user is required to obtain the first ++ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs ++ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet ++ trust the value of __cmsg->cmsg_len and therefore do not use it in any ++ pointer arithmetic until we check its value. */ ++ ++ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control; ++ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg; ++ ++ size_t __size_needed = sizeof (struct cmsghdr) ++ + __CMSG_PADDING (__cmsg->cmsg_len); ++ ++ /* The current header is malformed, too small to be a full header. */ + if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) +- /* The kernel header does this so there may be a reason. */ + return (struct cmsghdr *) 0; + ++ /* There isn't enough space between __cmsg and the end of the buffer to ++ hold the current cmsg *and* the next one. */ ++ if (((size_t) ++ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr) ++ < __size_needed) ++ || ((size_t) ++ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr ++ - __size_needed) ++ < __cmsg->cmsg_len)) ++ ++ return (struct cmsghdr *) 0; ++ ++ /* Now, we trust cmsg_len and can use it to find the next header. */ + __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg + + CMSG_ALIGN (__cmsg->cmsg_len)); +- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control +- + __mhdr->msg_controllen) +- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) +- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen))) +- /* No more entries. */ +- return (struct cmsghdr *) 0; + return __cmsg; + } + #endif /* Use `extern inline'. */ +diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h +index c81fab840918924e..7d56f877e0a73acb 100644 +--- a/sysdeps/unix/sysv/linux/bits/socket.h ++++ b/sysdeps/unix/sysv/linux/bits/socket.h +@@ -306,6 +306,12 @@ struct cmsghdr + + CMSG_ALIGN (sizeof (struct cmsghdr))) + #define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) + ++/* Given a length, return the additional padding necessary such that ++ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */ ++#define __CMSG_PADDING(len) ((sizeof (size_t) \ ++ - ((len) & (sizeof (size_t) - 1))) \ ++ & (sizeof (size_t) - 1)) ++ + extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, + struct cmsghdr *__cmsg) __THROW; + #ifdef __USE_EXTERN_INLINES +@@ -315,18 +321,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, + _EXTERN_INLINE struct cmsghdr * + __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) + { ++ /* We may safely assume that __cmsg lies between __mhdr->msg_control and ++ __mhdr->msg_controllen because the user is required to obtain the first ++ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs ++ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet ++ trust the value of __cmsg->cmsg_len and therefore do not use it in any ++ pointer arithmetic until we check its value. */ ++ ++ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control; ++ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg; ++ ++ size_t __size_needed = sizeof (struct cmsghdr) ++ + __CMSG_PADDING (__cmsg->cmsg_len); ++ ++ /* The current header is malformed, too small to be a full header. */ + if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) +- /* The kernel header does this so there may be a reason. */ + return (struct cmsghdr *) 0; + ++ /* There isn't enough space between __cmsg and the end of the buffer to ++ hold the current cmsg *and* the next one. */ ++ if (((size_t) ++ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr) ++ < __size_needed) ++ || ((size_t) ++ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr ++ - __size_needed) ++ < __cmsg->cmsg_len)) ++ ++ return (struct cmsghdr *) 0; ++ ++ /* Now, we trust cmsg_len and can use it to find the next header. */ + __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg + + CMSG_ALIGN (__cmsg->cmsg_len)); +- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control +- + __mhdr->msg_controllen) +- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) +- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen))) +- /* No more entries. */ +- return (struct cmsghdr *) 0; + return __cmsg; + } + #endif /* Use `extern inline'. */ +diff --git a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c b/sysdeps/unix/sysv/linux/cmsg_nxthdr.c +index a0fe49f28563d030..535d22e9a037b9a9 100644 +--- a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c ++++ b/sysdeps/unix/sysv/linux/cmsg_nxthdr.c +@@ -23,18 +23,38 @@ + struct cmsghdr * + __cmsg_nxthdr (struct msghdr *mhdr, struct cmsghdr *cmsg) + { ++ /* We may safely assume that cmsg lies between mhdr->msg_control and ++ mhdr->msg_controllen because the user is required to obtain the first ++ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs ++ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet ++ trust the value of cmsg->cmsg_len and therefore do not use it in any ++ pointer arithmetic until we check its value. */ ++ ++ unsigned char * msg_control_ptr = (unsigned char *) mhdr->msg_control; ++ unsigned char * cmsg_ptr = (unsigned char *) cmsg; ++ ++ size_t size_needed = sizeof (struct cmsghdr) ++ + __CMSG_PADDING (cmsg->cmsg_len); ++ ++ /* The current header is malformed, too small to be a full header. */ + if ((size_t) cmsg->cmsg_len < sizeof (struct cmsghdr)) +- /* The kernel header does this so there may be a reason. */ +- return NULL; ++ return (struct cmsghdr *) 0; ++ ++ /* There isn't enough space between cmsg and the end of the buffer to ++ hold the current cmsg *and* the next one. */ ++ if (((size_t) ++ (msg_control_ptr + mhdr->msg_controllen - cmsg_ptr) ++ < size_needed) ++ || ((size_t) ++ (msg_control_ptr + mhdr->msg_controllen - cmsg_ptr ++ - size_needed) ++ < cmsg->cmsg_len)) ++ ++ return (struct cmsghdr *) 0; + ++ /* Now, we trust cmsg_len and can use it to find the next header. */ + cmsg = (struct cmsghdr *) ((unsigned char *) cmsg + + CMSG_ALIGN (cmsg->cmsg_len)); +- if ((unsigned char *) (cmsg + 1) > ((unsigned char *) mhdr->msg_control +- + mhdr->msg_controllen) +- || ((unsigned char *) cmsg + CMSG_ALIGN (cmsg->cmsg_len) +- > ((unsigned char *) mhdr->msg_control + mhdr->msg_controllen))) +- /* No more entries. */ +- return NULL; + return cmsg; + } + libc_hidden_def (__cmsg_nxthdr) diff --git a/SOURCES/glibc-upstream-2.34-309.patch b/SOURCES/glibc-upstream-2.34-309.patch new file mode 100644 index 0000000..1c34dc0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-309.patch @@ -0,0 +1,212 @@ +commit 536ddc5c02f1ee82483319863a893ccb381beece +Author: Florian Weimer +Date: Fri Aug 26 21:15:43 2022 +0200 + + elf: Call __libc_early_init for reused namespaces (bug 29528) + + libc_map is never reset to NULL, neither during dlclose nor on a + dlopen call which reuses the namespace structure. As a result, if a + namespace is reused, its libc is not initialized properly. The most + visible result is a crash in the functions. + + To prevent similar bugs on namespace reuse from surfacing, + unconditionally initialize the chosen namespace to zero using memset. + + (cherry picked from commit d0e357ff45a75553dee3b17ed7d303bfa544f6fe) + +Conflicts: + elf/Makefile + (usual test differences) + +diff --git a/elf/Makefile b/elf/Makefile +index 2b547d5b58f1759b..feec365e4e5fe9b3 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -399,6 +399,7 @@ tests += \ + tst-dlmopen3 \ + tst-dlmopen-dlerror \ + tst-dlmopen-gethostbyname \ ++ tst-dlmopen-twice \ + tst-dlopenfail \ + tst-dlopenfail-2 \ + tst-dlopenrpath \ +@@ -744,6 +745,8 @@ modules-names = \ + tst-dlmopen1mod \ + tst-dlmopen-dlerror-mod \ + tst-dlmopen-gethostbyname-mod \ ++ tst-dlmopen-twice-mod1 \ ++ tst-dlmopen-twice-mod2 \ + tst-dlopenfaillinkmod \ + tst-dlopenfailmod1 \ + tst-dlopenfailmod2 \ +@@ -2665,3 +2668,7 @@ $(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so + tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so + $(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so + tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so ++ ++$(objpfx)tst-dlmopen-twice.out: \ ++ $(objpfx)tst-dlmopen-twice-mod1.so \ ++ $(objpfx)tst-dlmopen-twice-mod2.so +diff --git a/elf/dl-open.c b/elf/dl-open.c +index bc6872632880634e..1ab3c7b5ac2fbc45 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -839,11 +839,14 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, + _dl_signal_error (EINVAL, file, NULL, N_("\ + no more namespaces available for dlmopen()")); + } +- else if (nsid == GL(dl_nns)) +- { +- __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock); +- ++GL(dl_nns); +- } ++ ++ if (nsid == GL(dl_nns)) ++ ++GL(dl_nns); ++ ++ /* Initialize the new namespace. Most members are ++ zero-initialized, only the lock needs special treatment. */ ++ memset (&GL(dl_ns)[nsid], 0, sizeof (GL(dl_ns)[nsid])); ++ __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock); + + _dl_debug_initialize (0, nsid)->r_state = RT_CONSISTENT; + } +diff --git a/elf/tst-dlmopen-twice-mod1.c b/elf/tst-dlmopen-twice-mod1.c +new file mode 100644 +index 0000000000000000..0eaf04948ce5263e +--- /dev/null ++++ b/elf/tst-dlmopen-twice-mod1.c +@@ -0,0 +1,37 @@ ++/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528). Module 1. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ puts ("info: tst-dlmopen-twice-mod1.so loaded"); ++ fflush (stdout); ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ puts ("info: tst-dlmopen-twice-mod1.so about to be unloaded"); ++ fflush (stdout); ++} ++ ++/* Large allocation. The second module does not have this, so it ++ should load libc at a different address. */ ++char large_allocate[16 * 1024 * 1024]; +diff --git a/elf/tst-dlmopen-twice-mod2.c b/elf/tst-dlmopen-twice-mod2.c +new file mode 100644 +index 0000000000000000..40c6c01f9625e188 +--- /dev/null ++++ b/elf/tst-dlmopen-twice-mod2.c +@@ -0,0 +1,50 @@ ++/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528). Module 2. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ puts ("info: tst-dlmopen-twice-mod2.so loaded"); ++ fflush (stdout); ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ puts ("info: tst-dlmopen-twice-mod2.so about to be unloaded"); ++ fflush (stdout); ++} ++ ++int ++run_check (void) ++{ ++ puts ("info: about to call isalpha"); ++ fflush (stdout); ++ ++ volatile char ch = 'a'; ++ if (!isalpha (ch)) ++ { ++ puts ("error: isalpha ('a') is not true"); ++ fflush (stdout); ++ return 1; ++ } ++ return 0; ++} +diff --git a/elf/tst-dlmopen-twice.c b/elf/tst-dlmopen-twice.c +new file mode 100644 +index 0000000000000000..449f3c8fa9f2aa01 +--- /dev/null ++++ b/elf/tst-dlmopen-twice.c +@@ -0,0 +1,34 @@ ++/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528). Main. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", RTLD_NOW); ++ xdlclose (handle); ++ handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod2.so", RTLD_NOW); ++ int (*run_check) (void) = xdlsym (handle, "run_check"); ++ TEST_COMPARE (run_check (), 0); ++ xdlclose (handle); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-31.patch b/SOURCES/glibc-upstream-2.34-31.patch new file mode 100644 index 0000000..cb04843 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-31.patch @@ -0,0 +1,201 @@ +commit 822662cf2a4b170ade4c5342f035d68815a03276 +Author: Adhemerval Zanella +Date: Mon Sep 6 14:19:51 2021 -0300 + + linux: Revert the use of sched_getaffinity on get_nproc (BZ #28310) + + The use of sched_getaffinity on get_nproc and + sysconf (_SC_NPROCESSORS_ONLN) done in 903bc7dcc2acafc40 (BZ #27645) + breaks the top command in common hypervisor configurations and also + other monitoring tools. + + The main issue using sched_getaffinity changed the symbols semantic + from system-wide scope of online CPUs to per-process one (which can + be changed with kernel cpusets or book parameters in VM). + + This patch reverts mostly of the 903bc7dcc2acafc40, with the + exceptions: + + * No more cached values and atomic updates, since they are inherent + racy. + + * No /proc/cpuinfo fallback, since /proc/stat is already used and + it would require to revert more arch-specific code. + + * The alloca is replace with a static buffer of 1024 bytes. + + So the implementation first consult the sysfs, and fallbacks to procfs. + + Checked on x86_64-linux-gnu. + + Reviewed-by: Florian Weimer + (cherry picked from commit 342298278eabc75baabcaced110a11a02c3d3580) + +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index 61d20e7bab8640f2..d70ed9586950615c 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -18,6 +18,8 @@ + . */ + + #include ++#include ++#include + #include + #include + #include +@@ -30,7 +32,7 @@ + #include + + int +-__get_nprocs (void) ++__get_nprocs_sched (void) + { + enum + { +@@ -53,14 +55,141 @@ __get_nprocs (void) + atomics are needed). */ + return 2; + } +-libc_hidden_def (__get_nprocs) +-weak_alias (__get_nprocs, get_nprocs) ++ ++static char * ++next_line (int fd, char *const buffer, char **cp, char **re, ++ char *const buffer_end) ++{ ++ char *res = *cp; ++ char *nl = memchr (*cp, '\n', *re - *cp); ++ if (nl == NULL) ++ { ++ if (*cp != buffer) ++ { ++ if (*re == buffer_end) ++ { ++ memmove (buffer, *cp, *re - *cp); ++ *re = buffer + (*re - *cp); ++ *cp = buffer; ++ ++ ssize_t n = __read_nocancel (fd, *re, buffer_end - *re); ++ if (n < 0) ++ return NULL; ++ ++ *re += n; ++ ++ nl = memchr (*cp, '\n', *re - *cp); ++ while (nl == NULL && *re == buffer_end) ++ { ++ /* Truncate too long lines. */ ++ *re = buffer + 3 * (buffer_end - buffer) / 4; ++ n = __read_nocancel (fd, *re, buffer_end - *re); ++ if (n < 0) ++ return NULL; ++ ++ nl = memchr (*re, '\n', n); ++ **re = '\n'; ++ *re += n; ++ } ++ } ++ else ++ nl = memchr (*cp, '\n', *re - *cp); ++ ++ res = *cp; ++ } ++ ++ if (nl == NULL) ++ nl = *re - 1; ++ } ++ ++ *cp = nl + 1; ++ assert (*cp <= *re); ++ ++ return res == *re ? NULL : res; ++} ++ + + int +-__get_nprocs_sched (void) ++__get_nprocs (void) + { +- return __get_nprocs (); ++ enum { buffer_size = 1024 }; ++ char buffer[buffer_size]; ++ char *buffer_end = buffer + buffer_size; ++ char *cp = buffer_end; ++ char *re = buffer_end; ++ ++ const int flags = O_RDONLY | O_CLOEXEC; ++ /* This file contains comma-separated ranges. */ ++ int fd = __open_nocancel ("/sys/devices/system/cpu/online", flags); ++ char *l; ++ int result = 0; ++ if (fd != -1) ++ { ++ l = next_line (fd, buffer, &cp, &re, buffer_end); ++ if (l != NULL) ++ do ++ { ++ char *endp; ++ unsigned long int n = strtoul (l, &endp, 10); ++ if (l == endp) ++ { ++ result = 0; ++ break; ++ } ++ ++ unsigned long int m = n; ++ if (*endp == '-') ++ { ++ l = endp + 1; ++ m = strtoul (l, &endp, 10); ++ if (l == endp) ++ { ++ result = 0; ++ break; ++ } ++ } ++ ++ result += m - n + 1; ++ ++ l = endp; ++ if (l < re && *l == ',') ++ ++l; ++ } ++ while (l < re && *l != '\n'); ++ ++ __close_nocancel_nostatus (fd); ++ ++ if (result > 0) ++ return result; ++ } ++ ++ cp = buffer_end; ++ re = buffer_end; ++ ++ /* Default to an SMP system in case we cannot obtain an accurate ++ number. */ ++ result = 2; ++ ++ fd = __open_nocancel ("/proc/stat", flags); ++ if (fd != -1) ++ { ++ result = 0; ++ ++ while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL) ++ /* The current format of /proc/stat has all the cpu* entries ++ at the front. We assume here that stays this way. */ ++ if (strncmp (l, "cpu", 3) != 0) ++ break; ++ else if (isdigit (l[3])) ++ ++result; ++ ++ __close_nocancel_nostatus (fd); ++ } ++ ++ return result; + } ++libc_hidden_def (__get_nprocs) ++weak_alias (__get_nprocs, get_nprocs) + + + /* On some architectures it is possible to distinguish between configured diff --git a/SOURCES/glibc-upstream-2.34-310.patch b/SOURCES/glibc-upstream-2.34-310.patch new file mode 100644 index 0000000..7f949a0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-310.patch @@ -0,0 +1,334 @@ +commit 2a44960cbc78713c6a2721683a4319d50e71a01f +Author: Tulio Magno Quites Machado Filho +Date: Thu Jul 7 18:12:58 2022 -0300 + + Apply asm redirections in stdio.h before first use [BZ #27087] + + Compilers may not be able to apply asm redirections to functions after + these functions are used for the first time, e.g. clang 13. + Fix [BZ #27087] by applying all long double-related asm redirections + before using functions in bits/stdio.h. + However, as these asm redirections depend on the declarations provided + by libio/bits/stdio2.h, this header was split in 2: + + - libio/bits/stdio2-decl.h contains all function declarations; + - libio/bits/stdio2.h remains with the remaining contents, including + redirections. + + This also adds the access attribute to __vsnprintf_chk that was missing. + + Tested with build-many-glibcs.py. + + Reviewed-by: Paul E. Murphy + (cherry picked from commit d0fa09a7701956036ff36f8ca188e9fff81553d8) + +diff --git a/include/bits/stdio2-decl.h b/include/bits/stdio2-decl.h +new file mode 100644 +index 0000000000000000..bbb052f192218219 +--- /dev/null ++++ b/include/bits/stdio2-decl.h +@@ -0,0 +1 @@ ++#include +diff --git a/libio/Makefile b/libio/Makefile +index 5336b7d59584927f..981c876940f67fbf 100644 +--- a/libio/Makefile ++++ b/libio/Makefile +@@ -23,7 +23,7 @@ subdir := libio + include ../Makeconfig + + headers := stdio.h \ +- bits/stdio.h bits/stdio2.h bits/stdio-ldbl.h \ ++ bits/stdio.h bits/stdio2.h bits/stdio2-decl.h bits/stdio-ldbl.h \ + bits/types/FILE.h bits/types/__FILE.h bits/types/struct_FILE.h \ + bits/types/__fpos_t.h bits/types/__fpos64_t.h \ + bits/types/cookie_io_functions_t.h +diff --git a/libio/bits/stdio2-decl.h b/libio/bits/stdio2-decl.h +new file mode 100644 +index 0000000000000000..e398f7182b98e4d7 +--- /dev/null ++++ b/libio/bits/stdio2-decl.h +@@ -0,0 +1,111 @@ ++/* Checking macros for stdio functions. Declarations only. ++ Copyright (C) 2004-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _BITS_STDIO2_DEC_H ++#define _BITS_STDIO2_DEC_H 1 ++ ++#ifndef _STDIO_H ++# error "Never include directly; use instead." ++#endif ++ ++extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen, ++ const char *__restrict __format, ...) __THROW ++ __attr_access ((__write_only__, 1, 3)); ++extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen, ++ const char *__restrict __format, ++ __gnuc_va_list __ap) __THROW ++ __attr_access ((__write_only__, 1, 3)); ++ ++#if defined __USE_ISOC99 || defined __USE_UNIX98 ++ ++extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag, ++ size_t __slen, const char *__restrict __format, ++ ...) __THROW ++ __attr_access ((__write_only__, 1, 2)); ++extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag, ++ size_t __slen, const char *__restrict __format, ++ __gnuc_va_list __ap) __THROW ++ __attr_access ((__write_only__, 1, 2)); ++ ++#endif ++ ++#if __USE_FORTIFY_LEVEL > 1 ++ ++extern int __fprintf_chk (FILE *__restrict __stream, int __flag, ++ const char *__restrict __format, ...); ++extern int __printf_chk (int __flag, const char *__restrict __format, ...); ++extern int __vfprintf_chk (FILE *__restrict __stream, int __flag, ++ const char *__restrict __format, __gnuc_va_list __ap); ++extern int __vprintf_chk (int __flag, const char *__restrict __format, ++ __gnuc_va_list __ap); ++ ++# ifdef __USE_XOPEN2K8 ++extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt, ++ ...) __attribute__ ((__format__ (__printf__, 3, 4))); ++extern int __vdprintf_chk (int __fd, int __flag, ++ const char *__restrict __fmt, __gnuc_va_list __arg) ++ __attribute__ ((__format__ (__printf__, 3, 0))); ++# endif ++ ++# ifdef __USE_GNU ++ ++extern int __asprintf_chk (char **__restrict __ptr, int __flag, ++ const char *__restrict __fmt, ...) ++ __THROW __attribute__ ((__format__ (__printf__, 3, 4))) __wur; ++extern int __vasprintf_chk (char **__restrict __ptr, int __flag, ++ const char *__restrict __fmt, __gnuc_va_list __arg) ++ __THROW __attribute__ ((__format__ (__printf__, 3, 0))) __wur; ++extern int __obstack_printf_chk (struct obstack *__restrict __obstack, ++ int __flag, const char *__restrict __format, ++ ...) ++ __THROW __attribute__ ((__format__ (__printf__, 3, 4))); ++extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack, ++ int __flag, ++ const char *__restrict __format, ++ __gnuc_va_list __args) ++ __THROW __attribute__ ((__format__ (__printf__, 3, 0))); ++ ++# endif ++#endif ++ ++#if __GLIBC_USE (DEPRECATED_GETS) ++extern char *__gets_chk (char *__str, size_t) __wur; ++#endif ++ ++extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n, ++ FILE *__restrict __stream) ++ __wur __attr_access ((__write_only__, 1, 3)); ++ ++extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, ++ size_t __size, size_t __n, ++ FILE *__restrict __stream) __wur; ++ ++#ifdef __USE_GNU ++extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size, ++ int __n, FILE *__restrict __stream) ++ __wur __attr_access ((__write_only__, 1, 3)); ++#endif ++ ++#ifdef __USE_MISC ++# undef fread_unlocked ++extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen, ++ size_t __size, size_t __n, ++ FILE *__restrict __stream) __wur; ++#endif ++ ++#endif /* bits/stdio2-decl.h. */ +diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h +index 40ff16b01b4f4876..4570f86a4496c1ee 100644 +--- a/libio/bits/stdio2.h ++++ b/libio/bits/stdio2.h +@@ -23,14 +23,6 @@ + # error "Never include directly; use instead." + #endif + +-extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen, +- const char *__restrict __format, ...) __THROW +- __attr_access ((__write_only__, 1, 3)); +-extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen, +- const char *__restrict __format, +- __gnuc_va_list __ap) __THROW +- __attr_access ((__write_only__, 1, 3)); +- + #ifdef __va_arg_pack + __fortify_function int + __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...)) +@@ -54,15 +46,6 @@ __NTH (vsprintf (char *__restrict __s, const char *__restrict __fmt, + } + + #if defined __USE_ISOC99 || defined __USE_UNIX98 +- +-extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag, +- size_t __slen, const char *__restrict __format, +- ...) __THROW +- __attr_access ((__write_only__, 1, 2)); +-extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag, +- size_t __slen, const char *__restrict __format, +- __gnuc_va_list __ap) __THROW; +- + # ifdef __va_arg_pack + __fortify_function int + __NTH (snprintf (char *__restrict __s, size_t __n, +@@ -89,15 +72,6 @@ __NTH (vsnprintf (char *__restrict __s, size_t __n, + #endif + + #if __USE_FORTIFY_LEVEL > 1 +- +-extern int __fprintf_chk (FILE *__restrict __stream, int __flag, +- const char *__restrict __format, ...); +-extern int __printf_chk (int __flag, const char *__restrict __format, ...); +-extern int __vfprintf_chk (FILE *__restrict __stream, int __flag, +- const char *__restrict __format, __gnuc_va_list __ap); +-extern int __vprintf_chk (int __flag, const char *__restrict __format, +- __gnuc_va_list __ap); +- + # ifdef __va_arg_pack + __fortify_function int + fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...) +@@ -136,12 +110,6 @@ vfprintf (FILE *__restrict __stream, + } + + # ifdef __USE_XOPEN2K8 +-extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt, +- ...) __attribute__ ((__format__ (__printf__, 3, 4))); +-extern int __vdprintf_chk (int __fd, int __flag, +- const char *__restrict __fmt, __gnuc_va_list __arg) +- __attribute__ ((__format__ (__printf__, 3, 0))); +- + # ifdef __va_arg_pack + __fortify_function int + dprintf (int __fd, const char *__restrict __fmt, ...) +@@ -162,23 +130,6 @@ vdprintf (int __fd, const char *__restrict __fmt, __gnuc_va_list __ap) + # endif + + # ifdef __USE_GNU +- +-extern int __asprintf_chk (char **__restrict __ptr, int __flag, +- const char *__restrict __fmt, ...) +- __THROW __attribute__ ((__format__ (__printf__, 3, 4))) __wur; +-extern int __vasprintf_chk (char **__restrict __ptr, int __flag, +- const char *__restrict __fmt, __gnuc_va_list __arg) +- __THROW __attribute__ ((__format__ (__printf__, 3, 0))) __wur; +-extern int __obstack_printf_chk (struct obstack *__restrict __obstack, +- int __flag, const char *__restrict __format, +- ...) +- __THROW __attribute__ ((__format__ (__printf__, 3, 4))); +-extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack, +- int __flag, +- const char *__restrict __format, +- __gnuc_va_list __args) +- __THROW __attribute__ ((__format__ (__printf__, 3, 0))); +- + # ifdef __va_arg_pack + __fortify_function int + __NTH (asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...)) +@@ -231,7 +182,6 @@ __NTH (obstack_vprintf (struct obstack *__restrict __obstack, + #endif + + #if __GLIBC_USE (DEPRECATED_GETS) +-extern char *__gets_chk (char *__str, size_t) __wur; + extern char *__REDIRECT (__gets_warn, (char *__str), gets) + __wur __warnattr ("please use fgets or getline instead, gets can't " + "specify buffer size"); +@@ -245,9 +195,6 @@ gets (char *__str) + } + #endif + +-extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n, +- FILE *__restrict __stream) +- __wur __attr_access ((__write_only__, 1, 3)); + extern char *__REDIRECT (__fgets_alias, + (char *__restrict __s, int __n, + FILE *__restrict __stream), fgets) +@@ -269,9 +216,6 @@ fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + return __fgets_chk (__s, sz, __n, __stream); + } + +-extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, +- size_t __size, size_t __n, +- FILE *__restrict __stream) __wur; + extern size_t __REDIRECT (__fread_alias, + (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream), +@@ -297,9 +241,6 @@ fread (void *__restrict __ptr, size_t __size, size_t __n, + } + + #ifdef __USE_GNU +-extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size, +- int __n, FILE *__restrict __stream) +- __wur __attr_access ((__write_only__, 1, 3)); + extern char *__REDIRECT (__fgets_unlocked_alias, + (char *__restrict __s, int __n, + FILE *__restrict __stream), fgets_unlocked) +@@ -324,9 +265,6 @@ fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) + + #ifdef __USE_MISC + # undef fread_unlocked +-extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen, +- size_t __size, size_t __n, +- FILE *__restrict __stream) __wur; + extern size_t __REDIRECT (__fread_unlocked_alias, + (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream), +diff --git a/libio/stdio.h b/libio/stdio.h +index abefe640e52d18d5..d36e61c56bbb3117 100644 +--- a/libio/stdio.h ++++ b/libio/stdio.h +@@ -879,20 +879,27 @@ extern void funlockfile (FILE *__stream) __THROW; + extern int __uflow (FILE *); + extern int __overflow (FILE *, int); + ++#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function ++/* Declare all functions from bits/stdio2-decl.h first. */ ++# include ++#endif ++ ++/* The following headers provide asm redirections. These redirections must ++ appear before the first usage of these functions, e.g. in bits/stdio.h. */ ++#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 ++# include ++#endif ++ + /* If we are compiling with optimizing read this file. It contains + several optimizing inline functions and macros. */ + #ifdef __USE_EXTERN_INLINES + # include + #endif + #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function ++/* Now include the function definitions and redirects too. */ + # include + #endif + +-#include +-#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 +-# include +-#endif +- + __END_DECLS + + #endif /* included. */ diff --git a/SOURCES/glibc-upstream-2.34-311.patch b/SOURCES/glibc-upstream-2.34-311.patch new file mode 100644 index 0000000..2307c0c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-311.patch @@ -0,0 +1,414 @@ +commit b41c535f46e7e7bbd8ff2ac68b94c2348e2f66e4 +Author: Raphael Moreira Zinsly +Date: Wed Aug 24 11:43:37 2022 -0300 + + Apply asm redirections in wchar.h before first use + + Similar to d0fa09a770, but for wchar.h. Fixes [BZ #27087] by applying + all long double related asm redirections before using functions in + bits/wchar2.h. + Moves the function declarations from wcsmbs/bits/wchar2.h to a new file + wcsmbs/bits/wchar2-decl.h that will be included first in wcsmbs/wchar.h. + + Tested with build-many-glibcs.py. + Reviewed-by: Adhemerval Zanella + + (cherry picked from commit c7509d49c4e8fa494120c5ead21338559dad16f5) + +diff --git a/include/bits/wchar2-decl.h b/include/bits/wchar2-decl.h +new file mode 100644 +index 0000000000000000..00b1b93342ef28ff +--- /dev/null ++++ b/include/bits/wchar2-decl.h +@@ -0,0 +1 @@ ++#include +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index f38eb5cfe16fd3d7..5fe755e65df6c621 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -22,8 +22,9 @@ subdir := wcsmbs + + include ../Makeconfig + +-headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h \ +- bits/types/__mbstate_t.h bits/types/mbstate_t.h bits/types/wint_t.h ++headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar2-decl.h \ ++ bits/wchar-ldbl.h uchar.h bits/types/__mbstate_t.h \ ++ bits/types/mbstate_t.h bits/types/wint_t.h + + routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \ +diff --git a/wcsmbs/bits/wchar2-decl.h b/wcsmbs/bits/wchar2-decl.h +new file mode 100644 +index 0000000000000000..8e1735c33b7f7e78 +--- /dev/null ++++ b/wcsmbs/bits/wchar2-decl.h +@@ -0,0 +1,124 @@ ++/* Checking macros for wchar functions. Declarations only. ++ Copyright (C) 2004-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _BITS_WCHAR2_DECL_H ++#define _BITS_WCHAR2_DECL_H 1 ++ ++#ifndef _WCHAR_H ++# error "Never include directly; use instead." ++#endif ++ ++ ++extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1, ++ const wchar_t *__restrict __s2, size_t __n, ++ size_t __ns1) __THROW; ++extern wchar_t *__wmemmove_chk (wchar_t *__s1, const wchar_t *__s2, ++ size_t __n, size_t __ns1) __THROW; ++ ++ ++#ifdef __USE_GNU ++ ++extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1, ++ const wchar_t *__restrict __s2, size_t __n, ++ size_t __ns1) __THROW; ++ ++#endif ++ ++ ++extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n, ++ size_t __ns) __THROW; ++extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest, ++ const wchar_t *__restrict __src, ++ size_t __n) __THROW; ++extern wchar_t *__wcpcpy_chk (wchar_t *__restrict __dest, ++ const wchar_t *__restrict __src, ++ size_t __destlen) __THROW; ++extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest, ++ const wchar_t *__restrict __src, size_t __n, ++ size_t __destlen) __THROW; ++extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest, ++ const wchar_t *__restrict __src, size_t __n, ++ size_t __destlen) __THROW; ++extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest, ++ const wchar_t *__restrict __src, ++ size_t __destlen) __THROW; ++extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest, ++ const wchar_t *__restrict __src, ++ size_t __n, size_t __destlen) __THROW; ++extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n, ++ int __flag, size_t __s_len, ++ const wchar_t *__restrict __format, ...) ++ __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */; ++extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n, ++ int __flag, size_t __s_len, ++ const wchar_t *__restrict __format, ++ __gnuc_va_list __arg) ++ __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */; ++ ++#if __USE_FORTIFY_LEVEL > 1 ++ ++extern int __fwprintf_chk (__FILE *__restrict __stream, int __flag, ++ const wchar_t *__restrict __format, ...); ++extern int __wprintf_chk (int __flag, const wchar_t *__restrict __format, ++ ...); ++extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag, ++ const wchar_t *__restrict __format, ++ __gnuc_va_list __ap); ++extern int __vwprintf_chk (int __flag, const wchar_t *__restrict __format, ++ __gnuc_va_list __ap); ++ ++#endif ++ ++extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n, ++ __FILE *__restrict __stream) __wur; ++ ++#ifdef __USE_GNU ++ ++extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size, ++ int __n, __FILE *__restrict __stream) ++ __wur; ++ ++#endif ++ ++extern size_t __wcrtomb_chk (char *__restrict __s, wchar_t __wchar, ++ mbstate_t *__restrict __p, ++ size_t __buflen) __THROW __wur; ++extern size_t __mbsrtowcs_chk (wchar_t *__restrict __dst, ++ const char **__restrict __src, ++ size_t __len, mbstate_t *__restrict __ps, ++ size_t __dstlen) __THROW; ++extern size_t __wcsrtombs_chk (char *__restrict __dst, ++ const wchar_t **__restrict __src, ++ size_t __len, mbstate_t *__restrict __ps, ++ size_t __dstlen) __THROW; ++ ++#ifdef __USE_XOPEN2K8 ++ ++extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst, ++ const char **__restrict __src, size_t __nmc, ++ size_t __len, mbstate_t *__restrict __ps, ++ size_t __dstlen) __THROW; ++extern size_t __wcsnrtombs_chk (char *__restrict __dst, ++ const wchar_t **__restrict __src, ++ size_t __nwc, size_t __len, ++ mbstate_t *__restrict __ps, size_t __dstlen) ++ __THROW; ++ ++#endif ++ ++#endif /* bits/wchar2-decl.h. */ +diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h +index 88c1fdfcd34292f4..50151b424d85a032 100644 +--- a/wcsmbs/bits/wchar2.h ++++ b/wcsmbs/bits/wchar2.h +@@ -21,9 +21,6 @@ + #endif + + +-extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1, +- const wchar_t *__restrict __s2, size_t __n, +- size_t __ns1) __THROW; + extern wchar_t *__REDIRECT_NTH (__wmemcpy_alias, + (wchar_t *__restrict __s1, + const wchar_t *__restrict __s2, size_t __n), +@@ -45,8 +42,6 @@ __NTH (wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, + } + + +-extern wchar_t *__wmemmove_chk (wchar_t *__s1, const wchar_t *__s2, +- size_t __n, size_t __ns1) __THROW; + extern wchar_t *__REDIRECT_NTH (__wmemmove_alias, (wchar_t *__s1, + const wchar_t *__s2, + size_t __n), wmemmove); +@@ -66,9 +61,6 @@ __NTH (wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n)) + + + #ifdef __USE_GNU +-extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1, +- const wchar_t *__restrict __s2, size_t __n, +- size_t __ns1) __THROW; + extern wchar_t *__REDIRECT_NTH (__wmempcpy_alias, + (wchar_t *__restrict __s1, + const wchar_t *__restrict __s2, +@@ -91,8 +83,6 @@ __NTH (wmempcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, + #endif + + +-extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n, +- size_t __ns) __THROW; + extern wchar_t *__REDIRECT_NTH (__wmemset_alias, (wchar_t *__s, wchar_t __c, + size_t __n), wmemset); + extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn, +@@ -110,9 +100,6 @@ __NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n)) + } + + +-extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest, +- const wchar_t *__restrict __src, +- size_t __n) __THROW; + extern wchar_t *__REDIRECT_NTH (__wcscpy_alias, + (wchar_t *__restrict __dest, + const wchar_t *__restrict __src), wcscpy); +@@ -127,9 +114,6 @@ __NTH (wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + } + + +-extern wchar_t *__wcpcpy_chk (wchar_t *__restrict __dest, +- const wchar_t *__restrict __src, +- size_t __destlen) __THROW; + extern wchar_t *__REDIRECT_NTH (__wcpcpy_alias, + (wchar_t *__restrict __dest, + const wchar_t *__restrict __src), wcpcpy); +@@ -144,9 +128,6 @@ __NTH (wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + } + + +-extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest, +- const wchar_t *__restrict __src, size_t __n, +- size_t __destlen) __THROW; + extern wchar_t *__REDIRECT_NTH (__wcsncpy_alias, + (wchar_t *__restrict __dest, + const wchar_t *__restrict __src, +@@ -168,9 +149,6 @@ __NTH (wcsncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + } + + +-extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest, +- const wchar_t *__restrict __src, size_t __n, +- size_t __destlen) __THROW; + extern wchar_t *__REDIRECT_NTH (__wcpncpy_alias, + (wchar_t *__restrict __dest, + const wchar_t *__restrict __src, +@@ -192,9 +170,6 @@ __NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + } + + +-extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest, +- const wchar_t *__restrict __src, +- size_t __destlen) __THROW; + extern wchar_t *__REDIRECT_NTH (__wcscat_alias, + (wchar_t *__restrict __dest, + const wchar_t *__restrict __src), wcscat); +@@ -209,9 +184,6 @@ __NTH (wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + } + + +-extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest, +- const wchar_t *__restrict __src, +- size_t __n, size_t __destlen) __THROW; + extern wchar_t *__REDIRECT_NTH (__wcsncat_alias, + (wchar_t *__restrict __dest, + const wchar_t *__restrict __src, +@@ -228,10 +200,6 @@ __NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + } + + +-extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n, +- int __flag, size_t __s_len, +- const wchar_t *__restrict __format, ...) +- __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */; + + extern int __REDIRECT_NTH_LDBL (__swprintf_alias, + (wchar_t *__restrict __s, size_t __n, +@@ -258,11 +226,6 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n, + : swprintf (s, n, __VA_ARGS__)) + #endif + +-extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n, +- int __flag, size_t __s_len, +- const wchar_t *__restrict __format, +- __gnuc_va_list __arg) +- __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */; + + extern int __REDIRECT_NTH_LDBL (__vswprintf_alias, + (wchar_t *__restrict __s, size_t __n, +@@ -283,16 +246,6 @@ __NTH (vswprintf (wchar_t *__restrict __s, size_t __n, + + #if __USE_FORTIFY_LEVEL > 1 + +-extern int __fwprintf_chk (__FILE *__restrict __stream, int __flag, +- const wchar_t *__restrict __format, ...); +-extern int __wprintf_chk (int __flag, const wchar_t *__restrict __format, +- ...); +-extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag, +- const wchar_t *__restrict __format, +- __gnuc_va_list __ap); +-extern int __vwprintf_chk (int __flag, const wchar_t *__restrict __format, +- __gnuc_va_list __ap); +- + # ifdef __va_arg_pack + __fortify_function int + wprintf (const wchar_t *__restrict __fmt, ...) +@@ -328,8 +281,6 @@ vfwprintf (__FILE *__restrict __stream, + + #endif + +-extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n, +- __FILE *__restrict __stream) __wur; + extern wchar_t *__REDIRECT (__fgetws_alias, + (wchar_t *__restrict __s, int __n, + __FILE *__restrict __stream), fgetws) __wur; +@@ -351,9 +302,6 @@ fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + } + + #ifdef __USE_GNU +-extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size, +- int __n, __FILE *__restrict __stream) +- __wur; + extern wchar_t *__REDIRECT (__fgetws_unlocked_alias, + (wchar_t *__restrict __s, int __n, + __FILE *__restrict __stream), fgetws_unlocked) +@@ -379,9 +327,6 @@ fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + #endif + + +-extern size_t __wcrtomb_chk (char *__restrict __s, wchar_t __wchar, +- mbstate_t *__restrict __p, +- size_t __buflen) __THROW __wur; + extern size_t __REDIRECT_NTH (__wcrtomb_alias, + (char *__restrict __s, wchar_t __wchar, + mbstate_t *__restrict __ps), wcrtomb) __wur; +@@ -404,10 +349,6 @@ __NTH (wcrtomb (char *__restrict __s, wchar_t __wchar, + } + + +-extern size_t __mbsrtowcs_chk (wchar_t *__restrict __dst, +- const char **__restrict __src, +- size_t __len, mbstate_t *__restrict __ps, +- size_t __dstlen) __THROW; + extern size_t __REDIRECT_NTH (__mbsrtowcs_alias, + (wchar_t *__restrict __dst, + const char **__restrict __src, +@@ -431,10 +372,6 @@ __NTH (mbsrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, + } + + +-extern size_t __wcsrtombs_chk (char *__restrict __dst, +- const wchar_t **__restrict __src, +- size_t __len, mbstate_t *__restrict __ps, +- size_t __dstlen) __THROW; + extern size_t __REDIRECT_NTH (__wcsrtombs_alias, + (char *__restrict __dst, + const wchar_t **__restrict __src, +@@ -458,10 +395,6 @@ __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src, + + + #ifdef __USE_XOPEN2K8 +-extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst, +- const char **__restrict __src, size_t __nmc, +- size_t __len, mbstate_t *__restrict __ps, +- size_t __dstlen) __THROW; + extern size_t __REDIRECT_NTH (__mbsnrtowcs_alias, + (wchar_t *__restrict __dst, + const char **__restrict __src, size_t __nmc, +@@ -485,11 +418,6 @@ __NTH (mbsnrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, + } + + +-extern size_t __wcsnrtombs_chk (char *__restrict __dst, +- const wchar_t **__restrict __src, +- size_t __nwc, size_t __len, +- mbstate_t *__restrict __ps, size_t __dstlen) +- __THROW; + extern size_t __REDIRECT_NTH (__wcsnrtombs_alias, + (char *__restrict __dst, + const wchar_t **__restrict __src, +diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h +index 075776890f214842..1c6d4026c46b7306 100644 +--- a/wcsmbs/wchar.h ++++ b/wcsmbs/wchar.h +@@ -864,14 +864,21 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize, + + /* Define some macros helping to catch buffer overflows. */ + #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function +-# include ++/* Declare all functions from bits/wchar2-decl.h first. */ ++# include + #endif + +-#include ++/* The following headers provide asm redirections. These redirections must ++ appear before the first usage of these functions, e.g. in bits/wchar.h. */ + #if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 + # include + #endif + ++#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function ++/* Now include the function definitions and redirects too. */ ++# include ++#endif ++ + __END_DECLS + + #endif /* wchar.h */ diff --git a/SOURCES/glibc-upstream-2.34-312.patch b/SOURCES/glibc-upstream-2.34-312.patch new file mode 100644 index 0000000..f8add99 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-312.patch @@ -0,0 +1,40 @@ +commit 2b3d020055bea4fbbfc0ca2362d46038487c6dfd +Author: Fabian Vogt +Date: Wed Jul 27 11:44:07 2022 +0200 + + nscd: Fix netlink cache invalidation if epoll is used [BZ #29415] + + Processes cache network interface information such as whether IPv4 or IPv6 + are enabled. This is only checked again if the "netlink timestamp" provided + by nscd changed, which is triggered by netlink socket activity. + + However, in the epoll handler for the netlink socket, it was missed to + assign the new timestamp to the nscd database. The handler for plain poll + did that properly, copy that over. + + This bug caused that e.g. processes which started before network + configuration got unusuable addresses from getaddrinfo, like IPv6 only even + though only IPv4 is available: + https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1041 + + It's a bit hard to reproduce, so I verified this by checking the timestamp + on calls to __check_pf manually. Without this patch it's stuck at 1, now + it's increasing on network changes as expected. + + Signed-off-by: Fabian Vogt + (cherry picked from commit 02ca25fef2785974011e9c5beecc99b900b69fd7) + +diff --git a/nscd/connections.c b/nscd/connections.c +index 3f0bda4e97edb9df..bc941715cff47c49 100644 +--- a/nscd/connections.c ++++ b/nscd/connections.c +@@ -2285,7 +2285,8 @@ main_loop_epoll (int efd) + sizeof (buf))) != -1) + ; + +- __bump_nl_timestamp (); ++ dbs[hstdb].head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP] ++ = __bump_nl_timestamp (); + } + # endif + else diff --git a/SOURCES/glibc-upstream-2.34-314.patch b/SOURCES/glibc-upstream-2.34-314.patch new file mode 100644 index 0000000..be02589 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-314.patch @@ -0,0 +1,55 @@ +commit 2ff6775ad341b10a08e3b27d6e1df1da637747c7 +Author: Javier Pello +Date: Mon Sep 5 20:09:01 2022 +0200 + + elf: Fix hwcaps string size overestimation + + Commit dad90d528259b669342757c37dedefa8577e2636 added glibc-hwcaps + support for LD_LIBRARY_PATH and, for this, it adjusted the total + string size required in _dl_important_hwcaps. However, in doing so + it inadvertently altered the calculation of the size required for + the power set strings, as the computation of the power set string + size depended on the first value assigned to the total variable, + which is later shifted, resulting in overallocation of string + space. Fix this now by using a different variable to hold the + string size required for glibc-hwcaps. + + Signed-off-by: Javier Pello + (cherry picked from commit a23820f6052a740246fdc7dcd9c43ce8eed0c45a) + +diff --git a/elf/dl-hwcaps.c b/elf/dl-hwcaps.c +index e3c611e005ffbc0d..045911eb6d5d315a 100644 +--- a/elf/dl-hwcaps.c ++++ b/elf/dl-hwcaps.c +@@ -193,7 +193,7 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend, + /* Each hwcaps subdirectory has a GLIBC_HWCAPS_PREFIX string prefix + and a "/" suffix once stored in the result. */ + hwcaps_counts.maximum_length += strlen (GLIBC_HWCAPS_PREFIX) + 1; +- size_t total = (hwcaps_counts.count * (strlen (GLIBC_HWCAPS_PREFIX) + 1) ++ size_t hwcaps_sz = (hwcaps_counts.count * (strlen (GLIBC_HWCAPS_PREFIX) + 1) + + hwcaps_counts.total_length); + + /* Count the number of bits set in the masked value. */ +@@ -229,11 +229,12 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend, + assert (m == cnt); + + /* Determine the total size of all strings together. */ ++ size_t total; + if (cnt == 1) +- total += temp[0].len + 1; ++ total = temp[0].len + 1; + else + { +- total += temp[0].len + temp[cnt - 1].len + 2; ++ total = temp[0].len + temp[cnt - 1].len + 2; + if (cnt > 2) + { + total <<= 1; +@@ -255,6 +256,7 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend, + /* This is the overall result, including both glibc-hwcaps + subdirectories and the legacy hwcaps subdirectories using the + power set construction. */ ++ total += hwcaps_sz; + struct r_strlenpair *overall_result + = malloc (*sz * sizeof (*result) + total); + if (overall_result == NULL) diff --git a/SOURCES/glibc-upstream-2.34-315.patch b/SOURCES/glibc-upstream-2.34-315.patch new file mode 100644 index 0000000..89512a1 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-315.patch @@ -0,0 +1,62 @@ +commit f50a6c843a5b5186c0aa73747de033e08ef8246d +Author: Florian Weimer +Date: Tue Sep 20 12:12:43 2022 +0200 + + gconv: Use 64-bit interfaces in gconv_parseconfdir (bug 29583) + + It's possible that inode numbers are outside the 32-bit range. + The existing code only handles the in-libc case correctly, and + still uses the legacy interfaces when building iconv. + + Suggested-by: Helge Deller + (cherry picked from commit f97905f24631097af325d6a231093071c3077a5f) + +diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h +index 79398a980cde84e3..741cf7c67e36eccd 100644 +--- a/iconv/gconv_parseconfdir.h ++++ b/iconv/gconv_parseconfdir.h +@@ -29,14 +29,14 @@ + # define isspace(__c) __isspace_l ((__c), _nl_C_locobj_ptr) + # define asprintf __asprintf + # define opendir __opendir +-# define readdir __readdir ++# define readdir64 __readdir64 + # define closedir __closedir + # define mempcpy __mempcpy +-# define struct_stat struct __stat64_t64 +-# define lstat __lstat64_time64 ++# define struct_stat64 struct __stat64_t64 ++# define lstat64 __lstat64_time64 + # define feof_unlocked __feof_unlocked + #else +-# define struct_stat struct stat ++# define struct_stat64 struct stat64 + #endif + + /* Name of the file containing the module information in the directories +@@ -148,8 +148,8 @@ gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len) + DIR *confdir = opendir (buf); + if (confdir != NULL) + { +- struct dirent *ent; +- while ((ent = readdir (confdir)) != NULL) ++ struct dirent64 *ent; ++ while ((ent = readdir64 (confdir)) != NULL) + { + if (ent->d_type != DT_REG && ent->d_type != DT_UNKNOWN) + continue; +@@ -161,12 +161,12 @@ gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len) + && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0) + { + char *conf; +- struct_stat st; ++ struct_stat64 st; + if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0) + continue; + + if (ent->d_type != DT_UNKNOWN +- || (lstat (conf, &st) != -1 && S_ISREG (st.st_mode))) ++ || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode))) + found |= read_conf_file (conf, dir, dir_len); + + free (conf); diff --git a/SOURCES/glibc-upstream-2.34-316.patch b/SOURCES/glibc-upstream-2.34-316.patch new file mode 100644 index 0000000..6712840 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-316.patch @@ -0,0 +1,399 @@ +commit 1a3afdfe319a142228498f7a4ee82ac3917d97e8 +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + resolv: Add tst-resolv-byaddr for testing reverse lookup + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 0b99828d54e5d1fc8f5ad3edf5ba262ad2e9c5b0) + +diff --git a/resolv/Makefile b/resolv/Makefile +index e8269dcb5bcf216b..78165eb99e98b525 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -92,6 +92,7 @@ tests += \ + tst-res_hnok \ + tst-resolv-basic \ + tst-resolv-binary \ ++ tst-resolv-byaddr \ + tst-resolv-edns \ + tst-resolv-network \ + tst-resolv-noaaaa \ +@@ -251,6 +252,7 @@ $(objpfx)tst-resolv-ai_idn-nolibidn2.out: \ + $(gen-locales) $(objpfx)tst-no-libidn2.so + $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-binary: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-byaddr: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-res_init: $(objpfx)libresolv.so +diff --git a/resolv/tst-resolv-byaddr.c b/resolv/tst-resolv-byaddr.c +new file mode 100644 +index 0000000000000000..6299e89837da58c6 +--- /dev/null ++++ b/resolv/tst-resolv-byaddr.c +@@ -0,0 +1,326 @@ ++/* Test reverse DNS lookup. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "tst-resolv-maybe_insert_sig.h" ++ ++/* QNAME format: ++ ++ ADDRESSES.CNAMES...(lots of 0s)...8.b.d.0.1.0.0.2.ip6.arpa. ++ CNAMES|ADDRESSES.2.0.192.in-addr-arpa. ++ ++ For the IPv4 reverse lookup, the address count is in the lower ++ bits. ++ ++ CNAMES is the length of the CNAME chain, ADDRESSES is the number of ++ addresses in the response. The special value 15 means that there ++ are no addresses, and the RCODE is NXDOMAIN. */ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ TEST_COMPARE (qclass, C_IN); ++ TEST_COMPARE (qtype, T_PTR); ++ ++ unsigned int addresses, cnames, bits; ++ char *tail; ++ if (strstr (qname, "ip6.arpa") != NULL ++ && sscanf (qname, "%x.%x.%ms", &addresses, &cnames, &tail) == 3) ++ TEST_COMPARE_STRING (tail, "\ ++0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa"); ++ else if (sscanf (qname, "%u.%ms", &bits, &tail) == 2) ++ { ++ TEST_COMPARE_STRING (tail, "2.0.192.in-addr.arpa"); ++ addresses = bits & 0x0f; ++ cnames = bits >> 4; ++ } ++ else ++ FAIL_EXIT1 ("invalid QNAME: %s", qname); ++ free (tail); ++ ++ int rcode; ++ if (addresses == 15) ++ { ++ /* Special case: Use no addresses with NXDOMAIN response. */ ++ rcode = ns_r_nxdomain; ++ addresses = 0; ++ } ++ else ++ rcode = 0; ++ ++ struct resolv_response_flags flags = { .rcode = rcode }; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ maybe_insert_sig (b, qname); ++ ++ /* Provide the requested number of CNAME records. */ ++ char *previous_name = (char *) qname; ++ for (int unique = 0; unique < cnames; ++unique) ++ { ++ resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60); ++ char *new_name = xasprintf ("%d.alias.example", unique); ++ resolv_response_add_name (b, new_name); ++ resolv_response_close_record (b); ++ ++ maybe_insert_sig (b, qname); ++ ++ if (previous_name != qname) ++ free (previous_name); ++ previous_name = new_name; ++ } ++ ++ for (int unique = 0; unique < addresses; ++unique) ++ { ++ resolv_response_open_record (b, previous_name, qclass, T_PTR, 60); ++ char *ptr = xasprintf ("unique-%d.cnames-%u.addresses-%u.example", ++ unique, cnames, addresses); ++ resolv_response_add_name (b, ptr); ++ free (ptr); ++ resolv_response_close_record (b); ++ } ++ ++ if (previous_name != qname) ++ free (previous_name); ++} ++ ++/* Used to check that gethostbyaddr_r does not write past the buffer ++ end. */ ++static struct support_next_to_fault ntf; ++ ++/* Perform a gethostbyaddr call and check the result. */ ++static void ++check_gethostbyaddr (const char *address, const char *expected) ++{ ++ unsigned char bytes[16]; ++ unsigned int byteslen; ++ int family; ++ if (strchr (address, ':') != NULL) ++ { ++ family = AF_INET6; ++ byteslen = 16; ++ } ++ else ++ { ++ family = AF_INET; ++ byteslen = 4; ++ } ++ TEST_COMPARE (inet_pton (family, address, bytes), 1); ++ ++ struct hostent *e = gethostbyaddr (bytes, byteslen, family); ++ check_hostent (address, e, expected); ++ ++ if (e == NULL) ++ return; ++ ++ /* Try gethostbyaddr_r with increasing sizes until success. First ++ compute a reasonable minimum buffer size, to avoid many pointless ++ attempts. */ ++ size_t minimum_size = strlen (e->h_name); ++ for (int i = 0; e->h_addr_list[i] != NULL; ++i) ++ minimum_size += e->h_length + sizeof (char *); ++ for (int i = 0; e->h_aliases[i] != NULL; ++i) ++ minimum_size += strlen (e->h_aliases[i]) + 1 + sizeof (char *); ++ ++ /* Gradually increase the size until success. */ ++ for (size_t size = minimum_size; size < ntf.length; ++size) ++ { ++ struct hostent result; ++ int herrno; ++ int ret = gethostbyaddr_r (bytes, byteslen, family, &result, ++ ntf.buffer + ntf.length - size, size, ++ &e, &herrno); ++ if (ret == ERANGE) ++ /* Retry with larger size. */ ++ TEST_COMPARE (herrno, NETDB_INTERNAL); ++ else if (ret == 0) ++ { ++ TEST_VERIFY (size > minimum_size); ++ check_hostent (address, e, expected); ++ return; ++ } ++ else ++ FAIL_EXIT1 ("Unexpected gethostbyaddr_r failure: %d", ret); ++ } ++ ++ FAIL_EXIT1 ("gethostbyaddr_r always failed for: %s", address); ++} ++ ++/* Perform a getnameinfo call and check the result. */ ++static void ++check_getnameinfo (const char *address, const char *expected) ++{ ++ struct sockaddr_in sin = { }; ++ struct sockaddr_in6 sin6 = { }; ++ void *sa; ++ socklen_t salen; ++ if (strchr (address, ':') != NULL) ++ { ++ sin6.sin6_family = AF_INET6; ++ TEST_COMPARE (inet_pton (AF_INET6, address, &sin6.sin6_addr), 1); ++ sin6.sin6_port = htons (80); ++ sa = &sin6; ++ salen = sizeof (sin6); ++ } ++ else ++ { ++ sin.sin_family = AF_INET; ++ TEST_COMPARE (inet_pton (AF_INET, address, &sin.sin_addr), 1); ++ sin.sin_port = htons (80); ++ sa = &sin; ++ salen = sizeof (sin); ++ } ++ ++ char host[64]; ++ char service[64]; ++ int ret = getnameinfo (sa, salen, host, ++ sizeof (host), service, sizeof (service), ++ NI_NAMEREQD | NI_NUMERICSERV); ++ switch (ret) ++ { ++ case 0: ++ TEST_COMPARE_STRING (host, expected); ++ TEST_COMPARE_STRING (service, "80"); ++ break; ++ case EAI_SYSTEM: ++ TEST_COMPARE_STRING (strerror (errno), expected); ++ break; ++ default: ++ TEST_COMPARE_STRING (gai_strerror (ret), expected); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ /* Some reasonably upper bound for the maximum response size. */ ++ ntf = support_next_to_fault_allocate (4096); ++ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response ++ }); ++ ++ for (int do_insert_sig = 0; do_insert_sig < 2; ++do_insert_sig) ++ { ++ insert_sig = do_insert_sig; ++ ++ /* No PTR record, RCODE=0. */ ++ check_gethostbyaddr ("192.0.2.0", "error: NO_RECOVERY\n"); ++ check_getnameinfo ("192.0.2.0", "Name or service not known"); ++ check_gethostbyaddr ("192.0.2.16", "error: NO_RECOVERY\n"); ++ check_getnameinfo ("192.0.2.16", "Name or service not known"); ++ check_gethostbyaddr ("192.0.2.32", "error: NO_RECOVERY\n"); ++ check_getnameinfo ("192.0.2.32", "Name or service not known"); ++ check_gethostbyaddr ("2001:db8::", "error: NO_RECOVERY\n"); ++ check_getnameinfo ("2001:db8::", "Name or service not known"); ++ check_gethostbyaddr ("2001:db8::10", "error: NO_RECOVERY\n"); ++ check_getnameinfo ("2001:db8::10", "Name or service not known"); ++ check_gethostbyaddr ("2001:db8::20", "error: NO_RECOVERY\n"); ++ check_getnameinfo ("2001:db8::20", "Name or service not known"); ++ ++ /* No PTR record, NXDOMAIN. */ ++ check_gethostbyaddr ("192.0.2.15", "error: HOST_NOT_FOUND\n"); ++ check_getnameinfo ("192.0.2.15", "Name or service not known"); ++ check_gethostbyaddr ("192.0.2.31", "error: HOST_NOT_FOUND\n"); ++ check_getnameinfo ("192.0.2.31", "Name or service not known"); ++ check_gethostbyaddr ("192.0.2.47", "error: HOST_NOT_FOUND\n"); ++ check_getnameinfo ("192.0.2.47", "Name or service not known"); ++ check_gethostbyaddr ("2001:db8::f", "error: HOST_NOT_FOUND\n"); ++ check_getnameinfo ("2001:db8::f", "Name or service not known"); ++ check_gethostbyaddr ("2001:db8::1f", "error: HOST_NOT_FOUND\n"); ++ check_getnameinfo ("2001:db8::1f", "Name or service not known"); ++ check_gethostbyaddr ("2001:db8::2f", "error: HOST_NOT_FOUND\n"); ++ check_getnameinfo ("2001:db8::2f", "Name or service not known"); ++ ++ /* Actual response data. Only the first PTR record is returned. */ ++ check_gethostbyaddr ("192.0.2.1", ++ "name: unique-0.cnames-0.addresses-1.example\n" ++ "address: 192.0.2.1\n"); ++ check_getnameinfo ("192.0.2.1", ++ "unique-0.cnames-0.addresses-1.example"); ++ check_gethostbyaddr ("192.0.2.17", ++ "name: unique-0.cnames-1.addresses-1.example\n" ++ "address: 192.0.2.17\n"); ++ check_getnameinfo ("192.0.2.17", ++ "unique-0.cnames-1.addresses-1.example"); ++ check_gethostbyaddr ("192.0.2.18", ++ "name: unique-0.cnames-1.addresses-2.example\n" ++ "address: 192.0.2.18\n"); ++ check_getnameinfo ("192.0.2.18", ++ "unique-0.cnames-1.addresses-2.example"); ++ check_gethostbyaddr ("192.0.2.33", ++ "name: unique-0.cnames-2.addresses-1.example\n" ++ "address: 192.0.2.33\n"); ++ check_getnameinfo ("192.0.2.33", ++ "unique-0.cnames-2.addresses-1.example"); ++ check_gethostbyaddr ("192.0.2.34", ++ "name: unique-0.cnames-2.addresses-2.example\n" ++ "address: 192.0.2.34\n"); ++ check_getnameinfo ("192.0.2.34", ++ "unique-0.cnames-2.addresses-2.example"); ++ ++ /* Same for IPv6 addresses. */ ++ check_gethostbyaddr ("2001:db8::1", ++ "name: unique-0.cnames-0.addresses-1.example\n" ++ "address: 2001:db8::1\n"); ++ check_getnameinfo ("2001:db8::1", ++ "unique-0.cnames-0.addresses-1.example"); ++ check_gethostbyaddr ("2001:db8::11", ++ "name: unique-0.cnames-1.addresses-1.example\n" ++ "address: 2001:db8::11\n"); ++ check_getnameinfo ("2001:db8::11", ++ "unique-0.cnames-1.addresses-1.example"); ++ check_gethostbyaddr ("2001:db8::12", ++ "name: unique-0.cnames-1.addresses-2.example\n" ++ "address: 2001:db8::12\n"); ++ check_getnameinfo ("2001:db8::12", ++ "unique-0.cnames-1.addresses-2.example"); ++ check_gethostbyaddr ("2001:db8::21", ++ "name: unique-0.cnames-2.addresses-1.example\n" ++ "address: 2001:db8::21\n"); ++ check_getnameinfo ("2001:db8::21", ++ "unique-0.cnames-2.addresses-1.example"); ++ check_gethostbyaddr ("2001:db8::22", ++ "name: unique-0.cnames-2.addresses-2.example\n" ++ "address: 2001:db8::22\n"); ++ check_getnameinfo ("2001:db8::22", ++ "unique-0.cnames-2.addresses-2.example"); ++ } ++ ++ resolv_test_end (obj); ++ ++ support_next_to_fault_free (&ntf); ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-maybe_insert_sig.h b/resolv/tst-resolv-maybe_insert_sig.h +new file mode 100644 +index 0000000000000000..05725225af0818cb +--- /dev/null ++++ b/resolv/tst-resolv-maybe_insert_sig.h +@@ -0,0 +1,32 @@ ++/* Code snippet for optionally inserting ignored SIG records in resolver tests. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Set to true for an alternative pass that inserts (ignored) SIG ++ records. This does not alter the response, so this property is not ++ encoded in the QNAME. The variable needs to be volatile because ++ leaf attributes tell GCC that the response function is not ++ called. */ ++static volatile bool insert_sig; ++ ++static void ++maybe_insert_sig (struct resolv_response_builder *b, const char *owner) ++{ ++ resolv_response_open_record (b, owner, C_IN, T_SIG, 60); ++ resolv_response_add_data (b, "", 1); ++ resolv_response_close_record (b); ++} diff --git a/SOURCES/glibc-upstream-2.34-317.patch b/SOURCES/glibc-upstream-2.34-317.patch new file mode 100644 index 0000000..b99be70 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-317.patch @@ -0,0 +1,289 @@ +commit 6a833d798e87536587cd4cc14fe8d078f80b14a0 +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + resolv: Add tst-resolv-aliases + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 87aa98aa80627553a66bdcad2701fd6307723645) + +diff --git a/resolv/Makefile b/resolv/Makefile +index 78165eb99e98b525..567f4c2dcf5749df 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -90,6 +90,7 @@ tests += \ + tst-ns_name_pton \ + tst-res_hconf_reorder \ + tst-res_hnok \ ++ tst-resolv-aliases \ + tst-resolv-basic \ + tst-resolv-binary \ + tst-resolv-byaddr \ +@@ -250,6 +251,7 @@ $(objpfx)tst-resolv-ai_idn.out: $(gen-locales) + $(objpfx)tst-resolv-ai_idn-latin1.out: $(gen-locales) + $(objpfx)tst-resolv-ai_idn-nolibidn2.out: \ + $(gen-locales) $(objpfx)tst-no-libidn2.so ++$(objpfx)tst-resolv-aliases: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-binary: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-byaddr: $(objpfx)libresolv.so $(shared-thread-library) +diff --git a/resolv/tst-resolv-aliases.c b/resolv/tst-resolv-aliases.c +new file mode 100644 +index 0000000000000000..b212823aa07ceb21 +--- /dev/null ++++ b/resolv/tst-resolv-aliases.c +@@ -0,0 +1,254 @@ ++/* Test alias handling (mainly for gethostbyname). ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "tst-resolv-maybe_insert_sig.h" ++ ++/* QNAME format: ++ ++ aADDRESSES-cCNAMES.example.net ++ ++ CNAMES is the length of the CNAME chain, ADDRESSES is the number of ++ addresses in the response. The special value 255 means that there ++ are no addresses, and the RCODE is NXDOMAIN. */ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ TEST_COMPARE (qclass, C_IN); ++ if (qtype != T_A) ++ TEST_COMPARE (qtype, T_AAAA); ++ ++ unsigned int addresses, cnames; ++ char *tail; ++ if (sscanf (qname, "a%u-c%u%ms", &addresses, &cnames, &tail) == 3) ++ { ++ if (strcmp (tail, ".example.com") == 0 ++ || strcmp (tail, ".example.net.example.net") == 0 ++ || strcmp (tail, ".example.net.example.com") == 0) ++ /* These only happen after NXDOMAIN. */ ++ TEST_VERIFY (addresses == 255); ++ else if (strcmp (tail, ".example.net") != 0) ++ FAIL_EXIT1 ("invalid QNAME: %s", qname); ++ } ++ free (tail); ++ ++ int rcode; ++ if (addresses == 255) ++ { ++ /* Special case: Use no addresses with NXDOMAIN response. */ ++ rcode = ns_r_nxdomain; ++ addresses = 0; ++ } ++ else ++ rcode = 0; ++ ++ struct resolv_response_flags flags = { .rcode = rcode }; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ maybe_insert_sig (b, qname); ++ ++ /* Provide the requested number of CNAME records. */ ++ char *previous_name = (char *) qname; ++ for (int unique = 0; unique < cnames; ++unique) ++ { ++ resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60); ++ char *new_name = xasprintf ("%d.alias.example", unique); ++ resolv_response_add_name (b, new_name); ++ resolv_response_close_record (b); ++ ++ maybe_insert_sig (b, qname); ++ ++ if (previous_name != qname) ++ free (previous_name); ++ previous_name = new_name; ++ } ++ ++ for (int unique = 0; unique < addresses; ++unique) ++ { ++ resolv_response_open_record (b, previous_name, qclass, qtype, 60); ++ ++ if (qtype == T_A) ++ { ++ char ipv4[4] = {192, 0, 2, 1 + unique}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ else if (qtype == T_AAAA) ++ { ++ char ipv6[16] = ++ { ++ 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 1 + unique ++ }; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ resolv_response_close_record (b); ++ } ++ ++ if (previous_name != qname) ++ free (previous_name); ++} ++ ++static char * ++make_qname (bool do_search, int cnames, int addresses) ++{ ++ return xasprintf ("a%d-c%d%s", ++ addresses, cnames, do_search ? "" : ".example.net"); ++} ++ ++static void ++check_cnames_failure (int af, bool do_search, int cnames, int addresses) ++{ ++ char *qname = make_qname (do_search, cnames, addresses); ++ ++ struct hostent *e; ++ if (af == AF_UNSPEC) ++ e = gethostbyname (qname); ++ else ++ e = gethostbyname2 (qname, af); ++ ++ if (addresses == 0) ++ check_hostent (qname, e, "error: NO_RECOVERY\n"); ++ else ++ check_hostent (qname, e, "error: HOST_NOT_FOUND\n"); ++ ++ free (qname); ++} ++ ++static void ++check (int af, bool do_search, int cnames, int addresses) ++{ ++ char *qname = make_qname (do_search, cnames, addresses); ++ char *fqdn = make_qname (false, cnames, addresses); ++ ++ struct hostent *e; ++ if (af == AF_UNSPEC) ++ e = gethostbyname (qname); ++ else ++ e = gethostbyname2 (qname, af); ++ if (e == NULL) ++ FAIL_EXIT1 ("unexpected failure for %d, %d, %d", af, cnames, addresses); ++ ++ if (af == AF_UNSPEC || af == AF_INET) ++ { ++ TEST_COMPARE (e->h_addrtype, AF_INET); ++ TEST_COMPARE (e->h_length, 4); ++ } ++ else ++ { ++ TEST_COMPARE (e->h_addrtype, AF_INET6); ++ TEST_COMPARE (e->h_length, 16); ++ } ++ ++ for (int i = 0; i < addresses; ++i) ++ { ++ char ipv4[4] = {192, 0, 2, 1 + i}; ++ char ipv6[16] = ++ { 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + i }; ++ char *expected = e->h_addrtype == AF_INET ? ipv4 : ipv6; ++ TEST_COMPARE_BLOB (e->h_addr_list[i], e->h_length, ++ expected, e->h_length); ++ } ++ TEST_VERIFY (e->h_addr_list[addresses] == NULL); ++ ++ ++ if (cnames == 0) ++ { ++ /* QNAME is fully qualified. */ ++ TEST_COMPARE_STRING (e->h_name, fqdn); ++ TEST_VERIFY (e->h_aliases[0] == NULL); ++ } ++ else ++ { ++ /* Fully-qualified QNAME is demoted to an aliases. */ ++ TEST_COMPARE_STRING (e->h_aliases[0], fqdn); ++ ++ for (int i = 1; i <= cnames; ++i) ++ { ++ char *expected = xasprintf ("%d.alias.example", i - 1); ++ if (i == cnames) ++ TEST_COMPARE_STRING (e->h_name, expected); ++ else ++ TEST_COMPARE_STRING (e->h_aliases[i], expected); ++ free (expected); ++ } ++ TEST_VERIFY (e->h_aliases[cnames] == NULL); ++ } ++ ++ free (fqdn); ++ free (qname); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ .search = { "example.net", "example.com" }, ++ }); ++ ++ static const int families[] = { AF_UNSPEC, AF_INET, AF_INET6 }; ++ ++ for (int do_insert_sig = 0; do_insert_sig < 2; ++do_insert_sig) ++ { ++ insert_sig = do_insert_sig; ++ ++ /* If do_search is true, a bare host name (for example, a1-c1) ++ is used. This exercises search path processing and FQDN ++ qualification. */ ++ for (int do_search = 0; do_search < 2; ++do_search) ++ for (const int *paf = families; paf != array_end (families); ++paf) ++ { ++ for (int cnames = 0; cnames <= 100; ++cnames) ++ { ++ check_cnames_failure (*paf, do_search, cnames, 0); ++ /* Now with NXDOMAIN responses. */ ++ check_cnames_failure (*paf, do_search, cnames, 255); ++ } ++ ++ for (int cnames = 0; cnames <= 10; ++cnames) ++ for (int addresses = 1; addresses <= 10; ++addresses) ++ check (*paf, do_search, cnames, addresses); ++ ++ /* The current implementation is limited to 47 aliases. ++ Addresses do not have such a limit. */ ++ check (*paf, do_search, 47, 60); ++ } ++ } ++ ++ resolv_test_end (obj); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-318.patch b/SOURCES/glibc-upstream-2.34-318.patch new file mode 100644 index 0000000..0dd08c0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-318.patch @@ -0,0 +1,58 @@ +commit 4d2e67d6e5c910114dbccd17d9b93f06552c0024 +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + resolv: Add internal __res_binary_hnok function + + During package parsing, only the binary representation is available, + and it is convenient to check that directly for conformance with host + name requirements. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit c79327bf00a4be6d60259227acc78ef80ead3622) + +diff --git a/include/resolv.h b/include/resolv.h +index 3590b6f496d47710..4dbbac3800b7ef30 100644 +--- a/include/resolv.h ++++ b/include/resolv.h +@@ -70,5 +70,8 @@ libc_hidden_proto (__libc_res_nameinquery) + extern __typeof (__res_queriesmatch) __libc_res_queriesmatch; + libc_hidden_proto (__libc_res_queriesmatch) + ++/* Variant of res_hnok which operates on binary (but uncompressed) names. */ ++bool __res_binary_hnok (const unsigned char *dn) attribute_hidden; ++ + # endif /* _RESOLV_H_ && !_ISOMAC */ + #endif +diff --git a/resolv/res-name-checking.c b/resolv/res-name-checking.c +index 2c603494fa3ca992..513ddb5f6b12ccb0 100644 +--- a/resolv/res-name-checking.c ++++ b/resolv/res-name-checking.c +@@ -138,6 +138,12 @@ binary_leading_dash (const unsigned char *dn) + return dn[0] > 0 && dn[1] == '-'; + } + ++bool ++__res_binary_hnok (const unsigned char *dn) ++{ ++ return !binary_leading_dash (dn) && binary_hnok (dn); ++} ++ + /* Return 1 if res_hnok is a valid host name. Labels must only + contain [0-9a-zA-Z_-] characters, and the name must not start with + a '-'. The latter is to avoid confusion with program options. */ +@@ -145,11 +151,9 @@ int + ___res_hnok (const char *dn) + { + unsigned char buf[NS_MAXCDNAME]; +- if (!printable_string (dn) +- || __ns_name_pton (dn, buf, sizeof (buf)) < 0 +- || binary_leading_dash (buf)) +- return 0; +- return binary_hnok (buf); ++ return (printable_string (dn) ++ && __ns_name_pton (dn, buf, sizeof (buf)) >= 0 ++ && __res_binary_hnok (buf)); + } + versioned_symbol (libc, ___res_hnok, res_hnok, GLIBC_2_34); + versioned_symbol (libc, ___res_hnok, __libc_res_hnok, GLIBC_PRIVATE); diff --git a/SOURCES/glibc-upstream-2.34-319.patch b/SOURCES/glibc-upstream-2.34-319.patch new file mode 100644 index 0000000..e00dfbe --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-319.patch @@ -0,0 +1,182 @@ +commit bb8adbba4f5d9237a144786ba8e504039beff161 +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + resolv: Add the __ns_samebinaryname function + + During packet parsing, only the binary name is available. If the name + equality check is performed before conversion to text, we can sometimes + skip the last step. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 394085a34d25a51513019a4dc411acd3527fbd33) + +diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h +index 53f1dbc7c3f659e9..bb1dede187cf1500 100644 +--- a/include/arpa/nameser.h ++++ b/include/arpa/nameser.h +@@ -55,6 +55,12 @@ int __ns_name_ntop (const unsigned char *, char *, size_t) __THROW; + int __ns_name_unpack (const unsigned char *, const unsigned char *, + const unsigned char *, unsigned char *, size_t) __THROW; + ++/* Like ns_samename, but for uncompressed binary names. Return true ++ if the two arguments compare are equal as case-insensitive domain ++ names. */ ++_Bool __ns_samebinaryname (const unsigned char *, const unsigned char *) ++ attribute_hidden; ++ + #define ns_msg_getflag(handle, flag) \ + (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift) + +diff --git a/resolv/Makefile b/resolv/Makefile +index 567f4c2dcf5749df..0b4fa30716af3b8a 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -46,6 +46,7 @@ routines := \ + ns_name_skip \ + ns_name_uncompress \ + ns_name_unpack \ ++ ns_samebinaryname \ + ns_samename \ + nsap_addr \ + nss_dns_functions \ +@@ -107,6 +108,10 @@ tests += \ + tests-internal += tst-resolv-txnid-collision + tests-static += tst-resolv-txnid-collision + ++# Likewise for __ns_samebinaryname. ++tests-internal += tst-ns_samebinaryname ++tests-static += tst-ns_samebinaryname ++ + # These tests need libdl. + ifeq (yes,$(build-shared)) + tests += \ +diff --git a/resolv/ns_samebinaryname.c b/resolv/ns_samebinaryname.c +new file mode 100644 +index 0000000000000000..9a47d8e97a84c759 +--- /dev/null ++++ b/resolv/ns_samebinaryname.c +@@ -0,0 +1,55 @@ ++/* Compare two binary domain names for quality. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++/* Convert ASCII letters to upper case. */ ++static inline int ++ascii_toupper (unsigned char ch) ++{ ++ if (ch >= 'a' && ch <= 'z') ++ return ch - 'a' + 'A'; ++ else ++ return ch; ++} ++ ++bool ++__ns_samebinaryname (const unsigned char *a, const unsigned char *b) ++{ ++ while (*a != 0 && *b != 0) ++ { ++ if (*a != *b) ++ /* Different label length. */ ++ return false; ++ int labellen = *a; ++ ++a; ++ ++b; ++ for (int i = 0; i < labellen; ++i) ++ { ++ if (*a != *b && ascii_toupper (*a) != ascii_toupper (*b)) ++ /* Different character in label. */ ++ return false; ++ ++a; ++ ++b; ++ } ++ } ++ ++ /* Match if both names are at the root label. */ ++ return *a == 0 && *b == 0; ++} +diff --git a/resolv/tst-ns_samebinaryname.c b/resolv/tst-ns_samebinaryname.c +new file mode 100644 +index 0000000000000000..b06ac610b4cde8be +--- /dev/null ++++ b/resolv/tst-ns_samebinaryname.c +@@ -0,0 +1,62 @@ ++/* Test the __ns_samebinaryname function. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* First character denotes the comparison group: All names with the ++ same first character are expected to compare equal. */ ++static const char *const cases[] = ++ { ++ " ", ++ "1\001a", "1\001A", ++ "2\002ab", "2\002aB", "2\002Ab", "2\002AB", ++ "3\001a\002ab", "3\001A\002ab", ++ "w\003www\007example\003com", "w\003Www\007Example\003Com", ++ "w\003WWW\007EXAMPLE\003COM", ++ "W\003WWW", "W\003www", ++ }; ++ ++static int ++do_test (void) ++{ ++ for (int i = 0; i < array_length (cases); ++i) ++ for (int j = 0; j < array_length (cases); ++j) ++ { ++ unsigned char *a = (unsigned char *) &cases[i][1]; ++ unsigned char *b = (unsigned char *) &cases[j][1]; ++ bool actual = __ns_samebinaryname (a, b); ++ bool expected = cases[i][0] == cases[j][0]; ++ if (actual != expected) ++ { ++ char a1[NS_MAXDNAME]; ++ TEST_VERIFY (ns_name_ntop (a, a1, sizeof (a1)) > 0); ++ char b1[NS_MAXDNAME]; ++ TEST_VERIFY (ns_name_ntop (b, b1, sizeof (b1)) > 0); ++ printf ("error: \"%s\" \"%s\": expected %s\n", ++ a1, b1, expected ? "equal" : "unqueal"); ++ support_record_failure (); ++ } ++ } ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-32.patch b/SOURCES/glibc-upstream-2.34-32.patch new file mode 100644 index 0000000..d5fddc0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-32.patch @@ -0,0 +1,42 @@ +commit 80a009119ba2330768120476aaad63767b81d543 +Author: Jonathan Wakely +Date: Wed May 19 16:48:19 2021 +0100 + + Suppress -Wcast-qual warnings in bsearch + + The first cast to (void *) is redundant but should be (const void *) + anyway, because that's the type of the lvalue being assigned to. + + The second cast is necessary and intentionally not const-correct, so + tell the compiler not to warn about it. + + Reviewed-by: Florian Weimer + (cherry picked from commit a725ff1de965f4cc4f36a7e8ae795d40ca0350d7) + +diff --git a/bits/stdlib-bsearch.h b/bits/stdlib-bsearch.h +index 4132dc6af0077f31..d688ed2e15678e9c 100644 +--- a/bits/stdlib-bsearch.h ++++ b/bits/stdlib-bsearch.h +@@ -29,14 +29,21 @@ bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size, + while (__l < __u) + { + __idx = (__l + __u) / 2; +- __p = (void *) (((const char *) __base) + (__idx * __size)); ++ __p = (const void *) (((const char *) __base) + (__idx * __size)); + __comparison = (*__compar) (__key, __p); + if (__comparison < 0) + __u = __idx; + else if (__comparison > 0) + __l = __idx + 1; + else ++#if __GNUC_PREREQ(4, 6) ++# pragma GCC diagnostic push ++# pragma GCC diagnostic ignored "-Wcast-qual" ++#endif + return (void *) __p; ++#if __GNUC_PREREQ(4, 6) ++# pragma GCC diagnostic pop ++#endif + } + + return NULL; diff --git a/SOURCES/glibc-upstream-2.34-320.patch b/SOURCES/glibc-upstream-2.34-320.patch new file mode 100644 index 0000000..617e31c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-320.patch @@ -0,0 +1,272 @@ +commit c288e032ae107c48679ef3c46fb84af6de0a6baf +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + resolv: Add internal __ns_name_length_uncompressed function + + This function is useful for checking that the question name is + uncompressed (as it should be). + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 78b1a4f0e49064e5dfb686c7cd87bd4df2640b29) + +diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h +index bb1dede187cf1500..6e4808f00d60caf9 100644 +--- a/include/arpa/nameser.h ++++ b/include/arpa/nameser.h +@@ -95,5 +95,13 @@ libc_hidden_proto (__ns_name_unpack) + extern __typeof (ns_samename) __libc_ns_samename; + libc_hidden_proto (__libc_ns_samename) + ++/* Packet parser helper functions. */ ++ ++/* Verify that P points to an uncompressed domain name in wire format. ++ On success, return the length of the encoded name, including the ++ terminating null byte. On failure, return -1 and set errno. EOM ++ must point one past the last byte in the packet. */ ++int __ns_name_length_uncompressed (const unsigned char *p, ++ const unsigned char *eom) attribute_hidden; + # endif /* !_ISOMAC */ + #endif +diff --git a/resolv/Makefile b/resolv/Makefile +index 0b4fa30716af3b8a..308f18622a04965a 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -40,6 +40,7 @@ routines := \ + inet_pton \ + ns_makecanon \ + ns_name_compress \ ++ ns_name_length_uncompressed \ + ns_name_ntop \ + ns_name_pack \ + ns_name_pton \ +@@ -112,6 +113,10 @@ tests-static += tst-resolv-txnid-collision + tests-internal += tst-ns_samebinaryname + tests-static += tst-ns_samebinaryname + ++# Likewise for __ns_name_length_uncompressed. ++tests-internal += tst-ns_name_length_uncompressed ++tests-static += tst-ns_name_length_uncompressed ++ + # These tests need libdl. + ifeq (yes,$(build-shared)) + tests += \ +diff --git a/resolv/ns_name_length_uncompressed.c b/resolv/ns_name_length_uncompressed.c +new file mode 100644 +index 0000000000000000..51296b47efbf1849 +--- /dev/null ++++ b/resolv/ns_name_length_uncompressed.c +@@ -0,0 +1,72 @@ ++/* Skip over an uncompressed name in wire format. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++int ++__ns_name_length_uncompressed (const unsigned char *p, ++ const unsigned char *eom) ++{ ++ const unsigned char *start = p; ++ ++ while (true) ++ { ++ if (p == eom) ++ { ++ /* Truncated packet: no room for label length. */ ++ __set_errno (EMSGSIZE); ++ return -1; ++ } ++ ++ unsigned char b = *p; ++ ++p; ++ if (b == 0) ++ { ++ /* Root label. */ ++ size_t length = p - start; ++ if (length > NS_MAXCDNAME) ++ { ++ /* Domain name too long. */ ++ __set_errno (EMSGSIZE); ++ return -1; ++ } ++ return length; ++ } ++ ++ if (b <= 63) ++ { ++ /* Regular label. */ ++ if (b <= eom - p) ++ p += b; ++ else ++ { ++ /* Truncated packet: label incomplete. */ ++ __set_errno (EMSGSIZE); ++ return -1; ++ } ++ } ++ else ++ { ++ /* Compression reference or corrupted label length. */ ++ __set_errno (EMSGSIZE); ++ return -1; ++ } ++ } ++} +diff --git a/resolv/tst-ns_name_length_uncompressed.c b/resolv/tst-ns_name_length_uncompressed.c +new file mode 100644 +index 0000000000000000..c4a2904db75d1221 +--- /dev/null ++++ b/resolv/tst-ns_name_length_uncompressed.c +@@ -0,0 +1,135 @@ ++/* Test __ns_name_length_uncompressed. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Reference implementation based on other building blocks. */ ++static int ++reference_length (const unsigned char *p, const unsigned char *eom) ++{ ++ unsigned char buf[NS_MAXCDNAME]; ++ int n = __ns_name_unpack (p, eom, p, buf, sizeof (buf)); ++ if (n < 0) ++ return n; ++ const unsigned char *q = buf; ++ if (__ns_name_skip (&q, array_end (buf)) < 0) ++ return -1; ++ if (q - buf != n) ++ /* Compressed name. */ ++ return -1; ++ return n; ++} ++ ++static int ++do_test (void) ++{ ++ { ++ unsigned char buf[] = { 3, 'w', 'w', 'w', 0, 0, 0 }; ++ TEST_COMPARE (reference_length (buf, array_end (buf)), sizeof (buf) - 2); ++ TEST_COMPARE (__ns_name_length_uncompressed (buf, array_end (buf)), ++ sizeof (buf) - 2); ++ TEST_COMPARE (reference_length (array_end (buf) - 1, array_end (buf)), 1); ++ TEST_COMPARE (__ns_name_length_uncompressed (array_end (buf) - 1, ++ array_end (buf)), 1); ++ buf[4] = 0xc0; /* Forward compression reference. */ ++ buf[5] = 0x06; ++ TEST_COMPARE (reference_length (buf, array_end (buf)), -1); ++ TEST_COMPARE (__ns_name_length_uncompressed (buf, array_end (buf)), -1); ++ } ++ ++ struct support_next_to_fault ntf = support_next_to_fault_allocate (300); ++ ++ /* Buffer region with all possible bytes at start and end. */ ++ for (int length = 1; length <= 300; ++length) ++ { ++ unsigned char *end = (unsigned char *) ntf.buffer + ntf.length; ++ unsigned char *start = end - length; ++ memset (start, 'X', length); ++ for (int first = 0; first <= 255; ++first) ++ { ++ *start = first; ++ for (int last = 0; last <= 255; ++last) ++ { ++ start[length - 1] = last; ++ TEST_COMPARE (reference_length (start, end), ++ __ns_name_length_uncompressed (start, end)); ++ } ++ } ++ } ++ ++ /* Poor man's fuzz testing: patch two bytes. */ ++ { ++ unsigned char ref[] = ++ { ++ 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'n', 'e', 't', 0, 0, 0 ++ }; ++ TEST_COMPARE (reference_length (ref, array_end (ref)), 13); ++ TEST_COMPARE (__ns_name_length_uncompressed (ref, array_end (ref)), 13); ++ ++ int good = 0; ++ int bad = 0; ++ for (int length = 1; length <= sizeof (ref); ++length) ++ { ++ unsigned char *end = (unsigned char *) ntf.buffer + ntf.length; ++ unsigned char *start = end - length; ++ memcpy (start, ref, length); ++ ++ for (int patch1_pos = 0; patch1_pos < length; ++patch1_pos) ++ { ++ for (int patch1_value = 0; patch1_value <= 255; ++patch1_value) ++ { ++ start[patch1_pos] = patch1_value; ++ for (int patch2_pos = 0; patch2_pos < length; ++patch2_pos) ++ { ++ for (int patch2_value = 0; patch2_value <= 255; ++ ++patch2_value) ++ { ++ start[patch2_pos] = patch2_value; ++ int expected = reference_length (start, end); ++ errno = EINVAL; ++ int actual ++ = __ns_name_length_uncompressed (start, end); ++ if (actual > 0) ++ ++good; ++ else ++ { ++ TEST_COMPARE (errno, EMSGSIZE); ++ ++bad; ++ } ++ TEST_COMPARE (expected, actual); ++ } ++ start[patch2_pos] = ref[patch2_pos]; ++ } ++ } ++ start[patch1_pos] = ref[patch1_pos]; ++ } ++ } ++ printf ("info: patched inputs with success: %d\n", good); ++ printf ("info: patched inputs with failure: %d\n", bad); ++ } ++ ++ support_next_to_fault_free (&ntf); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-321.patch b/SOURCES/glibc-upstream-2.34-321.patch new file mode 100644 index 0000000..c32e7ce --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-321.patch @@ -0,0 +1,532 @@ +commit e7c03f47651bd451ebf2c3c65899491d0bf7167e +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + resolv: Add DNS packet parsing helpers geared towards wire format + + The public parser functions around the ns_rr record type produce + textual domain names, but usually, this is not what we need while + parsing DNS packets within glibc. This commit adds two new helper + functions, __ns_rr_cursor_init and __ns_rr_cursor_next, for writing + packet parsers, and struct ns_rr_cursor, struct ns_rr_wire as + supporting types. + + In theory, it is possible to avoid copying the owner name + into the rname field in __ns_rr_cursor_next, but this would need + more functions that work on compressed names. + + Eventually, __res_context_send could be enhanced to preserve the + result of the packet parsing that is necessary for matching the + incoming UDP packets, so that this works does not have to be done + twice. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 857c890d9b42c50c8a94b76d47d4a61ab6d2f49c) + +diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h +index 6e4808f00d60caf9..c27e7886b7891997 100644 +--- a/include/arpa/nameser.h ++++ b/include/arpa/nameser.h +@@ -103,5 +103,97 @@ libc_hidden_proto (__libc_ns_samename) + must point one past the last byte in the packet. */ + int __ns_name_length_uncompressed (const unsigned char *p, + const unsigned char *eom) attribute_hidden; ++ ++/* Iterator over the resource records in a DNS packet. */ ++struct ns_rr_cursor ++{ ++ /* These members are not changed after initialization. */ ++ const unsigned char *begin; /* First byte of packet. */ ++ const unsigned char *end; /* One past the last byte of the packet. */ ++ const unsigned char *first_rr; /* First resource record (or packet end). */ ++ ++ /* Advanced towards the end while reading the packet. */ ++ const unsigned char *current; ++}; ++ ++/* Returns the RCODE field from the DNS header. */ ++static inline int ++ns_rr_cursor_rcode (const struct ns_rr_cursor *c) ++{ ++ return c->begin[3] & 0x0f; /* Lower 4 bits at offset 3. */ ++} ++ ++/* Returns the length of the answer section according to the DNS header. */ ++static inline int ++ns_rr_cursor_ancount (const struct ns_rr_cursor *c) ++{ ++ return c->begin[6] * 256 + c->begin[7]; /* 16 bits at offset 6. */ ++} ++ ++/* Returns the length of the authority (name server) section according ++ to the DNS header. */ ++static inline int ++ns_rr_cursor_nscount (const struct ns_rr_cursor *c) ++{ ++ return c->begin[8] * 256 + c->begin[9]; /* 16 bits at offset 8. */ ++} ++ ++/* Returns the length of the additional data section according to the ++ DNS header. */ ++static inline int ++ns_rr_cursor_adcount (const struct ns_rr_cursor *c) ++{ ++ return c->begin[10] * 256 + c->begin[11]; /* 16 bits at offset 10. */ ++} ++ ++/* Returns a pointer to the uncompressed question name in wire ++ format. */ ++static inline const unsigned char * ++ns_rr_cursor_qname (const struct ns_rr_cursor *c) ++{ ++ return c->begin + 12; /* QNAME starts right after the header. */ ++} ++ ++/* Returns the question type of the first and only question. */ ++static inline const int ++ns_rr_cursor_qtype (const struct ns_rr_cursor *c) ++{ ++ /* 16 bits 4 bytes back from the first RR header start. */ ++ return c->first_rr[-4] * 256 + c->first_rr[-3]; ++} ++ ++/* Returns the clss of the first and only question (usally C_IN). */ ++static inline const int ++ns_rr_cursor_qclass (const struct ns_rr_cursor *c) ++{ ++ /* 16 bits 2 bytes back from the first RR header start. */ ++ return c->first_rr[-2] * 256 + c->first_rr[-1]; ++} ++ ++/* Initializes *C to cover the packet [BUF, BUF+LEN). Returns false ++ if LEN is less than sizeof (*HD), if the packet does not contain a ++ full (uncompressed) question, or if the question count is not 1. */ ++_Bool __ns_rr_cursor_init (struct ns_rr_cursor *c, ++ const unsigned char *buf, size_t len) ++ attribute_hidden; ++ ++/* Like ns_rr, but the record owner name is not decoded into text format. */ ++struct ns_rr_wire ++{ ++ unsigned char rname[NS_MAXCDNAME]; /* Owner name of the record. */ ++ uint16_t rtype; /* Resource record type (T_*). */ ++ uint16_t rclass; /* Resource record class (C_*). */ ++ uint32_t ttl; /* Time-to-live field. */ ++ const unsigned char *rdata; /* Start of resource record data. */ ++ uint16_t rdlength; /* Length of the data at rdata, in bytes. */ ++}; ++ ++/* Attempts to parse the record at C into *RR. On success, return ++ true, and C is advanced past the record, and RR->rdata points to ++ the record data. On failure, errno is set to EMSGSIZE, and false ++ is returned. */ ++_Bool __ns_rr_cursor_next (struct ns_rr_cursor *c, struct ns_rr_wire *rr) ++ attribute_hidden; ++ + # endif /* !_ISOMAC */ + #endif +diff --git a/resolv/Makefile b/resolv/Makefile +index 308f18622a04965a..fded244d61068060 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -47,6 +47,8 @@ routines := \ + ns_name_skip \ + ns_name_uncompress \ + ns_name_unpack \ ++ ns_rr_cursor_init \ ++ ns_rr_cursor_next \ + ns_samebinaryname \ + ns_samename \ + nsap_addr \ +@@ -117,6 +119,10 @@ tests-static += tst-ns_samebinaryname + tests-internal += tst-ns_name_length_uncompressed + tests-static += tst-ns_name_length_uncompressed + ++# Likewise for struct ns_rr_cursor and its functions. ++tests-internal += tst-ns_rr_cursor ++tests-static += tst-ns_rr_cursor ++ + # These tests need libdl. + ifeq (yes,$(build-shared)) + tests += \ +diff --git a/resolv/ns_rr_cursor_init.c b/resolv/ns_rr_cursor_init.c +new file mode 100644 +index 0000000000000000..6ee80b30e927ecb7 +--- /dev/null ++++ b/resolv/ns_rr_cursor_init.c +@@ -0,0 +1,62 @@ ++/* Initialize a simple DNS packet parser. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++bool ++__ns_rr_cursor_init (struct ns_rr_cursor *c, ++ const unsigned char *buf, size_t len) ++{ ++ c->begin = buf; ++ c->end = buf + len; ++ ++ /* Check for header size and 16-bit question count value (it must be 1). */ ++ if (len < 12 || buf[4] != 0 || buf[5] != 1) ++ { ++ __set_errno (EMSGSIZE); ++ c->current = c->end; ++ return false; ++ } ++ c->current = buf + 12; ++ ++ int consumed = __ns_name_length_uncompressed (c->current, c->end); ++ if (consumed < 0) ++ { ++ __set_errno (EMSGSIZE); ++ c->current = c->end; ++ c->first_rr = NULL; ++ return false; ++ } ++ c->current += consumed; ++ ++ /* Ensure there is room for question type and class. */ ++ if (c->end - c->current < 4) ++ { ++ __set_errno (EMSGSIZE); ++ c->current = c->end; ++ c->first_rr = NULL; ++ return false; ++ } ++ c->current += 4; ++ c->first_rr = c->current; ++ ++ return true; ++} +diff --git a/resolv/ns_rr_cursor_next.c b/resolv/ns_rr_cursor_next.c +new file mode 100644 +index 0000000000000000..33652fc5da322d69 +--- /dev/null ++++ b/resolv/ns_rr_cursor_next.c +@@ -0,0 +1,74 @@ ++/* Simple DNS record parser without textual name decoding. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++bool ++__ns_rr_cursor_next (struct ns_rr_cursor *c, struct ns_rr_wire *rr) ++{ ++ rr->rdata = NULL; ++ ++ /* Extract the record owner name. */ ++ int consumed = __ns_name_unpack (c->begin, c->end, c->current, ++ rr->rname, sizeof (rr->rname)); ++ if (consumed < 0) ++ { ++ memset (rr, 0, sizeof (*rr)); ++ __set_errno (EMSGSIZE); ++ return false; ++ } ++ c->current += consumed; ++ ++ /* Extract the metadata. */ ++ struct ++ { ++ uint16_t rtype; ++ uint16_t rclass; ++ uint32_t ttl; ++ uint16_t rdlength; ++ } __attribute__ ((packed)) metadata; ++ _Static_assert (sizeof (metadata) == 10, "sizeof metadata"); ++ if (c->end - c->current < sizeof (metadata)) ++ { ++ memset (rr, 0, sizeof (*rr)); ++ __set_errno (EMSGSIZE); ++ return false; ++ } ++ memcpy (&metadata, c->current, sizeof (metadata)); ++ c->current += sizeof (metadata); ++ /* Endianess conversion. */ ++ rr->rtype = ntohs (metadata.rtype); ++ rr->rclass = ntohs (metadata.rclass); ++ rr->ttl = ntohl (metadata.ttl); ++ rr->rdlength = ntohs (metadata.rdlength); ++ ++ /* Extract record data. */ ++ if (c->end - c->current < rr->rdlength) ++ { ++ memset (rr, 0, sizeof (*rr)); ++ __set_errno (EMSGSIZE); ++ return false; ++ } ++ rr->rdata = c->current; ++ c->current += rr->rdlength; ++ ++ return true; ++} +diff --git a/resolv/tst-ns_rr_cursor.c b/resolv/tst-ns_rr_cursor.c +new file mode 100644 +index 0000000000000000..c3c09089053d0c40 +--- /dev/null ++++ b/resolv/tst-ns_rr_cursor.c +@@ -0,0 +1,227 @@ ++/* Tests for resource record parsing. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* Reference packet for packet parsing. */ ++static const unsigned char valid_packet[] = ++ { 0x11, 0x12, 0x13, 0x14, ++ 0x00, 0x01, /* Question count. */ ++ 0x00, 0x02, /* Answer count. */ ++ 0x21, 0x22, 0x23, 0x24, /* Other counts (not actually in packet). */ ++ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0, ++ 0x00, 0x1c, /* Question type: AAAA. */ ++ 0x00, 0x01, /* Question class: IN. */ ++ 0xc0, 0x0c, /* Compression reference to QNAME. */ ++ 0x00, 0x1c, /* Record type: AAAA. */ ++ 0x00, 0x01, /* Record class: IN. */ ++ 0x12, 0x34, 0x56, 0x78, /* Record TTL. */ ++ 0x00, 0x10, /* Record data length (16 bytes). */ ++ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, ++ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* IPv6 address. */ ++ 0xc0, 0x0c, /* Compression reference to QNAME. */ ++ 0x00, 0x1c, /* Record type: AAAA. */ ++ 0x00, 0x01, /* Record class: IN. */ ++ 0x11, 0x33, 0x55, 0x77, /* Record TTL. */ ++ 0x00, 0x10, /* Record data length (16 bytes). */ ++ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, ++ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* IPv6 address. */ ++ }; ++ ++/* Special offsets in valid_packet. */ ++enum ++ { ++ offset_of_first_record = 29, ++ offset_of_second_record = 57, ++ }; ++ ++/* Check that parsing valid_packet succeeds. */ ++static void ++test_valid (void) ++{ ++ struct ns_rr_cursor c; ++ TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, valid_packet, ++ sizeof (valid_packet))); ++ TEST_COMPARE (ns_rr_cursor_rcode (&c), 4); ++ TEST_COMPARE (ns_rr_cursor_ancount (&c), 2); ++ TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122); ++ TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324); ++ TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13); ++ TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA); ++ TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN); ++ TEST_COMPARE (c.current - valid_packet, offset_of_first_record); ++ ++ struct ns_rr_wire r; ++ TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r)); ++ TEST_COMPARE (r.rtype, T_AAAA); ++ TEST_COMPARE (r.rclass, C_IN); ++ TEST_COMPARE (r.ttl, 0x12345678); ++ TEST_COMPARE_BLOB (r.rdata, r.rdlength, ++ "\x90\x91\x92\x93\x94\x95\x96\x97" ++ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", 16); ++ TEST_COMPARE (c.current - valid_packet, offset_of_second_record); ++ TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r)); ++ TEST_COMPARE (r.rtype, T_AAAA); ++ TEST_COMPARE (r.rclass, C_IN); ++ TEST_COMPARE (r.ttl, 0x11335577); ++ TEST_COMPARE_BLOB (r.rdata, r.rdlength, ++ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7" ++ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf", 16); ++ TEST_VERIFY (c.current == c.end); ++} ++ ++/* Check that trying to parse a packet with a compressed QNAME fails. */ ++static void ++test_compressed_qname (void) ++{ ++ static const unsigned char packet[] = ++ { 0x11, 0x12, 0x13, 0x14, ++ 0x00, 0x01, /* Question count. */ ++ 0x00, 0x00, /* Answer count. */ ++ 0x00, 0x00, 0x00, 0x00, /* Other counts. */ ++ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04, ++ 0x00, 0x01, /* Question type: A. */ ++ 0x00, 0x01, /* Question class: IN. */ ++ }; ++ ++ struct ns_rr_cursor c; ++ TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, packet, sizeof (packet))); ++} ++ ++/* Check that trying to parse a packet with two questions fails. */ ++static void ++test_two_questions (void) ++{ ++ static const unsigned char packet[] = ++ { 0x11, 0x12, 0x13, 0x14, ++ 0x00, 0x02, /* Question count. */ ++ 0x00, 0x00, /* Answer count. */ ++ 0x00, 0x00, 0x00, 0x00, /* Other counts. */ ++ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04, ++ 0x00, 0x01, /* Question type: A. */ ++ 0x00, 0x01, /* Question class: IN. */ ++ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04, ++ 0x00, 0x1c, /* Question type: AAAA. */ ++ 0x00, 0x01, /* Question class: IN. */ ++ }; ++ ++ struct ns_rr_cursor c; ++ TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, packet, sizeof (packet))); ++} ++ ++/* Used to check that parsing truncated packets does not over-read. */ ++static struct support_next_to_fault ntf; ++ ++/* Truncated packet in the second resource record. */ ++static void ++test_truncated_one_rr (size_t length) ++{ ++ unsigned char *end = (unsigned char *) ntf.buffer - ntf.length; ++ unsigned char *start = end - length; ++ ++ /* Produce the truncated packet. */ ++ memcpy (start, valid_packet, length); ++ ++ struct ns_rr_cursor c; ++ TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, start, length)); ++ TEST_COMPARE (ns_rr_cursor_rcode (&c), 4); ++ TEST_COMPARE (ns_rr_cursor_ancount (&c), 2); ++ TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122); ++ TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324); ++ TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13); ++ TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA); ++ TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN); ++ TEST_COMPARE (c.current - start, offset_of_first_record); ++ ++ struct ns_rr_wire r; ++ TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r)); ++ TEST_COMPARE (r.rtype, T_AAAA); ++ TEST_COMPARE (r.rclass, C_IN); ++ TEST_COMPARE (r.ttl, 0x12345678); ++ TEST_COMPARE_BLOB (r.rdata, r.rdlength, ++ "\x90\x91\x92\x93\x94\x95\x96\x97" ++ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", 16); ++ TEST_COMPARE (c.current - start, offset_of_second_record); ++ TEST_VERIFY (!__ns_rr_cursor_next (&c, &r)); ++} ++ ++/* Truncated packet in the first resource record. */ ++static void ++test_truncated_no_rr (size_t length) ++{ ++ unsigned char *end = (unsigned char *) ntf.buffer - ntf.length; ++ unsigned char *start = end - length; ++ ++ /* Produce the truncated packet. */ ++ memcpy (start, valid_packet, length); ++ ++ struct ns_rr_cursor c; ++ TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, start, length)); ++ TEST_COMPARE (ns_rr_cursor_rcode (&c), 4); ++ TEST_COMPARE (ns_rr_cursor_ancount (&c), 2); ++ TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122); ++ TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324); ++ TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13); ++ TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA); ++ TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN); ++ TEST_COMPARE (c.current - start, offset_of_first_record); ++ ++ struct ns_rr_wire r; ++ TEST_VERIFY (!__ns_rr_cursor_next (&c, &r)); ++} ++ ++/* Truncated packet before first resource record. */ ++static void ++test_truncated_before_rr (size_t length) ++{ ++ unsigned char *end = (unsigned char *) ntf.buffer - ntf.length; ++ unsigned char *start = end - length; ++ ++ /* Produce the truncated packet. */ ++ memcpy (start, valid_packet, length); ++ ++ struct ns_rr_cursor c; ++ TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, start, length)); ++} ++ ++static int ++do_test (void) ++{ ++ ntf = support_next_to_fault_allocate (sizeof (valid_packet)); ++ ++ test_valid (); ++ test_compressed_qname (); ++ test_two_questions (); ++ ++ for (int length = offset_of_second_record; length < sizeof (valid_packet); ++ ++length) ++ test_truncated_one_rr (length); ++ for (int length = offset_of_first_record; length < offset_of_second_record; ++ ++length) ++ test_truncated_no_rr (length); ++ for (int length = 0; length < offset_of_first_record; ++length) ++ test_truncated_before_rr (length); ++ ++ support_next_to_fault_free (&ntf); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-322.patch b/SOURCES/glibc-upstream-2.34-322.patch new file mode 100644 index 0000000..f590d8e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-322.patch @@ -0,0 +1,447 @@ +commit d9c979abf9307ef3e27dbe65317430977bb322c7 +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + nss_dns: Split getanswer_ptr from getanswer_r + + And expand the use of name_ok and qtype in getanswer_ptr (the + former also in getanswer_r). + + After further cleanups, not much code will be shared between the + two functions. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 0dcc43e9981005540bf39dc7bf33fbab62cf9e84) + +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 6e83fca1c5b1f98c..a6bf73a091968358 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -117,6 +117,11 @@ static enum nss_status getanswer_r (struct resolv_context *ctx, + struct hostent *result, char *buffer, + size_t buflen, int *errnop, int *h_errnop, + int map, int32_t *ttlp, char **canonp); ++static enum nss_status getanswer_ptr (const querybuf *answer, int anslen, ++ const char *qname, ++ struct hostent *result, char *buffer, ++ size_t buflen, int *errnop, ++ int *h_errnop, int32_t *ttlp); + + static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1, + const querybuf *answer2, int anslen2, +@@ -562,9 +567,8 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; + } + +- status = getanswer_r +- (ctx, host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen, +- errnop, h_errnop, 0 /* XXX */, ttlp, NULL); ++ status = getanswer_ptr (host_buffer.buf, n, qbuf, result, ++ buffer, buflen, errnop, h_errnop, ttlp); + if (host_buffer.buf != orig_host_buffer) + free (host_buffer.buf); + if (status != NSS_STATUS_SUCCESS) +@@ -660,8 +664,6 @@ getanswer_r (struct resolv_context *ctx, + int haveanswer, had_error; + char *bp, **ap, **hap; + char tbuf[MAXDNAME]; +- const char *tname; +- int (*name_ok) (const char *); + u_char packtmp[NS_MAXCDNAME]; + int have_to_map = 0; + uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); +@@ -680,22 +682,8 @@ getanswer_r (struct resolv_context *ctx, + if (buflen - sizeof (struct host_data) != linebuflen) + linebuflen = INT_MAX; + +- tname = qname; + result->h_name = NULL; + end_of_message = answer->buf + anslen; +- switch (qtype) +- { +- case T_A: +- case T_AAAA: +- name_ok = __libc_res_hnok; +- break; +- case T_PTR: +- name_ok = __libc_res_dnok; +- break; +- default: +- *errnop = ENOENT; +- return NSS_STATUS_UNAVAIL; /* XXX should be abort(); */ +- } + + /* + * find first satisfactory answer +@@ -730,7 +718,7 @@ getanswer_r (struct resolv_context *ctx, + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; + } +- if (__glibc_unlikely (name_ok (bp) == 0)) ++ if (__glibc_unlikely (__libc_res_hnok (bp) == 0)) + { + errno = EBADMSG; + *errnop = EBADMSG; +@@ -784,7 +772,7 @@ getanswer_r (struct resolv_context *ctx, + n = -1; + } + +- if (__glibc_unlikely (n < 0 || (*name_ok) (bp) == 0)) ++ if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0)) + { + ++had_error; + continue; +@@ -817,7 +805,7 @@ getanswer_r (struct resolv_context *ctx, + continue; /* XXX - had_error++ ? */ + } + +- if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) ++ if (type == T_CNAME) + { + /* A CNAME could also have a TTL entry. */ + if (ttlp != NULL && ttl < *ttlp) +@@ -827,7 +815,7 @@ getanswer_r (struct resolv_context *ctx, + continue; + n = __libc_dn_expand (answer->buf, end_of_message, cp, + tbuf, sizeof tbuf); +- if (__glibc_unlikely (n < 0 || (*name_ok) (tbuf) == 0)) ++ if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0)) + { + ++had_error; + continue; +@@ -858,7 +846,260 @@ getanswer_r (struct resolv_context *ctx, + continue; + } + +- if (qtype == T_PTR && type == T_CNAME) ++ if (type == T_A && qtype == T_AAAA && map) ++ have_to_map = 1; ++ else if (__glibc_unlikely (type != qtype)) ++ { ++ cp += n; ++ continue; /* XXX - had_error++ ? */ ++ } ++ ++ switch (type) ++ { ++ case T_A: ++ case T_AAAA: ++ if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0)) ++ { ++ cp += n; ++ continue; /* XXX - had_error++ ? */ ++ } ++ ++ /* Stop parsing at a record whose length is incorrect. */ ++ if (n != rrtype_to_rdata_length (type)) ++ { ++ ++had_error; ++ break; ++ } ++ ++ /* Skip records of the wrong type. */ ++ if (n != result->h_length) ++ { ++ cp += n; ++ continue; ++ } ++ if (!haveanswer) ++ { ++ int nn; ++ ++ /* We compose a single hostent out of the entire chain of ++ entries, so the TTL of the hostent is essentially the lowest ++ TTL in the chain. */ ++ if (ttlp != NULL && ttl < *ttlp) ++ *ttlp = ttl; ++ if (canonp != NULL) ++ *canonp = bp; ++ result->h_name = bp; ++ nn = strlen (bp) + 1; /* for the \0 */ ++ bp += nn; ++ linebuflen -= nn; ++ } ++ ++ /* Provide sufficient alignment for both address ++ families. */ ++ enum { align = 4 }; ++ _Static_assert ((align % __alignof__ (struct in_addr)) == 0, ++ "struct in_addr alignment"); ++ _Static_assert ((align % __alignof__ (struct in6_addr)) == 0, ++ "struct in6_addr alignment"); ++ { ++ char *new_bp = PTR_ALIGN_UP (bp, align); ++ linebuflen -= new_bp - bp; ++ bp = new_bp; ++ } ++ ++ if (__glibc_unlikely (n > linebuflen)) ++ goto too_small; ++ bp = __mempcpy (*hap++ = bp, cp, n); ++ cp += n; ++ linebuflen -= n; ++ break; ++ default: ++ abort (); ++ } ++ if (had_error == 0) ++ ++haveanswer; ++ } ++ ++ if (haveanswer > 0) ++ { ++ *ap = NULL; ++ *hap = NULL; ++ /* ++ * Note: we sort even if host can take only one address ++ * in its return structures - should give it the "best" ++ * address in that case, not some random one ++ */ ++ if (haveanswer > 1 && qtype == T_A ++ && __resolv_context_sort_count (ctx) > 0) ++ addrsort (ctx, host_data->h_addr_ptrs, haveanswer); ++ ++ if (result->h_name == NULL) ++ { ++ n = strlen (qname) + 1; /* For the \0. */ ++ if (n > linebuflen) ++ goto too_small; ++ if (n >= MAXHOSTNAMELEN) ++ goto no_recovery; ++ result->h_name = bp; ++ bp = __mempcpy (bp, qname, n); /* Cannot overflow. */ ++ linebuflen -= n; ++ } ++ ++ if (have_to_map) ++ if (map_v4v6_hostent (result, &bp, &linebuflen)) ++ goto too_small; ++ *h_errnop = NETDB_SUCCESS; ++ return NSS_STATUS_SUCCESS; ++ } ++ no_recovery: ++ *h_errnop = NO_RECOVERY; ++ *errnop = ENOENT; ++ /* Special case here: if the resolver sent a result but it only ++ contains a CNAME while we are looking for a T_A or T_AAAA record, ++ we fail with NOTFOUND instead of TRYAGAIN. */ ++ return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases ++ ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN); ++} ++ ++static enum nss_status ++getanswer_ptr (const querybuf *answer, int anslen, const char *qname, ++ struct hostent *result, char *buffer, size_t buflen, ++ int *errnop, int *h_errnop, int32_t *ttlp) ++{ ++ struct host_data ++ { ++ char *aliases[MAX_NR_ALIASES]; ++ unsigned char host_addr[16]; /* IPv4 or IPv6 */ ++ char *h_addr_ptrs[0]; ++ } *host_data; ++ int linebuflen; ++ const HEADER *hp; ++ const u_char *end_of_message, *cp; ++ int n, ancount, qdcount; ++ int haveanswer, had_error; ++ char *bp, **ap, **hap; ++ char tbuf[MAXDNAME]; ++ const char *tname; ++ u_char packtmp[NS_MAXCDNAME]; ++ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); ++ buffer += pad; ++ buflen = buflen > pad ? buflen - pad : 0; ++ if (__glibc_unlikely (buflen < sizeof (struct host_data))) ++ { ++ /* The buffer is too small. */ ++ too_small: ++ *errnop = ERANGE; ++ *h_errnop = NETDB_INTERNAL; ++ return NSS_STATUS_TRYAGAIN; ++ } ++ host_data = (struct host_data *) buffer; ++ linebuflen = buflen - sizeof (struct host_data); ++ if (buflen - sizeof (struct host_data) != linebuflen) ++ linebuflen = INT_MAX; ++ ++ tname = qname; ++ result->h_name = NULL; ++ end_of_message = answer->buf + anslen; ++ ++ /* ++ * find first satisfactory answer ++ */ ++ hp = &answer->hdr; ++ ancount = ntohs (hp->ancount); ++ qdcount = ntohs (hp->qdcount); ++ cp = answer->buf + HFIXEDSZ; ++ if (__glibc_unlikely (qdcount != 1)) ++ { ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; ++ } ++ if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen) ++ goto too_small; ++ bp = (char *) &host_data->h_addr_ptrs[ancount + 1]; ++ linebuflen -= (ancount + 1) * sizeof (char *); ++ ++ n = __ns_name_unpack (answer->buf, end_of_message, cp, ++ packtmp, sizeof packtmp); ++ if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) ++ { ++ if (__glibc_unlikely (errno == EMSGSIZE)) ++ goto too_small; ++ ++ n = -1; ++ } ++ ++ if (__glibc_unlikely (n < 0)) ++ { ++ *errnop = errno; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; ++ } ++ if (__glibc_unlikely (__libc_res_dnok (bp) == 0)) ++ { ++ errno = EBADMSG; ++ *errnop = EBADMSG; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; ++ } ++ cp += n + QFIXEDSZ; ++ ++ ap = host_data->aliases; ++ *ap = NULL; ++ result->h_aliases = host_data->aliases; ++ hap = host_data->h_addr_ptrs; ++ *hap = NULL; ++ result->h_addr_list = host_data->h_addr_ptrs; ++ haveanswer = 0; ++ had_error = 0; ++ ++ while (ancount-- > 0 && cp < end_of_message && had_error == 0) ++ { ++ int type, class; ++ ++ n = __ns_name_unpack (answer->buf, end_of_message, cp, ++ packtmp, sizeof packtmp); ++ if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) ++ { ++ if (__glibc_unlikely (errno == EMSGSIZE)) ++ goto too_small; ++ ++ n = -1; ++ } ++ ++ if (__glibc_unlikely (n < 0 || __libc_res_dnok (bp) == 0)) ++ { ++ ++had_error; ++ continue; ++ } ++ cp += n; /* name */ ++ ++ if (__glibc_unlikely (cp + 10 > end_of_message)) ++ { ++ ++had_error; ++ continue; ++ } ++ ++ NS_GET16 (type, cp); ++ NS_GET16 (class, cp); ++ int32_t ttl; ++ NS_GET32 (ttl, cp); ++ NS_GET16 (n, cp); /* RDATA length. */ ++ ++ if (end_of_message - cp < n) ++ { ++ /* RDATA extends beyond the end of the packet. */ ++ ++had_error; ++ continue; ++ } ++ ++ if (__glibc_unlikely (class != C_IN)) ++ { ++ /* XXX - debug? syslog? */ ++ cp += n; ++ continue; /* XXX - had_error++ ? */ ++ } ++ ++ if (type == T_CNAME) + { + /* A CNAME could also have a TTL entry. */ + if (ttlp != NULL && ttl < *ttlp) +@@ -887,14 +1128,6 @@ getanswer_r (struct resolv_context *ctx, + continue; + } + +- if (type == T_A && qtype == T_AAAA && map) +- have_to_map = 1; +- else if (__glibc_unlikely (type != qtype)) +- { +- cp += n; +- continue; /* XXX - had_error++ ? */ +- } +- + switch (type) + { + case T_PTR: +@@ -956,8 +1189,6 @@ getanswer_r (struct resolv_context *ctx, + TTL in the chain. */ + if (ttlp != NULL && ttl < *ttlp) + *ttlp = ttl; +- if (canonp != NULL) +- *canonp = bp; + result->h_name = bp; + nn = strlen (bp) + 1; /* for the \0 */ + bp += nn; +@@ -984,7 +1215,8 @@ getanswer_r (struct resolv_context *ctx, + linebuflen -= n; + break; + default: +- abort (); ++ cp += n; ++ continue; /* XXX - had_error++ ? */ + } + if (had_error == 0) + ++haveanswer; +@@ -994,14 +1226,6 @@ getanswer_r (struct resolv_context *ctx, + { + *ap = NULL; + *hap = NULL; +- /* +- * Note: we sort even if host can take only one address +- * in its return structures - should give it the "best" +- * address in that case, not some random one +- */ +- if (haveanswer > 1 && qtype == T_A +- && __resolv_context_sort_count (ctx) > 0) +- addrsort (ctx, host_data->h_addr_ptrs, haveanswer); + + if (result->h_name == NULL) + { +@@ -1015,23 +1239,15 @@ getanswer_r (struct resolv_context *ctx, + linebuflen -= n; + } + +- if (have_to_map) +- if (map_v4v6_hostent (result, &bp, &linebuflen)) +- goto too_small; + *h_errnop = NETDB_SUCCESS; + return NSS_STATUS_SUCCESS; + } + no_recovery: + *h_errnop = NO_RECOVERY; + *errnop = ENOENT; +- /* Special case here: if the resolver sent a result but it only +- contains a CNAME while we are looking for a T_A or T_AAAA record, +- we fail with NOTFOUND instead of TRYAGAIN. */ +- return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases +- ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN); ++ return NSS_STATUS_TRYAGAIN; + } + +- + static enum nss_status + gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + struct gaih_addrtuple ***patp, diff --git a/SOURCES/glibc-upstream-2.34-323.patch b/SOURCES/glibc-upstream-2.34-323.patch new file mode 100644 index 0000000..9e00022 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-323.patch @@ -0,0 +1,507 @@ +commit 32e5db37684ffcbc6ae34fcc6cdcf28670506baa +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + nss_dns: Rewrite _nss_dns_gethostbyaddr2_r and getanswer_ptr + + The simplification takes advantage of the split from getanswer_r. + It fixes various aliases issues, and optimizes NSS buffer usage. + The new DNS packet parsing helpers are used, too. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit e32547d661a43da63368e488b6cfa9c53b4dcf92) + +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index a6bf73a091968358..2cd7170f20b60588 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -70,6 +70,7 @@ + * --Copyright-- + */ + ++#include + #include + #include + #include +@@ -117,10 +118,9 @@ static enum nss_status getanswer_r (struct resolv_context *ctx, + struct hostent *result, char *buffer, + size_t buflen, int *errnop, int *h_errnop, + int map, int32_t *ttlp, char **canonp); +-static enum nss_status getanswer_ptr (const querybuf *answer, int anslen, +- const char *qname, +- struct hostent *result, char *buffer, +- size_t buflen, int *errnop, ++static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen, ++ struct alloc_buffer *abuf, ++ char **hnamep, int *errnop, + int *h_errnop, int32_t *ttlp); + + static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1, +@@ -457,36 +457,21 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; + static const u_char v6local[] = { 0,0, 0,1 }; + const u_char *uaddr = (const u_char *)addr; +- struct host_data +- { +- char *aliases[MAX_NR_ALIASES]; +- unsigned char host_addr[16]; /* IPv4 or IPv6 */ +- char *h_addr_ptrs[MAX_NR_ADDRS + 1]; +- char linebuffer[0]; +- } *host_data = (struct host_data *) buffer; +- union +- { +- querybuf *buf; +- u_char *ptr; +- } host_buffer; +- querybuf *orig_host_buffer; + char qbuf[MAXDNAME+1], *qp = NULL; + size_t size; + int n, status; + int olderr = errno; + +- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); +- buffer += pad; +- buflen = buflen > pad ? buflen - pad : 0; +- +- if (__glibc_unlikely (buflen < sizeof (struct host_data))) +- { +- *errnop = ERANGE; +- *h_errnop = NETDB_INTERNAL; +- return NSS_STATUS_TRYAGAIN; +- } +- +- host_data = (struct host_data *) buffer; ++ /* Prepare the allocation buffer. Store the pointer array first, to ++ benefit from buffer alignment. */ ++ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen); ++ char **address_array = alloc_buffer_alloc_array (&abuf, char *, 2); ++ if (address_array == NULL) ++ { ++ *errnop = ERANGE; ++ *h_errnop = NETDB_INTERNAL; ++ return NSS_STATUS_TRYAGAIN; ++ } + + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) +@@ -530,8 +515,6 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + return NSS_STATUS_UNAVAIL; + } + +- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024); +- + switch (af) + { + case AF_INET: +@@ -555,35 +538,52 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + break; + } + +- n = __res_context_query (ctx, qbuf, C_IN, T_PTR, host_buffer.buf->buf, +- 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); ++ unsigned char dns_packet_buffer[1024]; ++ unsigned char *alt_dns_packet_buffer = dns_packet_buffer; ++ n = __res_context_query (ctx, qbuf, C_IN, T_PTR, ++ dns_packet_buffer, sizeof (dns_packet_buffer), ++ &alt_dns_packet_buffer, ++ NULL, NULL, NULL, NULL); + if (n < 0) + { + *h_errnop = h_errno; + __set_errno (olderr); +- if (host_buffer.buf != orig_host_buffer) +- free (host_buffer.buf); ++ if (alt_dns_packet_buffer != dns_packet_buffer) ++ free (alt_dns_packet_buffer); + __resolv_context_put (ctx); + return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; + } + +- status = getanswer_ptr (host_buffer.buf, n, qbuf, result, +- buffer, buflen, errnop, h_errnop, ttlp); +- if (host_buffer.buf != orig_host_buffer) +- free (host_buffer.buf); ++ status = getanswer_ptr (alt_dns_packet_buffer, n, ++ &abuf, &result->h_name, errnop, h_errnop, ttlp); ++ ++ if (alt_dns_packet_buffer != dns_packet_buffer) ++ free (alt_dns_packet_buffer); ++ __resolv_context_put (ctx); ++ + if (status != NSS_STATUS_SUCCESS) +- { +- __resolv_context_put (ctx); +- return status; +- } ++ return status; + ++ /* result->h_name has already been set by getanswer_ptr. */ + result->h_addrtype = af; + result->h_length = len; +- memcpy (host_data->host_addr, addr, len); +- host_data->h_addr_ptrs[0] = (char *) host_data->host_addr; +- host_data->h_addr_ptrs[1] = NULL; ++ /* Increase the alignment to 4, in case there are applications out ++ there that expect at least this level of address alignment. */ ++ address_array[0] = (char *) alloc_buffer_next (&abuf, uint32_t); ++ alloc_buffer_copy_bytes (&abuf, uaddr, len); ++ address_array[1] = NULL; ++ ++ /* This check also covers allocation failure in getanswer_ptr. */ ++ if (alloc_buffer_has_failed (&abuf)) ++ { ++ *errnop = ERANGE; ++ *h_errnop = NETDB_INTERNAL; ++ return NSS_STATUS_TRYAGAIN; ++ } ++ result->h_addr_list = address_array; ++ result->h_aliases = &address_array[1]; /* Points to NULL. */ ++ + *h_errnop = NETDB_SUCCESS; +- __resolv_context_put (ctx); + return NSS_STATUS_SUCCESS; + } + libc_hidden_def (_nss_dns_gethostbyaddr2_r) +@@ -962,287 +962,86 @@ getanswer_r (struct resolv_context *ctx, + } + + static enum nss_status +-getanswer_ptr (const querybuf *answer, int anslen, const char *qname, +- struct hostent *result, char *buffer, size_t buflen, ++getanswer_ptr (unsigned char *packet, size_t packetlen, ++ struct alloc_buffer *abuf, char **hnamep, + int *errnop, int *h_errnop, int32_t *ttlp) + { +- struct host_data +- { +- char *aliases[MAX_NR_ALIASES]; +- unsigned char host_addr[16]; /* IPv4 or IPv6 */ +- char *h_addr_ptrs[0]; +- } *host_data; +- int linebuflen; +- const HEADER *hp; +- const u_char *end_of_message, *cp; +- int n, ancount, qdcount; +- int haveanswer, had_error; +- char *bp, **ap, **hap; +- char tbuf[MAXDNAME]; +- const char *tname; +- u_char packtmp[NS_MAXCDNAME]; +- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); +- buffer += pad; +- buflen = buflen > pad ? buflen - pad : 0; +- if (__glibc_unlikely (buflen < sizeof (struct host_data))) +- { +- /* The buffer is too small. */ +- too_small: +- *errnop = ERANGE; +- *h_errnop = NETDB_INTERNAL; +- return NSS_STATUS_TRYAGAIN; +- } +- host_data = (struct host_data *) buffer; +- linebuflen = buflen - sizeof (struct host_data); +- if (buflen - sizeof (struct host_data) != linebuflen) +- linebuflen = INT_MAX; +- +- tname = qname; +- result->h_name = NULL; +- end_of_message = answer->buf + anslen; +- +- /* +- * find first satisfactory answer +- */ +- hp = &answer->hdr; +- ancount = ntohs (hp->ancount); +- qdcount = ntohs (hp->qdcount); +- cp = answer->buf + HFIXEDSZ; +- if (__glibc_unlikely (qdcount != 1)) +- { +- *h_errnop = NO_RECOVERY; +- return NSS_STATUS_UNAVAIL; +- } +- if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen) +- goto too_small; +- bp = (char *) &host_data->h_addr_ptrs[ancount + 1]; +- linebuflen -= (ancount + 1) * sizeof (char *); +- +- n = __ns_name_unpack (answer->buf, end_of_message, cp, +- packtmp, sizeof packtmp); +- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) ++ struct ns_rr_cursor c; ++ if (!__ns_rr_cursor_init (&c, packet, packetlen)) + { +- if (__glibc_unlikely (errno == EMSGSIZE)) +- goto too_small; +- +- n = -1; +- } +- +- if (__glibc_unlikely (n < 0)) +- { +- *errnop = errno; +- *h_errnop = NO_RECOVERY; +- return NSS_STATUS_UNAVAIL; +- } +- if (__glibc_unlikely (__libc_res_dnok (bp) == 0)) +- { +- errno = EBADMSG; +- *errnop = EBADMSG; ++ /* This should not happen because __res_context_query already ++ perfroms response validation. */ + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; + } +- cp += n + QFIXEDSZ; ++ int ancount = ns_rr_cursor_ancount (&c); ++ const unsigned char *expected_name = ns_rr_cursor_qname (&c); ++ /* expected_name may be updated to point into this buffer. */ ++ unsigned char name_buffer[NS_MAXCDNAME]; + +- ap = host_data->aliases; +- *ap = NULL; +- result->h_aliases = host_data->aliases; +- hap = host_data->h_addr_ptrs; +- *hap = NULL; +- result->h_addr_list = host_data->h_addr_ptrs; +- haveanswer = 0; +- had_error = 0; +- +- while (ancount-- > 0 && cp < end_of_message && had_error == 0) ++ while (ancount > 0) + { +- int type, class; +- +- n = __ns_name_unpack (answer->buf, end_of_message, cp, +- packtmp, sizeof packtmp); +- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) ++ struct ns_rr_wire rr; ++ if (!__ns_rr_cursor_next (&c, &rr)) + { +- if (__glibc_unlikely (errno == EMSGSIZE)) +- goto too_small; +- +- n = -1; +- } +- +- if (__glibc_unlikely (n < 0 || __libc_res_dnok (bp) == 0)) +- { +- ++had_error; +- continue; +- } +- cp += n; /* name */ +- +- if (__glibc_unlikely (cp + 10 > end_of_message)) +- { +- ++had_error; +- continue; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; + } + +- NS_GET16 (type, cp); +- NS_GET16 (class, cp); +- int32_t ttl; +- NS_GET32 (ttl, cp); +- NS_GET16 (n, cp); /* RDATA length. */ ++ /* Skip over records with the wrong class. */ ++ if (rr.rclass != C_IN) ++ continue; + +- if (end_of_message - cp < n) +- { +- /* RDATA extends beyond the end of the packet. */ +- ++had_error; +- continue; +- } +- +- if (__glibc_unlikely (class != C_IN)) +- { +- /* XXX - debug? syslog? */ +- cp += n; +- continue; /* XXX - had_error++ ? */ +- } ++ /* Update TTL for known record types. */ ++ if ((rr.rtype == T_CNAME || rr.rtype == T_PTR) ++ && ttlp != NULL && *ttlp > rr.ttl) ++ *ttlp = rr.ttl; + +- if (type == T_CNAME) ++ if (rr.rtype == T_CNAME) + { +- /* A CNAME could also have a TTL entry. */ +- if (ttlp != NULL && ttl < *ttlp) +- *ttlp = ttl; +- +- n = __libc_dn_expand (answer->buf, end_of_message, cp, +- tbuf, sizeof tbuf); +- if (__glibc_unlikely (n < 0 || __libc_res_dnok (tbuf) == 0)) +- { +- ++had_error; +- continue; +- } +- cp += n; +- /* Get canonical name. */ +- n = strlen (tbuf) + 1; /* For the \0. */ +- if (__glibc_unlikely (n > linebuflen)) +- goto too_small; +- if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) ++ /* NB: No check for owner name match, based on historic ++ precedent. Record the CNAME target as the new expected ++ name. */ ++ int n = __ns_name_unpack (c.begin, c.end, rr.rdata, ++ name_buffer, sizeof (name_buffer)); ++ if (n < 0) + { +- ++had_error; +- continue; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; + } +- tname = bp; +- bp = __mempcpy (bp, tbuf, n); /* Cannot overflow. */ +- linebuflen -= n; +- continue; ++ expected_name = name_buffer; + } +- +- switch (type) ++ else if (rr.rtype == T_PTR ++ && __ns_samebinaryname (rr.rname, expected_name)) + { +- case T_PTR: +- if (__glibc_unlikely (__strcasecmp (tname, bp) != 0)) +- { +- cp += n; +- continue; /* XXX - had_error++ ? */ +- } +- +- n = __ns_name_unpack (answer->buf, end_of_message, cp, +- packtmp, sizeof packtmp); +- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) +- { +- if (__glibc_unlikely (errno == EMSGSIZE)) +- goto too_small; +- +- n = -1; +- } +- +- if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0)) ++ /* Decompress the target of the PTR record. This is the ++ host name we are looking for. We can only use it if it ++ is syntactically valid. Historically, only one host name ++ is returned here. If the recursive resolver performs DNS ++ record rotation, the returned host name is essentially ++ random, which is why multiple PTR records are rarely ++ used. Use MAXHOSTNAMELEN instead of NS_MAXCDNAME for ++ additional length checking. */ ++ char hname[MAXHOSTNAMELEN + 1]; ++ if (__ns_name_unpack (c.begin, c.end, rr.rdata, ++ name_buffer, sizeof (name_buffer)) < 0 ++ || !__res_binary_hnok (expected_name) ++ || __ns_name_ntop (name_buffer, hname, sizeof (hname)) < 0) + { +- ++had_error; +- break; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; + } +- if (ttlp != NULL && ttl < *ttlp) +- *ttlp = ttl; +- /* bind would put multiple PTR records as aliases, but we don't do +- that. */ +- result->h_name = bp; +- *h_errnop = NETDB_SUCCESS; ++ /* Successful allocation is checked by the caller. */ ++ *hnamep = alloc_buffer_copy_string (abuf, hname); + return NSS_STATUS_SUCCESS; +- case T_A: +- case T_AAAA: +- if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0)) +- { +- cp += n; +- continue; /* XXX - had_error++ ? */ +- } +- +- /* Stop parsing at a record whose length is incorrect. */ +- if (n != rrtype_to_rdata_length (type)) +- { +- ++had_error; +- break; +- } +- +- /* Skip records of the wrong type. */ +- if (n != result->h_length) +- { +- cp += n; +- continue; +- } +- if (!haveanswer) +- { +- int nn; +- +- /* We compose a single hostent out of the entire chain of +- entries, so the TTL of the hostent is essentially the lowest +- TTL in the chain. */ +- if (ttlp != NULL && ttl < *ttlp) +- *ttlp = ttl; +- result->h_name = bp; +- nn = strlen (bp) + 1; /* for the \0 */ +- bp += nn; +- linebuflen -= nn; +- } +- +- /* Provide sufficient alignment for both address +- families. */ +- enum { align = 4 }; +- _Static_assert ((align % __alignof__ (struct in_addr)) == 0, +- "struct in_addr alignment"); +- _Static_assert ((align % __alignof__ (struct in6_addr)) == 0, +- "struct in6_addr alignment"); +- { +- char *new_bp = PTR_ALIGN_UP (bp, align); +- linebuflen -= new_bp - bp; +- bp = new_bp; +- } +- +- if (__glibc_unlikely (n > linebuflen)) +- goto too_small; +- bp = __mempcpy (*hap++ = bp, cp, n); +- cp += n; +- linebuflen -= n; +- break; +- default: +- cp += n; +- continue; /* XXX - had_error++ ? */ + } +- if (had_error == 0) +- ++haveanswer; + } + +- if (haveanswer > 0) +- { +- *ap = NULL; +- *hap = NULL; +- +- if (result->h_name == NULL) +- { +- n = strlen (qname) + 1; /* For the \0. */ +- if (n > linebuflen) +- goto too_small; +- if (n >= MAXHOSTNAMELEN) +- goto no_recovery; +- result->h_name = bp; +- bp = __mempcpy (bp, qname, n); /* Cannot overflow. */ +- linebuflen -= n; +- } ++ /* No PTR record found. */ ++ if (ttlp != NULL) ++ /* No caching of negative responses. */ ++ *ttlp = 0; + +- *h_errnop = NETDB_SUCCESS; +- return NSS_STATUS_SUCCESS; +- } +- no_recovery: + *h_errnop = NO_RECOVERY; + *errnop = ENOENT; + return NSS_STATUS_TRYAGAIN; diff --git a/SOURCES/glibc-upstream-2.34-324.patch b/SOURCES/glibc-upstream-2.34-324.patch new file mode 100644 index 0000000..b77de6e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-324.patch @@ -0,0 +1,311 @@ +commit 7267341ec1b5c591c2e7946d0604d3cf1423db7d +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + nss_dns: Remove remnants of IPv6 address mapping + + res_use_inet6 always returns false since commit 3f8b44be0a658266adff5 + ("resolv: Remove support for RES_USE_INET6 and the inet6 option"). + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit a7fc30b522a0cd7c8c5e7e285b9531b704e02f04) + +diff --git a/resolv/README b/resolv/README +index 514e9bb617e710f1..2146bc3b27a6dc56 100644 +--- a/resolv/README ++++ b/resolv/README +@@ -146,6 +146,3 @@ res_libc.c is home-brewn, although parts of it are taken from res_data.c. + + res_hconf.c and res_hconf.h were contributed by David Mosberger, and + do not come from BIND. +- +-The files gethnamaddr.c, mapv4v6addr.h and mapv4v6hostent.h are +-leftovers from BIND 4.9.7. +diff --git a/resolv/mapv4v6addr.h b/resolv/mapv4v6addr.h +deleted file mode 100644 +index 7f85f7d5e393ec5f..0000000000000000 +--- a/resolv/mapv4v6addr.h ++++ /dev/null +@@ -1,69 +0,0 @@ +-/* +- * ++Copyright++ 1985, 1988, 1993 +- * - +- * Copyright (c) 1985, 1988, 1993 +- * The Regents of the University of California. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 4. Neither the name of the University nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * - +- * Portions Copyright (c) 1993 by Digital Equipment Corporation. +- * +- * Permission to use, copy, modify, and distribute this software for any +- * purpose with or without fee is hereby granted, provided that the above +- * copyright notice and this permission notice appear in all copies, and that +- * the name of Digital Equipment Corporation not be used in advertising or +- * publicity pertaining to distribution of the document or software without +- * specific, written prior permission. +- * +- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL +- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES +- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT +- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +- * SOFTWARE. +- * - +- * --Copyright-- +- */ +- +-#include +-#include +- +-static void +-map_v4v6_address (const char *src, char *dst) +-{ +- u_char *p = (u_char *) dst; +- int i; +- +- /* Move the IPv4 part to the right position. */ +- memcpy (dst + 12, src, INADDRSZ); +- +- /* Mark this ipv6 addr as a mapped ipv4. */ +- for (i = 0; i < 10; i++) +- *p++ = 0x00; +- *p++ = 0xff; +- *p = 0xff; +-} +diff --git a/resolv/mapv4v6hostent.h b/resolv/mapv4v6hostent.h +deleted file mode 100644 +index c11038adf33f154d..0000000000000000 +--- a/resolv/mapv4v6hostent.h ++++ /dev/null +@@ -1,84 +0,0 @@ +-/* +- * ++Copyright++ 1985, 1988, 1993 +- * - +- * Copyright (c) 1985, 1988, 1993 +- * The Regents of the University of California. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 4. Neither the name of the University nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * - +- * Portions Copyright (c) 1993 by Digital Equipment Corporation. +- * +- * Permission to use, copy, modify, and distribute this software for any +- * purpose with or without fee is hereby granted, provided that the above +- * copyright notice and this permission notice appear in all copies, and that +- * the name of Digital Equipment Corporation not be used in advertising or +- * publicity pertaining to distribution of the document or software without +- * specific, written prior permission. +- * +- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL +- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES +- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT +- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +- * SOFTWARE. +- * - +- * --Copyright-- +- */ +- +-#include +-#include +- +-typedef union { +- int32_t al; +- char ac; +-} align; +- +-static int +-map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp) +-{ +- char **ap; +- +- if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) +- return 0; +- hp->h_addrtype = AF_INET6; +- hp->h_length = IN6ADDRSZ; +- for (ap = hp->h_addr_list; *ap; ap++) +- { +- int i = sizeof (align) - ((u_long) *bpp % sizeof (align)); +- +- if (*lenp < (i + IN6ADDRSZ)) +- /* Out of memory. */ +- return 1; +- *bpp += i; +- *lenp -= i; +- map_v4v6_address (*ap, *bpp); +- *ap = *bpp; +- *bpp += IN6ADDRSZ; +- *lenp -= IN6ADDRSZ; +- } +- return 0; +-} +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 2cd7170f20b60588..f8dc5a0a7d1eb156 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -88,10 +88,6 @@ + #include + #include + +-/* Get implementations of some internal functions. */ +-#include +-#include +- + #define RESOLVSORT + + #if PACKETSZ > 65536 +@@ -117,7 +113,7 @@ static enum nss_status getanswer_r (struct resolv_context *ctx, + const char *qname, int qtype, + struct hostent *result, char *buffer, + size_t buflen, int *errnop, int *h_errnop, +- int map, int32_t *ttlp, char **canonp); ++ int32_t *ttlp, char **canonp); + static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen, + struct alloc_buffer *abuf, + char **hnamep, int *errnop, +@@ -198,7 +194,6 @@ gethostbyname3_context (struct resolv_context *ctx, + char tmp[NS_MAXDNAME]; + int size, type, n; + const char *cp; +- int map = 0; + int olderr = errno; + enum nss_status status; + +@@ -259,32 +254,12 @@ gethostbyname3_context (struct resolv_context *ctx, + *errnop = EAGAIN; + else + __set_errno (olderr); +- +- /* If we are looking for an IPv6 address and mapping is enabled +- by having the RES_USE_INET6 bit in _res.options set, we try +- another lookup. */ +- if (af == AF_INET6 && res_use_inet6 ()) +- n = __res_context_search (ctx, name, C_IN, T_A, host_buffer.buf->buf, +- host_buffer.buf != orig_host_buffer +- ? MAXPACKET : 1024, &host_buffer.ptr, +- NULL, NULL, NULL, NULL); +- +- if (n < 0) +- { +- if (host_buffer.buf != orig_host_buffer) +- free (host_buffer.buf); +- return status; +- } +- +- map = 1; +- +- result->h_addrtype = AF_INET; +- result->h_length = INADDRSZ; + } ++ else ++ status = getanswer_r ++ (ctx, host_buffer.buf, n, name, type, result, buffer, buflen, ++ errnop, h_errnop, ttlp, canonp); + +- status = getanswer_r +- (ctx, host_buffer.buf, n, name, type, result, buffer, buflen, +- errnop, h_errnop, map, ttlp, canonp); + if (host_buffer.buf != orig_host_buffer) + free (host_buffer.buf); + return status; +@@ -330,13 +305,8 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_UNAVAIL; + } +- status = NSS_STATUS_NOTFOUND; +- if (res_use_inet6 ()) +- status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer, +- buflen, errnop, h_errnop, NULL, NULL); +- if (status == NSS_STATUS_NOTFOUND) +- status = gethostbyname3_context (ctx, name, AF_INET, result, buffer, +- buflen, errnop, h_errnop, NULL, NULL); ++ status = gethostbyname3_context (ctx, name, AF_INET, result, buffer, ++ buflen, errnop, h_errnop, NULL, NULL); + __resolv_context_put (ctx); + return status; + } +@@ -649,7 +619,7 @@ static enum nss_status + getanswer_r (struct resolv_context *ctx, + const querybuf *answer, int anslen, const char *qname, int qtype, + struct hostent *result, char *buffer, size_t buflen, +- int *errnop, int *h_errnop, int map, int32_t *ttlp, char **canonp) ++ int *errnop, int *h_errnop, int32_t *ttlp, char **canonp) + { + struct host_data + { +@@ -665,7 +635,6 @@ getanswer_r (struct resolv_context *ctx, + char *bp, **ap, **hap; + char tbuf[MAXDNAME]; + u_char packtmp[NS_MAXCDNAME]; +- int have_to_map = 0; + uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); + buffer += pad; + buflen = buflen > pad ? buflen - pad : 0; +@@ -846,9 +815,7 @@ getanswer_r (struct resolv_context *ctx, + continue; + } + +- if (type == T_A && qtype == T_AAAA && map) +- have_to_map = 1; +- else if (__glibc_unlikely (type != qtype)) ++ if (__glibc_unlikely (type != qtype)) + { + cp += n; + continue; /* XXX - had_error++ ? */ +@@ -945,9 +912,6 @@ getanswer_r (struct resolv_context *ctx, + linebuflen -= n; + } + +- if (have_to_map) +- if (map_v4v6_hostent (result, &bp, &linebuflen)) +- goto too_small; + *h_errnop = NETDB_SUCCESS; + return NSS_STATUS_SUCCESS; + } diff --git a/SOURCES/glibc-upstream-2.34-325.patch b/SOURCES/glibc-upstream-2.34-325.patch new file mode 100644 index 0000000..7a282c5 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-325.patch @@ -0,0 +1,565 @@ +commit 9abc40d9b514fc51cd1a052d32d092a827c6e21a +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + nss_dns: Rewrite getanswer_r to match getanswer_ptr (bug 12154, bug 29305) + + Allocate the pointer arrays only at the end, when their sizes + are known. This addresses bug 29305. + + Skip over invalid names instead of failing lookups. This partially + fixes bug 12154 (for gethostbyname, fixing getaddrinfo requires + different changes). + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit d101d836e7e4bd1d4e4972b0e0bd0a55c9b650fa) + +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index f8dc5a0a7d1eb156..10c21e1e827cde12 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -108,12 +108,19 @@ typedef union querybuf + u_char buf[MAXPACKET]; + } querybuf; + +-static enum nss_status getanswer_r (struct resolv_context *ctx, +- const querybuf *answer, int anslen, +- const char *qname, int qtype, +- struct hostent *result, char *buffer, +- size_t buflen, int *errnop, int *h_errnop, +- int32_t *ttlp, char **canonp); ++/* For historic reasons, pointers to IP addresses are char *, so use a ++ single list type for addresses and host names. */ ++#define DYNARRAY_STRUCT ptrlist ++#define DYNARRAY_ELEMENT char * ++#define DYNARRAY_PREFIX ptrlist_ ++#include ++ ++static enum nss_status getanswer_r (unsigned char *packet, size_t packetlen, ++ uint16_t qtype, struct alloc_buffer *abuf, ++ struct ptrlist *addresses, ++ struct ptrlist *aliases, ++ int *errnop, int *h_errnop, int32_t *ttlp); ++static void addrsort (struct resolv_context *ctx, char **ap, int num); + static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen, + struct alloc_buffer *abuf, + char **hnamep, int *errnop, +@@ -185,12 +192,6 @@ gethostbyname3_context (struct resolv_context *ctx, + char *buffer, size_t buflen, int *errnop, + int *h_errnop, int32_t *ttlp, char **canonp) + { +- union +- { +- querybuf *buf; +- u_char *ptr; +- } host_buffer; +- querybuf *orig_host_buffer; + char tmp[NS_MAXDNAME]; + int size, type, n; + const char *cp; +@@ -224,10 +225,12 @@ gethostbyname3_context (struct resolv_context *ctx, + && (cp = __res_context_hostalias (ctx, name, tmp, sizeof (tmp))) != NULL) + name = cp; + +- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024); ++ unsigned char dns_packet_buffer[1024]; ++ unsigned char *alt_dns_packet_buffer = dns_packet_buffer; + +- n = __res_context_search (ctx, name, C_IN, type, host_buffer.buf->buf, +- 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); ++ n = __res_context_search (ctx, name, C_IN, type, ++ dns_packet_buffer, sizeof (dns_packet_buffer), ++ &alt_dns_packet_buffer, NULL, NULL, NULL, NULL); + if (n < 0) + { + switch (errno) +@@ -256,12 +259,77 @@ gethostbyname3_context (struct resolv_context *ctx, + __set_errno (olderr); + } + else +- status = getanswer_r +- (ctx, host_buffer.buf, n, name, type, result, buffer, buflen, +- errnop, h_errnop, ttlp, canonp); ++ { ++ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen); + +- if (host_buffer.buf != orig_host_buffer) +- free (host_buffer.buf); ++ struct ptrlist addresses; ++ ptrlist_init (&addresses); ++ struct ptrlist aliases; ++ ptrlist_init (&aliases); ++ ++ status = getanswer_r (alt_dns_packet_buffer, n, type, ++ &abuf, &addresses, &aliases, ++ errnop, h_errnop, ttlp); ++ if (status == NSS_STATUS_SUCCESS) ++ { ++ if (ptrlist_has_failed (&addresses) ++ || ptrlist_has_failed (&aliases)) ++ { ++ /* malloc failure. Do not retry using the ERANGE protocol. */ ++ *errnop = ENOMEM; ++ *h_errnop = NETDB_INTERNAL; ++ status = NSS_STATUS_UNAVAIL; ++ } ++ ++ /* Reserve the address and alias arrays in the result ++ buffer. Both are NULL-terminated, but the first element ++ of the alias array is stored in h_name, so no extra space ++ for the NULL terminator is needed there. */ ++ result->h_addr_list ++ = alloc_buffer_alloc_array (&abuf, char *, ++ ptrlist_size (&addresses) + 1); ++ result->h_aliases ++ = alloc_buffer_alloc_array (&abuf, char *, ++ ptrlist_size (&aliases)); ++ if (alloc_buffer_has_failed (&abuf)) ++ { ++ /* Retry using the ERANGE protocol. */ ++ *errnop = ERANGE; ++ *h_errnop = NETDB_INTERNAL; ++ status = NSS_STATUS_TRYAGAIN; ++ } ++ else ++ { ++ /* Copy the address list and NULL-terminate it. */ ++ memcpy (result->h_addr_list, ptrlist_begin (&addresses), ++ ptrlist_size (&addresses) * sizeof (char *)); ++ result->h_addr_list[ptrlist_size (&addresses)] = NULL; ++ ++ /* Sort the address list if requested. */ ++ if (type == T_A && __resolv_context_sort_count (ctx) > 0) ++ addrsort (ctx, result->h_addr_list, ptrlist_size (&addresses)); ++ ++ /* Copy the aliases, excluding the last one. */ ++ memcpy (result->h_aliases, ptrlist_begin (&aliases), ++ (ptrlist_size (&aliases) - 1) * sizeof (char *)); ++ result->h_aliases[ptrlist_size (&aliases) - 1] = NULL; ++ ++ /* The last alias goes into h_name. */ ++ assert (ptrlist_size (&aliases) >= 1); ++ result->h_name = ptrlist_end (&aliases)[-1]; ++ ++ /* This is also the canonical name. */ ++ if (canonp != NULL) ++ *canonp = result->h_name; ++ } ++ } ++ ++ ptrlist_free (&aliases); ++ ptrlist_free (&addresses); ++ } ++ ++ if (alt_dns_packet_buffer != dns_packet_buffer) ++ free (alt_dns_packet_buffer); + return status; + } + +@@ -615,314 +683,128 @@ addrsort (struct resolv_context *ctx, char **ap, int num) + break; + } + +-static enum nss_status +-getanswer_r (struct resolv_context *ctx, +- const querybuf *answer, int anslen, const char *qname, int qtype, +- struct hostent *result, char *buffer, size_t buflen, +- int *errnop, int *h_errnop, int32_t *ttlp, char **canonp) ++/* Convert the uncompressed, binary domain name CDNAME into its ++ textual representation and add it to the end of ALIASES, allocating ++ space for a copy of the name from ABUF. Skip adding the name if it ++ is not a valid host name, and return false in that case, otherwise ++ true. */ ++static bool ++getanswer_r_store_alias (const unsigned char *cdname, ++ struct alloc_buffer *abuf, ++ struct ptrlist *aliases) + { +- struct host_data +- { +- char *aliases[MAX_NR_ALIASES]; +- unsigned char host_addr[16]; /* IPv4 or IPv6 */ +- char *h_addr_ptrs[0]; +- } *host_data; +- int linebuflen; +- const HEADER *hp; +- const u_char *end_of_message, *cp; +- int n, ancount, qdcount; +- int haveanswer, had_error; +- char *bp, **ap, **hap; +- char tbuf[MAXDNAME]; +- u_char packtmp[NS_MAXCDNAME]; +- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); +- buffer += pad; +- buflen = buflen > pad ? buflen - pad : 0; +- if (__glibc_unlikely (buflen < sizeof (struct host_data))) +- { +- /* The buffer is too small. */ +- too_small: +- *errnop = ERANGE; +- *h_errnop = NETDB_INTERNAL; +- return NSS_STATUS_TRYAGAIN; +- } +- host_data = (struct host_data *) buffer; +- linebuflen = buflen - sizeof (struct host_data); +- if (buflen - sizeof (struct host_data) != linebuflen) +- linebuflen = INT_MAX; +- +- result->h_name = NULL; +- end_of_message = answer->buf + anslen; +- +- /* +- * find first satisfactory answer +- */ +- hp = &answer->hdr; +- ancount = ntohs (hp->ancount); +- qdcount = ntohs (hp->qdcount); +- cp = answer->buf + HFIXEDSZ; +- if (__glibc_unlikely (qdcount != 1)) +- { +- *h_errnop = NO_RECOVERY; +- return NSS_STATUS_UNAVAIL; +- } +- if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen) +- goto too_small; +- bp = (char *) &host_data->h_addr_ptrs[ancount + 1]; +- linebuflen -= (ancount + 1) * sizeof (char *); +- +- n = __ns_name_unpack (answer->buf, end_of_message, cp, +- packtmp, sizeof packtmp); +- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) +- { +- if (__glibc_unlikely (errno == EMSGSIZE)) +- goto too_small; +- +- n = -1; +- } ++ /* Filter out domain names that are not host names. */ ++ if (!__res_binary_hnok (cdname)) ++ return false; ++ ++ /* Note: Not NS_MAXCDNAME, so that __ns_name_ntop implicitly checks ++ for length. */ ++ char dname[MAXHOSTNAMELEN + 1]; ++ if (__ns_name_ntop (cdname, dname, sizeof (dname)) < 0) ++ return false; ++ /* Do not report an error on allocation failure, instead store NULL ++ or do nothing. getanswer_r's caller will see NSS_STATUS_SUCCESS ++ and detect the memory allocation failure or buffer space ++ exhaustion, and report it accordingly. */ ++ ptrlist_add (aliases, alloc_buffer_copy_string (abuf, dname)); ++ return true; ++} + +- if (__glibc_unlikely (n < 0)) +- { +- *errnop = errno; +- *h_errnop = NO_RECOVERY; +- return NSS_STATUS_UNAVAIL; +- } +- if (__glibc_unlikely (__libc_res_hnok (bp) == 0)) ++static enum nss_status __attribute__ ((noinline)) ++getanswer_r (unsigned char *packet, size_t packetlen, uint16_t qtype, ++ struct alloc_buffer *abuf, ++ struct ptrlist *addresses, struct ptrlist *aliases, ++ int *errnop, int *h_errnop, int32_t *ttlp) ++{ ++ struct ns_rr_cursor c; ++ if (!__ns_rr_cursor_init (&c, packet, packetlen)) + { +- errno = EBADMSG; +- *errnop = EBADMSG; ++ /* This should not happen because __res_context_query already ++ perfroms response validation. */ + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; + } +- cp += n + QFIXEDSZ; + +- if (qtype == T_A || qtype == T_AAAA) ++ /* Treat the QNAME just like an alias. Error out if it is not a ++ valid host name. */ ++ if (ns_rr_cursor_rcode (&c) == NXDOMAIN ++ || !getanswer_r_store_alias (ns_rr_cursor_qname (&c), abuf, aliases)) + { +- /* res_send() has already verified that the query name is the +- * same as the one we sent; this just gets the expanded name +- * (i.e., with the succeeding search-domain tacked on). +- */ +- n = strlen (bp) + 1; /* for the \0 */ +- if (n >= MAXHOSTNAMELEN) +- { +- *h_errnop = NO_RECOVERY; +- *errnop = ENOENT; +- return NSS_STATUS_TRYAGAIN; +- } +- result->h_name = bp; +- bp += n; +- linebuflen -= n; +- if (linebuflen < 0) +- goto too_small; +- /* The qname can be abbreviated, but h_name is now absolute. */ +- qname = result->h_name; ++ if (ttlp != NULL) ++ /* No negative caching. */ ++ *ttlp = 0; ++ *h_errnop = HOST_NOT_FOUND; ++ *errnop = ENOENT; ++ return NSS_STATUS_NOTFOUND; + } + +- ap = host_data->aliases; +- *ap = NULL; +- result->h_aliases = host_data->aliases; +- hap = host_data->h_addr_ptrs; +- *hap = NULL; +- result->h_addr_list = host_data->h_addr_ptrs; +- haveanswer = 0; +- had_error = 0; ++ int ancount = ns_rr_cursor_ancount (&c); ++ const unsigned char *expected_name = ns_rr_cursor_qname (&c); ++ /* expected_name may be updated to point into this buffer. */ ++ unsigned char name_buffer[NS_MAXCDNAME]; + +- while (ancount-- > 0 && cp < end_of_message && had_error == 0) ++ for (; ancount > 0; --ancount) + { +- int type, class; +- +- n = __ns_name_unpack (answer->buf, end_of_message, cp, +- packtmp, sizeof packtmp); +- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) +- { +- if (__glibc_unlikely (errno == EMSGSIZE)) +- goto too_small; +- +- n = -1; +- } +- +- if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0)) +- { +- ++had_error; +- continue; +- } +- cp += n; /* name */ +- +- if (__glibc_unlikely (cp + 10 > end_of_message)) ++ struct ns_rr_wire rr; ++ if (!__ns_rr_cursor_next (&c, &rr)) + { +- ++had_error; +- continue; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; + } + +- NS_GET16 (type, cp); +- NS_GET16 (class, cp); +- int32_t ttl; +- NS_GET32 (ttl, cp); +- NS_GET16 (n, cp); /* RDATA length. */ +- +- if (end_of_message - cp < n) +- { +- /* RDATA extends beyond the end of the packet. */ +- ++had_error; +- continue; +- } ++ /* Skip over records with the wrong class. */ ++ if (rr.rclass != C_IN) ++ continue; + +- if (__glibc_unlikely (class != C_IN)) +- { +- /* XXX - debug? syslog? */ +- cp += n; +- continue; /* XXX - had_error++ ? */ +- } ++ /* Update TTL for recognized record types. */ ++ if ((rr.rtype == T_CNAME || rr.rtype == qtype) ++ && ttlp != NULL && *ttlp > rr.ttl) ++ *ttlp = rr.ttl; + +- if (type == T_CNAME) ++ if (rr.rtype == T_CNAME) + { +- /* A CNAME could also have a TTL entry. */ +- if (ttlp != NULL && ttl < *ttlp) +- *ttlp = ttl; +- +- if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1]) +- continue; +- n = __libc_dn_expand (answer->buf, end_of_message, cp, +- tbuf, sizeof tbuf); +- if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0)) +- { +- ++had_error; +- continue; +- } +- cp += n; +- /* Store alias. */ +- *ap++ = bp; +- n = strlen (bp) + 1; /* For the \0. */ +- if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) +- { +- ++had_error; +- continue; +- } +- bp += n; +- linebuflen -= n; +- /* Get canonical name. */ +- n = strlen (tbuf) + 1; /* For the \0. */ +- if (__glibc_unlikely (n > linebuflen)) +- goto too_small; +- if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) ++ /* NB: No check for owner name match, based on historic ++ precedent. Record the CNAME target as the new expected ++ name. */ ++ int n = __ns_name_unpack (c.begin, c.end, rr.rdata, ++ name_buffer, sizeof (name_buffer)); ++ if (n < 0) + { +- ++had_error; +- continue; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; + } +- result->h_name = bp; +- bp = __mempcpy (bp, tbuf, n); /* Cannot overflow. */ +- linebuflen -= n; +- continue; ++ /* And store the new name as an alias. */ ++ getanswer_r_store_alias (name_buffer, abuf, aliases); ++ expected_name = name_buffer; + } +- +- if (__glibc_unlikely (type != qtype)) ++ else if (rr.rtype == qtype ++ && __ns_samebinaryname (rr.rname, expected_name) ++ && rr.rdlength == rrtype_to_rdata_length (qtype)) + { +- cp += n; +- continue; /* XXX - had_error++ ? */ ++ /* Make a copy of the address and store it. Increase the ++ alignment to 4, in case there are applications out there ++ that expect at least this level of address alignment. */ ++ ptrlist_add (addresses, (char *) alloc_buffer_next (abuf, uint32_t)); ++ alloc_buffer_copy_bytes (abuf, rr.rdata, rr.rdlength); + } +- +- switch (type) +- { +- case T_A: +- case T_AAAA: +- if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0)) +- { +- cp += n; +- continue; /* XXX - had_error++ ? */ +- } +- +- /* Stop parsing at a record whose length is incorrect. */ +- if (n != rrtype_to_rdata_length (type)) +- { +- ++had_error; +- break; +- } +- +- /* Skip records of the wrong type. */ +- if (n != result->h_length) +- { +- cp += n; +- continue; +- } +- if (!haveanswer) +- { +- int nn; +- +- /* We compose a single hostent out of the entire chain of +- entries, so the TTL of the hostent is essentially the lowest +- TTL in the chain. */ +- if (ttlp != NULL && ttl < *ttlp) +- *ttlp = ttl; +- if (canonp != NULL) +- *canonp = bp; +- result->h_name = bp; +- nn = strlen (bp) + 1; /* for the \0 */ +- bp += nn; +- linebuflen -= nn; +- } +- +- /* Provide sufficient alignment for both address +- families. */ +- enum { align = 4 }; +- _Static_assert ((align % __alignof__ (struct in_addr)) == 0, +- "struct in_addr alignment"); +- _Static_assert ((align % __alignof__ (struct in6_addr)) == 0, +- "struct in6_addr alignment"); +- { +- char *new_bp = PTR_ALIGN_UP (bp, align); +- linebuflen -= new_bp - bp; +- bp = new_bp; +- } +- +- if (__glibc_unlikely (n > linebuflen)) +- goto too_small; +- bp = __mempcpy (*hap++ = bp, cp, n); +- cp += n; +- linebuflen -= n; +- break; +- default: +- abort (); +- } +- if (had_error == 0) +- ++haveanswer; + } + +- if (haveanswer > 0) ++ if (ptrlist_size (addresses) == 0) + { +- *ap = NULL; +- *hap = NULL; +- /* +- * Note: we sort even if host can take only one address +- * in its return structures - should give it the "best" +- * address in that case, not some random one +- */ +- if (haveanswer > 1 && qtype == T_A +- && __resolv_context_sort_count (ctx) > 0) +- addrsort (ctx, host_data->h_addr_ptrs, haveanswer); +- +- if (result->h_name == NULL) +- { +- n = strlen (qname) + 1; /* For the \0. */ +- if (n > linebuflen) +- goto too_small; +- if (n >= MAXHOSTNAMELEN) +- goto no_recovery; +- result->h_name = bp; +- bp = __mempcpy (bp, qname, n); /* Cannot overflow. */ +- linebuflen -= n; +- } ++ /* No address record found. */ ++ if (ttlp != NULL) ++ /* No caching of negative responses. */ ++ *ttlp = 0; + ++ *h_errnop = NO_RECOVERY; ++ *errnop = ENOENT; ++ return NSS_STATUS_TRYAGAIN; ++ } ++ else ++ { + *h_errnop = NETDB_SUCCESS; + return NSS_STATUS_SUCCESS; + } +- no_recovery: +- *h_errnop = NO_RECOVERY; +- *errnop = ENOENT; +- /* Special case here: if the resolver sent a result but it only +- contains a CNAME while we are looking for a T_A or T_AAAA record, +- we fail with NOTFOUND instead of TRYAGAIN. */ +- return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases +- ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN); + } + + static enum nss_status diff --git a/SOURCES/glibc-upstream-2.34-326.patch b/SOURCES/glibc-upstream-2.34-326.patch new file mode 100644 index 0000000..3784a3e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-326.patch @@ -0,0 +1,51 @@ +commit c36e7cca3571b0c92b09409c1df86a142596c210 +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + nss_dns: In gaih_getanswer_slice, skip strange aliases (bug 12154) + + If the name is not a host name, skip adding it to the result, instead + of reporting query failure. This fixes bug 12154 for getaddrinfo. + + This commit still keeps the old parsing code, and only adjusts when + a host name is copied. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 32b599ac8c21c4c332cc3900a792a1395bca79c7) + +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 10c21e1e827cde12..1cb3be71f04d98eb 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -971,12 +971,12 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + + n = -1; + } +- if (__glibc_unlikely (n < 0 || __libc_res_hnok (buffer) == 0)) ++ if (__glibc_unlikely (n < 0)) + { + ++had_error; + continue; + } +- if (*firstp && canon == NULL) ++ if (*firstp && canon == NULL && __libc_res_hnok (buffer)) + { + h_name = buffer; + buffer += h_namelen; +@@ -1022,14 +1022,14 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + + n = __libc_dn_expand (answer->buf, end_of_message, cp, + tbuf, sizeof tbuf); +- if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0)) ++ if (__glibc_unlikely (n < 0)) + { + ++had_error; + continue; + } + cp += n; + +- if (*firstp) ++ if (*firstp && __libc_res_hnok (tbuf)) + { + /* Reclaim buffer space. */ + if (h_name + h_namelen == buffer) diff --git a/SOURCES/glibc-upstream-2.34-327.patch b/SOURCES/glibc-upstream-2.34-327.patch new file mode 100644 index 0000000..8019ca3 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-327.patch @@ -0,0 +1,449 @@ +commit 480c820493add16e8dda6f3189d834223e1f4f39 +Author: Florian Weimer +Date: Tue Aug 30 10:02:49 2022 +0200 + + resolv: Add new tst-resolv-invalid-cname + + This test checks resolution through CNAME chains that do not contain + host names (bug 12154). + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 9caf782276ecea4bc86fc94fbb52779736f3106d) + +Conflicts: + resolv/Makefile + (usual test differences) + +diff --git a/resolv/Makefile b/resolv/Makefile +index fded244d61068060..ea1518ec2da860c1 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -99,6 +99,7 @@ tests += \ + tst-resolv-binary \ + tst-resolv-byaddr \ + tst-resolv-edns \ ++ tst-resolv-invalid-cname \ + tst-resolv-network \ + tst-resolv-noaaaa \ + tst-resolv-nondecimal \ +@@ -279,6 +280,8 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \ + $(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \ + $(shared-thread-library) + $(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-invalid-cname: $(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) +diff --git a/resolv/tst-resolv-invalid-cname.c b/resolv/tst-resolv-invalid-cname.c +new file mode 100644 +index 0000000000000000..ae2d4419b1978c02 +--- /dev/null ++++ b/resolv/tst-resolv-invalid-cname.c +@@ -0,0 +1,406 @@ ++/* Test handling of CNAMEs with non-host domain names (bug 12154). ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Query strings describe the CNAME chain in the response. They have ++ the format "bitsBITS.countCOUNT.example.", where BITS and COUNT are ++ replaced by unsigned decimal numbers. COUNT is the number of CNAME ++ records in the response. BITS has two bits for each CNAME record, ++ describing a special prefix that is added to that CNAME. ++ ++ 0: No special leading label. ++ 1: Starting with "*.". ++ 2: Starting with "-x.". ++ 3: Starting with "star.*.". ++ ++ The first CNAME in the response using the two least significant ++ bits. ++ ++ For PTR queries, the QNAME format is different, it is either ++ COUNT.BITS.168.192.in-addr.arpa. (with BITS and COUNT still ++ decimal), or: ++ ++COUNT.BITS0.BITS1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. ++ ++ where BITS and COUNT are hexadecimal. */ ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ TEST_COMPARE (qclass, C_IN); ++ ++ /* The only other query type besides A is PTR. */ ++ if (qtype != T_A && qtype != T_AAAA) ++ TEST_COMPARE (qtype, T_PTR); ++ ++ unsigned int bits, bits1, count; ++ char *tail = NULL; ++ if (sscanf (qname, "bits%u.count%u.%ms", &bits, &count, &tail) == 3) ++ TEST_COMPARE_STRING (tail, "example"); ++ else if (strstr (qname, "in-addr.arpa") != NULL ++ && sscanf (qname, "%u.%u.%ms", &bits, &count, &tail) == 3) ++ TEST_COMPARE_STRING (tail, "168.192.in-addr.arpa"); ++ else if (sscanf (qname, "%x.%x.%x.%ms", &bits, &bits1, &count, &tail) == 4) ++ { ++ TEST_COMPARE_STRING (tail, "\ ++0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa"); ++ bits |= bits1 << 4; ++ } ++ else ++ FAIL_EXIT1 ("invalid QNAME: %s\n", qname); ++ free (tail); ++ ++ struct resolv_response_flags flags = {}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ ++ /* Provide the requested number of CNAME records. */ ++ char *previous_name = (char *) qname; ++ unsigned int original_bits = bits; ++ for (int unique = 0; unique < count; ++unique) ++ { ++ resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60); ++ ++ static const char bits_to_prefix[4][8] = { "", "*.", "-x.", "star.*." }; ++ char *new_name = xasprintf ("%sunique%d.example", ++ bits_to_prefix[bits & 3], unique); ++ bits >>= 2; ++ resolv_response_add_name (b, new_name); ++ resolv_response_close_record (b); ++ ++ if (previous_name != qname) ++ free (previous_name); ++ previous_name = new_name; ++ } ++ ++ /* Actual answer record. */ ++ resolv_response_open_record (b, previous_name, qclass, qtype, 60); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char ipv4[4] = {192, 168, count, original_bits}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char ipv6[16] = ++ { ++ 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ count, original_bits ++ }; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ break; ++ ++ case T_PTR: ++ { ++ char *name = xasprintf ("bits%u.count%u.example", ++ original_bits, count); ++ resolv_response_add_name (b, name); ++ free (name); ++ } ++ break; ++ } ++ resolv_response_close_record (b); ++ ++ if (previous_name != qname) ++ free (previous_name); ++} ++ ++/* Controls which name resolution function is invoked. */ ++enum test_mode ++ { ++ byname, /* gethostbyname. */ ++ byname2, /* gethostbyname2. */ ++ gai, /* getaddrinfo without AI_CANONNAME. */ ++ gai_canon, /* getaddrinfo with AI_CANONNAME. */ ++ ++ test_mode_num /* Number of enum values. */ ++ }; ++ ++static const char * ++test_mode_to_string (enum test_mode mode) ++{ ++ switch (mode) ++ { ++ case byname: ++ return "byname"; ++ case byname2: ++ return "byname2"; ++ case gai: ++ return "gai"; ++ case gai_canon: ++ return "gai_canon"; ++ case test_mode_num: ++ /* Report error below. */ ++ } ++ FAIL_EXIT1 ("invalid test_mode: %d", mode); ++} ++ ++/* Append the name and aliases to OUT. */ ++static void ++append_names (FILE *out, const char *qname, int bits, int count, ++ enum test_mode mode) ++{ ++ /* Largest valid index which has a corresponding zero in bits ++ (meaning a syntactically valid CNAME). */ ++ int last_valid_cname = -1; ++ ++ for (int i = 0; i < count; ++i) ++ if ((bits & (3 << (i * 2))) == 0) ++ last_valid_cname = i; ++ ++ if (mode != gai) ++ { ++ const char *label; ++ if (mode == gai_canon) ++ label = "canonname"; ++ else ++ label = "name"; ++ if (last_valid_cname >= 0) ++ fprintf (out, "%s: unique%d.example\n", label, last_valid_cname); ++ else ++ fprintf (out, "%s: %s\n", label, qname); ++ } ++ ++ if (mode == byname || mode == byname2) ++ { ++ if (last_valid_cname >= 0) ++ fprintf (out, "alias: %s\n", qname); ++ for (int i = 0; i < count; ++i) ++ { ++ if ((bits & (3 << (i * 2))) == 0 && i != last_valid_cname) ++ fprintf (out, "alias: unique%d.example\n", i); ++ } ++ } ++} ++ ++/* Append the address information to OUT. */ ++static void ++append_addresses (FILE *out, int af, int bits, int count, enum test_mode mode) ++{ ++ int last = count * 256 + bits; ++ if (mode == gai || mode == gai_canon) ++ { ++ if (af == AF_INET || af == AF_UNSPEC) ++ fprintf (out, "address: STREAM/TCP 192.168.%d.%d 80\n", count, bits); ++ if (af == AF_INET6 || af == AF_UNSPEC) ++ { ++ if (last == 0) ++ fprintf (out, "address: STREAM/TCP 2001:db8:: 80\n"); ++ else ++ fprintf (out, "address: STREAM/TCP 2001:db8::%x 80\n", last); ++ } ++ } ++ else ++ { ++ TEST_VERIFY (af != AF_UNSPEC); ++ if (af == AF_INET) ++ fprintf (out, "address: 192.168.%d.%d\n", count, bits); ++ if (af == AF_INET6) ++ { ++ if (last == 0) ++ fprintf (out, "address: 2001:db8::\n"); ++ else ++ fprintf (out, "address: 2001:db8::%x\n", last); ++ } ++ } ++} ++ ++/* Perform one test using a forward lookup. */ ++static void ++check_forward (int af, int bits, int count, enum test_mode mode) ++{ ++ char *qname = xasprintf ("bits%d.count%d.example", bits, count); ++ char *label = xasprintf ("af=%d bits=%d count=%d mode=%s qname=%s", ++ af, bits, count, test_mode_to_string (mode), qname); ++ ++ struct xmemstream expected; ++ xopen_memstream (&expected); ++ if (mode == gai_canon) ++ fprintf (expected.out, "flags: AI_CANONNAME\n"); ++ append_names (expected.out, qname, bits, count, mode); ++ append_addresses (expected.out, af, bits, count, mode); ++ xfclose_memstream (&expected); ++ ++ if (mode == gai || mode == gai_canon) ++ { ++ struct addrinfo *ai; ++ struct addrinfo hints = ++ { ++ .ai_family = af, ++ .ai_socktype = SOCK_STREAM, ++ }; ++ if (mode == gai_canon) ++ hints.ai_flags |= AI_CANONNAME; ++ int ret = getaddrinfo (qname, "80", &hints, &ai); ++ check_addrinfo (label, ai, ret, expected.buffer); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ } ++ else ++ { ++ struct hostent *e; ++ if (mode == gai) ++ { ++ TEST_COMPARE (af, AF_INET); ++ e = gethostbyname (qname); ++ } ++ else ++ { ++ if (af != AF_INET) ++ TEST_COMPARE (af, AF_INET6); ++ e = gethostbyname2 (qname, af); ++ } ++ check_hostent (label, e, expected.buffer); ++ } ++ ++ free (expected.buffer); ++ free (label); ++ free (qname); ++} ++ ++/* Perform one check using a reverse lookup. */ ++ ++static void ++check_reverse (int af, int bits, int count) ++{ ++ TEST_VERIFY (af == AF_INET || af == AF_INET6); ++ ++ char *label = xasprintf ("af=%d bits=%d count=%d", af, bits, count); ++ char *fqdn = xasprintf ("bits%d.count%d.example", bits, count); ++ ++ struct xmemstream expected; ++ xopen_memstream (&expected); ++ fprintf (expected.out, "name: %s\n", fqdn); ++ append_addresses (expected.out, af, bits, count, byname); ++ xfclose_memstream (&expected); ++ ++ char addr[16] = { 0 }; ++ socklen_t addrlen; ++ if (af == AF_INET) ++ { ++ addr[0] = 192; ++ addr[1] = 168; ++ addr[2] = count; ++ addr[3] = bits; ++ addrlen = 4; ++ } ++ else ++ { ++ addr[0] = 0x20; ++ addr[1] = 0x01; ++ addr[2] = 0x0d; ++ addr[3] = 0xb8; ++ addr[14] = count; ++ addr[15] = bits; ++ addrlen = 16; ++ } ++ ++ struct hostent *e = gethostbyaddr (addr, addrlen, af); ++ check_hostent (label, e, expected.buffer); ++ ++ /* getnameinfo check is different. There is no generic check_* ++ function for it. */ ++ { ++ struct sockaddr_in sin = { }; ++ struct sockaddr_in6 sin6 = { }; ++ void *sa; ++ socklen_t salen; ++ if (af == AF_INET) ++ { ++ sin.sin_family = AF_INET; ++ memcpy (&sin.sin_addr, addr, addrlen); ++ sin.sin_port = htons (80); ++ sa = &sin; ++ salen = sizeof (sin); ++ } ++ else ++ { ++ sin6.sin6_family = AF_INET6; ++ memcpy (&sin6.sin6_addr, addr, addrlen); ++ sin6.sin6_port = htons (80); ++ sa = &sin6; ++ salen = sizeof (sin6); ++ } ++ ++ char host[64]; ++ char service[64]; ++ int ret = getnameinfo (sa, salen, host, ++ sizeof (host), service, sizeof (service), ++ NI_NAMEREQD | NI_NUMERICSERV); ++ TEST_COMPARE (ret, 0); ++ TEST_COMPARE_STRING (host, fqdn); ++ TEST_COMPARE_STRING (service, "80"); ++ } ++ ++ free (expected.buffer); ++ free (fqdn); ++ free (label); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response ++ }); ++ ++ for (int count = 0; count <= 3; ++count) ++ for (int bits = 0; bits <= 1 << (count * 2); ++bits) ++ { ++ if (count > 0 && bits == count) ++ /* The last bits value is only checked if count == 0. */ ++ continue; ++ ++ for (enum test_mode mode = 0; mode < test_mode_num; ++mode) ++ { ++ check_forward (AF_INET, bits, count, mode); ++ if (mode != byname) ++ check_forward (AF_INET6, bits, count, mode); ++ if (mode == gai || mode == gai_canon) ++ check_forward (AF_UNSPEC, bits, count, mode); ++ } ++ ++ check_reverse (AF_INET, bits, count); ++ check_reverse (AF_INET6, bits, count); ++ } ++ ++ resolv_test_end (obj); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-329.patch b/SOURCES/glibc-upstream-2.34-329.patch new file mode 100644 index 0000000..d718c5f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-329.patch @@ -0,0 +1,31 @@ +commit 044755e2faeeca13bb77b2e9e638a45e6e90a5fa +Author: Florian Weimer +Date: Tue Aug 30 13:30:03 2022 +0200 + + resolv: Fix building tst-resolv-invalid-cname for earlier C standards + + This fixes this compiler error: + + tst-resolv-invalid-cname.c: In function ‘test_mode_to_string’: + tst-resolv-invalid-cname.c:164:10: error: label at end of compound statement + case test_mode_num: + ^~~~~~~~~~~~~ + + Fixes commit 9caf782276ecea4bc86fc94fbb52779736f3106d + ("resolv: Add new tst-resolv-invalid-cname"). + + (cherry picked from commit d09aa4a17229bcaa2ec7642006b12612498582e7) + +diff --git a/resolv/tst-resolv-invalid-cname.c b/resolv/tst-resolv-invalid-cname.c +index ae2d4419b1978c02..63dac90e02d6cbc7 100644 +--- a/resolv/tst-resolv-invalid-cname.c ++++ b/resolv/tst-resolv-invalid-cname.c +@@ -162,7 +162,7 @@ test_mode_to_string (enum test_mode mode) + case gai_canon: + return "gai_canon"; + case test_mode_num: +- /* Report error below. */ ++ break; /* Report error below. */ + } + FAIL_EXIT1 ("invalid test_mode: %d", mode); + } diff --git a/SOURCES/glibc-upstream-2.34-33.patch b/SOURCES/glibc-upstream-2.34-33.patch new file mode 100644 index 0000000..f7f9ca9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-33.patch @@ -0,0 +1,37 @@ +commit a996d13b8a2e101bedbb1bdaa7ffcfea3b959bb2 +Author: Florian Weimer +Date: Thu Sep 30 18:44:06 2021 +0200 + + Add missing braces to bsearch inline implementation [BZ #28400] + + GCC treats the pragma as a statement, so that the else branch only + consists of the pragma, not the return statement. + + Fixes commit a725ff1de965f4cc4f36a7e8ae795d40ca0350d7 ("Suppress + -Wcast-qual warnings in bsearch"). + + Reviewed-by: H.J. Lu + (cherry picked from commit 32b96d0dec0294465d2221a8f049703599d9d8e4) + +diff --git a/bits/stdlib-bsearch.h b/bits/stdlib-bsearch.h +index d688ed2e15678e9c..e2fcea6e172af72c 100644 +--- a/bits/stdlib-bsearch.h ++++ b/bits/stdlib-bsearch.h +@@ -36,14 +36,16 @@ bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size, + else if (__comparison > 0) + __l = __idx + 1; + else ++ { + #if __GNUC_PREREQ(4, 6) + # pragma GCC diagnostic push + # pragma GCC diagnostic ignored "-Wcast-qual" + #endif +- return (void *) __p; ++ return (void *) __p; + #if __GNUC_PREREQ(4, 6) + # pragma GCC diagnostic pop + #endif ++ } + } + + return NULL; diff --git a/SOURCES/glibc-upstream-2.34-330.patch b/SOURCES/glibc-upstream-2.34-330.patch new file mode 100644 index 0000000..4fb22ef --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-330.patch @@ -0,0 +1,33 @@ +commit a2e259014f8a0e5f3ff938314f3087b74255804d +Author: H.J. Lu +Date: Thu Nov 11 06:31:51 2021 -0800 + + Avoid extra load with CAS in __pthread_mutex_lock_full [BZ #28537] + + Replace boolean CAS with value CAS to avoid the extra load. + + Reviewed-by: Szabolcs Nagy + (cherry picked from commit 0b82747dc48d5bf0871bdc6da8cb6eec1256355f) + +diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c +index da624f322d06d0ee..a04e0158451c8fff 100644 +--- a/nptl/pthread_mutex_lock.c ++++ b/nptl/pthread_mutex_lock.c +@@ -298,12 +298,12 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex) + meantime. */ + if ((oldval & FUTEX_WAITERS) == 0) + { +- if (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock, +- oldval | FUTEX_WAITERS, +- oldval) +- != 0) ++ int val; ++ if ((val = atomic_compare_and_exchange_val_acq ++ (&mutex->__data.__lock, oldval | FUTEX_WAITERS, ++ oldval)) != oldval) + { +- oldval = mutex->__data.__lock; ++ oldval = val; + continue; + } + oldval |= FUTEX_WAITERS; diff --git a/SOURCES/glibc-upstream-2.34-331.patch b/SOURCES/glibc-upstream-2.34-331.patch new file mode 100644 index 0000000..59c359f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-331.patch @@ -0,0 +1,33 @@ +commit ed8300c054cae4aeb0bbfa043f5fccc91a4adbf5 +Author: H.J. Lu +Date: Thu Nov 11 06:54:01 2021 -0800 + + Avoid extra load with CAS in __pthread_mutex_clocklock_common [BZ #28537] + + Replace boolean CAS with value CAS to avoid the extra load. + + Reviewed-by: Szabolcs Nagy + (cherry picked from commit 49302b8fdf9103b6fc0a398678668a22fa19574c) + +diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c +index 11ad7005d07afc6e..90cede9446e33fcf 100644 +--- a/nptl/pthread_mutex_timedlock.c ++++ b/nptl/pthread_mutex_timedlock.c +@@ -234,12 +234,12 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, + meantime. */ + if ((oldval & FUTEX_WAITERS) == 0) + { +- if (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock, +- oldval | FUTEX_WAITERS, +- oldval) +- != 0) ++ int val; ++ if ((val = atomic_compare_and_exchange_val_acq ++ (&mutex->__data.__lock, oldval | FUTEX_WAITERS, ++ oldval)) != oldval) + { +- oldval = mutex->__data.__lock; ++ oldval = val; + continue; + } + oldval |= FUTEX_WAITERS; diff --git a/SOURCES/glibc-upstream-2.34-332.patch b/SOURCES/glibc-upstream-2.34-332.patch new file mode 100644 index 0000000..2a8d15a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-332.patch @@ -0,0 +1,46 @@ +commit a6b81f605dfba8650ea1f80122f41eb8e6c73dc7 +Author: H.J. Lu +Date: Tue Nov 2 18:33:07 2021 -0700 + + Add LLL_MUTEX_READ_LOCK [BZ #28537] + + CAS instruction is expensive. From the x86 CPU's point of view, getting + a cache line for writing is more expensive than reading. See Appendix + A.2 Spinlock in: + + https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/xeon-lock-scaling-analysis-paper.pdf + + The full compare and swap will grab the cache line exclusive and cause + excessive cache line bouncing. + + Add LLL_MUTEX_READ_LOCK to do an atomic load and skip CAS in spinlock + loop if compare may fail to reduce cache line bouncing on contended locks. + + Reviewed-by: Szabolcs Nagy + (cherry picked from commit d672a98a1af106bd68deb15576710cd61363f7a6) + +diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c +index a04e0158451c8fff..9f40928cc6b9a067 100644 +--- a/nptl/pthread_mutex_lock.c ++++ b/nptl/pthread_mutex_lock.c +@@ -65,6 +65,11 @@ lll_mutex_lock_optimized (pthread_mutex_t *mutex) + # define PTHREAD_MUTEX_VERSIONS 1 + #endif + ++#ifndef LLL_MUTEX_READ_LOCK ++# define LLL_MUTEX_READ_LOCK(mutex) \ ++ atomic_load_relaxed (&(mutex)->__data.__lock) ++#endif ++ + static int __pthread_mutex_lock_full (pthread_mutex_t *mutex) + __attribute_noinline__; + +@@ -142,6 +147,8 @@ PTHREAD_MUTEX_LOCK (pthread_mutex_t *mutex) + break; + } + atomic_spin_nop (); ++ if (LLL_MUTEX_READ_LOCK (mutex) != 0) ++ continue; + } + while (LLL_MUTEX_TRYLOCK (mutex) != 0); + diff --git a/SOURCES/glibc-upstream-2.34-333.patch b/SOURCES/glibc-upstream-2.34-333.patch new file mode 100644 index 0000000..71f9e2a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-333.patch @@ -0,0 +1,66 @@ +commit 6bcfbee7277e4faa4b693bd965931f0d1883005d +Author: H.J. Lu +Date: Fri Nov 12 11:47:42 2021 -0800 + + Move assignment out of the CAS condition + + Update + + commit 49302b8fdf9103b6fc0a398678668a22fa19574c + Author: H.J. Lu + Date: Thu Nov 11 06:54:01 2021 -0800 + + Avoid extra load with CAS in __pthread_mutex_clocklock_common [BZ #28537] + + Replace boolean CAS with value CAS to avoid the extra load. + + and + + commit 0b82747dc48d5bf0871bdc6da8cb6eec1256355f + Author: H.J. Lu + Date: Thu Nov 11 06:31:51 2021 -0800 + + Avoid extra load with CAS in __pthread_mutex_lock_full [BZ #28537] + + Replace boolean CAS with value CAS to avoid the extra load. + + by moving assignment out of the CAS condition. + + (cherry picked from commit 120ac6d238825452e8024e2f627da33b2508dfd3) + +diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c +index 9f40928cc6b9a067..49901ffa0a96d659 100644 +--- a/nptl/pthread_mutex_lock.c ++++ b/nptl/pthread_mutex_lock.c +@@ -305,10 +305,9 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex) + meantime. */ + if ((oldval & FUTEX_WAITERS) == 0) + { +- int val; +- if ((val = atomic_compare_and_exchange_val_acq +- (&mutex->__data.__lock, oldval | FUTEX_WAITERS, +- oldval)) != oldval) ++ int val = atomic_compare_and_exchange_val_acq ++ (&mutex->__data.__lock, oldval | FUTEX_WAITERS, oldval); ++ if (val != oldval) + { + oldval = val; + continue; +diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c +index 90cede9446e33fcf..2e5506db06ccb1ec 100644 +--- a/nptl/pthread_mutex_timedlock.c ++++ b/nptl/pthread_mutex_timedlock.c +@@ -234,10 +234,9 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, + meantime. */ + if ((oldval & FUTEX_WAITERS) == 0) + { +- int val; +- if ((val = atomic_compare_and_exchange_val_acq +- (&mutex->__data.__lock, oldval | FUTEX_WAITERS, +- oldval)) != oldval) ++ int val = atomic_compare_and_exchange_val_acq ++ (&mutex->__data.__lock, oldval | FUTEX_WAITERS, oldval); ++ if (val != oldval) + { + oldval = val; + continue; diff --git a/SOURCES/glibc-upstream-2.34-334.patch b/SOURCES/glibc-upstream-2.34-334.patch new file mode 100644 index 0000000..1138256 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-334.patch @@ -0,0 +1,38 @@ +commit 43760d33d78f9ea8c8af942b570112ee801b99df +Author: Jangwoong Kim <6812skiii@gmail.com> +Date: Tue Dec 14 21:30:51 2021 +0900 + + nptl: Effectively skip CAS in spinlock loop + + The commit: + "Add LLL_MUTEX_READ_LOCK [BZ #28537]" + SHA1: d672a98a1af106bd68deb15576710cd61363f7a6 + + introduced LLL_MUTEX_READ_LOCK, to skip CAS in spinlock loop + if atomic load fails. But, "continue" inside of do-while loop + does not skip the evaluation of escape expression, thus CAS + is not skipped. + + Replace do-while with while and skip LLL_MUTEX_TRYLOCK if + LLL_MUTEX_READ_LOCK fails. + + Reviewed-by: H.J. Lu + (cherry picked from commit 6b8dbbd03ac88f169b65b5c7d7278576a11d2e44) + +diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c +index 49901ffa0a96d659..bbe754a272b97d91 100644 +--- a/nptl/pthread_mutex_lock.c ++++ b/nptl/pthread_mutex_lock.c +@@ -147,10 +147,9 @@ PTHREAD_MUTEX_LOCK (pthread_mutex_t *mutex) + break; + } + atomic_spin_nop (); +- if (LLL_MUTEX_READ_LOCK (mutex) != 0) +- continue; + } +- while (LLL_MUTEX_TRYLOCK (mutex) != 0); ++ while (LLL_MUTEX_READ_LOCK (mutex) != 0 ++ || LLL_MUTEX_TRYLOCK (mutex) != 0); + + mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8; + } diff --git a/SOURCES/glibc-upstream-2.34-335.patch b/SOURCES/glibc-upstream-2.34-335.patch new file mode 100644 index 0000000..fdf1241 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-335.patch @@ -0,0 +1,68 @@ +commit 04efdcfac405723c23b25d124817bcfc1697e2d8 +Author: Noah Goldstein +Date: Wed Apr 27 15:13:02 2022 -0500 + + sysdeps: Add 'get_fast_jitter' interace in fast-jitter.h + + 'get_fast_jitter' is meant to be used purely for performance + purposes. In all cases it's used it should be acceptable to get no + randomness (see default case). An example use case is in setting + jitter for retries between threads at a lock. There is a + performance benefit to having jitter, but only if the jitter can + be generated very quickly and ultimately there is no serious issue + if no jitter is generated. + + The implementation generally uses 'HP_TIMING_NOW' iff it is + inlined (avoid any potential syscall paths). + Reviewed-by: H.J. Lu + + (cherry picked from commit 911c63a51c690dd1a97dfc587097277029baf00f) + +diff --git a/sysdeps/generic/fast-jitter.h b/sysdeps/generic/fast-jitter.h +new file mode 100644 +index 0000000000000000..4dd53e3475c3dfe6 +--- /dev/null ++++ b/sysdeps/generic/fast-jitter.h +@@ -0,0 +1,42 @@ ++/* Fallback for fast jitter just return 0. ++ Copyright (C) 2019-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _FAST_JITTER_H ++# define _FAST_JITTER_H ++ ++# include ++# include ++ ++/* Baseline just return 0. We could create jitter using a clock or ++ 'random_bits' but that may imply a syscall and the goal of ++ 'get_fast_jitter' is minimal overhead "randomness" when such ++ randomness helps performance. Adding high overhead the function ++ defeats the purpose. */ ++static inline uint32_t ++get_fast_jitter (void) ++{ ++# if HP_TIMING_INLINE ++ hp_timing_t jitter; ++ HP_TIMING_NOW (jitter); ++ return (uint32_t) jitter; ++# else ++ return 0; ++# endif ++} ++ ++#endif diff --git a/SOURCES/glibc-upstream-2.34-336.patch b/SOURCES/glibc-upstream-2.34-336.patch new file mode 100644 index 0000000..94b39f2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-336.patch @@ -0,0 +1,209 @@ +commit ea69248445fb9b80da02ee0c7261cba4b1a5532e +Author: Wangyang Guo +Date: Fri May 6 01:50:10 2022 +0000 + + nptl: Add backoff mechanism to spinlock loop + + When mutiple threads waiting for lock at the same time, once lock owner + releases the lock, waiters will see lock available and all try to lock, + which may cause an expensive CAS storm. + + Binary exponential backoff with random jitter is introduced. As try-lock + attempt increases, there is more likely that a larger number threads + compete for adaptive mutex lock, so increase wait time in exponential. + A random jitter is also added to avoid synchronous try-lock from other + threads. + + v2: Remove read-check before try-lock for performance. + + v3: + 1. Restore read-check since it works well in some platform. + 2. Make backoff arch dependent, and enable it for x86_64. + 3. Limit max backoff to reduce latency in large critical section. + + v4: Fix strict-prototypes error in sysdeps/nptl/pthread_mutex_backoff.h + + v5: Commit log updated for regression in large critical section. + + Result of pthread-mutex-locks bench + + Test Platform: Xeon 8280L (2 socket, 112 CPUs in total) + First Row: thread number + First Col: critical section length + Values: backoff vs upstream, time based, low is better + + non-critical-length: 1 + 1 2 4 8 16 32 64 112 140 + 0 0.99 0.58 0.52 0.49 0.43 0.44 0.46 0.52 0.54 + 1 0.98 0.43 0.56 0.50 0.44 0.45 0.50 0.56 0.57 + 2 0.99 0.41 0.57 0.51 0.45 0.47 0.48 0.60 0.61 + 4 0.99 0.45 0.59 0.53 0.48 0.49 0.52 0.64 0.65 + 8 1.00 0.66 0.71 0.63 0.56 0.59 0.66 0.72 0.71 + 16 0.97 0.78 0.91 0.73 0.67 0.70 0.79 0.80 0.80 + 32 0.95 1.17 0.98 0.87 0.82 0.86 0.89 0.90 0.90 + 64 0.96 0.95 1.01 1.01 0.98 1.00 1.03 0.99 0.99 + 128 0.99 1.01 1.01 1.17 1.08 1.12 1.02 0.97 1.02 + + non-critical-length: 32 + 1 2 4 8 16 32 64 112 140 + 0 1.03 0.97 0.75 0.65 0.58 0.58 0.56 0.70 0.70 + 1 0.94 0.95 0.76 0.65 0.58 0.58 0.61 0.71 0.72 + 2 0.97 0.96 0.77 0.66 0.58 0.59 0.62 0.74 0.74 + 4 0.99 0.96 0.78 0.66 0.60 0.61 0.66 0.76 0.77 + 8 0.99 0.99 0.84 0.70 0.64 0.66 0.71 0.80 0.80 + 16 0.98 0.97 0.95 0.76 0.70 0.73 0.81 0.85 0.84 + 32 1.04 1.12 1.04 0.89 0.82 0.86 0.93 0.91 0.91 + 64 0.99 1.15 1.07 1.00 0.99 1.01 1.05 0.99 0.99 + 128 1.00 1.21 1.20 1.22 1.25 1.31 1.12 1.10 0.99 + + non-critical-length: 128 + 1 2 4 8 16 32 64 112 140 + 0 1.02 1.00 0.99 0.67 0.61 0.61 0.61 0.74 0.73 + 1 0.95 0.99 1.00 0.68 0.61 0.60 0.60 0.74 0.74 + 2 1.00 1.04 1.00 0.68 0.59 0.61 0.65 0.76 0.76 + 4 1.00 0.96 0.98 0.70 0.63 0.63 0.67 0.78 0.77 + 8 1.01 1.02 0.89 0.73 0.65 0.67 0.71 0.81 0.80 + 16 0.99 0.96 0.96 0.79 0.71 0.73 0.80 0.84 0.84 + 32 0.99 0.95 1.05 0.89 0.84 0.85 0.94 0.92 0.91 + 64 1.00 0.99 1.16 1.04 1.00 1.02 1.06 0.99 0.99 + 128 1.00 1.06 0.98 1.14 1.39 1.26 1.08 1.02 0.98 + + There is regression in large critical section. But adaptive mutex is + aimed for "quick" locks. Small critical section is more common when + users choose to use adaptive pthread_mutex. + + Signed-off-by: Wangyang Guo + Reviewed-by: H.J. Lu + (cherry picked from commit 8162147872491bb5b48e91543b19c49a29ae6b6d) + +diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c +index bbe754a272b97d91..8f3f687f2a151d16 100644 +--- a/nptl/pthread_mutex_lock.c ++++ b/nptl/pthread_mutex_lock.c +@@ -139,14 +139,26 @@ PTHREAD_MUTEX_LOCK (pthread_mutex_t *mutex) + int cnt = 0; + int max_cnt = MIN (max_adaptive_count (), + mutex->__data.__spins * 2 + 10); ++ int spin_count, exp_backoff = 1; ++ unsigned int jitter = get_jitter (); + do + { +- if (cnt++ >= max_cnt) ++ /* In each loop, spin count is exponential backoff plus ++ random jitter, random range is [0, exp_backoff-1]. */ ++ spin_count = exp_backoff + (jitter & (exp_backoff - 1)); ++ cnt += spin_count; ++ if (cnt >= max_cnt) + { ++ /* If cnt exceeds max spin count, just go to wait ++ queue. */ + LLL_MUTEX_LOCK (mutex); + break; + } +- atomic_spin_nop (); ++ do ++ atomic_spin_nop (); ++ while (--spin_count > 0); ++ /* Prepare for next loop. */ ++ exp_backoff = get_next_backoff (exp_backoff); + } + while (LLL_MUTEX_READ_LOCK (mutex) != 0 + || LLL_MUTEX_TRYLOCK (mutex) != 0); +diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h +index b968afc4c6b61b92..ed186ce3df1fde0c 100644 +--- a/sysdeps/nptl/pthreadP.h ++++ b/sysdeps/nptl/pthreadP.h +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include "pthread_mutex_conf.h" + + +diff --git a/sysdeps/nptl/pthread_mutex_backoff.h b/sysdeps/nptl/pthread_mutex_backoff.h +new file mode 100644 +index 0000000000000000..5b26c22ac789f54f +--- /dev/null ++++ b/sysdeps/nptl/pthread_mutex_backoff.h +@@ -0,0 +1,35 @@ ++/* Pthread mutex backoff configuration. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++#ifndef _PTHREAD_MUTEX_BACKOFF_H ++#define _PTHREAD_MUTEX_BACKOFF_H 1 ++ ++static inline unsigned int ++get_jitter (void) ++{ ++ /* Arch dependent random jitter, return 0 disables random. */ ++ return 0; ++} ++ ++static inline int ++get_next_backoff (int backoff) ++{ ++ /* Next backoff, return 1 disables mutex backoff. */ ++ return 1; ++} ++ ++#endif +diff --git a/sysdeps/x86_64/nptl/pthread_mutex_backoff.h b/sysdeps/x86_64/nptl/pthread_mutex_backoff.h +new file mode 100644 +index 0000000000000000..ec74c3d9db61864e +--- /dev/null ++++ b/sysdeps/x86_64/nptl/pthread_mutex_backoff.h +@@ -0,0 +1,39 @@ ++/* Pthread mutex backoff configuration. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++#ifndef _PTHREAD_MUTEX_BACKOFF_H ++#define _PTHREAD_MUTEX_BACKOFF_H 1 ++ ++#include ++ ++static inline unsigned int ++get_jitter (void) ++{ ++ return get_fast_jitter (); ++} ++ ++#define MAX_BACKOFF 16 ++ ++static inline int ++get_next_backoff (int backoff) ++{ ++ /* Binary expontial backoff. Limiting max backoff ++ can reduce latency in large critical section. */ ++ return (backoff < MAX_BACKOFF) ? backoff << 1 : backoff; ++} ++ ++#endif diff --git a/SOURCES/glibc-upstream-2.34-337.patch b/SOURCES/glibc-upstream-2.34-337.patch new file mode 100644 index 0000000..41aea50 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-337.patch @@ -0,0 +1,26 @@ +commit 95f5089d4a57cd1e738be908c7a628cb7d0ce512 +Author: Aurelien Jarno +Date: Mon Oct 3 23:16:46 2022 +0200 + + x86: include BMI1 and BMI2 in x86-64-v3 level + + The "System V Application Binary Interface AMD64 Architecture Processor + Supplement" mandates the BMI1 and BMI2 CPU features for the x86-64-v3 + level. + + Reviewed-by: Noah Goldstein + (cherry picked from commit b80f16adbd979831bf25ea491e1261e81885c2b6) + +diff --git a/sysdeps/x86/get-isa-level.h b/sysdeps/x86/get-isa-level.h +index aa80f56ca635e54b..785c25a835edf004 100644 +--- a/sysdeps/x86/get-isa-level.h ++++ b/sysdeps/x86/get-isa-level.h +@@ -47,6 +47,8 @@ get_isa_level (const struct cpu_features *cpu_features) + isa_level |= GNU_PROPERTY_X86_ISA_1_V2; + if (CPU_FEATURE_USABLE_P (cpu_features, AVX) + && CPU_FEATURE_USABLE_P (cpu_features, AVX2) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI1) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI2) + && CPU_FEATURE_USABLE_P (cpu_features, F16C) + && CPU_FEATURE_USABLE_P (cpu_features, FMA) + && CPU_FEATURE_USABLE_P (cpu_features, LZCNT) diff --git a/SOURCES/glibc-upstream-2.34-338.patch b/SOURCES/glibc-upstream-2.34-338.patch new file mode 100644 index 0000000..44dec62 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-338.patch @@ -0,0 +1,111 @@ +commit 414fc856ff4e011e62b88a21d30294637a152dc7 +Author: Aurelien Jarno +Date: Mon Oct 3 23:16:46 2022 +0200 + + x86-64: Require BMI2 for AVX2 str(n)casecmp implementations + + The AVX2 str(n)casecmp implementations use the 'bzhi' instruction, which + belongs to the BMI2 CPU feature. + + NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF + as BSF if the CPU doesn't support TZCNT, and produces the same result + for non-zero input. + + Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S") + Partially resolves: BZ #29611 + + Reviewed-by: Noah Goldstein + (cherry picked from commit 10f79d3670b036925da63dc532b122d27ce65ff8) + +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index 8d649e263eb24b8a..ca64b34c146a76f9 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -386,13 +386,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL (i, name, strcasecmp, + IFUNC_IMPL_ADD (array, i, strcasecmp, + (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW)), ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), + __strcasecmp_evex) + IFUNC_IMPL_ADD (array, i, strcasecmp, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __strcasecmp_avx2) + IFUNC_IMPL_ADD (array, i, strcasecmp, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __strcasecmp_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strcasecmp, +@@ -407,13 +410,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL (i, name, strcasecmp_l, + IFUNC_IMPL_ADD (array, i, strcasecmp, + (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW)), ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), + __strcasecmp_l_evex) + IFUNC_IMPL_ADD (array, i, strcasecmp, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __strcasecmp_l_avx2) + IFUNC_IMPL_ADD (array, i, strcasecmp, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __strcasecmp_l_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strcasecmp_l, +@@ -542,13 +548,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL (i, name, strncasecmp, + IFUNC_IMPL_ADD (array, i, strncasecmp, + (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW)), ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), + __strncasecmp_evex) + IFUNC_IMPL_ADD (array, i, strncasecmp, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __strncasecmp_avx2) + IFUNC_IMPL_ADD (array, i, strncasecmp, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __strncasecmp_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strncasecmp, +@@ -564,13 +573,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL (i, name, strncasecmp_l, + IFUNC_IMPL_ADD (array, i, strncasecmp, + (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW)), ++ & CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), + __strncasecmp_l_evex) + IFUNC_IMPL_ADD (array, i, strncasecmp, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __strncasecmp_l_avx2) + IFUNC_IMPL_ADD (array, i, strncasecmp, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __strncasecmp_l_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strncasecmp_l, +diff --git a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h +index 40819caf5ab10337..e61d6e9497bce9d9 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h ++++ b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h +@@ -32,6 +32,7 @@ IFUNC_SELECTOR (void) + const struct cpu_features* cpu_features = __get_cpu_features (); + + if (CPU_FEATURE_USABLE_P (cpu_features, AVX2) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI2) + && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load)) + { + if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) diff --git a/SOURCES/glibc-upstream-2.34-339.patch b/SOURCES/glibc-upstream-2.34-339.patch new file mode 100644 index 0000000..4820b0f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-339.patch @@ -0,0 +1,55 @@ +commit e1561d8cf005a23bcaf514802854b493829a25b1 +Author: Aurelien Jarno +Date: Mon Oct 3 23:16:46 2022 +0200 + + x86-64: Require BMI2 for AVX2 strcmp implementation + + The AVX2 strcmp implementation uses the 'bzhi' instruction, which + belongs to the BMI2 CPU feature. + + NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF + as BSF if the CPU doesn't support TZCNT, and produces the same result + for non-zero input. + + Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S") + Partially resolves: BZ #29611 + + Reviewed-by: Noah Goldstein + (cherry picked from commit 4d64c6445735e9b34e2ac8e369312cbfc2f88e17) + +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index ca64b34c146a76f9..70931f15985334af 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -503,10 +503,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/strcmp.c. */ + IFUNC_IMPL (i, name, strcmp, + IFUNC_IMPL_ADD (array, i, strcmp, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __strcmp_avx2) + IFUNC_IMPL_ADD (array, i, strcmp, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __strcmp_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strcmp, +diff --git a/sysdeps/x86_64/multiarch/strcmp.c b/sysdeps/x86_64/multiarch/strcmp.c +index b457fb4c150e4407..0c0cd20a03278a2b 100644 +--- a/sysdeps/x86_64/multiarch/strcmp.c ++++ b/sysdeps/x86_64/multiarch/strcmp.c +@@ -40,11 +40,11 @@ IFUNC_SELECTOR (void) + const struct cpu_features* cpu_features = __get_cpu_features (); + + if (CPU_FEATURE_USABLE_P (cpu_features, AVX2) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI2) + && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load)) + { + if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) +- && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) +- && CPU_FEATURE_USABLE_P (cpu_features, BMI2)) ++ && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)) + return OPTIMIZE (evex); + + if (CPU_FEATURE_USABLE_P (cpu_features, RTM)) diff --git a/SOURCES/glibc-upstream-2.34-34.patch b/SOURCES/glibc-upstream-2.34-34.patch new file mode 100644 index 0000000..1828ac7 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-34.patch @@ -0,0 +1,41 @@ +commit 558168c78ea1eb8efb33959c1da9d6b5a997fd7b +Author: Siddhesh Poyarekar +Date: Wed Oct 6 21:48:35 2021 +0530 + + support: Also return fd when it is 0 + + The fd validity check in open_dev_null checks if fd > 0, which would + lead to a leaked fd if it is == 0. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 27b6edbb090f736b101f569620d8ad0e7217ddf8) + +diff --git a/support/support-open-dev-null-range.c b/support/support-open-dev-null-range.c +index 80d9dba50402ce12..66a850410557351b 100644 +--- a/support/support-open-dev-null-range.c ++++ b/support/support-open-dev-null-range.c +@@ -40,16 +40,16 @@ increase_nofile (void) + static int + open_dev_null (int flags, mode_t mode) + { +- int fd = open64 ("/dev/null", flags, mode); +- if (fd > 0) +- return fd; ++ int fd = open64 ("/dev/null", flags, mode); ++ if (fd >= 0) ++ return fd; + +- if (fd < 0 && errno != EMFILE) +- FAIL_EXIT1 ("open64 (\"/dev/null\", 0x%x, 0%o): %m", flags, mode); ++ if (fd < 0 && errno != EMFILE) ++ FAIL_EXIT1 ("open64 (\"/dev/null\", 0x%x, 0%o): %m", flags, mode); + +- increase_nofile (); ++ increase_nofile (); + +- return xopen ("/dev/null", flags, mode); ++ return xopen ("/dev/null", flags, mode); + } + + struct range diff --git a/SOURCES/glibc-upstream-2.34-340.patch b/SOURCES/glibc-upstream-2.34-340.patch new file mode 100644 index 0000000..077c288 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-340.patch @@ -0,0 +1,62 @@ +commit b9cbb8dd48b545f3b36b5d411481dc0bd118ee94 +Author: Aurelien Jarno +Date: Mon Oct 3 23:16:46 2022 +0200 + + x86-64: Require BMI2 for AVX2 strncmp implementation + + The AVX2 strncmp implementations uses the 'bzhi' instruction, which + belongs to the BMI2 CPU feature. + + NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF + as BSF if the CPU doesn't support TZCNT, and produces the same result + for non-zero input. + + Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S") + Partially resolves: BZ #29611 + + Reviewed-by: Noah Goldstein + (cherry picked from commit fc7de1d9b99ae1676bc626ddca422d7abee0eb48) + +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index 70931f15985334af..34d5f6efe5421014 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -1022,15 +1022,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/strncmp.c. */ + IFUNC_IMPL (i, name, strncmp, + IFUNC_IMPL_ADD (array, i, strncmp, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __strncmp_avx2) + IFUNC_IMPL_ADD (array, i, strncmp, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __strncmp_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strncmp, + (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW)), ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2)), + __strncmp_evex) + IFUNC_IMPL_ADD (array, i, strncmp, CPU_FEATURE_USABLE (SSE4_2), + __strncmp_sse42) +diff --git a/sysdeps/x86_64/multiarch/strncmp.c b/sysdeps/x86_64/multiarch/strncmp.c +index f94a421784bfe923..7632d7b2dd4447aa 100644 +--- a/sysdeps/x86_64/multiarch/strncmp.c ++++ b/sysdeps/x86_64/multiarch/strncmp.c +@@ -39,11 +39,11 @@ IFUNC_SELECTOR (void) + const struct cpu_features* cpu_features = __get_cpu_features (); + + if (CPU_FEATURE_USABLE_P (cpu_features, AVX2) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI2) + && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load)) + { + if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) +- && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) +- && CPU_FEATURE_USABLE_P (cpu_features, BMI2)) ++ && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)) + return OPTIMIZE (evex); + + if (CPU_FEATURE_USABLE_P (cpu_features, RTM)) diff --git a/SOURCES/glibc-upstream-2.34-341.patch b/SOURCES/glibc-upstream-2.34-341.patch new file mode 100644 index 0000000..6e9814a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-341.patch @@ -0,0 +1,51 @@ +commit 67e863742d98c990b3d3b814b80042c0fa0d50a5 +Author: Aurelien Jarno +Date: Mon Oct 3 23:16:46 2022 +0200 + + x86-64: Require BMI2 for AVX2 wcs(n)cmp implementations + + The AVX2 wcs(n)cmp implementations use the 'bzhi' instruction, which + belongs to the BMI2 CPU feature. + + NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF + as BSF if the CPU doesn't support TZCNT, and produces the same result + for non-zero input. + + Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S") + Partially resolves: BZ #29611 + + Reviewed-by: Noah Goldstein + (cherry picked from commit f31a5a884ed84bd37032729d4d1eb9d06c9f3c29) + +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index 34d5f6efe5421014..e76a991dc671c1a9 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -693,10 +693,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/wcscmp.c. */ + IFUNC_IMPL (i, name, wcscmp, + IFUNC_IMPL_ADD (array, i, wcscmp, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __wcscmp_avx2) + IFUNC_IMPL_ADD (array, i, wcscmp, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __wcscmp_avx2_rtm) + IFUNC_IMPL_ADD (array, i, wcscmp, +@@ -709,10 +711,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/wcsncmp.c. */ + IFUNC_IMPL (i, name, wcsncmp, + IFUNC_IMPL_ADD (array, i, wcsncmp, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __wcsncmp_avx2) + IFUNC_IMPL_ADD (array, i, wcsncmp, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __wcsncmp_avx2_rtm) + IFUNC_IMPL_ADD (array, i, wcsncmp, diff --git a/SOURCES/glibc-upstream-2.34-342.patch b/SOURCES/glibc-upstream-2.34-342.patch new file mode 100644 index 0000000..8750786 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-342.patch @@ -0,0 +1,61 @@ +commit 94b9c1b6409e34f3f0b2339f77d7ee78087422eb +Author: Aurelien Jarno +Date: Mon Oct 3 23:16:46 2022 +0200 + + x86-64: Require BMI2 for AVX2 (raw|w)memchr implementations + + The AVX2 memchr, rawmemchr and wmemchr implementations use the 'bzhi' + and 'sarx' instructions, which belongs to the BMI2 CPU feature. + + Fixes: acfd088a1963 ("x86: Optimize memchr-avx2.S") + Partially resolves: BZ #29611 + + Reviewed-by: Noah Goldstein + (cherry picked from commit e3e7fab7fe5186d18ca2046d99ba321c27db30ad) + +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index e76a991dc671c1a9..81640cf00664e3ed 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -41,10 +41,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/memchr.c. */ + IFUNC_IMPL (i, name, memchr, + IFUNC_IMPL_ADD (array, i, memchr, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __memchr_avx2) + IFUNC_IMPL_ADD (array, i, memchr, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __memchr_avx2_rtm) + IFUNC_IMPL_ADD (array, i, memchr, +@@ -283,10 +285,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/rawmemchr.c. */ + IFUNC_IMPL (i, name, rawmemchr, + IFUNC_IMPL_ADD (array, i, rawmemchr, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __rawmemchr_avx2) + IFUNC_IMPL_ADD (array, i, rawmemchr, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __rawmemchr_avx2_rtm) + IFUNC_IMPL_ADD (array, i, rawmemchr, +@@ -787,10 +791,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/wmemchr.c. */ + IFUNC_IMPL (i, name, wmemchr, + IFUNC_IMPL_ADD (array, i, wmemchr, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2)), + __wmemchr_avx2) + IFUNC_IMPL_ADD (array, i, wmemchr, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __wmemchr_avx2_rtm) + IFUNC_IMPL_ADD (array, i, wmemchr, diff --git a/SOURCES/glibc-upstream-2.34-343.patch b/SOURCES/glibc-upstream-2.34-343.patch new file mode 100644 index 0000000..dd9d4b8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-343.patch @@ -0,0 +1,56 @@ +commit 36d6b9be3d7008a78e1f6e2e2db1947b76b206d8 +Author: Aurelien Jarno +Date: Mon Oct 3 23:16:46 2022 +0200 + + x86-64: Require BMI2 and LZCNT for AVX2 memrchr implementation + + The AVX2 memrchr implementation uses the 'shlxl' instruction, which + belongs to the BMI2 CPU feature and uses the 'lzcnt' instruction, which + belongs to the LZCNT CPU feature. + + Fixes: af5306a735eb ("x86: Optimize memrchr-avx2.S") + Partially resolves: BZ #29611 + + Reviewed-by: Noah Goldstein + (cherry picked from commit 3c0c78afabfed4b6fc161c159e628fbf14ff370b) + +diff --git a/sysdeps/x86_64/multiarch/ifunc-avx2.h b/sysdeps/x86_64/multiarch/ifunc-avx2.h +index 6de72f72724b81ba..52bd00ea5cab6b22 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-avx2.h ++++ b/sysdeps/x86_64/multiarch/ifunc-avx2.h +@@ -31,6 +31,7 @@ IFUNC_SELECTOR (void) + + if (CPU_FEATURE_USABLE_P (cpu_features, AVX2) + && CPU_FEATURE_USABLE_P (cpu_features, BMI2) ++ && CPU_FEATURE_USABLE_P (cpu_features, LZCNT) + && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load)) + { + if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL) +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index 81640cf00664e3ed..d1fc1e75d6706413 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -174,15 +174,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/memrchr.c. */ + IFUNC_IMPL (i, name, memrchr, + IFUNC_IMPL_ADD (array, i, memrchr, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) ++ && CPU_FEATURE_USABLE (LZCNT)), + __memrchr_avx2) + IFUNC_IMPL_ADD (array, i, memrchr, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI2) ++ && CPU_FEATURE_USABLE (LZCNT) + && CPU_FEATURE_USABLE (RTM)), + __memrchr_avx2_rtm) + IFUNC_IMPL_ADD (array, i, memrchr, + (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW)), ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI2) ++ && CPU_FEATURE_USABLE (LZCNT)), + __memrchr_evex) + + IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_sse2)) diff --git a/SOURCES/glibc-upstream-2.34-344.patch b/SOURCES/glibc-upstream-2.34-344.patch new file mode 100644 index 0000000..754168f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-344.patch @@ -0,0 +1,78 @@ +commit e570b865b53f33453d97160791a7d97e38bcc6e8 +Author: Aurelien Jarno +Date: Mon Oct 3 23:16:46 2022 +0200 + + x86-64: Require BMI1/BMI2 for AVX2 strrchr and wcsrchr implementations + + The AVX2 strrchr and wcsrchr implementation uses the 'blsmsk' + instruction which belongs to the BMI1 CPU feature and the 'shrx' + instruction, which belongs to the BMI2 CPU feature. + + Fixes: df7e295d18ff ("x86: Optimize {str|wcs}rchr-avx2") + Partially resolves: BZ #29611 + + Reviewed-by: Noah Goldstein + (cherry picked from commit 7e8283170c5d6805b609a040801d819e362a6292) + +diff --git a/sysdeps/x86_64/multiarch/ifunc-avx2.h b/sysdeps/x86_64/multiarch/ifunc-avx2.h +index 52bd00ea5cab6b22..877f007dd6e38fe8 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-avx2.h ++++ b/sysdeps/x86_64/multiarch/ifunc-avx2.h +@@ -30,6 +30,7 @@ IFUNC_SELECTOR (void) + const struct cpu_features* cpu_features = __get_cpu_features (); + + if (CPU_FEATURE_USABLE_P (cpu_features, AVX2) ++ && CPU_FEATURE_USABLE_P (cpu_features, BMI1) + && CPU_FEATURE_USABLE_P (cpu_features, BMI2) + && CPU_FEATURE_USABLE_P (cpu_features, LZCNT) + && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load)) +diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +index d1fc1e75d6706413..84f9e73e2b7df816 100644 +--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -498,15 +498,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/strrchr.c. */ + IFUNC_IMPL (i, name, strrchr, + IFUNC_IMPL_ADD (array, i, strrchr, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI1) ++ && CPU_FEATURE_USABLE (BMI2)), + __strrchr_avx2) + IFUNC_IMPL_ADD (array, i, strrchr, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI1) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __strrchr_avx2_rtm) + IFUNC_IMPL_ADD (array, i, strrchr, + (CPU_FEATURE_USABLE (AVX512VL) +- && CPU_FEATURE_USABLE (AVX512BW)), ++ && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI1) ++ && CPU_FEATURE_USABLE (BMI2)), + __strrchr_evex) + IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_sse2)) + +@@ -687,15 +693,20 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/x86_64/multiarch/wcsrchr.c. */ + IFUNC_IMPL (i, name, wcsrchr, + IFUNC_IMPL_ADD (array, i, wcsrchr, +- CPU_FEATURE_USABLE (AVX2), ++ (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI1) ++ && CPU_FEATURE_USABLE (BMI2)), + __wcsrchr_avx2) + IFUNC_IMPL_ADD (array, i, wcsrchr, + (CPU_FEATURE_USABLE (AVX2) ++ && CPU_FEATURE_USABLE (BMI1) ++ && CPU_FEATURE_USABLE (BMI2) + && CPU_FEATURE_USABLE (RTM)), + __wcsrchr_avx2_rtm) + IFUNC_IMPL_ADD (array, i, wcsrchr, + (CPU_FEATURE_USABLE (AVX512VL) + && CPU_FEATURE_USABLE (AVX512BW) ++ && CPU_FEATURE_USABLE (BMI1) + && CPU_FEATURE_USABLE (BMI2)), + __wcsrchr_evex) + IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_sse2)) diff --git a/SOURCES/glibc-upstream-2.34-345.patch b/SOURCES/glibc-upstream-2.34-345.patch new file mode 100644 index 0000000..c0028eb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-345.patch @@ -0,0 +1,46 @@ +commit e3976287b22422787f3cc6fc9adda58304b55bd9 +Author: Siddhesh Poyarekar +Date: Tue Oct 4 18:40:25 2022 -0400 + + nscd: Drop local address tuple variable [BZ #29607] + + When a request needs to be resent (e.g. due to insufficient buffer + space), the references to subsequent tuples in the local variable are + stale and should not be used. This used to work by accident before, but + since 1d495912a it no longer does. Instead of trying to reset it, just + let gethostbyname4_r write into TUMPBUF6 for us, thus maintaining a + consistent state at all times. This is now consistent with what is done + in gaih_inet for getaddrinfo. + + Resolves: BZ #29607 + Reported-by: Holger Hoffstätte + Tested-by: Holger Hoffstätte + Reviewed-by: Carlos O'Donell + (cherry picked from commit 6e33e5c4b73cea7b8aa3de0947123db16200fb65) + +diff --git a/nscd/aicache.c b/nscd/aicache.c +index 737ace11cc276021..3b300ad9b7db2297 100644 +--- a/nscd/aicache.c ++++ b/nscd/aicache.c +@@ -111,11 +111,10 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, + "gethostbyname4_r"); + if (fct4 != NULL) + { +- struct gaih_addrtuple atmem; + struct gaih_addrtuple *at; + while (1) + { +- at = &atmem; ++ at = NULL; + rc6 = 0; + herrno = 0; + status[1] = DL_CALL_FCT (fct4, (key, &at, +@@ -138,7 +137,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, + goto next_nip; + + /* We found the data. Count the addresses and the size. */ +- for (const struct gaih_addrtuple *at2 = at = &atmem; at2 != NULL; ++ for (const struct gaih_addrtuple *at2 = at; at2 != NULL; + at2 = at2->next) + { + ++naddrs; diff --git a/SOURCES/glibc-upstream-2.34-346.patch b/SOURCES/glibc-upstream-2.34-346.patch new file mode 100644 index 0000000..a0fe300 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-346.patch @@ -0,0 +1,55 @@ +commit c95ef423d78d9a2ec0a8e4141c78165434685c6f +Author: Florian Weimer +Date: Tue Sep 13 16:10:20 2022 +0200 + + nss: Implement --no-addrconfig option for getent + + The ahosts, ahostsv4, ahostsv6 commands unconditionally pass + AI_ADDRCONFIG to getaddrinfo, which is not always desired. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit a623f13adfac47c8634a7288e08f821a846bc650) + +diff --git a/nss/getent.c b/nss/getent.c +index ec48ba4bf1f5f788..0f4d549b05da73ac 100644 +--- a/nss/getent.c ++++ b/nss/getent.c +@@ -59,6 +59,8 @@ static const struct argp_option args_options[] = + { + { "service", 's', N_("CONFIG"), 0, N_("Service configuration to be used") }, + { "no-idn", 'i', NULL, 0, N_("disable IDN encoding") }, ++ { "no-addrconfig", 'A', NULL, 0, ++ N_("do not filter out unsupported IPv4/IPv6 addresses (with ahosts*)") }, + { NULL, 0, NULL, 0, NULL }, + }; + +@@ -80,6 +82,9 @@ static struct argp argp = + /* Additional getaddrinfo flags for IDN encoding. */ + static int idn_flags = AI_IDN | AI_CANONIDN; + ++/* Set to 0 by --no-addrconfig. */ ++static int addrconfig_flags = AI_ADDRCONFIG; ++ + /* Print the version information. */ + static void + print_version (FILE *stream, struct argp_state *state) +@@ -347,7 +352,7 @@ ahosts_keys_int (int af, int xflags, int number, char *key[]) + + struct addrinfo hint; + memset (&hint, '\0', sizeof (hint)); +- hint.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME ++ hint.ai_flags = (AI_V4MAPPED | addrconfig_flags | AI_CANONNAME + | idn_flags | xflags); + hint.ai_family = af; + +@@ -906,6 +911,10 @@ parse_option (int key, char *arg, struct argp_state *state) + idn_flags = 0; + break; + ++ case 'A': ++ addrconfig_flags = 0; ++ break; ++ + default: + return ARGP_ERR_UNKNOWN; + } diff --git a/SOURCES/glibc-upstream-2.34-347.patch b/SOURCES/glibc-upstream-2.34-347.patch new file mode 100644 index 0000000..408e38f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-347.patch @@ -0,0 +1,38 @@ +commit 16c7ed6e68c13e5a5efd8ab464ebf9d07b4b0bb3 +Author: Florian Weimer +Date: Tue Sep 13 16:11:40 2022 +0200 + + nss: Fix tst-nss-files-hosts-long on single-stack hosts (bug 24816) + + getent implicitly passes AI_ADDRCONFIG to getaddrinfo by default. + Use --no-addrconfig to suppress that, so that both IPv4 and IPv6 + lookups succeed even if the address family is not supported by the + host. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit c75d20b5b27b0a60f0678236f51a4d3b0b058c00) + +diff --git a/nss/tst-nss-files-hosts-long.c b/nss/tst-nss-files-hosts-long.c +index 00f8bea409e0b4cb..42676ba4056dbde2 100644 +--- a/nss/tst-nss-files-hosts-long.c ++++ b/nss/tst-nss-files-hosts-long.c +@@ -28,14 +28,15 @@ do_test (void) + { + int ret; + +- /* Run getent to fetch the IPv4 address for host test4. +- This forces /etc/hosts to be parsed. */ +- ret = system("getent ahostsv4 test4"); ++ /* Run getent to fetch the IPv4 address for host test4. This forces ++ /etc/hosts to be parsed. Use --no-addrconfig to return addresses ++ even in an IPv6-only environment. */ ++ ret = system("getent --no-addrconfig ahostsv4 test4"); + if (ret != 0) + FAIL_EXIT1("ahostsv4 failed"); + + /* Likewise for IPv6. */ +- ret = system("getent ahostsv6 test6"); ++ ret = system("getent --no-addrconfig ahostsv6 test6"); + if (ret != 0) + FAIL_EXIT1("ahostsv6 failed"); + diff --git a/SOURCES/glibc-upstream-2.34-348.patch b/SOURCES/glibc-upstream-2.34-348.patch new file mode 100644 index 0000000..c33b026 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-348.patch @@ -0,0 +1,47 @@ +commit d5313bcb7e56cd949ca920bb0c741a1d1d4093cf +Author: Florian Weimer +Date: Fri Sep 23 19:30:57 2022 +0200 + + nss: Use shared prefix in IPv4 address in tst-reload1 + + Otherwise, sorting based on the longest-matching prefix in + getaddrinfo can reorder the addresses in ways the test does not + expect, depending on the IPv4 address of the host. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit c02e29a0ba47d636281e1a026444a1a0a254aa12) + +diff --git a/nss/tst-reload1.c b/nss/tst-reload1.c +index 27a18ed9c37607bb..844cfcddc5e0f638 100644 +--- a/nss/tst-reload1.c ++++ b/nss/tst-reload1.c +@@ -43,12 +43,12 @@ static struct passwd pwd_table_1[] = { + + static const char *hostaddr_5[] = + { +- "ABCD", "abcd", "1234", NULL ++ "ABCd", "ABCD", "ABC4", NULL + }; + + static const char *hostaddr_15[] = + { +- "4321", "ghij", NULL ++ "4321", "4322", NULL + }; + + static const char *hostaddr_25[] = +@@ -86,12 +86,12 @@ static const char *hostaddr_6[] = + + static const char *hostaddr_16[] = + { +- "7890", "a1b2", NULL ++ "7890", "7891", NULL + }; + + static const char *hostaddr_26[] = + { +- "qwer", "tyui", NULL ++ "qwer", "qweR", NULL + }; + + static struct hostent host_table_2[] = { diff --git a/SOURCES/glibc-upstream-2.34-349.patch b/SOURCES/glibc-upstream-2.34-349.patch new file mode 100644 index 0000000..0b05961 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-349.patch @@ -0,0 +1,92 @@ +commit 9f55d2e7c42e6ca862a25d3ee3eb2b367811c30d +Author: Florian Weimer +Date: Fri Oct 14 12:43:07 2022 +0200 + + elf: Do not completely clear reused namespace in dlmopen (bug 29600) + + The data in the _ns_debug member must be preserved, otherwise + _dl_debug_initialize enters an infinite loop. To be conservative, + only clear the libc_map member for now, to fix bug 29528. + + Fixes commit d0e357ff45a75553dee3b17ed7d303bfa544f6fe + ("elf: Call __libc_early_init for reused namespaces (bug 29528)"), + by reverting most of it. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 2c42257314536b94cc8d52edede86e94e98c1436) + (Conflict in elf/dl-open.c due to missing _r_debug namespace support.) + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 1ab3c7b5ac2fbc45..633b047ad2497296 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -839,15 +839,13 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, + _dl_signal_error (EINVAL, file, NULL, N_("\ + no more namespaces available for dlmopen()")); + } ++ else if (nsid == GL(dl_nns)) ++ { ++ __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock); ++ ++GL(dl_nns); ++ } + +- if (nsid == GL(dl_nns)) +- ++GL(dl_nns); +- +- /* Initialize the new namespace. Most members are +- zero-initialized, only the lock needs special treatment. */ +- memset (&GL(dl_ns)[nsid], 0, sizeof (GL(dl_ns)[nsid])); +- __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock); +- ++ GL(dl_ns)[nsid].libc_map = NULL; + _dl_debug_initialize (0, nsid)->r_state = RT_CONSISTENT; + } + /* Never allow loading a DSO in a namespace which is empty. Such +diff --git a/elf/tst-dlmopen-twice.c b/elf/tst-dlmopen-twice.c +index 449f3c8fa9f2aa01..70c71fe19c7d0bf9 100644 +--- a/elf/tst-dlmopen-twice.c ++++ b/elf/tst-dlmopen-twice.c +@@ -16,18 +16,38 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#include + #include ++#include + +-static int +-do_test (void) ++/* Run the test multiple times, to check finding a new namespace while ++ another namespace is already in use. This used to trigger bug 29600. */ ++static void ++recurse (int depth) + { +- void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", RTLD_NOW); ++ if (depth == 0) ++ return; ++ ++ printf ("info: running at depth %d\n", depth); ++ void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", ++ RTLD_NOW); + xdlclose (handle); + handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod2.so", RTLD_NOW); + int (*run_check) (void) = xdlsym (handle, "run_check"); + TEST_COMPARE (run_check (), 0); ++ recurse (depth - 1); + xdlclose (handle); ++} ++ ++static int ++do_test (void) ++{ ++ /* First run the test without nesting. */ ++ recurse (1); ++ ++ /* Then with nesting. The constant needs to be less than the ++ internal DL_NNS namespace constant. */ ++ recurse (10); + return 0; + } + diff --git a/SOURCES/glibc-upstream-2.34-35.patch b/SOURCES/glibc-upstream-2.34-35.patch new file mode 100644 index 0000000..cdee1af --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-35.patch @@ -0,0 +1,83 @@ +commit cb44a620ef2336449af60694b6696efced161774 +Author: Stefan Liebler +Date: Tue Oct 5 16:14:10 2021 +0200 + + S390: Add PCI_MIO and SIE HWCAPs + + Both new HWCAPs were introduced in these kernel commits: + - 7e8403ecaf884f307b627f3c371475913dd29292 + "s390: add HWCAP_S390_PCI_MIO to ELF hwcaps" + - 7e82523f2583e9813e4109df3656707162541297 + "s390/hwcaps: make sie capability regular hwcap" + + Also note that the kernel commit 511ad531afd4090625def4d9aba1f5227bd44b8e + "s390/hwcaps: shorten HWCAP defines" has shortened the prefix of the macros + from "HWCAP_S390_" to "HWCAP_". For compatibility reasons, we do not + change the prefix in public glibc header file. + + (cherry picked from commit f2e06656d04a9fcb0603802a4f8ce7aa3a1f055e) + +diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c +index c174e27b3559c57c..155f0bd99eccb3f9 100644 +--- a/sysdeps/s390/dl-procinfo.c ++++ b/sysdeps/s390/dl-procinfo.c +@@ -46,13 +46,13 @@ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_s390_cap_flags + #else +-PROCINFO_CLASS const char _dl_s390_cap_flags[21][9] ++PROCINFO_CLASS const char _dl_s390_cap_flags[23][9] + #endif + #ifndef PROCINFO_DECL + = { + "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", + "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt", +- "vxp2", "nnpa" ++ "vxp2", "nnpa", "pcimio", "sie" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index 2d9c3058083e5dda..e4e3e334a5b3d47c 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 21 ++#define _DL_HWCAP_COUNT 23 + + #define _DL_PLATFORMS_COUNT 10 + +@@ -63,6 +63,8 @@ enum + HWCAP_S390_DFLT = 1 << 18, + HWCAP_S390_VXRS_PDE2 = 1 << 19, + HWCAP_S390_NNPA = 1 << 20, ++ HWCAP_S390_PCI_MIO = 1 << 21, ++ HWCAP_S390_SIE = 1 << 22, + }; + + #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ +diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +index e9bd3684db862d1b..00e73a3e3bfdb711 100644 +--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h ++++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +@@ -22,6 +22,11 @@ + + /* + * The following must match the kernels asm/elf.h. ++ * Note: The kernel commit 511ad531afd4090625def4d9aba1f5227bd44b8e ++ * "s390/hwcaps: shorten HWCAP defines" has shortened the prefix of the macros ++ * from "HWCAP_S390_" to "HWCAP_". For compatibility reasons, we do not ++ * change the prefix in public glibc header file. ++ * + * Note that these are *not* the same as the STORE FACILITY LIST bits. + */ + #define HWCAP_S390_ESAN3 1 +@@ -48,3 +53,5 @@ + #define HWCAP_S390_DFLT 262144 + #define HWCAP_S390_VXRS_PDE2 524288 + #define HWCAP_S390_NNPA 1048576 ++#define HWCAP_S390_PCI_MIO 2097152 ++#define HWCAP_S390_SIE 4194304 diff --git a/SOURCES/glibc-upstream-2.34-350.patch b/SOURCES/glibc-upstream-2.34-350.patch new file mode 100644 index 0000000..7ab515b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-350.patch @@ -0,0 +1,861 @@ +commit ca5df795459b9242cd7d787ebf71a09be2244577 +Author: Adhemerval Zanella +Date: Wed Oct 19 19:14:04 2022 -0300 + + linux: Fix generic struct_stat for 64 bit time (BZ# 29657) + + The generic Linux struct_stat misses the conditionals to use + bits/struct_stat_time64_helper.h in the __USE_TIME_BITS64 for + architecture that uses __TIMESIZE == 32 (currently csky and nios2). + + Since newer ports should not support 32 bit time_t, the generic + implementation should be used as default. + + For arm, hppa, and sh a copy of default struct_stat is added, + while for csky and nios a new one based on generic is used, along + with conditionals to use bits/struct_stat_time64_helper.h. + + The default struct_stat is also replaced with the generic one. + + Checked on aarch64-linux-gnu and arm-linux-gnueabihf. + + (cherry picked from commit 7a6ca82f8007ddbd43e2b8fce806ba7101ee47f5) + +diff --git a/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h +new file mode 100644 +index 0000000000000000..30ee6279d2701242 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h +@@ -0,0 +1,139 @@ ++/* Definition for struct stat. Linux/arm version. ++ Copyright (C) 2020-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#if !defined _SYS_STAT_H && !defined _FCNTL_H ++# error "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_STRUCT_STAT_H ++#define _BITS_STRUCT_STAT_H 1 ++ ++#include ++#include ++ ++struct stat ++ { ++#ifdef __USE_TIME_BITS64 ++# include ++#else ++ __dev_t st_dev; /* Device. */ ++ unsigned short int __pad1; ++# ifndef __USE_FILE_OFFSET64 ++ __ino_t st_ino; /* File serial number. */ ++# else ++ __ino_t __st_ino; /* 32bit file serial number. */ ++# endif ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned short int __pad2; ++# ifndef __USE_FILE_OFFSET64 ++ __off_t st_size; /* Size of file, in bytes. */ ++# else ++ __off64_t st_size; /* Size of file, in bytes. */ ++# endif ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++# ifndef __USE_FILE_OFFSET64 ++ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ ++# else ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# endif ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++# ifndef __USE_FILE_OFFSET64 ++ unsigned long int __glibc_reserved4; ++ unsigned long int __glibc_reserved5; ++# else ++ __ino64_t st_ino; /* File serial number. */ ++# endif ++#endif /* __USE_TIME_BITS64 */ ++ }; ++ ++#ifdef __USE_LARGEFILE64 ++struct stat64 ++ { ++# ifdef __USE_TIME_BITS64 ++# include ++# else ++ __dev_t st_dev; /* Device. */ ++ unsigned int __pad1; ++ ++ __ino_t __st_ino; /* 32bit file serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned int __pad2; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ __ino64_t st_ino; /* File serial number. */ ++# endif /* __USE_TIME_BITS64 */ ++ }; ++#endif ++ ++/* Tell code we have these members. */ ++#define _STATBUF_ST_BLKSIZE ++#define _STATBUF_ST_RDEV ++/* Nanosecond resolution time values are supported. */ ++#define _STATBUF_ST_NSEC ++ ++ ++#endif /* _BITS_STRUCT_STAT_H */ +diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat.h b/sysdeps/unix/sysv/linux/bits/struct_stat.h +index 298418966f4d6e0b..32ef511ae5728276 100644 +--- a/sysdeps/unix/sysv/linux/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/bits/struct_stat.h +@@ -26,37 +26,36 @@ + #include + #include + +-struct stat +- { +-#ifdef __USE_TIME_BITS64 +-# include +-#else +- __dev_t st_dev; /* Device. */ +- unsigned short int __pad1; +-# ifndef __USE_FILE_OFFSET64 +- __ino_t st_ino; /* File serial number. */ +-# else +- __ino_t __st_ino; /* 32bit file serial number. */ ++#if defined __USE_FILE_OFFSET64 ++# define __field64(type, type64, name) type64 name ++#elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T ++# if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T ++# error "ino_t and off_t must both be the same type" + # endif +- __mode_t st_mode; /* File mode. */ +- __nlink_t st_nlink; /* Link count. */ +- __uid_t st_uid; /* User ID of the file's owner. */ +- __gid_t st_gid; /* Group ID of the file's group.*/ +- __dev_t st_rdev; /* Device number, if device. */ +- unsigned short int __pad2; +-# ifndef __USE_FILE_OFFSET64 +- __off_t st_size; /* Size of file, in bytes. */ +-# else +- __off64_t st_size; /* Size of file, in bytes. */ +-# endif +- __blksize_t st_blksize; /* Optimal block size for I/O. */ ++# define __field64(type, type64, name) type name ++#elif __BYTE_ORDER == __LITTLE_ENDIAN ++# define __field64(type, type64, name) \ ++ type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad ++#else ++# define __field64(type, type64, name) \ ++ int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name ++#endif + +-# ifndef __USE_FILE_OFFSET64 +- __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ +-# else +- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ +-# endif +-# ifdef __USE_XOPEN2K8 ++struct stat ++ { ++ __dev_t st_dev; /* Device. */ ++ __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ __dev_t __pad1; ++ __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ int __pad2; ++ __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ ++#ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -66,47 +65,38 @@ struct stat + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-# define st_atime st_atim.tv_sec /* Backward compatibility. */ +-# define st_mtime st_mtim.tv_sec +-# define st_ctime st_ctim.tv_sec +-# else ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++#else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-# endif +-# ifndef __USE_FILE_OFFSET64 +- unsigned long int __glibc_reserved4; +- unsigned long int __glibc_reserved5; +-# else +- __ino64_t st_ino; /* File serial number. */ +-# endif +-#endif /* __USE_TIME_BITS64 */ ++#endif ++ int __glibc_reserved[2]; + }; + ++#undef __field64 ++ + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 +-# include +-# else +- __dev_t st_dev; /* Device. */ +- unsigned int __pad1; +- +- __ino_t __st_ino; /* 32bit file serial number. */ +- __mode_t st_mode; /* File mode. */ +- __nlink_t st_nlink; /* Link count. */ +- __uid_t st_uid; /* User ID of the file's owner. */ +- __gid_t st_gid; /* Group ID of the file's group.*/ +- __dev_t st_rdev; /* Device number, if device. */ +- unsigned int __pad2; +- __off64_t st_size; /* Size of file, in bytes. */ +- __blksize_t st_blksize; /* Optimal block size for I/O. */ +- +- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ +-# ifdef __USE_XOPEN2K8 ++ __dev_t st_dev; /* Device. */ ++ __ino64_t st_ino; /* File serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ __dev_t __pad1; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ int __pad2; ++ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ ++#ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -116,16 +106,15 @@ struct stat64 + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-# else ++#else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-# endif +- __ino64_t st_ino; /* File serial number. */ +-# endif /* __USE_TIME_BITS64 */ ++#endif ++ int __glibc_reserved[2]; + }; + #endif + +@@ -135,5 +124,4 @@ struct stat64 + /* Nanosecond resolution time values are supported. */ + #define _STATBUF_ST_NSEC + +- + #endif /* _BITS_STRUCT_STAT_H */ +diff --git a/sysdeps/unix/sysv/linux/generic/bits/struct_stat.h b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h +similarity index 91% +rename from sysdeps/unix/sysv/linux/generic/bits/struct_stat.h +rename to sysdeps/unix/sysv/linux/csky/bits/struct_stat.h +index 32ef511ae5728276..f0ee455748d3ee41 100644 +--- a/sysdeps/unix/sysv/linux/generic/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h +@@ -1,5 +1,5 @@ +-/* Definition for struct stat. +- Copyright (C) 2020-2021 Free Software Foundation, Inc. ++/* Definition for struct stat. Linux/csky version. ++ Copyright (C) 2020-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -43,6 +43,9 @@ + + struct stat + { ++#ifdef __USE_TIME_BITS64 ++# include ++#else + __dev_t st_dev; /* Device. */ + __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ + __mode_t st_mode; /* File mode. */ +@@ -55,7 +58,7 @@ struct stat + __blksize_t st_blksize; /* Optimal block size for I/O. */ + int __pad2; + __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ +-#ifdef __USE_XOPEN2K8 ++# ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -65,18 +68,19 @@ struct stat + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-# define st_atime st_atim.tv_sec /* Backward compatibility. */ +-# define st_mtime st_mtim.tv_sec +-# define st_ctime st_ctim.tv_sec +-#else ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-#endif ++# endif + int __glibc_reserved[2]; ++#endif + }; + + #undef __field64 +@@ -84,6 +88,9 @@ struct stat + #ifdef __USE_LARGEFILE64 + struct stat64 + { ++# ifdef __USE_TIME_BITS64 ++# include ++# else + __dev_t st_dev; /* Device. */ + __ino64_t st_ino; /* File serial number. */ + __mode_t st_mode; /* File mode. */ +@@ -96,7 +103,7 @@ struct stat64 + __blksize_t st_blksize; /* Optimal block size for I/O. */ + int __pad2; + __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ +-#ifdef __USE_XOPEN2K8 ++# ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -106,15 +113,16 @@ struct stat64 + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-#else ++# else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-#endif ++# endif + int __glibc_reserved[2]; ++# endif + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h +new file mode 100644 +index 0000000000000000..38b6e13e68890c29 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h +@@ -0,0 +1,139 @@ ++/* Definition for struct stat. Linux/hppa version. ++ Copyright (C) 2020-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#if !defined _SYS_STAT_H && !defined _FCNTL_H ++# error "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_STRUCT_STAT_H ++#define _BITS_STRUCT_STAT_H 1 ++ ++#include ++#include ++ ++struct stat ++ { ++#ifdef __USE_TIME_BITS64 ++# include ++#else ++ __dev_t st_dev; /* Device. */ ++ unsigned short int __pad1; ++# ifndef __USE_FILE_OFFSET64 ++ __ino_t st_ino; /* File serial number. */ ++# else ++ __ino_t __st_ino; /* 32bit file serial number. */ ++# endif ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned short int __pad2; ++# ifndef __USE_FILE_OFFSET64 ++ __off_t st_size; /* Size of file, in bytes. */ ++# else ++ __off64_t st_size; /* Size of file, in bytes. */ ++# endif ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++# ifndef __USE_FILE_OFFSET64 ++ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ ++# else ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# endif ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++# ifndef __USE_FILE_OFFSET64 ++ unsigned long int __glibc_reserved4; ++ unsigned long int __glibc_reserved5; ++# else ++ __ino64_t st_ino; /* File serial number. */ ++# endif ++#endif /* __USE_TIME_BITS64 */ ++ }; ++ ++#ifdef __USE_LARGEFILE64 ++struct stat64 ++ { ++# ifdef __USE_TIME_BITS64 ++# include ++# else ++ __dev_t st_dev; /* Device. */ ++ unsigned int __pad1; ++ ++ __ino_t __st_ino; /* 32bit file serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned int __pad2; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ __ino64_t st_ino; /* File serial number. */ ++# endif /* __USE_TIME_BITS64 */ ++ }; ++#endif ++ ++/* Tell code we have these members. */ ++#define _STATBUF_ST_BLKSIZE ++#define _STATBUF_ST_RDEV ++/* Nanosecond resolution time values are supported. */ ++#define _STATBUF_ST_NSEC ++ ++ ++#endif /* _BITS_STRUCT_STAT_H */ +diff --git a/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h +new file mode 100644 +index 0000000000000000..e00e71173e184b48 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h +@@ -0,0 +1,135 @@ ++/* Definition for struct stat. Linux/nios2 version. ++ Copyright (C) 2020-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#if !defined _SYS_STAT_H && !defined _FCNTL_H ++# error "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_STRUCT_STAT_H ++#define _BITS_STRUCT_STAT_H 1 ++ ++#include ++#include ++ ++#if defined __USE_FILE_OFFSET64 ++# define __field64(type, type64, name) type64 name ++#elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T ++# if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T ++# error "ino_t and off_t must both be the same type" ++# endif ++# define __field64(type, type64, name) type name ++#elif __BYTE_ORDER == __LITTLE_ENDIAN ++# define __field64(type, type64, name) \ ++ type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad ++#else ++# define __field64(type, type64, name) \ ++ int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name ++#endif ++ ++struct stat ++ { ++#ifdef __USE_TIME_BITS64 ++# include ++#else ++ __dev_t st_dev; /* Device. */ ++ __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ __dev_t __pad1; ++ __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ int __pad2; ++ __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ int __glibc_reserved[2]; ++#endif ++ }; ++ ++#undef __field64 ++ ++#ifdef __USE_LARGEFILE64 ++struct stat64 ++ { ++# ifdef __USE_TIME_BITS64 ++# include ++# else ++ __dev_t st_dev; /* Device. */ ++ __ino64_t st_ino; /* File serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ __dev_t __pad1; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ int __pad2; ++ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ int __glibc_reserved[2]; ++# endif ++ }; ++#endif ++ ++/* Tell code we have these members. */ ++#define _STATBUF_ST_BLKSIZE ++#define _STATBUF_ST_RDEV ++/* Nanosecond resolution time values are supported. */ ++#define _STATBUF_ST_NSEC ++ ++#endif /* _BITS_STRUCT_STAT_H */ +diff --git a/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h +new file mode 100644 +index 0000000000000000..0f7c9cdc89ebf686 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h +@@ -0,0 +1,139 @@ ++/* Definition for struct stat. Linux/sh version. ++ Copyright (C) 2020-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#if !defined _SYS_STAT_H && !defined _FCNTL_H ++# error "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_STRUCT_STAT_H ++#define _BITS_STRUCT_STAT_H 1 ++ ++#include ++#include ++ ++struct stat ++ { ++#ifdef __USE_TIME_BITS64 ++# include ++#else ++ __dev_t st_dev; /* Device. */ ++ unsigned short int __pad1; ++# ifndef __USE_FILE_OFFSET64 ++ __ino_t st_ino; /* File serial number. */ ++# else ++ __ino_t __st_ino; /* 32bit file serial number. */ ++# endif ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned short int __pad2; ++# ifndef __USE_FILE_OFFSET64 ++ __off_t st_size; /* Size of file, in bytes. */ ++# else ++ __off64_t st_size; /* Size of file, in bytes. */ ++# endif ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++# ifndef __USE_FILE_OFFSET64 ++ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ ++# else ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# endif ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++# ifndef __USE_FILE_OFFSET64 ++ unsigned long int __glibc_reserved4; ++ unsigned long int __glibc_reserved5; ++# else ++ __ino64_t st_ino; /* File serial number. */ ++# endif ++#endif /* __USE_TIME_BITS64 */ ++ }; ++ ++#ifdef __USE_LARGEFILE64 ++struct stat64 ++ { ++# ifdef __USE_TIME_BITS64 ++# include ++# else ++ __dev_t st_dev; /* Device. */ ++ unsigned int __pad1; ++ ++ __ino_t __st_ino; /* 32bit file serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned int __pad2; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ __ino64_t st_ino; /* File serial number. */ ++# endif /* __USE_TIME_BITS64 */ ++ }; ++#endif ++ ++/* Tell code we have these members. */ ++#define _STATBUF_ST_BLKSIZE ++#define _STATBUF_ST_RDEV ++/* Nanosecond resolution time values are supported. */ ++#define _STATBUF_ST_NSEC ++ ++ ++#endif /* _BITS_STRUCT_STAT_H */ diff --git a/SOURCES/glibc-upstream-2.34-351.patch b/SOURCES/glibc-upstream-2.34-351.patch new file mode 100644 index 0000000..91141b0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-351.patch @@ -0,0 +1,107 @@ +commit f42d871b22f7eb5330e77ed9bccbb447c44e7101 +Author: Sergei Trofimovich +Date: Tue Sep 13 13:39:13 2022 -0400 + + Makerules: fix MAKEFLAGS assignment for upcoming make-4.4 [BZ# 29564] + + make-4.4 will add long flags to MAKEFLAGS variable: + + * WARNING: Backward-incompatibility! + Previously only simple (one-letter) options were added to the MAKEFLAGS + variable that was visible while parsing makefiles. Now, all options + are available in MAKEFLAGS. + + This causes locale builds to fail when long options are used: + + $ make --shuffle + ... + make -C localedata install-locales + make: invalid shuffle mode: '1662724426r' + + The change fixes it by passing eash option via whitespace and dashes. + That way option is appended to both single-word form and whitespace + separated form. + + While at it fixed --silent mode detection in $(MAKEFLAGS) by filtering + out --long-options. Otherwise options like --shuffle flag enable silent + mode unintentionally. $(silent-make) variable consolidates the checks. + + Resolves: BZ# 29564 + + CC: Paul Smith + CC: Siddhesh Poyarekar + Signed-off-by: Sergei Trofimovich + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 2d7ed98add14f75041499ac189696c9bd3d757fe) + +diff --git a/Makeconfig b/Makeconfig +index 99898a632a64be91..4e04dafb76a1e1a1 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -43,6 +43,22 @@ else + $(error objdir must be defined by the build-directory Makefile) + endif + ++# Did we request 'make -s' run? "yes" or "no". ++# Starting from make-4.4 MAKEFLAGS now contains long ++# options like '--shuffle'. To detect presence of 's' ++# we pick first word with short options. Long options ++# are guaranteed to come after whitespace. We use '-' ++# prefix to always have a word before long options ++# even if no short options were passed. ++# Typical MAKEFLAGS values to watch for: ++# "rs --shuffle=42" (silent) ++# " --shuffle" (not silent) ++ifeq ($(findstring s, $(firstword -$(MAKEFLAGS))),) ++silent-make := no ++else ++silent-make := yes ++endif ++ + # Root of the sysdeps tree. + sysdep_dir := $(..)sysdeps + export sysdep_dir := $(sysdep_dir) +@@ -918,7 +934,7 @@ endif + # umpteen zillion filenames along with it (we use `...' instead) + # but we don't want this echoing done when the user has said + # he doesn't want to see commands echoed by using -s. +-ifneq "$(findstring s,$(MAKEFLAGS))" "" # if -s ++ifeq ($(silent-make),yes) # if -s + +cmdecho := echo >/dev/null + else # not -s + +cmdecho := echo +diff --git a/Makerules b/Makerules +index 7fbe85719aacc230..e5916f29fa0d4593 100644 +--- a/Makerules ++++ b/Makerules +@@ -810,7 +810,7 @@ endif + # Maximize efficiency by minimizing the number of rules. + .SUFFIXES: # Clear the suffix list. We don't use suffix rules. + # Don't define any builtin rules. +-MAKEFLAGS := $(MAKEFLAGS)r ++MAKEFLAGS := $(MAKEFLAGS) -r + + # Generic rule for making directories. + %/: +@@ -827,7 +827,7 @@ MAKEFLAGS := $(MAKEFLAGS)r + .PRECIOUS: $(foreach l,$(libtypes),$(patsubst %,$(common-objpfx)$l,c)) + + # Use the verbose option of ar and tar when not running silently. +-ifeq "$(findstring s,$(MAKEFLAGS))" "" # if not -s ++ifeq ($(silent-make),no) # if not -s + verbose := v + else # -s + verbose := +diff --git a/elf/rtld-Rules b/elf/rtld-Rules +index 10de81918c07670f..a452536d39b5c198 100644 +--- a/elf/rtld-Rules ++++ b/elf/rtld-Rules +@@ -52,7 +52,7 @@ $(objpfx)rtld-libc.a: $(foreach dir,$(rtld-subdirs),\ + mv -f $@T $@ + + # Use the verbose option of ar and tar when not running silently. +-ifeq "$(findstring s,$(MAKEFLAGS))" "" # if not -s ++ifeq ($(silent-make),no) # if not -s + verbose := v + else # -s + verbose := diff --git a/SOURCES/glibc-upstream-2.34-352.patch b/SOURCES/glibc-upstream-2.34-352.patch new file mode 100644 index 0000000..5c4006e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-352.patch @@ -0,0 +1,73 @@ +commit 675ba1f361ea424626b48a40cfd24d113dfc1b65 +Author: Paul Eggert +Date: Thu Sep 8 20:08:32 2022 -0500 + + mktime: improve heuristic for ca-1986 Indiana DST + + This patch syncs mktime.c from Gnulib, fixing a + problem reported by Mark Krenz , + and it should fix BZ#29035 too. + * time/mktime.c (__mktime_internal): Be more generous about + accepting arguments with the wrong value of tm_isdst, by falling + back to a one-hour DST difference if we find no nearby DST that is + unusual. This fixes a problem where "1986-04-28 00:00 EDT" was + rejected when TZ="America/Indianapolis" because the nearest DST + timestamp occurred in 1970, a temporal distance too great for the + old heuristic. This also also narrows the search a bit, which + is a minor performance win. + + (cherry picked from commit 83859e1115269cf56d21669361d4ddbe2687831c) + +diff --git a/time/mktime.c b/time/mktime.c +index 8e78006eea7e693b..74d9bbaa5b375723 100644 +--- a/time/mktime.c ++++ b/time/mktime.c +@@ -429,8 +429,13 @@ __mktime_internal (struct tm *tp, + time with the right value, and use its UTC offset. + + Heuristic: probe the adjacent timestamps in both directions, +- looking for the desired isdst. This should work for all real +- time zone histories in the tz database. */ ++ looking for the desired isdst. If none is found within a ++ reasonable duration bound, assume a one-hour DST difference. ++ This should work for all real time zone histories in the tz ++ database. */ ++ ++ /* +1 if we wanted standard time but got DST, -1 if the reverse. */ ++ int dst_difference = (isdst == 0) - (tm.tm_isdst == 0); + + /* Distance between probes when looking for a DST boundary. In + tzdata2003a, the shortest period of DST is 601200 seconds +@@ -441,12 +446,14 @@ __mktime_internal (struct tm *tp, + periods when probing. */ + int stride = 601200; + +- /* The longest period of DST in tzdata2003a is 536454000 seconds +- (e.g., America/Jujuy starting 1946-10-01 01:00). The longest +- period of non-DST is much longer, but it makes no real sense +- to search for more than a year of non-DST, so use the DST +- max. */ +- int duration_max = 536454000; ++ /* In TZDB 2021e, the longest period of DST (or of non-DST), in ++ which the DST (or adjacent DST) difference is not one hour, ++ is 457243209 seconds: e.g., America/Cambridge_Bay with leap ++ seconds, starting 1965-10-31 00:00 in a switch from ++ double-daylight time (-05) to standard time (-07), and ++ continuing to 1980-04-27 02:00 in a switch from standard time ++ (-07) to daylight time (-06). */ ++ int duration_max = 457243209; + + /* Search in both directions, so the maximum distance is half + the duration; add the stride to avoid off-by-1 problems. */ +@@ -483,6 +490,11 @@ __mktime_internal (struct tm *tp, + } + } + ++ /* No unusual DST offset was found nearby. Assume one-hour DST. */ ++ t += 60 * 60 * dst_difference; ++ if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm)) ++ goto offset_found; ++ + __set_errno (EOVERFLOW); + return -1; + } diff --git a/SOURCES/glibc-upstream-2.34-353.patch b/SOURCES/glibc-upstream-2.34-353.patch new file mode 100644 index 0000000..2bf6250 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-353.patch @@ -0,0 +1,86 @@ +commit 6e8044e910600f71f4802dba2d105007af8428c3 +Author: Joseph Myers +Date: Mon Nov 8 19:11:51 2021 +0000 + + Fix memmove call in vfprintf-internal.c:group_number + + A recent GCC mainline change introduces errors of the form: + + vfprintf-internal.c: In function 'group_number': + vfprintf-internal.c:2093:15: error: 'memmove' specified bound between 9223372036854775808 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Werror=stringop-overflow=] + 2093 | memmove (w, s, (front_ptr -s) * sizeof (CHAR_T)); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This is a genuine bug in the glibc code: s > front_ptr is always true + at this point in the code, and the intent is clearly for the + subtraction to be the other way round. The other arguments to the + memmove call here also appear to be wrong; w and s point just *after* + the destination and source for copying the rest of the number, so the + size needs to be subtracted to get appropriate pointers for the + copying. Adjust the memmove call to conform to the apparent intent of + the code, so fixing the -Wstringop-overflow error. + + Now, if the original code were ever executed, a buffer overrun would + result. However, I believe this code (introduced in commit + edc1686af0c0fc2eb535f1d38cdf63c1a5a03675, "vfprintf: Reuse work_buffer + in group_number", so in glibc 2.26) is unreachable in prior glibc + releases (so there is no need for a bug in Bugzilla, no need to + consider any backports unless someone wants to build older glibc + releases with GCC 12 and no possibility of this buffer overrun + resulting in a security issue). + + work_buffer is 1000 bytes / 250 wide characters. This case is only + reachable if an initial part of the number, plus a grouped copy of the + rest of the number, fail to fit in that space; that is, if the grouped + number fails to fit in the space. In the wide character case, + grouping is always one wide character, so even with a locale (of which + there aren't any in glibc) grouping every digit, a number would need + to occupy at least 125 wide characters to overflow, and a 64-bit + integer occupies at most 23 characters in octal including a leading 0. + In the narrow character case, the multibyte encoding of the grouping + separator would need to be at least 42 bytes to overflow, again + supposing grouping every digit, but MB_LEN_MAX is 16. So even if we + admit the case of artificially constructed locales not shipped with + glibc, given that such a locale would need to use one of the character + sets supported by glibc, this code cannot be reached at present. (And + POSIX only actually specifies the ' flag for grouping for decimal + output, though glibc acts on it for other bases as well.) + + With binary output (if you consider use of grouping there to be + valid), you'd need a 15-byte multibyte character for overflow; I don't + know if any supported character set has such a character (if, again, + we admit constructed locales using grouping every digit and a grouping + separator chosen to have a multibyte encoding as long as possible, as + well as accepting use of grouping with binary), but given that we have + this code at all (clearly it's not *correct*, or in accordance with + the principle of avoiding arbitrary limits, to skip grouping on + running out of internal space like that), I don't think it should need + any further changes for binary printf support to go in. + + On the other hand, support for large sizes of _BitInt in printf (see + the N2858 proposal) *would* require something to be done about such + arbitrary limits (presumably using dynamic allocation in printf again, + for sufficiently large _BitInt arguments only - currently only + floating-point uses dynamic allocation, and, as previously discussed, + that could actually be replaced by bounded allocation given smarter + code). + + Tested with build-many-glibcs.py for aarch64-linux-gnu (GCC mainline). + Also tested natively for x86_64. + + (cherry picked from commit db6c4935fae6005d46af413b32aa92f4f6059dce) + +diff --git a/stdio-common/vfprintf-internal.c b/stdio-common/vfprintf-internal.c +index 3f3d1e148a8e7fda..53d93b2f07ecb261 100644 +--- a/stdio-common/vfprintf-internal.c ++++ b/stdio-common/vfprintf-internal.c +@@ -2154,7 +2154,8 @@ group_number (CHAR_T *front_ptr, CHAR_T *w, CHAR_T *rear_ptr, + copy_rest: + /* No further grouping to be done. Copy the rest of the + number. */ +- memmove (w, s, (front_ptr -s) * sizeof (CHAR_T)); ++ w -= s - front_ptr; ++ memmove (w, front_ptr, (s - front_ptr) * sizeof (CHAR_T)); + break; + } + else if (*grouping != '\0') diff --git a/SOURCES/glibc-upstream-2.34-354.patch b/SOURCES/glibc-upstream-2.34-354.patch new file mode 100644 index 0000000..0ac8827 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-354.patch @@ -0,0 +1,35 @@ +commit 291d4402067760edb7c0f339f9e451787a25e20a +Author: Joseph Myers +Date: Fri Aug 27 17:47:46 2021 +0000 + + Allow #pragma GCC in headers in conformtest + + No "#pragma GCC" pragma allows macro-expansion of its arguments, so no + namespace issues arise from use of such pragmas in installed headers. + Ignore them in conformtest tests of header namespace. + + Tested for x86_64, in conjunction with Paul's patch + + adding use of such pragmas to installed headers shared with gnulib. + + (cherry picked from commit 6090a4a1b32fd7859d0ad5b7e9b240bd5fa04b3f) + +diff --git a/conform/conformtest.py b/conform/conformtest.py +index 4898e16c9fb96503..164cf2917d464aa1 100644 +--- a/conform/conformtest.py ++++ b/conform/conformtest.py +@@ -631,6 +631,14 @@ class HeaderTests(object): + continue + if re.match(r'# [1-9]', line): + continue ++ if line.startswith('#pragma GCC '): ++ # No GCC pragma uses macro expansion, so no ++ # namespace issues arise from such pragmas. (Some ++ # pragmas not in the GCC namespace do macro-expand ++ # their arguments and so could be affected by ++ # macros defined by user code including the ++ # header.) ++ continue + match = re.match(r'#define (.*)', line) + if match: + self.check_token(bad_tokens, match.group(1)) diff --git a/SOURCES/glibc-upstream-2.34-355.patch b/SOURCES/glibc-upstream-2.34-355.patch new file mode 100644 index 0000000..4ba03a0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-355.patch @@ -0,0 +1,629 @@ +commit 86a701a20479dfbc23540b3143fd5b28660a2447 +Author: Paul Eggert +Date: Tue Sep 21 07:47:45 2021 -0700 + + regex: copy back from Gnulib + + Copy regex-related files back from Gnulib, to fix a problem with + static checking of regex calls noted by Martin Sebor. This merges the + following changes: + + * New macro __attribute_nonnull__ in misc/sys/cdefs.h, for use later + when copying other files back from Gnulib. + + * Use __GNULIB_CDEFS instead of __GLIBC__ when deciding + whether to include bits/wordsize.h etc. + + * Avoid duplicate entries in epsilon closure table. + + * New regex.h macro _REGEX_NELTS to let regexec say that its pmatch + arg should contain nmatch elts. Use that for regexec, instead of + __attr_access (which is incorrect). + + * New regex.h macro _Attr_access_ which is like __attr_access except + portable to non-glibc platforms. + + * Add some DEBUG_ASSERTs to pacify gcc -fanalyzer and to catch + recently-fixed performance bugs if they recur. + + * Add Gnulib-specific stuff to port the dynarray- and lock-using parts + of regex code to non-glibc platforms. + + * Fix glibc bug 11053. + + * Avoid some undefined behavior when popping an empty fail stack. + + (cherry picked from commit 0b5ca7c3e551e5502f3be3b06453324fe8604e82) + +diff --git a/include/intprops.h b/include/intprops.h +index 967e32ea0cbedd56..9d10028a5966c1c6 100644 +--- a/include/intprops.h ++++ b/include/intprops.h +@@ -133,7 +133,8 @@ + operators might not yield numerically correct answers due to + arithmetic overflow. They do not rely on undefined or + implementation-defined behavior. Their implementations are simple +- and straightforward, but they are a bit harder to use than the ++ and straightforward, but they are harder to use and may be less ++ efficient than the INT__WRAPV, INT__OK, and + INT__OVERFLOW macros described below. + + Example usage: +@@ -158,6 +159,9 @@ + must have minimum value MIN and maximum MAX. Unsigned types should + use a zero MIN of the proper type. + ++ Because all arguments are subject to integer promotions, these ++ macros typically do not work on types narrower than 'int'. ++ + These macros are tuned for constant MIN and MAX. For commutative + operations such as A + B, they are also tuned for constant B. */ + +@@ -339,9 +343,15 @@ + arguments should not have side effects. + + The WRAPV macros are not constant expressions. They support only +- +, binary -, and *. Because the WRAPV macros convert the result, +- they report overflow in different circumstances than the OVERFLOW +- macros do. ++ +, binary -, and *. ++ ++ Because the WRAPV macros convert the result, they report overflow ++ in different circumstances than the OVERFLOW macros do. For ++ example, in the typical case with 16-bit 'short' and 32-bit 'int', ++ if A, B and R are all of type 'short' then INT_ADD_OVERFLOW (A, B) ++ returns false because the addition cannot overflow after A and B ++ are converted to 'int', whereas INT_ADD_WRAPV (A, B, &R) returns ++ true or false depending on whether the sum fits into 'short'. + + These macros are tuned for their last input argument being a constant. + +diff --git a/include/regex.h b/include/regex.h +index 24eca2c297bb6043..34fb67d85536bcb9 100644 +--- a/include/regex.h ++++ b/include/regex.h +@@ -37,7 +37,8 @@ extern int __regcomp (regex_t *__preg, const char *__pattern, int __cflags); + libc_hidden_proto (__regcomp) + + extern int __regexec (const regex_t *__preg, const char *__string, +- size_t __nmatch, regmatch_t __pmatch[], int __eflags); ++ size_t __nmatch, regmatch_t __pmatch[__nmatch], ++ int __eflags); + libc_hidden_proto (__regexec) + + extern size_t __regerror (int __errcode, const regex_t *__preg, +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index e0ecd9147ee3ce48..b166f3d209fe361f 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -366,16 +366,18 @@ + #endif + + /* The nonnull function attribute marks pointer parameters that +- must not be NULL. */ +-#ifndef __nonnull ++ must not be NULL. This has the name __nonnull in glibc, ++ and __attribute_nonnull__ in files shared with Gnulib to avoid ++ collision with a different __nonnull in DragonFlyBSD 5.9. */ ++#ifndef __attribute_nonnull__ + # if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__) +-# define __nonnull(params) __attribute__ ((__nonnull__ params)) ++# define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params)) + # else +-# define __nonnull(params) ++# define __attribute_nonnull__(params) + # endif +-#elif !defined __GLIBC__ +-# undef __nonnull +-# define __nonnull(params) _GL_ATTRIBUTE_NONNULL (params) ++#endif ++#ifndef __nonnull ++# define __nonnull(params) __attribute_nonnull__ (params) + #endif + + /* The returns_nonnull function attribute marks the return type of the function +@@ -541,9 +543,9 @@ + [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })] + #endif + +-/* The #ifndef lets Gnulib avoid including these on non-glibc +- platforms, where the includes typically do not exist. */ +-#ifdef __GLIBC__ ++/* Gnulib avoids including these, as they don't work on non-glibc or ++ older glibc platforms. */ ++#ifndef __GNULIB_CDEFS + # include + # include + #endif +diff --git a/posix/regcomp.c b/posix/regcomp.c +index d93698ae78447b46..887e5b50684e22f5 100644 +--- a/posix/regcomp.c ++++ b/posix/regcomp.c +@@ -1695,12 +1695,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) + reg_errcode_t err; + Idx i; + re_node_set eclosure; +- bool ok; + bool incomplete = false; + err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + ++ /* An epsilon closure includes itself. */ ++ eclosure.elems[eclosure.nelem++] = node; ++ + /* This indicates that we are calculating this node now. + We reference this value to avoid infinite loop. */ + dfa->eclosures[node].nelem = -1; +@@ -1753,10 +1755,6 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) + } + } + +- /* An epsilon closure includes itself. */ +- ok = re_node_set_insert (&eclosure, node); +- if (__glibc_unlikely (! ok)) +- return REG_ESPACE; + if (incomplete && !root) + dfa->eclosures[node].nelem = 0; + else +diff --git a/posix/regex.c b/posix/regex.c +index 7296be0f08da88d8..d32863972c7bcdcf 100644 +--- a/posix/regex.c ++++ b/posix/regex.c +@@ -24,6 +24,7 @@ + + # if __GNUC_PREREQ (4, 6) + # pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" ++# pragma GCC diagnostic ignored "-Wvla" + # endif + # if __GNUC_PREREQ (4, 3) + # pragma GCC diagnostic ignored "-Wold-style-definition" +diff --git a/posix/regex.h b/posix/regex.h +index 14fb1d8364a11d29..adb69768ee520554 100644 +--- a/posix/regex.h ++++ b/posix/regex.h +@@ -522,6 +522,30 @@ typedef struct + + /* Declarations for routines. */ + ++#ifndef _REGEX_NELTS ++# if (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \ ++ && !defined __STDC_NO_VLA__) ++# define _REGEX_NELTS(n) n ++# else ++# define _REGEX_NELTS(n) ++# endif ++#endif ++ ++#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) ++# pragma GCC diagnostic push ++# pragma GCC diagnostic ignored "-Wvla" ++#endif ++ ++#ifndef _Attr_access_ ++# ifdef __attr_access ++# define _Attr_access_(arg) __attr_access (arg) ++# elif defined __GNUC__ && 10 <= __GNUC__ ++# define _Attr_access_(x) __attribute__ ((__access__ x)) ++# else ++# define _Attr_access_(x) ++# endif ++#endif ++ + #ifdef __USE_GNU + /* Sets the current default syntax to SYNTAX, and return the old syntax. + You can also simply assign to the 're_syntax_options' variable. */ +@@ -537,7 +561,7 @@ extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax); + 'regfree'. */ + extern const char *re_compile_pattern (const char *__pattern, size_t __length, + struct re_pattern_buffer *__buffer) +- __attr_access ((__read_only__, 1, 2)); ++ _Attr_access_ ((__read_only__, 1, 2)); + + + /* Compile a fastmap for the compiled pattern in BUFFER; used to +@@ -555,7 +579,7 @@ extern regoff_t re_search (struct re_pattern_buffer *__buffer, + const char *__String, regoff_t __length, + regoff_t __start, regoff_t __range, + struct re_registers *__regs) +- __attr_access ((__read_only__, 2, 3)); ++ _Attr_access_ ((__read_only__, 2, 3)); + + + /* Like 're_search', but search in the concatenation of STRING1 and +@@ -566,8 +590,8 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, + regoff_t __start, regoff_t __range, + struct re_registers *__regs, + regoff_t __stop) +- __attr_access ((__read_only__, 2, 3)) +- __attr_access ((__read_only__, 4, 5)); ++ _Attr_access_ ((__read_only__, 2, 3)) ++ _Attr_access_ ((__read_only__, 4, 5)); + + + /* Like 're_search', but return how many characters in STRING the regexp +@@ -575,7 +599,7 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, + extern regoff_t re_match (struct re_pattern_buffer *__buffer, + const char *__String, regoff_t __length, + regoff_t __start, struct re_registers *__regs) +- __attr_access ((__read_only__, 2, 3)); ++ _Attr_access_ ((__read_only__, 2, 3)); + + + /* Relates to 're_match' as 're_search_2' relates to 're_search'. */ +@@ -584,8 +608,8 @@ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, + const char *__string2, regoff_t __length2, + regoff_t __start, struct re_registers *__regs, + regoff_t __stop) +- __attr_access ((__read_only__, 2, 3)) +- __attr_access ((__read_only__, 4, 5)); ++ _Attr_access_ ((__read_only__, 2, 3)) ++ _Attr_access_ ((__read_only__, 4, 5)); + + + /* Set REGS to hold NUM_REGS registers, storing them in STARTS and +@@ -654,16 +678,19 @@ extern int regcomp (regex_t *_Restrict_ __preg, + + extern int regexec (const regex_t *_Restrict_ __preg, + const char *_Restrict_ __String, size_t __nmatch, +- regmatch_t __pmatch[_Restrict_arr_], +- int __eflags) +- __attr_access ((__write_only__, 4, 3)); ++ regmatch_t __pmatch[_Restrict_arr_ ++ _REGEX_NELTS (__nmatch)], ++ int __eflags); + + extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, + char *_Restrict_ __errbuf, size_t __errbuf_size) +- __attr_access ((__write_only__, 3, 4)); ++ _Attr_access_ ((__write_only__, 3, 4)); + + extern void regfree (regex_t *__preg); + ++#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) ++# pragma GCC diagnostic pop ++#endif + + #ifdef __cplusplus + } +diff --git a/posix/regex_internal.c b/posix/regex_internal.c +index 9dd387ef85d64e62..aefcfa2f52e68c6a 100644 +--- a/posix/regex_internal.c ++++ b/posix/regex_internal.c +@@ -1211,6 +1211,10 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) + + if (__glibc_unlikely (dest->nelem == 0)) + { ++ /* Although we already guaranteed above that dest->alloc != 0 and ++ therefore dest->elems != NULL, add a debug assertion to pacify ++ GCC 11.2.1's -fanalyzer. */ ++ DEBUG_ASSERT (dest->elems); + dest->nelem = src->nelem; + memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); + return REG_NOERROR; +@@ -1286,7 +1290,10 @@ re_node_set_insert (re_node_set *set, Idx elem) + + if (__glibc_unlikely (set->nelem) == 0) + { +- /* We already guaranteed above that set->alloc != 0. */ ++ /* Although we already guaranteed above that set->alloc != 0 and ++ therefore set->elems != NULL, add a debug assertion to pacify ++ GCC 11.2 -fanalyzer. */ ++ DEBUG_ASSERT (set->elems); + set->elems[0] = elem; + ++set->nelem; + return true; +@@ -1314,6 +1321,7 @@ re_node_set_insert (re_node_set *set, Idx elem) + { + for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) + set->elems[idx] = set->elems[idx - 1]; ++ DEBUG_ASSERT (set->elems[idx - 1] < elem); + } + + /* Insert the new element. */ +diff --git a/posix/regex_internal.h b/posix/regex_internal.h +index edcdc07e999694ac..1245e782ffc69086 100644 +--- a/posix/regex_internal.h ++++ b/posix/regex_internal.h +@@ -32,6 +32,10 @@ + #include + #include + ++#ifndef _LIBC ++# include ++#endif ++ + #include + #include + +@@ -49,14 +53,14 @@ + # define lock_fini(lock) ((void) 0) + # define lock_lock(lock) __libc_lock_lock (lock) + # define lock_unlock(lock) __libc_lock_unlock (lock) +-#elif defined GNULIB_LOCK && !defined USE_UNLOCKED_IO ++#elif defined GNULIB_LOCK && !defined GNULIB_REGEX_SINGLE_THREAD + # include "glthread/lock.h" + # define lock_define(name) gl_lock_define (, name) + # define lock_init(lock) glthread_lock_init (&(lock)) + # define lock_fini(lock) glthread_lock_destroy (&(lock)) + # define lock_lock(lock) glthread_lock_lock (&(lock)) + # define lock_unlock(lock) glthread_lock_unlock (&(lock)) +-#elif defined GNULIB_PTHREAD && !defined USE_UNLOCKED_IO ++#elif defined GNULIB_PTHREAD && !defined GNULIB_REGEX_SINGLE_THREAD + # include + # define lock_define(name) pthread_mutex_t name; + # define lock_init(lock) pthread_mutex_init (&(lock), 0) +diff --git a/posix/regexec.c b/posix/regexec.c +index f7b4f9cfc3f030df..83e9aaf8cad956a2 100644 +--- a/posix/regexec.c ++++ b/posix/regexec.c +@@ -59,7 +59,7 @@ static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, + Idx cur_idx, Idx nmatch); + static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs, + Idx str_idx, Idx dest_node, Idx nregs, +- regmatch_t *regs, ++ regmatch_t *regs, regmatch_t *prevregs, + re_node_set *eps_via_nodes); + static reg_errcode_t set_regs (const regex_t *preg, + const re_match_context_t *mctx, +@@ -186,11 +186,12 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len); + REG_NOTBOL is set, then ^ does not match at the beginning of the + string; if REG_NOTEOL is set, then $ does not match at the end. + +- We return 0 if we find a match and REG_NOMATCH if not. */ ++ Return 0 if a match is found, REG_NOMATCH if not, REG_BADPAT if ++ EFLAGS is invalid. */ + + int + regexec (const regex_t *__restrict preg, const char *__restrict string, +- size_t nmatch, regmatch_t pmatch[], int eflags) ++ size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) + { + reg_errcode_t err; + Idx start, length; +@@ -234,7 +235,7 @@ int + attribute_compat_text_section + __compat_regexec (const regex_t *__restrict preg, + const char *__restrict string, size_t nmatch, +- regmatch_t pmatch[], int eflags) ++ regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) + { + return regexec (preg, string, nmatch, pmatch, + eflags & (REG_NOTBOL | REG_NOTEOL)); +@@ -269,8 +270,8 @@ compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); + strings.) + + On success, re_match* functions return the length of the match, re_search* +- return the position of the start of the match. Return value -1 means no +- match was found and -2 indicates an internal error. */ ++ return the position of the start of the match. They return -1 on ++ match failure, -2 on error. */ + + regoff_t + re_match (struct re_pattern_buffer *bufp, const char *string, Idx length, +@@ -1206,27 +1207,30 @@ check_halt_state_context (const re_match_context_t *mctx, + /* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA + corresponding to the DFA). + Return the destination node, and update EPS_VIA_NODES; +- return -1 in case of errors. */ ++ return -1 on match failure, -2 on error. */ + + static Idx + proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, ++ regmatch_t *prevregs, + Idx *pidx, Idx node, re_node_set *eps_via_nodes, + struct re_fail_stack_t *fs) + { + const re_dfa_t *const dfa = mctx->dfa; +- Idx i; +- bool ok; + if (IS_EPSILON_NODE (dfa->nodes[node].type)) + { + re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes; + re_node_set *edests = &dfa->edests[node]; +- Idx dest_node; +- ok = re_node_set_insert (eps_via_nodes, node); +- if (__glibc_unlikely (! ok)) +- return -2; +- /* Pick up a valid destination, or return -1 if none +- is found. */ +- for (dest_node = -1, i = 0; i < edests->nelem; ++i) ++ ++ if (! re_node_set_contains (eps_via_nodes, node)) ++ { ++ bool ok = re_node_set_insert (eps_via_nodes, node); ++ if (__glibc_unlikely (! ok)) ++ return -2; ++ } ++ ++ /* Pick a valid destination, or return -1 if none is found. */ ++ Idx dest_node = -1; ++ for (Idx i = 0; i < edests->nelem; i++) + { + Idx candidate = edests->elems[i]; + if (!re_node_set_contains (cur_nodes, candidate)) +@@ -1244,7 +1248,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + /* Otherwise, push the second epsilon-transition on the fail stack. */ + else if (fs != NULL + && push_fail_stack (fs, *pidx, candidate, nregs, regs, +- eps_via_nodes)) ++ prevregs, eps_via_nodes)) + return -2; + + /* We know we are going to exit. */ +@@ -1288,7 +1292,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + if (naccepted == 0) + { + Idx dest_node; +- ok = re_node_set_insert (eps_via_nodes, node); ++ bool ok = re_node_set_insert (eps_via_nodes, node); + if (__glibc_unlikely (! ok)) + return -2; + dest_node = dfa->edests[node].elems[0]; +@@ -1317,7 +1321,8 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + static reg_errcode_t + __attribute_warn_unused_result__ + push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, +- Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes) ++ Idx nregs, regmatch_t *regs, regmatch_t *prevregs, ++ re_node_set *eps_via_nodes) + { + reg_errcode_t err; + Idx num = fs->num++; +@@ -1333,25 +1338,30 @@ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, + } + fs->stack[num].idx = str_idx; + fs->stack[num].node = dest_node; +- fs->stack[num].regs = re_malloc (regmatch_t, nregs); ++ fs->stack[num].regs = re_malloc (regmatch_t, 2 * nregs); + if (fs->stack[num].regs == NULL) + return REG_ESPACE; + memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs); ++ memcpy (fs->stack[num].regs + nregs, prevregs, sizeof (regmatch_t) * nregs); + err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes); + return err; + } + + static Idx + pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, +- regmatch_t *regs, re_node_set *eps_via_nodes) ++ regmatch_t *regs, regmatch_t *prevregs, ++ re_node_set *eps_via_nodes) + { ++ if (fs == NULL || fs->num == 0) ++ return -1; + Idx num = --fs->num; +- DEBUG_ASSERT (num >= 0); + *pidx = fs->stack[num].idx; + memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs); ++ memcpy (prevregs, fs->stack[num].regs + nregs, sizeof (regmatch_t) * nregs); + re_node_set_free (eps_via_nodes); + re_free (fs->stack[num].regs); + *eps_via_nodes = fs->stack[num].eps_via_nodes; ++ DEBUG_ASSERT (0 <= fs->stack[num].node); + return fs->stack[num].node; + } + +@@ -1407,33 +1417,32 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, + { + update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch); + +- if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node) ++ if ((idx == pmatch[0].rm_eo && cur_node == mctx->last_node) ++ || (fs && re_node_set_contains (&eps_via_nodes, cur_node))) + { + Idx reg_idx; ++ cur_node = -1; + if (fs) + { + for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) + if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1) +- break; +- if (reg_idx == nmatch) +- { +- re_node_set_free (&eps_via_nodes); +- regmatch_list_free (&prev_match); +- return free_fail_stack_return (fs); +- } +- cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, +- &eps_via_nodes); ++ { ++ cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, ++ prev_idx_match, &eps_via_nodes); ++ break; ++ } + } +- else ++ if (cur_node < 0) + { + re_node_set_free (&eps_via_nodes); + regmatch_list_free (&prev_match); +- return REG_NOERROR; ++ return free_fail_stack_return (fs); + } + } + + /* Proceed to next node. */ +- cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node, ++ cur_node = proceed_next_node (mctx, nmatch, pmatch, prev_idx_match, ++ &idx, cur_node, + &eps_via_nodes, fs); + + if (__glibc_unlikely (cur_node < 0)) +@@ -1445,13 +1454,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, + free_fail_stack_return (fs); + return REG_ESPACE; + } +- if (fs) +- cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, +- &eps_via_nodes); +- else ++ cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, ++ prev_idx_match, &eps_via_nodes); ++ if (cur_node < 0) + { + re_node_set_free (&eps_via_nodes); + regmatch_list_free (&prev_match); ++ free_fail_stack_return (fs); + return REG_NOMATCH; + } + } +@@ -1495,10 +1504,10 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, + } + else if (type == OP_CLOSE_SUBEXP) + { ++ /* We are at the last node of this sub expression. */ + Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; + if (reg_num < nmatch) + { +- /* We are at the last node of this sub expression. */ + if (pmatch[reg_num].rm_so < cur_idx) + { + pmatch[reg_num].rm_eo = cur_idx; +@@ -2195,6 +2204,7 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, + + /* Return the next state to which the current state STATE will transit by + accepting the current input byte, and update STATE_LOG if necessary. ++ Return NULL on failure. + If STATE can accept a multibyte char/collating element/back reference + update the destination of STATE_LOG. */ + +@@ -2395,7 +2405,7 @@ check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, + + #if 0 + /* Return the next state to which the current state STATE will transit by +- accepting the current input byte. */ ++ accepting the current input byte. Return NULL on failure. */ + + static re_dfastate_t * + transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, +@@ -2817,7 +2827,8 @@ find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, + /* Check whether the node TOP_NODE at TOP_STR can arrive to the node + LAST_NODE at LAST_STR. We record the path onto PATH since it will be + heavily reused. +- Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */ ++ Return REG_NOERROR if it can arrive, REG_NOMATCH if it cannot, ++ REG_ESPACE if memory is exhausted. */ + + static reg_errcode_t + __attribute_warn_unused_result__ +@@ -3433,7 +3444,8 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) + /* Group all nodes belonging to STATE into several destinations. + Then for all destinations, set the nodes belonging to the destination + to DESTS_NODE[i] and set the characters accepted by the destination +- to DEST_CH[i]. This function return the number of destinations. */ ++ to DEST_CH[i]. Return the number of destinations if successful, ++ -1 on internal error. */ + + static Idx + group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, +@@ -4211,7 +4223,8 @@ match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) + } + + /* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches +- at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */ ++ at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. ++ Return the new entry if successful, NULL if memory is exhausted. */ + + static re_sub_match_last_t * + match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx) diff --git a/SOURCES/glibc-upstream-2.34-356.patch b/SOURCES/glibc-upstream-2.34-356.patch new file mode 100644 index 0000000..fcaa4ad --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-356.patch @@ -0,0 +1,30 @@ +commit fa5044f1e38f4f6515253449b6ca77fd14f53b8e +Author: Paul Eggert +Date: Wed Nov 24 14:16:09 2021 -0800 + + regex: fix buffer read overrun in search [BZ#28470] + + Problem reported by Benno Schulenberg in: + https://lists.gnu.org/r/bug-gnulib/2021-10/msg00035.html + * posix/regexec.c (re_search_internal): Use better bounds check. + + (cherry picked from commit c52ef24829f95a819965214eeae28e3289a91a61) + +diff --git a/posix/regexec.c b/posix/regexec.c +index 83e9aaf8cad956a2..6aeba3c0b4da23cc 100644 +--- a/posix/regexec.c ++++ b/posix/regexec.c +@@ -758,10 +758,9 @@ re_search_internal (const regex_t *preg, const char *string, Idx length, + + offset = match_first - mctx.input.raw_mbs_idx; + } +- /* If MATCH_FIRST is out of the buffer, leave it as '\0'. +- Note that MATCH_FIRST must not be smaller than 0. */ +- ch = (match_first >= length +- ? 0 : re_string_byte_at (&mctx.input, offset)); ++ /* Use buffer byte if OFFSET is in buffer, otherwise '\0'. */ ++ ch = (offset < mctx.input.valid_len ++ ? re_string_byte_at (&mctx.input, offset) : 0); + if (fastmap[ch]) + break; + match_first += incr; diff --git a/SOURCES/glibc-upstream-2.34-357.patch b/SOURCES/glibc-upstream-2.34-357.patch new file mode 100644 index 0000000..732e8af --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-357.patch @@ -0,0 +1,203 @@ +commit 06afa5e09fbd984ed45ae6fc6ca050d544aba780 +Author: Adhemerval Zanella +Date: Wed Aug 25 11:17:06 2021 -0300 + + io: Fix ftw internal realloc buffer (BZ #28126) + + The 106ff08526d3ca did not take in consideration the buffer might be + reallocated if the total path is larger than PATH_MAX. The realloc + uses 'dirbuf', where 'dirstreams' is the allocated buffer. + + Checked on x86_64-linux-gnu. + + Reviewed-by: H.J. Lu + (cherry picked from commit 1836bb2ebf62bd9a3588f2ed2d851c8ae810097a) + +diff --git a/io/Makefile b/io/Makefile +index 01968b81042e01e4..5284a1282dd07e3d 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -79,6 +79,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ + tst-futimens \ + tst-utimensat \ + tst-closefrom \ ++ tst-ftw-bz28126 + + tests-time64 := \ + tst-fcntl-time64 \ +diff --git a/io/ftw.c b/io/ftw.c +index ce1c6a14a306152a..cf08d9f101657df0 100644 +--- a/io/ftw.c ++++ b/io/ftw.c +@@ -204,6 +204,20 @@ struct ftw_data + void *known_objects; + }; + ++static bool ++ftw_allocate (struct ftw_data *data, size_t newsize) ++{ ++ void *newp = realloc (data->dirstreams, data->maxdir ++ * sizeof (struct dir_data *) ++ + newsize); ++ if (newp == NULL) ++ return false; ++ data->dirstreams = newp; ++ data->dirbufsize = newsize; ++ data->dirbuf = (char *) data->dirstreams ++ + data->maxdir * sizeof (struct dir_data *); ++ return true; ++} + + /* Internally we use the FTW_* constants used for `nftw'. When invoked + as `ftw', map each flag to the subset of values used by `ftw'. */ +@@ -389,17 +403,9 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name, + return 0; + + new_buflen = data->ftw.base + namlen + 2; +- if (data->dirbufsize < new_buflen) +- { +- /* Enlarge the buffer. */ +- char *newp; +- +- data->dirbufsize = 2 * new_buflen; +- newp = (char *) realloc (data->dirbuf, data->dirbufsize); +- if (newp == NULL) +- return -1; +- data->dirbuf = newp; +- } ++ if (data->dirbufsize < new_buflen ++ && !ftw_allocate (data, 2 * new_buflen)) ++ return -1; + + *((char *) __mempcpy (data->dirbuf + data->ftw.base, name, namlen)) = '\0'; + +@@ -629,7 +635,7 @@ __attribute ((noinline)) + ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, + int flags) + { +- struct ftw_data data; ++ struct ftw_data data = { .dirstreams = NULL }; + struct STRUCT_STAT st; + int result = 0; + int save_err; +@@ -647,16 +653,9 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, + data.maxdir = descriptors < 1 ? 1 : descriptors; + data.actdir = 0; + /* PATH_MAX is always defined when we get here. */ +- data.dirbufsize = MAX (2 * strlen (dir), PATH_MAX); +- data.dirstreams = malloc (data.maxdir * sizeof (struct dir_data *) +- + data.dirbufsize); +- if (data.dirstreams == NULL) ++ if (!ftw_allocate (&data, MAX (2 * strlen (dir), PATH_MAX))) + return -1; +- + memset (data.dirstreams, '\0', data.maxdir * sizeof (struct dir_data *)); +- +- data.dirbuf = (char *) data.dirstreams +- + data.maxdir * sizeof (struct dir_data *); + cp = __stpcpy (data.dirbuf, dir); + /* Strip trailing slashes. */ + while (cp > data.dirbuf + 1 && cp[-1] == '/') +diff --git a/io/tst-ftw-bz28126.c b/io/tst-ftw-bz28126.c +new file mode 100644 +index 0000000000000000..94044ab9d1d0275b +--- /dev/null ++++ b/io/tst-ftw-bz28126.c +@@ -0,0 +1,97 @@ ++/* Check if internal buffer reallocation work for large paths (BZ #28126) ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++my_func (const char *file, const struct stat *sb, int flag) ++{ ++ return 0; ++} ++ ++static const char folder[NAME_MAX] = { [0 ... 253] = 'a', [254] = '\0' }; ++ ++#define NSUBFOLDERS 16 ++static int nsubfolders; ++ ++static void ++do_cleanup (void) ++{ ++ xchdir (".."); ++ for (int i = 0; i < nsubfolders; i++) ++ { ++ remove (folder); ++ xchdir (".."); ++ } ++ remove (folder); ++} ++#define CLEANUP_HANDLER do_cleanup ++ ++static void ++check_mkdir (const char *path) ++{ ++ int r = mkdir (path, 0777); ++ /* Some filesystem such as overlayfs does not support larger path required ++ to trigger the internal buffer reallocation. */ ++ if (r != 0) ++ { ++ if (errno == ENAMETOOLONG) ++ FAIL_UNSUPPORTED ("the filesystem does not support the required" ++ "large path"); ++ else ++ FAIL_EXIT1 ("mkdir (\"%s\", 0%o): %m", folder, 0777); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ char *tempdir = support_create_temp_directory ("tst-bz28126"); ++ ++ /* Create path with various subfolders to force an internal buffer ++ reallocation within ntfw. */ ++ char *path = xasprintf ("%s/%s", tempdir, folder); ++ check_mkdir (path); ++ xchdir (path); ++ free (path); ++ for (int i = 0; i < NSUBFOLDERS - 1; i++) ++ { ++ check_mkdir (folder); ++ xchdir (folder); ++ nsubfolders++; ++ } ++ ++ TEST_COMPARE (ftw (tempdir, my_func, 20), 0); ++ ++ free (tempdir); ++ ++ do_cleanup (); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-358.patch b/SOURCES/glibc-upstream-2.34-358.patch new file mode 100644 index 0000000..fb4f91e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-358.patch @@ -0,0 +1,25 @@ +commit deea6ab1bcb2696be514e579f3263c234ecc1683 +Author: Martin Sebor +Date: Tue Jan 25 17:39:02 2022 -0700 + + io: Fix use-after-free in ftw [BZ #26779] + + Reviewed-by: Carlos O'Donell + (cherry picked from commit ee52ab25ba875f458981fce22c54e3c04c7a17d3) + +diff --git a/io/ftw.c b/io/ftw.c +index cf08d9f101657df0..91a4e8e6de151ca1 100644 +--- a/io/ftw.c ++++ b/io/ftw.c +@@ -324,8 +324,9 @@ open_dir_stream (int *dfdp, struct ftw_data *data, struct dir_data *dirp) + buf[actsize++] = '\0'; + + /* Shrink the buffer to what we actually need. */ +- data->dirstreams[data->actdir]->content = realloc (buf, actsize); +- if (data->dirstreams[data->actdir]->content == NULL) ++ void *content = realloc (buf, actsize); ++ data->dirstreams[data->actdir]->content = content; ++ if (content == NULL) + { + int save_err = errno; + free (buf); diff --git a/SOURCES/glibc-upstream-2.34-359.patch b/SOURCES/glibc-upstream-2.34-359.patch new file mode 100644 index 0000000..25fdf9f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-359.patch @@ -0,0 +1,221 @@ +commit d57cdc1b5a52b5468b9259c0b9a215e22a1fa1f6 +Author: Florian Weimer +Date: Tue Nov 8 14:15:02 2022 +0100 + + Linux: Support __IPC_64 in sysvctl *ctl command arguments (bug 29771) + + Old applications pass __IPC_64 as part of the command argument because + old glibc did not check for unknown commands, and passed through the + arguments directly to the kernel, without adding __IPC_64. + Applications need to continue doing that for old glibc compatibility, + so this commit enables this approach in current glibc. + + For msgctl and shmctl, if no translation is required, make + direct system calls, as we did before the time64 changes. If + translation is required, mask __IPC_64 from the command argument. + + For semctl, the union-in-vararg argument handling means that + translation is needed on all architectures. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 22a46dee24351fd5f4f188ad80554cad79c82524) + +diff --git a/sysdeps/unix/sysv/linux/ipc_priv.h b/sysdeps/unix/sysv/linux/ipc_priv.h +index f9852367a466cea9..d4efb9f3483daa9f 100644 +--- a/sysdeps/unix/sysv/linux/ipc_priv.h ++++ b/sysdeps/unix/sysv/linux/ipc_priv.h +@@ -63,4 +63,10 @@ struct __old_ipc_perm + # define __IPC_TIME64 0 + #endif + ++#if __IPC_TIME64 || defined __ASSUME_SYSVIPC_BROKEN_MODE_T ++# define IPC_CTL_NEED_TRANSLATION 1 ++#else ++# define IPC_CTL_NEED_TRANSLATION 0 ++#endif ++ + #include +diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c +index 9f38c06d53936390..ba7b94c22d17bc7f 100644 +--- a/sysdeps/unix/sysv/linux/msgctl.c ++++ b/sysdeps/unix/sysv/linux/msgctl.c +@@ -86,11 +86,19 @@ msgctl_syscall (int msqid, int cmd, msgctl_arg_t *buf) + int + __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf) + { +-#if __IPC_TIME64 ++#if IPC_CTL_NEED_TRANSLATION ++# if __IPC_TIME64 + struct kernel_msqid64_ds ksemid, *arg = NULL; +-#else ++# else + msgctl_arg_t *arg; +-#endif ++# endif ++ ++ /* Some applications pass the __IPC_64 flag in cmd, to invoke ++ previously unsupported commands back when there was no EINVAL ++ error checking in glibc. Mask the flag for the switch statements ++ below. msgctl_syscall adds back the __IPC_64 flag for the actual ++ system call. */ ++ cmd &= ~__IPC_64; + + switch (cmd) + { +@@ -102,19 +110,19 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf) + case IPC_STAT: + case MSG_STAT: + case MSG_STAT_ANY: +-#if __IPC_TIME64 ++# if __IPC_TIME64 + if (buf != NULL) + { + msqid64_to_kmsqid64 (buf, &ksemid); + arg = &ksemid; + } +-# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T ++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + if (cmd == IPC_SET) + arg->msg_perm.mode *= 0x10000U; +-# endif +-#else ++# endif ++# else + arg = buf; +-#endif ++# endif + break; + + case IPC_INFO: +@@ -138,21 +146,25 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf) + case IPC_STAT: + case MSG_STAT: + case MSG_STAT_ANY: +-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T ++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + arg->msg_perm.mode >>= 16; +-#else ++# else + /* Old Linux kernel versions might not clear the mode padding. */ + if (sizeof ((struct msqid_ds){0}.msg_perm.mode) + != sizeof (__kernel_mode_t)) + arg->msg_perm.mode &= 0xFFFF; +-#endif ++# endif + +-#if __IPC_TIME64 ++# if __IPC_TIME64 + kmsqid64_to_msqid64 (arg, buf); +-#endif ++# endif + } + + return ret; ++ ++#else /* !IPC_CTL_NEED_TRANSLATION */ ++ return msgctl_syscall (msqid, cmd, buf); ++#endif + } + #if __TIMESIZE != 64 + libc_hidden_def (__msgctl64) +diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c +index bb2690d30f80bb22..97fa411547fdd81e 100644 +--- a/sysdeps/unix/sysv/linux/semctl.c ++++ b/sysdeps/unix/sysv/linux/semctl.c +@@ -141,6 +141,13 @@ __semctl64 (int semid, int semnum, int cmd, ...) + union semun64 arg64 = { 0 }; + va_list ap; + ++ /* Some applications pass the __IPC_64 flag in cmd, to invoke ++ previously unsupported commands back when there was no EINVAL ++ error checking in glibc. Mask the flag for the switch statements ++ below. semctl_syscall adds back the __IPC_64 flag for the actual ++ system call. */ ++ cmd &= ~__IPC_64; ++ + /* Get the argument only if required. */ + switch (cmd) + { +diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c +index f52018bfae4b3364..c44cbd6e4ac890a5 100644 +--- a/sysdeps/unix/sysv/linux/shmctl.c ++++ b/sysdeps/unix/sysv/linux/shmctl.c +@@ -86,11 +86,19 @@ shmctl_syscall (int shmid, int cmd, shmctl_arg_t *buf) + int + __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf) + { +-#if __IPC_TIME64 ++#if IPC_CTL_NEED_TRANSLATION ++# if __IPC_TIME64 + struct kernel_shmid64_ds kshmid, *arg = NULL; +-#else ++# else + shmctl_arg_t *arg; +-#endif ++# endif ++ ++ /* Some applications pass the __IPC_64 flag in cmd, to invoke ++ previously unsupported commands back when there was no EINVAL ++ error checking in glibc. Mask the flag for the switch statements ++ below. shmctl_syscall adds back the __IPC_64 flag for the actual ++ system call. */ ++ cmd &= ~__IPC_64; + + switch (cmd) + { +@@ -104,19 +112,19 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf) + case IPC_STAT: + case SHM_STAT: + case SHM_STAT_ANY: +-#if __IPC_TIME64 ++# if __IPC_TIME64 + if (buf != NULL) + { + shmid64_to_kshmid64 (buf, &kshmid); + arg = &kshmid; + } +-# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T ++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + if (cmd == IPC_SET) + arg->shm_perm.mode *= 0x10000U; +-# endif +-#else ++# endif ++# else + arg = buf; +-#endif ++# endif + break; + + case IPC_INFO: +@@ -141,21 +149,25 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf) + case IPC_STAT: + case SHM_STAT: + case SHM_STAT_ANY: +-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T ++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + arg->shm_perm.mode >>= 16; +-#else ++# else + /* Old Linux kernel versions might not clear the mode padding. */ + if (sizeof ((struct shmid_ds){0}.shm_perm.mode) + != sizeof (__kernel_mode_t)) + arg->shm_perm.mode &= 0xFFFF; +-#endif ++# endif + +-#if __IPC_TIME64 ++# if __IPC_TIME64 + kshmid64_to_shmid64 (arg, buf); +-#endif ++# endif + } + + return ret; ++ ++#else /* !IPC_CTL_NEED_TRANSLATION */ ++ return shmctl_syscall (shmid, cmd, buf); ++#endif + } + #if __TIMESIZE != 64 + libc_hidden_def (__shmctl64) diff --git a/SOURCES/glibc-upstream-2.34-36.patch b/SOURCES/glibc-upstream-2.34-36.patch new file mode 100644 index 0000000..76a5844 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-36.patch @@ -0,0 +1,47 @@ +commit 79528414dc1578800cbf1fba2fbdb6335f4f39bf +Author: H.J. Lu +Date: Thu Sep 30 10:29:17 2021 -0700 + + elf: Replace nsid with args.nsid [BZ #27609] + + commit ec935dea6332cb22f9881cd1162bad156173f4b0 + Author: Florian Weimer + Date: Fri Apr 24 22:31:15 2020 +0200 + + elf: Implement __libc_early_init + + has + + @@ -856,6 +876,11 @@ no more namespaces available for dlmopen()")); + /* See if an error occurred during loading. */ + if (__glibc_unlikely (exception.errstring != NULL)) + { + + /* Avoid keeping around a dangling reference to the libc.so link + + map in case it has been cached in libc_map. */ + + if (!args.libc_already_loaded) + + GL(dl_ns)[nsid].libc_map = NULL; + + + + do_dlopen calls _dl_open with nsid == __LM_ID_CALLER (-2), which calls + dl_open_worker with args.nsid = nsid. dl_open_worker updates args.nsid + if it is __LM_ID_CALLER. After dl_open_worker returns, it is wrong to + use nsid. + + Replace nsid with args.nsid after dl_open_worker returns. This fixes + BZ #27609. + + (cherry picked from commit 1e1ecea62e899acb58c3fdf3b320a0833ddd0dff) + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index ec386626f96e17f7..41c7250bf630f978 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -886,7 +886,7 @@ no more namespaces available for dlmopen()")); + /* Avoid keeping around a dangling reference to the libc.so link + map in case it has been cached in libc_map. */ + if (!args.libc_already_loaded) +- GL(dl_ns)[nsid].libc_map = NULL; ++ GL(dl_ns)[args.nsid].libc_map = NULL; + + /* Remove the object from memory. It may be in an inconsistent + state if relocation failed, for example. */ diff --git a/SOURCES/glibc-upstream-2.34-361.patch b/SOURCES/glibc-upstream-2.34-361.patch new file mode 100644 index 0000000..b6b86ca --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-361.patch @@ -0,0 +1,46 @@ +commit 691f70b84a1284f35c8cf9fbf3ef3b1cec41c234 +Author: Vladislav Khmelevsky +Date: Thu Nov 17 12:47:29 2022 +0400 + + elf: Fix rtld-audit trampoline for aarch64 + + This patch fixes two problems with audit: + + 1. The DL_OFFSET_RV_VPCS offset was mixed up with DL_OFFSET_RG_VPCS, + resulting in x2 register value nulling in RG structure. + + 2. We need to preserve the x8 register before function call, but + don't have to save it's new value and restore it before return. + + Anyway the final restore was using OFFSET_RV instead of OFFSET_RG value + which is wrong (althoug doesn't affect anything). + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit eb4181e9f4a512de37dad4ba623c921671584dea) + +diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S +index 457570e7df5148c0..b84c53d1a544c1b1 100644 +--- a/sysdeps/aarch64/dl-trampoline.S ++++ b/sysdeps/aarch64/dl-trampoline.S +@@ -298,12 +298,11 @@ _dl_runtime_profile: + stp x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1] + stp x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2] + stp x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3] +- str x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4] + stp q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0] + stp q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1] + stp q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2] + stp q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3] +- str xzr, [X29, #OFFSET_RV + DL_OFFSET_RG_VPCS] ++ str xzr, [X29, #OFFSET_RV + DL_OFFSET_RV_VPCS] + + /* Setup call to pltexit */ + ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0] +@@ -315,7 +314,6 @@ _dl_runtime_profile: + ldp x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1] + ldp x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2] + ldp x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3] +- ldr x8, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*4] + ldp q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0] + ldp q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1] + ldp q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2] diff --git a/SOURCES/glibc-upstream-2.34-362.patch b/SOURCES/glibc-upstream-2.34-362.patch new file mode 100644 index 0000000..d7b4767 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-362.patch @@ -0,0 +1,128 @@ +commit e3255e7d2188d1731aad83ad0dc147513560aa1e +Author: Noah Goldstein +Date: Tue Sep 20 17:58:04 2022 -0700 + + x86: Fix wcsnlen-avx2 page cross length comparison [BZ #29591] + + Previous implementation was adjusting length (rsi) to match + bytes (eax), but since there is no bound to length this can cause + overflow. + + Fix is to just convert the byte-count (eax) to length by dividing by + sizeof (wchar_t) before the comparison. + + Full check passes on x86-64 and build succeeds w/ and w/o multiarch. + + (cherry picked from commit b0969fa53a28b4ab2159806bf6c99a98999502ee) + +diff --git a/string/test-strnlen.c b/string/test-strnlen.c +index bb5d9b5f04fa6586..eac84cd17526d5d9 100644 +--- a/string/test-strnlen.c ++++ b/string/test-strnlen.c +@@ -75,7 +75,7 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char) + { + size_t i; + +- align &= 63; ++ align &= (getpagesize () / sizeof (CHAR) - 1); + if ((align + len) * sizeof (CHAR) >= page_size) + return; + +@@ -92,36 +92,50 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char) + static void + do_overflow_tests (void) + { +- size_t i, j, len; ++ size_t i, j, al_idx, repeats, len; + const size_t one = 1; + uintptr_t buf_addr = (uintptr_t) buf1; ++ const size_t alignments[] = { 0, 1, 7, 9, 31, 33, 63, 65, 95, 97, 127, 129 }; + +- for (i = 0; i < 750; ++i) ++ for (al_idx = 0; al_idx < sizeof (alignments) / sizeof (alignments[0]); ++ al_idx++) + { +- do_test (0, i, SIZE_MAX - i, BIG_CHAR); +- do_test (0, i, i - buf_addr, BIG_CHAR); +- do_test (0, i, -buf_addr - i, BIG_CHAR); +- do_test (0, i, SIZE_MAX - buf_addr - i, BIG_CHAR); +- do_test (0, i, SIZE_MAX - buf_addr + i, BIG_CHAR); +- +- len = 0; +- for (j = 8 * sizeof(size_t) - 1; j ; --j) +- { +- len |= one << j; +- do_test (0, i, len - i, BIG_CHAR); +- do_test (0, i, len + i, BIG_CHAR); +- do_test (0, i, len - buf_addr - i, BIG_CHAR); +- do_test (0, i, len - buf_addr + i, BIG_CHAR); +- +- do_test (0, i, ~len - i, BIG_CHAR); +- do_test (0, i, ~len + i, BIG_CHAR); +- do_test (0, i, ~len - buf_addr - i, BIG_CHAR); +- do_test (0, i, ~len - buf_addr + i, BIG_CHAR); +- +- do_test (0, i, -buf_addr, BIG_CHAR); +- do_test (0, i, j - buf_addr, BIG_CHAR); +- do_test (0, i, -buf_addr - j, BIG_CHAR); +- } ++ for (repeats = 0; repeats < 2; ++repeats) ++ { ++ size_t align = repeats ? (getpagesize () - alignments[al_idx]) ++ : alignments[al_idx]; ++ align /= sizeof (CHAR); ++ for (i = 0; i < 750; ++i) ++ { ++ do_test (align, i, SIZE_MAX, BIG_CHAR); ++ ++ do_test (align, i, SIZE_MAX - i, BIG_CHAR); ++ do_test (align, i, i - buf_addr, BIG_CHAR); ++ do_test (align, i, -buf_addr - i, BIG_CHAR); ++ do_test (align, i, SIZE_MAX - buf_addr - i, BIG_CHAR); ++ do_test (align, i, SIZE_MAX - buf_addr + i, BIG_CHAR); ++ ++ len = 0; ++ for (j = 8 * sizeof (size_t) - 1; j; --j) ++ { ++ len |= one << j; ++ do_test (align, i, len, BIG_CHAR); ++ do_test (align, i, len - i, BIG_CHAR); ++ do_test (align, i, len + i, BIG_CHAR); ++ do_test (align, i, len - buf_addr - i, BIG_CHAR); ++ do_test (align, i, len - buf_addr + i, BIG_CHAR); ++ ++ do_test (align, i, ~len - i, BIG_CHAR); ++ do_test (align, i, ~len + i, BIG_CHAR); ++ do_test (align, i, ~len - buf_addr - i, BIG_CHAR); ++ do_test (align, i, ~len - buf_addr + i, BIG_CHAR); ++ ++ do_test (align, i, -buf_addr, BIG_CHAR); ++ do_test (align, i, j - buf_addr, BIG_CHAR); ++ do_test (align, i, -buf_addr - j, BIG_CHAR); ++ } ++ } ++ } + } + } + +diff --git a/sysdeps/x86_64/multiarch/strlen-avx2.S b/sysdeps/x86_64/multiarch/strlen-avx2.S +index b282a75613bf52ab..4d7d68396bcd4049 100644 +--- a/sysdeps/x86_64/multiarch/strlen-avx2.S ++++ b/sysdeps/x86_64/multiarch/strlen-avx2.S +@@ -542,14 +542,11 @@ L(return_vzeroupper): + L(cross_page_less_vec): + tzcntl %eax, %eax + # ifdef USE_AS_WCSLEN +- /* NB: Multiply length by 4 to get byte count. */ +- sall $2, %esi ++ /* NB: Divide by 4 to convert from byte-count to length. */ ++ shrl $2, %eax + # endif + cmpq %rax, %rsi + cmovb %esi, %eax +-# ifdef USE_AS_WCSLEN +- shrl $2, %eax +-# endif + VZEROUPPER_RETURN + # endif + diff --git a/SOURCES/glibc-upstream-2.34-363.patch b/SOURCES/glibc-upstream-2.34-363.patch new file mode 100644 index 0000000..4428f12 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-363.patch @@ -0,0 +1,26 @@ +commit 309c4708aca762f57263a66e5bea926fdbfd82eb +Author: Adhemerval Zanella +Date: Fri Mar 25 11:16:49 2022 -0300 + + elf: Fix wrong fscanf usage on tst-pldd + + To take in consideration the extra '\0'. + + Checked on x86_64-linux-gnu. + + (cherry picked from commit b2cd93fce666fdc8c9a5c64af2741a8a6940ac99) + +diff --git a/elf/tst-pldd.c b/elf/tst-pldd.c +index 210ca4d24b8338ab..72b7a99b369a105d 100644 +--- a/elf/tst-pldd.c ++++ b/elf/tst-pldd.c +@@ -113,7 +113,8 @@ do_test (void) + TEST_VERIFY (out != NULL); + + /* First line is in the form of : */ +- TEST_COMPARE (fscanf (out, "%u: " STRINPUT (512), &pid, buffer), 2); ++ TEST_COMPARE (fscanf (out, "%u: " STRINPUT (sizeof (buffer) - 1), &pid, ++ buffer), 2); + + TEST_COMPARE (pid, *target_pid_ptr); + TEST_COMPARE (strcmp (basename (buffer), "tst-pldd"), 0); diff --git a/SOURCES/glibc-upstream-2.34-364.patch b/SOURCES/glibc-upstream-2.34-364.patch new file mode 100644 index 0000000..cf76f9b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-364.patch @@ -0,0 +1,362 @@ +commit 42b9d7def8fd7d26f1926cbc801923aa2c8a386a +Author: DJ Delorie +Date: Mon Mar 28 23:53:33 2022 -0400 + + Allow for unpriviledged nested containers + + If the build itself is run in a container, we may not be able to + fully set up a nested container for test-container testing. + Notably is the mounting of /proc, since it's critical that it + be mounted from within the same PID namespace as its users, and + thus cannot be bind mounted from outside the container like other + mounts. + + This patch defaults to using the parent's PID namespace instead of + creating a new one, as this is more likely to be allowed. + + If the test needs an isolated PID namespace, it should add the "pidns" + command to its init script. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit 2fe64148a81f0d78050c302f34a6853d21f7cae4) + +diff --git a/elf/tst-pldd.c b/elf/tst-pldd.c +index 72b7a99b369a105d..6e4174cbf95b15c0 100644 +--- a/elf/tst-pldd.c ++++ b/elf/tst-pldd.c +@@ -85,6 +85,8 @@ in_str_list (const char *libname, const char *const strlist[]) + static int + do_test (void) + { ++ support_need_proc ("needs /proc/sys/kernel/yama/ptrace_scope and /proc/$child"); ++ + /* Check if our subprocess can be debugged with ptrace. */ + { + int ptrace_scope = support_ptrace_scope (); +diff --git a/nptl/tst-pthread-getattr.c b/nptl/tst-pthread-getattr.c +index 5f60cf9722b77a1a..6128402b2673c010 100644 +--- a/nptl/tst-pthread-getattr.c ++++ b/nptl/tst-pthread-getattr.c +@@ -28,6 +28,8 @@ + #include + #include + ++#include ++ + /* There is an obscure bug in the kernel due to which RLIMIT_STACK is sometimes + returned as unlimited when it is not, which may cause this test to fail. + There is also the other case where RLIMIT_STACK is intentionally set as +@@ -153,6 +155,8 @@ check_stack_top (void) + static int + do_test (void) + { ++ support_need_proc ("Reads /proc/self/maps to get stack size."); ++ + pagesize = sysconf (_SC_PAGESIZE); + return check_stack_top (); + } +diff --git a/nss/tst-reload2.c b/nss/tst-reload2.c +index 5ecb032e9fcd6868..a494145dd679099d 100644 +--- a/nss/tst-reload2.c ++++ b/nss/tst-reload2.c +@@ -95,6 +95,8 @@ do_test (void) + char buf1[PATH_MAX]; + char buf2[PATH_MAX]; + ++ support_need_proc ("Our xmkdirp fails if we can't map our uid, which requires /proc."); ++ + sprintf (buf1, "/subdir%s", support_slibdir_prefix); + xmkdirp (buf1, 0777); + +diff --git a/support/Makefile b/support/Makefile +index 6a5fc9faf2ca2e2d..0aa9d41c5a890087 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -63,6 +63,7 @@ libsupport-routines = \ + support_format_hostent \ + support_format_netent \ + support_isolate_in_subprocess \ ++ support_need_proc \ + support_path_support_time64 \ + support_process_state \ + support_ptrace \ +diff --git a/support/support.h b/support/support.h +index ecfc9a336d272a30..b69f588e2edce6be 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -90,6 +90,11 @@ char *support_quote_string (const char *); + regular file open for writing, and initially empty. */ + int support_descriptor_supports_holes (int fd); + ++/* Predicates that a test requires a working /proc filesystem. This ++ call will exit with UNSUPPORTED if /proc is not available, printing ++ WHY_MSG as part of the diagnostic. */ ++void support_need_proc (const char *why_msg); ++ + /* Error-checking wrapper functions which terminate the process on + error. */ + +diff --git a/support/support_need_proc.c b/support/support_need_proc.c +new file mode 100644 +index 0000000000000000..9b4eab7539b2d6c3 +--- /dev/null ++++ b/support/support_need_proc.c +@@ -0,0 +1,35 @@ ++/* Indicate that a test requires a working /proc. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* We test for /proc/self/maps since that's one of the files that one ++ of our tests actually uses, but the general idea is if Linux's ++ /proc/ (procfs) filesystem is mounted. If not, the process exits ++ with an UNSUPPORTED result code. */ ++ ++void ++support_need_proc (const char *why_msg) ++{ ++#ifdef __linux__ ++ if (access ("/proc/self/maps", R_OK)) ++ FAIL_UNSUPPORTED ("/proc is not available, %s", why_msg); ++#endif ++} +diff --git a/support/test-container.c b/support/test-container.c +index 94498d39019a4776..7310335f7566b41e 100644 +--- a/support/test-container.c ++++ b/support/test-container.c +@@ -97,6 +97,7 @@ int verbose = 0; + * mytest.root/mytest.script has a list of "commands" to run: + syntax: + # comment ++ pidns + su + mv FILE FILE + cp FILE FILE +@@ -122,6 +123,8 @@ int verbose = 0; + + details: + - '#': A comment. ++ - 'pidns': Require a separate PID namespace, prints comment if it can't ++ (default is a shared pid namespace) + - 'su': Enables running test as root in the container. + - 'mv': A minimal move files command. + - 'cp': A minimal copy files command. +@@ -148,7 +151,7 @@ int verbose = 0; + * 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 ++ * The current implementation is parallel-make-safe, but only in + that it uses a lock to prevent parallel access to the testroot. */ + + +@@ -227,11 +230,37 @@ concat (const char *str, ...) + return bufs[n]; + } + ++/* Like the above, but put spaces between words. Caller frees. */ ++static char * ++concat_words (char **words, int num_words) ++{ ++ int len = 0; ++ int i; ++ char *rv, *p; ++ ++ for (i = 0; i < num_words; i ++) ++ { ++ len += strlen (words[i]); ++ len ++; ++ } ++ ++ p = rv = (char *) xmalloc (len); ++ ++ for (i = 0; i < num_words; i ++) ++ { ++ if (i > 0) ++ p = stpcpy (p, " "); ++ p = stpcpy (p, words[i]); ++ } ++ ++ return rv; ++} ++ + /* Try to mount SRC onto DEST. */ + static void + trymount (const char *src, const char *dest) + { +- if (mount (src, dest, "", MS_BIND, NULL) < 0) ++ if (mount (src, dest, "", MS_BIND | MS_REC, NULL) < 0) + FAIL_EXIT1 ("can't mount %s onto %s\n", src, dest); + } + +@@ -726,6 +755,9 @@ main (int argc, char **argv) + gid_t original_gid; + /* If set, the test runs as root instead of the user running the testsuite. */ + int be_su = 0; ++ int require_pidns = 0; ++ const char *pidns_comment = NULL; ++ int do_proc_mounts = 0; + int UMAP; + int GMAP; + /* Used for "%lld %lld 1" so need not be large. */ +@@ -1011,6 +1043,12 @@ main (int argc, char **argv) + { + be_su = 1; + } ++ else if (nt >= 1 && strcmp (the_words[0], "pidns") == 0) ++ { ++ require_pidns = 1; ++ if (nt > 1) ++ pidns_comment = concat_words (the_words + 1, nt - 1); ++ } + else if (nt == 3 && strcmp (the_words[0], "mkdirp") == 0) + { + long int m; +@@ -1068,7 +1106,8 @@ main (int argc, char **argv) + + #ifdef CLONE_NEWNS + /* The unshare here gives us our own spaces and capabilities. */ +- if (unshare (CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS) < 0) ++ if (unshare (CLONE_NEWUSER | CLONE_NEWNS ++ | (require_pidns ? CLONE_NEWPID : 0)) < 0) + { + /* Older kernels may not support all the options, or security + policy may block this call. */ +@@ -1079,6 +1118,11 @@ main (int argc, char **argv) + check_for_unshare_hints (); + FAIL_UNSUPPORTED ("unable to unshare user/fs: %s", strerror (saved_errno)); + } ++ /* We're about to exit anyway, it's "safe" to call unshare again ++ just to see if the CLONE_NEWPID caused the error. */ ++ else if (require_pidns && unshare (CLONE_NEWUSER | CLONE_NEWNS) >= 0) ++ FAIL_EXIT1 ("unable to unshare pid ns: %s : %s", strerror (errno), ++ pidns_comment ? pidns_comment : "required by test"); + else + FAIL_EXIT1 ("unable to unshare user/fs: %s", strerror (errno)); + } +@@ -1094,6 +1138,15 @@ main (int argc, char **argv) + trymount (support_srcdir_root, new_srcdir_path); + trymount (support_objdir_root, new_objdir_path); + ++ /* It may not be possible to mount /proc directly. */ ++ if (! require_pidns) ++ { ++ char *new_proc = concat (new_root_path, "/proc", NULL); ++ xmkdirp (new_proc, 0755); ++ trymount ("/proc", new_proc); ++ do_proc_mounts = 1; ++ } ++ + xmkdirp (concat (new_root_path, "/dev", NULL), 0755); + devmount (new_root_path, "null"); + devmount (new_root_path, "zero"); +@@ -1163,42 +1216,60 @@ main (int argc, char **argv) + + 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) (be_su ? 0 : 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) ++ if (require_pidns) + { +- /* We support kernels old enough to not have this. */ +- write (GMAP, "deny\n", 5); +- xclose (GMAP); ++ /* Now that we're pid 1 (effectively "root") we can mount /proc */ ++ maybe_xmkdir ("/proc", 0777); ++ if (mount ("proc", "/proc", "proc", 0, NULL) != 0) ++ { ++ /* This happens if we're trying to create a nested container, ++ like if the build is running under podman, and we lack ++ priviledges. ++ ++ Ideally we would WARN here, but that would just add noise to ++ *every* test-container test, and the ones that care should ++ have their own relevent diagnostics. ++ ++ FAIL_EXIT1 ("Unable to mount /proc: "); */ ++ } ++ else ++ do_proc_mounts = 1; + } + +- /* 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"); ++ if (do_proc_mounts) ++ { ++ /* 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) (be_su ? 0 : 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); ++ } + +- sprintf (tmp, "%lld %lld 1\n", +- (long long) (be_su ? 0 : original_gid), (long long) original_gid); +- write (GMAP, tmp, strlen (tmp)); +- 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) (be_su ? 0 : original_gid), (long long) original_gid); ++ write (GMAP, tmp, strlen (tmp)); ++ xclose (GMAP); ++ } + + if (change_cwd) + { diff --git a/SOURCES/glibc-upstream-2.34-365.patch b/SOURCES/glibc-upstream-2.34-365.patch new file mode 100644 index 0000000..1fd3d7c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-365.patch @@ -0,0 +1,39 @@ +commit 405b8ae13540e9fd614df614e3361ebf9abd14cf +Author: Adhemerval Zanella +Date: Tue Jul 5 12:58:40 2022 -0300 + + elf: Fix wrong fscanf usage on tst-pldd + + The fix done b2cd93fce666fdc8c9a5c64af2741a8a6940ac99 does not really + work since macro strification does not expand the sizeof nor the + arithmetic operation. + + Checked on x86_64-linux-gnu. + + (cherry picked from commit c353689e49e72f3aafa1a9e68d4f7a4f33a79cbe) + +diff --git a/elf/tst-pldd.c b/elf/tst-pldd.c +index 6e4174cbf95b15c0..d3ecb99149d619c6 100644 +--- a/elf/tst-pldd.c ++++ b/elf/tst-pldd.c +@@ -108,15 +108,16 @@ do_test (void) + loader and libc. */ + { + pid_t pid; +- char buffer[512]; +-#define STRINPUT(size) "%" # size "s" ++#define BUFFERLEN 511 ++ char buffer[BUFFERLEN + 1]; ++#define STRINPUT(size) XSTRINPUT(size) ++#define XSTRINPUT(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 (sizeof (buffer) - 1), &pid, +- buffer), 2); ++ TEST_COMPARE (fscanf (out, "%u: " STRINPUT (BUFFERLEN), &pid, buffer), 2); + + TEST_COMPARE (pid, *target_pid_ptr); + TEST_COMPARE (strcmp (basename (buffer), "tst-pldd"), 0); diff --git a/SOURCES/glibc-upstream-2.34-366.patch b/SOURCES/glibc-upstream-2.34-366.patch new file mode 100644 index 0000000..dec7dc4 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-366.patch @@ -0,0 +1,29 @@ +commit a1c12fdf3f9b8665719835ce8330b3b2e2574b37 +Author: Florian Weimer +Date: Fri Sep 10 13:18:36 2021 +0200 + + _Static_assert needs two arguments for compatibility with GCC before 9 + + This macro definition enforces two arguments even with newer compilers + that accept the single-argument form, too. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit c9fef4b7d1d0f2dad192c74f06102752247677a9) + +diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h +index 6a76160ed4e4cabb..56adb231aa8f8cbe 100644 +--- a/include/sys/cdefs.h ++++ b/include/sys/cdefs.h +@@ -1,5 +1,12 @@ + #ifndef _SYS_CDEFS_H + ++/* This is outside of _ISOMAC to enforce that _Static_assert always ++ uses the two-argument form. This can be removed once the minimum ++ GCC version used to compile glibc is GCC 9.1. */ ++#ifndef __cplusplus ++# define _Static_assert(expr, diagnostic) _Static_assert (expr, diagnostic) ++#endif ++ + #include + + #ifndef _ISOMAC diff --git a/SOURCES/glibc-upstream-2.34-367.patch b/SOURCES/glibc-upstream-2.34-367.patch new file mode 100644 index 0000000..7df9998 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-367.patch @@ -0,0 +1,72 @@ +commit a4217408a3d6050a7f42ac23adb6ac7218dca85f +Author: Tulio Magno Quites Machado Filho +Date: Fri Nov 11 17:00:15 2022 -0300 + + Apply asm redirections in syslog.h before first use [BZ #27087] + + Similar to d0fa09a770, but for syslog.h when _FORTIFY_SOURCE > 0. + Fixes [BZ #27087] by applying long double-related asm redirections + before using functions in bits/syslog.h. + + Tested with build-many-glibcs.py. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 227df6243a2b5b4d70d11772d12c02eb9cb666ca) + +diff --git a/misc/bits/syslog.h b/misc/bits/syslog.h +index 6f3137a98ee593f3..10c9c1151382a51c 100644 +--- a/misc/bits/syslog.h ++++ b/misc/bits/syslog.h +@@ -24,6 +24,20 @@ + extern void __syslog_chk (int __pri, int __flag, const char *__fmt, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); + ++#ifdef __USE_MISC ++extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt, ++ __gnuc_va_list __ap) ++ __attribute__ ((__format__ (__printf__, 3, 0))); ++#endif ++ ++#include ++#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 ++# include ++#endif ++ ++/* The following functions must be used only after applying all asm ++ redirections, e.g. long double asm redirections. */ ++ + #ifdef __va_arg_pack + __fortify_function void + syslog (int __pri, const char *__fmt, ...) +@@ -37,10 +51,6 @@ syslog (int __pri, const char *__fmt, ...) + + + #ifdef __USE_MISC +-extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt, +- __gnuc_va_list __ap) +- __attribute__ ((__format__ (__printf__, 3, 0))); +- + __fortify_function void + vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap) + { +diff --git a/misc/sys/syslog.h b/misc/sys/syslog.h +index dc3b0e7ef81de812..e7a98fb9b13ce132 100644 +--- a/misc/sys/syslog.h ++++ b/misc/sys/syslog.h +@@ -205,11 +205,11 @@ extern void vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap) + /* Define some macros helping to catch buffer overflows. */ + #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function + # include +-#endif +- +-#include +-#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 +-# include ++#else ++# include ++# if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 ++# include ++# endif + #endif + + __END_DECLS diff --git a/SOURCES/glibc-upstream-2.34-368.patch b/SOURCES/glibc-upstream-2.34-368.patch new file mode 100644 index 0000000..3f61281 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-368.patch @@ -0,0 +1,241 @@ +commit 42eb735a5d3458a24a44ace9eca87c8b61573d97 +Author: Adhemerval Zanella +Date: Thu May 20 14:20:18 2021 -0300 + + Use LFS and 64 bit time for installed programs (BZ #15333) + + The installed programs are built with a combination of different + values for MODULE_NAME, as below. To enable both Long File Support + and 64 bt time, -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 is added for + nonlibi, nscd, lddlibc4, libresolv, ldconfig, locale_programs, + iconvprogs, libnss_files, libnss_compat, libnss_db, libnss_hesiod, + libutil, libpcprofile, and libSegFault. + + nscd/nscd + nscd/nscd.o MODULE_NAME=nscd + nscd/connections.o MODULE_NAME=nscd + nscd/pwdcache.o MODULE_NAME=nscd + nscd/getpwnam_r.o MODULE_NAME=nscd + nscd/getpwuid_r.o MODULE_NAME=nscd + nscd/grpcache.o MODULE_NAME=nscd + nscd/getgrnam_r.o MODULE_NAME=nscd + nscd/getgrgid_r.o MODULE_NAME=nscd + nscd/hstcache.o MODULE_NAME=nscd + nscd/gethstbyad_r.o MODULE_NAME=nscd + nscd/gethstbynm3_r.o MODULE_NAME=nscd + nscd/getsrvbynm_r.o MODULE_NAME=nscd + nscd/getsrvbypt_r.o MODULE_NAME=nscd + nscd/servicescache.o MODULE_NAME=nscd + nscd/dbg_log.o MODULE_NAME=nscd + nscd/nscd_conf.o MODULE_NAME=nscd + nscd/nscd_stat.o MODULE_NAME=nscd + nscd/cache.o MODULE_NAME=nscd + nscd/mem.o MODULE_NAME=nscd + nscd/nscd_setup_thread.o MODULE_NAME=nscd + nscd/xmalloc.o MODULE_NAME=nscd + nscd/xstrdup.o MODULE_NAME=nscd + nscd/aicache.o MODULE_NAME=nscd + nscd/initgrcache.o MODULE_NAME=nscd + nscd/gai.o MODULE_NAME=nscd + nscd/res_hconf.o MODULE_NAME=nscd + nscd/netgroupcache.o MODULE_NAME=nscd + nscd/cachedumper.o MODULE_NAME=nscd + elf/lddlibc4 + elf/lddlibc4 MODULE_NAME=lddlibc4 + elf/pldd + elf/pldd.o MODULE_NAME=nonlib + elf/xmalloc.o MODULE_NAME=nonlib + elf/sln + elf/sln.o MODULE_NAME=nonlib + elf/static-stubs.o MODULE_NAME=nonlib + elf/sprof MODULE_NAME=nonlib + elf/ldconfig + elf/ldconfig.o MODULE_NAME=ldconfig + elf/cache.o MODULE_NAME=nonlib + elf/readlib.o MODULE_NAME=nonlib + elf/xmalloc.o MODULE_NAME=nonlib + elf/xstrdup.o MODULE_NAME=nonlib + elf/chroot_canon.o MODULE_NAME=nonlib + elf/static-stubs.o MODULE_NAME=nonlib + elf/stringtable.o MODULE_NAME=nonlib + io/pwd + io/pwd.o MODULE_NAME=nonlib + locale/locale + locale/locale.o MODULE_NAME=locale_programs + locale/locale-spec.o MODULE_NAME=locale_programs + locale/charmap-dir.o MODULE_NAME=locale_programs + locale/simple-hash.o MODULE_NAME=locale_programs + locale/xmalloc.o MODULE_NAME=locale_programs + locale/xstrdup.o MODULE_NAME=locale_programs + locale/record-status.o MODULE_NAME=locale_programs + locale/xasprintf.o MODULE_NAME=locale_programs + locale/localedef + locale/localedef.o MODULE_NAME=locale_programs + locale/ld-ctype.o MODULE_NAME=locale_programs + locale/ld-messages.o MODULE_NAME=locale_programs + locale/ld-monetary.o MODULE_NAME=locale_programs + locale/ld-numeric.o MODULE_NAME=locale_programs + locale/ld-time.o MODULE_NAME=locale_programs + locale/ld-paper.o MODULE_NAME=locale_programs + locale/ld-name.o MODULE_NAME=locale_programs + locale/ld-address.o MODULE_NAME=locale_programs + locale/ld-telephone.o MODULE_NAME=locale_programs + locale/ld-measurement.o MODULE_NAME=locale_programs + locale/ld-identification.o MODULE_NAME=locale_programs + locale/ld-collate.o MODULE_NAME=locale_programs + locale/charmap.o MODULE_NAME=locale_programs + locale/linereader.o MODULE_NAME=locale_programs + locale/locfile.o MODULE_NAME=locale_programs + locale/repertoire.o MODULE_NAME=locale_programs + locale/locarchive.o MODULE_NAME=locale_programs + locale/md5.o MODULE_NAME=locale_programs + locale/charmap-dir.o MODULE_NAME=locale_programs + locale/simple-hash.o MODULE_NAME=locale_programs + locale/xmalloc.o MODULE_NAME=locale_programs + locale/xstrdup.o MODULE_NAME=locale_programs + locale/record-status.o MODULE_NAME=locale_programs + locale/xasprintf.o MODULE_NAME=locale_programs + catgets/gencat + catgets/gencat.o MODULE_NAME=nonlib + catgets/xmalloc.o MODULE_NAME=nonlib + nss/makedb + nss/makedb.o MODULE_NAME=nonlib + nss/xmalloc.o MODULE_NAME=nonlib + nss/hash-string.o MODULE_NAME=nonlib + nss/getent + nss/getent.o MODULE_NAME=nonlib + posix/getconf + posix/getconf.o MODULE_NAME=nonlib + login/utmpdump + login/utmpdump.o MODULE_NAME=nonlib + debug/pcprofiledump + debug/pcprofiledump.o MODULE_NAME=nonlib + timezone/zic + timezone/zic.o MODULE_NAME=nonlib + timezone/zdump + timezone/zdump.o MODULE_NAME=nonlib + iconv/iconv_prog + iconv/iconv_prog.o MODULE_NAME=nonlib + iconv/iconv_charmap.o MODULE_NAME=iconvprogs + iconv/charmap.o MODULE_NAME=iconvprogs + iconv/charmap-dir.o MODULE_NAME=iconvprogs + iconv/linereader.o MODULE_NAME=iconvprogs + iconv/dummy-repertoire.o MODULE_NAME=iconvprogs + iconv/simple-hash.o MODULE_NAME=iconvprogs + iconv/xstrdup.o MODULE_NAME=iconvprogs + iconv/xmalloc.o MODULE_NAME=iconvprogs + iconv/record-status.o MODULE_NAME=iconvprogs + iconv/iconvconfig + iconv/iconvconfig.o MODULE_NAME=nonlib + iconv/strtab.o MODULE_NAME=iconvprogs + iconv/xmalloc.o MODULE_NAME=iconvprogs + iconv/hash-string.o MODULE_NAME=iconvprogs + nss/libnss_files.so MODULE_NAME=libnss_files + nss/libnss_compat.so.2 MODULE_NAME=libnss_compat + nss/libnss_db.so MODULE_NAME=libnss_db + hesiod/libnss_hesiod.so MODULE_NAME=libnss_hesiod + login/libutil.so MODULE_NAME=libutil + debug/libpcprofile.so MODULE_NAME=libpcprofile + debug/libSegFault.so MODULE_NAME=libSegFault + + Also, to avoid adding both LFS and 64 bit time support on internal + tests they are moved to a newer 'testsuite-internal' module. It + should be similar to 'nonlib' regarding internal definition and + linking namespace. + + This patch also enables LFS and 64 bit support of libsupport container + programs (echo-container, test-container, shell-container, and + true-container). + + Checked on x86_64-linux-gnu and i686-linux-gnu. + + Reviewed-by: DJ Delorie + (cherry picked from commit a6d2f948b71adcb5ea395cb04833bc645eab45e6) + +diff --git a/Makeconfig b/Makeconfig +index 4e04dafb76a1e1a1..9accb5b38d1d37b3 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -882,6 +882,13 @@ endif + # -fno-math-errno. + +extra-math-flags = $(if $(filter libm,$(in-module)),-fno-math-errno,-fmath-errno) + ++# Use 64 bit time_t support for installed programs ++installed-modules = nonlib nscd lddlibc4 libresolv ldconfig locale_programs \ ++ iconvprogs libnss_files libnss_compat libnss_db libnss_hesiod \ ++ libutil libpcprofile libSegFault +++extra-time-flags = $(if $(filter $(installed-modules),\ ++ $(in-module)),-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64) ++ + # We might want to compile with some stack-protection flag. + ifneq ($(stack-protector),) + +stack-protector=$(stack-protector) +@@ -986,7 +993,7 @@ libio-include = -I$(..)libio + built-modules = iconvprogs iconvdata ldconfig lddlibc4 libmemusage \ + libSegFault libpcprofile librpcsvc locale-programs \ + memusagestat nonlib nscd extramodules libnldbl libsupport \ +- testsuite ++ testsuite testsuite-internal + + in-module = $(subst -,_,$(firstword $(libof-$(basename $(@F))) \ + $(libof-$( +Date: Wed Oct 26 16:04:23 2022 -0300 + + nis: Build libnsl with 64 bit time_t + + And remove the usage of glibc reserved names. + Reviewed-by: DJ Delorie + + (cherry picked from commit 545eefc2f5da61801ba82b7a32ca2589b769ec90) + +diff --git a/Makeconfig b/Makeconfig +index 9accb5b38d1d37b3..89a2881b1ef605e4 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -885,7 +885,7 @@ endif + # Use 64 bit time_t support for installed programs + installed-modules = nonlib nscd lddlibc4 libresolv ldconfig locale_programs \ + iconvprogs libnss_files libnss_compat libnss_db libnss_hesiod \ +- libutil libpcprofile libSegFault ++ libutil libpcprofile libSegFault libnsl + +extra-time-flags = $(if $(filter $(installed-modules),\ + $(in-module)),-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64) + +diff --git a/nis/nis_call.c b/nis/nis_call.c +index 043f1bd4316aa284..37feba201c37cbca 100644 +--- a/nis/nis_call.c ++++ b/nis/nis_call.c +@@ -575,7 +575,7 @@ static struct nis_server_cache + unsigned int size; + unsigned int server_used; + unsigned int current_ep; +- __time64_t expires; ++ time_t expires; + char name[]; + } *nis_server_cache[16]; + static time_t nis_cold_start_mtime; +@@ -584,7 +584,7 @@ __libc_lock_define_initialized (static, nis_server_cache_lock) + static directory_obj * + nis_server_cache_search (const_nis_name name, int search_parent, + unsigned int *server_used, unsigned int *current_ep, +- struct __timespec64 *now) ++ struct timespec *now) + { + directory_obj *ret = NULL; + int i; +@@ -642,7 +642,7 @@ nis_server_cache_search (const_nis_name name, int search_parent, + static void + nis_server_cache_add (const_nis_name name, int search_parent, + directory_obj *dir, unsigned int server_used, +- unsigned int current_ep, struct __timespec64 *now) ++ unsigned int current_ep, struct timespec *now) + { + struct nis_server_cache **loc; + struct nis_server_cache *new; +@@ -708,7 +708,7 @@ __nisfind_server (const_nis_name name, int search_parent, + nis_error result = NIS_SUCCESS; + nis_error status; + directory_obj *obj; +- struct __timespec64 ts; ++ struct timespec ts; + unsigned int server_used = ~0; + unsigned int current_ep = ~0; + +@@ -718,7 +718,7 @@ __nisfind_server (const_nis_name name, int search_parent, + if (*dir != NULL) + return NIS_SUCCESS; + +- __clock_gettime64 (CLOCK_REALTIME, &ts); ++ clock_gettime (CLOCK_REALTIME, &ts); + + if ((flags & NO_CACHE) == 0) + *dir = nis_server_cache_search (name, search_parent, &server_used, diff --git a/SOURCES/glibc-upstream-2.34-37.patch b/SOURCES/glibc-upstream-2.34-37.patch new file mode 100644 index 0000000..5a7eea7 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-37.patch @@ -0,0 +1,137 @@ +commit 76843f3b3ecb886b8d300220e6ec378e0fd09a8b +Author: Adhemerval Zanella +Date: Wed Oct 6 08:10:13 2021 -0300 + + y2038: Use a common definition for stat for sparc32 + + The sparc32 misses support for support done by 4e8521333bea6. + + Checked on sparcv9-linux-gnu. + + (cherry picked from commit d2b1254db208b35ff060f00a15f22a1eed5306d2) + +diff --git a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h +index b481b4f9f80a94f4..45db6b6ffbb19b8b 100644 +--- a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h +@@ -28,32 +28,35 @@ + + struct stat + { ++#ifdef __USE_TIME_BITS64 ++# include ++#else + __dev_t st_dev; /* Device. */ +-#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64 ++# if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64 + unsigned short int __pad1; + __ino_t st_ino; /* File serial number. */ +-#else ++# else + __ino64_t st_ino; /* File serial number. */ +-#endif ++# endif + __mode_t st_mode; /* File mode. */ + __nlink_t st_nlink; /* Link count. */ + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group.*/ + __dev_t st_rdev; /* Device number, if device. */ + unsigned short int __pad2; +-#ifndef __USE_FILE_OFFSET64 ++# ifndef __USE_FILE_OFFSET64 + __off_t st_size; /* Size of file, in bytes. */ +-#else ++# else + __off64_t st_size; /* Size of file, in bytes. */ +-#endif ++# endif + __blksize_t st_blksize; /* Optimal block size for I/O. */ + +-#ifndef __USE_FILE_OFFSET64 ++# ifndef __USE_FILE_OFFSET64 + __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ +-#else ++# else + __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ +-#endif +-#ifdef __USE_XOPEN2K8 ++# endif ++# ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -63,28 +66,32 @@ struct stat + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-# define st_atime st_atim.tv_sec /* Backward compatibility. */ +-# define st_mtime st_mtim.tv_sec +-# define st_ctime st_ctim.tv_sec +-#else ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-#endif ++# endif + unsigned long int __glibc_reserved4; + unsigned long int __glibc_reserved5; ++#endif /* __USE_TIME_BITS64 */ + }; + + #ifdef __USE_LARGEFILE64 + struct stat64 + { ++# ifdef __USE_TIME_BITS64 ++# include ++# else + __dev_t st_dev; /* Device. */ +-# if __WORDSIZE == 64 ++# if __WORDSIZE == 64 + unsigned short int __pad1; +-# endif ++# endif + __ino64_t st_ino; /* File serial number. */ + __mode_t st_mode; /* File mode. */ + __nlink_t st_nlink; /* Link count. */ +@@ -96,7 +103,7 @@ struct stat64 + __blksize_t st_blksize; /* Optimal block size for I/O. */ + + __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ +-# ifdef __USE_XOPEN2K8 ++# ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -106,19 +113,20 @@ struct stat64 + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-# define st_atime st_atim.tv_sec /* Backward compatibility. */ +-# define st_mtime st_mtim.tv_sec +-# define st_ctime st_ctim.tv_sec +-# else ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-# endif ++# endif + unsigned long int __glibc_reserved4; + unsigned long int __glibc_reserved5; ++# endif /* __USE_TIME_BITS64 */ + }; + #endif + diff --git a/SOURCES/glibc-upstream-2.34-370.patch b/SOURCES/glibc-upstream-2.34-370.patch new file mode 100644 index 0000000..41037ec --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-370.patch @@ -0,0 +1,38 @@ +commit 01c0a0405c5ea63d9b528e062b935d2ff6a6e2ed +Author: Adhemerval Zanella Netto +Date: Wed Oct 26 16:04:24 2022 -0300 + + nscd: Use 64 bit time_t on libc nscd routines (BZ# 29402) + + Although the nscd module is built with 64 bit time_t, the routines + linked direct to libc.so need to use the internal symbols. + Reviewed-by: DJ Delorie + + (cherry picked from commit fa4a19277842fd09a4815a986f70e0fe0903836f) + +diff --git a/nscd/nscd.h b/nscd/nscd.h +index b5da5be98a11d4de..1ce4c1f7fdb215f0 100644 +--- a/nscd/nscd.h ++++ b/nscd/nscd.h +@@ -66,7 +66,7 @@ typedef enum + struct traced_file + { + /* Tracks the last modified time of the traced file. */ +- time_t mtime; ++ __time64_t mtime; + /* Support multiple registered files per database. */ + struct traced_file *next; + int call_res_init; +diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c +index 81bf324256384de7..b6baa8abf881461c 100644 +--- a/nscd/nscd_gethst_r.c ++++ b/nscd/nscd_gethst_r.c +@@ -113,7 +113,7 @@ __nscd_get_nl_timestamp (void) + if (map == NULL + || (map != NO_MAPPING + && map->head->nscd_certainly_running == 0 +- && map->head->timestamp + MAPPING_TIMEOUT < time_now ())) ++ && map->head->timestamp + MAPPING_TIMEOUT < time64_now ())) + map = __nscd_get_mapping (GETFDHST, "hosts", &__hst_map_handle.mapped); + + if (map == NO_MAPPING) diff --git a/SOURCES/glibc-upstream-2.34-371.patch b/SOURCES/glibc-upstream-2.34-371.patch new file mode 100644 index 0000000..b4ded31 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-371.patch @@ -0,0 +1,24 @@ +commit e14a91e59d35bf2fa649a9726ccce838b8c6e4b7 +Author: Adhemerval Zanella Netto +Date: Wed Oct 26 16:04:25 2022 -0300 + + time: Use 64 bit time on tzfile + + The tzfile_mtime is already compared to 64 bit time_t stat call. + Reviewed-by: DJ Delorie + + (cherry picked from commit 4e21c2075193e406a92c0d1cb091a7c804fda4d9) + +diff --git a/time/tzfile.c b/time/tzfile.c +index 8668392ad387af05..84fd9df65f76f148 100644 +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -32,7 +32,7 @@ + int __use_tzfile; + static dev_t tzfile_dev; + static ino64_t tzfile_ino; +-static time_t tzfile_mtime; ++static __time64_t tzfile_mtime; + + struct ttinfo + { diff --git a/SOURCES/glibc-upstream-2.34-372.patch b/SOURCES/glibc-upstream-2.34-372.patch new file mode 100644 index 0000000..dd41022 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-372.patch @@ -0,0 +1,28 @@ +commit d0e2ac0c5902bd0e671863cc6cb14024d0365e67 +Author: Alan Modra +Date: Sat Nov 12 11:20:31 2022 +1030 + + elf/tst-tlsopt-powerpc fails when compiled with -mcpu=power10 (BZ# 29776) + + Supports pcrel addressing of TLS GOT entry. Also tweak the non-pcrel + asm constraint to better reflect how the reg is used. + + (cherry picked from commit 94628de77888c3292fc103840731ff85f283368e) + +diff --git a/sysdeps/powerpc/mod-tlsopt-powerpc.c b/sysdeps/powerpc/mod-tlsopt-powerpc.c +index ee0db12a737d6ab5..51cc502f2860e969 100644 +--- a/sysdeps/powerpc/mod-tlsopt-powerpc.c ++++ b/sysdeps/powerpc/mod-tlsopt-powerpc.c +@@ -24,7 +24,11 @@ tls_get_addr_opt_test (void) + tls_index *tls_arg; + #ifdef __powerpc64__ + register unsigned long thread_pointer __asm__ ("r13"); +- asm ("addi %0,2,foo@got@tlsgd" : "=r" (tls_arg)); ++# ifdef __PCREL__ ++ asm ("paddi %0,0,foo@got@tlsgd@pcrel,1" : "=b" (tls_arg)); ++# else ++ asm ("addi %0,2,foo@got@tlsgd" : "=b" (tls_arg)); ++# endif + #else + register unsigned long thread_pointer __asm__ ("r2"); + asm ("bcl 20,31,1f\n1:\t" diff --git a/SOURCES/glibc-upstream-2.34-373.patch b/SOURCES/glibc-upstream-2.34-373.patch new file mode 100644 index 0000000..01b4007 Binary files /dev/null and b/SOURCES/glibc-upstream-2.34-373.patch differ diff --git a/SOURCES/glibc-upstream-2.34-374.patch b/SOURCES/glibc-upstream-2.34-374.patch new file mode 100644 index 0000000..709b5c2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-374.patch @@ -0,0 +1,526 @@ +commit bbe4bbb6e8997b5ff9843bd3f32ac77dbaec7284 +Author: Fangrui Song +Date: Mon Aug 16 09:59:30 2021 -0700 + + elf: Drop elf/tls-macros.h in favor of __thread and tls_model attributes [BZ #28152] [BZ #28205] + + elf/tls-macros.h was added for TLS testing when GCC did not support + __thread. __thread and tls_model attributes are mature now and have been + used by many newer tests. + + Also delete tst-tls2.c which tests .tls_common (unused by modern GCC and + unsupported by Clang/LLD). .tls_common and .tbss definition are almost + identical after linking, so the runtime test doesn't add additional + coverage. Assembler and linker tests should be on the binutils side. + + When LLD 13.0.0 is allowed in configure.ac + (https://sourceware.org/pipermail/libc-alpha/2021-August/129866.html), + `make check` result is on par with glibc built with GNU ld on aarch64 + and x86_64. + + As a future clean-up, TLS_GD/TLS_LD/TLS_IE/TLS_IE macros can be removed from + sysdeps/*/tls-macros.h. We can add optional -mtls-dialect={gnu2,trad} + tests to ensure coverage. + + Tested on aarch64-linux-gnu, powerpc64le-linux-gnu, and x86_64-linux-gnu. + + Reviewed-by: Szabolcs Nagy + (cherry picked from commit 33c50ef42878b07ee6ead8b3f1a81d8c2c74697c) + +Conflicts: + elf/Makefile + (different backport order) + +diff --git a/elf/Makefile b/elf/Makefile +index feec365e4e5fe9b3..3a8590e0d3cc33ab 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -275,7 +275,6 @@ tests-static-internal := \ + tst-ptrguard1-static \ + tst-stackguard1-static \ + tst-tls1-static \ +- tst-tls2-static \ + tst-tls1-static-non-pie \ + # tests-static-internal + +@@ -308,7 +307,6 @@ tests := \ + tests-internal := \ + $(tests-static-internal) \ + tst-tls1 \ +- tst-tls2 \ + # tests-internal + + tests-static := $(tests-static-normal) $(tests-static-internal) +diff --git a/elf/tls-macros.h b/elf/tls-macros.h +deleted file mode 100644 +index e25e33b0f032099d..0000000000000000 +--- a/elf/tls-macros.h ++++ /dev/null +@@ -1,25 +0,0 @@ +-/* Macros to support TLS testing in times of missing compiler support. */ +- +-#define COMMON_INT_DEF(x) \ +- asm (".tls_common " #x ",4,4") +-/* XXX Until we get compiler support we don't need declarations. */ +-#define COMMON_INT_DECL(x) +- +-/* XXX This definition will probably be machine specific, too. */ +-#define VAR_INT_DEF(x) \ +- asm (".section .tdata\n\t" \ +- ".globl " #x "\n" \ +- ".balign 4\n" \ +- #x ":\t.long 0\n\t" \ +- ".size " #x ",4\n\t" \ +- ".previous") +-/* XXX Until we get compiler support we don't need declarations. */ +-#define VAR_INT_DECL(x) +- +-#include_next +- +- /* XXX Each architecture must have its own asm for now. */ +-#if !defined TLS_LE || !defined TLS_IE \ +- || !defined TLS_LD || !defined TLS_GD +-# error "No support for this architecture so far." +-#endif +diff --git a/elf/tst-tls1.c b/elf/tst-tls1.c +index c31da56ce9cb3e8f..b3412213ee9eaa7e 100644 +--- a/elf/tst-tls1.c ++++ b/elf/tst-tls1.c +@@ -1,13 +1,14 @@ + /* glibc test for TLS in ld.so. */ + #include + +-#include "tls-macros.h" +- +- +-/* Two common 'int' variables in TLS. */ +-COMMON_INT_DEF(foo); +-COMMON_INT_DEF(bar); + ++__thread int foo, bar __attribute__ ((tls_model("local-exec"))); ++extern __thread int foo_gd asm ("foo") __attribute__ ((tls_model("global-dynamic"))); ++extern __thread int foo_ld asm ("foo") __attribute__ ((tls_model("local-dynamic"))); ++extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec"))); ++extern __thread int bar_gd asm ("bar") __attribute__ ((tls_model("global-dynamic"))); ++extern __thread int bar_ld asm ("bar") __attribute__ ((tls_model("local-dynamic"))); ++extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec"))); + + static int + do_test (void) +@@ -18,63 +19,48 @@ do_test (void) + + /* Set the variable using the local exec model. */ + puts ("set bar to 1 (LE)"); +- ap = TLS_LE (bar); +- *ap = 1; ++ bar = 1; + + + /* Get variables using initial exec model. */ + fputs ("get sum of foo and bar (IE)", stdout); +- ap = TLS_IE (foo); +- bp = TLS_IE (bar); ++ ap = &foo_ie; ++ bp = &bar_ie; + printf (" = %d\n", *ap + *bp); + result |= *ap + *bp != 1; +- if (*ap != 0) +- { +- printf ("foo = %d\n", *ap); +- result = 1; +- } +- if (*bp != 1) ++ if (*ap != 0 || *bp != 1) + { +- printf ("bar = %d\n", *bp); ++ printf ("foo = %d\nbar = %d\n", *ap, *bp); + result = 1; + } + + +- /* Get variables using local dynamic model. */ +- fputs ("get sum of foo and bar (LD)", stdout); +- ap = TLS_LD (foo); +- bp = TLS_LD (bar); ++ /* Get variables using local dynamic model or TLSDESC. */ ++ fputs ("get sum of foo and bar (LD or TLSDESC)", stdout); ++ ap = &foo_ld; ++ bp = &bar_ld; + printf (" = %d\n", *ap + *bp); + result |= *ap + *bp != 1; +- if (*ap != 0) +- { +- printf ("foo = %d\n", *ap); +- result = 1; +- } +- if (*bp != 1) ++ if (*ap != 0 || *bp != 1) + { +- printf ("bar = %d\n", *bp); ++ printf ("foo = %d\nbar = %d\n", *ap, *bp); + result = 1; + } + + +- /* Get variables using generic dynamic model. */ +- fputs ("get sum of foo and bar (GD)", stdout); +- ap = TLS_GD (foo); +- bp = TLS_GD (bar); ++ /* Get variables using general dynamic model or TLSDESC. */ ++ fputs ("get sum of foo and bar (GD or TLSDESC)", stdout); ++ ap = &foo_gd; ++ bp = &bar_gd; + printf (" = %d\n", *ap + *bp); + result |= *ap + *bp != 1; +- if (*ap != 0) +- { +- printf ("foo = %d\n", *ap); +- result = 1; +- } +- if (*bp != 1) ++ if (*ap != 0 || *bp != 1) + { +- printf ("bar = %d\n", *bp); ++ printf ("foo = %d\nbar = %d\n", *ap, *bp); + result = 1; + } + ++ + return result; + } + +diff --git a/elf/tst-tls2.c b/elf/tst-tls2.c +deleted file mode 100644 +index 963b8d6c88bba0b5..0000000000000000 +--- a/elf/tst-tls2.c ++++ /dev/null +@@ -1,82 +0,0 @@ +-/* glibc test for TLS in ld.so. */ +-#include +- +-#include "tls-macros.h" +- +- +-/* Two 'int' variables in TLS. */ +-VAR_INT_DEF(foo); +-VAR_INT_DEF(bar); +- +- +-static int +-do_test (void) +-{ +- int result = 0; +- int *ap, *bp; +- +- +- /* Set the variable using the local exec model. */ +- puts ("set bar to 1 (LE)"); +- ap = TLS_LE (bar); +- *ap = 1; +- +- +- /* Get variables using initial exec model. */ +- fputs ("get sum of foo and bar (IE)", stdout); +- ap = TLS_IE (foo); +- bp = TLS_IE (bar); +- printf (" = %d\n", *ap + *bp); +- result |= *ap + *bp != 1; +- if (*ap != 0) +- { +- printf ("foo = %d\n", *ap); +- result = 1; +- } +- if (*bp != 1) +- { +- printf ("bar = %d\n", *bp); +- result = 1; +- } +- +- +- /* Get variables using local dynamic model. */ +- fputs ("get sum of foo and bar (LD)", stdout); +- ap = TLS_LD (foo); +- bp = TLS_LD (bar); +- printf (" = %d\n", *ap + *bp); +- result |= *ap + *bp != 1; +- if (*ap != 0) +- { +- printf ("foo = %d\n", *ap); +- result = 1; +- } +- if (*bp != 1) +- { +- printf ("bar = %d\n", *bp); +- result = 1; +- } +- +- +- /* Get variables using generic dynamic model. */ +- fputs ("get sum of foo and bar (GD)", stdout); +- ap = TLS_GD (foo); +- bp = TLS_GD (bar); +- printf (" = %d\n", *ap + *bp); +- result |= *ap + *bp != 1; +- if (*ap != 0) +- { +- printf ("foo = %d\n", *ap); +- result = 1; +- } +- if (*bp != 1) +- { +- printf ("bar = %d\n", *bp); +- result = 1; +- } +- +- return result; +-} +- +- +-#include +diff --git a/elf/tst-tls3.c b/elf/tst-tls3.c +index 7e0abb4c58c8ff50..222b179626161897 100644 +--- a/elf/tst-tls3.c ++++ b/elf/tst-tls3.c +@@ -1,13 +1,12 @@ + /* glibc test for TLS in ld.so. */ + #include + +-#include "tls-macros.h" + +- +-/* One define int variable, two externs. */ +-COMMON_INT_DECL(foo); +-VAR_INT_DECL(bar); +-VAR_INT_DEF(baz); ++__thread int foo, bar __attribute__ ((tls_model("initial-exec"))); ++__thread int baz __attribute__ ((tls_model("local-exec"))); ++extern __thread int foo_gd __attribute__ ((alias("foo"), tls_model("global-dynamic"))); ++extern __thread int bar_gd __attribute__ ((alias("bar"), tls_model("global-dynamic"))); ++extern __thread int baz_ld __attribute__ ((alias("baz"), tls_model("local-dynamic"))); + + + extern int in_dso (void); +@@ -22,23 +21,20 @@ do_test (void) + + /* Set the variable using the local exec model. */ + puts ("set baz to 3 (LE)"); +- ap = TLS_LE (baz); +- *ap = 3; ++ baz = 3; + + + /* Get variables using initial exec model. */ + puts ("set variables foo and bar (IE)"); +- ap = TLS_IE (foo); +- *ap = 1; +- bp = TLS_IE (bar); +- *bp = 2; ++ foo = 1; ++ bar = 2; + + + /* Get variables using local dynamic model. */ + fputs ("get sum of foo, bar (GD) and baz (LD)", stdout); +- ap = TLS_GD (foo); +- bp = TLS_GD (bar); +- cp = TLS_LD (baz); ++ ap = &foo_gd; ++ bp = &bar_gd; ++ cp = &baz_ld; + printf (" = %d\n", *ap + *bp + *cp); + result |= *ap + *bp + *cp != 6; + if (*ap != 1) +diff --git a/elf/tst-tlsmod1.c b/elf/tst-tlsmod1.c +index 8d9156791be9eabf..a448c4dc37eaf01b 100644 +--- a/elf/tst-tlsmod1.c ++++ b/elf/tst-tlsmod1.c +@@ -1,12 +1,12 @@ + #include + +-#include "tls-macros.h" + ++__thread int foo, bar __attribute__ ((tls_model("global-dynamic"))); ++extern __thread int baz __attribute__ ((tls_model("global-dynamic"))); ++extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec"))); ++extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec"))); ++extern __thread int baz_ie asm ("baz") __attribute__ ((tls_model("initial-exec"))); + +-/* One define int variable, two externs. */ +-COMMON_INT_DEF(foo); +-VAR_INT_DEF(bar); +-VAR_INT_DECL(baz); + + extern int in_dso (void); + +@@ -19,8 +19,8 @@ in_dso (void) + /* Get variables using initial exec model. */ + fputs ("get sum of foo and bar (IE)", stdout); + asm ("" ::: "memory"); +- ap = TLS_IE (foo); +- bp = TLS_IE (bar); ++ ap = &foo_ie; ++ bp = &bar_ie; + printf (" = %d\n", *ap + *bp); + result |= *ap + *bp != 3; + if (*ap != 1) +@@ -35,11 +35,11 @@ in_dso (void) + } + + +- /* Get variables using generic dynamic model. */ +- fputs ("get sum of foo and bar and baz (GD)", stdout); +- ap = TLS_GD (foo); +- bp = TLS_GD (bar); +- cp = TLS_GD (baz); ++ /* Get variables using generic dynamic model or TLSDESC. */ ++ fputs ("get sum of foo and bar and baz (GD or TLSDESC)", stdout); ++ ap = &foo; ++ bp = &bar; ++ cp = &baz; + printf (" = %d\n", *ap + *bp + *cp); + result |= *ap + *bp + *cp != 6; + if (*ap != 1) +diff --git a/elf/tst-tlsmod2.c b/elf/tst-tlsmod2.c +index 40eb1407f864f64a..3223fe494bb7e1f0 100644 +--- a/elf/tst-tlsmod2.c ++++ b/elf/tst-tlsmod2.c +@@ -1,9 +1,7 @@ + #include + +-#include "tls-macros.h" + +- +-COMMON_INT_DEF(foo); ++__thread int foo; + + + int +@@ -15,7 +13,7 @@ in_dso (int n, int *caller_foop) + puts ("foo"); /* Make sure PLT is used before macros. */ + asm ("" ::: "memory"); + +- foop = TLS_GD (foo); ++ foop = &foo; + + if (caller_foop != NULL && foop != caller_foop) + { +diff --git a/elf/tst-tlsmod3.c b/elf/tst-tlsmod3.c +index 6d186c47ee6ba104..d6e7498fd8331cb7 100644 +--- a/elf/tst-tlsmod3.c ++++ b/elf/tst-tlsmod3.c +@@ -1,10 +1,10 @@ + #include + +-#include "tls-macros.h" + + extern int in_dso (int n, int *caller_foop); + +-COMMON_INT_DEF(comm_n); ++extern __thread int foo; ++__thread int comm_n; + + + +@@ -20,8 +20,8 @@ in_dso2 (void) + puts ("foo"); /* Make sure PLT is used before macros. */ + asm ("" ::: "memory"); + +- foop = TLS_GD (foo); +- np = TLS_GD (comm_n); ++ foop = &foo; ++ np = &comm_n; + + if (n != *np) + { +diff --git a/elf/tst-tlsmod4.c b/elf/tst-tlsmod4.c +index 86889aac7e58bcf5..f38919a8a94861c1 100644 +--- a/elf/tst-tlsmod4.c ++++ b/elf/tst-tlsmod4.c +@@ -1,9 +1,7 @@ + #include + +-#include "tls-macros.h" + +- +-COMMON_INT_DEF(baz); ++__thread int baz; + + + int +@@ -15,7 +13,7 @@ in_dso (int n, int *caller_bazp) + puts ("foo"); /* Make sure PLT is used before macros. */ + asm ("" ::: "memory"); + +- bazp = TLS_GD (baz); ++ bazp = &baz; + + if (caller_bazp != NULL && bazp != caller_bazp) + { +diff --git a/elf/tst-tlsmod5.c b/elf/tst-tlsmod5.c +index a97c7e5e0c69de26..3f39c5bdb76e0b5c 100644 +--- a/elf/tst-tlsmod5.c ++++ b/elf/tst-tlsmod5.c +@@ -1,3 +1 @@ +-#include "tls-macros.h" +- +-COMMON_INT_DEF(foo); ++__thread int foo; +diff --git a/elf/tst-tlsmod6.c b/elf/tst-tlsmod6.c +index e968596dd4ef7756..7b3571f428b7243b 100644 +--- a/elf/tst-tlsmod6.c ++++ b/elf/tst-tlsmod6.c +@@ -1,3 +1 @@ +-#include "tls-macros.h" +- +-COMMON_INT_DEF(bar); ++__thread int bar; +diff --git a/sysdeps/powerpc/mod-tlsopt-powerpc.c b/sysdeps/powerpc/mod-tlsopt-powerpc.c +index 51cc502f2860e969..d941024963fc7e6a 100644 +--- a/sysdeps/powerpc/mod-tlsopt-powerpc.c ++++ b/sysdeps/powerpc/mod-tlsopt-powerpc.c +@@ -1,11 +1,9 @@ + /* shared library to test for __tls_get_addr optimization. */ + #include + +-#include "../../elf/tls-macros.h" + #include "dl-tls.h" + +-/* common 'int' variable in TLS. */ +-COMMON_INT_DEF(foo); ++__thread int foo __attribute__ ((tls_model("global-dynamic"))); + + + int +@@ -14,7 +12,7 @@ tls_get_addr_opt_test (void) + int result = 0; + + /* Get variable using general dynamic model. */ +- int *ap = TLS_GD (foo); ++ int *ap = &foo; + if (*ap != 0) + { + printf ("foo = %d\n", *ap); +diff --git a/sysdeps/powerpc/tst-tlsifunc.c b/sysdeps/powerpc/tst-tlsifunc.c +index 3095d41a68320d72..c8c0bada4547e1a4 100644 +--- a/sysdeps/powerpc/tst-tlsifunc.c ++++ b/sysdeps/powerpc/tst-tlsifunc.c +@@ -21,9 +21,9 @@ + #include + #include + #include +-#include + + __thread int bar; ++extern __thread int bar_gd asm ("bar") __attribute__ ((tls_model("global-dynamic"))); + static int *bar_ptr = NULL; + + static uint32_t resolver_platform = 0; +@@ -57,7 +57,7 @@ get_platform (void) + void + init_foo (void) + { +- bar_ptr = TLS_GD (bar); ++ bar_ptr = &bar_gd; + } + + int diff --git a/SOURCES/glibc-upstream-2.34-375.patch b/SOURCES/glibc-upstream-2.34-375.patch new file mode 100644 index 0000000..a02bbb3 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-375.patch @@ -0,0 +1,39 @@ +commit d36f457870a807f6f29880a2f2bde5e9b761f00c +Author: Martin Sebor +Date: Tue Jan 25 17:38:31 2022 -0700 + + intl: Avoid -Wuse-after-free [BZ #26779] + + Reviewed-by: Carlos O'Donell + (cherry picked from commit 7845064d2d5a50e347ee9f4b78ec5e6316190154) + +diff --git a/intl/localealias.c b/intl/localealias.c +index 375af2b03153acce..28041f2a48f643fa 100644 +--- a/intl/localealias.c ++++ b/intl/localealias.c +@@ -318,7 +318,15 @@ read_alias_file (const char *fname, int fname_len) + + if (string_space_act + alias_len + value_len > string_space_max) + { +- /* Increase size of memory pool. */ ++#pragma GCC diagnostic push ++ ++#if defined __GNUC__ && __GNUC__ >= 12 ++ /* Suppress the valid GCC 12 warning until the code below is changed ++ to avoid using pointers to the reallocated block. */ ++# pragma GCC diagnostic ignored "-Wuse-after-free" ++#endif ++ ++ /* Increase size of memory pool. */ + size_t new_size = (string_space_max + + (alias_len + value_len > 1024 + ? alias_len + value_len : 1024)); +@@ -351,6 +359,8 @@ read_alias_file (const char *fname, int fname_len) + value, value_len); + string_space_act += value_len; + ++#pragma GCC diagnostic pop ++ + ++nmap; + ++added; + } diff --git a/SOURCES/glibc-upstream-2.34-376.patch b/SOURCES/glibc-upstream-2.34-376.patch new file mode 100644 index 0000000..d0513d9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-376.patch @@ -0,0 +1,27 @@ +commit 92d5c52aaac0fa8e58b92e96bf2025d6848a2845 +Author: Martin Sebor +Date: Mon Oct 11 09:36:57 2021 -0600 + + resolv: Avoid GCC 12 false positive warning [BZ #28439]. + + Replace a call to sprintf with an equivalent pair of stpcpy/strcpy calls + to avoid a GCC 12 -Wformat-overflow false positive due to recent optimizer + improvements. + + (cherry picked from commit eb73b87897798de981dbbf019aa957045d768adb) + +diff --git a/resolv/res_query.c b/resolv/res_query.c +index 2f3c28cfc8c0d832..1d2c81737bc889c9 100644 +--- a/resolv/res_query.c ++++ b/resolv/res_query.c +@@ -626,7 +626,9 @@ __res_context_querydomain (struct resolv_context *ctx, + RES_SET_H_ERRNO(statp, NO_RECOVERY); + return (-1); + } +- sprintf(nbuf, "%s.%s", name, domain); ++ char *p = __stpcpy (nbuf, name); ++ *p++ = '.'; ++ strcpy (p, domain); + } + return __res_context_query (ctx, longname, class, type, answer, + anslen, answerp, answerp2, nanswerp2, diff --git a/SOURCES/glibc-upstream-2.34-377.patch b/SOURCES/glibc-upstream-2.34-377.patch new file mode 100644 index 0000000..90cff64 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-377.patch @@ -0,0 +1,34 @@ +commit 26c7c6bac9da305b634a661aa491dae2756581ec +Author: Joseph Myers +Date: Tue Oct 5 14:25:40 2021 +0000 + + Fix stdlib/tst-setcontext.c for GCC 12 -Warray-compare + + Building stdlib/tst-setcontext.c fails with GCC mainline: + + tst-setcontext.c: In function 'f2': + tst-setcontext.c:61:16: error: comparison between two arrays [-Werror=array-compare] + 61 | if (on_stack < st2 || on_stack >= st2 + sizeof (st2)) + | ^ + tst-setcontext.c:61:16: note: use '&on_stack[0] < &st2[0]' to compare the addresses + + The comparison in this case is deliberate, so adjust it as suggested + in that note. + + Tested with build-many-glibcs.py (GCC mainline) for aarch64-linux-gnu. + + (cherry picked from commit a0f0c08e4fe18e78866539b0571f8e4b57dba7a3) + +diff --git a/stdlib/tst-setcontext.c b/stdlib/tst-setcontext.c +index 1b511708c1469444..1c2925bb760c9eb4 100644 +--- a/stdlib/tst-setcontext.c ++++ b/stdlib/tst-setcontext.c +@@ -58,7 +58,7 @@ f2 (void) + puts ("start f2"); + + printf ("&on_stack=%p\n", on_stack); +- if (on_stack < st2 || on_stack >= st2 + sizeof (st2)) ++ if (&on_stack[0] < &st2[0] || &on_stack[0] >= st2 + sizeof (st2)) + { + printf ("%s: memory stack is not where it belongs!", __FUNCTION__); + exit (1); diff --git a/SOURCES/glibc-upstream-2.34-378.patch b/SOURCES/glibc-upstream-2.34-378.patch new file mode 100644 index 0000000..76de777 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-378.patch @@ -0,0 +1,86 @@ +commit 6ff61a51459d141782fbcc32ae81c0ef1954dad6 +Author: Joseph Myers +Date: Mon Oct 4 19:10:43 2021 +0000 + + Fix stdio-common tests for GCC 12 -Waddress + + My glibc bot shows failures building the testsuite with GCC mainline + across all architectures: + + tst-vfprintf-width-prec.c: In function 'do_test': + tst-vfprintf-width-prec.c:90:16: error: the comparison will always evaluate as 'false' for the address of 'result' will never be NULL [-Werror=address] + 90 | if (result == NULL) + | ^~ + tst-vfprintf-width-prec.c:89:13: note: 'result' declared here + 89 | wchar_t result[100]; + | ^~~~~~ + + This is clearly a correct warning; the comparison against NULL is + clearly a cut-and-paste mistake from an earlier case in the test that + does use calloc. Thus, remove the unnecessary check for NULL shown up + by the warning. + + Similarly, two other tests have bogus comparisons against NULL; remove + those as well: + + scanf14a.c:95:13: error: the comparison will always evaluate as 'false' for the address of 'fname' will never be NULL [-Werror=address] + 95 | if (fname == NULL) + | ^~ + scanf14a.c:93:8: note: 'fname' declared here + 93 | char fname[strlen (tmpdir) + sizeof "/tst-scanf14.XXXXXX"]; + | ^~~~~ + + scanf16a.c:125:13: error: the comparison will always evaluate as 'false' for the address of 'fname' will never be NULL [-Werror=address] + 125 | if (fname == NULL) + | ^~ + scanf16a.c:123:8: note: 'fname' declared here + 123 | char fname[strlen (tmpdir) + sizeof "/tst-scanf16.XXXXXX"]; + | ^~~~~ + + Tested with build-many-glibcs.py (GCC mainline) for aarch64-linux-gnu. + + (cherry picked from commit a312e8fe6d89f5eae6a4583d5db577121e61c0b5) + +diff --git a/stdio-common/scanf14a.c b/stdio-common/scanf14a.c +index 12adcff5a4970da1..b37712d1c673fa3a 100644 +--- a/stdio-common/scanf14a.c ++++ b/stdio-common/scanf14a.c +@@ -92,8 +92,6 @@ main (void) + + char fname[strlen (tmpdir) + sizeof "/tst-scanf14.XXXXXX"]; + sprintf (fname, "%s/tst-scanf14.XXXXXX", tmpdir); +- if (fname == NULL) +- FAIL (); + + /* Create a temporary file. */ + int fd = mkstemp (fname); +diff --git a/stdio-common/scanf16a.c b/stdio-common/scanf16a.c +index 400d85a54e81c3cb..74d0295c97f73b14 100644 +--- a/stdio-common/scanf16a.c ++++ b/stdio-common/scanf16a.c +@@ -122,8 +122,6 @@ main (void) + + char fname[strlen (tmpdir) + sizeof "/tst-scanf16.XXXXXX"]; + sprintf (fname, "%s/tst-scanf16.XXXXXX", tmpdir); +- if (fname == NULL) +- FAIL (); + + /* Create a temporary file. */ + int fd = mkstemp (fname); +diff --git a/stdio-common/tst-vfprintf-width-prec.c b/stdio-common/tst-vfprintf-width-prec.c +index 3192fd797ad4ea90..278d57f739f576e9 100644 +--- a/stdio-common/tst-vfprintf-width-prec.c ++++ b/stdio-common/tst-vfprintf-width-prec.c +@@ -87,12 +87,6 @@ do_test (void) + } + { + wchar_t result[100]; +- if (result == NULL) +- { +- printf ("error: calloc (%d, %zu): %m", ret + 1, sizeof (wchar_t)); +- return 1; +- } +- + ret = swprintf (result, 100, L"%133000.999999999x", 17); + if (ret >= 0) + { diff --git a/SOURCES/glibc-upstream-2.34-379.patch b/SOURCES/glibc-upstream-2.34-379.patch new file mode 100644 index 0000000..8ceaa45 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-379.patch @@ -0,0 +1,33 @@ +commit 803c959745fd7c679e00f9bad58822616f0e51cb +Author: Joseph Myers +Date: Mon Aug 2 16:33:44 2021 +0000 + + Fix build of nptl/tst-thread_local1.cc with GCC 12 + + The test nptl/tst-thread_local1.cc fails to build with GCC mainline + because of changes to what libstdc++ headers implicitly include what + other headers: + + tst-thread_local1.cc: In function 'int do_test()': + tst-thread_local1.cc:177:5: error: variable 'std::array >, 2> do_thread_X' has initializer but incomplete type + 177 | do_thread_X + | ^~~~~~~~~~~ + + Fix this by adding an explicit include of . + + Tested with build-many-glibcs.py for aarch64-linux-gnu. + + (cherry picked from commit 2ee9b24f47db8d0a8d0ccadb999335a1d4cfc364) + +diff --git a/nptl/tst-thread_local1.cc b/nptl/tst-thread_local1.cc +index 9608afa4b739e360..338aafea059e10b7 100644 +--- a/nptl/tst-thread_local1.cc ++++ b/nptl/tst-thread_local1.cc +@@ -21,6 +21,7 @@ + #include + #include + ++#include + #include + #include + #include diff --git a/SOURCES/glibc-upstream-2.34-38.patch b/SOURCES/glibc-upstream-2.34-38.patch new file mode 100644 index 0000000..7cdb50c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-38.patch @@ -0,0 +1,41 @@ +commit cb9b8b5d7670df1a13544857640efd86a299d0e4 +Author: Stafford Horne +Date: Fri Oct 15 06:17:41 2021 +0900 + + timex: Use 64-bit fields on 32-bit TIMESIZE=64 systems (BZ #28469) + + This was found when testing the OpenRISC port I am working on. These + two tests fail with SIGSEGV: + + FAIL: misc/tst-ntp_gettime + FAIL: misc/tst-ntp_gettimex + + This was found to be due to the kernel overwriting the stack space + allocated by the timex structure. The reason for the overwrite being + that the kernel timex has 64-bit fields and user space code only + allocates enough stack space for timex with 32-bit fields. + + On 32-bit systems with TIMESIZE=64 __USE_TIME_BITS64 is not defined. + This causes the timex structure to use 32-bit fields with type + __syscall_slong_t. + + This patch adjusts the ifdef condition to allow 32-bit systems with + TIMESIZE=64 to use the 64-bit long long timex definition. + + Reviewed-by: Adhemerval Zanella + + (Cherry picked from commit 1d550265a75b412cea4889a50b101395f6a8e025) + +diff --git a/sysdeps/unix/sysv/linux/bits/timex.h b/sysdeps/unix/sysv/linux/bits/timex.h +index ee37694e8f09a8e4..4a5db6deca10de58 100644 +--- a/sysdeps/unix/sysv/linux/bits/timex.h ++++ b/sysdeps/unix/sysv/linux/bits/timex.h +@@ -25,7 +25,7 @@ + + struct timex + { +-# ifdef __USE_TIME_BITS64 ++# if defined __USE_TIME_BITS64 || (__TIMESIZE == 64 && __WORDSIZE == 32) + unsigned int modes; /* mode selector */ + int :32; /* pad */ + long long offset; /* time offset (usec) */ diff --git a/SOURCES/glibc-upstream-2.34-380.patch b/SOURCES/glibc-upstream-2.34-380.patch new file mode 100644 index 0000000..509a9e8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-380.patch @@ -0,0 +1,176 @@ +commit 88b3228d9f6322b035fa89bb34f82d93b4190d48 +Author: Martin Sebor +Date: Tue Jan 25 15:39:38 2022 -0700 + + Avoid -Wuse-after-free in tests [BZ #26779]. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit c094c232eb3246154265bb035182f92fe1b17ab8) + +diff --git a/malloc/tst-malloc-backtrace.c b/malloc/tst-malloc-backtrace.c +index 4eb42e7f32f706e9..2ae3fb11efc245cb 100644 +--- a/malloc/tst-malloc-backtrace.c ++++ b/malloc/tst-malloc-backtrace.c +@@ -20,6 +20,7 @@ + #include + + #include ++#include + + #define SIZE 4096 + +@@ -29,7 +30,15 @@ __attribute__((noinline)) + call_free (void *ptr) + { + free (ptr); ++#if __GNUC_PREREQ (12, 0) ++ /* Ignore a valid warning about using a pointer made indeterminate ++ by a prior call to free(). */ ++ DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free"); ++#endif + *(size_t *)(ptr - sizeof (size_t)) = 1; ++#if __GNUC_PREREQ (12, 0) ++ DIAG_POP_NEEDS_COMMENT; ++#endif + } + + int +diff --git a/malloc/tst-malloc-check.c b/malloc/tst-malloc-check.c +index 6650d09cf6cdde75..c5c9254a9e8936b0 100644 +--- a/malloc/tst-malloc-check.c ++++ b/malloc/tst-malloc-check.c +@@ -87,7 +87,15 @@ do_test (void) + merror ("errno is not set correctly."); + DIAG_POP_NEEDS_COMMENT; + ++#if __GNUC_PREREQ (12, 0) ++ /* Ignore a valid warning about using a pointer made indeterminate ++ by a prior call to realloc(). */ ++ DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free"); ++#endif + free (p); ++#if __GNUC_PREREQ (12, 0) ++ DIAG_POP_NEEDS_COMMENT; ++#endif + + p = malloc (512); + if (p == NULL) +@@ -105,7 +113,15 @@ do_test (void) + merror ("errno is not set correctly."); + DIAG_POP_NEEDS_COMMENT; + ++#if __GNUC_PREREQ (12, 0) ++ /* Ignore a valid warning about using a pointer made indeterminate ++ by a prior call to realloc(). */ ++ DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free"); ++#endif + free (p); ++#if __GNUC_PREREQ (12, 0) ++ DIAG_POP_NEEDS_COMMENT; ++#endif + free (q); + + return errors != 0; +diff --git a/malloc/tst-malloc-too-large.c b/malloc/tst-malloc-too-large.c +index a4349a9b4c506dfc..328b4a2a4fd72cf4 100644 +--- a/malloc/tst-malloc-too-large.c ++++ b/malloc/tst-malloc-too-large.c +@@ -95,7 +95,15 @@ test_large_allocations (size_t size) + DIAG_POP_NEEDS_COMMENT; + #endif + TEST_VERIFY (errno == ENOMEM); ++#if __GNUC_PREREQ (12, 0) ++ /* Ignore a warning about using a pointer made indeterminate by ++ a prior call to realloc(). */ ++ DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free"); ++#endif + free (ptr_to_realloc); ++#if __GNUC_PREREQ (12, 0) ++ DIAG_POP_NEEDS_COMMENT; ++#endif + + for (size_t nmemb = 1; nmemb <= 8; nmemb *= 2) + if ((size % nmemb) == 0) +@@ -113,14 +121,30 @@ test_large_allocations (size_t size) + test_setup (); + TEST_VERIFY (reallocarray (ptr_to_realloc, nmemb, size / nmemb) == NULL); + TEST_VERIFY (errno == ENOMEM); ++#if __GNUC_PREREQ (12, 0) ++ /* Ignore a warning about using a pointer made indeterminate by ++ a prior call to realloc(). */ ++ DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free"); ++#endif + free (ptr_to_realloc); ++#if __GNUC_PREREQ (12, 0) ++ DIAG_POP_NEEDS_COMMENT; ++#endif + + ptr_to_realloc = malloc (16); + TEST_VERIFY_EXIT (ptr_to_realloc != NULL); + test_setup (); + TEST_VERIFY (reallocarray (ptr_to_realloc, size / nmemb, nmemb) == NULL); + TEST_VERIFY (errno == ENOMEM); ++#if __GNUC_PREREQ (12, 0) ++ /* Ignore a warning about using a pointer made indeterminate by ++ a prior call to realloc(). */ ++ DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free"); ++#endif + free (ptr_to_realloc); ++#if __GNUC_PREREQ (12, 0) ++ DIAG_POP_NEEDS_COMMENT; ++#endif + } + else + break; +diff --git a/malloc/tst-obstack.c b/malloc/tst-obstack.c +index ee1385d0f764e368..7d700c4f9a86b676 100644 +--- a/malloc/tst-obstack.c ++++ b/malloc/tst-obstack.c +@@ -21,8 +21,8 @@ verbose_malloc (size_t size) + static void + verbose_free (void *buf) + { +- free (buf); + printf ("free (%p)\n", buf); ++ free (buf); + } + + static int +diff --git a/malloc/tst-realloc.c b/malloc/tst-realloc.c +index c89ac07e192d70eb..80711beab1257ed5 100644 +--- a/malloc/tst-realloc.c ++++ b/malloc/tst-realloc.c +@@ -138,8 +138,16 @@ do_test (void) + if (ok == 0) + merror ("first 16 bytes were not correct after failed realloc"); + ++#if __GNUC_PREREQ (12, 0) ++ /* Ignore a valid warning about using a pointer made indeterminate ++ by a prior call to realloc(). */ ++ DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free"); ++#endif + /* realloc (p, 0) frees p (C89) and returns NULL (glibc). */ + p = realloc (p, 0); ++#if __GNUC_PREREQ (12, 0) ++ DIAG_POP_NEEDS_COMMENT; ++#endif + if (p != NULL) + merror ("realloc (p, 0) returned non-NULL."); + +diff --git a/support/tst-support-open-dev-null-range.c b/support/tst-support-open-dev-null-range.c +index 8e29def1ce780629..80c97e51586bf6ce 100644 +--- a/support/tst-support-open-dev-null-range.c ++++ b/support/tst-support-open-dev-null-range.c +@@ -39,10 +39,11 @@ check_path (int fd) + char file_path[PATH_MAX]; + ssize_t file_path_length + = readlink (proc_fd_path, file_path, sizeof (file_path)); +- free (proc_fd_path); + if (file_path_length < 0) + FAIL_EXIT1 ("readlink (%s, %p, %zu)", proc_fd_path, file_path, + sizeof (file_path)); ++ ++ free (proc_fd_path); + file_path[file_path_length] = '\0'; + TEST_COMPARE_STRING (file_path, "/dev/null"); + } diff --git a/SOURCES/glibc-upstream-2.34-381.patch b/SOURCES/glibc-upstream-2.34-381.patch new file mode 100644 index 0000000..f123f25 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-381.patch @@ -0,0 +1,28 @@ +commit dd0c72fb461a8879164588cd870702efae0c7237 +Author: H.J. Lu +Date: Mon Dec 20 15:15:12 2021 -0800 + + Regenerate ulps on x86_64 with GCC 12 + + Fix + + FAIL: math/test-float-clog10 + FAIL: math/test-float32-clog10 + + on Intel Core i7-1165G7 with GCC 12. + + (cherry picked from commit de8a0897e3c084dc93676e331b610f146000a0ab) + +diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps +index 312575f93397c4b0..1c75f0ead46819a7 100644 +--- a/sysdeps/x86_64/fpu/libm-test-ulps ++++ b/sysdeps/x86_64/fpu/libm-test-ulps +@@ -705,7 +705,7 @@ ldouble: 3 + + Function: Real part of "clog10_towardzero": + double: 5 +-float: 5 ++float: 6 + float128: 4 + ldouble: 8 + diff --git a/SOURCES/glibc-upstream-2.34-382.patch b/SOURCES/glibc-upstream-2.34-382.patch new file mode 100644 index 0000000..e82998c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-382.patch @@ -0,0 +1,111 @@ +commit 80b24b86548eee3d96130a48e760d1d6c2e0c587 +Author: H.J. Lu +Date: Mon Dec 20 15:00:24 2021 -0800 + + math: Properly cast X_TLOSS to float [BZ #28713] + + Add + + #define AS_FLOAT_CONSTANT_1(x) x##f + #define AS_FLOAT_CONSTANT(x) AS_FLOAT_CONSTANT_1(x) + + to cast X_TLOSS to float at compile-time to fix: + + FAIL: math/test-float-j0 + FAIL: math/test-float-jn + FAIL: math/test-float-y0 + FAIL: math/test-float-y1 + FAIL: math/test-float-yn + FAIL: math/test-float32-j0 + FAIL: math/test-float32-jn + FAIL: math/test-float32-y0 + FAIL: math/test-float32-y1 + FAIL: math/test-float32-yn + + when compiling with GCC 12. + + Reviewed-by: Paul Zimmermann + (cherry picked from commit 6e30181b4a3ab6c56da0378b65f4d60504982300) + +diff --git a/math/math-svid-compat.h b/math/math-svid-compat.h +index 5c18cb1b039cb3be..876cadde4084dab0 100644 +--- a/math/math-svid-compat.h ++++ b/math/math-svid-compat.h +@@ -49,6 +49,8 @@ extern int matherr (struct exception *__exc); + extern int __matherr (struct exception *__exc); + + #define X_TLOSS 1.41484755040568800000e+16 ++#define AS_FLOAT_CONSTANT_1(x) x##f ++#define AS_FLOAT_CONSTANT(x) AS_FLOAT_CONSTANT_1(x) + + /* Types of exceptions in the `type' field. */ + #define DOMAIN 1 +diff --git a/math/w_j0f_compat.c b/math/w_j0f_compat.c +index a4882eadb33853b2..f35a55219f7baa78 100644 +--- a/math/w_j0f_compat.c ++++ b/math/w_j0f_compat.c +@@ -28,7 +28,8 @@ + float + __j0f (float x) + { +- if (__builtin_expect (isgreater (fabsf (x), (float) X_TLOSS), 0) ++ if (__builtin_expect (isgreater (fabsf (x), ++ AS_FLOAT_CONSTANT (X_TLOSS)), 0) + && _LIB_VERSION != _IEEE_ && _LIB_VERSION != _POSIX_) + /* j0(|x|>X_TLOSS) */ + return __kernel_standard_f (x, x, 134); +@@ -43,7 +44,7 @@ float + __y0f (float x) + { + if (__builtin_expect (islessequal (x, 0.0f) +- || isgreater (x, (float) X_TLOSS), 0) ++ || isgreater (x, AS_FLOAT_CONSTANT (X_TLOSS)), 0) + && _LIB_VERSION != _IEEE_) + { + if (x < 0.0f) +diff --git a/math/w_j1f_compat.c b/math/w_j1f_compat.c +index f2ec7b327d2bc90a..c5e3ccd035031799 100644 +--- a/math/w_j1f_compat.c ++++ b/math/w_j1f_compat.c +@@ -28,7 +28,8 @@ + float + __j1f (float x) + { +- if (__builtin_expect (isgreater (fabsf (x), X_TLOSS), 0) ++ if (__builtin_expect (isgreater (fabsf (x), ++ AS_FLOAT_CONSTANT (X_TLOSS)), 0) + && _LIB_VERSION != _IEEE_ && _LIB_VERSION != _POSIX_) + /* j1(|x|>X_TLOSS) */ + return __kernel_standard_f (x, x, 136); +@@ -43,7 +44,7 @@ float + __y1f (float x) + { + if (__builtin_expect (islessequal (x, 0.0f) +- || isgreater (x, (float) X_TLOSS), 0) ++ || isgreater (x, AS_FLOAT_CONSTANT (X_TLOSS)), 0) + && _LIB_VERSION != _IEEE_) + { + if (x < 0.0f) +diff --git a/math/w_jnf_compat.c b/math/w_jnf_compat.c +index fb6e5060096fb070..925ccc4cd0988a8f 100644 +--- a/math/w_jnf_compat.c ++++ b/math/w_jnf_compat.c +@@ -28,7 +28,8 @@ + float + __jnf (int n, float x) + { +- if (__builtin_expect (isgreater (fabsf (x), (float) X_TLOSS), 0) ++ if (__builtin_expect (isgreater (fabsf (x), ++ AS_FLOAT_CONSTANT (X_TLOSS)), 0) + && _LIB_VERSION != _IEEE_ && _LIB_VERSION != _POSIX_) + /* jn(n,|x|>X_TLOSS) */ + return __kernel_standard_f (n, x, 138); +@@ -43,7 +44,7 @@ float + __ynf (int n, float x) + { + if (__builtin_expect (islessequal (x, 0.0f) +- || isgreater (x, (float) X_TLOSS), 0) ++ || isgreater (x, AS_FLOAT_CONSTANT (X_TLOSS)), 0) + && _LIB_VERSION != _IEEE_) + { + if (x < 0.0f) diff --git a/SOURCES/glibc-upstream-2.34-383.patch b/SOURCES/glibc-upstream-2.34-383.patch new file mode 100644 index 0000000..25a4892 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-383.patch @@ -0,0 +1,43 @@ +commit c5c666f34939d4bbf73aac8b753ab39621ebf33c +Author: H.J. Lu +Date: Mon Dec 20 14:37:26 2021 -0800 + + s_sincosf.h: Change pio4 type to float [BZ #28713] + + s_cosf.c and s_sinf.c have + + if (abstop12 (y) < abstop12 (pio4)) + + where abstop12 takes a float argument, but pio4 is static const double. + pio4 is used only in calls to abstop12 and never in arithmetic. Apply + + -static const double pio4 = 0x1.921FB54442D18p-1; + +static const float pio4 = 0x1.921FB6p-1f; + + to fix: + + FAIL: math/test-float-cos + FAIL: math/test-float-sin + FAIL: math/test-float-sincos + FAIL: math/test-float32-cos + FAIL: math/test-float32-sin + FAIL: math/test-float32-sincos + + when compiling with GCC 12. + + Reviewed-by: Paul Zimmermann + (cherry picked from commit d3e4f5a1014db09ff1c62c6506f92cba469e193d) + +diff --git a/sysdeps/ieee754/flt-32/s_sincosf.h b/sysdeps/ieee754/flt-32/s_sincosf.h +index 125ab7f846c463c6..372d8542c2c9a9c7 100644 +--- a/sysdeps/ieee754/flt-32/s_sincosf.h ++++ b/sysdeps/ieee754/flt-32/s_sincosf.h +@@ -24,7 +24,7 @@ + /* 2PI * 2^-64. */ + static const double pi63 = 0x1.921FB54442D18p-62; + /* PI / 4. */ +-static const double pio4 = 0x1.921FB54442D18p-1; ++static const float pio4 = 0x1.921FB6p-1f; + + /* Polynomial data (the cosine polynomial is negated in the 2nd entry). */ + extern const sincos_t __sincosf_table[2] attribute_hidden; diff --git a/SOURCES/glibc-upstream-2.34-384.patch b/SOURCES/glibc-upstream-2.34-384.patch new file mode 100644 index 0000000..1dfffbe --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-384.patch @@ -0,0 +1,83 @@ +commit 6484ae5b8c4d4314f748e4d3c9a9baa5385e57c5 +Author: Carlos O'Donell +Date: Fri Jan 28 15:14:29 2022 -0500 + + malloc: Fix -Wuse-after-free warning in tst-mallocalign1 [BZ #26779] + + The test leaks bits from the freed pointer via the return value + in ret, and the compiler correctly identifies this issue. + We switch the test to use TEST_VERIFY and terminate the test + if any of the pointers return an unexpected alignment. + + This fixes another -Wuse-after-free error when compiling glibc + with gcc 12. + + Tested on x86_64 and i686 without regression. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 3a7bed5f5a527dbd87412551f41e42e63aeef07a) + +diff --git a/malloc/tst-mallocalign1.c b/malloc/tst-mallocalign1.c +index 294e821afebd25ac..3e09ff30c4aa9f91 100644 +--- a/malloc/tst-mallocalign1.c ++++ b/malloc/tst-mallocalign1.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + static void * + test (size_t s) +@@ -31,41 +32,42 @@ test (size_t s) + return p; + } + ++#define ALIGNED(p) (((uintptr_t )p & MALLOC_ALIGN_MASK) == 0) ++ + static int + do_test (void) + { + void *p; +- int ret = 0; + + p = test (2); +- ret |= (uintptr_t) p & MALLOC_ALIGN_MASK; ++ TEST_VERIFY (ALIGNED (p)); + free (p); + + p = test (8); +- ret |= (uintptr_t) p & MALLOC_ALIGN_MASK; ++ TEST_VERIFY (ALIGNED (p)); + free (p); + + p = test (13); +- ret |= (uintptr_t) p & MALLOC_ALIGN_MASK; ++ TEST_VERIFY (ALIGNED (p)); + free (p); + + p = test (16); +- ret |= (uintptr_t) p & MALLOC_ALIGN_MASK; ++ TEST_VERIFY (ALIGNED (p)); + free (p); + + p = test (23); +- ret |= (uintptr_t) p & MALLOC_ALIGN_MASK; ++ TEST_VERIFY (ALIGNED (p)); + free (p); + + p = test (43); +- ret |= (uintptr_t) p & MALLOC_ALIGN_MASK; ++ TEST_VERIFY (ALIGNED (p)); + free (p); + + p = test (123); +- ret |= (uintptr_t) p & MALLOC_ALIGN_MASK; ++ TEST_VERIFY (ALIGNED (p)); + free (p); + +- return ret; ++ return 0; + } + + #include diff --git a/SOURCES/glibc-upstream-2.34-385.patch b/SOURCES/glibc-upstream-2.34-385.patch new file mode 100644 index 0000000..d952d48 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-385.patch @@ -0,0 +1,48 @@ +commit c5c792092b57687ae3ebecbe8645fa71ddb19f8c +Author: Siddhesh Poyarekar +Date: Thu Feb 2 07:49:02 2023 -0500 + + cdefs: Limit definition of fortification macros + + Define the __glibc_fortify and other macros only when __FORTIFY_LEVEL > + 0. This has the effect of not defining these macros on older C90 + compilers that do not have support for variable length argument lists. + + Also trim off the trailing backslashes from the definition of + __glibc_fortify and __glibc_fortify_n macros. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Florian Weimer + (cherry picked from commit 2337e04e21ba6040926ec871e403533f77043c40) + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index b166f3d209fe361f..92dbd3e1fc68dae7 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -151,6 +151,7 @@ + # define __glibc_objsize(__o) __bos (__o) + #endif + ++#if __USE_FORTIFY_LEVEL > 0 + /* Compile time conditions to choose between the regular, _chk and _chk_warn + variants. These conditions should get evaluated to constant and optimized + away. */ +@@ -186,7 +187,7 @@ + ? __ ## f ## _alias (__VA_ARGS__) \ + : (__glibc_unsafe_len (__l, __s, __osz) \ + ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ +- : __ ## f ## _chk (__VA_ARGS__, __osz))) \ ++ : __ ## f ## _chk (__VA_ARGS__, __osz))) + + /* Fortify function f, where object size argument passed to f is the number of + elements and not total size. */ +@@ -196,7 +197,8 @@ + ? __ ## f ## _alias (__VA_ARGS__) \ + : (__glibc_unsafe_len (__l, __s, __osz) \ + ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ +- : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) \ ++ : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) ++#endif + + #if __GNUC_PREREQ (4,3) + # define __warnattr(msg) __attribute__((__warning__ (msg))) diff --git a/SOURCES/glibc-upstream-2.34-386.patch b/SOURCES/glibc-upstream-2.34-386.patch new file mode 100644 index 0000000..fc111d4 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-386.patch @@ -0,0 +1,127 @@ +commit 0b962177ee3b45cf775176eb454fcf6aa1b0f6e3 +Author: Andreas Schwab +Date: Thu Jan 26 14:25:05 2023 +0100 + + Use 64-bit time_t interfaces in strftime and strptime (bug 30053) + + Both functions use time_t only internally, so the ABI is not affected. + + (cherry picked from commit 41349f6f67c83e7bafe49f985b56493d2c4c9c77) + +diff --git a/time/Makefile b/time/Makefile +index 38e3a7f4c77ea27f..ef3bb767b825f76a 100644 +--- a/time/Makefile ++++ b/time/Makefile +@@ -50,7 +50,7 @@ tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ + tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1 \ + tst-adjtime tst-ctime tst-difftime tst-mktime4 tst-clock_settime \ + tst-settimeofday tst-itimer tst-gmtime tst-timegm \ +- tst-timespec_get tst-timespec_getres ++ tst-timespec_get tst-timespec_getres tst-strftime4 + + tests-time64 := \ + tst-adjtime-time64 \ +@@ -65,6 +65,7 @@ tests-time64 := \ + tst-itimer-time64 \ + tst-mktime4-time64 \ + tst-settimeofday-time64 \ ++ tst-strftime4-time64 \ + tst-timegm-time64 \ + tst-timespec_get-time64 \ + tst-timespec_getres-time64 \ +diff --git a/time/strftime_l.c b/time/strftime_l.c +index d8cde9c5a3af87c7..57abbaa571694505 100644 +--- a/time/strftime_l.c ++++ b/time/strftime_l.c +@@ -159,6 +159,10 @@ extern char *tzname[]; + #ifdef _LIBC + # define tzname __tzname + # define tzset __tzset ++ ++# define time_t __time64_t ++# define __gmtime_r(t, tp) __gmtime64_r (t, tp) ++# define mktime(tp) __mktime64 (tp) + #endif + + #if !HAVE_TM_GMTOFF +diff --git a/time/strptime_l.c b/time/strptime_l.c +index 02c5d63c798f9c13..39d1e59b0871f4b4 100644 +--- a/time/strptime_l.c ++++ b/time/strptime_l.c +@@ -30,8 +30,10 @@ + #ifdef _LIBC + # define HAVE_LOCALTIME_R 0 + # include "../locale/localeinfo.h" +-#endif + ++# define time_t __time64_t ++# define __localtime_r(t, tp) __localtime64_r (t, tp) ++#endif + + #if ! HAVE_LOCALTIME_R && ! defined localtime_r + # ifdef _LIBC +diff --git a/time/tst-strftime4-time64.c b/time/tst-strftime4-time64.c +new file mode 100644 +index 0000000000000000..4d47ee7d79f9e648 +--- /dev/null ++++ b/time/tst-strftime4-time64.c +@@ -0,0 +1 @@ ++#include "tst-strftime4.c" +diff --git a/time/tst-strftime4.c b/time/tst-strftime4.c +new file mode 100644 +index 0000000000000000..659716d0fa4534ae +--- /dev/null ++++ b/time/tst-strftime4.c +@@ -0,0 +1,52 @@ ++/* Test strftime and strptime after 2038-01-19 03:14:07 UTC (bug 30053). ++ Copyright (C) 2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ TEST_VERIFY_EXIT (setenv ("TZ", "UTC0", 1) == 0); ++ tzset (); ++ if (sizeof (time_t) > 4) ++ { ++ time_t wrap = (time_t) 2147483648LL; ++ char buf[80]; ++ struct tm *tm = gmtime (&wrap); ++ TEST_VERIFY_EXIT (tm != NULL); ++ TEST_VERIFY_EXIT (strftime (buf, sizeof buf, "%s", tm) > 0); ++ puts (buf); ++ TEST_VERIFY (strcmp (buf, "2147483648") == 0); ++ ++ struct tm tm2; ++ char *p = strptime (buf, "%s", &tm2); ++ TEST_VERIFY_EXIT (p != NULL && *p == '\0'); ++ time_t t = mktime (&tm2); ++ printf ("%lld\n", (long long) t); ++ TEST_VERIFY (t == wrap); ++ } ++ else ++ FAIL_UNSUPPORTED ("32-bit time_t"); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-388.patch b/SOURCES/glibc-upstream-2.34-388.patch new file mode 100644 index 0000000..f749370 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-388.patch @@ -0,0 +1,328 @@ +commit 11ad405fd4c4c9f320d461d9ae1dd2e087cc8c32 +Author: Adhemerval Zanella +Date: Wed Dec 29 10:20:46 2021 -0300 + + elf: Fix 64 time_t support for installed statically binaries + + The usage of internal static symbol for statically linked binaries + does not work correctly for objects built with -D_TIME_BITS=64, + since the internal definition does not provide the expected aliases. + + This patch makes it to use the default stat functions instead (which + uses the default 64 time_t alias and types). + + Checked on i686-linux-gnu. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 9fe6f6363886aae6b2b210cae3ed1f5921299083) + +diff --git a/elf/cache.c b/elf/cache.c +index 8a3404923c625d18..062ec7fb0c9c300f 100644 +--- a/elf/cache.c ++++ b/elf/cache.c +@@ -319,8 +319,8 @@ print_cache (const char *cache_name) + if (fd < 0) + error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name); + +- struct stat64 st; +- if (__fstat64 (fd, &st) < 0 ++ struct stat st; ++ if (fstat (fd, &st) < 0 + /* No need to map the file if it is empty. */ + || st.st_size == 0) + { +@@ -933,7 +933,7 @@ init_aux_cache (void) + } + + int +-search_aux_cache (struct stat64 *stat_buf, int *flags, ++search_aux_cache (struct stat *stat_buf, int *flags, + unsigned int *osversion, unsigned int *isa_level, + char **soname) + { +@@ -995,7 +995,7 @@ insert_to_aux_cache (struct aux_cache_entry_id *id, int flags, + } + + void +-add_to_aux_cache (struct stat64 *stat_buf, int flags, ++add_to_aux_cache (struct stat *stat_buf, int flags, + unsigned int osversion, unsigned int isa_level, + const char *soname) + { +@@ -1018,8 +1018,8 @@ load_aux_cache (const char *aux_cache_name) + return; + } + +- struct stat64 st; +- if (__fstat64 (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file)) ++ struct stat st; ++ if (fstat (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file)) + { + close (fd); + init_aux_cache (); +@@ -1135,8 +1135,8 @@ save_aux_cache (const char *aux_cache_name) + char *dir = strdupa (aux_cache_name); + dir = dirname (dir); + +- struct stat64 st; +- if (stat64 (dir, &st) < 0) ++ struct stat st; ++ if (stat (dir, &st) < 0) + { + if (mkdir (dir, 0700) < 0) + goto out_fail; +diff --git a/elf/chroot_canon.c b/elf/chroot_canon.c +index 045611e730be9e41..a70fd25046112290 100644 +--- a/elf/chroot_canon.c ++++ b/elf/chroot_canon.c +@@ -67,7 +67,7 @@ chroot_canon (const char *chroot, const char *name) + + for (start = end = name; *start; start = end) + { +- struct stat64 st; ++ struct stat st; + + /* Skip sequence of multiple path-separators. */ + while (*start == '/') +@@ -114,7 +114,7 @@ chroot_canon (const char *chroot, const char *name) + dest = mempcpy (dest, start, end - start); + *dest = '\0'; + +- if (lstat64 (rpath, &st) < 0) ++ if (lstat (rpath, &st) < 0) + { + if (*end == '\0') + goto done; +diff --git a/elf/ldconfig.c b/elf/ldconfig.c +index b8893637f8aaea8d..be47ad8c2d7f89f3 100644 +--- a/elf/ldconfig.c ++++ b/elf/ldconfig.c +@@ -338,7 +338,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ + inode data from *ST. */ + static struct dir_entry * + new_sub_entry (const struct dir_entry *entry, const char *path, +- const struct stat64 *st) ++ const struct stat *st) + { + struct dir_entry *new_entry = xmalloc (sizeof (struct dir_entry)); + new_entry->from_file = entry->from_file; +@@ -428,8 +428,8 @@ add_glibc_hwcaps_subdirectories (struct dir_entry *entry, const char *path) + continue; + + /* See if this entry eventually resolves to a directory. */ +- struct stat64 st; +- if (fstatat64 (dirfd (dir), e->d_name, &st, 0) < 0) ++ struct stat st; ++ if (fstatat (dirfd (dir), e->d_name, &st, 0) < 0) + /* Ignore unreadable entries. */ + continue; + +@@ -513,8 +513,8 @@ add_dir_1 (const char *line, const char *from_file, int from_line) + if (opt_chroot != NULL) + path = chroot_canon (opt_chroot, path); + +- struct stat64 stat_buf; +- if (path == NULL || stat64 (path, &stat_buf)) ++ struct stat stat_buf; ++ if (path == NULL || stat (path, &stat_buf)) + { + if (opt_verbose) + error (0, errno, _("Can't stat %s"), entry->path); +@@ -542,15 +542,15 @@ add_dir (const char *line) + } + + static int +-chroot_stat (const char *real_path, const char *path, struct stat64 *st) ++chroot_stat (const char *real_path, const char *path, struct stat *st) + { + int ret; + char *canon_path; + + if (!opt_chroot) +- return stat64 (real_path, st); ++ return stat (real_path, st); + +- ret = lstat64 (real_path, st); ++ ret = lstat (real_path, st); + if (ret || !S_ISLNK (st->st_mode)) + return ret; + +@@ -558,7 +558,7 @@ chroot_stat (const char *real_path, const char *path, struct stat64 *st) + if (canon_path == NULL) + return -1; + +- ret = stat64 (canon_path, st); ++ ret = stat (canon_path, st); + free (canon_path); + return ret; + } +@@ -570,7 +570,7 @@ create_links (const char *real_path, const char *path, const char *libname, + { + char *full_libname, *full_soname; + char *real_full_libname, *real_full_soname; +- struct stat64 stat_lib, stat_so, lstat_so; ++ struct stat stat_lib, stat_so, lstat_so; + int do_link = 1; + int do_remove = 1; + /* XXX: The logics in this function should be simplified. */ +@@ -605,7 +605,7 @@ create_links (const char *real_path, const char *path, const char *libname, + && stat_lib.st_ino == stat_so.st_ino) + /* Link is already correct. */ + do_link = 0; +- else if (lstat64 (full_soname, &lstat_so) == 0 ++ else if (lstat (full_soname, &lstat_so) == 0 + && !S_ISLNK (lstat_so.st_mode)) + { + error (0, 0, _("%s is not a symbolic link\n"), full_soname); +@@ -613,7 +613,7 @@ create_links (const char *real_path, const char *path, const char *libname, + do_remove = 0; + } + } +- else if (lstat64 (real_full_soname, &lstat_so) != 0 ++ else if (lstat (real_full_soname, &lstat_so) != 0 + || !S_ISLNK (lstat_so.st_mode)) + /* Unless it is a stale symlink, there is no need to remove. */ + do_remove = 0; +@@ -657,7 +657,7 @@ manual_link (char *library) + char *real_library; + char *libname; + char *soname; +- struct stat64 stat_buf; ++ struct stat stat_buf; + int flag; + unsigned int osversion; + unsigned int isa_level; +@@ -711,7 +711,7 @@ manual_link (char *library) + } + + /* Do some sanity checks first. */ +- if (lstat64 (real_library, &stat_buf)) ++ if (lstat (real_library, &stat_buf)) + { + error (0, errno, _("Cannot lstat %s"), library); + goto out; +@@ -886,18 +886,18 @@ search_dir (const struct dir_entry *entry) + sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name); + } + +- struct stat64 lstat_buf; ++ struct stat lstat_buf; + /* We optimize and try to do the lstat call only if needed. */ + if (direntry->d_type != DT_UNKNOWN) + lstat_buf.st_mode = DTTOIF (direntry->d_type); + else +- if (__glibc_unlikely (lstat64 (real_file_name, &lstat_buf))) ++ if (__glibc_unlikely (lstat (real_file_name, &lstat_buf))) + { + error (0, errno, _("Cannot lstat %s"), file_name); + continue; + } + +- struct stat64 stat_buf; ++ struct stat stat_buf; + bool is_dir; + int is_link = S_ISLNK (lstat_buf.st_mode); + if (is_link) +@@ -915,7 +915,7 @@ search_dir (const struct dir_entry *entry) + continue; + } + } +- if (__glibc_unlikely (stat64 (target_name, &stat_buf))) ++ if (__glibc_unlikely (stat (target_name, &stat_buf))) + { + if (opt_verbose) + error (0, errno, _("Cannot stat %s"), file_name); +@@ -951,7 +951,7 @@ search_dir (const struct dir_entry *entry) + { + if (!is_link + && direntry->d_type != DT_UNKNOWN +- && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0)) ++ && __builtin_expect (lstat (real_file_name, &lstat_buf), 0)) + { + error (0, errno, _("Cannot lstat %s"), file_name); + continue; +@@ -980,10 +980,10 @@ search_dir (const struct dir_entry *entry) + else + real_name = real_file_name; + +- /* Call lstat64 if not done yet. */ ++ /* Call lstat if not done yet. */ + if (!is_link + && direntry->d_type != DT_UNKNOWN +- && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0)) ++ && __builtin_expect (lstat (real_file_name, &lstat_buf), 0)) + { + error (0, errno, _("Cannot lstat %s"), file_name); + continue; +diff --git a/elf/readlib.c b/elf/readlib.c +index 7383c23249426c44..8901de2684835653 100644 +--- a/elf/readlib.c ++++ b/elf/readlib.c +@@ -76,10 +76,10 @@ int + process_file (const char *real_file_name, const char *file_name, + const char *lib, int *flag, unsigned int *osversion, + unsigned int *isa_level, char **soname, int is_link, +- struct stat64 *stat_buf) ++ struct stat *stat_buf) + { + FILE *file; +- struct stat64 statbuf; ++ struct stat statbuf; + void *file_contents; + int ret; + ElfW(Ehdr) *elf_header; +@@ -99,7 +99,7 @@ process_file (const char *real_file_name, const char *file_name, + return 1; + } + +- if (fstat64 (fileno (file), &statbuf) < 0) ++ if (fstat (fileno (file), &statbuf) < 0) + { + error (0, 0, _("Cannot fstat file %s.\n"), file_name); + fclose (file); +diff --git a/elf/sln.c b/elf/sln.c +index 26f371a4932cf475..f71321d565803f06 100644 +--- a/elf/sln.c ++++ b/elf/sln.c +@@ -153,11 +153,11 @@ makesymlinks (const char *file) + static int + makesymlink (const char *src, const char *dest) + { +- struct stat64 stats; ++ struct stat stats; + const char *error; + + /* Destination must not be a directory. */ +- if (lstat64 (dest, &stats) == 0) ++ if (lstat (dest, &stats) == 0) + { + if (S_ISDIR (stats.st_mode)) + { +diff --git a/sysdeps/generic/ldconfig.h b/sysdeps/generic/ldconfig.h +index 3ab757077d160520..c0eb95bcf989dddc 100644 +--- a/sysdeps/generic/ldconfig.h ++++ b/sysdeps/generic/ldconfig.h +@@ -79,11 +79,11 @@ extern void init_aux_cache (void); + + extern void load_aux_cache (const char *aux_cache_name); + +-extern int search_aux_cache (struct stat64 *stat_buf, int *flags, ++extern int search_aux_cache (struct stat *stat_buf, int *flags, + unsigned int *osversion, + unsigned int *isa_level, char **soname); + +-extern void add_to_aux_cache (struct stat64 *stat_buf, int flags, ++extern void add_to_aux_cache (struct stat *stat_buf, int flags, + unsigned int osversion, + unsigned int isa_level, const char *soname); + +@@ -94,7 +94,7 @@ extern int process_file (const char *real_file_name, const char *file_name, + const char *lib, int *flag, + unsigned int *osversion, unsigned int *isa_level, + char **soname, int is_link, +- struct stat64 *stat_buf); ++ struct stat *stat_buf); + + extern char *implicit_soname (const char *lib, int flag); + diff --git a/SOURCES/glibc-upstream-2.34-389.patch b/SOURCES/glibc-upstream-2.34-389.patch new file mode 100644 index 0000000..83170ad --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-389.patch @@ -0,0 +1,120 @@ +commit 2d7550e6cfff541380d3a1f2ac33e76aaf1273de +Author: Florian Weimer +Date: Wed Feb 8 18:11:04 2023 +0100 + + elf: Smoke-test ldconfig -p against system /etc/ld.so.cache + + The test is sufficient to detect the ldconfig bug fixed in + commit 9fe6f6363886aae6b2b210cae3ed1f5921299083 ("elf: Fix 64 time_t + support for installed statically binaries"). + + Reviewed-by: Carlos O'Donell + (cherry picked from commit 9fd63e35371b9939e9153907c6a753e6960b68ad) + +diff --git a/elf/Makefile b/elf/Makefile +index 3a8590e0d3cc33ab..0daa8a85ec1a1bc5 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -553,6 +553,7 @@ ifeq ($(run-built-tests),yes) + tests-special += \ + $(objpfx)noload-mem.out \ + $(objpfx)tst-ldconfig-X.out \ ++ $(objpfx)tst-ldconfig-p.out \ + $(objpfx)tst-leaks1-mem.out \ + $(objpfx)tst-rtld-help.out \ + # tests-special +@@ -2259,6 +2260,11 @@ $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh $(objpfx)ldconfig + '$(run-program-env)' > $@; \ + $(evaluate-test) + ++$(objpfx)tst-ldconfig-p.out : tst-ldconfig-p.sh $(objpfx)ldconfig ++ $(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \ ++ '$(run-program-env)' > $@; \ ++ $(evaluate-test) ++ + # Test static linking of all the libraries we can possibly link + # together. Note that in some configurations this may be less than the + # complete list of libraries we build but we try to maxmimize this list. +diff --git a/elf/tst-ldconfig-p.sh b/elf/tst-ldconfig-p.sh +new file mode 100644 +index 0000000000000000..ec937bf4ec04e8c0 +--- /dev/null ++++ b/elf/tst-ldconfig-p.sh +@@ -0,0 +1,77 @@ ++#!/bin/sh ++# Test that ldconfig -p prints something useful. ++# Copyright (C) 2023 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++# Check that the newly built ldconfig -p can dump the system ++# /etc/ld.so.cache file. This should always work even if the ABIs are ++# not compatible, except in a cross-endian build (that presumably ++# involves emulation when running ldconfig). ++ ++common_objpfx=$1 ++test_wrapper_env=$2 ++run_program_env=$3 ++ ++if ! test -r /etc/ld.so.cache; then ++ echo "warning: /etc/ld.so.cache does not exist, test skipped" ++ exit 77 ++fi ++ ++testout="${common_objpfx}elf/tst-ldconfig-p.out" ++# Truncate file. ++: > "$testout" ++ ++${test_wrapper_env} \ ++${run_program_env} \ ++${common_objpfx}elf/ldconfig -p \ ++ $testroot/lib >>"$testout" 2>>"$testout" ++status=$? ++echo "info: ldconfig exit status: $status" >>"$testout" ++ ++errors=0 ++case $status in ++ (0) ++ if head -n 1 "$testout" | \ ++ grep -q "libs found in cache \`/etc/ld.so.cache'\$" ; then ++ echo "info: initial string found" >>"$testout" ++ else ++ echo "error: initial string not found" >>"$testout" ++ errors=1 ++ fi ++ if grep -q "^ libc\.so\..* => " "$testout"; then ++ echo "info: libc.so.* string found" >>"$testout" ++ else ++ echo "error: libc.so.* string not found" >>"$testout" ++ errors=1 ++ fi ++ ;; ++ (1) ++ if head -n 1 "$testout" | \ ++ grep -q ": Cache file has wrong endianness\.$" ; then ++ echo "info: cache file has wrong endianess" >> "$testout" ++ else ++ echo "error: unexpected ldconfig error message" >> "$testout" ++ errors=1 ++ fi ++ ;; ++ (*) ++ echo "error: unexpected exit status" >> "$testout" ++ errors=1 ++ ;; ++esac ++ ++exit $errors diff --git a/SOURCES/glibc-upstream-2.34-39.patch b/SOURCES/glibc-upstream-2.34-39.patch new file mode 100644 index 0000000..9b0b380 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-39.patch @@ -0,0 +1,466 @@ +commit 024a7640ab9ecea80e527f4e4d7f7a1868e952c5 +Author: Szabolcs Nagy +Date: Wed Sep 15 15:16:19 2021 +0100 + + elf: Avoid deadlock between pthread_create and ctors [BZ #28357] + + The fix for bug 19329 caused a regression such that pthread_create can + deadlock when concurrent ctors from dlopen are waiting for it to finish. + Use a new GL(dl_load_tls_lock) in pthread_create that is not taken + around ctors in dlopen. + + The new lock is also used in __tls_get_addr instead of GL(dl_load_lock). + + The new lock is held in _dl_open_worker and _dl_close_worker around + most of the logic before/after the init/fini routines. When init/fini + routines are running then TLS is in a consistent, usable state. + In _dl_open_worker the new lock requires catching and reraising dlopen + failures that happen in the critical section. + + The new lock is reinitialized in a fork child, to keep the existing + behaviour and it is kept recursive in case malloc interposition or TLS + access from signal handlers can retake it. It is not obvious if this + is necessary or helps, but avoids changing the preexisting behaviour. + + The new lock may be more appropriate for dl_iterate_phdr too than + GL(dl_load_write_lock), since TLS state of an incompletely loaded + module may be accessed. If the new lock can replace the old one, + that can be a separate change. + + Fixes bug 28357. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 83b5323261bb72313bffcf37476c1b8f0847c736) + +diff --git a/elf/dl-close.c b/elf/dl-close.c +index f39001cab981b723..cd7b9c9fe83a1a44 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -549,6 +549,9 @@ _dl_close_worker (struct link_map *map, bool force) + size_t tls_free_end; + tls_free_start = tls_free_end = NO_TLS_OFFSET; + ++ /* Protects global and module specitic TLS state. */ ++ __rtld_lock_lock_recursive (GL(dl_load_tls_lock)); ++ + /* We modify the list of loaded objects. */ + __rtld_lock_lock_recursive (GL(dl_load_write_lock)); + +@@ -784,6 +787,9 @@ _dl_close_worker (struct link_map *map, bool force) + GL(dl_tls_static_used) = tls_free_start; + } + ++ /* TLS is cleaned up for the unloaded modules. */ ++ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); ++ + #ifdef SHARED + /* Auditing checkpoint: we have deleted all objects. */ + if (__glibc_unlikely (do_audit)) +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 41c7250bf630f978..bc68e2c376debd71 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -66,6 +66,9 @@ struct dl_open_args + libc_map value in the namespace in case of a dlopen failure. */ + bool libc_already_loaded; + ++ /* Set to true if the end of dl_open_worker_begin was reached. */ ++ bool worker_continue; ++ + /* Original parameters to the program and the current environment. */ + int argc; + char **argv; +@@ -482,7 +485,7 @@ call_dl_init (void *closure) + } + + static void +-dl_open_worker (void *a) ++dl_open_worker_begin (void *a) + { + struct dl_open_args *args = a; + const char *file = args->file; +@@ -774,6 +777,36 @@ dl_open_worker (void *a) + _dl_call_libc_early_init (libc_map, false); + } + ++ args->worker_continue = true; ++} ++ ++static void ++dl_open_worker (void *a) ++{ ++ struct dl_open_args *args = a; ++ ++ args->worker_continue = false; ++ ++ { ++ /* Protects global and module specific TLS state. */ ++ __rtld_lock_lock_recursive (GL(dl_load_tls_lock)); ++ ++ struct dl_exception ex; ++ int err = _dl_catch_exception (&ex, dl_open_worker_begin, args); ++ ++ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); ++ ++ if (__glibc_unlikely (ex.errstring != NULL)) ++ /* Reraise the error. */ ++ _dl_signal_exception (err, &ex, NULL); ++ } ++ ++ if (!args->worker_continue) ++ return; ++ ++ int mode = args->mode; ++ struct link_map *new = args->map; ++ + /* Run the initializer functions of new objects. Temporarily + disable the exception handler, so that lazy binding failures are + fatal. */ +diff --git a/elf/dl-support.c b/elf/dl-support.c +index 01557181753fb38d..d8c06ba7eb4c76ea 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -229,6 +229,13 @@ __rtld_lock_define_initialized_recursive (, _dl_load_lock) + list of loaded objects while an object is added to or removed from + that list. */ + __rtld_lock_define_initialized_recursive (, _dl_load_write_lock) ++ /* This lock protects global and module specific TLS related data. ++ E.g. it is held in dlopen and dlclose when GL(dl_tls_generation), ++ GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are ++ accessed and when TLS related relocations are processed for a ++ module. It was introduced to keep pthread_create accessing TLS ++ state that is being set up. */ ++__rtld_lock_define_initialized_recursive (, _dl_load_tls_lock) + + + #ifdef HAVE_AUX_VECTOR +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index 423e380f7ca654fe..40263cf586e74c64 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -532,7 +532,7 @@ _dl_allocate_tls_init (void *result) + size_t maxgen = 0; + + /* Protects global dynamic TLS related state. */ +- __rtld_lock_lock_recursive (GL(dl_load_lock)); ++ __rtld_lock_lock_recursive (GL(dl_load_tls_lock)); + + /* Check if the current dtv is big enough. */ + if (dtv[-1].counter < GL(dl_tls_max_dtv_idx)) +@@ -606,7 +606,7 @@ _dl_allocate_tls_init (void *result) + listp = listp->next; + assert (listp != NULL); + } +- __rtld_lock_unlock_recursive (GL(dl_load_lock)); ++ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); + + /* The DTV version is up-to-date now. */ + dtv[0].counter = maxgen; +@@ -745,7 +745,7 @@ _dl_update_slotinfo (unsigned long int req_modid) + + Here the dtv needs to be updated to new_gen generation count. + +- This code may be called during TLS access when GL(dl_load_lock) ++ This code may be called during TLS access when GL(dl_load_tls_lock) + is not held. In that case the user code has to synchronize with + dlopen and dlclose calls of relevant modules. A module m is + relevant if the generation of m <= new_gen and dlclose of m is +@@ -867,11 +867,11 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map) + if (__glibc_unlikely (the_map->l_tls_offset + != FORCED_DYNAMIC_TLS_OFFSET)) + { +- __rtld_lock_lock_recursive (GL(dl_load_lock)); ++ __rtld_lock_lock_recursive (GL(dl_load_tls_lock)); + if (__glibc_likely (the_map->l_tls_offset == NO_TLS_OFFSET)) + { + the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET; +- __rtld_lock_unlock_recursive (GL(dl_load_lock)); ++ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); + } + else if (__glibc_likely (the_map->l_tls_offset + != FORCED_DYNAMIC_TLS_OFFSET)) +@@ -883,7 +883,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map) + #else + # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" + #endif +- __rtld_lock_unlock_recursive (GL(dl_load_lock)); ++ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); + + dtv[GET_ADDR_MODULE].pointer.to_free = NULL; + dtv[GET_ADDR_MODULE].pointer.val = p; +@@ -891,7 +891,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map) + return (char *) p + GET_ADDR_OFFSET; + } + else +- __rtld_lock_unlock_recursive (GL(dl_load_lock)); ++ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); + } + struct dtv_pointer result = allocate_and_init (the_map); + dtv[GET_ADDR_MODULE].pointer = result; +@@ -962,7 +962,7 @@ _dl_tls_get_addr_soft (struct link_map *l) + return NULL; + + dtv_t *dtv = THREAD_DTV (); +- /* This may be called without holding the GL(dl_load_lock). Reading ++ /* This may be called without holding the GL(dl_load_tls_lock). Reading + arbitrary gen value is fine since this is best effort code. */ + size_t gen = atomic_load_relaxed (&GL(dl_tls_generation)); + if (__glibc_unlikely (dtv[0].counter != gen)) +diff --git a/elf/rtld.c b/elf/rtld.c +index d733359eaf808b8a..08cf50145a1c01ce 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -322,6 +322,7 @@ struct rtld_global _rtld_global = + #ifdef _LIBC_REENTRANT + ._dl_load_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER, + ._dl_load_write_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER, ++ ._dl_load_tls_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER, + #endif + ._dl_nns = 1, + ._dl_ns = +diff --git a/posix/fork.c b/posix/fork.c +index c471f7b15fe4290d..021691b9b7441f15 100644 +--- a/posix/fork.c ++++ b/posix/fork.c +@@ -99,6 +99,9 @@ __libc_fork (void) + /* Reset the lock the dynamic loader uses to protect its data. */ + __rtld_lock_initialize (GL(dl_load_lock)); + ++ /* Reset the lock protecting dynamic TLS related data. */ ++ __rtld_lock_initialize (GL(dl_load_tls_lock)); ++ + reclaim_stacks (); + + /* Run the handlers registered for the child. */ +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 9c15259236adab43..1ceb9c3212c148ba 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -372,6 +372,13 @@ struct rtld_global + list of loaded objects while an object is added to or removed + from that list. */ + __rtld_lock_define_recursive (EXTERN, _dl_load_write_lock) ++ /* This lock protects global and module specific TLS related data. ++ E.g. it is held in dlopen and dlclose when GL(dl_tls_generation), ++ GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are ++ accessed and when TLS related relocations are processed for a ++ module. It was introduced to keep pthread_create accessing TLS ++ state that is being set up. */ ++ __rtld_lock_define_recursive (EXTERN, _dl_load_tls_lock) + + /* Incremented whenever something may have been added to dl_loaded. */ + EXTERN unsigned long long _dl_load_adds; +@@ -1261,7 +1268,7 @@ extern int _dl_scope_free (void *) attribute_hidden; + + /* Add module to slot information data. If DO_ADD is false, only the + required memory is allocated. Must be called with GL +- (dl_load_lock) acquired. If the function has already been called ++ (dl_load_tls_lock) acquired. If the function has already been called + for the link map L with !do_add, then this function will not raise + an exception, otherwise it is possible that it encounters a memory + allocation failure. */ +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index 0af9c59b425aefb1..df8943f4860a39d8 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -152,15 +152,17 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx6 tst-cancelx8 tst-cancelx9 \ + tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 + + ifeq ($(build-shared),yes) +-tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1 ++tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1 tst-create1 + tests-nolibpthread += tst-fini1 + endif + + modules-names += tst-atfork2mod tst-tls4moda tst-tls4modb \ +- tst-_res1mod1 tst-_res1mod2 tst-fini1mod ++ tst-_res1mod1 tst-_res1mod2 tst-fini1mod \ ++ tst-create1mod + test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names))) + + tst-atfork2mod.so-no-z-defs = yes ++tst-create1mod.so-no-z-defs = yes + + ifeq ($(build-shared),yes) + # Build all the modules even when not actually running test programs. +@@ -279,4 +281,8 @@ LDFLAGS-tst-join7mod.so = -Wl,-soname,tst-join7mod.so + + CFLAGS-tst-unwind-thread.c += -funwind-tables + ++LDFLAGS-tst-create1 = -Wl,-export-dynamic ++$(objpfx)tst-create1: $(shared-thread-library) ++$(objpfx)tst-create1.out: $(objpfx)tst-create1mod.so ++ + endif +diff --git a/sysdeps/pthread/tst-create1.c b/sysdeps/pthread/tst-create1.c +new file mode 100644 +index 0000000000000000..932586c30990d1d4 +--- /dev/null ++++ b/sysdeps/pthread/tst-create1.c +@@ -0,0 +1,119 @@ ++/* Verify that pthread_create does not deadlock when ctors take locks. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* ++Check if ctor and pthread_create deadlocks in ++ ++thread 1: dlopen -> ctor -> lock(user_lock) ++thread 2: lock(user_lock) -> pthread_create ++ ++or in ++ ++thread 1: dlclose -> dtor -> lock(user_lock) ++thread 2: lock(user_lock) -> pthread_create ++*/ ++ ++static pthread_barrier_t bar_ctor; ++static pthread_barrier_t bar_dtor; ++static pthread_mutex_t user_lock = PTHREAD_MUTEX_INITIALIZER; ++ ++void ++ctor (void) ++{ ++ xpthread_barrier_wait (&bar_ctor); ++ dprintf (1, "thread 1: in ctor: started.\n"); ++ xpthread_mutex_lock (&user_lock); ++ dprintf (1, "thread 1: in ctor: locked user_lock.\n"); ++ xpthread_mutex_unlock (&user_lock); ++ dprintf (1, "thread 1: in ctor: unlocked user_lock.\n"); ++ dprintf (1, "thread 1: in ctor: done.\n"); ++} ++ ++void ++dtor (void) ++{ ++ xpthread_barrier_wait (&bar_dtor); ++ dprintf (1, "thread 1: in dtor: started.\n"); ++ xpthread_mutex_lock (&user_lock); ++ dprintf (1, "thread 1: in dtor: locked user_lock.\n"); ++ xpthread_mutex_unlock (&user_lock); ++ dprintf (1, "thread 1: in dtor: unlocked user_lock.\n"); ++ dprintf (1, "thread 1: in dtor: done.\n"); ++} ++ ++static void * ++thread3 (void *a) ++{ ++ dprintf (1, "thread 3: started.\n"); ++ dprintf (1, "thread 3: done.\n"); ++ return 0; ++} ++ ++static void * ++thread2 (void *a) ++{ ++ pthread_t t3; ++ dprintf (1, "thread 2: started.\n"); ++ ++ xpthread_mutex_lock (&user_lock); ++ dprintf (1, "thread 2: locked user_lock.\n"); ++ xpthread_barrier_wait (&bar_ctor); ++ t3 = xpthread_create (0, thread3, 0); ++ xpthread_mutex_unlock (&user_lock); ++ dprintf (1, "thread 2: unlocked user_lock.\n"); ++ xpthread_join (t3); ++ ++ xpthread_mutex_lock (&user_lock); ++ dprintf (1, "thread 2: locked user_lock.\n"); ++ xpthread_barrier_wait (&bar_dtor); ++ t3 = xpthread_create (0, thread3, 0); ++ xpthread_mutex_unlock (&user_lock); ++ dprintf (1, "thread 2: unlocked user_lock.\n"); ++ xpthread_join (t3); ++ ++ dprintf (1, "thread 2: done.\n"); ++ return 0; ++} ++ ++static void ++thread1 (void) ++{ ++ dprintf (1, "thread 1: started.\n"); ++ xpthread_barrier_init (&bar_ctor, NULL, 2); ++ xpthread_barrier_init (&bar_dtor, NULL, 2); ++ pthread_t t2 = xpthread_create (0, thread2, 0); ++ void *p = xdlopen ("tst-create1mod.so", RTLD_NOW | RTLD_GLOBAL); ++ dprintf (1, "thread 1: dlopen done.\n"); ++ xdlclose (p); ++ dprintf (1, "thread 1: dlclose done.\n"); ++ xpthread_join (t2); ++ dprintf (1, "thread 1: done.\n"); ++} ++ ++static int ++do_test (void) ++{ ++ thread1 (); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/pthread/tst-create1mod.c b/sysdeps/pthread/tst-create1mod.c +new file mode 100644 +index 0000000000000000..62c9006961683177 +--- /dev/null ++++ b/sysdeps/pthread/tst-create1mod.c +@@ -0,0 +1,41 @@ ++/* Verify that pthread_create does not deadlock when ctors take locks. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* Require TLS setup for the module. */ ++__thread int tlsvar; ++ ++void ctor (void); ++void dtor (void); ++ ++static void __attribute__ ((constructor)) ++do_init (void) ++{ ++ dprintf (1, "constructor started: %d.\n", tlsvar++); ++ ctor (); ++ dprintf (1, "constructor done: %d.\n", tlsvar++); ++} ++ ++static void __attribute__ ((destructor)) ++do_end (void) ++{ ++ dprintf (1, "destructor started: %d.\n", tlsvar++); ++ dtor (); ++ dprintf (1, "destructor done: %d.\n", tlsvar++); ++} diff --git a/SOURCES/glibc-upstream-2.34-4.patch b/SOURCES/glibc-upstream-2.34-4.patch new file mode 100644 index 0000000..12ce5e6 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-4.patch @@ -0,0 +1,24 @@ +commit 7ff4da3dc26de351a5abe7c2905038cbe55c8041 +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:10:53 2021 +0530 + + copy_and_spawn_sgid: Avoid double calls to close() + + If close() on infd and outfd succeeded, reset the fd numbers so that + we don't attempt to close them again. + + Reviewed-by: Arjun Shankar + (cherry picked from commit 45caed9d67a00af917d8b5b88d4b5eb1225b7aef) + +diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +index 27bfd19c9374a183..0bacf6dbc23b0732 100644 +--- a/support/support_capture_subprocess.c ++++ b/support/support_capture_subprocess.c +@@ -170,6 +170,7 @@ copy_and_spawn_sgid (char *child_id, gid_t gid) + support_subprogram because we only want the program exit status, not the + contents. */ + ret = 0; ++ infd = outfd = -1; + + char * const args[] = {execname, child_id, NULL}; + diff --git a/SOURCES/glibc-upstream-2.34-40.patch b/SOURCES/glibc-upstream-2.34-40.patch new file mode 100644 index 0000000..40655b6 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-40.patch @@ -0,0 +1,151 @@ +commit 01bffc013cdad1e0c45db7aa57efb2bee61f3338 +Author: Siddhesh Poyarekar +Date: Fri Oct 29 14:53:55 2021 +0530 + + Handle NULL input to malloc_usable_size [BZ #28506] + + Hoist the NULL check for malloc_usable_size into its entry points in + malloc-debug and malloc and assume non-NULL in all callees. This fixes + BZ #28506 + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Florian Weimer + Reviewed-by: Richard W.M. Jones + (cherry picked from commit 88e316b06414ee7c944cd6f8b30b07a972b78499) + +diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c +index 9922ef5f25d2e018..3d7e6d44fdc9e17b 100644 +--- a/malloc/malloc-debug.c ++++ b/malloc/malloc-debug.c +@@ -1,5 +1,6 @@ + /* Malloc debug DSO. + Copyright (C) 2021 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -399,17 +400,17 @@ strong_alias (__debug_calloc, calloc) + size_t + malloc_usable_size (void *mem) + { ++ if (mem == NULL) ++ return 0; ++ + if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)) + return mcheck_usable_size (mem); + if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)) + return malloc_check_get_size (mem); + +- if (mem != NULL) +- { +- mchunkptr p = mem2chunk (mem); +- if (DUMPED_MAIN_ARENA_CHUNK (p)) +- return chunksize (p) - SIZE_SZ; +- } ++ mchunkptr p = mem2chunk (mem); ++ if (DUMPED_MAIN_ARENA_CHUNK (p)) ++ return chunksize (p) - SIZE_SZ; + + return musable (mem); + } +diff --git a/malloc/malloc.c b/malloc/malloc.c +index e065785af77af72c..7882c70f0a0312d1 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1,5 +1,6 @@ + /* Malloc implementation for multiple threads without lock contention. + Copyright (C) 1996-2021 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. + This file is part of the GNU C Library. + Contributed by Wolfram Gloger + and Doug Lea , 2001. +@@ -5009,20 +5010,13 @@ __malloc_trim (size_t s) + static size_t + musable (void *mem) + { +- mchunkptr p; +- if (mem != 0) +- { +- size_t result = 0; +- +- p = mem2chunk (mem); ++ mchunkptr p = mem2chunk (mem); + +- if (chunk_is_mmapped (p)) +- result = chunksize (p) - CHUNK_HDR_SZ; +- else if (inuse (p)) +- result = memsize (p); ++ if (chunk_is_mmapped (p)) ++ return chunksize (p) - CHUNK_HDR_SZ; ++ else if (inuse (p)) ++ return memsize (p); + +- return result; +- } + return 0; + } + +@@ -5030,10 +5024,9 @@ musable (void *mem) + size_t + __malloc_usable_size (void *m) + { +- size_t result; +- +- result = musable (m); +- return result; ++ if (m == NULL) ++ return 0; ++ return musable (m); + } + #endif + +diff --git a/malloc/tst-malloc-usable.c b/malloc/tst-malloc-usable.c +index a1074b782a0de96c..b0d702be10ba1610 100644 +--- a/malloc/tst-malloc-usable.c ++++ b/malloc/tst-malloc-usable.c +@@ -2,6 +2,7 @@ + MALLOC_CHECK_ exported to a positive value. + + Copyright (C) 2012-2021 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -21,29 +22,24 @@ + #include + #include + #include ++#include ++#include + + static int + do_test (void) + { + size_t usable_size; + void *p = malloc (7); +- if (!p) +- { +- printf ("memory allocation failed\n"); +- return 1; +- } + ++ TEST_VERIFY_EXIT (p != NULL); + usable_size = malloc_usable_size (p); +- if (usable_size != 7) +- { +- printf ("malloc_usable_size: expected 7 but got %zu\n", usable_size); +- return 1; +- } +- ++ TEST_COMPARE (usable_size, 7); + memset (p, 0, usable_size); + free (p); ++ ++ TEST_COMPARE (malloc_usable_size (NULL), 0); ++ + return 0; + } + +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" ++#include "support/test-driver.c" diff --git a/SOURCES/glibc-upstream-2.34-41.patch b/SOURCES/glibc-upstream-2.34-41.patch new file mode 100644 index 0000000..770fa6c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-41.patch @@ -0,0 +1,489 @@ +commit f42373f911a28d34325a5bfc1ed5a962c89da7eb +Author: H.J. Lu +Date: Thu Sep 16 08:15:29 2021 -0700 + + ld.so: Replace DL_RO_DYN_SECTION with dl_relocate_ld [BZ #28340] + + We can't relocate entries in dynamic section if it is readonly: + + 1. Add a l_ld_readonly field to struct link_map to indicate if dynamic + section is readonly and set it based on p_flags of PT_DYNAMIC segment. + 2. Replace DL_RO_DYN_SECTION with dl_relocate_ld to decide if dynamic + section should be relocated. + 3. Remove DL_RO_DYN_TEMP_CNT. + 4. Don't use a static dynamic section to make readonly dynamic section + in vDSO writable. + 5. Remove the temp argument from elf_get_dynamic_info. + + This fixes BZ #28340. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit b413280cfb16834450f66f554bc0d618bb513851) + +diff --git a/elf/Makefile b/elf/Makefile +index d05f410592723f09..de854b4d1a815bd3 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -224,7 +224,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-tls-ie tst-tls-ie-dlmopen argv0test \ + tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \ + tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \ +- tst-dl-is_dso ++ tst-dl-is_dso tst-ro-dynamic + # reldep9 + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ +@@ -357,7 +357,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \ + tst-tls20mod-bad tst-tls21mod tst-dlmopen-dlerror-mod \ + tst-auxvalmod \ +- tst-dlmopen-gethostbyname-mod \ ++ tst-dlmopen-gethostbyname-mod tst-ro-dynamic-mod \ + + # Most modules build with _ISOMAC defined, but those filtered out + # depend on internal headers. +@@ -1906,3 +1906,10 @@ $(objpfx)tst-getauxval-static.out: $(objpfx)tst-auxvalmod.so + tst-getauxval-static-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx) + + $(objpfx)tst-dlmopen-gethostbyname.out: $(objpfx)tst-dlmopen-gethostbyname-mod.so ++ ++$(objpfx)tst-ro-dynamic: $(objpfx)tst-ro-dynamic-mod.so ++$(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \ ++ tst-ro-dynamic-mod.map ++ $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \ ++ -Wl,--script=tst-ro-dynamic-mod.map \ ++ $(objpfx)tst-ro-dynamic-mod.os +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 650e4edc35e5e582..4445c28ef3fb4a7e 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1149,6 +1149,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + such a segment to avoid a crash later. */ + l->l_ld = (void *) ph->p_vaddr; + l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn)); ++ l->l_ld_readonly = (ph->p_flags & PF_W) == 0; + } + break; + +@@ -1292,7 +1293,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + else + l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr); + +- elf_get_dynamic_info (l, NULL); ++ elf_get_dynamic_info (l); + + /* Make sure we are not dlopen'ing an object that has the + DF_1_NOOPEN flag set, or a PIE object. */ +diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c +index d5bd2f31e9ca50ce..2fb02d727654c87d 100644 +--- a/elf/dl-reloc-static-pie.c ++++ b/elf/dl-reloc-static-pie.c +@@ -40,7 +40,17 @@ _dl_relocate_static_pie (void) + + /* Read our own dynamic section and fill in the info array. */ + main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ()); +- elf_get_dynamic_info (main_map, NULL); ++ ++ const ElfW(Phdr) *ph, *phdr = GL(dl_phdr); ++ size_t phnum = GL(dl_phnum); ++ for (ph = phdr; ph < &phdr[phnum]; ++ph) ++ if (ph->p_type == PT_DYNAMIC) ++ { ++ main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0; ++ break; ++ } ++ ++ elf_get_dynamic_info (main_map); + + # ifdef ELF_MACHINE_BEFORE_RTLD_RELOC + ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info); +diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h +index d8ec32377d37635c..4aa2058abf6443c9 100644 +--- a/elf/get-dynamic-info.h ++++ b/elf/get-dynamic-info.h +@@ -28,7 +28,7 @@ static + auto + #endif + inline void __attribute__ ((unused, always_inline)) +-elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) ++elf_get_dynamic_info (struct link_map *l) + { + #if __ELF_NATIVE_CLASS == 32 + typedef Elf32_Word d_tag_utype; +@@ -69,28 +69,15 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) + info[i] = dyn; + } + +-#define DL_RO_DYN_TEMP_CNT 8 +- +-#ifndef DL_RO_DYN_SECTION + /* Don't adjust .dynamic unnecessarily. */ +- if (l->l_addr != 0) ++ if (l->l_addr != 0 && dl_relocate_ld (l)) + { + ElfW(Addr) l_addr = l->l_addr; +- int cnt = 0; + + # define ADJUST_DYN_INFO(tag) \ + do \ + if (info[tag] != NULL) \ +- { \ +- if (temp) \ +- { \ +- temp[cnt].d_tag = info[tag]->d_tag; \ +- temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \ +- info[tag] = temp + cnt++; \ +- } \ +- else \ +- info[tag]->d_un.d_ptr += l_addr; \ +- } \ ++ info[tag]->d_un.d_ptr += l_addr; \ + while (0) + + ADJUST_DYN_INFO (DT_HASH); +@@ -107,9 +94,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) + ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); + ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH)); + # undef ADJUST_DYN_INFO +- assert (cnt <= DL_RO_DYN_TEMP_CNT); + } +-#endif + if (info[DT_PLTREL] != NULL) + { + #if ELF_MACHINE_NO_RELA +diff --git a/elf/rtld.c b/elf/rtld.c +index 08cf50145a1c01ce..405166d62b34847c 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -464,6 +464,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) + #ifndef DONT_USE_BOOTSTRAP_MAP + GL(dl_rtld_map).l_addr = info->l.l_addr; + GL(dl_rtld_map).l_ld = info->l.l_ld; ++ GL(dl_rtld_map).l_ld_readonly = info->l.l_ld_readonly; + memcpy (GL(dl_rtld_map).l_info, info->l.l_info, + sizeof GL(dl_rtld_map).l_info); + GL(dl_rtld_map).l_mach = info->l.l_mach; +@@ -547,7 +548,7 @@ _dl_start (void *arg) + + /* Read our own dynamic section and fill in the info array. */ + bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); +- elf_get_dynamic_info (&bootstrap_map, NULL); ++ elf_get_dynamic_info (&bootstrap_map); + + #if NO_TLS_OFFSET != 0 + bootstrap_map.l_tls_offset = NO_TLS_OFFSET; +@@ -1469,6 +1470,7 @@ dl_main (const ElfW(Phdr) *phdr, + /* This tells us where to find the dynamic section, + which tells us everything we need to do. */ + main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr; ++ main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0; + break; + case PT_INTERP: + /* This "interpreter segment" was used by the program loader to +@@ -1614,7 +1616,7 @@ dl_main (const ElfW(Phdr) *phdr, + if (! rtld_is_main) + { + /* Extract the contents of the dynamic section for easy access. */ +- elf_get_dynamic_info (main_map, NULL); ++ elf_get_dynamic_info (main_map); + + /* If the main map is libc.so, update the base namespace to + refer to this map. If libc.so is loaded later, this happens +diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h +index 86c491e49c98345d..f44748bc9858e5fd 100644 +--- a/elf/setup-vdso.h ++++ b/elf/setup-vdso.h +@@ -33,8 +33,6 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)), + 0, LM_ID_BASE); + if (__glibc_likely (l != NULL)) + { +- static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro; +- + l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso) + + GLRO(dl_sysinfo_dso)->e_phoff); + l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum; +@@ -45,6 +43,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)), + { + l->l_ld = (void *) ph->p_vaddr; + l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn)); ++ l->l_ld_readonly = (ph->p_flags & PF_W) == 0; + } + else if (ph->p_type == PT_LOAD) + { +@@ -65,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)), + l->l_map_end += l->l_addr; + l->l_text_end += l->l_addr; + l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr); +- elf_get_dynamic_info (l, dyn_temp); ++ elf_get_dynamic_info (l); + _dl_setup_hash (l); + l->l_relocated = 1; + +diff --git a/elf/tst-ro-dynamic-mod.c b/elf/tst-ro-dynamic-mod.c +new file mode 100644 +index 0000000000000000..6d99925964c50caf +--- /dev/null ++++ b/elf/tst-ro-dynamic-mod.c +@@ -0,0 +1,19 @@ ++/* Test case for DSO with readonly dynamic section. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++int foo = -1; +diff --git a/elf/tst-ro-dynamic-mod.map b/elf/tst-ro-dynamic-mod.map +new file mode 100644 +index 0000000000000000..2fe4a2998cddd587 +--- /dev/null ++++ b/elf/tst-ro-dynamic-mod.map +@@ -0,0 +1,16 @@ ++SECTIONS ++{ ++ . = SIZEOF_HEADERS; ++ .dynamic : { *(.dynamic) } :text :dynamic ++ .rodata : { *(.data*) *(.bss*) } :text ++ /DISCARD/ : { ++ *(.note.gnu.property) ++ } ++ .note : { *(.note.*) } :text :note ++} ++PHDRS ++{ ++ text PT_LOAD FLAGS(5) FILEHDR PHDRS; ++ dynamic PT_DYNAMIC FLAGS(4); ++ note PT_NOTE FLAGS(4); ++} +diff --git a/elf/tst-ro-dynamic.c b/elf/tst-ro-dynamic.c +new file mode 100644 +index 0000000000000000..3a18f8789ad386bb +--- /dev/null ++++ b/elf/tst-ro-dynamic.c +@@ -0,0 +1,31 @@ ++/* Test case for DSO with readonly dynamic section. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++extern int foo; ++ ++static int ++do_test (void) ++{ ++ TEST_COMPARE (foo, -1); ++ return 0; ++} ++ ++#include +diff --git a/include/link.h b/include/link.h +index 4af16cb59639a077..c46aced9f7b43ba0 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -205,6 +205,7 @@ struct link_map + unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be + freed, ie. not allocated with + the dummy malloc in ld.so. */ ++ unsigned int l_ld_readonly:1; /* Nonzero if dynamic section is readonly. */ + + /* NODELETE status of the map. Only valid for maps of type + lt_loaded. Lazy binding sets l_nodelete_active directly, +@@ -342,6 +343,8 @@ struct link_map + unsigned long long int l_serial; + }; + ++#include ++ + /* Information used by audit modules. For most link maps, this data + immediate follows the link map in memory. For the dynamic linker, + it is allocated separately. See link_map_audit_state in +diff --git a/sysdeps/generic/dl-relocate-ld.h b/sysdeps/generic/dl-relocate-ld.h +new file mode 100644 +index 0000000000000000..5fae206db9941e97 +--- /dev/null ++++ b/sysdeps/generic/dl-relocate-ld.h +@@ -0,0 +1,32 @@ ++/* Check if dynamic section should be relocated. Generic version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_RELOCATE_LD_H ++#define _DL_RELOCATE_LD_H ++ ++/* Return true if dynamic section in the shared library L should be ++ relocated. */ ++ ++static inline bool ++dl_relocate_ld (const struct link_map *l) ++{ ++ /* Don't relocate dynamic section if it is readonly */ ++ return !l->l_ld_readonly; ++} ++ ++#endif /* _DL_RELOCATE_LD_H */ +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 1ceb9c3212c148ba..ed10953f34b96c49 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -75,11 +75,8 @@ __BEGIN_DECLS + have to be accessed via the D_PTR macro. The macro is needed since for + most architectures the entry is already relocated - but for some not + and we need to relocate at access time. */ +-#ifdef DL_RO_DYN_SECTION +-# define D_PTR(map, i) ((map)->i->d_un.d_ptr + (map)->l_addr) +-#else +-# define D_PTR(map, i) (map)->i->d_un.d_ptr +-#endif ++#define D_PTR(map, i) \ ++ ((map)->i->d_un.d_ptr + (dl_relocate_ld (map) ? 0 : (map)->l_addr)) + + /* Result of the lookup functions and how to retrieve the base address. */ + typedef struct link_map *lookup_t; +diff --git a/sysdeps/mips/dl-relocate-ld.h b/sysdeps/mips/dl-relocate-ld.h +new file mode 100644 +index 0000000000000000..0c18d9a567cad54f +--- /dev/null ++++ b/sysdeps/mips/dl-relocate-ld.h +@@ -0,0 +1,32 @@ ++/* Check if dynamic section should be relocated. MIPS version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_RELOCATE_LD_H ++#define _DL_RELOCATE_LD_H ++ ++/* Return true if dynamic section in the shared library L should be ++ relocated. */ ++ ++static inline bool ++dl_relocate_ld (const struct link_map *l) ++{ ++ /* Never relocate dynamic section. */ ++ return false; ++} ++ ++#endif /* _DL_RELOCATE_LD_H */ +diff --git a/sysdeps/mips/ldsodefs.h b/sysdeps/mips/ldsodefs.h +index 4db7c60e38e42ef2..36fd09a8bdb4cacf 100644 +--- a/sysdeps/mips/ldsodefs.h ++++ b/sysdeps/mips/ldsodefs.h +@@ -75,10 +75,6 @@ struct La_mips_64_retval; + struct La_mips_64_retval *, \ + const char *); + +-/* The MIPS ABI specifies that the dynamic section has to be read-only. */ +- +-#define DL_RO_DYN_SECTION 1 +- + #include_next + + /* The 64-bit MIPS ELF ABI uses an unusual reloc format. Each +diff --git a/sysdeps/riscv/dl-relocate-ld.h b/sysdeps/riscv/dl-relocate-ld.h +new file mode 100644 +index 0000000000000000..10327454b17a7097 +--- /dev/null ++++ b/sysdeps/riscv/dl-relocate-ld.h +@@ -0,0 +1,32 @@ ++/* Check if dynamic section should be relocated. RISC-V version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_RELOCATE_LD_H ++#define _DL_RELOCATE_LD_H ++ ++/* Return true if dynamic section in the shared library L should be ++ relocated. */ ++ ++static inline bool ++dl_relocate_ld (const struct link_map *l) ++{ ++ /* Never relocate dynamic section for ABI compatibility. */ ++ return false; ++} ++ ++#endif /* _DL_RELOCATE_LD_H */ +diff --git a/sysdeps/riscv/ldsodefs.h b/sysdeps/riscv/ldsodefs.h +index 0c696714a7a93cff..8947ffe4b5026a2e 100644 +--- a/sysdeps/riscv/ldsodefs.h ++++ b/sysdeps/riscv/ldsodefs.h +@@ -38,11 +38,6 @@ struct La_riscv_retval; + struct La_riscv_retval *, \ + const char *); + +-/* Although the RISC-V ABI does not specify that the dynamic section has +- to be read-only, it needs to be kept for ABI compatibility. */ +- +-#define DL_RO_DYN_SECTION 1 +- + #include_next + + #endif diff --git a/SOURCES/glibc-upstream-2.34-42.patch b/SOURCES/glibc-upstream-2.34-42.patch new file mode 100644 index 0000000..51bc4fb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-42.patch @@ -0,0 +1,117 @@ +commit 5f36e5c70107ecb59281ef57f9f1c0e37ec3076d +Author: H.J. Lu +Date: Thu Sep 23 09:06:49 2021 -0700 + + ld.so: Initialize bootstrap_map.l_ld_readonly [BZ #28340] + + 1. Define DL_RO_DYN_SECTION to initalize bootstrap_map.l_ld_readonly + before calling elf_get_dynamic_info to get dynamic info in bootstrap_map, + 2. Define a single + + static inline bool + dl_relocate_ld (const struct link_map *l) + { + /* Don't relocate dynamic section if it is readonly */ + return !(l->l_ld_readonly || DL_RO_DYN_SECTION); + } + + This updates BZ #28340 fix. + + (cherry picked from commit 2ec99d8c42b2ff1a1231e4df462a0910a9b7fdef) + +diff --git a/elf/rtld.c b/elf/rtld.c +index 405166d62b34847c..d83ac1bdc40a6081 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -548,6 +548,7 @@ _dl_start (void *arg) + + /* Read our own dynamic section and fill in the info array. */ + bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); ++ bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION; + elf_get_dynamic_info (&bootstrap_map); + + #if NO_TLS_OFFSET != 0 +diff --git a/sysdeps/generic/dl-relocate-ld.h b/sysdeps/generic/dl-relocate-ld.h +index 5fae206db9941e97..cfb86c2d6a2394c1 100644 +--- a/sysdeps/generic/dl-relocate-ld.h ++++ b/sysdeps/generic/dl-relocate-ld.h +@@ -19,14 +19,7 @@ + #ifndef _DL_RELOCATE_LD_H + #define _DL_RELOCATE_LD_H + +-/* Return true if dynamic section in the shared library L should be +- relocated. */ +- +-static inline bool +-dl_relocate_ld (const struct link_map *l) +-{ +- /* Don't relocate dynamic section if it is readonly */ +- return !l->l_ld_readonly; +-} ++/* The dynamic section is writable. */ ++#define DL_RO_DYN_SECTION 0 + + #endif /* _DL_RELOCATE_LD_H */ +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index ed10953f34b96c49..fcbbf6974827cdf1 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -69,6 +69,16 @@ __BEGIN_DECLS + `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ + #define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) + ++/* Return true if dynamic section in the shared library L should be ++ relocated. */ ++ ++static inline bool ++dl_relocate_ld (const struct link_map *l) ++{ ++ /* Don't relocate dynamic section if it is readonly */ ++ return !(l->l_ld_readonly || DL_RO_DYN_SECTION); ++} ++ + /* All references to the value of l_info[DT_PLTGOT], + l_info[DT_STRTAB], l_info[DT_SYMTAB], l_info[DT_RELA], + l_info[DT_REL], l_info[DT_JMPREL], and l_info[VERSYMIDX (DT_VERSYM)] +diff --git a/sysdeps/mips/dl-relocate-ld.h b/sysdeps/mips/dl-relocate-ld.h +index 0c18d9a567cad54f..376ad75dd1695fe3 100644 +--- a/sysdeps/mips/dl-relocate-ld.h ++++ b/sysdeps/mips/dl-relocate-ld.h +@@ -19,14 +19,7 @@ + #ifndef _DL_RELOCATE_LD_H + #define _DL_RELOCATE_LD_H + +-/* Return true if dynamic section in the shared library L should be +- relocated. */ +- +-static inline bool +-dl_relocate_ld (const struct link_map *l) +-{ +- /* Never relocate dynamic section. */ +- return false; +-} ++/* The dynamic section is readonly. */ ++#define DL_RO_DYN_SECTION 1 + + #endif /* _DL_RELOCATE_LD_H */ +diff --git a/sysdeps/riscv/dl-relocate-ld.h b/sysdeps/riscv/dl-relocate-ld.h +index 10327454b17a7097..2ab2b8ac6c09af82 100644 +--- a/sysdeps/riscv/dl-relocate-ld.h ++++ b/sysdeps/riscv/dl-relocate-ld.h +@@ -19,14 +19,7 @@ + #ifndef _DL_RELOCATE_LD_H + #define _DL_RELOCATE_LD_H + +-/* Return true if dynamic section in the shared library L should be +- relocated. */ +- +-static inline bool +-dl_relocate_ld (const struct link_map *l) +-{ +- /* Never relocate dynamic section for ABI compatibility. */ +- return false; +-} ++/* The dynamic section is readonly for ABI compatibility. */ ++#define DL_RO_DYN_SECTION 1 + + #endif /* _DL_RELOCATE_LD_H */ diff --git a/SOURCES/glibc-upstream-2.34-43.patch b/SOURCES/glibc-upstream-2.34-43.patch new file mode 100644 index 0000000..9c5ea97 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-43.patch @@ -0,0 +1,30 @@ +commit 6548a9bdba95b3e1fcdbd85445342467e4b0cd4f +Author: H.J. Lu +Date: Fri Sep 24 08:56:42 2021 -0700 + + Avoid warning: overriding recipe for .../tst-ro-dynamic-mod.so + + Add tst-ro-dynamic-mod to modules-names-nobuild to avoid + + ../Makerules:767: warning: ignoring old recipe for target '.../elf/tst-ro-dynamic-mod.so' + + This updates BZ #28340 fix. + + (cherry picked from commit 15e6d6785ac2935bb963506b47a37b3d1f728952) + +diff --git a/elf/Makefile b/elf/Makefile +index de854b4d1a815bd3..118d579c42c38110 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -399,8 +399,9 @@ endif + modules-execstack-yes = tst-execstack-mod + extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) + +-# filtmod1.so, tst-big-note-lib.so have special rules. +-modules-names-nobuild := filtmod1 tst-big-note-lib ++# filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special ++# rules. ++modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod + + tests += $(tests-static) + diff --git a/SOURCES/glibc-upstream-2.34-44.patch b/SOURCES/glibc-upstream-2.34-44.patch new file mode 100644 index 0000000..547da51 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-44.patch @@ -0,0 +1,177 @@ +commit f411207a833d0c49578ebe7062aee3660813ed5f +Author: Nikita Popov +Date: Tue Nov 2 13:21:42 2021 +0500 + + gconv: Do not emit spurious NUL character in ISO-2022-JP-3 (bug 28524) + + Bugfix 27256 has introduced another issue: + In conversion from ISO-2022-JP-3 encoding, it is possible + to force iconv to emit extra NUL character on internal state reset. + To do this, it is sufficient to feed iconv with escape sequence + which switches active character set. + The simplified check 'data->__statep->__count != ASCII_set' + introduced by the aforementioned bugfix picks that case and + behaves as if '\0' character has been queued thus emitting it. + + To eliminate this issue, these steps are taken: + * Restore original condition + '(data->__statep->__count & ~7) != ASCII_set'. + It is necessary since bits 0-2 may contain + number of buffered input characters. + * Check that queued character is not NUL. + Similar step is taken for main conversion loop. + + Bundled test case follows following logic: + * Try to convert ISO-2022-JP-3 escape sequence + switching active character set + * Reset internal state by providing NULL as input buffer + * Ensure that nothing has been converted. + + Signed-off-by: Nikita Popov + (cherry picked from commit ff012870b2c02a62598c04daa1e54632e020fd7d) + +diff --git a/iconvdata/Makefile b/iconvdata/Makefile +index c216f959df1413f8..d5507a048c6a6508 100644 +--- a/iconvdata/Makefile ++++ b/iconvdata/Makefile +@@ -1,4 +1,5 @@ + # Copyright (C) 1997-2021 Free Software Foundation, Inc. ++# Copyright (C) The GNU Toolchain Authors. + # This file is part of the GNU C Library. + + # The GNU C Library is free software; you can redistribute it and/or +@@ -74,7 +75,7 @@ ifeq (yes,$(build-shared)) + tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ + tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \ + bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \ +- bug-iconv13 bug-iconv14 ++ bug-iconv13 bug-iconv14 bug-iconv15 + ifeq ($(have-thread-library),yes) + tests += bug-iconv3 + endif +@@ -327,6 +328,8 @@ $(objpfx)bug-iconv12.out: $(addprefix $(objpfx), $(gconv-modules)) \ + $(addprefix $(objpfx),$(modules.so)) + $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \ + $(addprefix $(objpfx),$(modules.so)) ++$(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \ ++ $(addprefix $(objpfx),$(modules.so)) + + $(objpfx)iconv-test.out: run-iconv-test.sh \ + $(addprefix $(objpfx), $(gconv-modules)) \ +diff --git a/iconvdata/bug-iconv15.c b/iconvdata/bug-iconv15.c +new file mode 100644 +index 0000000000000000..cc04bd0313a68786 +--- /dev/null ++++ b/iconvdata/bug-iconv15.c +@@ -0,0 +1,60 @@ ++/* Bug 28524: Conversion from ISO-2022-JP-3 with iconv ++ may emit spurious NUL character on state reset. ++ Copyright (C) The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ char in[] = "\x1b(I"; ++ char *inbuf = in; ++ size_t inleft = sizeof (in) - 1; ++ char out[1]; ++ char *outbuf = out; ++ size_t outleft = sizeof (out); ++ iconv_t cd; ++ ++ cd = iconv_open ("UTF8", "ISO-2022-JP-3"); ++ TEST_VERIFY_EXIT (cd != (iconv_t) -1); ++ ++ /* First call to iconv should alter internal state. ++ Now, JISX0201_Kana_set is selected and ++ state value != ASCII_set. */ ++ TEST_VERIFY (iconv (cd, &inbuf, &inleft, &outbuf, &outleft) != (size_t) -1); ++ ++ /* No bytes should have been added to ++ the output buffer at this point. */ ++ TEST_VERIFY (outbuf == out); ++ TEST_VERIFY (outleft == sizeof (out)); ++ ++ /* Second call shall emit spurious NUL character in unpatched glibc. */ ++ TEST_VERIFY (iconv (cd, NULL, NULL, &outbuf, &outleft) != (size_t) -1); ++ ++ /* No characters are expected to be produced. */ ++ TEST_VERIFY (outbuf == out); ++ TEST_VERIFY (outleft == sizeof (out)); ++ ++ TEST_VERIFY_EXIT (iconv_close (cd) != -1); ++ ++ return 0; ++} ++ ++#include +diff --git a/iconvdata/iso-2022-jp-3.c b/iconvdata/iso-2022-jp-3.c +index c8ba88cdc9fe9200..5fc0c0f7397935fe 100644 +--- a/iconvdata/iso-2022-jp-3.c ++++ b/iconvdata/iso-2022-jp-3.c +@@ -1,5 +1,6 @@ + /* Conversion module for ISO-2022-JP-3. + Copyright (C) 1998-2021 Free Software Foundation, Inc. ++ Copyright (C) The GNU Toolchain Authors. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1998, + and Bruno Haible , 2002. +@@ -81,20 +82,31 @@ enum + the output state to the initial state. This has to be done during the + flushing. */ + #define EMIT_SHIFT_TO_INIT \ +- if (data->__statep->__count != ASCII_set) \ ++ if ((data->__statep->__count & ~7) != ASCII_set) \ + { \ + if (FROM_DIRECTION) \ + { \ +- if (__glibc_likely (outbuf + 4 <= outend)) \ ++ uint32_t ch = data->__statep->__count >> 6; \ ++ \ ++ if (__glibc_unlikely (ch != 0)) \ + { \ +- /* Write out the last character. */ \ +- *((uint32_t *) outbuf) = data->__statep->__count >> 6; \ +- outbuf += sizeof (uint32_t); \ +- data->__statep->__count = ASCII_set; \ ++ if (__glibc_likely (outbuf + 4 <= outend)) \ ++ { \ ++ /* Write out the last character. */ \ ++ put32u (outbuf, ch); \ ++ outbuf += 4; \ ++ data->__statep->__count &= 7; \ ++ data->__statep->__count |= ASCII_set; \ ++ } \ ++ else \ ++ /* We don't have enough room in the output buffer. */ \ ++ status = __GCONV_FULL_OUTPUT; \ + } \ + else \ +- /* We don't have enough room in the output buffer. */ \ +- status = __GCONV_FULL_OUTPUT; \ ++ { \ ++ data->__statep->__count &= 7; \ ++ data->__statep->__count |= ASCII_set; \ ++ } \ + } \ + else \ + { \ diff --git a/SOURCES/glibc-upstream-2.34-45.patch b/SOURCES/glibc-upstream-2.34-45.patch new file mode 100644 index 0000000..b2c69d5 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-45.patch @@ -0,0 +1,68 @@ +commit cf8c6a634c0a04a9f5d198ef05310f85f7338839 +Author: Florian Weimer +Date: Fri Nov 5 17:01:24 2021 +0100 + + elf: Earlier missing dynamic segment check in _dl_map_object_from_fd + + Separated debuginfo files have PT_DYNAMIC with p_filesz == 0. We + need to check for that before the _dl_map_segments call because + that could attempt to write to mappings that extend beyond the end + of the file, resulting in SIGBUS. + + Reviewed-by: H.J. Lu + (cherry picked from commit ea32ec354c65ddad11b82ca9d057010df13a9cea) + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 4445c28ef3fb4a7e..0976977fbdf21902 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1130,6 +1130,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + struct loadcmd loadcmds[l->l_phnum]; + size_t nloadcmds = 0; + bool has_holes = false; ++ bool empty_dynamic = false; + + /* The struct is initialized to zero so this is not necessary: + l->l_ld = 0; +@@ -1142,7 +1143,9 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + segments are mapped in. We record the addresses it says + verbatim, and later correct for the run-time load address. */ + case PT_DYNAMIC: +- if (ph->p_filesz) ++ if (ph->p_filesz == 0) ++ empty_dynamic = true; /* Usually separate debuginfo. */ ++ else + { + /* Debuginfo only files from "objcopy --only-keep-debug" + contain a PT_DYNAMIC segment with p_filesz == 0. Skip +@@ -1265,6 +1268,13 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + goto lose; + } + ++ /* This check recognizes most separate debuginfo files. */ ++ if (__glibc_unlikely ((l->l_ld == 0 && type == ET_DYN) || empty_dynamic)) ++ { ++ errstring = N_("object file has no dynamic section"); ++ goto lose; ++ } ++ + /* Length of the sections to be loaded. */ + maplength = loadcmds[nloadcmds - 1].allocend - loadcmds[0].mapstart; + +@@ -1282,15 +1292,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + } + } + +- if (l->l_ld == 0) +- { +- if (__glibc_unlikely (type == ET_DYN)) +- { +- errstring = N_("object file has no dynamic section"); +- goto lose; +- } +- } +- else ++ if (l->l_ld != 0) + l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr); + + elf_get_dynamic_info (l); diff --git a/SOURCES/glibc-upstream-2.34-46.patch b/SOURCES/glibc-upstream-2.34-46.patch new file mode 100644 index 0000000..fa16e48 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-46.patch @@ -0,0 +1,41 @@ +commit a4f3bc23461e3f9f6053e827715984ba0d2e589a +Author: Florian Weimer +Date: Wed Nov 10 15:21:37 2021 +0100 + + s390: Use long branches across object boundaries (jgh instead of jh) + + Depending on the layout chosen by the linker, the 16-bit displacement + of the jh instruction is insufficient to reach the target label. + + Analysis of the linker failure was carried out by Nick Clifton. + + Reviewed-by: Carlos O'Donell + Reviewed-by: Stefan Liebler + (cherry picked from commit 98966749f2b418825ff2ea496a0ee89fe63d2cc8) + +diff --git a/sysdeps/s390/memmem-arch13.S b/sysdeps/s390/memmem-arch13.S +index c5c8d8c97efb3b9f..58df8cdb142a6b25 100644 +--- a/sysdeps/s390/memmem-arch13.S ++++ b/sysdeps/s390/memmem-arch13.S +@@ -41,7 +41,7 @@ ENTRY(MEMMEM_ARCH13) + # error The arch13 variant of memmem needs the z13 variant of memmem! + # endif + clgfi %r5,9 +- jh MEMMEM_Z13 ++ jgh MEMMEM_Z13 + + aghik %r0,%r5,-1 /* vll needs highest index. */ + bc 4,0(%r14) /* cc==1: return if needle-len == 0. */ +diff --git a/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S +index c7183e627c9fa986..222a6de91abb3fc6 100644 +--- a/sysdeps/s390/strstr-arch13.S ++++ b/sysdeps/s390/strstr-arch13.S +@@ -49,7 +49,7 @@ ENTRY(STRSTR_ARCH13) + # error The arch13 variant of strstr needs the z13 variant of strstr! + # endif + clgfi %r4,9 +- jh STRSTR_Z13 ++ jgh 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 diff --git a/SOURCES/glibc-upstream-2.34-47.patch b/SOURCES/glibc-upstream-2.34-47.patch new file mode 100644 index 0000000..f23193a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-47.patch @@ -0,0 +1,102 @@ +commit bfe68fe3c475fe34bed4e017d6e63196c305c934 +Author: Florian Weimer +Date: Wed Nov 24 08:59:54 2021 +0100 + + nptl: Do not set signal mask on second setjmp return [BZ #28607] + + __libc_signal_restore_set was in the wrong place: It also ran + when setjmp returned the second time (after pthread_exit or + pthread_cancel). This is observable with blocked pending + signals during thread exit. + + Fixes commit b3cae39dcbfa2432b3f3aa28854d8ac57f0de1b8 + ("nptl: Start new threads with all signals blocked [BZ #25098]"). + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit e186fc5a31e46f2cbf5ea1a75223b4412907f3d8) + +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index bc213f0bc4e948bd..3db0c9fdf40ae2bf 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -407,8 +407,6 @@ start_thread (void *arg) + unwind_buf.priv.data.prev = NULL; + unwind_buf.priv.data.cleanup = NULL; + +- __libc_signal_restore_set (&pd->sigmask); +- + /* Allow setxid from now onwards. */ + if (__glibc_unlikely (atomic_exchange_acq (&pd->setxid_futex, 0) == -2)) + futex_wake (&pd->setxid_futex, 1, FUTEX_PRIVATE); +@@ -418,6 +416,8 @@ start_thread (void *arg) + /* Store the new cleanup handler info. */ + THREAD_SETMEM (pd, cleanup_jmp_buf, &unwind_buf); + ++ __libc_signal_restore_set (&pd->sigmask); ++ + LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg); + + /* Run the code the user provided. */ +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index df8943f4860a39d8..c65710169697ad95 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -118,6 +118,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-unload \ + tst-unwind-thread \ + tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ ++ tst-pthread-exit-signal \ + tst-pthread-setuid-loop \ + tst-pthread_cancel-exited \ + tst-pthread_cancel-select-loop \ +diff --git a/sysdeps/pthread/tst-pthread-exit-signal.c b/sysdeps/pthread/tst-pthread-exit-signal.c +new file mode 100644 +index 0000000000000000..b4526fe663671068 +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread-exit-signal.c +@@ -0,0 +1,45 @@ ++/* Test that pending signals are not delivered on thread exit (bug 28607). ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Due to bug 28607, pthread_kill (or pthread_cancel) restored the ++ signal mask during during thread exit, triggering the delivery of a ++ blocked pending signal (SIGUSR1 in this test). */ ++ ++#include ++#include ++ ++static void * ++threadfunc (void *closure) ++{ ++ sigset_t sigmask; ++ sigfillset (&sigmask); ++ xpthread_sigmask (SIG_SETMASK, &sigmask, NULL); ++ xpthread_kill (pthread_self (), SIGUSR1); ++ pthread_exit (NULL); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ pthread_t thr = xpthread_create (NULL, threadfunc, NULL); ++ xpthread_join (thr); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-48.patch b/SOURCES/glibc-upstream-2.34-48.patch new file mode 100644 index 0000000..31f08db --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-48.patch @@ -0,0 +1,97 @@ +commit f988b7f228851370d1faa1e8f28d02f4b4e6dc46 +Author: Adhemerval Zanella +Date: Thu Nov 25 09:12:00 2021 -0300 + + linux: Use /proc/stat fallback for __get_nprocs_conf (BZ #28624) + + The /proc/statm fallback was removed by f13fb81ad3159 if sysfs is + not available, reinstate it. + + Checked on x86_64-linux-gnu. + (cherry-picked from commit 137ed5ac440a4d3cf4178ce97f349b349a9c2c66) + +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index d70ed9586950615c..7fc6521942e87293 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -108,6 +108,37 @@ next_line (int fd, char *const buffer, char **cp, char **re, + return res == *re ? NULL : res; + } + ++static int ++get_nproc_stat (char *buffer, size_t buffer_size) ++{ ++ char *buffer_end = buffer + buffer_size; ++ char *cp = buffer_end; ++ char *re = buffer_end; ++ ++ /* Default to an SMP system in case we cannot obtain an accurate ++ number. */ ++ int result = 2; ++ ++ const int flags = O_RDONLY | O_CLOEXEC; ++ int fd = __open_nocancel ("/proc/stat", flags); ++ if (fd != -1) ++ { ++ result = 0; ++ ++ char *l; ++ while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL) ++ /* The current format of /proc/stat has all the cpu* entries ++ at the front. We assume here that stays this way. */ ++ if (strncmp (l, "cpu", 3) != 0) ++ break; ++ else if (isdigit (l[3])) ++ ++result; ++ ++ __close_nocancel_nostatus (fd); ++ } ++ ++ return result; ++} + + int + __get_nprocs (void) +@@ -163,30 +194,7 @@ __get_nprocs (void) + return result; + } + +- cp = buffer_end; +- re = buffer_end; +- +- /* Default to an SMP system in case we cannot obtain an accurate +- number. */ +- result = 2; +- +- fd = __open_nocancel ("/proc/stat", flags); +- if (fd != -1) +- { +- result = 0; +- +- while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL) +- /* The current format of /proc/stat has all the cpu* entries +- at the front. We assume here that stays this way. */ +- if (strncmp (l, "cpu", 3) != 0) +- break; +- else if (isdigit (l[3])) +- ++result; +- +- __close_nocancel_nostatus (fd); +- } +- +- return result; ++ return get_nproc_stat (buffer, buffer_size); + } + libc_hidden_def (__get_nprocs) + weak_alias (__get_nprocs, get_nprocs) +@@ -220,7 +228,9 @@ __get_nprocs_conf (void) + return count; + } + +- return 1; ++ enum { buffer_size = 1024 }; ++ char buffer[buffer_size]; ++ return get_nproc_stat (buffer, buffer_size); + } + libc_hidden_def (__get_nprocs_conf) + weak_alias (__get_nprocs_conf, get_nprocs_conf) diff --git a/SOURCES/glibc-upstream-2.34-49.patch b/SOURCES/glibc-upstream-2.34-49.patch new file mode 100644 index 0000000..e4cd827 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-49.patch @@ -0,0 +1,101 @@ +commit 387bff63dc2dccd62b09aa26dccf8cdc5f3c985c +Author: Matheus Castanho +Date: Tue Oct 26 10:44:59 2021 -0300 + + powerpc64[le]: Fix CFI and LR save address for asm syscalls [BZ #28532] + + Syscalls based on the assembly templates are missing CFI for r31, which gets + clobbered when scv is used, and info for LR is inaccurate, placed in the wrong + LOC and not using the proper offset. LR was also being saved to the callee's + frame, while the ABI mandates it to be saved to the caller's frame. These are + fixed by this commit. + + After this change: + + $ readelf -wF libc.so.6 | grep 0004b9d4.. -A 7 && objdump --disassemble=kill libc.so.6 + 00004a48 0000000000000020 00004a4c FDE cie=00000000 pc=000000000004b9d4..000000000004ba3c + LOC CFA r31 ra + 000000000004b9d4 r1+0 u u + 000000000004b9e4 r1+48 u u + 000000000004b9e8 r1+48 c-16 u + 000000000004b9fc r1+48 c-16 c+16 + 000000000004ba08 r1+48 c-16 + 000000000004ba18 r1+48 u + 000000000004ba1c r1+0 u + + libc.so.6: file format elf64-powerpcle + + Disassembly of section .text: + + 000000000004b9d4 : + 4b9d4: 1f 00 4c 3c addis r2,r12,31 + 4b9d8: 2c c3 42 38 addi r2,r2,-15572 + 4b9dc: 25 00 00 38 li r0,37 + 4b9e0: d1 ff 21 f8 stdu r1,-48(r1) + 4b9e4: 20 00 e1 fb std r31,32(r1) + 4b9e8: 98 8f ed eb ld r31,-28776(r13) + 4b9ec: 10 00 ff 77 andis. r31,r31,16 + 4b9f0: 1c 00 82 41 beq 4ba0c + 4b9f4: a6 02 28 7d mflr r9 + 4b9f8: 40 00 21 f9 std r9,64(r1) + 4b9fc: 01 00 00 44 scv 0 + 4ba00: 40 00 21 e9 ld r9,64(r1) + 4ba04: a6 03 28 7d mtlr r9 + 4ba08: 08 00 00 48 b 4ba10 + 4ba0c: 02 00 00 44 sc + 4ba10: 00 00 bf 2e cmpdi cr5,r31,0 + 4ba14: 20 00 e1 eb ld r31,32(r1) + 4ba18: 30 00 21 38 addi r1,r1,48 + 4ba1c: 18 00 96 41 beq cr5,4ba34 + 4ba20: 01 f0 20 39 li r9,-4095 + 4ba24: 40 48 23 7c cmpld r3,r9 + 4ba28: 20 00 e0 4d bltlr+ + 4ba2c: d0 00 63 7c neg r3,r3 + 4ba30: 08 00 00 48 b 4ba38 + 4ba34: 20 00 e3 4c bnslr+ + 4ba38: c8 32 fe 4b b 2ed00 <__syscall_error> + ... + 4ba44: 40 20 0c 00 .long 0xc2040 + 4ba48: 68 00 00 00 .long 0x68 + 4ba4c: 06 00 5f 5f rlwnm r31,r26,r0,0,3 + 4ba50: 6b 69 6c 6c xoris r12,r3,26987 + + (cherry picked from commit d120fb9941be1fb1934f0b50c6ad64e4c5e404fb) + +diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h +index 589f7c8d18814ee9..cfcfa69f91f1773d 100644 +--- a/sysdeps/powerpc/powerpc64/sysdep.h ++++ b/sysdeps/powerpc/powerpc64/sysdep.h +@@ -275,12 +275,14 @@ LT_LABELSUFFIX(name,_name_end): ; \ + /* Allocate frame and save register */ + #define NVOLREG_SAVE \ + stdu r1,-SCV_FRAME_SIZE(r1); \ ++ cfi_adjust_cfa_offset(SCV_FRAME_SIZE); \ + std r31,SCV_FRAME_NVOLREG_SAVE(r1); \ +- cfi_adjust_cfa_offset(SCV_FRAME_SIZE); ++ cfi_rel_offset(r31,SCV_FRAME_NVOLREG_SAVE); + + /* Restore register and destroy frame */ + #define NVOLREG_RESTORE \ + ld r31,SCV_FRAME_NVOLREG_SAVE(r1); \ ++ cfi_restore(r31); \ + addi r1,r1,SCV_FRAME_SIZE; \ + cfi_adjust_cfa_offset(-SCV_FRAME_SIZE); + +@@ -331,13 +333,13 @@ LT_LABELSUFFIX(name,_name_end): ; \ + + #define DO_CALL_SCV \ + mflr r9; \ +- std r9,FRAME_LR_SAVE(r1); \ +- cfi_offset(lr,FRAME_LR_SAVE); \ ++ std r9,SCV_FRAME_SIZE+FRAME_LR_SAVE(r1); \ ++ cfi_rel_offset(lr,SCV_FRAME_SIZE+FRAME_LR_SAVE); \ + .machine "push"; \ + .machine "power9"; \ + scv 0; \ + .machine "pop"; \ +- ld r9,FRAME_LR_SAVE(r1); \ ++ ld r9,SCV_FRAME_SIZE+FRAME_LR_SAVE(r1); \ + mtlr r9; \ + cfi_restore(lr); + diff --git a/SOURCES/glibc-upstream-2.34-5.patch b/SOURCES/glibc-upstream-2.34-5.patch new file mode 100644 index 0000000..fe8b853 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-5.patch @@ -0,0 +1,22 @@ +commit 9995d0588f4f9adc68419224d2b3698e2ca4f77e +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:10:29 2021 +0530 + + iconv_charmap: Close output file when done + + Reviewed-by: Arjun Shankar + (cherry picked from commit 1e0e6d656db9dfa12ef7eb67976385d3deb0d4ff) + +diff --git a/iconv/iconv_charmap.c b/iconv/iconv_charmap.c +index e2d53fee3cbfbb7a..a8b6b56124909f6c 100644 +--- a/iconv/iconv_charmap.c ++++ b/iconv/iconv_charmap.c +@@ -234,6 +234,8 @@ charmap_conversion (const char *from_code, struct charmap_t *from_charmap, + while (++remaining < argc); + + /* All done. */ ++ if (output != stdout) ++ fclose (output); + free_table (cvtbl); + return status; + } diff --git a/SOURCES/glibc-upstream-2.34-50.patch b/SOURCES/glibc-upstream-2.34-50.patch new file mode 100644 index 0000000..91a274f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-50.patch @@ -0,0 +1,63 @@ +commit e9f81c261a2ca74d31d07ff9c8e780ac8a25993c +Author: Florian Weimer +Date: Fri Dec 10 05:14:24 2021 +0100 + + nptl: Add one more barrier to nptl/tst-create1 + + Without the bar_ctor_finish barrier, it was possible that thread2 + re-locked user_lock before ctor had a chance to lock it. ctor then + blocked in its locking operation, xdlopen from the main thread + did not return, and thread2 was stuck waiting in bar_dtor: + + thread 1: started. + thread 2: started. + thread 2: locked user_lock. + constructor started: 0. + thread 1: in ctor: started. + thread 3: started. + thread 3: done. + thread 2: unlocked user_lock. + thread 2: locked user_lock. + + Fixes the test in commit 83b5323261bb72313bffcf37476c1b8f0847c736 + ("elf: Avoid deadlock between pthread_create and ctors [BZ #28357]"). + + Reviewed-by: Szabolcs Nagy + (cherry picked from commit 5cc338565479a620244c2f8ff35956629c4dbf81) + +diff --git a/sysdeps/pthread/tst-create1.c b/sysdeps/pthread/tst-create1.c +index 932586c30990d1d4..763ded8d7956f943 100644 +--- a/sysdeps/pthread/tst-create1.c ++++ b/sysdeps/pthread/tst-create1.c +@@ -33,6 +33,7 @@ thread 2: lock(user_lock) -> pthread_create + */ + + static pthread_barrier_t bar_ctor; ++static pthread_barrier_t bar_ctor_finish; + static pthread_barrier_t bar_dtor; + static pthread_mutex_t user_lock = PTHREAD_MUTEX_INITIALIZER; + +@@ -46,6 +47,7 @@ ctor (void) + xpthread_mutex_unlock (&user_lock); + dprintf (1, "thread 1: in ctor: unlocked user_lock.\n"); + dprintf (1, "thread 1: in ctor: done.\n"); ++ xpthread_barrier_wait (&bar_ctor_finish); + } + + void +@@ -81,6 +83,7 @@ thread2 (void *a) + xpthread_mutex_unlock (&user_lock); + dprintf (1, "thread 2: unlocked user_lock.\n"); + xpthread_join (t3); ++ xpthread_barrier_wait (&bar_ctor_finish); + + xpthread_mutex_lock (&user_lock); + dprintf (1, "thread 2: locked user_lock.\n"); +@@ -99,6 +102,7 @@ thread1 (void) + { + dprintf (1, "thread 1: started.\n"); + xpthread_barrier_init (&bar_ctor, NULL, 2); ++ xpthread_barrier_init (&bar_ctor_finish, NULL, 2); + xpthread_barrier_init (&bar_dtor, NULL, 2); + pthread_t t2 = xpthread_create (0, thread2, 0); + void *p = xdlopen ("tst-create1mod.so", RTLD_NOW | RTLD_GLOBAL); diff --git a/SOURCES/glibc-upstream-2.34-51.patch b/SOURCES/glibc-upstream-2.34-51.patch new file mode 100644 index 0000000..2b179be --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-51.patch @@ -0,0 +1,191 @@ +commit 0dcbf4c8705309af8c8c1620491c60539901a3b0 +Author: Joseph Myers +Date: Fri Sep 17 13:12:10 2021 +0000 + + Run conform/ tests using newly built libc + + Although the conform/ header tests are built using the headers of the + glibc under test, the execution tests from conformtest (a few tests of + the values of macros evaluating to string constants) are linked and + run with system libc, not the newly built libc. + + Apart from preventing testing in cross environments, this can be a + problem even for native testing. Specifically, it can be useful to do + native testing when building with a cross compiler that links with a + libc that is not the system libc; for example, on x86_64, you can test + all three ABIs that way if the kernel support is present, even if the + host OS lacks 32-bit or x32 libraries or they are older than the + libraries in the sysroot used by the compiler used to build glibc. + This works for almost all tests, but not for these conformtest tests. + + Arrange for conformtest to link and run test programs similarly to + other tests, with consequent refactoring of various variables in + Makeconfig to allow passing relevant parts of the link-time command + lines down to conformtest. In general, the parts of the link command + involving $@ or $^ are separated out from the parts that should be + passed to conformtest (the variables passed to conformtest still + involve various variables whose names involve $(@F), but those + variables simply won't be defined for the conformtest makefile rules + and I think their presence there is harmless). + + This is also most of the support that would be needed to allow running + those tests of string constants for cross testing when test-wrapper is + defined. That will also need changes to where conformtest.py puts the + test executables, so it puts them in the main object directory + (expected to be shared with a test system in cross testing) rather + than /tmp (not expected to be shared) as at present. + + Tested for x86_64. + + (cherry picked from commit f3eef963902d0f54f68cffc74f79b97f4d6154b7) + +diff --git a/Makeconfig b/Makeconfig +index 68663d984e6a1264..2fa0884b4eee5e53 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -412,12 +412,13 @@ link-extra-libs-tests = $(libsupport) + + # Command for linking PIE programs with the C library. + ifndef +link-pie +-+link-pie-before-libc = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \ +- -Wl,-O1 -nostdlib -nostartfiles -o $@ \ +++link-pie-before-inputs = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \ ++ -Wl,-O1 -nostdlib -nostartfiles \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)S$(start-installed-name)) \ +- $(+preinit) $(+prectorS) \ ++ $(+preinit) $(+prectorS) +++link-pie-before-libc = -o $@ $(+link-pie-before-inputs) \ + $(filter-out $(addprefix $(csu-objpfx),start.o \ + S$(start-installed-name))\ + $(+preinit) $(link-extra-libs) \ +@@ -442,11 +443,12 @@ endef + endif + # Command for statically linking programs with the C library. + ifndef +link-static +-+link-static-before-libc = -nostdlib -nostartfiles -static -o $@ \ +++link-static-before-inputs = -nostdlib -nostartfiles -static \ + $(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)) \ +- $(+preinit) $(+prectorT) \ ++ $(+preinit) $(+prectorT) +++link-static-before-libc = -o $@ $(+link-static-before-inputs) \ + $(filter-out $(addprefix $(csu-objpfx),start.o \ + $(start-installed-name))\ + $(+preinit) $(link-extra-libs-static) \ +@@ -473,13 +475,16 @@ endif + ifeq (yes,$(build-pie-default)) + +link = $(+link-pie) + +link-tests = $(+link-pie-tests) +++link-tests-before-inputs = $(+link-pie-before-inputs) $(rtld-tests-LDFLAGS) +++link-tests-after-inputs = $(link-libc-tests) $(+link-pie-after-libc) + +link-printers-tests = $(+link-pie-printers-tests) + else # not build-pie-default +-+link-before-libc = -nostdlib -nostartfiles -o $@ \ +++link-before-inputs = -nostdlib -nostartfiles \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \ +- $(+preinit) $(+prector) \ ++ $(+preinit) $(+prector) +++link-before-libc = -o $@ $(+link-before-inputs) \ + $(filter-out $(addprefix $(csu-objpfx),start.o \ + $(start-installed-name))\ + $(+preinit) $(link-extra-libs) \ +@@ -491,6 +496,8 @@ $(CC) $(link-libc-rpath-link) $(+link-before-libc) $(rtld-LDFLAGS) \ + $(link-extra-flags) $(link-libc) $(+link-after-libc) + $(call after-link,$@) + endef +++link-tests-before-inputs = $(+link-before-inputs) $(rtld-tests-LDFLAGS) +++link-tests-after-inputs = $(link-libc-tests) $(+link-after-libc) + define +link-tests + $(CC) $(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ + $(+link-after-libc) +@@ -505,6 +512,8 @@ endif # build-pie-default + else # build-static + +link = $(+link-static) + +link-tests = $(+link-static-tests) +++link-tests-before-inputs = $(+link-static-before-inputs) +++link-tests-after-inputs = $(link-libc-static-tests) $(+link-static-after-libc) + +link-printers-tests = $(+link-static-tests) + endif # build-shared + endif # +link +diff --git a/conform/Makefile b/conform/Makefile +index c64a83a905b991cc..296db818f0a72253 100644 +--- a/conform/Makefile ++++ b/conform/Makefile +@@ -176,6 +176,9 @@ $(conformtest-header-tests): $(objpfx)%/conform.out: \ + (set -e; std_hdr=$*; std=$${std_hdr%%/*}; hdr=$${std_hdr#*/}; \ + mkdir -p $(@D); \ + $(PYTHON) $< --cc='$(CC)' --flags='$(conformtest-cc-flags)' \ ++ --ldflags='$(+link-tests-before-inputs)' \ ++ --libs='$(+link-tests-after-inputs)' \ ++ --run-program-prefix='$(run-program-prefix)' \ + --standard=$$std --header=$$hdr $(conformtest-xfail) \ + $(conformtest-cross) \ + > $@ 2>&1); \ +diff --git a/conform/conformtest.py b/conform/conformtest.py +index f0405b71869831f9..4898e16c9fb96503 100644 +--- a/conform/conformtest.py ++++ b/conform/conformtest.py +@@ -381,12 +381,16 @@ class MacroStrTest(object): + class HeaderTests(object): + """The set of tests run for a header.""" + +- def __init__(self, header, standard, cc, flags, cross, xfail): ++ def __init__(self, header, standard, cc, flags, ldflags, libs, ++ run_program_prefix, cross, xfail): + """Initialize a HeaderTests object.""" + self.header = header + self.standard = standard + self.cc = cc + self.flags = flags ++ self.ldflags = ldflags ++ self.libs = libs ++ self.run_program_prefix = run_program_prefix + self.cross = cross + self.xfail_str = xfail + self.cflags_namespace = ('%s -fno-builtin %s -D_ISOMAC' +@@ -590,7 +594,8 @@ class HeaderTests(object): + exe_file = os.path.join(self.temp_dir, 'test') + with open(c_file, 'w') as c_file_out: + c_file_out.write('#include <%s>\n%s' % (self.header, text)) +- cmd = ('%s %s %s -o %s' % (self.cc, self.cflags, c_file, exe_file)) ++ cmd = ('%s %s %s %s %s -o %s' % (self.cc, self.cflags, self.ldflags, ++ c_file, self.libs, exe_file)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError: +@@ -600,7 +605,9 @@ class HeaderTests(object): + self.note_skip(name) + return + try: +- subprocess.check_call(exe_file, shell=True) ++ subprocess.check_call('%s %s' % (self.run_program_prefix, ++ exe_file), ++ shell=True) + except subprocess.CalledProcessError: + self.note_error(name, self.group_xfail) + return +@@ -719,12 +726,19 @@ def main(): + help='C compiler to use') + parser.add_argument('--flags', metavar='CFLAGS', + help='Compiler flags to use with CC') ++ parser.add_argument('--ldflags', metavar='LDFLAGS', ++ help='Compiler arguments for linking before inputs') ++ parser.add_argument('--libs', metavar='LIBS', ++ help='Compiler arguments for linking after inputs') ++ parser.add_argument('--run-program-prefix', metavar='RUN-PROGRAM-PREFIX', ++ help='Wrapper for running newly built program') + parser.add_argument('--cross', action='store_true', + help='Do not run compiled test programs') + parser.add_argument('--xfail', metavar='COND', + help='Name of condition for XFAILs') + args = parser.parse_args() + tests = HeaderTests(args.header, args.standard, args.cc, args.flags, ++ args.ldflags, args.libs, args.run_program_prefix, + args.cross, args.xfail) + tests.run() + diff --git a/SOURCES/glibc-upstream-2.34-52.patch b/SOURCES/glibc-upstream-2.34-52.patch new file mode 100644 index 0000000..10d9393 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-52.patch @@ -0,0 +1,37 @@ +commit 1fe4b8d6937139faa47410552d4e21b356810d67 +Author: Joseph Myers +Date: Fri Sep 17 19:24:14 2021 +0000 + + Use $(pie-default) with conformtest + + My glibc bot showed that my conformtest changes fail the build of the + conformtest execution tests for x86_64-linux-gnu-static-pie, because + linking the newly built object with the newly built libc and the + associated options normally used for linking requires it to be built + as PIE. Add $(pie-default) to the compiler command used so that PIE + options are used when required. + + There's a case for using the whole of $(CFLAGS-.o) (which includes + $(pie-default)), but that raises questions of any impact from using + optimization flags from CFLAGS in these tests. So for now just use + $(pie-default) as the key part of $(CFLAGS-.o) that's definitely + needed. + + Tested with build-many-glibcs.py for x86_64-linux-gnu-static-pie. + + (cherry picked from commit 885762aa31d75de8b9fea4c0e2e372b582d4c548) + +diff --git a/conform/Makefile b/conform/Makefile +index 296db818f0a72253..27ad98caf866879f 100644 +--- a/conform/Makefile ++++ b/conform/Makefile +@@ -175,7 +175,8 @@ $(conformtest-header-tests): $(objpfx)%/conform.out: \ + conformtest.py $(conformtest-headers-data) + (set -e; std_hdr=$*; std=$${std_hdr%%/*}; hdr=$${std_hdr#*/}; \ + mkdir -p $(@D); \ +- $(PYTHON) $< --cc='$(CC)' --flags='$(conformtest-cc-flags)' \ ++ $(PYTHON) $< --cc='$(CC) $(pie-default)' \ ++ --flags='$(conformtest-cc-flags)' \ + --ldflags='$(+link-tests-before-inputs)' \ + --libs='$(+link-tests-after-inputs)' \ + --run-program-prefix='$(run-program-prefix)' \ diff --git a/SOURCES/glibc-upstream-2.34-53.patch b/SOURCES/glibc-upstream-2.34-53.patch new file mode 100644 index 0000000..9e3453a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-53.patch @@ -0,0 +1,37 @@ +commit 06865865151579d1aa17d38110060a68b85c5d90 +Author: Stafford Horne +Date: Sat Sep 25 17:02:06 2021 +0900 + + pthread/tst-cancel28: Fix barrier re-init race condition + + When running this test on the OpenRISC port I am working on this test + fails with a timeout. The test passes when being straced or debugged. + Looking at the code there seems to be a race condition in that: + + 1 main thread: calls xpthread_cancel + 2 sub thread : receives cancel signal + 3 sub thread : cleanup routine waits on barrier + 4 main thread: re-inits barrier + 5 main thread: waits on barrier + + After getting to 5 the main thread and sub thread wait forever as the 2 + barriers are no longer the same. + + Removing the barrier re-init seems to fix this issue. Also, the barrier + does not need to be reinitialized as that is done by default. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 9874ca536b1d0662b1cea46af3ce09a4d42aeb32) + +diff --git a/sysdeps/pthread/tst-cancel28.c b/sysdeps/pthread/tst-cancel28.c +index 627cbc8160191c5c..9286c159b3be5e8a 100644 +--- a/sysdeps/pthread/tst-cancel28.c ++++ b/sysdeps/pthread/tst-cancel28.c +@@ -69,7 +69,6 @@ do_test (void) + + xpthread_cancel (timer_thread); + +- xpthread_barrier_init (&barrier, NULL, 2); + xpthread_barrier_wait (&barrier); + + return 0; diff --git a/SOURCES/glibc-upstream-2.34-54.patch b/SOURCES/glibc-upstream-2.34-54.patch new file mode 100644 index 0000000..fec14bf --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-54.patch @@ -0,0 +1,32 @@ +commit 7af07fe795f43e53d31be1c6f9adba7e05f87b0b +Author: Xi Ruoyao +Date: Thu Aug 12 20:31:59 2021 +0000 + + mips: align stack in clone [BZ #28223] + + The MIPS O32 ABI requires 4 byte aligned stack, and the MIPS N64 and N32 + ABI require 8 byte aligned stack. Previously if the caller passed an + unaligned stack to clone the the child misbehaved. + + Fixes bug 28223. + + (cherry picked from commit 1f51cd9a860ee45eee8a56fb2ba925267a2a7bfe) + +diff --git a/sysdeps/unix/sysv/linux/mips/clone.S b/sysdeps/unix/sysv/linux/mips/clone.S +index 71d9dba8bd9e8f9e..43a5ad3a400d9504 100644 +--- a/sysdeps/unix/sysv/linux/mips/clone.S ++++ b/sysdeps/unix/sysv/linux/mips/clone.S +@@ -55,6 +55,13 @@ NESTED(__clone,4*SZREG,sp) + .set at + #endif + ++ /* Align stack to 4/8 bytes per the ABI. */ ++#if _MIPS_SIM == _ABIO32 ++ li t0,-4 ++#else ++ li t0,-8 ++#endif ++ and a1,a1,t0 + + /* Sanity check arguments. */ + li v0,EINVAL diff --git a/SOURCES/glibc-upstream-2.34-55.patch b/SOURCES/glibc-upstream-2.34-55.patch new file mode 100644 index 0000000..9746705 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-55.patch @@ -0,0 +1,37 @@ +commit 4db172a54d43f9b7fd17e66fc44a34efb3cab1e1 +Author: Xi Ruoyao +Date: Fri Aug 13 16:01:14 2021 +0000 + + mips: increase stack alignment in clone to match the ABI + + In "mips: align stack in clone [BZ #28223]" + (commit 1f51cd9a860ee45eee8a56fb2ba925267a2a7bfe) I made a mistake: I + misbelieved one "word" was 2-byte and "doubleword" should be 4-byte. + But in MIPS ABI one "word" is defined 32-bit (4-byte), so "doubleword" is + 8-byte [1], and "quadword" is 16-byte [2]. + + [1]: "System V Application Binary Interface: MIPS(R) RISC Processor + Supplement, 3rd edition", page 3-31 + [2]: "MIPSpro(TM) 64-Bit Porting and Transition Guide", page 23 + + (cherry picked from commit 0f62fe053273ff6c62ac95c59b7687c964737b00) + +diff --git a/sysdeps/unix/sysv/linux/mips/clone.S b/sysdeps/unix/sysv/linux/mips/clone.S +index 43a5ad3a400d9504..fd71b5ca2eb86089 100644 +--- a/sysdeps/unix/sysv/linux/mips/clone.S ++++ b/sysdeps/unix/sysv/linux/mips/clone.S +@@ -55,11 +55,11 @@ NESTED(__clone,4*SZREG,sp) + .set at + #endif + +- /* Align stack to 4/8 bytes per the ABI. */ ++ /* Align stack to 8/16 bytes per the ABI. */ + #if _MIPS_SIM == _ABIO32 +- li t0,-4 +-#else + li t0,-8 ++#else ++ li t0,-16 + #endif + and a1,a1,t0 + diff --git a/SOURCES/glibc-upstream-2.34-56.patch b/SOURCES/glibc-upstream-2.34-56.patch new file mode 100644 index 0000000..ee2ad63 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-56.patch @@ -0,0 +1,65 @@ +commit 93aabf891e96e93f100081ee07989c23d7107d17 +Author: Florian Weimer +Date: Fri Dec 17 11:48:41 2021 +0100 + + arm: Guard ucontext _rtld_global_ro access by SHARED, not PIC macro + + Due to PIE-by-default, PIC is now defined in more cases. libc.a + does not have _rtld_global_ro, and statically linking setcontext + fails. SHARED is the right condition to use, so that libc.a + references _dl_hwcap instead of _rtld_global_ro. + + For static PIE support, the !SHARED case would still have to be made + PIC. This patch does not achieve that. + + Fixes commit 23645707f12f2dd9d80b51effb2d9618a7b65565 + ("Replace --enable-static-pie with --disable-default-pie"). + + Reviewed-by: Siddhesh Poyarekar + Reviewed-by: Szabolcs Nagy + (cherry picked from commit ce1e5b11229f19820b86f8b19d651f16009552b0) + +diff --git a/sysdeps/unix/sysv/linux/arm/getcontext.S b/sysdeps/unix/sysv/linux/arm/getcontext.S +index 3aa581c4da6d1166..11bfcbe5f53afc6e 100644 +--- a/sysdeps/unix/sysv/linux/arm/getcontext.S ++++ b/sysdeps/unix/sysv/linux/arm/getcontext.S +@@ -50,7 +50,7 @@ ENTRY(__getcontext) + + /* Store FP regs. Much of the FP code is copied from arm/setjmp.S. */ + +-#ifdef PIC ++#ifdef SHARED + ldr r2, 1f + ldr r1, .Lrtld_global_ro + 0: add r2, pc, r2 +@@ -102,7 +102,7 @@ ENTRY(__getcontext) + + END(__getcontext) + +-#ifdef PIC ++#ifdef SHARED + 1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS + .Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +diff --git a/sysdeps/unix/sysv/linux/arm/setcontext.S b/sysdeps/unix/sysv/linux/arm/setcontext.S +index 8be8beefea13883e..4c7c6e550944138c 100644 +--- a/sysdeps/unix/sysv/linux/arm/setcontext.S ++++ b/sysdeps/unix/sysv/linux/arm/setcontext.S +@@ -32,7 +32,7 @@ ENTRY(__setcontext) + add r0, r0, #UCONTEXT_REGSPACE + + /* Restore the VFP registers. Copied from arm/__longjmp.S. */ +-#ifdef PIC ++#ifdef SHARED + ldr r2, 1f + ldr r1, .Lrtld_global_ro + 0: add r2, pc, r2 +@@ -101,7 +101,7 @@ ENTRY(__startcontext) + .fnend + END(__startcontext) + +-#ifdef PIC ++#ifdef SHARED + 1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS + .Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) diff --git a/SOURCES/glibc-upstream-2.34-57.patch b/SOURCES/glibc-upstream-2.34-57.patch new file mode 100644 index 0000000..c8523f9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-57.patch @@ -0,0 +1,74 @@ +commit dc9b69d5331dcdca4547c0490cb9fefbd89e40f6 +Author: Florian Weimer +Date: Fri Dec 17 12:01:20 2021 +0100 + + nss: Use "files dns" as the default for the hosts database (bug 28700) + + This matches what is currently in nss/nsswitch.conf. The new ordering + matches what most distributions use in their installed configuration + files. + + It is common to add localhost to /etc/hosts because the name does not + exist in the DNS, but is commonly used as a host name. + + With the built-in "dns [!UNAVAIL=return] files" default, dns is + searched first and provides an answer for "localhost" (NXDOMAIN). + We never look at the files database as a result, so the contents of + /etc/hosts is ignored. This means that "getent hosts localhost" + fail without a /etc/nsswitch.conf file, even though the host name + is listed in /etc/hosts. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit b99b0f93ee8762fe53ff65802deb6f00700b9924) + +diff --git a/manual/nss.texi b/manual/nss.texi +index 3aaa7786f8cf3168..524d22ad1e7f8ca0 100644 +--- a/manual/nss.texi ++++ b/manual/nss.texi +@@ -324,9 +324,8 @@ missing. + + @cindex default value, and NSS + For the @code{hosts} and @code{networks} databases the default value is +-@code{dns [!UNAVAIL=return] files}. I.e., the system is prepared for +-the DNS service not to be available but if it is available the answer it +-returns is definitive. ++@code{files dns}. I.e., local configuration will override the contents ++of the domain name system (DNS). + + The @code{passwd}, @code{group}, and @code{shadow} databases was + traditionally handled in a special way. The appropriate files in the +diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c +index f1c97f7c8e9d7378..dbc87868dd408d9f 100644 +--- a/nss/XXX-lookup.c ++++ b/nss/XXX-lookup.c +@@ -29,7 +29,7 @@ + |* ALTERNATE_NAME - name of another service which is examined in *| + |* case DATABASE_NAME is not found *| + |* *| +-|* DEFAULT_CONFIG - string for default conf (e.g. "dns files") *| ++|* DEFAULT_CONFIG - string for default conf (e.g. "files dns") *| + |* *| + \*******************************************************************/ + +diff --git a/nss/nss_database.c b/nss/nss_database.c +index ab121cb371c087e9..54561f03287db2e4 100644 +--- a/nss/nss_database.c ++++ b/nss/nss_database.c +@@ -80,7 +80,7 @@ enum nss_database_default + { + nss_database_default_defconfig = 0, /* "nis [NOTFOUND=return] files". */ + nss_database_default_compat, /* "compat [NOTFOUND=return] files". */ +- nss_database_default_dns, /* "dns [!UNAVAIL=return] files". */ ++ nss_database_default_dns, /* "files dns". */ + nss_database_default_files, /* "files". */ + nss_database_default_nis, /* "nis". */ + nss_database_default_nis_nisplus, /* "nis nisplus". */ +@@ -133,7 +133,7 @@ nss_database_select_default (struct nss_database_default_cache *cache, + #endif + + case nss_database_default_dns: +- line = "dns [!UNAVAIL=return] files"; ++ line = "files dns"; + break; + + case nss_database_default_files: diff --git a/SOURCES/glibc-upstream-2.34-58.patch b/SOURCES/glibc-upstream-2.34-58.patch new file mode 100644 index 0000000..d95112e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-58.patch @@ -0,0 +1,35 @@ +commit 03de6917bd11c0591867607ce74ef658f76eabb9 +Author: Aurelien Jarno +Date: Wed Dec 15 23:46:19 2021 +0100 + + elf: Fix tst-cpu-features-cpuinfo for KVM guests on some AMD systems [BZ #28704] + + On KVM guests running on some AMD systems, the IBRS feature is reported + as a synthetic feature using the Intel feature, while the cpuinfo entry + keeps the same. Handle that by first checking the presence of the Intel + feature on AMD systems. + + Fixes bug 28704. + + (cherry picked from commit 94058f6cde8b887178885954740ac6c866d25eab) + +diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo.c b/sysdeps/x86/tst-cpu-features-cpuinfo.c +index 2d4927f5e52dc260..830aaca2ecae971b 100644 +--- a/sysdeps/x86/tst-cpu-features-cpuinfo.c ++++ b/sysdeps/x86/tst-cpu-features-cpuinfo.c +@@ -169,7 +169,14 @@ do_test (int argc, char **argv) + else if (cpu_features->basic.kind == arch_kind_amd) + { + fails += CHECK_PROC (ibpb, AMD_IBPB); +- fails += CHECK_PROC (ibrs, AMD_IBRS); ++ ++ /* The IBRS feature on AMD processors is reported using the Intel feature ++ * on KVM guests (synthetic bit). In both cases the cpuinfo entry is the ++ * same. */ ++ if (HAS_CPU_FEATURE (IBRS_IBPB)) ++ fails += CHECK_PROC (ibrs, IBRS_IBPB); ++ else ++ fails += CHECK_PROC (ibrs, AMD_IBRS); + fails += CHECK_PROC (stibp, AMD_STIBP); + } + fails += CHECK_PROC (ibt, IBT); diff --git a/SOURCES/glibc-upstream-2.34-59.patch b/SOURCES/glibc-upstream-2.34-59.patch new file mode 100644 index 0000000..b0ea00c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-59.patch @@ -0,0 +1,35 @@ +commit 5daf13b1e637eec0f7a2de05b177cb0d76479aa2 +Author: Matheus Castanho +Date: Wed Dec 1 11:14:40 2021 -0300 + + powerpc64[le]: Allocate extra stack frame on syscall.S + + The syscall function does not allocate the extra stack frame for scv like other + assembly syscalls using DO_CALL_SCV. So after commit d120fb9941 changed the + offset that is used to save LR, syscall ended up using an invalid offset, + causing regressions on powerpc64. So make sure the extra stack frame is + allocated in syscall.S as well to make it consistent with other uses of + DO_CALL_SCV and avoid similar issues in the future. + + Tested on powerpc, powerpc64, and powerpc64le (with and without scv) + + Reviewed-by: Raphael M Zinsly + + (cherry picked from commit ae91d3df24a4a1b1f264d101a71a298bff310d14) + +diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S +index a29652feaf6764cf..a5497c8370982fe3 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/syscall.S ++++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S +@@ -27,7 +27,11 @@ ENTRY (syscall) + mr r8,r9 + #if defined(USE_PPC_SCV) && !IS_IN(rtld) && (defined(__PPC64__) || defined(__powerpc64__)) + CHECK_SCV_SUPPORT r9 0f ++ stdu r1,-SCV_FRAME_SIZE(r1) ++ cfi_adjust_cfa_offset(SCV_FRAME_SIZE) + DO_CALL_SCV ++ addi r1,r1,SCV_FRAME_SIZE ++ cfi_adjust_cfa_offset(-SCV_FRAME_SIZE) + RET_SCV + b 1f + #endif diff --git a/SOURCES/glibc-upstream-2.34-6.patch b/SOURCES/glibc-upstream-2.34-6.patch new file mode 100644 index 0000000..5e6a43d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-6.patch @@ -0,0 +1,65 @@ +commit 31902ae639d6a50e768a85f1cd2a17e56b8463c2 +Author: Florian Weimer +Date: Fri Aug 6 09:51:38 2021 +0200 + + Linux: Fix fcntl, ioctl, prctl redirects for _TIME_BITS=64 (bug 28182) + + __REDIRECT and __THROW are not compatible with C++ due to the ordering of the + __asm__ alias and the throw specifier. __REDIRECT_NTH has to be used + instead. + + Fixes commit 8a40aff86ba5f64a3a84883e539cb67b ("io: Add time64 alias + for fcntl"), commit 82c395d91ea4f69120d453aeec398e30 ("misc: Add + time64 alias for ioctl"), commit b39ffab860cd743a82c91946619f1b8158 + ("Linux: Add time64 alias for prctl"). + + Reviewed-by: Carlos O'Donell + (cherry picked from commit c87fcacc50505d550f1bb038382bcc7ea73a5926) + +diff --git a/io/fcntl.h b/io/fcntl.h +index 8917a73b420b503d..1c96f98f4d75ce65 100644 +--- a/io/fcntl.h ++++ b/io/fcntl.h +@@ -187,10 +187,10 @@ extern int fcntl64 (int __fd, int __cmd, ...); + # endif + #else /* __USE_TIME_BITS64 */ + # ifdef __REDIRECT +-extern int __REDIRECT (fcntl, (int __fd, int __request, ...), +- __fcntl_time64) __THROW; +-extern int __REDIRECT (fcntl64, (int __fd, int __request, ...), +- __fcntl_time64) __THROW; ++extern int __REDIRECT_NTH (fcntl, (int __fd, int __request, ...), ++ __fcntl_time64); ++extern int __REDIRECT_NTH (fcntl64, (int __fd, int __request, ...), ++ __fcntl_time64); + # else + extern int __fcntl_time64 (int __fd, int __request, ...) __THROW; + # define fcntl64 __fcntl_time64 +diff --git a/misc/sys/ioctl.h b/misc/sys/ioctl.h +index 6884d9925f06125f..9945c1e9181eb313 100644 +--- a/misc/sys/ioctl.h ++++ b/misc/sys/ioctl.h +@@ -42,8 +42,8 @@ __BEGIN_DECLS + extern int ioctl (int __fd, unsigned long int __request, ...) __THROW; + #else + # ifdef __REDIRECT +-extern int __REDIRECT (ioctl, (int __fd, unsigned long int __request, ...), +- __ioctl_time64) __THROW; ++extern int __REDIRECT_NTH (ioctl, (int __fd, unsigned long int __request, ...), ++ __ioctl_time64); + # else + extern int __ioctl_time64 (int __fd, unsigned long int __request, ...) __THROW; + # define ioctl __ioctl_time64 +diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h +index db88938b3a542b0b..f0e0d2f27f9b9ee9 100644 +--- a/sysdeps/unix/sysv/linux/sys/prctl.h ++++ b/sysdeps/unix/sysv/linux/sys/prctl.h +@@ -42,7 +42,7 @@ __BEGIN_DECLS + extern int prctl (int __option, ...) __THROW; + #else + # ifdef __REDIRECT +-extern int __REDIRECT (prctl, (int __option, ...), __prctl_time64) __THROW; ++extern int __REDIRECT_NTH (prctl, (int __option, ...), __prctl_time64); + # else + extern int __prctl_time64 (int __option,d ...) __THROW; + # define ioctl __prctl_time64 diff --git a/SOURCES/glibc-upstream-2.34-60.patch b/SOURCES/glibc-upstream-2.34-60.patch new file mode 100644 index 0000000..60d2765 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-60.patch @@ -0,0 +1,32 @@ +commit 9de8011c328021f10588a8acb418daf5121d5f3d +Author: Aurelien Jarno +Date: Tue Dec 14 22:44:35 2021 +0100 + + riscv: align stack in clone [BZ #28702] + + The RISC-V ABI [1] mandates that "the stack pointer shall be aligned to + a 128-bit boundary upon procedure entry". This as not the case in clone. + + This fixes the misc/tst-misalign-clone-internal and + misc/tst-misalign-clone tests. + + Fixes bug 28702. + + [1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc + + (cherry picked from commit d2e594d71509faf36cf851a69370db34a4f5fa65) + +diff --git a/sysdeps/unix/sysv/linux/riscv/clone.S b/sysdeps/unix/sysv/linux/riscv/clone.S +index 12f91a20d3bb34f5..161e83c7e3786b8d 100644 +--- a/sysdeps/unix/sysv/linux/riscv/clone.S ++++ b/sysdeps/unix/sysv/linux/riscv/clone.S +@@ -32,6 +32,9 @@ + .text + LEAF (__clone) + ++ /* Align stack to a 128-bit boundary as per RISC-V ABI. */ ++ andi a1,a1,ALMASK ++ + /* Sanity check arguments. */ + beqz a0,L (invalid) /* No NULL function pointers. */ + beqz a1,L (invalid) /* No NULL stack pointers. */ diff --git a/SOURCES/glibc-upstream-2.34-61.patch b/SOURCES/glibc-upstream-2.34-61.patch new file mode 100644 index 0000000..82214de --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-61.patch @@ -0,0 +1,34 @@ +commit aa3a97496c82a8443039248ebee650322c9480f4 +Author: Aurelien Jarno +Date: Thu Dec 16 00:06:28 2021 +0100 + + riscv: align stack before calling _dl_init [BZ #28703] + + Align the stack pointer to 128 bits during the call to _dl_init() as + specified by the RISC-V ABI [1]. This fixes the elf/tst-align2 test. + + Fixes bug 28703. + + [1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc + + (cherry picked from commit 225da459cebef1037dcd78b56471edc0721e1c41) + +diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h +index aedf69fcdd8aff50..951268923da26a37 100644 +--- a/sysdeps/riscv/dl-machine.h ++++ b/sysdeps/riscv/dl-machine.h +@@ -127,8 +127,14 @@ elf_machine_load_address (void) + sll a3, a1, " STRINGXP (PTRLOG) "\n\ + add a3, a3, a2\n\ + add a3, a3, " STRINGXP (SZREG) "\n\ ++ # Stash the stack pointer in s1.\n\ ++ mv s1, sp\n\ ++ # Align stack to 128 bits for the _dl_init call.\n\ ++ andi sp, sp,-16\n\ + # Call the function to run the initializers.\n\ + jal _dl_init\n\ ++ # Restore the stack pointer for _start.\n\ ++ mv sp, s1\n\ + # Pass our finalizer function to _start.\n\ + lla a0, _dl_fini\n\ + # Jump to the user entry point.\n\ diff --git a/SOURCES/glibc-upstream-2.34-62.patch b/SOURCES/glibc-upstream-2.34-62.patch new file mode 100644 index 0000000..656bcfb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-62.patch @@ -0,0 +1,21 @@ +commit 4029747c592cb2d59805b3a4e7a8963fcdcdbeb1 +Author: John David Anglin +Date: Mon Sep 6 17:37:29 2021 +0000 + + Update hppa libm-test-ulps + + (cherry picked from commit d8cf84ac7e504663dfeb2bb45d8d48ae81effe05) + +diff --git a/sysdeps/hppa/fpu/libm-test-ulps b/sysdeps/hppa/fpu/libm-test-ulps +index 90e16a72692e9199..3d60fc25a14d053f 100644 +--- a/sysdeps/hppa/fpu/libm-test-ulps ++++ b/sysdeps/hppa/fpu/libm-test-ulps +@@ -1104,7 +1104,7 @@ float: 8 + ldouble: 1 + + Function: "tgamma_downward": +-double: 8 ++double: 9 + float: 7 + + Function: "tgamma_towardzero": diff --git a/SOURCES/glibc-upstream-2.34-63.patch b/SOURCES/glibc-upstream-2.34-63.patch new file mode 100644 index 0000000..e0944e1 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-63.patch @@ -0,0 +1,21 @@ +commit e94544c82f4ac37017589d8d83156d72388fc4af +Author: Adhemerval Zanella +Date: Wed Aug 4 21:40:32 2021 +0300 + + Update sparc libm-test-ulps + + (cherry picked from commit c52eb066bc634a79e4194457362384abe5b43b3a) + +diff --git a/sysdeps/sparc/fpu/libm-test-ulps b/sysdeps/sparc/fpu/libm-test-ulps +index c2e4649524aa3a44..f34bbe6c592814d0 100644 +--- a/sysdeps/sparc/fpu/libm-test-ulps ++++ b/sysdeps/sparc/fpu/libm-test-ulps +@@ -1346,7 +1346,7 @@ float: 8 + ldouble: 4 + + Function: "tgamma_downward": +-double: 8 ++double: 9 + float: 7 + ldouble: 5 + diff --git a/SOURCES/glibc-upstream-2.34-64.patch b/SOURCES/glibc-upstream-2.34-64.patch new file mode 100644 index 0000000..54ae960 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-64.patch @@ -0,0 +1,81 @@ +commit 1d9764aba8c00754fbf8299e48afbe222245ee3e +Author: Adhemerval Zanella +Date: Wed Aug 4 21:34:12 2021 +0300 + + linux: Add sparck brk implementation + + It turned that the generic implementation of brk() does not work + for sparc, since on failure kernel will just return the previous + input value without setting the conditional register. + + This patches adds back a sparc32 and sparc64 implementation removed + by 720480934ab9107. + + Checked on sparc64-linux-gnu and sparcv9-linux-gnu. + + (cherry picked from commit 5b86241a032c50462988bdd1439e078384690d34) + +diff --git a/sysdeps/unix/sysv/linux/sparc/brk.c b/sysdeps/unix/sysv/linux/sparc/brk.c +new file mode 100644 +index 0000000000000000..aafe9673e3062cf8 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sparc/brk.c +@@ -0,0 +1,58 @@ ++/* Change data segment. Linux SPARC version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* This must be initialized data because commons can't have aliases. */ ++void *__curbrk = 0; ++ ++#if HAVE_INTERNAL_BRK_ADDR_SYMBOL ++/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt ++ to work around different old braindamage in the old Linux ELF dynamic ++ linker. */ ++weak_alias (__curbrk, ___brk_addr) ++#endif ++ ++#ifdef __arch64__ ++# define SYSCALL_NUM "0x6d" ++#else ++# define SYSCALL_NUM "0x10" ++#endif ++ ++int ++__brk (void *addr) ++{ ++ register long int g1 asm ("g1") = __NR_brk; ++ register long int o0 asm ("o0") = (long int) addr; ++ asm volatile ("ta " SYSCALL_NUM ++ : "=r"(o0) ++ : "r"(g1), "0"(o0) ++ : "cc"); ++ __curbrk = (void *) o0; ++ ++ if (__curbrk < addr) ++ { ++ __set_errno (ENOMEM); ++ return -1; ++ } ++ ++ return 0; ++} ++weak_alias (__brk, brk) diff --git a/SOURCES/glibc-upstream-2.34-65.patch b/SOURCES/glibc-upstream-2.34-65.patch new file mode 100644 index 0000000..6644c9d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-65.patch @@ -0,0 +1,33 @@ +commit 8ad6d6d8ed33631bd2ca5d1112e6da2f92731432 +Author: maminjie +Date: Mon Dec 20 19:36:32 2021 +0800 + + Linux: Fix 32-bit vDSO for clock_gettime on powerpc32 + + When the clock_id is CLOCK_PROCESS_CPUTIME_ID or CLOCK_THREAD_CPUTIME_ID, + on the 5.10 kernel powerpc 32-bit, the 32-bit vDSO is executed successfully ( + because the __kernel_clock_gettime in arch/powerpc/kernel/vdso32/gettimeofday.S + does not support these two IDs, the 32-bit time_t syscall will be used), + but tp32.tv_sec is equal to 0, causing the 64-bit time_t syscall to continue to be used, + resulting in two system calls. + + Fix commit 72e84d1db22203e01a43268de71ea8669eca2863. + + Signed-off-by: maminjie + Reviewed-by: Adhemerval Zanella + + (cherry picked from commit e0fc721ce600038dd390e77cfe52440707ef574d) + +diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c +index 91df6b3d967bf945..9c7d9073254843c7 100644 +--- a/sysdeps/unix/sysv/linux/clock_gettime.c ++++ b/sysdeps/unix/sysv/linux/clock_gettime.c +@@ -53,7 +53,7 @@ __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp) + { + struct timespec tp32; + r = INTERNAL_VSYSCALL_CALL (vdso_time, 2, clock_id, &tp32); +- if (r == 0 && tp32.tv_sec > 0) ++ if (r == 0 && tp32.tv_sec >= 0) + { + *tp = valid_timespec_to_timespec64 (tp32); + return 0; diff --git a/SOURCES/glibc-upstream-2.34-66.patch b/SOURCES/glibc-upstream-2.34-66.patch new file mode 100644 index 0000000..9619100 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-66.patch @@ -0,0 +1,37 @@ +commit 41fddc064ded5c9a36d8ffaad59a85407a22a535 +Author: Andrea Monaco +Date: Sun Dec 12 10:24:28 2021 +0100 + + intl/plural.y: Avoid conflicting declarations of yyerror and yylex + + bison-3.8 includes these lines in the generated intl/plural.c: + + #if !defined __gettexterror && !defined YYERROR_IS_DECLARED + void __gettexterror (struct parse_args *arg, const char *msg); + #endif + #if !defined __gettextlex && !defined YYLEX_IS_DECLARED + int __gettextlex (YYSTYPE *yylvalp, struct parse_args *arg); + #endif + + Those default prototypes provided by bison conflict with the + declarations later on in plural.y. This patch solves the issue. + + Reviewed-by: Arjun Shankar + (cherry picked from commit c6d7d6312c21bbcfb236d48bb7c11cedb234389f) + +diff --git a/intl/plural.y b/intl/plural.y +index e02e74541c4574eb..2ee128ba01b5820d 100644 +--- a/intl/plural.y ++++ b/intl/plural.y +@@ -40,6 +40,11 @@ + # define __gettextparse PLURAL_PARSE + #endif + ++/* Later we provide those prototypes. Without these macros, bison may ++ generate its own prototypes with possible conflicts. */ ++#define YYLEX_IS_DECLARED ++#define YYERROR_IS_DECLARED ++ + %} + %parse-param {struct parse_args *arg} + %lex-param {struct parse_args *arg} diff --git a/SOURCES/glibc-upstream-2.34-67.patch b/SOURCES/glibc-upstream-2.34-67.patch new file mode 100644 index 0000000..2ee0841 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-67.patch @@ -0,0 +1,50 @@ +commit 217b84127b3a6590afcc7e198e6c3f665935e8f4 +Author: Wilco Dijkstra +Date: Thu Jan 6 14:36:28 2022 +0000 + + AArch64: Check for SVE in ifuncs [BZ #28744] + + Add a check for SVE in the A64FX ifuncs for memcpy, memset and memmove. + This fixes BZ #28744. + + (cherry picked from commit e5fa62b8db546f8792ec9e5c61e6419f4f8e3f4d) + +diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c +index 25e0081eeb51727c..b6703af44b3f1a3d 100644 +--- a/sysdeps/aarch64/multiarch/memcpy.c ++++ b/sysdeps/aarch64/multiarch/memcpy.c +@@ -48,7 +48,7 @@ libc_ifunc (__libc_memcpy, + || IS_NEOVERSE_V1 (midr) + ? __memcpy_simd + # if HAVE_AARCH64_SVE_ASM +- : (IS_A64FX (midr) ++ : (IS_A64FX (midr) && sve + ? __memcpy_a64fx + : __memcpy_generic)))))); + # else +diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c +index d0adefc547f60030..d2339ff34ff7b3e5 100644 +--- a/sysdeps/aarch64/multiarch/memmove.c ++++ b/sysdeps/aarch64/multiarch/memmove.c +@@ -48,7 +48,7 @@ libc_ifunc (__libc_memmove, + || IS_NEOVERSE_V1 (midr) + ? __memmove_simd + # if HAVE_AARCH64_SVE_ASM +- : (IS_A64FX (midr) ++ : (IS_A64FX (midr) && sve + ? __memmove_a64fx + : __memmove_generic)))))); + # else +diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c +index d7d9bbbda095e051..3d839bc02e96380d 100644 +--- a/sysdeps/aarch64/multiarch/memset.c ++++ b/sysdeps/aarch64/multiarch/memset.c +@@ -44,7 +44,7 @@ libc_ifunc (__libc_memset, + : (IS_EMAG (midr) && zva_size == 64 + ? __memset_emag + # if HAVE_AARCH64_SVE_ASM +- : (IS_A64FX (midr) ++ : (IS_A64FX (midr) && sve + ? __memset_a64fx + : __memset_generic)))); + # else diff --git a/SOURCES/glibc-upstream-2.34-68.patch b/SOURCES/glibc-upstream-2.34-68.patch new file mode 100644 index 0000000..935e4f0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-68.patch @@ -0,0 +1,27 @@ +commit 515a6f53cd984d5e6e374fbee52772f967fc3c73 +Author: Paul Eggert +Date: Mon Sep 13 22:49:45 2021 -0700 + + Fix subscript error with odd TZif file [BZ #28338] + + * time/tzfile.c (__tzfile_compute): Fix unlikely off-by-one bug + that accessed before start of an array when an oddball-but-valid + TZif file was queried with an unusual time_t value. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 645277434a42efc547d2cac8bfede4da10b4049f) + +diff --git a/time/tzfile.c b/time/tzfile.c +index 4377018a55936389..190a777152b31cee 100644 +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -765,8 +765,7 @@ __tzfile_compute (__time64_t timer, int use_localtime, + *leap_correct = leaps[i].change; + + if (timer == leaps[i].transition /* Exactly at the transition time. */ +- && ((i == 0 && leaps[i].change > 0) +- || leaps[i].change > leaps[i - 1].change)) ++ && (leaps[i].change > (i == 0 ? 0 : leaps[i - 1].change))) + { + *leap_hit = 1; + while (i > 0 diff --git a/SOURCES/glibc-upstream-2.34-69.patch b/SOURCES/glibc-upstream-2.34-69.patch new file mode 100644 index 0000000..1346263 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-69.patch @@ -0,0 +1,52 @@ +commit 85b24f9694e21f1d2f2d8b80d3bf690687723347 +Author: Hans-Peter Nilsson +Date: Fri Dec 17 21:38:00 2021 +0100 + + timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707) + + When using a timezone file with a truncated starting time, + generated by the zic in IANA tzcode-2021d a.k.a. tzlib-2021d + (also in tzlib-2021e; current as of this writing), glibc + asserts in __tzfile_read (on e.g. tzset() for this file) and + you may find lines matching "tzfile.c:435: __tzfile_read: + Assertion `num_types == 1' failed" in your syslog. + + One example of such a file is the tzfile for Asuncion + generated by tzlib-2021e as follows, using the tzlib-2021e zic: + "zic -d DEST -r @1546300800 -L /dev/null -b slim + SOURCE/southamerica". Note that in its type 2 header, it has + two entries in its "time-types" array (types), but only one + entry in its "transition types" array (type_idxs). + + This is valid and expected already in the published RFC8536, and + not even frowned upon: "Local time for timestamps before the + first transition is specified by the first time type (time type + 0)" ... "every nonzero local time type index SHOULD appear at + least once in the transition type array". Note the "nonzero ... + index". Until the 2021d zic, index 0 has been shared by the + first valid transition but with 2021d it's separate, set apart + as a placeholder and only "implicitly" indexed. (A draft update + of the RFC mandates that the entry at index 0 is a placeholder + in this case, hence can no longer be shared.) + + * time/tzfile.c (__tzfile_read): Don't assert when no transitions + are found. + + Co-authored-by: Christopher Wong + (cherry picked from commit c36f64aa6dff13b12a1e03a185e75a50fa9f6a4c) + +diff --git a/time/tzfile.c b/time/tzfile.c +index 190a777152b31cee..8668392ad387af05 100644 +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -431,8 +431,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + if (__tzname[0] == NULL) + { + /* This should only happen if there are no transition rules. +- In this case there should be only one single type. */ +- assert (num_types == 1); ++ In this case there's usually only one single type, unless ++ e.g. the data file has a truncated time-range. */ + __tzname[0] = __tzstring (zone_names); + } + if (__tzname[1] == NULL) diff --git a/SOURCES/glibc-upstream-2.34-7.patch b/SOURCES/glibc-upstream-2.34-7.patch new file mode 100644 index 0000000..c49b837 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-7.patch @@ -0,0 +1,35 @@ +commit 79474303223c5665bec75ffbdb2a86ee04a2514b +Author: Nikita Popov +Date: Mon Aug 9 20:17:34 2021 +0530 + + librt: fix NULL pointer dereference (bug 28213) + + Helper thread frees copied attribute on NOTIFY_REMOVED message + received from the OS kernel. Unfortunately, it fails to check whether + copied attribute actually exists (data.attr != NULL). This worked + earlier because free() checks passed pointer before actually + attempting to release corresponding memory. But + __pthread_attr_destroy assumes pointer is not NULL. + + So passing NULL pointer to __pthread_attr_destroy will result in + segmentation fault. This scenario is possible if + notification->sigev_notify_attributes == NULL (which means default + thread attributes should be used). + + Signed-off-by: Nikita Popov + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit b805aebd42364fe696e417808a700fdb9800c9e8) + +diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c +index 9799dcdaa479a1d5..eccae2e4c6cdfefa 100644 +--- a/sysdeps/unix/sysv/linux/mq_notify.c ++++ b/sysdeps/unix/sysv/linux/mq_notify.c +@@ -131,7 +131,7 @@ helper_thread (void *arg) + to wait until it is done with it. */ + (void) __pthread_barrier_wait (¬ify_barrier); + } +- else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED) ++ else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED && data.attr != NULL) + { + /* The only state we keep is the copy of the thread attributes. */ + __pthread_attr_destroy (data.attr); diff --git a/SOURCES/glibc-upstream-2.34-70.patch b/SOURCES/glibc-upstream-2.34-70.patch new file mode 100644 index 0000000..b83ae03 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-70.patch @@ -0,0 +1,130 @@ +commit d5ba02f67dd62a63e29c29eebd6c543722aa6b5b +Author: Hans-Peter Nilsson +Date: Fri Dec 17 21:45:54 2021 +0100 + + timezone: test-case for BZ #28707 + + This test-case is the tzfile for Asuncion generated by + tzlib-2021e as follows, using the tzlib-2021e zic: "zic -d + DEST -r @1546300800 -L /dev/null -b slim + SOURCE/southamerica". Note that in its type 2 header, it + has two entries in its "time-types" array (types), but only + one entry in its "transition types" array (type_idxs). + + * timezone/Makefile, timezone/tst-pr28707.c, + timezone/testdata/gen-XT5.sh: New test. + + Co-authored-by: Christopher Wong + (cherry picked from commit ebe899af0dc3215159a9c896ac6f35b72a18cb6e) + +diff --git a/timezone/Makefile b/timezone/Makefile +index c624a189b322cb5f..f091663b8bbbceda 100644 +--- a/timezone/Makefile ++++ b/timezone/Makefile +@@ -23,7 +23,7 @@ subdir := timezone + include ../Makeconfig + + others := zdump zic +-tests := test-tz tst-timezone tst-tzset ++tests := test-tz tst-timezone tst-tzset tst-bz28707 + + generated-dirs += testdata + +@@ -85,10 +85,12 @@ $(objpfx)tst-timezone.out: $(addprefix $(testdata)/, \ + America/Sao_Paulo Asia/Tokyo \ + Europe/London) + $(objpfx)tst-tzset.out: $(addprefix $(testdata)/XT, 1 2 3 4) ++$(objpfx)tst-bz28707.out: $(testdata)/XT5 + + test-tz-ENV = TZDIR=$(testdata) + tst-timezone-ENV = TZDIR=$(testdata) + tst-tzset-ENV = TZDIR=$(testdata) ++tst-bz28707-ENV = TZDIR=$(testdata) + + # Note this must come second in the deps list for $(built-program-cmd) to work. + zic-deps = $(objpfx)zic $(leapseconds) yearistype +@@ -122,6 +124,10 @@ $(testdata)/XT%: testdata/XT% + $(make-target-directory) + cp $< $@ + ++$(testdata)/XT%: testdata/gen-XT%.sh ++ $(SHELL) $< > $@.tmp ++ mv $@.tmp $@ ++ + $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make + sed -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \ + -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \ +diff --git a/timezone/testdata/gen-XT5.sh b/timezone/testdata/gen-XT5.sh +new file mode 100755 +index 0000000000000000..3cea0569eb5a6a57 +--- /dev/null ++++ b/timezone/testdata/gen-XT5.sh +@@ -0,0 +1,16 @@ ++#! /bin/sh ++ ++# This test-case is the tzfile for America/Asuncion ++# generated by tzlib-2021e as follows, using the tzlib-2021e ++# zic: "zic -d DEST -r @1546300800 -L /dev/null -b slim ++# SOURCE/southamerica". Note that in its type 2 header, it ++# has two entries in its "time-types" array (types), but ++# only one entry in its "transition types" array ++# (type_idxs). ++ ++printf \ ++'TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'\ ++'\0\0\0\0\0\0\0\1\0\0\0\1\0\0\0\0\0\0\0TZif2\0\0\0\0\0\0\0\0'\ ++'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\2\0\0\0\b\0'\ ++'\0\0\0\*\255\200\1\0\0\0\0\0\0\377\377\325\320\1\4-00\0-03\0\n'\ ++'<-04>4<-03>,M10.1.0/0,M3.4.0/0\n' +diff --git a/timezone/tst-bz28707.c b/timezone/tst-bz28707.c +new file mode 100644 +index 0000000000000000..0a9df1e9a094f1e9 +--- /dev/null ++++ b/timezone/tst-bz28707.c +@@ -0,0 +1,46 @@ ++/* Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* Test that we can use a truncated timezone-file, where the time-type ++ at index 0 is not indexed by the transition-types array (and the ++ transition-types array does not contain at least both one DST and one ++ normal time members). */ ++ ++static int ++do_test (void) ++{ ++ if (setenv ("TZ", "XT5", 1)) ++ { ++ puts ("setenv failed."); ++ return 1; ++ } ++ ++ tzset (); ++ ++ return ++ /* Sanity-check that we got the right timezone-name for DST. For ++ normal time, we're likely to get "-00" (the "unspecified" marker), ++ even though the POSIX timezone string says "-04". Let's not test ++ that. */ ++ !(strcmp (tzname[1], "-03") == 0); ++} ++#include diff --git a/SOURCES/glibc-upstream-2.34-71.patch b/SOURCES/glibc-upstream-2.34-71.patch new file mode 100644 index 0000000..4e534ed --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-71.patch @@ -0,0 +1,39 @@ +commit e64235ff4266e87b20505101877fe57350ab69ab +Author: Paul A. Clarke +Date: Tue Sep 14 13:13:33 2021 -0500 + + powerpc: Fix unrecognized instruction errors with recent GCC + + Recent binutils commit b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a + changes the behavior of `.machine` directives to override, rather + than augment, the base CPU. This can result in _reduced_ functionality + when, for example, compiling for default machine "power8", but explicitly + asking for ".machine power5", which loses Altivec instructions. + + In tst-ucontext-ppc64-vscr.c, while the instructions provoking the new + error messages are bracketed by ".machine power5", which is ostensibly + Power ISA 2.03 (POWER5), the POWER5 processor did not support the + VSX subset, so these instructions are not recognized as "power5". + + Error: unrecognized opcode: `vspltisb' + Error: unrecognized opcode: `vpkuwus' + Error: unrecognized opcode: `mfvscr' + Error: unrecognized opcode: `stvx' + + Manually adding the VSX subset via ".machine altivec" is sufficient. + + Reviewed-by: Tulio Magno Quites Machado Filho + (cherry picked from commit 064b475a2e5662b6b3973fabf505eade86e61510) + +diff --git a/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c b/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c +index 28c87fcef72bded6..d3fc4ab589f4752a 100644 +--- a/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c ++++ b/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c +@@ -50,6 +50,7 @@ do_test (void) + /* Set SAT bit in VSCR register. */ + asm volatile (".machine push;\n" + ".machine \"power5\";\n" ++ ".machine altivec;\n" + "vspltisb %0,0;\n" + "vspltisb %1,-1;\n" + "vpkuwus %0,%0,%1;\n" diff --git a/SOURCES/glibc-upstream-2.34-72.patch b/SOURCES/glibc-upstream-2.34-72.patch new file mode 100644 index 0000000..548e54e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-72.patch @@ -0,0 +1,377 @@ +commit 73558ffe841cf4c60ccb4c71cf6dcebf84f2b736 +Author: Joseph Myers +Date: Wed Nov 10 15:21:19 2021 +0000 + + Update syscall lists for Linux 5.15 + + Linux 5.15 has one new syscall, process_mrelease (and also enables the + clone3 syscall for RV32). It also has a macro __NR_SYSCALL_MASK for + Arm, which is not a syscall but matches the pattern used for syscall + macro names. + + Add __NR_SYSCALL_MASK to the names filtered out in the code dealing + with syscall lists, update syscall-names.list for the new syscall and + regenerate the arch-syscall.h headers with build-many-glibcs.py + update-syscalls. + + Tested with build-many-glibcs.py. + + (cherry picked from commit 3387c40a8bbad5faf85b1feb56429cb20feaa640) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +index bedab1abbac7f6c1..74a809561a45edc4 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +@@ -180,6 +180,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6 72 +diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +index 91354ed9e29b8d15..6fc0a23504c3b53d 100644 +--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +@@ -328,6 +328,7 @@ + #define __NR_preadv2 520 + #define __NR_prlimit64 496 + #define __NR_process_madvise 550 ++#define __NR_process_mrelease 558 + #define __NR_process_vm_readv 504 + #define __NR_process_vm_writev 505 + #define __NR_pselect6 463 +diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +index ff5c7eb36db89494..0c66762bf868a992 100644 +--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +@@ -182,6 +182,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6_time64 413 +diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +index 5772333ceef6ce59..c41a864c6d530eb0 100644 +--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +@@ -235,6 +235,7 @@ + #define __NR_preadv2 392 + #define __NR_prlimit64 369 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 376 + #define __NR_process_vm_writev 377 + #define __NR_pselect6 335 +diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +index 4af6d6202f6df7ae..863ffa3e0cd34d3e 100644 +--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +@@ -190,6 +190,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6 72 +diff --git a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk +index dddfd517471e5cc9..85b017918ef20736 100644 +--- a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk ++++ b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk +@@ -22,7 +22,7 @@ + } + + # Skip pseudo-system calls which describe ranges. +-/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) / { ++/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE|SYSCALL_MASK) / { + next; + } + /^#define __NR_(|64_|[NO]32_)Linux(_syscalls)? / { +diff --git a/sysdeps/unix/sysv/linux/glibcsyscalls.py b/sysdeps/unix/sysv/linux/glibcsyscalls.py +index 621a202ed75cd725..fe7896eebe74cdf4 100644 +--- a/sysdeps/unix/sysv/linux/glibcsyscalls.py ++++ b/sysdeps/unix/sysv/linux/glibcsyscalls.py +@@ -41,7 +41,7 @@ RE_PSEUDO_SYSCALL = re.compile(r"""__NR_( + (unused|reserved)[0-9]+ + + # Pseudo-system call which describes a range. +- |(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) ++ |(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE|SYSCALL_MASK) + |(|64_|[NO]32_)Linux(_syscalls)? + )""", re.X) + +diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +index b07fc8549de34157..6cf27cd17c1ad0c0 100644 +--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +@@ -222,6 +222,7 @@ + #define __NR_preadv2 347 + #define __NR_prlimit64 321 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 330 + #define __NR_process_vm_writev 331 + #define __NR_pselect6 273 +diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +index 6e4264698b5ce480..2512508b7daa8ed2 100644 +--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +@@ -254,6 +254,7 @@ + #define __NR_preadv2 378 + #define __NR_prlimit64 340 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 347 + #define __NR_process_vm_writev 348 + #define __NR_prof 44 +diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +index 1ca706d7216a3902..4a0c737369217367 100644 +--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +@@ -209,6 +209,7 @@ + #define __NR_preadv2 1348 + #define __NR_prlimit64 1325 + #define __NR_process_madvise 1464 ++#define __NR_process_mrelease 1472 + #define __NR_process_vm_readv 1332 + #define __NR_process_vm_writev 1333 + #define __NR_pselect6 1294 +diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +index 2f10f71f90d225ff..e310eb5075fb22d8 100644 +--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +@@ -243,6 +243,7 @@ + #define __NR_preadv2 377 + #define __NR_prlimit64 339 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 345 + #define __NR_process_vm_writev 346 + #define __NR_pselect6 301 +diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +index 0607a4dfa6adaa23..b4ecad010c2a6abf 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +@@ -253,6 +253,7 @@ + #define __NR_preadv2 393 + #define __NR_prlimit64 370 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 377 + #define __NR_process_vm_writev 378 + #define __NR_prof 44 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +index 0055eec0b169ba96..7e3d138ba969c57b 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +@@ -238,6 +238,7 @@ + #define __NR_preadv2 4361 + #define __NR_prlimit64 4338 + #define __NR_process_madvise 4440 ++#define __NR_process_mrelease 4448 + #define __NR_process_vm_readv 4345 + #define __NR_process_vm_writev 4346 + #define __NR_prof 4044 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +index 8e8e9f91ccfebfab..7e9e232e5256bc89 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +@@ -221,6 +221,7 @@ + #define __NR_preadv2 6325 + #define __NR_prlimit64 6302 + #define __NR_process_madvise 6440 ++#define __NR_process_mrelease 6448 + #define __NR_process_vm_readv 6309 + #define __NR_process_vm_writev 6310 + #define __NR_pselect6 6264 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +index ebd1545f806564bb..f9e7ef72b0aa1749 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +@@ -209,6 +209,7 @@ + #define __NR_preadv2 5321 + #define __NR_prlimit64 5297 + #define __NR_process_madvise 5440 ++#define __NR_process_mrelease 5448 + #define __NR_process_vm_readv 5304 + #define __NR_process_vm_writev 5305 + #define __NR_pselect6 5260 +diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +index 2b530b1f88e4c52a..afd73fc1daca1fb4 100644 +--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +@@ -189,6 +189,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6 72 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +index a32984a9c17315ee..0ac2992028eda27e 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +@@ -247,6 +247,7 @@ + #define __NR_preadv2 380 + #define __NR_prlimit64 325 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 351 + #define __NR_process_vm_writev 352 + #define __NR_prof 44 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +index b01e464fb906d632..c890bc644e14fe06 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +@@ -231,6 +231,7 @@ + #define __NR_preadv2 380 + #define __NR_prlimit64 325 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 351 + #define __NR_process_vm_writev 352 + #define __NR_prof 44 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index 24d0a2c455caa630..cd336d755a42598a 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -16,6 +16,7 @@ + #define __NR_clock_nanosleep_time64 407 + #define __NR_clock_settime64 404 + #define __NR_clone 220 ++#define __NR_clone3 435 + #define __NR_close 57 + #define __NR_close_range 436 + #define __NR_connect 203 +@@ -171,6 +172,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6_time64 413 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index e526c89ae7b285cc..8edd21620bb4ef64 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -179,6 +179,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6 72 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +index d4c7b101b64c010f..1a4873f505765617 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +@@ -240,6 +240,7 @@ + #define __NR_preadv2 376 + #define __NR_prlimit64 334 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 340 + #define __NR_process_vm_writev 341 + #define __NR_pselect6 301 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +index bd8c78d7059a0f31..2af4607c1d36d173 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +@@ -211,6 +211,7 @@ + #define __NR_preadv2 376 + #define __NR_prlimit64 334 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 340 + #define __NR_process_vm_writev 341 + #define __NR_pselect6 301 +diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +index 3b6ac3d084d74638..7b422ce268ba14d0 100644 +--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +@@ -237,6 +237,7 @@ + #define __NR_preadv2 381 + #define __NR_prlimit64 339 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 365 + #define __NR_process_vm_writev 366 + #define __NR_pselect6 308 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +index 35221a707e4d4a7c..77c3cc64f95ea7f3 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +@@ -242,6 +242,7 @@ + #define __NR_preadv2 358 + #define __NR_prlimit64 331 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 338 + #define __NR_process_vm_writev 339 + #define __NR_pselect6 297 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +index 5ba2b2050924df1c..7ad50bc4ad6cef04 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +@@ -222,6 +222,7 @@ + #define __NR_preadv2 358 + #define __NR_prlimit64 331 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 338 + #define __NR_process_vm_writev 339 + #define __NR_pselect6 297 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index fd98893b0e44a606..1a74d090b72f4d61 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.14. +-kernel 5.14 ++# The list of system calls is current as of Linux 5.15. ++kernel 5.15 + + FAST_atomic_update + FAST_cmpxchg +@@ -440,6 +440,7 @@ preadv + preadv2 + prlimit64 + process_madvise ++process_mrelease + process_vm_readv + process_vm_writev + prof +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +index 26d6ac68a651ec98..3ce2a1fcfc1c15f2 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +@@ -215,6 +215,7 @@ + #define __NR_preadv2 327 + #define __NR_prlimit64 302 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 310 + #define __NR_process_vm_writev 311 + #define __NR_pselect6 270 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index 36847783f6b91d5e..9e87e89baccc397c 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -208,6 +208,7 @@ + #define __NR_preadv2 1073742370 + #define __NR_prlimit64 1073742126 + #define __NR_process_madvise 1073742264 ++#define __NR_process_mrelease 1073742272 + #define __NR_process_vm_readv 1073742363 + #define __NR_process_vm_writev 1073742364 + #define __NR_pselect6 1073742094 diff --git a/SOURCES/glibc-upstream-2.34-73.patch b/SOURCES/glibc-upstream-2.34-73.patch new file mode 100644 index 0000000..5081674 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-73.patch @@ -0,0 +1,442 @@ +commit 2fe2af88abd13ae5636881da2e26f461ecb7dfb5 +Author: Florian Weimer +Date: Thu Jan 13 14:59:29 2022 +0100 + + i386: Remove broken CAN_USE_REGISTER_ASM_EBP (bug 28771) + + The configure check for CAN_USE_REGISTER_ASM_EBP tried to compile a + simple function that uses %ebp as an inline assembly operand. If + compilation failed, CAN_USE_REGISTER_ASM_EBP was set 0, which + eventually had these consequences: + + (1) %ebx was avoided as an inline assembly operand, with an + assembler macro hack to avoid unnecessary register moves. + (2) %ebp was avoided as an inline assembly operand, using an + out-of-line syscall function for 6-argument system calls. + + (1) is no longer needed for any GCC version that is supported for + building glibc. %ebx can be used directly as a register operand. + Therefore, this commit removes the %ebx avoidance completely. This + avoids the assembler macro hack, which turns out to be incompatible + with the current Systemtap probe macros (which switch to .altmacro + unconditionally). + + (2) is still needed in many build configurations. The existing + configure check cannot really capture that because the simple function + succeeds to compile, while the full glibc build still fails. + Therefore, this commit removes the check, the CAN_USE_REGISTER_ASM_EBP + macro, and uses the out-of-line syscall function for 6-argument system + calls unconditionally. + + Reviewed-by: H.J. Lu + (cherry picked from commit a78e6a10d0b50d0ca80309775980fc99944b1727) + +diff --git a/config.h.in b/config.h.in +index 458342887e4e9380..790038fec60eb049 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -286,10 +286,6 @@ + /* Define if static PIE is enabled. */ + #define ENABLE_STATIC_PIE 0 + +-/* Some compiler options may now allow to use ebp in __asm__ (used mainly +- in i386 6 argument syscall issue). */ +-#define CAN_USE_REGISTER_ASM_EBP 0 +- + /* The default value of x86 CET control. */ + #define DEFAULT_DL_X86_CET_CONTROL cet_elf_property + +diff --git a/sysdeps/unix/sysv/linux/i386/configure b/sysdeps/unix/sysv/linux/i386/configure +index 0327590486c80777..f119e62fc31903b3 100644 +--- a/sysdeps/unix/sysv/linux/i386/configure ++++ b/sysdeps/unix/sysv/linux/i386/configure +@@ -1,44 +1,5 @@ + # This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/unix/sysv/linux/i386. + +-# Check if CFLAGS allows compiler to use ebp register in inline assembly. +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler flags allows ebp in inline assembly" >&5 +-$as_echo_n "checking if compiler flags allows ebp in inline assembly... " >&6; } +-if ${libc_cv_can_use_register_asm_ebp+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- void foo (int i) +- { +- register int reg asm ("ebp") = i; +- asm ("# %0" : : "r" (reg)); +- } +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- libc_cv_can_use_register_asm_ebp=yes +-else +- libc_cv_can_use_register_asm_ebp=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_can_use_register_asm_ebp" >&5 +-$as_echo "$libc_cv_can_use_register_asm_ebp" >&6; } +-if test $libc_cv_can_use_register_asm_ebp = yes; then +- $as_echo "#define CAN_USE_REGISTER_ASM_EBP 1" >>confdefs.h +- +-fi +- + libc_cv_gcc_unwind_find_fde=yes + ldd_rewrite_script=sysdeps/unix/sysv/linux/ldd-rewrite.sed +diff --git a/sysdeps/unix/sysv/linux/i386/configure.ac b/sysdeps/unix/sysv/linux/i386/configure.ac +index 9e980784bb826463..64ab2cc2c8f9deec 100644 +--- a/sysdeps/unix/sysv/linux/i386/configure.ac ++++ b/sysdeps/unix/sysv/linux/i386/configure.ac +@@ -1,22 +1,5 @@ + GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + # Local configure fragment for sysdeps/unix/sysv/linux/i386. + +-# Check if CFLAGS allows compiler to use ebp register in inline assembly. +-AC_CACHE_CHECK([if compiler flags allows ebp in inline assembly], +- libc_cv_can_use_register_asm_ebp, [ +-AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM([ +- void foo (int i) +- { +- register int reg asm ("ebp") = i; +- asm ("# %0" : : "r" (reg)); +- }])], +- [libc_cv_can_use_register_asm_ebp=yes], +- [libc_cv_can_use_register_asm_ebp=no]) +-]) +-if test $libc_cv_can_use_register_asm_ebp = yes; then +- AC_DEFINE(CAN_USE_REGISTER_ASM_EBP) +-fi +- + libc_cv_gcc_unwind_find_fde=yes + ldd_rewrite_script=sysdeps/unix/sysv/linux/ldd-rewrite.sed +diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h +index 8a9911b7acd9e692..39d6a3c13427abb5 100644 +--- a/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ b/sysdeps/unix/sysv/linux/i386/sysdep.h +@@ -43,15 +43,6 @@ + # endif + #endif + +-/* Since GCC 5 and above can properly spill %ebx with PIC when needed, +- we can inline syscalls with 6 arguments if GCC 5 or above is used +- to compile glibc. Disable GCC 5 optimization when compiling for +- profiling or when -fno-omit-frame-pointer is used since asm ("ebp") +- can't be used to put the 6th argument in %ebp for syscall. */ +-#if !defined PROF && CAN_USE_REGISTER_ASM_EBP +-# define OPTIMIZE_FOR_GCC_5 +-#endif +- + #ifdef __ASSEMBLER__ + + /* Linux uses a negative return value to indicate syscall errors, +@@ -239,36 +230,6 @@ + extern int __syscall_error (int) + attribute_hidden __attribute__ ((__regparm__ (1))); + +-#ifndef OPTIMIZE_FOR_GCC_5 +-/* We need some help from the assembler to generate optimal code. We +- define some macros here which later will be used. */ +-asm (".L__X'%ebx = 1\n\t" +- ".L__X'%ecx = 2\n\t" +- ".L__X'%edx = 2\n\t" +- ".L__X'%eax = 3\n\t" +- ".L__X'%esi = 3\n\t" +- ".L__X'%edi = 3\n\t" +- ".L__X'%ebp = 3\n\t" +- ".L__X'%esp = 3\n\t" +- ".macro bpushl name reg\n\t" +- ".if 1 - \\name\n\t" +- ".if 2 - \\name\n\t" +- "error\n\t" +- ".else\n\t" +- "xchgl \\reg, %ebx\n\t" +- ".endif\n\t" +- ".endif\n\t" +- ".endm\n\t" +- ".macro bpopl name reg\n\t" +- ".if 1 - \\name\n\t" +- ".if 2 - \\name\n\t" +- "error\n\t" +- ".else\n\t" +- "xchgl \\reg, %ebx\n\t" +- ".endif\n\t" +- ".endif\n\t" +- ".endm\n\t"); +- + /* Six-argument syscalls use an out-of-line helper, because an inline + asm using all registers apart from %esp cannot work reliably and + the assembler does not support describing an asm that saves and +@@ -279,7 +240,6 @@ struct libc_do_syscall_args + { + int ebx, edi, ebp; + }; +-#endif + + # define VDSO_NAME "LINUX_2.6" + # define VDSO_HASH 61765110 +@@ -332,14 +292,8 @@ struct libc_do_syscall_args + + /* Each object using 6-argument inline syscalls must include a + definition of __libc_do_syscall. */ +-#ifdef OPTIMIZE_FOR_GCC_5 +-# define INTERNAL_SYSCALL_MAIN_6(name, args...) \ +- INTERNAL_SYSCALL_MAIN_INLINE(name, 6, args) +-# define INTERNAL_SYSCALL_MAIN_NCS_6(name, args...) \ +- INTERNAL_SYSCALL_MAIN_NCS(name, 6, args) +-#else /* GCC 5 */ +-# define INTERNAL_SYSCALL_MAIN_6(name, arg1, arg2, arg3, \ +- arg4, arg5, arg6) \ ++#define INTERNAL_SYSCALL_MAIN_6(name, arg1, arg2, arg3, \ ++ arg4, arg5, arg6) \ + struct libc_do_syscall_args _xv = \ + { \ + (int) (arg1), \ +@@ -352,8 +306,8 @@ struct libc_do_syscall_args + : "=a" (resultvar) \ + : "i" (__NR_##name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \ + : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS_6(name, arg1, arg2, arg3, \ +- arg4, arg5, arg6) \ ++#define INTERNAL_SYSCALL_MAIN_NCS_6(name, arg1, arg2, arg3, \ ++ arg4, arg5, arg6) \ + struct libc_do_syscall_args _xv = \ + { \ + (int) (arg1), \ +@@ -366,7 +320,6 @@ struct libc_do_syscall_args + : "=a" (resultvar) \ + : "a" (name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \ + : "memory", "cc") +-#endif /* GCC 5 */ + + #define INTERNAL_SYSCALL(name, nr, args...) \ + ({ \ +@@ -380,193 +333,72 @@ struct libc_do_syscall_args + (int) resultvar; }) + + #if I386_USE_SYSENTER +-# ifdef OPTIMIZE_FOR_GCC_5 +-# ifdef PIC +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ ++# ifdef PIC ++# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "call *%%gs:%P2" \ + : "=a" (resultvar) \ + : "a" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \ + ASMARGS_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ ++# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "call *%%gs:%P2" \ + : "=a" (resultvar) \ + : "a" (name), "i" (offsetof (tcbhead_t, sysinfo)) \ + ASMARGS_##nr(args) : "memory", "cc") +-# else +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ ++# else /* I386_USE_SYSENTER && !PIC */ ++# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "call *_dl_sysinfo" \ + : "=a" (resultvar) \ + : "a" (__NR_##name) ASMARGS_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ ++# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "call *_dl_sysinfo" \ + : "=a" (resultvar) \ + : "a" (name) ASMARGS_##nr(args) : "memory", "cc") +-# endif +-# else /* GCC 5 */ +-# ifdef PIC +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "movl %1, %%eax\n\t" \ +- "call *%%gs:%P2\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \ +- ASMFMT_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "call *%%gs:%P2\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \ +- ASMFMT_##nr(args) : "memory", "cc") +-# else +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "movl %1, %%eax\n\t" \ +- "call *_dl_sysinfo\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "call *_dl_sysinfo\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "0" (name) ASMFMT_##nr(args) : "memory", "cc") +-# endif +-# endif /* GCC 5 */ +-#else +-# ifdef OPTIMIZE_FOR_GCC_5 +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ ++# endif /* I386_USE_SYSENTER && !PIC */ ++#else /* !I386_USE_SYSENTER */ ++# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "int $0x80" \ + : "=a" (resultvar) \ + : "a" (__NR_##name) ASMARGS_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ ++# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "int $0x80" \ + : "=a" (resultvar) \ + : "a" (name) ASMARGS_##nr(args) : "memory", "cc") +-# else /* GCC 5 */ +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "movl %1, %%eax\n\t" \ +- "int $0x80\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "int $0x80\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "0" (name) ASMFMT_##nr(args) : "memory", "cc") +-# endif /* GCC 5 */ +-#endif +- +-#define LOADARGS_0 +-#ifdef __PIC__ +-# if I386_USE_SYSENTER && defined PIC +-# define LOADARGS_1 \ +- "bpushl .L__X'%k3, %k3\n\t" +-# define LOADARGS_5 \ +- "movl %%ebx, %4\n\t" \ +- "movl %3, %%ebx\n\t" +-# else +-# define LOADARGS_1 \ +- "bpushl .L__X'%k2, %k2\n\t" +-# define LOADARGS_5 \ +- "movl %%ebx, %3\n\t" \ +- "movl %2, %%ebx\n\t" +-# endif +-# define LOADARGS_2 LOADARGS_1 +-# define LOADARGS_3 \ +- "xchgl %%ebx, %%edi\n\t" +-# define LOADARGS_4 LOADARGS_3 +-#else +-# define LOADARGS_1 +-# define LOADARGS_2 +-# define LOADARGS_3 +-# define LOADARGS_4 +-# define LOADARGS_5 +-#endif +- +-#define RESTOREARGS_0 +-#ifdef __PIC__ +-# if I386_USE_SYSENTER && defined PIC +-# define RESTOREARGS_1 \ +- "bpopl .L__X'%k3, %k3\n\t" +-# define RESTOREARGS_5 \ +- "movl %4, %%ebx" +-# else +-# define RESTOREARGS_1 \ +- "bpopl .L__X'%k2, %k2\n\t" +-# define RESTOREARGS_5 \ +- "movl %3, %%ebx" +-# endif +-# define RESTOREARGS_2 RESTOREARGS_1 +-# define RESTOREARGS_3 \ +- "xchgl %%edi, %%ebx\n\t" +-# define RESTOREARGS_4 RESTOREARGS_3 +-#else +-# define RESTOREARGS_1 +-# define RESTOREARGS_2 +-# define RESTOREARGS_3 +-# define RESTOREARGS_4 +-# define RESTOREARGS_5 +-#endif ++#endif /* !I386_USE_SYSENTER */ + +-#ifdef OPTIMIZE_FOR_GCC_5 +-# define LOADREGS_0() +-# define ASMARGS_0() +-# define LOADREGS_1(arg1) \ ++#define LOADREGS_0() ++#define ASMARGS_0() ++#define LOADREGS_1(arg1) \ + LOADREGS_0 () +-# define ASMARGS_1(arg1) \ ++#define ASMARGS_1(arg1) \ + ASMARGS_0 (), "b" ((unsigned int) (arg1)) +-# define LOADREGS_2(arg1, arg2) \ ++#define LOADREGS_2(arg1, arg2) \ + LOADREGS_1 (arg1) +-# define ASMARGS_2(arg1, arg2) \ ++#define ASMARGS_2(arg1, arg2) \ + ASMARGS_1 (arg1), "c" ((unsigned int) (arg2)) +-# define LOADREGS_3(arg1, arg2, arg3) \ ++#define LOADREGS_3(arg1, arg2, arg3) \ + LOADREGS_2 (arg1, arg2) +-# define ASMARGS_3(arg1, arg2, arg3) \ ++#define ASMARGS_3(arg1, arg2, arg3) \ + ASMARGS_2 (arg1, arg2), "d" ((unsigned int) (arg3)) +-# define LOADREGS_4(arg1, arg2, arg3, arg4) \ ++#define LOADREGS_4(arg1, arg2, arg3, arg4) \ + LOADREGS_3 (arg1, arg2, arg3) +-# define ASMARGS_4(arg1, arg2, arg3, arg4) \ ++#define ASMARGS_4(arg1, arg2, arg3, arg4) \ + ASMARGS_3 (arg1, arg2, arg3), "S" ((unsigned int) (arg4)) +-# define LOADREGS_5(arg1, arg2, arg3, arg4, arg5) \ ++#define LOADREGS_5(arg1, arg2, arg3, arg4, arg5) \ + LOADREGS_4 (arg1, arg2, arg3, arg4) +-# define ASMARGS_5(arg1, arg2, arg3, arg4, arg5) \ ++#define ASMARGS_5(arg1, arg2, arg3, arg4, arg5) \ + ASMARGS_4 (arg1, arg2, arg3, arg4), "D" ((unsigned int) (arg5)) +-# define LOADREGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \ +- register unsigned int _a6 asm ("ebp") = (unsigned int) (arg6); \ +- LOADREGS_5 (arg1, arg2, arg3, arg4, arg5) +-# define ASMARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \ +- ASMARGS_5 (arg1, arg2, arg3, arg4, arg5), "r" (_a6) +-#endif /* GCC 5 */ + + #define ASMFMT_0() + #ifdef __PIC__ diff --git a/SOURCES/glibc-upstream-2.34-74.patch b/SOURCES/glibc-upstream-2.34-74.patch new file mode 100644 index 0000000..15d3b62 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-74.patch @@ -0,0 +1,337 @@ +commit 705f1e4606aa78f4e861b4e3346725bf5f083a56 +Author: Joseph Myers +Date: Thu Jan 13 22:18:13 2022 +0000 + + Update syscall lists for Linux 5.16 + + Linux 5.16 has one new syscall, futex_waitv. Update + syscall-names.list and regenerate the arch-syscall.h headers with + build-many-glibcs.py update-syscalls. + + Tested with build-many-glibcs.py. + + (cherry picked from commit 4997a533ae4b51ef66a6b68862b7578a7acb82df) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +index 74a809561a45edc4..9905ebedf298954c 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +@@ -62,6 +62,7 @@ + #define __NR_fsync 82 + #define __NR_ftruncate 46 + #define __NR_futex 98 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +index 6fc0a23504c3b53d..ee8085be69958b25 100644 +--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +@@ -78,6 +78,7 @@ + #define __NR_fsync 95 + #define __NR_ftruncate 130 + #define __NR_futex 394 ++#define __NR_futex_waitv 559 + #define __NR_futimesat 454 + #define __NR_get_kernel_syms 309 + #define __NR_get_mempolicy 430 +diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +index 0c66762bf868a992..1b626d97705d545a 100644 +--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +@@ -65,6 +65,7 @@ + #define __NR_fsync 82 + #define __NR_ftruncate64 46 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +index c41a864c6d530eb0..96ef8db9368e7de4 100644 +--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +@@ -90,6 +90,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 240 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 326 + #define __NR_get_mempolicy 320 + #define __NR_get_robust_list 339 +diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +index 863ffa3e0cd34d3e..96910154ed6a5c1b 100644 +--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +@@ -70,6 +70,7 @@ + #define __NR_ftruncate64 46 + #define __NR_futex 98 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +index 6cf27cd17c1ad0c0..36675fd48e6f50c5 100644 +--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +@@ -87,6 +87,7 @@ + #define __NR_ftruncate64 200 + #define __NR_futex 210 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 279 + #define __NR_get_mempolicy 261 + #define __NR_get_robust_list 290 +diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +index 2512508b7daa8ed2..c86ccbda4681066c 100644 +--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +@@ -94,6 +94,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 240 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 299 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 275 +diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +index 4a0c737369217367..d898bce404955ef0 100644 +--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +@@ -74,6 +74,7 @@ + #define __NR_fsync 1051 + #define __NR_ftruncate 1098 + #define __NR_futex 1230 ++#define __NR_futex_waitv 1473 + #define __NR_futimesat 1285 + #define __NR_get_mempolicy 1260 + #define __NR_get_robust_list 1299 +diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +index e310eb5075fb22d8..fe721b809076abeb 100644 +--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +@@ -93,6 +93,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 235 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 292 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 269 +diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +index b4ecad010c2a6abf..6e10c3661db96a1e 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +@@ -94,6 +94,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 240 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 299 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 275 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +index 7e3d138ba969c57b..26a6d594a2222f15 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +@@ -93,6 +93,7 @@ + #define __NR_ftruncate64 4212 + #define __NR_futex 4238 + #define __NR_futex_time64 4422 ++#define __NR_futex_waitv 4449 + #define __NR_futimesat 4292 + #define __NR_get_kernel_syms 4130 + #define __NR_get_mempolicy 4269 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +index 7e9e232e5256bc89..83e0d49c5e3ca1bc 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +@@ -86,6 +86,7 @@ + #define __NR_ftruncate 6075 + #define __NR_futex 6194 + #define __NR_futex_time64 6422 ++#define __NR_futex_waitv 6449 + #define __NR_futimesat 6255 + #define __NR_get_kernel_syms 6170 + #define __NR_get_mempolicy 6232 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +index f9e7ef72b0aa1749..d6747c542f63202b 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +@@ -78,6 +78,7 @@ + #define __NR_fsync 5072 + #define __NR_ftruncate 5075 + #define __NR_futex 5194 ++#define __NR_futex_waitv 5449 + #define __NR_futimesat 5251 + #define __NR_get_kernel_syms 5170 + #define __NR_get_mempolicy 5228 +diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +index afd73fc1daca1fb4..4ee209bc4475ea7d 100644 +--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +@@ -69,6 +69,7 @@ + #define __NR_ftruncate64 46 + #define __NR_futex 98 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +index 0ac2992028eda27e..497299fbc47a708c 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +@@ -92,6 +92,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 221 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 290 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 260 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +index c890bc644e14fe06..e840279f171b10b9 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +@@ -81,6 +81,7 @@ + #define __NR_ftime 35 + #define __NR_ftruncate 93 + #define __NR_futex 221 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 290 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 260 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index cd336d755a42598a..73ef74c005e5a2bb 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -60,6 +60,7 @@ + #define __NR_fsync 82 + #define __NR_ftruncate64 46 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index 8edd21620bb4ef64..919a79ee91177459 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -62,6 +62,7 @@ + #define __NR_fsync 82 + #define __NR_ftruncate 46 + #define __NR_futex 98 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +index 1a4873f505765617..005c0ada7aab85a1 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +@@ -91,6 +91,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 238 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 292 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 269 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +index 2af4607c1d36d173..9131fddcc16116e4 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +@@ -76,6 +76,7 @@ + #define __NR_fsync 118 + #define __NR_ftruncate 93 + #define __NR_futex 238 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 292 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 269 +diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +index 7b422ce268ba14d0..d8fb041568ecb4da 100644 +--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +@@ -90,6 +90,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 240 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 299 + #define __NR_get_mempolicy 275 + #define __NR_get_robust_list 312 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +index 77c3cc64f95ea7f3..2bc014fe6a1a1f4a 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +@@ -92,6 +92,7 @@ + #define __NR_ftruncate64 84 + #define __NR_futex 142 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 288 + #define __NR_get_kernel_syms 223 + #define __NR_get_mempolicy 304 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +index 7ad50bc4ad6cef04..76dbbe595ffe868f 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +@@ -82,6 +82,7 @@ + #define __NR_fsync 95 + #define __NR_ftruncate 130 + #define __NR_futex 142 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 288 + #define __NR_get_kernel_syms 223 + #define __NR_get_mempolicy 304 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 1a74d090b72f4d61..0bc2af37dfa1eeb5 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.15. +-kernel 5.15 ++# The list of system calls is current as of Linux 5.16. ++kernel 5.16 + + FAST_atomic_update + FAST_cmpxchg +@@ -146,6 +146,7 @@ ftruncate + ftruncate64 + futex + futex_time64 ++futex_waitv + futimesat + get_kernel_syms + get_mempolicy +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +index 3ce2a1fcfc1c15f2..28558279b48a1ef4 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +@@ -78,6 +78,7 @@ + #define __NR_fsync 74 + #define __NR_ftruncate 77 + #define __NR_futex 202 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 261 + #define __NR_get_kernel_syms 177 + #define __NR_get_mempolicy 239 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index 9e87e89baccc397c..c1ab8ec45e8b8fd3 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -74,6 +74,7 @@ + #define __NR_fsync 1073741898 + #define __NR_ftruncate 1073741901 + #define __NR_futex 1073742026 ++#define __NR_futex_waitv 1073742273 + #define __NR_futimesat 1073742085 + #define __NR_get_mempolicy 1073742063 + #define __NR_get_robust_list 1073742355 diff --git a/SOURCES/glibc-upstream-2.34-75.patch b/SOURCES/glibc-upstream-2.34-75.patch new file mode 100644 index 0000000..7fada18 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-75.patch @@ -0,0 +1,53 @@ +commit 03e6e02e6a216cfb913f49b3be80d5088603864f +Author: H.J. Lu +Date: Sun Jan 9 09:06:15 2022 -0800 + + Disable debuginfod in printer tests [BZ #28757] + + With gdb-11.1-6.fc35.x86_64, I got + + FAIL: nptl/test-cond-printers + FAIL: nptl/test-condattr-printers + FAIL: nptl/test-mutex-printers + FAIL: nptl/test-mutexattr-printers + FAIL: nptl/test-rwlock-printers + FAIL: nptl/test-rwlockattr-printers + + $ cat nptl/test-condattr-printers.out + Error: Response does not match the expected pattern. + Command: start + Expected pattern: main + Response: Temporary breakpoint 1 at 0x11d5: file test-condattr-printers.c, line 43. + Starting program: /export/build/gnu/tools-build/glibc-cet-gitlab/build-x86_64-linux/nptl/test-condattr-printers + + This GDB supports auto-downloading debuginfo from the following URLs: + https://debuginfod.fedoraproject.org/ + Enable debuginfod for this session? (y or [n]) + + Disable debuginfod to avoid GDB messages. This fixes BZ #28757. + + Reviewed-by: Florian Weimer + (cherry picked from commit 7de501f9418bf099e7104b63b0e4423257981b14) + +diff --git a/scripts/test_printers_common.py b/scripts/test_printers_common.py +index 34a3df6e6bd8b363..53b6d30d40ce2622 100644 +--- a/scripts/test_printers_common.py ++++ b/scripts/test_printers_common.py +@@ -161,6 +161,17 @@ def init_test(test_bin, printer_files, printer_names): + printer files. + """ + ++ # Disable debuginfod to avoid GDB messages like: ++ # ++ # This GDB supports auto-downloading debuginfo from the following URLs: ++ # https://debuginfod.fedoraproject.org/ ++ # Enable debuginfod for this session? (y or [n]) ++ # ++ try: ++ test('set debuginfod enabled off') ++ except Exception: ++ pass ++ + # Load all the pretty printer files. We're assuming these are safe. + for printer_file in printer_files: + test('source {0}'.format(printer_file)) diff --git a/SOURCES/glibc-upstream-2.34-76.patch b/SOURCES/glibc-upstream-2.34-76.patch new file mode 100644 index 0000000..3d669c3 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-76.patch @@ -0,0 +1,165 @@ +commit 5575daae5099e779bb860b566b4d608418a5b832 +Author: Florian Weimer +Date: Mon Jan 17 10:21:34 2022 +0100 + + socket: Add the __sockaddr_un_set function + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit e368b12f6c16b6888dda99ba641e999b9c9643c8) + +diff --git a/include/sys/un.h b/include/sys/un.h +index bdbee999806930f4..152afd9fc7426d8b 100644 +--- a/include/sys/un.h ++++ b/include/sys/un.h +@@ -1 +1,13 @@ + #include ++ ++#ifndef _ISOMAC ++ ++/* Set ADDR->sun_family to AF_UNIX and ADDR->sun_path to PATHNAME. ++ Return 0 on success or -1 on failure (due to overlong PATHNAME). ++ The caller should always use sizeof (struct sockaddr_un) as the ++ socket address length, disregaring the length of PATHNAME. ++ Only concrete (non-abstract) pathnames are supported. */ ++int __sockaddr_un_set (struct sockaddr_un *addr, const char *pathname) ++ attribute_hidden; ++ ++#endif /* _ISOMAC */ +diff --git a/socket/Makefile b/socket/Makefile +index 375957601024c12e..c2de11d73ca1e324 100644 +--- a/socket/Makefile ++++ b/socket/Makefile +@@ -29,13 +29,17 @@ headers := sys/socket.h sys/un.h bits/sockaddr.h bits/socket.h \ + routines := accept bind connect getpeername getsockname getsockopt \ + listen recv recvfrom recvmsg send sendmsg sendto \ + setsockopt shutdown socket socketpair isfdtype opensock \ +- sockatmark accept4 recvmmsg sendmmsg ++ sockatmark accept4 recvmmsg sendmmsg sockaddr_un_set + + tests := \ + tst-accept4 \ + tst-sockopt \ + # tests + ++tests-internal := \ ++ tst-sockaddr_un_set \ ++ # tests-internal ++ + tests-time64 := \ + tst-sockopt-time64 \ + # tests +diff --git a/socket/sockaddr_un_set.c b/socket/sockaddr_un_set.c +new file mode 100644 +index 0000000000000000..0bd40dc34e3d7efc +--- /dev/null ++++ b/socket/sockaddr_un_set.c +@@ -0,0 +1,41 @@ ++/* Set the sun_path member of struct sockaddr_un. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++int ++__sockaddr_un_set (struct sockaddr_un *addr, const char *pathname) ++{ ++ size_t name_length = strlen (pathname); ++ ++ /* The kernel supports names of exactly sizeof (addr->sun_path) ++ bytes, without a null terminator, but userspace does not; see the ++ SUN_LEN macro. */ ++ if (name_length >= sizeof (addr->sun_path)) ++ { ++ __set_errno (EINVAL); /* Error code used by the kernel. */ ++ return -1; ++ } ++ ++ addr->sun_family = AF_UNIX; ++ memcpy (addr->sun_path, pathname, name_length + 1); ++ return 0; ++} +diff --git a/socket/tst-sockaddr_un_set.c b/socket/tst-sockaddr_un_set.c +new file mode 100644 +index 0000000000000000..29c2a81afda81b5e +--- /dev/null ++++ b/socket/tst-sockaddr_un_set.c +@@ -0,0 +1,62 @@ ++/* Test the __sockaddr_un_set function. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Re-compile the function because the version in libc is not ++ exported. */ ++#include "sockaddr_un_set.c" ++ ++#include ++ ++static int ++do_test (void) ++{ ++ struct sockaddr_un sun; ++ ++ memset (&sun, 0xcc, sizeof (sun)); ++ __sockaddr_un_set (&sun, ""); ++ TEST_COMPARE (sun.sun_family, AF_UNIX); ++ TEST_COMPARE (__sockaddr_un_set (&sun, ""), 0); ++ ++ memset (&sun, 0xcc, sizeof (sun)); ++ TEST_COMPARE (__sockaddr_un_set (&sun, "/example"), 0); ++ TEST_COMPARE_STRING (sun.sun_path, "/example"); ++ ++ { ++ char pathname[108]; /* Length of sun_path (ABI constant). */ ++ memset (pathname, 'x', sizeof (pathname)); ++ pathname[sizeof (pathname) - 1] = '\0'; ++ memset (&sun, 0xcc, sizeof (sun)); ++ TEST_COMPARE (__sockaddr_un_set (&sun, pathname), 0); ++ TEST_COMPARE (sun.sun_family, AF_UNIX); ++ TEST_COMPARE_STRING (sun.sun_path, pathname); ++ } ++ ++ { ++ char pathname[109]; ++ memset (pathname, 'x', sizeof (pathname)); ++ pathname[sizeof (pathname) - 1] = '\0'; ++ memset (&sun, 0xcc, sizeof (sun)); ++ errno = 0; ++ TEST_COMPARE (__sockaddr_un_set (&sun, pathname), -1); ++ TEST_COMPARE (errno, EINVAL); ++ } ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-77.patch b/SOURCES/glibc-upstream-2.34-77.patch new file mode 100644 index 0000000..752a81a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-77.patch @@ -0,0 +1,33 @@ +commit 7b5d433fd097b8ed74e458eca33597290e07b974 +Author: Florian Weimer +Date: Mon Jan 17 10:21:34 2022 +0100 + + CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542) + + Processing an overlong pathname in the sunrpc clnt_create function + results in a stack-based buffer overflow. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 226b46770c82899b555986583294b049c6ec9b40) + +diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c +index 13ced8994e49d4ee..b44357cd88e60599 100644 +--- a/sunrpc/clnt_gen.c ++++ b/sunrpc/clnt_gen.c +@@ -57,9 +57,13 @@ clnt_create (const char *hostname, u_long prog, u_long vers, + + if (strcmp (proto, "unix") == 0) + { +- memset ((char *)&sun, 0, sizeof (sun)); +- sun.sun_family = AF_UNIX; +- strcpy (sun.sun_path, hostname); ++ if (__sockaddr_un_set (&sun, hostname) < 0) ++ { ++ struct rpc_createerr *ce = &get_rpc_createerr (); ++ ce->cf_stat = RPC_SYSTEMERROR; ++ ce->cf_error.re_errno = errno; ++ return NULL; ++ } + sock = RPC_ANYSOCK; + client = clntunix_create (&sun, prog, vers, &sock, 0, 0); + if (client == NULL) diff --git a/SOURCES/glibc-upstream-2.34-78.patch b/SOURCES/glibc-upstream-2.34-78.patch new file mode 100644 index 0000000..cfd76f0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-78.patch @@ -0,0 +1,82 @@ +commit 1081f1d3dd7c84ba3416b5198d47a4df2b70185d +Author: Martin Sebor +Date: Mon Jan 17 10:21:34 2022 +0100 + + sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542) + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit ef972a4c50014a16132b5c75571cfb6b30bef136) + +diff --git a/sunrpc/Makefile b/sunrpc/Makefile +index 7e5bbfd951b1e835..a4281b18d04c78e9 100644 +--- a/sunrpc/Makefile ++++ b/sunrpc/Makefile +@@ -65,7 +65,8 @@ shared-only-routines = $(routines) + endif + + tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \ +- tst-udp-nonblocking ++ tst-udp-nonblocking tst-bug22542 ++ + xtests := tst-getmyaddr + + ifeq ($(have-thread-library),yes) +@@ -110,6 +111,8 @@ $(objpfx)tst-udp-nonblocking: $(common-objpfx)linkobj/libc.so + $(objpfx)tst-udp-garbage: \ + $(common-objpfx)linkobj/libc.so $(shared-thread-library) + ++$(objpfx)tst-bug22542: $(common-objpfx)linkobj/libc.so ++ + else # !have-GLIBC_2.31 + + routines = $(routines-for-nss) +diff --git a/sunrpc/tst-bug22542.c b/sunrpc/tst-bug22542.c +new file mode 100644 +index 0000000000000000..d6cd79787bdef21d +--- /dev/null ++++ b/sunrpc/tst-bug22542.c +@@ -0,0 +1,44 @@ ++/* Test to verify that overlong hostname is rejected by clnt_create ++ and doesn't cause a buffer overflow (bug 22542). ++ ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ /* Create an arbitrary hostname that's longer than fits in sun_path. */ ++ char name [sizeof ((struct sockaddr_un*)0)->sun_path * 2]; ++ memset (name, 'x', sizeof name - 1); ++ name [sizeof name - 1] = '\0'; ++ ++ errno = 0; ++ CLIENT *clnt = clnt_create (name, 0, 0, "unix"); ++ ++ TEST_VERIFY (clnt == NULL); ++ TEST_COMPARE (errno, EINVAL); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-79.patch b/SOURCES/glibc-upstream-2.34-79.patch new file mode 100644 index 0000000..84f34f8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-79.patch @@ -0,0 +1,102 @@ +commit 6890b8a3ae40ab9d4c96024ab95b04816fcc8a4a +Author: Florian Weimer +Date: Mon Jan 17 11:49:25 2022 +0100 + + CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768) + + The sunrpc function svcunix_create suffers from a stack-based buffer + overflow with overlong pathname arguments. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit f545ad4928fa1f27a3075265182b38a4f939a5f7) + +diff --git a/sunrpc/Makefile b/sunrpc/Makefile +index a4281b18d04c78e9..6408ab5c073538e9 100644 +--- a/sunrpc/Makefile ++++ b/sunrpc/Makefile +@@ -65,7 +65,7 @@ shared-only-routines = $(routines) + endif + + tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \ +- tst-udp-nonblocking tst-bug22542 ++ tst-udp-nonblocking tst-bug22542 tst-bug28768 + + xtests := tst-getmyaddr + +diff --git a/sunrpc/svc_unix.c b/sunrpc/svc_unix.c +index 679fbe9cb69587bd..46f8d16fe94a3d4f 100644 +--- a/sunrpc/svc_unix.c ++++ b/sunrpc/svc_unix.c +@@ -154,7 +154,10 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path) + SVCXPRT *xprt; + struct unix_rendezvous *r; + struct sockaddr_un addr; +- socklen_t len = sizeof (struct sockaddr_in); ++ socklen_t len = sizeof (addr); ++ ++ if (__sockaddr_un_set (&addr, path) < 0) ++ return NULL; + + if (sock == RPC_ANYSOCK) + { +@@ -165,12 +168,6 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path) + } + madesock = TRUE; + } +- memset (&addr, '\0', sizeof (addr)); +- addr.sun_family = AF_UNIX; +- len = strlen (path) + 1; +- memcpy (addr.sun_path, path, len); +- len += sizeof (addr.sun_family); +- + __bind (sock, (struct sockaddr *) &addr, len); + + if (__getsockname (sock, (struct sockaddr *) &addr, &len) != 0 +diff --git a/sunrpc/tst-bug28768.c b/sunrpc/tst-bug28768.c +new file mode 100644 +index 0000000000000000..35a4b7b0b3d34350 +--- /dev/null ++++ b/sunrpc/tst-bug28768.c +@@ -0,0 +1,42 @@ ++/* Test to verify that long path is rejected by svcunix_create (bug 28768). ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* svcunix_create does not have a default version in linkobj/libc.so. */ ++compat_symbol_reference (libc, svcunix_create, svcunix_create, GLIBC_2_1); ++ ++static int ++do_test (void) ++{ ++ char pathname[109]; ++ memset (pathname, 'x', sizeof (pathname)); ++ pathname[sizeof (pathname) - 1] = '\0'; ++ ++ errno = 0; ++ TEST_VERIFY (svcunix_create (RPC_ANYSOCK, 4096, 4096, pathname) == NULL); ++ TEST_COMPARE (errno, EINVAL); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-8.patch b/SOURCES/glibc-upstream-2.34-8.patch new file mode 100644 index 0000000..b08f0ce --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-8.patch @@ -0,0 +1,140 @@ +commit 7c987a5ccb31df80456d53a094e47f81310f549b +Author: Nikita Popov +Date: Thu Aug 12 16:09:50 2021 +0530 + + librt: add test (bug 28213) + + This test implements following logic: + 1) Create POSIX message queue. + Register a notification with mq_notify (using NULL attributes). + Then immediately unregister the notification with mq_notify. + Helper thread in a vulnerable version of glibc + should cause NULL pointer dereference after these steps. + 2) Once again, register the same notification. + Try to send a dummy message. + Test is considered successfulif the dummy message + is successfully received by the callback function. + + Signed-off-by: Nikita Popov + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 4cc79c217744743077bf7a0ec5e0a4318f1e6641) + +diff --git a/rt/Makefile b/rt/Makefile +index 113cea03a5b75613..910e7759956d7ae9 100644 +--- a/rt/Makefile ++++ b/rt/Makefile +@@ -74,6 +74,7 @@ tests := tst-shm tst-timer tst-timer2 \ + tst-aio7 tst-aio8 tst-aio9 tst-aio10 \ + tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \ + tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \ ++ tst-bz28213 \ + tst-timer3 tst-timer4 tst-timer5 \ + tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \ + tst-shm-cancel \ +diff --git a/rt/tst-bz28213.c b/rt/tst-bz28213.c +new file mode 100644 +index 0000000000000000..0c096b5a0ad4170a +--- /dev/null ++++ b/rt/tst-bz28213.c +@@ -0,0 +1,101 @@ ++/* Bug 28213: test for NULL pointer dereference in mq_notify. ++ Copyright (C) The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static mqd_t m = -1; ++static const char msg[] = "hello"; ++ ++static void ++check_bz28213_cb (union sigval sv) ++{ ++ char buf[sizeof (msg)]; ++ ++ (void) sv; ++ ++ TEST_VERIFY_EXIT ((size_t) mq_receive (m, buf, sizeof (buf), NULL) ++ == sizeof (buf)); ++ TEST_VERIFY_EXIT (memcmp (buf, msg, sizeof (buf)) == 0); ++ ++ exit (0); ++} ++ ++static void ++check_bz28213 (void) ++{ ++ struct sigevent sev; ++ ++ memset (&sev, '\0', sizeof (sev)); ++ sev.sigev_notify = SIGEV_THREAD; ++ sev.sigev_notify_function = check_bz28213_cb; ++ ++ /* Step 1: Register & unregister notifier. ++ Helper thread should receive NOTIFY_REMOVED notification. ++ In a vulnerable version of glibc, NULL pointer dereference follows. */ ++ TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0); ++ TEST_VERIFY_EXIT (mq_notify (m, NULL) == 0); ++ ++ /* Step 2: Once again, register notification. ++ Try to send one message. ++ Test is considered successful, if the callback does exit (0). */ ++ TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0); ++ TEST_VERIFY_EXIT (mq_send (m, msg, sizeof (msg), 1) == 0); ++ ++ /* Wait... */ ++ pause (); ++} ++ ++static int ++do_test (void) ++{ ++ static const char m_name[] = "/bz28213_queue"; ++ struct mq_attr m_attr; ++ ++ memset (&m_attr, '\0', sizeof (m_attr)); ++ m_attr.mq_maxmsg = 1; ++ m_attr.mq_msgsize = sizeof (msg); ++ ++ m = mq_open (m_name, ++ O_RDWR | O_CREAT | O_EXCL, ++ 0600, ++ &m_attr); ++ ++ if (m < 0) ++ { ++ if (errno == ENOSYS) ++ FAIL_UNSUPPORTED ("POSIX message queues are not implemented\n"); ++ FAIL_EXIT1 ("Failed to create POSIX message queue: %m\n"); ++ } ++ ++ TEST_VERIFY_EXIT (mq_unlink (m_name) == 0); ++ ++ check_bz28213 (); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-80.patch b/SOURCES/glibc-upstream-2.34-80.patch new file mode 100644 index 0000000..fec92e2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-80.patch @@ -0,0 +1,56 @@ +commit 1d401d1fccb85046402089268b94d86d822070e6 +Author: Aurelien Jarno +Date: Mon Jan 17 19:41:40 2022 +0100 + + x86: use default cache size if it cannot be determined [BZ #28784] + + In some cases (e.g QEMU, non-Intel/AMD CPU) the cache information can + not be retrieved and the corresponding values are set to 0. + + Commit 2d651eb9265d ("x86: Move x86 processor cache info to + cpu_features") changed the behaviour in such case by defining the + __x86_shared_cache_size and __x86_data_cache_size variables to 0 instead + of using the default values. This cause an issue with the i686 SSE2 + optimized bzero/routine which assumes that the cache size is at least + 128 bytes, and otherwise tries to zero/set the whole address space minus + 128 bytes. + + Fix that by restoring the original code to only update + __x86_shared_cache_size and __x86_data_cache_size variables if the + corresponding cache sizes are not zero. + + Fixes bug 28784 + Fixes commit 2d651eb9265d + + Reviewed-by: H.J. Lu + (cherry picked from commit c242fcce06e3102ca663b2f992611d0bda4f2668) + +diff --git a/sysdeps/x86/cacheinfo.h b/sysdeps/x86/cacheinfo.h +index 41d2c81369840ada..63f36877e3f35d99 100644 +--- a/sysdeps/x86/cacheinfo.h ++++ b/sysdeps/x86/cacheinfo.h +@@ -61,14 +61,20 @@ init_cacheinfo (void) + long int data = cpu_features->data_cache_size; + /* Round data cache size to multiple of 256 bytes. */ + data = data & ~255L; +- __x86_data_cache_size_half = data / 2; +- __x86_data_cache_size = data; ++ if (data > 0) ++ { ++ __x86_data_cache_size_half = data / 2; ++ __x86_data_cache_size = data; ++ } + + long int shared = cpu_features->shared_cache_size; + /* Round shared cache size to multiple of 256 bytes. */ + shared = shared & ~255L; +- __x86_shared_cache_size_half = shared / 2; +- __x86_shared_cache_size = shared; ++ if (shared > 0) ++ { ++ __x86_shared_cache_size_half = shared / 2; ++ __x86_shared_cache_size = shared; ++ } + + __x86_shared_non_temporal_threshold + = cpu_features->non_temporal_threshold; diff --git a/SOURCES/glibc-upstream-2.34-81.patch b/SOURCES/glibc-upstream-2.34-81.patch new file mode 100644 index 0000000..3fcbbf4 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-81.patch @@ -0,0 +1,64 @@ +commit 82b1acd9de9796298a230d7484f26fe9a7756d18 +Author: Paul A. Clarke +Date: Sat Sep 25 09:57:15 2021 -0500 + + powerpc: Fix unrecognized instruction errors with recent binutils + + Recent versions of binutils (with commit + b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a) stopped preserving "sticky" + options across a base `.machine` directive, nullifying the use of + passing "-many" through GCC to the assembler. As a result, some + instructions which were recognized even under older, more stringent + `.machine` directives become unrecognized instructions in that + context. + + In `sysdeps/powerpc/tst-set_ppr.c`, the use of the `mfppr32` extended + mnemonic became unrecognized, as the default compilation with GCC for + 32bit powerpc adds a `.machine ppc` in the resulting assembly, so the + command line option `-Wa,-many` is essentially ignored, and the ISA 2.06 + instructions and mnemonics, like `mfppr32`, are unrecognized. + + The compilation of `sysdeps/powerpc/tst-set_ppr.c` fails with: + Error: unrecognized opcode: `mfppr32' + + Add appropriate `.machine` directives in the assembly to bracket the + `mfppr32` instruction. + + Part of a 2019 fix (commit 9250e6610fdb0f3a6f238d2813e319a41fb7a810) to + the above test's Makefile to add `-many` to the compilation when GCC + itself stopped passing `-many` to the assember no longer has any effect, + so remove that. + + Reported-by: Joseph Myers + (cherry picked from commit ee874f44fd55988808a4a162ef21bfa2cc8dc6f7) + +diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile +index 09860ffc0155d765..5e6cb07ce66decfa 100644 +--- a/sysdeps/powerpc/Makefile ++++ b/sysdeps/powerpc/Makefile +@@ -61,11 +61,6 @@ ifeq ($(subdir),misc) + sysdep_headers += sys/platform/ppc.h + tests += test-gettimebase + tests += tst-set_ppr +- +-# This test is expected to run and exit with EXIT_UNSUPPORTED on +-# processors that do not implement the Power ISA 2.06 or greater. +-# But the test makes use of instructions from Power ISA 2.06 and 2.07. +-CFLAGS-tst-set_ppr.c += -Wa,-many + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/powerpc/tst-set_ppr.c b/sysdeps/powerpc/tst-set_ppr.c +index 7684f5d6ea905c60..e80da15320635585 100644 +--- a/sysdeps/powerpc/tst-set_ppr.c ++++ b/sysdeps/powerpc/tst-set_ppr.c +@@ -44,7 +44,8 @@ get_thread_priority (void) + { + /* Read the PPR. */ + ppr_t ppr; +- asm volatile (MFPPR" %0" : "=r"(ppr)); ++ asm volatile (".machine push; .machine power7; "MFPPR" %0; .machine pop" ++ : "=r"(ppr)); + /* Return the thread priority value. */ + return EXTRACT_THREAD_PRIORITY (ppr); + } diff --git a/SOURCES/glibc-upstream-2.34-82.patch b/SOURCES/glibc-upstream-2.34-82.patch new file mode 100644 index 0000000..1f522aa --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-82.patch @@ -0,0 +1,276 @@ +commit 062ff490c1467059f6cd64bb9c3d85f6cc6cf97a +Author: Siddhesh Poyarekar +Date: Tue Jan 18 13:29:36 2022 +0530 + + support: Add helpers to create paths longer than PATH_MAX + + Add new helpers support_create_and_chdir_toolong_temp_directory and + support_chdir_toolong_temp_directory to create and descend into + directory trees longer than PATH_MAX. + + Reviewed-by: Adhemerval Zanella + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit fb7bff12e81c677a6622f724edd4d4987dd9d971) + +diff --git a/support/temp_file.c b/support/temp_file.c +index c6df641876285bb2..e41128c2d43fe903 100644 +--- a/support/temp_file.c ++++ b/support/temp_file.c +@@ -1,5 +1,6 @@ + /* Temporary file handling for tests. +- Copyright (C) 1998-2021 Free Software Foundation, Inc. ++ Copyright (C) 1998-2022 Free Software Foundation, Inc. ++ Copyright The GNU Tools Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -20,15 +21,17 @@ + some 32-bit platforms. */ + #define _FILE_OFFSET_BITS 64 + ++#include + #include + #include + #include + ++#include + #include + #include + #include + #include +-#include ++#include + + /* List of temporary files. */ + static struct temp_name_list +@@ -36,14 +39,20 @@ static struct temp_name_list + struct temp_name_list *next; + char *name; + pid_t owner; ++ bool toolong; + } *temp_name_list; + + /* Location of the temporary files. Set by the test skeleton via + support_set_test_dir. The string is not be freed. */ + static const char *test_dir = _PATH_TMP; + +-void +-add_temp_file (const char *name) ++/* Name of subdirectories in a too long temporary directory tree. */ ++static char toolong_subdir[NAME_MAX + 1]; ++static bool toolong_initialized; ++static size_t toolong_path_max; ++ ++static void ++add_temp_file_internal (const char *name, bool toolong) + { + struct temp_name_list *newp + = (struct temp_name_list *) xcalloc (sizeof (*newp), 1); +@@ -53,12 +62,19 @@ add_temp_file (const char *name) + newp->name = newname; + newp->next = temp_name_list; + newp->owner = getpid (); ++ newp->toolong = toolong; + temp_name_list = newp; + } + else + free (newp); + } + ++void ++add_temp_file (const char *name) ++{ ++ add_temp_file_internal (name, false); ++} ++ + int + create_temp_file_in_dir (const char *base, const char *dir, char **filename) + { +@@ -90,8 +106,8 @@ create_temp_file (const char *base, char **filename) + return create_temp_file_in_dir (base, test_dir, filename); + } + +-char * +-support_create_temp_directory (const char *base) ++static char * ++create_temp_directory_internal (const char *base, bool toolong) + { + char *path = xasprintf ("%s/%sXXXXXX", test_dir, base); + if (mkdtemp (path) == NULL) +@@ -99,16 +115,132 @@ support_create_temp_directory (const char *base) + printf ("error: mkdtemp (\"%s\"): %m", path); + exit (1); + } +- add_temp_file (path); ++ add_temp_file_internal (path, toolong); + return path; + } + +-/* Helper functions called by the test skeleton follow. */ ++char * ++support_create_temp_directory (const char *base) ++{ ++ return create_temp_directory_internal (base, false); ++} ++ ++static void ++ensure_toolong_initialized (void) ++{ ++ if (!toolong_initialized) ++ FAIL_EXIT1 ("uninitialized toolong directory tree\n"); ++} ++ ++static void ++initialize_toolong (const char *base) ++{ ++ long name_max = pathconf (base, _PC_NAME_MAX); ++ name_max = (name_max < 0 ? 64 ++ : (name_max < sizeof (toolong_subdir) ? name_max ++ : sizeof (toolong_subdir) - 1)); ++ ++ long path_max = pathconf (base, _PC_PATH_MAX); ++ path_max = (path_max < 0 ? 1024 ++ : path_max <= PTRDIFF_MAX ? path_max : PTRDIFF_MAX); ++ ++ /* Sanity check to ensure that the test does not create temporary directories ++ in different filesystems because this API doesn't support it. */ ++ if (toolong_initialized) ++ { ++ if (name_max != strlen (toolong_subdir)) ++ FAIL_UNSUPPORTED ("name_max: Temporary directories in different" ++ " filesystems not supported yet\n"); ++ if (path_max != toolong_path_max) ++ FAIL_UNSUPPORTED ("path_max: Temporary directories in different" ++ " filesystems not supported yet\n"); ++ return; ++ } ++ ++ toolong_path_max = path_max; ++ ++ size_t len = name_max; ++ memset (toolong_subdir, 'X', len); ++ toolong_initialized = true; ++} ++ ++char * ++support_create_and_chdir_toolong_temp_directory (const char *basename) ++{ ++ char *base = create_temp_directory_internal (basename, true); ++ xchdir (base); ++ ++ initialize_toolong (base); ++ ++ size_t sz = strlen (toolong_subdir); ++ ++ /* Create directories and descend into them so that the final path is larger ++ than PATH_MAX. */ ++ for (size_t i = 0; i <= toolong_path_max / sz; i++) ++ { ++ int ret = mkdir (toolong_subdir, S_IRWXU); ++ if (ret != 0 && errno == ENAMETOOLONG) ++ FAIL_UNSUPPORTED ("Filesystem does not support creating too long " ++ "directory trees\n"); ++ else if (ret != 0) ++ FAIL_EXIT1 ("Failed to create directory tree: %m\n"); ++ xchdir (toolong_subdir); ++ } ++ return base; ++} + + void +-support_set_test_dir (const char *path) ++support_chdir_toolong_temp_directory (const char *base) + { +- test_dir = path; ++ ensure_toolong_initialized (); ++ ++ xchdir (base); ++ ++ size_t sz = strlen (toolong_subdir); ++ for (size_t i = 0; i <= toolong_path_max / sz; i++) ++ xchdir (toolong_subdir); ++} ++ ++/* Helper functions called by the test skeleton follow. */ ++ ++static void ++remove_toolong_subdirs (const char *base) ++{ ++ ensure_toolong_initialized (); ++ ++ if (chdir (base) != 0) ++ { ++ printf ("warning: toolong cleanup base failed: chdir (\"%s\"): %m\n", ++ base); ++ return; ++ } ++ ++ /* Descend. */ ++ int levels = 0; ++ size_t sz = strlen (toolong_subdir); ++ for (levels = 0; levels <= toolong_path_max / sz; levels++) ++ if (chdir (toolong_subdir) != 0) ++ { ++ printf ("warning: toolong cleanup failed: chdir (\"%s\"): %m\n", ++ toolong_subdir); ++ break; ++ } ++ ++ /* Ascend and remove. */ ++ while (--levels >= 0) ++ { ++ if (chdir ("..") != 0) ++ { ++ printf ("warning: toolong cleanup failed: chdir (\"..\"): %m\n"); ++ return; ++ } ++ if (remove (toolong_subdir) != 0) ++ { ++ printf ("warning: could not remove subdirectory: %s: %m\n", ++ toolong_subdir); ++ return; ++ } ++ } + } + + void +@@ -123,6 +255,9 @@ support_delete_temp_files (void) + around, to prevent PID reuse.) */ + if (temp_name_list->owner == pid) + { ++ if (temp_name_list->toolong) ++ remove_toolong_subdirs (temp_name_list->name); ++ + if (remove (temp_name_list->name) != 0) + printf ("warning: could not remove temporary file: %s: %m\n", + temp_name_list->name); +@@ -147,3 +282,9 @@ support_print_temp_files (FILE *f) + fprintf (f, ")\n"); + } + } ++ ++void ++support_set_test_dir (const char *path) ++{ ++ test_dir = path; ++} +diff --git a/support/temp_file.h b/support/temp_file.h +index f3a7fb6f9ca44d19..a22964c6fa11abd2 100644 +--- a/support/temp_file.h ++++ b/support/temp_file.h +@@ -44,6 +44,15 @@ int create_temp_file_in_dir (const char *base, const char *dir, + returns. The caller should free this string. */ + char *support_create_temp_directory (const char *base); + ++/* Create a temporary directory tree that is longer than PATH_MAX and schedule ++ it for deletion. BASENAME is used as a prefix for the unique directory ++ name, which the function returns. The caller should free this string. */ ++char *support_create_and_chdir_toolong_temp_directory (const char *basename); ++ ++/* Change into the innermost directory of the directory tree BASE, which was ++ created using support_create_and_chdir_toolong_temp_directory. */ ++void support_chdir_toolong_temp_directory (const char *base); ++ + __END_DECLS + + #endif /* SUPPORT_TEMP_FILE_H */ diff --git a/SOURCES/glibc-upstream-2.34-83.patch b/SOURCES/glibc-upstream-2.34-83.patch new file mode 100644 index 0000000..4a37c4d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-83.patch @@ -0,0 +1,121 @@ +commit 269eb9d930546ce57e83b56c44c430f154684a23 +Author: Siddhesh Poyarekar +Date: Thu Jan 13 10:34:37 2022 +0530 + + stdlib: Sort tests in Makefile + + Put one test per line and sort them. + + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 5b766603efa727c236a5f0cdcf09b71ff60b7584) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 7c15549cafa8e397..6a1c3580bd1648ee 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -65,30 +65,81 @@ aux = grouping groupingwc tens_in_limb + static-only-routines = atexit at_quick_exit + + test-srcs := tst-fmtmsg +-tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ +- test-canon test-canon2 tst-strtoll tst-environ \ +- tst-xpg-basename tst-random tst-random2 tst-bsearch \ +- tst-limits tst-rand48 bug-strtod tst-setcontext \ +- tst-setcontext2 test-a64l tst-qsort testmb2 \ +- bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 \ +- tst-rand48-2 tst-makecontext tst-strtod5 \ +- tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \ +- tst-makecontext3 bug-getcontext bug-fmtmsg1 \ +- tst-secure-getenv tst-strtod-overflow tst-strtod-round \ +- tst-tininess tst-strtod-underflow tst-setcontext3 \ +- tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l \ +- tst-quick_exit tst-thread-quick_exit tst-width \ +- tst-width-stdint tst-strfrom tst-strfrom-locale \ +- tst-getrandom tst-atexit tst-at_quick_exit \ +- tst-cxa_atexit tst-on_exit test-atexit-race \ +- test-at_quick_exit-race test-cxa_atexit-race \ +- test-cxa_atexit-race2 \ +- test-on_exit-race test-dlclose-exit-race \ +- tst-makecontext-align test-bz22786 tst-strtod-nan-sign \ +- tst-swapcontext1 tst-setcontext4 tst-setcontext5 \ +- tst-setcontext6 tst-setcontext7 tst-setcontext8 \ +- tst-setcontext9 tst-bz20544 tst-canon-bz26341 \ +- tst-realpath ++tests := bug-fmtmsg1 \ ++ bug-getcontext \ ++ bug-strtod \ ++ bug-strtod2 \ ++ test-a64l \ ++ test-at_quick_exit-race \ ++ test-atexit-race \ ++ test-bz22786 \ ++ test-canon \ ++ test-canon2 \ ++ test-cxa_atexit-race \ ++ test-cxa_atexit-race2 \ ++ test-dlclose-exit-race \ ++ test-on_exit-race \ ++ testdiv \ ++ testmb \ ++ testmb2 \ ++ testrand \ ++ testsort \ ++ tst-at_quick_exit \ ++ tst-atexit \ ++ tst-atof1 \ ++ tst-atof2 \ ++ tst-bsearch \ ++ tst-bz20544 \ ++ tst-canon-bz26341 \ ++ tst-cxa_atexit \ ++ tst-environ \ ++ tst-getrandom \ ++ tst-limits \ ++ tst-makecontext \ ++ tst-makecontext-align \ ++ tst-makecontext2 \ ++ tst-makecontext3 \ ++ tst-on_exit \ ++ tst-qsort \ ++ tst-qsort2 \ ++ tst-quick_exit \ ++ tst-rand48 \ ++ tst-rand48-2 \ ++ tst-random \ ++ tst-random2 \ ++ tst-realpath \ ++ tst-secure-getenv \ ++ tst-setcontext \ ++ tst-setcontext2 \ ++ tst-setcontext3 \ ++ tst-setcontext4 \ ++ tst-setcontext5 \ ++ tst-setcontext6 \ ++ tst-setcontext7 \ ++ tst-setcontext8 \ ++ tst-setcontext9 \ ++ tst-strfmon_l \ ++ tst-strfrom \ ++ tst-strfrom-locale \ ++ tst-strtod \ ++ tst-strtod-nan-locale \ ++ tst-strtod-nan-sign \ ++ tst-strtod-overflow \ ++ tst-strtod-round \ ++ tst-strtod-underflow \ ++ tst-strtod2 \ ++ tst-strtod5 \ ++ tst-strtod6 \ ++ tst-strtol \ ++ tst-strtol-locale \ ++ tst-strtoll \ ++ tst-swapcontext1 \ ++ tst-thread-quick_exit \ ++ tst-tininess \ ++ tst-unsetenv1 \ ++ tst-width \ ++ tst-width-stdint \ ++ tst-xpg-basename + + tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ + tst-tls-atexit tst-tls-atexit-nodelete diff --git a/SOURCES/glibc-upstream-2.34-84.patch b/SOURCES/glibc-upstream-2.34-84.patch new file mode 100644 index 0000000..e97805a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-84.patch @@ -0,0 +1,173 @@ +commit 73c362840c4efde45125a6c27bf41726397f4038 +Author: Siddhesh Poyarekar +Date: Thu Jan 13 18:50:55 2022 +0530 + + stdlib: Fix formatting of tests list in Makefile + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Florian Weimer + (cherry picked from commit f9dab1b5f23d0fb008a56c7c6c8919adb49d3611) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 6a1c3580bd1648ee..9bb5c221e8be3288 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -65,81 +65,83 @@ aux = grouping groupingwc tens_in_limb + static-only-routines = atexit at_quick_exit + + test-srcs := tst-fmtmsg +-tests := bug-fmtmsg1 \ +- bug-getcontext \ +- bug-strtod \ +- bug-strtod2 \ +- test-a64l \ +- test-at_quick_exit-race \ +- test-atexit-race \ +- test-bz22786 \ +- test-canon \ +- test-canon2 \ +- test-cxa_atexit-race \ +- test-cxa_atexit-race2 \ +- test-dlclose-exit-race \ +- test-on_exit-race \ +- testdiv \ +- testmb \ +- testmb2 \ +- testrand \ +- testsort \ +- tst-at_quick_exit \ +- tst-atexit \ +- tst-atof1 \ +- tst-atof2 \ +- tst-bsearch \ +- tst-bz20544 \ +- tst-canon-bz26341 \ +- tst-cxa_atexit \ +- tst-environ \ +- tst-getrandom \ +- tst-limits \ +- tst-makecontext \ +- tst-makecontext-align \ +- tst-makecontext2 \ +- tst-makecontext3 \ +- tst-on_exit \ +- tst-qsort \ +- tst-qsort2 \ +- tst-quick_exit \ +- tst-rand48 \ +- tst-rand48-2 \ +- tst-random \ +- tst-random2 \ +- tst-realpath \ +- tst-secure-getenv \ +- tst-setcontext \ +- tst-setcontext2 \ +- tst-setcontext3 \ +- tst-setcontext4 \ +- tst-setcontext5 \ +- tst-setcontext6 \ +- tst-setcontext7 \ +- tst-setcontext8 \ +- tst-setcontext9 \ +- tst-strfmon_l \ +- tst-strfrom \ +- tst-strfrom-locale \ +- tst-strtod \ +- tst-strtod-nan-locale \ +- tst-strtod-nan-sign \ +- tst-strtod-overflow \ +- tst-strtod-round \ +- tst-strtod-underflow \ +- tst-strtod2 \ +- tst-strtod5 \ +- tst-strtod6 \ +- tst-strtol \ +- tst-strtol-locale \ +- tst-strtoll \ +- tst-swapcontext1 \ +- tst-thread-quick_exit \ +- tst-tininess \ +- tst-unsetenv1 \ +- tst-width \ +- tst-width-stdint \ +- tst-xpg-basename ++tests := \ ++ bug-fmtmsg1 \ ++ bug-getcontext \ ++ bug-strtod \ ++ bug-strtod2 \ ++ test-a64l \ ++ test-at_quick_exit-race \ ++ test-atexit-race \ ++ test-bz22786 \ ++ test-canon \ ++ test-canon2 \ ++ test-cxa_atexit-race \ ++ test-cxa_atexit-race2 \ ++ test-dlclose-exit-race \ ++ test-on_exit-race \ ++ testdiv \ ++ testmb \ ++ testmb2 \ ++ testrand \ ++ testsort \ ++ tst-at_quick_exit \ ++ tst-atexit \ ++ tst-atof1 \ ++ tst-atof2 \ ++ tst-bsearch \ ++ tst-bz20544 \ ++ tst-canon-bz26341 \ ++ tst-cxa_atexit \ ++ tst-environ \ ++ tst-getrandom \ ++ tst-limits \ ++ tst-makecontext \ ++ tst-makecontext-align \ ++ tst-makecontext2 \ ++ tst-makecontext3 \ ++ tst-on_exit \ ++ tst-qsort \ ++ tst-qsort2 \ ++ tst-quick_exit \ ++ tst-rand48 \ ++ tst-rand48-2 \ ++ tst-random \ ++ tst-random2 \ ++ tst-realpath \ ++ tst-secure-getenv \ ++ tst-setcontext \ ++ tst-setcontext2 \ ++ tst-setcontext3 \ ++ tst-setcontext4 \ ++ tst-setcontext5 \ ++ tst-setcontext6 \ ++ tst-setcontext7 \ ++ tst-setcontext8 \ ++ tst-setcontext9 \ ++ tst-strfmon_l \ ++ tst-strfrom \ ++ tst-strfrom-locale \ ++ tst-strtod \ ++ tst-strtod-nan-locale \ ++ tst-strtod-nan-sign \ ++ tst-strtod-overflow \ ++ tst-strtod-round \ ++ tst-strtod-underflow \ ++ tst-strtod2 \ ++ tst-strtod5 \ ++ tst-strtod6 \ ++ tst-strtol \ ++ tst-strtol-locale \ ++ tst-strtoll \ ++ tst-swapcontext1 \ ++ tst-thread-quick_exit \ ++ tst-tininess \ ++ tst-unsetenv1 \ ++ tst-width \ ++ tst-width-stdint \ ++ tst-xpg-basename \ ++# tests + + tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ + tst-tls-atexit tst-tls-atexit-nodelete diff --git a/SOURCES/glibc-upstream-2.34-85.patch b/SOURCES/glibc-upstream-2.34-85.patch new file mode 100644 index 0000000..3ea12aa --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-85.patch @@ -0,0 +1,109 @@ +commit f7a79879c0b2bef0dadd6caaaeeb0d26423e04e5 +Author: Siddhesh Poyarekar +Date: Thu Jan 13 11:28:36 2022 +0530 + + realpath: Set errno to ENAMETOOLONG for result larger than PATH_MAX [BZ #28770] + + realpath returns an allocated string when the result exceeds PATH_MAX, + which is unexpected when its second argument is not NULL. This results + in the second argument (resolved) being uninitialized and also results + in a memory leak since the caller expects resolved to be the same as the + returned value. + + Return NULL and set errno to ENAMETOOLONG if the result exceeds + PATH_MAX. This fixes [BZ #28770], which is CVE-2021-3998. + + Reviewed-by: Adhemerval Zanella + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit ee8d5e33adb284601c00c94687bc907e10aec9bb) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 9bb5c221e8be3288..a4ac30d1f6359561 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -109,6 +109,7 @@ tests := \ + tst-random \ + tst-random2 \ + tst-realpath \ ++ tst-realpath-toolong \ + tst-secure-getenv \ + tst-setcontext \ + tst-setcontext2 \ +diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c +index 698f9ede25570ef2..7a23a51b3a395eb3 100644 +--- a/stdlib/canonicalize.c ++++ b/stdlib/canonicalize.c +@@ -400,8 +400,16 @@ realpath_stk (const char *name, char *resolved, + + error: + *dest++ = '\0'; +- if (resolved != NULL && dest - rname <= get_path_max ()) +- rname = strcpy (resolved, rname); ++ if (resolved != NULL) ++ { ++ if (dest - rname <= get_path_max ()) ++ rname = strcpy (resolved, rname); ++ else ++ { ++ failed = true; ++ __set_errno (ENAMETOOLONG); ++ } ++ } + + error_nomem: + scratch_buffer_free (&extra_buffer); +diff --git a/stdlib/tst-realpath-toolong.c b/stdlib/tst-realpath-toolong.c +new file mode 100644 +index 0000000000000000..8bed772460b37571 +--- /dev/null ++++ b/stdlib/tst-realpath-toolong.c +@@ -0,0 +1,49 @@ ++/* Verify that realpath returns NULL with ENAMETOOLONG if the result exceeds ++ NAME_MAX. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define BASENAME "tst-realpath-toolong." ++ ++int ++do_test (void) ++{ ++ char *base = support_create_and_chdir_toolong_temp_directory (BASENAME); ++ ++ char buf[PATH_MAX + 1]; ++ const char *res = realpath (".", buf); ++ ++ /* canonicalize.c states that if the real path is >= PATH_MAX, then ++ realpath returns NULL and sets ENAMETOOLONG. */ ++ TEST_VERIFY (res == NULL); ++ TEST_VERIFY (errno == ENAMETOOLONG); ++ ++ free (base); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-86.patch b/SOURCES/glibc-upstream-2.34-86.patch new file mode 100644 index 0000000..1885d41 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-86.patch @@ -0,0 +1,26 @@ +commit 8c8a71c85f2ed5cc90d08d82ce645513fc907cb6 +Author: Siddhesh Poyarekar +Date: Mon Jan 24 10:57:09 2022 +0530 + + tst-realpath-toolong: Fix hurd build + + Define PATH_MAX to a constant if it isn't already defined, like in hurd. + + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 976db046bc3a3738f69255ae00b0a09b8e77fd9c) + +diff --git a/stdlib/tst-realpath-toolong.c b/stdlib/tst-realpath-toolong.c +index 8bed772460b37571..4388890294374601 100644 +--- a/stdlib/tst-realpath-toolong.c ++++ b/stdlib/tst-realpath-toolong.c +@@ -29,6 +29,10 @@ + + #define BASENAME "tst-realpath-toolong." + ++#ifndef PATH_MAX ++# define PATH_MAX 1024 ++#endif ++ + int + do_test (void) + { diff --git a/SOURCES/glibc-upstream-2.34-87.patch b/SOURCES/glibc-upstream-2.34-87.patch new file mode 100644 index 0000000..a696584 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-87.patch @@ -0,0 +1,329 @@ +commit 472e799a5f2102bc0c3206dbd5a801765fceb39c +Author: Siddhesh Poyarekar +Date: Fri Jan 21 23:32:56 2022 +0530 + + getcwd: Set errno to ERANGE for size == 1 (CVE-2021-3999) + + No valid path returned by getcwd would fit into 1 byte, so reject the + size early and return NULL with errno set to ERANGE. This change is + prompted by CVE-2021-3999, which describes a single byte buffer + underflow and overflow when all of the following conditions are met: + + - The buffer size (i.e. the second argument of getcwd) is 1 byte + - The current working directory is too long + - '/' is also mounted on the current working directory + + Sequence of events: + + - In sysdeps/unix/sysv/linux/getcwd.c, the syscall returns ENAMETOOLONG + because the linux kernel checks for name length before it checks + buffer size + + - The code falls back to the generic getcwd in sysdeps/posix + + - In the generic func, the buf[0] is set to '\0' on line 250 + + - this while loop on line 262 is bypassed: + + while (!(thisdev == rootdev && thisino == rootino)) + + since the rootfs (/) is bind mounted onto the directory and the flow + goes on to line 449, where it puts a '/' in the byte before the + buffer. + + - Finally on line 458, it moves 2 bytes (the underflowed byte and the + '\0') to the buf[0] and buf[1], resulting in a 1 byte buffer overflow. + + - buf is returned on line 469 and errno is not set. + + This resolves BZ #28769. + + Reviewed-by: Andreas Schwab + Reviewed-by: Adhemerval Zanella + Signed-off-by: Qualys Security Advisory + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 23e0e8f5f1fb5ed150253d986ecccdc90c2dcd5e) + +diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c +index 13680026ffecbd51..b6984a382c3e1711 100644 +--- a/sysdeps/posix/getcwd.c ++++ b/sysdeps/posix/getcwd.c +@@ -187,6 +187,13 @@ __getcwd_generic (char *buf, size_t size) + size_t allocated = size; + size_t used; + ++ /* A size of 1 byte is never useful. */ ++ if (allocated == 1) ++ { ++ __set_errno (ERANGE); ++ return NULL; ++ } ++ + #if HAVE_MINIMALLY_WORKING_GETCWD + /* If AT_FDCWD is not defined, the algorithm below is O(N**2) and + this is much slower than the system getcwd (at least on +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index d30d21898b402d1e..cdc01a3f023ec09a 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -342,7 +342,12 @@ sysdep_routines += xstatconv internal_statvfs \ + + sysdep_headers += bits/fcntl-linux.h + +-tests += tst-fallocate tst-fallocate64 tst-o_path-locks ++tests += \ ++ tst-fallocate \ ++ tst-fallocate64 \ ++ tst-getcwd-smallbuff \ ++ tst-o_path-locks \ ++# tests + endif + + ifeq ($(subdir),elf) +diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c +new file mode 100644 +index 0000000000000000..d460d6e7662dc5e4 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c +@@ -0,0 +1,241 @@ ++/* Verify that getcwd returns ERANGE for size 1 byte and does not underflow ++ buffer when the CWD is too long and is also a mount target of /. See bug ++ #28769 or CVE-2021-3999 for more context. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static char *base; ++#define BASENAME "tst-getcwd-smallbuff" ++#define MOUNT_NAME "mpoint" ++static int sockfd[2]; ++ ++static void ++do_cleanup (void) ++{ ++ support_chdir_toolong_temp_directory (base); ++ TEST_VERIFY_EXIT (rmdir (MOUNT_NAME) == 0); ++ free (base); ++} ++ ++static void ++send_fd (const int sock, const int fd) ++{ ++ struct msghdr msg = {0}; ++ union ++ { ++ struct cmsghdr hdr; ++ char buf[CMSG_SPACE (sizeof (int))]; ++ } cmsgbuf = {0}; ++ struct cmsghdr *cmsg; ++ struct iovec vec; ++ char ch = 'A'; ++ ssize_t n; ++ ++ msg.msg_control = &cmsgbuf.buf; ++ msg.msg_controllen = sizeof (cmsgbuf.buf); ++ ++ cmsg = CMSG_FIRSTHDR (&msg); ++ cmsg->cmsg_len = CMSG_LEN (sizeof (int)); ++ cmsg->cmsg_level = SOL_SOCKET; ++ cmsg->cmsg_type = SCM_RIGHTS; ++ memcpy (CMSG_DATA (cmsg), &fd, sizeof (fd)); ++ ++ vec.iov_base = &ch; ++ vec.iov_len = 1; ++ msg.msg_iov = &vec; ++ msg.msg_iovlen = 1; ++ ++ while ((n = sendmsg (sock, &msg, 0)) == -1 && errno == EINTR); ++ ++ TEST_VERIFY_EXIT (n == 1); ++} ++ ++static int ++recv_fd (const int sock) ++{ ++ struct msghdr msg = {0}; ++ union ++ { ++ struct cmsghdr hdr; ++ char buf[CMSG_SPACE(sizeof(int))]; ++ } cmsgbuf = {0}; ++ struct cmsghdr *cmsg; ++ struct iovec vec; ++ ssize_t n; ++ char ch = '\0'; ++ int fd = -1; ++ ++ vec.iov_base = &ch; ++ vec.iov_len = 1; ++ msg.msg_iov = &vec; ++ msg.msg_iovlen = 1; ++ ++ msg.msg_control = &cmsgbuf.buf; ++ msg.msg_controllen = sizeof (cmsgbuf.buf); ++ ++ while ((n = recvmsg (sock, &msg, 0)) == -1 && errno == EINTR); ++ if (n != 1 || ch != 'A') ++ return -1; ++ ++ cmsg = CMSG_FIRSTHDR (&msg); ++ if (cmsg == NULL) ++ return -1; ++ if (cmsg->cmsg_type != SCM_RIGHTS) ++ return -1; ++ memcpy (&fd, CMSG_DATA (cmsg), sizeof (fd)); ++ if (fd < 0) ++ return -1; ++ return fd; ++} ++ ++static int ++child_func (void * const arg) ++{ ++ xclose (sockfd[0]); ++ const int sock = sockfd[1]; ++ char ch; ++ ++ TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1); ++ TEST_VERIFY_EXIT (ch == '1'); ++ ++ if (mount ("/", MOUNT_NAME, NULL, MS_BIND | MS_REC, NULL)) ++ FAIL_EXIT1 ("mount failed: %m\n"); ++ const int fd = xopen ("mpoint", ++ O_RDONLY | O_PATH | O_DIRECTORY | O_NOFOLLOW, 0); ++ ++ send_fd (sock, fd); ++ xclose (fd); ++ ++ TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1); ++ TEST_VERIFY_EXIT (ch == 'a'); ++ ++ xclose (sock); ++ return 0; ++} ++ ++static void ++update_map (char * const mapping, const char * const map_file) ++{ ++ const size_t map_len = strlen (mapping); ++ ++ const int fd = xopen (map_file, O_WRONLY, 0); ++ xwrite (fd, mapping, map_len); ++ xclose (fd); ++} ++ ++static void ++proc_setgroups_write (const long child_pid, const char * const str) ++{ ++ const size_t str_len = strlen(str); ++ ++ char setgroups_path[sizeof ("/proc//setgroups") + INT_STRLEN_BOUND (long)]; ++ ++ snprintf (setgroups_path, sizeof (setgroups_path), ++ "/proc/%ld/setgroups", child_pid); ++ ++ const int fd = open (setgroups_path, O_WRONLY); ++ ++ if (fd < 0) ++ { ++ TEST_VERIFY_EXIT (errno == ENOENT); ++ FAIL_UNSUPPORTED ("/proc/%ld/setgroups not found\n", child_pid); ++ } ++ ++ xwrite (fd, str, str_len); ++ xclose(fd); ++} ++ ++static char child_stack[1024 * 1024]; ++ ++int ++do_test (void) ++{ ++ base = support_create_and_chdir_toolong_temp_directory (BASENAME); ++ ++ xmkdir (MOUNT_NAME, S_IRWXU); ++ atexit (do_cleanup); ++ ++ TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0); ++ pid_t child_pid = xclone (child_func, NULL, child_stack, ++ sizeof (child_stack), ++ CLONE_NEWUSER | CLONE_NEWNS | SIGCHLD); ++ ++ xclose (sockfd[1]); ++ const int sock = sockfd[0]; ++ ++ char map_path[sizeof ("/proc//uid_map") + INT_STRLEN_BOUND (long)]; ++ char map_buf[sizeof ("0 1") + INT_STRLEN_BOUND (long)]; ++ ++ snprintf (map_path, sizeof (map_path), "/proc/%ld/uid_map", ++ (long) child_pid); ++ snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getuid()); ++ update_map (map_buf, map_path); ++ ++ proc_setgroups_write ((long) child_pid, "deny"); ++ snprintf (map_path, sizeof (map_path), "/proc/%ld/gid_map", ++ (long) child_pid); ++ snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getgid()); ++ update_map (map_buf, map_path); ++ ++ TEST_VERIFY_EXIT (send (sock, "1", 1, MSG_NOSIGNAL) == 1); ++ const int fd = recv_fd (sock); ++ TEST_VERIFY_EXIT (fd >= 0); ++ TEST_VERIFY_EXIT (fchdir (fd) == 0); ++ ++ static char buf[2 * 10 + 1]; ++ memset (buf, 'A', sizeof (buf)); ++ ++ /* Finally, call getcwd and check if it resulted in a buffer underflow. */ ++ char * cwd = getcwd (buf + sizeof (buf) / 2, 1); ++ TEST_VERIFY (cwd == NULL); ++ TEST_VERIFY (errno == ERANGE); ++ ++ for (int i = 0; i < sizeof (buf); i++) ++ if (buf[i] != 'A') ++ { ++ printf ("buf[%d] = %02x\n", i, (unsigned int) buf[i]); ++ support_record_failure (); ++ } ++ ++ TEST_VERIFY_EXIT (send (sock, "a", 1, MSG_NOSIGNAL) == 1); ++ xclose (sock); ++ TEST_VERIFY_EXIT (xwaitpid (child_pid, NULL, 0) == child_pid); ++ ++ return 0; ++} ++ ++#define CLEANUP_HANDLER do_cleanup ++#include diff --git a/SOURCES/glibc-upstream-2.34-88.patch b/SOURCES/glibc-upstream-2.34-88.patch new file mode 100644 index 0000000..d741c3c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-88.patch @@ -0,0 +1,28 @@ +commit d084965adc7baa8ea804427cccf973cea556d697 +Author: Siddhesh Poyarekar +Date: Mon Jan 24 21:36:41 2022 +0530 + + realpath: Avoid overwriting preexisting error (CVE-2021-3998) + + Set errno and failure for paths that are too long only if no other error + occurred earlier. + + Related: BZ #28770 + + Reviewed-by: Andreas Schwab + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 84d2d0fe20bdf94feed82b21b4d7d136db471f03) + +diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c +index 7a23a51b3a395eb3..e2d4244fc7b8fa25 100644 +--- a/stdlib/canonicalize.c ++++ b/stdlib/canonicalize.c +@@ -404,7 +404,7 @@ error: + { + if (dest - rname <= get_path_max ()) + rname = strcpy (resolved, rname); +- else ++ else if (!failed) + { + failed = true; + __set_errno (ENAMETOOLONG); diff --git a/SOURCES/glibc-upstream-2.34-89.patch b/SOURCES/glibc-upstream-2.34-89.patch new file mode 100644 index 0000000..37ddc35 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-89.patch @@ -0,0 +1,47 @@ +commit 3438bbca90895d32825a52e31a77dc44d273c1c1 +Author: Florian Weimer +Date: Mon Jan 24 18:14:24 2022 +0100 + + Linux: Detect user namespace support in io/tst-getcwd-smallbuff + + Otherwise the test fails with certain container runtimes. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 5b8e7980c5dabd9aaefeba4f0208baa8cf7653ee) + +diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c +index d460d6e7662dc5e4..55362f6060a2b3be 100644 +--- a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c ++++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -188,6 +189,23 @@ do_test (void) + xmkdir (MOUNT_NAME, S_IRWXU); + atexit (do_cleanup); + ++ /* Check whether user namespaces are supported. */ ++ { ++ pid_t pid = xfork (); ++ if (pid == 0) ++ { ++ if (unshare (CLONE_NEWUSER | CLONE_NEWNS) != 0) ++ _exit (EXIT_UNSUPPORTED); ++ else ++ _exit (0); ++ } ++ int status; ++ xwaitpid (pid, &status, 0); ++ TEST_VERIFY_EXIT (WIFEXITED (status)); ++ if (WEXITSTATUS (status) != 0) ++ return WEXITSTATUS (status); ++ } ++ + TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0); + pid_t child_pid = xclone (child_func, NULL, child_stack, + sizeof (child_stack), diff --git a/SOURCES/glibc-upstream-2.34-9.patch b/SOURCES/glibc-upstream-2.34-9.patch new file mode 100644 index 0000000..b22636d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-9.patch @@ -0,0 +1,24 @@ +commit 9acab0bba6a5a57323b1f94bf95b21618a9e5aa4 +Author: Arjun Shankar +Date: Fri Aug 20 16:24:05 2021 +0200 + + elf: Fix missing colon in LD_SHOW_AUXV output [BZ #28253] + + This commit adds a missing colon in the AT_MINSIGSTKSZ entry in + the _dl_show_auxv function. + + (cherry picked from commit 82fbcd7118d760492e2ecc9fa291e358b9ba0361) + +diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c +index d47bef1340ce6f35..2c684c2db2a1f59b 100644 +--- a/elf/dl-sysdep.c ++++ b/elf/dl-sysdep.c +@@ -317,7 +317,7 @@ _dl_show_auxv (void) + [AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex }, + [AT_RANDOM - 2] = { "RANDOM: 0x", hex }, + [AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex }, +- [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ ", dec }, ++ [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ: ", dec }, + [AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec }, + [AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex }, + [AT_L1D_CACHESIZE - 2] = { "L1D_CACHESIZE: ", dec }, diff --git a/SOURCES/glibc-upstream-2.34-91.patch b/SOURCES/glibc-upstream-2.34-91.patch new file mode 100644 index 0000000..f577e34 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-91.patch @@ -0,0 +1,36 @@ +commit b50d5b746cc0af5ad52164dcb0d3628f08b05a0d +Author: Noah Goldstein +Date: Sun Jan 9 16:02:21 2022 -0600 + + x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755] + + Fixes [BZ# 28755] for wcsncmp by redirecting length >= 2^56 to + __wcscmp_avx2. For x86_64 this covers the entire address range so any + length larger could not possibly be used to bound `s1` or `s2`. + + test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass. + + Signed-off-by: Noah Goldstein + (cherry picked from commit ddf0992cf57a93200e0c782e2a94d0733a5a0b87) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S +index 40333010a65650f9..3dfcb1bf803cf9ec 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S ++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S +@@ -87,6 +87,16 @@ ENTRY (STRCMP) + je L(char0) + jb L(zero) + # ifdef USE_AS_WCSCMP ++# ifndef __ILP32__ ++ movq %rdx, %rcx ++ /* Check if length could overflow when multiplied by ++ sizeof(wchar_t). Checking top 8 bits will cover all potential ++ overflow cases as well as redirect cases where its impossible to ++ length to bound a valid memory region. In these cases just use ++ 'wcscmp'. */ ++ shrq $56, %rcx ++ jnz __wcscmp_avx2 ++# endif + /* Convert units: from wide to byte char. */ + shl $2, %RDX_LP + # endif diff --git a/SOURCES/glibc-upstream-2.34-92.patch b/SOURCES/glibc-upstream-2.34-92.patch new file mode 100644 index 0000000..03a51c6 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-92.patch @@ -0,0 +1,36 @@ +commit 08beb3a3f4f46e306fffe184a08c5664bf0e13d6 +Author: Noah Goldstein +Date: Sun Jan 9 16:02:28 2022 -0600 + + x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755] + + Fixes [BZ# 28755] for wcsncmp by redirecting length >= 2^56 to + __wcscmp_evex. For x86_64 this covers the entire address range so any + length larger could not possibly be used to bound `s1` or `s2`. + + test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass. + + Signed-off-by: Noah Goldstein + (cherry picked from commit 7e08db3359c86c94918feb33a1182cd0ff3bb10b) + +diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S +index 459eeed09f5e276e..d5aa6daa46c7ed25 100644 +--- a/sysdeps/x86_64/multiarch/strcmp-evex.S ++++ b/sysdeps/x86_64/multiarch/strcmp-evex.S +@@ -97,6 +97,16 @@ ENTRY (STRCMP) + je L(char0) + jb L(zero) + # ifdef USE_AS_WCSCMP ++# ifndef __ILP32__ ++ movq %rdx, %rcx ++ /* Check if length could overflow when multiplied by ++ sizeof(wchar_t). Checking top 8 bits will cover all potential ++ overflow cases as well as redirect cases where its impossible to ++ length to bound a valid memory region. In these cases just use ++ 'wcscmp'. */ ++ shrq $56, %rcx ++ jnz __wcscmp_evex ++# endif + /* Convert units: from wide to byte char. */ + shl $2, %RDX_LP + # endif diff --git a/SOURCES/glibc-upstream-2.34-97.patch b/SOURCES/glibc-upstream-2.34-97.patch new file mode 100644 index 0000000..e9adea4 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-97.patch @@ -0,0 +1,360 @@ +commit 948ebc098ed3cd928ea10997f990115e7770bda3 +Author: Florian Weimer +Date: Thu Jan 27 16:03:58 2022 +0100 + + Fix glibc 2.34 ABI omission (missing GLIBC_2.34 in dynamic loader) + + The glibc 2.34 release really should have added a GLIBC_2.34 + symbol to the dynamic loader. With it, we could move functions such + as dlopen or pthread_key_create that work on process-global state + into the dynamic loader (once we have fixed a longstanding issue + with static linking). Without the GLIBC_2.34 symbol, yet another + new symbol version would be needed because old glibc will fail to + load binaries due to the missing symbol version in ld.so that newly + linked programs will require. + + Reviewed-by: H.J. Lu + (cherry picked from commit af121ae3e7cd12628c91ecfc46a9d65313a6e972) + +diff --git a/elf/Makefile b/elf/Makefile +index 11ff0aa8438de4e4..cd8725c76f4cfb48 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -117,6 +117,7 @@ elide-routines.os = \ + # interpreter and operating independent of libc. + rtld-routines = \ + $(all-dl-routines) \ ++ dl-compat \ + dl-conflict \ + dl-diagnostics \ + dl-diagnostics-cpu \ +diff --git a/elf/Versions b/elf/Versions +index 775aab62af500f6c..2af210b8f771c950 100644 +--- a/elf/Versions ++++ b/elf/Versions +@@ -48,6 +48,9 @@ ld { + # stack canary + __stack_chk_guard; + } ++ GLIBC_2.34 { ++ __rtld_version_placeholder; ++ } + GLIBC_PRIVATE { + # Those are in the dynamic linker, but used by libc.so. + __libc_enable_secure; +diff --git a/elf/dl-compat.c b/elf/dl-compat.c +new file mode 100644 +index 0000000000000000..cc560c515930f59a +--- /dev/null ++++ b/elf/dl-compat.c +@@ -0,0 +1,32 @@ ++/* Placeholder compatibility symbols. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++/* GLIBC_2.34 placeholder for future symbol moves. */ ++ ++void ++attribute_compat_text_section ++__attribute_used__ ++__rtld_version_placeholder_1 (void) ++{ ++} ++ ++compat_symbol (ld, __rtld_version_placeholder_1, ++ __rtld_version_placeholder, GLIBC_2_34); +diff --git a/sysdeps/mach/hurd/i386/ld.abilist b/sysdeps/mach/hurd/i386/ld.abilist +index 7e20c5e7ce8a7a5e..ebba31f7706d854d 100644 +--- a/sysdeps/mach/hurd/i386/ld.abilist ++++ b/sysdeps/mach/hurd/i386/ld.abilist +@@ -16,3 +16,4 @@ GLIBC_2.2.6 _r_debug D 0x14 + GLIBC_2.2.6 abort F + GLIBC_2.3 ___tls_get_addr F + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/aarch64/ld.abilist b/sysdeps/unix/sysv/linux/aarch64/ld.abilist +index 80b2fe672541c6e9..b7196a80e2df8efc 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/aarch64/ld.abilist +@@ -3,3 +3,4 @@ GLIBC_2.17 __stack_chk_guard D 0x8 + GLIBC_2.17 __tls_get_addr F + GLIBC_2.17 _dl_mcount F + GLIBC_2.17 _r_debug D 0x28 ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/alpha/ld.abilist b/sysdeps/unix/sysv/linux/alpha/ld.abilist +index 98a03f611f98f3a4..13f7fc74af62941d 100644 +--- a/sysdeps/unix/sysv/linux/alpha/ld.abilist ++++ b/sysdeps/unix/sysv/linux/alpha/ld.abilist +@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x28 + GLIBC_2.1 __libc_stack_end D 0x8 + GLIBC_2.1 _dl_mcount F + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __stack_chk_guard D 0x8 +diff --git a/sysdeps/unix/sysv/linux/arc/ld.abilist b/sysdeps/unix/sysv/linux/arc/ld.abilist +index 048f17c8486f3d54..7284383a6bea8e64 100644 +--- a/sysdeps/unix/sysv/linux/arc/ld.abilist ++++ b/sysdeps/unix/sysv/linux/arc/ld.abilist +@@ -3,3 +3,4 @@ GLIBC_2.32 __stack_chk_guard D 0x4 + GLIBC_2.32 __tls_get_addr F + GLIBC_2.32 _dl_mcount F + GLIBC_2.32 _r_debug D 0x14 ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/arm/be/ld.abilist b/sysdeps/unix/sysv/linux/arm/be/ld.abilist +index cc8825c3bc68ad4a..7987bbae1112aa3d 100644 +--- a/sysdeps/unix/sysv/linux/arm/be/ld.abilist ++++ b/sysdeps/unix/sysv/linux/arm/be/ld.abilist +@@ -1,3 +1,4 @@ ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __libc_stack_end D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 + GLIBC_2.4 __tls_get_addr F +diff --git a/sysdeps/unix/sysv/linux/arm/le/ld.abilist b/sysdeps/unix/sysv/linux/arm/le/ld.abilist +index cc8825c3bc68ad4a..7987bbae1112aa3d 100644 +--- a/sysdeps/unix/sysv/linux/arm/le/ld.abilist ++++ b/sysdeps/unix/sysv/linux/arm/le/ld.abilist +@@ -1,3 +1,4 @@ ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __libc_stack_end D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 + GLIBC_2.4 __tls_get_addr F +diff --git a/sysdeps/unix/sysv/linux/csky/ld.abilist b/sysdeps/unix/sysv/linux/csky/ld.abilist +index 564ac09737d6d8d5..4939b20631dc6c54 100644 +--- a/sysdeps/unix/sysv/linux/csky/ld.abilist ++++ b/sysdeps/unix/sysv/linux/csky/ld.abilist +@@ -3,3 +3,4 @@ GLIBC_2.29 __stack_chk_guard D 0x4 + GLIBC_2.29 __tls_get_addr F + GLIBC_2.29 _dl_mcount F + GLIBC_2.29 _r_debug D 0x14 ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/hppa/ld.abilist b/sysdeps/unix/sysv/linux/hppa/ld.abilist +index d155a59843df9091..7cc9ebd792c2aadc 100644 +--- a/sysdeps/unix/sysv/linux/hppa/ld.abilist ++++ b/sysdeps/unix/sysv/linux/hppa/ld.abilist +@@ -2,4 +2,5 @@ GLIBC_2.2 __libc_stack_end D 0x4 + GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x14 + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist +index 0478e220712a55e6..e8d187b14d722a64 100644 +--- a/sysdeps/unix/sysv/linux/i386/ld.abilist ++++ b/sysdeps/unix/sysv/linux/i386/ld.abilist +@@ -3,3 +3,4 @@ GLIBC_2.1 __libc_stack_end D 0x4 + GLIBC_2.1 _dl_mcount F + GLIBC_2.3 ___tls_get_addr F + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/ia64/ld.abilist b/sysdeps/unix/sysv/linux/ia64/ld.abilist +index 33f91199bfa516fb..be5122650ae2b327 100644 +--- a/sysdeps/unix/sysv/linux/ia64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/ia64/ld.abilist +@@ -2,3 +2,4 @@ GLIBC_2.2 __libc_stack_end D 0x8 + GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x28 + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist +index cc8825c3bc68ad4a..7987bbae1112aa3d 100644 +--- a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist +@@ -1,3 +1,4 @@ ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __libc_stack_end D 0x4 + GLIBC_2.4 __stack_chk_guard D 0x4 + GLIBC_2.4 __tls_get_addr F +diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist +index 3ba474c27f62fb10..4f2854edf7746958 100644 +--- a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist +@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x14 + GLIBC_2.1 __libc_stack_end D 0x4 + GLIBC_2.1 _dl_mcount F + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/microblaze/ld.abilist b/sysdeps/unix/sysv/linux/microblaze/ld.abilist +index a4933c3541119538..9f0fdeca38890a34 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/ld.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/ld.abilist +@@ -3,3 +3,4 @@ GLIBC_2.18 __stack_chk_guard D 0x4 + GLIBC_2.18 __tls_get_addr F + GLIBC_2.18 _dl_mcount F + GLIBC_2.18 _r_debug D 0x14 ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist +index be09641a48962434..f750067d5c34bf42 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist +@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x14 + GLIBC_2.2 __libc_stack_end D 0x4 + GLIBC_2.2 _dl_mcount F + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist +index be09641a48962434..f750067d5c34bf42 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist +@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x14 + GLIBC_2.2 __libc_stack_end D 0x4 + GLIBC_2.2 _dl_mcount F + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist +index 1ea36e13f294a249..2fba6a9b6ec92e47 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist +@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x28 + GLIBC_2.2 __libc_stack_end D 0x8 + GLIBC_2.2 _dl_mcount F + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __stack_chk_guard D 0x8 +diff --git a/sysdeps/unix/sysv/linux/nios2/ld.abilist b/sysdeps/unix/sysv/linux/nios2/ld.abilist +index 52178802dd82b59a..57dfad5a53b739e8 100644 +--- a/sysdeps/unix/sysv/linux/nios2/ld.abilist ++++ b/sysdeps/unix/sysv/linux/nios2/ld.abilist +@@ -3,3 +3,4 @@ GLIBC_2.21 __stack_chk_guard D 0x4 + GLIBC_2.21 __tls_get_addr F + GLIBC_2.21 _dl_mcount F + GLIBC_2.21 _r_debug D 0x14 ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist +index 4bbfba7a61c7a5ef..e89660739262c6ab 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist +@@ -4,3 +4,4 @@ GLIBC_2.1 _dl_mcount F + GLIBC_2.22 __tls_get_addr_opt F + GLIBC_2.23 __parse_hwcap_and_convert_at_platform F + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist +index 283fb4510bea40ba..ce0bc639597c4bd9 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist +@@ -4,3 +4,4 @@ GLIBC_2.3 __libc_stack_end D 0x8 + GLIBC_2.3 __tls_get_addr F + GLIBC_2.3 _dl_mcount F + GLIBC_2.3 _r_debug D 0x28 ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist +index b1f313c7cd33defc..65b22674d2462e96 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist +@@ -4,3 +4,4 @@ GLIBC_2.17 _dl_mcount F + GLIBC_2.17 _r_debug D 0x28 + GLIBC_2.22 __tls_get_addr_opt F + GLIBC_2.23 __parse_hwcap_and_convert_at_platform F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist +index 94ca64c43db63b2a..5ad4c81d12d7a612 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist +@@ -3,3 +3,4 @@ GLIBC_2.33 __stack_chk_guard D 0x4 + GLIBC_2.33 __tls_get_addr F + GLIBC_2.33 _dl_mcount F + GLIBC_2.33 _r_debug D 0x14 ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist +index 845f356c3c3fad54..479efdea9bb654bb 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist +@@ -3,3 +3,4 @@ GLIBC_2.27 __stack_chk_guard D 0x8 + GLIBC_2.27 __tls_get_addr F + GLIBC_2.27 _dl_mcount F + GLIBC_2.27 _r_debug D 0x28 ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist +index b56f005bebd3baf1..d5ecb636bb792bdf 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist +@@ -2,3 +2,4 @@ GLIBC_2.0 _r_debug D 0x14 + GLIBC_2.1 __libc_stack_end D 0x4 + GLIBC_2.1 _dl_mcount F + GLIBC_2.3 __tls_get_offset F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist +index 6f788a086d68aaa5..62a5e1d99a2e6f42 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist +@@ -2,3 +2,4 @@ GLIBC_2.2 __libc_stack_end D 0x8 + GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x28 + GLIBC_2.3 __tls_get_offset F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/sh/be/ld.abilist b/sysdeps/unix/sysv/linux/sh/be/ld.abilist +index d155a59843df9091..7cc9ebd792c2aadc 100644 +--- a/sysdeps/unix/sysv/linux/sh/be/ld.abilist ++++ b/sysdeps/unix/sysv/linux/sh/be/ld.abilist +@@ -2,4 +2,5 @@ GLIBC_2.2 __libc_stack_end D 0x4 + GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x14 + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/sh/le/ld.abilist b/sysdeps/unix/sysv/linux/sh/le/ld.abilist +index d155a59843df9091..7cc9ebd792c2aadc 100644 +--- a/sysdeps/unix/sysv/linux/sh/le/ld.abilist ++++ b/sysdeps/unix/sysv/linux/sh/le/ld.abilist +@@ -2,4 +2,5 @@ GLIBC_2.2 __libc_stack_end D 0x4 + GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x14 + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F + GLIBC_2.4 __stack_chk_guard D 0x4 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist +index 0c6610e3c2f00cf3..2e6054349871e7d5 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist +@@ -2,3 +2,4 @@ GLIBC_2.0 _r_debug D 0x14 + GLIBC_2.1 __libc_stack_end D 0x4 + GLIBC_2.1 _dl_mcount F + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist +index 33f91199bfa516fb..be5122650ae2b327 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist +@@ -2,3 +2,4 @@ GLIBC_2.2 __libc_stack_end D 0x8 + GLIBC_2.2 _dl_mcount F + GLIBC_2.2 _r_debug D 0x28 + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist +index d3cdf7611eb9cab3..afddaec57c11f837 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist +@@ -2,3 +2,4 @@ GLIBC_2.2.5 __libc_stack_end D 0x8 + GLIBC_2.2.5 _dl_mcount F + GLIBC_2.2.5 _r_debug D 0x28 + GLIBC_2.3 __tls_get_addr F ++GLIBC_2.34 __rtld_version_placeholder F +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist +index c70bccf78245a552..defc488d137c61c3 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist +@@ -2,3 +2,4 @@ GLIBC_2.16 __libc_stack_end D 0x4 + GLIBC_2.16 __tls_get_addr F + GLIBC_2.16 _dl_mcount F + GLIBC_2.16 _r_debug D 0x14 ++GLIBC_2.34 __rtld_version_placeholder F diff --git a/SOURCES/glibc-upstream-2.34-98.patch b/SOURCES/glibc-upstream-2.34-98.patch new file mode 100644 index 0000000..adbb154 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-98.patch @@ -0,0 +1,62 @@ +commit b952c25dc7adf0684c53ad72d1d667da0348c929 +Author: H.J. Lu +Date: Fri Jan 14 14:48:01 2022 -0800 + + x86: Black list more Intel CPUs for TSX [BZ #27398] + + Disable TSX and enable RTM_ALWAYS_ABORT for Intel CPUs listed in: + + https://www.intel.com/content/www/us/en/support/articles/000059422/processors.html + + This fixes BZ #27398. + + Reviewed-by: Noah Goldstein + (cherry picked from commit 1e000d3d33211d5a954300e2a69b90f93f18a1a1) + +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index 645bba63147f6589..de4e3c3b7258120d 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -507,11 +507,39 @@ init_cpu_features (struct cpu_features *cpu_features) + 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). */ ++ /* Disable TSX on some processors to avoid TSX on kernels that ++ weren't updated with the latest microcode package (which ++ disables broken feature by default). */ + switch (model) + { ++ case 0x55: ++ if (stepping <= 5) ++ goto disable_tsx; ++ break; ++ case 0x8e: ++ /* NB: Although the errata documents that for model == 0x8e, ++ only 0xb stepping or lower are impacted, the intention of ++ the errata was to disable TSX on all client processors on ++ all steppings. Include 0xc stepping which is an Intel ++ Core i7-8665U, a client mobile processor. */ ++ case 0x9e: ++ if (stepping > 0xc) ++ break; ++ /* Fall through. */ ++ case 0x4e: ++ case 0x5e: ++ { ++ /* Disable Intel TSX and enable RTM_ALWAYS_ABORT for ++ processors listed in: ++ ++https://www.intel.com/content/www/us/en/support/articles/000059422/processors.html ++ */ ++disable_tsx: ++ CPU_FEATURE_UNSET (cpu_features, HLE); ++ CPU_FEATURE_UNSET (cpu_features, RTM); ++ CPU_FEATURE_SET (cpu_features, RTM_ALWAYS_ABORT); ++ } ++ break; + case 0x3f: + /* Xeon E7 v3 with stepping >= 4 has working TSX. */ + if (stepping >= 4) diff --git a/SOURCES/glibc-upstream-2.34-99.patch b/SOURCES/glibc-upstream-2.34-99.patch new file mode 100644 index 0000000..7df75d8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-99.patch @@ -0,0 +1,24 @@ +commit aa601d024424c40ae9a69b0c4e394a70ea0570c8 +Author: H.J. Lu +Date: Mon Jan 24 19:33:43 2022 -0800 + + x86: Use CHECK_FEATURE_PRESENT to check HLE [BZ #27398] + + HLE is disabled on blacklisted CPUs. Use CHECK_FEATURE_PRESENT, instead + of CHECK_FEATURE_ACTIVE, to check HLE. + + (cherry picked from commit 501246c5e2dfcc278f0ebbdb72345cdd239521c7) + +diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c +index 9d76e6bd3f8db024..faa5091b78431487 100644 +--- a/sysdeps/x86/tst-cpu-features-supports.c ++++ b/sysdeps/x86/tst-cpu-features-supports.c +@@ -130,7 +130,7 @@ do_test (int argc, char **argv) + fails += CHECK_FEATURE_ACTIVE (gfni, GFNI); + #endif + #if __GNUC_PREREQ (11, 0) +- fails += CHECK_FEATURE_ACTIVE (hle, HLE); ++ fails += CHECK_FEATURE_PRESENT (hle, HLE); + fails += CHECK_FEATURE_PRESENT (ibt, IBT); + fails += CHECK_FEATURE_ACTIVE (lahf_lm, LAHF64_SAHF64); + fails += CHECK_FEATURE_PRESENT (lm, LM); diff --git a/SOURCES/glibc.attr b/SOURCES/glibc.attr new file mode 100644 index 0000000..fddfd91 --- /dev/null +++ b/SOURCES/glibc.attr @@ -0,0 +1,3 @@ +%__glibc_requires %{_rpmconfigdir}/glibc.req +%__glibc_magic ELF +%__glibc_flags exeonly diff --git a/SOURCES/glibc.req.in b/SOURCES/glibc.req.in new file mode 100644 index 0000000..9fb7f76 --- /dev/null +++ b/SOURCES/glibc.req.in @@ -0,0 +1,42 @@ +#!/bin/bash +# Auto-generating dependencies for glibc development snapshots. +# +# A glibc development snapshot (say version 2.33.9000) may define +# symbols in its under-development symbol version (GLIBC_2.34). RPM +# automatically derives RPM dependencies such as +# libc.so.6(GLIBC_2.34)(64bit) from that. While the GLIBC_2.34 +# version is under development, these dependencies may be inaccurate +# and could be satisfied by glibc RPM package versions that lack the +# symbols because they were created from an earlier development +# snapshot that had some other GLIBC_2.34 symbols. Therefore, if the +# latest, under-development ELF symbol version is detected, this +# dependency generator adds an explicit RPM dependencies on the glibc +# packaging version against which an RPM package is built. +# +# This script runs for the glibc build itself. In this case, it may +# produce a >= dependency on the build-time glibc, but there will also +# be an (potentially indirect) = dependency, which takes precedence. + +set -e +set -o pipefail + +searching=true +# Pre-filter using eu-elfclassify, to skip kernel modules. +eu-elfclassify --loadable --file --stdin --print | while read path; do + # Assume that all dynamically linked objects depend on glibc in + # some way. + if $searching; then + # Undefined symbols within latest, under-development + # (changing) symbol versions trigger the versioned RPM + # dependency. Do not use "egrep -q" to keep reading from the + # pipe, avoiding a spurious EPIPE error in eu-readelf. + if eu-readelf -s "$path" \ + | egrep '\sUNDEF\s.*@''@SYMVER@(\s|$)' >/dev/null + then + echo 'glibc >= @VERSION@-@RELEASE@' + # Stop searching after the first match, but keep reading from + # the pipe. + searching=false + fi + fi +done 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/parse-SUPPORTED.py b/SOURCES/parse-SUPPORTED.py new file mode 100644 index 0000000..cf512de --- /dev/null +++ b/SOURCES/parse-SUPPORTED.py @@ -0,0 +1,40 @@ +#!/usr/bin/python3 +# +# This script turns localedata/SUPPORTED (whose path is passed as the +# first argument) into a normalized list of LANGUAGE "_" REGION pairs. +# (If there is no REGION defined, only LANGUAGE is used.) The list +# is written to standard output, with one element per line. + +import sys + +supported, = sys.argv[1:] + +# Pairs seen so far. Used to suppress duplicates. +seen = set() +with open(supported) as inp: + for line in inp: + if line.startswith("#") or line == "SUPPORTED-LOCALES=\\\n": + # Comment or prefix. + continue + if not line.endswith(" \\\n"): + raise IOError("line without continuation: " + repr(line)) + try: + slash = line.index("/") + except ValueError: + raise IOError("line without slash: " + repr(line)) + spec = line[:slash] + for separator in ".@": + try: + # Strip charset, variant specifiers. + spec = spec[:spec.index(separator)] + except ValueError: + pass + seen.add(spec) + +# The C locale does not correspond to a language. +seen.remove("C") + +# The glibc source file is not sorted. +for spec in sorted(seen): + print(spec) +print() # The Lua generator produces a trailing newline. diff --git a/SOURCES/wrap-find-debuginfo.sh b/SOURCES/wrap-find-debuginfo.sh new file mode 100644 index 0000000..4cbb01b --- /dev/null +++ b/SOURCES/wrap-find-debuginfo.sh @@ -0,0 +1,154 @@ +#!/bin/bash +# Wrapper script for find-debuginfo.sh +# +# Usage: +# wrap-find-debuginfo.sh SYSROOT-PATH SCRIPT-PATH SCRIPT-ARGS... +# +# The wrapper saves the original version of ld.so found in SYSROOT-PATH, +# invokes SCRIPT-PATH with SCRIPT-ARGS, and then restores the +# LDSO-PATH file, followed by note merging and DWZ compression. +# As a result, ld.so has (mostly) unchanged debuginfo even +# after debuginfo extraction. +# +# For libc.so.6, a set of strategic symbols is preserved in .symtab +# that are frequently used in valgrind suppressions and elsewhere. + +set -ex + +workdir="$(mktemp -d -t find_debuginfo.XXXXXX)" + +ldso_tmp="$workdir/ld.so" +libc_tmp_dir="$workdir/" + +# Return the path where a libc should be saved temporarily. This path is +# based on its original path received in $1. +libc_tmp_path() { + echo "$libc_tmp_dir"`dirname "$1"`"/libc.so" +} + +# Prefer a separately installed debugedit over the RPM-integrated one. +if command -v debugedit >/dev/null ; then + debugedit=debugedit +else + debugedit=/usr/lib/rpm/debugedit +fi + +cleanup () { + rm -rf "$workdir" +} +trap cleanup 0 + +sysroot_path="$1" +shift +script_path="$1" +shift + +# See ldso_path setting in glibc.spec. +ldso_path= +for ldso_candidate in `find "$sysroot_path" -maxdepth 2 \ + -regextype posix-extended -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do + if test -z "$ldso_path" ; then + ldso_path="$ldso_candidate" + else + echo "error: multiple ld.so candidates: $ldso_path, $ldso_candidate" + exit 1 + fi +done + +# libc.so.6 always uses this name, so it is simpler to locate. +libc_path=`find "$sysroot_path" -name libc.so.6` + + +# Preserve the original files. +cp "$ldso_path" "$ldso_tmp" +for lib in $libc_path ; do + libtmp=`libc_tmp_path $lib` + mkdir -p `dirname "$libtmp"` + cp "$lib" "$libtmp" +done + +# Run the debuginfo extraction. +"$script_path" "$@" + +for lib in $libc_path ; do + libtmp=`libc_tmp_path "$lib"` + # libc.so.6: Extract the .gnu_debuglink section + objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \ + -O binary "$lib" "$libtmp.debuglink" + # Restore the original files. + cp "$libtmp" "$lib" + + # Reduce the size of libc notes. Primarily for annobin. + objcopy --merge-notes "$lib" + + # libc.so.6: Restore the .gnu_debuglink section + objcopy --add-section .gnu_debuglink="$libtmp.debuglink" "$lib" + + # libc.so.6: Reduce to valuable symbols. Eliminate file symbols, + # annobin symbols, and symbols used by the glibc build to implement + # hidden aliases (__EI_*). We would also like to remove __GI_* + # symbols, but even listing them explicitly (as in -K __GI_strlen) + # still causes strip to remove them, so there is no filtering of + # __GI_* here. (Debuginfo is gone after this, so no need to optimize + # it.) + strip -w \ + -K '*' \ + -K '!*.c' \ + -K '!*.os' \ + -K '!.annobin_*' \ + -K '!__EI_*' \ + -K '!__PRETTY_FUNCTION__*' \ + "$lib" +done + +# Restore the original ld.so. +cp "$ldso_tmp" "$ldso_path" + +# Reduce the size of notes. Primarily for annobin. +objcopy --merge-notes "$ldso_path" + +# ld.so does not have separated debuginfo and so the debuginfo file +# generated by find-debuginfo is redundant. Therefore, remove it. +ldso_debug= +for ldso_debug_candidate in `find "$sysroot_path" -maxdepth 2 \ + -regextype posix-extended \ + -regex '.*/ld(-.*|64|)\.so\.[0-9]+.*debug$' -type f` ; do + if test -z "$ldso_debug" ; then + ldso_debug="$ldso_debug_candidate" + else + echo "error: multiple ld.so debug candidates: $ldso_debug, $ldso_debug_candidate" + exit 1 + fi +done +rm -f "$ldso_debug" + +# ld.so: Rewrite the source file paths to match the extracted +# locations. First compute the arguments for invoking debugedit. +# See find-debuginfo.sh. +debug_dest_name="/usr/src/debug" +last_arg= +while true ; do + arg="$1" + shift || break + case "$arg" in + (--unique-debug-src-base) + debug_dest_name="/usr/src/debug/$1" + shift + ;; + (-*) + ;; + (*) + last_arg="$arg" + ;; + esac +done +debug_base_name=${last_arg:-$RPM_BUILD_ROOT} +$debugedit -b "$debug_base_name" -d "$debug_dest_name" -n $ldso_path +# Remove the .annobin* symbols (and only them). +if nm --format=posix "$ldso_path" | cut -d' ' -f1 \ + | grep '^\.annobin' > "$ldso_tmp.annobin-symbols"; then + objcopy --strip-symbols="$ldso_tmp.annobin-symbols" "$ldso_path" +fi + +# Apply single-file DWARF optimization. +dwz $ldso_path diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec new file mode 100644 index 0000000..ddb8035 --- /dev/null +++ b/SPECS/glibc.spec @@ -0,0 +1,3462 @@ +%define glibcsrcdir glibc-2.34 +%define glibcversion 2.34 +# 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. +# Conversly, glibc_autorequires is set for development snapshots, where +# dependencies based on symbol versions are inaccurate. +%{lua: if string.match(rpm.expand("%glibcsrcdir"), "^glibc%-[0-9.]+$") then + rpm.define("glibc_release_url https://ftp.gnu.org/gnu/glibc/") + end + local major, minor = string.match(rpm.expand("%glibcversion"), + "^([0-9]+)%.([0-9]+)%.9000$") + if major and minor then + rpm.define("glibc_autorequires 1") + -- The minor version in a .9000 development version lags the actual + -- symbol version by one. + local symver = "GLIBC_" .. major .. "." .. (minor + 1) + rpm.define("glibc_autorequires_symver " .. symver) + else + rpm.define("glibc_autorequires 0") + 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 + +# Build the POWER10 runtime on POWER, but only for downstream. +%ifarch ppc64le +%define buildpower10 0%{?rhel} > 0 +%else +%define buildpower10 0 +%endif + +# The annobin annotations cause binutils to produce broken ARM EABI +# unwinding information. Symptom is a hang/test failure for +# malloc/tst-malloc-stats-cancellation. See +# . +%ifarch armv7hl +%undefine _annotated_build +%endif + +############################################################################## +# 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 s390 s390x + +# Avoid generating a glibc-headers package on architectures which are +# not biarch. +%ifarch %{biarcharches} +%define need_headers_package 1 +%if 0%{?rhel} > 0 +%define headers_package_name glibc-headers +%else +%ifarch %{ix86} x86_64 +%define headers_package_name glibc-headers-x86 +%endif +%ifarch s390 s390x +%define headers_package_name glibc-headers-s390 +%endif +%dnl !rhel +%endif +%else +%define need_headers_package 0 +%dnl !biarcharches +%endif + +############################################################################## +# Utility functions for pre/post scripts. Stick them at the beginning of +# any lua %pre, %post, %postun, etc. sections to have them expand into +# those scripts. It only works in lua sections and not anywhere else. +%define glibc_post_funcs() \ +-- We use lua posix.exec because there may be no shell that we can \ +-- run during glibc upgrade. We used to implement much of %%post as a \ +-- C program, but from an overall maintenance perspective the lua in \ +-- the spec file was simpler and safer given the operations required. \ +-- All lua code will be ignored by rpm-ostree; see: \ +-- https://github.com/projectatomic/rpm-ostree/pull/1869 \ +-- If we add new lua actions to the %%post code we should coordinate \ +-- with rpm-ostree and ensure that their glibc install is functional. \ +function post_exec (program, ...) \ + local pid = posix.fork () \ + if pid == 0 then \ + posix.exec (program, ...) \ + assert (nil) \ + elseif pid > 0 then \ + posix.wait (pid) \ + end \ +end \ +\ +function update_gconv_modules_cache () \ + local iconv_dir = "%{_libdir}/gconv" \ + local iconv_cache = iconv_dir .. "/gconv-modules.cache" \ + local iconv_modules = iconv_dir .. "/gconv-modules" \ + if (posix.utime (iconv_modules) == 0) then \ + 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 \ + end \ +end \ +%{nil} + +############################################################################## +# %%package glibc - The GNU C Library (glibc) core package. +############################################################################## +Summary: The GNU libc libraries +Name: glibc +Version: %{glibcversion} +Release: 60%{?dist} + +# 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: nscd.conf +Source2: bench.mk +Source3: glibc-bench-compare +Source4: glibc.req.in +Source5: glibc.attr +Source10: wrap-find-debuginfo.sh +Source11: parse-SUPPORTED.py +# Include in the source RPM for reference. +Source12: ChangeLog.old + +###################################################################### +# Activate the wrapper script for debuginfo generation, by rewriting +# the definition of __debug_install_post. +%{lua: +local wrapper = rpm.expand("%{SOURCE10}") +local sysroot = rpm.expand("%{glibc_sysroot}") +local original = rpm.expand("%{macrobody:__debug_install_post}") +-- Strip leading newline. It confuses the macro redefinition. +-- Avoid embedded newlines that confuse the macro definition. +original = original:match("^%s*(.-)%s*$"):gsub("\\\n", "") +rpm.define("__debug_install_post bash " .. wrapper + .. " " .. sysroot .. " " .. original) +} + +# sysroot package support. These contain arch-specific packages, so +# turn off the rpmbuild check. +%global _binaries_in_noarch_packages_terminate_build 0 +# Variant of %%dist that contains just the distribution release, no affixes. +%{?fedora:%global sysroot_dist fc%{fedora}} +%{?rhel:%global sysroot_dist el%{rhel}} +%{?!sysroot_dist:%global sysroot_dist root} +# The name of the sysroot package. +%global sysroot_package_arch sysroot-%{_arch}-%{sysroot_dist}-%{name} +# Installed path for the sysroot tree. Must contain /sys-root/, which +# triggers filtering. +%global sysroot_prefix /usr/%{_arch}-redhat-linux/sys-root/%{sysroot_dist} + +# The wrapper script relies on the fact that debugedit does not change +# build IDs. +%define _no_recompute_build_ids 1 +%undefine _unique_build_ids + +############################################################################## +# Patches: +# - See each individual patch file for origin and upstream status. +# - For new patches follow template.patch format. +############################################################################## +Patch1: glibc-fedora-nscd.patch +Patch4: glibc-fedora-linux-tcsetattr.patch +Patch8: glibc-fedora-manual-dircategory.patch +Patch9: glibc-rh827510.patch +Patch13: glibc-fedora-localedata-rh61908.patch +Patch15: glibc-rh1070416.patch +Patch16: glibc-nscd-sysconfig.patch +Patch17: glibc-cs-path.patch +Patch18: glibc-c-utf8-locale-1.patch +Patch19: glibc-c-utf8-locale-2.patch +Patch23: glibc-python3.patch +Patch29: glibc-fedora-nsswitch.patch +Patch30: glibc-deprecated-selinux-makedb.patch +Patch31: glibc-deprecated-selinux-nscd.patch +Patch32: glibc-upstream-2.34-1.patch +Patch33: glibc-upstream-2.34-2.patch +Patch34: glibc-upstream-2.34-3.patch +Patch35: glibc-upstream-2.34-4.patch +Patch36: glibc-upstream-2.34-5.patch +Patch37: glibc-upstream-2.34-6.patch +Patch38: glibc-upstream-2.34-7.patch +Patch39: glibc-upstream-2.34-8.patch +Patch40: glibc-upstream-2.34-9.patch +Patch41: glibc-upstream-2.34-10.patch +Patch42: glibc-upstream-2.34-11.patch +Patch43: glibc-upstream-2.34-12.patch +Patch44: glibc-upstream-2.34-13.patch +Patch45: glibc-upstream-2.34-14.patch +Patch46: glibc-upstream-2.34-15.patch +Patch47: glibc-upstream-2.34-16.patch +Patch48: glibc-upstream-2.34-17.patch +Patch49: glibc-upstream-2.34-18.patch +Patch50: glibc-upstream-2.34-19.patch +Patch51: glibc-upstream-2.34-20.patch +Patch52: glibc-upstream-2.34-21.patch +Patch53: glibc-upstream-2.34-22.patch +Patch54: glibc-upstream-2.34-23.patch +Patch55: glibc-upstream-2.34-24.patch +Patch56: glibc-upstream-2.34-25.patch +Patch57: glibc-upstream-2.34-26.patch +Patch58: glibc-upstream-2.34-27.patch +Patch59: glibc-upstream-2.34-28.patch +Patch60: glibc-upstream-2.34-29.patch +Patch61: glibc-upstream-2.34-30.patch +Patch62: glibc-upstream-2.34-31.patch +Patch63: glibc-upstream-2.34-32.patch +Patch64: glibc-upstream-2.34-33.patch +Patch65: glibc-upstream-2.34-34.patch +Patch66: glibc-upstream-2.34-35.patch +Patch67: glibc-upstream-2.34-36.patch +Patch68: glibc-upstream-2.34-37.patch +Patch69: glibc-upstream-2.34-38.patch +Patch70: glibc-upstream-2.34-39.patch +Patch71: glibc-upstream-2.34-40.patch +Patch72: glibc-upstream-2.34-41.patch +Patch73: glibc-upstream-2.34-42.patch +Patch74: glibc-upstream-2.34-43.patch +Patch75: glibc-upstream-2.34-44.patch +Patch76: glibc-upstream-2.34-45.patch +Patch77: glibc-upstream-2.34-46.patch +Patch78: glibc-upstream-2.34-47.patch +Patch79: glibc-upstream-2.34-48.patch +Patch80: glibc-upstream-2.34-49.patch +Patch81: glibc-rh2027789.patch +Patch82: glibc-rh2023422-1.patch +Patch83: glibc-rh2023422-2.patch +Patch84: glibc-rh2023422-3.patch +Patch85: glibc-rh2029410.patch +Patch86: glibc-upstream-2.34-50.patch +Patch87: glibc-upstream-2.34-51.patch +Patch88: glibc-upstream-2.34-52.patch +Patch89: glibc-upstream-2.34-53.patch +Patch90: glibc-rh1988382.patch +Patch91: glibc-upstream-2.34-54.patch +Patch92: glibc-upstream-2.34-55.patch +Patch93: glibc-upstream-2.34-56.patch +Patch94: glibc-upstream-2.34-57.patch +Patch95: glibc-upstream-2.34-58.patch +Patch96: glibc-upstream-2.34-59.patch +Patch97: glibc-upstream-2.34-60.patch +Patch98: glibc-upstream-2.34-61.patch +Patch99: glibc-upstream-2.34-62.patch +Patch100: glibc-upstream-2.34-63.patch +Patch101: glibc-upstream-2.34-64.patch +Patch102: glibc-upstream-2.34-65.patch +Patch103: glibc-upstream-2.34-66.patch +Patch104: glibc-upstream-2.34-67.patch +Patch105: glibc-upstream-2.34-68.patch +Patch106: glibc-upstream-2.34-69.patch +Patch107: glibc-upstream-2.34-70.patch +Patch108: glibc-upstream-2.34-71.patch +Patch109: glibc-upstream-2.34-72.patch +Patch110: glibc-upstream-2.34-73.patch +Patch111: glibc-rh2032647-1.patch +Patch112: glibc-rh2032647-2.patch +Patch113: glibc-rh2032647-3.patch +Patch114: glibc-rh2032647-4.patch +Patch115: glibc-rh2032647-5.patch +Patch116: glibc-rh2032647-6.patch +Patch117: glibc-rh2024347-1.patch +Patch118: glibc-rh2024347-2.patch +Patch119: glibc-rh2024347-3.patch +Patch120: glibc-rh2024347-4.patch +Patch121: glibc-rh2024347-5.patch +Patch122: glibc-rh2024347-6.patch +Patch123: glibc-rh2024347-7.patch +Patch124: glibc-rh2024347-8.patch +Patch125: glibc-rh2024347-9.patch +Patch126: glibc-rh2024347-10.patch +Patch127: glibc-rh2024347-11.patch +Patch128: glibc-rh2024347-12.patch +Patch129: glibc-rh2024347-13.patch +Patch130: glibc-rh2040657-1.patch +Patch131: glibc-rh2040657-2.patch +Patch132: glibc-rh2040657-3.patch +Patch133: glibc-rh2040657-4.patch +Patch134: glibc-rh2040657-5.patch +Patch135: glibc-rh2040657-6.patch +Patch136: glibc-rh2040657-7.patch +Patch137: glibc-rh2040657-8.patch +Patch138: glibc-rh2040657-9.patch +Patch139: glibc-rh2040657-10.patch +Patch140: glibc-rh2040657-11.patch +Patch141: glibc-rh2040657-12.patch +Patch142: glibc-upstream-2.34-74.patch +Patch143: glibc-upstream-2.34-75.patch +Patch144: glibc-upstream-2.34-76.patch +Patch145: glibc-upstream-2.34-77.patch +Patch146: glibc-upstream-2.34-78.patch +Patch147: glibc-upstream-2.34-79.patch +Patch148: glibc-upstream-2.34-80.patch +Patch149: glibc-upstream-2.34-81.patch +Patch150: glibc-upstream-2.34-82.patch +Patch151: glibc-upstream-2.34-83.patch +Patch152: glibc-upstream-2.34-84.patch +Patch153: glibc-upstream-2.34-85.patch +Patch154: glibc-upstream-2.34-86.patch +Patch155: glibc-upstream-2.34-87.patch +Patch156: glibc-upstream-2.34-88.patch +Patch157: glibc-upstream-2.34-89.patch +# glibc-2.34-90-g1b9cd6a721 only changes NEWS. +Patch158: glibc-upstream-2.34-91.patch +Patch159: glibc-upstream-2.34-92.patch +# glibc-2.34-93-g72123e1b56 only changes NEWS. +# glibc-2.34-94-g31186e2cb7 is glibc-rh2040657-1.patch. +# glibc-2.34-95-g511b244cc5 is glibc-rh2040657-2.patch. +# glibc-2.34-96-gde6cdd6875 is glibc-rh2040657-6.patch. +Patch160: glibc-upstream-2.34-97.patch +Patch161: glibc-upstream-2.34-98.patch +Patch162: glibc-upstream-2.34-99.patch +Patch163: glibc-c-utf8-locale-3.patch +Patch164: glibc-c-utf8-locale-4.patch +Patch165: glibc-c-utf8-locale-5.patch +Patch166: glibc-upstream-2.34-100.patch +Patch167: glibc-upstream-2.34-101.patch +Patch168: glibc-upstream-2.34-102.patch +Patch169: glibc-upstream-2.34-103.patch +Patch170: glibc-upstream-2.34-104.patch +Patch171: glibc-upstream-2.34-105.patch +Patch172: glibc-upstream-2.34-106.patch +Patch173: glibc-upstream-2.34-107.patch +Patch174: glibc-rh2058224-1.patch +Patch175: glibc-rh2058224-2.patch +Patch176: glibc-rh2058230.patch +Patch177: glibc-rh2054789.patch +Patch178: glibc-upstream-2.34-108.patch +# glibc-2.34-109-gd64b08d5ba only changes NEWS. +Patch179: glibc-upstream-2.34-110.patch +Patch180: glibc-upstream-2.34-111.patch +Patch181: glibc-upstream-2.34-112.patch +Patch182: glibc-upstream-2.34-113.patch +Patch183: glibc-upstream-2.34-114.patch +# glibc-2.34-115-gd5d1c95aaf only changes NEWS. +# glibc-2.34-116-g852361b5a3 is glibc-rh2054789.patch. +Patch184: glibc-upstream-2.34-117.patch +Patch185: glibc-upstream-2.34-118.patch +Patch186: glibc-upstream-2.34-119.patch +Patch187: glibc-upstream-2.34-120.patch +Patch188: glibc-upstream-2.34-121.patch +Patch189: glibc-upstream-2.34-122.patch +Patch190: glibc-upstream-2.34-123.patch +Patch191: glibc-upstream-2.34-124.patch +Patch192: glibc-upstream-2.34-125.patch +Patch193: glibc-upstream-2.34-126.patch +Patch194: glibc-upstream-2.34-127.patch +Patch195: glibc-upstream-2.34-128.patch +Patch196: glibc-upstream-2.34-129.patch +Patch197: glibc-upstream-2.34-130.patch +Patch198: glibc-upstream-2.34-131.patch +Patch199: glibc-upstream-2.34-132.patch +Patch200: glibc-upstream-2.34-133.patch +Patch201: glibc-upstream-2.34-134.patch +Patch202: glibc-upstream-2.34-135.patch +Patch203: glibc-upstream-2.34-136.patch +Patch204: glibc-upstream-2.34-137.patch +Patch205: glibc-upstream-2.34-138.patch +Patch206: glibc-upstream-2.34-139.patch +Patch207: glibc-upstream-2.34-140.patch +Patch208: glibc-upstream-2.34-141.patch +Patch209: glibc-upstream-2.34-142.patch +Patch210: glibc-upstream-2.34-143.patch +Patch211: glibc-upstream-2.34-144.patch +Patch212: glibc-upstream-2.34-145.patch +Patch213: glibc-upstream-2.34-146.patch +Patch214: glibc-upstream-2.34-147.patch +Patch215: glibc-upstream-2.34-148.patch +Patch216: glibc-upstream-2.34-149.patch +Patch217: glibc-upstream-2.34-150.patch +Patch218: glibc-upstream-2.34-151.patch +Patch219: glibc-upstream-2.34-152.patch +Patch220: glibc-upstream-2.34-153.patch +Patch221: glibc-upstream-2.34-154.patch +Patch222: glibc-upstream-2.34-155.patch +Patch223: glibc-upstream-2.34-156.patch +Patch224: glibc-upstream-2.34-157.patch +Patch225: glibc-upstream-2.34-158.patch +Patch226: glibc-upstream-2.34-159.patch +Patch227: glibc-upstream-2.34-160.patch +# glibc-2.34-161-gceed89d089 only changes NEWS. +Patch228: glibc-upstream-2.34-162.patch +Patch229: glibc-upstream-2.34-163.patch +Patch230: glibc-upstream-2.34-164.patch +Patch231: glibc-upstream-2.34-165.patch +Patch232: glibc-upstream-2.34-166.patch +Patch233: glibc-upstream-2.34-167.patch +Patch234: glibc-upstream-2.34-168.patch +Patch235: glibc-upstream-2.34-169.patch +Patch236: glibc-upstream-2.34-170.patch +Patch237: glibc-upstream-2.34-171.patch +Patch238: glibc-upstream-2.34-172.patch +Patch239: glibc-upstream-2.34-173.patch +Patch240: glibc-upstream-2.34-174.patch +Patch241: glibc-upstream-2.34-175.patch +Patch242: glibc-upstream-2.34-176.patch +Patch243: glibc-upstream-2.34-177.patch +Patch244: glibc-upstream-2.34-178.patch +Patch245: glibc-upstream-2.34-179.patch +Patch246: glibc-upstream-2.34-180.patch +Patch247: glibc-upstream-2.34-181.patch +Patch248: glibc-upstream-2.34-182.patch +Patch249: glibc-upstream-2.34-183.patch +Patch250: glibc-upstream-2.34-184.patch +Patch251: glibc-upstream-2.34-185.patch +Patch252: glibc-upstream-2.34-186.patch +Patch253: glibc-upstream-2.34-187.patch +Patch254: glibc-upstream-2.34-188.patch +Patch255: glibc-upstream-2.34-189.patch +Patch256: glibc-upstream-2.34-190.patch +Patch257: glibc-upstream-2.34-191.patch +Patch258: glibc-upstream-2.34-192.patch +Patch259: glibc-upstream-2.34-193.patch +Patch260: glibc-upstream-2.34-194.patch +Patch261: glibc-upstream-2.34-195.patch +Patch262: glibc-upstream-2.34-196.patch +Patch263: glibc-upstream-2.34-197.patch +Patch264: glibc-upstream-2.34-198.patch +Patch265: glibc-upstream-2.34-199.patch +Patch266: glibc-upstream-2.34-200.patch +Patch267: glibc-upstream-2.34-201.patch +Patch268: glibc-upstream-2.34-202.patch +Patch269: glibc-upstream-2.34-203.patch +Patch270: glibc-upstream-2.34-204.patch +Patch271: glibc-upstream-2.34-205.patch +Patch272: glibc-upstream-2.34-206.patch +Patch273: glibc-upstream-2.34-207.patch +Patch274: glibc-upstream-2.34-208.patch +Patch275: glibc-upstream-2.34-209.patch +Patch276: glibc-upstream-2.34-210.patch +Patch277: glibc-upstream-2.34-211.patch +Patch278: glibc-upstream-2.34-212.patch +Patch279: glibc-upstream-2.34-213.patch +Patch280: glibc-upstream-2.34-214.patch +Patch281: glibc-upstream-2.34-215.patch +Patch282: glibc-upstream-2.34-216.patch +Patch283: glibc-upstream-2.34-217.patch +Patch284: glibc-upstream-2.34-218.patch +Patch285: glibc-upstream-2.34-219.patch +Patch286: glibc-upstream-2.34-220.patch +Patch287: glibc-upstream-2.34-221.patch +Patch288: glibc-upstream-2.34-222.patch +Patch289: glibc-upstream-2.34-223.patch +Patch290: glibc-upstream-2.34-224.patch +Patch291: glibc-upstream-2.34-225.patch +Patch292: glibc-upstream-2.34-226.patch +Patch293: glibc-upstream-2.34-227.patch +Patch294: glibc-upstream-2.34-228.patch +Patch295: glibc-upstream-2.34-229.patch +Patch296: glibc-upstream-2.34-230.patch +Patch297: glibc-upstream-2.34-231.patch +Patch298: glibc-upstream-2.34-232.patch +Patch299: glibc-upstream-2.34-233.patch +Patch300: glibc-upstream-2.34-234.patch +Patch301: glibc-upstream-2.34-235.patch +Patch302: glibc-upstream-2.34-236.patch +Patch303: glibc-upstream-2.34-237.patch +Patch304: glibc-upstream-2.34-238.patch +Patch305: glibc-upstream-2.34-239.patch +Patch306: glibc-upstream-2.34-240.patch +Patch307: glibc-upstream-2.34-241.patch +Patch308: glibc-upstream-2.34-242.patch +Patch309: glibc-upstream-2.34-243.patch +Patch310: glibc-upstream-2.34-244.patch +Patch311: glibc-upstream-2.34-245.patch +Patch312: glibc-upstream-2.34-246.patch +Patch313: glibc-upstream-2.34-247.patch +Patch314: glibc-upstream-2.34-248.patch +Patch315: glibc-upstream-2.34-249.patch +Patch316: glibc-upstream-2.34-250.patch +Patch317: glibc-upstream-2.34-251.patch +Patch318: glibc-upstream-2.34-252.patch +Patch319: glibc-upstream-2.34-253.patch +Patch320: glibc-upstream-2.34-254.patch +Patch321: glibc-upstream-2.34-255.patch +Patch322: glibc-upstream-2.34-256.patch +Patch323: glibc-upstream-2.34-257.patch +Patch324: glibc-upstream-2.34-258.patch +Patch325: glibc-upstream-2.34-259.patch +Patch326: glibc-upstream-2.34-260.patch +Patch327: glibc-upstream-2.34-261.patch +Patch328: glibc-upstream-2.34-262.patch +Patch329: glibc-upstream-2.34-263.patch +Patch330: glibc-upstream-2.34-264.patch +Patch331: glibc-upstream-2.34-265.patch +Patch332: glibc-upstream-2.34-266.patch +Patch333: glibc-upstream-2.34-267.patch +Patch334: glibc-upstream-2.34-268.patch +Patch335: glibc-rh2085529-1.patch +Patch336: glibc-rh2085529-2.patch +Patch337: glibc-rh2085529-3.patch +Patch338: glibc-rh2085529-4.patch +Patch339: glibc-upstream-2.34-269.patch +Patch340: glibc-upstream-2.34-270.patch +Patch341: glibc-upstream-2.34-271.patch +Patch342: glibc-upstream-2.34-272.patch +Patch343: glibc-upstream-2.34-273.patch +Patch344: glibc-rh2096191-1.patch +Patch345: glibc-rh2096191-2.patch +Patch346: glibc-upstream-2.34-274.patch +Patch347: glibc-upstream-2.34-275.patch +Patch348: glibc-upstream-2.34-276.patch +Patch349: glibc-upstream-2.34-277.patch +Patch350: glibc-upstream-2.34-278.patch +Patch351: glibc-upstream-2.34-279.patch +Patch352: glibc-upstream-2.34-280.patch +Patch353: glibc-upstream-2.34-281.patch +Patch354: glibc-upstream-2.34-282.patch +Patch355: glibc-upstream-2.34-283.patch +Patch356: glibc-upstream-2.34-284.patch +Patch357: glibc-upstream-2.34-285.patch +Patch358: glibc-upstream-2.34-286.patch +Patch359: glibc-upstream-2.34-287.patch +Patch360: glibc-upstream-2.34-288.patch +Patch361: glibc-upstream-2.34-289.patch +Patch362: glibc-upstream-2.34-290.patch +Patch363: glibc-upstream-2.34-291.patch +Patch364: glibc-upstream-2.34-292.patch +Patch365: glibc-upstream-2.34-293.patch +Patch366: glibc-upstream-2.34-294.patch +Patch367: glibc-upstream-2.34-295.patch +Patch368: glibc-upstream-2.34-296.patch +Patch369: glibc-upstream-2.34-297.patch +Patch370: glibc-upstream-2.34-298.patch +Patch371: glibc-upstream-2.34-299.patch +Patch372: glibc-upstream-2.34-300.patch +Patch373: glibc-upstream-2.34-301.patch +Patch374: glibc-upstream-2.34-302.patch +Patch375: glibc-upstream-2.34-303.patch +Patch376: glibc-upstream-2.34-304.patch +Patch377: glibc-upstream-2.34-305.patch +Patch378: glibc-upstream-2.34-306.patch +Patch379: glibc-upstream-2.34-307.patch +Patch380: glibc-upstream-2.34-308.patch +Patch381: glibc-rh2118666.patch +Patch382: glibc-rh2128615-1.patch +Patch383: glibc-rh2128615-2.patch +Patch384: glibc-rh2128615-3.patch +Patch385: glibc-rh2117712-1.patch +Patch386: glibc-rh2117712-2.patch +Patch387: glibc-rh2117712-3.patch +Patch388: glibc-rh2117712-4.patch +Patch389: glibc-rh2117712-5.patch +Patch390: glibc-rh2117712-6.patch +Patch391: glibc-upstream-2.34-309.patch +Patch392: glibc-upstream-2.34-310.patch +Patch393: glibc-upstream-2.34-311.patch +Patch394: glibc-upstream-2.34-312.patch +# glibc-2.34-313-gbc5cb538e5 backported above as glibc-rh2118666.patch. +Patch395: glibc-upstream-2.34-314.patch +Patch396: glibc-upstream-2.34-315.patch +Patch397: glibc-upstream-2.34-316.patch +Patch398: glibc-upstream-2.34-317.patch +Patch399: glibc-upstream-2.34-318.patch +Patch400: glibc-upstream-2.34-319.patch +Patch401: glibc-upstream-2.34-320.patch +Patch402: glibc-upstream-2.34-321.patch +Patch403: glibc-upstream-2.34-322.patch +Patch404: glibc-upstream-2.34-323.patch +Patch405: glibc-upstream-2.34-324.patch +Patch406: glibc-upstream-2.34-325.patch +Patch407: glibc-upstream-2.34-326.patch +Patch408: glibc-upstream-2.34-327.patch +# glibc-2.34-328-g2def56a349 conflicts with glibc-rh2096191-2.patch; +# glibc-rh2129005.patch contains the original master branch commit instead. +Patch409: glibc-rh2129005.patch +Patch410: glibc-upstream-2.34-329.patch +Patch411: glibc-upstream-2.34-330.patch +Patch412: glibc-upstream-2.34-331.patch +Patch413: glibc-upstream-2.34-332.patch +Patch414: glibc-upstream-2.34-333.patch +Patch415: glibc-upstream-2.34-334.patch +Patch416: glibc-upstream-2.34-335.patch +Patch417: glibc-upstream-2.34-336.patch +Patch418: glibc-upstream-2.34-337.patch +Patch419: glibc-upstream-2.34-338.patch +Patch420: glibc-upstream-2.34-339.patch +Patch421: glibc-upstream-2.34-340.patch +Patch422: glibc-upstream-2.34-341.patch +Patch423: glibc-upstream-2.34-342.patch +Patch424: glibc-upstream-2.34-343.patch +Patch425: glibc-upstream-2.34-344.patch +Patch426: glibc-upstream-2.34-345.patch +Patch427: glibc-upstream-2.34-346.patch +Patch428: glibc-upstream-2.34-347.patch +Patch429: glibc-upstream-2.34-348.patch +Patch430: glibc-upstream-2.34-349.patch +Patch431: glibc-upstream-2.34-350.patch +Patch432: glibc-upstream-2.34-351.patch +Patch433: glibc-upstream-2.34-352.patch +Patch434: glibc-upstream-2.34-353.patch +Patch435: glibc-upstream-2.34-354.patch +Patch436: glibc-upstream-2.34-355.patch +Patch437: glibc-upstream-2.34-356.patch +Patch438: glibc-upstream-2.34-357.patch +Patch439: glibc-upstream-2.34-358.patch +Patch440: glibc-upstream-2.34-359.patch +# glibc-2.34-360-g75b0edb7ef only changes NEWS. +Patch441: glibc-upstream-2.34-361.patch +Patch442: glibc-upstream-2.34-362.patch +Patch443: glibc-upstream-2.34-363.patch +Patch444: glibc-upstream-2.34-364.patch +Patch445: glibc-upstream-2.34-365.patch +Patch446: glibc-rh2149102.patch +Patch447: glibc-upstream-2.34-366.patch +Patch448: glibc-upstream-2.34-367.patch +Patch449: glibc-upstream-2.34-368.patch +Patch450: glibc-upstream-2.34-369.patch +Patch451: glibc-upstream-2.34-370.patch +Patch452: glibc-upstream-2.34-371.patch +Patch453: glibc-upstream-2.34-372.patch +Patch454: glibc-upstream-2.34-373.patch +Patch455: glibc-upstream-2.34-374.patch +Patch456: glibc-upstream-2.34-375.patch +Patch457: glibc-upstream-2.34-376.patch +Patch458: glibc-upstream-2.34-377.patch +Patch459: glibc-upstream-2.34-378.patch +Patch460: glibc-upstream-2.34-379.patch +Patch461: glibc-upstream-2.34-380.patch +Patch462: glibc-upstream-2.34-381.patch +Patch463: glibc-upstream-2.34-382.patch +Patch464: glibc-upstream-2.34-383.patch +Patch465: glibc-upstream-2.34-384.patch +Patch466: glibc-rh2162962.patch +Patch467: glibc-upstream-2.34-385.patch +Patch468: glibc-upstream-2.34-386.patch +# glibc-upstream-2.34-387.patch is a NEWS-only update. Skipped downstream. +Patch469: glibc-upstream-2.34-388.patch +Patch470: glibc-upstream-2.34-389.patch + +############################################################################## +# 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) + +# We need libgcc for cancellation support in POSIX threads. +Requires: libgcc%{_isa} + +Requires: glibc-common = %{version}-%{release} + +# Various components (regex, glob) have been imported from gnulib. +Provides: bundled(gnulib) + +Requires(pre): basesystem +Requires: basesystem + +%ifarch %{ix86} +# Automatically install the 32-bit variant if the 64-bit variant has +# been installed. This covers the case when glibc.i686 is installed +# after nss_*.x86_64. (See below for the other ordering.) +Recommends: (nss_db(x86-32) if nss_db(x86-64)) +Recommends: (nss_hesiod(x86-32) if nss_hesiod(x86-64)) +%endif + +# 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} +%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 GCC version is needed for -fstack-clash-protection support. +BuildRequires: gcc >= 7.2.1-6 +%define enablekernel 3.2 +Conflicts: kernel < %{enablekernel} +%define target %{_target_cpu}-redhat-linux +%ifarch %{arm} +%define target %{_target_cpu}-redhat-linuxeabi +%endif +%ifarch ppc64le +%define target ppc64le-redhat-linux +%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-17 is needed for --generate-missing-build-notes. +BuildRequires: binutils >= 2.30-17 + +# Earlier releases have broken support for IRELATIVE relocations +Conflicts: prelink < 0.4.2 + +%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 + +# The testsuite runs mtrace, which is a perl script +BuildRequires: perl-interpreter +%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 +%global __provides_exclude ^libc_malloc_debug\\.so.*$ + +# 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 language-neutral support e.g. C, POSIX, and C.UTF-8 locales. +# In the past we used to install the glibc-all-langpacks by default +# but we no longer do this to minimize container and VM sizes. +# Today you must actively use the language packs infrastructure to +# install language support. +Requires: glibc-langpack = %{version}-%{release} +Suggests: glibc-minimal-langpack = %{version}-%{release} + +# Suggest extra gconv modules so that they are installed by default but can be +# removed if needed to build a minimal OS image. +Recommends: glibc-gconv-extra%{_isa} = %{version}-%{release} +# Use redhat-rpm-config as a marker for a buildroot configuration, and +# unconditionally pull in glibc-gconv-extra in that case. +Requires: (glibc-gconv-extra%{_isa} = %{version}-%{release} if redhat-rpm-config) + +%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: %{name} = %{version}-%{release} +Requires: libxcrypt-devel%{_isa} >= 4.0.0 +Requires: kernel-headers >= 3.2 +BuildRequires: kernel-headers >= 3.2 +%if %{need_headers_package} +Requires: %{headers_package_name} = %{version}-%{release} +%endif +%if !(0%{?rhel} > 0 && %{need_headers_package}) +# For backwards compatibility, when the glibc-headers package existed. +Provides: glibc-headers = %{version}-%{release} +Provides: glibc-headers(%{_target_cpu}) +Obsoletes: glibc-headers < %{version}-%{release} +%endif + +%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 "doc" sub-package +############################################################################## +%if %{with docs} +%package doc +Summary: Documentation for GNU libc +BuildArch: noarch +Requires: %{name} = %{version}-%{release} + +# 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 + +%description doc +The glibc-doc package contains The GNU C Library Reference Manual in info +format. Additional package documentation is also provided. +%endif + +############################################################################## +# 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 avoids file conflicts between the architecture- +# specific glibc-devel variants. +# Files like gnu/stubs.h which have gnu/stubs-32.h (i686) and gnu/stubs-64.h +# are included in glibc-headers, but the -32 and -64 files are in their +# respective i686 and x86_64 devel packages. +############################################################################## +%if %{need_headers_package} +%package -n %{headers_package_name} +Summary: Additional internal header files for glibc-devel. +Requires: %{name} = %{version}-%{release} +%if 0%{?rhel} > 0 +Provides: %{name}-headers(%{_target_cpu}) +Obsoletes: glibc-headers-x86 < %{version}-%{release} +Obsoletes: glibc-headers-s390 < %{version}-%{release} +%else +BuildArch: noarch +%endif + +%description -n %{headers_package_name} +The %{headers_package_name} package contains the architecture-specific +header files which cannot be included in glibc-devel package. +%endif + +############################################################################## +# glibc "common" sub-package +############################################################################## +%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: +-- To make lua-mode happy: ' + +-- List of supported locales. This is used to generate the langpack +-- subpackages below. This table needs adjustments if the set of +-- glibc locales changes. "code" is the glibc code for the language +-- (before the "_". "name" is the English translation of the language +-- name (for use in subpackage descriptions). "regions" is a table of +-- variant specifiers (after the "_", excluding "@" and "." +-- variants/charset specifiers). The table must be sorted by the code +-- field, and the regions table must be sorted as well. +-- +-- English translations of language names can be obtained using (for +-- the "aa" language in this example): +-- +-- python3 -c 'import langtable; print(langtable.language_name("aa", languageIdQuery="en"))' + +local locales = { + { code="aa", name="Afar", regions={ "DJ", "ER", "ET" } }, + { code="af", name="Afrikaans", regions={ "ZA" } }, + { code="agr", name="Aguaruna", regions={ "PE" } }, + { code="ak", name="Akan", regions={ "GH" } }, + { code="am", name="Amharic", regions={ "ET" } }, + { code="an", name="Aragonese", regions={ "ES" } }, + { code="anp", name="Angika", regions={ "IN" } }, + { + code="ar", + name="Arabic", + regions={ + "AE", + "BH", + "DZ", + "EG", + "IN", + "IQ", + "JO", + "KW", + "LB", + "LY", + "MA", + "OM", + "QA", + "SA", + "SD", + "SS", + "SY", + "TN", + "YE" + } + }, + { code="as", name="Assamese", regions={ "IN" } }, + { code="ast", name="Asturian", regions={ "ES" } }, + { code="ayc", name="Southern Aymara", regions={ "PE" } }, + { code="az", name="Azerbaijani", regions={ "AZ", "IR" } }, + { code="be", name="Belarusian", regions={ "BY" } }, + { code="bem", name="Bemba", regions={ "ZM" } }, + { code="ber", name="Berber", regions={ "DZ", "MA" } }, + { code="bg", name="Bulgarian", regions={ "BG" } }, + { code="bhb", name="Bhili", regions={ "IN" } }, + { code="bho", name="Bhojpuri", regions={ "IN", "NP" } }, + { code="bi", name="Bislama", regions={ "VU" } }, + { code="bn", name="Bangla", regions={ "BD", "IN" } }, + { code="bo", name="Tibetan", regions={ "CN", "IN" } }, + { code="br", name="Breton", regions={ "FR" } }, + { code="brx", name="Bodo", regions={ "IN" } }, + { code="bs", name="Bosnian", regions={ "BA" } }, + { code="byn", name="Blin", regions={ "ER" } }, + { code="ca", name="Catalan", regions={ "AD", "ES", "FR", "IT" } }, + { code="ce", name="Chechen", regions={ "RU" } }, + { code="chr", name="Cherokee", regions={ "US" } }, + { code="ckb", name="Central Kurdish", regions={ "IQ" } }, + { code="cmn", name="Mandarin Chinese", regions={ "TW" } }, + { code="crh", name="Crimean Turkish", regions={ "UA" } }, + { code="cs", name="Czech", regions={ "CZ" } }, + { code="csb", name="Kashubian", regions={ "PL" } }, + { code="cv", name="Chuvash", regions={ "RU" } }, + { code="cy", name="Welsh", regions={ "GB" } }, + { code="da", name="Danish", regions={ "DK" } }, + { + code="de", + name="German", + regions={ "AT", "BE", "CH", "DE", "IT", "LI", "LU" } + }, + { code="doi", name="Dogri", regions={ "IN" } }, + { code="dsb", name="Lower Sorbian", regions={ "DE" } }, + { code="dv", name="Divehi", regions={ "MV" } }, + { code="dz", name="Dzongkha", regions={ "BT" } }, + { code="el", name="Greek", regions={ "CY", "GR" } }, + { + code="en", + name="English", + regions={ + "AG", + "AU", + "BW", + "CA", + "DK", + "GB", + "HK", + "IE", + "IL", + "IN", + "NG", + "NZ", + "PH", + "SC", + "SG", + "US", + "ZA", + "ZM", + "ZW" + } + }, + { code="eo", name="Esperanto", regions={} }, + { + code="es", + name="Spanish", + regions={ + "AR", + "BO", + "CL", + "CO", + "CR", + "CU", + "DO", + "EC", + "ES", + "GT", + "HN", + "MX", + "NI", + "PA", + "PE", + "PR", + "PY", + "SV", + "US", + "UY", + "VE" + } + }, + { code="et", name="Estonian", regions={ "EE" } }, + { code="eu", name="Basque", regions={ "ES" } }, + { code="fa", name="Persian", regions={ "IR" } }, + { code="ff", name="Fulah", regions={ "SN" } }, + { code="fi", name="Finnish", regions={ "FI" } }, + { code="fil", name="Filipino", regions={ "PH" } }, + { code="fo", name="Faroese", regions={ "FO" } }, + { code="fr", name="French", regions={ "BE", "CA", "CH", "FR", "LU" } }, + { code="fur", name="Friulian", regions={ "IT" } }, + { code="fy", name="Western Frisian", regions={ "DE", "NL" } }, + { code="ga", name="Irish", regions={ "IE" } }, + { code="gd", name="Scottish Gaelic", regions={ "GB" } }, + { code="gez", name="Geez", regions={ "ER", "ET" } }, + { code="gl", name="Galician", regions={ "ES" } }, + { code="gu", name="Gujarati", regions={ "IN" } }, + { code="gv", name="Manx", regions={ "GB" } }, + { code="ha", name="Hausa", regions={ "NG" } }, + { code="hak", name="Hakka Chinese", regions={ "TW" } }, + { code="he", name="Hebrew", regions={ "IL" } }, + { code="hi", name="Hindi", regions={ "IN" } }, + { code="hif", name="Fiji Hindi", regions={ "FJ" } }, + { code="hne", name="Chhattisgarhi", regions={ "IN" } }, + { code="hr", name="Croatian", regions={ "HR" } }, + { code="hsb", name="Upper Sorbian", regions={ "DE" } }, + { code="ht", name="Haitian Creole", regions={ "HT" } }, + { code="hu", name="Hungarian", regions={ "HU" } }, + { code="hy", name="Armenian", regions={ "AM" } }, + { code="ia", name="Interlingua", regions={ "FR" } }, + { code="id", name="Indonesian", regions={ "ID" } }, + { code="ig", name="Igbo", regions={ "NG" } }, + { code="ik", name="Inupiaq", regions={ "CA" } }, + { code="is", name="Icelandic", regions={ "IS" } }, + { code="it", name="Italian", regions={ "CH", "IT" } }, + { code="iu", name="Inuktitut", regions={ "CA" } }, + { code="ja", name="Japanese", regions={ "JP" } }, + { code="ka", name="Georgian", regions={ "GE" } }, + { code="kab", name="Kabyle", regions={ "DZ" } }, + { code="kk", name="Kazakh", regions={ "KZ" } }, + { code="kl", name="Kalaallisut", regions={ "GL" } }, + { code="km", name="Khmer", regions={ "KH" } }, + { code="kn", name="Kannada", regions={ "IN" } }, + { code="ko", name="Korean", regions={ "KR" } }, + { code="kok", name="Konkani", regions={ "IN" } }, + { code="ks", name="Kashmiri", regions={ "IN" } }, + { code="ku", name="Kurdish", regions={ "TR" } }, + { code="kw", name="Cornish", regions={ "GB" } }, + { code="ky", name="Kyrgyz", regions={ "KG" } }, + { code="lb", name="Luxembourgish", regions={ "LU" } }, + { code="lg", name="Ganda", regions={ "UG" } }, + { code="li", name="Limburgish", regions={ "BE", "NL" } }, + { code="lij", name="Ligurian", regions={ "IT" } }, + { code="ln", name="Lingala", regions={ "CD" } }, + { code="lo", name="Lao", regions={ "LA" } }, + { code="lt", name="Lithuanian", regions={ "LT" } }, + { code="lv", name="Latvian", regions={ "LV" } }, + { code="lzh", name="Literary Chinese", regions={ "TW" } }, + { code="mag", name="Magahi", regions={ "IN" } }, + { code="mai", name="Maithili", regions={ "IN", "NP" } }, + { code="mfe", name="Morisyen", regions={ "MU" } }, + { code="mg", name="Malagasy", regions={ "MG" } }, + { code="mhr", name="Meadow Mari", regions={ "RU" } }, + { code="mi", name="Maori", regions={ "NZ" } }, + { code="miq", name="Miskito", regions={ "NI" } }, + { code="mjw", name="Karbi", regions={ "IN" } }, + { code="mk", name="Macedonian", regions={ "MK" } }, + { code="ml", name="Malayalam", regions={ "IN" } }, + { code="mn", name="Mongolian", regions={ "MN" } }, + { code="mni", name="Manipuri", regions={ "IN" } }, + { code="mnw", name="Mon", regions={ "MM" } }, + { code="mr", name="Marathi", regions={ "IN" } }, + { code="ms", name="Malay", regions={ "MY" } }, + { code="mt", name="Maltese", regions={ "MT" } }, + { code="my", name="Burmese", regions={ "MM" } }, + { code="nan", name="Min Nan Chinese", regions={ "TW" } }, + { code="nb", name="Norwegian BokmÃ¥l", regions={ "NO" } }, + { code="nds", name="Low German", regions={ "DE", "NL" } }, + { code="ne", name="Nepali", regions={ "NP" } }, + { code="nhn", name="Tlaxcala-Puebla Nahuatl", regions={ "MX" } }, + { code="niu", name="Niuean", regions={ "NU", "NZ" } }, + { code="nl", name="Dutch", regions={ "AW", "BE", "NL" } }, + { code="nn", name="Norwegian Nynorsk", regions={ "NO" } }, + { code="nr", name="South Ndebele", regions={ "ZA" } }, + { code="nso", name="Northern Sotho", regions={ "ZA" } }, + { code="oc", name="Occitan", regions={ "FR" } }, + { code="om", name="Oromo", regions={ "ET", "KE" } }, + { code="or", name="Odia", regions={ "IN" } }, + { code="os", name="Ossetic", regions={ "RU" } }, + { code="pa", name="Punjabi", regions={ "IN", "PK" } }, + { code="pap", name="Papiamento", regions={ "AW", "CW" } }, + { code="pl", name="Polish", regions={ "PL" } }, + { code="ps", name="Pashto", regions={ "AF" } }, + { code="pt", name="Portuguese", regions={ "BR", "PT" } }, + { code="quz", name="Cusco Quechua", regions={ "PE" } }, + { code="raj", name="Rajasthani", regions={ "IN" } }, + { code="ro", name="Romanian", regions={ "RO" } }, + { code="ru", name="Russian", regions={ "RU", "UA" } }, + { code="rw", name="Kinyarwanda", regions={ "RW" } }, + { code="sa", name="Sanskrit", regions={ "IN" } }, + { code="sah", name="Sakha", regions={ "RU" } }, + { code="sat", name="Santali", regions={ "IN" } }, + { code="sc", name="Sardinian", regions={ "IT" } }, + { code="sd", name="Sindhi", regions={ "IN" } }, + { code="se", name="Northern Sami", regions={ "NO" } }, + { code="sgs", name="Samogitian", regions={ "LT" } }, + { code="shn", name="Shan", regions={ "MM" } }, + { code="shs", name="Shuswap", regions={ "CA" } }, + { code="si", name="Sinhala", regions={ "LK" } }, + { code="sid", name="Sidamo", regions={ "ET" } }, + { code="sk", name="Slovak", regions={ "SK" } }, + { code="sl", name="Slovenian", regions={ "SI" } }, + { code="sm", name="Samoan", regions={ "WS" } }, + { code="so", name="Somali", regions={ "DJ", "ET", "KE", "SO" } }, + { code="sq", name="Albanian", regions={ "AL", "MK" } }, + { code="sr", name="Serbian", regions={ "ME", "RS" } }, + { code="ss", name="Swati", regions={ "ZA" } }, + { code="st", name="Southern Sotho", regions={ "ZA" } }, + { code="sv", name="Swedish", regions={ "FI", "SE" } }, + { code="sw", name="Swahili", regions={ "KE", "TZ" } }, + { code="szl", name="Silesian", regions={ "PL" } }, + { code="ta", name="Tamil", regions={ "IN", "LK" } }, + { code="tcy", name="Tulu", regions={ "IN" } }, + { code="te", name="Telugu", regions={ "IN" } }, + { code="tg", name="Tajik", regions={ "TJ" } }, + { code="th", name="Thai", regions={ "TH" } }, + { code="the", name="Chitwania Tharu", regions={ "NP" } }, + { code="ti", name="Tigrinya", regions={ "ER", "ET" } }, + { code="tig", name="Tigre", regions={ "ER" } }, + { code="tk", name="Turkmen", regions={ "TM" } }, + { code="tl", name="Tagalog", regions={ "PH" } }, + { code="tn", name="Tswana", regions={ "ZA" } }, + { code="to", name="Tongan", regions={ "TO" } }, + { code="tpi", name="Tok Pisin", regions={ "PG" } }, + { code="tr", name="Turkish", regions={ "CY", "TR" } }, + { code="ts", name="Tsonga", regions={ "ZA" } }, + { code="tt", name="Tatar", regions={ "RU" } }, + { code="ug", name="Uyghur", regions={ "CN" } }, + { code="uk", name="Ukrainian", regions={ "UA" } }, + { code="unm", name="Unami language", regions={ "US" } }, + { code="ur", name="Urdu", regions={ "IN", "PK" } }, + { code="uz", name="Uzbek", regions={ "UZ" } }, + { code="ve", name="Venda", regions={ "ZA" } }, + { code="vi", name="Vietnamese", regions={ "VN" } }, + { code="wa", name="Walloon", regions={ "BE" } }, + { code="wae", name="Walser", regions={ "CH" } }, + { code="wal", name="Wolaytta", regions={ "ET" } }, + { code="wo", name="Wolof", regions={ "SN" } }, + { code="xh", name="Xhosa", regions={ "ZA" } }, + { code="yi", name="Yiddish", regions={ "US" } }, + { code="yo", name="Yoruba", regions={ "NG" } }, + { code="yue", name="Cantonese", regions={ "HK" } }, + { code="yuw", name="Yau", regions={ "PG" } }, + { code="zh", name="Mandarin Chinese", regions={ "CN", "HK", "SG", "TW" } }, + { code="zu", name="Zulu", regions={ "ZA" } } +} + +-- Prints a list of LANGUAGE "_" REGION pairs. The output is expected +-- to be identical to parse-SUPPORTED.py. Called from the %%prep section. +function print_locale_pairs() + for i = 1, #locales do + local locale = locales[i] + if #locale.regions == 0 then + print(locale.code .. "\n") + else + for j = 1, #locale.regions do + print(locale.code .. "_" .. locale.regions[j] .. "\n") + end + end + end +end + +local function compute_supplements(locale) + local lang = locale.code + local regions = locale.regions + result = "langpacks-core-" .. lang + for i = 1, #regions do + result = result .. " or langpacks-core-" .. lang .. "_" .. regions[i] + end + return result +end + +-- Emit the definition of a language pack package. +local function lang_package(locale) + local lang = locale.code + local langname = locale.name + local suppl = compute_supplements(locale) + print(rpm.expand([[ + +%package langpack-]]..lang..[[ + +Summary: Locale data for ]]..langname..[[ + +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 ]]..langname..[[ language in your applications. +%files -f langpack-]]..lang..[[.filelist langpack-]]..lang..[[ +]])) +end + +for i = 1, #locales do + lang_package(locales[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 package. 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. +%files minimal-langpack + +# Infrequently used iconv converter modules. +%package gconv-extra +Summary: All iconv converter modules for %{name}. +Requires: %{name}%{_isa} = %{version}-%{release} +Requires: %{name}-common = %{version}-%{release} + +%description gconv-extra +This package contains all iconv converter modules built in %{name}. + +############################################################################## +# glibc "nscd" sub-package +# +# Deprecated in Fedora 34 and planned for removal in Fedora 35. +# +# systemd-resolved is now enabled by default for DNS caching in Fedora, and +# sssd is capable of caching the remaining named services that nscd handles. +# It is therefore time to retire nscd in Fedora and move to more modern named +# services caches. +# +# For details, see: +# bug 1905135: https://fedoraproject.org/wiki/Changes/DeprecateNSCD +# bug 1905142: https://fedoraproject.org/wiki/Changes/RemoveNSCD +############################################################################## +%package -n nscd +Summary: A Name Service Caching Daemon (nscd). +# Fedora 35 is planned for release on Oct 26 2021, with nscd removed +Provides: deprecated() = 20211026 +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} +%ifarch x86_64 +# Automatically install the 32-bit variant if the 64-bit variant has +# been installed. This covers the case when glibc.i686 is installed +# before nss_db.x86_64. (See above for the other ordering.) +Recommends: (nss_db(x86-32) if glibc(x86-32)) +%endif + +%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} +%ifarch x86_64 +# Automatically install the 32-bit variant if the 64-bit variant has +# been installed. This covers the case when glibc.i686 is installed +# before nss_hesiod.x86_64. (See above for the other ordering.) +Recommends: (nss_hesiod(x86-32) if glibc(x86-32)) +%endif + +%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. + +%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. + +%if %{without bootstrap} +%package -n %sysroot_package_arch +Summary: Sysroot package for glibc, %{_arch} architecture +BuildArch: noarch +Provides: sysroot-%{_arch}-%{name} +# The files are not usable for execution, so do not provide nor +# require anything. +AutoReqProv: no + +%description -n %sysroot_package_arch +This package contains development files for the glibc package +that can be installed across architectures. +%dnl %%{without bootstrap} +%endif + +############################################################################## +# 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 locales table is compatible with the locales table +# in the spec file. +set +x +echo '%{lua: print_locale_pairs()}' > localedata/SUPPORTED.spec +set -x +python3 %{SOURCE11} localedata/SUPPORTED > localedata/SUPPORTED.glibc +diff -u \ + --label "spec file" localedata/SUPPORTED.spec \ + --label "glibc localedata/SUPPORTED" localedata/SUPPORTED.glibc +rm localedata/SUPPORTED.spec localedata/SUPPORTED.glibc + +############################################################################## +# Build glibc... +############################################################################## +%build +# Log osystem 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=armv8-a+lse" \ + "-march=armv8.1-a" \ + "-march=haswell" \ + "-march=i686" \ + "-march=x86-64" \ + "-march=x86-64-v2" \ + "-march=x86-64-v3" \ + "-march=x86-64-v4" \ + "-march=z13" \ + "-march=z14" \ + "-march=z15" \ + "-march=zEC12" \ + "-mbranch-protection=standard" \ + "-mcpu=power10" \ + "-mcpu=power8" \ + "-mcpu=power9" \ + "-mfpmath=sse" \ + "-msse2" \ + "-mstackrealign" \ + "-mtune=generic" \ + "-mtune=power10" \ + "-mtune=power8" \ + "-mtune=power9" \ + "-mtune=z13" \ + "-mtune=z14" \ + "-mtune=z15" \ + "-mtune=zEC12" \ + "-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1" \ + +# Use the RHEL 8 baseline for the early dynamic loader code, so that +# running on too old CPUs results in a diagnostic. +%if 0%{?rhel} >= 9 +%ifarch ppc64le +%define glibc_rtld_early_cflags -mcpu=power8 +%endif +%ifarch s390x +%define glibc_rtld_early_cflags -march=z13 +%endif +%ifarch x86_64 +%define glibc_rtld_early_cflags -march=x86-64 +%endif +%endif + +# libc_nonshared.a cannot be built with the default hardening flags +# because the glibc build system is incompatible with +# -D_FORTIFY_SOURCE. The object files need to be marked as to be +# skipped in annobin annotations. (The -specs= variant of activating +# annobin does not work here because of flag ordering issues.) +# See . +BuildFlagsNonshared="-fplugin=annobin -fplugin-arg-annobin-disable -Wa,--generate-missing-build-notes=yes" + +# 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 \ + --enable-tunables \ + --enable-systemtap \ + ${core_with_options} \ + %{?glibc_rtld_early_cflags:--with-rtld-early-cflags=%glibc_rtld_early_cflags} \ +%ifarch x86_64 %{ix86} + --enable-cet \ +%endif +%ifarch %{ix86} + --disable-multi-arch \ +%endif +%if %{without werror} + --disable-werror \ +%endif + --disable-profile \ +%if %{with bootstrap} + --without-selinux \ +%endif +%ifarch aarch64 + --enable-memory-tagging \ +%endif + --disable-crypt || + { cat config.log; false; } + + %make_build -r %{glibc_make_flags} + popd +} + +# Default set of compiler options. +build + +%if %{buildpower10} +( + GCC="$GCC -mcpu=power10 -mtune=power10" + GXX="$GXX -mcpu=power10 -mtune=power10" + core_with_options="--with-cpu=power10" + build power10 +) +%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 {} \; + +# 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: +pushd build-%{target} +%make_build install_root=%{glibc_sysroot} install +%make_build install_root=%{glibc_sysroot} \ + install-locale-files -C ../localedata objdir=`pwd` +popd +# Locale creation via install-locale-files does not group identical files +# via hardlinks, so we must group them ourselves. +hardlink -c %{glibc_sysroot}/usr/lib/locale + +# 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 + 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 + done +} + +%if %{buildpower10} +pushd build-%{target}-power10 +install_different "$RPM_BUILD_ROOT/%{_libdir}/glibc-hwcaps" power10 .. +popd +%endif + +############################################################################## +# Remove the files we don't want to distribute +############################################################################## + +# 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* + +# Copy the debugger interface documentation over to the right location +mkdir -p %{glibc_sysroot}%{_docdir}/glibc +cp elf/rtld-debugger-interface.txt %{glibc_sysroot}%{_docdir}/glibc +%else +rm -f %{glibc_sysroot}%{_infodir}/dir +rm -f %{glibc_sysroot}%{_infodir}/libc.info* +%endif + +############################################################################## +# Create locale sub-package file lists +############################################################################## + +olddir=`pwd` +pushd %{glibc_sysroot}%{_prefix}/lib/locale +rm -f locale-archive +$olddir/build-%{target}/elf/ld.so \ + --library-path $olddir/build-%{target}/ \ + $olddir/build-%{target}/locale/localedef \ + --alias-file=$olddir/intl/locale.alias \ + --prefix %{glibc_sysroot} --add-to-archive \ + eo *_* +# Historically, glibc-all-langpacks deleted the file on updates (sic), +# so we need to restore it in the posttrans scriptlet (like the old +# glibc-all-langpacks versions) +ln locale-archive locale-archive.real + +# Almost half the LC_CTYPE files in langpacks are identical to the C.utf8 +# variant which is installed by default. When we keep them as hardlinks, +# each langpack ends up retaining a copy. If we convert these to symbolic +# links instead, we save ~350K each when they get installed that way. +# +# LC_MEASUREMENT and LC_PAPER also have several duplicates but we don't +# bother with these because they are only ~30 bytes each. +pushd %{glibc_sysroot}/usr/lib/locale +for f in $(find eo *_* -samefile C.utf8/LC_CTYPE); do + rm $f && ln -s '../C.utf8/LC_CTYPE' $f +done +popd + +# 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 . + +############################################################################## +# Install configuration files for services +############################################################################## + +install -p -m 644 nss/nsswitch.conf %{glibc_sysroot}/etc/nsswitch.conf + +# 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 %{SOURCE1} %{buildroot}%{_tmpfilesdir} +mkdir -p %{glibc_sysroot}/lib/systemd/system +install -m 644 nscd/nscd.service nscd/nscd.socket %{glibc_sysroot}/lib/systemd/system + +# 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 +mkdir -p %{glibc_sysroot}/etc/sysconfig +truncate -s 0 %{glibc_sysroot}/etc/sysconfig/nscd +truncate -s 0 %{glibc_sysroot}/etc/gai.conf + +# 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 + +# 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 inet/etc.rpc %{glibc_sysroot}/etc/rpc + +%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 %{SOURCE2} %{SOURCE3}; 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/ +%endif + +# 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 + +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} + +# Move libpcprofile.so and libmemusage.so into the proper library directory. +# They can be moved without any real consequences because users would not use +# them directly. +mkdir -p %{glibc_sysroot}%{_libdir} +mv -f %{glibc_sysroot}/%{_lib}/lib{pcprofile,memusage}.so \ + %{glibc_sysroot}%{_libdir} + +# Disallow linking against libc_malloc_debug. +rm %{glibc_sysroot}%{_libdir}/libc_malloc_debug.so + +# Strip all of the installed object files. +strip -g %{glibc_sysroot}%{_libdir}/*.o + +# 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 + +############################################################################### +# Sysroot package creation. +############################################################################### + +%if %{without bootstrap} +mkdir -p %{glibc_sysroot}/%{sysroot_prefix} +pushd %{glibc_sysroot}/%{sysroot_prefix} +mkdir -p usr/lib usr/lib64 + +cp -a %{glibc_sysroot}/%{_prefix}/include usr/. +for lib in lib lib64; do + for pfx in "" %{_prefix}/; do + if test -d %{glibc_sysroot}/$pfx$lib ; then + # Implement UsrMove: everything goes into usr/$lib. Only + # copy files directly in $lib. + find %{glibc_sysroot}/$pfx$lib -maxdepth 1 -type f \ + | xargs -I '{}' cp '{}' usr/$lib/. + # Symbolic links need to be adjusted for UsrMove: They + # need to stay within the same directory. + for sl in `find %{glibc_sysroot}/$pfx$lib -maxdepth 1 -type l`; do + set +x + slbase=$(basename $sl) + sltarget=$(basename $(readlink $sl)) + if ! test -r usr/$lib/$sltarget; then + echo "$sl: inferred $sltarget ($(readlink $sl)) missing" + exit 1 + fi + set -x + ln -s $sltarget usr/$lib/$slbase + done + fi + done +done + +# Workaround for the lack of a kernel sysroot package. Copy the +# kernel headers into the sysroot. +rpm -ql kernel-headers | grep "^/usr/include" | while read f ; do + if test -f "$f" ; then + install -D "$f" "./$f" + fi +done + +# Remove the executable bit from files in the sysroot. This prevents +# debuginfo extraction. +find -type f | xargs chmod a-x + +# Use sysroot-relative paths in linker script. Ignore symbolic links. +sed -e 's,\([^0-9a-zA-Z=*]/lib\),=/usr/lib,g' \ + -e 's,\([^0-9a-zA-Z=*]\)/,\1=/,g' \ + -i $(find -type f -name 'lib[cm].so') + +popd +%dnl %%{without bootstrap} +%endif + +############################################################################## +# Beyond this point in the install process we no longer modify the set of +# installed files. +############################################################################## + +############################################################################## +# Build the file lists used for describing the package and subpackages. +############################################################################## +# There are several main file lists (and many more for +# the langpack sub-packages (langpack-${lang}.filelist)): +# * master.filelist +# - Master file list from which all other lists are built. +# * glibc.filelist +# - Files for the glibc packages. +# * common.filelist +# - Flies for the common subpackage. +# * utils.filelist +# - Files for the utils subpackage. +# * nscd.filelist +# - Files for the nscd subpackage. +# * devel.filelist +# - Files for the devel subpackage. +# * doc.filelist +# - Files for the documentation subpackage. +# * headers.filelist +# - Files for the headers subpackage. +# * static.filelist +# - Files for the static subpackage. +# * libnsl.filelist +# - Files for the libnsl subpackage +# * nss_db.filelist +# * nss_hesiod.filelist +# - File lists for nss_* NSS module subpackages. +# * nss-devel.filelist +# - File list with the .so symbolic links for NSS packages. +# * compat-libpthread-nonshared.filelist. +# - File list for compat-libpthread-nonshared subpackage. + +# Create the main file lists. This way we can append to any one of them later +# wihtout having to create it. Note these are removed at the start of the +# install phase. +touch master.filelist +touch glibc.filelist +touch common.filelist +touch utils.filelist +touch gconv.filelist +touch nscd.filelist +touch devel.filelist +touch doc.filelist +touch headers.filelist +touch static.filelist +touch libnsl.filelist +touch nss_db.filelist +touch nss_hesiod.filelist +touch nss-devel.filelist +touch compat-libpthread-nonshared.filelist + +############################################################################### +# Master file list, excluding a few things. +############################################################################### +{ + # List all files or links that we have created during install. + # Files with 'etc' are configuration files, likewise 'gconv-modules' + # and 'gconv-modules.cache' are caches, and we exclude them. + find %{glibc_sysroot} \( -type f -o -type l \) \ + \( \ + -name etc -printf "%%%%config " -o \ + -name gconv-modules.cache \ + -printf "%%%%verify(not md5 size mtime) " -o \ + -name gconv-modules* \ + -printf "%%%%verify(not md5 size mtime) %%%%config(noreplace) " \ + , \ + ! -path "*/lib/debug/*" -printf "/%%P\n" \) + # List all directories with a %%dir prefix. We omit the info directory and + # all directories in (and including) /usr/share/locale. + find %{glibc_sysroot} -type d \ + \( -path '*%{_prefix}/share/locale' -prune -o \ + \( -path '*%{_prefix}/share/*' \ +%if %{with docs} + ! -path '*%{_infodir}' -o \ +%endif + -path "*%{_prefix}/include/*" \ + \) -printf "%%%%dir /%%P\n" \) +} | { + # Also remove the *.mo entries. We will add them to the + # language specific sub-packages. + # libnss_ files go into subpackages related to NSS modules. + # and .*/share/i18n/charmaps/.*), they go into the sub-package + # "locale-source". /sys-root/ files are put into the sysroot package. + sed -e '\,.*/share/locale/\([^/_]\+\).*/LC_MESSAGES/.*\.mo,d' \ + -e '\,.*/share/i18n/locales/.*,d' \ + -e '\,.*/share/i18n/charmaps/.*,d' \ + -e '\,.*/etc/\(localtime\|nsswitch.conf\|ld\.so\.conf\|ld\.so\.cache\|default\|rpc\|gai\.conf\),d' \ + -e '\,.*/%{_libdir}/lib\(pcprofile\|memusage\)\.so,d' \ + -e '\,.*/bin/\(memusage\|mtrace\|xtrace\|pcprofiledump\),d' \ + -e '\,.*/sys-root,d' +} | sort > master.filelist + +# 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. +# - Extra gconv modules. We add the required modules later. +cat master.filelist \ + | grep -v \ + -e '%{_infodir}' \ + -e '%{_libdir}/lib.*_p.a' \ + -e '%{_prefix}/include' \ + -e '%{_libdir}/lib.*\.a' \ + -e '%{_libdir}/.*\.o' \ + -e '%{_libdir}/lib.*\.so' \ + -e '%{_libdir}/gconv/.*\.so$' \ + -e '%{_libdir}/gconv/gconv-modules.d/gconv-modules-extra\.conf$' \ + -e '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' \ + > 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-gconv-extra +############################################################################### + +grep -e "gconv-modules-extra.conf" master.filelist > gconv.filelist + +# Put the essential gconv modules into the main package. +GconvBaseModules="ANSI_X3.110 ISO8859-15 ISO8859-1 CP1252" +GconvBaseModules="$GconvBaseModules UNICODE UTF-16 UTF-32 UTF-7" +%ifarch s390 s390x +GconvBaseModules="$GconvBaseModules ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9" +GconvBaseModules="$GconvBaseModules UTF16_UTF32_Z9 UTF8_UTF32_Z9" +%endif +GconvAllModules=$(cat master.filelist | + sed -n 's|%{_libdir}/gconv/\(.*\)\.so|\1|p') + +# Put the base modules into glibc and the rest into glibc-gconv-extra +for conv in $GconvAllModules; do + if echo $GconvBaseModules | grep -q $conv; then + grep -E -e "%{_libdir}/gconv/$conv.so$" \ + master.filelist >> glibc.filelist + else + grep -E -e "%{_libdir}/gconv/$conv.so$" \ + master.filelist >> gconv.filelist + fi +done + +############################################################################### +# glibc-devel +############################################################################### + +# Static libraries that land in glibc-devel, not glibc-static. +devel_static_library_pattern='/lib\(\(c\|nldbl\|mvec\)_nonshared\|g\|ieee\|mcheck\|pthread\|dl\|rt\|util\|anl\)\.a$' +# Static libraries neither in glibc-devel nor in glibc-static. +other_static_library_pattern='/libpthread_nonshared\.a' + +grep '%{_libdir}/lib.*\.a' master.filelist \ + | grep "$devel_static_library_pattern" \ + | grep -v "$other_static_library_pattern" \ + > 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 + +%if %{glibc_autorequires} +mkdir -p %{glibc_sysroot}/%{_rpmconfigdir} %{glibc_sysroot}/%{_fileattrsdir} +sed < %{SOURCE4} \ + -e s/@VERSION@/%{version}/ \ + -e s/@RELEASE@/%{release}/ \ + -e s/@SYMVER@/%{glibc_autorequires_symver}/ \ + > %{glibc_sysroot}/%{_rpmconfigdir}/glibc.req +cp %{SOURCE5} %{glibc_sysroot}/%{_fileattrsdir}/glibc.attr +%endif + +############################################################################### +# glibc-doc +############################################################################### + +%if %{with docs} +# Put the info files into the doc file list, but exclude the generated dir. +grep '%{_infodir}' master.filelist | grep -v '%{_infodir}/dir' > doc.filelist +grep '%{_docdir}' master.filelist >> doc.filelist +%endif + +############################################################################### +# glibc-headers +############################################################################### + +%if %{need_headers_package} +# The glibc-headers package includes only common files which are identical +# across all multilib packages. We must keep gnu/stubs.h and gnu/lib-names.h +# in the glibc-headers package, but the -32, -64, -64-v1, and -64-v2 versions +# go into glibc-devel. +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 +%else +# If there is no glibc-headers package, all header files go into the +# glibc-devel package. +grep '%{_prefix}/include' < master.filelist >> devel.filelist +%endif + +############################################################################### +# glibc-static +############################################################################### + +# Put the rest of the static files into the static package. +grep '%{_libdir}/lib.*\.a' < master.filelist \ + | grep -v "$devel_static_library_pattern" \ + | grep -v "$other_static_library_pattern" \ + > 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. The makedb binary is in nss_db. +grep '%{_prefix}/bin' master.filelist \ + | grep -v '%{_prefix}/bin/makedb' \ + >> common.filelist +grep '%{_prefix}/sbin' master.filelist \ + | grep -v '%{_prefix}/sbin/iconvconfig' \ + | 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 into doc, and the info directory. +# - All documentation files, which go into doc. +grep '%{_prefix}/share' master.filelist \ + | grep -v \ + -e '%{_prefix}/share/info/libc.info.*' \ + -e '%%dir %{prefix}/share/info' \ + -e '%%dir %{prefix}/share' \ + -e '%{_docdir}' \ + >> common.filelist + +############################################################################### +# 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 +grep -E "%{_prefix}/bin/makedb$" master.filelist >> nss_db.filelist + +############################################################################### +# nss-devel +############################################################################### + +# Symlinks go into the nss-devel package (instead of the main devel +# package). +grep '/libnss_[a-z]*\.so$' master.filelist > nss-devel.filelist + +############################################################################### +# libnsl +############################################################################### + +# Prepare the libnsl-related file lists. +grep -E '/libnsl\.so\.[0-9]+$' master.filelist > libnsl.filelist +test $(wc -l < libnsl.filelist) -eq 1 + +%if %{with benchtests} +############################################################################### +# glibc-benchtests +############################################################################### + +# List of benchmarks. +find build-%{target}/benchtests -type f -executable | while read b; do + echo "%{_prefix}/libexec/glibc-benchtests/$(basename $b)" +done >> benchtests.filelist +# ... and the makefile. +for b in %{SOURCE2} %{SOURCE3}; 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 + +############################################################################## +# 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_build 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 %{buildpower10} +# Run this test only if the server supports Power10 instructions. +if LD_SHOW_AUXV=1 /bin/true | grep -E "AT_HWCAP2:[^$]*arch_3_1" > /dev/null; then + echo ====================TESTING -mcpu=power10============= + pushd build-%{target}-power10 + run_tests + popd +fi +%endif + +echo ====================TESTING END===================== +PLTCMD='/^Relocation section .*\(\.rela\?\.plt\|\.rela\.IA_64\.pltoff\)/,/^$/p' +echo ====================PLT RELOCS LD.SO================ +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================== + +# Obtain a way to run the dynamic loader. Avoid matching the symbolic +# link and then pick the first loader (although there should be only +# one). Use -maxdepth 2 to avoid descending into the /sys-root/ +# sub-tree. See wrap-find-debuginfo.sh. +ldso_path="$(find %{glibc_sysroot}/ -maxdepth 2 -regextype posix-extended \ + -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f | LC_ALL=C sort | head -n1)" +run_ldso="$ldso_path --library-path %{glibc_sysroot}/%{_lib}" + +# Show the auxiliary vector as seen by the new library +# (even if we do not perform the valgrind test). +LD_SHOW_AUXV=1 $run_ldso /bin/true + +%if 0%{?_enable_debug_packages} +# 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. +%if %{with valgrind} +$run_ldso /usr/bin/valgrind --error-exitcode=1 \ + $run_ldso /usr/bin/true +# true --help performs some memory allocations. +$run_ldso /usr/bin/valgrind --error-exitcode=1 \ + $run_ldso /usr/bin/true --help >/dev/null +%endif +%endif + +%endif + + +%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 + +-- (1) Remove multilib libraries from previous installs. +-- In order to support in-place upgrades, we must immediately remove +-- all platform directories before installing a new glibc +-- version. RPM only deletes files removed by updates near the end +-- of the transaction. If we did not remove all platform +-- directories here, they may be preferred by the dynamic linker +-- during the execution of subsequent RPM scriptlets, likely +-- resulting in process startup failures. + +-- 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. +-- For the versioned install names, the version are [2.0,9.9*], so we +-- match "libc-2.0.so" and so on up to "libc-9.9*". +-- For the unversioned install names, we match the library plus ".so." +-- followed by digests. +remove_regexps = {} +for i = 1, #install_libs do + -- Versioned install name. + remove_regexps[#remove_regexps + 1] = ("lib" .. install_libs[i] + .. "%%-[2-9]%%.[0-9]+%%.so$") + -- Unversioned install name. + remove_regexps[#remove_regexps + 1] = ("lib" .. install_libs[i] + .. "%%.so%%.[0-9]+$") +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", + "%{_libdir}/power9", + } + +-- Add all the subdirectories of the glibc-hwcaps subdirectory. +repeat + local iter = posix.files("%{_libdir}/glibc-hwcaps") + if iter ~= nil then + for entry in iter do + if entry ~= "." and entry ~= ".." then + local path = "%{_libdir}/glibc-hwcaps/" .. entry + if posix.access(path .. "/.", "x") then + remove_dirs[#remove_dirs + 1] = path + end + end + end + end +until true + +-- 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 + +%post -p +%glibc_post_funcs +-- (1) Update /etc/ld.so.conf +-- Next we update /etc/ld.so.conf to ensure that it starts with +-- a literal "include ld.so.conf.d/*.conf". + +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 + +-- (2) Rebuild ld.so.cache early. +-- If the format of the cache changes then we need to rebuild +-- the cache early to avoid any problems running binaries with +-- the new glibc. + +-- Note: We use _prefix because Fedora's UsrMove says so. +post_exec ("%{_prefix}/sbin/ldconfig") + +-- (3) Update gconv modules cache. +-- If the /usr/lib/gconv/gconv-modules.cache exists, then update it +-- with the latest set of modules that were just installed. +-- We assume that the cache is in _libdir/gconv and called +-- "gconv-modules.cache". + +update_gconv_modules_cache() + +-- (4) On upgrades, restart systemd if installed. "systemctl -q" does +-- not suppress the error message (which is common in chroots), so +-- open-code post_exec with standard error suppressed. +if tonumber(arg[2]) >= 2 + and posix.access("%{_prefix}/bin/systemctl", "x") +then + local pid = posix.fork() + if pid == 0 then + posix.redirect2null(2) + assert(posix.exec("%{_prefix}/bin/systemctl", "daemon-reexec")) + elseif pid > 0 then + posix.wait(pid) + end +end + +%posttrans all-langpacks -e -p +-- The old glibc-all-langpacks postun scriptlet deleted the locale-archive +-- file, so we may have to resurrect it on upgrades. +local archive_path = "%{_prefix}/lib/locale/locale-archive" +local real_path = "%{_prefix}/lib/locale/locale-archive.real" +local stat_archive = posix.stat(archive_path) +local stat_real = posix.stat(real_path) +-- If the hard link was removed, restore it. +if stat_archive ~= nil and stat_real ~= nil + and (stat_archive.ino ~= stat_real.ino + or stat_archive.dev ~= stat_real.dev) then + posix.unlink(archive_path) + stat_archive = nil +end +-- If the file is gone, restore it. +if stat_archive == nil then + posix.link(real_path, archive_path) +end +-- Remove .rpmsave file potentially created due to config file change. +local save_path = archive_path .. ".rpmsave" +if posix.access(save_path) then + posix.unlink(save_path) +end + +%post gconv-extra -p +%glibc_post_funcs +update_gconv_modules_cache () + +%postun gconv-extra -p +%glibc_post_funcs +update_gconv_modules_cache () + +%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 %{buildpower10} +%dir /%{_libdir}/glibc-hwcaps/power10 +%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 %{_libdir}/gconv/gconv-modules.d +%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 +# If rpm doesn't support %license, then use %doc instead. +%{!?_licensedir:%global license %%doc} +%license COPYING COPYING.LIB LICENSES + +%files -f common.filelist common +%dir %{_prefix}/lib/locale +%dir %{_prefix}/lib/locale/C.utf8 +%{_prefix}/lib/locale/C.utf8/* + +%files all-langpacks +%{_prefix}/lib/locale/locale-archive +%{_prefix}/lib/locale/locale-archive.real +%{_prefix}/share/locale/*/LC_MESSAGES/libc.mo + +%files locale-source +%dir %{_prefix}/share/i18n/locales +%{_prefix}/share/i18n/locales/* +%dir %{_prefix}/share/i18n/charmaps +%{_prefix}/share/i18n/charmaps/* + +%files -f devel.filelist devel +%if %{glibc_autorequires} +%attr(0755,root,root) %{_rpmconfigdir}/glibc.req +%{_fileattrsdir}/glibc.attr +%endif + +%if %{with docs} +%files -f doc.filelist doc +%endif + +%files -f static.filelist static + +%if %{need_headers_package} +%files -f headers.filelist -n %{headers_package_name} +%endif + +%files -f utils.filelist utils + +%files -f gconv.filelist gconv-extra + +%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 + +%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 %{with benchtests} +%files benchtests -f benchtests.filelist +%endif + +%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared + +%if %{without bootstrap} +%files -n sysroot-%{_arch}-%{sysroot_dist}-glibc +%{sysroot_prefix} +%endif + +%changelog +* Wed Feb 8 2023 Florian Weimer - 2.34-60 +- Upstream test for ldconfig -p (#2167811) + +* Wed Feb 8 2023 Florian Weimer - 2.34-59 +- Fix ldconfig -p on i686 (#2167811) + +* Wed Jan 25 2023 Florian Weimer - 2.34-58 +- Enhance internal tunables ABI stability (awk iteration order) (#2162962) + +* Tue Jan 17 2023 Florian Weimer - 2.34-57 +- Sync with upstream branch release/2.34/master, + commit 6484ae5b8c4d4314f748e4d3c9a9baa5385e57c5 +- malloc: Fix -Wuse-after-free warning in tst-mallocalign1 [BZ #26779] +- s_sincosf.h: Change pio4 type to float [BZ #28713] +- math: Properly cast X_TLOSS to float [BZ #28713] +- Regenerate ulps on x86_64 with GCC 12 +- Avoid -Wuse-after-free in tests [BZ #26779]. +- Fix build of nptl/tst-thread_local1.cc with GCC 12 +- Fix stdio-common tests for GCC 12 -Waddress +- Fix stdlib/tst-setcontext.c for GCC 12 -Warray-compare +- resolv: Avoid GCC 12 false positive warning [BZ #28439]. +- intl: Avoid -Wuse-after-free [BZ #26779] +- elf: Drop elf/tls-macros.h in favor of __thread and tls_model attributes [BZ #28152] [BZ #28205] +- time: Set daylight to 1 for matching DST/offset change (RHBZ#2155352) +- elf/tst-tlsopt-powerpc fails when compiled with -mcpu=power10 (BZ# 29776) +- time: Use 64 bit time on tzfile +- nscd: Use 64 bit time_t on libc nscd routines (BZ# 29402) +- nis: Build libnsl with 64 bit time_t +- Use LFS and 64 bit time for installed programs (BZ #15333) + +* Mon Dec 12 2022 Tulio Magno Quites Machado Filho - 2.34-56 +- Earlier removal of alternative multilibs (#2149994) + +* Mon Dec 12 2022 Tulio Magno Quites Machado Filho - 2.34-55 +- Earlier removal of alternative multilibs (#2149994) + +* Mon Dec 12 2022 Florian Weimer - 2.34-54 +- Install kernel header files into the sysroot subpackage (#2149644) + +* Wed Dec 07 2022 Arjun Shankar - 2.34-53 +- Sync with upstream branch release/2.34/master, + commit a4217408a3d6050a7f42ac23adb6ac7218dca85f: +- Apply asm redirections in syslog.h before first use [BZ #27087] +- _Static_assert needs two arguments for compatibility with GCC before 9 + +* Wed Nov 30 2022 Florian Weimer - 2.34-52 +- Add noarch sysroot subpackages (#2149644) + +* Tue Nov 29 2022 Florian Weimer - 2.34-51 +- Prepare for integration of GCC 8 compatible _Static_assert (#2149102) + +* Fri Nov 25 2022 Arjun Shankar - 2.34-50 +- Sync with upstream branch release/2.34/master, + commit 405b8ae13540e9fd614df614e3361ebf9abd14cf: +- elf: Fix wrong fscanf usage on tst-pldd +- Allow for unpriviledged nested containers +- elf: Fix wrong fscanf usage on tst-pldd +- x86: Fix wcsnlen-avx2 page cross length comparison [BZ #29591] +- elf: Fix rtld-audit trampoline for aarch64 + +* Mon Nov 14 2022 Arjun Shankar - 2.34-49 +- Sync with upstream branch release/2.34/master, + commit: 75b0edb7ef338084e53925139ae81fb0dfc07dd4: +- Update NEWS file in the right place +- Linux: Support __IPC_64 in sysvctl *ctl command arguments (bug 29771) +- io: Fix use-after-free in ftw [BZ #26779] +- io: Fix ftw internal realloc buffer (BZ #28126) +- regex: fix buffer read overrun in search [BZ#28470] +- regex: copy back from Gnulib +- Allow #pragma GCC in headers in conformtest +- Fix memmove call in vfprintf-internal.c:group_number +- mktime: improve heuristic for ca-1986 Indiana DST +- Makerules: fix MAKEFLAGS assignment for upcoming make-4.4 [BZ# 29564] +- linux: Fix generic struct_stat for 64 bit time (BZ# 29657) +- elf: Do not completely clear reused namespace in dlmopen (bug 29600) +- nss: Use shared prefix in IPv4 address in tst-reload1 +- nss: Fix tst-nss-files-hosts-long on single-stack hosts (bug 24816) +- nss: Implement --no-addrconfig option for getent + +* Thu Oct 13 2022 Arjun Shankar - 2.34-48 +- Handle non-hostname CNAME aliases during name resolution (#2129005) +- Sync with upstream branch release/2.34/master, + commit e3976287b22422787f3cc6fc9adda58304b55bd9: +- nscd: Drop local address tuple variable [BZ #29607] +- x86-64: Require BMI1/BMI2 for AVX2 strrchr and wcsrchr implementations +- x86-64: Require BMI2 and LZCNT for AVX2 memrchr implementation +- x86-64: Require BMI2 for AVX2 (raw|w)memchr implementations +- x86-64: Require BMI2 for AVX2 wcs(n)cmp implementations +- x86-64: Require BMI2 for AVX2 strncmp implementation +- x86-64: Require BMI2 for AVX2 strcmp implementation +- x86-64: Require BMI2 for AVX2 str(n)casecmp implementations +- x86: include BMI1 and BMI2 in x86-64-v3 level +- nptl: Add backoff mechanism to spinlock loop +- sysdeps: Add 'get_fast_jitter' interace in fast-jitter.h +- nptl: Effectively skip CAS in spinlock loop +- Move assignment out of the CAS condition +- Add LLL_MUTEX_READ_LOCK [BZ #28537] +- Avoid extra load with CAS in __pthread_mutex_clocklock_common [BZ #28537] +- Avoid extra load with CAS in __pthread_mutex_lock_full [BZ #28537] +- resolv: Fix building tst-resolv-invalid-cname for earlier C standards +- nss_dns: Rewrite _nss_dns_gethostbyname4_r using current interfaces +- resolv: Add new tst-resolv-invalid-cname +- nss_dns: In gaih_getanswer_slice, skip strange aliases (bug 12154) + (#2129005) +- nss_dns: Rewrite getanswer_r to match getanswer_ptr (bug 12154, bug 29305) +- nss_dns: Remove remnants of IPv6 address mapping +- nss_dns: Rewrite _nss_dns_gethostbyaddr2_r and getanswer_ptr +- nss_dns: Split getanswer_ptr from getanswer_r +- resolv: Add DNS packet parsing helpers geared towards wire format +- resolv: Add internal __ns_name_length_uncompressed function +- resolv: Add the __ns_samebinaryname function +- resolv: Add internal __res_binary_hnok function +- resolv: Add tst-resolv-aliases +- resolv: Add tst-resolv-byaddr for testing reverse lookup +- gconv: Use 64-bit interfaces in gconv_parseconfdir (bug 29583) +- elf: Fix hwcaps string size overestimation +- nscd: Fix netlink cache invalidation if epoll is used [BZ #29415] +- Apply asm redirections in wchar.h before first use +- Apply asm redirections in stdio.h before first use [BZ #27087] +- elf: Call __libc_early_init for reused namespaces (bug 29528) + +* Tue Oct 11 2022 Florian Weimer - 2.34-47 +- Simplify the glibc system call profile (#2117712) + +* Tue Oct 11 2022 Florian Weimer - 2.34-46 +- DSO dependency sort must put new map first even if in cycle (#2128615) + +* Tue Oct 11 2022 Florian Weimer - 2.34-45 +- Run tst-audit-tlsdesc{,-dlopen} on all architectures (#2118666) + +* Thu Oct 06 2022 Arjun Shankar - 2.34-44 +- wrap-find-debuginfo.sh: Use nm --format=posix instead of --format=just-symbols + +* Mon Oct 03 2022 Arjun Shankar - 2.34-43 +- Remove .annobin* symbols from ld.so (#2126477) + +* Tue Sep 06 2022 Arjun Shankar - 2.34-42 +- Co-Authored-By: Benjamin Herrenschmidt +- Retain .gnu_debuglink section in libc.so.6 (#2090744) +- Remove redundant ld.so debuginfo file (#2090744) + +* Tue Aug 23 2022 Arjun Shankar - 2.34-41 +- Sync with upstream branch release/2.34/master, + commit 68507377f249d165f1f35502d96e9365edb07d9a: +- socket: Check lengths before advancing pointer in CMSG_NXTHDR +- alpha: Fix generic brk system call emulation in __brk_call (bug 29490) +- stdlib: Fixup mbstowcs NULL __dst handling. [BZ #29279] +- stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265] +- Update syscall lists for Linux 5.19 +- dlfcn: Pass caller pointer to static dlopen implementation (bug 29446) + +* Fri Jul 22 2022 Arjun Shankar - 2.34-40 +- Sync with upstream branch release/2.34/master, + commit b2f32e746492615a6eb3e66fac1e766e32e8deb1: +- malloc: Simplify implementation of __malloc_assert +- Update syscall-names.list for Linux 5.18 +- x86: Add missing IS_IN (libc) check to strncmp-sse4_2.S +- x86: Move mem{p}{mov|cpy}_{chk_}erms to its own file +- x86: Move and slightly improve memset_erms +- x86: Add definition for __wmemset_chk AVX2 RTM in ifunc impl list +- x86: Put wcs{n}len-sse4.1 in the sse4.1 text section +- x86: Align entry for memrchr to 64-bytes. +- x86: Add BMI1/BMI2 checks for ISA_V3 check +- x86: Cleanup bounds checking in large memcpy case +- x86: Add bounds `x86_non_temporal_threshold` +- x86: Add sse42 implementation to strcmp's ifunc +- x86: Fix misordered logic for setting `rep_movsb_stop_threshold` +- x86: Align varshift table to 32-bytes +- x86: ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST expect no transactions +- x86: Shrink code size of memchr-evex.S +- x86: Shrink code size of memchr-avx2.S +- x86: Optimize memrchr-avx2.S +- x86: Optimize memrchr-evex.S +- x86: Optimize memrchr-sse2.S +- x86: Add COND_VZEROUPPER that can replace vzeroupper if no `ret` +- x86: Create header for VEC classes in x86 strings library +- x86_64: Add strstr function with 512-bit EVEX +- x86-64: Ignore r_addend for R_X86_64_GLOB_DAT/R_X86_64_JUMP_SLOT +- x86_64: Implement evex512 version of strlen, strnlen, wcslen and wcsnlen +- x86_64: Remove bzero optimization +- x86_64: Remove end of line trailing spaces +- nptl: Fix ___pthread_unregister_cancel_restore asynchronous restore +- linux: Fix mq_timereceive check for 32 bit fallback code (BZ 29304) + +* Fri Jun 24 2022 Florian Weimer - 2.34-39 +- Add the no-aaaa DNS stub resolver option (#2096191) + +* Tue Jun 14 2022 Arjun Shankar - 2.34-38 +- Sync with upstream branch release/2.34/master, + commit 94ab2088c37d8e4285354af120b7ed6b887b9e53: +- nss: handle stat failure in check_reload_and_get (BZ #28752) +- nss: add assert to DB_LOOKUP_FCT (BZ #28752) +- nios2: Remove _dl_skip_args usage (BZ# 29187) +- hppa: Remove _dl_skip_args usage (BZ# 29165) +- nptl: Fix __libc_cleanup_pop_restore asynchronous restore (BZ#29214) + +* Wed Jun 8 2022 Florian Weimer - 2.34-37 +- Enable rseq by default and add GLIBC_2.35 rseq symbols (#2085529) + +* Wed Jun 8 2022 Florian Weimer - 2.34-36 +- Sync with upstream branch release/2.34/master, + commit 4c92a1041257c0155c6aa7a182fe5f78e477b0e6: +- powerpc: Fix VSX register number on __strncpy_power9 [BZ #29197] +- socket: Fix mistyped define statement in socket/sys/socket.h (BZ #29225) +- iconv: Use 64 bit stat for gconv_parseconfdir (BZ# 29213) +- catgets: Use 64 bit stat for __open_catalog (BZ# 29211) +- inet: Use 64 bit stat for ruserpass (BZ# 29210) +- socket: Use 64 bit stat for isfdtype (BZ# 29209) +- posix: Use 64 bit stat for fpathconf (_PC_ASYNC_IO) (BZ# 29208) +- posix: Use 64 bit stat for posix_fallocate fallback (BZ# 29207) +- misc: Use 64 bit stat for getusershell (BZ# 29204) +- misc: Use 64 bit stat for daemon (BZ# 29203) + +* Tue May 31 2022 Arjun Shankar - 2.34-35 +- Sync with upstream branch release/2.34/master, + commit ff450cdbdee0b8cb6b9d653d6d2fa892de29be31: +- Fix deadlock when pthread_atfork handler calls pthread_atfork or dlclose +- x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #29127] +- string.h: fix __fortified_attr_access macro call [BZ #29162] +- linux: Add a getauxval test [BZ #23293] +- rtld: Use generic argv adjustment in ld.so [BZ #23293] +- S390: Enable static PIE + +* Thu May 19 2022 Florian Weimer - 2.34-34 +- Sync with upstream branch release/2.34/master, + commit ede8d94d154157d269b18f3601440ac576c1f96a: +- csu: Implement and use _dl_early_allocate during static startup +- Linux: Introduce __brk_call for invoking the brk system call +- Linux: Implement a useful version of _startup_fatal +- ia64: Always define IA64_USE_NEW_STUB as a flag macro +- Linux: Define MMAP_CALL_INTERNAL +- i386: Honor I386_USE_SYSENTER for 6-argument Linux system calls +- i386: Remove OPTIMIZE_FOR_GCC_5 from Linux libc-do-syscall.S +- elf: Remove __libc_init_secure +- Linux: Consolidate auxiliary vector parsing (redo) +- Linux: Include in dl-sysdep.c only for SHARED +- Revert "Linux: Consolidate auxiliary vector parsing" +- Linux: Consolidate auxiliary vector parsing +- Linux: Assume that NEED_DL_SYSINFO_DSO is always defined +- Linux: Remove DL_FIND_ARG_COMPONENTS +- Linux: Remove HAVE_AUX_SECURE, HAVE_AUX_XID, HAVE_AUX_PAGESIZE +- elf: Merge dl-sysdep.c into the Linux version +- elf: Remove unused NEED_DL_BASE_ADDR and _dl_base_addr +- x86: Optimize {str|wcs}rchr-evex +- x86: Optimize {str|wcs}rchr-avx2 +- x86: Optimize {str|wcs}rchr-sse2 +- x86: Cleanup page cross code in memcmp-avx2-movbe.S +- x86: Remove memcmp-sse4.S +- x86: Small improvements for wcslen +- x86: Remove AVX str{n}casecmp +- x86: Add EVEX optimized str{n}casecmp +- x86: Add AVX2 optimized str{n}casecmp +- x86: Optimize str{n}casecmp TOLOWER logic in strcmp-sse42.S +- x86: Optimize str{n}casecmp TOLOWER logic in strcmp.S +- x86: Remove strspn-sse2.S and use the generic implementation +- x86: Remove strpbrk-sse2.S and use the generic implementation +- x86: Remove strcspn-sse2.S and use the generic implementation +- x86: Optimize strspn in strspn-c.c +- x86: Optimize strcspn and strpbrk in strcspn-c.c +- x86: Code cleanup in strchr-evex and comment justifying branch +- x86: Code cleanup in strchr-avx2 and comment justifying branch +- x86_64: Remove bcopy optimizations +- x86-64: Remove bzero weak alias in SS2 memset +- x86_64/multiarch: Sort sysdep_routines and put one entry per line +- x86: Improve L to support L(XXX_SYMBOL (YYY, ZZZ)) +- fortify: Ensure that __glibc_fortify condition is a constant [BZ #29141] + +* Thu May 12 2022 Florian Weimer - 2.34-33 +- Sync with upstream branch release/2.34/master, + commit 91c2e6c3db44297bf4cb3a2e3c40236c5b6a0b23: +- dlfcn: Implement the RTLD_DI_PHDR request type for dlinfo +- manual: Document the dlinfo function +- x86: Fix fallback for wcsncmp_avx2 in strcmp-avx2.S [BZ #28896] +- x86: Fix bug in strncmp-evex and strncmp-avx2 [BZ #28895] +- x86: Set .text section in memset-vec-unaligned-erms +- x86-64: Optimize bzero +- x86: Remove SSSE3 instruction for broadcast in memset.S (SSE2 Only) +- x86: Improve vec generation in memset-vec-unaligned-erms.S +- x86-64: Fix strcmp-evex.S +- x86-64: Fix strcmp-avx2.S +- x86: Optimize strcmp-evex.S +- x86: Optimize strcmp-avx2.S +- manual: Clarify that abbreviations of long options are allowed +- Add HWCAP2_AFP, HWCAP2_RPRES from Linux 5.17 to AArch64 bits/hwcap.h +- aarch64: Add HWCAP2_ECV from Linux 5.16 +- Add SOL_MPTCP, SOL_MCTP from Linux 5.16 to bits/socket.h +- Update kernel version to 5.17 in tst-mman-consts.py +- Update kernel version to 5.16 in tst-mman-consts.py +- Update syscall lists for Linux 5.17 +- Add ARPHRD_CAN, ARPHRD_MCTP to net/if_arp.h +- Update kernel version to 5.15 in tst-mman-consts.py +- Add PF_MCTP, AF_MCTP from Linux 5.15 to bits/socket.h + +* Thu Apr 28 2022 Carlos O'Donell - 2.34-32 +- Sync with upstream branch release/2.34/master, + commit c66c92181ddbd82306537a608e8c0282587131de: +- posix/glob.c: update from gnulib (BZ#25659) +- linux: Fix fchmodat with AT_SYMLINK_NOFOLLOW for 64 bit time_t (BZ#29097) + +* Wed Apr 27 2022 Carlos O'Donell - 2.34-31 +- Sync with upstream branch release/2.34/master, + commit 55640ed3fde48360a8e8083be4843bd2dc7cecfe: +- i386: Regenerate ulps +- linux: Fix missing internal 64 bit time_t stat usage +- x86: Optimize L(less_vec) case in memcmp-evex-movbe.S +- x86: Don't set Prefer_No_AVX512 for processors with AVX512 and AVX-VNNI +- x86-64: Use notl in EVEX strcmp [BZ #28646] +- x86: Shrink memcmp-sse4.S code size +- x86: Double size of ERMS rep_movsb_threshold in dl-cacheinfo.h +- x86: Optimize memmove-vec-unaligned-erms.S +- x86-64: Replace movzx with movzbl +- x86-64: Remove Prefer_AVX2_STRCMP +- x86-64: Improve EVEX strcmp with masked load +- x86: Replace sse2 instructions with avx in memcmp-evex-movbe.S +- x86: Optimize memset-vec-unaligned-erms.S +- x86: Optimize memcmp-evex-movbe.S for frontend behavior and size +- x86: Modify ENTRY in sysdep.h so that p2align can be specified +- x86-64: Optimize load of all bits set into ZMM register [BZ #28252] +- scripts/glibcelf.py: Mark as UNSUPPORTED on Python 3.5 and earlier +- dlfcn: Do not use rtld_active () to determine ld.so state (bug 29078) +- INSTALL: Rephrase -with-default-link documentation +- misc: Fix rare fortify crash on wchar funcs. [BZ 29030] +- Default to --with-default-link=no (bug 25812) +- scripts: Add glibcelf.py module + +* Thu Apr 21 2022 Carlos O'Donell - 2.34-30 +- Sync with upstream branch release/2.34/master, + commit 71326f1f2fd09dafb9c34404765fb88129e94237: +- nptl: Fix pthread_cancel cancelhandling atomic operations +- mips: Fix mips64n32 64 bit time_t stat support (BZ#29069) +- hurd: Fix arbitrary error code +- nptl: Handle spurious EINTR when thread cancellation is disabled (BZ#29029) +- S390: Add new s390 platform z16. +- NEWS: Update fixed bug list for LD_AUDIT backports. +- hppa: Fix bind-now audit (BZ #28857) +- elf: Replace tst-audit24bmod2.so with tst-audit24bmod2 +- Fix elf/tst-audit25a with default bind now toolchains +- elf: Fix runtime linker auditing on aarch64 (BZ #26643) +- elf: Issue la_symbind for bind-now (BZ #23734) +- elf: Fix initial-exec TLS access on audit modules (BZ #28096) +- elf: Add la_activity during application exit +- elf: Do not fail for failed dlmopen on audit modules (BZ #28061) +- elf: Issue audit la_objopen for vDSO +- elf: Add audit tests for modules with TLSDESC +- elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533) +- elf: Add _dl_audit_pltexit +- elf: Add _dl_audit_pltenter +- elf: Add _dl_audit_preinit +- elf: Add _dl_audit_symbind_alt and _dl_audit_symbind +- elf: Add _dl_audit_objclose +- elf: Add _dl_audit_objsearch +- elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid +- elf: Add _dl_audit_objopen +- elf: Move la_activity (LA_ACT_ADD) after _dl_add_to_namespace_list() (BZ #28062) +- elf: Move LAV_CURRENT to link_lavcurrent.h +- elf: Fix elf_get_dynamic_info() for bootstrap +- elf: Fix dynamic-link.h usage on rtld.c +- elf: Fix elf_get_dynamic_info definition +- elf: Avoid nested functions in the loader [BZ #27220] +- powerpc: Delete unneeded ELF_MACHINE_BEFORE_RTLD_RELOC +- hppa: Use END instead of PSEUDO_END in swapcontext.S +- hppa: Implement swapcontext in assembler (bug 28960) + +* Tue Mar 15 2022 Florian Weimer - 2.34-29 +- Sync with upstream branch release/2.34/master, + commit 224d8c1890b6c57c7e4e8ddbb792dd9552086704: +- debug: Synchronize feature guards in fortified functions [BZ #28746] +- debug: Autogenerate _FORTIFY_SOURCE tests +- Enable _FORTIFY_SOURCE=3 for gcc 12 and above +- fortify: Fix spurious warning with realpath +- __glibc_unsafe_len: Fix comment +- debug: Add tests for _FORTIFY_SOURCE=3 +- Make sure that the fortified function conditionals are constant +- Don't add access size hints to fortifiable functions +- nss: Protect against errno changes in function lookup (bug 28953) +- nss: Do not mention NSS test modules in +- io: Add fsync call in tst-stat +- hppa: Fix warnings from _dl_lookup_address +- nptl: Fix cleanups for stack grows up [BZ# 28899] +- hppa: Revise gettext trampoline design +- hppa: Fix swapcontext +- Fix elf/tst-audit2 on hppa +- localedef: Handle symbolic links when generating locale-archive +- NEWS: Add a bug fix entry for BZ #28896 +- x86: Fix TEST_NAME to make it a string in tst-strncmp-rtm.c +- x86: Test wcscmp RTM in the wcsncmp overflow case [BZ #28896] +- x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #28896] +- string: Add a testcase for wcsncmp with SIZE_MAX [BZ #28755] +- linux: fix accuracy of get_nprocs and get_nprocs_conf [BZ #28865] +- Add reference to BZ#28860 on NEWS +- linux: Fix missing __convert_scm_timestamps (BZ #28860) + +* Tue Mar 08 2022 Arjun Shankar - 2.34-28 +- Reduce installed size of some langpacks by de-duplicating LC_CTYPE (#2054789) +- Fix localedef so it can handle symbolic links when generating locale-archive. +- Drop glibc-fedora-localedef.patch and adjust locale installation + accordingly so that installed content remains unchanged. + +* Mon Feb 28 2022 Florian Weimer - 2.34-27 +- Fix regression (ldd crash) during dependency sorting in ld.so (#2058230) + +* Mon Feb 28 2022 Florian Weimer - 2.34-26 +- Fix localedef compilation of C.UTF-8 (empty LC_MONETARY keywords) (#2058224) + +* Thu Feb 3 2022 Florian Weimer - 2.34-25 +- Sync with upstream branch release/2.34/master, + commit 6eaf10cbb78d22eae7999d9de55f6b93999e0860: +- socket: Do not use AF_NETLINK in __opensock +- hurd if_index: Explicitly use AF_INET for if index discovery +- Linux: Simplify __opensock and fix race condition [BZ #28353] +- linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage [BZ #28850] + +* Tue Feb 1 2022 Florian Weimer - 2.34-24 +- Sync with upstream branch release/2.34/master, + commit 008003dc6e83439c5e04a744b7fd8197df19096e: +- tst-socket-timestamp-compat.c: Check __TIMESIZE [BZ #28837] +- Linux: Only generate 64 bit timestamps for 64 bit time_t recvmsg/recvmmsg +- linux: Fix ancillary 64-bit time timestamp conversion (BZ #28349, BZ#28350) +- support: Add support_socket_so_timestamp_time64 + +* Tue Feb 1 2022 Florian Weimer - 2.34-23 +- Align with glibc 2.35 version of C.UTF-8 + +* Tue Feb 1 2022 Florian Weimer - 2.34-22 +- Sync with upstream branch release/2.34/master, + commit aa601d024424c40ae9a69b0c4e394a70ea0570c8: +- x86: Use CHECK_FEATURE_PRESENT to check HLE [BZ #27398] +- x86: Filter out more Intel CPUs for TSX [BZ #27398] +- Fix glibc 2.34 ABI omission (missing GLIBC_2.34 in dynamic loader) +- x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755] +- x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755] + +* Mon Jan 24 2022 Florian Weimer - 2.34-21 +- Sync with upstream branch release/2.34/master, + commit 3438bbca90895d32825a52e31a77dc44d273c1c1: +- Linux: Detect user namespace support in io/tst-getcwd-smallbuff +- realpath: Avoid overwriting preexisting error +- CVE-2021-3999: getcwd: Set errno to ERANGE for size == 1 +- tst-realpath-toolong: Fix hurd build +- CVE-2021-3998: realpath: ENAMETOOLONG for result larger than PATH_MAX +- stdlib: Fix formatting of tests list in Makefile +- stdlib: Sort tests in Makefile +- support: Add helpers to create paths longer than PATH_MAX +- powerpc: Fix unrecognized instruction errors with recent binutils +- x86: use default cache size if it cannot be determined [BZ #28784] +- CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768) +- sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542) +- CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542) +- socket: Add the __sockaddr_un_set function +- Disable debuginfod in printer tests [BZ #28757] +- Update syscall lists for Linux 5.16 + +* Wed Jan 19 2022 Florian Weimer - 2.34-20 +- More reliable CPU compatibility diagnostics (#2040657) + +* Fri Jan 14 2022 Florian Weimer - 2.34-19 +- Optionally accelerate sched_getcpu using rseq (#2024347) + +* Thu Jan 13 2022 Florian Weimer - 2.34-18 +- Backport optimized ELF dependency sorting algorithm (#2032647) + +* Thu Jan 13 2022 Florian Weimer - 2.34-17 +- Sync with upstream branch release/2.34/master, + commit 2fe2af88abd13ae5636881da2e26f461ecb7dfb5 +- i386: Remove broken CAN_USE_REGISTER_ASM_EBP (bug 28771) +- Update syscall lists for Linux 5.15 +- powerpc: Fix unrecognized instruction errors with recent GCC +- timezone: test-case for BZ #28707 +- timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707) +- Fix subscript error with odd TZif file [BZ #28338] +- AArch64: Check for SVE in ifuncs [BZ #28744] +- intl/plural.y: Avoid conflicting declarations of yyerror and yylex +- Linux: Fix 32-bit vDSO for clock_gettime on powerpc32 +- linux: Add sparck brk implementation +- Update sparc libm-test-ulps +- Update hppa libm-test-ulps +- riscv: align stack before calling _dl_init [BZ #28703] +- riscv: align stack in clone [BZ #28702] +- powerpc64[le]: Allocate extra stack frame on syscall.S +- elf: Fix tst-cpu-features-cpuinfo for KVM guests on some AMD systems [BZ #28704] +- nss: Use "files dns" as the default for the hosts database (bug 28700) +- arm: Guard ucontext _rtld_global_ro access by SHARED, not PIC macro +- mips: increase stack alignment in clone to match the ABI +- mips: align stack in clone [BZ #28223] + +* Tue Dec 14 2021 Siddhesh Poyarekar - 2.34-16 +- Enable PIE by default on all architectures (#1988382) + +* Tue Dec 14 2021 Florian Weimer - 2.34-15 +- Sync with upstream branch release/2.34/master, + commit 06865865151579d1aa17d38110060a68b85c5d90: +- pthread/tst-cancel28: Fix barrier re-init race condition +- Use $(pie-default) with conformtest +- Run conform/ tests using newly built libc +- nptl: Add one more barrier to nptl/tst-create1 + +* Fri Dec 10 2021 Florian Weimer - 2.34-13 +- x86-64: Remove LD_PREFER_MAP_32BIT_EXEC support (#2029410) + +* Fri Dec 10 2021 Florian Weimer - 2.34-12 +- Add /usr/bin/ld.so --list-diagnostics (#2023422) + +* Tue Dec 7 2021 Florian Weimer - 2.34-11 +- backtrace function crashes without vDSO on ppc64le (#2027789) + +* Fri Dec 3 2021 Florian Weimer - 2.34-10 +- Sync with upstream branch release/2.34/master, + commit 387bff63dc2dccd62b09aa26dccf8cdc5f3c985c: +- powerpc64[le]: Fix CFI and LR save address for asm syscalls [BZ #28532] +- linux: Use /proc/stat fallback for __get_nprocs_conf (BZ #28624) +- nptl: Do not set signal mask on second setjmp return [BZ #28607] +- s390: Use long branches across object boundaries (jgh instead of jh) +- elf: Earlier missing dynamic segment check in _dl_map_object_from_fd +- gconv: Do not emit spurious NUL character in ISO-2022-JP-3 (bug 28524) + +* Tue Nov 16 2021 Arjun Shankar - 2.34-9 +- Create /{bin,lib,lib64,sbin} as symbolic links in test-container + +* Wed Nov 3 2021 Florian Weimer - 2.34-8 +- Sync with upstream branch release/2.34/master, + commit 6548a9bdba95b3e1fcdbd85445342467e4b0cd4f: +- Avoid warning: overriding recipe for .../tst-ro-dynamic-mod.so +- ld.so: Initialize bootstrap_map.l_ld_readonly [BZ #28340] +- ld.so: Replace DL_RO_DYN_SECTION with dl_relocate_ld [BZ #28340] +- Handle NULL input to malloc_usable_size [BZ #28506] +- elf: Avoid deadlock between pthread_create and ctors [BZ #28357] +- timex: Use 64-bit fields on 32-bit TIMESIZE=64 systems (BZ #28469) +- y2038: Use a common definition for stat for sparc32 +- elf: Replace nsid with args.nsid [BZ #27609] +- S390: Add PCI_MIO and SIE HWCAPs +- support: Also return fd when it is 0 + +* Fri Oct 1 2021 Florian Weimer - 2.34-7 +- Drop glibc-rh1992702-*.patch, applied upstream. (#1992702) +- Sync with upstream branch release/2.34/master, + commit a996d13b8a2e101bedbb1bdaa7ffcfea3b959bb2: +- Add missing braces to bsearch inline implementation [BZ #28400] +- Suppress -Wcast-qual warnings in bsearch +- linux: Revert the use of sched_getaffinity on get_nproc (BZ #28310) +- linux: Simplify get_nprocs +- misc: Add __get_nprocs_sched +- nptl: pthread_kill must send signals to a specific thread [BZ #28407] +- support: Add check for TID zero in support_wait_for_thread_exit + +* Thu Sep 23 2021 Florian Weimer - 2.34-6 +- Sync with upstream branch release/2.34/master, + commit 33adeaa3e2b9143c38884bc5aa65ded222ed274e: +- nptl: Avoid setxid deadlock with blocked signals in thread exit [BZ #28361] +- Use support_open_dev_null_range io/tst-closefrom, misc/tst-close_range, and + posix/tst-spawn5 (BZ #28260) +- support: Add support_open_dev_null_range +- nptl: Fix type of pthread_mutexattr_getrobust_np, + pthread_mutexattr_setrobust_np (bug 28036) +- nptl: pthread_kill needs to return ESRCH for old programs (bug 19193) + +* Wed Sep 15 2021 Florian Weimer - 2.34-5 +- Use system CPU count for sysconf(_SC_NPROCESSORS_*) (#1992702) + +* Wed Sep 15 2021 Florian Weimer - 2.34-4 +- Sync with upstream branch release/2.34/master, + commit 4ed990e5b97a61f29f929bdeb36c5b2abb547a64: +- Add MADV_POPULATE_READ and MADV_POPULATE_WRITE from Linux 5.14 to + bits/mman-linux.h +- Update kernel version to 5.14 in tst-mman-consts.py +- Update syscall lists for Linux 5.14 +- Use Linux 5.14 in build-many-glibcs.py +- Fix failing nss/tst-nss-files-hosts-long with local resolver +- iconvconfig: Fix behaviour with --prefix [BZ #28199] +- nptl: Fix race between pthread_kill and thread exit (swbz#12889, #1994068) +- nptl: pthread_kill, pthread_cancel should not fail after exit + (swbz#19193, #1994068) +- support: Add support_wait_for_thread_exit +- MIPS: Setup errno for {f,l,}xstat +- x86-64: Use testl to check __x86_string_control +- elf: Fix missing colon in LD_SHOW_AUXV output (swbz#28253, #1995648) +- librt: add test (swbz#28213, #1994264) +- CVE-2021-38604: fix NULL pointer dereference in mq_notify + (swbz#28213, #1994264) +- Linux: Fix fcntl, ioctl, prctl redirects for _TIME_BITS=64 (bug 28182) +- iconv_charmap: Close output file when done +- copy_and_spawn_sgid: Avoid double calls to close() +- gaiconf_init: Avoid double-free in label and precedence lists +- gconv_parseconfdir: Fix memory leak +- ldconfig: avoid leak on empty paths in config file + +* Wed Sep 15 2021 Florian Weimer - 2.34-3 +- Switch to upstream version of C.UTF-8 (#1997589) + +* Wed Aug 25 2021 Siddhesh Poyarekar - 2.34-2 +- Disable dependencies and linking for libc_malloc_debug.so (#1985048). + +* Mon Aug 2 2021 Florian Weimer - 2.34-1 +- Switch to glibc 2.34 release tarball: +- Update ChangeLog.old/ChangeLog.23. +- Prepare for glibc 2.34 release. +- po/nl.po: Update Dutch translation. +- Update install.texi, and regenerate INSTALL. +- Update translations. +- Update NEWS. +- NEWS: Fix typos, grammar, and missing words +- elf: Fix audit regression