diff options
author | CoprDistGit <infra@openeuler.org> | 2024-10-09 03:36:26 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-10-09 03:36:26 +0000 |
commit | db43dfdfa8bc2b938582aef3d87e43594c13ee50 (patch) | |
tree | 47b95b2f6ac8d8b7e6fa373a5bd7d661bf7234df | |
parent | b933872de72b006230559f77acc3ccfb38a1f343 (diff) |
automatic import of glibcopeneuler20.03
157 files changed, 30999 insertions, 0 deletions
@@ -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, ¬found, sizeof (notfound), MSG_NOSIGNAL)); ++ return -1; ++} ++ + /* Sends a notfound message and prepares a notfound dataset to write to the + cache. Returns true if there was enough memory to allocate the dataset and + returns the dataset in DATASETP, total bytes to write in TOTALP and the +@@ -83,8 +94,7 @@ do_notfound (struct database_dyn *db, int fd, request_header *req, + total = sizeof (notfound); + timeout = time (NULL) + db->negtimeout; + +- if (fd != -1) +- TEMP_FAILURE_RETRY (send (fd, ¬found, total, MSG_NOSIGNAL)); ++ send_notfound (fd); + + dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1); + /* If we cannot permanently store the result, so be it. */ +@@ -109,11 +119,78 @@ do_notfound (struct database_dyn *db, int fd, request_header *req, + return cacheable; + } + ++struct addgetnetgrentX_scratch ++{ ++ /* This is the result that the caller should use. It can be NULL, ++ point into buffer, or it can be in the cache. */ ++ struct dataset *dataset; ++ ++ struct scratch_buffer buffer; ++ ++ /* Used internally in addgetnetgrentX as a staging area. */ ++ struct scratch_buffer tmp; ++ ++ /* Number of bytes in buffer that are actually used. */ ++ size_t buffer_used; ++}; ++ ++static void ++addgetnetgrentX_scratch_init (struct addgetnetgrentX_scratch *scratch) ++{ ++ scratch->dataset = NULL; ++ scratch_buffer_init (&scratch->buffer); ++ scratch_buffer_init (&scratch->tmp); ++ ++ /* Reserve space for the header. */ ++ scratch->buffer_used = sizeof (struct dataset); ++ static_assert (sizeof (struct dataset) < sizeof (scratch->tmp.__space), ++ "initial buffer space"); ++ memset (scratch->tmp.data, 0, sizeof (struct dataset)); ++} ++ ++static void ++addgetnetgrentX_scratch_free (struct addgetnetgrentX_scratch *scratch) ++{ ++ scratch_buffer_free (&scratch->buffer); ++ scratch_buffer_free (&scratch->tmp); ++} ++ ++/* Copy LENGTH bytes from S into SCRATCH. Returns NULL if SCRATCH ++ could not be resized, otherwise a pointer to the copy. */ ++static char * ++addgetnetgrentX_append_n (struct addgetnetgrentX_scratch *scratch, ++ const char *s, size_t length) ++{ ++ while (true) ++ { ++ size_t remaining = scratch->buffer.length - scratch->buffer_used; ++ if (remaining >= length) ++ break; ++ if (!scratch_buffer_grow_preserve (&scratch->buffer)) ++ return NULL; ++ } ++ char *copy = scratch->buffer.data + scratch->buffer_used; ++ memcpy (copy, s, length); ++ scratch->buffer_used += length; ++ return copy; ++} ++ ++/* Copy S into SCRATCH, including its null terminator. Returns false ++ if SCRATCH could not be resized. */ ++static bool ++addgetnetgrentX_append (struct addgetnetgrentX_scratch *scratch, const char *s) ++{ ++ if (s == NULL) ++ s = ""; ++ return addgetnetgrentX_append_n (scratch, s, strlen (s) + 1) != NULL; ++} ++ ++/* Caller must initialize and free *SCRATCH. If the return value is ++ negative, this function has sent a notfound response. */ + static time_t + addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + const char *key, uid_t uid, struct hashentry *he, +- struct datahead *dh, struct dataset **resultp, +- void **tofreep) ++ struct datahead *dh, struct addgetnetgrentX_scratch *scratch) + { + if (__glibc_unlikely (debug_level > 0)) + { +@@ -132,14 +209,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + + char *key_copy = NULL; + struct __netgrent data; +- size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len); +- size_t buffilled = sizeof (*dataset); +- char *buffer = NULL; + size_t nentries = 0; + size_t group_len = strlen (key) + 1; + struct name_list *first_needed + = alloca (sizeof (struct name_list) + group_len); +- *tofreep = NULL; + + if (netgroup_database == NULL + && !__nss_database_get (nss_database_netgroup, &netgroup_database)) +@@ -151,8 +224,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + } + + memset (&data, '\0', sizeof (data)); +- buffer = xmalloc (buflen); +- *tofreep = buffer; + first_needed->next = first_needed; + memcpy (first_needed->name, key, group_len); + data.needed_groups = first_needed; +@@ -195,8 +266,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + while (1) + { + int e; +- status = getfct.f (&data, buffer + buffilled, +- buflen - buffilled - req->key_len, &e); ++ status = getfct.f (&data, scratch->tmp.data, ++ scratch->tmp.length, &e); + if (status == NSS_STATUS_SUCCESS) + { + if (data.type == triple_val) +@@ -204,68 +275,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + const char *nhost = data.val.triple.host; + const char *nuser = data.val.triple.user; + const char *ndomain = data.val.triple.domain; +- +- size_t hostlen = strlen (nhost ?: "") + 1; +- size_t userlen = strlen (nuser ?: "") + 1; +- size_t domainlen = strlen (ndomain ?: "") + 1; +- +- if (nhost == NULL || nuser == NULL || ndomain == NULL +- || nhost > nuser || nuser > ndomain) +- { +- const char *last = nhost; +- if (last == NULL +- || (nuser != NULL && nuser > last)) +- last = nuser; +- if (last == NULL +- || (ndomain != NULL && ndomain > last)) +- last = ndomain; +- +- size_t bufused +- = (last == NULL +- ? buffilled +- : last + strlen (last) + 1 - buffer); +- +- /* We have to make temporary copies. */ +- size_t needed = hostlen + userlen + domainlen; +- +- if (buflen - req->key_len - bufused < needed) +- { +- buflen += MAX (buflen, 2 * needed); +- /* Save offset in the old buffer. We don't +- bother with the NULL check here since +- we'll do that later anyway. */ +- size_t nhostdiff = nhost - buffer; +- size_t nuserdiff = nuser - buffer; +- size_t ndomaindiff = ndomain - buffer; +- +- char *newbuf = xrealloc (buffer, buflen); +- /* Fix up the triplet pointers into the new +- buffer. */ +- nhost = (nhost ? newbuf + nhostdiff +- : NULL); +- nuser = (nuser ? newbuf + nuserdiff +- : NULL); +- ndomain = (ndomain ? newbuf + ndomaindiff +- : NULL); +- *tofreep = buffer = newbuf; +- } +- +- nhost = memcpy (buffer + bufused, +- nhost ?: "", hostlen); +- nuser = memcpy ((char *) nhost + hostlen, +- nuser ?: "", userlen); +- ndomain = memcpy ((char *) nuser + userlen, +- ndomain ?: "", domainlen); +- } +- +- char *wp = buffer + buffilled; +- wp = memmove (wp, nhost ?: "", hostlen); +- wp += hostlen; +- wp = memmove (wp, nuser ?: "", userlen); +- wp += userlen; +- wp = memmove (wp, ndomain ?: "", domainlen); +- wp += domainlen; +- buffilled = wp - buffer; ++ if (!(addgetnetgrentX_append (scratch, nhost) ++ && addgetnetgrentX_append (scratch, nuser) ++ && addgetnetgrentX_append (scratch, ndomain))) ++ return send_notfound (fd); + ++nentries; + } + else +@@ -317,8 +330,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + } + else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE) + { +- buflen *= 2; +- *tofreep = buffer = xrealloc (buffer, buflen); ++ if (!scratch_buffer_grow (&scratch->tmp)) ++ return send_notfound (fd); + } + else if (status == NSS_STATUS_RETURN + || status == NSS_STATUS_NOTFOUND +@@ -351,10 +364,17 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + goto maybe_cache_add; + } + +- total = buffilled; ++ /* Capture the result size without the key appended. */ ++ total = scratch->buffer_used; ++ ++ /* Make a copy of the key. The scratch buffer must not move after ++ this point. */ ++ key_copy = addgetnetgrentX_append_n (scratch, key, req->key_len); ++ if (key_copy == NULL) ++ return send_notfound (fd); + + /* Fill in the dataset. */ +- dataset = (struct dataset *) buffer; ++ dataset = scratch->buffer.data; + timeout = datahead_init_pos (&dataset->head, total + req->key_len, + total - offsetof (struct dataset, resp), + he == NULL ? 0 : dh->nreloads + 1, +@@ -363,11 +383,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + dataset->resp.version = NSCD_VERSION; + dataset->resp.found = 1; + dataset->resp.nresults = nentries; +- dataset->resp.result_len = buffilled - sizeof (*dataset); +- +- assert (buflen - buffilled >= req->key_len); +- key_copy = memcpy (buffer + buffilled, key, req->key_len); +- buffilled += req->key_len; ++ dataset->resp.result_len = total - sizeof (*dataset); + + /* Now we can determine whether on refill we have to create a new + record or not. */ +@@ -398,7 +414,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + if (__glibc_likely (newp != NULL)) + { + /* Adjust pointer into the memory block. */ +- key_copy = (char *) newp + (key_copy - buffer); ++ key_copy = (char *) newp + (key_copy - (char *) dataset); + + dataset = memcpy (newp, dataset, total + req->key_len); + cacheable = true; +@@ -439,7 +455,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + } + + out: +- *resultp = dataset; ++ scratch->dataset = dataset; + + return timeout; + } +@@ -460,6 +476,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + if (user != NULL) + key = strchr (key, '\0') + 1; + const char *domain = *key++ ? key : NULL; ++ struct addgetnetgrentX_scratch scratch; ++ ++ addgetnetgrentX_scratch_init (&scratch); + + if (__glibc_unlikely (debug_level > 0)) + { +@@ -475,12 +494,8 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + group, group_len, + db, uid); + time_t timeout; +- void *tofree; + if (result != NULL) +- { +- timeout = result->head.timeout; +- tofree = NULL; +- } ++ timeout = result->head.timeout; + else + { + request_header req_get = +@@ -489,7 +504,10 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + .key_len = group_len + }; + timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL, +- &result, &tofree); ++ &scratch); ++ result = scratch.dataset; ++ if (timeout < 0) ++ goto out; + } + + struct indataset +@@ -603,7 +621,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + } + + out: +- free (tofree); ++ addgetnetgrentX_scratch_free (&scratch); + return timeout; + } + +@@ -613,11 +631,12 @@ addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req, + const char *key, uid_t uid, struct hashentry *he, + struct datahead *dh) + { +- struct dataset *ignore; +- void *tofree; +- time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, +- &ignore, &tofree); +- free (tofree); ++ struct addgetnetgrentX_scratch scratch; ++ addgetnetgrentX_scratch_init (&scratch); ++ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, &scratch); ++ addgetnetgrentX_scratch_free (&scratch); ++ if (timeout < 0) ++ timeout = 0; + return timeout; + } + +@@ -661,5 +680,9 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he, + .key_len = he->len + }; + +- return addinnetgrX (db, -1, &req, db->data + he->key, he->owner, he, dh); ++ int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner, ++ he, dh); ++ if (timeout < 0) ++ timeout = 0; ++ return timeout; + } +-- +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() @@ -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 + |