Compare commits
No commits in common. "glibc-2.28-236.0.1.an8.12" and "a23.1" have entirely different histories.
glibc-2.28
...
a23.1
921 changed files with 15372 additions and 213071 deletions
|
@ -1,36 +1,40 @@
|
|||
commit bd77dd7e73e3530203be1c52c8a29d08270cb25d
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Sep 13 14:10:56 2023 +0200
|
||||
From 4ea972b7edd7e36610e8cde18bf7a8149d7bac4f 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
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Fixes commit f282cdbe7f436c75864e5640a4 ("resolv: Implement no-aaaa
|
||||
stub resolver option") and bug 30842.
|
||||
|
||||
Conflicts:
|
||||
resolv/nss_dns/dns-host.c
|
||||
(missing dns_packet_buffer cleanup downstream)
|
||||
(cherry picked from commit bd77dd7e73e3530203be1c52c8a29d08270cb25d)
|
||||
---
|
||||
resolv/Makefile | 2 +
|
||||
resolv/nss_dns/dns-host.c | 2 +-
|
||||
resolv/tst-resolv-noaaaa-vc.c | 129 ++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 139 insertions(+), 1 deletion(-)
|
||||
create mode 100644 resolv/tst-resolv-noaaaa-vc.c
|
||||
|
||||
diff --git a/resolv/Makefile b/resolv/Makefile
|
||||
index ab8ad49b5318ad41..4f4eaf060443c128 100644
|
||||
index f8a92c6cff..28cedf49ee 100644
|
||||
--- a/resolv/Makefile
|
||||
+++ b/resolv/Makefile
|
||||
@@ -58,6 +58,7 @@ tests += \
|
||||
tst-resolv-edns \
|
||||
@@ -101,6 +101,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 \
|
||||
@@ -202,6 +203,7 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
|
||||
$(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \
|
||||
@@ -291,6 +292,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)
|
||||
|
@ -38,21 +42,21 @@ index ab8ad49b5318ad41..4f4eaf060443c128 100644
|
|||
$(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 ff0a0b6f7f1f4703..f678c7d7caa3a026 100644
|
||||
index 9fa81f23c8..227734da5c 100644
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ b/resolv/nss_dns/dns-host.c
|
||||
@@ -392,7 +392,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
|
||||
else
|
||||
@@ -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,
|
||||
- host_buffer.buf->buf, 2048, NULL,
|
||||
+ host_buffer.buf->buf, 2048, &host_buffer.ptr,
|
||||
NULL, NULL, NULL, NULL);
|
||||
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 (host_buffer.buf, n,
|
||||
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 0000000000000000..9f5aebd99f2d74a2
|
||||
index 0000000000..9f5aebd99f
|
||||
--- /dev/null
|
||||
+++ b/resolv/tst-resolv-noaaaa-vc.c
|
||||
@@ -0,0 +1,129 @@
|
||||
|
@ -185,3 +189,6 @@ index 0000000000000000..9f5aebd99f2d74a2
|
|||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
--
|
||||
2.39.3
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
Avoid UAF in getcanonname (CVE-2023-4806)
|
||||
From a9728f798ec7f05454c95637ee6581afaa9b487d Mon Sep 17 00:00:00 2001
|
||||
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Fri, 15 Sep 2023 13:51:12 -0400
|
||||
Subject: [PATCH] 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
|
||||
|
@ -17,60 +21,39 @@ 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. This is a minimal
|
||||
RHEL-8-specific fix. Test case differences from upstream:
|
||||
resolves BZ #30843, which is assigned CVE-2023-4806.
|
||||
|
||||
- The test module needs to explicitly link against libnss_files on
|
||||
RHEL-8; upstream libnss_files is built into libc.so.
|
||||
|
||||
- Test module code was adapted to not use the upstream NSS module
|
||||
convenience macros.
|
||||
|
||||
This change is adapted from the following commit from upstream:
|
||||
|
||||
commit 973fe93a5675c42798b2161c6f29c01b0e243994
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Fri Sep 15 13:51:12 2023 -0400
|
||||
|
||||
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>
|
||||
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 cfb255c6e7a3a4de..5829a2539306ddb5 100644
|
||||
index a978e3927a..f0af87e6f1 100644
|
||||
--- a/nss/Makefile
|
||||
+++ b/nss/Makefile
|
||||
@@ -66,7 +66,8 @@ xtests = bug-erange
|
||||
tests-container = \
|
||||
tst-nss-db-endpwent \
|
||||
tst-nss-db-endgrent \
|
||||
- tst-nss-gai-actions
|
||||
+ tst-nss-gai-actions \
|
||||
+ tst-nss-gai-hv2-canonname
|
||||
@@ -81,6 +81,7 @@ tests-container := \
|
||||
tst-nss-test3 \
|
||||
tst-reload1 \
|
||||
tst-reload2 \
|
||||
+ tst-nss-gai-hv2-canonname \
|
||||
# tests-container
|
||||
|
||||
# Tests which need libdl
|
||||
ifeq (yes,$(build-shared))
|
||||
@@ -132,7 +133,8 @@ routines += $(libnss_files-routines)
|
||||
static-only-routines += $(libnss_files-routines)
|
||||
@@ -144,7 +145,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
|
||||
|
@ -79,7 +62,7 @@ index cfb255c6e7a3a4de..5829a2539306ddb5 100644
|
|||
|
||||
include ../Rules
|
||||
|
||||
@@ -169,12 +171,17 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
|
||||
@@ -179,12 +181,16 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
|
||||
libof-nss_test1 = extramodules
|
||||
libof-nss_test2 = extramodules
|
||||
libof-nss_test_errno = extramodules
|
||||
|
@ -91,34 +74,38 @@ index cfb255c6e7a3a4de..5829a2539306ddb5 100644
|
|||
$(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) \
|
||||
+ $(objpfx)/libnss_files.so
|
||||
+ $(objpfx)nss_test_gai_hv2_canonname.os $(link-libc-deps)
|
||||
+ $(build-module)
|
||||
$(objpfx)nss_test2.os : nss_test1.c
|
||||
ifdef libnss_test1.so-version
|
||||
$(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so
|
||||
@@ -187,10 +194,14 @@ endif
|
||||
# Use the nss_files suffix for these objects as well.
|
||||
$(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so
|
||||
@@ -194,10 +200,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)) : \
|
||||
$(objpfx)/libnss_test1.so$(libnss_test1.so-version) \
|
||||
$(objpfx)/libnss_test2.so$(libnss_test2.so-version) \
|
||||
$(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)
|
||||
@@ -214,3 +224,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 0000000000000000..4195d7d24fdd5f6d
|
||||
index 0000000000..4439c83c9f
|
||||
--- /dev/null
|
||||
+++ b/nss/nss_test_gai_hv2_canonname.c
|
||||
@@ -0,0 +1,64 @@
|
||||
@@ -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.
|
||||
|
@ -137,7 +124,6 @@ index 0000000000000000..4195d7d24fdd5f6d
|
|||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <netdb.h>
|
||||
+#include <nss.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
|
@ -145,20 +131,13 @@ index 0000000000000000..4195d7d24fdd5f6d
|
|||
+
|
||||
+/* 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 *, int, struct hostent
|
||||
+ *, char *, size_t, int *, int *);
|
||||
+
|
||||
+enum nss_status
|
||||
+_nss_test_gai_hv2_canonname_getcanonname_r (const char *, char *, size_t, char
|
||||
+ **, 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,
|
||||
|
@ -185,7 +164,7 @@ index 0000000000000000..4195d7d24fdd5f6d
|
|||
+}
|
||||
diff --git a/nss/tst-nss-gai-hv2-canonname.c b/nss/tst-nss-gai-hv2-canonname.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d5f10c07d6a90773
|
||||
index 0000000000..d5f10c07d6
|
||||
--- /dev/null
|
||||
+++ b/nss/tst-nss-gai-hv2-canonname.c
|
||||
@@ -0,0 +1,63 @@
|
||||
|
@ -254,61 +233,86 @@ index 0000000000000000..d5f10c07d6a90773
|
|||
+#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 0000000000000000..14f2a9cb0867dff9
|
||||
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 0000000000000000..e69de29bb2d1d643
|
||||
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 0000000000000000..31848b4a28524af6
|
||||
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 4fa963644af8b7d5..46046504a6858f2e 100644
|
||||
index 5cda9bb072..7a43a3bf4c 100644
|
||||
--- a/sysdeps/posix/getaddrinfo.c
|
||||
+++ b/sysdeps/posix/getaddrinfo.c
|
||||
@@ -233,7 +233,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||
@@ -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;
|
||||
|
||||
*result = array;
|
||||
@@ -287,6 +286,18 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||
} \
|
||||
*pat = addrmem; \
|
||||
\
|
||||
+ /* Store h_name so that it survives accidental deallocation when \
|
||||
+ gethosts is called again and tmpbuf gets reallocated. */ \
|
||||
+ if (h_name == NULL && th.h_name != NULL) \
|
||||
+ { \
|
||||
+ h_name = __strdup (th.h_name); \
|
||||
+ if (h_name == NULL) \
|
||||
+ { \
|
||||
+ __resolv_context_put (res_ctx); \
|
||||
+ result = -EAI_SYSTEM; \
|
||||
+ goto free_and_return; \
|
||||
+ } \
|
||||
+ } \
|
||||
if (localcanon != NULL && canon == NULL) \
|
||||
{ \
|
||||
canonbuf = __strdup (localcanon); \
|
||||
@@ -323,15 +334,15 @@ typedef enum nss_status (*nss_getcanonname_r)
|
||||
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 (service_user *nip, struct gaih_addrtuple *at, const char *name)
|
||||
+getcanonname (service_user *nip, const char *hname, const char *name)
|
||||
-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");
|
||||
nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
|
||||
char *s = (char *) name;
|
||||
if (cfct != NULL)
|
||||
{
|
||||
|
@ -320,28 +324,15 @@ index 4fa963644af8b7d5..46046504a6858f2e 100644
|
|||
/* If the canonical name cannot be determined, use the passed
|
||||
string. */
|
||||
s = (char *) name;
|
||||
@@ -349,6 +360,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
struct gaih_addrtuple *at = NULL;
|
||||
bool got_ipv6 = false;
|
||||
const char *canon = NULL;
|
||||
+ char *h_name = NULL;
|
||||
const char *orig_name = name;
|
||||
|
||||
/* Reserve stack memory for the scratch buffer in the getaddrinfo
|
||||
@@ -919,7 +931,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
if ((req->ai_flags & AI_CANONNAME) != 0
|
||||
&& canon == NULL)
|
||||
{
|
||||
- canonbuf = getcanonname (nip, at, name);
|
||||
+ canonbuf = getcanonname (nip, h_name, name);
|
||||
if (canonbuf == NULL)
|
||||
{
|
||||
__resolv_context_enable_inet6
|
||||
@@ -1169,6 +1181,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
free ((char *) name);
|
||||
free (addrmem);
|
||||
free (canonbuf);
|
||||
+ free (h_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -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.39.3
|
||||
|
98
0085-CVE-2023-5156.patch
Normal file
98
0085-CVE-2023-5156.patch
Normal file
|
@ -0,0 +1,98 @@
|
|||
From 856bac55f98dc840e7c27cfa82262b933385de90 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] 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 f0af87e6f1..7a52c68791 100644
|
||||
--- a/nss/Makefile
|
||||
+++ b/nss/Makefile
|
||||
@@ -148,6 +148,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))
|
||||
@@ -216,6 +225,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 7a43a3bf4c..f975dcd2bc 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.39.3
|
||||
|
181
0087-CVE-2023-6246.patch
Normal file
181
0087-CVE-2023-6246.patch
Normal file
|
@ -0,0 +1,181 @@
|
|||
From d1a83b6767f68b3cb5b4b4ea2617254acd040c82 Mon Sep 17 00:00:00 2001
|
||||
From: Arjun Shankar <arjun@redhat.com>
|
||||
Date: Mon, 15 Jan 2024 17:44:43 +0100
|
||||
Subject: [PATCH] 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 ba8232a0e9..66e9ded8f9 100644
|
||||
--- a/misc/Makefile
|
||||
+++ b/misc/Makefile
|
||||
@@ -115,7 +115,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)
|
||||
@@ -175,6 +178,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 f67d4b58a4..fe1daf988b 100644
|
||||
--- a/misc/syslog.c
|
||||
+++ b/misc/syslog.c
|
||||
@@ -122,8 +122,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;
|
||||
|
||||
@@ -175,29 +176,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.39.3
|
||||
|
106
0088-CVE-2023-6779.patch
Normal file
106
0088-CVE-2023-6779.patch
Normal file
|
@ -0,0 +1,106 @@
|
|||
From 2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 Mon Sep 17 00:00:00 2001
|
||||
From: Arjun Shankar <arjun@redhat.com>
|
||||
Date: Mon, 15 Jan 2024 17:44:44 +0100
|
||||
Subject: [PATCH] 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 fe1daf988b..3108ae9134 100644
|
||||
--- a/misc/syslog.c
|
||||
+++ b/misc/syslog.c
|
||||
@@ -183,11 +183,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. */
|
||||
@@ -213,12 +215,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)
|
||||
@@ -229,25 +234,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.39.3
|
||||
|
41
0089-CVE-2023-6780.patch
Normal file
41
0089-CVE-2023-6780.patch
Normal file
|
@ -0,0 +1,41 @@
|
|||
From b9b7d6a27aa0632f334352fa400771115b3c69b7 Mon Sep 17 00:00:00 2001
|
||||
From: Arjun Shankar <arjun@redhat.com>
|
||||
Date: Mon, 15 Jan 2024 17:44:45 +0100
|
||||
Subject: [PATCH] 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 3108ae9134..9336036666 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 */
|
||||
@@ -217,7 +218,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.39.3
|
||||
|
213
0090-CVE-2024-2961.patch
Normal file
213
0090-CVE-2024-2961.patch
Normal file
|
@ -0,0 +1,213 @@
|
|||
From f9dc609e06b1136bb0408be9605ce7973a767ada Mon Sep 17 00:00:00 2001
|
||||
From: Charles Fol <folcharles@gmail.com>
|
||||
Date: Thu, 28 Mar 2024 12:25:38 -0300
|
||||
Subject: [PATCH] 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>
|
||||
---
|
||||
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 ea019ce5c0..7196a8744b 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 b34c8a36f4..cce29b1969 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.39.3
|
|
@ -1,38 +1,18 @@
|
|||
This patch was developed under embargo and cannot reference an upstream
|
||||
commit. To find the associated commit please review the upstream git
|
||||
log for CVE-2023-4911 to identify the relevant commits.
|
||||
From 27e06a423cf06845a0515ab767a109b31b34724a Mon Sep 17 00:00:00 2001
|
||||
From: Chunmei Xu <xuchunmei@linux.alibaba.com>
|
||||
Date: Tue, 5 Mar 2024 14:12:15 +0800
|
||||
Subject: [PATCH 1/1] fix CVE-2023-4911
|
||||
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Tue Sep 19 18:39:32 2023 -0400
|
||||
|
||||
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>
|
||||
|
||||
Conflicts:
|
||||
NEWS
|
||||
(Dropped)
|
||||
elf/tst-env-setuid-tunables.c
|
||||
(Trivial conflict at HAVE_TUNABLES)
|
||||
---
|
||||
elf/dl-tunables.c | 16 ++++++++-------
|
||||
elf/tst-env-setuid-tunables.c | 37 +++++++++++++++++++++++++++--------
|
||||
2 files changed, 38 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
|
||||
index 3c84809d44381241..2c878e08ea197b29 100644
|
||||
index 62b7332d..0edfade8 100644
|
||||
--- a/elf/dl-tunables.c
|
||||
+++ b/elf/dl-tunables.c
|
||||
@@ -193,11 +193,7 @@ parse_tunables (char *tunestr, char *valstring)
|
||||
@@ -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')
|
||||
|
@ -45,7 +25,7 @@ index 3c84809d44381241..2c878e08ea197b29 100644
|
|||
|
||||
/* We did not find a valid name-value pair before encountering the
|
||||
colon. */
|
||||
@@ -257,9 +253,16 @@ parse_tunables (char *tunestr, char *valstring)
|
||||
@@ -244,9 +240,15 @@ parse_tunables (char *tunestr, char *valstring)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +34,6 @@ index 3c84809d44381241..2c878e08ea197b29 100644
|
|||
+ /* We reached the end while processing the tunable string. */
|
||||
+ if (p[len] == '\0')
|
||||
+ break;
|
||||
+
|
||||
+ p += len + 1;
|
||||
}
|
||||
+
|
||||
|
@ -62,13 +41,13 @@ index 3c84809d44381241..2c878e08ea197b29 100644
|
|||
+ if (__libc_enable_secure)
|
||||
+ tunestr[off] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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 0b9b075c40598c6f..8b0861c4ad853040 100644
|
||||
index 7dfb0e07..2364d162 100644
|
||||
--- a/elf/tst-env-setuid-tunables.c
|
||||
+++ b/elf/tst-env-setuid-tunables.c
|
||||
@@ -52,6 +52,8 @@ const char *teststrings[] =
|
||||
@@ -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",
|
||||
|
@ -77,7 +56,7 @@ index 0b9b075c40598c6f..8b0861c4ad853040 100644
|
|||
"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",
|
||||
@@ -70,6 +72,8 @@ const char *resultstrings[] =
|
||||
@@ -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",
|
||||
|
@ -86,10 +65,10 @@ index 0b9b075c40598c6f..8b0861c4ad853040 100644
|
|||
"",
|
||||
"",
|
||||
"",
|
||||
@@ -84,11 +88,18 @@ test_child (int off)
|
||||
@@ -81,11 +85,17 @@ test_child (int off)
|
||||
{
|
||||
const char *val = getenv ("GLIBC_TUNABLES");
|
||||
|
||||
#if HAVE_TUNABLES
|
||||
+ printf (" [%d] GLIBC_TUNABLES is %s\n", off, val);
|
||||
+ fflush (stdout);
|
||||
if (val != NULL && strcmp (val, resultstrings[off]) == 0)
|
||||
|
@ -98,27 +77,26 @@ index 0b9b075c40598c6f..8b0861c4ad853040 100644
|
|||
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]);
|
||||
+ off, val, resultstrings[off]);
|
||||
+ else
|
||||
+ printf (" [%d] GLIBC_TUNABLES environment variable absent\n", off);
|
||||
+
|
||||
+ fflush (stdout);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
@@ -117,21 +128,26 @@ do_test (int argc, char **argv)
|
||||
}
|
||||
@@ -106,31 +116,42 @@ 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. */
|
||||
+ through. */
|
||||
+ exit (42);
|
||||
}
|
||||
else
|
||||
{
|
||||
- int ret = 0;
|
||||
-
|
||||
|
||||
/* Spawn tests. */
|
||||
for (int i = 0; i < array_length (teststrings); i++)
|
||||
{
|
||||
|
@ -130,28 +108,32 @@ index 0b9b075c40598c6f..8b0861c4ad853040 100644
|
|||
+ 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;
|
||||
+ }
|
||||
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
int status = support_capture_subprogram_self_sgid (buf);
|
||||
|
||||
@@ -139,9 +155,14 @@ do_test (int argc, char **argv)
|
||||
/* Bail out early if unsupported. */
|
||||
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 ();
|
||||
+ }
|
||||
+ {
|
||||
+ printf (" [%d] child failed with status %d\n", i,
|
||||
+ WEXITSTATUS (status));
|
||||
+ support_record_failure ();
|
||||
+ }
|
||||
}
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.41.0
|
||||
|
6058
ChangeLog.old
6058
ChangeLog.old
File diff suppressed because it is too large
Load diff
40
Decrease-value-of-arch_minimum_kernel-with-LoongArch.patch
Normal file
40
Decrease-value-of-arch_minimum_kernel-with-LoongArch.patch
Normal file
|
@ -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
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From c5de7c407853b807e8d0c764e6325bb1311f39cd Mon Sep 17 00:00:00 2001
|
||||
From: Xing Li <lixing@loongson.cn>
|
||||
Date: Tue, 4 Jul 2023 15:10:03 +0800
|
||||
Subject: [PATCH 2/2] Fix tst-cancel21.c to suit kernel struct sigcontext
|
||||
change. * nptl/tst-cancel21.c
|
||||
|
||||
---
|
||||
nptl/tst-cancel21.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/nptl/tst-cancel21.c b/nptl/tst-cancel21.c
|
||||
index b10fdbc1..a3653f21 100644
|
||||
--- a/nptl/tst-cancel21.c
|
||||
+++ b/nptl/tst-cancel21.c
|
||||
@@ -217,14 +217,14 @@ static int
|
||||
do_test (void)
|
||||
{
|
||||
stack_t ss;
|
||||
- ss.ss_sp = malloc (2 * SIGSTKSZ);
|
||||
+ ss.ss_sp = malloc (4 * SIGSTKSZ);
|
||||
if (ss.ss_sp == NULL)
|
||||
{
|
||||
puts ("failed to allocate alternate stack");
|
||||
return 1;
|
||||
}
|
||||
ss.ss_flags = 0;
|
||||
- ss.ss_size = 2 * SIGSTKSZ;
|
||||
+ ss.ss_size = 4 * SIGSTKSZ;
|
||||
if (sigaltstack (&ss, NULL) < 0)
|
||||
{
|
||||
printf ("sigaltstack failed %m\n");
|
||||
--
|
||||
2.27.0
|
||||
|
499
LoongArch-Add-glibc.cpu.hwcap-support.patch
Normal file
499
LoongArch-Add-glibc.cpu.hwcap-support.patch
Normal file
|
@ -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
|
||||
|
485
LoongArch-Add-ifunc-support-for-memchr-aligned-lsx-l.patch
Normal file
485
LoongArch-Add-ifunc-support-for-memchr-aligned-lsx-l.patch
Normal file
|
@ -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
|
||||
|
946
LoongArch-Add-ifunc-support-for-memcmp-aligned-lsx-l.patch
Normal file
946
LoongArch-Add-ifunc-support-for-memcmp-aligned-lsx-l.patch
Normal file
|
@ -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
|
||||
|
417
LoongArch-Add-ifunc-support-for-memrchr-lsx-lasx.patch
Normal file
417
LoongArch-Add-ifunc-support-for-memrchr-lsx-lasx.patch
Normal file
|
@ -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
|
||||
|
784
LoongArch-Add-ifunc-support-for-memset-aligned-unali.patch
Normal file
784
LoongArch-Add-ifunc-support-for-memset-aligned-unali.patch
Normal file
|
@ -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
|
||||
|
448
LoongArch-Add-ifunc-support-for-rawmemchr-aligned-ls.patch
Normal file
448
LoongArch-Add-ifunc-support-for-rawmemchr-aligned-ls.patch
Normal file
|
@ -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
|
||||
|
499
LoongArch-Add-ifunc-support-for-strcmp-aligned-lsx.patch
Normal file
499
LoongArch-Add-ifunc-support-for-strcmp-aligned-lsx.patch
Normal file
|
@ -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
|
||||
|
1099
LoongArch-Add-ifunc-support-for-strcpy-stpcpy-aligne.patch
Normal file
1099
LoongArch-Add-ifunc-support-for-strcpy-stpcpy-aligne.patch
Normal file
File diff suppressed because it is too large
Load diff
583
LoongArch-Add-ifunc-support-for-strncmp-aligned-lsx.patch
Normal file
583
LoongArch-Add-ifunc-support-for-strncmp-aligned-lsx.patch
Normal file
|
@ -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
|
||||
|
465
LoongArch-Add-ifunc-support-for-strnlen-aligned-lsx-.patch
Normal file
465
LoongArch-Add-ifunc-support-for-strnlen-aligned-lsx-.patch
Normal file
|
@ -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
|
||||
|
670
LoongArch-Add-ifunc-support-for-strrchr-aligned-lsx-.patch
Normal file
670
LoongArch-Add-ifunc-support-for-strrchr-aligned-lsx-.patch
Normal file
|
@ -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
|
||||
|
626
LoongArch-Add-lasx-lsx-support-for-_dl_runtime_profi.patch
Normal file
626
LoongArch-Add-lasx-lsx-support-for-_dl_runtime_profi.patch
Normal file
|
@ -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
|
||||
|
102
LoongArch-Add-minuimum-binutils-required-version.patch
Normal file
102
LoongArch-Add-minuimum-binutils-required-version.patch
Normal file
|
@ -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
|
||||
|
277
LoongArch-Change-loongarch-to-LoongArch-in-comments.patch
Normal file
277
LoongArch-Change-loongarch-to-LoongArch-in-comments.patch
Normal file
|
@ -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
|
||||
|
67
LoongArch-Change-to-put-magic-number-to-.rodata-sect.patch
Normal file
67
LoongArch-Change-to-put-magic-number-to-.rodata-sect.patch
Normal file
|
@ -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
|
||||
|
44
LoongArch-Micro-optimize-LD_PCREL.patch
Normal file
44
LoongArch-Micro-optimize-LD_PCREL.patch
Normal file
|
@ -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
|
||||
|
65
LoongArch-Redefine-macro-LEAF-ENTRY.patch
Normal file
65
LoongArch-Redefine-macro-LEAF-ENTRY.patch
Normal file
|
@ -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
|
||||
|
56
LoongArch-Remove-support-code-for-old-linker-in-star.patch
Normal file
56
LoongArch-Remove-support-code-for-old-linker-in-star.patch
Normal file
|
@ -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
|
||||
|
28
LoongArch-Replace-deprecated-v0-with-a0-to-eliminate.patch
Normal file
28
LoongArch-Replace-deprecated-v0-with-a0-to-eliminate.patch
Normal file
|
@ -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
|
||||
|
81
LoongArch-Unify-Register-Names.patch
Normal file
81
LoongArch-Unify-Register-Names.patch
Normal file
|
@ -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
|
||||
|
24
LoongArch-Update-hwcap.h-to-sync-with-LoongArch-kern.patch
Normal file
24
LoongArch-Update-hwcap.h-to-sync-with-LoongArch-kern.patch
Normal file
|
@ -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
|
||||
|
30
LoongArch-elf-Add-new-LoongArch-reloc-types-109-into.patch
Normal file
30
LoongArch-elf-Add-new-LoongArch-reloc-types-109-into.patch
Normal file
|
@ -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
|
||||
|
528
Loongarch-Add-ifunc-support-and-add-different-versio.patch
Normal file
528
Loongarch-Add-ifunc-support-and-add-different-versio.patch
Normal file
|
@ -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
|
||||
|
2570
Loongarch-Add-ifunc-support-for-memcpy-aligned-unali.patch
Normal file
2570
Loongarch-Add-ifunc-support-for-memcpy-aligned-unali.patch
Normal file
File diff suppressed because it is too large
Load diff
706
Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch
Normal file
706
Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch
Normal file
|
@ -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
|
||||
|
11
README.md
Normal file
11
README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
Anolis OS
|
||||
=======================================
|
||||
# 代码仓库说明
|
||||
## 分支说明
|
||||
>进行代码开发工作时,请注意选择当前版本对应的分支
|
||||
* aX分支为对应大版本的主分支,如a8分支对应当前最新版本
|
||||
* aX.Y分支为对应小版本的维护分支,如a8.2分支对应8.2版本
|
||||
## 开发流程
|
||||
1. 首先fork目标分支到自己的namespace
|
||||
2. 在自己的fork分支上做出修改
|
||||
3. 向对应的仓库中提交merge request,源分支为fork分支
|
478
Revert-LoongArch-Add-glibc.cpu.hwcap-support.patch
Normal file
478
Revert-LoongArch-Add-glibc.cpu.hwcap-support.patch
Normal file
|
@ -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
|
||||
|
496
SUPPORTED
496
SUPPORTED
|
@ -1,496 +0,0 @@
|
|||
# This file names the currently supported and somewhat tested locales.
|
||||
# If you have any additions please file a glibc bug report.
|
||||
SUPPORTED-LOCALES=\
|
||||
C.UTF-8/UTF-8 \
|
||||
aa_DJ.UTF-8/UTF-8 \
|
||||
aa_DJ/ISO-8859-1 \
|
||||
aa_ER/UTF-8 \
|
||||
aa_ER@saaho/UTF-8 \
|
||||
aa_ET/UTF-8 \
|
||||
af_ZA.UTF-8/UTF-8 \
|
||||
af_ZA/ISO-8859-1 \
|
||||
agr_PE/UTF-8 \
|
||||
ak_GH/UTF-8 \
|
||||
am_ET/UTF-8 \
|
||||
an_ES.UTF-8/UTF-8 \
|
||||
an_ES/ISO-8859-15 \
|
||||
anp_IN/UTF-8 \
|
||||
ar_AE.UTF-8/UTF-8 \
|
||||
ar_AE/ISO-8859-6 \
|
||||
ar_BH.UTF-8/UTF-8 \
|
||||
ar_BH/ISO-8859-6 \
|
||||
ar_DZ.UTF-8/UTF-8 \
|
||||
ar_DZ/ISO-8859-6 \
|
||||
ar_EG.UTF-8/UTF-8 \
|
||||
ar_EG/ISO-8859-6 \
|
||||
ar_IN/UTF-8 \
|
||||
ar_IQ.UTF-8/UTF-8 \
|
||||
ar_IQ/ISO-8859-6 \
|
||||
ar_JO.UTF-8/UTF-8 \
|
||||
ar_JO/ISO-8859-6 \
|
||||
ar_KW.UTF-8/UTF-8 \
|
||||
ar_KW/ISO-8859-6 \
|
||||
ar_LB.UTF-8/UTF-8 \
|
||||
ar_LB/ISO-8859-6 \
|
||||
ar_LY.UTF-8/UTF-8 \
|
||||
ar_LY/ISO-8859-6 \
|
||||
ar_MA.UTF-8/UTF-8 \
|
||||
ar_MA/ISO-8859-6 \
|
||||
ar_OM.UTF-8/UTF-8 \
|
||||
ar_OM/ISO-8859-6 \
|
||||
ar_QA.UTF-8/UTF-8 \
|
||||
ar_QA/ISO-8859-6 \
|
||||
ar_SA.UTF-8/UTF-8 \
|
||||
ar_SA/ISO-8859-6 \
|
||||
ar_SD.UTF-8/UTF-8 \
|
||||
ar_SD/ISO-8859-6 \
|
||||
ar_SS/UTF-8 \
|
||||
ar_SY.UTF-8/UTF-8 \
|
||||
ar_SY/ISO-8859-6 \
|
||||
ar_TN.UTF-8/UTF-8 \
|
||||
ar_TN/ISO-8859-6 \
|
||||
ar_YE.UTF-8/UTF-8 \
|
||||
ar_YE/ISO-8859-6 \
|
||||
ayc_PE/UTF-8 \
|
||||
az_AZ/UTF-8 \
|
||||
az_IR/UTF-8 \
|
||||
as_IN/UTF-8 \
|
||||
ast_ES.UTF-8/UTF-8 \
|
||||
ast_ES/ISO-8859-15 \
|
||||
be_BY.UTF-8/UTF-8 \
|
||||
be_BY/CP1251 \
|
||||
be_BY@latin/UTF-8 \
|
||||
bem_ZM/UTF-8 \
|
||||
ber_DZ/UTF-8 \
|
||||
ber_MA/UTF-8 \
|
||||
bg_BG.UTF-8/UTF-8 \
|
||||
bg_BG/CP1251 \
|
||||
bhb_IN.UTF-8/UTF-8 \
|
||||
bho_IN/UTF-8 \
|
||||
bho_NP/UTF-8 \
|
||||
bi_VU/UTF-8 \
|
||||
bn_BD/UTF-8 \
|
||||
bn_IN/UTF-8 \
|
||||
bo_CN/UTF-8 \
|
||||
bo_IN/UTF-8 \
|
||||
br_FR.UTF-8/UTF-8 \
|
||||
br_FR/ISO-8859-1 \
|
||||
br_FR@euro/ISO-8859-15 \
|
||||
brx_IN/UTF-8 \
|
||||
bs_BA.UTF-8/UTF-8 \
|
||||
bs_BA/ISO-8859-2 \
|
||||
byn_ER/UTF-8 \
|
||||
ca_AD.UTF-8/UTF-8 \
|
||||
ca_AD/ISO-8859-15 \
|
||||
ca_ES.UTF-8/UTF-8 \
|
||||
ca_ES/ISO-8859-1 \
|
||||
ca_ES@euro/ISO-8859-15 \
|
||||
ca_ES@valencia/UTF-8 \
|
||||
ca_FR.UTF-8/UTF-8 \
|
||||
ca_FR/ISO-8859-15 \
|
||||
ca_IT.UTF-8/UTF-8 \
|
||||
ca_IT/ISO-8859-15 \
|
||||
ce_RU/UTF-8 \
|
||||
chr_US/UTF-8 \
|
||||
cmn_TW/UTF-8 \
|
||||
crh_UA/UTF-8 \
|
||||
cs_CZ.UTF-8/UTF-8 \
|
||||
cs_CZ/ISO-8859-2 \
|
||||
csb_PL/UTF-8 \
|
||||
cv_RU/UTF-8 \
|
||||
cy_GB.UTF-8/UTF-8 \
|
||||
cy_GB/ISO-8859-14 \
|
||||
da_DK.UTF-8/UTF-8 \
|
||||
da_DK/ISO-8859-1 \
|
||||
da_DK.ISO-8859-15/ISO-8859-15 \
|
||||
de_AT.UTF-8/UTF-8 \
|
||||
de_AT/ISO-8859-1 \
|
||||
de_AT@euro/ISO-8859-15 \
|
||||
de_BE.UTF-8/UTF-8 \
|
||||
de_BE/ISO-8859-1 \
|
||||
de_BE@euro/ISO-8859-15 \
|
||||
de_CH.UTF-8/UTF-8 \
|
||||
de_CH/ISO-8859-1 \
|
||||
de_DE.UTF-8/UTF-8 \
|
||||
de_DE/ISO-8859-1 \
|
||||
de_DE@euro/ISO-8859-15 \
|
||||
de_IT.UTF-8/UTF-8 \
|
||||
de_IT/ISO-8859-1 \
|
||||
de_LI.UTF-8/UTF-8 \
|
||||
de_LU.UTF-8/UTF-8 \
|
||||
de_LU/ISO-8859-1 \
|
||||
de_LU@euro/ISO-8859-15 \
|
||||
doi_IN/UTF-8 \
|
||||
dsb_DE/UTF-8 \
|
||||
dv_MV/UTF-8 \
|
||||
dz_BT/UTF-8 \
|
||||
el_GR.UTF-8/UTF-8 \
|
||||
el_GR/ISO-8859-7 \
|
||||
el_GR@euro/ISO-8859-7 \
|
||||
el_CY.UTF-8/UTF-8 \
|
||||
el_CY/ISO-8859-7 \
|
||||
en_AG/UTF-8 \
|
||||
en_AU.UTF-8/UTF-8 \
|
||||
en_AU/ISO-8859-1 \
|
||||
en_BW.UTF-8/UTF-8 \
|
||||
en_BW/ISO-8859-1 \
|
||||
en_CA.UTF-8/UTF-8 \
|
||||
en_CA/ISO-8859-1 \
|
||||
en_DK.UTF-8/UTF-8 \
|
||||
en_DK/ISO-8859-1 \
|
||||
en_GB.UTF-8/UTF-8 \
|
||||
en_GB/ISO-8859-1 \
|
||||
en_GB.ISO-8859-15/ISO-8859-15 \
|
||||
en_HK.UTF-8/UTF-8 \
|
||||
en_HK/ISO-8859-1 \
|
||||
en_IE.UTF-8/UTF-8 \
|
||||
en_IE/ISO-8859-1 \
|
||||
en_IE@euro/ISO-8859-15 \
|
||||
en_IL/UTF-8 \
|
||||
en_IN/UTF-8 \
|
||||
en_NG/UTF-8 \
|
||||
en_NZ.UTF-8/UTF-8 \
|
||||
en_NZ/ISO-8859-1 \
|
||||
en_PH.UTF-8/UTF-8 \
|
||||
en_PH/ISO-8859-1 \
|
||||
en_SC.UTF-8/UTF-8 \
|
||||
en_SG.UTF-8/UTF-8 \
|
||||
en_SG/ISO-8859-1 \
|
||||
en_US.UTF-8/UTF-8 \
|
||||
en_US/ISO-8859-1 \
|
||||
en_US.ISO-8859-15/ISO-8859-15 \
|
||||
en_US@ampm/UTF-8 \
|
||||
en_US.UTF-8@ampm/UTF-8 \
|
||||
en_ZA.UTF-8/UTF-8 \
|
||||
en_ZA/ISO-8859-1 \
|
||||
en_ZM/UTF-8 \
|
||||
en_ZW.UTF-8/UTF-8 \
|
||||
en_ZW/ISO-8859-1 \
|
||||
eo/UTF-8 \
|
||||
es_AR.UTF-8/UTF-8 \
|
||||
es_AR/ISO-8859-1 \
|
||||
es_BO.UTF-8/UTF-8 \
|
||||
es_BO/ISO-8859-1 \
|
||||
es_CL.UTF-8/UTF-8 \
|
||||
es_CL/ISO-8859-1 \
|
||||
es_CO.UTF-8/UTF-8 \
|
||||
es_CO/ISO-8859-1 \
|
||||
es_CR.UTF-8/UTF-8 \
|
||||
es_CR/ISO-8859-1 \
|
||||
es_CU/UTF-8 \
|
||||
es_DO.UTF-8/UTF-8 \
|
||||
es_DO/ISO-8859-1 \
|
||||
es_EC.UTF-8/UTF-8 \
|
||||
es_EC/ISO-8859-1 \
|
||||
es_ES.UTF-8/UTF-8 \
|
||||
es_ES/ISO-8859-1 \
|
||||
es_ES@euro/ISO-8859-15 \
|
||||
es_GT.UTF-8/UTF-8 \
|
||||
es_GT/ISO-8859-1 \
|
||||
es_HN.UTF-8/UTF-8 \
|
||||
es_HN/ISO-8859-1 \
|
||||
es_MX.UTF-8/UTF-8 \
|
||||
es_MX/ISO-8859-1 \
|
||||
es_NI.UTF-8/UTF-8 \
|
||||
es_NI/ISO-8859-1 \
|
||||
es_PA.UTF-8/UTF-8 \
|
||||
es_PA/ISO-8859-1 \
|
||||
es_PE.UTF-8/UTF-8 \
|
||||
es_PE/ISO-8859-1 \
|
||||
es_PR.UTF-8/UTF-8 \
|
||||
es_PR/ISO-8859-1 \
|
||||
es_PY.UTF-8/UTF-8 \
|
||||
es_PY/ISO-8859-1 \
|
||||
es_SV.UTF-8/UTF-8 \
|
||||
es_SV/ISO-8859-1 \
|
||||
es_US.UTF-8/UTF-8 \
|
||||
es_US/ISO-8859-1 \
|
||||
es_UY.UTF-8/UTF-8 \
|
||||
es_UY/ISO-8859-1 \
|
||||
es_VE.UTF-8/UTF-8 \
|
||||
es_VE/ISO-8859-1 \
|
||||
et_EE.UTF-8/UTF-8 \
|
||||
et_EE/ISO-8859-1 \
|
||||
et_EE.ISO-8859-15/ISO-8859-15 \
|
||||
eu_ES.UTF-8/UTF-8 \
|
||||
eu_ES/ISO-8859-1 \
|
||||
eu_ES@euro/ISO-8859-15 \
|
||||
fa_IR/UTF-8 \
|
||||
ff_SN/UTF-8 \
|
||||
fi_FI.UTF-8/UTF-8 \
|
||||
fi_FI/ISO-8859-1 \
|
||||
fi_FI@euro/ISO-8859-15 \
|
||||
fil_PH/UTF-8 \
|
||||
fo_FO.UTF-8/UTF-8 \
|
||||
fo_FO/ISO-8859-1 \
|
||||
fr_BE.UTF-8/UTF-8 \
|
||||
fr_BE/ISO-8859-1 \
|
||||
fr_BE@euro/ISO-8859-15 \
|
||||
fr_CA.UTF-8/UTF-8 \
|
||||
fr_CA/ISO-8859-1 \
|
||||
fr_CH.UTF-8/UTF-8 \
|
||||
fr_CH/ISO-8859-1 \
|
||||
fr_FR.UTF-8/UTF-8 \
|
||||
fr_FR/ISO-8859-1 \
|
||||
fr_FR@euro/ISO-8859-15 \
|
||||
fr_LU.UTF-8/UTF-8 \
|
||||
fr_LU/ISO-8859-1 \
|
||||
fr_LU@euro/ISO-8859-15 \
|
||||
fur_IT/UTF-8 \
|
||||
fy_NL/UTF-8 \
|
||||
fy_DE/UTF-8 \
|
||||
ga_IE.UTF-8/UTF-8 \
|
||||
ga_IE/ISO-8859-1 \
|
||||
ga_IE@euro/ISO-8859-15 \
|
||||
gd_GB.UTF-8/UTF-8 \
|
||||
gd_GB/ISO-8859-15 \
|
||||
gez_ER/UTF-8 \
|
||||
gez_ER@abegede/UTF-8 \
|
||||
gez_ET/UTF-8 \
|
||||
gez_ET@abegede/UTF-8 \
|
||||
gl_ES.UTF-8/UTF-8 \
|
||||
gl_ES/ISO-8859-1 \
|
||||
gl_ES@euro/ISO-8859-15 \
|
||||
gu_IN/UTF-8 \
|
||||
gv_GB.UTF-8/UTF-8 \
|
||||
gv_GB/ISO-8859-1 \
|
||||
ha_NG/UTF-8 \
|
||||
hak_TW/UTF-8 \
|
||||
he_IL.UTF-8/UTF-8 \
|
||||
he_IL/ISO-8859-8 \
|
||||
hi_IN/UTF-8 \
|
||||
hif_FJ/UTF-8 \
|
||||
hne_IN/UTF-8 \
|
||||
hr_HR.UTF-8/UTF-8 \
|
||||
hr_HR/ISO-8859-2 \
|
||||
hsb_DE/ISO-8859-2 \
|
||||
hsb_DE.UTF-8/UTF-8 \
|
||||
ht_HT/UTF-8 \
|
||||
hu_HU.UTF-8/UTF-8 \
|
||||
hu_HU/ISO-8859-2 \
|
||||
hy_AM/UTF-8 \
|
||||
hy_AM.ARMSCII-8/ARMSCII-8 \
|
||||
ia_FR/UTF-8 \
|
||||
id_ID.UTF-8/UTF-8 \
|
||||
id_ID/ISO-8859-1 \
|
||||
ig_NG/UTF-8 \
|
||||
ik_CA/UTF-8 \
|
||||
is_IS.UTF-8/UTF-8 \
|
||||
is_IS/ISO-8859-1 \
|
||||
it_CH.UTF-8/UTF-8 \
|
||||
it_CH/ISO-8859-1 \
|
||||
it_IT.UTF-8/UTF-8 \
|
||||
it_IT/ISO-8859-1 \
|
||||
it_IT@euro/ISO-8859-15 \
|
||||
iu_CA/UTF-8 \
|
||||
ja_JP.EUC-JP/EUC-JP \
|
||||
ja_JP.UTF-8/UTF-8 \
|
||||
ka_GE.UTF-8/UTF-8 \
|
||||
ka_GE/GEORGIAN-PS \
|
||||
kab_DZ/UTF-8 \
|
||||
kk_KZ.UTF-8/UTF-8 \
|
||||
kk_KZ/PT154 \
|
||||
kl_GL.UTF-8/UTF-8 \
|
||||
kl_GL/ISO-8859-1 \
|
||||
km_KH/UTF-8 \
|
||||
kn_IN/UTF-8 \
|
||||
ko_KR.EUC-KR/EUC-KR \
|
||||
ko_KR.UTF-8/UTF-8 \
|
||||
kok_IN/UTF-8 \
|
||||
ks_IN/UTF-8 \
|
||||
ks_IN@devanagari/UTF-8 \
|
||||
ku_TR.UTF-8/UTF-8 \
|
||||
ku_TR/ISO-8859-9 \
|
||||
kw_GB.UTF-8/UTF-8 \
|
||||
kw_GB/ISO-8859-1 \
|
||||
ky_KG/UTF-8 \
|
||||
lb_LU/UTF-8 \
|
||||
lg_UG.UTF-8/UTF-8 \
|
||||
lg_UG/ISO-8859-10 \
|
||||
li_BE/UTF-8 \
|
||||
li_NL/UTF-8 \
|
||||
lij_IT/UTF-8 \
|
||||
ln_CD/UTF-8 \
|
||||
lo_LA/UTF-8 \
|
||||
lt_LT.UTF-8/UTF-8 \
|
||||
lt_LT/ISO-8859-13 \
|
||||
lv_LV.UTF-8/UTF-8 \
|
||||
lv_LV/ISO-8859-13 \
|
||||
lzh_TW/UTF-8 \
|
||||
mag_IN/UTF-8 \
|
||||
mai_IN/UTF-8 \
|
||||
mai_NP/UTF-8 \
|
||||
mfe_MU/UTF-8 \
|
||||
mg_MG.UTF-8/UTF-8 \
|
||||
mg_MG/ISO-8859-15 \
|
||||
mhr_RU/UTF-8 \
|
||||
mi_NZ.UTF-8/UTF-8 \
|
||||
mi_NZ/ISO-8859-13 \
|
||||
miq_NI/UTF-8 \
|
||||
mjw_IN/UTF-8 \
|
||||
mk_MK.UTF-8/UTF-8 \
|
||||
mk_MK/ISO-8859-5 \
|
||||
ml_IN/UTF-8 \
|
||||
mn_MN/UTF-8 \
|
||||
mni_IN/UTF-8 \
|
||||
mr_IN/UTF-8 \
|
||||
ms_MY.UTF-8/UTF-8 \
|
||||
ms_MY/ISO-8859-1 \
|
||||
mt_MT.UTF-8/UTF-8 \
|
||||
mt_MT/ISO-8859-3 \
|
||||
my_MM/UTF-8 \
|
||||
nan_TW/UTF-8 \
|
||||
nan_TW@latin/UTF-8 \
|
||||
nb_NO.UTF-8/UTF-8 \
|
||||
nb_NO/ISO-8859-1 \
|
||||
nds_DE/UTF-8 \
|
||||
nds_NL/UTF-8 \
|
||||
ne_NP/UTF-8 \
|
||||
nhn_MX/UTF-8 \
|
||||
niu_NU/UTF-8 \
|
||||
niu_NZ/UTF-8 \
|
||||
nl_AW/UTF-8 \
|
||||
nl_BE.UTF-8/UTF-8 \
|
||||
nl_BE/ISO-8859-1 \
|
||||
nl_BE@euro/ISO-8859-15 \
|
||||
nl_NL.UTF-8/UTF-8 \
|
||||
nl_NL/ISO-8859-1 \
|
||||
nl_NL@euro/ISO-8859-15 \
|
||||
nn_NO.UTF-8/UTF-8 \
|
||||
nn_NO/ISO-8859-1 \
|
||||
nr_ZA/UTF-8 \
|
||||
nso_ZA/UTF-8 \
|
||||
oc_FR.UTF-8/UTF-8 \
|
||||
oc_FR/ISO-8859-1 \
|
||||
om_ET/UTF-8 \
|
||||
om_KE.UTF-8/UTF-8 \
|
||||
om_KE/ISO-8859-1 \
|
||||
or_IN/UTF-8 \
|
||||
os_RU/UTF-8 \
|
||||
pa_IN/UTF-8 \
|
||||
pa_PK/UTF-8 \
|
||||
pap_AW/UTF-8 \
|
||||
pap_CW/UTF-8 \
|
||||
pl_PL.UTF-8/UTF-8 \
|
||||
pl_PL/ISO-8859-2 \
|
||||
ps_AF/UTF-8 \
|
||||
pt_BR.UTF-8/UTF-8 \
|
||||
pt_BR/ISO-8859-1 \
|
||||
pt_PT.UTF-8/UTF-8 \
|
||||
pt_PT/ISO-8859-1 \
|
||||
pt_PT@euro/ISO-8859-15 \
|
||||
quz_PE/UTF-8 \
|
||||
raj_IN/UTF-8 \
|
||||
ro_RO.UTF-8/UTF-8 \
|
||||
ro_RO/ISO-8859-2 \
|
||||
ru_RU.KOI8-R/KOI8-R \
|
||||
ru_RU.UTF-8/UTF-8 \
|
||||
ru_RU/ISO-8859-5 \
|
||||
ru_UA.UTF-8/UTF-8 \
|
||||
ru_UA/KOI8-U \
|
||||
rw_RW/UTF-8 \
|
||||
sa_IN/UTF-8 \
|
||||
sah_RU/UTF-8 \
|
||||
sat_IN/UTF-8 \
|
||||
sc_IT/UTF-8 \
|
||||
sd_IN/UTF-8 \
|
||||
sd_IN@devanagari/UTF-8 \
|
||||
se_NO/UTF-8 \
|
||||
sgs_LT/UTF-8 \
|
||||
shn_MM/UTF-8 \
|
||||
shs_CA/UTF-8 \
|
||||
si_LK/UTF-8 \
|
||||
sid_ET/UTF-8 \
|
||||
sk_SK.UTF-8/UTF-8 \
|
||||
sk_SK/ISO-8859-2 \
|
||||
sl_SI.UTF-8/UTF-8 \
|
||||
sl_SI/ISO-8859-2 \
|
||||
sm_WS/UTF-8 \
|
||||
so_DJ.UTF-8/UTF-8 \
|
||||
so_DJ/ISO-8859-1 \
|
||||
so_ET/UTF-8 \
|
||||
so_KE.UTF-8/UTF-8 \
|
||||
so_KE/ISO-8859-1 \
|
||||
so_SO.UTF-8/UTF-8 \
|
||||
so_SO/ISO-8859-1 \
|
||||
sq_AL.UTF-8/UTF-8 \
|
||||
sq_AL/ISO-8859-1 \
|
||||
sq_MK/UTF-8 \
|
||||
sr_ME/UTF-8 \
|
||||
sr_RS/UTF-8 \
|
||||
sr_RS@latin/UTF-8 \
|
||||
ss_ZA/UTF-8 \
|
||||
st_ZA.UTF-8/UTF-8 \
|
||||
st_ZA/ISO-8859-1 \
|
||||
sv_FI.UTF-8/UTF-8 \
|
||||
sv_FI/ISO-8859-1 \
|
||||
sv_FI@euro/ISO-8859-15 \
|
||||
sv_SE.UTF-8/UTF-8 \
|
||||
sv_SE/ISO-8859-1 \
|
||||
sv_SE.ISO-8859-15/ISO-8859-15 \
|
||||
sw_KE/UTF-8 \
|
||||
sw_TZ/UTF-8 \
|
||||
szl_PL/UTF-8 \
|
||||
ta_IN/UTF-8 \
|
||||
ta_LK/UTF-8 \
|
||||
tcy_IN.UTF-8/UTF-8 \
|
||||
te_IN/UTF-8 \
|
||||
tg_TJ.UTF-8/UTF-8 \
|
||||
tg_TJ/KOI8-T \
|
||||
th_TH.UTF-8/UTF-8 \
|
||||
th_TH/TIS-620 \
|
||||
the_NP/UTF-8 \
|
||||
ti_ER/UTF-8 \
|
||||
ti_ET/UTF-8 \
|
||||
tig_ER/UTF-8 \
|
||||
tk_TM/UTF-8 \
|
||||
tl_PH.UTF-8/UTF-8 \
|
||||
tl_PH/ISO-8859-1 \
|
||||
tn_ZA/UTF-8 \
|
||||
to_TO/UTF-8 \
|
||||
tpi_PG/UTF-8 \
|
||||
tr_CY.UTF-8/UTF-8 \
|
||||
tr_CY/ISO-8859-9 \
|
||||
tr_TR.UTF-8/UTF-8 \
|
||||
tr_TR/ISO-8859-9 \
|
||||
ts_ZA/UTF-8 \
|
||||
tt_RU/UTF-8 \
|
||||
tt_RU@iqtelif/UTF-8 \
|
||||
ug_CN/UTF-8 \
|
||||
uk_UA.UTF-8/UTF-8 \
|
||||
uk_UA/KOI8-U \
|
||||
unm_US/UTF-8 \
|
||||
ur_IN/UTF-8 \
|
||||
ur_PK/UTF-8 \
|
||||
uz_UZ.UTF-8/UTF-8 \
|
||||
uz_UZ/ISO-8859-1 \
|
||||
uz_UZ@cyrillic/UTF-8 \
|
||||
ve_ZA/UTF-8 \
|
||||
vi_VN/UTF-8 \
|
||||
wa_BE/ISO-8859-1 \
|
||||
wa_BE@euro/ISO-8859-15 \
|
||||
wa_BE.UTF-8/UTF-8 \
|
||||
wae_CH/UTF-8 \
|
||||
wal_ET/UTF-8 \
|
||||
wo_SN/UTF-8 \
|
||||
xh_ZA.UTF-8/UTF-8 \
|
||||
xh_ZA/ISO-8859-1 \
|
||||
yi_US.UTF-8/UTF-8 \
|
||||
yi_US/CP1255 \
|
||||
yo_NG/UTF-8 \
|
||||
yue_HK/UTF-8 \
|
||||
yuw_PG/UTF-8 \
|
||||
zh_CN.GB18030/GB18030 \
|
||||
zh_CN.GBK/GBK \
|
||||
zh_CN.UTF-8/UTF-8 \
|
||||
zh_CN/GB2312 \
|
||||
zh_HK.UTF-8/UTF-8 \
|
||||
zh_HK/BIG5-HKSCS \
|
||||
zh_SG.UTF-8/UTF-8 \
|
||||
zh_SG.GBK/GBK \
|
||||
zh_SG/GB2312 \
|
||||
zh_TW.EUC-TW/EUC-TW \
|
||||
zh_TW.UTF-8/UTF-8 \
|
||||
zh_TW/BIG5 \
|
||||
zu_ZA.UTF-8/UTF-8 \
|
||||
zu_ZA/ISO-8859-1 \
|
|
@ -1,862 +0,0 @@
|
|||
#define _GNU_SOURCE
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include "../locale/hashval.h"
|
||||
#define __LC_LAST 13
|
||||
#include "../locale/locarchive.h"
|
||||
#include "../crypt/md5.h"
|
||||
|
||||
const char *alias_file = DATADIR "/locale/locale.alias";
|
||||
const char *locar_file = PREFIX "/lib/locale/locale-archive";
|
||||
const char *tmpl_file = PREFIX "/lib/locale/locale-archive.tmpl";
|
||||
const char *loc_path = PREFIX "/lib/locale/";
|
||||
/* Flags set by `--verbose` option. */
|
||||
int be_quiet = 1;
|
||||
int verbose = 0;
|
||||
int max_locarchive_open_retry = 10;
|
||||
const char *output_prefix;
|
||||
|
||||
/* Endianness should have been taken care of by localedef. We don't need to do
|
||||
additional swapping. We need this variable exported however, since
|
||||
locarchive.c uses it to determine if it needs to swap endianness of a value
|
||||
before writing to or reading from the archive. */
|
||||
bool swap_endianness_p = false;
|
||||
|
||||
static const char *locnames[] =
|
||||
{
|
||||
#define DEFINE_CATEGORY(category, category_name, items, a) \
|
||||
[category] = category_name,
|
||||
#include "../locale/categories.def"
|
||||
#undef DEFINE_CATEGORY
|
||||
};
|
||||
|
||||
static int
|
||||
is_prime (unsigned long candidate)
|
||||
{
|
||||
/* No even number and none less than 10 will be passed here. */
|
||||
unsigned long int divn = 3;
|
||||
unsigned long int sq = divn * divn;
|
||||
|
||||
while (sq < candidate && candidate % divn != 0)
|
||||
{
|
||||
++divn;
|
||||
sq += 4 * divn;
|
||||
++divn;
|
||||
}
|
||||
|
||||
return candidate % divn != 0;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
next_prime (unsigned long seed)
|
||||
{
|
||||
/* Make it definitely odd. */
|
||||
seed |= 1;
|
||||
|
||||
while (!is_prime (seed))
|
||||
seed += 2;
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
void
|
||||
error (int status, int errnum, const char *message, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, message);
|
||||
fflush (stdout);
|
||||
fprintf (stderr, "%s: ", program_invocation_name);
|
||||
vfprintf (stderr, message, args);
|
||||
va_end (args);
|
||||
if (errnum)
|
||||
fprintf (stderr, ": %s", strerror (errnum));
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
if (status)
|
||||
exit (errnum == EROFS ? 0 : status);
|
||||
}
|
||||
|
||||
void *
|
||||
xmalloc (size_t size)
|
||||
{
|
||||
void *p = malloc (size);
|
||||
if (p == NULL)
|
||||
error (EXIT_FAILURE, errno, "could not allocate %zd bytes of memory", size);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void
|
||||
open_tmpl_archive (struct locarhandle *ah)
|
||||
{
|
||||
struct stat64 st;
|
||||
int fd;
|
||||
struct locarhead head;
|
||||
const char *archivefname = ah->fname == NULL ? tmpl_file : ah->fname;
|
||||
|
||||
/* Open the archive. We must have exclusive write access. */
|
||||
fd = open64 (archivefname, O_RDONLY);
|
||||
if (fd == -1)
|
||||
error (EXIT_FAILURE, errno, "cannot open locale archive template file \"%s\"",
|
||||
archivefname);
|
||||
|
||||
if (fstat64 (fd, &st) < 0)
|
||||
error (EXIT_FAILURE, errno, "cannot stat locale archive template file \"%s\"",
|
||||
archivefname);
|
||||
|
||||
/* Read the header. */
|
||||
if (TEMP_FAILURE_RETRY (read (fd, &head, sizeof (head))) != sizeof (head))
|
||||
error (EXIT_FAILURE, errno, "cannot read archive header");
|
||||
|
||||
ah->fd = fd;
|
||||
ah->mmaped = (head.sumhash_offset
|
||||
+ head.sumhash_size * sizeof (struct sumhashent));
|
||||
if (ah->mmaped > (unsigned long) st.st_size)
|
||||
error (EXIT_FAILURE, 0, "locale archive template file truncated");
|
||||
ah->mmaped = st.st_size;
|
||||
ah->reserved = st.st_size;
|
||||
|
||||
/* Now we know how large the administrative information part is.
|
||||
Map all of it. */
|
||||
ah->addr = mmap64 (NULL, ah->mmaped, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (ah->addr == MAP_FAILED)
|
||||
error (EXIT_FAILURE, errno, "cannot map archive header");
|
||||
}
|
||||
|
||||
/* Open the locale archive. */
|
||||
extern void open_archive (struct locarhandle *ah, bool readonly);
|
||||
|
||||
/* Close the locale archive. */
|
||||
extern void close_archive (struct locarhandle *ah);
|
||||
|
||||
/* Add given locale data to the archive. */
|
||||
extern int add_locale_to_archive (struct locarhandle *ah, const char *name,
|
||||
locale_data_t data, bool replace);
|
||||
|
||||
extern void add_alias (struct locarhandle *ah, const char *alias,
|
||||
bool replace, const char *oldname,
|
||||
uint32_t *locrec_offset_p);
|
||||
|
||||
extern struct namehashent *
|
||||
insert_name (struct locarhandle *ah,
|
||||
const char *name, size_t name_len, bool replace);
|
||||
|
||||
struct nameent
|
||||
{
|
||||
char *name;
|
||||
struct locrecent *locrec;
|
||||
};
|
||||
|
||||
struct dataent
|
||||
{
|
||||
const unsigned char *sum;
|
||||
uint32_t file_offset;
|
||||
};
|
||||
|
||||
static int
|
||||
nameentcmp (const void *a, const void *b)
|
||||
{
|
||||
struct locrecent *la = ((const struct nameent *) a)->locrec;
|
||||
struct locrecent *lb = ((const struct nameent *) b)->locrec;
|
||||
uint32_t start_a = -1, end_a = 0;
|
||||
uint32_t start_b = -1, end_b = 0;
|
||||
int cnt;
|
||||
|
||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
||||
if (cnt != LC_ALL)
|
||||
{
|
||||
if (la->record[cnt].offset < start_a)
|
||||
start_a = la->record[cnt].offset;
|
||||
if (la->record[cnt].offset + la->record[cnt].len > end_a)
|
||||
end_a = la->record[cnt].offset + la->record[cnt].len;
|
||||
}
|
||||
assert (start_a != (uint32_t)-1);
|
||||
assert (end_a != 0);
|
||||
|
||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
||||
if (cnt != LC_ALL)
|
||||
{
|
||||
if (lb->record[cnt].offset < start_b)
|
||||
start_b = lb->record[cnt].offset;
|
||||
if (lb->record[cnt].offset + lb->record[cnt].len > end_b)
|
||||
end_b = lb->record[cnt].offset + lb->record[cnt].len;
|
||||
}
|
||||
assert (start_b != (uint32_t)-1);
|
||||
assert (end_b != 0);
|
||||
|
||||
if (start_a != start_b)
|
||||
return (int)start_a - (int)start_b;
|
||||
return (int)end_a - (int)end_b;
|
||||
}
|
||||
|
||||
static int
|
||||
dataentcmp (const void *a, const void *b)
|
||||
{
|
||||
if (((const struct dataent *) a)->file_offset
|
||||
< ((const struct dataent *) b)->file_offset)
|
||||
return -1;
|
||||
|
||||
if (((const struct dataent *) a)->file_offset
|
||||
> ((const struct dataent *) b)->file_offset)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sumsearchfn (const void *key, const void *ent)
|
||||
{
|
||||
uint32_t keyn = *(uint32_t *)key;
|
||||
uint32_t entn = ((struct dataent *)ent)->file_offset;
|
||||
|
||||
if (keyn < entn)
|
||||
return -1;
|
||||
if (keyn > entn)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
compute_data (struct locarhandle *ah, struct nameent *name, size_t sumused,
|
||||
struct dataent *files, locale_data_t data)
|
||||
{
|
||||
int cnt;
|
||||
struct locrecent *locrec = name->locrec;
|
||||
struct dataent *file;
|
||||
data[LC_ALL].addr = ((char *) ah->addr) + locrec->record[LC_ALL].offset;
|
||||
data[LC_ALL].size = locrec->record[LC_ALL].len;
|
||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
||||
if (cnt != LC_ALL)
|
||||
{
|
||||
data[cnt].addr = ((char *) ah->addr) + locrec->record[cnt].offset;
|
||||
data[cnt].size = locrec->record[cnt].len;
|
||||
if (data[cnt].addr >= data[LC_ALL].addr
|
||||
&& data[cnt].addr + data[cnt].size
|
||||
<= data[LC_ALL].addr + data[LC_ALL].size)
|
||||
__md5_buffer (data[cnt].addr, data[cnt].size, data[cnt].sum);
|
||||
else
|
||||
{
|
||||
file = bsearch (&locrec->record[cnt].offset, files, sumused,
|
||||
sizeof (*files), sumsearchfn);
|
||||
if (file == NULL)
|
||||
error (EXIT_FAILURE, 0, "inconsistent template file");
|
||||
memcpy (data[cnt].sum, file->sum, sizeof (data[cnt].sum));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
fill_archive (struct locarhandle *tmpl_ah,
|
||||
const char *fname,
|
||||
size_t install_langs_count, char *install_langs_list[],
|
||||
size_t nlist, char *list[],
|
||||
const char *primary)
|
||||
{
|
||||
struct locarhandle ah;
|
||||
struct locarhead *head;
|
||||
int result = 0;
|
||||
struct nameent *names;
|
||||
struct namehashent *namehashtab;
|
||||
size_t cnt, used;
|
||||
struct dataent *files;
|
||||
struct sumhashent *sumhashtab;
|
||||
size_t sumused;
|
||||
struct locrecent *primary_locrec = NULL;
|
||||
struct nameent *primary_nameent = NULL;
|
||||
|
||||
head = tmpl_ah->addr;
|
||||
names = (struct nameent *) malloc (head->namehash_used
|
||||
* sizeof (struct nameent));
|
||||
files = (struct dataent *) malloc (head->sumhash_used
|
||||
* sizeof (struct dataent));
|
||||
if (names == NULL || files == NULL)
|
||||
error (EXIT_FAILURE, errno, "could not allocate tables");
|
||||
|
||||
namehashtab = (struct namehashent *) ((char *) tmpl_ah->addr
|
||||
+ head->namehash_offset);
|
||||
sumhashtab = (struct sumhashent *) ((char *) tmpl_ah->addr
|
||||
+ head->sumhash_offset);
|
||||
|
||||
for (cnt = used = 0; cnt < head->namehash_size; ++cnt)
|
||||
if (namehashtab[cnt].locrec_offset != 0)
|
||||
{
|
||||
char * name;
|
||||
int i;
|
||||
assert (used < head->namehash_used);
|
||||
name = tmpl_ah->addr + namehashtab[cnt].name_offset;
|
||||
if (install_langs_count == 0)
|
||||
{
|
||||
/* Always intstall the entry. */
|
||||
names[used].name = name;
|
||||
names[used++].locrec
|
||||
= (struct locrecent *) ((char *) tmpl_ah->addr +
|
||||
namehashtab[cnt].locrec_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Only install the entry if the user asked for it via
|
||||
--install-langs. */
|
||||
for (i = 0; i < install_langs_count; i++)
|
||||
{
|
||||
/* Add one for "_" and one for the null terminator. */
|
||||
size_t len = strlen (install_langs_list[i]) + 2;
|
||||
char *install_lang = (char *)xmalloc (len);
|
||||
strcpy (install_lang, install_langs_list[i]);
|
||||
if (strchr (install_lang, '_') == NULL)
|
||||
strcat (install_lang, "_");
|
||||
if (strncmp (name, install_lang, strlen (install_lang)) == 0)
|
||||
{
|
||||
names[used].name = name;
|
||||
names[used++].locrec
|
||||
= (struct locrecent *) ((char *)tmpl_ah->addr
|
||||
+ namehashtab[cnt].locrec_offset);
|
||||
}
|
||||
free (install_lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort the names. */
|
||||
qsort (names, used, sizeof (struct nameent), nameentcmp);
|
||||
|
||||
for (cnt = sumused = 0; cnt < head->sumhash_size; ++cnt)
|
||||
if (sumhashtab[cnt].file_offset != 0)
|
||||
{
|
||||
assert (sumused < head->sumhash_used);
|
||||
files[sumused].sum = (const unsigned char *) sumhashtab[cnt].sum;
|
||||
files[sumused++].file_offset = sumhashtab[cnt].file_offset;
|
||||
}
|
||||
|
||||
/* Sort by file locations. */
|
||||
qsort (files, sumused, sizeof (struct dataent), dataentcmp);
|
||||
|
||||
/* Open the archive. This call never returns if we cannot
|
||||
successfully open the archive. */
|
||||
ah.fname = NULL;
|
||||
if (fname != NULL)
|
||||
ah.fname = fname;
|
||||
open_archive (&ah, false);
|
||||
|
||||
if (primary != NULL)
|
||||
{
|
||||
for (cnt = 0; cnt < used; ++cnt)
|
||||
if (strcmp (names[cnt].name, primary) == 0)
|
||||
break;
|
||||
if (cnt < used)
|
||||
{
|
||||
locale_data_t data;
|
||||
|
||||
compute_data (tmpl_ah, &names[cnt], sumused, files, data);
|
||||
result |= add_locale_to_archive (&ah, primary, data, 0);
|
||||
primary_locrec = names[cnt].locrec;
|
||||
primary_nameent = &names[cnt];
|
||||
}
|
||||
}
|
||||
|
||||
for (cnt = 0; cnt < used; ++cnt)
|
||||
if (&names[cnt] == primary_nameent)
|
||||
continue;
|
||||
else if ((cnt > 0 && names[cnt - 1].locrec == names[cnt].locrec)
|
||||
|| names[cnt].locrec == primary_locrec)
|
||||
{
|
||||
const char *oldname;
|
||||
struct namehashent *namehashent;
|
||||
uint32_t locrec_offset;
|
||||
|
||||
if (names[cnt].locrec == primary_locrec)
|
||||
oldname = primary;
|
||||
else
|
||||
oldname = names[cnt - 1].name;
|
||||
namehashent = insert_name (&ah, oldname, strlen (oldname), true);
|
||||
assert (namehashent->name_offset != 0);
|
||||
assert (namehashent->locrec_offset != 0);
|
||||
locrec_offset = namehashent->locrec_offset;
|
||||
add_alias (&ah, names[cnt].name, 0, oldname, &locrec_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
locale_data_t data;
|
||||
|
||||
compute_data (tmpl_ah, &names[cnt], sumused, files, data);
|
||||
result |= add_locale_to_archive (&ah, names[cnt].name, data, 0);
|
||||
}
|
||||
|
||||
while (nlist-- > 0)
|
||||
{
|
||||
const char *fname = *list++;
|
||||
size_t fnamelen = strlen (fname);
|
||||
struct stat64 st;
|
||||
DIR *dirp;
|
||||
struct dirent64 *d;
|
||||
int seen;
|
||||
locale_data_t data;
|
||||
int cnt;
|
||||
|
||||
/* First see whether this really is a directory and whether it
|
||||
contains all the require locale category files. */
|
||||
if (stat64 (fname, &st) < 0)
|
||||
{
|
||||
error (0, 0, "stat of \"%s\" failed: %s: ignored", fname,
|
||||
strerror (errno));
|
||||
continue;
|
||||
}
|
||||
if (!S_ISDIR (st.st_mode))
|
||||
{
|
||||
error (0, 0, "\"%s\" is no directory; ignored", fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
dirp = opendir (fname);
|
||||
if (dirp == NULL)
|
||||
{
|
||||
error (0, 0, "cannot open directory \"%s\": %s: ignored",
|
||||
fname, strerror (errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
seen = 0;
|
||||
while ((d = readdir64 (dirp)) != NULL)
|
||||
{
|
||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
||||
if (cnt != LC_ALL)
|
||||
if (strcmp (d->d_name, locnames[cnt]) == 0)
|
||||
{
|
||||
unsigned char d_type;
|
||||
|
||||
/* We have an object of the required name. If it's
|
||||
a directory we have to look at a file with the
|
||||
prefix "SYS_". Otherwise we have found what we
|
||||
are looking for. */
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
d_type = d->d_type;
|
||||
|
||||
if (d_type != DT_REG)
|
||||
#endif
|
||||
{
|
||||
char fullname[fnamelen + 2 * strlen (d->d_name) + 7];
|
||||
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
if (d_type == DT_UNKNOWN || d_type == DT_LNK)
|
||||
#endif
|
||||
{
|
||||
strcpy (stpcpy (stpcpy (fullname, fname), "/"),
|
||||
d->d_name);
|
||||
|
||||
if (stat64 (fullname, &st) == -1)
|
||||
/* We cannot stat the file, ignore it. */
|
||||
break;
|
||||
|
||||
d_type = IFTODT (st.st_mode);
|
||||
}
|
||||
|
||||
if (d_type == DT_DIR)
|
||||
{
|
||||
/* We have to do more tests. The file is a
|
||||
directory and it therefore must contain a
|
||||
regular file with the same name except a
|
||||
"SYS_" prefix. */
|
||||
char *t = stpcpy (stpcpy (fullname, fname), "/");
|
||||
strcpy (stpcpy (stpcpy (t, d->d_name), "/SYS_"),
|
||||
d->d_name);
|
||||
|
||||
if (stat64 (fullname, &st) == -1)
|
||||
/* There is no SYS_* file or we cannot
|
||||
access it. */
|
||||
break;
|
||||
|
||||
d_type = IFTODT (st.st_mode);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we found a regular file (eventually after
|
||||
following a symlink) we are successful. */
|
||||
if (d_type == DT_REG)
|
||||
++seen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir (dirp);
|
||||
|
||||
if (seen != __LC_LAST - 1)
|
||||
{
|
||||
/* We don't have all locale category files. Ignore the name. */
|
||||
error (0, 0, "incomplete set of locale files in \"%s\"",
|
||||
fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Add the files to the archive. To do this we first compute
|
||||
sizes and the MD5 sums of all the files. */
|
||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
||||
if (cnt != LC_ALL)
|
||||
{
|
||||
char fullname[fnamelen + 2 * strlen (locnames[cnt]) + 7];
|
||||
int fd;
|
||||
|
||||
strcpy (stpcpy (stpcpy (fullname, fname), "/"), locnames[cnt]);
|
||||
fd = open64 (fullname, O_RDONLY);
|
||||
if (fd == -1 || fstat64 (fd, &st) == -1)
|
||||
{
|
||||
/* Cannot read the file. */
|
||||
if (fd != -1)
|
||||
close (fd);
|
||||
break;
|
||||
}
|
||||
|
||||
if (S_ISDIR (st.st_mode))
|
||||
{
|
||||
char *t;
|
||||
close (fd);
|
||||
t = stpcpy (stpcpy (fullname, fname), "/");
|
||||
strcpy (stpcpy (stpcpy (t, locnames[cnt]), "/SYS_"),
|
||||
locnames[cnt]);
|
||||
|
||||
fd = open64 (fullname, O_RDONLY);
|
||||
if (fd == -1 || fstat64 (fd, &st) == -1
|
||||
|| !S_ISREG (st.st_mode))
|
||||
{
|
||||
if (fd != -1)
|
||||
close (fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Map the file. */
|
||||
data[cnt].addr = mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED,
|
||||
fd, 0);
|
||||
if (data[cnt].addr == MAP_FAILED)
|
||||
{
|
||||
/* Cannot map it. */
|
||||
close (fd);
|
||||
break;
|
||||
}
|
||||
|
||||
data[cnt].size = st.st_size;
|
||||
__md5_buffer (data[cnt].addr, st.st_size, data[cnt].sum);
|
||||
|
||||
/* We don't need the file descriptor anymore. */
|
||||
close (fd);
|
||||
}
|
||||
|
||||
if (cnt != __LC_LAST)
|
||||
{
|
||||
while (cnt-- > 0)
|
||||
if (cnt != LC_ALL)
|
||||
munmap (data[cnt].addr, data[cnt].size);
|
||||
|
||||
error (0, 0, "cannot read all files in \"%s\": ignored", fname);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
result |= add_locale_to_archive (&ah, basename (fname), data, 0);
|
||||
|
||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
||||
if (cnt != LC_ALL)
|
||||
munmap (data[cnt].addr, data[cnt].size);
|
||||
}
|
||||
|
||||
/* We are done. */
|
||||
close_archive (&ah);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
printf ("\
|
||||
Usage: build-locale-archive [OPTION]... [TEMPLATE-FILE] [ARCHIVE-FILE]\n\
|
||||
Builds a locale archive from a template file.\n\
|
||||
Options:\n\
|
||||
-h, --help Print this usage message.\n\
|
||||
-v, --verbose Verbose execution.\n\
|
||||
-l, --install-langs=LIST Only include locales given in LIST into the \n\
|
||||
locale archive. LIST is a colon separated list\n\
|
||||
of locale prefixes, for example \"de:en:ja\".\n\
|
||||
The special argument \"all\" means to install\n\
|
||||
all languages and it must be present by itself.\n\
|
||||
If \"all\" is present with any other language it\n\
|
||||
will be treated as the name of a locale.\n\
|
||||
If the --install-langs option is missing, all\n\
|
||||
locales are installed. The colon separated list\n\
|
||||
can contain any strings matching the beginning of\n\
|
||||
locale names.\n\
|
||||
If a string does not contain a \"_\", it is added.\n\
|
||||
Examples:\n\
|
||||
--install-langs=\"en\"\n\
|
||||
installs en_US, en_US.iso88591,\n\
|
||||
en_US.iso885915, en_US.utf8,\n\
|
||||
en_GB ...\n\
|
||||
--install-langs=\"en_US.utf8\"\n\
|
||||
installs only en_US.utf8.\n\
|
||||
--install-langs=\"ko\"\n\
|
||||
installs ko_KR, ko_KR.euckr,\n\
|
||||
ko_KR.utf8 but *not* kok_IN\n\
|
||||
because \"ko\" does not contain\n\
|
||||
\"_\" and it is silently added\n\
|
||||
--install-langs\"ko:kok\"\n\
|
||||
installs ko_KR, ko_KR.euckr,\n\
|
||||
ko_KR.utf8, kok_IN, and\n\
|
||||
kok_IN.utf8.\n\
|
||||
--install-langs=\"POSIX\" will\n\
|
||||
installs *no* locales at all\n\
|
||||
because POSIX matches none of\n\
|
||||
the locales. Actually, any string\n\
|
||||
matching nothing will do that.\n\
|
||||
POSIX and C will always be\n\
|
||||
available because they are\n\
|
||||
builtin.\n\
|
||||
Aliases are installed as well,\n\
|
||||
i.e. --install-langs=\"de\"\n\
|
||||
will install not only every locale starting with\n\
|
||||
\"de\" but also the aliases \"deutsch\"\n\
|
||||
and and \"german\" although the latter does not\n\
|
||||
start with \"de\".\n\
|
||||
\n\
|
||||
If the arguments TEMPLATE-FILE and ARCHIVE-FILE are not given the locations\n\
|
||||
where the glibc used expects these files are used by default.\n\
|
||||
");
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
char path[4096];
|
||||
DIR *dirp;
|
||||
struct dirent64 *d;
|
||||
struct stat64 st;
|
||||
char *list[16384], *primary;
|
||||
char *lang;
|
||||
int install_langs_count = 0;
|
||||
int i;
|
||||
char *install_langs_arg, *ila_start;
|
||||
char **install_langs_list = NULL;
|
||||
unsigned int cnt = 0;
|
||||
struct locarhandle tmpl_ah;
|
||||
char *new_locar_fname = NULL;
|
||||
size_t loc_path_len = strlen (loc_path);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c;
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"install-langs", required_argument, 0, 'l'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
/* getopt_long stores the option index here. */
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long (argc, argv, "vhl:",
|
||||
long_options, &option_index);
|
||||
|
||||
/* Detect the end of the options. */
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("unknown option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
usage ();
|
||||
exit (1);
|
||||
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
be_quiet = 0;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage ();
|
||||
exit (0);
|
||||
|
||||
case 'l':
|
||||
install_langs_arg = ila_start = strdup (optarg);
|
||||
/* If the argument to --install-lang is "all", do
|
||||
not limit the list of languages to install and install
|
||||
them all. We do not support installing a single locale
|
||||
called "all". */
|
||||
#define MAGIC_INSTALL_ALL "all"
|
||||
if (install_langs_arg != NULL
|
||||
&& install_langs_arg[0] != '\0'
|
||||
&& !(strncmp(install_langs_arg, MAGIC_INSTALL_ALL,
|
||||
strlen(MAGIC_INSTALL_ALL)) == 0
|
||||
&& strlen (install_langs_arg) == 3))
|
||||
{
|
||||
/* Count the number of languages we will install. */
|
||||
while (true)
|
||||
{
|
||||
lang = strtok(install_langs_arg, ":;,");
|
||||
if (lang == NULL)
|
||||
break;
|
||||
install_langs_count++;
|
||||
install_langs_arg = NULL;
|
||||
}
|
||||
free (ila_start);
|
||||
|
||||
/* Reject an entire string made up of delimiters. */
|
||||
if (install_langs_count == 0)
|
||||
break;
|
||||
|
||||
/* Copy the list. */
|
||||
install_langs_list = (char **)xmalloc (sizeof(char *) * install_langs_count);
|
||||
install_langs_arg = ila_start = strdup (optarg);
|
||||
install_langs_count = 0;
|
||||
while (true)
|
||||
{
|
||||
lang = strtok(install_langs_arg, ":;,");
|
||||
if (lang == NULL)
|
||||
break;
|
||||
install_langs_list[install_langs_count] = lang;
|
||||
install_langs_count++;
|
||||
install_langs_arg = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '?':
|
||||
/* getopt_long already printed an error message. */
|
||||
usage ();
|
||||
exit (0);
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
tmpl_ah.fname = NULL;
|
||||
if (optind < argc)
|
||||
tmpl_ah.fname = argv[optind];
|
||||
if (optind + 1 < argc)
|
||||
new_locar_fname = argv[optind + 1];
|
||||
if (verbose)
|
||||
{
|
||||
if (tmpl_ah.fname)
|
||||
printf("input archive file specified on command line: %s\n",
|
||||
tmpl_ah.fname);
|
||||
else
|
||||
printf("using default input archive file.\n");
|
||||
if (new_locar_fname)
|
||||
printf("output archive file specified on command line: %s\n",
|
||||
new_locar_fname);
|
||||
else
|
||||
printf("using default output archive file.\n");
|
||||
}
|
||||
|
||||
dirp = opendir (loc_path);
|
||||
if (dirp == NULL)
|
||||
error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path);
|
||||
|
||||
open_tmpl_archive (&tmpl_ah);
|
||||
|
||||
if (new_locar_fname)
|
||||
unlink (new_locar_fname);
|
||||
else
|
||||
unlink (locar_file);
|
||||
primary = getenv ("LC_ALL");
|
||||
if (primary == NULL)
|
||||
primary = getenv ("LANG");
|
||||
if (primary != NULL)
|
||||
{
|
||||
if (strncmp (primary, "ja", 2) != 0
|
||||
&& strncmp (primary, "ko", 2) != 0
|
||||
&& strncmp (primary, "zh", 2) != 0)
|
||||
{
|
||||
char *ptr = malloc (strlen (primary) + strlen (".utf8") + 1), *p, *q;
|
||||
/* This leads to invalid locales sometimes:
|
||||
de_DE.iso885915@euro -> de_DE.utf8@euro */
|
||||
if (ptr != NULL)
|
||||
{
|
||||
p = ptr;
|
||||
q = primary;
|
||||
while (*q && *q != '.' && *q != '@')
|
||||
*p++ = *q++;
|
||||
if (*q == '.')
|
||||
while (*q && *q != '@')
|
||||
q++;
|
||||
p = stpcpy (p, ".utf8");
|
||||
strcpy (p, q);
|
||||
primary = ptr;
|
||||
}
|
||||
else
|
||||
primary = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (path, loc_path, loc_path_len);
|
||||
|
||||
while ((d = readdir64 (dirp)) != NULL)
|
||||
{
|
||||
if (strcmp (d->d_name, ".") == 0 || strcmp (d->d_name, "..") == 0)
|
||||
continue;
|
||||
if (strchr (d->d_name, '_') == NULL)
|
||||
continue;
|
||||
|
||||
size_t d_name_len = strlen (d->d_name);
|
||||
if (loc_path_len + d_name_len + 1 > sizeof (path))
|
||||
{
|
||||
error (0, 0, "too long filename \"%s\"", d->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy (path + loc_path_len, d->d_name, d_name_len + 1);
|
||||
if (stat64 (path, &st) < 0)
|
||||
{
|
||||
error (0, errno, "cannot stat \"%s\"", path);
|
||||
continue;
|
||||
}
|
||||
if (! S_ISDIR (st.st_mode))
|
||||
continue;
|
||||
if (cnt == 16384)
|
||||
{
|
||||
error (0, 0, "too many directories in \"%s\"", loc_path);
|
||||
break;
|
||||
}
|
||||
list[cnt] = strdup (path);
|
||||
if (list[cnt] == NULL)
|
||||
{
|
||||
error (0, errno, "cannot add file to list \"%s\"", path);
|
||||
continue;
|
||||
}
|
||||
if (primary != NULL && cnt > 0 && strcmp (primary, d->d_name) == 0)
|
||||
{
|
||||
char *p = list[0];
|
||||
list[0] = list[cnt];
|
||||
list[cnt] = p;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
closedir (dirp);
|
||||
/* Store the archive to the file specified as the second argument on the
|
||||
command line or the default locale archive. */
|
||||
fill_archive (&tmpl_ah, new_locar_fname,
|
||||
install_langs_count, install_langs_list,
|
||||
cnt, list, primary);
|
||||
close_archive (&tmpl_ah);
|
||||
truncate (tmpl_file, 0);
|
||||
if (install_langs_count > 0)
|
||||
{
|
||||
free (ila_start);
|
||||
free (install_langs_list);
|
||||
}
|
||||
char *tz_argv[] = { "/usr/sbin/tzdata-update", NULL };
|
||||
execve (tz_argv[0], (char *const *)tz_argv, (char *const *)&tz_argv[1]);
|
||||
exit (0);
|
||||
}
|
1
dist
1
dist
|
@ -1 +0,0 @@
|
|||
an8_9
|
1
download
1
download
|
@ -1 +0,0 @@
|
|||
c81d2388896379997bc359d4f2084239 glibc-2.28.tar.xz
|
39
elf-Add-new-LoongArch-reloc-types-101-to-108-into-el.patch
Normal file
39
elf-Add-new-LoongArch-reloc-types-101-to-108-into-el.patch
Normal file
|
@ -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
|
||||
|
BIN
glibc-2.38.tar.xz
Normal file
BIN
glibc-2.38.tar.xz
Normal file
Binary file not shown.
|
@ -1,28 +0,0 @@
|
|||
From ed64d30125f855e25ac6f12d8863857dfd3e2cbe Mon Sep 17 00:00:00 2001
|
||||
From: lijing22222 <lijing@hygon.cn>
|
||||
Date: Fri, 1 Mar 2024 16:00:15 +0800
|
||||
Subject: [PATCH] Add Hygon Support
|
||||
|
||||
---
|
||||
sysdeps/x86/cpu-features.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
|
||||
index 91042505..0ce37a9a 100644
|
||||
--- a/sysdeps/x86/cpu-features.c
|
||||
+++ b/sysdeps/x86/cpu-features.c
|
||||
@@ -527,8 +527,9 @@ init_cpu_features (struct cpu_features *cpu_features)
|
||||
cpu_features->preferred[index_arch_Prefer_No_AVX512]
|
||||
|= bit_arch_Prefer_No_AVX512;
|
||||
}
|
||||
- /* This spells out "AuthenticAMD". */
|
||||
- else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
|
||||
+ /* This spells out "AuthenticAMD" or "HygonGenuine". */
|
||||
+ else if ((ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)||(ebx == 0x6f677948 && ecx == 0x656e6975 && edx == 0x6e65476e))
|
||||
+
|
||||
{
|
||||
unsigned int extended_model;
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
From 58f93dff514cc0bdf3c72eff590dcf5fe5bf9e00 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 19 Jul 2023 23:09:09 +0800
|
||||
Subject: [PATCH 3/6] Add a testcase to check alignment of PT_LOAD segment [BZ
|
||||
#28676]
|
||||
|
||||
Backport from master commit: fc2334a
|
||||
|
||||
Signed-off-by: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||
---
|
||||
elf/Makefile | 13 ++++++++++++-
|
||||
elf/tst-align3.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
elf/tst-alignmod3.c | 32 ++++++++++++++++++++++++++++++++
|
||||
3 files changed, 82 insertions(+), 1 deletion(-)
|
||||
create mode 100644 elf/tst-align3.c
|
||||
create mode 100644 elf/tst-alignmod3.c
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 634c3113..442817ca 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -331,6 +331,7 @@ tests += \
|
||||
tst-addr1 \
|
||||
tst-align \
|
||||
tst-align2 \
|
||||
+ tst-align3 \
|
||||
tst-audit-tlsdesc \
|
||||
tst-audit-tlsdesc-dlopen \
|
||||
tst-audit1 \
|
||||
@@ -466,7 +467,9 @@ endif
|
||||
test-srcs = \
|
||||
tst-pathopt
|
||||
# tests-srcs
|
||||
-
|
||||
+ifeq (yes,$(have-fpie))
|
||||
+tests-pie += tst-align3
|
||||
+endif
|
||||
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
|
||||
|
||||
ifneq ($(selinux-enabled),1)
|
||||
@@ -647,6 +650,7 @@ modules-names = \
|
||||
tst-absolute-zero-lib \
|
||||
tst-alignmod \
|
||||
tst-alignmod2 \
|
||||
+ tst-alignmod3 \
|
||||
tst-array2dep \
|
||||
tst-array5dep \
|
||||
tst-audit-tlsdesc-mod1 \
|
||||
@@ -1669,6 +1673,13 @@ CFLAGS-tst-alignmod2.c += $(stack-align-test-flags)
|
||||
$(objpfx)tst-align: $(libdl)
|
||||
$(objpfx)tst-align.out: $(objpfx)tst-alignmod.so
|
||||
$(objpfx)tst-align2: $(objpfx)tst-alignmod2.so
|
||||
+$(objpfx)tst-align3: $(objpfx)tst-alignmod3.so
|
||||
+ifeq (yes,$(have-fpie))
|
||||
+CFLAGS-tst-align3.c += $(PIE-ccflag)
|
||||
+endif
|
||||
+LDFLAGS-tst-align3 += -Wl,-z,max-page-size=0x200000
|
||||
+LDFLAGS-tst-alignmod3.so += -Wl,-z,max-page-size=0x200000
|
||||
+$(objpfx)tst-alignmod3.so: $(libsupport)
|
||||
|
||||
$(objpfx)unload3: $(libdl)
|
||||
$(objpfx)unload3.out: $(objpfx)unload3mod1.so $(objpfx)unload3mod2.so \
|
||||
diff --git a/elf/tst-align3.c b/elf/tst-align3.c
|
||||
new file mode 100644
|
||||
index 00000000..ac86d623
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-align3.c
|
||||
@@ -0,0 +1,38 @@
|
||||
+/* Check alignment of PT_LOAD segment in a shared library.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <tst-stack-align.h>
|
||||
+
|
||||
+/* This should cover all possible page sizes we currently support. */
|
||||
+#define ALIGN 0x200000
|
||||
+
|
||||
+int bar __attribute__ ((aligned (ALIGN))) = 1;
|
||||
+
|
||||
+extern int do_load_test (void);
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ printf ("bar: %p\n", &bar);
|
||||
+ TEST_VERIFY (is_aligned (&bar, ALIGN) == 0);
|
||||
+
|
||||
+ return do_load_test ();
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-alignmod3.c b/elf/tst-alignmod3.c
|
||||
new file mode 100644
|
||||
index 00000000..0d33f237
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-alignmod3.c
|
||||
@@ -0,0 +1,32 @@
|
||||
+/* Check alignment of PT_LOAD segment in a shared library.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <tst-stack-align.h>
|
||||
+
|
||||
+/* This should cover all possible page sizes we currently support. */
|
||||
+#define ALIGN 0x200000
|
||||
+
|
||||
+int foo __attribute__ ((aligned (ALIGN))) = 1;
|
||||
+
|
||||
+void
|
||||
+do_load_test (void)
|
||||
+{
|
||||
+ printf ("foo: %p\n", &foo);
|
||||
+ TEST_VERIFY (is_aligned (&foo, ALIGN) == 0);
|
||||
+}
|
||||
--
|
||||
2.27.0
|
||||
|
|
@ -1,325 +0,0 @@
|
|||
From 6152628751bf13f74c9336263a9c22f29ccd8ffb Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 19 Jul 2023 23:01:53 +0800
|
||||
Subject: [PATCH 1/6] Properly check stack alignment [BZ #27901]
|
||||
|
||||
1. Replace
|
||||
|
||||
if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0)
|
||||
|
||||
which may be optimized out by compiler, with
|
||||
|
||||
int
|
||||
__attribute__ ((weak, noclone, noinline))
|
||||
is_aligned (void *p, int align)
|
||||
{
|
||||
return (((uintptr_t) p) & (align - 1)) != 0;
|
||||
}
|
||||
|
||||
2. Add TEST_STACK_ALIGN_INIT to TEST_STACK_ALIGN.
|
||||
3. Add a common TEST_STACK_ALIGN_INIT to check 16-byte stack alignment
|
||||
for both i386 and x86-64.
|
||||
4. Update powerpc to use TEST_STACK_ALIGN_INIT.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Signed-off-by: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||
---
|
||||
sysdeps/generic/tst-stack-align.h | 40 ++++++++++++++++---------
|
||||
sysdeps/i386/i686/tst-stack-align.h | 44 ---------------------------
|
||||
sysdeps/i386/tst-stack-align.h | 41 -------------------------
|
||||
sysdeps/powerpc/tst-stack-align.h | 27 +++++------------
|
||||
sysdeps/x86/tst-stack-align.h | 28 ++++++++++++++++++
|
||||
sysdeps/x86_64/tst-stack-align.h | 46 -----------------------------
|
||||
6 files changed, 61 insertions(+), 165 deletions(-)
|
||||
delete mode 100644 sysdeps/i386/i686/tst-stack-align.h
|
||||
delete mode 100644 sysdeps/i386/tst-stack-align.h
|
||||
create mode 100644 sysdeps/x86/tst-stack-align.h
|
||||
delete mode 100644 sysdeps/x86_64/tst-stack-align.h
|
||||
|
||||
diff --git a/sysdeps/generic/tst-stack-align.h b/sysdeps/generic/tst-stack-align.h
|
||||
index e5cb3310..e6050901 100644
|
||||
--- a/sysdeps/generic/tst-stack-align.h
|
||||
+++ b/sysdeps/generic/tst-stack-align.h
|
||||
@@ -1,4 +1,5 @@
|
||||
-/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
|
||||
+/* Check stack alignment. Generic version.
|
||||
+ Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -18,17 +19,28 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
+int
|
||||
+__attribute__ ((weak, noclone, noinline))
|
||||
+is_aligned (void *p, int align)
|
||||
+{
|
||||
+ return (((uintptr_t) p) & (align - 1)) != 0;
|
||||
+}
|
||||
+
|
||||
+#ifndef TEST_STACK_ALIGN_INIT
|
||||
+# define TEST_STACK_ALIGN_INIT() 0
|
||||
+#endif
|
||||
+
|
||||
#define TEST_STACK_ALIGN() \
|
||||
- ({ \
|
||||
- double _d = 12.0; \
|
||||
- long double _ld = 15.0; \
|
||||
- int _ret = 0; \
|
||||
- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- \
|
||||
- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- _ret; \
|
||||
- })
|
||||
+ ({ \
|
||||
+ double _d = 12.0; \
|
||||
+ long double _ld = 15.0; \
|
||||
+ int _ret = TEST_STACK_ALIGN_INIT (); \
|
||||
+ \
|
||||
+ printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
+ _ret += is_aligned (&_d, __alignof (double)); \
|
||||
+ \
|
||||
+ printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, \
|
||||
+ __alignof (long double)); \
|
||||
+ _ret += is_aligned (&_ld, __alignof (long double)); \
|
||||
+ _ret; \
|
||||
+ })
|
||||
diff --git a/sysdeps/i386/i686/tst-stack-align.h b/sysdeps/i386/i686/tst-stack-align.h
|
||||
deleted file mode 100644
|
||||
index 975f26ef..00000000
|
||||
--- a/sysdeps/i386/i686/tst-stack-align.h
|
||||
+++ /dev/null
|
||||
@@ -1,44 +0,0 @@
|
||||
-/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include <stdio.h>
|
||||
-#include <stdint.h>
|
||||
-#ifndef __SSE__
|
||||
-#include_next <tst-stack-align.h>
|
||||
-#else
|
||||
-#include <xmmintrin.h>
|
||||
-
|
||||
-#define TEST_STACK_ALIGN() \
|
||||
- ({ \
|
||||
- __m128 _m; \
|
||||
- double _d = 12.0; \
|
||||
- long double _ld = 15.0; \
|
||||
- int _ret = 0; \
|
||||
- printf ("__m128: %p %zu\n", &_m, __alignof (__m128)); \
|
||||
- if ((((uintptr_t) &_m) & (__alignof (__m128) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- \
|
||||
- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- \
|
||||
- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- _ret; \
|
||||
- })
|
||||
-#endif
|
||||
diff --git a/sysdeps/i386/tst-stack-align.h b/sysdeps/i386/tst-stack-align.h
|
||||
deleted file mode 100644
|
||||
index 394ff773..00000000
|
||||
--- a/sysdeps/i386/tst-stack-align.h
|
||||
+++ /dev/null
|
||||
@@ -1,41 +0,0 @@
|
||||
-/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include <stdio.h>
|
||||
-#include <stdint.h>
|
||||
-
|
||||
-typedef struct { int i[4]; } int_al16 __attribute__((aligned (16)));
|
||||
-
|
||||
-#define TEST_STACK_ALIGN() \
|
||||
- ({ \
|
||||
- int_al16 _m; \
|
||||
- double _d = 12.0; \
|
||||
- long double _ld = 15.0; \
|
||||
- int _ret = 0; \
|
||||
- printf ("int_al16: %p %zu\n", &_m, __alignof (int_al16)); \
|
||||
- if ((((uintptr_t) &_m) & (__alignof (int_al16) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- \
|
||||
- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- \
|
||||
- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- _ret; \
|
||||
- })
|
||||
diff --git a/sysdeps/powerpc/tst-stack-align.h b/sysdeps/powerpc/tst-stack-align.h
|
||||
index 7fd7013b..d7400b28 100644
|
||||
--- a/sysdeps/powerpc/tst-stack-align.h
|
||||
+++ b/sysdeps/powerpc/tst-stack-align.h
|
||||
@@ -1,4 +1,5 @@
|
||||
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
|
||||
+/* Check stack alignment. PowerPC version.
|
||||
+ Copyright (C) 2005-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -15,10 +16,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
-#include <stdio.h>
|
||||
-#include <stdint.h>
|
||||
-
|
||||
-#define TEST_STACK_ALIGN() \
|
||||
+#define TEST_STACK_ALIGN_INIT() \
|
||||
({ \
|
||||
/* Altivec __vector int etc. needs 16byte aligned stack. \
|
||||
Instead of using altivec.h here, use aligned attribute instead. */ \
|
||||
@@ -27,20 +25,9 @@
|
||||
int _i __attribute__((aligned (16))); \
|
||||
int _j[3]; \
|
||||
} _s = { ._i = 18, ._j[0] = 19, ._j[1] = 20, ._j[2] = 21 }; \
|
||||
- double _d = 12.0; \
|
||||
- long double _ld = 15.0; \
|
||||
- int _ret = 0; \
|
||||
printf ("__vector int: { %d, %d, %d, %d } %p %zu\n", _s._i, _s._j[0], \
|
||||
_s._j[1], _s._j[2], &_s, __alignof (_s)); \
|
||||
- if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- \
|
||||
- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- \
|
||||
- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- _ret; \
|
||||
- })
|
||||
+ is_aligned (&_s, __alignof (_s)); \
|
||||
+ })
|
||||
+
|
||||
+#include_next <tst-stack-align.h>
|
||||
diff --git a/sysdeps/x86/tst-stack-align.h b/sysdeps/x86/tst-stack-align.h
|
||||
new file mode 100644
|
||||
index 00000000..02ecc72d
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/x86/tst-stack-align.h
|
||||
@@ -0,0 +1,28 @@
|
||||
+/* Check stack alignment. X86 version.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+typedef struct { int i[16]; } int_al16 __attribute__((aligned (16)));
|
||||
+
|
||||
+#define TEST_STACK_ALIGN_INIT() \
|
||||
+ ({ \
|
||||
+ int_al16 _m; \
|
||||
+ printf ("int_al16: %p %zu\n", &_m, __alignof (int_al16)); \
|
||||
+ is_aligned (&_m, __alignof (int_al16)); \
|
||||
+ })
|
||||
+
|
||||
+#include_next <tst-stack-align.h>
|
||||
diff --git a/sysdeps/x86_64/tst-stack-align.h b/sysdeps/x86_64/tst-stack-align.h
|
||||
deleted file mode 100644
|
||||
index b2ef77f6..00000000
|
||||
--- a/sysdeps/x86_64/tst-stack-align.h
|
||||
+++ /dev/null
|
||||
@@ -1,46 +0,0 @@
|
||||
-/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include <stdio.h>
|
||||
-#include <stdint.h>
|
||||
-
|
||||
-#define TEST_STACK_ALIGN() \
|
||||
- ({ \
|
||||
- /* AMD64 ABI mandates 16byte aligned stack. \
|
||||
- Unfortunately, current GCC doesn't support __int128 or __float128 \
|
||||
- types, so use aligned attribute instead. */ \
|
||||
- struct _S \
|
||||
- { \
|
||||
- int _i __attribute__((aligned (16))); \
|
||||
- int _pad[3]; \
|
||||
- } _s = { ._i = 18 }; \
|
||||
- double _d = 12.0; \
|
||||
- long double _ld = 15.0; \
|
||||
- int _ret = 0; \
|
||||
- printf ("__int128: %d %p %zu\n", _s._i, &_s, __alignof (_s)); \
|
||||
- if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- \
|
||||
- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- \
|
||||
- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
- _ret = 1; \
|
||||
- _ret; \
|
||||
- })
|
||||
--
|
||||
2.27.0
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
commit 849274d48fc59bfa6db3c713c8ced8026b20f3b7
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Nov 16 19:55:35 2023 +0100
|
||||
|
||||
elf: Fix force_first handling in dlclose (bug 30981)
|
||||
|
||||
The force_first parameter was ineffective because the dlclose'd
|
||||
object was not necessarily the first in the maps array. Also
|
||||
enable force_first handling unconditionally, regardless of namespace.
|
||||
The initial object in a namespace should be destructed first, too.
|
||||
|
||||
The _dl_sort_maps_dfs function had early returns for relocation
|
||||
dependency processing which broke force_first handling, too, and
|
||||
this is fixed in this change as well.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||
index 22225efb3226c3e1..16a39f5bf17b440f 100644
|
||||
--- a/elf/dl-close.c
|
||||
+++ b/elf/dl-close.c
|
||||
@@ -182,6 +182,16 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
}
|
||||
assert (idx == nloaded);
|
||||
|
||||
+ /* Put the dlclose'd map first, so that its destructor runs first.
|
||||
+ The map variable is NULL after a retry. */
|
||||
+ if (map != NULL)
|
||||
+ {
|
||||
+ maps[map->l_idx] = maps[0];
|
||||
+ maps[map->l_idx]->l_idx = map->l_idx;
|
||||
+ maps[0] = map;
|
||||
+ maps[0]->l_idx = 0;
|
||||
+ }
|
||||
+
|
||||
/* Keep track of the lowest index link map we have covered already. */
|
||||
int done_index = -1;
|
||||
while (++done_index < nloaded)
|
||||
@@ -255,9 +265,10 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
}
|
||||
}
|
||||
|
||||
- /* Sort the entries. We can skip looking for the binary itself which is
|
||||
- at the front of the search list for the main namespace. */
|
||||
- _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
|
||||
+ /* Sort the entries. Unless retrying, the maps[0] object (the
|
||||
+ original argument to dlclose) needs to remain first, so that its
|
||||
+ destructor runs first. */
|
||||
+ _dl_sort_maps (maps, nloaded, /* force_first */ map != NULL, true);
|
||||
|
||||
/* Call all termination functions at once. */
|
||||
bool unload_any = false;
|
||||
@@ -768,7 +779,11 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
/* Recheck if we need to retry, release the lock. */
|
||||
out:
|
||||
if (dl_close_state == rerun)
|
||||
- goto retry;
|
||||
+ {
|
||||
+ /* The map may have been deallocated. */
|
||||
+ map = NULL;
|
||||
+ goto retry;
|
||||
+ }
|
||||
|
||||
dl_close_state = not_pending;
|
||||
}
|
||||
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||
index aeb79b40b45054c0..c17ac325eca658ef 100644
|
||||
--- a/elf/dl-sort-maps.c
|
||||
+++ b/elf/dl-sort-maps.c
|
||||
@@ -260,13 +260,12 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
The below memcpy is not needed in the do_reldeps case here,
|
||||
since we wrote back to maps[] during DFS traversal. */
|
||||
if (maps_head == maps)
|
||||
- return;
|
||||
+ break;
|
||||
}
|
||||
assert (maps_head == maps);
|
||||
- return;
|
||||
}
|
||||
-
|
||||
- memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
|
||||
+ else
|
||||
+ memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
|
||||
|
||||
/* Skipping the first object at maps[0] is not valid in general,
|
||||
since traversing along object dependency-links may "find" that
|
||||
diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
|
||||
index 4bf9052db16fb352..cf6453e9eb85ac65 100644
|
||||
--- a/elf/dso-sort-tests-1.def
|
||||
+++ b/elf/dso-sort-tests-1.def
|
||||
@@ -56,14 +56,16 @@ output: b>a>{}<a<b
|
||||
# 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 older dynamic_sort=1 algorithm originally did not achieve this,
|
||||
+# but this was a bug in the way _dl_sort_maps was called from _dl_close_worker,
|
||||
+# effectively disabling proper force_first handling.
|
||||
+# The new dynamic_sort=2 algorithm shows the effect of the simpler force_first
|
||||
+# handling: the a object is simply moved to the front.
|
||||
# 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(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(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<b<c<d<g<f<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[<a<g<f<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).
|
|
@ -1,35 +0,0 @@
|
|||
commit b893410be304ddcea0bd43f537a13e8b18d37cf2
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 27 11:28:07 2023 +0100
|
||||
|
||||
elf: In _dl_relocate_object, skip processing if object is relocated
|
||||
|
||||
This is just a minor optimization. It also makes it more obvious that
|
||||
_dl_relocate_object can be called multiple times.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
|
||||
index 7a84b1fa8c3a7fdd..a80a54fb013adab5 100644
|
||||
--- a/elf/dl-reloc.c
|
||||
+++ b/elf/dl-reloc.c
|
||||
@@ -165,6 +165,9 @@ void
|
||||
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
int reloc_mode, int consider_profiling)
|
||||
{
|
||||
+ if (l->l_relocated)
|
||||
+ return;
|
||||
+
|
||||
struct textrels
|
||||
{
|
||||
caddr_t start;
|
||||
@@ -202,9 +205,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
# define consider_symbind 0
|
||||
#endif
|
||||
|
||||
- if (l->l_relocated)
|
||||
- return;
|
||||
-
|
||||
/* If DT_BIND_NOW is set relocate all references in this object. We
|
||||
do not do this if we are profiling, of course. */
|
||||
// XXX Correct for auditing?
|
|
@ -1,121 +0,0 @@
|
|||
commit a74c2e1cbc8673dd7e97aae2f2705392e2ccc3f6
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 27 11:28:10 2023 +0100
|
||||
|
||||
elf: Introduce the _dl_open_relocate_one_object function
|
||||
|
||||
It is extracted from dl_open_worker_begin.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||
index e82e53ff8b38fa11..1505fdb73088dcdb 100644
|
||||
--- a/elf/dl-open.c
|
||||
+++ b/elf/dl-open.c
|
||||
@@ -466,6 +466,50 @@ activate_nodelete (struct link_map *new)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Relocate the object L. *RELOCATION_IN_PROGRESS controls whether
|
||||
+ the debugger is notified of the start of relocation processing. */
|
||||
+static void
|
||||
+_dl_open_relocate_one_object (struct dl_open_args *args, struct r_debug *r,
|
||||
+ struct link_map *l, int reloc_mode,
|
||||
+ bool *relocation_in_progress)
|
||||
+{
|
||||
+ if (l->l_real->l_relocated)
|
||||
+ return;
|
||||
+
|
||||
+ if (!*relocation_in_progress)
|
||||
+ {
|
||||
+ /* Notify the debugger that relocations are about to happen. */
|
||||
+ LIBC_PROBE (reloc_start, 2, args->nsid, r);
|
||||
+ *relocation_in_progress = true;
|
||||
+ }
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+ if (__glibc_unlikely (GLRO(dl_profile) != NULL))
|
||||
+ {
|
||||
+ /* If this here is the shared object which we want to profile
|
||||
+ make sure the profile is started. We can find out whether
|
||||
+ this is necessary or not by observing the `_dl_profile_map'
|
||||
+ variable. If it was NULL but is not NULL afterwards we must
|
||||
+ start the profiling. */
|
||||
+ struct link_map *old_profile_map = GL(dl_profile_map);
|
||||
+
|
||||
+ _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
|
||||
+
|
||||
+ if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
|
||||
+ {
|
||||
+ /* We must prepare the profiling. */
|
||||
+ _dl_start_profile ();
|
||||
+
|
||||
+ /* Prevent unloading the object. */
|
||||
+ GL(dl_profile_map)->l_nodelete_active = true;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* struct dl_init_args and call_dl_init are used to call _dl_init with
|
||||
exception handling disabled. */
|
||||
struct dl_init_args
|
||||
@@ -638,7 +682,7 @@ dl_open_worker_begin (void *a)
|
||||
}
|
||||
while (l != NULL);
|
||||
|
||||
- int relocation_in_progress = 0;
|
||||
+ bool relocation_in_progress = false;
|
||||
|
||||
/* Perform relocation. This can trigger lazy binding in IFUNC
|
||||
resolvers. For NODELETE mappings, these dependencies are not
|
||||
@@ -649,44 +693,8 @@ dl_open_worker_begin (void *a)
|
||||
are undefined anyway, so this is not a problem. */
|
||||
|
||||
for (unsigned int i = last; i-- > first; )
|
||||
- {
|
||||
- l = new->l_initfini[i];
|
||||
-
|
||||
- if (l->l_real->l_relocated)
|
||||
- continue;
|
||||
-
|
||||
- if (! relocation_in_progress)
|
||||
- {
|
||||
- /* Notify the debugger that relocations are about to happen. */
|
||||
- LIBC_PROBE (reloc_start, 2, args->nsid, r);
|
||||
- relocation_in_progress = 1;
|
||||
- }
|
||||
-
|
||||
-#ifdef SHARED
|
||||
- if (__glibc_unlikely (GLRO(dl_profile) != NULL))
|
||||
- {
|
||||
- /* If this here is the shared object which we want to profile
|
||||
- make sure the profile is started. We can find out whether
|
||||
- this is necessary or not by observing the `_dl_profile_map'
|
||||
- variable. If it was NULL but is not NULL afterwards we must
|
||||
- start the profiling. */
|
||||
- struct link_map *old_profile_map = GL(dl_profile_map);
|
||||
-
|
||||
- _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
|
||||
-
|
||||
- if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
|
||||
- {
|
||||
- /* We must prepare the profiling. */
|
||||
- _dl_start_profile ();
|
||||
-
|
||||
- /* Prevent unloading the object. */
|
||||
- GL(dl_profile_map)->l_nodelete_active = true;
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
-#endif
|
||||
- _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
|
||||
- }
|
||||
+ _dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
|
||||
+ &relocation_in_progress);
|
||||
|
||||
/* This only performs the memory allocations. The actual update of
|
||||
the scopes happens below, after failure is impossible. */
|
|
@ -1,223 +0,0 @@
|
|||
commit 78ca44da0160a0b442f0ca1f253e3360f044b2ec
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 27 11:28:13 2023 +0100
|
||||
|
||||
elf: Relocate libc.so early during startup and dlmopen (bug 31083)
|
||||
|
||||
This makes it more likely that objects without dependencies can
|
||||
use IFUNC resolvers in libc.so.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile
|
||||
(differences in test backports)
|
||||
elf/rtld.c
|
||||
(removal of prelink support upstream)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 634c3113227d64a6..6f0f36cdfe3961e8 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -386,6 +386,8 @@ tests += \
|
||||
tst-nodelete2 \
|
||||
tst-nodelete-dlclose \
|
||||
tst-nodelete-opened \
|
||||
+ tst-nodeps1 \
|
||||
+ tst-nodeps2 \
|
||||
tst-noload \
|
||||
tst-null-argv \
|
||||
tst-relsort1 \
|
||||
@@ -740,6 +742,8 @@ modules-names = \
|
||||
tst-nodelete-dlclose-dso \
|
||||
tst-nodelete-dlclose-plugin \
|
||||
tst-nodelete-opened-lib \
|
||||
+ tst-nodeps1-mod \
|
||||
+ tst-nodeps2-mod \
|
||||
tst-null-argv-lib \
|
||||
tst-relsort1mod1 \
|
||||
tst-relsort1mod2 \
|
||||
@@ -886,8 +890,13 @@ modules-execstack-yes = tst-execstack-mod
|
||||
extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
|
||||
|
||||
# filtmod1.so has a special rule
|
||||
-modules-names-nobuild := filtmod1 \
|
||||
- tst-audit24bmod1 tst-audit24bmod2
|
||||
+modules-names-nobuild += \
|
||||
+ filtmod1 \
|
||||
+ tst-audit24bmod1 \
|
||||
+ tst-audit24bmod2 \
|
||||
+ tst-nodeps1-mod \
|
||||
+ tst-nodeps2-mod \
|
||||
+ # modules-names-nobuild
|
||||
|
||||
tests += $(tests-static)
|
||||
|
||||
@@ -2697,3 +2706,19 @@ $(objpfx)tst-dlmopen-twice: $(libdl)
|
||||
$(objpfx)tst-dlmopen-twice.out: \
|
||||
$(objpfx)tst-dlmopen-twice-mod1.so \
|
||||
$(objpfx)tst-dlmopen-twice-mod2.so
|
||||
+
|
||||
+# The object tst-nodeps1-mod.so has no explicit dependencies on libc.so.
|
||||
+$(objpfx)tst-nodeps1-mod.so: $(objpfx)tst-nodeps1-mod.os
|
||||
+ $(LINK.o) -nostartfiles -nostdlib -shared -o $@ $^
|
||||
+tst-nodeps1.so-no-z-defs = yes
|
||||
+# Link libc.so before the test module with the IFUNC resolver reference.
|
||||
+LDFLAGS-tst-nodeps1 = $(common-objpfx)libc.so $(objpfx)tst-nodeps1-mod.so
|
||||
+$(objpfx)tst-nodeps1: $(objpfx)tst-nodeps1-mod.so
|
||||
+# Reuse the tst-nodeps1 module. Link libc.so before the test module
|
||||
+# with the IFUNC resolver reference.
|
||||
+$(objpfx)tst-nodeps2-mod.so: $(common-objpfx)libc.so \
|
||||
+ $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.os
|
||||
+ $(LINK.o) -Wl,--no-as-needed -nostartfiles -nostdlib -shared -o $@ $^
|
||||
+$(objpfx)tst-nodeps2: $(libdl)
|
||||
+$(objpfx)tst-nodeps2.out: \
|
||||
+ $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.so
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||
index 1505fdb73088dcdb..6508b0ea545440b8 100644
|
||||
--- a/elf/dl-open.c
|
||||
+++ b/elf/dl-open.c
|
||||
@@ -692,6 +692,17 @@ dl_open_worker_begin (void *a)
|
||||
them. However, such relocation dependencies in IFUNC resolvers
|
||||
are undefined anyway, so this is not a problem. */
|
||||
|
||||
+ /* Ensure that libc is relocated first. This helps with the
|
||||
+ execution of IFUNC resolvers in libc, and matters only to newly
|
||||
+ created dlmopen namespaces. Do not do this for static dlopen
|
||||
+ because libc has relocations against ld.so, which may not have
|
||||
+ been relocated at this point. */
|
||||
+#ifdef SHARED
|
||||
+ if (GL(dl_ns)[args->nsid].libc_map != NULL)
|
||||
+ _dl_open_relocate_one_object (args, r, GL(dl_ns)[args->nsid].libc_map,
|
||||
+ reloc_mode, &relocation_in_progress);
|
||||
+#endif
|
||||
+
|
||||
for (unsigned int i = last; i-- > first; )
|
||||
_dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
|
||||
&relocation_in_progress);
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index cd2cc4024a3581c2..502d2a1c58505d88 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -2414,11 +2414,17 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||
objects. We do not re-relocate the dynamic linker itself in this
|
||||
loop because that could result in the GOT entries for functions we
|
||||
call being changed, and that would break us. It is safe to relocate
|
||||
- the dynamic linker out of order because it has no copy relocs (we
|
||||
- know that because it is self-contained). */
|
||||
+ the dynamic linker out of order because it has no copy relocations.
|
||||
+ Likewise for libc, which is relocated early to ensure that IFUNC
|
||||
+ resolvers in libc work. */
|
||||
|
||||
int consider_profiling = GLRO(dl_profile) != NULL;
|
||||
|
||||
+ if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
|
||||
+ _dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map,
|
||||
+ GL(dl_ns)[LM_ID_BASE].libc_map->l_scope,
|
||||
+ GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling);
|
||||
+
|
||||
/* If we are profiling we also must do lazy reloaction. */
|
||||
GLRO(dl_lazy) |= consider_profiling;
|
||||
|
||||
diff --git a/elf/tst-nodeps1-mod.c b/elf/tst-nodeps1-mod.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..45c8e3c631251a89
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-nodeps1-mod.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* Test module with no libc.so dependency and string function references.
|
||||
+ 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 <string.h>
|
||||
+
|
||||
+/* Some references to libc symbols which are likely to have IFUNC
|
||||
+ resolvers. If they do not, this module does not exercise bug 31083. */
|
||||
+void *memcpy_pointer = memcpy;
|
||||
+void *memmove_pointer = memmove;
|
||||
+void *memset_pointer = memset;
|
||||
diff --git a/elf/tst-nodeps1.c b/elf/tst-nodeps1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1a8bde36cdb71446
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-nodeps1.c
|
||||
@@ -0,0 +1,23 @@
|
||||
+/* Test initially loaded module with implicit libc.so dependency (bug 31083).
|
||||
+ 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/>. */
|
||||
+
|
||||
+/* Testing happens before main. */
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+}
|
||||
diff --git a/elf/tst-nodeps2-mod.c b/elf/tst-nodeps2-mod.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4913feee9b56e0e1
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-nodeps2-mod.c
|
||||
@@ -0,0 +1 @@
|
||||
+/* Empty test module which depends on tst-nodeps1-mod.so. */
|
||||
diff --git a/elf/tst-nodeps2.c b/elf/tst-nodeps2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0bdc8eeb8cba3a99
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-nodeps2.c
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* Test dlmopen with implicit libc.so dependency (bug 31083).
|
||||
+ 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 <support/xdlfcn.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ void *handle = xdlmopen (LM_ID_NEWLM, "tst-nodeps2-mod.so", RTLD_NOW);
|
||||
+ xdlclose (handle);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
|
@ -1,41 +0,0 @@
|
|||
commit b3bee76c5f59498b9c189608f0a3132e2013fa1a
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Dec 8 09:51:34 2023 +0100
|
||||
|
||||
elf: Initialize GLRO(dl_lazy) before relocating libc in dynamic startup
|
||||
|
||||
GLRO(dl_lazy) is used to set the parameters for the early
|
||||
_dl_relocate_object call, so the consider_profiling setting has to
|
||||
be applied before the call.
|
||||
|
||||
Fixes commit 78ca44da0160a0b442f0ca1f253e3360f044b2ec ("elf: Relocate
|
||||
libc.so early during startup and dlmopen (bug 31083)").
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
elf/rtld.c
|
||||
(removal of prelink support upstream)
|
||||
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 502d2a1c58505d88..4f317a2a874e6af7 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -2420,14 +2420,14 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||
|
||||
int consider_profiling = GLRO(dl_profile) != NULL;
|
||||
|
||||
+ /* If we are profiling we also must do lazy reloaction. */
|
||||
+ GLRO(dl_lazy) |= consider_profiling;
|
||||
+
|
||||
if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
|
||||
_dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map,
|
||||
GL(dl_ns)[LM_ID_BASE].libc_map->l_scope,
|
||||
GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling);
|
||||
|
||||
- /* If we are profiling we also must do lazy reloaction. */
|
||||
- GLRO(dl_lazy) |= consider_profiling;
|
||||
-
|
||||
RTLD_TIMING_VAR (start);
|
||||
rtld_timer_start (&start);
|
||||
unsigned i = main_map->l_searchlist.r_nlist;
|
|
@ -1,83 +0,0 @@
|
|||
commit c00b984fcd53f679ca2dafcd1aee2c89836e6e73
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Aug 29 08:28:31 2023 +0200
|
||||
|
||||
nscd: Skip unusable entries in first pass in prune_cache (bug 30800)
|
||||
|
||||
Previously, if an entry was marked unusable for any reason, but had
|
||||
not timed out yet, the assert would trigger.
|
||||
|
||||
One way to get into such state is if a data change is detected during
|
||||
re-validation of an entry. This causes the entry to be marked as not
|
||||
usable. If exits nscd soon after that, then the clock jumps
|
||||
backwards, and nscd restarted, the cache re-validation run after
|
||||
startup triggers the removed assert.
|
||||
|
||||
The change is more complicated than just the removal of the assert
|
||||
because entries marked as not usable should be garbage-collected in
|
||||
the second pass. To make this happen, it is necessary to update some
|
||||
book-keeping data.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/nscd/cache.c b/nscd/cache.c
|
||||
index efe4214d953edb30..2fd3f78ebb567bbe 100644
|
||||
--- a/nscd/cache.c
|
||||
+++ b/nscd/cache.c
|
||||
@@ -371,8 +371,11 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||
serv2str[runp->type], str, dh->timeout);
|
||||
}
|
||||
|
||||
- /* Check whether the entry timed out. */
|
||||
- if (dh->timeout < now)
|
||||
+ /* Check whether the entry timed out. Timed out entries
|
||||
+ will be revalidated. For unusable records, it is still
|
||||
+ necessary to record that the bucket needs to be scanned
|
||||
+ again below. */
|
||||
+ if (dh->timeout < now || !dh->usable)
|
||||
{
|
||||
/* This hash bucket could contain entries which need to
|
||||
be looked at. */
|
||||
@@ -384,7 +387,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||
/* We only have to look at the data of the first entries
|
||||
since the count information is kept in the data part
|
||||
which is shared. */
|
||||
- if (runp->first)
|
||||
+ if (runp->first && dh->usable)
|
||||
{
|
||||
|
||||
/* At this point there are two choices: we reload the
|
||||
@@ -400,9 +403,6 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||
{
|
||||
/* Remove the value. */
|
||||
dh->usable = false;
|
||||
-
|
||||
- /* We definitely have some garbage entries now. */
|
||||
- any = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -414,18 +414,15 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||
|
||||
time_t timeout = readdfcts[runp->type] (table, runp, dh);
|
||||
next_timeout = MIN (next_timeout, timeout);
|
||||
-
|
||||
- /* If the entry has been replaced, we might need
|
||||
- cleanup. */
|
||||
- any |= !dh->usable;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /* If the entry has been replaced, we might need cleanup. */
|
||||
+ any |= !dh->usable;
|
||||
}
|
||||
else
|
||||
- {
|
||||
- assert (dh->usable);
|
||||
- next_timeout = MIN (next_timeout, dh->timeout);
|
||||
- }
|
||||
+ /* Entry has not timed out and is usable. */
|
||||
+ next_timeout = MIN (next_timeout, dh->timeout);
|
||||
|
||||
run = runp->next;
|
||||
}
|
|
@ -1,237 +0,0 @@
|
|||
commit d0f07f7df8d9758c838674b70144ac73bcbd1634
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue May 30 13:25:50 2023 +0200
|
||||
|
||||
elf: Make more functions available for binding during dlclose (bug 30425)
|
||||
|
||||
Previously, after destructors for a DSO have been invoked, ld.so refused
|
||||
to bind against that DSO in all cases. Relax this restriction somewhat
|
||||
if the referencing object is itself a DSO that is being unloaded. This
|
||||
assumes that the symbol reference is not going to be stored anywhere.
|
||||
|
||||
The situation in the test case can arise fairly easily with C++ and
|
||||
objects that are built with different optimization levels and therefore
|
||||
define different functions with vague linkage.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile
|
||||
(usual test differences, link test with -ldl)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 6f0f36cdfe3961e8..ebf46a297d241d8f 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -362,6 +362,7 @@ tests += \
|
||||
tst-big-note \
|
||||
tst-debug1 \
|
||||
tst-deep1 \
|
||||
+ tst-dlclose-lazy \
|
||||
tst-dlmodcount \
|
||||
tst-dlmopen1 \
|
||||
tst-dlmopen3 \
|
||||
@@ -711,6 +712,8 @@ modules-names = \
|
||||
tst-deep1mod2 \
|
||||
tst-deep1mod3 \
|
||||
tst-dlmopen1mod \
|
||||
+ tst-dlclose-lazy-mod1 \
|
||||
+ tst-dlclose-lazy-mod2 \
|
||||
tst-dlmopen-dlerror-mod \
|
||||
tst-dlmopen-gethostbyname-mod \
|
||||
tst-dlmopen-twice-mod1 \
|
||||
@@ -2707,6 +2710,12 @@ $(objpfx)tst-dlmopen-twice.out: \
|
||||
$(objpfx)tst-dlmopen-twice-mod1.so \
|
||||
$(objpfx)tst-dlmopen-twice-mod2.so
|
||||
|
||||
+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: $(libdl)
|
||||
+$(objpfx)tst-dlclose-lazy.out: \
|
||||
+ $(objpfx)tst-dlclose-lazy-mod1.so $(objpfx)tst-dlclose-lazy-mod2.so
|
||||
+
|
||||
# The object tst-nodeps1-mod.so has no explicit dependencies on libc.so.
|
||||
$(objpfx)tst-nodeps1-mod.so: $(objpfx)tst-nodeps1-mod.os
|
||||
$(LINK.o) -nostartfiles -nostdlib -shared -o $@ $^
|
||||
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
|
||||
index 47acd134600b44b5..9e8f14b8483f5eba 100644
|
||||
--- a/elf/dl-lookup.c
|
||||
+++ b/elf/dl-lookup.c
|
||||
@@ -380,8 +380,25 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
|
||||
if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable)
|
||||
continue;
|
||||
|
||||
- /* Do not look into objects which are going to be removed. */
|
||||
- if (map->l_removed)
|
||||
+ /* Do not look into objects which are going to be removed,
|
||||
+ except when the referencing object itself is being removed.
|
||||
+
|
||||
+ The second part covers the situation when an object lazily
|
||||
+ binds to another object while running its destructor, but the
|
||||
+ destructor of the other object has already run, so that
|
||||
+ dlclose has set l_removed. It may not always be obvious how
|
||||
+ to avoid such a scenario to programmers creating DSOs,
|
||||
+ particularly if C++ vague linkage is involved and triggers
|
||||
+ symbol interposition.
|
||||
+
|
||||
+ Accepting these to-be-removed objects makes the lazy and
|
||||
+ BIND_NOW cases more similar. (With BIND_NOW, the symbol is
|
||||
+ resolved early, before the destructor call, so the issue does
|
||||
+ not arise.). Behavior matches the constructor scenario: the
|
||||
+ implementation allows binding to symbols of objects whose
|
||||
+ constructors have not run. In fact, not doing this would be
|
||||
+ mostly incompatible with symbol interposition. */
|
||||
+ if (map->l_removed && !(undef_map != NULL && undef_map->l_removed))
|
||||
continue;
|
||||
|
||||
/* Print some debugging info if wanted. */
|
||||
diff --git a/elf/tst-dlclose-lazy-mod1.c b/elf/tst-dlclose-lazy-mod1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8439dc1925cc8b41
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-dlclose-lazy-mod1.c
|
||||
@@ -0,0 +1,36 @@
|
||||
+/* Lazy binding during dlclose. Directly loaded module.
|
||||
+ 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/>. */
|
||||
+
|
||||
+/* This function is called from exported_function below. It is only
|
||||
+ defined in this module. The weak attribute mimics how G++
|
||||
+ implements vague linkage for C++. */
|
||||
+void __attribute__ ((weak))
|
||||
+lazily_bound_exported_function (void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+/* Called from tst-dlclose-lazy-mod2.so. */
|
||||
+void
|
||||
+exported_function (int call_it)
|
||||
+{
|
||||
+ if (call_it)
|
||||
+ /* Previous to the fix this would crash when called during dlclose
|
||||
+ since symbols from the DSO were no longer available for binding
|
||||
+ (bug 30425) after the DSO started being closed by dlclose. */
|
||||
+ lazily_bound_exported_function ();
|
||||
+}
|
||||
diff --git a/elf/tst-dlclose-lazy-mod2.c b/elf/tst-dlclose-lazy-mod2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..767f69ffdb23a685
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-dlclose-lazy-mod2.c
|
||||
@@ -0,0 +1,49 @@
|
||||
+/* Lazy binding during dlclose. Indirectly loaded module.
|
||||
+ 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 <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+void
|
||||
+exported_function (int ignored)
|
||||
+{
|
||||
+ /* This function is interposed from tst-dlclose-lazy-mod1.so and
|
||||
+ thus never called. */
|
||||
+ abort ();
|
||||
+}
|
||||
+
|
||||
+static void __attribute__ ((constructor))
|
||||
+init (void)
|
||||
+{
|
||||
+ puts ("info: tst-dlclose-lazy-mod2.so constructor called");
|
||||
+
|
||||
+ /* Trigger lazy binding to the definition in
|
||||
+ tst-dlclose-lazy-mod1.so, but not for
|
||||
+ lazily_bound_exported_function in that module. */
|
||||
+ exported_function (0);
|
||||
+}
|
||||
+
|
||||
+static void __attribute__ ((destructor))
|
||||
+fini (void)
|
||||
+{
|
||||
+ puts ("info: tst-dlclose-lazy-mod2.so destructor called");
|
||||
+
|
||||
+ /* Trigger the lazily_bound_exported_function call in
|
||||
+ exported_function in tst-dlclose-lazy-mod1.so. */
|
||||
+ exported_function (1);
|
||||
+}
|
||||
diff --git a/elf/tst-dlclose-lazy.c b/elf/tst-dlclose-lazy.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..976a6bb6f64fa981
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-dlclose-lazy.c
|
||||
@@ -0,0 +1,47 @@
|
||||
+/* Test lazy binding during dlclose (bug 30425).
|
||||
+ 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/>. */
|
||||
+
|
||||
+/* This test re-creates a situation that can arise naturally for C++
|
||||
+ applications due to the use of vague linkage and differences in the
|
||||
+ set of compiler-emitted functions. A function in
|
||||
+ tst-dlclose-lazy-mod1.so (exported_function) interposes a function
|
||||
+ in tst-dlclose-lazy-mod2.so. This function is called from the
|
||||
+ destructor in tst-dlclose-lazy-mod2.so, after the destructor for
|
||||
+ tst-dlclose-lazy-mod1.so has already completed. Prior to the fix
|
||||
+ for bug 30425, this would lead to a lazy binding failure in
|
||||
+ tst-dlclose-lazy-mod1.so because dlclose had already marked the DSO
|
||||
+ as unavailable for binding (by setting l_removed). */
|
||||
+
|
||||
+#include <dlfcn.h>
|
||||
+#include <support/xdlfcn.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ /* Load tst-dlclose-lazy-mod1.so, indirectly loading
|
||||
+ tst-dlclose-lazy-mod2.so. */
|
||||
+ void *handle = xdlopen ("tst-dlclose-lazy-mod1.so", RTLD_GLOBAL | RTLD_LAZY);
|
||||
+
|
||||
+ /* Invoke the destructor of tst-dlclose-lazy-mod2.so, which calls
|
||||
+ into tst-dlclose-lazy-mod1.so after its destructor has been
|
||||
+ called. */
|
||||
+ xdlclose (handle);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
|
@ -1,27 +0,0 @@
|
|||
commit ecc7c3deb9f347649c2078fcc0f94d4cedf92d60
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Jan 2 14:36:17 2024 +0100
|
||||
|
||||
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)").
|
||||
|
||||
diff --git a/libio/wfileops.c b/libio/wfileops.c
|
||||
index d3deb34ba058ca39..6a6421f8880f9356 100644
|
||||
--- a/libio/wfileops.c
|
||||
+++ b/libio/wfileops.c
|
||||
@@ -57,7 +57,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. */
|
|
@ -1,22 +0,0 @@
|
|||
Work around in the test case, the fact that RHEL-8 NSS modules
|
||||
infrastructure incorrectly allows merging in the hosts database. This
|
||||
is a RHEL-8 only fix.
|
||||
|
||||
diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c
|
||||
index efca6cd1837a172a..c35e752896eceb2a 100644
|
||||
--- a/nss/tst-nss-gai-actions.c
|
||||
+++ b/nss/tst-nss-gai-actions.c
|
||||
@@ -87,6 +87,13 @@ do_one_test (int action, int family, bool canon)
|
||||
case ACTION_MERGE:
|
||||
if (ret == 0)
|
||||
{
|
||||
+ if (hints.ai_flags == 0 && hints.ai_family == AF_INET)
|
||||
+ {
|
||||
+ printf ("***** RHEL-8 limitation: "
|
||||
+ "NSS modules infrastructure incorrectly allows MERGE\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
char *formatted = support_format_addrinfo (ai, ret);
|
||||
|
||||
printf ("merge unexpectedly succeeded:\n %s\n", formatted);
|
|
@ -1,979 +0,0 @@
|
|||
commit 228cdb00a045ae3b68a91b35c7548bab6029446e
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Thu Mar 17 11:44:34 2022 +0530
|
||||
|
||||
Simplify allocations and fix merge and continue actions [BZ #28931]
|
||||
|
||||
Allocations for address tuples is currently a bit confusing because of
|
||||
the pointer chasing through PAT, making it hard to observe the sequence
|
||||
in which allocations have been made. Narrow scope of the pointer
|
||||
chasing through PAT so that it is only used where necessary.
|
||||
|
||||
This also tightens actions behaviour with the hosts database in
|
||||
getaddrinfo to comply with the manual text. The "continue" action
|
||||
discards previous results and the "merge" action results in an immedate
|
||||
lookup failure. Consequently, chaining of allocations across modules is
|
||||
no longer necessary, thus opening up cleanup opportunities.
|
||||
|
||||
A test has been added that checks some combinations to ensure that they
|
||||
work correctly.
|
||||
|
||||
Resolves: BZ #28931
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
(cherry picked from commit 1c37b8022e8763fedbb3f79c02e05c6acfe5a215)
|
||||
|
||||
Conflicts:
|
||||
nss/Makefile
|
||||
(Missing test cases)
|
||||
sysdeps/posix/getaddrinfo.c
|
||||
(RES_USE_INET6 still present in RHEL-8 and NSS module traversal rewrite
|
||||
not in RHEL-8)
|
||||
|
||||
diff --git a/nss/Makefile b/nss/Makefile
|
||||
index e8a7d9c7b3cefcdf..cfb255c6e7a3a4de 100644
|
||||
--- a/nss/Makefile
|
||||
+++ b/nss/Makefile
|
||||
@@ -65,7 +65,8 @@ xtests = bug-erange
|
||||
|
||||
tests-container = \
|
||||
tst-nss-db-endpwent \
|
||||
- tst-nss-db-endgrent
|
||||
+ tst-nss-db-endgrent \
|
||||
+ tst-nss-gai-actions
|
||||
|
||||
# Tests which need libdl
|
||||
ifeq (yes,$(build-shared))
|
||||
diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..efca6cd1837a172a
|
||||
--- /dev/null
|
||||
+++ b/nss/tst-nss-gai-actions.c
|
||||
@@ -0,0 +1,149 @@
|
||||
+/* Test continue and merge NSS actions for getaddrinfo.
|
||||
+ 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 <dlfcn.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
+#include <nss.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/format_nss.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+enum
|
||||
+{
|
||||
+ ACTION_MERGE = 0,
|
||||
+ ACTION_CONTINUE,
|
||||
+};
|
||||
+
|
||||
+static const char *
|
||||
+family_str (int family)
|
||||
+{
|
||||
+ switch (family)
|
||||
+ {
|
||||
+ case AF_UNSPEC:
|
||||
+ return "AF_UNSPEC";
|
||||
+ case AF_INET:
|
||||
+ return "AF_INET";
|
||||
+ default:
|
||||
+ __builtin_unreachable ();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const char *
|
||||
+action_str (int action)
|
||||
+{
|
||||
+ switch (action)
|
||||
+ {
|
||||
+ case ACTION_MERGE:
|
||||
+ return "merge";
|
||||
+ case ACTION_CONTINUE:
|
||||
+ return "continue";
|
||||
+ default:
|
||||
+ __builtin_unreachable ();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+do_one_test (int action, int family, bool canon)
|
||||
+{
|
||||
+ struct addrinfo hints =
|
||||
+ {
|
||||
+ .ai_family = family,
|
||||
+ };
|
||||
+
|
||||
+ struct addrinfo *ai;
|
||||
+
|
||||
+ if (canon)
|
||||
+ hints.ai_flags = AI_CANONNAME;
|
||||
+
|
||||
+ printf ("***** Testing \"files [SUCCESS=%s] files\" for family %s, %s\n",
|
||||
+ action_str (action), family_str (family),
|
||||
+ canon ? "AI_CANONNAME" : "");
|
||||
+
|
||||
+ int ret = getaddrinfo ("example.org", "80", &hints, &ai);
|
||||
+
|
||||
+ switch (action)
|
||||
+ {
|
||||
+ case ACTION_MERGE:
|
||||
+ if (ret == 0)
|
||||
+ {
|
||||
+ char *formatted = support_format_addrinfo (ai, ret);
|
||||
+
|
||||
+ printf ("merge unexpectedly succeeded:\n %s\n", formatted);
|
||||
+ support_record_failure ();
|
||||
+ free (formatted);
|
||||
+ }
|
||||
+ else
|
||||
+ return;
|
||||
+ case ACTION_CONTINUE:
|
||||
+ {
|
||||
+ char *formatted = support_format_addrinfo (ai, ret);
|
||||
+
|
||||
+ /* Verify that the result appears exactly once. */
|
||||
+ const char *expected = "address: STREAM/TCP 192.0.0.1 80\n"
|
||||
+ "address: DGRAM/UDP 192.0.0.1 80\n"
|
||||
+ "address: RAW/IP 192.0.0.1 80\n";
|
||||
+
|
||||
+ const char *contains = strstr (formatted, expected);
|
||||
+ const char *contains2 = NULL;
|
||||
+
|
||||
+ if (contains != NULL)
|
||||
+ contains2 = strstr (contains + strlen (expected), expected);
|
||||
+
|
||||
+ if (contains == NULL || contains2 != NULL)
|
||||
+ {
|
||||
+ printf ("continue failed:\n%s\n", formatted);
|
||||
+ support_record_failure ();
|
||||
+ }
|
||||
+
|
||||
+ free (formatted);
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ __builtin_unreachable ();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+do_one_test_set (int action)
|
||||
+{
|
||||
+ char buf[32];
|
||||
+
|
||||
+ snprintf (buf, sizeof (buf), "files [SUCCESS=%s] files",
|
||||
+ action_str (action));
|
||||
+ __nss_configure_lookup ("hosts", buf);
|
||||
+
|
||||
+ do_one_test (action, AF_UNSPEC, false);
|
||||
+ do_one_test (action, AF_INET, false);
|
||||
+ do_one_test (action, AF_INET, true);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ do_one_test_set (ACTION_CONTINUE);
|
||||
+ do_one_test_set (ACTION_MERGE);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/nss/tst-nss-gai-actions.root/etc/host.conf b/nss/tst-nss-gai-actions.root/etc/host.conf
|
||||
new file mode 100644
|
||||
index 0000000000000000..d1a59f73a90f2993
|
||||
--- /dev/null
|
||||
+++ b/nss/tst-nss-gai-actions.root/etc/host.conf
|
||||
@@ -0,0 +1 @@
|
||||
+multi on
|
||||
diff --git a/nss/tst-nss-gai-actions.root/etc/hosts b/nss/tst-nss-gai-actions.root/etc/hosts
|
||||
new file mode 100644
|
||||
index 0000000000000000..50ce9774dc2c21d9
|
||||
--- /dev/null
|
||||
+++ b/nss/tst-nss-gai-actions.root/etc/hosts
|
||||
@@ -0,0 +1,508 @@
|
||||
+192.0.0.1 example.org
|
||||
+192.0.0.2 example.org
|
||||
+192.0.0.3 example.org
|
||||
+192.0.0.4 example.org
|
||||
+192.0.0.5 example.org
|
||||
+192.0.0.6 example.org
|
||||
+192.0.0.7 example.org
|
||||
+192.0.0.8 example.org
|
||||
+192.0.0.9 example.org
|
||||
+192.0.0.10 example.org
|
||||
+192.0.0.11 example.org
|
||||
+192.0.0.12 example.org
|
||||
+192.0.0.13 example.org
|
||||
+192.0.0.14 example.org
|
||||
+192.0.0.15 example.org
|
||||
+192.0.0.16 example.org
|
||||
+192.0.0.17 example.org
|
||||
+192.0.0.18 example.org
|
||||
+192.0.0.19 example.org
|
||||
+192.0.0.20 example.org
|
||||
+192.0.0.21 example.org
|
||||
+192.0.0.22 example.org
|
||||
+192.0.0.23 example.org
|
||||
+192.0.0.24 example.org
|
||||
+192.0.0.25 example.org
|
||||
+192.0.0.26 example.org
|
||||
+192.0.0.27 example.org
|
||||
+192.0.0.28 example.org
|
||||
+192.0.0.29 example.org
|
||||
+192.0.0.30 example.org
|
||||
+192.0.0.31 example.org
|
||||
+192.0.0.32 example.org
|
||||
+192.0.0.33 example.org
|
||||
+192.0.0.34 example.org
|
||||
+192.0.0.35 example.org
|
||||
+192.0.0.36 example.org
|
||||
+192.0.0.37 example.org
|
||||
+192.0.0.38 example.org
|
||||
+192.0.0.39 example.org
|
||||
+192.0.0.40 example.org
|
||||
+192.0.0.41 example.org
|
||||
+192.0.0.42 example.org
|
||||
+192.0.0.43 example.org
|
||||
+192.0.0.44 example.org
|
||||
+192.0.0.45 example.org
|
||||
+192.0.0.46 example.org
|
||||
+192.0.0.47 example.org
|
||||
+192.0.0.48 example.org
|
||||
+192.0.0.49 example.org
|
||||
+192.0.0.50 example.org
|
||||
+192.0.0.51 example.org
|
||||
+192.0.0.52 example.org
|
||||
+192.0.0.53 example.org
|
||||
+192.0.0.54 example.org
|
||||
+192.0.0.55 example.org
|
||||
+192.0.0.56 example.org
|
||||
+192.0.0.57 example.org
|
||||
+192.0.0.58 example.org
|
||||
+192.0.0.59 example.org
|
||||
+192.0.0.60 example.org
|
||||
+192.0.0.61 example.org
|
||||
+192.0.0.62 example.org
|
||||
+192.0.0.63 example.org
|
||||
+192.0.0.64 example.org
|
||||
+192.0.0.65 example.org
|
||||
+192.0.0.66 example.org
|
||||
+192.0.0.67 example.org
|
||||
+192.0.0.68 example.org
|
||||
+192.0.0.69 example.org
|
||||
+192.0.0.70 example.org
|
||||
+192.0.0.71 example.org
|
||||
+192.0.0.72 example.org
|
||||
+192.0.0.73 example.org
|
||||
+192.0.0.74 example.org
|
||||
+192.0.0.75 example.org
|
||||
+192.0.0.76 example.org
|
||||
+192.0.0.77 example.org
|
||||
+192.0.0.78 example.org
|
||||
+192.0.0.79 example.org
|
||||
+192.0.0.80 example.org
|
||||
+192.0.0.81 example.org
|
||||
+192.0.0.82 example.org
|
||||
+192.0.0.83 example.org
|
||||
+192.0.0.84 example.org
|
||||
+192.0.0.85 example.org
|
||||
+192.0.0.86 example.org
|
||||
+192.0.0.87 example.org
|
||||
+192.0.0.88 example.org
|
||||
+192.0.0.89 example.org
|
||||
+192.0.0.90 example.org
|
||||
+192.0.0.91 example.org
|
||||
+192.0.0.92 example.org
|
||||
+192.0.0.93 example.org
|
||||
+192.0.0.94 example.org
|
||||
+192.0.0.95 example.org
|
||||
+192.0.0.96 example.org
|
||||
+192.0.0.97 example.org
|
||||
+192.0.0.98 example.org
|
||||
+192.0.0.99 example.org
|
||||
+192.0.0.100 example.org
|
||||
+192.0.0.101 example.org
|
||||
+192.0.0.102 example.org
|
||||
+192.0.0.103 example.org
|
||||
+192.0.0.104 example.org
|
||||
+192.0.0.105 example.org
|
||||
+192.0.0.106 example.org
|
||||
+192.0.0.107 example.org
|
||||
+192.0.0.108 example.org
|
||||
+192.0.0.109 example.org
|
||||
+192.0.0.110 example.org
|
||||
+192.0.0.111 example.org
|
||||
+192.0.0.112 example.org
|
||||
+192.0.0.113 example.org
|
||||
+192.0.0.114 example.org
|
||||
+192.0.0.115 example.org
|
||||
+192.0.0.116 example.org
|
||||
+192.0.0.117 example.org
|
||||
+192.0.0.118 example.org
|
||||
+192.0.0.119 example.org
|
||||
+192.0.0.120 example.org
|
||||
+192.0.0.121 example.org
|
||||
+192.0.0.122 example.org
|
||||
+192.0.0.123 example.org
|
||||
+192.0.0.124 example.org
|
||||
+192.0.0.125 example.org
|
||||
+192.0.0.126 example.org
|
||||
+192.0.0.127 example.org
|
||||
+192.0.0.128 example.org
|
||||
+192.0.0.129 example.org
|
||||
+192.0.0.130 example.org
|
||||
+192.0.0.131 example.org
|
||||
+192.0.0.132 example.org
|
||||
+192.0.0.133 example.org
|
||||
+192.0.0.134 example.org
|
||||
+192.0.0.135 example.org
|
||||
+192.0.0.136 example.org
|
||||
+192.0.0.137 example.org
|
||||
+192.0.0.138 example.org
|
||||
+192.0.0.139 example.org
|
||||
+192.0.0.140 example.org
|
||||
+192.0.0.141 example.org
|
||||
+192.0.0.142 example.org
|
||||
+192.0.0.143 example.org
|
||||
+192.0.0.144 example.org
|
||||
+192.0.0.145 example.org
|
||||
+192.0.0.146 example.org
|
||||
+192.0.0.147 example.org
|
||||
+192.0.0.148 example.org
|
||||
+192.0.0.149 example.org
|
||||
+192.0.0.150 example.org
|
||||
+192.0.0.151 example.org
|
||||
+192.0.0.152 example.org
|
||||
+192.0.0.153 example.org
|
||||
+192.0.0.154 example.org
|
||||
+192.0.0.155 example.org
|
||||
+192.0.0.156 example.org
|
||||
+192.0.0.157 example.org
|
||||
+192.0.0.158 example.org
|
||||
+192.0.0.159 example.org
|
||||
+192.0.0.160 example.org
|
||||
+192.0.0.161 example.org
|
||||
+192.0.0.162 example.org
|
||||
+192.0.0.163 example.org
|
||||
+192.0.0.164 example.org
|
||||
+192.0.0.165 example.org
|
||||
+192.0.0.166 example.org
|
||||
+192.0.0.167 example.org
|
||||
+192.0.0.168 example.org
|
||||
+192.0.0.169 example.org
|
||||
+192.0.0.170 example.org
|
||||
+192.0.0.171 example.org
|
||||
+192.0.0.172 example.org
|
||||
+192.0.0.173 example.org
|
||||
+192.0.0.174 example.org
|
||||
+192.0.0.175 example.org
|
||||
+192.0.0.176 example.org
|
||||
+192.0.0.177 example.org
|
||||
+192.0.0.178 example.org
|
||||
+192.0.0.179 example.org
|
||||
+192.0.0.180 example.org
|
||||
+192.0.0.181 example.org
|
||||
+192.0.0.182 example.org
|
||||
+192.0.0.183 example.org
|
||||
+192.0.0.184 example.org
|
||||
+192.0.0.185 example.org
|
||||
+192.0.0.186 example.org
|
||||
+192.0.0.187 example.org
|
||||
+192.0.0.188 example.org
|
||||
+192.0.0.189 example.org
|
||||
+192.0.0.190 example.org
|
||||
+192.0.0.191 example.org
|
||||
+192.0.0.192 example.org
|
||||
+192.0.0.193 example.org
|
||||
+192.0.0.194 example.org
|
||||
+192.0.0.195 example.org
|
||||
+192.0.0.196 example.org
|
||||
+192.0.0.197 example.org
|
||||
+192.0.0.198 example.org
|
||||
+192.0.0.199 example.org
|
||||
+192.0.0.200 example.org
|
||||
+192.0.0.201 example.org
|
||||
+192.0.0.202 example.org
|
||||
+192.0.0.203 example.org
|
||||
+192.0.0.204 example.org
|
||||
+192.0.0.205 example.org
|
||||
+192.0.0.206 example.org
|
||||
+192.0.0.207 example.org
|
||||
+192.0.0.208 example.org
|
||||
+192.0.0.209 example.org
|
||||
+192.0.0.210 example.org
|
||||
+192.0.0.211 example.org
|
||||
+192.0.0.212 example.org
|
||||
+192.0.0.213 example.org
|
||||
+192.0.0.214 example.org
|
||||
+192.0.0.215 example.org
|
||||
+192.0.0.216 example.org
|
||||
+192.0.0.217 example.org
|
||||
+192.0.0.218 example.org
|
||||
+192.0.0.219 example.org
|
||||
+192.0.0.220 example.org
|
||||
+192.0.0.221 example.org
|
||||
+192.0.0.222 example.org
|
||||
+192.0.0.223 example.org
|
||||
+192.0.0.224 example.org
|
||||
+192.0.0.225 example.org
|
||||
+192.0.0.226 example.org
|
||||
+192.0.0.227 example.org
|
||||
+192.0.0.228 example.org
|
||||
+192.0.0.229 example.org
|
||||
+192.0.0.230 example.org
|
||||
+192.0.0.231 example.org
|
||||
+192.0.0.232 example.org
|
||||
+192.0.0.233 example.org
|
||||
+192.0.0.234 example.org
|
||||
+192.0.0.235 example.org
|
||||
+192.0.0.236 example.org
|
||||
+192.0.0.237 example.org
|
||||
+192.0.0.238 example.org
|
||||
+192.0.0.239 example.org
|
||||
+192.0.0.240 example.org
|
||||
+192.0.0.241 example.org
|
||||
+192.0.0.242 example.org
|
||||
+192.0.0.243 example.org
|
||||
+192.0.0.244 example.org
|
||||
+192.0.0.245 example.org
|
||||
+192.0.0.246 example.org
|
||||
+192.0.0.247 example.org
|
||||
+192.0.0.248 example.org
|
||||
+192.0.0.249 example.org
|
||||
+192.0.0.250 example.org
|
||||
+192.0.0.251 example.org
|
||||
+192.0.0.252 example.org
|
||||
+192.0.0.253 example.org
|
||||
+192.0.0.254 example.org
|
||||
+192.0.1.1 example.org
|
||||
+192.0.1.2 example.org
|
||||
+192.0.1.3 example.org
|
||||
+192.0.1.4 example.org
|
||||
+192.0.1.5 example.org
|
||||
+192.0.1.6 example.org
|
||||
+192.0.1.7 example.org
|
||||
+192.0.1.8 example.org
|
||||
+192.0.1.9 example.org
|
||||
+192.0.1.10 example.org
|
||||
+192.0.1.11 example.org
|
||||
+192.0.1.12 example.org
|
||||
+192.0.1.13 example.org
|
||||
+192.0.1.14 example.org
|
||||
+192.0.1.15 example.org
|
||||
+192.0.1.16 example.org
|
||||
+192.0.1.17 example.org
|
||||
+192.0.1.18 example.org
|
||||
+192.0.1.19 example.org
|
||||
+192.0.1.20 example.org
|
||||
+192.0.1.21 example.org
|
||||
+192.0.1.22 example.org
|
||||
+192.0.1.23 example.org
|
||||
+192.0.1.24 example.org
|
||||
+192.0.1.25 example.org
|
||||
+192.0.1.26 example.org
|
||||
+192.0.1.27 example.org
|
||||
+192.0.1.28 example.org
|
||||
+192.0.1.29 example.org
|
||||
+192.0.1.30 example.org
|
||||
+192.0.1.31 example.org
|
||||
+192.0.1.32 example.org
|
||||
+192.0.1.33 example.org
|
||||
+192.0.1.34 example.org
|
||||
+192.0.1.35 example.org
|
||||
+192.0.1.36 example.org
|
||||
+192.0.1.37 example.org
|
||||
+192.0.1.38 example.org
|
||||
+192.0.1.39 example.org
|
||||
+192.0.1.40 example.org
|
||||
+192.0.1.41 example.org
|
||||
+192.0.1.42 example.org
|
||||
+192.0.1.43 example.org
|
||||
+192.0.1.44 example.org
|
||||
+192.0.1.45 example.org
|
||||
+192.0.1.46 example.org
|
||||
+192.0.1.47 example.org
|
||||
+192.0.1.48 example.org
|
||||
+192.0.1.49 example.org
|
||||
+192.0.1.50 example.org
|
||||
+192.0.1.51 example.org
|
||||
+192.0.1.52 example.org
|
||||
+192.0.1.53 example.org
|
||||
+192.0.1.54 example.org
|
||||
+192.0.1.55 example.org
|
||||
+192.0.1.56 example.org
|
||||
+192.0.1.57 example.org
|
||||
+192.0.1.58 example.org
|
||||
+192.0.1.59 example.org
|
||||
+192.0.1.60 example.org
|
||||
+192.0.1.61 example.org
|
||||
+192.0.1.62 example.org
|
||||
+192.0.1.63 example.org
|
||||
+192.0.1.64 example.org
|
||||
+192.0.1.65 example.org
|
||||
+192.0.1.66 example.org
|
||||
+192.0.1.67 example.org
|
||||
+192.0.1.68 example.org
|
||||
+192.0.1.69 example.org
|
||||
+192.0.1.70 example.org
|
||||
+192.0.1.71 example.org
|
||||
+192.0.1.72 example.org
|
||||
+192.0.1.73 example.org
|
||||
+192.0.1.74 example.org
|
||||
+192.0.1.75 example.org
|
||||
+192.0.1.76 example.org
|
||||
+192.0.1.77 example.org
|
||||
+192.0.1.78 example.org
|
||||
+192.0.1.79 example.org
|
||||
+192.0.1.80 example.org
|
||||
+192.0.1.81 example.org
|
||||
+192.0.1.82 example.org
|
||||
+192.0.1.83 example.org
|
||||
+192.0.1.84 example.org
|
||||
+192.0.1.85 example.org
|
||||
+192.0.1.86 example.org
|
||||
+192.0.1.87 example.org
|
||||
+192.0.1.88 example.org
|
||||
+192.0.1.89 example.org
|
||||
+192.0.1.90 example.org
|
||||
+192.0.1.91 example.org
|
||||
+192.0.1.92 example.org
|
||||
+192.0.1.93 example.org
|
||||
+192.0.1.94 example.org
|
||||
+192.0.1.95 example.org
|
||||
+192.0.1.96 example.org
|
||||
+192.0.1.97 example.org
|
||||
+192.0.1.98 example.org
|
||||
+192.0.1.99 example.org
|
||||
+192.0.1.100 example.org
|
||||
+192.0.1.101 example.org
|
||||
+192.0.1.102 example.org
|
||||
+192.0.1.103 example.org
|
||||
+192.0.1.104 example.org
|
||||
+192.0.1.105 example.org
|
||||
+192.0.1.106 example.org
|
||||
+192.0.1.107 example.org
|
||||
+192.0.1.108 example.org
|
||||
+192.0.1.109 example.org
|
||||
+192.0.1.110 example.org
|
||||
+192.0.1.111 example.org
|
||||
+192.0.1.112 example.org
|
||||
+192.0.1.113 example.org
|
||||
+192.0.1.114 example.org
|
||||
+192.0.1.115 example.org
|
||||
+192.0.1.116 example.org
|
||||
+192.0.1.117 example.org
|
||||
+192.0.1.118 example.org
|
||||
+192.0.1.119 example.org
|
||||
+192.0.1.120 example.org
|
||||
+192.0.1.121 example.org
|
||||
+192.0.1.122 example.org
|
||||
+192.0.1.123 example.org
|
||||
+192.0.1.124 example.org
|
||||
+192.0.1.125 example.org
|
||||
+192.0.1.126 example.org
|
||||
+192.0.1.127 example.org
|
||||
+192.0.1.128 example.org
|
||||
+192.0.1.129 example.org
|
||||
+192.0.1.130 example.org
|
||||
+192.0.1.131 example.org
|
||||
+192.0.1.132 example.org
|
||||
+192.0.1.133 example.org
|
||||
+192.0.1.134 example.org
|
||||
+192.0.1.135 example.org
|
||||
+192.0.1.136 example.org
|
||||
+192.0.1.137 example.org
|
||||
+192.0.1.138 example.org
|
||||
+192.0.1.139 example.org
|
||||
+192.0.1.140 example.org
|
||||
+192.0.1.141 example.org
|
||||
+192.0.1.142 example.org
|
||||
+192.0.1.143 example.org
|
||||
+192.0.1.144 example.org
|
||||
+192.0.1.145 example.org
|
||||
+192.0.1.146 example.org
|
||||
+192.0.1.147 example.org
|
||||
+192.0.1.148 example.org
|
||||
+192.0.1.149 example.org
|
||||
+192.0.1.150 example.org
|
||||
+192.0.1.151 example.org
|
||||
+192.0.1.152 example.org
|
||||
+192.0.1.153 example.org
|
||||
+192.0.1.154 example.org
|
||||
+192.0.1.155 example.org
|
||||
+192.0.1.156 example.org
|
||||
+192.0.1.157 example.org
|
||||
+192.0.1.158 example.org
|
||||
+192.0.1.159 example.org
|
||||
+192.0.1.160 example.org
|
||||
+192.0.1.161 example.org
|
||||
+192.0.1.162 example.org
|
||||
+192.0.1.163 example.org
|
||||
+192.0.1.164 example.org
|
||||
+192.0.1.165 example.org
|
||||
+192.0.1.166 example.org
|
||||
+192.0.1.167 example.org
|
||||
+192.0.1.168 example.org
|
||||
+192.0.1.169 example.org
|
||||
+192.0.1.170 example.org
|
||||
+192.0.1.171 example.org
|
||||
+192.0.1.172 example.org
|
||||
+192.0.1.173 example.org
|
||||
+192.0.1.174 example.org
|
||||
+192.0.1.175 example.org
|
||||
+192.0.1.176 example.org
|
||||
+192.0.1.177 example.org
|
||||
+192.0.1.178 example.org
|
||||
+192.0.1.179 example.org
|
||||
+192.0.1.180 example.org
|
||||
+192.0.1.181 example.org
|
||||
+192.0.1.182 example.org
|
||||
+192.0.1.183 example.org
|
||||
+192.0.1.184 example.org
|
||||
+192.0.1.185 example.org
|
||||
+192.0.1.186 example.org
|
||||
+192.0.1.187 example.org
|
||||
+192.0.1.188 example.org
|
||||
+192.0.1.189 example.org
|
||||
+192.0.1.190 example.org
|
||||
+192.0.1.191 example.org
|
||||
+192.0.1.192 example.org
|
||||
+192.0.1.193 example.org
|
||||
+192.0.1.194 example.org
|
||||
+192.0.1.195 example.org
|
||||
+192.0.1.196 example.org
|
||||
+192.0.1.197 example.org
|
||||
+192.0.1.198 example.org
|
||||
+192.0.1.199 example.org
|
||||
+192.0.1.200 example.org
|
||||
+192.0.1.201 example.org
|
||||
+192.0.1.202 example.org
|
||||
+192.0.1.203 example.org
|
||||
+192.0.1.204 example.org
|
||||
+192.0.1.205 example.org
|
||||
+192.0.1.206 example.org
|
||||
+192.0.1.207 example.org
|
||||
+192.0.1.208 example.org
|
||||
+192.0.1.209 example.org
|
||||
+192.0.1.210 example.org
|
||||
+192.0.1.211 example.org
|
||||
+192.0.1.212 example.org
|
||||
+192.0.1.213 example.org
|
||||
+192.0.1.214 example.org
|
||||
+192.0.1.215 example.org
|
||||
+192.0.1.216 example.org
|
||||
+192.0.1.217 example.org
|
||||
+192.0.1.218 example.org
|
||||
+192.0.1.219 example.org
|
||||
+192.0.1.220 example.org
|
||||
+192.0.1.221 example.org
|
||||
+192.0.1.222 example.org
|
||||
+192.0.1.223 example.org
|
||||
+192.0.1.224 example.org
|
||||
+192.0.1.225 example.org
|
||||
+192.0.1.226 example.org
|
||||
+192.0.1.227 example.org
|
||||
+192.0.1.228 example.org
|
||||
+192.0.1.229 example.org
|
||||
+192.0.1.230 example.org
|
||||
+192.0.1.231 example.org
|
||||
+192.0.1.232 example.org
|
||||
+192.0.1.233 example.org
|
||||
+192.0.1.234 example.org
|
||||
+192.0.1.235 example.org
|
||||
+192.0.1.236 example.org
|
||||
+192.0.1.237 example.org
|
||||
+192.0.1.238 example.org
|
||||
+192.0.1.239 example.org
|
||||
+192.0.1.240 example.org
|
||||
+192.0.1.241 example.org
|
||||
+192.0.1.242 example.org
|
||||
+192.0.1.243 example.org
|
||||
+192.0.1.244 example.org
|
||||
+192.0.1.245 example.org
|
||||
+192.0.1.246 example.org
|
||||
+192.0.1.247 example.org
|
||||
+192.0.1.248 example.org
|
||||
+192.0.1.249 example.org
|
||||
+192.0.1.250 example.org
|
||||
+192.0.1.251 example.org
|
||||
+192.0.1.252 example.org
|
||||
+192.0.1.253 example.org
|
||||
+192.0.1.254 example.org
|
||||
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||
index fae3dea81f19dba6..4fa963644af8b7d5 100644
|
||||
--- a/sysdeps/posix/getaddrinfo.c
|
||||
+++ b/sysdeps/posix/getaddrinfo.c
|
||||
@@ -474,11 +474,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
|
||||
if (name != NULL)
|
||||
{
|
||||
- at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||||
- at->family = AF_UNSPEC;
|
||||
- at->scopeid = 0;
|
||||
- at->next = NULL;
|
||||
-
|
||||
if (req->ai_flags & AI_IDN)
|
||||
{
|
||||
char *out;
|
||||
@@ -489,13 +484,21 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
malloc_name = true;
|
||||
}
|
||||
|
||||
- if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
|
||||
+ uint32_t addr[4];
|
||||
+ if (__inet_aton_exact (name, (struct in_addr *) addr) != 0)
|
||||
{
|
||||
+ at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||||
+ at->scopeid = 0;
|
||||
+ at->next = NULL;
|
||||
+
|
||||
if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
|
||||
- at->family = AF_INET;
|
||||
+ {
|
||||
+ memcpy (at->addr, addr, sizeof (at->addr));
|
||||
+ at->family = AF_INET;
|
||||
+ }
|
||||
else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
|
||||
{
|
||||
- at->addr[3] = at->addr[0];
|
||||
+ at->addr[3] = addr[0];
|
||||
at->addr[2] = htonl (0xffff);
|
||||
at->addr[1] = 0;
|
||||
at->addr[0] = 0;
|
||||
@@ -509,49 +512,62 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
|
||||
if (req->ai_flags & AI_CANONNAME)
|
||||
canon = name;
|
||||
+
|
||||
+ goto process_list;
|
||||
}
|
||||
- else if (at->family == AF_UNSPEC)
|
||||
+
|
||||
+ char *scope_delim = strchr (name, SCOPE_DELIMITER);
|
||||
+ int e;
|
||||
+
|
||||
+ if (scope_delim == NULL)
|
||||
+ e = inet_pton (AF_INET6, name, addr);
|
||||
+ else
|
||||
+ e = __inet_pton_length (AF_INET6, name, scope_delim - name, addr);
|
||||
+
|
||||
+ if (e > 0)
|
||||
{
|
||||
- char *scope_delim = strchr (name, SCOPE_DELIMITER);
|
||||
- int e;
|
||||
- if (scope_delim == NULL)
|
||||
- e = inet_pton (AF_INET6, name, at->addr);
|
||||
+ at = alloca_account (sizeof (struct gaih_addrtuple),
|
||||
+ alloca_used);
|
||||
+ at->scopeid = 0;
|
||||
+ at->next = NULL;
|
||||
+
|
||||
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||||
+ {
|
||||
+ memcpy (at->addr, addr, sizeof (at->addr));
|
||||
+ at->family = AF_INET6;
|
||||
+ }
|
||||
+ else if (req->ai_family == AF_INET
|
||||
+ && IN6_IS_ADDR_V4MAPPED (addr))
|
||||
+ {
|
||||
+ at->addr[0] = addr[3];
|
||||
+ at->addr[1] = addr[1];
|
||||
+ at->addr[2] = addr[2];
|
||||
+ at->addr[3] = addr[3];
|
||||
+ at->family = AF_INET;
|
||||
+ }
|
||||
else
|
||||
- e = __inet_pton_length (AF_INET6, name, scope_delim - name,
|
||||
- at->addr);
|
||||
- if (e > 0)
|
||||
{
|
||||
- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||||
- at->family = AF_INET6;
|
||||
- else if (req->ai_family == AF_INET
|
||||
- && IN6_IS_ADDR_V4MAPPED (at->addr))
|
||||
- {
|
||||
- at->addr[0] = at->addr[3];
|
||||
- at->family = AF_INET;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- result = -EAI_ADDRFAMILY;
|
||||
- goto free_and_return;
|
||||
- }
|
||||
-
|
||||
- if (scope_delim != NULL
|
||||
- && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
|
||||
- scope_delim + 1,
|
||||
- &at->scopeid) != 0)
|
||||
- {
|
||||
- result = -EAI_NONAME;
|
||||
- goto free_and_return;
|
||||
- }
|
||||
+ result = -EAI_ADDRFAMILY;
|
||||
+ goto free_and_return;
|
||||
+ }
|
||||
|
||||
- if (req->ai_flags & AI_CANONNAME)
|
||||
- canon = name;
|
||||
+ if (scope_delim != NULL
|
||||
+ && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
|
||||
+ scope_delim + 1,
|
||||
+ &at->scopeid) != 0)
|
||||
+ {
|
||||
+ result = -EAI_NONAME;
|
||||
+ goto free_and_return;
|
||||
}
|
||||
+
|
||||
+ if (req->ai_flags & AI_CANONNAME)
|
||||
+ canon = name;
|
||||
+
|
||||
+ goto process_list;
|
||||
}
|
||||
|
||||
- if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
|
||||
+ if ((req->ai_flags & AI_NUMERICHOST) == 0)
|
||||
{
|
||||
- struct gaih_addrtuple **pat = &at;
|
||||
int no_data = 0;
|
||||
int no_inet6_data = 0;
|
||||
service_user *nip;
|
||||
@@ -560,6 +576,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
int no_more;
|
||||
struct resolv_context *res_ctx = NULL;
|
||||
bool res_enable_inet6 = false;
|
||||
+ bool do_merge = false;
|
||||
|
||||
/* If we do not have to look for IPv6 addresses or the canonical
|
||||
name, use the simple, old functions, which do not support
|
||||
@@ -596,7 +613,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
result = -EAI_MEMORY;
|
||||
goto free_and_return;
|
||||
}
|
||||
- *pat = addrmem;
|
||||
+ at = addrmem;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -649,6 +666,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
}
|
||||
|
||||
struct gaih_addrtuple *addrfree = addrmem;
|
||||
+ struct gaih_addrtuple **pat = &at;
|
||||
+
|
||||
for (int i = 0; i < air->naddrs; ++i)
|
||||
{
|
||||
socklen_t size = (air->family[i] == AF_INET
|
||||
@@ -712,12 +731,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
|
||||
free (air);
|
||||
|
||||
- if (at->family == AF_UNSPEC)
|
||||
- {
|
||||
- result = -EAI_NONAME;
|
||||
- goto free_and_return;
|
||||
- }
|
||||
-
|
||||
goto process_list;
|
||||
}
|
||||
else if (err == 0)
|
||||
@@ -756,6 +769,22 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
|
||||
while (!no_more)
|
||||
{
|
||||
+ /* Always start afresh; continue should discard previous results
|
||||
+ and the hosts database does not support merge. */
|
||||
+ at = NULL;
|
||||
+ free (canonbuf);
|
||||
+ free (addrmem);
|
||||
+ canon = canonbuf = NULL;
|
||||
+ addrmem = NULL;
|
||||
+ got_ipv6 = false;
|
||||
+
|
||||
+ if (do_merge)
|
||||
+ {
|
||||
+ __set_h_errno (NETDB_INTERNAL);
|
||||
+ __set_errno (EBUSY);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
no_data = 0;
|
||||
nss_gethostbyname4_r fct4 = NULL;
|
||||
|
||||
@@ -768,12 +797,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
- status = DL_CALL_FCT (fct4, (name, pat,
|
||||
+ status = DL_CALL_FCT (fct4, (name, &at,
|
||||
tmpbuf->data, tmpbuf->length,
|
||||
&errno, &h_errno,
|
||||
NULL));
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
break;
|
||||
+ /* gethostbyname4_r may write into AT, so reset it. */
|
||||
+ at = NULL;
|
||||
if (status != NSS_STATUS_TRYAGAIN
|
||||
|| errno != ERANGE || h_errno != NETDB_INTERNAL)
|
||||
{
|
||||
@@ -800,7 +831,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
no_data = 1;
|
||||
|
||||
if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
|
||||
- canon = (*pat)->name;
|
||||
+ canon = at->name;
|
||||
+
|
||||
+ struct gaih_addrtuple **pat = &at;
|
||||
|
||||
while (*pat != NULL)
|
||||
{
|
||||
@@ -852,6 +885,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
|
||||
if (fct != NULL)
|
||||
{
|
||||
+ struct gaih_addrtuple **pat = &at;
|
||||
+
|
||||
if (req->ai_family == AF_INET6
|
||||
|| req->ai_family == AF_UNSPEC)
|
||||
{
|
||||
@@ -927,6 +962,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
|
||||
break;
|
||||
|
||||
+ /* The hosts database does not support MERGE. */
|
||||
+ if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
|
||||
+ do_merge = true;
|
||||
+
|
||||
if (nip->next == NULL)
|
||||
no_more = -1;
|
||||
else
|
||||
@@ -960,7 +999,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
}
|
||||
|
||||
process_list:
|
||||
- if (at->family == AF_UNSPEC)
|
||||
+ if (at == NULL)
|
||||
{
|
||||
result = -EAI_NONAME;
|
||||
goto free_and_return;
|
|
@ -1,171 +0,0 @@
|
|||
From 2e86602d21fcaa8353c529f2f6768125396da39f Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 19 Jul 2023 23:12:30 +0800
|
||||
Subject: [PATCH 5/6] Support target specific ALIGN for variable alignment test
|
||||
[BZ #28676]
|
||||
|
||||
Add <tst-file-align.h> to support target specific ALIGN for variable
|
||||
alignment test:
|
||||
|
||||
1. Alpha: Use 0x10000.
|
||||
2. MicroBlaze and Nios II: Use 0x8000.
|
||||
3. All others: Use 0x200000.
|
||||
|
||||
Backport from master commit: 4435c29
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Signed-off-by: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||
---
|
||||
elf/tst-align3.c | 4 +---
|
||||
elf/tst-alignmod3.c | 4 +---
|
||||
sysdeps/alpha/tst-file-align.h | 20 ++++++++++++++++++++
|
||||
sysdeps/generic/tst-file-align.h | 20 ++++++++++++++++++++
|
||||
sysdeps/microblaze/tst-file-align.h | 20 ++++++++++++++++++++
|
||||
sysdeps/nios2/tst-file-align.h | 20 ++++++++++++++++++++
|
||||
6 files changed, 82 insertions(+), 6 deletions(-)
|
||||
create mode 100644 sysdeps/alpha/tst-file-align.h
|
||||
create mode 100644 sysdeps/generic/tst-file-align.h
|
||||
create mode 100644 sysdeps/microblaze/tst-file-align.h
|
||||
create mode 100644 sysdeps/nios2/tst-file-align.h
|
||||
|
||||
diff --git a/elf/tst-align3.c b/elf/tst-align3.c
|
||||
index ac86d623..87a8ff81 100644
|
||||
--- a/elf/tst-align3.c
|
||||
+++ b/elf/tst-align3.c
|
||||
@@ -17,11 +17,9 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <support/check.h>
|
||||
+#include <tst-file-align.h>
|
||||
#include <tst-stack-align.h>
|
||||
|
||||
-/* This should cover all possible page sizes we currently support. */
|
||||
-#define ALIGN 0x200000
|
||||
-
|
||||
int bar __attribute__ ((aligned (ALIGN))) = 1;
|
||||
|
||||
extern int do_load_test (void);
|
||||
diff --git a/elf/tst-alignmod3.c b/elf/tst-alignmod3.c
|
||||
index 0d33f237..9520c352 100644
|
||||
--- a/elf/tst-alignmod3.c
|
||||
+++ b/elf/tst-alignmod3.c
|
||||
@@ -17,11 +17,9 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <support/check.h>
|
||||
+#include <tst-file-align.h>
|
||||
#include <tst-stack-align.h>
|
||||
|
||||
-/* This should cover all possible page sizes we currently support. */
|
||||
-#define ALIGN 0x200000
|
||||
-
|
||||
int foo __attribute__ ((aligned (ALIGN))) = 1;
|
||||
|
||||
void
|
||||
diff --git a/sysdeps/alpha/tst-file-align.h b/sysdeps/alpha/tst-file-align.h
|
||||
new file mode 100644
|
||||
index 00000000..8fc3c940
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/alpha/tst-file-align.h
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Check file alignment. Alpha version.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This should cover all possible alignments we currently support. */
|
||||
+#define ALIGN 0x10000
|
||||
diff --git a/sysdeps/generic/tst-file-align.h b/sysdeps/generic/tst-file-align.h
|
||||
new file mode 100644
|
||||
index 00000000..6ee6783a
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/generic/tst-file-align.h
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Check file alignment. Generic version.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This should cover all possible page sizes we currently support. */
|
||||
+#define ALIGN 0x200000
|
||||
diff --git a/sysdeps/microblaze/tst-file-align.h b/sysdeps/microblaze/tst-file-align.h
|
||||
new file mode 100644
|
||||
index 00000000..43c58b29
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/microblaze/tst-file-align.h
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Check file alignment. MicroBlaze version.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This should cover all possible alignments we currently support. */
|
||||
+#define ALIGN 0x8000
|
||||
diff --git a/sysdeps/nios2/tst-file-align.h b/sysdeps/nios2/tst-file-align.h
|
||||
new file mode 100644
|
||||
index 00000000..589a2d5a
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/nios2/tst-file-align.h
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Check file alignment. Nios II version.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This should cover all possible alignments we currently support. */
|
||||
+#define ALIGN 0x8000
|
||||
--
|
||||
2.27.0
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,183 +0,0 @@
|
|||
From b9f145df85145506f8e61bac38b792584a38d88f Mon Sep 17 00:00:00 2001
|
||||
From: Krzysztof Koch <Krzysztof.Koch@arm.com>
|
||||
Date: Tue, 5 Nov 2019 17:35:18 +0000
|
||||
Subject: [PATCH 02/14] aarch64: Increase small and medium cases for
|
||||
__memcpy_generic
|
||||
|
||||
Increase the upper bound on medium cases from 96 to 128 bytes.
|
||||
Now, up to 128 bytes are copied unrolled.
|
||||
|
||||
Increase the upper bound on small cases from 16 to 32 bytes so that
|
||||
copies of 17-32 bytes are not impacted by the larger medium case.
|
||||
|
||||
Benchmarking:
|
||||
The attached figures show relative timing difference with respect
|
||||
to 'memcpy_generic', which is the existing implementation.
|
||||
'memcpy_med_128' denotes the the version of memcpy_generic with
|
||||
only the medium case enlarged. The 'memcpy_med_128_small_32' numbers
|
||||
are for the version of memcpy_generic submitted in this patch, which
|
||||
has both medium and small cases enlarged. The figures were generated
|
||||
using the script from:
|
||||
https://www.sourceware.org/ml/libc-alpha/2019-10/msg00563.html
|
||||
|
||||
Depending on the platform, the performance improvement in the
|
||||
bench-memcpy-random.c benchmark ranges from 6% to 20% between
|
||||
the original and final version of memcpy.S
|
||||
|
||||
Tested against GLIBC testsuite and randomized tests.
|
||||
---
|
||||
sysdeps/aarch64/memcpy.S | 82 +++++++++++++++++++++++-----------------
|
||||
1 file changed, 47 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/sysdeps/aarch64/memcpy.S b/sysdeps/aarch64/memcpy.S
|
||||
index 6e4f4a74bd..10801aa0f4 100644
|
||||
--- a/sysdeps/aarch64/memcpy.S
|
||||
+++ b/sysdeps/aarch64/memcpy.S
|
||||
@@ -41,17 +41,19 @@
|
||||
#define C_h x11
|
||||
#define D_l x12
|
||||
#define D_h x13
|
||||
-#define E_l src
|
||||
-#define E_h count
|
||||
-#define F_l srcend
|
||||
-#define F_h dst
|
||||
+#define E_l x14
|
||||
+#define E_h x15
|
||||
+#define F_l x16
|
||||
+#define F_h x17
|
||||
#define G_l count
|
||||
#define G_h dst
|
||||
+#define H_l src
|
||||
+#define H_h srcend
|
||||
#define tmp1 x14
|
||||
|
||||
-/* Copies are split into 3 main cases: small copies of up to 16 bytes,
|
||||
- medium copies of 17..96 bytes which are fully unrolled. Large copies
|
||||
- of more than 96 bytes align the destination and use an unrolled loop
|
||||
+/* Copies are split into 3 main cases: small copies of up to 32 bytes,
|
||||
+ medium copies of 33..128 bytes which are fully unrolled. Large copies
|
||||
+ of more than 128 bytes align the destination and use an unrolled loop
|
||||
processing 64 bytes per iteration.
|
||||
In order to share code with memmove, small and medium copies read all
|
||||
data before writing, allowing any kind of overlap. So small, medium
|
||||
@@ -73,7 +75,7 @@ ENTRY_ALIGN (MEMMOVE, 6)
|
||||
DELOUSE (2)
|
||||
|
||||
sub tmp1, dstin, src
|
||||
- cmp count, 96
|
||||
+ cmp count, 128
|
||||
ccmp tmp1, count, 2, hi
|
||||
b.lo L(move_long)
|
||||
|
||||
@@ -89,31 +91,39 @@ ENTRY (MEMCPY)
|
||||
prfm PLDL1KEEP, [src]
|
||||
add srcend, src, count
|
||||
add dstend, dstin, count
|
||||
- cmp count, 16
|
||||
- b.ls L(copy16)
|
||||
- cmp count, 96
|
||||
+ cmp count, 32
|
||||
+ b.ls L(copy32)
|
||||
+ cmp count, 128
|
||||
b.hi L(copy_long)
|
||||
|
||||
- /* Medium copies: 17..96 bytes. */
|
||||
- sub tmp1, count, 1
|
||||
+ /* Medium copies: 33..128 bytes. */
|
||||
ldp A_l, A_h, [src]
|
||||
- tbnz tmp1, 6, L(copy96)
|
||||
- ldp D_l, D_h, [srcend, -16]
|
||||
- tbz tmp1, 5, 1f
|
||||
ldp B_l, B_h, [src, 16]
|
||||
ldp C_l, C_h, [srcend, -32]
|
||||
+ ldp D_l, D_h, [srcend, -16]
|
||||
+ cmp count, 64
|
||||
+ b.hi L(copy128)
|
||||
+ stp A_l, A_h, [dstin]
|
||||
stp B_l, B_h, [dstin, 16]
|
||||
stp C_l, C_h, [dstend, -32]
|
||||
-1:
|
||||
- stp A_l, A_h, [dstin]
|
||||
stp D_l, D_h, [dstend, -16]
|
||||
ret
|
||||
|
||||
.p2align 4
|
||||
- /* Small copies: 0..16 bytes. */
|
||||
-L(copy16):
|
||||
- cmp count, 8
|
||||
+ /* Small copies: 0..32 bytes. */
|
||||
+L(copy32):
|
||||
+ /* 16-32 bytes. */
|
||||
+ cmp count, 16
|
||||
b.lo 1f
|
||||
+ ldp A_l, A_h, [src]
|
||||
+ ldp B_l, B_h, [srcend, -16]
|
||||
+ stp A_l, A_h, [dstin]
|
||||
+ stp B_l, B_h, [dstend, -16]
|
||||
+ ret
|
||||
+ .p2align 4
|
||||
+1:
|
||||
+ /* 8-15 bytes. */
|
||||
+ tbz count, 3, 1f
|
||||
ldr A_l, [src]
|
||||
ldr A_h, [srcend, -8]
|
||||
str A_l, [dstin]
|
||||
@@ -121,6 +131,7 @@ L(copy16):
|
||||
ret
|
||||
.p2align 4
|
||||
1:
|
||||
+ /* 4-7 bytes. */
|
||||
tbz count, 2, 1f
|
||||
ldr A_lw, [src]
|
||||
ldr A_hw, [srcend, -4]
|
||||
@@ -142,24 +153,25 @@ L(copy16):
|
||||
2: ret
|
||||
|
||||
.p2align 4
|
||||
- /* Copy 64..96 bytes. Copy 64 bytes from the start and
|
||||
- 32 bytes from the end. */
|
||||
-L(copy96):
|
||||
- ldp B_l, B_h, [src, 16]
|
||||
- ldp C_l, C_h, [src, 32]
|
||||
- ldp D_l, D_h, [src, 48]
|
||||
- ldp E_l, E_h, [srcend, -32]
|
||||
- ldp F_l, F_h, [srcend, -16]
|
||||
+ /* Copy 65..128 bytes. Copy 64 bytes from the start and
|
||||
+ 64 bytes from the end. */
|
||||
+L(copy128):
|
||||
+ ldp E_l, E_h, [src, 32]
|
||||
+ ldp F_l, F_h, [src, 48]
|
||||
+ ldp G_l, G_h, [srcend, -64]
|
||||
+ ldp H_l, H_h, [srcend, -48]
|
||||
stp A_l, A_h, [dstin]
|
||||
stp B_l, B_h, [dstin, 16]
|
||||
- stp C_l, C_h, [dstin, 32]
|
||||
- stp D_l, D_h, [dstin, 48]
|
||||
- stp E_l, E_h, [dstend, -32]
|
||||
- stp F_l, F_h, [dstend, -16]
|
||||
+ stp E_l, E_h, [dstin, 32]
|
||||
+ stp F_l, F_h, [dstin, 48]
|
||||
+ stp G_l, G_h, [dstend, -64]
|
||||
+ stp H_l, H_h, [dstend, -48]
|
||||
+ stp C_l, C_h, [dstend, -32]
|
||||
+ stp D_l, D_h, [dstend, -16]
|
||||
ret
|
||||
|
||||
/* Align DST to 16 byte alignment so that we don't cross cache line
|
||||
- boundaries on both loads and stores. There are at least 96 bytes
|
||||
+ 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 64 bytes per iteration and prefetches one iteration ahead. */
|
||||
|
||||
@@ -215,7 +227,7 @@ L(move_long):
|
||||
add dstend, dstin, count
|
||||
|
||||
/* Align dstend to 16 byte alignment so that we don't cross cache line
|
||||
- boundaries on both loads and stores. There are at least 96 bytes
|
||||
+ 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 64 bytes per iteration and prefetches one iteration ahead. */
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Jul 4 16:16:57 2018 +0200
|
||||
|
||||
Makeconfig (ASFLAGS): Always append required assembler flags.
|
||||
|
||||
Submitted upstream here:
|
||||
|
||||
https://sourceware.org/ml/libc-alpha/2018-07/msg00077.html
|
||||
|
||||
Otherwise, we lose essential flags such as -Wa,--noexecstack due to
|
||||
the way += works in make due to the ASFLAGS command line override.
|
||||
|
||||
diff --git a/Makeconfig b/Makeconfig
|
||||
index b0b27f0113ac18b8..92e76d6200bbcd5b 100644
|
||||
--- a/Makeconfig
|
||||
+++ b/Makeconfig
|
||||
@@ -1047,7 +1047,7 @@ endif
|
||||
ifndef ASFLAGS
|
||||
ASFLAGS := $(filter -g% -fdebug-prefix-map=%,$(CFLAGS))
|
||||
endif
|
||||
-ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu)
|
||||
+override ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu)
|
||||
|
||||
ifndef BUILD_CC
|
||||
BUILD_CC = $(CC)
|
|
@ -1,286 +0,0 @@
|
|||
Short description: Add C.UTF-8 support.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-submitted
|
||||
|
||||
This patch needs to upstream as part of Carlos O'Donell
|
||||
<carlos@redhat.com>'s work on enabling upstream C.UTF-8 support. This
|
||||
work is currently blocked on cleaning up the test results to prove that
|
||||
full code-point sorting is working as intended.
|
||||
|
||||
Note that this patch does not provide full code-point sorting as
|
||||
expected.
|
||||
|
||||
This patch needs to upstream as soon as possible since it would be nice
|
||||
to have this in F29 and fixed.
|
||||
|
||||
From 2eda7b462b415105f5a05c1323372d4e39d46439 Mon Sep 17 00:00:00 2001
|
||||
From: Mike FABIAN <mfabian@redhat.com>
|
||||
Date: Mon, 10 Aug 2015 15:58:12 +0200
|
||||
Subject: [PATCH] Add a C.UTF-8 locale
|
||||
|
||||
---
|
||||
localedata/SUPPORTED | 1 +
|
||||
localedata/locales/C | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 239 insertions(+)
|
||||
create mode 100644 localedata/locales/C
|
||||
|
||||
diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED
|
||||
index 8ca023e..2a78391 100644
|
||||
--- a/localedata/SUPPORTED
|
||||
+++ b/localedata/SUPPORTED
|
||||
@@ -1,6 +1,7 @@
|
||||
# This file names the currently supported and somewhat tested locales.
|
||||
# If you have any additions please file a glibc bug report.
|
||||
SUPPORTED-LOCALES=\
|
||||
+C.UTF-8/UTF-8 \
|
||||
aa_DJ.UTF-8/UTF-8 \
|
||||
aa_DJ/ISO-8859-1 \
|
||||
aa_ER/UTF-8 \
|
||||
diff --git a/localedata/locales/C b/localedata/locales/C
|
||||
new file mode 100644
|
||||
index 0000000..fdf460e
|
||||
--- /dev/null
|
||||
+++ b/localedata/locales/C
|
||||
@@ -0,0 +1,238 @@
|
||||
+escape_char /
|
||||
+comment_char %
|
||||
+% Locale for C locale in UTF-8
|
||||
+
|
||||
+LC_IDENTIFICATION
|
||||
+title "C locale"
|
||||
+source ""
|
||||
+address ""
|
||||
+contact ""
|
||||
+email "mfabian@redhat.com"
|
||||
+tel ""
|
||||
+fax ""
|
||||
+language "C"
|
||||
+territory ""
|
||||
+revision "1.0"
|
||||
+date "2015-08-10"
|
||||
+%
|
||||
+category "i18n:2012";LC_IDENTIFICATION
|
||||
+category "i18n:2012";LC_CTYPE
|
||||
+category "i18n:2012";LC_COLLATE
|
||||
+category "i18n:2012";LC_TIME
|
||||
+category "i18n:2012";LC_NUMERIC
|
||||
+category "i18n:2012";LC_MONETARY
|
||||
+category "i18n:2012";LC_MESSAGES
|
||||
+category "i18n:2012";LC_PAPER
|
||||
+category "i18n:2012";LC_NAME
|
||||
+category "i18n:2012";LC_ADDRESS
|
||||
+category "i18n:2012";LC_TELEPHONE
|
||||
+category "i18n:2012";LC_MEASUREMENT
|
||||
+END LC_IDENTIFICATION
|
||||
+
|
||||
+LC_CTYPE
|
||||
+copy "i18n"
|
||||
+
|
||||
+translit_start
|
||||
+include "translit_combining";""
|
||||
+translit_end
|
||||
+
|
||||
+END LC_CTYPE
|
||||
+
|
||||
+LC_COLLATE
|
||||
+order_start forward
|
||||
+<U0000>
|
||||
+..
|
||||
+<UFFFF>
|
||||
+<U10000>
|
||||
+..
|
||||
+<U1FFFF>
|
||||
+<U20000>
|
||||
+..
|
||||
+<U2FFFF>
|
||||
+<UE0000>
|
||||
+..
|
||||
+<UEFFFF>
|
||||
+<UF0000>
|
||||
+..
|
||||
+<UFFFFF>
|
||||
+<U100000>
|
||||
+..
|
||||
+<U10FFFF>
|
||||
+UNDEFINED
|
||||
+order_end
|
||||
+END LC_COLLATE
|
||||
+
|
||||
+LC_MONETARY
|
||||
+% This is the 14652 i18n fdcc-set definition for
|
||||
+% the LC_MONETARY category
|
||||
+% (except for the int_curr_symbol and currency_symbol, they are empty in
|
||||
+% the 14652 i18n fdcc-set definition and also empty in
|
||||
+% glibc/locale/C-monetary.c. But localedef complains in that case).
|
||||
+%
|
||||
+% Using "USD" for int_curr_symbol. But maybe "XXX" would be better?
|
||||
+% XXX is "No currency" (https://en.wikipedia.org/wiki/ISO_4217)
|
||||
+int_curr_symbol "<U0055><U0053><U0044><U0020>"
|
||||
+% Using "$" for currency_symbol. But maybe <U00A4> would be better?
|
||||
+% U+00A4 is the "generic currency symbol"
|
||||
+% (https://en.wikipedia.org/wiki/Currency_sign_%28typography%29)
|
||||
+currency_symbol "<U0024>"
|
||||
+mon_decimal_point "<U002E>"
|
||||
+mon_thousands_sep ""
|
||||
+mon_grouping -1
|
||||
+positive_sign ""
|
||||
+negative_sign "<U002D>"
|
||||
+int_frac_digits -1
|
||||
+frac_digits -1
|
||||
+p_cs_precedes -1
|
||||
+int_p_sep_by_space -1
|
||||
+p_sep_by_space -1
|
||||
+n_cs_precedes -1
|
||||
+int_n_sep_by_space -1
|
||||
+n_sep_by_space -1
|
||||
+p_sign_posn -1
|
||||
+n_sign_posn -1
|
||||
+%
|
||||
+END LC_MONETARY
|
||||
+
|
||||
+LC_NUMERIC
|
||||
+% This is the POSIX Locale definition for
|
||||
+% the LC_NUMERIC category.
|
||||
+%
|
||||
+decimal_point "<U002E>"
|
||||
+thousands_sep ""
|
||||
+grouping -1
|
||||
+END LC_NUMERIC
|
||||
+
|
||||
+LC_TIME
|
||||
+% This is the POSIX Locale definition for
|
||||
+% the LC_TIME category.
|
||||
+%
|
||||
+% Abbreviated weekday names (%a)
|
||||
+abday "<U0053><U0075><U006E>";"<U004D><U006F><U006E>";/
|
||||
+ "<U0054><U0075><U0065>";"<U0057><U0065><U0064>";/
|
||||
+ "<U0054><U0068><U0075>";"<U0046><U0072><U0069>";/
|
||||
+ "<U0053><U0061><U0074>"
|
||||
+
|
||||
+% Full weekday names (%A)
|
||||
+day "<U0053><U0075><U006E><U0064><U0061><U0079>";/
|
||||
+ "<U004D><U006F><U006E><U0064><U0061><U0079>";/
|
||||
+ "<U0054><U0075><U0065><U0073><U0064><U0061><U0079>";/
|
||||
+ "<U0057><U0065><U0064><U006E><U0065><U0073><U0064><U0061><U0079>";/
|
||||
+ "<U0054><U0068><U0075><U0072><U0073><U0064><U0061><U0079>";/
|
||||
+ "<U0046><U0072><U0069><U0064><U0061><U0079>";/
|
||||
+ "<U0053><U0061><U0074><U0075><U0072><U0064><U0061><U0079>"
|
||||
+
|
||||
+% Abbreviated month names (%b)
|
||||
+abmon "<U004A><U0061><U006E>";"<U0046><U0065><U0062>";/
|
||||
+ "<U004D><U0061><U0072>";"<U0041><U0070><U0072>";/
|
||||
+ "<U004D><U0061><U0079>";"<U004A><U0075><U006E>";/
|
||||
+ "<U004A><U0075><U006C>";"<U0041><U0075><U0067>";/
|
||||
+ "<U0053><U0065><U0070>";"<U004F><U0063><U0074>";/
|
||||
+ "<U004E><U006F><U0076>";"<U0044><U0065><U0063>"
|
||||
+
|
||||
+% Full month names (%B)
|
||||
+mon "<U004A><U0061><U006E><U0075><U0061><U0072><U0079>";/
|
||||
+ "<U0046><U0065><U0062><U0072><U0075><U0061><U0072><U0079>";/
|
||||
+ "<U004D><U0061><U0072><U0063><U0068>";/
|
||||
+ "<U0041><U0070><U0072><U0069><U006C>";/
|
||||
+ "<U004D><U0061><U0079>";/
|
||||
+ "<U004A><U0075><U006E><U0065>";/
|
||||
+ "<U004A><U0075><U006C><U0079>";/
|
||||
+ "<U0041><U0075><U0067><U0075><U0073><U0074>";/
|
||||
+ "<U0053><U0065><U0070><U0074><U0065><U006D><U0062><U0065><U0072>";/
|
||||
+ "<U004F><U0063><U0074><U006F><U0062><U0065><U0072>";/
|
||||
+ "<U004E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
|
||||
+ "<U0044><U0065><U0063><U0065><U006D><U0062><U0065><U0072>"
|
||||
+
|
||||
+% Week description, consists of three fields:
|
||||
+% 1. Number of days in a week.
|
||||
+% 2. Gregorian date that is a first weekday (19971130 for Sunday, 19971201 for Monday).
|
||||
+% 3. The weekday number to be contained in the first week of the year.
|
||||
+%
|
||||
+% ISO 8601 conforming applications should use the values 7, 19971201 (a
|
||||
+% Monday), and 4 (Thursday), respectively.
|
||||
+week 7;19971201;4
|
||||
+first_weekday 1
|
||||
+first_workday 1
|
||||
+
|
||||
+% Appropriate date and time representation (%c)
|
||||
+% "%a %b %e %H:%M:%S %Y"
|
||||
+d_t_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0059>"
|
||||
+
|
||||
+% Appropriate date representation (%x)
|
||||
+% "%m/%d/%y"
|
||||
+d_fmt "<U0025><U006D><U002F><U0025><U0064><U002F><U0025><U0079>"
|
||||
+
|
||||
+% Appropriate time representation (%X)
|
||||
+% "%H:%M:%S"
|
||||
+t_fmt "<U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053>"
|
||||
+
|
||||
+% Appropriate AM/PM time representation (%r)
|
||||
+% "%I:%M:%S %p"
|
||||
+t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0070>"
|
||||
+
|
||||
+% Equivalent of AM/PM (%p) "AM"/"PM"
|
||||
+%
|
||||
+am_pm "<U0041><U004D>";"<U0050><U004D>"
|
||||
+
|
||||
+% Appropriate date representation (date(1)) "%a %b %e %H:%M:%S %Z %Y"
|
||||
+date_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U0020><U0025><U0059>"
|
||||
+END LC_TIME
|
||||
+
|
||||
+LC_MESSAGES
|
||||
+% This is the POSIX Locale definition for
|
||||
+% the LC_NUMERIC category.
|
||||
+%
|
||||
+yesexpr "<U005E><U005B><U0079><U0059><U005D>"
|
||||
+noexpr "<U005E><U005B><U006E><U004E><U005D>"
|
||||
+yesstr "<U0059><U0065><U0073>"
|
||||
+nostr "<U004E><U006F>"
|
||||
+END LC_MESSAGES
|
||||
+
|
||||
+LC_PAPER
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_PAPER category.
|
||||
+% (A4 paper, this is also used in the built in C/POSIX
|
||||
+% locale in glibc/locale/C-paper.c)
|
||||
+height 297
|
||||
+width 210
|
||||
+END LC_PAPER
|
||||
+
|
||||
+LC_NAME
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_NAME category.
|
||||
+% "%p%t%g%t%m%t%f"
|
||||
+% (also used in the built in C/POSIX locale in glibc/locale/C-name.c)
|
||||
+name_fmt "<U0025><U0070><U0025><U0074><U0025><U0067><U0025><U0074>/
|
||||
+<U0025><U006D><U0025><U0074><U0025><U0066>"
|
||||
+END LC_NAME
|
||||
+
|
||||
+LC_ADDRESS
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_ADDRESS category.
|
||||
+% "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N"
|
||||
+% (also used in the built in C/POSIX locale in glibc/locale/C-address.c)
|
||||
+postal_fmt "<U0025><U0061><U0025><U004E><U0025><U0066><U0025><U004E>/
|
||||
+<U0025><U0064><U0025><U004E><U0025><U0062><U0025><U004E><U0025><U0073>/
|
||||
+<U0020><U0025><U0068><U0020><U0025><U0065><U0020><U0025><U0072><U0025>/
|
||||
+<U004E><U0025><U0043><U002D><U0025><U007A><U0020><U0025><U0054><U0025>/
|
||||
+<U004E><U0025><U0063><U0025><U004E>"
|
||||
+END LC_ADDRESS
|
||||
+
|
||||
+LC_TELEPHONE
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_TELEPHONE category.
|
||||
+% "+%c %a %l"
|
||||
+tel_int_fmt "<U002B><U0025><U0063><U0020><U0025><U0061><U0020><U0025>/
|
||||
+<U006C>"
|
||||
+% (also used in the built in C/POSIX locale in glibc/locale/C-telephone.c)
|
||||
+END LC_TELEPHONE
|
||||
+
|
||||
+LC_MEASUREMENT
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_MEASUREMENT category.
|
||||
+% (same as in the built in C/POSIX locale in glibc/locale/C-measurement.c)
|
||||
+%metric
|
||||
+measurement 1
|
||||
+END LC_MEASUREMENT
|
||||
+
|
||||
--
|
||||
2.4.3
|
||||
|
|
@ -1,15 +1,44 @@
|
|||
Short description: Adjust CS_PATH return value.
|
||||
Short description: Adjust CS_PATH and the test container layout.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-needed
|
||||
|
||||
In Fedora we should return only /usr/bin because /bin is just a symlink
|
||||
to /usr/bin after MoveToUsr transition (which glibc has not really
|
||||
completed).
|
||||
In Fedora we should return only /usr/bin as CS_PATH because /bin is just
|
||||
a symlink to /usr/bin after MoveToUsr transition (which glibc has not
|
||||
really completed).
|
||||
|
||||
diff -pruN a/sysdeps/unix/confstr.h b/sysdeps/unix/confstr.h
|
||||
--- a/sysdeps/unix/confstr.h 2012-12-25 08:32:13.000000000 +0530
|
||||
+++ b/sysdeps/unix/confstr.h 2014-09-05 20:02:55.698275219 +0530
|
||||
We also create /{bin,lib,lib64,sbin} in the test container as symbolic
|
||||
links. This brings the test container in line with Fedora's filesystem
|
||||
layout and avoids some test failures. For example, because Fedora's
|
||||
CS_PATH is /usr/bin, tst-vfork3 will try to execute /usr/bin/echo in the
|
||||
container. Without this change the container installs `echo' in /bin
|
||||
not /usr/bin, causing the test to fail.
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index a49870d3d1e636a9..feb2599203b10098 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -598,9 +598,13 @@ $(tests-container) $(addsuffix /tests,$(subdirs)) : \
|
||||
$(objpfx)testroot.pristine/install.stamp :
|
||||
test -d $(objpfx)testroot.pristine || \
|
||||
mkdir $(objpfx)testroot.pristine
|
||||
- # We need a working /bin/sh for some of the tests.
|
||||
- test -d $(objpfx)testroot.pristine/bin || \
|
||||
- mkdir $(objpfx)testroot.pristine/bin
|
||||
+ # Set up symlinks to directories whose contents got moved to /usr
|
||||
+ for moved in bin lib lib64 sbin; do \
|
||||
+ test -d $(objpfx)testroot.pristine/usr/$$moved || \
|
||||
+ mkdir -p $(objpfx)testroot.pristine/usr/$$moved ;\
|
||||
+ test -e $(objpfx)testroot.pristine/$$moved || \
|
||||
+ ln -s usr/$$moved $(objpfx)testroot.pristine/$$moved ;\
|
||||
+ done
|
||||
# We need the compiled locale dir for localedef tests.
|
||||
test -d $(objpfx)testroot.pristine/$(complocaledir) || \
|
||||
mkdir -p $(objpfx)testroot.pristine/$(complocaledir)
|
||||
diff --git a/sysdeps/unix/confstr.h b/sysdeps/unix/confstr.h
|
||||
index 15859c3b2759878e..9b63b7f8069866fd 100644
|
||||
--- a/sysdeps/unix/confstr.h
|
||||
+++ b/sysdeps/unix/confstr.h
|
||||
@@ -1 +1 @@
|
||||
-#define CS_PATH "/bin:/usr/bin"
|
||||
+#define CS_PATH "/usr/bin"
|
||||
|
|
20
glibc-deprecated-selinux-makedb.patch
Normal file
20
glibc-deprecated-selinux-makedb.patch
Normal file
|
@ -0,0 +1,20 @@
|
|||
This is necessary to get things building again after libselinux changes.
|
||||
A proper fix is under discussion upstream:
|
||||
|
||||
<https://sourceware.org/pipermail/libc-alpha/2020-July/116504.html>
|
||||
|
||||
diff --git a/nss/makedb.c b/nss/makedb.c
|
||||
index 8e389a1683747cf1..9d81aed57d384a22 100644
|
||||
--- a/nss/makedb.c
|
||||
+++ b/nss/makedb.c
|
||||
@@ -17,6 +17,10 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+/* This file uses deprecated declarations from libselinux. */
|
||||
+#include <libc-diag.h>
|
||||
+DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
|
||||
+
|
||||
#include <argp.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
|
@ -1,36 +0,0 @@
|
|||
From bf126f79dff0370d1e52ef8193da7fd593c37833 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 19 Jul 2023 23:10:48 +0800
|
||||
Subject: [PATCH 4/6] elf: Align argument of __munmap to page size [BZ #28676]
|
||||
|
||||
On Linux/x86-64, for elf/tst-align3, we now get
|
||||
|
||||
munmap(0x7f88f9401000, 1126424) = 0
|
||||
|
||||
instead of
|
||||
|
||||
munmap(0x7f1615200018, 544768) = -1 EINVAL (Invalid argument)
|
||||
|
||||
Backport from master commit: fd6062e
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
Signed-off-by: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||
---
|
||||
elf/dl-map-segments.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h
|
||||
index 61ba04cd..f1f7ad88 100644
|
||||
--- a/elf/dl-map-segments.h
|
||||
+++ b/elf/dl-map-segments.h
|
||||
@@ -55,6 +55,7 @@ _dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref,
|
||||
if (delta)
|
||||
__munmap ((void *) map_start, delta);
|
||||
ElfW(Addr) map_end = map_start_aligned + maplength;
|
||||
+ map_end = ALIGN_UP (map_end, GLRO(dl_pagesize));
|
||||
delta = map_start + maplen - map_end;
|
||||
if (delta)
|
||||
__munmap ((void *) map_end, delta);
|
||||
--
|
||||
2.27.0
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
From 8b39d3b4bf2fc49ab31f31cf30aa80104afa3432 Mon Sep 17 00:00:00 2001
|
||||
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed, 19 Jul 2023 23:14:33 +0800
|
||||
Subject: [PATCH 6/6] elf: Fix tst-align3
|
||||
|
||||
The elf/tst-align3.c declares the function using a wrong prototype.
|
||||
|
||||
Checked on aarch64-linux-gnu.
|
||||
|
||||
Signed-off-by: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||
---
|
||||
elf/tst-align3.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/elf/tst-align3.c b/elf/tst-align3.c
|
||||
index 87a8ff81..731dd59f 100644
|
||||
--- a/elf/tst-align3.c
|
||||
+++ b/elf/tst-align3.c
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
int bar __attribute__ ((aligned (ALIGN))) = 1;
|
||||
|
||||
-extern int do_load_test (void);
|
||||
+extern void do_load_test (void);
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -30,7 +30,8 @@ do_test (void)
|
||||
printf ("bar: %p\n", &bar);
|
||||
TEST_VERIFY (is_aligned (&bar, ALIGN) == 0);
|
||||
|
||||
- return do_load_test ();
|
||||
+ do_load_test ();
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
||||
--
|
||||
2.27.0
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
From fe5893121176136b0ae3a5f9198536feeb6f64f8 Mon Sep 17 00:00:00 2001
|
||||
From: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||
Date: Wed, 19 Jul 2023 23:05:39 +0800
|
||||
Subject: [PATCH 2/6] elf: Properly align PT_LOAD segments [BZ #28676]
|
||||
|
||||
When PT_LOAD segment alignment > the page size, allocate enough space to
|
||||
ensure that the segment can be properly aligned. This change helps code
|
||||
segments use huge pages become simple and available.
|
||||
|
||||
This fixes [BZ #28676].
|
||||
|
||||
Backport from master commit: 718fdd8
|
||||
|
||||
Signed-off-by: Xu Yu <xuyu@linux.alibaba.com>
|
||||
Signed-off-by: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||
---
|
||||
elf/dl-load.c | 2 ++
|
||||
elf/dl-load.h | 3 ++-
|
||||
elf/dl-map-segments.h | 50 +++++++++++++++++++++++++++++++++++++++----
|
||||
3 files changed, 50 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index 0b45e6e3..132e4233 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Map in a shared object's segments from the file.
|
||||
Copyright (C) 1995-2018 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
|
||||
@@ -1076,6 +1077,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||
c->mapend = ALIGN_UP (ph->p_vaddr + ph->p_filesz, GLRO(dl_pagesize));
|
||||
c->dataend = ph->p_vaddr + ph->p_filesz;
|
||||
c->allocend = ph->p_vaddr + ph->p_memsz;
|
||||
+ c->mapalign = ph->p_align;
|
||||
c->mapoff = ALIGN_DOWN (ph->p_offset, GLRO(dl_pagesize));
|
||||
|
||||
/* Determine whether there is a gap between the last segment
|
||||
diff --git a/elf/dl-load.h b/elf/dl-load.h
|
||||
index 66ea2e92..d9f648ea 100644
|
||||
--- a/elf/dl-load.h
|
||||
+++ b/elf/dl-load.h
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Map in a shared object's segments from the file.
|
||||
Copyright (C) 1995-2018 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
|
||||
@@ -74,7 +75,7 @@ ELF_PREFERRED_ADDRESS_DATA;
|
||||
Its details have been expanded out and converted. */
|
||||
struct loadcmd
|
||||
{
|
||||
- ElfW(Addr) mapstart, mapend, dataend, allocend;
|
||||
+ ElfW(Addr) mapstart, mapend, dataend, allocend, mapalign;
|
||||
ElfW(Off) mapoff;
|
||||
int prot; /* PROT_* bits. */
|
||||
};
|
||||
diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h
|
||||
index 084076a2..61ba04cd 100644
|
||||
--- a/elf/dl-map-segments.h
|
||||
+++ b/elf/dl-map-segments.h
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Map in a shared object's segments. Generic version.
|
||||
Copyright (C) 1995-2018 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
|
||||
@@ -18,6 +19,50 @@
|
||||
|
||||
#include <dl-load.h>
|
||||
|
||||
+/* Map a segment and align it properly. */
|
||||
+
|
||||
+static __always_inline ElfW(Addr)
|
||||
+_dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref,
|
||||
+ const size_t maplength, int fd)
|
||||
+{
|
||||
+ if (__glibc_likely (c->mapalign <= GLRO(dl_pagesize)))
|
||||
+ return (ElfW(Addr)) __mmap ((void *) mappref, maplength, c->prot,
|
||||
+ MAP_COPY|MAP_FILE, fd, c->mapoff);
|
||||
+
|
||||
+ /* If the segment alignment > the page size, allocate enough space to
|
||||
+ ensure that the segment can be properly aligned. */
|
||||
+ ElfW(Addr) maplen = (maplength >= c->mapalign
|
||||
+ ? (maplength + c->mapalign)
|
||||
+ : (2 * c->mapalign));
|
||||
+ ElfW(Addr) map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplen,
|
||||
+ PROT_NONE,
|
||||
+ MAP_ANONYMOUS|MAP_PRIVATE,
|
||||
+ -1, 0);
|
||||
+ if (__glibc_unlikely ((void *) map_start == MAP_FAILED))
|
||||
+ return map_start;
|
||||
+
|
||||
+ ElfW(Addr) map_start_aligned = ALIGN_UP (map_start, c->mapalign);
|
||||
+ map_start_aligned = (ElfW(Addr)) __mmap ((void *) map_start_aligned,
|
||||
+ maplength, c->prot,
|
||||
+ MAP_COPY|MAP_FILE|MAP_FIXED,
|
||||
+ fd, c->mapoff);
|
||||
+ if (__glibc_unlikely ((void *) map_start_aligned == MAP_FAILED))
|
||||
+ __munmap ((void *) map_start, maplen);
|
||||
+ else
|
||||
+ {
|
||||
+ /* Unmap the unused regions. */
|
||||
+ ElfW(Addr) delta = map_start_aligned - map_start;
|
||||
+ if (delta)
|
||||
+ __munmap ((void *) map_start, delta);
|
||||
+ ElfW(Addr) map_end = map_start_aligned + maplength;
|
||||
+ delta = map_start + maplen - map_end;
|
||||
+ if (delta)
|
||||
+ __munmap ((void *) map_end, delta);
|
||||
+ }
|
||||
+
|
||||
+ return map_start_aligned;
|
||||
+}
|
||||
+
|
||||
/* This implementation assumes (as does the corresponding implementation
|
||||
of _dl_unmap_segments, in dl-unmap-segments.h) that shared objects
|
||||
are always laid out with all segments contiguous (or with gaps
|
||||
@@ -53,10 +98,7 @@ _dl_map_segments (struct link_map *l, int fd,
|
||||
- MAP_BASE_ADDR (l));
|
||||
|
||||
/* Remember which part of the address space this object uses. */
|
||||
- l->l_map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplength,
|
||||
- c->prot,
|
||||
- MAP_COPY|MAP_FILE,
|
||||
- fd, c->mapoff);
|
||||
+ l->l_map_start = _dl_map_segment (c, mappref, maplength, fd);
|
||||
if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED))
|
||||
return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
Short description: Cleanup use of _dl_starting_up.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: https://sourceware.org/ml/libc-alpha/2014-02/msg00589.html
|
||||
|
||||
Upstream discussions:
|
||||
https://sourceware.org/ml/libc-alpha/2014-02/msg00580.html
|
||||
|
||||
Based on the following commit:
|
||||
~~~
|
||||
From 16552c01a66633c9e412984d9d92616bd4e5303c Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schwab <schwab@redhat.com>
|
||||
Date: Fri, 11 Jun 2010 11:04:11 +0200
|
||||
Subject: [PATCH] Properly set __libc_multiple_libcs
|
||||
|
||||
* elf/rtld.c (_dl_starting_up): Always define.
|
||||
(dl_main): Always set _dl_starting_up.
|
||||
* elf/dl-support.c (_dl_starting_up): Always define.
|
||||
* elf/dl-init.c (_dl_init): Always clear _dl_starting_up.
|
||||
|
||||
---
|
||||
ChangeLog | 7 +++++++
|
||||
elf/dl-init.c | 4 ----
|
||||
elf/dl-support.c | 2 --
|
||||
elf/rtld.c | 4 ----
|
||||
4 files changed, 7 insertions(+), 10 deletions(-)
|
||||
~~~
|
||||
|
||||
This patch needs to go upstream to get cleaned up, but has always involed
|
||||
analysis of the GNU/Hurd parts of the change and that stalled out, but
|
||||
perhaps with build-many-glibcs we can now test these changes more easily.
|
||||
|
||||
Index: b/elf/dl-init.c
|
||||
===================================================================
|
||||
--- a/elf/dl-init.c
|
||||
+++ b/elf/dl-init.c
|
||||
@@ -119,8 +119,6 @@ _dl_init (struct link_map *main_map, int
|
||||
while (i-- > 0)
|
||||
call_init (main_map->l_initfini[i], argc, argv, env);
|
||||
|
||||
-#ifndef HAVE_INLINED_SYSCALLS
|
||||
/* Finished starting up. */
|
||||
_dl_starting_up = 0;
|
||||
-#endif
|
||||
}
|
||||
Index: b/elf/dl-support.c
|
||||
===================================================================
|
||||
--- a/elf/dl-support.c
|
||||
+++ b/elf/dl-support.c
|
||||
@@ -117,10 +117,8 @@ struct r_scope_elem _dl_initial_searchli
|
||||
.r_nlist = 1,
|
||||
};
|
||||
|
||||
-#ifndef HAVE_INLINED_SYSCALLS
|
||||
/* Nonzero during startup. */
|
||||
int _dl_starting_up = 1;
|
||||
-#endif
|
||||
|
||||
/* Random data provided by the kernel. */
|
||||
void *_dl_random;
|
||||
Index: b/elf/rtld.c
|
||||
===================================================================
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -214,7 +214,6 @@ audit_list_iter_next (struct audit_list_
|
||||
return iter->previous->name;
|
||||
}
|
||||
|
||||
-#ifndef HAVE_INLINED_SYSCALLS
|
||||
/* Set nonzero during loading and initialization of executable and
|
||||
libraries, cleared before the executable's entry point runs. This
|
||||
must not be initialized to nonzero, because the unused dynamic
|
||||
@@ -224,7 +223,6 @@ audit_list_iter_next (struct audit_list_
|
||||
never be called. */
|
||||
int _dl_starting_up = 0;
|
||||
rtld_hidden_def (_dl_starting_up)
|
||||
-#endif
|
||||
|
||||
/* This is the structure which defines all variables global to ld.so
|
||||
(except those which cannot be added for some reason). */
|
||||
@@ -898,10 +896,8 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
/* Process the environment variable which control the behaviour. */
|
||||
process_envvars (&mode);
|
||||
|
||||
-#ifndef HAVE_INLINED_SYSCALLS
|
||||
/* Set up a flag which tells we are just starting. */
|
||||
_dl_starting_up = 1;
|
||||
-#endif
|
||||
|
||||
if (*user_entry == (ElfW(Addr)) ENTRY_POINT)
|
||||
{
|
|
@ -1,61 +0,0 @@
|
|||
Short description: Fedora-specific workaround for kernel pty bug.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-submitted
|
||||
|
||||
This is a Fedora-specific workaround for a kernel bug where calling
|
||||
ioctl on a pty will silently ignore the invalid c_cflag. The
|
||||
workaround is to use TCGETS to verify the setting matches. This is
|
||||
not upstream and needs to either be removed or submitted upstream
|
||||
after analysis.
|
||||
|
||||
Index: b/sysdeps/unix/sysv/linux/tcsetattr.c
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/tcsetattr.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tcsetattr.c
|
||||
@@ -45,6 +45,7 @@ __tcsetattr (int fd, int optional_action
|
||||
{
|
||||
struct __kernel_termios k_termios;
|
||||
unsigned long int cmd;
|
||||
+ int retval;
|
||||
|
||||
switch (optional_actions)
|
||||
{
|
||||
@@ -75,7 +76,36 @@ __tcsetattr (int fd, int optional_action
|
||||
memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
|
||||
__KERNEL_NCCS * sizeof (cc_t));
|
||||
|
||||
- return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
|
||||
+ retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
|
||||
+
|
||||
+ if (retval == 0 && cmd == TCSETS)
|
||||
+ {
|
||||
+ /* The Linux kernel has a bug which silently ignore the invalid
|
||||
+ c_cflag on pty. We have to check it here. */
|
||||
+ int save = errno;
|
||||
+ retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
|
||||
+ if (retval)
|
||||
+ {
|
||||
+ /* We cannot verify if the setting is ok. We don't return
|
||||
+ an error (?). */
|
||||
+ __set_errno (save);
|
||||
+ retval = 0;
|
||||
+ }
|
||||
+ else if ((termios_p->c_cflag & (PARENB | CREAD))
|
||||
+ != (k_termios.c_cflag & (PARENB | CREAD))
|
||||
+ || ((termios_p->c_cflag & CSIZE)
|
||||
+ && ((termios_p->c_cflag & CSIZE)
|
||||
+ != (k_termios.c_cflag & CSIZE))))
|
||||
+ {
|
||||
+ /* It looks like the Linux kernel silently changed the
|
||||
+ PARENB/CREAD/CSIZE bits in c_cflag. Report it as an
|
||||
+ error. */
|
||||
+ __set_errno (EINVAL);
|
||||
+ retval = -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return retval;
|
||||
}
|
||||
weak_alias (__tcsetattr, tcsetattr)
|
||||
libc_hidden_def (tcsetattr)
|
|
@ -1,49 +0,0 @@
|
|||
Short description: Add 4 ISO-8859-15 locales to SUPPORTED for Euro symbol.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Bug-RHEL: #61908
|
||||
Upstream status: not-needed
|
||||
|
||||
Very early RHL 7.3 requirement to add these locales so users can
|
||||
get access to Euro symbol. We should review this bug and decide if
|
||||
the UTF-8 locales are now serving the same purpose and drop the
|
||||
additional locales.
|
||||
|
||||
* Tue Mar 26 2002 Jakub Jelinek <jakub@redhat.com> 2.2.5-28
|
||||
- add a couple of .ISO-8859-15 locales (#61908)
|
||||
|
||||
diff -Nrup a/localedata/SUPPORTED b/localedata/SUPPORTED
|
||||
--- a/localedata/SUPPORTED 2012-11-25 12:59:31.000000000 -0700
|
||||
+++ b/localedata/SUPPORTED 2012-11-26 12:58:43.298223018 -0700
|
||||
@@ -89,6 +89,7 @@ cy_GB.UTF-8/UTF-8 \
|
||||
cy_GB/ISO-8859-14 \
|
||||
da_DK.UTF-8/UTF-8 \
|
||||
da_DK/ISO-8859-1 \
|
||||
+da_DK.ISO-8859-15/ISO-8859-15 \
|
||||
de_AT.UTF-8/UTF-8 \
|
||||
de_AT/ISO-8859-1 \
|
||||
de_AT@euro/ISO-8859-15 \
|
||||
@@ -121,6 +122,7 @@ en_DK.UTF-8/UTF-8 \
|
||||
en_DK/ISO-8859-1 \
|
||||
en_GB.UTF-8/UTF-8 \
|
||||
en_GB/ISO-8859-1 \
|
||||
+en_GB.ISO-8859-15/ISO-8859-15 \
|
||||
en_HK.UTF-8/UTF-8 \
|
||||
en_HK/ISO-8859-1 \
|
||||
en_IE.UTF-8/UTF-8 \
|
||||
@@ -136,6 +138,7 @@ en_SG.UTF-8/UTF-8 \
|
||||
en_SG/ISO-8859-1 \
|
||||
en_US.UTF-8/UTF-8 \
|
||||
en_US/ISO-8859-1 \
|
||||
+en_US.ISO-8859-15/ISO-8859-15 \
|
||||
en_ZA.UTF-8/UTF-8 \
|
||||
en_ZA/ISO-8859-1 \
|
||||
en_ZM/UTF-8 \
|
||||
@@ -385,6 +388,7 @@ sv_FI/ISO-8859-1 \
|
||||
sv_FI@euro/ISO-8859-15 \
|
||||
sv_SE.UTF-8/UTF-8 \
|
||||
sv_SE/ISO-8859-1 \
|
||||
+sv_SE.ISO-8859-15/ISO-8859-15 \
|
||||
sw_KE/UTF-8 \
|
||||
sw_TZ/UTF-8 \
|
||||
szl_PL/UTF-8 \
|
|
@ -1,46 +0,0 @@
|
|||
Short description: Allow access to internal locale archive functions.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-needed
|
||||
|
||||
This is a part of commit glibc-2.3.3-1492-ga891c7b,
|
||||
needed for fedora/build-locale-archive.c only.
|
||||
|
||||
2007-04-16 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* locale/programs/locarchive.c (add_alias, insert_name): Remove static.
|
||||
|
||||
diff -Nrup a/locale/programs/locarchive.c b/locale/programs/locarchive.c
|
||||
--- a/locale/programs/locarchive.c 2012-06-05 07:42:49.000000000 -0600
|
||||
+++ b/locale/programs/locarchive.c 2012-06-07 12:15:21.585319540 -0600
|
||||
@@ -252,9 +252,9 @@ oldlocrecentcmp (const void *a, const vo
|
||||
/* forward decls for below */
|
||||
static uint32_t add_locale (struct locarhandle *ah, const char *name,
|
||||
locale_data_t data, bool replace);
|
||||
-static void add_alias (struct locarhandle *ah, const char *alias,
|
||||
- bool replace, const char *oldname,
|
||||
- uint32_t *locrec_offset_p);
|
||||
+void add_alias (struct locarhandle *ah, const char *alias,
|
||||
+ bool replace, const char *oldname,
|
||||
+ uint32_t *locrec_offset_p);
|
||||
|
||||
|
||||
static bool
|
||||
@@ -635,7 +635,7 @@ close_archive (struct locarhandle *ah)
|
||||
#include "../../intl/explodename.c"
|
||||
#include "../../intl/l10nflist.c"
|
||||
|
||||
-static struct namehashent *
|
||||
+struct namehashent *
|
||||
insert_name (struct locarhandle *ah,
|
||||
const char *name, size_t name_len, bool replace)
|
||||
{
|
||||
@@ -693,7 +693,7 @@ insert_name (struct locarhandle *ah,
|
||||
return &namehashtab[idx];
|
||||
}
|
||||
|
||||
-static void
|
||||
+void
|
||||
add_alias (struct locarhandle *ah, const char *alias, bool replace,
|
||||
const char *oldname, uint32_t *locrec_offset_p)
|
||||
{
|
|
@ -1,31 +0,0 @@
|
|||
Short description: Fedora-specific enabling batch read in NSS.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Bug-RHEL: #188246
|
||||
Upstream status: not-submitted
|
||||
|
||||
Enable batch read in NSS. It's not clear if this is always a win or
|
||||
just a win for NIS+, this needs to be analyzed and sent upstream or
|
||||
removed.
|
||||
|
||||
From baba5d9461d4e8a581ac26fe4412ad783ffc73e7 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Mon, 1 May 2006 08:02:53 +0000
|
||||
Subject: [PATCH] Enable SETENT_BATCH_READ nis/nss option by default
|
||||
|
||||
* Mon May 1 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-4
|
||||
- SETENT_BATCH_READ /etc/default/nss option for speeding up
|
||||
some usages of NIS+ (#188246)
|
||||
|
||||
diff --git a/nis/nss b/nis/nss
|
||||
--- a/nis/nss
|
||||
+++ b/nis/nss
|
||||
@@ -25,7 +25,7 @@
|
||||
# memory with every getXXent() call. Otherwise each getXXent() call
|
||||
# might result into a network communication with the server to get
|
||||
# the next entry.
|
||||
-#SETENT_BATCH_READ=TRUE
|
||||
+SETENT_BATCH_READ=TRUE
|
||||
#
|
||||
# ADJUNCT_AS_SHADOW
|
||||
# If set to TRUE, the passwd routines in the NIS NSS module will not
|
|
@ -1,20 +0,0 @@
|
|||
Short description: NSCD must use nscd user.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-needed
|
||||
|
||||
Fedora-specific configuration adjustment to introduce the nscd user.
|
||||
(Upstream does not assume this user exists.)
|
||||
|
||||
diff -Nrup a/nscd/nscd.conf b/nscd/nscd.conf
|
||||
--- a/nscd/nscd.conf 2012-06-05 07:42:49.000000000 -0600
|
||||
+++ b/nscd/nscd.conf 2012-06-07 12:15:21.818318670 -0600
|
||||
@@ -33,7 +33,7 @@
|
||||
# logfile /var/log/nscd.log
|
||||
# threads 4
|
||||
# max-threads 32
|
||||
-# server-user nobody
|
||||
+ server-user nscd
|
||||
# stat-user somebody
|
||||
debug-level 0
|
||||
# reload-count 5
|
|
@ -1,38 +0,0 @@
|
|||
Short description: Do not define _XOPEN_STREAMS.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Bug-Fedora: #436349
|
||||
Upstream status: not-submitted
|
||||
|
||||
This patch should go upstream. Not defining _XOPEN_STREAMS is the
|
||||
same as setting it to -1 for POSIX conformance. The headers setting
|
||||
needs to be reviewed indepedently.
|
||||
|
||||
This is part of commit glibc-2.3.3-1564-gd0b6ac6
|
||||
|
||||
* Fri Mar 14 2008 Jakub Jelinek <jakub@redhat.com> 2.7.90-11
|
||||
- remove <stropts.h>, define _XOPEN_STREAMS -1 (#436349)
|
||||
|
||||
diff -Nrup a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
|
||||
--- a/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-05 07:42:49.000000000 -0600
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-07 12:15:21.817318674 -0600
|
||||
@@ -188,4 +188,7 @@
|
||||
/* Typed memory objects are not available. */
|
||||
#define _POSIX_TYPED_MEMORY_OBJECTS -1
|
||||
|
||||
+/* Streams are not available. */
|
||||
+#define _XOPEN_STREAMS -1
|
||||
+
|
||||
#endif /* bits/posix_opt.h */
|
||||
diff -Nrup a/streams/Makefile b/streams/Makefile
|
||||
--- a/streams/Makefile 2012-06-05 07:42:49.000000000 -0600
|
||||
+++ b/streams/Makefile 2012-06-07 12:15:21.824318649 -0600
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
-headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
|
||||
+#headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
|
||||
routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach
|
||||
|
||||
include ../Rules
|
797
glibc-gb18030-2022-bug30243.patch
Normal file
797
glibc-gb18030-2022-bug30243.patch
Normal file
|
@ -0,0 +1,797 @@
|
|||
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>
|
|
@ -8,14 +8,14 @@ behaviour which updates the locale archive. The Fedora install phase
|
|||
in the spec file of the rpm will handle this manually.
|
||||
|
||||
diff --git a/localedata/Makefile b/localedata/Makefile
|
||||
index a5f3c92d58954dfc..56719c7c714aa0f1 100644
|
||||
index 0eea396ad86da956..54caabda33728207 100644
|
||||
--- a/localedata/Makefile
|
||||
+++ b/localedata/Makefile
|
||||
@@ -218,6 +218,7 @@ $(INSTALL-SUPPORTED-LOCALES): install-locales-dir
|
||||
@@ -413,6 +413,7 @@ define build-one-locale
|
||||
echo -n '...'; \
|
||||
input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \
|
||||
$(LOCALEDEF) $$flags --alias-file=../intl/locale.alias \
|
||||
+ --no-archive \
|
||||
-i locales/$$input -f charmaps/$$charset \
|
||||
$(addprefix --prefix=,$(install_root)) $$locale \
|
||||
&& echo ' done'; \
|
||||
&& echo ' done';
|
|
@ -1,21 +0,0 @@
|
|||
Short description: Provide options to nscd startup.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-needed
|
||||
|
||||
Fedora-specific nscd startup configuration file.
|
||||
|
||||
diff --git a/nscd/nscd.service b/nscd/nscd.service
|
||||
index b7428a3..19ba185 100644
|
||||
--- a/nscd/nscd.service
|
||||
+++ b/nscd/nscd.service
|
||||
@@ -5,7 +5,8 @@ Description=Name Service Cache Daemon
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
-ExecStart=/usr/sbin/nscd
|
||||
+EnvironmentFile=-/etc/sysconfig/nscd
|
||||
+ExecStart=/usr/sbin/nscd $NSCD_OPTIONS
|
||||
ExecStop=/usr/sbin/nscd --shutdown
|
||||
ExecReload=/usr/sbin/nscd -i passwd
|
||||
ExecReload=/usr/sbin/nscd -i group
|
|
@ -8,33 +8,24 @@ python3 during a transitional phase.
|
|||
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
|
||||
diff --git a/benchtests/scripts/compare_bench.py b/benchtests/scripts/compare_bench.py
|
||||
index ea25f778c09bba9d..b53beb3c6e32c3cf 100755
|
||||
index a85ca3a38be1fdeb..9f1ea9d85f4b833a 100755
|
||||
--- a/benchtests/scripts/compare_bench.py
|
||||
+++ b/benchtests/scripts/compare_bench.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# Copyright (C) 2015-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2015-2023 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
#
|
||||
diff --git a/benchtests/scripts/import_bench.py b/benchtests/scripts/import_bench.py
|
||||
index 602b3f954d4801a6..76bf1528a5418748 100644
|
||||
index d8bdde7753885a4d..698c4ff81b13f697 100644
|
||||
--- a/benchtests/scripts/import_bench.py
|
||||
+++ b/benchtests/scripts/import_bench.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# Copyright (C) 2015-2018 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
#
|
||||
diff --git a/benchtests/scripts/validate_benchout.py b/benchtests/scripts/validate_benchout.py
|
||||
index 6147f05bec3a4844..9a5c7947ee4ed7e9 100755
|
||||
--- a/benchtests/scripts/validate_benchout.py
|
||||
+++ b/benchtests/scripts/validate_benchout.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# Copyright (C) 2014-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2015-2023 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
#
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,79 +0,0 @@
|
|||
commit dbb75513f5cf9285c77c9e55777c5c35b653f890
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 6 07:38:10 2022 +0200
|
||||
|
||||
elf: Rename _dl_sort_maps parameter from skip to force_first
|
||||
|
||||
The new implementation will not be able to skip an arbitrary number
|
||||
of objects.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||
index 99354dc08a010dd3..7a586749adc3fa7d 100644
|
||||
--- a/elf/dl-sort-maps.c
|
||||
+++ b/elf/dl-sort-maps.c
|
||||
@@ -27,12 +27,12 @@
|
||||
If FOR_FINI is true, this is called for finishing an object. */
|
||||
static void
|
||||
_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
|
||||
- unsigned int skip, bool for_fini)
|
||||
+ bool force_first, bool for_fini)
|
||||
{
|
||||
/* Allows caller to do the common optimization of skipping the first map,
|
||||
usually the main binary. */
|
||||
- maps += skip;
|
||||
- nmaps -= skip;
|
||||
+ maps += force_first;
|
||||
+ nmaps -= force_first;
|
||||
|
||||
/* A list of one element need not be sorted. */
|
||||
if (nmaps <= 1)
|
||||
@@ -182,7 +182,7 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
|
||||
|
||||
static void
|
||||
_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
- unsigned int skip __attribute__ ((unused)), bool for_fini)
|
||||
+ bool force_first __attribute__ ((unused)), bool for_fini)
|
||||
{
|
||||
for (int i = nmaps - 1; i >= 0; i--)
|
||||
maps[i]->l_visited = 0;
|
||||
@@ -286,7 +286,7 @@ _dl_sort_maps_init (void)
|
||||
|
||||
void
|
||||
_dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
- unsigned int skip, bool for_fini)
|
||||
+ bool force_first, bool for_fini)
|
||||
{
|
||||
/* It can be tempting to use a static function pointer to store and call
|
||||
the current selected sorting algorithm routine, but experimentation
|
||||
@@ -296,9 +296,9 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
input cases. A simple if-case with direct function calls appears to
|
||||
be the fastest. */
|
||||
if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original))
|
||||
- _dl_sort_maps_original (maps, nmaps, skip, for_fini);
|
||||
+ _dl_sort_maps_original (maps, nmaps, force_first, for_fini);
|
||||
else
|
||||
- _dl_sort_maps_dfs (maps, nmaps, skip, for_fini);
|
||||
+ _dl_sort_maps_dfs (maps, nmaps, force_first, for_fini);
|
||||
}
|
||||
|
||||
#endif /* HAVE_TUNABLES. */
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 9f09a4a280396659..2c1b4c47c6a6c643 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1056,9 +1056,11 @@ extern void _dl_init (struct link_map *main_map, int argc, char **argv,
|
||||
initializer functions have completed. */
|
||||
extern void _dl_fini (void) attribute_hidden;
|
||||
|
||||
-/* Sort array MAPS according to dependencies of the contained objects. */
|
||||
+/* Sort array MAPS according to dependencies of the contained objects.
|
||||
+ If FORCE_FIRST, MAPS[0] keeps its place even if the dependencies
|
||||
+ say otherwise. */
|
||||
extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
- unsigned int skip, bool for_fini) attribute_hidden;
|
||||
+ bool force_first, bool for_fini) attribute_hidden;
|
||||
|
||||
/* The dynamic linker calls this function before and having changing
|
||||
any shared object mappings. The `r_state' member of `struct r_debug'
|
|
@ -1,90 +0,0 @@
|
|||
commit 1df71d32fe5f5905ffd5d100e5e9ca8ad6210891
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 20 11:00:42 2022 +0200
|
||||
|
||||
elf: Implement force_first handling in _dl_sort_maps_dfs (bug 28937)
|
||||
|
||||
The implementation in _dl_close_worker requires that the first
|
||||
element of l_initfini is always this very map (“We are always the
|
||||
zeroth entry, and since we don't include ourselves in the
|
||||
dependency analysis start at 1.”). Rather than fixing that
|
||||
assumption, this commit adds an implementation of the force_first
|
||||
argument to the new dependency sorting algorithm. This also means
|
||||
that the directly dlopen'ed shared object is always initialized last,
|
||||
which is the least surprising behavior in the presence of cycles.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||
index 7a586749adc3fa7d..6f5c17b47b98fbc7 100644
|
||||
--- a/elf/dl-sort-maps.c
|
||||
+++ b/elf/dl-sort-maps.c
|
||||
@@ -182,8 +182,9 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
|
||||
|
||||
static void
|
||||
_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
- bool force_first __attribute__ ((unused)), bool for_fini)
|
||||
+ bool force_first, bool for_fini)
|
||||
{
|
||||
+ struct link_map *first_map = maps[0];
|
||||
for (int i = nmaps - 1; i >= 0; i--)
|
||||
maps[i]->l_visited = 0;
|
||||
|
||||
@@ -208,14 +209,6 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
Adjusting the order so that maps[0] is last traversed naturally avoids
|
||||
this problem.
|
||||
|
||||
- Further, the old "optimization" of skipping the main object at maps[0]
|
||||
- from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general
|
||||
- no longer valid, since traversing along object dependency-links
|
||||
- may "find" the main object even when it is not included in the initial
|
||||
- order (e.g. a dlopen()'ed shared object can have circular dependencies
|
||||
- linked back to itself). In such a case, traversing N-1 objects will
|
||||
- create a N-object result, and raise problems.
|
||||
-
|
||||
To summarize, just passing in the full list, and iterating from back
|
||||
to front makes things much more straightforward. */
|
||||
|
||||
@@ -274,6 +267,27 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
}
|
||||
|
||||
memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
|
||||
+
|
||||
+ /* Skipping the first object at maps[0] is not valid in general,
|
||||
+ since traversing along object dependency-links may "find" that
|
||||
+ first object even when it is not included in the initial order
|
||||
+ (e.g., a dlopen'ed shared object can have circular dependencies
|
||||
+ linked back to itself). In such a case, traversing N-1 objects
|
||||
+ will create a N-object result, and raise problems. Instead,
|
||||
+ force the object back into first place after sorting. This naive
|
||||
+ approach may introduce further dependency ordering violations
|
||||
+ compared to rotating the cycle until the first map is again in
|
||||
+ the first position, but as there is a cycle, at least one
|
||||
+ violation is already present. */
|
||||
+ if (force_first && maps[0] != first_map)
|
||||
+ {
|
||||
+ int i;
|
||||
+ for (i = 0; maps[i] != first_map; ++i)
|
||||
+ ;
|
||||
+ assert (i < nmaps);
|
||||
+ memmove (&maps[1], maps, i * sizeof (maps[0]));
|
||||
+ maps[0] = first_map;
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
|
||||
index 5f7f18ef270bc12d..4bf9052db16fb352 100644
|
||||
--- a/elf/dso-sort-tests-1.def
|
||||
+++ b/elf/dso-sort-tests-1.def
|
||||
@@ -64,3 +64,10 @@ output: b>a>{}<a<b
|
||||
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];}
|
||||
+
|
||||
+# 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.
|
||||
+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
|
|
@ -1,35 +0,0 @@
|
|||
Downstream-specific patch to link DSO sorting tests with -ldl
|
||||
if needed. Upstream does not need this because <dlfcn.h> interfaces
|
||||
are part of libc.
|
||||
|
||||
diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
|
||||
index 43b5ec4d920ad6a3..ae85e0f4a6ae5b3e 100644
|
||||
--- a/scripts/dso-ordering-test.py
|
||||
+++ b/scripts/dso-ordering-test.py
|
||||
@@ -657,6 +657,8 @@ def process_testcase(t):
|
||||
% (test_name + "-" + dep + ".FAKE.so",
|
||||
("$(objpfx)" + test_subdir + "/"
|
||||
+ test_name + "-" + dep + ".so")))
|
||||
+ makefile.write(
|
||||
+ "LDLIBS-%s += -Wl,--as-needed -ldl -Wl,--no-as-needed\n" % dso)
|
||||
rule = ("$(objpfx)" + test_subdir + "/"
|
||||
+ test_name + "-" + dep + ".FAKE.os: "
|
||||
"$(objpfx)" + test_srcdir
|
||||
@@ -685,6 +687,8 @@ def process_testcase(t):
|
||||
+ test_descr.soname_map[o] + ".so")
|
||||
ldflags += (" -Wl,-soname=" + soname)
|
||||
makefile.write("LDFLAGS-%s = %s\n" % (dso, ldflags))
|
||||
+ makefile.write(
|
||||
+ "LDLIBS-%s += -Wl,--as-needed -ldl -Wl,--no-as-needed\n" % dso)
|
||||
if o in test_descr.callrefs:
|
||||
makefile.write("%s-no-z-defs = yes\n" % (dso))
|
||||
|
||||
@@ -702,6 +706,8 @@ def process_testcase(t):
|
||||
+ test_descr.soname_map['#'] + ".so")
|
||||
ldflags += (" -Wl,-soname=" + soname)
|
||||
makefile.write("LDFLAGS-%s = %s\n" % (test_name, ldflags))
|
||||
+ makefile.write(
|
||||
+ "LDLIBS-%s += -Wl,--as-needed -ldl -Wl,--no-as-needed\n" % test_name)
|
||||
rule = ("$(objpfx)" + test_subdir + "/" + test_name + ".o: "
|
||||
"$(objpfx)" + test_srcdir + test_name + ".c\n"
|
||||
"\t$(compile.c) $(OUTPUT_OPTION)\n")
|
|
@ -1,189 +0,0 @@
|
|||
commit b4bbedb1e75737a80bcc3d53d6eef1fbe0b5f4d5
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Sat Nov 6 14:13:27 2021 -0700
|
||||
|
||||
dso-ordering-test.py: Put all sources in one directory [BZ #28550]
|
||||
|
||||
Put all sources for DSO sorting tests in the dso-sort-tests-src directory
|
||||
and compile test relocatable objects with
|
||||
|
||||
$(objpfx)tst-dso-ordering1-dir/tst-dso-ordering1-a.os: $(objpfx)dso-sort-tests-src/tst-dso-ordering1-a.c
|
||||
$(compile.c) $(OUTPUT_OPTION)
|
||||
|
||||
to avoid random $< values from $(before-compile) when compiling test
|
||||
relocatable objects with
|
||||
|
||||
$(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c)
|
||||
compile-command.c = $(compile.c) $(OUTPUT_OPTION) $(compile-mkdep-flags)
|
||||
compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS)
|
||||
|
||||
for 3 "make -j 28" parallel builds on a machine with 112 cores at the
|
||||
same time.
|
||||
|
||||
This partially fixes BZ #28550.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
|
||||
index 944ee740527d60fd..bde0406be9da14fc 100644
|
||||
--- a/scripts/dso-ordering-test.py
|
||||
+++ b/scripts/dso-ordering-test.py
|
||||
@@ -526,9 +526,13 @@ def process_testcase(t):
|
||||
base_test_name = t.test_name
|
||||
test_subdir = base_test_name + "-dir"
|
||||
testpfx = objpfx + test_subdir + "/"
|
||||
+ test_srcdir = "dso-sort-tests-src/"
|
||||
+ testpfx_src = objpfx + test_srcdir
|
||||
|
||||
if not os.path.exists(testpfx):
|
||||
os.mkdir(testpfx)
|
||||
+ if not os.path.exists(testpfx_src):
|
||||
+ os.mkdir(testpfx_src)
|
||||
|
||||
def find_objs_not_depended_on(t):
|
||||
objs_not_depended_on = []
|
||||
@@ -595,6 +599,11 @@ def process_testcase(t):
|
||||
# Print out needed Makefile fragments for use in glibc/elf/Makefile.
|
||||
module_names = ""
|
||||
for o in test_descr.objs:
|
||||
+ rule = ("$(objpfx)" + test_subdir + "/" + test_name
|
||||
+ + "-" + o + ".os: $(objpfx)" + test_srcdir
|
||||
+ + test_name + "-" + o + ".c\n"
|
||||
+ "\t$(compile.c) $(OUTPUT_OPTION)\n")
|
||||
+ makefile.write (rule)
|
||||
module_names += " " + test_subdir + "/" + test_name + "-" + o
|
||||
makefile.write("modules-names +=%s\n" % (module_names))
|
||||
|
||||
@@ -637,7 +646,7 @@ def process_testcase(t):
|
||||
# object. This only needs to be done at most once for
|
||||
# an object name.
|
||||
if not dep in fake_created:
|
||||
- f = open(testpfx + test_name + "-" + dep
|
||||
+ f = open(testpfx_src + test_name + "-" + dep
|
||||
+ ".FAKE.c", "w")
|
||||
f.write(" \n")
|
||||
f.close()
|
||||
@@ -648,6 +657,12 @@ def process_testcase(t):
|
||||
% (test_name + "-" + dep + ".FAKE.so",
|
||||
("$(objpfx)" + test_subdir + "/"
|
||||
+ test_name + "-" + dep + ".so")))
|
||||
+ rule = ("$(objpfx)" + test_subdir + "/"
|
||||
+ + test_name + "-" + dep + ".FAKE.os: "
|
||||
+ "$(objpfx)" + test_srcdir
|
||||
+ + test_name + "-" + dep + ".FAKE.c\n"
|
||||
+ "\t$(compile.c) $(OUTPUT_OPTION)\n")
|
||||
+ makefile.write (rule)
|
||||
makefile.write \
|
||||
("modules-names += %s\n"
|
||||
% (test_subdir + "/"
|
||||
@@ -687,6 +702,10 @@ def process_testcase(t):
|
||||
+ test_descr.soname_map['#'] + ".so")
|
||||
ldflags += (" -Wl,-soname=" + soname)
|
||||
makefile.write("LDFLAGS-%s = %s\n" % (test_name, ldflags))
|
||||
+ rule = ("$(objpfx)" + test_subdir + "/" + test_name + ".o: "
|
||||
+ "$(objpfx)" + test_srcdir + test_name + ".c\n"
|
||||
+ "\t$(compile.c) $(OUTPUT_OPTION)\n")
|
||||
+ makefile.write (rule)
|
||||
|
||||
not_depended_objs = find_objs_not_depended_on(test_descr)
|
||||
if not_depended_objs:
|
||||
@@ -745,7 +764,7 @@ def process_testcase(t):
|
||||
" something_failed=true\n"
|
||||
"else\n"
|
||||
" diff -wu ${common_objpfx}elf/%s/%s%s.output \\\n"
|
||||
- " ${common_objpfx}elf/%s/%s%s.exp\n"
|
||||
+ " ${common_objpfx}elf/%s%s%s.exp\n"
|
||||
" if [ $? -ne 0 ]; then\n"
|
||||
" echo '%sFAIL: %s%s expected output comparison'\n"
|
||||
" something_failed=true\n"
|
||||
@@ -753,14 +772,14 @@ def process_testcase(t):
|
||||
"fi\n"
|
||||
% (("X" if xfail else ""), test_name, tunable_descr,
|
||||
test_subdir, test_name, tunable_sfx,
|
||||
- test_subdir, base_test_name, exp_tunable_sfx,
|
||||
+ test_srcdir, base_test_name, exp_tunable_sfx,
|
||||
("X" if xfail else ""), test_name, tunable_descr))
|
||||
|
||||
# Generate C files according to dependency and calling relations from
|
||||
# description string.
|
||||
for obj in test_descr.objs:
|
||||
src_name = test_name + "-" + obj + ".c"
|
||||
- f = open(testpfx + src_name, "w")
|
||||
+ f = open(testpfx_src + src_name, "w")
|
||||
if obj in test_descr.callrefs:
|
||||
called_objs = test_descr.callrefs[obj]
|
||||
for callee in called_objs:
|
||||
@@ -804,7 +823,7 @@ def process_testcase(t):
|
||||
f.close()
|
||||
|
||||
# Open C file for writing main program
|
||||
- f = open(testpfx + test_name + ".c", "w")
|
||||
+ f = open(testpfx_src + test_name + ".c", "w")
|
||||
|
||||
# if there are some operations in main(), it means we need -ldl
|
||||
f.write("#include <stdio.h>\n")
|
||||
@@ -885,7 +904,7 @@ def process_testcase(t):
|
||||
for obj in test_descr.objs:
|
||||
src_name = test_name + "-" + obj + ".c"
|
||||
obj_name = test_name + "-" + obj + ".os"
|
||||
- run_cmd([build_gcc, "-c", "-fPIC", testpfx + src_name,
|
||||
+ run_cmd([build_gcc, "-c", "-fPIC", testpfx_src + src_name,
|
||||
"-o", testpfx + obj_name])
|
||||
|
||||
obj_processed = {}
|
||||
@@ -903,10 +922,12 @@ def process_testcase(t):
|
||||
deps.append(dep + ".FAKE")
|
||||
if not dep in fake_created:
|
||||
base_name = testpfx + test_name + "-" + dep
|
||||
+ src_base_name = (testpfx_src + test_name
|
||||
+ + "-" + dep)
|
||||
cmd = [build_gcc, "-Wl,--no-as-needed",
|
||||
("-Wl,-soname=" + base_name + ".so"),
|
||||
"-shared", base_name + ".FAKE.c",
|
||||
- "-o", base_name + ".FAKE.so"]
|
||||
+ "-o", src_base_name + ".FAKE.so"]
|
||||
run_cmd(cmd)
|
||||
fake_created[dep] = True
|
||||
dso_deps = map(lambda d: testpfx + test_name + "-" + d + ".so",
|
||||
@@ -932,7 +953,7 @@ def process_testcase(t):
|
||||
main_deps = map(lambda d: testpfx + test_name + "-" + d + ".so",
|
||||
deps)
|
||||
cmd = [build_gcc, "-Wl,--no-as-needed", "-o", testpfx + test_name,
|
||||
- testpfx + test_name + ".c", "-L%s" % (os.getcwd()),
|
||||
+ testpfx_src + test_name + ".c", "-L%s" % (os.getcwd()),
|
||||
"-Wl,-rpath-link=%s" % (os.getcwd())]
|
||||
if '#' in test_descr.soname_map:
|
||||
soname = ("-Wl,-soname=" + testpfx + test_name + "-"
|
||||
@@ -987,14 +1008,14 @@ def process_testcase(t):
|
||||
sfx = ""
|
||||
if r[0] != "":
|
||||
sfx = "-" + r[0].replace("=","_")
|
||||
- f = open(testpfx + t.test_name + sfx + ".exp", "w")
|
||||
+ f = open(testpfx_src + t.test_name + sfx + ".exp", "w")
|
||||
(output, xfail) = r[1]
|
||||
f.write('%s' % output)
|
||||
f.close()
|
||||
|
||||
# Create header part of top-level testcase shell script, to wrap execution
|
||||
# and output comparison together.
|
||||
- t.sh = open(testpfx + t.test_name + ".sh", "w")
|
||||
+ t.sh = open(testpfx_src + t.test_name + ".sh", "w")
|
||||
t.sh.write("#!/bin/sh\n")
|
||||
t.sh.write("# Test driver for %s, generated by "
|
||||
"dso-ordering-test.py\n" % (t.test_name))
|
||||
@@ -1022,12 +1043,12 @@ def process_testcase(t):
|
||||
sfx = ""
|
||||
if r[0] != "":
|
||||
sfx = "-" + r[0].replace("=","_")
|
||||
- expected_output_files += " $(objpfx)%s/%s%s.exp" % (test_subdir,
|
||||
+ expected_output_files += " $(objpfx)%s%s%s.exp" % (test_srcdir,
|
||||
t.test_name, sfx)
|
||||
makefile.write \
|
||||
- ("$(objpfx)%s.out: $(objpfx)%s/%s.sh%s "
|
||||
+ ("$(objpfx)%s.out: $(objpfx)%s%s.sh%s "
|
||||
"$(common-objpfx)support/test-run-command\n"
|
||||
- % (t.test_name, test_subdir, t.test_name,
|
||||
+ % (t.test_name, test_srcdir, t.test_name,
|
||||
expected_output_files))
|
||||
makefile.write("\t$(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' "
|
||||
"'$(run-program-env)' > $@; $(evaluate-test)\n")
|
|
@ -1,589 +0,0 @@
|
|||
commit 15a0c5730d1d5aeb95f50c9ec7470640084feae8
|
||||
Author: Chung-Lin Tang <cltang@codesourcery.com>
|
||||
Date: Thu Oct 21 21:41:22 2021 +0800
|
||||
|
||||
elf: Fix slow DSO sorting behavior in dynamic loader (BZ #17645)
|
||||
|
||||
This second patch contains the actual implementation of a new sorting algorithm
|
||||
for shared objects in the dynamic loader, which solves the slow behavior that
|
||||
the current "old" algorithm falls into when the DSO set contains circular
|
||||
dependencies.
|
||||
|
||||
The new algorithm implemented here is simply depth-first search (DFS) to obtain
|
||||
the Reverse-Post Order (RPO) sequence, a topological sort. A new l_visited:1
|
||||
bitfield is added to struct link_map to more elegantly facilitate such a search.
|
||||
|
||||
The DFS algorithm is applied to the input maps[nmap-1] backwards towards
|
||||
maps[0]. This has the effect of a more "shallow" recursion depth in general
|
||||
since the input is in BFS. Also, when combined with the natural order of
|
||||
processing l_initfini[] at each node, this creates a resulting output sorting
|
||||
closer to the intuitive "left-to-right" order in most cases.
|
||||
|
||||
Another notable implementation adjustment related to this _dl_sort_maps change
|
||||
is the removing of two char arrays 'used' and 'done' in _dl_close_worker to
|
||||
represent two per-map attributes. This has been changed to simply use two new
|
||||
bit-fields l_map_used:1, l_map_done:1 added to struct link_map. This also allows
|
||||
discarding the clunky 'used' array sorting that _dl_sort_maps had to sometimes
|
||||
do along the way.
|
||||
|
||||
Tunable support for switching between different sorting algorithms at runtime is
|
||||
also added. A new tunable 'glibc.rtld.dynamic_sort' with current valid values 1
|
||||
(old algorithm) and 2 (new DFS algorithm) has been added. At time of commit
|
||||
of this patch, the default setting is 1 (old algorithm).
|
||||
|
||||
Signed-off-by: Chung-Lin Tang <cltang@codesourcery.com>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
Conflicts:
|
||||
elf/dl-tunables.list
|
||||
(No mem.tagging tunable downstream.)
|
||||
|
||||
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||
index 74ca9a85dd309780..22225efb3226c3e1 100644
|
||||
--- a/elf/dl-close.c
|
||||
+++ b/elf/dl-close.c
|
||||
@@ -167,8 +167,6 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
|
||||
bool any_tls = false;
|
||||
const unsigned int nloaded = ns->_ns_nloaded;
|
||||
- char used[nloaded];
|
||||
- char done[nloaded];
|
||||
struct link_map *maps[nloaded];
|
||||
|
||||
/* Run over the list and assign indexes to the link maps and enter
|
||||
@@ -176,24 +174,21 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
int idx = 0;
|
||||
for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next)
|
||||
{
|
||||
+ l->l_map_used = 0;
|
||||
+ l->l_map_done = 0;
|
||||
l->l_idx = idx;
|
||||
maps[idx] = l;
|
||||
++idx;
|
||||
-
|
||||
}
|
||||
assert (idx == nloaded);
|
||||
|
||||
- /* Prepare the bitmaps. */
|
||||
- memset (used, '\0', sizeof (used));
|
||||
- memset (done, '\0', sizeof (done));
|
||||
-
|
||||
/* Keep track of the lowest index link map we have covered already. */
|
||||
int done_index = -1;
|
||||
while (++done_index < nloaded)
|
||||
{
|
||||
struct link_map *l = maps[done_index];
|
||||
|
||||
- if (done[done_index])
|
||||
+ if (l->l_map_done)
|
||||
/* Already handled. */
|
||||
continue;
|
||||
|
||||
@@ -204,12 +199,12 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
/* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why
|
||||
acquire is sufficient and correct. */
|
||||
&& atomic_load_acquire (&l->l_tls_dtor_count) == 0
|
||||
- && !used[done_index])
|
||||
+ && !l->l_map_used)
|
||||
continue;
|
||||
|
||||
/* We need this object and we handle it now. */
|
||||
- done[done_index] = 1;
|
||||
- used[done_index] = 1;
|
||||
+ l->l_map_used = 1;
|
||||
+ l->l_map_done = 1;
|
||||
/* Signal the object is still needed. */
|
||||
l->l_idx = IDX_STILL_USED;
|
||||
|
||||
@@ -225,9 +220,9 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
{
|
||||
assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded);
|
||||
|
||||
- if (!used[(*lp)->l_idx])
|
||||
+ if (!(*lp)->l_map_used)
|
||||
{
|
||||
- used[(*lp)->l_idx] = 1;
|
||||
+ (*lp)->l_map_used = 1;
|
||||
/* If we marked a new object as used, and we've
|
||||
already processed it, then we need to go back
|
||||
and process again from that point forward to
|
||||
@@ -250,9 +245,9 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
{
|
||||
assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded);
|
||||
|
||||
- if (!used[jmap->l_idx])
|
||||
+ if (!jmap->l_map_used)
|
||||
{
|
||||
- used[jmap->l_idx] = 1;
|
||||
+ jmap->l_map_used = 1;
|
||||
if (jmap->l_idx - 1 < done_index)
|
||||
done_index = jmap->l_idx - 1;
|
||||
}
|
||||
@@ -262,8 +257,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
|
||||
/* Sort the entries. We can skip looking for the binary itself which is
|
||||
at the front of the search list for the main namespace. */
|
||||
- _dl_sort_maps (maps + (nsid == LM_ID_BASE), nloaded - (nsid == LM_ID_BASE),
|
||||
- used + (nsid == LM_ID_BASE), true);
|
||||
+ _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
|
||||
|
||||
/* Call all termination functions at once. */
|
||||
bool unload_any = false;
|
||||
@@ -277,7 +271,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
/* All elements must be in the same namespace. */
|
||||
assert (imap->l_ns == nsid);
|
||||
|
||||
- if (!used[i])
|
||||
+ if (!imap->l_map_used)
|
||||
{
|
||||
assert (imap->l_type == lt_loaded && !imap->l_nodelete_active);
|
||||
|
||||
@@ -315,7 +309,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
if (i < first_loaded)
|
||||
first_loaded = i;
|
||||
}
|
||||
- /* Else used[i]. */
|
||||
+ /* Else imap->l_map_used. */
|
||||
else if (imap->l_type == lt_loaded)
|
||||
{
|
||||
struct r_scope_elem *new_list = NULL;
|
||||
@@ -524,7 +518,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
for (unsigned int i = first_loaded; i < nloaded; ++i)
|
||||
{
|
||||
struct link_map *imap = maps[i];
|
||||
- if (!used[i])
|
||||
+ if (!imap->l_map_used)
|
||||
{
|
||||
assert (imap->l_type == lt_loaded);
|
||||
|
||||
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
|
||||
index 007069f670eced95..9365d54c8e03e5f4 100644
|
||||
--- a/elf/dl-deps.c
|
||||
+++ b/elf/dl-deps.c
|
||||
@@ -612,10 +612,9 @@ Filters not supported with LD_TRACE_PRELINKING"));
|
||||
|
||||
/* If libc.so.6 is the main map, it participates in the sort, so
|
||||
that the relocation order is correct regarding libc.so.6. */
|
||||
- if (l_initfini[0] == GL (dl_ns)[l_initfini[0]->l_ns].libc_map)
|
||||
- _dl_sort_maps (l_initfini, nlist, NULL, false);
|
||||
- else
|
||||
- _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
|
||||
+ _dl_sort_maps (l_initfini, nlist,
|
||||
+ (l_initfini[0] != GL (dl_ns)[l_initfini[0]->l_ns].libc_map),
|
||||
+ false);
|
||||
|
||||
/* Terminate the list of dependencies. */
|
||||
l_initfini[nlist] = NULL;
|
||||
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
|
||||
index eea9d8aad736a99e..e14259a3c8806e0d 100644
|
||||
--- a/elf/dl-fini.c
|
||||
+++ b/elf/dl-fini.c
|
||||
@@ -95,8 +95,7 @@ _dl_fini (void)
|
||||
/* Now we have to do the sorting. We can skip looking for the
|
||||
binary itself which is at the front of the search list for
|
||||
the main namespace. */
|
||||
- _dl_sort_maps (maps + (ns == LM_ID_BASE), nmaps - (ns == LM_ID_BASE),
|
||||
- NULL, true);
|
||||
+ _dl_sort_maps (maps, nmaps, (ns == LM_ID_BASE), true);
|
||||
|
||||
/* We do not rely on the linked list of loaded object anymore
|
||||
from this point on. We have our own list here (maps). The
|
||||
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||
index b2a01ede627be1e9..398a08f28c4d9ff1 100644
|
||||
--- a/elf/dl-sort-maps.c
|
||||
+++ b/elf/dl-sort-maps.c
|
||||
@@ -16,16 +16,24 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <assert.h>
|
||||
#include <ldsodefs.h>
|
||||
+#include <elf/dl-tunables.h>
|
||||
|
||||
+/* Note: this is the older, "original" sorting algorithm, being used as
|
||||
+ default up to 2.35.
|
||||
|
||||
-/* Sort array MAPS according to dependencies of the contained objects.
|
||||
- Array USED, if non-NULL, is permutated along MAPS. If FOR_FINI this is
|
||||
- called for finishing an object. */
|
||||
-void
|
||||
-_dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
|
||||
- bool for_fini)
|
||||
+ Sort array MAPS according to dependencies of the contained objects.
|
||||
+ If FOR_FINI is true, this is called for finishing an object. */
|
||||
+static void
|
||||
+_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
|
||||
+ unsigned int skip, bool for_fini)
|
||||
{
|
||||
+ /* Allows caller to do the common optimization of skipping the first map,
|
||||
+ usually the main binary. */
|
||||
+ maps += skip;
|
||||
+ nmaps -= skip;
|
||||
+
|
||||
/* A list of one element need not be sorted. */
|
||||
if (nmaps <= 1)
|
||||
return;
|
||||
@@ -66,14 +74,6 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
|
||||
(k - i) * sizeof (maps[0]));
|
||||
maps[k] = thisp;
|
||||
|
||||
- if (used != NULL)
|
||||
- {
|
||||
- char here_used = used[i];
|
||||
- memmove (&used[i], &used[i + 1],
|
||||
- (k - i) * sizeof (used[0]));
|
||||
- used[k] = here_used;
|
||||
- }
|
||||
-
|
||||
if (seen[i + 1] > nmaps - i)
|
||||
{
|
||||
++i;
|
||||
@@ -120,3 +120,183 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
|
||||
next:;
|
||||
}
|
||||
}
|
||||
+
|
||||
+#if !HAVE_TUNABLES
|
||||
+/* In this case, just default to the original algorithm. */
|
||||
+strong_alias (_dl_sort_maps_original, _dl_sort_maps);
|
||||
+#else
|
||||
+
|
||||
+/* We use a recursive function due to its better clarity and ease of
|
||||
+ implementation, as well as faster execution speed. We already use
|
||||
+ alloca() for list allocation during the breadth-first search of
|
||||
+ dependencies in _dl_map_object_deps(), and this should be on the
|
||||
+ same order of worst-case stack usage.
|
||||
+
|
||||
+ Note: the '*rpo' parameter is supposed to point to one past the
|
||||
+ last element of the array where we save the sort results, and is
|
||||
+ decremented before storing the current map at each level. */
|
||||
+
|
||||
+static void
|
||||
+dfs_traversal (struct link_map ***rpo, struct link_map *map,
|
||||
+ bool *do_reldeps)
|
||||
+{
|
||||
+ if (map->l_visited)
|
||||
+ return;
|
||||
+
|
||||
+ map->l_visited = 1;
|
||||
+
|
||||
+ if (map->l_initfini)
|
||||
+ {
|
||||
+ for (int i = 0; map->l_initfini[i] != NULL; i++)
|
||||
+ {
|
||||
+ struct link_map *dep = map->l_initfini[i];
|
||||
+ if (dep->l_visited == 0
|
||||
+ && dep->l_main_map == 0)
|
||||
+ dfs_traversal (rpo, dep, do_reldeps);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (__glibc_unlikely (do_reldeps != NULL && map->l_reldeps != NULL))
|
||||
+ {
|
||||
+ /* Indicate that we encountered relocation dependencies during
|
||||
+ traversal. */
|
||||
+ *do_reldeps = true;
|
||||
+
|
||||
+ for (int m = map->l_reldeps->act - 1; m >= 0; m--)
|
||||
+ {
|
||||
+ struct link_map *dep = map->l_reldeps->list[m];
|
||||
+ if (dep->l_visited == 0
|
||||
+ && dep->l_main_map == 0)
|
||||
+ dfs_traversal (rpo, dep, do_reldeps);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *rpo -= 1;
|
||||
+ **rpo = map;
|
||||
+}
|
||||
+
|
||||
+/* Topologically sort array MAPS according to dependencies of the contained
|
||||
+ objects. */
|
||||
+
|
||||
+static void
|
||||
+_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
+ unsigned int skip __attribute__ ((unused)), bool for_fini)
|
||||
+{
|
||||
+ for (int i = nmaps - 1; i >= 0; i--)
|
||||
+ maps[i]->l_visited = 0;
|
||||
+
|
||||
+ /* We apply DFS traversal for each of maps[i] until the whole total order
|
||||
+ is found and we're at the start of the Reverse-Postorder (RPO) sequence,
|
||||
+ which is a topological sort.
|
||||
+
|
||||
+ We go from maps[nmaps - 1] backwards towards maps[0] at this level.
|
||||
+ Due to the breadth-first search (BFS) ordering we receive, going
|
||||
+ backwards usually gives a more shallow depth-first recursion depth,
|
||||
+ adding more stack usage safety. Also, combined with the natural
|
||||
+ processing order of l_initfini[] at each node during DFS, this maintains
|
||||
+ an ordering closer to the original link ordering in the sorting results
|
||||
+ under most simpler cases.
|
||||
+
|
||||
+ Another reason we order the top level backwards, it that maps[0] is
|
||||
+ usually exactly the main object of which we're in the midst of
|
||||
+ _dl_map_object_deps() processing, and maps[0]->l_initfini[] is still
|
||||
+ blank. If we start the traversal from maps[0], since having no
|
||||
+ dependencies yet filled in, maps[0] will always be immediately
|
||||
+ incorrectly placed at the last place in the order (first in reverse).
|
||||
+ Adjusting the order so that maps[0] is last traversed naturally avoids
|
||||
+ this problem.
|
||||
+
|
||||
+ Further, the old "optimization" of skipping the main object at maps[0]
|
||||
+ from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general
|
||||
+ no longer valid, since traversing along object dependency-links
|
||||
+ may "find" the main object even when it is not included in the initial
|
||||
+ order (e.g. a dlopen()'ed shared object can have circular dependencies
|
||||
+ linked back to itself). In such a case, traversing N-1 objects will
|
||||
+ create a N-object result, and raise problems.
|
||||
+
|
||||
+ To summarize, just passing in the full list, and iterating from back
|
||||
+ to front makes things much more straightforward. */
|
||||
+
|
||||
+ /* Array to hold RPO sorting results, before we copy back to maps[]. */
|
||||
+ struct link_map *rpo[nmaps];
|
||||
+
|
||||
+ /* The 'head' position during each DFS iteration. Note that we start at
|
||||
+ one past the last element due to first-decrement-then-store (see the
|
||||
+ bottom of above dfs_traversal() routine). */
|
||||
+ struct link_map **rpo_head = &rpo[nmaps];
|
||||
+
|
||||
+ bool do_reldeps = false;
|
||||
+ bool *do_reldeps_ref = (for_fini ? &do_reldeps : NULL);
|
||||
+
|
||||
+ for (int i = nmaps - 1; i >= 0; i--)
|
||||
+ {
|
||||
+ dfs_traversal (&rpo_head, maps[i], do_reldeps_ref);
|
||||
+
|
||||
+ /* We can break early if all objects are already placed. */
|
||||
+ if (rpo_head == rpo)
|
||||
+ goto end;
|
||||
+ }
|
||||
+ assert (rpo_head == rpo);
|
||||
+
|
||||
+ end:
|
||||
+ /* Here we may do a second pass of sorting, using only l_initfini[]
|
||||
+ static dependency links. This is avoided if !FOR_FINI or if we didn't
|
||||
+ find any reldeps in the first DFS traversal.
|
||||
+
|
||||
+ The reason we do this is: while it is unspecified how circular
|
||||
+ dependencies should be handled, the presumed reasonable behavior is to
|
||||
+ have destructors to respect static dependency links as much as possible,
|
||||
+ overriding reldeps if needed. And the first sorting pass, which takes
|
||||
+ l_initfini/l_reldeps links equally, may not preserve this priority.
|
||||
+
|
||||
+ Hence we do a 2nd sorting pass, taking only DT_NEEDED links into account
|
||||
+ (see how the do_reldeps argument to dfs_traversal() is NULL below). */
|
||||
+ if (do_reldeps)
|
||||
+ {
|
||||
+ for (int i = nmaps - 1; i >= 0; i--)
|
||||
+ rpo[i]->l_visited = 0;
|
||||
+
|
||||
+ struct link_map **maps_head = &maps[nmaps];
|
||||
+ for (int i = nmaps - 1; i >= 0; i--)
|
||||
+ {
|
||||
+ dfs_traversal (&maps_head, rpo[i], NULL);
|
||||
+
|
||||
+ /* We can break early if all objects are already placed.
|
||||
+ The below memcpy is not needed in the do_reldeps case here,
|
||||
+ since we wrote back to maps[] during DFS traversal. */
|
||||
+ if (maps_head == maps)
|
||||
+ return;
|
||||
+ }
|
||||
+ assert (maps_head == maps);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+_dl_sort_maps_init (void)
|
||||
+{
|
||||
+ int32_t algorithm = TUNABLE_GET (glibc, rtld, dynamic_sort, int32_t, NULL);
|
||||
+ GLRO(dl_dso_sort_algo) = algorithm == 1 ? dso_sort_algorithm_original
|
||||
+ : dso_sort_algorithm_dfs;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+_dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
+ unsigned int skip, bool for_fini)
|
||||
+{
|
||||
+ /* It can be tempting to use a static function pointer to store and call
|
||||
+ the current selected sorting algorithm routine, but experimentation
|
||||
+ shows that current processors still do not handle indirect branches
|
||||
+ that efficiently, plus a static function pointer will involve
|
||||
+ PTR_MANGLE/DEMANGLE, further impairing performance of small, common
|
||||
+ input cases. A simple if-case with direct function calls appears to
|
||||
+ be the fastest. */
|
||||
+ if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original))
|
||||
+ _dl_sort_maps_original (maps, nmaps, skip, for_fini);
|
||||
+ else
|
||||
+ _dl_sort_maps_dfs (maps, nmaps, skip, for_fini);
|
||||
+}
|
||||
+
|
||||
+#endif /* HAVE_TUNABLES. */
|
||||
diff --git a/elf/dl-support.c b/elf/dl-support.c
|
||||
index e9943e889ef447ad..ae03aec9764e29d3 100644
|
||||
--- a/elf/dl-support.c
|
||||
+++ b/elf/dl-support.c
|
||||
@@ -155,6 +155,8 @@ size_t _dl_phnum;
|
||||
uint64_t _dl_hwcap __attribute__ ((nocommon));
|
||||
uint64_t _dl_hwcap2 __attribute__ ((nocommon));
|
||||
|
||||
+enum dso_sort_algorithm _dl_dso_sort_algo;
|
||||
+
|
||||
/* The value of the FPU control word the kernel will preset in hardware. */
|
||||
fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
|
||||
|
||||
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
|
||||
index 998c5d52bcab8193..4e8a986541fc4c09 100644
|
||||
--- a/elf/dl-sysdep.c
|
||||
+++ b/elf/dl-sysdep.c
|
||||
@@ -223,6 +223,9 @@ _dl_sysdep_start (void **start_argptr,
|
||||
|
||||
__tunables_init (_environ);
|
||||
|
||||
+ /* Initialize DSO sorting algorithm after tunables. */
|
||||
+ _dl_sort_maps_init ();
|
||||
+
|
||||
#ifdef DL_SYSDEP_INIT
|
||||
DL_SYSDEP_INIT;
|
||||
#endif
|
||||
diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
|
||||
index 6408a8e5ae92d2c6..54ef2a921310b229 100644
|
||||
--- a/elf/dl-tunables.list
|
||||
+++ b/elf/dl-tunables.list
|
||||
@@ -140,4 +140,13 @@ glibc {
|
||||
default: 512
|
||||
}
|
||||
}
|
||||
+
|
||||
+ rtld {
|
||||
+ dynamic_sort {
|
||||
+ type: INT_32
|
||||
+ minval: 1
|
||||
+ maxval: 2
|
||||
+ default: 1
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
|
||||
index 873ddf55d91155c6..5f7f18ef270bc12d 100644
|
||||
--- a/elf/dso-sort-tests-1.def
|
||||
+++ b/elf/dso-sort-tests-1.def
|
||||
@@ -62,5 +62,5 @@ output: b>a>{}<a<b
|
||||
# The below expected outputs are what the two algorithms currently produce
|
||||
# respectively, for regression testing purposes.
|
||||
tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
|
||||
-xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
|
||||
+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];}
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index b47e84ca2fb6f03c..cd2cc4024a3581c2 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -1453,6 +1453,9 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
main_map->l_name = (char *) "";
|
||||
*user_entry = main_map->l_entry;
|
||||
|
||||
+ /* Set bit indicating this is the main program map. */
|
||||
+ main_map->l_main_map = 1;
|
||||
+
|
||||
#ifdef HAVE_AUX_VECTOR
|
||||
/* Adjust the on-stack auxiliary vector so that it looks like the
|
||||
binary was executed directly. */
|
||||
diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
|
||||
index 4f3f7ee4e30a2b42..118afc271057afd4 100644
|
||||
--- a/elf/tst-rtld-list-tunables.exp
|
||||
+++ b/elf/tst-rtld-list-tunables.exp
|
||||
@@ -10,5 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
+glibc.rtld.dynamic_sort: 1 (min: 1, max: 2)
|
||||
glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
|
||||
glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+)
|
||||
diff --git a/include/link.h b/include/link.h
|
||||
index dd491989beb41353..041ff5f753a9ee11 100644
|
||||
--- a/include/link.h
|
||||
+++ b/include/link.h
|
||||
@@ -181,6 +181,11 @@ struct link_map
|
||||
unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
|
||||
unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
|
||||
unsigned int l_reserved:2; /* Reserved for internal use. */
|
||||
+ unsigned int l_main_map:1; /* Nonzero for the map of the main program. */
|
||||
+ unsigned int l_visited:1; /* Used internally for map dependency
|
||||
+ graph traversal. */
|
||||
+ unsigned int l_map_used:1; /* These two bits are used during traversal */
|
||||
+ unsigned int l_map_done:1; /* of maps in _dl_close_worker. */
|
||||
unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed
|
||||
to by `l_phdr' is allocated. */
|
||||
unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in
|
||||
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||
index 43272cf885d1e3e6..c3f96cdc85208926 100644
|
||||
--- a/manual/tunables.texi
|
||||
+++ b/manual/tunables.texi
|
||||
@@ -303,6 +303,17 @@ changed once allocated at process startup. The default allocation of
|
||||
optional static TLS is 512 bytes and is allocated in every thread.
|
||||
@end deftp
|
||||
|
||||
+@deftp Tunable glibc.rtld.dynamic_sort
|
||||
+Sets the algorithm to use for DSO sorting, valid values are @samp{1} and
|
||||
+@samp{2}. For value of @samp{1}, an older O(n^3) algorithm is used, which is
|
||||
+long time tested, but may have performance issues when dependencies between
|
||||
+shared objects contain cycles due to circular dependencies. When set to the
|
||||
+value of @samp{2}, a different algorithm is used, which implements a
|
||||
+topological sort through depth-first search, and does not exhibit the
|
||||
+performance issues of @samp{1}.
|
||||
+
|
||||
+The default value of this tunable is @samp{1}.
|
||||
+@end deftp
|
||||
|
||||
@node Elision Tunables
|
||||
@section Elision Tunables
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 5e56550a4d556fa7..9f09a4a280396659 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -240,6 +240,13 @@ enum allowmask
|
||||
};
|
||||
|
||||
|
||||
+/* DSO sort algorithm to use (check dl-sort-maps.c). */
|
||||
+enum dso_sort_algorithm
|
||||
+ {
|
||||
+ dso_sort_algorithm_original,
|
||||
+ dso_sort_algorithm_dfs
|
||||
+ };
|
||||
+
|
||||
struct audit_ifaces
|
||||
{
|
||||
void (*activity) (uintptr_t *, unsigned int);
|
||||
@@ -633,6 +640,8 @@ struct rtld_global_ro
|
||||
platforms. */
|
||||
EXTERN uint64_t _dl_hwcap2;
|
||||
|
||||
+ EXTERN enum dso_sort_algorithm _dl_dso_sort_algo;
|
||||
+
|
||||
#ifdef SHARED
|
||||
/* We add a function table to _rtld_global which is then used to
|
||||
call the function instead of going through the PLT. The result
|
||||
@@ -1049,7 +1058,7 @@ extern void _dl_fini (void) attribute_hidden;
|
||||
|
||||
/* Sort array MAPS according to dependencies of the contained objects. */
|
||||
extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
- char *used, bool for_fini) attribute_hidden;
|
||||
+ unsigned int skip, bool for_fini) attribute_hidden;
|
||||
|
||||
/* The dynamic linker calls this function before and having changing
|
||||
any shared object mappings. The `r_state' member of `struct r_debug'
|
||||
@@ -1167,6 +1176,9 @@ extern struct link_map * _dl_get_dl_main_map (void)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+/* Initialize the DSO sort algorithm to use. */
|
||||
+extern void _dl_sort_maps_init (void) attribute_hidden;
|
||||
+
|
||||
/* Initialization of libpthread for statically linked applications.
|
||||
If libpthread is not linked in, this is an empty function. */
|
||||
void __pthread_initialize_minimal (void) weak_function;
|
|
@ -1,25 +0,0 @@
|
|||
commit d3bf2f5927d51258a51ac7fde04f4805f8ee294a
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Nov 3 09:19:30 2021 -0300
|
||||
|
||||
elf: Do not run DSO sorting if tunables is not enabled
|
||||
|
||||
Since the argorithm selection requires tunables.
|
||||
|
||||
Checked on x86_64-linux-gnu with --enable-tunables=no.
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index e92f62f279566684..3b5e1f59e6696a2b 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -998,8 +998,10 @@ include $(objpfx)$(1).generated-makefile
|
||||
endef
|
||||
|
||||
# Generate from each testcase description file
|
||||
+ifeq (yes,$(have-tunables))
|
||||
$(eval $(call include_dsosort_tests,dso-sort-tests-1.def))
|
||||
$(eval $(call include_dsosort_tests,dso-sort-tests-2.def))
|
||||
+endif
|
||||
|
||||
check-abi: $(objpfx)check-abi-ld.out
|
||||
tests-special += $(objpfx)check-abi-ld.out
|
|
@ -1,45 +0,0 @@
|
|||
commit 1f67d8286b5da9266a138198ef1f15c27cbb0010
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Mon Nov 15 16:28:39 2021 -0800
|
||||
|
||||
elf: Use a temporary file to generate Makefile fragments [BZ #28550]
|
||||
|
||||
1. Use a temporary file to generate Makefile fragments for DSO sorting
|
||||
tests and use -include on them.
|
||||
2. Add Makefile fragments to postclean-generated so that a "make clean"
|
||||
removes the autogenerated fragments and a subsequent "make" regenerates
|
||||
them.
|
||||
|
||||
This partially fixes BZ #28550.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 3b5e1f59e6696a2b..22a8060f7d3bb1a1 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -986,6 +986,7 @@ tests-special += \
|
||||
# tests-special
|
||||
endif
|
||||
|
||||
+ifndef avoid-generated
|
||||
# DSO sorting tests:
|
||||
# The dso-ordering-test.py script generates testcase source files in $(objpfx),
|
||||
# creating a $(objpfx)<testcase-name>-dir for each testcase, and creates a
|
||||
@@ -993,9 +994,14 @@ endif
|
||||
define include_dsosort_tests
|
||||
$(objpfx)$(1).generated-makefile: $(1)
|
||||
$(PYTHON) $(..)scripts/dso-ordering-test.py \
|
||||
- --description-file $$< --objpfx $(objpfx) --output-makefile $$@
|
||||
-include $(objpfx)$(1).generated-makefile
|
||||
+ --description-file $$< --objpfx $(objpfx) --output-makefile $$@T
|
||||
+ mv $$@T $$@
|
||||
+-include $(objpfx)$(1).generated-makefile
|
||||
endef
|
||||
+endif
|
||||
+
|
||||
+postclean-generated += $(objpfx)/dso-sort-tests-2.generated-makefile \
|
||||
+ $(objpfx)/dso-sort-tests-2.generated-makefile
|
||||
|
||||
# Generate from each testcase description file
|
||||
ifeq (yes,$(have-tunables))
|
|
@ -1,49 +0,0 @@
|
|||
commit 0884724a95b60452ad483dbe086d237d02ba624d
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Dec 14 12:37:44 2021 +0100
|
||||
|
||||
elf: Use new dependency sorting algorithm by default
|
||||
|
||||
The default has to change eventually, and there are no known failures
|
||||
that require a delay.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
|
||||
index 54ef2a921310b229..f11ca5b3e8b09b43 100644
|
||||
--- a/elf/dl-tunables.list
|
||||
+++ b/elf/dl-tunables.list
|
||||
@@ -146,7 +146,7 @@ glibc {
|
||||
type: INT_32
|
||||
minval: 1
|
||||
maxval: 2
|
||||
- default: 1
|
||||
+ default: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
|
||||
index 118afc271057afd4..478ee8ab091685eb 100644
|
||||
--- a/elf/tst-rtld-list-tunables.exp
|
||||
+++ b/elf/tst-rtld-list-tunables.exp
|
||||
@@ -10,6 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
-glibc.rtld.dynamic_sort: 1 (min: 1, max: 2)
|
||||
+glibc.rtld.dynamic_sort: 2 (min: 1, max: 2)
|
||||
glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
|
||||
glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+)
|
||||
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||
index c3f96cdc85208926..7b70e80391ee87f7 100644
|
||||
--- a/manual/tunables.texi
|
||||
+++ b/manual/tunables.texi
|
||||
@@ -312,7 +312,7 @@ value of @samp{2}, a different algorithm is used, which implements a
|
||||
topological sort through depth-first search, and does not exhibit the
|
||||
performance issues of @samp{1}.
|
||||
|
||||
-The default value of this tunable is @samp{1}.
|
||||
+The default value of this tunable is @samp{2}.
|
||||
@end deftp
|
||||
|
||||
@node Elision Tunables
|
|
@ -1,357 +0,0 @@
|
|||
commit 3a0588ae48fb35384a6bd33f9b66403badfa1262
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Tue Feb 8 15:22:49 2022 -0300
|
||||
|
||||
elf: Fix DFS sorting algorithm for LD_TRACE_LOADED_OBJECTS with missing libraries (BZ #28868)
|
||||
|
||||
On _dl_map_object the underlying file is not opened in trace mode
|
||||
(in other cases where the underlying file can't be opened,
|
||||
_dl_map_object quits with an error). If there any missing libraries
|
||||
being processed, they will not be considered on final nlist size
|
||||
passed on _dl_sort_maps later in the function. And it is then used by
|
||||
_dl_sort_maps_dfs on the stack allocated working maps:
|
||||
|
||||
222 /* Array to hold RPO sorting results, before we copy back to maps[]. */
|
||||
223 struct link_map *rpo[nmaps];
|
||||
224
|
||||
225 /* The 'head' position during each DFS iteration. Note that we start at
|
||||
226 one past the last element due to first-decrement-then-store (see the
|
||||
227 bottom of above dfs_traversal() routine). */
|
||||
228 struct link_map **rpo_head = &rpo[nmaps];
|
||||
|
||||
However while transversing the 'l_initfini' on dfs_traversal it will
|
||||
still consider the l_faked maps and thus update rpo more times than the
|
||||
allocated working 'rpo', overflowing the stack object.
|
||||
|
||||
As suggested in bugzilla, one option would be to avoid sorting the maps
|
||||
for trace mode. However I think ignoring l_faked object does make
|
||||
sense (there is one less constraint to call the sorting function), it
|
||||
allows a slight less stack usage for trace, and it is slight simpler
|
||||
solution.
|
||||
|
||||
The tests does trigger the stack overflow, however I tried to make
|
||||
it more generic to check different scenarios or missing objects.
|
||||
|
||||
Checked on x86_64-linux-gnu.
|
||||
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile
|
||||
(differences in backported tests)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 22a8060f7d3bb1a1..634c3113227d64a6 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -584,6 +584,11 @@ modules-names = \
|
||||
libmarkermod5-3 \
|
||||
libmarkermod5-4 \
|
||||
libmarkermod5-5 \
|
||||
+ libtracemod1-1 \
|
||||
+ libtracemod2-1 \
|
||||
+ libtracemod3-1 \
|
||||
+ libtracemod4-1 \
|
||||
+ libtracemod5-1 \
|
||||
ltglobmod1 \
|
||||
ltglobmod2 \
|
||||
neededobj1 \
|
||||
@@ -983,6 +988,11 @@ tests-special += \
|
||||
$(objpfx)tst-initorder2-cmp.out \
|
||||
$(objpfx)tst-unused-dep-cmp.out \
|
||||
$(objpfx)tst-unused-dep.out \
|
||||
+ $(objpfx)tst-trace1.out \
|
||||
+ $(objpfx)tst-trace2.out \
|
||||
+ $(objpfx)tst-trace3.out \
|
||||
+ $(objpfx)tst-trace4.out \
|
||||
+ $(objpfx)tst-trace5.out \
|
||||
# tests-special
|
||||
endif
|
||||
|
||||
@@ -2619,6 +2629,51 @@ $(objpfx)tst-rtld-run-static.out: $(objpfx)/ldconfig
|
||||
|
||||
$(objpfx)tst-dlmopen-gethostbyname: $(libdl)
|
||||
$(objpfx)tst-dlmopen-gethostbyname.out: $(objpfx)tst-dlmopen-gethostbyname-mod.so
|
||||
+
|
||||
+LDFLAGS-libtracemod1-1.so += -Wl,-soname,libtracemod1.so
|
||||
+LDFLAGS-libtracemod2-1.so += -Wl,-soname,libtracemod2.so
|
||||
+LDFLAGS-libtracemod3-1.so += -Wl,-soname,libtracemod3.so
|
||||
+LDFLAGS-libtracemod4-1.so += -Wl,-soname,libtracemod4.so
|
||||
+LDFLAGS-libtracemod5-1.so += -Wl,-soname,libtracemod5.so
|
||||
+
|
||||
+$(objpfx)libtracemod1-1.so: $(objpfx)libtracemod2-1.so \
|
||||
+ $(objpfx)libtracemod3-1.so
|
||||
+$(objpfx)libtracemod2-1.so: $(objpfx)libtracemod4-1.so \
|
||||
+ $(objpfx)libtracemod5-1.so
|
||||
+
|
||||
+define libtracemod-x
|
||||
+$(objpfx)libtracemod$(1)/libtracemod$(1).so: $(objpfx)libtracemod$(1)-1.so
|
||||
+ $$(make-target-directory)
|
||||
+ cp $$< $$@
|
||||
+endef
|
||||
+libtracemod-suffixes = 1 2 3 4 5
|
||||
+$(foreach i,$(libtracemod-suffixes), $(eval $(call libtracemod-x,$(i))))
|
||||
+
|
||||
+define tst-trace-skeleton
|
||||
+$(objpfx)tst-trace$(1).out: $(objpfx)libtracemod1/libtracemod1.so \
|
||||
+ $(objpfx)libtracemod2/libtracemod2.so \
|
||||
+ $(objpfx)libtracemod3/libtracemod3.so \
|
||||
+ $(objpfx)libtracemod4/libtracemod4.so \
|
||||
+ $(objpfx)libtracemod5/libtracemod5.so \
|
||||
+ $(..)scripts/tst-ld-trace.py \
|
||||
+ tst-trace$(1).exp
|
||||
+ ${ $(PYTHON) $(..)scripts/tst-ld-trace.py \
|
||||
+ "$(test-wrapper-env) $(elf-objpfx)$(rtld-installed-name) \
|
||||
+ --library-path $(common-objpfx):$(strip $(2)) \
|
||||
+ $(objpfx)libtracemod1/libtracemod1.so" tst-trace$(1).exp \
|
||||
+ } > $$@; $$(evaluate-test)
|
||||
+endef
|
||||
+
|
||||
+$(eval $(call tst-trace-skeleton,1,))
|
||||
+$(eval $(call tst-trace-skeleton,2,\
|
||||
+ $(objpfx)libtracemod2))
|
||||
+$(eval $(call tst-trace-skeleton,3,\
|
||||
+ $(objpfx)libtracemod2:$(objpfx)libtracemod3))
|
||||
+$(eval $(call tst-trace-skeleton,4,\
|
||||
+ $(objpfx)libtracemod2:$(objpfx)libtracemod3:$(objpfx)libtracemod4))
|
||||
+$(eval $(call tst-trace-skeleton,5,\
|
||||
+ $(objpfx)libtracemod2:$(objpfx)libtracemod3:$(objpfx)libtracemod4:$(objpfx)libtracemod5))
|
||||
+
|
||||
$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||
$(objpfx)tst-audit-tlsdesc-mod2.so \
|
||||
$(shared-thread-library)
|
||||
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
|
||||
index 9365d54c8e03e5f4..9ff589c8562b2dd1 100644
|
||||
--- a/elf/dl-deps.c
|
||||
+++ b/elf/dl-deps.c
|
||||
@@ -489,6 +489,8 @@ _dl_map_object_deps (struct link_map *map,
|
||||
|
||||
for (nlist = 0, runp = known; runp; runp = runp->next)
|
||||
{
|
||||
+ /* _dl_sort_maps ignores l_faked object, so it is safe to not consider
|
||||
+ them for nlist. */
|
||||
if (__builtin_expect (trace_mode, 0) && runp->map->l_faked)
|
||||
/* This can happen when we trace the loading. */
|
||||
--map->l_searchlist.r_nlist;
|
||||
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||
index 398a08f28c4d9ff1..99354dc08a010dd3 100644
|
||||
--- a/elf/dl-sort-maps.c
|
||||
+++ b/elf/dl-sort-maps.c
|
||||
@@ -140,7 +140,9 @@ static void
|
||||
dfs_traversal (struct link_map ***rpo, struct link_map *map,
|
||||
bool *do_reldeps)
|
||||
{
|
||||
- if (map->l_visited)
|
||||
+ /* _dl_map_object_deps ignores l_faked objects when calculating the
|
||||
+ number of maps before calling _dl_sort_maps, ignore them as well. */
|
||||
+ if (map->l_visited || map->l_faked)
|
||||
return;
|
||||
|
||||
map->l_visited = 1;
|
||||
diff --git a/elf/libtracemod1-1.c b/elf/libtracemod1-1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7c89c9a5a40b9668
|
||||
--- /dev/null
|
||||
+++ b/elf/libtracemod1-1.c
|
||||
@@ -0,0 +1 @@
|
||||
+/* Empty */
|
||||
diff --git a/elf/libtracemod2-1.c b/elf/libtracemod2-1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7c89c9a5a40b9668
|
||||
--- /dev/null
|
||||
+++ b/elf/libtracemod2-1.c
|
||||
@@ -0,0 +1 @@
|
||||
+/* Empty */
|
||||
diff --git a/elf/libtracemod3-1.c b/elf/libtracemod3-1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7c89c9a5a40b9668
|
||||
--- /dev/null
|
||||
+++ b/elf/libtracemod3-1.c
|
||||
@@ -0,0 +1 @@
|
||||
+/* Empty */
|
||||
diff --git a/elf/libtracemod4-1.c b/elf/libtracemod4-1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7c89c9a5a40b9668
|
||||
--- /dev/null
|
||||
+++ b/elf/libtracemod4-1.c
|
||||
@@ -0,0 +1 @@
|
||||
+/* Empty */
|
||||
diff --git a/elf/libtracemod5-1.c b/elf/libtracemod5-1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7c89c9a5a40b9668
|
||||
--- /dev/null
|
||||
+++ b/elf/libtracemod5-1.c
|
||||
@@ -0,0 +1 @@
|
||||
+/* Empty */
|
||||
diff --git a/elf/tst-trace1.exp b/elf/tst-trace1.exp
|
||||
new file mode 100644
|
||||
index 0000000000000000..4a6f5211a68fe2c8
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-trace1.exp
|
||||
@@ -0,0 +1,4 @@
|
||||
+ld 1
|
||||
+libc 1
|
||||
+libtracemod2.so 0
|
||||
+libtracemod3.so 0
|
||||
diff --git a/elf/tst-trace2.exp b/elf/tst-trace2.exp
|
||||
new file mode 100644
|
||||
index 0000000000000000..e13506e2eb9aeca2
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-trace2.exp
|
||||
@@ -0,0 +1,6 @@
|
||||
+ld 1
|
||||
+libc 1
|
||||
+libtracemod2.so 1
|
||||
+libtracemod3.so 0
|
||||
+libtracemod4.so 0
|
||||
+libtracemod5.so 0
|
||||
diff --git a/elf/tst-trace3.exp b/elf/tst-trace3.exp
|
||||
new file mode 100644
|
||||
index 0000000000000000..e574549d12a53d72
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-trace3.exp
|
||||
@@ -0,0 +1,6 @@
|
||||
+ld 1
|
||||
+libc 1
|
||||
+libtracemod2.so 1
|
||||
+libtracemod3.so 1
|
||||
+libtracemod4.so 0
|
||||
+libtracemod5.so 0
|
||||
diff --git a/elf/tst-trace4.exp b/elf/tst-trace4.exp
|
||||
new file mode 100644
|
||||
index 0000000000000000..31ca97b35bde0009
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-trace4.exp
|
||||
@@ -0,0 +1,6 @@
|
||||
+ld 1
|
||||
+libc 1
|
||||
+libtracemod2.so 1
|
||||
+libtracemod3.so 1
|
||||
+libtracemod4.so 1
|
||||
+libtracemod5.so 0
|
||||
diff --git a/elf/tst-trace5.exp b/elf/tst-trace5.exp
|
||||
new file mode 100644
|
||||
index 0000000000000000..5d7d95372656396f
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-trace5.exp
|
||||
@@ -0,0 +1,6 @@
|
||||
+ld 1
|
||||
+libc 1
|
||||
+libtracemod2.so 1
|
||||
+libtracemod3.so 1
|
||||
+libtracemod4.so 1
|
||||
+libtracemod5.so 1
|
||||
diff --git a/scripts/tst-ld-trace.py b/scripts/tst-ld-trace.py
|
||||
new file mode 100755
|
||||
index 0000000000000000..f5a402800377f44b
|
||||
--- /dev/null
|
||||
+++ b/scripts/tst-ld-trace.py
|
||||
@@ -0,0 +1,108 @@
|
||||
+#!/usr/bin/python3
|
||||
+# Dump the output of LD_TRACE_LOADED_OBJECTS in architecture neutral format.
|
||||
+# Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+# Copyright The GNU Toolchain Authors.
|
||||
+# This file is part of the GNU C Library.
|
||||
+#
|
||||
+# The GNU C Library is free software; you can redistribute it and/or
|
||||
+# modify it under the terms of the GNU Lesser General Public
|
||||
+# License as published by the Free Software Foundation; either
|
||||
+# version 2.1 of the License, or (at your option) any later version.
|
||||
+#
|
||||
+# The GNU C Library is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+# Lesser General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU Lesser General Public
|
||||
+# License along with the GNU C Library; if not, see
|
||||
+# <https://www.gnu.org/licenses/>.
|
||||
+
|
||||
+import argparse
|
||||
+import os
|
||||
+import subprocess
|
||||
+import sys
|
||||
+
|
||||
+try:
|
||||
+ subprocess.run
|
||||
+except:
|
||||
+ class _CompletedProcess:
|
||||
+ def __init__(self, args, returncode, stdout=None, stderr=None):
|
||||
+ self.args = args
|
||||
+ self.returncode = returncode
|
||||
+ self.stdout = stdout
|
||||
+ self.stderr = stderr
|
||||
+
|
||||
+ def _run(*popenargs, input=None, timeout=None, check=False, **kwargs):
|
||||
+ assert(timeout is None)
|
||||
+ with subprocess.Popen(*popenargs, **kwargs) as process:
|
||||
+ try:
|
||||
+ stdout, stderr = process.communicate(input)
|
||||
+ except:
|
||||
+ process.kill()
|
||||
+ process.wait()
|
||||
+ raise
|
||||
+ returncode = process.poll()
|
||||
+ if check and returncode:
|
||||
+ raise subprocess.CalledProcessError(returncode, popenargs)
|
||||
+ return _CompletedProcess(popenargs, returncode, stdout, stderr)
|
||||
+
|
||||
+ subprocess.run = _run
|
||||
+
|
||||
+def is_vdso(lib):
|
||||
+ return lib.startswith('linux-gate') or lib.startswith('linux-vdso')
|
||||
+
|
||||
+
|
||||
+def parse_trace(cmd, fref):
|
||||
+ new_env = os.environ.copy()
|
||||
+ new_env['LD_TRACE_LOADED_OBJECTS'] = '1'
|
||||
+ trace_out = subprocess.run(cmd, stdout=subprocess.PIPE, check=True,
|
||||
+ universal_newlines=True, env=new_env).stdout
|
||||
+ trace = []
|
||||
+ for line in trace_out.splitlines():
|
||||
+ line = line.strip()
|
||||
+ if is_vdso(line):
|
||||
+ continue
|
||||
+ fields = line.split('=>' if '=>' in line else ' ')
|
||||
+ lib = os.path.basename(fields[0].strip())
|
||||
+ if lib.startswith('ld'):
|
||||
+ lib = 'ld'
|
||||
+ elif lib.startswith('libc'):
|
||||
+ lib = 'libc'
|
||||
+ found = 1 if fields[1].strip() != 'not found' else 0
|
||||
+ trace += ['{} {}'.format(lib, found)]
|
||||
+ trace = sorted(trace)
|
||||
+
|
||||
+ reference = sorted(line.replace('\n','') for line in fref.readlines())
|
||||
+
|
||||
+ ret = 0 if trace == reference else 1
|
||||
+ if ret != 0:
|
||||
+ for i in reference:
|
||||
+ if i not in trace:
|
||||
+ print("Only in {}: {}".format(fref.name, i))
|
||||
+ for i in trace:
|
||||
+ if i not in reference:
|
||||
+ print("Only in trace: {}".format(i))
|
||||
+
|
||||
+ sys.exit(ret)
|
||||
+
|
||||
+
|
||||
+def get_parser():
|
||||
+ parser = argparse.ArgumentParser(description=__doc__)
|
||||
+ parser.add_argument('command',
|
||||
+ help='comand to run')
|
||||
+ parser.add_argument('reference',
|
||||
+ help='reference file to compare')
|
||||
+ return parser
|
||||
+
|
||||
+
|
||||
+def main(argv):
|
||||
+ parser = get_parser()
|
||||
+ opts = parser.parse_args(argv)
|
||||
+ with open(opts.reference, 'r') as fref:
|
||||
+ # Remove the initial 'env' command.
|
||||
+ parse_trace(opts.command.split()[1:], fref)
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ main(sys.argv[1:])
|
|
@ -1,36 +0,0 @@
|
|||
commit a2211c76c3b994099fd58a06d6072d7495d699cd
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Mar 18 18:18:35 2022 +0100
|
||||
|
||||
scripts/dso-ordering-test.py: Fix C&P error in * callrefs processing
|
||||
|
||||
The elf/dso-sort-tests-src subdirectory is not changed by this commit,
|
||||
so it seems that the cut-and-paste error was not material.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
|
||||
index bde0406be9da14fc..ee476c810c76f1b0 100644
|
||||
--- a/scripts/dso-ordering-test.py
|
||||
+++ b/scripts/dso-ordering-test.py
|
||||
@@ -551,17 +551,17 @@ def process_testcase(t):
|
||||
if obj in t.deps:
|
||||
deps = t.deps[obj]
|
||||
if '*' in deps:
|
||||
- t.deps[obj].remove('*')
|
||||
+ deps.remove('*')
|
||||
t.add_deps([obj], non_dep_tgt_objs)
|
||||
if obj in t.callrefs:
|
||||
deps = t.callrefs[obj]
|
||||
if '*' in deps:
|
||||
- t.deps[obj].remove('*')
|
||||
+ deps.remove('*')
|
||||
t.add_callrefs([obj], non_dep_tgt_objs)
|
||||
if "#" in t.deps:
|
||||
deps = t.deps["#"]
|
||||
if '*' in deps:
|
||||
- t.deps["#"].remove('*')
|
||||
+ deps.remove('*')
|
||||
t.add_deps(["#"], non_dep_tgt_objs)
|
||||
|
||||
# If no main program was specified in dependency description, make a
|
|
@ -1,37 +0,0 @@
|
|||
commit 183d99737298bb3200f0610fdcd1c7549c8ed560
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 6 07:38:10 2022 +0200
|
||||
|
||||
scripts/dso-ordering-test.py: Generate program run-time dependencies
|
||||
|
||||
The main program needs to depend on all shared objects, even objects
|
||||
that have link-time dependencies among shared objects. Filtering
|
||||
out shared objects that already have an link-time dependencies is not
|
||||
necessary here; make will do this automatically.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
|
||||
index ee476c810c76f1b0..43b5ec4d920ad6a3 100644
|
||||
--- a/scripts/dso-ordering-test.py
|
||||
+++ b/scripts/dso-ordering-test.py
|
||||
@@ -707,13 +707,12 @@ def process_testcase(t):
|
||||
"\t$(compile.c) $(OUTPUT_OPTION)\n")
|
||||
makefile.write (rule)
|
||||
|
||||
- not_depended_objs = find_objs_not_depended_on(test_descr)
|
||||
- if not_depended_objs:
|
||||
- depstr = ""
|
||||
- for dep in not_depended_objs:
|
||||
- depstr += (" $(objpfx)" + test_subdir + "/"
|
||||
- + test_name + "-" + dep + ".so")
|
||||
- makefile.write("$(objpfx)%s.out:%s\n" % (base_test_name, depstr))
|
||||
+ # Ensure that all shared objects are built before running the
|
||||
+ # test, whether there link-time dependencies or not.
|
||||
+ depobjs = ["$(objpfx){}/{}-{}.so".format(test_subdir, test_name, dep)
|
||||
+ for dep in test_descr.objs]
|
||||
+ makefile.write("$(objpfx){}.out: {}\n".format(
|
||||
+ base_test_name, " ".join(depobjs)))
|
||||
|
||||
# Add main executable to test-srcs
|
||||
makefile.write("test-srcs += %s/%s\n" % (test_subdir, test_name))
|
|
@ -1,49 +0,0 @@
|
|||
Backport of this Fedora Rawhide commit but split out into a distinct
|
||||
patch.
|
||||
|
||||
commit 72195d44855ab96875f117acb75c37f98dcb26a9
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Thu Jun 6 23:58:21 2019 -0400
|
||||
|
||||
locale: Fix C.UTF-8 ranges.
|
||||
|
||||
The ellipsis range support only allows <Uxxxx> or <Uxxxxxxxx> as
|
||||
valid unicode code points, otherwise it treats it as a symbol and
|
||||
since we don't define the symbol the entire range is unused.
|
||||
|
||||
diff --git a/localedata/locales/C b/localedata/locales/C
|
||||
index b2c2d1dc417cde69..30d9563213b8cb0f 100644
|
||||
--- a/localedata/locales/C
|
||||
+++ b/localedata/locales/C
|
||||
@@ -43,21 +43,21 @@ order_start forward
|
||||
<U0000>
|
||||
..
|
||||
<UFFFF>
|
||||
-<U10000>
|
||||
+<U00010000>
|
||||
..
|
||||
-<U1FFFF>
|
||||
-<U20000>
|
||||
+<U0001FFFF>
|
||||
+<U00020000>
|
||||
..
|
||||
-<U2FFFF>
|
||||
-<UE0000>
|
||||
+<U0002FFFF>
|
||||
+<U000E0000>
|
||||
..
|
||||
-<UEFFFF>
|
||||
-<UF0000>
|
||||
+<U000EFFFF>
|
||||
+<U000F0000>
|
||||
..
|
||||
-<UFFFFF>
|
||||
-<U100000>
|
||||
+<U000FFFFF>
|
||||
+<U00100000>
|
||||
..
|
||||
-<U10FFFF>
|
||||
+<U0010FFFF>
|
||||
UNDEFINED
|
||||
order_end
|
||||
END LC_COLLATE
|
|
@ -1,185 +0,0 @@
|
|||
commit 96cd0558bcd69481ccc42e1b392f0c0b36fce2b0
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Nov 28 19:59:45 2018 +0100
|
||||
|
||||
support: Add signal support to support_capture_subprocess_check
|
||||
|
||||
Signal zero does not terminate a process, so it is safe to use negative
|
||||
values for signal numbers.
|
||||
|
||||
Adjust libio/tst-vtables-common.c to use this new functionality,
|
||||
instead of determining the termination status for a signal indirectly.
|
||||
|
||||
diff --git a/libio/tst-vtables-common.c b/libio/tst-vtables-common.c
|
||||
index 5e3101206919fa1b..85e246cd1131f8e8 100644
|
||||
--- a/libio/tst-vtables-common.c
|
||||
+++ b/libio/tst-vtables-common.c
|
||||
@@ -380,21 +380,6 @@ without_compatibility_fflush (void *closure)
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
-/* Exit status after abnormal termination. */
|
||||
-static int termination_status;
|
||||
-
|
||||
-static void
|
||||
-init_termination_status (void)
|
||||
-{
|
||||
- pid_t pid = xfork ();
|
||||
- if (pid == 0)
|
||||
- abort ();
|
||||
- xwaitpid (pid, &termination_status, 0);
|
||||
-
|
||||
- TEST_VERIFY (WIFSIGNALED (termination_status));
|
||||
- TEST_COMPARE (WTERMSIG (termination_status), SIGABRT);
|
||||
-}
|
||||
-
|
||||
static void
|
||||
check_for_termination (const char *name, void (*callback) (void *))
|
||||
{
|
||||
@@ -404,7 +389,7 @@ check_for_termination (const char *name, void (*callback) (void *))
|
||||
shared->calls = 0;
|
||||
struct support_capture_subprocess proc
|
||||
= support_capture_subprocess (callback, NULL);
|
||||
- support_capture_subprocess_check (&proc, name, termination_status,
|
||||
+ support_capture_subprocess_check (&proc, name, -SIGABRT,
|
||||
sc_allow_stderr);
|
||||
const char *message
|
||||
= "Fatal error: glibc detected an invalid stdio handle\n";
|
||||
@@ -491,7 +476,6 @@ run_tests (bool initially_disabled)
|
||||
|
||||
shared = support_shared_allocate (sizeof (*shared));
|
||||
shared->initially_disabled = initially_disabled;
|
||||
- init_termination_status ();
|
||||
|
||||
if (initially_disabled)
|
||||
{
|
||||
diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h
|
||||
index d5eac84d09ae325f..2d2384e73df0d2d0 100644
|
||||
--- a/support/capture_subprocess.h
|
||||
+++ b/support/capture_subprocess.h
|
||||
@@ -55,13 +55,16 @@ enum support_capture_allow
|
||||
sc_allow_stderr = 0x04,
|
||||
};
|
||||
|
||||
-/* Check that the subprocess exited with STATUS and that only the
|
||||
- allowed outputs happened. ALLOWED is a combination of
|
||||
- support_capture_allow flags. Report errors under the CONTEXT
|
||||
- message. */
|
||||
+/* Check that the subprocess exited and that only the allowed outputs
|
||||
+ happened. If STATUS_OR_SIGNAL is nonnegative, it is the expected
|
||||
+ (decoded) exit status of the process, as returned by WEXITSTATUS.
|
||||
+ If STATUS_OR_SIGNAL is negative, -STATUS_OR_SIGNAL is the expected
|
||||
+ termination signal, as returned by WTERMSIG. ALLOWED is a
|
||||
+ combination of support_capture_allow flags. Report errors under
|
||||
+ the CONTEXT message. */
|
||||
void support_capture_subprocess_check (struct support_capture_subprocess *,
|
||||
- const char *context, int status,
|
||||
- int allowed)
|
||||
+ const char *context,
|
||||
+ int status_or_signal, int allowed)
|
||||
__attribute__ ((nonnull (1, 2)));
|
||||
|
||||
#endif /* SUPPORT_CAPTURE_SUBPROCESS_H */
|
||||
diff --git a/support/support_capture_subprocess_check.c b/support/support_capture_subprocess_check.c
|
||||
index ff5ee89fb02599ae..8b4c352c96227b78 100644
|
||||
--- a/support/support_capture_subprocess_check.c
|
||||
+++ b/support/support_capture_subprocess_check.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <stdio.h>
|
||||
#include <support/capture_subprocess.h>
|
||||
#include <support/check.h>
|
||||
+#include <sys/wait.h>
|
||||
|
||||
static void
|
||||
print_context (const char *context, bool *failed)
|
||||
@@ -31,9 +32,22 @@ print_context (const char *context, bool *failed)
|
||||
printf ("error: subprocess failed: %s\n", context);
|
||||
}
|
||||
|
||||
+static void
|
||||
+print_actual_status (struct support_capture_subprocess *proc)
|
||||
+{
|
||||
+ if (WIFEXITED (proc->status))
|
||||
+ printf ("error: actual exit status: %d [0x%x]\n",
|
||||
+ WEXITSTATUS (proc->status), proc->status);
|
||||
+ else if (WIFSIGNALED (proc->status))
|
||||
+ printf ("error: actual termination signal: %d [0x%x]\n",
|
||||
+ WTERMSIG (proc->status), proc->status);
|
||||
+ else
|
||||
+ printf ("error: actual undecoded exit status: [0x%x]\n", proc->status);
|
||||
+}
|
||||
+
|
||||
void
|
||||
support_capture_subprocess_check (struct support_capture_subprocess *proc,
|
||||
- const char *context, int status,
|
||||
+ const char *context, int status_or_signal,
|
||||
int allowed)
|
||||
{
|
||||
TEST_VERIFY ((allowed & sc_allow_none)
|
||||
@@ -44,11 +58,28 @@ support_capture_subprocess_check (struct support_capture_subprocess *proc,
|
||||
|| (allowed & sc_allow_stderr))));
|
||||
|
||||
bool failed = false;
|
||||
- if (proc->status != status)
|
||||
+ if (status_or_signal >= 0)
|
||||
{
|
||||
- print_context (context, &failed);
|
||||
- printf ("error: expected exit status: %d\n", status);
|
||||
- printf ("error: actual exit status: %d\n", proc->status);
|
||||
+ /* Expect regular termination. */
|
||||
+ if (!(WIFEXITED (proc->status)
|
||||
+ && WEXITSTATUS (proc->status) == status_or_signal))
|
||||
+ {
|
||||
+ print_context (context, &failed);
|
||||
+ printf ("error: expected exit status: %d\n", status_or_signal);
|
||||
+ print_actual_status (proc);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* status_or_signal < 0. Expect termination by signal. */
|
||||
+ if (!(WIFSIGNALED (proc->status)
|
||||
+ && WTERMSIG (proc->status) == -status_or_signal))
|
||||
+ {
|
||||
+ print_context (context, &failed);
|
||||
+ printf ("error: expected termination signal: %d\n",
|
||||
+ -status_or_signal);
|
||||
+ print_actual_status (proc);
|
||||
+ }
|
||||
}
|
||||
if (!(allowed & sc_allow_stdout) && proc->out.length != 0)
|
||||
{
|
||||
diff --git a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c
|
||||
index 63b6699622f97fcc..99570879eedd65b1 100644
|
||||
--- a/support/tst-support_capture_subprocess.c
|
||||
+++ b/support/tst-support_capture_subprocess.c
|
||||
@@ -285,15 +285,29 @@ do_multiple_tests (enum test_type type)
|
||||
|
||||
check_stream ("stdout", &result.out, test.out);
|
||||
check_stream ("stderr", &result.err, test.err);
|
||||
+
|
||||
+ /* Allowed output for support_capture_subprocess_check. */
|
||||
+ int check_allow = 0;
|
||||
+ if (lengths[length_idx_stdout] > 0)
|
||||
+ check_allow |= sc_allow_stdout;
|
||||
+ if (lengths[length_idx_stderr] > 0)
|
||||
+ check_allow |= sc_allow_stderr;
|
||||
+ if (check_allow == 0)
|
||||
+ check_allow = sc_allow_none;
|
||||
+
|
||||
if (test.signal != 0)
|
||||
{
|
||||
TEST_VERIFY (WIFSIGNALED (result.status));
|
||||
TEST_VERIFY (WTERMSIG (result.status) == test.signal);
|
||||
+ support_capture_subprocess_check (&result, "signal",
|
||||
+ -SIGTERM, check_allow);
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_VERIFY (WIFEXITED (result.status));
|
||||
TEST_VERIFY (WEXITSTATUS (result.status) == test.status);
|
||||
+ support_capture_subprocess_check (&result, "exit",
|
||||
+ test.status, check_allow);
|
||||
}
|
||||
support_capture_subprocess_free (&result);
|
||||
free (test.out);
|
|
@ -1,42 +0,0 @@
|
|||
commit e37c2cf299b61ce18f62852f6c5624c27829b610
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Oct 31 18:48:43 2019 +0100
|
||||
|
||||
Move _dl_open_check to its original place in dl_open_worker
|
||||
|
||||
This reverts the non-test change from commit d0093c5cefb7f7a4143f
|
||||
("Call _dl_open_check after relocation [BZ #24259]"), given that
|
||||
the underlying bug has been fixed properly in commit 61b74477fa7f63
|
||||
("Remove all loaded objects if dlopen fails, ignoring NODELETE
|
||||
[BZ #20839]").
|
||||
|
||||
Tested on x86-64-linux-gnu, with and without --enable-cet.
|
||||
|
||||
Change-Id: I995a6cfb89f25d2b0cf5e606428c2a93eb48fc33
|
||||
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||
index 25838b073ac1edaf..e13968d4d7c4c83f 100644
|
||||
--- a/elf/dl-open.c
|
||||
+++ b/elf/dl-open.c
|
||||
@@ -619,6 +619,8 @@ dl_open_worker (void *a)
|
||||
_dl_debug_state ();
|
||||
LIBC_PROBE (map_complete, 3, args->nsid, r, new);
|
||||
|
||||
+ _dl_open_check (new);
|
||||
+
|
||||
/* Print scope information. */
|
||||
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
|
||||
_dl_show_scope (new, 0);
|
||||
@@ -699,12 +701,6 @@ dl_open_worker (void *a)
|
||||
_dl_relocate_object (l, l->l_scope, reloc_mode, 0);
|
||||
}
|
||||
|
||||
- /* NB: Workaround for [BZ #20839] which doesn't remove the NODELETE
|
||||
- object when _dl_open_check throws an exception. Move it after
|
||||
- relocation to avoid leaving the NODELETE object mapped without
|
||||
- relocation. */
|
||||
- _dl_open_check (new);
|
||||
-
|
||||
/* This only performs the memory allocations. The actual update of
|
||||
the scopes happens below, after failure is impossible. */
|
||||
resize_scopes (new);
|
|
@ -1,27 +0,0 @@
|
|||
commit 61a7c9df71ee4e6f94b56c20f0d37c6e17d5f284
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Dec 2 14:53:16 2019 +0100
|
||||
|
||||
elf/tst-dlopenfail: Disable --no-as-needed for tst-dlopenfailmod1.so
|
||||
|
||||
Otherwise, the shared object dependency which triggers the load
|
||||
failure is dropped, invalidating the test.
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index bf7c41f38be42184..467e810e784bb96d 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -1543,8 +1543,11 @@ LDFLAGS-tst-finilazyfailmod.so = \
|
||||
$(objpfx)tst-dlopenfail: $(libdl)
|
||||
$(objpfx)tst-dlopenfail.out: \
|
||||
$(objpfx)tst-dlopenfailmod1.so $(objpfx)tst-dlopenfailmod2.so
|
||||
-# Order matters here. tst-dlopenfaillinkmod.so's soname ensures
|
||||
-# a run-time loader failure.
|
||||
+# Order matters here. tst-dlopenfaillinkmod.so's soname ensures a
|
||||
+# run-time loader failure. --as-needed breaks this test because
|
||||
+# nothing actually references tst-dlopenfailmod2.so (with its soname
|
||||
+# tst-dlopenfail-missingmod.so).
|
||||
+LDFLAGS-tst-dlopenfailmod1.so = -Wl,--no-as-needed
|
||||
$(objpfx)tst-dlopenfailmod1.so: \
|
||||
$(shared-thread-library) $(objpfx)tst-dlopenfaillinkmod.so
|
||||
LDFLAGS-tst-dlopenfaillinkmod.so = -Wl,-soname,tst-dlopenfail-missingmod.so
|
File diff suppressed because it is too large
Load diff
|
@ -1,328 +0,0 @@
|
|||
commit f8ed116aa574435c6e28260f21963233682d3b57
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Dec 13 10:18:46 2019 +0100
|
||||
|
||||
dlopen: Rework handling of pending NODELETE status
|
||||
|
||||
Commit a2e8aa0d9ea648068d8be52dd7b15f1b6a008e23 ("Block signals during
|
||||
the initial part of dlopen") was deemed necessary because of
|
||||
read-modify-write operations like the one in add_dependency in
|
||||
elf/dl-lookup.c. In the old code, we check for any kind of NODELETE
|
||||
status and bail out:
|
||||
|
||||
/* Redo the NODELETE check, as when dl_load_lock wasn't held
|
||||
yet this could have changed. */
|
||||
if (map->l_nodelete != link_map_nodelete_inactive)
|
||||
goto out;
|
||||
|
||||
And then set pending status (during relocation):
|
||||
|
||||
if (flags & DL_LOOKUP_FOR_RELOCATE)
|
||||
map->l_nodelete = link_map_nodelete_pending;
|
||||
else
|
||||
map->l_nodelete = link_map_nodelete_active;
|
||||
|
||||
If a signal arrives during relocation and the signal handler, through
|
||||
lazy binding, adds a global scope dependency on the same map, it will
|
||||
set map->l_nodelete to link_map_nodelete_active. This will be
|
||||
overwritten with link_map_nodelete_pending by the dlopen relocation
|
||||
code.
|
||||
|
||||
To avoid such problems in relation to the l_nodelete member, this
|
||||
commit introduces two flags for active NODELETE status (irrevocable)
|
||||
and pending NODELETE status (revocable until activate_nodelete is
|
||||
invoked). As a result, NODELETE processing in dlopen does not
|
||||
introduce further reasons why lazy binding from signal handlers
|
||||
is unsafe during dlopen, and a subsequent commit can remove signal
|
||||
blocking from dlopen.
|
||||
|
||||
This does not address pre-existing issues (unrelated to the NODELETE
|
||||
changes) which make lazy binding in a signal handler during dlopen
|
||||
unsafe, such as the use of malloc in both cases.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||
index 243a028c443173c1..fa7f3e8174576e46 100644
|
||||
--- a/elf/dl-close.c
|
||||
+++ b/elf/dl-close.c
|
||||
@@ -197,7 +197,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
/* Check whether this object is still used. */
|
||||
if (l->l_type == lt_loaded
|
||||
&& l->l_direct_opencount == 0
|
||||
- && l->l_nodelete != link_map_nodelete_active
|
||||
+ && !l->l_nodelete_active
|
||||
/* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why
|
||||
acquire is sufficient and correct. */
|
||||
&& atomic_load_acquire (&l->l_tls_dtor_count) == 0
|
||||
@@ -279,8 +279,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
|
||||
if (!used[i])
|
||||
{
|
||||
- assert (imap->l_type == lt_loaded
|
||||
- && imap->l_nodelete != link_map_nodelete_active);
|
||||
+ assert (imap->l_type == lt_loaded && !imap->l_nodelete_active);
|
||||
|
||||
/* Call its termination function. Do not do it for
|
||||
half-cooked objects. Temporarily disable exception
|
||||
@@ -820,7 +819,7 @@ _dl_close (void *_map)
|
||||
before we took the lock. There is no way to detect this (see below)
|
||||
so we proceed assuming this isn't the case. First see whether we
|
||||
can remove the object at all. */
|
||||
- if (__glibc_unlikely (map->l_nodelete == link_map_nodelete_active))
|
||||
+ if (__glibc_unlikely (map->l_nodelete_active))
|
||||
{
|
||||
/* Nope. Do nothing. */
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
|
||||
index 35a3f96a6296294a..01724a54f8840f9f 100644
|
||||
--- a/elf/dl-lookup.c
|
||||
+++ b/elf/dl-lookup.c
|
||||
@@ -187,6 +187,28 @@ enter_unique_sym (struct unique_sym *table, size_t size,
|
||||
table[idx].map = map;
|
||||
}
|
||||
|
||||
+/* Mark MAP as NODELETE according to the lookup mode in FLAGS. During
|
||||
+ initial relocation, NODELETE state is pending only. */
|
||||
+static void
|
||||
+mark_nodelete (struct link_map *map, int flags)
|
||||
+{
|
||||
+ if (flags & DL_LOOKUP_FOR_RELOCATE)
|
||||
+ map->l_nodelete_pending = true;
|
||||
+ else
|
||||
+ map->l_nodelete_active = true;
|
||||
+}
|
||||
+
|
||||
+/* Return true if MAP is marked as NODELETE according to the lookup
|
||||
+ mode in FLAGS> */
|
||||
+static bool
|
||||
+is_nodelete (struct link_map *map, int flags)
|
||||
+{
|
||||
+ /* Non-pending NODELETE always counts. Pending NODELETE only counts
|
||||
+ during initial relocation processing. */
|
||||
+ return map->l_nodelete_active
|
||||
+ || ((flags & DL_LOOKUP_FOR_RELOCATE) && map->l_nodelete_pending);
|
||||
+}
|
||||
+
|
||||
/* Utility function for do_lookup_x. Lookup an STB_GNU_UNIQUE symbol
|
||||
in the unique symbol table, creating a new entry if necessary.
|
||||
Return the matching symbol in RESULT. */
|
||||
@@ -311,8 +333,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash,
|
||||
enter_unique_sym (entries, size,
|
||||
new_hash, strtab + sym->st_name, sym, map);
|
||||
|
||||
- if (map->l_type == lt_loaded
|
||||
- && map->l_nodelete == link_map_nodelete_inactive)
|
||||
+ if (map->l_type == lt_loaded && !is_nodelete (map, flags))
|
||||
{
|
||||
/* Make sure we don't unload this object by
|
||||
setting the appropriate flag. */
|
||||
@@ -320,10 +341,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash,
|
||||
_dl_debug_printf ("\
|
||||
marking %s [%lu] as NODELETE due to unique symbol\n",
|
||||
map->l_name, map->l_ns);
|
||||
- if (flags & DL_LOOKUP_FOR_RELOCATE)
|
||||
- map->l_nodelete = link_map_nodelete_pending;
|
||||
- else
|
||||
- map->l_nodelete = link_map_nodelete_active;
|
||||
+ mark_nodelete (map, flags);
|
||||
}
|
||||
}
|
||||
++tab->n_elements;
|
||||
@@ -586,7 +604,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
|
||||
dependencies may pick an dependency which can be dlclose'd, but
|
||||
such IFUNC resolvers are undefined anyway. */
|
||||
assert (map->l_type == lt_loaded);
|
||||
- if (map->l_nodelete != link_map_nodelete_inactive)
|
||||
+ if (is_nodelete (map, flags))
|
||||
return 0;
|
||||
|
||||
struct link_map_reldeps *l_reldeps
|
||||
@@ -694,17 +712,16 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
|
||||
|
||||
/* Redo the NODELETE check, as when dl_load_lock wasn't held
|
||||
yet this could have changed. */
|
||||
- if (map->l_nodelete != link_map_nodelete_inactive)
|
||||
+ if (is_nodelete (map, flags))
|
||||
goto out;
|
||||
|
||||
/* If the object with the undefined reference cannot be removed ever
|
||||
just make sure the same is true for the object which contains the
|
||||
definition. */
|
||||
- if (undef_map->l_type != lt_loaded
|
||||
- || (undef_map->l_nodelete != link_map_nodelete_inactive))
|
||||
+ if (undef_map->l_type != lt_loaded || is_nodelete (map, flags))
|
||||
{
|
||||
if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)
|
||||
- && map->l_nodelete == link_map_nodelete_inactive)
|
||||
+ && !is_nodelete (map, flags))
|
||||
{
|
||||
if (undef_map->l_name[0] == '\0')
|
||||
_dl_debug_printf ("\
|
||||
@@ -716,11 +733,7 @@ marking %s [%lu] as NODELETE due to reference to %s [%lu]\n",
|
||||
map->l_name, map->l_ns,
|
||||
undef_map->l_name, undef_map->l_ns);
|
||||
}
|
||||
-
|
||||
- if (flags & DL_LOOKUP_FOR_RELOCATE)
|
||||
- map->l_nodelete = link_map_nodelete_pending;
|
||||
- else
|
||||
- map->l_nodelete = link_map_nodelete_active;
|
||||
+ mark_nodelete (map, flags);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -746,17 +759,14 @@ marking %s [%lu] as NODELETE due to reference to %s [%lu]\n",
|
||||
cannot be unloaded. This is semantically the correct
|
||||
behavior. */
|
||||
if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)
|
||||
- && map->l_nodelete == link_map_nodelete_inactive)
|
||||
+ && !is_nodelete (map, flags))
|
||||
_dl_debug_printf ("\
|
||||
marking %s [%lu] as NODELETE due to memory allocation failure\n",
|
||||
map->l_name, map->l_ns);
|
||||
- if (flags & DL_LOOKUP_FOR_RELOCATE)
|
||||
- /* In case of non-lazy binding, we could actually
|
||||
- report the memory allocation error, but for now, we
|
||||
- use the conservative approximation as well. */
|
||||
- map->l_nodelete = link_map_nodelete_pending;
|
||||
- else
|
||||
- map->l_nodelete = link_map_nodelete_active;
|
||||
+ /* In case of non-lazy binding, we could actually report
|
||||
+ the memory allocation error, but for now, we use the
|
||||
+ conservative approximation as well. */
|
||||
+ mark_nodelete (map, flags);
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||
index c7ed85b7ee99a296..a382bfae8aa3a2f8 100644
|
||||
--- a/elf/dl-open.c
|
||||
+++ b/elf/dl-open.c
|
||||
@@ -440,13 +440,17 @@ activate_nodelete (struct link_map *new)
|
||||
NODELETE status for objects outside the local scope. */
|
||||
for (struct link_map *l = GL (dl_ns)[new->l_ns]._ns_loaded; l != NULL;
|
||||
l = l->l_next)
|
||||
- if (l->l_nodelete == link_map_nodelete_pending)
|
||||
+ if (l->l_nodelete_pending)
|
||||
{
|
||||
if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES))
|
||||
_dl_debug_printf ("activating NODELETE for %s [%lu]\n",
|
||||
l->l_name, l->l_ns);
|
||||
|
||||
- l->l_nodelete = link_map_nodelete_active;
|
||||
+ l->l_nodelete_active = true;
|
||||
+
|
||||
+ /* This is just a debugging aid, to indicate that
|
||||
+ activate_nodelete has run for this map. */
|
||||
+ l->l_nodelete_pending = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,10 +553,10 @@ dl_open_worker (void *a)
|
||||
if (__glibc_unlikely (mode & RTLD_NODELETE))
|
||||
{
|
||||
if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)
|
||||
- && new->l_nodelete == link_map_nodelete_inactive)
|
||||
+ && !new->l_nodelete_active)
|
||||
_dl_debug_printf ("marking %s [%lu] as NODELETE\n",
|
||||
new->l_name, new->l_ns);
|
||||
- new->l_nodelete = link_map_nodelete_active;
|
||||
+ new->l_nodelete_active = true;
|
||||
}
|
||||
|
||||
/* Finalize the addition to the global scope. */
|
||||
@@ -568,7 +572,7 @@ dl_open_worker (void *a)
|
||||
/* Schedule NODELETE marking for the directly loaded object if
|
||||
requested. */
|
||||
if (__glibc_unlikely (mode & RTLD_NODELETE))
|
||||
- new->l_nodelete = link_map_nodelete_pending;
|
||||
+ new->l_nodelete_pending = true;
|
||||
|
||||
/* Load that object's dependencies. */
|
||||
_dl_map_object_deps (new, NULL, 0, 0,
|
||||
@@ -680,7 +684,7 @@ dl_open_worker (void *a)
|
||||
_dl_start_profile ();
|
||||
|
||||
/* Prevent unloading the object. */
|
||||
- GL(dl_profile_map)->l_nodelete = link_map_nodelete_active;
|
||||
+ GL(dl_profile_map)->l_nodelete_active = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -879,9 +883,9 @@ no more namespaces available for dlmopen()"));
|
||||
happens inside dl_open_worker. */
|
||||
__libc_signal_restore_set (&args.original_signal_mask);
|
||||
|
||||
- /* All link_map_nodelete_pending objects should have been
|
||||
- deleted at this point, which is why it is not necessary
|
||||
- to reset the flag here. */
|
||||
+ /* All l_nodelete_pending objects should have been deleted
|
||||
+ at this point, which is why it is not necessary to reset
|
||||
+ the flag here. */
|
||||
}
|
||||
else
|
||||
__libc_signal_restore_set (&args.original_signal_mask);
|
||||
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
|
||||
index ea286abaea0128d1..78ba7e76db9706cc 100644
|
||||
--- a/elf/get-dynamic-info.h
|
||||
+++ b/elf/get-dynamic-info.h
|
||||
@@ -164,7 +164,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
{
|
||||
l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
|
||||
if (l->l_flags_1 & DF_1_NODELETE)
|
||||
- l->l_nodelete = link_map_nodelete_pending;
|
||||
+ l->l_nodelete_pending = true;
|
||||
|
||||
/* Only DT_1_SUPPORTED_MASK bits are supported, and we would like
|
||||
to assert this, but we can't. Users have been setting
|
||||
diff --git a/include/link.h b/include/link.h
|
||||
index a277b77cad6b52b1..e90fa79a0b332087 100644
|
||||
--- a/include/link.h
|
||||
+++ b/include/link.h
|
||||
@@ -79,22 +79,6 @@ struct r_search_path_struct
|
||||
int malloced;
|
||||
};
|
||||
|
||||
-/* Type used by the l_nodelete member. */
|
||||
-enum link_map_nodelete
|
||||
-{
|
||||
- /* This link map can be deallocated. */
|
||||
- link_map_nodelete_inactive = 0, /* Zero-initialized in _dl_new_object. */
|
||||
-
|
||||
- /* This link map cannot be deallocated. */
|
||||
- link_map_nodelete_active,
|
||||
-
|
||||
- /* This link map cannot be deallocated after dlopen has succeded.
|
||||
- dlopen turns this into link_map_nodelete_active. dlclose treats
|
||||
- this intermediate state as link_map_nodelete_active. */
|
||||
- link_map_nodelete_pending,
|
||||
-};
|
||||
-
|
||||
-
|
||||
/* Structure describing a loaded shared object. The `l_next' and `l_prev'
|
||||
members form a chain of all the shared objects loaded at startup.
|
||||
|
||||
@@ -218,10 +202,17 @@ struct link_map
|
||||
freed, ie. not allocated with
|
||||
the dummy malloc in ld.so. */
|
||||
|
||||
- /* Actually of type enum link_map_nodelete. Separate byte due to
|
||||
- a read in add_dependency in elf/dl-lookup.c outside the loader
|
||||
- lock. Only valid for l_type == lt_loaded. */
|
||||
- unsigned char l_nodelete;
|
||||
+ /* NODELETE status of the map. Only valid for maps of type
|
||||
+ lt_loaded. Lazy binding sets l_nodelete_active directly,
|
||||
+ potentially from signal handlers. Initial loading of an
|
||||
+ DF_1_NODELETE object set l_nodelete_pending. Relocation may
|
||||
+ set l_nodelete_pending as well. l_nodelete_pending maps are
|
||||
+ promoted to l_nodelete_active status in the final stages of
|
||||
+ dlopen, prior to calling ELF constructors. dlclose only
|
||||
+ refuses to unload l_nodelete_active maps, the pending status is
|
||||
+ ignored. */
|
||||
+ bool l_nodelete_active;
|
||||
+ bool l_nodelete_pending;
|
||||
|
||||
#include <link_map.h>
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
commit f7649d5780aa4682393b9daedd653e4d9c12784c
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Dec 13 10:23:10 2019 +0100
|
||||
|
||||
dlopen: Do not block signals
|
||||
|
||||
Blocking signals causes issues with certain anti-malware solutions
|
||||
which rely on an unblocked SIGSYS signal for system calls they
|
||||
intercept.
|
||||
|
||||
This reverts commit a2e8aa0d9ea648068d8be52dd7b15f1b6a008e23
|
||||
("Block signals during the initial part of dlopen") and adds
|
||||
comments related to async signal safety to active_nodelete and
|
||||
its caller.
|
||||
|
||||
Note that this does not make lazy binding async-signal-safe with regards
|
||||
to dlopen. It merely avoids introducing new async-signal-safety hazards
|
||||
as part of the NODELETE changes.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||
index a382bfae8aa3a2f8..d834b89754d2b073 100644
|
||||
--- a/elf/dl-open.c
|
||||
+++ b/elf/dl-open.c
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <atomic.h>
|
||||
#include <libc-internal.h>
|
||||
#include <array_length.h>
|
||||
-#include <internal-signals.h>
|
||||
|
||||
#include <dl-dst.h>
|
||||
#include <dl-prop.h>
|
||||
@@ -53,10 +52,6 @@ struct dl_open_args
|
||||
/* Namespace ID. */
|
||||
Lmid_t nsid;
|
||||
|
||||
- /* Original signal mask. Used for unblocking signal handlers before
|
||||
- running ELF constructors. */
|
||||
- sigset_t original_signal_mask;
|
||||
-
|
||||
/* Original value of _ns_global_scope_pending_adds. Set by
|
||||
dl_open_worker. Only valid if nsid is a real namespace
|
||||
(non-negative). */
|
||||
@@ -446,6 +441,9 @@ activate_nodelete (struct link_map *new)
|
||||
_dl_debug_printf ("activating NODELETE for %s [%lu]\n",
|
||||
l->l_name, l->l_ns);
|
||||
|
||||
+ /* The flag can already be true at this point, e.g. a signal
|
||||
+ handler may have triggered lazy binding and set NODELETE
|
||||
+ status immediately. */
|
||||
l->l_nodelete_active = true;
|
||||
|
||||
/* This is just a debugging aid, to indicate that
|
||||
@@ -520,16 +518,12 @@ dl_open_worker (void *a)
|
||||
if (new == NULL)
|
||||
{
|
||||
assert (mode & RTLD_NOLOAD);
|
||||
- __libc_signal_restore_set (&args->original_signal_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
if (__glibc_unlikely (mode & __RTLD_SPROF))
|
||||
- {
|
||||
- /* This happens only if we load a DSO for 'sprof'. */
|
||||
- __libc_signal_restore_set (&args->original_signal_mask);
|
||||
- return;
|
||||
- }
|
||||
+ /* This happens only if we load a DSO for 'sprof'. */
|
||||
+ return;
|
||||
|
||||
/* This object is directly loaded. */
|
||||
++new->l_direct_opencount;
|
||||
@@ -565,7 +559,6 @@ dl_open_worker (void *a)
|
||||
|
||||
assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT);
|
||||
|
||||
- __libc_signal_restore_set (&args->original_signal_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -709,6 +702,12 @@ dl_open_worker (void *a)
|
||||
All memory allocations for new objects must have happened
|
||||
before. */
|
||||
|
||||
+ /* Finalize the NODELETE status first. This comes before
|
||||
+ update_scopes, so that lazy binding will not see pending NODELETE
|
||||
+ state for newly loaded objects. There is a compiler barrier in
|
||||
+ update_scopes which ensures that the changes from
|
||||
+ activate_nodelete are visible before new objects show up in the
|
||||
+ local scope. */
|
||||
activate_nodelete (new);
|
||||
|
||||
/* Second stage after resize_scopes: Actually perform the scope
|
||||
@@ -742,10 +741,6 @@ dl_open_worker (void *a)
|
||||
if (mode & RTLD_GLOBAL)
|
||||
add_to_global_resize (new);
|
||||
|
||||
- /* Unblock signals. Data structures are now consistent, and
|
||||
- application code may run. */
|
||||
- __libc_signal_restore_set (&args->original_signal_mask);
|
||||
-
|
||||
/* Run the initializer functions of new objects. Temporarily
|
||||
disable the exception handler, so that lazy binding failures are
|
||||
fatal. */
|
||||
@@ -835,10 +830,6 @@ no more namespaces available for dlmopen()"));
|
||||
args.argv = argv;
|
||||
args.env = env;
|
||||
|
||||
- /* Recursive lazy binding during manipulation of the dynamic loader
|
||||
- structures may result in incorrect behavior. */
|
||||
- __libc_signal_block_all (&args.original_signal_mask);
|
||||
-
|
||||
struct dl_exception exception;
|
||||
int errcode = _dl_catch_exception (&exception, dl_open_worker, &args);
|
||||
|
||||
@@ -879,16 +870,10 @@ no more namespaces available for dlmopen()"));
|
||||
|
||||
_dl_close_worker (args.map, true);
|
||||
|
||||
- /* Restore the signal mask. In the success case, this
|
||||
- happens inside dl_open_worker. */
|
||||
- __libc_signal_restore_set (&args.original_signal_mask);
|
||||
-
|
||||
/* All l_nodelete_pending objects should have been deleted
|
||||
at this point, which is why it is not necessary to reset
|
||||
the flag here. */
|
||||
}
|
||||
- else
|
||||
- __libc_signal_restore_set (&args.original_signal_mask);
|
||||
|
||||
assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue