summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-10-09 03:36:26 +0000
committerCoprDistGit <infra@openeuler.org>2024-10-09 03:36:26 +0000
commitdb43dfdfa8bc2b938582aef3d87e43594c13ee50 (patch)
tree47b95b2f6ac8d8b7e6fa373a5bd7d661bf7234df
parentb933872de72b006230559f77acc3ccfb38a1f343 (diff)
automatic import of glibcopeneuler20.03
-rw-r--r--.gitignore1
-rw-r--r--0001-Fix-leak-in-getaddrinfo-introduced-by-the-fix-for-CV.patch98
-rw-r--r--0001-Revert-elf-Remove-unused-l_text_end-field-from-struc.patch135
-rw-r--r--0001-S390-Do-not-clobber-r7-in-clone-BZ-31402.patch157
-rw-r--r--0001-elf-Do-not-run-constructors-for-proxy-objects.patch37
-rw-r--r--0001-fix-glibc-build-error-on-x86.patch56
-rw-r--r--0001-getaddrinfo-Fix-use-after-free-in-getcanonname-CVE-2.patch338
-rw-r--r--0001-s390x-Fix-segfault-in-wcsncmp-BZ-31934.patch58
-rw-r--r--0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch181
-rw-r--r--0001-x86-Fix-for-cache-computation-on-AMD-legacy-cpus.patch286
-rw-r--r--0002-Document-CVE-2023-4806-and-CVE-2023-5156-in-NEWS.patch36
-rw-r--r--0002-Revert-elf-Always-call-destructors-in-reverse-constr.patch593
-rw-r--r--0002-elf-Always-call-destructors-in-reverse-constructor-o.patch669
-rw-r--r--0002-iconv-restore-verbosity-with-unrecognized-encoding-n.patch32
-rw-r--r--0002-linux-Use-rseq-area-unconditionally-in-sched_getcpu-.patch52
-rw-r--r--0002-nptl-fix-potential-merge-of-__rseq_-relro-symbols.patch161
-rw-r--r--0002-nscd-Do-not-rebuild-getaddrinfo-bug-30709.patch185
-rw-r--r--0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch106
-rw-r--r--0003-LoongArch-Correct-__ieee754-_-_scalb-__ieee754-_-_sc.patch23
-rw-r--r--0003-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch32
-rw-r--r--0003-Revert-elf-Move-l_init_called_next-to-old-place-of-l.patch42
-rw-r--r--0003-elf-Make-dl-rseq-symbols-Linux-only.patch51
-rw-r--r--0003-elf-Remove-unused-l_text_end-field-from-struct-link_.patch142
-rw-r--r--0003-string-Fix-tester-build-with-fortify-enable-with-gcc.patch50
-rw-r--r--0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch41
-rw-r--r--0003-x86-Fix-incorrect-scope-of-setting-shared_per_thread.patch45
-rw-r--r--0004-Add-HWCAP2_MOPS-from-Linux-6.5-to-AArch64-bits-hwcap.patch27
-rw-r--r--0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch171
-rw-r--r--0004-elf-Move-l_init_called_next-to-old-place-of-l_text_e.patch41
-rw-r--r--0004-manual-jobs.texi-Add-missing-item-EPERM-for-getpgid.patch30
-rw-r--r--0004-tunables-Terminate-if-end-of-input-is-reached-CVE-20.patch173
-rw-r--r--0004-x86_64-Fix-build-with-disable-multiarch-BZ-30721.patch60
-rw-r--r--0005-AArch64-Add-support-for-MOPS-memcpy-memmove-memset.patch314
-rw-r--r--0005-NEWS-Add-the-2.38.1-bug-list.patch37
-rw-r--r--0005-i686-Fix-build-with-disable-multiarch.patch100
-rw-r--r--0005-resolv-Allow-short-error-responses-to-match-any-quer.patch223
-rw-r--r--0006-AArch64-Cleanup-ifuncs.patch540
-rw-r--r--0006-malloc-Enable-merging-of-remainders-in-memalign-bug-.patch301
-rw-r--r--0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch232
-rw-r--r--0007-AArch64-Cleanup-emag-memset.patch348
-rw-r--r--0007-malloc-Remove-bin-scanning-from-memalign-bug-30723.patch269
-rw-r--r--0007-resolv-Track-single-request-fallback-via-_res._flags.patch81
-rw-r--r--0008-AArch64-Add-memset_zva64.patch228
-rw-r--r--0008-linux-Update-the-mremap-C-implementation-BZ-31968.patch68
-rw-r--r--0008-sysdeps-tst-bz21269-fix-test-parameter.patch31
-rw-r--r--0009-AArch64-Remove-Falkor-memcpy.patch468
-rw-r--r--0009-mremap-Update-manual-entry.patch88
-rw-r--r--0009-sysdeps-tst-bz21269-handle-ENOSYS-skip-appropriately.patch42
-rw-r--r--0010-Add-mremap-tests.patch302
-rw-r--r--0010-aarch64-correct-CFI-in-rawmemchr-bug-31113.patch31
-rw-r--r--0010-sysdeps-tst-bz21269-fix-Wreturn-type.patch30
-rw-r--r--0011-Update-syscall-lists-for-Linux-6.5.patch394
-rw-r--r--0011-aarch64-fix-check-for-SVE-support-in-assembler.patch61
-rw-r--r--0011-io-Fix-record-locking-contants-for-powerpc64-with-__.patch91
-rw-r--r--0012-AArch64-Check-kernel-version-for-SVE-ifuncs.patch153
-rw-r--r--0012-libio-Fix-oversized-__io_vtables.patch51
-rw-r--r--0012-resolv-Fix-tst-resolv-short-response-for-older-GCC-b.patch35
-rw-r--r--0013-powerpc-Fix-ld.so-address-determination-for-PCREL-mo.patch56
-rw-r--r--0014-iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch216
-rw-r--r--0015-sparc-Remove-64-bit-check-on-sparc32-wordsize-BZ-275.patch38
-rw-r--r--0016-login-Check-default-sizes-of-structs-utmp-utmpx-last.patch247
-rw-r--r--0017-login-structs-utmp-utmpx-lastlog-_TIME_BITS-independ.patch399
-rw-r--r--0018-nptl-Fix-tst-cancel30-on-kernels-without-ppoll_time6.patch55
-rw-r--r--0019-i386-ulp-update-for-SSE2-disable-multi-arch-configur.patch26
-rw-r--r--0020-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch38
-rw-r--r--0021-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch59
-rw-r--r--0022-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch60
-rw-r--r--0023-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two-.patch390
-rw-r--r--0024-elf-Also-compile-dl-misc.os-with-rtld-early-cflags.patch54
-rw-r--r--0025-nscd-Use-time_t-for-return-type-of-addgetnetgrentX.patch36
-rw-r--r--0026-resolv-Fix-some-unaligned-accesses-in-resolver-BZ-30.patch57
-rw-r--r--19614-locale-Handle-loading-a-missing-locale-twice-Bug-14.patch274
-rw-r--r--CVE-2023-4527-Stack-read-overflow-with-large-TCP-res.patch221
-rw-r--r--Decrease-value-of-arch_minimum_kernel-with-LoongArch.patch40
-rw-r--r--Fix-name-space-violation-in-fortify-wrappers-bug-320.patch298
-rw-r--r--Force-DT_RPATH-for-enable-hardcoded-path-in-tests.patch50
-rw-r--r--LanguageList196
-rw-r--r--LicenseList26
-rw-r--r--LoongArch-Add-glibc.cpu.hwcap-support.patch499
-rw-r--r--LoongArch-Add-ifunc-support-for-memchr-aligned-lsx-l.patch485
-rw-r--r--LoongArch-Add-ifunc-support-for-memcmp-aligned-lsx-l.patch946
-rw-r--r--LoongArch-Add-ifunc-support-for-memrchr-lsx-lasx.patch417
-rw-r--r--LoongArch-Add-ifunc-support-for-memset-aligned-unali.patch784
-rw-r--r--LoongArch-Add-ifunc-support-for-rawmemchr-aligned-ls.patch448
-rw-r--r--LoongArch-Add-ifunc-support-for-strcmp-aligned-lsx.patch499
-rw-r--r--LoongArch-Add-ifunc-support-for-strcpy-stpcpy-aligne.patch1099
-rw-r--r--LoongArch-Add-ifunc-support-for-strncmp-aligned-lsx.patch583
-rw-r--r--LoongArch-Add-ifunc-support-for-strnlen-aligned-lsx-.patch465
-rw-r--r--LoongArch-Add-ifunc-support-for-strrchr-aligned-lsx-.patch670
-rw-r--r--LoongArch-Add-lasx-lsx-support-for-_dl_runtime_profi.patch626
-rw-r--r--LoongArch-Add-minuimum-binutils-required-version.patch102
-rw-r--r--LoongArch-Change-loongarch-to-LoongArch-in-comments.patch277
-rw-r--r--LoongArch-Change-to-put-magic-number-to-.rodata-sect.patch67
-rw-r--r--LoongArch-Delete-excessively-allocated-memory.patch109
-rw-r--r--LoongArch-Micro-optimize-LD_PCREL.patch44
-rw-r--r--LoongArch-Redefine-macro-LEAF-ENTRY.patch65
-rw-r--r--LoongArch-Remove-support-code-for-old-linker-in-star.patch56
-rw-r--r--LoongArch-Replace-deprecated-v0-with-a0-to-eliminate.patch28
-rw-r--r--LoongArch-Unify-Register-Names.patch81
-rw-r--r--LoongArch-Update-hwcap.h-to-sync-with-LoongArch-kern.patch24
-rw-r--r--LoongArch-elf-Add-new-LoongArch-reloc-types-109-into.patch30
-rw-r--r--Loongarch-Add-ifunc-support-and-add-different-versio.patch528
-rw-r--r--Loongarch-Add-ifunc-support-for-memcpy-aligned-unali.patch2570
-rw-r--r--Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch706
-rw-r--r--Make-tst-ungetc-use-libsupport.patch147
-rw-r--r--NEWS-Mention-bug-fixes-for-29039-30694-30709-30721.patch27
-rw-r--r--NEWS-Mention-bug-fixes-for-30745-30843.patch30
-rw-r--r--Revert-LoongArch-Add-glibc.cpu.hwcap-support.patch478
-rw-r--r--S390-Fix-building-with-disable-mutli-arch-BZ-31196.patch66
-rw-r--r--add-GB18030-2022-charmap-BZ-30243.patch853
-rw-r--r--add-Wl-z-noseparate-code-for-so.patch29
-rw-r--r--add-pthread_cond_clockwait-GLIBC_2_28.patch66
-rw-r--r--arm-Remove-wrong-ldr-from-_dl_start_user-BZ-31339.patch40
-rw-r--r--backport-elf-Handle-non-directory-name-in-search-path-BZ-3103.patch220
-rw-r--r--bench.mk77
-rw-r--r--elf-Add-TLS-modid-reuse-test-for-bug-29039.patch210
-rw-r--r--elf-Add-a-way-to-check-if-tunable-is-set-BZ-27069.patch201
-rw-r--r--elf-Add-new-LoongArch-reloc-types-101-to-108-into-el.patch39
-rw-r--r--elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch53
-rw-r--r--elf-Fix-wrong-break-removal-from-8ee878592c.patch26
-rw-r--r--fix-Segmentation-fault-in-nss-module.patch40
-rw-r--r--fix_nss_database_check_reload_and_get_memleak.patch38
-rw-r--r--getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch36
-rw-r--r--glibc-1070416.patch38
-rw-r--r--glibc-bench-compare153
-rw-r--r--glibc.spec2031
-rw-r--r--i386-Disable-Intel-Xeon-Phi-tests-for-GCC-15-and-abo.patch68
-rw-r--r--libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch48
-rw-r--r--linux-Sync-Linux-6.6-elf.h.patch48
-rw-r--r--locale-delete-no-hard-link-to-avoid-all_language-pac.patch26
-rw-r--r--malloc-Improve-MAP_HUGETLB-with-glibc.malloc.hugetlb.patch50
-rw-r--r--malloc-Use-__get_nprocs-on-arena_get2-BZ-30945.patch106
-rw-r--r--misc-Add-support-for-Linux-uio.h-RWF_NOAPPEND-flag.patch75
-rw-r--r--nptl-Use-support-check.h-facilities-in-tst-setuid3.patch134
-rw-r--r--nscd.conf1
-rw-r--r--nsswitch.conf56
-rw-r--r--posix-Use-support-check.h-facilities-in-tst-truncate.patch89
-rw-r--r--replace_same_file_to_hard_link.py98
-rw-r--r--sources1
-rw-r--r--sparc-Fix-broken-memset-for-sparc32-BZ-31068.patch43
-rw-r--r--sparc-Fix-sparc64-memmove-length-comparison-BZ-31266.patch32
-rw-r--r--sparc-Remove-unwind-information-from-signal-return-s.patch74
-rw-r--r--sparc64-Remove-unwind-information-from-signal-return.patch42
-rw-r--r--stdio-common-Add-test-for-vfscanf-with-matches-longe.patch176
-rw-r--r--stdlib-Improve-tst-realpath-compatibility-with-sourc.patch43
-rw-r--r--strcmp-delete-align-for-loop_aligned.patch32
-rw-r--r--support-Add-FAIL-test-failure-helper.patch201
-rw-r--r--sysdeps-sem_open-Clear-O_CREAT-when-semaphore-file-i.patch105
-rw-r--r--testsuite_whitelist129
-rw-r--r--turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch29
-rw-r--r--ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch145
-rw-r--r--ungetc-Fix-uninitialized-read-when-putting-into-unus.patch78
-rw-r--r--use-region-to-instead-of-country-for-extract-timezon.patch152
-rw-r--r--x86-64-Fix-the-dtv-field-load-for-x32-BZ-31184.patch68
-rw-r--r--x86-64-Fix-the-tcb-field-load-for-x32-BZ-31185.patch69
-rw-r--r--x86-Fix-bug-in-strchrnul-evex512-BZ-32078.patch162
-rw-r--r--x86_64-Optimize-ffsll-function-code-size.patch50
157 files changed, 30999 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..cb4776b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/glibc-2.38.tar.xz
diff --git a/0001-Fix-leak-in-getaddrinfo-introduced-by-the-fix-for-CV.patch b/0001-Fix-leak-in-getaddrinfo-introduced-by-the-fix-for-CV.patch
new file mode 100644
index 0000000..933e109
--- /dev/null
+++ b/0001-Fix-leak-in-getaddrinfo-introduced-by-the-fix-for-CV.patch
@@ -0,0 +1,98 @@
+From 5ee59ca371b99984232d7584fe2b1a758b4421d3 Mon Sep 17 00:00:00 2001
+From: Romain Geissler <romain.geissler@amadeus.com>
+Date: Mon, 25 Sep 2023 01:21:51 +0100
+Subject: [PATCH 1/4] Fix leak in getaddrinfo introduced by the fix for
+ CVE-2023-4806 [BZ #30843]
+
+This patch fixes a very recently added leak in getaddrinfo.
+
+This was assigned CVE-2023-5156.
+
+Resolves: BZ #30884
+Related: BZ #30842
+
+Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+(cherry picked from commit ec6b95c3303c700eb89eebeda2d7264cc184a796)
+---
+ nss/Makefile | 20 ++++++++++++++++++++
+ nss/tst-nss-gai-hv2-canonname.c | 3 +++
+ sysdeps/posix/getaddrinfo.c | 4 +---
+ 3 files changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/nss/Makefile b/nss/Makefile
+index 8a5126ecf3..668ba34b18 100644
+--- a/nss/Makefile
++++ b/nss/Makefile
+@@ -149,6 +149,15 @@ endif
+ extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os \
+ nss_test_gai_hv2_canonname.os
+
++ifeq ($(run-built-tests),yes)
++ifneq (no,$(PERL))
++tests-special += $(objpfx)mtrace-tst-nss-gai-hv2-canonname.out
++endif
++endif
++
++generated += mtrace-tst-nss-gai-hv2-canonname.out \
++ tst-nss-gai-hv2-canonname.mtrace
++
+ include ../Rules
+
+ ifeq (yes,$(have-selinux))
+@@ -217,6 +226,17 @@ endif
+ $(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so
+ $(objpfx)tst-nss-files-alias-truncated.out: $(objpfx)/libnss_files.so
+
++tst-nss-gai-hv2-canonname-ENV = \
++ MALLOC_TRACE=$(objpfx)tst-nss-gai-hv2-canonname.mtrace \
++ LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
++$(objpfx)mtrace-tst-nss-gai-hv2-canonname.out: \
++ $(objpfx)tst-nss-gai-hv2-canonname.out
++ { test -r $(objpfx)tst-nss-gai-hv2-canonname.mtrace \
++ || ( echo "tst-nss-gai-hv2-canonname.mtrace does not exist"; exit 77; ) \
++ && $(common-objpfx)malloc/mtrace \
++ $(objpfx)tst-nss-gai-hv2-canonname.mtrace; } > $@; \
++ $(evaluate-test)
++
+ # Disable DT_RUNPATH on NSS tests so that the glibc internal NSS
+ # functions can load testing NSS modules via DT_RPATH.
+ LDFLAGS-tst-nss-test1 = -Wl,--disable-new-dtags
+diff --git a/nss/tst-nss-gai-hv2-canonname.c b/nss/tst-nss-gai-hv2-canonname.c
+index d5f10c07d6..7db53cf09d 100644
+--- a/nss/tst-nss-gai-hv2-canonname.c
++++ b/nss/tst-nss-gai-hv2-canonname.c
+@@ -21,6 +21,7 @@
+ #include <netdb.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <mcheck.h>
+ #include <support/check.h>
+ #include <support/xstdio.h>
+ #include "nss/tst-nss-gai-hv2-canonname.h"
+@@ -41,6 +42,8 @@ static void do_prepare (int a, char **av)
+ static int
+ do_test (void)
+ {
++ mtrace ();
++
+ __nss_configure_lookup ("hosts", "test_gai_hv2_canonname");
+
+ struct addrinfo hints = {};
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index b2236b105c..13082305d3 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -1196,9 +1196,7 @@ free_and_return:
+ if (malloc_name)
+ free ((char *) name);
+ free (addrmem);
+- if (res.free_at)
+- free (res.at);
+- free (res.canon);
++ gaih_result_reset (&res);
+
+ return result;
+ }
+--
+2.33.0
+
diff --git a/0001-Revert-elf-Remove-unused-l_text_end-field-from-struc.patch b/0001-Revert-elf-Remove-unused-l_text_end-field-from-struc.patch
new file mode 100644
index 0000000..90d6c1f
--- /dev/null
+++ b/0001-Revert-elf-Remove-unused-l_text_end-field-from-struc.patch
@@ -0,0 +1,135 @@
+From e0b6c9706c91a642c781918eea52588ee8dc9f09 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 18 Oct 2023 14:22:59 +0200
+Subject: [PATCH 1/3] Revert "elf: Remove unused l_text_end field from struct
+ link_map"
+
+This reverts commit 750f19526ae71aac801c77a3f7ef5374890c09b7.
+
+Reason for revert: Restore ABI after revert of commit a3189f66a5f.
+---
+ elf/dl-load.c | 2 +-
+ elf/dl-load.h | 7 +++++--
+ elf/rtld.c | 6 ++++++
+ elf/setup-vdso.h | 4 ++++
+ include/link.h | 2 ++
+ 5 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 2923b1141d..9a87fda9c9 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1253,7 +1253,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
+
+ /* Now process the load commands and map segments into memory.
+ This is responsible for filling in:
+- l_map_start, l_map_end, l_addr, l_contiguous, l_phdr
++ l_map_start, l_map_end, l_addr, l_contiguous, l_text_end, l_phdr
+ */
+ errstring = _dl_map_segments (l, fd, header, type, loadcmds, nloadcmds,
+ maplength, has_holes, loader);
+diff --git a/elf/dl-load.h b/elf/dl-load.h
+index 1d5207694b..ecf6910c68 100644
+--- a/elf/dl-load.h
++++ b/elf/dl-load.h
+@@ -83,11 +83,14 @@ struct loadcmd
+
+ /* This is a subroutine of _dl_map_segments. It should be called for each
+ load command, some time after L->l_addr has been set correctly. It is
+- responsible for setting the l_phdr fields */
++ responsible for setting up the l_text_end and l_phdr fields. */
+ static __always_inline void
+ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
+ const struct loadcmd *c)
+ {
++ if (c->prot & PROT_EXEC)
++ l->l_text_end = l->l_addr + c->mapend;
++
+ if (l->l_phdr == 0
+ && c->mapoff <= header->e_phoff
+ && ((size_t) (c->mapend - c->mapstart + c->mapoff)
+@@ -100,7 +103,7 @@ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
+
+ /* This is a subroutine of _dl_map_object_from_fd. It is responsible
+ for filling in several fields in *L: l_map_start, l_map_end, l_addr,
+- l_contiguous, l_phdr. On successful return, all the
++ l_contiguous, l_text_end, l_phdr. On successful return, all the
+ segments are mapped (or copied, or whatever) from the file into their
+ final places in the address space, with the correct page permissions,
+ and any bss-like regions already zeroed. It returns a null pointer
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 5107d16fe3..a91e2a4471 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -477,6 +477,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
+ GL(dl_rtld_map).l_real = &GL(dl_rtld_map);
+ GL(dl_rtld_map).l_map_start = (ElfW(Addr)) &__ehdr_start;
+ GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
++ GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext;
+ /* Copy the TLS related data if necessary. */
+ #ifndef DONT_USE_BOOTSTRAP_MAP
+ # if NO_TLS_OFFSET != 0
+@@ -1118,6 +1119,7 @@ rtld_setup_main_map (struct link_map *main_map)
+ bool has_interp = false;
+
+ main_map->l_map_end = 0;
++ main_map->l_text_end = 0;
+ /* Perhaps the executable has no PT_LOAD header entries at all. */
+ main_map->l_map_start = ~0;
+ /* And it was opened directly. */
+@@ -1209,6 +1211,8 @@ rtld_setup_main_map (struct link_map *main_map)
+ allocend = main_map->l_addr + ph->p_vaddr + ph->p_memsz;
+ if (main_map->l_map_end < allocend)
+ main_map->l_map_end = allocend;
++ if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end)
++ main_map->l_text_end = allocend;
+
+ /* The next expected address is the page following this load
+ segment. */
+@@ -1268,6 +1272,8 @@ rtld_setup_main_map (struct link_map *main_map)
+ = (char *) main_map->l_tls_initimage + main_map->l_addr;
+ if (! main_map->l_map_end)
+ main_map->l_map_end = ~0;
++ if (! main_map->l_text_end)
++ main_map->l_text_end = ~0;
+ if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name)
+ {
+ /* We were invoked directly, so the program might not have a
+diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
+index d92b12a7aa..0079842d1f 100644
+--- a/elf/setup-vdso.h
++++ b/elf/setup-vdso.h
+@@ -51,6 +51,9 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
+ l->l_addr = ph->p_vaddr;
+ if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
+ l->l_map_end = ph->p_vaddr + ph->p_memsz;
++ if ((ph->p_flags & PF_X)
++ && ph->p_vaddr + ph->p_memsz >= l->l_text_end)
++ l->l_text_end = ph->p_vaddr + ph->p_memsz;
+ }
+ else
+ /* There must be no TLS segment. */
+@@ -59,6 +62,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
+ l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
+ l->l_addr = l->l_map_start - l->l_addr;
+ 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, false);
+ _dl_setup_hash (l);
+diff --git a/include/link.h b/include/link.h
+index 686813f281..a02d5f2eba 100644
+--- a/include/link.h
++++ b/include/link.h
+@@ -253,6 +253,8 @@ struct link_map
+ /* Start and finish of memory map for this object. l_map_start
+ need not be the same as l_addr. */
+ ElfW(Addr) l_map_start, l_map_end;
++ /* End of the executable part of the mapping. */
++ ElfW(Addr) l_text_end;
+
+ /* Linked list of objects in reverse ELF constructor execution
+ order. Head of list is stored in _dl_init_called_list. */
+--
+2.33.0
+
diff --git a/0001-S390-Do-not-clobber-r7-in-clone-BZ-31402.patch b/0001-S390-Do-not-clobber-r7-in-clone-BZ-31402.patch
new file mode 100644
index 0000000..02bfee3
--- /dev/null
+++ b/0001-S390-Do-not-clobber-r7-in-clone-BZ-31402.patch
@@ -0,0 +1,157 @@
+From ee4806e978467d705b26ccb7dfddb9e0a710f8e4 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Thu, 22 Feb 2024 15:03:27 +0100
+Subject: [PATCH 01/26] S390: Do not clobber r7 in clone [BZ #31402]
+
+Starting with commit e57d8fc97b90127de4ed3e3a9cdf663667580935
+"S390: Always use svc 0"
+clone clobbers the call-saved register r7 in error case:
+function or stack is NULL.
+
+This patch restores the saved registers also in the error case.
+Furthermore the existing test misc/tst-clone is extended to check
+all error cases and that clone does not clobber registers in this
+error case.
+
+(cherry picked from commit 02782fd12849b6673cb5c2728cb750e8ec295aa3)
+Note: Added ia64 __clone2 call to tst-clone.c.
+---
+ sysdeps/unix/sysv/linux/s390/s390-32/clone.S | 1 +
+ sysdeps/unix/sysv/linux/s390/s390-64/clone.S | 1 +
+ sysdeps/unix/sysv/linux/tst-clone.c | 76 ++++++++++++++++----
+ 3 files changed, 65 insertions(+), 13 deletions(-)
+
+diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/clone.S b/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
+index 5d8d873383..fd1e509cf4 100644
+--- a/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
++++ b/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
+@@ -53,6 +53,7 @@ ENTRY(__clone)
+ br %r14
+ error:
+ lhi %r2,-EINVAL
++ lm %r6,%r7,24(%r15) /* Load registers. */
+ j SYSCALL_ERROR_LABEL
+ PSEUDO_END (__clone)
+
+diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/clone.S b/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
+index f1c4288a3d..7b37b18010 100644
+--- a/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
++++ b/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
+@@ -54,6 +54,7 @@ ENTRY(__clone)
+ br %r14
+ error:
+ lghi %r2,-EINVAL
++ lmg %r6,%r7,48(%r15) /* Restore registers. */
+ jg SYSCALL_ERROR_LABEL
+ PSEUDO_END (__clone)
+
+diff --git a/sysdeps/unix/sysv/linux/tst-clone.c b/sysdeps/unix/sysv/linux/tst-clone.c
+index 56348707d4..95bd0f6ccb 100644
+--- a/sysdeps/unix/sysv/linux/tst-clone.c
++++ b/sysdeps/unix/sysv/linux/tst-clone.c
+@@ -16,12 +16,16 @@
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+-/* BZ #2386 */
++/* BZ #2386, BZ #31402 */
+ #include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sched.h>
++#include <stackinfo.h> /* For _STACK_GROWS_{UP,DOWN}. */
++#include <support/check.h>
++
++volatile unsigned v = 0xdeadbeef;
+
+ #ifdef __ia64__
+ extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base,
+@@ -35,26 +39,72 @@ int child_fn(void *arg)
+ }
+
+ static int
+-do_test (void)
++__attribute__((noinline))
++do_clone (int (*fn)(void *), void *stack)
+ {
+ int result;
++ unsigned int a = v;
++ unsigned int b = v;
++ unsigned int c = v;
++ unsigned int d = v;
++ unsigned int e = v;
++ unsigned int f = v;
++ unsigned int g = v;
++ unsigned int h = v;
++ unsigned int i = v;
++ unsigned int j = v;
++ unsigned int k = v;
++ unsigned int l = v;
++ unsigned int m = v;
++ unsigned int n = v;
++ unsigned int o = v;
+
+ #ifdef __ia64__
+- result = __clone2 (child_fn, NULL, 0, 0, NULL, NULL, NULL);
++ result = __clone2 (fn, stack, stack != NULL ? 128 * 1024 : 0, 0, NULL, NULL,
++ NULL);
++#else
++ result = clone (fn, stack, 0, NULL);
++#endif
++
++ /* Check that clone does not clobber call-saved registers. */
++ TEST_VERIFY (a == v && b == v && c == v && d == v && e == v && f == v
++ && g == v && h == v && i == v && j == v && k == v && l == v
++ && m == v && n == v && o == v);
++
++ return result;
++}
++
++static void
++__attribute__((noinline))
++do_test_single (int (*fn)(void *), void *stack)
++{
++ printf ("%s (fn=%p, stack=%p)\n", __FUNCTION__, fn, stack);
++ errno = 0;
++
++ int result = do_clone (fn, stack);
++
++ TEST_COMPARE (errno, EINVAL);
++ TEST_COMPARE (result, -1);
++}
++
++static int
++do_test (void)
++{
++ char st[128 * 1024] __attribute__ ((aligned));
++ void *stack = NULL;
++#if defined __ia64__ || _STACK_GROWS_UP
++ stack = st;
++#elif _STACK_GROWS_DOWN
++ stack = st + sizeof (st);
+ #else
+- result = clone (child_fn, NULL, 0, NULL);
++# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
+ #endif
+
+- if (errno != EINVAL || result != -1)
+- {
+- printf ("FAIL: clone()=%d (wanted -1) errno=%d (wanted %d)\n",
+- result, errno, EINVAL);
+- return 1;
+- }
++ do_test_single (child_fn, NULL);
++ do_test_single (NULL, stack);
++ do_test_single (NULL, NULL);
+
+- puts ("All OK");
+ return 0;
+ }
+
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+--
+2.33.0
+
diff --git a/0001-elf-Do-not-run-constructors-for-proxy-objects.patch b/0001-elf-Do-not-run-constructors-for-proxy-objects.patch
new file mode 100644
index 0000000..f7d1463
--- /dev/null
+++ b/0001-elf-Do-not-run-constructors-for-proxy-objects.patch
@@ -0,0 +1,37 @@
+From 7ae211a01b085d0bde54bd13b887ce8f9d57c2b4 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 22 Aug 2023 13:56:25 +0200
+Subject: [PATCH 1/5] elf: Do not run constructors for proxy objects
+
+Otherwise, the ld.so constructor runs for each audit namespace
+and each dlmopen namespace.
+
+(cherry picked from commit f6c8204fd7fabf0cf4162eaf10ccf23258e4d10e)
+---
+ elf/dl-init.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/elf/dl-init.c b/elf/dl-init.c
+index 5b0732590f..ba4d2fdc85 100644
+--- a/elf/dl-init.c
++++ b/elf/dl-init.c
+@@ -25,10 +25,14 @@
+ static void
+ call_init (struct link_map *l, int argc, char **argv, char **env)
+ {
++ /* Do not run constructors for proxy objects. */
++ if (l != l->l_real)
++ return;
++
+ /* If the object has not been relocated, this is a bug. The
+ function pointers are invalid in this case. (Executables do not
+- need relocation, and neither do proxy objects.) */
+- assert (l->l_real->l_relocated || l->l_real->l_type == lt_executable);
++ need relocation.) */
++ assert (l->l_relocated || l->l_type == lt_executable);
+
+ if (l->l_init_called)
+ /* This object is all done. */
+--
+2.33.0
+
diff --git a/0001-fix-glibc-build-error-on-x86.patch b/0001-fix-glibc-build-error-on-x86.patch
new file mode 100644
index 0000000..c27dd9d
--- /dev/null
+++ b/0001-fix-glibc-build-error-on-x86.patch
@@ -0,0 +1,56 @@
+From a2150b0d854b6ce3100d7823e3e48b2710161bfc Mon Sep 17 00:00:00 2001
+From: chenhaixiang <chenhaixiang3@huawei.com>
+Date: Wed, 16 Aug 2023 15:47:44 +0800
+Subject: [PATCH] skipping test case building fix glibc build error on x86
+
+Due to the upgrade of binutils to version 2.40,
+support for the -z pack-relative-relocs
+compilation option was added during glibc building.
+This caused the linking failure of the test cases
+tst-protected1a, tst-protected1b, and vismain.
+These files are only compiled when have-protected-data
+ is set to 'yes'.
+To ensure the successful building of glibc, these files are temporarily skipped.
+
+---
+ elf/Makefile | 19 -------------------
+ 1 file changed, 19 deletions(-)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index c00e2ccf..8cd01845 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -986,30 +986,11 @@ tst-gnu2-tls1mod.so-no-z-defs = yes
+ CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
+ endif # $(have-mtls-dialect-gnu2)
+
+-ifeq (yes,$(have-protected-data))
+-modules-names += tst-protected1moda tst-protected1modb
+-tests += tst-protected1a tst-protected1b
+-$(objpfx)tst-protected1a: $(addprefix $(objpfx),tst-protected1moda.so tst-protected1modb.so)
+-$(objpfx)tst-protected1b: $(addprefix $(objpfx),tst-protected1modb.so tst-protected1moda.so)
+-tst-protected1modb.so-no-z-defs = yes
+-# These tests fail with GCC versions prior to 5.1 and with some versions
+-# of binutils. See https://sourceware.org/bugzilla/show_bug.cgi?id=17709
+-# and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248 for details.
+-# Perhaps in future we can make these XFAILs conditional on some detection
+-# of compiler/linker behavior/version.
+-test-xfail-tst-protected1a = yes
+-test-xfail-tst-protected1b = yes
+-endif
+ ifeq (yesyes,$(have-fpie)$(build-shared))
+ modules-names += tst-piemod1
+ tests += tst-pie1 tst-pie2 tst-dlopen-pie tst-dlopen-tlsmodid-pie \
+ tst-dlopen-self-pie
+ tests-pie += tst-pie1 tst-pie2 tst-dlopen-tlsmodid-pie tst-dlopen-self-pie
+-ifeq (yes,$(have-protected-data))
+-tests += vismain
+-tests-pie += vismain
+-CFLAGS-vismain.c += $(PIE-ccflag)
+-endif
+ endif
+ modules-execstack-yes = tst-execstack-mod
+ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
+--
+2.41.0
+
diff --git a/0001-getaddrinfo-Fix-use-after-free-in-getcanonname-CVE-2.patch b/0001-getaddrinfo-Fix-use-after-free-in-getcanonname-CVE-2.patch
new file mode 100644
index 0000000..307b1eb
--- /dev/null
+++ b/0001-getaddrinfo-Fix-use-after-free-in-getcanonname-CVE-2.patch
@@ -0,0 +1,338 @@
+From 00ae4f10b504bc4564e9f22f00907093f1ab9338 Mon Sep 17 00:00:00 2001
+From: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date: Fri, 15 Sep 2023 13:51:12 -0400
+Subject: [PATCH 1/4] getaddrinfo: Fix use after free in getcanonname
+ (CVE-2023-4806)
+
+When an NSS plugin only implements the _gethostbyname2_r and
+_getcanonname_r callbacks, getaddrinfo could use memory that was freed
+during tmpbuf resizing, through h_name in a previous query response.
+
+The backing store for res->at->name when doing a query with
+gethostbyname3_r or gethostbyname2_r is tmpbuf, which is reallocated in
+gethosts during the query. For AF_INET6 lookup with AI_ALL |
+AI_V4MAPPED, gethosts gets called twice, once for a v6 lookup and second
+for a v4 lookup. In this case, if the first call reallocates tmpbuf
+enough number of times, resulting in a malloc, th->h_name (that
+res->at->name refers to) ends up on a heap allocated storage in tmpbuf.
+Now if the second call to gethosts also causes the plugin callback to
+return NSS_STATUS_TRYAGAIN, tmpbuf will get freed, resulting in a UAF
+reference in res->at->name. This then gets dereferenced in the
+getcanonname_r plugin call, resulting in the use after free.
+
+Fix this by copying h_name over and freeing it at the end. This
+resolves BZ #30843, which is assigned CVE-2023-4806.
+
+Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+(cherry picked from commit 973fe93a5675c42798b2161c6f29c01b0e243994)
+---
+ nss/Makefile | 15 ++++-
+ nss/nss_test_gai_hv2_canonname.c | 56 +++++++++++++++++
+ nss/tst-nss-gai-hv2-canonname.c | 63 +++++++++++++++++++
+ nss/tst-nss-gai-hv2-canonname.h | 1 +
+ .../postclean.req | 0
+ .../tst-nss-gai-hv2-canonname.script | 2 +
+ sysdeps/posix/getaddrinfo.c | 25 +++++---
+ 7 files changed, 152 insertions(+), 10 deletions(-)
+ create mode 100644 nss/nss_test_gai_hv2_canonname.c
+ create mode 100644 nss/tst-nss-gai-hv2-canonname.c
+ create mode 100644 nss/tst-nss-gai-hv2-canonname.h
+ create mode 100644 nss/tst-nss-gai-hv2-canonname.root/postclean.req
+ create mode 100644 nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script
+
+diff --git a/nss/Makefile b/nss/Makefile
+index 06fcdc450f..8a5126ecf3 100644
+--- a/nss/Makefile
++++ b/nss/Makefile
+@@ -82,6 +82,7 @@ tests-container := \
+ tst-nss-test3 \
+ tst-reload1 \
+ tst-reload2 \
++ tst-nss-gai-hv2-canonname \
+ # tests-container
+
+ # Tests which need libdl
+@@ -145,7 +146,8 @@ 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 nss_test_errno.os
++extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os \
++ nss_test_gai_hv2_canonname.os
+
+ include ../Rules
+
+@@ -180,12 +182,16 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
+ libof-nss_test1 = extramodules
+ libof-nss_test2 = extramodules
+ libof-nss_test_errno = extramodules
++libof-nss_test_gai_hv2_canonname = extramodules
+ $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps)
+ $(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)/libnss_test_gai_hv2_canonname.so: \
++ $(objpfx)nss_test_gai_hv2_canonname.os $(link-libc-deps)
++ $(build-module)
+ $(objpfx)nss_test2.os : nss_test1.c
+ # Use the nss_files suffix for these objects as well.
+ $(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so
+@@ -195,10 +201,14 @@ $(objpfx)/libnss_test2.so$(libnss_files.so-version): $(objpfx)/libnss_test2.so
+ $(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \
+ $(objpfx)/libnss_test_errno.so
+ $(make-link)
++$(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): \
++ $(objpfx)/libnss_test_gai_hv2_canonname.so
++ $(make-link)
+ $(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \
+ $(objpfx)/libnss_test1.so$(libnss_files.so-version) \
+ $(objpfx)/libnss_test2.so$(libnss_files.so-version) \
+- $(objpfx)/libnss_test_errno.so$(libnss_files.so-version)
++ $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) \
++ $(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version)
+
+ ifeq (yes,$(have-thread-library))
+ $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library)
+@@ -215,3 +225,4 @@ LDFLAGS-tst-nss-test3 = -Wl,--disable-new-dtags
+ LDFLAGS-tst-nss-test4 = -Wl,--disable-new-dtags
+ LDFLAGS-tst-nss-test5 = -Wl,--disable-new-dtags
+ LDFLAGS-tst-nss-test_errno = -Wl,--disable-new-dtags
++LDFLAGS-tst-nss-test_gai_hv2_canonname = -Wl,--disable-new-dtags
+diff --git a/nss/nss_test_gai_hv2_canonname.c b/nss/nss_test_gai_hv2_canonname.c
+new file mode 100644
+index 0000000000..4439c83c9f
+--- /dev/null
++++ b/nss/nss_test_gai_hv2_canonname.c
+@@ -0,0 +1,56 @@
++/* NSS service provider that only provides gethostbyname2_r.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <nss.h>
++#include <stdlib.h>
++#include <string.h>
++#include "nss/tst-nss-gai-hv2-canonname.h"
++
++/* Catch misnamed and functions. */
++#pragma GCC diagnostic error "-Wmissing-prototypes"
++NSS_DECLARE_MODULE_FUNCTIONS (test_gai_hv2_canonname)
++
++extern enum nss_status _nss_files_gethostbyname2_r (const char *, int,
++ struct hostent *, char *,
++ size_t, int *, int *);
++
++enum nss_status
++_nss_test_gai_hv2_canonname_gethostbyname2_r (const char *name, int af,
++ struct hostent *result,
++ char *buffer, size_t buflen,
++ int *errnop, int *herrnop)
++{
++ return _nss_files_gethostbyname2_r (name, af, result, buffer, buflen, errnop,
++ herrnop);
++}
++
++enum nss_status
++_nss_test_gai_hv2_canonname_getcanonname_r (const char *name, char *buffer,
++ size_t buflen, char **result,
++ int *errnop, int *h_errnop)
++{
++ /* We expect QUERYNAME, which is a small enough string that it shouldn't fail
++ the test. */
++ if (memcmp (QUERYNAME, name, sizeof (QUERYNAME))
++ || buflen < sizeof (QUERYNAME))
++ abort ();
++
++ strncpy (buffer, name, buflen);
++ *result = buffer;
++ return NSS_STATUS_SUCCESS;
++}
+diff --git a/nss/tst-nss-gai-hv2-canonname.c b/nss/tst-nss-gai-hv2-canonname.c
+new file mode 100644
+index 0000000000..d5f10c07d6
+--- /dev/null
++++ b/nss/tst-nss-gai-hv2-canonname.c
+@@ -0,0 +1,63 @@
++/* Test NSS query path for plugins that only implement gethostbyname2
++ (#30843).
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <nss.h>
++#include <netdb.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/xstdio.h>
++#include "nss/tst-nss-gai-hv2-canonname.h"
++
++#define PREPARE do_prepare
++
++static void do_prepare (int a, char **av)
++{
++ FILE *hosts = xfopen ("/etc/hosts", "w");
++ for (unsigned i = 2; i < 255; i++)
++ {
++ fprintf (hosts, "ff01::ff02:ff03:%u:2\ttest.example.com\n", i);
++ fprintf (hosts, "192.168.0.%u\ttest.example.com\n", i);
++ }
++ xfclose (hosts);
++}
++
++static int
++do_test (void)
++{
++ __nss_configure_lookup ("hosts", "test_gai_hv2_canonname");
++
++ struct addrinfo hints = {};
++ struct addrinfo *result = NULL;
++
++ hints.ai_family = AF_INET6;
++ hints.ai_flags = AI_ALL | AI_V4MAPPED | AI_CANONNAME;
++
++ int ret = getaddrinfo (QUERYNAME, NULL, &hints, &result);
++
++ if (ret != 0)
++ FAIL_EXIT1 ("getaddrinfo failed: %s\n", gai_strerror (ret));
++
++ TEST_COMPARE_STRING (result->ai_canonname, QUERYNAME);
++
++ freeaddrinfo(result);
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/nss/tst-nss-gai-hv2-canonname.h b/nss/tst-nss-gai-hv2-canonname.h
+new file mode 100644
+index 0000000000..14f2a9cb08
+--- /dev/null
++++ b/nss/tst-nss-gai-hv2-canonname.h
+@@ -0,0 +1 @@
++#define QUERYNAME "test.example.com"
+diff --git a/nss/tst-nss-gai-hv2-canonname.root/postclean.req b/nss/tst-nss-gai-hv2-canonname.root/postclean.req
+new file mode 100644
+index 0000000000..e69de29bb2
+diff --git a/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script
+new file mode 100644
+index 0000000000..31848b4a28
+--- /dev/null
++++ b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script
+@@ -0,0 +1,2 @@
++cp $B/nss/libnss_test_gai_hv2_canonname.so $L/libnss_test_gai_hv2_canonname.so.2
++su
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index 0356b622be..b2236b105c 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -120,6 +120,7 @@ struct gaih_result
+ {
+ struct gaih_addrtuple *at;
+ char *canon;
++ char *h_name;
+ bool free_at;
+ bool got_ipv6;
+ };
+@@ -165,6 +166,7 @@ gaih_result_reset (struct gaih_result *res)
+ if (res->free_at)
+ free (res->at);
+ free (res->canon);
++ free (res->h_name);
+ memset (res, 0, sizeof (*res));
+ }
+
+@@ -203,9 +205,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
+ return 0;
+ }
+
+-/* Convert struct hostent to a list of struct gaih_addrtuple objects. h_name
+- is not copied, and the struct hostent object must not be deallocated
+- prematurely. The new addresses are appended to the tuple array in RES. */
++/* Convert struct hostent to a list of struct gaih_addrtuple objects. The new
++ addresses are appended to the tuple array in RES. */
+ static bool
+ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
+ struct hostent *h, struct gaih_result *res)
+@@ -238,6 +239,15 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
+ res->at = array;
+ res->free_at = true;
+
++ /* Duplicate h_name because it may get reclaimed when the underlying storage
++ is freed. */
++ if (res->h_name == NULL)
++ {
++ res->h_name = __strdup (h->h_name);
++ if (res->h_name == NULL)
++ return false;
++ }
++
+ /* Update the next pointers on reallocation. */
+ for (size_t i = 0; i < old; i++)
+ array[i].next = array + i + 1;
+@@ -262,7 +272,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
+ }
+ array[i].next = array + i + 1;
+ }
+- array[0].name = h->h_name;
+ array[count - 1].next = NULL;
+
+ return true;
+@@ -324,15 +333,15 @@ gethosts (nss_gethostbyname3_r fct, int family, const char *name,
+ memory allocation failure. The returned string is allocated on the
+ heap; the caller has to free it. */
+ static char *
+-getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
++getcanonname (nss_action_list nip, const char *hname, const char *name)
+ {
+ nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
+ char *s = (char *) name;
+ if (cfct != NULL)
+ {
+ char buf[256];
+- if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
+- &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
++ if (DL_CALL_FCT (cfct, (hname ?: name, buf, sizeof (buf), &s, &errno,
++ &h_errno)) != NSS_STATUS_SUCCESS)
+ /* If the canonical name cannot be determined, use the passed
+ string. */
+ s = (char *) name;
+@@ -771,7 +780,7 @@ get_nss_addresses (const char *name, const struct addrinfo *req,
+ if ((req->ai_flags & AI_CANONNAME) != 0
+ && res->canon == NULL)
+ {
+- char *canonbuf = getcanonname (nip, res->at, name);
++ char *canonbuf = getcanonname (nip, res->h_name, name);
+ if (canonbuf == NULL)
+ {
+ __resolv_context_put (res_ctx);
+--
+2.33.0
+
diff --git a/0001-s390x-Fix-segfault-in-wcsncmp-BZ-31934.patch b/0001-s390x-Fix-segfault-in-wcsncmp-BZ-31934.patch
new file mode 100644
index 0000000..fddb6c8
--- /dev/null
+++ b/0001-s390x-Fix-segfault-in-wcsncmp-BZ-31934.patch
@@ -0,0 +1,58 @@
+From 712453634c8efd71a9b3ff0122145a9e90e9955c Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Thu, 11 Jul 2024 11:28:53 +0200
+Subject: [PATCH 01/12] s390x: Fix segfault in wcsncmp [BZ #31934]
+
+The z13/vector-optimized wcsncmp implementation segfaults if n=1
+and there is only one character (equal on both strings) before
+the page end. Then it loads and compares one character and misses
+to check n again. The following load fails.
+
+This patch removes the extra load and compare of the first character
+and just start with the loop which uses vector-load-to-block-boundary.
+This code-path also checks n.
+
+With this patch both tests are passing:
+- the simplified one mentioned in the bugzilla 31934
+- the full one in Florian Weimer's patch:
+"manual: Document a GNU extension for strncmp/wcsncmp"
+(https://patchwork.sourceware.org/project/glibc/patch/874j9eml6y.fsf@oldenburg.str.redhat.com/):
+On s390x-linux-gnu (z16), the new wcsncmp test fails due to bug 31934.
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+(cherry picked from commit 9b7651410375ec8848a1944992d663d514db4ba7)
+---
+ sysdeps/s390/wcsncmp-vx.S | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+diff --git a/sysdeps/s390/wcsncmp-vx.S b/sysdeps/s390/wcsncmp-vx.S
+index 1bf769b870..4028d1e624 100644
+--- a/sysdeps/s390/wcsncmp-vx.S
++++ b/sysdeps/s390/wcsncmp-vx.S
+@@ -59,14 +59,7 @@ ENTRY(WCSNCMP_Z13)
+ sllg %r4,%r4,2 /* Convert character-count to byte-count. */
+ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */
+
+- /* Check first character without vector load. */
+- lghi %r5,4 /* current_len = 4 bytes. */
+- /* Check s1/2[0]. */
+- lt %r0,0(%r2)
+- l %r1,0(%r3)
+- je .Lend_cmp_one_char
+- crjne %r0,%r1,.Lend_cmp_one_char
+-
++ lghi %r5,0 /* current_len = 0 bytes. */
+ .Lloop:
+ vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */
+ vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */
+@@ -167,7 +160,6 @@ ENTRY(WCSNCMP_Z13)
+ srl %r4,2 /* And convert it to character-index. */
+ vlgvf %r0,%v16,0(%r4) /* Load character-values. */
+ vlgvf %r1,%v17,0(%r4)
+-.Lend_cmp_one_char:
+ cr %r0,%r1
+ je .Lend_equal
+ lghi %r2,1
+--
+2.33.0
+
diff --git a/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch b/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
new file mode 100644
index 0000000..395b520
--- /dev/null
+++ b/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
@@ -0,0 +1,181 @@
+From 23514c72b780f3da097ecf33a793b7ba9c2070d2 Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun@redhat.com>
+Date: Mon, 15 Jan 2024 17:44:43 +0100
+Subject: [PATCH 1/3] syslog: Fix heap buffer overflow in __vsyslog_internal
+ (CVE-2023-6246)
+
+__vsyslog_internal did not handle a case where printing a SYSLOG_HEADER
+containing a long program name failed to update the required buffer
+size, leading to the allocation and overflow of a too-small buffer on
+the heap. This commit fixes that. It also adds a new regression test
+that uses glibc.malloc.check.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+Tested-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 6bd0e4efcc78f3c0115e5ea9739a1642807450da)
+---
+ misc/Makefile | 8 ++-
+ misc/syslog.c | 50 +++++++++++++------
+ misc/tst-syslog-long-progname.c | 39 +++++++++++++++
+ .../postclean.req | 0
+ 4 files changed, 82 insertions(+), 15 deletions(-)
+ create mode 100644 misc/tst-syslog-long-progname.c
+ create mode 100644 misc/tst-syslog-long-progname.root/postclean.req
+
+diff --git a/misc/Makefile b/misc/Makefile
+index fe0d49c1de..90b31952c5 100644
+--- a/misc/Makefile
++++ b/misc/Makefile
+@@ -289,7 +289,10 @@ tests-special += $(objpfx)tst-error1-mem.out \
+ $(objpfx)tst-allocate_once-mem.out
+ endif
+
+-tests-container := tst-syslog
++tests-container := \
++ tst-syslog \
++ tst-syslog-long-progname \
++ # tests-container
+
+ CFLAGS-select.c += -fexceptions -fasynchronous-unwind-tables
+ CFLAGS-tsearch.c += $(uses-callbacks)
+@@ -351,6 +354,9 @@ $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
+ $(evaluate-test)
+
++tst-syslog-long-progname-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
++ LD_PRELOAD=libc_malloc_debug.so.0
++
+ $(objpfx)tst-select: $(librt)
+ $(objpfx)tst-select-time64: $(librt)
+ $(objpfx)tst-pselect: $(librt)
+diff --git a/misc/syslog.c b/misc/syslog.c
+index 1b8cb722c5..814d224a1e 100644
+--- a/misc/syslog.c
++++ b/misc/syslog.c
+@@ -124,8 +124,9 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ {
+ /* Try to use a static buffer as an optimization. */
+ char bufs[1024];
+- char *buf = NULL;
+- size_t bufsize = 0;
++ char *buf = bufs;
++ size_t bufsize;
++
+ int msgoff;
+ int saved_errno = errno;
+
+@@ -177,29 +178,50 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ #define SYSLOG_HEADER_WITHOUT_TS(__pri, __msgoff) \
+ "<%d>: %n", __pri, __msgoff
+
+- int l;
++ int l, vl;
+ if (has_ts)
+ l = __snprintf (bufs, sizeof bufs,
+ SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+ else
+ l = __snprintf (bufs, sizeof bufs,
+ SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++
++ char *pos;
++ size_t len;
++
+ if (0 <= l && l < sizeof bufs)
+ {
+- va_list apc;
+- va_copy (apc, ap);
++ /* At this point, there is still a chance that we can print the
++ remaining part of the log into bufs and use that. */
++ pos = bufs + l;
++ len = sizeof (bufs) - l;
++ }
++ else
++ {
++ buf = NULL;
++ /* We already know that bufs is too small to use for this log message.
++ The next vsnprintf into bufs is used only to calculate the total
++ required buffer length. We will discard bufs contents and allocate
++ an appropriately sized buffer later instead. */
++ pos = bufs;
++ len = sizeof (bufs);
++ }
+
+- /* Restore errno for %m format. */
+- __set_errno (saved_errno);
++ {
++ va_list apc;
++ va_copy (apc, ap);
+
+- int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
+- mode_flags);
+- if (0 <= vl && vl < sizeof bufs - l)
+- buf = bufs;
+- bufsize = l + vl;
++ /* Restore errno for %m format. */
++ __set_errno (saved_errno);
+
+- va_end (apc);
+- }
++ vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
++
++ if (!(0 <= vl && vl < len))
++ buf = NULL;
++
++ bufsize = l + vl;
++ va_end (apc);
++ }
+
+ if (buf == NULL)
+ {
+diff --git a/misc/tst-syslog-long-progname.c b/misc/tst-syslog-long-progname.c
+new file mode 100644
+index 0000000000..88f37a8a00
+--- /dev/null
++++ b/misc/tst-syslog-long-progname.c
+@@ -0,0 +1,39 @@
++/* Test heap buffer overflow in syslog with long __progname (CVE-2023-6246)
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <syslog.h>
++#include <string.h>
++
++extern char * __progname;
++
++static int
++do_test (void)
++{
++ char long_progname[2048];
++
++ memset (long_progname, 'X', sizeof (long_progname) - 1);
++ long_progname[sizeof (long_progname) - 1] = '\0';
++
++ __progname = long_progname;
++
++ syslog (LOG_INFO, "Hello, World!");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/misc/tst-syslog-long-progname.root/postclean.req b/misc/tst-syslog-long-progname.root/postclean.req
+new file mode 100644
+index 0000000000..e69de29bb2
+--
+2.33.0
+
diff --git a/0001-x86-Fix-for-cache-computation-on-AMD-legacy-cpus.patch b/0001-x86-Fix-for-cache-computation-on-AMD-legacy-cpus.patch
new file mode 100644
index 0000000..cb4f03e
--- /dev/null
+++ b/0001-x86-Fix-for-cache-computation-on-AMD-legacy-cpus.patch
@@ -0,0 +1,286 @@
+From ced101ed9d3b7cfd12d97ef24940cb00b8658c81 Mon Sep 17 00:00:00 2001
+From: Sajan Karumanchi <sajan.karumanchi@amd.com>
+Date: Tue, 1 Aug 2023 15:20:55 +0000
+Subject: [PATCH 01/12] x86: Fix for cache computation on AMD legacy cpus.
+
+Some legacy AMD CPUs and hypervisors have the _cpuid_ '0x8000_001D'
+set to Zero, thus resulting in zeroed-out computed cache values.
+This patch reintroduces the old way of cache computation as a
+fail-safe option to handle these exceptions.
+Fixed 'level4_cache_size' value through handle_amd().
+
+Reviewed-by: Premachandra Mallappa <premachandra.mallappa@amd.com>
+Tested-by: Florian Weimer <fweimer@redhat.com>
+---
+ sysdeps/x86/dl-cacheinfo.h | 226 ++++++++++++++++++++++++++++++++-----
+ 1 file changed, 199 insertions(+), 27 deletions(-)
+
+diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
+index cd4d0351ae..285773039f 100644
+--- a/sysdeps/x86/dl-cacheinfo.h
++++ b/sysdeps/x86/dl-cacheinfo.h
+@@ -315,40 +315,206 @@ handle_amd (int name)
+ {
+ unsigned int eax;
+ unsigned int ebx;
+- unsigned int ecx;
++ unsigned int ecx = 0;
+ unsigned int edx;
+- unsigned int count = 0x1;
++ unsigned int max_cpuid = 0;
++ unsigned int fn = 0;
+
+ /* No level 4 cache (yet). */
+ if (name > _SC_LEVEL3_CACHE_LINESIZE)
+ return 0;
+
+- if (name >= _SC_LEVEL3_CACHE_SIZE)
+- count = 0x3;
+- else if (name >= _SC_LEVEL2_CACHE_SIZE)
+- count = 0x2;
+- else if (name >= _SC_LEVEL1_DCACHE_SIZE)
+- count = 0x0;
++ __cpuid (0x80000000, max_cpuid, ebx, ecx, edx);
++
++ if (max_cpuid >= 0x8000001D)
++ /* Use __cpuid__ '0x8000_001D' to compute cache details. */
++ {
++ unsigned int count = 0x1;
++
++ if (name >= _SC_LEVEL3_CACHE_SIZE)
++ count = 0x3;
++ else if (name >= _SC_LEVEL2_CACHE_SIZE)
++ count = 0x2;
++ else if (name >= _SC_LEVEL1_DCACHE_SIZE)
++ count = 0x0;
++
++ __cpuid_count (0x8000001D, count, eax, ebx, ecx, edx);
++
++ if (ecx != 0)
++ {
++ switch (name)
++ {
++ case _SC_LEVEL1_ICACHE_ASSOC:
++ case _SC_LEVEL1_DCACHE_ASSOC:
++ case _SC_LEVEL2_CACHE_ASSOC:
++ case _SC_LEVEL3_CACHE_ASSOC:
++ return ((ebx >> 22) & 0x3ff) + 1;
++ case _SC_LEVEL1_ICACHE_LINESIZE:
++ case _SC_LEVEL1_DCACHE_LINESIZE:
++ case _SC_LEVEL2_CACHE_LINESIZE:
++ case _SC_LEVEL3_CACHE_LINESIZE:
++ return (ebx & 0xfff) + 1;
++ case _SC_LEVEL1_ICACHE_SIZE:
++ case _SC_LEVEL1_DCACHE_SIZE:
++ case _SC_LEVEL2_CACHE_SIZE:
++ case _SC_LEVEL3_CACHE_SIZE:
++ return (((ebx >> 22) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1);
++ default:
++ __builtin_unreachable ();
++ }
++ return -1;
++ }
++ }
++
++ /* Legacy cache computation for CPUs prior to Bulldozer family.
++ This is also a fail-safe mechanism for some hypervisors that
++ accidentally configure __cpuid__ '0x8000_001D' to Zero. */
+
+- __cpuid_count (0x8000001D, count, eax, ebx, ecx, edx);
++ fn = 0x80000005 + (name >= _SC_LEVEL2_CACHE_SIZE);
++
++ if (max_cpuid < fn)
++ return 0;
++
++ __cpuid (fn, eax, ebx, ecx, edx);
++
++ if (name < _SC_LEVEL1_DCACHE_SIZE)
++ {
++ name += _SC_LEVEL1_DCACHE_SIZE - _SC_LEVEL1_ICACHE_SIZE;
++ ecx = edx;
++ }
+
+ switch (name)
+ {
+- case _SC_LEVEL1_ICACHE_ASSOC:
+- case _SC_LEVEL1_DCACHE_ASSOC:
+- case _SC_LEVEL2_CACHE_ASSOC:
++ case _SC_LEVEL1_DCACHE_SIZE:
++ return (ecx >> 14) & 0x3fc00;
++
++ case _SC_LEVEL1_DCACHE_ASSOC:
++ ecx >>= 16;
++ if ((ecx & 0xff) == 0xff)
++ {
++ /* Fully associative. */
++ return (ecx << 2) & 0x3fc00;
++ }
++ return ecx & 0xff;
++
++ case _SC_LEVEL1_DCACHE_LINESIZE:
++ return ecx & 0xff;
++
++ case _SC_LEVEL2_CACHE_SIZE:
++ return (ecx & 0xf000) == 0 ? 0 : (ecx >> 6) & 0x3fffc00;
++
++ case _SC_LEVEL2_CACHE_ASSOC:
++ switch ((ecx >> 12) & 0xf)
++ {
++ case 0:
++ case 1:
++ case 2:
++ case 4:
++ return (ecx >> 12) & 0xf;
++ case 6:
++ return 8;
++ case 8:
++ return 16;
++ case 10:
++ return 32;
++ case 11:
++ return 48;
++ case 12:
++ return 64;
++ case 13:
++ return 96;
++ case 14:
++ return 128;
++ case 15:
++ return ((ecx >> 6) & 0x3fffc00) / (ecx & 0xff);
++ default:
++ return 0;
++ }
++
++ case _SC_LEVEL2_CACHE_LINESIZE:
++ return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff;
++
++ case _SC_LEVEL3_CACHE_SIZE:
++ {
++ long int total_l3_cache = 0, l3_cache_per_thread = 0;
++ unsigned int threads = 0;
++ const struct cpu_features *cpu_features;
++
++ if ((edx & 0xf000) == 0)
++ return 0;
++
++ total_l3_cache = (edx & 0x3ffc0000) << 1;
++ cpu_features = __get_cpu_features ();
++
++ /* Figure out the number of logical threads that share L3. */
++ if (max_cpuid >= 0x80000008)
++ {
++ /* Get width of APIC ID. */
++ __cpuid (0x80000008, eax, ebx, ecx, edx);
++ threads = (ecx & 0xff) + 1;
++ }
++
++ if (threads == 0)
++ {
++ /* If APIC ID width is not available, use logical
++ processor count. */
++ __cpuid (0x00000001, eax, ebx, ecx, edx);
++ if ((edx & (1 << 28)) != 0)
++ threads = (ebx >> 16) & 0xff;
++ }
++
++ /* Cap usage of highest cache level to the number of
++ supported threads. */
++ if (threads > 0)
++ l3_cache_per_thread = total_l3_cache/threads;
++
++ /* Get shared cache per ccx for Zen architectures. */
++ if (cpu_features->basic.family >= 0x17)
++ {
++ long int l3_cache_per_ccx = 0;
++ /* Get number of threads share the L3 cache in CCX. */
++ __cpuid_count (0x8000001D, 0x3, eax, ebx, ecx, edx);
++ unsigned int threads_per_ccx = ((eax >> 14) & 0xfff) + 1;
++ l3_cache_per_ccx = l3_cache_per_thread * threads_per_ccx;
++ return l3_cache_per_ccx;
++ }
++ else
++ {
++ return l3_cache_per_thread;
++ }
++ }
++
+ case _SC_LEVEL3_CACHE_ASSOC:
+- return ecx ? ((ebx >> 22) & 0x3ff) + 1 : 0;
+- case _SC_LEVEL1_ICACHE_LINESIZE:
+- case _SC_LEVEL1_DCACHE_LINESIZE:
+- case _SC_LEVEL2_CACHE_LINESIZE:
++ switch ((edx >> 12) & 0xf)
++ {
++ case 0:
++ case 1:
++ case 2:
++ case 4:
++ return (edx >> 12) & 0xf;
++ case 6:
++ return 8;
++ case 8:
++ return 16;
++ case 10:
++ return 32;
++ case 11:
++ return 48;
++ case 12:
++ return 64;
++ case 13:
++ return 96;
++ case 14:
++ return 128;
++ case 15:
++ return ((edx & 0x3ffc0000) << 1) / (edx & 0xff);
++ default:
++ return 0;
++ }
++
+ case _SC_LEVEL3_CACHE_LINESIZE:
+- return ecx ? (ebx & 0xfff) + 1 : 0;
+- case _SC_LEVEL1_ICACHE_SIZE:
+- case _SC_LEVEL1_DCACHE_SIZE:
+- case _SC_LEVEL2_CACHE_SIZE:
+- case _SC_LEVEL3_CACHE_SIZE:
+- return ecx ? (((ebx >> 22) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1): 0;
++ return (edx & 0xf000) == 0 ? 0 : edx & 0xff;
++
+ default:
+ __builtin_unreachable ();
+ }
+@@ -703,7 +869,6 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
+ data = handle_amd (_SC_LEVEL1_DCACHE_SIZE);
+ core = handle_amd (_SC_LEVEL2_CACHE_SIZE);
+ shared = handle_amd (_SC_LEVEL3_CACHE_SIZE);
+- shared_per_thread = shared;
+
+ level1_icache_size = handle_amd (_SC_LEVEL1_ICACHE_SIZE);
+ level1_icache_linesize = handle_amd (_SC_LEVEL1_ICACHE_LINESIZE);
+@@ -716,13 +881,20 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
+ level3_cache_size = shared;
+ level3_cache_assoc = handle_amd (_SC_LEVEL3_CACHE_ASSOC);
+ level3_cache_linesize = handle_amd (_SC_LEVEL3_CACHE_LINESIZE);
++ level4_cache_size = handle_amd (_SC_LEVEL4_CACHE_SIZE);
+
+ if (shared <= 0)
+- /* No shared L3 cache. All we have is the L2 cache. */
+- shared = core;
++ {
++ /* No shared L3 cache. All we have is the L2 cache. */
++ shared = core;
++ }
++ else if (cpu_features->basic.family < 0x17)
++ {
++ /* Account for exclusive L2 and L3 caches. */
++ shared += core;
++ }
+
+- if (shared_per_thread <= 0)
+- shared_per_thread = shared;
++ shared_per_thread = shared;
+ }
+
+ cpu_features->level1_icache_size = level1_icache_size;
+--
+2.33.0
+
diff --git a/0002-Document-CVE-2023-4806-and-CVE-2023-5156-in-NEWS.patch b/0002-Document-CVE-2023-4806-and-CVE-2023-5156-in-NEWS.patch
new file mode 100644
index 0000000..13d6904
--- /dev/null
+++ b/0002-Document-CVE-2023-4806-and-CVE-2023-5156-in-NEWS.patch
@@ -0,0 +1,36 @@
+From f6445dc94da185b3d1ee283f0ca0a34c4e1986cc Mon Sep 17 00:00:00 2001
+From: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date: Tue, 26 Sep 2023 07:38:07 -0400
+Subject: [PATCH 2/4] Document CVE-2023-4806 and CVE-2023-5156 in NEWS
+
+These are tracked in BZ #30884 and BZ #30843.
+
+Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+(cherry picked from commit fd134feba35fa839018965733b34d28a09a075dd)
+---
+ NEWS | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index dfee278a9c..f1b1b0a3b4 100644
+--- a/NEWS
++++ b/NEWS
+@@ -15,6 +15,15 @@ Security related changes:
+ 2048 bytes, getaddrinfo may potentially disclose stack contents via
+ the returned address data, or crash.
+
++ CVE-2023-4806: When an NSS plugin only implements the
++ _gethostbyname2_r and _getcanonname_r callbacks, getaddrinfo could use
++ memory that was freed during buffer resizing, potentially causing a
++ crash or read or write to arbitrary memory.
++
++ CVE-2023-5156: The fix for CVE-2023-4806 introduced a memory leak when
++ an application calls getaddrinfo for AF_INET6 with AI_CANONNAME,
++ AI_ALL and AI_V4MAPPED flags set.
++
+ The following bugs are resolved with this release:
+
+ [30723] posix_memalign repeatedly scans long bin lists
+--
+2.33.0
+
diff --git a/0002-Revert-elf-Always-call-destructors-in-reverse-constr.patch b/0002-Revert-elf-Always-call-destructors-in-reverse-constr.patch
new file mode 100644
index 0000000..10d9b58
--- /dev/null
+++ b/0002-Revert-elf-Always-call-destructors-in-reverse-constr.patch
@@ -0,0 +1,593 @@
+From 719866ab2ff0e6d514a04fb47e507d92e70ef7ee Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 18 Oct 2023 14:25:46 +0200
+Subject: [PATCH 2/3] Revert "elf: Always call destructors in reverse
+ constructor order (bug 30785)"
+
+This reverts commit a3189f66a5f2fe86568286fa025fa153be04c6c0.
+
+Reason for revert: Incompatibility with existing applications.
+---
+ NEWS | 1 -
+ elf/dl-close.c | 113 ++++++++++-----------------
+ elf/dl-fini.c | 152 ++++++++++++++++++++++++-------------
+ elf/dl-init.c | 16 ----
+ elf/dso-sort-tests-1.def | 19 +++--
+ elf/tst-audit23.c | 44 +++++------
+ sysdeps/generic/ldsodefs.h | 4 -
+ 7 files changed, 173 insertions(+), 176 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index bfcd46efa9..f117874e34 100644
+--- a/NEWS
++++ b/NEWS
+@@ -32,7 +32,6 @@ Security related changes:
+ The following bugs are resolved with this release:
+
+ [30723] posix_memalign repeatedly scans long bin lists
+- [30785] Always call destructors in reverse constructor order
+ [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+ -D_FILE_OFFSET_BITS=64
+ [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index ea62d0e601..b887a44888 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -138,31 +138,30 @@ _dl_close_worker (struct link_map *map, bool force)
+
+ bool any_tls = false;
+ const unsigned int nloaded = ns->_ns_nloaded;
++ struct link_map *maps[nloaded];
+
+- /* Run over the list and assign indexes to the link maps. */
++ /* Run over the list and assign indexes to the link maps and enter
++ them into the MAPS array. */
+ 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);
+
+- /* Keep marking link maps until no new link maps are found. */
+- for (struct link_map *l = ns->_ns_loaded; l != NULL; )
++ /* Keep track of the lowest index link map we have covered already. */
++ int done_index = -1;
++ while (++done_index < nloaded)
+ {
+- /* next is reset to earlier link maps for remarking. */
+- struct link_map *next = l->l_next;
+- int next_idx = l->l_idx + 1; /* next->l_idx, but covers next == NULL. */
++ struct link_map *l = maps[done_index];
+
+ if (l->l_map_done)
+- {
+- /* Already handled. */
+- l = next;
+- continue;
+- }
++ /* Already handled. */
++ continue;
+
+ /* Check whether this object is still used. */
+ if (l->l_type == lt_loaded
+@@ -172,10 +171,7 @@ _dl_close_worker (struct link_map *map, bool force)
+ acquire is sufficient and correct. */
+ && atomic_load_acquire (&l->l_tls_dtor_count) == 0
+ && !l->l_map_used)
+- {
+- l = next;
+- continue;
+- }
++ continue;
+
+ /* We need this object and we handle it now. */
+ l->l_map_used = 1;
+@@ -202,11 +198,8 @@ _dl_close_worker (struct link_map *map, bool force)
+ already processed it, then we need to go back
+ and process again from that point forward to
+ ensure we keep all of its dependencies also. */
+- if ((*lp)->l_idx < next_idx)
+- {
+- next = *lp;
+- next_idx = next->l_idx;
+- }
++ if ((*lp)->l_idx - 1 < done_index)
++ done_index = (*lp)->l_idx - 1;
+ }
+ }
+
+@@ -226,65 +219,44 @@ _dl_close_worker (struct link_map *map, bool force)
+ if (!jmap->l_map_used)
+ {
+ jmap->l_map_used = 1;
+- if (jmap->l_idx < next_idx)
+- {
+- next = jmap;
+- next_idx = next->l_idx;
+- }
++ if (jmap->l_idx - 1 < done_index)
++ done_index = jmap->l_idx - 1;
+ }
+ }
+ }
+-
+- l = next;
+ }
+
+- /* Call the destructors in reverse constructor order, and remove the
+- closed link maps from the list. */
+- for (struct link_map **init_called_head = &_dl_init_called_list;
+- *init_called_head != NULL; )
++ /* 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, nloaded, (nsid == LM_ID_BASE), true);
++
++ /* Call all termination functions at once. */
++ bool unload_any = false;
++ bool scope_mem_left = false;
++ unsigned int unload_global = 0;
++ unsigned int first_loaded = ~0;
++ for (unsigned int i = 0; i < nloaded; ++i)
+ {
+- struct link_map *imap = *init_called_head;
++ struct link_map *imap = maps[i];
+
+- /* _dl_init_called_list is global, to produce a global odering.
+- Ignore the other namespaces (and link maps that are still used). */
+- if (imap->l_ns != nsid || imap->l_map_used)
+- init_called_head = &imap->l_init_called_next;
+- else
++ /* All elements must be in the same namespace. */
++ assert (imap->l_ns == nsid);
++
++ if (!imap->l_map_used)
+ {
+ assert (imap->l_type == lt_loaded && !imap->l_nodelete_active);
+
+- /* _dl_init_called_list is updated at the same time as
+- l_init_called. */
+- assert (imap->l_init_called);
+-
+- if (imap->l_info[DT_FINI_ARRAY] != NULL
+- || imap->l_info[DT_FINI] != NULL)
++ /* Call its termination function. Do not do it for
++ half-cooked objects. Temporarily disable exception
++ handling, so that errors are fatal. */
++ if (imap->l_init_called)
+ _dl_catch_exception (NULL, _dl_call_fini, imap);
+
+ #ifdef SHARED
+ /* Auditing checkpoint: we remove an object. */
+ _dl_audit_objclose (imap);
+ #endif
+- /* Unlink this link map. */
+- *init_called_head = imap->l_init_called_next;
+- }
+- }
+-
+-
+- bool unload_any = false;
+- bool scope_mem_left = false;
+- unsigned int unload_global = 0;
+-
+- /* For skipping un-unloadable link maps in the second loop. */
+- struct link_map *first_loaded = ns->_ns_loaded;
+
+- /* Iterate over the namespace to find objects to unload. Some
+- unloadable objects may not be on _dl_init_called_list due to
+- dlopen failure. */
+- for (struct link_map *imap = first_loaded; imap != NULL; imap = imap->l_next)
+- {
+- if (!imap->l_map_used)
+- {
+ /* This object must not be used anymore. */
+ imap->l_removed = 1;
+
+@@ -295,8 +267,8 @@ _dl_close_worker (struct link_map *map, bool force)
+ ++unload_global;
+
+ /* Remember where the first dynamically loaded object is. */
+- if (first_loaded == NULL)
+- first_loaded = imap;
++ if (i < first_loaded)
++ first_loaded = i;
+ }
+ /* Else imap->l_map_used. */
+ else if (imap->l_type == lt_loaded)
+@@ -432,8 +404,8 @@ _dl_close_worker (struct link_map *map, bool force)
+ imap->l_loader = NULL;
+
+ /* Remember where the first dynamically loaded object is. */
+- if (first_loaded == NULL)
+- first_loaded = imap;
++ if (i < first_loaded)
++ first_loaded = i;
+ }
+ }
+
+@@ -504,11 +476,10 @@ _dl_close_worker (struct link_map *map, bool force)
+
+ /* Check each element of the search list to see if all references to
+ it are gone. */
+- for (struct link_map *imap = first_loaded; imap != NULL; )
++ for (unsigned int i = first_loaded; i < nloaded; ++i)
+ {
+- if (imap->l_map_used)
+- imap = imap->l_next;
+- else
++ struct link_map *imap = maps[i];
++ if (!imap->l_map_used)
+ {
+ assert (imap->l_type == lt_loaded);
+
+@@ -719,9 +690,7 @@ _dl_close_worker (struct link_map *map, bool force)
+ if (imap == GL(dl_initfirst))
+ GL(dl_initfirst) = NULL;
+
+- struct link_map *next = imap->l_next;
+ free (imap);
+- imap = next;
+ }
+ }
+
+diff --git a/elf/dl-fini.c b/elf/dl-fini.c
+index e201d36651..9acb64f47c 100644
+--- a/elf/dl-fini.c
++++ b/elf/dl-fini.c
+@@ -24,68 +24,116 @@
+ void
+ _dl_fini (void)
+ {
+- /* Call destructors strictly in the reverse order of constructors.
+- This causes fewer surprises than some arbitrary reordering based
+- on new (relocation) dependencies. None of the objects are
+- unmapped, so applications can deal with this if their DSOs remain
+- in a consistent state after destructors have run. */
+-
+- /* Protect against concurrent loads and unloads. */
+- __rtld_lock_lock_recursive (GL(dl_load_lock));
+-
+- /* Ignore objects which are opened during shutdown. */
+- struct link_map *local_init_called_list = _dl_init_called_list;
+-
+- for (struct link_map *l = local_init_called_list; l != NULL;
+- l = l->l_init_called_next)
+- /* Bump l_direct_opencount of all objects so that they
+- are not dlclose()ed from underneath us. */
+- ++l->l_direct_opencount;
+-
+- /* After this point, everything linked from local_init_called_list
+- cannot be unloaded because of the reference counter update. */
+- __rtld_lock_unlock_recursive (GL(dl_load_lock));
+-
+- /* Perform two passes: One for non-audit modules, one for audit
+- modules. This way, audit modules receive unload notifications
+- for non-audit objects, and the destructors for audit modules
+- still run. */
++ /* Lots of fun ahead. We have to call the destructors for all still
++ loaded objects, in all namespaces. The problem is that the ELF
++ specification now demands that dependencies between the modules
++ are taken into account. I.e., the destructor for a module is
++ called before the ones for any of its dependencies.
++
++ To make things more complicated, we cannot simply use the reverse
++ order of the constructors. Since the user might have loaded objects
++ using `dlopen' there are possibly several other modules with its
++ dependencies to be taken into account. Therefore we have to start
++ determining the order of the modules once again from the beginning. */
++
++ /* We run the destructors of the main namespaces last. As for the
++ other namespaces, we pick run the destructors in them in reverse
++ order of the namespace ID. */
++#ifdef SHARED
++ int do_audit = 0;
++ again:
++#endif
++ for (Lmid_t ns = GL(dl_nns) - 1; ns >= 0; --ns)
++ {
++ /* Protect against concurrent loads and unloads. */
++ __rtld_lock_lock_recursive (GL(dl_load_lock));
++
++ unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded;
++ /* No need to do anything for empty namespaces or those used for
++ auditing DSOs. */
++ if (nloaded == 0
++#ifdef SHARED
++ || GL(dl_ns)[ns]._ns_loaded->l_auditing != do_audit
++#endif
++ )
++ __rtld_lock_unlock_recursive (GL(dl_load_lock));
++ else
++ {
+ #ifdef SHARED
+- int last_pass = GLRO(dl_naudit) > 0;
+- Lmid_t last_ns = -1;
+- for (int do_audit = 0; do_audit <= last_pass; ++do_audit)
++ _dl_audit_activity_nsid (ns, LA_ACT_DELETE);
+ #endif
+- for (struct link_map *l = local_init_called_list; l != NULL;
+- l = l->l_init_called_next)
+- {
++
++ /* Now we can allocate an array to hold all the pointers and
++ copy the pointers in. */
++ struct link_map *maps[nloaded];
++
++ unsigned int i;
++ struct link_map *l;
++ assert (nloaded != 0 || GL(dl_ns)[ns]._ns_loaded == NULL);
++ for (l = GL(dl_ns)[ns]._ns_loaded, i = 0; l != NULL; l = l->l_next)
++ /* Do not handle ld.so in secondary namespaces. */
++ if (l == l->l_real)
++ {
++ assert (i < nloaded);
++
++ maps[i] = l;
++ l->l_idx = i;
++ ++i;
++
++ /* Bump l_direct_opencount of all objects so that they
++ are not dlclose()ed from underneath us. */
++ ++l->l_direct_opencount;
++ }
++ assert (ns != LM_ID_BASE || i == nloaded);
++ assert (ns == LM_ID_BASE || i == nloaded || i == nloaded - 1);
++ unsigned int nmaps = i;
++
++ /* 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, 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
++ various members of this list cannot vanish since the open
++ count is too high and will be decremented in this loop. So
++ we release the lock so that some code which might be called
++ from a destructor can directly or indirectly access the
++ lock. */
++ __rtld_lock_unlock_recursive (GL(dl_load_lock));
++
++ /* 'maps' now contains the objects in the right order. Now
++ call the destructors. We have to process this array from
++ the front. */
++ for (i = 0; i < nmaps; ++i)
++ {
++ struct link_map *l = maps[i];
++
++ if (l->l_init_called)
++ {
++ _dl_call_fini (l);
+ #ifdef SHARED
+- if (GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing != do_audit)
+- continue;
+-
+- /* Avoid back-to-back calls of _dl_audit_activity_nsid for the
+- same namespace. */
+- if (last_ns != l->l_ns)
+- {
+- if (last_ns >= 0)
+- _dl_audit_activity_nsid (last_ns, LA_ACT_CONSISTENT);
+- _dl_audit_activity_nsid (l->l_ns, LA_ACT_DELETE);
+- last_ns = l->l_ns;
+- }
++ /* Auditing checkpoint: another object closed. */
++ _dl_audit_objclose (l);
+ #endif
++ }
+
+- /* There is no need to re-enable exceptions because _dl_fini
+- is not called from a context where exceptions are caught. */
+- _dl_call_fini (l);
++ /* Correct the previous increment. */
++ --l->l_direct_opencount;
++ }
+
+ #ifdef SHARED
+- /* Auditing checkpoint: another object closed. */
+- _dl_audit_objclose (l);
++ _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
+ #endif
+- }
++ }
++ }
+
+ #ifdef SHARED
+- if (last_ns >= 0)
+- _dl_audit_activity_nsid (last_ns, LA_ACT_CONSISTENT);
++ if (! do_audit && GLRO(dl_naudit) > 0)
++ {
++ do_audit = 1;
++ goto again;
++ }
+
+ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
+ _dl_debug_printf ("\nruntime linker statistics:\n"
+diff --git a/elf/dl-init.c b/elf/dl-init.c
+index ffd05b7806..ba4d2fdc85 100644
+--- a/elf/dl-init.c
++++ b/elf/dl-init.c
+@@ -21,7 +21,6 @@
+ #include <ldsodefs.h>
+ #include <elf-initfini.h>
+
+-struct link_map *_dl_init_called_list;
+
+ static void
+ call_init (struct link_map *l, int argc, char **argv, char **env)
+@@ -43,21 +42,6 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
+ dependency. */
+ l->l_init_called = 1;
+
+- /* Help an already-running dlclose: The just-loaded object must not
+- be removed during the current pass. (No effect if no dlclose in
+- progress.) */
+- l->l_map_used = 1;
+-
+- /* Record execution before starting any initializers. This way, if
+- the initializers themselves call dlopen, their ELF destructors
+- will eventually be run before this object is destructed, matching
+- that their ELF constructors have run before this object was
+- constructed. _dl_fini uses this list for audit callbacks, so
+- register objects on the list even if they do not have a
+- constructor. */
+- l->l_init_called_next = _dl_init_called_list;
+- _dl_init_called_list = l;
+-
+ /* Check for object which constructors we do not run here. */
+ if (__builtin_expect (l->l_name[0], 'a') == '\0'
+ && l->l_type == lt_executable)
+diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
+index 61dc54f8ae..4bf9052db1 100644
+--- a/elf/dso-sort-tests-1.def
++++ b/elf/dso-sort-tests-1.def
+@@ -53,14 +53,21 @@ tst-dso-ordering10: {}->a->b->c;soname({})=c
+ output: b>a>{}<a<b
+
+ # Complex example from Bugzilla #15311, under-linked and with circular
+-# relocation(dynamic) dependencies. For both sorting algorithms, the
+-# destruction order is the reverse of the construction order, and
+-# relocation dependencies are not taken into account.
++# relocation(dynamic) dependencies. While this is technically unspecified, the
++# presumed reasonable practical behavior is for the destructor order to respect
++# the static DT_NEEDED links (here this means the 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
+-output: {+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[<g<f<e<a<b<c<d];}
++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[<a<c<d<g<f<b<e];}
++output(glibc.rtld.dynamic_sort=2): {+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[<g<f<a<b<c<d<e];}
+
+ # Test that even in the presence of dependency loops involving dlopen'ed
+ # object, that object is initialized last (and not unloaded prematurely).
+-# Final destructor order is the opposite of constructor order.
++# Final destructor order is indeterminate due to the cycle.
+ tst-bz28937: {+a;+b;-b;+c;%c};a->a1;a->a2;a2->a;b->b1;c->a1;c=>a1
+-output: {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<c<a<a1<a2
++output(glibc.rtld.dynamic_sort=1): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a<a2<c<a1
++output(glibc.rtld.dynamic_sort=2): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a2<a<c<a1
+diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
+index 503699c36a..bb7d66c385 100644
+--- a/elf/tst-audit23.c
++++ b/elf/tst-audit23.c
+@@ -98,8 +98,6 @@ do_test (int argc, char *argv[])
+ char *lname;
+ uintptr_t laddr;
+ Lmid_t lmid;
+- uintptr_t cookie;
+- uintptr_t namespace;
+ bool closed;
+ } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
+ size_t nobjs = 0;
+@@ -119,9 +117,6 @@ do_test (int argc, char *argv[])
+ size_t buffer_length = 0;
+ while (xgetline (&buffer, &buffer_length, out))
+ {
+- *strchrnul (buffer, '\n') = '\0';
+- printf ("info: subprocess output: %s\n", buffer);
+-
+ if (startswith (buffer, "la_activity: "))
+ {
+ uintptr_t cookie;
+@@ -130,26 +125,29 @@ do_test (int argc, char *argv[])
+ &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)
+ {
+- /* 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);
+-
+ acts[nacts++] = cookie;
+ last_act_cookie = cookie;
+ }
+- /* LA_ACT_DELETE is called multiple times for each
+- namespace, depending on destruction order. */
++ /* 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 = cookie;
++ {
++ 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);
+- last_act_cookie = -1;
+
+ /* LA_ACT_DELETE must always be followed by an la_objclose. */
+ if (last_act == LA_ACT_DELETE)
+@@ -181,8 +179,6 @@ do_test (int argc, char *argv[])
+ objs[nobjs].lname = lname;
+ objs[nobjs].laddr = laddr;
+ objs[nobjs].lmid = lmid;
+- objs[nobjs].cookie = cookie;
+- objs[nobjs].namespace = last_act_cookie;
+ objs[nobjs].closed = false;
+ nobjs++;
+
+@@ -205,12 +201,6 @@ do_test (int argc, char *argv[])
+ if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
+ {
+ TEST_COMPARE (objs[i].closed, false);
+- TEST_COMPARE (objs[i].cookie, cookie);
+- if (objs[i].namespace == -1)
+- /* No LA_ACT_ADD before the first la_objopen call. */
+- TEST_COMPARE (acts[0], last_act_cookie);
+- else
+- TEST_COMPARE (objs[i].namespace, last_act_cookie);
+ objs[i].closed = true;
+ break;
+ }
+@@ -219,7 +209,11 @@ do_test (int argc, char *argv[])
+ /* la_objclose should be called after la_activity(LA_ACT_DELETE) for
+ the closed object's namespace. */
+ TEST_COMPARE (last_act, LA_ACT_DELETE);
+- seen_first_objclose = true;
++ if (!seen_first_objclose)
++ {
++ TEST_COMPARE (last_act_cookie, cookie);
++ seen_first_objclose = true;
++ }
+ }
+ }
+
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index 9ea9389a39..e8b7359b04 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -1037,10 +1037,6 @@ extern int _dl_check_map_versions (struct link_map *map, int verbose,
+ extern void _dl_init (struct link_map *main_map, int argc, char **argv,
+ char **env) attribute_hidden;
+
+-/* List of ELF objects in reverse order of their constructor
+- invocation. */
+-extern struct link_map *_dl_init_called_list attribute_hidden;
+-
+ /* Call the finalizer functions of all shared objects whose
+ initializer functions have completed. */
+ extern void _dl_fini (void) attribute_hidden;
+--
+2.33.0
+
diff --git a/0002-elf-Always-call-destructors-in-reverse-constructor-o.patch b/0002-elf-Always-call-destructors-in-reverse-constructor-o.patch
new file mode 100644
index 0000000..7406a87
--- /dev/null
+++ b/0002-elf-Always-call-destructors-in-reverse-constructor-o.patch
@@ -0,0 +1,669 @@
+From a3189f66a5f2fe86568286fa025fa153be04c6c0 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Fri, 8 Sep 2023 12:32:14 +0200
+Subject: [PATCH 2/5] elf: Always call destructors in reverse constructor order
+ (bug 30785)
+
+The current implementation of dlclose (and process exit) re-sorts the
+link maps before calling ELF destructors. Destructor order is not the
+reverse of the constructor order as a result: The second sort takes
+relocation dependencies into account, and other differences can result
+from ambiguous inputs, such as cycles. (The force_first handling in
+_dl_sort_maps is not effective for dlclose.) After the changes in
+this commit, there is still a required difference due to
+dlopen/dlclose ordering by the application, but the previous
+discrepancies went beyond that.
+
+A new global (namespace-spanning) list of link maps,
+_dl_init_called_list, is updated right before ELF constructors are
+called from _dl_init.
+
+In dl_close_worker, the maps variable, an on-stack variable length
+array, is eliminated. (VLAs are problematic, and dlclose should not
+call malloc because it cannot readily deal with malloc failure.)
+Marking still-used objects uses the namespace list directly, with
+next and next_idx replacing the done_index variable.
+
+After marking, _dl_init_called_list is used to call the destructors
+of now-unused maps in reverse destructor order. These destructors
+can call dlopen. Previously, new objects do not have l_map_used set.
+This had to change: There is no copy of the link map list anymore,
+so processing would cover newly opened (and unmarked) mappings,
+unloading them. Now, _dl_init (indirectly) sets l_map_used, too.
+(dlclose is handled by the existing reentrancy guard.)
+
+After _dl_init_called_list traversal, two more loops follow. The
+processing order changes to the original link map order in the
+namespace. Previously, dependency order was used. The difference
+should not matter because relocation dependencies could already
+reorder link maps in the old code.
+
+The changes to _dl_fini remove the sorting step and replace it with
+a traversal of _dl_init_called_list. The l_direct_opencount
+decrement outside the loader lock is removed because it appears
+incorrect: the counter manipulation could race with other dynamic
+loader operations.
+
+tst-audit23 needs adjustments to the changes in LA_ACT_DELETE
+notifications. The new approach for checking la_activity should
+make it clearer that la_activty calls come in pairs around namespace
+updates.
+
+The dependency sorting test cases need updates because the destructor
+order is always the opposite order of constructor order, even with
+relocation dependencies or cycles present.
+
+There is a future cleanup opportunity to remove the now-constant
+force_first and for_fini arguments from the _dl_sort_maps function.
+
+Fixes commit 1df71d32fe5f5905ffd5d100e5e9ca8ad62 ("elf: Implement
+force_first handling in _dl_sort_maps_dfs (bug 28937)").
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit 6985865bc3ad5b23147ee73466583dd7fdf65892)
+---
+ NEWS | 7 ++
+ elf/dl-close.c | 113 +++++++++++++++++----------
+ elf/dl-fini.c | 152 +++++++++++++------------------------
+ elf/dl-init.c | 16 ++++
+ elf/dso-sort-tests-1.def | 19 ++---
+ elf/tst-audit23.c | 44 ++++++-----
+ include/link.h | 4 +
+ sysdeps/generic/ldsodefs.h | 4 +
+ 8 files changed, 186 insertions(+), 173 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 8156572cdf..f1a14f45dd 100644
+--- a/NEWS
++++ b/NEWS
+@@ -4,6 +4,13 @@ See the end for copying conditions.
+
+ Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
+ using `glibc' in the "product" field.
++
++Version 2.38.1
++
++The following bugs are resolved with this release:
++
++ [30785] Always call destructors in reverse constructor order
++
+
+ Version 2.38
+
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index b887a44888..ea62d0e601 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -138,30 +138,31 @@ _dl_close_worker (struct link_map *map, bool force)
+
+ bool any_tls = false;
+ const unsigned int nloaded = ns->_ns_nloaded;
+- struct link_map *maps[nloaded];
+
+- /* Run over the list and assign indexes to the link maps and enter
+- them into the MAPS array. */
++ /* Run over the list and assign indexes to the link maps. */
+ 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);
+
+- /* Keep track of the lowest index link map we have covered already. */
+- int done_index = -1;
+- while (++done_index < nloaded)
++ /* Keep marking link maps until no new link maps are found. */
++ for (struct link_map *l = ns->_ns_loaded; l != NULL; )
+ {
+- struct link_map *l = maps[done_index];
++ /* next is reset to earlier link maps for remarking. */
++ struct link_map *next = l->l_next;
++ int next_idx = l->l_idx + 1; /* next->l_idx, but covers next == NULL. */
+
+ if (l->l_map_done)
+- /* Already handled. */
+- continue;
++ {
++ /* Already handled. */
++ l = next;
++ continue;
++ }
+
+ /* Check whether this object is still used. */
+ if (l->l_type == lt_loaded
+@@ -171,7 +172,10 @@ _dl_close_worker (struct link_map *map, bool force)
+ acquire is sufficient and correct. */
+ && atomic_load_acquire (&l->l_tls_dtor_count) == 0
+ && !l->l_map_used)
+- continue;
++ {
++ l = next;
++ continue;
++ }
+
+ /* We need this object and we handle it now. */
+ l->l_map_used = 1;
+@@ -198,8 +202,11 @@ _dl_close_worker (struct link_map *map, bool force)
+ already processed it, then we need to go back
+ and process again from that point forward to
+ ensure we keep all of its dependencies also. */
+- if ((*lp)->l_idx - 1 < done_index)
+- done_index = (*lp)->l_idx - 1;
++ if ((*lp)->l_idx < next_idx)
++ {
++ next = *lp;
++ next_idx = next->l_idx;
++ }
+ }
+ }
+
+@@ -219,44 +226,65 @@ _dl_close_worker (struct link_map *map, bool force)
+ if (!jmap->l_map_used)
+ {
+ jmap->l_map_used = 1;
+- if (jmap->l_idx - 1 < done_index)
+- done_index = jmap->l_idx - 1;
++ if (jmap->l_idx < next_idx)
++ {
++ next = jmap;
++ next_idx = next->l_idx;
++ }
+ }
+ }
+ }
+- }
+
+- /* 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, nloaded, (nsid == LM_ID_BASE), true);
++ l = next;
++ }
+
+- /* Call all termination functions at once. */
+- bool unload_any = false;
+- bool scope_mem_left = false;
+- unsigned int unload_global = 0;
+- unsigned int first_loaded = ~0;
+- for (unsigned int i = 0; i < nloaded; ++i)
++ /* Call the destructors in reverse constructor order, and remove the
++ closed link maps from the list. */
++ for (struct link_map **init_called_head = &_dl_init_called_list;
++ *init_called_head != NULL; )
+ {
+- struct link_map *imap = maps[i];
++ struct link_map *imap = *init_called_head;
+
+- /* All elements must be in the same namespace. */
+- assert (imap->l_ns == nsid);
+-
+- if (!imap->l_map_used)
++ /* _dl_init_called_list is global, to produce a global odering.
++ Ignore the other namespaces (and link maps that are still used). */
++ if (imap->l_ns != nsid || imap->l_map_used)
++ init_called_head = &imap->l_init_called_next;
++ else
+ {
+ assert (imap->l_type == lt_loaded && !imap->l_nodelete_active);
+
+- /* Call its termination function. Do not do it for
+- half-cooked objects. Temporarily disable exception
+- handling, so that errors are fatal. */
+- if (imap->l_init_called)
++ /* _dl_init_called_list is updated at the same time as
++ l_init_called. */
++ assert (imap->l_init_called);
++
++ if (imap->l_info[DT_FINI_ARRAY] != NULL
++ || imap->l_info[DT_FINI] != NULL)
+ _dl_catch_exception (NULL, _dl_call_fini, imap);
+
+ #ifdef SHARED
+ /* Auditing checkpoint: we remove an object. */
+ _dl_audit_objclose (imap);
+ #endif
++ /* Unlink this link map. */
++ *init_called_head = imap->l_init_called_next;
++ }
++ }
++
++
++ bool unload_any = false;
++ bool scope_mem_left = false;
++ unsigned int unload_global = 0;
++
++ /* For skipping un-unloadable link maps in the second loop. */
++ struct link_map *first_loaded = ns->_ns_loaded;
+
++ /* Iterate over the namespace to find objects to unload. Some
++ unloadable objects may not be on _dl_init_called_list due to
++ dlopen failure. */
++ for (struct link_map *imap = first_loaded; imap != NULL; imap = imap->l_next)
++ {
++ if (!imap->l_map_used)
++ {
+ /* This object must not be used anymore. */
+ imap->l_removed = 1;
+
+@@ -267,8 +295,8 @@ _dl_close_worker (struct link_map *map, bool force)
+ ++unload_global;
+
+ /* Remember where the first dynamically loaded object is. */
+- if (i < first_loaded)
+- first_loaded = i;
++ if (first_loaded == NULL)
++ first_loaded = imap;
+ }
+ /* Else imap->l_map_used. */
+ else if (imap->l_type == lt_loaded)
+@@ -404,8 +432,8 @@ _dl_close_worker (struct link_map *map, bool force)
+ imap->l_loader = NULL;
+
+ /* Remember where the first dynamically loaded object is. */
+- if (i < first_loaded)
+- first_loaded = i;
++ if (first_loaded == NULL)
++ first_loaded = imap;
+ }
+ }
+
+@@ -476,10 +504,11 @@ _dl_close_worker (struct link_map *map, bool force)
+
+ /* Check each element of the search list to see if all references to
+ it are gone. */
+- for (unsigned int i = first_loaded; i < nloaded; ++i)
++ for (struct link_map *imap = first_loaded; imap != NULL; )
+ {
+- struct link_map *imap = maps[i];
+- if (!imap->l_map_used)
++ if (imap->l_map_used)
++ imap = imap->l_next;
++ else
+ {
+ assert (imap->l_type == lt_loaded);
+
+@@ -690,7 +719,9 @@ _dl_close_worker (struct link_map *map, bool force)
+ if (imap == GL(dl_initfirst))
+ GL(dl_initfirst) = NULL;
+
++ struct link_map *next = imap->l_next;
+ free (imap);
++ imap = next;
+ }
+ }
+
+diff --git a/elf/dl-fini.c b/elf/dl-fini.c
+index 9acb64f47c..e201d36651 100644
+--- a/elf/dl-fini.c
++++ b/elf/dl-fini.c
+@@ -24,116 +24,68 @@
+ void
+ _dl_fini (void)
+ {
+- /* Lots of fun ahead. We have to call the destructors for all still
+- loaded objects, in all namespaces. The problem is that the ELF
+- specification now demands that dependencies between the modules
+- are taken into account. I.e., the destructor for a module is
+- called before the ones for any of its dependencies.
+-
+- To make things more complicated, we cannot simply use the reverse
+- order of the constructors. Since the user might have loaded objects
+- using `dlopen' there are possibly several other modules with its
+- dependencies to be taken into account. Therefore we have to start
+- determining the order of the modules once again from the beginning. */
+-
+- /* We run the destructors of the main namespaces last. As for the
+- other namespaces, we pick run the destructors in them in reverse
+- order of the namespace ID. */
+-#ifdef SHARED
+- int do_audit = 0;
+- again:
+-#endif
+- for (Lmid_t ns = GL(dl_nns) - 1; ns >= 0; --ns)
+- {
+- /* Protect against concurrent loads and unloads. */
+- __rtld_lock_lock_recursive (GL(dl_load_lock));
+-
+- unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded;
+- /* No need to do anything for empty namespaces or those used for
+- auditing DSOs. */
+- if (nloaded == 0
+-#ifdef SHARED
+- || GL(dl_ns)[ns]._ns_loaded->l_auditing != do_audit
+-#endif
+- )
+- __rtld_lock_unlock_recursive (GL(dl_load_lock));
+- else
+- {
++ /* Call destructors strictly in the reverse order of constructors.
++ This causes fewer surprises than some arbitrary reordering based
++ on new (relocation) dependencies. None of the objects are
++ unmapped, so applications can deal with this if their DSOs remain
++ in a consistent state after destructors have run. */
++
++ /* Protect against concurrent loads and unloads. */
++ __rtld_lock_lock_recursive (GL(dl_load_lock));
++
++ /* Ignore objects which are opened during shutdown. */
++ struct link_map *local_init_called_list = _dl_init_called_list;
++
++ for (struct link_map *l = local_init_called_list; l != NULL;
++ l = l->l_init_called_next)
++ /* Bump l_direct_opencount of all objects so that they
++ are not dlclose()ed from underneath us. */
++ ++l->l_direct_opencount;
++
++ /* After this point, everything linked from local_init_called_list
++ cannot be unloaded because of the reference counter update. */
++ __rtld_lock_unlock_recursive (GL(dl_load_lock));
++
++ /* Perform two passes: One for non-audit modules, one for audit
++ modules. This way, audit modules receive unload notifications
++ for non-audit objects, and the destructors for audit modules
++ still run. */
+ #ifdef SHARED
+- _dl_audit_activity_nsid (ns, LA_ACT_DELETE);
++ int last_pass = GLRO(dl_naudit) > 0;
++ Lmid_t last_ns = -1;
++ for (int do_audit = 0; do_audit <= last_pass; ++do_audit)
+ #endif
+-
+- /* Now we can allocate an array to hold all the pointers and
+- copy the pointers in. */
+- struct link_map *maps[nloaded];
+-
+- unsigned int i;
+- struct link_map *l;
+- assert (nloaded != 0 || GL(dl_ns)[ns]._ns_loaded == NULL);
+- for (l = GL(dl_ns)[ns]._ns_loaded, i = 0; l != NULL; l = l->l_next)
+- /* Do not handle ld.so in secondary namespaces. */
+- if (l == l->l_real)
+- {
+- assert (i < nloaded);
+-
+- maps[i] = l;
+- l->l_idx = i;
+- ++i;
+-
+- /* Bump l_direct_opencount of all objects so that they
+- are not dlclose()ed from underneath us. */
+- ++l->l_direct_opencount;
+- }
+- assert (ns != LM_ID_BASE || i == nloaded);
+- assert (ns == LM_ID_BASE || i == nloaded || i == nloaded - 1);
+- unsigned int nmaps = i;
+-
+- /* 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, 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
+- various members of this list cannot vanish since the open
+- count is too high and will be decremented in this loop. So
+- we release the lock so that some code which might be called
+- from a destructor can directly or indirectly access the
+- lock. */
+- __rtld_lock_unlock_recursive (GL(dl_load_lock));
+-
+- /* 'maps' now contains the objects in the right order. Now
+- call the destructors. We have to process this array from
+- the front. */
+- for (i = 0; i < nmaps; ++i)
+- {
+- struct link_map *l = maps[i];
+-
+- if (l->l_init_called)
+- {
+- _dl_call_fini (l);
++ for (struct link_map *l = local_init_called_list; l != NULL;
++ l = l->l_init_called_next)
++ {
+ #ifdef SHARED
+- /* Auditing checkpoint: another object closed. */
+- _dl_audit_objclose (l);
++ if (GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing != do_audit)
++ continue;
++
++ /* Avoid back-to-back calls of _dl_audit_activity_nsid for the
++ same namespace. */
++ if (last_ns != l->l_ns)
++ {
++ if (last_ns >= 0)
++ _dl_audit_activity_nsid (last_ns, LA_ACT_CONSISTENT);
++ _dl_audit_activity_nsid (l->l_ns, LA_ACT_DELETE);
++ last_ns = l->l_ns;
++ }
+ #endif
+- }
+
+- /* Correct the previous increment. */
+- --l->l_direct_opencount;
+- }
++ /* There is no need to re-enable exceptions because _dl_fini
++ is not called from a context where exceptions are caught. */
++ _dl_call_fini (l);
+
+ #ifdef SHARED
+- _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
++ /* Auditing checkpoint: another object closed. */
++ _dl_audit_objclose (l);
+ #endif
+- }
+- }
++ }
+
+ #ifdef SHARED
+- if (! do_audit && GLRO(dl_naudit) > 0)
+- {
+- do_audit = 1;
+- goto again;
+- }
++ if (last_ns >= 0)
++ _dl_audit_activity_nsid (last_ns, LA_ACT_CONSISTENT);
+
+ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
+ _dl_debug_printf ("\nruntime linker statistics:\n"
+diff --git a/elf/dl-init.c b/elf/dl-init.c
+index ba4d2fdc85..ffd05b7806 100644
+--- a/elf/dl-init.c
++++ b/elf/dl-init.c
+@@ -21,6 +21,7 @@
+ #include <ldsodefs.h>
+ #include <elf-initfini.h>
+
++struct link_map *_dl_init_called_list;
+
+ static void
+ call_init (struct link_map *l, int argc, char **argv, char **env)
+@@ -42,6 +43,21 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
+ dependency. */
+ l->l_init_called = 1;
+
++ /* Help an already-running dlclose: The just-loaded object must not
++ be removed during the current pass. (No effect if no dlclose in
++ progress.) */
++ l->l_map_used = 1;
++
++ /* Record execution before starting any initializers. This way, if
++ the initializers themselves call dlopen, their ELF destructors
++ will eventually be run before this object is destructed, matching
++ that their ELF constructors have run before this object was
++ constructed. _dl_fini uses this list for audit callbacks, so
++ register objects on the list even if they do not have a
++ constructor. */
++ l->l_init_called_next = _dl_init_called_list;
++ _dl_init_called_list = l;
++
+ /* Check for object which constructors we do not run here. */
+ if (__builtin_expect (l->l_name[0], 'a') == '\0'
+ && l->l_type == lt_executable)
+diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
+index 4bf9052db1..61dc54f8ae 100644
+--- a/elf/dso-sort-tests-1.def
++++ b/elf/dso-sort-tests-1.def
+@@ -53,21 +53,14 @@ tst-dso-ordering10: {}->a->b->c;soname({})=c
+ output: b>a>{}<a<b
+
+ # Complex example from Bugzilla #15311, under-linked and with circular
+-# relocation(dynamic) dependencies. While this is technically unspecified, the
+-# presumed reasonable practical behavior is for the destructor order to respect
+-# the static DT_NEEDED links (here this means the 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.
++# relocation(dynamic) dependencies. For both sorting algorithms, the
++# destruction order is the reverse of the construction order, and
++# relocation dependencies are not taken into account.
+ 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
+-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[<a<c<d<g<f<b<e];}
+-output(glibc.rtld.dynamic_sort=2): {+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[<g<f<a<b<c<d<e];}
++output: {+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[<g<f<e<a<b<c<d];}
+
+ # Test that even in the presence of dependency loops involving dlopen'ed
+ # object, that object is initialized last (and not unloaded prematurely).
+-# Final destructor order is indeterminate due to the cycle.
++# Final destructor order is the opposite of constructor order.
+ tst-bz28937: {+a;+b;-b;+c;%c};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[<b<b1];+c[c>];%c(a1());}<a<a2<c<a1
+-output(glibc.rtld.dynamic_sort=2): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a2<a<c<a1
++output: {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<c<a<a1<a2
+diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
+index bb7d66c385..503699c36a 100644
+--- a/elf/tst-audit23.c
++++ b/elf/tst-audit23.c
+@@ -98,6 +98,8 @@ do_test (int argc, char *argv[])
+ char *lname;
+ uintptr_t laddr;
+ Lmid_t lmid;
++ uintptr_t cookie;
++ uintptr_t namespace;
+ bool closed;
+ } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
+ size_t nobjs = 0;
+@@ -117,6 +119,9 @@ do_test (int argc, char *argv[])
+ size_t buffer_length = 0;
+ while (xgetline (&buffer, &buffer_length, out))
+ {
++ *strchrnul (buffer, '\n') = '\0';
++ printf ("info: subprocess output: %s\n", buffer);
++
+ if (startswith (buffer, "la_activity: "))
+ {
+ uintptr_t cookie;
+@@ -125,29 +130,26 @@ do_test (int argc, char *argv[])
+ &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)
+ {
++ /* 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);
++
+ 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). */
++ /* LA_ACT_DELETE is called multiple times for each
++ namespace, depending on destruction order. */
+ else if (this_act == LA_ACT_DELETE)
+- {
+- last_act_cookie = acts[--nacts];
+- TEST_COMPARE (acts[nacts], cookie);
+- acts[nacts] = 0;
+- }
++ last_act_cookie = cookie;
+ else if (this_act == LA_ACT_CONSISTENT)
+ {
+ TEST_COMPARE (cookie, last_act_cookie);
++ last_act_cookie = -1;
+
+ /* LA_ACT_DELETE must always be followed by an la_objclose. */
+ if (last_act == LA_ACT_DELETE)
+@@ -179,6 +181,8 @@ do_test (int argc, char *argv[])
+ objs[nobjs].lname = lname;
+ objs[nobjs].laddr = laddr;
+ objs[nobjs].lmid = lmid;
++ objs[nobjs].cookie = cookie;
++ objs[nobjs].namespace = last_act_cookie;
+ objs[nobjs].closed = false;
+ nobjs++;
+
+@@ -201,6 +205,12 @@ do_test (int argc, char *argv[])
+ if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
+ {
+ TEST_COMPARE (objs[i].closed, false);
++ TEST_COMPARE (objs[i].cookie, cookie);
++ if (objs[i].namespace == -1)
++ /* No LA_ACT_ADD before the first la_objopen call. */
++ TEST_COMPARE (acts[0], last_act_cookie);
++ else
++ TEST_COMPARE (objs[i].namespace, last_act_cookie);
+ objs[i].closed = true;
+ break;
+ }
+@@ -209,11 +219,7 @@ do_test (int argc, char *argv[])
+ /* 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;
+- }
++ seen_first_objclose = true;
+ }
+ }
+
+diff --git a/include/link.h b/include/link.h
+index 1d74feb2bd..69bda3ed17 100644
+--- a/include/link.h
++++ b/include/link.h
+@@ -278,6 +278,10 @@ struct link_map
+ /* List of object in order of the init and fini calls. */
+ struct link_map **l_initfini;
+
++ /* Linked list of objects in reverse ELF constructor execution
++ order. Head of list is stored in _dl_init_called_list. */
++ struct link_map *l_init_called_next;
++
+ /* List of the dependencies introduced through symbol binding. */
+ struct link_map_reldeps
+ {
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index e8b7359b04..9ea9389a39 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -1037,6 +1037,10 @@ extern int _dl_check_map_versions (struct link_map *map, int verbose,
+ extern void _dl_init (struct link_map *main_map, int argc, char **argv,
+ char **env) attribute_hidden;
+
++/* List of ELF objects in reverse order of their constructor
++ invocation. */
++extern struct link_map *_dl_init_called_list attribute_hidden;
++
+ /* Call the finalizer functions of all shared objects whose
+ initializer functions have completed. */
+ extern void _dl_fini (void) attribute_hidden;
+--
+2.33.0
+
diff --git a/0002-iconv-restore-verbosity-with-unrecognized-encoding-n.patch b/0002-iconv-restore-verbosity-with-unrecognized-encoding-n.patch
new file mode 100644
index 0000000..eb18910
--- /dev/null
+++ b/0002-iconv-restore-verbosity-with-unrecognized-encoding-n.patch
@@ -0,0 +1,32 @@
+From 63250e9c571314b6daa2c949ea0af335ee766751 Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@suse.de>
+Date: Tue, 1 Aug 2023 17:01:37 +0200
+Subject: [PATCH 2/4] iconv: restore verbosity with unrecognized encoding names
+ (bug 30694)
+
+Commit 91927b7c76 ("Rewrite iconv option parsing [BZ #19519]") changed the
+iconv program to call __gconv_open directly instead of the iconv_open
+wrapper, but the former does not set errno. Update the caller to
+interpret the return codes like iconv_open does.
+
+(cherry picked from commit fc72b6d7d818ab2868920af956d1542d03342a4d)
+---
+ iconv/iconv_prog.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
+index bee898c63c..cf32cf9b44 100644
+--- a/iconv/iconv_prog.c
++++ b/iconv/iconv_prog.c
+@@ -187,7 +187,7 @@ main (int argc, char *argv[])
+
+ if (res != __GCONV_OK)
+ {
+- if (errno == EINVAL)
++ if (res == __GCONV_NOCONV || res == __GCONV_NODB)
+ {
+ /* Try to be nice with the user and tell her which of the
+ two encoding names is wrong. This is possible because
+--
+2.33.0
+
diff --git a/0002-linux-Use-rseq-area-unconditionally-in-sched_getcpu-.patch b/0002-linux-Use-rseq-area-unconditionally-in-sched_getcpu-.patch
new file mode 100644
index 0000000..b3d890d
--- /dev/null
+++ b/0002-linux-Use-rseq-area-unconditionally-in-sched_getcpu-.patch
@@ -0,0 +1,52 @@
+From 5753cda1ca0749002c4718122a9b6d5177087b7b Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Fri, 15 Mar 2024 19:08:24 +0100
+Subject: [PATCH 02/26] linux: Use rseq area unconditionally in sched_getcpu
+ (bug 31479)
+
+Originally, nptl/descr.h included <sys/rseq.h>, but we removed that
+in commit 2c6b4b272e6b4d07303af25709051c3e96288f2d ("nptl:
+Unconditionally use a 32-byte rseq area"). After that, it was
+not ensured that the RSEQ_SIG macro was defined during sched_getcpu.c
+compilation that provided a definition. This commit always checks
+the rseq area for CPU number information before using the other
+approaches.
+
+This adds an unnecessary (but well-predictable) branch on
+architectures which do not define RSEQ_SIG, but its cost is small
+compared to the system call. Most architectures that have vDSO
+acceleration for getcpu also have rseq support.
+
+Fixes: 2c6b4b272e6b4d07303af25709051c3e96288f2d
+Fixes: 1d350aa06091211863e41169729cee1bca39f72f
+Reviewed-by: Arjun Shankar <arjun@redhat.com>
+(cherry picked from commit 7a76f218677d149d8b7875b336722108239f7ee9)
+---
+ sysdeps/unix/sysv/linux/sched_getcpu.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c
+index 4457d714bc..22700ef846 100644
+--- a/sysdeps/unix/sysv/linux/sched_getcpu.c
++++ b/sysdeps/unix/sysv/linux/sched_getcpu.c
+@@ -33,17 +33,9 @@ vsyscall_sched_getcpu (void)
+ return r == -1 ? r : cpu;
+ }
+
+-#ifdef RSEQ_SIG
+ int
+ sched_getcpu (void)
+ {
+ int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id);
+ return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu ();
+ }
+-#else /* RSEQ_SIG */
+-int
+-sched_getcpu (void)
+-{
+- return vsyscall_sched_getcpu ();
+-}
+-#endif /* RSEQ_SIG */
+--
+2.33.0
+
diff --git a/0002-nptl-fix-potential-merge-of-__rseq_-relro-symbols.patch b/0002-nptl-fix-potential-merge-of-__rseq_-relro-symbols.patch
new file mode 100644
index 0000000..f393800
--- /dev/null
+++ b/0002-nptl-fix-potential-merge-of-__rseq_-relro-symbols.patch
@@ -0,0 +1,161 @@
+From 7bfc35959dae3287e9097a960ebfddb19441bb55 Mon Sep 17 00:00:00 2001
+From: Michael Jeanson <mjeanson@efficios.com>
+Date: Wed, 3 Jul 2024 12:35:34 -0400
+Subject: [PATCH 02/12] nptl: fix potential merge of __rseq_* relro symbols
+
+While working on a patch to add support for the extensible rseq ABI, we
+came across an issue where a new 'const' variable would be merged with
+the existing '__rseq_size' variable. We tracked this to the use of
+'-fmerge-all-constants' which allows the compiler to merge identical
+constant variables. This means that all 'const' variables in a compile
+unit that are of the same size and are initialized to the same value can
+be merged.
+
+In this specific case, on 32 bit systems 'unsigned int' and 'ptrdiff_t'
+are both 4 bytes and initialized to 0 which should trigger the merge.
+However for reasons we haven't delved into when the attribute 'section
+(".data.rel.ro")' is added to the mix, only variables of the same exact
+types are merged. As far as we know this behavior is not specified
+anywhere and could change with a new compiler version, hence this patch.
+
+Move the definitions of these variables into an assembler file and add
+hidden writable aliases for internal use. This has the added bonus of
+removing the asm workaround to set the values on rseq registration.
+
+Tested on Debian 12 with GCC 12.2.
+
+Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
+Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Reviewed-by: Florian Weimer <fweimer@redhat.com>
+(cherry picked from commit 2b92982e2369d292560793bee8e730f695f48ff3)
+---
+ elf/Makefile | 1 +
+ elf/dl-rseq-symbols.S | 64 +++++++++++++++++++++++++++++++++++
+ sysdeps/nptl/dl-tls_init_tp.c | 14 ++++----
+ 3 files changed, 71 insertions(+), 8 deletions(-)
+ create mode 100644 elf/dl-rseq-symbols.S
+
+diff --git a/elf/Makefile b/elf/Makefile
+index c2af11b92c..04e1d7ded5 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -74,6 +74,7 @@ dl-routines = \
+ dl-printf \
+ dl-profile \
+ dl-reloc \
++ dl-rseq-symbols \
+ dl-runtime \
+ dl-scope \
+ dl-setup_hash \
+diff --git a/elf/dl-rseq-symbols.S b/elf/dl-rseq-symbols.S
+new file mode 100644
+index 0000000000..b4bba06a99
+--- /dev/null
++++ b/elf/dl-rseq-symbols.S
+@@ -0,0 +1,64 @@
++/* Define symbols used by rseq.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++
++#if __WORDSIZE == 64
++#define RSEQ_OFFSET_SIZE 8
++#else
++#define RSEQ_OFFSET_SIZE 4
++#endif
++
++/* Some targets define a macro to denote the zero register. */
++#undef zero
++
++/* Define 2 symbols: '__rseq_size' is public const and '_rseq_size' (an
++ alias of '__rseq_size') is hidden and writable for internal use by the
++ dynamic linker which will initialize the value both symbols point to
++ before copy relocations take place. */
++
++ .globl __rseq_size
++ .type __rseq_size, %object
++ .size __rseq_size, 4
++ .hidden _rseq_size
++ .globl _rseq_size
++ .type _rseq_size, %object
++ .size _rseq_size, 4
++ .section .data.rel.ro
++ .balign 4
++__rseq_size:
++_rseq_size:
++ .zero 4
++
++/* Define 2 symbols: '__rseq_offset' is public const and '_rseq_offset' (an
++ alias of '__rseq_offset') is hidden and writable for internal use by the
++ dynamic linker which will initialize the value both symbols point to
++ before copy relocations take place. */
++
++ .globl __rseq_offset
++ .type __rseq_offset, %object
++ .size __rseq_offset, RSEQ_OFFSET_SIZE
++ .hidden _rseq_offset
++ .globl _rseq_offset
++ .type _rseq_offset, %object
++ .size _rseq_offset, RSEQ_OFFSET_SIZE
++ .section .data.rel.ro
++ .balign RSEQ_OFFSET_SIZE
++__rseq_offset:
++_rseq_offset:
++ .zero RSEQ_OFFSET_SIZE
+diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
+index 2ed98c5a31..45ae260ceb 100644
+--- a/sysdeps/nptl/dl-tls_init_tp.c
++++ b/sysdeps/nptl/dl-tls_init_tp.c
+@@ -45,8 +45,10 @@ rtld_mutex_dummy (pthread_mutex_t *lock)
+ #endif
+
+ const unsigned int __rseq_flags;
+-const unsigned int __rseq_size attribute_relro;
+-const ptrdiff_t __rseq_offset attribute_relro;
++
++/* The variables are in .data.relro but are not yet write-protected. */
++extern unsigned int _rseq_size attribute_hidden;
++extern ptrdiff_t _rseq_offset attribute_hidden;
+
+ void
+ __tls_pre_init_tp (void)
+@@ -105,10 +107,7 @@ __tls_init_tp (void)
+ do_rseq = TUNABLE_GET (rseq, int, NULL);
+ if (rseq_register_current_thread (pd, do_rseq))
+ {
+- /* We need a writable view of the variables. They are in
+- .data.relro and are not yet write-protected. */
+- extern unsigned int size __asm__ ("__rseq_size");
+- size = sizeof (pd->rseq_area);
++ _rseq_size = sizeof (pd->rseq_area);
+ }
+
+ #ifdef RSEQ_SIG
+@@ -117,8 +116,7 @@ __tls_init_tp (void)
+ all targets support __thread_pointer, so set __rseq_offset only
+ if the rseq registration may have happened because RSEQ_SIG is
+ defined. */
+- extern ptrdiff_t offset __asm__ ("__rseq_offset");
+- offset = (char *) &pd->rseq_area - (char *) __thread_pointer ();
++ _rseq_offset = (char *) &pd->rseq_area - (char *) __thread_pointer ();
+ #endif
+ }
+
+--
+2.33.0
+
diff --git a/0002-nscd-Do-not-rebuild-getaddrinfo-bug-30709.patch b/0002-nscd-Do-not-rebuild-getaddrinfo-bug-30709.patch
new file mode 100644
index 0000000..a0aed1a
--- /dev/null
+++ b/0002-nscd-Do-not-rebuild-getaddrinfo-bug-30709.patch
@@ -0,0 +1,185 @@
+From 6b99458d197ab779ebb6ff632c168e2cbfa4f543 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Fri, 11 Aug 2023 10:10:16 +0200
+Subject: [PATCH 02/12] nscd: Do not rebuild getaddrinfo (bug 30709)
+
+The nscd daemon caches hosts data from NSS modules verbatim, without
+filtering protocol families or sorting them (otherwise separate caches
+would be needed for certain ai_flags combinations). The cache
+implementation is complete separate from the getaddrinfo code. This
+means that rebuilding getaddrinfo is not needed. The only function
+actually used is __bump_nl_timestamp from check_pf.c, and this change
+moves it into nscd/connections.c.
+
+Tested on x86_64-linux-gnu with -fexceptions, built with
+build-many-glibcs.py. I also backported this patch into a distribution
+that still supports nscd and verified manually that caching still works.
+
+Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+(cherry picked from commit 039ff51ac7e02db1cfc0c23e38ac7bfbb00221d1)
+---
+ include/ifaddrs.h | 4 ---
+ inet/check_pf.c | 9 ------
+ nscd/Makefile | 2 +-
+ nscd/connections.c | 11 +++++++
+ nscd/gai.c | 50 ------------------------------
+ sysdeps/unix/sysv/linux/check_pf.c | 17 +---------
+ 6 files changed, 13 insertions(+), 80 deletions(-)
+ delete mode 100644 nscd/gai.c
+
+diff --git a/include/ifaddrs.h b/include/ifaddrs.h
+index 416118f1b3..19a3afb19f 100644
+--- a/include/ifaddrs.h
++++ b/include/ifaddrs.h
+@@ -34,9 +34,5 @@ extern void __check_native (uint32_t a1_index, int *a1_native,
+ uint32_t a2_index, int *a2_native)
+ attribute_hidden;
+
+-#if IS_IN (nscd)
+-extern uint32_t __bump_nl_timestamp (void) attribute_hidden;
+-#endif
+-
+ # endif /* !_ISOMAC */
+ #endif /* ifaddrs.h */
+diff --git a/inet/check_pf.c b/inet/check_pf.c
+index 5310c99121..6d1475920f 100644
+--- a/inet/check_pf.c
++++ b/inet/check_pf.c
+@@ -60,12 +60,3 @@ __free_in6ai (struct in6addrinfo *in6ai)
+ {
+ /* Nothing to do. */
+ }
+-
+-
+-#if IS_IN (nscd)
+-uint32_t
+-__bump_nl_timestamp (void)
+-{
+- return 0;
+-}
+-#endif
+diff --git a/nscd/Makefile b/nscd/Makefile
+index 2a0489f4cf..16b6460ee9 100644
+--- a/nscd/Makefile
++++ b/nscd/Makefile
+@@ -35,7 +35,7 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
+ getgrnam_r getgrgid_r hstcache gethstbyad_r gethstbynm3_r \
+ getsrvbynm_r getsrvbypt_r servicescache \
+ dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
+- xmalloc xstrdup aicache initgrcache gai res_hconf \
++ xmalloc xstrdup aicache initgrcache res_hconf \
+ netgroupcache cachedumper
+
+ ifeq ($(build-nscd)$(have-thread-library),yesyes)
+diff --git a/nscd/connections.c b/nscd/connections.c
+index a405a44a9b..15693e5090 100644
+--- a/nscd/connections.c
++++ b/nscd/connections.c
+@@ -256,6 +256,17 @@ int inotify_fd = -1;
+ #ifdef HAVE_NETLINK
+ /* Descriptor for netlink status updates. */
+ static int nl_status_fd = -1;
++
++static uint32_t
++__bump_nl_timestamp (void)
++{
++ static uint32_t nl_timestamp;
++
++ if (atomic_fetch_add_relaxed (&nl_timestamp, 1) + 1 == 0)
++ atomic_fetch_add_relaxed (&nl_timestamp, 1);
++
++ return nl_timestamp;
++}
+ #endif
+
+ /* Number of times clients had to wait. */
+diff --git a/nscd/gai.c b/nscd/gai.c
+deleted file mode 100644
+index e29f3fe583..0000000000
+--- a/nscd/gai.c
++++ /dev/null
+@@ -1,50 +0,0 @@
+-/* Copyright (C) 2004-2023 Free Software Foundation, Inc.
+- This file is part of the GNU C Library.
+-
+- This program is free software; you can redistribute it and/or modify
+- it under the terms of the GNU General Public License as published
+- by the Free Software Foundation; version 2 of the License, or
+- (at your option) any later version.
+-
+- This program is distributed in the hope that it will be useful,
+- but WITHOUT ANY WARRANTY; without even the implied warranty of
+- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- GNU General Public License for more details.
+-
+- You should have received a copy of the GNU General Public License
+- along with this program; if not, see <https://www.gnu.org/licenses/>. */
+-
+-#include <alloca.h>
+-#include <sys/stat.h>
+-
+-/* This file uses the getaddrinfo code but it compiles it without NSCD
+- support. We just need a few symbol renames. */
+-#define __ioctl ioctl
+-#define __getsockname getsockname
+-#define __socket socket
+-#define __recvmsg recvmsg
+-#define __bind bind
+-#define __sendto sendto
+-#define __strchrnul strchrnul
+-#define __getline getline
+-#define __qsort_r qsort_r
+-/* nscd uses 1MB or 2MB thread stacks. */
+-#define __libc_use_alloca(size) (size <= __MAX_ALLOCA_CUTOFF)
+-#define __getifaddrs getifaddrs
+-#define __freeifaddrs freeifaddrs
+-#undef __fstat64
+-#define __fstat64 fstat64
+-#undef __stat64
+-#define __stat64 stat64
+-
+-/* We are nscd, so we don't want to be talking to ourselves. */
+-#undef USE_NSCD
+-
+-#include <getaddrinfo.c>
+-
+-/* Support code. */
+-#include <check_pf.c>
+-#include <check_native.c>
+-
+-/* Some variables normally defined in libc. */
+-nss_action_list __nss_hosts_database attribute_hidden;
+diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
+index 2b0b8b6368..3aa6a00348 100644
+--- a/sysdeps/unix/sysv/linux/check_pf.c
++++ b/sysdeps/unix/sysv/linux/check_pf.c
+@@ -66,25 +66,10 @@ static struct cached_data *cache;
+ __libc_lock_define_initialized (static, lock);
+
+
+-#if IS_IN (nscd)
+-static uint32_t nl_timestamp;
+-
+-uint32_t
+-__bump_nl_timestamp (void)
+-{
+- if (atomic_fetch_add_relaxed (&nl_timestamp, 1) + 1 == 0)
+- atomic_fetch_add_relaxed (&nl_timestamp, 1);
+-
+- return nl_timestamp;
+-}
+-#endif
+-
+ static inline uint32_t
+ get_nl_timestamp (void)
+ {
+-#if IS_IN (nscd)
+- return nl_timestamp;
+-#elif defined USE_NSCD
++#if defined USE_NSCD
+ return __nscd_get_nl_timestamp ();
+ #else
+ return 0;
+--
+2.33.0
+
diff --git a/0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch b/0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
new file mode 100644
index 0000000..c19c3bf
--- /dev/null
+++ b/0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
@@ -0,0 +1,106 @@
+From d0338312aace5bbfef85e03055e1212dd0e49578 Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun@redhat.com>
+Date: Mon, 15 Jan 2024 17:44:44 +0100
+Subject: [PATCH 2/3] syslog: Fix heap buffer overflow in __vsyslog_internal
+ (CVE-2023-6779)
+
+__vsyslog_internal used the return value of snprintf/vsnprintf to
+calculate buffer sizes for memory allocation. If these functions (for
+any reason) failed and returned -1, the resulting buffer would be too
+small to hold output. This commit fixes that.
+
+All snprintf/vsnprintf calls are checked for negative return values and
+the function silently returns upon encountering them.
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 7e5a0c286da33159d47d0122007aac016f3e02cd)
+---
+ misc/syslog.c | 39 ++++++++++++++++++++++++++++-----------
+ 1 file changed, 28 insertions(+), 11 deletions(-)
+
+diff --git a/misc/syslog.c b/misc/syslog.c
+index 814d224a1e..53440e47ad 100644
+--- a/misc/syslog.c
++++ b/misc/syslog.c
+@@ -185,11 +185,13 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ else
+ l = __snprintf (bufs, sizeof bufs,
+ SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++ if (l < 0)
++ goto out;
+
+ char *pos;
+ size_t len;
+
+- if (0 <= l && l < sizeof bufs)
++ if (l < sizeof bufs)
+ {
+ /* At this point, there is still a chance that we can print the
+ remaining part of the log into bufs and use that. */
+@@ -215,12 +217,15 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ __set_errno (saved_errno);
+
+ vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
++ va_end (apc);
++
++ if (vl < 0)
++ goto out;
+
+- if (!(0 <= vl && vl < len))
++ if (vl >= len)
+ buf = NULL;
+
+ bufsize = l + vl;
+- va_end (apc);
+ }
+
+ if (buf == NULL)
+@@ -231,25 +236,37 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ /* Tell the cancellation handler to free this buffer. */
+ clarg.buf = buf;
+
++ int cl;
+ if (has_ts)
+- __snprintf (buf, l + 1,
+- SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
++ cl = __snprintf (buf, l + 1,
++ SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+ else
+- __snprintf (buf, l + 1,
+- SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++ cl = __snprintf (buf, l + 1,
++ SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++ if (cl != l)
++ goto out;
+
+ va_list apc;
+ va_copy (apc, ap);
+- __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
+- mode_flags);
++ cl = __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
++ mode_flags);
+ va_end (apc);
++
++ if (cl != vl)
++ goto out;
+ }
+ else
+ {
++ int bl;
+ /* Nothing much to do but emit an error message. */
+- bufsize = __snprintf (bufs, sizeof bufs,
+- "out of memory[%d]", __getpid ());
++ bl = __snprintf (bufs, sizeof bufs,
++ "out of memory[%d]", __getpid ());
++ if (bl < 0 || bl >= sizeof bufs)
++ goto out;
++
++ bufsize = bl;
+ buf = bufs;
++ msgoff = 0;
+ }
+ }
+
+--
+2.33.0
+
diff --git a/0003-LoongArch-Correct-__ieee754-_-_scalb-__ieee754-_-_sc.patch b/0003-LoongArch-Correct-__ieee754-_-_scalb-__ieee754-_-_sc.patch
new file mode 100644
index 0000000..580d498
--- /dev/null
+++ b/0003-LoongArch-Correct-__ieee754-_-_scalb-__ieee754-_-_sc.patch
@@ -0,0 +1,23 @@
+From 0518bb0c16cb5986aaf35cf5e634964d7a06978b Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Mon, 11 Mar 2024 16:07:48 +0800
+Subject: [PATCH 03/26] LoongArch: Correct {__ieee754, _}_scalb -> {__ieee754,
+ _}_scalbf
+
+---
+ sysdeps/loongarch/fpu/e_scalbf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sysdeps/loongarch/fpu/e_scalbf.c b/sysdeps/loongarch/fpu/e_scalbf.c
+index c37b0fd19d..4690224621 100644
+--- a/sysdeps/loongarch/fpu/e_scalbf.c
++++ b/sysdeps/loongarch/fpu/e_scalbf.c
+@@ -57,4 +57,4 @@ __ieee754_scalbf (float x, float fn)
+
+ return x;
+ }
+-libm_alias_finite (__ieee754_scalb, __scalb)
++libm_alias_finite (__ieee754_scalbf, __scalbf)
+--
+2.33.0
+
diff --git a/0003-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch b/0003-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch
new file mode 100644
index 0000000..0508bef
--- /dev/null
+++ b/0003-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch
@@ -0,0 +1,32 @@
+From 73e3fcd1a552783e66ff1f65c5f322e2f17a81d1 Mon Sep 17 00:00:00 2001
+From: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date: Tue, 19 Sep 2023 13:25:40 -0400
+Subject: [PATCH 3/4] Propagate GLIBC_TUNABLES in setxid binaries
+
+GLIBC_TUNABLES scrubbing happens earlier than envvar scrubbing and some
+tunables are required to propagate past setxid boundary, like their
+env_alias. Rely on tunable scrubbing to clean out GLIBC_TUNABLES like
+before, restoring behaviour in glibc 2.37 and earlier.
+
+Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 0d5f9ea97f1b39f2a855756078771673a68497e1)
+---
+ sysdeps/generic/unsecvars.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/sysdeps/generic/unsecvars.h b/sysdeps/generic/unsecvars.h
+index 81397fb90b..8278c50a84 100644
+--- a/sysdeps/generic/unsecvars.h
++++ b/sysdeps/generic/unsecvars.h
+@@ -4,7 +4,6 @@
+ #define UNSECURE_ENVVARS \
+ "GCONV_PATH\0" \
+ "GETCONF_DIR\0" \
+- "GLIBC_TUNABLES\0" \
+ "HOSTALIASES\0" \
+ "LD_AUDIT\0" \
+ "LD_DEBUG\0" \
+--
+2.33.0
+
diff --git a/0003-Revert-elf-Move-l_init_called_next-to-old-place-of-l.patch b/0003-Revert-elf-Move-l_init_called_next-to-old-place-of-l.patch
new file mode 100644
index 0000000..f634150
--- /dev/null
+++ b/0003-Revert-elf-Move-l_init_called_next-to-old-place-of-l.patch
@@ -0,0 +1,42 @@
+From 1e04dcec491bd8f48b5b74ce3e8414132578a645 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 19 Oct 2023 09:17:38 +0200
+Subject: [PATCH 3/3] Revert "elf: Move l_init_called_next to old place of
+ l_text_end in link map"
+
+This reverts commit d3ba6c1333b10680ce5900a628108507d9d4b844.
+
+Reason: Preserve internal ABI.
+---
+ include/link.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/link.h b/include/link.h
+index a02d5f2eba..69bda3ed17 100644
+--- a/include/link.h
++++ b/include/link.h
+@@ -256,10 +256,6 @@ struct link_map
+ /* End of the executable part of the mapping. */
+ ElfW(Addr) l_text_end;
+
+- /* Linked list of objects in reverse ELF constructor execution
+- order. Head of list is stored in _dl_init_called_list. */
+- struct link_map *l_init_called_next;
+-
+ /* Default array for 'l_scope'. */
+ struct r_scope_elem *l_scope_mem[4];
+ /* Size of array allocated for 'l_scope'. */
+@@ -282,6 +278,10 @@ struct link_map
+ /* List of object in order of the init and fini calls. */
+ struct link_map **l_initfini;
+
++ /* Linked list of objects in reverse ELF constructor execution
++ order. Head of list is stored in _dl_init_called_list. */
++ struct link_map *l_init_called_next;
++
+ /* List of the dependencies introduced through symbol binding. */
+ struct link_map_reldeps
+ {
+--
+2.33.0
+
diff --git a/0003-elf-Make-dl-rseq-symbols-Linux-only.patch b/0003-elf-Make-dl-rseq-symbols-Linux-only.patch
new file mode 100644
index 0000000..484d0d0
--- /dev/null
+++ b/0003-elf-Make-dl-rseq-symbols-Linux-only.patch
@@ -0,0 +1,51 @@
+From d9d019d674f95509b5001f4d878ae09e32ea7a10 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Thu, 4 Jul 2024 10:09:07 -0300
+Subject: [PATCH 03/12] elf: Make dl-rseq-symbols Linux only
+
+And avoid a Hurd build failures.
+
+Checked on x86_64-linux-gnu.
+
+(cherry picked from commit 9fc639f654dc004736836613be703e6bed0c36a8)
+---
+ elf/Makefile | 1 -
+ sysdeps/unix/sysv/linux/Makefile | 4 ++++
+ {elf => sysdeps/unix/sysv/linux}/dl-rseq-symbols.S | 0
+ 3 files changed, 4 insertions(+), 1 deletion(-)
+ rename {elf => sysdeps/unix/sysv/linux}/dl-rseq-symbols.S (100%)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 04e1d7ded5..c2af11b92c 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -74,7 +74,6 @@ dl-routines = \
+ dl-printf \
+ dl-profile \
+ dl-reloc \
+- dl-rseq-symbols \
+ dl-runtime \
+ dl-scope \
+ dl-setup_hash \
+diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
+index be801e3be4..623a7d4de0 100644
+--- a/sysdeps/unix/sysv/linux/Makefile
++++ b/sysdeps/unix/sysv/linux/Makefile
+@@ -587,6 +587,10 @@ tests += \
+ endif
+
+ ifeq ($(subdir),elf)
++dl-routines += \
++ dl-rseq-symbols \
++ # dl-routines
++
+ sysdep-rtld-routines += \
+ dl-brk \
+ dl-getcwd \
+diff --git a/elf/dl-rseq-symbols.S b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S
+similarity index 100%
+rename from elf/dl-rseq-symbols.S
+rename to sysdeps/unix/sysv/linux/dl-rseq-symbols.S
+--
+2.33.0
+
diff --git a/0003-elf-Remove-unused-l_text_end-field-from-struct-link_.patch b/0003-elf-Remove-unused-l_text_end-field-from-struct-link_.patch
new file mode 100644
index 0000000..86e34f8
--- /dev/null
+++ b/0003-elf-Remove-unused-l_text_end-field-from-struct-link_.patch
@@ -0,0 +1,142 @@
+From 750f19526ae71aac801c77a3f7ef5374890c09b7 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Fri, 8 Sep 2023 13:02:06 +0200
+Subject: [PATCH 3/5] elf: Remove unused l_text_end field from struct link_map
+
+It is a left-over from commit 52a01100ad011293197637e42b5be1a479a2
+("elf: Remove ad-hoc restrictions on dlopen callers [BZ #22787]").
+
+When backporting commmit 6985865bc3ad5b23147ee73466583dd7fdf65892
+("elf: Always call destructors in reverse constructor order
+(bug 30785)"), we can move the l_init_called_next field to this
+place, so that the internal GLIBC_PRIVATE ABI does not change.
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+Tested-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 53df2ce6885da3d0e89e87dca7b095622296014f)
+---
+ elf/dl-load.c | 2 +-
+ elf/dl-load.h | 7 ++-----
+ elf/rtld.c | 6 ------
+ elf/setup-vdso.h | 4 ----
+ include/link.h | 2 --
+ 5 files changed, 3 insertions(+), 18 deletions(-)
+
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 9a87fda9c9..2923b1141d 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1253,7 +1253,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
+
+ /* Now process the load commands and map segments into memory.
+ This is responsible for filling in:
+- l_map_start, l_map_end, l_addr, l_contiguous, l_text_end, l_phdr
++ l_map_start, l_map_end, l_addr, l_contiguous, l_phdr
+ */
+ errstring = _dl_map_segments (l, fd, header, type, loadcmds, nloadcmds,
+ maplength, has_holes, loader);
+diff --git a/elf/dl-load.h b/elf/dl-load.h
+index ecf6910c68..1d5207694b 100644
+--- a/elf/dl-load.h
++++ b/elf/dl-load.h
+@@ -83,14 +83,11 @@ struct loadcmd
+
+ /* This is a subroutine of _dl_map_segments. It should be called for each
+ load command, some time after L->l_addr has been set correctly. It is
+- responsible for setting up the l_text_end and l_phdr fields. */
++ responsible for setting the l_phdr fields */
+ static __always_inline void
+ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
+ const struct loadcmd *c)
+ {
+- if (c->prot & PROT_EXEC)
+- l->l_text_end = l->l_addr + c->mapend;
+-
+ if (l->l_phdr == 0
+ && c->mapoff <= header->e_phoff
+ && ((size_t) (c->mapend - c->mapstart + c->mapoff)
+@@ -103,7 +100,7 @@ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
+
+ /* This is a subroutine of _dl_map_object_from_fd. It is responsible
+ for filling in several fields in *L: l_map_start, l_map_end, l_addr,
+- l_contiguous, l_text_end, l_phdr. On successful return, all the
++ l_contiguous, l_phdr. On successful return, all the
+ segments are mapped (or copied, or whatever) from the file into their
+ final places in the address space, with the correct page permissions,
+ and any bss-like regions already zeroed. It returns a null pointer
+diff --git a/elf/rtld.c b/elf/rtld.c
+index a91e2a4471..5107d16fe3 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -477,7 +477,6 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
+ GL(dl_rtld_map).l_real = &GL(dl_rtld_map);
+ GL(dl_rtld_map).l_map_start = (ElfW(Addr)) &__ehdr_start;
+ GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
+- GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext;
+ /* Copy the TLS related data if necessary. */
+ #ifndef DONT_USE_BOOTSTRAP_MAP
+ # if NO_TLS_OFFSET != 0
+@@ -1119,7 +1118,6 @@ rtld_setup_main_map (struct link_map *main_map)
+ bool has_interp = false;
+
+ main_map->l_map_end = 0;
+- main_map->l_text_end = 0;
+ /* Perhaps the executable has no PT_LOAD header entries at all. */
+ main_map->l_map_start = ~0;
+ /* And it was opened directly. */
+@@ -1211,8 +1209,6 @@ rtld_setup_main_map (struct link_map *main_map)
+ allocend = main_map->l_addr + ph->p_vaddr + ph->p_memsz;
+ if (main_map->l_map_end < allocend)
+ main_map->l_map_end = allocend;
+- if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end)
+- main_map->l_text_end = allocend;
+
+ /* The next expected address is the page following this load
+ segment. */
+@@ -1272,8 +1268,6 @@ rtld_setup_main_map (struct link_map *main_map)
+ = (char *) main_map->l_tls_initimage + main_map->l_addr;
+ if (! main_map->l_map_end)
+ main_map->l_map_end = ~0;
+- if (! main_map->l_text_end)
+- main_map->l_text_end = ~0;
+ if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name)
+ {
+ /* We were invoked directly, so the program might not have a
+diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
+index 0079842d1f..d92b12a7aa 100644
+--- a/elf/setup-vdso.h
++++ b/elf/setup-vdso.h
+@@ -51,9 +51,6 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
+ l->l_addr = ph->p_vaddr;
+ if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
+ l->l_map_end = ph->p_vaddr + ph->p_memsz;
+- if ((ph->p_flags & PF_X)
+- && ph->p_vaddr + ph->p_memsz >= l->l_text_end)
+- l->l_text_end = ph->p_vaddr + ph->p_memsz;
+ }
+ else
+ /* There must be no TLS segment. */
+@@ -62,7 +59,6 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
+ l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
+ l->l_addr = l->l_map_start - l->l_addr;
+ 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, false);
+ _dl_setup_hash (l);
+diff --git a/include/link.h b/include/link.h
+index 69bda3ed17..c6af095d87 100644
+--- a/include/link.h
++++ b/include/link.h
+@@ -253,8 +253,6 @@ struct link_map
+ /* Start and finish of memory map for this object. l_map_start
+ need not be the same as l_addr. */
+ ElfW(Addr) l_map_start, l_map_end;
+- /* End of the executable part of the mapping. */
+- ElfW(Addr) l_text_end;
+
+ /* Default array for 'l_scope'. */
+ struct r_scope_elem *l_scope_mem[4];
+--
+2.33.0
+
diff --git a/0003-string-Fix-tester-build-with-fortify-enable-with-gcc.patch b/0003-string-Fix-tester-build-with-fortify-enable-with-gcc.patch
new file mode 100644
index 0000000..b467daa
--- /dev/null
+++ b/0003-string-Fix-tester-build-with-fortify-enable-with-gcc.patch
@@ -0,0 +1,50 @@
+From d94461bb86ba176b9390c0015bb612a528e22d95 Mon Sep 17 00:00:00 2001
+From: Mahesh Bodapati <bmahi496@linux.ibm.com>
+Date: Fri, 11 Aug 2023 10:38:25 -0500
+Subject: [PATCH 3/4] string: Fix tester build with fortify enable with gcc <
+ 12
+
+When building with fortify enabled, GCC < 12 issues a warning on the
+fortify strncat wrapper might overflow the destination buffer (the
+failure is tied to -Werror).
+
+Checked on ppc64 and x86_64.
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+(cherry picked from commit f1c7ed0859a45929136836341741c7cd70f428cb)
+---
+ string/tester.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/string/tester.c b/string/tester.c
+index f7d4bac5a8..824cf315ff 100644
+--- a/string/tester.c
++++ b/string/tester.c
+@@ -34,6 +34,14 @@
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
+ #endif
+
++/* When building with fortify enabled, GCC < 12 issues a warning on the
++ fortify strncat wrapper might overflow the destination buffer (the
++ failure is tied to -Werror).
++ Triggered by strncat fortify wrapper when it is enabled. */
++#if __GNUC_PREREQ (11, 0)
++DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overread");
++#endif
++
+ #include <errno.h>
+ #include <stdint.h>
+ #include <stdio.h>
+@@ -52,9 +60,6 @@ DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args");
+ DIAG_IGNORE_NEEDS_COMMENT (9, "-Wrestrict");
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+ #endif
+-#if __GNUC_PREREQ (11, 0)
+-DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overread");
+-#endif
+
+
+ #define STREQ(a, b) (strcmp((a), (b)) == 0)
+--
+2.33.0
+
diff --git a/0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch b/0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch
new file mode 100644
index 0000000..70ee520
--- /dev/null
+++ b/0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch
@@ -0,0 +1,41 @@
+From d37c2b20a4787463d192b32041c3406c2bd91de0 Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun@redhat.com>
+Date: Mon, 15 Jan 2024 17:44:45 +0100
+Subject: [PATCH 3/3] syslog: Fix integer overflow in __vsyslog_internal
+ (CVE-2023-6780)
+
+__vsyslog_internal calculated a buffer size by adding two integers, but
+did not first check if the addition would overflow. This commit fixes
+that.
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+Tested-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit ddf542da94caf97ff43cc2875c88749880b7259b)
+---
+ misc/syslog.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/misc/syslog.c b/misc/syslog.c
+index 53440e47ad..4af87f54fd 100644
+--- a/misc/syslog.c
++++ b/misc/syslog.c
+@@ -41,6 +41,7 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94";
+ #include <sys/uio.h>
+ #include <sys/un.h>
+ #include <syslog.h>
++#include <limits.h>
+
+ static int LogType = SOCK_DGRAM; /* type of socket connection */
+ static int LogFile = -1; /* fd for log */
+@@ -219,7 +220,7 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
+ va_end (apc);
+
+- if (vl < 0)
++ if (vl < 0 || vl >= INT_MAX - l)
+ goto out;
+
+ if (vl >= len)
+--
+2.33.0
+
diff --git a/0003-x86-Fix-incorrect-scope-of-setting-shared_per_thread.patch b/0003-x86-Fix-incorrect-scope-of-setting-shared_per_thread.patch
new file mode 100644
index 0000000..cb8390d
--- /dev/null
+++ b/0003-x86-Fix-incorrect-scope-of-setting-shared_per_thread.patch
@@ -0,0 +1,45 @@
+From 5ea70cc02626d9b85f1570153873d8648a47bf95 Mon Sep 17 00:00:00 2001
+From: Noah Goldstein <goldstein.w.n@gmail.com>
+Date: Thu, 10 Aug 2023 19:28:24 -0500
+Subject: [PATCH 03/12] x86: Fix incorrect scope of setting `shared_per_thread`
+ [BZ# 30745]
+
+The:
+
+```
+ if (shared_per_thread > 0 && threads > 0)
+ shared_per_thread /= threads;
+```
+
+Code was accidentally moved to inside the else scope. This doesn't
+match how it was previously (before af992e7abd).
+
+This patch fixes that by putting the division after the `else` block.
+
+(cherry picked from commit 084fb31bc2c5f95ae0b9e6df4d3cf0ff43471ede)
+---
+ sysdeps/x86/dl-cacheinfo.h | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
+index 285773039f..5ddb35c9d9 100644
+--- a/sysdeps/x86/dl-cacheinfo.h
++++ b/sysdeps/x86/dl-cacheinfo.h
+@@ -770,11 +770,10 @@ get_common_cache_info (long int *shared_ptr, long int * shared_per_thread_ptr, u
+ level. */
+ threads = ((cpu_features->features[CPUID_INDEX_1].cpuid.ebx >> 16)
+ & 0xff);
+-
+- /* Get per-thread size of highest level cache. */
+- if (shared_per_thread > 0 && threads > 0)
+- shared_per_thread /= threads;
+ }
++ /* Get per-thread size of highest level cache. */
++ if (shared_per_thread > 0 && threads > 0)
++ shared_per_thread /= threads;
+ }
+
+ /* Account for non-inclusive L2 and L3 caches. */
+--
+2.33.0
+
diff --git a/0004-Add-HWCAP2_MOPS-from-Linux-6.5-to-AArch64-bits-hwcap.patch b/0004-Add-HWCAP2_MOPS-from-Linux-6.5-to-AArch64-bits-hwcap.patch
new file mode 100644
index 0000000..2efca3d
--- /dev/null
+++ b/0004-Add-HWCAP2_MOPS-from-Linux-6.5-to-AArch64-bits-hwcap.patch
@@ -0,0 +1,27 @@
+From 5456ff5d80e45741a73cf9fa792d789a1ed17a09 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Tue, 17 Oct 2023 13:13:27 +0000
+Subject: [PATCH 04/26] Add HWCAP2_MOPS from Linux 6.5 to AArch64 bits/hwcap.h
+
+Linux 6.5 adds a new AArch64 HWCAP2 value, HWCAP2_MOPS. Add it to
+glibc's bits/hwcap.h.
+
+Tested with build-many-glibcs.py for aarch64-linux-gnu.
+
+(cherry picked from commit ff5d2abd18629e0efac41e31699cdff3be0e08fa)
+---
+ sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h
+index 55c7ed39be..b251c2d417 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h
++++ b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h
+@@ -98,3 +98,4 @@
+ #define HWCAP2_SME_BI32I32 (1UL << 40)
+ #define HWCAP2_SME_B16B16 (1UL << 41)
+ #define HWCAP2_SME_F16F16 (1UL << 42)
++#define HWCAP2_MOPS (1UL << 43)
+--
+2.33.0
+
diff --git a/0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch b/0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch
new file mode 100644
index 0000000..3dd3fd1
--- /dev/null
+++ b/0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch
@@ -0,0 +1,171 @@
+From bb30bd21622910715b7b3020b17e6e97a8b4ec80 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 8 Jul 2024 21:14:00 +0200
+Subject: [PATCH 04/12] Linux: Make __rseq_size useful for feature detection
+ (bug 31965)
+
+The __rseq_size value is now the active area of struct rseq
+(so 20 initially), not the full struct size including padding
+at the end (32 initially).
+
+Update misc/tst-rseq to print some additional diagnostics.
+
+Reviewed-by: Michael Jeanson <mjeanson@efficios.com>
+Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+(cherry picked from commit 2e456ccf0c34a056e3ccafac4a0c7effef14d918)
+---
+ NEWS | 6 ++++++
+ manual/threads.texi | 8 ++++++--
+ sysdeps/nptl/dl-tls_init_tp.c | 8 +-------
+ sysdeps/unix/sysv/linux/rseq-internal.h | 23 +++++++++++++++++++++--
+ sysdeps/unix/sysv/linux/tst-rseq.c | 10 +++++++++-
+ 5 files changed, 43 insertions(+), 12 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 6768c2da6f..f0a0834496 100644
+--- a/NEWS
++++ b/NEWS
+@@ -7,6 +7,11 @@ using `glibc' in the "product" field.
+
+ Version 2.38.1
+
++Deprecated and removed features, and other changes affecting compatibility:
++
++* __rseq_size now denotes the size of the active rseq area (20 bytes
++ initially), not the size of struct rseq (32 bytes initially).
++
+ Security related changes:
+
+ CVE-2023-4527: If the system is configured in no-aaaa mode via
+@@ -46,6 +51,7 @@ The following bugs are resolved with this release:
+ [31183] Wide stream buffer size reduced MB_LEN_MAX bytes after bug 17522 fix
+ [31184] FAIL: elf/tst-tlsgap
+ [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
++ [31965] rseq extension mechanism does not work as intended
+
+
+ Version 2.38
+diff --git a/manual/threads.texi b/manual/threads.texi
+index e5544ff3da..25e99c9606 100644
+--- a/manual/threads.texi
++++ b/manual/threads.texi
+@@ -1007,8 +1007,12 @@ This variable is either zero (if restartable sequence registration
+ failed or has been disabled) or the size of the restartable sequence
+ registration. This can be different from the size of @code{struct rseq}
+ if the kernel has extended the size of the registration. If
+-registration is successful, @code{__rseq_size} is at least 32 (the
+-initial size of @code{struct rseq}).
++registration is successful, @code{__rseq_size} is at least 20 (the
++initially active size of @code{struct rseq}).
++
++Previous versions of @theglibc{} set this to 32 even if the kernel only
++supported the initial area of 20 bytes because the value included unused
++padding at the end of the restartable sequence area.
+ @end deftypevar
+
+ @deftypevar {unsigned int} __rseq_flags
+diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
+index 45ae260ceb..8f731393c4 100644
+--- a/sysdeps/nptl/dl-tls_init_tp.c
++++ b/sysdeps/nptl/dl-tls_init_tp.c
+@@ -46,10 +46,6 @@ rtld_mutex_dummy (pthread_mutex_t *lock)
+
+ const unsigned int __rseq_flags;
+
+-/* The variables are in .data.relro but are not yet write-protected. */
+-extern unsigned int _rseq_size attribute_hidden;
+-extern ptrdiff_t _rseq_offset attribute_hidden;
+-
+ void
+ __tls_pre_init_tp (void)
+ {
+@@ -106,9 +102,7 @@ __tls_init_tp (void)
+ bool do_rseq = true;
+ do_rseq = TUNABLE_GET (rseq, int, NULL);
+ if (rseq_register_current_thread (pd, do_rseq))
+- {
+- _rseq_size = sizeof (pd->rseq_area);
+- }
++ _rseq_size = RSEQ_AREA_SIZE_INITIAL_USED;
+
+ #ifdef RSEQ_SIG
+ /* This should be a compile-time constant, but the current
+diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
+index 294880c04e..226ba59a24 100644
+--- a/sysdeps/unix/sysv/linux/rseq-internal.h
++++ b/sysdeps/unix/sysv/linux/rseq-internal.h
+@@ -25,15 +25,34 @@
+ #include <stdio.h>
+ #include <sys/rseq.h>
+
++/* 32 is the initially required value for the area size. The
++ actually used rseq size may be less (20 bytes initially). */
++#define RSEQ_AREA_SIZE_INITIAL 32
++#define RSEQ_AREA_SIZE_INITIAL_USED 20
++
++/* The variables are in .data.relro but are not yet write-protected. */
++extern unsigned int _rseq_size attribute_hidden;
++extern ptrdiff_t _rseq_offset attribute_hidden;
++
+ #ifdef RSEQ_SIG
+ static inline bool
+ rseq_register_current_thread (struct pthread *self, bool do_rseq)
+ {
+ if (do_rseq)
+ {
++ unsigned int size;
++#if IS_IN (rtld)
++ /* Use the hidden symbol in ld.so. */
++ size = _rseq_size;
++#else
++ size = __rseq_size;
++#endif
++ if (size < RSEQ_AREA_SIZE_INITIAL)
++ /* The initial implementation used only 20 bytes out of 32,
++ but still expected size 32. */
++ size = RSEQ_AREA_SIZE_INITIAL;
+ int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area,
+- sizeof (self->rseq_area),
+- 0, RSEQ_SIG);
++ size, 0, RSEQ_SIG);
+ if (!INTERNAL_SYSCALL_ERROR_P (ret))
+ return true;
+ }
+diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c
+index 16983503b1..9f9aa7eb21 100644
+--- a/sysdeps/unix/sysv/linux/tst-rseq.c
++++ b/sysdeps/unix/sysv/linux/tst-rseq.c
+@@ -29,6 +29,7 @@
+ # include <stdlib.h>
+ # include <string.h>
+ # include <syscall.h>
++# include <sys/auxv.h>
+ # include <thread_pointer.h>
+ # include <tls.h>
+ # include "tst-rseq.h"
+@@ -42,7 +43,8 @@ do_rseq_main_test (void)
+ TEST_COMPARE (__rseq_flags, 0);
+ TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset
+ == (char *) &pd->rseq_area);
+- TEST_COMPARE (__rseq_size, sizeof (pd->rseq_area));
++ /* The current implementation only supports the initial size. */
++ TEST_COMPARE (__rseq_size, 20);
+ }
+
+ static void
+@@ -52,6 +54,12 @@ do_rseq_test (void)
+ {
+ FAIL_UNSUPPORTED ("kernel does not support rseq, skipping test");
+ }
++ printf ("info: __rseq_size: %u\n", __rseq_size);
++ printf ("info: __rseq_offset: %td\n", __rseq_offset);
++ printf ("info: __rseq_flags: %u\n", __rseq_flags);
++ printf ("info: getauxval (AT_RSEQ_FEATURE_SIZE): %ld\n",
++ getauxval (AT_RSEQ_FEATURE_SIZE));
++ printf ("info: getauxval (AT_RSEQ_ALIGN): %ld\n", getauxval (AT_RSEQ_ALIGN));
+ do_rseq_main_test ();
+ }
+ #else /* RSEQ_SIG */
+--
+2.33.0
+
diff --git a/0004-elf-Move-l_init_called_next-to-old-place-of-l_text_e.patch b/0004-elf-Move-l_init_called_next-to-old-place-of-l_text_e.patch
new file mode 100644
index 0000000..53db4f2
--- /dev/null
+++ b/0004-elf-Move-l_init_called_next-to-old-place-of-l_text_e.patch
@@ -0,0 +1,41 @@
+From d3ba6c1333b10680ce5900a628108507d9d4b844 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 11 Sep 2023 09:17:52 +0200
+Subject: [PATCH 4/5] elf: Move l_init_called_next to old place of l_text_end
+ in link map
+
+This preserves all member offsets and the GLIBC_PRIVATE ABI
+for backporting.
+---
+ include/link.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/link.h b/include/link.h
+index c6af095d87..686813f281 100644
+--- a/include/link.h
++++ b/include/link.h
+@@ -254,6 +254,10 @@ struct link_map
+ need not be the same as l_addr. */
+ ElfW(Addr) l_map_start, l_map_end;
+
++ /* Linked list of objects in reverse ELF constructor execution
++ order. Head of list is stored in _dl_init_called_list. */
++ struct link_map *l_init_called_next;
++
+ /* Default array for 'l_scope'. */
+ struct r_scope_elem *l_scope_mem[4];
+ /* Size of array allocated for 'l_scope'. */
+@@ -276,10 +280,6 @@ struct link_map
+ /* List of object in order of the init and fini calls. */
+ struct link_map **l_initfini;
+
+- /* Linked list of objects in reverse ELF constructor execution
+- order. Head of list is stored in _dl_init_called_list. */
+- struct link_map *l_init_called_next;
+-
+ /* List of the dependencies introduced through symbol binding. */
+ struct link_map_reldeps
+ {
+--
+2.33.0
+
diff --git a/0004-manual-jobs.texi-Add-missing-item-EPERM-for-getpgid.patch b/0004-manual-jobs.texi-Add-missing-item-EPERM-for-getpgid.patch
new file mode 100644
index 0000000..a60c664
--- /dev/null
+++ b/0004-manual-jobs.texi-Add-missing-item-EPERM-for-getpgid.patch
@@ -0,0 +1,30 @@
+From 0e1ef6779a90bc0f8a05bc367796df2793deecaa Mon Sep 17 00:00:00 2001
+From: Mark Wielaard <mark@klomp.org>
+Date: Thu, 24 Aug 2023 21:36:34 +0200
+Subject: [PATCH 4/4] manual/jobs.texi: Add missing @item EPERM for getpgid
+
+The missing @item makes it look like errno will be set to ESRCH
+if a cross-session getpgid is not permitted.
+
+Found by ulfvonbelow on irc.
+
+(cherry picked from commit 5a21cefd5abab1b99eda1fbf84204a9bf41662ab)
+---
+ manual/job.texi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/manual/job.texi b/manual/job.texi
+index 42cb9fb26d..8157f13a1c 100644
+--- a/manual/job.texi
++++ b/manual/job.texi
+@@ -1133,6 +1133,7 @@ following @code{errno} error conditions are defined for this function:
+ @table @code
+ @item ESRCH
+ There is no process with the given process ID @var{pid}.
++@item EPERM
+ The calling process and the process specified by @var{pid} are in
+ different sessions, and the implementation doesn't allow to access the
+ process group ID of the process with ID @var{pid} from the calling
+--
+2.33.0
+
diff --git a/0004-tunables-Terminate-if-end-of-input-is-reached-CVE-20.patch b/0004-tunables-Terminate-if-end-of-input-is-reached-CVE-20.patch
new file mode 100644
index 0000000..1de6445
--- /dev/null
+++ b/0004-tunables-Terminate-if-end-of-input-is-reached-CVE-20.patch
@@ -0,0 +1,173 @@
+From 750a45a783906a19591fb8ff6b7841470f1f5701 Mon Sep 17 00:00:00 2001
+From: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date: Tue, 19 Sep 2023 18:39:32 -0400
+Subject: [PATCH 4/4] tunables: Terminate if end of input is reached
+ (CVE-2023-4911)
+
+The string parsing routine may end up writing beyond bounds of tunestr
+if the input tunable string is malformed, of the form name=name=val.
+This gets processed twice, first as name=name=val and next as name=val,
+resulting in tunestr being name=name=val:name=val, thus overflowing
+tunestr.
+
+Terminate the parsing loop at the first instance itself so that tunestr
+does not overflow.
+
+This also fixes up tst-env-setuid-tunables to actually handle failures
+correct and add new tests to validate the fix for this CVE.
+
+Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 1056e5b4c3f2d90ed2b4a55f96add28da2f4c8fa)
+---
+ NEWS | 5 +++++
+ elf/dl-tunables.c | 17 +++++++++-------
+ elf/tst-env-setuid-tunables.c | 37 +++++++++++++++++++++++++++--------
+ 3 files changed, 44 insertions(+), 15 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index f1b1b0a3b4..bfcd46efa9 100644
+--- a/NEWS
++++ b/NEWS
+@@ -24,6 +24,11 @@ Security related changes:
+ an application calls getaddrinfo for AF_INET6 with AI_CANONNAME,
+ AI_ALL and AI_V4MAPPED flags set.
+
++ CVE-2023-4911: If a tunable of the form NAME=NAME=VAL is passed in the
++ environment of a setuid program and NAME is valid, it may result in a
++ buffer overflow, which could be exploited to achieve escalated
++ privileges. This flaw was introduced in glibc 2.34.
++
+ The following bugs are resolved with this release:
+
+ [30723] posix_memalign repeatedly scans long bin lists
+diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
+index 62b7332d95..cae67efa0a 100644
+--- a/elf/dl-tunables.c
++++ b/elf/dl-tunables.c
+@@ -180,11 +180,7 @@ parse_tunables (char *tunestr, char *valstring)
+ /* If we reach the end of the string before getting a valid name-value
+ pair, bail out. */
+ if (p[len] == '\0')
+- {
+- if (__libc_enable_secure)
+- tunestr[off] = '\0';
+- return;
+- }
++ break;
+
+ /* We did not find a valid name-value pair before encountering the
+ colon. */
+@@ -244,9 +240,16 @@ parse_tunables (char *tunestr, char *valstring)
+ }
+ }
+
+- if (p[len] != '\0')
+- p += len + 1;
++ /* We reached the end while processing the tunable string. */
++ if (p[len] == '\0')
++ break;
++
++ p += len + 1;
+ }
++
++ /* Terminate tunestr before we leave. */
++ if (__libc_enable_secure)
++ tunestr[off] = '\0';
+ }
+
+ /* Enable the glibc.malloc.check tunable in SETUID/SETGID programs only when
+diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
+index 7dfb0e073a..f0b92c97e7 100644
+--- a/elf/tst-env-setuid-tunables.c
++++ b/elf/tst-env-setuid-tunables.c
+@@ -50,6 +50,8 @@ const char *teststrings[] =
+ "glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
+ "glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096",
+ "not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
++ "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096",
++ "glibc.malloc.check=2",
+ "glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2",
+ "glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096",
+ ":glibc.malloc.garbage=2:glibc.malloc.check=1",
+@@ -68,6 +70,8 @@ const char *resultstrings[] =
+ "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.mmap_threshold=4096",
++ "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096",
++ "",
+ "",
+ "",
+ "",
+@@ -81,11 +85,18 @@ test_child (int off)
+ {
+ const char *val = getenv ("GLIBC_TUNABLES");
+
++ printf (" [%d] GLIBC_TUNABLES is %s\n", off, val);
++ fflush (stdout);
+ if (val != NULL && strcmp (val, resultstrings[off]) == 0)
+ return 0;
+
+ if (val != NULL)
+- printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val);
++ printf (" [%d] Unexpected GLIBC_TUNABLES VALUE %s, expected %s\n",
++ off, val, resultstrings[off]);
++ else
++ printf (" [%d] GLIBC_TUNABLES environment variable absent\n", off);
++
++ fflush (stdout);
+
+ return 1;
+ }
+@@ -106,21 +117,26 @@ do_test (int argc, char **argv)
+ if (ret != 0)
+ exit (1);
+
+- exit (EXIT_SUCCESS);
++ /* Special return code to make sure that the child executed all the way
++ through. */
++ exit (42);
+ }
+ else
+ {
+- int ret = 0;
+-
+ /* Spawn tests. */
+ for (int i = 0; i < array_length (teststrings); i++)
+ {
+ char buf[INT_BUFSIZE_BOUND (int)];
+
+- printf ("Spawned test for %s (%d)\n", teststrings[i], i);
++ printf ("[%d] Spawned test for %s\n", i, teststrings[i]);
+ snprintf (buf, sizeof (buf), "%d\n", i);
++ fflush (stdout);
+ if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
+- exit (1);
++ {
++ printf (" [%d] Failed to set GLIBC_TUNABLES: %m", i);
++ support_record_failure ();
++ continue;
++ }
+
+ int status = support_capture_subprogram_self_sgid (buf);
+
+@@ -128,9 +144,14 @@ do_test (int argc, char **argv)
+ if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+ return EXIT_UNSUPPORTED;
+
+- ret |= status;
++ if (WEXITSTATUS (status) != 42)
++ {
++ printf (" [%d] child failed with status %d\n", i,
++ WEXITSTATUS (status));
++ support_record_failure ();
++ }
+ }
+- return ret;
++ return 0;
+ }
+ }
+
+--
+2.33.0
+
diff --git a/0004-x86_64-Fix-build-with-disable-multiarch-BZ-30721.patch b/0004-x86_64-Fix-build-with-disable-multiarch-BZ-30721.patch
new file mode 100644
index 0000000..5eacc8d
--- /dev/null
+++ b/0004-x86_64-Fix-build-with-disable-multiarch-BZ-30721.patch
@@ -0,0 +1,60 @@
+From 6135d50e44233d8c89ca788f78c669941ad09fb9 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Tue, 8 Aug 2023 09:27:54 -0300
+Subject: [PATCH 04/12] x86_64: Fix build with --disable-multiarch (BZ 30721)
+
+With multiarch disabled, the default memmove implementation provides
+the fortify routines for memcpy, mempcpy, and memmove. However, it
+does not provide the internal hidden definitions used when building
+with fortify enabled. The memset has a similar issue.
+
+Checked on x86_64-linux-gnu building with different options:
+default and --disable-multi-arch plus default, --disable-default-pie,
+--enable-fortify-source={2,3}, and --enable-fortify-source={2,3}
+with --disable-default-pie.
+Tested-by: Andreas K. Huettel <dilfridge@gentoo.org>
+Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+(cherry picked from commit 51cb52214fcd72849c640b12f5099ed3ac776181)
+---
+ sysdeps/x86_64/memcpy.S | 2 +-
+ sysdeps/x86_64/memmove.S | 3 +++
+ sysdeps/x86_64/memset.S | 1 +
+ 3 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/sysdeps/x86_64/memcpy.S b/sysdeps/x86_64/memcpy.S
+index d98500a78a..4922cba657 100644
+--- a/sysdeps/x86_64/memcpy.S
++++ b/sysdeps/x86_64/memcpy.S
+@@ -1 +1 @@
+-/* Implemented in memcpy.S. */
++/* Implemented in memmove.S. */
+diff --git a/sysdeps/x86_64/memmove.S b/sysdeps/x86_64/memmove.S
+index f0b84e3b52..c3c08165e1 100644
+--- a/sysdeps/x86_64/memmove.S
++++ b/sysdeps/x86_64/memmove.S
+@@ -46,6 +46,9 @@ weak_alias (__mempcpy, mempcpy)
+
+ #ifndef USE_MULTIARCH
+ libc_hidden_builtin_def (memmove)
++libc_hidden_builtin_def (__memmove_chk)
++libc_hidden_builtin_def (__memcpy_chk)
++libc_hidden_builtin_def (__mempcpy_chk)
+ # if defined SHARED && IS_IN (libc)
+ strong_alias (memmove, __memcpy)
+ libc_hidden_ver (memmove, memcpy)
+diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S
+index 7c99df36db..c6df24e8de 100644
+--- a/sysdeps/x86_64/memset.S
++++ b/sysdeps/x86_64/memset.S
+@@ -32,6 +32,7 @@
+ #include "isa-default-impl.h"
+
+ libc_hidden_builtin_def (memset)
++libc_hidden_builtin_def (__memset_chk)
+
+ #if IS_IN (libc)
+ libc_hidden_def (__wmemset)
+--
+2.33.0
+
diff --git a/0005-AArch64-Add-support-for-MOPS-memcpy-memmove-memset.patch b/0005-AArch64-Add-support-for-MOPS-memcpy-memmove-memset.patch
new file mode 100644
index 0000000..ef0ab27
--- /dev/null
+++ b/0005-AArch64-Add-support-for-MOPS-memcpy-memmove-memset.patch
@@ -0,0 +1,314 @@
+From d8a2b56b4fdf39488eb8a94f8b1064e262708b6f Mon Sep 17 00:00:00 2001
+From: Wilco Dijkstra <wilco.dijkstra@arm.com>
+Date: Tue, 17 Oct 2023 16:54:21 +0100
+Subject: [PATCH 05/26] AArch64: Add support for MOPS memcpy/memmove/memset
+
+Add support for MOPS in cpu_features and INIT_ARCH. Add ifuncs using MOPS for
+memcpy, memmove and memset (use .inst for now so it works with all binutils
+versions without needing complex configure and conditional compilation).
+
+Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+(cherry picked from commit 2bd00179885928fd95fcabfafc50e7b5c6e660d2)
+---
+ sysdeps/aarch64/multiarch/Makefile | 3 ++
+ sysdeps/aarch64/multiarch/ifunc-impl-list.c | 3 ++
+ sysdeps/aarch64/multiarch/init-arch.h | 4 +-
+ sysdeps/aarch64/multiarch/memcpy.c | 4 ++
+ sysdeps/aarch64/multiarch/memcpy_mops.S | 39 +++++++++++++++++++
+ sysdeps/aarch64/multiarch/memmove.c | 4 ++
+ sysdeps/aarch64/multiarch/memmove_mops.S | 39 +++++++++++++++++++
+ sysdeps/aarch64/multiarch/memset.c | 4 ++
+ sysdeps/aarch64/multiarch/memset_mops.S | 38 ++++++++++++++++++
+ .../unix/sysv/linux/aarch64/cpu-features.c | 3 ++
+ .../unix/sysv/linux/aarch64/cpu-features.h | 1 +
+ 11 files changed, 141 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/aarch64/multiarch/memcpy_mops.S
+ create mode 100644 sysdeps/aarch64/multiarch/memmove_mops.S
+ create mode 100644 sysdeps/aarch64/multiarch/memset_mops.S
+
+diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
+index 223777d94e..e6099548b9 100644
+--- a/sysdeps/aarch64/multiarch/Makefile
++++ b/sysdeps/aarch64/multiarch/Makefile
+@@ -5,14 +5,17 @@ sysdep_routines += \
+ memcpy_a64fx \
+ memcpy_falkor \
+ memcpy_generic \
++ memcpy_mops \
+ memcpy_sve \
+ memcpy_thunderx \
+ memcpy_thunderx2 \
++ memmove_mops \
+ memset_a64fx \
+ memset_emag \
+ memset_falkor \
+ memset_generic \
+ memset_kunpeng \
++ memset_mops \
+ strlen_asimd \
+ strlen_mte \
+ # sysdep_routines
+diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+index d274f01fdb..da7f115377 100644
+--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+@@ -41,6 +41,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, memcpy, sve, __memcpy_a64fx)
+ IFUNC_IMPL_ADD (array, i, memcpy, sve, __memcpy_sve)
+ #endif
++ IFUNC_IMPL_ADD (array, i, memcpy, mops, __memcpy_mops)
+ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_generic))
+ IFUNC_IMPL (i, name, memmove,
+ IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_thunderx)
+@@ -50,6 +51,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, memmove, sve, __memmove_a64fx)
+ IFUNC_IMPL_ADD (array, i, memmove, sve, __memmove_sve)
+ #endif
++ IFUNC_IMPL_ADD (array, i, memmove, mops, __memmove_mops)
+ IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_generic))
+ IFUNC_IMPL (i, name, memset,
+ /* Enable this on non-falkor processors too so that other cores
+@@ -60,6 +62,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ #if HAVE_AARCH64_SVE_ASM
+ IFUNC_IMPL_ADD (array, i, memset, sve && zva_size == 256, __memset_a64fx)
+ #endif
++ IFUNC_IMPL_ADD (array, i, memset, mops, __memset_mops)
+ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_generic))
+ IFUNC_IMPL (i, name, memchr,
+ IFUNC_IMPL_ADD (array, i, memchr, !mte, __memchr_nosimd)
+diff --git a/sysdeps/aarch64/multiarch/init-arch.h b/sysdeps/aarch64/multiarch/init-arch.h
+index 6de081e381..e23e6ff290 100644
+--- a/sysdeps/aarch64/multiarch/init-arch.h
++++ b/sysdeps/aarch64/multiarch/init-arch.h
+@@ -35,4 +35,6 @@
+ bool __attribute__((unused)) mte = \
+ MTE_ENABLED (); \
+ bool __attribute__((unused)) sve = \
+- GLRO(dl_aarch64_cpu_features).sve;
++ GLRO(dl_aarch64_cpu_features).sve; \
++ bool __attribute__((unused)) mops = \
++ GLRO(dl_aarch64_cpu_features).mops;
+diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
+index 3aae915c5f..9aace954cb 100644
+--- a/sysdeps/aarch64/multiarch/memcpy.c
++++ b/sysdeps/aarch64/multiarch/memcpy.c
+@@ -34,12 +34,16 @@ extern __typeof (__redirect_memcpy) __memcpy_thunderx2 attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_falkor attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_a64fx attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_sve attribute_hidden;
++extern __typeof (__redirect_memcpy) __memcpy_mops attribute_hidden;
+
+ static inline __typeof (__redirect_memcpy) *
+ select_memcpy_ifunc (void)
+ {
+ INIT_ARCH ();
+
++ if (mops)
++ return __memcpy_mops;
++
+ if (sve && HAVE_AARCH64_SVE_ASM)
+ {
+ if (IS_A64FX (midr))
+diff --git a/sysdeps/aarch64/multiarch/memcpy_mops.S b/sysdeps/aarch64/multiarch/memcpy_mops.S
+new file mode 100644
+index 0000000000..4685629664
+--- /dev/null
++++ b/sysdeps/aarch64/multiarch/memcpy_mops.S
+@@ -0,0 +1,39 @@
++/* Optimized memcpy for MOPS.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++
++/* Assumptions:
++ *
++ * AArch64, MOPS.
++ *
++ */
++
++ENTRY (__memcpy_mops)
++ PTR_ARG (0)
++ PTR_ARG (1)
++ SIZE_ARG (2)
++
++ mov x3, x0
++ .inst 0x19010443 /* cpyfp [x3]!, [x1]!, x2! */
++ .inst 0x19410443 /* cpyfm [x3]!, [x1]!, x2! */
++ .inst 0x19810443 /* cpyfe [x3]!, [x1]!, x2! */
++ ret
++
++END (__memcpy_mops)
+diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
+index 312f90f111..fd346e7b73 100644
+--- a/sysdeps/aarch64/multiarch/memmove.c
++++ b/sysdeps/aarch64/multiarch/memmove.c
+@@ -34,12 +34,16 @@ extern __typeof (__redirect_memmove) __memmove_thunderx2 attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_falkor attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_a64fx attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_sve attribute_hidden;
++extern __typeof (__redirect_memmove) __memmove_mops attribute_hidden;
+
+ static inline __typeof (__redirect_memmove) *
+ select_memmove_ifunc (void)
+ {
+ INIT_ARCH ();
+
++ if (mops)
++ return __memmove_mops;
++
+ if (sve && HAVE_AARCH64_SVE_ASM)
+ {
+ if (IS_A64FX (midr))
+diff --git a/sysdeps/aarch64/multiarch/memmove_mops.S b/sysdeps/aarch64/multiarch/memmove_mops.S
+new file mode 100644
+index 0000000000..c5ea66be3a
+--- /dev/null
++++ b/sysdeps/aarch64/multiarch/memmove_mops.S
+@@ -0,0 +1,39 @@
++/* Optimized memmove for MOPS.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++
++/* Assumptions:
++ *
++ * AArch64, MOPS.
++ *
++ */
++
++ENTRY (__memmove_mops)
++ PTR_ARG (0)
++ PTR_ARG (1)
++ SIZE_ARG (2)
++
++ mov x3, x0
++ .inst 0x1d010443 /* cpyp [x3]!, [x1]!, x2! */
++ .inst 0x1d410443 /* cpym [x3]!, [x1]!, x2! */
++ .inst 0x1d810443 /* cpye [x3]!, [x1]!, x2! */
++ ret
++
++END (__memmove_mops)
+diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c
+index f9c81d3d8e..23fc66e158 100644
+--- a/sysdeps/aarch64/multiarch/memset.c
++++ b/sysdeps/aarch64/multiarch/memset.c
+@@ -33,12 +33,16 @@ extern __typeof (__redirect_memset) __memset_emag attribute_hidden;
+ extern __typeof (__redirect_memset) __memset_kunpeng attribute_hidden;
+ extern __typeof (__redirect_memset) __memset_a64fx attribute_hidden;
+ extern __typeof (__redirect_memset) __memset_generic attribute_hidden;
++extern __typeof (__redirect_memset) __memset_mops attribute_hidden;
+
+ static inline __typeof (__redirect_memset) *
+ select_memset_ifunc (void)
+ {
+ INIT_ARCH ();
+
++ if (mops)
++ return __memset_mops;
++
+ if (sve && HAVE_AARCH64_SVE_ASM)
+ {
+ if (IS_A64FX (midr) && zva_size == 256)
+diff --git a/sysdeps/aarch64/multiarch/memset_mops.S b/sysdeps/aarch64/multiarch/memset_mops.S
+new file mode 100644
+index 0000000000..ca820b8636
+--- /dev/null
++++ b/sysdeps/aarch64/multiarch/memset_mops.S
+@@ -0,0 +1,38 @@
++/* Optimized memset for MOPS.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++
++/* Assumptions:
++ *
++ * AArch64, MOPS.
++ *
++ */
++
++ENTRY (__memset_mops)
++ PTR_ARG (0)
++ SIZE_ARG (2)
++
++ mov x3, x0
++ .inst 0x19c10443 /* setp [x3]!, x2!, x1 */
++ .inst 0x19c14443 /* setm [x3]!, x2!, x1 */
++ .inst 0x19c18443 /* sete [x3]!, x2!, x1 */
++ ret
++
++END (__memset_mops)
+diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+index dc09c1c827..233d5b2407 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+@@ -120,4 +120,7 @@ init_cpu_features (struct cpu_features *cpu_features)
+
+ /* Check if SVE is supported. */
+ cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE;
++
++ /* Check if MOPS is supported. */
++ cpu_features->mops = GLRO (dl_hwcap2) & HWCAP2_MOPS;
+ }
+diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+index d67d286b53..40b709677d 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+@@ -76,6 +76,7 @@ struct cpu_features
+ /* Currently, the GLIBC memory tagging tunable only defines 8 bits. */
+ uint8_t mte_state;
+ bool sve;
++ bool mops;
+ };
+
+ #endif /* _CPU_FEATURES_AARCH64_H */
+--
+2.33.0
+
diff --git a/0005-NEWS-Add-the-2.38.1-bug-list.patch b/0005-NEWS-Add-the-2.38.1-bug-list.patch
new file mode 100644
index 0000000..bb59835
--- /dev/null
+++ b/0005-NEWS-Add-the-2.38.1-bug-list.patch
@@ -0,0 +1,37 @@
+From 89da8bc588c2296252543b049bf6d9272321f90d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 11 Sep 2023 10:06:15 +0200
+Subject: [PATCH 5/5] NEWS: Add the 2.38.1 bug list
+
+---
+ NEWS | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index f1a14f45dd..64596d5d09 100644
+--- a/NEWS
++++ b/NEWS
+@@ -9,7 +9,10 @@ Version 2.38.1
+
+ The following bugs are resolved with this release:
+
++ [30723] posix_memalign repeatedly scans long bin lists
+ [30785] Always call destructors in reverse constructor order
++ [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
++ -D_FILE_OFFSET_BITS=64
+
+
+ Version 2.38
+@@ -139,9 +142,6 @@ The following bugs are resolved with this release:
+ [30555] string: strerror can incorrectly return NULL
+ [30579] malloc: trim_threshold in realloc lead to high memory usage
+ [30662] nscd: Group and password cache use errno in place of errval
+- [30723] posix_memalign repeatedly scans long bin lists
+- [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+- -D_FILE_OFFSET_BITS=64
+
+ Version 2.37
+
+--
+2.33.0
+
diff --git a/0005-i686-Fix-build-with-disable-multiarch.patch b/0005-i686-Fix-build-with-disable-multiarch.patch
new file mode 100644
index 0000000..a2b7349
--- /dev/null
+++ b/0005-i686-Fix-build-with-disable-multiarch.patch
@@ -0,0 +1,100 @@
+From 7ac405a74c6069b0627dc2d8449a82a621f8ff06 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Tue, 8 Aug 2023 09:27:55 -0300
+Subject: [PATCH 05/12] i686: Fix build with --disable-multiarch
+
+Since i686 provides the fortified wrappers for memcpy, mempcpy,
+memmove, and memset on the same string implementation, the static
+build tries to optimized it by not tying the fortified wrappers
+to string routine (to avoid pulling the fortify function if
+they are not required).
+
+Checked on i686-linux-gnu building with different option:
+default and --disable-multi-arch plus default, --disable-default-pie,
+--enable-fortify-source={2,3}, and --enable-fortify-source={2,3}
+with --disable-default-pie.
+Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+(cherry picked from commit c73c96a4a1af1326df7f96eec58209e1e04066d8)
+---
+ sysdeps/i386/i686/memcpy.S | 2 +-
+ sysdeps/i386/i686/mempcpy.S | 2 +-
+ sysdeps/i386/i686/multiarch/memcpy_chk.c | 2 ++
+ sysdeps/i386/i686/multiarch/memmove_chk.c | 2 ++
+ sysdeps/i386/i686/multiarch/mempcpy_chk.c | 2 ++
+ sysdeps/i386/i686/multiarch/memset_chk.c | 2 ++
+ 6 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/sysdeps/i386/i686/memcpy.S b/sysdeps/i386/i686/memcpy.S
+index 9b48ec0ea1..b86af4aac9 100644
+--- a/sysdeps/i386/i686/memcpy.S
++++ b/sysdeps/i386/i686/memcpy.S
+@@ -27,7 +27,7 @@
+ #define LEN SRC+4
+
+ .text
+-#if defined PIC && IS_IN (libc)
++#if defined SHARED && IS_IN (libc)
+ ENTRY_CHK (__memcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+diff --git a/sysdeps/i386/i686/mempcpy.S b/sysdeps/i386/i686/mempcpy.S
+index 26f8501e7d..14d9dd681a 100644
+--- a/sysdeps/i386/i686/mempcpy.S
++++ b/sysdeps/i386/i686/mempcpy.S
+@@ -27,7 +27,7 @@
+ #define LEN SRC+4
+
+ .text
+-#if defined PIC && IS_IN (libc)
++#if defined SHARED && IS_IN (libc)
+ ENTRY_CHK (__mempcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+diff --git a/sysdeps/i386/i686/multiarch/memcpy_chk.c b/sysdeps/i386/i686/multiarch/memcpy_chk.c
+index ec945dc91f..c3a8aeaf18 100644
+--- a/sysdeps/i386/i686/multiarch/memcpy_chk.c
++++ b/sysdeps/i386/i686/multiarch/memcpy_chk.c
+@@ -32,4 +32,6 @@ libc_ifunc_redirected (__redirect_memcpy_chk, __memcpy_chk,
+ __hidden_ver1 (__memcpy_chk, __GI___memcpy_chk, __redirect_memcpy_chk)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (__memcpy_chk);
+ # endif
++#else
++# include <debug/memcpy_chk.c>
+ #endif
+diff --git a/sysdeps/i386/i686/multiarch/memmove_chk.c b/sysdeps/i386/i686/multiarch/memmove_chk.c
+index 55c7601d5d..070dde083a 100644
+--- a/sysdeps/i386/i686/multiarch/memmove_chk.c
++++ b/sysdeps/i386/i686/multiarch/memmove_chk.c
+@@ -32,4 +32,6 @@ libc_ifunc_redirected (__redirect_memmove_chk, __memmove_chk,
+ __hidden_ver1 (__memmove_chk, __GI___memmove_chk, __redirect_memmove_chk)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (__memmove_chk);
+ # endif
++#else
++# include <debug/memmove_chk.c>
+ #endif
+diff --git a/sysdeps/i386/i686/multiarch/mempcpy_chk.c b/sysdeps/i386/i686/multiarch/mempcpy_chk.c
+index 83569cf9d9..14360f1828 100644
+--- a/sysdeps/i386/i686/multiarch/mempcpy_chk.c
++++ b/sysdeps/i386/i686/multiarch/mempcpy_chk.c
+@@ -32,4 +32,6 @@ libc_ifunc_redirected (__redirect_mempcpy_chk, __mempcpy_chk,
+ __hidden_ver1 (__mempcpy_chk, __GI___mempcpy_chk, __redirect_mempcpy_chk)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (__mempcpy_chk);
+ # endif
++#else
++# include <debug/mempcpy_chk.c>
+ #endif
+diff --git a/sysdeps/i386/i686/multiarch/memset_chk.c b/sysdeps/i386/i686/multiarch/memset_chk.c
+index 1a7503858d..8179ef7c0b 100644
+--- a/sysdeps/i386/i686/multiarch/memset_chk.c
++++ b/sysdeps/i386/i686/multiarch/memset_chk.c
+@@ -32,4 +32,6 @@ libc_ifunc_redirected (__redirect_memset_chk, __memset_chk,
+ __hidden_ver1 (__memset_chk, __GI___memset_chk, __redirect_memset_chk)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (__memset_chk);
+ # endif
++#else
++# include <debug/memset_chk.c>
+ #endif
+--
+2.33.0
+
diff --git a/0005-resolv-Allow-short-error-responses-to-match-any-quer.patch b/0005-resolv-Allow-short-error-responses-to-match-any-quer.patch
new file mode 100644
index 0000000..811a328
--- /dev/null
+++ b/0005-resolv-Allow-short-error-responses-to-match-any-quer.patch
@@ -0,0 +1,223 @@
+From dc512364e8490facb30f8c23fcc496d21adfc4e4 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 24 Jul 2024 12:06:47 +0200
+Subject: [PATCH 05/12] resolv: Allow short error responses to match any query
+ (bug 31890)
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit 691a3b2e9bfaba842e46a5ccb7f5e6ea144c3ade)
+---
+ NEWS | 1 +
+ resolv/Makefile | 3 +
+ resolv/res_send.c | 29 +++++---
+ resolv/tst-resolv-short-response.c | 112 +++++++++++++++++++++++++++++
+ 4 files changed, 135 insertions(+), 10 deletions(-)
+ create mode 100644 resolv/tst-resolv-short-response.c
+
+diff --git a/NEWS b/NEWS
+index f0a0834496..c331604747 100644
+--- a/NEWS
++++ b/NEWS
+@@ -51,6 +51,7 @@ The following bugs are resolved with this release:
+ [31183] Wide stream buffer size reduced MB_LEN_MAX bytes after bug 17522 fix
+ [31184] FAIL: elf/tst-tlsgap
+ [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
++ [31890] resolv: Allow short error responses to match any DNS query
+ [31965] rseq extension mechanism does not work as intended
+
+
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 2f99eb3862..cca0748f9a 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -106,6 +106,7 @@ tests += \
+ tst-resolv-nondecimal \
+ tst-resolv-res_init-multi \
+ tst-resolv-search \
++ tst-resolv-short-response \
+ tst-resolv-trailing \
+
+ # This test calls __res_context_send directly, which is not exported
+@@ -299,6 +300,8 @@ $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
++$(objpfx)tst-resolv-short-response: $(objpfx)libresolv.so \
++ $(shared-thread-library)
+ $(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-threads: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-txnid-collision: $(objpfx)libresolv.a \
+diff --git a/resolv/res_send.c b/resolv/res_send.c
+index d098eba470..bf4ce67b1d 100644
+--- a/resolv/res_send.c
++++ b/resolv/res_send.c
+@@ -1197,19 +1197,30 @@ send_dg(res_state statp,
+ }
+
+ /* Check for the correct header layout and a matching
+- question. */
++ question. Some recursive resolvers send REFUSED
++ without copying back the question section
++ (producing a response that is only HFIXEDSZ bytes
++ long). Skip query matching in this case. */
++ bool thisansp_error = (anhp->rcode == SERVFAIL ||
++ anhp->rcode == NOTIMP ||
++ anhp->rcode == REFUSED);
++ bool skip_query_match = (*thisresplenp == HFIXEDSZ
++ && ntohs (anhp->qdcount) == 0
++ && thisansp_error);
+ int matching_query = 0; /* Default to no matching query. */
+ if (!recvresp1
+ && anhp->id == hp->id
+- && __libc_res_queriesmatch (buf, buf + buflen,
+- *thisansp,
+- *thisansp + *thisanssizp))
++ && (skip_query_match
++ || __libc_res_queriesmatch (buf, buf + buflen,
++ *thisansp,
++ *thisansp + *thisanssizp)))
+ matching_query = 1;
+ if (!recvresp2
+ && anhp->id == hp2->id
+- && __libc_res_queriesmatch (buf2, buf2 + buflen2,
+- *thisansp,
+- *thisansp + *thisanssizp))
++ && (skip_query_match
++ || __libc_res_queriesmatch (buf2, buf2 + buflen2,
++ *thisansp,
++ *thisansp + *thisanssizp)))
+ matching_query = 2;
+ if (matching_query == 0)
+ /* Spurious UDP packet. Drop it and continue
+@@ -1219,9 +1230,7 @@ send_dg(res_state statp,
+ goto wait;
+ }
+
+- if (anhp->rcode == SERVFAIL ||
+- anhp->rcode == NOTIMP ||
+- anhp->rcode == REFUSED) {
++ if (thisansp_error) {
+ next_ns:
+ if (recvresp1 || (buf2 != NULL && recvresp2)) {
+ *resplen2 = 0;
+diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c
+new file mode 100644
+index 0000000000..cf1e39876f
+--- /dev/null
++++ b/resolv/tst-resolv-short-response.c
+@@ -0,0 +1,112 @@
++/* Test for spurious timeouts with short 12-byte responses (bug 31890).
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <resolv.h>
++#include <support/check.h>
++#include <support/resolv_test.h>
++#include <support/check_nss.h>
++
++/* The rcode in the initial response. */
++static volatile int rcode;
++
++static void
++response (const struct resolv_response_context *ctx,
++ struct resolv_response_builder *b,
++ const char *qname, uint16_t qclass, uint16_t qtype)
++{
++ switch (ctx->server_index)
++ {
++ case 0:
++ /* First server times out. */
++ struct resolv_response_flags flags = {.rcode = rcode};
++ resolv_response_init (b, flags);
++ break;
++ case 1:
++ /* Second server sends reply. */
++ resolv_response_init (b, (struct resolv_response_flags) {});
++ resolv_response_add_question (b, qname, qclass, qtype);
++ resolv_response_section (b, ns_s_an);
++ resolv_response_open_record (b, qname, qclass, qtype, 0);
++ switch (qtype)
++ {
++ case T_A:
++ {
++ char ipv4[4] = {192, 0, 2, 17};
++ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
++ }
++ break;
++ case T_AAAA:
++ {
++ char ipv6[16]
++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
++ resolv_response_add_data (b, &ipv6, sizeof (ipv6));
++ }
++ break;
++ default:
++ FAIL_EXIT1 ("unexpected TYPE%d query", qtype);
++ }
++ resolv_response_close_record (b);
++ break;
++ default:
++ FAIL_EXIT1 ("unexpected query to server %d", ctx->server_index);
++ }
++}
++
++static void
++check_one (void)
++{
++
++ /* The buggy 1-second query timeout results in 30 seconds of delay,
++ which triggers a test timeout failure. */
++ for (int i = 0; i < 10; ++i)
++ {
++ check_hostent ("www.example", gethostbyname ("www.example"),
++ "name: www.example\n"
++ "address: 192.0.2.17\n");
++ check_hostent ("www.example", gethostbyname2 ("www.example", AF_INET6),
++ "name: www.example\n"
++ "address: 2001:db8::1\n");
++ }
++}
++
++static int
++do_test (void)
++{
++ struct resolv_test *aux = resolv_test_start
++ ((struct resolv_redirect_config)
++ {
++ .response_callback = response,
++ });
++
++ _res.options |= RES_SNGLKUP;
++
++ rcode = 2; /* SERVFAIL. */
++ check_one ();
++
++ rcode = 4; /* NOTIMP. */
++ check_one ();
++
++ rcode = 5; /* REFUSED. */
++ check_one ();
++
++ resolv_test_end (aux);
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.33.0
+
diff --git a/0006-AArch64-Cleanup-ifuncs.patch b/0006-AArch64-Cleanup-ifuncs.patch
new file mode 100644
index 0000000..c1ce54b
--- /dev/null
+++ b/0006-AArch64-Cleanup-ifuncs.patch
@@ -0,0 +1,540 @@
+From 25b66e8c4a75b51b0122089cf6b99860fb05470d Mon Sep 17 00:00:00 2001
+From: Wilco Dijkstra <wilco.dijkstra@arm.com>
+Date: Tue, 24 Oct 2023 13:51:07 +0100
+Subject: [PATCH 06/26] AArch64: Cleanup ifuncs
+
+Cleanup ifuncs. Remove uses of libc_hidden_builtin_def, use ENTRY rather than
+ENTRY_ALIGN, remove unnecessary defines and conditional compilation. Rename
+strlen_mte to strlen_generic. Remove rtld-memset.
+
+Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+(cherry picked from commit 9fd3409842b3e2d31cff5dbd6f96066c430f0aa2)
+---
+ sysdeps/aarch64/memset.S | 2 +-
+ sysdeps/aarch64/multiarch/Makefile | 2 +-
+ sysdeps/aarch64/multiarch/ifunc-impl-list.c | 2 +-
+ sysdeps/aarch64/multiarch/memchr_nosimd.S | 9 ++----
+ sysdeps/aarch64/multiarch/memcpy_a64fx.S | 14 +++-------
+ sysdeps/aarch64/multiarch/memcpy_falkor.S | 6 ++--
+ sysdeps/aarch64/multiarch/memcpy_sve.S | 2 --
+ sysdeps/aarch64/multiarch/memcpy_thunderx.S | 27 ++++--------------
+ sysdeps/aarch64/multiarch/memcpy_thunderx2.S | 28 +++----------------
+ sysdeps/aarch64/multiarch/memset_a64fx.S | 8 ++----
+ sysdeps/aarch64/multiarch/memset_base64.S | 3 +-
+ sysdeps/aarch64/multiarch/memset_emag.S | 8 ++----
+ sysdeps/aarch64/multiarch/memset_generic.S | 8 +++++-
+ sysdeps/aarch64/multiarch/memset_kunpeng.S | 9 ++----
+ sysdeps/aarch64/multiarch/rtld-memset.S | 25 -----------------
+ sysdeps/aarch64/multiarch/strlen.c | 4 +--
+ sysdeps/aarch64/multiarch/strlen_asimd.S | 1 -
+ .../{strlen_mte.S => strlen_generic.S} | 8 +++---
+ 18 files changed, 41 insertions(+), 125 deletions(-)
+ delete mode 100644 sysdeps/aarch64/multiarch/rtld-memset.S
+ rename sysdeps/aarch64/multiarch/{strlen_mte.S => strlen_generic.S} (85%)
+
+diff --git a/sysdeps/aarch64/memset.S b/sysdeps/aarch64/memset.S
+index 50e5da3e7a..bf3cf85c8a 100644
+--- a/sysdeps/aarch64/memset.S
++++ b/sysdeps/aarch64/memset.S
+@@ -29,7 +29,7 @@
+ *
+ */
+
+-ENTRY_ALIGN (MEMSET, 6)
++ENTRY (MEMSET)
+
+ PTR_ARG (0)
+ SIZE_ARG (2)
+diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
+index e6099548b9..a1a4de3cd9 100644
+--- a/sysdeps/aarch64/multiarch/Makefile
++++ b/sysdeps/aarch64/multiarch/Makefile
+@@ -17,6 +17,6 @@ sysdep_routines += \
+ memset_kunpeng \
+ memset_mops \
+ strlen_asimd \
+- strlen_mte \
++ strlen_generic \
+ # sysdep_routines
+ endif
+diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+index da7f115377..836e8317a5 100644
+--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+@@ -70,7 +70,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+
+ IFUNC_IMPL (i, name, strlen,
+ IFUNC_IMPL_ADD (array, i, strlen, !mte, __strlen_asimd)
+- IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_mte))
++ IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_generic))
+
+ return 0;
+ }
+diff --git a/sysdeps/aarch64/multiarch/memchr_nosimd.S b/sysdeps/aarch64/multiarch/memchr_nosimd.S
+index 57e48375e9..7800751899 100644
+--- a/sysdeps/aarch64/multiarch/memchr_nosimd.S
++++ b/sysdeps/aarch64/multiarch/memchr_nosimd.S
+@@ -26,10 +26,6 @@
+ * Use base integer registers.
+ */
+
+-#ifndef MEMCHR
+-# define MEMCHR __memchr_nosimd
+-#endif
+-
+ /* Arguments and results. */
+ #define srcin x0
+ #define chrin x1
+@@ -62,7 +58,7 @@
+ #define REP8_7f 0x7f7f7f7f7f7f7f7f
+
+
+-ENTRY_ALIGN (MEMCHR, 6)
++ENTRY (__memchr_nosimd)
+
+ PTR_ARG (0)
+ SIZE_ARG (2)
+@@ -219,5 +215,4 @@ L(none_chr):
+ mov result, 0
+ ret
+
+-END (MEMCHR)
+-libc_hidden_builtin_def (MEMCHR)
++END (__memchr_nosimd)
+diff --git a/sysdeps/aarch64/multiarch/memcpy_a64fx.S b/sysdeps/aarch64/multiarch/memcpy_a64fx.S
+index f89b5b670a..baff7e96d0 100644
+--- a/sysdeps/aarch64/multiarch/memcpy_a64fx.S
++++ b/sysdeps/aarch64/multiarch/memcpy_a64fx.S
+@@ -39,9 +39,6 @@
+ #define vlen8 x8
+
+ #if HAVE_AARCH64_SVE_ASM
+-# if IS_IN (libc)
+-# define MEMCPY __memcpy_a64fx
+-# define MEMMOVE __memmove_a64fx
+
+ .arch armv8.2-a+sve
+
+@@ -97,7 +94,7 @@
+ #undef BTI_C
+ #define BTI_C
+
+-ENTRY (MEMCPY)
++ENTRY (__memcpy_a64fx)
+
+ PTR_ARG (0)
+ PTR_ARG (1)
+@@ -234,11 +231,10 @@ L(last_bytes):
+ st1b z3.b, p0, [dstend, -1, mul vl]
+ ret
+
+-END (MEMCPY)
+-libc_hidden_builtin_def (MEMCPY)
++END (__memcpy_a64fx)
+
+
+-ENTRY_ALIGN (MEMMOVE, 4)
++ENTRY_ALIGN (__memmove_a64fx, 4)
+
+ PTR_ARG (0)
+ PTR_ARG (1)
+@@ -307,7 +303,5 @@ L(full_overlap):
+ mov dst, dstin
+ b L(last_bytes)
+
+-END (MEMMOVE)
+-libc_hidden_builtin_def (MEMMOVE)
+-# endif /* IS_IN (libc) */
++END (__memmove_a64fx)
+ #endif /* HAVE_AARCH64_SVE_ASM */
+diff --git a/sysdeps/aarch64/multiarch/memcpy_falkor.S b/sysdeps/aarch64/multiarch/memcpy_falkor.S
+index ec0e4ade24..67c4ab34eb 100644
+--- a/sysdeps/aarch64/multiarch/memcpy_falkor.S
++++ b/sysdeps/aarch64/multiarch/memcpy_falkor.S
+@@ -71,7 +71,7 @@
+ The non-temporal stores help optimize cache utilization. */
+
+ #if IS_IN (libc)
+-ENTRY_ALIGN (__memcpy_falkor, 6)
++ENTRY (__memcpy_falkor)
+
+ PTR_ARG (0)
+ PTR_ARG (1)
+@@ -198,7 +198,6 @@ L(loop64):
+ ret
+
+ END (__memcpy_falkor)
+-libc_hidden_builtin_def (__memcpy_falkor)
+
+
+ /* RATIONALE:
+@@ -216,7 +215,7 @@ libc_hidden_builtin_def (__memcpy_falkor)
+
+ For small and medium cases memcpy is used. */
+
+-ENTRY_ALIGN (__memmove_falkor, 6)
++ENTRY (__memmove_falkor)
+
+ PTR_ARG (0)
+ PTR_ARG (1)
+@@ -311,5 +310,4 @@ L(move_long):
+ 3: ret
+
+ END (__memmove_falkor)
+-libc_hidden_builtin_def (__memmove_falkor)
+ #endif
+diff --git a/sysdeps/aarch64/multiarch/memcpy_sve.S b/sysdeps/aarch64/multiarch/memcpy_sve.S
+index d11be6a443..2f14f91366 100644
+--- a/sysdeps/aarch64/multiarch/memcpy_sve.S
++++ b/sysdeps/aarch64/multiarch/memcpy_sve.S
+@@ -141,7 +141,6 @@ L(copy64_from_end):
+ ret
+
+ END (__memcpy_sve)
+-libc_hidden_builtin_def (__memcpy_sve)
+
+
+ ENTRY (__memmove_sve)
+@@ -208,5 +207,4 @@ L(return):
+ ret
+
+ END (__memmove_sve)
+-libc_hidden_builtin_def (__memmove_sve)
+ #endif
+diff --git a/sysdeps/aarch64/multiarch/memcpy_thunderx.S b/sysdeps/aarch64/multiarch/memcpy_thunderx.S
+index 366287587f..14269b1a47 100644
+--- a/sysdeps/aarch64/multiarch/memcpy_thunderx.S
++++ b/sysdeps/aarch64/multiarch/memcpy_thunderx.S
+@@ -65,21 +65,7 @@
+ Overlapping large forward memmoves use a loop that copies backwards.
+ */
+
+-#ifndef MEMMOVE
+-# define MEMMOVE memmove
+-#endif
+-#ifndef MEMCPY
+-# define MEMCPY memcpy
+-#endif
+-
+-#if IS_IN (libc)
+-
+-# undef MEMCPY
+-# define MEMCPY __memcpy_thunderx
+-# undef MEMMOVE
+-# define MEMMOVE __memmove_thunderx
+-
+-ENTRY_ALIGN (MEMMOVE, 6)
++ENTRY (__memmove_thunderx)
+
+ PTR_ARG (0)
+ PTR_ARG (1)
+@@ -91,9 +77,9 @@ ENTRY_ALIGN (MEMMOVE, 6)
+ b.lo L(move_long)
+
+ /* Common case falls through into memcpy. */
+-END (MEMMOVE)
+-libc_hidden_builtin_def (MEMMOVE)
+-ENTRY (MEMCPY)
++END (__memmove_thunderx)
++
++ENTRY (__memcpy_thunderx)
+
+ PTR_ARG (0)
+ PTR_ARG (1)
+@@ -316,7 +302,4 @@ L(move_long):
+ stp C_l, C_h, [dstin]
+ 3: ret
+
+-END (MEMCPY)
+-libc_hidden_builtin_def (MEMCPY)
+-
+-#endif
++END (__memcpy_thunderx)
+diff --git a/sysdeps/aarch64/multiarch/memcpy_thunderx2.S b/sysdeps/aarch64/multiarch/memcpy_thunderx2.S
+index d3d6f1debc..93993b9e03 100644
+--- a/sysdeps/aarch64/multiarch/memcpy_thunderx2.S
++++ b/sysdeps/aarch64/multiarch/memcpy_thunderx2.S
+@@ -75,27 +75,12 @@
+ #define I_v v16
+ #define J_v v17
+
+-#ifndef MEMMOVE
+-# define MEMMOVE memmove
+-#endif
+-#ifndef MEMCPY
+-# define MEMCPY memcpy
+-#endif
+-
+-#if IS_IN (libc)
+-
+-#undef MEMCPY
+-#define MEMCPY __memcpy_thunderx2
+-#undef MEMMOVE
+-#define MEMMOVE __memmove_thunderx2
+-
+-
+ /* Overlapping large forward memmoves use a loop that copies backwards.
+ Otherwise memcpy is used. Small moves branch to memcopy16 directly.
+ The longer memcpy cases fall through to the memcpy head.
+ */
+
+-ENTRY_ALIGN (MEMMOVE, 6)
++ENTRY (__memmove_thunderx2)
+
+ PTR_ARG (0)
+ PTR_ARG (1)
+@@ -109,8 +94,7 @@ ENTRY_ALIGN (MEMMOVE, 6)
+ ccmp tmp1, count, 2, hi
+ b.lo L(move_long)
+
+-END (MEMMOVE)
+-libc_hidden_builtin_def (MEMMOVE)
++END (__memmove_thunderx2)
+
+
+ /* Copies are split into 3 main cases: small copies of up to 16 bytes,
+@@ -124,8 +108,7 @@ libc_hidden_builtin_def (MEMMOVE)
+
+ #define MEMCPY_PREFETCH_LDR 640
+
+- .p2align 4
+-ENTRY (MEMCPY)
++ENTRY (__memcpy_thunderx2)
+
+ PTR_ARG (0)
+ PTR_ARG (1)
+@@ -449,7 +432,7 @@ L(move_long):
+ 3: ret
+
+
+-END (MEMCPY)
++END (__memcpy_thunderx2)
+ .section .rodata
+ .p2align 4
+
+@@ -472,6 +455,3 @@ L(ext_table):
+ .word L(ext_size_13) -.
+ .word L(ext_size_14) -.
+ .word L(ext_size_15) -.
+-
+-libc_hidden_builtin_def (MEMCPY)
+-#endif
+diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S
+index d520355143..7176f3d284 100644
+--- a/sysdeps/aarch64/multiarch/memset_a64fx.S
++++ b/sysdeps/aarch64/multiarch/memset_a64fx.S
+@@ -33,8 +33,6 @@
+ #define vector_length x9
+
+ #if HAVE_AARCH64_SVE_ASM
+-# if IS_IN (libc)
+-# define MEMSET __memset_a64fx
+
+ .arch armv8.2-a+sve
+
+@@ -49,7 +47,7 @@
+ #undef BTI_C
+ #define BTI_C
+
+-ENTRY (MEMSET)
++ENTRY (__memset_a64fx)
+ PTR_ARG (0)
+ SIZE_ARG (2)
+
+@@ -166,8 +164,6 @@ L(L2):
+ add count, count, CACHE_LINE_SIZE
+ b L(last)
+
+-END (MEMSET)
+-libc_hidden_builtin_def (MEMSET)
++END (__memset_a64fx)
+
+-#endif /* IS_IN (libc) */
+ #endif /* HAVE_AARCH64_SVE_ASM */
+diff --git a/sysdeps/aarch64/multiarch/memset_base64.S b/sysdeps/aarch64/multiarch/memset_base64.S
+index 35296a6dec..0e8f709fa5 100644
+--- a/sysdeps/aarch64/multiarch/memset_base64.S
++++ b/sysdeps/aarch64/multiarch/memset_base64.S
+@@ -34,7 +34,7 @@
+ *
+ */
+
+-ENTRY_ALIGN (MEMSET, 6)
++ENTRY (MEMSET)
+
+ PTR_ARG (0)
+ SIZE_ARG (2)
+@@ -183,4 +183,3 @@ L(zva_64):
+ #endif
+
+ END (MEMSET)
+-libc_hidden_builtin_def (MEMSET)
+diff --git a/sysdeps/aarch64/multiarch/memset_emag.S b/sysdeps/aarch64/multiarch/memset_emag.S
+index 17d609cead..6fecad4fae 100644
+--- a/sysdeps/aarch64/multiarch/memset_emag.S
++++ b/sysdeps/aarch64/multiarch/memset_emag.S
+@@ -19,8 +19,7 @@
+
+ #include <sysdep.h>
+
+-#if IS_IN (libc)
+-# define MEMSET __memset_emag
++#define MEMSET __memset_emag
+
+ /*
+ * Using DC ZVA to zero memory does not produce better performance if
+@@ -30,7 +29,6 @@
+ * workloads.
+ */
+
+-# define DC_ZVA_THRESHOLD 0
++#define DC_ZVA_THRESHOLD 0
+
+-# include "./memset_base64.S"
+-#endif
++#include "./memset_base64.S"
+diff --git a/sysdeps/aarch64/multiarch/memset_generic.S b/sysdeps/aarch64/multiarch/memset_generic.S
+index 9c23e482bf..6c1f0daac8 100644
+--- a/sysdeps/aarch64/multiarch/memset_generic.S
++++ b/sysdeps/aarch64/multiarch/memset_generic.S
+@@ -21,9 +21,15 @@
+
+ #if IS_IN (libc)
+ # define MEMSET __memset_generic
++
++/* Do not hide the generic version of memset, we use it internally. */
++# undef libc_hidden_builtin_def
++# define libc_hidden_builtin_def(name)
++
+ /* Add a hidden definition for use within libc.so. */
+ # ifdef SHARED
+ .globl __GI_memset; __GI_memset = __memset_generic
+ # endif
+-# include <sysdeps/aarch64/memset.S>
+ #endif
++
++#include <../memset.S>
+diff --git a/sysdeps/aarch64/multiarch/memset_kunpeng.S b/sysdeps/aarch64/multiarch/memset_kunpeng.S
+index 86c46434fd..4a54373398 100644
+--- a/sysdeps/aarch64/multiarch/memset_kunpeng.S
++++ b/sysdeps/aarch64/multiarch/memset_kunpeng.S
+@@ -20,16 +20,13 @@
+ #include <sysdep.h>
+ #include <sysdeps/aarch64/memset-reg.h>
+
+-#if IS_IN (libc)
+-# define MEMSET __memset_kunpeng
+-
+ /* Assumptions:
+ *
+ * ARMv8-a, AArch64, unaligned accesses
+ *
+ */
+
+-ENTRY_ALIGN (MEMSET, 6)
++ENTRY (__memset_kunpeng)
+
+ PTR_ARG (0)
+ SIZE_ARG (2)
+@@ -108,6 +105,4 @@ L(set_long):
+ stp q0, q0, [dstend, -32]
+ ret
+
+-END (MEMSET)
+-libc_hidden_builtin_def (MEMSET)
+-#endif
++END (__memset_kunpeng)
+diff --git a/sysdeps/aarch64/multiarch/rtld-memset.S b/sysdeps/aarch64/multiarch/rtld-memset.S
+deleted file mode 100644
+index 4b035ed8b2..0000000000
+--- a/sysdeps/aarch64/multiarch/rtld-memset.S
++++ /dev/null
+@@ -1,25 +0,0 @@
+-/* Memset for aarch64, for the dynamic linker.
+- Copyright (C) 2017-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
+- <https://www.gnu.org/licenses/>. */
+-
+-#include <sysdep.h>
+-
+-#if IS_IN (rtld)
+-# define MEMSET memset
+-# include <sysdeps/aarch64/memset.S>
+-#endif
+diff --git a/sysdeps/aarch64/multiarch/strlen.c b/sysdeps/aarch64/multiarch/strlen.c
+index bbdd3de8c4..728bd1936a 100644
+--- a/sysdeps/aarch64/multiarch/strlen.c
++++ b/sysdeps/aarch64/multiarch/strlen.c
+@@ -28,10 +28,10 @@
+
+ extern __typeof (__redirect_strlen) __strlen;
+
+-extern __typeof (__redirect_strlen) __strlen_mte attribute_hidden;
++extern __typeof (__redirect_strlen) __strlen_generic attribute_hidden;
+ extern __typeof (__redirect_strlen) __strlen_asimd attribute_hidden;
+
+-libc_ifunc (__strlen, (mte ? __strlen_mte : __strlen_asimd));
++libc_ifunc (__strlen, (mte ? __strlen_generic : __strlen_asimd));
+
+ # undef strlen
+ strong_alias (__strlen, strlen);
+diff --git a/sysdeps/aarch64/multiarch/strlen_asimd.S b/sysdeps/aarch64/multiarch/strlen_asimd.S
+index 490439491d..aee5ef9f78 100644
+--- a/sysdeps/aarch64/multiarch/strlen_asimd.S
++++ b/sysdeps/aarch64/multiarch/strlen_asimd.S
+@@ -203,4 +203,3 @@ L(page_cross):
+ ret
+
+ END (__strlen_asimd)
+-libc_hidden_builtin_def (__strlen_asimd)
+diff --git a/sysdeps/aarch64/multiarch/strlen_mte.S b/sysdeps/aarch64/multiarch/strlen_generic.S
+similarity index 85%
+rename from sysdeps/aarch64/multiarch/strlen_mte.S
+rename to sysdeps/aarch64/multiarch/strlen_generic.S
+index 1c1220b767..2346296a18 100644
+--- a/sysdeps/aarch64/multiarch/strlen_mte.S
++++ b/sysdeps/aarch64/multiarch/strlen_generic.S
+@@ -17,14 +17,14 @@
+ <https://www.gnu.org/licenses/>. */
+
+ /* The actual strlen code is in ../strlen.S. If we are building libc this file
+- defines __strlen_mte. Otherwise the include of ../strlen.S will define
+- the normal __strlen entry points. */
++ defines __strlen_generic. Otherwise the include of ../strlen.S will define
++ the normal __strlen entry points. */
+
+ #include <sysdep.h>
+
+ #if IS_IN (libc)
+
+-# define STRLEN __strlen_mte
++# define STRLEN __strlen_generic
+
+ /* Do not hide the generic version of strlen, we use it internally. */
+ # undef libc_hidden_builtin_def
+@@ -32,7 +32,7 @@
+
+ # ifdef SHARED
+ /* It doesn't make sense to send libc-internal strlen calls through a PLT. */
+- .globl __GI_strlen; __GI_strlen = __strlen_mte
++ .globl __GI_strlen; __GI_strlen = __strlen_generic
+ # endif
+ #endif
+
+--
+2.33.0
+
diff --git a/0006-malloc-Enable-merging-of-remainders-in-memalign-bug-.patch b/0006-malloc-Enable-merging-of-remainders-in-memalign-bug-.patch
new file mode 100644
index 0000000..38f39e1
--- /dev/null
+++ b/0006-malloc-Enable-merging-of-remainders-in-memalign-bug-.patch
@@ -0,0 +1,301 @@
+From 98c293c61f770b6b7a22f89a6ea81b711ecb1952 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Fri, 11 Aug 2023 11:18:17 +0200
+Subject: [PATCH 06/12] malloc: Enable merging of remainders in memalign (bug
+ 30723)
+
+Previously, calling _int_free from _int_memalign could put remainders
+into the tcache or into fastbins, where they are invisible to the
+low-level allocator. This results in missed merge opportunities
+because once these freed chunks become available to the low-level
+allocator, further memalign allocations (even of the same size are)
+likely obstructing merges.
+
+Furthermore, during forwards merging in _int_memalign, do not
+completely give up when the remainder is too small to serve as a
+chunk on its own. We can still give it back if it can be merged
+with the following unused chunk. This makes it more likely that
+memalign calls in a loop achieve a compact memory layout,
+independently of initial heap layout.
+
+Drop some useless (unsigned long) casts along the way, and tweak
+the style to more closely match GNU on changed lines.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit 542b1105852568c3ebc712225ae78b8c8ba31a78)
+---
+ malloc/malloc.c | 197 +++++++++++++++++++++++++++++-------------------
+ 1 file changed, 121 insertions(+), 76 deletions(-)
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index e2f1a615a4..948f9759af 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -1086,6 +1086,11 @@ typedef struct malloc_chunk* mchunkptr;
+
+ static void* _int_malloc(mstate, size_t);
+ static void _int_free(mstate, mchunkptr, int);
++static void _int_free_merge_chunk (mstate, mchunkptr, INTERNAL_SIZE_T);
++static INTERNAL_SIZE_T _int_free_create_chunk (mstate,
++ mchunkptr, INTERNAL_SIZE_T,
++ mchunkptr, INTERNAL_SIZE_T);
++static void _int_free_maybe_consolidate (mstate, INTERNAL_SIZE_T);
+ static void* _int_realloc(mstate, mchunkptr, INTERNAL_SIZE_T,
+ INTERNAL_SIZE_T);
+ static void* _int_memalign(mstate, size_t, size_t);
+@@ -4637,31 +4642,52 @@ _int_free (mstate av, mchunkptr p, int have_lock)
+ if (!have_lock)
+ __libc_lock_lock (av->mutex);
+
+- nextchunk = chunk_at_offset(p, size);
+-
+- /* Lightweight tests: check whether the block is already the
+- top block. */
+- if (__glibc_unlikely (p == av->top))
+- malloc_printerr ("double free or corruption (top)");
+- /* Or whether the next chunk is beyond the boundaries of the arena. */
+- if (__builtin_expect (contiguous (av)
+- && (char *) nextchunk
+- >= ((char *) av->top + chunksize(av->top)), 0))
+- malloc_printerr ("double free or corruption (out)");
+- /* Or whether the block is actually not marked used. */
+- if (__glibc_unlikely (!prev_inuse(nextchunk)))
+- malloc_printerr ("double free or corruption (!prev)");
+-
+- nextsize = chunksize(nextchunk);
+- if (__builtin_expect (chunksize_nomask (nextchunk) <= CHUNK_HDR_SZ, 0)
+- || __builtin_expect (nextsize >= av->system_mem, 0))
+- malloc_printerr ("free(): invalid next size (normal)");
++ _int_free_merge_chunk (av, p, size);
+
+- free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);
++ if (!have_lock)
++ __libc_lock_unlock (av->mutex);
++ }
++ /*
++ If the chunk was allocated via mmap, release via munmap().
++ */
++
++ else {
++ munmap_chunk (p);
++ }
++}
++
++/* Try to merge chunk P of SIZE bytes with its neighbors. Put the
++ resulting chunk on the appropriate bin list. P must not be on a
++ bin list yet, and it can be in use. */
++static void
++_int_free_merge_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size)
++{
++ mchunkptr nextchunk = chunk_at_offset(p, size);
++
++ /* Lightweight tests: check whether the block is already the
++ top block. */
++ if (__glibc_unlikely (p == av->top))
++ malloc_printerr ("double free or corruption (top)");
++ /* Or whether the next chunk is beyond the boundaries of the arena. */
++ if (__builtin_expect (contiguous (av)
++ && (char *) nextchunk
++ >= ((char *) av->top + chunksize(av->top)), 0))
++ malloc_printerr ("double free or corruption (out)");
++ /* Or whether the block is actually not marked used. */
++ if (__glibc_unlikely (!prev_inuse(nextchunk)))
++ malloc_printerr ("double free or corruption (!prev)");
++
++ INTERNAL_SIZE_T nextsize = chunksize(nextchunk);
++ if (__builtin_expect (chunksize_nomask (nextchunk) <= CHUNK_HDR_SZ, 0)
++ || __builtin_expect (nextsize >= av->system_mem, 0))
++ malloc_printerr ("free(): invalid next size (normal)");
++
++ free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);
+
+- /* consolidate backward */
+- if (!prev_inuse(p)) {
+- prevsize = prev_size (p);
++ /* Consolidate backward. */
++ if (!prev_inuse(p))
++ {
++ INTERNAL_SIZE_T prevsize = prev_size (p);
+ size += prevsize;
+ p = chunk_at_offset(p, -((long) prevsize));
+ if (__glibc_unlikely (chunksize(p) != prevsize))
+@@ -4669,9 +4695,25 @@ _int_free (mstate av, mchunkptr p, int have_lock)
+ unlink_chunk (av, p);
+ }
+
+- if (nextchunk != av->top) {
++ /* Write the chunk header, maybe after merging with the following chunk. */
++ size = _int_free_create_chunk (av, p, size, nextchunk, nextsize);
++ _int_free_maybe_consolidate (av, size);
++}
++
++/* Create a chunk at P of SIZE bytes, with SIZE potentially increased
++ to cover the immediately following chunk NEXTCHUNK of NEXTSIZE
++ bytes (if NEXTCHUNK is unused). The chunk at P is not actually
++ read and does not have to be initialized. After creation, it is
++ placed on the appropriate bin list. The function returns the size
++ of the new chunk. */
++static INTERNAL_SIZE_T
++_int_free_create_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size,
++ mchunkptr nextchunk, INTERNAL_SIZE_T nextsize)
++{
++ if (nextchunk != av->top)
++ {
+ /* get and clear inuse bit */
+- nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
++ bool nextinuse = inuse_bit_at_offset (nextchunk, nextsize);
+
+ /* consolidate forward */
+ if (!nextinuse) {
+@@ -4686,8 +4728,8 @@ _int_free (mstate av, mchunkptr p, int have_lock)
+ been given one chance to be used in malloc.
+ */
+
+- bck = unsorted_chunks(av);
+- fwd = bck->fd;
++ mchunkptr bck = unsorted_chunks (av);
++ mchunkptr fwd = bck->fd;
+ if (__glibc_unlikely (fwd->bk != bck))
+ malloc_printerr ("free(): corrupted unsorted chunks");
+ p->fd = fwd;
+@@ -4706,61 +4748,52 @@ _int_free (mstate av, mchunkptr p, int have_lock)
+ check_free_chunk(av, p);
+ }
+
+- /*
+- If the chunk borders the current high end of memory,
+- consolidate into top
+- */
+-
+- else {
++ else
++ {
++ /* If the chunk borders the current high end of memory,
++ consolidate into top. */
+ size += nextsize;
+ set_head(p, size | PREV_INUSE);
+ av->top = p;
+ check_chunk(av, p);
+ }
+
+- /*
+- If freeing a large space, consolidate possibly-surrounding
+- chunks. Then, if the total unused topmost memory exceeds trim
+- threshold, ask malloc_trim to reduce top.
+-
+- Unless max_fast is 0, we don't know if there are fastbins
+- bordering top, so we cannot tell for sure whether threshold
+- has been reached unless fastbins are consolidated. But we
+- don't want to consolidate on each free. As a compromise,
+- consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD
+- is reached.
+- */
++ return size;
++}
+
+- if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
++/* If freeing a large space, consolidate possibly-surrounding
++ chunks. Then, if the total unused topmost memory exceeds trim
++ threshold, ask malloc_trim to reduce top. */
++static void
++_int_free_maybe_consolidate (mstate av, INTERNAL_SIZE_T size)
++{
++ /* Unless max_fast is 0, we don't know if there are fastbins
++ bordering top, so we cannot tell for sure whether threshold has
++ been reached unless fastbins are consolidated. But we don't want
++ to consolidate on each free. As a compromise, consolidation is
++ performed if FASTBIN_CONSOLIDATION_THRESHOLD is reached. */
++ if (size >= FASTBIN_CONSOLIDATION_THRESHOLD)
++ {
+ if (atomic_load_relaxed (&av->have_fastchunks))
+ malloc_consolidate(av);
+
+- if (av == &main_arena) {
++ if (av == &main_arena)
++ {
+ #ifndef MORECORE_CANNOT_TRIM
+- if ((unsigned long)(chunksize(av->top)) >=
+- (unsigned long)(mp_.trim_threshold))
+- systrim(mp_.top_pad, av);
++ if (chunksize (av->top) >= mp_.trim_threshold)
++ systrim (mp_.top_pad, av);
+ #endif
+- } else {
+- /* Always try heap_trim(), even if the top chunk is not
+- large, because the corresponding heap might go away. */
+- heap_info *heap = heap_for_ptr(top(av));
++ }
++ else
++ {
++ /* Always try heap_trim, even if the top chunk is not large,
++ because the corresponding heap might go away. */
++ heap_info *heap = heap_for_ptr (top (av));
+
+- assert(heap->ar_ptr == av);
+- heap_trim(heap, mp_.top_pad);
+- }
++ assert (heap->ar_ptr == av);
++ heap_trim (heap, mp_.top_pad);
++ }
+ }
+-
+- if (!have_lock)
+- __libc_lock_unlock (av->mutex);
+- }
+- /*
+- If the chunk was allocated via mmap, release via munmap().
+- */
+-
+- else {
+- munmap_chunk (p);
+- }
+ }
+
+ /*
+@@ -5221,7 +5254,7 @@ _int_memalign (mstate av, size_t alignment, size_t bytes)
+ (av != &main_arena ? NON_MAIN_ARENA : 0));
+ set_inuse_bit_at_offset (newp, newsize);
+ set_head_size (p, leadsize | (av != &main_arena ? NON_MAIN_ARENA : 0));
+- _int_free (av, p, 1);
++ _int_free_merge_chunk (av, p, leadsize);
+ p = newp;
+
+ assert (newsize >= nb &&
+@@ -5232,15 +5265,27 @@ _int_memalign (mstate av, size_t alignment, size_t bytes)
+ if (!chunk_is_mmapped (p))
+ {
+ size = chunksize (p);
+- if ((unsigned long) (size) > (unsigned long) (nb + MINSIZE))
++ mchunkptr nextchunk = chunk_at_offset(p, size);
++ INTERNAL_SIZE_T nextsize = chunksize(nextchunk);
++ if (size > nb)
+ {
+ remainder_size = size - nb;
+- remainder = chunk_at_offset (p, nb);
+- set_head (remainder, remainder_size | PREV_INUSE |
+- (av != &main_arena ? NON_MAIN_ARENA : 0));
+- set_head_size (p, nb);
+- _int_free (av, remainder, 1);
+- }
++ if (remainder_size >= MINSIZE
++ || nextchunk == av->top
++ || !inuse_bit_at_offset (nextchunk, nextsize))
++ {
++ /* We can only give back the tail if it is larger than
++ MINSIZE, or if the following chunk is unused (top
++ chunk or unused in-heap chunk). Otherwise we would
++ create a chunk that is smaller than MINSIZE. */
++ remainder = chunk_at_offset (p, nb);
++ set_head_size (p, nb);
++ remainder_size = _int_free_create_chunk (av, remainder,
++ remainder_size,
++ nextchunk, nextsize);
++ _int_free_maybe_consolidate (av, remainder_size);
++ }
++ }
+ }
+
+ check_inuse_chunk (av, p);
+--
+2.33.0
+
diff --git a/0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch b/0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch
new file mode 100644
index 0000000..572527b
--- /dev/null
+++ b/0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch
@@ -0,0 +1,232 @@
+From 6cad0f543ccac5abd35a3a617fab72a9c8c64155 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 24 Jul 2024 12:06:47 +0200
+Subject: [PATCH 06/12] resolv: Do not wait for non-existing second DNS
+ response after error (bug 30081)
+
+In single-request mode, there is no second response after an error
+because the second query has not been sent yet. Waiting for it
+introduces an unnecessary timeout.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit af625987d619388a100b153520d3ee308bda9889)
+---
+ NEWS | 1 +
+ resolv/Makefile | 3 +
+ resolv/res_send.c | 2 +-
+ resolv/tst-resolv-semi-failure.c | 133 +++++++++++++++++++++++++++++
+ resolv/tst-resolv-short-response.c | 12 +++
+ 5 files changed, 150 insertions(+), 1 deletion(-)
+ create mode 100644 resolv/tst-resolv-semi-failure.c
+
+diff --git a/NEWS b/NEWS
+index c331604747..4156a017ac 100644
+--- a/NEWS
++++ b/NEWS
+@@ -37,6 +37,7 @@ Security related changes:
+ The following bugs are resolved with this release:
+
+ [29039] Corrupt DTV after reuse of a TLS module ID following dlclose with unused TLS
++ [30081] resolv: Do not wait for non-existing second DNS response after error
+ [30694] The iconv program no longer tells the user which given encoding name was wrong
+ [30709] nscd fails to build with cleanup handler if built with -fexceptions
+ [30721] x86_64: Fix build with --disable-multiarch
+diff --git a/resolv/Makefile b/resolv/Makefile
+index cca0748f9a..b53a5fcfdb 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -106,6 +106,7 @@ tests += \
+ tst-resolv-nondecimal \
+ tst-resolv-res_init-multi \
+ tst-resolv-search \
++ tst-resolv-semi-failure \
+ tst-resolv-short-response \
+ tst-resolv-trailing \
+
+@@ -300,6 +301,8 @@ $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
++$(objpfx)tst-resolv-semi-failure: $(objpfx)libresolv.so \
++ $(shared-thread-library)
+ $(objpfx)tst-resolv-short-response: $(objpfx)libresolv.so \
+ $(shared-thread-library)
+ $(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
+diff --git a/resolv/res_send.c b/resolv/res_send.c
+index bf4ce67b1d..b741b42cae 100644
+--- a/resolv/res_send.c
++++ b/resolv/res_send.c
+@@ -1236,7 +1236,7 @@ send_dg(res_state statp,
+ *resplen2 = 0;
+ return resplen;
+ }
+- if (buf2 != NULL)
++ if (buf2 != NULL && !single_request)
+ {
+ /* No data from the first reply. */
+ resplen = 0;
+diff --git a/resolv/tst-resolv-semi-failure.c b/resolv/tst-resolv-semi-failure.c
+new file mode 100644
+index 0000000000..aa9798b5a7
+--- /dev/null
++++ b/resolv/tst-resolv-semi-failure.c
+@@ -0,0 +1,133 @@
++/* Test parallel failure/success responses (bug 30081).
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <resolv.h>
++#include <support/check.h>
++#include <support/resolv_test.h>
++#include <support/check_nss.h>
++
++/* The rcode in the initial response. */
++static volatile int rcode;
++
++/* Whether to fail the initial A query (!fail_aaaa) or the initial
++ AAAA query (fail_aaaa). */
++static volatile bool fail_aaaa;
++
++static void
++response (const struct resolv_response_context *ctx,
++ struct resolv_response_builder *b,
++ const char *qname, uint16_t qclass, uint16_t qtype)
++{
++ /* Handle the failing query. */
++ if ((fail_aaaa && qtype == T_AAAA) && ctx->server_index == 0)
++ {
++ struct resolv_response_flags flags = {.rcode = rcode};
++ resolv_response_init (b, flags);
++ return;
++ }
++
++ /* Otherwise produce a response. */
++ resolv_response_init (b, (struct resolv_response_flags) {});
++ resolv_response_add_question (b, qname, qclass, qtype);
++ resolv_response_section (b, ns_s_an);
++ resolv_response_open_record (b, qname, qclass, qtype, 0);
++ switch (qtype)
++ {
++ case T_A:
++ {
++ char ipv4[4] = {192, 0, 2, 17};
++ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
++ }
++ break;
++ case T_AAAA:
++ {
++ char ipv6[16]
++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
++ resolv_response_add_data (b, &ipv6, sizeof (ipv6));
++ }
++ break;
++ default:
++ FAIL_EXIT1 ("unexpected TYPE%d query", qtype);
++ }
++ resolv_response_close_record (b);
++}
++
++static void
++check_one (void)
++{
++
++ /* The buggy 1-second query timeout results in 30 seconds of delay,
++ which triggers are test timeout failure. */
++ for (int i = 0; i < 30; ++i)
++ {
++ static const struct addrinfo hints =
++ {
++ .ai_family = AF_UNSPEC,
++ .ai_socktype = SOCK_STREAM,
++ };
++ struct addrinfo *ai;
++ int ret = getaddrinfo ("www.example", "80", &hints, &ai);
++ const char *expected;
++ if (ret == 0 && ai->ai_next != NULL)
++ expected = ("address: STREAM/TCP 192.0.2.17 80\n"
++ "address: STREAM/TCP 2001:db8::1 80\n");
++ else
++ /* Only one response because the AAAA lookup failure is
++ treated as an ignoreable error. */
++ expected = "address: STREAM/TCP 192.0.2.17 80\n";
++ check_addrinfo ("www.example", ai, ret, expected);
++ if (ret == 0)
++ freeaddrinfo (ai);
++ }
++}
++
++static int
++do_test (void)
++{
++ for (int do_single_lookup = 0; do_single_lookup < 2; ++do_single_lookup)
++ {
++ struct resolv_test *aux = resolv_test_start
++ ((struct resolv_redirect_config)
++ {
++ .response_callback = response,
++ });
++
++ if (do_single_lookup)
++ _res.options |= RES_SNGLKUP;
++
++ for (int do_fail_aaaa = 0; do_fail_aaaa < 2; ++do_fail_aaaa)
++ {
++ fail_aaaa = do_fail_aaaa;
++
++ rcode = 2; /* SERVFAIL. */
++ check_one ();
++
++ rcode = 4; /* NOTIMP. */
++ check_one ();
++
++ rcode = 5; /* REFUSED. */
++ check_one ();
++ }
++
++ resolv_test_end (aux);
++ }
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c
+index cf1e39876f..be354ae1c7 100644
+--- a/resolv/tst-resolv-short-response.c
++++ b/resolv/tst-resolv-short-response.c
+@@ -81,6 +81,18 @@ check_one (void)
+ check_hostent ("www.example", gethostbyname2 ("www.example", AF_INET6),
+ "name: www.example\n"
+ "address: 2001:db8::1\n");
++ static const struct addrinfo hints =
++ {
++ .ai_family = AF_UNSPEC,
++ .ai_socktype = SOCK_STREAM,
++ };
++ struct addrinfo *ai;
++ int ret = getaddrinfo ("www.example", "80", &hints, &ai);
++ check_addrinfo ("www.example", ai, ret,
++ "address: STREAM/TCP 192.0.2.17 80\n"
++ "address: STREAM/TCP 2001:db8::1 80\n");
++ if (ret == 0)
++ freeaddrinfo (ai);
+ }
+ }
+
+--
+2.33.0
+
diff --git a/0007-AArch64-Cleanup-emag-memset.patch b/0007-AArch64-Cleanup-emag-memset.patch
new file mode 100644
index 0000000..c579cfa
--- /dev/null
+++ b/0007-AArch64-Cleanup-emag-memset.patch
@@ -0,0 +1,348 @@
+From 1521237c3211bb0b1a8f7a9c5793d382789b2b68 Mon Sep 17 00:00:00 2001
+From: Wilco Dijkstra <wilco.dijkstra@arm.com>
+Date: Thu, 26 Oct 2023 16:34:47 +0100
+Subject: [PATCH 07/26] AArch64: Cleanup emag memset
+
+Cleanup emag memset - merge the memset_base64.S file, remove
+the unused ZVA code (since it is disabled on emag).
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 9627ab99b50d250c6dd3001a3355aa03692f7fe5)
+---
+ sysdeps/aarch64/multiarch/ifunc-impl-list.c | 2 +-
+ sysdeps/aarch64/multiarch/memset.c | 2 +-
+ sysdeps/aarch64/multiarch/memset_base64.S | 185 --------------------
+ sysdeps/aarch64/multiarch/memset_emag.S | 98 +++++++++--
+ 4 files changed, 90 insertions(+), 197 deletions(-)
+ delete mode 100644 sysdeps/aarch64/multiarch/memset_base64.S
+
+diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+index 836e8317a5..3596d3c8d3 100644
+--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+@@ -57,7 +57,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ /* Enable this on non-falkor processors too so that other cores
+ can do a comparative analysis with __memset_generic. */
+ IFUNC_IMPL_ADD (array, i, memset, (zva_size == 64), __memset_falkor)
+- IFUNC_IMPL_ADD (array, i, memset, (zva_size == 64), __memset_emag)
++ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_emag)
+ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_kunpeng)
+ #if HAVE_AARCH64_SVE_ASM
+ IFUNC_IMPL_ADD (array, i, memset, sve && zva_size == 256, __memset_a64fx)
+diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c
+index 23fc66e158..9193b197dd 100644
+--- a/sysdeps/aarch64/multiarch/memset.c
++++ b/sysdeps/aarch64/multiarch/memset.c
+@@ -56,7 +56,7 @@ select_memset_ifunc (void)
+ if ((IS_FALKOR (midr) || IS_PHECDA (midr)) && zva_size == 64)
+ return __memset_falkor;
+
+- if (IS_EMAG (midr) && zva_size == 64)
++ if (IS_EMAG (midr))
+ return __memset_emag;
+
+ return __memset_generic;
+diff --git a/sysdeps/aarch64/multiarch/memset_base64.S b/sysdeps/aarch64/multiarch/memset_base64.S
+deleted file mode 100644
+index 0e8f709fa5..0000000000
+--- a/sysdeps/aarch64/multiarch/memset_base64.S
++++ /dev/null
+@@ -1,185 +0,0 @@
+-/* Copyright (C) 2018-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
+- <https://www.gnu.org/licenses/>. */
+-
+-#include <sysdep.h>
+-#include "memset-reg.h"
+-
+-#ifndef MEMSET
+-# define MEMSET __memset_base64
+-#endif
+-
+-/* To disable DC ZVA, set this threshold to 0. */
+-#ifndef DC_ZVA_THRESHOLD
+-# define DC_ZVA_THRESHOLD 512
+-#endif
+-
+-/* Assumptions:
+- *
+- * ARMv8-a, AArch64, unaligned accesses
+- *
+- */
+-
+-ENTRY (MEMSET)
+-
+- PTR_ARG (0)
+- SIZE_ARG (2)
+-
+- bfi valw, valw, 8, 8
+- bfi valw, valw, 16, 16
+- bfi val, val, 32, 32
+-
+- add dstend, dstin, count
+-
+- cmp count, 96
+- b.hi L(set_long)
+- cmp count, 16
+- b.hs L(set_medium)
+-
+- /* Set 0..15 bytes. */
+- tbz count, 3, 1f
+- str val, [dstin]
+- str val, [dstend, -8]
+- ret
+-
+- .p2align 3
+-1: tbz count, 2, 2f
+- str valw, [dstin]
+- str valw, [dstend, -4]
+- ret
+-2: cbz count, 3f
+- strb valw, [dstin]
+- tbz count, 1, 3f
+- strh valw, [dstend, -2]
+-3: ret
+-
+- .p2align 3
+- /* Set 16..96 bytes. */
+-L(set_medium):
+- stp val, val, [dstin]
+- tbnz count, 6, L(set96)
+- stp val, val, [dstend, -16]
+- tbz count, 5, 1f
+- stp val, val, [dstin, 16]
+- stp val, val, [dstend, -32]
+-1: ret
+-
+- .p2align 4
+- /* Set 64..96 bytes. Write 64 bytes from the start and
+- 32 bytes from the end. */
+-L(set96):
+- stp val, val, [dstin, 16]
+- stp val, val, [dstin, 32]
+- stp val, val, [dstin, 48]
+- stp val, val, [dstend, -32]
+- stp val, val, [dstend, -16]
+- ret
+-
+- .p2align 4
+-L(set_long):
+- stp val, val, [dstin]
+- bic dst, dstin, 15
+-#if DC_ZVA_THRESHOLD
+- cmp count, DC_ZVA_THRESHOLD
+- ccmp val, 0, 0, cs
+- b.eq L(zva_64)
+-#endif
+- /* Small-size or non-zero memset does not use DC ZVA. */
+- sub count, dstend, dst
+-
+- /*
+- * Adjust count and bias for loop. By subtracting extra 1 from count,
+- * it is easy to use tbz instruction to check whether loop tailing
+- * count is less than 33 bytes, so as to bypass 2 unnecessary stps.
+- */
+- sub count, count, 64+16+1
+-
+-#if DC_ZVA_THRESHOLD
+- /* Align loop on 16-byte boundary, this might be friendly to i-cache. */
+- nop
+-#endif
+-
+-1: stp val, val, [dst, 16]
+- stp val, val, [dst, 32]
+- stp val, val, [dst, 48]
+- stp val, val, [dst, 64]!
+- subs count, count, 64
+- b.hs 1b
+-
+- tbz count, 5, 1f /* Remaining count is less than 33 bytes? */
+- stp val, val, [dst, 16]
+- stp val, val, [dst, 32]
+-1: stp val, val, [dstend, -32]
+- stp val, val, [dstend, -16]
+- ret
+-
+-#if DC_ZVA_THRESHOLD
+- .p2align 3
+-L(zva_64):
+- stp val, val, [dst, 16]
+- stp val, val, [dst, 32]
+- stp val, val, [dst, 48]
+- bic dst, dst, 63
+-
+- /*
+- * Previous memory writes might cross cache line boundary, and cause
+- * cache line partially dirty. Zeroing this kind of cache line using
+- * DC ZVA will incur extra cost, for it requires loading untouched
+- * part of the line from memory before zeoring.
+- *
+- * So, write the first 64 byte aligned block using stp to force
+- * fully dirty cache line.
+- */
+- stp val, val, [dst, 64]
+- stp val, val, [dst, 80]
+- stp val, val, [dst, 96]
+- stp val, val, [dst, 112]
+-
+- sub count, dstend, dst
+- /*
+- * Adjust count and bias for loop. By subtracting extra 1 from count,
+- * it is easy to use tbz instruction to check whether loop tailing
+- * count is less than 33 bytes, so as to bypass 2 unnecessary stps.
+- */
+- sub count, count, 128+64+64+1
+- add dst, dst, 128
+- nop
+-
+- /* DC ZVA sets 64 bytes each time. */
+-1: dc zva, dst
+- add dst, dst, 64
+- subs count, count, 64
+- b.hs 1b
+-
+- /*
+- * Write the last 64 byte aligned block using stp to force fully
+- * dirty cache line.
+- */
+- stp val, val, [dst, 0]
+- stp val, val, [dst, 16]
+- stp val, val, [dst, 32]
+- stp val, val, [dst, 48]
+-
+- tbz count, 5, 1f /* Remaining count is less than 33 bytes? */
+- stp val, val, [dst, 64]
+- stp val, val, [dst, 80]
+-1: stp val, val, [dstend, -32]
+- stp val, val, [dstend, -16]
+- ret
+-#endif
+-
+-END (MEMSET)
+diff --git a/sysdeps/aarch64/multiarch/memset_emag.S b/sysdeps/aarch64/multiarch/memset_emag.S
+index 6fecad4fae..bbfa815925 100644
+--- a/sysdeps/aarch64/multiarch/memset_emag.S
++++ b/sysdeps/aarch64/multiarch/memset_emag.S
+@@ -18,17 +18,95 @@
+ <https://www.gnu.org/licenses/>. */
+
+ #include <sysdep.h>
++#include "memset-reg.h"
+
+-#define MEMSET __memset_emag
+-
+-/*
+- * Using DC ZVA to zero memory does not produce better performance if
+- * memory size is not very large, especially when there are multiple
+- * processes/threads contending memory/cache. Here we set threshold to
+- * zero to disable using DC ZVA, which is good for multi-process/thread
+- * workloads.
++/* Assumptions:
++ *
++ * ARMv8-a, AArch64, unaligned accesses
++ *
+ */
+
+-#define DC_ZVA_THRESHOLD 0
++ENTRY (__memset_emag)
++
++ PTR_ARG (0)
++ SIZE_ARG (2)
++
++ bfi valw, valw, 8, 8
++ bfi valw, valw, 16, 16
++ bfi val, val, 32, 32
++
++ add dstend, dstin, count
++
++ cmp count, 96
++ b.hi L(set_long)
++ cmp count, 16
++ b.hs L(set_medium)
++
++ /* Set 0..15 bytes. */
++ tbz count, 3, 1f
++ str val, [dstin]
++ str val, [dstend, -8]
++ ret
++
++ .p2align 3
++1: tbz count, 2, 2f
++ str valw, [dstin]
++ str valw, [dstend, -4]
++ ret
++2: cbz count, 3f
++ strb valw, [dstin]
++ tbz count, 1, 3f
++ strh valw, [dstend, -2]
++3: ret
++
++ .p2align 3
++ /* Set 16..96 bytes. */
++L(set_medium):
++ stp val, val, [dstin]
++ tbnz count, 6, L(set96)
++ stp val, val, [dstend, -16]
++ tbz count, 5, 1f
++ stp val, val, [dstin, 16]
++ stp val, val, [dstend, -32]
++1: ret
++
++ .p2align 4
++ /* Set 64..96 bytes. Write 64 bytes from the start and
++ 32 bytes from the end. */
++L(set96):
++ stp val, val, [dstin, 16]
++ stp val, val, [dstin, 32]
++ stp val, val, [dstin, 48]
++ stp val, val, [dstend, -32]
++ stp val, val, [dstend, -16]
++ ret
++
++ .p2align 4
++L(set_long):
++ stp val, val, [dstin]
++ bic dst, dstin, 15
++ /* Small-size or non-zero memset does not use DC ZVA. */
++ sub count, dstend, dst
++
++ /*
++ * Adjust count and bias for loop. By subtracting extra 1 from count,
++ * it is easy to use tbz instruction to check whether loop tailing
++ * count is less than 33 bytes, so as to bypass 2 unnecessary stps.
++ */
++ sub count, count, 64+16+1
++
++1: stp val, val, [dst, 16]
++ stp val, val, [dst, 32]
++ stp val, val, [dst, 48]
++ stp val, val, [dst, 64]!
++ subs count, count, 64
++ b.hs 1b
++
++ tbz count, 5, 1f /* Remaining count is less than 33 bytes? */
++ stp val, val, [dst, 16]
++ stp val, val, [dst, 32]
++1: stp val, val, [dstend, -32]
++ stp val, val, [dstend, -16]
++ ret
+
+-#include "./memset_base64.S"
++END (__memset_emag)
+--
+2.33.0
+
diff --git a/0007-malloc-Remove-bin-scanning-from-memalign-bug-30723.patch b/0007-malloc-Remove-bin-scanning-from-memalign-bug-30723.patch
new file mode 100644
index 0000000..87db13c
--- /dev/null
+++ b/0007-malloc-Remove-bin-scanning-from-memalign-bug-30723.patch
@@ -0,0 +1,269 @@
+From 2af141bda3cd407abd4bedf615f9e45fe79518e2 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 10 Aug 2023 19:36:56 +0200
+Subject: [PATCH 07/12] malloc: Remove bin scanning from memalign (bug 30723)
+
+On the test workload (mpv --cache=yes with VP9 video decoding), the
+bin scanning has a very poor success rate (less than 2%). The tcache
+scanning has about 50% success rate, so keep that.
+
+Update comments in malloc/tst-memalign-2 to indicate the purpose
+of the tests. Even with the scanning removed, the additional
+merging opportunities since commit 542b1105852568c3ebc712225ae78b
+("malloc: Enable merging of remainders in memalign (bug 30723)")
+are sufficient to pass the existing large bins test.
+
+Remove leftover variables from _int_free from refactoring in the
+same commit.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit 0dc7fc1cf094406a138e4d1bcf9553e59edcf89d)
+---
+ NEWS | 1 +
+ malloc/malloc.c | 169 ++--------------------------------------
+ malloc/tst-memalign-2.c | 7 +-
+ 3 files changed, 11 insertions(+), 166 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 872bc8907b..c339cb444e 100644
+--- a/NEWS
++++ b/NEWS
+@@ -132,6 +132,7 @@ The following bugs are resolved with this release:
+ [30555] string: strerror can incorrectly return NULL
+ [30579] malloc: trim_threshold in realloc lead to high memory usage
+ [30662] nscd: Group and password cache use errno in place of errval
++ [30723] posix_memalign repeatedly scans long bin lists
+
+ Version 2.37
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 948f9759af..d0bbbf3710 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -4488,12 +4488,6 @@ _int_free (mstate av, mchunkptr p, int have_lock)
+ {
+ INTERNAL_SIZE_T size; /* its size */
+ mfastbinptr *fb; /* associated fastbin */
+- mchunkptr nextchunk; /* next contiguous chunk */
+- INTERNAL_SIZE_T nextsize; /* its size */
+- int nextinuse; /* true if nextchunk is used */
+- INTERNAL_SIZE_T prevsize; /* size of previous contiguous chunk */
+- mchunkptr bck; /* misc temp for linking */
+- mchunkptr fwd; /* misc temp for linking */
+
+ size = chunksize (p);
+
+@@ -5032,42 +5026,6 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
+ ------------------------------ memalign ------------------------------
+ */
+
+-/* Returns 0 if the chunk is not and does not contain the requested
+- aligned sub-chunk, else returns the amount of "waste" from
+- trimming. NB is the *chunk* byte size, not the user byte
+- size. */
+-static size_t
+-chunk_ok_for_memalign (mchunkptr p, size_t alignment, size_t nb)
+-{
+- void *m = chunk2mem (p);
+- INTERNAL_SIZE_T size = chunksize (p);
+- void *aligned_m = m;
+-
+- if (__glibc_unlikely (misaligned_chunk (p)))
+- malloc_printerr ("_int_memalign(): unaligned chunk detected");
+-
+- aligned_m = PTR_ALIGN_UP (m, alignment);
+-
+- INTERNAL_SIZE_T front_extra = (intptr_t) aligned_m - (intptr_t) m;
+-
+- /* We can't trim off the front as it's too small. */
+- if (front_extra > 0 && front_extra < MINSIZE)
+- return 0;
+-
+- /* If it's a perfect fit, it's an exception to the return value rule
+- (we would return zero waste, which looks like "not usable"), so
+- handle it here by returning a small non-zero value instead. */
+- if (size == nb && front_extra == 0)
+- return 1;
+-
+- /* If the block we need fits in the chunk, calculate total waste. */
+- if (size > nb + front_extra)
+- return size - nb;
+-
+- /* Can't use this chunk. */
+- return 0;
+-}
+-
+ /* BYTES is user requested bytes, not requested chunksize bytes. */
+ static void *
+ _int_memalign (mstate av, size_t alignment, size_t bytes)
+@@ -5082,7 +5040,6 @@ _int_memalign (mstate av, size_t alignment, size_t bytes)
+ mchunkptr remainder; /* spare room at end to split off */
+ unsigned long remainder_size; /* its size */
+ INTERNAL_SIZE_T size;
+- mchunkptr victim;
+
+ nb = checked_request2size (bytes);
+ if (nb == 0)
+@@ -5101,129 +5058,13 @@ _int_memalign (mstate av, size_t alignment, size_t bytes)
+ we don't find anything in those bins, the common malloc code will
+ scan starting at 2x. */
+
+- /* This will be set if we found a candidate chunk. */
+- victim = NULL;
+-
+- /* Fast bins are singly-linked, hard to remove a chunk from the middle
+- and unlikely to meet our alignment requirements. We have not done
+- any experimentation with searching for aligned fastbins. */
+-
+- if (av != NULL)
+- {
+- int first_bin_index;
+- int first_largebin_index;
+- int last_bin_index;
+-
+- if (in_smallbin_range (nb))
+- first_bin_index = smallbin_index (nb);
+- else
+- first_bin_index = largebin_index (nb);
+-
+- if (in_smallbin_range (nb * 2))
+- last_bin_index = smallbin_index (nb * 2);
+- else
+- last_bin_index = largebin_index (nb * 2);
+-
+- first_largebin_index = largebin_index (MIN_LARGE_SIZE);
+-
+- int victim_index; /* its bin index */
+-
+- for (victim_index = first_bin_index;
+- victim_index < last_bin_index;
+- victim_index ++)
+- {
+- victim = NULL;
+-
+- if (victim_index < first_largebin_index)
+- {
+- /* Check small bins. Small bin chunks are doubly-linked despite
+- being the same size. */
+-
+- mchunkptr fwd; /* misc temp for linking */
+- mchunkptr bck; /* misc temp for linking */
+-
+- bck = bin_at (av, victim_index);
+- fwd = bck->fd;
+- while (fwd != bck)
+- {
+- if (chunk_ok_for_memalign (fwd, alignment, nb) > 0)
+- {
+- victim = fwd;
+-
+- /* Unlink it */
+- victim->fd->bk = victim->bk;
+- victim->bk->fd = victim->fd;
+- break;
+- }
+-
+- fwd = fwd->fd;
+- }
+- }
+- else
+- {
+- /* Check large bins. */
+- mchunkptr fwd; /* misc temp for linking */
+- mchunkptr bck; /* misc temp for linking */
+- mchunkptr best = NULL;
+- size_t best_size = 0;
+-
+- bck = bin_at (av, victim_index);
+- fwd = bck->fd;
++ /* Call malloc with worst case padding to hit alignment. */
++ m = (char *) (_int_malloc (av, nb + alignment + MINSIZE));
+
+- while (fwd != bck)
+- {
+- int extra;
+-
+- if (chunksize (fwd) < nb)
+- break;
+- extra = chunk_ok_for_memalign (fwd, alignment, nb);
+- if (extra > 0
+- && (extra <= best_size || best == NULL))
+- {
+- best = fwd;
+- best_size = extra;
+- }
++ if (m == 0)
++ return 0; /* propagate failure */
+
+- fwd = fwd->fd;
+- }
+- victim = best;
+-
+- if (victim != NULL)
+- {
+- unlink_chunk (av, victim);
+- break;
+- }
+- }
+-
+- if (victim != NULL)
+- break;
+- }
+- }
+-
+- /* Strategy: find a spot within that chunk that meets the alignment
+- request, and then possibly free the leading and trailing space.
+- This strategy is incredibly costly and can lead to external
+- fragmentation if header and footer chunks are unused. */
+-
+- if (victim != NULL)
+- {
+- p = victim;
+- m = chunk2mem (p);
+- set_inuse (p);
+- if (av != &main_arena)
+- set_non_main_arena (p);
+- }
+- else
+- {
+- /* Call malloc with worst case padding to hit alignment. */
+-
+- m = (char *) (_int_malloc (av, nb + alignment + MINSIZE));
+-
+- if (m == 0)
+- return 0; /* propagate failure */
+-
+- p = mem2chunk (m);
+- }
++ p = mem2chunk (m);
+
+ if ((((unsigned long) (m)) % alignment) != 0) /* misaligned */
+ {
+diff --git a/malloc/tst-memalign-2.c b/malloc/tst-memalign-2.c
+index f229283dbf..ecd6fa249e 100644
+--- a/malloc/tst-memalign-2.c
++++ b/malloc/tst-memalign-2.c
+@@ -86,7 +86,8 @@ do_test (void)
+ TEST_VERIFY (tcache_allocs[i].ptr1 == tcache_allocs[i].ptr2);
+ }
+
+- /* Test for non-head tcache hits. */
++ /* Test for non-head tcache hits. This exercises the memalign
++ scanning code to find matching allocations. */
+ for (i = 0; i < array_length (ptr); ++ i)
+ {
+ if (i == 4)
+@@ -113,7 +114,9 @@ do_test (void)
+ free (p);
+ TEST_VERIFY (count > 0);
+
+- /* Large bins test. */
++ /* Large bins test. This verifies that the over-allocated parts
++ that memalign releases for future allocations can be reused by
++ memalign itself at least in some cases. */
+
+ for (i = 0; i < LN; ++ i)
+ {
+--
+2.33.0
+
diff --git a/0007-resolv-Track-single-request-fallback-via-_res._flags.patch b/0007-resolv-Track-single-request-fallback-via-_res._flags.patch
new file mode 100644
index 0000000..e8963df
--- /dev/null
+++ b/0007-resolv-Track-single-request-fallback-via-_res._flags.patch
@@ -0,0 +1,81 @@
+From 1bed6acf50f6fdedf5a501cbd6a8225e5c13b886 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 13 Jun 2024 18:56:30 +0200
+Subject: [PATCH 07/12] resolv: Track single-request fallback via _res._flags
+ (bug 31476)
+
+This avoids changing _res.options, which inteferes with change
+detection as part of automatic reloading of /etc/resolv.conf.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit 868ab8923a2ec977faafec97ecafac0c3159c1b2)
+---
+ NEWS | 1 +
+ resolv/res_send.c | 12 +++++++-----
+ resolv/resolv-internal.h | 2 ++
+ 3 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 4156a017ac..3b252c96b4 100644
+--- a/NEWS
++++ b/NEWS
+@@ -52,6 +52,7 @@ The following bugs are resolved with this release:
+ [31183] Wide stream buffer size reduced MB_LEN_MAX bytes after bug 17522 fix
+ [31184] FAIL: elf/tst-tlsgap
+ [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
++ [31476] resolv: Track single-request fallback via _res._flags
+ [31890] resolv: Allow short error responses to match any DNS query
+ [31965] rseq extension mechanism does not work as intended
+
+diff --git a/resolv/res_send.c b/resolv/res_send.c
+index b741b42cae..1b130b4df4 100644
+--- a/resolv/res_send.c
++++ b/resolv/res_send.c
+@@ -947,9 +947,11 @@ send_dg(res_state statp,
+ seconds /= statp->nscount;
+ if (seconds <= 0)
+ seconds = 1;
+- bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
+- bool single_request = (((statp->options & RES_SNGLKUP) != 0)
+- | single_request_reopen);
++ bool single_request_reopen = ((statp->options & RES_SNGLKUPREOP)
++ || (statp->_flags & RES_F_SNGLKUPREOP));
++ bool single_request = ((statp->options & RES_SNGLKUP)
++ || (statp->_flags & RES_F_SNGLKUP)
++ || single_request_reopen);
+ int save_gotsomewhere = *gotsomewhere;
+
+ int retval;
+@@ -1006,14 +1008,14 @@ send_dg(res_state statp,
+ have received the first answer. */
+ if (!single_request)
+ {
+- statp->options |= RES_SNGLKUP;
++ statp->_flags |= RES_F_SNGLKUP;
+ single_request = true;
+ *gotsomewhere = save_gotsomewhere;
+ goto retry;
+ }
+ else if (!single_request_reopen)
+ {
+- statp->options |= RES_SNGLKUPREOP;
++ statp->_flags |= RES_F_SNGLKUPREOP;
+ single_request_reopen = true;
+ *gotsomewhere = save_gotsomewhere;
+ __res_iclose (statp, false);
+diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h
+index 2b98ac4920..3fa81d784f 100644
+--- a/resolv/resolv-internal.h
++++ b/resolv/resolv-internal.h
+@@ -26,6 +26,8 @@
+ #define RES_F_VC 0x00000001 /* Socket is TCP. */
+ #define RES_F_CONN 0x00000002 /* Socket is connected. */
+ #define RES_F_EDNS0ERR 0x00000004 /* EDNS0 caused errors. */
++#define RES_F_SNGLKUP 0x00200000 /* Private version of RES_SNGLKUP. */
++#define RES_F_SNGLKUPREOP 0x00400000 /* Private version of RES_SNGLKUPREOP. */
+
+ /* The structure HEADER is normally aligned on a word boundary. In
+ some code, we need to access this structure when it may be aligned
+--
+2.33.0
+
diff --git a/0008-AArch64-Add-memset_zva64.patch b/0008-AArch64-Add-memset_zva64.patch
new file mode 100644
index 0000000..5225816
--- /dev/null
+++ b/0008-AArch64-Add-memset_zva64.patch
@@ -0,0 +1,228 @@
+From 156e44845f4137d6d3ea6c2824dd459652a7efda Mon Sep 17 00:00:00 2001
+From: Wilco Dijkstra <wilco.dijkstra@arm.com>
+Date: Thu, 26 Oct 2023 17:07:21 +0100
+Subject: [PATCH 08/26] AArch64: Add memset_zva64
+
+Add a specialized memset for the common ZVA size of 64 to avoid the
+overhead of reading the ZVA size. Since the code is identical to
+__memset_falkor, remove the latter.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 3d7090f14b13312320e425b27dcf0fe72de026fd)
+---
+ sysdeps/aarch64/memset.S | 10 ++--
+ sysdeps/aarch64/multiarch/Makefile | 2 +-
+ sysdeps/aarch64/multiarch/ifunc-impl-list.c | 4 +-
+ sysdeps/aarch64/multiarch/memset.c | 9 ++--
+ sysdeps/aarch64/multiarch/memset_falkor.S | 54 ---------------------
+ sysdeps/aarch64/multiarch/memset_zva64.S | 27 +++++++++++
+ 6 files changed, 38 insertions(+), 68 deletions(-)
+ delete mode 100644 sysdeps/aarch64/multiarch/memset_falkor.S
+ create mode 100644 sysdeps/aarch64/multiarch/memset_zva64.S
+
+diff --git a/sysdeps/aarch64/memset.S b/sysdeps/aarch64/memset.S
+index bf3cf85c8a..bbfb7184c3 100644
+--- a/sysdeps/aarch64/memset.S
++++ b/sysdeps/aarch64/memset.S
+@@ -101,19 +101,19 @@ L(tail64):
+ ret
+
+ L(try_zva):
+-#ifdef ZVA_MACRO
+- zva_macro
+-#else
++#ifndef ZVA64_ONLY
+ .p2align 3
+ mrs tmp1, dczid_el0
+ tbnz tmp1w, 4, L(no_zva)
+ and tmp1w, tmp1w, 15
+ cmp tmp1w, 4 /* ZVA size is 64 bytes. */
+ b.ne L(zva_128)
+-
++ nop
++#endif
+ /* Write the first and last 64 byte aligned block using stp rather
+ than using DC ZVA. This is faster on some cores.
+ */
++ .p2align 4
+ L(zva_64):
+ str q0, [dst, 16]
+ stp q0, q0, [dst, 32]
+@@ -123,7 +123,6 @@ L(zva_64):
+ sub count, dstend, dst /* Count is now 128 too large. */
+ sub count, count, 128+64+64 /* Adjust count and bias for loop. */
+ add dst, dst, 128
+- nop
+ 1: dc zva, dst
+ add dst, dst, 64
+ subs count, count, 64
+@@ -134,6 +133,7 @@ L(zva_64):
+ stp q0, q0, [dstend, -32]
+ ret
+
++#ifndef ZVA64_ONLY
+ .p2align 3
+ L(zva_128):
+ cmp tmp1w, 5 /* ZVA size is 128 bytes. */
+diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
+index a1a4de3cd9..171ca5e4cf 100644
+--- a/sysdeps/aarch64/multiarch/Makefile
++++ b/sysdeps/aarch64/multiarch/Makefile
+@@ -12,10 +12,10 @@ sysdep_routines += \
+ memmove_mops \
+ memset_a64fx \
+ memset_emag \
+- memset_falkor \
+ memset_generic \
+ memset_kunpeng \
+ memset_mops \
++ memset_zva64 \
+ strlen_asimd \
+ strlen_generic \
+ # sysdep_routines
+diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+index 3596d3c8d3..fdd9ea9246 100644
+--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+@@ -54,9 +54,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, memmove, mops, __memmove_mops)
+ IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_generic))
+ IFUNC_IMPL (i, name, memset,
+- /* Enable this on non-falkor processors too so that other cores
+- can do a comparative analysis with __memset_generic. */
+- IFUNC_IMPL_ADD (array, i, memset, (zva_size == 64), __memset_falkor)
++ IFUNC_IMPL_ADD (array, i, memset, (zva_size == 64), __memset_zva64)
+ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_emag)
+ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_kunpeng)
+ #if HAVE_AARCH64_SVE_ASM
+diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c
+index 9193b197dd..6deb6865e5 100644
+--- a/sysdeps/aarch64/multiarch/memset.c
++++ b/sysdeps/aarch64/multiarch/memset.c
+@@ -28,7 +28,7 @@
+
+ extern __typeof (__redirect_memset) __libc_memset;
+
+-extern __typeof (__redirect_memset) __memset_falkor attribute_hidden;
++extern __typeof (__redirect_memset) __memset_zva64 attribute_hidden;
+ extern __typeof (__redirect_memset) __memset_emag attribute_hidden;
+ extern __typeof (__redirect_memset) __memset_kunpeng attribute_hidden;
+ extern __typeof (__redirect_memset) __memset_a64fx attribute_hidden;
+@@ -47,18 +47,17 @@ select_memset_ifunc (void)
+ {
+ if (IS_A64FX (midr) && zva_size == 256)
+ return __memset_a64fx;
+- return __memset_generic;
+ }
+
+ if (IS_KUNPENG920 (midr))
+ return __memset_kunpeng;
+
+- if ((IS_FALKOR (midr) || IS_PHECDA (midr)) && zva_size == 64)
+- return __memset_falkor;
+-
+ if (IS_EMAG (midr))
+ return __memset_emag;
+
++ if (zva_size == 64)
++ return __memset_zva64;
++
+ return __memset_generic;
+ }
+
+diff --git a/sysdeps/aarch64/multiarch/memset_falkor.S b/sysdeps/aarch64/multiarch/memset_falkor.S
+deleted file mode 100644
+index c6946a8072..0000000000
+--- a/sysdeps/aarch64/multiarch/memset_falkor.S
++++ /dev/null
+@@ -1,54 +0,0 @@
+-/* Memset for falkor.
+- Copyright (C) 2017-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
+- <https://www.gnu.org/licenses/>. */
+-
+-#include <sysdep.h>
+-#include <memset-reg.h>
+-
+-/* Reading dczid_el0 is expensive on falkor so move it into the ifunc
+- resolver and assume ZVA size of 64 bytes. The IFUNC resolver takes care to
+- use this function only when ZVA is enabled. */
+-
+-#if IS_IN (libc)
+-.macro zva_macro
+- .p2align 4
+- /* Write the first and last 64 byte aligned block using stp rather
+- than using DC ZVA. This is faster on some cores. */
+- str q0, [dst, 16]
+- stp q0, q0, [dst, 32]
+- bic dst, dst, 63
+- stp q0, q0, [dst, 64]
+- stp q0, q0, [dst, 96]
+- sub count, dstend, dst /* Count is now 128 too large. */
+- sub count, count, 128+64+64 /* Adjust count and bias for loop. */
+- add dst, dst, 128
+-1: dc zva, dst
+- add dst, dst, 64
+- subs count, count, 64
+- b.hi 1b
+- stp q0, q0, [dst, 0]
+- stp q0, q0, [dst, 32]
+- stp q0, q0, [dstend, -64]
+- stp q0, q0, [dstend, -32]
+- ret
+-.endm
+-
+-# define ZVA_MACRO zva_macro
+-# define MEMSET __memset_falkor
+-# include <sysdeps/aarch64/memset.S>
+-#endif
+diff --git a/sysdeps/aarch64/multiarch/memset_zva64.S b/sysdeps/aarch64/multiarch/memset_zva64.S
+new file mode 100644
+index 0000000000..13f45fd3d8
+--- /dev/null
++++ b/sysdeps/aarch64/multiarch/memset_zva64.S
+@@ -0,0 +1,27 @@
++/* Optimized memset for zva size = 64.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++
++#define ZVA64_ONLY 1
++#define MEMSET __memset_zva64
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(X)
++
++#include "../memset.S"
+--
+2.33.0
+
diff --git a/0008-linux-Update-the-mremap-C-implementation-BZ-31968.patch b/0008-linux-Update-the-mremap-C-implementation-BZ-31968.patch
new file mode 100644
index 0000000..a63fefc
--- /dev/null
+++ b/0008-linux-Update-the-mremap-C-implementation-BZ-31968.patch
@@ -0,0 +1,68 @@
+From 0301637b9931766ee389aedf3899cde756b37283 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Wed, 24 Jul 2024 14:05:13 -0700
+Subject: [PATCH 08/12] linux: Update the mremap C implementation [BZ #31968]
+
+Update the mremap C implementation to support the optional argument for
+MREMAP_DONTUNMAP added in Linux 5.7 since it may not always be correct
+to implement a variadic function as a non-variadic function on all Linux
+targets. Return MAP_FAILED and set errno to EINVAL for unknown flag bits.
+This fixes BZ #31968.
+
+Note: A test must be added when a new flag bit is introduced.
+
+Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 6c40cb0e9f893d49dc7caee580a055de53562206)
+---
+ NEWS | 1 +
+ sysdeps/unix/sysv/linux/mremap.c | 14 +++++++++++++-
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/NEWS b/NEWS
+index 3b252c96b4..5172049eb2 100644
+--- a/NEWS
++++ b/NEWS
+@@ -55,6 +55,7 @@ The following bugs are resolved with this release:
+ [31476] resolv: Track single-request fallback via _res._flags
+ [31890] resolv: Allow short error responses to match any DNS query
+ [31965] rseq extension mechanism does not work as intended
++ [31968] mremap implementation in C does not handle arguments correctly
+
+
+ Version 2.38
+diff --git a/sysdeps/unix/sysv/linux/mremap.c b/sysdeps/unix/sysv/linux/mremap.c
+index 0ad5da86a2..05ed8febfa 100644
+--- a/sysdeps/unix/sysv/linux/mremap.c
++++ b/sysdeps/unix/sysv/linux/mremap.c
+@@ -20,6 +20,12 @@
+ #include <sysdep.h>
+ #include <stdarg.h>
+ #include <stddef.h>
++#include <errno.h>
++
++#define MREMAP_KNOWN_BITS \
++ (MREMAP_MAYMOVE \
++ | MREMAP_FIXED \
++ | MREMAP_DONTUNMAP)
+
+ void *
+ __mremap (void *addr, size_t old_len, size_t new_len, int flags, ...)
+@@ -27,7 +33,13 @@ __mremap (void *addr, size_t old_len, size_t new_len, int flags, ...)
+ va_list va;
+ void *new_addr = NULL;
+
+- if (flags & MREMAP_FIXED)
++ if (flags & ~(MREMAP_KNOWN_BITS))
++ {
++ __set_errno (EINVAL);
++ return MAP_FAILED;
++ }
++
++ if (flags & (MREMAP_FIXED | MREMAP_DONTUNMAP))
+ {
+ va_start (va, flags);
+ new_addr = va_arg (va, void *);
+--
+2.33.0
+
diff --git a/0008-sysdeps-tst-bz21269-fix-test-parameter.patch b/0008-sysdeps-tst-bz21269-fix-test-parameter.patch
new file mode 100644
index 0000000..b7c1eee
--- /dev/null
+++ b/0008-sysdeps-tst-bz21269-fix-test-parameter.patch
@@ -0,0 +1,31 @@
+From c8ecda6251dd4a0dfe074e0a6011211cadeef742 Mon Sep 17 00:00:00 2001
+From: Sam James <sam@gentoo.org>
+Date: Fri, 4 Aug 2023 23:58:27 +0100
+Subject: [PATCH 08/12] sysdeps: tst-bz21269: fix test parameter
+
+All callers pass 1 or 0x11 anyway (same meaning according to man page),
+but still.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+Signed-off-by: Sam James <sam@gentoo.org>
+(cherry picked from commit e0b712dd9183d527aae4506cd39564c14af3bb28)
+---
+ sysdeps/unix/sysv/linux/i386/tst-bz21269.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+index 51d4a1b082..f508ef8f16 100644
+--- a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
++++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+@@ -52,7 +52,7 @@ xset_thread_area (struct user_desc *u_info)
+ static void
+ xmodify_ldt (int func, const void *ptr, unsigned long bytecount)
+ {
+- TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, 1, ptr, bytecount) == 0);
++ TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, func, ptr, bytecount) == 0);
+ }
+
+ static int
+--
+2.33.0
+
diff --git a/0009-AArch64-Remove-Falkor-memcpy.patch b/0009-AArch64-Remove-Falkor-memcpy.patch
new file mode 100644
index 0000000..4efda02
--- /dev/null
+++ b/0009-AArch64-Remove-Falkor-memcpy.patch
@@ -0,0 +1,468 @@
+From a08ff922946dca0303a270bbfa2557f74caa47aa Mon Sep 17 00:00:00 2001
+From: Wilco Dijkstra <wilco.dijkstra@arm.com>
+Date: Thu, 26 Oct 2023 17:30:36 +0100
+Subject: [PATCH 09/26] AArch64: Remove Falkor memcpy
+
+The latest implementations of memcpy are actually faster than the Falkor
+implementations [1], so remove the falkor/phecda ifuncs for memcpy and
+the now unused IS_FALKOR/IS_PHECDA defines.
+
+[1] https://sourceware.org/pipermail/libc-alpha/2022-December/144227.html
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 2f5524cc5381eb75fef55f7901bb907bd5628333)
+---
+ manual/tunables.texi | 2 +-
+ sysdeps/aarch64/multiarch/Makefile | 1 -
+ sysdeps/aarch64/multiarch/ifunc-impl-list.c | 2 -
+ sysdeps/aarch64/multiarch/memcpy.c | 4 -
+ sysdeps/aarch64/multiarch/memcpy_falkor.S | 313 ------------------
+ sysdeps/aarch64/multiarch/memmove.c | 4 -
+ .../unix/sysv/linux/aarch64/cpu-features.c | 2 -
+ .../unix/sysv/linux/aarch64/cpu-features.h | 5 -
+ 8 files changed, 1 insertion(+), 332 deletions(-)
+ delete mode 100644 sysdeps/aarch64/multiarch/memcpy_falkor.S
+
+diff --git a/manual/tunables.texi b/manual/tunables.texi
+index 4ca0e42a11..bb17fef5bd 100644
+--- a/manual/tunables.texi
++++ b/manual/tunables.texi
+@@ -529,7 +529,7 @@ This tunable is specific to powerpc, powerpc64 and powerpc64le.
+ @deftp Tunable glibc.cpu.name
+ The @code{glibc.cpu.name=xxx} tunable allows the user to tell @theglibc{} to
+ assume that the CPU is @code{xxx} where xxx may have one of these values:
+-@code{generic}, @code{falkor}, @code{thunderxt88}, @code{thunderx2t99},
++@code{generic}, @code{thunderxt88}, @code{thunderx2t99},
+ @code{thunderx2t99p1}, @code{ares}, @code{emag}, @code{kunpeng},
+ @code{a64fx}.
+
+diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
+index 171ca5e4cf..e4720b7468 100644
+--- a/sysdeps/aarch64/multiarch/Makefile
++++ b/sysdeps/aarch64/multiarch/Makefile
+@@ -3,7 +3,6 @@ sysdep_routines += \
+ memchr_generic \
+ memchr_nosimd \
+ memcpy_a64fx \
+- memcpy_falkor \
+ memcpy_generic \
+ memcpy_mops \
+ memcpy_sve \
+diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+index fdd9ea9246..73038ac810 100644
+--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+@@ -36,7 +36,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL (i, name, memcpy,
+ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_thunderx)
+ IFUNC_IMPL_ADD (array, i, memcpy, !bti, __memcpy_thunderx2)
+- IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_falkor)
+ #if HAVE_AARCH64_SVE_ASM
+ IFUNC_IMPL_ADD (array, i, memcpy, sve, __memcpy_a64fx)
+ IFUNC_IMPL_ADD (array, i, memcpy, sve, __memcpy_sve)
+@@ -46,7 +45,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL (i, name, memmove,
+ IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_thunderx)
+ IFUNC_IMPL_ADD (array, i, memmove, !bti, __memmove_thunderx2)
+- IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_falkor)
+ #if HAVE_AARCH64_SVE_ASM
+ IFUNC_IMPL_ADD (array, i, memmove, sve, __memmove_a64fx)
+ IFUNC_IMPL_ADD (array, i, memmove, sve, __memmove_sve)
+diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
+index 9aace954cb..6471fe82e3 100644
+--- a/sysdeps/aarch64/multiarch/memcpy.c
++++ b/sysdeps/aarch64/multiarch/memcpy.c
+@@ -31,7 +31,6 @@ extern __typeof (__redirect_memcpy) __libc_memcpy;
+ extern __typeof (__redirect_memcpy) __memcpy_generic attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_thunderx attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_thunderx2 attribute_hidden;
+-extern __typeof (__redirect_memcpy) __memcpy_falkor attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_a64fx attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_sve attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_mops attribute_hidden;
+@@ -57,9 +56,6 @@ select_memcpy_ifunc (void)
+ if (IS_THUNDERX2 (midr) || IS_THUNDERX2PA (midr))
+ return __memcpy_thunderx2;
+
+- if (IS_FALKOR (midr) || IS_PHECDA (midr))
+- return __memcpy_falkor;
+-
+ return __memcpy_generic;
+ }
+
+diff --git a/sysdeps/aarch64/multiarch/memcpy_falkor.S b/sysdeps/aarch64/multiarch/memcpy_falkor.S
+deleted file mode 100644
+index 67c4ab34eb..0000000000
+--- a/sysdeps/aarch64/multiarch/memcpy_falkor.S
++++ /dev/null
+@@ -1,313 +0,0 @@
+-/* Optimized memcpy for Qualcomm Falkor processor.
+- Copyright (C) 2017-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
+- <https://www.gnu.org/licenses/>. */
+-
+-#include <sysdep.h>
+-
+-/* Assumptions:
+-
+- ARMv8-a, AArch64, falkor, unaligned accesses. */
+-
+-#define dstin x0
+-#define src x1
+-#define count x2
+-#define dst x3
+-#define srcend x4
+-#define dstend x5
+-#define tmp1 x14
+-#define A_x x6
+-#define B_x x7
+-#define A_w w6
+-#define B_w w7
+-
+-#define A_q q0
+-#define B_q q1
+-#define C_q q2
+-#define D_q q3
+-#define E_q q4
+-#define F_q q5
+-#define G_q q6
+-#define H_q q7
+-#define Q_q q6
+-#define S_q q22
+-
+-/* Copies are split into 3 main cases:
+-
+- 1. Small copies of up to 32 bytes
+- 2. Medium copies of 33..128 bytes which are fully unrolled
+- 3. Large copies of more than 128 bytes.
+-
+- Large copies align the source to a quad word and use an unrolled loop
+- processing 64 bytes per iteration.
+-
+- FALKOR-SPECIFIC DESIGN:
+-
+- The smallest copies (32 bytes or less) focus on optimal pipeline usage,
+- which is why the redundant copies of 0-3 bytes have been replaced with
+- conditionals, since the former would unnecessarily break across multiple
+- issue groups. The medium copy group has been enlarged to 128 bytes since
+- bumping up the small copies up to 32 bytes allows us to do that without
+- cost and also allows us to reduce the size of the prep code before loop64.
+-
+- The copy loop uses only one register q0. This is to ensure that all loads
+- hit a single hardware prefetcher which can get correctly trained to prefetch
+- a single stream.
+-
+- The non-temporal stores help optimize cache utilization. */
+-
+-#if IS_IN (libc)
+-ENTRY (__memcpy_falkor)
+-
+- PTR_ARG (0)
+- PTR_ARG (1)
+- SIZE_ARG (2)
+-
+- cmp count, 32
+- add srcend, src, count
+- add dstend, dstin, count
+- b.ls L(copy32)
+- cmp count, 128
+- b.hi L(copy_long)
+-
+- /* Medium copies: 33..128 bytes. */
+-L(copy128):
+- sub tmp1, count, 1
+- ldr A_q, [src]
+- ldr B_q, [src, 16]
+- ldr C_q, [srcend, -32]
+- ldr D_q, [srcend, -16]
+- tbz tmp1, 6, 1f
+- ldr E_q, [src, 32]
+- ldr F_q, [src, 48]
+- ldr G_q, [srcend, -64]
+- ldr H_q, [srcend, -48]
+- str G_q, [dstend, -64]
+- str H_q, [dstend, -48]
+- str E_q, [dstin, 32]
+- str F_q, [dstin, 48]
+-1:
+- str A_q, [dstin]
+- str B_q, [dstin, 16]
+- str C_q, [dstend, -32]
+- str D_q, [dstend, -16]
+- ret
+-
+- .p2align 4
+- /* Small copies: 0..32 bytes. */
+-L(copy32):
+- /* 16-32 */
+- cmp count, 16
+- b.lo 1f
+- ldr A_q, [src]
+- ldr B_q, [srcend, -16]
+- str A_q, [dstin]
+- str B_q, [dstend, -16]
+- ret
+- .p2align 4
+-1:
+- /* 8-15 */
+- tbz count, 3, 1f
+- ldr A_x, [src]
+- ldr B_x, [srcend, -8]
+- str A_x, [dstin]
+- str B_x, [dstend, -8]
+- ret
+- .p2align 4
+-1:
+- /* 4-7 */
+- tbz count, 2, 1f
+- ldr A_w, [src]
+- ldr B_w, [srcend, -4]
+- str A_w, [dstin]
+- str B_w, [dstend, -4]
+- ret
+- .p2align 4
+-1:
+- /* 2-3 */
+- tbz count, 1, 1f
+- ldrh A_w, [src]
+- ldrh B_w, [srcend, -2]
+- strh A_w, [dstin]
+- strh B_w, [dstend, -2]
+- ret
+- .p2align 4
+-1:
+- /* 0-1 */
+- tbz count, 0, 1f
+- ldrb A_w, [src]
+- strb A_w, [dstin]
+-1:
+- ret
+-
+- /* Align SRC to 16 bytes and copy; that way at least one of the
+- accesses is aligned throughout the copy sequence.
+-
+- The count is off by 0 to 15 bytes, but this is OK because we trim
+- off the last 64 bytes to copy off from the end. Due to this the
+- loop never runs out of bounds. */
+-
+- .p2align 4
+- nop /* Align loop64 below. */
+-L(copy_long):
+- ldr A_q, [src]
+- sub count, count, 64 + 16
+- and tmp1, src, 15
+- str A_q, [dstin]
+- bic src, src, 15
+- sub dst, dstin, tmp1
+- add count, count, tmp1
+-
+-L(loop64):
+- ldr A_q, [src, 16]!
+- str A_q, [dst, 16]
+- ldr A_q, [src, 16]!
+- subs count, count, 64
+- str A_q, [dst, 32]
+- ldr A_q, [src, 16]!
+- str A_q, [dst, 48]
+- ldr A_q, [src, 16]!
+- str A_q, [dst, 64]!
+- b.hi L(loop64)
+-
+- /* Write the last full set of 64 bytes. The remainder is at most 64
+- bytes, so it is safe to always copy 64 bytes from the end even if
+- there is just 1 byte left. */
+- ldr E_q, [srcend, -64]
+- str E_q, [dstend, -64]
+- ldr D_q, [srcend, -48]
+- str D_q, [dstend, -48]
+- ldr C_q, [srcend, -32]
+- str C_q, [dstend, -32]
+- ldr B_q, [srcend, -16]
+- str B_q, [dstend, -16]
+- ret
+-
+-END (__memcpy_falkor)
+-
+-
+-/* RATIONALE:
+-
+- The move has 4 distinct parts:
+- * Small moves of 32 bytes and under.
+- * Medium sized moves of 33-128 bytes (fully unrolled).
+- * Large moves where the source address is higher than the destination
+- (forward copies)
+- * Large moves where the destination address is higher than the source
+- (copy backward, or move).
+-
+- We use only two registers q6 and q22 for the moves and move 32 bytes at a
+- time to correctly train the hardware prefetcher for better throughput.
+-
+- For small and medium cases memcpy is used. */
+-
+-ENTRY (__memmove_falkor)
+-
+- PTR_ARG (0)
+- PTR_ARG (1)
+- SIZE_ARG (2)
+-
+- cmp count, 32
+- add srcend, src, count
+- add dstend, dstin, count
+- b.ls L(copy32)
+- cmp count, 128
+- b.ls L(copy128)
+- sub tmp1, dstin, src
+- ccmp tmp1, count, 2, hi
+- b.lo L(move_long)
+-
+- /* CASE: Copy Forwards
+-
+- Align src to 16 byte alignment so that we don't cross cache line
+- boundaries on both loads and stores. There are at least 128 bytes
+- to copy, so copy 16 bytes unaligned and then align. The loop
+- copies 32 bytes per iteration and prefetches one iteration ahead. */
+-
+- ldr S_q, [src]
+- and tmp1, src, 15
+- bic src, src, 15
+- sub dst, dstin, tmp1
+- add count, count, tmp1 /* Count is now 16 too large. */
+- ldr Q_q, [src, 16]!
+- str S_q, [dstin]
+- ldr S_q, [src, 16]!
+- sub count, count, 32 + 32 + 16 /* Test and readjust count. */
+-
+- .p2align 4
+-1:
+- subs count, count, 32
+- str Q_q, [dst, 16]
+- ldr Q_q, [src, 16]!
+- str S_q, [dst, 32]!
+- ldr S_q, [src, 16]!
+- b.hi 1b
+-
+- /* Copy 32 bytes from the end before writing the data prefetched in the
+- last loop iteration. */
+-2:
+- ldr B_q, [srcend, -32]
+- ldr C_q, [srcend, -16]
+- str Q_q, [dst, 16]
+- str S_q, [dst, 32]
+- str B_q, [dstend, -32]
+- str C_q, [dstend, -16]
+- ret
+-
+- /* CASE: Copy Backwards
+-
+- Align srcend to 16 byte alignment so that we don't cross cache line
+- boundaries on both loads and stores. There are at least 128 bytes
+- to copy, so copy 16 bytes unaligned and then align. The loop
+- copies 32 bytes per iteration and prefetches one iteration ahead. */
+-
+- .p2align 4
+- nop
+- nop
+-L(move_long):
+- cbz tmp1, 3f /* Return early if src == dstin */
+- ldr S_q, [srcend, -16]
+- and tmp1, srcend, 15
+- sub srcend, srcend, tmp1
+- ldr Q_q, [srcend, -16]!
+- str S_q, [dstend, -16]
+- sub count, count, tmp1
+- ldr S_q, [srcend, -16]!
+- sub dstend, dstend, tmp1
+- sub count, count, 32 + 32
+-
+-1:
+- subs count, count, 32
+- str Q_q, [dstend, -16]
+- ldr Q_q, [srcend, -16]!
+- str S_q, [dstend, -32]!
+- ldr S_q, [srcend, -16]!
+- b.hi 1b
+-
+- /* Copy 32 bytes from the start before writing the data prefetched in the
+- last loop iteration. */
+-
+- ldr B_q, [src, 16]
+- ldr C_q, [src]
+- str Q_q, [dstend, -16]
+- str S_q, [dstend, -32]
+- str B_q, [dstin, 16]
+- str C_q, [dstin]
+-3: ret
+-
+-END (__memmove_falkor)
+-#endif
+diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
+index fd346e7b73..7602a5d57d 100644
+--- a/sysdeps/aarch64/multiarch/memmove.c
++++ b/sysdeps/aarch64/multiarch/memmove.c
+@@ -31,7 +31,6 @@ extern __typeof (__redirect_memmove) __libc_memmove;
+ extern __typeof (__redirect_memmove) __memmove_generic attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_thunderx attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_thunderx2 attribute_hidden;
+-extern __typeof (__redirect_memmove) __memmove_falkor attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_a64fx attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_sve attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_mops attribute_hidden;
+@@ -57,9 +56,6 @@ select_memmove_ifunc (void)
+ if (IS_THUNDERX2 (midr) || IS_THUNDERX2PA (midr))
+ return __memmove_thunderx2;
+
+- if (IS_FALKOR (midr) || IS_PHECDA (midr))
+- return __memmove_falkor;
+-
+ return __memmove_generic;
+ }
+
+diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+index 233d5b2407..a11a86efab 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+@@ -37,11 +37,9 @@ struct cpu_list
+ };
+
+ static struct cpu_list cpu_list[] = {
+- {"falkor", 0x510FC000},
+ {"thunderxt88", 0x430F0A10},
+ {"thunderx2t99", 0x431F0AF0},
+ {"thunderx2t99p1", 0x420F5160},
+- {"phecda", 0x680F0000},
+ {"ares", 0x411FD0C0},
+ {"emag", 0x503F0001},
+ {"kunpeng920", 0x481FD010},
+diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+index 40b709677d..2cf745cd19 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+@@ -47,11 +47,6 @@
+ #define IS_THUNDERX2(midr) (MIDR_IMPLEMENTOR(midr) == 'C' \
+ && MIDR_PARTNUM(midr) == 0xaf)
+
+-#define IS_FALKOR(midr) (MIDR_IMPLEMENTOR(midr) == 'Q' \
+- && MIDR_PARTNUM(midr) == 0xc00)
+-
+-#define IS_PHECDA(midr) (MIDR_IMPLEMENTOR(midr) == 'h' \
+- && MIDR_PARTNUM(midr) == 0x000)
+ #define IS_NEOVERSE_N1(midr) (MIDR_IMPLEMENTOR(midr) == 'A' \
+ && MIDR_PARTNUM(midr) == 0xd0c)
+ #define IS_NEOVERSE_N2(midr) (MIDR_IMPLEMENTOR(midr) == 'A' \
+--
+2.33.0
+
diff --git a/0009-mremap-Update-manual-entry.patch b/0009-mremap-Update-manual-entry.patch
new file mode 100644
index 0000000..8d47fda
--- /dev/null
+++ b/0009-mremap-Update-manual-entry.patch
@@ -0,0 +1,88 @@
+From f0e211453546a134ac27e1e54579332534acb349 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Wed, 24 Jul 2024 14:05:14 -0700
+Subject: [PATCH 09/12] mremap: Update manual entry
+
+Update mremap manual entry:
+
+1. Change mremap to variadic.
+2. Document MREMAP_FIXED and MREMAP_DONTUNMAP.
+
+Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit cb2dee4eccf46642eef588bee64f9c875c408f1c)
+---
+ manual/llio.texi | 42 +++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 35 insertions(+), 7 deletions(-)
+
+diff --git a/manual/llio.texi b/manual/llio.texi
+index fae49d1433..a65230d612 100644
+--- a/manual/llio.texi
++++ b/manual/llio.texi
+@@ -1781,7 +1781,7 @@ There is no existing mapping in at least part of the given region.
+
+ @end deftypefun
+
+-@deftypefun {void *} mremap (void *@var{address}, size_t @var{length}, size_t @var{new_length}, int @var{flag})
++@deftypefun {void *} mremap (void *@var{address}, size_t @var{length}, size_t @var{new_length}, int @var{flag}, ... /* void *@var{new_address} */)
+ @standards{GNU, sys/mman.h}
+ @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+@@ -1790,12 +1790,40 @@ area. @var{address} and @var{length} must cover a region entirely mapped
+ in the same @code{mmap} statement. A new mapping with the same
+ characteristics will be returned with the length @var{new_length}.
+
+-One option is possible, @code{MREMAP_MAYMOVE}. If it is given in
+-@var{flags}, the system may remove the existing mapping and create a new
+-one of the desired length in another location.
++Possible flags are
+
+-The address of the resulting mapping is returned, or @math{-1}. Possible
+-error codes include:
++@table @code
++
++@item MREMAP_MAYMOVE
++If it is given in @var{flags}, the system may remove the existing mapping
++and create a new one of the desired length in another location.
++
++@item MREMAP_FIXED
++If it is given in @var{flags}, @code{mremap} accepts a fifth argument,
++@code{void *new_address}, which specifies a page-aligned address to
++which the mapping must be moved. Any previous mapping at the address
++range specified by @var{new_address} and @var{new_size} is unmapped.
++
++@code{MREMAP_FIXED} must be used together with @code{MREMAP_MAYMOVE}.
++
++@item MREMAP_DONTUNMAP
++If it is given in @var{flags}, @code{mremap} accepts a fifth argument,
++@code{void *new_address}, which specifies a page-aligned address. Any
++previous mapping at the address range specified by @var{new_address} and
++@var{new_size} is unmapped. If @var{new_address} is @code{NULL}, the
++kernel chooses the page-aligned address at which to create the mapping.
++Otherwise, the kernel takes it as a hint about where to place the mapping.
++The mapping at the address range specified by @var{old_address} and
++@var{old_size} isn't unmapped.
++
++@code{MREMAP_DONTUNMAP} must be used together with @code{MREMAP_MAYMOVE}.
++@var{old_size} must be the same as @var{new_size}. This flag bit is
++Linux-specific.
++
++@end table
++
++The address of the resulting mapping is returned, or @code{MAP_FAILED}.
++Possible error codes include:
+
+ @table @code
+
+@@ -1804,7 +1832,7 @@ There is no existing mapping in at least part of the original region, or
+ the region covers two or more distinct mappings.
+
+ @item EINVAL
+-The address given is misaligned or inappropriate.
++Any arguments are inappropriate, including unknown @var{flags} values.
+
+ @item EAGAIN
+ The region has pages locked, and if extended it would exceed the
+--
+2.33.0
+
diff --git a/0009-sysdeps-tst-bz21269-handle-ENOSYS-skip-appropriately.patch b/0009-sysdeps-tst-bz21269-handle-ENOSYS-skip-appropriately.patch
new file mode 100644
index 0000000..986eb98
--- /dev/null
+++ b/0009-sysdeps-tst-bz21269-handle-ENOSYS-skip-appropriately.patch
@@ -0,0 +1,42 @@
+From ad9b8399537670a990572c4b0c4da5411e3b68cf Mon Sep 17 00:00:00 2001
+From: Sam James <sam@gentoo.org>
+Date: Sat, 5 Aug 2023 00:04:33 +0100
+Subject: [PATCH 09/12] sysdeps: tst-bz21269: handle ENOSYS & skip
+ appropriately
+
+SYS_modify_ldt requires CONFIG_MODIFY_LDT_SYSCALL to be set in the kernel, which
+some distributions may disable for hardening. Check if that's the case (unset)
+and mark the test as UNSUPPORTED if so.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+Signed-off-by: Sam James <sam@gentoo.org>
+(cherry picked from commit 652b9fdb77d9fd056d4dd26dad2c14142768ab49)
+---
+ sysdeps/unix/sysv/linux/i386/tst-bz21269.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+index f508ef8f16..28f5359bea 100644
+--- a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
++++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+@@ -52,7 +52,16 @@ xset_thread_area (struct user_desc *u_info)
+ static void
+ xmodify_ldt (int func, const void *ptr, unsigned long bytecount)
+ {
+- TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, func, ptr, bytecount) == 0);
++ long ret = syscall (SYS_modify_ldt, func, ptr, bytecount);
++
++ if (ret == -1)
++ {
++ if (errno == ENOSYS)
++ FAIL_UNSUPPORTED ("modify_ldt not supported");
++ FAIL_EXIT1 ("modify_ldt failed (errno=%d)", errno);
++ }
++
++ return 0;
+ }
+
+ static int
+--
+2.33.0
+
diff --git a/0010-Add-mremap-tests.patch b/0010-Add-mremap-tests.patch
new file mode 100644
index 0000000..e63fb93
--- /dev/null
+++ b/0010-Add-mremap-tests.patch
@@ -0,0 +1,302 @@
+From 6bb75212e6198cd14ab9d1d538a61fa9cdec31d1 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Wed, 24 Jul 2024 14:05:15 -0700
+Subject: [PATCH 10/12] Add mremap tests
+
+Add tests for MREMAP_MAYMOVE and MREMAP_FIXED. On Linux, also test
+MREMAP_DONTUNMAP.
+
+Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit ff0320bec2810192d453c579623482fab87bfa01)
+---
+ misc/Makefile | 2 +
+ misc/tst-mremap1.c | 46 +++++++++++++++
+ misc/tst-mremap2.c | 54 ++++++++++++++++++
+ sysdeps/generic/mremap-failure.h | 25 ++++++++
+ sysdeps/unix/sysv/linux/Makefile | 1 +
+ sysdeps/unix/sysv/linux/mremap-failure.h | 30 ++++++++++
+ sysdeps/unix/sysv/linux/tst-linux-mremap1.c | 63 +++++++++++++++++++++
+ 7 files changed, 221 insertions(+)
+ create mode 100644 misc/tst-mremap1.c
+ create mode 100644 misc/tst-mremap2.c
+ create mode 100644 sysdeps/generic/mremap-failure.h
+ create mode 100644 sysdeps/unix/sysv/linux/mremap-failure.h
+ create mode 100644 sysdeps/unix/sysv/linux/tst-linux-mremap1.c
+
+diff --git a/misc/Makefile b/misc/Makefile
+index 90b31952c5..87778a538a 100644
+--- a/misc/Makefile
++++ b/misc/Makefile
+@@ -251,6 +251,8 @@ tests := \
+ tst-mntent-blank-passno \
+ tst-mntent-escape \
+ tst-mntent2 \
++ tst-mremap1 \
++ tst-mremap2 \
+ tst-preadvwritev \
+ tst-preadvwritev2 \
+ tst-preadvwritev64 \
+diff --git a/misc/tst-mremap1.c b/misc/tst-mremap1.c
+new file mode 100644
+index 0000000000..0469991a6c
+--- /dev/null
++++ b/misc/tst-mremap1.c
+@@ -0,0 +1,46 @@
++/* Test mremap with MREMAP_MAYMOVE.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <support/xstdlib.h>
++#include <support/xunistd.h>
++#include <support/check.h>
++#include <support/test-driver.h>
++
++static int
++do_test (void)
++{
++ size_t old_size = getpagesize ();
++ char *old_addr = xmmap (NULL, old_size, PROT_READ | PROT_WRITE,
++ MAP_PRIVATE | MAP_ANONYMOUS, -1);
++ old_addr[0] = 1;
++ old_addr[old_size - 1] = 2;
++
++ /* Test MREMAP_MAYMOVE. */
++ size_t new_size = old_size + old_size;
++ char *new_addr = mremap (old_addr, old_size, new_size, MREMAP_MAYMOVE);
++ TEST_VERIFY_EXIT (new_addr != MAP_FAILED);
++ new_addr[0] = 1;
++ new_addr[new_size - 1] = 2;
++ xmunmap (new_addr, new_size);
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/misc/tst-mremap2.c b/misc/tst-mremap2.c
+new file mode 100644
+index 0000000000..45be7f0369
+--- /dev/null
++++ b/misc/tst-mremap2.c
+@@ -0,0 +1,54 @@
++/* Test mremap with MREMAP_FIXED.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <support/xstdlib.h>
++#include <support/xunistd.h>
++#include <support/test-driver.h>
++#include <mremap-failure.h>
++
++static int
++do_test (void)
++{
++ size_t old_size = getpagesize ();
++ size_t new_size = old_size + old_size;
++ char *old_addr = xmmap (NULL, old_size, PROT_READ | PROT_WRITE,
++ MAP_PRIVATE | MAP_ANONYMOUS, -1);
++ old_addr[0] = 1;
++ old_addr[old_size - 1] = 2;
++
++ char *fixed_addr = xmmap (NULL, new_size, PROT_READ | PROT_WRITE,
++ MAP_PRIVATE | MAP_ANONYMOUS, -1);
++ fixed_addr[0] = 1;
++ fixed_addr[new_size - 1] = 2;
++
++ /* Test MREMAP_FIXED. */
++ char *new_addr = mremap (old_addr, old_size, new_size,
++ MREMAP_FIXED | MREMAP_MAYMOVE,
++ fixed_addr);
++ if (new_addr == MAP_FAILED)
++ return mremap_failure_exit (errno);
++ new_addr[0] = 1;
++ new_addr[new_size - 1] = 2;
++ xmunmap (new_addr, new_size);
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/generic/mremap-failure.h b/sysdeps/generic/mremap-failure.h
+new file mode 100644
+index 0000000000..bc0d476368
+--- /dev/null
++++ b/sysdeps/generic/mremap-failure.h
+@@ -0,0 +1,25 @@
++/* mremap failure handling. Generic version.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++/* Return exit value on mremap failure with errno ERR. */
++
++static int
++mremap_failure_exit (int err)
++{
++ return EXIT_FAILURE;
++}
+diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
+index 623a7d4de0..9b503c8379 100644
+--- a/sysdeps/unix/sysv/linux/Makefile
++++ b/sysdeps/unix/sysv/linux/Makefile
+@@ -202,6 +202,7 @@ tests += \
+ tst-getauxval \
+ tst-gettid \
+ tst-gettid-kill \
++ tst-linux-mremap1 \
+ tst-memfd_create \
+ tst-misalign-clone \
+ tst-mlock2 \
+diff --git a/sysdeps/unix/sysv/linux/mremap-failure.h b/sysdeps/unix/sysv/linux/mremap-failure.h
+new file mode 100644
+index 0000000000..c99ab30ca9
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/mremap-failure.h
+@@ -0,0 +1,30 @@
++/* mremap failure handling. Linux version.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <support/check.h>
++
++/* Return exit value on mremap failure with errno ERR. */
++
++static int
++mremap_failure_exit (int err)
++{
++ if (err != EINVAL)
++ return EXIT_FAILURE;
++
++ return EXIT_UNSUPPORTED;
++}
+diff --git a/sysdeps/unix/sysv/linux/tst-linux-mremap1.c b/sysdeps/unix/sysv/linux/tst-linux-mremap1.c
+new file mode 100644
+index 0000000000..408e8af2ab
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/tst-linux-mremap1.c
+@@ -0,0 +1,63 @@
++/* Test mremap with MREMAP_DONTUNMAP.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <support/xstdlib.h>
++#include <support/xunistd.h>
++#include <support/check.h>
++#include <support/test-driver.h>
++#include <mremap-failure.h>
++
++static int
++do_test (void)
++{
++ size_t old_size = getpagesize ();
++ size_t new_size = old_size;
++ char *old_addr = xmmap (NULL, old_size, PROT_READ | PROT_WRITE,
++ MAP_PRIVATE | MAP_ANONYMOUS, -1);
++ old_addr[0] = 1;
++ old_addr[old_size - 1] = 2;
++
++ /* Create an available 64-page mmap region. */
++ size_t fixed_size = old_size * 64;
++ char *fixed_addr = xmmap (NULL, fixed_size, PROT_READ | PROT_WRITE,
++ MAP_PRIVATE | MAP_ANONYMOUS, -1);
++ xmunmap (fixed_addr, fixed_size);
++
++ /* Add 3 * pagesize. */
++ fixed_size += 3 * old_size;
++
++ /* Test MREMAP_DONTUNMAP. It should return FIXED_ADDR created above. */
++ char *new_addr = mremap (old_addr, old_size, new_size,
++ MREMAP_DONTUNMAP | MREMAP_MAYMOVE,
++ fixed_addr);
++ if (new_addr == MAP_FAILED)
++ return mremap_failure_exit (errno);
++ TEST_VERIFY_EXIT (fixed_addr == new_addr);
++ old_addr[0] = 3;
++ old_addr[old_size - 1] = 4;
++ new_addr[0] = 1;
++ new_addr[new_size - 1] = 2;
++ xmunmap (new_addr, new_size);
++ xmunmap (old_addr, old_size);
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.33.0
+
diff --git a/0010-aarch64-correct-CFI-in-rawmemchr-bug-31113.patch b/0010-aarch64-correct-CFI-in-rawmemchr-bug-31113.patch
new file mode 100644
index 0000000..b260311
--- /dev/null
+++ b/0010-aarch64-correct-CFI-in-rawmemchr-bug-31113.patch
@@ -0,0 +1,31 @@
+From 168ae58e6e705a53a71850ee63ba5514fd5d7b70 Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@suse.de>
+Date: Thu, 23 Nov 2023 18:23:46 +0100
+Subject: [PATCH 10/26] aarch64: correct CFI in rawmemchr (bug 31113)
+
+The .cfi_return_column directive changes the return column for the whole
+FDE range. But the actual intent is to tell the unwinder that the value
+in x30 (lr) now resides in x15 after the move, and that is expressed by
+the .cfi_register directive.
+
+(cherry picked from commit 3f798427884fa57770e8e2291cf58d5918254bb5)
+---
+ sysdeps/aarch64/rawmemchr.S | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sysdeps/aarch64/rawmemchr.S b/sysdeps/aarch64/rawmemchr.S
+index efc4b7007b..1fff094215 100644
+--- a/sysdeps/aarch64/rawmemchr.S
++++ b/sysdeps/aarch64/rawmemchr.S
+@@ -31,7 +31,7 @@ ENTRY (__rawmemchr)
+
+ L(do_strlen):
+ mov x15, x30
+- cfi_return_column (x15)
++ cfi_register (x30, x15)
+ mov x14, x0
+ bl __strlen
+ add x0, x14, x0
+--
+2.33.0
+
diff --git a/0010-sysdeps-tst-bz21269-fix-Wreturn-type.patch b/0010-sysdeps-tst-bz21269-fix-Wreturn-type.patch
new file mode 100644
index 0000000..e329830
--- /dev/null
+++ b/0010-sysdeps-tst-bz21269-fix-Wreturn-type.patch
@@ -0,0 +1,30 @@
+From 1aed90c9c8f8be9f68b58e96b6e4cd0fc08eb2b1 Mon Sep 17 00:00:00 2001
+From: Sam James <sam@gentoo.org>
+Date: Thu, 17 Aug 2023 09:30:29 +0100
+Subject: [PATCH 10/12] sysdeps: tst-bz21269: fix -Wreturn-type
+
+Thanks to Andreas Schwab for reporting.
+
+Fixes: 652b9fdb77d9fd056d4dd26dad2c14142768ab49
+Signed-off-by: Sam James <sam@gentoo.org>
+(cherry picked from commit 369f373057073c307938da91af16922bda3dff6a)
+---
+ sysdeps/unix/sysv/linux/i386/tst-bz21269.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+index 28f5359bea..822c41fceb 100644
+--- a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
++++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+@@ -60,8 +60,6 @@ xmodify_ldt (int func, const void *ptr, unsigned long bytecount)
+ FAIL_UNSUPPORTED ("modify_ldt not supported");
+ FAIL_EXIT1 ("modify_ldt failed (errno=%d)", errno);
+ }
+-
+- return 0;
+ }
+
+ static int
+--
+2.33.0
+
diff --git a/0011-Update-syscall-lists-for-Linux-6.5.patch b/0011-Update-syscall-lists-for-Linux-6.5.patch
new file mode 100644
index 0000000..b7db5ca
--- /dev/null
+++ b/0011-Update-syscall-lists-for-Linux-6.5.patch
@@ -0,0 +1,394 @@
+From 3ac7ba61d2d4a914b64a1d793857b84f6a875fa0 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Tue, 12 Sep 2023 14:08:53 +0000
+Subject: [PATCH 11/12] Update syscall lists for Linux 6.5
+
+Linux 6.5 has one new syscall, cachestat, and also enables the
+cacheflush syscall for hppa. 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 72511f539cc34681ec61c6a0dc2fe6d684760ffe)
+---
+ sysdeps/unix/sysv/linux/aarch64/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/alpha/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/arc/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/arm/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/csky/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/hppa/arch-syscall.h | 2 ++
+ sysdeps/unix/sysv/linux/i386/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/ia64/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/loongarch/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/m68k/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/microblaze/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/nios2/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/or1k/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/sh/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/syscall-names.list | 5 +++--
+ sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h | 1 +
+ sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h | 1 +
+ 28 files changed, 31 insertions(+), 2 deletions(-)
+
+diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
+index 4fcb6da80a..8f21ee66a0 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
+@@ -7,6 +7,7 @@
+ #define __NR_bind 200
+ #define __NR_bpf 280
+ #define __NR_brk 214
++#define __NR_cachestat 451
+ #define __NR_capget 90
+ #define __NR_capset 91
+ #define __NR_chdir 49
+diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
+index 0cf74c1a96..c5802a5fec 100644
+--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
+@@ -11,6 +11,7 @@
+ #define __NR_bind 104
+ #define __NR_bpf 515
+ #define __NR_brk 17
++#define __NR_cachestat 561
+ #define __NR_capget 368
+ #define __NR_capset 369
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
+index c1207aaa12..f23f9e1154 100644
+--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
+@@ -11,6 +11,7 @@
+ #define __NR_bpf 280
+ #define __NR_brk 214
+ #define __NR_cacheflush 244
++#define __NR_cachestat 451
+ #define __NR_capget 90
+ #define __NR_capset 91
+ #define __NR_chdir 49
+diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
+index e7ba04c106..7edf574899 100644
+--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
+@@ -15,6 +15,7 @@
+ #define __NR_bpf 386
+ #define __NR_brk 45
+ #define __NR_cacheflush 983042
++#define __NR_cachestat 451
+ #define __NR_capget 184
+ #define __NR_capset 185
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
+index dc9383758e..d74a06e063 100644
+--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
+@@ -8,6 +8,7 @@
+ #define __NR_bpf 280
+ #define __NR_brk 214
+ #define __NR_cacheflush 245
++#define __NR_cachestat 451
+ #define __NR_capget 90
+ #define __NR_capset 91
+ #define __NR_chdir 49
+diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
+index 767f1287a3..5568b94cd3 100644
+--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
+@@ -13,6 +13,8 @@
+ #define __NR_bind 22
+ #define __NR_bpf 341
+ #define __NR_brk 45
++#define __NR_cacheflush 356
++#define __NR_cachestat 451
+ #define __NR_capget 106
+ #define __NR_capset 107
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
+index 1998f0d76a..3af21a15cb 100644
+--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
+@@ -15,6 +15,7 @@
+ #define __NR_bpf 357
+ #define __NR_break 17
+ #define __NR_brk 45
++#define __NR_cachestat 451
+ #define __NR_capget 184
+ #define __NR_capset 185
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
+index b2eab1b93d..39b270e642 100644
+--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
+@@ -11,6 +11,7 @@
+ #define __NR_bind 1191
+ #define __NR_bpf 1341
+ #define __NR_brk 1060
++#define __NR_cachestat 1475
+ #define __NR_capget 1185
+ #define __NR_capset 1186
+ #define __NR_chdir 1034
+diff --git a/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h b/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h
+index 6bb3c8adbc..fdefe8bb6f 100644
+--- a/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h
+@@ -7,6 +7,7 @@
+ #define __NR_bind 200
+ #define __NR_bpf 280
+ #define __NR_brk 214
++#define __NR_cachestat 451
+ #define __NR_capget 90
+ #define __NR_capset 91
+ #define __NR_chdir 49
+diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
+index 5fc3723772..315e49cd33 100644
+--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
+@@ -15,6 +15,7 @@
+ #define __NR_bpf 354
+ #define __NR_brk 45
+ #define __NR_cacheflush 123
++#define __NR_cachestat 451
+ #define __NR_capget 184
+ #define __NR_capset 185
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
+index b6e9b007e4..54af12780c 100644
+--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
+@@ -15,6 +15,7 @@
+ #define __NR_bpf 387
+ #define __NR_break 17
+ #define __NR_brk 45
++#define __NR_cachestat 451
+ #define __NR_capget 184
+ #define __NR_capset 185
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
+index b3a3871f8a..a2aa1ffa1b 100644
+--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
+@@ -17,6 +17,7 @@
+ #define __NR_brk 4045
+ #define __NR_cachectl 4148
+ #define __NR_cacheflush 4147
++#define __NR_cachestat 4451
+ #define __NR_capget 4204
+ #define __NR_capset 4205
+ #define __NR_chdir 4012
+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 b462182723..5bec858040 100644
+--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
+@@ -14,6 +14,7 @@
+ #define __NR_brk 6012
+ #define __NR_cachectl 6198
+ #define __NR_cacheflush 6197
++#define __NR_cachestat 6451
+ #define __NR_capget 6123
+ #define __NR_capset 6124
+ #define __NR_chdir 6078
+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 a9d6b94572..0166371ee2 100644
+--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
+@@ -14,6 +14,7 @@
+ #define __NR_brk 5012
+ #define __NR_cachectl 5198
+ #define __NR_cacheflush 5197
++#define __NR_cachestat 5451
+ #define __NR_capget 5123
+ #define __NR_capset 5124
+ #define __NR_chdir 5078
+diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
+index 809a219ef3..29a4cfa988 100644
+--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
+@@ -8,6 +8,7 @@
+ #define __NR_bpf 280
+ #define __NR_brk 214
+ #define __NR_cacheflush 244
++#define __NR_cachestat 451
+ #define __NR_capget 90
+ #define __NR_capset 91
+ #define __NR_chdir 49
+diff --git a/sysdeps/unix/sysv/linux/or1k/arch-syscall.h b/sysdeps/unix/sysv/linux/or1k/arch-syscall.h
+index 1364f4cbc0..f5a3729663 100644
+--- a/sysdeps/unix/sysv/linux/or1k/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/or1k/arch-syscall.h
+@@ -7,6 +7,7 @@
+ #define __NR_bind 200
+ #define __NR_bpf 280
+ #define __NR_brk 214
++#define __NR_cachestat 451
+ #define __NR_capget 90
+ #define __NR_capset 91
+ #define __NR_chdir 49
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
+index 627831ebae..3a212a0269 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
+@@ -15,6 +15,7 @@
+ #define __NR_bpf 361
+ #define __NR_break 17
+ #define __NR_brk 45
++#define __NR_cachestat 451
+ #define __NR_capget 183
+ #define __NR_capset 184
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
+index bae597199d..1038ead227 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
+@@ -15,6 +15,7 @@
+ #define __NR_bpf 361
+ #define __NR_break 17
+ #define __NR_brk 45
++#define __NR_cachestat 451
+ #define __NR_capget 183
+ #define __NR_capset 184
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+index 2416e041c8..57b043ffb5 100644
+--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+@@ -6,6 +6,7 @@
+ #define __NR_bind 200
+ #define __NR_bpf 280
+ #define __NR_brk 214
++#define __NR_cachestat 451
+ #define __NR_capget 90
+ #define __NR_capset 91
+ #define __NR_chdir 49
+diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+index a32bc82f60..1041a0f8c9 100644
+--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+@@ -7,6 +7,7 @@
+ #define __NR_bind 200
+ #define __NR_bpf 280
+ #define __NR_brk 214
++#define __NR_cachestat 451
+ #define __NR_capget 90
+ #define __NR_capset 91
+ #define __NR_chdir 49
+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 2288f20e45..70d4c6782e 100644
+--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
+@@ -13,6 +13,7 @@
+ #define __NR_bind 361
+ #define __NR_bpf 351
+ #define __NR_brk 45
++#define __NR_cachestat 451
+ #define __NR_capget 184
+ #define __NR_capset 185
+ #define __NR_chdir 12
+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 05e6d8428e..65a8a9e316 100644
+--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
+@@ -11,6 +11,7 @@
+ #define __NR_bind 361
+ #define __NR_bpf 351
+ #define __NR_brk 45
++#define __NR_cachestat 451
+ #define __NR_capget 184
+ #define __NR_capset 185
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
+index d52b522d9c..94aad0f119 100644
+--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
+@@ -14,6 +14,7 @@
+ #define __NR_bpf 375
+ #define __NR_brk 45
+ #define __NR_cacheflush 123
++#define __NR_cachestat 451
+ #define __NR_capget 184
+ #define __NR_capset 185
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
+index d3f4d8aa3e..d630306c75 100644
+--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
+@@ -14,6 +14,7 @@
+ #define __NR_bind 353
+ #define __NR_bpf 349
+ #define __NR_brk 17
++#define __NR_cachestat 451
+ #define __NR_capget 21
+ #define __NR_capset 22
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
+index 2cc03d7a24..930f29b4d2 100644
+--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
+@@ -14,6 +14,7 @@
+ #define __NR_bind 353
+ #define __NR_bpf 349
+ #define __NR_brk 17
++#define __NR_cachestat 451
+ #define __NR_capget 21
+ #define __NR_capset 22
+ #define __NR_chdir 12
+diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
+index 5b69106434..cf6f70ecd9 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 6.4.
+-kernel 6.4
++# The list of system calls is current as of Linux 6.5.
++kernel 6.5
+
+ FAST_atomic_update
+ FAST_cmpxchg
+@@ -58,6 +58,7 @@ breakpoint
+ brk
+ cachectl
+ cacheflush
++cachestat
+ capget
+ capset
+ chdir
+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 b4ab892ec1..58646cf0bd 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
+@@ -12,6 +12,7 @@
+ #define __NR_bind 49
+ #define __NR_bpf 321
+ #define __NR_brk 12
++#define __NR_cachestat 451
+ #define __NR_capget 125
+ #define __NR_capset 126
+ #define __NR_chdir 80
+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 772559c87b..604bcdfa5b 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
+@@ -11,6 +11,7 @@
+ #define __NR_bind 1073741873
+ #define __NR_bpf 1073742145
+ #define __NR_brk 1073741836
++#define __NR_cachestat 1073742275
+ #define __NR_capget 1073741949
+ #define __NR_capset 1073741950
+ #define __NR_chdir 1073741904
+--
+2.33.0
+
diff --git a/0011-aarch64-fix-check-for-SVE-support-in-assembler.patch b/0011-aarch64-fix-check-for-SVE-support-in-assembler.patch
new file mode 100644
index 0000000..ecc3b27
--- /dev/null
+++ b/0011-aarch64-fix-check-for-SVE-support-in-assembler.patch
@@ -0,0 +1,61 @@
+From 1bf17ce978da71431dbd1fc3660cfae3dff0672f Mon Sep 17 00:00:00 2001
+From: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date: Wed, 13 Mar 2024 14:34:14 +0000
+Subject: [PATCH 11/26] aarch64: fix check for SVE support in assembler
+
+Due to GCC bug 110901 -mcpu can override -march setting when compiling
+asm code and thus a compiler targetting a specific cpu can fail the
+configure check even when binutils gas supports SVE.
+
+The workaround is that explicit .arch directive overrides both -mcpu
+and -march, and since that's what the actual SVE memcpy uses the
+configure check should use that too even if the GCC issue is fixed
+independently.
+
+Reviewed-by: Florian Weimer <fweimer@redhat.com>
+(cherry picked from commit 73c26018ed0ecd9c807bb363cc2c2ab4aca66a82)
+---
+ sysdeps/aarch64/configure | 5 +++--
+ sysdeps/aarch64/configure.ac | 5 +++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+ mode change 100644 => 100755 sysdeps/aarch64/configure
+
+diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
+old mode 100644
+new mode 100755
+index ca57edce47..9606137e8d
+--- a/sysdeps/aarch64/configure
++++ b/sysdeps/aarch64/configure
+@@ -325,9 +325,10 @@ then :
+ printf %s "(cached) " >&6
+ else $as_nop
+ cat > conftest.s <<\EOF
+- ptrue p0.b
++ .arch armv8.2-a+sve
++ ptrue p0.b
+ EOF
+-if { ac_try='${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&5'
++if { ac_try='${CC-cc} -c conftest.s 1>&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
+index 27874eceb4..56d12d661d 100644
+--- a/sysdeps/aarch64/configure.ac
++++ b/sysdeps/aarch64/configure.ac
+@@ -90,9 +90,10 @@ LIBC_CONFIG_VAR([aarch64-variant-pcs], [$libc_cv_aarch64_variant_pcs])
+ # Check if asm support armv8.2-a+sve
+ AC_CACHE_CHECK([for SVE support in assembler], [libc_cv_aarch64_sve_asm], [dnl
+ cat > conftest.s <<\EOF
+- ptrue p0.b
++ .arch armv8.2-a+sve
++ ptrue p0.b
+ EOF
+-if AC_TRY_COMMAND(${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&AS_MESSAGE_LOG_FD); then
++if AC_TRY_COMMAND(${CC-cc} -c conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_aarch64_sve_asm=yes
+ else
+ libc_cv_aarch64_sve_asm=no
+--
+2.33.0
+
diff --git a/0011-io-Fix-record-locking-contants-for-powerpc64-with-__.patch b/0011-io-Fix-record-locking-contants-for-powerpc64-with-__.patch
new file mode 100644
index 0000000..1e9a5c3
--- /dev/null
+++ b/0011-io-Fix-record-locking-contants-for-powerpc64-with-__.patch
@@ -0,0 +1,91 @@
+From 5bdef6f27c91f45505ed5444147be4ed0e9bc3c7 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien@aurel32.net>
+Date: Mon, 28 Aug 2023 23:30:37 +0200
+Subject: [PATCH 11/12] io: Fix record locking contants for powerpc64 with
+ __USE_FILE_OFFSET64
+
+Commit 5f828ff824e3b7cd1 ("io: Fix F_GETLK, F_SETLK, and F_SETLKW for
+powerpc64") fixed an issue with the value of the lock constants on
+powerpc64 when not using __USE_FILE_OFFSET64, but it ended-up also
+changing the value when using __USE_FILE_OFFSET64 causing an API change.
+
+Fix that by also checking that define, restoring the pre
+4d0fe291aed3a476a commit values:
+
+Default values:
+- F_GETLK: 5
+- F_SETLK: 6
+- F_SETLKW: 7
+
+With -D_FILE_OFFSET_BITS=64:
+- F_GETLK: 12
+- F_SETLK: 13
+- F_SETLKW: 14
+
+At the same time, it has been noticed that there was no test for io lock
+with __USE_FILE_OFFSET64, so just add one.
+
+Tested on x86_64-linux-gnu, i686-linux-gnu and
+powerpc64le-unknown-linux-gnu.
+
+Resolves: BZ #30804.
+Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+(cherry picked from commit 434bf72a94de68f0cc7fbf3c44bf38c1911b70cb)
+---
+ NEWS | 2 ++
+ io/Makefile | 1 +
+ io/tst-fcntl-lock-lfs.c | 2 ++
+ sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h | 2 +-
+ 4 files changed, 6 insertions(+), 1 deletion(-)
+ create mode 100644 io/tst-fcntl-lock-lfs.c
+
+diff --git a/NEWS b/NEWS
+index c339cb444e..8156572cdf 100644
+--- a/NEWS
++++ b/NEWS
+@@ -133,6 +133,8 @@ The following bugs are resolved with this release:
+ [30579] malloc: trim_threshold in realloc lead to high memory usage
+ [30662] nscd: Group and password cache use errno in place of errval
+ [30723] posix_memalign repeatedly scans long bin lists
++ [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
++ -D_FILE_OFFSET_BITS=64
+
+ Version 2.37
+
+diff --git a/io/Makefile b/io/Makefile
+index 6ccc0e8691..8a3c83a3bb 100644
+--- a/io/Makefile
++++ b/io/Makefile
+@@ -192,6 +192,7 @@ tests := \
+ tst-fchownat \
+ tst-fcntl \
+ tst-fcntl-lock \
++ tst-fcntl-lock-lfs \
+ tst-fstatat \
+ tst-fts \
+ tst-fts-lfs \
+diff --git a/io/tst-fcntl-lock-lfs.c b/io/tst-fcntl-lock-lfs.c
+new file mode 100644
+index 0000000000..f2a909fb02
+--- /dev/null
++++ b/io/tst-fcntl-lock-lfs.c
+@@ -0,0 +1,2 @@
++#define _FILE_OFFSET_BITS 64
++#include <io/tst-fcntl-lock.c>
+diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
+index f7615a447e..d8a291a331 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
+@@ -33,7 +33,7 @@
+ # define __O_LARGEFILE 0200000
+ #endif
+
+-#if __WORDSIZE == 64
++#if __WORDSIZE == 64 && !defined __USE_FILE_OFFSET64
+ # define F_GETLK 5
+ # define F_SETLK 6
+ # define F_SETLKW 7
+--
+2.33.0
+
diff --git a/0012-AArch64-Check-kernel-version-for-SVE-ifuncs.patch b/0012-AArch64-Check-kernel-version-for-SVE-ifuncs.patch
new file mode 100644
index 0000000..687c821
--- /dev/null
+++ b/0012-AArch64-Check-kernel-version-for-SVE-ifuncs.patch
@@ -0,0 +1,153 @@
+From 92da7c2cfeeea36d651142f47e570dd5076bc166 Mon Sep 17 00:00:00 2001
+From: Wilco Dijkstra <wilco.dijkstra@arm.com>
+Date: Thu, 21 Mar 2024 16:48:33 +0000
+Subject: [PATCH 12/26] AArch64: Check kernel version for SVE ifuncs
+
+Old Linux kernels disable SVE after every system call. Calling the
+SVE-optimized memcpy afterwards will then cause a trap to reenable SVE.
+As a result, applications with a high use of syscalls may run slower with
+the SVE memcpy. This is true for kernels between 4.15.0 and before 6.2.0,
+except for 5.14.0 which was patched. Avoid this by checking the kernel
+version and selecting the SVE ifunc on modern kernels.
+
+Parse the kernel version reported by uname() into a 24-bit kernel.major.minor
+value without calling any library functions. If uname() is not supported or
+if the version format is not recognized, assume the kernel is modern.
+
+Tested-by: Florian Weimer <fweimer@redhat.com>
+Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+(cherry picked from commit 2e94e2f5d2bf2de124c8ad7da85463355e54ccb2)
+---
+ sysdeps/aarch64/multiarch/init-arch.h | 2 +
+ sysdeps/aarch64/multiarch/memcpy.c | 2 +-
+ sysdeps/aarch64/multiarch/memmove.c | 2 +-
+ .../unix/sysv/linux/aarch64/cpu-features.c | 48 +++++++++++++++++++
+ .../unix/sysv/linux/aarch64/cpu-features.h | 1 +
+ 5 files changed, 53 insertions(+), 2 deletions(-)
+
+diff --git a/sysdeps/aarch64/multiarch/init-arch.h b/sysdeps/aarch64/multiarch/init-arch.h
+index e23e6ff290..daef631e04 100644
+--- a/sysdeps/aarch64/multiarch/init-arch.h
++++ b/sysdeps/aarch64/multiarch/init-arch.h
+@@ -36,5 +36,7 @@
+ MTE_ENABLED (); \
+ bool __attribute__((unused)) sve = \
+ GLRO(dl_aarch64_cpu_features).sve; \
++ bool __attribute__((unused)) prefer_sve_ifuncs = \
++ GLRO(dl_aarch64_cpu_features).prefer_sve_ifuncs; \
+ bool __attribute__((unused)) mops = \
+ GLRO(dl_aarch64_cpu_features).mops;
+diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
+index 6471fe82e3..e7c7795db6 100644
+--- a/sysdeps/aarch64/multiarch/memcpy.c
++++ b/sysdeps/aarch64/multiarch/memcpy.c
+@@ -47,7 +47,7 @@ select_memcpy_ifunc (void)
+ {
+ if (IS_A64FX (midr))
+ return __memcpy_a64fx;
+- return __memcpy_sve;
++ return prefer_sve_ifuncs ? __memcpy_sve : __memcpy_generic;
+ }
+
+ if (IS_THUNDERX (midr))
+diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
+index 7602a5d57d..6b77166851 100644
+--- a/sysdeps/aarch64/multiarch/memmove.c
++++ b/sysdeps/aarch64/multiarch/memmove.c
+@@ -47,7 +47,7 @@ select_memmove_ifunc (void)
+ {
+ if (IS_A64FX (midr))
+ return __memmove_a64fx;
+- return __memmove_sve;
++ return prefer_sve_ifuncs ? __memmove_sve : __memmove_generic;
+ }
+
+ if (IS_THUNDERX (midr))
+diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+index a11a86efab..4a205a6b35 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+@@ -20,6 +20,7 @@
+ #include <sys/auxv.h>
+ #include <elf/dl-hwcaps.h>
+ #include <sys/prctl.h>
++#include <sys/utsname.h>
+
+ #define DCZID_DZP_MASK (1 << 4)
+ #define DCZID_BS_MASK (0xf)
+@@ -57,6 +58,46 @@ get_midr_from_mcpu (const char *mcpu)
+ return UINT64_MAX;
+ }
+
++#if __LINUX_KERNEL_VERSION < 0x060200
++
++/* Return true if we prefer using SVE in string ifuncs. Old kernels disable
++ SVE after every system call which results in unnecessary traps if memcpy
++ uses SVE. This is true for kernels between 4.15.0 and before 6.2.0, except
++ for 5.14.0 which was patched. For these versions return false to avoid using
++ SVE ifuncs.
++ Parse the kernel version into a 24-bit kernel.major.minor value without
++ calling any library functions. If uname() is not supported or if the version
++ format is not recognized, assume the kernel is modern and return true. */
++
++static inline bool
++prefer_sve_ifuncs (void)
++{
++ struct utsname buf;
++ const char *p = &buf.release[0];
++ int kernel = 0;
++ int val;
++
++ if (__uname (&buf) < 0)
++ return true;
++
++ for (int shift = 16; shift >= 0; shift -= 8)
++ {
++ for (val = 0; *p >= '0' && *p <= '9'; p++)
++ val = val * 10 + *p - '0';
++ kernel |= (val & 255) << shift;
++ if (*p++ != '.')
++ break;
++ }
++
++ if (kernel >= 0x060200 || kernel == 0x050e00)
++ return true;
++ if (kernel >= 0x040f00)
++ return false;
++ return true;
++}
++
++#endif
++
+ static inline void
+ init_cpu_features (struct cpu_features *cpu_features)
+ {
+@@ -119,6 +160,13 @@ init_cpu_features (struct cpu_features *cpu_features)
+ /* Check if SVE is supported. */
+ cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE;
+
++ cpu_features->prefer_sve_ifuncs = cpu_features->sve;
++
++#if __LINUX_KERNEL_VERSION < 0x060200
++ if (cpu_features->sve)
++ cpu_features->prefer_sve_ifuncs = prefer_sve_ifuncs ();
++#endif
++
+ /* Check if MOPS is supported. */
+ cpu_features->mops = GLRO (dl_hwcap2) & HWCAP2_MOPS;
+ }
+diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+index 2cf745cd19..351a619dcb 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+@@ -71,6 +71,7 @@ struct cpu_features
+ /* Currently, the GLIBC memory tagging tunable only defines 8 bits. */
+ uint8_t mte_state;
+ bool sve;
++ bool prefer_sve_ifuncs;
+ bool mops;
+ };
+
+--
+2.33.0
+
diff --git a/0012-libio-Fix-oversized-__io_vtables.patch b/0012-libio-Fix-oversized-__io_vtables.patch
new file mode 100644
index 0000000..6f8a158
--- /dev/null
+++ b/0012-libio-Fix-oversized-__io_vtables.patch
@@ -0,0 +1,51 @@
+From 92201f16cbcfd9eafe314ef6654be2ea7ba25675 Mon Sep 17 00:00:00 2001
+From: Adam Jackson <ajax@redhat.com>
+Date: Fri, 8 Sep 2023 15:55:19 -0400
+Subject: [PATCH 12/12] libio: Fix oversized __io_vtables
+
+IO_VTABLES_LEN is the size of the struct array in bytes, not the number
+of __IO_jump_t's in the array. Drops just under 384kb from .rodata on
+LP64 machines.
+
+Fixes: 3020f72618e ("libio: Remove the usage of __libc_IO_vtables")
+Signed-off-by: Adam Jackson <ajax@redhat.com>
+Reviewed-by: Florian Weimer <fweimer@redhat.com>
+Tested-by: Florian Weimer <fweimer@redhat.com>
+(cherry picked from commit 8cb69e054386f980f9ff4d93b157861d72b2019e)
+---
+ libio/vtables.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/libio/vtables.c b/libio/vtables.c
+index 1d8ad612e9..34f7e15f1c 100644
+--- a/libio/vtables.c
++++ b/libio/vtables.c
+@@ -20,6 +20,7 @@
+ #include <libioP.h>
+ #include <stdio.h>
+ #include <ldsodefs.h>
++#include <array_length.h>
+ #include <pointer_guard.h>
+ #include <libio-macros.h>
+
+@@ -88,7 +89,7 @@
+ # pragma weak __wprintf_buffer_as_file_xsputn
+ #endif
+
+-const struct _IO_jump_t __io_vtables[IO_VTABLES_LEN] attribute_relro =
++const struct _IO_jump_t __io_vtables[] attribute_relro =
+ {
+ /* _IO_str_jumps */
+ [IO_STR_JUMPS] =
+@@ -485,6 +486,8 @@ const struct _IO_jump_t __io_vtables[IO_VTABLES_LEN] attribute_relro =
+ },
+ #endif
+ };
++_Static_assert (array_length (__io_vtables) == IO_VTABLES_NUM,
++ "initializer count");
+
+ #ifdef SHARED
+
+--
+2.33.0
+
diff --git a/0012-resolv-Fix-tst-resolv-short-response-for-older-GCC-b.patch b/0012-resolv-Fix-tst-resolv-short-response-for-older-GCC-b.patch
new file mode 100644
index 0000000..fc16820
--- /dev/null
+++ b/0012-resolv-Fix-tst-resolv-short-response-for-older-GCC-b.patch
@@ -0,0 +1,35 @@
+From 9184c13681b5de1f9e078538f0e1ee9b8599e1c3 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 1 Aug 2024 10:46:10 +0200
+Subject: [PATCH 12/12] resolv: Fix tst-resolv-short-response for older GCC
+ (bug 32042)
+
+Previous GCC versions do not support the C23 change that
+allows labels on declarations.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit ec119972cb2598c04ec7d4219e20506006836f64)
+---
+ resolv/tst-resolv-short-response.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c
+index be354ae1c7..9b06b0c176 100644
+--- a/resolv/tst-resolv-short-response.c
++++ b/resolv/tst-resolv-short-response.c
+@@ -33,8 +33,10 @@ response (const struct resolv_response_context *ctx,
+ {
+ case 0:
+ /* First server times out. */
+- struct resolv_response_flags flags = {.rcode = rcode};
+- resolv_response_init (b, flags);
++ {
++ struct resolv_response_flags flags = {.rcode = rcode};
++ resolv_response_init (b, flags);
++ }
+ break;
+ case 1:
+ /* Second server sends reply. */
+--
+2.33.0
+
diff --git a/0013-powerpc-Fix-ld.so-address-determination-for-PCREL-mo.patch b/0013-powerpc-Fix-ld.so-address-determination-for-PCREL-mo.patch
new file mode 100644
index 0000000..526dc2c
--- /dev/null
+++ b/0013-powerpc-Fix-ld.so-address-determination-for-PCREL-mo.patch
@@ -0,0 +1,56 @@
+From 20534f81760635f3a71fb11ba251568cdc11c6a0 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Sun, 14 Apr 2024 08:24:51 +0200
+Subject: [PATCH 13/26] powerpc: Fix ld.so address determination for PCREL mode
+ (bug 31640)
+
+This seems to have stopped working with some GCC 14 versions,
+which clobber r2. With other compilers, the kernel-provided
+r2 value is still available at this point.
+
+Reviewed-by: Peter Bergner <bergner@linux.ibm.com>
+(cherry picked from commit 14e56bd4ce15ac2d1cc43f762eb2e6b83fec1afe)
+---
+ sysdeps/powerpc/powerpc64/dl-machine.h | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
+index 9b8943bc91..7fa8a355b5 100644
+--- a/sysdeps/powerpc/powerpc64/dl-machine.h
++++ b/sysdeps/powerpc/powerpc64/dl-machine.h
+@@ -79,6 +79,7 @@ elf_host_tolerates_class (const Elf64_Ehdr *ehdr)
+ static inline Elf64_Addr
+ elf_machine_load_address (void) __attribute__ ((const));
+
++#ifndef __PCREL__
+ static inline Elf64_Addr
+ elf_machine_load_address (void)
+ {
+@@ -106,6 +107,24 @@ elf_machine_dynamic (void)
+ /* Then subtract off the load address offset. */
+ return runtime_dynamic - elf_machine_load_address() ;
+ }
++#else /* __PCREL__ */
++/* In PCREL mode, r2 may have been clobbered. Rely on relative
++ relocations instead. */
++
++static inline ElfW(Addr)
++elf_machine_load_address (void)
++{
++ extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
++ return (ElfW(Addr)) &__ehdr_start;
++}
++
++static inline ElfW(Addr)
++elf_machine_dynamic (void)
++{
++ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
++ return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
++}
++#endif /* __PCREL__ */
+
+ /* The PLT uses Elf64_Rela relocs. */
+ #define elf_machine_relplt elf_machine_rela
+--
+2.33.0
+
diff --git a/0014-iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch b/0014-iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch
new file mode 100644
index 0000000..1cd02a8
--- /dev/null
+++ b/0014-iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch
@@ -0,0 +1,216 @@
+From e1135387deded5d73924f6ca20c72a35dc8e1bda Mon Sep 17 00:00:00 2001
+From: Charles Fol <folcharles@gmail.com>
+Date: Thu, 28 Mar 2024 12:25:38 -0300
+Subject: [PATCH 14/26] iconv: ISO-2022-CN-EXT: fix out-of-bound writes when
+ writing escape sequence (CVE-2024-2961)
+
+ISO-2022-CN-EXT uses escape sequences to indicate character set changes
+(as specified by RFC 1922). While the SOdesignation has the expected
+bounds checks, neither SS2designation nor SS3designation have its;
+allowing a write overflow of 1, 2, or 3 bytes with fixed values:
+'$+I', '$+J', '$+K', '$+L', '$+M', or '$*H'.
+
+Checked on aarch64-linux-gnu.
+
+Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+Tested-by: Carlos O'Donell <carlos@redhat.com>
+
+(cherry picked from commit f9dc609e06b1136bb0408be9605ce7973a767ada)
+---
+ iconvdata/Makefile | 5 +-
+ iconvdata/iso-2022-cn-ext.c | 12 +++
+ iconvdata/tst-iconv-iso-2022-cn-ext.c | 128 ++++++++++++++++++++++++++
+ 3 files changed, 144 insertions(+), 1 deletion(-)
+ create mode 100644 iconvdata/tst-iconv-iso-2022-cn-ext.c
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index dd5cafab21..075098dce8 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -75,7 +75,8 @@ ifeq (yes,$(build-shared))
+ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
+ tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
+ bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \
+- bug-iconv13 bug-iconv14 bug-iconv15
++ bug-iconv13 bug-iconv14 bug-iconv15 \
++ tst-iconv-iso-2022-cn-ext
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
+@@ -330,6 +331,8 @@ $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ $(addprefix $(objpfx),$(modules.so))
+ $(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ $(addprefix $(objpfx),$(modules.so))
++$(objpfx)tst-iconv-iso-2022-cn-ext.out: $(addprefix $(objpfx), $(gconv-modules)) \
++ $(addprefix $(objpfx),$(modules.so))
+
+ $(objpfx)iconv-test.out: run-iconv-test.sh \
+ $(addprefix $(objpfx), $(gconv-modules)) \
+diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c
+index 36727f0865..9bb02238a3 100644
+--- a/iconvdata/iso-2022-cn-ext.c
++++ b/iconvdata/iso-2022-cn-ext.c
+@@ -574,6 +574,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+ { \
+ const char *escseq; \
+ \
++ if (outptr + 4 > outend) \
++ { \
++ result = __GCONV_FULL_OUTPUT; \
++ break; \
++ } \
++ \
+ assert (used == CNS11643_2_set); /* XXX */ \
+ escseq = "*H"; \
+ *outptr++ = ESC; \
+@@ -587,6 +593,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+ { \
+ const char *escseq; \
+ \
++ if (outptr + 4 > outend) \
++ { \
++ result = __GCONV_FULL_OUTPUT; \
++ break; \
++ } \
++ \
+ assert ((used >> 5) >= 3 && (used >> 5) <= 7); \
+ escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2; \
+ *outptr++ = ESC; \
+diff --git a/iconvdata/tst-iconv-iso-2022-cn-ext.c b/iconvdata/tst-iconv-iso-2022-cn-ext.c
+new file mode 100644
+index 0000000000..96a8765fd5
+--- /dev/null
++++ b/iconvdata/tst-iconv-iso-2022-cn-ext.c
+@@ -0,0 +1,128 @@
++/* Verify ISO-2022-CN-EXT does not write out of the bounds.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <string.h>
++
++#include <errno.h>
++#include <iconv.h>
++#include <sys/mman.h>
++
++#include <support/xunistd.h>
++#include <support/check.h>
++#include <support/support.h>
++
++/* The test sets up a two memory page buffer with the second page marked
++ PROT_NONE to trigger a fault if the conversion writes beyond the exact
++ expected amount. Then we carry out various conversions and precisely
++ place the start of the output buffer in order to trigger a SIGSEGV if the
++ process writes anywhere between 1 and page sized bytes more (only one
++ PROT_NONE page is setup as a canary) than expected. These tests exercise
++ all three of the cases in ISO-2022-CN-EXT where the converter must switch
++ character sets and may run out of buffer space while doing the
++ operation. */
++
++static int
++do_test (void)
++{
++ iconv_t cd = iconv_open ("ISO-2022-CN-EXT", "UTF-8");
++ TEST_VERIFY_EXIT (cd != (iconv_t) -1);
++
++ char *ntf;
++ size_t ntfsize;
++ char *outbufbase;
++ {
++ int pgz = getpagesize ();
++ TEST_VERIFY_EXIT (pgz > 0);
++ ntfsize = 2 * pgz;
++
++ ntf = xmmap (NULL, ntfsize, PROT_READ | PROT_WRITE, MAP_PRIVATE
++ | MAP_ANONYMOUS, -1);
++ xmprotect (ntf + pgz, pgz, PROT_NONE);
++
++ outbufbase = ntf + pgz;
++ }
++
++ /* Check if SOdesignation escape sequence does not trigger an OOB write. */
++ {
++ char inbuf[] = "\xe4\xba\xa4\xe6\x8d\xa2";
++
++ for (int i = 0; i < 9; i++)
++ {
++ char *inp = inbuf;
++ size_t inleft = sizeof (inbuf) - 1;
++
++ char *outp = outbufbase - i;
++ size_t outleft = i;
++
++ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
++ == (size_t) -1);
++ TEST_COMPARE (errno, E2BIG);
++
++ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
++ }
++ }
++
++ /* Same as before for SS2designation. */
++ {
++ char inbuf[] = "ã´½ \xe3\xb4\xbd";
++
++ for (int i = 0; i < 14; i++)
++ {
++ char *inp = inbuf;
++ size_t inleft = sizeof (inbuf) - 1;
++
++ char *outp = outbufbase - i;
++ size_t outleft = i;
++
++ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
++ == (size_t) -1);
++ TEST_COMPARE (errno, E2BIG);
++
++ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
++ }
++ }
++
++ /* Same as before for SS3designation. */
++ {
++ char inbuf[] = "劄 \xe5\x8a\x84";
++
++ for (int i = 0; i < 14; i++)
++ {
++ char *inp = inbuf;
++ size_t inleft = sizeof (inbuf) - 1;
++
++ char *outp = outbufbase - i;
++ size_t outleft = i;
++
++ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
++ == (size_t) -1);
++ TEST_COMPARE (errno, E2BIG);
++
++ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
++ }
++ }
++
++ TEST_VERIFY_EXIT (iconv_close (cd) != -1);
++
++ xmunmap (ntf, ntfsize);
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.33.0
+
diff --git a/0015-sparc-Remove-64-bit-check-on-sparc32-wordsize-BZ-275.patch b/0015-sparc-Remove-64-bit-check-on-sparc32-wordsize-BZ-275.patch
new file mode 100644
index 0000000..b32b5b4
--- /dev/null
+++ b/0015-sparc-Remove-64-bit-check-on-sparc32-wordsize-BZ-275.patch
@@ -0,0 +1,38 @@
+From 61484011e76d2bfafbe401f7058717c2029dd155 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Wed, 17 Jan 2024 10:13:06 -0300
+Subject: [PATCH 15/26] sparc: Remove 64 bit check on sparc32 wordsize (BZ
+ 27574)
+
+The sparc32 is always 32 bits.
+
+Checked on sparcv9-linux-gnu.
+
+(cherry picked from commit dd57f5e7b652772499cb220d78157c1038d24f06)
+---
+ sysdeps/sparc/sparc32/bits/wordsize.h | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/sysdeps/sparc/sparc32/bits/wordsize.h b/sysdeps/sparc/sparc32/bits/wordsize.h
+index 2f66f10d72..4bbd2e63b4 100644
+--- a/sysdeps/sparc/sparc32/bits/wordsize.h
++++ b/sysdeps/sparc/sparc32/bits/wordsize.h
+@@ -1,11 +1,6 @@
+ /* Determine the wordsize from the preprocessor defines. */
+
+-#if defined __arch64__ || defined __sparcv9
+-# define __WORDSIZE 64
+-# define __WORDSIZE_TIME64_COMPAT32 1
+-#else
+-# define __WORDSIZE 32
+-# define __WORDSIZE_TIME64_COMPAT32 0
+-# define __WORDSIZE32_SIZE_ULONG 0
+-# define __WORDSIZE32_PTRDIFF_LONG 0
+-#endif
++#define __WORDSIZE 32
++#define __WORDSIZE_TIME64_COMPAT32 0
++#define __WORDSIZE32_SIZE_ULONG 0
++#define __WORDSIZE32_PTRDIFF_LONG 0
+--
+2.33.0
+
diff --git a/0016-login-Check-default-sizes-of-structs-utmp-utmpx-last.patch b/0016-login-Check-default-sizes-of-structs-utmp-utmpx-last.patch
new file mode 100644
index 0000000..c1595fa
--- /dev/null
+++ b/0016-login-Check-default-sizes-of-structs-utmp-utmpx-last.patch
@@ -0,0 +1,247 @@
+From 78d9f91da6682f4073f05abaf309e4ca2b746003 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Fri, 19 Apr 2024 14:38:17 +0200
+Subject: [PATCH 16/26] login: Check default sizes of structs utmp, utmpx,
+ lastlog
+
+The default <utmp-size.h> is for ports with a 64-bit time_t.
+Ports with a 32-bit time_t or with __WORDSIZE_TIME64_COMPAT32=1
+need to override it.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 4d4da5aab936504b2d3eca3146e109630d9093c4)
+---
+ login/Makefile | 2 +-
+ login/tst-utmp-size.c | 33 +++++++++++++++++++++++++++++++++
+ sysdeps/arc/utmp-size.h | 3 +++
+ sysdeps/arm/utmp-size.h | 2 ++
+ sysdeps/csky/utmp-size.h | 2 ++
+ sysdeps/generic/utmp-size.h | 23 +++++++++++++++++++++++
+ sysdeps/hppa/utmp-size.h | 2 ++
+ sysdeps/m68k/utmp-size.h | 3 +++
+ sysdeps/microblaze/utmp-size.h | 2 ++
+ sysdeps/mips/utmp-size.h | 2 ++
+ sysdeps/nios2/utmp-size.h | 2 ++
+ sysdeps/or1k/utmp-size.h | 3 +++
+ sysdeps/powerpc/utmp-size.h | 2 ++
+ sysdeps/riscv/utmp-size.h | 2 ++
+ sysdeps/sh/utmp-size.h | 2 ++
+ sysdeps/sparc/utmp-size.h | 2 ++
+ sysdeps/x86/utmp-size.h | 2 ++
+ 17 files changed, 88 insertions(+), 1 deletion(-)
+ create mode 100644 login/tst-utmp-size.c
+ create mode 100644 sysdeps/arc/utmp-size.h
+ create mode 100644 sysdeps/arm/utmp-size.h
+ create mode 100644 sysdeps/csky/utmp-size.h
+ create mode 100644 sysdeps/generic/utmp-size.h
+ create mode 100644 sysdeps/hppa/utmp-size.h
+ create mode 100644 sysdeps/m68k/utmp-size.h
+ create mode 100644 sysdeps/microblaze/utmp-size.h
+ create mode 100644 sysdeps/mips/utmp-size.h
+ create mode 100644 sysdeps/nios2/utmp-size.h
+ create mode 100644 sysdeps/or1k/utmp-size.h
+ create mode 100644 sysdeps/powerpc/utmp-size.h
+ create mode 100644 sysdeps/riscv/utmp-size.h
+ create mode 100644 sysdeps/sh/utmp-size.h
+ create mode 100644 sysdeps/sparc/utmp-size.h
+ create mode 100644 sysdeps/x86/utmp-size.h
+
+diff --git a/login/Makefile b/login/Makefile
+index 74216cbcb2..1cca663769 100644
+--- a/login/Makefile
++++ b/login/Makefile
+@@ -44,7 +44,7 @@ subdir-dirs = programs
+ vpath %.c programs
+
+ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
+- tst-pututxline-lockfail tst-pututxline-cache
++ tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size
+
+ # Empty compatibility library for old binaries.
+ extra-libs := libutil
+diff --git a/login/tst-utmp-size.c b/login/tst-utmp-size.c
+new file mode 100644
+index 0000000000..1b7f7ff042
+--- /dev/null
++++ b/login/tst-utmp-size.c
+@@ -0,0 +1,33 @@
++/* Check expected sizes of struct utmp, struct utmpx, struct lastlog.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <utmp.h>
++#include <utmpx.h>
++#include <utmp-size.h>
++
++static int
++do_test (void)
++{
++ _Static_assert (sizeof (struct utmp) == UTMP_SIZE, "struct utmp size");
++ _Static_assert (sizeof (struct utmpx) == UTMP_SIZE, "struct utmpx size");
++ _Static_assert (sizeof (struct lastlog) == LASTLOG_SIZE,
++ "struct lastlog size");
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/arc/utmp-size.h b/sysdeps/arc/utmp-size.h
+new file mode 100644
+index 0000000000..a247fcd3da
+--- /dev/null
++++ b/sysdeps/arc/utmp-size.h
+@@ -0,0 +1,3 @@
++/* arc has less padding than other architectures with 64-bit time_t. */
++#define UTMP_SIZE 392
++#define LASTLOG_SIZE 296
+diff --git a/sysdeps/arm/utmp-size.h b/sysdeps/arm/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/arm/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/csky/utmp-size.h b/sysdeps/csky/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/csky/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/generic/utmp-size.h b/sysdeps/generic/utmp-size.h
+new file mode 100644
+index 0000000000..89dbe878b0
+--- /dev/null
++++ b/sysdeps/generic/utmp-size.h
+@@ -0,0 +1,23 @@
++/* Expected sizes of utmp-related structures stored in files. 64-bit version.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++/* Expected size, in bytes, of struct utmp and struct utmpx. */
++#define UTMP_SIZE 400
++
++/* Expected size, in bytes, of struct lastlog. */
++#define LASTLOG_SIZE 296
+diff --git a/sysdeps/hppa/utmp-size.h b/sysdeps/hppa/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/hppa/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/m68k/utmp-size.h b/sysdeps/m68k/utmp-size.h
+new file mode 100644
+index 0000000000..5946685819
+--- /dev/null
++++ b/sysdeps/m68k/utmp-size.h
+@@ -0,0 +1,3 @@
++/* m68k has 2-byte alignment. */
++#define UTMP_SIZE 382
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/microblaze/utmp-size.h b/sysdeps/microblaze/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/microblaze/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/mips/utmp-size.h b/sysdeps/mips/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/mips/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/nios2/utmp-size.h b/sysdeps/nios2/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/nios2/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/or1k/utmp-size.h b/sysdeps/or1k/utmp-size.h
+new file mode 100644
+index 0000000000..6b3653aa4d
+--- /dev/null
++++ b/sysdeps/or1k/utmp-size.h
+@@ -0,0 +1,3 @@
++/* or1k has less padding than other architectures with 64-bit time_t. */
++#define UTMP_SIZE 392
++#define LASTLOG_SIZE 296
+diff --git a/sysdeps/powerpc/utmp-size.h b/sysdeps/powerpc/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/powerpc/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/riscv/utmp-size.h b/sysdeps/riscv/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/riscv/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/sh/utmp-size.h b/sysdeps/sh/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/sh/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/sparc/utmp-size.h b/sysdeps/sparc/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/sparc/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/x86/utmp-size.h b/sysdeps/x86/utmp-size.h
+new file mode 100644
+index 0000000000..8f21ebe1b6
+--- /dev/null
++++ b/sysdeps/x86/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+--
+2.33.0
+
diff --git a/0017-login-structs-utmp-utmpx-lastlog-_TIME_BITS-independ.patch b/0017-login-structs-utmp-utmpx-lastlog-_TIME_BITS-independ.patch
new file mode 100644
index 0000000..9de4ff7
--- /dev/null
+++ b/0017-login-structs-utmp-utmpx-lastlog-_TIME_BITS-independ.patch
@@ -0,0 +1,399 @@
+From 68bff8859231787f7e19b01788cc59b673c14046 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Fri, 19 Apr 2024 14:38:17 +0200
+Subject: [PATCH 17/26] login: structs utmp, utmpx, lastlog _TIME_BITS
+ independence (bug 30701)
+
+These structs describe file formats under /var/log, and should not
+depend on the definition of _TIME_BITS. This is achieved by
+defining __WORDSIZE_TIME64_COMPAT32 to 1 on 32-bit ports that
+support 32-bit time_t values (where __time_t is 32 bits).
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 9abdae94c7454c45e02e97e4ed1eb1b1915d13d8)
+---
+ bits/wordsize.h | 6 ++++--
+ login/Makefile | 4 +++-
+ login/tst-utmp-size-64.c | 2 ++
+ sysdeps/arm/bits/wordsize.h | 21 +++++++++++++++++++
+ sysdeps/csky/bits/wordsize.h | 21 +++++++++++++++++++
+ sysdeps/m68k/bits/wordsize.h | 21 +++++++++++++++++++
+ sysdeps/microblaze/bits/wordsize.h | 21 +++++++++++++++++++
+ sysdeps/mips/bits/wordsize.h | 6 +-----
+ sysdeps/nios2/bits/wordsize.h | 21 +++++++++++++++++++
+ sysdeps/powerpc/powerpc32/bits/wordsize.h | 3 +--
+ sysdeps/powerpc/powerpc64/bits/wordsize.h | 3 +--
+ sysdeps/sh/bits/wordsize.h | 21 +++++++++++++++++++
+ sysdeps/sparc/sparc32/bits/wordsize.h | 2 +-
+ sysdeps/sparc/sparc64/bits/wordsize.h | 3 +--
+ sysdeps/unix/sysv/linux/hppa/bits/wordsize.h | 21 +++++++++++++++++++
+ .../unix/sysv/linux/powerpc/bits/wordsize.h | 3 +--
+ sysdeps/unix/sysv/linux/sparc/bits/wordsize.h | 3 +--
+ sysdeps/x86/bits/wordsize.h | 5 ++---
+ 18 files changed, 165 insertions(+), 22 deletions(-)
+ create mode 100644 login/tst-utmp-size-64.c
+ create mode 100644 sysdeps/arm/bits/wordsize.h
+ create mode 100644 sysdeps/csky/bits/wordsize.h
+ create mode 100644 sysdeps/m68k/bits/wordsize.h
+ create mode 100644 sysdeps/microblaze/bits/wordsize.h
+ create mode 100644 sysdeps/nios2/bits/wordsize.h
+ create mode 100644 sysdeps/sh/bits/wordsize.h
+ create mode 100644 sysdeps/unix/sysv/linux/hppa/bits/wordsize.h
+
+diff --git a/bits/wordsize.h b/bits/wordsize.h
+index 14edae3a11..53013a9275 100644
+--- a/bits/wordsize.h
++++ b/bits/wordsize.h
+@@ -21,7 +21,9 @@
+ #define __WORDSIZE32_PTRDIFF_LONG
+
+ /* Set to 1 in order to force time types to be 32 bits instead of 64 bits in
+- struct lastlog and struct utmp{,x} on 64-bit ports. This may be done in
++ struct lastlog and struct utmp{,x}. This may be done in
+ order to make 64-bit ports compatible with 32-bit ports. Set to 0 for
+- 64-bit ports where the time types are 64-bits or for any 32-bit ports. */
++ 64-bit ports where the time types are 64-bits and new 32-bit ports
++ where time_t is 64 bits, and there is no companion architecture with
++ 32-bit time_t. */
+ #define __WORDSIZE_TIME64_COMPAT32
+diff --git a/login/Makefile b/login/Makefile
+index 1cca663769..7dd6cab9c9 100644
+--- a/login/Makefile
++++ b/login/Makefile
+@@ -44,7 +44,9 @@ subdir-dirs = programs
+ vpath %.c programs
+
+ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
+- tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size
++ tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size tst-utmp-size-64
++
++CFLAGS-tst-utmp-size-64.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
+
+ # Empty compatibility library for old binaries.
+ extra-libs := libutil
+diff --git a/login/tst-utmp-size-64.c b/login/tst-utmp-size-64.c
+new file mode 100644
+index 0000000000..7a581a4c12
+--- /dev/null
++++ b/login/tst-utmp-size-64.c
+@@ -0,0 +1,2 @@
++/* The on-disk layout must not change in time64 mode. */
++#include "tst-utmp-size.c"
+diff --git a/sysdeps/arm/bits/wordsize.h b/sysdeps/arm/bits/wordsize.h
+new file mode 100644
+index 0000000000..6ecbfe7c86
+--- /dev/null
++++ b/sysdeps/arm/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#define __WORDSIZE 32
++#define __WORDSIZE_TIME64_COMPAT32 1
++#define __WORDSIZE32_SIZE_ULONG 0
++#define __WORDSIZE32_PTRDIFF_LONG 0
+diff --git a/sysdeps/csky/bits/wordsize.h b/sysdeps/csky/bits/wordsize.h
+new file mode 100644
+index 0000000000..6ecbfe7c86
+--- /dev/null
++++ b/sysdeps/csky/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#define __WORDSIZE 32
++#define __WORDSIZE_TIME64_COMPAT32 1
++#define __WORDSIZE32_SIZE_ULONG 0
++#define __WORDSIZE32_PTRDIFF_LONG 0
+diff --git a/sysdeps/m68k/bits/wordsize.h b/sysdeps/m68k/bits/wordsize.h
+new file mode 100644
+index 0000000000..6ecbfe7c86
+--- /dev/null
++++ b/sysdeps/m68k/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#define __WORDSIZE 32
++#define __WORDSIZE_TIME64_COMPAT32 1
++#define __WORDSIZE32_SIZE_ULONG 0
++#define __WORDSIZE32_PTRDIFF_LONG 0
+diff --git a/sysdeps/microblaze/bits/wordsize.h b/sysdeps/microblaze/bits/wordsize.h
+new file mode 100644
+index 0000000000..6ecbfe7c86
+--- /dev/null
++++ b/sysdeps/microblaze/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#define __WORDSIZE 32
++#define __WORDSIZE_TIME64_COMPAT32 1
++#define __WORDSIZE32_SIZE_ULONG 0
++#define __WORDSIZE32_PTRDIFF_LONG 0
+diff --git a/sysdeps/mips/bits/wordsize.h b/sysdeps/mips/bits/wordsize.h
+index 9d7d961f3e..cb72a0869a 100644
+--- a/sysdeps/mips/bits/wordsize.h
++++ b/sysdeps/mips/bits/wordsize.h
+@@ -19,11 +19,7 @@
+
+ #define __WORDSIZE _MIPS_SZPTR
+
+-#if _MIPS_SIM == _ABI64
+-# define __WORDSIZE_TIME64_COMPAT32 1
+-#else
+-# define __WORDSIZE_TIME64_COMPAT32 0
+-#endif
++#define __WORDSIZE_TIME64_COMPAT32 1
+
+ #if __WORDSIZE == 32
+ #define __WORDSIZE32_SIZE_ULONG 0
+diff --git a/sysdeps/nios2/bits/wordsize.h b/sysdeps/nios2/bits/wordsize.h
+new file mode 100644
+index 0000000000..6ecbfe7c86
+--- /dev/null
++++ b/sysdeps/nios2/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#define __WORDSIZE 32
++#define __WORDSIZE_TIME64_COMPAT32 1
++#define __WORDSIZE32_SIZE_ULONG 0
++#define __WORDSIZE32_PTRDIFF_LONG 0
+diff --git a/sysdeps/powerpc/powerpc32/bits/wordsize.h b/sysdeps/powerpc/powerpc32/bits/wordsize.h
+index 04ca9debf0..6993fb6b29 100644
+--- a/sysdeps/powerpc/powerpc32/bits/wordsize.h
++++ b/sysdeps/powerpc/powerpc32/bits/wordsize.h
+@@ -2,10 +2,9 @@
+
+ #if defined __powerpc64__
+ # define __WORDSIZE 64
+-# define __WORDSIZE_TIME64_COMPAT32 1
+ #else
+ # define __WORDSIZE 32
+-# define __WORDSIZE_TIME64_COMPAT32 0
+ # define __WORDSIZE32_SIZE_ULONG 0
+ # define __WORDSIZE32_PTRDIFF_LONG 0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32 1
+diff --git a/sysdeps/powerpc/powerpc64/bits/wordsize.h b/sysdeps/powerpc/powerpc64/bits/wordsize.h
+index 04ca9debf0..6993fb6b29 100644
+--- a/sysdeps/powerpc/powerpc64/bits/wordsize.h
++++ b/sysdeps/powerpc/powerpc64/bits/wordsize.h
+@@ -2,10 +2,9 @@
+
+ #if defined __powerpc64__
+ # define __WORDSIZE 64
+-# define __WORDSIZE_TIME64_COMPAT32 1
+ #else
+ # define __WORDSIZE 32
+-# define __WORDSIZE_TIME64_COMPAT32 0
+ # define __WORDSIZE32_SIZE_ULONG 0
+ # define __WORDSIZE32_PTRDIFF_LONG 0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32 1
+diff --git a/sysdeps/sh/bits/wordsize.h b/sysdeps/sh/bits/wordsize.h
+new file mode 100644
+index 0000000000..6ecbfe7c86
+--- /dev/null
++++ b/sysdeps/sh/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#define __WORDSIZE 32
++#define __WORDSIZE_TIME64_COMPAT32 1
++#define __WORDSIZE32_SIZE_ULONG 0
++#define __WORDSIZE32_PTRDIFF_LONG 0
+diff --git a/sysdeps/sparc/sparc32/bits/wordsize.h b/sysdeps/sparc/sparc32/bits/wordsize.h
+index 4bbd2e63b4..a2e79e0fa9 100644
+--- a/sysdeps/sparc/sparc32/bits/wordsize.h
++++ b/sysdeps/sparc/sparc32/bits/wordsize.h
+@@ -1,6 +1,6 @@
+ /* Determine the wordsize from the preprocessor defines. */
+
+ #define __WORDSIZE 32
+-#define __WORDSIZE_TIME64_COMPAT32 0
++#define __WORDSIZE_TIME64_COMPAT32 1
+ #define __WORDSIZE32_SIZE_ULONG 0
+ #define __WORDSIZE32_PTRDIFF_LONG 0
+diff --git a/sysdeps/sparc/sparc64/bits/wordsize.h b/sysdeps/sparc/sparc64/bits/wordsize.h
+index 2f66f10d72..ea103e5970 100644
+--- a/sysdeps/sparc/sparc64/bits/wordsize.h
++++ b/sysdeps/sparc/sparc64/bits/wordsize.h
+@@ -2,10 +2,9 @@
+
+ #if defined __arch64__ || defined __sparcv9
+ # define __WORDSIZE 64
+-# define __WORDSIZE_TIME64_COMPAT32 1
+ #else
+ # define __WORDSIZE 32
+-# define __WORDSIZE_TIME64_COMPAT32 0
+ # define __WORDSIZE32_SIZE_ULONG 0
+ # define __WORDSIZE32_PTRDIFF_LONG 0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32 1
+diff --git a/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h b/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h
+new file mode 100644
+index 0000000000..6ecbfe7c86
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#define __WORDSIZE 32
++#define __WORDSIZE_TIME64_COMPAT32 1
++#define __WORDSIZE32_SIZE_ULONG 0
++#define __WORDSIZE32_PTRDIFF_LONG 0
+diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h b/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
+index 04ca9debf0..6993fb6b29 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
+@@ -2,10 +2,9 @@
+
+ #if defined __powerpc64__
+ # define __WORDSIZE 64
+-# define __WORDSIZE_TIME64_COMPAT32 1
+ #else
+ # define __WORDSIZE 32
+-# define __WORDSIZE_TIME64_COMPAT32 0
+ # define __WORDSIZE32_SIZE_ULONG 0
+ # define __WORDSIZE32_PTRDIFF_LONG 0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32 1
+diff --git a/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h b/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
+index 7562875ee2..ea103e5970 100644
+--- a/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
+@@ -2,10 +2,9 @@
+
+ #if defined __arch64__ || defined __sparcv9
+ # define __WORDSIZE 64
+-# define __WORDSIZE_TIME64_COMPAT32 1
+ #else
+ # define __WORDSIZE 32
+ # define __WORDSIZE32_SIZE_ULONG 0
+ # define __WORDSIZE32_PTRDIFF_LONG 0
+-# define __WORDSIZE_TIME64_COMPAT32 0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32 1
+diff --git a/sysdeps/x86/bits/wordsize.h b/sysdeps/x86/bits/wordsize.h
+index 70f652bca1..3f40aa76f9 100644
+--- a/sysdeps/x86/bits/wordsize.h
++++ b/sysdeps/x86/bits/wordsize.h
+@@ -8,10 +8,9 @@
+ #define __WORDSIZE32_PTRDIFF_LONG 0
+ #endif
+
++#define __WORDSIZE_TIME64_COMPAT32 1
++
+ #ifdef __x86_64__
+-# define __WORDSIZE_TIME64_COMPAT32 1
+ /* Both x86-64 and x32 use the 64-bit system call interface. */
+ # define __SYSCALL_WORDSIZE 64
+-#else
+-# define __WORDSIZE_TIME64_COMPAT32 0
+ #endif
+--
+2.33.0
+
diff --git a/0018-nptl-Fix-tst-cancel30-on-kernels-without-ppoll_time6.patch b/0018-nptl-Fix-tst-cancel30-on-kernels-without-ppoll_time6.patch
new file mode 100644
index 0000000..0aeaa18
--- /dev/null
+++ b/0018-nptl-Fix-tst-cancel30-on-kernels-without-ppoll_time6.patch
@@ -0,0 +1,55 @@
+From decc9f504ae78bbee6faa49b9bca71c7eae62ea9 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 23 Apr 2024 21:16:32 +0200
+Subject: [PATCH 18/26] nptl: Fix tst-cancel30 on kernels without ppoll_time64
+ support
+
+Fall back to ppoll if ppoll_time64 fails with ENOSYS.
+Fixes commit 370da8a121c3ba9eeb2f13da15fc0f21f4136b25 ("nptl: Fix
+tst-cancel30 on sparc64").
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit f4724843ada64a51d66f65d3199fe431f9d4c254)
+---
+ sysdeps/pthread/tst-cancel30.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/sysdeps/pthread/tst-cancel30.c b/sysdeps/pthread/tst-cancel30.c
+index ff803386be..ace925ca67 100644
+--- a/sysdeps/pthread/tst-cancel30.c
++++ b/sysdeps/pthread/tst-cancel30.c
+@@ -18,6 +18,7 @@
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
++#include <errno.h>
+ #include <support/check.h>
+ #include <support/xstdio.h>
+ #include <support/xthread.h>
+@@ -46,13 +47,19 @@ tf (void *arg)
+
+ /* Wait indefinitely for cancellation, which only works if asynchronous
+ cancellation is enabled. */
+-#if defined SYS_ppoll || defined SYS_ppoll_time64
+-# ifndef SYS_ppoll_time64
+-# define SYS_ppoll_time64 SYS_ppoll
++#ifdef SYS_ppoll_time64
++ long int ret = syscall (SYS_ppoll_time64, NULL, 0, NULL, NULL);
++ (void) ret;
++# ifdef SYS_ppoll
++ if (ret == -1 && errno == ENOSYS)
++ syscall (SYS_ppoll, NULL, 0, NULL, NULL);
+ # endif
+- syscall (SYS_ppoll_time64, NULL, 0, NULL, NULL);
+ #else
++# ifdef SYS_ppoll
++ syscall (SYS_ppoll, NULL, 0, NULL, NULL);
++# else
+ for (;;);
++# endif
+ #endif
+
+ return 0;
+--
+2.33.0
+
diff --git a/0019-i386-ulp-update-for-SSE2-disable-multi-arch-configur.patch b/0019-i386-ulp-update-for-SSE2-disable-multi-arch-configur.patch
new file mode 100644
index 0000000..8acf758
--- /dev/null
+++ b/0019-i386-ulp-update-for-SSE2-disable-multi-arch-configur.patch
@@ -0,0 +1,26 @@
+From 29e20bd1222cb69dcc6827e899ce7181090052dc Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 25 Apr 2024 12:56:48 +0200
+Subject: [PATCH 19/26] i386: ulp update for SSE2 --disable-multi-arch
+ configurations
+
+(cherry picked from commit 3a3a4497421422aa854c855cbe5110ca7d598ffc)
+---
+ sysdeps/i386/fpu/libm-test-ulps | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
+index 84e6686eba..f2139fc172 100644
+--- a/sysdeps/i386/fpu/libm-test-ulps
++++ b/sysdeps/i386/fpu/libm-test-ulps
+@@ -1232,6 +1232,7 @@ ldouble: 6
+
+ Function: "hypot":
+ double: 1
++float: 1
+ float128: 1
+ ldouble: 1
+
+--
+2.33.0
+
diff --git a/0020-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch b/0020-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch
new file mode 100644
index 0000000..2188c60
--- /dev/null
+++ b/0020-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch
@@ -0,0 +1,38 @@
+From 5968aebb86164034b8f8421b4abab2f837a5bdaf Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 25 Apr 2024 15:00:45 +0200
+Subject: [PATCH 20/26] CVE-2024-33599: nscd: Stack-based buffer overflow in
+ netgroup cache (bug 31677)
+
+Using alloca matches what other caches do. The request length is
+bounded by MAXKEYLEN.
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 87801a8fd06db1d654eea3e4f7626ff476a9bdaa)
+---
+ nscd/netgroupcache.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index 06b7d7b6ca..31b721bbee 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -502,12 +502,13 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ = (struct indataset *) mempool_alloc (db,
+ sizeof (*dataset) + req->key_len,
+ 1);
+- struct indataset dataset_mem;
+ bool cacheable = true;
+ if (__glibc_unlikely (dataset == NULL))
+ {
+ cacheable = false;
+- dataset = &dataset_mem;
++ /* The alloca is safe because nscd_run_worker verfies that
++ key_len is not larger than MAXKEYLEN. */
++ dataset = alloca (sizeof (*dataset) + req->key_len);
+ }
+
+ datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
+--
+2.33.0
+
diff --git a/0021-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch b/0021-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch
new file mode 100644
index 0000000..29b9214
--- /dev/null
+++ b/0021-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch
@@ -0,0 +1,59 @@
+From 541ea5172aa658c4bd5c6c6d6fd13903c3d5bb0a Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 25 Apr 2024 15:01:07 +0200
+Subject: [PATCH 21/26] CVE-2024-33600: nscd: Do not send missing not-found
+ response in addgetnetgrentX (bug 31678)
+
+If we failed to add a not-found response to the cache, the dataset
+point can be null, resulting in a null pointer dereference.
+
+Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+(cherry picked from commit 7835b00dbce53c3c87bbbb1754a95fb5e58187aa)
+---
+ nscd/netgroupcache.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index 31b721bbee..32c6aef370 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -147,7 +147,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ /* No such service. */
+ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
+ &key_copy);
+- goto writeout;
++ goto maybe_cache_add;
+ }
+
+ memset (&data, '\0', sizeof (data));
+@@ -348,7 +348,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ {
+ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
+ &key_copy);
+- goto writeout;
++ goto maybe_cache_add;
+ }
+
+ total = buffilled;
+@@ -410,14 +410,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ }
+
+ if (he == NULL && fd != -1)
+- {
+- /* We write the dataset before inserting it to the database
+- since while inserting this thread might block and so would
+- unnecessarily let the receiver wait. */
+- writeout:
++ /* We write the dataset before inserting it to the database since
++ while inserting this thread might block and so would
++ unnecessarily let the receiver wait. */
+ writeall (fd, &dataset->resp, dataset->head.recsize);
+- }
+
++ maybe_cache_add:
+ if (cacheable)
+ {
+ /* If necessary, we also propagate the data to disk. */
+--
+2.33.0
+
diff --git a/0022-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch b/0022-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch
new file mode 100644
index 0000000..b861cda
--- /dev/null
+++ b/0022-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch
@@ -0,0 +1,60 @@
+From 2ae9446c1b7a3064743b4a51c0bbae668ee43e4c Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 25 Apr 2024 15:01:07 +0200
+Subject: [PATCH 22/26] CVE-2024-33600: nscd: Avoid null pointer crashes after
+ notfound response (bug 31678)
+
+The addgetnetgrentX call in addinnetgrX may have failed to produce
+a result, so the result variable in addinnetgrX can be NULL.
+Use db->negtimeout as the fallback value if there is no result data;
+the timeout is also overwritten below.
+
+Also avoid sending a second not-found response. (The client
+disconnects after receiving the first response, so the data stream did
+not go out of sync even without this fix.) It is still beneficial to
+add the negative response to the mapping, so that the client can get
+it from there in the future, instead of going through the socket.
+
+Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+(cherry picked from commit b048a482f088e53144d26a61c390bed0210f49f2)
+---
+ nscd/netgroupcache.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index 32c6aef370..c3cd79dec5 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -511,14 +511,15 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+
+ datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
+ sizeof (innetgroup_response_header),
+- he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
++ he == NULL ? 0 : dh->nreloads + 1,
++ result == NULL ? db->negtimeout : result->head.ttl);
+ /* Set the notfound status and timeout based on the result from
+ getnetgrent. */
+- dataset->head.notfound = result->head.notfound;
++ dataset->head.notfound = result == NULL || result->head.notfound;
+ dataset->head.timeout = timeout;
+
+ dataset->resp.version = NSCD_VERSION;
+- dataset->resp.found = result->resp.found;
++ dataset->resp.found = result != NULL && result->resp.found;
+ /* Until we find a matching entry the result is 0. */
+ dataset->resp.result = 0;
+
+@@ -566,7 +567,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ goto out;
+ }
+
+- if (he == NULL)
++ /* addgetnetgrentX may have already sent a notfound response. Do
++ not send another one. */
++ if (he == NULL && dataset->resp.found)
+ {
+ /* We write the dataset before inserting it to the database
+ since while inserting this thread might block and so would
+--
+2.33.0
+
diff --git a/0023-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two-.patch b/0023-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two-.patch
new file mode 100644
index 0000000..8f027b3
--- /dev/null
+++ b/0023-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two-.patch
@@ -0,0 +1,390 @@
+From 71af8ca864345d39b746d5cee84b94b430fad5db Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 25 Apr 2024 15:01:07 +0200
+Subject: [PATCH 23/26] CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two
+ buffers in addgetnetgrentX (bug 31680)
+
+This avoids potential memory corruption when the underlying NSS
+callback function does not use the buffer space to store all strings
+(e.g., for constant strings).
+
+Instead of custom buffer management, two scratch buffers are used.
+This increases stack usage somewhat.
+
+Scratch buffer allocation failure is handled by return -1
+(an invalid timeout value) instead of terminating the process.
+This fixes bug 31679.
+
+Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+(cherry picked from commit c04a21e050d64a1193a6daab872bca2528bda44b)
+---
+ nscd/netgroupcache.c | 219 ++++++++++++++++++++++++-------------------
+ 1 file changed, 121 insertions(+), 98 deletions(-)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index c3cd79dec5..cc4e270c1f 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -23,6 +23,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/mman.h>
++#include <scratch_buffer.h>
+
+ #include "../inet/netgroup.h"
+ #include "nscd.h"
+@@ -65,6 +66,16 @@ struct dataset
+ char strdata[0];
+ };
+
++/* Send a notfound response to FD. Always returns -1 to indicate an
++ ephemeral error. */
++static time_t
++send_notfound (int fd)
++{
++ if (fd != -1)
++ TEMP_FAILURE_RETRY (send (fd, &notfound, sizeof (notfound), MSG_NOSIGNAL));
++ return -1;
++}
++
+ /* Sends a notfound message and prepares a notfound dataset to write to the
+ cache. Returns true if there was enough memory to allocate the dataset and
+ returns the dataset in DATASETP, total bytes to write in TOTALP and the
+@@ -83,8 +94,7 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
+ total = sizeof (notfound);
+ timeout = time (NULL) + db->negtimeout;
+
+- if (fd != -1)
+- TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
++ send_notfound (fd);
+
+ dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
+ /* If we cannot permanently store the result, so be it. */
+@@ -109,11 +119,78 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
+ return cacheable;
+ }
+
++struct addgetnetgrentX_scratch
++{
++ /* This is the result that the caller should use. It can be NULL,
++ point into buffer, or it can be in the cache. */
++ struct dataset *dataset;
++
++ struct scratch_buffer buffer;
++
++ /* Used internally in addgetnetgrentX as a staging area. */
++ struct scratch_buffer tmp;
++
++ /* Number of bytes in buffer that are actually used. */
++ size_t buffer_used;
++};
++
++static void
++addgetnetgrentX_scratch_init (struct addgetnetgrentX_scratch *scratch)
++{
++ scratch->dataset = NULL;
++ scratch_buffer_init (&scratch->buffer);
++ scratch_buffer_init (&scratch->tmp);
++
++ /* Reserve space for the header. */
++ scratch->buffer_used = sizeof (struct dataset);
++ static_assert (sizeof (struct dataset) < sizeof (scratch->tmp.__space),
++ "initial buffer space");
++ memset (scratch->tmp.data, 0, sizeof (struct dataset));
++}
++
++static void
++addgetnetgrentX_scratch_free (struct addgetnetgrentX_scratch *scratch)
++{
++ scratch_buffer_free (&scratch->buffer);
++ scratch_buffer_free (&scratch->tmp);
++}
++
++/* Copy LENGTH bytes from S into SCRATCH. Returns NULL if SCRATCH
++ could not be resized, otherwise a pointer to the copy. */
++static char *
++addgetnetgrentX_append_n (struct addgetnetgrentX_scratch *scratch,
++ const char *s, size_t length)
++{
++ while (true)
++ {
++ size_t remaining = scratch->buffer.length - scratch->buffer_used;
++ if (remaining >= length)
++ break;
++ if (!scratch_buffer_grow_preserve (&scratch->buffer))
++ return NULL;
++ }
++ char *copy = scratch->buffer.data + scratch->buffer_used;
++ memcpy (copy, s, length);
++ scratch->buffer_used += length;
++ return copy;
++}
++
++/* Copy S into SCRATCH, including its null terminator. Returns false
++ if SCRATCH could not be resized. */
++static bool
++addgetnetgrentX_append (struct addgetnetgrentX_scratch *scratch, const char *s)
++{
++ if (s == NULL)
++ s = "";
++ return addgetnetgrentX_append_n (scratch, s, strlen (s) + 1) != NULL;
++}
++
++/* Caller must initialize and free *SCRATCH. If the return value is
++ negative, this function has sent a notfound response. */
+ static time_t
+ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ const char *key, uid_t uid, struct hashentry *he,
+- struct datahead *dh, struct dataset **resultp,
+- void **tofreep)
++ struct datahead *dh, struct addgetnetgrentX_scratch *scratch)
+ {
+ if (__glibc_unlikely (debug_level > 0))
+ {
+@@ -132,14 +209,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+
+ char *key_copy = NULL;
+ struct __netgrent data;
+- size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len);
+- size_t buffilled = sizeof (*dataset);
+- char *buffer = NULL;
+ size_t nentries = 0;
+ size_t group_len = strlen (key) + 1;
+ struct name_list *first_needed
+ = alloca (sizeof (struct name_list) + group_len);
+- *tofreep = NULL;
+
+ if (netgroup_database == NULL
+ && !__nss_database_get (nss_database_netgroup, &netgroup_database))
+@@ -151,8 +224,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ }
+
+ memset (&data, '\0', sizeof (data));
+- buffer = xmalloc (buflen);
+- *tofreep = buffer;
+ first_needed->next = first_needed;
+ memcpy (first_needed->name, key, group_len);
+ data.needed_groups = first_needed;
+@@ -195,8 +266,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ while (1)
+ {
+ int e;
+- status = getfct.f (&data, buffer + buffilled,
+- buflen - buffilled - req->key_len, &e);
++ status = getfct.f (&data, scratch->tmp.data,
++ scratch->tmp.length, &e);
+ if (status == NSS_STATUS_SUCCESS)
+ {
+ if (data.type == triple_val)
+@@ -204,68 +275,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ const char *nhost = data.val.triple.host;
+ const char *nuser = data.val.triple.user;
+ const char *ndomain = data.val.triple.domain;
+-
+- size_t hostlen = strlen (nhost ?: "") + 1;
+- size_t userlen = strlen (nuser ?: "") + 1;
+- size_t domainlen = strlen (ndomain ?: "") + 1;
+-
+- if (nhost == NULL || nuser == NULL || ndomain == NULL
+- || nhost > nuser || nuser > ndomain)
+- {
+- const char *last = nhost;
+- if (last == NULL
+- || (nuser != NULL && nuser > last))
+- last = nuser;
+- if (last == NULL
+- || (ndomain != NULL && ndomain > last))
+- last = ndomain;
+-
+- size_t bufused
+- = (last == NULL
+- ? buffilled
+- : last + strlen (last) + 1 - buffer);
+-
+- /* We have to make temporary copies. */
+- size_t needed = hostlen + userlen + domainlen;
+-
+- if (buflen - req->key_len - bufused < needed)
+- {
+- buflen += MAX (buflen, 2 * needed);
+- /* Save offset in the old buffer. We don't
+- bother with the NULL check here since
+- we'll do that later anyway. */
+- size_t nhostdiff = nhost - buffer;
+- size_t nuserdiff = nuser - buffer;
+- size_t ndomaindiff = ndomain - buffer;
+-
+- char *newbuf = xrealloc (buffer, buflen);
+- /* Fix up the triplet pointers into the new
+- buffer. */
+- nhost = (nhost ? newbuf + nhostdiff
+- : NULL);
+- nuser = (nuser ? newbuf + nuserdiff
+- : NULL);
+- ndomain = (ndomain ? newbuf + ndomaindiff
+- : NULL);
+- *tofreep = buffer = newbuf;
+- }
+-
+- nhost = memcpy (buffer + bufused,
+- nhost ?: "", hostlen);
+- nuser = memcpy ((char *) nhost + hostlen,
+- nuser ?: "", userlen);
+- ndomain = memcpy ((char *) nuser + userlen,
+- ndomain ?: "", domainlen);
+- }
+-
+- char *wp = buffer + buffilled;
+- wp = memmove (wp, nhost ?: "", hostlen);
+- wp += hostlen;
+- wp = memmove (wp, nuser ?: "", userlen);
+- wp += userlen;
+- wp = memmove (wp, ndomain ?: "", domainlen);
+- wp += domainlen;
+- buffilled = wp - buffer;
++ if (!(addgetnetgrentX_append (scratch, nhost)
++ && addgetnetgrentX_append (scratch, nuser)
++ && addgetnetgrentX_append (scratch, ndomain)))
++ return send_notfound (fd);
+ ++nentries;
+ }
+ else
+@@ -317,8 +330,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ }
+ else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
+ {
+- buflen *= 2;
+- *tofreep = buffer = xrealloc (buffer, buflen);
++ if (!scratch_buffer_grow (&scratch->tmp))
++ return send_notfound (fd);
+ }
+ else if (status == NSS_STATUS_RETURN
+ || status == NSS_STATUS_NOTFOUND
+@@ -351,10 +364,17 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ goto maybe_cache_add;
+ }
+
+- total = buffilled;
++ /* Capture the result size without the key appended. */
++ total = scratch->buffer_used;
++
++ /* Make a copy of the key. The scratch buffer must not move after
++ this point. */
++ key_copy = addgetnetgrentX_append_n (scratch, key, req->key_len);
++ if (key_copy == NULL)
++ return send_notfound (fd);
+
+ /* Fill in the dataset. */
+- dataset = (struct dataset *) buffer;
++ dataset = scratch->buffer.data;
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
+ total - offsetof (struct dataset, resp),
+ he == NULL ? 0 : dh->nreloads + 1,
+@@ -363,11 +383,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ dataset->resp.version = NSCD_VERSION;
+ dataset->resp.found = 1;
+ dataset->resp.nresults = nentries;
+- dataset->resp.result_len = buffilled - sizeof (*dataset);
+-
+- assert (buflen - buffilled >= req->key_len);
+- key_copy = memcpy (buffer + buffilled, key, req->key_len);
+- buffilled += req->key_len;
++ dataset->resp.result_len = total - sizeof (*dataset);
+
+ /* Now we can determine whether on refill we have to create a new
+ record or not. */
+@@ -398,7 +414,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ if (__glibc_likely (newp != NULL))
+ {
+ /* Adjust pointer into the memory block. */
+- key_copy = (char *) newp + (key_copy - buffer);
++ key_copy = (char *) newp + (key_copy - (char *) dataset);
+
+ dataset = memcpy (newp, dataset, total + req->key_len);
+ cacheable = true;
+@@ -439,7 +455,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ }
+
+ out:
+- *resultp = dataset;
++ scratch->dataset = dataset;
+
+ return timeout;
+ }
+@@ -460,6 +476,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ if (user != NULL)
+ key = strchr (key, '\0') + 1;
+ const char *domain = *key++ ? key : NULL;
++ struct addgetnetgrentX_scratch scratch;
++
++ addgetnetgrentX_scratch_init (&scratch);
+
+ if (__glibc_unlikely (debug_level > 0))
+ {
+@@ -475,12 +494,8 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ group, group_len,
+ db, uid);
+ time_t timeout;
+- void *tofree;
+ if (result != NULL)
+- {
+- timeout = result->head.timeout;
+- tofree = NULL;
+- }
++ timeout = result->head.timeout;
+ else
+ {
+ request_header req_get =
+@@ -489,7 +504,10 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ .key_len = group_len
+ };
+ timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
+- &result, &tofree);
++ &scratch);
++ result = scratch.dataset;
++ if (timeout < 0)
++ goto out;
+ }
+
+ struct indataset
+@@ -603,7 +621,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ }
+
+ out:
+- free (tofree);
++ addgetnetgrentX_scratch_free (&scratch);
+ return timeout;
+ }
+
+@@ -613,11 +631,12 @@ addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
+ const char *key, uid_t uid, struct hashentry *he,
+ struct datahead *dh)
+ {
+- struct dataset *ignore;
+- void *tofree;
+- time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
+- &ignore, &tofree);
+- free (tofree);
++ struct addgetnetgrentX_scratch scratch;
++ addgetnetgrentX_scratch_init (&scratch);
++ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, &scratch);
++ addgetnetgrentX_scratch_free (&scratch);
++ if (timeout < 0)
++ timeout = 0;
+ return timeout;
+ }
+
+@@ -661,5 +680,9 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he,
+ .key_len = he->len
+ };
+
+- return addinnetgrX (db, -1, &req, db->data + he->key, he->owner, he, dh);
++ int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
++ he, dh);
++ if (timeout < 0)
++ timeout = 0;
++ return timeout;
+ }
+--
+2.33.0
+
diff --git a/0024-elf-Also-compile-dl-misc.os-with-rtld-early-cflags.patch b/0024-elf-Also-compile-dl-misc.os-with-rtld-early-cflags.patch
new file mode 100644
index 0000000..8233425
--- /dev/null
+++ b/0024-elf-Also-compile-dl-misc.os-with-rtld-early-cflags.patch
@@ -0,0 +1,54 @@
+From e9f05fa1c62c8044ff025963498063f73eb51c5f Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Thu, 25 Apr 2024 08:06:52 -0700
+Subject: [PATCH 24/26] elf: Also compile dl-misc.os with $(rtld-early-cflags)
+
+Also compile dl-misc.os with $(rtld-early-cflags) to avoid
+
+Program received signal SIGILL, Illegal instruction.
+0x00007ffff7fd36ea in _dl_strtoul (nptr=nptr@entry=0x7fffffffe2c9 "2",
+ endptr=endptr@entry=0x7fffffffd728) at dl-misc.c:156
+156 bool positive = true;
+(gdb) bt
+ #0 0x00007ffff7fd36ea in _dl_strtoul (nptr=nptr@entry=0x7fffffffe2c9 "2",
+ endptr=endptr@entry=0x7fffffffd728) at dl-misc.c:156
+ #1 0x00007ffff7fdb1a9 in tunable_initialize (
+ cur=cur@entry=0x7ffff7ffbc00 <tunable_list+2176>,
+ strval=strval@entry=0x7fffffffe2c9 "2", len=len@entry=1)
+ at dl-tunables.c:131
+ #2 0x00007ffff7fdb3a2 in parse_tunables (valstring=<optimized out>)
+ at dl-tunables.c:258
+ #3 0x00007ffff7fdb5d9 in __GI___tunables_init (envp=0x7fffffffdd58)
+ at dl-tunables.c:288
+ #4 0x00007ffff7fe44c3 in _dl_sysdep_start (
+ start_argptr=start_argptr@entry=0x7fffffffdcb0,
+ dl_main=dl_main@entry=0x7ffff7fe5f80 <dl_main>)
+ at ../sysdeps/unix/sysv/linux/dl-sysdep.c:110
+ #5 0x00007ffff7fe5cae in _dl_start_final (arg=0x7fffffffdcb0) at rtld.c:494
+ #6 _dl_start (arg=0x7fffffffdcb0) at rtld.c:581
+ #7 0x00007ffff7fe4b38 in _start ()
+(gdb)
+
+when setting GLIBC_TUNABLES in glibc compiled with APX.
+Reviewed-by: Florian Weimer <fweimer@redhat.com>
+
+(cherry picked from commit 049b7684c912dd32b67b1b15b0f43bf07d5f512e)
+---
+ elf/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 1a05a6aaca..c2af11b92c 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -166,6 +166,7 @@ CFLAGS-.op += $(call elide-stack-protector,.op,$(elide-routines.os))
+ CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines))
+
+ # Add the requested compiler flags to the early startup code.
++CFLAGS-dl-misc.os += $(rtld-early-cflags)
+ CFLAGS-dl-printf.os += $(rtld-early-cflags)
+ CFLAGS-dl-setup_hash.os += $(rtld-early-cflags)
+ CFLAGS-dl-sysdep.os += $(rtld-early-cflags)
+--
+2.33.0
+
diff --git a/0025-nscd-Use-time_t-for-return-type-of-addgetnetgrentX.patch b/0025-nscd-Use-time_t-for-return-type-of-addgetnetgrentX.patch
new file mode 100644
index 0000000..dd97d37
--- /dev/null
+++ b/0025-nscd-Use-time_t-for-return-type-of-addgetnetgrentX.patch
@@ -0,0 +1,36 @@
+From f510d75ff7f7405328853bd67b75f6847dfe9d31 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 2 May 2024 17:06:19 +0200
+Subject: [PATCH 25/26] nscd: Use time_t for return type of addgetnetgrentX
+
+Using int may give false results for future dates (timeouts after the
+year 2028).
+
+Fixes commit 04a21e050d64a1193a6daab872bca2528bda44b ("CVE-2024-33601,
+CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX
+(bug 31680)").
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 4bbca1a44691a6e9adcee5c6798a707b626bc331)
+---
+ nscd/netgroupcache.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index cc4e270c1f..a63b260fdb 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -680,8 +680,8 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he,
+ .key_len = he->len
+ };
+
+- int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
+- he, dh);
++ time_t timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
++ he, dh);
+ if (timeout < 0)
+ timeout = 0;
+ return timeout;
+--
+2.33.0
+
diff --git a/0026-resolv-Fix-some-unaligned-accesses-in-resolver-BZ-30.patch b/0026-resolv-Fix-some-unaligned-accesses-in-resolver-BZ-30.patch
new file mode 100644
index 0000000..38d2a39
--- /dev/null
+++ b/0026-resolv-Fix-some-unaligned-accesses-in-resolver-BZ-30.patch
@@ -0,0 +1,57 @@
+From 5aa4bb67b9cbd334789199c03c9d30b90662a313 Mon Sep 17 00:00:00 2001
+From: John David Anglin <danglin@gcc.gnu.org>
+Date: Wed, 13 Sep 2023 11:04:41 +0000
+Subject: [PATCH 26/26] resolv: Fix some unaligned accesses in resolver [BZ
+ #30750]
+
+Signed-off-by: John David Anglin <dave.anglin@bell.net>
+---
+ resolv/res_nameinquery.c | 3 ++-
+ resolv/res_queriesmatch.c | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/resolv/res_nameinquery.c b/resolv/res_nameinquery.c
+index 24172700e1..ca56bc9283 100644
+--- a/resolv/res_nameinquery.c
++++ b/resolv/res_nameinquery.c
+@@ -84,6 +84,7 @@
+
+ #include <arpa/nameser.h>
+ #include <resolv.h>
++#include <resolv/resolv-internal.h>
+
+ /* Author: paul vixie, 29may94. */
+ int
+@@ -91,7 +92,7 @@ __libc_res_nameinquery (const char *name, int type, int class,
+ const unsigned char *buf, const unsigned char *eom)
+ {
+ const unsigned char *cp = buf + HFIXEDSZ;
+- int qdcount = ntohs (((HEADER *) buf)->qdcount);
++ int qdcount = ntohs (((UHEADER *) buf)->qdcount);
+
+ while (qdcount-- > 0)
+ {
+diff --git a/resolv/res_queriesmatch.c b/resolv/res_queriesmatch.c
+index 13a6936c47..ba1c1d0c0c 100644
+--- a/resolv/res_queriesmatch.c
++++ b/resolv/res_queriesmatch.c
+@@ -83,6 +83,7 @@
+ */
+
+ #include <resolv.h>
++#include <resolv/resolv-internal.h>
+
+ /* Author: paul vixie, 29may94. */
+ int
+@@ -102,7 +103,7 @@ __libc_res_queriesmatch (const unsigned char *buf1, const unsigned char *eom1,
+ order. We can compare it with the second buffer's QDCOUNT
+ value without doing this. */
+ int qdcount = ((HEADER *) buf1)->qdcount;
+- if (qdcount != ((HEADER *) buf2)->qdcount)
++ if (qdcount != ((UHEADER *) buf2)->qdcount)
+ return 0;
+
+ qdcount = htons (qdcount);
+--
+2.33.0
+
diff --git a/19614-locale-Handle-loading-a-missing-locale-twice-Bug-14.patch b/19614-locale-Handle-loading-a-missing-locale-twice-Bug-14.patch
new file mode 100644
index 0000000..fcb335f
--- /dev/null
+++ b/19614-locale-Handle-loading-a-missing-locale-twice-Bug-14.patch
@@ -0,0 +1,274 @@
+From 684fbab755e727a8c15f8b621648d66694cd1f53 Mon Sep 17 00:00:00 2001
+From: Carlos O'Donell <carlos@redhat.com>
+Date: Mon, 22 Apr 2024 08:16:09 -0400
+Subject: locale: Handle loading a missing locale twice (Bug 14247)
+
+Delay setting file->decided until the data has been successfully loaded
+by _nl_load_locale(). If the function fails to load the data then we
+must return and error and leave decided untouched to allow the caller to
+attempt to load the data again at a later time. We should not set
+decided to 1 early in the function since doing so may prevent attempting
+to load it again. We want to try loading it again because that allows an
+open to fail and set errno correctly.
+
+On the other side of this problem is that if we are called again with
+the same inputs we will fetch the cached version of the object and carry
+out no open syscalls and that fails to set errno so we must set errno to
+ENOENT in that case. There is a second code path that has to be handled
+where the name of the locale matches but the codeset doesn't match.
+
+These changes ensure that errno is correctly set on failure in all the
+return paths in _nl_find_locale().
+
+Adds tst-locale-loadlocale to cover the bug.
+
+No regressions on x86_64.
+
+Co-authored-by: Jeff Law <law@redhat.com>
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+---
+ gen-locales.mk | 13 +++++-
+ locale/findlocale.c | 19 +++++++--
+ locale/loadlocale.c | 2 +-
+ localedata/Makefile | 4 ++
+ localedata/gen-locale.sh | 24 ++++++++---
+ localedata/tst-locale-loadlocale.c | 67 ++++++++++++++++++++++++++++++
+ 6 files changed, 119 insertions(+), 10 deletions(-)
+ create mode 100644 localedata/tst-locale-loadlocale.c
+
+diff --git a/gen-locales.mk b/gen-locales.mk
+index 9c523d2a..b005a728 100644
+--- a/gen-locales.mk
++++ b/gen-locales.mk
+@@ -1,8 +1,19 @@
+ # defines target $(gen-locales) that generates the locales given in $(LOCALES)
+
+ LOCALE_SRCS := $(shell echo "$(LOCALES)"|sed 's/\([^ .]*\)[^@ ]*\(@[^ ]*\)\?/\1\2/g')
++# The CHARMAPS dependency handling must be able to process:
++# 1. No character map e.g. eo, en_US
++# 2. Character maps e.g. en_US.UTF-8
++# 3. Character maps with modifier e.g. tt_RU.UTF-8@iqtelif
++# This complicates the processing slightly so we do it in multiple edits,
++# the first captures the character map with the anchoring period while
++# the rest of the edits remove the period to get a valid file or adjust
++# the name to match the true name.
+ CHARMAPS := $(shell echo "$(LOCALES)" | \
+- sed -e 's/[^ .]*[.]\([^@ ]*\)\(@[^@ ]*\)*/\1/g' -e s/SJIS/SHIFT_JIS/g)
++ sed -e 's/\([^ .]*\)\([^@ ]*\)\(@[^@ ]*\)*/\2/g' \
++ -e 's/^\./ /g' \
++ -e 's/ \./ /g' \
++ -e s/SJIS/SHIFT_JIS/g)
+ CTYPE_FILES = $(addsuffix /LC_CTYPE,$(LOCALES))
+ gen-locales := $(addprefix $(common-objpfx)localedata/,$(CTYPE_FILES))
+
+diff --git a/locale/findlocale.c b/locale/findlocale.c
+index 1b703434..df74fbae 100644
+--- a/locale/findlocale.c
++++ b/locale/findlocale.c
+@@ -244,7 +244,14 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
+ locale_file = locale_file->successor[cnt];
+
+ if (locale_file == NULL)
+- return NULL;
++ {
++ /* If this is the second time we tried to load a failed
++ locale then the locale_file value comes from the cache
++ and we will not carry out any actual filesystem
++ operations so we must set ENOENT here. */
++ __set_errno (ENOENT);
++ return NULL;
++ }
+ }
+
+ /* The LC_CTYPE category allows to check whether a locale is really
+@@ -291,8 +298,14 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
+ if (__gconv_compare_alias (upstr (ccodeset, ccodeset),
+ upstr (clocale_codeset,
+ clocale_codeset)) != 0)
+- /* The codesets are not identical, don't use the locale. */
+- return NULL;
++ {
++ /* The codesets are not identical, don't use the locale.
++ If this is the second time we tried to load a locale
++ whose codeset doesn't match then the result came from
++ the cache and must set ENOENT here. */
++ __set_errno (ENOENT);
++ return NULL;
++ }
+ }
+
+ /* Determine the locale name for which loading succeeded. This
+diff --git a/locale/loadlocale.c b/locale/loadlocale.c
+index 671e71cf..1b4d0b05 100644
+--- a/locale/loadlocale.c
++++ b/locale/loadlocale.c
+@@ -237,7 +237,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);
+@@ -345,6 +344,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
+ newdata->alloc = alloc;
+
+ file->data = newdata;
++ file->decided = 1;
+ }
+
+ void
+diff --git a/localedata/Makefile b/localedata/Makefile
+index 3453b8c9..888634b3 100644
+--- a/localedata/Makefile
++++ b/localedata/Makefile
+@@ -166,6 +166,7 @@ tests = \
+ tst-digits \
+ tst-iconv-math-trans \
+ tst-leaks \
++ tst-locale-loadlocale \
+ tst-mbswcs1 \
+ tst-mbswcs2 \
+ tst-mbswcs3 \
+@@ -243,6 +244,7 @@ LOCALES := \
+ dsb_DE.UTF-8 \
+ dz_BT.UTF-8 \
+ en_GB.UTF-8 \
++ en_US \
+ en_US.ANSI_X3.4-1968 \
+ en_US.ISO-8859-1\
+ en_US.UTF-8 \
+@@ -321,6 +323,8 @@ LOCALES := \
+ include ../gen-locales.mk
+
+ $(objpfx)tst-iconv-math-trans.out: $(gen-locales)
++# tst-locale-loadlocale: Needs an en_US-named locale for the test.
++$(objpfx)tst-locale-loadlocale.out: $(gen-locales)
+ endif
+
+ include ../Rules
+diff --git a/localedata/gen-locale.sh b/localedata/gen-locale.sh
+index 7a9e8556..740b6500 100644
+--- a/localedata/gen-locale.sh
++++ b/localedata/gen-locale.sh
+@@ -48,9 +48,9 @@ generate_locale ()
+ }
+
+ locfile=`echo $locfile|sed 's|.*/\([^/]*/LC_CTYPE\)|\1|'`
+-locale=`echo $locfile|sed 's|\([^.]*\)[.].*/LC_CTYPE|\1|'`
+-charmap=`echo $locfile|sed 's|[^.]*[.]\([^@ ]*\)\(@[^ ]*\)\?/LC_CTYPE|\1|'`
+-modifier=`echo $locfile|sed 's|[^.]*[.]\([^@ ]*\)\(@[^ ]*\)\?/LC_CTYPE|\2|'`
++locale=`echo $locfile|sed 's|\([^.]*\).*/LC_CTYPE|\1|'`
++charmap=`echo $locfile|sed -e 's|[^.]*\([^@ ]*\)\(@[^ ]*\)\?/LC_CTYPE|\1|' -e 's|^\.||g'`
++modifier=`echo $locfile|sed 's|[^.]*\([^@ ]*\)\(@[^ ]*\)\?/LC_CTYPE|\2|'`
+
+ echo "Generating locale $locale.$charmap: this might take a while..."
+
+@@ -63,10 +63,16 @@ echo "Generating locale $locale.$charmap: this might take a while..."
+ # you to develop in-progress locales.
+ flags=""
+
++charmap_real="$charmap"
++
++# If no character map is specified then we fall back to UTF-8.
++if [ -z "$charmap" ]; then
++ charmap_real="UTF-8"
++fi
++
+ # 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
+ # means we need a mapping here.
+-charmap_real="$charmap"
+ if [ "$charmap" = "SJIS" ]; then
+ charmap_real="SHIFT_JIS"
+ fi
+@@ -80,4 +86,12 @@ if [ "$charmap_real" = 'SHIFT_JIS' ] \
+ flags="$flags --no-warnings=ascii"
+ fi
+
+-generate_locale $charmap_real $locale$modifier $locale.$charmap$modifier "$flags"
++# If the character map is not specified then we output a locale
++# with the just the name of the locale e.g. eo, en_US. This is
++# used for test locales that act as fallbacks.
++output_file="$locale.$charmap$modifier"
++if [ -z "$charmap" ]; then
++ output_file="$locale"
++fi
++
++generate_locale $charmap_real $locale$modifier $output_file "$flags"
+diff --git a/localedata/tst-locale-loadlocale.c b/localedata/tst-locale-loadlocale.c
+new file mode 100644
+index 00000000..64796e97
+--- /dev/null
++++ b/localedata/tst-locale-loadlocale.c
+@@ -0,0 +1,67 @@
++/* Test for locale loading error handling (Bug 14247)
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <errno.h>
++#include <locale.h>
++#include <support/check.h>
++#include <support/support.h>
++
++static int
++do_test (void)
++{
++ locale_t loc = NULL;
++
++ /* We must load an en_US-based locale for the final test to fail.
++ The locale loading code will find the en_US locale already loaded
++ but the codesets won't match. */
++ xsetlocale (LC_ALL, "en_US.UTF-8");
++
++ /* Call newlocale with an invalid locale. We expect the test system
++ does not have "invalidlocale" locale. */
++ errno = 0;
++ loc = newlocale (LC_COLLATE_MASK | LC_CTYPE_MASK, "invalidlocale.utf8", 0);
++ TEST_VERIFY (loc == NULL && errno != 0);
++
++ /* Call newlocale again with the same name. This triggers bug 14247 where
++ the second call fails to set errno correctly. */
++ errno = 0;
++ loc = newlocale (LC_COLLATE_MASK | LC_CTYPE_MASK, "invalidlocale.utf8", 0);
++ TEST_VERIFY (loc == NULL && errno != 0);
++
++ /* Next we attempt to load a locale that exists but whose codeset
++ does not match the codeset of the locale on the system.
++ This is more difficult to test but we rely on the fact that locale
++ processing will normalize the locale name and attempt to open
++ "en_US" with no codeset as a fallback and this will allow us to
++ compare a loaded "en_US" locale with a UTF-8 codeset to the
++ ficiticious "en_US.utf99" and get a codeset match failure. */
++ errno = 0;
++ loc = newlocale (LC_COLLATE_MASK | LC_CTYPE_MASK, "en_US.utf99", 0);
++ TEST_VERIFY (loc == NULL && errno != 0);
++
++ /* Call newlocale again with the same name. This triggers bug 14247 where
++ the second call fails to set errno correctly. */
++ errno = 0;
++ loc = newlocale (LC_COLLATE_MASK | LC_CTYPE_MASK, "en_US.utf99", 0);
++ TEST_VERIFY (loc == NULL && errno != 0);
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.27.0
+
diff --git a/CVE-2023-4527-Stack-read-overflow-with-large-TCP-res.patch b/CVE-2023-4527-Stack-read-overflow-with-large-TCP-res.patch
new file mode 100644
index 0000000..8040136
--- /dev/null
+++ b/CVE-2023-4527-Stack-read-overflow-with-large-TCP-res.patch
@@ -0,0 +1,221 @@
+From b25508dd774b617f99419bdc3cf2ace4560cd2d6 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 13 Sep 2023 14:10:56 +0200
+Subject: [PATCH] CVE-2023-4527: Stack read overflow with large TCP responses
+ in no-aaaa mode
+
+Without passing alt_dns_packet_buffer, __res_context_search can only
+store 2048 bytes (what fits into dns_packet_buffer). However,
+the function returns the total packet size, and the subsequent
+DNS parsing code in _nss_dns_gethostbyname4_r reads beyond the end
+of the stack-allocated buffer.
+
+Fixes commit f282cdbe7f436c75864e5640a4 ("resolv: Implement no-aaaa
+stub resolver option") and bug 30842.
+
+(cherry picked from commit bd77dd7e73e3530203be1c52c8a29d08270cb25d)
+---
+ NEWS | 9 +++
+ resolv/Makefile | 2 +
+ resolv/nss_dns/dns-host.c | 2 +-
+ resolv/tst-resolv-noaaaa-vc.c | 129 ++++++++++++++++++++++++++++++++++
+ 4 files changed, 141 insertions(+), 1 deletion(-)
+ create mode 100644 resolv/tst-resolv-noaaaa-vc.c
+
+diff --git a/NEWS b/NEWS
+index 64596d5d09..dfee278a9c 100644
+--- a/NEWS
++++ b/NEWS
+@@ -7,12 +7,21 @@ using `glibc' in the "product" field.
+
+ Version 2.38.1
+
++Security related changes:
++
++ CVE-2023-4527: If the system is configured in no-aaaa mode via
++ /etc/resolv.conf, getaddrinfo is called for the AF_UNSPEC address
++ family, and a DNS response is received over TCP that is larger than
++ 2048 bytes, getaddrinfo may potentially disclose stack contents via
++ the returned address data, or crash.
++
+ The following bugs are resolved with this release:
+
+ [30723] posix_memalign repeatedly scans long bin lists
+ [30785] Always call destructors in reverse constructor order
+ [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+ -D_FILE_OFFSET_BITS=64
++ [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
+
+
+ Version 2.38
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 054b1fa36c..2f99eb3862 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -102,6 +102,7 @@ tests += \
+ tst-resolv-invalid-cname \
+ tst-resolv-network \
+ tst-resolv-noaaaa \
++ tst-resolv-noaaaa-vc \
+ tst-resolv-nondecimal \
+ tst-resolv-res_init-multi \
+ tst-resolv-search \
+@@ -293,6 +294,7 @@ $(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \
+ $(objpfx)tst-resolv-invalid-cname: $(objpfx)libresolv.so \
+ $(shared-thread-library)
+ $(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library)
++$(objpfx)tst-resolv-noaaaa-vc: $(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 1d60c51f5e..5d0ab30de6 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -427,7 +427,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
+ {
+ n = __res_context_search (ctx, name, C_IN, T_A,
+ dns_packet_buffer, sizeof (dns_packet_buffer),
+- NULL, NULL, NULL, NULL, NULL);
++ &alt_dns_packet_buffer, NULL, NULL, NULL, NULL);
+ if (n >= 0)
+ status = gaih_getanswer_noaaaa (alt_dns_packet_buffer, n,
+ &abuf, pat, errnop, herrnop, ttlp);
+diff --git a/resolv/tst-resolv-noaaaa-vc.c b/resolv/tst-resolv-noaaaa-vc.c
+new file mode 100644
+index 0000000000..9f5aebd99f
+--- /dev/null
++++ b/resolv/tst-resolv-noaaaa-vc.c
+@@ -0,0 +1,129 @@
++/* Test the RES_NOAAAA resolver option with a large response.
++ Copyright (C) 2022-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
++ <https://www.gnu.org/licenses/>. */
++
++#include <errno.h>
++#include <netdb.h>
++#include <resolv.h>
++#include <stdbool.h>
++#include <stdlib.h>
++#include <support/check.h>
++#include <support/check_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++#include <support/xmemstream.h>
++
++/* Used to keep track of the number of queries. */
++static volatile unsigned int queries;
++
++/* If true, add a large TXT record at the start of the answer section. */
++static volatile bool stuff_txt;
++
++static void
++response (const struct resolv_response_context *ctx,
++ struct resolv_response_builder *b,
++ const char *qname, uint16_t qclass, uint16_t qtype)
++{
++ /* If not using TCP, just force its use. */
++ if (!ctx->tcp)
++ {
++ struct resolv_response_flags flags = {.tc = true};
++ resolv_response_init (b, flags);
++ resolv_response_add_question (b, qname, qclass, qtype);
++ return;
++ }
++
++ /* The test needs to send four queries, the first three are used to
++ grow the NSS buffer via the ERANGE handshake. */
++ ++queries;
++ TEST_VERIFY (queries <= 4);
++
++ /* AAAA queries are supposed to be disabled. */
++ TEST_COMPARE (qtype, T_A);
++ TEST_COMPARE (qclass, C_IN);
++ TEST_COMPARE_STRING (qname, "example.com");
++
++ 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);
++
++ if (stuff_txt)
++ {
++ resolv_response_open_record (b, qname, qclass, T_TXT, 60);
++ int zero = 0;
++ for (int i = 0; i <= 15000; ++i)
++ resolv_response_add_data (b, &zero, sizeof (zero));
++ resolv_response_close_record (b);
++ }
++
++ for (int i = 0; i < 200; ++i)
++ {
++ resolv_response_open_record (b, qname, qclass, qtype, 60);
++ char ipv4[4] = {192, 0, 2, i + 1};
++ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
++ resolv_response_close_record (b);
++ }
++}
++
++static int
++do_test (void)
++{
++ struct resolv_test *obj = resolv_test_start
++ ((struct resolv_redirect_config)
++ {
++ .response_callback = response
++ });
++
++ _res.options |= RES_NOAAAA;
++
++ for (int do_stuff_txt = 0; do_stuff_txt < 2; ++do_stuff_txt)
++ {
++ queries = 0;
++ stuff_txt = do_stuff_txt;
++
++ struct addrinfo *ai = NULL;
++ int ret;
++ ret = getaddrinfo ("example.com", "80",
++ &(struct addrinfo)
++ {
++ .ai_family = AF_UNSPEC,
++ .ai_socktype = SOCK_STREAM,
++ }, &ai);
++
++ char *expected_result;
++ {
++ struct xmemstream mem;
++ xopen_memstream (&mem);
++ for (int i = 0; i < 200; ++i)
++ fprintf (mem.out, "address: STREAM/TCP 192.0.2.%d 80\n", i + 1);
++ xfclose_memstream (&mem);
++ expected_result = mem.buffer;
++ }
++
++ check_addrinfo ("example.com", ai, ret, expected_result);
++
++ free (expected_result);
++ freeaddrinfo (ai);
++ }
++
++ resolv_test_end (obj);
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.33.0
+
diff --git a/Decrease-value-of-arch_minimum_kernel-with-LoongArch.patch b/Decrease-value-of-arch_minimum_kernel-with-LoongArch.patch
new file mode 100644
index 0000000..0c43817
--- /dev/null
+++ b/Decrease-value-of-arch_minimum_kernel-with-LoongArch.patch
@@ -0,0 +1,40 @@
+From 2c8dfc45a8009e5110a9d2148b62d802e989fde7 Mon Sep 17 00:00:00 2001
+From: ticat_fp <fanpeng@loongson.cn>
+Date: Thu, 29 Feb 2024 15:58:31 +0800
+Subject: [PATCH] Decrease value of arch_minimum_kernel with LoongArch
+
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/unix/sysv/linux/loongarch/configure | 2 +-
+ sysdeps/unix/sysv/linux/loongarch/configure.ac | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sysdeps/unix/sysv/linux/loongarch/configure b/sysdeps/unix/sysv/linux/loongarch/configure
+index 0d1159e9..851b2285 100644
+--- a/sysdeps/unix/sysv/linux/loongarch/configure
++++ b/sysdeps/unix/sysv/linux/loongarch/configure
+@@ -1,7 +1,7 @@
+ # This file is generated from configure.ac by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/unix/sysv/linux/loongarch.
+
+-arch_minimum_kernel=5.19.0
++arch_minimum_kernel=4.19.0
+
+ libc_cv_loongarch_int_abi=no
+
+diff --git a/sysdeps/unix/sysv/linux/loongarch/configure.ac b/sysdeps/unix/sysv/linux/loongarch/configure.ac
+index 04e9150a..00815c2f 100644
+--- a/sysdeps/unix/sysv/linux/loongarch/configure.ac
++++ b/sysdeps/unix/sysv/linux/loongarch/configure.ac
+@@ -2,7 +2,7 @@ sinclude(./aclocal.m4)dnl Autoconf lossage
+ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+ # Local configure fragment for sysdeps/unix/sysv/linux/loongarch.
+
+-arch_minimum_kernel=5.19.0
++arch_minimum_kernel=4.19.0
+
+ libc_cv_loongarch_int_abi=no
+ AC_EGREP_CPP(4 8 8, [__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__
+--
+2.33.0
+
diff --git a/Fix-name-space-violation-in-fortify-wrappers-bug-320.patch b/Fix-name-space-violation-in-fortify-wrappers-bug-320.patch
new file mode 100644
index 0000000..daab1bf
--- /dev/null
+++ b/Fix-name-space-violation-in-fortify-wrappers-bug-320.patch
@@ -0,0 +1,298 @@
+From 059f82c3b9bd929182195c163c6d7f3bbffabf51 Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@suse.de>
+Date: Mon, 5 Aug 2024 10:55:51 +0200
+Subject: [PATCH] Fix name space violation in fortify wrappers (bug 32052)
+
+Rename the identifier sz to __sz everywhere.
+
+Fixes: a643f60c53 ("Make sure that the fortified function conditionals are constant")
+(cherry picked from commit 39ca997ab378990d5ac1aadbaa52aaf1db6d526f)
+(redone from scratch because of many conflicts)
+---
+ NEWS | 2 +-
+ libio/bits/stdio2.h | 40 +++++++++++++++----------------
+ socket/bits/socket2.h | 20 ++++++++--------
+ stdlib/bits/stdlib.h | 10 ++++----
+ wcsmbs/bits/wchar2.h | 56 +++++++++++++++++++++----------------------
+ 5 files changed, 64 insertions(+), 64 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 5172049eb2..7a9a4b7ea3 100644
+--- a/NEWS
++++ b/NEWS
+@@ -56,7 +56,7 @@ The following bugs are resolved with this release:
+ [31890] resolv: Allow short error responses to match any DNS query
+ [31965] rseq extension mechanism does not work as intended
+ [31968] mremap implementation in C does not handle arguments correctly
+-
++ [32052] Name space violation in fortify wrappers
+
+ Version 2.38
+
+diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
+index 71226408ab..6cecd1b956 100644
+--- a/libio/bits/stdio2.h
++++ b/libio/bits/stdio2.h
+@@ -194,36 +194,36 @@ gets (char *__str)
+ __fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char *
+ fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
+ {
+- size_t sz = __glibc_objsize (__s);
+- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
++ size_t __sz = __glibc_objsize (__s);
++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
+ return __fgets_alias (__s, __n, __stream);
+- if (__glibc_unsafe_len (__n, sizeof (char), sz))
+- return __fgets_chk_warn (__s, sz, __n, __stream);
+- return __fgets_chk (__s, sz, __n, __stream);
++ if (__glibc_unsafe_len (__n, sizeof (char), __sz))
++ return __fgets_chk_warn (__s, __sz, __n, __stream);
++ return __fgets_chk (__s, __sz, __n, __stream);
+ }
+
+ __fortify_function __wur size_t
+ fread (void *__restrict __ptr, size_t __size, size_t __n,
+ FILE *__restrict __stream)
+ {
+- size_t sz = __glibc_objsize0 (__ptr);
+- if (__glibc_safe_or_unknown_len (__n, __size, sz))
++ size_t __sz = __glibc_objsize0 (__ptr);
++ if (__glibc_safe_or_unknown_len (__n, __size, __sz))
+ return __fread_alias (__ptr, __size, __n, __stream);
+- if (__glibc_unsafe_len (__n, __size, sz))
+- return __fread_chk_warn (__ptr, sz, __size, __n, __stream);
+- return __fread_chk (__ptr, sz, __size, __n, __stream);
++ if (__glibc_unsafe_len (__n, __size, __sz))
++ return __fread_chk_warn (__ptr, __sz, __size, __n, __stream);
++ return __fread_chk (__ptr, __sz, __size, __n, __stream);
+ }
+
+ #ifdef __USE_GNU
+ __fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char *
+ fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
+ {
+- size_t sz = __glibc_objsize (__s);
+- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
++ size_t __sz = __glibc_objsize (__s);
++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
+ return __fgets_unlocked_alias (__s, __n, __stream);
+- if (__glibc_unsafe_len (__n, sizeof (char), sz))
+- return __fgets_unlocked_chk_warn (__s, sz, __n, __stream);
+- return __fgets_unlocked_chk (__s, sz, __n, __stream);
++ if (__glibc_unsafe_len (__n, sizeof (char), __sz))
++ return __fgets_unlocked_chk_warn (__s, __sz, __n, __stream);
++ return __fgets_unlocked_chk (__s, __sz, __n, __stream);
+ }
+ #endif
+
+@@ -233,8 +233,8 @@ __fortify_function __wur size_t
+ fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
+ FILE *__restrict __stream)
+ {
+- size_t sz = __glibc_objsize0 (__ptr);
+- if (__glibc_safe_or_unknown_len (__n, __size, sz))
++ size_t __sz = __glibc_objsize0 (__ptr);
++ if (__glibc_safe_or_unknown_len (__n, __size, __sz))
+ {
+ # ifdef __USE_EXTERN_INLINES
+ if (__builtin_constant_p (__size)
+@@ -259,9 +259,9 @@ fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
+ # endif
+ return __fread_unlocked_alias (__ptr, __size, __n, __stream);
+ }
+- if (__glibc_unsafe_len (__n, __size, sz))
+- return __fread_unlocked_chk_warn (__ptr, sz, __size, __n, __stream);
+- return __fread_unlocked_chk (__ptr, sz, __size, __n, __stream);
++ if (__glibc_unsafe_len (__n, __size, __sz))
++ return __fread_unlocked_chk_warn (__ptr, __sz, __size, __n, __stream);
++ return __fread_unlocked_chk (__ptr, __sz, __size, __n, __stream);
+
+ }
+ #endif
+diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h
+index ffcc671625..5ed2498782 100644
+--- a/socket/bits/socket2.h
++++ b/socket/bits/socket2.h
+@@ -33,12 +33,12 @@ extern ssize_t __REDIRECT (__recv_chk_warn,
+ __fortify_function ssize_t
+ recv (int __fd, void *__buf, size_t __n, int __flags)
+ {
+- size_t sz = __glibc_objsize0 (__buf);
+- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
++ size_t __sz = __glibc_objsize0 (__buf);
++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
+ return __recv_alias (__fd, __buf, __n, __flags);
+- if (__glibc_unsafe_len (__n, sizeof (char), sz))
+- return __recv_chk_warn (__fd, __buf, __n, sz, __flags);
+- return __recv_chk (__fd, __buf, __n, sz, __flags);
++ if (__glibc_unsafe_len (__n, sizeof (char), __sz))
++ return __recv_chk_warn (__fd, __buf, __n, __sz, __flags);
++ return __recv_chk (__fd, __buf, __n, __sz, __flags);
+ }
+
+ extern ssize_t __recvfrom_chk (int __fd, void *__restrict __buf, size_t __n,
+@@ -61,11 +61,11 @@ __fortify_function ssize_t
+ recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags,
+ __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len)
+ {
+- size_t sz = __glibc_objsize0 (__buf);
+- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
++ size_t __sz = __glibc_objsize0 (__buf);
++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
+ return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len);
+- if (__glibc_unsafe_len (__n, sizeof (char), sz))
+- return __recvfrom_chk_warn (__fd, __buf, __n, sz, __flags, __addr,
++ if (__glibc_unsafe_len (__n, sizeof (char), __sz))
++ return __recvfrom_chk_warn (__fd, __buf, __n, __sz, __flags, __addr,
+ __addr_len);
+- return __recvfrom_chk (__fd, __buf, __n, sz, __flags, __addr, __addr_len);
++ return __recvfrom_chk (__fd, __buf, __n, __sz, __flags, __addr, __addr_len);
+ }
+diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
+index c6c0082ad5..ef33180f10 100644
+--- a/stdlib/bits/stdlib.h
++++ b/stdlib/bits/stdlib.h
+@@ -36,16 +36,16 @@ extern char *__REDIRECT_NTH (__realpath_chk_warn,
+ __fortify_function __wur char *
+ __NTH (realpath (const char *__restrict __name, char *__restrict __resolved))
+ {
+- size_t sz = __glibc_objsize (__resolved);
++ size_t __sz = __glibc_objsize (__resolved);
+
+- if (sz == (size_t) -1)
++ if (__sz == (size_t) -1)
+ return __realpath_alias (__name, __resolved);
+
+ #if defined _LIBC_LIMITS_H_ && defined PATH_MAX
+- if (__glibc_unsafe_len (PATH_MAX, sizeof (char), sz))
+- return __realpath_chk_warn (__name, __resolved, sz);
++ if (__glibc_unsafe_len (PATH_MAX, sizeof (char), __sz))
++ return __realpath_chk_warn (__name, __resolved, __sz);
+ #endif
+- return __realpath_chk (__name, __resolved, sz);
++ return __realpath_chk (__name, __resolved, __sz);
+ }
+
+
+diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
+index 6e6234d606..44c1643565 100644
+--- a/wcsmbs/bits/wchar2.h
++++ b/wcsmbs/bits/wchar2.h
+@@ -59,18 +59,18 @@ __NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n))
+ __fortify_function wchar_t *
+ __NTH (wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
+ {
+- size_t sz = __glibc_objsize (__dest);
+- if (sz != (size_t) -1)
+- return __wcscpy_chk (__dest, __src, sz / sizeof (wchar_t));
++ size_t __sz = __glibc_objsize (__dest);
++ if (__sz != (size_t) -1)
++ return __wcscpy_chk (__dest, __src, __sz / sizeof (wchar_t));
+ return __wcscpy_alias (__dest, __src);
+ }
+
+ __fortify_function wchar_t *
+ __NTH (wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
+ {
+- size_t sz = __glibc_objsize (__dest);
+- if (sz != (size_t) -1)
+- return __wcpcpy_chk (__dest, __src, sz / sizeof (wchar_t));
++ size_t __sz = __glibc_objsize (__dest);
++ if (__sz != (size_t) -1)
++ return __wcpcpy_chk (__dest, __src, __sz / sizeof (wchar_t));
+ return __wcpcpy_alias (__dest, __src);
+ }
+
+@@ -95,9 +95,9 @@ __NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
+ __fortify_function wchar_t *
+ __NTH (wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
+ {
+- size_t sz = __glibc_objsize (__dest);
+- if (sz != (size_t) -1)
+- return __wcscat_chk (__dest, __src, sz / sizeof (wchar_t));
++ size_t __sz = __glibc_objsize (__dest);
++ if (__sz != (size_t) -1)
++ return __wcscat_chk (__dest, __src, __sz / sizeof (wchar_t));
+ return __wcscat_alias (__dest, __src);
+ }
+
+@@ -105,9 +105,9 @@ __fortify_function wchar_t *
+ __NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
+ size_t __n))
+ {
+- size_t sz = __glibc_objsize (__dest);
+- if (sz != (size_t) -1)
+- return __wcsncat_chk (__dest, __src, __n, sz / sizeof (wchar_t));
++ size_t __sz = __glibc_objsize (__dest);
++ if (__sz != (size_t) -1)
++ return __wcsncat_chk (__dest, __src, __n, __sz / sizeof (wchar_t));
+ return __wcsncat_alias (__dest, __src, __n);
+ }
+
+@@ -144,10 +144,10 @@ __fortify_function int
+ __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
+ const wchar_t *__restrict __fmt, ...))
+ {
+- size_t sz = __glibc_objsize (__s);
+- if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
++ size_t __sz = __glibc_objsize (__s);
++ if (__sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
+ return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
+- sz / sizeof (wchar_t), __fmt, __va_arg_pack ());
++ __sz / sizeof (wchar_t), __fmt, __va_arg_pack ());
+ return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
+ }
+ #elif !defined __cplusplus
+@@ -163,10 +163,10 @@ __fortify_function int
+ __NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
+ const wchar_t *__restrict __fmt, __gnuc_va_list __ap))
+ {
+- size_t sz = __glibc_objsize (__s);
+- if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
++ size_t __sz = __glibc_objsize (__s);
++ if (__sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
+ return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
+- sz / sizeof (wchar_t), __fmt, __ap);
++ __sz / sizeof (wchar_t), __fmt, __ap);
+ return __vswprintf_alias (__s, __n, __fmt, __ap);
+ }
+
+@@ -210,25 +210,25 @@ vfwprintf (__FILE *__restrict __stream,
+ __fortify_function __wur wchar_t *
+ fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
+ {
+- size_t sz = __glibc_objsize (__s);
+- if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz))
++ size_t __sz = __glibc_objsize (__s);
++ if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), __sz))
+ return __fgetws_alias (__s, __n, __stream);
+- if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz))
+- return __fgetws_chk_warn (__s, sz / sizeof (wchar_t), __n, __stream);
+- return __fgetws_chk (__s, sz / sizeof (wchar_t), __n, __stream);
++ if (__glibc_unsafe_len (__n, sizeof (wchar_t), __sz))
++ return __fgetws_chk_warn (__s, __sz / sizeof (wchar_t), __n, __stream);
++ return __fgetws_chk (__s, __sz / sizeof (wchar_t), __n, __stream);
+ }
+
+ #ifdef __USE_GNU
+ __fortify_function __wur wchar_t *
+ fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
+ {
+- size_t sz = __glibc_objsize (__s);
+- if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz))
++ size_t __sz = __glibc_objsize (__s);
++ if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), __sz))
+ return __fgetws_unlocked_alias (__s, __n, __stream);
+- if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz))
+- return __fgetws_unlocked_chk_warn (__s, sz / sizeof (wchar_t), __n,
++ if (__glibc_unsafe_len (__n, sizeof (wchar_t), __sz))
++ return __fgetws_unlocked_chk_warn (__s, __sz / sizeof (wchar_t), __n,
+ __stream);
+- return __fgetws_unlocked_chk (__s, sz / sizeof (wchar_t), __n, __stream);
++ return __fgetws_unlocked_chk (__s, __sz / sizeof (wchar_t), __n, __stream);
+ }
+ #endif
+
+--
+2.33.0
+
diff --git a/Force-DT_RPATH-for-enable-hardcoded-path-in-tests.patch b/Force-DT_RPATH-for-enable-hardcoded-path-in-tests.patch
new file mode 100644
index 0000000..aff97d9
--- /dev/null
+++ b/Force-DT_RPATH-for-enable-hardcoded-path-in-tests.patch
@@ -0,0 +1,50 @@
+From 249646f12b08f3dbd9a8e8b8021e5c0e3a0b7e1e Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Thu, 9 May 2024 20:07:01 -0700
+Subject: [PATCH] Force DT_RPATH for --enable-hardcoded-path-in-tests
+
+On Fedora 40/x86-64, linker enables --enable-new-dtags by default which
+generates DT_RUNPATH instead of DT_RPATH. Unlike DT_RPATH, DT_RUNPATH
+only applies to DT_NEEDED entries in the executable and doesn't applies
+to DT_NEEDED entries in shared libraries which are loaded via DT_NEEDED
+entries in the executable. Some glibc tests have libstdc++.so.6 in
+DT_NEEDED, which has libm.so.6 in DT_NEEDED. When DT_RUNPATH is generated,
+/lib64/libm.so.6 is loaded for such tests. If the newly built glibc is
+older than glibc 2.36, these tests fail with
+
+assert/tst-assert-c++: /export/build/gnu/tools-build/glibc-gitlab-release/build-x86_64-linux/libc.so.6: version `GLIBC_2.36' not found (required by /lib64/libm.so.6)
+assert/tst-assert-c++: /export/build/gnu/tools-build/glibc-gitlab-release/build-x86_64-linux/libc.so.6: version `GLIBC_ABI_DT_RELR' not found (required by /lib64/libm.so.6)
+
+Pass -Wl,--disable-new-dtags to linker when building glibc tests with
+--enable-hardcoded-path-in-tests. This fixes BZ #31719.
+
+Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
+(cherry picked from commit 2dcaf70643710e22f92a351e36e3cff8b48c60dc)
+---
+ Makeconfig | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/Makeconfig b/Makeconfig
+index 77d7fd14df..3f8acff459 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -586,10 +586,13 @@ link-libc-rpath-link = -Wl,-rpath-link=$(rpath-link)
+ # before the expansion of LDLIBS-* variables).
+
+ # Tests use -Wl,-rpath instead of -Wl,-rpath-link for
+-# build-hardcoded-path-in-tests.
++# build-hardcoded-path-in-tests. Add -Wl,--disable-new-dtags to force
++# DT_RPATH instead of DT_RUNPATH which only applies to DT_NEEDED entries
++# in the executable and doesn't applies to DT_NEEDED entries in shared
++# libraries which are loaded via DT_NEEDED entries in the executable.
+ ifeq (yes,$(build-hardcoded-path-in-tests))
+-link-libc-tests-rpath-link = $(link-libc-rpath)
+-link-test-modules-rpath-link = $(link-libc-rpath)
++link-libc-tests-rpath-link = $(link-libc-rpath) -Wl,--disable-new-dtags
++link-test-modules-rpath-link = $(link-libc-rpath) -Wl,--disable-new-dtags
+ else
+ link-libc-tests-rpath-link = $(link-libc-rpath-link)
+ link-test-modules-rpath-link =
+--
+2.33.0
+
diff --git a/LanguageList b/LanguageList
new file mode 100644
index 0000000..7ae6391
--- /dev/null
+++ b/LanguageList
@@ -0,0 +1,196 @@
+glibc-langpack-aa
+glibc-langpack-af
+glibc-langpack-agr
+glibc-langpack-ak
+glibc-langpack-am
+glibc-langpack-an
+glibc-langpack-anp
+glibc-langpack-ar
+glibc-langpack-as
+glibc-langpack-ast
+glibc-langpack-ayc
+glibc-langpack-az
+glibc-langpack-be
+glibc-langpack-bem
+glibc-langpack-ber
+glibc-langpack-bg
+glibc-langpack-bhb
+glibc-langpack-bho
+glibc-langpack-bi
+glibc-langpack-bn
+glibc-langpack-bo
+glibc-langpack-br
+glibc-langpack-brx
+glibc-langpack-bs
+glibc-langpack-byn
+glibc-langpack-ca
+glibc-langpack-ce
+glibc-langpack-chr
+glibc-langpack-cmn
+glibc-langpack-crh
+glibc-langpack-cs
+glibc-langpack-csb
+glibc-langpack-cv
+glibc-langpack-cy
+glibc-langpack-da
+glibc-langpack-de
+glibc-langpack-doi
+glibc-langpack-dsb
+glibc-langpack-dv
+glibc-langpack-dz
+glibc-langpack-el
+glibc-langpack-en
+glibc-langpack-eo
+glibc-langpack-es
+glibc-langpack-et
+glibc-langpack-eu
+glibc-langpack-fa
+glibc-langpack-ff
+glibc-langpack-fi
+glibc-langpack-fil
+glibc-langpack-fo
+glibc-langpack-fr
+glibc-langpack-fur
+glibc-langpack-fy
+glibc-langpack-ga
+glibc-langpack-gd
+glibc-langpack-gez
+glibc-langpack-gl
+glibc-langpack-gu
+glibc-langpack-gv
+glibc-langpack-ha
+glibc-langpack-hak
+glibc-langpack-he
+glibc-langpack-hi
+glibc-langpack-hif
+glibc-langpack-hne
+glibc-langpack-hr
+glibc-langpack-hsb
+glibc-langpack-ht
+glibc-langpack-hu
+glibc-langpack-hy
+glibc-langpack-ia
+glibc-langpack-id
+glibc-langpack-ig
+glibc-langpack-ik
+glibc-langpack-is
+glibc-langpack-it
+glibc-langpack-iu
+glibc-langpack-ja
+glibc-langpack-ka
+glibc-langpack-kab
+glibc-langpack-kk
+glibc-langpack-kl
+glibc-langpack-km
+glibc-langpack-kn
+glibc-langpack-ko
+glibc-langpack-kok
+glibc-langpack-ks
+glibc-langpack-ku
+glibc-langpack-kw
+glibc-langpack-ky
+glibc-langpack-lb
+glibc-langpack-lg
+glibc-langpack-li
+glibc-langpack-lij
+glibc-langpack-ln
+glibc-langpack-lo
+glibc-langpack-lt
+glibc-langpack-lv
+glibc-langpack-lzh
+glibc-langpack-mag
+glibc-langpack-mai
+glibc-langpack-mfe
+glibc-langpack-mg
+glibc-langpack-mhr
+glibc-langpack-mi
+glibc-langpack-miq
+glibc-langpack-mjw
+glibc-langpack-mk
+glibc-langpack-ml
+glibc-langpack-mn
+glibc-langpack-mni
+glibc-langpack-mr
+glibc-langpack-ms
+glibc-langpack-mt
+glibc-langpack-my
+glibc-langpack-nan
+glibc-langpack-nb
+glibc-langpack-nds
+glibc-langpack-ne
+glibc-langpack-nhn
+glibc-langpack-niu
+glibc-langpack-nl
+glibc-langpack-nn
+glibc-langpack-nr
+glibc-langpack-nso
+glibc-langpack-oc
+glibc-langpack-om
+glibc-langpack-or
+glibc-langpack-os
+glibc-langpack-pa
+glibc-langpack-pap
+glibc-langpack-pl
+glibc-langpack-ps
+glibc-langpack-pt
+glibc-langpack-quz
+glibc-langpack-raj
+glibc-langpack-ro
+glibc-langpack-ru
+glibc-langpack-rw
+glibc-langpack-sa
+glibc-langpack-sah
+glibc-langpack-sat
+glibc-langpack-sc
+glibc-langpack-sd
+glibc-langpack-se
+glibc-langpack-sgs
+glibc-langpack-shn
+glibc-langpack-shs
+glibc-langpack-si
+glibc-langpack-sid
+glibc-langpack-sk
+glibc-langpack-sl
+glibc-langpack-sm
+glibc-langpack-so
+glibc-langpack-sq
+glibc-langpack-sr
+glibc-langpack-ss
+glibc-langpack-st
+glibc-langpack-sv
+glibc-langpack-sw
+glibc-langpack-szl
+glibc-langpack-ta
+glibc-langpack-tcy
+glibc-langpack-te
+glibc-langpack-tg
+glibc-langpack-th
+glibc-langpack-the
+glibc-langpack-ti
+glibc-langpack-tig
+glibc-langpack-tk
+glibc-langpack-tl
+glibc-langpack-tn
+glibc-langpack-to
+glibc-langpack-tpi
+glibc-langpack-tr
+glibc-langpack-ts
+glibc-langpack-tt
+glibc-langpack-ug
+glibc-langpack-uk
+glibc-langpack-unm
+glibc-langpack-ur
+glibc-langpack-uz
+glibc-langpack-ve
+glibc-langpack-vi
+glibc-langpack-wa
+glibc-langpack-wae
+glibc-langpack-wal
+glibc-langpack-wo
+glibc-langpack-xh
+glibc-langpack-yi
+glibc-langpack-yo
+glibc-langpack-yue
+glibc-langpack-yuw
+glibc-langpack-zh
+glibc-langpack-zu
diff --git a/LicenseList b/LicenseList
new file mode 100644
index 0000000..bcffe7a
--- /dev/null
+++ b/LicenseList
@@ -0,0 +1,26 @@
+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.
+
diff --git a/LoongArch-Add-glibc.cpu.hwcap-support.patch b/LoongArch-Add-glibc.cpu.hwcap-support.patch
new file mode 100644
index 0000000..3629d05
--- /dev/null
+++ b/LoongArch-Add-glibc.cpu.hwcap-support.patch
@@ -0,0 +1,499 @@
+From 8923e4e9c79e672fd6b3b89aba598a60d5c01211 Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Fri, 15 Sep 2023 17:35:19 +0800
+Subject: [PATCH 25/29] LoongArch: Add glibc.cpu.hwcap support.
+
+Key Points:
+1. On lasx & lsx platforms, We must use _dl_runtime_{profile, resolve}_{lsx, lasx}
+ to save vector registers.
+2. Via "tunables", users can choose str/mem_{lasx,lsx,unaligned} functions with
+ `export GLIBC_TUNABLES=glibc.cpu.hwcaps=LASX,...`.
+ Note: glibc.cpu.hwcaps doesn't affect _dl_runtime_{profile, resolve}_{lsx, lasx}
+ selection.
+
+Usage Notes:
+1. Only valid inputs: LASX, LSX, UAL. Case-sensitive, comma-separated, no spaces.
+2. Example: `export GLIBC_TUNABLES=glibc.cpu.hwcaps=LASX,UAL` turns on LASX & UAL.
+ Unmentioned features turn off. With default ifunc: lasx > lsx > unaligned >
+ aligned > generic, effect is: lasx > unaligned > aligned > generic; lsx off.
+3. Incorrect GLIBC_TUNABLES settings will show error messages.
+ For example: On lsx platforms, you cannot enable lasx features. If you do
+ that, you will get error messages.
+4. Valid input examples:
+ - GLIBC_TUNABLES=glibc.cpu.hwcaps=LASX: lasx > aligned > generic.
+ - GLIBC_TUNABLES=glibc.cpu.hwcaps=LSX,UAL: lsx > unaligned > aligned > generic.
+ - GLIBC_TUNABLES=glibc.cpu.hwcaps=LASX,UAL,LASX,UAL,LSX,LASX,UAL: Repetitions
+ allowed but not recommended. Results in: lasx > lsx > unaligned > aligned >
+ generic.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/Makefile | 4 +
+ sysdeps/loongarch/Versions | 5 ++
+ sysdeps/loongarch/cpu-tunables.c | 89 +++++++++++++++++++
+ sysdeps/loongarch/dl-get-cpu-features.c | 25 ++++++
+ sysdeps/loongarch/dl-machine.h | 27 +++++-
+ sysdeps/loongarch/dl-tunables.list | 25 ++++++
+ .../unix/sysv/linux/loongarch/cpu-features.c | 29 ++++++
+ .../unix/sysv/linux/loongarch/cpu-features.h | 18 +++-
+ .../unix/sysv/linux/loongarch/dl-procinfo.c | 60 +++++++++++++
+ sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c | 21 +++++
+ .../unix/sysv/linux/loongarch/libc-start.c | 34 +++++++
+ 11 files changed, 329 insertions(+), 8 deletions(-)
+ create mode 100644 sysdeps/loongarch/Versions
+ create mode 100644 sysdeps/loongarch/cpu-tunables.c
+ create mode 100644 sysdeps/loongarch/dl-get-cpu-features.c
+ create mode 100644 sysdeps/loongarch/dl-tunables.list
+ create mode 100644 sysdeps/unix/sysv/linux/loongarch/cpu-features.c
+ create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c
+ create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c
+ create mode 100644 sysdeps/unix/sysv/linux/loongarch/libc-start.c
+
+diff --git a/sysdeps/loongarch/Makefile b/sysdeps/loongarch/Makefile
+index 43d2f583..30a1f4a8 100644
+--- a/sysdeps/loongarch/Makefile
++++ b/sysdeps/loongarch/Makefile
+@@ -6,6 +6,10 @@ ifeq ($(subdir),elf)
+ gen-as-const-headers += dl-link.sym
+ endif
+
++ifeq ($(subdir),elf)
++ sysdep-dl-routines += dl-get-cpu-features
++endif
++
+ # LoongArch's assembler also needs to know about PIC as it changes the
+ # definition of some assembler macros.
+ ASFLAGS-.os += $(pic-ccflag)
+diff --git a/sysdeps/loongarch/Versions b/sysdeps/loongarch/Versions
+new file mode 100644
+index 00000000..33ae2cc0
+--- /dev/null
++++ b/sysdeps/loongarch/Versions
+@@ -0,0 +1,5 @@
++ld {
++ GLIBC_PRIVATE {
++ _dl_larch_get_cpu_features;
++ }
++}
+diff --git a/sysdeps/loongarch/cpu-tunables.c b/sysdeps/loongarch/cpu-tunables.c
+new file mode 100644
+index 00000000..8e9fab93
+--- /dev/null
++++ b/sysdeps/loongarch/cpu-tunables.c
+@@ -0,0 +1,89 @@
++/* LoongArch CPU feature tuning.
++ This file is part of the GNU C Library.
++ Copyright (C) 2023 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
++ <http://www.gnu.org/licenses/>. */
++
++# include <stdbool.h>
++# include <stdint.h>
++# include <unistd.h> /* Get STDOUT_FILENO for _dl_printf. */
++# include <elf/dl-tunables.h>
++# include <string.h>
++# include <cpu-features.h>
++# include <ldsodefs.h>
++# include <sys/auxv.h>
++
++# define HWCAP_LOONGARCH_IFUNC \
++ (HWCAP_LOONGARCH_UAL | HWCAP_LOONGARCH_LSX | HWCAP_LOONGARCH_LASX)
++
++# define CHECK_GLIBC_IFUNC_CPU_OFF(f, name, len) \
++ _Static_assert (sizeof (#name) - 1 == len, #name " != " #len); \
++ if (!memcmp (f, #name, len) && \
++ (GLRO (dl_hwcap) & HWCAP_LOONGARCH_##name)) \
++ { \
++ hwcap |= (HWCAP_LOONGARCH_##name | (~HWCAP_LOONGARCH_IFUNC)); \
++ break; \
++ } \
++
++attribute_hidden
++void
++TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
++{
++ const char *p = valp->strval;
++ size_t len;
++ unsigned long hwcap = 0;
++ const char *c;
++
++ do {
++ for (c = p; *c != ','; c++)
++ if (*c == '\0')
++ break;
++
++ len = c - p;
++
++ switch(len)
++ {
++ default:
++ _dl_fatal_printf (
++ "The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!\n"
++ );
++ break;
++ case 3:
++ {
++ CHECK_GLIBC_IFUNC_CPU_OFF (p, LSX, 3);
++ CHECK_GLIBC_IFUNC_CPU_OFF (p, UAL, 3);
++ _dl_fatal_printf (
++ "Some features are invalid or not supported on this machine!!\n"
++ "The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!\n"
++ );
++ }
++ break;
++ case 4:
++ {
++ CHECK_GLIBC_IFUNC_CPU_OFF (p, LASX, 4);
++ _dl_fatal_printf (
++ "Some features are invalid or not supported on this machine!!\n"
++ "The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!\n"
++ );
++ }
++ break;
++ }
++
++ p += len + 1;
++ }
++ while (*c != '\0');
++
++ GLRO (dl_larch_cpu_features).hwcap &= hwcap;
++}
+diff --git a/sysdeps/loongarch/dl-get-cpu-features.c b/sysdeps/loongarch/dl-get-cpu-features.c
+new file mode 100644
+index 00000000..7cd9bc15
+--- /dev/null
++++ b/sysdeps/loongarch/dl-get-cpu-features.c
+@@ -0,0 +1,25 @@
++/* Define _dl_larch_get_cpu_features.
++ Copyright (C) 2023 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
++ <https://www.gnu.org/licenses/>. */
++
++
++#include <ldsodefs.h>
++
++const struct cpu_features *
++_dl_larch_get_cpu_features (void)
++{
++ return &GLRO(dl_larch_cpu_features);
++}
+diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
+index 57913cef..b395a928 100644
+--- a/sysdeps/loongarch/dl-machine.h
++++ b/sysdeps/loongarch/dl-machine.h
+@@ -29,6 +29,8 @@
+ #include <dl-static-tls.h>
+ #include <dl-machine-rel.h>
+
++#include <cpu-features.c>
++
+ #ifndef _RTLD_PROLOGUE
+ # define _RTLD_PROLOGUE(entry) \
+ ".globl\t" __STRING (entry) "\n\t" \
+@@ -53,6 +55,23 @@
+ #define ELF_MACHINE_NO_REL 1
+ #define ELF_MACHINE_NO_RELA 0
+
++#define DL_PLATFORM_INIT dl_platform_init ()
++
++static inline void __attribute__ ((unused))
++dl_platform_init (void)
++{
++ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
++ /* Avoid an empty string which would disturb us. */
++ GLRO(dl_platform) = NULL;
++
++#ifdef SHARED
++ /* init_cpu_features has been called early from __libc_start_main in
++ static executable. */
++ init_cpu_features (&GLRO(dl_larch_cpu_features));
++#endif
++}
++
++
+ /* Return nonzero iff ELF header is compatible with the running host. */
+ static inline int
+ elf_machine_matches_host (const ElfW (Ehdr) *ehdr)
+@@ -290,9 +309,9 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+ if (profile != 0)
+ {
+ #if !defined __loongarch_soft_float
+- if (SUPPORT_LASX)
++ if (RTLD_SUPPORT_LASX)
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile_lasx;
+- else if (SUPPORT_LSX)
++ else if (RTLD_SUPPORT_LSX)
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile_lsx;
+ else
+ #endif
+@@ -310,9 +329,9 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+ indicated by the offset on the stack, and then jump to
+ the resolved address. */
+ #if !defined __loongarch_soft_float
+- if (SUPPORT_LASX)
++ if (RTLD_SUPPORT_LASX)
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve_lasx;
+- else if (SUPPORT_LSX)
++ else if (RTLD_SUPPORT_LSX)
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve_lsx;
+ else
+ #endif
+diff --git a/sysdeps/loongarch/dl-tunables.list b/sysdeps/loongarch/dl-tunables.list
+new file mode 100644
+index 00000000..66b34275
+--- /dev/null
++++ b/sysdeps/loongarch/dl-tunables.list
+@@ -0,0 +1,25 @@
++# LoongArch specific tunables.
++# 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
++# <http://www.gnu.org/licenses/>.
++
++glibc {
++ cpu {
++ hwcaps {
++ type: STRING
++ }
++ }
++}
+diff --git a/sysdeps/unix/sysv/linux/loongarch/cpu-features.c b/sysdeps/unix/sysv/linux/loongarch/cpu-features.c
+new file mode 100644
+index 00000000..1290c4ce
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.c
+@@ -0,0 +1,29 @@
++/* Initialize CPU feature data. LoongArch64 version.
++ This file is part of the GNU C Library.
++ Copyright (C) 2023 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
++ <http://www.gnu.org/licenses/>. */
++
++#include <cpu-features.h>
++#include <elf/dl-hwcaps.h>
++#include <elf/dl-tunables.h>
++extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) attribute_hidden;
++
++static inline void
++init_cpu_features (struct cpu_features *cpu_features)
++{
++ GLRO (dl_larch_cpu_features).hwcap = GLRO (dl_hwcap);
++ TUNABLE_GET (glibc, cpu, hwcaps, tunable_val_t *, TUNABLE_CALLBACK (set_hwcaps));
++}
+diff --git a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
+index d1a280a5..450963ce 100644
+--- a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
++++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
+@@ -19,13 +19,23 @@
+ #ifndef _CPU_FEATURES_LOONGARCH64_H
+ #define _CPU_FEATURES_LOONGARCH64_H
+
++#include <stdint.h>
+ #include <sys/auxv.h>
+
+-#define SUPPORT_UAL (GLRO (dl_hwcap) & HWCAP_LOONGARCH_UAL)
+-#define SUPPORT_LSX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LSX)
+-#define SUPPORT_LASX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LASX)
++struct cpu_features
++ {
++ uint64_t hwcap;
++ };
+
++/* Get a pointer to the CPU features structure. */
++extern const struct cpu_features *_dl_larch_get_cpu_features (void)
++ __attribute__ ((pure));
++
++#define SUPPORT_UAL (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_UAL)
++#define SUPPORT_LSX (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_LSX)
++#define SUPPORT_LASX (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_LASX)
++#define RTLD_SUPPORT_LSX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LSX)
++#define RTLD_SUPPORT_LASX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LASX)
+ #define INIT_ARCH()
+
+ #endif /* _CPU_FEATURES_LOONGARCH64_H */
+-
+diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c b/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c
+new file mode 100644
+index 00000000..6217fda9
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c
+@@ -0,0 +1,60 @@
++/* Data for LoongArch64 version of processor capability information.
++ Linux version.
++ 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
++ <http://www.gnu.org/licenses/>. */
++
++/* If anything should be added here check whether the size of each string
++ is still ok with the given array size.
++
++ All the #ifdefs in the definitions are quite irritating but
++ necessary if we want to avoid duplicating the information. There
++ are three different modes:
++
++ - PROCINFO_DECL is defined. This means we are only interested in
++ declarations.
++
++ - PROCINFO_DECL is not defined:
++
++ + if SHARED is defined the file is included in an array
++ initializer. The .element = { ... } syntax is needed.
++
++ + if SHARED is not defined a normal array initialization is
++ needed.
++ */
++
++#ifndef PROCINFO_CLASS
++# define PROCINFO_CLASS
++#endif
++
++#if !IS_IN (ldconfig)
++# if !defined PROCINFO_DECL && defined SHARED
++ ._dl_larch_cpu_features
++# else
++PROCINFO_CLASS struct cpu_features _dl_larch_cpu_features
++# endif
++# ifndef PROCINFO_DECL
++= { }
++# endif
++# if !defined SHARED || defined PROCINFO_DECL
++;
++# else
++,
++# endif
++#endif
++
++#undef PROCINFO_DECL
++#undef PROCINFO_CLASS
+diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c b/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c
+new file mode 100644
+index 00000000..455fd71a
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c
+@@ -0,0 +1,21 @@
++/* Operating system support for run-time dynamic linker. LoongArch version.
++ 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
++ <http://www.gnu.org/licenses/>. */
++
++#include <config.h>
++#include <sysdeps/loongarch/cpu-tunables.c>
++#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
+diff --git a/sysdeps/unix/sysv/linux/loongarch/libc-start.c b/sysdeps/unix/sysv/linux/loongarch/libc-start.c
+new file mode 100644
+index 00000000..f1346ece
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/loongarch/libc-start.c
+@@ -0,0 +1,34 @@
++/* Override csu/libc-start.c on LoongArch64.
++ 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
++ <http://www.gnu.org/licenses/>. */
++
++#ifndef SHARED
++
++/* Mark symbols hidden in static PIE for early self relocation to work. */
++# if BUILD_PIE_DEFAULT
++# pragma GCC visibility push(hidden)
++# endif
++
++# include <ldsodefs.h>
++# include <cpu-features.c>
++
++extern struct cpu_features _dl_larch_cpu_features;
++
++# define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_larch_cpu_features)
++
++#endif
++#include <csu/libc-start.c>
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-memchr-aligned-lsx-l.patch b/LoongArch-Add-ifunc-support-for-memchr-aligned-lsx-l.patch
new file mode 100644
index 0000000..ad7e613
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-memchr-aligned-lsx-l.patch
@@ -0,0 +1,485 @@
+From 3ee56bbc56faa7b85a6513340db4a4fdd6ce709d Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Mon, 28 Aug 2023 10:08:36 +0800
+Subject: [PATCH 15/29] LoongArch: Add ifunc support for memchr{aligned, lsx,
+ lasx}
+
+According to glibc memchr microbenchmark, this implementation could reduce
+the runtime as following:
+
+Name Percent of runtime reduced
+memchr-lasx 37%-83%
+memchr-lsx 30%-66%
+memchr-aligned 0%-15%
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 3 +
+ .../lp64/multiarch/ifunc-impl-list.c | 7 ++
+ .../loongarch/lp64/multiarch/ifunc-memchr.h | 40 ++++++
+ .../loongarch/lp64/multiarch/memchr-aligned.S | 95 ++++++++++++++
+ .../loongarch/lp64/multiarch/memchr-lasx.S | 117 ++++++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/memchr-lsx.S | 102 +++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/memchr.c | 37 ++++++
+ 7 files changed, 401 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-memchr.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memchr-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memchr-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memchr-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memchr.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index 64416b02..2f4802cf 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -24,5 +24,8 @@ sysdep_routines += \
+ rawmemchr-aligned \
+ rawmemchr-lsx \
+ rawmemchr-lasx \
++ memchr-aligned \
++ memchr-lsx \
++ memchr-lasx \
+ # sysdep_routines
+ endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index 3db9af14..a567b9cf 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -102,5 +102,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_aligned)
+ )
+
++ IFUNC_IMPL (i, name, memchr,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, memchr, SUPPORT_LASX, __memchr_lasx)
++ IFUNC_IMPL_ADD (array, i, memchr, SUPPORT_LSX, __memchr_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_aligned)
++ )
+ return i;
+ }
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-memchr.h b/sysdeps/loongarch/lp64/multiarch/ifunc-memchr.h
+new file mode 100644
+index 00000000..9060ccd5
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-memchr.h
+@@ -0,0 +1,40 @@
++/* Common definition for memchr ifunc selections.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/memchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/memchr-aligned.S
+new file mode 100644
+index 00000000..81d0d004
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memchr-aligned.S
+@@ -0,0 +1,95 @@
++/* Optimized memchr implementation using basic LoongArch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define MEMCHR_NAME __memchr_aligned
++#else
++# define MEMCHR_NAME memchr
++#endif
++
++LEAF(MEMCHR_NAME, 6)
++ beqz a2, L(out)
++ andi t1, a0, 0x7
++ add.d a5, a0, a2
++ bstrins.d a0, zero, 2, 0
++
++ ld.d t0, a0, 0
++ bstrins.d a1, a1, 15, 8
++ lu12i.w a3, 0x01010
++ slli.d t2, t1, 03
++
++ bstrins.d a1, a1, 31, 16
++ ori a3, a3, 0x101
++ li.d t7, -1
++ li.d t8, 8
++
++ bstrins.d a1, a1, 63, 32
++ bstrins.d a3, a3, 63, 32
++ sll.d t2, t7, t2
++ xor t0, t0, a1
++
++
++ addi.d a6, a5, -1
++ slli.d a4, a3, 7
++ sub.d t1, t8, t1
++ orn t0, t0, t2
++
++ sub.d t2, t0, a3
++ andn t3, a4, t0
++ bstrins.d a6, zero, 2, 0
++ and t0, t2, t3
++
++ bgeu t1, a2, L(end)
++L(loop):
++ bnez t0, L(found)
++ ld.d t1, a0, 8
++ xor t0, t1, a1
++
++ addi.d a0, a0, 8
++ sub.d t2, t0, a3
++ andn t3, a4, t0
++ and t0, t2, t3
++
++
++ bne a0, a6, L(loop)
++L(end):
++ sub.d t1, a5, a6
++ ctz.d t0, t0
++ srli.d t0, t0, 3
++
++ sltu t1, t0, t1
++ add.d a0, a0, t0
++ maskeqz a0, a0, t1
++ jr ra
++
++L(found):
++ ctz.d t0, t0
++ srli.d t0, t0, 3
++ add.d a0, a0, t0
++ jr ra
++
++L(out):
++ move a0, zero
++ jr ra
++END(MEMCHR_NAME)
++
++libc_hidden_builtin_def (MEMCHR_NAME)
+diff --git a/sysdeps/loongarch/lp64/multiarch/memchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/memchr-lasx.S
+new file mode 100644
+index 00000000..a26cdf48
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memchr-lasx.S
+@@ -0,0 +1,117 @@
++/* Optimized memchr implementation using LoongArch LASX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define MEMCHR __memchr_lasx
++
++LEAF(MEMCHR, 6)
++ beqz a2, L(ret0)
++ add.d a3, a0, a2
++ andi t0, a0, 0x3f
++ bstrins.d a0, zero, 5, 0
++
++ xvld xr0, a0, 0
++ xvld xr1, a0, 32
++ li.d t1, -1
++ li.d t2, 64
++
++ xvreplgr2vr.b xr2, a1
++ sll.d t3, t1, t0
++ sub.d t2, t2, t0
++ xvseq.b xr0, xr0, xr2
++
++ xvseq.b xr1, xr1, xr2
++ xvmsknz.b xr0, xr0
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr3, xr0, 4
++
++
++ xvpickve.w xr4, xr1, 4
++ vilvl.h vr0, vr3, vr0
++ vilvl.h vr1, vr4, vr1
++ vilvl.w vr0, vr1, vr0
++
++ movfr2gr.d t0, fa0
++ and t0, t0, t3
++ bgeu t2, a2, L(end)
++ bnez t0, L(found)
++
++ addi.d a4, a3, -1
++ bstrins.d a4, zero, 5, 0
++L(loop):
++ xvld xr0, a0, 64
++ xvld xr1, a0, 96
++
++ addi.d a0, a0, 64
++ xvseq.b xr0, xr0, xr2
++ xvseq.b xr1, xr1, xr2
++ beq a0, a4, L(out)
++
++
++ xvmax.bu xr3, xr0, xr1
++ xvseteqz.v fcc0, xr3
++ bcnez fcc0, L(loop)
++ xvmsknz.b xr0, xr0
++
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr3, xr0, 4
++ xvpickve.w xr4, xr1, 4
++ vilvl.h vr0, vr3, vr0
++
++ vilvl.h vr1, vr4, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++L(found):
++ ctz.d t1, t0
++
++ add.d a0, a0, t1
++ jr ra
++L(ret0):
++ move a0, zero
++ jr ra
++
++
++L(out):
++ xvmsknz.b xr0, xr0
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr3, xr0, 4
++ xvpickve.w xr4, xr1, 4
++
++ vilvl.h vr0, vr3, vr0
++ vilvl.h vr1, vr4, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++
++L(end):
++ sub.d t2, zero, a3
++ srl.d t1, t1, t2
++ and t0, t0, t1
++ ctz.d t1, t0
++
++ add.d a0, a0, t1
++ maskeqz a0, a0, t0
++ jr ra
++END(MEMCHR)
++
++libc_hidden_builtin_def (MEMCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/memchr-lsx.S
+new file mode 100644
+index 00000000..a73ecd25
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memchr-lsx.S
+@@ -0,0 +1,102 @@
++/* Optimized memchr implementation using LoongArch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define MEMCHR __memchr_lsx
++
++LEAF(MEMCHR, 6)
++ beqz a2, L(ret0)
++ add.d a3, a0, a2
++ andi t0, a0, 0x1f
++ bstrins.d a0, zero, 4, 0
++
++ vld vr0, a0, 0
++ vld vr1, a0, 16
++ li.d t1, -1
++ li.d t2, 32
++
++ vreplgr2vr.b vr2, a1
++ sll.d t3, t1, t0
++ sub.d t2, t2, t0
++ vseq.b vr0, vr0, vr2
++
++ vseq.b vr1, vr1, vr2
++ vmsknz.b vr0, vr0
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++
++
++ movfr2gr.s t0, fa0
++ and t0, t0, t3
++ bgeu t2, a2, L(end)
++ bnez t0, L(found)
++
++ addi.d a4, a3, -1
++ bstrins.d a4, zero, 4, 0
++L(loop):
++ vld vr0, a0, 32
++ vld vr1, a0, 48
++
++ addi.d a0, a0, 32
++ vseq.b vr0, vr0, vr2
++ vseq.b vr1, vr1, vr2
++ beq a0, a4, L(out)
++
++ vmax.bu vr3, vr0, vr1
++ vseteqz.v fcc0, vr3
++ bcnez fcc0, L(loop)
++ vmsknz.b vr0, vr0
++
++
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++L(found):
++ ctz.w t0, t0
++
++ add.d a0, a0, t0
++ jr ra
++L(ret0):
++ move a0, zero
++ jr ra
++
++L(out):
++ vmsknz.b vr0, vr0
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++
++L(end):
++ sub.d t2, zero, a3
++ srl.w t1, t1, t2
++ and t0, t0, t1
++ ctz.w t1, t0
++
++
++ add.d a0, a0, t1
++ maskeqz a0, a0, t0
++ jr ra
++END(MEMCHR)
++
++libc_hidden_builtin_def (MEMCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memchr.c b/sysdeps/loongarch/lp64/multiarch/memchr.c
+new file mode 100644
+index 00000000..059479c0
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memchr.c
+@@ -0,0 +1,37 @@
++/* Multiple versions of memchr.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define memchr __redirect_memchr
++# include <string.h>
++# undef memchr
++
++# define SYMBOL_NAME memchr
++# include "ifunc-memchr.h"
++
++libc_ifunc_redirected (__redirect_memchr, memchr,
++ IFUNC_SELECTOR ());
++
++# ifdef SHARED
++__hidden_ver1 (memchr, __GI_memchr, __redirect_memchr)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memchr);
++# endif
++
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-memcmp-aligned-lsx-l.patch b/LoongArch-Add-ifunc-support-for-memcmp-aligned-lsx-l.patch
new file mode 100644
index 0000000..72c26d0
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-memcmp-aligned-lsx-l.patch
@@ -0,0 +1,946 @@
+From 60f4bbd1eec528ba8df044ae6b3091f6337a7fcc Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Mon, 28 Aug 2023 10:08:39 +0800
+Subject: [PATCH 18/29] LoongArch: Add ifunc support for memcmp{aligned, lsx,
+ lasx}
+
+According to glibc memcmp microbenchmark test results(Add generic
+memcmp), this implementation have performance improvement
+except the length is less than 3, details as below:
+
+Name Percent of time reduced
+memcmp-lasx 16%-74%
+memcmp-lsx 20%-50%
+memcmp-aligned 5%-20%
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 3 +
+ .../lp64/multiarch/ifunc-impl-list.c | 7 +
+ .../loongarch/lp64/multiarch/ifunc-memcmp.h | 40 +++
+ .../loongarch/lp64/multiarch/memcmp-aligned.S | 292 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/memcmp-lasx.S | 207 +++++++++++++
+ sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S | 269 ++++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/memcmp.c | 43 +++
+ 7 files changed, 861 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-memcmp.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memcmp-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memcmp-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memcmp.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index 216886c5..360a6718 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -34,5 +34,8 @@ sysdep_routines += \
+ memset-unaligned \
+ memset-lsx \
+ memset-lasx \
++ memcmp-aligned \
++ memcmp-lsx \
++ memcmp-lasx \
+ # sysdep_routines
+ endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index 37f60dde..e397d58c 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -127,5 +127,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_aligned)
+ )
+
++ IFUNC_IMPL (i, name, memcmp,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, memcmp, SUPPORT_LASX, __memcmp_lasx)
++ IFUNC_IMPL_ADD (array, i, memcmp, SUPPORT_LSX, __memcmp_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_aligned)
++ )
+ return i;
+ }
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-memcmp.h b/sysdeps/loongarch/lp64/multiarch/ifunc-memcmp.h
+new file mode 100644
+index 00000000..04adc2e5
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-memcmp.h
+@@ -0,0 +1,40 @@
++/* Common definition for memcmp ifunc selections.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcmp-aligned.S b/sysdeps/loongarch/lp64/multiarch/memcmp-aligned.S
+new file mode 100644
+index 00000000..14a7caa9
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memcmp-aligned.S
+@@ -0,0 +1,292 @@
++/* Optimized memcmp implementation using basic LoongArch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define MEMCMP_NAME __memcmp_aligned
++#else
++# define MEMCMP_NAME memcmp
++#endif
++
++LEAF(MEMCMP_NAME, 6)
++ beqz a2, L(ret)
++ andi a4, a1, 0x7
++ andi a3, a0, 0x7
++ sltu a5, a4, a3
++
++ xor t0, a0, a1
++ li.w t8, 8
++ maskeqz t0, t0, a5
++ li.w t7, -1
++
++ xor a0, a0, t0
++ xor a1, a1, t0
++ andi a3, a0, 0x7
++ andi a4, a1, 0x7
++
++ xor a0, a0, a3
++ xor a1, a1, a4
++ ld.d t2, a0, 0
++ ld.d t1, a1, 0
++
++ slli.d t3, a3, 3
++ slli.d t4, a4, 3
++ sub.d a6, t3, t4
++ srl.d t1, t1, t4
++
++ srl.d t0, t2, t3
++ srl.d t5, t7, t4
++ sub.d t6, t0, t1
++ and t6, t6, t5
++
++ sub.d t5, t8, a4
++ bnez t6, L(first_out)
++ bgeu t5, a2, L(ret)
++ sub.d a2, a2, t5
++
++ bnez a6, L(unaligned)
++ blt a2, t8, L(al_less_8bytes)
++ andi t1, a2, 31
++ beq t1, a2, L(al_less_32bytes)
++
++ sub.d t2, a2, t1
++ add.d a4, a0, t2
++ move a2, t1
++
++L(al_loop):
++ ld.d t0, a0, 8
++
++ ld.d t1, a1, 8
++ ld.d t2, a0, 16
++ ld.d t3, a1, 16
++ ld.d t4, a0, 24
++
++ ld.d t5, a1, 24
++ ld.d t6, a0, 32
++ ld.d t7, a1, 32
++ addi.d a0, a0, 32
++
++ addi.d a1, a1, 32
++ bne t0, t1, L(out1)
++ bne t2, t3, L(out2)
++ bne t4, t5, L(out3)
++
++ bne t6, t7, L(out4)
++ bne a0, a4, L(al_loop)
++
++L(al_less_32bytes):
++ srai.d a4, a2, 4
++ beqz a4, L(al_less_16bytes)
++
++ ld.d t0, a0, 8
++ ld.d t1, a1, 8
++ ld.d t2, a0, 16
++ ld.d t3, a1, 16
++
++ addi.d a0, a0, 16
++ addi.d a1, a1, 16
++ addi.d a2, a2, -16
++ bne t0, t1, L(out1)
++
++ bne t2, t3, L(out2)
++
++L(al_less_16bytes):
++ srai.d a4, a2, 3
++ beqz a4, L(al_less_8bytes)
++ ld.d t0, a0, 8
++
++ ld.d t1, a1, 8
++ addi.d a0, a0, 8
++ addi.d a1, a1, 8
++ addi.d a2, a2, -8
++
++ bne t0, t1, L(out1)
++
++L(al_less_8bytes):
++ beqz a2, L(ret)
++ ld.d t0, a0, 8
++ ld.d t1, a1, 8
++
++ li.d t7, -1
++ slli.d t2, a2, 3
++ sll.d t2, t7, t2
++ sub.d t3, t0, t1
++
++ andn t6, t3, t2
++ bnez t6, L(count_diff)
++
++L(ret):
++ move a0, zero
++ jr ra
++
++L(out4):
++ move t0, t6
++ move t1, t7
++ sub.d t6, t6, t7
++ b L(count_diff)
++
++L(out3):
++ move t0, t4
++ move t1, t5
++ sub.d t6, t4, t5
++ b L(count_diff)
++
++L(out2):
++ move t0, t2
++ move t1, t3
++L(out1):
++ sub.d t6, t0, t1
++ b L(count_diff)
++
++L(first_out):
++ slli.d t4, a2, 3
++ slt t3, a2, t5
++ sll.d t4, t7, t4
++ maskeqz t4, t4, t3
++
++ andn t6, t6, t4
++
++L(count_diff):
++ ctz.d t2, t6
++ bstrins.d t2, zero, 2, 0
++ srl.d t0, t0, t2
++
++ srl.d t1, t1, t2
++ andi t0, t0, 0xff
++ andi t1, t1, 0xff
++ sub.d t2, t0, t1
++
++ sub.d t3, t1, t0
++ masknez t2, t2, a5
++ maskeqz t3, t3, a5
++ or a0, t2, t3
++
++ jr ra
++
++L(unaligned):
++ sub.d a7, zero, a6
++ srl.d t0, t2, a6
++ blt a2, t8, L(un_less_8bytes)
++
++ andi t1, a2, 31
++ beq t1, a2, L(un_less_32bytes)
++ sub.d t2, a2, t1
++ add.d a4, a0, t2
++
++ move a2, t1
++
++L(un_loop):
++ ld.d t2, a0, 8
++ ld.d t1, a1, 8
++ ld.d t4, a0, 16
++
++ ld.d t3, a1, 16
++ ld.d t6, a0, 24
++ ld.d t5, a1, 24
++ ld.d t8, a0, 32
++
++ ld.d t7, a1, 32
++ addi.d a0, a0, 32
++ addi.d a1, a1, 32
++ sll.d a3, t2, a7
++
++ or t0, a3, t0
++ bne t0, t1, L(out1)
++ srl.d t0, t2, a6
++ sll.d a3, t4, a7
++
++ or t2, a3, t0
++ bne t2, t3, L(out2)
++ srl.d t0, t4, a6
++ sll.d a3, t6, a7
++
++ or t4, a3, t0
++ bne t4, t5, L(out3)
++ srl.d t0, t6, a6
++ sll.d a3, t8, a7
++
++ or t6, t0, a3
++ bne t6, t7, L(out4)
++ srl.d t0, t8, a6
++ bne a0, a4, L(un_loop)
++
++L(un_less_32bytes):
++ srai.d a4, a2, 4
++ beqz a4, L(un_less_16bytes)
++ ld.d t2, a0, 8
++ ld.d t1, a1, 8
++
++ ld.d t4, a0, 16
++ ld.d t3, a1, 16
++ addi.d a0, a0, 16
++ addi.d a1, a1, 16
++
++ addi.d a2, a2, -16
++ sll.d a3, t2, a7
++ or t0, a3, t0
++ bne t0, t1, L(out1)
++
++ srl.d t0, t2, a6
++ sll.d a3, t4, a7
++ or t2, a3, t0
++ bne t2, t3, L(out2)
++
++ srl.d t0, t4, a6
++
++L(un_less_16bytes):
++ srai.d a4, a2, 3
++ beqz a4, L(un_less_8bytes)
++ ld.d t2, a0, 8
++
++ ld.d t1, a1, 8
++ addi.d a0, a0, 8
++ addi.d a1, a1, 8
++ addi.d a2, a2, -8
++
++ sll.d a3, t2, a7
++ or t0, a3, t0
++ bne t0, t1, L(out1)
++ srl.d t0, t2, a6
++
++L(un_less_8bytes):
++ beqz a2, L(ret)
++ andi a7, a7, 63
++ slli.d a4, a2, 3
++ bgeu a7, a4, L(last_cmp)
++
++ ld.d t2, a0, 8
++ sll.d a3, t2, a7
++ or t0, a3, t0
++
++L(last_cmp):
++ ld.d t1, a1, 8
++
++ li.d t7, -1
++ sll.d t2, t7, a4
++ sub.d t3, t0, t1
++ andn t6, t3, t2
++
++ bnez t6, L(count_diff)
++ move a0, zero
++ jr ra
++END(MEMCMP_NAME)
++
++libc_hidden_builtin_def (MEMCMP_NAME)
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcmp-lasx.S b/sysdeps/loongarch/lp64/multiarch/memcmp-lasx.S
+new file mode 100644
+index 00000000..3151a179
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memcmp-lasx.S
+@@ -0,0 +1,207 @@
++/* Optimized memcmp implementation using LoongArch LASX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define MEMCMP __memcmp_lasx
++
++LEAF(MEMCMP, 6)
++ li.d t2, 32
++ add.d a3, a0, a2
++ add.d a4, a1, a2
++ bgeu t2, a2, L(less32)
++
++ li.d t1, 160
++ bgeu a2, t1, L(make_aligned)
++L(loop32):
++ xvld xr0, a0, 0
++ xvld xr1, a1, 0
++
++ addi.d a0, a0, 32
++ addi.d a1, a1, 32
++ addi.d a2, a2, -32
++ xvseq.b xr2, xr0, xr1
++
++ xvsetanyeqz.b fcc0, xr2
++ bcnez fcc0, L(end)
++L(last_bytes):
++ bltu t2, a2, L(loop32)
++ xvld xr0, a3, -32
++
++
++ xvld xr1, a4, -32
++ xvseq.b xr2, xr0, xr1
++L(end):
++ xvmsknz.b xr2, xr2
++ xvpermi.q xr4, xr0, 1
++
++ xvpickve.w xr3, xr2, 4
++ xvpermi.q xr5, xr1, 1
++ vilvl.h vr2, vr3, vr2
++ movfr2gr.s t0, fa2
++
++ cto.w t0, t0
++ vreplgr2vr.b vr2, t0
++ vshuf.b vr0, vr4, vr0, vr2
++ vshuf.b vr1, vr5, vr1, vr2
++
++ vpickve2gr.bu t0, vr0, 0
++ vpickve2gr.bu t1, vr1, 0
++ sub.d a0, t0, t1
++ jr ra
++
++
++L(less32):
++ srli.d t0, a2, 4
++ beqz t0, L(less16)
++ vld vr0, a0, 0
++ vld vr1, a1, 0
++
++ vld vr2, a3, -16
++ vld vr3, a4, -16
++L(short_ret):
++ vseq.b vr4, vr0, vr1
++ vseq.b vr5, vr2, vr3
++
++ vmsknz.b vr4, vr4
++ vmsknz.b vr5, vr5
++ vilvl.h vr4, vr5, vr4
++ movfr2gr.s t0, fa4
++
++ cto.w t0, t0
++ vreplgr2vr.b vr4, t0
++ vshuf.b vr0, vr2, vr0, vr4
++ vshuf.b vr1, vr3, vr1, vr4
++
++
++ vpickve2gr.bu t0, vr0, 0
++ vpickve2gr.bu t1, vr1, 0
++ sub.d a0, t0, t1
++ jr ra
++
++L(less16):
++ srli.d t0, a2, 3
++ beqz t0, L(less8)
++ vldrepl.d vr0, a0, 0
++ vldrepl.d vr1, a1, 0
++
++ vldrepl.d vr2, a3, -8
++ vldrepl.d vr3, a4, -8
++ b L(short_ret)
++ nop
++
++L(less8):
++ srli.d t0, a2, 2
++ beqz t0, L(less4)
++ vldrepl.w vr0, a0, 0
++ vldrepl.w vr1, a1, 0
++
++
++ vldrepl.w vr2, a3, -4
++ vldrepl.w vr3, a4, -4
++ b L(short_ret)
++ nop
++
++L(less4):
++ srli.d t0, a2, 1
++ beqz t0, L(less2)
++ vldrepl.h vr0, a0, 0
++ vldrepl.h vr1, a1, 0
++
++ vldrepl.h vr2, a3, -2
++ vldrepl.h vr3, a4, -2
++ b L(short_ret)
++ nop
++
++L(less2):
++ beqz a2, L(ret0)
++ ld.bu t0, a0, 0
++ ld.bu t1, a1, 0
++ sub.d a0, t0, t1
++
++ jr ra
++L(ret0):
++ move a0, zero
++ jr ra
++
++L(make_aligned):
++ xvld xr0, a0, 0
++
++ xvld xr1, a1, 0
++ xvseq.b xr2, xr0, xr1
++ xvsetanyeqz.b fcc0, xr2
++ bcnez fcc0, L(end)
++
++ andi t0, a0, 0x1f
++ sub.d t0, t2, t0
++ sub.d t1, a2, t0
++ add.d a0, a0, t0
++
++ add.d a1, a1, t0
++ andi a2, t1, 0x3f
++ sub.d t0, t1, a2
++ add.d a5, a0, t0
++
++
++L(loop_align):
++ xvld xr0, a0, 0
++ xvld xr1, a1, 0
++ xvld xr2, a0, 32
++ xvld xr3, a1, 32
++
++ xvseq.b xr0, xr0, xr1
++ xvseq.b xr1, xr2, xr3
++ xvmin.bu xr2, xr1, xr0
++ xvsetanyeqz.b fcc0, xr2
++
++ bcnez fcc0, L(pair_end)
++ addi.d a0, a0, 64
++ addi.d a1, a1, 64
++ bne a0, a5, L(loop_align)
++
++ bnez a2, L(last_bytes)
++ move a0, zero
++ jr ra
++ nop
++
++
++L(pair_end):
++ xvmsknz.b xr0, xr0
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr2, xr0, 4
++ xvpickve.w xr3, xr1, 4
++
++ vilvl.h vr0, vr2, vr0
++ vilvl.h vr1, vr3, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++
++ cto.d t0, t0
++ ldx.bu t1, a0, t0
++ ldx.bu t2, a1, t0
++ sub.d a0, t1, t2
++
++ jr ra
++END(MEMCMP)
++
++libc_hidden_builtin_def (MEMCMP)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S b/sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S
+new file mode 100644
+index 00000000..38a50a4c
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S
+@@ -0,0 +1,269 @@
++/* Optimized memcmp implementation using LoongArch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++#define MEMCMP __memcmp_lsx
++
++LEAF(MEMCMP, 6)
++ beqz a2, L(out)
++ pcalau12i t0, %pc_hi20(L(INDEX))
++ andi a3, a0, 0xf
++ vld vr5, t0, %pc_lo12(L(INDEX))
++
++ andi a4, a1, 0xf
++ bne a3, a4, L(unaligned)
++ bstrins.d a0, zero, 3, 0
++ xor a1, a1, a4
++
++ vld vr0, a0, 0
++ vld vr1, a1, 0
++ li.d t0, 16
++ vreplgr2vr.b vr3, a3
++
++ sub.d t1, t0, a3
++ vadd.b vr3, vr3, vr5
++ vshuf.b vr0, vr3, vr0, vr3
++ vshuf.b vr1, vr3, vr1, vr3
++
++
++ vseq.b vr4, vr0, vr1
++ bgeu t1, a2, L(al_end)
++ vsetanyeqz.b fcc0, vr4
++ bcnez fcc0, L(al_found)
++
++ sub.d t1, a2, t1
++ andi a2, t1, 31
++ beq a2, t1, L(al_less_32bytes)
++ sub.d t2, t1, a2
++
++ add.d a4, a0, t2
++L(al_loop):
++ vld vr0, a0, 16
++ vld vr1, a1, 16
++ vld vr2, a0, 32
++
++ vld vr3, a1, 32
++ addi.d a0, a0, 32
++ addi.d a1, a1, 32
++ vseq.b vr4, vr0, vr1
++
++
++ vseq.b vr6, vr2, vr3
++ vand.v vr6, vr4, vr6
++ vsetanyeqz.b fcc0, vr6
++ bcnez fcc0, L(al_pair_end)
++
++ bne a0, a4, L(al_loop)
++L(al_less_32bytes):
++ bgeu t0, a2, L(al_less_16bytes)
++ vld vr0, a0, 16
++ vld vr1, a1, 16
++
++ vld vr2, a0, 32
++ vld vr3, a1, 32
++ addi.d a2, a2, -16
++ vreplgr2vr.b vr6, a2
++
++ vslt.b vr5, vr5, vr6
++ vseq.b vr4, vr0, vr1
++ vseq.b vr6, vr2, vr3
++ vorn.v vr6, vr6, vr5
++
++
++L(al_pair_end):
++ vsetanyeqz.b fcc0, vr4
++ bcnez fcc0, L(al_found)
++ vnori.b vr4, vr6, 0
++ vfrstpi.b vr4, vr4, 0
++
++ vshuf.b vr0, vr2, vr2, vr4
++ vshuf.b vr1, vr3, vr3, vr4
++ vpickve2gr.bu t0, vr0, 0
++ vpickve2gr.bu t1, vr1, 0
++
++ sub.d a0, t0, t1
++ jr ra
++ nop
++ nop
++
++L(al_less_16bytes):
++ beqz a2, L(out)
++ vld vr0, a0, 16
++ vld vr1, a1, 16
++ vseq.b vr4, vr0, vr1
++
++
++L(al_end):
++ vreplgr2vr.b vr6, a2
++ vslt.b vr5, vr5, vr6
++ vorn.v vr4, vr4, vr5
++ nop
++
++L(al_found):
++ vnori.b vr4, vr4, 0
++ vfrstpi.b vr4, vr4, 0
++ vshuf.b vr0, vr0, vr0, vr4
++ vshuf.b vr1, vr1, vr1, vr4
++
++ vpickve2gr.bu t0, vr0, 0
++ vpickve2gr.bu t1, vr1, 0
++ sub.d a0, t0, t1
++ jr ra
++
++L(out):
++ move a0, zero
++ jr ra
++ nop
++ nop
++
++
++L(unaligned):
++ xor t2, a0, a1
++ sltu a5, a3, a4
++ masknez t2, t2, a5
++ xor a0, a0, t2
++
++ xor a1, a1, t2
++ andi a3, a0, 0xf
++ andi a4, a1, 0xf
++ bstrins.d a0, zero, 3, 0
++
++ xor a1, a1, a4
++ vld vr4, a0, 0
++ vld vr1, a1, 0
++ li.d t0, 16
++
++ vreplgr2vr.b vr2, a4
++ sub.d a6, a4, a3
++ sub.d t1, t0, a4
++ sub.d t2, t0, a6
++
++
++ vadd.b vr2, vr2, vr5
++ vreplgr2vr.b vr6, t2
++ vadd.b vr6, vr6, vr5
++ vshuf.b vr0, vr4, vr4, vr6
++
++ vshuf.b vr1, vr2, vr1, vr2
++ vshuf.b vr0, vr2, vr0, vr2
++ vseq.b vr7, vr0, vr1
++ bgeu t1, a2, L(un_end)
++
++ vsetanyeqz.b fcc0, vr7
++ bcnez fcc0, L(un_found)
++ sub.d a2, a2, t1
++ andi t1, a2, 31
++
++ beq a2, t1, L(un_less_32bytes)
++ sub.d t2, a2, t1
++ move a2, t1
++ add.d a4, a1, t2
++
++
++L(un_loop):
++ vld vr2, a0, 16
++ vld vr1, a1, 16
++ vld vr3, a1, 32
++ addi.d a1, a1, 32
++
++ addi.d a0, a0, 32
++ vshuf.b vr0, vr2, vr4, vr6
++ vld vr4, a0, 0
++ vseq.b vr7, vr0, vr1
++
++ vshuf.b vr2, vr4, vr2, vr6
++ vseq.b vr8, vr2, vr3
++ vand.v vr8, vr7, vr8
++ vsetanyeqz.b fcc0, vr8
++
++ bcnez fcc0, L(un_pair_end)
++ bne a1, a4, L(un_loop)
++
++L(un_less_32bytes):
++ bltu a2, t0, L(un_less_16bytes)
++ vld vr2, a0, 16
++ vld vr1, a1, 16
++ addi.d a0, a0, 16
++
++ addi.d a1, a1, 16
++ addi.d a2, a2, -16
++ vshuf.b vr0, vr2, vr4, vr6
++ vor.v vr4, vr2, vr2
++
++ vseq.b vr7, vr0, vr1
++ vsetanyeqz.b fcc0, vr7
++ bcnez fcc0, L(un_found)
++L(un_less_16bytes):
++ beqz a2, L(out)
++ vld vr1, a1, 16
++ bgeu a6, a2, 1f
++
++ vld vr2, a0, 16
++1:
++ vshuf.b vr0, vr2, vr4, vr6
++ vseq.b vr7, vr0, vr1
++L(un_end):
++ vreplgr2vr.b vr3, a2
++
++
++ vslt.b vr3, vr5, vr3
++ vorn.v vr7, vr7, vr3
++
++L(un_found):
++ vnori.b vr7, vr7, 0
++ vfrstpi.b vr7, vr7, 0
++
++ vshuf.b vr0, vr0, vr0, vr7
++ vshuf.b vr1, vr1, vr1, vr7
++L(calc_result):
++ vpickve2gr.bu t0, vr0, 0
++ vpickve2gr.bu t1, vr1, 0
++
++ sub.d t2, t0, t1
++ sub.d t3, t1, t0
++ masknez t0, t3, a5
++ maskeqz t1, t2, a5
++
++ or a0, t0, t1
++ jr ra
++L(un_pair_end):
++ vsetanyeqz.b fcc0, vr7
++ bcnez fcc0, L(un_found)
++
++
++ vnori.b vr7, vr8, 0
++ vfrstpi.b vr7, vr7, 0
++ vshuf.b vr0, vr2, vr2, vr7
++ vshuf.b vr1, vr3, vr3, vr7
++
++ b L(calc_result)
++END(MEMCMP)
++
++ .section .rodata.cst16,"M",@progbits,16
++ .align 4
++L(INDEX):
++ .dword 0x0706050403020100
++ .dword 0x0f0e0d0c0b0a0908
++
++libc_hidden_builtin_def (MEMCMP)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcmp.c b/sysdeps/loongarch/lp64/multiarch/memcmp.c
+new file mode 100644
+index 00000000..32eccac2
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memcmp.c
+@@ -0,0 +1,43 @@
++/* Multiple versions of memcmp.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define memcmp __redirect_memcmp
++# include <string.h>
++# undef memcmp
++
++# define SYMBOL_NAME memcmp
++# include "ifunc-memcmp.h"
++
++libc_ifunc_redirected (__redirect_memcmp, memcmp,
++ IFUNC_SELECTOR ());
++# undef bcmp
++weak_alias (memcmp, bcmp)
++
++# undef __memcmpeq
++strong_alias (memcmp, __memcmpeq)
++libc_hidden_def (__memcmpeq)
++
++# ifdef SHARED
++__hidden_ver1 (memcmp, __GI_memcmp, __redirect_memcmp)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memcmp);
++# endif
++
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-memrchr-lsx-lasx.patch b/LoongArch-Add-ifunc-support-for-memrchr-lsx-lasx.patch
new file mode 100644
index 0000000..26a0f40
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-memrchr-lsx-lasx.patch
@@ -0,0 +1,417 @@
+From c4c272fb8067364530a2a78df92c37403acc963f Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Mon, 28 Aug 2023 10:08:37 +0800
+Subject: [PATCH 16/29] LoongArch: Add ifunc support for memrchr{lsx, lasx}
+
+According to glibc memrchr microbenchmark, this implementation could reduce
+the runtime as following:
+
+Name Percent of rutime reduced
+memrchr-lasx 20%-83%
+memrchr-lsx 20%-64%
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 3 +
+ .../lp64/multiarch/ifunc-impl-list.c | 8 ++
+ .../loongarch/lp64/multiarch/ifunc-memrchr.h | 40 ++++++
+ .../lp64/multiarch/memrchr-generic.c | 23 ++++
+ .../loongarch/lp64/multiarch/memrchr-lasx.S | 123 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/memrchr-lsx.S | 105 +++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/memrchr.c | 33 +++++
+ 7 files changed, 335 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-memrchr.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memrchr-generic.c
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memrchr-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memrchr-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memrchr.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index 2f4802cf..7b87bc90 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -27,5 +27,8 @@ sysdep_routines += \
+ memchr-aligned \
+ memchr-lsx \
+ memchr-lasx \
++ memrchr-generic \
++ memrchr-lsx \
++ memrchr-lasx \
+ # sysdep_routines
+ endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index a567b9cf..8bd5489e 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -109,5 +109,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ #endif
+ IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_aligned)
+ )
++
++ IFUNC_IMPL (i, name, memrchr,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, memrchr, SUPPORT_LASX, __memrchr_lasx)
++ IFUNC_IMPL_ADD (array, i, memrchr, SUPPORT_LSX, __memrchr_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_generic)
++ )
+ return i;
+ }
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-memrchr.h b/sysdeps/loongarch/lp64/multiarch/ifunc-memrchr.h
+new file mode 100644
+index 00000000..8215f9ad
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-memrchr.h
+@@ -0,0 +1,40 @@
++/* Common definition for memrchr implementation.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++extern __typeof (REDIRECT_NAME) OPTIMIZE (generic) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (generic);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/memrchr-generic.c b/sysdeps/loongarch/lp64/multiarch/memrchr-generic.c
+new file mode 100644
+index 00000000..ced61ebc
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memrchr-generic.c
+@@ -0,0 +1,23 @@
++/* Generic implementation of memrchr.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#if IS_IN (libc)
++# define MEMRCHR __memrchr_generic
++#endif
++
++#include <string/memrchr.c>
+diff --git a/sysdeps/loongarch/lp64/multiarch/memrchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/memrchr-lasx.S
+new file mode 100644
+index 00000000..5f3e0d06
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memrchr-lasx.S
+@@ -0,0 +1,123 @@
++/* Optimized memrchr implementation using LoongArch LASX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++#ifndef MEMRCHR
++# define MEMRCHR __memrchr_lasx
++#endif
++
++LEAF(MEMRCHR, 6)
++ beqz a2, L(ret0)
++ addi.d a2, a2, -1
++ add.d a3, a0, a2
++ andi t1, a3, 0x3f
++
++ bstrins.d a3, zero, 5, 0
++ addi.d t1, t1, 1
++ xvld xr0, a3, 0
++ xvld xr1, a3, 32
++
++ sub.d t2, zero, t1
++ li.d t3, -1
++ xvreplgr2vr.b xr2, a1
++ andi t4, a0, 0x3f
++
++ srl.d t2, t3, t2
++ xvseq.b xr0, xr0, xr2
++ xvseq.b xr1, xr1, xr2
++ xvmsknz.b xr0, xr0
++
++
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr3, xr0, 4
++ xvpickve.w xr4, xr1, 4
++ vilvl.h vr0, vr3, vr0
++
++ vilvl.h vr1, vr4, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++ and t0, t0, t2
++
++ bltu a2, t1, L(end)
++ bnez t0, L(found)
++ bstrins.d a0, zero, 5, 0
++L(loop):
++ xvld xr0, a3, -64
++
++ xvld xr1, a3, -32
++ addi.d a3, a3, -64
++ xvseq.b xr0, xr0, xr2
++ xvseq.b xr1, xr1, xr2
++
++
++ beq a0, a3, L(out)
++ xvmax.bu xr3, xr0, xr1
++ xvseteqz.v fcc0, xr3
++ bcnez fcc0, L(loop)
++
++ xvmsknz.b xr0, xr0
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr3, xr0, 4
++ xvpickve.w xr4, xr1, 4
++
++ vilvl.h vr0, vr3, vr0
++ vilvl.h vr1, vr4, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++
++L(found):
++ addi.d a0, a3, 63
++ clz.d t1, t0
++ sub.d a0, a0, t1
++ jr ra
++
++
++L(out):
++ xvmsknz.b xr0, xr0
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr3, xr0, 4
++ xvpickve.w xr4, xr1, 4
++
++ vilvl.h vr0, vr3, vr0
++ vilvl.h vr1, vr4, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++
++L(end):
++ sll.d t2, t3, t4
++ and t0, t0, t2
++ addi.d a0, a3, 63
++ clz.d t1, t0
++
++ sub.d a0, a0, t1
++ maskeqz a0, a0, t0
++ jr ra
++L(ret0):
++ move a0, zero
++
++
++ jr ra
++END(MEMRCHR)
++
++libc_hidden_builtin_def (MEMRCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memrchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/memrchr-lsx.S
+new file mode 100644
+index 00000000..39a7c8b0
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memrchr-lsx.S
+@@ -0,0 +1,105 @@
++/* Optimized memrchr implementation using LoongArch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define MEMRCHR __memrchr_lsx
++
++LEAF(MEMRCHR, 6)
++ beqz a2, L(ret0)
++ addi.d a2, a2, -1
++ add.d a3, a0, a2
++ andi t1, a3, 0x1f
++
++ bstrins.d a3, zero, 4, 0
++ addi.d t1, t1, 1
++ vld vr0, a3, 0
++ vld vr1, a3, 16
++
++ sub.d t2, zero, t1
++ li.d t3, -1
++ vreplgr2vr.b vr2, a1
++ andi t4, a0, 0x1f
++
++ srl.d t2, t3, t2
++ vseq.b vr0, vr0, vr2
++ vseq.b vr1, vr1, vr2
++ vmsknz.b vr0, vr0
++
++
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++ and t0, t0, t2
++
++ bltu a2, t1, L(end)
++ bnez t0, L(found)
++ bstrins.d a0, zero, 4, 0
++L(loop):
++ vld vr0, a3, -32
++
++ vld vr1, a3, -16
++ addi.d a3, a3, -32
++ vseq.b vr0, vr0, vr2
++ vseq.b vr1, vr1, vr2
++
++ beq a0, a3, L(out)
++ vmax.bu vr3, vr0, vr1
++ vseteqz.v fcc0, vr3
++ bcnez fcc0, L(loop)
++
++
++ vmsknz.b vr0, vr0
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++
++L(found):
++ addi.d a0, a3, 31
++ clz.w t1, t0
++ sub.d a0, a0, t1
++ jr ra
++
++L(out):
++ vmsknz.b vr0, vr0
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++
++L(end):
++ sll.d t2, t3, t4
++ and t0, t0, t2
++ addi.d a0, a3, 31
++ clz.w t1, t0
++
++
++ sub.d a0, a0, t1
++ maskeqz a0, a0, t0
++ jr ra
++L(ret0):
++ move a0, zero
++
++ jr ra
++END(MEMRCHR)
++
++libc_hidden_builtin_def (MEMRCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memrchr.c b/sysdeps/loongarch/lp64/multiarch/memrchr.c
+new file mode 100644
+index 00000000..8baba9ab
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memrchr.c
+@@ -0,0 +1,33 @@
++/* Multiple versions of memrchr.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define memrchr __redirect_memrchr
++# include <string.h>
++# undef memrchr
++
++# define SYMBOL_NAME memrchr
++# include "ifunc-memrchr.h"
++
++libc_ifunc_redirected (__redirect_memrchr, __memrchr, IFUNC_SELECTOR ());
++libc_hidden_def (__memrchr)
++weak_alias (__memrchr, memrchr)
++
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-memset-aligned-unali.patch b/LoongArch-Add-ifunc-support-for-memset-aligned-unali.patch
new file mode 100644
index 0000000..2e18ba2
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-memset-aligned-unali.patch
@@ -0,0 +1,784 @@
+From 14032f7bbe18443af8492f5d0365f72b76701673 Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Mon, 28 Aug 2023 10:08:38 +0800
+Subject: [PATCH 17/29] LoongArch: Add ifunc support for memset{aligned,
+ unaligned, lsx, lasx}
+
+According to glibc memset microbenchmark test results, for LSX and LASX
+versions, A few cases with length less than 8 experience performace
+degradation, overall, the LASX version could reduce the runtime about
+15% - 75%, LSX version could reduce the runtime about 15%-50%.
+
+The unaligned version uses unaligned memmory access to set data which
+length is less than 64 and make address aligned with 8. For this part,
+the performace is better than aligned version. Comparing with the generic
+version, the performance is close when the length is larger than 128. When
+the length is 8-128, the unaligned version could reduce the runtime about
+30%-70%, the aligned version could reduce the runtime about 20%-50%.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 4 +
+ .../lp64/multiarch/dl-symbol-redir-ifunc.h | 24 +++
+ .../lp64/multiarch/ifunc-impl-list.c | 10 +
+ .../loongarch/lp64/multiarch/memset-aligned.S | 174 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/memset-lasx.S | 142 ++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/memset-lsx.S | 135 ++++++++++++++
+ .../lp64/multiarch/memset-unaligned.S | 162 ++++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/memset.c | 37 ++++
+ 8 files changed, 688 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memset-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memset-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memset-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memset-unaligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memset.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index 7b87bc90..216886c5 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -30,5 +30,9 @@ sysdep_routines += \
+ memrchr-generic \
+ memrchr-lsx \
+ memrchr-lasx \
++ memset-aligned \
++ memset-unaligned \
++ memset-lsx \
++ memset-lasx \
+ # sysdep_routines
+ endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
+new file mode 100644
+index 00000000..e2723873
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
+@@ -0,0 +1,24 @@
++/* Symbol rediretion for loader/static initialization code.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#ifndef _DL_IFUNC_GENERIC_H
++#define _DL_IFUNC_GENERIC_H
++
++asm ("memset = __memset_aligned");
++
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index 8bd5489e..37f60dde 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -117,5 +117,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ #endif
+ IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_generic)
+ )
++
++ IFUNC_IMPL (i, name, memset,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, memset, SUPPORT_LASX, __memset_lasx)
++ IFUNC_IMPL_ADD (array, i, memset, SUPPORT_LSX, __memset_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, memset, SUPPORT_UAL, __memset_unaligned)
++ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_aligned)
++ )
++
+ return i;
+ }
+diff --git a/sysdeps/loongarch/lp64/multiarch/memset-aligned.S b/sysdeps/loongarch/lp64/multiarch/memset-aligned.S
+new file mode 100644
+index 00000000..1fce95b7
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memset-aligned.S
+@@ -0,0 +1,174 @@
++/* Optimized memset aligned implementation using basic LoongArch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define MEMSET_NAME __memset_aligned
++#else
++# define MEMSET_NAME memset
++#endif
++
++LEAF(MEMSET_NAME, 6)
++ move t0, a0
++ andi a3, a0, 0x7
++ li.w t6, 16
++ beqz a3, L(align)
++ bltu a2, t6, L(short_data)
++
++L(make_align):
++ li.w t8, 8
++ sub.d t2, t8, a3
++ pcaddi t1, 11
++ slli.d t3, t2, 2
++ sub.d t1, t1, t3
++ jr t1
++
++L(al7):
++ st.b a1, t0, 6
++L(al6):
++ st.b a1, t0, 5
++L(al5):
++ st.b a1, t0, 4
++L(al4):
++ st.b a1, t0, 3
++L(al3):
++ st.b a1, t0, 2
++L(al2):
++ st.b a1, t0, 1
++L(al1):
++ st.b a1, t0, 0
++L(al0):
++ add.d t0, t0, t2
++ sub.d a2, a2, t2
++
++L(align):
++ bstrins.d a1, a1, 15, 8
++ bstrins.d a1, a1, 31, 16
++ bstrins.d a1, a1, 63, 32
++ bltu a2, t6, L(less_16bytes)
++
++ andi a4, a2, 0x3f
++ beq a4, a2, L(less_64bytes)
++
++ sub.d t1, a2, a4
++ move a2, a4
++ add.d a5, t0, t1
++
++L(loop_64bytes):
++ addi.d t0, t0, 64
++ st.d a1, t0, -64
++ st.d a1, t0, -56
++ st.d a1, t0, -48
++ st.d a1, t0, -40
++
++ st.d a1, t0, -32
++ st.d a1, t0, -24
++ st.d a1, t0, -16
++ st.d a1, t0, -8
++ bne t0, a5, L(loop_64bytes)
++
++L(less_64bytes):
++ srai.d a4, a2, 5
++ beqz a4, L(less_32bytes)
++ addi.d a2, a2, -32
++ st.d a1, t0, 0
++
++ st.d a1, t0, 8
++ st.d a1, t0, 16
++ st.d a1, t0, 24
++ addi.d t0, t0, 32
++
++L(less_32bytes):
++ bltu a2, t6, L(less_16bytes)
++ addi.d a2, a2, -16
++ st.d a1, t0, 0
++ st.d a1, t0, 8
++ addi.d t0, t0, 16
++
++L(less_16bytes):
++ srai.d a4, a2, 3
++ beqz a4, L(less_8bytes)
++ addi.d a2, a2, -8
++ st.d a1, t0, 0
++ addi.d t0, t0, 8
++
++L(less_8bytes):
++ beqz a2, L(less_1byte)
++ srai.d a4, a2, 2
++ beqz a4, L(less_4bytes)
++ addi.d a2, a2, -4
++ st.w a1, t0, 0
++ addi.d t0, t0, 4
++
++L(less_4bytes):
++ srai.d a3, a2, 1
++ beqz a3, L(less_2bytes)
++ addi.d a2, a2, -2
++ st.h a1, t0, 0
++ addi.d t0, t0, 2
++
++L(less_2bytes):
++ beqz a2, L(less_1byte)
++ st.b a1, t0, 0
++L(less_1byte):
++ jr ra
++
++L(short_data):
++ pcaddi t1, 19
++ slli.d t3, a2, 2
++ sub.d t1, t1, t3
++ jr t1
++L(short_15):
++ st.b a1, a0, 14
++L(short_14):
++ st.b a1, a0, 13
++L(short_13):
++ st.b a1, a0, 12
++L(short_12):
++ st.b a1, a0, 11
++L(short_11):
++ st.b a1, a0, 10
++L(short_10):
++ st.b a1, a0, 9
++L(short_9):
++ st.b a1, a0, 8
++L(short_8):
++ st.b a1, a0, 7
++L(short_7):
++ st.b a1, a0, 6
++L(short_6):
++ st.b a1, a0, 5
++L(short_5):
++ st.b a1, a0, 4
++L(short_4):
++ st.b a1, a0, 3
++L(short_3):
++ st.b a1, a0, 2
++L(short_2):
++ st.b a1, a0, 1
++L(short_1):
++ st.b a1, a0, 0
++L(short_0):
++ jr ra
++END(MEMSET_NAME)
++
++libc_hidden_builtin_def (MEMSET_NAME)
+diff --git a/sysdeps/loongarch/lp64/multiarch/memset-lasx.S b/sysdeps/loongarch/lp64/multiarch/memset-lasx.S
+new file mode 100644
+index 00000000..041abbac
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memset-lasx.S
+@@ -0,0 +1,142 @@
++/* Optimized memset implementation using LoongArch LASX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define MEMSET __memset_lasx
++
++LEAF(MEMSET, 6)
++ li.d t1, 32
++ move a3, a0
++ xvreplgr2vr.b xr0, a1
++ add.d a4, a0, a2
++
++ bgeu t1, a2, L(less_32bytes)
++ li.d t3, 128
++ li.d t2, 64
++ blt t3, a2, L(long_bytes)
++
++L(less_128bytes):
++ bgeu t2, a2, L(less_64bytes)
++ xvst xr0, a3, 0
++ xvst xr0, a3, 32
++ xvst xr0, a4, -32
++
++ xvst xr0, a4, -64
++ jr ra
++L(less_64bytes):
++ xvst xr0, a3, 0
++ xvst xr0, a4, -32
++
++
++ jr ra
++L(less_32bytes):
++ srli.d t0, a2, 4
++ beqz t0, L(less_16bytes)
++ vst vr0, a3, 0
++
++ vst vr0, a4, -16
++ jr ra
++L(less_16bytes):
++ srli.d t0, a2, 3
++ beqz t0, L(less_8bytes)
++
++ vstelm.d vr0, a3, 0, 0
++ vstelm.d vr0, a4, -8, 0
++ jr ra
++L(less_8bytes):
++ srli.d t0, a2, 2
++
++ beqz t0, L(less_4bytes)
++ vstelm.w vr0, a3, 0, 0
++ vstelm.w vr0, a4, -4, 0
++ jr ra
++
++
++L(less_4bytes):
++ srli.d t0, a2, 1
++ beqz t0, L(less_2bytes)
++ vstelm.h vr0, a3, 0, 0
++ vstelm.h vr0, a4, -2, 0
++
++ jr ra
++L(less_2bytes):
++ beqz a2, L(less_1bytes)
++ st.b a1, a3, 0
++L(less_1bytes):
++ jr ra
++
++L(long_bytes):
++ xvst xr0, a3, 0
++ bstrins.d a3, zero, 4, 0
++ addi.d a3, a3, 32
++ sub.d a2, a4, a3
++
++ andi t0, a2, 0xff
++ beq t0, a2, L(long_end)
++ move a2, t0
++ sub.d t0, a4, t0
++
++
++L(loop_256):
++ xvst xr0, a3, 0
++ xvst xr0, a3, 32
++ xvst xr0, a3, 64
++ xvst xr0, a3, 96
++
++ xvst xr0, a3, 128
++ xvst xr0, a3, 160
++ xvst xr0, a3, 192
++ xvst xr0, a3, 224
++
++ addi.d a3, a3, 256
++ bne a3, t0, L(loop_256)
++L(long_end):
++ bltu a2, t3, L(end_less_128)
++ addi.d a2, a2, -128
++
++ xvst xr0, a3, 0
++ xvst xr0, a3, 32
++ xvst xr0, a3, 64
++ xvst xr0, a3, 96
++
++
++ addi.d a3, a3, 128
++L(end_less_128):
++ bltu a2, t2, L(end_less_64)
++ addi.d a2, a2, -64
++ xvst xr0, a3, 0
++
++ xvst xr0, a3, 32
++ addi.d a3, a3, 64
++L(end_less_64):
++ bltu a2, t1, L(end_less_32)
++ xvst xr0, a3, 0
++
++L(end_less_32):
++ xvst xr0, a4, -32
++ jr ra
++END(MEMSET)
++
++libc_hidden_builtin_def (MEMSET)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memset-lsx.S b/sysdeps/loongarch/lp64/multiarch/memset-lsx.S
+new file mode 100644
+index 00000000..3d3982aa
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memset-lsx.S
+@@ -0,0 +1,135 @@
++/* Optimized memset implementation using LoongArch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define MEMSET __memset_lsx
++
++LEAF(MEMSET, 6)
++ li.d t1, 16
++ move a3, a0
++ vreplgr2vr.b vr0, a1
++ add.d a4, a0, a2
++
++ bgeu t1, a2, L(less_16bytes)
++ li.d t3, 64
++ li.d t2, 32
++ bgeu a2, t3, L(long_bytes)
++
++L(less_64bytes):
++ bgeu t2, a2, L(less_32bytes)
++ vst vr0, a3, 0
++ vst vr0, a3, 16
++ vst vr0, a4, -32
++
++ vst vr0, a4, -16
++ jr ra
++L(less_32bytes):
++ vst vr0, a3, 0
++ vst vr0, a4, -16
++
++
++ jr ra
++L(less_16bytes):
++ srli.d t0, a2, 3
++ beqz t0, L(less_8bytes)
++ vstelm.d vr0, a3, 0, 0
++
++ vstelm.d vr0, a4, -8, 0
++ jr ra
++L(less_8bytes):
++ srli.d t0, a2, 2
++ beqz t0, L(less_4bytes)
++
++ vstelm.w vr0, a3, 0, 0
++ vstelm.w vr0, a4, -4, 0
++ jr ra
++L(less_4bytes):
++ srli.d t0, a2, 1
++
++ beqz t0, L(less_2bytes)
++ vstelm.h vr0, a3, 0, 0
++ vstelm.h vr0, a4, -2, 0
++ jr ra
++
++
++L(less_2bytes):
++ beqz a2, L(less_1bytes)
++ vstelm.b vr0, a3, 0, 0
++L(less_1bytes):
++ jr ra
++L(long_bytes):
++ vst vr0, a3, 0
++
++ bstrins.d a3, zero, 3, 0
++ addi.d a3, a3, 16
++ sub.d a2, a4, a3
++ andi t0, a2, 0x7f
++
++ beq t0, a2, L(long_end)
++ move a2, t0
++ sub.d t0, a4, t0
++
++L(loop_128):
++ vst vr0, a3, 0
++
++ vst vr0, a3, 16
++ vst vr0, a3, 32
++ vst vr0, a3, 48
++ vst vr0, a3, 64
++
++
++ vst vr0, a3, 80
++ vst vr0, a3, 96
++ vst vr0, a3, 112
++ addi.d a3, a3, 128
++
++ bne a3, t0, L(loop_128)
++L(long_end):
++ bltu a2, t3, L(end_less_64)
++ addi.d a2, a2, -64
++ vst vr0, a3, 0
++
++ vst vr0, a3, 16
++ vst vr0, a3, 32
++ vst vr0, a3, 48
++ addi.d a3, a3, 64
++
++L(end_less_64):
++ bltu a2, t2, L(end_less_32)
++ addi.d a2, a2, -32
++ vst vr0, a3, 0
++ vst vr0, a3, 16
++
++ addi.d a3, a3, 32
++L(end_less_32):
++ bltu a2, t1, L(end_less_16)
++ vst vr0, a3, 0
++
++L(end_less_16):
++ vst vr0, a4, -16
++ jr ra
++END(MEMSET)
++
++libc_hidden_builtin_def (MEMSET)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memset-unaligned.S b/sysdeps/loongarch/lp64/multiarch/memset-unaligned.S
+new file mode 100644
+index 00000000..f7d32039
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memset-unaligned.S
+@@ -0,0 +1,162 @@
++/* Optimized memset unaligned implementation using basic LoongArch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++
++# define MEMSET_NAME __memset_unaligned
++
++#define ST_128(n) \
++ st.d a1, a0, n; \
++ st.d a1, a0, n+8 ; \
++ st.d a1, a0, n+16 ; \
++ st.d a1, a0, n+24 ; \
++ st.d a1, a0, n+32 ; \
++ st.d a1, a0, n+40 ; \
++ st.d a1, a0, n+48 ; \
++ st.d a1, a0, n+56 ; \
++ st.d a1, a0, n+64 ; \
++ st.d a1, a0, n+72 ; \
++ st.d a1, a0, n+80 ; \
++ st.d a1, a0, n+88 ; \
++ st.d a1, a0, n+96 ; \
++ st.d a1, a0, n+104; \
++ st.d a1, a0, n+112; \
++ st.d a1, a0, n+120;
++
++LEAF(MEMSET_NAME, 6)
++ bstrins.d a1, a1, 15, 8
++ add.d t7, a0, a2
++ bstrins.d a1, a1, 31, 16
++ move t0, a0
++
++ bstrins.d a1, a1, 63, 32
++ srai.d t8, a2, 4
++ beqz t8, L(less_16bytes)
++ srai.d t8, a2, 6
++
++ bnez t8, L(more_64bytes)
++ srai.d t8, a2, 5
++ beqz t8, L(less_32bytes)
++
++ st.d a1, a0, 0
++ st.d a1, a0, 8
++ st.d a1, a0, 16
++ st.d a1, a0, 24
++
++ st.d a1, t7, -32
++ st.d a1, t7, -24
++ st.d a1, t7, -16
++ st.d a1, t7, -8
++
++ jr ra
++
++L(less_32bytes):
++ st.d a1, a0, 0
++ st.d a1, a0, 8
++ st.d a1, t7, -16
++ st.d a1, t7, -8
++
++ jr ra
++
++L(less_16bytes):
++ srai.d t8, a2, 3
++ beqz t8, L(less_8bytes)
++ st.d a1, a0, 0
++ st.d a1, t7, -8
++
++ jr ra
++
++L(less_8bytes):
++ srai.d t8, a2, 2
++ beqz t8, L(less_4bytes)
++ st.w a1, a0, 0
++ st.w a1, t7, -4
++
++ jr ra
++
++L(less_4bytes):
++ srai.d t8, a2, 1
++ beqz t8, L(less_2bytes)
++ st.h a1, a0, 0
++ st.h a1, t7, -2
++
++ jr ra
++
++L(less_2bytes):
++ beqz a2, L(less_1bytes)
++ st.b a1, a0, 0
++
++ jr ra
++
++L(less_1bytes):
++ jr ra
++
++L(more_64bytes):
++ srli.d a0, a0, 3
++ slli.d a0, a0, 3
++ addi.d a0, a0, 0x8
++ st.d a1, t0, 0
++
++ sub.d t2, t0, a0
++ add.d a2, t2, a2
++ addi.d a2, a2, -0x80
++ blt a2, zero, L(end_unalign_proc)
++
++L(loop_less):
++ ST_128(0)
++ addi.d a0, a0, 0x80
++ addi.d a2, a2, -0x80
++ bge a2, zero, L(loop_less)
++
++L(end_unalign_proc):
++ addi.d a2, a2, 0x80
++ pcaddi t1, 20
++ andi t5, a2, 0x78
++ srli.d t5, t5, 1
++
++ sub.d t1, t1, t5
++ jr t1
++
++ st.d a1, a0, 112
++ st.d a1, a0, 104
++ st.d a1, a0, 96
++ st.d a1, a0, 88
++ st.d a1, a0, 80
++ st.d a1, a0, 72
++ st.d a1, a0, 64
++ st.d a1, a0, 56
++ st.d a1, a0, 48
++ st.d a1, a0, 40
++ st.d a1, a0, 32
++ st.d a1, a0, 24
++ st.d a1, a0, 16
++ st.d a1, a0, 8
++ st.d a1, a0, 0
++ st.d a1, t7, -8
++
++ move a0, t0
++ jr ra
++END(MEMSET_NAME)
++
++libc_hidden_builtin_def (MEMSET_NAME)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memset.c b/sysdeps/loongarch/lp64/multiarch/memset.c
+new file mode 100644
+index 00000000..3ff60d8a
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memset.c
+@@ -0,0 +1,37 @@
++/* Multiple versions of memset.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define memset __redirect_memset
++# include <string.h>
++# undef memset
++
++# define SYMBOL_NAME memset
++# include "ifunc-lasx.h"
++
++libc_ifunc_redirected (__redirect_memset, memset,
++ IFUNC_SELECTOR ());
++
++# ifdef SHARED
++__hidden_ver1 (memset, __GI_memset, __redirect_memset)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memset);
++# endif
++
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-rawmemchr-aligned-ls.patch b/LoongArch-Add-ifunc-support-for-rawmemchr-aligned-ls.patch
new file mode 100644
index 0000000..1ac8637
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-rawmemchr-aligned-ls.patch
@@ -0,0 +1,448 @@
+From b412bcb2cf4914a664bcd24924d670a2e37394b3 Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Mon, 28 Aug 2023 10:08:35 +0800
+Subject: [PATCH 14/29] LoongArch: Add ifunc support for rawmemchr{aligned,
+ lsx, lasx}
+
+According to glibc rawmemchr microbenchmark, A few cases tested with
+char '\0' experience performance degradation due to the lasx and lsx
+versions don't handle the '\0' separately. Overall, rawmemchr-lasx
+implementation could reduce the runtime about 40%-80%, rawmemchr-lsx
+implementation could reduce the runtime about 40%-66%, rawmemchr-aligned
+implementation could reduce the runtime about 20%-40%.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 3 +
+ .../lp64/multiarch/ifunc-impl-list.c | 8 ++
+ .../lp64/multiarch/ifunc-rawmemchr.h | 40 ++++++
+ .../lp64/multiarch/rawmemchr-aligned.S | 124 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/rawmemchr-lasx.S | 82 ++++++++++++
+ .../loongarch/lp64/multiarch/rawmemchr-lsx.S | 71 ++++++++++
+ sysdeps/loongarch/lp64/multiarch/rawmemchr.c | 37 ++++++
+ 7 files changed, 365 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-rawmemchr.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/rawmemchr-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/rawmemchr-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/rawmemchr-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/rawmemchr.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index 5d7ae7ae..64416b02 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -21,5 +21,8 @@ sysdep_routines += \
+ memmove-unaligned \
+ memmove-lsx \
+ memmove-lasx \
++ rawmemchr-aligned \
++ rawmemchr-lsx \
++ rawmemchr-lasx \
+ # sysdep_routines
+ endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index c8ba87bd..3db9af14 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -94,5 +94,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_aligned)
+ )
+
++ IFUNC_IMPL (i, name, rawmemchr,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, rawmemchr, SUPPORT_LASX, __rawmemchr_lasx)
++ IFUNC_IMPL_ADD (array, i, rawmemchr, SUPPORT_LSX, __rawmemchr_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_aligned)
++ )
++
+ return i;
+ }
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-rawmemchr.h b/sysdeps/loongarch/lp64/multiarch/ifunc-rawmemchr.h
+new file mode 100644
+index 00000000..a7bb4cf9
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-rawmemchr.h
+@@ -0,0 +1,40 @@
++/* Common definition for rawmemchr ifunc selections.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/rawmemchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/rawmemchr-aligned.S
+new file mode 100644
+index 00000000..9c7155ae
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/rawmemchr-aligned.S
+@@ -0,0 +1,124 @@
++/* Optimized rawmemchr implementation using basic LoongArch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define RAWMEMCHR_NAME __rawmemchr_aligned
++#else
++# define RAWMEMCHR_NAME __rawmemchr
++#endif
++
++LEAF(RAWMEMCHR_NAME, 6)
++ andi t1, a0, 0x7
++ bstrins.d a0, zero, 2, 0
++ lu12i.w a2, 0x01010
++ bstrins.d a1, a1, 15, 8
++
++ ld.d t0, a0, 0
++ slli.d t1, t1, 3
++ ori a2, a2, 0x101
++ bstrins.d a1, a1, 31, 16
++
++ li.w t8, -1
++ bstrins.d a1, a1, 63, 32
++ bstrins.d a2, a2, 63, 32
++ sll.d t2, t8, t1
++
++ sll.d t3, a1, t1
++ orn t0, t0, t2
++ slli.d a3, a2, 7
++ beqz a1, L(find_zero)
++
++ xor t0, t0, t3
++ sub.d t1, t0, a2
++ andn t2, a3, t0
++ and t3, t1, t2
++
++ bnez t3, L(count_pos)
++ addi.d a0, a0, 8
++
++L(loop):
++ ld.d t0, a0, 0
++ xor t0, t0, a1
++
++ sub.d t1, t0, a2
++ andn t2, a3, t0
++ and t3, t1, t2
++ bnez t3, L(count_pos)
++
++ ld.d t0, a0, 8
++ addi.d a0, a0, 16
++ xor t0, t0, a1
++ sub.d t1, t0, a2
++
++ andn t2, a3, t0
++ and t3, t1, t2
++ beqz t3, L(loop)
++ addi.d a0, a0, -8
++L(count_pos):
++ ctz.d t0, t3
++ srli.d t0, t0, 3
++ add.d a0, a0, t0
++ jr ra
++
++L(loop_7bit):
++ ld.d t0, a0, 0
++L(find_zero):
++ sub.d t1, t0, a2
++ and t2, t1, a3
++ bnez t2, L(more_check)
++
++ ld.d t0, a0, 8
++ addi.d a0, a0, 16
++ sub.d t1, t0, a2
++ and t2, t1, a3
++
++ beqz t2, L(loop_7bit)
++ addi.d a0, a0, -8
++
++L(more_check):
++ andn t2, a3, t0
++ and t3, t1, t2
++ bnez t3, L(count_pos)
++ addi.d a0, a0, 8
++
++L(loop_8bit):
++ ld.d t0, a0, 0
++
++ sub.d t1, t0, a2
++ andn t2, a3, t0
++ and t3, t1, t2
++ bnez t3, L(count_pos)
++
++ ld.d t0, a0, 8
++ addi.d a0, a0, 16
++ sub.d t1, t0, a2
++
++ andn t2, a3, t0
++ and t3, t1, t2
++ beqz t3, L(loop_8bit)
++
++ addi.d a0, a0, -8
++ b L(count_pos)
++
++END(RAWMEMCHR_NAME)
++
++libc_hidden_builtin_def (__rawmemchr)
+diff --git a/sysdeps/loongarch/lp64/multiarch/rawmemchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/rawmemchr-lasx.S
+new file mode 100644
+index 00000000..be2eb59d
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/rawmemchr-lasx.S
+@@ -0,0 +1,82 @@
++/* Optimized rawmemchr implementation using LoongArch LASX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/asm.h>
++#include <sys/regdef.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define RAWMEMCHR __rawmemchr_lasx
++
++LEAF(RAWMEMCHR, 6)
++ move a2, a0
++ bstrins.d a0, zero, 5, 0
++ xvld xr0, a0, 0
++ xvld xr1, a0, 32
++
++ xvreplgr2vr.b xr2, a1
++ xvseq.b xr0, xr0, xr2
++ xvseq.b xr1, xr1, xr2
++ xvmsknz.b xr0, xr0
++
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr3, xr0, 4
++ xvpickve.w xr4, xr1, 4
++ vilvl.h vr0, vr3, vr0
++
++ vilvl.h vr1, vr4, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++ sra.d t0, t0, a2
++
++
++ beqz t0, L(loop)
++ ctz.d t0, t0
++ add.d a0, a2, t0
++ jr ra
++
++L(loop):
++ xvld xr0, a0, 64
++ xvld xr1, a0, 96
++ addi.d a0, a0, 64
++ xvseq.b xr0, xr0, xr2
++
++ xvseq.b xr1, xr1, xr2
++ xvmax.bu xr3, xr0, xr1
++ xvseteqz.v fcc0, xr3
++ bcnez fcc0, L(loop)
++
++ xvmsknz.b xr0, xr0
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr3, xr0, 4
++ xvpickve.w xr4, xr1, 4
++
++
++ vilvl.h vr0, vr3, vr0
++ vilvl.h vr1, vr4, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++
++ ctz.d t0, t0
++ add.d a0, a0, t0
++ jr ra
++END(RAWMEMCHR)
++
++libc_hidden_builtin_def (RAWMEMCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/rawmemchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/rawmemchr-lsx.S
+new file mode 100644
+index 00000000..2f6fe024
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/rawmemchr-lsx.S
+@@ -0,0 +1,71 @@
++/* Optimized rawmemchr implementation using LoongArch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define RAWMEMCHR __rawmemchr_lsx
++
++LEAF(RAWMEMCHR, 6)
++ move a2, a0
++ bstrins.d a0, zero, 4, 0
++ vld vr0, a0, 0
++ vld vr1, a0, 16
++
++ vreplgr2vr.b vr2, a1
++ vseq.b vr0, vr0, vr2
++ vseq.b vr1, vr1, vr2
++ vmsknz.b vr0, vr0
++
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++ sra.w t0, t0, a2
++
++ beqz t0, L(loop)
++ ctz.w t0, t0
++ add.d a0, a2, t0
++ jr ra
++
++
++L(loop):
++ vld vr0, a0, 32
++ vld vr1, a0, 48
++ addi.d a0, a0, 32
++ vseq.b vr0, vr0, vr2
++
++ vseq.b vr1, vr1, vr2
++ vmax.bu vr3, vr0, vr1
++ vseteqz.v fcc0, vr3
++ bcnez fcc0, L(loop)
++
++ vmsknz.b vr0, vr0
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++
++ ctz.w t0, t0
++ add.d a0, a0, t0
++ jr ra
++END(RAWMEMCHR)
++
++libc_hidden_builtin_def (RAWMEMCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/rawmemchr.c b/sysdeps/loongarch/lp64/multiarch/rawmemchr.c
+new file mode 100644
+index 00000000..89c7ffff
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/rawmemchr.c
+@@ -0,0 +1,37 @@
++/* Multiple versions of rawmemchr.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#if IS_IN (libc)
++# define rawmemchr __redirect_rawmemchr
++# define __rawmemchr __redirect___rawmemchr
++# include <string.h>
++# undef rawmemchr
++# undef __rawmemchr
++
++# define SYMBOL_NAME rawmemchr
++# include "ifunc-rawmemchr.h"
++
++libc_ifunc_redirected (__redirect_rawmemchr, __rawmemchr,
++ IFUNC_SELECTOR ());
++weak_alias (__rawmemchr, rawmemchr)
++# ifdef SHARED
++__hidden_ver1 (__rawmemchr, __GI___rawmemchr, __redirect___rawmemchr)
++ __attribute__((visibility ("hidden")));
++# endif
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-strcmp-aligned-lsx.patch b/LoongArch-Add-ifunc-support-for-strcmp-aligned-lsx.patch
new file mode 100644
index 0000000..d960bc6
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-strcmp-aligned-lsx.patch
@@ -0,0 +1,499 @@
+From e258cfcf92f5e31e902fa045b41652f00fcf2521 Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Thu, 24 Aug 2023 16:50:18 +0800
+Subject: [PATCH 09/29] LoongArch: Add ifunc support for strcmp{aligned, lsx}
+
+Based on the glibc microbenchmark, strcmp-aligned implementation could
+reduce the runtime 0%-10% for aligned comparison, 10%-20% for unaligned
+comparison, strcmp-lsx implemenation could reduce the runtime 0%-50%.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 2 +
+ .../lp64/multiarch/ifunc-impl-list.c | 7 +
+ .../loongarch/lp64/multiarch/ifunc-strcmp.h | 38 ++++
+ .../loongarch/lp64/multiarch/strcmp-aligned.S | 179 ++++++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S | 165 ++++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/strcmp.c | 35 ++++
+ 6 files changed, 426 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-strcmp.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strcmp.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index c4dd3143..d5a500de 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -12,6 +12,8 @@ sysdep_routines += \
+ strchrnul-aligned \
+ strchrnul-lsx \
+ strchrnul-lasx \
++ strcmp-aligned \
++ strcmp-lsx \
+ memcpy-aligned \
+ memcpy-unaligned \
+ memmove-unaligned \
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index 7cec0b77..9183b7da 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -62,6 +62,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, strchrnul, 1, __strchrnul_aligned)
+ )
+
++ IFUNC_IMPL (i, name, strcmp,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, strcmp, SUPPORT_LSX, __strcmp_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_aligned)
++ )
++
+ IFUNC_IMPL (i, name, memcpy,
+ #if !defined __loongarch_soft_float
+ IFUNC_IMPL_ADD (array, i, memcpy, SUPPORT_LASX, __memcpy_lasx)
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-strcmp.h b/sysdeps/loongarch/lp64/multiarch/ifunc-strcmp.h
+new file mode 100644
+index 00000000..ca26352b
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-strcmp.h
+@@ -0,0 +1,38 @@
++/* Common definition for strcmp ifunc selection.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S b/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S
+new file mode 100644
+index 00000000..f5f4f336
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S
+@@ -0,0 +1,179 @@
++/* Optimized strcmp implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define STRCMP_NAME __strcmp_aligned
++#else
++# define STRCMP_NAME strcmp
++#endif
++
++LEAF(STRCMP_NAME, 6)
++ lu12i.w a4, 0x01010
++ andi a2, a0, 0x7
++ ori a4, a4, 0x101
++ andi a3, a1, 0x7
++
++ bstrins.d a4, a4, 63, 32
++ li.d t7, -1
++ li.d t8, 8
++ slli.d a5, a4, 7
++
++ bne a2, a3, L(unaligned)
++ bstrins.d a0, zero, 2, 0
++ bstrins.d a1, zero, 2, 0
++ ld.d t0, a0, 0
++
++ ld.d t1, a1, 0
++ slli.d t3, a2, 3
++ sll.d t2, t7, t3
++ orn t0, t0, t2
++
++
++ orn t1, t1, t2
++ sub.d t2, t0, a4
++ andn t3, a5, t0
++ and t2, t2, t3
++
++ bne t0, t1, L(al_end)
++L(al_loop):
++ bnez t2, L(ret0)
++ ldx.d t0, a0, t8
++ ldx.d t1, a1, t8
++
++ addi.d t8, t8, 8
++ sub.d t2, t0, a4
++ andn t3, a5, t0
++ and t2, t2, t3
++
++ beq t0, t1, L(al_loop)
++L(al_end):
++ xor t3, t0, t1
++ or t2, t2, t3
++ ctz.d t3, t2
++
++
++ bstrins.d t3, zero, 2, 0
++ srl.d t0, t0, t3
++ srl.d t1, t1, t3
++ andi t0, t0, 0xff
++
++ andi t1, t1, 0xff
++ sub.d a0, t0, t1
++ jr ra
++ nop
++
++L(ret0):
++ move a0, zero
++ jr ra
++ nop
++ nop
++
++L(unaligned):
++ slt a6, a3, a2
++ xor t0, a0, a1
++ maskeqz t0, t0, a6
++ xor a0, a0, t0
++
++
++ xor a1, a1, t0
++ andi a2, a0, 0x7
++ andi a3, a1, 0x7
++ bstrins.d a0, zero, 2, 0
++
++ bstrins.d a1, zero, 2, 0
++ ld.d t4, a0, 0
++ ld.d t1, a1, 0
++ slli.d a2, a2, 3
++
++ slli.d a3, a3, 3
++ srl.d t0, t4, a2
++ srl.d t1, t1, a3
++ srl.d t5, t7, a3
++
++ orn t0, t0, t5
++ orn t1, t1, t5
++ bne t0, t1, L(not_equal)
++ sll.d t5, t7, a2
++
++
++ sub.d a3, a2, a3
++ orn t4, t4, t5
++ sub.d a2, zero, a3
++ sub.d t2, t4, a4
++
++ andn t3, a5, t4
++ and t2, t2, t3
++ bnez t2, L(find_zero)
++L(un_loop):
++ srl.d t5, t4, a3
++
++ ldx.d t4, a0, t8
++ ldx.d t1, a1, t8
++ addi.d t8, t8, 8
++ sll.d t0, t4, a2
++
++ or t0, t0, t5
++ bne t0, t1, L(not_equal)
++ sub.d t2, t4, a4
++ andn t3, a5, t4
++
++
++ and t2, t2, t3
++ beqz t2, L(un_loop)
++L(find_zero):
++ sub.d t2, t0, a4
++ andn t3, a5, t0
++
++ and t2, t2, t3
++ bnez t2, L(ret0)
++ ldx.d t1, a1, t8
++ srl.d t0, t4, a3
++
++L(not_equal):
++ sub.d t2, t0, a4
++ andn t3, a5, t0
++ and t2, t2, t3
++ xor t3, t0, t1
++
++ or t2, t2, t3
++L(un_end):
++ ctz.d t3, t2
++ bstrins.d t3, zero, 2, 0
++ srl.d t0, t0, t3
++
++
++ srl.d t1, t1, t3
++ andi t0, t0, 0xff
++ andi t1, t1, 0xff
++ sub.d t2, t0, t1
++
++
++ sub.d t3, t1, t0
++ masknez t0, t2, a6
++ maskeqz t1, t3, a6
++ or a0, t0, t1
++
++ jr ra
++END(STRCMP_NAME)
++
++libc_hidden_builtin_def (STRCMP_NAME)
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S b/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S
+new file mode 100644
+index 00000000..2e177a38
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S
+@@ -0,0 +1,165 @@
++/* Optimized strcmp implementation using Loongarch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define STRCMP __strcmp_lsx
++
++LEAF(STRCMP, 6)
++ pcalau12i t0, %pc_hi20(L(INDEX))
++ andi a2, a0, 0xf
++ vld vr2, t0, %pc_lo12(L(INDEX))
++ andi a3, a1, 0xf
++
++ bne a2, a3, L(unaligned)
++ bstrins.d a0, zero, 3, 0
++ bstrins.d a1, zero, 3, 0
++ vld vr0, a0, 0
++
++ vld vr1, a1, 0
++ vreplgr2vr.b vr3, a2
++ vslt.b vr2, vr2, vr3
++ vseq.b vr3, vr0, vr1
++
++ vmin.bu vr3, vr0, vr3
++ vor.v vr3, vr3, vr2
++ vsetanyeqz.b fcc0, vr3
++ bcnez fcc0, L(al_out)
++
++
++L(al_loop):
++ vld vr0, a0, 16
++ vld vr1, a1, 16
++ addi.d a0, a0, 16
++ addi.d a1, a1, 16
++
++ vseq.b vr3, vr0, vr1
++ vmin.bu vr3, vr0, vr3
++ vsetanyeqz.b fcc0, vr3
++ bceqz fcc0, L(al_loop)
++
++L(al_out):
++ vseqi.b vr3, vr3, 0
++ vfrstpi.b vr3, vr3, 0
++ vshuf.b vr0, vr0, vr0, vr3
++ vshuf.b vr1, vr1, vr1, vr3
++
++ vpickve2gr.bu t0, vr0, 0
++ vpickve2gr.bu t1, vr1, 0
++ sub.d a0, t0, t1
++ jr ra
++
++
++L(unaligned):
++ slt a4, a3, a2
++ xor t0, a0, a1
++ maskeqz t0, t0, a4
++ xor a0, a0, t0
++
++ xor a1, a1, t0
++ andi a2, a0, 0xf
++ andi a3, a1, 0xf
++ bstrins.d a0, zero, 3, 0
++
++ bstrins.d a1, zero, 3, 0
++ vld vr3, a0, 0
++ vld vr1, a1, 0
++ vreplgr2vr.b vr4, a2
++
++ vreplgr2vr.b vr5, a3
++ vslt.b vr7, vr2, vr5
++ vsub.b vr5, vr5, vr4
++ vaddi.bu vr6, vr2, 16
++
++
++ vsub.b vr6, vr6, vr5
++ vshuf.b vr0, vr3, vr3, vr6
++ vor.v vr0, vr0, vr7
++ vor.v vr1, vr1, vr7
++
++ vseq.b vr5, vr0, vr1
++ vsetanyeqz.b fcc0, vr5
++ bcnez fcc0, L(not_equal)
++ vslt.b vr4, vr2, vr4
++
++ vor.v vr0, vr3, vr4
++ vsetanyeqz.b fcc0, vr0
++ bcnez fcc0, L(find_zero)
++ nop
++
++L(un_loop):
++ vld vr3, a0, 16
++ vld vr1, a1, 16
++ addi.d a0, a0, 16
++ addi.d a1, a1, 16
++
++
++ vshuf.b vr0, vr3, vr0, vr6
++ vseq.b vr5, vr0, vr1
++ vsetanyeqz.b fcc0, vr5
++ bcnez fcc0, L(not_equal)
++
++ vsetanyeqz.b fcc0, vr3
++ vor.v vr0, vr3, vr3
++ bceqz fcc0, L(un_loop)
++L(find_zero):
++ vmin.bu vr5, vr1, vr5
++
++ vsetanyeqz.b fcc0, vr5
++ bcnez fcc0, L(ret0)
++ vld vr1, a1, 16
++ vshuf.b vr0, vr3, vr3, vr6
++
++ vseq.b vr5, vr0, vr1
++L(not_equal):
++ vmin.bu vr5, vr0, vr5
++L(un_end):
++ vseqi.b vr5, vr5, 0
++ vfrstpi.b vr5, vr5, 0
++
++
++ vshuf.b vr0, vr0, vr0, vr5
++ vshuf.b vr1, vr1, vr1, vr5
++ vpickve2gr.bu t0, vr0, 0
++ vpickve2gr.bu t1, vr1, 0
++
++ sub.d t3, t0, t1
++ sub.d t4, t1, t0
++ masknez t0, t3, a4
++ maskeqz t1, t4, a4
++
++ or a0, t0, t1
++ jr ra
++L(ret0):
++ move a0, zero
++ jr ra
++END(STRCMP)
++
++ .section .rodata.cst16,"M",@progbits,16
++ .align 4
++L(INDEX):
++ .dword 0x0706050403020100
++ .dword 0x0f0e0d0c0b0a0908
++
++libc_hidden_builtin_def (STRCMP)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcmp.c b/sysdeps/loongarch/lp64/multiarch/strcmp.c
+new file mode 100644
+index 00000000..6f249c0b
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strcmp.c
+@@ -0,0 +1,35 @@
++/* Multiple versions of strcmp.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <http://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define strcmp __redirect_strcmp
++# include <string.h>
++# undef strcmp
++
++# define SYMBOL_NAME strcmp
++# include "ifunc-strcmp.h"
++
++libc_ifunc_redirected (__redirect_strcmp, strcmp, IFUNC_SELECTOR ());
++
++# ifdef SHARED
++__hidden_ver1 (strcmp, __GI_strcmp, __redirect_strcmp)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strcmp);
++# endif
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-strcpy-stpcpy-aligne.patch b/LoongArch-Add-ifunc-support-for-strcpy-stpcpy-aligne.patch
new file mode 100644
index 0000000..2e98b05
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-strcpy-stpcpy-aligne.patch
@@ -0,0 +1,1099 @@
+From 351086591d938aaf884d475261ae96ec5da00384 Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Wed, 13 Sep 2023 15:34:59 +0800
+Subject: [PATCH 22/29] LoongArch: Add ifunc support for strcpy,
+ stpcpy{aligned, unaligned, lsx, lasx}
+
+According to glibc strcpy and stpcpy microbenchmark test results(changed
+to use generic_strcpy and generic_stpcpy instead of strlen + memcpy),
+comparing with the generic version, this implementation could reduce the
+runtime as following:
+
+Name Percent of rutime reduced
+strcpy-aligned 8%-45%
+strcpy-unaligned 8%-48%, comparing with the aligned version, unaligned
+ version takes less instructions to copy the tail of data
+ which length is less than 8. it also has better performance
+ in case src and dest cannot be both aligned with 8bytes
+strcpy-lsx 20%-80%
+strcpy-lasx 15%-86%
+stpcpy-aligned 6%-43%
+stpcpy-unaligned 8%-48%
+stpcpy-lsx 10%-80%
+stpcpy-lasx 10%-87%
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 8 +
+ .../lp64/multiarch/ifunc-impl-list.c | 18 ++
+ .../loongarch/lp64/multiarch/stpcpy-aligned.S | 27 +++
+ .../loongarch/lp64/multiarch/stpcpy-lasx.S | 22 ++
+ sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S | 22 ++
+ .../lp64/multiarch/stpcpy-unaligned.S | 22 ++
+ sysdeps/loongarch/lp64/multiarch/stpcpy.c | 42 ++++
+ .../loongarch/lp64/multiarch/strcpy-aligned.S | 202 ++++++++++++++++
+ .../loongarch/lp64/multiarch/strcpy-lasx.S | 215 ++++++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S | 212 +++++++++++++++++
+ .../lp64/multiarch/strcpy-unaligned.S | 138 +++++++++++
+ sysdeps/loongarch/lp64/multiarch/strcpy.c | 35 +++
+ 12 files changed, 963 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/stpcpy-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/stpcpy-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/stpcpy-unaligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/stpcpy.c
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strcpy-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strcpy-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strcpy-unaligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strcpy.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index 360a6718..39550bea 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -16,6 +16,14 @@ sysdep_routines += \
+ strcmp-lsx \
+ strncmp-aligned \
+ strncmp-lsx \
++ strcpy-aligned \
++ strcpy-unaligned \
++ strcpy-lsx \
++ strcpy-lasx \
++ stpcpy-aligned \
++ stpcpy-unaligned \
++ stpcpy-lsx \
++ stpcpy-lasx \
+ memcpy-aligned \
+ memcpy-unaligned \
+ memmove-unaligned \
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index e397d58c..39a14f1d 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -76,6 +76,24 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_aligned)
+ )
+
++ IFUNC_IMPL (i, name, strcpy,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, strcpy, SUPPORT_LASX, __strcpy_lasx)
++ IFUNC_IMPL_ADD (array, i, strcpy, SUPPORT_LSX, __strcpy_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, strcpy, SUPPORT_UAL, __strcpy_unaligned)
++ IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_aligned)
++ )
++
++ IFUNC_IMPL (i, name, stpcpy,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, stpcpy, SUPPORT_LASX, __stpcpy_lasx)
++ IFUNC_IMPL_ADD (array, i, stpcpy, SUPPORT_LSX, __stpcpy_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, stpcpy, SUPPORT_UAL, __stpcpy_unaligned)
++ IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_aligned)
++ )
++
+ IFUNC_IMPL (i, name, memcpy,
+ #if !defined __loongarch_soft_float
+ IFUNC_IMPL_ADD (array, i, memcpy, SUPPORT_LASX, __memcpy_lasx)
+diff --git a/sysdeps/loongarch/lp64/multiarch/stpcpy-aligned.S b/sysdeps/loongarch/lp64/multiarch/stpcpy-aligned.S
+new file mode 100644
+index 00000000..1f763db6
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/stpcpy-aligned.S
+@@ -0,0 +1,27 @@
++/* stpcpy-aligned implementation is in strcpy-aligned.S.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#if IS_IN (libc)
++# define STPCPY __stpcpy_aligned
++#else
++# define STPCPY __stpcpy
++#endif
++
++#define USE_AS_STPCPY
++#define STRCPY STPCPY
++#include "strcpy-aligned.S"
+diff --git a/sysdeps/loongarch/lp64/multiarch/stpcpy-lasx.S b/sysdeps/loongarch/lp64/multiarch/stpcpy-lasx.S
+new file mode 100644
+index 00000000..13d6c953
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/stpcpy-lasx.S
+@@ -0,0 +1,22 @@
++/* stpcpy-lasx implementation is in strcpy-lasx.S.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#define STPCPY __stpcpy_lasx
++#define USE_AS_STPCPY
++#define STRCPY STPCPY
++#include "strcpy-lasx.S"
+diff --git a/sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S b/sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S
+new file mode 100644
+index 00000000..e0f17ab5
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S
+@@ -0,0 +1,22 @@
++/* stpcpy-lsx implementation is in strcpy-lsx.S.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#define STPCPY __stpcpy_lsx
++#define USE_AS_STPCPY
++#define STRCPY STPCPY
++#include "strcpy-lsx.S"
+diff --git a/sysdeps/loongarch/lp64/multiarch/stpcpy-unaligned.S b/sysdeps/loongarch/lp64/multiarch/stpcpy-unaligned.S
+new file mode 100644
+index 00000000..cc2f9712
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/stpcpy-unaligned.S
+@@ -0,0 +1,22 @@
++/* stpcpy-unaligned implementation is in strcpy-unaligned.S.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#define STPCPY __stpcpy_unaligned
++#define USE_AS_STPCPY
++#define STRCPY STPCPY
++#include "strcpy-unaligned.S"
+diff --git a/sysdeps/loongarch/lp64/multiarch/stpcpy.c b/sysdeps/loongarch/lp64/multiarch/stpcpy.c
+new file mode 100644
+index 00000000..d4860d7a
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/stpcpy.c
+@@ -0,0 +1,42 @@
++/* Multiple versions of stpcpy.
++ All versions must be listed in ifunc-impl-list.c.
++ Copyright (C) 2017-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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define stpcpy __redirect_stpcpy
++# define __stpcpy __redirect___stpcpy
++# define NO_MEMPCPY_STPCPY_REDIRECT
++# define __NO_STRING_INLINES
++# include <string.h>
++# undef stpcpy
++# undef __stpcpy
++
++# define SYMBOL_NAME stpcpy
++# include "ifunc-lasx.h"
++
++libc_ifunc_redirected (__redirect_stpcpy, __stpcpy, IFUNC_SELECTOR ());
++
++weak_alias (__stpcpy, stpcpy)
++# ifdef SHARED
++__hidden_ver1 (__stpcpy, __GI___stpcpy, __redirect___stpcpy)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (stpcpy);
++__hidden_ver1 (stpcpy, __GI_stpcpy, __redirect_stpcpy)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (stpcpy);
++# endif
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcpy-aligned.S b/sysdeps/loongarch/lp64/multiarch/strcpy-aligned.S
+new file mode 100644
+index 00000000..4ed539fd
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strcpy-aligned.S
+@@ -0,0 +1,202 @@
++/* Optimized strcpy stpcpy aligned implementation using basic LoongArch
++ instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# ifndef STRCPY
++# define STRCPY __strcpy_aligned
++# endif
++#else
++# ifndef STRCPY
++# define STRCPY strcpy
++# endif
++#endif
++
++LEAF(STRCPY, 6)
++ andi a3, a0, 0x7
++ move a2, a0
++ beqz a3, L(dest_align)
++ sub.d a5, a1, a3
++ addi.d a5, a5, 8
++
++L(make_dest_align):
++ ld.b t0, a1, 0
++ addi.d a1, a1, 1
++ st.b t0, a2, 0
++ addi.d a2, a2, 1
++ beqz t0, L(al_out)
++
++ bne a1, a5, L(make_dest_align)
++
++L(dest_align):
++ andi a4, a1, 7
++ bstrins.d a1, zero, 2, 0
++
++ lu12i.w t5, 0x1010
++ ld.d t0, a1, 0
++ ori t5, t5, 0x101
++ bstrins.d t5, t5, 63, 32
++
++ slli.d t6, t5, 0x7
++ bnez a4, L(unalign)
++ sub.d t1, t0, t5
++ andn t2, t6, t0
++
++ and t3, t1, t2
++ bnez t3, L(al_end)
++
++L(al_loop):
++ st.d t0, a2, 0
++ ld.d t0, a1, 8
++
++ addi.d a1, a1, 8
++ addi.d a2, a2, 8
++ sub.d t1, t0, t5
++ andn t2, t6, t0
++
++ and t3, t1, t2
++ beqz t3, L(al_loop)
++
++L(al_end):
++ ctz.d t1, t3
++ srli.d t1, t1, 3
++ addi.d t1, t1, 1
++
++ andi a3, t1, 8
++ andi a4, t1, 4
++ andi a5, t1, 2
++ andi a6, t1, 1
++
++L(al_end_8):
++ beqz a3, L(al_end_4)
++ st.d t0, a2, 0
++#ifdef USE_AS_STPCPY
++ addi.d a0, a2, 7
++#endif
++ jr ra
++L(al_end_4):
++ beqz a4, L(al_end_2)
++ st.w t0, a2, 0
++ addi.d a2, a2, 4
++ srli.d t0, t0, 32
++L(al_end_2):
++ beqz a5, L(al_end_1)
++ st.h t0, a2, 0
++ addi.d a2, a2, 2
++ srli.d t0, t0, 16
++L(al_end_1):
++ beqz a6, L(al_out)
++ st.b t0, a2, 0
++ addi.d a2, a2, 1
++L(al_out):
++#ifdef USE_AS_STPCPY
++ addi.d a0, a2, -1
++#endif
++ jr ra
++
++ .align 4
++L(unalign):
++ slli.d a5, a4, 3
++ li.d t1, -1
++ sub.d a6, zero, a5
++
++ srl.d a7, t0, a5
++ sll.d t7, t1, a6
++
++ or t0, a7, t7
++ sub.d t1, t0, t5
++ andn t2, t6, t0
++ and t3, t1, t2
++
++ bnez t3, L(un_end)
++
++ ld.d t4, a1, 8
++
++ sub.d t1, t4, t5
++ andn t2, t6, t4
++ sll.d t0, t4, a6
++ and t3, t1, t2
++
++ or t0, t0, a7
++ bnez t3, L(un_end_with_remaining)
++
++L(un_loop):
++ srl.d a7, t4, a5
++
++ ld.d t4, a1, 16
++ addi.d a1, a1, 8
++
++ st.d t0, a2, 0
++ addi.d a2, a2, 8
++
++ sub.d t1, t4, t5
++ andn t2, t6, t4
++ sll.d t0, t4, a6
++ and t3, t1, t2
++
++ or t0, t0, a7
++ beqz t3, L(un_loop)
++
++L(un_end_with_remaining):
++ ctz.d t1, t3
++ srli.d t1, t1, 3
++ addi.d t1, t1, 1
++ sub.d t1, t1, a4
++
++ blt t1, zero, L(un_end_less_8)
++ st.d t0, a2, 0
++ addi.d a2, a2, 8
++ beqz t1, L(un_out)
++ srl.d t0, t4, a5
++ b L(un_end_less_8)
++
++L(un_end):
++ ctz.d t1, t3
++ srli.d t1, t1, 3
++ addi.d t1, t1, 1
++
++L(un_end_less_8):
++ andi a4, t1, 4
++ andi a5, t1, 2
++ andi a6, t1, 1
++L(un_end_4):
++ beqz a4, L(un_end_2)
++ st.w t0, a2, 0
++ addi.d a2, a2, 4
++ srli.d t0, t0, 32
++L(un_end_2):
++ beqz a5, L(un_end_1)
++ st.h t0, a2, 0
++ addi.d a2, a2, 2
++ srli.d t0, t0, 16
++L(un_end_1):
++ beqz a6, L(un_out)
++ st.b t0, a2, 0
++ addi.d a2, a2, 1
++L(un_out):
++#ifdef USE_AS_STPCPY
++ addi.d a0, a2, -1
++#endif
++ jr ra
++END(STRCPY)
++
++libc_hidden_builtin_def (STRCPY)
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcpy-lasx.S b/sysdeps/loongarch/lp64/multiarch/strcpy-lasx.S
+new file mode 100644
+index 00000000..c2825612
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strcpy-lasx.S
+@@ -0,0 +1,215 @@
++/* Optimized strcpy stpcpy implementation using LoongArch LASX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# ifndef STRCPY
++# define STRCPY __strcpy_lasx
++# endif
++
++# ifdef USE_AS_STPCPY
++# define dstend a0
++# else
++# define dstend a4
++# endif
++
++LEAF(STRCPY, 6)
++ ori t8, zero, 0xfe0
++ andi t0, a1, 0xfff
++ li.d t7, -1
++ move a2, a0
++
++ bltu t8, t0, L(page_cross_start)
++L(start_entry):
++ xvld xr0, a1, 0
++ li.d t0, 32
++ andi t1, a2, 0x1f
++
++ xvsetanyeqz.b fcc0, xr0
++ sub.d t0, t0, t1
++ bcnez fcc0, L(end)
++ add.d a1, a1, t0
++
++ xvst xr0, a2, 0
++ andi a3, a1, 0x1f
++ add.d a2, a2, t0
++ bnez a3, L(unaligned)
++
++
++ xvld xr0, a1, 0
++ xvsetanyeqz.b fcc0, xr0
++ bcnez fcc0, L(al_end)
++L(al_loop):
++ xvst xr0, a2, 0
++
++ xvld xr0, a1, 32
++ addi.d a2, a2, 32
++ addi.d a1, a1, 32
++ xvsetanyeqz.b fcc0, xr0
++
++ bceqz fcc0, L(al_loop)
++L(al_end):
++ xvmsknz.b xr0, xr0
++ xvpickve.w xr1, xr0, 4
++ vilvl.h vr0, vr1, vr0
++
++ movfr2gr.s t0, fa0
++ cto.w t0, t0
++ add.d a1, a1, t0
++ xvld xr0, a1, -31
++
++
++ add.d dstend, a2, t0
++ xvst xr0, dstend, -31
++ jr ra
++ nop
++
++L(page_cross_start):
++ move a4, a1
++ bstrins.d a4, zero, 4, 0
++ xvld xr0, a4, 0
++ xvmsknz.b xr0, xr0
++
++ xvpickve.w xr1, xr0, 4
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++ sra.w t0, t0, a1
++
++ beq t0, t7, L(start_entry)
++ b L(tail)
++L(unaligned):
++ andi t0, a1, 0xfff
++ bltu t8, t0, L(un_page_cross)
++
++
++L(un_start_entry):
++ xvld xr0, a1, 0
++ xvsetanyeqz.b fcc0, xr0
++ bcnez fcc0, L(un_end)
++ addi.d a1, a1, 32
++
++L(un_loop):
++ xvst xr0, a2, 0
++ andi t0, a1, 0xfff
++ addi.d a2, a2, 32
++ bltu t8, t0, L(page_cross_loop)
++
++L(un_loop_entry):
++ xvld xr0, a1, 0
++ addi.d a1, a1, 32
++ xvsetanyeqz.b fcc0, xr0
++ bceqz fcc0, L(un_loop)
++
++ addi.d a1, a1, -32
++L(un_end):
++ xvmsknz.b xr0, xr0
++ xvpickve.w xr1, xr0, 4
++ vilvl.h vr0, vr1, vr0
++
++
++ movfr2gr.s t0, fa0
++L(un_tail):
++ cto.w t0, t0
++ add.d a1, a1, t0
++ xvld xr0, a1, -31
++
++ add.d dstend, a2, t0
++ xvst xr0, dstend, -31
++ jr ra
++L(un_page_cross):
++ sub.d a4, a1, a3
++
++ xvld xr0, a4, 0
++ xvmsknz.b xr0, xr0
++ xvpickve.w xr1, xr0, 4
++ vilvl.h vr0, vr1, vr0
++
++ movfr2gr.s t0, fa0
++ sra.w t0, t0, a1
++ beq t0, t7, L(un_start_entry)
++ b L(un_tail)
++
++
++L(page_cross_loop):
++ sub.d a4, a1, a3
++ xvld xr0, a4, 0
++ xvmsknz.b xr0, xr0
++ xvpickve.w xr1, xr0, 4
++
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++ sra.w t0, t0, a1
++ beq t0, t7, L(un_loop_entry)
++
++ b L(un_tail)
++L(end):
++ xvmsknz.b xr0, xr0
++ xvpickve.w xr1, xr0, 4
++ vilvl.h vr0, vr1, vr0
++
++ movfr2gr.s t0, fa0
++L(tail):
++ cto.w t0, t0
++ add.d dstend, a2, t0
++ add.d a5, a1, t0
++
++L(less_32):
++ srli.d t1, t0, 4
++ beqz t1, L(less_16)
++ vld vr0, a1, 0
++ vld vr1, a5, -15
++
++ vst vr0, a2, 0
++ vst vr1, dstend, -15
++ jr ra
++L(less_16):
++ srli.d t1, t0, 3
++
++ beqz t1, L(less_8)
++ ld.d t2, a1, 0
++ ld.d t3, a5, -7
++ st.d t2, a2, 0
++
++ st.d t3, dstend, -7
++ jr ra
++L(less_8):
++ li.d t1, 3
++ bltu t0, t1, L(less_3)
++
++ ld.w t2, a1, 0
++ ld.w t3, a5, -3
++ st.w t2, a2, 0
++ st.w t3, dstend, -3
++
++ jr ra
++L(less_3):
++ beqz t0, L(zero_byte)
++ ld.h t2, a1, 0
++
++ st.h t2, a2, 0
++L(zero_byte):
++ st.b zero, dstend, 0
++ jr ra
++END(STRCPY)
++
++libc_hidden_builtin_def (STRCPY)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S b/sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S
+new file mode 100644
+index 00000000..fc2498f7
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S
+@@ -0,0 +1,212 @@
++/* Optimized strcpy stpcpy implementation using LoongArch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# ifndef STRCPY
++# define STRCPY __strcpy_lsx
++# endif
++
++LEAF(STRCPY, 6)
++ pcalau12i t0, %pc_hi20(L(INDEX))
++ andi a4, a1, 0xf
++ vld vr1, t0, %pc_lo12(L(INDEX))
++ move a2, a0
++
++ beqz a4, L(load_start)
++ xor t0, a1, a4
++ vld vr0, t0, 0
++ vreplgr2vr.b vr2, a4
++
++ vadd.b vr2, vr2, vr1
++ vshuf.b vr0, vr2, vr0, vr2
++ vsetanyeqz.b fcc0, vr0
++ bcnez fcc0, L(end)
++
++L(load_start):
++ vld vr0, a1, 0
++ li.d t1, 16
++ andi a3, a2, 0xf
++ vsetanyeqz.b fcc0, vr0
++
++
++ sub.d t0, t1, a3
++ bcnez fcc0, L(end)
++ add.d a1, a1, t0
++ vst vr0, a2, 0
++
++ andi a3, a1, 0xf
++ add.d a2, a2, t0
++ bnez a3, L(unaligned)
++ vld vr0, a1, 0
++
++ vsetanyeqz.b fcc0, vr0
++ bcnez fcc0, L(al_end)
++L(al_loop):
++ vst vr0, a2, 0
++ vld vr0, a1, 16
++
++ addi.d a2, a2, 16
++ addi.d a1, a1, 16
++ vsetanyeqz.b fcc0, vr0
++ bceqz fcc0, L(al_loop)
++
++
++L(al_end):
++ vmsknz.b vr1, vr0
++ movfr2gr.s t0, fa1
++ cto.w t0, t0
++ add.d a1, a1, t0
++
++ vld vr0, a1, -15
++# ifdef USE_AS_STPCPY
++ add.d a0, a2, t0
++ vst vr0, a0, -15
++# else
++ add.d a2, a2, t0
++ vst vr0, a2, -15
++# endif
++ jr ra
++
++L(end):
++ vmsknz.b vr1, vr0
++ movfr2gr.s t0, fa1
++ cto.w t0, t0
++ addi.d t0, t0, 1
++
++L(end_16):
++ andi t1, t0, 16
++ beqz t1, L(end_8)
++ vst vr0, a2, 0
++# ifdef USE_AS_STPCPY
++ addi.d a0, a2, 15
++# endif
++ jr ra
++
++L(end_8):
++ andi t2, t0, 8
++ andi t3, t0, 4
++ andi t4, t0, 2
++ andi t5, t0, 1
++
++ beqz t2, L(end_4)
++ vstelm.d vr0, a2, 0, 0
++ addi.d a2, a2, 8
++ vbsrl.v vr0, vr0, 8
++
++L(end_4):
++ beqz t3, L(end_2)
++ vstelm.w vr0, a2, 0, 0
++ addi.d a2, a2, 4
++ vbsrl.v vr0, vr0, 4
++
++L(end_2):
++ beqz t4, L(end_1)
++ vstelm.h vr0, a2, 0, 0
++ addi.d a2, a2, 2
++ vbsrl.v vr0, vr0, 2
++
++
++L(end_1):
++ beqz t5, L(out)
++ vstelm.b vr0, a2, 0, 0
++ addi.d a2, a2, 1
++L(out):
++# ifdef USE_AS_STPCPY
++ addi.d a0, a2, -1
++# endif
++ jr ra
++
++ .align 4
++L(unaligned):
++ bstrins.d a1, zero, 3, 0
++ vld vr2, a1, 0
++ vreplgr2vr.b vr3, a3
++ vslt.b vr4, vr1, vr3
++
++ vor.v vr0, vr2, vr4
++ vsetanyeqz.b fcc0, vr0
++ bcnez fcc0, L(un_first_end)
++ vld vr0, a1, 16
++
++ vadd.b vr3, vr3, vr1
++ vshuf.b vr4, vr0, vr2, vr3
++ vsetanyeqz.b fcc0, vr0
++ bcnez fcc0, L(un_end)
++
++
++ vor.v vr2, vr0, vr0
++ addi.d a1, a1, 16
++L(un_loop):
++ vld vr0, a1, 16
++ vst vr4, a2, 0
++
++ addi.d a2, a2, 16
++ vshuf.b vr4, vr0, vr2, vr3
++ vsetanyeqz.b fcc0, vr0
++ bcnez fcc0, L(un_end)
++
++ vld vr2, a1, 32
++ vst vr4, a2, 0
++ addi.d a1, a1, 32
++ addi.d a2, a2, 16
++
++ vshuf.b vr4, vr2, vr0, vr3
++ vsetanyeqz.b fcc0, vr2
++ bceqz fcc0, L(un_loop)
++ vor.v vr0, vr2, vr2
++
++
++ addi.d a1, a1, -16
++L(un_end):
++ vsetanyeqz.b fcc0, vr4
++ bcnez fcc0, 1f
++ vst vr4, a2, 0
++
++1:
++ vmsknz.b vr1, vr0
++ movfr2gr.s t0, fa1
++ cto.w t0, t0
++ add.d a1, a1, t0
++
++ vld vr0, a1, 1
++ add.d a2, a2, t0
++ sub.d a2, a2, a3
++ vst vr0, a2, 1
++# ifdef USE_AS_STPCPY
++ addi.d a0, a2, 16
++# endif
++ jr ra
++L(un_first_end):
++ addi.d a2, a2, -16
++ addi.d a1, a1, -16
++ b 1b
++END(STRCPY)
++
++ .section .rodata.cst16,"M",@progbits,16
++ .align 4
++L(INDEX):
++ .dword 0x0706050403020100
++ .dword 0x0f0e0d0c0b0a0908
++
++libc_hidden_builtin_def (STRCPY)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcpy-unaligned.S b/sysdeps/loongarch/lp64/multiarch/strcpy-unaligned.S
+new file mode 100644
+index 00000000..9e31883b
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strcpy-unaligned.S
+@@ -0,0 +1,138 @@
++/* Optimized strcpy unaligned implementation using basic LoongArch
++ instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++
++# ifndef STRCPY
++# define STRCPY __strcpy_unaligned
++# endif
++
++# ifdef USE_AS_STPCPY
++# define dstend a0
++# else
++# define dstend a4
++# endif
++
++LEAF(STRCPY, 6)
++ lu12i.w t5, 0x01010
++ li.w t0, 0xff8
++ ori t5, t5, 0x101
++ andi t1, a1, 0xfff
++
++ bstrins.d t5, t5, 63, 32
++ move a2, a0
++ slli.d t6, t5, 7
++ bltu t0, t1, L(page_cross)
++
++L(start_entry):
++ ld.d t0, a1, 0
++ li.d t3, 8
++ andi a3, a1, 0x7
++ sub.d t1, t0, t5
++
++ andn t2, t6, t0
++ sub.d t3, t3, a3
++ and t1, t1, t2
++ bnez t1, L(end)
++
++
++ add.d a1, a1, t3
++ st.d t0, a2, 0
++ add.d a2, a2, t3
++ ld.d t0, a1, 0
++
++ sub.d t1, t0, t5
++ andn t2, t6, t0
++ and t1, t1, t2
++ bnez t1, L(long_end)
++
++L(loop):
++ st.d t0, a2, 0
++ ld.d t0, a1, 8
++ addi.d a2, a2, 8
++ addi.d a1, a1, 8
++
++ sub.d t1, t0, t5
++ andn t2, t6, t0
++ and t1, t1, t2
++ beqz t1, L(loop)
++
++
++L(long_end):
++ ctz.d t1, t1
++ srli.d t1, t1, 3
++ add.d a1, a1, t1
++ ld.d t0, a1, -7
++
++ add.d dstend, a2, t1
++ st.d t0, dstend, -7
++ jr ra
++ nop
++
++L(end):
++ ctz.d t1, t1
++ srli.d t1, t1, 3
++ add.d a3, a1, t1
++ add.d dstend, a2, t1
++
++L(less_8):
++ li.d t0, 3
++ bltu t1, t0, L(less_3)
++ ld.w t1, a1, 0
++ ld.w t2, a3, -3
++
++
++ st.w t1, a2, 0
++ st.w t2, dstend, -3
++ jr ra
++L(less_3):
++ beqz t1, L(zero_bytes)
++
++ ld.h t1, a1, 0
++ st.h t1, a2, 0
++L(zero_bytes):
++ st.b zero, dstend, 0
++ jr ra
++
++L(page_cross):
++ move a4, a1
++ bstrins.d a4, zero, 2, 0
++ ld.d t0, a4, 0
++ li.d t3, -1
++
++ slli.d t4, a1, 3
++ srl.d t3, t3, t4
++ srl.d t0, t0, t4
++ orn t0, t0, t3
++
++
++ sub.d t1, t0, t5
++ andn t2, t6, t0
++ and t1, t1, t2
++ beqz t1, L(start_entry)
++
++ b L(end)
++END(STRCPY)
++
++libc_hidden_builtin_def (STRCPY)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcpy.c b/sysdeps/loongarch/lp64/multiarch/strcpy.c
+new file mode 100644
+index 00000000..46afd068
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strcpy.c
+@@ -0,0 +1,35 @@
++/* Multiple versions of strcpy.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define strcpy __redirect_strcpy
++# include <string.h>
++# undef strcpy
++
++# define SYMBOL_NAME strcpy
++# include "ifunc-lasx.h"
++
++libc_ifunc_redirected (__redirect_strcpy, strcpy, IFUNC_SELECTOR ());
++
++# ifdef SHARED
++__hidden_ver1 (strcpy, __GI_strcpy, __redirect_strcpy)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strcpy);
++# endif
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-strncmp-aligned-lsx.patch b/LoongArch-Add-ifunc-support-for-strncmp-aligned-lsx.patch
new file mode 100644
index 0000000..0297fc3
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-strncmp-aligned-lsx.patch
@@ -0,0 +1,583 @@
+From 6f03da2d7ef218c0f78375cf706dada59c3fee63 Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Thu, 24 Aug 2023 16:50:19 +0800
+Subject: [PATCH 10/29] LoongArch: Add ifunc support for strncmp{aligned, lsx}
+
+Based on the glibc microbenchmark, only a few short inputs with this
+strncmp-aligned and strncmp-lsx implementation experience performance
+degradation, overall, strncmp-aligned could reduce the runtime 0%-10%
+for aligned comparision, 10%-25% for unaligend comparision, strncmp-lsx
+could reduce the runtime about 0%-60%.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 2 +
+ .../lp64/multiarch/ifunc-impl-list.c | 7 +
+ .../loongarch/lp64/multiarch/ifunc-strncmp.h | 38 +++
+ .../lp64/multiarch/strncmp-aligned.S | 218 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/strncmp-lsx.S | 208 +++++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/strncmp.c | 35 +++
+ 6 files changed, 508 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-strncmp.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strncmp.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index d5a500de..5d7ae7ae 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -14,6 +14,8 @@ sysdep_routines += \
+ strchrnul-lasx \
+ strcmp-aligned \
+ strcmp-lsx \
++ strncmp-aligned \
++ strncmp-lsx \
+ memcpy-aligned \
+ memcpy-unaligned \
+ memmove-unaligned \
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index 9183b7da..c8ba87bd 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -69,6 +69,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_aligned)
+ )
+
++ IFUNC_IMPL (i, name, strncmp,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, strncmp, SUPPORT_LSX, __strncmp_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_aligned)
++ )
++
+ IFUNC_IMPL (i, name, memcpy,
+ #if !defined __loongarch_soft_float
+ IFUNC_IMPL_ADD (array, i, memcpy, SUPPORT_LASX, __memcpy_lasx)
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-strncmp.h b/sysdeps/loongarch/lp64/multiarch/ifunc-strncmp.h
+new file mode 100644
+index 00000000..1a7dc36b
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-strncmp.h
+@@ -0,0 +1,38 @@
++/* Common definition for strncmp ifunc selection.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S b/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S
+new file mode 100644
+index 00000000..e2687fa7
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S
+@@ -0,0 +1,218 @@
++/* Optimized strncmp implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define STRNCMP __strncmp_aligned
++#else
++# define STRNCMP strncmp
++#endif
++
++LEAF(STRNCMP, 6)
++ beqz a2, L(ret0)
++ lu12i.w a5, 0x01010
++ andi a3, a0, 0x7
++ ori a5, a5, 0x101
++
++ andi a4, a1, 0x7
++ bstrins.d a5, a5, 63, 32
++ li.d t7, -1
++ li.d t8, 8
++
++ addi.d a2, a2, -1
++ slli.d a6, a5, 7
++ bne a3, a4, L(unaligned)
++ bstrins.d a0, zero, 2, 0
++
++ bstrins.d a1, zero, 2, 0
++ ld.d t0, a0, 0
++ ld.d t1, a1, 0
++ slli.d t2, a3, 3
++
++
++ sub.d t5, t8, a3
++ srl.d t3, t7, t2
++ srl.d t0, t0, t2
++ srl.d t1, t1, t2
++
++ orn t0, t0, t3
++ orn t1, t1, t3
++ sub.d t2, t0, a5
++ andn t3, a6, t0
++
++ and t2, t2, t3
++ bne t0, t1, L(al_end)
++ sltu t4, a2, t5
++ sub.d a2, a2, t5
++
++L(al_loop):
++ or t4, t2, t4
++ bnez t4, L(ret0)
++ ldx.d t0, a0, t8
++ ldx.d t1, a1, t8
++
++
++ addi.d t8, t8, 8
++ sltui t4, a2, 8
++ addi.d a2, a2, -8
++ sub.d t2, t0, a5
++
++ andn t3, a6, t0
++ and t2, t2, t3
++ beq t0, t1, L(al_loop)
++ addi.d a2, a2, 8
++
++L(al_end):
++ xor t3, t0, t1
++ or t2, t2, t3
++ ctz.d t2, t2
++ srli.d t4, t2, 3
++
++ bstrins.d t2, zero, 2, 0
++ srl.d t0, t0, t2
++ srl.d t1, t1, t2
++ andi t0, t0, 0xff
++
++
++ andi t1, t1, 0xff
++ sltu t2, a2, t4
++ sub.d a0, t0, t1
++ masknez a0, a0, t2
++
++ jr ra
++L(ret0):
++ move a0, zero
++ jr ra
++ nop
++
++L(unaligned):
++ slt a7, a4, a3
++ xor t0, a0, a1
++ maskeqz t0, t0, a7
++ xor a0, a0, t0
++
++ xor a1, a1, t0
++ andi a3, a0, 0x7
++ andi a4, a1, 0x7
++ bstrins.d a0, zero, 2, 0
++
++
++ bstrins.d a1, zero, 2, 0
++ ld.d t4, a0, 0
++ ld.d t1, a1, 0
++ slli.d t2, a3, 3
++
++ slli.d t3, a4, 3
++ srl.d t5, t7, t3
++ srl.d t0, t4, t2
++ srl.d t1, t1, t3
++
++ orn t0, t0, t5
++ orn t1, t1, t5
++ bne t0, t1, L(not_equal)
++ sub.d t6, t8, a4
++
++ sub.d a4, t2, t3
++ sll.d t2, t7, t2
++ sub.d t5, t8, a3
++ orn t4, t4, t2
++
++
++ sub.d t2, t4, a5
++ andn t3, a6, t4
++ sltu t7, a2, t5
++ and t2, t2, t3
++
++ sub.d a3, zero, a4
++ or t2, t2, t7
++ bnez t2, L(un_end)
++ sub.d t7, t5, t6
++
++ sub.d a2, a2, t5
++ sub.d t6, t8, t7
++L(un_loop):
++ srl.d t5, t4, a4
++ ldx.d t4, a0, t8
++
++ ldx.d t1, a1, t8
++ addi.d t8, t8, 8
++ sll.d t0, t4, a3
++ or t0, t0, t5
++
++
++ bne t0, t1, L(loop_not_equal)
++ sub.d t2, t4, a5
++ andn t3, a6, t4
++ sltui t5, a2, 8
++
++ and t2, t2, t3
++ addi.d a2, a2, -8
++ or t3, t2, t5
++ beqz t3, L(un_loop)
++
++ addi.d a2, a2, 8
++L(un_end):
++ sub.d t2, t0, a5
++ andn t3, a6, t0
++ sltu t5, a2, t6
++
++ and t2, t2, t3
++ or t2, t2, t5
++ bnez t2, L(ret0)
++ ldx.d t1, a1, t8
++
++
++ srl.d t0, t4, a4
++ sub.d a2, a2, t6
++L(not_equal):
++ sub.d t2, t0, a5
++ andn t3, a6, t0
++
++ xor t4, t0, t1
++ and t2, t2, t3
++ or t2, t2, t4
++ ctz.d t2, t2
++
++ bstrins.d t2, zero, 2, 0
++ srli.d t4, t2, 3
++ srl.d t0, t0, t2
++ srl.d t1, t1, t2
++
++ andi t0, t0, 0xff
++ andi t1, t1, 0xff
++ sub.d t2, t0, t1
++ sub.d t3, t1, t0
++
++
++ masknez t0, t2, a7
++ maskeqz t1, t3, a7
++ sltu t2, a2, t4
++ or a0, t0, t1
++
++ masknez a0, a0, t2
++ jr ra
++L(loop_not_equal):
++ add.d a2, a2, t7
++ b L(not_equal)
++END(STRNCMP)
++
++libc_hidden_builtin_def (STRNCMP)
+diff --git a/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S b/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S
+new file mode 100644
+index 00000000..0b4eee2a
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S
+@@ -0,0 +1,208 @@
++/* Optimized strncmp implementation using Loongarch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define STRNCMP __strncmp_lsx
++
++LEAF(STRNCMP, 6)
++ beqz a2, L(ret0)
++ pcalau12i t0, %pc_hi20(L(INDEX))
++ andi a3, a0, 0xf
++ vld vr2, t0, %pc_lo12(L(INDEX))
++
++ andi a4, a1, 0xf
++ li.d t2, 16
++ bne a3, a4, L(unaligned)
++ xor t0, a0, a3
++
++ xor t1, a1, a4
++ vld vr0, t0, 0
++ vld vr1, t1, 0
++ vreplgr2vr.b vr3, a3
++
++
++ sub.d t2, t2, a3
++ vadd.b vr3, vr3, vr2
++ vshuf.b vr0, vr3, vr0, vr3
++ vshuf.b vr1, vr3, vr1, vr3
++
++ vseq.b vr3, vr0, vr1
++ vmin.bu vr3, vr0, vr3
++ bgeu t2, a2, L(al_early_end)
++ vsetanyeqz.b fcc0, vr3
++
++ bcnez fcc0, L(al_end)
++ add.d a3, a0, a2
++ addi.d a4, a3, -1
++ bstrins.d a4, zero, 3, 0
++
++ sub.d a2, a3, a4
++L(al_loop):
++ vld vr0, t0, 16
++ vld vr1, t1, 16
++ addi.d t0, t0, 16
++
++
++ addi.d t1, t1, 16
++ vseq.b vr3, vr0, vr1
++ vmin.bu vr3, vr0, vr3
++ beq t0, a4, L(al_early_end)
++
++ vsetanyeqz.b fcc0, vr3
++ bceqz fcc0, L(al_loop)
++L(al_end):
++ vseqi.b vr3, vr3, 0
++ vfrstpi.b vr3, vr3, 0
++
++ vshuf.b vr0, vr0, vr0, vr3
++ vshuf.b vr1, vr1, vr1, vr3
++ vpickve2gr.bu t0, vr0, 0
++ vpickve2gr.bu t1, vr1, 0
++
++ sub.d a0, t0, t1
++ jr ra
++L(al_early_end):
++ vreplgr2vr.b vr4, a2
++ vslt.b vr4, vr2, vr4
++
++
++ vorn.v vr3, vr3, vr4
++ b L(al_end)
++L(unaligned):
++ slt a5, a3, a4
++ xor t0, a0, a1
++
++ maskeqz t0, t0, a5
++ xor a0, a0, t0
++ xor a1, a1, t0
++ andi a3, a0, 0xf
++
++ andi a4, a1, 0xf
++ xor t0, a0, a3
++ xor t1, a1, a4
++ vld vr0, t0, 0
++
++ vld vr3, t1, 0
++ sub.d t2, t2, a3
++ vreplgr2vr.b vr4, a3
++ vreplgr2vr.b vr5, a4
++
++
++ vaddi.bu vr6, vr2, 16
++ vsub.b vr7, vr4, vr5
++ vsub.b vr6, vr6, vr7
++ vadd.b vr4, vr2, vr4
++
++ vshuf.b vr1, vr3, vr3, vr6
++ vshuf.b vr0, vr7, vr0, vr4
++ vshuf.b vr1, vr7, vr1, vr4
++ vseq.b vr4, vr0, vr1
++
++ vmin.bu vr4, vr0, vr4
++ bgeu t2, a2, L(un_early_end)
++ vsetanyeqz.b fcc0, vr4
++ bcnez fcc0, L(un_end)
++
++ add.d a6, a0, a2
++ vslt.b vr5, vr2, vr5
++ addi.d a7, a6, -1
++ vor.v vr3, vr3, vr5
++
++
++ bstrins.d a7, zero, 3, 0
++ sub.d a2, a6, a7
++L(un_loop):
++ vld vr0, t0, 16
++ addi.d t0, t0, 16
++
++ vsetanyeqz.b fcc0, vr3
++ bcnez fcc0, L(has_zero)
++ beq t0, a7, L(end_with_len)
++ vor.v vr1, vr3, vr3
++
++ vld vr3, t1, 16
++ addi.d t1, t1, 16
++ vshuf.b vr1, vr3, vr1, vr6
++ vseq.b vr4, vr0, vr1
++
++ vmin.bu vr4, vr0, vr4
++ vsetanyeqz.b fcc0, vr4
++ bceqz fcc0, L(un_loop)
++L(un_end):
++ vseqi.b vr4, vr4, 0
++
++
++ vfrstpi.b vr4, vr4, 0
++ vshuf.b vr0, vr0, vr0, vr4
++ vshuf.b vr1, vr1, vr1, vr4
++ vpickve2gr.bu t0, vr0, 0
++
++ vpickve2gr.bu t1, vr1, 0
++ sub.d t2, t0, t1
++ sub.d t3, t1, t0
++ masknez t0, t2, a5
++
++ maskeqz t1, t3, a5
++ or a0, t0, t1
++ jr ra
++L(has_zero):
++ vshuf.b vr1, vr3, vr3, vr6
++
++ vseq.b vr4, vr0, vr1
++ vmin.bu vr4, vr0, vr4
++ bne t0, a7, L(un_end)
++L(un_early_end):
++ vreplgr2vr.b vr5, a2
++
++ vslt.b vr5, vr2, vr5
++ vorn.v vr4, vr4, vr5
++ b L(un_end)
++L(end_with_len):
++ sub.d a6, a3, a4
++
++ bgeu a6, a2, 1f
++ vld vr4, t1, 16
++1:
++ vshuf.b vr1, vr4, vr3, vr6
++ vseq.b vr4, vr0, vr1
++
++ vmin.bu vr4, vr0, vr4
++ vreplgr2vr.b vr5, a2
++ vslt.b vr5, vr2, vr5
++ vorn.v vr4, vr4, vr5
++
++ b L(un_end)
++L(ret0):
++ move a0, zero
++ jr ra
++END(STRNCMP)
++
++ .section .rodata.cst16,"M",@progbits,16
++ .align 4
++L(INDEX):
++ .dword 0x0706050403020100
++ .dword 0x0f0e0d0c0b0a0908
++
++libc_hidden_builtin_def (STRNCMP)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strncmp.c b/sysdeps/loongarch/lp64/multiarch/strncmp.c
+new file mode 100644
+index 00000000..af6d0bc4
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strncmp.c
+@@ -0,0 +1,35 @@
++/* Multiple versions of strncmp.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <http://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define strncmp __redirect_strncmp
++# include <string.h>
++# undef strncmp
++
++# define SYMBOL_NAME strncmp
++# include "ifunc-strncmp.h"
++
++libc_ifunc_redirected (__redirect_strncmp, strncmp, IFUNC_SELECTOR ());
++
++# ifdef SHARED
++__hidden_ver1 (strncmp, __GI_strncmp, __redirect_strncmp)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strncmp);
++# endif
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-strnlen-aligned-lsx-.patch b/LoongArch-Add-ifunc-support-for-strnlen-aligned-lsx-.patch
new file mode 100644
index 0000000..e6b4d91
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-strnlen-aligned-lsx-.patch
@@ -0,0 +1,465 @@
+From e494d32d3b76eee0d59cfab37789a356459b517a Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Thu, 24 Aug 2023 16:50:17 +0800
+Subject: [PATCH 08/29] LoongArch: Add ifunc support for strnlen{aligned, lsx,
+ lasx}
+
+Based on the glibc microbenchmark, strnlen-aligned implementation could
+reduce the runtime more than 10%, strnlen-lsx implementation could reduce
+the runtime about 50%-78%, strnlen-lasx implementation could reduce the
+runtime about 50%-88%.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 3 +
+ .../lp64/multiarch/ifunc-impl-list.c | 8 ++
+ .../loongarch/lp64/multiarch/ifunc-strnlen.h | 41 +++++++
+ .../lp64/multiarch/strnlen-aligned.S | 102 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/strnlen-lasx.S | 100 +++++++++++++++++
+ .../loongarch/lp64/multiarch/strnlen-lsx.S | 89 +++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/strnlen.c | 39 +++++++
+ 7 files changed, 382 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-strnlen.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strnlen.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index afa51041..c4dd3143 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -3,6 +3,9 @@ sysdep_routines += \
+ strlen-aligned \
+ strlen-lsx \
+ strlen-lasx \
++ strnlen-aligned \
++ strnlen-lsx \
++ strnlen-lasx \
+ strchr-aligned \
+ strchr-lsx \
+ strchr-lasx \
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index 25eb96b0..7cec0b77 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -38,6 +38,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_aligned)
+ )
+
++ IFUNC_IMPL (i, name, strnlen,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, strnlen, SUPPORT_LASX, __strnlen_lasx)
++ IFUNC_IMPL_ADD (array, i, strnlen, SUPPORT_LSX, __strnlen_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_aligned)
++ )
++
+ IFUNC_IMPL (i, name, strchr,
+ #if !defined __loongarch_soft_float
+ IFUNC_IMPL_ADD (array, i, strchr, SUPPORT_LASX, __strchr_lasx)
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-strnlen.h b/sysdeps/loongarch/lp64/multiarch/ifunc-strnlen.h
+new file mode 100644
+index 00000000..5cf89810
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-strnlen.h
+@@ -0,0 +1,41 @@
++/* Common definition for strnlen ifunc selections.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S b/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S
+new file mode 100644
+index 00000000..b900430a
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S
+@@ -0,0 +1,102 @@
++/* Optimized strnlen implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define STRNLEN __strnlen_aligned
++#else
++# define STRNLEN __strnlen
++#endif
++
++LEAF(STRNLEN, 6)
++ beqz a1, L(out)
++ lu12i.w a2, 0x01010
++ andi t1, a0, 0x7
++ move t4, a0
++
++ bstrins.d a0, zero, 2, 0
++ ori a2, a2, 0x101
++ li.w t0, -1
++ ld.d t2, a0, 0
++
++ slli.d t3, t1, 3
++ bstrins.d a2, a2, 63, 32
++ li.w t5, 8
++ slli.d a3, a2, 7
++
++ sub.w t1, t5, t1
++ sll.d t0, t0, t3
++ orn t2, t2, t0
++ sub.d t0, t2, a2
++
++
++ andn t3, a3, t2
++ and t0, t0, t3
++ bnez t0, L(count_pos)
++ sub.d t5, a1, t1
++
++ bgeu t1, a1, L(out)
++ addi.d a0, a0, 8
++L(loop):
++ ld.d t2, a0, 0
++ sub.d t0, t2, a2
++
++ andn t1, a3, t2
++ sltui t6, t5, 9
++ and t0, t0, t1
++ or t7, t0, t6
++
++ bnez t7, L(count_pos)
++ ld.d t2, a0, 8
++ addi.d a0, a0, 16
++ sub.d t0, t2, a2
++
++
++ andn t1, a3, t2
++ sltui t6, t5, 17
++ and t0, t0, t1
++ addi.d t5, t5, -16
++
++ or t7, t0, t6
++ beqz t7, L(loop)
++ addi.d a0, a0, -8
++L(count_pos):
++ ctz.d t1, t0
++
++ sub.d a0, a0, t4
++ srli.d t1, t1, 3
++ add.d a0, t1, a0
++ sltu t0, a0, a1
++
++ masknez t1, a1, t0
++ maskeqz a0, a0, t0
++ or a0, a0, t1
++ jr ra
++
++
++L(out):
++ move a0, a1
++ jr ra
++END(STRNLEN)
++
++weak_alias (STRNLEN, strnlen)
++libc_hidden_builtin_def (STRNLEN)
+diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S b/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S
+new file mode 100644
+index 00000000..2c03d3d9
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S
+@@ -0,0 +1,100 @@
++/* Optimized strnlen implementation using loongarch LASX instructions
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define STRNLEN __strnlen_lasx
++
++LEAF(STRNLEN, 6)
++ beqz a1, L(ret0)
++ andi t1, a0, 0x3f
++ li.d t3, 65
++ sub.d a2, a0, t1
++
++ xvld xr0, a2, 0
++ xvld xr1, a2, 32
++ sub.d t1, t3, t1
++ move a3, a0
++
++ sltu t1, a1, t1
++ xvmsknz.b xr0, xr0
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr2, xr0, 4
++
++ xvpickve.w xr3, xr1, 4
++ vilvl.h vr0, vr2, vr0
++ vilvl.h vr1, vr3, vr1
++ vilvl.w vr0, vr1, vr0
++
++
++ movfr2gr.d t0, fa0
++ sra.d t0, t0, a0
++ orn t1, t1, t0
++ bnez t1, L(end)
++
++ add.d a4, a0, a1
++ move a0, a2
++ addi.d a4, a4, -1
++ bstrins.d a4, zero, 5, 0
++
++L(loop):
++ xvld xr0, a0, 64
++ xvld xr1, a0, 96
++ addi.d a0, a0, 64
++ beq a0, a4, L(out)
++
++ xvmin.bu xr2, xr0, xr1
++ xvsetanyeqz.b fcc0, xr2
++ bceqz fcc0, L(loop)
++L(out):
++ xvmsknz.b xr0, xr0
++
++
++ xvmsknz.b xr1, xr1
++ xvpickve.w xr2, xr0, 4
++ xvpickve.w xr3, xr1, 4
++ vilvl.h vr0, vr2, vr0
++
++ vilvl.h vr1, vr3, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++L(end):
++ sub.d a0, a0, a3
++
++ cto.d t0, t0
++ add.d a0, a0, t0
++ sltu t1, a0, a1
++ masknez t0, a1, t1
++
++ maskeqz t1, a0, t1
++ or a0, t0, t1
++ jr ra
++L(ret0):
++ move a0, zero
++
++
++ jr ra
++END(STRNLEN)
++
++libc_hidden_def (STRNLEN)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S b/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S
+new file mode 100644
+index 00000000..b769a895
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S
+@@ -0,0 +1,89 @@
++/* Optimized strnlen implementation using loongarch LSX instructions
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define STRNLEN __strnlen_lsx
++
++LEAF(STRNLEN, 6)
++ beqz a1, L(ret0)
++ andi t1, a0, 0x1f
++ li.d t3, 33
++ sub.d a2, a0, t1
++
++ vld vr0, a2, 0
++ vld vr1, a2, 16
++ sub.d t1, t3, t1
++ move a3, a0
++
++ sltu t1, a1, t1
++ vmsknz.b vr0, vr0
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++
++ movfr2gr.s t0, fa0
++ sra.w t0, t0, a0
++ orn t1, t1, t0
++ bnez t1, L(end)
++
++
++ add.d a4, a0, a1
++ move a0, a2
++ addi.d a4, a4, -1
++ bstrins.d a4, zero, 4, 0
++
++L(loop):
++ vld vr0, a0, 32
++ vld vr1, a0, 48
++ addi.d a0, a0, 32
++ beq a0, a4, L(out)
++
++ vmin.bu vr2, vr0, vr1
++ vsetanyeqz.b fcc0, vr2
++ bceqz fcc0, L(loop)
++L(out):
++ vmsknz.b vr0, vr0
++
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++L(end):
++ sub.d a0, a0, a3
++
++
++ cto.w t0, t0
++ add.d a0, a0, t0
++ sltu t1, a0, a1
++ masknez t0, a1, t1
++
++ maskeqz t1, a0, t1
++ or a0, t0, t1
++ jr ra
++L(ret0):
++ move a0, zero
++
++ jr ra
++END(STRNLEN)
++
++libc_hidden_builtin_def (STRNLEN)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen.c b/sysdeps/loongarch/lp64/multiarch/strnlen.c
+new file mode 100644
+index 00000000..38b7a25a
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strnlen.c
+@@ -0,0 +1,39 @@
++/* Multiple versions of strnlen.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define strnlen __redirect_strnlen
++# define __strnlen __redirect___strnlen
++# include <string.h>
++# undef __strnlen
++# undef strnlen
++
++# define SYMBOL_NAME strnlen
++# include "ifunc-strnlen.h"
++
++libc_ifunc_redirected (__redirect_strnlen, __strnlen, IFUNC_SELECTOR ());
++weak_alias (__strnlen, strnlen);
++# ifdef SHARED
++__hidden_ver1 (__strnlen, __GI___strnlen, __redirect___strnlen)
++ __attribute__((visibility ("hidden"))) __attribute_copy__ (strnlen);
++__hidden_ver1 (strnlen, __GI_strnlen, __redirect_strnlen)
++ __attribute__((weak, visibility ("hidden"))) __attribute_copy__ (strnlen);
++# endif
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-ifunc-support-for-strrchr-aligned-lsx-.patch b/LoongArch-Add-ifunc-support-for-strrchr-aligned-lsx-.patch
new file mode 100644
index 0000000..63301f8
--- /dev/null
+++ b/LoongArch-Add-ifunc-support-for-strrchr-aligned-lsx-.patch
@@ -0,0 +1,670 @@
+From d537d0ab45a55048c8da483e73be4448ddb45525 Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Wed, 13 Sep 2023 15:35:00 +0800
+Subject: [PATCH 23/29] LoongArch: Add ifunc support for strrchr{aligned, lsx,
+ lasx}
+
+According to glibc strrchr microbenchmark test results, this implementation
+could reduce the runtime time as following:
+
+Name Percent of rutime reduced
+strrchr-lasx 10%-50%
+strrchr-lsx 0%-50%
+strrchr-aligned 5%-50%
+
+Generic strrchr is implemented by function strlen + memrchr, the lasx version
+will compare with generic strrchr implemented by strlen-lasx + memrchr-lasx,
+the lsx version will compare with generic strrchr implemented by strlen-lsx +
+memrchr-lsx, the aligned version will compare with generic strrchr implemented
+by strlen-aligned + memrchr-generic.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 3 +
+ .../lp64/multiarch/ifunc-impl-list.c | 8 +
+ .../loongarch/lp64/multiarch/ifunc-strrchr.h | 41 ++++
+ .../lp64/multiarch/strrchr-aligned.S | 170 +++++++++++++++++
+ .../loongarch/lp64/multiarch/strrchr-lasx.S | 176 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/strrchr-lsx.S | 144 ++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/strrchr.c | 36 ++++
+ 7 files changed, 578 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-strrchr.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strrchr-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strrchr-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strrchr-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strrchr.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index 39550bea..fe863e1b 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -9,6 +9,9 @@ sysdep_routines += \
+ strchr-aligned \
+ strchr-lsx \
+ strchr-lasx \
++ strrchr-aligned \
++ strrchr-lsx \
++ strrchr-lasx \
+ strchrnul-aligned \
+ strchrnul-lsx \
+ strchrnul-lasx \
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index 39a14f1d..529e2369 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -94,6 +94,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_aligned)
+ )
+
++ IFUNC_IMPL (i, name, strrchr,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, strrchr, SUPPORT_LASX, __strrchr_lasx)
++ IFUNC_IMPL_ADD (array, i, strrchr, SUPPORT_LSX, __strrchr_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_aligned)
++ )
++
+ IFUNC_IMPL (i, name, memcpy,
+ #if !defined __loongarch_soft_float
+ IFUNC_IMPL_ADD (array, i, memcpy, SUPPORT_LASX, __memcpy_lasx)
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-strrchr.h b/sysdeps/loongarch/lp64/multiarch/ifunc-strrchr.h
+new file mode 100644
+index 00000000..bbb34089
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-strrchr.h
+@@ -0,0 +1,41 @@
++/* Common definition for strrchr ifunc selections.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/strrchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/strrchr-aligned.S
+new file mode 100644
+index 00000000..a73deb78
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strrchr-aligned.S
+@@ -0,0 +1,170 @@
++/* Optimized strrchr implementation using basic LoongArch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define STRRCHR __strrchr_aligned
++#else
++# define STRRCHR strrchr
++#endif
++
++LEAF(STRRCHR, 6)
++ slli.d t0, a0, 3
++ bstrins.d a0, zero, 2, 0
++ lu12i.w a2, 0x01010
++ ld.d t2, a0, 0
++
++ andi a1, a1, 0xff
++ ori a2, a2, 0x101
++ li.d t3, -1
++ bstrins.d a2, a2, 63, 32
++
++ sll.d t5, t3, t0
++ slli.d a3, a2, 7
++ orn t4, t2, t5
++ mul.d a1, a1, a2
++
++ sub.d t0, t4, a2
++ andn t1, a3, t4
++ and t1, t0, t1
++ beqz t1, L(find_tail)
++
++
++ ctz.d t0, t1
++ orn t0, zero, t0
++ xor t2, t4, a1
++ srl.d t0, t3, t0
++
++ orn t2, t2, t0
++ orn t2, t2, t5
++ revb.d t2, t2
++ sub.d t1, t2, a2
++
++ andn t0, a3, t2
++ and t1, t0, t1
++ ctz.d t0, t1
++ srli.d t0, t0, 3
++
++ addi.d a0, a0, 7
++ sub.d a0, a0, t0
++ maskeqz a0, a0, t1
++ jr ra
++
++
++L(find_tail):
++ addi.d a4, a0, 8
++ addi.d a0, a0, 8
++L(loop_ascii):
++ ld.d t2, a0, 0
++ sub.d t1, t2, a2
++
++ and t0, t1, a3
++ bnez t0, L(more_check)
++ ld.d t2, a0, 8
++ sub.d t1, t2, a2
++
++ and t0, t1, a3
++ addi.d a0, a0, 16
++ beqz t0, L(loop_ascii)
++ addi.d a0, a0, -8
++
++L(more_check):
++ andn t0, a3, t2
++ and t1, t1, t0
++ bnez t1, L(tail)
++ addi.d a0, a0, 8
++
++
++L(loop_nonascii):
++ ld.d t2, a0, 0
++ sub.d t1, t2, a2
++ andn t0, a3, t2
++ and t1, t0, t1
++
++ bnez t1, L(tail)
++ ld.d t2, a0, 8
++ addi.d a0, a0, 16
++ sub.d t1, t2, a2
++
++ andn t0, a3, t2
++ and t1, t0, t1
++ beqz t1, L(loop_nonascii)
++ addi.d a0, a0, -8
++
++L(tail):
++ ctz.d t0, t1
++ orn t0, zero, t0
++ xor t2, t2, a1
++ srl.d t0, t3, t0
++
++
++ orn t2, t2, t0
++ revb.d t2, t2
++ sub.d t1, t2, a2
++ andn t0, a3, t2
++
++ and t1, t0, t1
++ bnez t1, L(count_pos)
++L(find_loop):
++ beq a0, a4, L(find_end)
++ ld.d t2, a0, -8
++
++ addi.d a0, a0, -8
++ xor t2, t2, a1
++ sub.d t1, t2, a2
++ andn t0, a3, t2
++
++ and t1, t0, t1
++ beqz t1, L(find_loop)
++ revb.d t2, t2
++ sub.d t1, t2, a2
++
++
++ andn t0, a3, t2
++ and t1, t0, t1
++L(count_pos):
++ ctz.d t0, t1
++ addi.d a0, a0, 7
++
++ srli.d t0, t0, 3
++ sub.d a0, a0, t0
++ jr ra
++ nop
++
++L(find_end):
++ xor t2, t4, a1
++ orn t2, t2, t5
++ revb.d t2, t2
++ sub.d t1, t2, a2
++
++
++ andn t0, a3, t2
++ and t1, t0, t1
++ ctz.d t0, t1
++ srli.d t0, t0, 3
++
++ addi.d a0, a4, -1
++ sub.d a0, a0, t0
++ maskeqz a0, a0, t1
++ jr ra
++END(STRRCHR)
++
++libc_hidden_builtin_def(STRRCHR)
+diff --git a/sysdeps/loongarch/lp64/multiarch/strrchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/strrchr-lasx.S
+new file mode 100644
+index 00000000..5a6e2297
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strrchr-lasx.S
+@@ -0,0 +1,176 @@
++/* Optimized strrchr implementation using LoongArch LASX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++#define STRRCHR __strrchr_lasx
++
++LEAF(STRRCHR, 6)
++ move a2, a0
++ bstrins.d a0, zero, 5, 0
++ xvld xr0, a0, 0
++ xvld xr1, a0, 32
++
++ li.d t2, -1
++ xvreplgr2vr.b xr4, a1
++ xvmsknz.b xr2, xr0
++ xvmsknz.b xr3, xr1
++
++ xvpickve.w xr5, xr2, 4
++ xvpickve.w xr6, xr3, 4
++ vilvl.h vr2, vr5, vr2
++ vilvl.h vr3, vr6, vr3
++
++ vilvl.w vr2, vr3, vr2
++ movfr2gr.d t0, fa2
++ sra.d t0, t0, a2
++ beq t0, t2, L(find_tail)
++
++
++ xvseq.b xr2, xr0, xr4
++ xvseq.b xr3, xr1, xr4
++ xvmsknz.b xr2, xr2
++ xvmsknz.b xr3, xr3
++
++ xvpickve.w xr4, xr2, 4
++ xvpickve.w xr5, xr3, 4
++ vilvl.h vr2, vr4, vr2
++ vilvl.h vr3, vr5, vr3
++
++ vilvl.w vr1, vr3, vr2
++ slli.d t3, t2, 1
++ movfr2gr.d t1, fa1
++ cto.d t0, t0
++
++ srl.d t1, t1, a2
++ sll.d t3, t3, t0
++ addi.d a0, a2, 63
++ andn t1, t1, t3
++
++
++ clz.d t0, t1
++ sub.d a0, a0, t0
++ maskeqz a0, a0, t1
++ jr ra
++
++ .align 5
++L(find_tail):
++ addi.d a3, a0, 64
++L(loop):
++ xvld xr2, a0, 64
++ xvld xr3, a0, 96
++ addi.d a0, a0, 64
++
++ xvmin.bu xr5, xr2, xr3
++ xvsetanyeqz.b fcc0, xr5
++ bceqz fcc0, L(loop)
++ xvmsknz.b xr5, xr2
++
++
++ xvmsknz.b xr6, xr3
++ xvpickve.w xr7, xr5, 4
++ xvpickve.w xr8, xr6, 4
++ vilvl.h vr5, vr7, vr5
++
++ vilvl.h vr6, vr8, vr6
++ xvseq.b xr2, xr2, xr4
++ xvseq.b xr3, xr3, xr4
++ xvmsknz.b xr2, xr2
++
++ xvmsknz.b xr3, xr3
++ xvpickve.w xr7, xr2, 4
++ xvpickve.w xr8, xr3, 4
++ vilvl.h vr2, vr7, vr2
++
++ vilvl.h vr3, vr8, vr3
++ vilvl.w vr5, vr6, vr5
++ vilvl.w vr2, vr3, vr2
++ movfr2gr.d t0, fa5
++
++
++ movfr2gr.d t1, fa2
++ slli.d t3, t2, 1
++ cto.d t0, t0
++ sll.d t3, t3, t0
++
++ andn t1, t1, t3
++ beqz t1, L(find_loop)
++ clz.d t0, t1
++ addi.d a0, a0, 63
++
++ sub.d a0, a0, t0
++ jr ra
++L(find_loop):
++ beq a0, a3, L(find_end)
++ xvld xr2, a0, -64
++
++ xvld xr3, a0, -32
++ addi.d a0, a0, -64
++ xvseq.b xr2, xr2, xr4
++ xvseq.b xr3, xr3, xr4
++
++
++ xvmax.bu xr5, xr2, xr3
++ xvseteqz.v fcc0, xr5
++ bcnez fcc0, L(find_loop)
++ xvmsknz.b xr0, xr2
++
++ xvmsknz.b xr1, xr3
++ xvpickve.w xr2, xr0, 4
++ xvpickve.w xr3, xr1, 4
++ vilvl.h vr0, vr2, vr0
++
++ vilvl.h vr1, vr3, vr1
++ vilvl.w vr0, vr1, vr0
++ movfr2gr.d t0, fa0
++ addi.d a0, a0, 63
++
++ clz.d t0, t0
++ sub.d a0, a0, t0
++ jr ra
++ nop
++
++
++L(find_end):
++ xvseq.b xr2, xr0, xr4
++ xvseq.b xr3, xr1, xr4
++ xvmsknz.b xr2, xr2
++ xvmsknz.b xr3, xr3
++
++ xvpickve.w xr4, xr2, 4
++ xvpickve.w xr5, xr3, 4
++ vilvl.h vr2, vr4, vr2
++ vilvl.h vr3, vr5, vr3
++
++ vilvl.w vr1, vr3, vr2
++ movfr2gr.d t1, fa1
++ addi.d a0, a2, 63
++ srl.d t1, t1, a2
++
++ clz.d t0, t1
++ sub.d a0, a0, t0
++ maskeqz a0, a0, t1
++ jr ra
++END(STRRCHR)
++
++libc_hidden_builtin_def(STRRCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strrchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/strrchr-lsx.S
+new file mode 100644
+index 00000000..8f2fd22e
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strrchr-lsx.S
+@@ -0,0 +1,144 @@
++/* Optimized strrchr implementation using LoongArch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++#define STRRCHR __strrchr_lsx
++
++LEAF(STRRCHR, 6)
++ move a2, a0
++ bstrins.d a0, zero, 4, 0
++ vld vr0, a0, 0
++ vld vr1, a0, 16
++
++ li.d t2, -1
++ vreplgr2vr.b vr4, a1
++ vmsknz.b vr2, vr0
++ vmsknz.b vr3, vr1
++
++ vilvl.h vr2, vr3, vr2
++ movfr2gr.s t0, fa2
++ sra.w t0, t0, a2
++ beq t0, t2, L(find_tail)
++
++ vseq.b vr2, vr0, vr4
++ vseq.b vr3, vr1, vr4
++ vmsknz.b vr2, vr2
++ vmsknz.b vr3, vr3
++
++
++ vilvl.h vr1, vr3, vr2
++ slli.d t3, t2, 1
++ movfr2gr.s t1, fa1
++ cto.w t0, t0
++
++ srl.w t1, t1, a2
++ sll.d t3, t3, t0
++ addi.d a0, a2, 31
++ andn t1, t1, t3
++
++ clz.w t0, t1
++ sub.d a0, a0, t0
++ maskeqz a0, a0, t1
++ jr ra
++
++ .align 5
++L(find_tail):
++ addi.d a3, a0, 32
++L(loop):
++ vld vr2, a0, 32
++ vld vr3, a0, 48
++ addi.d a0, a0, 32
++
++ vmin.bu vr5, vr2, vr3
++ vsetanyeqz.b fcc0, vr5
++ bceqz fcc0, L(loop)
++ vmsknz.b vr5, vr2
++
++ vmsknz.b vr6, vr3
++ vilvl.h vr5, vr6, vr5
++ vseq.b vr2, vr2, vr4
++ vseq.b vr3, vr3, vr4
++
++ vmsknz.b vr2, vr2
++ vmsknz.b vr3, vr3
++ vilvl.h vr2, vr3, vr2
++ movfr2gr.s t0, fa5
++
++
++ movfr2gr.s t1, fa2
++ slli.d t3, t2, 1
++ cto.w t0, t0
++ sll.d t3, t3, t0
++
++ andn t1, t1, t3
++ beqz t1, L(find_loop)
++ clz.w t0, t1
++ addi.d a0, a0, 31
++
++ sub.d a0, a0, t0
++ jr ra
++L(find_loop):
++ beq a0, a3, L(find_end)
++ vld vr2, a0, -32
++
++ vld vr3, a0, -16
++ addi.d a0, a0, -32
++ vseq.b vr2, vr2, vr4
++ vseq.b vr3, vr3, vr4
++
++
++ vmax.bu vr5, vr2, vr3
++ vseteqz.v fcc0, vr5
++ bcnez fcc0, L(find_loop)
++ vmsknz.b vr0, vr2
++
++ vmsknz.b vr1, vr3
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++ addi.d a0, a0, 31
++
++ clz.w t0, t0
++ sub.d a0, a0, t0
++ jr ra
++ nop
++
++L(find_end):
++ vseq.b vr2, vr0, vr4
++ vseq.b vr3, vr1, vr4
++ vmsknz.b vr2, vr2
++ vmsknz.b vr3, vr3
++
++
++ vilvl.h vr1, vr3, vr2
++ movfr2gr.s t1, fa1
++ addi.d a0, a2, 31
++ srl.w t1, t1, a2
++
++ clz.w t0, t1
++ sub.d a0, a0, t0
++ maskeqz a0, a0, t1
++ jr ra
++END(STRRCHR)
++
++libc_hidden_builtin_def(STRRCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strrchr.c b/sysdeps/loongarch/lp64/multiarch/strrchr.c
+new file mode 100644
+index 00000000..d9c9f660
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strrchr.c
+@@ -0,0 +1,36 @@
++/* Multiple versions of strrchr.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define strrchr __redirect_strrchr
++# include <string.h>
++# undef strrchr
++
++# define SYMBOL_NAME strrchr
++# include "ifunc-strrchr.h"
++
++libc_ifunc_redirected (__redirect_strrchr, strrchr, IFUNC_SELECTOR ());
++weak_alias (strrchr, rindex)
++# ifdef SHARED
++__hidden_ver1 (strrchr, __GI_strrchr, __redirect_strrchr)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strrchr);
++# endif
++
++#endif
+--
+2.33.0
+
diff --git a/LoongArch-Add-lasx-lsx-support-for-_dl_runtime_profi.patch b/LoongArch-Add-lasx-lsx-support-for-_dl_runtime_profi.patch
new file mode 100644
index 0000000..35acd20
--- /dev/null
+++ b/LoongArch-Add-lasx-lsx-support-for-_dl_runtime_profi.patch
@@ -0,0 +1,626 @@
+From b5979df8ad07823c79a934c1fa0a91ec0abffb61 Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Fri, 8 Sep 2023 14:10:55 +0800
+Subject: [PATCH 20/29] LoongArch: Add lasx/lsx support for
+ _dl_runtime_profile.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/bits/link.h | 24 ++-
+ sysdeps/loongarch/bits/link_lavcurrent.h | 25 +++
+ sysdeps/loongarch/dl-audit-check.h | 23 +++
+ sysdeps/loongarch/dl-link.sym | 8 +-
+ sysdeps/loongarch/dl-machine.h | 11 +-
+ sysdeps/loongarch/dl-trampoline.S | 177 +----------------
+ sysdeps/loongarch/dl-trampoline.h | 242 +++++++++++++++++++++++
+ 7 files changed, 331 insertions(+), 179 deletions(-)
+ create mode 100644 sysdeps/loongarch/bits/link_lavcurrent.h
+ create mode 100644 sysdeps/loongarch/dl-audit-check.h
+
+diff --git a/sysdeps/loongarch/bits/link.h b/sysdeps/loongarch/bits/link.h
+index 7fa61312..00f6f25f 100644
+--- a/sysdeps/loongarch/bits/link.h
++++ b/sysdeps/loongarch/bits/link.h
+@@ -20,10 +20,26 @@
+ #error "Never include <bits/link.h> directly; use <link.h> instead."
+ #endif
+
++#ifndef __loongarch_soft_float
++typedef float La_loongarch_vr
++ __attribute__ ((__vector_size__ (16), __aligned__ (16)));
++typedef float La_loongarch_xr
++ __attribute__ ((__vector_size__ (32), __aligned__ (16)));
++
++typedef union
++{
++ double fpreg[4];
++ La_loongarch_vr vr[2];
++ La_loongarch_xr xr[1];
++} La_loongarch_vector __attribute__ ((__aligned__ (16)));
++#endif
++
+ typedef struct La_loongarch_regs
+ {
+ unsigned long int lr_reg[8]; /* a0 - a7 */
+- double lr_fpreg[8]; /* fa0 - fa7 */
++#ifndef __loongarch_soft_float
++ La_loongarch_vector lr_vec[8]; /* fa0 - fa7 or vr0 - vr7 or xr0 - xr7*/
++#endif
+ unsigned long int lr_ra;
+ unsigned long int lr_sp;
+ } La_loongarch_regs;
+@@ -33,8 +49,10 @@ typedef struct La_loongarch_retval
+ {
+ unsigned long int lrv_a0;
+ unsigned long int lrv_a1;
+- double lrv_fa0;
+- double lrv_fa1;
++#ifndef __loongarch_soft_float
++ La_loongarch_vector lrv_vec0;
++ La_loongarch_vector lrv_vec1;
++#endif
+ } La_loongarch_retval;
+
+ __BEGIN_DECLS
+diff --git a/sysdeps/loongarch/bits/link_lavcurrent.h b/sysdeps/loongarch/bits/link_lavcurrent.h
+new file mode 100644
+index 00000000..15f1eb84
+--- /dev/null
++++ b/sysdeps/loongarch/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) 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
++ <https://www.gnu.org/licenses/>. */
++
++#ifndef _LINK_H
++# error "Never include <bits/link_lavcurrent.h> directly; use <link.h> instead."
++#endif
++
++/* Version numbers for la_version handshake interface. */
++#define LAV_CURRENT 3
+diff --git a/sysdeps/loongarch/dl-audit-check.h b/sysdeps/loongarch/dl-audit-check.h
+new file mode 100644
+index 00000000..a139c939
+--- /dev/null
++++ b/sysdeps/loongarch/dl-audit-check.h
+@@ -0,0 +1,23 @@
++/* rtld-audit version check. LoongArch version.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++static inline bool
++_dl_audit_check_version (unsigned int lav)
++{
++ return lav == LAV_CURRENT;
++}
+diff --git a/sysdeps/loongarch/dl-link.sym b/sysdeps/loongarch/dl-link.sym
+index 868ab7c6..b534968e 100644
+--- a/sysdeps/loongarch/dl-link.sym
++++ b/sysdeps/loongarch/dl-link.sym
+@@ -6,9 +6,13 @@ DL_SIZEOF_RG sizeof(struct La_loongarch_regs)
+ DL_SIZEOF_RV sizeof(struct La_loongarch_retval)
+
+ DL_OFFSET_RG_A0 offsetof(struct La_loongarch_regs, lr_reg)
+-DL_OFFSET_RG_FA0 offsetof(struct La_loongarch_regs, lr_fpreg)
++#ifndef __loongarch_soft_float
++DL_OFFSET_RG_VEC0 offsetof(struct La_loongarch_regs, lr_vec)
++#endif
+ DL_OFFSET_RG_RA offsetof(struct La_loongarch_regs, lr_ra)
+ DL_OFFSET_RG_SP offsetof(struct La_loongarch_regs, lr_sp)
+
+ DL_OFFSET_RV_A0 offsetof(struct La_loongarch_retval, lrv_a0)
+-DL_OFFSET_RV_FA0 offsetof(struct La_loongarch_retval, lrv_a1)
++#ifndef __loongarch_soft_float
++DL_OFFSET_RV_VEC0 offsetof(struct La_loongarch_retval, lrv_vec0)
++#endif
+diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
+index 066bb233..8a2db9de 100644
+--- a/sysdeps/loongarch/dl-machine.h
++++ b/sysdeps/loongarch/dl-machine.h
+@@ -273,6 +273,8 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+ #if !defined __loongarch_soft_float
+ extern void _dl_runtime_resolve_lasx (void) attribute_hidden;
+ extern void _dl_runtime_resolve_lsx (void) attribute_hidden;
++ extern void _dl_runtime_profile_lasx (void) attribute_hidden;
++ extern void _dl_runtime_profile_lsx (void) attribute_hidden;
+ #endif
+ extern void _dl_runtime_resolve (void) attribute_hidden;
+ extern void _dl_runtime_profile (void) attribute_hidden;
+@@ -287,7 +289,14 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+ end in this function. */
+ if (profile != 0)
+ {
+- gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile;
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile_lasx;
++ else if (SUPPORT_LSX)
++ gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile_lsx;
++ else
++#endif
++ gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile;
+
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+diff --git a/sysdeps/loongarch/dl-trampoline.S b/sysdeps/loongarch/dl-trampoline.S
+index 8fd91469..bb449ecf 100644
+--- a/sysdeps/loongarch/dl-trampoline.S
++++ b/sysdeps/loongarch/dl-trampoline.S
+@@ -22,190 +22,21 @@
+ #if !defined __loongarch_soft_float
+ #define USE_LASX
+ #define _dl_runtime_resolve _dl_runtime_resolve_lasx
++#define _dl_runtime_profile _dl_runtime_profile_lasx
+ #include "dl-trampoline.h"
+ #undef FRAME_SIZE
+ #undef USE_LASX
+ #undef _dl_runtime_resolve
++#undef _dl_runtime_profile
+
+ #define USE_LSX
+ #define _dl_runtime_resolve _dl_runtime_resolve_lsx
++#define _dl_runtime_profile _dl_runtime_profile_lsx
+ #include "dl-trampoline.h"
+ #undef FRAME_SIZE
+ #undef USE_LSX
+ #undef _dl_runtime_resolve
++#undef _dl_runtime_profile
+ #endif
+
+ #include "dl-trampoline.h"
+-
+-#include "dl-link.h"
+-
+-ENTRY (_dl_runtime_profile)
+- /* LoongArch we get called with:
+- t0 linkr_map pointer
+- t1 the scaled offset stored in t0, which can be used
+- to calculate the offset of the current symbol in .rela.plt
+- t2 %hi(%pcrel(.got.plt)) stored in t2, no use in this function
+- t3 dl resolver entry point, no use in this function
+-
+- Stack frame layout:
+- [sp, #96] La_loongarch_regs
+- [sp, #48] La_loongarch_retval
+- [sp, #40] frame size return from pltenter
+- [sp, #32] dl_profile_call saved a1
+- [sp, #24] dl_profile_call saved a0
+- [sp, #16] T1
+- [sp, #0] ra, fp <- fp
+- */
+-
+-# define OFFSET_T1 16
+-# define OFFSET_SAVED_CALL_A0 OFFSET_T1 + 8
+-# define OFFSET_FS OFFSET_SAVED_CALL_A0 + 16
+-# define OFFSET_RV OFFSET_FS + 8
+-# define OFFSET_RG OFFSET_RV + DL_SIZEOF_RV
+-
+-# define SF_SIZE (-(-(OFFSET_RG + DL_SIZEOF_RG) & ALMASK))
+-
+- /* Save arguments to stack. */
+- ADDI sp, sp, -SF_SIZE
+- REG_S ra, sp, 0
+- REG_S fp, sp, 8
+-
+- or fp, sp, zero
+-
+- REG_S a0, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 0*SZREG
+- REG_S a1, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 1*SZREG
+- REG_S a2, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 2*SZREG
+- REG_S a3, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 3*SZREG
+- REG_S a4, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 4*SZREG
+- REG_S a5, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 5*SZREG
+- REG_S a6, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 6*SZREG
+- REG_S a7, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 7*SZREG
+-
+-#ifndef __loongarch_soft_float
+- FREG_S fa0, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 0*SZFREG
+- FREG_S fa1, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 1*SZFREG
+- FREG_S fa2, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 2*SZFREG
+- FREG_S fa3, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 3*SZFREG
+- FREG_S fa4, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 4*SZFREG
+- FREG_S fa5, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 5*SZFREG
+- FREG_S fa6, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 6*SZFREG
+- FREG_S fa7, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 7*SZFREG
+-#endif
+-
+- /* Update .got.plt and obtain runtime address of callee. */
+- SLLI a1, t1, 1
+- or a0, t0, zero
+- ADD a1, a1, t1
+- or a2, ra, zero /* return addr */
+- ADDI a3, fp, OFFSET_RG /* La_loongarch_regs pointer */
+- ADDI a4, fp, OFFSET_FS /* frame size return from pltenter */
+-
+- REG_S a0, fp, OFFSET_SAVED_CALL_A0
+- REG_S a1, fp, OFFSET_SAVED_CALL_A0 + SZREG
+-
+- la t2, _dl_profile_fixup
+- jirl ra, t2, 0
+-
+- REG_L t3, fp, OFFSET_FS
+- bge t3, zero, 1f
+-
+- /* Save the return. */
+- or t4, v0, zero
+-
+- /* Restore arguments from stack. */
+- REG_L a0, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 0*SZREG
+- REG_L a1, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 1*SZREG
+- REG_L a2, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 2*SZREG
+- REG_L a3, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 3*SZREG
+- REG_L a4, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 4*SZREG
+- REG_L a5, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 5*SZREG
+- REG_L a6, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 6*SZREG
+- REG_L a7, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 7*SZREG
+-
+-#ifndef __loongarch_soft_float
+- FREG_L fa0, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 0*SZFREG
+- FREG_L fa1, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 1*SZFREG
+- FREG_L fa2, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 2*SZFREG
+- FREG_L fa3, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 3*SZFREG
+- FREG_L fa4, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 4*SZFREG
+- FREG_L fa5, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 5*SZFREG
+- FREG_L fa6, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 6*SZFREG
+- FREG_L fa7, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 7*SZFREG
+-#endif
+-
+- REG_L ra, fp, 0
+- REG_L fp, fp, SZREG
+-
+- ADDI sp, sp, SF_SIZE
+- jirl zero, t4, 0
+-
+-1:
+- /* The new frame size is in t3. */
+- SUB sp, fp, t3
+- BSTRINS sp, zero, 3, 0
+-
+- REG_S a0, fp, OFFSET_T1
+-
+- or a0, sp, zero
+- ADDI a1, fp, SF_SIZE
+- or a2, t3, zero
+- la t5, memcpy
+- jirl ra, t5, 0
+-
+- REG_L t6, fp, OFFSET_T1
+-
+- /* Call the function. */
+- REG_L a0, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 0*SZREG
+- REG_L a1, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 1*SZREG
+- REG_L a2, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 2*SZREG
+- REG_L a3, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 3*SZREG
+- REG_L a4, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 4*SZREG
+- REG_L a5, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 5*SZREG
+- REG_L a6, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 6*SZREG
+- REG_L a7, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 7*SZREG
+-
+-#ifndef __loongarch_soft_float
+- FREG_L fa0, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 0*SZFREG
+- FREG_L fa1, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 1*SZFREG
+- FREG_L fa2, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 2*SZFREG
+- FREG_L fa3, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 3*SZFREG
+- FREG_L fa4, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 4*SZFREG
+- FREG_L fa5, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 5*SZFREG
+- FREG_L fa6, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 6*SZFREG
+- FREG_L fa7, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 7*SZFREG
+-#endif
+- jirl ra, t6, 0
+-
+- REG_S a0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_A0
+- REG_S a1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_A0 + SZREG
+-
+-#ifndef __loongarch_soft_float
+- FREG_S fa0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_FA0
+- FREG_S fa1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_FA0 + SZFREG
+-#endif
+-
+- /* Setup call to pltexit. */
+- REG_L a0, fp, OFFSET_SAVED_CALL_A0
+- REG_L a1, fp, OFFSET_SAVED_CALL_A0 + SZREG
+- ADDI a2, fp, OFFSET_RG
+- ADDI a3, fp, OFFSET_RV
+- la t7, _dl_audit_pltexit
+- jirl ra, t7, 0
+-
+- REG_L a0, fp, OFFSET_RV + DL_OFFSET_RV_A0
+- REG_L a1, fp, OFFSET_RV + DL_OFFSET_RV_A0 + SZREG
+-
+-#ifndef __loongarch_soft_float
+- FREG_L fa0, fp, OFFSET_RV + DL_OFFSET_RV_FA0
+- FREG_L fa1, fp, OFFSET_RV + DL_OFFSET_RV_FA0 + SZFREG
+-#endif
+-
+- /* RA from within La_loongarch_reg. */
+- REG_L ra, fp, OFFSET_RG + DL_OFFSET_RG_RA
+- or sp, fp, zero
+- ADDI sp, sp, SF_SIZE
+- REG_S fp, fp, SZREG
+-
+- jirl zero, ra, 0
+-
+-END (_dl_runtime_profile)
+diff --git a/sysdeps/loongarch/dl-trampoline.h b/sysdeps/loongarch/dl-trampoline.h
+index 99fcacab..e298439d 100644
+--- a/sysdeps/loongarch/dl-trampoline.h
++++ b/sysdeps/loongarch/dl-trampoline.h
+@@ -125,3 +125,245 @@ ENTRY (_dl_runtime_resolve)
+ /* Invoke the callee. */
+ jirl zero, t1, 0
+ END (_dl_runtime_resolve)
++
++#include "dl-link.h"
++
++ENTRY (_dl_runtime_profile)
++ /* LoongArch we get called with:
++ t0 linkr_map pointer
++ t1 the scaled offset stored in t0, which can be used
++ to calculate the offset of the current symbol in .rela.plt
++ t2 %hi(%pcrel(.got.plt)) stored in t2, no use in this function
++ t3 dl resolver entry point, no use in this function
++
++ Stack frame layout:
++ [sp, #208] La_loongarch_regs
++ [sp, #128] La_loongarch_retval // align: 16
++ [sp, #112] frame size return from pltenter
++ [sp, #80 ] dl_profile_call saved vec1
++ [sp, #48 ] dl_profile_call saved vec0 // align: 16
++ [sp, #32 ] dl_profile_call saved a1
++ [sp, #24 ] dl_profile_call saved a0
++ [sp, #16 ] T1
++ [sp, #0 ] ra, fp <- fp
++ */
++
++# define OFFSET_T1 16
++# define OFFSET_SAVED_CALL_A0 OFFSET_T1 + 8
++# define OFFSET_FS OFFSET_SAVED_CALL_A0 + 16 + 8 + 64
++# define OFFSET_RV OFFSET_FS + 8 + 8
++# define OFFSET_RG OFFSET_RV + DL_SIZEOF_RV
++
++# define SF_SIZE (-(-(OFFSET_RG + DL_SIZEOF_RG) & ALMASK))
++
++ /* Save arguments to stack. */
++ ADDI sp, sp, -SF_SIZE
++ REG_S ra, sp, 0
++ REG_S fp, sp, 8
++
++ or fp, sp, zero
++
++ REG_S a0, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 0*SZREG
++ REG_S a1, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 1*SZREG
++ REG_S a2, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 2*SZREG
++ REG_S a3, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 3*SZREG
++ REG_S a4, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 4*SZREG
++ REG_S a5, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 5*SZREG
++ REG_S a6, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 6*SZREG
++ REG_S a7, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 7*SZREG
++
++#ifdef USE_LASX
++ xvst xr0, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 0*SZXREG
++ xvst xr1, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 1*SZXREG
++ xvst xr2, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 2*SZXREG
++ xvst xr3, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 3*SZXREG
++ xvst xr4, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 4*SZXREG
++ xvst xr5, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 5*SZXREG
++ xvst xr6, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 6*SZXREG
++ xvst xr7, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 7*SZXREG
++#elif defined USE_LSX
++ vst vr0, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 0*SZVREG
++ vst vr1, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 1*SZVREG
++ vst vr2, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 2*SZVREG
++ vst vr3, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 3*SZVREG
++ vst vr4, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 4*SZVREG
++ vst vr5, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 5*SZVREG
++ vst vr6, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 6*SZVREG
++ vst vr7, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 7*SZVREG
++#elif !defined __loongarch_soft_float
++ FREG_S fa0, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 0*SZFREG
++ FREG_S fa1, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 1*SZFREG
++ FREG_S fa2, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 2*SZFREG
++ FREG_S fa3, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 3*SZFREG
++ FREG_S fa4, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 4*SZFREG
++ FREG_S fa5, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 5*SZFREG
++ FREG_S fa6, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 6*SZFREG
++ FREG_S fa7, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 7*SZFREG
++#endif
++
++ /* Update .got.plt and obtain runtime address of callee. */
++ SLLI a1, t1, 1
++ or a0, t0, zero
++ ADD a1, a1, t1
++ or a2, ra, zero /* return addr */
++ ADDI a3, fp, OFFSET_RG /* La_loongarch_regs pointer */
++ ADDI a4, fp, OFFSET_FS /* frame size return from pltenter */
++
++ REG_S a0, fp, OFFSET_SAVED_CALL_A0
++ REG_S a1, fp, OFFSET_SAVED_CALL_A0 + SZREG
++
++ la t2, _dl_profile_fixup
++ jirl ra, t2, 0
++
++ REG_L t3, fp, OFFSET_FS
++ bge t3, zero, 1f
++
++ /* Save the return. */
++ or t4, v0, zero
++
++ /* Restore arguments from stack. */
++ REG_L a0, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 0*SZREG
++ REG_L a1, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 1*SZREG
++ REG_L a2, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 2*SZREG
++ REG_L a3, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 3*SZREG
++ REG_L a4, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 4*SZREG
++ REG_L a5, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 5*SZREG
++ REG_L a6, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 6*SZREG
++ REG_L a7, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 7*SZREG
++
++#ifdef USE_LASX
++ xvld xr0, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 0*SZXREG
++ xvld xr1, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 1*SZXREG
++ xvld xr2, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 2*SZXREG
++ xvld xr3, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 3*SZXREG
++ xvld xr4, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 4*SZXREG
++ xvld xr5, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 5*SZXREG
++ xvld xr6, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 6*SZXREG
++ xvld xr7, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 7*SZXREG
++#elif defined USE_LSX
++ vld vr0, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 0*SZVREG
++ vld vr1, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 1*SZVREG
++ vld vr2, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 2*SZVREG
++ vld vr3, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 3*SZVREG
++ vld vr4, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 4*SZVREG
++ vld vr5, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 5*SZVREG
++ vld vr6, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 6*SZVREG
++ vld vr7, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 7*SZVREG
++#elif !defined __loongarch_soft_float
++ FREG_L fa0, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 0*SZFREG
++ FREG_L fa1, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 1*SZFREG
++ FREG_L fa2, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 2*SZFREG
++ FREG_L fa3, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 3*SZFREG
++ FREG_L fa4, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 4*SZFREG
++ FREG_L fa5, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 5*SZFREG
++ FREG_L fa6, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 6*SZFREG
++ FREG_L fa7, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 7*SZFREG
++#endif
++
++ REG_L ra, fp, 0
++ REG_L fp, fp, SZREG
++
++ ADDI sp, sp, SF_SIZE
++ jirl zero, t4, 0
++
++1:
++ /* The new frame size is in t3. */
++ SUB sp, fp, t3
++ BSTRINS sp, zero, 3, 0
++
++ REG_S a0, fp, OFFSET_T1
++
++ or a0, sp, zero
++ ADDI a1, fp, SF_SIZE
++ or a2, t3, zero
++ la t5, memcpy
++ jirl ra, t5, 0
++
++ REG_L t6, fp, OFFSET_T1
++
++ /* Call the function. */
++ REG_L a0, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 0*SZREG
++ REG_L a1, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 1*SZREG
++ REG_L a2, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 2*SZREG
++ REG_L a3, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 3*SZREG
++ REG_L a4, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 4*SZREG
++ REG_L a5, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 5*SZREG
++ REG_L a6, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 6*SZREG
++ REG_L a7, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 7*SZREG
++
++#ifdef USE_LASX
++ xvld xr0, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 0*SZXREG
++ xvld xr1, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 1*SZXREG
++ xvld xr2, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 2*SZXREG
++ xvld xr3, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 3*SZXREG
++ xvld xr4, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 4*SZXREG
++ xvld xr5, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 5*SZXREG
++ xvld xr6, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 6*SZXREG
++ xvld xr7, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 7*SZXREG
++#elif defined USE_LSX
++ vld vr0, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 0*SZVREG
++ vld vr1, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 1*SZVREG
++ vld vr2, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 2*SZVREG
++ vld vr3, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 3*SZVREG
++ vld vr4, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 4*SZVREG
++ vld vr5, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 5*SZVREG
++ vld vr6, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 6*SZVREG
++ vld vr7, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 7*SZVREG
++#elif !defined __loongarch_soft_float
++ FREG_L fa0, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 0*SZFREG
++ FREG_L fa1, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 1*SZFREG
++ FREG_L fa2, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 2*SZFREG
++ FREG_L fa3, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 3*SZFREG
++ FREG_L fa4, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 4*SZFREG
++ FREG_L fa5, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 5*SZFREG
++ FREG_L fa6, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 6*SZFREG
++ FREG_L fa7, fp, OFFSET_RG + DL_OFFSET_RG_VEC0 + 7*SZFREG
++#endif
++
++ jirl ra, t6, 0
++
++ REG_S a0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_A0
++ REG_S a1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_A0 + SZREG
++
++#ifdef USE_LASX
++ xvst xr0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0
++ xvst xr1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0 + SZXREG
++#elif defined USE_LSX
++ vst vr0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0
++ vst vr1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0 + SZVREG
++#elif !defined __loongarch_soft_float
++ FREG_S fa0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0
++ FREG_S fa1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0 + SZFREG
++#endif
++
++ /* Setup call to pltexit. */
++ REG_L a0, fp, OFFSET_SAVED_CALL_A0
++ REG_L a1, fp, OFFSET_SAVED_CALL_A0 + SZREG
++ ADDI a2, fp, OFFSET_RG
++ ADDI a3, fp, OFFSET_RV
++ la t7, _dl_audit_pltexit
++ jirl ra, t7, 0
++
++ REG_L a0, fp, OFFSET_RV + DL_OFFSET_RV_A0
++ REG_L a1, fp, OFFSET_RV + DL_OFFSET_RV_A0 + SZREG
++
++#ifdef USE_LASX
++ xvld xr0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0
++ xvld xr1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0 + SZXREG
++#elif defined USE_LSX
++ vld vr0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0
++ vld vr1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0 + SZVREG
++#elif !defined __loongarch_soft_float
++ FREG_L fa0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0
++ FREG_L fa1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_VEC0 + SZFREG
++#endif
++
++ /* RA from within La_loongarch_reg. */
++ REG_L ra, fp, OFFSET_RG + DL_OFFSET_RG_RA
++ or sp, fp, zero
++ ADDI sp, sp, SF_SIZE
++ REG_S fp, fp, SZREG
++
++ jirl zero, ra, 0
++
++END (_dl_runtime_profile)
+--
+2.33.0
+
diff --git a/LoongArch-Add-minuimum-binutils-required-version.patch b/LoongArch-Add-minuimum-binutils-required-version.patch
new file mode 100644
index 0000000..9bdcf22
--- /dev/null
+++ b/LoongArch-Add-minuimum-binutils-required-version.patch
@@ -0,0 +1,102 @@
+From 7353f21f6ed1754b67e455e2b80123787efa9e91 Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Tue, 8 Aug 2023 14:15:43 +0800
+Subject: [PATCH 02/29] LoongArch: Add minuimum binutils required version
+
+LoongArch glibc can add some LASX/LSX vector instructions codes,
+change the required minimum binutils version to 2.41 which could
+support vector instructions. HAVE_LOONGARCH_VEC_ASM is removed
+accordingly.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ config.h.in | 5 -----
+ sysdeps/loongarch/configure | 5 ++---
+ sysdeps/loongarch/configure.ac | 4 ++--
+ sysdeps/loongarch/dl-machine.h | 4 ++--
+ sysdeps/loongarch/dl-trampoline.S | 2 +-
+ 5 files changed, 7 insertions(+), 13 deletions(-)
+
+diff --git a/config.h.in b/config.h.in
+index 0dedc124..44a34072 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -141,11 +141,6 @@
+ /* LOONGARCH floating-point ABI for ld.so. */
+ #undef LOONGARCH_ABI_FRLEN
+
+-/* Assembler support LoongArch LASX/LSX vector instructions.
+- This macro becomes obsolete when glibc increased the minimum
+- required version of GNU 'binutils' to 2.41 or later. */
+-#define HAVE_LOONGARCH_VEC_ASM 0
+-
+ /* Linux specific: minimum supported kernel version. */
+ #undef __LINUX_KERNEL_VERSION
+
+diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure
+index 5843c7cf..395ddc92 100644
+--- a/sysdeps/loongarch/configure
++++ b/sysdeps/loongarch/configure
+@@ -128,8 +128,7 @@ rm -f conftest*
+ fi
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_loongarch_vec_asm" >&5
+ printf "%s\n" "$libc_cv_loongarch_vec_asm" >&6; }
+-if test $libc_cv_loongarch_vec_asm = yes; then
+- printf "%s\n" "#define HAVE_LOONGARCH_VEC_ASM 1" >>confdefs.h
+-
++if test $libc_cv_loongarch_vec_asm = no; then
++ as_fn_error $? "binutils version is too old, use 2.41 or newer version" "$LINENO" 5
+ fi
+
+diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac
+index ba89d834..989287c6 100644
+--- a/sysdeps/loongarch/configure.ac
++++ b/sysdeps/loongarch/configure.ac
+@@ -74,6 +74,6 @@ else
+ libc_cv_loongarch_vec_asm=no
+ fi
+ rm -f conftest*])
+-if test $libc_cv_loongarch_vec_asm = yes; then
+- AC_DEFINE(HAVE_LOONGARCH_VEC_ASM)
++if test $libc_cv_loongarch_vec_asm = no; then
++ AC_MSG_ERROR([binutils version is too old, use 2.41 or newer version])
+ fi
+diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
+index 51ce9af8..066bb233 100644
+--- a/sysdeps/loongarch/dl-machine.h
++++ b/sysdeps/loongarch/dl-machine.h
+@@ -270,7 +270,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+ /* If using PLTs, fill in the first two entries of .got.plt. */
+ if (l->l_info[DT_JMPREL])
+ {
+-#if HAVE_LOONGARCH_VEC_ASM && !defined __loongarch_soft_float
++#if !defined __loongarch_soft_float
+ extern void _dl_runtime_resolve_lasx (void) attribute_hidden;
+ extern void _dl_runtime_resolve_lsx (void) attribute_hidden;
+ #endif
+@@ -300,7 +300,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+ /* This function will get called to fix up the GOT entry
+ indicated by the offset on the stack, and then jump to
+ the resolved address. */
+-#if HAVE_LOONGARCH_VEC_ASM && !defined __loongarch_soft_float
++#if !defined __loongarch_soft_float
+ if (SUPPORT_LASX)
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve_lasx;
+ else if (SUPPORT_LSX)
+diff --git a/sysdeps/loongarch/dl-trampoline.S b/sysdeps/loongarch/dl-trampoline.S
+index f6ba5e44..8fd91469 100644
+--- a/sysdeps/loongarch/dl-trampoline.S
++++ b/sysdeps/loongarch/dl-trampoline.S
+@@ -19,7 +19,7 @@
+ #include <sysdep.h>
+ #include <sys/asm.h>
+
+-#if HAVE_LOONGARCH_VEC_ASM && !defined __loongarch_soft_float
++#if !defined __loongarch_soft_float
+ #define USE_LASX
+ #define _dl_runtime_resolve _dl_runtime_resolve_lasx
+ #include "dl-trampoline.h"
+--
+2.33.0
+
diff --git a/LoongArch-Change-loongarch-to-LoongArch-in-comments.patch b/LoongArch-Change-loongarch-to-LoongArch-in-comments.patch
new file mode 100644
index 0000000..1f7bff6
--- /dev/null
+++ b/LoongArch-Change-loongarch-to-LoongArch-in-comments.patch
@@ -0,0 +1,277 @@
+From e5ccd79e81de7ad5821fde83875973e878d85d4b Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Mon, 28 Aug 2023 10:08:40 +0800
+Subject: [PATCH 19/29] LoongArch: Change loongarch to LoongArch in comments
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/memmove-aligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/memmove-lasx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/memmove-lsx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strchr-aligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strchr-lasx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strchr-lsx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strlen-aligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strlen-lasx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strlen-lsx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S | 2 +-
+ sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S | 2 +-
+ 24 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S b/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S
+index 299dd49c..7eb34395 100644
+--- a/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized memcpy_aligned implementation using basic Loongarch instructions.
++/* Optimized memcpy_aligned implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S b/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S
+index 4aae5bf8..ae148df5 100644
+--- a/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S
++++ b/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S
+@@ -1,4 +1,4 @@
+-/* Optimized memcpy implementation using Loongarch LASX instructions.
++/* Optimized memcpy implementation using LoongArch LASX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S b/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S
+index 6ebbe7a2..feb2bb0e 100644
+--- a/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S
++++ b/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S
+@@ -1,4 +1,4 @@
+-/* Optimized memcpy implementation using Loongarch LSX instructions.
++/* Optimized memcpy implementation using LoongArch LSX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S b/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S
+index 8e60a22d..31019b13 100644
+--- a/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized unaligned memcpy implementation using basic Loongarch instructions.
++/* Optimized unaligned memcpy implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S b/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S
+index 5354f383..a02114c0 100644
+--- a/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized memmove_aligned implementation using basic Loongarch instructions.
++/* Optimized memmove_aligned implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S b/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S
+index ff68e7a2..95d8ee7b 100644
+--- a/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S
++++ b/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S
+@@ -1,4 +1,4 @@
+-/* Optimized memmove implementation using Loongarch LASX instructions.
++/* Optimized memmove implementation using LoongArch LASX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S b/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
+index 9e1502a7..8a936770 100644
+--- a/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
++++ b/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
+@@ -1,4 +1,4 @@
+-/* Optimized memmove implementation using Loongarch LSX instructions.
++/* Optimized memmove implementation using LoongArch LSX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S b/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S
+index 90a64b6b..3284ce25 100644
+--- a/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized memmove_unaligned implementation using basic Loongarch instructions.
++/* Optimized memmove_unaligned implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S
+index 5fb01806..62020054 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized strchr implementation using basic Loongarch instructions.
++/* Optimized strchr implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S
+index 254402da..4d3cc588 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strchr implementation using loongarch LASX SIMD instructions.
++/* Optimized strchr implementation using LoongArch LASX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S
+index dae98b0a..8b78c35c 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strlen implementation using loongarch LSX SIMD instructions.
++/* Optimized strlen implementation using LoongArch LSX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S
+index 1c01a023..20856a06 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized strchrnul implementation using basic Loongarch instructions.
++/* Optimized strchrnul implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S
+index d45495e4..4753d4ce 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strchrnul implementation using loongarch LASX SIMD instructions.
++/* Optimized strchrnul implementation using LoongArch LASX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S
+index 07d793ae..671e740c 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strchrnul implementation using loongarch LSX SIMD instructions.
++/* Optimized strchrnul implementation using LoongArch LSX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S b/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S
+index f5f4f336..ba1f9667 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized strcmp implementation using basic Loongarch instructions.
++/* Optimized strcmp implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S b/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S
+index 2e177a38..091c8c9e 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strcmp implementation using Loongarch LSX instructions.
++/* Optimized strcmp implementation using LoongArch LSX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S b/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S
+index e9e1d2fc..ed0548e4 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized strlen implementation using basic Loongarch instructions.
++/* Optimized strlen implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S b/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S
+index 258c47ce..91342f34 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strlen implementation using loongarch LASX SIMD instructions.
++/* Optimized strlen implementation using LoongArch LASX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S b/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S
+index b194355e..b09c12e0 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strlen implementation using Loongarch LSX SIMD instructions.
++/* Optimized strlen implementation using LoongArch LSX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S b/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S
+index e2687fa7..f63de872 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized strncmp implementation using basic Loongarch instructions.
++/* Optimized strncmp implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S b/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S
+index 0b4eee2a..83cb801d 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strncmp implementation using Loongarch LSX instructions.
++/* Optimized strncmp implementation using LoongArch LSX instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S b/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S
+index b900430a..a8296a1b 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S
++++ b/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S
+@@ -1,4 +1,4 @@
+-/* Optimized strnlen implementation using basic Loongarch instructions.
++/* Optimized strnlen implementation using basic LoongArch instructions.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S b/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S
+index 2c03d3d9..aa6c812d 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strnlen implementation using loongarch LASX instructions
++/* Optimized strnlen implementation using LoongArch LASX instructions
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S b/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S
+index b769a895..d0febe3e 100644
+--- a/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S
++++ b/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S
+@@ -1,4 +1,4 @@
+-/* Optimized strnlen implementation using loongarch LSX instructions
++/* Optimized strnlen implementation using LoongArch LSX instructions
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+--
+2.33.0
+
diff --git a/LoongArch-Change-to-put-magic-number-to-.rodata-sect.patch b/LoongArch-Change-to-put-magic-number-to-.rodata-sect.patch
new file mode 100644
index 0000000..896eb1f
--- /dev/null
+++ b/LoongArch-Change-to-put-magic-number-to-.rodata-sect.patch
@@ -0,0 +1,67 @@
+From fb72c81f9894b23797f6e2e066532c0963f5155f Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Wed, 13 Sep 2023 15:35:01 +0800
+Subject: [PATCH 24/29] LoongArch: Change to put magic number to .rodata
+ section
+
+Change to put magic number to .rodata section in memmove-lsx, and use
+pcalau12i and %pc_lo12 with vld to get the data.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ .../loongarch/lp64/multiarch/memmove-lsx.S | 20 +++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S b/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
+index 8a936770..5eb819ef 100644
+--- a/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
++++ b/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
+@@ -209,13 +209,10 @@ L(al_less_16):
+ nop
+
+
+-L(magic_num):
+- .dword 0x0706050403020100
+- .dword 0x0f0e0d0c0b0a0908
+ L(unaligned):
+- pcaddi t2, -4
++ pcalau12i t2, %pc_hi20(L(INDEX))
+ bstrins.d a1, zero, 3, 0
+- vld vr8, t2, 0
++ vld vr8, t2, %pc_lo12(L(INDEX))
+ vld vr0, a1, 0
+
+ vld vr1, a1, 16
+@@ -413,13 +410,10 @@ L(back_al_less_16):
+ vst vr1, a0, 0
+ jr ra
+
+-L(magic_num_2):
+- .dword 0x0706050403020100
+- .dword 0x0f0e0d0c0b0a0908
+ L(back_unaligned):
+- pcaddi t2, -4
++ pcalau12i t2, %pc_hi20(L(INDEX))
+ bstrins.d a4, zero, 3, 0
+- vld vr8, t2, 0
++ vld vr8, t2, %pc_lo12(L(INDEX))
+ vld vr0, a4, 0
+
+ vld vr1, a4, -16
+@@ -529,6 +523,12 @@ L(back_un_less_16):
+ jr ra
+ END(MEMMOVE_NAME)
+
++ .section .rodata.cst16,"M",@progbits,16
++ .align 4
++L(INDEX):
++ .dword 0x0706050403020100
++ .dword 0x0f0e0d0c0b0a0908
++
+ libc_hidden_builtin_def (MEMCPY_NAME)
+ libc_hidden_builtin_def (MEMMOVE_NAME)
+ #endif
+--
+2.33.0
+
diff --git a/LoongArch-Delete-excessively-allocated-memory.patch b/LoongArch-Delete-excessively-allocated-memory.patch
new file mode 100644
index 0000000..f7d36a6
--- /dev/null
+++ b/LoongArch-Delete-excessively-allocated-memory.patch
@@ -0,0 +1,109 @@
+From 44f757a6364a546359809d48c76b3debd26e77d4 Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Thu, 26 Oct 2023 17:27:21 +0800
+Subject: [PATCH 1/9] LoongArch: Delete excessively allocated memory.
+
+Backported from glibc 2.39 development.
+---
+ sysdeps/loongarch/dl-trampoline.h | 68 +++++++++++++++----------------
+ 1 file changed, 34 insertions(+), 34 deletions(-)
+
+diff --git a/sysdeps/loongarch/dl-trampoline.h b/sysdeps/loongarch/dl-trampoline.h
+index 02375286f8..99fcacab76 100644
+--- a/sysdeps/loongarch/dl-trampoline.h
++++ b/sysdeps/loongarch/dl-trampoline.h
+@@ -19,9 +19,9 @@
+ /* Assembler veneer called from the PLT header code for lazy loading.
+ The PLT header passes its own args in t0-t2. */
+ #ifdef USE_LASX
+-# define FRAME_SIZE (-((-9 * SZREG - 8 * SZFREG - 8 * SZXREG) & ALMASK))
++# define FRAME_SIZE (-((-9 * SZREG - 8 * SZXREG) & ALMASK))
+ #elif defined USE_LSX
+-# define FRAME_SIZE (-((-9 * SZREG - 8 * SZFREG - 8 * SZVREG) & ALMASK))
++# define FRAME_SIZE (-((-9 * SZREG - 8 * SZVREG) & ALMASK))
+ #elif !defined __loongarch_soft_float
+ # define FRAME_SIZE (-((-9 * SZREG - 8 * SZFREG) & ALMASK))
+ #else
+@@ -44,23 +44,23 @@ ENTRY (_dl_runtime_resolve)
+ REG_S a7, sp, 8*SZREG
+
+ #ifdef USE_LASX
+- xvst xr0, sp, 9*SZREG + 8*SZFREG + 0*SZXREG
+- xvst xr1, sp, 9*SZREG + 8*SZFREG + 1*SZXREG
+- xvst xr2, sp, 9*SZREG + 8*SZFREG + 2*SZXREG
+- xvst xr3, sp, 9*SZREG + 8*SZFREG + 3*SZXREG
+- xvst xr4, sp, 9*SZREG + 8*SZFREG + 4*SZXREG
+- xvst xr5, sp, 9*SZREG + 8*SZFREG + 5*SZXREG
+- xvst xr6, sp, 9*SZREG + 8*SZFREG + 6*SZXREG
+- xvst xr7, sp, 9*SZREG + 8*SZFREG + 7*SZXREG
++ xvst xr0, sp, 9*SZREG + 0*SZXREG
++ xvst xr1, sp, 9*SZREG + 1*SZXREG
++ xvst xr2, sp, 9*SZREG + 2*SZXREG
++ xvst xr3, sp, 9*SZREG + 3*SZXREG
++ xvst xr4, sp, 9*SZREG + 4*SZXREG
++ xvst xr5, sp, 9*SZREG + 5*SZXREG
++ xvst xr6, sp, 9*SZREG + 6*SZXREG
++ xvst xr7, sp, 9*SZREG + 7*SZXREG
+ #elif defined USE_LSX
+- vst vr0, sp, 9*SZREG + 8*SZFREG + 0*SZVREG
+- vst vr1, sp, 9*SZREG + 8*SZFREG + 1*SZVREG
+- vst vr2, sp, 9*SZREG + 8*SZFREG + 2*SZVREG
+- vst vr3, sp, 9*SZREG + 8*SZFREG + 3*SZVREG
+- vst vr4, sp, 9*SZREG + 8*SZFREG + 4*SZVREG
+- vst vr5, sp, 9*SZREG + 8*SZFREG + 5*SZVREG
+- vst vr6, sp, 9*SZREG + 8*SZFREG + 6*SZVREG
+- vst vr7, sp, 9*SZREG + 8*SZFREG + 7*SZVREG
++ vst vr0, sp, 9*SZREG + 0*SZVREG
++ vst vr1, sp, 9*SZREG + 1*SZVREG
++ vst vr2, sp, 9*SZREG + 2*SZVREG
++ vst vr3, sp, 9*SZREG + 3*SZVREG
++ vst vr4, sp, 9*SZREG + 4*SZVREG
++ vst vr5, sp, 9*SZREG + 5*SZVREG
++ vst vr6, sp, 9*SZREG + 6*SZVREG
++ vst vr7, sp, 9*SZREG + 7*SZVREG
+ #elif !defined __loongarch_soft_float
+ FREG_S fa0, sp, 9*SZREG + 0*SZFREG
+ FREG_S fa1, sp, 9*SZREG + 1*SZFREG
+@@ -92,23 +92,23 @@ ENTRY (_dl_runtime_resolve)
+ REG_L a7, sp, 8*SZREG
+
+ #ifdef USE_LASX
+- xvld xr0, sp, 9*SZREG + 8*SZFREG + 0*SZXREG
+- xvld xr1, sp, 9*SZREG + 8*SZFREG + 1*SZXREG
+- xvld xr2, sp, 9*SZREG + 8*SZFREG + 2*SZXREG
+- xvld xr3, sp, 9*SZREG + 8*SZFREG + 3*SZXREG
+- xvld xr4, sp, 9*SZREG + 8*SZFREG + 4*SZXREG
+- xvld xr5, sp, 9*SZREG + 8*SZFREG + 5*SZXREG
+- xvld xr6, sp, 9*SZREG + 8*SZFREG + 6*SZXREG
+- xvld xr7, sp, 9*SZREG + 8*SZFREG + 7*SZXREG
++ xvld xr0, sp, 9*SZREG + 0*SZXREG
++ xvld xr1, sp, 9*SZREG + 1*SZXREG
++ xvld xr2, sp, 9*SZREG + 2*SZXREG
++ xvld xr3, sp, 9*SZREG + 3*SZXREG
++ xvld xr4, sp, 9*SZREG + 4*SZXREG
++ xvld xr5, sp, 9*SZREG + 5*SZXREG
++ xvld xr6, sp, 9*SZREG + 6*SZXREG
++ xvld xr7, sp, 9*SZREG + 7*SZXREG
+ #elif defined USE_LSX
+- vld vr0, sp, 9*SZREG + 8*SZFREG + 0*SZVREG
+- vld vr1, sp, 9*SZREG + 8*SZFREG + 1*SZVREG
+- vld vr2, sp, 9*SZREG + 8*SZFREG + 2*SZVREG
+- vld vr3, sp, 9*SZREG + 8*SZFREG + 3*SZVREG
+- vld vr4, sp, 9*SZREG + 8*SZFREG + 4*SZVREG
+- vld vr5, sp, 9*SZREG + 8*SZFREG + 5*SZVREG
+- vld vr6, sp, 9*SZREG + 8*SZFREG + 6*SZVREG
+- vld vr7, sp, 9*SZREG + 8*SZFREG + 7*SZVREG
++ vld vr0, sp, 9*SZREG + 0*SZVREG
++ vld vr1, sp, 9*SZREG + 1*SZVREG
++ vld vr2, sp, 9*SZREG + 2*SZVREG
++ vld vr3, sp, 9*SZREG + 3*SZVREG
++ vld vr4, sp, 9*SZREG + 4*SZVREG
++ vld vr5, sp, 9*SZREG + 5*SZVREG
++ vld vr6, sp, 9*SZREG + 6*SZVREG
++ vld vr7, sp, 9*SZREG + 7*SZVREG
+ #elif !defined __loongarch_soft_float
+ FREG_L fa0, sp, 9*SZREG + 0*SZFREG
+ FREG_L fa1, sp, 9*SZREG + 1*SZFREG
+--
+2.33.0
+
diff --git a/LoongArch-Micro-optimize-LD_PCREL.patch b/LoongArch-Micro-optimize-LD_PCREL.patch
new file mode 100644
index 0000000..0362e34
--- /dev/null
+++ b/LoongArch-Micro-optimize-LD_PCREL.patch
@@ -0,0 +1,44 @@
+From 7f703cf758c4f185dd62f2a4f463002bb514af16 Mon Sep 17 00:00:00 2001
+From: Xi Ruoyao <xry111@xry111.site>
+Date: Sun, 27 Aug 2023 00:36:51 +0800
+Subject: [PATCH 13/29] LoongArch: Micro-optimize LD_PCREL
+
+We are requiring Binutils >= 2.41, so explicit relocation syntax is
+always supported by the assembler. Use it to reduce one instruction.
+
+Signed-off-by: Xi Ruoyao <xry111@xry111.site>
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/unix/sysv/linux/loongarch/pointer_guard.h | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h b/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
+index b25e353b..d6c78687 100644
+--- a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
++++ b/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
+@@ -19,17 +19,15 @@
+ #ifndef POINTER_GUARD_H
+ #define POINTER_GUARD_H
+
+-/* Load a got-relative EXPR into G, using T.
+- Note G and T are register names. */
++/* Load a got-relative EXPR into register G. */
+ #define LD_GLOBAL(G, EXPR) \
+ la.global G, EXPR; \
+ REG_L G, G, 0;
+
+-/* Load a pc-relative EXPR into G, using T.
+- Note G and T are register names. */
++/* Load a pc-relative EXPR into register G. */
+ #define LD_PCREL(G, EXPR) \
+- la.pcrel G, EXPR; \
+- REG_L G, G, 0;
++ pcalau12i G, %pc_hi20(EXPR); \
++ REG_L G, G, %pc_lo12(EXPR);
+
+ #if (IS_IN (rtld) \
+ || (!defined SHARED && (IS_IN (libc) \
+--
+2.33.0
+
diff --git a/LoongArch-Redefine-macro-LEAF-ENTRY.patch b/LoongArch-Redefine-macro-LEAF-ENTRY.patch
new file mode 100644
index 0000000..414ba83
--- /dev/null
+++ b/LoongArch-Redefine-macro-LEAF-ENTRY.patch
@@ -0,0 +1,65 @@
+From 8dcd8c837df2e3cf81675522487697522f1542f8 Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Tue, 8 Aug 2023 14:15:42 +0800
+Subject: [PATCH 01/29] LoongArch: Redefine macro LEAF/ENTRY.
+
+The following usage of macro LEAF/ENTRY are all feasible:
+1. LEAF(fcn) -- the align value of fcn is .align 3(default value)
+2. LEAF(fcn, 6) -- the align value of fcn is .align 6
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/sys/asm.h | 36 ++++++++++++++++++++++++++----------
+ 1 file changed, 26 insertions(+), 10 deletions(-)
+
+diff --git a/sysdeps/loongarch/sys/asm.h b/sysdeps/loongarch/sys/asm.h
+index d1a279b8..c5eb8afa 100644
+--- a/sysdeps/loongarch/sys/asm.h
++++ b/sysdeps/loongarch/sys/asm.h
+@@ -39,16 +39,32 @@
+ #define FREG_L fld.d
+ #define FREG_S fst.d
+
+-/* Declare leaf routine. */
+-#define LEAF(symbol) \
+- .text; \
+- .globl symbol; \
+- .align 3; \
+- cfi_startproc; \
+- .type symbol, @function; \
+- symbol:
+-
+-#define ENTRY(symbol) LEAF (symbol)
++/* Declare leaf routine.
++ The usage of macro LEAF/ENTRY is as follows:
++ 1. LEAF(fcn) -- the align value of fcn is .align 3 (default value)
++ 2. LEAF(fcn, 6) -- the align value of fcn is .align 6
++*/
++#define LEAF_IMPL(symbol, aln, ...) \
++ .text; \
++ .globl symbol; \
++ .align aln; \
++ .type symbol, @function; \
++symbol: \
++ cfi_startproc;
++
++
++#define LEAF(...) LEAF_IMPL(__VA_ARGS__, 3)
++#define ENTRY(...) LEAF(__VA_ARGS__)
++
++#define LEAF_NO_ALIGN(symbol) \
++ .text; \
++ .globl symbol; \
++ .type symbol, @function; \
++symbol: \
++ cfi_startproc;
++
++#define ENTRY_NO_ALIGN(symbol) LEAF_NO_ALIGN(symbol)
++
+
+ /* Mark end of function. */
+ #undef END
+--
+2.33.0
+
diff --git a/LoongArch-Remove-support-code-for-old-linker-in-star.patch b/LoongArch-Remove-support-code-for-old-linker-in-star.patch
new file mode 100644
index 0000000..3d688da
--- /dev/null
+++ b/LoongArch-Remove-support-code-for-old-linker-in-star.patch
@@ -0,0 +1,56 @@
+From f8d66a269cb6f1a7087afadf3375bdf0553abf53 Mon Sep 17 00:00:00 2001
+From: Xi Ruoyao <xry111@xry111.site>
+Date: Sun, 27 Aug 2023 00:36:50 +0800
+Subject: [PATCH 12/29] LoongArch: Remove support code for old linker in
+ start.S
+
+We are requiring Binutils >= 2.41, so la.pcrel always works here.
+
+Signed-off-by: Xi Ruoyao <xry111@xry111.site>
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/start.S | 19 +++----------------
+ 1 file changed, 3 insertions(+), 16 deletions(-)
+
+diff --git a/sysdeps/loongarch/start.S b/sysdeps/loongarch/start.S
+index e9d82033..bf6bfc9e 100644
+--- a/sysdeps/loongarch/start.S
++++ b/sysdeps/loongarch/start.S
+@@ -60,20 +60,7 @@ ENTRY (ENTRY_POINT)
+ cfi_undefined (1)
+ or a5, a0, zero /* rtld_fini */
+
+-#if ENABLE_STATIC_PIE
+-/* For static PIE, the GOT cannot be used in _start because the GOT entries are
+- offsets instead of real addresses before __libc_start_main.
+- __libc_start_main and/or main may be not local, so we rely on the linker to
+- produce PLT entries for them. GNU ld >= 2.40 supports this. */
+-# define LA la.pcrel
+-#else
+-/* Old GNU ld (< 2.40) cannot handle PC relative address against a non-local
+- function correctly. We deem these old linkers failing to support static PIE
+- and load the addresses from GOT. */
+-# define LA la.got
+-#endif
+-
+- LA a0, t0, main
++ la.pcrel a0, t0, main
+ REG_L a1, sp, 0
+ ADDI a2, sp, SZREG
+
+@@ -84,9 +71,9 @@ ENTRY (ENTRY_POINT)
+ move a4, zero /* used to be fini */
+ or a6, sp, zero /* stack_end */
+
+- LA ra, t0, __libc_start_main
++ la.pcrel ra, t0, __libc_start_main
+ jirl ra, ra, 0
+
+- LA ra, t0, abort
++ la.pcrel ra, t0, abort
+ jirl ra, ra, 0
+ END (ENTRY_POINT)
+--
+2.33.0
+
diff --git a/LoongArch-Replace-deprecated-v0-with-a0-to-eliminate.patch b/LoongArch-Replace-deprecated-v0-with-a0-to-eliminate.patch
new file mode 100644
index 0000000..82ae1be
--- /dev/null
+++ b/LoongArch-Replace-deprecated-v0-with-a0-to-eliminate.patch
@@ -0,0 +1,28 @@
+From b4b4bb7c9220a0bbdf5aec0ac8c1de1d22329280 Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Thu, 14 Sep 2023 19:48:24 +0800
+Subject: [PATCH 21/29] LoongArch: Replace deprecated $v0 with $a0 to eliminate
+ 'as' Warnings.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/dl-machine.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
+index 8a2db9de..57913cef 100644
+--- a/sysdeps/loongarch/dl-machine.h
++++ b/sysdeps/loongarch/dl-machine.h
+@@ -90,7 +90,7 @@ static inline ElfW (Addr) elf_machine_dynamic (void)
+ or $a0, $sp, $zero \n\
+ bl _dl_start \n\
+ # Stash user entry point in s0. \n\
+- or $s0, $v0, $zero \n\
++ or $s0, $a0, $zero \n\
+ # Load the original argument count. \n\
+ ld.d $a1, $sp, 0 \n\
+ # Call _dl_init (struct link_map *main_map, int argc, \
+--
+2.33.0
+
diff --git a/LoongArch-Unify-Register-Names.patch b/LoongArch-Unify-Register-Names.patch
new file mode 100644
index 0000000..9473b78
--- /dev/null
+++ b/LoongArch-Unify-Register-Names.patch
@@ -0,0 +1,81 @@
+From 458ab6d5f39cca1cabd83abd2022f67491f6f5ed Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Fri, 20 Oct 2023 09:20:02 +0800
+Subject: [PATCH 27/29] LoongArch: Unify Register Names.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/__longjmp.S | 20 ++++++++++----------
+ sysdeps/loongarch/setjmp.S | 18 +++++++++---------
+ 2 files changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/sysdeps/loongarch/__longjmp.S b/sysdeps/loongarch/__longjmp.S
+index cbde1946..e87ce311 100644
+--- a/sysdeps/loongarch/__longjmp.S
++++ b/sysdeps/loongarch/__longjmp.S
+@@ -43,18 +43,18 @@ ENTRY (__longjmp)
+ REG_L s8, a0, 12*SZREG
+
+ #ifndef __loongarch_soft_float
+- FREG_L $f24, a0, 13*SZREG + 0*SZFREG
+- FREG_L $f25, a0, 13*SZREG + 1*SZFREG
+- FREG_L $f26, a0, 13*SZREG + 2*SZFREG
+- FREG_L $f27, a0, 13*SZREG + 3*SZFREG
+- FREG_L $f28, a0, 13*SZREG + 4*SZFREG
+- FREG_L $f29, a0, 13*SZREG + 5*SZFREG
+- FREG_L $f30, a0, 13*SZREG + 6*SZFREG
+- FREG_L $f31, a0, 13*SZREG + 7*SZFREG
++ FREG_L fs0, a0, 13*SZREG + 0*SZFREG
++ FREG_L fs1, a0, 13*SZREG + 1*SZFREG
++ FREG_L fs2, a0, 13*SZREG + 2*SZFREG
++ FREG_L fs3, a0, 13*SZREG + 3*SZFREG
++ FREG_L fs4, a0, 13*SZREG + 4*SZFREG
++ FREG_L fs5, a0, 13*SZREG + 5*SZFREG
++ FREG_L fs6, a0, 13*SZREG + 6*SZFREG
++ FREG_L fs7, a0, 13*SZREG + 7*SZFREG
+ #endif
+
+- sltui a0,a1,1
++ sltui a0, a1, 1
+ ADD a0, a0, a1 # a0 = (a1 == 0) ? 1 : a1
+- jirl zero,ra,0
++ jirl zero, ra, 0
+
+ END (__longjmp)
+diff --git a/sysdeps/loongarch/setjmp.S b/sysdeps/loongarch/setjmp.S
+index 6c7065cd..b6e4f727 100644
+--- a/sysdeps/loongarch/setjmp.S
++++ b/sysdeps/loongarch/setjmp.S
+@@ -52,19 +52,19 @@ ENTRY (__sigsetjmp)
+ REG_S s8, a0, 12*SZREG
+
+ #ifndef __loongarch_soft_float
+- FREG_S $f24, a0, 13*SZREG + 0*SZFREG
+- FREG_S $f25, a0, 13*SZREG + 1*SZFREG
+- FREG_S $f26, a0, 13*SZREG + 2*SZFREG
+- FREG_S $f27, a0, 13*SZREG + 3*SZFREG
+- FREG_S $f28, a0, 13*SZREG + 4*SZFREG
+- FREG_S $f29, a0, 13*SZREG + 5*SZFREG
+- FREG_S $f30, a0, 13*SZREG + 6*SZFREG
+- FREG_S $f31, a0, 13*SZREG + 7*SZFREG
++ FREG_S fs0, a0, 13*SZREG + 0*SZFREG
++ FREG_S fs1, a0, 13*SZREG + 1*SZFREG
++ FREG_S fs2, a0, 13*SZREG + 2*SZFREG
++ FREG_S fs3, a0, 13*SZREG + 3*SZFREG
++ FREG_S fs4, a0, 13*SZREG + 4*SZFREG
++ FREG_S fs5, a0, 13*SZREG + 5*SZFREG
++ FREG_S fs6, a0, 13*SZREG + 6*SZFREG
++ FREG_S fs7, a0, 13*SZREG + 7*SZFREG
+ #endif
+
+ #if !IS_IN (libc) && IS_IN(rtld)
+ li.w v0, 0
+- jirl zero,ra,0
++ jirl zero, ra, 0
+ #else
+ b __sigjmp_save
+ #endif
+--
+2.33.0
+
diff --git a/LoongArch-Update-hwcap.h-to-sync-with-LoongArch-kern.patch b/LoongArch-Update-hwcap.h-to-sync-with-LoongArch-kern.patch
new file mode 100644
index 0000000..27ee625
--- /dev/null
+++ b/LoongArch-Update-hwcap.h-to-sync-with-LoongArch-kern.patch
@@ -0,0 +1,24 @@
+From 4828d1aa0028e819a5fb336d962e8f7cbfedf8b4 Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Mon, 23 Oct 2023 15:53:38 +0800
+Subject: [PATCH 28/29] LoongArch: Update hwcap.h to sync with LoongArch
+ kernel.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/unix/sysv/linux/loongarch/bits/hwcap.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/hwcap.h b/sysdeps/unix/sysv/linux/loongarch/bits/hwcap.h
+index 5104b69c..7acec23d 100644
+--- a/sysdeps/unix/sysv/linux/loongarch/bits/hwcap.h
++++ b/sysdeps/unix/sysv/linux/loongarch/bits/hwcap.h
+@@ -35,3 +35,4 @@
+ #define HWCAP_LOONGARCH_LBT_X86 (1 << 10)
+ #define HWCAP_LOONGARCH_LBT_ARM (1 << 11)
+ #define HWCAP_LOONGARCH_LBT_MIPS (1 << 12)
++#define HWCAP_LOONGARCH_PTW (1 << 13)
+--
+2.33.0
+
diff --git a/LoongArch-elf-Add-new-LoongArch-reloc-types-109-into.patch b/LoongArch-elf-Add-new-LoongArch-reloc-types-109-into.patch
new file mode 100644
index 0000000..b9b6f0d
--- /dev/null
+++ b/LoongArch-elf-Add-new-LoongArch-reloc-types-109-into.patch
@@ -0,0 +1,30 @@
+From 4938840b15ff9734fdcc63cc0744ce3f3bbb0b16 Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Mon, 14 Aug 2023 15:34:08 +0800
+Subject: [PATCH 05/29] LoongArch: elf: Add new LoongArch reloc types 109 into
+ elf.h
+
+These reloc types are generated by GNU assembler >= 2.41 for relaxation
+support.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ elf/elf.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/elf/elf.h b/elf/elf.h
+index d623bdeb..9c51073f 100644
+--- a/elf/elf.h
++++ b/elf/elf.h
+@@ -4213,6 +4213,7 @@ enum
+ #define R_LARCH_SUB6 106
+ #define R_LARCH_ADD_ULEB128 107
+ #define R_LARCH_SUB_ULEB128 108
++#define R_LARCH_64_PCREL 109
+
+ /* ARC specific declarations. */
+
+--
+2.33.0
+
diff --git a/Loongarch-Add-ifunc-support-and-add-different-versio.patch b/Loongarch-Add-ifunc-support-and-add-different-versio.patch
new file mode 100644
index 0000000..aae8ddc
--- /dev/null
+++ b/Loongarch-Add-ifunc-support-and-add-different-versio.patch
@@ -0,0 +1,528 @@
+From 43abd8772a143cd96688c081500397dd712e631b Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Tue, 8 Aug 2023 14:15:44 +0800
+Subject: [PATCH 03/29] Loongarch: Add ifunc support and add different versions
+ of strlen
+
+strlen-lasx is implemeted by LASX simd instructions(256bit)
+strlen-lsx is implemeted by LSX simd instructions(128bit)
+strlen-align is implemented by LA basic instructions and never use unaligned memory acess
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 7 ++
+ .../lp64/multiarch/ifunc-impl-list.c | 41 +++++++
+ .../loongarch/lp64/multiarch/ifunc-strlen.h | 40 +++++++
+ .../loongarch/lp64/multiarch/strlen-aligned.S | 100 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/strlen-lasx.S | 63 +++++++++++
+ sysdeps/loongarch/lp64/multiarch/strlen-lsx.S | 71 +++++++++++++
+ sysdeps/loongarch/lp64/multiarch/strlen.c | 37 +++++++
+ sysdeps/loongarch/sys/regdef.h | 57 ++++++++++
+ .../unix/sysv/linux/loongarch/cpu-features.h | 2 +
+ 9 files changed, 418 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/Makefile
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-strlen.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strlen-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strlen-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strlen-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strlen.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+new file mode 100644
+index 00000000..76c506c9
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -0,0 +1,7 @@
++ifeq ($(subdir),string)
++sysdep_routines += \
++ strlen-aligned \
++ strlen-lsx \
++ strlen-lasx \
++# sysdep_routines
++endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+new file mode 100644
+index 00000000..1a2a576f
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -0,0 +1,41 @@
++/* Enumerate available IFUNC implementations of a function LoongArch64 version.
++ 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
++ <http://www.gnu.org/licenses/>. */
++
++#include <assert.h>
++#include <string.h>
++#include <wchar.h>
++#include <ldsodefs.h>
++#include <ifunc-impl-list.h>
++#include <stdio.h>
++
++size_t
++__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
++ size_t max)
++{
++
++ size_t i = max;
++
++ IFUNC_IMPL (i, name, strlen,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, strlen, SUPPORT_LASX, __strlen_lasx)
++ IFUNC_IMPL_ADD (array, i, strlen, SUPPORT_LSX, __strlen_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_aligned)
++ )
++ return i;
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-strlen.h b/sysdeps/loongarch/lp64/multiarch/ifunc-strlen.h
+new file mode 100644
+index 00000000..6258bb76
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-strlen.h
+@@ -0,0 +1,40 @@
++/* Common definition for strlen ifunc selections.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S b/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S
+new file mode 100644
+index 00000000..e9e1d2fc
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S
+@@ -0,0 +1,100 @@
++/* Optimized strlen implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define STRLEN __strlen_aligned
++#else
++# define STRLEN strlen
++#endif
++
++LEAF(STRLEN, 6)
++ move a1, a0
++ bstrins.d a0, zero, 2, 0
++ lu12i.w a2, 0x01010
++ li.w t0, -1
++
++ ld.d t2, a0, 0
++ andi t1, a1, 0x7
++ ori a2, a2, 0x101
++ slli.d t1, t1, 3
++
++ bstrins.d a2, a2, 63, 32
++ sll.d t1, t0, t1
++ slli.d t3, a2, 7
++ nor a3, zero, t3
++
++ orn t2, t2, t1
++ sub.d t0, t2, a2
++ nor t1, t2, a3
++ and t0, t0, t1
++
++
++ bnez t0, L(count_pos)
++ addi.d a0, a0, 8
++L(loop_16_7bit):
++ ld.d t2, a0, 0
++ sub.d t1, t2, a2
++
++ and t0, t1, t3
++ bnez t0, L(more_check)
++ ld.d t2, a0, 8
++ sub.d t1, t2, a2
++
++ and t0, t1, t3
++ addi.d a0, a0, 16
++ beqz t0, L(loop_16_7bit)
++ addi.d a0, a0, -8
++
++L(more_check):
++ nor t0, t2, a3
++ and t0, t1, t0
++ bnez t0, L(count_pos)
++ addi.d a0, a0, 8
++
++
++L(loop_16_8bit):
++ ld.d t2, a0, 0
++ sub.d t1, t2, a2
++ nor t0, t2, a3
++ and t0, t0, t1
++
++ bnez t0, L(count_pos)
++ ld.d t2, a0, 8
++ addi.d a0, a0, 16
++ sub.d t1, t2, a2
++
++ nor t0, t2, a3
++ and t0, t0, t1
++ beqz t0, L(loop_16_8bit)
++ addi.d a0, a0, -8
++
++L(count_pos):
++ ctz.d t1, t0
++ sub.d a0, a0, a1
++ srli.d t1, t1, 3
++ add.d a0, a0, t1
++
++ jr ra
++END(STRLEN)
++
++libc_hidden_builtin_def (STRLEN)
+diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S b/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S
+new file mode 100644
+index 00000000..258c47ce
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S
+@@ -0,0 +1,63 @@
++/* Optimized strlen implementation using loongarch LASX SIMD instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define STRLEN __strlen_lasx
++
++LEAF(STRLEN, 6)
++ move a1, a0
++ bstrins.d a0, zero, 4, 0
++ li.d t1, -1
++ xvld xr0, a0, 0
++
++ xvmsknz.b xr0, xr0
++ xvpickve.w xr1, xr0, 4
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0 # sign extend
++
++ sra.w t0, t0, a1
++ beq t0, t1, L(loop)
++ cto.w a0, t0
++ jr ra
++
++L(loop):
++ xvld xr0, a0, 32
++ addi.d a0, a0, 32
++ xvsetanyeqz.b fcc0, xr0
++ bceqz fcc0, L(loop)
++
++
++ xvmsknz.b xr0, xr0
++ sub.d a0, a0, a1
++ xvpickve.w xr1, xr0, 4
++ vilvl.h vr0, vr1, vr0
++
++ movfr2gr.s t0, fa0
++ cto.w t0, t0
++ add.d a0, a0, t0
++ jr ra
++END(STRLEN)
++
++libc_hidden_builtin_def (STRLEN)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S b/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S
+new file mode 100644
+index 00000000..b194355e
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S
+@@ -0,0 +1,71 @@
++/* Optimized strlen implementation using Loongarch LSX SIMD instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define STRLEN __strlen_lsx
++
++LEAF(STRLEN, 6)
++ move a1, a0
++ bstrins.d a0, zero, 4, 0
++ vld vr0, a0, 0
++ vld vr1, a0, 16
++
++ li.d t1, -1
++ vmsknz.b vr0, vr0
++ vmsknz.b vr1, vr1
++ vilvl.h vr0, vr1, vr0
++
++ movfr2gr.s t0, fa0
++ sra.w t0, t0, a1
++ beq t0, t1, L(loop)
++ cto.w a0, t0
++
++ jr ra
++ nop
++ nop
++ nop
++
++
++L(loop):
++ vld vr0, a0, 32
++ vld vr1, a0, 48
++ addi.d a0, a0, 32
++ vmin.bu vr2, vr0, vr1
++
++ vsetanyeqz.b fcc0, vr2
++ bceqz fcc0, L(loop)
++ vmsknz.b vr0, vr0
++ vmsknz.b vr1, vr1
++
++ vilvl.h vr0, vr1, vr0
++ sub.d a0, a0, a1
++ movfr2gr.s t0, fa0
++ cto.w t0, t0
++
++ add.d a0, a0, t0
++ jr ra
++END(STRLEN)
++
++libc_hidden_builtin_def (STRLEN)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strlen.c b/sysdeps/loongarch/lp64/multiarch/strlen.c
+new file mode 100644
+index 00000000..381c2daa
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strlen.c
+@@ -0,0 +1,37 @@
++/* Multiple versions of strlen.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++
++#if IS_IN (libc)
++# define strlen __redirect_strlen
++# include <string.h>
++# undef strlen
++
++# define SYMBOL_NAME strlen
++# include "ifunc-strlen.h"
++
++libc_ifunc_redirected (__redirect_strlen, strlen, IFUNC_SELECTOR ());
++
++# ifdef SHARED
++__hidden_ver1 (strlen, __GI_strlen, __redirect_strlen)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strlen);
++# endif
++
++#endif
+diff --git a/sysdeps/loongarch/sys/regdef.h b/sysdeps/loongarch/sys/regdef.h
+index 5100f36d..524d2e32 100644
+--- a/sysdeps/loongarch/sys/regdef.h
++++ b/sysdeps/loongarch/sys/regdef.h
+@@ -89,6 +89,14 @@
+ #define fs5 $f29
+ #define fs6 $f30
+ #define fs7 $f31
++#define fcc0 $fcc0
++#define fcc1 $fcc1
++#define fcc2 $fcc2
++#define fcc3 $fcc3
++#define fcc4 $fcc4
++#define fcc5 $fcc5
++#define fcc6 $fcc6
++#define fcc7 $fcc7
+
+ #define vr0 $vr0
+ #define vr1 $vr1
+@@ -98,6 +106,30 @@
+ #define vr5 $vr5
+ #define vr6 $vr6
+ #define vr7 $vr7
++#define vr8 $vr8
++#define vr9 $vr9
++#define vr10 $vr10
++#define vr11 $vr11
++#define vr12 $vr12
++#define vr13 $vr13
++#define vr14 $vr14
++#define vr15 $vr15
++#define vr16 $vr16
++#define vr17 $vr17
++#define vr18 $vr18
++#define vr19 $vr19
++#define vr20 $vr20
++#define vr21 $vr21
++#define vr22 $vr22
++#define vr23 $vr23
++#define vr24 $vr24
++#define vr25 $vr25
++#define vr26 $vr26
++#define vr27 $vr27
++#define vr28 $vr28
++#define vr29 $vr29
++#define vr30 $vr30
++#define vr31 $vr31
+
+ #define xr0 $xr0
+ #define xr1 $xr1
+@@ -107,5 +139,30 @@
+ #define xr5 $xr5
+ #define xr6 $xr6
+ #define xr7 $xr7
++#define xr7 $xr7
++#define xr8 $xr8
++#define xr9 $xr9
++#define xr10 $xr10
++#define xr11 $xr11
++#define xr12 $xr12
++#define xr13 $xr13
++#define xr14 $xr14
++#define xr15 $xr15
++#define xr16 $xr16
++#define xr17 $xr17
++#define xr18 $xr18
++#define xr19 $xr19
++#define xr20 $xr20
++#define xr21 $xr21
++#define xr22 $xr22
++#define xr23 $xr23
++#define xr24 $xr24
++#define xr25 $xr25
++#define xr26 $xr26
++#define xr27 $xr27
++#define xr28 $xr28
++#define xr29 $xr29
++#define xr30 $xr30
++#define xr31 $xr31
+
+ #endif /* _SYS_REGDEF_H */
+diff --git a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
+index e371e13b..d1a280a5 100644
+--- a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
++++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
+@@ -25,5 +25,7 @@
+ #define SUPPORT_LSX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LSX)
+ #define SUPPORT_LASX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LASX)
+
++#define INIT_ARCH()
++
+ #endif /* _CPU_FEATURES_LOONGARCH64_H */
+
+--
+2.33.0
+
diff --git a/Loongarch-Add-ifunc-support-for-memcpy-aligned-unali.patch b/Loongarch-Add-ifunc-support-for-memcpy-aligned-unali.patch
new file mode 100644
index 0000000..2bbf367
--- /dev/null
+++ b/Loongarch-Add-ifunc-support-for-memcpy-aligned-unali.patch
@@ -0,0 +1,2570 @@
+From 9c522272146423c1ef9fb9e071737a8ad26e844e Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Tue, 15 Aug 2023 09:11:53 +0800
+Subject: [PATCH 07/29] Loongarch: Add ifunc support for memcpy{aligned,
+ unaligned, lsx, lasx} and memmove{aligned, unaligned, lsx, lasx}
+
+These implementations improve the time to copy data in the glibc
+microbenchmark as below:
+memcpy-lasx reduces the runtime about 8%-76%
+memcpy-lsx reduces the runtime about 8%-72%
+memcpy-unaligned reduces the runtime of unaligned data copying up to 40%
+memcpy-aligned reduece the runtime of unaligned data copying up to 25%
+memmove-lasx reduces the runtime about 20%-73%
+memmove-lsx reduces the runtime about 50%
+memmove-unaligned reduces the runtime of unaligned data moving up to 40%
+memmove-aligned reduces the runtime of unaligned data moving up to 25%
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 5 +
+ .../lp64/multiarch/ifunc-impl-list.c | 19 +
+ sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h | 45 +
+ .../loongarch/lp64/multiarch/memcpy-aligned.S | 783 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/memcpy-lasx.S | 20 +
+ sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S | 20 +
+ .../lp64/multiarch/memcpy-unaligned.S | 247 ++++++
+ sysdeps/loongarch/lp64/multiarch/memcpy.c | 37 +
+ .../lp64/multiarch/memmove-aligned.S | 20 +
+ .../loongarch/lp64/multiarch/memmove-lasx.S | 287 +++++++
+ .../loongarch/lp64/multiarch/memmove-lsx.S | 534 ++++++++++++
+ .../lp64/multiarch/memmove-unaligned.S | 380 +++++++++
+ sysdeps/loongarch/lp64/multiarch/memmove.c | 38 +
+ 13 files changed, 2435 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy.c
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index 110a8c5c..afa51041 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -9,5 +9,10 @@ sysdep_routines += \
+ strchrnul-aligned \
+ strchrnul-lsx \
+ strchrnul-lasx \
++ memcpy-aligned \
++ memcpy-unaligned \
++ memmove-unaligned \
++ memmove-lsx \
++ memmove-lasx \
+ # sysdep_routines
+ endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index c7164b45..25eb96b0 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -53,5 +53,24 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ #endif
+ IFUNC_IMPL_ADD (array, i, strchrnul, 1, __strchrnul_aligned)
+ )
++
++ IFUNC_IMPL (i, name, memcpy,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, memcpy, SUPPORT_LASX, __memcpy_lasx)
++ IFUNC_IMPL_ADD (array, i, memcpy, SUPPORT_LSX, __memcpy_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, memcpy, SUPPORT_UAL, __memcpy_unaligned)
++ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_aligned)
++ )
++
++ IFUNC_IMPL (i, name, memmove,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, memmove, SUPPORT_LASX, __memmove_lasx)
++ IFUNC_IMPL_ADD (array, i, memmove, SUPPORT_LSX, __memmove_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, memmove, SUPPORT_UAL, __memmove_unaligned)
++ IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_aligned)
++ )
++
+ return i;
+ }
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h b/sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h
+new file mode 100644
+index 00000000..3be67da6
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h
+@@ -0,0 +1,45 @@
++/* Common definition for ifunc selection implementation.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (unaligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ if (SUPPORT_UAL)
++ return OPTIMIZE (unaligned);
++ else
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S b/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S
+new file mode 100644
+index 00000000..299dd49c
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S
+@@ -0,0 +1,783 @@
++/* Optimized memcpy_aligned implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define MEMCPY_NAME __memcpy_aligned
++# define MEMMOVE_NAME __memmove_aligned
++#else
++# define MEMCPY_NAME memcpy
++# define MEMMOVE_NAME memmove
++#endif
++
++#define LD_64(reg, n) \
++ ld.d t0, reg, n; \
++ ld.d t1, reg, n + 8; \
++ ld.d t2, reg, n + 16; \
++ ld.d t3, reg, n + 24; \
++ ld.d t4, reg, n + 32; \
++ ld.d t5, reg, n + 40; \
++ ld.d t6, reg, n + 48; \
++ ld.d t7, reg, n + 56;
++
++#define ST_64(reg, n) \
++ st.d t0, reg, n; \
++ st.d t1, reg, n + 8; \
++ st.d t2, reg, n + 16; \
++ st.d t3, reg, n + 24; \
++ st.d t4, reg, n + 32; \
++ st.d t5, reg, n + 40; \
++ st.d t6, reg, n + 48; \
++ st.d t7, reg, n + 56;
++
++LEAF(MEMMOVE_NAME, 6)
++ sub.d t0, a0, a1
++ bltu t0, a2, L(copy_back)
++END(MEMMOVE_NAME)
++
++LEAF_NO_ALIGN(MEMCPY_NAME)
++ srai.d a3, a2, 4
++ beqz a3, L(short_data)
++
++ move a4, a0
++ andi a5, a0, 0x7
++ andi a6, a1, 0x7
++ li.d t8, 8
++ beqz a5, L(check_align)
++
++ sub.d t2, t8, a5
++ sub.d a2, a2, t2
++ pcaddi t1, 20
++ slli.d t3, t2, 3
++
++ add.d a1, a1, t2
++ sub.d t1, t1, t3
++ add.d a4, a4, t2
++ jr t1
++
++L(al7):
++ ld.b t0, a1, -7
++ st.b t0, a4, -7
++L(al6):
++ ld.b t0, a1, -6
++ st.b t0, a4, -6
++L(al5):
++ ld.b t0, a1, -5
++ st.b t0, a4, -5
++L(al4):
++ ld.b t0, a1, -4
++ st.b t0, a4, -4
++L(al3):
++ ld.b t0, a1, -3
++ st.b t0, a4, -3
++L(al2):
++ ld.b t0, a1, -2
++ st.b t0, a4, -2
++L(al1):
++ ld.b t0, a1, -1
++ st.b t0, a4, -1
++
++L(check_align):
++ bne a5, a6, L(unalign)
++ srai.d a3, a2, 4
++ beqz a3, L(al_less_16bytes)
++ andi a3, a2, 0x3f
++
++ beq a3, a2, L(al_less_64bytes)
++ sub.d t0, a2, a3
++ move a2, a3
++ add.d a5, a1, t0
++
++L(loop_64bytes):
++ LD_64(a1, 0)
++ addi.d a1, a1, 64
++ ST_64(a4, 0)
++
++ addi.d a4, a4, 64
++ bne a1, a5, L(loop_64bytes)
++
++L(al_less_64bytes):
++ srai.d a3, a2, 5
++ beqz a3, L(al_less_32bytes)
++
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ ld.d t2, a1, 16
++ ld.d t3, a1, 24
++
++ addi.d a1, a1, 32
++ addi.d a2, a2, -32
++
++ st.d t0, a4, 0
++ st.d t1, a4, 8
++ st.d t2, a4, 16
++ st.d t3, a4, 24
++
++ addi.d a4, a4, 32
++
++L(al_less_32bytes):
++ srai.d a3, a2, 4
++ beqz a3, L(al_less_16bytes)
++
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ addi.d a1, a1, 16
++ addi.d a2, a2, -16
++
++ st.d t0, a4, 0
++ st.d t1, a4, 8
++ addi.d a4, a4, 16
++
++L(al_less_16bytes):
++ srai.d a3, a2, 3
++ beqz a3, L(al_less_8bytes)
++
++ ld.d t0, a1, 0
++ addi.d a1, a1, 8
++ addi.d a2, a2, -8
++ st.d t0, a4, 0
++ addi.d a4, a4, 8
++
++L(al_less_8bytes):
++ srai.d a3, a2, 2
++ beqz a3, L(al_less_4bytes)
++
++ ld.w t0, a1, 0
++ addi.d a1, a1, 4
++ addi.d a2, a2, -4
++ st.w t0, a4, 0
++ addi.d a4, a4, 4
++
++L(al_less_4bytes):
++ srai.d a3, a2, 1
++ beqz a3, L(al_less_2bytes)
++
++ ld.h t0, a1, 0
++ addi.d a1, a1, 2
++ addi.d a2, a2, -2
++ st.h t0, a4, 0
++ addi.d a4, a4, 2
++
++L(al_less_2bytes):
++ beqz a2, L(al_less_1byte)
++
++ ld.b t0, a1, 0
++ st.b t0, a4, 0
++
++L(al_less_1byte):
++ jr ra
++
++L(unalign):
++ andi a5, a1, 0x7
++ bstrins.d a1, zero, 2, 0
++ sub.d t8, t8, a5
++ slli.d a5, a5, 3
++
++ ld.d t0, a1, 0
++ addi.d a1, a1, 8
++ slli.d a6, t8, 3
++ srl.d a7, t0, a5
++
++ srai.d a3, a2, 4
++ beqz a3, L(un_less_16bytes)
++ andi a3, a2, 0x3f
++ beq a3, a2, L(un_less_64bytes)
++
++ sub.d t0, a2, a3
++ move a2, a3
++ add.d a3, a1, t0
++
++L(un_long_bytes):
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ ld.d t2, a1, 16
++ ld.d t3, a1, 24
++
++ srl.d t4, t0, a5
++ sll.d t0, t0, a6
++ srl.d t5, t1, a5
++ sll.d t1, t1, a6
++
++ srl.d t6, t2, a5
++ sll.d t2, t2, a6
++ srl.d t7, t3, a5
++ sll.d t3, t3, a6
++
++ or t0, a7, t0
++ or t1, t4, t1
++ or t2, t5, t2
++ or t3, t6, t3
++
++ ld.d t4, a1, 32
++ ld.d t5, a1, 40
++ ld.d t6, a1, 48
++ ld.d a7, a1, 56
++
++ st.d t0, a4, 0
++ st.d t1, a4, 8
++ st.d t2, a4, 16
++ st.d t3, a4, 24
++
++ addi.d a1, a1, 64
++
++ srl.d t0, t4, a5
++ sll.d t4, t4, a6
++ srl.d t1, t5, a5
++ sll.d t5, t5, a6
++
++ srl.d t2, t6, a5
++ sll.d t6, t6, a6
++ sll.d t3, a7, a6
++ srl.d a7, a7, a5
++
++ or t4, t7, t4
++ or t5, t0, t5
++ or t6, t1, t6
++ or t3, t2, t3
++
++ st.d t4, a4, 32
++ st.d t5, a4, 40
++ st.d t6, a4, 48
++ st.d t3, a4, 56
++
++ addi.d a4, a4, 64
++ bne a3, a1, L(un_long_bytes)
++
++L(un_less_64bytes):
++ srai.d a3, a2, 5
++ beqz a3, L(un_less_32bytes)
++
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ ld.d t2, a1, 16
++ ld.d t3, a1, 24
++
++ addi.d a1, a1, 32
++ addi.d a2, a2, -32
++
++ srl.d t4, t0, a5
++ sll.d t0, t0, a6
++ srl.d t5, t1, a5
++ sll.d t1, t1, a6
++
++ srl.d t6, t2, a5
++ sll.d t2, t2, a6
++ or t0, a7, t0
++ srl.d a7, t3, a5
++ sll.d t3, t3, a6
++
++ or t1, t4, t1
++ or t2, t5, t2
++ or t3, t6, t3
++
++ st.d t0, a4, 0
++ st.d t1, a4, 8
++ st.d t2, a4, 16
++ st.d t3, a4, 24
++
++ addi.d a4, a4, 32
++
++L(un_less_32bytes):
++ srai.d a3, a2, 4
++ beqz a3, L(un_less_16bytes)
++
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ addi.d a1, a1, 16
++ addi.d a2, a2, -16
++
++ srl.d t2, t0, a5
++ sll.d t3, t0, a6
++ sll.d t4, t1, a6
++ or t3, a7, t3
++ or t4, t2, t4
++
++ srl.d a7, t1, a5
++ st.d t3, a4, 0
++ st.d t4, a4, 8
++ addi.d a4, a4, 16
++
++L(un_less_16bytes):
++ srai.d a3, a2, 3
++ beqz a3, L(un_less_8bytes)
++
++ ld.d t0, a1, 0
++ addi.d a1, a1, 8
++ addi.d a2, a2, -8
++ sll.d t1, t0, a6
++
++ or t2, a7, t1
++ srl.d a7, t0, a5
++ st.d t2, a4, 0
++ addi.d a4, a4, 8
++
++L(un_less_8bytes):
++ beqz a2, L(un_less_1byte)
++ bge t8, a2, 1f
++
++ ld.d t0, a1, 0
++ sll.d t0, t0, a6
++ or a7, a7, t0
++
++1:
++ srai.d a3, a2, 2
++ beqz a3, L(un_less_4bytes)
++
++ addi.d a2, a2, -4
++ st.w a7, a4, 0
++ addi.d a4, a4, 4
++ srai.d a7, a7, 32
++
++L(un_less_4bytes):
++ srai.d a3, a2, 1
++ beqz a3, L(un_less_2bytes)
++
++ addi.d a2, a2, -2
++ st.h a7, a4, 0
++ addi.d a4, a4, 2
++ srai.d a7, a7, 16
++
++L(un_less_2bytes):
++ beqz a2, L(un_less_1byte)
++ st.b a7, a4, 0
++
++L(un_less_1byte):
++ jr ra
++
++L(short_data):
++ pcaddi t1, 36
++ slli.d t2, a2, 3
++ add.d a4, a0, a2
++ sub.d t1, t1, t2
++ add.d a1, a1, a2
++ jr t1
++
++L(short_15_bytes):
++ ld.b t0, a1, -15
++ st.b t0, a4, -15
++L(short_14_bytes):
++ ld.b t0, a1, -14
++ st.b t0, a4, -14
++L(short_13_bytes):
++ ld.b t0, a1, -13
++ st.b t0, a4, -13
++L(short_12_bytes):
++ ld.b t0, a1, -12
++ st.b t0, a4, -12
++L(short_11_bytes):
++ ld.b t0, a1, -11
++ st.b t0, a4, -11
++L(short_10_bytes):
++ ld.b t0, a1, -10
++ st.b t0, a4, -10
++L(short_9_bytes):
++ ld.b t0, a1, -9
++ st.b t0, a4, -9
++L(short_8_bytes):
++ ld.b t0, a1, -8
++ st.b t0, a4, -8
++L(short_7_bytes):
++ ld.b t0, a1, -7
++ st.b t0, a4, -7
++L(short_6_bytes):
++ ld.b t0, a1, -6
++ st.b t0, a4, -6
++L(short_5_bytes):
++ ld.b t0, a1, -5
++ st.b t0, a4, -5
++L(short_4_bytes):
++ ld.b t0, a1, -4
++ st.b t0, a4, -4
++L(short_3_bytes):
++ ld.b t0, a1, -3
++ st.b t0, a4, -3
++L(short_2_bytes):
++ ld.b t0, a1, -2
++ st.b t0, a4, -2
++L(short_1_bytes):
++ ld.b t0, a1, -1
++ st.b t0, a4, -1
++ jr ra
++
++L(copy_back):
++ srai.d a3, a2, 4
++ beqz a3, L(back_short_data)
++
++ add.d a4, a0, a2
++ add.d a1, a1, a2
++
++ andi a5, a4, 0x7
++ andi a6, a1, 0x7
++ beqz a5, L(back_check_align)
++
++ sub.d a2, a2, a5
++ sub.d a1, a1, a5
++ sub.d a4, a4, a5
++
++ pcaddi t1, 18
++ slli.d t3, a5, 3
++ sub.d t1, t1, t3
++ jr t1
++
++ ld.b t0, a1, 6
++ st.b t0, a4, 6
++ ld.b t0, a1, 5
++ st.b t0, a4, 5
++ ld.b t0, a1, 4
++ st.b t0, a4, 4
++ ld.b t0, a1, 3
++ st.b t0, a4, 3
++ ld.b t0, a1, 2
++ st.b t0, a4, 2
++ ld.b t0, a1, 1
++ st.b t0, a4, 1
++ ld.b t0, a1, 0
++ st.b t0, a4, 0
++
++L(back_check_align):
++ bne a5, a6, L(back_unalign)
++
++ srai.d a3, a2, 4
++ beqz a3, L(back_less_16bytes)
++
++ andi a3, a2, 0x3f
++ beq a3, a2, L(back_less_64bytes)
++
++ sub.d t0, a2, a3
++ move a2, a3
++ sub.d a5, a1, t0
++
++L(back_loop_64bytes):
++ LD_64(a1, -64)
++ addi.d a1, a1, -64
++ ST_64(a4, -64)
++
++ addi.d a4, a4, -64
++ bne a1, a5, L(back_loop_64bytes)
++
++L(back_less_64bytes):
++ srai.d a3, a2, 5
++ beqz a3, L(back_less_32bytes)
++
++ ld.d t0, a1, -32
++ ld.d t1, a1, -24
++ ld.d t2, a1, -16
++ ld.d t3, a1, -8
++
++ addi.d a1, a1, -32
++ addi.d a2, a2, -32
++
++ st.d t0, a4, -32
++ st.d t1, a4, -24
++ st.d t2, a4, -16
++ st.d t3, a4, -8
++
++ addi.d a4, a4, -32
++
++L(back_less_32bytes):
++ srai.d a3, a2, 4
++ beqz a3, L(back_less_16bytes)
++
++ ld.d t0, a1, -16
++ ld.d t1, a1, -8
++
++ addi.d a2, a2, -16
++ addi.d a1, a1, -16
++
++ st.d t0, a4, -16
++ st.d t1, a4, -8
++ addi.d a4, a4, -16
++
++L(back_less_16bytes):
++ srai.d a3, a2, 3
++ beqz a3, L(back_less_8bytes)
++
++ ld.d t0, a1, -8
++ addi.d a2, a2, -8
++ addi.d a1, a1, -8
++
++ st.d t0, a4, -8
++ addi.d a4, a4, -8
++
++L(back_less_8bytes):
++ srai.d a3, a2, 2
++ beqz a3, L(back_less_4bytes)
++
++ ld.w t0, a1, -4
++ addi.d a2, a2, -4
++ addi.d a1, a1, -4
++
++ st.w t0, a4, -4
++ addi.d a4, a4, -4
++
++L(back_less_4bytes):
++ srai.d a3, a2, 1
++ beqz a3, L(back_less_2bytes)
++
++ ld.h t0, a1, -2
++ addi.d a2, a2, -2
++ addi.d a1, a1, -2
++
++ st.h t0, a4, -2
++ addi.d a4, a4, -2
++
++L(back_less_2bytes):
++ beqz a2, L(back_less_1byte)
++
++ ld.b t0, a1, -1
++ st.b t0, a4, -1
++
++L(back_less_1byte):
++ jr ra
++
++L(back_unalign):
++ andi t8, a1, 0x7
++ bstrins.d a1, zero, 2, 0
++
++ sub.d a6, zero, t8
++
++ ld.d t0, a1, 0
++ slli.d a6, a6, 3
++ slli.d a5, t8, 3
++ sll.d a7, t0, a6
++
++ srai.d a3, a2, 4
++ beqz a3, L(back_un_less_16bytes)
++
++ andi a3, a2, 0x3f
++ beq a3, a2, L(back_un_less_64bytes)
++
++ sub.d t0, a2, a3
++ move a2, a3
++ sub.d a3, a1, t0
++
++L(back_un_long_bytes):
++ ld.d t0, a1, -8
++ ld.d t1, a1, -16
++ ld.d t2, a1, -24
++ ld.d t3, a1, -32
++
++ sll.d t4, t0, a6
++ srl.d t0, t0, a5
++
++ sll.d t5, t1, a6
++ srl.d t1, t1, a5
++
++ sll.d t6, t2, a6
++ srl.d t2, t2, a5
++
++ sll.d t7, t3, a6
++ srl.d t3, t3, a5
++
++ or t0, t0, a7
++ or t1, t1, t4
++ or t2, t2, t5
++ or t3, t3, t6
++
++ ld.d t4, a1, -40
++ ld.d t5, a1, -48
++ ld.d t6, a1, -56
++ ld.d a7, a1, -64
++ st.d t0, a4, -8
++ st.d t1, a4, -16
++ st.d t2, a4, -24
++ st.d t3, a4, -32
++
++ addi.d a1, a1, -64
++
++ sll.d t0, t4, a6
++ srl.d t4, t4, a5
++
++ sll.d t1, t5, a6
++ srl.d t5, t5, a5
++
++ sll.d t2, t6, a6
++ srl.d t6, t6, a5
++
++ srl.d t3, a7, a5
++ sll.d a7, a7, a6
++
++ or t4, t7, t4
++ or t5, t0, t5
++ or t6, t1, t6
++ or t3, t2, t3
++
++ st.d t4, a4, -40
++ st.d t5, a4, -48
++ st.d t6, a4, -56
++ st.d t3, a4, -64
++
++ addi.d a4, a4, -64
++ bne a3, a1, L(back_un_long_bytes)
++
++L(back_un_less_64bytes):
++ srai.d a3, a2, 5
++ beqz a3, L(back_un_less_32bytes)
++
++ ld.d t0, a1, -8
++ ld.d t1, a1, -16
++ ld.d t2, a1, -24
++ ld.d t3, a1, -32
++
++ addi.d a1, a1, -32
++ addi.d a2, a2, -32
++
++ sll.d t4, t0, a6
++ srl.d t0, t0, a5
++
++ sll.d t5, t1, a6
++ srl.d t1, t1, a5
++
++ sll.d t6, t2, a6
++ srl.d t2, t2, a5
++
++ or t0, a7, t0
++
++ sll.d a7, t3, a6
++ srl.d t3, t3, a5
++
++ or t1, t4, t1
++ or t2, t5, t2
++ or t3, t6, t3
++
++ st.d t0, a4, -8
++ st.d t1, a4, -16
++ st.d t2, a4, -24
++ st.d t3, a4, -32
++
++ addi.d a4, a4, -32
++
++L(back_un_less_32bytes):
++ srai.d a3, a2, 4
++ beqz a3, L(back_un_less_16bytes)
++
++ ld.d t0, a1, -8
++ ld.d t1, a1, -16
++
++ addi.d a1, a1, -16
++ addi.d a2, a2, -16
++
++ sll.d t2, t0, a6
++ srl.d t3, t0, a5
++
++ srl.d t4, t1, a5
++ or t3, a7, t3
++ or t4, t2, t4
++ sll.d a7, t1, a6
++
++ st.d t3, a4, -8
++ st.d t4, a4, -16
++
++ addi.d a4, a4, -16
++
++L(back_un_less_16bytes):
++ srai.d a3, a2, 3
++ beqz a3, L(back_un_less_8bytes)
++
++ ld.d t0, a1, -8
++
++ addi.d a1, a1, -8
++ addi.d a2, a2, -8
++
++ srl.d t1, t0, a5
++ or t2, a7, t1
++ sll.d a7, t0, a6
++
++ st.d t2, a4, -8
++ addi.d a4, a4, -8
++
++L(back_un_less_8bytes):
++ beqz a2, L(back_end)
++ bge t8, a2, 1f
++
++ ld.d t0, a1, -8
++ srl.d t0, t0, a5
++ or a7, a7, t0
++
++1:
++ srai.d a3, a2, 2
++ beqz a3, L(back_un_less_4bytes)
++
++ srai.d t0, a7, 32
++ addi.d a2, a2, -4
++ st.w t0, a4, -4
++ addi.d a4, a4, -4
++ slli.d a7, a7, 32
++
++L(back_un_less_4bytes):
++ srai.d a3, a2, 1
++ beqz a3, L(back_un_less_2bytes)
++ srai.d t0, a7, 48
++ addi.d a2, a2, -2
++ st.h t0, a4, -2
++ addi.d a4, a4, -2
++ slli.d a7, a7, 16
++L(back_un_less_2bytes):
++ beqz a2, L(back_un_less_1byte)
++ srai.d t0, a7, 56
++ st.b t0, a4, -1
++L(back_un_less_1byte):
++ jr ra
++
++L(back_short_data):
++ pcaddi t1, 34
++ slli.d t2, a2, 3
++ sub.d t1, t1, t2
++ jr t1
++
++ ld.b t0, a1, 14
++ st.b t0, a0, 14
++ ld.b t0, a1, 13
++ st.b t0, a0, 13
++ ld.b t0, a1, 12
++ st.b t0, a0, 12
++ ld.b t0, a1, 11
++ st.b t0, a0, 11
++ ld.b t0, a1, 10
++ st.b t0, a0, 10
++ ld.b t0, a1, 9
++ st.b t0, a0, 9
++ ld.b t0, a1, 8
++ st.b t0, a0, 8
++ ld.b t0, a1, 7
++ st.b t0, a0, 7
++ ld.b t0, a1, 6
++ st.b t0, a0, 6
++ ld.b t0, a1, 5
++ st.b t0, a0, 5
++ ld.b t0, a1, 4
++ st.b t0, a0, 4
++ ld.b t0, a1, 3
++ st.b t0, a0, 3
++ ld.b t0, a1, 2
++ st.b t0, a0, 2
++ ld.b t0, a1, 1
++ st.b t0, a0, 1
++ ld.b t0, a1, 0
++ st.b t0, a0, 0
++L(back_end):
++ jr ra
++
++END(MEMCPY_NAME)
++
++libc_hidden_builtin_def (MEMMOVE_NAME)
++libc_hidden_builtin_def (MEMCPY_NAME)
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S b/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S
+new file mode 100644
+index 00000000..4aae5bf8
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S
+@@ -0,0 +1,20 @@
++/* Optimized memcpy implementation using Loongarch LASX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* memcpy is part of memmove.S */
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S b/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S
+new file mode 100644
+index 00000000..6ebbe7a2
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S
+@@ -0,0 +1,20 @@
++/* Optimized memcpy implementation using Loongarch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* memcpy is part of memmove.S */
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S b/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S
+new file mode 100644
+index 00000000..8e60a22d
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S
+@@ -0,0 +1,247 @@
++/* Optimized unaligned memcpy implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++
++# define MEMCPY_NAME __memcpy_unaligned
++
++# define LD_64(reg, n) \
++ ld.d t0, reg, n; \
++ ld.d t1, reg, n + 8; \
++ ld.d t2, reg, n + 16; \
++ ld.d t3, reg, n + 24; \
++ ld.d t4, reg, n + 32; \
++ ld.d t5, reg, n + 40; \
++ ld.d t6, reg, n + 48; \
++ ld.d t7, reg, n + 56;
++
++# define ST_64(reg, n) \
++ st.d t0, reg, n; \
++ st.d t1, reg, n + 8; \
++ st.d t2, reg, n + 16; \
++ st.d t3, reg, n + 24; \
++ st.d t4, reg, n + 32; \
++ st.d t5, reg, n + 40; \
++ st.d t6, reg, n + 48; \
++ st.d t7, reg, n + 56;
++
++LEAF(MEMCPY_NAME, 3)
++ add.d a4, a1, a2
++ add.d a3, a0, a2
++ li.w a6, 16
++ bge a6, a2, L(less_16bytes)
++
++ li.w a6, 128
++ blt a6, a2, L(long_bytes)
++ li.w a6, 64
++ blt a6, a2, L(more_64bytes)
++
++ li.w a6, 32
++ blt a6, a2, L(more_32bytes)
++
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ ld.d t2, a4, -16
++ ld.d t3, a4, -8
++
++ st.d t0, a0, 0
++ st.d t1, a0, 8
++ st.d t2, a3, -16
++ st.d t3, a3, -8
++ jr ra
++
++L(more_64bytes):
++ srli.d t8, a0, 3
++ slli.d t8, t8, 3
++ addi.d t8, t8, 0x8
++ sub.d a7, a0, t8
++
++ ld.d t0, a1, 0
++ sub.d a1, a1, a7
++ st.d t0, a0, 0
++ add.d a7, a7, a2
++ addi.d a7, a7, -0x20
++
++L(loop_32):
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ ld.d t2, a1, 16
++ ld.d t3, a1, 24
++
++ st.d t0, t8, 0
++ st.d t1, t8, 8
++ st.d t2, t8, 16
++ st.d t3, t8, 24
++
++ addi.d t8, t8, 0x20
++ addi.d a1, a1, 0x20
++ addi.d a7, a7, -0x20
++ blt zero, a7, L(loop_32)
++
++ ld.d t4, a4, -32
++ ld.d t5, a4, -24
++ ld.d t6, a4, -16
++ ld.d t7, a4, -8
++
++ st.d t4, a3, -32
++ st.d t5, a3, -24
++ st.d t6, a3, -16
++ st.d t7, a3, -8
++
++ jr ra
++
++L(more_32bytes):
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ ld.d t2, a1, 16
++ ld.d t3, a1, 24
++
++ ld.d t4, a4, -32
++ ld.d t5, a4, -24
++ ld.d t6, a4, -16
++ ld.d t7, a4, -8
++
++ st.d t0, a0, 0
++ st.d t1, a0, 8
++ st.d t2, a0, 16
++ st.d t3, a0, 24
++
++ st.d t4, a3, -32
++ st.d t5, a3, -24
++ st.d t6, a3, -16
++ st.d t7, a3, -8
++
++ jr ra
++
++L(less_16bytes):
++ srai.d a6, a2, 3
++ beqz a6, L(less_8bytes)
++
++ ld.d t0, a1, 0
++ ld.d t1, a4, -8
++ st.d t0, a0, 0
++ st.d t1, a3, -8
++
++ jr ra
++
++L(less_8bytes):
++ srai.d a6, a2, 2
++ beqz a6, L(less_4bytes)
++
++ ld.w t0, a1, 0
++ ld.w t1, a4, -4
++ st.w t0, a0, 0
++ st.w t1, a3, -4
++
++ jr ra
++
++L(less_4bytes):
++ srai.d a6, a2, 1
++ beqz a6, L(less_2bytes)
++
++ ld.h t0, a1, 0
++ ld.h t1, a4, -2
++ st.h t0, a0, 0
++ st.h t1, a3, -2
++
++ jr ra
++
++L(less_2bytes):
++ beqz a2, L(less_1bytes)
++
++ ld.b t0, a1, 0
++ st.b t0, a0, 0
++ jr ra
++
++L(less_1bytes):
++ jr ra
++
++L(long_bytes):
++ srli.d t8, a0, 3
++ slli.d t8, t8, 3
++ beq a0, t8, L(start)
++ ld.d t0, a1, 0
++
++ addi.d t8, t8, 0x8
++ st.d t0, a0, 0
++ sub.d a7, a0, t8
++ sub.d a1, a1, a7
++
++L(start):
++ addi.d a5, a3, -0x80
++ blt a5, t8, L(align_end_proc)
++
++L(loop_128):
++ LD_64(a1, 0)
++ ST_64(t8, 0)
++ LD_64(a1, 64)
++ addi.d a1, a1, 0x80
++ ST_64(t8, 64)
++ addi.d t8, t8, 0x80
++ bge a5, t8, L(loop_128)
++
++L(align_end_proc):
++ sub.d a2, a3, t8
++ pcaddi t1, 34
++ andi t2, a2, 0x78
++ sub.d t1, t1, t2
++ jr t1
++
++ ld.d t0, a1, 112
++ st.d t0, t8, 112
++ ld.d t0, a1, 104
++ st.d t0, t8, 104
++ ld.d t0, a1, 96
++ st.d t0, t8, 96
++ ld.d t0, a1, 88
++ st.d t0, t8, 88
++ ld.d t0, a1, 80
++ st.d t0, t8, 80
++ ld.d t0, a1, 72
++ st.d t0, t8, 72
++ ld.d t0, a1, 64
++ st.d t0, t8, 64
++ ld.d t0, a1, 56
++ st.d t0, t8, 56
++ ld.d t0, a1, 48
++ st.d t0, t8, 48
++ ld.d t0, a1, 40
++ st.d t0, t8, 40
++ ld.d t0, a1, 32
++ st.d t0, t8, 32
++ ld.d t0, a1, 24
++ st.d t0, t8, 24
++ ld.d t0, a1, 16
++ st.d t0, t8, 16
++ ld.d t0, a1, 8
++ st.d t0, t8, 8
++ ld.d t0, a1, 0
++ st.d t0, t8, 0
++ ld.d t0, a4, -8
++ st.d t0, a3, -8
++
++ jr ra
++END(MEMCPY_NAME)
++
++libc_hidden_builtin_def (MEMCPY_NAME)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy.c b/sysdeps/loongarch/lp64/multiarch/memcpy.c
+new file mode 100644
+index 00000000..93b238ce
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memcpy.c
+@@ -0,0 +1,37 @@
++/* Multiple versions of memcpy.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define memcpy __redirect_memcpy
++# include <string.h>
++# undef memcpy
++
++# define SYMBOL_NAME memcpy
++# include "ifunc-lasx.h"
++
++libc_ifunc_redirected (__redirect_memcpy, memcpy,
++ IFUNC_SELECTOR ());
++
++# ifdef SHARED
++__hidden_ver1 (memcpy, __GI_memcpy, __redirect_memcpy)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memcmp);
++# endif
++
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S b/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S
+new file mode 100644
+index 00000000..5354f383
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S
+@@ -0,0 +1,20 @@
++/* Optimized memmove_aligned implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* memmove_aligned is part of memcpy_aligned, see memcpy-aligned.S. */
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S b/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S
+new file mode 100644
+index 00000000..ff68e7a2
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S
+@@ -0,0 +1,287 @@
++/* Optimized memmove implementation using Loongarch LASX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++#ifndef MEMCPY_NAME
++# define MEMCPY_NAME __memcpy_lasx
++#endif
++
++#ifndef MEMMOVE_NAME
++# define MEMMOVE_NAME __memmove_lasx
++#endif
++
++LEAF(MEMCPY_NAME, 6)
++ li.d t0, 32
++ add.d a3, a0, a2
++ add.d a4, a1, a2
++ bgeu t0, a2, L(less_32bytes)
++
++ li.d t1, 64
++ bltu t1, a2, L(copy_long)
++ xvld xr0, a1, 0
++ xvld xr1, a4, -32
++
++ xvst xr0, a0, 0
++ xvst xr1, a3, -32
++ jr ra
++L(less_32bytes):
++ srli.d t0, a2, 4
++
++ beqz t0, L(less_16bytes)
++ vld vr0, a1, 0
++ vld vr1, a4, -16
++ vst vr0, a0, 0
++
++
++ vst vr1, a3, -16
++ jr ra
++L(less_16bytes):
++ srli.d t0, a2, 3
++ beqz t0, L(less_8bytes)
++
++ ld.d t0, a1, 0
++ ld.d t1, a4, -8
++ st.d t0, a0, 0
++ st.d t1, a3, -8
++
++ jr ra
++L(less_8bytes):
++ srli.d t0, a2, 2
++ beqz t0, L(less_4bytes)
++ ld.w t0, a1, 0
++
++ ld.w t1, a4, -4
++ st.w t0, a0, 0
++ st.w t1, a3, -4
++ jr ra
++
++
++L(less_4bytes):
++ srli.d t0, a2, 1
++ beqz t0, L(less_2bytes)
++ ld.h t0, a1, 0
++ ld.h t1, a4, -2
++
++ st.h t0, a0, 0
++ st.h t1, a3, -2
++ jr ra
++L(less_2bytes):
++ beqz a2, L(less_1bytes)
++
++ ld.b t0, a1, 0
++ st.b t0, a0, 0
++L(less_1bytes):
++ jr ra
++END(MEMCPY_NAME)
++
++LEAF(MEMMOVE_NAME, 6)
++
++ li.d t0, 32
++ add.d a3, a0, a2
++ add.d a4, a1, a2
++ bgeu t0, a2, L(less_32bytes)
++
++ li.d t1, 64
++ bltu t1, a2, L(move_long)
++ xvld xr0, a1, 0
++ xvld xr1, a4, -32
++
++ xvst xr0, a0, 0
++ xvst xr1, a3, -32
++ jr ra
++L(move_long):
++ sub.d t2, a0, a1
++
++ bltu t2, a2, L(copy_back)
++L(copy_long):
++ andi t2, a0, 0x1f
++ addi.d a2, a2, -1
++ sub.d t2, t0, t2
++
++
++ xvld xr8, a1, 0
++ xvld xr9, a4, -32
++ sub.d t3, a2, t2
++ add.d a5, a0, t2
++
++ andi a2, t3, 0xff
++ add.d a1, a1, t2
++ beq a2, t3, L(lt256)
++ sub.d a6, a4, a2
++
++ addi.d a6, a6, -1
++L(loop_256):
++ xvld xr0, a1, 0
++ xvld xr1, a1, 32
++ xvld xr2, a1, 64
++
++ xvld xr3, a1, 96
++ xvld xr4, a1, 128
++ xvld xr5, a1, 160
++ xvld xr6, a1, 192
++
++
++ xvld xr7, a1, 224
++ addi.d a1, a1, 256
++ xvst xr0, a5, 0
++ xvst xr1, a5, 32
++
++ xvst xr2, a5, 64
++ xvst xr3, a5, 96
++ xvst xr4, a5, 128
++ xvst xr5, a5, 160
++
++ xvst xr6, a5, 192
++ xvst xr7, a5, 224
++ addi.d a5, a5, 256
++ bne a1, a6, L(loop_256)
++
++L(lt256):
++ srli.d t2, a2, 7
++ beqz t2, L(lt128)
++ xvld xr0, a1, 0
++ xvld xr1, a1, 32
++
++
++ xvld xr2, a1, 64
++ xvld xr3, a1, 96
++ addi.d a1, a1, 128
++ addi.d a2, a2, -128
++
++ xvst xr0, a5, 0
++ xvst xr1, a5, 32
++ xvst xr2, a5, 64
++ xvst xr3, a5, 96
++
++ addi.d a5, a5, 128
++L(lt128):
++ bltu a2, t1, L(lt64)
++ xvld xr0, a1, 0
++ xvld xr1, a1, 32
++
++ addi.d a1, a1, 64
++ addi.d a2, a2, -64
++ xvst xr0, a5, 0
++ xvst xr1, a5, 32
++
++
++ addi.d a5, a5, 64
++L(lt64):
++ bltu a2, t0, L(lt32)
++ xvld xr0, a1, 0
++ xvst xr0, a5, 0
++
++L(lt32):
++ xvst xr8, a0, 0
++ xvst xr9, a3, -32
++ jr ra
++ nop
++
++L(copy_back):
++ addi.d a3, a3, -1
++ addi.d a2, a2, -2
++ andi t2, a3, 0x1f
++ xvld xr8, a1, 0
++
++ xvld xr9, a4, -32
++ sub.d t3, a2, t2
++ sub.d a5, a3, t2
++ sub.d a4, a4, t2
++
++
++ andi a2, t3, 0xff
++ beq a2, t3, L(back_lt256)
++ add.d a6, a1, a2
++ addi.d a6, a6, 2
++
++L(back_loop_256):
++ xvld xr0, a4, -33
++ xvld xr1, a4, -65
++ xvld xr2, a4, -97
++ xvld xr3, a4, -129
++
++ xvld xr4, a4, -161
++ xvld xr5, a4, -193
++ xvld xr6, a4, -225
++ xvld xr7, a4, -257
++
++ addi.d a4, a4, -256
++ xvst xr0, a5, -32
++ xvst xr1, a5, -64
++ xvst xr2, a5, -96
++
++
++ xvst xr3, a5, -128
++ xvst xr4, a5, -160
++ xvst xr5, a5, -192
++ xvst xr6, a5, -224
++
++ xvst xr7, a5, -256
++ addi.d a5, a5, -256
++ bne a4, a6, L(back_loop_256)
++L(back_lt256):
++ srli.d t2, a2, 7
++
++ beqz t2, L(back_lt128)
++ xvld xr0, a4, -33
++ xvld xr1, a4, -65
++ xvld xr2, a4, -97
++
++ xvld xr3, a4, -129
++ addi.d a2, a2, -128
++ addi.d a4, a4, -128
++ xvst xr0, a5, -32
++
++
++ xvst xr1, a5, -64
++ xvst xr2, a5, -96
++ xvst xr3, a5, -128
++ addi.d a5, a5, -128
++
++L(back_lt128):
++ blt a2, t1, L(back_lt64)
++ xvld xr0, a4, -33
++ xvld xr1, a4, -65
++ addi.d a2, a2, -64
++
++ addi.d a4, a4, -64
++ xvst xr0, a5, -32
++ xvst xr1, a5, -64
++ addi.d a5, a5, -64
++
++L(back_lt64):
++ bltu a2, t0, L(back_lt32)
++ xvld xr0, a4, -33
++ xvst xr0, a5, -32
++L(back_lt32):
++ xvst xr8, a0, 0
++
++
++ xvst xr9, a3, -31
++ jr ra
++END(MEMMOVE_NAME)
++
++libc_hidden_builtin_def (MEMCPY_NAME)
++libc_hidden_builtin_def (MEMMOVE_NAME)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S b/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
+new file mode 100644
+index 00000000..9e1502a7
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
+@@ -0,0 +1,534 @@
++/* Optimized memmove implementation using Loongarch LSX instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++# define MEMCPY_NAME __memcpy_lsx
++# define MEMMOVE_NAME __memmove_lsx
++
++LEAF(MEMCPY_NAME, 6)
++ li.d t6, 16
++ add.d a3, a0, a2
++ add.d a4, a1, a2
++ bgeu t6, a2, L(less_16bytes)
++
++ li.d t8, 64
++ li.d t7, 32
++ bltu t8, a2, L(copy_long)
++ bltu t7, a2, L(more_32bytes)
++
++ vld vr0, a1, 0
++ vld vr1, a4, -16
++ vst vr0, a0, 0
++ vst vr1, a3, -16
++
++ jr ra
++L(more_32bytes):
++ vld vr0, a1, 0
++ vld vr1, a1, 16
++ vld vr2, a4, -32
++
++
++ vld vr3, a4, -16
++ vst vr0, a0, 0
++ vst vr1, a0, 16
++ vst vr2, a3, -32
++
++ vst vr3, a3, -16
++ jr ra
++L(less_16bytes):
++ srli.d t0, a2, 3
++ beqz t0, L(less_8bytes)
++
++ vldrepl.d vr0, a1, 0
++ vldrepl.d vr1, a4, -8
++ vstelm.d vr0, a0, 0, 0
++ vstelm.d vr1, a3, -8, 0
++
++ jr ra
++L(less_8bytes):
++ srli.d t0, a2, 2
++ beqz t0, L(less_4bytes)
++ vldrepl.w vr0, a1, 0
++
++
++ vldrepl.w vr1, a4, -4
++ vstelm.w vr0, a0, 0, 0
++ vstelm.w vr1, a3, -4, 0
++ jr ra
++
++L(less_4bytes):
++ srli.d t0, a2, 1
++ beqz t0, L(less_2bytes)
++ vldrepl.h vr0, a1, 0
++ vldrepl.h vr1, a4, -2
++
++ vstelm.h vr0, a0, 0, 0
++ vstelm.h vr1, a3, -2, 0
++ jr ra
++L(less_2bytes):
++ beqz a2, L(less_1bytes)
++
++ ld.b t0, a1, 0
++ st.b t0, a0, 0
++L(less_1bytes):
++ jr ra
++ nop
++END(MEMCPY_NAME)
++
++LEAF(MEMMOVE_NAME, 6)
++ li.d t6, 16
++ add.d a3, a0, a2
++ add.d a4, a1, a2
++ bgeu t6, a2, L(less_16bytes)
++
++ li.d t8, 64
++ li.d t7, 32
++ bltu t8, a2, L(move_long)
++ bltu t7, a2, L(more_32bytes)
++
++ vld vr0, a1, 0
++ vld vr1, a4, -16
++ vst vr0, a0, 0
++ vst vr1, a3, -16
++
++ jr ra
++ nop
++L(move_long):
++ sub.d t0, a0, a1
++ bltu t0, a2, L(copy_back)
++
++
++L(copy_long):
++ vld vr2, a1, 0
++ andi t0, a0, 0xf
++ sub.d t0, t6, t0
++ add.d a1, a1, t0
++
++ sub.d a2, a2, t0
++ andi t1, a1, 0xf
++ bnez t1, L(unaligned)
++ vld vr0, a1, 0
++
++ addi.d a2, a2, -16
++ vst vr2, a0, 0
++ andi t2, a2, 0x7f
++ add.d a5, a0, t0
++
++ beq a2, t2, L(al_less_128)
++ sub.d t3, a2, t2
++ move a2, t2
++ add.d a6, a1, t3
++
++
++L(al_loop):
++ vld vr1, a1, 16
++ vld vr2, a1, 32
++ vld vr3, a1, 48
++ vld vr4, a1, 64
++
++ vld vr5, a1, 80
++ vld vr6, a1, 96
++ vld vr7, a1, 112
++ vst vr0, a5, 0
++
++ vld vr0, a1, 128
++ addi.d a1, a1, 128
++ vst vr1, a5, 16
++ vst vr2, a5, 32
++
++ vst vr3, a5, 48
++ vst vr4, a5, 64
++ vst vr5, a5, 80
++ vst vr6, a5, 96
++
++
++ vst vr7, a5, 112
++ addi.d a5, a5, 128
++ bne a1, a6, L(al_loop)
++L(al_less_128):
++ blt a2, t8, L(al_less_64)
++
++ vld vr1, a1, 16
++ vld vr2, a1, 32
++ vld vr3, a1, 48
++ addi.d a2, a2, -64
++
++ vst vr0, a5, 0
++ vld vr0, a1, 64
++ addi.d a1, a1, 64
++ vst vr1, a5, 16
++
++ vst vr2, a5, 32
++ vst vr3, a5, 48
++ addi.d a5, a5, 64
++L(al_less_64):
++ blt a2, t7, L(al_less_32)
++
++
++ vld vr1, a1, 16
++ addi.d a2, a2, -32
++ vst vr0, a5, 0
++ vld vr0, a1, 32
++
++ addi.d a1, a1, 32
++ vst vr1, a5, 16
++ addi.d a5, a5, 32
++L(al_less_32):
++ blt a2, t6, L(al_less_16)
++
++ vst vr0, a5, 0
++ vld vr0, a1, 16
++ addi.d a5, a5, 16
++L(al_less_16):
++ vld vr1, a4, -16
++
++ vst vr0, a5, 0
++ vst vr1, a3, -16
++ jr ra
++ nop
++
++
++L(magic_num):
++ .dword 0x0706050403020100
++ .dword 0x0f0e0d0c0b0a0908
++L(unaligned):
++ pcaddi t2, -4
++ bstrins.d a1, zero, 3, 0
++ vld vr8, t2, 0
++ vld vr0, a1, 0
++
++ vld vr1, a1, 16
++ addi.d a2, a2, -16
++ vst vr2, a0, 0
++ add.d a5, a0, t0
++
++ vreplgr2vr.b vr9, t1
++ andi t2, a2, 0x7f
++ vadd.b vr9, vr9, vr8
++ addi.d a1, a1, 32
++
++
++ beq t2, a2, L(un_less_128)
++ sub.d t3, a2, t2
++ move a2, t2
++ add.d a6, a1, t3
++
++L(un_loop):
++ vld vr2, a1, 0
++ vld vr3, a1, 16
++ vld vr4, a1, 32
++ vld vr5, a1, 48
++
++ vld vr6, a1, 64
++ vld vr7, a1, 80
++ vshuf.b vr8, vr1, vr0, vr9
++ vld vr0, a1, 96
++
++ vst vr8, a5, 0
++ vshuf.b vr8, vr2, vr1, vr9
++ vld vr1, a1, 112
++ vst vr8, a5, 16
++
++
++ addi.d a1, a1, 128
++ vshuf.b vr2, vr3, vr2, vr9
++ vshuf.b vr3, vr4, vr3, vr9
++ vst vr2, a5, 32
++
++ vshuf.b vr4, vr5, vr4, vr9
++ vst vr3, a5, 48
++ vshuf.b vr5, vr6, vr5, vr9
++ vst vr4, a5, 64
++
++ vshuf.b vr6, vr7, vr6, vr9
++ vst vr5, a5, 80
++ vshuf.b vr7, vr0, vr7, vr9
++ vst vr6, a5, 96
++
++ vst vr7, a5, 112
++ addi.d a5, a5, 128
++ bne a1, a6, L(un_loop)
++L(un_less_128):
++ blt a2, t8, L(un_less_64)
++
++
++ vld vr2, a1, 0
++ vld vr3, a1, 16
++ vshuf.b vr4, vr1, vr0, vr9
++ vld vr0, a1, 32
++
++ vst vr4, a5, 0
++ addi.d a2, a2, -64
++ vshuf.b vr4, vr2, vr1, vr9
++ vld vr1, a1, 48
++
++ addi.d a1, a1, 64
++ vst vr4, a5, 16
++ vshuf.b vr2, vr3, vr2, vr9
++ vshuf.b vr3, vr0, vr3, vr9
++
++ vst vr2, a5, 32
++ vst vr3, a5, 48
++ addi.d a5, a5, 64
++L(un_less_64):
++ blt a2, t7, L(un_less_32)
++
++
++ vshuf.b vr3, vr1, vr0, vr9
++ vld vr0, a1, 0
++ vst vr3, a5, 0
++ addi.d a2, a2, -32
++
++ vshuf.b vr3, vr0, vr1, vr9
++ vld vr1, a1, 16
++ addi.d a1, a1, 32
++ vst vr3, a5, 16
++
++ addi.d a5, a5, 32
++L(un_less_32):
++ blt a2, t6, L(un_less_16)
++ vshuf.b vr2, vr1, vr0, vr9
++ vor.v vr0, vr1, vr1
++
++ vld vr1, a1, 0
++ vst vr2, a5, 0
++ addi.d a5, a5, 16
++L(un_less_16):
++ vld vr2, a4, -16
++
++
++ vshuf.b vr0, vr1, vr0, vr9
++ vst vr0, a5, 0
++ vst vr2, a3, -16
++ jr ra
++
++L(copy_back):
++ addi.d t0, a3, -1
++ vld vr2, a4, -16
++ andi t0, t0, 0xf
++ addi.d t0, t0, 1
++
++ sub.d a4, a4, t0
++ sub.d a2, a2, t0
++ andi t1, a4, 0xf
++ bnez t1, L(back_unaligned)
++
++ vld vr0, a4, -16
++ addi.d a2, a2, -16
++ vst vr2, a3, -16
++ andi t2, a2, 0x7f
++
++
++ sub.d a3, a3, t0
++ beq t2, a2, L(back_al_less_128)
++ sub.d t3, a2, t2
++ move a2, t2
++
++ sub.d a6, a4, t3
++L(back_al_loop):
++ vld vr1, a4, -32
++ vld vr2, a4, -48
++ vld vr3, a4, -64
++
++ vld vr4, a4, -80
++ vld vr5, a4, -96
++ vld vr6, a4, -112
++ vld vr7, a4, -128
++
++ vst vr0, a3, -16
++ vld vr0, a4, -144
++ addi.d a4, a4, -128
++ vst vr1, a3, -32
++
++
++ vst vr2, a3, -48
++ vst vr3, a3, -64
++ vst vr4, a3, -80
++ vst vr5, a3, -96
++
++ vst vr6, a3, -112
++ vst vr7, a3, -128
++ addi.d a3, a3, -128
++ bne a4, a6, L(back_al_loop)
++
++L(back_al_less_128):
++ blt a2, t8, L(back_al_less_64)
++ vld vr1, a4, -32
++ vld vr2, a4, -48
++ vld vr3, a4, -64
++
++ addi.d a2, a2, -64
++ vst vr0, a3, -16
++ vld vr0, a4, -80
++ addi.d a4, a4, -64
++
++
++ vst vr1, a3, -32
++ vst vr2, a3, -48
++ vst vr3, a3, -64
++ addi.d a3, a3, -64
++
++L(back_al_less_64):
++ blt a2, t7, L(back_al_less_32)
++ vld vr1, a4, -32
++ addi.d a2, a2, -32
++ vst vr0, a3, -16
++
++ vld vr0, a4, -48
++ vst vr1, a3, -32
++ addi.d a3, a3, -32
++ addi.d a4, a4, -32
++
++L(back_al_less_32):
++ blt a2, t6, L(back_al_less_16)
++ vst vr0, a3, -16
++ vld vr0, a4, -32
++ addi.d a3, a3, -16
++
++
++L(back_al_less_16):
++ vld vr1, a1, 0
++ vst vr0, a3, -16
++ vst vr1, a0, 0
++ jr ra
++
++L(magic_num_2):
++ .dword 0x0706050403020100
++ .dword 0x0f0e0d0c0b0a0908
++L(back_unaligned):
++ pcaddi t2, -4
++ bstrins.d a4, zero, 3, 0
++ vld vr8, t2, 0
++ vld vr0, a4, 0
++
++ vld vr1, a4, -16
++ addi.d a2, a2, -16
++ vst vr2, a3, -16
++ sub.d a3, a3, t0
++
++
++ vreplgr2vr.b vr9, t1
++ andi t2, a2, 0x7f
++ vadd.b vr9, vr9, vr8
++ addi.d a4, a4, -16
++
++ beq t2, a2, L(back_un_less_128)
++ sub.d t3, a2, t2
++ move a2, t2
++ sub.d a6, a4, t3
++
++L(back_un_loop):
++ vld vr2, a4, -16
++ vld vr3, a4, -32
++ vld vr4, a4, -48
++
++ vld vr5, a4, -64
++ vld vr6, a4, -80
++ vld vr7, a4, -96
++ vshuf.b vr8, vr0, vr1, vr9
++
++
++ vld vr0, a4, -112
++ vst vr8, a3, -16
++ vshuf.b vr8, vr1, vr2, vr9
++ vld vr1, a4, -128
++
++ vst vr8, a3, -32
++ addi.d a4, a4, -128
++ vshuf.b vr2, vr2, vr3, vr9
++ vshuf.b vr3, vr3, vr4, vr9
++
++ vst vr2, a3, -48
++ vshuf.b vr4, vr4, vr5, vr9
++ vst vr3, a3, -64
++ vshuf.b vr5, vr5, vr6, vr9
++
++ vst vr4, a3, -80
++ vshuf.b vr6, vr6, vr7, vr9
++ vst vr5, a3, -96
++ vshuf.b vr7, vr7, vr0, vr9
++
++
++ vst vr6, a3, -112
++ vst vr7, a3, -128
++ addi.d a3, a3, -128
++ bne a4, a6, L(back_un_loop)
++
++L(back_un_less_128):
++ blt a2, t8, L(back_un_less_64)
++ vld vr2, a4, -16
++ vld vr3, a4, -32
++ vshuf.b vr4, vr0, vr1, vr9
++
++ vld vr0, a4, -48
++ vst vr4, a3, -16
++ addi.d a2, a2, -64
++ vshuf.b vr4, vr1, vr2, vr9
++
++ vld vr1, a4, -64
++ addi.d a4, a4, -64
++ vst vr4, a3, -32
++ vshuf.b vr2, vr2, vr3, vr9
++
++
++ vshuf.b vr3, vr3, vr0, vr9
++ vst vr2, a3, -48
++ vst vr3, a3, -64
++ addi.d a3, a3, -64
++
++L(back_un_less_64):
++ blt a2, t7, L(back_un_less_32)
++ vshuf.b vr3, vr0, vr1, vr9
++ vld vr0, a4, -16
++ vst vr3, a3, -16
++
++ addi.d a2, a2, -32
++ vshuf.b vr3, vr1, vr0, vr9
++ vld vr1, a4, -32
++ addi.d a4, a4, -32
++
++ vst vr3, a3, -32
++ addi.d a3, a3, -32
++L(back_un_less_32):
++ blt a2, t6, L(back_un_less_16)
++ vshuf.b vr2, vr0, vr1, vr9
++
++
++ vor.v vr0, vr1, vr1
++ vld vr1, a4, -16
++ vst vr2, a3, -16
++ addi.d a3, a3, -16
++
++L(back_un_less_16):
++ vld vr2, a1, 0
++ vshuf.b vr0, vr0, vr1, vr9
++ vst vr0, a3, -16
++ vst vr2, a0, 0
++
++ jr ra
++END(MEMMOVE_NAME)
++
++libc_hidden_builtin_def (MEMCPY_NAME)
++libc_hidden_builtin_def (MEMMOVE_NAME)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S b/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S
+new file mode 100644
+index 00000000..90a64b6b
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S
+@@ -0,0 +1,380 @@
++/* Optimized memmove_unaligned implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++
++# define MEMMOVE_NAME __memmove_unaligned
++
++# define LD_64(reg, n) \
++ ld.d t0, reg, n; \
++ ld.d t1, reg, n + 8; \
++ ld.d t2, reg, n + 16; \
++ ld.d t3, reg, n + 24; \
++ ld.d t4, reg, n + 32; \
++ ld.d t5, reg, n + 40; \
++ ld.d t6, reg, n + 48; \
++ ld.d t7, reg, n + 56;
++
++# define ST_64(reg, n) \
++ st.d t0, reg, n; \
++ st.d t1, reg, n + 8; \
++ st.d t2, reg, n + 16; \
++ st.d t3, reg, n + 24; \
++ st.d t4, reg, n + 32; \
++ st.d t5, reg, n + 40; \
++ st.d t6, reg, n + 48; \
++ st.d t7, reg, n + 56;
++
++LEAF(MEMMOVE_NAME, 3)
++ add.d a4, a1, a2
++ add.d a3, a0, a2
++ beq a1, a0, L(less_1bytes)
++ move t8, a0
++
++ srai.d a6, a2, 4
++ beqz a6, L(less_16bytes)
++ srai.d a6, a2, 6
++ bnez a6, L(more_64bytes)
++ srai.d a6, a2, 5
++ beqz a6, L(less_32bytes)
++
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ ld.d t2, a1, 16
++ ld.d t3, a1, 24
++
++ ld.d t4, a4, -32
++ ld.d t5, a4, -24
++ ld.d t6, a4, -16
++ ld.d t7, a4, -8
++
++ st.d t0, a0, 0
++ st.d t1, a0, 8
++ st.d t2, a0, 16
++ st.d t3, a0, 24
++
++ st.d t4, a3, -32
++ st.d t5, a3, -24
++ st.d t6, a3, -16
++ st.d t7, a3, -8
++
++ jr ra
++
++L(less_32bytes):
++ ld.d t0, a1, 0
++ ld.d t1, a1, 8
++ ld.d t2, a4, -16
++ ld.d t3, a4, -8
++
++ st.d t0, a0, 0
++ st.d t1, a0, 8
++ st.d t2, a3, -16
++ st.d t3, a3, -8
++
++ jr ra
++
++L(less_16bytes):
++ srai.d a6, a2, 3
++ beqz a6, L(less_8bytes)
++
++ ld.d t0, a1, 0
++ ld.d t1, a4, -8
++ st.d t0, a0, 0
++ st.d t1, a3, -8
++
++ jr ra
++
++L(less_8bytes):
++ srai.d a6, a2, 2
++ beqz a6, L(less_4bytes)
++
++ ld.w t0, a1, 0
++ ld.w t1, a4, -4
++ st.w t0, a0, 0
++ st.w t1, a3, -4
++
++ jr ra
++
++L(less_4bytes):
++ srai.d a6, a2, 1
++ beqz a6, L(less_2bytes)
++
++ ld.h t0, a1, 0
++ ld.h t1, a4, -2
++ st.h t0, a0, 0
++ st.h t1, a3, -2
++
++ jr ra
++
++L(less_2bytes):
++ beqz a2, L(less_1bytes)
++
++ ld.b t0, a1, 0
++ st.b t0, a0, 0
++
++ jr ra
++
++L(less_1bytes):
++ jr ra
++
++L(more_64bytes):
++ sub.d a7, a0, a1
++ bltu a7, a2, L(copy_backward)
++
++L(copy_forward):
++ srli.d a0, a0, 3
++ slli.d a0, a0, 3
++ beq a0, t8, L(all_align)
++ addi.d a0, a0, 0x8
++ sub.d a7, t8, a0
++ sub.d a1, a1, a7
++ add.d a2, a7, a2
++
++L(start_unalign_proc):
++ pcaddi t1, 18
++ slli.d a6, a7, 3
++ add.d t1, t1, a6
++ jr t1
++
++ ld.b t0, a1, -7
++ st.b t0, a0, -7
++ ld.b t0, a1, -6
++ st.b t0, a0, -6
++ ld.b t0, a1, -5
++ st.b t0, a0, -5
++ ld.b t0, a1, -4
++ st.b t0, a0, -4
++ ld.b t0, a1, -3
++ st.b t0, a0, -3
++ ld.b t0, a1, -2
++ st.b t0, a0, -2
++ ld.b t0, a1, -1
++ st.b t0, a0, -1
++L(start_over):
++
++ addi.d a2, a2, -0x80
++ blt a2, zero, L(end_unalign_proc)
++
++L(loop_less):
++ LD_64(a1, 0)
++ ST_64(a0, 0)
++ LD_64(a1, 64)
++ ST_64(a0, 64)
++
++ addi.d a0, a0, 0x80
++ addi.d a1, a1, 0x80
++ addi.d a2, a2, -0x80
++ bge a2, zero, L(loop_less)
++
++L(end_unalign_proc):
++ addi.d a2, a2, 0x80
++
++ pcaddi t1, 36
++ andi t2, a2, 0x78
++ add.d a1, a1, t2
++ add.d a0, a0, t2
++ sub.d t1, t1, t2
++ jr t1
++
++ ld.d t0, a1, -120
++ st.d t0, a0, -120
++ ld.d t0, a1, -112
++ st.d t0, a0, -112
++ ld.d t0, a1, -104
++ st.d t0, a0, -104
++ ld.d t0, a1, -96
++ st.d t0, a0, -96
++ ld.d t0, a1, -88
++ st.d t0, a0, -88
++ ld.d t0, a1, -80
++ st.d t0, a0, -80
++ ld.d t0, a1, -72
++ st.d t0, a0, -72
++ ld.d t0, a1, -64
++ st.d t0, a0, -64
++ ld.d t0, a1, -56
++ st.d t0, a0, -56
++ ld.d t0, a1, -48
++ st.d t0, a0, -48
++ ld.d t0, a1, -40
++ st.d t0, a0, -40
++ ld.d t0, a1, -32
++ st.d t0, a0, -32
++ ld.d t0, a1, -24
++ st.d t0, a0, -24
++ ld.d t0, a1, -16
++ st.d t0, a0, -16
++ ld.d t0, a1, -8
++ st.d t0, a0, -8
++
++ andi a2, a2, 0x7
++ pcaddi t1, 18
++ slli.d a2, a2, 3
++ sub.d t1, t1, a2
++ jr t1
++
++ ld.b t0, a4, -7
++ st.b t0, a3, -7
++ ld.b t0, a4, -6
++ st.b t0, a3, -6
++ ld.b t0, a4, -5
++ st.b t0, a3, -5
++ ld.b t0, a4, -4
++ st.b t0, a3, -4
++ ld.b t0, a4, -3
++ st.b t0, a3, -3
++ ld.b t0, a4, -2
++ st.b t0, a3, -2
++ ld.b t0, a4, -1
++ st.b t0, a3, -1
++L(end):
++ move a0, t8
++ jr ra
++
++L(all_align):
++ addi.d a1, a1, 0x8
++ addi.d a0, a0, 0x8
++ ld.d t0, a1, -8
++ st.d t0, a0, -8
++ addi.d a2, a2, -8
++ b L(start_over)
++
++L(all_align_back):
++ addi.d a4, a4, -0x8
++ addi.d a3, a3, -0x8
++ ld.d t0, a4, 0
++ st.d t0, a3, 0
++ addi.d a2, a2, -8
++ b L(start_over_back)
++
++L(copy_backward):
++ move a5, a3
++ srli.d a3, a3, 3
++ slli.d a3, a3, 3
++ beq a3, a5, L(all_align_back)
++ sub.d a7, a3, a5
++ add.d a4, a4, a7
++ add.d a2, a7, a2
++
++ pcaddi t1, 18
++ slli.d a6, a7, 3
++ add.d t1, t1, a6
++ jr t1
++
++ ld.b t0, a4, 6
++ st.b t0, a3, 6
++ ld.b t0, a4, 5
++ st.b t0, a3, 5
++ ld.b t0, a4, 4
++ st.b t0, a3, 4
++ ld.b t0, a4, 3
++ st.b t0, a3, 3
++ ld.b t0, a4, 2
++ st.b t0, a3, 2
++ ld.b t0, a4, 1
++ st.b t0, a3, 1
++ ld.b t0, a4, 0
++ st.b t0, a3, 0
++L(start_over_back):
++ addi.d a2, a2, -0x80
++ blt a2, zero, L(end_unalign_proc_back)
++
++L(loop_less_back):
++ LD_64(a4, -64)
++ ST_64(a3, -64)
++ LD_64(a4, -128)
++ ST_64(a3, -128)
++
++ addi.d a4, a4, -0x80
++ addi.d a3, a3, -0x80
++ addi.d a2, a2, -0x80
++ bge a2, zero, L(loop_less_back)
++
++L(end_unalign_proc_back):
++ addi.d a2, a2, 0x80
++
++ pcaddi t1, 36
++ andi t2, a2, 0x78
++ sub.d a4, a4, t2
++ sub.d a3, a3, t2
++ sub.d t1, t1, t2
++ jr t1
++
++ ld.d t0, a4, 112
++ st.d t0, a3, 112
++ ld.d t0, a4, 104
++ st.d t0, a3, 104
++ ld.d t0, a4, 96
++ st.d t0, a3, 96
++ ld.d t0, a4, 88
++ st.d t0, a3, 88
++ ld.d t0, a4, 80
++ st.d t0, a3, 80
++ ld.d t0, a4, 72
++ st.d t0, a3, 72
++ ld.d t0, a4, 64
++ st.d t0, a3, 64
++ ld.d t0, a4, 56
++ st.d t0, a3, 56
++ ld.d t0, a4, 48
++ st.d t0, a3, 48
++ ld.d t0, a4, 40
++ st.d t0, a3, 40
++ ld.d t0, a4, 32
++ st.d t0, a3, 32
++ ld.d t0, a4, 24
++ st.d t0, a3, 24
++ ld.d t0, a4, 16
++ st.d t0, a3, 16
++ ld.d t0, a4, 8
++ st.d t0, a3, 8
++ ld.d t0, a4, 0
++ st.d t0, a3, 0
++
++ andi a2, a2, 0x7
++ pcaddi t1, 18
++ slli.d a2, a2, 3
++ sub.d t1, t1, a2
++ jr t1
++
++ ld.b t0, a1, 6
++ st.b t0, a0, 6
++ ld.b t0, a1, 5
++ st.b t0, a0, 5
++ ld.b t0, a1, 4
++ st.b t0, a0, 4
++ ld.b t0, a1, 3
++ st.b t0, a0, 3
++ ld.b t0, a1, 2
++ st.b t0, a0, 2
++ ld.b t0, a1, 1
++ st.b t0, a0, 1
++ ld.b t0, a1, 0
++ st.b t0, a0, 0
++
++ move a0, t8
++ jr ra
++END(MEMMOVE_NAME)
++
++libc_hidden_builtin_def (MEMMOVE_NAME)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/memmove.c b/sysdeps/loongarch/lp64/multiarch/memmove.c
+new file mode 100644
+index 00000000..7e3ca4c4
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/memmove.c
+@@ -0,0 +1,38 @@
++/* Multiple versions of memmove.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define memmove __redirect_memmove
++# include <string.h>
++# undef memmove
++
++# define SYMBOL_NAME memmove
++# include "ifunc-lasx.h"
++
++libc_ifunc_redirected (__redirect_memmove, __libc_memmove,
++ IFUNC_SELECTOR ());
++strong_alias (__libc_memmove, memmove);
++
++# ifdef SHARED
++__hidden_ver1 (__libc_memmove, __GI_memmove, __redirect_memmove)
++ __attribute__ ((visibility ("hidden")));
++# endif
++
++#endif
+--
+2.33.0
+
diff --git a/Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch b/Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch
new file mode 100644
index 0000000..03e1299
--- /dev/null
+++ b/Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch
@@ -0,0 +1,706 @@
+From aca7d7f0dde5f56344e8e58e5f6648c96bb1f1cc Mon Sep 17 00:00:00 2001
+From: dengjianbo <dengjianbo@loongson.cn>
+Date: Tue, 15 Aug 2023 09:08:11 +0800
+Subject: [PATCH 06/29] Loongarch: Add ifunc support for strchr{aligned, lsx,
+ lasx} and strchrnul{aligned, lsx, lasx}
+
+These implementations improve the time to run strchr{nul}
+microbenchmark in glibc as below:
+strchr-lasx reduces the runtime about 50%-83%
+strchr-lsx reduces the runtime about 30%-67%
+strchr-aligned reduces the runtime about 10%-20%
+strchrnul-lasx reduces the runtime about 50%-83%
+strchrnul-lsx reduces the runtime about 36%-65%
+strchrnul-aligned reduces the runtime about 6%-10%
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/lp64/multiarch/Makefile | 6 ++
+ .../lp64/multiarch/ifunc-impl-list.c | 16 +++
+ .../loongarch/lp64/multiarch/ifunc-strchr.h | 41 ++++++++
+ .../lp64/multiarch/ifunc-strchrnul.h | 41 ++++++++
+ .../loongarch/lp64/multiarch/strchr-aligned.S | 99 +++++++++++++++++++
+ .../loongarch/lp64/multiarch/strchr-lasx.S | 91 +++++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/strchr-lsx.S | 73 ++++++++++++++
+ sysdeps/loongarch/lp64/multiarch/strchr.c | 36 +++++++
+ .../lp64/multiarch/strchrnul-aligned.S | 95 ++++++++++++++++++
+ .../loongarch/lp64/multiarch/strchrnul-lasx.S | 22 +++++
+ .../loongarch/lp64/multiarch/strchrnul-lsx.S | 22 +++++
+ sysdeps/loongarch/lp64/multiarch/strchrnul.c | 39 ++++++++
+ 12 files changed, 581 insertions(+)
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-strchr.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-strchrnul.h
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr.c
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S
+ create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul.c
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index 76c506c9..110a8c5c 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -3,5 +3,11 @@ sysdep_routines += \
+ strlen-aligned \
+ strlen-lsx \
+ strlen-lasx \
++ strchr-aligned \
++ strchr-lsx \
++ strchr-lasx \
++ strchrnul-aligned \
++ strchrnul-lsx \
++ strchrnul-lasx \
+ # sysdep_routines
+ endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+index 1a2a576f..c7164b45 100644
+--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
+@@ -37,5 +37,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ #endif
+ IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_aligned)
+ )
++
++ IFUNC_IMPL (i, name, strchr,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, strchr, SUPPORT_LASX, __strchr_lasx)
++ IFUNC_IMPL_ADD (array, i, strchr, SUPPORT_LSX, __strchr_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_aligned)
++ )
++
++ IFUNC_IMPL (i, name, strchrnul,
++#if !defined __loongarch_soft_float
++ IFUNC_IMPL_ADD (array, i, strchrnul, SUPPORT_LASX, __strchrnul_lasx)
++ IFUNC_IMPL_ADD (array, i, strchrnul, SUPPORT_LSX, __strchrnul_lsx)
++#endif
++ IFUNC_IMPL_ADD (array, i, strchrnul, 1, __strchrnul_aligned)
++ )
+ return i;
+ }
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-strchr.h b/sysdeps/loongarch/lp64/multiarch/ifunc-strchr.h
+new file mode 100644
+index 00000000..4494db79
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-strchr.h
+@@ -0,0 +1,41 @@
++/* Common definition for strchr ifunc selections.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-strchrnul.h b/sysdeps/loongarch/lp64/multiarch/ifunc-strchrnul.h
+new file mode 100644
+index 00000000..8a925120
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-strchrnul.h
+@@ -0,0 +1,41 @@
++/* Common definition for strchrnul ifunc selections.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <ldsodefs.h>
++#include <ifunc-init.h>
++
++#if !defined __loongarch_soft_float
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
++#endif
++
++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
++
++static inline void *
++IFUNC_SELECTOR (void)
++{
++#if !defined __loongarch_soft_float
++ if (SUPPORT_LASX)
++ return OPTIMIZE (lasx);
++ else if (SUPPORT_LSX)
++ return OPTIMIZE (lsx);
++ else
++#endif
++ return OPTIMIZE (aligned);
++}
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S
+new file mode 100644
+index 00000000..5fb01806
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S
+@@ -0,0 +1,99 @@
++/* Optimized strchr implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define STRCHR_NAME __strchr_aligned
++#else
++# define STRCHR_NAME strchr
++#endif
++
++LEAF(STRCHR_NAME, 6)
++ slli.d t1, a0, 3
++ bstrins.d a0, zero, 2, 0
++ lu12i.w a2, 0x01010
++ ld.d t2, a0, 0
++
++ ori a2, a2, 0x101
++ andi a1, a1, 0xff
++ bstrins.d a2, a2, 63, 32
++ li.w t0, -1
++
++ mul.d a1, a1, a2
++ sll.d t0, t0, t1
++ slli.d a3, a2, 7
++ orn t2, t2, t0
++
++ sll.d t3, a1, t1
++ xor t4, t2, t3
++ sub.d a4, t2, a2
++ sub.d a5, t4, a2
++
++
++ andn a4, a4, t2
++ andn a5, a5, t4
++ or t0, a4, a5
++ and t0, t0, a3
++
++ bnez t0, L(end)
++ addi.d a0, a0, 8
++L(loop):
++ ld.d t4, a0, 0
++ xor t2, t4, a1
++
++ sub.d a4, t4, a2
++ sub.d a5, t2, a2
++ andn a4, a4, t4
++ andn a5, a5, t2
++
++ or t0, a4, a5
++ and t0, t0, a3
++ bnez t0, L(end)
++ ld.d t4, a0, 8
++
++
++ addi.d a0, a0, 16
++ xor t2, t4, a1
++ sub.d a4, t4, a2
++ sub.d a5, t2, a2
++
++ andn a4, a4, t4
++ andn a5, a5, t2
++ or t0, a4, a5
++ and t0, t0, a3
++
++ beqz t0, L(loop)
++ addi.d a0, a0, -8
++L(end):
++ and t0, a5, a3
++ and t1, a4, a3
++
++ ctz.d t0, t0
++ ctz.d t1, t1
++ srli.w t2, t0, 3
++ sltu t3, t1, t0
++
++
++ add.d a0, a0, t2
++ masknez a0, a0, t3
++ jr ra
++END(STRCHR_NAME)
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S
+new file mode 100644
+index 00000000..254402da
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S
+@@ -0,0 +1,91 @@
++/* Optimized strchr implementation using loongarch LASX SIMD instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++#ifndef AS_STRCHRNUL
++# define STRCHR __strchr_lasx
++#endif
++
++LEAF(STRCHR, 6)
++ andi t1, a0, 0x1f
++ bstrins.d a0, zero, 4, 0
++ xvld xr0, a0, 0
++ li.d t2, -1
++
++ xvreplgr2vr.b xr1, a1
++ sll.d t1, t2, t1
++ xvxor.v xr2, xr0, xr1
++ xvmin.bu xr0, xr0, xr2
++
++ xvmsknz.b xr0, xr0
++ xvpickve.w xr3, xr0, 4
++ vilvl.h vr0, vr3, vr0
++ movfr2gr.s t0, fa0
++
++ orn t0, t0, t1
++ bne t0, t2, L(end)
++ addi.d a0, a0, 32
++ nop
++
++
++L(loop):
++ xvld xr0, a0, 0
++ xvxor.v xr2, xr0, xr1
++ xvmin.bu xr0, xr0, xr2
++ xvsetanyeqz.b fcc0, xr0
++
++ bcnez fcc0, L(loop_end)
++ xvld xr0, a0, 32
++ addi.d a0, a0, 64
++ xvxor.v xr2, xr0, xr1
++
++ xvmin.bu xr0, xr0, xr2
++ xvsetanyeqz.b fcc0, xr0
++ bceqz fcc0, L(loop)
++ addi.d a0, a0, -32
++
++L(loop_end):
++ xvmsknz.b xr0, xr0
++ xvpickve.w xr1, xr0, 4
++ vilvl.h vr0, vr1, vr0
++ movfr2gr.s t0, fa0
++
++
++L(end):
++ cto.w t0, t0
++ add.d a0, a0, t0
++#ifndef AS_STRCHRNUL
++ vreplgr2vr.b vr0, t0
++ xvpermi.q xr3, xr2, 1
++
++ vshuf.b vr0, vr3, vr2, vr0
++ vpickve2gr.bu t0, vr0, 0
++ masknez a0, a0, t0
++#endif
++ jr ra
++
++END(STRCHR)
++
++libc_hidden_builtin_def(STRCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S
+new file mode 100644
+index 00000000..dae98b0a
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S
+@@ -0,0 +1,73 @@
++/* Optimized strlen implementation using loongarch LSX SIMD instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc) && !defined __loongarch_soft_float
++
++#ifndef AS_STRCHRNUL
++# define STRCHR __strchr_lsx
++#endif
++
++LEAF(STRCHR, 6)
++ andi t1, a0, 0xf
++ bstrins.d a0, zero, 3, 0
++ vld vr0, a0, 0
++ li.d t2, -1
++
++ vreplgr2vr.b vr1, a1
++ sll.d t3, t2, t1
++ vxor.v vr2, vr0, vr1
++ vmin.bu vr0, vr0, vr2
++
++ vmsknz.b vr0, vr0
++ movfr2gr.s t0, fa0
++ ext.w.h t0, t0
++ orn t0, t0, t3
++
++ beq t0, t2, L(loop)
++L(found):
++ cto.w t0, t0
++ add.d a0, a0, t0
++#ifndef AS_STRCHRNUL
++ vreplve.b vr2, vr2, t0
++ vpickve2gr.bu t1, vr2, 0
++ masknez a0, a0, t1
++#endif
++ jr ra
++
++
++L(loop):
++ vld vr0, a0, 16
++ addi.d a0, a0, 16
++ vxor.v vr2, vr0, vr1
++ vmin.bu vr0, vr0, vr2
++
++ vsetanyeqz.b fcc0, vr0
++ bceqz fcc0, L(loop)
++ vmsknz.b vr0, vr0
++ movfr2gr.s t0, fa0
++
++ b L(found)
++END(STRCHR)
++
++libc_hidden_builtin_def (STRCHR)
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchr.c b/sysdeps/loongarch/lp64/multiarch/strchr.c
+new file mode 100644
+index 00000000..404e97bd
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strchr.c
+@@ -0,0 +1,36 @@
++/* Multiple versions of strchr.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++#if IS_IN (libc)
++# define strchr __redirect_strchr
++# include <string.h>
++# undef strchr
++
++# define SYMBOL_NAME strchr
++# include "ifunc-strchr.h"
++
++libc_ifunc_redirected (__redirect_strchr, strchr, IFUNC_SELECTOR ());
++weak_alias(strchr, index)
++# ifdef SHARED
++__hidden_ver1 (strchr, __GI_strchr, __redirect_strchr)
++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strchr);
++# endif
++
++#endif
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S
+new file mode 100644
+index 00000000..1c01a023
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S
+@@ -0,0 +1,95 @@
++/* Optimized strchrnul implementation using basic Loongarch instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <sysdep.h>
++#include <sys/regdef.h>
++#include <sys/asm.h>
++
++#if IS_IN (libc)
++# define STRCHRNUL_NAME __strchrnul_aligned
++#else
++# define STRCHRNUL_NAME __strchrnul
++#endif
++
++LEAF(STRCHRNUL_NAME, 6)
++ slli.d t1, a0, 3
++ bstrins.d a0, zero, 2, 0
++ lu12i.w a2, 0x01010
++ ld.d t2, a0, 0
++
++ ori a2, a2, 0x101
++ andi a1, a1, 0xff
++ bstrins.d a2, a2, 63, 32
++ li.w t0, -1
++
++ mul.d a1, a1, a2
++ sll.d t0, t0, t1
++ slli.d a3, a2, 7
++ orn t2, t2, t0
++
++ sll.d t3, a1, t1
++ xor t4, t2, t3
++ sub.d a4, t2, a2
++ sub.d a5, t4, a2
++
++
++ andn a4, a4, t2
++ andn a5, a5, t4
++ or t0, a4, a5
++ and t0, t0, a3
++
++ bnez t0, L(end)
++ addi.d a0, a0, 8
++L(loop):
++ ld.d t4, a0, 0
++ xor t2, t4, a1
++
++ sub.d a4, t4, a2
++ sub.d a5, t2, a2
++ andn a4, a4, t4
++ andn a5, a5, t2
++
++ or t0, a4, a5
++ and t0, t0, a3
++ bnez t0, L(end)
++ ld.d t4, a0, 8
++
++
++ addi.d a0, a0, 16
++ xor t2, t4, a1
++ sub.d a4, t4, a2
++ sub.d a5, t2, a2
++
++ andn a4, a4, t4
++ andn a5, a5, t2
++ or t0, a4, a5
++ and t0, t0, a3
++
++ beqz t0, L(loop)
++ addi.d a0, a0, -8
++L(end):
++ ctz.d t0, t0
++ srli.w t0, t0, 3
++
++
++ add.d a0, a0, t0
++ jr ra
++END(STRCHRNUL_NAME)
++
++libc_hidden_builtin_def (STRCHRNUL_NAME)
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S
+new file mode 100644
+index 00000000..d45495e4
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S
+@@ -0,0 +1,22 @@
++/* Optimized strchrnul implementation using loongarch LASX SIMD instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#define STRCHR __strchrnul_lasx
++#define AS_STRCHRNUL
++#include "strchr-lasx.S"
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S
+new file mode 100644
+index 00000000..07d793ae
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S
+@@ -0,0 +1,22 @@
++/* Optimized strchrnul implementation using loongarch LSX SIMD instructions.
++ 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
++ <https://www.gnu.org/licenses/>. */
++
++#define STRCHR __strchrnul_lsx
++#define AS_STRCHRNUL
++#include "strchr-lsx.S"
+diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul.c b/sysdeps/loongarch/lp64/multiarch/strchrnul.c
+new file mode 100644
+index 00000000..f3b8296e
+--- /dev/null
++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul.c
+@@ -0,0 +1,39 @@
++/* Multiple versions of strchrnul.
++ All versions must be listed in ifunc-impl-list.c.
++ 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
++ <http://www.gnu.org/licenses/>. */
++
++/* Define multiple versions only for the definition in libc. */
++
++#if IS_IN (libc)
++# define strchrnul __redirect_strchrnul
++# define __strchrnul __redirect___strchrnul
++# include <string.h>
++# undef __strchrnul
++# undef strchrnul
++
++# define SYMBOL_NAME strchrnul
++# include "ifunc-strchrnul.h"
++
++libc_ifunc_redirected (__redirect_strchrnul, __strchrnul,
++ IFUNC_SELECTOR ());
++weak_alias (__strchrnul, strchrnul)
++# ifdef SHARED
++__hidden_ver1 (__strchrnul, __GI___strchrnul, __redirect_strchrnul)
++ __attribute__((visibility ("hidden"))) __attribute_copy__ (strchrnul);
++# endif
++#endif
+--
+2.33.0
+
diff --git a/Make-tst-ungetc-use-libsupport.patch b/Make-tst-ungetc-use-libsupport.patch
new file mode 100644
index 0000000..8a0a140
--- /dev/null
+++ b/Make-tst-ungetc-use-libsupport.patch
@@ -0,0 +1,147 @@
+From 87a1968a72e4b4e5436f3e2be1ed8a8d5a5862c7 Mon Sep 17 00:00:00 2001
+From: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date: Wed, 14 Aug 2024 19:20:04 -0400
+Subject: [PATCH] Make tst-ungetc use libsupport
+
+Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 3f7df7e757f4efec38e45d4068e5492efcac4856)
+---
+ stdio-common/tst-ungetc.c | 112 +++++++++++++++++++-------------------
+ 1 file changed, 57 insertions(+), 55 deletions(-)
+
+diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c
+index 1344b2b591..5c808f0734 100644
+--- a/stdio-common/tst-ungetc.c
++++ b/stdio-common/tst-ungetc.c
+@@ -1,70 +1,72 @@
+-/* Test for ungetc bugs. */
++/* Test for ungetc bugs.
++ Copyright (C) 1996-2024 Free Software Foundation, Inc.
++ Copyright The GNU Toolchain Authors.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
+
+ #include <stdio.h>
+ #include <stdlib.h>
+-#include <unistd.h>
+-
+-#undef assert
+-#define assert(x) \
+- if (!(x)) \
+- { \
+- fputs ("test failed: " #x "\n", stderr); \
+- retval = 1; \
+- goto the_end; \
+- }
++#include <support/check.h>
++#include <support/support.h>
++#include <support/temp_file.h>
++#include <support/xstdio.h>
++#include <support/xunistd.h>
+
+-int
+-main (int argc, char *argv[])
++static int
++do_test (void)
+ {
+- char name[] = "/tmp/tst-ungetc.XXXXXX";
++ char *name = NULL;
+ FILE *fp = NULL;
+- int retval = 0;
+ int c;
+ char buffer[64];
+
+- int fd = mkstemp (name);
++ int fd = create_temp_file ("tst-ungetc.", &name);
+ if (fd == -1)
+- {
+- printf ("mkstemp failed: %m\n");
+- return 1;
+- }
+- close (fd);
+- fp = fopen (name, "w");
+- assert (fp != NULL)
+- fputs ("bla", fp);
+- fclose (fp);
+- fp = NULL;
++ FAIL_EXIT1 ("cannot create temporary file: %m");
++ xclose (fd);
+
+- fp = fopen (name, "r");
+- assert (fp != NULL);
+- assert (ungetc ('z', fp) == 'z');
+- assert (getc (fp) == 'z');
+- assert (getc (fp) == 'b');
+- assert (getc (fp) == 'l');
+- assert (ungetc ('m', fp) == 'm');
+- assert (getc (fp) == 'm');
+- assert ((c = getc (fp)) == 'a');
+- assert (getc (fp) == EOF);
+- assert (ungetc (c, fp) == c);
+- assert (feof (fp) == 0);
+- assert (getc (fp) == c);
+- assert (getc (fp) == EOF);
+- fclose (fp);
+- fp = NULL;
++ fp = xfopen (name, "w");
++ fputs ("bla", fp);
++ xfclose (fp);
+
+- fp = fopen (name, "r");
+- assert (fp != NULL);
+- assert (getc (fp) == 'b');
+- assert (getc (fp) == 'l');
+- assert (ungetc ('b', fp) == 'b');
+- assert (fread (buffer, 1, 64, fp) == 2);
+- assert (buffer[0] == 'b');
+- assert (buffer[1] == 'a');
++ fp = xfopen (name, "r");
++ TEST_VERIFY_EXIT (ungetc ('z', fp) == 'z');
++ TEST_VERIFY_EXIT (getc (fp) == 'z');
++ TEST_VERIFY_EXIT (getc (fp) == 'b');
++ TEST_VERIFY_EXIT (getc (fp) == 'l');
++ TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
++ TEST_VERIFY_EXIT (getc (fp) == 'm');
++ TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
++ TEST_VERIFY_EXIT (getc (fp) == EOF);
++ TEST_VERIFY_EXIT (ungetc (c, fp) == c);
++ TEST_VERIFY_EXIT (feof (fp) == 0);
++ TEST_VERIFY_EXIT (getc (fp) == c);
++ TEST_VERIFY_EXIT (getc (fp) == EOF);
++ xfclose (fp);
+
+-the_end:
+- if (fp != NULL)
+- fclose (fp);
+- unlink (name);
++ fp = xfopen (name, "r");
++ TEST_VERIFY_EXIT (getc (fp) == 'b');
++ TEST_VERIFY_EXIT (getc (fp) == 'l');
++ TEST_VERIFY_EXIT (ungetc ('b', fp) == 'b');
++ TEST_VERIFY_EXIT (fread (buffer, 1, 64, fp) == 2);
++ TEST_VERIFY_EXIT (buffer[0] == 'b');
++ TEST_VERIFY_EXIT (buffer[1] == 'a');
++ xfclose (fp);
+
+- return retval;
++ return 0;
+ }
++
++#include <support/test-driver.c>
+--
+2.33.0
+
diff --git a/NEWS-Mention-bug-fixes-for-29039-30694-30709-30721.patch b/NEWS-Mention-bug-fixes-for-29039-30694-30709-30721.patch
new file mode 100644
index 0000000..3c6ba52
--- /dev/null
+++ b/NEWS-Mention-bug-fixes-for-29039-30694-30709-30721.patch
@@ -0,0 +1,27 @@
+From d25e2c8d5cb0778ae87ad43b1f4c301abe5a932b Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Sat, 23 Dec 2023 06:24:41 -0800
+Subject: [PATCH 6/9] NEWS: Mention bug fixes for 29039/30694/30709/30721
+
+---
+ NEWS | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 6fbb8a9e1d..db4d6c8373 100644
+--- a/NEWS
++++ b/NEWS
+@@ -31,6 +31,10 @@ Security related changes:
+
+ The following bugs are resolved with this release:
+
++ [29039] Corrupt DTV after reuse of a TLS module ID following dlclose with unused TLS
++ [30694] The iconv program no longer tells the user which given encoding name was wrong
++ [30709] nscd fails to build with cleanup handler if built with -fexceptions
++ [30721] x86_64: Fix build with --disable-multiarch
+ [30723] posix_memalign repeatedly scans long bin lists
+ [30789] sem_open will fail on multithreaded scenarios when semaphore
+ file doesn't exist (O_CREAT)
+--
+2.33.0
+
diff --git a/NEWS-Mention-bug-fixes-for-30745-30843.patch b/NEWS-Mention-bug-fixes-for-30745-30843.patch
new file mode 100644
index 0000000..4148758
--- /dev/null
+++ b/NEWS-Mention-bug-fixes-for-30745-30843.patch
@@ -0,0 +1,30 @@
+From 27339a3eb8f987eebae72b854af80256c1588ebd Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Sat, 23 Dec 2023 06:27:50 -0800
+Subject: [PATCH 7/9] NEWS: Mention bug fixes for 30745/30843
+
+---
+ NEWS | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index db4d6c8373..905230b838 100644
+--- a/NEWS
++++ b/NEWS
+@@ -36,11 +36,13 @@ The following bugs are resolved with this release:
+ [30709] nscd fails to build with cleanup handler if built with -fexceptions
+ [30721] x86_64: Fix build with --disable-multiarch
+ [30723] posix_memalign repeatedly scans long bin lists
++ [30745] Slight bug in cache info codes for x86
+ [30789] sem_open will fail on multithreaded scenarios when semaphore
+ file doesn't exist (O_CREAT)
+ [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+ -D_FILE_OFFSET_BITS=64
+ [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
++ [30843] potential use-after-free in getcanonname (CVE-2023-4806)
+ [31184] FAIL: elf/tst-tlsgap
+ [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
+
+--
+2.33.0
+
diff --git a/Revert-LoongArch-Add-glibc.cpu.hwcap-support.patch b/Revert-LoongArch-Add-glibc.cpu.hwcap-support.patch
new file mode 100644
index 0000000..6180f26
--- /dev/null
+++ b/Revert-LoongArch-Add-glibc.cpu.hwcap-support.patch
@@ -0,0 +1,478 @@
+From c0f3b0a8c71c26d5351e8ddabe3e8a323803e683 Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Thu, 21 Sep 2023 09:10:11 +0800
+Subject: [PATCH 26/29] Revert "LoongArch: Add glibc.cpu.hwcap support."
+
+This reverts commit a53451559dc9cce765ea5bcbb92c4007e058e92b.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ sysdeps/loongarch/Makefile | 4 -
+ sysdeps/loongarch/Versions | 5 --
+ sysdeps/loongarch/cpu-tunables.c | 89 -------------------
+ sysdeps/loongarch/dl-get-cpu-features.c | 25 ------
+ sysdeps/loongarch/dl-machine.h | 27 +-----
+ sysdeps/loongarch/dl-tunables.list | 25 ------
+ .../unix/sysv/linux/loongarch/cpu-features.c | 29 ------
+ .../unix/sysv/linux/loongarch/cpu-features.h | 18 +---
+ .../unix/sysv/linux/loongarch/dl-procinfo.c | 60 -------------
+ sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c | 21 -----
+ .../unix/sysv/linux/loongarch/libc-start.c | 34 -------
+ 11 files changed, 8 insertions(+), 329 deletions(-)
+ delete mode 100644 sysdeps/loongarch/Versions
+ delete mode 100644 sysdeps/loongarch/cpu-tunables.c
+ delete mode 100644 sysdeps/loongarch/dl-get-cpu-features.c
+ delete mode 100644 sysdeps/loongarch/dl-tunables.list
+ delete mode 100644 sysdeps/unix/sysv/linux/loongarch/cpu-features.c
+ delete mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c
+ delete mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c
+ delete mode 100644 sysdeps/unix/sysv/linux/loongarch/libc-start.c
+
+diff --git a/sysdeps/loongarch/Makefile b/sysdeps/loongarch/Makefile
+index 30a1f4a8..43d2f583 100644
+--- a/sysdeps/loongarch/Makefile
++++ b/sysdeps/loongarch/Makefile
+@@ -6,10 +6,6 @@ ifeq ($(subdir),elf)
+ gen-as-const-headers += dl-link.sym
+ endif
+
+-ifeq ($(subdir),elf)
+- sysdep-dl-routines += dl-get-cpu-features
+-endif
+-
+ # LoongArch's assembler also needs to know about PIC as it changes the
+ # definition of some assembler macros.
+ ASFLAGS-.os += $(pic-ccflag)
+diff --git a/sysdeps/loongarch/Versions b/sysdeps/loongarch/Versions
+deleted file mode 100644
+index 33ae2cc0..00000000
+--- a/sysdeps/loongarch/Versions
++++ /dev/null
+@@ -1,5 +0,0 @@
+-ld {
+- GLIBC_PRIVATE {
+- _dl_larch_get_cpu_features;
+- }
+-}
+diff --git a/sysdeps/loongarch/cpu-tunables.c b/sysdeps/loongarch/cpu-tunables.c
+deleted file mode 100644
+index 8e9fab93..00000000
+--- a/sysdeps/loongarch/cpu-tunables.c
++++ /dev/null
+@@ -1,89 +0,0 @@
+-/* LoongArch CPU feature tuning.
+- This file is part of the GNU C Library.
+- Copyright (C) 2023 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
+- <http://www.gnu.org/licenses/>. */
+-
+-# include <stdbool.h>
+-# include <stdint.h>
+-# include <unistd.h> /* Get STDOUT_FILENO for _dl_printf. */
+-# include <elf/dl-tunables.h>
+-# include <string.h>
+-# include <cpu-features.h>
+-# include <ldsodefs.h>
+-# include <sys/auxv.h>
+-
+-# define HWCAP_LOONGARCH_IFUNC \
+- (HWCAP_LOONGARCH_UAL | HWCAP_LOONGARCH_LSX | HWCAP_LOONGARCH_LASX)
+-
+-# define CHECK_GLIBC_IFUNC_CPU_OFF(f, name, len) \
+- _Static_assert (sizeof (#name) - 1 == len, #name " != " #len); \
+- if (!memcmp (f, #name, len) && \
+- (GLRO (dl_hwcap) & HWCAP_LOONGARCH_##name)) \
+- { \
+- hwcap |= (HWCAP_LOONGARCH_##name | (~HWCAP_LOONGARCH_IFUNC)); \
+- break; \
+- } \
+-
+-attribute_hidden
+-void
+-TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
+-{
+- const char *p = valp->strval;
+- size_t len;
+- unsigned long hwcap = 0;
+- const char *c;
+-
+- do {
+- for (c = p; *c != ','; c++)
+- if (*c == '\0')
+- break;
+-
+- len = c - p;
+-
+- switch(len)
+- {
+- default:
+- _dl_fatal_printf (
+- "The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!\n"
+- );
+- break;
+- case 3:
+- {
+- CHECK_GLIBC_IFUNC_CPU_OFF (p, LSX, 3);
+- CHECK_GLIBC_IFUNC_CPU_OFF (p, UAL, 3);
+- _dl_fatal_printf (
+- "Some features are invalid or not supported on this machine!!\n"
+- "The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!\n"
+- );
+- }
+- break;
+- case 4:
+- {
+- CHECK_GLIBC_IFUNC_CPU_OFF (p, LASX, 4);
+- _dl_fatal_printf (
+- "Some features are invalid or not supported on this machine!!\n"
+- "The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!\n"
+- );
+- }
+- break;
+- }
+-
+- p += len + 1;
+- }
+- while (*c != '\0');
+-
+- GLRO (dl_larch_cpu_features).hwcap &= hwcap;
+-}
+diff --git a/sysdeps/loongarch/dl-get-cpu-features.c b/sysdeps/loongarch/dl-get-cpu-features.c
+deleted file mode 100644
+index 7cd9bc15..00000000
+--- a/sysdeps/loongarch/dl-get-cpu-features.c
++++ /dev/null
+@@ -1,25 +0,0 @@
+-/* Define _dl_larch_get_cpu_features.
+- Copyright (C) 2023 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
+- <https://www.gnu.org/licenses/>. */
+-
+-
+-#include <ldsodefs.h>
+-
+-const struct cpu_features *
+-_dl_larch_get_cpu_features (void)
+-{
+- return &GLRO(dl_larch_cpu_features);
+-}
+diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
+index b395a928..57913cef 100644
+--- a/sysdeps/loongarch/dl-machine.h
++++ b/sysdeps/loongarch/dl-machine.h
+@@ -29,8 +29,6 @@
+ #include <dl-static-tls.h>
+ #include <dl-machine-rel.h>
+
+-#include <cpu-features.c>
+-
+ #ifndef _RTLD_PROLOGUE
+ # define _RTLD_PROLOGUE(entry) \
+ ".globl\t" __STRING (entry) "\n\t" \
+@@ -55,23 +53,6 @@
+ #define ELF_MACHINE_NO_REL 1
+ #define ELF_MACHINE_NO_RELA 0
+
+-#define DL_PLATFORM_INIT dl_platform_init ()
+-
+-static inline void __attribute__ ((unused))
+-dl_platform_init (void)
+-{
+- if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+- /* Avoid an empty string which would disturb us. */
+- GLRO(dl_platform) = NULL;
+-
+-#ifdef SHARED
+- /* init_cpu_features has been called early from __libc_start_main in
+- static executable. */
+- init_cpu_features (&GLRO(dl_larch_cpu_features));
+-#endif
+-}
+-
+-
+ /* Return nonzero iff ELF header is compatible with the running host. */
+ static inline int
+ elf_machine_matches_host (const ElfW (Ehdr) *ehdr)
+@@ -309,9 +290,9 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+ if (profile != 0)
+ {
+ #if !defined __loongarch_soft_float
+- if (RTLD_SUPPORT_LASX)
++ if (SUPPORT_LASX)
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile_lasx;
+- else if (RTLD_SUPPORT_LSX)
++ else if (SUPPORT_LSX)
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile_lsx;
+ else
+ #endif
+@@ -329,9 +310,9 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+ indicated by the offset on the stack, and then jump to
+ the resolved address. */
+ #if !defined __loongarch_soft_float
+- if (RTLD_SUPPORT_LASX)
++ if (SUPPORT_LASX)
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve_lasx;
+- else if (RTLD_SUPPORT_LSX)
++ else if (SUPPORT_LSX)
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve_lsx;
+ else
+ #endif
+diff --git a/sysdeps/loongarch/dl-tunables.list b/sysdeps/loongarch/dl-tunables.list
+deleted file mode 100644
+index 66b34275..00000000
+--- a/sysdeps/loongarch/dl-tunables.list
++++ /dev/null
+@@ -1,25 +0,0 @@
+-# LoongArch specific tunables.
+-# 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
+-# <http://www.gnu.org/licenses/>.
+-
+-glibc {
+- cpu {
+- hwcaps {
+- type: STRING
+- }
+- }
+-}
+diff --git a/sysdeps/unix/sysv/linux/loongarch/cpu-features.c b/sysdeps/unix/sysv/linux/loongarch/cpu-features.c
+deleted file mode 100644
+index 1290c4ce..00000000
+--- a/sysdeps/unix/sysv/linux/loongarch/cpu-features.c
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/* Initialize CPU feature data. LoongArch64 version.
+- This file is part of the GNU C Library.
+- Copyright (C) 2023 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
+- <http://www.gnu.org/licenses/>. */
+-
+-#include <cpu-features.h>
+-#include <elf/dl-hwcaps.h>
+-#include <elf/dl-tunables.h>
+-extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) attribute_hidden;
+-
+-static inline void
+-init_cpu_features (struct cpu_features *cpu_features)
+-{
+- GLRO (dl_larch_cpu_features).hwcap = GLRO (dl_hwcap);
+- TUNABLE_GET (glibc, cpu, hwcaps, tunable_val_t *, TUNABLE_CALLBACK (set_hwcaps));
+-}
+diff --git a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
+index 450963ce..d1a280a5 100644
+--- a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
++++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
+@@ -19,23 +19,13 @@
+ #ifndef _CPU_FEATURES_LOONGARCH64_H
+ #define _CPU_FEATURES_LOONGARCH64_H
+
+-#include <stdint.h>
+ #include <sys/auxv.h>
+
+-struct cpu_features
+- {
+- uint64_t hwcap;
+- };
++#define SUPPORT_UAL (GLRO (dl_hwcap) & HWCAP_LOONGARCH_UAL)
++#define SUPPORT_LSX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LSX)
++#define SUPPORT_LASX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LASX)
+
+-/* Get a pointer to the CPU features structure. */
+-extern const struct cpu_features *_dl_larch_get_cpu_features (void)
+- __attribute__ ((pure));
+-
+-#define SUPPORT_UAL (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_UAL)
+-#define SUPPORT_LSX (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_LSX)
+-#define SUPPORT_LASX (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_LASX)
+-#define RTLD_SUPPORT_LSX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LSX)
+-#define RTLD_SUPPORT_LASX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LASX)
+ #define INIT_ARCH()
+
+ #endif /* _CPU_FEATURES_LOONGARCH64_H */
++
+diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c b/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c
+deleted file mode 100644
+index 6217fda9..00000000
+--- a/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c
++++ /dev/null
+@@ -1,60 +0,0 @@
+-/* Data for LoongArch64 version of processor capability information.
+- Linux version.
+- 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
+- <http://www.gnu.org/licenses/>. */
+-
+-/* If anything should be added here check whether the size of each string
+- is still ok with the given array size.
+-
+- All the #ifdefs in the definitions are quite irritating but
+- necessary if we want to avoid duplicating the information. There
+- are three different modes:
+-
+- - PROCINFO_DECL is defined. This means we are only interested in
+- declarations.
+-
+- - PROCINFO_DECL is not defined:
+-
+- + if SHARED is defined the file is included in an array
+- initializer. The .element = { ... } syntax is needed.
+-
+- + if SHARED is not defined a normal array initialization is
+- needed.
+- */
+-
+-#ifndef PROCINFO_CLASS
+-# define PROCINFO_CLASS
+-#endif
+-
+-#if !IS_IN (ldconfig)
+-# if !defined PROCINFO_DECL && defined SHARED
+- ._dl_larch_cpu_features
+-# else
+-PROCINFO_CLASS struct cpu_features _dl_larch_cpu_features
+-# endif
+-# ifndef PROCINFO_DECL
+-= { }
+-# endif
+-# if !defined SHARED || defined PROCINFO_DECL
+-;
+-# else
+-,
+-# endif
+-#endif
+-
+-#undef PROCINFO_DECL
+-#undef PROCINFO_CLASS
+diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c b/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c
+deleted file mode 100644
+index 455fd71a..00000000
+--- a/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* Operating system support for run-time dynamic linker. LoongArch version.
+- 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
+- <http://www.gnu.org/licenses/>. */
+-
+-#include <config.h>
+-#include <sysdeps/loongarch/cpu-tunables.c>
+-#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
+diff --git a/sysdeps/unix/sysv/linux/loongarch/libc-start.c b/sysdeps/unix/sysv/linux/loongarch/libc-start.c
+deleted file mode 100644
+index f1346ece..00000000
+--- a/sysdeps/unix/sysv/linux/loongarch/libc-start.c
++++ /dev/null
+@@ -1,34 +0,0 @@
+-/* Override csu/libc-start.c on LoongArch64.
+- 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
+- <http://www.gnu.org/licenses/>. */
+-
+-#ifndef SHARED
+-
+-/* Mark symbols hidden in static PIE for early self relocation to work. */
+-# if BUILD_PIE_DEFAULT
+-# pragma GCC visibility push(hidden)
+-# endif
+-
+-# include <ldsodefs.h>
+-# include <cpu-features.c>
+-
+-extern struct cpu_features _dl_larch_cpu_features;
+-
+-# define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_larch_cpu_features)
+-
+-#endif
+-#include <csu/libc-start.c>
+--
+2.33.0
+
diff --git a/S390-Fix-building-with-disable-mutli-arch-BZ-31196.patch b/S390-Fix-building-with-disable-mutli-arch-BZ-31196.patch
new file mode 100644
index 0000000..5ad5372
--- /dev/null
+++ b/S390-Fix-building-with-disable-mutli-arch-BZ-31196.patch
@@ -0,0 +1,66 @@
+From 18876c9ff52c3d9aefe2c663b1a287589bebedc0 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Tue, 30 Jan 2024 09:34:32 +0100
+Subject: [PATCH 2/6] S390: Fix building with --disable-mutli-arch [BZ #31196]
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Starting with commits
+- 7ea510127e2067efa07865158ac92c330c379950
+string: Add libc_hidden_proto for strchrnul
+- 22999b2f0fb62eed1af4095d062bd1272d6afeb1
+string: Add libc_hidden_proto for memrchr
+
+building glibc on s390x with --disable-multi-arch fails if only
+the C-variant of strchrnul / memrchr is used. This is the case
+if gcc uses -march < z13.
+
+The build fails with:
+../sysdeps/s390/strchrnul-c.c:28:49: error: ‘__strchrnul_c’ undeclared here (not in a function); did you mean ‘__strchrnul’?
+ 28 | __hidden_ver1 (__strchrnul_c, __GI___strchrnul, __strchrnul_c);
+
+With --disable-multi-arch, __strchrnul_c is not available as string/strchrnul.c
+is just included without defining STRCHRNUL and thus we also don't have to create
+the internal hidden symbol.
+
+Tested-by: Andreas K. Hüttel <dilfridge@gentoo.org>
+(cherry picked from commit cc1b91eabd806057aa7e3058a84bf129ed36e157)
+---
+ sysdeps/s390/memrchr-c.c | 4 +++-
+ sysdeps/s390/strchrnul-c.c | 4 +++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/sysdeps/s390/memrchr-c.c b/sysdeps/s390/memrchr-c.c
+index bdf3c7bbe0..fadd63087a 100644
+--- a/sysdeps/s390/memrchr-c.c
++++ b/sysdeps/s390/memrchr-c.c
+@@ -25,7 +25,9 @@
+
+ # include <string/memrchr.c>
+
+-# if defined SHARED && IS_IN (libc)
++# if HAVE_MEMRCHR_IFUNC
++# if defined SHARED && IS_IN (libc)
+ __hidden_ver1 (__memrchr_c, __GI___memrchr, __memrchr_c);
++# endif
+ # endif
+ #endif
+diff --git a/sysdeps/s390/strchrnul-c.c b/sysdeps/s390/strchrnul-c.c
+index f6f5bae311..97fbc16edb 100644
+--- a/sysdeps/s390/strchrnul-c.c
++++ b/sysdeps/s390/strchrnul-c.c
+@@ -24,7 +24,9 @@
+ # endif
+
+ # include <string/strchrnul.c>
+-# if defined SHARED && IS_IN (libc)
++# if HAVE_STRCHRNUL_IFUNC
++# if defined SHARED && IS_IN (libc)
+ __hidden_ver1 (__strchrnul_c, __GI___strchrnul, __strchrnul_c);
++# endif
+ # endif
+ #endif
+--
+2.33.0
+
diff --git a/add-GB18030-2022-charmap-BZ-30243.patch b/add-GB18030-2022-charmap-BZ-30243.patch
new file mode 100644
index 0000000..0c15b24
--- /dev/null
+++ b/add-GB18030-2022-charmap-BZ-30243.patch
@@ -0,0 +1,853 @@
+From 1dc4a7192a27142bf3b916287c9cd37a361784f5 Mon Sep 17 00:00:00 2001
+From: lijianglin <lijianglin2@huawei.com>
+Date: Thu, 15 Jun 2023 16:50:13 +0800
+Subject: [PATCH v3] add GB18030-2022 charmap and test the entire GB18030 charmap [BZ #30243]
+
+support GB18030-2022 after add and change some transcoding relationship
+of GB18030-2022.Details are as follows:
+add 25 transcoding relationship
+ UE81E 0x82359037
+ UE826 0x82359038
+ UE82B 0x82359039
+ UE82C 0x82359130
+ UE832 0x82359131
+ UE843 0x82359132
+ UE854 0x82359133
+ UE864 0x82359134
+ UE78D 0x84318236
+ UE78F 0x84318237
+ UE78E 0x84318238
+ UE790 0x84318239
+ UE791 0x84318330
+ UE792 0x84318331
+ UE793 0x84318332
+ UE794 0x84318333
+ UE795 0x84318334
+ UE796 0x84318335
+ UE816 0xfe51
+ UE817 0xfe52
+ UE818 0xfe53
+ UE831 0xfe6c
+ UE83B 0xfe76
+ UE855 0xfe91
+change 6 transcoding relationship
+ U20087 0x95329031
+ U20089 0x95329033
+ U200CC 0x95329730
+ U215D7 0x9536b937
+ U2298F 0x9630ba35
+ U241FE 0x9635b630
+Test the entire GB18030 charmap, not only the Unicode BMP part.
+
+Co-authored-by: yangyanchao <yangyanchao6@huawei.com>
+Co-authored-by: liqingqing <liqingqing3@huawei.com>
+Co-authored-by: Bruno Haible <bruno@clisp.org>
+Reviewed-by: Andreas Schwab <schwab@suse.de>
+---
+ iconvdata/gb18030.c | 423 +++++++++++++++++++-----------------
+ iconvdata/tst-table-from.c | 5 +-
+ iconvdata/tst-table-to.c | 12 +-
+ iconvdata/tst-table.sh | 50 +++--
+ localedata/charmaps/GB18030 | 91 +++-----
+ 5 files changed, 292 insertions(+), 289 deletions(-)
+
+diff --git a/iconvdata/gb18030.c b/iconvdata/gb18030.c
+index 0b03b9bb..ca383dc0 100644
+--- a/iconvdata/gb18030.c
++++ b/iconvdata/gb18030.c
+@@ -6020,49 +6020,50 @@ static const uint16_t __twobyte_to_ucs[] =
+ [0x5dc2] = 0xfa0e, [0x5dc3] = 0xfa0f, [0x5dc4] = 0xfa11, [0x5dc5] = 0xfa13,
+ [0x5dc6] = 0xfa14, [0x5dc7] = 0xfa18, [0x5dc8] = 0xfa1f, [0x5dc9] = 0xfa20,
+ [0x5dca] = 0xfa21, [0x5dcb] = 0xfa23, [0x5dcc] = 0xfa24, [0x5dcd] = 0xfa27,
+- [0x5dce] = 0xfa28, [0x5dcf] = 0xfa29, [0x5dd0] = 0x2e81, [0x5dd4] = 0x2e84,
+- [0x5dd5] = 0x3473, [0x5dd6] = 0x3447, [0x5dd7] = 0x2e88, [0x5dd8] = 0x2e8b,
+- [0x5dd9] = 0x9fb4, [0x5dda] = 0x359e, [0x5ddb] = 0x361a, [0x5ddc] = 0x360e,
+- [0x5ddd] = 0x2e8c, [0x5dde] = 0x2e97, [0x5ddf] = 0x396e, [0x5de0] = 0x3918,
+- [0x5de1] = 0x9fb5, [0x5de2] = 0x39cf, [0x5de3] = 0x39df, [0x5de4] = 0x3a73,
+- [0x5de5] = 0x39d0, [0x5de6] = 0x9fb6, [0x5de7] = 0x9fb7, [0x5de8] = 0x3b4e,
+- [0x5de9] = 0x3c6e, [0x5dea] = 0x3ce0, [0x5deb] = 0x2ea7, [0x5ded] = 0x9fb8,
++ [0x5dce] = 0xfa28, [0x5dcf] = 0xfa29, [0x5dd0] = 0x2e81, [0x5dd1] = 0xe816,
++ [0x5dd2] = 0xe817, [0x5dd3] = 0xe818, [0x5dd4] = 0x2e84, [0x5dd5] = 0x3473,
++ [0x5dd6] = 0x3447, [0x5dd7] = 0x2e88, [0x5dd8] = 0x2e8b, [0x5dd9] = 0x9fb4,
++ [0x5dda] = 0x359e, [0x5ddb] = 0x361a, [0x5ddc] = 0x360e, [0x5ddd] = 0x2e8c,
++ [0x5dde] = 0x2e97, [0x5ddf] = 0x396e, [0x5de0] = 0x3918, [0x5de1] = 0x9fb5,
++ [0x5de2] = 0x39cf, [0x5de3] = 0x39df, [0x5de4] = 0x3a73, [0x5de5] = 0x39d0,
++ [0x5de6] = 0x9fb6, [0x5de7] = 0x9fb7, [0x5de8] = 0x3b4e, [0x5de9] = 0x3c6e,
++ [0x5dea] = 0x3ce0, [0x5deb] = 0x2ea7, [0x5dec] = 0xe831, [0x5ded] = 0x9fb8,
+ [0x5dee] = 0x2eaa, [0x5def] = 0x4056, [0x5df0] = 0x415f, [0x5df1] = 0x2eae,
+ [0x5df2] = 0x4337, [0x5df3] = 0x2eb3, [0x5df4] = 0x2eb6, [0x5df5] = 0x2eb7,
+- [0x5df7] = 0x43b1, [0x5df8] = 0x43ac, [0x5df9] = 0x2ebb, [0x5dfa] = 0x43dd,
+- [0x5dfb] = 0x44d6, [0x5dfc] = 0x4661, [0x5dfd] = 0x464c, [0x5dfe] = 0x9fb9,
+- [0x5e00] = 0x4723, [0x5e01] = 0x4729, [0x5e02] = 0x477c, [0x5e03] = 0x478d,
+- [0x5e04] = 0x2eca, [0x5e05] = 0x4947, [0x5e06] = 0x497a, [0x5e07] = 0x497d,
+- [0x5e08] = 0x4982, [0x5e09] = 0x4983, [0x5e0a] = 0x4985, [0x5e0b] = 0x4986,
+- [0x5e0c] = 0x499f, [0x5e0d] = 0x499b, [0x5e0e] = 0x49b7, [0x5e0f] = 0x49b6,
+- [0x5e10] = 0x9fba, [0x5e12] = 0x4ca3, [0x5e13] = 0x4c9f, [0x5e14] = 0x4ca0,
+- [0x5e15] = 0x4ca1, [0x5e16] = 0x4c77, [0x5e17] = 0x4ca2, [0x5e18] = 0x4d13,
+- [0x5e19] = 0x4d14, [0x5e1a] = 0x4d15, [0x5e1b] = 0x4d16, [0x5e1c] = 0x4d17,
+- [0x5e1d] = 0x4d18, [0x5e1e] = 0x4d19, [0x5e1f] = 0x4dae, [0x5e20] = 0x9fbb,
+- [0x5e21] = 0xe468, [0x5e22] = 0xe469, [0x5e23] = 0xe46a, [0x5e24] = 0xe46b,
+- [0x5e25] = 0xe46c, [0x5e26] = 0xe46d, [0x5e27] = 0xe46e, [0x5e28] = 0xe46f,
+- [0x5e29] = 0xe470, [0x5e2a] = 0xe471, [0x5e2b] = 0xe472, [0x5e2c] = 0xe473,
+- [0x5e2d] = 0xe474, [0x5e2e] = 0xe475, [0x5e2f] = 0xe476, [0x5e30] = 0xe477,
+- [0x5e31] = 0xe478, [0x5e32] = 0xe479, [0x5e33] = 0xe47a, [0x5e34] = 0xe47b,
+- [0x5e35] = 0xe47c, [0x5e36] = 0xe47d, [0x5e37] = 0xe47e, [0x5e38] = 0xe47f,
+- [0x5e39] = 0xe480, [0x5e3a] = 0xe481, [0x5e3b] = 0xe482, [0x5e3c] = 0xe483,
+- [0x5e3d] = 0xe484, [0x5e3e] = 0xe485, [0x5e3f] = 0xe486, [0x5e40] = 0xe487,
+- [0x5e41] = 0xe488, [0x5e42] = 0xe489, [0x5e43] = 0xe48a, [0x5e44] = 0xe48b,
+- [0x5e45] = 0xe48c, [0x5e46] = 0xe48d, [0x5e47] = 0xe48e, [0x5e48] = 0xe48f,
+- [0x5e49] = 0xe490, [0x5e4a] = 0xe491, [0x5e4b] = 0xe492, [0x5e4c] = 0xe493,
+- [0x5e4d] = 0xe494, [0x5e4e] = 0xe495, [0x5e4f] = 0xe496, [0x5e50] = 0xe497,
+- [0x5e51] = 0xe498, [0x5e52] = 0xe499, [0x5e53] = 0xe49a, [0x5e54] = 0xe49b,
+- [0x5e55] = 0xe49c, [0x5e56] = 0xe49d, [0x5e57] = 0xe49e, [0x5e58] = 0xe49f,
+- [0x5e59] = 0xe4a0, [0x5e5a] = 0xe4a1, [0x5e5b] = 0xe4a2, [0x5e5c] = 0xe4a3,
+- [0x5e5d] = 0xe4a4, [0x5e5e] = 0xe4a5, [0x5e5f] = 0xe4a6, [0x5e60] = 0xe4a7,
+- [0x5e61] = 0xe4a8, [0x5e62] = 0xe4a9, [0x5e63] = 0xe4aa, [0x5e64] = 0xe4ab,
+- [0x5e65] = 0xe4ac, [0x5e66] = 0xe4ad, [0x5e67] = 0xe4ae, [0x5e68] = 0xe4af,
+- [0x5e69] = 0xe4b0, [0x5e6a] = 0xe4b1, [0x5e6b] = 0xe4b2, [0x5e6c] = 0xe4b3,
+- [0x5e6d] = 0xe4b4, [0x5e6e] = 0xe4b5, [0x5e6f] = 0xe4b6, [0x5e70] = 0xe4b7,
+- [0x5e71] = 0xe4b8, [0x5e72] = 0xe4b9, [0x5e73] = 0xe4ba, [0x5e74] = 0xe4bb,
+- [0x5e75] = 0xe4bc, [0x5e76] = 0xe4bd, [0x5e77] = 0xe4be, [0x5e78] = 0xe4bf,
+- [0x5e79] = 0xe4c0, [0x5e7a] = 0xe4c1, [0x5e7b] = 0xe4c2, [0x5e7c] = 0xe4c3,
+- [0x5e7d] = 0xe4c4, [0x5e7e] = 0xe4c5,
++ [0x5df6] = 0xe83b, [0x5df7] = 0x43b1, [0x5df8] = 0x43ac, [0x5df9] = 0x2ebb,
++ [0x5dfa] = 0x43dd, [0x5dfb] = 0x44d6, [0x5dfc] = 0x4661, [0x5dfd] = 0x464c,
++ [0x5dfe] = 0x9fb9, [0x5e00] = 0x4723, [0x5e01] = 0x4729, [0x5e02] = 0x477c,
++ [0x5e03] = 0x478d, [0x5e04] = 0x2eca, [0x5e05] = 0x4947, [0x5e06] = 0x497a,
++ [0x5e07] = 0x497d, [0x5e08] = 0x4982, [0x5e09] = 0x4983, [0x5e0a] = 0x4985,
++ [0x5e0b] = 0x4986, [0x5e0c] = 0x499f, [0x5e0d] = 0x499b, [0x5e0e] = 0x49b7,
++ [0x5e0f] = 0x49b6, [0x5e10] = 0x9fba, [0x5e11] = 0xe855, [0x5e12] = 0x4ca3,
++ [0x5e13] = 0x4c9f, [0x5e14] = 0x4ca0, [0x5e15] = 0x4ca1, [0x5e16] = 0x4c77,
++ [0x5e17] = 0x4ca2, [0x5e18] = 0x4d13, [0x5e19] = 0x4d14, [0x5e1a] = 0x4d15,
++ [0x5e1b] = 0x4d16, [0x5e1c] = 0x4d17, [0x5e1d] = 0x4d18, [0x5e1e] = 0x4d19,
++ [0x5e1f] = 0x4dae, [0x5e20] = 0x9fbb, [0x5e21] = 0xe468, [0x5e22] = 0xe469,
++ [0x5e23] = 0xe46a, [0x5e24] = 0xe46b, [0x5e25] = 0xe46c, [0x5e26] = 0xe46d,
++ [0x5e27] = 0xe46e, [0x5e28] = 0xe46f, [0x5e29] = 0xe470, [0x5e2a] = 0xe471,
++ [0x5e2b] = 0xe472, [0x5e2c] = 0xe473, [0x5e2d] = 0xe474, [0x5e2e] = 0xe475,
++ [0x5e2f] = 0xe476, [0x5e30] = 0xe477, [0x5e31] = 0xe478, [0x5e32] = 0xe479,
++ [0x5e33] = 0xe47a, [0x5e34] = 0xe47b, [0x5e35] = 0xe47c, [0x5e36] = 0xe47d,
++ [0x5e37] = 0xe47e, [0x5e38] = 0xe47f, [0x5e39] = 0xe480, [0x5e3a] = 0xe481,
++ [0x5e3b] = 0xe482, [0x5e3c] = 0xe483, [0x5e3d] = 0xe484, [0x5e3e] = 0xe485,
++ [0x5e3f] = 0xe486, [0x5e40] = 0xe487, [0x5e41] = 0xe488, [0x5e42] = 0xe489,
++ [0x5e43] = 0xe48a, [0x5e44] = 0xe48b, [0x5e45] = 0xe48c, [0x5e46] = 0xe48d,
++ [0x5e47] = 0xe48e, [0x5e48] = 0xe48f, [0x5e49] = 0xe490, [0x5e4a] = 0xe491,
++ [0x5e4b] = 0xe492, [0x5e4c] = 0xe493, [0x5e4d] = 0xe494, [0x5e4e] = 0xe495,
++ [0x5e4f] = 0xe496, [0x5e50] = 0xe497, [0x5e51] = 0xe498, [0x5e52] = 0xe499,
++ [0x5e53] = 0xe49a, [0x5e54] = 0xe49b, [0x5e55] = 0xe49c, [0x5e56] = 0xe49d,
++ [0x5e57] = 0xe49e, [0x5e58] = 0xe49f, [0x5e59] = 0xe4a0, [0x5e5a] = 0xe4a1,
++ [0x5e5b] = 0xe4a2, [0x5e5c] = 0xe4a3, [0x5e5d] = 0xe4a4, [0x5e5e] = 0xe4a5,
++ [0x5e5f] = 0xe4a6, [0x5e60] = 0xe4a7, [0x5e61] = 0xe4a8, [0x5e62] = 0xe4a9,
++ [0x5e63] = 0xe4aa, [0x5e64] = 0xe4ab, [0x5e65] = 0xe4ac, [0x5e66] = 0xe4ad,
++ [0x5e67] = 0xe4ae, [0x5e68] = 0xe4af, [0x5e69] = 0xe4b0, [0x5e6a] = 0xe4b1,
++ [0x5e6b] = 0xe4b2, [0x5e6c] = 0xe4b3, [0x5e6d] = 0xe4b4, [0x5e6e] = 0xe4b5,
++ [0x5e6f] = 0xe4b6, [0x5e70] = 0xe4b7, [0x5e71] = 0xe4b8, [0x5e72] = 0xe4b9,
++ [0x5e73] = 0xe4ba, [0x5e74] = 0xe4bb, [0x5e75] = 0xe4bc, [0x5e76] = 0xe4bd,
++ [0x5e77] = 0xe4be, [0x5e78] = 0xe4bf, [0x5e79] = 0xe4c0, [0x5e7a] = 0xe4c1,
++ [0x5e7b] = 0xe4c2, [0x5e7c] = 0xe4c3, [0x5e7d] = 0xe4c4, [0x5e7e] = 0xe4c5,
+ };
+
+ /* Table for GB18030 -> UCS-4, containing the four-byte characters only,
+@@ -8691,7 +8692,9 @@ static const uint16_t __fourbyte_to_ucs[0x99e2 - 6637 - 2110 - 14404 - 4295] =
+ [0x2838] = 0x9fa6, [0x2839] = 0x9fa7, [0x283a] = 0x9fa8, [0x283b] = 0x9fa9,
+ [0x283c] = 0x9faa, [0x283d] = 0x9fab, [0x283e] = 0x9fac, [0x283f] = 0x9fad,
+ [0x2840] = 0x9fae, [0x2841] = 0x9faf, [0x2842] = 0x9fb0, [0x2843] = 0x9fb1,
+- [0x2844] = 0x9fb2, [0x2845] = 0x9fb3, [0x284e] = 0xe76c, [0x284f] = 0xe7c8,
++ [0x2844] = 0x9fb2, [0x2845] = 0x9fb3, [0x2846] = 0xe81e, [0x2847] = 0xe826,
++ [0x2848] = 0xe82b, [0x2849] = 0xe82c, [0x284a] = 0xe832, [0x284b] = 0xe843,
++ [0x284c] = 0xe854, [0x284d] = 0xe864, [0x284e] = 0xe76c, [0x284f] = 0xe7c8,
+ [0x2850] = 0xe7e7, [0x2851] = 0xe7e8, [0x2852] = 0xe7e9, [0x2853] = 0xe7ea,
+ [0x2854] = 0xe7eb, [0x2855] = 0xe7ec, [0x2856] = 0xe7ed, [0x2857] = 0xe7ee,
+ [0x2858] = 0xe7ef, [0x2859] = 0xe7f0, [0x285a] = 0xe7f1, [0x285b] = 0xe7f2,
+@@ -9019,84 +9022,86 @@ static const uint16_t __fourbyte_to_ucs[0x99e2 - 6637 - 2110 - 14404 - 4295] =
+ [0x2d60] = 0xfe02, [0x2d61] = 0xfe03, [0x2d62] = 0xfe04, [0x2d63] = 0xfe05,
+ [0x2d64] = 0xfe06, [0x2d65] = 0xfe07, [0x2d66] = 0xfe08, [0x2d67] = 0xfe09,
+ [0x2d68] = 0xfe0a, [0x2d69] = 0xfe0b, [0x2d6a] = 0xfe0c, [0x2d6b] = 0xfe0d,
+- [0x2d6c] = 0xfe0e, [0x2d6d] = 0xfe0f, [0x2d78] = 0xfe1a, [0x2d79] = 0xfe1b,
+- [0x2d7a] = 0xfe1c, [0x2d7b] = 0xfe1d, [0x2d7c] = 0xfe1e, [0x2d7d] = 0xfe1f,
+- [0x2d7e] = 0xfe20, [0x2d7f] = 0xfe21, [0x2d80] = 0xfe22, [0x2d81] = 0xfe23,
+- [0x2d82] = 0xfe24, [0x2d83] = 0xfe25, [0x2d84] = 0xfe26, [0x2d85] = 0xfe27,
+- [0x2d86] = 0xfe28, [0x2d87] = 0xfe29, [0x2d88] = 0xfe2a, [0x2d89] = 0xfe2b,
+- [0x2d8a] = 0xfe2c, [0x2d8b] = 0xfe2d, [0x2d8c] = 0xfe2e, [0x2d8d] = 0xfe2f,
+- [0x2d8e] = 0xfe32, [0x2d8f] = 0xfe45, [0x2d90] = 0xfe46, [0x2d91] = 0xfe47,
+- [0x2d92] = 0xfe48, [0x2d93] = 0xfe53, [0x2d94] = 0xfe58, [0x2d95] = 0xfe67,
+- [0x2d96] = 0xfe6c, [0x2d97] = 0xfe6d, [0x2d98] = 0xfe6e, [0x2d99] = 0xfe6f,
+- [0x2d9a] = 0xfe70, [0x2d9b] = 0xfe71, [0x2d9c] = 0xfe72, [0x2d9d] = 0xfe73,
+- [0x2d9e] = 0xfe74, [0x2d9f] = 0xfe75, [0x2da0] = 0xfe76, [0x2da1] = 0xfe77,
+- [0x2da2] = 0xfe78, [0x2da3] = 0xfe79, [0x2da4] = 0xfe7a, [0x2da5] = 0xfe7b,
+- [0x2da6] = 0xfe7c, [0x2da7] = 0xfe7d, [0x2da8] = 0xfe7e, [0x2da9] = 0xfe7f,
+- [0x2daa] = 0xfe80, [0x2dab] = 0xfe81, [0x2dac] = 0xfe82, [0x2dad] = 0xfe83,
+- [0x2dae] = 0xfe84, [0x2daf] = 0xfe85, [0x2db0] = 0xfe86, [0x2db1] = 0xfe87,
+- [0x2db2] = 0xfe88, [0x2db3] = 0xfe89, [0x2db4] = 0xfe8a, [0x2db5] = 0xfe8b,
+- [0x2db6] = 0xfe8c, [0x2db7] = 0xfe8d, [0x2db8] = 0xfe8e, [0x2db9] = 0xfe8f,
+- [0x2dba] = 0xfe90, [0x2dbb] = 0xfe91, [0x2dbc] = 0xfe92, [0x2dbd] = 0xfe93,
+- [0x2dbe] = 0xfe94, [0x2dbf] = 0xfe95, [0x2dc0] = 0xfe96, [0x2dc1] = 0xfe97,
+- [0x2dc2] = 0xfe98, [0x2dc3] = 0xfe99, [0x2dc4] = 0xfe9a, [0x2dc5] = 0xfe9b,
+- [0x2dc6] = 0xfe9c, [0x2dc7] = 0xfe9d, [0x2dc8] = 0xfe9e, [0x2dc9] = 0xfe9f,
+- [0x2dca] = 0xfea0, [0x2dcb] = 0xfea1, [0x2dcc] = 0xfea2, [0x2dcd] = 0xfea3,
+- [0x2dce] = 0xfea4, [0x2dcf] = 0xfea5, [0x2dd0] = 0xfea6, [0x2dd1] = 0xfea7,
+- [0x2dd2] = 0xfea8, [0x2dd3] = 0xfea9, [0x2dd4] = 0xfeaa, [0x2dd5] = 0xfeab,
+- [0x2dd6] = 0xfeac, [0x2dd7] = 0xfead, [0x2dd8] = 0xfeae, [0x2dd9] = 0xfeaf,
+- [0x2dda] = 0xfeb0, [0x2ddb] = 0xfeb1, [0x2ddc] = 0xfeb2, [0x2ddd] = 0xfeb3,
+- [0x2dde] = 0xfeb4, [0x2ddf] = 0xfeb5, [0x2de0] = 0xfeb6, [0x2de1] = 0xfeb7,
+- [0x2de2] = 0xfeb8, [0x2de3] = 0xfeb9, [0x2de4] = 0xfeba, [0x2de5] = 0xfebb,
+- [0x2de6] = 0xfebc, [0x2de7] = 0xfebd, [0x2de8] = 0xfebe, [0x2de9] = 0xfebf,
+- [0x2dea] = 0xfec0, [0x2deb] = 0xfec1, [0x2dec] = 0xfec2, [0x2ded] = 0xfec3,
+- [0x2dee] = 0xfec4, [0x2def] = 0xfec5, [0x2df0] = 0xfec6, [0x2df1] = 0xfec7,
+- [0x2df2] = 0xfec8, [0x2df3] = 0xfec9, [0x2df4] = 0xfeca, [0x2df5] = 0xfecb,
+- [0x2df6] = 0xfecc, [0x2df7] = 0xfecd, [0x2df8] = 0xfece, [0x2df9] = 0xfecf,
+- [0x2dfa] = 0xfed0, [0x2dfb] = 0xfed1, [0x2dfc] = 0xfed2, [0x2dfd] = 0xfed3,
+- [0x2dfe] = 0xfed4, [0x2dff] = 0xfed5, [0x2e00] = 0xfed6, [0x2e01] = 0xfed7,
+- [0x2e02] = 0xfed8, [0x2e03] = 0xfed9, [0x2e04] = 0xfeda, [0x2e05] = 0xfedb,
+- [0x2e06] = 0xfedc, [0x2e07] = 0xfedd, [0x2e08] = 0xfede, [0x2e09] = 0xfedf,
+- [0x2e0a] = 0xfee0, [0x2e0b] = 0xfee1, [0x2e0c] = 0xfee2, [0x2e0d] = 0xfee3,
+- [0x2e0e] = 0xfee4, [0x2e0f] = 0xfee5, [0x2e10] = 0xfee6, [0x2e11] = 0xfee7,
+- [0x2e12] = 0xfee8, [0x2e13] = 0xfee9, [0x2e14] = 0xfeea, [0x2e15] = 0xfeeb,
+- [0x2e16] = 0xfeec, [0x2e17] = 0xfeed, [0x2e18] = 0xfeee, [0x2e19] = 0xfeef,
+- [0x2e1a] = 0xfef0, [0x2e1b] = 0xfef1, [0x2e1c] = 0xfef2, [0x2e1d] = 0xfef3,
+- [0x2e1e] = 0xfef4, [0x2e1f] = 0xfef5, [0x2e20] = 0xfef6, [0x2e21] = 0xfef7,
+- [0x2e22] = 0xfef8, [0x2e23] = 0xfef9, [0x2e24] = 0xfefa, [0x2e25] = 0xfefb,
+- [0x2e26] = 0xfefc, [0x2e27] = 0xfefd, [0x2e28] = 0xfefe, [0x2e29] = 0xfeff,
+- [0x2e2a] = 0xff00, [0x2e2b] = 0xff5f, [0x2e2c] = 0xff60, [0x2e2d] = 0xff61,
+- [0x2e2e] = 0xff62, [0x2e2f] = 0xff63, [0x2e30] = 0xff64, [0x2e31] = 0xff65,
+- [0x2e32] = 0xff66, [0x2e33] = 0xff67, [0x2e34] = 0xff68, [0x2e35] = 0xff69,
+- [0x2e36] = 0xff6a, [0x2e37] = 0xff6b, [0x2e38] = 0xff6c, [0x2e39] = 0xff6d,
+- [0x2e3a] = 0xff6e, [0x2e3b] = 0xff6f, [0x2e3c] = 0xff70, [0x2e3d] = 0xff71,
+- [0x2e3e] = 0xff72, [0x2e3f] = 0xff73, [0x2e40] = 0xff74, [0x2e41] = 0xff75,
+- [0x2e42] = 0xff76, [0x2e43] = 0xff77, [0x2e44] = 0xff78, [0x2e45] = 0xff79,
+- [0x2e46] = 0xff7a, [0x2e47] = 0xff7b, [0x2e48] = 0xff7c, [0x2e49] = 0xff7d,
+- [0x2e4a] = 0xff7e, [0x2e4b] = 0xff7f, [0x2e4c] = 0xff80, [0x2e4d] = 0xff81,
+- [0x2e4e] = 0xff82, [0x2e4f] = 0xff83, [0x2e50] = 0xff84, [0x2e51] = 0xff85,
+- [0x2e52] = 0xff86, [0x2e53] = 0xff87, [0x2e54] = 0xff88, [0x2e55] = 0xff89,
+- [0x2e56] = 0xff8a, [0x2e57] = 0xff8b, [0x2e58] = 0xff8c, [0x2e59] = 0xff8d,
+- [0x2e5a] = 0xff8e, [0x2e5b] = 0xff8f, [0x2e5c] = 0xff90, [0x2e5d] = 0xff91,
+- [0x2e5e] = 0xff92, [0x2e5f] = 0xff93, [0x2e60] = 0xff94, [0x2e61] = 0xff95,
+- [0x2e62] = 0xff96, [0x2e63] = 0xff97, [0x2e64] = 0xff98, [0x2e65] = 0xff99,
+- [0x2e66] = 0xff9a, [0x2e67] = 0xff9b, [0x2e68] = 0xff9c, [0x2e69] = 0xff9d,
+- [0x2e6a] = 0xff9e, [0x2e6b] = 0xff9f, [0x2e6c] = 0xffa0, [0x2e6d] = 0xffa1,
+- [0x2e6e] = 0xffa2, [0x2e6f] = 0xffa3, [0x2e70] = 0xffa4, [0x2e71] = 0xffa5,
+- [0x2e72] = 0xffa6, [0x2e73] = 0xffa7, [0x2e74] = 0xffa8, [0x2e75] = 0xffa9,
+- [0x2e76] = 0xffaa, [0x2e77] = 0xffab, [0x2e78] = 0xffac, [0x2e79] = 0xffad,
+- [0x2e7a] = 0xffae, [0x2e7b] = 0xffaf, [0x2e7c] = 0xffb0, [0x2e7d] = 0xffb1,
+- [0x2e7e] = 0xffb2, [0x2e7f] = 0xffb3, [0x2e80] = 0xffb4, [0x2e81] = 0xffb5,
+- [0x2e82] = 0xffb6, [0x2e83] = 0xffb7, [0x2e84] = 0xffb8, [0x2e85] = 0xffb9,
+- [0x2e86] = 0xffba, [0x2e87] = 0xffbb, [0x2e88] = 0xffbc, [0x2e89] = 0xffbd,
+- [0x2e8a] = 0xffbe, [0x2e8b] = 0xffbf, [0x2e8c] = 0xffc0, [0x2e8d] = 0xffc1,
+- [0x2e8e] = 0xffc2, [0x2e8f] = 0xffc3, [0x2e90] = 0xffc4, [0x2e91] = 0xffc5,
+- [0x2e92] = 0xffc6, [0x2e93] = 0xffc7, [0x2e94] = 0xffc8, [0x2e95] = 0xffc9,
+- [0x2e96] = 0xffca, [0x2e97] = 0xffcb, [0x2e98] = 0xffcc, [0x2e99] = 0xffcd,
+- [0x2e9a] = 0xffce, [0x2e9b] = 0xffcf, [0x2e9c] = 0xffd0, [0x2e9d] = 0xffd1,
+- [0x2e9e] = 0xffd2, [0x2e9f] = 0xffd3, [0x2ea0] = 0xffd4, [0x2ea1] = 0xffd5,
+- [0x2ea2] = 0xffd6, [0x2ea3] = 0xffd7, [0x2ea4] = 0xffd8, [0x2ea5] = 0xffd9,
+- [0x2ea6] = 0xffda, [0x2ea7] = 0xffdb, [0x2ea8] = 0xffdc, [0x2ea9] = 0xffdd,
+- [0x2eaa] = 0xffde, [0x2eab] = 0xffdf,
++ [0x2d6c] = 0xfe0e, [0x2d6d] = 0xfe0f, [0x2d6e] = 0xe78d, [0x2d6f] = 0xe78f,
++ [0x2d70] = 0xe78e, [0x2d71] = 0xe790, [0x2d72] = 0xe791, [0x2d73] = 0xe792,
++ [0x2d74] = 0xe793, [0x2d75] = 0xe794, [0x2d76] = 0xe795, [0x2d77] = 0xe796,
++ [0x2d78] = 0xfe1a, [0x2d79] = 0xfe1b, [0x2d7a] = 0xfe1c, [0x2d7b] = 0xfe1d,
++ [0x2d7c] = 0xfe1e, [0x2d7d] = 0xfe1f, [0x2d7e] = 0xfe20, [0x2d7f] = 0xfe21,
++ [0x2d80] = 0xfe22, [0x2d81] = 0xfe23, [0x2d82] = 0xfe24, [0x2d83] = 0xfe25,
++ [0x2d84] = 0xfe26, [0x2d85] = 0xfe27, [0x2d86] = 0xfe28, [0x2d87] = 0xfe29,
++ [0x2d88] = 0xfe2a, [0x2d89] = 0xfe2b, [0x2d8a] = 0xfe2c, [0x2d8b] = 0xfe2d,
++ [0x2d8c] = 0xfe2e, [0x2d8d] = 0xfe2f, [0x2d8e] = 0xfe32, [0x2d8f] = 0xfe45,
++ [0x2d90] = 0xfe46, [0x2d91] = 0xfe47, [0x2d92] = 0xfe48, [0x2d93] = 0xfe53,
++ [0x2d94] = 0xfe58, [0x2d95] = 0xfe67, [0x2d96] = 0xfe6c, [0x2d97] = 0xfe6d,
++ [0x2d98] = 0xfe6e, [0x2d99] = 0xfe6f, [0x2d9a] = 0xfe70, [0x2d9b] = 0xfe71,
++ [0x2d9c] = 0xfe72, [0x2d9d] = 0xfe73, [0x2d9e] = 0xfe74, [0x2d9f] = 0xfe75,
++ [0x2da0] = 0xfe76, [0x2da1] = 0xfe77, [0x2da2] = 0xfe78, [0x2da3] = 0xfe79,
++ [0x2da4] = 0xfe7a, [0x2da5] = 0xfe7b, [0x2da6] = 0xfe7c, [0x2da7] = 0xfe7d,
++ [0x2da8] = 0xfe7e, [0x2da9] = 0xfe7f, [0x2daa] = 0xfe80, [0x2dab] = 0xfe81,
++ [0x2dac] = 0xfe82, [0x2dad] = 0xfe83, [0x2dae] = 0xfe84, [0x2daf] = 0xfe85,
++ [0x2db0] = 0xfe86, [0x2db1] = 0xfe87, [0x2db2] = 0xfe88, [0x2db3] = 0xfe89,
++ [0x2db4] = 0xfe8a, [0x2db5] = 0xfe8b, [0x2db6] = 0xfe8c, [0x2db7] = 0xfe8d,
++ [0x2db8] = 0xfe8e, [0x2db9] = 0xfe8f, [0x2dba] = 0xfe90, [0x2dbb] = 0xfe91,
++ [0x2dbc] = 0xfe92, [0x2dbd] = 0xfe93, [0x2dbe] = 0xfe94, [0x2dbf] = 0xfe95,
++ [0x2dc0] = 0xfe96, [0x2dc1] = 0xfe97, [0x2dc2] = 0xfe98, [0x2dc3] = 0xfe99,
++ [0x2dc4] = 0xfe9a, [0x2dc5] = 0xfe9b, [0x2dc6] = 0xfe9c, [0x2dc7] = 0xfe9d,
++ [0x2dc8] = 0xfe9e, [0x2dc9] = 0xfe9f, [0x2dca] = 0xfea0, [0x2dcb] = 0xfea1,
++ [0x2dcc] = 0xfea2, [0x2dcd] = 0xfea3, [0x2dce] = 0xfea4, [0x2dcf] = 0xfea5,
++ [0x2dd0] = 0xfea6, [0x2dd1] = 0xfea7, [0x2dd2] = 0xfea8, [0x2dd3] = 0xfea9,
++ [0x2dd4] = 0xfeaa, [0x2dd5] = 0xfeab, [0x2dd6] = 0xfeac, [0x2dd7] = 0xfead,
++ [0x2dd8] = 0xfeae, [0x2dd9] = 0xfeaf, [0x2dda] = 0xfeb0, [0x2ddb] = 0xfeb1,
++ [0x2ddc] = 0xfeb2, [0x2ddd] = 0xfeb3, [0x2dde] = 0xfeb4, [0x2ddf] = 0xfeb5,
++ [0x2de0] = 0xfeb6, [0x2de1] = 0xfeb7, [0x2de2] = 0xfeb8, [0x2de3] = 0xfeb9,
++ [0x2de4] = 0xfeba, [0x2de5] = 0xfebb, [0x2de6] = 0xfebc, [0x2de7] = 0xfebd,
++ [0x2de8] = 0xfebe, [0x2de9] = 0xfebf, [0x2dea] = 0xfec0, [0x2deb] = 0xfec1,
++ [0x2dec] = 0xfec2, [0x2ded] = 0xfec3, [0x2dee] = 0xfec4, [0x2def] = 0xfec5,
++ [0x2df0] = 0xfec6, [0x2df1] = 0xfec7, [0x2df2] = 0xfec8, [0x2df3] = 0xfec9,
++ [0x2df4] = 0xfeca, [0x2df5] = 0xfecb, [0x2df6] = 0xfecc, [0x2df7] = 0xfecd,
++ [0x2df8] = 0xfece, [0x2df9] = 0xfecf, [0x2dfa] = 0xfed0, [0x2dfb] = 0xfed1,
++ [0x2dfc] = 0xfed2, [0x2dfd] = 0xfed3, [0x2dfe] = 0xfed4, [0x2dff] = 0xfed5,
++ [0x2e00] = 0xfed6, [0x2e01] = 0xfed7, [0x2e02] = 0xfed8, [0x2e03] = 0xfed9,
++ [0x2e04] = 0xfeda, [0x2e05] = 0xfedb, [0x2e06] = 0xfedc, [0x2e07] = 0xfedd,
++ [0x2e08] = 0xfede, [0x2e09] = 0xfedf, [0x2e0a] = 0xfee0, [0x2e0b] = 0xfee1,
++ [0x2e0c] = 0xfee2, [0x2e0d] = 0xfee3, [0x2e0e] = 0xfee4, [0x2e0f] = 0xfee5,
++ [0x2e10] = 0xfee6, [0x2e11] = 0xfee7, [0x2e12] = 0xfee8, [0x2e13] = 0xfee9,
++ [0x2e14] = 0xfeea, [0x2e15] = 0xfeeb, [0x2e16] = 0xfeec, [0x2e17] = 0xfeed,
++ [0x2e18] = 0xfeee, [0x2e19] = 0xfeef, [0x2e1a] = 0xfef0, [0x2e1b] = 0xfef1,
++ [0x2e1c] = 0xfef2, [0x2e1d] = 0xfef3, [0x2e1e] = 0xfef4, [0x2e1f] = 0xfef5,
++ [0x2e20] = 0xfef6, [0x2e21] = 0xfef7, [0x2e22] = 0xfef8, [0x2e23] = 0xfef9,
++ [0x2e24] = 0xfefa, [0x2e25] = 0xfefb, [0x2e26] = 0xfefc, [0x2e27] = 0xfefd,
++ [0x2e28] = 0xfefe, [0x2e29] = 0xfeff, [0x2e2a] = 0xff00, [0x2e2b] = 0xff5f,
++ [0x2e2c] = 0xff60, [0x2e2d] = 0xff61, [0x2e2e] = 0xff62, [0x2e2f] = 0xff63,
++ [0x2e30] = 0xff64, [0x2e31] = 0xff65, [0x2e32] = 0xff66, [0x2e33] = 0xff67,
++ [0x2e34] = 0xff68, [0x2e35] = 0xff69, [0x2e36] = 0xff6a, [0x2e37] = 0xff6b,
++ [0x2e38] = 0xff6c, [0x2e39] = 0xff6d, [0x2e3a] = 0xff6e, [0x2e3b] = 0xff6f,
++ [0x2e3c] = 0xff70, [0x2e3d] = 0xff71, [0x2e3e] = 0xff72, [0x2e3f] = 0xff73,
++ [0x2e40] = 0xff74, [0x2e41] = 0xff75, [0x2e42] = 0xff76, [0x2e43] = 0xff77,
++ [0x2e44] = 0xff78, [0x2e45] = 0xff79, [0x2e46] = 0xff7a, [0x2e47] = 0xff7b,
++ [0x2e48] = 0xff7c, [0x2e49] = 0xff7d, [0x2e4a] = 0xff7e, [0x2e4b] = 0xff7f,
++ [0x2e4c] = 0xff80, [0x2e4d] = 0xff81, [0x2e4e] = 0xff82, [0x2e4f] = 0xff83,
++ [0x2e50] = 0xff84, [0x2e51] = 0xff85, [0x2e52] = 0xff86, [0x2e53] = 0xff87,
++ [0x2e54] = 0xff88, [0x2e55] = 0xff89, [0x2e56] = 0xff8a, [0x2e57] = 0xff8b,
++ [0x2e58] = 0xff8c, [0x2e59] = 0xff8d, [0x2e5a] = 0xff8e, [0x2e5b] = 0xff8f,
++ [0x2e5c] = 0xff90, [0x2e5d] = 0xff91, [0x2e5e] = 0xff92, [0x2e5f] = 0xff93,
++ [0x2e60] = 0xff94, [0x2e61] = 0xff95, [0x2e62] = 0xff96, [0x2e63] = 0xff97,
++ [0x2e64] = 0xff98, [0x2e65] = 0xff99, [0x2e66] = 0xff9a, [0x2e67] = 0xff9b,
++ [0x2e68] = 0xff9c, [0x2e69] = 0xff9d, [0x2e6a] = 0xff9e, [0x2e6b] = 0xff9f,
++ [0x2e6c] = 0xffa0, [0x2e6d] = 0xffa1, [0x2e6e] = 0xffa2, [0x2e6f] = 0xffa3,
++ [0x2e70] = 0xffa4, [0x2e71] = 0xffa5, [0x2e72] = 0xffa6, [0x2e73] = 0xffa7,
++ [0x2e74] = 0xffa8, [0x2e75] = 0xffa9, [0x2e76] = 0xffaa, [0x2e77] = 0xffab,
++ [0x2e78] = 0xffac, [0x2e79] = 0xffad, [0x2e7a] = 0xffae, [0x2e7b] = 0xffaf,
++ [0x2e7c] = 0xffb0, [0x2e7d] = 0xffb1, [0x2e7e] = 0xffb2, [0x2e7f] = 0xffb3,
++ [0x2e80] = 0xffb4, [0x2e81] = 0xffb5, [0x2e82] = 0xffb6, [0x2e83] = 0xffb7,
++ [0x2e84] = 0xffb8, [0x2e85] = 0xffb9, [0x2e86] = 0xffba, [0x2e87] = 0xffbb,
++ [0x2e88] = 0xffbc, [0x2e89] = 0xffbd, [0x2e8a] = 0xffbe, [0x2e8b] = 0xffbf,
++ [0x2e8c] = 0xffc0, [0x2e8d] = 0xffc1, [0x2e8e] = 0xffc2, [0x2e8f] = 0xffc3,
++ [0x2e90] = 0xffc4, [0x2e91] = 0xffc5, [0x2e92] = 0xffc6, [0x2e93] = 0xffc7,
++ [0x2e94] = 0xffc8, [0x2e95] = 0xffc9, [0x2e96] = 0xffca, [0x2e97] = 0xffcb,
++ [0x2e98] = 0xffcc, [0x2e99] = 0xffcd, [0x2e9a] = 0xffce, [0x2e9b] = 0xffcf,
++ [0x2e9c] = 0xffd0, [0x2e9d] = 0xffd1, [0x2e9e] = 0xffd2, [0x2e9f] = 0xffd3,
++ [0x2ea0] = 0xffd4, [0x2ea1] = 0xffd5, [0x2ea2] = 0xffd6, [0x2ea3] = 0xffd7,
++ [0x2ea4] = 0xffd8, [0x2ea5] = 0xffd9, [0x2ea6] = 0xffda, [0x2ea7] = 0xffdb,
++ [0x2ea8] = 0xffdc, [0x2ea9] = 0xffdd, [0x2eaa] = 0xffde, [0x2eab] = 0xffdf,
+ };
+
+ /* Table for UCS-4 -> GB18030, for the range U+0080..U+9FBB.
+@@ -23448,71 +23453,79 @@ static const unsigned char __ucs_to_gb18030_tab2[][2] =
+ [0x0783] = "\xa5\xfd", [0x0784] = "\xa5\xfe", [0x0785] = "\xa6\xb9",
+ [0x0786] = "\xa6\xba", [0x0787] = "\xa6\xbb", [0x0788] = "\xa6\xbc",
+ [0x0789] = "\xa6\xbd", [0x078a] = "\xa6\xbe", [0x078b] = "\xa6\xbf",
+- [0x078c] = "\xa6\xc0", [0x0797] = "\xa6\xf6", [0x0798] = "\xa6\xf7",
+- [0x0799] = "\xa6\xf8", [0x079a] = "\xa6\xf9", [0x079b] = "\xa6\xfa",
+- [0x079c] = "\xa6\xfb", [0x079d] = "\xa6\xfc", [0x079e] = "\xa6\xfd",
+- [0x079f] = "\xa6\xfe", [0x07a0] = "\xa7\xc2", [0x07a1] = "\xa7\xc3",
+- [0x07a2] = "\xa7\xc4", [0x07a3] = "\xa7\xc5", [0x07a4] = "\xa7\xc6",
+- [0x07a5] = "\xa7\xc7", [0x07a6] = "\xa7\xc8", [0x07a7] = "\xa7\xc9",
+- [0x07a8] = "\xa7\xca", [0x07a9] = "\xa7\xcb", [0x07aa] = "\xa7\xcc",
+- [0x07ab] = "\xa7\xcd", [0x07ac] = "\xa7\xce", [0x07ad] = "\xa7\xcf",
+- [0x07ae] = "\xa7\xd0", [0x07af] = "\xa7\xf2", [0x07b0] = "\xa7\xf3",
+- [0x07b1] = "\xa7\xf4", [0x07b2] = "\xa7\xf5", [0x07b3] = "\xa7\xf6",
+- [0x07b4] = "\xa7\xf7", [0x07b5] = "\xa7\xf8", [0x07b6] = "\xa7\xf9",
+- [0x07b7] = "\xa7\xfa", [0x07b8] = "\xa7\xfb", [0x07b9] = "\xa7\xfc",
+- [0x07ba] = "\xa7\xfd", [0x07bb] = "\xa7\xfe", [0x07bc] = "\xa8\x96",
+- [0x07bd] = "\xa8\x97", [0x07be] = "\xa8\x98", [0x07bf] = "\xa8\x99",
+- [0x07c0] = "\xa8\x9a", [0x07c1] = "\xa8\x9b", [0x07c2] = "\xa8\x9c",
+- [0x07c3] = "\xa8\x9d", [0x07c4] = "\xa8\x9e", [0x07c5] = "\xa8\x9f",
+- [0x07c6] = "\xa8\xa0", [0x07c7] = "\x00\x01", [0x07c8] = "\x65\x9e",
+- [0x07c9] = "\xa8\xc1", [0x07ca] = "\xa8\xc2", [0x07cb] = "\xa8\xc3",
+- [0x07cc] = "\xa8\xc4", [0x07cd] = "\xa8\xea", [0x07ce] = "\xa8\xeb",
+- [0x07cf] = "\xa8\xec", [0x07d0] = "\xa8\xed", [0x07d1] = "\xa8\xee",
+- [0x07d2] = "\xa8\xef", [0x07d3] = "\xa8\xf0", [0x07d4] = "\xa8\xf1",
+- [0x07d5] = "\xa8\xf2", [0x07d6] = "\xa8\xf3", [0x07d7] = "\xa8\xf4",
+- [0x07d8] = "\xa8\xf5", [0x07d9] = "\xa8\xf6", [0x07da] = "\xa8\xf7",
+- [0x07db] = "\xa8\xf8", [0x07dc] = "\xa8\xf9", [0x07dd] = "\xa8\xfa",
+- [0x07de] = "\xa8\xfb", [0x07df] = "\xa8\xfc", [0x07e0] = "\xa8\xfd",
+- [0x07e1] = "\xa8\xfe", [0x07e2] = "\xa9\x58", [0x07e3] = "\xa9\x5b",
+- [0x07e4] = "\xa9\x5d", [0x07e5] = "\xa9\x5e", [0x07e6] = "\xa9\x5f",
+- [0x07e7] = "\x65\x9f", [0x07e8] = "\x65\xa0", [0x07e9] = "\x65\xa1",
+- [0x07ea] = "\x65\xa2", [0x07eb] = "\x65\xa3", [0x07ec] = "\x65\xa4",
+- [0x07ed] = "\x65\xa5", [0x07ee] = "\x65\xa6", [0x07ef] = "\x65\xa7",
+- [0x07f0] = "\x65\xa8", [0x07f1] = "\x65\xa9", [0x07f2] = "\x65\xaa",
+- [0x07f3] = "\x65\xab", [0x07f4] = "\xa9\x97", [0x07f5] = "\xa9\x98",
+- [0x07f6] = "\xa9\x99", [0x07f7] = "\xa9\x9a", [0x07f8] = "\xa9\x9b",
+- [0x07f9] = "\xa9\x9c", [0x07fa] = "\xa9\x9d", [0x07fb] = "\xa9\x9e",
+- [0x07fc] = "\xa9\x9f", [0x07fd] = "\xa9\xa0", [0x07fe] = "\xa9\xa1",
+- [0x07ff] = "\xa9\xa2", [0x0800] = "\xa9\xa3", [0x0801] = "\xa9\xf0",
+- [0x0802] = "\xa9\xf1", [0x0803] = "\xa9\xf2", [0x0804] = "\xa9\xf3",
+- [0x0805] = "\xa9\xf4", [0x0806] = "\xa9\xf5", [0x0807] = "\xa9\xf6",
+- [0x0808] = "\xa9\xf7", [0x0809] = "\xa9\xf8", [0x080a] = "\xa9\xf9",
+- [0x080b] = "\xa9\xfa", [0x080c] = "\xa9\xfb", [0x080d] = "\xa9\xfc",
+- [0x080e] = "\xa9\xfd", [0x080f] = "\xa9\xfe", [0x0810] = "\xd7\xfa",
+- [0x0811] = "\xd7\xfb", [0x0812] = "\xd7\xfc", [0x0813] = "\xd7\xfd",
+- [0x0814] = "\xd7\xfe", [0x0815] = "\x65\xac", [0x0819] = "\x65\xad",
+- [0x081a] = "\x65\xae", [0x081b] = "\x65\xaf", [0x081c] = "\x65\xb0",
+- [0x081d] = "\x65\xb1", [0x081f] = "\x65\xb2", [0x0820] = "\x65\xb3",
+- [0x0821] = "\x65\xb4", [0x0822] = "\x65\xb5", [0x0823] = "\x65\xb6",
+- [0x0824] = "\x65\xb7", [0x0825] = "\x65\xb8", [0x0827] = "\x65\xb9",
++ [0x078c] = "\xa6\xc0", [0x078d] = "\x7b\x84", [0x078e] = "\x7b\x86",
++ [0x078f] = "\x7b\x85", [0x0790] = "\x7b\x87", [0x0791] = "\x7b\x88",
++ [0x0792] = "\x7b\x89", [0x0793] = "\x7b\x8a", [0x0794] = "\x7b\x8b",
++ [0x0795] = "\x7b\x8c", [0x0796] = "\x7b\x8d", [0x0797] = "\xa6\xf6",
++ [0x0798] = "\xa6\xf7", [0x0799] = "\xa6\xf8", [0x079a] = "\xa6\xf9",
++ [0x079b] = "\xa6\xfa", [0x079c] = "\xa6\xfb", [0x079d] = "\xa6\xfc",
++ [0x079e] = "\xa6\xfd", [0x079f] = "\xa6\xfe", [0x07a0] = "\xa7\xc2",
++ [0x07a1] = "\xa7\xc3", [0x07a2] = "\xa7\xc4", [0x07a3] = "\xa7\xc5",
++ [0x07a4] = "\xa7\xc6", [0x07a5] = "\xa7\xc7", [0x07a6] = "\xa7\xc8",
++ [0x07a7] = "\xa7\xc9", [0x07a8] = "\xa7\xca", [0x07a9] = "\xa7\xcb",
++ [0x07aa] = "\xa7\xcc", [0x07ab] = "\xa7\xcd", [0x07ac] = "\xa7\xce",
++ [0x07ad] = "\xa7\xcf", [0x07ae] = "\xa7\xd0", [0x07af] = "\xa7\xf2",
++ [0x07b0] = "\xa7\xf3", [0x07b1] = "\xa7\xf4", [0x07b2] = "\xa7\xf5",
++ [0x07b3] = "\xa7\xf6", [0x07b4] = "\xa7\xf7", [0x07b5] = "\xa7\xf8",
++ [0x07b6] = "\xa7\xf9", [0x07b7] = "\xa7\xfa", [0x07b8] = "\xa7\xfb",
++ [0x07b9] = "\xa7\xfc", [0x07ba] = "\xa7\xfd", [0x07bb] = "\xa7\xfe",
++ [0x07bc] = "\xa8\x96", [0x07bd] = "\xa8\x97", [0x07be] = "\xa8\x98",
++ [0x07bf] = "\xa8\x99", [0x07c0] = "\xa8\x9a", [0x07c1] = "\xa8\x9b",
++ [0x07c2] = "\xa8\x9c", [0x07c3] = "\xa8\x9d", [0x07c4] = "\xa8\x9e",
++ [0x07c5] = "\xa8\x9f", [0x07c6] = "\xa8\xa0", [0x07c7] = "\x00\x01",
++ [0x07c8] = "\x65\x9e", [0x07c9] = "\xa8\xc1", [0x07ca] = "\xa8\xc2",
++ [0x07cb] = "\xa8\xc3", [0x07cc] = "\xa8\xc4", [0x07cd] = "\xa8\xea",
++ [0x07ce] = "\xa8\xeb", [0x07cf] = "\xa8\xec", [0x07d0] = "\xa8\xed",
++ [0x07d1] = "\xa8\xee", [0x07d2] = "\xa8\xef", [0x07d3] = "\xa8\xf0",
++ [0x07d4] = "\xa8\xf1", [0x07d5] = "\xa8\xf2", [0x07d6] = "\xa8\xf3",
++ [0x07d7] = "\xa8\xf4", [0x07d8] = "\xa8\xf5", [0x07d9] = "\xa8\xf6",
++ [0x07da] = "\xa8\xf7", [0x07db] = "\xa8\xf8", [0x07dc] = "\xa8\xf9",
++ [0x07dd] = "\xa8\xfa", [0x07de] = "\xa8\xfb", [0x07df] = "\xa8\xfc",
++ [0x07e0] = "\xa8\xfd", [0x07e1] = "\xa8\xfe", [0x07e2] = "\xa9\x58",
++ [0x07e3] = "\xa9\x5b", [0x07e4] = "\xa9\x5d", [0x07e5] = "\xa9\x5e",
++ [0x07e6] = "\xa9\x5f", [0x07e7] = "\x65\x9f", [0x07e8] = "\x65\xa0",
++ [0x07e9] = "\x65\xa1", [0x07ea] = "\x65\xa2", [0x07eb] = "\x65\xa3",
++ [0x07ec] = "\x65\xa4", [0x07ed] = "\x65\xa5", [0x07ee] = "\x65\xa6",
++ [0x07ef] = "\x65\xa7", [0x07f0] = "\x65\xa8", [0x07f1] = "\x65\xa9",
++ [0x07f2] = "\x65\xaa", [0x07f3] = "\x65\xab", [0x07f4] = "\xa9\x97",
++ [0x07f5] = "\xa9\x98", [0x07f6] = "\xa9\x99", [0x07f7] = "\xa9\x9a",
++ [0x07f8] = "\xa9\x9b", [0x07f9] = "\xa9\x9c", [0x07fa] = "\xa9\x9d",
++ [0x07fb] = "\xa9\x9e", [0x07fc] = "\xa9\x9f", [0x07fd] = "\xa9\xa0",
++ [0x07fe] = "\xa9\xa1", [0x07ff] = "\xa9\xa2", [0x0800] = "\xa9\xa3",
++ [0x0801] = "\xa9\xf0", [0x0802] = "\xa9\xf1", [0x0803] = "\xa9\xf2",
++ [0x0804] = "\xa9\xf3", [0x0805] = "\xa9\xf4", [0x0806] = "\xa9\xf5",
++ [0x0807] = "\xa9\xf6", [0x0808] = "\xa9\xf7", [0x0809] = "\xa9\xf8",
++ [0x080a] = "\xa9\xf9", [0x080b] = "\xa9\xfa", [0x080c] = "\xa9\xfb",
++ [0x080d] = "\xa9\xfc", [0x080e] = "\xa9\xfd", [0x080f] = "\xa9\xfe",
++ [0x0810] = "\xd7\xfa", [0x0811] = "\xd7\xfb", [0x0812] = "\xd7\xfc",
++ [0x0813] = "\xd7\xfd", [0x0814] = "\xd7\xfe", [0x0815] = "\x65\xac",
++ [0x0816] = "\xfe\x51", [0x0817] = "\xfe\x52", [0x0818] = "\xfe\x53",
++ [0x0819] = "\x65\xad", [0x081a] = "\x65\xae", [0x081b] = "\x65\xaf",
++ [0x081c] = "\x65\xb0", [0x081d] = "\x65\xb1", [0x081e] = "\x2d\x51",
++ [0x081f] = "\x65\xb2", [0x0820] = "\x65\xb3", [0x0821] = "\x65\xb4",
++ [0x0822] = "\x65\xb5", [0x0823] = "\x65\xb6", [0x0824] = "\x65\xb7",
++ [0x0825] = "\x65\xb8", [0x0826] = "\x2d\x52", [0x0827] = "\x65\xb9",
+ [0x0828] = "\x65\xba", [0x0829] = "\x65\xbb", [0x082a] = "\x65\xbc",
+- [0x082d] = "\x65\xbd", [0x082e] = "\x65\xbe", [0x082f] = "\x65\xbf",
+- [0x0830] = "\x65\xc0", [0x0833] = "\x65\xc1", [0x0834] = "\x65\xc2",
+- [0x0835] = "\x65\xc3", [0x0836] = "\x65\xc4", [0x0837] = "\x65\xc5",
+- [0x0838] = "\x65\xc6", [0x0839] = "\x65\xc7", [0x083a] = "\x65\xc8",
+- [0x083c] = "\x65\xc9", [0x083d] = "\x65\xca", [0x083e] = "\x65\xcb",
+- [0x083f] = "\x65\xcc", [0x0840] = "\x65\xcd", [0x0841] = "\x65\xce",
+- [0x0842] = "\x65\xcf", [0x0844] = "\x65\xd0", [0x0845] = "\x65\xd1",
++ [0x082b] = "\x2d\x53", [0x082c] = "\x2d\x54", [0x082d] = "\x65\xbd",
++ [0x082e] = "\x65\xbe", [0x082f] = "\x65\xbf", [0x0830] = "\x65\xc0",
++ [0x0831] = "\xfe\x6c", [0x0832] = "\x2d\x55", [0x0833] = "\x65\xc1",
++ [0x0834] = "\x65\xc2", [0x0835] = "\x65\xc3", [0x0836] = "\x65\xc4",
++ [0x0837] = "\x65\xc5", [0x0838] = "\x65\xc6", [0x0839] = "\x65\xc7",
++ [0x083a] = "\x65\xc8", [0x083b] = "\xfe\x76", [0x083c] = "\x65\xc9",
++ [0x083d] = "\x65\xca", [0x083e] = "\x65\xcb", [0x083f] = "\x65\xcc",
++ [0x0840] = "\x65\xcd", [0x0841] = "\x65\xce", [0x0842] = "\x65\xcf",
++ [0x0843] = "\x2d\x56", [0x0844] = "\x65\xd0", [0x0845] = "\x65\xd1",
+ [0x0846] = "\x65\xd2", [0x0847] = "\x65\xd3", [0x0848] = "\x65\xd4",
+ [0x0849] = "\x65\xd5", [0x084a] = "\x65\xd6", [0x084b] = "\x65\xd7",
+ [0x084c] = "\x65\xd8", [0x084d] = "\x65\xd9", [0x084e] = "\x65\xda",
+ [0x084f] = "\x65\xdb", [0x0850] = "\x65\xdc", [0x0851] = "\x65\xdd",
+- [0x0852] = "\x65\xde", [0x0853] = "\x65\xdf", [0x0856] = "\x65\xe0",
+- [0x0857] = "\x65\xe1", [0x0858] = "\x65\xe2", [0x0859] = "\x65\xe3",
+- [0x085a] = "\x65\xe4", [0x085b] = "\x65\xe5", [0x085c] = "\x65\xe6",
+- [0x085d] = "\x65\xe7", [0x085e] = "\x65\xe8", [0x085f] = "\x65\xe9",
+- [0x0860] = "\x65\xea", [0x0861] = "\x65\xeb", [0x0862] = "\x65\xec",
+- [0x0863] = "\x65\xed", [0x0865] = "\xfd\x9c", [0x0866] = "\x76\xb5",
++ [0x0852] = "\x65\xde", [0x0853] = "\x65\xdf", [0x0854] = "\x2d\x57",
++ [0x0855] = "\xfe\x91", [0x0856] = "\x65\xe0", [0x0857] = "\x65\xe1",
++ [0x0858] = "\x65\xe2", [0x0859] = "\x65\xe3", [0x085a] = "\x65\xe4",
++ [0x085b] = "\x65\xe5", [0x085c] = "\x65\xe6", [0x085d] = "\x65\xe7",
++ [0x085e] = "\x65\xe8", [0x085f] = "\x65\xe9", [0x0860] = "\x65\xea",
++ [0x0861] = "\x65\xeb", [0x0862] = "\x65\xec", [0x0863] = "\x65\xed",
++ [0x0864] = "\x2d\x58", [0x0865] = "\xfd\x9c", [0x0866] = "\x76\xb5",
+ [0x0867] = "\x76\xb6", [0x0868] = "\x76\xb7", [0x0869] = "\x76\xb8",
+ [0x086a] = "\x76\xb9", [0x086b] = "\x76\xba", [0x086c] = "\x76\xbb",
+ [0x086d] = "\x76\xbc", [0x086e] = "\x76\xbd", [0x086f] = "\x76\xbe",
+@@ -24222,24 +24235,8 @@ static const unsigned char __ucs_to_gb18030_tab2[][2] =
+ || (ch = __twobyte_to_ucs[idx], \
+ ch == 0 && *inptr != '\0')) \
+ { \
+- /* Handle a few special cases. */ \
+- if (idx == 0x5dd1) \
+- ch = 0x20087; \
+- else if (idx == 0x5dd2) \
+- ch = 0x20089; \
+- else if (idx == 0x5dd3) \
+- ch = 0x200cc; \
+- else if (idx == 0x5dec) \
+- ch = 0x215D7; \
+- else if (idx == 0x5df6) \
+- ch = 0x2298F; \
+- else if (idx == 0x5e11) \
+- ch = 0x241FE; \
+- else \
+- { \
+- /* This is an illegal character. */ \
+- STANDARD_FROM_LOOP_ERR_HANDLER (2); \
+- } \
++ /* This is an illegal character. */ \
++ STANDARD_FROM_LOOP_ERR_HANDLER (2); \
+ } \
+ \
+ inptr += 2; \
+@@ -24331,17 +24328,35 @@ static const unsigned char __ucs_to_gb18030_tab2[][2] =
+ len = 4; \
+ } \
+ else if (ch == 0x20087) \
+- cp = (const unsigned char *) "\xfe\x51"; \
++ { \
++ idx = 0x3E2CF; \
++ len = 4; \
++ } \
+ else if (ch == 0x20089) \
+- cp = (const unsigned char *) "\xfe\x52"; \
++ { \
++ idx = 0x3E2D1; \
++ len = 4; \
++ } \
+ else if (ch == 0x200CC) \
+- cp = (const unsigned char *) "\xfe\x53"; \
++ { \
++ idx = 0x3E314; \
++ len = 4; \
++ } \
+ else if (ch == 0x215d7) \
+- cp = (const unsigned char *) "\xfe\x6c"; \
++ { \
++ idx = 0x3F81F; \
++ len = 4; \
++ } \
+ else if (ch == 0x2298F) \
+- cp = (const unsigned char *) "\xfe\x76"; \
++ { \
++ idx = 0x40BD7; \
++ len = 4; \
++ } \
+ else if (ch == 0x241FE) \
+- cp = (const unsigned char *) "\xfe\x91"; \
++ { \
++ idx = 0x42446; \
++ len = 4; \
++ } \
+ else if (ch >= 0x10000 && ch <= 0x10FFFF) \
+ { \
+ idx = ch + 0x1E248; \
+diff --git a/iconvdata/tst-table-from.c b/iconvdata/tst-table-from.c
+index 9ad1f44e..c881c86b 100644
+--- a/iconvdata/tst-table-from.c
++++ b/iconvdata/tst-table-from.c
+@@ -195,10 +195,9 @@ main (int argc, char *argv[])
+ exit (1);
+ }
+
+- /* When testing UTF-8 or GB18030, stop at 0x10000, otherwise the output
++ /* When testing UTF-8, stop at 0x10000, otherwise the output
+ file gets too big. */
+- bmp_only = (strcmp (charset, "UTF-8") == 0
+- || strcmp (charset, "GB18030") == 0);
++ bmp_only = (strcmp (charset, "UTF-8") == 0);
+ search_depth = (strcmp (charset, "UTF-8") == 0 ? 3 : 4);
+
+ {
+diff --git a/iconvdata/tst-table-to.c b/iconvdata/tst-table-to.c
+index 6f0aa29c..8d097527 100644
+--- a/iconvdata/tst-table-to.c
++++ b/iconvdata/tst-table-to.c
+@@ -33,6 +33,7 @@ main (int argc, char *argv[])
+ const char *charset;
+ iconv_t cd;
+ int bmp_only;
++ int no_tags;
+
+ if (argc != 2)
+ {
+@@ -48,16 +49,19 @@ main (int argc, char *argv[])
+ return 1;
+ }
+
+- /* When testing UTF-8 or GB18030, stop at 0x10000, otherwise the output
++ /* When testing UTF-8, stop at 0x10000, otherwise the output
+ file gets too big. */
+- bmp_only = (strcmp (charset, "UTF-8") == 0
++ bmp_only = (strcmp (charset, "UTF-8") == 0);
++ /* When testing any encoding other than UTF-8 or GB18030, stop at 0xE0000,
++ because the conversion drops Unicode tag characters (range
++ U+E0000..U+E007F). */
++ no_tags = !(strcmp (charset, "UTF-8") == 0
+ || strcmp (charset, "GB18030") == 0);
+
+ {
+ unsigned int i;
+ unsigned char buf[10];
+-
+- for (i = 0; i < (bmp_only ? 0x10000 : 0x30000); i++)
++ for (i = 0; i < (bmp_only ? 0x10000 : no_tags ? 0xE0000 : 0x110000); i++)
+ {
+ unsigned char in[6];
+ unsigned int incount =
+diff --git a/iconvdata/tst-table.sh b/iconvdata/tst-table.sh
+index 04c06136..3c6927ee 100755
+--- a/iconvdata/tst-table.sh
++++ b/iconvdata/tst-table.sh
+@@ -38,7 +38,8 @@ set -e
+ < ../localedata/charmaps/${charmap:-$charset} \
+ > ${objpfx}tst-${charset}.charmap.table
+ # When the charset is GB18030, truncate this table because for this encoding,
+-# the tst-table-from and tst-table-to programs scan the Unicode BMP only.
++# the charmap contains ranges (<Unnnn>..<Ummmm> notation), which the
++# tst-table-charmap.sh script does not grok.
+ if test ${charset} = GB18030; then
+ grep '0x....$' < ${objpfx}tst-${charset}.charmap.table \
+ > ${objpfx}tst-${charset}.truncated.table
+@@ -74,25 +75,42 @@ diff ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.inverse.table
+
+ # Check 1: charmap and iconv forward should be identical, except for
+ # precomposed characters.
+-if test -f ${precomposed}; then
+- cat ${objpfx}tst-${charset}.table ${precomposed} | sort | uniq -u \
+- > ${objpfx}tst-${charset}.tmp.table
+- cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.tmp.table ||
++{ if test -f ${precomposed}; then
++ cat ${objpfx}tst-${charset}.table ${precomposed} | sort | uniq -u
++ else
++ cat ${objpfx}tst-${charset}.table
++ fi
++} | { if test ${charset} = GB18030; then grep '0x....$'; else cat; fi; } \
++ > ${objpfx}tst-${charset}.tmp1.table
++cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.tmp1.table ||
+ exit 1
+-else
+- cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.table ||
+- exit 1
+-fi
+
+ # Check 2: the difference between the charmap and iconv backward.
+-if test -f ${irreversible}; then
+- cat ${objpfx}tst-${charset}.charmap.table ${irreversible} | sort | uniq -u \
+- > ${objpfx}tst-${charset}.tmp.table
+- cmp -s ${objpfx}tst-${charset}.tmp.table ${objpfx}tst-${charset}.inverse.table ||
+- exit 1
+-else
+- cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.inverse.table ||
++{ if test -f ${irreversible}; then
++ cat ${objpfx}tst-${charset}.charmap.table ${irreversible} | sort | uniq -u
++ else
++ cat ${objpfx}tst-${charset}.charmap.table
++ fi
++} | { if test ${charset} = GB18030; then grep '0x....$'; else cat; fi; } \
++ > ${objpfx}tst-${charset}.tmp2c.table
++cat ${objpfx}tst-${charset}.inverse.table \
++ | { if test ${charset} = GB18030; then grep '0x....$'; else cat; fi; } \
++ > ${objpfx}tst-${charset}.tmp2i.table
++cmp -s ${objpfx}tst-${charset}.tmp2c.table ${objpfx}tst-${charset}.tmp2i.table ||
+ exit 1
++
++# Check 3: the difference between iconv forward and iconv backward. This is
++# necessary only for GB18030, because ${objpfx}tst-${charset}.charmap.table
++# is truncated for this encoding (see above).
++if test ${charset} = GB18030; then
++ { if test -f ${irreversible}; then
++ cat ${objpfx}tst-${charset}.table ${irreversible} | sort | uniq -u
++ else
++ cat ${objpfx}tst-${charset}.table
++ fi
++ } > ${objpfx}tst-${charset}.tmp3.table
++ cmp -s ${objpfx}tst-${charset}.tmp3.table ${objpfx}tst-${charset}.inverse.table ||
++ exit 1
+ fi
+
+ exit 0
+diff --git a/localedata/charmaps/GB18030 b/localedata/charmaps/GB18030
+index ad6728c5..fc3b1d2d 100644
+--- a/localedata/charmaps/GB18030
++++ b/localedata/charmaps/GB18030
+@@ -57234,32 +57234,16 @@ CHARMAP
+ <UE78A> /xa6/xbe <Private Use>
+ <UE78B> /xa6/xbf <Private Use>
+ <UE78C> /xa6/xc0 <Private Use>
+-% The newest GB 18030-2005 standard still uses some private use area
+-% code points. Any implementation which has Unicode 4.1 or newer
+-% support should not use these PUA code points, and instead should
+-% map these entries to their equivalent non-PUA code points. There
+-% are 24 idiograms in GB 18030-2005 which have non-PUA equivalents.
+-% In glibc we only support roundtrip code points, and so must choose
+-% between supporting the old PUA code points, or using the newer
+-% non-PUA code points. We choose to use the non-PUA code points to
+-% be compatible with ICU's similar choice. In choosing the non-PUA
+-% code points we can no longer convert the old PUA code points back
+-% to GB-18030-2005 (technically only fixable if we added support
+-% for non-roundtrip code points e.g. ICU's "fallback mapping").
+-% The recommendation to use the non-PUA code points, where available,
+-% is based on "CJKV Information Processing" 2nd Ed. by Dr. Ken Lunde.
+-%
+-% These 10 PUA mappings use equivalents from <UFE10> to <UFE19>.
+-% <UE78D> /xa6/xd9 <Private Use>
+-% <UE78E> /xa6/xda <Private Use>
+-% <UE78F> /xa6/xdb <Private Use>
+-% <UE790> /xa6/xdc <Private Use>
+-% <UE791> /xa6/xdd <Private Use>
+-% <UE792> /xa6/xde <Private Use>
+-% <UE793> /xa6/xdf <Private Use>
+-% <UE794> /xa6/xec <Private Use>
+-% <UE795> /xa6/xed <Private Use>
+-% <UE796> /xa6/xf3 <Private Use>
++<UE78D> /x84/x31/x82/x36 <Private Use>
++<UE78E> /x84/x31/x82/x38 <Private Use>
++<UE78F> /x84/x31/x82/x37 <Private Use>
++<UE790> /x84/x31/x82/x39 <Private Use>
++<UE791> /x84/x31/x83/x30 <Private Use>
++<UE792> /x84/x31/x83/x31 <Private Use>
++<UE793> /x84/x31/x83/x32 <Private Use>
++<UE794> /x84/x31/x83/x33 <Private Use>
++<UE795> /x84/x31/x83/x34 <Private Use>
++<UE796> /x84/x31/x83/x35 <Private Use>
+ <UE797> /xa6/xf6 <Private Use>
+ <UE798> /xa6/xf7 <Private Use>
+ <UE799> /xa6/xf8 <Private Use>
+@@ -57387,17 +57371,15 @@ CHARMAP
+ <UE813> /xd7/xfd <Private Use>
+ <UE814> /xd7/xfe <Private Use>
+ <UE815> /x83/x36/xc9/x34 <Private Use>
+-% These 3 PUA mappings use equivalents <U20087>, <U20089> and <U200CC>.
+-% <UE816> /xfe/x51 <Private Use>
+-% <UE817> /xfe/x52 <Private Use>
+-% <UE818> /xfe/x53 <Private Use>
++<UE816> /xfe/x51 <Private Use>
++<UE817> /xfe/x52 <Private Use>
++<UE818> /xfe/x53 <Private Use>
+ <UE819> /x83/x36/xc9/x35 <Private Use>
+ <UE81A> /x83/x36/xc9/x36 <Private Use>
+ <UE81B> /x83/x36/xc9/x37 <Private Use>
+ <UE81C> /x83/x36/xc9/x38 <Private Use>
+ <UE81D> /x83/x36/xc9/x39 <Private Use>
+-% This 1 PUA mapping uses the equivalent <U9FB4>.
+-% <UE81E> /xfe/x59 <Private Use>
++<UE81E> /x82/x35/x90/x37 <Private Use>
+ <UE81F> /x83/x36/xca/x30 <Private Use>
+ <UE820> /x83/x36/xca/x31 <Private Use>
+ <UE821> /x83/x36/xca/x32 <Private Use>
+@@ -57405,22 +57387,19 @@ CHARMAP
+ <UE823> /x83/x36/xca/x34 <Private Use>
+ <UE824> /x83/x36/xca/x35 <Private Use>
+ <UE825> /x83/x36/xca/x36 <Private Use>
+-% This 1 PUA mapping uses the equivalent <U9FB5>.
+-% <UE826> /xfe/x61 <Private Use>
++<UE826> /x82/x35/x90/x38 <Private Use>
+ <UE827> /x83/x36/xca/x37 <Private Use>
+ <UE828> /x83/x36/xca/x38 <Private Use>
+ <UE829> /x83/x36/xca/x39 <Private Use>
+ <UE82A> /x83/x36/xcb/x30 <Private Use>
+-% These 2 PUA mappings use the equivalents <U9FB6> and <U9FB7>.
+-% <UE82B> /xfe/x66 <Private Use>
+-% <UE82C> /xfe/x67 <Private Use>
++<UE82B> /x82/x35/x90/x39 <Private Use>
++<UE82C> /x82/x35/x91/x30 <Private Use>
+ <UE82D> /x83/x36/xcb/x31 <Private Use>
+ <UE82E> /x83/x36/xcb/x32 <Private Use>
+ <UE82F> /x83/x36/xcb/x33 <Private Use>
+ <UE830> /x83/x36/xcb/x34 <Private Use>
+-% These 2 PUA mappings use the equivalents <U215D7> and <U9FB8>.
+-% <UE831> /xfe/x6c <Private Use>
+-% <UE832> /xfe/x6d <Private Use>
++<UE831> /xfe/x6c <Private Use>
++<UE832> /x82/x35/x91/x31 <Private Use>
+ <UE833> /x83/x36/xcb/x35 <Private Use>
+ <UE834> /x83/x36/xcb/x36 <Private Use>
+ <UE835> /x83/x36/xcb/x37 <Private Use>
+@@ -57429,8 +57408,7 @@ CHARMAP
+ <UE838> /x83/x36/xcc/x30 <Private Use>
+ <UE839> /x83/x36/xcc/x31 <Private Use>
+ <UE83A> /x83/x36/xcc/x32 <Private Use>
+-% This 1 PUA mapping uses the equivalent <U2298F>.
+-% <UE83B> /xfe/x76 <Private Use>
++<UE83B> /xfe/x76 <Private Use>
+ <UE83C> /x83/x36/xcc/x33 <Private Use>
+ <UE83D> /x83/x36/xcc/x34 <Private Use>
+ <UE83E> /x83/x36/xcc/x35 <Private Use>
+@@ -57438,8 +57416,7 @@ CHARMAP
+ <UE840> /x83/x36/xcc/x37 <Private Use>
+ <UE841> /x83/x36/xcc/x38 <Private Use>
+ <UE842> /x83/x36/xcc/x39 <Private Use>
+-% This 1 PUA mapping uses the equivalent <U9FB9>.
+-% <UE843> /xfe/x7e <Private Use>
++<UE843> /x82/x35/x91/x32 <Private Use>
+ <UE844> /x83/x36/xcd/x30 <Private Use>
+ <UE845> /x83/x36/xcd/x31 <Private Use>
+ <UE846> /x83/x36/xcd/x32 <Private Use>
+@@ -57456,9 +57433,8 @@ CHARMAP
+ <UE851> /x83/x36/xce/x33 <Private Use>
+ <UE852> /x83/x36/xce/x34 <Private Use>
+ <UE853> /x83/x36/xce/x35 <Private Use>
+-% These 2 PUA mappings use the equivalents <U9FBA> and <U241FE>.
+-% <UE854> /xfe/x90 <Private Use>
+-% <UE855> /xfe/x91 <Private Use>
++<UE854> /x82/x35/x91/x33 <Private Use>
++<UE855> /xfe/x91 <Private Use>
+ <UE856> /x83/x36/xce/x36 <Private Use>
+ <UE857> /x83/x36/xce/x37 <Private Use>
+ <UE858> /x83/x36/xce/x38 <Private Use>
+@@ -57473,8 +57449,7 @@ CHARMAP
+ <UE861> /x83/x36/xcf/x37 <Private Use>
+ <UE862> /x83/x36/xcf/x38 <Private Use>
+ <UE863> /x83/x36/xcf/x39 <Private Use>
+-% This 1 PUA mapping uses the equivalent <U9FBB>.
+-% <UE864> /xfe/xa0 <Private Use>
++<UE864> /x82/x35/x91/x34 <Private Use>
+ <UE865> /x83/x36/xd0/x30 <Private Use>
+ <UE866> /x83/x36/xd0/x31 <Private Use>
+ <UE867> /x83/x36/xd0/x32 <Private Use>
+@@ -70447,19 +70422,14 @@ CHARMAP
+ <U00020068>..<U00020071> /x95/x32/x8d/x30 <CJK>
+ <U00020072>..<U0002007B> /x95/x32/x8e/x30 <CJK>
+ <U0002007C>..<U00020085> /x95/x32/x8f/x30 <CJK>
+-<U00020086> /x95/x32/x90/x30 <CJK>
+-<U00020087> /xfe/x51 <CJK>
+-<U00020088> /x95/x32/x90/x32 <CJK>
+-<U00020089> /xfe/x52 <CJK>
+-<U0002008A>..<U0002008F> /x95/x32/x90/x34 <CJK>
++<U00020086>..<U0002008F> /x95/x32/x90/x30 <CJK>
+ <U00020090>..<U00020099> /x95/x32/x91/x30 <CJK>
+ <U0002009A>..<U000200A3> /x95/x32/x92/x30 <CJK>
+ <U000200A4>..<U000200AD> /x95/x32/x93/x30 <CJK>
+ <U000200AE>..<U000200B7> /x95/x32/x94/x30 <CJK>
+ <U000200B8>..<U000200C1> /x95/x32/x95/x30 <CJK>
+ <U000200C2>..<U000200CB> /x95/x32/x96/x30 <CJK>
+-<U000200CC> /xfe/x53 <CJK>
+-<U000200CD>..<U000200D5> /x95/x32/x97/x31 <CJK>
++<U000200CC>..<U000200D5> /x95/x32/x97/x30 <CJK>
+ <U000200D6>..<U000200DF> /x95/x32/x98/x30 <CJK>
+ <U000200E0>..<U000200E9> /x95/x32/x99/x30 <CJK>
+ <U000200EA>..<U000200F3> /x95/x32/x9a/x30 <CJK>
+@@ -70998,8 +70968,7 @@ CHARMAP
+ <U000215BC>..<U000215C5> /x95/x36/xb7/x30 <CJK>
+ <U000215C6>..<U000215CF> /x95/x36/xb8/x30 <CJK>
+ <U000215D0>..<U000215D6> /x95/x36/xb9/x30 <CJK>
+-<U000215D7> /xfe/x6c <CJK>
+-<U000215D8>..<U000215D9> /x95/x36/xb9/x38 <CJK>
++<U000215D7>..<U000215D9> /x95/x36/xb9/x37 <CJK>
+ <U000215DA>..<U000215E3> /x95/x36/xba/x30 <CJK>
+ <U000215E4>..<U000215ED> /x95/x36/xbb/x30 <CJK>
+ <U000215EE>..<U000215F7> /x95/x36/xbc/x30 <CJK>
+@@ -71505,8 +71474,7 @@ CHARMAP
+ <U00022976>..<U0002297F> /x96/x30/xb8/x30 <CJK>
+ <U00022980>..<U00022989> /x96/x30/xb9/x30 <CJK>
+ <U0002298A>..<U0002298E> /x96/x30/xba/x30 <CJK>
+-<U0002298F> /xfe/x76 <CJK>
+-<U00022990>..<U00022993> /x96/x30/xba/x36 <CJK>
++<U0002298F>..<U00022993> /x96/x30/xba/x35 <CJK>
+ <U00022994>..<U0002299D> /x96/x30/xbb/x30 <CJK>
+ <U0002299E>..<U000229A7> /x96/x30/xbc/x30 <CJK>
+ <U000229A8>..<U000229B1> /x96/x30/xbd/x30 <CJK>
+@@ -72132,8 +72100,7 @@ CHARMAP
+ <U000241E0>..<U000241E9> /x96/x35/xb3/x30 <CJK>
+ <U000241EA>..<U000241F3> /x96/x35/xb4/x30 <CJK>
+ <U000241F4>..<U000241FD> /x96/x35/xb5/x30 <CJK>
+-<U000241FE> /xfe/x91 <CJK>
+-<U000241FF>..<U00024207> /x96/x35/xb6/x31 <CJK>
++<U000241FE>..<U00024207> /x96/x35/xb6/x30 <CJK>
+ <U00024208>..<U00024211> /x96/x35/xb7/x30 <CJK>
+ <U00024212>..<U0002421B> /x96/x35/xb8/x30 <CJK>
+ <U0002421C>..<U00024225> /x96/x35/xb9/x30 <CJK>
+--
+2.33.0
+
diff --git a/add-Wl-z-noseparate-code-for-so.patch b/add-Wl-z-noseparate-code-for-so.patch
new file mode 100644
index 0000000..1cdf45f
--- /dev/null
+++ b/add-Wl-z-noseparate-code-for-so.patch
@@ -0,0 +1,29 @@
+From 2eb52cc0dd1ce02871d4f863649a8656831805c7 Mon Sep 17 00:00:00 2001
+From: hongrongxuan <hongrongxuan@huawei.com>
+Date: Tue, 25 Oct 2022 21:24:21 +0800
+Subject: [PATCH] add Wl,-z,noseparate-code for so
+binutils 2.31 add a separate-code(default)/noseparate-code link option to separate
+.rodata from .text segment. Cause this is a dubious feature that intends to
+reduce the number of ROP gadgets, and this will reduce batch program's
+performance, like unixbench shell program, it will reduce 8%~10%. So
+add 'Wl,-z,noseparate-code' to disable this feature.
+
+Refrences:
+https://sourceware.org/pipermail/binutils/2018-February/101950.html
+https://reviews.llvmm.org/D64903
+https://packagehub.suse.com/packages/binutils/2_37-1050100_7_34_1/
+---
+ sysdeps/x86_64/Makeconfig | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 100644 sysdeps/x86_64/Makeconfig
+
+diff --git a/sysdeps/x86_64/Makeconfig b/sysdeps/x86_64/Makeconfig
+new file mode 100644
+index 00000000..5f544fd7
+--- /dev/null
++++ b/sysdeps/x86_64/Makeconfig
+@@ -0,0 +1 @@
++relro-LDFLAGS = -Wl,-z,relro -Wl,-z,noseparate-code
+--
+2.33.0
+
diff --git a/add-pthread_cond_clockwait-GLIBC_2_28.patch b/add-pthread_cond_clockwait-GLIBC_2_28.patch
new file mode 100644
index 0000000..7d04082
--- /dev/null
+++ b/add-pthread_cond_clockwait-GLIBC_2_28.patch
@@ -0,0 +1,66 @@
+From e6569a3c53c25916f5c04ccc3d6a467c57d4eab8 Mon Sep 17 00:00:00 2001
+From: Yang Yanchao <yangyanchao6@huawei.com>
+Date: Thu, 19 Jan 2023 21:40:08 +0800
+Subject: [PATCH] add pthread_cond_clockwait@GLIBC_2_28
+
+Since the pthread_cond_clockwait@GLIBC_2_28 is introduced in earlier
+versions, this symbol is required to keep the previous items compatible.
+
+---
+ nptl/Versions | 1 +
+ nptl/pthread_cond_wait.c | 4 ++++
+ sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 +
+ sysdeps/unix/sysv/linux/x86_64/64/libc.abilist | 1 +
+ 5 files changed, 9 insertions(+)
+
+diff --git a/nptl/Versions b/nptl/Versions
+index 3221de89..dc341f9d 100644
+--- a/nptl/Versions
++++ b/nptl/Versions
+@@ -231,6 +231,7 @@ libc {
+ tss_delete;
+ tss_get;
+ tss_set;
++ pthread_cond_clockwait;
+ }
+ GLIBC_2.30 {
+ pthread_cond_clockwait;
+diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
+index dc8c511f..04eeff34 100644
+--- a/nptl/pthread_cond_wait.c
++++ b/nptl/pthread_cond_wait.c
+@@ -709,3 +709,7 @@ versioned_symbol (libc, ___pthread_cond_clockwait,
+ compat_symbol (libpthread, ___pthread_cond_clockwait,
+ pthread_cond_clockwait, GLIBC_2_30);
+ #endif
++#if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_28, GLIBC_2_34)
++compat_symbol (libpthread, ___pthread_cond_clockwait,
++ pthread_cond_clockwait, GLIBC_2_28);
++#endif
+diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+index a4262419..a0795a80 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
++++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+@@ -383,6 +383,7 @@ GLIBC_2.28 mtx_lock F
+ GLIBC_2.28 mtx_timedlock F
+ GLIBC_2.28 mtx_trylock F
+ GLIBC_2.28 mtx_unlock F
++GLIBC_2.28 pthread_cond_clockwait F
+ GLIBC_2.28 renameat2 F
+ GLIBC_2.28 statx F
+ GLIBC_2.28 thrd_create F
+diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+index 095e914b..0eaab342 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
++++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+@@ -2413,6 +2413,7 @@ GLIBC_2.28 mtx_lock F
+ GLIBC_2.28 mtx_timedlock F
+ GLIBC_2.28 mtx_trylock F
+ GLIBC_2.28 mtx_unlock F
++GLIBC_2.28 pthread_cond_clockwait F
+ GLIBC_2.28 renameat2 F
+ GLIBC_2.28 statx F
+ GLIBC_2.28 thrd_create F
+--
+2.33.0
+
diff --git a/arm-Remove-wrong-ldr-from-_dl_start_user-BZ-31339.patch b/arm-Remove-wrong-ldr-from-_dl_start_user-BZ-31339.patch
new file mode 100644
index 0000000..cf400cd
--- /dev/null
+++ b/arm-Remove-wrong-ldr-from-_dl_start_user-BZ-31339.patch
@@ -0,0 +1,40 @@
+From b09073e63138ce409bf6426cf820eeaa0d28ca74 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Mon, 5 Feb 2024 16:10:24 +0000
+Subject: [PATCH] arm: Remove wrong ldr from _dl_start_user (BZ 31339)
+
+The commit 49d877a80b29d3002887b084eec6676d9f5fec18 (arm: Remove
+_dl_skip_args usage) removed the _SKIP_ARGS literal, which was
+previously loader to r4 on loader _start. However, the cleanup did not
+remove the following 'ldr r4, [sl, r4]' on _dl_start_user, used to check
+to skip the arguments after ld self-relocations.
+
+In my testing, the kernel initially set r4 to 0, which makes the
+ldr instruction just read the _GLOBAL_OFFSET_TABLE_. However, since r4
+is a callee-saved register; a different runtime might not zero
+initialize it and thus trigger an invalid memory access.
+
+Checked on arm-linux-gnu.
+
+Reported-by: Adrian Ratiu <adrian.ratiu@collabora.com>
+Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+(cherry picked from commit 1e25112dc0cb2515d27d8d178b1ecce778a9d37a)
+---
+ sysdeps/arm/dl-machine.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
+index d720c02c96..77dc7415e9 100644
+--- a/sysdeps/arm/dl-machine.h
++++ b/sysdeps/arm/dl-machine.h
+@@ -137,7 +137,6 @@ _start:\n\
+ _dl_start_user:\n\
+ adr r6, .L_GET_GOT\n\
+ add sl, sl, r6\n\
+- ldr r4, [sl, r4]\n\
+ @ save the entry point in another register\n\
+ mov r6, r0\n\
+ @ get the original arg count\n\
+--
+2.33.0
+
diff --git a/backport-elf-Handle-non-directory-name-in-search-path-BZ-3103.patch b/backport-elf-Handle-non-directory-name-in-search-path-BZ-3103.patch
new file mode 100644
index 0000000..8385aac
--- /dev/null
+++ b/backport-elf-Handle-non-directory-name-in-search-path-BZ-3103.patch
@@ -0,0 +1,220 @@
+From a8dcffb30680d6db5704f9ce2fc30621ceb454e7 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Fri, 10 Nov 2023 10:43:12 -0300
+Subject: [PATCH] elf: Handle non-directory name in search path (BZ 31035)
+
+The open_path stops if a relative path in search path contains a
+component that is a non directory (for instance, if the component
+is an existing file).
+
+For instance:
+
+ $ cat > lib.c <<EOF
+ > void foo (void) {}
+ > EOF
+ $ gcc -shared -fPIC -o lib.so lib.c
+ $ cat > main.c <<EOF
+ extern void foo ();
+ int main () { foo (); return 0; }
+ EOF
+ $ gcc -o main main.c lib.so
+ $ LD_LIBRARY_PATH=. ./main
+ $ LD_LIBRARY_PATH=non-existing/path:. ./main
+ $ LD_LIBRARY_PATH=$(pwd)/main:. ./main
+ $ LD_LIBRARY_PATH=./main:. ./main
+ ./main: error while loading shared libraries: lib.so: cannot open shared object file: No such file or directory
+
+The invalid './main' should be ignored as a non-existent one,
+instead as a valid but non accessible file.
+
+Absolute paths do not trigger this issue because their status are
+initialized as 'unknown' and open_path check if this is a directory.
+
+Checked on x86_64-linux-gnu.
+
+Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+---
+ elf/Makefile | 12 ++++++
+ elf/dl-load.c | 9 ++--
+ elf/tst-non-directory-mod.c | 1 +
+ elf/tst-non-directory-path.c | 7 ++++
+ elf/tst-non-directory-path.sh | 77 +++++++++++++++++++++++++++++++++++
+ 5 files changed, 103 insertions(+), 3 deletions(-)
+ create mode 100644 elf/tst-non-directory-mod.c
+ create mode 100644 elf/tst-non-directory-path.c
+ create mode 100755 elf/tst-non-directory-path.sh
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 8cd01845..00ac7430 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -427,6 +427,7 @@ tests += \
+ tst-nodelete-opened \
+ tst-nodelete2 \
+ tst-noload \
++ tst-non-directory-path \
+ tst-null-argv \
+ tst-p_align1 \
+ tst-p_align2 \
+@@ -855,6 +856,7 @@ modules-names += \
+ tst-nodelete-dlclose-plugin \
+ tst-nodelete-opened-lib \
+ tst-nodelete2mod \
++ tst-non-directory-mod \
+ tst-null-argv-lib \
+ tst-p_alignmod-base \
+ tst-p_alignmod3 \
+@@ -1102,6 +1104,7 @@ ifeq (yes,$(build-shared))
+ ifeq ($(run-built-tests),yes)
+ tests-special += \
+ $(objpfx)argv0test.out \
++ $(objpfx)tst-non-directory-path.out \
+ $(objpfx)tst-pathopt.out \
+ $(objpfx)tst-rtld-help.out \
+ $(objpfx)tst-rtld-load-self.out \
+@@ -2990,3 +2993,12 @@ LDFLAGS-tst-dlclose-lazy-mod1.so = -Wl,-z,lazy,--no-as-needed
+ $(objpfx)tst-dlclose-lazy-mod1.so: $(objpfx)tst-dlclose-lazy-mod2.so
+ $(objpfx)tst-dlclose-lazy.out: \
+ $(objpfx)tst-dlclose-lazy-mod1.so $(objpfx)tst-dlclose-lazy-mod2.so
++
++LDFLAGS-tst-non-directory-mod.so = -Wl,-soname,tst-non-directory-mod.so
++$(objpfx)tst-non-directory-path: $(objpfx)tst-non-directory-mod.so
++$(objpfx)tst-non-directory-path.out: tst-non-directory-path.sh \
++ $(objpfx)tst-non-directory-path
++ $(SHELL) tst-non-directory-path.sh $(objpfx)ld.so $(objpfx)tst-non-directory-path \
++ '$(test-wrapper-env)' '$(run_program_env)' \
++ '$(rpath-link)' $(objpfx) > $@; \
++ $(evaluate-test)
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 9a87fda9..7caa405b 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1810,7 +1810,6 @@ open_path (const char *name, size_t namelen, int mode,
+ size_t cnt;
+ char *edp;
+ int here_any = 0;
+- int err;
+
+ /* If we are debugging the search for libraries print the path
+ now if it hasn't happened now. */
+@@ -1911,8 +1910,12 @@ open_path (const char *name, size_t namelen, int mode,
+ return -1;
+ }
+ }
+- if (here_any && (err = errno) != ENOENT && err != EACCES)
+- /* The file exists and is readable, but something went wrong. */
++
++ /* Continue the search if the file does not exist (ENOENT), if it can
++ not be accessed (EACCES), or if the a component in the path is not a
++ directory (for instance, if the component is a existing file meaning
++ essentially that the pathname is invalid - ENOTDIR). */
++ if (here_any && errno != ENOENT && errno != EACCES && errno != ENOTDIR)
+ return -1;
+
+ /* Remember whether we found anything. */
+diff --git a/elf/tst-non-directory-mod.c b/elf/tst-non-directory-mod.c
+new file mode 100644
+index 00000000..aa6d4c27
+--- /dev/null
++++ b/elf/tst-non-directory-mod.c
+@@ -0,0 +1 @@
++void foo (void) {}
+diff --git a/elf/tst-non-directory-path.c b/elf/tst-non-directory-path.c
+new file mode 100644
+index 00000000..1016a97a
+--- /dev/null
++++ b/elf/tst-non-directory-path.c
+@@ -0,0 +1,7 @@
++extern void foo (void);
++
++int main (int argc, char *argv[])
++{
++ foo ();
++ return 0;
++}
+diff --git a/elf/tst-non-directory-path.sh b/elf/tst-non-directory-path.sh
+new file mode 100755
+index 00000000..e804a445
+--- /dev/null
++++ b/elf/tst-non-directory-path.sh
+@@ -0,0 +1,77 @@
++#!/bin/sh
++# Test if library search path does not terminates with non-directory
++# components.
++# 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
++# <https://www.gnu.org/licenses/>.
++
++set -e
++
++rtld=$1
++test_program=$2
++test_wrapper_env=$3
++run_program_env=$4
++# Remove the last space to allow concatenate extra paths.
++library_path=$(echo $5)
++objpfx=$6
++
++test_binary=$(basename ${test_program})
++test_libpath=${test_binary}-x
++
++mkdir -p ${objpfx}/${test_libpath}
++mv ${objpfx}/tst-non-directory-mod.so ${objpfx}/${test_libpath}
++
++# Check with absolute paths.
++${test_wrapper_env} \
++${run_program_env} \
++$rtld --inhibit-cache \
++ --library-path \
++ "$library_path":"${objpfx}"tst-non-directory-invalid:"${objpfx}"${test_libpath} \
++ $test_program 2>&1 && rc=0 || rc=$?
++
++${test_wrapper_env} \
++${run_program_env} \
++$rtld --inhibit-cache \
++ --library-path \
++ "$library_path":"${objpfx}"${test_binary}:"${objpfx}"${test_libpath} \
++ $test_program 2>&1 && rc=0 || rc=$?
++
++# Relative paths along with non-existent path in search list.
++cd "$objpfx"
++${test_wrapper_env} \
++${run_program_env} \
++$rtld --inhibit-cache \
++ --library-path \
++ "$library_path":../elf/tst-non-directory-invalid::../elf/${test_libpath} \
++ $test_program 2>&1 && rc=0 || rc=$?
++
++# Relative paths along with component in the path is not a directory in search list.
++${test_wrapper_env} \
++${run_program_env} \
++$rtld --inhibit-cache \
++ --library-path \
++ "$library_path":../elf/${test_binary}:../elf/${test_libpath} \
++ $test_program 2>&1 && rc=0 || rc=$?
++
++# Relative paths along with non-existent path and a component in the path that is not a directory.
++${test_wrapper_env} \
++${run_program_env} \
++$rtld --inhibit-cache \
++ --library-path \
++ "$library_path":../elf/tst-non-directory-invalid:../elf/${test_binary}:../elf/${test_libpath} \
++ $test_program 2>&1 && rc=0 || rc=$?
++
++exit $rc
+--
+2.27.0
+
diff --git a/bench.mk b/bench.mk
new file mode 100644
index 0000000..dfe46bd
--- /dev/null
+++ b/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/elf-Add-TLS-modid-reuse-test-for-bug-29039.patch b/elf-Add-TLS-modid-reuse-test-for-bug-29039.patch
new file mode 100644
index 0000000..2dddd8e
--- /dev/null
+++ b/elf-Add-TLS-modid-reuse-test-for-bug-29039.patch
@@ -0,0 +1,210 @@
+From 0de9082ed8d8f149ca87d569a73692046e236c18 Mon Sep 17 00:00:00 2001
+From: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date: Wed, 29 Nov 2023 11:31:37 +0000
+Subject: [PATCH 3/9] elf: Add TLS modid reuse test for bug 29039
+
+This is a minimal regression test for bug 29039 which only affects
+targets with TLSDESC and a reproducer requires that
+
+1) Have modid gaps (closed modules) with old generation.
+2) Update a DTV to a newer generation (needs a newer dlopen).
+3) But do not update the closed gap entry in that DTV.
+4) Reuse the modid gap for a new module (another dlopen).
+5) Use dynamic TLSDESC in that new module with old generation (bug).
+6) Access TLS via this TLSDESC and the now outdated DTV.
+
+However step (3) in practice rarely happens: during DTV update the
+entries for closed modids are initialized to "unallocated" and then
+dynamic TLSDESC calls __tls_get_addr independently of its generation.
+The only exception to this is DTV setup at thread creation (gaps are
+initialized to NULL instead of unallocated) or DTV resize where the
+gap entries are outside the previous DTV array (again NULL instead
+of unallocated, and this requires loading > DTV_SURPLUS modules).
+
+So the bug can only cause NULL (+ offset) dereference, not use after
+free. And the easiest way to get (3) is via thread creation.
+
+Note that step (5) requires that the newly loaded module has larger
+TLS than the remaining optional static TLS. And for (6) there cannot
+be other TLS access or dlopen in the thread that updates the DTV.
+
+Tested on aarch64-linux-gnu.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 980450f12685326729d63ff72e93a996113bf073)
+
+Conflict: This adapt the context elf/Makefile due to BZ 31035.
+---
+ elf/Makefile | 15 +++++++
+ elf/tst-tlsgap-mod0.c | 2 +
+ elf/tst-tlsgap-mod1.c | 2 +
+ elf/tst-tlsgap-mod2.c | 2 +
+ elf/tst-tlsgap.c | 92 +++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 113 insertions(+)
+ create mode 100644 elf/tst-tlsgap-mod0.c
+ create mode 100644 elf/tst-tlsgap-mod1.c
+ create mode 100644 elf/tst-tlsgap-mod2.c
+ create mode 100644 elf/tst-tlsgap.c
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 00ac7430..711f96fe 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -460,6 +460,7 @@ tests += \
+ tst-tls21 \
+ tst-tlsalign \
+ tst-tlsalign-extern \
++ tst-tlsgap \
+ tst-unique1 \
+ tst-unique2 \
+ tst-unwind-ctor \
+@@ -885,6 +886,9 @@ modules-names += \
+ tst-tls20mod-bad \
+ tst-tls21mod \
+ tst-tlsalign-lib \
++ tst-tlsgap-mod0 \
++ tst-tlsgap-mod1 \
++ tst-tlsgap-mod2 \
+ tst-tlsmod1 \
+ tst-tlsmod10 \
+ tst-tlsmod11 \
+@@ -3002,3 +3006,14 @@ $(objpfx)tst-non-directory-path.out: tst-non-directory-path.sh \
+ '$(test-wrapper-env)' '$(run_program_env)' \
+ '$(rpath-link)' $(objpfx) > $@; \
+ $(evaluate-test)
++
++$(objpfx)tst-tlsgap: $(shared-thread-library)
++$(objpfx)tst-tlsgap.out: \
++ $(objpfx)tst-tlsgap-mod0.so \
++ $(objpfx)tst-tlsgap-mod1.so \
++ $(objpfx)tst-tlsgap-mod2.so
++ifeq (yes,$(have-mtls-dialect-gnu2))
++CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2
++CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2
++CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2
++endif
+diff --git a/elf/tst-tlsgap-mod0.c b/elf/tst-tlsgap-mod0.c
+new file mode 100644
+index 00000000..1478b0be
+--- /dev/null
++++ b/elf/tst-tlsgap-mod0.c
+@@ -0,0 +1,2 @@
++int __thread tls0;
++int *f0(void) { return &tls0; }
+diff --git a/elf/tst-tlsgap-mod1.c b/elf/tst-tlsgap-mod1.c
+new file mode 100644
+index 00000000..b10fc370
+--- /dev/null
++++ b/elf/tst-tlsgap-mod1.c
+@@ -0,0 +1,2 @@
++int __thread tls1[100]; /* Size > glibc.rtld.optional_static_tls / 2. */
++int *f1(void) { return tls1; }
+diff --git a/elf/tst-tlsgap-mod2.c b/elf/tst-tlsgap-mod2.c
+new file mode 100644
+index 00000000..166c27d7
+--- /dev/null
++++ b/elf/tst-tlsgap-mod2.c
+@@ -0,0 +1,2 @@
++int __thread tls2;
++int *f2(void) { return &tls2; }
+diff --git a/elf/tst-tlsgap.c b/elf/tst-tlsgap.c
+new file mode 100644
+index 00000000..49328850
+--- /dev/null
++++ b/elf/tst-tlsgap.c
+@@ -0,0 +1,92 @@
++/* TLS modid gap reuse regression test for bug 29039.
++ 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
++ <http://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <dlfcn.h>
++#include <pthread.h>
++#include <support/xdlfcn.h>
++#include <support/xthread.h>
++#include <support/check.h>
++
++static void *mod[3];
++#define MOD(i) "tst-tlsgap-mod" #i ".so"
++static const char *modname[3] = { MOD(0), MOD(1), MOD(2) };
++#undef MOD
++
++static void
++open_mod (int i)
++{
++ mod[i] = xdlopen (modname[i], RTLD_LAZY);
++ printf ("open %s\n", modname[i]);
++}
++
++static void
++close_mod (int i)
++{
++ xdlclose (mod[i]);
++ mod[i] = NULL;
++ printf ("close %s\n", modname[i]);
++}
++
++static void
++access_mod (int i, const char *sym)
++{
++ int *(*f) (void) = xdlsym (mod[i], sym);
++ int *p = f ();
++ printf ("access %s: %s() = %p\n", modname[i], sym, p);
++ TEST_VERIFY_EXIT (p != NULL);
++ ++*p;
++}
++
++static void *
++start (void *arg)
++{
++ /* The DTV generation is at the last dlopen of mod0 and the
++ entry for mod1 is NULL. */
++
++ open_mod (1); /* Reuse modid of mod1. Uses dynamic TLS. */
++
++ /* DTV is unchanged: dlopen only updates the DTV to the latest
++ generation if static TLS is allocated for a loaded module.
++
++ With bug 29039, the TLSDESC relocation in mod1 uses the old
++ dlclose generation of mod1 instead of the new dlopen one so
++ DTV is not updated on TLS access. */
++
++ access_mod (1, "f1");
++
++ return arg;
++}
++
++static int
++do_test (void)
++{
++ open_mod (0);
++ open_mod (1);
++ open_mod (2);
++ close_mod (0);
++ close_mod (1); /* Create modid gap at mod1. */
++ open_mod (0); /* Reuse modid of mod0, bump generation count. */
++
++ /* Create a thread where DTV of mod1 is NULL. */
++ pthread_t t = xpthread_create (NULL, start, NULL);
++ xpthread_join (t);
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.33.0
+
diff --git a/elf-Add-a-way-to-check-if-tunable-is-set-BZ-27069.patch b/elf-Add-a-way-to-check-if-tunable-is-set-BZ-27069.patch
new file mode 100644
index 0000000..79ffdec
--- /dev/null
+++ b/elf-Add-a-way-to-check-if-tunable-is-set-BZ-27069.patch
@@ -0,0 +1,201 @@
+From a4c3f5f46e850c977cda81c251036475aab8313c Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Thu, 23 Nov 2023 14:29:14 -0300
+Subject: [PATCH] elf: Add a way to check if tunable is set (BZ 27069)
+
+The patch adds two new macros, TUNABLE_GET_DEFAULT and TUNABLE_IS_INITIALIZED,
+here the former get the default value with a signature similar to
+TUNABLE_GET, while the later returns whether the tunable was set by
+the environment variable.
+
+Checked on x86_64-linux-gnu.
+Reviewed-by: DJ Delorie <dj@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+
+Conflict: this adapt the context of scripts/gen-tunables.awk
+---
+ elf/Versions | 1 +
+ elf/dl-tunable-types.h | 1 +
+ elf/dl-tunables.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ elf/dl-tunables.h | 28 ++++++++++++++++++++++++++++
+ elf/dl-tunables.list | 1 +
+ scripts/gen-tunables.awk | 4 ++--
+ 6 files changed, 73 insertions(+), 2 deletions(-)
+
+diff --git a/elf/Versions b/elf/Versions
+index 4614acea..1591031d 100644
+--- a/elf/Versions
++++ b/elf/Versions
+@@ -77,6 +77,7 @@ ld {
+ _dl_signal_error;
+
+ # Set value of a tunable.
++ __tunable_is_initialized;
+ __tunable_get_val;
+ }
+ }
+diff --git a/elf/dl-tunable-types.h b/elf/dl-tunable-types.h
+index c8833265..c41a3b3b 100644
+--- a/elf/dl-tunable-types.h
++++ b/elf/dl-tunable-types.h
+@@ -61,6 +61,7 @@ struct _tunable
+ {
+ const char name[TUNABLE_NAME_MAX]; /* Internal name of the tunable. */
+ tunable_type_t type; /* Data type of the tunable. */
++ const tunable_val_t def; /* The value. */
+ tunable_val_t val; /* The value. */
+ bool initialized; /* Flag to indicate that the tunable is
+ initialized. */
+diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
+index cae67efa..79b4d542 100644
+--- a/elf/dl-tunables.c
++++ b/elf/dl-tunables.c
+@@ -145,6 +145,13 @@ tunable_initialize (tunable_t *cur, const char *strval)
+ do_tunable_update_val (cur, &val, NULL, NULL);
+ }
+
++bool
++__tunable_is_initialized (tunable_id_t id)
++{
++ return tunable_list[id].initialized;
++}
++rtld_hidden_def (__tunable_is_initialized)
++
+ void
+ __tunable_set_val (tunable_id_t id, tunable_val_t *valp, tunable_num_t *minp,
+ tunable_num_t *maxp)
+@@ -388,6 +395,39 @@ __tunables_print (void)
+ }
+ }
+
++void
++__tunable_get_default (tunable_id_t id, void *valp)
++{
++ tunable_t *cur = &tunable_list[id];
++
++ switch (cur->type.type_code)
++ {
++ case TUNABLE_TYPE_UINT_64:
++ {
++ *((uint64_t *) valp) = (uint64_t) cur->def.numval;
++ break;
++ }
++ case TUNABLE_TYPE_INT_32:
++ {
++ *((int32_t *) valp) = (int32_t) cur->def.numval;
++ break;
++ }
++ case TUNABLE_TYPE_SIZE_T:
++ {
++ *((size_t *) valp) = (size_t) cur->def.numval;
++ break;
++ }
++ case TUNABLE_TYPE_STRING:
++ {
++ *((const char **)valp) = cur->def.strval;
++ break;
++ }
++ default:
++ __builtin_unreachable ();
++ }
++}
++rtld_hidden_def (__tunable_get_default)
++
+ /* Set the tunable value. This is called by the module that the tunable exists
+ in. */
+ void
+diff --git a/elf/dl-tunables.h b/elf/dl-tunables.h
+index 45c191e0..0df4dde2 100644
+--- a/elf/dl-tunables.h
++++ b/elf/dl-tunables.h
+@@ -45,18 +45,26 @@ typedef void (*tunable_callback_t) (tunable_val_t *);
+
+ extern void __tunables_init (char **);
+ extern void __tunables_print (void);
++extern bool __tunable_is_initialized (tunable_id_t);
+ extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t);
+ extern void __tunable_set_val (tunable_id_t, tunable_val_t *, tunable_num_t *,
+ tunable_num_t *);
++extern void __tunable_get_default (tunable_id_t id, void *valp);
+ rtld_hidden_proto (__tunables_init)
+ rtld_hidden_proto (__tunables_print)
++rtld_hidden_proto (__tunable_is_initialized)
+ rtld_hidden_proto (__tunable_get_val)
+ rtld_hidden_proto (__tunable_set_val)
++rtld_hidden_proto (__tunable_get_default)
+
+ /* Define TUNABLE_GET and TUNABLE_SET in short form if TOP_NAMESPACE and
+ TUNABLE_NAMESPACE are defined. This is useful shorthand to get and set
+ tunables within a module. */
+ #if defined TOP_NAMESPACE && defined TUNABLE_NAMESPACE
++# define TUNABLE_IS_INITIALIZED(__id) \
++ TUNABLE_IS_INITIALIZED_FULL(TOP_NAMESPACE, TUNABLE_NAMESPACE, __id)
++# define TUNABLE_GET_DEFAULT(__id, __type) \
++ TUNABLE_GET_DEFAULT_FULL(TOP_NAMESPACE, TUNABLE_NAMESPACE,__id, __type)
+ # define TUNABLE_GET(__id, __type, __cb) \
+ TUNABLE_GET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __cb)
+ # define TUNABLE_SET(__id, __val) \
+@@ -65,6 +73,10 @@ rtld_hidden_proto (__tunable_set_val)
+ TUNABLE_SET_WITH_BOUNDS_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, \
+ __val, __min, __max)
+ #else
++# define TUNABLE_IS_INITIALIZED(__top, __ns, __id) \
++ TUNABLE_IS_INITIALIZED_FULL(__top, __ns, __id)
++# define TUNABLE_GET_DEFAULT(__top, __ns, __type) \
++ TUNABLE_GET_DEFAULT_FULL(__top, __ns, __id, __type)
+ # define TUNABLE_GET(__top, __ns, __id, __type, __cb) \
+ TUNABLE_GET_FULL (__top, __ns, __id, __type, __cb)
+ # define TUNABLE_SET(__top, __ns, __id, __val) \
+@@ -73,6 +85,22 @@ rtld_hidden_proto (__tunable_set_val)
+ TUNABLE_SET_WITH_BOUNDS_FULL (__top, __ns, __id, __val, __min, __max)
+ #endif
+
++/* Return whether the tunable was initialized by the environment variable. */
++#define TUNABLE_IS_INITIALIZED_FULL(__top, __ns, __id) \
++({ \
++ tunable_id_t id = TUNABLE_ENUM_NAME (__top, __ns, __id); \
++ __tunable_is_initialized (id); \
++})
++
++/* Return the default value of the tunable. */
++#define TUNABLE_GET_DEFAULT_FULL(__top, __ns, __id, __type) \
++({ \
++ tunable_id_t id = TUNABLE_ENUM_NAME (__top, __ns, __id); \
++ __type __ret; \
++ __tunable_get_default (id, &__ret); \
++ __ret; \
++})
++
+ /* Get and return a tunable value. If the tunable was set externally and __CB
+ is defined then call __CB before returning the value. */
+ #define TUNABLE_GET_FULL(__top, __ns, __id, __type, __cb) \
+diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
+index 695ba719..5bb858b1 100644
+--- a/elf/dl-tunables.list
++++ b/elf/dl-tunables.list
+@@ -20,6 +20,7 @@
+ # type: Defaults to STRING
+ # minval: Optional minimum acceptable value
+ # maxval: Optional maximum acceptable value
++# default: Optional default value (if not specified it will be 0 or "")
+ # env_alias: An alias environment variable
+ # security_level: Specify security level of the tunable for AT_SECURE binaries.
+ # Valid values are:
+diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk
+index d6de100d..9726b052 100644
+--- a/scripts/gen-tunables.awk
++++ b/scripts/gen-tunables.awk
+@@ -177,8 +177,8 @@ END {
+ n = indices[2];
+ m = indices[3];
+ printf (" {TUNABLE_NAME_S(%s, %s, %s)", t, n, m)
+- printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, false, TUNABLE_SECLEVEL_%s, %s},\n",
+- types[t,n,m], minvals[t,n,m], maxvals[t,n,m],
++ printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, {%s}, false, TUNABLE_SECLEVEL_%s, %s},\n",
++ types[t,n,m], minvals[t,n,m], maxvals[t,n,m], default_val[t,n,m],
+ default_val[t,n,m], security_level[t,n,m], env_alias[t,n,m]);
+ }
+ print "};"
+--
+2.33.0
+
diff --git a/elf-Add-new-LoongArch-reloc-types-101-to-108-into-el.patch b/elf-Add-new-LoongArch-reloc-types-101-to-108-into-el.patch
new file mode 100644
index 0000000..b3d7545
--- /dev/null
+++ b/elf-Add-new-LoongArch-reloc-types-101-to-108-into-el.patch
@@ -0,0 +1,39 @@
+From fc60db3cf29ba157d09ba4f4b92e3ab382b0339d Mon Sep 17 00:00:00 2001
+From: Xi Ruoyao <xry111@xry111.site>
+Date: Wed, 9 Aug 2023 19:12:54 +0800
+Subject: [PATCH 04/29] elf: Add new LoongArch reloc types (101 to 108) into
+ elf.h
+
+These reloc types are generated by GNU assembler >= 2.41 for relaxation
+support.
+
+Link: https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=57a930e3
+Signed-off-by: Xi Ruoyao <xry111@xry111.site>
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ elf/elf.h | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/elf/elf.h b/elf/elf.h
+index 89fc8021..d623bdeb 100644
+--- a/elf/elf.h
++++ b/elf/elf.h
+@@ -4205,6 +4205,14 @@ enum
+ #define R_LARCH_TLS_GD_HI20 98
+ #define R_LARCH_32_PCREL 99
+ #define R_LARCH_RELAX 100
++#define R_LARCH_DELETE 101
++#define R_LARCH_ALIGN 102
++#define R_LARCH_PCREL20_S2 103
++#define R_LARCH_CFA 104
++#define R_LARCH_ADD6 105
++#define R_LARCH_SUB6 106
++#define R_LARCH_ADD_ULEB128 107
++#define R_LARCH_SUB_ULEB128 108
+
+ /* ARC specific declarations. */
+
+--
+2.33.0
+
diff --git a/elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch b/elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch
new file mode 100644
index 0000000..395a0a6
--- /dev/null
+++ b/elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch
@@ -0,0 +1,53 @@
+From ccdc4cba07684fe1397e1f5f134a0a827af98c04 Mon Sep 17 00:00:00 2001
+From: Hector Martin <marcan@marcan.st>
+Date: Tue, 28 Nov 2023 15:23:07 +0900
+Subject: [PATCH 2/9] elf: Fix TLS modid reuse generation assignment (BZ 29039)
+
+_dl_assign_tls_modid() assigns a slotinfo entry for a new module, but
+does *not* do anything to the generation counter. The first time this
+happens, the generation is zero and map_generation() returns the current
+generation to be used during relocation processing. However, if
+a slotinfo entry is later reused, it will already have a generation
+assigned. If this generation has fallen behind the current global max
+generation, then this causes an obsolete generation to be assigned
+during relocation processing, as map_generation() returns this
+generation if nonzero. _dl_add_to_slotinfo() eventually resets the
+generation, but by then it is too late. This causes DTV updates to be
+skipped, leading to NULL or broken TLS slot pointers and segfaults.
+
+Fix this by resetting the generation to zero in _dl_assign_tls_modid(),
+so it behaves the same as the first time a slot is assigned.
+_dl_add_to_slotinfo() will still assign the correct static generation
+later during module load, but relocation processing will no longer use
+an obsolete generation.
+
+Note that slotinfo entry (aka modid) reuse typically happens after a
+dlclose and only TLS access via dynamic tlsdesc is affected. Because
+tlsdesc is optimized to use the optional part of static TLS, dynamic
+tlsdesc can be avoided by increasing the glibc.rtld.optional_static_tls
+tunable to a large enough value, or by LD_PRELOAD-ing the affected
+modules.
+
+Fixes bug 29039.
+
+Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+(cherry picked from commit 3921c5b40f293c57cb326f58713c924b0662ef59)
+---
+ elf/dl-tls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 99b83ca696..1f6f820819 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -154,6 +154,7 @@ _dl_assign_tls_modid (struct link_map *l)
+ {
+ /* Mark the entry as used, so any dependency see it. */
+ atomic_store_relaxed (&runp->slotinfo[result - disp].map, l);
++ atomic_store_relaxed (&runp->slotinfo[result - disp].gen, 0);
+ break;
+ }
+
+--
+2.33.0
+
diff --git a/elf-Fix-wrong-break-removal-from-8ee878592c.patch b/elf-Fix-wrong-break-removal-from-8ee878592c.patch
new file mode 100644
index 0000000..b7afc64
--- /dev/null
+++ b/elf-Fix-wrong-break-removal-from-8ee878592c.patch
@@ -0,0 +1,26 @@
+From bf5aa419cbf545d2cd09dc097e518033d6e4df5e Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Thu, 7 Dec 2023 11:17:35 -0300
+Subject: [PATCH] elf: Fix wrong break removal from 8ee878592c
+
+Reported-by: Alexander Monakov <amonakov@ispras.ru>
+(cherry picked from commit 546a1ba664626603660b595662249d524e429013)
+---
+ elf/readelflib.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/elf/readelflib.c b/elf/readelflib.c
+index f5b8c80e38..64f1d662a9 100644
+--- a/elf/readelflib.c
++++ b/elf/readelflib.c
+@@ -107,6 +107,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
+ case PT_INTERP:
+ program_interpreter = (char *) (file_contents + segment->p_offset);
+ check_ptr (program_interpreter);
++ break;
+
+ case PT_GNU_PROPERTY:
+ /* The NT_GNU_PROPERTY_TYPE_0 note must be aligned to 4 bytes
+--
+2.33.0
+
diff --git a/fix-Segmentation-fault-in-nss-module.patch b/fix-Segmentation-fault-in-nss-module.patch
new file mode 100644
index 0000000..21d75b9
--- /dev/null
+++ b/fix-Segmentation-fault-in-nss-module.patch
@@ -0,0 +1,40 @@
+From f5b9e0f2a8ada29cebeb6e51cbcbea396375ab26 Mon Sep 17 00:00:00 2001
+From: huangyu <huangyu106@huawei.com>
+Date: Wed, 7 Dec 2022 14:35:26 +0800
+Subject: [PATCH] fix Segmentation fault in nss module
+
+Signed-off-by: huangyu <huangyu106@huawei.com>
+---
+ nss/nss_module.c | 2 +-
+ nss/nsswitch.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/nss/nss_module.c b/nss/nss_module.c
+index b28cb94a..bb2807e9 100644
+--- a/nss/nss_module.c
++++ b/nss/nss_module.c
+@@ -352,7 +352,7 @@ nss_load_all_libraries (enum nss_database service)
+ {
+ nss_action_list ni = NULL;
+
+- if (__nss_database_get (service, &ni))
++ if (__nss_database_get (service, &ni) && ni != NULL)
+ while (ni->module != NULL)
+ {
+ __nss_module_load (ni->module);
+diff --git a/nss/nsswitch.c b/nss/nsswitch.c
+index 6b7d4c78..c9d7e372 100644
+--- a/nss/nsswitch.c
++++ b/nss/nsswitch.c
+@@ -133,7 +133,7 @@ libc_hidden_def (__nss_next2)
+ void *
+ __nss_lookup_function (nss_action_list ni, const char *fct_name)
+ {
+- if (ni->module == NULL)
++ if (ni == NULL || ni->module == NULL)
+ return NULL;
+ return __nss_module_get_function (ni->module, fct_name);
+ }
+--
+2.33.0
+
diff --git a/fix_nss_database_check_reload_and_get_memleak.patch b/fix_nss_database_check_reload_and_get_memleak.patch
new file mode 100644
index 0000000..6fc5789
--- /dev/null
+++ b/fix_nss_database_check_reload_and_get_memleak.patch
@@ -0,0 +1,38 @@
+From 66c23fa97a1bf8819051f1c358ae5eb38eeefae2 Mon Sep 17 00:00:00 2001
+From: huangyu <huangyu106@huawei.com>
+Date: Tue, 6 Sep 2022 11:55:40 +0800
+Subject: [PATCH] huawei-fix_nss_database_check_reload_and_get_memleak.patch
+The return nss_database_check_reload_adn_get (local, actions, db) does not check
+whether the local value is empty before invoking the local interface.
+
+Signed-off-by: huangyu <huangyu106@huawei.com>
+---
+ nss/nss_database.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/nss/nss_database.c b/nss/nss_database.c
+index 54561f03..a503890a 100644
+--- a/nss/nss_database.c
++++ b/nss/nss_database.c
+@@ -254,6 +254,8 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
+ __nss_database_get (db, &result);
+
+ local = nss_database_state_get ();
++ if (local == NULL)
++ return -1;
+
+ result = __nss_action_parse (service_line);
+ if (result == NULL)
+@@ -399,6 +401,9 @@ nss_database_check_reload_and_get (struct nss_database_state *local,
+ /* Acquire MO is needed because the thread that sets reload_disabled
+ may have loaded the configuration first, so synchronize with the
+ Release MO store there. */
++ if (local == NULL)
++ return false;
++
+ if (atomic_load_acquire (&local->data.reload_disabled))
+ {
+ *result = local->data.services[database_index];
+--
+2.33.0
+
diff --git a/getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch b/getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch
new file mode 100644
index 0000000..29a633d
--- /dev/null
+++ b/getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch
@@ -0,0 +1,36 @@
+From ae1e5217021e43e1f2de443d26e87ea3adfb221c Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@suse.de>
+Date: Wed, 6 Dec 2023 14:48:22 +0100
+Subject: [PATCH 8/9] getaddrinfo: translate ENOMEM to EAI_MEMORY (bug 31163)
+
+When __resolv_context_get returns NULL due to out of memory, translate it
+to a return value of EAI_MEMORY.
+
+(cherry picked from commit 5eabdb6a6ac1599d23dd5966a37417215950245f)
+---
+ sysdeps/posix/getaddrinfo.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index 13082305d3..da573bea24 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -616,7 +616,14 @@ get_nss_addresses (const char *name, const struct addrinfo *req,
+ function variant. */
+ res_ctx = __resolv_context_get ();
+ if (res_ctx == NULL)
+- no_more = 1;
++ {
++ if (errno == ENOMEM)
++ {
++ result = -EAI_MEMORY;
++ goto out;
++ }
++ no_more = 1;
++ }
+
+ while (!no_more)
+ {
+--
+2.33.0
+
diff --git a/glibc-1070416.patch b/glibc-1070416.patch
new file mode 100644
index 0000000..0975e0f
--- /dev/null
+++ b/glibc-1070416.patch
@@ -0,0 +1,38 @@
+Short description: Add syslog.target dependency.
+Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
+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/glibc-bench-compare b/glibc-bench-compare
new file mode 100644
index 0000000..84e3aba
--- /dev/null
+++ b/glibc-bench-compare
@@ -0,0 +1,153 @@
+#!/usr/bin/bash
+# This script can be invoked as follows:
+#
+# glibc-bench-compare [options] <BUILD> [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] <old> [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/glibc.spec b/glibc.spec
new file mode 100644
index 0000000..73a43a5
--- /dev/null
+++ b/glibc.spec
@@ -0,0 +1,2031 @@
+%global __filter_GLIBC_PRIVATE 1
+
+%define rpm_ver_major %(eval "echo `rpm -q rpm |cut -d '-' -f2 |cut -d. -f1`")
+%define rpm_ver_minor %(eval "echo `rpm -q rpm |cut -d '-' -f2 |cut -d. -f2`")
+%define rpm_version_ge_412 %(eval "if [ %{rpm_ver_major} -gt 4 -o %{rpm_ver_major} -eq 4 -a %{rpm_ver_minor} -ge 12 ]; then echo 1; else echo 0; fi")
+%define gcc_version %(eval "echo `gcc --version |head -1 |awk '{print $3}' |awk -F '.' '{print $1}'`")
+##############################################################################
+# We support the following options:
+# --with/--without,
+# * testsuite
+# - Running the testsuite. It must run for production builds.
+# - Default: Always run the testsuite.
+# * benchtests
+# - Running and building benchmark subpackage.
+# - Default: Always build the benchtests.
+# * bootstrap
+# - Bootstrapping the package.
+# - Default: Not bootstrapping.
+# * werror
+# - Build with -Werror
+# - Default: Enable using -Werror
+# * docs
+# - Build with documentation and the required dependencies.
+# - Default: Always build documentation.
+# * valgrind
+# - Run smoke tests with valgrind to verify dynamic loader.
+# - Default: Always run valgrind tests if there is architecture support.
+##############################################################################
+%bcond_without testsuite
+%bcond_with benchtests
+%bcond_with bootstrap
+%bcond_without werror
+%bcond_without docs
+%ifarch x86_64 aarch64
+%bcond_with compat_2_17
+%endif
+
+%ifarch %{valgrind_arches}
+%bcond_without valgrind
+%else
+%bcond_with valgrind
+%endif
+
+%if %{with bootstrap}
+%undefine with_benchtests
+%undefine with_werror
+%undefine with_docs
+%undefine with_valgrind
+%endif
+
+%global ENABLE_RELOC 0
+
+# Only some architectures have static PIE support
+%define pie_arches %{ix86} x86_64 aarch64 loongarch64
+
+%define enablekernel 3.2
+%define target %{_target_cpu}-%{_vendor}-linux
+%ifarch %{arm}
+%define target %{_target_cpu}-%{_vendor}-linuxeabi
+%endif
+%define x86_arches %{ix86} x86_64
+%define all_license LGPLv2+ and LGPLv2+ with exceptions and GPLv2+ and GPLv2+ with exceptions and BSD and Inner-Net and ISC and Public Domain and GFDL-1.3-only
+%define GCC gcc
+%define GXX g++
+##############################################################################
+# glibc - The GNU C Library (glibc) core package.
+##############################################################################
+Name: glibc
+Version: 2.38
+Release: 39
+Summary: The GNU libc libraries
+License: %{all_license}
+URL: http://www.gnu.org/software/glibc/
+
+Source0: https://ftp.gnu.org/gnu/glibc/%{name}-%{version}.tar.xz
+Source1: nscd.conf
+Source2: nsswitch.conf
+Source3: bench.mk
+Source4: glibc-bench-compare
+Source5: LanguageList
+Source6: LicenseList
+Source7: replace_same_file_to_hard_link.py
+
+%if %{with testsuite}
+Source8: testsuite_whitelist
+%endif
+
+#upstream glibc patch
+Patch0: glibc-1070416.patch
+Patch1: stdlib-Improve-tst-realpath-compatibility-with-sourc.patch
+Patch2: 0001-x86-Fix-for-cache-computation-on-AMD-legacy-cpus.patch
+Patch3: 0002-nscd-Do-not-rebuild-getaddrinfo-bug-30709.patch
+Patch4: 0003-x86-Fix-incorrect-scope-of-setting-shared_per_thread.patch
+Patch5: 0004-x86_64-Fix-build-with-disable-multiarch-BZ-30721.patch
+Patch6: 0005-i686-Fix-build-with-disable-multiarch.patch
+Patch7: 0006-malloc-Enable-merging-of-remainders-in-memalign-bug-.patch
+Patch8: 0007-malloc-Remove-bin-scanning-from-memalign-bug-30723.patch
+Patch9: 0008-sysdeps-tst-bz21269-fix-test-parameter.patch
+Patch10: 0009-sysdeps-tst-bz21269-handle-ENOSYS-skip-appropriately.patch
+Patch11: 0010-sysdeps-tst-bz21269-fix-Wreturn-type.patch
+Patch12: 0011-io-Fix-record-locking-contants-for-powerpc64-with-__.patch
+Patch13: 0012-libio-Fix-oversized-__io_vtables.patch
+Patch14: 0001-elf-Do-not-run-constructors-for-proxy-objects.patch
+Patch15: 0002-elf-Always-call-destructors-in-reverse-constructor-o.patch
+Patch16: 0003-elf-Remove-unused-l_text_end-field-from-struct-link_.patch
+Patch17: 0004-elf-Move-l_init_called_next-to-old-place-of-l_text_e.patch
+Patch18: 0005-NEWS-Add-the-2.38.1-bug-list.patch
+Patch19: CVE-2023-4527-Stack-read-overflow-with-large-TCP-res.patch
+Patch20: 0001-getaddrinfo-Fix-use-after-free-in-getcanonname-CVE-2.patch
+Patch21: 0002-iconv-restore-verbosity-with-unrecognized-encoding-n.patch
+Patch22: 0003-string-Fix-tester-build-with-fortify-enable-with-gcc.patch
+Patch23: 0004-manual-jobs.texi-Add-missing-item-EPERM-for-getpgid.patch
+Patch24: 0001-Fix-leak-in-getaddrinfo-introduced-by-the-fix-for-CV.patch
+Patch25: 0002-Document-CVE-2023-4806-and-CVE-2023-5156-in-NEWS.patch
+Patch26: 0003-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch
+Patch27: 0004-tunables-Terminate-if-end-of-input-is-reached-CVE-20.patch
+Patch28: 0001-Revert-elf-Remove-unused-l_text_end-field-from-struc.patch
+Patch29: 0002-Revert-elf-Always-call-destructors-in-reverse-constr.patch
+Patch30: 0003-Revert-elf-Move-l_init_called_next-to-old-place-of-l.patch
+Patch31: sysdeps-sem_open-Clear-O_CREAT-when-semaphore-file-i.patch
+Patch32: elf-Fix-wrong-break-removal-from-8ee878592c.patch
+Patch33: backport-elf-Handle-non-directory-name-in-search-path-BZ-3103.patch
+Patch34: LoongArch-Delete-excessively-allocated-memory.patch
+Patch35: elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch
+Patch36: elf-Add-TLS-modid-reuse-test-for-bug-29039.patch
+Patch37: x86-64-Fix-the-dtv-field-load-for-x32-BZ-31184.patch
+Patch38: x86-64-Fix-the-tcb-field-load-for-x32-BZ-31185.patch
+Patch39: NEWS-Mention-bug-fixes-for-29039-30694-30709-30721.patch
+Patch40: NEWS-Mention-bug-fixes-for-30745-30843.patch
+Patch41: getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch
+Patch42: libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch
+Patch43: elf-Add-a-way-to-check-if-tunable-is-set-BZ-27069.patch
+Patch44: malloc-Improve-MAP_HUGETLB-with-glibc.malloc.hugetlb.patch
+Patch45: 0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
+Patch46: 0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
+Patch47: 0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch
+Patch48: x86_64-Optimize-ffsll-function-code-size.patch
+Patch49: S390-Fix-building-with-disable-mutli-arch-BZ-31196.patch
+Patch50: sparc-Fix-broken-memset-for-sparc32-BZ-31068.patch
+Patch51: sparc64-Remove-unwind-information-from-signal-return.patch
+Patch52: sparc-Fix-sparc64-memmove-length-comparison-BZ-31266.patch
+Patch53: sparc-Remove-unwind-information-from-signal-return-s.patch
+Patch54: arm-Remove-wrong-ldr-from-_dl_start_user-BZ-31339.patch
+Patch55: malloc-Use-__get_nprocs-on-arena_get2-BZ-30945.patch
+Patch56: LoongArch-Redefine-macro-LEAF-ENTRY.patch
+Patch57: LoongArch-Add-minuimum-binutils-required-version.patch
+Patch58: Loongarch-Add-ifunc-support-and-add-different-versio.patch
+Patch59: elf-Add-new-LoongArch-reloc-types-101-to-108-into-el.patch
+Patch60: LoongArch-elf-Add-new-LoongArch-reloc-types-109-into.patch
+Patch61: Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch
+Patch62: Loongarch-Add-ifunc-support-for-memcpy-aligned-unali.patch
+Patch63: LoongArch-Add-ifunc-support-for-strnlen-aligned-lsx-.patch
+Patch64: LoongArch-Add-ifunc-support-for-strcmp-aligned-lsx.patch
+Patch65: LoongArch-Add-ifunc-support-for-strncmp-aligned-lsx.patch
+Patch66: LoongArch-Remove-support-code-for-old-linker-in-star.patch
+Patch67: LoongArch-Micro-optimize-LD_PCREL.patch
+Patch68: LoongArch-Add-ifunc-support-for-rawmemchr-aligned-ls.patch
+Patch69: LoongArch-Add-ifunc-support-for-memchr-aligned-lsx-l.patch
+Patch70: LoongArch-Add-ifunc-support-for-memrchr-lsx-lasx.patch
+Patch71: LoongArch-Add-ifunc-support-for-memset-aligned-unali.patch
+Patch72: LoongArch-Add-ifunc-support-for-memcmp-aligned-lsx-l.patch
+Patch73: LoongArch-Change-loongarch-to-LoongArch-in-comments.patch
+Patch74: LoongArch-Add-lasx-lsx-support-for-_dl_runtime_profi.patch
+Patch75: LoongArch-Replace-deprecated-v0-with-a0-to-eliminate.patch
+Patch76: LoongArch-Add-ifunc-support-for-strcpy-stpcpy-aligne.patch
+Patch77: LoongArch-Add-ifunc-support-for-strrchr-aligned-lsx-.patch
+Patch78: LoongArch-Change-to-put-magic-number-to-.rodata-sect.patch
+Patch79: LoongArch-Add-glibc.cpu.hwcap-support.patch
+Patch80: Revert-LoongArch-Add-glibc.cpu.hwcap-support.patch
+Patch81: LoongArch-Unify-Register-Names.patch
+Patch82: LoongArch-Update-hwcap.h-to-sync-with-LoongArch-kern.patch
+Patch83: linux-Sync-Linux-6.6-elf.h.patch
+Patch84: Decrease-value-of-arch_minimum_kernel-with-LoongArch.patch
+Patch85: 0001-S390-Do-not-clobber-r7-in-clone-BZ-31402.patch
+Patch86: 0002-linux-Use-rseq-area-unconditionally-in-sched_getcpu-.patch
+Patch87: 0003-LoongArch-Correct-__ieee754-_-_scalb-__ieee754-_-_sc.patch
+Patch88: 0004-Add-HWCAP2_MOPS-from-Linux-6.5-to-AArch64-bits-hwcap.patch
+Patch89: 0005-AArch64-Add-support-for-MOPS-memcpy-memmove-memset.patch
+Patch90: 0006-AArch64-Cleanup-ifuncs.patch
+Patch91: 0007-AArch64-Cleanup-emag-memset.patch
+Patch92: 0008-AArch64-Add-memset_zva64.patch
+Patch93: 0009-AArch64-Remove-Falkor-memcpy.patch
+Patch94: 0010-aarch64-correct-CFI-in-rawmemchr-bug-31113.patch
+Patch95: 0011-aarch64-fix-check-for-SVE-support-in-assembler.patch
+Patch96: 0012-AArch64-Check-kernel-version-for-SVE-ifuncs.patch
+Patch97: 0013-powerpc-Fix-ld.so-address-determination-for-PCREL-mo.patch
+Patch98: 0014-iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch
+Patch99: 0015-sparc-Remove-64-bit-check-on-sparc32-wordsize-BZ-275.patch
+Patch100: 0016-login-Check-default-sizes-of-structs-utmp-utmpx-last.patch
+Patch101: 0017-login-structs-utmp-utmpx-lastlog-_TIME_BITS-independ.patch
+Patch102: 0018-nptl-Fix-tst-cancel30-on-kernels-without-ppoll_time6.patch
+Patch103: 0019-i386-ulp-update-for-SSE2-disable-multi-arch-configur.patch
+Patch104: 0020-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch
+Patch105: 0021-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch
+Patch106: 0022-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch
+Patch107: 0023-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two-.patch
+Patch108: 0024-elf-Also-compile-dl-misc.os-with-rtld-early-cflags.patch
+Patch109: 0025-nscd-Use-time_t-for-return-type-of-addgetnetgrentX.patch
+Patch110: 0026-resolv-Fix-some-unaligned-accesses-in-resolver-BZ-30.patch
+Patch111: Force-DT_RPATH-for-enable-hardcoded-path-in-tests.patch
+Patch112: i386-Disable-Intel-Xeon-Phi-tests-for-GCC-15-and-abo.patch
+Patch113: misc-Add-support-for-Linux-uio.h-RWF_NOAPPEND-flag.patch
+Patch114: 0001-s390x-Fix-segfault-in-wcsncmp-BZ-31934.patch
+Patch115: 0002-nptl-fix-potential-merge-of-__rseq_-relro-symbols.patch
+Patch116: 0003-elf-Make-dl-rseq-symbols-Linux-only.patch
+Patch117: 0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch
+Patch118: 0005-resolv-Allow-short-error-responses-to-match-any-quer.patch
+Patch119: 0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch
+Patch120: 0007-resolv-Track-single-request-fallback-via-_res._flags.patch
+Patch121: 0008-linux-Update-the-mremap-C-implementation-BZ-31968.patch
+Patch122: 0009-mremap-Update-manual-entry.patch
+Patch123: 0010-Add-mremap-tests.patch
+Patch124: 0011-Update-syscall-lists-for-Linux-6.5.patch
+Patch125: 0012-resolv-Fix-tst-resolv-short-response-for-older-GCC-b.patch
+Patch126: Fix-name-space-violation-in-fortify-wrappers-bug-320.patch
+Patch127: x86-Fix-bug-in-strchrnul-evex512-BZ-32078.patch
+Patch128: 19614-locale-Handle-loading-a-missing-locale-twice-Bug-14.patch
+Patch129: support-Add-FAIL-test-failure-helper.patch
+Patch130: stdio-common-Add-test-for-vfscanf-with-matches-longe.patch
+Patch131: Make-tst-ungetc-use-libsupport.patch
+Patch132: ungetc-Fix-uninitialized-read-when-putting-into-unus.patch
+Patch133: ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch
+Patch134: posix-Use-support-check.h-facilities-in-tst-truncate.patch
+Patch135: nptl-Use-support-check.h-facilities-in-tst-setuid3.patch
+
+#openEuler patch list
+Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
+Patch9001: locale-delete-no-hard-link-to-avoid-all_language-pac.patch
+Patch9002: use-region-to-instead-of-country-for-extract-timezon.patch
+Patch9003: strcmp-delete-align-for-loop_aligned.patch
+Patch9004: add-pthread_cond_clockwait-GLIBC_2_28.patch
+Patch9005: add-GB18030-2022-charmap-BZ-30243.patch
+Patch9006: fix-Segmentation-fault-in-nss-module.patch
+Patch9007: fix_nss_database_check_reload_and_get_memleak.patch
+Patch9008: 0001-fix-glibc-build-error-on-x86.patch
+
+%if %{ENABLE_RELOC}
+Patch9009: reserve-relocation-information-for-sysboost.patch
+%endif
+Patch9010: add-Wl-z-noseparate-code-for-so.patch
+
+Provides: ldconfig rtld(GNU_HASH) bundled(gnulib)
+
+BuildRequires: audit-libs-devel >= 1.1.3, sed >= 3.95, libcap-devel, gettext
+BuildRequires: procps-ng, util-linux, gawk, systemtap-sdt-devel, systemd, python3
+BuildRequires: make >= 4.0, bison >= 2.7, binutils >= 2.30-17, gcc >= 7.2.1-6
+BuildRequires: m4, chrpath
+
+%if %{without bootstrap}
+BuildRequires: gd-devel libpng-devel zlib-devel
+%endif
+
+%if %{with docs}
+BuildRequires: texinfo >= 5.0
+%endif
+
+%if %{without bootstrap}
+BuildRequires: libselinux-devel >= 1.33.4-3
+%endif
+
+%if %{with valgrind}
+BuildRequires: valgrind
+%endif
+
+%if 0%{?_enable_debug_packages}
+BuildRequires: elfutils >= 0.72 rpm >= 4.2-0.56
+%endif
+
+%if %{without bootstrap}
+%if %{with testsuite}
+BuildRequires: gcc-c++ libstdc++-static glibc-devel libidn2
+%endif
+%endif
+
+Requires: glibc-common = %{version}-%{release}
+Requires: glibc-langpack = %{version}-%{release}
+Requires: basesystem
+
+%description
+The GNU C Library project provides the core libraries for the GNU system and
+GNU/Linux systems, as well as many other systems that use Linux as the kernel.
+These libraries provide critical APIs including ISO C11, POSIX.1-2008, BSD,
+OS-specific APIs and more. These APIs include such foundational facilities as
+open, read, write, malloc, printf, getaddrinfo, dlopen, pthread_create, crypt,
+ login, exit and more.
+
+##############################################################################
+# glibc "common" sub-package
+##############################################################################
+%package common
+Summary: Common binaries and locale data for glibc
+Provides: glibc-langpack = %{version}-%{release}
+
+Provides: glibc-langpack-en = %{version}-%{release}
+Provides: glibc-langpack-en%{?_isa} = %{version}-%{release}
+Provides: glibc-langpack-zh = %{version}-%{release}
+Provides: glibc-langpack-zh%{?_isa} = %{version}-%{release}
+
+Requires: %{name} = %{version}-%{release}
+Requires: tzdata >= 2003a
+
+%description common
+The glibc-common package includes common binaries for the GNU libc
+libraries and national language (locale) support. Besides, zh_CN and
+en_US are included.
+
+%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
+
+%undefine __brp_ldconfig
+
+##############################################################################
+# glibc "all-langpacks" sub-package
+##############################################################################
+%package all-langpacks
+Summary: All language packs for %{name}.
+Requires: %{name} = %{version}-%{release}
+Requires: %{name}-common = %{version}-%{release}
+Provides: %{name}-langpack = %{version}-%{release}
+Obsoletes: %{name}-minimal-langpack <= 2.28
+
+%{lua:
+-- List the Symbol provided by all-langpacks
+lang_provides = {}
+for line in io.lines(rpm.expand("%{SOURCE5}")) do
+ print(rpm.expand([[
+Provides:]]..line..[[ = %{version}-%{release}
+Obsoletes:]]..line..[[ <= 2.28
+]]))
+end
+}
+
+%description all-langpacks
+The glibc-all-langpacks provides all the glibc-langpacks. Every entry
+includes the basic information required to support the corresponding
+language in your applications.
+
+##############################################################################
+# glibc "locale-source" sub-package
+##############################################################################
+%package locale-source
+Summary: The sources package of locales
+Requires: %{name} = %{version}-%{release}
+Requires: %{name}-common = %{version}-%{release}
+
+%description locale-source
+The locale-source package contains all language packs which are built custom
+locales
+
+##############################################################################
+# glibc "locale-archive" sub-package
+##############################################################################
+%package locale-archive
+Summary: The locale-archive of glibc
+Requires: %{name} = %{version}-%{release}
+Requires: %{name}-common = %{version}-%{release}
+
+%description locale-archive
+The locale-archive sub package contains the locale-archive. In the past,
+this file is provided in "glibc-common".Now, we provide basic language support
+in "glibc-common", but if you need a customized language, you can extract
+it from the "local-archive".
+
+##############################################################################
+# glibc "devel" sub-package
+##############################################################################
+%package devel
+Summary: The devel for %{name}
+Requires: %{name} = %{version}-%{release}
+Requires: libgcc%{_isa}
+Requires(pre): kernel-headers
+Requires(pre): coreutils
+Requires: kernel-headers >= 3.2
+%if 0%{rpm_version_ge_412}
+Requires: libxcrypt-devel%{_isa} >= 4.0.0
+Requires: libxcrypt-static%{?_isa} >= 4.0.0
+%endif
+BuildRequires: kernel-headers >= 3.2
+
+Provides: %{name}-static = %{version}-%{release}
+Provides: %{name}-static%{_isa} = %{version}-%{release}
+Provides: %{name}-headers = %{version}-%{release}
+Provides: %{name}-headers(%{_target_cpu})
+Provides: %{name}-headers%{_isa} = %{version}-%{release}
+
+Obsoletes: %{name}-static <= 2.28
+Obsoletes: %{name}-headers <= 2.28
+
+%description devel
+The glibc-devel package contains the object files necessary for developing
+programs which use the standard C libraries. Besides, it contains the
+headers. Thus, it is necessory to install glibc-devel if you ned develop programs.
+
+##############################################################################
+# glibc "nscd" sub-package
+##############################################################################
+%package -n nscd
+Summary: Name caching service daemon.
+Requires: %{name} = %{version}-%{release}
+%if %{without bootstrap}
+Requires: libselinux >= 1.17.10-1
+%endif
+Requires: audit-libs >= 1.1.3
+Requires(pre): shadow-utils, coreutils
+Requires: systemd
+Requires(postun): shadow-utils
+
+%description -n nscd
+The nscd package is able to daemon caches name service lookups and improve
+the performance with LDAP.
+
+##############################################################################
+# nss modules sub-package
+##############################################################################
+%package -n nss_modules
+Summary: Name Service Switch module using hash-indexed files and Hesiod
+Requires: %{name}%{_isa} = %{version}-%{release}
+Provides: nss_db = %{version}-%{release}
+Provides: nss_db%{_isa} = %{version}-%{release}
+Provides: nss_hesiod = %{version}-%{release}
+Provides: nss_hesiod%{_isa} = %{version}-%{release}
+Obsoletes: nss_db <= 2.28, nss_hesiod <= 2.28
+
+%description -n nss_modules
+This package contains nss_db and nss_hesiod. The former uses hash-indexed files
+to speed up user, group, service, host name, and other NSS-based lookups.The
+latter uses the Domain Name System (DNS) as a source for user, group, and service
+information to follow the Hesiod convention of Project Athena.
+
+##############################################################################
+# nss-devel sub-package
+##############################################################################
+%package nss-devel
+Summary: The devel for directly linking NSS service modules
+Requires: nss_db%{_isa} = %{version}-%{release}
+Requires: nss_hesiod%{_isa} = %{version}-%{release}
+
+%description nss-devel
+This package contains the necessary devel files to compile applications and
+libraries which directly link against NSS modules supplied by glibc. This
+package is rarely used, and in most cases use the glibc-devel package instead.
+
+##############################################################################
+# libnsl subpackage
+##############################################################################
+%package -n libnsl
+Summary: Public client interface for NIS(YP) and NIS+
+Requires: %{name}%{_isa} = %{version}-%{release}
+
+%description -n libnsl
+The libnsl package contains the public client interface for NIS(YP) and NIS+.
+It replaces the NIS library that used to be in glibc.
+
+##############################################################################
+# glibc benchtests sub-package
+##############################################################################
+%if %{with benchtests}
+
+%package benchtests
+Summary: Build benchmarking binaries and scripts for %{name}
+
+%description benchtests
+This package provides built benchmark binaries and scripts which will be used
+to run microbenchmark tests on the system.
+%endif
+
+##############################################################################
+# glibc debugutils sub-package
+##############################################################################
+%package debugutils
+Summary: debug files for %{name}
+Requires: %{name} = %{version}-%{release}
+Provides: %{name}-utils = %{version}-%{release}
+Provides: %{name}-utils%{_isa} = %{version}-%{release}
+
+Obsoletes: %{name}-utils <= 2.28
+
+%description debugutils
+This package provides memusage, a memory usage profiler, mtrace, a memory leak
+tracer and xtrace, a function call tracer, all of which is not necessory for you.
+
+##############################################################################
+# glibc help sub-package
+##############################################################################
+%package help
+Summary: The doc and man for %{name}
+Buildarch: noarch
+Requires: man info
+Requires: %{name} = %{version}-%{release}
+
+%description help
+This package provides all doc, man and info files of %{name}
+
+##############################################################################
+# glibc compat-2.17 sub-package
+##############################################################################
+%if %{with compat_2_17}
+%package compat-2.17
+Summary: provides pthread library with glibc-2.17
+
+%description compat-2.17
+This subpackage to provide the function of the glibc-2.17 pthread library.
+Currently, provide pthread_condition function.
+To keep older applications compatible, glibc-compat-2.17 provides libpthread_nonshared.a
+%endif
+
+%if %{ENABLE_RELOC}
+##############################################################################
+# glibc reloc sub-package
+##############################################################################
+%package relocation
+Summary: Relocations for %{name}
+Requires: %{name} = %{version}-%{release}
+BuildRequires: native-turbo-tools
+
+%description relocation
+This package contains relocations for %{name}.
+%endif
+
+##############################################################################
+# Prepare for the build.
+##############################################################################
+%prep
+%autosetup -n %{name}-%{version} -p1
+
+chmod +x benchtests/scripts/*.py scripts/pylint
+
+find . -type f -size 0 -o -name "*.orig" -exec rm -f {} \;
+
+touch `find . -name configure`
+
+touch locale/programs/*-kw.h
+
+##############################################################################
+# Build glibc...
+##############################################################################
+%build
+
+BuildFlags="-O2 -g -DNDEBUG -fPIC -fPIE -fstack-protector-strong"
+LinkFlags="-pie -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack"
+
+%ifarch aarch64
+BuildFlags="$BuildFlags -mno-outline-atomics"
+%endif
+
+reference=" \
+ "-Wp,-D_GLIBCXX_ASSERTIONS" \
+ "-fasynchronous-unwind-tables" \
+ "-fstack-clash-protection" \
+ "-funwind-tables" \
+ "-m31" \
+ "-m32" \
+ "-m64" \
+ "-march=haswell" \
+ "-march=i686" \
+ "-march=x86-64" \
+ "-march=z13" \
+ "-march=z14" \
+ "-march=zEC12" \
+ "-mfpmath=sse" \
+ "-msse2" \
+ "-mstackrealign" \
+ "-mtune=generic" \
+ "-mtune=z13" \
+ "-mtune=z14" \
+ "-mtune=zEC12" \
+ "-specs=/usr/lib/rpm/%{_vendor}/%{_vendor}-annobin-cc1" "
+
+for flag in $RPM_OPT_FLAGS $RPM_LD_FLAGS ; do
+ if echo "$reference" | grep -q -F " $flag " ; then
+ BuildFlags="$BuildFlags $flag"
+ fi
+done
+
+%define glibc_make_flags_as ASFLAGS="-g -Wa,--generate-missing-build-notes=yes"
+%define glibc_make_flags %{glibc_make_flags_as}
+
+EnableKernel="--enable-kernel=%{enablekernel}"
+
+builddir=build-%{target}
+rm -rf $builddir
+mkdir $builddir
+pushd $builddir
+../configure CC="%GCC" CXX="%GXX" CFLAGS="$BuildFlags" LDFLAGS="$LinkFlags" \
+ --prefix=%{_prefix} \
+ --with-headers=%{_prefix}/include $EnableKernel \
+ --with-nonshared-cflags=-Wp,-D_FORTIFY_SOURCE=2 \
+ --enable-bind-now \
+ --enable-shared \
+ --build=%{target} \
+ --enable-stack-protector=strong \
+%ifarch %{pie_arches}
+%if 0%{?gcc_version} >= 8
+ --enable-static-pie \
+%endif
+%endif
+%ifarch %{x86_arches}
+%if 0%{?gcc_version} >= 8
+ --enable-cet \
+%endif
+%endif
+ --enable-tunables \
+ --enable-systemtap \
+%ifarch %{ix86}
+ --disable-multi-arch \
+%endif
+%if %{without werror}
+ --disable-werror \
+%endif
+ --disable-profile \
+%if %{with bootstrap}
+ --without-selinux \
+%endif
+%if 0%{rpm_version_ge_412}
+ --disable-crypt \
+%endif
+ ||
+ { cat config.log; false; }
+
+make %{?_smp_mflags} -O -r %{glibc_make_flags}
+%if %{ENABLE_RELOC}
+objreloc libc.so.6
+%endif
+popd
+
+##############################################################################
+# Build libpthread-2.17.so
+##############################################################################
+%if %{with compat_2_17}
+ cd nptl_2_17
+ sh build_libpthread-2.17.so.sh %{_target_cpu} $builddir
+ cd ..
+%endif
+
+##############################################################################
+# Install glibc...
+##############################################################################
+%install
+%ifarch riscv64
+for d in $RPM_BUILD_ROOT%{_libdir} $RPM_BUILD_ROOT/%{_lib}; do
+ mkdir -p $d
+ (cd $d && ln -sf . lp64d)
+done
+%endif
+
+make %{?_smp_mflags} install_root=$RPM_BUILD_ROOT install -C build-%{target}
+
+pushd build-%{target}
+
+make %{?_smp_mflags} install_root=$RPM_BUILD_ROOT \
+ install-locale-files -C ../localedata objdir=`pwd`
+popd
+
+python3 %{SOURCE7} $RPM_BUILD_ROOT/usr/lib/locale
+
+rm -f $RPM_BUILD_ROOT/%{_libdir}/libNoVersion*
+rm -f $RPM_BUILD_ROOT/%{_lib}/libNoVersion*
+rm -f $RPM_BUILD_ROOT/%{_lib}/libnss1-*
+rm -f $RPM_BUILD_ROOT/%{_lib}/libnss-*.so.1
+rm -f $RPM_BUILD_ROOT/{usr/,}sbin/sln
+
+mkdir -p $RPM_BUILD_ROOT/var/cache/ldconfig
+truncate -s 0 $RPM_BUILD_ROOT/var/cache/ldconfig/aux-cache
+
+$RPM_BUILD_ROOT/sbin/ldconfig -N -r $RPM_BUILD_ROOT
+
+# Install info files
+%if %{with docs}
+# Move the info files if glibc installed them into the wrong location.
+if [ -d $RPM_BUILD_ROOT%{_prefix}/info -a "%{_infodir}" != "%{_prefix}/info" ]; then
+ mkdir -p $RPM_BUILD_ROOT%{_infodir}
+ mv -f $RPM_BUILD_ROOT%{_prefix}/info/* $RPM_BUILD_ROOT%{_infodir}
+ rm -rf $RPM_BUILD_ROOT%{_prefix}/info
+fi
+
+# Compress all of the info files.
+gzip -9nvf $RPM_BUILD_ROOT%{_infodir}/libc*
+
+%else
+rm -f $RPM_BUILD_ROOT%{_infodir}/dir
+rm -f $RPM_BUILD_ROOT%{_infodir}/libc.info*
+%endif
+
+# Create all-packages libc.lang
+olddir=`pwd`
+pushd $RPM_BUILD_ROOT%{_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 $RPM_BUILD_ROOT --add-to-archive \
+ eo *_*
+%{find_lang} libc
+# In the past, locale-archive is provided by common.
+# In the current version, locale-archive is provided by locale-archive.
+# Due to the change of the packing mode, the locale-archive fails to be
+# replaced during the upgrade. Therefore, a backup file is required to
+# replace the locale-archive.
+mv locale-archive locale-archive.update
+
+$olddir/build-%{target}/elf/ld.so \
+ --library-path $olddir/build-%{target}/ \
+ $olddir/build-%{target}/locale/localedef \
+ --alias-file=$olddir/intl/locale.alias \
+ --prefix $RPM_BUILD_ROOT --add-to-archive \
+ zh_* en_*
+mv locale-archive locale-archive.default
+popd
+mv $RPM_BUILD_ROOT%{_prefix}/lib/locale/libc.lang .
+
+# Install configuration files for services
+install -p -m 644 %{SOURCE2} $RPM_BUILD_ROOT/etc/nsswitch.conf
+
+# This is for compat-2.17
+%if %{with compat_2_17}
+install -p -m 755 build-%{target}/nptl/libpthread-2.17.so $RPM_BUILD_ROOT%{_libdir}
+# Build an empty libpthread_nonshared.a for compatiliby with applications
+# that have old linker scripts that reference this file.
+ar cr %{glibc_sysroot}%{_prefix}/%{_lib}/libpthread_nonshared.a
+
+%endif
+
+# This is for ncsd - in glibc 2.2
+install -m 644 nscd/nscd.conf $RPM_BUILD_ROOT/etc
+mkdir -p $RPM_BUILD_ROOT%{_tmpfilesdir}
+install -m 644 %{SOURCE1} %{buildroot}%{_tmpfilesdir}
+mkdir -p $RPM_BUILD_ROOT/lib/systemd/system
+install -m 644 nscd/nscd.service nscd/nscd.socket $RPM_BUILD_ROOT/lib/systemd/system
+
+# Include ld.so.conf
+echo 'include ld.so.conf.d/*.conf' > $RPM_BUILD_ROOT/etc/ld.so.conf
+truncate -s 0 $RPM_BUILD_ROOT/etc/ld.so.cache
+chmod 644 $RPM_BUILD_ROOT/etc/ld.so.conf
+mkdir -p $RPM_BUILD_ROOT/etc/ld.so.conf.d
+mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
+truncate -s 0 $RPM_BUILD_ROOT/etc/sysconfig/nscd
+truncate -s 0 $RPM_BUILD_ROOT/etc/gai.conf
+
+# Include %{_libdir}/gconv/gconv-modules.cache
+truncate -s 0 $RPM_BUILD_ROOT%{_libdir}/gconv/gconv-modules.cache
+chmod 644 $RPM_BUILD_ROOT%{_libdir}/gconv/gconv-modules.cache
+
+# Remove any zoneinfo files; they are maintained by tzdata.
+rm -rf $RPM_BUILD_ROOT%{_prefix}/share/zoneinfo
+
+touch -r %{SOURCE0} $RPM_BUILD_ROOT/etc/ld.so.conf
+touch -r inet/etc.rpc $RPM_BUILD_ROOT/etc/rpc
+
+# Lastly copy some additional documentation for the packages.
+rm -rf documentation
+mkdir documentation
+cp timezone/README documentation/README.timezone
+cp posix/gai.conf documentation/
+
+%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 $RPM_BUILD_ROOT%{_prefix}/libexec/glibc-benchtests
+cp $(find build-%{target}/benchtests -type f -executable) $RPM_BUILD_ROOT%{_prefix}/libexec/glibc-benchtests/
+
+#makefile.
+for b in %{SOURCE3} %{SOURCE4}; do
+ cp $b $RPM_BUILD_ROOT%{_prefix}/libexec/glibc-benchtests/
+done
+
+#comparison scripts.
+for i in benchout.schema.json compare_bench.py import_bench.py validate_benchout.py; do
+ cp benchtests/scripts/$i $RPM_BUILD_ROOT%{_prefix}/libexec/glibc-benchtests/
+done
+%endif
+
+pushd locale
+ln -s programs/*.gperf .
+popd
+
+pushd iconv
+ln -s ../locale/programs/charmap-kw.gperf .
+popd
+
+%if %{with docs}
+rm -f $RPM_BUILD_ROOT%{_infodir}/dir
+%endif
+
+mkdir -p $RPM_BUILD_ROOT/var/{db,run}/nscd
+touch $RPM_BUILD_ROOT/var/{db,run}/nscd/{passwd,group,hosts,services}
+touch $RPM_BUILD_ROOT/var/run/nscd/{socket,nscd.pid}
+
+mkdir -p $RPM_BUILD_ROOT%{_libdir}
+mv -f $RPM_BUILD_ROOT/%{_lib}/lib{pcprofile,memusage}.so \
+ $RPM_BUILD_ROOT%{_libdir}
+
+# Strip all of the installed object files.
+strip -g $RPM_BUILD_ROOT%{_libdir}/*.o
+
+# create a null libpthread static link for compatibility.
+pushd $RPM_BUILD_ROOT%{_prefix}/%{_lib}/
+rm libpthread.a
+ar rc libpthread.a
+popd
+
+for i in $RPM_BUILD_ROOT%{_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
+
+%if %{ENABLE_RELOC}
+mkdir -p ${RPM_BUILD_ROOT}/usr/lib/relocation/%{_libdir}
+install -p ${RPM_BUILD_DIR}/%{name}-%{version}/build-%{target}/libc.so.6.relocation ${RPM_BUILD_ROOT}/usr/lib/relocation/%{_libdir}
+%endif
+
+touch master.filelist
+touch glibc.filelist
+touch common.filelist
+touch devel.filelist
+touch nscd.filelist
+touch nss_modules.filelist
+touch nss-devel.filelist
+%ifnarch loongarch64
+touch libnsl.filelist
+%endif
+touch debugutils.filelist
+touch benchtests.filelist
+touch help.filelist
+%if %{with compat_2_17}
+touch compat-2.17.filelist
+%endif
+
+{
+ find $RPM_BUILD_ROOT \( -type f -o -type l \) \
+ \( \
+ -name etc -printf "%%%%config " -o \
+ -name gconv-modules \
+ -printf "%%%%verify(not md5 size mtime) %%%%config(noreplace) " -o \
+ -name gconv-modules.cache \
+ -printf "%%%%verify(not md5 size mtime) " \
+ , \
+ ! -path "*/lib/debug/*" -printf "/%%P\n" \)
+
+ find $RPM_BUILD_ROOT -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" \)
+} | {
+ 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' \
+%if %{with compat_2_17}
+ -e '\,.*%{_libdir}/libpthread-2.17.so,d' \
+%endif
+ -e '\,.*/bin/\(memusage\|mtrace\|xtrace\|pcprofiledump\),d'
+} | sort > master.filelist
+
+chmod 0444 master.filelist
+
+##############################################################################
+# glibc - The GNU C Library (glibc) core package.
+##############################################################################
+cat master.filelist \
+ | grep -v \
+ -e '%{_infodir}' \
+ -e '%{_libdir}/lib.*_p.a' \
+ -e '%{_prefix}/include' \
+ -e '%{_libdir}/lib.*\.a' \
+ -e '%{_libdir}/.*\.o' \
+ -e '%{_libdir}/lib.*\.so' \
+ -e 'nscd' \
+ -e '%{_prefix}/bin' \
+ -e '%{_prefix}/lib/locale' \
+ -e '%{_prefix}/sbin/[^i]' \
+ -e '%{_prefix}/share' \
+ -e '/var/db/Makefile' \
+ -e '/libnss_.*\.so[0-9.]*$' \
+%ifnarch loongarch64
+ -e '/libnsl' \
+%endif
+ -e 'glibc-benchtests' \
+ -e 'aux-cache' \
+ > glibc.filelist
+
+for module in compat files dns; do
+ cat master.filelist \
+ | grep -E \
+ -e "/libnss_$module(\.so\.[0-9.]+|-[0-9.]+\.so)$" \
+ >> glibc.filelist
+done
+
+echo '%{_libdir}/libmemusage.so' >> glibc.filelist
+echo '%{_libdir}/libpcprofile.so' >> glibc.filelist
+
+##############################################################################
+# glibc "common" sub-package
+##############################################################################
+grep '%{_prefix}/bin' master.filelist > common.filelist
+grep '%{_prefix}/sbin' master.filelist \
+ | grep -v '%{_prefix}/sbin/iconvconfig' \
+ | grep -v 'nscd' >> common.filelist
+
+grep '%{_prefix}/share' master.filelist \
+ | grep -v \
+ -e '%{_prefix}/share/info/libc.info.*' \
+ -e '%%dir %{prefix}/share/info' \
+ -e '%%dir %{prefix}/share' \
+ >> common.filelist
+
+###############################################################################
+# glibc "devel" sub-package
+###############################################################################
+%if %{with docs}
+grep '%{_infodir}' master.filelist | grep -v '%{_infodir}/dir' > help.filelist
+%endif
+
+grep '%{_libdir}/lib.*\.a' master.filelist \
+ | grep '/lib\(\(c\|pthread\|nldbl\|mvec\)_nonshared\|g\|ieee\|mcheck\)\.a$' \
+ >> devel.filelist
+
+grep '%{_libdir}/.*\.o' < master.filelist >> devel.filelist
+grep '%{_libdir}/lib.*\.so' < master.filelist >> devel.filelist
+
+sed -i -e '\,/libnss_[a-z]*\.so$,d' devel.filelist
+
+grep '%{_prefix}/include' < master.filelist >> devel.filelist
+
+grep '%{_libdir}/lib.*\.a' < master.filelist \
+ | grep -v '/lib\(\(c\|pthread\|nldbl\|mvec\)_nonshared\|g\|ieee\|mcheck\)\.a$' \
+ >> devel.filelist
+
+sed -i '/.relocation/d' devel.filelist
+
+##############################################################################
+# glibc "nscd" sub-package
+##############################################################################
+echo '%{_prefix}/sbin/nscd' > nscd.filelist
+
+##############################################################################
+# nss modules sub-package
+##############################################################################
+grep -E "%{_lib}/libnss_(db|hesiod)(\.so\.[0-9.]+|-[0-9.]+\.so)$" \
+master.filelist > nss_modules.filelist
+
+##############################################################################
+# nss-devel sub-package
+##############################################################################
+grep '/libnss_[a-z]*\.so$' master.filelist > nss-devel.filelist
+
+##############################################################################
+# libnsl subpackage
+##############################################################################
+%ifnarch loongarch64
+grep -E '%{_lib}/libnsl\.so\.[0-9]+$' master.filelist > libnsl.filelist
+test $(wc -l < libnsl.filelist) -eq 1
+%endif
+
+##############################################################################
+# glibc debugutils sub-package
+##############################################################################
+cat > debugutils.filelist <<EOF
+%if %{without bootstrap}
+%{_prefix}/bin/memusage
+%{_prefix}/bin/memusagestat
+%endif
+%{_prefix}/bin/mtrace
+%{_prefix}/bin/pcprofiledump
+%{_prefix}/bin/xtrace
+EOF
+
+%if %{with benchtests}
+##############################################################################
+# glibc benchtests sub-package
+##############################################################################
+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 %{SOURCE3} %{SOURCE4}; 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
+
+%if %{with compat_2_17}
+##############################################################################
+# glibc compat-2.17 sub-package
+##############################################################################
+ echo "%{_libdir}/libpthread-2.17.so" >> compat-2.17.filelist
+ echo "%{_libdir}/libpthread_nonshared.a" >> compat-2.17.filelist
+%endif
+
+reliantlib=""
+
+function findReliantLib()
+{
+ local library=$1
+ reliantlib=$(readelf -d $library | grep "(NEEDED)" | awk -F "Shared library" '{print $2}')$reliantlib
+}
+
+# remove gconv rpath/runpath
+function removeLoadPath()
+{
+ local file=$1
+ local rpathInfo=$(chrpath -l $file | grep "RPATH=")
+ local runpathInfo=$(chrpath -l $file | grep "RUNPATH=")
+
+ local currPath=""
+ if [ x"$rpathInfo" != x"" ]; then
+ currPath=$(echo $rpathInfo | awk -F "RPATH=" '{print $2}')
+ fi
+
+ if [ x"$runpathInfo" != x"" ]; then
+ currPath=$(echo $runpathInfo | awk -F "RUNPATH=" '{print $2}')
+ fi
+
+ if [ x"$currPath" == x"\$ORIGIN" ]; then
+ chrpath -d $file
+
+ findReliantLib $file
+ fi
+}
+
+set +e
+
+# find and remove RPATH/RUNPATH
+for file in $(find $RPM_BUILD_ROOT%{_libdir}/gconv/ -name "*.so" -exec file {} ';' | grep "\<ELF\>" | awk -F ':' '{print $1}')
+do
+ removeLoadPath $file
+done
+
+function createSoftLink()
+{
+ # pick up the dynamic libraries and create softlink for them
+ local tmplib=$(echo $reliantlib | sed 's/://g' | sed 's/ //g' | sed 's/\[//g' | sed 's/]/\n/g' | sort | uniq)
+
+ for temp in $tmplib
+ do
+ if [ -f "$RPM_BUILD_ROOT%{_libdir}/gconv/$temp" ]; then
+ ln -sf %{_libdir}/gconv/$temp $RPM_BUILD_ROOT%{_libdir}/$temp
+ echo %{_libdir}/$temp >> glibc.filelist
+ fi
+ done
+}
+
+# create soft link for the reliant libraries
+createSoftLink
+set -e
+
+##############################################################################
+# Run the glibc testsuite
+##############################################################################
+%check
+%if %{with testsuite}
+
+omit_testsuite() {
+ while read testsuite; do
+ testsuite_escape=$(echo "$testsuite" | \
+ sed 's/\([.+?^$\/\\|()\[]\|\]\)/\\\0/g')
+ sed -i "/${testsuite_escape}/d" rpmbuild.tests.sum.not-passing
+ done
+}
+
+# Increase timeouts
+export TIMEOUTFACTOR=16
+parent=$$
+echo ====================TESTING=========================
+
+# Default libraries.
+pushd build-%{target}
+make %{?_smp_mflags} -O check |& tee rpmbuild.check.log >&2
+test -s tests.sum
+
+# 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.
+if ! grep -q '^Summary of test results:$' rpmbuild.check.log ; then
+ echo "FAIL: test suite build of target: $(basename "$(pwd)")" >& 2
+ exit 1
+fi
+grep -v ^PASS: tests.sum | grep -v ^UNSUPPORTED > rpmbuild.tests.sum.not-passing || true
+
+# Delete the testsuite from the whitelist
+cat %{SOURCE8} | \
+ grep -v "^$\|^#" | \
+ awk -F':' '{if($2 == "" || $2 ~ /'%{_target_cpu}'/ ) {print $1}}' |\
+ omit_testsuite
+
+set +x
+if test -s 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 <rpmbuild.tests.sum.not-passing
+%if 0%{?glibc_abort_after_test_fail}
+ #exit 1
+%endif
+fi
+
+# Unconditonally dump differences in the system call list.
+echo "* System call consistency checks:" >&2
+cat misc/tst-syscall-list.out >&2
+set -x
+popd
+
+echo ====================TESTING END=====================
+PLTCMD='/^Relocation section .*\(\.rela\?\.plt\|\.rela\.IA_64\.pltoff\)/,/^$/p'
+echo ====================PLT RELOCS LD.SO================
+readelf -Wr $RPM_BUILD_ROOT/%{_lib}/ld-*.so | sed -n -e "$PLTCMD"
+echo ====================PLT RELOCS LIBC.SO==============
+readelf -Wr $RPM_BUILD_ROOT/%{_lib}/libc-*.so | sed -n -e "$PLTCMD"
+echo ====================PLT RELOCS END==================
+
+pushd build-%{target}
+LD_SHOW_AUXV=1 elf/ld.so --library-path .:elf:nptl:dlfcn /bin/true
+
+%if %{with valgrind}
+elf/ld.so --library-path .:elf:nptl:dlfcn \
+ /usr/bin/valgrind --error-exitcode=1 \
+ elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/true
+%endif
+popd
+
+%endif # %{run_glibc_tests}
+
+##############################################################################
+# Install and uninstall scripts
+##############################################################################
+%pre -p <lua>
+-- Check that the running kernel is new enough
+required = '%{enablekernel}'
+rel = posix.uname("%r")
+if rpm.vercmp(rel, required) < 0 then
+ error("FATAL: kernel too old", 0)
+end
+
+%post -p <lua>
+-- We use lua's posix.exec because there may be no shell that we can
+-- run during glibc upgrade.
+function post_exec (program, ...)
+ local pid = posix.fork ()
+ if pid == 0 then
+ assert (posix.exec (program, ...))
+ elseif pid > 0 then
+ posix.wait (pid)
+ end
+end
+
+-- (1) Remove multilib libraries from previous installs.
+-- In order to support in-place upgrades, we must immediately remove
+-- obsolete platform directories after installing a new glibc
+-- version. RPM only deletes files removed by updates near the end
+-- of the transaction. If we did not remove the obsolete platform
+-- directories here, they may be preferred by the dynamic linker
+-- during the execution of subsequent RPM scriptlets, likely
+-- resulting in process startup failures.
+
+-- Full set of libraries glibc may install.
+install_libs = { "anl", "BrokenLocale", "c", "dl", "m", "mvec",
+ "nss_compat", "nss_db", "nss_dns", "nss_files",
+ "nss_hesiod", "pthread", "resolv", "rt", "SegFault",
+ "thread_db", "util" }
+
+-- We are going to remove these libraries. Generally speaking we remove
+-- all core libraries in the multilib directory.
+-- We employ a tight match where X.Y is in [2.0,9.9*], so we would
+-- match "libc-2.0.so" and so on up to "libc-9.9*".
+remove_regexps = {}
+for i = 1, #install_libs do
+ remove_regexps[i] = ("lib" .. install_libs[i]
+ .. "%%-[2-9]%%.[0-9]+%%.so$")
+end
+
+-- Two exceptions:
+remove_regexps[#install_libs + 1] = "libthread_db%%-1%%.0%%.so"
+remove_regexps[#install_libs + 2] = "libSegFault%%.so"
+
+-- We are going to search these directories.
+local remove_dirs = { "%{_libdir}/i686",
+ "%{_libdir}/i686/nosegneg" }
+
+-- Walk all the directories with files we need to remove...
+for _, rdir in ipairs (remove_dirs) do
+ if posix.access (rdir) then
+ -- If the directory exists we look at all the files...
+ local remove_files = posix.files (rdir)
+ for rfile in remove_files do
+ for _, rregexp in ipairs (remove_regexps) do
+ -- Does it match the regexp?
+ local dso = string.match (rfile, rregexp)
+ if (dso ~= nil) then
+ -- Removing file...
+ os.remove (rdir .. '/' .. rfile)
+ end
+ end
+ end
+ end
+end
+
+-- (2) Update /etc/ld.so.conf
+-- Next we update /etc/ld.so.conf to ensure that it starts with
+-- a literal "include ld.so.conf.d/*.conf".
+
+local ldsoconf = "/etc/ld.so.conf"
+local ldsoconf_tmp = "/etc/glibc_post_upgrade.ld.so.conf"
+
+if posix.access (ldsoconf) then
+
+ -- We must have a "include ld.so.conf.d/*.conf" line.
+ local have_include = false
+ for line in io.lines (ldsoconf) do
+ -- This must match, and we don't ignore whitespace.
+ if string.match (line, "^include ld.so.conf.d/%%*%%.conf$") ~= nil then
+ have_include = true
+ end
+ end
+
+ if not have_include then
+ -- Insert "include ld.so.conf.d/*.conf" line at the start of the
+ -- file. We only support one of these post upgrades running at
+ -- a time (temporary file name is fixed).
+ local tmp_fd = io.open (ldsoconf_tmp, "w")
+ if tmp_fd ~= nil then
+ tmp_fd:write ("include ld.so.conf.d/*.conf\n")
+ for line in io.lines (ldsoconf) do
+ tmp_fd:write (line .. "\n")
+ end
+ tmp_fd:close ()
+ local res = os.rename (ldsoconf_tmp, ldsoconf)
+ if res == nil then
+ io.stdout:write ("Error: Unable to update configuration file (rename).\n")
+ end
+ else
+ io.stdout:write ("Error: Unable to update configuration file (open).\n")
+ end
+ end
+end
+
+-- (3) Rebuild ld.so.cache early.
+-- If the format of the cache changes then we need to rebuild
+-- the cache early to avoid any problems running binaries with
+-- the new glibc.
+
+-- Note: We use _prefix because Fedora's UsrMove says so.
+post_exec ("%{_prefix}/sbin/ldconfig")
+
+-- (4) Update gconv modules cache.
+-- If the /usr/lib/gconv/gconv-modules.cache exists, then update it
+-- with the latest set of modules that were just installed.
+-- We assume that the cache is in _libdir/gconv and called
+-- "gconv-modules.cache".
+local iconv_dir = "%{_libdir}/gconv"
+local iconv_cache = iconv_dir .. "/gconv-modules.cache"
+if (posix.utime (iconv_cache) == 0) then
+ post_exec ("%{_prefix}/sbin/iconvconfig",
+ "-o", iconv_cache,
+ "--nostdlib",
+ iconv_dir)
+else
+ io.stdout:write ("Error: Missing " .. iconv_cache .. " file.\n")
+end
+
+%postun -p <lua> common
+archive_path = "%{_prefix}/lib/locale/locale-archive"
+os.remove (archive_path)
+
+%posttrans -p <lua> common
+archive_path = "%{_prefix}/lib/locale/locale-archive"
+default_path = "%{_prefix}/lib/locale/locale-archive.default"
+os.remove (archive_path)
+posix.link(default_path, archive_path)
+
+%postun -p <lua> locale-archive
+archive_path = "%{_prefix}/lib/locale/locale-archive"
+default_path = "%{_prefix}/lib/locale/locale-archive.default"
+os.remove (archive_path)
+posix.link(default_path, archive_path)
+
+%posttrans -p <lua> locale-archive
+archive_path = "%{_prefix}/lib/locale/locale-archive"
+update_path = "%{_prefix}/lib/locale/locale-archive.update"
+os.remove (archive_path)
+posix.link(update_path, archive_path)
+
+%pre devel
+# this used to be a link and it is causing nightmares now
+if [ -L %{_prefix}/include/scsi ] ; then
+ rm -f %{_prefix}/include/scsi
+fi
+
+%if %{with docs}
+%post help
+/sbin/install-info %{_infodir}/libc.info.gz %{_infodir}/dir > /dev/null 2>&1 || :
+
+%preun help
+if [ "$1" = 0 ]; then
+ /sbin/install-info --delete %{_infodir}/libc.info.gz %{_infodir}/dir > /dev/null 2>&1 || :
+fi
+%endif
+
+%pre -n nscd
+getent group nscd >/dev/null || /usr/sbin/groupadd -g 28 -r nscd
+getent passwd nscd >/dev/null ||
+ /usr/sbin/useradd -M -o -r -d / -s /sbin/nologin \
+ -c "NSCD Daemon" -u 28 -g nscd nscd
+
+%post -n nscd
+%systemd_post nscd.service
+
+%preun -n nscd
+%systemd_preun nscd.service
+
+%postun -n nscd
+if test $1 = 0; then
+ /usr/sbin/userdel nscd > /dev/null 2>&1 || :
+fi
+%systemd_postun_with_restart nscd.service
+
+##############################################################################
+# Files list
+##############################################################################
+%files -f glibc.filelist
+%dir %{_prefix}/%{_lib}/audit
+%verify(not md5 size mtime) %config(noreplace) /etc/nsswitch.conf
+%verify(not md5 size mtime) %config(noreplace) /etc/ld.so.conf
+%verify(not md5 size mtime) %config(noreplace) /etc/rpc
+%dir /etc/ld.so.conf.d
+%dir %{_prefix}/libexec/getconf
+%dir %{_libdir}/gconv
+%dir %attr(0700,root,root) /var/cache/ldconfig
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/cache/ldconfig/aux-cache
+%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/ld.so.cache
+%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/gai.conf
+%{!?_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/*
+%attr(0644,root,root) %config(noreplace) %{_prefix}/lib/locale/locale-archive.default
+
+%files -f libc.lang all-langpacks
+%{_prefix}/lib/locale
+%exclude %{_prefix}/lib/locale/locale-archive
+%exclude %{_prefix}/lib/locale/locale-archive.update
+%exclude %{_prefix}/lib/locale/locale-archive.default
+%exclude %{_prefix}/lib/locale/C.utf8
+
+%files locale-source
+%dir %{_prefix}/share/i18n/locales
+%{_prefix}/share/i18n/locales/*
+%dir %{_prefix}/share/i18n/charmaps
+%{_prefix}/share/i18n/charmaps/*
+
+%files locale-archive
+%attr(0644,root,root) %{_prefix}/lib/locale/locale-archive.update
+
+%files -f devel.filelist devel
+
+%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
+
+%if %{ENABLE_RELOC}
+%files relocation
+%dir %attr(500, root, root) /usr/lib/relocation
+%dir %attr(500, root, root) /usr/lib/relocation/%{_libdir}
+%attr(400, root, root) /usr/lib/relocation/%{_libdir}/libc.so.6.relocation
+%endif
+
+%files -f nss_modules.filelist -n nss_modules
+/var/db/Makefile
+
+%files -f nss-devel.filelist nss-devel
+
+%ifnarch loongarch64
+%files -f libnsl.filelist -n libnsl
+%endif
+
+%files -f debugutils.filelist debugutils
+
+%if %{with benchtests}
+%files -f benchtests.filelist benchtests
+%endif
+
+%files -f help.filelist help
+#Doc of glibc package
+%doc README NEWS INSTALL elf/rtld-debugger-interface.txt
+#Doc of common sub-package
+%doc documentation/README.timezone
+%doc documentation/gai.conf
+#Doc of nss_modules sub-package
+%doc hesiod/README.hesiod
+
+%if %{with compat_2_17}
+%files -f compat-2.17.filelist compat-2.17
+%endif
+
+%changelog
+* Fri Sep 20 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-39
+- clean code, remove some oe patches which already fixed in upstream
+
+* Mon Sep 9 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-38
+- nptl: Use <support/check.h> facilities in tst-setuid3
+- posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64
+- ungetc: Fix backup buffer leak on program exit [BZ #27821]
+- ungetc: Fix uninitialized read when putting into unused streams [BZ #27821]
+- Make tst-ungetc use libsupport
+- stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650]
+- support: Add FAIL test failure helper
+
+* Wed Sep 4 2024 Zhaoshuang <zhaoshuang@uniontech.com> - 2.38-37
+- Fix issue that loading a missing locale twice [BZ #14247]
+
+* Tue Aug 27 2024 YunQiang Su <yunqiang@isrc.iscas.ac.cn> - 2.38-36
+- Fix libnsl.so and libnss_.so filelist process (PR 877)
+
+* Thu Aug 22 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-35
+- x86: Fix bug in strchrnul-evex512 [BZ #32078]
+
+* Fri Aug 9 2024 taoyuxiang <taoyuxiang2@huawei.com> - 2.38-34
+- Specify the GFDL version to GFDL-1.3-ONLY in spec
+
+* Thu Aug 8 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-33
+- Fix name space violation in fortify wrappers (bug 32052)
+
+* Fri Aug 2 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-32
+- resolv: Fix tst-resolv-short-response for older GCC (bug 32042)
+- Update syscall lists for Linux 6.5
+- Add mremap tests
+- mremap: Update manual entry
+- linux: Update the mremap C implementation [BZ #31968]
+- resolv: Track single-request fallback via _res._flags (bug 31476)
+- resolv: Do not wait for non-existing second DNS response after error (bug 30081)
+- resolv: Allow short error responses to match any query (bug 31890)
+- Linux: Make __rseq_size useful for feature detection (bug 31965)
+- elf: Make dl-rseq-symbols Linux only
+- nptl: fix potential merge of __rseq_* relro symbols
+- s390x: Fix segfault in wcsncmp [BZ #31934]
+
+* Thu Jul 4 2024 lipengyu <lipengyu@kylinos.cn> - 2.38-31
+- fix bug "info command cannot index the glibc help documentation"
+- add the install-info libc.info.gz step during the glibc-help installation process
+
+* Wed Jun 5 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-30
+- misc: Add support for Linux uio.h RWF_NOAPPEND flag
+- Disable Intel Xeon Phi tests for GCC 15 and above (BZ 31782)
+
+* Mon May 13 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-29
+- Force DT_RPATH for --enable-hardcoded-path-in-tests
+
+* Fri May 10 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-28
+- backport glibc upstream 2.38 branch, here is the 26 patches:
+- resolv: Fix some unaligned accesses in resolver [BZ #30750]
+- nscd: Use time_t for return type of addgetnetgrentX
+- elf: Also compile dl-misc.os with $(rtld-early-cflags)
+- CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX (bug 31680)
+- CVE-2024-33600: nscd: Avoid null pointer crashes after notfound response (bug 31678)
+- CVE-2024-33600: nscd: Do not send missing not-found response in addgetnetgrentX (bug 31678)
+- CVE-2024-33599: nscd: Stack-based buffer overflow in netgroup cache (bug 31677)
+- i386: ulp update for SSE2 --disable-multi-arch configurations
+- nptl: Fix tst-cancel30 on kernels without ppoll_time64 support
+- login: structs utmp, utmpx, lastlog _TIME_BITS independence (bug 30701)
+- login: Check default sizes of structs utmp, utmpx, lastlog
+- sparc: Remove 64 bit check on sparc32 wordsize (BZ 27574)
+- iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961)
+- powerpc: Fix ld.so address determination for PCREL mode (bug 31640)
+- AArch64: Check kernel version for SVE ifuncs
+- aarch64: fix check for SVE support in assembler
+- aarch64: correct CFI in rawmemchr (bug 31113)
+- AArch64: Remove Falkor memcpy
+- AArch64: Add memset_zva64
+- AArch64: Cleanup emag memset
+- AArch64: Cleanup ifuncs
+- AArch64: Add support for MOPS memcpy/memmove/memset
+- Add HWCAP2_MOPS from Linux 6.5 to AArch64 bits/hwcap.h
+- LoongArch: Correct {__ieee754, _}_scalb -> {__ieee754, _}_scalbf
+- linux: Use rseq area unconditionally in sched_getcpu (bug 31479)
+- S390: Do not clobber r7 in clone [BZ #31402]
+
+* Mon Apr 29 2024 chengyechun <chengyechun1@huawei.com> - 2.38-27
+- Type:CVE
+- ID:CVE-2024-33599 CVE-2024-33600 CVE-2024-33601 CVE-2024-33602
+- SUG:NA
+- DESC:fix CVE-2024-33599 CVE-2024-33600 CVE-2024-33601 CVE-2024-33602
+
+* Tue Apr 23 2024 Yang Yanchao <yangyanchao6@huawei.com> - 2.38-26
+- iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961)
+
+* Thu Apr 18 2024 zhangnaichuan <zhangnaichuan@huawei.com> - 2.38-25
+- add Wl,-z,noseparate-code for so
+
+* Tue Apr 9 2024 yangpan <yangpan51@huawei.com> - 2.38-24
+- disable sysboost
+
+* Thu Feb 29 2024 Peng Fan <fanpeng@loongson.cn> - 2.38-23
+- LoongArch: sync patch from glibc upstream
+- Reduced kernel version requirements
+
+* Fri Feb 23 Jingxiao Lu <lujingxiao@huawei.com> - 2.38-22
+- malloc: Use __get_nprocs on arena_get2 (BZ 30945)
+
+* Tue Feb 6 Qingqing Li <liqingqing3@huawei.com> - 2.38-21
+- arm: Remove wrong ldr from _dl_start_user (BZ 31339)
+
+* Mon Feb 5 Qingqing Li <liqingqing3@huawei.com> - 2.38-20
+- x86_64: Optimize ffsll function code size
+- S390: Fix building with disable mutli arch (BZ 31196)
+- sparc: Fix broken memset for sparc32 (BZ 31068)
+- sparc: Remove unwind information from signal return
+- sparc: Fix sparc64 memmove length comparison (BZ 31266)
+- sparc: Remove unwind information from signal return stubs (BZ 31244)
+
+* Thu Feb 1 Hewenliang <hewenliang4@huawei.com> - 2.38-19
+- backport:fix CVE-2023-6779 CVE-2023-6780
+
+* Wed Jan 31 Qingqing Li <liqingqing3@huawei.com> - 2.38-18
+- backport:fix CVE-2023-6246.
+
+* Sat Jan 13 Qingqing Li <liqingqing3@huawei.com> - 2.38-17
+- elf: Add a way to check if tunable is set (BZ 27069)
+- malloc: Improve MAPE_HUGETLB with glibc.malloc.hugetlb=2
+
+* Wed Jan 3 Qingqing Li <liqingqing3@huawei.com> - 2.38-16
+- backport patches from glibc upstream 2.38 branch
+
+* Thu Dec 14 shixuantong <shixuantong1@huawei.com> - 2.38-15
+- elf: Handle non-directory name in search path (BZ 31035)
+
+* Fri Dec 8 2023 Qingqing Li <liqingqing3@huawei.com> - 2.38-14
+- elf: Fix wrong break removal from 8ee878592c
+
+* Thu Dec 7 2023 Qingqing Li <liqingqing3@huawei.com> - 2.38-13
+- sysdeps: sem_open: Clear O_CREAT when semaphore file is
+ expected to exist [BZ #30789]
+
+* Tue Oct 24 2023 Qingqing Li <liqingqing3@huawei.com> - 2.38-12
+- weekly backport patches from glibc upstream 2.38 branch
+
+* Sat Oct 7 2023 Qingqing Li <liqingqing3@huawei.com> - 2.38-11
+- backport patches from glibc upstream 2.38 branch
+
+* Sat Sep 16 2023 Qingqing Li <liqingqing3@huawei.com> - 2.38-10
+- backport patches from glibc upstream 2.38 branch
+- revert some customization modification
+
+* Fri Sep 15 2023 Qingqing Li <liqingqing3@huawei.com> - 2.38-9
+- fix CVE-2023-4527
+
+* Mon Sep 11 2023 Qingqing Li <liqingqing3@huawei.com> - 2.38-8
+- backport patches from glibc upstream 2.38 branch
+
+* Mon Sep 11 2023 Qingqing Li <liqingqing3@huawei.com> - 2.38-7
+- backport patches from glibc upstream 2.38 branch
+
+* Mon Sep 11 2023 Qingqing Li <liqingqing3@huawei.com> - 2.38-6
+- stdlib: Improve tst-realpath compatibility with source fortification
+
+* Mon Aug 21 2023 longwei<longwei27@huawei.com> - 2.38-5
+- add libc.so relocation file for sysboost
+
+* Wed Aug 16 2023 chenhaixiang<chenhaixiang3@huawei.com> - 2.38-4
+- skipping test case building to fix glibc build error on x86
+
+* Mon Aug 7 2023 zhanghao<zhanghao383@huawei.com> - 2.38-3
+- fix Segmentation fault in nss module
+- fix nss database check reload and get memleak
+
+* Wed Aug 2 2023 chenhaixiang<chenhaixiang3@huawei.com> - 2.38-2
+- use the released glibc 2.38 version
+
+* Tue Jul 25 2023 chenhaixiang<chenhaixiang3@huawei.com> - 2.38-1
+- Pre Update to glibc-2.38
+
+* Tue Jul 11 2023 jiangyingxin<jiangyingxin1@huawei.com> - 2.36-18
+- Optimizing __random for single-threaded scenarios
+
+* Tue Jul 11 2023 lijianglin<lijianglin2@huawei.com> - 2.36-17
+- add the test of the entire GB18030 charmap
+
+* Mon Jun 5 2023 li-miaomiao_zhr <mmlidc@isoftstone.com> - 2.36-16
+- processing of annotated patch files in spec files
+
+* Wed May 10 2023 lijianglin<lijianglin2@huawei.com> - 2.36-15
+- add GB18030-2022 charmap
+
+* Mon May 08 2023 laokz <zhangkai@iscas.ac.cn> - 2.36-14
+- Backport RISC-V patches:
+ - stdlib/strfrom: Add copysign to fix NAN issue (from v2.37)
+ - Assume only FLAG_ELF_LIBC6 suport (from v2.37)
+ - Restore libc6 implicit soname logic (from v2.38)
+
+* Thu Feb 23 2023 Qingqing Li <liqingqing3@huawei.com> - 2.36-13
+- gmon: Fix allocated buffer overflow (bug 29444)
+
+* Wed Feb 1 2023 Yang Yanchao <yangyanchao6@huawei.com> - 2.36-12
+- Since the pthread_cond_clockwait@GLIBC_2_28 is introduced in earlier
+ versions, this symbol is required to keep the previous items compatible.
+
+* Thu Jan 12 2023 Qingqing Li <liqingqing3@huawei.com> - 2.36-11
+- Makerules: fix MAKEFLAGS assignment for upcoming make-4.4
+
+* Sat Sep 24 2022 Xu Wu<wuxu.wu@huawei.com> - 2.36-10
+- syslog: Fix large messages (BZ#29536)
+
+* Fri Sep 23 2022 Xu Wu<wuxu.wu@huawei.com> - 2.36-9
+- gconv: Use 64-bit interfaces in gconv_parseconfdir (bug 29583)
+
+* Tue Sep 20 2022 SuperHugePan <zhangpan26@huawei.com> - 2.36-8
+- linux: Do not skip d_ino==0 entries in readdir, readdir64(bug 12165)
+
+* Thu Sep 8 2022 Qingqing Li <liqingqing3@huawei.com> - 2.36-7
+- add requires between glibc-info and glibc
+
+* Thu Sep 1 2022 Qingqing Li <liqingqing3@huawei.com> - 2.36-6
+- syslog:Fix large messages (BZ#29536/CVE-2022-39046)
+
+* Tue Aug 16 2022 Qingqing Li <liqingqing3@huawei.com> - 2.36-5
+- linux: Fix enum fsconfig_command detection in <sys/mount.h>
+
+* Mon Aug 15 2022 Qingqing Li <liqingqing3@huawei.com> - 2.36-4
+- linux: Fix sys/mount.h usage with kernel headers
+
+* Mon Aug 15 2022 Qingqing Li <liqingqing3@huawei.com> - 2.36-3
+- refactoring testsuite whitelist
+
+* Wed Aug 10 2022 Qingqing Li <liqingqing3@huawei.com> - 2.36-2
+- aarch64: strcmp delete align for better unixbench performance
+
+* Tue Aug 2 2022 Qingqing Li <liqingqing3@huawei.com> - 2.36-1
+- upgrade to 2.36
+
+* Thu Jul 28 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-16
+- optimize Obsoletes version
+
+* Thu Jul 7 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-15
+- enable -werror by default
+
+* Tue Jul 5 2022 Yang Yanchao <yangyanchao6@huawei.com> - 2.35-14
+- add libpthread_nonshared.a in glibc-compat-2.17 for old applications
+
+* Tue Jun 28 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-13
+- aarch64: add -mno-outline-atomics to prevent mallocT2_xx performance regression
+
+* Mon Jun 27 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-12
+- x86: use total l3cache size for non_temporal_threshold
+
+* Tue Jun 14 2022 Yang Yanchao <yangyanchao6@huawei.com> - 2.35-11
+- Use Lua to compile the installation scripts of glibc-common and glibc-locale-archive.
+
+* Wed Jun 1 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-10
+- use locale-archive to prevent basic command performance regression
+
+* Thu May 12 2022 jiangheng <jiangheng14@huawei.com> - 2.35-9
+- restore nscd
+
+* Wed Mar 30 2022 Yang Yanchao <yangyanchao@huawei.com> - 2.35-8
+- delete the BuildRequires:gcc_secure.
+
+* Tue Mar 29 2022 Yang Yanchao <yangyanchao@huawei.com> - 2.35-7
+- mv libc.info.gz* to the package glibc-help
+
+* Sat Mar 12 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-6
+- malloc: use __get_nprocs replace __get_nprocs_sched.
+
+* Wed Mar 2 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-5
+- add chrpath to build requires for removing RPATH/RUNPATH
+
+* Tue Mar 1 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-4
+- remove shared library's RPATH/RUNPATH for security
+
+* Tue Feb 22 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-3
+- tzselect: use region to select timezone
+
+* Thu Feb 10 2022 jiangheng12 <jiangheng12@huawei.com> - 2.35-2
+- remove nscd; The functionality nscd currently provides can be
+ achieved by using systemd-resolved for DNS caching and the sssd
+ daemon for everything else
+
+* Tue Feb 8 2022 Qingqing Li <liqingqing3@huawei.com> - 2.35-1
+- upgrade to 2.35
+
+* Fri Jan 28 2022 Yang Yanchao <yangyanchao6@huawei.com> - 2.34-39
+- refactor the generation mode of the debug package and
+ add correct files to the glibc-debugsource sync form 22.03-LTS
+
+* Tue Jan 4 2022 Yang Yanchao <yangyanchao6@huawei.com> - 2.34-38
+- testsuit: delete check-installed-headers-c and check-installed-headers-cxx
+ which are checked in CI to improves the compilation speed.
+- testsuit: delete glibc-benchtest
+
+* Sat Dec 25 2021 liusirui <liusirui@huawei.com> - 2.34-37
+- ld.so: Don't fill the DT_DEBUG entry in ld.so [BZ #28129]
+
+* Fri Dec 24 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-36
+- do not define tgmath.h fmaxmag, fminmag macros for C2X (BZ #28397)
+
+* Fri Dec 24 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-35
+- io: Fix ftw internal realloc buffer (BZ #28126)
+
+* Tue Dec 21 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-34
+- tst: fix failing nss/tst-nss-files-hosts-long with local resolver
+ use support_open_dev_null_range io/tst-closefrom, mise/tst-close_range, and posix/tst-spawn5(BZ#28260)
+ nptl: add one more barrier to nptl/tst-create1
+
+* Wed Dec 15 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-33
+- pthread/tst-cancel28: Fix barrier re-init race condition
+
+* Thu Dec 9 2021 Yang Yanchao <yangyanchao6@huawei.com> - 2.34-32
+- Deleted some unnecessary command when make master.filelist
+
+* Thu Dec 9 2021 Yang Yanchao <yangyanchao6@huawei.com> - 2.34-31
+- support all Chinese and English by default
+ add zh_* and en_* to glibc-common
+ the size of glibc-common is increased from 1.8MB to 3.5MB
+
+* Fri Dec 3 2021 Yang Yanchao <yangyanchao6@huawei.com> - 2.34-30
+- turn the default value of x86_rep_stosb_threshold from 2k to 1M
+
+* Thu Dec 2 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-29
+- revert the use of sched_getaffinity [BZ #28310]
+
+* Tue Nov 30 2021 Bin Wang <wangbin224@huawei.com> - 2.34-28
+- Linux: Simplify __opensock and fix race condition [BZ #28353]
+
+* Wed Nov 24 2021 Yang Yanchao <yangyanchao6@huawei.com> - 2.34-27
+- Refactor the libpthread-2.17.so code and pass all test cases.
+ delete libpthread-2.17.so from glibc-devel
+
+* Fri Nov 19 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-26
+- revert supress -Wcast-qual warnings in bsearch
+
+* Mon Nov 15 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-25
+- fix attribute access mode on getcwd [BZ #27476]
+- supress -Wcast-qual warnings in bsearch
+
+* Mon Nov 15 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-24
+- elf: fix ld.so crash while loading a DSO with a read-only dynamic section
+ https://sourceware.org/bugzilla/show_bug.cgi?id=28340
+
+* Wed Nov 10 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-23
+- gconv: Do not emit spurious NUL character in ISO-2022-JP-3,
+ this also fix CVE-2021-43396.
+ uplink: https://sourceware.org/bugzilla/show_bug.cgi?id=28524
+
+* Tue Nov 9 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-22
+- iconvconfig: Fix behaviour with --prefix
+ uplink: https://sourceware.org/bugzilla/show_bug.cgi?id=28199
+
+* Mon Nov 8 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-21
+- nptl: pthread_kill race condition issues fixed.
+ uplink: https://sourceware.org/bugzilla/show_bug.cgi?id=19193
+ https://sourceware.org/bugzilla/show_bug.cgi?id=12889
+ https://sourceware.org/bugzilla/show_bug.cgi?id=28036
+ https://sourceware.org/bugzilla/show_bug.cgi?id=28363
+ https://sourceware.org/bugzilla/show_bug.cgi?id=28407
+
+* Thu Nov 4 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-20
+- nptl: pthread_kill and pthread_cancel return success
+ for satisfy posix standard.
+ uplink: https://sourceware.org/bugzilla/show_bug.cgi?id=19193
+
+* Fri Oct 29 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-19
+- aarch64: update a64fx memset not to degrade at 16KB
+
+* Thu Oct 28 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-18
+- use testl instead of andl to check __x86_string_control to
+ avoid updating __x86_string_control
+
+* Tue Oct 26 2021 Yang Yanchao<yangyanchao6@huawei.com> - 2.34-17
+- Show more debugging information during testsuite
+
+* Tue Oct 26 2021 Chuangchuang Fang<fangchuangchuang@huawei.com> - 2.34-16
+- Use __executable_start as the lowest address for profiling
+
+* Tue Oct 26 2021 Yang Yanchao<yangyanchao6@huawei.com> - 2.34-15
+- add glibc-compat-2.17 subpackage to provide the function of
+ the glibc-2.17 pthread library.
+ Currently, provide pthread_condition function.
+
+* Mon Oct 25 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-14
+- mtrace fix output with PIE and ASLR.
+- elf: rtld copy terminating null in tunables strdup.
+
+* Mon Oct 25 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-13
+- fpu: x86-64 optimize load of all bits set into ZMM register.
+
+* Tue Oct 19 2021 Yang Yanchao <yangyanchao6@huawei.com> - 2.34-12
+- Add locale-archive sub packages to support more languages
+ and reduce memory usage.
+
+* Tue Oct 12 2021 Yang Yanchao<yangyanchao6@huawei.com> - 2.34-11
+- Add the testsuite whitelist.
+ If a test case out of the trustlist fails, the compilation is interrupted.
+
+* Mon Oct 11 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-10
+- update test memmove.c to cover 16KB.
+
+* Wed Sep 29 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-9
+- elf: drop elf/tls-macros.h in favor of thread tls_mode attribute.
+- use __ehdr_start for __GLOBAL_OFFSET_TABLE[0]
+
+* Wed Sep 29 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-8
+- fix overflow ittimer tests on 32 bit system
+
+* Mon Sep 27 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-7
+- mtrace: use a static buffer for printing, fix memory leak.
+ upstream link: https://sourceware.org/bugzilla/show_bug.cgi?id=25947
+
+* Sun Sep 26 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-6
+- elf: Unconditionally use __ehdr_start.
+- aarch64: Make elf_machine_{load_addr,dynamic} robust [BZ #28203].
+ upstream link: https://sourceware.org/bugzilla/show_bug.cgi?id=28203
+
+* Fri Sep 17 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-5
+- aarch64: optimize memset performance.
+
+* Fri Sep 17 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-4
+- backport upstream patches to fix some memory leak and double free bugs
+
+* Tue Sep 14 2021 Yang Yanchao<yangyanchao6@huawei.com> - 2.34-3
+- add --enable-static-pie in aarch64
+
+* Wed Aug 25 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-2
+- fix CVE-2021-38604
+ https://sourceware.org/bugzilla/show_bug.cgi?id=28213
+
+* Thu Aug 5 2021 Qingqing Li<liqingqing3@huawei.com> - 2.34-1
+- upgrade to 2.34.
+
+* Fri Jul 23 2021 zhouwenpei<zhouwenpei1@huawei.com> - 2.33-7
+- remove unnecessary build require.
+
+* Sat Jul 3 2021 Qingqing Li<liqingqing3@huawei.com> - 2.33-6
+- malloc: tcache shutdown sequence does not work if the thread never allocated anything. (bug 28028)
+ https://sourceware.org/bugzilla/show_bug.cgi?id=28028
+
+* Thu Jul 1 2021 Qingqing Li<liqingqing3@huawei.com> - 2.33-5
+- wordexp: Use strtoul instead of atoi so that overflow can be detected. (bug 28011)
+ https://sourceware.org/bugzilla/show_bug.cgi?id=28011
+
+* Fri Jun 18 2021 Qingqing Li<liqingqing3@huawei.com> - 2.33-4
+- fix CVE-2021-33574(bug 27896)
+ https://sourceware.org/bugzilla/show_bug.cgi?id=27896
+
+* Tue Apr 27 2021 xuhuijie<xuhujie@huawei.com> - 2.33-3
+- Fix locales BEP inconsistence, use python to replace same file
+ to hard link
+
+* Wed Apr 7 2021 xieliuhua<xieliuhua@huawei.com> - 2.33-2
+- Fix-the-inaccuracy-of-j0f-j1f-y0f-y1f-BZ.patch
+
+* Fri Mar 5 2021 Wang Shuo<wangshuo_1994@foxmail.com> - 2.33-1
+- upgrade glibc to 2.33-1
+
+* Tue Jan 26 2021 shanzhikun <shanzhikun@huawei.com> - 2.31-9
+- elf: Allow dlopen of filter object to work [BZ #16272]
+ https://sourceware.org/bugzilla/show_bug.cgi?id=16272
+
+* Fri Jan 8 2021 Wang Shuo<wangshuo_1994@foxmail.com> - 2.31-8
+- Replace "openEuler" by %{_vendor} for versatility
+
+* Tue Nov 10 2020 liusirui <liusirui@huawei.com> - 2.31-7
+- Fix CVE-2020-27618, iconv accept redundant shift sequences in IBM1364 [BZ #26224]
+ https://sourceware.org/bugzilla/show_bug.cgi?id=26224
+
+* Tue Sep 15 2020 shanzhikun<shanzhikun@huawei.com> - 2.31-6
+- rtld: Avoid using up static TLS surplus for optimizations [BZ #25051].
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=ffb17e7ba3a5ba9632cee97330b325072fbe41dd
+
+* Fri Sep 4 2020 MarsChan<chenmingmin@huawei.com> - 2.31-5
+- For political reasons, remove country selection from tzselect.ksh
+
+* Fri Aug 14 2020 Xu Huijie<546391727@qq.com> - 2.31-4
+- since the new version of the pthread_cond_wait()
+ function has performance degradation in multi-core
+ scenarios, here is an extra libpthreadcond.so using
+ old version of the function. you can use it by adding
+ LD_PRELOAD=./libpthreadcond.so in front of your program
+ (eg: LD_PRELOAD=./libpthreadcond.so ./test).
+ use with-libpthreadcond to compile it.
+ warning:2.17 version pthread_cond_wait() does not meet
+ the posix standard, you should pay attention when using
+ it.
+
+* Fri Jul 24 2020 Wang Shuo<wangshuo_1994@foxmail.com> - 2.31-3
+- backport patch to disable warnings due to deprecated libselinux
+- symbols used by nss and nscd
+
+* Fri Jul 24 2020 Wang Shuo<wangshuo_1994@foxmail.com> - 2.31-2
+- fix CVE-2020-6096
+- fix bugzilla 26137, 26214 and 26215
+
+* Thu Jul 9 2020 wuxu<wuxu.wu@hotmail.com> - 2.31-1
+- upgrade glibc to 2.31-1
+- delete build-locale-archive command
+- delete nsswitch.conf file
+- replace glibc_post_upgrade function with lua
+- remove sys/sysctl.h header file
+- delete stime, ftime function
+
+* Tue Jul 7 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-45
+- disable rpc, it has been splited to libnss and libtirpc
+- disable parallel compilation
+
+* Tue Jul 7 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-44
+- backup to version 40
+
+* Mon Jul 6 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-43
+- disable rpc, it has been splited to libnss and libtirpc
+- disable parallel compilation
+
+* Mon Jul 6 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-42
+- add zh and en to LanguageList
+
+* Thu Jul 2 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-41
+- add filelist to improve the scalability
+- backport many patch for bugfix
+
+* Sat May 30 2020 liqingqing<liqignqing3@huawei.com> - 2.28-40
+- Fix array overflow in backtrace on PowerPC (bug 25423)
+
+* Thu May 28 2020 jdkboy<guoge1@huawei.com> - 2.28-39
+- Disable compilation warnings temporarily
+
+* Tue Apr 28 2020 liqingqing<liqignqing3@huawei.com> - 2.28-38
+- Avoid ldbl-96 stack corruption from range reduction of pseudo-zero (bug 25487)
+
+* Thu Apr 16 2020 wangbin<wangbin224@huawei.com> - 2.28-37
+- backport Kunpeng patches
+
+* Thu Mar 19 2020 yuxiangyang<yuxiangyang4@huawei.com> - 2.28-36
+- fix build src.rpm error
+
+* Fri Mar 13 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-35
+- exclude conflict files about rpc
+
+* Fri Mar 13 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-34
+- enable obsolete rpc
+
+* Tue Mar 10 2020 liqingqing<liqingqing3@huawei.com> - 2.28-33
+- fix use after free in glob when expanding user bug
+
+* Wed Feb 26 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-32
+- remove aditional require for debugutils package
+
+* Tue Jan 7 2020 Wang Shuo <wangshuo47@huawei.com> - 2.28-31
+- Fix compile macro
+
+* Mon Jan 6 2020 Wang Shuo <wangshuo47@huawei.com> - 2.28-30
+- add obsoletes symbol for language
+
+* Fri Dec 20 2019 liqingqing <liqingqing3@huawei.com> - 2.28-29
+- remove country selection from tzselect
+- fix some bugs https://sourceware.org/git/?p=glibc.git;a=commit;h=1df872fd74f730bcae3df201a229195445d2e18a
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=823624bdc47f1f80109c9c52dee7939b9386d708
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=bc10e22c90e42613bd5dafb77b80a9ea1759dd1b
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=6c29942cbf059aca47fd4bbd852ea42c9d46b71f
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=31effacee2fc1b327bedc9a5fcb4b83f227c6539
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=5b06f538c5aee0389ed034f60d90a8884d6d54de
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=57ada43c905eec7ba28fe60a08b93a52d88e26c1
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=e0e4c321c3145b6ac0e8f6e894f87790cf9437ce
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=182a3746b8cc28784718c8ea27346e97d1423945
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=02d8b5ab1c89bcef2627d2b621bfb35b573852c2
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=f59a54ab0c2dcaf9ee946df2bfee9d4be81f09b8
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=fefa21790b5081e5d04662a240e2efd18603ef86
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=2bd81b60d6ffdf7e0d22006d69f4b812b1c80513
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=a55541fd1c4774d483c2d2b4bd17bcb9faac62e7
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=b6d2c4475d5abc05dd009575b90556bdd3c78ad0
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=8a80ee5e2bab17a1f8e1e78fab5c33ac7efa8b29
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=c0fd3244e71db39cef1e2d1d8ba12bb8b7375ce4
+- fix CVE-2016-10739 CVE-2019-19126 CVE-2019-6488
+- add pie compile option for debug/Makefile and remove -static for build-locale-archive
+
+* Fri Dec 20 2019 liusirui <liusirui@huawei.com> - 2.28-28
+- Fix null pointer in mtrace
+
+* Thu Nov 21 2019 mengxian <mengxian@huawei.com> - 2.28-27
+- In x86, configure static pie and cet only with gcc 8 or above
+
+* Wed Nov 13 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.28-26
+- Optimized instructions for Kunpeng processor
+
+* Fri Jan 18 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.28-25
+- Package init
diff --git a/i386-Disable-Intel-Xeon-Phi-tests-for-GCC-15-and-abo.patch b/i386-Disable-Intel-Xeon-Phi-tests-for-GCC-15-and-abo.patch
new file mode 100644
index 0000000..239b876
--- /dev/null
+++ b/i386-Disable-Intel-Xeon-Phi-tests-for-GCC-15-and-abo.patch
@@ -0,0 +1,68 @@
+From 697ab62d1176180bea49094130ad0af2b108874d Mon Sep 17 00:00:00 2001
+From: Sunil K Pandey <skpgkp2@gmail.com>
+Date: Mon, 27 May 2024 10:08:18 -0700
+Subject: [PATCH 1/2] i386: Disable Intel Xeon Phi tests for GCC 15 and above
+ (BZ 31782)
+
+This patch disables Intel Xeon Phi tests for GCC 15 and above.
+
+GCC 15 removed Intel Xeon Phi ISA support.
+commit e1a7e2c54d52d0ba374735e285b617af44841ace
+Author: Haochen Jiang <haochen.jiang@intel.com>
+Date: Mon May 20 10:43:44 2024 +0800
+
+ i386: Remove Xeon Phi ISA support
+
+Fixes BZ 31782.
+
+Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+(cherry picked from commit 1b713c9a5349ef3cd1a8ccf9de017c7865713c67)
+---
+ sysdeps/x86/tst-cpu-features-supports.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c
+index 32daf51053..f85356b589 100644
+--- a/sysdeps/x86/tst-cpu-features-supports.c
++++ b/sysdeps/x86/tst-cpu-features-supports.c
+@@ -65,7 +65,7 @@ do_test (int argc, char **argv)
+ #endif
+ fails += CHECK_FEATURE_ACTIVE (avx, AVX);
+ fails += CHECK_FEATURE_ACTIVE (avx2, AVX2);
+-#if __GNUC_PREREQ (7, 0)
++#if __GNUC_PREREQ (7, 0) && !__GNUC_PREREQ (15, 0)
+ fails += CHECK_FEATURE_ACTIVE (avx5124fmaps, AVX512_4FMAPS);
+ fails += CHECK_FEATURE_ACTIVE (avx5124vnniw, AVX512_4VNNIW);
+ #endif
+@@ -92,14 +92,18 @@ do_test (int argc, char **argv)
+ #if __GNUC_PREREQ (6, 0)
+ fails += CHECK_FEATURE_ACTIVE (avx512bw, AVX512BW);
+ fails += CHECK_FEATURE_ACTIVE (avx512cd, AVX512CD);
++# if !__GNUC_PREREQ (15, 0)
+ fails += CHECK_FEATURE_ACTIVE (avx512er, AVX512ER);
++# endif
+ fails += CHECK_FEATURE_ACTIVE (avx512dq, AVX512DQ);
+ #endif
+ #if __GNUC_PREREQ (5, 0)
+ fails += CHECK_FEATURE_ACTIVE (avx512f, AVX512F);
+ #endif
+ #if __GNUC_PREREQ (6, 0)
++# if !__GNUC_PREREQ (15, 0)
+ fails += CHECK_FEATURE_ACTIVE (avx512pf, AVX512PF);
++# endif
+ fails += CHECK_FEATURE_ACTIVE (avx512vl, AVX512VL);
+ #endif
+ #if __GNUC_PREREQ (5, 0)
+@@ -148,7 +152,9 @@ do_test (int argc, char **argv)
+ #endif
+ fails += CHECK_FEATURE_ACTIVE (popcnt, POPCNT);
+ #if __GNUC_PREREQ (11, 0)
++# if !__GNUC_PREREQ (15, 0)
+ fails += CHECK_FEATURE_ACTIVE (prefetchwt1, PREFETCHWT1);
++# endif
+ fails += CHECK_FEATURE_ACTIVE (ptwrite, PTWRITE);
+ fails += CHECK_FEATURE_ACTIVE (rdpid, RDPID);
+ fails += CHECK_FEATURE_ACTIVE (rdrnd, RDRAND);
+--
+2.33.0
+
diff --git a/libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch b/libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch
new file mode 100644
index 0000000..83f974e
--- /dev/null
+++ b/libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch
@@ -0,0 +1,48 @@
+From cfe121910013a46e2477562282c56ae8062089aa Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 2 Jan 2024 14:36:17 +0100
+Subject: [PATCH 9/9] libio: Check remaining buffer size in _IO_wdo_write (bug
+ 31183)
+
+The multibyte character needs to fit into the remaining buffer space,
+not the already-written buffer space. Without the fix, we were never
+moving the write pointer from the start of the buffer, always using
+the single-character fallback buffer.
+
+Fixes commit 04b76b5aa8b2d1d19066e42dd1 ("Don't error out writing
+a multibyte character to an unbuffered stream (bug 17522)").
+
+(cherry picked from commit ecc7c3deb9f347649c2078fcc0f94d4cedf92d60)
+---
+ NEWS | 1 +
+ libio/wfileops.c | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/NEWS b/NEWS
+index 905230b838..6768c2da6f 100644
+--- a/NEWS
++++ b/NEWS
+@@ -43,6 +43,7 @@ The following bugs are resolved with this release:
+ -D_FILE_OFFSET_BITS=64
+ [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
+ [30843] potential use-after-free in getcanonname (CVE-2023-4806)
++ [31183] Wide stream buffer size reduced MB_LEN_MAX bytes after bug 17522 fix
+ [31184] FAIL: elf/tst-tlsgap
+ [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
+
+diff --git a/libio/wfileops.c b/libio/wfileops.c
+index f16f6db1c3..9ab8f2e7f3 100644
+--- a/libio/wfileops.c
++++ b/libio/wfileops.c
+@@ -55,7 +55,7 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do)
+ char mb_buf[MB_LEN_MAX];
+ char *write_base, *write_ptr, *buf_end;
+
+- if (fp->_IO_write_ptr - fp->_IO_write_base < sizeof (mb_buf))
++ if (fp->_IO_buf_end - fp->_IO_write_ptr < sizeof (mb_buf))
+ {
+ /* Make sure we have room for at least one multibyte
+ character. */
+--
+2.33.0
+
diff --git a/linux-Sync-Linux-6.6-elf.h.patch b/linux-Sync-Linux-6.6-elf.h.patch
new file mode 100644
index 0000000..ac3c74a
--- /dev/null
+++ b/linux-Sync-Linux-6.6-elf.h.patch
@@ -0,0 +1,48 @@
+From 6b3d687470b8f91bc6eb87e924fe97d4592b3aa5 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Tue, 31 Oct 2023 13:32:38 -0300
+Subject: [PATCH 29/29] linux: Sync Linux 6.6 elf.h
+
+It adds NT_X86_SHSTK (2fab02b25ae7cf5), NT_RISCV_CSR/NT_RISCV_VECTOR
+(9300f00439743c4), and NT_LOONGARCH_HW_BREAK/NT_LOONGARCH_HW_WATCH
+(1a69f7a161a78ae).
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Signed-off-by: ticat_fp <fanpeng@loongson.cn>
+---
+ elf/elf.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/elf/elf.h b/elf/elf.h
+index 9c51073f..51633079 100644
+--- a/elf/elf.h
++++ b/elf/elf.h
+@@ -794,6 +794,7 @@ typedef struct
+ #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
+ #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
+ #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
++#define NT_X86_SHSTK 0x204 /* x86 SHSTK state */
+ #define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
+ #define NT_S390_TIMER 0x301 /* s390 timer register */
+ #define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
+@@ -832,6 +833,8 @@ typedef struct
+ #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers. */
+ #define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode. */
+ #define NT_MIPS_MSA 0x802 /* MIPS SIMD registers. */
++#define NT_RISCV_CSR 0x900 /* RISC-V Control and Status Registers */
++#define NT_RISCV_VECTOR 0x901 /* RISC-V vector registers */
+ #define NT_LOONGARCH_CPUCFG 0xa00 /* LoongArch CPU config registers. */
+ #define NT_LOONGARCH_CSR 0xa01 /* LoongArch control and
+ status registers. */
+@@ -841,6 +844,8 @@ typedef struct
+ SIMD Extension registers. */
+ #define NT_LOONGARCH_LBT 0xa04 /* LoongArch Loongson Binary
+ Translation registers. */
++#define NT_LOONGARCH_HW_BREAK 0xa05 /* LoongArch hardware breakpoint registers */
++#define NT_LOONGARCH_HW_WATCH 0xa06 /* LoongArch hardware watchpoint registers */
+
+ /* Legal values for the note segment descriptor types for object files. */
+
+--
+2.33.0
+
diff --git a/locale-delete-no-hard-link-to-avoid-all_language-pac.patch b/locale-delete-no-hard-link-to-avoid-all_language-pac.patch
new file mode 100644
index 0000000..5f1a8fa
--- /dev/null
+++ b/locale-delete-no-hard-link-to-avoid-all_language-pac.patch
@@ -0,0 +1,26 @@
+From 6b462949b0cb8265c44c2f9ddbc0758af2279345 Mon Sep 17 00:00:00 2001
+From: liqingqing_1229 <liqingqing3@huawei.com>
+Date: Tue, 2 Aug 2022 15:10:32 +0800
+Subject: [PATCH] locale: delete --no-hard-link to avoid all_language packages
+ too large
+
+---
+ localedata/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/localedata/Makefile b/localedata/Makefile
+index da92b67..eb4c3d8 100644
+--- a/localedata/Makefile
++++ b/localedata/Makefile
+@@ -476,7 +476,7 @@ $(INSTALL-SUPPORTED-LOCALE-ARCHIVE): install-locales-dir
+ $(build-one-locale)
+
+ $(INSTALL-SUPPORTED-LOCALE-FILES): install-locales-dir
+- @flags="--no-archive --no-hard-links"; \
++ @flags="--no-archive"; \
+ $(build-one-locale)
+
+ tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP
+--
+1.8.3.1
+
diff --git a/malloc-Improve-MAP_HUGETLB-with-glibc.malloc.hugetlb.patch b/malloc-Improve-MAP_HUGETLB-with-glibc.malloc.hugetlb.patch
new file mode 100644
index 0000000..7f42d72
--- /dev/null
+++ b/malloc-Improve-MAP_HUGETLB-with-glibc.malloc.hugetlb.patch
@@ -0,0 +1,50 @@
+From bc6d79f4ae99206e7ec7d6a8c5abf26cdefc8bff Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Thu, 23 Nov 2023 14:29:15 -0300
+Subject: [PATCH] malloc: Improve MAP_HUGETLB with glibc.malloc.hugetlb=2
+
+Even for explicit large page support, allocation might use mmap without
+the hugepage bit set if the requested size is smaller than
+mmap_threshold. For this case where mmap is issued, MAP_HUGETLB is set
+iff the allocation size is larger than the used large page.
+
+To force such allocations to use large pages, also tune the mmap_threhold
+(if it is not explicit set by a tunable). This forces allocation to
+follow the sbrk path, which will fall back to mmap (which will try large
+pages before galling back to default mmap).
+
+Checked on x86_64-linux-gnu.
+Reviewed-by: DJ Delorie <dj@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+---
+ malloc/arena.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/malloc/arena.c b/malloc/arena.c
+index a1a75e5a2b..c73f68890d 100644
+--- a/malloc/arena.c
++++ b/malloc/arena.c
+@@ -312,10 +312,17 @@ ptmalloc_init (void)
+ # endif
+ TUNABLE_GET (mxfast, size_t, TUNABLE_CALLBACK (set_mxfast));
+ TUNABLE_GET (hugetlb, size_t, TUNABLE_CALLBACK (set_hugetlb));
++
+ if (mp_.hp_pagesize > 0)
+- /* Force mmap for main arena instead of sbrk, so hugepages are explicitly
+- used. */
+- __always_fail_morecore = true;
++ {
++ /* Force mmap for main arena instead of sbrk, so MAP_HUGETLB is always
++ tried. Also tune the mmap threshold, so allocation smaller than the
++ large page will also try to use large pages by falling back
++ to sysmalloc_mmap_fallback on sysmalloc. */
++ if (!TUNABLE_IS_INITIALIZED (mmap_threshold))
++ do_set_mmap_threshold (mp_.hp_pagesize);
++ __always_fail_morecore = true;
++ }
+ }
+
+ /* Managing heaps and arenas (for concurrent threads) */
+--
+2.27.0
+
diff --git a/malloc-Use-__get_nprocs-on-arena_get2-BZ-30945.patch b/malloc-Use-__get_nprocs-on-arena_get2-BZ-30945.patch
new file mode 100644
index 0000000..85814ac
--- /dev/null
+++ b/malloc-Use-__get_nprocs-on-arena_get2-BZ-30945.patch
@@ -0,0 +1,106 @@
+From 506e47da1d66b33e24440a495eeef85daf7f2a78 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Wed, 11 Oct 2023 13:43:56 -0300
+Subject: [PATCH] malloc: Use __get_nprocs on arena_get2 (BZ 30945)
+
+This restore the 2.33 semantic for arena_get2. It was changed by
+11a02b035b46 to avoid arena_get2 call malloc (back when __get_nproc
+was refactored to use an scratch_buffer - 903bc7dcc2acafc). The
+__get_nproc was refactored over then and now it also avoid to call
+malloc.
+
+The 11a02b035b46 did not take in consideration any performance
+implication, which should have been discussed properly. The
+__get_nprocs_sched is still used as a fallback mechanism if procfs
+and sysfs is not acessible.
+
+Checked on x86_64-linux-gnu.
+Reviewed-by: DJ Delorie <dj@redhat.com>
+
+(cherry picked from commit 472894d2cfee5751b44c0aaa71ed87df81c8e62e)
+---
+ include/sys/sysinfo.h | 4 ----
+ malloc/arena.c | 2 +-
+ misc/getsysstats.c | 6 ------
+ sysdeps/mach/getsysstats.c | 6 ------
+ sysdeps/unix/sysv/linux/getsysstats.c | 2 +-
+ 5 files changed, 2 insertions(+), 18 deletions(-)
+
+diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h
+index c490561581..65742b1036 100644
+--- a/include/sys/sysinfo.h
++++ b/include/sys/sysinfo.h
+@@ -14,10 +14,6 @@ libc_hidden_proto (__get_nprocs_conf)
+ 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 6f03955ff2..82b09adb47 100644
+--- a/malloc/arena.c
++++ b/malloc/arena.c
+@@ -820,7 +820,7 @@ arena_get2 (size_t size, mstate avoid_arena)
+ narenas_limit = mp_.arena_max;
+ else if (narenas > mp_.arena_test)
+ {
+- int n = __get_nprocs_sched ();
++ int n = __get_nprocs ();
+
+ if (n >= 1)
+ narenas_limit = NARENAS_FROM_NCORES (n);
+diff --git a/misc/getsysstats.c b/misc/getsysstats.c
+index 5f36adc0e8..23cc112074 100644
+--- a/misc/getsysstats.c
++++ b/misc/getsysstats.c
+@@ -44,12 +44,6 @@ 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 5184e5eee1..d3834f3b69 100644
+--- a/sysdeps/mach/getsysstats.c
++++ b/sysdeps/mach/getsysstats.c
+@@ -62,12 +62,6 @@ __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 b0b6c154ac..1ea7f1f01f 100644
+--- a/sysdeps/unix/sysv/linux/getsysstats.c
++++ b/sysdeps/unix/sysv/linux/getsysstats.c
+@@ -29,7 +29,7 @@
+ #include <sys/sysinfo.h>
+ #include <sysdep.h>
+
+-int
++static int
+ __get_nprocs_sched (void)
+ {
+ enum
+--
+2.33.0
+
diff --git a/misc-Add-support-for-Linux-uio.h-RWF_NOAPPEND-flag.patch b/misc-Add-support-for-Linux-uio.h-RWF_NOAPPEND-flag.patch
new file mode 100644
index 0000000..b1799c1
--- /dev/null
+++ b/misc-Add-support-for-Linux-uio.h-RWF_NOAPPEND-flag.patch
@@ -0,0 +1,75 @@
+From c8cb4d2b86ece572793e31a3422ea29e88d77df5 Mon Sep 17 00:00:00 2001
+From: Stafford Horne <shorne@gmail.com>
+Date: Wed, 3 Apr 2024 06:40:37 +0100
+Subject: [PATCH 2/2] misc: Add support for Linux uio.h RWF_NOAPPEND flag
+
+In Linux 6.9 a new flag is added to allow for Per-io operations to
+disable append mode even if a file was opened with the flag O_APPEND.
+This is done with the new RWF_NOAPPEND flag.
+
+This caused two test failures as these tests expected the flag 0x00000020
+to be unused. Adding the flag definition now fixes these tests on Linux
+6.9 (v6.9-rc1).
+
+ FAIL: misc/tst-preadvwritev2
+ FAIL: misc/tst-preadvwritev64v2
+
+This patch adds the flag, adjusts the test and adds details to
+documentation.
+
+Link: https://lore.kernel.org/all/20200831153207.GO3265@brightrain.aerifal.cx/
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 3db9d208dd5f30b12900989c6d2214782b8e2011)
+---
+ manual/llio.texi | 4 ++++
+ misc/tst-preadvwritev2-common.c | 5 ++++-
+ sysdeps/unix/sysv/linux/bits/uio-ext.h | 1 +
+ 3 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/manual/llio.texi b/manual/llio.texi
+index 0b61d491f5..fae49d1433 100644
+--- a/manual/llio.texi
++++ b/manual/llio.texi
+@@ -1339,6 +1339,10 @@ will fail and set @code{errno} to @code{EAGAIN} if the operation would block.
+
+ @item RWF_APPEND
+ Per-IO synchronization as if the file was opened with @code{O_APPEND} flag.
++
++@item RWF_NOAPPEND
++This flag allows an offset to be honored, even if the file was opened with
++@code{O_APPEND} flag.
+ @end vtable
+
+ When the source file is compiled with @code{_FILE_OFFSET_BITS == 64} the
+diff --git a/misc/tst-preadvwritev2-common.c b/misc/tst-preadvwritev2-common.c
+index 355dbea05c..0d3729eac0 100644
+--- a/misc/tst-preadvwritev2-common.c
++++ b/misc/tst-preadvwritev2-common.c
+@@ -34,8 +34,11 @@
+ #ifndef RWF_APPEND
+ # define RWF_APPEND 0
+ #endif
++#ifndef RWF_NOAPPEND
++# define RWF_NOAPPEND 0
++#endif
+ #define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \
+- | RWF_APPEND)
++ | RWF_APPEND | RWF_NOAPPEND)
+
+ /* Generic uio_lim.h does not define IOV_MAX. */
+ #ifndef IOV_MAX
+diff --git a/sysdeps/unix/sysv/linux/bits/uio-ext.h b/sysdeps/unix/sysv/linux/bits/uio-ext.h
+index 311f5b16ce..d641f57b01 100644
+--- a/sysdeps/unix/sysv/linux/bits/uio-ext.h
++++ b/sysdeps/unix/sysv/linux/bits/uio-ext.h
+@@ -47,6 +47,7 @@ extern ssize_t process_vm_writev (pid_t __pid, const struct iovec *__lvec,
+ #define RWF_SYNC 0x00000004 /* per-IO O_SYNC. */
+ #define RWF_NOWAIT 0x00000008 /* per-IO nonblocking mode. */
+ #define RWF_APPEND 0x00000010 /* per-IO O_APPEND. */
++#define RWF_NOAPPEND 0x00000020 /* per-IO negation of O_APPEND */
+
+ __END_DECLS
+
+--
+2.33.0
+
diff --git a/nptl-Use-support-check.h-facilities-in-tst-setuid3.patch b/nptl-Use-support-check.h-facilities-in-tst-setuid3.patch
new file mode 100644
index 0000000..2251783
--- /dev/null
+++ b/nptl-Use-support-check.h-facilities-in-tst-setuid3.patch
@@ -0,0 +1,134 @@
+From f30501ca7557a194a53af22ff5b47b3189c48216 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@redhat.com>
+Date: Fri, 26 Jul 2024 13:21:34 +0100
+Subject: [PATCH] nptl: Use <support/check.h> facilities in tst-setuid3
+
+Remove local FAIL macro in favor to FAIL_EXIT1 from <support/check.h>,
+which provides equivalent reporting, with the name of the file and the
+line number within of the failure site additionally included. Remove
+FAIL_ERR altogether and include ": %m" explicitly with the format string
+supplied to FAIL_EXIT1 as there seems little value to have a separate
+macro just for this.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit 8c98195af6e6f1ce21743fc26c723e0f7e45bcf2)
+---
+ sysdeps/pthread/tst-setuid3.c | 37 +++++++++++++++--------------------
+ 1 file changed, 16 insertions(+), 21 deletions(-)
+
+diff --git a/sysdeps/pthread/tst-setuid3.c b/sysdeps/pthread/tst-setuid3.c
+index 58b78d3116..d13848a647 100644
+--- a/sysdeps/pthread/tst-setuid3.c
++++ b/sysdeps/pthread/tst-setuid3.c
+@@ -15,24 +15,19 @@
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+-#include <stdio.h>
+ #include <errno.h>
+ #include <pthread.h>
+ #include <stdbool.h>
+ #include <unistd.h>
+
++#include <support/check.h>
++
+ /* The test must run under a non-privileged user ID. */
+ static const uid_t test_uid = 1;
+
+ static pthread_barrier_t barrier1;
+ static pthread_barrier_t barrier2;
+
+-#define FAIL(fmt, ...) \
+- do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0)
+-
+-#define FAIL_ERR(fmt, ...) \
+- do { printf ("FAIL: " fmt ": %m\n", __VA_ARGS__); _exit (1); } while (0)
+-
+ /* True if x is not a successful return code from pthread_barrier_wait. */
+ static inline bool
+ is_invalid_barrier_ret (int x)
+@@ -45,10 +40,10 @@ thread_func (void *ctx __attribute__ ((unused)))
+ {
+ int ret = pthread_barrier_wait (&barrier1);
+ if (is_invalid_barrier_ret (ret))
+- FAIL ("pthread_barrier_wait (barrier1) (on thread): %d", ret);
++ FAIL_EXIT1 ("pthread_barrier_wait (barrier1) (on thread): %d", ret);
+ ret = pthread_barrier_wait (&barrier2);
+ if (is_invalid_barrier_ret (ret))
+- FAIL ("pthread_barrier_wait (barrier2) (on thread): %d", ret);
++ FAIL_EXIT1 ("pthread_barrier_wait (barrier2) (on thread): %d", ret);
+ return NULL;
+ }
+
+@@ -59,13 +54,13 @@ setuid_failure (int phase)
+ switch (ret)
+ {
+ case 0:
+- FAIL ("setuid succeeded unexpectedly in phase %d", phase);
++ FAIL_EXIT1 ("setuid succeeded unexpectedly in phase %d", phase);
+ case -1:
+ if (errno != EPERM)
+- FAIL_ERR ("setuid phase %d", phase);
++ FAIL_EXIT1 ("setuid phase %d: %m", phase);
+ break;
+ default:
+- FAIL ("invalid setuid return value in phase %d: %d", phase, ret);
++ FAIL_EXIT1 ("invalid setuid return value in phase %d: %d", phase, ret);
+ }
+ }
+
+@@ -74,42 +69,42 @@ do_test (void)
+ {
+ if (getuid () == 0)
+ if (setuid (test_uid) != 0)
+- FAIL_ERR ("setuid (%u)", (unsigned) test_uid);
++ FAIL_EXIT1 ("setuid (%u): %m", (unsigned) test_uid);
+ if (setuid (getuid ()))
+- FAIL_ERR ("setuid (%s)", "getuid ()");
++ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()");
+ setuid_failure (1);
+
+ int ret = pthread_barrier_init (&barrier1, NULL, 2);
+ if (ret != 0)
+- FAIL ("pthread_barrier_init (barrier1): %d", ret);
++ FAIL_EXIT1 ("pthread_barrier_init (barrier1): %d", ret);
+ ret = pthread_barrier_init (&barrier2, NULL, 2);
+ if (ret != 0)
+- FAIL ("pthread_barrier_init (barrier2): %d", ret);
++ FAIL_EXIT1 ("pthread_barrier_init (barrier2): %d", ret);
+
+ pthread_t thread;
+ ret = pthread_create (&thread, NULL, thread_func, NULL);
+ if (ret != 0)
+- FAIL ("pthread_create: %d", ret);
++ FAIL_EXIT1 ("pthread_create: %d", ret);
+
+ /* Ensure that the thread is running properly. */
+ ret = pthread_barrier_wait (&barrier1);
+ if (is_invalid_barrier_ret (ret))
+- FAIL ("pthread_barrier_wait (barrier1): %d", ret);
++ FAIL_EXIT1 ("pthread_barrier_wait (barrier1): %d", ret);
+
+ setuid_failure (2);
+
+ /* Check success case. */
+ if (setuid (getuid ()) != 0)
+- FAIL_ERR ("setuid (%s)", "getuid ()");
++ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()");
+
+ /* Shutdown. */
+ ret = pthread_barrier_wait (&barrier2);
+ if (is_invalid_barrier_ret (ret))
+- FAIL ("pthread_barrier_wait (barrier2): %d", ret);
++ FAIL_EXIT1 ("pthread_barrier_wait (barrier2): %d", ret);
+
+ ret = pthread_join (thread, NULL);
+ if (ret != 0)
+- FAIL ("pthread_join: %d", ret);
++ FAIL_EXIT1 ("pthread_join: %d", ret);
+
+ return 0;
+ }
+--
+2.33.0
+
diff --git a/nscd.conf b/nscd.conf
new file mode 100644
index 0000000..8a24a78
--- /dev/null
+++ b/nscd.conf
@@ -0,0 +1 @@
+d /run/nscd 0755 root root
diff --git a/nsswitch.conf b/nsswitch.conf
new file mode 100644
index 0000000..b49a3b2
--- /dev/null
+++ b/nsswitch.conf
@@ -0,0 +1,56 @@
+#
+# /etc/nsswitch.conf
+#
+# An example Name Service Switch config file. This file should be
+# sorted with the most-used services at the beginning.
+#
+# The entry '[NOTFOUND=return]' means that the search for an
+# entry should stop if the search in the previous entry turned
+# up nothing. Note that if the search failed due to some other reason
+# (like no NIS server responding) then the search continues with the
+# next entry.
+#
+# Valid entries include:
+#
+# nisplus Use NIS+ (NIS version 3)
+# nis Use NIS (NIS version 2), also called YP
+# dns Use DNS (Domain Name Service)
+# files Use the local files in /etc
+# db Use the pre-processed /var/db files
+# compat Use /etc files plus *_compat pseudo-databases
+# hesiod Use Hesiod (DNS) for user lookups
+# sss Use sssd (System Security Services Daemon)
+# [NOTFOUND=return] Stop searching if not found so far
+#
+# 'sssd' performs its own 'files'-based caching, so it should
+# generally come before 'files'.
+
+# To use 'db', install the nss_db package, and put the 'db' in front
+# of 'files' for entries you want to be looked up first in the
+# databases, like this:
+#
+# passwd: db files
+# shadow: db files
+# group: db files
+
+passwd: sss files
+shadow: files sss
+group: sss files
+
+hosts: files dns myhostname
+
+bootparams: files
+
+ethers: files
+netmasks: files
+networks: files
+protocols: files
+rpc: files
+services: files sss
+
+netgroup: sss
+
+publickey: files
+
+automount: files sss
+aliases: files
diff --git a/posix-Use-support-check.h-facilities-in-tst-truncate.patch b/posix-Use-support-check.h-facilities-in-tst-truncate.patch
new file mode 100644
index 0000000..e41025b
--- /dev/null
+++ b/posix-Use-support-check.h-facilities-in-tst-truncate.patch
@@ -0,0 +1,89 @@
+From 15ca66303f7a7ce463bb41a83d88474996e46efd Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@redhat.com>
+Date: Fri, 26 Jul 2024 13:21:34 +0100
+Subject: [PATCH] posix: Use <support/check.h> facilities in tst-truncate
+ and tst-truncate64
+
+Remove local FAIL macro in favor to FAIL_RET from <support/check.h>,
+which provides equivalent reporting, with the name of the file of the
+failure site additionally included, for the tst-truncate-common core
+shared between the tst-truncate and tst-truncate64 tests.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit fe47595504a55e7bb992f8928533df154b510383)
+---
+ posix/tst-truncate-common.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/posix/tst-truncate-common.c b/posix/tst-truncate-common.c
+index 9a8163fdfe..fd32eb73c5 100644
+--- a/posix/tst-truncate-common.c
++++ b/posix/tst-truncate-common.c
+@@ -21,6 +21,8 @@
+ #include <sys/stat.h>
+ #include <unistd.h>
+
++#include <support/check.h>
++
+ static void do_prepare (void);
+ #define PREPARE(argc, argv) do_prepare ()
+ static int do_test (void);
+@@ -42,9 +44,6 @@ do_prepare (void)
+ }
+ }
+
+-#define FAIL(str) \
+- do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0)
+-
+ static int
+ do_test_with_offset (off_t offset)
+ {
+@@ -54,35 +53,35 @@ do_test_with_offset (off_t offset)
+ memset (buf, 0xcf, sizeof (buf));
+
+ if (pwrite (temp_fd, buf, sizeof (buf), offset) != sizeof (buf))
+- FAIL ("write failed");
++ FAIL_RET ("write failed");
+ if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + sizeof (buf)))
+- FAIL ("initial size wrong");
++ FAIL_RET ("initial size wrong");
+
+ if (ftruncate (temp_fd, offset + 800) < 0)
+- FAIL ("size reduction with ftruncate failed");
++ FAIL_RET ("size reduction with ftruncate failed");
+ if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800))
+- FAIL ("size after reduction with ftruncate is incorrect");
++ FAIL_RET ("size after reduction with ftruncate is incorrect");
+
+ /* The following test covers more than POSIX. POSIX does not require
+ that ftruncate() can increase the file size. But we are testing
+ Unix systems. */
+ if (ftruncate (temp_fd, offset + 1200) < 0)
+- FAIL ("size increate with ftruncate failed");
++ FAIL_RET ("size increate with ftruncate failed");
+ if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200))
+- FAIL ("size after increase is incorrect");
++ FAIL_RET ("size after increase is incorrect");
+
+ if (truncate (temp_filename, offset + 800) < 0)
+- FAIL ("size reduction with truncate failed");
++ FAIL_RET ("size reduction with truncate failed");
+ if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800))
+- FAIL ("size after reduction with truncate incorrect");
++ FAIL_RET ("size after reduction with truncate incorrect");
+
+ /* The following test covers more than POSIX. POSIX does not require
+ that truncate() can increase the file size. But we are testing
+ Unix systems. */
+ if (truncate (temp_filename, (offset + 1200)) < 0)
+- FAIL ("size increase with truncate failed");
++ FAIL_RET ("size increase with truncate failed");
+ if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200))
+- FAIL ("size increase with truncate is incorrect");
++ FAIL_RET ("size increase with truncate is incorrect");
+
+ return 0;
+ }
+--
+2.33.0
+
diff --git a/replace_same_file_to_hard_link.py b/replace_same_file_to_hard_link.py
new file mode 100644
index 0000000..12829f0
--- /dev/null
+++ b/replace_same_file_to_hard_link.py
@@ -0,0 +1,98 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""
+function: This script resolves locales's BEP inconsistence,
+ it scans a specific path and replaces the same file
+ in that path with a hard link.Avoid different language
+ packs each time due to concurrent compilation.
+"""
+import os
+import sys
+import time
+
+all_file = {}
+
+def cmp_file(f1, f2):
+ """compare two files in bytes"""
+ st1 = os.stat(f1)
+ st2 = os.stat(f2)
+
+ bufsize = 8 * 1024
+ with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2:
+ while True:
+ b1 = fp1.read(bufsize)
+ b2 = fp2.read(bufsize)
+ if b1 != b2:
+ return False
+ if not b1:
+ return True
+
+
+def search_all_inode(dir_path):
+ """recursively traverse the directory to group all"""
+ files = os.listdir(dir_path)
+
+ for fi in files:
+ fi_d = os.path.join(dir_path, fi)
+ if os.path.isdir(fi_d):
+ search_all_inode(fi_d)
+ else:
+ size = os.stat(fi_d).st_size
+ if size in all_file:
+ all_file[size].append(fi_d)
+ else:
+ all_file[size] = [fi_d]
+
+
+def deal_one(file_paths):
+ """traverse the file array, delete the same file and create a hard link"""
+ file_count = len(file_paths)
+ inode_files = {}
+
+ for i in range(0, file_count):
+ for j in range(i + 1, file_count):
+ file1 = file_paths[i]
+ file2 = file_paths[j]
+
+ file1_inode = os.stat(file1).st_ino
+ file2_inode = os.stat(file2).st_ino
+
+ if file1_inode not in inode_files:
+ inode_files[file1_inode] = file1
+
+ if file1_inode == file2_inode:
+ continue
+
+ if cmp_file(file1, file2):
+ print('deal same file:', file1, '==', file2)
+ os.remove(file2)
+ os.link(file1, file2)
+ else:
+ if file2_inode not in inode_files:
+ inode_files[file2_inode] = file2
+
+
+def deal_files():
+ """get file array and processed one by one"""
+ for size in all_file:
+ file_paths = all_file[size]
+ if len(file_paths) > 1:
+ deal_one(file_paths)
+
+
+def usage():
+ """print usage"""
+ print("""
+rm_same_file: Replace the same file with a hard link.
+
+rm_same_file.py [target path]
+
+ """)
+
+if __name__ == "__main__":
+ if len(sys.argv) == 2:
+ search_all_inode(sys.argv[1])
+ deal_files()
+ else:
+ usage()
+ sys.exit()
diff --git a/sources b/sources
new file mode 100644
index 0000000..8702858
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+778cce0ea6bf7f84ca8caacf4a01f45b glibc-2.38.tar.xz
diff --git a/sparc-Fix-broken-memset-for-sparc32-BZ-31068.patch b/sparc-Fix-broken-memset-for-sparc32-BZ-31068.patch
new file mode 100644
index 0000000..db3f4ae
--- /dev/null
+++ b/sparc-Fix-broken-memset-for-sparc32-BZ-31068.patch
@@ -0,0 +1,43 @@
+From 6f68075869f6034f5fde3823741623d34164dc7d Mon Sep 17 00:00:00 2001
+From: Andreas Larsson <andreas@gaisler.com>
+Date: Wed, 15 Nov 2023 13:29:43 +0100
+Subject: [PATCH 3/6] sparc: Fix broken memset for sparc32 [BZ #31068]
+
+Fixes commit a61933fe27df ("sparc: Remove bzero optimization") that
+after moving code jumped to the wrong label 4.
+
+Verfied by successfully running string/test-memset on sparc32.
+
+Signed-off-by: Andreas Larsson <andreas@gaisler.com>
+Signed-off-by: Ludwig Rydberg <ludwig.rydberg@gaisler.com>
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 578190b7e43305141512dee777e4a3b3e8159393)
+---
+ sysdeps/sparc/sparc32/memset.S | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sysdeps/sparc/sparc32/memset.S b/sysdeps/sparc/sparc32/memset.S
+index ca29ff5685..1dc3a640e8 100644
+--- a/sysdeps/sparc/sparc32/memset.S
++++ b/sysdeps/sparc/sparc32/memset.S
+@@ -55,7 +55,7 @@ ENTRY(memset)
+
+ andcc %o0, 3, %o2
+ bne 3f
+-4: andcc %o0, 4, %g0
++5: andcc %o0, 4, %g0
+
+ be 2f
+ mov %g3, %g2
+@@ -139,7 +139,7 @@ ENTRY(memset)
+ stb %g3, [%o0 + 0x02]
+ 2: sub %o2, 4, %o2
+ add %o1, %o2, %o1
+- b 4b
++ b 5b
+ sub %o0, %o2, %o0
+ END(memset)
+ libc_hidden_builtin_def (memset)
+--
+2.33.0
+
diff --git a/sparc-Fix-sparc64-memmove-length-comparison-BZ-31266.patch b/sparc-Fix-sparc64-memmove-length-comparison-BZ-31266.patch
new file mode 100644
index 0000000..a74f672
--- /dev/null
+++ b/sparc-Fix-sparc64-memmove-length-comparison-BZ-31266.patch
@@ -0,0 +1,32 @@
+From aac57faf5425b472a72132b09f4b3a2aa1f77a63 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Thu, 18 Jan 2024 10:52:18 -0300
+Subject: [PATCH 5/6] sparc: Fix sparc64 memmove length comparison (BZ 31266)
+
+The small counts copy bytes comparsion should be unsigned (as the
+memmove size argument). It fixes string/tst-memmove-overflow on
+sparcv9, where the input size triggers an invalid code path.
+
+Checked on sparc64-linux-gnu and sparcv9-linux-gnu.
+
+(cherry picked from commit 926a4bdbb5fc8955570208b5571b2d04c6ffbd1d)
+---
+ sysdeps/sparc/sparc64/memmove.S | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sysdeps/sparc/sparc64/memmove.S b/sysdeps/sparc/sparc64/memmove.S
+index db6f4f0e84..62b19ebc1b 100644
+--- a/sysdeps/sparc/sparc64/memmove.S
++++ b/sysdeps/sparc/sparc64/memmove.S
+@@ -38,7 +38,7 @@ ENTRY(memmove)
+ /*
+ * normal, copy forwards
+ */
+-2: ble %XCC, .Ldbytecp
++2: bleu %XCC, .Ldbytecp
+ andcc %o1, 3, %o5 /* is src word aligned */
+ bz,pn %icc, .Laldst
+ cmp %o5, 2 /* is src half-word aligned */
+--
+2.33.0
+
diff --git a/sparc-Remove-unwind-information-from-signal-return-s.patch b/sparc-Remove-unwind-information-from-signal-return-s.patch
new file mode 100644
index 0000000..0db30ef
--- /dev/null
+++ b/sparc-Remove-unwind-information-from-signal-return-s.patch
@@ -0,0 +1,74 @@
+From 0c5e5bace57578ed3e28eb89ee2d2b31b74c4ecc Mon Sep 17 00:00:00 2001
+From: Daniel Cederman <cederman@gaisler.com>
+Date: Tue, 16 Jan 2024 09:31:41 +0100
+Subject: [PATCH 6/6] sparc: Remove unwind information from signal return stubs
+ [BZ #31244]
+
+The functions were previously written in C, but were not compiled
+with unwind information. The ENTRY/END macros includes .cfi_startproc
+and .cfi_endproc which adds unwind information. This caused the
+tests cleanup-8 and cleanup-10 in the GCC testsuite to fail.
+This patch adds a version of the ENTRY/END macros without the
+CFI instructions that can be used instead.
+
+sigaction registers a restorer address that is located two instructions
+before the stub function. This patch adds a two instruction padding to
+avoid that the unwinder accesses the unwind information from the function
+that the linker has placed right before it in memory. This fixes an issue
+with pthread_cancel that caused tst-mutex8-static (and other tests) to fail.
+
+Signed-off-by: Daniel Cederman <cederman@gaisler.com>
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 7bd06985c0a143cdcba2762bfe020e53514a53de)
+---
+ sysdeps/sparc/sysdep.h | 9 +++++++++
+ .../unix/sysv/linux/sparc/sparc32/sigreturn_stub.S | 11 +++++++----
+ 2 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/sysdeps/sparc/sysdep.h b/sysdeps/sparc/sysdep.h
+index 687e626182..151baa5e10 100644
+--- a/sysdeps/sparc/sysdep.h
++++ b/sysdeps/sparc/sysdep.h
+@@ -76,6 +76,15 @@ C_LABEL(name) \
+ cfi_endproc; \
+ .size name, . - name
+
++#define ENTRY_NOCFI(name) \
++ .align 4; \
++ .global C_SYMBOL_NAME(name); \
++ .type name, @function; \
++C_LABEL(name)
++
++#define END_NOCFI(name) \
++ .size name, . - name
++
+ #undef LOC
+ #define LOC(name) .L##name
+
+diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
+index cf509c8d5c..1962f9053c 100644
+--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
+@@ -23,12 +23,15 @@
+
+ [1] https://lkml.org/lkml/2016/5/27/465 */
+
+-ENTRY (__rt_sigreturn_stub)
++ nop
++ nop
++
++ENTRY_NOCFI (__rt_sigreturn_stub)
+ mov __NR_rt_sigreturn, %g1
+ ta 0x10
+-END (__rt_sigreturn_stub)
++END_NOCFI (__rt_sigreturn_stub)
+
+-ENTRY (__sigreturn_stub)
++ENTRY_NOCFI (__sigreturn_stub)
+ mov __NR_sigreturn, %g1
+ ta 0x10
+-END (__sigreturn_stub)
++END_NOCFI (__sigreturn_stub)
+--
+2.33.0
+
diff --git a/sparc64-Remove-unwind-information-from-signal-return.patch b/sparc64-Remove-unwind-information-from-signal-return.patch
new file mode 100644
index 0000000..809a556
--- /dev/null
+++ b/sparc64-Remove-unwind-information-from-signal-return.patch
@@ -0,0 +1,42 @@
+From 0e383d2d4e7c08b36ad3edb30c072a3dc4d26ed8 Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Wed, 17 Jan 2024 10:38:09 -0300
+Subject: [PATCH 4/6] sparc64: Remove unwind information from signal return
+ stubs [BZ#31244]
+
+Similar to sparc32 fix, remove the unwind information on the signal
+return stubs. This fixes the regressions:
+
+FAIL: nptl/tst-cancel24-static
+FAIL: nptl/tst-cond8-static
+FAIL: nptl/tst-mutex8-static
+FAIL: nptl/tst-mutexpi8-static
+FAIL: nptl/tst-mutexpi9
+
+On sparc64-linux-gnu.
+
+(cherry picked from commit 369efd817780276dbe0ecf8be6e1f354bdbc9857)
+---
+ sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S
+index 7fac04f657..f089bcaf68 100644
+--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S
++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S
+@@ -23,7 +23,10 @@
+
+ [1] https://lkml.org/lkml/2016/5/27/465 */
+
+-ENTRY (__rt_sigreturn_stub)
++ nop
++ nop
++
++ENTRY_NOCFI (__rt_sigreturn_stub)
+ mov __NR_rt_sigreturn, %g1
+ ta 0x6d
+-END (__rt_sigreturn_stub)
++END_NOCFI (__rt_sigreturn_stub)
+--
+2.33.0
+
diff --git a/stdio-common-Add-test-for-vfscanf-with-matches-longe.patch b/stdio-common-Add-test-for-vfscanf-with-matches-longe.patch
new file mode 100644
index 0000000..77a1cf1
--- /dev/null
+++ b/stdio-common-Add-test-for-vfscanf-with-matches-longe.patch
@@ -0,0 +1,176 @@
+From 99ffa84bdcdc3d81e82f448279f0c8278dd30964 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@redhat.com>
+Date: Fri, 26 Jul 2024 13:21:34 +0100
+Subject: [PATCH] stdio-common: Add test for vfscanf with matches longer
+ than INT_MAX [BZ #27650]
+
+Complement commit b03e4d7bd25b ("stdio: fix vfscanf with matches longer
+than INT_MAX (bug 27650)") and add a test case for the issue, inspired
+by the reproducer provided with the bug report.
+
+This has been verified to succeed as from the commit referred and fail
+beforehand.
+
+As the test requires 2GiB of data to be passed around its performance
+has been evaluated using a choice of systems and the execution time
+determined to be respectively in the range of 9s for POWER9@2.166GHz,
+24s for FU740@1.2GHz, and 40s for 74Kf@950MHz. As this is on the verge
+of and beyond the default timeout it has been increased by the factor of
+8. Regardless, following recent practice the test has been added to the
+standard rather than extended set.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit 89cddc8a7096f3d9225868304d2bc0a1aaf07d63)
+---
+ stdio-common/Makefile | 5 ++
+ stdio-common/tst-scanf-bz27650.c | 108 +++++++++++++++++++++++++++++++
+ 2 files changed, 113 insertions(+)
+ create mode 100644 stdio-common/tst-scanf-bz27650.c
+
+diff --git a/stdio-common/Makefile b/stdio-common/Makefile
+index 3866362bae..2bcbaf754a 100644
+--- a/stdio-common/Makefile
++++ b/stdio-common/Makefile
+@@ -243,6 +243,7 @@ tests := \
+ tst-scanf-binary-c2x \
+ tst-scanf-binary-gnu11 \
+ tst-scanf-binary-gnu89 \
++ tst-scanf-bz27650 \
+ tst-scanf-round \
+ tst-scanf-to_inpunct \
+ tst-setvbuf1 \
+@@ -312,6 +313,7 @@ generated += \
+ tst-printf-fp-free.mtrace \
+ tst-printf-fp-leak-mem.out \
+ tst-printf-fp-leak.mtrace \
++ tst-scanf-bz27650.mtrace \
+ tst-vfprintf-width-prec-mem.out \
+ tst-vfprintf-width-prec.mtrace \
+ # generated
+@@ -398,6 +400,9 @@ tst-printf-fp-free-ENV = \
+ tst-printf-fp-leak-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace \
+ LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
++tst-scanf-bz27650-ENV = \
++ MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \
++ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+
+ $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
+ $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
+diff --git a/stdio-common/tst-scanf-bz27650.c b/stdio-common/tst-scanf-bz27650.c
+new file mode 100644
+index 0000000000..3a742bc865
+--- /dev/null
++++ b/stdio-common/tst-scanf-bz27650.c
+@@ -0,0 +1,108 @@
++/* Test for BZ #27650, formatted input matching beyond INT_MAX.
++ Copyright (C) 2024 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <error.h>
++#include <errno.h>
++#include <limits.h>
++#include <mcheck.h>
++#include <stddef.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <sys/types.h>
++
++#include <support/check.h>
++#include <support/test-driver.h>
++
++/* Produce a stream of more than INT_MAX characters via buffer BUF of
++ size SIZE according to bookkeeping in COOKIE and then return EOF. */
++
++static ssize_t
++io_read (void *cookie, char *buf, size_t size)
++{
++ unsigned int *written = cookie;
++ unsigned int w = *written;
++
++ if (w > INT_MAX)
++ return 0;
++
++ memset (buf, 'a', size);
++ *written = w + size;
++ return size;
++}
++
++/* Consume a stream of more than INT_MAX characters from an artificial
++ input stream of which none is the new line character. The call to
++ fscanf is supposed to complete upon the EOF condition of input,
++ however in the presence of BZ #27650 it will terminate prematurely
++ with characters still outstanding in input. Diagnose the condition
++ and return status accordingly. */
++
++int
++do_test (void)
++{
++ static cookie_io_functions_t io_funcs = { .read = io_read };
++ unsigned int written = 0;
++ FILE *in;
++ int v;
++
++ mtrace ();
++
++ in = fopencookie (&written, "r", io_funcs);
++ if (in == NULL)
++ {
++ FAIL ("fopencookie: %m");
++ goto out;
++ }
++
++ v = fscanf (in, "%*[^\n]");
++ if (ferror (in))
++ {
++ FAIL ("fscanf: input failure, at %u: %m", written);
++ goto out_close;
++ }
++ else if (v == EOF)
++ {
++ FAIL ("fscanf: unexpected end of file, at %u", written);
++ goto out_close;
++ }
++
++ if (!feof (in))
++ {
++ v = fgetc (in);
++ if (ferror (in))
++ FAIL ("fgetc: input failure: %m");
++ else if (v == EOF)
++ FAIL ("fgetc: unexpected end of file after missing end of file");
++ else if (v == '\n')
++ FAIL ("unexpected new line character received");
++ else
++ FAIL ("character received after end of file expected: \\x%02x", v);
++ }
++
++out_close:
++ if (fclose (in) != 0)
++ FAIL ("fclose: %m");
++
++out:
++ return EXIT_SUCCESS;
++}
++
++#define TIMEOUT (DEFAULT_TIMEOUT * 8)
++#include <support/test-driver.c>
+--
+2.33.0
+
diff --git a/stdlib-Improve-tst-realpath-compatibility-with-sourc.patch b/stdlib-Improve-tst-realpath-compatibility-with-sourc.patch
new file mode 100644
index 0000000..b58b467
--- /dev/null
+++ b/stdlib-Improve-tst-realpath-compatibility-with-sourc.patch
@@ -0,0 +1,43 @@
+From d97cca1e5df812be0e4de1e38091f02bb1e7ec4e Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 1 Aug 2023 10:27:15 +0200
+Subject: [PATCH] stdlib: Improve tst-realpath compatibility with source
+ fortification
+
+On GCC before 11, IPA can make the fortified realpath aware that the
+buffer size is not large enough (8 bytes instead of PATH_MAX bytes).
+Fix this by using a buffer that is large enough.
+
+(cherry picked from commit 510fc20d73de12c85823d9996faac74666e9c2e7)
+---
+ stdlib/tst-realpath.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/stdlib/tst-realpath.c b/stdlib/tst-realpath.c
+index f325c95a44..3694ecd8af 100644
+--- a/stdlib/tst-realpath.c
++++ b/stdlib/tst-realpath.c
+@@ -24,6 +24,7 @@
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
++#include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <malloc.h>
+@@ -50,7 +51,11 @@ void dealloc (void *p)
+
+ char* alloc (void)
+ {
+- return (char *)malloc (8);
++#ifdef PATH_MAX
++ return (char *)malloc (PATH_MAX);
++#else
++ return (char *)malloc (4096);
++#endif
+ }
+
+ static int
+--
+2.33.0
+
diff --git a/strcmp-delete-align-for-loop_aligned.patch b/strcmp-delete-align-for-loop_aligned.patch
new file mode 100644
index 0000000..cf5b15a
--- /dev/null
+++ b/strcmp-delete-align-for-loop_aligned.patch
@@ -0,0 +1,32 @@
+From 9bbffed83b93f633b272368fc536a4f24e9942e6 Mon Sep 17 00:00:00 2001
+From: Yang Yanchao <yangyanchao6@huawei.com>
+Date: Mon, 21 Feb 2022 14:25:25 +0800
+Subject: [PATCH] strcmp: delete align for loop_aligned
+
+In Kunpeng-920, the performance of strcmp deteriorates only
+when the 16 to 23 characters are different.Or the string is
+only 16-23 characters.That shows 2 misses per iteration which
+means this is a branch predictor issue indeed.
+In the preceding scenario, strcmp performance is 300% worse than expected.
+
+Fortunately, this problem can be solved by modifying the alignment of the functions.
+---
+ sysdeps/aarch64/strcmp.S | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/sysdeps/aarch64/strcmp.S b/sysdeps/aarch64/strcmp.S
+index f225d718..7a048b66 100644
+--- a/sysdeps/aarch64/strcmp.S
++++ b/sysdeps/aarch64/strcmp.S
+@@ -71,8 +71,6 @@ ENTRY(strcmp)
+ b.ne L(misaligned8)
+ cbnz tmp, L(mutual_align)
+
+- .p2align 4
+-
+ L(loop_aligned):
+ ldr data2, [src1, off2]
+ ldr data1, [src1], 8
+--
+2.33.0
+
diff --git a/support-Add-FAIL-test-failure-helper.patch b/support-Add-FAIL-test-failure-helper.patch
new file mode 100644
index 0000000..aef686b
--- /dev/null
+++ b/support-Add-FAIL-test-failure-helper.patch
@@ -0,0 +1,201 @@
+From 28f358bc4209ab0425170cdccf65bb1fe861148f Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@redhat.com>
+Date: Fri, 26 Jul 2024 13:21:34 +0100
+Subject: [PATCH] support: Add FAIL test failure helper
+
+Add a FAIL test failure helper analogous to FAIL_RET, that does not
+cause the current function to return, providing a standardized way to
+report a test failure with a message supplied while permitting the
+caller to continue executing, for further reporting, cleaning up, etc.
+
+Update existing test cases that provide a conflicting definition of FAIL
+by removing the local FAIL definition and then as follows:
+
+- tst-fortify-syslog: provide a meaningful message in addition to the
+ file name already added by <support/check.h>; 'support_record_failure'
+ is already called by 'support_print_failure_impl' invoked by the new
+ FAIL test failure helper.
+
+- tst-ctype: no update to FAIL calls required, with the name of the file
+ and the line number within of the failure site additionally included
+ by the new FAIL test failure helper, and error counting plus count
+ reporting upon test program termination also already provided by
+ 'support_record_failure' and 'support_report_failure' respectively,
+ called by 'support_print_failure_impl' and 'adjust_exit_status' also
+ respectively. However in a number of places 'printf' is called and
+ the error count adjusted by hand, so update these places to make use
+ of FAIL instead. And last but not least adjust the final summary just
+ to report completion, with any error count following as reported by
+ the test driver.
+
+- test-tgmath2: no update to FAIL calls required, with the name of the
+ file of the failure site additionally included by the new FAIL test
+ failure helper. Also there is no need to track the return status by
+ hand as any call to FAIL will eventually cause the test case to return
+ an unsuccesful exit status regardless of the return status from the
+ test function, via a call to 'adjust_exit_status' made by the test
+ driver.
+
+Reviewed-by: DJ Delorie <dj@redhat.com>
+(cherry picked from commit 1b97a9f23bf605ca608162089c94187573fb2a9e)
+---
+ localedata/tst-ctype.c | 40 +++++++++-------------------------------
+ math/test-tgmath2.c | 13 +++----------
+ support/check.h | 5 +++++
+ 3 files changed, 17 insertions(+), 41 deletions(-)
+
+diff --git a/localedata/tst-ctype.c b/localedata/tst-ctype.c
+index 098bf51335..355b666866 100644
+--- a/localedata/tst-ctype.c
++++ b/localedata/tst-ctype.c
+@@ -21,6 +21,8 @@
+ #include <stdio.h>
+ #include <string.h>
+
++#include <support/check.h>
++
+
+ static const char lower[] = "abcdefghijklmnopqrstuvwxyz";
+ static const char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+@@ -53,19 +55,11 @@ static struct classes
+ #define nclasses (sizeof (classes) / sizeof (classes[0]))
+
+
+-#define FAIL(str, args...) \
+- { \
+- printf (" " str "\n", ##args); \
+- ++errors; \
+- }
+-
+-
+ static int
+ do_test (void)
+ {
+ const char *cp;
+ const char *cp2;
+- int errors = 0;
+ char *inpline = NULL;
+ size_t inplinelen = 0;
+ char *resline = NULL;
+@@ -394,11 +388,8 @@ punct = %04x alnum = %04x\n",
+ {
+ if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0)
+ != (*resp != '0'))
+- {
+- printf (" is%s('%c' = '\\x%02x') %s true\n", inpline,
+- *inp, *inp, *resp == '1' ? "not" : "is");
+- ++errors;
+- }
++ FAIL (" is%s('%c' = '\\x%02x') %s true\n", inpline,
++ *inp, *inp, *resp == '1' ? "not" : "is");
+ ++inp;
+ ++resp;
+ }
+@@ -408,11 +399,8 @@ punct = %04x alnum = %04x\n",
+ while (*inp != '\0')
+ {
+ if (tolower (*inp) != *resp)
+- {
+- printf (" tolower('%c' = '\\x%02x') != '%c'\n",
+- *inp, *inp, *resp);
+- ++errors;
+- }
++ FAIL (" tolower('%c' = '\\x%02x') != '%c'\n",
++ *inp, *inp, *resp);
+ ++inp;
+ ++resp;
+ }
+@@ -422,11 +410,8 @@ punct = %04x alnum = %04x\n",
+ while (*inp != '\0')
+ {
+ if (toupper (*inp) != *resp)
+- {
+- printf (" toupper('%c' = '\\x%02x') != '%c'\n",
+- *inp, *inp, *resp);
+- ++errors;
+- }
++ FAIL (" toupper('%c' = '\\x%02x') != '%c'\n",
++ *inp, *inp, *resp);
+ ++inp;
+ ++resp;
+ }
+@@ -436,14 +421,7 @@ punct = %04x alnum = %04x\n",
+ }
+
+
+- if (errors != 0)
+- {
+- printf (" %d error%s for `%s' locale\n\n\n", errors,
+- errors == 1 ? "" : "s", setlocale (LC_ALL, NULL));
+- return 1;
+- }
+-
+- printf (" No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
++ printf ("Completed testing for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
+ return 0;
+ }
+
+diff --git a/math/test-tgmath2.c b/math/test-tgmath2.c
+index 6dd0d64da5..deba439e0c 100644
+--- a/math/test-tgmath2.c
++++ b/math/test-tgmath2.c
+@@ -24,6 +24,8 @@
+ #include <string.h>
+ #include <tgmath.h>
+
++#include <support/check.h>
++
+ //#define DEBUG
+
+ typedef complex float cfloat;
+@@ -87,13 +89,6 @@ enum
+ int count;
+ int counts[Tlast][C_last];
+
+-#define FAIL(str) \
+- do \
+- { \
+- printf ("%s failure on line %d\n", (str), __LINE__); \
+- result = 1; \
+- } \
+- while (0)
+ #define TEST_TYPE_ONLY(expr, rettype) \
+ do \
+ { \
+@@ -133,8 +128,6 @@ int counts[Tlast][C_last];
+ int
+ test_cos (const int Vint4, const long long int Vllong4)
+ {
+- int result = 0;
+-
+ TEST (cos (vfloat1), float, cos);
+ TEST (cos (vdouble1), double, cos);
+ TEST (cos (vldouble1), ldouble, cos);
+@@ -152,7 +145,7 @@ test_cos (const int Vint4, const long long int Vllong4)
+ TEST (cos (Vcdouble1), cdouble, cos);
+ TEST (cos (Vcldouble1), cldouble, cos);
+
+- return result;
++ return 0;
+ }
+
+ int
+diff --git a/support/check.h b/support/check.h
+index e6ae39f1a1..0a9fff484f 100644
+--- a/support/check.h
++++ b/support/check.h
+@@ -24,6 +24,11 @@
+
+ __BEGIN_DECLS
+
++/* Record a test failure, print the failure message to standard output
++ and pass the result of 1 through. */
++#define FAIL(...) \
++ support_print_failure_impl (__FILE__, __LINE__, __VA_ARGS__)
++
+ /* Record a test failure, print the failure message to standard output
+ and return 1. */
+ #define FAIL_RET(...) \
+--
+2.33.0
+
diff --git a/sysdeps-sem_open-Clear-O_CREAT-when-semaphore-file-i.patch b/sysdeps-sem_open-Clear-O_CREAT-when-semaphore-file-i.patch
new file mode 100644
index 0000000..1ca450d
--- /dev/null
+++ b/sysdeps-sem_open-Clear-O_CREAT-when-semaphore-file-i.patch
@@ -0,0 +1,105 @@
+From 63dbbc5c52f9823f86270f32fce20d1e91cdf484 Mon Sep 17 00:00:00 2001
+From: Sergio Durigan Junior <sergiodj@sergiodj.net>
+Date: Wed, 1 Nov 2023 18:15:23 -0400
+Subject: [PATCH] sysdeps: sem_open: Clear O_CREAT when semaphore file is
+ expected to exist [BZ #30789]
+
+When invoking sem_open with O_CREAT as one of its flags, we'll end up
+in the second part of sem_open's "if ((oflag & O_CREAT) == 0 || (oflag
+& O_EXCL) == 0)", which means that we don't expect the semaphore file
+to exist.
+
+In that part, open_flags is initialized as "O_RDWR | O_CREAT | O_EXCL
+| O_CLOEXEC" and there's an attempt to open(2) the file, which will
+likely fail because it won't exist. After that first (expected)
+failure, some cleanup is done and we go back to the label "try_again",
+which lives in the first part of the aforementioned "if".
+
+The problem is that, in that part of the code, we expect the semaphore
+file to exist, and as such O_CREAT (this time the flag we pass to
+open(2)) needs to be cleaned from open_flags, otherwise we'll see
+another failure (this time unexpected) when trying to open the file,
+which will lead the call to sem_open to fail as well.
+
+This can cause very strange bugs, especially with OpenMPI, which makes
+extensive use of semaphores.
+
+Fix the bug by simplifying the logic when choosing open(2) flags and
+making sure O_CREAT is not set when the semaphore file is expected to
+exist.
+
+A regression test for this issue would require a complex and cpu time
+consuming logic, since to trigger the wrong code path is not
+straightforward due the racy condition. There is a somewhat reliable
+reproducer in the bug, but it requires using OpenMPI.
+
+This resolves BZ #30789.
+
+See also: https://bugs.launchpad.net/ubuntu/+source/h5py/+bug/2031912
+
+Signed-off-by: Sergio Durigan Junior <sergiodj@sergiodj.net>
+Co-Authored-By: Simon Chopin <simon.chopin@canonical.com>
+Co-Authored-By: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
+Fixes: 533deafbdf189f5fbb280c28562dd43ace2f4b0f ("Use O_CLOEXEC in more places (BZ #15722)")
+(cherry picked from commit f957f47df75b9fab995754011491edebc6feb147)
+---
+ NEWS | 2 ++
+ sysdeps/pthread/sem_open.c | 10 ++++------
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index f117874e34..5ac488bf9b 100644
+--- a/NEWS
++++ b/NEWS
+@@ -32,6 +32,8 @@ Security related changes:
+ The following bugs are resolved with this release:
+
+ [30723] posix_memalign repeatedly scans long bin lists
++ [30789] sem_open will fail on multithreaded scenarios when semaphore
++ file doesn't exist (O_CREAT)
+ [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+ -D_FILE_OFFSET_BITS=64
+ [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
+diff --git a/sysdeps/pthread/sem_open.c b/sysdeps/pthread/sem_open.c
+index e5db929d20..0e331a7445 100644
+--- a/sysdeps/pthread/sem_open.c
++++ b/sysdeps/pthread/sem_open.c
+@@ -32,11 +32,12 @@
+ # define __unlink unlink
+ #endif
+
++#define SEM_OPEN_FLAGS (O_RDWR | O_NOFOLLOW | O_CLOEXEC)
++
+ sem_t *
+ __sem_open (const char *name, int oflag, ...)
+ {
+ int fd;
+- int open_flags;
+ sem_t *result;
+
+ /* Check that shared futexes are supported. */
+@@ -65,10 +66,8 @@ __sem_open (const char *name, int oflag, ...)
+ /* If the semaphore object has to exist simply open it. */
+ if ((oflag & O_CREAT) == 0 || (oflag & O_EXCL) == 0)
+ {
+- open_flags = O_RDWR | O_NOFOLLOW | O_CLOEXEC;
+- open_flags |= (oflag & ~(O_CREAT|O_ACCMODE));
+ try_again:
+- fd = __open (dirname.name, open_flags);
++ fd = __open (dirname.name, (oflag & O_EXCL) | SEM_OPEN_FLAGS);
+
+ if (fd == -1)
+ {
+@@ -135,8 +134,7 @@ __sem_open (const char *name, int oflag, ...)
+ }
+
+ /* Open the file. Make sure we do not overwrite anything. */
+- open_flags = O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC;
+- fd = __open (tmpfname, open_flags, mode);
++ fd = __open (tmpfname, O_CREAT | O_EXCL | SEM_OPEN_FLAGS, mode);
+ if (fd == -1)
+ {
+ if (errno == EEXIST)
+--
+2.33.0
+
diff --git a/testsuite_whitelist b/testsuite_whitelist
new file mode 100644
index 0000000..b99f3d5
--- /dev/null
+++ b/testsuite_whitelist
@@ -0,0 +1,129 @@
+# USAGE:
+# If it's a generic error:
+# testsuite
+# If the test case fails on part of the architecture:
+# testsuite:arch1,arch2
+
+# These test cases failed due to gcc_secure
+conform/ISO/setjmp.h/conform
+conform/ISO/stdlib.h/conform
+conform/ISO/stdlib.h/linknamespace
+conform/ISO/string.h/conform
+conform/ISO11/setjmp.h/conform
+conform/ISO11/stdio.h/conform
+conform/ISO11/stdlib.h/conform
+conform/ISO11/stdlib.h/linknamespace
+conform/ISO11/string.h/conform
+conform/ISO11/wchar.h/conform
+conform/ISO99/setjmp.h/conform
+conform/ISO99/stdio.h/conform
+conform/ISO99/stdlib.h/conform
+conform/ISO99/stdlib.h/linknamespace
+conform/ISO99/string.h/conform
+conform/ISO99/wchar.h/conform
+conform/POSIX/stdlib.h/conform
+conform/POSIX/stdlib.h/linknamespace
+conform/POSIX/string.h/conform
+conform/POSIX2008/fcntl.h/conform
+conform/POSIX2008/mqueue.h/conform
+conform/POSIX2008/stdio.h/conform
+conform/POSIX2008/stdlib.h/conform
+conform/POSIX2008/stdlib.h/linknamespace
+conform/POSIX2008/wchar.h/conform
+conform/UNIX98/stdlib.h/conform
+conform/UNIX98/string.h/conform
+conform/UNIX98/unistd.h/conform
+conform/UNIX98/unistd.h/linknamespace
+conform/UNIX98/wchar.h/conform
+conform/XOPEN2K/fcntl.h/conform
+conform/XOPEN2K/mqueue.h/conform
+conform/XOPEN2K/stdio.h/conform
+conform/XOPEN2K/stdlib.h/conform
+conform/XOPEN2K/string.h/conform
+conform/XOPEN2K/syslog.h/conform
+conform/XOPEN2K/unistd.h/conform
+conform/XOPEN2K/unistd.h/linknamespace
+conform/XOPEN2K/wchar.h/conform
+conform/XOPEN2K8/fcntl.h/conform
+conform/XOPEN2K8/mqueue.h/conform
+conform/XOPEN2K8/stdio.h/conform
+conform/XOPEN2K8/stdlib.h/conform
+conform/XOPEN2K8/syslog.h/conform
+conform/XOPEN2K8/unistd.h/conform
+conform/XOPEN2K8/unistd.h/linknamespace
+conform/XOPEN2K8/wchar.h/conform
+conform/XPG4/stdlib.h/conform
+conform/XPG4/stdlib.h/linknamespace
+conform/XPG4/string.h/conform
+conform/XPG4/unistd.h/conform
+conform/XPG42/stdlib.h/conform
+conform/XPG42/string.h/conform
+conform/XPG42/unistd.h/conform
+elf/circleload1
+elf/constload1
+elf/dblload
+elf/dblunload
+elf/ifuncmain6pie:x86_64
+elf/lateglobal
+elf/reldep6
+elf/resolvfail
+elf/tst-global1
+elf/tst-tls20
+nptl/tst-execstack
+
+# GCC no longer implements <varargs.h>
+conform/UNIX98/varargs.h/conform
+conform/UNIX98/varargs.h/linknamespace
+conform/XPG4/varargs.h/conform
+conform/XPG4/varargs.h/linknamespace
+conform/XPG42/varargs.h/conform
+conform/XPG42/varargs.h/linknamespace
+
+# These cases depend on gdbm-devel
+conform/UNIX98/ndbm.h/conform
+conform/UNIX98/ndbm.h/linknamespace
+conform/XOPEN2K/ndbm.h/conform
+conform/XOPEN2K/ndbm.h/linknamespace
+conform/XOPEN2K8/ndbm.h/conform
+conform/XOPEN2K8/ndbm.h/linknamespace
+conform/XPG42/ndbm.h/conform
+conform/XPG42/ndbm.h/linknamespace
+
+# Test whether the date/time is correct under different
+# language libraries, use case problems, and see that
+# the compiled language library itself has no errors
+# https://sourceware.org/bugzilla/show_bug.cgi?id=23164
+localedata/tst-langinfo-newlocale-static
+
+# The use case itself passed but because
+# test-xfail-tst-protected1a/test-xfail-tst-protected1b was added
+elf/tst-protected1a
+elf/tst-protected1b
+
+# the test case is due to check whether a macro is defined
+# in the header files. As GLIBC evolves, the position of the
+# macro changes, causing the use case to fail
+posix/annexc
+
+# Check whether sys/mman.h is consistent with linux/mman.h.
+# kernel has a self-developed macro that does not require glibc adaptation
+# https://gitee.com/src-openeuler/kernel/issues/I4BZ9T?from=project-issue
+misc/tst-mman-consts
+
+# It need to build GliBC on a platform that supports CET
+elf/check-cet:x86_64
+
+# Add the tst-nss-files-hosts-long.root/etc/hosts of glibc to
+# the /etc/hosts directory of the system, and then run sucess
+nss/tst-nss-files-hosts-long
+
+# The test case fails due to OBS machine restrictions which can be passed locally.
+elf/tst-debug1:aarch64
+
+# This test case often fails in CI which is the high-pressure environment.
+# No better solution is available. This test case is shielded.
+rt/tst-cpuclock2
+
+# These testcase fails because rseq is disabled by default
+misc/tst-rseq-nptl
+misc/tst-rseq
diff --git a/turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch b/turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
new file mode 100644
index 0000000..e9e053d
--- /dev/null
+++ b/turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
@@ -0,0 +1,29 @@
+From 4dee2794b8c78ccd540e3f72bc07585828e0143b Mon Sep 17 00:00:00 2001
+From: Yang Yanchao <yangyanchao6@huawei.com>
+Date: Thu, 2 Dec 2021 19:56:20 +0800
+Subject: [PATCH] turn the default value of x86_rep_stosb_threshold from 2k to 1M
+
+x86_rep_stosb_threshold is designed to choose vec mov or stosb.
+For the libMicro, after set this x86_rep_stosb_threshold to 1 MB.
+The performance of memset_256_u, memset_4k_uc, and memset_1m is improved.
+The performance deteriorates in the memset_4k and memset_10k scenarios.
+---
+ sysdeps/x86/dl-tunables.list | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sysdeps/x86/dl-tunables.list b/sysdeps/x86/dl-tunables.list
+index dd6e1d65..a4c3af69 100644
+--- a/sysdeps/x86/dl-tunables.list
++++ b/sysdeps/x86/dl-tunables.list
+@@ -54,7 +54,7 @@ glibc {
+ # stored value is fixed, larger register size has minimal impact
+ # on threshold.
+ minval: 1
+- default: 2048
++ default: 1048576
+ }
+ x86_data_cache_size {
+ type: SIZE_T
+--
+2.30.0
+
diff --git a/ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch b/ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch
new file mode 100644
index 0000000..9faa58c
--- /dev/null
+++ b/ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch
@@ -0,0 +1,145 @@
+From b9f72bd5de931eac39219018c2fa319a449bb2cf Mon Sep 17 00:00:00 2001
+From: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date: Tue, 13 Aug 2024 21:08:49 -0400
+Subject: [PATCH] ungetc: Fix backup buffer leak on program exit [BZ
+ #27821]
+
+If a file descriptor is left unclosed and is cleaned up by _IO_cleanup
+on exit, its backup buffer remains unfreed, registering as a leak in
+valgrind. This is not strictly an issue since (1) the program should
+ideally be closing the stream once it's not in use and (2) the program
+is about to exit anyway, so keeping the backup buffer around a wee bit
+longer isn't a real problem. Free it anyway to keep valgrind happy
+when the streams in question are the standard ones, i.e. stdout, stdin
+or stderr.
+
+Also, the _IO_have_backup macro checks for _IO_save_base,
+which is a roundabout way to check for a backup buffer instead of
+directly looking for _IO_backup_base. The roundabout check breaks when
+the main get area has not been used and user pushes a char into the
+backup buffer with ungetc. Fix this to use the _IO_backup_base
+directly.
+
+Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 3e1d8d1d1dca24ae90df2ea826a8916896fc7e77)
+---
+ libio/genops.c | 6 ++++++
+ libio/libioP.h | 4 ++--
+ stdio-common/Makefile | 7 +++++++
+ stdio-common/tst-ungetc-leak.c | 32 ++++++++++++++++++++++++++++++++
+ 4 files changed, 47 insertions(+), 2 deletions(-)
+ create mode 100644 stdio-common/tst-ungetc-leak.c
+
+diff --git a/libio/genops.c b/libio/genops.c
+index c673c0acec..fb06245467 100644
+--- a/libio/genops.c
++++ b/libio/genops.c
+@@ -789,6 +789,12 @@ _IO_unbuffer_all (void)
+ legacy = 1;
+ #endif
+
++ /* Free up the backup area if it was ever allocated. */
++ if (_IO_have_backup (fp))
++ _IO_free_backup_area (fp);
++ if (fp->_mode > 0 && _IO_have_wbackup (fp))
++ _IO_free_wbackup_area (fp);
++
+ if (! (fp->_flags & _IO_UNBUFFERED)
+ /* Iff stream is un-orientated, it wasn't used. */
+ && (legacy || fp->_mode != 0))
+diff --git a/libio/libioP.h b/libio/libioP.h
+index 745278e076..e75ee770bc 100644
+--- a/libio/libioP.h
++++ b/libio/libioP.h
+@@ -577,8 +577,8 @@ extern void _IO_old_init (FILE *fp, int flags) __THROW;
+ ((__fp)->_wide_data->_IO_write_base \
+ = (__fp)->_wide_data->_IO_write_ptr = __p, \
+ (__fp)->_wide_data->_IO_write_end = (__ep))
+-#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL)
+-#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL)
++#define _IO_have_backup(fp) ((fp)->_IO_backup_base != NULL)
++#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_backup_base != NULL)
+ #define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP)
+ #define _IO_have_markers(fp) ((fp)->_markers != NULL)
+ #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
+diff --git a/stdio-common/Makefile b/stdio-common/Makefile
+index 2bcbaf754a..381040570b 100644
+--- a/stdio-common/Makefile
++++ b/stdio-common/Makefile
+@@ -256,6 +256,7 @@ tests := \
+ tst-swscanf \
+ tst-tmpnam \
+ tst-ungetc \
++ tst-ungetc-leak \
+ tst-unlockedio \
+ tst-vfprintf-mbs-prec \
+ tst-vfprintf-user-type \
+@@ -300,6 +301,7 @@ tests-special += \
+ $(objpfx)tst-printfsz-islongdouble.out \
+ $(objpfx)tst-setvbuf1-cmp.out \
+ $(objpfx)tst-unbputc.out \
++ $(objpfx)tst-ungetc-leak-mem.out \
+ $(objpfx)tst-vfprintf-width-prec-mem.out \
+ # tests-special
+
+@@ -314,6 +316,8 @@ generated += \
+ tst-printf-fp-leak-mem.out \
+ tst-printf-fp-leak.mtrace \
+ tst-scanf-bz27650.mtrace \
++ tst-ungetc-leak-mem.out \
++ tst-ungetc-leak.mtrace \
+ tst-vfprintf-width-prec-mem.out \
+ tst-vfprintf-width-prec.mtrace \
+ # generated
+@@ -403,6 +407,9 @@ tst-printf-fp-leak-ENV = \
+ tst-scanf-bz27650-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
++tst-ungetc-leak-ENV = \
++ MALLOC_TRACE=$(objpfx)tst-ungetc-leak.mtrace \
++ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+
+ $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
+ $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
+diff --git a/stdio-common/tst-ungetc-leak.c b/stdio-common/tst-ungetc-leak.c
+new file mode 100644
+index 0000000000..6c5152b43f
+--- /dev/null
++++ b/stdio-common/tst-ungetc-leak.c
+@@ -0,0 +1,32 @@
++/* Test for memory leak with ungetc when stream is unused.
++ Copyright The GNU Toolchain Authors.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <mcheck.h>
++#include <support/check.h>
++#include <support/support.h>
++
++static int
++do_test (void)
++{
++ mtrace ();
++ TEST_COMPARE (ungetc('y', stdin), 'y');
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.33.0
+
diff --git a/ungetc-Fix-uninitialized-read-when-putting-into-unus.patch b/ungetc-Fix-uninitialized-read-when-putting-into-unus.patch
new file mode 100644
index 0000000..405239f
--- /dev/null
+++ b/ungetc-Fix-uninitialized-read-when-putting-into-unus.patch
@@ -0,0 +1,78 @@
+From 804d3c8db79db204154dcf5e11a76f14fdddc570 Mon Sep 17 00:00:00 2001
+From: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date: Tue, 13 Aug 2024 21:00:06 -0400
+Subject: [PATCH] ungetc: Fix uninitialized read when putting into unused
+ streams [BZ #27821]
+
+When ungetc is called on an unused stream, the backup buffer is
+allocated without the main get area being present. This results in
+every subsequent ungetc (as the stream remains in the backup area)
+checking uninitialized memory in the backup buffer when trying to put a
+character back into the stream.
+
+Avoid comparing the input character with buffer contents when in backup
+to avoid this uninitialized read. The uninitialized read is harmless in
+this context since the location is promptly overwritten with the input
+character, thus fulfilling ungetc functionality.
+
+Also adjust wording in the manual to drop the paragraph that says glibc
+cannot do multiple ungetc back to back since with this change, ungetc
+can actually do this.
+
+Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit cdf0f88f97b0aaceb894cc02b21159d148d7065c)
+---
+ libio/genops.c | 2 +-
+ manual/stdio.texi | 8 +++-----
+ stdio-common/tst-ungetc.c | 2 ++
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/libio/genops.c b/libio/genops.c
+index fbd8dd9e75..c673c0acec 100644
+--- a/libio/genops.c
++++ b/libio/genops.c
+@@ -635,7 +635,7 @@ _IO_sputbackc (FILE *fp, int c)
+ {
+ int result;
+
+- if (fp->_IO_read_ptr > fp->_IO_read_base
++ if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
+ && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
+ {
+ fp->_IO_read_ptr--;
+diff --git a/manual/stdio.texi b/manual/stdio.texi
+index 9cf622403f..a54cd369db 100644
+--- a/manual/stdio.texi
++++ b/manual/stdio.texi
+@@ -1474,11 +1474,9 @@ program; usually @code{ungetc} is used only to unread a character that
+ was just read from the same stream. @Theglibc{} supports this
+ even on files opened in binary mode, but other systems might not.
+
+-@Theglibc{} only supports one character of pushback---in other
+-words, it does not work to call @code{ungetc} twice without doing input
+-in between. Other systems might let you push back multiple characters;
+-then reading from the stream retrieves the characters in the reverse
+-order that they were pushed.
++@Theglibc{} supports pushing back multiple characters; subsequently
++reading from the stream retrieves the characters in the reverse order
++that they were pushed.
+
+ Pushing back characters doesn't alter the file; only the internal
+ buffering for the stream is affected. If a file positioning function
+diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c
+index 5c808f0734..388b202493 100644
+--- a/stdio-common/tst-ungetc.c
++++ b/stdio-common/tst-ungetc.c
+@@ -48,6 +48,8 @@ do_test (void)
+ TEST_VERIFY_EXIT (getc (fp) == 'b');
+ TEST_VERIFY_EXIT (getc (fp) == 'l');
+ TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
++ TEST_VERIFY_EXIT (ungetc ('n', fp) == 'n');
++ TEST_VERIFY_EXIT (getc (fp) == 'n');
+ TEST_VERIFY_EXIT (getc (fp) == 'm');
+ TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
+ TEST_VERIFY_EXIT (getc (fp) == EOF);
+--
+2.33.0
+
diff --git a/use-region-to-instead-of-country-for-extract-timezon.patch b/use-region-to-instead-of-country-for-extract-timezon.patch
new file mode 100644
index 0000000..7e8eb07
--- /dev/null
+++ b/use-region-to-instead-of-country-for-extract-timezon.patch
@@ -0,0 +1,152 @@
+From 1c20cf491471a4a70f103a9d052fcca993eaa341 Mon Sep 17 00:00:00 2001
+From: Qingqing Li <liqingqing3@huawei.com>
+Date: Tue, 22 Feb 2022 15:00:55 +0800
+Subject: [PATCH] use region to instead of country for extract timezone
+ selection.
+Co-authored-by: liusirui <liusirui@huawei.com>
+---
+ timezone/tzselect.ksh | 97 +++++++++----------------------------------
+ 1 file changed, 20 insertions(+), 77 deletions(-)
+
+diff --git a/timezone/tzselect.ksh b/timezone/tzselect.ksh
+index 18fce27e..414bfa2a 100755
+--- a/timezone/tzselect.ksh
++++ b/timezone/tzselect.ksh
+@@ -51,7 +51,7 @@ say() {
+
+ coord=
+ location_limit=10
+-zonetabtype=zone1970
++zonetabtype=zone
+
+ usage="Usage: tzselect [--version] [--help] [-c COORD] [-n LIMIT]
+ Select a timezone interactively.
+@@ -398,94 +398,38 @@ while
+ '`
+ ;;
+ *)
+- # Get list of names of countries in the continent or ocean.
+- countries=`$AWK \
++ # Get list of regions in the continent or ocean.
++ timezones=`$AWK \
+ -v continent="$continent" \
+ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+ '
+ BEGIN { FS = "\t" }
+ /^#/ { next }
+ $3 ~ ("^" continent "/") {
+- ncc = split($1, cc, /,/)
++ ncc = split($3, cc, /,/)
+ for (i = 1; i <= ncc; i++)
+ if (!cc_seen[cc[i]]++) cc_list[++ccs] = cc[i]
+ }
+ END {
+- while (getline <TZ_COUNTRY_TABLE) {
+- if ($0 !~ /^#/) cc_name[$1] = $2
+- }
+ for (i = 1; i <= ccs; i++) {
+- country = cc_list[i]
+- if (cc_name[country]) {
+- country = cc_name[country]
+- }
+- print country
++ print cc_list[i]
+ }
+ }
+ ' <"$TZ_ZONE_TABLE" | sort -f`
+
+-
+- # If there's more than one country, ask the user which one.
+- case $countries in
+- *"$newline"*)
+- echo >&2 'Please select a country' \
+- 'whose clocks agree with yours.'
+- doselect $countries
+- country=$select_result;;
+- *)
+- country=$countries
+- esac
+-
+-
+- # Get list of timezones in the country.
+- regions=`$AWK \
+- -v country="$country" \
+- -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+- '
+- BEGIN {
+- FS = "\t"
+- cc = country
+- while (getline <TZ_COUNTRY_TABLE) {
+- if ($0 !~ /^#/ && country == $2) {
+- cc = $1
+- break
+- }
+- }
+- }
+- /^#/ { next }
+- $1 ~ cc { print $4 }
+- ' <"$TZ_ZONE_TABLE"`
+-
+-
+- # If there's more than one region, ask the user which one.
+- case $regions in
+- *"$newline"*)
+- echo >&2 'Please select one of the following timezones.'
+- doselect $regions
+- region=$select_result;;
+- *)
+- region=$regions
+- esac
++ regions=[]
++ index=0
++ for item in $timezones; do
++ regions[$index]=`echo $item | awk -F '/' '{print $2}'`
++ index=$(($index+1))
++ done
++ echo >&2 'Please select a timezone' \
++ 'whose clocks agree with yours.'
++ doselect ${regions[@]}
++ region=$select_result
+
+ # Determine TZ from country and region.
+- TZ=`$AWK \
+- -v country="$country" \
+- -v region="$region" \
+- -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+- '
+- BEGIN {
+- FS = "\t"
+- cc = country
+- while (getline <TZ_COUNTRY_TABLE) {
+- if ($0 !~ /^#/ && country == $2) {
+- cc = $1
+- break
+- }
+- }
+- }
+- /^#/ { next }
+- $1 ~ cc && $4 == region { print $3 }
+- ' <"$TZ_ZONE_TABLE"`
++ TZ=$continent/$region
+ esac
+
+ # Make sure the corresponding zoneinfo file exists.
+@@ -523,11 +467,10 @@ Universal Time is now: $UTdate."
+ echo >&2 ""
+ echo >&2 "The following information has been given:"
+ echo >&2 ""
+- case $country%$region%$coord in
+- ?*%?*%) say >&2 " $country$newline $region";;
+- ?*%%) say >&2 " $country";;
+- %?*%?*) say >&2 " coord $coord$newline $region";;
+- %%?*) say >&2 " coord $coord";;
++ case $region%$coord in
++ ?*%) say >&2 " $region";;
++ ?*%?*) say >&2 " coord $coord$newline $region";;
++ %?*) say >&2 " coord $coord";;
+ *) say >&2 " TZ='$TZ'"
+ esac
+ say >&2 ""
+--
+2.27.0
+
diff --git a/x86-64-Fix-the-dtv-field-load-for-x32-BZ-31184.patch b/x86-64-Fix-the-dtv-field-load-for-x32-BZ-31184.patch
new file mode 100644
index 0000000..c55bdf9
--- /dev/null
+++ b/x86-64-Fix-the-dtv-field-load-for-x32-BZ-31184.patch
@@ -0,0 +1,68 @@
+From 35ea7549751d4f13a28c732e6ad68204f5e60a06 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Wed, 20 Dec 2023 16:31:43 -0800
+Subject: [PATCH 4/9] x86-64: Fix the dtv field load for x32 [BZ #31184]
+
+On x32, I got
+
+FAIL: elf/tst-tlsgap
+
+$ gdb elf/tst-tlsgap
+...
+open tst-tlsgap-mod1.so
+
+Thread 2 "tst-tlsgap" received signal SIGSEGV, Segmentation fault.
+[Switching to LWP 2268754]
+_dl_tlsdesc_dynamic () at ../sysdeps/x86_64/dl-tlsdesc.S:108
+108 movq (%rsi), %rax
+(gdb) p/x $rsi
+$4 = 0xf7dbf9005655fb18
+(gdb)
+
+This is caused by
+
+_dl_tlsdesc_dynamic:
+ _CET_ENDBR
+ /* Preserve call-clobbered registers that we modify.
+ We need two scratch regs anyway. */
+ movq %rsi, -16(%rsp)
+ movq %fs:DTV_OFFSET, %rsi
+
+Since the dtv field in TCB is a pointer, %fs:DTV_OFFSET is a 32-bit
+location, not 64-bit. Load the dtv field to RSI_LP instead of rsi.
+This fixes BZ #31184.
+
+(cherry picked from commit 3502440397bbb840e2f7223734aa5cc2cc0e29b6)
+---
+ NEWS | 1 +
+ sysdeps/x86_64/dl-tlsdesc.S | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/NEWS b/NEWS
+index 5ac488bf9b..71057e4793 100644
+--- a/NEWS
++++ b/NEWS
+@@ -37,6 +37,7 @@ The following bugs are resolved with this release:
+ [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+ -D_FILE_OFFSET_BITS=64
+ [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
++ [31184] FAIL: elf/tst-tlsgap
+
+
+ Version 2.38
+diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S
+index 5593897e29..c4823547d7 100644
+--- a/sysdeps/x86_64/dl-tlsdesc.S
++++ b/sysdeps/x86_64/dl-tlsdesc.S
+@@ -102,7 +102,7 @@ _dl_tlsdesc_dynamic:
+ /* Preserve call-clobbered registers that we modify.
+ We need two scratch regs anyway. */
+ movq %rsi, -16(%rsp)
+- movq %fs:DTV_OFFSET, %rsi
++ mov %fs:DTV_OFFSET, %RSI_LP
+ movq %rdi, -8(%rsp)
+ movq TLSDESC_ARG(%rax), %rdi
+ movq (%rsi), %rax
+--
+2.33.0
+
diff --git a/x86-64-Fix-the-tcb-field-load-for-x32-BZ-31185.patch b/x86-64-Fix-the-tcb-field-load-for-x32-BZ-31185.patch
new file mode 100644
index 0000000..515db6d
--- /dev/null
+++ b/x86-64-Fix-the-tcb-field-load-for-x32-BZ-31185.patch
@@ -0,0 +1,69 @@
+From 968c983d43bc51f719f3e7a0fcb1bb8669b5f7c4 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Wed, 20 Dec 2023 19:42:12 -0800
+Subject: [PATCH 5/9] x86-64: Fix the tcb field load for x32 [BZ #31185]
+
+_dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic access the thread pointer
+via the tcb field in TCB:
+
+_dl_tlsdesc_undefweak:
+ _CET_ENDBR
+ movq 8(%rax), %rax
+ subq %fs:0, %rax
+ ret
+
+_dl_tlsdesc_dynamic:
+ ...
+ subq %fs:0, %rax
+ movq -8(%rsp), %rdi
+ ret
+
+Since the tcb field in TCB is a pointer, %fs:0 is a 32-bit location,
+not 64-bit. It should use "sub %fs:0, %RAX_LP" instead. Since
+_dl_tlsdesc_undefweak returns ptrdiff_t and _dl_make_tlsdesc_dynamic
+returns void *, RAX_LP is appropriate here for x32 and x86-64. This
+fixes BZ #31185.
+
+(cherry picked from commit 81be2a61dafc168327c1639e97b6dae128c7ccf3)
+---
+ NEWS | 1 +
+ sysdeps/x86_64/dl-tlsdesc.S | 4 ++--
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 71057e4793..6fbb8a9e1d 100644
+--- a/NEWS
++++ b/NEWS
+@@ -38,6 +38,7 @@ The following bugs are resolved with this release:
+ -D_FILE_OFFSET_BITS=64
+ [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
+ [31184] FAIL: elf/tst-tlsgap
++ [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
+
+
+ Version 2.38
+diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S
+index c4823547d7..4579424bf7 100644
+--- a/sysdeps/x86_64/dl-tlsdesc.S
++++ b/sysdeps/x86_64/dl-tlsdesc.S
+@@ -61,7 +61,7 @@ _dl_tlsdesc_return:
+ _dl_tlsdesc_undefweak:
+ _CET_ENDBR
+ movq 8(%rax), %rax
+- subq %fs:0, %rax
++ sub %fs:0, %RAX_LP
+ ret
+ cfi_endproc
+ .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
+@@ -116,7 +116,7 @@ _dl_tlsdesc_dynamic:
+ addq TLSDESC_MODOFF(%rdi), %rax
+ .Lret:
+ movq -16(%rsp), %rsi
+- subq %fs:0, %rax
++ sub %fs:0, %RAX_LP
+ movq -8(%rsp), %rdi
+ ret
+ .Lslow:
+--
+2.33.0
+
diff --git a/x86-Fix-bug-in-strchrnul-evex512-BZ-32078.patch b/x86-Fix-bug-in-strchrnul-evex512-BZ-32078.patch
new file mode 100644
index 0000000..85af57b
--- /dev/null
+++ b/x86-Fix-bug-in-strchrnul-evex512-BZ-32078.patch
@@ -0,0 +1,162 @@
+From c005d1bd6f0e88ab4b822844d75d10c8978f5404 Mon Sep 17 00:00:00 2001
+From: Noah Goldstein <goldstein.w.n@gmail.com>
+Date: Tue, 13 Aug 2024 23:29:14 +0800
+Subject: [PATCH] x86: Fix bug in strchrnul-evex512 [BZ #32078]
+
+Issue was we were expecting not matches with CHAR before the start of
+the string in the page cross case.
+
+The check code in the page cross case:
+```
+ and $0xffffffffffffffc0,%rax
+ vmovdqa64 (%rax),%zmm17
+ vpcmpneqb %zmm17,%zmm16,%k1
+ vptestmb %zmm17,%zmm17,%k0{%k1}
+ kmovq %k0,%rax
+ inc %rax
+ shr %cl,%rax
+ je L(continue)
+```
+
+expects that all characters that neither match null nor CHAR will be
+1s in `rax` prior to the `inc`. Then the `inc` will overflow all of
+the 1s where no relevant match was found.
+
+This is incorrect in the page-cross case, as the
+`vmovdqa64 (%rax),%zmm17` loads from before the start of the input
+string.
+
+If there are matches with CHAR before the start of the string, `rax`
+won't properly overflow.
+
+The fix is quite simple. Just replace:
+
+```
+ inc %rax
+ shr %cl,%rax
+```
+With:
+```
+ sar %cl,%rax
+ inc %rax
+```
+
+The arithmetic shift will clear any matches prior to the start of the
+string while maintaining the signbit so the 1s can properly overflow
+to zero in the case of no matches.
+Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+
+(cherry picked from commit 7da08862471dfec6fdae731c2a5f351ad485c71f)
+---
+ string/test-strchr.c | 65 ++++++++++++++++++++-
+ sysdeps/x86_64/multiarch/strchr-evex-base.S | 8 +--
+ 2 files changed, 68 insertions(+), 5 deletions(-)
+
+diff --git a/string/test-strchr.c b/string/test-strchr.c
+index 933fc0bbba..2bfcf901fa 100644
+--- a/string/test-strchr.c
++++ b/string/test-strchr.c
+@@ -248,6 +248,69 @@ check1 (void)
+ check_result (impl, s, c, exp_result);
+ }
+
++static void
++check2 (void)
++{
++ CHAR *s = (CHAR *) (buf1 + getpagesize () - 4 * sizeof (CHAR));
++ CHAR *s_begin = (CHAR *) (buf1 + getpagesize () - 64);
++#ifndef USE_FOR_STRCHRNUL
++ CHAR *exp_result = NULL;
++#else
++ CHAR *exp_result = s + 1;
++#endif
++ CHAR val = 0x12;
++ for (; s_begin != s; ++s_begin)
++ *s_begin = val;
++
++ s[0] = val + 1;
++ s[1] = 0;
++ s[2] = val + 1;
++ s[3] = val + 1;
++
++ {
++ FOR_EACH_IMPL (impl, 0)
++ check_result (impl, s, val, exp_result);
++ }
++ s[3] = val;
++ {
++ FOR_EACH_IMPL (impl, 0)
++ check_result (impl, s, val, exp_result);
++ }
++ exp_result = s;
++ s[0] = val;
++ {
++ FOR_EACH_IMPL (impl, 0)
++ check_result (impl, s, val, exp_result);
++ }
++
++ s[3] = val + 1;
++ {
++ FOR_EACH_IMPL (impl, 0)
++ check_result (impl, s, val, exp_result);
++ }
++
++ s[0] = val + 1;
++ s[1] = val + 1;
++ s[2] = val + 1;
++ s[3] = val + 1;
++ s[4] = val;
++ exp_result = s + 4;
++ {
++ FOR_EACH_IMPL (impl, 0)
++ check_result (impl, s, val, exp_result);
++ }
++ s[4] = 0;
++#ifndef USE_FOR_STRCHRNUL
++ exp_result = NULL;
++#else
++ exp_result = s + 4;
++#endif
++ {
++ FOR_EACH_IMPL (impl, 0)
++ check_result (impl, s, val, exp_result);
++ }
++}
++
+ int
+ test_main (void)
+ {
+@@ -256,7 +319,7 @@ test_main (void)
+ test_init ();
+
+ check1 ();
+-
++ check2 ();
+ printf ("%20s", "");
+ FOR_EACH_IMPL (impl, 0)
+ printf ("\t%s", impl->name);
+diff --git a/sysdeps/x86_64/multiarch/strchr-evex-base.S b/sysdeps/x86_64/multiarch/strchr-evex-base.S
+index 7209435caf..da6d0eafbb 100644
+--- a/sysdeps/x86_64/multiarch/strchr-evex-base.S
++++ b/sysdeps/x86_64/multiarch/strchr-evex-base.S
+@@ -124,13 +124,13 @@ L(page_cross):
+ VPCMPNE %VMM(1), %VMM(0), %k1
+ VPTEST %VMM(1), %VMM(1), %k0{%k1}
+ KMOV %k0, %VRAX
+-# ifdef USE_AS_WCSCHR
++ sar %cl, %VRAX
++#ifdef USE_AS_WCSCHR
+ sub $VEC_MATCH_MASK, %VRAX
+-# else
++#else
+ inc %VRAX
+-# endif
++#endif
+ /* Ignore number of character for alignment adjustment. */
+- shr %cl, %VRAX
+ jz L(align_more)
+
+ bsf %VRAX, %VRAX
+--
+2.33.0
+
diff --git a/x86_64-Optimize-ffsll-function-code-size.patch b/x86_64-Optimize-ffsll-function-code-size.patch
new file mode 100644
index 0000000..e5531b5
--- /dev/null
+++ b/x86_64-Optimize-ffsll-function-code-size.patch
@@ -0,0 +1,50 @@
+From 30e546d76e756fe4d2d20a8b2286de4fbf30ceb5 Mon Sep 17 00:00:00 2001
+From: Sunil K Pandey <skpgkp2@gmail.com>
+Date: Wed, 26 Jul 2023 08:34:05 -0700
+Subject: [PATCH 1/6] x86_64: Optimize ffsll function code size.
+
+Ffsll function randomly regress by ~20%, depending on how code gets
+aligned in memory. Ffsll function code size is 17 bytes. Since default
+function alignment is 16 bytes, it can load on 16, 32, 48 or 64 bytes
+aligned memory. When ffsll function load at 16, 32 or 64 bytes aligned
+memory, entire code fits in single 64 bytes cache line. When ffsll
+function load at 48 bytes aligned memory, it splits in two cache line,
+hence random regression.
+
+Ffsll function size reduction from 17 bytes to 12 bytes ensures that it
+will always fit in single 64 bytes cache line.
+
+This patch fixes ffsll function random performance regression.
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 9d94997b5f9445afd4f2bccc5fa60ff7c4361ec1)
+---
+ sysdeps/x86_64/ffsll.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/sysdeps/x86_64/ffsll.c b/sysdeps/x86_64/ffsll.c
+index a1c13d4906..0c6680735c 100644
+--- a/sysdeps/x86_64/ffsll.c
++++ b/sysdeps/x86_64/ffsll.c
+@@ -26,13 +26,13 @@ int
+ ffsll (long long int x)
+ {
+ long long int cnt;
+- long long int tmp;
+
+- asm ("bsfq %2,%0\n" /* Count low bits in X and store in %1. */
+- "cmoveq %1,%0\n" /* If number was zero, use -1 as result. */
+- : "=&r" (cnt), "=r" (tmp) : "rm" (x), "1" (-1));
++ asm ("mov $-1,%k0\n" /* Initialize cnt to -1. */
++ "bsf %1,%0\n" /* Count low bits in x and store in cnt. */
++ "inc %k0\n" /* Increment cnt by 1. */
++ : "=&r" (cnt) : "r" (x));
+
+- return cnt + 1;
++ return cnt;
+ }
+
+ #ifndef __ILP32__
+--
+2.33.0
+