import glibc-2.34-40.el9
This commit is contained in:
parent
9632a2a656
commit
96694ca8ed
@ -1,21 +0,0 @@
|
||||
Short description: Fedora-specific glibc install locale changes.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-needed
|
||||
|
||||
The Fedora glibc build and install does not need the normal install
|
||||
behaviour which updates the locale archive. The Fedora install phase
|
||||
in the spec file of the rpm will handle this manually.
|
||||
|
||||
diff --git a/localedata/Makefile b/localedata/Makefile
|
||||
index 0eea396ad86da956..54caabda33728207 100644
|
||||
--- a/localedata/Makefile
|
||||
+++ b/localedata/Makefile
|
||||
@@ -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';
|
27
SOURCES/glibc-rh2054789.patch
Normal file
27
SOURCES/glibc-rh2054789.patch
Normal file
@ -0,0 +1,27 @@
|
||||
commit ea89d5bbd9e5e514b606045d909e6ab87d851c88
|
||||
Author: Arjun Shankar <arjun@redhat.com>
|
||||
Date: Thu Feb 24 21:43:09 2022 +0100
|
||||
|
||||
localedef: Handle symbolic links when generating locale-archive
|
||||
|
||||
Whenever locale data for any locale included symbolic links, localedef
|
||||
would throw the error "incomplete set of locale files" and exclude it
|
||||
from the generated locale archive. This commit fixes that.
|
||||
|
||||
Co-authored-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c
|
||||
index f38e835c52e4a967..d79278b6ed7340bf 100644
|
||||
--- a/locale/programs/locarchive.c
|
||||
+++ b/locale/programs/locarchive.c
|
||||
@@ -1391,7 +1391,7 @@ add_locales_to_archive (size_t nlist, char *list[], bool replace)
|
||||
{
|
||||
char fullname[fnamelen + 2 * strlen (d->d_name) + 7];
|
||||
|
||||
- if (d_type == DT_UNKNOWN)
|
||||
+ if (d_type == DT_UNKNOWN || d_type == DT_LNK)
|
||||
{
|
||||
strcpy (stpcpy (stpcpy (fullname, fname), "/"),
|
||||
d->d_name);
|
@ -16,7 +16,7 @@ Date: Thu Dec 9 09:49:32 2021 +0100
|
||||
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
|
||||
diff --git a/manual/threads.texi b/manual/threads.texi
|
||||
index 06b6b277a1228af1..ab44a92ca0f5a6a5 100644
|
||||
index 7f166bfa87e88c36..4869f69d2ceed255 100644
|
||||
--- a/manual/threads.texi
|
||||
+++ b/manual/threads.texi
|
||||
@@ -629,6 +629,8 @@ the standard.
|
||||
@ -115,7 +115,7 @@ index 06b6b277a1228af1..ab44a92ca0f5a6a5 100644
|
||||
@c pthread_atfork
|
||||
@c pthread_attr_destroy
|
||||
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
index b39dfbff2c6678d5..4a73927f805abf94 100644
|
||||
index 23aa4cfc0b784dfc..0f5280a75d546d2f 100644
|
||||
--- a/sysdeps/nptl/dl-tls_init_tp.c
|
||||
+++ b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
@@ -22,6 +22,7 @@
|
||||
@ -163,7 +163,7 @@ index b39dfbff2c6678d5..4a73927f805abf94 100644
|
||||
|
||||
/* Set initial thread's stack block from 0 up to __libc_stack_end.
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index 0657f4003e7116c6..856a9d58cef6a879 100644
|
||||
index 5c772f69d1b1f1f1..9b7e214219943531 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -110,7 +110,8 @@ sysdep_headers += sys/mount.h sys/acct.h \
|
@ -11,7 +11,7 @@ Date: Wed Feb 2 22:37:20 2022 +0100
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/manual/threads.texi b/manual/threads.texi
|
||||
index ab44a92ca0f5a6a5..4b9fc946916190ef 100644
|
||||
index 4869f69d2ceed255..48fd562923800b34 100644
|
||||
--- a/manual/threads.texi
|
||||
+++ b/manual/threads.texi
|
||||
@@ -1004,7 +1004,7 @@ The manual for the @code{rseq} system call can be found
|
||||
@ -24,7 +24,7 @@ index ab44a92ca0f5a6a5..4b9fc946916190ef 100644
|
||||
This variable contains the offset between the thread pointer (as defined
|
||||
by @code{__builtin_thread_pointer} or the thread pointer register for
|
||||
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
index 4a73927f805abf94..86e87c7da4e88d66 100644
|
||||
index 0f5280a75d546d2f..d5f2587f1348441c 100644
|
||||
--- a/sysdeps/nptl/dl-tls_init_tp.c
|
||||
+++ b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
@@ -46,7 +46,7 @@ rtld_mutex_dummy (pthread_mutex_t *lock)
|
38
SOURCES/glibc-rh2085529-4.patch
Normal file
38
SOURCES/glibc-rh2085529-4.patch
Normal file
@ -0,0 +1,38 @@
|
||||
Revert glibc-rh2024347-13.patch. Enable rseq by default.
|
||||
|
||||
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||
index f559c44dcec4624b..28ff502990c2a10f 100644
|
||||
--- a/manual/tunables.texi
|
||||
+++ b/manual/tunables.texi
|
||||
@@ -425,13 +425,11 @@ The value is measured in bytes. The default is @samp{41943040}
|
||||
@end deftp
|
||||
|
||||
@deftp Tunable glibc.pthread.rseq
|
||||
-The @code{glibc.pthread.rseq} tunable can be set to @samp{1}, to enable
|
||||
-restartable sequences support. @Theglibc{} uses this to optimize the
|
||||
-@code{sched_getcpu} function.
|
||||
-
|
||||
-The default is @samp{0}, which means that applications can perform
|
||||
-restartable sequences registration, but @code{sched_getcpu} is not
|
||||
-accelerated.
|
||||
+The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable
|
||||
+restartable sequences support in @theglibc{}. This enables applications
|
||||
+to perform direct restartable sequence registration with the kernel.
|
||||
+The default is @samp{1}, which means that @theglibc{} performs
|
||||
+registration on behalf of the application.
|
||||
|
||||
Restartable sequences are a Linux-specific extension.
|
||||
@end deftp
|
||||
diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list
|
||||
index df2a39ce01858d3b..d24f4be0d08ba407 100644
|
||||
--- a/sysdeps/nptl/dl-tunables.list
|
||||
+++ b/sysdeps/nptl/dl-tunables.list
|
||||
@@ -31,7 +31,7 @@ glibc {
|
||||
type: INT_32
|
||||
minval: 0
|
||||
maxval: 1
|
||||
- default: 0
|
||||
+ default: 1
|
||||
}
|
||||
}
|
||||
}
|
67
SOURCES/glibc-rh2096191-1.patch
Normal file
67
SOURCES/glibc-rh2096191-1.patch
Normal file
@ -0,0 +1,67 @@
|
||||
commit 62a321b12d0e397af88fa422db65079332f971dc
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jun 24 18:16:41 2022 +0200
|
||||
|
||||
support: Change non-address output format of support_format_dns_packet
|
||||
|
||||
It makes sense to include the owner name (LHS) and record type in the
|
||||
output, so that they can be checked for correctness.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/support/support_format_dns_packet.c b/support/support_format_dns_packet.c
|
||||
index 1f8e9ca172a06f4f..c3dff0e019801904 100644
|
||||
--- a/support/support_format_dns_packet.c
|
||||
+++ b/support/support_format_dns_packet.c
|
||||
@@ -101,6 +101,17 @@ extract_name (struct in_buffer full, struct in_buffer *in, struct dname *value)
|
||||
return true;
|
||||
}
|
||||
|
||||
+static void
|
||||
+extract_name_data (struct in_buffer full, struct in_buffer *rdata,
|
||||
+ const struct dname *owner, const char *typename, FILE *out)
|
||||
+{
|
||||
+ struct dname name;
|
||||
+ if (extract_name (full, rdata, &name))
|
||||
+ fprintf (out, "data: %s %s %s\n", owner->name, typename, name.name);
|
||||
+ else
|
||||
+ fprintf (out, "error: malformed CNAME/PTR record\n");
|
||||
+}
|
||||
+
|
||||
char *
|
||||
support_format_dns_packet (const unsigned char *buffer, size_t length)
|
||||
{
|
||||
@@ -206,14 +217,11 @@ support_format_dns_packet (const unsigned char *buffer, size_t length)
|
||||
}
|
||||
break;
|
||||
case T_CNAME:
|
||||
+ extract_name_data (full, &rdata, &rname, "CNAME", mem.out);
|
||||
+ break;
|
||||
case T_PTR:
|
||||
- {
|
||||
- struct dname name;
|
||||
- if (extract_name (full, &rdata, &name))
|
||||
- fprintf (mem.out, "name: %s\n", name.name);
|
||||
- else
|
||||
- fprintf (mem.out, "error: malformed CNAME/PTR record\n");
|
||||
- }
|
||||
+ extract_name_data (full, &rdata, &rname, "PTR", mem.out);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/support/tst-support_format_dns_packet.c b/support/tst-support_format_dns_packet.c
|
||||
index 03ff59457e3bdde8..5596db1785009557 100644
|
||||
--- a/support/tst-support_format_dns_packet.c
|
||||
+++ b/support/tst-support_format_dns_packet.c
|
||||
@@ -85,8 +85,8 @@ test_multiple_cnames (void)
|
||||
"\xc0\x00\x02\x01";
|
||||
check_packet (packet, sizeof (packet) - 1, __func__,
|
||||
"name: www.example\n"
|
||||
- "name: www1.example\n"
|
||||
- "name: www2.example\n"
|
||||
+ "data: www.example CNAME www1.example\n"
|
||||
+ "data: www1.example CNAME www2.example\n"
|
||||
"address: 192.0.2.1\n");
|
||||
}
|
||||
|
941
SOURCES/glibc-rh2096191-2.patch
Normal file
941
SOURCES/glibc-rh2096191-2.patch
Normal file
@ -0,0 +1,941 @@
|
||||
commit f282cdbe7f436c75864e5640a409a10485e9abb2
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jun 24 18:16:41 2022 +0200
|
||||
|
||||
resolv: Implement no-aaaa stub resolver option
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/resolv/Makefile b/resolv/Makefile
|
||||
index 59e599535c7aa6eb..e8269dcb5bcf216b 100644
|
||||
--- a/resolv/Makefile
|
||||
+++ b/resolv/Makefile
|
||||
@@ -51,6 +51,7 @@ routines := \
|
||||
nss_dns_functions \
|
||||
res-close \
|
||||
res-name-checking \
|
||||
+ res-noaaaa \
|
||||
res-state \
|
||||
res_context_hostalias \
|
||||
res_enable_icmp \
|
||||
@@ -93,6 +94,7 @@ tests += \
|
||||
tst-resolv-binary \
|
||||
tst-resolv-edns \
|
||||
tst-resolv-network \
|
||||
+ tst-resolv-noaaaa \
|
||||
tst-resolv-nondecimal \
|
||||
tst-resolv-res_init-multi \
|
||||
tst-resolv-search \
|
||||
@@ -256,6 +258,7 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
|
||||
$(shared-thread-library)
|
||||
$(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \
|
||||
$(shared-thread-library)
|
||||
+$(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
|
||||
index 7248ade18db5ba47..6e83fca1c5b1f98c 100644
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ b/resolv/nss_dns/dns-host.c
|
||||
@@ -125,6 +125,14 @@ static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
|
||||
char *buffer, size_t buflen,
|
||||
int *errnop, int *h_errnop,
|
||||
int32_t *ttlp);
|
||||
+static enum nss_status gaih_getanswer_noaaaa (const querybuf *answer1,
|
||||
+ int anslen1,
|
||||
+ const char *qname,
|
||||
+ struct gaih_addrtuple **pat,
|
||||
+ char *buffer, size_t buflen,
|
||||
+ int *errnop, int *h_errnop,
|
||||
+ int32_t *ttlp);
|
||||
+
|
||||
|
||||
static enum nss_status gethostbyname3_context (struct resolv_context *ctx,
|
||||
const char *name, int af,
|
||||
@@ -370,17 +378,31 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
|
||||
int resplen2 = 0;
|
||||
int ans2p_malloced = 0;
|
||||
|
||||
+
|
||||
int olderr = errno;
|
||||
- int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
|
||||
+ int n;
|
||||
+
|
||||
+ if ((ctx->resp->options & RES_NOAAAA) == 0)
|
||||
+ {
|
||||
+ n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
|
||||
host_buffer.buf->buf, 2048, &host_buffer.ptr,
|
||||
&ans2p, &nans2p, &resplen2, &ans2p_malloced);
|
||||
- if (n >= 0)
|
||||
- {
|
||||
- status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
|
||||
- resplen2, name, pat, buffer, buflen,
|
||||
- errnop, herrnop, ttlp);
|
||||
+ if (n >= 0)
|
||||
+ status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
|
||||
+ resplen2, name, pat, buffer, buflen,
|
||||
+ errnop, herrnop, ttlp);
|
||||
}
|
||||
else
|
||||
+ {
|
||||
+ n = __res_context_search (ctx, name, C_IN, T_A,
|
||||
+ host_buffer.buf->buf, 2048, NULL,
|
||||
+ NULL, NULL, NULL, NULL);
|
||||
+ if (n >= 0)
|
||||
+ status = gaih_getanswer_noaaaa (host_buffer.buf, n,
|
||||
+ name, pat, buffer, buflen,
|
||||
+ errnop, herrnop, ttlp);
|
||||
+ }
|
||||
+ if (n < 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
@@ -1388,3 +1410,21 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
|
||||
|
||||
return status;
|
||||
}
|
||||
+
|
||||
+/* Variant of gaih_getanswer without a second (AAAA) response. */
|
||||
+static enum nss_status
|
||||
+gaih_getanswer_noaaaa (const querybuf *answer1, int anslen1, const char *qname,
|
||||
+ struct gaih_addrtuple **pat,
|
||||
+ char *buffer, size_t buflen,
|
||||
+ int *errnop, int *h_errnop, int32_t *ttlp)
|
||||
+{
|
||||
+ int first = 1;
|
||||
+
|
||||
+ enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
+ if (anslen1 > 0)
|
||||
+ status = gaih_getanswer_slice (answer1, anslen1, qname,
|
||||
+ &pat, &buffer, &buflen,
|
||||
+ errnop, h_errnop, ttlp,
|
||||
+ &first);
|
||||
+ return status;
|
||||
+}
|
||||
diff --git a/resolv/res-noaaaa.c b/resolv/res-noaaaa.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4ba197664a86aed7
|
||||
--- /dev/null
|
||||
+++ b/resolv/res-noaaaa.c
|
||||
@@ -0,0 +1,143 @@
|
||||
+/* Implement suppression of AAAA queries.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <resolv.h>
|
||||
+#include <string.h>
|
||||
+#include <resolv-internal.h>
|
||||
+#include <resolv_context.h>
|
||||
+#include <arpa/nameser.h>
|
||||
+
|
||||
+/* Returns true if the question type at P matches EXPECTED, and the
|
||||
+ class is IN. */
|
||||
+static bool
|
||||
+qtype_matches (const unsigned char *p, int expected)
|
||||
+{
|
||||
+ /* This assumes that T_A/C_IN constants are less than 256, which
|
||||
+ they are. */
|
||||
+ return p[0] == 0 && p[1] == expected && p[2] == 0 && p[3] == C_IN;
|
||||
+}
|
||||
+
|
||||
+/* Handle RES_NOAAAA translation of AAAA queries. To produce a Name
|
||||
+ Error (NXDOMAIN) repsonse for domain names that do not exist, it is
|
||||
+ still necessary to send a query. Using question type A is a
|
||||
+ conservative choice. In the returned answer, it is necessary to
|
||||
+ switch back the question type to AAAA. */
|
||||
+bool
|
||||
+__res_handle_no_aaaa (struct resolv_context *ctx,
|
||||
+ const unsigned char *buf, int buflen,
|
||||
+ unsigned char *ans, int anssiz, int *result)
|
||||
+{
|
||||
+ /* AAAA mode is not active, or the query looks invalid (will not be
|
||||
+ able to be parsed). */
|
||||
+ if ((ctx->resp->options & RES_NOAAAA) == 0
|
||||
+ || buflen <= sizeof (HEADER))
|
||||
+ return false;
|
||||
+
|
||||
+ /* The replacement A query is produced here. */
|
||||
+ struct
|
||||
+ {
|
||||
+ HEADER header;
|
||||
+ unsigned char question[NS_MAXCDNAME + 4];
|
||||
+ } replacement;
|
||||
+ memcpy (&replacement.header, buf, sizeof (replacement.header));
|
||||
+
|
||||
+ if (replacement.header.qr
|
||||
+ || replacement.header.opcode != 0
|
||||
+ || replacement.header.rcode != 0
|
||||
+ || ntohs (replacement.header.qdcount) != 1
|
||||
+ || ntohs (replacement.header.ancount) != 0
|
||||
+ || ntohs (replacement.header.nscount) != 0)
|
||||
+ /* Not a well-formed question. Let the core resolver code produce
|
||||
+ the proper error. */
|
||||
+ return false;
|
||||
+
|
||||
+ /* Disable EDNS0. */
|
||||
+ replacement.header.arcount = htons (0);
|
||||
+
|
||||
+ /* Extract the QNAME. */
|
||||
+ int ret = __ns_name_unpack (buf, buf + buflen, buf + sizeof (HEADER),
|
||||
+ replacement.question, NS_MAXCDNAME);
|
||||
+ if (ret < 0)
|
||||
+ /* Format error. */
|
||||
+ return false;
|
||||
+
|
||||
+ /* Compute the end of the question name. */
|
||||
+ const unsigned char *after_question = buf + sizeof (HEADER) + ret;
|
||||
+
|
||||
+ /* Check that we are dealing with an AAAA query. */
|
||||
+ if (buf + buflen - after_question < 4
|
||||
+ || !qtype_matches (after_question, T_AAAA))
|
||||
+ return false;
|
||||
+
|
||||
+ /* Find the place to store the type/class data in the replacement
|
||||
+ query. */
|
||||
+ after_question = replacement.question;
|
||||
+ /* This cannot fail because __ns_name_unpack above produced a valid
|
||||
+ domain name. */
|
||||
+ (void) __ns_name_skip (&after_question, &replacement.question[NS_MAXCDNAME]);
|
||||
+ unsigned char *start_of_query = (unsigned char *) &replacement;
|
||||
+ const unsigned char *end_of_query = after_question + 4;
|
||||
+
|
||||
+ /* Produce an A/IN query. */
|
||||
+ {
|
||||
+ unsigned char *p = (unsigned char *) after_question;
|
||||
+ p[0] = 0;
|
||||
+ p[1] = T_A;
|
||||
+ p[2] = 0;
|
||||
+ p[3] = C_IN;
|
||||
+ }
|
||||
+
|
||||
+ /* Clear the output buffer, to avoid reading undefined data when
|
||||
+ rewriting the result from A to AAAA. */
|
||||
+ memset (ans, 0, anssiz);
|
||||
+
|
||||
+ /* Always perform the message translation, independent of the error
|
||||
+ code. */
|
||||
+ ret = __res_context_send (ctx,
|
||||
+ start_of_query, end_of_query - start_of_query,
|
||||
+ NULL, 0, ans, anssiz,
|
||||
+ NULL, NULL, NULL, NULL, NULL);
|
||||
+
|
||||
+ /* Patch in the AAAA question type if there is room and the A query
|
||||
+ type was received. */
|
||||
+ after_question = ans + sizeof (HEADER);
|
||||
+ if (__ns_name_skip (&after_question, ans + anssiz) == 0
|
||||
+ && ans + anssiz - after_question >= 4
|
||||
+ && qtype_matches (after_question, T_A))
|
||||
+ {
|
||||
+ ((unsigned char *) after_question)[1] = T_AAAA;
|
||||
+
|
||||
+ /* Create an aligned copy of the header. Hide all data except
|
||||
+ the question from the response. Put back the header. There is
|
||||
+ no need to change the response code. The zero answer count turns
|
||||
+ a positive response with data into a no-data response. */
|
||||
+ memcpy (&replacement.header, ans, sizeof (replacement.header));
|
||||
+ replacement.header.ancount = htons (0);
|
||||
+ replacement.header.nscount = htons (0);
|
||||
+ replacement.header.arcount = htons (0);
|
||||
+ memcpy (ans, &replacement.header, sizeof (replacement.header));
|
||||
+
|
||||
+ /* Truncate the reply. */
|
||||
+ if (ret <= 0)
|
||||
+ *result = ret;
|
||||
+ else
|
||||
+ *result = after_question - ans + 4;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
|
||||
index 030df0aa90c9f34f..b0fe69b1aa5186a0 100644
|
||||
--- a/resolv/res_debug.c
|
||||
+++ b/resolv/res_debug.c
|
||||
@@ -613,6 +613,7 @@ p_option(u_long option) {
|
||||
case RES_NOTLDQUERY: return "no-tld-query";
|
||||
case RES_NORELOAD: return "no-reload";
|
||||
case RES_TRUSTAD: return "trust-ad";
|
||||
+ case RES_NOAAAA: return "no-aaaa";
|
||||
/* XXX nonreentrant */
|
||||
default: sprintf(nbuf, "?0x%lx?", (u_long)option);
|
||||
return (nbuf);
|
||||
diff --git a/resolv/res_init.c b/resolv/res_init.c
|
||||
index 6b2936eda9618ac9..8bde915903565f60 100644
|
||||
--- a/resolv/res_init.c
|
||||
+++ b/resolv/res_init.c
|
||||
@@ -695,6 +695,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options)
|
||||
{ STRnLEN ("no-reload"), 0, RES_NORELOAD },
|
||||
{ STRnLEN ("use-vc"), 0, RES_USEVC },
|
||||
{ STRnLEN ("trust-ad"), 0, RES_TRUSTAD },
|
||||
+ { STRnLEN ("no-aaaa"), 0, RES_NOAAAA },
|
||||
};
|
||||
#define noptions (sizeof (options) / sizeof (options[0]))
|
||||
for (int i = 0; i < noptions; ++i)
|
||||
diff --git a/resolv/res_query.c b/resolv/res_query.c
|
||||
index 75b0e5f2f7b51eb2..2f3c28cfc8c0d832 100644
|
||||
--- a/resolv/res_query.c
|
||||
+++ b/resolv/res_query.c
|
||||
@@ -204,10 +204,26 @@ __res_context_query (struct resolv_context *ctx, const char *name,
|
||||
free (buf);
|
||||
return (n);
|
||||
}
|
||||
- assert (answerp == NULL || (void *) *answerp == (void *) answer);
|
||||
- n = __res_context_send (ctx, query1, nquery1, query2, nquery2, answer,
|
||||
- anslen, answerp, answerp2, nanswerp2, resplen2,
|
||||
- answerp2_malloced);
|
||||
+
|
||||
+ /* Suppress AAAA lookups if required. __res_handle_no_aaaa
|
||||
+ checks RES_NOAAAA first, so avoids parsing the
|
||||
+ just-generated query packet in most cases. nss_dns avoids
|
||||
+ using T_QUERY_A_AND_AAAA in RES_NOAAAA mode, so there is no
|
||||
+ need to handle it here. */
|
||||
+ if (type == T_AAAA && __res_handle_no_aaaa (ctx, query1, nquery1,
|
||||
+ answer, anslen, &n))
|
||||
+ /* There must be no second query for AAAA queries. The code
|
||||
+ below is still needed to translate NODATA responses. */
|
||||
+ assert (query2 == NULL);
|
||||
+ else
|
||||
+ {
|
||||
+ assert (answerp == NULL || (void *) *answerp == (void *) answer);
|
||||
+ n = __res_context_send (ctx, query1, nquery1, query2, nquery2,
|
||||
+ answer, anslen,
|
||||
+ answerp, answerp2, nanswerp2, resplen2,
|
||||
+ answerp2_malloced);
|
||||
+ }
|
||||
+
|
||||
if (use_malloc)
|
||||
free (buf);
|
||||
if (n < 0) {
|
||||
diff --git a/resolv/res_send.c b/resolv/res_send.c
|
||||
index 9f86f5fe47194887..8ac6a307b40fa2ca 100644
|
||||
--- a/resolv/res_send.c
|
||||
+++ b/resolv/res_send.c
|
||||
@@ -438,8 +438,13 @@ context_send_common (struct resolv_context *ctx,
|
||||
RES_SET_H_ERRNO (&_res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
- int result = __res_context_send (ctx, buf, buflen, NULL, 0, ans, anssiz,
|
||||
- NULL, NULL, NULL, NULL, NULL);
|
||||
+
|
||||
+ int result;
|
||||
+ if (__res_handle_no_aaaa (ctx, buf, buflen, ans, anssiz, &result))
|
||||
+ return result;
|
||||
+
|
||||
+ result = __res_context_send (ctx, buf, buflen, NULL, 0, ans, anssiz,
|
||||
+ NULL, NULL, NULL, NULL, NULL);
|
||||
__resolv_context_put (ctx);
|
||||
return result;
|
||||
}
|
||||
diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h
|
||||
index 216e47ed42076b72..8ab02fc9e648d30f 100644
|
||||
--- a/resolv/resolv-internal.h
|
||||
+++ b/resolv/resolv-internal.h
|
||||
@@ -78,6 +78,14 @@ int __res_context_send (struct resolv_context *, const unsigned char *, int,
|
||||
int *, int *, int *);
|
||||
libc_hidden_proto (__res_context_send)
|
||||
|
||||
+/* Return true if the query has been handled in RES_NOAAAA mode. For
|
||||
+ that, RES_NOAAAA must be active, and the question type must be AAAA.
|
||||
+ The caller is expected to return *RESULT as the return value. */
|
||||
+bool __res_handle_no_aaaa (struct resolv_context *ctx,
|
||||
+ const unsigned char *buf, int buflen,
|
||||
+ unsigned char *ans, int anssiz, int *result)
|
||||
+ attribute_hidden;
|
||||
+
|
||||
/* Internal function similar to res_hostalias. */
|
||||
const char *__res_context_hostalias (struct resolv_context *,
|
||||
const char *, char *, size_t);
|
||||
diff --git a/resolv/resolv.h b/resolv/resolv.h
|
||||
index e7c8d44645912ddf..3a79ffea57a6916f 100644
|
||||
--- a/resolv/resolv.h
|
||||
+++ b/resolv/resolv.h
|
||||
@@ -132,6 +132,7 @@ struct res_sym {
|
||||
as a TLD. */
|
||||
#define RES_NORELOAD 0x02000000 /* No automatic configuration reload. */
|
||||
#define RES_TRUSTAD 0x04000000 /* Request AD bit, keep it in responses. */
|
||||
+#define RES_NOAAAA 0x08000000 /* Suppress AAAA queries. */
|
||||
|
||||
#define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH)
|
||||
|
||||
diff --git a/resolv/tst-resolv-noaaaa.c b/resolv/tst-resolv-noaaaa.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..56b25f88a58ad286
|
||||
--- /dev/null
|
||||
+++ b/resolv/tst-resolv-noaaaa.c
|
||||
@@ -0,0 +1,533 @@
|
||||
+/* Test the RES_NOAAAA resolver option.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <netdb.h>
|
||||
+#include <resolv.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/check_nss.h>
|
||||
+#include <support/resolv_test.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+/* Used to keep track of the number of queries. */
|
||||
+static volatile unsigned int queries;
|
||||
+
|
||||
+static void
|
||||
+response (const struct resolv_response_context *ctx,
|
||||
+ struct resolv_response_builder *b,
|
||||
+ const char *qname, uint16_t qclass, uint16_t qtype)
|
||||
+{
|
||||
+ /* Each test should only send one query. */
|
||||
+ ++queries;
|
||||
+ TEST_COMPARE (queries, 1);
|
||||
+
|
||||
+ /* AAAA queries are supposed to be disabled. */
|
||||
+ TEST_VERIFY (qtype != T_AAAA);
|
||||
+ TEST_COMPARE (qclass, C_IN);
|
||||
+
|
||||
+ /* The only other query type besides A is PTR. */
|
||||
+ if (qtype != T_A)
|
||||
+ TEST_COMPARE (qtype, T_PTR);
|
||||
+
|
||||
+ int an, ns, ar;
|
||||
+ char *tail;
|
||||
+ if (sscanf (qname, "an%d.ns%d.ar%d.%ms", &an, &ns, &ar, &tail) != 4)
|
||||
+ FAIL_EXIT1 ("invalid QNAME: %s\n", qname);
|
||||
+ TEST_COMPARE_STRING (tail, "example");
|
||||
+ free (tail);
|
||||
+
|
||||
+ if (an < 0 || ns < 0 || ar < 0)
|
||||
+ {
|
||||
+ struct resolv_response_flags flags = { .rcode = NXDOMAIN, };
|
||||
+ resolv_response_init (b, flags);
|
||||
+ resolv_response_add_question (b, qname, qclass, qtype);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ struct resolv_response_flags flags = {};
|
||||
+ resolv_response_init (b, flags);
|
||||
+ resolv_response_add_question (b, qname, qclass, qtype);
|
||||
+
|
||||
+ resolv_response_section (b, ns_s_an);
|
||||
+ for (int i = 0; i < an; ++i)
|
||||
+ {
|
||||
+ resolv_response_open_record (b, qname, qclass, qtype, 60);
|
||||
+ switch (qtype)
|
||||
+ {
|
||||
+ case T_A:
|
||||
+ char ipv4[4] = {192, 0, 2, i + 1};
|
||||
+ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
|
||||
+ break;
|
||||
+
|
||||
+ case T_PTR:
|
||||
+ char *name = xasprintf ("ptr-%d", i);
|
||||
+ resolv_response_add_name (b, name);
|
||||
+ free (name);
|
||||
+ break;
|
||||
+ }
|
||||
+ resolv_response_close_record (b);
|
||||
+ }
|
||||
+
|
||||
+ resolv_response_section (b, ns_s_ns);
|
||||
+ for (int i = 0; i < ns; ++i)
|
||||
+ {
|
||||
+ resolv_response_open_record (b, qname, qclass, T_NS, 60);
|
||||
+ char *name = xasprintf ("ns%d.example.net", i);
|
||||
+ resolv_response_add_name (b, name);
|
||||
+ free (name);
|
||||
+ resolv_response_close_record (b);
|
||||
+ }
|
||||
+
|
||||
+ resolv_response_section (b, ns_s_ar);
|
||||
+ int addr = 1;
|
||||
+ for (int i = 0; i < ns; ++i)
|
||||
+ {
|
||||
+ char *name = xasprintf ("ns%d.example.net", i);
|
||||
+ for (int j = 0; j < ar; ++j)
|
||||
+ {
|
||||
+ resolv_response_open_record (b, name, qclass, T_A, 60);
|
||||
+ char ipv4[4] = {192, 0, 2, addr};
|
||||
+ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
|
||||
+ resolv_response_close_record (b);
|
||||
+
|
||||
+ resolv_response_open_record (b, name, qclass, T_AAAA, 60);
|
||||
+ char ipv6[16]
|
||||
+ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, addr};
|
||||
+ resolv_response_add_data (b, &ipv6, sizeof (ipv6));
|
||||
+ resolv_response_close_record (b);
|
||||
+
|
||||
+ ++addr;
|
||||
+ }
|
||||
+ free (name);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Number of modes. Lowest bit encodes *n* function vs implicit _res
|
||||
+ argument. The mode numbers themselves are arbitrary. */
|
||||
+enum { mode_count = 8 };
|
||||
+
|
||||
+/* res_send-like modes do not perform error translation. */
|
||||
+enum { first_send_mode = 6 };
|
||||
+
|
||||
+static int
|
||||
+libresolv_query (unsigned int mode, const char *qname, uint16_t qtype,
|
||||
+ unsigned char *buf, size_t buflen)
|
||||
+{
|
||||
+ int saved_errno = errno;
|
||||
+
|
||||
+ TEST_VERIFY_EXIT (mode < mode_count);
|
||||
+
|
||||
+ switch (mode)
|
||||
+ {
|
||||
+ case 0:
|
||||
+ return res_query (qname, C_IN, qtype, buf, buflen);
|
||||
+ case 1:
|
||||
+ return res_nquery (&_res, qname, C_IN, qtype, buf, buflen);
|
||||
+ case 2:
|
||||
+ return res_search (qname, C_IN, qtype, buf, buflen);
|
||||
+ case 3:
|
||||
+ return res_nsearch (&_res, qname, C_IN, qtype, buf, buflen);
|
||||
+ case 4:
|
||||
+ return res_querydomain (qname, "", C_IN, qtype, buf, buflen);
|
||||
+ case 5:
|
||||
+ return res_nquerydomain (&_res, qname, "", C_IN, qtype, buf, buflen);
|
||||
+ case 6:
|
||||
+ {
|
||||
+ unsigned char querybuf[512];
|
||||
+ int ret = res_mkquery (QUERY, qname, C_IN, qtype,
|
||||
+ NULL, 0, NULL, querybuf, sizeof (querybuf));
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ errno = saved_errno;
|
||||
+ return res_send (querybuf, ret, buf, buflen);
|
||||
+ }
|
||||
+ case 7:
|
||||
+ {
|
||||
+ unsigned char querybuf[512];
|
||||
+ int ret = res_nmkquery (&_res, QUERY, qname, C_IN, qtype,
|
||||
+ NULL, 0, NULL, querybuf, sizeof (querybuf));
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ errno = saved_errno;
|
||||
+ return res_nsend (&_res, querybuf, ret, buf, buflen);
|
||||
+ }
|
||||
+ }
|
||||
+ __builtin_unreachable ();
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct resolv_test *obj = resolv_test_start
|
||||
+ ((struct resolv_redirect_config)
|
||||
+ {
|
||||
+ .response_callback = response
|
||||
+ });
|
||||
+
|
||||
+ _res.options |= RES_NOAAAA;
|
||||
+
|
||||
+ check_hostent ("an1.ns2.ar1.example",
|
||||
+ gethostbyname ("an1.ns2.ar1.example"),
|
||||
+ "name: an1.ns2.ar1.example\n"
|
||||
+ "address: 192.0.2.1\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an0.ns2.ar1.example",
|
||||
+ gethostbyname ("an0.ns2.ar1.example"),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an-1.ns2.ar1.example",
|
||||
+ gethostbyname ("an-1.ns2.ar1.example"),
|
||||
+ "error: HOST_NOT_FOUND\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ check_hostent ("an1.ns2.ar1.example AF_INET",
|
||||
+ gethostbyname2 ("an1.ns2.ar1.example", AF_INET),
|
||||
+ "name: an1.ns2.ar1.example\n"
|
||||
+ "address: 192.0.2.1\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an0.ns2.ar1.example AF_INET",
|
||||
+ gethostbyname2 ("an0.ns2.ar1.example", AF_INET),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an-1.ns2.ar1.example AF_INET",
|
||||
+ gethostbyname2 ("an-1.ns2.ar1.example", AF_INET),
|
||||
+ "error: HOST_NOT_FOUND\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ check_hostent ("an1.ns2.ar1.example AF_INET6",
|
||||
+ gethostbyname2 ("an1.ns2.ar1.example", AF_INET6),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an0.ns2.ar1.example AF_INET6",
|
||||
+ gethostbyname2 ("an0.ns2.ar1.example", AF_INET6),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an-1.ns2.ar1.example AF_INET6",
|
||||
+ gethostbyname2 ("an-1.ns2.ar1.example", AF_INET6),
|
||||
+ "error: HOST_NOT_FOUND\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* Multiple addresses. */
|
||||
+ check_hostent ("an2.ns0.ar0.example",
|
||||
+ gethostbyname ("an2.ns0.ar0.example"),
|
||||
+ "name: an2.ns0.ar0.example\n"
|
||||
+ "address: 192.0.2.1\n"
|
||||
+ "address: 192.0.2.2\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an2.ns0.ar0.example AF_INET6",
|
||||
+ gethostbyname2 ("an2.ns0.ar0.example", AF_INET6),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* getaddrinfo checks with one address. */
|
||||
+ struct addrinfo *ai;
|
||||
+ int ret;
|
||||
+ ret = getaddrinfo ("an1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an1.ns2.ar1.example (AF_INET)", ai, ret,
|
||||
+ "address: STREAM/TCP 192.0.2.1 80\n");
|
||||
+ freeaddrinfo (ai);
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET6,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an1.ns2.ar1.example (AF_INET6)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_UNSPEC,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an1.ns2.ar1.example (AF_UNSPEC)", ai, ret,
|
||||
+ "address: STREAM/TCP 192.0.2.1 80\n");
|
||||
+ freeaddrinfo (ai);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* getaddrinfo checks with three addresses. */
|
||||
+ ret = getaddrinfo ("an3.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an3.ns2.ar1.example (AF_INET)", ai, ret,
|
||||
+ "address: STREAM/TCP 192.0.2.1 80\n"
|
||||
+ "address: STREAM/TCP 192.0.2.2 80\n"
|
||||
+ "address: STREAM/TCP 192.0.2.3 80\n");
|
||||
+ freeaddrinfo (ai);
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an3.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET6,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an3.ns2.ar1.example (AF_INET6)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an3.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_UNSPEC,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an3.ns2.ar1.example (AF_UNSPEC)", ai, ret,
|
||||
+ "address: STREAM/TCP 192.0.2.1 80\n"
|
||||
+ "address: STREAM/TCP 192.0.2.2 80\n"
|
||||
+ "address: STREAM/TCP 192.0.2.3 80\n");
|
||||
+ freeaddrinfo (ai);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* getaddrinfo checks with no address. */
|
||||
+ ret = getaddrinfo ("an0.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an0.ns2.ar1.example (AF_INET)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an0.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET6,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an0.ns2.ar1.example (AF_INET6)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an0.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_UNSPEC,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an-1.ns2.ar1.example (AF_UNSPEC)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* getaddrinfo checks with NXDOMAIN. */
|
||||
+ ret = getaddrinfo ("an-1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an-1.ns2.ar1.example (AF_INET)", ai, ret,
|
||||
+ "error: Name or service not known\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an-1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET6,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an-1.ns2.ar1.example (AF_INET6)", ai, ret,
|
||||
+ "error: Name or service not known\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an-1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_UNSPEC,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an-1.ns2.ar1.example (AF_UNSPEC)", ai, ret,
|
||||
+ "error: Name or service not known\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ for (unsigned int mode = 0; mode < mode_count; ++mode)
|
||||
+ {
|
||||
+ unsigned char *buf;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Response for A. */
|
||||
+ buf = malloc (512);
|
||||
+ ret = libresolv_query (mode, "an1.ns2.ar1.example", T_A, buf, 512);
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an1.ns2.ar1.example\n"
|
||||
+ "address: 192.0.2.1\n");
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NODATA response for A. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an0.ns2.ar1.example", T_A, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, NO_ADDRESS);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an0.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NXDOMAIN response for A. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_A, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an-1.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* Response for PTR. */
|
||||
+ buf = malloc (512);
|
||||
+ ret = libresolv_query (mode, "an1.ns2.ar1.example", T_PTR, buf, 512);
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret,
|
||||
+ "name: an1.ns2.ar1.example\n"
|
||||
+ "data: an1.ns2.ar1.example PTR ptr-0\n");
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NODATA response for PTR. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an0.ns2.ar1.example", T_PTR, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, NO_ADDRESS);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret,
|
||||
+ "name: an0.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NXDOMAIN response for PTR. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_PTR, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret,
|
||||
+ "name: an-1.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NODATA response for AAAA. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an1.ns2.ar1.example", T_AAAA, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, NO_ADDRESS);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an1.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NODATA response for AAAA (original is already NODATA). */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an0.ns2.ar1.example", T_AAAA, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, NO_ADDRESS);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, 0);
|
||||
+ check_dns_packet ("an0.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an0.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NXDOMAIN response. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_AAAA, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN);
|
||||
+ check_dns_packet ("an-1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an-1.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+ }
|
||||
+
|
||||
+ resolv_test_end (obj);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c
|
||||
index c87596762fcb23b1..28ed9c2eb150532d 100644
|
||||
--- a/resolv/tst-resolv-res_init-skeleton.c
|
||||
+++ b/resolv/tst-resolv-res_init-skeleton.c
|
||||
@@ -128,6 +128,7 @@ print_resp (FILE *fp, res_state resp)
|
||||
print_option_flag (fp, &options, RES_NOTLDQUERY, "no-tld-query");
|
||||
print_option_flag (fp, &options, RES_NORELOAD, "no-reload");
|
||||
print_option_flag (fp, &options, RES_TRUSTAD, "trust-ad");
|
||||
+ print_option_flag (fp, &options, RES_NOAAAA, "no-aaaa");
|
||||
fputc ('\n', fp);
|
||||
if (options != 0)
|
||||
fprintf (fp, "; error: unresolved option bits: 0x%x\n", options);
|
||||
@@ -721,6 +722,15 @@ struct test_case test_cases[] =
|
||||
"nameserver 192.0.2.1\n"
|
||||
"; nameserver[0]: [192.0.2.1]:53\n"
|
||||
},
|
||||
+ {.name = "no-aaaa flag",
|
||||
+ .conf = "options no-aaaa\n"
|
||||
+ "nameserver 192.0.2.1\n",
|
||||
+ .expected = "options no-aaaa\n"
|
||||
+ "search example.com\n"
|
||||
+ "; search[0]: example.com\n"
|
||||
+ "nameserver 192.0.2.1\n"
|
||||
+ "; nameserver[0]: [192.0.2.1]:53\n"
|
||||
+ },
|
||||
{ NULL }
|
||||
};
|
||||
|
@ -1,16 +0,0 @@
|
||||
Adjust for disabled-by default rseq in downstream: tst-rseq needs to enable
|
||||
rseq using the tunable, tst-rseq-disable should use the default.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index 856a9d58cef6a879..23a577e263d6dc22 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -233,7 +233,7 @@ $(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
< /dev/null > $@ 2>&1; $(evaluate-test)
|
||||
$(objpfx)tst-mman-consts.out: $(sysdeps-linux-python-deps)
|
||||
|
||||
-tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0
|
||||
+tst-rseq-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=1
|
||||
|
||||
endif # $(subdir) == misc
|
||||
|
32
SOURCES/glibc-upstream-2.34-108.patch
Normal file
32
SOURCES/glibc-upstream-2.34-108.patch
Normal file
@ -0,0 +1,32 @@
|
||||
commit 0351c75c5f94134fcec0e778e8cf86d149f8bbfb
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Feb 3 16:52:52 2022 -0300
|
||||
|
||||
linux: Fix missing __convert_scm_timestamps (BZ #28860)
|
||||
|
||||
Commit 948ce73b31 made recvmsg/recvmmsg to always call
|
||||
__convert_scm_timestamps for 64 bit time_t symbol, so adjust it to
|
||||
always build it for __TIMESIZE != 64.
|
||||
|
||||
It fixes build for architecture with 32 bit time_t support when
|
||||
configured with minimum kernel of 5.1.
|
||||
|
||||
(cherry-picked from 798d716df71fb23dc89d1d5dba1fc26a1b5c0024)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
|
||||
index 5d3c4199e0b32944..953ce97bd2e03849 100644
|
||||
--- a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
|
||||
+++ b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
|
||||
@@ -16,9 +16,10 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#include <kernel-features.h>
|
||||
+#include <bits/wordsize.h>
|
||||
+#include <bits/timesize.h>
|
||||
|
||||
-#ifndef __ASSUME_TIME64_SYSCALLS
|
||||
+#if __TIMESIZE != 64
|
||||
# include <stdint.h>
|
||||
# include <string.h>
|
||||
# include <sys/socket.h>
|
192
SOURCES/glibc-upstream-2.34-110.patch
Normal file
192
SOURCES/glibc-upstream-2.34-110.patch
Normal file
@ -0,0 +1,192 @@
|
||||
commit 007e054d786be340699c634e3a3b30ab1fde1a7a
|
||||
Author: Dmitry V. Levin <ldv@altlinux.org>
|
||||
Date: Sat Feb 5 08:00:00 2022 +0000
|
||||
|
||||
linux: fix accuracy of get_nprocs and get_nprocs_conf [BZ #28865]
|
||||
|
||||
get_nprocs() and get_nprocs_conf() use various methods to obtain an
|
||||
accurate number of processors. Re-introduce __get_nprocs_sched() as
|
||||
a source of information, and fix the order in which these methods are
|
||||
used to return the most accurate information. The primary source of
|
||||
information used in both functions remains unchanged.
|
||||
|
||||
This also changes __get_nprocs_sched() error return value from 2 to 0,
|
||||
but all its users are already prepared to handle that.
|
||||
|
||||
Old fallback order:
|
||||
get_nprocs:
|
||||
/sys/devices/system/cpu/online -> /proc/stat -> 2
|
||||
get_nprocs_conf:
|
||||
/sys/devices/system/cpu/ -> /proc/stat -> 2
|
||||
|
||||
New fallback order:
|
||||
get_nprocs:
|
||||
/sys/devices/system/cpu/online -> /proc/stat -> sched_getaffinity -> 2
|
||||
get_nprocs_conf:
|
||||
/sys/devices/system/cpu/ -> /proc/stat -> sched_getaffinity -> 2
|
||||
|
||||
Fixes: 342298278e ("linux: Revert the use of sched_getaffinity on get_nproc")
|
||||
Closes: BZ #28865
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
(cherry picked from commit e1d32b836410767270a3adf1f82b1a47e6e4cd51)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
|
||||
index 7babd947aa902e77..327802b14c7326a3 100644
|
||||
--- a/sysdeps/unix/sysv/linux/getsysstats.c
|
||||
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
|
||||
@@ -51,9 +51,8 @@ __get_nprocs_sched (void)
|
||||
is an arbitrary values assuming such systems should be rare and there
|
||||
is no offline cpus. */
|
||||
return max_num_cpus;
|
||||
- /* Some other error. 2 is conservative (not a uniprocessor system, so
|
||||
- atomics are needed). */
|
||||
- return 2;
|
||||
+ /* Some other error. */
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -109,22 +108,19 @@ next_line (int fd, char *const buffer, char **cp, char **re,
|
||||
}
|
||||
|
||||
static int
|
||||
-get_nproc_stat (char *buffer, size_t buffer_size)
|
||||
+get_nproc_stat (void)
|
||||
{
|
||||
+ enum { buffer_size = 1024 };
|
||||
+ char buffer[buffer_size];
|
||||
char *buffer_end = buffer + buffer_size;
|
||||
char *cp = buffer_end;
|
||||
char *re = buffer_end;
|
||||
-
|
||||
- /* Default to an SMP system in case we cannot obtain an accurate
|
||||
- number. */
|
||||
- int result = 2;
|
||||
+ int result = 0;
|
||||
|
||||
const int flags = O_RDONLY | O_CLOEXEC;
|
||||
int fd = __open_nocancel ("/proc/stat", flags);
|
||||
if (fd != -1)
|
||||
{
|
||||
- result = 0;
|
||||
-
|
||||
char *l;
|
||||
while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL)
|
||||
/* The current format of /proc/stat has all the cpu* entries
|
||||
@@ -140,8 +136,8 @@ get_nproc_stat (char *buffer, size_t buffer_size)
|
||||
return result;
|
||||
}
|
||||
|
||||
-int
|
||||
-__get_nprocs (void)
|
||||
+static int
|
||||
+get_nprocs_cpu_online (void)
|
||||
{
|
||||
enum { buffer_size = 1024 };
|
||||
char buffer[buffer_size];
|
||||
@@ -180,7 +176,8 @@ __get_nprocs (void)
|
||||
}
|
||||
}
|
||||
|
||||
- result += m - n + 1;
|
||||
+ if (m >= n)
|
||||
+ result += m - n + 1;
|
||||
|
||||
l = endp;
|
||||
if (l < re && *l == ',')
|
||||
@@ -189,28 +186,18 @@ __get_nprocs (void)
|
||||
while (l < re && *l != '\n');
|
||||
|
||||
__close_nocancel_nostatus (fd);
|
||||
-
|
||||
- if (result > 0)
|
||||
- return result;
|
||||
}
|
||||
|
||||
- return get_nproc_stat (buffer, buffer_size);
|
||||
+ return result;
|
||||
}
|
||||
-libc_hidden_def (__get_nprocs)
|
||||
-weak_alias (__get_nprocs, get_nprocs)
|
||||
-
|
||||
|
||||
-/* On some architectures it is possible to distinguish between configured
|
||||
- and active cpus. */
|
||||
-int
|
||||
-__get_nprocs_conf (void)
|
||||
+static int
|
||||
+get_nprocs_cpu (void)
|
||||
{
|
||||
- /* Try to use the sysfs filesystem. It has actual information about
|
||||
- online processors. */
|
||||
+ int count = 0;
|
||||
DIR *dir = __opendir ("/sys/devices/system/cpu");
|
||||
if (dir != NULL)
|
||||
{
|
||||
- int count = 0;
|
||||
struct dirent64 *d;
|
||||
|
||||
while ((d = __readdir64 (dir)) != NULL)
|
||||
@@ -225,12 +212,57 @@ __get_nprocs_conf (void)
|
||||
|
||||
__closedir (dir);
|
||||
|
||||
- return count;
|
||||
}
|
||||
+ return count;
|
||||
+}
|
||||
|
||||
- enum { buffer_size = 1024 };
|
||||
- char buffer[buffer_size];
|
||||
- return get_nproc_stat (buffer, buffer_size);
|
||||
+static int
|
||||
+get_nprocs_fallback (void)
|
||||
+{
|
||||
+ int result;
|
||||
+
|
||||
+ /* Try /proc/stat first. */
|
||||
+ result = get_nproc_stat ();
|
||||
+ if (result != 0)
|
||||
+ return result;
|
||||
+
|
||||
+ /* Try sched_getaffinity. */
|
||||
+ result = __get_nprocs_sched ();
|
||||
+ if (result != 0)
|
||||
+ return result;
|
||||
+
|
||||
+ /* We failed to obtain an accurate number. Be conservative: return
|
||||
+ the smallest number meaning that this is not a uniprocessor system,
|
||||
+ so atomics are needed. */
|
||||
+ return 2;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+__get_nprocs (void)
|
||||
+{
|
||||
+ /* Try /sys/devices/system/cpu/online first. */
|
||||
+ int result = get_nprocs_cpu_online ();
|
||||
+ if (result != 0)
|
||||
+ return result;
|
||||
+
|
||||
+ /* Fall back to /proc/stat and sched_getaffinity. */
|
||||
+ return get_nprocs_fallback ();
|
||||
+}
|
||||
+libc_hidden_def (__get_nprocs)
|
||||
+weak_alias (__get_nprocs, get_nprocs)
|
||||
+
|
||||
+/* On some architectures it is possible to distinguish between configured
|
||||
+ and active cpus. */
|
||||
+int
|
||||
+__get_nprocs_conf (void)
|
||||
+{
|
||||
+ /* Try /sys/devices/system/cpu/ first. */
|
||||
+ int result = get_nprocs_cpu ();
|
||||
+ if (result != 0)
|
||||
+ return result;
|
||||
+
|
||||
+ /* Fall back to /proc/stat and sched_getaffinity. */
|
||||
+ return get_nprocs_fallback ();
|
||||
}
|
||||
libc_hidden_def (__get_nprocs_conf)
|
||||
weak_alias (__get_nprocs_conf, get_nprocs_conf)
|
60
SOURCES/glibc-upstream-2.34-111.patch
Normal file
60
SOURCES/glibc-upstream-2.34-111.patch
Normal file
@ -0,0 +1,60 @@
|
||||
commit 04d60ce0f21ffe2a4add148cb37a1942dbad64e2
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Thu Feb 17 08:10:35 2022 -0800
|
||||
|
||||
string: Add a testcase for wcsncmp with SIZE_MAX [BZ #28755]
|
||||
|
||||
Verify that wcsncmp (L("abc"), L("abd"), SIZE_MAX) == 0. The new test
|
||||
fails without
|
||||
|
||||
commit ddf0992cf57a93200e0c782e2a94d0733a5a0b87
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Sun Jan 9 16:02:21 2022 -0600
|
||||
|
||||
x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755]
|
||||
|
||||
and
|
||||
|
||||
commit 7e08db3359c86c94918feb33a1182cd0ff3bb10b
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Sun Jan 9 16:02:28 2022 -0600
|
||||
|
||||
x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755]
|
||||
|
||||
This is for BZ #28755.
|
||||
|
||||
Reviewed-by: Sunil K Pandey <skpgkp2@gmail.com>
|
||||
|
||||
(cherry picked from commit aa5a720056d37cf24924c138a3dbe6dace98e97c)
|
||||
|
||||
diff --git a/string/test-strncmp.c b/string/test-strncmp.c
|
||||
index 10b34de8d2acb2a1..97e831d88fd24316 100644
|
||||
--- a/string/test-strncmp.c
|
||||
+++ b/string/test-strncmp.c
|
||||
@@ -435,6 +435,18 @@ check3 (void)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+check4 (void)
|
||||
+{
|
||||
+ const CHAR *s1 = L ("abc");
|
||||
+ CHAR *s2 = STRDUP (s1);
|
||||
+
|
||||
+ FOR_EACH_IMPL (impl, 0)
|
||||
+ check_result (impl, s1, s2, SIZE_MAX, 0);
|
||||
+
|
||||
+ free (s2);
|
||||
+}
|
||||
+
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
@@ -445,6 +457,7 @@ test_main (void)
|
||||
check1 ();
|
||||
check2 ();
|
||||
check3 ();
|
||||
+ check4 ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
120
SOURCES/glibc-upstream-2.34-112.patch
Normal file
120
SOURCES/glibc-upstream-2.34-112.patch
Normal file
@ -0,0 +1,120 @@
|
||||
commit 38e0d2479413ccdbc02b4c9e9e246eca31e956c9
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Tue Feb 15 08:18:15 2022 -0600
|
||||
|
||||
x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #28896]
|
||||
|
||||
In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would
|
||||
call strcmp-avx2 and wcscmp-avx2 respectively. This would have
|
||||
not checks around vzeroupper and would trigger spurious
|
||||
aborts. This commit fixes that.
|
||||
|
||||
test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on
|
||||
AVX2 machines with and without RTM.
|
||||
|
||||
Co-authored-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
(cherry picked from commit c6272098323153db373f2986c67786ea8c85f1cf)
|
||||
|
||||
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
|
||||
index 36ca1a7126047b86..af934d6ccf1fa337 100644
|
||||
--- a/sysdeps/x86/Makefile
|
||||
+++ b/sysdeps/x86/Makefile
|
||||
@@ -105,7 +105,7 @@ CFLAGS-tst-memset-rtm.c += -mrtm
|
||||
CFLAGS-tst-strchr-rtm.c += -mrtm
|
||||
CFLAGS-tst-strcpy-rtm.c += -mrtm
|
||||
CFLAGS-tst-strlen-rtm.c += -mrtm
|
||||
-CFLAGS-tst-strncmp-rtm.c += -mrtm
|
||||
+CFLAGS-tst-strncmp-rtm.c += -mrtm -Wno-error
|
||||
CFLAGS-tst-strrchr-rtm.c += -mrtm
|
||||
endif
|
||||
|
||||
diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
index 236ad951b5b59cd1..4d0004b58aae428d 100644
|
||||
--- a/sysdeps/x86/tst-strncmp-rtm.c
|
||||
+++ b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
@@ -16,6 +16,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <stdint.h>
|
||||
#include <tst-string-rtm.h>
|
||||
|
||||
#define LOOP 3000
|
||||
@@ -45,8 +46,22 @@ function (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+__attribute__ ((noinline, noclone))
|
||||
+static int
|
||||
+function_overflow (void)
|
||||
+{
|
||||
+ if (strncmp (string1, string2, SIZE_MAX) == 0)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
- return do_test_1 ("strncmp", LOOP, prepare, function);
|
||||
+ int status = do_test_1 ("strncmp", LOOP, prepare, function);
|
||||
+ if (status != EXIT_SUCCESS)
|
||||
+ return status;
|
||||
+ status = do_test_1 ("strncmp", LOOP, prepare, function_overflow);
|
||||
+ return status;
|
||||
}
|
||||
diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
|
||||
index 3dfcb1bf803cf9ec..fa70c994fc25dfd8 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S
|
||||
@@ -95,7 +95,7 @@ ENTRY (STRCMP)
|
||||
length to bound a valid memory region. In these cases just use
|
||||
'wcscmp'. */
|
||||
shrq $56, %rcx
|
||||
- jnz __wcscmp_avx2
|
||||
+ jnz OVERFLOW_STRCMP
|
||||
# endif
|
||||
/* Convert units: from wide to byte char. */
|
||||
shl $2, %RDX_LP
|
||||
diff --git a/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S b/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
|
||||
index 37d1224bb9b7056b..68bad365ba728eec 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
|
||||
@@ -1,3 +1,4 @@
|
||||
#define STRCMP __strncmp_avx2_rtm
|
||||
#define USE_AS_STRNCMP 1
|
||||
+#define OVERFLOW_STRCMP __strcmp_avx2_rtm
|
||||
#include "strcmp-avx2-rtm.S"
|
||||
diff --git a/sysdeps/x86_64/multiarch/strncmp-avx2.S b/sysdeps/x86_64/multiarch/strncmp-avx2.S
|
||||
index 1678bcc235a4bc6a..f138e9f1fdcf277c 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strncmp-avx2.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strncmp-avx2.S
|
||||
@@ -1,3 +1,4 @@
|
||||
#define STRCMP __strncmp_avx2
|
||||
#define USE_AS_STRNCMP 1
|
||||
+#define OVERFLOW_STRCMP __strcmp_avx2
|
||||
#include "strcmp-avx2.S"
|
||||
diff --git a/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S b/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
|
||||
index 4e88c70cc696b82d..f467582cbedd4535 100644
|
||||
--- a/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
|
||||
+++ b/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
|
||||
@@ -1,5 +1,5 @@
|
||||
#define STRCMP __wcsncmp_avx2_rtm
|
||||
#define USE_AS_STRNCMP 1
|
||||
#define USE_AS_WCSCMP 1
|
||||
-
|
||||
+#define OVERFLOW_STRCMP __wcscmp_avx2_rtm
|
||||
#include "strcmp-avx2-rtm.S"
|
||||
diff --git a/sysdeps/x86_64/multiarch/wcsncmp-avx2.S b/sysdeps/x86_64/multiarch/wcsncmp-avx2.S
|
||||
index 4fa1de4d3f1f97ff..e9ede522b8bde27d 100644
|
||||
--- a/sysdeps/x86_64/multiarch/wcsncmp-avx2.S
|
||||
+++ b/sysdeps/x86_64/multiarch/wcsncmp-avx2.S
|
||||
@@ -1,5 +1,5 @@
|
||||
#define STRCMP __wcsncmp_avx2
|
||||
#define USE_AS_STRNCMP 1
|
||||
#define USE_AS_WCSCMP 1
|
||||
-
|
||||
+#define OVERFLOW_STRCMP __wcscmp_avx2
|
||||
#include "strcmp-avx2.S"
|
139
SOURCES/glibc-upstream-2.34-113.patch
Normal file
139
SOURCES/glibc-upstream-2.34-113.patch
Normal file
@ -0,0 +1,139 @@
|
||||
commit d093b677c36ef4b360bf30483b68b95d9f0ad1d2
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Fri Feb 18 14:19:15 2022 -0600
|
||||
|
||||
x86: Test wcscmp RTM in the wcsncmp overflow case [BZ #28896]
|
||||
|
||||
In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would
|
||||
call strcmp-avx2 and wcscmp-avx2 respectively. This would have
|
||||
not checks around vzeroupper and would trigger spurious
|
||||
aborts. This commit fixes that.
|
||||
|
||||
test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on
|
||||
AVX2 machines with and without RTM.
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
(cherry picked from commit 7835d611af0854e69a0c71e3806f8fe379282d6f)
|
||||
|
||||
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
|
||||
index af934d6ccf1fa337..cd94e683afd5b4a4 100644
|
||||
--- a/sysdeps/x86/Makefile
|
||||
+++ b/sysdeps/x86/Makefile
|
||||
@@ -95,7 +95,9 @@ tests += \
|
||||
tst-strcpy-rtm \
|
||||
tst-strlen-rtm \
|
||||
tst-strncmp-rtm \
|
||||
- tst-strrchr-rtm
|
||||
+ tst-strrchr-rtm \
|
||||
+ tst-wcsncmp-rtm \
|
||||
+# tests
|
||||
|
||||
CFLAGS-tst-memchr-rtm.c += -mrtm
|
||||
CFLAGS-tst-memcmp-rtm.c += -mrtm
|
||||
@@ -107,6 +109,7 @@ CFLAGS-tst-strcpy-rtm.c += -mrtm
|
||||
CFLAGS-tst-strlen-rtm.c += -mrtm
|
||||
CFLAGS-tst-strncmp-rtm.c += -mrtm -Wno-error
|
||||
CFLAGS-tst-strrchr-rtm.c += -mrtm
|
||||
+CFLAGS-tst-wcsncmp-rtm.c += -mrtm -Wno-error
|
||||
endif
|
||||
|
||||
ifneq ($(enable-cet),no)
|
||||
diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
index 4d0004b58aae428d..4e9f094f39c72f67 100644
|
||||
--- a/sysdeps/x86/tst-strncmp-rtm.c
|
||||
+++ b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
@@ -19,18 +19,32 @@
|
||||
#include <stdint.h>
|
||||
#include <tst-string-rtm.h>
|
||||
|
||||
+#ifdef WIDE
|
||||
+# define CHAR wchar_t
|
||||
+# define MEMSET wmemset
|
||||
+# define STRNCMP wcsncmp
|
||||
+# define TEST_NAME wcsncmp
|
||||
+#else /* !WIDE */
|
||||
+# define CHAR char
|
||||
+# define MEMSET memset
|
||||
+# define STRNCMP strncmp
|
||||
+# define TEST_NAME strncmp
|
||||
+#endif /* !WIDE */
|
||||
+
|
||||
+
|
||||
+
|
||||
#define LOOP 3000
|
||||
#define STRING_SIZE 1024
|
||||
-char string1[STRING_SIZE];
|
||||
-char string2[STRING_SIZE];
|
||||
+CHAR string1[STRING_SIZE];
|
||||
+CHAR string2[STRING_SIZE];
|
||||
|
||||
__attribute__ ((noinline, noclone))
|
||||
static int
|
||||
prepare (void)
|
||||
{
|
||||
- memset (string1, 'a', STRING_SIZE - 1);
|
||||
- memset (string2, 'a', STRING_SIZE - 1);
|
||||
- if (strncmp (string1, string2, STRING_SIZE) == 0)
|
||||
+ MEMSET (string1, 'a', STRING_SIZE - 1);
|
||||
+ MEMSET (string2, 'a', STRING_SIZE - 1);
|
||||
+ if (STRNCMP (string1, string2, STRING_SIZE) == 0)
|
||||
return EXIT_SUCCESS;
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
@@ -40,7 +54,7 @@ __attribute__ ((noinline, noclone))
|
||||
static int
|
||||
function (void)
|
||||
{
|
||||
- if (strncmp (string1, string2, STRING_SIZE) == 0)
|
||||
+ if (STRNCMP (string1, string2, STRING_SIZE) == 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@@ -50,7 +64,7 @@ __attribute__ ((noinline, noclone))
|
||||
static int
|
||||
function_overflow (void)
|
||||
{
|
||||
- if (strncmp (string1, string2, SIZE_MAX) == 0)
|
||||
+ if (STRNCMP (string1, string2, SIZE_MAX) == 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@@ -59,9 +73,9 @@ function_overflow (void)
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
- int status = do_test_1 ("strncmp", LOOP, prepare, function);
|
||||
+ int status = do_test_1 (TEST_NAME, LOOP, prepare, function);
|
||||
if (status != EXIT_SUCCESS)
|
||||
return status;
|
||||
- status = do_test_1 ("strncmp", LOOP, prepare, function_overflow);
|
||||
+ status = do_test_1 (TEST_NAME, LOOP, prepare, function_overflow);
|
||||
return status;
|
||||
}
|
||||
diff --git a/sysdeps/x86/tst-wcsncmp-rtm.c b/sysdeps/x86/tst-wcsncmp-rtm.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..bad3b863782c5e56
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/x86/tst-wcsncmp-rtm.c
|
||||
@@ -0,0 +1,21 @@
|
||||
+/* Test case for wcsncmp inside a transactionally executing RTM region.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#define WIDE 1
|
||||
+#include <wchar.h>
|
||||
+#include "tst-strncmp-rtm.c"
|
32
SOURCES/glibc-upstream-2.34-114.patch
Normal file
32
SOURCES/glibc-upstream-2.34-114.patch
Normal file
@ -0,0 +1,32 @@
|
||||
commit 15b00d2af0e56dcc8c244a36d6872d301b0c7185
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Fri Feb 18 17:00:25 2022 -0600
|
||||
|
||||
x86: Fix TEST_NAME to make it a string in tst-strncmp-rtm.c
|
||||
|
||||
Previously TEST_NAME was passing a function pointer. This didn't fail
|
||||
because of the -Wno-error flag (to allow for overflow sizes passed
|
||||
to strncmp/wcsncmp)
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
(cherry picked from commit b98d0bbf747f39770e0caba7e984ce9f8f900330)
|
||||
|
||||
diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
index 4e9f094f39c72f67..aef9866cf2fbe774 100644
|
||||
--- a/sysdeps/x86/tst-strncmp-rtm.c
|
||||
+++ b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
@@ -23,12 +23,12 @@
|
||||
# define CHAR wchar_t
|
||||
# define MEMSET wmemset
|
||||
# define STRNCMP wcsncmp
|
||||
-# define TEST_NAME wcsncmp
|
||||
+# define TEST_NAME "wcsncmp"
|
||||
#else /* !WIDE */
|
||||
# define CHAR char
|
||||
# define MEMSET memset
|
||||
# define STRNCMP strncmp
|
||||
-# define TEST_NAME strncmp
|
||||
+# define TEST_NAME "strncmp"
|
||||
#endif /* !WIDE */
|
||||
|
||||
|
104
SOURCES/glibc-upstream-2.34-117.patch
Normal file
104
SOURCES/glibc-upstream-2.34-117.patch
Normal file
@ -0,0 +1,104 @@
|
||||
commit 3be79b72d556e3ac37075ad6b99eb5eac18e1402
|
||||
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||
Date: Sun Mar 6 15:56:57 2022 +0000
|
||||
|
||||
Fix elf/tst-audit2 on hppa
|
||||
|
||||
The test elf/tst-audit2 fails on hppa with a segmentation fault in the
|
||||
long branch stub used to call malloc from calloc. This occurs because
|
||||
the test is not a PIC executable and calloc is called from the dynamic
|
||||
linker before the dp register is initialized in _dl_start_user.
|
||||
|
||||
The fix is to move the dp register initialization into
|
||||
elf_machine_runtime_setup. Since the address of $global$ can't be
|
||||
loaded directly, we continue to use the DT_PLTGOT value from the
|
||||
the main_map to initialize dp. Since l_main_map is not available
|
||||
in v2.34 and earlier, we use a new function, elf_machine_main_map,
|
||||
to find the main map.
|
||||
|
||||
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
|
||||
index f048fd20728ccde6..24f0f47d8f1e25cd 100644
|
||||
--- a/sysdeps/hppa/dl-machine.h
|
||||
+++ b/sysdeps/hppa/dl-machine.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <string.h>
|
||||
#include <link.h>
|
||||
#include <errno.h>
|
||||
+#include <ldsodefs.h>
|
||||
#include <dl-fptr.h>
|
||||
#include <abort-instr.h>
|
||||
#include <tls.h>
|
||||
@@ -159,6 +160,24 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
|
||||
return (struct fdesc) { value.ip + reloc->r_addend, value.gp };
|
||||
}
|
||||
|
||||
+static inline struct link_map *
|
||||
+elf_machine_main_map (void)
|
||||
+{
|
||||
+ struct link_map *main_map;
|
||||
+
|
||||
+#if defined SHARED && IS_IN (rtld)
|
||||
+ asm (
|
||||
+" bl 1f,%0\n"
|
||||
+" addil L'_rtld_local - ($PIC_pcrel$0 - 1),%0\n"
|
||||
+"1: ldw R'_rtld_local - ($PIC_pcrel$0 - 5)(%%r1),%0\n"
|
||||
+ : "=r" (main_map) : : "r1");
|
||||
+#else
|
||||
+ main_map = NULL;
|
||||
+#endif
|
||||
+
|
||||
+ return main_map;
|
||||
+}
|
||||
+
|
||||
/* Set up the loaded object described by L so its unrelocated PLT
|
||||
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||
|
||||
@@ -174,6 +193,15 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
Elf32_Addr i[2];
|
||||
} sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}};
|
||||
|
||||
+ /* Initialize dp register for main executable. */
|
||||
+ if (l == elf_machine_main_map ())
|
||||
+ {
|
||||
+ register Elf32_Addr dp asm ("%r27");
|
||||
+
|
||||
+ dp = D_PTR (l, l_info[DT_PLTGOT]);
|
||||
+ asm volatile ("" : : "r" (dp));
|
||||
+ }
|
||||
+
|
||||
/* If we don't have a PLT we can just skip all this... */
|
||||
if (__builtin_expect (l->l_info[DT_JMPREL] == NULL,0))
|
||||
return lazy;
|
||||
@@ -336,16 +364,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
its return value is the user program's entry point. */
|
||||
|
||||
#define RTLD_START \
|
||||
-/* Set up dp for any non-PIC lib constructors that may be called. */ \
|
||||
-static struct link_map * __attribute__((used)) \
|
||||
-set_dp (struct link_map *map) \
|
||||
-{ \
|
||||
- register Elf32_Addr dp asm ("%r27"); \
|
||||
- dp = D_PTR (map, l_info[DT_PLTGOT]); \
|
||||
- asm volatile ("" : : "r" (dp)); \
|
||||
- return map; \
|
||||
-} \
|
||||
- \
|
||||
asm ( \
|
||||
" .text\n" \
|
||||
" .globl _start\n" \
|
||||
@@ -445,14 +463,11 @@ asm ( \
|
||||
" stw %r24,-44(%sp)\n" \
|
||||
\
|
||||
".Lnofix:\n" \
|
||||
+ /* Call _dl_init(main_map, argc, argv, envp). */ \
|
||||
" addil LT'_rtld_local,%r19\n" \
|
||||
" ldw RT'_rtld_local(%r1),%r26\n" \
|
||||
-" bl set_dp, %r2\n" \
|
||||
" ldw 0(%r26),%r26\n" \
|
||||
\
|
||||
- /* Call _dl_init(_dl_loaded, argc, argv, envp). */ \
|
||||
-" copy %r28,%r26\n" \
|
||||
- \
|
||||
/* envp = argv + argc + 1 */ \
|
||||
" sh2add %r25,%r24,%r23\n" \
|
||||
" bl _dl_init,%r2\n" \
|
146
SOURCES/glibc-upstream-2.34-118.patch
Normal file
146
SOURCES/glibc-upstream-2.34-118.patch
Normal file
@ -0,0 +1,146 @@
|
||||
commit c6f9085ee4e913a0b8260340ac7b75c426b780ce
|
||||
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||
Date: Fri Feb 18 20:38:25 2022 +0000
|
||||
|
||||
hppa: Fix swapcontext
|
||||
|
||||
This change fixes the failure of stdlib/tst-setcontext2 and
|
||||
stdlib/tst-setcontext7 on hppa. The implementation of swapcontext
|
||||
in C is broken. C saves the return pointer (rp) and any non
|
||||
call-clobbered registers (in this case r3, r4 and r5) on the
|
||||
stack. However, the setcontext call in swapcontext pops the
|
||||
stack and subsequent calls clobber the saved registers. When
|
||||
the context in oucp is restored, both tests fault.
|
||||
|
||||
Here we rewrite swapcontext in assembly code to avoid using
|
||||
the stack for register values that need to be used after
|
||||
restoration. The getcontext and setcontext routines are
|
||||
revised to save and restore register ret1 for normal returns.
|
||||
We copy the oucp pointer to ret1. This allows access to
|
||||
the old context after calling getcontext and setcontext.
|
||||
|
||||
(cherry picked from commit 71b108d7eb33b2bf3e61d5e92d2a47f74c1f7d96)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/getcontext.S b/sysdeps/unix/sysv/linux/hppa/getcontext.S
|
||||
index 1405b42819c38993..c8b690aab8ecc47c 100644
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/getcontext.S
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/getcontext.S
|
||||
@@ -138,6 +138,8 @@ ENTRY(__getcontext)
|
||||
stw %r19, -32(%sp)
|
||||
.cfi_offset 19, 32
|
||||
#endif
|
||||
+ stw %ret1, -60(%sp)
|
||||
+ .cfi_offset 29, 4
|
||||
|
||||
/* Set up the trampoline registers.
|
||||
r20, r23, r24, r25, r26 and r2 are clobbered
|
||||
@@ -168,6 +170,7 @@ ENTRY(__getcontext)
|
||||
#ifdef PIC
|
||||
ldw -32(%sp), %r19
|
||||
#endif
|
||||
+ ldw -60(%sp), %ret1
|
||||
bv %r0(%r2)
|
||||
ldwm -64(%sp), %r4
|
||||
END(__getcontext)
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/setcontext.S b/sysdeps/unix/sysv/linux/hppa/setcontext.S
|
||||
index 8fc5f5e56cb31f51..e1ae3aefcaac198d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/setcontext.S
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/setcontext.S
|
||||
@@ -34,6 +34,8 @@ ENTRY(__setcontext)
|
||||
stw %r19, -32(%sp)
|
||||
.cfi_offset 19, 32
|
||||
#endif
|
||||
+ stw %ret1, -60(%sp)
|
||||
+ .cfi_offset 29, 4
|
||||
|
||||
/* Save ucp. */
|
||||
copy %r26, %r3
|
||||
@@ -155,6 +157,7 @@ ENTRY(__setcontext)
|
||||
#ifdef PIC
|
||||
ldw -32(%r30), %r19
|
||||
#endif
|
||||
+ ldw -60(%r30), %ret1
|
||||
bv %r0(%r2)
|
||||
ldwm -64(%r30), %r3
|
||||
L(pseudo_end):
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.c b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||
index f9a8207543c164cb..562f00ff0546177d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||
@@ -18,6 +18,7 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <ucontext.h>
|
||||
+#include "ucontext_i.h"
|
||||
|
||||
extern int __getcontext (ucontext_t *ucp);
|
||||
extern int __setcontext (const ucontext_t *ucp);
|
||||
@@ -25,17 +26,61 @@ extern int __setcontext (const ucontext_t *ucp);
|
||||
int
|
||||
__swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
|
||||
{
|
||||
+ /* Save ucp in stack argument slot. */
|
||||
+ asm ("stw %r25,-40(%sp)");
|
||||
+ asm (".cfi_offset 25, -40");
|
||||
+
|
||||
+ /* Save rp for debugger. */
|
||||
+ asm ("stw %rp,-20(%sp)");
|
||||
+ asm (".cfi_offset 2, -20");
|
||||
+
|
||||
+ /* Copy rp to ret0 (r28). */
|
||||
+ asm ("copy %rp,%ret0");
|
||||
+
|
||||
+ /* Create a frame. */
|
||||
+ asm ("ldo 64(%sp),%sp");
|
||||
+ asm (".cfi_def_cfa_offset -64");
|
||||
+
|
||||
/* Save the current machine context to oucp. */
|
||||
- __getcontext (oucp);
|
||||
+ asm ("bl __getcontext,%rp");
|
||||
+
|
||||
+ /* Copy oucp to register ret1 (r29). __getcontext saves and restores it
|
||||
+ on a normal return. It is restored from oR29 on reactivation. */
|
||||
+ asm ("copy %r26,%ret1");
|
||||
+
|
||||
+ /* Pop frame. */
|
||||
+ asm ("ldo -64(%sp),%sp");
|
||||
+ asm (".cfi_def_cfa_offset 0");
|
||||
+
|
||||
+ /* Load return pointer from oR28. */
|
||||
+ asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28));
|
||||
+
|
||||
+ /* Return if error. */
|
||||
+ asm ("or,= %r0,%ret0,%r0");
|
||||
+ asm ("bv,n %r0(%rp)");
|
||||
+
|
||||
+ /* Load sc_sar flag. */
|
||||
+ asm ("ldw %0(%%ret1),%%r20" : : "i" (oSAR));
|
||||
+
|
||||
+ /* Return if oucp context has been reactivated. */
|
||||
+ asm ("or,= %r0,%r20,%r0");
|
||||
+ asm ("bv,n %r0(%rp)");
|
||||
+
|
||||
+ /* Mark sc_sar flag. */
|
||||
+ asm ("1: ldi 1,%r20");
|
||||
+ asm ("stw %%r20,%0(%%ret1)" : : "i" (oSAR));
|
||||
+
|
||||
+ /* Activate the machine context in ucp. */
|
||||
+ asm ("bl __setcontext,%rp");
|
||||
+ asm ("ldw -40(%sp),%r26");
|
||||
|
||||
- /* mark sc_sar flag to skip the setcontext call on reactivation. */
|
||||
- if (oucp->uc_mcontext.sc_sar == 0) {
|
||||
- oucp->uc_mcontext.sc_sar++;
|
||||
+ /* Load return pointer. */
|
||||
+ asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28));
|
||||
|
||||
- /* Restore the machine context in ucp. */
|
||||
- __setcontext (ucp);
|
||||
- }
|
||||
+ /* A successful call to setcontext does not return. */
|
||||
+ asm ("bv,n %r0(%rp)");
|
||||
|
||||
+ /* Make gcc happy. */
|
||||
return 0;
|
||||
}
|
||||
|
177
SOURCES/glibc-upstream-2.34-119.patch
Normal file
177
SOURCES/glibc-upstream-2.34-119.patch
Normal file
@ -0,0 +1,177 @@
|
||||
commit f610d2935f041c5f41ddcb96924ea42ca2fb5ea5
|
||||
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||
Date: Tue Feb 22 17:28:46 2022 +0000
|
||||
|
||||
hppa: Revise gettext trampoline design
|
||||
|
||||
The current getcontext return trampoline is overly complex and it
|
||||
unnecessarily clobbers several registers. By saving the context
|
||||
pointer (r26) in the context, __getcontext_ret can restore any
|
||||
registers not restored by setcontext. This allows getcontext to
|
||||
save and restore the entire register context present when getcontext
|
||||
is entered. We use the unused oR0 context slot for the return
|
||||
from __getcontext_ret.
|
||||
|
||||
While this is not directly useful in C, it can be exploited in
|
||||
assembly code. Registers r20, r23, r24 and r25 are not clobbered
|
||||
in the call path to getcontext. This allows a small simplification
|
||||
of swapcontext.
|
||||
|
||||
It also allows saving and restoring the 6-bit SAR register in the
|
||||
LSB of the oSAR context slot. The getcontext flag value can be
|
||||
stored in the MSB of the oSAR slot.
|
||||
|
||||
(cherry picked from commit 9e7e5fda38471e00d1190479ea91d7b08ae3e304)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/getcontext.S b/sysdeps/unix/sysv/linux/hppa/getcontext.S
|
||||
index c8b690aab8ecc47c..4f2e2587d60effc8 100644
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/getcontext.S
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/getcontext.S
|
||||
@@ -22,22 +22,28 @@
|
||||
#include "ucontext_i.h"
|
||||
|
||||
|
||||
- /* Trampoline function. Non-standard calling ABI. */
|
||||
+ /* Trampoline function. Non-standard calling ABI. */
|
||||
/* Can not use ENTRY(__getcontext_ret) here. */
|
||||
.type __getcontext_ret, @function
|
||||
.hidden __getcontext_ret
|
||||
__getcontext_ret:
|
||||
.proc
|
||||
.callinfo FRAME=0,NO_CALLS
|
||||
- /* r26-r23 contain original r3-r6, but because setcontext
|
||||
- does not reload r3-r6 (it's using them as temporaries)
|
||||
- we must save them elsewhere and swap them back in. */
|
||||
- copy %r23, %r3
|
||||
- copy %r24, %r4
|
||||
- copy %r25, %r5
|
||||
- copy %r26, %r6
|
||||
- /* r20 contains original return pointer. */
|
||||
- bv 0(%r20)
|
||||
+ /* Because setcontext does not reload r3-r6 (it's using them
|
||||
+ as temporaries), we must load them ourself. */
|
||||
+ ldw oR3(%r26), %r3
|
||||
+ ldw oR4(%r26), %r4
|
||||
+ ldw oR5(%r26), %r5
|
||||
+ ldw oR6(%r26), %r6
|
||||
+
|
||||
+ /* Also reload registers clobbered by $$dyncall. */
|
||||
+ ldw oR21(%r26), %r21
|
||||
+ ldw oR22(%r26), %r22
|
||||
+ ldw oR31(%r26), %r31
|
||||
+
|
||||
+ /* oR0 contains original return pointer. */
|
||||
+ ldw oR0(%r26), %rp
|
||||
+ bv 0(%rp)
|
||||
copy %r0, %ret0
|
||||
.procend
|
||||
.size __getcontext_ret, .-__getcontext_ret
|
||||
@@ -65,13 +71,13 @@ ENTRY(__getcontext)
|
||||
stw %r17, oR17(%r26)
|
||||
stw %r18, oR18(%r26)
|
||||
stw %r19, oR19(%r26)
|
||||
- /* stw %r20, oR20(%r26) - used for trampoline. */
|
||||
+ stw %r20, oR20(%r26)
|
||||
stw %r21, oR21(%r26)
|
||||
stw %r22, oR22(%r26)
|
||||
- /* stw %r23, oR23(%r26) - used for trampoline. */
|
||||
- /* stw %r24, oR24(%r26) - used for trampoline. */
|
||||
- /* stw %r25, oR25(%r26) - used for trampoline. */
|
||||
- /* stw %r26, oR26(%r26) - used for trampoline. */
|
||||
+ stw %r23, oR23(%r26)
|
||||
+ stw %r24, oR24(%r26)
|
||||
+ stw %r25, oR25(%r26)
|
||||
+ stw %r26, oR26(%r26)
|
||||
stw %r27, oR27(%r26)
|
||||
stw %r28, oR28(%r26)
|
||||
stw %r29, oR29(%r26)
|
||||
@@ -90,7 +96,10 @@ ENTRY(__getcontext)
|
||||
stw %r0, oIASQ1(%r26)
|
||||
stw %r0, oIAOQ0(%r26)
|
||||
stw %r0, oIAOQ1(%r26)
|
||||
- stw %r0, oSAR(%r26) /* used as flag in swapcontext(). */
|
||||
+
|
||||
+ /* Save SAR register. */
|
||||
+ mfctl %sar, %r1
|
||||
+ stw %r1, oSAR(%r26) /* MSB used as flag in swapcontext(). */
|
||||
|
||||
|
||||
/* Store floating-point regs. */
|
||||
@@ -142,13 +151,8 @@ ENTRY(__getcontext)
|
||||
.cfi_offset 29, 4
|
||||
|
||||
/* Set up the trampoline registers.
|
||||
- r20, r23, r24, r25, r26 and r2 are clobbered
|
||||
- by call to getcontext() anyway. Reuse them. */
|
||||
- stw %r2, oR20(%r26)
|
||||
- stw %r3, oR23(%r26)
|
||||
- stw %r4, oR24(%r26)
|
||||
- stw %r5, oR25(%r26)
|
||||
- stw %r6, oR26(%r26)
|
||||
+ Use oR0 context slot to save return value. */
|
||||
+ stw %r2, oR0(%r26)
|
||||
#ifdef PIC
|
||||
addil LT%__getcontext_ret, %r19
|
||||
ldw RT%__getcontext_ret(%r1), %r1
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/setcontext.S b/sysdeps/unix/sysv/linux/hppa/setcontext.S
|
||||
index e1ae3aefcaac198d..616405b80c61d531 100644
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/setcontext.S
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/setcontext.S
|
||||
@@ -76,7 +76,7 @@ ENTRY(__setcontext)
|
||||
ldw oR18(%r3), %r18
|
||||
ldw oR19(%r3), %r19
|
||||
ldw oR20(%r3), %r20
|
||||
- ldw oR21(%r3), %r21
|
||||
+ ldw oR21(%r3), %r21 /* maybe clobbered by dyncall */
|
||||
/* ldw oR22(%r3), %r22 - dyncall arg. */
|
||||
ldw oR23(%r3), %r23
|
||||
ldw oR24(%r3), %r24
|
||||
@@ -88,6 +88,10 @@ ENTRY(__setcontext)
|
||||
ldw oR30(%r3), %sp
|
||||
/* ldw oR31(%r3), %r31 - dyncall scratch register */
|
||||
|
||||
+ /* Restore SAR register. */
|
||||
+ ldw oSAR(%r3), %r22
|
||||
+ mtsar %r22
|
||||
+
|
||||
/* Restore floating-point registers. */
|
||||
ldo oFPREGS31(%r3), %r22
|
||||
fldds 0(%r22), %fr31
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.c b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||
index 562f00ff0546177d..1664f68c7b9982e8 100644
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||
@@ -26,10 +26,6 @@ extern int __setcontext (const ucontext_t *ucp);
|
||||
int
|
||||
__swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
|
||||
{
|
||||
- /* Save ucp in stack argument slot. */
|
||||
- asm ("stw %r25,-40(%sp)");
|
||||
- asm (".cfi_offset 25, -40");
|
||||
-
|
||||
/* Save rp for debugger. */
|
||||
asm ("stw %rp,-20(%sp)");
|
||||
asm (".cfi_offset 2, -20");
|
||||
@@ -60,7 +56,7 @@ __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
|
||||
asm ("bv,n %r0(%rp)");
|
||||
|
||||
/* Load sc_sar flag. */
|
||||
- asm ("ldw %0(%%ret1),%%r20" : : "i" (oSAR));
|
||||
+ asm ("ldb %0(%%ret1),%%r20" : : "i" (oSAR));
|
||||
|
||||
/* Return if oucp context has been reactivated. */
|
||||
asm ("or,= %r0,%r20,%r0");
|
||||
@@ -68,11 +64,11 @@ __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
|
||||
|
||||
/* Mark sc_sar flag. */
|
||||
asm ("1: ldi 1,%r20");
|
||||
- asm ("stw %%r20,%0(%%ret1)" : : "i" (oSAR));
|
||||
+ asm ("stb %%r20,%0(%%ret1)" : : "i" (oSAR));
|
||||
|
||||
/* Activate the machine context in ucp. */
|
||||
asm ("bl __setcontext,%rp");
|
||||
- asm ("ldw -40(%sp),%r26");
|
||||
+ asm ("ldw %0(%%ret1),%%r26" : : "i" (oR25));
|
||||
|
||||
/* Load return pointer. */
|
||||
asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28));
|
27
SOURCES/glibc-upstream-2.34-120.patch
Normal file
27
SOURCES/glibc-upstream-2.34-120.patch
Normal file
@ -0,0 +1,27 @@
|
||||
commit 40fc6a74ee3dd600c84d311d91cbb16962f11a71
|
||||
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||
Date: Mon Feb 28 15:47:38 2022 +0000
|
||||
|
||||
nptl: Fix cleanups for stack grows up [BZ# 28899]
|
||||
|
||||
_STACK_GROWS_DOWN is defined to 0 when the stack grows up. The
|
||||
code in unwind.c used `#ifdef _STACK_GROWS_DOWN' to selct the
|
||||
stack grows down define for FRAME_LEFT. As a result, the
|
||||
_STACK_GROWS_DOWN define was always selected and cleanups were
|
||||
incorrectly sequenced when the stack grows up.
|
||||
|
||||
(cherry picked from commit 2bbc694df279020a6620096d31c1e05c93966f9b)
|
||||
|
||||
diff --git a/nptl/unwind.c b/nptl/unwind.c
|
||||
index f50997f728ccde0d..404fab46d00e9f10 100644
|
||||
--- a/nptl/unwind.c
|
||||
+++ b/nptl/unwind.c
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <jmpbuf-unwind.h>
|
||||
#include <shlib-compat.h>
|
||||
|
||||
-#ifdef _STACK_GROWS_DOWN
|
||||
+#if _STACK_GROWS_DOWN
|
||||
# define FRAME_LEFT(frame, other, adj) \
|
||||
((uintptr_t) frame - adj >= (uintptr_t) other - adj)
|
||||
#elif _STACK_GROWS_UP
|
122
SOURCES/glibc-upstream-2.34-121.patch
Normal file
122
SOURCES/glibc-upstream-2.34-121.patch
Normal file
@ -0,0 +1,122 @@
|
||||
commit 6c9c2307657529e52c5fa7037618835f2a50b916
|
||||
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||
Date: Sun Mar 6 16:04:32 2022 +0000
|
||||
|
||||
hppa: Fix warnings from _dl_lookup_address
|
||||
|
||||
This change fixes two warnings from _dl_lookup_address.
|
||||
|
||||
The first warning comes from dropping the volatile keyword from
|
||||
desc in the call to _dl_read_access_allowed. We now have a full
|
||||
atomic barrier between loading desc[0] and the access check, so
|
||||
desc no longer needs to be declared as volatile.
|
||||
|
||||
The second warning comes from the implicit declaration of
|
||||
_dl_fix_reloc_arg. This is fixed by including dl-runtime.h and
|
||||
declaring _dl_fix_reloc_arg in dl-runtime.h.
|
||||
|
||||
diff --git a/sysdeps/hppa/dl-fptr.c b/sysdeps/hppa/dl-fptr.c
|
||||
index 62ef68b62bd601f4..cd4f77c0ecfd376f 100644
|
||||
--- a/sysdeps/hppa/dl-fptr.c
|
||||
+++ b/sysdeps/hppa/dl-fptr.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <ldsodefs.h>
|
||||
#include <elf/dynamic-link.h>
|
||||
#include <dl-fptr.h>
|
||||
+#include <dl-runtime.h>
|
||||
#include <dl-unmap-segments.h>
|
||||
#include <atomic.h>
|
||||
#include <libc-pointer-arith.h>
|
||||
@@ -351,21 +352,20 @@ _dl_lookup_address (const void *address)
|
||||
{
|
||||
ElfW(Addr) addr = (ElfW(Addr)) address;
|
||||
ElfW(Word) reloc_arg;
|
||||
- volatile unsigned int *desc;
|
||||
- unsigned int *gptr;
|
||||
+ unsigned int *desc, *gptr;
|
||||
|
||||
/* Return ADDR if the least-significant two bits of ADDR are not consistent
|
||||
with ADDR being a linker defined function pointer. The normal value for
|
||||
a code address in a backtrace is 3. */
|
||||
- if (((unsigned int) addr & 3) != 2)
|
||||
+ if (((uintptr_t) addr & 3) != 2)
|
||||
return addr;
|
||||
|
||||
/* Handle special case where ADDR points to page 0. */
|
||||
- if ((unsigned int) addr < 4096)
|
||||
+ if ((uintptr_t) addr < 4096)
|
||||
return addr;
|
||||
|
||||
/* Clear least-significant two bits from descriptor address. */
|
||||
- desc = (unsigned int *) ((unsigned int) addr & ~3);
|
||||
+ desc = (unsigned int *) ((uintptr_t) addr & ~3);
|
||||
if (!_dl_read_access_allowed (desc))
|
||||
return addr;
|
||||
|
||||
@@ -376,7 +376,7 @@ _dl_lookup_address (const void *address)
|
||||
/* Then load first word of candidate descriptor. It should be a pointer
|
||||
with word alignment and point to memory that can be read. */
|
||||
gptr = (unsigned int *) desc[0];
|
||||
- if (((unsigned int) gptr & 3) != 0
|
||||
+ if (((uintptr_t) gptr & 3) != 0
|
||||
|| !_dl_read_access_allowed (gptr))
|
||||
return addr;
|
||||
|
||||
@@ -400,10 +400,11 @@ _dl_lookup_address (const void *address)
|
||||
|
||||
/* If gp has been resolved, we need to hunt for relocation offset. */
|
||||
if (!(reloc_arg & PA_GP_RELOC))
|
||||
- reloc_arg = _dl_fix_reloc_arg (addr, l);
|
||||
+ reloc_arg = _dl_fix_reloc_arg ((struct fdesc *) addr, l);
|
||||
|
||||
_dl_fixup (l, reloc_arg);
|
||||
}
|
||||
|
||||
return (ElfW(Addr)) desc[0];
|
||||
}
|
||||
+rtld_hidden_def (_dl_lookup_address)
|
||||
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
|
||||
index a9a927f26c6fec09..2f6991aa16e87a00 100644
|
||||
--- a/sysdeps/hppa/dl-lookupcfg.h
|
||||
+++ b/sysdeps/hppa/dl-lookupcfg.h
|
||||
@@ -30,6 +30,7 @@ rtld_hidden_proto (_dl_symbol_address)
|
||||
#define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
|
||||
|
||||
Elf32_Addr _dl_lookup_address (const void *address);
|
||||
+rtld_hidden_proto (_dl_lookup_address)
|
||||
|
||||
#define DL_LOOKUP_ADDRESS(addr) _dl_lookup_address ((const void *) addr)
|
||||
|
||||
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
|
||||
index e7fbb7417d866bb0..a71b5b2013abf723 100644
|
||||
--- a/sysdeps/hppa/dl-runtime.c
|
||||
+++ b/sysdeps/hppa/dl-runtime.c
|
||||
@@ -25,8 +25,7 @@
|
||||
return that to the caller. The caller will continue on to call
|
||||
_dl_fixup with the relocation offset. */
|
||||
|
||||
-ElfW(Word)
|
||||
-attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||
+ElfW(Word) __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||
_dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l)
|
||||
{
|
||||
Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type;
|
||||
@@ -52,3 +51,4 @@ _dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l)
|
||||
ABORT_INSTRUCTION;
|
||||
return 0;
|
||||
}
|
||||
+rtld_hidden_def (_dl_fix_reloc_arg)
|
||||
diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h
|
||||
index 5d6ee53b076d5e0e..9913539b5f0e7435 100644
|
||||
--- a/sysdeps/hppa/dl-runtime.h
|
||||
+++ b/sysdeps/hppa/dl-runtime.h
|
||||
@@ -17,6 +17,9 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
+ElfW(Word) _dl_fix_reloc_arg (struct fdesc *, struct link_map *);
|
||||
+rtld_hidden_proto (_dl_fix_reloc_arg)
|
||||
+
|
||||
/* Clear PA_GP_RELOC bit in relocation offset. */
|
||||
static inline uintptr_t
|
||||
reloc_offset (uintptr_t plt0, uintptr_t pltn)
|
26
SOURCES/glibc-upstream-2.34-122.patch
Normal file
26
SOURCES/glibc-upstream-2.34-122.patch
Normal file
@ -0,0 +1,26 @@
|
||||
commit b5032c3d37aa614644c7afbad33bb8226a52e6da
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Feb 28 11:50:41 2022 +0100
|
||||
|
||||
io: Add fsync call in tst-stat
|
||||
|
||||
io/tst-stat and io/tst-stat-lfs fail sporadically on the Fedora
|
||||
builders, and this change hopefully helps to avoid the issue.
|
||||
|
||||
(cherry picked from commit ae132284092edc5885315b44cd17d5ea91177e49)
|
||||
|
||||
diff --git a/io/tst-stat.c b/io/tst-stat.c
|
||||
index 82e965de6ad87f61..be20cf16d70d05cc 100644
|
||||
--- a/io/tst-stat.c
|
||||
+++ b/io/tst-stat.c
|
||||
@@ -69,6 +69,10 @@ do_test (void)
|
||||
TEST_VERIFY_EXIT (fd >= 0);
|
||||
support_write_file_string (path, "abc");
|
||||
|
||||
+ /* This should help to prevent delayed allocation, which may result
|
||||
+ in a spurious stx_blocks/st_blocks difference. */
|
||||
+ fsync (fd);
|
||||
+
|
||||
bool check_ns = support_stat_nanoseconds (path);
|
||||
if (!check_ns)
|
||||
printf ("warning: timestamp with nanoseconds not supported\n");
|
56
SOURCES/glibc-upstream-2.34-123.patch
Normal file
56
SOURCES/glibc-upstream-2.34-123.patch
Normal file
@ -0,0 +1,56 @@
|
||||
commit b53f0c11de409b04560a70570178d1a9d03d5860
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Mar 11 08:23:56 2022 +0100
|
||||
|
||||
nss: Do not mention NSS test modules in <gnu/lib-names.h>
|
||||
|
||||
They are not actually installed. Use the nss_files version instead
|
||||
in nss/Makefile, similar to how __nss_shlib_revision is derived
|
||||
from LIBNSS_FILES_SO.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit aefc79ab5ad4bb9feea2876720cec70dca7cd8ed)
|
||||
|
||||
diff --git a/nss/Makefile b/nss/Makefile
|
||||
index bccf9f2806c15651..e223243d9d62041c 100644
|
||||
--- a/nss/Makefile
|
||||
+++ b/nss/Makefile
|
||||
@@ -171,17 +171,14 @@ $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps)
|
||||
$(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps)
|
||||
$(build-module)
|
||||
$(objpfx)nss_test2.os : nss_test1.c
|
||||
-ifdef libnss_test1.so-version
|
||||
-$(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so
|
||||
+# Use the nss_files suffix for these objects as well.
|
||||
+$(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so
|
||||
$(make-link)
|
||||
-endif
|
||||
-ifdef libnss_test2.so-version
|
||||
-$(objpfx)/libnss_test2.so$(libnss_test2.so-version): $(objpfx)/libnss_test2.so
|
||||
+$(objpfx)/libnss_test2.so$(libnss_files.so-version): $(objpfx)/libnss_test2.so
|
||||
$(make-link)
|
||||
-endif
|
||||
$(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \
|
||||
- $(objpfx)/libnss_test1.so$(libnss_test1.so-version) \
|
||||
- $(objpfx)/libnss_test2.so$(libnss_test2.so-version)
|
||||
+ $(objpfx)/libnss_test1.so$(libnss_files.so-version) \
|
||||
+ $(objpfx)/libnss_test2.so$(libnss_files.so-version)
|
||||
|
||||
ifeq (yes,$(have-thread-library))
|
||||
$(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library)
|
||||
diff --git a/shlib-versions b/shlib-versions
|
||||
index df6603e6992b8382..b87ab50c59af1bfd 100644
|
||||
--- a/shlib-versions
|
||||
+++ b/shlib-versions
|
||||
@@ -47,11 +47,6 @@ libnss_ldap=2
|
||||
libnss_hesiod=2
|
||||
libnss_db=2
|
||||
|
||||
-# Tests for NSS. They must have the same NSS_SHLIB_REVISION number as
|
||||
-# the rest.
|
||||
-libnss_test1=2
|
||||
-libnss_test2=2
|
||||
-
|
||||
# Version for libnsl with YP and NIS+ functions.
|
||||
libnsl=1
|
||||
|
224
SOURCES/glibc-upstream-2.34-124.patch
Normal file
224
SOURCES/glibc-upstream-2.34-124.patch
Normal file
@ -0,0 +1,224 @@
|
||||
commit 54b12733959238204d7b0e46e69fc7f7d8890b20
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Mar 11 08:23:56 2022 +0100
|
||||
|
||||
nss: Protect against errno changes in function lookup (bug 28953)
|
||||
|
||||
dlopen may clobber errno. The nss_test_errno module uses an ELF
|
||||
constructor to achieve that, but there could be internal errors
|
||||
during dlopen that cause this, too. Therefore, the NSS framework
|
||||
has to guard against such errno clobbers.
|
||||
|
||||
__nss_module_get_function is currently the only function that calls
|
||||
__nss_module_load, so it is sufficient to save and restore errno
|
||||
around this call.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit 9bdf92c79d63b42f931101bb6df87129c408b0c4)
|
||||
|
||||
diff --git a/nss/Makefile b/nss/Makefile
|
||||
index e223243d9d62041c..716bc8f6ef5276b0 100644
|
||||
--- a/nss/Makefile
|
||||
+++ b/nss/Makefile
|
||||
@@ -60,7 +60,8 @@ tests = test-netdb test-digits-dots tst-nss-getpwent bug17079 \
|
||||
tst-nss-test1 \
|
||||
tst-nss-test2 \
|
||||
tst-nss-test4 \
|
||||
- tst-nss-test5
|
||||
+ tst-nss-test5 \
|
||||
+ tst-nss-test_errno
|
||||
xtests = bug-erange
|
||||
|
||||
tests-container = \
|
||||
@@ -132,7 +133,7 @@ libnss_compat-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
ifeq ($(build-static-nss),yes)
|
||||
tests-static += tst-nss-static
|
||||
endif
|
||||
-extra-test-objs += nss_test1.os nss_test2.os
|
||||
+extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os
|
||||
|
||||
include ../Rules
|
||||
|
||||
@@ -166,19 +167,26 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
|
||||
|
||||
libof-nss_test1 = extramodules
|
||||
libof-nss_test2 = extramodules
|
||||
+libof-nss_test_errno = extramodules
|
||||
$(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps)
|
||||
$(build-module)
|
||||
$(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps)
|
||||
$(build-module)
|
||||
+$(objpfx)/libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps)
|
||||
+ $(build-module)
|
||||
$(objpfx)nss_test2.os : nss_test1.c
|
||||
# Use the nss_files suffix for these objects as well.
|
||||
$(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so
|
||||
$(make-link)
|
||||
$(objpfx)/libnss_test2.so$(libnss_files.so-version): $(objpfx)/libnss_test2.so
|
||||
$(make-link)
|
||||
+$(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \
|
||||
+ $(objpfx)/libnss_test_errno.so
|
||||
+ $(make-link)
|
||||
$(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \
|
||||
$(objpfx)/libnss_test1.so$(libnss_files.so-version) \
|
||||
- $(objpfx)/libnss_test2.so$(libnss_files.so-version)
|
||||
+ $(objpfx)/libnss_test2.so$(libnss_files.so-version) \
|
||||
+ $(objpfx)/libnss_test_errno.so$(libnss_files.so-version)
|
||||
|
||||
ifeq (yes,$(have-thread-library))
|
||||
$(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library)
|
||||
diff --git a/nss/nss_module.c b/nss/nss_module.c
|
||||
index b28cb94a6a0aeb41..3a4a464256121e41 100644
|
||||
--- a/nss/nss_module.c
|
||||
+++ b/nss/nss_module.c
|
||||
@@ -330,8 +330,18 @@ name_search (const void *left, const void *right)
|
||||
void *
|
||||
__nss_module_get_function (struct nss_module *module, const char *name)
|
||||
{
|
||||
+ /* A successful dlopen might clobber errno. */
|
||||
+ int saved_errno = errno;
|
||||
+
|
||||
if (!__nss_module_load (module))
|
||||
- return NULL;
|
||||
+ {
|
||||
+ /* Reporting module load failure is currently inaccurate. See
|
||||
+ bug 22041. Not changing errno is the conservative choice. */
|
||||
+ __set_errno (saved_errno);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ __set_errno (saved_errno);
|
||||
|
||||
function_name *name_entry = bsearch (name, nss_function_name_array,
|
||||
array_length (nss_function_name_array),
|
||||
diff --git a/nss/nss_test_errno.c b/nss/nss_test_errno.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..680f8a07b97fe263
|
||||
--- /dev/null
|
||||
+++ b/nss/nss_test_errno.c
|
||||
@@ -0,0 +1,58 @@
|
||||
+/* NSS service provider with errno clobber.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <nss.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+/* Catch misnamed and functions. */
|
||||
+#pragma GCC diagnostic error "-Wmissing-prototypes"
|
||||
+NSS_DECLARE_MODULE_FUNCTIONS (test_errno)
|
||||
+
|
||||
+static void __attribute__ ((constructor))
|
||||
+init (void)
|
||||
+{
|
||||
+ /* An arbitrary error code which is otherwise not used. */
|
||||
+ errno = ELIBBAD;
|
||||
+}
|
||||
+
|
||||
+/* Lookup functions for pwd follow that do not return any data. */
|
||||
+
|
||||
+/* Catch misnamed function definitions. */
|
||||
+
|
||||
+enum nss_status
|
||||
+_nss_test_errno_setpwent (int stayopen)
|
||||
+{
|
||||
+ setenv ("_nss_test_errno_setpwent", "yes", 1);
|
||||
+ return NSS_STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+enum nss_status
|
||||
+_nss_test_errno_getpwent_r (struct passwd *result,
|
||||
+ char *buffer, size_t size, int *errnop)
|
||||
+{
|
||||
+ setenv ("_nss_test_errno_getpwent_r", "yes", 1);
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+}
|
||||
+
|
||||
+enum nss_status
|
||||
+_nss_test_errno_endpwent (void)
|
||||
+{
|
||||
+ setenv ("_nss_test_errno_endpwent", "yes", 1);
|
||||
+ return NSS_STATUS_SUCCESS;
|
||||
+}
|
||||
diff --git a/nss/tst-nss-test_errno.c b/nss/tst-nss-test_errno.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d2c42dd363a38b0e
|
||||
--- /dev/null
|
||||
+++ b/nss/tst-nss-test_errno.c
|
||||
@@ -0,0 +1,61 @@
|
||||
+/* getpwent failure when dlopen clobbers errno (bug 28953).
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <nss.h>
|
||||
+#include <support/check.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <errno.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <pwd.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ __nss_configure_lookup ("passwd", "files test_errno");
|
||||
+
|
||||
+ errno = 0;
|
||||
+ setpwent ();
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+
|
||||
+ bool root_seen = false;
|
||||
+ while (true)
|
||||
+ {
|
||||
+ errno = 0;
|
||||
+ struct passwd *e = getpwent ();
|
||||
+ if (e == NULL)
|
||||
+ break;
|
||||
+ if (strcmp (e->pw_name, "root"))
|
||||
+ root_seen = true;
|
||||
+ }
|
||||
+
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_VERIFY (root_seen);
|
||||
+
|
||||
+ errno = 0;
|
||||
+ endpwent ();
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+
|
||||
+ TEST_COMPARE_STRING (getenv ("_nss_test_errno_setpwent"), "yes");
|
||||
+ TEST_COMPARE_STRING (getenv ("_nss_test_errno_getpwent_r"), "yes");
|
||||
+ TEST_COMPARE_STRING (getenv ("_nss_test_errno_endpwent"), "yes");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
345
SOURCES/glibc-upstream-2.34-125.patch
Normal file
345
SOURCES/glibc-upstream-2.34-125.patch
Normal file
@ -0,0 +1,345 @@
|
||||
commit c82bdf033f93a710044e25f721340c26e89a3769
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Tue Oct 12 12:29:13 2021 +0530
|
||||
|
||||
Don't add access size hints to fortifiable functions
|
||||
|
||||
In the context of a function definition, the size hints imply that the
|
||||
size of an object pointed to by one parameter is another parameter.
|
||||
This doesn't make sense for the fortified versions of the functions
|
||||
since that's the bit it's trying to validate.
|
||||
|
||||
This is harmless with __builtin_object_size since it has fairly simple
|
||||
semantics when it comes to objects passed as function parameters.
|
||||
With __builtin_dynamic_object_size we could (as my patchset for gcc[1]
|
||||
already does) use the access attribute to determine the object size in
|
||||
the general case but it misleads the fortified functions.
|
||||
|
||||
Basically the problem occurs when access attributes are present on
|
||||
regular functions that have inline fortified definitions to generate
|
||||
_chk variants; the attributes get inherited by these definitions,
|
||||
causing problems when analyzing them. For example with poll(fds, nfds,
|
||||
timeout), nfds is hinted using the __attr_access as being the size of
|
||||
fds.
|
||||
|
||||
Now, when analyzing the inline function definition in bits/poll2.h, the
|
||||
compiler sees that nfds is the size of fds and tries to use that
|
||||
information in the function body. In _FORTIFY_SOURCE=3 case, where the
|
||||
object size could be a non-constant expression, this information results
|
||||
in the conclusion that nfds is the size of fds, which defeats the
|
||||
purpose of the implementation because we're trying to check here if nfds
|
||||
does indeed represent the size of fds. Hence for this case, it is best
|
||||
to not have the access attribute.
|
||||
|
||||
With the attributes gone, the expression evaluation should get delayed
|
||||
until the function is actually inlined into its destinations.
|
||||
|
||||
Disable the access attribute for fortified function inline functions
|
||||
when building at _FORTIFY_SOURCE=3 to make this work better. The
|
||||
access attributes remain for the _chk variants since they can be used
|
||||
by the compiler to warn when the caller is passing invalid arguments.
|
||||
|
||||
[1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581125.html
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
(cherry picked from commit e938c02748402c50f60ba0eb983273e7b52937d1)
|
||||
|
||||
diff --git a/io/bits/poll2.h b/io/bits/poll2.h
|
||||
index a623678c09f9f04f..be74d020f2e0e434 100644
|
||||
--- a/io/bits/poll2.h
|
||||
+++ b/io/bits/poll2.h
|
||||
@@ -33,7 +33,7 @@ extern int __REDIRECT (__poll_chk_warn, (struct pollfd *__fds, nfds_t __nfds,
|
||||
__poll_chk)
|
||||
__warnattr ("poll called with fds buffer too small file nfds entries");
|
||||
|
||||
-__fortify_function __attr_access ((__write_only__, 1, 2)) int
|
||||
+__fortify_function __fortified_attr_access (__write_only__, 1, 2) int
|
||||
poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
|
||||
{
|
||||
if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1)
|
||||
@@ -64,7 +64,7 @@ extern int __REDIRECT (__ppoll_chk_warn, (struct pollfd *__fds, nfds_t __nfds,
|
||||
__ppoll_chk)
|
||||
__warnattr ("ppoll called with fds buffer too small file nfds entries");
|
||||
|
||||
-__fortify_function __attr_access ((__write_only__, 1, 2)) int
|
||||
+__fortify_function __fortified_attr_access (__write_only__, 1, 2) int
|
||||
ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout,
|
||||
const __sigset_t *__ss)
|
||||
{
|
||||
diff --git a/io/sys/poll.h b/io/sys/poll.h
|
||||
index e640efb2bce7ea67..751c7f5f72db8be2 100644
|
||||
--- a/io/sys/poll.h
|
||||
+++ b/io/sys/poll.h
|
||||
@@ -52,7 +52,7 @@ __BEGIN_DECLS
|
||||
This function is a cancellation point and therefore not marked with
|
||||
__THROW. */
|
||||
extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
|
||||
- __attr_access ((__write_only__, 1, 2));
|
||||
+ __fortified_attr_access (__write_only__, 1, 2);
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Like poll, but before waiting the threads signal mask is replaced
|
||||
@@ -64,7 +64,7 @@ extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
|
||||
extern int ppoll (struct pollfd *__fds, nfds_t __nfds,
|
||||
const struct timespec *__timeout,
|
||||
const __sigset_t *__ss)
|
||||
- __attr_access ((__write_only__, 1, 2));
|
||||
+ __fortified_attr_access (__write_only__, 1, 2);
|
||||
|
||||
# ifdef __USE_TIME_BITS64
|
||||
# ifdef __REDIRECT
|
||||
@@ -72,7 +72,7 @@ extern int __REDIRECT (ppoll, (struct pollfd *__fds, nfds_t __nfds,
|
||||
const struct timespec *__timeout,
|
||||
const __sigset_t *__ss),
|
||||
__ppoll64)
|
||||
- __attr_access ((__write_only__, 1, 2));
|
||||
+ __fortified_attr_access (__write_only__, 1, 2);
|
||||
# else
|
||||
# define ppoll __ppoll64
|
||||
# endif
|
||||
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
|
||||
index 3f0cab1254b02c43..4f016a563857a137 100644
|
||||
--- a/libio/bits/stdio2.h
|
||||
+++ b/libio/bits/stdio2.h
|
||||
@@ -258,7 +258,7 @@ extern char *__REDIRECT (__fgets_chk_warn,
|
||||
__wur __warnattr ("fgets called with bigger size than length "
|
||||
"of destination buffer");
|
||||
|
||||
-__fortify_function __wur __attr_access ((__write_only__, 1, 2)) char *
|
||||
+__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char *
|
||||
fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
|
||||
{
|
||||
if (__glibc_objsize (__s) != (size_t) -1)
|
||||
@@ -320,7 +320,7 @@ extern char *__REDIRECT (__fgets_unlocked_chk_warn,
|
||||
__wur __warnattr ("fgets_unlocked called with bigger size than length "
|
||||
"of destination buffer");
|
||||
|
||||
-__fortify_function __wur __attr_access ((__write_only__, 1, 2)) char *
|
||||
+__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char *
|
||||
fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
|
||||
{
|
||||
if (__glibc_objsize (__s) != (size_t) -1)
|
||||
diff --git a/libio/stdio.h b/libio/stdio.h
|
||||
index 497da016ffa2e230..abefe640e52d18d5 100644
|
||||
--- a/libio/stdio.h
|
||||
+++ b/libio/stdio.h
|
||||
@@ -584,7 +584,7 @@ extern int putw (int __w, FILE *__stream);
|
||||
This function is a possible cancellation point and therefore not
|
||||
marked with __THROW. */
|
||||
extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
|
||||
- __wur __attr_access ((__write_only__, 1, 2));
|
||||
+ __wur __fortified_attr_access (__write_only__, 1, 2);
|
||||
|
||||
#if __GLIBC_USE (DEPRECATED_GETS)
|
||||
/* Get a newline-terminated string from stdin, removing the newline.
|
||||
@@ -608,7 +608,7 @@ extern char *gets (char *__s) __wur __attribute_deprecated__;
|
||||
therefore not marked with __THROW. */
|
||||
extern char *fgets_unlocked (char *__restrict __s, int __n,
|
||||
FILE *__restrict __stream) __wur
|
||||
- __attr_access ((__write_only__, 1, 2));
|
||||
+ __fortified_attr_access (__write_only__, 1, 2);
|
||||
#endif
|
||||
|
||||
|
||||
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
|
||||
index e490fc1aebeadc3d..cd836441a9807d6a 100644
|
||||
--- a/misc/sys/cdefs.h
|
||||
+++ b/misc/sys/cdefs.h
|
||||
@@ -603,12 +603,22 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf
|
||||
size-index is not provided:
|
||||
access (access-mode, <ref-index> [, <size-index>]) */
|
||||
# define __attr_access(x) __attribute__ ((__access__ x))
|
||||
+/* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may
|
||||
+ use the access attribute to get object sizes from function definition
|
||||
+ arguments, so we can't use them on functions we fortify. Drop the object
|
||||
+ size hints for such functions. */
|
||||
+# if __USE_FORTIFY_LEVEL == 3
|
||||
+# define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, o)))
|
||||
+# else
|
||||
+# define __fortified_attr_access(a, o, s) __attr_access ((a, o, s))
|
||||
+# endif
|
||||
# if __GNUC_PREREQ (11, 0)
|
||||
# define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno)))
|
||||
# else
|
||||
# define __attr_access_none(argno)
|
||||
# endif
|
||||
#else
|
||||
+# define __fortified_attr_access(a, o, s)
|
||||
# define __attr_access(x)
|
||||
# define __attr_access_none(argno)
|
||||
#endif
|
||||
diff --git a/posix/unistd.h b/posix/unistd.h
|
||||
index 8224c5fbc956306f..7a61ff5e868c3456 100644
|
||||
--- a/posix/unistd.h
|
||||
+++ b/posix/unistd.h
|
||||
@@ -369,7 +369,7 @@ extern void closefrom (int __lowfd) __THROW;
|
||||
This function is a cancellation point and therefore not marked with
|
||||
__THROW. */
|
||||
extern ssize_t read (int __fd, void *__buf, size_t __nbytes) __wur
|
||||
- __attr_access ((__write_only__, 2, 3));
|
||||
+ __fortified_attr_access (__write_only__, 2, 3);
|
||||
|
||||
/* Write N bytes of BUF to FD. Return the number written, or -1.
|
||||
|
||||
@@ -388,7 +388,7 @@ extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur
|
||||
__THROW. */
|
||||
extern ssize_t pread (int __fd, void *__buf, size_t __nbytes,
|
||||
__off_t __offset) __wur
|
||||
- __attr_access ((__write_only__, 2, 3));
|
||||
+ __fortified_attr_access (__write_only__, 2, 3);
|
||||
|
||||
/* Write N bytes of BUF to FD at the given position OFFSET without
|
||||
changing the file pointer. Return the number written, or -1.
|
||||
@@ -404,7 +404,7 @@ extern ssize_t pwrite (int __fd, const void *__buf, size_t __n,
|
||||
extern ssize_t __REDIRECT (pread, (int __fd, void *__buf, size_t __nbytes,
|
||||
__off64_t __offset),
|
||||
pread64) __wur
|
||||
- __attr_access ((__write_only__, 2, 3));
|
||||
+ __fortified_attr_access (__write_only__, 2, 3);
|
||||
extern ssize_t __REDIRECT (pwrite, (int __fd, const void *__buf,
|
||||
size_t __nbytes, __off64_t __offset),
|
||||
pwrite64) __wur
|
||||
@@ -421,7 +421,7 @@ extern ssize_t __REDIRECT (pwrite, (int __fd, const void *__buf,
|
||||
or 0 for EOF. */
|
||||
extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
|
||||
__off64_t __offset) __wur
|
||||
- __attr_access ((__write_only__, 2, 3));
|
||||
+ __fortified_attr_access (__write_only__, 2, 3);
|
||||
/* Write N bytes of BUF to FD at the given position OFFSET without
|
||||
changing the file pointer. Return the number written, or -1. */
|
||||
extern ssize_t pwrite64 (int __fd, const void *__buf, size_t __n,
|
||||
@@ -642,7 +642,7 @@ extern long int sysconf (int __name) __THROW;
|
||||
#ifdef __USE_POSIX2
|
||||
/* Get the value of the string-valued system variable NAME. */
|
||||
extern size_t confstr (int __name, char *__buf, size_t __len) __THROW
|
||||
- __attr_access ((__write_only__, 2, 3));
|
||||
+ __fortified_attr_access (__write_only__, 2, 3);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -709,7 +709,7 @@ extern __gid_t getegid (void) __THROW;
|
||||
the calling process is in. Otherwise, fill in the group IDs
|
||||
of its supplementary groups in LIST and return the number written. */
|
||||
extern int getgroups (int __size, __gid_t __list[]) __THROW __wur
|
||||
- __attr_access ((__write_only__, 2, 1));
|
||||
+ __fortified_attr_access (__write_only__, 2, 1);
|
||||
#ifdef __USE_GNU
|
||||
/* Return nonzero iff the calling process is in group GID. */
|
||||
extern int group_member (__gid_t __gid) __THROW;
|
||||
@@ -801,7 +801,8 @@ extern char *ttyname (int __fd) __THROW;
|
||||
/* Store at most BUFLEN characters of the pathname of the terminal FD is
|
||||
open on in BUF. Return 0 on success, otherwise an error number. */
|
||||
extern int ttyname_r (int __fd, char *__buf, size_t __buflen)
|
||||
- __THROW __nonnull ((2)) __wur __attr_access ((__write_only__, 2, 3));
|
||||
+ __THROW __nonnull ((2)) __wur
|
||||
+ __fortified_attr_access (__write_only__, 2, 3);
|
||||
|
||||
/* Return 1 if FD is a valid descriptor associated
|
||||
with a terminal, zero if not. */
|
||||
@@ -836,7 +837,8 @@ extern int symlink (const char *__from, const char *__to)
|
||||
Returns the number of characters read, or -1 for errors. */
|
||||
extern ssize_t readlink (const char *__restrict __path,
|
||||
char *__restrict __buf, size_t __len)
|
||||
- __THROW __nonnull ((1, 2)) __wur __attr_access ((__write_only__, 2, 3));
|
||||
+ __THROW __nonnull ((1, 2)) __wur
|
||||
+ __fortified_attr_access (__write_only__, 2, 3);
|
||||
|
||||
#endif /* Use POSIX.1-2001. */
|
||||
|
||||
@@ -848,7 +850,8 @@ extern int symlinkat (const char *__from, int __tofd,
|
||||
/* Like readlink but a relative PATH is interpreted relative to FD. */
|
||||
extern ssize_t readlinkat (int __fd, const char *__restrict __path,
|
||||
char *__restrict __buf, size_t __len)
|
||||
- __THROW __nonnull ((2, 3)) __wur __attr_access ((__write_only__, 3, 4));
|
||||
+ __THROW __nonnull ((2, 3)) __wur
|
||||
+ __fortified_attr_access (__write_only__, 3, 4);
|
||||
#endif
|
||||
|
||||
/* Remove the link NAME. */
|
||||
@@ -884,7 +887,7 @@ extern char *getlogin (void);
|
||||
This function is a possible cancellation point and therefore not
|
||||
marked with __THROW. */
|
||||
extern int getlogin_r (char *__name, size_t __name_len) __nonnull ((1))
|
||||
- __attr_access ((__write_only__, 1, 2));
|
||||
+ __fortified_attr_access (__write_only__, 1, 2);
|
||||
#endif
|
||||
|
||||
#ifdef __USE_MISC
|
||||
@@ -906,7 +909,7 @@ extern int setlogin (const char *__name) __THROW __nonnull ((1));
|
||||
The result is null-terminated if LEN is large enough for the full
|
||||
name and the terminator. */
|
||||
extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1))
|
||||
- __attr_access ((__write_only__, 1, 2));
|
||||
+ __fortified_attr_access (__write_only__, 1, 2);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -925,7 +928,8 @@ extern int sethostid (long int __id) __THROW __wur;
|
||||
Called just like `gethostname' and `sethostname'.
|
||||
The NIS domain name is usually the empty string when not using NIS. */
|
||||
extern int getdomainname (char *__name, size_t __len)
|
||||
- __THROW __nonnull ((1)) __wur __attr_access ((__write_only__, 1, 2));
|
||||
+ __THROW __nonnull ((1)) __wur
|
||||
+ __fortified_attr_access (__write_only__, 1, 2);
|
||||
extern int setdomainname (const char *__name, size_t __len)
|
||||
__THROW __nonnull ((1)) __wur __attr_access ((__read_only__, 1, 2));
|
||||
|
||||
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
|
||||
index 0481c1235514f6e7..74c00eee73e4009d 100644
|
||||
--- a/stdlib/stdlib.h
|
||||
+++ b/stdlib/stdlib.h
|
||||
@@ -943,7 +943,8 @@ extern size_t mbstowcs (wchar_t *__restrict __pwcs,
|
||||
extern size_t wcstombs (char *__restrict __s,
|
||||
const wchar_t *__restrict __pwcs, size_t __n)
|
||||
__THROW
|
||||
- __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2));
|
||||
+ __fortified_attr_access (__write_only__, 1, 3)
|
||||
+ __attr_access ((__read_only__, 2));
|
||||
|
||||
#ifdef __USE_MISC
|
||||
/* Determine whether the string value of RESPONSE matches the affirmation
|
||||
@@ -997,7 +998,7 @@ extern char *ptsname (int __fd) __THROW __wur;
|
||||
terminal associated with the master FD is open on in BUF.
|
||||
Return 0 on success, otherwise an error number. */
|
||||
extern int ptsname_r (int __fd, char *__buf, size_t __buflen)
|
||||
- __THROW __nonnull ((2)) __attr_access ((__write_only__, 2, 3));
|
||||
+ __THROW __nonnull ((2)) __fortified_attr_access (__write_only__, 2, 3);
|
||||
|
||||
/* Open a master pseudo terminal and return its file descriptor. */
|
||||
extern int getpt (void);
|
||||
diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h
|
||||
index 67ae2c6b50435368..5731274848260ad2 100644
|
||||
--- a/string/bits/string_fortified.h
|
||||
+++ b/string/bits/string_fortified.h
|
||||
@@ -64,7 +64,7 @@ __NTH (memset (void *__dest, int __ch, size_t __len))
|
||||
# include <bits/strings_fortified.h>
|
||||
|
||||
void __explicit_bzero_chk (void *__dest, size_t __len, size_t __destlen)
|
||||
- __THROW __nonnull ((1)) __attr_access ((__write_only__, 1, 2));
|
||||
+ __THROW __nonnull ((1)) __fortified_attr_access (__write_only__, 1, 2);
|
||||
|
||||
__fortify_function void
|
||||
__NTH (explicit_bzero (void *__dest, size_t __len))
|
||||
@@ -106,7 +106,8 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||
#else
|
||||
extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
|
||||
size_t __destlen) __THROW
|
||||
- __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2));
|
||||
+ __fortified_attr_access ((__write_only__, 1, 3))
|
||||
+ __attr_access ((__read_only__, 2));
|
||||
extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src,
|
||||
size_t __n), stpncpy);
|
||||
|
||||
diff --git a/string/string.h b/string/string.h
|
||||
index 04e1b7067dc31d3c..8dcafb4ac4952853 100644
|
||||
--- a/string/string.h
|
||||
+++ b/string/string.h
|
||||
@@ -448,7 +448,7 @@ extern char *strerror_l (int __errnum, locale_t __l) __THROW;
|
||||
/* Set N bytes of S to 0. The compiler will not delete a call to this
|
||||
function, even if S is dead after the call. */
|
||||
extern void explicit_bzero (void *__s, size_t __n) __THROW __nonnull ((1))
|
||||
- __attr_access ((__write_only__, 1, 2));
|
||||
+ __fortified_attr_access (__write_only__, 1, 2);
|
||||
|
||||
/* Return the next DELIM-delimited token from *STRINGP,
|
||||
terminating it with a '\0', and update *STRINGP to point past it. */
|
1038
SOURCES/glibc-upstream-2.34-126.patch
Normal file
1038
SOURCES/glibc-upstream-2.34-126.patch
Normal file
File diff suppressed because it is too large
Load Diff
358
SOURCES/glibc-upstream-2.34-127.patch
Normal file
358
SOURCES/glibc-upstream-2.34-127.patch
Normal file
@ -0,0 +1,358 @@
|
||||
commit 536910724d30a38eeecd14cdbe2c93c78ea67646
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Wed Oct 20 18:13:05 2021 +0530
|
||||
|
||||
debug: Add tests for _FORTIFY_SOURCE=3
|
||||
|
||||
Add some testing coverage for _FORTIFY_SOURCE=3.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
(cherry picked from commit ad6f2a010c2ce759936de4747f6e0d53991912f8)
|
||||
|
||||
diff --git a/debug/Makefile b/debug/Makefile
|
||||
index 6893111cbfaa0900..357f888246061e15 100644
|
||||
--- a/debug/Makefile
|
||||
+++ b/debug/Makefile
|
||||
@@ -120,6 +120,8 @@ CFLAGS-tst-chk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
CFLAGS-tst-chk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
CFLAGS-tst-chk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
CFLAGS-tst-chk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
+CFLAGS-tst-chk7.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
+CFLAGS-tst-chk8.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
CFLAGS-tst-lfschk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
CFLAGS-tst-lfschk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
CFLAGS-tst-lfschk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
@@ -129,6 +131,7 @@ CFLAGS-tst-lfschk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
LDLIBS-tst-chk4 = -lstdc++
|
||||
LDLIBS-tst-chk5 = -lstdc++
|
||||
LDLIBS-tst-chk6 = -lstdc++
|
||||
+LDLIBS-tst-chk8 = -lstdc++
|
||||
LDLIBS-tst-lfschk4 = -lstdc++
|
||||
LDLIBS-tst-lfschk5 = -lstdc++
|
||||
LDLIBS-tst-lfschk6 = -lstdc++
|
||||
@@ -150,16 +153,16 @@ CFLAGS-tst-ssp-1.c += -fstack-protector-all
|
||||
|
||||
tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
|
||||
tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
|
||||
- tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \
|
||||
- tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \
|
||||
- tst-backtrace5 tst-backtrace6
|
||||
+ tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \
|
||||
+ tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \
|
||||
+ tst-backtrace4 tst-backtrace5 tst-backtrace6
|
||||
|
||||
ifeq ($(have-ssp),yes)
|
||||
tests += tst-ssp-1
|
||||
endif
|
||||
|
||||
ifeq (,$(CXX))
|
||||
-tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \
|
||||
+tests-unsupported = tst-chk4 tst-chk5 tst-chk6 tst-chk8 \
|
||||
tst-lfschk4 tst-lfschk5 tst-lfschk6
|
||||
endif
|
||||
|
||||
@@ -193,6 +196,8 @@ $(objpfx)tst-chk3.out: $(gen-locales)
|
||||
$(objpfx)tst-chk4.out: $(gen-locales)
|
||||
$(objpfx)tst-chk5.out: $(gen-locales)
|
||||
$(objpfx)tst-chk6.out: $(gen-locales)
|
||||
+$(objpfx)tst-chk7.out: $(gen-locales)
|
||||
+$(objpfx)tst-chk8.out: $(gen-locales)
|
||||
$(objpfx)tst-lfschk1.out: $(gen-locales)
|
||||
$(objpfx)tst-lfschk2.out: $(gen-locales)
|
||||
$(objpfx)tst-lfschk3.out: $(gen-locales)
|
||||
diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
|
||||
index 6c1d32cc62c3a964..68ac00d1808382b8 100644
|
||||
--- a/debug/tst-chk1.c
|
||||
+++ b/debug/tst-chk1.c
|
||||
@@ -83,8 +83,14 @@ handler (int sig)
|
||||
_exit (127);
|
||||
}
|
||||
|
||||
+#if __USE_FORTIFY_LEVEL == 3
|
||||
+volatile size_t buf_size = 10;
|
||||
+#else
|
||||
char buf[10];
|
||||
wchar_t wbuf[10];
|
||||
+#define buf_size sizeof (buf)
|
||||
+#endif
|
||||
+
|
||||
volatile size_t l0;
|
||||
volatile char *p;
|
||||
volatile wchar_t *wp;
|
||||
@@ -123,6 +129,10 @@ int num2 = 987654;
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
+#if __USE_FORTIFY_LEVEL == 3
|
||||
+ char *buf = (char *) malloc (buf_size);
|
||||
+ wchar_t *wbuf = (wchar_t *) malloc (buf_size * sizeof (wchar_t));
|
||||
+#endif
|
||||
set_fortify_handler (handler);
|
||||
|
||||
struct A { char buf1[9]; char buf2[1]; } a;
|
||||
@@ -947,93 +957,93 @@ do_test (void)
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
- if (fgets (buf, sizeof (buf), stdin) != buf
|
||||
+ if (fgets (buf, buf_size, stdin) != buf
|
||||
|| memcmp (buf, "abcdefgh\n", 10))
|
||||
FAIL ();
|
||||
- if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
|
||||
+ if (fgets (buf, buf_size, stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
|
||||
FAIL ();
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
- if (fgets (buf, l0 + sizeof (buf), stdin) != buf
|
||||
+ if (fgets (buf, l0 + buf_size, stdin) != buf
|
||||
|| memcmp (buf, "abcdefgh\n", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
- if (fgets (buf, sizeof (buf) + 1, stdin) != buf)
|
||||
+ if (fgets (buf, buf_size + 1, stdin) != buf)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
- if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf)
|
||||
+ if (fgets (buf, l0 + buf_size + 1, stdin) != buf)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
- if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
|
||||
+ if (fgets_unlocked (buf, buf_size, stdin) != buf
|
||||
|| memcmp (buf, "abcdefgh\n", 10))
|
||||
FAIL ();
|
||||
- if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
|
||||
+ if (fgets_unlocked (buf, buf_size, stdin) != buf
|
||||
|| memcmp (buf, "ABCDEFGHI", 10))
|
||||
FAIL ();
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
- if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf
|
||||
+ if (fgets_unlocked (buf, l0 + buf_size, stdin) != buf
|
||||
|| memcmp (buf, "abcdefgh\n", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
- if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf)
|
||||
+ if (fgets_unlocked (buf, buf_size + 1, stdin) != buf)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
- if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf)
|
||||
+ if (fgets_unlocked (buf, l0 + buf_size + 1, stdin) != buf)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
- if (fread (buf, 1, sizeof (buf), stdin) != sizeof (buf)
|
||||
+ if (fread (buf, 1, buf_size, stdin) != buf_size
|
||||
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||
FAIL ();
|
||||
- if (fread (buf, sizeof (buf), 1, stdin) != 1
|
||||
+ if (fread (buf, buf_size, 1, stdin) != 1
|
||||
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||
FAIL ();
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
- if (fread (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
|
||||
+ if (fread (buf, l0 + 1, buf_size, stdin) != buf_size
|
||||
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||
FAIL ();
|
||||
- if (fread (buf, sizeof (buf), l0 + 1, stdin) != 1
|
||||
+ if (fread (buf, buf_size, l0 + 1, stdin) != 1
|
||||
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
- if (fread (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
|
||||
+ if (fread (buf, 1, buf_size + 1, stdin) != buf_size + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
- if (fread (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
|
||||
+ if (fread (buf, buf_size + 1, l0 + 1, stdin) != 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
- if (fread_unlocked (buf, 1, sizeof (buf), stdin) != sizeof (buf)
|
||||
+ if (fread_unlocked (buf, 1, buf_size, stdin) != buf_size
|
||||
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||
FAIL ();
|
||||
- if (fread_unlocked (buf, sizeof (buf), 1, stdin) != 1
|
||||
+ if (fread_unlocked (buf, buf_size, 1, stdin) != 1
|
||||
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||
FAIL ();
|
||||
|
||||
@@ -1048,100 +1058,100 @@ do_test (void)
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
- if (fread_unlocked (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
|
||||
+ if (fread_unlocked (buf, l0 + 1, buf_size, stdin) != buf_size
|
||||
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||
FAIL ();
|
||||
- if (fread_unlocked (buf, sizeof (buf), l0 + 1, stdin) != 1
|
||||
+ if (fread_unlocked (buf, buf_size, l0 + 1, stdin) != 1
|
||||
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
- if (fread_unlocked (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
|
||||
+ if (fread_unlocked (buf, 1, buf_size + 1, stdin) != buf_size + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
- if (fread_unlocked (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
|
||||
+ if (fread_unlocked (buf, buf_size + 1, l0 + 1, stdin) != 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
lseek (fileno (stdin), 0, SEEK_SET);
|
||||
|
||||
- if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
|
||||
+ if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
|
||||
|| memcmp (buf, "abcdefgh\n", 9))
|
||||
FAIL ();
|
||||
- if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
|
||||
+ if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
|
||||
|| memcmp (buf, "ABCDEFGHI", 9))
|
||||
FAIL ();
|
||||
|
||||
lseek (fileno (stdin), 0, SEEK_SET);
|
||||
|
||||
- if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1
|
||||
+ if (read (fileno (stdin), buf, l0 + buf_size - 1) != buf_size - 1
|
||||
|| memcmp (buf, "abcdefgh\n", 9))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
- if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1)
|
||||
+ if (read (fileno (stdin), buf, buf_size + 1) != buf_size + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
- if (read (fileno (stdin), buf, l0 + sizeof (buf) + 1) != sizeof (buf) + 1)
|
||||
+ if (read (fileno (stdin), buf, l0 + buf_size + 1) != buf_size + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
- if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
|
||||
- != sizeof (buf) - 1
|
||||
+ if (pread (fileno (stdin), buf, buf_size - 1, buf_size - 2)
|
||||
+ != buf_size - 1
|
||||
|| memcmp (buf, "\nABCDEFGH", 9))
|
||||
FAIL ();
|
||||
- if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
|
||||
+ if (pread (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
|
||||
|| memcmp (buf, "abcdefgh\n", 9))
|
||||
FAIL ();
|
||||
- if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
|
||||
- != sizeof (buf) - 1
|
||||
+ if (pread (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
|
||||
+ != buf_size - 1
|
||||
|| memcmp (buf, "h\nABCDEFG", 9))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
- if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
|
||||
- != sizeof (buf) + 1)
|
||||
+ if (pread (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
|
||||
+ != buf_size + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
- if (pread (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
|
||||
- != sizeof (buf) + 1)
|
||||
+ if (pread (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
|
||||
+ != buf_size + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
- if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
|
||||
- != sizeof (buf) - 1
|
||||
+ if (pread64 (fileno (stdin), buf, buf_size - 1, buf_size - 2)
|
||||
+ != buf_size - 1
|
||||
|| memcmp (buf, "\nABCDEFGH", 9))
|
||||
FAIL ();
|
||||
- if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
|
||||
+ if (pread64 (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
|
||||
|| memcmp (buf, "abcdefgh\n", 9))
|
||||
FAIL ();
|
||||
- if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
|
||||
- != sizeof (buf) - 1
|
||||
+ if (pread64 (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
|
||||
+ != buf_size - 1
|
||||
|| memcmp (buf, "h\nABCDEFG", 9))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
- if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
|
||||
- != sizeof (buf) + 1)
|
||||
+ if (pread64 (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
|
||||
+ != buf_size + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
- if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
|
||||
- != sizeof (buf) + 1)
|
||||
+ if (pread64 (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
|
||||
+ != buf_size + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
@@ -1179,7 +1189,7 @@ do_test (void)
|
||||
CHK_FAIL2_END
|
||||
|
||||
CHK_FAIL2_START
|
||||
- snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4);
|
||||
+ snprintf (buf, buf_size, "%3$d\n", 1, 2, 3, 4);
|
||||
CHK_FAIL2_END
|
||||
|
||||
int sp[2];
|
||||
diff --git a/debug/tst-chk7.c b/debug/tst-chk7.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..2a7b32381268135c
|
||||
--- /dev/null
|
||||
+++ b/debug/tst-chk7.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define _FORTIFY_SOURCE 3
|
||||
+#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-chk8.cc b/debug/tst-chk8.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000..2a7b32381268135c
|
||||
--- /dev/null
|
||||
+++ b/debug/tst-chk8.cc
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define _FORTIFY_SOURCE 3
|
||||
+#include "tst-chk1.c"
|
24
SOURCES/glibc-upstream-2.34-128.patch
Normal file
24
SOURCES/glibc-upstream-2.34-128.patch
Normal file
@ -0,0 +1,24 @@
|
||||
commit 98ea9372cc8d60b12aa33e007fdd5f5fb042a651
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Thu Dec 16 07:19:14 2021 +0530
|
||||
|
||||
__glibc_unsafe_len: Fix comment
|
||||
|
||||
We know that the length is *unsafe*.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
(cherry picked from commit ae23fa3e5fe24daf94fc7f8e5268bb8ceeda7477)
|
||||
|
||||
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
|
||||
index 4825ff0351c1e5d4..3bb9f38916e30295 100644
|
||||
--- a/misc/sys/cdefs.h
|
||||
+++ b/misc/sys/cdefs.h
|
||||
@@ -168,7 +168,7 @@
|
||||
__s, __osz)) \
|
||||
&& __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
|
||||
|
||||
-/* Conversely, we know at compile time that the length is safe if the
|
||||
+/* Conversely, we know at compile time that the length is unsafe if the
|
||||
__L * __S <= __OBJSZ condition can be folded to a constant and if it is
|
||||
false. */
|
||||
#define __glibc_unsafe_len(__l, __s, __osz) \
|
91
SOURCES/glibc-upstream-2.34-129.patch
Normal file
91
SOURCES/glibc-upstream-2.34-129.patch
Normal file
@ -0,0 +1,91 @@
|
||||
commit 10f7bdebe570e42d1f7a43de4f90eda8ccb4f0da
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Fri Dec 17 18:35:44 2021 +0530
|
||||
|
||||
fortify: Fix spurious warning with realpath
|
||||
|
||||
The length and object size arguments were swapped around for realpath.
|
||||
Also add a smoke test so that any changes in this area get caught in
|
||||
future.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
(cherry picked from commit 2bbd07c715275eb6c616988925738a0517180d57)
|
||||
|
||||
diff --git a/debug/Makefile b/debug/Makefile
|
||||
index 357f888246061e15..bc37e466eed490fa 100644
|
||||
--- a/debug/Makefile
|
||||
+++ b/debug/Makefile
|
||||
@@ -108,6 +108,7 @@ CFLAGS-tst-longjmp_chk2.c += -fexceptions -fasynchronous-unwind-tables
|
||||
CPPFLAGS-tst-longjmp_chk2.c += -D_FORTIFY_SOURCE=1
|
||||
CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables
|
||||
CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1
|
||||
+CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2
|
||||
|
||||
# We know these tests have problems with format strings, this is what
|
||||
# we are testing. Disable that warning. They are also testing
|
||||
@@ -155,7 +156,7 @@ tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
|
||||
tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
|
||||
tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \
|
||||
tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \
|
||||
- tst-backtrace4 tst-backtrace5 tst-backtrace6
|
||||
+ tst-backtrace4 tst-backtrace5 tst-backtrace6 tst-realpath-chk
|
||||
|
||||
ifeq ($(have-ssp),yes)
|
||||
tests += tst-ssp-1
|
||||
diff --git a/debug/tst-realpath-chk.c b/debug/tst-realpath-chk.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..a8fcb327c43fb34d
|
||||
--- /dev/null
|
||||
+++ b/debug/tst-realpath-chk.c
|
||||
@@ -0,0 +1,37 @@
|
||||
+/* Smoke test to verify that realpath does not cause spurious warnings.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <limits.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+#ifdef PATH_MAX
|
||||
+ char buf[PATH_MAX + 1];
|
||||
+ char *res = realpath (".", buf);
|
||||
+ TEST_VERIFY (res == buf);
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
|
||||
index 067115eeca123c6d..ccacbdf76a08225a 100644
|
||||
--- a/stdlib/bits/stdlib.h
|
||||
+++ b/stdlib/bits/stdlib.h
|
||||
@@ -42,7 +42,7 @@ __NTH (realpath (const char *__restrict __name, char *__restrict __resolved))
|
||||
return __realpath_alias (__name, __resolved);
|
||||
|
||||
#if defined _LIBC_LIMITS_H_ && defined PATH_MAX
|
||||
- if (__glibc_unsafe_len (sz, sizeof (char), PATH_MAX))
|
||||
+ if (__glibc_unsafe_len (PATH_MAX, sizeof (char), sz))
|
||||
return __realpath_chk_warn (__name, __resolved, sz);
|
||||
#endif
|
||||
return __realpath_chk (__name, __resolved, sz);
|
42
SOURCES/glibc-upstream-2.34-130.patch
Normal file
42
SOURCES/glibc-upstream-2.34-130.patch
Normal file
@ -0,0 +1,42 @@
|
||||
commit d6a58bd81d07322ff5da8f419d8620ef037b6a36
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Wed Jan 12 18:46:28 2022 +0530
|
||||
|
||||
Enable _FORTIFY_SOURCE=3 for gcc 12 and above
|
||||
|
||||
gcc 12 now has support for the __builtin_dynamic_object_size builtin.
|
||||
Adapt the macro checks to enable _FORTIFY_SOURCE=3 on gcc 12 and above.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
(cherry picked from commit 86bf0feb0e3ec8e37872f72499d6ae33406561d7)
|
||||
|
||||
diff --git a/include/features.h b/include/features.h
|
||||
index d974eabfafc24ffb..933499bcff8f1449 100644
|
||||
--- a/include/features.h
|
||||
+++ b/include/features.h
|
||||
@@ -412,7 +412,9 @@
|
||||
# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
|
||||
# elif !__GNUC_PREREQ (4, 1)
|
||||
# warning _FORTIFY_SOURCE requires GCC 4.1 or later
|
||||
-# elif _FORTIFY_SOURCE > 2 && __glibc_clang_prereq (9, 0)
|
||||
+# elif _FORTIFY_SOURCE > 2 && (__glibc_clang_prereq (9, 0) \
|
||||
+ || __GNUC_PREREQ (12, 0))
|
||||
+
|
||||
# if _FORTIFY_SOURCE > 3
|
||||
# warning _FORTIFY_SOURCE > 3 is treated like 3 on this platform
|
||||
# endif
|
||||
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
|
||||
index 3bb9f38916e30295..515fb681a0547217 100644
|
||||
--- a/misc/sys/cdefs.h
|
||||
+++ b/misc/sys/cdefs.h
|
||||
@@ -142,7 +142,8 @@
|
||||
#define __bos0(ptr) __builtin_object_size (ptr, 0)
|
||||
|
||||
/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */
|
||||
-#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0)
|
||||
+#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \
|
||||
+ || __GNUC_PREREQ (12, 0))
|
||||
# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
|
||||
# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
|
||||
#else
|
293
SOURCES/glibc-upstream-2.34-131.patch
Normal file
293
SOURCES/glibc-upstream-2.34-131.patch
Normal file
@ -0,0 +1,293 @@
|
||||
commit f8c2f620f1929ad78cb0a247601bec972f140c51
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Wed Jan 12 23:34:23 2022 +0530
|
||||
|
||||
debug: Autogenerate _FORTIFY_SOURCE tests
|
||||
|
||||
Rename debug/tst-chk1.c to debug/tst-fortify.c and add make hackery to
|
||||
autogenerate tests with different macros enabled to build and run the
|
||||
same test with different configurations as well as different
|
||||
fortification levels.
|
||||
|
||||
The change also ends up expanding the -lfs tests to include
|
||||
_FORTIFY_SOURCE=3.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
(cherry picked from commit db27f1251b008280a29d540b4f8ab2a38a0d80af)
|
||||
|
||||
diff --git a/Makerules b/Makerules
|
||||
index 596fa68376f45298..7fbe85719aacc230 100644
|
||||
--- a/Makerules
|
||||
+++ b/Makerules
|
||||
@@ -424,6 +424,12 @@ $(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c)
|
||||
endef
|
||||
object-suffixes-left := $(all-object-suffixes)
|
||||
include $(o-iterator)
|
||||
+
|
||||
+define o-iterator-doit
|
||||
+$(objpfx)%$o: $(objpfx)%.cc $(before-compile); $$(compile-command.cc)
|
||||
+endef
|
||||
+object-suffixes-left := $(all-object-suffixes)
|
||||
+include $(o-iterator)
|
||||
endif
|
||||
|
||||
# Generate .dT files as we compile.
|
||||
diff --git a/debug/Makefile b/debug/Makefile
|
||||
index bc37e466eed490fa..acc1b8f6ad029c62 100644
|
||||
--- a/debug/Makefile
|
||||
+++ b/debug/Makefile
|
||||
@@ -1,4 +1,5 @@
|
||||
-# Copyright (C) 1998-2021 Free Software Foundation, Inc.
|
||||
+# Copyright (C) 1998-2022 Free Software Foundation, Inc.
|
||||
+# Copyright The GNU Toolchain Authors.
|
||||
# This file is part of the GNU C Library.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -110,32 +111,60 @@ CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables
|
||||
CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1
|
||||
CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2
|
||||
|
||||
+# _FORTIFY_SOURCE tests.
|
||||
+# Auto-generate tests for _FORTIFY_SOURCE for different levels, compilers and
|
||||
+# preprocessor conditions based on tst-fortify.c.
|
||||
+#
|
||||
+# To add a new test condition, define a cflags-$(cond) make variable to set
|
||||
+# CFLAGS for the file.
|
||||
+
|
||||
+tests-all-chk = tst-fortify
|
||||
+tests-c-chk =
|
||||
+tests-cc-chk =
|
||||
+
|
||||
+CFLAGS-tst-fortify.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
+
|
||||
+# No additional flags for the default tests.
|
||||
+define cflags-default
|
||||
+endef
|
||||
+
|
||||
+define cflags-lfs
|
||||
+CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64
|
||||
+endef
|
||||
+
|
||||
# We know these tests have problems with format strings, this is what
|
||||
# we are testing. Disable that warning. They are also testing
|
||||
# deprecated functions (notably gets) so disable that warning as well.
|
||||
# And they also generate warnings from warning attributes, which
|
||||
# cannot be disabled via pragmas, so require -Wno-error to be used.
|
||||
-CFLAGS-tst-chk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-chk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-chk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-chk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-chk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-chk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-chk7.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-chk8.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-lfschk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-lfschk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-lfschk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-lfschk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-lfschk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-CFLAGS-tst-lfschk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||
-LDLIBS-tst-chk4 = -lstdc++
|
||||
-LDLIBS-tst-chk5 = -lstdc++
|
||||
-LDLIBS-tst-chk6 = -lstdc++
|
||||
-LDLIBS-tst-chk8 = -lstdc++
|
||||
-LDLIBS-tst-lfschk4 = -lstdc++
|
||||
-LDLIBS-tst-lfschk5 = -lstdc++
|
||||
-LDLIBS-tst-lfschk6 = -lstdc++
|
||||
+define gen-chk-test
|
||||
+tests-$(1)-chk += tst-fortify-$(1)-$(2)-$(3)
|
||||
+CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \
|
||||
+ -Wno-deprecated-declarations \
|
||||
+ -Wno-error
|
||||
+$(eval $(call cflags-$(2),$(1),$(3)))
|
||||
+$(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile
|
||||
+ ( echo "/* Autogenerated from Makefile. */"; \
|
||||
+ echo ""; \
|
||||
+ echo "#include \"tst-fortify.c\"" ) > $$@.tmp
|
||||
+ mv $$@.tmp $$@
|
||||
+endef
|
||||
+
|
||||
+chk-extensions = c cc
|
||||
+chk-types = default lfs
|
||||
+chk-levels = 1 2 3
|
||||
+
|
||||
+$(foreach e,$(chk-extensions), \
|
||||
+ $(foreach t,$(chk-types), \
|
||||
+ $(foreach l,$(chk-levels), \
|
||||
+ $(eval $(call gen-chk-test,$(e),$(t),$(l))))))
|
||||
+
|
||||
+tests-all-chk += $(tests-c-chk) $(tests-cc-chk)
|
||||
+
|
||||
+define link-cc
|
||||
+LDLIBS-$(1) = -lstdc++
|
||||
+endef
|
||||
+$(foreach t,$(tests-cc-chk), $(eval $(call link-cc,$(t))))
|
||||
|
||||
# backtrace_symbols only works if we link with -rdynamic. backtrace
|
||||
# requires unwind tables on most architectures.
|
||||
@@ -152,19 +181,25 @@ LDFLAGS-tst-backtrace6 = -rdynamic
|
||||
|
||||
CFLAGS-tst-ssp-1.c += -fstack-protector-all
|
||||
|
||||
-tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
|
||||
- tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
|
||||
- tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \
|
||||
- tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \
|
||||
- tst-backtrace4 tst-backtrace5 tst-backtrace6 tst-realpath-chk
|
||||
+tests = backtrace-tst \
|
||||
+ tst-longjmp_chk \
|
||||
+ test-strcpy_chk \
|
||||
+ test-stpcpy_chk \
|
||||
+ tst-longjmp_chk2 \
|
||||
+ tst-backtrace2 \
|
||||
+ tst-backtrace3 \
|
||||
+ tst-backtrace4 \
|
||||
+ tst-backtrace5 \
|
||||
+ tst-backtrace6 \
|
||||
+ tst-realpath-chk \
|
||||
+ $(tests-all-chk)
|
||||
|
||||
ifeq ($(have-ssp),yes)
|
||||
tests += tst-ssp-1
|
||||
endif
|
||||
|
||||
ifeq (,$(CXX))
|
||||
-tests-unsupported = tst-chk4 tst-chk5 tst-chk6 tst-chk8 \
|
||||
- tst-lfschk4 tst-lfschk5 tst-lfschk6
|
||||
+tests-unsupported = $(tests-cc-chk)
|
||||
endif
|
||||
|
||||
extra-libs = libSegFault libpcprofile
|
||||
@@ -191,20 +226,10 @@ ifeq ($(run-built-tests),yes)
|
||||
LOCALES := de_DE.UTF-8
|
||||
include ../gen-locales.mk
|
||||
|
||||
-$(objpfx)tst-chk1.out: $(gen-locales)
|
||||
-$(objpfx)tst-chk2.out: $(gen-locales)
|
||||
-$(objpfx)tst-chk3.out: $(gen-locales)
|
||||
-$(objpfx)tst-chk4.out: $(gen-locales)
|
||||
-$(objpfx)tst-chk5.out: $(gen-locales)
|
||||
-$(objpfx)tst-chk6.out: $(gen-locales)
|
||||
-$(objpfx)tst-chk7.out: $(gen-locales)
|
||||
-$(objpfx)tst-chk8.out: $(gen-locales)
|
||||
-$(objpfx)tst-lfschk1.out: $(gen-locales)
|
||||
-$(objpfx)tst-lfschk2.out: $(gen-locales)
|
||||
-$(objpfx)tst-lfschk3.out: $(gen-locales)
|
||||
-$(objpfx)tst-lfschk4.out: $(gen-locales)
|
||||
-$(objpfx)tst-lfschk5.out: $(gen-locales)
|
||||
-$(objpfx)tst-lfschk6.out: $(gen-locales)
|
||||
+define chk-gen-locales
|
||||
+$(objpfx)$(1).out: $(gen-locales)
|
||||
+endef
|
||||
+$(foreach t, $(tests-all-chk), $(eval $(call chk-gen-locales,$(t))))
|
||||
endif
|
||||
|
||||
sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,')
|
||||
diff --git a/debug/tst-chk2.c b/debug/tst-chk2.c
|
||||
deleted file mode 100644
|
||||
index be37ce2d22f0760a..0000000000000000
|
||||
--- a/debug/tst-chk2.c
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FORTIFY_SOURCE 1
|
||||
-#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-chk3.c b/debug/tst-chk3.c
|
||||
deleted file mode 100644
|
||||
index 38b8e4fb360ba722..0000000000000000
|
||||
--- a/debug/tst-chk3.c
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FORTIFY_SOURCE 2
|
||||
-#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-chk4.cc b/debug/tst-chk4.cc
|
||||
deleted file mode 100644
|
||||
index c82e6aac86038791..0000000000000000
|
||||
--- a/debug/tst-chk4.cc
|
||||
+++ /dev/null
|
||||
@@ -1 +0,0 @@
|
||||
-#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-chk5.cc b/debug/tst-chk5.cc
|
||||
deleted file mode 100644
|
||||
index be37ce2d22f0760a..0000000000000000
|
||||
--- a/debug/tst-chk5.cc
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FORTIFY_SOURCE 1
|
||||
-#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-chk6.cc b/debug/tst-chk6.cc
|
||||
deleted file mode 100644
|
||||
index 38b8e4fb360ba722..0000000000000000
|
||||
--- a/debug/tst-chk6.cc
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FORTIFY_SOURCE 2
|
||||
-#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-chk7.c b/debug/tst-chk7.c
|
||||
deleted file mode 100644
|
||||
index 2a7b32381268135c..0000000000000000
|
||||
--- a/debug/tst-chk7.c
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FORTIFY_SOURCE 3
|
||||
-#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-chk8.cc b/debug/tst-chk8.cc
|
||||
deleted file mode 100644
|
||||
index 2a7b32381268135c..0000000000000000
|
||||
--- a/debug/tst-chk8.cc
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FORTIFY_SOURCE 3
|
||||
-#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-chk1.c b/debug/tst-fortify.c
|
||||
similarity index 100%
|
||||
rename from debug/tst-chk1.c
|
||||
rename to debug/tst-fortify.c
|
||||
diff --git a/debug/tst-lfschk1.c b/debug/tst-lfschk1.c
|
||||
deleted file mode 100644
|
||||
index f3e6d47d5e4484c3..0000000000000000
|
||||
--- a/debug/tst-lfschk1.c
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FILE_OFFSET_BITS 64
|
||||
-#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-lfschk2.c b/debug/tst-lfschk2.c
|
||||
deleted file mode 100644
|
||||
index 95d4db1d32d2eeb3..0000000000000000
|
||||
--- a/debug/tst-lfschk2.c
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FILE_OFFSET_BITS 64
|
||||
-#include "tst-chk2.c"
|
||||
diff --git a/debug/tst-lfschk3.c b/debug/tst-lfschk3.c
|
||||
deleted file mode 100644
|
||||
index 50a1ae1258f1553d..0000000000000000
|
||||
--- a/debug/tst-lfschk3.c
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FILE_OFFSET_BITS 64
|
||||
-#include "tst-chk3.c"
|
||||
diff --git a/debug/tst-lfschk4.cc b/debug/tst-lfschk4.cc
|
||||
deleted file mode 100644
|
||||
index f3e6d47d5e4484c3..0000000000000000
|
||||
--- a/debug/tst-lfschk4.cc
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FILE_OFFSET_BITS 64
|
||||
-#include "tst-chk1.c"
|
||||
diff --git a/debug/tst-lfschk5.cc b/debug/tst-lfschk5.cc
|
||||
deleted file mode 100644
|
||||
index 95d4db1d32d2eeb3..0000000000000000
|
||||
--- a/debug/tst-lfschk5.cc
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FILE_OFFSET_BITS 64
|
||||
-#include "tst-chk2.c"
|
||||
diff --git a/debug/tst-lfschk6.cc b/debug/tst-lfschk6.cc
|
||||
deleted file mode 100644
|
||||
index 50a1ae1258f1553d..0000000000000000
|
||||
--- a/debug/tst-lfschk6.cc
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define _FILE_OFFSET_BITS 64
|
||||
-#include "tst-chk3.c"
|
356
SOURCES/glibc-upstream-2.34-132.patch
Normal file
356
SOURCES/glibc-upstream-2.34-132.patch
Normal file
@ -0,0 +1,356 @@
|
||||
commit 224d8c1890b6c57c7e4e8ddbb792dd9552086704
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Wed Jan 12 23:34:48 2022 +0530
|
||||
|
||||
debug: Synchronize feature guards in fortified functions [BZ #28746]
|
||||
|
||||
Some functions (e.g. stpcpy, pread64, etc.) had moved to POSIX in the
|
||||
main headers as they got incorporated into the standard, but their
|
||||
fortified variants remained under __USE_GNU. As a result, these
|
||||
functions did not get fortified when _GNU_SOURCE was not defined.
|
||||
|
||||
Add test wrappers that check all functions tested in tst-chk0 at all
|
||||
levels with _GNU_SOURCE undefined and then use the failures to (1)
|
||||
exclude checks for _GNU_SOURCE functions in these tests and (2) Fix
|
||||
feature macro guards in the fortified function headers so that they're
|
||||
the same as the ones in the main headers.
|
||||
|
||||
This fixes BZ #28746.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
(cherry picked from commit fcfc9086815bf0d277ad47a90ee3fda4c37acca8)
|
||||
|
||||
diff --git a/debug/Makefile b/debug/Makefile
|
||||
index acc1b8f6ad029c62..71248e0d457a5b12 100644
|
||||
--- a/debug/Makefile
|
||||
+++ b/debug/Makefile
|
||||
@@ -132,6 +132,12 @@ define cflags-lfs
|
||||
CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64
|
||||
endef
|
||||
|
||||
+define cflags-nongnu
|
||||
+CFLAGS-tst-fortify-$(1)-nongnu-$(2).$(1) += -D_LARGEFILE64_SOURCE=1
|
||||
+endef
|
||||
+
|
||||
+src-chk-nongnu = \#undef _GNU_SOURCE
|
||||
+
|
||||
# We know these tests have problems with format strings, this is what
|
||||
# we are testing. Disable that warning. They are also testing
|
||||
# deprecated functions (notably gets) so disable that warning as well.
|
||||
@@ -145,13 +151,13 @@ CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \
|
||||
$(eval $(call cflags-$(2),$(1),$(3)))
|
||||
$(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile
|
||||
( echo "/* Autogenerated from Makefile. */"; \
|
||||
- echo ""; \
|
||||
+ echo "$(src-chk-$(2))"; \
|
||||
echo "#include \"tst-fortify.c\"" ) > $$@.tmp
|
||||
mv $$@.tmp $$@
|
||||
endef
|
||||
|
||||
chk-extensions = c cc
|
||||
-chk-types = default lfs
|
||||
+chk-types = default lfs nongnu
|
||||
chk-levels = 1 2 3
|
||||
|
||||
$(foreach e,$(chk-extensions), \
|
||||
diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
|
||||
index 68ac00d1808382b8..8b5902423cf0ad88 100644
|
||||
--- a/debug/tst-fortify.c
|
||||
+++ b/debug/tst-fortify.c
|
||||
@@ -1,4 +1,5 @@
|
||||
-/* Copyright (C) 2004-2021 Free Software Foundation, Inc.
|
||||
+/* Copyright (C) 2004-2022 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
|
||||
|
||||
@@ -37,6 +38,17 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
+#ifndef _GNU_SOURCE
|
||||
+# define MEMPCPY memcpy
|
||||
+# define WMEMPCPY wmemcpy
|
||||
+# define MEMPCPY_RET(x) 0
|
||||
+# define WMEMPCPY_RET(x) 0
|
||||
+#else
|
||||
+# define MEMPCPY mempcpy
|
||||
+# define WMEMPCPY wmempcpy
|
||||
+# define MEMPCPY_RET(x) __builtin_strlen (x)
|
||||
+# define WMEMPCPY_RET(x) wcslen (x)
|
||||
+#endif
|
||||
|
||||
#define obstack_chunk_alloc malloc
|
||||
#define obstack_chunk_free free
|
||||
@@ -163,7 +175,7 @@ do_test (void)
|
||||
if (memcmp (buf, "aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
- if (mempcpy (buf + 5, "abcde", 5) != buf + 10
|
||||
+ if (MEMPCPY (buf + 5, "abcde", 5) != buf + 5 + MEMPCPY_RET ("abcde")
|
||||
|| memcmp (buf, "aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
@@ -208,7 +220,7 @@ do_test (void)
|
||||
if (memcmp (buf, "aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
- if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10
|
||||
+ if (MEMPCPY (buf + 5, "abcde", l0 + 5) != buf + 5 + MEMPCPY_RET ("abcde")
|
||||
|| memcmp (buf, "aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
@@ -267,7 +279,8 @@ do_test (void)
|
||||
if (memcmp (a.buf1, "aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
- if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
|
||||
+ if (MEMPCPY (a.buf1 + 5, "abcde", l0 + 5)
|
||||
+ != a.buf1 + 5 + MEMPCPY_RET ("abcde")
|
||||
|| memcmp (a.buf1, "aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
@@ -348,6 +361,7 @@ do_test (void)
|
||||
bcopy (buf + 1, buf + 2, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
+#ifdef _GNU_SOURCE
|
||||
CHK_FAIL_START
|
||||
p = (char *) mempcpy (buf + 6, "abcde", 5);
|
||||
CHK_FAIL_END
|
||||
@@ -355,6 +369,7 @@ do_test (void)
|
||||
CHK_FAIL_START
|
||||
p = (char *) mempcpy (buf + 6, "abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
+#endif
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (buf + 9, 'j', 2);
|
||||
@@ -465,6 +480,7 @@ do_test (void)
|
||||
bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
+#ifdef _GNU_SOURCE
|
||||
CHK_FAIL_START
|
||||
p = (char *) mempcpy (a.buf1 + 6, "abcde", 5);
|
||||
CHK_FAIL_END
|
||||
@@ -472,6 +488,7 @@ do_test (void)
|
||||
CHK_FAIL_START
|
||||
p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
+#endif
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (a.buf1 + 9, 'j', 2);
|
||||
@@ -551,7 +568,7 @@ do_test (void)
|
||||
if (wmemcmp (wbuf, L"aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
- if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10
|
||||
+ if (WMEMPCPY (wbuf + 5, L"abcde", 5) != wbuf + 5 + WMEMPCPY_RET (L"abcde")
|
||||
|| wmemcmp (wbuf, L"aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
@@ -584,7 +601,8 @@ do_test (void)
|
||||
if (wmemcmp (wbuf, L"aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
- if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10
|
||||
+ if (WMEMPCPY (wbuf + 5, L"abcde", l0 + 5)
|
||||
+ != wbuf + 5 + WMEMPCPY_RET (L"abcde")
|
||||
|| wmemcmp (wbuf, L"aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
@@ -626,7 +644,8 @@ do_test (void)
|
||||
if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
- if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10
|
||||
+ if (WMEMPCPY (wa.buf1 + 5, L"abcde", l0 + 5)
|
||||
+ != wa.buf1 + 5 + WMEMPCPY_RET (L"abcde")
|
||||
|| wmemcmp (wa.buf1, L"aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
@@ -695,6 +714,7 @@ do_test (void)
|
||||
wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
+#ifdef _GNU_SOURCE
|
||||
CHK_FAIL_START
|
||||
wp = wmempcpy (wbuf + 6, L"abcde", 5);
|
||||
CHK_FAIL_END
|
||||
@@ -702,6 +722,7 @@ do_test (void)
|
||||
CHK_FAIL_START
|
||||
wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
+#endif
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemset (wbuf + 9, L'j', 2);
|
||||
@@ -769,6 +790,7 @@ do_test (void)
|
||||
wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
+#ifdef _GNU_SOURCE
|
||||
CHK_FAIL_START
|
||||
wp = wmempcpy (wa.buf1 + 6, L"abcde", 5);
|
||||
CHK_FAIL_END
|
||||
@@ -776,6 +798,7 @@ do_test (void)
|
||||
CHK_FAIL_START
|
||||
wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
+#endif
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemset (wa.buf1 + 9, L'j', 2);
|
||||
@@ -907,6 +930,7 @@ do_test (void)
|
||||
if (fprintf (fp, buf2 + 4, str5) != 7)
|
||||
FAIL ();
|
||||
|
||||
+#ifdef _GNU_SOURCE
|
||||
char *my_ptr = NULL;
|
||||
strcpy (buf2 + 2, "%n%s%n");
|
||||
/* When the format string is writable and contains %n,
|
||||
@@ -936,6 +960,7 @@ do_test (void)
|
||||
if (obstack_printf (&obs, "%s%n%s%n", str4, &n1, str5, &n1) != 14)
|
||||
FAIL ();
|
||||
obstack_free (&obs, NULL);
|
||||
+#endif
|
||||
|
||||
if (freopen (temp_filename, "r", stdin) == NULL)
|
||||
{
|
||||
@@ -983,6 +1008,7 @@ do_test (void)
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
+#ifdef _GNU_SOURCE
|
||||
if (fgets_unlocked (buf, buf_size, stdin) != buf
|
||||
|| memcmp (buf, "abcdefgh\n", 10))
|
||||
FAIL ();
|
||||
@@ -1009,6 +1035,7 @@ do_test (void)
|
||||
#endif
|
||||
|
||||
rewind (stdin);
|
||||
+#endif
|
||||
|
||||
if (fread (buf, 1, buf_size, stdin) != buf_size
|
||||
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||
@@ -1579,7 +1606,10 @@ do_test (void)
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
- int fd = posix_openpt (O_RDWR);
|
||||
+ int fd;
|
||||
+
|
||||
+#ifdef _GNU_SOURCE
|
||||
+ fd = posix_openpt (O_RDWR);
|
||||
if (fd != -1)
|
||||
{
|
||||
char enough[1000];
|
||||
@@ -1595,6 +1625,7 @@ do_test (void)
|
||||
#endif
|
||||
close (fd);
|
||||
}
|
||||
+#endif
|
||||
|
||||
#if PATH_MAX > 0
|
||||
confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf));
|
||||
@@ -1712,8 +1743,9 @@ do_test (void)
|
||||
poll (fds, l0 + 2, 0);
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
+#ifdef _GNU_SOURCE
|
||||
ppoll (fds, 1, NULL, NULL);
|
||||
-#if __USE_FORTIFY_LEVEL >= 1
|
||||
+# if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
ppoll (fds, 2, NULL, NULL);
|
||||
CHK_FAIL_END
|
||||
@@ -1721,6 +1753,7 @@ do_test (void)
|
||||
CHK_FAIL_START
|
||||
ppoll (fds, l0 + 2, NULL, NULL);
|
||||
CHK_FAIL_END
|
||||
+# endif
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h
|
||||
index 697dcbbf7b4b26f6..1df7e5ceef3e1fd4 100644
|
||||
--- a/posix/bits/unistd.h
|
||||
+++ b/posix/bits/unistd.h
|
||||
@@ -40,7 +40,7 @@ read (int __fd, void *__buf, size_t __nbytes)
|
||||
__fd, __buf, __nbytes);
|
||||
}
|
||||
|
||||
-#ifdef __USE_UNIX98
|
||||
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
|
||||
extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes,
|
||||
__off_t __offset, size_t __bufsize)
|
||||
__wur __attr_access ((__write_only__, 2, 3));
|
||||
diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h
|
||||
index 5731274848260ad2..218006c9ba882d9c 100644
|
||||
--- a/string/bits/string_fortified.h
|
||||
+++ b/string/bits/string_fortified.h
|
||||
@@ -79,7 +79,7 @@ __NTH (strcpy (char *__restrict __dest, const char *__restrict __src))
|
||||
return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest));
|
||||
}
|
||||
|
||||
-#ifdef __USE_GNU
|
||||
+#ifdef __USE_XOPEN2K8
|
||||
__fortify_function char *
|
||||
__NTH (stpcpy (char *__restrict __dest, const char *__restrict __src))
|
||||
{
|
||||
@@ -96,14 +96,15 @@ __NTH (strncpy (char *__restrict __dest, const char *__restrict __src,
|
||||
__glibc_objsize (__dest));
|
||||
}
|
||||
|
||||
-#if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6)
|
||||
+#ifdef __USE_XOPEN2K8
|
||||
+# if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6)
|
||||
__fortify_function char *
|
||||
__NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||
{
|
||||
return __builtin___stpncpy_chk (__dest, __src, __n,
|
||||
__glibc_objsize (__dest));
|
||||
}
|
||||
-#else
|
||||
+# else
|
||||
extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
|
||||
size_t __destlen) __THROW
|
||||
__fortified_attr_access ((__write_only__, 1, 3))
|
||||
@@ -119,6 +120,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||
return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
|
||||
return __stpncpy_alias (__dest, __src, __n);
|
||||
}
|
||||
+# endif
|
||||
#endif
|
||||
|
||||
|
||||
diff --git a/support/xsignal.h b/support/xsignal.h
|
||||
index 8ee1fa6b4dceeadf..692e0f2c4242d848 100644
|
||||
--- a/support/xsignal.h
|
||||
+++ b/support/xsignal.h
|
||||
@@ -28,7 +28,9 @@ __BEGIN_DECLS
|
||||
terminate the process on error. */
|
||||
|
||||
void xraise (int sig);
|
||||
+#ifdef _GNU_SOURCE
|
||||
sighandler_t xsignal (int sig, sighandler_t handler);
|
||||
+#endif
|
||||
void xsigaction (int sig, const struct sigaction *newact,
|
||||
struct sigaction *oldact);
|
||||
|
||||
diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
|
||||
index 26012ef9366c0b88..88c1fdfcd34292f4 100644
|
||||
--- a/wcsmbs/bits/wchar2.h
|
||||
+++ b/wcsmbs/bits/wchar2.h
|
||||
@@ -457,7 +457,7 @@ __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src,
|
||||
}
|
||||
|
||||
|
||||
-#ifdef __USE_GNU
|
||||
+#ifdef __USE_XOPEN2K8
|
||||
extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst,
|
||||
const char **__restrict __src, size_t __nmc,
|
||||
size_t __len, mbstate_t *__restrict __ps,
|
178
SOURCES/glibc-upstream-2.34-133.patch
Normal file
178
SOURCES/glibc-upstream-2.34-133.patch
Normal file
@ -0,0 +1,178 @@
|
||||
commit 738ee53f0ce5e39b9b7a6777f5d3057afbaac498
|
||||
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||
Date: Tue Mar 15 23:12:37 2022 +0000
|
||||
|
||||
hppa: Implement swapcontext in assembler (bug 28960)
|
||||
|
||||
When swapcontext.c is compiled without -g, the following error occurs:
|
||||
Error: CFI instruction used without previous .cfi_startproc
|
||||
|
||||
Fix by converting swapcontext routine to assembler.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.S b/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||
new file mode 100644
|
||||
index 0000000000000000..94b164dc6375563e
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||
@@ -0,0 +1,72 @@
|
||||
+/* Swap to new context.
|
||||
+ Copyright (C) 2008-2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library. If not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <sysdep.h>
|
||||
+#include "ucontext_i.h"
|
||||
+
|
||||
+ .text
|
||||
+ENTRY(__swapcontext)
|
||||
+
|
||||
+ /* Copy rp to ret0 (r28). */
|
||||
+ copy %rp,%ret0
|
||||
+
|
||||
+ /* Create a frame. */
|
||||
+ ldo 64(%sp),%sp
|
||||
+ .cfi_def_cfa_offset -64
|
||||
+
|
||||
+ /* Save the current machine context to oucp. */
|
||||
+ bl __getcontext,%rp
|
||||
+
|
||||
+ /* Copy oucp to register ret1 (r29). __getcontext saves and
|
||||
+ restores it on a normal return. It is restored from oR29
|
||||
+ on reactivation. */
|
||||
+ copy %r26,%ret1
|
||||
+
|
||||
+ /* Pop frame. */
|
||||
+ ldo -64(%sp),%sp
|
||||
+ .cfi_def_cfa_offset 0
|
||||
+
|
||||
+ /* Load return pointer from oR28. */
|
||||
+ ldw oR28(%ret1),%rp
|
||||
+
|
||||
+ /* Return if error. */
|
||||
+ or,= %r0,%ret0,%r0
|
||||
+ bv,n %r0(%rp)
|
||||
+
|
||||
+ /* Load sc_sar flag. */
|
||||
+ ldb oSAR(%ret1),%r20
|
||||
+
|
||||
+ /* Return if oucp context has been reactivated. */
|
||||
+ or,= %r0,%r20,%r0
|
||||
+ bv,n %r0(%rp)
|
||||
+
|
||||
+ /* Mark sc_sar flag. */
|
||||
+ ldi 1,%r20
|
||||
+ stb %r20,oSAR(%ret1)
|
||||
+
|
||||
+ /* Activate the machine context in ucp. */
|
||||
+ bl __setcontext,%rp
|
||||
+ ldw oR25(%ret1),%r26
|
||||
+
|
||||
+ /* Load return pointer. */
|
||||
+ ldw oR28(%ret1),%rp
|
||||
+ bv,n %r0(%rp)
|
||||
+
|
||||
+PSEUDO_END(__swapcontext)
|
||||
+
|
||||
+weak_alias (__swapcontext, swapcontext)
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.c b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||
deleted file mode 100644
|
||||
index 1664f68c7b9982e8..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||
+++ /dev/null
|
||||
@@ -1,83 +0,0 @@
|
||||
-/* Swap to new context.
|
||||
- Copyright (C) 2008-2021 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Helge Deller <deller@gmx.de>, 2008.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library. If not, see
|
||||
- <https://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include <ucontext.h>
|
||||
-#include "ucontext_i.h"
|
||||
-
|
||||
-extern int __getcontext (ucontext_t *ucp);
|
||||
-extern int __setcontext (const ucontext_t *ucp);
|
||||
-
|
||||
-int
|
||||
-__swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
|
||||
-{
|
||||
- /* Save rp for debugger. */
|
||||
- asm ("stw %rp,-20(%sp)");
|
||||
- asm (".cfi_offset 2, -20");
|
||||
-
|
||||
- /* Copy rp to ret0 (r28). */
|
||||
- asm ("copy %rp,%ret0");
|
||||
-
|
||||
- /* Create a frame. */
|
||||
- asm ("ldo 64(%sp),%sp");
|
||||
- asm (".cfi_def_cfa_offset -64");
|
||||
-
|
||||
- /* Save the current machine context to oucp. */
|
||||
- asm ("bl __getcontext,%rp");
|
||||
-
|
||||
- /* Copy oucp to register ret1 (r29). __getcontext saves and restores it
|
||||
- on a normal return. It is restored from oR29 on reactivation. */
|
||||
- asm ("copy %r26,%ret1");
|
||||
-
|
||||
- /* Pop frame. */
|
||||
- asm ("ldo -64(%sp),%sp");
|
||||
- asm (".cfi_def_cfa_offset 0");
|
||||
-
|
||||
- /* Load return pointer from oR28. */
|
||||
- asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28));
|
||||
-
|
||||
- /* Return if error. */
|
||||
- asm ("or,= %r0,%ret0,%r0");
|
||||
- asm ("bv,n %r0(%rp)");
|
||||
-
|
||||
- /* Load sc_sar flag. */
|
||||
- asm ("ldb %0(%%ret1),%%r20" : : "i" (oSAR));
|
||||
-
|
||||
- /* Return if oucp context has been reactivated. */
|
||||
- asm ("or,= %r0,%r20,%r0");
|
||||
- asm ("bv,n %r0(%rp)");
|
||||
-
|
||||
- /* Mark sc_sar flag. */
|
||||
- asm ("1: ldi 1,%r20");
|
||||
- asm ("stb %%r20,%0(%%ret1)" : : "i" (oSAR));
|
||||
-
|
||||
- /* Activate the machine context in ucp. */
|
||||
- asm ("bl __setcontext,%rp");
|
||||
- asm ("ldw %0(%%ret1),%%r26" : : "i" (oR25));
|
||||
-
|
||||
- /* Load return pointer. */
|
||||
- asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28));
|
||||
-
|
||||
- /* A successful call to setcontext does not return. */
|
||||
- asm ("bv,n %r0(%rp)");
|
||||
-
|
||||
- /* Make gcc happy. */
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-weak_alias (__swapcontext, swapcontext)
|
20
SOURCES/glibc-upstream-2.34-134.patch
Normal file
20
SOURCES/glibc-upstream-2.34-134.patch
Normal file
@ -0,0 +1,20 @@
|
||||
commit d53b9cc391c72a1011ea8fe7a9f70dc5060a0db2
|
||||
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||
Date: Tue Mar 15 23:04:39 2022 +0000
|
||||
|
||||
hppa: Use END instead of PSEUDO_END in swapcontext.S
|
||||
|
||||
(cherry picked from commit 7a5c440102d4ec7fafd9bbd98eca9bd90ecaaafd)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.S b/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||
index 94b164dc6375563e..fbc22586d1195a0d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||
@@ -67,6 +67,6 @@ ENTRY(__swapcontext)
|
||||
ldw oR28(%ret1),%rp
|
||||
bv,n %r0(%rp)
|
||||
|
||||
-PSEUDO_END(__swapcontext)
|
||||
+END(__swapcontext)
|
||||
|
||||
weak_alias (__swapcontext, swapcontext)
|
35
SOURCES/glibc-upstream-2.34-135.patch
Normal file
35
SOURCES/glibc-upstream-2.34-135.patch
Normal file
@ -0,0 +1,35 @@
|
||||
commit 4b5b8a1cdf39bed02b8b973717796eccde455ed6
|
||||
Author: Fangrui Song <maskray@google.com>
|
||||
Date: Mon Sep 27 10:12:50 2021 -0700
|
||||
|
||||
powerpc: Delete unneeded ELF_MACHINE_BEFORE_RTLD_RELOC
|
||||
|
||||
Reviewed-by: Raphael M Zinsly <rzinsly@linux.ibm.com>
|
||||
(cherry picked from commit 8e2557a2b85b2eb0ed50a9016a4ffc6b859b97e6)
|
||||
|
||||
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
|
||||
index ced3a7b659cfcff1..b93cf486b6cda5fd 100644
|
||||
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
|
||||
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
|
||||
@@ -109,8 +109,6 @@ elf_machine_load_address (void)
|
||||
return runtime_dynamic - elf_machine_dynamic ();
|
||||
}
|
||||
|
||||
-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
|
||||
-
|
||||
/* The PLT uses Elf32_Rela relocs. */
|
||||
#define elf_machine_relplt elf_machine_rela
|
||||
|
||||
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||
index b90f407119efd431..b3f3352bcf5a52b0 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||
@@ -116,8 +116,6 @@ elf_machine_dynamic (void)
|
||||
return runtime_dynamic - elf_machine_load_address() ;
|
||||
}
|
||||
|
||||
-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
|
||||
-
|
||||
/* The PLT uses Elf64_Rela relocs. */
|
||||
#define elf_machine_relplt elf_machine_rela
|
||||
|
2020
SOURCES/glibc-upstream-2.34-136.patch
Normal file
2020
SOURCES/glibc-upstream-2.34-136.patch
Normal file
File diff suppressed because it is too large
Load Diff
241
SOURCES/glibc-upstream-2.34-137.patch
Normal file
241
SOURCES/glibc-upstream-2.34-137.patch
Normal file
@ -0,0 +1,241 @@
|
||||
commit c6df39a0bd2aafd2a4280a0000ef201f30273bee
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Mon Oct 11 16:01:49 2021 -0300
|
||||
|
||||
elf: Fix elf_get_dynamic_info definition
|
||||
|
||||
Before to 490e6c62aa31a8a ('elf: Avoid nested functions in the loader
|
||||
[BZ #27220]'), elf_get_dynamic_info() was defined twice on rtld.c: on
|
||||
the first dynamic-link.h include and later within _dl_start(). The
|
||||
former definition did not define DONT_USE_BOOTSTRAP_MAP and it is used
|
||||
on setup_vdso() (since it is a global definition), while the former does
|
||||
define DONT_USE_BOOTSTRAP_MAP and it is used on loader self-relocation.
|
||||
|
||||
With the commit change, the function is now included and defined once
|
||||
instead of defined as a nested function. So rtld.c defines without
|
||||
defining RTLD_BOOTSTRAP and it brokes at least powerpc32.
|
||||
|
||||
This patch fixes by moving the get-dynamic-info.h include out of
|
||||
dynamic-link.h, which then the caller can corirectly set the expected
|
||||
semantic by defining STATIC_PIE_BOOTSTRAP, RTLD_BOOTSTRAP, and/or
|
||||
RESOLVE_MAP.
|
||||
|
||||
It also required to enable some asserts only for the loader bootstrap
|
||||
to avoid issues when called from setup_vdso().
|
||||
|
||||
As a side note, this is another issues with nested functions: it is
|
||||
not clear from pre-processed output (-E -dD) how the function will
|
||||
be build and its semantic (since nested function will be local and
|
||||
extra C defines may change it).
|
||||
|
||||
I checked on x86_64-linux-gnu (w/o --enable-static-pie),
|
||||
i686-linux-gnu, powerpc64-linux-gnu, powerpc-linux-gnu-power4,
|
||||
aarch64-linux-gnu, arm-linux-gnu, sparc64-linux-gnu, and
|
||||
s390x-linux-gnu.
|
||||
|
||||
Reviewed-by: Fangrui Song <maskray@google.com>
|
||||
(cherry picked from commit 4af6982e4c9fc465ffb7a54b794aaaa134241f05)
|
||||
|
||||
Resolved conflicts:
|
||||
elf/rtld.c
|
||||
|
||||
diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
|
||||
index 5c8e51d19ae095d6..d54356dee3f86ae0 100644
|
||||
--- a/elf/dl-conflict.c
|
||||
+++ b/elf/dl-conflict.c
|
||||
@@ -17,6 +17,7 @@
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <libintl.h>
|
||||
#include <stdlib.h>
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index 0976977fbdf21902..eea06629a978aaf3 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -58,6 +58,7 @@ struct filebuf
|
||||
};
|
||||
|
||||
#include "dynamic-link.h"
|
||||
+#include "get-dynamic-info.h"
|
||||
#include <abi-tag.h>
|
||||
#include <stackinfo.h>
|
||||
#include <sysdep.h>
|
||||
@@ -1295,7 +1296,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||
if (l->l_ld != 0)
|
||||
l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||
|
||||
- elf_get_dynamic_info (l);
|
||||
+ elf_get_dynamic_info (l, false);
|
||||
|
||||
/* Make sure we are not dlopen'ing an object that has the
|
||||
DF_1_NOOPEN flag set, or a PIE object. */
|
||||
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
|
||||
index a52ba8aeb8b573cb..f323b4dd0d5ba279 100644
|
||||
--- a/elf/dl-reloc-static-pie.c
|
||||
+++ b/elf/dl-reloc-static-pie.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#define STATIC_PIE_BOOTSTRAP
|
||||
#define RESOLVE_MAP(map, scope, sym, version, flags) map
|
||||
#include "dynamic-link.h"
|
||||
+#include "get-dynamic-info.h"
|
||||
|
||||
/* Relocate static executable with PIE. */
|
||||
|
||||
@@ -51,7 +52,7 @@ _dl_relocate_static_pie (void)
|
||||
break;
|
||||
}
|
||||
|
||||
- elf_get_dynamic_info (main_map);
|
||||
+ elf_get_dynamic_info (main_map, false);
|
||||
|
||||
# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
|
||||
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info);
|
||||
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||
index 9d0d941000f6114f..61c260ddb81b586c 100644
|
||||
--- a/elf/dl-runtime.c
|
||||
+++ b/elf/dl-runtime.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#define IN_DL_RUNTIME 1 /* This can be tested in dl-machine.h. */
|
||||
|
||||
#include <alloca.h>
|
||||
+#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
|
||||
index 7cc30211649d3820..21cdfc88bbfb89ea 100644
|
||||
--- a/elf/dynamic-link.h
|
||||
+++ b/elf/dynamic-link.h
|
||||
@@ -93,7 +93,6 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||
|
||||
#include <dl-machine.h>
|
||||
|
||||
-#include "get-dynamic-info.h"
|
||||
|
||||
#ifdef RESOLVE_MAP
|
||||
|
||||
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
|
||||
index 15c316b38c05a90c..d169099fbc9897cf 100644
|
||||
--- a/elf/get-dynamic-info.h
|
||||
+++ b/elf/get-dynamic-info.h
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <libc-diag.h>
|
||||
|
||||
static inline void __attribute__ ((unused, always_inline))
|
||||
-elf_get_dynamic_info (struct link_map *l)
|
||||
+elf_get_dynamic_info (struct link_map *l, bool check)
|
||||
{
|
||||
#if __ELF_NATIVE_CLASS == 32
|
||||
typedef Elf32_Word d_tag_utype;
|
||||
@@ -112,16 +112,19 @@ elf_get_dynamic_info (struct link_map *l)
|
||||
assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
|
||||
#endif
|
||||
#ifdef RTLD_BOOTSTRAP
|
||||
- /* Only the bind now flags are allowed. */
|
||||
- assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
|
||||
- || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
|
||||
- /* Flags must not be set for ld.so. */
|
||||
- assert (info[DT_FLAGS] == NULL
|
||||
- || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
|
||||
-#endif
|
||||
-#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
|
||||
- assert (info[DT_RUNPATH] == NULL);
|
||||
- assert (info[DT_RPATH] == NULL);
|
||||
+ if (check)
|
||||
+ {
|
||||
+ /* Only the bind now flags are allowed. */
|
||||
+ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
|
||||
+ || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
|
||||
+ /* Flags must not be set for ld.so. */
|
||||
+ assert (info[DT_FLAGS] == NULL
|
||||
+ || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
|
||||
+# ifdef STATIC_PIE_BOOTSTRAP
|
||||
+ assert (info[DT_RUNPATH] == NULL);
|
||||
+ assert (info[DT_RPATH] == NULL);
|
||||
+# endif
|
||||
+ }
|
||||
#else
|
||||
if (info[DT_FLAGS] != NULL)
|
||||
{
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index ee45657aeac14f3c..352d596dedb42e79 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -514,6 +514,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
|
||||
is trivial: always the map of ld.so itself. */
|
||||
#define RTLD_BOOTSTRAP
|
||||
#define RESOLVE_MAP(map, scope, sym, version, flags) map
|
||||
+#include "get-dynamic-info.h"
|
||||
#include "dynamic-link.h"
|
||||
|
||||
static ElfW(Addr) __attribute_used__
|
||||
@@ -549,7 +550,7 @@ _dl_start (void *arg)
|
||||
/* Read our own dynamic section and fill in the info array. */
|
||||
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
|
||||
bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION;
|
||||
- elf_get_dynamic_info (&bootstrap_map);
|
||||
+ elf_get_dynamic_info (&bootstrap_map, true);
|
||||
|
||||
#if NO_TLS_OFFSET != 0
|
||||
bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
|
||||
@@ -1653,7 +1654,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
if (! rtld_is_main)
|
||||
{
|
||||
/* Extract the contents of the dynamic section for easy access. */
|
||||
- elf_get_dynamic_info (main_map);
|
||||
+ elf_get_dynamic_info (main_map, false);
|
||||
|
||||
/* If the main map is libc.so, update the base namespace to
|
||||
refer to this map. If libc.so is loaded later, this happens
|
||||
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
|
||||
index f44748bc9858e5fd..6fdffafcca5e9916 100644
|
||||
--- a/elf/setup-vdso.h
|
||||
+++ b/elf/setup-vdso.h
|
||||
@@ -64,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||
l->l_map_end += l->l_addr;
|
||||
l->l_text_end += l->l_addr;
|
||||
l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||
- elf_get_dynamic_info (l);
|
||||
+ elf_get_dynamic_info (l, false);
|
||||
_dl_setup_hash (l);
|
||||
l->l_relocated = 1;
|
||||
|
||||
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
|
||||
index 7e6761bbe87540d5..86f866ca7c17bd9b 100644
|
||||
--- a/sysdeps/arm/dl-machine.h
|
||||
+++ b/sysdeps/arm/dl-machine.h
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#define ELF_MACHINE_NAME "ARM"
|
||||
|
||||
+#include <assert.h>
|
||||
#include <sys/param.h>
|
||||
#include <tls.h>
|
||||
#include <dl-tlsdesc.h>
|
||||
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
|
||||
index 78ce890c0ff333ca..fa902612ca8557f9 100644
|
||||
--- a/sysdeps/i386/dl-machine.h
|
||||
+++ b/sysdeps/i386/dl-machine.h
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#define ELF_MACHINE_NAME "i386"
|
||||
|
||||
+#include <assert.h>
|
||||
#include <sys/param.h>
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
|
||||
index d3fcbb37bf1f4f7c..90c77cfea1de8d63 100644
|
||||
--- a/sysdeps/x86_64/dl-machine.h
|
||||
+++ b/sysdeps/x86_64/dl-machine.h
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#define ELF_MACHINE_NAME "x86_64"
|
||||
|
||||
+#include <assert.h>
|
||||
#include <sys/param.h>
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
1115
SOURCES/glibc-upstream-2.34-138.patch
Normal file
1115
SOURCES/glibc-upstream-2.34-138.patch
Normal file
File diff suppressed because it is too large
Load Diff
221
SOURCES/glibc-upstream-2.34-139.patch
Normal file
221
SOURCES/glibc-upstream-2.34-139.patch
Normal file
@ -0,0 +1,221 @@
|
||||
commit f6a54a304223666ea4af73260c99c830d7726eca
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Fri Oct 15 14:35:31 2021 -0300
|
||||
|
||||
elf: Fix elf_get_dynamic_info() for bootstrap
|
||||
|
||||
THe d6d89608ac8c broke powerpc for --enable-bind-now because it turned
|
||||
out that different than patch assumption rtld elf_get_dynamic_info()
|
||||
does require to handle RTLD_BOOTSTRAP to avoid DT_FLAGS and
|
||||
DT_RUNPATH (more specially the GLRO usage which is not reallocate
|
||||
yet).
|
||||
|
||||
This patch fixes by passing two arguments to elf_get_dynamic_info()
|
||||
to inform that by rtld (bootstrap) or static pie initialization
|
||||
(static_pie_bootstrap). I think using explicit argument is way more
|
||||
clear and burried C preprocessor, and compiler should remove the
|
||||
dead code.
|
||||
|
||||
I checked on x86_64 and i686 with default options, --enable-bind-now,
|
||||
and --enable-bind-now and --enable--static-pie. I also check on
|
||||
aarch64, armhf, powerpc64, and powerpc with default and
|
||||
--enable-bind-now.
|
||||
|
||||
(cherry picked from commit 5118dcac68c4eadfd6304bb33adde63d062dc07f)
|
||||
|
||||
Resolved conflicts:
|
||||
elf/rtld.c - Manual merge.
|
||||
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index fb3da5aa565908a6..a920b12a906a9dec 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1296,7 +1296,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||
if (l->l_ld != 0)
|
||||
l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||
|
||||
- elf_get_dynamic_info (l);
|
||||
+ elf_get_dynamic_info (l, false, false);
|
||||
|
||||
/* Make sure we are not dlopen'ing an object that has the
|
||||
DF_1_NOOPEN flag set, or a PIE object. */
|
||||
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
|
||||
index ababafcf98f9945d..757205affe65d9e1 100644
|
||||
--- a/elf/dl-reloc-static-pie.c
|
||||
+++ b/elf/dl-reloc-static-pie.c
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include <dl-machine.h>
|
||||
|
||||
-#define STATIC_PIE_BOOTSTRAP
|
||||
#define RESOLVE_MAP(map, scope, sym, version, flags) map
|
||||
#include "dynamic-link.h"
|
||||
#include "get-dynamic-info.h"
|
||||
@@ -52,7 +51,7 @@ _dl_relocate_static_pie (void)
|
||||
break;
|
||||
}
|
||||
|
||||
- elf_get_dynamic_info (main_map);
|
||||
+ elf_get_dynamic_info (main_map, false, true);
|
||||
|
||||
# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
|
||||
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info);
|
||||
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
|
||||
index 1ac0663d1ff5de24..f63e07dc6d2cd5e6 100644
|
||||
--- a/elf/get-dynamic-info.h
|
||||
+++ b/elf/get-dynamic-info.h
|
||||
@@ -26,7 +26,8 @@
|
||||
#include <libc-diag.h>
|
||||
|
||||
static inline void __attribute__ ((unused, always_inline))
|
||||
-elf_get_dynamic_info (struct link_map *l)
|
||||
+elf_get_dynamic_info (struct link_map *l, bool bootstrap,
|
||||
+ bool static_pie_bootstrap)
|
||||
{
|
||||
#if __ELF_NATIVE_CLASS == 32
|
||||
typedef Elf32_Word d_tag_utype;
|
||||
@@ -35,7 +36,7 @@ elf_get_dynamic_info (struct link_map *l)
|
||||
#endif
|
||||
|
||||
#ifndef STATIC_PIE_BOOTSTRAP
|
||||
- if (l->l_ld == NULL)
|
||||
+ if (!bootstrap && l->l_ld == NULL)
|
||||
return;
|
||||
#endif
|
||||
|
||||
@@ -112,47 +113,63 @@ elf_get_dynamic_info (struct link_map *l)
|
||||
if (info[DT_REL] != NULL)
|
||||
assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
|
||||
#endif
|
||||
-#ifdef STATIC_PIE_BOOTSTRAP
|
||||
- assert (info[DT_RUNPATH] == NULL);
|
||||
- assert (info[DT_RPATH] == NULL);
|
||||
-#endif
|
||||
- if (info[DT_FLAGS] != NULL)
|
||||
+ if (bootstrap || static_pie_bootstrap)
|
||||
{
|
||||
- /* Flags are used. Translate to the old form where available.
|
||||
- Since these l_info entries are only tested for NULL pointers it
|
||||
- is ok if they point to the DT_FLAGS entry. */
|
||||
- l->l_flags = info[DT_FLAGS]->d_un.d_val;
|
||||
-
|
||||
- if (l->l_flags & DF_SYMBOLIC)
|
||||
- info[DT_SYMBOLIC] = info[DT_FLAGS];
|
||||
- if (l->l_flags & DF_TEXTREL)
|
||||
- info[DT_TEXTREL] = info[DT_FLAGS];
|
||||
- if (l->l_flags & DF_BIND_NOW)
|
||||
- info[DT_BIND_NOW] = info[DT_FLAGS];
|
||||
+ assert (info[DT_RUNPATH] == NULL);
|
||||
+ assert (info[DT_RPATH] == NULL);
|
||||
}
|
||||
- if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
|
||||
+ if (bootstrap)
|
||||
{
|
||||
- l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
|
||||
- if (l->l_flags_1 & DF_1_NODELETE)
|
||||
- l->l_nodelete_pending = true;
|
||||
-
|
||||
- /* Only DT_1_SUPPORTED_MASK bits are supported, and we would like
|
||||
- to assert this, but we can't. Users have been setting
|
||||
- unsupported DF_1_* flags for a long time and glibc has ignored
|
||||
- them. Therefore to avoid breaking existing applications the
|
||||
- best we can do is add a warning during debugging with the
|
||||
- intent of notifying the user of the problem. */
|
||||
- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
|
||||
- && l->l_flags_1 & ~DT_1_SUPPORTED_MASK)
|
||||
- _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.\n",
|
||||
- l->l_flags_1 & ~DT_1_SUPPORTED_MASK);
|
||||
-
|
||||
- if (l->l_flags_1 & DF_1_NOW)
|
||||
- info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)];
|
||||
+ /* Only the bind now flags are allowed. */
|
||||
+ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
|
||||
+ || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
|
||||
+ /* Flags must not be set for ld.so. */
|
||||
+ assert (info[DT_FLAGS] == NULL
|
||||
+ || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
|
||||
}
|
||||
- if (info[DT_RUNPATH] != NULL)
|
||||
- /* If both RUNPATH and RPATH are given, the latter is ignored. */
|
||||
- info[DT_RPATH] = NULL;
|
||||
+ else
|
||||
+ {
|
||||
+ if (info[DT_FLAGS] != NULL)
|
||||
+ {
|
||||
+ /* Flags are used. Translate to the old form where available.
|
||||
+ Since these l_info entries are only tested for NULL pointers it
|
||||
+ is ok if they point to the DT_FLAGS entry. */
|
||||
+ l->l_flags = info[DT_FLAGS]->d_un.d_val;
|
||||
+
|
||||
+ if (l->l_flags & DF_SYMBOLIC)
|
||||
+ info[DT_SYMBOLIC] = info[DT_FLAGS];
|
||||
+ if (l->l_flags & DF_TEXTREL)
|
||||
+ info[DT_TEXTREL] = info[DT_FLAGS];
|
||||
+ if (l->l_flags & DF_BIND_NOW)
|
||||
+ info[DT_BIND_NOW] = info[DT_FLAGS];
|
||||
+ }
|
||||
+
|
||||
+ if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
|
||||
+ {
|
||||
+ l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
|
||||
+ if (l->l_flags_1 & DF_1_NODELETE)
|
||||
+ l->l_nodelete_pending = true;
|
||||
+
|
||||
+ /* Only DT_1_SUPPORTED_MASK bits are supported, and we would like
|
||||
+ to assert this, but we can't. Users have been setting
|
||||
+ unsupported DF_1_* flags for a long time and glibc has ignored
|
||||
+ them. Therefore to avoid breaking existing applications the
|
||||
+ best we can do is add a warning during debugging with the
|
||||
+ intent of notifying the user of the problem. */
|
||||
+ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
|
||||
+ && l->l_flags_1 & ~DT_1_SUPPORTED_MASK)
|
||||
+ _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x "
|
||||
+ "in DT_FLAGS_1.\n",
|
||||
+ l->l_flags_1 & ~DT_1_SUPPORTED_MASK);
|
||||
+
|
||||
+ if (l->l_flags_1 & DF_1_NOW)
|
||||
+ info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)];
|
||||
+ }
|
||||
+
|
||||
+ if (info[DT_RUNPATH] != NULL)
|
||||
+ /* If both RUNPATH and RPATH are given, the latter is ignored. */
|
||||
+ info[DT_RPATH] = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
#endif
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 37d28d5a66d7b5d6..ad5ddb2a0ab94e7f 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -549,7 +549,7 @@ _dl_start (void *arg)
|
||||
/* Read our own dynamic section and fill in the info array. */
|
||||
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
|
||||
bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION;
|
||||
- elf_get_dynamic_info (&bootstrap_map);
|
||||
+ elf_get_dynamic_info (&bootstrap_map, true, false);
|
||||
|
||||
#if NO_TLS_OFFSET != 0
|
||||
bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
|
||||
@@ -1653,7 +1653,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
if (! rtld_is_main)
|
||||
{
|
||||
/* Extract the contents of the dynamic section for easy access. */
|
||||
- elf_get_dynamic_info (main_map);
|
||||
+ elf_get_dynamic_info (main_map, false, false);
|
||||
|
||||
/* If the main map is libc.so, update the base namespace to
|
||||
refer to this map. If libc.so is loaded later, this happens
|
||||
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
|
||||
index f44748bc9858e5fd..3f20578046de76ed 100644
|
||||
--- a/elf/setup-vdso.h
|
||||
+++ b/elf/setup-vdso.h
|
||||
@@ -64,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||
l->l_map_end += l->l_addr;
|
||||
l->l_text_end += l->l_addr;
|
||||
l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||
- elf_get_dynamic_info (l);
|
||||
+ elf_get_dynamic_info (l, false, false);
|
||||
_dl_setup_hash (l);
|
||||
l->l_relocated = 1;
|
||||
|
69
SOURCES/glibc-upstream-2.34-140.patch
Normal file
69
SOURCES/glibc-upstream-2.34-140.patch
Normal file
@ -0,0 +1,69 @@
|
||||
commit a31bbe3242266aaea423e5879f38aed69aea1d5e
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Jul 29 11:13:57 2021 -0300
|
||||
|
||||
elf: Move LAV_CURRENT to link_lavcurrent.h
|
||||
|
||||
No functional change.
|
||||
|
||||
(cherry picked from commit 54816ae98d57930b7c945f17485714a5574bfe47)
|
||||
|
||||
Resolved conflicts:
|
||||
elf/Makefile
|
||||
|
||||
diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..44fbea1e8060997f
|
||||
--- /dev/null
|
||||
+++ b/bits/link_lavcurrent.h
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* Data structure for communication from the run-time dynamic linker for
|
||||
+ loaded ELF shared objects. LAV_CURRENT definition.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <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 1
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index cd8725c76f4cfb48..7fa80946ff3aae42 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -24,6 +24,7 @@ include ../Makeconfig
|
||||
headers = \
|
||||
bits/elfclass.h \
|
||||
bits/link.h \
|
||||
+ bits/link_lavcurrent.h \
|
||||
elf.h \
|
||||
link.h \
|
||||
# headers
|
||||
diff --git a/elf/link.h b/elf/link.h
|
||||
index ff3a85c847930b9b..21a351686b9bf7c8 100644
|
||||
--- a/elf/link.h
|
||||
+++ b/elf/link.h
|
||||
@@ -96,7 +96,7 @@ struct link_map
|
||||
#ifdef __USE_GNU
|
||||
|
||||
/* Version numbers for la_version handshake interface. */
|
||||
-#define LAV_CURRENT 1
|
||||
+#include <bits/link_lavcurrent.h>
|
||||
|
||||
/* Activity types signaled through la_activity. */
|
||||
enum
|
390
SOURCES/glibc-upstream-2.34-141.patch
Normal file
390
SOURCES/glibc-upstream-2.34-141.patch
Normal file
@ -0,0 +1,390 @@
|
||||
commit e25fe992132c460fecc1ab9fade185d5dd3f91ff
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Nov 11 09:28:21 2021 -0300
|
||||
|
||||
elf: Move la_activity (LA_ACT_ADD) after _dl_add_to_namespace_list() (BZ #28062)
|
||||
|
||||
It ensures that the the namespace is guaranteed to not be empty.
|
||||
|
||||
Checked on x86_64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit ed3ce71f5c64c5f07cbde0ef03554ea8950d8f2c)
|
||||
|
||||
Resolved conflicts:
|
||||
elf/Makefile
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 7fa80946ff3aae42..bf6da98bdd15a18d 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -363,6 +363,7 @@ tests += \
|
||||
tst-audit15 \
|
||||
tst-audit16 \
|
||||
tst-audit17 \
|
||||
+ tst-audit18 \
|
||||
tst-auditmany \
|
||||
tst-auxobj \
|
||||
tst-auxobj-dlopen \
|
||||
@@ -623,6 +624,7 @@ modules-names = \
|
||||
tst-audit12mod2 \
|
||||
tst-audit12mod3 \
|
||||
tst-audit13mod1 \
|
||||
+ tst-audit18mod \
|
||||
tst-auditlogmod-1 \
|
||||
tst-auditlogmod-2 \
|
||||
tst-auditlogmod-3 \
|
||||
@@ -640,6 +642,7 @@ modules-names = \
|
||||
tst-auditmod9b \
|
||||
tst-auditmod11 \
|
||||
tst-auditmod12 \
|
||||
+ tst-auditmod18 \
|
||||
tst-auxvalmod \
|
||||
tst-big-note-lib \
|
||||
tst-deep1mod1 \
|
||||
@@ -1999,6 +2002,10 @@ $(objpfx)tst-auditmod17.so: $(objpfx)tst-auditmod17.os
|
||||
CFLAGS-.os += $(call elide-stack-protector,.os,tst-auditmod17)
|
||||
tst-audit17-ENV = LD_AUDIT=$(objpfx)tst-auditmod17.so
|
||||
|
||||
+$(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \
|
||||
+ $(objpfx)tst-audit18mod.so
|
||||
+tst-audit18-ARGS = -- $(host-test-program-cmd)
|
||||
+
|
||||
# tst-sonamemove links against an older implementation of the library.
|
||||
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index a920b12a906a9dec..a8c6df3959f2b331 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1054,42 +1054,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||
/* This is the ELF header. We read it in `open_verify'. */
|
||||
header = (void *) fbp->buf;
|
||||
|
||||
- /* Signal that we are going to add new objects. */
|
||||
- if (r->r_state == RT_CONSISTENT)
|
||||
- {
|
||||
-#ifdef SHARED
|
||||
- /* Auditing checkpoint: we are going to add new objects. */
|
||||
- if ((mode & __RTLD_AUDIT) == 0
|
||||
- && __glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
- {
|
||||
- struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||
- /* Do not call the functions for any auditing object. */
|
||||
- if (head->l_auditing == 0)
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->activity != NULL)
|
||||
- afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||
- LA_ACT_ADD);
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- /* Notify the debugger we have added some objects. We need to
|
||||
- call _dl_debug_initialize in a static program in case dynamic
|
||||
- linking has not been used before. */
|
||||
- r->r_state = RT_ADD;
|
||||
- _dl_debug_state ();
|
||||
- LIBC_PROBE (map_start, 2, nsid, r);
|
||||
- make_consistent = true;
|
||||
- }
|
||||
- else
|
||||
- assert (r->r_state == RT_ADD);
|
||||
-
|
||||
/* Enter the new object in the list of loaded objects. */
|
||||
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
|
||||
if (__glibc_unlikely (l == NULL))
|
||||
@@ -1511,6 +1475,44 @@ cannot enable executable stack as shared object requires");
|
||||
/* Now that the object is fully initialized add it to the object list. */
|
||||
_dl_add_to_namespace_list (l, nsid);
|
||||
|
||||
+ /* Signal that we are going to add new objects. */
|
||||
+ if (r->r_state == RT_CONSISTENT)
|
||||
+ {
|
||||
+#ifdef SHARED
|
||||
+ /* Auditing checkpoint: we are going to add new objects. Since this
|
||||
+ is called after _dl_add_to_namespace_list the namespace is guaranteed
|
||||
+ to not be empty. */
|
||||
+ if ((mode & __RTLD_AUDIT) == 0
|
||||
+ && __glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
+ {
|
||||
+ struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||
+ /* Do not call the functions for any auditing object. */
|
||||
+ if (head->l_auditing == 0)
|
||||
+ {
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ if (afct->activity != NULL)
|
||||
+ afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||
+ LA_ACT_ADD);
|
||||
+
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* Notify the debugger we have added some objects. We need to
|
||||
+ call _dl_debug_initialize in a static program in case dynamic
|
||||
+ linking has not been used before. */
|
||||
+ r->r_state = RT_ADD;
|
||||
+ _dl_debug_state ();
|
||||
+ LIBC_PROBE (map_start, 2, nsid, r);
|
||||
+ make_consistent = true;
|
||||
+ }
|
||||
+ else
|
||||
+ assert (r->r_state == RT_ADD);
|
||||
+
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: we have a new object. */
|
||||
if (__glibc_unlikely (GLRO(dl_naudit) > 0)
|
||||
diff --git a/elf/tst-audit18.c b/elf/tst-audit18.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..ef784908f60d50aa
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit18.c
|
||||
@@ -0,0 +1,129 @@
|
||||
+/* Check DT_AUDIT with dlmopen.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <getopt.h>
|
||||
+#include <string.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xdlfcn.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static int restart;
|
||||
+#define CMDLINE_OPTIONS \
|
||||
+ { "restart", no_argument, &restart, 1 },
|
||||
+
|
||||
+static int
|
||||
+handle_restart (void)
|
||||
+{
|
||||
+ {
|
||||
+ void *h = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||
+
|
||||
+ pid_t (*s) (void) = xdlsym (h, "getpid");
|
||||
+ TEST_COMPARE (s (), getpid ());
|
||||
+
|
||||
+ xdlclose (h);
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ void *h = xdlmopen (LM_ID_NEWLM, "tst-audit18mod.so", RTLD_NOW);
|
||||
+
|
||||
+ int (*foo) (void) = xdlsym (h, "foo");
|
||||
+ TEST_COMPARE (foo (), 10);
|
||||
+
|
||||
+ xdlclose (h);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (int argc, char *argv[])
|
||||
+{
|
||||
+ /* We must have either:
|
||||
+ - One our fource parameters left if called initially:
|
||||
+ + path to ld.so optional
|
||||
+ + "--library-path" optional
|
||||
+ + the library path optional
|
||||
+ + the application name */
|
||||
+
|
||||
+ if (restart)
|
||||
+ return handle_restart ();
|
||||
+
|
||||
+ char *spargv[9];
|
||||
+ int i = 0;
|
||||
+ for (; i < argc - 1; i++)
|
||||
+ spargv[i] = argv[i + 1];
|
||||
+ spargv[i++] = (char *) "--direct";
|
||||
+ spargv[i++] = (char *) "--restart";
|
||||
+ spargv[i] = NULL;
|
||||
+
|
||||
+ setenv ("LD_AUDIT", "tst-auditmod18.so", 0);
|
||||
+ struct support_capture_subprocess result
|
||||
+ = support_capture_subprogram (spargv[0], spargv);
|
||||
+ support_capture_subprocess_check (&result, "tst-audit18", 0, sc_allow_stderr);
|
||||
+
|
||||
+ struct
|
||||
+ {
|
||||
+ const char *name;
|
||||
+ bool found;
|
||||
+ } audit_iface[] =
|
||||
+ {
|
||||
+ { "la_version", false },
|
||||
+ { "la_objsearch", false },
|
||||
+ { "la_activity", false },
|
||||
+ { "la_objopen", false },
|
||||
+ { "la_objclose", false },
|
||||
+ { "la_preinit", false },
|
||||
+#if __WORDSIZE == 32
|
||||
+ { "la_symbind32", false },
|
||||
+#elif __WORDSIZE == 64
|
||||
+ { "la_symbind64", false },
|
||||
+#endif
|
||||
+ };
|
||||
+
|
||||
+ /* Some hooks are called more than once but the test only check if any
|
||||
+ is called at least once. */
|
||||
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||
+ TEST_VERIFY (out != NULL);
|
||||
+ char *buffer = NULL;
|
||||
+ size_t buffer_length = 0;
|
||||
+ while (xgetline (&buffer, &buffer_length, out))
|
||||
+ {
|
||||
+ for (int i = 0; i < array_length (audit_iface); i++)
|
||||
+ if (strncmp (buffer, audit_iface[i].name,
|
||||
+ strlen (audit_iface[i].name)) == 0)
|
||||
+ audit_iface[i].found = true;
|
||||
+ }
|
||||
+ free (buffer);
|
||||
+ xfclose (out);
|
||||
+
|
||||
+ for (int i = 0; i < array_length (audit_iface); i++)
|
||||
+ TEST_COMPARE (audit_iface[i].found, true);
|
||||
+
|
||||
+ support_capture_subprocess_free (&result);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION_ARGV do_test
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-audit18mod.c b/elf/tst-audit18mod.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..096a9167c9f8353f
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit18mod.c
|
||||
@@ -0,0 +1,23 @@
|
||||
+/* Check DT_AUDIT with dlmopen.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+int
|
||||
+foo (void)
|
||||
+{
|
||||
+ return 10;
|
||||
+}
|
||||
diff --git a/elf/tst-auditmod18.c b/elf/tst-auditmod18.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..182992e9fdb1620c
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod18.c
|
||||
@@ -0,0 +1,73 @@
|
||||
+/* Check DT_AUDIT with dlmopen.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <link.h>
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int version)
|
||||
+{
|
||||
+ fprintf (stderr, "%s\n", __func__);
|
||||
+ return LAV_CURRENT;
|
||||
+}
|
||||
+
|
||||
+char *
|
||||
+la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
|
||||
+{
|
||||
+ fprintf (stderr, "%s\n", __func__);
|
||||
+ return (char *) name;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+la_activity (uintptr_t *cookie, unsigned int flag)
|
||||
+{
|
||||
+ fprintf (stderr, "%s\n", __func__);
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||
+{
|
||||
+ fprintf (stderr, "%s\n", __func__);
|
||||
+ return LA_FLG_BINDTO | LA_FLG_BINDFROM;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_objclose (uintptr_t *cookie)
|
||||
+{
|
||||
+ fprintf (stderr, "%s\n", __func__);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+la_preinit (uintptr_t *cookie)
|
||||
+{
|
||||
+ fprintf (stderr, "%s\n", __func__);
|
||||
+}
|
||||
+
|
||||
+uintptr_t
|
||||
+#if __ELF_NATIVE_CLASS == 32
|
||||
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||
+#else
|
||||
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||
+#endif
|
||||
+{
|
||||
+ fprintf (stderr, "%s\n", __func__);
|
||||
+ return sym->st_value;
|
||||
+}
|
159
SOURCES/glibc-upstream-2.34-142.patch
Normal file
159
SOURCES/glibc-upstream-2.34-142.patch
Normal file
@ -0,0 +1,159 @@
|
||||
commit ce0cb6d1d2daac2d58006a41c3d19c551b86f255
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Mon Jul 19 15:47:51 2021 -0300
|
||||
|
||||
elf: Add _dl_audit_objopen
|
||||
|
||||
It consolidates the code required to call la_objopen audit callback.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit aee6e90f93e285016b6cd9c8bd00402c19ba271b)
|
||||
|
||||
Resolved conflicts:
|
||||
elf/Makefile
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index bf6da98bdd15a18d..85165c0591412a45 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -118,6 +118,7 @@ elide-routines.os = \
|
||||
# interpreter and operating independent of libc.
|
||||
rtld-routines = \
|
||||
$(all-dl-routines) \
|
||||
+ dl-audit \
|
||||
dl-compat \
|
||||
dl-conflict \
|
||||
dl-diagnostics \
|
||||
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4066dfe85146b9d4
|
||||
--- /dev/null
|
||||
+++ b/elf/dl-audit.c
|
||||
@@ -0,0 +1,39 @@
|
||||
+/* Audit common functions.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <ldsodefs.h>
|
||||
+
|
||||
+void
|
||||
+_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||
+{
|
||||
+ if (__glibc_likely (GLRO(dl_naudit) == 0))
|
||||
+ return;
|
||||
+
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ if (afct->objopen != NULL)
|
||||
+ {
|
||||
+ struct auditstate *state = link_map_audit_state (l, cnt);
|
||||
+ state->bindflags = afct->objopen (l, nsid, &state->cookie);
|
||||
+ l->l_audit_any_plt |= state->bindflags != 0;
|
||||
+ }
|
||||
+
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index a8c6df3959f2b331..a2d73d025c65cd79 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1515,22 +1515,8 @@ cannot enable executable stack as shared object requires");
|
||||
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: we have a new object. */
|
||||
- if (__glibc_unlikely (GLRO(dl_naudit) > 0)
|
||||
- && !GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->objopen != NULL)
|
||||
- {
|
||||
- struct auditstate *state = link_map_audit_state (l, cnt);
|
||||
- state->bindflags = afct->objopen (l, nsid, &state->cookie);
|
||||
- l->l_audit_any_plt |= state->bindflags != 0;
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
+ if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||
+ _dl_audit_objopen (l, nsid);
|
||||
#endif
|
||||
|
||||
return l;
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index ad5ddb2a0ab94e7f..45fec0df3043b90a 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -1064,25 +1064,6 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
|
||||
dlmargs.map->l_auditing = 1;
|
||||
}
|
||||
|
||||
-/* Notify the the audit modules that the object MAP has already been
|
||||
- loaded. */
|
||||
-static void
|
||||
-notify_audit_modules_of_loaded_object (struct link_map *map)
|
||||
-{
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->objopen != NULL)
|
||||
- {
|
||||
- struct auditstate *state = link_map_audit_state (map, cnt);
|
||||
- state->bindflags = afct->objopen (map, LM_ID_BASE, &state->cookie);
|
||||
- map->l_audit_any_plt |= state->bindflags != 0;
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/* Load all audit modules. */
|
||||
static void
|
||||
load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
|
||||
@@ -1101,8 +1082,8 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
|
||||
program and the dynamic linker itself). */
|
||||
if (GLRO(dl_naudit) > 0)
|
||||
{
|
||||
- notify_audit_modules_of_loaded_object (main_map);
|
||||
- notify_audit_modules_of_loaded_object (&GL(dl_rtld_map));
|
||||
+ _dl_audit_objopen (main_map, LM_ID_BASE);
|
||||
+ _dl_audit_objopen (&GL(dl_rtld_map), LM_ID_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index bcf1f199c5985c65..5709e4e48dff4355 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1372,6 +1372,11 @@ link_map_audit_state (struct link_map *l, size_t index)
|
||||
return &base[index];
|
||||
}
|
||||
}
|
||||
+
|
||||
+/* Call the la_objopen from the audit modules for the link_map L on the
|
||||
+ namespace identification NSID. */
|
||||
+void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||
+ attribute_hidden;
|
||||
#endif /* SHARED */
|
||||
|
||||
#if PTHREAD_IN_LIBC && defined SHARED
|
254
SOURCES/glibc-upstream-2.34-143.patch
Normal file
254
SOURCES/glibc-upstream-2.34-143.patch
Normal file
@ -0,0 +1,254 @@
|
||||
commit 66e9d27a090874ab93030a908eb86fc29f856151
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Tue Jul 20 11:03:34 2021 -0300
|
||||
|
||||
elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid
|
||||
|
||||
It consolidates the code required to call la_activity audit
|
||||
callback.
|
||||
|
||||
Also for a new Lmid_t the namespace link_map list are empty, so it
|
||||
requires to check if before using it. This can happen for when audit
|
||||
module is used along with dlmopen.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit 3dac3959a5cb585b065cef2cb8a8d909c907e202)
|
||||
|
||||
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||
index 4066dfe85146b9d4..74b87f4b39be75e1 100644
|
||||
--- a/elf/dl-audit.c
|
||||
+++ b/elf/dl-audit.c
|
||||
@@ -18,6 +18,32 @@
|
||||
|
||||
#include <ldsodefs.h>
|
||||
|
||||
+void
|
||||
+_dl_audit_activity_map (struct link_map *l, int action)
|
||||
+{
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ if (afct->activity != NULL)
|
||||
+ afct->activity (&link_map_audit_state (l, cnt)->cookie, action);
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+_dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||
+{
|
||||
+ /* If head is NULL, the namespace has become empty, and the audit interface
|
||||
+ does not give us a way to signal LA_ACT_CONSISTENT for it because the
|
||||
+ first loaded module is used to identify the namespace. */
|
||||
+ struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||
+ if (__glibc_likely (GLRO(dl_naudit) == 0)
|
||||
+ || head == NULL || head->l_auditing)
|
||||
+ return;
|
||||
+
|
||||
+ _dl_audit_activity_map (head, action);
|
||||
+}
|
||||
+
|
||||
void
|
||||
_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||
{
|
||||
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||
index f6fbf9de7d78555b..5a8cc9e7cb5186cc 100644
|
||||
--- a/elf/dl-close.c
|
||||
+++ b/elf/dl-close.c
|
||||
@@ -472,25 +472,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: we will start deleting objects. */
|
||||
- if (__glibc_unlikely (do_audit))
|
||||
- {
|
||||
- struct link_map *head = ns->_ns_loaded;
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- /* Do not call the functions for any auditing object. */
|
||||
- if (head->l_auditing == 0)
|
||||
- {
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->activity != NULL)
|
||||
- {
|
||||
- struct auditstate *state = link_map_audit_state (head, cnt);
|
||||
- afct->activity (&state->cookie, LA_ACT_DELETE);
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ _dl_audit_activity_nsid (nsid, LA_ACT_DELETE);
|
||||
#endif
|
||||
|
||||
/* Notify the debugger we are about to remove some loaded objects. */
|
||||
@@ -785,32 +767,9 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
||||
|
||||
#ifdef SHARED
|
||||
- /* Auditing checkpoint: we have deleted all objects. */
|
||||
- if (__glibc_unlikely (do_audit))
|
||||
- {
|
||||
- struct link_map *head = ns->_ns_loaded;
|
||||
- /* If head is NULL, the namespace has become empty, and the
|
||||
- audit interface does not give us a way to signal
|
||||
- LA_ACT_CONSISTENT for it because the first loaded module is
|
||||
- used to identify the namespace.
|
||||
-
|
||||
- Furthermore, do not notify auditors of the cleanup of a
|
||||
- failed audit module loading attempt. */
|
||||
- if (head != NULL && head->l_auditing == 0)
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->activity != NULL)
|
||||
- {
|
||||
- struct auditstate *state = link_map_audit_state (head, cnt);
|
||||
- afct->activity (&state->cookie, LA_ACT_CONSISTENT);
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ /* Auditing checkpoint: we have deleted all objects. Also, do not notify
|
||||
+ auditors of the cleanup of a failed audit module loading attempt. */
|
||||
+ _dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT);
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (ns->_ns_loaded == NULL, 0)
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index a2d73d025c65cd79..baf0a926053deaed 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1482,24 +1482,8 @@ cannot enable executable stack as shared object requires");
|
||||
/* Auditing checkpoint: we are going to add new objects. Since this
|
||||
is called after _dl_add_to_namespace_list the namespace is guaranteed
|
||||
to not be empty. */
|
||||
- if ((mode & __RTLD_AUDIT) == 0
|
||||
- && __glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
- {
|
||||
- struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||
- /* Do not call the functions for any auditing object. */
|
||||
- if (head->l_auditing == 0)
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->activity != NULL)
|
||||
- afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||
- LA_ACT_ADD);
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ if ((mode & __RTLD_AUDIT) == 0)
|
||||
+ _dl_audit_activity_nsid (nsid, LA_ACT_ADD);
|
||||
#endif
|
||||
|
||||
/* Notify the debugger we have added some objects. We need to
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||
index bc68e2c376debd71..3f01aa480730da13 100644
|
||||
--- a/elf/dl-open.c
|
||||
+++ b/elf/dl-open.c
|
||||
@@ -611,25 +611,7 @@ dl_open_worker_begin (void *a)
|
||||
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: we have added all objects. */
|
||||
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
- {
|
||||
- struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded;
|
||||
- /* Do not call the functions for any auditing object. */
|
||||
- if (head->l_auditing == 0)
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->activity != NULL)
|
||||
- {
|
||||
- struct auditstate *state = link_map_audit_state (head, cnt);
|
||||
- afct->activity (&state->cookie, LA_ACT_CONSISTENT);
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT);
|
||||
#endif
|
||||
|
||||
/* Notify the debugger all new objects are now ready to go. */
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 45fec0df3043b90a..b6bb46ca97b7972f 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -1804,18 +1804,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
|
||||
/* Auditing checkpoint: we are ready to signal that the initial map
|
||||
is being constructed. */
|
||||
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->activity != NULL)
|
||||
- afct->activity (&link_map_audit_state (main_map, cnt)->cookie,
|
||||
- LA_ACT_ADD);
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
+ _dl_audit_activity_map (main_map, LA_ACT_ADD);
|
||||
|
||||
/* We have two ways to specify objects to preload: via environment
|
||||
variable and via the file /etc/ld.so.preload. The latter can also
|
||||
@@ -2496,23 +2485,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: we have added all objects. */
|
||||
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
- {
|
||||
- struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
- /* Do not call the functions for any auditing object. */
|
||||
- if (head->l_auditing == 0)
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->activity != NULL)
|
||||
- afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||
- LA_ACT_CONSISTENT);
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT);
|
||||
#endif
|
||||
|
||||
/* Notify the debugger all new objects are now ready to go. We must re-get
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 5709e4e48dff4355..7384abcf5e0e8e24 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1373,6 +1373,16 @@ link_map_audit_state (struct link_map *l, size_t index)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Call the la_activity from the audit modules from the link map L and issues
|
||||
+ the ACTION argument. */
|
||||
+void _dl_audit_activity_map (struct link_map *l, int action)
|
||||
+ attribute_hidden;
|
||||
+
|
||||
+/* Call the la_activity from the audit modules from the link map from the
|
||||
+ namespace NSID and issues the ACTION argument. */
|
||||
+void _dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||
+ attribute_hidden;
|
||||
+
|
||||
/* Call the la_objopen from the audit modules for the link_map L on the
|
||||
namespace identification NSID. */
|
||||
void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
157
SOURCES/glibc-upstream-2.34-144.patch
Normal file
157
SOURCES/glibc-upstream-2.34-144.patch
Normal file
@ -0,0 +1,157 @@
|
||||
commit ec0fc2a15358dc5f7191f9994f04b1385d14377d
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Tue Jul 20 13:47:36 2021 -0300
|
||||
|
||||
elf: Add _dl_audit_objsearch
|
||||
|
||||
It consolidates the code required to call la_objsearch audit
|
||||
callback.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit c91008d3490e4e3ce29520068405f081f0d368ca)
|
||||
|
||||
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||
index 74b87f4b39be75e1..5682427220569d90 100644
|
||||
--- a/elf/dl-audit.c
|
||||
+++ b/elf/dl-audit.c
|
||||
@@ -44,6 +44,28 @@ _dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||
_dl_audit_activity_map (head, action);
|
||||
}
|
||||
|
||||
+const char *
|
||||
+_dl_audit_objsearch (const char *name, struct link_map *l, unsigned int code)
|
||||
+{
|
||||
+ if (l == NULL || l->l_auditing || code == 0)
|
||||
+ return name;
|
||||
+
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ if (afct->objsearch != NULL)
|
||||
+ {
|
||||
+ struct auditstate *state = link_map_audit_state (l, cnt);
|
||||
+ name = afct->objsearch (name, &state->cookie, code);
|
||||
+ if (name == NULL)
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+
|
||||
+ return name;
|
||||
+}
|
||||
+
|
||||
void
|
||||
_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||
{
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index baf0a926053deaed..eb6b658b698f5694 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1596,32 +1596,20 @@ open_verify (const char *name, int fd,
|
||||
|
||||
#ifdef SHARED
|
||||
/* Give the auditing libraries a chance. */
|
||||
- if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0
|
||||
- && loader->l_auditing == 0)
|
||||
+ if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
{
|
||||
const char *original_name = name;
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->objsearch != NULL)
|
||||
- {
|
||||
- struct auditstate *state = link_map_audit_state (loader, cnt);
|
||||
- name = afct->objsearch (name, &state->cookie, whatcode);
|
||||
- if (name == NULL)
|
||||
- /* Ignore the path. */
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
+ name = _dl_audit_objsearch (name, loader, whatcode);
|
||||
+ if (name == NULL)
|
||||
+ return -1;
|
||||
|
||||
if (fd != -1 && name != original_name && strcmp (name, original_name))
|
||||
- {
|
||||
- /* An audit library changed what we're supposed to open,
|
||||
- so FD no longer matches it. */
|
||||
- __close_nocancel (fd);
|
||||
- fd = -1;
|
||||
- }
|
||||
+ {
|
||||
+ /* An audit library changed what we're supposed to open,
|
||||
+ so FD no longer matches it. */
|
||||
+ __close_nocancel (fd);
|
||||
+ fd = -1;
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2060,36 +2048,17 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||
#ifdef SHARED
|
||||
/* Give the auditing libraries a chance to change the name before we
|
||||
try anything. */
|
||||
- if (__glibc_unlikely (GLRO(dl_naudit) > 0)
|
||||
- && (loader == NULL || loader->l_auditing == 0))
|
||||
+ if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
{
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ const char *before = name;
|
||||
+ name = _dl_audit_objsearch (name, loader, LA_SER_ORIG);
|
||||
+ if (name == NULL)
|
||||
{
|
||||
- if (afct->objsearch != NULL)
|
||||
- {
|
||||
- const char *before = name;
|
||||
- struct auditstate *state = link_map_audit_state (loader, cnt);
|
||||
- name = afct->objsearch (name, &state->cookie, LA_SER_ORIG);
|
||||
- if (name == NULL)
|
||||
- {
|
||||
- /* Do not try anything further. */
|
||||
- fd = -1;
|
||||
- goto no_file;
|
||||
- }
|
||||
- if (before != name && strcmp (before, name) != 0)
|
||||
- {
|
||||
- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
|
||||
- _dl_debug_printf ("audit changed filename %s -> %s\n",
|
||||
- before, name);
|
||||
-
|
||||
- if (origname == NULL)
|
||||
- origname = before;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
+ fd = -1;
|
||||
+ goto no_file;
|
||||
}
|
||||
+ if (before != name && strcmp (before, name) != 0)
|
||||
+ origname = before;
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 7384abcf5e0e8e24..1f212a18d7bfc440 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1373,6 +1373,13 @@ link_map_audit_state (struct link_map *l, size_t index)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Call the la_objsearch from the audit modules from the link map L. If
|
||||
+ ORIGNAME is non NULL, it is updated with the revious name prior calling
|
||||
+ la_objsearch. */
|
||||
+const char *_dl_audit_objsearch (const char *name, struct link_map *l,
|
||||
+ unsigned int code)
|
||||
+ attribute_hidden;
|
||||
+
|
||||
/* Call the la_activity from the audit modules from the link map L and issues
|
||||
the ACTION argument. */
|
||||
void _dl_audit_activity_map (struct link_map *l, int action)
|
123
SOURCES/glibc-upstream-2.34-145.patch
Normal file
123
SOURCES/glibc-upstream-2.34-145.patch
Normal file
@ -0,0 +1,123 @@
|
||||
commit 198660741b23ec9defb19e22951d4a721de603c8
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Tue Jul 20 14:04:51 2021 -0300
|
||||
|
||||
elf: Add _dl_audit_objclose
|
||||
|
||||
It consolidates the code required to call la_objclose audit
|
||||
callback.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit 311c9ee54ea963ff69bd3a2e6981c37e893b4c3e)
|
||||
|
||||
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||
index 5682427220569d90..cb1c3de93cba447b 100644
|
||||
--- a/elf/dl-audit.c
|
||||
+++ b/elf/dl-audit.c
|
||||
@@ -85,3 +85,24 @@ _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||
afct = afct->next;
|
||||
}
|
||||
}
|
||||
+
|
||||
+void
|
||||
+_dl_audit_objclose (struct link_map *l)
|
||||
+{
|
||||
+ if (__glibc_likely (GLRO(dl_naudit) == 0)
|
||||
+ || GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||
+ return;
|
||||
+
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ if (afct->objclose != NULL)
|
||||
+ {
|
||||
+ struct auditstate *state= link_map_audit_state (l, cnt);
|
||||
+ /* Return value is ignored. */
|
||||
+ afct->objclose (&state->cookie);
|
||||
+ }
|
||||
+
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||
index 5a8cc9e7cb5186cc..985cd4e2821436af 100644
|
||||
--- a/elf/dl-close.c
|
||||
+++ b/elf/dl-close.c
|
||||
@@ -260,9 +260,6 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
_dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
|
||||
|
||||
/* Call all termination functions at once. */
|
||||
-#ifdef SHARED
|
||||
- bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing;
|
||||
-#endif
|
||||
bool unload_any = false;
|
||||
bool scope_mem_left = false;
|
||||
unsigned int unload_global = 0;
|
||||
@@ -296,22 +293,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: we remove an object. */
|
||||
- if (__glibc_unlikely (do_audit))
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->objclose != NULL)
|
||||
- {
|
||||
- struct auditstate *state
|
||||
- = link_map_audit_state (imap, cnt);
|
||||
- /* Return value is ignored. */
|
||||
- (void) afct->objclose (&state->cookie);
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
+ _dl_audit_objclose (imap);
|
||||
#endif
|
||||
|
||||
/* This object must not be used anymore. */
|
||||
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
|
||||
index c683884c355dfd52..b789cfb9f2ac6c85 100644
|
||||
--- a/elf/dl-fini.c
|
||||
+++ b/elf/dl-fini.c
|
||||
@@ -146,21 +146,7 @@ _dl_fini (void)
|
||||
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: another object closed. */
|
||||
- if (!do_audit && __builtin_expect (GLRO(dl_naudit) > 0, 0))
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->objclose != NULL)
|
||||
- {
|
||||
- struct auditstate *state
|
||||
- = link_map_audit_state (l, cnt);
|
||||
- /* Return value is ignored. */
|
||||
- (void) afct->objclose (&state->cookie);
|
||||
- }
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
+ _dl_audit_objclose (l);
|
||||
#endif
|
||||
}
|
||||
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 1f212a18d7bfc440..982f23c0287955fe 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1394,6 +1394,10 @@ void _dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||
namespace identification NSID. */
|
||||
void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||
attribute_hidden;
|
||||
+
|
||||
+/* Call the la_objclose from the audit modules for the link_map L. */
|
||||
+void _dl_audit_objclose (struct link_map *l)
|
||||
+ attribute_hidden;
|
||||
#endif /* SHARED */
|
||||
|
||||
#if PTHREAD_IN_LIBC && defined SHARED
|
334
SOURCES/glibc-upstream-2.34-146.patch
Normal file
334
SOURCES/glibc-upstream-2.34-146.patch
Normal file
@ -0,0 +1,334 @@
|
||||
commit b2d99731b6d27c719a30b8ffa931e91c73a6bb4b
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Tue Jul 20 15:58:35 2021 -0300
|
||||
|
||||
elf: Add _dl_audit_symbind_alt and _dl_audit_symbind
|
||||
|
||||
It consolidates the code required to call la_symbind{32,64} audit
|
||||
callback.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit cda4f265c65fb6c4ce38ca1cf0a7e527c5e77cd5)
|
||||
|
||||
diff --git a/elf/Versions b/elf/Versions
|
||||
index 2af210b8f771c950..164682eaeaa9a1da 100644
|
||||
--- a/elf/Versions
|
||||
+++ b/elf/Versions
|
||||
@@ -58,6 +58,7 @@ ld {
|
||||
_dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info;
|
||||
_dl_deallocate_tls; _dl_make_stack_executable;
|
||||
_dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf;
|
||||
+ _dl_audit_symbind_alt;
|
||||
_rtld_global; _rtld_global_ro;
|
||||
|
||||
# Only here for gdb while a better method is developed.
|
||||
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||
index cb1c3de93cba447b..a21530f30bc5524b 100644
|
||||
--- a/elf/dl-audit.c
|
||||
+++ b/elf/dl-audit.c
|
||||
@@ -16,6 +16,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <assert.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
void
|
||||
@@ -106,3 +107,124 @@ _dl_audit_objclose (struct link_map *l)
|
||||
afct = afct->next;
|
||||
}
|
||||
}
|
||||
+
|
||||
+void
|
||||
+_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value,
|
||||
+ lookup_t result)
|
||||
+{
|
||||
+ if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
|
||||
+ return;
|
||||
+
|
||||
+ const char *strtab = (const char *) D_PTR (result, l_info[DT_STRTAB]);
|
||||
+ /* Compute index of the symbol entry in the symbol table of the DSO with
|
||||
+ the definition. */
|
||||
+ unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, l_info[DT_SYMTAB]));
|
||||
+
|
||||
+ unsigned int altvalue = 0;
|
||||
+ /* Synthesize a symbol record where the st_value field is the result. */
|
||||
+ ElfW(Sym) sym = *ref;
|
||||
+ sym.st_value = (ElfW(Addr)) *value;
|
||||
+
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ struct auditstate *match_audit = link_map_audit_state (l, cnt);
|
||||
+ struct auditstate *result_audit = link_map_audit_state (result, cnt);
|
||||
+ if (afct->symbind != NULL
|
||||
+ && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
|
||||
+ || ((result_audit->bindflags & LA_FLG_BINDTO)
|
||||
+ != 0)))
|
||||
+ {
|
||||
+ unsigned int flags = altvalue | LA_SYMB_DLSYM;
|
||||
+ uintptr_t new_value = afct->symbind (&sym, ndx,
|
||||
+ &match_audit->cookie,
|
||||
+ &result_audit->cookie,
|
||||
+ &flags, strtab + ref->st_name);
|
||||
+ if (new_value != (uintptr_t) sym.st_value)
|
||||
+ {
|
||||
+ altvalue = LA_SYMB_ALTVALUE;
|
||||
+ sym.st_value = new_value;
|
||||
+ }
|
||||
+
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+
|
||||
+ *value = (void *) sym.st_value;
|
||||
+ }
|
||||
+}
|
||||
+rtld_hidden_def (_dl_audit_symbind_alt)
|
||||
+
|
||||
+void
|
||||
+_dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||
+ const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
|
||||
+ lookup_t result)
|
||||
+{
|
||||
+ reloc_result->bound = result;
|
||||
+ /* Compute index of the symbol entry in the symbol table of the DSO with the
|
||||
+ definition. */
|
||||
+ reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result,
|
||||
+ l_info[DT_SYMTAB]));
|
||||
+
|
||||
+ if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
|
||||
+ {
|
||||
+ /* Set all bits since this symbol binding is not interesting. */
|
||||
+ reloc_result->enterexit = (1u << DL_NNS) - 1;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Synthesize a symbol record where the st_value field is the result. */
|
||||
+ ElfW(Sym) sym = *defsym;
|
||||
+ sym.st_value = DL_FIXUP_VALUE_ADDR (*value);
|
||||
+
|
||||
+ /* Keep track whether there is any interest in tracing the call in the lower
|
||||
+ two bits. */
|
||||
+ assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
|
||||
+ assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
|
||||
+ reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
|
||||
+
|
||||
+ const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]);
|
||||
+
|
||||
+ unsigned int flags = 0;
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ /* XXX Check whether both DSOs must request action or only one */
|
||||
+ struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||
+ struct auditstate *result_state = link_map_audit_state (result, cnt);
|
||||
+ if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
|
||||
+ && (result_state->bindflags & LA_FLG_BINDTO) != 0)
|
||||
+ {
|
||||
+ if (afct->symbind != NULL)
|
||||
+ {
|
||||
+ uintptr_t new_value = afct->symbind (&sym,
|
||||
+ reloc_result->boundndx,
|
||||
+ &l_state->cookie,
|
||||
+ &result_state->cookie,
|
||||
+ &flags,
|
||||
+ strtab2 + defsym->st_name);
|
||||
+ if (new_value != (uintptr_t) sym.st_value)
|
||||
+ {
|
||||
+ flags |= LA_SYMB_ALTVALUE;
|
||||
+ sym.st_value = new_value;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Remember the results for every audit library and store a summary
|
||||
+ in the first two bits. */
|
||||
+ reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER
|
||||
+ | LA_SYMB_NOPLTEXIT);
|
||||
+ reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
|
||||
+ | LA_SYMB_NOPLTEXIT))
|
||||
+ << ((cnt + 1) * 2));
|
||||
+ }
|
||||
+ else
|
||||
+ /* If the bind flags say this auditor is not interested, set the bits
|
||||
+ manually. */
|
||||
+ reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
|
||||
+ << ((cnt + 1) * 2));
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+
|
||||
+ reloc_result->flags = flags;
|
||||
+ *value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||
+}
|
||||
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||
index 61c260ddb81b586c..c4413c9165cec8cb 100644
|
||||
--- a/elf/dl-runtime.c
|
||||
+++ b/elf/dl-runtime.c
|
||||
@@ -297,84 +297,7 @@ _dl_profile_fixup (
|
||||
auditing libraries the possibility to change the value and
|
||||
tell us whether further auditing is wanted. */
|
||||
if (defsym != NULL && GLRO(dl_naudit) > 0)
|
||||
- {
|
||||
- reloc_result->bound = result;
|
||||
- /* Compute index of the symbol entry in the symbol table of
|
||||
- the DSO with the definition. */
|
||||
- reloc_result->boundndx = (defsym
|
||||
- - (ElfW(Sym) *) D_PTR (result,
|
||||
- l_info[DT_SYMTAB]));
|
||||
-
|
||||
- /* Determine whether any of the two participating DSOs is
|
||||
- interested in auditing. */
|
||||
- if ((l->l_audit_any_plt | result->l_audit_any_plt) != 0)
|
||||
- {
|
||||
- unsigned int flags = 0;
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- /* Synthesize a symbol record where the st_value field is
|
||||
- the result. */
|
||||
- ElfW(Sym) sym = *defsym;
|
||||
- sym.st_value = DL_FIXUP_VALUE_ADDR (value);
|
||||
-
|
||||
- /* Keep track whether there is any interest in tracing
|
||||
- the call in the lower two bits. */
|
||||
- assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
|
||||
- assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
|
||||
- reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
|
||||
-
|
||||
- const char *strtab2 = (const void *) D_PTR (result,
|
||||
- l_info[DT_STRTAB]);
|
||||
-
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- /* XXX Check whether both DSOs must request action or
|
||||
- only one */
|
||||
- struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||
- struct auditstate *result_state
|
||||
- = link_map_audit_state (result, cnt);
|
||||
- if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
|
||||
- && (result_state->bindflags & LA_FLG_BINDTO) != 0)
|
||||
- {
|
||||
- if (afct->symbind != NULL)
|
||||
- {
|
||||
- uintptr_t new_value
|
||||
- = afct->symbind (&sym, reloc_result->boundndx,
|
||||
- &l_state->cookie,
|
||||
- &result_state->cookie,
|
||||
- &flags,
|
||||
- strtab2 + defsym->st_name);
|
||||
- if (new_value != (uintptr_t) sym.st_value)
|
||||
- {
|
||||
- flags |= LA_SYMB_ALTVALUE;
|
||||
- sym.st_value = new_value;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* Remember the results for every audit library and
|
||||
- store a summary in the first two bits. */
|
||||
- reloc_result->enterexit
|
||||
- &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
|
||||
- reloc_result->enterexit
|
||||
- |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
|
||||
- << ((cnt + 1) * 2));
|
||||
- }
|
||||
- else
|
||||
- /* If the bind flags say this auditor is not interested,
|
||||
- set the bits manually. */
|
||||
- reloc_result->enterexit
|
||||
- |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
|
||||
- << ((cnt + 1) * 2));
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
-
|
||||
- reloc_result->flags = flags;
|
||||
- value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||
- }
|
||||
- else
|
||||
- /* Set all bits since this symbol binding is not interesting. */
|
||||
- reloc_result->enterexit = (1u << DL_NNS) - 1;
|
||||
- }
|
||||
+ _dl_audit_symbind (l, reloc_result, defsym, &value, result);
|
||||
#endif
|
||||
|
||||
/* Store the result for later runs. */
|
||||
diff --git a/elf/dl-sym-post.h b/elf/dl-sym-post.h
|
||||
index d68c2d2b1cd43c9b..a11095d3e8c3c937 100644
|
||||
--- a/elf/dl-sym-post.h
|
||||
+++ b/elf/dl-sym-post.h
|
||||
@@ -52,54 +52,9 @@ _dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value,
|
||||
tell us whether further auditing is wanted. */
|
||||
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
{
|
||||
- const char *strtab = (const char *) D_PTR (result,
|
||||
- l_info[DT_STRTAB]);
|
||||
- /* Compute index of the symbol entry in the symbol table of
|
||||
- the DSO with the definition. */
|
||||
- unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result,
|
||||
- l_info[DT_SYMTAB]));
|
||||
-
|
||||
if (match == NULL)
|
||||
match = _dl_sym_find_caller_link_map (caller);
|
||||
-
|
||||
- if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0)
|
||||
- {
|
||||
- unsigned int altvalue = 0;
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- /* Synthesize a symbol record where the st_value field is
|
||||
- the result. */
|
||||
- ElfW(Sym) sym = *ref;
|
||||
- sym.st_value = (ElfW(Addr)) value;
|
||||
-
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- struct auditstate *match_audit
|
||||
- = link_map_audit_state (match, cnt);
|
||||
- struct auditstate *result_audit
|
||||
- = link_map_audit_state (result, cnt);
|
||||
- if (afct->symbind != NULL
|
||||
- && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
|
||||
- || ((result_audit->bindflags & LA_FLG_BINDTO)
|
||||
- != 0)))
|
||||
- {
|
||||
- unsigned int flags = altvalue | LA_SYMB_DLSYM;
|
||||
- uintptr_t new_value
|
||||
- = afct->symbind (&sym, ndx,
|
||||
- &match_audit->cookie,
|
||||
- &result_audit->cookie,
|
||||
- &flags, strtab + ref->st_name);
|
||||
- if (new_value != (uintptr_t) sym.st_value)
|
||||
- {
|
||||
- altvalue = LA_SYMB_ALTVALUE;
|
||||
- sym.st_value = new_value;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
-
|
||||
- value = (void *) sym.st_value;
|
||||
- }
|
||||
+ _dl_audit_symbind_alt (match, ref, &value, result);
|
||||
}
|
||||
#endif
|
||||
return value;
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 982f23c0287955fe..61f1dfb3f79a613a 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1398,6 +1398,16 @@ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||
/* Call the la_objclose from the audit modules for the link_map L. */
|
||||
void _dl_audit_objclose (struct link_map *l)
|
||||
attribute_hidden;
|
||||
+
|
||||
+/* Call the la_symbind{32,64} from the audit modules for the link_map L. */
|
||||
+void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||
+ const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
|
||||
+ lookup_t result)
|
||||
+ attribute_hidden;
|
||||
+/* Same as _dl_audit_symbind, but also sets LA_SYMB_DLSYM flag. */
|
||||
+void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref,
|
||||
+ void **value, lookup_t result);
|
||||
+rtld_hidden_proto (_dl_audit_symbind_alt)
|
||||
#endif /* SHARED */
|
||||
|
||||
#if PTHREAD_IN_LIBC && defined SHARED
|
107
SOURCES/glibc-upstream-2.34-147.patch
Normal file
107
SOURCES/glibc-upstream-2.34-147.patch
Normal file
@ -0,0 +1,107 @@
|
||||
commit 31473c273be14270f8eef68e35c03fd2305eb2c3
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Jul 22 17:10:57 2021 -0300
|
||||
|
||||
elf: Add _dl_audit_preinit
|
||||
|
||||
It consolidates the code required to call la_preinit audit
|
||||
callback.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit 0b98a8748759e88b58927882a8714109abe0a2d6)
|
||||
|
||||
diff --git a/csu/libc-start.c b/csu/libc-start.c
|
||||
index 0350b006fdcc22d2..d01e57ea59ceb880 100644
|
||||
--- a/csu/libc-start.c
|
||||
+++ b/csu/libc-start.c
|
||||
@@ -377,32 +377,15 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
|
||||
/* This is a current program. Use the dynamic segment to find
|
||||
constructors. */
|
||||
call_init (argc, argv, __environ);
|
||||
-#else /* !SHARED */
|
||||
- call_init (argc, argv, __environ);
|
||||
-#endif /* SHARED */
|
||||
|
||||
-#ifdef SHARED
|
||||
/* Auditing checkpoint: we have a new object. */
|
||||
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->preinit != NULL)
|
||||
- afct->preinit (&link_map_audit_state (head, cnt)->cookie);
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
+ _dl_audit_preinit (GL(dl_ns)[LM_ID_BASE]._ns_loaded);
|
||||
|
||||
-#ifdef SHARED
|
||||
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
|
||||
GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
|
||||
-#endif
|
||||
+#else /* !SHARED */
|
||||
+ call_init (argc, argv, __environ);
|
||||
|
||||
-#ifndef SHARED
|
||||
_dl_debug_initialize (0, LM_ID_BASE);
|
||||
#endif
|
||||
|
||||
diff --git a/elf/Versions b/elf/Versions
|
||||
index 164682eaeaa9a1da..bb6697647b397772 100644
|
||||
--- a/elf/Versions
|
||||
+++ b/elf/Versions
|
||||
@@ -58,7 +58,7 @@ ld {
|
||||
_dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info;
|
||||
_dl_deallocate_tls; _dl_make_stack_executable;
|
||||
_dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf;
|
||||
- _dl_audit_symbind_alt;
|
||||
+ _dl_audit_symbind_alt; _dl_audit_preinit;
|
||||
_rtld_global; _rtld_global_ro;
|
||||
|
||||
# Only here for gdb while a better method is developed.
|
||||
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||
index a21530f30bc5524b..0b6fac8e48877c93 100644
|
||||
--- a/elf/dl-audit.c
|
||||
+++ b/elf/dl-audit.c
|
||||
@@ -108,6 +108,21 @@ _dl_audit_objclose (struct link_map *l)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+_dl_audit_preinit (struct link_map *l)
|
||||
+{
|
||||
+ if (__glibc_likely (GLRO(dl_naudit) == 0))
|
||||
+ return;
|
||||
+
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ if (afct->preinit != NULL)
|
||||
+ afct->preinit (&link_map_audit_state (l, cnt)->cookie);
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value,
|
||||
lookup_t result)
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 61f1dfb3f79a613a..91193a036fc5c6ef 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1399,6 +1399,9 @@ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||
void _dl_audit_objclose (struct link_map *l)
|
||||
attribute_hidden;
|
||||
|
||||
+/* Call the la_preinit from the audit modules for the link_map L. */
|
||||
+void _dl_audit_preinit (struct link_map *l);
|
||||
+
|
||||
/* Call the la_symbind{32,64} from the audit modules for the link_map L. */
|
||||
void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||
const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
|
206
SOURCES/glibc-upstream-2.34-148.patch
Normal file
206
SOURCES/glibc-upstream-2.34-148.patch
Normal file
@ -0,0 +1,206 @@
|
||||
commit fd9c4e8a1b72fa1372855051217f9480680d882a
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Jul 22 17:45:33 2021 -0300
|
||||
|
||||
elf: Add _dl_audit_pltenter
|
||||
|
||||
It consolidates the code required to call la_pltenter audit
|
||||
callback.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit eff687e8462b0eaf65992a6031b54a4b1cd16796)
|
||||
|
||||
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||
index 0b6fac8e48877c93..15250c67e8ac1658 100644
|
||||
--- a/elf/dl-audit.c
|
||||
+++ b/elf/dl-audit.c
|
||||
@@ -17,7 +17,9 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <assert.h>
|
||||
+#include <link.h>
|
||||
#include <ldsodefs.h>
|
||||
+#include <dl-machine.h>
|
||||
|
||||
void
|
||||
_dl_audit_activity_map (struct link_map *l, int action)
|
||||
@@ -243,3 +245,78 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||
reloc_result->flags = flags;
|
||||
*value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+_dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||
+ DL_FIXUP_VALUE_TYPE *value, void *regs, long int *framesize)
|
||||
+{
|
||||
+ /* Don't do anything if no auditor wants to intercept this call. */
|
||||
+ if (GLRO(dl_naudit) == 0
|
||||
+ || (reloc_result->enterexit & LA_SYMB_NOPLTENTER))
|
||||
+ return;
|
||||
+
|
||||
+ /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
|
||||
+ initialized earlier in this function or in another thread. */
|
||||
+ assert (DL_FIXUP_VALUE_CODE_ADDR (*value) != 0);
|
||||
+ ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||
+ l_info[DT_SYMTAB])
|
||||
+ + reloc_result->boundndx);
|
||||
+
|
||||
+ /* Set up the sym parameter. */
|
||||
+ ElfW(Sym) sym = *defsym;
|
||||
+ sym.st_value = DL_FIXUP_VALUE_ADDR (*value);
|
||||
+
|
||||
+ /* Get the symbol name. */
|
||||
+ const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||
+ l_info[DT_STRTAB]);
|
||||
+ const char *symname = strtab + sym.st_name;
|
||||
+
|
||||
+ /* Keep track of overwritten addresses. */
|
||||
+ unsigned int flags = reloc_result->flags;
|
||||
+
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ if (afct->ARCH_LA_PLTENTER != NULL
|
||||
+ && (reloc_result->enterexit
|
||||
+ & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
|
||||
+ {
|
||||
+ long int new_framesize = -1;
|
||||
+ struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||
+ struct auditstate *bound_state
|
||||
+ = link_map_audit_state (reloc_result->bound, cnt);
|
||||
+ uintptr_t new_value
|
||||
+ = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
|
||||
+ &l_state->cookie, &bound_state->cookie,
|
||||
+ regs, &flags, symname, &new_framesize);
|
||||
+ if (new_value != (uintptr_t) sym.st_value)
|
||||
+ {
|
||||
+ flags |= LA_SYMB_ALTVALUE;
|
||||
+ sym.st_value = new_value;
|
||||
+ }
|
||||
+
|
||||
+ /* Remember the results for every audit library and store a summary
|
||||
+ in the first two bits. */
|
||||
+ reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
|
||||
+ | LA_SYMB_NOPLTEXIT))
|
||||
+ << (2 * (cnt + 1)));
|
||||
+
|
||||
+ if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
|
||||
+ << (2 * (cnt + 1))))
|
||||
+ == 0 && new_framesize != -1 && *framesize != -2)
|
||||
+ {
|
||||
+ /* If this is the first call providing information, use it. */
|
||||
+ if (*framesize == -1)
|
||||
+ *framesize = new_framesize;
|
||||
+ /* If two pltenter calls provide conflicting information, use
|
||||
+ the larger value. */
|
||||
+ else if (new_framesize != *framesize)
|
||||
+ *framesize = MAX (new_framesize, *framesize);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+
|
||||
+ *value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||
+}
|
||||
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||
index c4413c9165cec8cb..dfedeaf2dd1c7253 100644
|
||||
--- a/elf/dl-runtime.c
|
||||
+++ b/elf/dl-runtime.c
|
||||
@@ -320,78 +320,7 @@ _dl_profile_fixup (
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: report the PLT entering and allow the
|
||||
auditors to change the value. */
|
||||
- if (GLRO(dl_naudit) > 0
|
||||
- /* Don't do anything if no auditor wants to intercept this call. */
|
||||
- && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
|
||||
- {
|
||||
- /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
|
||||
- initialized earlier in this function or in another thread. */
|
||||
- assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
|
||||
- ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||
- l_info[DT_SYMTAB])
|
||||
- + reloc_result->boundndx);
|
||||
-
|
||||
- /* Set up the sym parameter. */
|
||||
- ElfW(Sym) sym = *defsym;
|
||||
- sym.st_value = DL_FIXUP_VALUE_ADDR (value);
|
||||
-
|
||||
- /* Get the symbol name. */
|
||||
- const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||
- l_info[DT_STRTAB]);
|
||||
- const char *symname = strtab + sym.st_name;
|
||||
-
|
||||
- /* Keep track of overwritten addresses. */
|
||||
- unsigned int flags = reloc_result->flags;
|
||||
-
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->ARCH_LA_PLTENTER != NULL
|
||||
- && (reloc_result->enterexit
|
||||
- & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
|
||||
- {
|
||||
- long int new_framesize = -1;
|
||||
- struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||
- struct auditstate *bound_state
|
||||
- = link_map_audit_state (reloc_result->bound, cnt);
|
||||
- uintptr_t new_value
|
||||
- = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
|
||||
- &l_state->cookie,
|
||||
- &bound_state->cookie,
|
||||
- regs, &flags, symname,
|
||||
- &new_framesize);
|
||||
- if (new_value != (uintptr_t) sym.st_value)
|
||||
- {
|
||||
- flags |= LA_SYMB_ALTVALUE;
|
||||
- sym.st_value = new_value;
|
||||
- }
|
||||
-
|
||||
- /* Remember the results for every audit library and
|
||||
- store a summary in the first two bits. */
|
||||
- reloc_result->enterexit
|
||||
- |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
|
||||
- << (2 * (cnt + 1)));
|
||||
-
|
||||
- if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
|
||||
- << (2 * (cnt + 1))))
|
||||
- == 0 && new_framesize != -1 && framesize != -2)
|
||||
- {
|
||||
- /* If this is the first call providing information,
|
||||
- use it. */
|
||||
- if (framesize == -1)
|
||||
- framesize = new_framesize;
|
||||
- /* If two pltenter calls provide conflicting information,
|
||||
- use the larger value. */
|
||||
- else if (new_framesize != framesize)
|
||||
- framesize = MAX (new_framesize, framesize);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
-
|
||||
- value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||
- }
|
||||
+ _dl_audit_pltenter (l, reloc_result, &value, regs, &framesize);
|
||||
#endif
|
||||
|
||||
/* Store the frame size information. */
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 91193a036fc5c6ef..ea187dd266f14e06 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1411,6 +1411,10 @@ void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||
void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref,
|
||||
void **value, lookup_t result);
|
||||
rtld_hidden_proto (_dl_audit_symbind_alt)
|
||||
+void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||
+ DL_FIXUP_VALUE_TYPE *value, void *regs,
|
||||
+ long int *framesize)
|
||||
+ attribute_hidden;
|
||||
#endif /* SHARED */
|
||||
|
||||
#if PTHREAD_IN_LIBC && defined SHARED
|
715
SOURCES/glibc-upstream-2.34-149.patch
Normal file
715
SOURCES/glibc-upstream-2.34-149.patch
Normal file
@ -0,0 +1,715 @@
|
||||
commit a8e211daea6bdb505b10319ed3492e7d871c1e75
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Jul 22 18:02:42 2021 -0300
|
||||
|
||||
elf: Add _dl_audit_pltexit
|
||||
|
||||
It consolidates the code required to call la_pltexit audit
|
||||
callback.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit 8c0664e2b861fd3789602cc0b0b1922b0e20cb3a)
|
||||
|
||||
Resolved conflicts:
|
||||
sysdeps/hppa/dl-runtime.c
|
||||
|
||||
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||
index 15250c67e8ac1658..152712b12fed6de2 100644
|
||||
--- a/elf/dl-audit.c
|
||||
+++ b/elf/dl-audit.c
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <link.h>
|
||||
#include <ldsodefs.h>
|
||||
#include <dl-machine.h>
|
||||
+#include <dl-runtime.h>
|
||||
+#include <dl-fixup-attribute.h>
|
||||
|
||||
void
|
||||
_dl_audit_activity_map (struct link_map *l, int action)
|
||||
@@ -320,3 +322,48 @@ _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||
|
||||
*value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+DL_ARCH_FIXUP_ATTRIBUTE
|
||||
+_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||
+ const void *inregs, void *outregs)
|
||||
+{
|
||||
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
+
|
||||
+ /* This is the address in the array where we store the result of previous
|
||||
+ relocations. */
|
||||
+ // XXX Maybe the bound information must be stored on the stack since
|
||||
+ // XXX with bind_not a new value could have been stored in the meantime.
|
||||
+ struct reloc_result *reloc_result =
|
||||
+ &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||
+ ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||
+ l_info[DT_SYMTAB])
|
||||
+ + reloc_result->boundndx);
|
||||
+
|
||||
+ /* Set up the sym parameter. */
|
||||
+ ElfW(Sym) sym = *defsym;
|
||||
+ sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr);
|
||||
+
|
||||
+ /* Get the symbol name. */
|
||||
+ const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||
+ l_info[DT_STRTAB]);
|
||||
+ const char *symname = strtab + sym.st_name;
|
||||
+
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ if (afct->ARCH_LA_PLTEXIT != NULL
|
||||
+ && (reloc_result->enterexit
|
||||
+ & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
|
||||
+ {
|
||||
+ struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||
+ struct auditstate *bound_state
|
||||
+ = link_map_audit_state (reloc_result->bound, cnt);
|
||||
+ afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
|
||||
+ &l_state->cookie, &bound_state->cookie,
|
||||
+ inregs, outregs, symname);
|
||||
+ }
|
||||
+
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||
index dfedeaf2dd1c7253..e42f6e8b8dfca08e 100644
|
||||
--- a/elf/dl-runtime.c
|
||||
+++ b/elf/dl-runtime.c
|
||||
@@ -16,8 +16,6 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#define IN_DL_RUNTIME 1 /* This can be tested in dl-machine.h. */
|
||||
-
|
||||
#include <alloca.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@@ -31,19 +29,6 @@
|
||||
#include <dl-runtime.h>
|
||||
|
||||
|
||||
-#if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
|
||||
- || ELF_MACHINE_NO_REL
|
||||
-# define PLTREL ElfW(Rela)
|
||||
-#else
|
||||
-# define PLTREL ElfW(Rel)
|
||||
-#endif
|
||||
-
|
||||
-/* The fixup functions might have need special attributes. If none
|
||||
- are provided define the macro as empty. */
|
||||
-#ifndef ARCH_FIXUP_ATTRIBUTE
|
||||
-# define ARCH_FIXUP_ATTRIBUTE
|
||||
-#endif
|
||||
-
|
||||
/* This function is called through a special trampoline from the PLT the
|
||||
first time each PLT entry is called. We must perform the relocation
|
||||
specified in the PLT of the given shared object, and return the resolved
|
||||
@@ -52,7 +37,7 @@
|
||||
function. */
|
||||
|
||||
DL_FIXUP_VALUE_TYPE
|
||||
-attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||
+attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE
|
||||
_dl_fixup (
|
||||
# ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
|
||||
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
|
||||
@@ -148,7 +133,8 @@ _dl_fixup (
|
||||
|
||||
#ifndef PROF
|
||||
DL_FIXUP_VALUE_TYPE
|
||||
-__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||
+__attribute ((noinline))
|
||||
+DL_ARCH_FIXUP_ATTRIBUTE
|
||||
_dl_profile_fixup (
|
||||
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
|
||||
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
|
||||
@@ -332,52 +318,3 @@ _dl_profile_fixup (
|
||||
}
|
||||
|
||||
#endif /* PROF */
|
||||
-
|
||||
-
|
||||
-#include <stdio.h>
|
||||
-void
|
||||
-ARCH_FIXUP_ATTRIBUTE
|
||||
-_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||
- const void *inregs, void *outregs)
|
||||
-{
|
||||
-#ifdef SHARED
|
||||
- const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
-
|
||||
- /* This is the address in the array where we store the result of previous
|
||||
- relocations. */
|
||||
- // XXX Maybe the bound information must be stored on the stack since
|
||||
- // XXX with bind_not a new value could have been stored in the meantime.
|
||||
- struct reloc_result *reloc_result =
|
||||
- &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||
- ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||
- l_info[DT_SYMTAB])
|
||||
- + reloc_result->boundndx);
|
||||
-
|
||||
- /* Set up the sym parameter. */
|
||||
- ElfW(Sym) sym = *defsym;
|
||||
- sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr);
|
||||
-
|
||||
- /* Get the symbol name. */
|
||||
- const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||
- l_info[DT_STRTAB]);
|
||||
- const char *symname = strtab + sym.st_name;
|
||||
-
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->ARCH_LA_PLTEXIT != NULL
|
||||
- && (reloc_result->enterexit
|
||||
- & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
|
||||
- {
|
||||
- struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||
- struct auditstate *bound_state
|
||||
- = link_map_audit_state (reloc_result->bound, cnt);
|
||||
- afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
|
||||
- &l_state->cookie, &bound_state->cookie,
|
||||
- inregs, outregs, symname);
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
-#endif
|
||||
-}
|
||||
diff --git a/elf/dl-support.c b/elf/dl-support.c
|
||||
index c5ee5d33aa7e1d65..f29dc965f4d10648 100644
|
||||
--- a/elf/dl-support.c
|
||||
+++ b/elf/dl-support.c
|
||||
@@ -437,3 +437,11 @@ _dl_get_dl_main_map (void)
|
||||
return &_dl_main_map;
|
||||
}
|
||||
#endif
|
||||
+
|
||||
+/* This is used by _dl_runtime_profile, not used on static code. */
|
||||
+void
|
||||
+DL_ARCH_FIXUP_ATTRIBUTE
|
||||
+_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||
+ const void *inregs, void *outregs)
|
||||
+{
|
||||
+}
|
||||
diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
|
||||
index a7e9267c1c6a4863..9b352b1d0f7d62e7 100644
|
||||
--- a/sysdeps/aarch64/dl-trampoline.S
|
||||
+++ b/sysdeps/aarch64/dl-trampoline.S
|
||||
@@ -293,7 +293,7 @@ _dl_runtime_profile:
|
||||
ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
|
||||
add x2, x29, #OFFSET_RG
|
||||
add x3, x29, #OFFSET_RV
|
||||
- bl _dl_call_pltexit
|
||||
+ bl _dl_audit_pltexit
|
||||
|
||||
ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
|
||||
ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
|
||||
diff --git a/sysdeps/alpha/dl-trampoline.S b/sysdeps/alpha/dl-trampoline.S
|
||||
index 9dfce5b0839dc122..55380d48ad8536ee 100644
|
||||
--- a/sysdeps/alpha/dl-trampoline.S
|
||||
+++ b/sysdeps/alpha/dl-trampoline.S
|
||||
@@ -187,7 +187,7 @@ _dl_runtime_profile_new:
|
||||
jsr $26, ($27), 0
|
||||
ldgp $29, 0($26)
|
||||
|
||||
- /* Set up for call to _dl_call_pltexit. */
|
||||
+ /* Set up for call to _dl_audit_pltexit. */
|
||||
ldq $16, 16*8($15)
|
||||
ldq $17, 17*8($15)
|
||||
stq $0, 16*8($15)
|
||||
@@ -196,7 +196,7 @@ _dl_runtime_profile_new:
|
||||
lda $19, 16*8($15)
|
||||
stt $f0, 18*8($15)
|
||||
stt $f1, 19*8($15)
|
||||
- bsr $26, _dl_call_pltexit !samegp
|
||||
+ bsr $26, _dl_audit_pltexit !samegp
|
||||
|
||||
mov $15, $30
|
||||
cfi_def_cfa_register (30)
|
||||
@@ -518,7 +518,7 @@ _dl_runtime_profile_old:
|
||||
jsr $26, ($27), 0
|
||||
ldgp $29, 0($26)
|
||||
|
||||
- /* Set up for call to _dl_call_pltexit. */
|
||||
+ /* Set up for call to _dl_audit_pltexit. */
|
||||
ldq $16, 48*8($15)
|
||||
ldq $17, 49*8($15)
|
||||
stq $0, 46*8($15)
|
||||
@@ -527,7 +527,7 @@ _dl_runtime_profile_old:
|
||||
lda $19, 46*8($15)
|
||||
stt $f0, 48*8($15)
|
||||
stt $f1, 49*8($15)
|
||||
- bsr $26, _dl_call_pltexit !samegp
|
||||
+ bsr $26, _dl_audit_pltexit !samegp
|
||||
|
||||
mov $15, $30
|
||||
cfi_def_cfa_register (30)
|
||||
diff --git a/sysdeps/arm/dl-machine-rel.h b/sysdeps/arm/dl-machine-rel.h
|
||||
index bec114706cd027a4..a9ee25a6b1d381ac 100644
|
||||
--- a/sysdeps/arm/dl-machine-rel.h
|
||||
+++ b/sysdeps/arm/dl-machine-rel.h
|
||||
@@ -28,4 +28,6 @@
|
||||
Prelinked libraries may use Elf32_Rela though. */
|
||||
#define ELF_MACHINE_PLT_REL 1
|
||||
|
||||
+#define PLTREL ElfW(Rel)
|
||||
+
|
||||
#endif
|
||||
diff --git a/sysdeps/arm/dl-trampoline.S b/sysdeps/arm/dl-trampoline.S
|
||||
index 70105308ca7df934..a2d322706db77981 100644
|
||||
--- a/sysdeps/arm/dl-trampoline.S
|
||||
+++ b/sysdeps/arm/dl-trampoline.S
|
||||
@@ -194,7 +194,7 @@ _dl_runtime_profile:
|
||||
ldmia ip, {r0,r1}
|
||||
add r2, r7, #72
|
||||
add r3, r7, #0
|
||||
- bl _dl_call_pltexit
|
||||
+ bl _dl_audit_pltexit
|
||||
|
||||
@ Return to caller.
|
||||
ldmia r7, {r0-r3}
|
||||
diff --git a/sysdeps/generic/dl-fixup-attribute.h b/sysdeps/generic/dl-fixup-attribute.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..aa92169b709b3fea
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/generic/dl-fixup-attribute.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* ABI specifics for lazy resolution functions.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef _DL_FIXUP_ATTRIBUTE_H
|
||||
+#define _DL_FIXUP_ATTRIBUTE_H
|
||||
+
|
||||
+#define DL_ARCH_FIXUP_ATTRIBUTE
|
||||
+
|
||||
+#endif
|
||||
diff --git a/sysdeps/generic/dl-machine-rel.h b/sysdeps/generic/dl-machine-rel.h
|
||||
index 9167a1dffc715704..9d5b7bb749e69e63 100644
|
||||
--- a/sysdeps/generic/dl-machine-rel.h
|
||||
+++ b/sysdeps/generic/dl-machine-rel.h
|
||||
@@ -23,5 +23,7 @@
|
||||
#define ELF_MACHINE_NO_REL 1
|
||||
/* Defined if the architecture supports Elf{32,64}_Rela relocations. */
|
||||
#define ELF_MACHINE_NO_RELA 0
|
||||
+/* Used to calculate the index of link_map l_reloc_result. */
|
||||
+#define PLTREL ElfW(Rela)
|
||||
|
||||
#endif
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index ea187dd266f14e06..686f0a7b9709eb10 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <link.h>
|
||||
#include <dl-lookupcfg.h>
|
||||
#include <dl-sysdep.h>
|
||||
+#include <dl-fixup-attribute.h>
|
||||
#include <libc-lock.h>
|
||||
#include <hp-timing.h>
|
||||
#include <tls.h>
|
||||
@@ -1415,6 +1416,11 @@ void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||
DL_FIXUP_VALUE_TYPE *value, void *regs,
|
||||
long int *framesize)
|
||||
attribute_hidden;
|
||||
+void DL_ARCH_FIXUP_ATTRIBUTE _dl_audit_pltexit (struct link_map *l,
|
||||
+ ElfW(Word) reloc_arg,
|
||||
+ const void *inregs,
|
||||
+ void *outregs)
|
||||
+ attribute_hidden;
|
||||
#endif /* SHARED */
|
||||
|
||||
#if PTHREAD_IN_LIBC && defined SHARED
|
||||
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
|
||||
index a71b5b2013abf723..8699171930f51489 100644
|
||||
--- a/sysdeps/hppa/dl-runtime.c
|
||||
+++ b/sysdeps/hppa/dl-runtime.c
|
||||
@@ -25,7 +25,7 @@
|
||||
return that to the caller. The caller will continue on to call
|
||||
_dl_fixup with the relocation offset. */
|
||||
|
||||
-ElfW(Word) __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||
+ElfW(Word) __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE
|
||||
_dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l)
|
||||
{
|
||||
Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type;
|
||||
diff --git a/sysdeps/hppa/dl-trampoline.S b/sysdeps/hppa/dl-trampoline.S
|
||||
index cb18ea7eabba41ed..c54879bae0148012 100644
|
||||
--- a/sysdeps/hppa/dl-trampoline.S
|
||||
+++ b/sysdeps/hppa/dl-trampoline.S
|
||||
@@ -300,7 +300,7 @@ L(cont):
|
||||
ldw -4(%sp),%r1
|
||||
copy %r1, %sp
|
||||
|
||||
- /* Arguments to _dl_call_pltexit */
|
||||
+ /* Arguments to _dl_audit_pltexit */
|
||||
ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */
|
||||
ldw -120(%sp), %r25 /* (2) reloc offsets */
|
||||
ldo -56(%sp), %r24 /* (3) *La_hppa_regs */
|
||||
@@ -312,8 +312,8 @@ L(cont):
|
||||
ldo -128(%sp), %r1
|
||||
fstd %fr4,0(%r1)
|
||||
|
||||
- /* Call _dl_call_pltexit */
|
||||
- bl _dl_call_pltexit,%rp
|
||||
+ /* Call _dl_audit_pltexit */
|
||||
+ bl _dl_audit_pltexit,%rp
|
||||
nop
|
||||
|
||||
/* Restore *La_hppa_retval */
|
||||
diff --git a/sysdeps/i386/dl-fixup-attribute.h b/sysdeps/i386/dl-fixup-attribute.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..c10e9936f4db7254
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/i386/dl-fixup-attribute.h
|
||||
@@ -0,0 +1,30 @@
|
||||
+/* ABI specifics for lazy resolution functions. i386 version.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef _DL_FIXUP_ATTRIBUTE_H
|
||||
+#define _DL_FIXUP_ATTRIBUTE_H
|
||||
+
|
||||
+/* We cannot use this scheme for profiling because the _mcount call destroys
|
||||
+ the passed register information. */
|
||||
+#ifndef PROF
|
||||
+# define DL_ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused))
|
||||
+#else
|
||||
+# define DL_ARCH_FIXUP_ATTRIBUTE
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
diff --git a/sysdeps/i386/dl-machine-rel.h b/sysdeps/i386/dl-machine-rel.h
|
||||
index 7ac46f78a69fbf98..bb3480d45415d761 100644
|
||||
--- a/sysdeps/i386/dl-machine-rel.h
|
||||
+++ b/sysdeps/i386/dl-machine-rel.h
|
||||
@@ -28,4 +28,6 @@
|
||||
Prelinked libraries may use Elf32_Rela though. */
|
||||
#define ELF_MACHINE_PLT_REL 1
|
||||
|
||||
+#define PLTREL ElfW(Rel)
|
||||
+
|
||||
#endif
|
||||
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
|
||||
index c55c9a3d64bed1f2..5483e903d81e85c6 100644
|
||||
--- a/sysdeps/i386/dl-machine.h
|
||||
+++ b/sysdeps/i386/dl-machine.h
|
||||
@@ -122,29 +122,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
|
||||
return lazy;
|
||||
}
|
||||
|
||||
-#ifdef IN_DL_RUNTIME
|
||||
-
|
||||
-# ifndef PROF
|
||||
-/* We add a declaration of this function here so that in dl-runtime.c
|
||||
- the ELF_MACHINE_RUNTIME_TRAMPOLINE macro really can pass the parameters
|
||||
- in registers.
|
||||
-
|
||||
- We cannot use this scheme for profiling because the _mcount call
|
||||
- destroys the passed register information. */
|
||||
-#define ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused))
|
||||
-
|
||||
-extern ElfW(Addr) _dl_fixup (struct link_map *l,
|
||||
- ElfW(Word) reloc_offset)
|
||||
- ARCH_FIXUP_ATTRIBUTE;
|
||||
-extern ElfW(Addr) _dl_profile_fixup (struct link_map *l,
|
||||
- ElfW(Word) reloc_offset,
|
||||
- ElfW(Addr) retaddr, void *regs,
|
||||
- long int *framesizep)
|
||||
- ARCH_FIXUP_ATTRIBUTE;
|
||||
-# endif
|
||||
-
|
||||
-#endif
|
||||
-
|
||||
/* Mask identifying addresses reserved for the user program,
|
||||
where the dynamic linker should not map anything. */
|
||||
#define ELF_MACHINE_USER_ADDRESS_MASK 0xf0000000UL
|
||||
diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S
|
||||
index b5ec0326df94f0fd..3a33051c52da9cde 100644
|
||||
--- a/sysdeps/i386/dl-trampoline.S
|
||||
+++ b/sysdeps/i386/dl-trampoline.S
|
||||
@@ -265,7 +265,7 @@ _dl_runtime_profile:
|
||||
movl (LRV_SIZE + 4 + LR_SIZE)(%esp), %eax
|
||||
# PLT1
|
||||
movl (LRV_SIZE + 4 + LR_SIZE + 4)(%esp), %edx
|
||||
- call _dl_call_pltexit
|
||||
+ call _dl_audit_pltexit
|
||||
movl LRV_EAX_OFFSET(%esp), %eax
|
||||
movl LRV_EDX_OFFSET(%esp), %edx
|
||||
fldt LRV_ST1_OFFSET(%esp)
|
||||
diff --git a/sysdeps/ia64/dl-trampoline.S b/sysdeps/ia64/dl-trampoline.S
|
||||
index 3053405a3a21d62e..11e86932c75d5b6b 100644
|
||||
--- a/sysdeps/ia64/dl-trampoline.S
|
||||
+++ b/sysdeps/ia64/dl-trampoline.S
|
||||
@@ -133,7 +133,7 @@ END(_dl_runtime_resolve)
|
||||
|
||||
|
||||
/* The fourth argument to _dl_profile_fixup and the third one to
|
||||
- _dl_call_pltexit are a pointer to La_ia64_regs:
|
||||
+ _dl_audit_pltexit are a pointer to La_ia64_regs:
|
||||
|
||||
8byte r8
|
||||
8byte r9
|
||||
@@ -159,7 +159,7 @@ END(_dl_runtime_resolve)
|
||||
8byte sp
|
||||
|
||||
The fifth argument to _dl_profile_fixup is a pointer to long int.
|
||||
- The fourth argument to _dl_call_pltexit is a pointer to
|
||||
+ The fourth argument to _dl_audit_pltexit is a pointer to
|
||||
La_ia64_retval:
|
||||
|
||||
8byte r8
|
||||
@@ -261,7 +261,7 @@ ENTRY(_dl_runtime_profile)
|
||||
}
|
||||
{ .mii
|
||||
mov r18 = ar.unat /* save it in La_ia64_regs */
|
||||
- mov loc7 = out3 /* save it for _dl_call_pltexit */
|
||||
+ mov loc7 = out3 /* save it for _dl_audit_pltexit */
|
||||
mov loc5 = r11 /* preserve language specific register */
|
||||
}
|
||||
{ .mmi
|
||||
@@ -272,7 +272,7 @@ ENTRY(_dl_runtime_profile)
|
||||
}
|
||||
{ .mii
|
||||
mov ar.unat = r17 /* restore it for function call */
|
||||
- mov loc8 = r16 /* save it for _dl_call_pltexit */
|
||||
+ mov loc8 = r16 /* save it for _dl_audit_pltexit */
|
||||
nop.i 0x0
|
||||
}
|
||||
{ .mmi
|
||||
@@ -291,7 +291,7 @@ ENTRY(_dl_runtime_profile)
|
||||
{ .mmi
|
||||
stf.spill [r2] = f14, 32
|
||||
stf.spill [r3] = f15, 24
|
||||
- mov loc9 = out1 /* save it for _dl_call_pltexit */
|
||||
+ mov loc9 = out1 /* save it for _dl_audit_pltexit */
|
||||
;;
|
||||
}
|
||||
{ .mmb
|
||||
@@ -426,7 +426,7 @@ ENTRY(_dl_runtime_profile)
|
||||
br.call.sptk.many b0 = b6
|
||||
}
|
||||
{ .mii
|
||||
- /* Prepare stack for _dl_call_pltexit. Loc10 has the original
|
||||
+ /* Prepare stack for _dl_audit_pltexit. Loc10 has the original
|
||||
stack pointer. */
|
||||
adds r12 = -PLTEXIT_FRAME_SIZE, loc10
|
||||
adds r2 = -(PLTEXIT_FRAME_SIZE - 16), loc10
|
||||
@@ -461,14 +461,14 @@ ENTRY(_dl_runtime_profile)
|
||||
{ .mmi
|
||||
stf.spill [r2] = f12, 32
|
||||
stf.spill [r3] = f13, 32
|
||||
- /* We need to restore gp for _dl_call_pltexit. */
|
||||
+ /* We need to restore gp for _dl_audit_pltexit. */
|
||||
mov gp = loc11
|
||||
;;
|
||||
}
|
||||
{ .mmb
|
||||
stf.spill [r2] = f14
|
||||
stf.spill [r3] = f15
|
||||
- br.call.sptk.many b0 = _dl_call_pltexit
|
||||
+ br.call.sptk.many b0 = _dl_audit_pltexit
|
||||
}
|
||||
{ .mmi
|
||||
/* Load all the non-floating and floating return values. Skip
|
||||
diff --git a/sysdeps/m68k/dl-trampoline.S b/sysdeps/m68k/dl-trampoline.S
|
||||
index a51a5f7f573c6330..72bde664c31c4256 100644
|
||||
--- a/sysdeps/m68k/dl-trampoline.S
|
||||
+++ b/sysdeps/m68k/dl-trampoline.S
|
||||
@@ -202,7 +202,7 @@ _dl_runtime_profile:
|
||||
cfi_adjust_cfa_offset (4)
|
||||
move.l (32+FPSPACE)(%sp), -(%sp)
|
||||
cfi_adjust_cfa_offset (4)
|
||||
- jbsr _dl_call_pltexit
|
||||
+ jbsr _dl_audit_pltexit
|
||||
lea 16(%sp), %sp
|
||||
cfi_adjust_cfa_offset (-16)
|
||||
move.l (%sp)+, %d0
|
||||
diff --git a/sysdeps/mips/dl-machine-rel.h b/sysdeps/mips/dl-machine-rel.h
|
||||
index ed396180412bc723..3d0dfec01f6b193e 100644
|
||||
--- a/sysdeps/mips/dl-machine-rel.h
|
||||
+++ b/sysdeps/mips/dl-machine-rel.h
|
||||
@@ -22,5 +22,6 @@
|
||||
#define ELF_MACHINE_PLT_REL 1
|
||||
#define ELF_MACHINE_NO_REL 0
|
||||
#define ELF_MACHINE_NO_RELA 0
|
||||
+#define PLTREL ElfW(Rel)
|
||||
|
||||
#endif
|
||||
diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S
|
||||
index 61bd8571fcc93caa..97f0105ce780514e 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/dl-trampoline.S
|
||||
+++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S
|
||||
@@ -197,7 +197,7 @@ END(_dl_runtime_resolve)
|
||||
#ifndef PROF
|
||||
ENTRY (_dl_profile_resolve, 4)
|
||||
/* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
|
||||
- need to call _dl_call_pltexit. */
|
||||
+ need to call _dl_audit_pltexit. */
|
||||
std r31,-8(r1)
|
||||
std r30,-16(r1)
|
||||
/* We need to save the registers used to pass parameters, ie. r3 thru
|
||||
@@ -452,7 +452,7 @@ L(restoreFXR2):
|
||||
L(callpltexit):
|
||||
addi r5,r1,INT_PARMS
|
||||
addi r6,r1,INT_RTN
|
||||
- bl JUMPTARGET(_dl_call_pltexit)
|
||||
+ bl JUMPTARGET(_dl_audit_pltexit)
|
||||
#ifndef SHARED
|
||||
nop
|
||||
#endif
|
||||
diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h
|
||||
index c224a2b92832af9b..9e4cd1055fe6ab20 100644
|
||||
--- a/sysdeps/s390/s390-32/dl-trampoline.h
|
||||
+++ b/sysdeps/s390/s390-32/dl-trampoline.h
|
||||
@@ -282,7 +282,7 @@ _dl_runtime_profile:
|
||||
basr %r1,0
|
||||
5: l %r14,7f-5b(%r1)
|
||||
la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_32_retval *
|
||||
- bas %r14,0(%r14,%r1) # call _dl_call_pltexit
|
||||
+ bas %r14,0(%r14,%r1) # call _dl_audit_pltexit
|
||||
|
||||
lr %r15,%r12 # remove stack frame
|
||||
# undef FRAME_SIZE
|
||||
@@ -301,7 +301,7 @@ _dl_runtime_profile:
|
||||
br %r14
|
||||
|
||||
6: .long _dl_profile_fixup - 0b
|
||||
-7: .long _dl_call_pltexit - 5b
|
||||
+7: .long _dl_audit_pltexit - 5b
|
||||
cfi_endproc
|
||||
.size _dl_runtime_profile, .-_dl_runtime_profile
|
||||
# undef SIZEOF_STRUCT_LA_S390_32_REGS
|
||||
diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h
|
||||
index ae741a3bad5ec77e..6e5bad40459ec765 100644
|
||||
--- a/sysdeps/s390/s390-64/dl-trampoline.h
|
||||
+++ b/sysdeps/s390/s390-64/dl-trampoline.h
|
||||
@@ -284,7 +284,7 @@ _dl_runtime_profile:
|
||||
lmg %r2,%r4,CFA_OFF+PLT1_OFF(%r12) # r2, r3: args saved by PLT
|
||||
# r4: struct La_s390_64_regs *
|
||||
la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_64_retval *
|
||||
- brasl %r14,_dl_call_pltexit
|
||||
+ brasl %r14,_dl_audit_pltexit
|
||||
|
||||
lgr %r15,%r12 # remove stack frame
|
||||
# undef FRAME_SIZE
|
||||
diff --git a/sysdeps/sh/dl-trampoline.S b/sysdeps/sh/dl-trampoline.S
|
||||
index 824ac84ba1830ce5..f9038cd10ed5286f 100644
|
||||
--- a/sysdeps/sh/dl-trampoline.S
|
||||
+++ b/sysdeps/sh/dl-trampoline.S
|
||||
@@ -423,8 +423,8 @@ _dl_runtime_profile:
|
||||
.align 2
|
||||
#ifdef SHARED
|
||||
7: .long _GLOBAL_OFFSET_TABLE_
|
||||
-8: .long _dl_call_pltexit@GOTOFF
|
||||
+8: .long _dl_audit_pltexit@GOTOFF
|
||||
#else
|
||||
-8: .long _dl_call_pltexit
|
||||
+8: .long _dl_audit_pltexit
|
||||
#endif
|
||||
.size _dl_runtime_profile, .-_dl_runtime_profile
|
||||
diff --git a/sysdeps/sparc/sparc32/dl-trampoline.S b/sysdeps/sparc/sparc32/dl-trampoline.S
|
||||
index 426f90c99a7ed369..2f64809731c865a2 100644
|
||||
--- a/sysdeps/sparc/sparc32/dl-trampoline.S
|
||||
+++ b/sysdeps/sparc/sparc32/dl-trampoline.S
|
||||
@@ -127,7 +127,7 @@ _dl_profile_invoke:
|
||||
mov %l5, %o0
|
||||
mov %l6, %o1
|
||||
add %sp, (11 * 8), %o2
|
||||
- call _dl_call_pltexit
|
||||
+ call _dl_audit_pltexit
|
||||
add %sp, ( 9 * 8), %o3
|
||||
|
||||
ldd [%sp + ( 9 * 8)], %i0
|
||||
diff --git a/sysdeps/sparc/sparc64/dl-trampoline.S b/sysdeps/sparc/sparc64/dl-trampoline.S
|
||||
index 8d59fa67209cd8ab..86605e37acd929fd 100644
|
||||
--- a/sysdeps/sparc/sparc64/dl-trampoline.S
|
||||
+++ b/sysdeps/sparc/sparc64/dl-trampoline.S
|
||||
@@ -196,7 +196,7 @@ _dl_profile_invoke:
|
||||
mov %l5, %o0
|
||||
mov %l6, %o1
|
||||
add %sp, STACK_BIAS + (24 * 8), %o2
|
||||
- call _dl_call_pltexit
|
||||
+ call _dl_audit_pltexit
|
||||
add %sp, STACK_BIAS + (16 * 8), %o3
|
||||
|
||||
ldx [%sp + STACK_BIAS + (16 * 8)], %i0
|
||||
diff --git a/sysdeps/x86_64/dl-runtime.h b/sysdeps/x86_64/dl-runtime.h
|
||||
index 9c8d3977eee27069..19ba33ef30970c20 100644
|
||||
--- a/sysdeps/x86_64/dl-runtime.h
|
||||
+++ b/sysdeps/x86_64/dl-runtime.h
|
||||
@@ -18,7 +18,7 @@
|
||||
02111-1307 USA. */
|
||||
|
||||
/* The ABI calls for the PLT stubs to pass the index of the relocation
|
||||
- and not its offset. In _dl_profile_fixup and _dl_call_pltexit we
|
||||
+ and not its offset. In _dl_profile_fixup and _dl_audit_pltexit we
|
||||
also use the index. Therefore it is wasteful to compute the offset
|
||||
in the trampoline just to reverse the operation immediately
|
||||
afterwards. */
|
||||
diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h
|
||||
index b9a12970cd6206ee..b5de7efff778559e 100644
|
||||
--- a/sysdeps/x86_64/dl-trampoline.h
|
||||
+++ b/sysdeps/x86_64/dl-trampoline.h
|
||||
@@ -388,7 +388,7 @@ _dl_runtime_profile:
|
||||
jns 3f
|
||||
|
||||
/* There's nothing in the frame size, so there
|
||||
- will be no call to the _dl_call_pltexit. */
|
||||
+ will be no call to the _dl_audit_pltexit. */
|
||||
|
||||
/* Get back registers content. */
|
||||
movq LR_RCX_OFFSET(%rsp), %rcx
|
||||
@@ -436,7 +436,7 @@ _dl_runtime_profile:
|
||||
mov 24(%rbx), %RSP_LP # Drop the copied stack content
|
||||
|
||||
/* Now we have to prepare the La_x86_64_retval structure for the
|
||||
- _dl_call_pltexit. The La_x86_64_regs is being pointed by rsp now,
|
||||
+ _dl_audit_pltexit. The La_x86_64_regs is being pointed by rsp now,
|
||||
so we just need to allocate the sizeof(La_x86_64_retval) space on
|
||||
the stack, since the alignment has already been taken care of. */
|
||||
# ifdef RESTORE_AVX
|
||||
@@ -491,7 +491,7 @@ _dl_runtime_profile:
|
||||
movq 24(%rbx), %rdx # La_x86_64_regs argument to %rdx.
|
||||
movq 40(%rbx), %rsi # Copy args pushed by PLT in register.
|
||||
movq 32(%rbx), %rdi # %rdi: link_map, %rsi: reloc_index
|
||||
- call _dl_call_pltexit
|
||||
+ call _dl_audit_pltexit
|
||||
|
||||
/* Restore return registers. */
|
||||
movq LRV_RAX_OFFSET(%rsp), %rax
|
454
SOURCES/glibc-upstream-2.34-150.patch
Normal file
454
SOURCES/glibc-upstream-2.34-150.patch
Normal file
@ -0,0 +1,454 @@
|
||||
commit 29496b3103ff13aa3c1d8b62552a98f39da0fe59
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Jun 30 10:24:09 2021 -0300
|
||||
|
||||
elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533)
|
||||
|
||||
The rtld-audit interfaces introduces a slowdown due to enabling
|
||||
profiling instrumentation (as if LD_AUDIT implied LD_PROFILE).
|
||||
However, instrumenting is only necessary if one of audit libraries
|
||||
provides PLT callbacks (la_pltenter or la_pltexit symbols). Otherwise,
|
||||
the slowdown can be avoided.
|
||||
|
||||
The following patch adjusts the logic that enables profiling to iterate
|
||||
over all audit modules and check if any of those provides a PLT hook.
|
||||
To keep la_symbind to work even without PLT callbacks, _dl_fixup now
|
||||
calls the audit callback if the modules implements it.
|
||||
|
||||
Co-authored-by: Alexander Monakov <amonakov@ispras.ru>
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit 063f9ba220f434c7f30dd65c4cff17c0c458a7cf)
|
||||
|
||||
Resolved conflicts:
|
||||
NEWS
|
||||
elf/Makefile
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 85165c0591412a45..eab9d46b6165e6be 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -365,6 +365,7 @@ tests += \
|
||||
tst-audit16 \
|
||||
tst-audit17 \
|
||||
tst-audit18 \
|
||||
+ tst-audit19b \
|
||||
tst-auditmany \
|
||||
tst-auxobj \
|
||||
tst-auxobj-dlopen \
|
||||
@@ -454,6 +455,7 @@ tests-internal += \
|
||||
neededtest2 \
|
||||
neededtest3 \
|
||||
neededtest4 \
|
||||
+ tst-audit19a \
|
||||
tst-create_format1 \
|
||||
tst-dl-hwcaps_split \
|
||||
tst-dlmopen2 \
|
||||
@@ -626,6 +628,7 @@ modules-names = \
|
||||
tst-audit12mod3 \
|
||||
tst-audit13mod1 \
|
||||
tst-audit18mod \
|
||||
+ tst-audit19bmod \
|
||||
tst-auditlogmod-1 \
|
||||
tst-auditlogmod-2 \
|
||||
tst-auditlogmod-3 \
|
||||
@@ -644,6 +647,8 @@ modules-names = \
|
||||
tst-auditmod11 \
|
||||
tst-auditmod12 \
|
||||
tst-auditmod18 \
|
||||
+ tst-auditmod19a \
|
||||
+ tst-auditmod19b \
|
||||
tst-auxvalmod \
|
||||
tst-big-note-lib \
|
||||
tst-deep1mod1 \
|
||||
@@ -2007,6 +2012,13 @@ $(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \
|
||||
$(objpfx)tst-audit18mod.so
|
||||
tst-audit18-ARGS = -- $(host-test-program-cmd)
|
||||
|
||||
+$(objpfx)tst-audit19a.out: $(objpfx)tst-auditmod19a.so
|
||||
+tst-audit19a-ENV = LD_AUDIT=$(objpfx)tst-auditmod19a.so
|
||||
+
|
||||
+$(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so
|
||||
+$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so
|
||||
+tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||
+
|
||||
# tst-sonamemove links against an older implementation of the library.
|
||||
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
|
||||
index 3447de7f3536cd70..5b69321bda1f2b27 100644
|
||||
--- a/elf/dl-reloc.c
|
||||
+++ b/elf/dl-reloc.c
|
||||
@@ -205,12 +205,28 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
int skip_ifunc = reloc_mode & __RTLD_NOIFUNC;
|
||||
|
||||
#ifdef SHARED
|
||||
+ bool consider_symbind = false;
|
||||
/* If we are auditing, install the same handlers we need for profiling. */
|
||||
if ((reloc_mode & __RTLD_AUDIT) == 0)
|
||||
- consider_profiling |= GLRO(dl_audit) != NULL;
|
||||
+ {
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ /* Profiling is needed only if PLT hooks are provided. */
|
||||
+ if (afct->ARCH_LA_PLTENTER != NULL
|
||||
+ || afct->ARCH_LA_PLTEXIT != NULL)
|
||||
+ consider_profiling = 1;
|
||||
+ if (afct->symbind != NULL)
|
||||
+ consider_symbind = true;
|
||||
+
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+ }
|
||||
#elif defined PROF
|
||||
/* Never use dynamic linker profiling for gprof profiling code. */
|
||||
# define consider_profiling 0
|
||||
+#else
|
||||
+# define consider_symbind 0
|
||||
#endif
|
||||
|
||||
if (l->l_relocated)
|
||||
@@ -272,7 +288,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc);
|
||||
|
||||
#ifndef PROF
|
||||
- if (__glibc_unlikely (consider_profiling)
|
||||
+ if ((consider_profiling || consider_symbind)
|
||||
&& l->l_info[DT_PLTRELSZ] != NULL)
|
||||
{
|
||||
/* Allocate the array which will contain the already found
|
||||
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||
index e42f6e8b8dfca08e..77a5cccdcbcb9293 100644
|
||||
--- a/elf/dl-runtime.c
|
||||
+++ b/elf/dl-runtime.c
|
||||
@@ -124,6 +124,37 @@ _dl_fixup (
|
||||
&& __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
|
||||
value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value));
|
||||
|
||||
+#ifdef SHARED
|
||||
+ /* Auditing checkpoint: we have a new binding. Provide the auditing
|
||||
+ libraries the possibility to change the value and tell us whether further
|
||||
+ auditing is wanted.
|
||||
+ The l_reloc_result is only allocated if there is an audit module which
|
||||
+ provides a la_symbind. */
|
||||
+ if (l->l_reloc_result != NULL)
|
||||
+ {
|
||||
+ /* This is the address in the array where we store the result of previous
|
||||
+ relocations. */
|
||||
+ struct reloc_result *reloc_result
|
||||
+ = &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||
+ unsigned int init = atomic_load_acquire (&reloc_result->init);
|
||||
+ if (init == 0)
|
||||
+ {
|
||||
+ _dl_audit_symbind (l, reloc_result, sym, &value, result);
|
||||
+
|
||||
+ /* Store the result for later runs. */
|
||||
+ if (__glibc_likely (! GLRO(dl_bind_not)))
|
||||
+ {
|
||||
+ reloc_result->addr = value;
|
||||
+ /* Guarantee all previous writes complete before init is
|
||||
+ updated. See CONCURRENCY NOTES below. */
|
||||
+ atomic_store_release (&reloc_result->init, 1);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ value = reloc_result->addr;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/* Finally, fix up the plt itself. */
|
||||
if (__glibc_unlikely (GLRO(dl_bind_not)))
|
||||
return value;
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index b6bb46ca97b7972f..f632a767d7a269ef 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -1016,13 +1016,7 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
|
||||
"la_objsearch\0"
|
||||
"la_objopen\0"
|
||||
"la_preinit\0"
|
||||
-#if __ELF_NATIVE_CLASS == 32
|
||||
- "la_symbind32\0"
|
||||
-#elif __ELF_NATIVE_CLASS == 64
|
||||
- "la_symbind64\0"
|
||||
-#else
|
||||
-# error "__ELF_NATIVE_CLASS must be defined"
|
||||
-#endif
|
||||
+ LA_SYMBIND "\0"
|
||||
#define STRING(s) __STRING (s)
|
||||
"la_" STRING (ARCH_LA_PLTENTER) "\0"
|
||||
"la_" STRING (ARCH_LA_PLTEXIT) "\0"
|
||||
diff --git a/elf/tst-audit19a.c b/elf/tst-audit19a.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..035cde9351c2711b
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit19a.c
|
||||
@@ -0,0 +1,38 @@
|
||||
+/* Check if DT_AUDIT a module without la_plt{enter,exit} symbols does not incur
|
||||
+ in profiling (BZ#15533).
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <link.h>
|
||||
+#include <support/xdlfcn.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ void *h = xdlopen ("tst-auditmod19a.so", RTLD_NOW);
|
||||
+
|
||||
+ struct link_map *lmap;
|
||||
+ TEST_VERIFY_EXIT (dlinfo (h, RTLD_DI_LINKMAP, &lmap) == 0);
|
||||
+
|
||||
+ /* The internal array is only allocated if profiling is enabled. */
|
||||
+ TEST_VERIFY (lmap->l_reloc_result == NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-audit19b.c b/elf/tst-audit19b.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..da015734f24e0d79
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit19b.c
|
||||
@@ -0,0 +1,94 @@
|
||||
+/* Check if DT_AUDIT a module with la_plt{enter,exit} call la_symbind
|
||||
+ for lazy resolution.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <getopt.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+static int restart;
|
||||
+#define CMDLINE_OPTIONS \
|
||||
+ { "restart", no_argument, &restart, 1 },
|
||||
+
|
||||
+int tst_audit18bmod1_func (void);
|
||||
+
|
||||
+static int
|
||||
+handle_restart (void)
|
||||
+{
|
||||
+ TEST_COMPARE (tst_audit18bmod1_func (), 10);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline bool
|
||||
+startswith (const char *str, const char *pre)
|
||||
+{
|
||||
+ size_t lenpre = strlen (pre);
|
||||
+ size_t lenstr = strlen (str);
|
||||
+ return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (int argc, char *argv[])
|
||||
+{
|
||||
+ /* We must have either:
|
||||
+ - One our fource parameters left if called initially:
|
||||
+ + path to ld.so optional
|
||||
+ + "--library-path" optional
|
||||
+ + the library path optional
|
||||
+ + the application name */
|
||||
+
|
||||
+ if (restart)
|
||||
+ return handle_restart ();
|
||||
+
|
||||
+ char *spargv[9];
|
||||
+ int i = 0;
|
||||
+ for (; i < argc - 1; i++)
|
||||
+ spargv[i] = argv[i + 1];
|
||||
+ spargv[i++] = (char *) "--direct";
|
||||
+ spargv[i++] = (char *) "--restart";
|
||||
+ spargv[i] = NULL;
|
||||
+
|
||||
+ setenv ("LD_AUDIT", "tst-auditmod18b.so", 0);
|
||||
+ struct support_capture_subprocess result
|
||||
+ = support_capture_subprogram (spargv[0], spargv);
|
||||
+ support_capture_subprocess_check (&result, "tst-audit18b", 0, sc_allow_stderr);
|
||||
+
|
||||
+ bool find_symbind = false;
|
||||
+
|
||||
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||
+ TEST_VERIFY (out != NULL);
|
||||
+ char *buffer = NULL;
|
||||
+ size_t buffer_length = 0;
|
||||
+ while (xgetline (&buffer, &buffer_length, out))
|
||||
+ if (startswith (buffer, "la_symbind: tst_audit18bmod1_func") == 0)
|
||||
+ find_symbind = true;
|
||||
+
|
||||
+ TEST_COMPARE (find_symbind, true);
|
||||
+
|
||||
+ free (buffer);
|
||||
+ xfclose (out);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION_ARGV do_test
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-audit19bmod.c b/elf/tst-audit19bmod.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..9ffdcd8f3ffbc38e
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit19bmod.c
|
||||
@@ -0,0 +1,23 @@
|
||||
+/* Extra module for tst-audit18b.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+int
|
||||
+tst_audit18bmod1_func (void)
|
||||
+{
|
||||
+ return 10;
|
||||
+}
|
||||
diff --git a/elf/tst-auditmod19a.c b/elf/tst-auditmod19a.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f58204099457743d
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod19a.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* Audit module for tst-audit18a.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <link.h>
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int version)
|
||||
+{
|
||||
+ return LAV_CURRENT;
|
||||
+}
|
||||
diff --git a/elf/tst-auditmod19b.c b/elf/tst-auditmod19b.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e2248b2a75946746
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod19b.c
|
||||
@@ -0,0 +1,46 @@
|
||||
+/* Audit module for tst-audit18b.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <link.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int version)
|
||||
+{
|
||||
+ return LAV_CURRENT;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||
+{
|
||||
+ return LA_FLG_BINDTO | LA_FLG_BINDFROM;
|
||||
+}
|
||||
+
|
||||
+uintptr_t
|
||||
+#if __ELF_NATIVE_CLASS == 32
|
||||
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||
+#else
|
||||
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||
+#endif
|
||||
+{
|
||||
+ fprintf (stderr, "la_symbind: %s\n", symname);
|
||||
+ return sym->st_value;
|
||||
+}
|
||||
diff --git a/include/link.h b/include/link.h
|
||||
index 4dcf01d8aea90bc2..b3f160c278222b3c 100644
|
||||
--- a/include/link.h
|
||||
+++ b/include/link.h
|
||||
@@ -363,8 +363,10 @@ struct auditstate
|
||||
|
||||
#if __ELF_NATIVE_CLASS == 32
|
||||
# define symbind symbind32
|
||||
+# define LA_SYMBIND "la_symbind32"
|
||||
#elif __ELF_NATIVE_CLASS == 64
|
||||
# define symbind symbind64
|
||||
+# define LA_SYMBIND "la_symbind64"
|
||||
#else
|
||||
# error "__ELF_NATIVE_CLASS must be defined"
|
||||
#endif
|
294
SOURCES/glibc-upstream-2.34-151.patch
Normal file
294
SOURCES/glibc-upstream-2.34-151.patch
Normal file
@ -0,0 +1,294 @@
|
||||
commit 02c6a3d35316d360ae08623f617b1873d2f6159a
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Jun 30 15:51:31 2021 -0300
|
||||
|
||||
elf: Add audit tests for modules with TLSDESC
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit d1b38173c9255b1a4ae00018ad9b35404a7c74d0)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index eab9d46b6165e6be..29f545d2272bf6e2 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -807,6 +807,22 @@ modules-names += tst-gnu2-tls1mod
|
||||
$(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
|
||||
tst-gnu2-tls1mod.so-no-z-defs = yes
|
||||
CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
|
||||
+
|
||||
+tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen
|
||||
+modules-names += tst-audit-tlsdesc-mod1 tst-audit-tlsdesc-mod2 tst-auditmod-tlsdesc
|
||||
+$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||
+ $(objpfx)tst-audit-tlsdesc-mod2.so \
|
||||
+ $(shared-thread-library)
|
||||
+CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
|
||||
+CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
|
||||
+$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library)
|
||||
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||
+ $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||
+$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||
+$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||
+tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
||||
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||
+tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
||||
endif
|
||||
ifeq (yes,$(have-protected-data))
|
||||
modules-names += tst-protected1moda tst-protected1modb
|
||||
diff --git a/elf/tst-audit-tlsdesc-dlopen.c b/elf/tst-audit-tlsdesc-dlopen.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..9c16bb087aca1b77
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit-tlsdesc-dlopen.c
|
||||
@@ -0,0 +1,67 @@
|
||||
+/* DT_AUDIT with modules with TLSDESC.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <support/xdlfcn.h>
|
||||
+
|
||||
+static void *
|
||||
+thr_func (void *mod)
|
||||
+{
|
||||
+ int* (*get_global1)(void) = xdlsym (mod, "get_global1");
|
||||
+ int* (*get_global2)(void) = xdlsym (mod, "get_global2");
|
||||
+ void (*set_global2)(int) = xdlsym (mod, "set_global2");
|
||||
+ int* (*get_local1)(void) = xdlsym (mod, "get_local1");
|
||||
+ int* (*get_local2)(void) = xdlsym (mod, "get_local2");
|
||||
+
|
||||
+ int *global1 = get_global1 ();
|
||||
+ TEST_COMPARE (*global1, 0);
|
||||
+ ++*global1;
|
||||
+
|
||||
+ int *global2 = get_global2 ();
|
||||
+ TEST_COMPARE (*global2, 0);
|
||||
+ ++*global2;
|
||||
+ TEST_COMPARE (*global2, 1);
|
||||
+
|
||||
+ set_global2 (10);
|
||||
+ TEST_COMPARE (*global2, 10);
|
||||
+
|
||||
+ int *local1 = get_local1 ();
|
||||
+ TEST_COMPARE (*local1, 0);
|
||||
+ ++*local1;
|
||||
+
|
||||
+ int *local2 = get_local2 ();
|
||||
+ TEST_COMPARE (*local2, 0);
|
||||
+ ++*local2;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ void *mod = xdlopen ("tst-audit-tlsdesc-mod1.so", RTLD_LAZY);
|
||||
+
|
||||
+ pthread_t thr = xpthread_create (NULL, thr_func, mod);
|
||||
+ void *r = xpthread_join (thr);
|
||||
+ TEST_VERIFY (r == NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-audit-tlsdesc-mod1.c b/elf/tst-audit-tlsdesc-mod1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..61c7dd99a2fb5e28
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit-tlsdesc-mod1.c
|
||||
@@ -0,0 +1,41 @@
|
||||
+/* DT_AUDIT with modules with TLSDESC.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+__thread int global1;
|
||||
+
|
||||
+int *
|
||||
+get_global1 (void)
|
||||
+{
|
||||
+ return &global1;
|
||||
+}
|
||||
+
|
||||
+static __thread int local1;
|
||||
+
|
||||
+void *
|
||||
+get_local1 (void)
|
||||
+{
|
||||
+ return &local1;
|
||||
+}
|
||||
+
|
||||
+extern __thread int global2;
|
||||
+
|
||||
+void
|
||||
+set_global2 (int v)
|
||||
+{
|
||||
+ global2 = v;
|
||||
+}
|
||||
diff --git a/elf/tst-audit-tlsdesc-mod2.c b/elf/tst-audit-tlsdesc-mod2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..28aef635f688ee03
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit-tlsdesc-mod2.c
|
||||
@@ -0,0 +1,33 @@
|
||||
+/* DT_AUDIT with modules with TLSDESC.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+__thread int global2;
|
||||
+
|
||||
+int *
|
||||
+get_global2 (void)
|
||||
+{
|
||||
+ return &global2;
|
||||
+}
|
||||
+
|
||||
+static __thread int local2;
|
||||
+
|
||||
+void *
|
||||
+get_local2 (void)
|
||||
+{
|
||||
+ return &local2;
|
||||
+}
|
||||
diff --git a/elf/tst-audit-tlsdesc.c b/elf/tst-audit-tlsdesc.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3c8be81c95528f47
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit-tlsdesc.c
|
||||
@@ -0,0 +1,60 @@
|
||||
+/* DT_AUDIT with modules with TLSDESC.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/xthread.h>
|
||||
+
|
||||
+extern __thread int global1;
|
||||
+extern __thread int global2;
|
||||
+void *get_local1 (void);
|
||||
+void set_global2 (int v);
|
||||
+void *get_local2 (void);
|
||||
+
|
||||
+static void *
|
||||
+thr_func (void *clousure)
|
||||
+{
|
||||
+ TEST_COMPARE (global1, 0);
|
||||
+ ++global1;
|
||||
+ TEST_COMPARE (global2, 0);
|
||||
+ ++global2;
|
||||
+ TEST_COMPARE (global2, 1);
|
||||
+
|
||||
+ set_global2 (10);
|
||||
+ TEST_COMPARE (global2, 10);
|
||||
+
|
||||
+ int *local1 = get_local1 ();
|
||||
+ TEST_COMPARE (*local1, 0);
|
||||
+ ++*local1;
|
||||
+
|
||||
+ int *local2 = get_local2 ();
|
||||
+ TEST_COMPARE (*local2, 0);
|
||||
+ ++*local2;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ pthread_t thr = xpthread_create (NULL, thr_func, NULL);
|
||||
+ void *r = xpthread_join (thr);
|
||||
+ TEST_VERIFY (r == NULL);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-auditmod-tlsdesc.c b/elf/tst-auditmod-tlsdesc.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e4b835d1f1fb6f73
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod-tlsdesc.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* DT_AUDIT with modules with TLSDESC.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <link.h>
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int version)
|
||||
+{
|
||||
+ return LAV_CURRENT;
|
||||
+}
|
314
SOURCES/glibc-upstream-2.34-152.patch
Normal file
314
SOURCES/glibc-upstream-2.34-152.patch
Normal file
@ -0,0 +1,314 @@
|
||||
commit d1b9bee29a1c4e0b80db53f228e22550c3604894
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Mon Jul 19 18:42:26 2021 -0300
|
||||
|
||||
elf: Issue audit la_objopen for vDSO
|
||||
|
||||
The vDSO is is listed in the link_map chain, but is never the subject of
|
||||
an la_objopen call. A new internal flag __RTLD_VDSO is added that
|
||||
acts as __RTLD_OPENEXEC to allocate the required 'struct auditstate'
|
||||
extra space for the 'struct link_map'.
|
||||
|
||||
The return value from the callback is currently ignored, since there
|
||||
is no PLT call involved by glibc when using the vDSO, neither the vDSO
|
||||
are exported directly.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit f0e23d34a7bdf6b90fba954ee741419171ac41b2)
|
||||
|
||||
Resolved conflicts:
|
||||
elf/Makefile
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 29f545d2272bf6e2..465442bf59fa9794 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -366,6 +366,7 @@ tests += \
|
||||
tst-audit17 \
|
||||
tst-audit18 \
|
||||
tst-audit19b \
|
||||
+ tst-audit22 \
|
||||
tst-auditmany \
|
||||
tst-auxobj \
|
||||
tst-auxobj-dlopen \
|
||||
@@ -649,6 +650,7 @@ modules-names = \
|
||||
tst-auditmod18 \
|
||||
tst-auditmod19a \
|
||||
tst-auditmod19b \
|
||||
+ tst-auditmod22 \
|
||||
tst-auxvalmod \
|
||||
tst-big-note-lib \
|
||||
tst-deep1mod1 \
|
||||
@@ -2035,6 +2037,9 @@ $(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so
|
||||
$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so
|
||||
tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||
|
||||
+$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||
+tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||
+
|
||||
# tst-sonamemove links against an older implementation of the library.
|
||||
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||
diff --git a/elf/dl-object.c b/elf/dl-object.c
|
||||
index 1875599eb274dc35..dee49a32d4fdf07d 100644
|
||||
--- a/elf/dl-object.c
|
||||
+++ b/elf/dl-object.c
|
||||
@@ -59,16 +59,19 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
{
|
||||
#ifdef SHARED
|
||||
unsigned int naudit;
|
||||
- if (__glibc_unlikely ((mode & __RTLD_OPENEXEC) != 0))
|
||||
+ if (__glibc_unlikely ((mode & (__RTLD_OPENEXEC | __RTLD_VDSO)) != 0))
|
||||
{
|
||||
- assert (type == lt_executable);
|
||||
- assert (nsid == LM_ID_BASE);
|
||||
+ if (mode & __RTLD_OPENEXEC)
|
||||
+ {
|
||||
+ assert (type == lt_executable);
|
||||
+ assert (nsid == LM_ID_BASE);
|
||||
|
||||
- /* Ignore the specified libname for the main executable. It is
|
||||
- only known with an explicit loader invocation. */
|
||||
- libname = "";
|
||||
+ /* Ignore the specified libname for the main executable. It is
|
||||
+ only known with an explicit loader invocation. */
|
||||
+ libname = "";
|
||||
+ }
|
||||
|
||||
- /* We create the map for the executable before we know whether
|
||||
+ /* We create the map for the executable and vDSO before we know whether
|
||||
we have auditing libraries and if yes, how many. Assume the
|
||||
worst. */
|
||||
naudit = DL_NNS;
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index f632a767d7a269ef..b089e5cf4740443e 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -1922,6 +1922,12 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
assert (i == npreloads);
|
||||
}
|
||||
|
||||
+#ifdef NEED_DL_SYSINFO_DSO
|
||||
+ /* Now that the audit modules are opened, call la_objopen for the vDSO. */
|
||||
+ if (GLRO(dl_sysinfo_map) != NULL)
|
||||
+ _dl_audit_objopen (GLRO(dl_sysinfo_map), LM_ID_BASE);
|
||||
+#endif
|
||||
+
|
||||
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
|
||||
specified some libraries to load, these are inserted before the actual
|
||||
dependencies in the executable's searchlist for symbol resolution. */
|
||||
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
|
||||
index 3f20578046de76ed..2b013d974a377a83 100644
|
||||
--- a/elf/setup-vdso.h
|
||||
+++ b/elf/setup-vdso.h
|
||||
@@ -30,7 +30,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||
We just want our data structures to describe it as if we had just
|
||||
mapped and relocated it normally. */
|
||||
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
|
||||
- 0, LM_ID_BASE);
|
||||
+ __RTLD_VDSO, LM_ID_BASE);
|
||||
if (__glibc_likely (l != NULL))
|
||||
{
|
||||
l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
|
||||
diff --git a/elf/tst-audit22.c b/elf/tst-audit22.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..18fd22a760ddc3d8
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit22.c
|
||||
@@ -0,0 +1,124 @@
|
||||
+/* Check DTAUDIT and vDSO interaction.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <getopt.h>
|
||||
+#include <limits.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <string.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/support.h>
|
||||
+#include <sys/auxv.h>
|
||||
+
|
||||
+static int restart;
|
||||
+#define CMDLINE_OPTIONS \
|
||||
+ { "restart", no_argument, &restart, 1 },
|
||||
+
|
||||
+static uintptr_t vdso_addr;
|
||||
+
|
||||
+static int
|
||||
+handle_restart (void)
|
||||
+{
|
||||
+ fprintf (stderr, "vdso: %p\n", (void*) vdso_addr);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static uintptr_t
|
||||
+parse_address (const char *str)
|
||||
+{
|
||||
+ void *r;
|
||||
+ TEST_COMPARE (sscanf (str, "%p\n", &r), 1);
|
||||
+ return (uintptr_t) r;
|
||||
+}
|
||||
+
|
||||
+static inline bool
|
||||
+startswith (const char *str, const char *pre)
|
||||
+{
|
||||
+ size_t lenpre = strlen (pre);
|
||||
+ size_t lenstr = strlen (str);
|
||||
+ return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (int argc, char *argv[])
|
||||
+{
|
||||
+ vdso_addr = getauxval (AT_SYSINFO_EHDR);
|
||||
+ if (vdso_addr == 0)
|
||||
+ FAIL_UNSUPPORTED ("getauxval (AT_SYSINFO_EHDR) returned 0");
|
||||
+
|
||||
+ /* We must have either:
|
||||
+ - One our fource parameters left if called initially:
|
||||
+ + path to ld.so optional
|
||||
+ + "--library-path" optional
|
||||
+ + the library path optional
|
||||
+ + the application name */
|
||||
+ if (restart)
|
||||
+ return handle_restart ();
|
||||
+
|
||||
+ char *spargv[9];
|
||||
+ int i = 0;
|
||||
+ for (; i < argc - 1; i++)
|
||||
+ spargv[i] = argv[i + 1];
|
||||
+ spargv[i++] = (char *) "--direct";
|
||||
+ spargv[i++] = (char *) "--restart";
|
||||
+ spargv[i] = NULL;
|
||||
+
|
||||
+ setenv ("LD_AUDIT", "tst-auditmod22.so", 0);
|
||||
+ struct support_capture_subprocess result
|
||||
+ = support_capture_subprogram (spargv[0], spargv);
|
||||
+ support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
|
||||
+
|
||||
+ /* The respawned process should always print the vDSO address (otherwise it
|
||||
+ will fails as unsupported). However, on some architectures the audit
|
||||
+ module might see the vDSO with l_addr being 0, meaning a fixed mapping
|
||||
+ (linux-gate.so). In this case we don't check its value against
|
||||
+ AT_SYSINFO_EHDR one. */
|
||||
+ uintptr_t vdso_process = 0;
|
||||
+ bool vdso_audit_found = false;
|
||||
+ uintptr_t vdso_audit = 0;
|
||||
+
|
||||
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||
+ TEST_VERIFY (out != NULL);
|
||||
+ char *buffer = NULL;
|
||||
+ size_t buffer_length = 0;
|
||||
+ while (xgetline (&buffer, &buffer_length, out))
|
||||
+ {
|
||||
+ if (startswith (buffer, "vdso: "))
|
||||
+ vdso_process = parse_address (buffer + strlen ("vdso: "));
|
||||
+ else if (startswith (buffer, "vdso found: "))
|
||||
+ {
|
||||
+ vdso_audit = parse_address (buffer + strlen ("vdso found: "));
|
||||
+ vdso_audit_found = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ TEST_COMPARE (vdso_audit_found, true);
|
||||
+ if (vdso_audit != 0)
|
||||
+ TEST_COMPARE (vdso_process, vdso_audit);
|
||||
+
|
||||
+ free (buffer);
|
||||
+ xfclose (out);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION_ARGV do_test
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-auditmod22.c b/elf/tst-auditmod22.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8e05ce8cbb215dd5
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod22.c
|
||||
@@ -0,0 +1,51 @@
|
||||
+/* Check DTAUDIT and vDSO interaction.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <link.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+#include <sys/auxv.h>
|
||||
+
|
||||
+static inline bool
|
||||
+startswith (const char *str, const char *pre)
|
||||
+{
|
||||
+ size_t lenpre = strlen (pre);
|
||||
+ size_t lenstr = strlen (str);
|
||||
+ return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int version)
|
||||
+{
|
||||
+ return LAV_CURRENT;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||
+{
|
||||
+ /* The linux-gate.so is placed at a fixed address, thus l_addr being 0,
|
||||
+ and it might be the value reported as the AT_SYSINFO_EHDR. */
|
||||
+ if (map->l_addr == 0 && startswith (map->l_name, "linux-gate.so"))
|
||||
+ fprintf (stderr, "vdso found: %p\n", NULL);
|
||||
+ else if (map->l_addr == getauxval (AT_SYSINFO_EHDR))
|
||||
+ fprintf (stderr, "vdso found: %p\n", (void*) map->l_addr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/include/dlfcn.h b/include/dlfcn.h
|
||||
index a4c283728f94deb4..e73294b0af587913 100644
|
||||
--- a/include/dlfcn.h
|
||||
+++ b/include/dlfcn.h
|
||||
@@ -12,6 +12,8 @@
|
||||
#define __RTLD_AUDIT 0x08000000
|
||||
#define __RTLD_SECURE 0x04000000 /* Apply additional security checks. */
|
||||
#define __RTLD_NOIFUNC 0x02000000 /* Suppress calling ifunc functions. */
|
||||
+#define __RTLD_VDSO 0x01000000 /* Tell _dl_new_object the object is
|
||||
+ system-loaded. */
|
||||
|
||||
#define __LM_ID_CALLER -2
|
||||
|
167
SOURCES/glibc-upstream-2.34-153.patch
Normal file
167
SOURCES/glibc-upstream-2.34-153.patch
Normal file
@ -0,0 +1,167 @@
|
||||
commit 2255621f0e2cd07f7a6147928ce644e13526ffb6
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Jun 30 17:33:57 2021 -0300
|
||||
|
||||
elf: Do not fail for failed dlmopen on audit modules (BZ #28061)
|
||||
|
||||
The dl_main sets the LM_ID_BASE to RT_ADD just before starting to
|
||||
add load new shared objects. The state is set to RT_CONSISTENT just
|
||||
after all objects are loaded.
|
||||
|
||||
However if a audit modules tries to dlmopen an inexistent module,
|
||||
the _dl_open will assert that the namespace is in an inconsistent
|
||||
state.
|
||||
|
||||
This is different than dlopen, since first it will not use
|
||||
LM_ID_BASE and second _dl_map_object_from_fd is the sole responsible
|
||||
to set and reset the r_state value.
|
||||
|
||||
So the assert on _dl_open can not really be seen if the state is
|
||||
consistent, since _dt_main resets it. This patch removes the assert.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
(cherry picked from commit 484e672ddabe0a919a692520e6ac8f2580866235)
|
||||
|
||||
Resolved conflicts:
|
||||
elf/Makefile
|
||||
elf/dl-open.c
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 465442bf59fa9794..91b2269257523a64 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -366,6 +366,7 @@ tests += \
|
||||
tst-audit17 \
|
||||
tst-audit18 \
|
||||
tst-audit19b \
|
||||
+ tst-audit20 \
|
||||
tst-audit22 \
|
||||
tst-auditmany \
|
||||
tst-auxobj \
|
||||
@@ -650,6 +651,7 @@ modules-names = \
|
||||
tst-auditmod18 \
|
||||
tst-auditmod19a \
|
||||
tst-auditmod19b \
|
||||
+ tst-auditmod20 \
|
||||
tst-auditmod22 \
|
||||
tst-auxvalmod \
|
||||
tst-big-note-lib \
|
||||
@@ -2037,6 +2039,9 @@ $(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so
|
||||
$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so
|
||||
tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||
|
||||
+$(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so
|
||||
+tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
|
||||
+
|
||||
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||
tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||
index 3f01aa480730da13..bc6872632880634e 100644
|
||||
--- a/elf/dl-open.c
|
||||
+++ b/elf/dl-open.c
|
||||
@@ -914,8 +914,6 @@ no more namespaces available for dlmopen()"));
|
||||
the flag here. */
|
||||
}
|
||||
|
||||
- assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
|
||||
-
|
||||
/* Release the lock. */
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
|
||||
diff --git a/elf/tst-audit20.c b/elf/tst-audit20.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6f39ccee865b012b
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit20.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* Check dlopen failure on audit modules.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-auditmod20.c b/elf/tst-auditmod20.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..c57e50ee4e88dd6b
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod20.c
|
||||
@@ -0,0 +1,57 @@
|
||||
+/* Check dlopen failure on audit modules.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <dlfcn.h>
|
||||
+#include <link.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int v)
|
||||
+{
|
||||
+ return LAV_CURRENT;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+check (void)
|
||||
+{
|
||||
+ {
|
||||
+ void *mod = dlopen ("nonexistent.so", RTLD_NOW);
|
||||
+ if (mod != NULL)
|
||||
+ abort ();
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ void *mod = dlmopen (LM_ID_BASE, "nonexistent.so", RTLD_NOW);
|
||||
+ if (mod != NULL)
|
||||
+ abort ();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+la_activity (uintptr_t *cookie, unsigned int flag)
|
||||
+{
|
||||
+ if (flag != LA_ACT_CONSISTENT)
|
||||
+ return;
|
||||
+ check ();
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+la_preinit (uintptr_t *cookie)
|
||||
+{
|
||||
+ check ();
|
||||
+}
|
434
SOURCES/glibc-upstream-2.34-154.patch
Normal file
434
SOURCES/glibc-upstream-2.34-154.patch
Normal file
@ -0,0 +1,434 @@
|
||||
commit 98047ba95caf9ed596908ca73a22070c5e27597b
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Mon Jan 24 10:46:15 2022 -0300
|
||||
|
||||
elf: Add la_activity during application exit
|
||||
|
||||
la_activity is not called during application exit, even though
|
||||
la_objclose is.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit 5fa11a2bc94c912c3b25860065086902674537ba)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 91b2269257523a64..407aaeaeb8c84020 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -368,6 +368,7 @@ tests += \
|
||||
tst-audit19b \
|
||||
tst-audit20 \
|
||||
tst-audit22 \
|
||||
+ tst-audit23 \
|
||||
tst-auditmany \
|
||||
tst-auxobj \
|
||||
tst-auxobj-dlopen \
|
||||
@@ -631,6 +632,7 @@ modules-names = \
|
||||
tst-audit13mod1 \
|
||||
tst-audit18mod \
|
||||
tst-audit19bmod \
|
||||
+ tst-audit23mod \
|
||||
tst-auditlogmod-1 \
|
||||
tst-auditlogmod-2 \
|
||||
tst-auditlogmod-3 \
|
||||
@@ -653,6 +655,7 @@ modules-names = \
|
||||
tst-auditmod19b \
|
||||
tst-auditmod20 \
|
||||
tst-auditmod22 \
|
||||
+ tst-auditmod23 \
|
||||
tst-auxvalmod \
|
||||
tst-big-note-lib \
|
||||
tst-deep1mod1 \
|
||||
@@ -2045,6 +2048,10 @@ tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
|
||||
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||
tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||
|
||||
+$(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \
|
||||
+ $(objpfx)tst-audit23mod.so
|
||||
+tst-audit23-ARGS = -- $(host-test-program-cmd)
|
||||
+
|
||||
# tst-sonamemove links against an older implementation of the library.
|
||||
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
|
||||
index b789cfb9f2ac6c85..fa876da0ffa1cf97 100644
|
||||
--- a/elf/dl-fini.c
|
||||
+++ b/elf/dl-fini.c
|
||||
@@ -64,6 +64,10 @@ _dl_fini (void)
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
else
|
||||
{
|
||||
+#ifdef SHARED
|
||||
+ _dl_audit_activity_nsid (ns, LA_ACT_DELETE);
|
||||
+#endif
|
||||
+
|
||||
/* Now we can allocate an array to hold all the pointers and
|
||||
copy the pointers in. */
|
||||
struct link_map *maps[nloaded];
|
||||
@@ -153,6 +157,10 @@ _dl_fini (void)
|
||||
/* Correct the previous increment. */
|
||||
--l->l_direct_opencount;
|
||||
}
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+ _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4904cf1340a97ee1
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit23.c
|
||||
@@ -0,0 +1,239 @@
|
||||
+/* Check for expected la_objopen and la_objeclose for all objects.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <errno.h>
|
||||
+#include <getopt.h>
|
||||
+#include <link.h>
|
||||
+#include <limits.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
+#include <string.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/xdlfcn.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static int restart;
|
||||
+#define CMDLINE_OPTIONS \
|
||||
+ { "restart", no_argument, &restart, 1 },
|
||||
+
|
||||
+static int
|
||||
+handle_restart (void)
|
||||
+{
|
||||
+ xdlopen ("tst-audit23mod.so", RTLD_NOW);
|
||||
+ xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline bool
|
||||
+startswith (const char *str, const char *pre)
|
||||
+{
|
||||
+ size_t lenpre = strlen (pre);
|
||||
+ size_t lenstr = strlen (str);
|
||||
+ return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
|
||||
+}
|
||||
+
|
||||
+static inline bool
|
||||
+is_vdso (const char *str)
|
||||
+{
|
||||
+ return startswith (str, "linux-gate")
|
||||
+ || startswith (str, "linux-vdso");
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (int argc, char *argv[])
|
||||
+{
|
||||
+ /* We must have either:
|
||||
+ - One or four parameters left if called initially:
|
||||
+ + path to ld.so optional
|
||||
+ + "--library-path" optional
|
||||
+ + the library path optional
|
||||
+ + the application name */
|
||||
+ if (restart)
|
||||
+ return handle_restart ();
|
||||
+
|
||||
+ char *spargv[9];
|
||||
+ TEST_VERIFY_EXIT (((argc - 1) + 3) < array_length (spargv));
|
||||
+ int i = 0;
|
||||
+ for (; i < argc - 1; i++)
|
||||
+ spargv[i] = argv[i + 1];
|
||||
+ spargv[i++] = (char *) "--direct";
|
||||
+ spargv[i++] = (char *) "--restart";
|
||||
+ spargv[i] = NULL;
|
||||
+
|
||||
+ setenv ("LD_AUDIT", "tst-auditmod23.so", 0);
|
||||
+ struct support_capture_subprocess result
|
||||
+ = support_capture_subprogram (spargv[0], spargv);
|
||||
+ support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
|
||||
+
|
||||
+ /* The expected la_objopen/la_objclose:
|
||||
+ 1. executable
|
||||
+ 2. loader
|
||||
+ 3. libc.so
|
||||
+ 4. tst-audit23mod.so
|
||||
+ 5. libc.so (LM_ID_NEWLM).
|
||||
+ 6. vdso (optional and ignored). */
|
||||
+ enum { max_objs = 6 };
|
||||
+ struct la_obj_t
|
||||
+ {
|
||||
+ char *lname;
|
||||
+ uintptr_t laddr;
|
||||
+ Lmid_t lmid;
|
||||
+ bool closed;
|
||||
+ } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
|
||||
+ size_t nobjs = 0;
|
||||
+
|
||||
+ /* The expected namespaces are one for the audit module, one for the
|
||||
+ application, and another for the dlmopen on handle_restart. */
|
||||
+ enum { max_ns = 3 };
|
||||
+ uintptr_t acts[max_ns] = { 0 };
|
||||
+ size_t nacts = 0;
|
||||
+ int last_act = -1;
|
||||
+ uintptr_t last_act_cookie = -1;
|
||||
+ bool seen_first_objclose = false;
|
||||
+
|
||||
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||
+ TEST_VERIFY (out != NULL);
|
||||
+ char *buffer = NULL;
|
||||
+ size_t buffer_length = 0;
|
||||
+ while (xgetline (&buffer, &buffer_length, out))
|
||||
+ {
|
||||
+ if (startswith (buffer, "la_activity: "))
|
||||
+ {
|
||||
+ uintptr_t cookie;
|
||||
+ int this_act;
|
||||
+ int r = sscanf (buffer, "la_activity: %d %"SCNxPTR"", &this_act,
|
||||
+ &cookie);
|
||||
+ TEST_COMPARE (r, 2);
|
||||
+
|
||||
+ /* The cookie identifies the object at the head of the link map,
|
||||
+ so we only add a new namespace if it changes from the previous
|
||||
+ one. This works since dlmopen is the last in the test body. */
|
||||
+ if (cookie != last_act_cookie && last_act_cookie != -1)
|
||||
+ TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
|
||||
+
|
||||
+ if (this_act == LA_ACT_ADD && acts[nacts] != cookie)
|
||||
+ {
|
||||
+ acts[nacts++] = cookie;
|
||||
+ last_act_cookie = cookie;
|
||||
+ }
|
||||
+ /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD
|
||||
+ at program termination (if the tests adds a dlclose or a library
|
||||
+ with extra dependencies this will need to be adapted). */
|
||||
+ else if (this_act == LA_ACT_DELETE)
|
||||
+ {
|
||||
+ last_act_cookie = acts[--nacts];
|
||||
+ TEST_COMPARE (acts[nacts], cookie);
|
||||
+ acts[nacts] = 0;
|
||||
+ }
|
||||
+ else if (this_act == LA_ACT_CONSISTENT)
|
||||
+ {
|
||||
+ TEST_COMPARE (cookie, last_act_cookie);
|
||||
+
|
||||
+ /* LA_ACT_DELETE must always be followed by an la_objclose. */
|
||||
+ if (last_act == LA_ACT_DELETE)
|
||||
+ TEST_COMPARE (seen_first_objclose, true);
|
||||
+ else
|
||||
+ TEST_COMPARE (last_act, LA_ACT_ADD);
|
||||
+ }
|
||||
+
|
||||
+ last_act = this_act;
|
||||
+ seen_first_objclose = false;
|
||||
+ }
|
||||
+ else if (startswith (buffer, "la_objopen: "))
|
||||
+ {
|
||||
+ char *lname;
|
||||
+ uintptr_t laddr;
|
||||
+ Lmid_t lmid;
|
||||
+ uintptr_t cookie;
|
||||
+ int r = sscanf (buffer, "la_objopen: %"SCNxPTR" %ms %"SCNxPTR" %ld",
|
||||
+ &cookie, &lname, &laddr, &lmid);
|
||||
+ TEST_COMPARE (r, 4);
|
||||
+
|
||||
+ /* la_objclose is not triggered by vDSO because glibc does not
|
||||
+ unload it. */
|
||||
+ if (is_vdso (lname))
|
||||
+ continue;
|
||||
+ if (nobjs == max_objs)
|
||||
+ FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld",
|
||||
+ lname, laddr, lmid);
|
||||
+ objs[nobjs].lname = lname;
|
||||
+ objs[nobjs].laddr = laddr;
|
||||
+ objs[nobjs].lmid = lmid;
|
||||
+ objs[nobjs].closed = false;
|
||||
+ nobjs++;
|
||||
+
|
||||
+ /* This indirectly checks that la_objopen always comes before
|
||||
+ la_objclose btween la_activity calls. */
|
||||
+ seen_first_objclose = false;
|
||||
+ }
|
||||
+ else if (startswith (buffer, "la_objclose: "))
|
||||
+ {
|
||||
+ char *lname;
|
||||
+ uintptr_t laddr;
|
||||
+ Lmid_t lmid;
|
||||
+ uintptr_t cookie;
|
||||
+ int r = sscanf (buffer, "la_objclose: %"SCNxPTR" %ms %"SCNxPTR" %ld",
|
||||
+ &cookie, &lname, &laddr, &lmid);
|
||||
+ TEST_COMPARE (r, 4);
|
||||
+
|
||||
+ for (size_t i = 0; i < nobjs; i++)
|
||||
+ {
|
||||
+ if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
|
||||
+ {
|
||||
+ TEST_COMPARE (objs[i].closed, false);
|
||||
+ objs[i].closed = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* la_objclose should be called after la_activity(LA_ACT_DELETE) for
|
||||
+ the closed object's namespace. */
|
||||
+ TEST_COMPARE (last_act, LA_ACT_DELETE);
|
||||
+ if (!seen_first_objclose)
|
||||
+ {
|
||||
+ TEST_COMPARE (last_act_cookie, cookie);
|
||||
+ seen_first_objclose = true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (size_t i = 0; i < nobjs; i++)
|
||||
+ {
|
||||
+ TEST_COMPARE (objs[i].closed, true);
|
||||
+ free (objs[i].lname);
|
||||
+ }
|
||||
+
|
||||
+ /* la_activity(LA_ACT_CONSISTENT) should be the last callback received.
|
||||
+ Since only one link map may be not-CONSISTENT at a time, this also
|
||||
+ ensures la_activity(LA_ACT_CONSISTENT) is the last callback received
|
||||
+ for every namespace. */
|
||||
+ TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
|
||||
+
|
||||
+ free (buffer);
|
||||
+ xfclose (out);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION_ARGV do_test
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-audit23mod.c b/elf/tst-audit23mod.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..30315687037d25e8
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit23mod.c
|
||||
@@ -0,0 +1,23 @@
|
||||
+/* Extra module for tst-audit23
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+int
|
||||
+foo (void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/elf/tst-auditmod23.c b/elf/tst-auditmod23.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d7c60d7a5cbc4f8a
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod23.c
|
||||
@@ -0,0 +1,74 @@
|
||||
+/* Audit module loaded by tst-audit23.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <link.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/auxv.h>
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int version)
|
||||
+{
|
||||
+ return LAV_CURRENT;
|
||||
+}
|
||||
+
|
||||
+struct map_desc_t
|
||||
+{
|
||||
+ char *lname;
|
||||
+ uintptr_t laddr;
|
||||
+ Lmid_t lmid;
|
||||
+};
|
||||
+
|
||||
+void
|
||||
+la_activity (uintptr_t *cookie, unsigned int flag)
|
||||
+{
|
||||
+ fprintf (stderr, "%s: %d %"PRIxPTR"\n", __func__, flag, (uintptr_t) cookie);
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||
+{
|
||||
+ const char *l_name = map->l_name[0] == '\0' ? "mainapp" : map->l_name;
|
||||
+ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
|
||||
+ (uintptr_t) cookie, l_name, map->l_addr, lmid);
|
||||
+
|
||||
+ struct map_desc_t *map_desc = malloc (sizeof (struct map_desc_t));
|
||||
+ if (map_desc == NULL)
|
||||
+ abort ();
|
||||
+
|
||||
+ map_desc->lname = strdup (l_name);
|
||||
+ map_desc->laddr = map->l_addr;
|
||||
+ map_desc->lmid = lmid;
|
||||
+
|
||||
+ *cookie = (uintptr_t) map_desc;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_objclose (uintptr_t *cookie)
|
||||
+{
|
||||
+ struct map_desc_t *map_desc = (struct map_desc_t *) *cookie;
|
||||
+ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
|
||||
+ (uintptr_t) cookie, map_desc->lname, map_desc->laddr,
|
||||
+ map_desc->lmid);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
299
SOURCES/glibc-upstream-2.34-155.patch
Normal file
299
SOURCES/glibc-upstream-2.34-155.patch
Normal file
@ -0,0 +1,299 @@
|
||||
commit efb21b5fb27fbad447d9f242436fb591870f0045
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Mon Jan 24 10:46:16 2022 -0300
|
||||
|
||||
elf: Fix initial-exec TLS access on audit modules (BZ #28096)
|
||||
|
||||
For audit modules and dependencies with initial-exec TLS, we can not
|
||||
set the initial TLS image on default loader initialization because it
|
||||
would already be set by the audit setup. However, subsequent thread
|
||||
creation would need to follow the default behaviour.
|
||||
|
||||
This patch fixes it by setting l_auditing link_map field not only
|
||||
for the audit modules, but also for all its dependencies. This is
|
||||
used on _dl_allocate_tls_init to avoid the static TLS initialization
|
||||
at load time.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit 254d3d5aef2fd8430c469e1938209ac100ebf132)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 407aaeaeb8c84020..3ccf78f62985e2d0 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -367,6 +367,7 @@ tests += \
|
||||
tst-audit18 \
|
||||
tst-audit19b \
|
||||
tst-audit20 \
|
||||
+ tst-audit21 \
|
||||
tst-audit22 \
|
||||
tst-audit23 \
|
||||
tst-auditmany \
|
||||
@@ -654,6 +655,8 @@ modules-names = \
|
||||
tst-auditmod19a \
|
||||
tst-auditmod19b \
|
||||
tst-auditmod20 \
|
||||
+ tst-auditmod21a \
|
||||
+ tst-auditmod21b \
|
||||
tst-auditmod22 \
|
||||
tst-auditmod23 \
|
||||
tst-auxvalmod \
|
||||
@@ -2045,6 +2048,11 @@ tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||
$(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so
|
||||
tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
|
||||
|
||||
+$(objpfx)tst-audit21: $(shared-thread-library)
|
||||
+$(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21a.so
|
||||
+$(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so
|
||||
+tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.so
|
||||
+
|
||||
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||
tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||
|
||||
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||
index e2012d0cd515103b..fab6546e2d31edd4 100644
|
||||
--- a/elf/dl-tls.c
|
||||
+++ b/elf/dl-tls.c
|
||||
@@ -519,8 +519,12 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
|
||||
}
|
||||
|
||||
|
||||
+/* Allocate initial TLS. RESULT should be a non-NULL pointer to storage
|
||||
+ for the TLS space. The DTV may be resized, and so this function may
|
||||
+ call malloc to allocate that space. The loader's GL(dl_load_tls_lock)
|
||||
+ is taken when manipulating global TLS-related data in the loader. */
|
||||
void *
|
||||
-_dl_allocate_tls_init (void *result)
|
||||
+_dl_allocate_tls_init (void *result, bool init_tls)
|
||||
{
|
||||
if (result == NULL)
|
||||
/* The memory allocation failed. */
|
||||
@@ -593,7 +597,14 @@ _dl_allocate_tls_init (void *result)
|
||||
some platforms use in static programs requires it. */
|
||||
dtv[map->l_tls_modid].pointer.val = dest;
|
||||
|
||||
- /* Copy the initialization image and clear the BSS part. */
|
||||
+ /* Copy the initialization image and clear the BSS part. For
|
||||
+ audit modules or dependencies with initial-exec TLS, we can not
|
||||
+ set the initial TLS image on default loader initialization
|
||||
+ because it would already be set by the audit setup. However,
|
||||
+ subsequent thread creation would need to follow the default
|
||||
+ behaviour. */
|
||||
+ if (map->l_ns != LM_ID_BASE && !init_tls)
|
||||
+ continue;
|
||||
memset (__mempcpy (dest, map->l_tls_initimage,
|
||||
map->l_tls_initimage_size), '\0',
|
||||
map->l_tls_blocksize - map->l_tls_initimage_size);
|
||||
@@ -620,7 +631,7 @@ _dl_allocate_tls (void *mem)
|
||||
{
|
||||
return _dl_allocate_tls_init (mem == NULL
|
||||
? _dl_allocate_tls_storage ()
|
||||
- : allocate_dtv (mem));
|
||||
+ : allocate_dtv (mem), true);
|
||||
}
|
||||
rtld_hidden_def (_dl_allocate_tls)
|
||||
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index b089e5cf4740443e..26c6fb6479c9008c 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -2429,7 +2429,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
into the main thread's TLS area, which we allocated above.
|
||||
Note: thread-local variables must only be accessed after completing
|
||||
the next step. */
|
||||
- _dl_allocate_tls_init (tcbp);
|
||||
+ _dl_allocate_tls_init (tcbp, false);
|
||||
|
||||
/* And finally install it for the main thread. */
|
||||
if (! tls_init_tp_called)
|
||||
diff --git a/elf/tst-audit21.c b/elf/tst-audit21.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3a47ab64d44421ee
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit21.c
|
||||
@@ -0,0 +1,42 @@
|
||||
+/* Check LD_AUDIT with static TLS.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <ctype.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+static volatile __thread int out __attribute__ ((tls_model ("initial-exec")));
|
||||
+
|
||||
+static void *
|
||||
+tf (void *arg)
|
||||
+{
|
||||
+ TEST_COMPARE (out, 0);
|
||||
+ out = isspace (' ');
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+int main (int argc, char *argv[])
|
||||
+{
|
||||
+ TEST_COMPARE (out, 0);
|
||||
+ out = isspace (' ');
|
||||
+
|
||||
+ pthread_t t = xpthread_create (NULL, tf, NULL);
|
||||
+ xpthread_join (t);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/elf/tst-auditmod21a.c b/elf/tst-auditmod21a.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f6d51b5c0531c49d
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod21a.c
|
||||
@@ -0,0 +1,80 @@
|
||||
+/* Check LD_AUDIT with static TLS.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <ctype.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <link.h>
|
||||
+
|
||||
+#define tls_ie __attribute__ ((tls_model ("initial-exec")))
|
||||
+
|
||||
+__thread int tls_var0 tls_ie;
|
||||
+__thread int tls_var1 tls_ie = 0x10;
|
||||
+
|
||||
+/* Defined at tst-auditmod21b.so */
|
||||
+extern __thread int tls_var2;
|
||||
+extern __thread int tls_var3;
|
||||
+
|
||||
+static volatile int out;
|
||||
+
|
||||
+static void
|
||||
+call_libc (void)
|
||||
+{
|
||||
+ /* isspace accesses the initial-exec glibc TLS variables, which are
|
||||
+ setup in glibc initialization. */
|
||||
+ out = isspace (' ');
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int v)
|
||||
+{
|
||||
+ tls_var0 = 0x1;
|
||||
+ if (tls_var1 != 0x10)
|
||||
+ abort ();
|
||||
+ tls_var1 = 0x20;
|
||||
+
|
||||
+ tls_var2 = 0x2;
|
||||
+ if (tls_var3 != 0x20)
|
||||
+ abort ();
|
||||
+ tls_var3 = 0x40;
|
||||
+
|
||||
+ call_libc ();
|
||||
+
|
||||
+ return LAV_CURRENT;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_objopen (struct link_map* map, Lmid_t lmid, uintptr_t* cookie)
|
||||
+{
|
||||
+ call_libc ();
|
||||
+ *cookie = (uintptr_t) map;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+la_activity (uintptr_t* cookie, unsigned int flag)
|
||||
+{
|
||||
+ if (tls_var0 != 0x1 || tls_var1 != 0x20)
|
||||
+ abort ();
|
||||
+ call_libc ();
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+la_preinit (uintptr_t* cookie)
|
||||
+{
|
||||
+ call_libc ();
|
||||
+}
|
||||
diff --git a/elf/tst-auditmod21b.c b/elf/tst-auditmod21b.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6ba5335b7514c674
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod21b.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* Check LD_AUDIT with static TLS.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#define tls_ie __attribute__ ((tls_model ("initial-exec")))
|
||||
+
|
||||
+__thread int tls_var2 tls_ie;
|
||||
+__thread int tls_var3 tls_ie = 0x20;
|
||||
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
|
||||
index 50065bc9bd8a28e5..554a721f814b53c4 100644
|
||||
--- a/nptl/allocatestack.c
|
||||
+++ b/nptl/allocatestack.c
|
||||
@@ -139,7 +139,7 @@ get_cached_stack (size_t *sizep, void **memp)
|
||||
memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
|
||||
|
||||
/* Re-initialize the TLS. */
|
||||
- _dl_allocate_tls_init (TLS_TPADJ (result));
|
||||
+ _dl_allocate_tls_init (TLS_TPADJ (result), true);
|
||||
|
||||
return result;
|
||||
}
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 686f0a7b9709eb10..a56060d0204cc453 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1254,7 +1254,7 @@ extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
|
||||
/* These are internal entry points to the two halves of _dl_allocate_tls,
|
||||
only used within rtld.c itself at startup time. */
|
||||
extern void *_dl_allocate_tls_storage (void) attribute_hidden;
|
||||
-extern void *_dl_allocate_tls_init (void *);
|
||||
+extern void *_dl_allocate_tls_init (void *, bool);
|
||||
rtld_hidden_proto (_dl_allocate_tls_init)
|
||||
|
||||
/* Deallocate memory allocated with _dl_allocate_tls. */
|
1778
SOURCES/glibc-upstream-2.34-156.patch
Normal file
1778
SOURCES/glibc-upstream-2.34-156.patch
Normal file
File diff suppressed because it is too large
Load Diff
1042
SOURCES/glibc-upstream-2.34-157.patch
Normal file
1042
SOURCES/glibc-upstream-2.34-157.patch
Normal file
File diff suppressed because it is too large
Load Diff
23
SOURCES/glibc-upstream-2.34-158.patch
Normal file
23
SOURCES/glibc-upstream-2.34-158.patch
Normal file
@ -0,0 +1,23 @@
|
||||
commit 165e7ad459fbba2f89708fba04a55bb3981e884c
|
||||
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
Date: Wed Feb 2 14:03:58 2022 +0000
|
||||
|
||||
Fix elf/tst-audit25a with default bind now toolchains
|
||||
|
||||
This test relies on lazy binding for the executable so request that
|
||||
explicitly in case the toolchain defaults to bind now.
|
||||
|
||||
(cherry picked from commit 80a08d0faa9b224019f895800c4d97de4e23e1aa)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 0ab3e885f5e35671..9e4e056938a75ddb 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -2133,6 +2133,7 @@ $(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \
|
||||
$(objpfx)tst-audit25mod2.so \
|
||||
$(objpfx)tst-audit25mod3.so \
|
||||
$(objpfx)tst-audit25mod4.so
|
||||
+LDFLAGS-tst-audit25a = -Wl,-z,lazy
|
||||
$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so
|
||||
LDFLAGS-tst-audit25mod1.so = -Wl,-z,now
|
||||
$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so
|
27
SOURCES/glibc-upstream-2.34-159.patch
Normal file
27
SOURCES/glibc-upstream-2.34-159.patch
Normal file
@ -0,0 +1,27 @@
|
||||
commit aabdad371f44defc6046aabdc96af7782a2e94be
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Sun Feb 6 11:12:24 2022 -0800
|
||||
|
||||
elf: Replace tst-audit24bmod2.so with tst-audit24bmod2
|
||||
|
||||
Replace tst-audit24bmod2.so with tst-audit24bmod2 to silence:
|
||||
|
||||
make[2]: Entering directory '/export/gnu/import/git/gitlab/x86-glibc/elf'
|
||||
Makefile:2201: warning: overriding recipe for target '/export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/elf/tst-audit24bmod2.so'
|
||||
../Makerules:765: warning: ignoring old recipe for target '/export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/elf/tst-audit24bmod2.so'
|
||||
|
||||
(cherry picked from commit fa7ad1df1915c8a62f50e3a5b7e10f9c7118cd7f)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 9e4e056938a75ddb..57059293d0bc86cb 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -888,7 +888,7 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
|
||||
# filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
|
||||
# rules.
|
||||
modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \
|
||||
- tst-audit24bmod1 tst-audit24bmod2.so
|
||||
+ tst-audit24bmod1 tst-audit24bmod2
|
||||
|
||||
tests += $(tests-static)
|
||||
|
114
SOURCES/glibc-upstream-2.34-160.patch
Normal file
114
SOURCES/glibc-upstream-2.34-160.patch
Normal file
@ -0,0 +1,114 @@
|
||||
commit 4dca2d3a7b43bf99bd6a567870a3144af4e763ef
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Fri Feb 4 15:54:59 2022 -0300
|
||||
|
||||
hppa: Fix bind-now audit (BZ #28857)
|
||||
|
||||
On hppa, a function pointer returned by la_symbind is actually a function
|
||||
descriptor has the plabel bit set (bit 30). This must be cleared to get
|
||||
the actual address of the descriptor. If the descriptor has been bound,
|
||||
the first word of the descriptor is the physical address of theA function,
|
||||
otherwise, the first word of the descriptor points to a trampoline in the
|
||||
PLT.
|
||||
|
||||
This patch also adds a workaround on tests because on hppa (and it seems
|
||||
to be the only ABI I have see it), some shared library adds a dynamic PLT
|
||||
relocation to am empty symbol name:
|
||||
|
||||
$ readelf -r elf/tst-audit25mod1.so
|
||||
[...]
|
||||
Relocation section '.rela.plt' at offset 0x464 contains 6 entries:
|
||||
Offset Info Type Sym.Value Sym. Name + Addend
|
||||
00002008 00000081 R_PARISC_IPLT 508
|
||||
[...]
|
||||
|
||||
It breaks some assumptions on the test, where a symbol with an empty
|
||||
name ("") is passed on la_symbind.
|
||||
|
||||
Checked on x86_64-linux-gnu and hppa-linux-gnu.
|
||||
|
||||
(cherry picked from commit 9e94f57484a2aba0fe67ea2059b5843f651887c2)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 57059293d0bc86cb..3e17a0706f5ec2df 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -2116,7 +2116,7 @@ $(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so
|
||||
$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \
|
||||
$(objpfx)tst-audit24amod2.so
|
||||
tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so
|
||||
-LDFLAGS-tst-audit24b = -Wl,-z,lazy
|
||||
+LDFLAGS-tst-audit24c = -Wl,-z,lazy
|
||||
|
||||
$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so
|
||||
$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \
|
||||
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||
index 72a50717ef60a357..ec9b032eae37c103 100644
|
||||
--- a/elf/dl-audit.c
|
||||
+++ b/elf/dl-audit.c
|
||||
@@ -257,7 +257,8 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||
reloc_result->flags = flags;
|
||||
}
|
||||
|
||||
- DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
|
||||
+ if (flags & LA_SYMB_ALTVALUE)
|
||||
+ DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
|
||||
}
|
||||
|
||||
void
|
||||
diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c
|
||||
index d8e88f3984af1707..3075dfae2fd3d288 100644
|
||||
--- a/elf/tst-auditmod24a.c
|
||||
+++ b/elf/tst-auditmod24a.c
|
||||
@@ -110,5 +110,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||
return sym->st_value;
|
||||
}
|
||||
|
||||
- abort ();
|
||||
+ if (symname[0] != '\0')
|
||||
+ abort ();
|
||||
+ return sym->st_value;
|
||||
}
|
||||
diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c
|
||||
index 8c803ecc0a48f21b..badc6be451ee0357 100644
|
||||
--- a/elf/tst-auditmod24d.c
|
||||
+++ b/elf/tst-auditmod24d.c
|
||||
@@ -116,5 +116,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||
}
|
||||
}
|
||||
|
||||
- abort ();
|
||||
+ if (symname[0] != '\0')
|
||||
+ abort ();
|
||||
+ return sym->st_value;
|
||||
}
|
||||
diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c
|
||||
index 526f5c54bc2c3b8c..20640a8daf346b5f 100644
|
||||
--- a/elf/tst-auditmod25.c
|
||||
+++ b/elf/tst-auditmod25.c
|
||||
@@ -72,7 +72,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||
unsigned int *flags, const char *symname)
|
||||
#endif
|
||||
{
|
||||
- if (*refcook != -1 && *defcook != -1)
|
||||
+ if (*refcook != -1 && *defcook != -1 && symname[0] != '\0')
|
||||
fprintf (stderr, "la_symbind: %s %u\n", symname,
|
||||
*flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0);
|
||||
return sym->st_value;
|
||||
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
|
||||
index f4f00714fa158e18..92fd0b7c844713ce 100644
|
||||
--- a/sysdeps/hppa/dl-lookupcfg.h
|
||||
+++ b/sysdeps/hppa/dl-lookupcfg.h
|
||||
@@ -80,7 +80,9 @@ void attribute_hidden _dl_unmap (struct link_map *map);
|
||||
/* Extract the code address from a fixup value */
|
||||
#define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
|
||||
#define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
|
||||
-#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
|
||||
+/* Clear the plabel bit to get the actual address of the descriptor. */
|
||||
+#define DL_FIXUP_ADDR_VALUE(addr) \
|
||||
+ (*(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (addr) & ~2))
|
||||
#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
|
||||
-#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
|
||||
- (*value) = *(struct fdesc *) (st_value)
|
||||
+#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
|
||||
+ *(value) = *(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (new_value) & ~2)
|
242
SOURCES/glibc-upstream-2.34-162.patch
Normal file
242
SOURCES/glibc-upstream-2.34-162.patch
Normal file
@ -0,0 +1,242 @@
|
||||
commit 0c03cb54c808173d8e7ba96f6152dfcf627ac496
|
||||
Author: Stefan Liebler <stli@linux.ibm.com>
|
||||
Date: Wed Apr 13 14:36:09 2022 +0200
|
||||
|
||||
S390: Add new s390 platform z16.
|
||||
|
||||
The new IBM z16 is added to platform string array.
|
||||
The macro _DL_PLATFORMS_COUNT is incremented.
|
||||
|
||||
_dl_hwcaps_subdir is extended by "z16" if HWCAP_S390_VXRS_PDE2
|
||||
is set. HWCAP_S390_NNPA is not tested in _dl_hwcaps_subdirs_active
|
||||
as those instructions may be replaced or removed in future.
|
||||
|
||||
tst-glibc-hwcaps.c is extended in order to test z16 via new marker5.
|
||||
|
||||
A fatal glibc error is dumped if glibc was build with architecture
|
||||
level set for z16, but run on an older machine. (See dl-hwcap-check.h)
|
||||
|
||||
(cherry picked from commit 2376944b9e5c0364b9fb473e4d8dabca31b57167)
|
||||
|
||||
Conflicts:
|
||||
sysdeps/s390/s390-64/dl-hwcap-check.h - Use GCCMACRO__ARCH__.
|
||||
- Backported f01d482f0355a7029d0715ace0ccf3323e7e94bc requires it.
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 3e17a0706f5ec2df..8e2dd91c583f9a62 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -571,6 +571,11 @@ modules-names = \
|
||||
libmarkermod4-2 \
|
||||
libmarkermod4-3 \
|
||||
libmarkermod4-4 \
|
||||
+ libmarkermod5-1 \
|
||||
+ libmarkermod5-2 \
|
||||
+ libmarkermod5-3 \
|
||||
+ libmarkermod5-4 \
|
||||
+ libmarkermod5-5 \
|
||||
ltglobmod1 \
|
||||
ltglobmod2 \
|
||||
neededobj1 \
|
||||
@@ -2412,6 +2417,7 @@ LDFLAGS-libmarkermod1-1.so += -Wl,-soname,libmarkermod1.so
|
||||
LDFLAGS-libmarkermod2-1.so += -Wl,-soname,libmarkermod2.so
|
||||
LDFLAGS-libmarkermod3-1.so += -Wl,-soname,libmarkermod3.so
|
||||
LDFLAGS-libmarkermod4-1.so += -Wl,-soname,libmarkermod4.so
|
||||
+LDFLAGS-libmarkermod5-1.so += -Wl,-soname,libmarkermod5.so
|
||||
$(objpfx)libmarkermod%.os : markermodMARKER-VALUE.c
|
||||
$(compile-command.c) \
|
||||
-DMARKER=marker$(firstword $(subst -, ,$*)) \
|
||||
@@ -2424,6 +2430,8 @@ $(objpfx)libmarkermod3.so: $(objpfx)libmarkermod3-1.so
|
||||
cp $< $@
|
||||
$(objpfx)libmarkermod4.so: $(objpfx)libmarkermod4-1.so
|
||||
cp $< $@
|
||||
+$(objpfx)libmarkermod5.so: $(objpfx)libmarkermod5-1.so
|
||||
+ cp $< $@
|
||||
|
||||
# tst-glibc-hwcaps-prepend checks that --glibc-hwcaps-prepend is
|
||||
# preferred over auto-detected subdirectories.
|
||||
diff --git a/elf/tst-glibc-hwcaps-cache.script b/elf/tst-glibc-hwcaps-cache.script
|
||||
index c3271f61f9e50f2e..d58fc8c5de3c5198 100644
|
||||
--- a/elf/tst-glibc-hwcaps-cache.script
|
||||
+++ b/elf/tst-glibc-hwcaps-cache.script
|
||||
@@ -4,6 +4,7 @@
|
||||
cp $B/elf/libmarkermod2-1.so $L/libmarkermod2.so
|
||||
cp $B/elf/libmarkermod3-1.so $L/libmarkermod3.so
|
||||
cp $B/elf/libmarkermod4-1.so $L/libmarkermod4.so
|
||||
+cp $B/elf/libmarkermod5-1.so $L/libmarkermod5.so
|
||||
|
||||
mkdirp 0770 $L/glibc-hwcaps/power9
|
||||
cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/power9/libmarkermod2.so
|
||||
@@ -20,6 +21,11 @@ mkdirp 0770 $L/glibc-hwcaps/z15
|
||||
cp $B/elf/libmarkermod4-2.so $L/glibc-hwcaps/z13/libmarkermod4.so
|
||||
cp $B/elf/libmarkermod4-3.so $L/glibc-hwcaps/z14/libmarkermod4.so
|
||||
cp $B/elf/libmarkermod4-4.so $L/glibc-hwcaps/z15/libmarkermod4.so
|
||||
+mkdirp 0770 $L/glibc-hwcaps/z16
|
||||
+cp $B/elf/libmarkermod5-2.so $L/glibc-hwcaps/z13/libmarkermod5.so
|
||||
+cp $B/elf/libmarkermod5-3.so $L/glibc-hwcaps/z14/libmarkermod5.so
|
||||
+cp $B/elf/libmarkermod5-4.so $L/glibc-hwcaps/z15/libmarkermod5.so
|
||||
+cp $B/elf/libmarkermod5-5.so $L/glibc-hwcaps/z16/libmarkermod5.so
|
||||
|
||||
mkdirp 0770 $L/glibc-hwcaps/x86-64-v2
|
||||
cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/x86-64-v2/libmarkermod2.so
|
||||
diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
|
||||
index 155f0bd99eccb3f9..755b54ff13a0fa2f 100644
|
||||
--- a/sysdeps/s390/dl-procinfo.c
|
||||
+++ b/sysdeps/s390/dl-procinfo.c
|
||||
@@ -64,11 +64,12 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[23][9]
|
||||
#if !defined PROCINFO_DECL && defined SHARED
|
||||
._dl_s390_platforms
|
||||
#else
|
||||
-PROCINFO_CLASS const char _dl_s390_platforms[10][7]
|
||||
+PROCINFO_CLASS const char _dl_s390_platforms[11][7]
|
||||
#endif
|
||||
#ifndef PROCINFO_DECL
|
||||
= {
|
||||
- "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15"
|
||||
+ "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15",
|
||||
+ "z16"
|
||||
}
|
||||
#endif
|
||||
#if !defined SHARED || defined PROCINFO_DECL
|
||||
diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
|
||||
index e4e3e334a5b3d47c..d44e1dd97441bd90 100644
|
||||
--- a/sysdeps/s390/dl-procinfo.h
|
||||
+++ b/sysdeps/s390/dl-procinfo.h
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#define _DL_HWCAP_COUNT 23
|
||||
|
||||
-#define _DL_PLATFORMS_COUNT 10
|
||||
+#define _DL_PLATFORMS_COUNT 11
|
||||
|
||||
/* The kernel provides up to 32 capability bits with elf_hwcap. */
|
||||
#define _DL_FIRST_PLATFORM 32
|
||||
diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile
|
||||
index e5da26871c862e63..66ed844e68df5159 100644
|
||||
--- a/sysdeps/s390/s390-64/Makefile
|
||||
+++ b/sysdeps/s390/s390-64/Makefile
|
||||
@@ -7,8 +7,11 @@ CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused
|
||||
CFLAGS-dl-load.c += -Wno-unused
|
||||
CFLAGS-dl-reloc.c += -Wno-unused
|
||||
|
||||
-$(objpfx)tst-glibc-hwcaps: $(objpfx)libmarkermod2-1.so \
|
||||
- $(objpfx)libmarkermod3-1.so $(objpfx)libmarkermod4-1.so
|
||||
+$(objpfx)tst-glibc-hwcaps: \
|
||||
+ $(objpfx)libmarkermod2-1.so \
|
||||
+ $(objpfx)libmarkermod3-1.so \
|
||||
+ $(objpfx)libmarkermod4-1.so \
|
||||
+ $(objpfx)libmarkermod5-1.so
|
||||
$(objpfx)tst-glibc-hwcaps.out: \
|
||||
$(objpfx)libmarkermod2.so \
|
||||
$(objpfx)glibc-hwcaps/z13/libmarkermod2.so \
|
||||
@@ -19,6 +22,11 @@ $(objpfx)tst-glibc-hwcaps.out: \
|
||||
$(objpfx)glibc-hwcaps/z13/libmarkermod4.so \
|
||||
$(objpfx)glibc-hwcaps/z14/libmarkermod4.so \
|
||||
$(objpfx)glibc-hwcaps/z15/libmarkermod4.so \
|
||||
+ $(objpfx)libmarkermod5.so \
|
||||
+ $(objpfx)glibc-hwcaps/z13/libmarkermod5.so \
|
||||
+ $(objpfx)glibc-hwcaps/z14/libmarkermod5.so \
|
||||
+ $(objpfx)glibc-hwcaps/z15/libmarkermod5.so \
|
||||
+ $(objpfx)glibc-hwcaps/z16/libmarkermod5.so
|
||||
|
||||
$(objpfx)glibc-hwcaps/z13/libmarkermod2.so: $(objpfx)libmarkermod2-2.so
|
||||
$(make-target-directory)
|
||||
@@ -38,6 +46,19 @@ $(objpfx)glibc-hwcaps/z14/libmarkermod4.so: $(objpfx)libmarkermod4-3.so
|
||||
$(objpfx)glibc-hwcaps/z15/libmarkermod4.so: $(objpfx)libmarkermod4-4.so
|
||||
$(make-target-directory)
|
||||
cp $< $@
|
||||
+$(objpfx)glibc-hwcaps/z13/libmarkermod5.so: $(objpfx)libmarkermod5-2.so
|
||||
+ $(make-target-directory)
|
||||
+ cp $< $@
|
||||
+$(objpfx)glibc-hwcaps/z14/libmarkermod5.so: $(objpfx)libmarkermod5-3.so
|
||||
+ $(make-target-directory)
|
||||
+ cp $< $@
|
||||
+$(objpfx)glibc-hwcaps/z15/libmarkermod5.so: $(objpfx)libmarkermod5-4.so
|
||||
+ $(make-target-directory)
|
||||
+ cp $< $@
|
||||
+$(objpfx)glibc-hwcaps/z16/libmarkermod5.so: $(objpfx)libmarkermod5-5.so
|
||||
+ $(make-target-directory)
|
||||
+ cp $< $@
|
||||
+
|
||||
|
||||
ifeq (no,$(build-hardcoded-path-in-tests))
|
||||
# This is an ld.so.cache test, and RPATH/RUNPATH in the executable
|
||||
diff --git a/sysdeps/s390/s390-64/dl-hwcap-check.h b/sysdeps/s390/s390-64/dl-hwcap-check.h
|
||||
index 27f7e245b1d1a9e9..52c609571b32f4ab 100644
|
||||
--- a/sysdeps/s390/s390-64/dl-hwcap-check.h
|
||||
+++ b/sysdeps/s390/s390-64/dl-hwcap-check.h
|
||||
@@ -26,7 +26,11 @@ static inline void
|
||||
dl_hwcap_check (void)
|
||||
{
|
||||
#if defined __ARCH__
|
||||
-# if GCCMACRO__ARCH__ >= 13
|
||||
+# if GCCMACRO__ARCH__ >= 14
|
||||
+ if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_PDE2))
|
||||
+ _dl_fatal_printf ("\
|
||||
+Fatal glibc error: CPU lacks VXRS_PDE2 support (z16 or later required)\n");
|
||||
+# elif GCCMACRO__ARCH__ >= 13
|
||||
if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_EXT2))
|
||||
_dl_fatal_printf ("\
|
||||
Fatal glibc error: CPU lacks VXRS_EXT2 support (z15 or later required)\n");
|
||||
diff --git a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c
|
||||
index b9d094f3d73c2d7a..187d732d560c4a62 100644
|
||||
--- a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c
|
||||
+++ b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c
|
||||
@@ -19,8 +19,8 @@
|
||||
#include <dl-hwcaps.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
-const char _dl_hwcaps_subdirs[] = "z15:z14:z13";
|
||||
-enum { subdirs_count = 3 }; /* Number of components in _dl_hwcaps_subdirs. */
|
||||
+const char _dl_hwcaps_subdirs[] = "z16:z15:z14:z13";
|
||||
+enum { subdirs_count = 4 }; /* Number of components in _dl_hwcaps_subdirs. */
|
||||
|
||||
uint32_t
|
||||
_dl_hwcaps_subdirs_active (void)
|
||||
@@ -50,5 +50,12 @@ _dl_hwcaps_subdirs_active (void)
|
||||
return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active);
|
||||
++active;
|
||||
|
||||
+ /* z16.
|
||||
+ Note: We do not list HWCAP_S390_NNPA here as, according to the Principles of
|
||||
+ Operation, those instructions may be replaced or removed in future. */
|
||||
+ if (!(GLRO (dl_hwcap) & HWCAP_S390_VXRS_PDE2))
|
||||
+ return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active);
|
||||
+ ++active;
|
||||
+
|
||||
return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active);
|
||||
}
|
||||
diff --git a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c
|
||||
index 02397a478c552516..f3b8ef3dec80d2d1 100644
|
||||
--- a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c
|
||||
+++ b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c
|
||||
@@ -25,6 +25,7 @@
|
||||
extern int marker2 (void);
|
||||
extern int marker3 (void);
|
||||
extern int marker4 (void);
|
||||
+extern int marker5 (void);
|
||||
|
||||
/* Return the arch level, 10 for the baseline libmarkermod*.so's. */
|
||||
static int
|
||||
@@ -63,9 +64,11 @@ compute_level (void)
|
||||
return 12;
|
||||
if (strcmp (platform, "z15") == 0)
|
||||
return 13;
|
||||
+ if (strcmp (platform, "z16") == 0)
|
||||
+ return 14;
|
||||
printf ("warning: unrecognized AT_PLATFORM value: %s\n", platform);
|
||||
- /* Assume that the new platform supports z15. */
|
||||
- return 13;
|
||||
+ /* Assume that the new platform supports z16. */
|
||||
+ return 14;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -76,6 +79,7 @@ do_test (void)
|
||||
TEST_COMPARE (marker2 (), MIN (level - 9, 2));
|
||||
TEST_COMPARE (marker3 (), MIN (level - 9, 3));
|
||||
TEST_COMPARE (marker4 (), MIN (level - 9, 4));
|
||||
+ TEST_COMPARE (marker5 (), MIN (level - 9, 5));
|
||||
return 0;
|
||||
}
|
||||
|
834
SOURCES/glibc-upstream-2.34-163.patch
Normal file
834
SOURCES/glibc-upstream-2.34-163.patch
Normal file
@ -0,0 +1,834 @@
|
||||
commit 290db09546b260a30137d03ce97a857e6f15b648
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Apr 6 12:24:42 2022 -0300
|
||||
|
||||
nptl: Handle spurious EINTR when thread cancellation is disabled (BZ#29029)
|
||||
|
||||
Some Linux interfaces never restart after being interrupted by a signal
|
||||
handler, regardless of the use of SA_RESTART [1]. It means that for
|
||||
pthread cancellation, if the target thread disables cancellation with
|
||||
pthread_setcancelstate and calls such interfaces (like poll or select),
|
||||
it should not see spurious EINTR failures due the internal SIGCANCEL.
|
||||
|
||||
However recent changes made pthread_cancel to always sent the internal
|
||||
signal, regardless of the target thread cancellation status or type.
|
||||
To fix it, the previous semantic is restored, where the cancel signal
|
||||
is only sent if the target thread has cancelation enabled in
|
||||
asynchronous mode.
|
||||
|
||||
The cancel state and cancel type is moved back to cancelhandling
|
||||
and atomic operation are used to synchronize between threads. The
|
||||
patch essentially revert the following commits:
|
||||
|
||||
8c1c0aae20 nptl: Move cancel type out of cancelhandling
|
||||
2b51742531 nptl: Move cancel state out of cancelhandling
|
||||
26cfbb7162 nptl: Remove CANCELING_BITMASK
|
||||
|
||||
However I changed the atomic operation to follow the internal C11
|
||||
semantic and removed the MACRO usage, it simplifies a bit the
|
||||
resulting code (and removes another usage of the old atomic macros).
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
|
||||
and powerpc64-linux-gnu.
|
||||
|
||||
[1] https://man7.org/linux/man-pages/man7/signal.7.html
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
Tested-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
|
||||
(cherry-picked from commit 404656009b459658138ed1bd18f3c6cf3863e6a6)
|
||||
|
||||
diff --git a/manual/process.texi b/manual/process.texi
|
||||
index 28c9531f4294f56e..9307379194c6f666 100644
|
||||
--- a/manual/process.texi
|
||||
+++ b/manual/process.texi
|
||||
@@ -68,8 +68,7 @@ until the subprogram terminates before you can do anything else.
|
||||
@c CLEANUP_HANDLER @ascuplugin @ascuheap @acsmem
|
||||
@c libc_cleanup_region_start @ascuplugin @ascuheap @acsmem
|
||||
@c pthread_cleanup_push_defer @ascuplugin @ascuheap @acsmem
|
||||
-@c __pthread_testcancel @ascuplugin @ascuheap @acsmem
|
||||
-@c CANCEL_ENABLED_AND_CANCELED ok
|
||||
+@c cancel_enabled_and_canceled @ascuplugin @ascuheap @acsmem
|
||||
@c do_cancel @ascuplugin @ascuheap @acsmem
|
||||
@c cancel_handler ok
|
||||
@c kill syscall ok
|
||||
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
|
||||
index 554a721f814b53c4..96101753ec2f4323 100644
|
||||
--- a/nptl/allocatestack.c
|
||||
+++ b/nptl/allocatestack.c
|
||||
@@ -120,8 +120,6 @@ get_cached_stack (size_t *sizep, void **memp)
|
||||
|
||||
/* Cancellation handling is back to the default. */
|
||||
result->cancelhandling = 0;
|
||||
- result->cancelstate = PTHREAD_CANCEL_ENABLE;
|
||||
- result->canceltype = PTHREAD_CANCEL_DEFERRED;
|
||||
result->cleanup = NULL;
|
||||
result->setup_failed = 0;
|
||||
|
||||
diff --git a/nptl/cancellation.c b/nptl/cancellation.c
|
||||
index 05962784d51fb98b..e97d56f97d7a5698 100644
|
||||
--- a/nptl/cancellation.c
|
||||
+++ b/nptl/cancellation.c
|
||||
@@ -31,19 +31,26 @@ int
|
||||
__pthread_enable_asynccancel (void)
|
||||
{
|
||||
struct pthread *self = THREAD_SELF;
|
||||
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||
|
||||
- int oldval = THREAD_GETMEM (self, canceltype);
|
||||
- THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_ASYNCHRONOUS);
|
||||
+ while (1)
|
||||
+ {
|
||||
+ int newval = oldval | CANCELTYPE_BITMASK;
|
||||
|
||||
- int ch = THREAD_GETMEM (self, cancelhandling);
|
||||
+ if (newval == oldval)
|
||||
+ break;
|
||||
|
||||
- if (self->cancelstate == PTHREAD_CANCEL_ENABLE
|
||||
- && (ch & CANCELED_BITMASK)
|
||||
- && !(ch & EXITING_BITMASK)
|
||||
- && !(ch & TERMINATED_BITMASK))
|
||||
- {
|
||||
- THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||
- __do_cancel ();
|
||||
+ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||
+ &oldval, newval))
|
||||
+ {
|
||||
+ if (cancel_enabled_and_canceled_and_async (newval))
|
||||
+ {
|
||||
+ self->result = PTHREAD_CANCELED;
|
||||
+ __do_cancel ();
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
return oldval;
|
||||
@@ -57,10 +64,29 @@ __pthread_disable_asynccancel (int oldtype)
|
||||
{
|
||||
/* If asynchronous cancellation was enabled before we do not have
|
||||
anything to do. */
|
||||
- if (oldtype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||
+ if (oldtype & CANCELTYPE_BITMASK)
|
||||
return;
|
||||
|
||||
struct pthread *self = THREAD_SELF;
|
||||
- self->canceltype = PTHREAD_CANCEL_DEFERRED;
|
||||
+ int newval;
|
||||
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||
+ do
|
||||
+ {
|
||||
+ newval = oldval & ~CANCELTYPE_BITMASK;
|
||||
+ }
|
||||
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||
+ &oldval, newval));
|
||||
+
|
||||
+ /* We cannot return when we are being canceled. Upon return the
|
||||
+ thread might be things which would have to be undone. The
|
||||
+ following loop should loop until the cancellation signal is
|
||||
+ delivered. */
|
||||
+ while (__glibc_unlikely ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
|
||||
+ == CANCELING_BITMASK))
|
||||
+ {
|
||||
+ futex_wait_simple ((unsigned int *) &self->cancelhandling, newval,
|
||||
+ FUTEX_PRIVATE);
|
||||
+ newval = atomic_load_relaxed (&self->cancelhandling);
|
||||
+ }
|
||||
}
|
||||
libc_hidden_def (__pthread_disable_asynccancel)
|
||||
diff --git a/nptl/cleanup_defer.c b/nptl/cleanup_defer.c
|
||||
index 7e858d0df068276b..35ba40fb0247c7cc 100644
|
||||
--- a/nptl/cleanup_defer.c
|
||||
+++ b/nptl/cleanup_defer.c
|
||||
@@ -31,9 +31,22 @@ ___pthread_register_cancel_defer (__pthread_unwind_buf_t *buf)
|
||||
ibuf->priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
|
||||
ibuf->priv.data.cleanup = THREAD_GETMEM (self, cleanup);
|
||||
|
||||
- /* Disable asynchronous cancellation for now. */
|
||||
- ibuf->priv.data.canceltype = THREAD_GETMEM (self, canceltype);
|
||||
- THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_DEFERRED);
|
||||
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||
+ if (__glibc_unlikely (cancelhandling & CANCELTYPE_BITMASK))
|
||||
+ {
|
||||
+ int newval;
|
||||
+ do
|
||||
+ {
|
||||
+ newval = cancelhandling & ~CANCELTYPE_BITMASK;
|
||||
+ }
|
||||
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||
+ &cancelhandling,
|
||||
+ newval));
|
||||
+ }
|
||||
+
|
||||
+ ibuf->priv.data.canceltype = (cancelhandling & CANCELTYPE_BITMASK
|
||||
+ ? PTHREAD_CANCEL_ASYNCHRONOUS
|
||||
+ : PTHREAD_CANCEL_DEFERRED);
|
||||
|
||||
/* Store the new cleanup handler info. */
|
||||
THREAD_SETMEM (self, cleanup_jmp_buf, (struct pthread_unwind_buf *) buf);
|
||||
@@ -55,9 +68,26 @@ ___pthread_unregister_cancel_restore (__pthread_unwind_buf_t *buf)
|
||||
|
||||
THREAD_SETMEM (self, cleanup_jmp_buf, ibuf->priv.data.prev);
|
||||
|
||||
- THREAD_SETMEM (self, canceltype, ibuf->priv.data.canceltype);
|
||||
- if (ibuf->priv.data.canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||
- __pthread_testcancel ();
|
||||
+ if (ibuf->priv.data.canceltype == PTHREAD_CANCEL_DEFERRED)
|
||||
+ return;
|
||||
+
|
||||
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||
+ if (cancelhandling & CANCELTYPE_BITMASK)
|
||||
+ {
|
||||
+ int newval;
|
||||
+ do
|
||||
+ {
|
||||
+ newval = cancelhandling | CANCELTYPE_BITMASK;
|
||||
+ }
|
||||
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||
+ &cancelhandling, newval));
|
||||
+
|
||||
+ if (cancel_enabled_and_canceled (cancelhandling))
|
||||
+ {
|
||||
+ self->result = PTHREAD_CANCELED;
|
||||
+ __do_cancel ();
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
versioned_symbol (libc, ___pthread_unregister_cancel_restore,
|
||||
__pthread_unregister_cancel_restore, GLIBC_2_34);
|
||||
diff --git a/nptl/descr.h b/nptl/descr.h
|
||||
index dabf980e29615db3..dfef9c4bda075d13 100644
|
||||
--- a/nptl/descr.h
|
||||
+++ b/nptl/descr.h
|
||||
@@ -280,18 +280,27 @@ struct pthread
|
||||
|
||||
/* Flags determining processing of cancellation. */
|
||||
int cancelhandling;
|
||||
+ /* Bit set if cancellation is disabled. */
|
||||
+#define CANCELSTATE_BIT 0
|
||||
+#define CANCELSTATE_BITMASK (1 << CANCELSTATE_BIT)
|
||||
+ /* Bit set if asynchronous cancellation mode is selected. */
|
||||
+#define CANCELTYPE_BIT 1
|
||||
+#define CANCELTYPE_BITMASK (1 << CANCELTYPE_BIT)
|
||||
+ /* Bit set if canceling has been initiated. */
|
||||
+#define CANCELING_BIT 2
|
||||
+#define CANCELING_BITMASK (1 << CANCELING_BIT)
|
||||
/* Bit set if canceled. */
|
||||
#define CANCELED_BIT 3
|
||||
-#define CANCELED_BITMASK (0x01 << CANCELED_BIT)
|
||||
+#define CANCELED_BITMASK (1 << CANCELED_BIT)
|
||||
/* Bit set if thread is exiting. */
|
||||
#define EXITING_BIT 4
|
||||
-#define EXITING_BITMASK (0x01 << EXITING_BIT)
|
||||
+#define EXITING_BITMASK (1 << EXITING_BIT)
|
||||
/* Bit set if thread terminated and TCB is freed. */
|
||||
#define TERMINATED_BIT 5
|
||||
-#define TERMINATED_BITMASK (0x01 << TERMINATED_BIT)
|
||||
+#define TERMINATED_BITMASK (1 << TERMINATED_BIT)
|
||||
/* Bit set if thread is supposed to change XID. */
|
||||
#define SETXID_BIT 6
|
||||
-#define SETXID_BITMASK (0x01 << SETXID_BIT)
|
||||
+#define SETXID_BITMASK (1 << SETXID_BIT)
|
||||
|
||||
/* Flags. Including those copied from the thread attribute. */
|
||||
int flags;
|
||||
@@ -391,14 +400,6 @@ struct pthread
|
||||
/* Indicates whether is a C11 thread created by thrd_creat. */
|
||||
bool c11;
|
||||
|
||||
- /* Thread cancel state (PTHREAD_CANCEL_ENABLE or
|
||||
- PTHREAD_CANCEL_DISABLE). */
|
||||
- unsigned char cancelstate;
|
||||
-
|
||||
- /* Thread cancel type (PTHREAD_CANCEL_DEFERRED or
|
||||
- PTHREAD_CANCEL_ASYNCHRONOUS). */
|
||||
- unsigned char canceltype;
|
||||
-
|
||||
/* Used in __pthread_kill_internal to detected a thread that has
|
||||
exited or is about to exit. exit_lock must only be acquired
|
||||
after blocking signals. */
|
||||
@@ -418,6 +419,22 @@ struct pthread
|
||||
(sizeof (struct pthread) - offsetof (struct pthread, end_padding))
|
||||
} __attribute ((aligned (TCB_ALIGNMENT)));
|
||||
|
||||
+static inline bool
|
||||
+cancel_enabled_and_canceled (int value)
|
||||
+{
|
||||
+ return (value & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK
|
||||
+ | TERMINATED_BITMASK))
|
||||
+ == CANCELED_BITMASK;
|
||||
+}
|
||||
+
|
||||
+static inline bool
|
||||
+cancel_enabled_and_canceled_and_async (int value)
|
||||
+{
|
||||
+ return ((value) & (CANCELSTATE_BITMASK | CANCELTYPE_BITMASK | CANCELED_BITMASK
|
||||
+ | EXITING_BITMASK | TERMINATED_BITMASK))
|
||||
+ == (CANCELTYPE_BITMASK | CANCELED_BITMASK);
|
||||
+}
|
||||
+
|
||||
/* This yields the pointer that TLS support code calls the thread pointer. */
|
||||
#if TLS_TCB_AT_TP
|
||||
# define TLS_TPADJ(pd) (pd)
|
||||
diff --git a/nptl/libc-cleanup.c b/nptl/libc-cleanup.c
|
||||
index 180d15bc9e9a8368..fccb1abe69aa693c 100644
|
||||
--- a/nptl/libc-cleanup.c
|
||||
+++ b/nptl/libc-cleanup.c
|
||||
@@ -27,9 +27,24 @@ __libc_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer)
|
||||
|
||||
buffer->__prev = THREAD_GETMEM (self, cleanup);
|
||||
|
||||
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||
+
|
||||
/* Disable asynchronous cancellation for now. */
|
||||
- buffer->__canceltype = THREAD_GETMEM (self, canceltype);
|
||||
- THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_DEFERRED);
|
||||
+ if (__glibc_unlikely (cancelhandling & CANCELTYPE_BITMASK))
|
||||
+ {
|
||||
+ int newval;
|
||||
+ do
|
||||
+ {
|
||||
+ newval = cancelhandling & ~CANCELTYPE_BITMASK;
|
||||
+ }
|
||||
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||
+ &cancelhandling,
|
||||
+ newval));
|
||||
+ }
|
||||
+
|
||||
+ buffer->__canceltype = (cancelhandling & CANCELTYPE_BITMASK
|
||||
+ ? PTHREAD_CANCEL_ASYNCHRONOUS
|
||||
+ : PTHREAD_CANCEL_DEFERRED);
|
||||
|
||||
THREAD_SETMEM (self, cleanup, buffer);
|
||||
}
|
||||
@@ -42,8 +57,22 @@ __libc_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer)
|
||||
|
||||
THREAD_SETMEM (self, cleanup, buffer->__prev);
|
||||
|
||||
- THREAD_SETMEM (self, canceltype, buffer->__canceltype);
|
||||
- if (buffer->__canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||
- __pthread_testcancel ();
|
||||
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||
+ if (cancelhandling & CANCELTYPE_BITMASK)
|
||||
+ {
|
||||
+ int newval;
|
||||
+ do
|
||||
+ {
|
||||
+ newval = cancelhandling | CANCELTYPE_BITMASK;
|
||||
+ }
|
||||
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||
+ &cancelhandling, newval));
|
||||
+
|
||||
+ if (cancel_enabled_and_canceled (cancelhandling))
|
||||
+ {
|
||||
+ self->result = PTHREAD_CANCELED;
|
||||
+ __do_cancel ();
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
libc_hidden_def (__libc_cleanup_pop_restore)
|
||||
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
|
||||
index 9bac6e3b76a20312..2680b55586e035fe 100644
|
||||
--- a/nptl/pthread_cancel.c
|
||||
+++ b/nptl/pthread_cancel.c
|
||||
@@ -43,18 +43,29 @@ sigcancel_handler (int sig, siginfo_t *si, void *ctx)
|
||||
|
||||
struct pthread *self = THREAD_SELF;
|
||||
|
||||
- int ch = atomic_load_relaxed (&self->cancelhandling);
|
||||
- /* Cancelation not enabled, not cancelled, or already exitting. */
|
||||
- if (self->cancelstate == PTHREAD_CANCEL_DISABLE
|
||||
- || (ch & CANCELED_BITMASK) == 0
|
||||
- || (ch & EXITING_BITMASK) != 0)
|
||||
- return;
|
||||
-
|
||||
- /* Set the return value. */
|
||||
- THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||
- /* Make sure asynchronous cancellation is still enabled. */
|
||||
- if (self->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||
- __do_cancel ();
|
||||
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||
+ while (1)
|
||||
+ {
|
||||
+ /* We are canceled now. When canceled by another thread this flag
|
||||
+ is already set but if the signal is directly send (internally or
|
||||
+ from another process) is has to be done here. */
|
||||
+ int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
|
||||
+
|
||||
+ if (oldval == newval || (oldval & EXITING_BITMASK) != 0)
|
||||
+ /* Already canceled or exiting. */
|
||||
+ break;
|
||||
+
|
||||
+ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||
+ &oldval, newval))
|
||||
+ {
|
||||
+ self->result = PTHREAD_CANCELED;
|
||||
+
|
||||
+ /* Make sure asynchronous cancellation is still enabled. */
|
||||
+ if ((oldval & CANCELTYPE_BITMASK) != 0)
|
||||
+ /* Run the registered destructors and terminate the thread. */
|
||||
+ __do_cancel ();
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
int
|
||||
@@ -93,29 +104,70 @@ __pthread_cancel (pthread_t th)
|
||||
}
|
||||
#endif
|
||||
|
||||
- int oldch = atomic_fetch_or_acquire (&pd->cancelhandling, CANCELED_BITMASK);
|
||||
- if ((oldch & CANCELED_BITMASK) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- if (pd == THREAD_SELF)
|
||||
+ /* Some syscalls are never restarted after being interrupted by a signal
|
||||
+ handler, regardless of the use of SA_RESTART (they always fail with
|
||||
+ EINTR). So pthread_cancel cannot send SIGCANCEL unless the cancellation
|
||||
+ is enabled and set as asynchronous (in this case the cancellation will
|
||||
+ be acted in the cancellation handler instead by the syscall wrapper).
|
||||
+ Otherwise the target thread is set as 'cancelling' (CANCELING_BITMASK)
|
||||
+ by atomically setting 'cancelhandling' and the cancelation will be acted
|
||||
+ upon on next cancellation entrypoing in the target thread.
|
||||
+
|
||||
+ It also requires to atomically check if cancellation is enabled and
|
||||
+ asynchronous, so both cancellation state and type are tracked on
|
||||
+ 'cancelhandling'. */
|
||||
+
|
||||
+ int result = 0;
|
||||
+ int oldval = atomic_load_relaxed (&pd->cancelhandling);
|
||||
+ int newval;
|
||||
+ do
|
||||
{
|
||||
- /* A single-threaded process should be able to kill itself, since there
|
||||
- is nothing in the POSIX specification that says that it cannot. So
|
||||
- we set multiple_threads to true so that cancellation points get
|
||||
- executed. */
|
||||
- THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
|
||||
+ newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
|
||||
+ if (oldval == newval)
|
||||
+ break;
|
||||
+
|
||||
+ /* If the cancellation is handled asynchronously just send a
|
||||
+ signal. We avoid this if possible since it's more
|
||||
+ expensive. */
|
||||
+ if (cancel_enabled_and_canceled_and_async (newval))
|
||||
+ {
|
||||
+ /* Mark the cancellation as "in progress". */
|
||||
+ int newval2 = oldval | CANCELING_BITMASK;
|
||||
+ if (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling,
|
||||
+ &oldval, newval2))
|
||||
+ continue;
|
||||
+
|
||||
+ if (pd == THREAD_SELF)
|
||||
+ /* This is not merely an optimization: An application may
|
||||
+ call pthread_cancel (pthread_self ()) without calling
|
||||
+ pthread_create, so the signal handler may not have been
|
||||
+ set up for a self-cancel. */
|
||||
+ {
|
||||
+ pd->result = PTHREAD_CANCELED;
|
||||
+ if ((newval & CANCELTYPE_BITMASK) != 0)
|
||||
+ __do_cancel ();
|
||||
+ }
|
||||
+ else
|
||||
+ /* The cancellation handler will take care of marking the
|
||||
+ thread as canceled. */
|
||||
+ result = __pthread_kill_internal (th, SIGCANCEL);
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* A single-threaded process should be able to kill itself, since
|
||||
+ there is nothing in the POSIX specification that says that it
|
||||
+ cannot. So we set multiple_threads to true so that cancellation
|
||||
+ points get executed. */
|
||||
+ THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
|
||||
#ifndef TLS_MULTIPLE_THREADS_IN_TCB
|
||||
__libc_multiple_threads = 1;
|
||||
#endif
|
||||
-
|
||||
- THREAD_SETMEM (pd, result, PTHREAD_CANCELED);
|
||||
- if (pd->cancelstate == PTHREAD_CANCEL_ENABLE
|
||||
- && pd->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||
- __do_cancel ();
|
||||
- return 0;
|
||||
}
|
||||
+ while (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling, &oldval,
|
||||
+ newval));
|
||||
|
||||
- return __pthread_kill_internal (th, SIGCANCEL);
|
||||
+ return result;
|
||||
}
|
||||
versioned_symbol (libc, __pthread_cancel, pthread_cancel, GLIBC_2_34);
|
||||
|
||||
diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c
|
||||
index 7303069316caef13..617056ef10671607 100644
|
||||
--- a/nptl/pthread_join_common.c
|
||||
+++ b/nptl/pthread_join_common.c
|
||||
@@ -57,12 +57,9 @@ __pthread_clockjoin_ex (pthread_t threadid, void **thread_return,
|
||||
if ((pd == self
|
||||
|| (self->joinid == pd
|
||||
&& (pd->cancelhandling
|
||||
- & (CANCELED_BITMASK | EXITING_BITMASK
|
||||
+ & (CANCELING_BITMASK | CANCELED_BITMASK | EXITING_BITMASK
|
||||
| TERMINATED_BITMASK)) == 0))
|
||||
- && !(self->cancelstate == PTHREAD_CANCEL_ENABLE
|
||||
- && (pd->cancelhandling & (CANCELED_BITMASK | EXITING_BITMASK
|
||||
- | TERMINATED_BITMASK))
|
||||
- == CANCELED_BITMASK))
|
||||
+ && !cancel_enabled_and_canceled (self->cancelhandling))
|
||||
/* This is a deadlock situation. The threads are waiting for each
|
||||
other to finish. Note that this is a "may" error. To be 100%
|
||||
sure we catch this error we would have to lock the data
|
||||
diff --git a/nptl/pthread_setcancelstate.c b/nptl/pthread_setcancelstate.c
|
||||
index 7e2b6e4974bd58bd..cb567be5926816f1 100644
|
||||
--- a/nptl/pthread_setcancelstate.c
|
||||
+++ b/nptl/pthread_setcancelstate.c
|
||||
@@ -31,9 +31,29 @@ __pthread_setcancelstate (int state, int *oldstate)
|
||||
|
||||
self = THREAD_SELF;
|
||||
|
||||
- if (oldstate != NULL)
|
||||
- *oldstate = self->cancelstate;
|
||||
- self->cancelstate = state;
|
||||
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||
+ while (1)
|
||||
+ {
|
||||
+ int newval = (state == PTHREAD_CANCEL_DISABLE
|
||||
+ ? oldval | CANCELSTATE_BITMASK
|
||||
+ : oldval & ~CANCELSTATE_BITMASK);
|
||||
+
|
||||
+ if (oldstate != NULL)
|
||||
+ *oldstate = ((oldval & CANCELSTATE_BITMASK)
|
||||
+ ? PTHREAD_CANCEL_DISABLE : PTHREAD_CANCEL_ENABLE);
|
||||
+
|
||||
+ if (oldval == newval)
|
||||
+ break;
|
||||
+
|
||||
+ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||
+ &oldval, newval))
|
||||
+ {
|
||||
+ if (cancel_enabled_and_canceled_and_async (newval))
|
||||
+ __do_cancel ();
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/nptl/pthread_setcanceltype.c b/nptl/pthread_setcanceltype.c
|
||||
index e7b24ae733dcc0f2..e08ff7b141f904f1 100644
|
||||
--- a/nptl/pthread_setcanceltype.c
|
||||
+++ b/nptl/pthread_setcanceltype.c
|
||||
@@ -29,11 +29,32 @@ __pthread_setcanceltype (int type, int *oldtype)
|
||||
|
||||
volatile struct pthread *self = THREAD_SELF;
|
||||
|
||||
- if (oldtype != NULL)
|
||||
- *oldtype = self->canceltype;
|
||||
- self->canceltype = type;
|
||||
- if (type == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||
- __pthread_testcancel ();
|
||||
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||
+ while (1)
|
||||
+ {
|
||||
+ int newval = (type == PTHREAD_CANCEL_ASYNCHRONOUS
|
||||
+ ? oldval | CANCELTYPE_BITMASK
|
||||
+ : oldval & ~CANCELTYPE_BITMASK);
|
||||
+
|
||||
+ if (oldtype != NULL)
|
||||
+ *oldtype = ((oldval & CANCELTYPE_BITMASK)
|
||||
+ ? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED);
|
||||
+
|
||||
+ if (oldval == newval)
|
||||
+ break;
|
||||
+
|
||||
+ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||
+ &oldval, newval))
|
||||
+ {
|
||||
+ if (cancel_enabled_and_canceled_and_async (newval))
|
||||
+ {
|
||||
+ THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||
+ __do_cancel ();
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/nptl/pthread_testcancel.c b/nptl/pthread_testcancel.c
|
||||
index 31185d89f2ab84c6..25230215fd607e8b 100644
|
||||
--- a/nptl/pthread_testcancel.c
|
||||
+++ b/nptl/pthread_testcancel.c
|
||||
@@ -24,13 +24,10 @@ void
|
||||
___pthread_testcancel (void)
|
||||
{
|
||||
struct pthread *self = THREAD_SELF;
|
||||
- int cancelhandling = THREAD_GETMEM (self, cancelhandling);
|
||||
- if (self->cancelstate == PTHREAD_CANCEL_ENABLE
|
||||
- && (cancelhandling & CANCELED_BITMASK)
|
||||
- && !(cancelhandling & EXITING_BITMASK)
|
||||
- && !(cancelhandling & TERMINATED_BITMASK))
|
||||
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||
+ if (cancel_enabled_and_canceled (cancelhandling))
|
||||
{
|
||||
- THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||
+ self->result = PTHREAD_CANCELED;
|
||||
__do_cancel ();
|
||||
}
|
||||
}
|
||||
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
index b39dfbff2c6678d5..23aa4cfc0b784dfc 100644
|
||||
--- a/sysdeps/nptl/dl-tls_init_tp.c
|
||||
+++ b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
@@ -107,7 +107,4 @@ __tls_init_tp (void)
|
||||
It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
|
||||
purposes this is good enough. */
|
||||
THREAD_SETMEM (pd, stackblock_size, (size_t) __libc_stack_end);
|
||||
-
|
||||
- THREAD_SETMEM (pd, cancelstate, PTHREAD_CANCEL_ENABLE);
|
||||
- THREAD_SETMEM (pd, canceltype, PTHREAD_CANCEL_DEFERRED);
|
||||
}
|
||||
diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h
|
||||
index 374657a2fd0ee19a..b968afc4c6b61b92 100644
|
||||
--- a/sysdeps/nptl/pthreadP.h
|
||||
+++ b/sysdeps/nptl/pthreadP.h
|
||||
@@ -276,7 +276,7 @@ __do_cancel (void)
|
||||
struct pthread *self = THREAD_SELF;
|
||||
|
||||
/* Make sure we get no more cancellations. */
|
||||
- THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
|
||||
+ atomic_bit_set (&self->cancelhandling, EXITING_BIT);
|
||||
|
||||
__pthread_unwind ((__pthread_unwind_buf_t *)
|
||||
THREAD_GETMEM (self, cleanup_jmp_buf));
|
||||
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
|
||||
index c65710169697ad95..00419c4d199df912 100644
|
||||
--- a/sysdeps/pthread/Makefile
|
||||
+++ b/sysdeps/pthread/Makefile
|
||||
@@ -69,6 +69,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
|
||||
tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 tst-cancel16 \
|
||||
tst-cancel18 tst-cancel19 tst-cancel20 tst-cancel21 \
|
||||
tst-cancel22 tst-cancel23 tst-cancel26 tst-cancel27 tst-cancel28 \
|
||||
+ tst-cancel29 \
|
||||
tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 \
|
||||
tst-clock1 \
|
||||
tst-cond-except \
|
||||
diff --git a/sysdeps/pthread/tst-cancel29.c b/sysdeps/pthread/tst-cancel29.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4f0d99e002883be4
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/pthread/tst-cancel29.c
|
||||
@@ -0,0 +1,207 @@
|
||||
+/* Check if a thread that disables cancellation and which call functions
|
||||
+ that might be interrupted by a signal do not see the internal SIGCANCEL.
|
||||
+
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <errno.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <poll.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <signal.h>
|
||||
+#include <stdio.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+/* On Linux some interfaces are never restarted after being interrupted by
|
||||
+ a signal handler, regardless of the use of SA_RESTART. It means that
|
||||
+ if asynchronous cancellation is not enabled, the pthread_cancel can not
|
||||
+ set the internal SIGCANCEL otherwise the interface might see a spurious
|
||||
+ EINTR failure. */
|
||||
+
|
||||
+static pthread_barrier_t b;
|
||||
+
|
||||
+/* Cleanup handling test. */
|
||||
+static int cl_called;
|
||||
+static void
|
||||
+cl (void *arg)
|
||||
+{
|
||||
+ ++cl_called;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+tf_sigtimedwait (void *arg)
|
||||
+{
|
||||
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||
+ xpthread_barrier_wait (&b);
|
||||
+
|
||||
+ int r;
|
||||
+ pthread_cleanup_push (cl, NULL);
|
||||
+
|
||||
+ sigset_t mask;
|
||||
+ sigemptyset (&mask);
|
||||
+ r = sigtimedwait (&mask, NULL, &(struct timespec) { 0, 250000000 });
|
||||
+ if (r != -1)
|
||||
+ return (void*) -1;
|
||||
+ if (errno != EAGAIN)
|
||||
+ return (void*) -2;
|
||||
+
|
||||
+ pthread_cleanup_pop (0);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+tf_poll (void *arg)
|
||||
+{
|
||||
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||
+ xpthread_barrier_wait (&b);
|
||||
+
|
||||
+ int r;
|
||||
+ pthread_cleanup_push (cl, NULL);
|
||||
+
|
||||
+ r = poll (NULL, 0, 250);
|
||||
+ if (r != 0)
|
||||
+ return (void*) -1;
|
||||
+
|
||||
+ pthread_cleanup_pop (0);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+tf_ppoll (void *arg)
|
||||
+{
|
||||
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||
+
|
||||
+ xpthread_barrier_wait (&b);
|
||||
+
|
||||
+ int r;
|
||||
+ pthread_cleanup_push (cl, NULL);
|
||||
+
|
||||
+ r = ppoll (NULL, 0, &(struct timespec) { 0, 250000000 }, NULL);
|
||||
+ if (r != 0)
|
||||
+ return (void*) -1;
|
||||
+
|
||||
+ pthread_cleanup_pop (0);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+tf_select (void *arg)
|
||||
+{
|
||||
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||
+ xpthread_barrier_wait (&b);
|
||||
+
|
||||
+ int r;
|
||||
+ pthread_cleanup_push (cl, NULL);
|
||||
+
|
||||
+ r = select (0, NULL, NULL, NULL, &(struct timeval) { 0, 250000 });
|
||||
+ if (r != 0)
|
||||
+ return (void*) -1;
|
||||
+
|
||||
+ pthread_cleanup_pop (0);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+tf_pselect (void *arg)
|
||||
+{
|
||||
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||
+ xpthread_barrier_wait (&b);
|
||||
+
|
||||
+ int r;
|
||||
+ pthread_cleanup_push (cl, NULL);
|
||||
+
|
||||
+ r = pselect (0, NULL, NULL, NULL, &(struct timespec) { 0, 250000000 }, NULL);
|
||||
+ if (r != 0)
|
||||
+ return (void*) -1;
|
||||
+
|
||||
+ pthread_cleanup_pop (0);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+tf_clock_nanosleep (void *arg)
|
||||
+{
|
||||
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||
+ xpthread_barrier_wait (&b);
|
||||
+
|
||||
+ int r;
|
||||
+ pthread_cleanup_push (cl, NULL);
|
||||
+
|
||||
+ r = clock_nanosleep (CLOCK_REALTIME, 0, &(struct timespec) { 0, 250000000 },
|
||||
+ NULL);
|
||||
+ if (r != 0)
|
||||
+ return (void*) -1;
|
||||
+
|
||||
+ pthread_cleanup_pop (0);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+struct cancel_test_t
|
||||
+{
|
||||
+ const char *name;
|
||||
+ void * (*cf) (void *);
|
||||
+} tests[] =
|
||||
+{
|
||||
+ { "sigtimedwait", tf_sigtimedwait, },
|
||||
+ { "poll", tf_poll, },
|
||||
+ { "ppoll", tf_ppoll, },
|
||||
+ { "select", tf_select, },
|
||||
+ { "pselect", tf_pselect , },
|
||||
+ { "clock_nanosleep", tf_clock_nanosleep, },
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ for (int i = 0; i < array_length (tests); i++)
|
||||
+ {
|
||||
+ xpthread_barrier_init (&b, NULL, 2);
|
||||
+
|
||||
+ cl_called = 0;
|
||||
+
|
||||
+ pthread_t th = xpthread_create (NULL, tests[i].cf, NULL);
|
||||
+
|
||||
+ xpthread_barrier_wait (&b);
|
||||
+
|
||||
+ struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
|
||||
+ while (nanosleep (&ts, &ts) != 0)
|
||||
+ continue;
|
||||
+
|
||||
+ xpthread_cancel (th);
|
||||
+
|
||||
+ void *status = xpthread_join (th);
|
||||
+ if (status != NULL)
|
||||
+ printf ("test '%s' failed: %" PRIdPTR "\n", tests[i].name,
|
||||
+ (intptr_t) status);
|
||||
+ TEST_VERIFY (status == NULL);
|
||||
+
|
||||
+ xpthread_barrier_destroy (&b);
|
||||
+
|
||||
+ TEST_COMPARE (cl_called, 0);
|
||||
+
|
||||
+ printf ("in-time cancel test of '%s' successful\n", tests[i].name);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
23
SOURCES/glibc-upstream-2.34-164.patch
Normal file
23
SOURCES/glibc-upstream-2.34-164.patch
Normal file
@ -0,0 +1,23 @@
|
||||
commit 5d8c7776343b3f1b96ef7777e4504378f23c041a
|
||||
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
|
||||
Date: Tue Apr 12 22:14:34 2022 +0200
|
||||
|
||||
hurd: Fix arbitrary error code
|
||||
|
||||
ELIBBAD is Linux-specific.
|
||||
|
||||
(cherry picked from commit 67ab66541dc1164540abda284645e38be90b5119)
|
||||
|
||||
diff --git a/nss/nss_test_errno.c b/nss/nss_test_errno.c
|
||||
index 680f8a07b97fe263..59a5c717bebd296f 100644
|
||||
--- a/nss/nss_test_errno.c
|
||||
+++ b/nss/nss_test_errno.c
|
||||
@@ -28,7 +28,7 @@ static void __attribute__ ((constructor))
|
||||
init (void)
|
||||
{
|
||||
/* An arbitrary error code which is otherwise not used. */
|
||||
- errno = ELIBBAD;
|
||||
+ errno = -1009;
|
||||
}
|
||||
|
||||
/* Lookup functions for pwd follow that do not return any data. */
|
104
SOURCES/glibc-upstream-2.34-165.patch
Normal file
104
SOURCES/glibc-upstream-2.34-165.patch
Normal file
@ -0,0 +1,104 @@
|
||||
commit b87b697f15d6bf7e576a2eeadc1f740172f9d013
|
||||
Author: =Joshua Kinard <kumba@gentoo.org>
|
||||
Date: Mon Apr 18 09:55:08 2022 -0300
|
||||
|
||||
mips: Fix mips64n32 64 bit time_t stat support (BZ#29069)
|
||||
|
||||
Add missing support initially added by 4e8521333bea6e89fcef1020
|
||||
(which missed n32 stat).
|
||||
|
||||
(cherry picked from commit 78fb88827362fbd2cc8aa32892ae5b015106e25c)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
|
||||
index ab9f474cbc271b7c..ed5b1bc00ba52406 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
|
||||
@@ -131,27 +131,30 @@ struct stat64
|
||||
|
||||
struct stat
|
||||
{
|
||||
+# ifdef __USE_TIME_BITS64
|
||||
+# include <bits/struct_stat_time64_helper.h>
|
||||
+# else
|
||||
__dev_t st_dev;
|
||||
int st_pad1[3]; /* Reserved for st_dev expansion */
|
||||
-# ifndef __USE_FILE_OFFSET64
|
||||
+# ifndef __USE_FILE_OFFSET64
|
||||
__ino_t st_ino;
|
||||
-# else
|
||||
+# else
|
||||
__ino64_t st_ino;
|
||||
-# endif
|
||||
+# endif
|
||||
__mode_t st_mode;
|
||||
__nlink_t st_nlink;
|
||||
__uid_t st_uid;
|
||||
__gid_t st_gid;
|
||||
__dev_t st_rdev;
|
||||
-# if !defined __USE_FILE_OFFSET64
|
||||
+# if !defined __USE_FILE_OFFSET64
|
||||
unsigned int st_pad2[2]; /* Reserved for st_rdev expansion */
|
||||
__off_t st_size;
|
||||
int st_pad3;
|
||||
-# else
|
||||
+# else
|
||||
unsigned int st_pad2[3]; /* Reserved for st_rdev expansion */
|
||||
__off64_t st_size;
|
||||
-# endif
|
||||
-# ifdef __USE_XOPEN2K8
|
||||
+# endif
|
||||
+# ifdef __USE_XOPEN2K8
|
||||
/* Nanosecond resolution timestamps are stored in a format
|
||||
equivalent to 'struct timespec'. This is the type used
|
||||
whenever possible but the Unix namespace rules do not allow the
|
||||
@@ -161,30 +164,34 @@ struct stat
|
||||
struct timespec st_atim; /* Time of last access. */
|
||||
struct timespec st_mtim; /* Time of last modification. */
|
||||
struct timespec st_ctim; /* Time of last status change. */
|
||||
-# define st_atime st_atim.tv_sec /* Backward compatibility. */
|
||||
-# define st_mtime st_mtim.tv_sec
|
||||
-# define st_ctime st_ctim.tv_sec
|
||||
-# else
|
||||
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
|
||||
+# define st_mtime st_mtim.tv_sec
|
||||
+# define st_ctime st_ctim.tv_sec
|
||||
+# else
|
||||
__time_t st_atime; /* Time of last access. */
|
||||
unsigned long int st_atimensec; /* Nscecs of last access. */
|
||||
__time_t st_mtime; /* Time of last modification. */
|
||||
unsigned long int st_mtimensec; /* Nsecs of last modification. */
|
||||
__time_t st_ctime; /* Time of last status change. */
|
||||
unsigned long int st_ctimensec; /* Nsecs of last status change. */
|
||||
-# endif
|
||||
+# endif
|
||||
__blksize_t st_blksize;
|
||||
unsigned int st_pad4;
|
||||
-# ifndef __USE_FILE_OFFSET64
|
||||
+# ifndef __USE_FILE_OFFSET64
|
||||
__blkcnt_t st_blocks;
|
||||
-# else
|
||||
+# else
|
||||
__blkcnt64_t st_blocks;
|
||||
-# endif
|
||||
+# endif
|
||||
int st_pad5[14];
|
||||
+# endif
|
||||
};
|
||||
|
||||
#ifdef __USE_LARGEFILE64
|
||||
struct stat64
|
||||
{
|
||||
+# ifdef __USE_TIME_BITS64
|
||||
+# include <bits/struct_stat_time64_helper.h>
|
||||
+# else
|
||||
__dev_t st_dev;
|
||||
unsigned int st_pad1[3]; /* Reserved for st_dev expansion */
|
||||
__ino64_t st_ino;
|
||||
@@ -217,6 +224,7 @@ struct stat64
|
||||
unsigned int st_pad3;
|
||||
__blkcnt64_t st_blocks;
|
||||
int st_pad4[14];
|
||||
+# endif /* __USE_TIME_BITS64 */
|
||||
};
|
||||
#endif
|
||||
|
35
SOURCES/glibc-upstream-2.34-166.patch
Normal file
35
SOURCES/glibc-upstream-2.34-166.patch
Normal file
@ -0,0 +1,35 @@
|
||||
commit 71326f1f2fd09dafb9c34404765fb88129e94237
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Apr 20 12:01:43 2022 -0300
|
||||
|
||||
nptl: Fix pthread_cancel cancelhandling atomic operations
|
||||
|
||||
The 404656009b reversion did not setup the atomic loop to set the
|
||||
cancel bits correctly. The fix is essentially what pthread_cancel
|
||||
did prior 26cfbb7162ad.
|
||||
|
||||
Checked on x86_64-linux-gnu and aarch64-linux-gnu.
|
||||
|
||||
(cherry picked from commit 62be9681677e7ce820db721c126909979382d379)
|
||||
|
||||
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
|
||||
index 2680b55586e035fe..64fd183fde59907b 100644
|
||||
--- a/nptl/pthread_cancel.c
|
||||
+++ b/nptl/pthread_cancel.c
|
||||
@@ -122,6 +122,7 @@ __pthread_cancel (pthread_t th)
|
||||
int newval;
|
||||
do
|
||||
{
|
||||
+ again:
|
||||
newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
|
||||
if (oldval == newval)
|
||||
break;
|
||||
@@ -135,7 +136,7 @@ __pthread_cancel (pthread_t th)
|
||||
int newval2 = oldval | CANCELING_BITMASK;
|
||||
if (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling,
|
||||
&oldval, newval2))
|
||||
- continue;
|
||||
+ goto again;
|
||||
|
||||
if (pd == THREAD_SELF)
|
||||
/* This is not merely an optimization: An application may
|
1446
SOURCES/glibc-upstream-2.34-167.patch
Normal file
1446
SOURCES/glibc-upstream-2.34-167.patch
Normal file
File diff suppressed because it is too large
Load Diff
407
SOURCES/glibc-upstream-2.34-168.patch
Normal file
407
SOURCES/glibc-upstream-2.34-168.patch
Normal file
@ -0,0 +1,407 @@
|
||||
commit f0c71b34f96c816292c49122d50da3a511b67bf2
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Apr 11 11:30:31 2022 +0200
|
||||
|
||||
Default to --with-default-link=no (bug 25812)
|
||||
|
||||
This is necessary to place the libio vtables into the RELRO segment.
|
||||
New tests elf/tst-relro-ldso and elf/tst-relro-libc are added to
|
||||
verify that this is what actually happens.
|
||||
|
||||
The new tests fail on ia64 due to lack of (default) RELRO support
|
||||
inbutils, so they are XFAILed there.
|
||||
|
||||
(cherry picked from commit 198abcbb94618730dae1b3f4393efaa49e0ec8c7)
|
||||
|
||||
diff --git a/INSTALL b/INSTALL
|
||||
index d8d4e9f155f56616..60d01568d77645c7 100644
|
||||
--- a/INSTALL
|
||||
+++ b/INSTALL
|
||||
@@ -90,6 +90,12 @@ if 'CFLAGS' is specified it must enable optimization. For example:
|
||||
library will still be usable, but functionality may be lost--for
|
||||
example, you can't build a shared libc with old binutils.
|
||||
|
||||
+'--with-default-link=FLAG'
|
||||
+ With '--with-default-link=yes', the build system does not use a
|
||||
+ custom linker script for linking shared objects. The default for
|
||||
+ FLAG is the opposite, 'no', because the custom linker script is
|
||||
+ needed for full RELRO protection.
|
||||
+
|
||||
'--with-nonshared-cflags=CFLAGS'
|
||||
Use additional compiler flags CFLAGS to build the parts of the
|
||||
library which are always statically linked into applications and
|
||||
diff --git a/configure b/configure
|
||||
index 03f4e59e754b5463..34c64f8de44e3086 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -3373,7 +3373,7 @@ fi
|
||||
if test "${with_default_link+set}" = set; then :
|
||||
withval=$with_default_link; use_default_link=$withval
|
||||
else
|
||||
- use_default_link=default
|
||||
+ use_default_link=no
|
||||
fi
|
||||
|
||||
|
||||
@@ -6085,69 +6085,6 @@ fi
|
||||
$as_echo "$libc_cv_hashstyle" >&6; }
|
||||
|
||||
|
||||
-# The linker's default -shared behavior is good enough if it
|
||||
-# does these things that our custom linker scripts ensure that
|
||||
-# all allocated NOTE sections come first.
|
||||
-if test "$use_default_link" = default; then
|
||||
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sufficient default -shared layout" >&5
|
||||
-$as_echo_n "checking for sufficient default -shared layout... " >&6; }
|
||||
-if ${libc_cv_use_default_link+:} false; then :
|
||||
- $as_echo_n "(cached) " >&6
|
||||
-else
|
||||
- libc_cv_use_default_link=no
|
||||
- cat > conftest.s <<\EOF
|
||||
- .section .note.a,"a",%note
|
||||
- .balign 4
|
||||
- .long 4,4,9
|
||||
- .string "GNU"
|
||||
- .string "foo"
|
||||
- .section .note.b,"a",%note
|
||||
- .balign 4
|
||||
- .long 4,4,9
|
||||
- .string "GNU"
|
||||
- .string "bar"
|
||||
-EOF
|
||||
- if { ac_try=' ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&5'
|
||||
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||
- (eval $ac_try) 2>&5
|
||||
- ac_status=$?
|
||||
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
- test $ac_status = 0; }; } &&
|
||||
- ac_try=`$READELF -S conftest.so | sed -n \
|
||||
- '${x;p;}
|
||||
- s/^ *\[ *[1-9][0-9]*\] *\([^ ][^ ]*\) *\([^ ][^ ]*\) .*$/\2 \1/
|
||||
- t a
|
||||
- b
|
||||
- : a
|
||||
- H'`
|
||||
- then
|
||||
- libc_seen_a=no libc_seen_b=no
|
||||
- set -- $ac_try
|
||||
- while test $# -ge 2 -a "$1" = NOTE; do
|
||||
- case "$2" in
|
||||
- .note.a) libc_seen_a=yes ;;
|
||||
- .note.b) libc_seen_b=yes ;;
|
||||
- esac
|
||||
- shift 2
|
||||
- done
|
||||
- case "$libc_seen_a$libc_seen_b" in
|
||||
- yesyes)
|
||||
- libc_cv_use_default_link=yes
|
||||
- ;;
|
||||
- *)
|
||||
- echo >&5 "\
|
||||
-$libc_seen_a$libc_seen_b from:
|
||||
-$ac_try"
|
||||
- ;;
|
||||
- esac
|
||||
- fi
|
||||
- rm -f conftest*
|
||||
-fi
|
||||
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_use_default_link" >&5
|
||||
-$as_echo "$libc_cv_use_default_link" >&6; }
|
||||
- use_default_link=$libc_cv_use_default_link
|
||||
-fi
|
||||
-
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_DAT reloc" >&5
|
||||
$as_echo_n "checking for GLOB_DAT reloc... " >&6; }
|
||||
if ${libc_cv_has_glob_dat+:} false; then :
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index eb9431875fae1b0e..2c69af0807266e7e 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -153,7 +153,7 @@ AC_ARG_WITH([default-link],
|
||||
AS_HELP_STRING([--with-default-link],
|
||||
[do not use explicit linker scripts]),
|
||||
[use_default_link=$withval],
|
||||
- [use_default_link=default])
|
||||
+ [use_default_link=no])
|
||||
|
||||
dnl Additional build flags injection.
|
||||
AC_ARG_WITH([nonshared-cflags],
|
||||
@@ -1378,59 +1378,6 @@ fi
|
||||
rm -f conftest*])
|
||||
AC_SUBST(libc_cv_hashstyle)
|
||||
|
||||
-# The linker's default -shared behavior is good enough if it
|
||||
-# does these things that our custom linker scripts ensure that
|
||||
-# all allocated NOTE sections come first.
|
||||
-if test "$use_default_link" = default; then
|
||||
- AC_CACHE_CHECK([for sufficient default -shared layout],
|
||||
- libc_cv_use_default_link, [dnl
|
||||
- libc_cv_use_default_link=no
|
||||
- cat > conftest.s <<\EOF
|
||||
- .section .note.a,"a",%note
|
||||
- .balign 4
|
||||
- .long 4,4,9
|
||||
- .string "GNU"
|
||||
- .string "foo"
|
||||
- .section .note.b,"a",%note
|
||||
- .balign 4
|
||||
- .long 4,4,9
|
||||
- .string "GNU"
|
||||
- .string "bar"
|
||||
-EOF
|
||||
- if AC_TRY_COMMAND([dnl
|
||||
- ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&AS_MESSAGE_LOG_FD]) &&
|
||||
- ac_try=`$READELF -S conftest.so | sed -n \
|
||||
- ['${x;p;}
|
||||
- s/^ *\[ *[1-9][0-9]*\] *\([^ ][^ ]*\) *\([^ ][^ ]*\) .*$/\2 \1/
|
||||
- t a
|
||||
- b
|
||||
- : a
|
||||
- H']`
|
||||
- then
|
||||
- libc_seen_a=no libc_seen_b=no
|
||||
- set -- $ac_try
|
||||
- while test $# -ge 2 -a "$1" = NOTE; do
|
||||
- case "$2" in
|
||||
- .note.a) libc_seen_a=yes ;;
|
||||
- .note.b) libc_seen_b=yes ;;
|
||||
- esac
|
||||
- shift 2
|
||||
- done
|
||||
- case "$libc_seen_a$libc_seen_b" in
|
||||
- yesyes)
|
||||
- libc_cv_use_default_link=yes
|
||||
- ;;
|
||||
- *)
|
||||
- echo >&AS_MESSAGE_LOG_FD "\
|
||||
-$libc_seen_a$libc_seen_b from:
|
||||
-$ac_try"
|
||||
- ;;
|
||||
- esac
|
||||
- fi
|
||||
- rm -f conftest*])
|
||||
- use_default_link=$libc_cv_use_default_link
|
||||
-fi
|
||||
-
|
||||
AC_CACHE_CHECK(for GLOB_DAT reloc,
|
||||
libc_cv_has_glob_dat, [dnl
|
||||
cat > conftest.c <<EOF
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 8afbe3f6ab259331..fec6e23b5b625e3b 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -504,6 +504,40 @@ tests-execstack-yes = \
|
||||
# tests-execstack-yes
|
||||
endif
|
||||
endif
|
||||
+
|
||||
+tests-special += $(objpfx)tst-relro-ldso.out $(objpfx)tst-relro-libc.out
|
||||
+$(objpfx)tst-relro-ldso.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \
|
||||
+ $(objpfx)ld.so
|
||||
+ $(PYTHON) tst-relro-symbols.py $(objpfx)ld.so \
|
||||
+ --required=_rtld_global_ro \
|
||||
+ > $@ 2>&1; $(evaluate-test)
|
||||
+# The optional symbols are present in libc only if the architecture has
|
||||
+# the GLIBC_2.0 symbol set in libc.
|
||||
+$(objpfx)tst-relro-libc.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \
|
||||
+ $(common-objpfx)libc.so
|
||||
+ $(PYTHON) tst-relro-symbols.py $(common-objpfx)libc.so \
|
||||
+ --required=_IO_cookie_jumps \
|
||||
+ --required=_IO_file_jumps \
|
||||
+ --required=_IO_file_jumps_maybe_mmap \
|
||||
+ --required=_IO_file_jumps_mmap \
|
||||
+ --required=_IO_helper_jumps \
|
||||
+ --required=_IO_mem_jumps \
|
||||
+ --required=_IO_obstack_jumps \
|
||||
+ --required=_IO_proc_jumps \
|
||||
+ --required=_IO_str_chk_jumps \
|
||||
+ --required=_IO_str_jumps \
|
||||
+ --required=_IO_strn_jumps \
|
||||
+ --required=_IO_wfile_jumps \
|
||||
+ --required=_IO_wfile_jumps_maybe_mmap \
|
||||
+ --required=_IO_wfile_jumps_mmap \
|
||||
+ --required=_IO_wmem_jumps \
|
||||
+ --required=_IO_wstr_jumps \
|
||||
+ --required=_IO_wstrn_jumps \
|
||||
+ --optional=_IO_old_cookie_jumps \
|
||||
+ --optional=_IO_old_file_jumps \
|
||||
+ --optional=_IO_old_proc_jumps \
|
||||
+ > $@ 2>&1; $(evaluate-test)
|
||||
+
|
||||
tests += $(tests-execstack-$(have-z-execstack))
|
||||
ifeq ($(run-built-tests),yes)
|
||||
tests-special += \
|
||||
diff --git a/elf/tst-relro-symbols.py b/elf/tst-relro-symbols.py
|
||||
new file mode 100644
|
||||
index 0000000000000000..368ea3349f86bd81
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-relro-symbols.py
|
||||
@@ -0,0 +1,137 @@
|
||||
+#!/usr/bin/python3
|
||||
+# Verify that certain symbols are covered by RELRO.
|
||||
+# Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+# This file is part of the GNU C Library.
|
||||
+#
|
||||
+# The GNU C Library is free software; you can redistribute it and/or
|
||||
+# modify it under the terms of the GNU Lesser General Public
|
||||
+# License as published by the Free Software Foundation; either
|
||||
+# version 2.1 of the License, or (at your option) any later version.
|
||||
+#
|
||||
+# The GNU C Library is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+# Lesser General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU Lesser General Public
|
||||
+# License along with the GNU C Library; if not, see
|
||||
+# <https://www.gnu.org/licenses/>.
|
||||
+
|
||||
+"""Analyze a (shared) object to verify that certain symbols are
|
||||
+present and covered by the PT_GNU_RELRO segment.
|
||||
+
|
||||
+"""
|
||||
+
|
||||
+import argparse
|
||||
+import os.path
|
||||
+import sys
|
||||
+
|
||||
+# Make available glibc Python modules.
|
||||
+sys.path.append(os.path.join(
|
||||
+ os.path.dirname(os.path.realpath(__file__)), os.path.pardir, 'scripts'))
|
||||
+
|
||||
+import glibcelf
|
||||
+
|
||||
+def find_relro(path: str, img: glibcelf.Image) -> (int, int):
|
||||
+ """Discover the address range of the PT_GNU_RELRO segment."""
|
||||
+ for phdr in img.phdrs():
|
||||
+ if phdr.p_type == glibcelf.Pt.PT_GNU_RELRO:
|
||||
+ # The computation is not entirely accurate because
|
||||
+ # _dl_protect_relro in elf/dl-reloc.c rounds both the
|
||||
+ # start end and downwards using the run-time page size.
|
||||
+ return phdr.p_vaddr, phdr.p_vaddr + phdr.p_memsz
|
||||
+ sys.stdout.write('{}: error: no PT_GNU_RELRO segment\n'.format(path))
|
||||
+ sys.exit(1)
|
||||
+
|
||||
+def check_in_relro(kind, relro_begin, relro_end, name, start, size, error):
|
||||
+ """Check if a section or symbol falls within in the RELRO segment."""
|
||||
+ end = start + size - 1
|
||||
+ if not (relro_begin <= start < end < relro_end):
|
||||
+ error(
|
||||
+ '{} {!r} of size {} at 0x{:x} is not in RELRO range [0x{:x}, 0x{:x})'.format(
|
||||
+ kind, name.decode('UTF-8'), start, size,
|
||||
+ relro_begin, relro_end))
|
||||
+
|
||||
+def get_parser():
|
||||
+ """Return an argument parser for this script."""
|
||||
+ parser = argparse.ArgumentParser(description=__doc__)
|
||||
+ parser.add_argument('object', help='path to object file to check')
|
||||
+ parser.add_argument('--required', metavar='NAME', default=(),
|
||||
+ help='required symbol names', nargs='*')
|
||||
+ parser.add_argument('--optional', metavar='NAME', default=(),
|
||||
+ help='required symbol names', nargs='*')
|
||||
+ return parser
|
||||
+
|
||||
+def main(argv):
|
||||
+ """The main entry point."""
|
||||
+ parser = get_parser()
|
||||
+ opts = parser.parse_args(argv)
|
||||
+ img = glibcelf.Image.readfile(opts.object)
|
||||
+
|
||||
+ required_symbols = frozenset([sym.encode('UTF-8')
|
||||
+ for sym in opts.required])
|
||||
+ optional_symbols = frozenset([sym.encode('UTF-8')
|
||||
+ for sym in opts.optional])
|
||||
+ check_symbols = required_symbols | optional_symbols
|
||||
+
|
||||
+ # Tracks the symbols in check_symbols that have been found.
|
||||
+ symbols_found = set()
|
||||
+
|
||||
+ # Discover the extent of the RELRO segment.
|
||||
+ relro_begin, relro_end = find_relro(opts.object, img)
|
||||
+ symbol_table_found = False
|
||||
+
|
||||
+ errors = False
|
||||
+ def error(msg: str) -> None:
|
||||
+ """Record an error condition and write a message to standard output."""
|
||||
+ nonlocal errors
|
||||
+ errors = True
|
||||
+ sys.stdout.write('{}: error: {}\n'.format(opts.object, msg))
|
||||
+
|
||||
+ # Iterate over section headers to find the symbol table.
|
||||
+ for shdr in img.shdrs():
|
||||
+ if shdr.sh_type == glibcelf.Sht.SHT_SYMTAB:
|
||||
+ symbol_table_found = True
|
||||
+ for sym in img.syms(shdr):
|
||||
+ if sym.st_name in check_symbols:
|
||||
+ symbols_found.add(sym.st_name)
|
||||
+
|
||||
+ # Validate symbol type, section, and size.
|
||||
+ if sym.st_info.type != glibcelf.Stt.STT_OBJECT:
|
||||
+ error('symbol {!r} has wrong type {}'.format(
|
||||
+ sym.st_name.decode('UTF-8'), sym.st_info.type))
|
||||
+ if sym.st_shndx in glibcelf.Shn:
|
||||
+ error('symbol {!r} has reserved section {}'.format(
|
||||
+ sym.st_name.decode('UTF-8'), sym.st_shndx))
|
||||
+ continue
|
||||
+ if sym.st_size == 0:
|
||||
+ error('symbol {!r} has size zero'.format(
|
||||
+ sym.st_name.decode('UTF-8')))
|
||||
+ continue
|
||||
+
|
||||
+ check_in_relro('symbol', relro_begin, relro_end,
|
||||
+ sym.st_name, sym.st_value, sym.st_size,
|
||||
+ error)
|
||||
+ continue # SHT_SYMTAB
|
||||
+ if shdr.sh_name == b'.data.rel.ro' \
|
||||
+ or shdr.sh_name.startswith(b'.data.rel.ro.'):
|
||||
+ check_in_relro('section', relro_begin, relro_end,
|
||||
+ shdr.sh_name, shdr.sh_addr, shdr.sh_size,
|
||||
+ error)
|
||||
+ continue
|
||||
+
|
||||
+ if required_symbols - symbols_found:
|
||||
+ for sym in sorted(required_symbols - symbols_found):
|
||||
+ error('symbol {!r} not found'.format(sym.decode('UTF-8')))
|
||||
+
|
||||
+ if errors:
|
||||
+ sys.exit(1)
|
||||
+
|
||||
+ if not symbol_table_found:
|
||||
+ sys.stdout.write(
|
||||
+ '{}: warning: no symbol table found (stripped object)\n'.format(
|
||||
+ opts.object))
|
||||
+ sys.exit(77)
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ main(sys.argv[1:])
|
||||
diff --git a/manual/install.texi b/manual/install.texi
|
||||
index 816b77a0a25a88a7..36a5af62bc5722b0 100644
|
||||
--- a/manual/install.texi
|
||||
+++ b/manual/install.texi
|
||||
@@ -117,6 +117,12 @@ problem and suppress these constructs, so that the library will still be
|
||||
usable, but functionality may be lost---for example, you can't build a
|
||||
shared libc with old binutils.
|
||||
|
||||
+@item --with-default-link=@var{FLAG}
|
||||
+With @code{--with-default-link=yes}, the build system does not use a
|
||||
+custom linker script for linking shared objects. The default for
|
||||
+@var{FLAG} is the opposite, @samp{no}, because the custom linker script
|
||||
+is needed for full RELRO protection.
|
||||
+
|
||||
@item --with-nonshared-cflags=@var{cflags}
|
||||
Use additional compiler flags @var{cflags} to build the parts of the
|
||||
library which are always statically linked into applications and
|
||||
diff --git a/sysdeps/unix/sysv/linux/ia64/Makefile b/sysdeps/unix/sysv/linux/ia64/Makefile
|
||||
index da85ba43e2d0ddef..c5cc41b3677d4a2a 100644
|
||||
--- a/sysdeps/unix/sysv/linux/ia64/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/ia64/Makefile
|
||||
@@ -1,3 +1,9 @@
|
||||
+ifeq ($(subdir),elf)
|
||||
+# ia64 does not support PT_GNU_RELRO.
|
||||
+test-xfail-tst-relro-ldso = yes
|
||||
+test-xfail-tst-relro-libc = yes
|
||||
+endif
|
||||
+
|
||||
ifeq ($(subdir),misc)
|
||||
sysdep_headers += sys/rse.h
|
||||
endif
|
87
SOURCES/glibc-upstream-2.34-169.patch
Normal file
87
SOURCES/glibc-upstream-2.34-169.patch
Normal file
@ -0,0 +1,87 @@
|
||||
commit ca0faa140ff8cebe4c041d935f0f5eb480873d99
|
||||
Author: Joan Bruguera <joanbrugueram@gmail.com>
|
||||
Date: Mon Apr 11 19:49:56 2022 +0200
|
||||
|
||||
misc: Fix rare fortify crash on wchar funcs. [BZ 29030]
|
||||
|
||||
If `__glibc_objsize (__o) == (size_t) -1` (i.e. `__o` is unknown size), fortify
|
||||
checks should pass, and `__whatever_alias` should be called.
|
||||
|
||||
Previously, `__glibc_objsize (__o) == (size_t) -1` was explicitly checked, but
|
||||
on commit a643f60c53876b, this was moved into `__glibc_safe_or_unknown_len`.
|
||||
|
||||
A comment says the -1 case should work as: "The -1 check is redundant because
|
||||
since it implies that __glibc_safe_len_cond is true.". But this fails when:
|
||||
* `__s > 1`
|
||||
* `__osz == -1` (i.e. unknown size at compile time)
|
||||
* `__l` is big enough
|
||||
* `__l * __s <= __osz` can be folded to a constant
|
||||
(I only found this to be true for `mbsrtowcs` and other functions in wchar2.h)
|
||||
|
||||
In this case `__l * __s <= __osz` is false, and `__whatever_chk_warn` will be
|
||||
called by `__glibc_fortify` or `__glibc_fortify_n` and crash the program.
|
||||
|
||||
This commit adds the explicit `__osz == -1` check again.
|
||||
moc crashes on startup due to this, see: https://bugs.archlinux.org/task/74041
|
||||
|
||||
Minimal test case (test.c):
|
||||
#include <wchar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
const char *hw = "HelloWorld";
|
||||
mbsrtowcs (NULL, &hw, (size_t)-1, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Build with:
|
||||
gcc -O2 -Wp,-D_FORTIFY_SOURCE=2 test.c -o test && ./test
|
||||
|
||||
Output:
|
||||
*** buffer overflow detected ***: terminated
|
||||
|
||||
Fixes: BZ #29030
|
||||
Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
(cherry picked from commit 33e03f9cd2be4f2cd62f93fda539cc07d9c8130e)
|
||||
|
||||
diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
|
||||
index 8b5902423cf0ad88..fb02452f5993c594 100644
|
||||
--- a/debug/tst-fortify.c
|
||||
+++ b/debug/tst-fortify.c
|
||||
@@ -1505,6 +1505,11 @@ do_test (void)
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
+ /* Bug 29030 regresion check */
|
||||
+ cp = "HelloWorld";
|
||||
+ if (mbsrtowcs (NULL, &cp, (size_t)-1, &s) != 10)
|
||||
+ FAIL ();
|
||||
+
|
||||
cp = "A";
|
||||
if (mbstowcs (wenough, cp, 10) != 1
|
||||
|| wcscmp (wenough, L"A") != 0)
|
||||
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
|
||||
index 515fb681a0547217..b36013b9a6b4d9c3 100644
|
||||
--- a/misc/sys/cdefs.h
|
||||
+++ b/misc/sys/cdefs.h
|
||||
@@ -161,13 +161,13 @@
|
||||
|| (__builtin_constant_p (__l) && (__l) > 0))
|
||||
|
||||
/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ
|
||||
- condition can be folded to a constant and if it is true. The -1 check is
|
||||
- redundant because since it implies that __glibc_safe_len_cond is true. */
|
||||
+ condition can be folded to a constant and if it is true, or unknown (-1) */
|
||||
#define __glibc_safe_or_unknown_len(__l, __s, __osz) \
|
||||
- (__glibc_unsigned_or_positive (__l) \
|
||||
- && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
|
||||
- __s, __osz)) \
|
||||
- && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
|
||||
+ ((__osz) == (__SIZE_TYPE__) -1 \
|
||||
+ || (__glibc_unsigned_or_positive (__l) \
|
||||
+ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
|
||||
+ (__s), (__osz))) \
|
||||
+ && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz))))
|
||||
|
||||
/* Conversely, we know at compile time that the length is unsafe if the
|
||||
__L * __S <= __OBJSZ condition can be folded to a constant and if it is
|
49
SOURCES/glibc-upstream-2.34-170.patch
Normal file
49
SOURCES/glibc-upstream-2.34-170.patch
Normal file
@ -0,0 +1,49 @@
|
||||
commit 0d477e92c49db2906b32e44135b98746ccc73c7b
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Apr 26 14:22:10 2022 +0200
|
||||
|
||||
INSTALL: Rephrase -with-default-link documentation
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit c935789bdf40ba22b5698da869d3a4789797e09f)
|
||||
|
||||
diff --git a/INSTALL b/INSTALL
|
||||
index 60d01568d77645c7..10a3dcdc0a8db665 100644
|
||||
--- a/INSTALL
|
||||
+++ b/INSTALL
|
||||
@@ -90,10 +90,10 @@ if 'CFLAGS' is specified it must enable optimization. For example:
|
||||
library will still be usable, but functionality may be lost--for
|
||||
example, you can't build a shared libc with old binutils.
|
||||
|
||||
-'--with-default-link=FLAG'
|
||||
- With '--with-default-link=yes', the build system does not use a
|
||||
- custom linker script for linking shared objects. The default for
|
||||
- FLAG is the opposite, 'no', because the custom linker script is
|
||||
+'--with-default-link'
|
||||
+ With '--with-default-link', the build system does not use a custom
|
||||
+ linker script for linking shared objects. The default is
|
||||
+ '--without-default-link', because the custom linker script is
|
||||
needed for full RELRO protection.
|
||||
|
||||
'--with-nonshared-cflags=CFLAGS'
|
||||
diff --git a/manual/install.texi b/manual/install.texi
|
||||
index 36a5af62bc5722b0..8e34ff7e1847f3ae 100644
|
||||
--- a/manual/install.texi
|
||||
+++ b/manual/install.texi
|
||||
@@ -117,11 +117,11 @@ problem and suppress these constructs, so that the library will still be
|
||||
usable, but functionality may be lost---for example, you can't build a
|
||||
shared libc with old binutils.
|
||||
|
||||
-@item --with-default-link=@var{FLAG}
|
||||
-With @code{--with-default-link=yes}, the build system does not use a
|
||||
-custom linker script for linking shared objects. The default for
|
||||
-@var{FLAG} is the opposite, @samp{no}, because the custom linker script
|
||||
-is needed for full RELRO protection.
|
||||
+@item --with-default-link
|
||||
+With @code{--with-default-link}, the build system does not use a custom
|
||||
+linker script for linking shared objects. The default is
|
||||
+@code{--without-default-link}, because the custom linker script is
|
||||
+needed for full RELRO protection.
|
||||
|
||||
@item --with-nonshared-cflags=@var{cflags}
|
||||
Use additional compiler flags @var{cflags} to build the parts of the
|
377
SOURCES/glibc-upstream-2.34-171.patch
Normal file
377
SOURCES/glibc-upstream-2.34-171.patch
Normal file
@ -0,0 +1,377 @@
|
||||
commit bc56ab1f4aa937665034373d3e320d0779a839aa
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Apr 26 14:23:02 2022 +0200
|
||||
|
||||
dlfcn: Do not use rtld_active () to determine ld.so state (bug 29078)
|
||||
|
||||
When audit modules are loaded, ld.so initialization is not yet
|
||||
complete, and rtld_active () returns false even though ld.so is
|
||||
mostly working. Instead, the static dlopen hook is used, but that
|
||||
does not work at all because this is not a static dlopen situation.
|
||||
|
||||
Commit 466c1ea15f461edb8e3ffaf5d86d708876343bbf ("dlfcn: Rework
|
||||
static dlopen hooks") moved the hook pointer into _rtld_global_ro,
|
||||
which means that separate protection is not needed anymore and the
|
||||
hook pointer can be checked directly.
|
||||
|
||||
The guard for disabling libio vtable hardening in _IO_vtable_check
|
||||
should stay for now.
|
||||
|
||||
Fixes commit 8e1472d2c1e25e6eabc2059170731365f6d5b3d1 ("ld.so:
|
||||
Examine GLRO to detect inactive loader [BZ #20204]").
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
(cherry picked from commit 8dcb6d0af07fda3607b541857e4f3970a74ed55b)
|
||||
|
||||
diff --git a/dlfcn/dladdr.c b/dlfcn/dladdr.c
|
||||
index 1cc305f0c46e7c3b..0d07ae1cd4dbb7a2 100644
|
||||
--- a/dlfcn/dladdr.c
|
||||
+++ b/dlfcn/dladdr.c
|
||||
@@ -24,7 +24,7 @@ int
|
||||
__dladdr (const void *address, Dl_info *info)
|
||||
{
|
||||
#ifdef SHARED
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dladdr (address, info);
|
||||
#endif
|
||||
return _dl_addr (address, info, NULL, NULL);
|
||||
diff --git a/dlfcn/dladdr1.c b/dlfcn/dladdr1.c
|
||||
index 78560dbac208c316..93ce68c1d6067fe2 100644
|
||||
--- a/dlfcn/dladdr1.c
|
||||
+++ b/dlfcn/dladdr1.c
|
||||
@@ -24,7 +24,7 @@ int
|
||||
__dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
|
||||
{
|
||||
#ifdef SHARED
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dladdr1 (address, info, extra, flags);
|
||||
#endif
|
||||
|
||||
diff --git a/dlfcn/dlclose.c b/dlfcn/dlclose.c
|
||||
index 6a013a81bb648191..07ecb21bf7d43be4 100644
|
||||
--- a/dlfcn/dlclose.c
|
||||
+++ b/dlfcn/dlclose.c
|
||||
@@ -24,7 +24,7 @@ int
|
||||
__dlclose (void *handle)
|
||||
{
|
||||
#ifdef SHARED
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dlclose (handle);
|
||||
#endif
|
||||
|
||||
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
|
||||
index 5047b140662bc33e..63da79c63000eef0 100644
|
||||
--- a/dlfcn/dlerror.c
|
||||
+++ b/dlfcn/dlerror.c
|
||||
@@ -32,7 +32,7 @@ char *
|
||||
__dlerror (void)
|
||||
{
|
||||
# ifdef SHARED
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dlerror ();
|
||||
# endif
|
||||
|
||||
diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
|
||||
index c6f9a1da09ff8622..47d2daa96fa5986f 100644
|
||||
--- a/dlfcn/dlinfo.c
|
||||
+++ b/dlfcn/dlinfo.c
|
||||
@@ -89,7 +89,7 @@ dlinfo_implementation (void *handle, int request, void *arg)
|
||||
int
|
||||
___dlinfo (void *handle, int request, void *arg)
|
||||
{
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dlinfo (handle, request, arg);
|
||||
else
|
||||
return dlinfo_implementation (handle, request, arg);
|
||||
diff --git a/dlfcn/dlmopen.c b/dlfcn/dlmopen.c
|
||||
index c171c8953da20fc7..2309224eb8484b1a 100644
|
||||
--- a/dlfcn/dlmopen.c
|
||||
+++ b/dlfcn/dlmopen.c
|
||||
@@ -80,7 +80,7 @@ dlmopen_implementation (Lmid_t nsid, const char *file, int mode,
|
||||
void *
|
||||
___dlmopen (Lmid_t nsid, const char *file, int mode)
|
||||
{
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
|
||||
else
|
||||
return dlmopen_implementation (nsid, file, mode, RETURN_ADDRESS (0));
|
||||
diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c
|
||||
index e04b374b82b04337..9c59c751c4eaf7a7 100644
|
||||
--- a/dlfcn/dlopen.c
|
||||
+++ b/dlfcn/dlopen.c
|
||||
@@ -75,7 +75,7 @@ dlopen_implementation (const char *file, int mode, void *dl_caller)
|
||||
void *
|
||||
___dlopen (const char *file, int mode)
|
||||
{
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0));
|
||||
else
|
||||
return dlopen_implementation (file, mode, RETURN_ADDRESS (0));
|
||||
diff --git a/dlfcn/dlopenold.c b/dlfcn/dlopenold.c
|
||||
index 9115501ac121eeca..c2f2a42194d50953 100644
|
||||
--- a/dlfcn/dlopenold.c
|
||||
+++ b/dlfcn/dlopenold.c
|
||||
@@ -70,7 +70,7 @@ __dlopen_nocheck (const char *file, int mode)
|
||||
mode |= RTLD_LAZY;
|
||||
args.mode = mode;
|
||||
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0));
|
||||
|
||||
return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
|
||||
diff --git a/dlfcn/dlsym.c b/dlfcn/dlsym.c
|
||||
index 43044cf7bb95801e..d3861170a7631d01 100644
|
||||
--- a/dlfcn/dlsym.c
|
||||
+++ b/dlfcn/dlsym.c
|
||||
@@ -62,7 +62,7 @@ dlsym_implementation (void *handle, const char *name, void *dl_caller)
|
||||
void *
|
||||
___dlsym (void *handle, const char *name)
|
||||
{
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dlsym (handle, name, RETURN_ADDRESS (0));
|
||||
else
|
||||
return dlsym_implementation (handle, name, RETURN_ADDRESS (0));
|
||||
diff --git a/dlfcn/dlvsym.c b/dlfcn/dlvsym.c
|
||||
index 9b76f9afa513e11f..3af02109c306b800 100644
|
||||
--- a/dlfcn/dlvsym.c
|
||||
+++ b/dlfcn/dlvsym.c
|
||||
@@ -65,7 +65,7 @@ dlvsym_implementation (void *handle, const char *name, const char *version,
|
||||
void *
|
||||
___dlvsym (void *handle, const char *name, const char *version)
|
||||
{
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->dlvsym (handle, name, version,
|
||||
RETURN_ADDRESS (0));
|
||||
else
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index fec6e23b5b625e3b..c89a6a58690646ee 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -376,6 +376,7 @@ tests += \
|
||||
tst-audit24d \
|
||||
tst-audit25a \
|
||||
tst-audit25b \
|
||||
+ tst-audit26 \
|
||||
tst-auditmany \
|
||||
tst-auxobj \
|
||||
tst-auxobj-dlopen \
|
||||
@@ -721,6 +722,7 @@ modules-names = \
|
||||
tst-auditmod24c \
|
||||
tst-auditmod24d \
|
||||
tst-auditmod25 \
|
||||
+ tst-auditmod26 \
|
||||
tst-auxvalmod \
|
||||
tst-big-note-lib \
|
||||
tst-deep1mod1 \
|
||||
@@ -2194,6 +2196,10 @@ $(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \
|
||||
LDFLAGS-tst-audit25b = -Wl,-z,now
|
||||
tst-audit25b-ARGS = -- $(host-test-program-cmd)
|
||||
|
||||
+$(objpfx)tst-audit26.out: $(objpfx)tst-auditmod26.so
|
||||
+$(objpfx)tst-auditmod26.so: $(libsupport)
|
||||
+tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so
|
||||
+
|
||||
# tst-sonamemove links against an older implementation of the library.
|
||||
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
|
||||
index d5bc4a277f4c6ef3..db4342a3256921f0 100644
|
||||
--- a/elf/dl-libc.c
|
||||
+++ b/elf/dl-libc.c
|
||||
@@ -157,7 +157,7 @@ __libc_dlopen_mode (const char *name, int mode)
|
||||
args.caller_dlopen = RETURN_ADDRESS (0);
|
||||
|
||||
#ifdef SHARED
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->libc_dlopen_mode (name, mode);
|
||||
#endif
|
||||
return dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map;
|
||||
@@ -185,7 +185,7 @@ __libc_dlsym (void *map, const char *name)
|
||||
args.name = name;
|
||||
|
||||
#ifdef SHARED
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->libc_dlsym (map, name);
|
||||
#endif
|
||||
return (dlerror_run (do_dlsym, &args) ? NULL
|
||||
@@ -199,7 +199,7 @@ void *
|
||||
__libc_dlvsym (void *map, const char *name, const char *version)
|
||||
{
|
||||
#ifdef SHARED
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->libc_dlvsym (map, name, version);
|
||||
#endif
|
||||
|
||||
@@ -222,7 +222,7 @@ int
|
||||
__libc_dlclose (void *map)
|
||||
{
|
||||
#ifdef SHARED
|
||||
- if (!rtld_active ())
|
||||
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||
return GLRO (dl_dlfcn_hook)->libc_dlclose (map);
|
||||
#endif
|
||||
return dlerror_run (do_dlclose, map);
|
||||
diff --git a/elf/tst-audit26.c b/elf/tst-audit26.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3f920e83bac247a5
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-audit26.c
|
||||
@@ -0,0 +1,35 @@
|
||||
+/* Check the usability of <dlfcn.h> functions in audit modules.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <gnu/lib-names.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/xdlfcn.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* Check that the audit module has been loaded. */
|
||||
+ void *handle = xdlopen ("mapped to libc", RTLD_LOCAL | RTLD_NOW);
|
||||
+ TEST_VERIFY (handle
|
||||
+ == xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/elf/tst-auditmod26.c b/elf/tst-auditmod26.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..db7ba95abec20f53
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-auditmod26.c
|
||||
@@ -0,0 +1,104 @@
|
||||
+/* Check the usability of <dlfcn.h> functions in audit modules. Audit module.
|
||||
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <dlfcn.h>
|
||||
+#include <first-versions.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
+#include <link.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/xdlfcn.h>
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int current)
|
||||
+{
|
||||
+ /* Exercise various <dlfcn.h> functions. */
|
||||
+
|
||||
+ /* Check dlopen, dlsym, dlclose. */
|
||||
+ void *handle = xdlopen (LIBM_SO, RTLD_LOCAL | RTLD_NOW);
|
||||
+ void *ptr = xdlsym (handle, "sincos");
|
||||
+ TEST_VERIFY (ptr != NULL);
|
||||
+ ptr = dlsym (handle, "SINCOS");
|
||||
+ TEST_VERIFY (ptr == NULL);
|
||||
+ const char *message = dlerror ();
|
||||
+ TEST_VERIFY (strstr (message, ": undefined symbol: SINCOS") != NULL);
|
||||
+ ptr = dlsym (handle, "SINCOS");
|
||||
+ TEST_VERIFY (ptr == NULL);
|
||||
+ xdlclose (handle);
|
||||
+ TEST_COMPARE_STRING (dlerror (), NULL);
|
||||
+
|
||||
+ handle = xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD);
|
||||
+
|
||||
+ /* Check dlvsym. _exit is unlikely to gain another symbol
|
||||
+ version. */
|
||||
+ TEST_VERIFY (xdlsym (handle, "_exit")
|
||||
+ == xdlvsym (handle, "_exit", FIRST_VERSION_libc__exit_STRING));
|
||||
+
|
||||
+ /* Check dlinfo. */
|
||||
+ {
|
||||
+ void *handle2 = NULL;
|
||||
+ TEST_COMPARE (dlinfo (handle, RTLD_DI_LINKMAP, &handle2), 0);
|
||||
+ TEST_VERIFY (handle2 == handle);
|
||||
+ }
|
||||
+
|
||||
+ /* Check dladdr and dladdr1. */
|
||||
+ Dl_info info = { };
|
||||
+ TEST_VERIFY (dladdr (&_exit, &info) != 0);
|
||||
+ if (strcmp (info.dli_sname, "_Exit") != 0) /* _Exit is an alias. */
|
||||
+ TEST_COMPARE_STRING (info.dli_sname, "_exit");
|
||||
+ TEST_VERIFY (info.dli_saddr == &_exit);
|
||||
+ TEST_VERIFY (strstr (info.dli_fname, LIBC_SO));
|
||||
+ void *extra_info;
|
||||
+ memset (&info, 0, sizeof (info));
|
||||
+ TEST_VERIFY (dladdr1 (&_exit, &info, &extra_info, RTLD_DL_LINKMAP) != 0);
|
||||
+ TEST_VERIFY (extra_info == handle);
|
||||
+
|
||||
+ /* Verify that dlmopen creates a new namespace. */
|
||||
+ void *dlmopen_handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||
+ TEST_VERIFY (dlmopen_handle != handle);
|
||||
+ memset (&info, 0, sizeof (info));
|
||||
+ extra_info = NULL;
|
||||
+ ptr = xdlsym (dlmopen_handle, "_exit");
|
||||
+ TEST_VERIFY (dladdr1 (ptr, &info, &extra_info, RTLD_DL_LINKMAP) != 0);
|
||||
+ TEST_VERIFY (extra_info == dlmopen_handle);
|
||||
+ xdlclose (dlmopen_handle);
|
||||
+
|
||||
+ /* Terminate the process with an error state. This does not happen
|
||||
+ automatically because the audit module state is not shared with
|
||||
+ the main program. */
|
||||
+ if (support_record_failure_is_failed ())
|
||||
+ {
|
||||
+ fflush (stdout);
|
||||
+ fflush (stderr);
|
||||
+ _exit (1);
|
||||
+ }
|
||||
+
|
||||
+ return LAV_CURRENT;
|
||||
+}
|
||||
+
|
||||
+char *
|
||||
+la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
|
||||
+{
|
||||
+ if (strcmp (name, "mapped to libc") == 0)
|
||||
+ return (char *) LIBC_SO;
|
||||
+ else
|
||||
+ return (char *) name;
|
||||
+}
|
28
SOURCES/glibc-upstream-2.34-172.patch
Normal file
28
SOURCES/glibc-upstream-2.34-172.patch
Normal file
@ -0,0 +1,28 @@
|
||||
commit 83cc145830bdbefdabe03787ed884d548bea9c99
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Apr 22 19:34:52 2022 +0200
|
||||
|
||||
scripts/glibcelf.py: Mark as UNSUPPORTED on Python 3.5 and earlier
|
||||
|
||||
enum.IntFlag and enum.EnumMeta._missing_ support are not part of
|
||||
earlier Python versions.
|
||||
|
||||
(cherry picked from commit b571f3adffdcbed23f35ea39b0ca43809dbb4f5b)
|
||||
|
||||
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||
index 8f7d0ca184845714..da0d5380f33a195e 100644
|
||||
--- a/scripts/glibcelf.py
|
||||
+++ b/scripts/glibcelf.py
|
||||
@@ -28,6 +28,12 @@ import collections
|
||||
import enum
|
||||
import struct
|
||||
|
||||
+if not hasattr(enum, 'IntFlag'):
|
||||
+ import sys
|
||||
+ sys.stdout.write(
|
||||
+ 'warning: glibcelf.py needs Python 3.6 for enum support\n')
|
||||
+ sys.exit(77)
|
||||
+
|
||||
class _OpenIntEnum(enum.IntEnum):
|
||||
"""Integer enumeration that supports arbitrary int values."""
|
||||
@classmethod
|
254
SOURCES/glibc-upstream-2.34-173.patch
Normal file
254
SOURCES/glibc-upstream-2.34-173.patch
Normal file
@ -0,0 +1,254 @@
|
||||
commit 16245986fb9bfe396113fc7dfd1929f69a9e748e
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Fri Aug 20 06:42:24 2021 -0700
|
||||
|
||||
x86-64: Optimize load of all bits set into ZMM register [BZ #28252]
|
||||
|
||||
Optimize loads of all bits set into ZMM register in AVX512 SVML codes
|
||||
by replacing
|
||||
|
||||
vpbroadcastq .L_2il0floatpacket.16(%rip), %zmmX
|
||||
|
||||
and
|
||||
|
||||
vmovups .L_2il0floatpacket.13(%rip), %zmmX
|
||||
|
||||
with
|
||||
vpternlogd $0xff, %zmmX, %zmmX, %zmmX
|
||||
|
||||
This fixes BZ #28252.
|
||||
|
||||
(cherry picked from commit 78c9ec9000f873abe7a15a91b87080a2e4308260)
|
||||
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S
|
||||
index e68fcdbb16a79f36..58e588a3d42a8bc9 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S
|
||||
@@ -265,7 +265,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_cos
|
||||
vmovaps %zmm0, %zmm8
|
||||
|
||||
/* Check for large arguments path */
|
||||
- vpbroadcastq .L_2il0floatpacket.16(%rip), %zmm2
|
||||
+ vpternlogd $0xff, %zmm2, %zmm2, %zmm2
|
||||
|
||||
/*
|
||||
ARGUMENT RANGE REDUCTION:
|
||||
@@ -456,8 +456,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_cos
|
||||
jmp .LBL_2_7
|
||||
#endif
|
||||
END (_ZGVeN8v_cos_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.16:
|
||||
- .long 0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.16,@object
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S
|
||||
index dfa2acafc486b56b..f5f117d474f66176 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S
|
||||
@@ -274,7 +274,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_log
|
||||
|
||||
/* preserve mantissa, set input exponent to 2^(-10) */
|
||||
vpternlogq $248, _ExpMask(%rax), %zmm3, %zmm2
|
||||
- vpbroadcastq .L_2il0floatpacket.12(%rip), %zmm1
|
||||
+ vpternlogd $0xff, %zmm1, %zmm1, %zmm1
|
||||
vpsrlq $32, %zmm4, %zmm6
|
||||
|
||||
/* reciprocal approximation good to at least 11 bits */
|
||||
@@ -461,8 +461,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_log
|
||||
jmp .LBL_2_7
|
||||
#endif
|
||||
END (_ZGVeN8v_log_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.12:
|
||||
- .long 0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.12,@object
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S
|
||||
index be8ab7c6e0e33819..48d251db16ccab9d 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S
|
||||
@@ -261,7 +261,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_sin
|
||||
andq $-64, %rsp
|
||||
subq $1280, %rsp
|
||||
movq __svml_d_trig_data@GOTPCREL(%rip), %rax
|
||||
- vpbroadcastq .L_2il0floatpacket.14(%rip), %zmm14
|
||||
+ vpternlogd $0xff, %zmm1, %zmm1, %zmm14
|
||||
vmovups __dAbsMask(%rax), %zmm7
|
||||
vmovups __dInvPI(%rax), %zmm2
|
||||
vmovups __dRShifter(%rax), %zmm1
|
||||
@@ -458,8 +458,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_sin
|
||||
jmp .LBL_2_7
|
||||
#endif
|
||||
END (_ZGVeN8v_sin_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.14:
|
||||
- .long 0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.14,@object
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S
|
||||
index 611887082a545854..a4944a4feef6aa98 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S
|
||||
@@ -430,7 +430,7 @@ WRAPPER_IMPL_AVX512_fFF _ZGVdN4vl8l8_sincos
|
||||
|
||||
/* SinPoly = SinR*SinPoly */
|
||||
vfmadd213pd %zmm5, %zmm5, %zmm4
|
||||
- vpbroadcastq .L_2il0floatpacket.15(%rip), %zmm3
|
||||
+ vpternlogd $0xff, %zmm3, %zmm3, %zmm3
|
||||
|
||||
/* Update Cos result's sign */
|
||||
vxorpd %zmm2, %zmm1, %zmm1
|
||||
@@ -741,8 +741,3 @@ END (_ZGVeN8vvv_sincos_knl)
|
||||
ENTRY (_ZGVeN8vvv_sincos_skx)
|
||||
WRAPPER_AVX512_vvv_vl8l8 _ZGVeN8vl8l8_sincos_skx
|
||||
END (_ZGVeN8vvv_sincos_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.15:
|
||||
- .long 0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.15,@object
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S
|
||||
index f671d60d5dab5a0e..fe8474fed943e8ad 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S
|
||||
@@ -278,7 +278,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_cosf
|
||||
X = X - Y*PI1 - Y*PI2 - Y*PI3
|
||||
*/
|
||||
vmovaps %zmm0, %zmm6
|
||||
- vmovups .L_2il0floatpacket.13(%rip), %zmm12
|
||||
+ vpternlogd $0xff, %zmm12, %zmm12, %zmm12
|
||||
vmovups __sRShifter(%rax), %zmm3
|
||||
vmovups __sPI1_FMA(%rax), %zmm5
|
||||
vmovups __sA9_FMA(%rax), %zmm9
|
||||
@@ -453,8 +453,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_cosf
|
||||
jmp .LBL_2_7
|
||||
#endif
|
||||
END (_ZGVeN16v_cosf_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.13:
|
||||
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.13,@object
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S
|
||||
index 637bfe3c06ab9ad4..229b7828cde04db2 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S
|
||||
@@ -264,7 +264,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_expf
|
||||
vmovaps %zmm0, %zmm7
|
||||
|
||||
/* compare against threshold */
|
||||
- vmovups .L_2il0floatpacket.13(%rip), %zmm3
|
||||
+ vpternlogd $0xff, %zmm3, %zmm3, %zmm3
|
||||
vmovups __sInvLn2(%rax), %zmm4
|
||||
vmovups __sShifter(%rax), %zmm1
|
||||
vmovups __sLn2hi(%rax), %zmm6
|
||||
@@ -440,8 +440,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_expf
|
||||
|
||||
#endif
|
||||
END (_ZGVeN16v_expf_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.13:
|
||||
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.13,@object
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S
|
||||
index 9d790fbf0ad6c8ec..fa2aae986f543582 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S
|
||||
@@ -235,7 +235,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_logf
|
||||
andq $-64, %rsp
|
||||
subq $1280, %rsp
|
||||
movq __svml_slog_data@GOTPCREL(%rip), %rax
|
||||
- vmovups .L_2il0floatpacket.7(%rip), %zmm6
|
||||
+ vpternlogd $0xff, %zmm6, %zmm6, %zmm6
|
||||
vmovups _iBrkValue(%rax), %zmm4
|
||||
vmovups _sPoly_7(%rax), %zmm8
|
||||
|
||||
@@ -409,8 +409,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_logf
|
||||
|
||||
#endif
|
||||
END (_ZGVeN16v_logf_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.7:
|
||||
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.7,@object
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S
|
||||
index c5c43c46ff7af5a3..6aea2a4f11d1f85f 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S
|
||||
@@ -385,7 +385,7 @@ WRAPPER_IMPL_AVX512_ff _ZGVdN8vv_powf
|
||||
vpsrlq $32, %zmm3, %zmm2
|
||||
vpmovqd %zmm2, %ymm11
|
||||
vcvtps2pd %ymm14, %zmm13
|
||||
- vmovups .L_2il0floatpacket.23(%rip), %zmm14
|
||||
+ vpternlogd $0xff, %zmm14, %zmm14, %zmm14
|
||||
vmovaps %zmm14, %zmm26
|
||||
vpandd _ABSMASK(%rax), %zmm1, %zmm8
|
||||
vpcmpd $1, _INF(%rax), %zmm8, %k2
|
||||
@@ -427,7 +427,7 @@ WRAPPER_IMPL_AVX512_ff _ZGVdN8vv_powf
|
||||
vpmovqd %zmm11, %ymm5
|
||||
vpxord %zmm10, %zmm10, %zmm10
|
||||
vgatherdpd _Log2Rcp_lookup(%rax,%ymm4), %zmm10{%k3}
|
||||
- vpbroadcastq .L_2il0floatpacket.24(%rip), %zmm4
|
||||
+ vpternlogd $0xff, %zmm4, %zmm4, %zmm4
|
||||
vpxord %zmm11, %zmm11, %zmm11
|
||||
vcvtdq2pd %ymm7, %zmm7
|
||||
vgatherdpd _Log2Rcp_lookup(%rax,%ymm5), %zmm11{%k1}
|
||||
@@ -643,11 +643,3 @@ WRAPPER_IMPL_AVX512_ff _ZGVdN8vv_powf
|
||||
jmp .LBL_2_7
|
||||
#endif
|
||||
END (_ZGVeN16vv_powf_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.23:
|
||||
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.23,@object
|
||||
-.L_2il0floatpacket.24:
|
||||
- .long 0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.24,@object
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S
|
||||
index 9cf359c86ff9bd70..a446c504f63c9399 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S
|
||||
@@ -317,7 +317,7 @@ WRAPPER_IMPL_AVX512_fFF _ZGVdN8vvv_sincosf
|
||||
|
||||
/* Result sign calculations */
|
||||
vpternlogd $150, %zmm0, %zmm14, %zmm1
|
||||
- vmovups .L_2il0floatpacket.13(%rip), %zmm14
|
||||
+ vpternlogd $0xff, %zmm14, %zmm14, %zmm14
|
||||
|
||||
/* Add correction term 0.5 for cos() part */
|
||||
vaddps %zmm8, %zmm5, %zmm15
|
||||
@@ -748,8 +748,3 @@ END (_ZGVeN16vvv_sincosf_knl)
|
||||
ENTRY (_ZGVeN16vvv_sincosf_skx)
|
||||
WRAPPER_AVX512_vvv_vl4l4 _ZGVeN16vl4l4_sincosf_skx
|
||||
END (_ZGVeN16vvv_sincosf_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.13:
|
||||
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.13,@object
|
||||
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S
|
||||
index bd05109a62181f22..c1b352d0ad1992cd 100644
|
||||
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S
|
||||
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S
|
||||
@@ -280,7 +280,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_sinf
|
||||
movq __svml_s_trig_data@GOTPCREL(%rip), %rax
|
||||
|
||||
/* Check for large and special values */
|
||||
- vmovups .L_2il0floatpacket.11(%rip), %zmm14
|
||||
+ vpternlogd $0xff, %zmm14, %zmm14, %zmm14
|
||||
vmovups __sAbsMask(%rax), %zmm5
|
||||
vmovups __sInvPI(%rax), %zmm1
|
||||
vmovups __sRShifter(%rax), %zmm2
|
||||
@@ -472,8 +472,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_sinf
|
||||
jmp .LBL_2_7
|
||||
#endif
|
||||
END (_ZGVeN16v_sinf_skx)
|
||||
-
|
||||
- .section .rodata, "a"
|
||||
-.L_2il0floatpacket.11:
|
||||
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||
- .type .L_2il0floatpacket.11,@object
|
42
SOURCES/glibc-upstream-2.34-174.patch
Normal file
42
SOURCES/glibc-upstream-2.34-174.patch
Normal file
@ -0,0 +1,42 @@
|
||||
commit b5a44a6a471aafd3677659a610f32468c40a666b
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Tue Sep 21 18:31:49 2021 -0500
|
||||
|
||||
x86: Modify ENTRY in sysdep.h so that p2align can be specified
|
||||
|
||||
No bug.
|
||||
|
||||
This change adds a new macro ENTRY_P2ALIGN which takes a second
|
||||
argument, log2 of the desired function alignment.
|
||||
|
||||
The old ENTRY(name) macro is just ENTRY_P2ALIGN(name, 4) so this
|
||||
doesn't affect any existing functionality.
|
||||
|
||||
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
(cherry picked from commit fc5bd179ef3a953dff8d1655bd530d0e230ffe71)
|
||||
|
||||
diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h
|
||||
index cac1d762fb3f99d0..937180c1bd791570 100644
|
||||
--- a/sysdeps/x86/sysdep.h
|
||||
+++ b/sysdeps/x86/sysdep.h
|
||||
@@ -78,15 +78,18 @@ enum cf_protection_level
|
||||
#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
|
||||
|
||||
/* Define an entry point visible from C. */
|
||||
-#define ENTRY(name) \
|
||||
+#define ENTRY_P2ALIGN(name, alignment) \
|
||||
.globl C_SYMBOL_NAME(name); \
|
||||
.type C_SYMBOL_NAME(name),@function; \
|
||||
- .align ALIGNARG(4); \
|
||||
+ .align ALIGNARG(alignment); \
|
||||
C_LABEL(name) \
|
||||
cfi_startproc; \
|
||||
_CET_ENDBR; \
|
||||
CALL_MCOUNT
|
||||
|
||||
+/* Common entry 16 byte aligns. */
|
||||
+#define ENTRY(name) ENTRY_P2ALIGN (name, 4)
|
||||
+
|
||||
#undef END
|
||||
#define END(name) \
|
||||
cfi_endproc; \
|
653
SOURCES/glibc-upstream-2.34-175.patch
Normal file
653
SOURCES/glibc-upstream-2.34-175.patch
Normal file
@ -0,0 +1,653 @@
|
||||
commit 5ec3416853c4150c4d13312e05f93a053586d528
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Tue Sep 21 18:45:03 2021 -0500
|
||||
|
||||
x86: Optimize memcmp-evex-movbe.S for frontend behavior and size
|
||||
|
||||
No bug.
|
||||
|
||||
The frontend optimizations are to:
|
||||
1. Reorganize logically connected basic blocks so they are either in
|
||||
the same cache line or adjacent cache lines.
|
||||
2. Avoid cases when basic blocks unnecissarily cross cache lines.
|
||||
3. Try and 32 byte align any basic blocks possible without sacrificing
|
||||
code size. Smaller / Less hot basic blocks are used for this.
|
||||
|
||||
Overall code size shrunk by 168 bytes. This should make up for any
|
||||
extra costs due to aligning to 64 bytes.
|
||||
|
||||
In general performance before deviated a great deal dependending on
|
||||
whether entry alignment % 64 was 0, 16, 32, or 48. These changes
|
||||
essentially make it so that the current implementation is at least
|
||||
equal to the best alignment of the original for any arguments.
|
||||
|
||||
The only additional optimization is in the page cross case. Branch on
|
||||
equals case was removed from the size == [4, 7] case. As well the [4,
|
||||
7] and [2, 3] case where swapped as [4, 7] is likely a more hot
|
||||
argument size.
|
||||
|
||||
test-memcmp and test-wmemcmp are both passing.
|
||||
|
||||
(cherry picked from commit 1bd8b8d58fc9967cc073d2c13bfb6befefca2faa)
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||
index 654dc7ac8ccb9445..2761b54f2e7dea9f 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||
@@ -34,7 +34,24 @@
|
||||
area.
|
||||
7. Use 2 vector compares when size is 2 * CHAR_PER_VEC or less.
|
||||
8. Use 4 vector compares when size is 4 * CHAR_PER_VEC or less.
|
||||
- 9. Use 8 vector compares when size is 8 * CHAR_PER_VEC or less. */
|
||||
+ 9. Use 8 vector compares when size is 8 * CHAR_PER_VEC or less.
|
||||
+
|
||||
+When possible the implementation tries to optimize for frontend in the
|
||||
+following ways:
|
||||
+Throughput:
|
||||
+ 1. All code sections that fit are able to run optimally out of the
|
||||
+ LSD.
|
||||
+ 2. All code sections that fit are able to run optimally out of the
|
||||
+ DSB
|
||||
+ 3. Basic blocks are contained in minimum number of fetch blocks
|
||||
+ necessary.
|
||||
+
|
||||
+Latency:
|
||||
+ 1. Logically connected basic blocks are put in the same
|
||||
+ cache-line.
|
||||
+ 2. Logically connected basic blocks that do not fit in the same
|
||||
+ cache-line are put in adjacent lines. This can get beneficial
|
||||
+ L2 spatial prefetching and L1 next-line prefetching. */
|
||||
|
||||
# include <sysdep.h>
|
||||
|
||||
@@ -47,9 +64,11 @@
|
||||
# ifdef USE_AS_WMEMCMP
|
||||
# define CHAR_SIZE 4
|
||||
# define VPCMP vpcmpd
|
||||
+# define VPTEST vptestmd
|
||||
# else
|
||||
# define CHAR_SIZE 1
|
||||
# define VPCMP vpcmpub
|
||||
+# define VPTEST vptestmb
|
||||
# endif
|
||||
|
||||
# define VEC_SIZE 32
|
||||
@@ -75,7 +94,9 @@
|
||||
*/
|
||||
|
||||
.section .text.evex,"ax",@progbits
|
||||
-ENTRY (MEMCMP)
|
||||
+/* Cache align memcmp entry. This allows for much more thorough
|
||||
+ frontend optimization. */
|
||||
+ENTRY_P2ALIGN (MEMCMP, 6)
|
||||
# ifdef __ILP32__
|
||||
/* Clear the upper 32 bits. */
|
||||
movl %edx, %edx
|
||||
@@ -89,7 +110,7 @@ ENTRY (MEMCMP)
|
||||
VPCMP $4, (%rdi), %YMM1, %k1
|
||||
kmovd %k1, %eax
|
||||
/* NB: eax must be destination register if going to
|
||||
- L(return_vec_[0,2]). For L(return_vec_3 destination register
|
||||
+ L(return_vec_[0,2]). For L(return_vec_3) destination register
|
||||
must be ecx. */
|
||||
testl %eax, %eax
|
||||
jnz L(return_vec_0)
|
||||
@@ -121,10 +142,6 @@ ENTRY (MEMCMP)
|
||||
testl %ecx, %ecx
|
||||
jnz L(return_vec_3)
|
||||
|
||||
- /* Zero YMM0. 4x VEC reduction is done with vpxor + vtern so
|
||||
- compare with zero to get a mask is needed. */
|
||||
- vpxorq %XMM0, %XMM0, %XMM0
|
||||
-
|
||||
/* Go to 4x VEC loop. */
|
||||
cmpq $(CHAR_PER_VEC * 8), %rdx
|
||||
ja L(more_8x_vec)
|
||||
@@ -148,47 +165,61 @@ ENTRY (MEMCMP)
|
||||
|
||||
VMOVU (VEC_SIZE * 2)(%rsi), %YMM3
|
||||
vpxorq (VEC_SIZE * 2)(%rdi), %YMM3, %YMM3
|
||||
- /* Or together YMM1, YMM2, and YMM3 into YMM3. */
|
||||
- vpternlogd $0xfe, %YMM1, %YMM2, %YMM3
|
||||
|
||||
VMOVU (VEC_SIZE * 3)(%rsi), %YMM4
|
||||
/* Ternary logic to xor (VEC_SIZE * 3)(%rdi) with YMM4 while
|
||||
- oring with YMM3. Result is stored in YMM4. */
|
||||
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM3, %YMM4
|
||||
- /* Compare YMM4 with 0. If any 1s s1 and s2 don't match. */
|
||||
- VPCMP $4, %YMM4, %YMM0, %k1
|
||||
+ oring with YMM1. Result is stored in YMM4. */
|
||||
+ vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||
+
|
||||
+ /* Or together YMM2, YMM3, and YMM4 into YMM4. */
|
||||
+ vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||
+
|
||||
+ /* Test YMM4 against itself. Store any CHAR mismatches in k1.
|
||||
+ */
|
||||
+ VPTEST %YMM4, %YMM4, %k1
|
||||
+ /* k1 must go to ecx for L(return_vec_0_1_2_3). */
|
||||
kmovd %k1, %ecx
|
||||
testl %ecx, %ecx
|
||||
jnz L(return_vec_0_1_2_3)
|
||||
/* NB: eax must be zero to reach here. */
|
||||
ret
|
||||
|
||||
- /* NB: aligning 32 here allows for the rest of the jump targets
|
||||
- to be tuned for 32 byte alignment. Most important this ensures
|
||||
- the L(more_8x_vec) loop is 32 byte aligned. */
|
||||
- .p2align 5
|
||||
-L(less_vec):
|
||||
- /* Check if one or less CHAR. This is necessary for size = 0 but
|
||||
- is also faster for size = CHAR_SIZE. */
|
||||
- cmpl $1, %edx
|
||||
- jbe L(one_or_less)
|
||||
+ .p2align 4
|
||||
+L(8x_end_return_vec_0_1_2_3):
|
||||
+ movq %rdx, %rdi
|
||||
+L(8x_return_vec_0_1_2_3):
|
||||
+ addq %rdi, %rsi
|
||||
+L(return_vec_0_1_2_3):
|
||||
+ VPTEST %YMM1, %YMM1, %k0
|
||||
+ kmovd %k0, %eax
|
||||
+ testl %eax, %eax
|
||||
+ jnz L(return_vec_0)
|
||||
|
||||
- /* Check if loading one VEC from either s1 or s2 could cause a
|
||||
- page cross. This can have false positives but is by far the
|
||||
- fastest method. */
|
||||
- movl %edi, %eax
|
||||
- orl %esi, %eax
|
||||
- andl $(PAGE_SIZE - 1), %eax
|
||||
- cmpl $(PAGE_SIZE - VEC_SIZE), %eax
|
||||
- jg L(page_cross_less_vec)
|
||||
+ VPTEST %YMM2, %YMM2, %k0
|
||||
+ kmovd %k0, %eax
|
||||
+ testl %eax, %eax
|
||||
+ jnz L(return_vec_1)
|
||||
|
||||
- /* No page cross possible. */
|
||||
- VMOVU (%rsi), %YMM2
|
||||
- VPCMP $4, (%rdi), %YMM2, %k1
|
||||
- kmovd %k1, %eax
|
||||
- /* Create mask in ecx for potentially in bound matches. */
|
||||
- bzhil %edx, %eax, %eax
|
||||
- jnz L(return_vec_0)
|
||||
+ VPTEST %YMM3, %YMM3, %k0
|
||||
+ kmovd %k0, %eax
|
||||
+ testl %eax, %eax
|
||||
+ jnz L(return_vec_2)
|
||||
+L(return_vec_3):
|
||||
+ /* bsf saves 1 byte from tzcnt. This keep L(return_vec_3) in one
|
||||
+ fetch block and the entire L(*return_vec_0_1_2_3) in 1 cache
|
||||
+ line. */
|
||||
+ bsfl %ecx, %ecx
|
||||
+# ifdef USE_AS_WMEMCMP
|
||||
+ movl (VEC_SIZE * 3)(%rdi, %rcx, CHAR_SIZE), %eax
|
||||
+ xorl %edx, %edx
|
||||
+ cmpl (VEC_SIZE * 3)(%rsi, %rcx, CHAR_SIZE), %eax
|
||||
+ setg %dl
|
||||
+ leal -1(%rdx, %rdx), %eax
|
||||
+# else
|
||||
+ movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax
|
||||
+ movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx
|
||||
+ subl %ecx, %eax
|
||||
+# endif
|
||||
ret
|
||||
|
||||
.p2align 4
|
||||
@@ -209,10 +240,11 @@ L(return_vec_0):
|
||||
# endif
|
||||
ret
|
||||
|
||||
- /* NB: No p2align necessary. Alignment % 16 is naturally 1
|
||||
- which is good enough for a target not in a loop. */
|
||||
+ .p2align 4
|
||||
L(return_vec_1):
|
||||
- tzcntl %eax, %eax
|
||||
+ /* bsf saves 1 byte over tzcnt and keeps L(return_vec_1) in one
|
||||
+ fetch block. */
|
||||
+ bsfl %eax, %eax
|
||||
# ifdef USE_AS_WMEMCMP
|
||||
movl VEC_SIZE(%rdi, %rax, CHAR_SIZE), %ecx
|
||||
xorl %edx, %edx
|
||||
@@ -226,10 +258,11 @@ L(return_vec_1):
|
||||
# endif
|
||||
ret
|
||||
|
||||
- /* NB: No p2align necessary. Alignment % 16 is naturally 2
|
||||
- which is good enough for a target not in a loop. */
|
||||
+ .p2align 4,, 10
|
||||
L(return_vec_2):
|
||||
- tzcntl %eax, %eax
|
||||
+ /* bsf saves 1 byte over tzcnt and keeps L(return_vec_2) in one
|
||||
+ fetch block. */
|
||||
+ bsfl %eax, %eax
|
||||
# ifdef USE_AS_WMEMCMP
|
||||
movl (VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %ecx
|
||||
xorl %edx, %edx
|
||||
@@ -243,40 +276,6 @@ L(return_vec_2):
|
||||
# endif
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
-L(8x_return_vec_0_1_2_3):
|
||||
- /* Returning from L(more_8x_vec) requires restoring rsi. */
|
||||
- addq %rdi, %rsi
|
||||
-L(return_vec_0_1_2_3):
|
||||
- VPCMP $4, %YMM1, %YMM0, %k0
|
||||
- kmovd %k0, %eax
|
||||
- testl %eax, %eax
|
||||
- jnz L(return_vec_0)
|
||||
-
|
||||
- VPCMP $4, %YMM2, %YMM0, %k0
|
||||
- kmovd %k0, %eax
|
||||
- testl %eax, %eax
|
||||
- jnz L(return_vec_1)
|
||||
-
|
||||
- VPCMP $4, %YMM3, %YMM0, %k0
|
||||
- kmovd %k0, %eax
|
||||
- testl %eax, %eax
|
||||
- jnz L(return_vec_2)
|
||||
-L(return_vec_3):
|
||||
- tzcntl %ecx, %ecx
|
||||
-# ifdef USE_AS_WMEMCMP
|
||||
- movl (VEC_SIZE * 3)(%rdi, %rcx, CHAR_SIZE), %eax
|
||||
- xorl %edx, %edx
|
||||
- cmpl (VEC_SIZE * 3)(%rsi, %rcx, CHAR_SIZE), %eax
|
||||
- setg %dl
|
||||
- leal -1(%rdx, %rdx), %eax
|
||||
-# else
|
||||
- movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax
|
||||
- movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx
|
||||
- subl %ecx, %eax
|
||||
-# endif
|
||||
- ret
|
||||
-
|
||||
.p2align 4
|
||||
L(more_8x_vec):
|
||||
/* Set end of s1 in rdx. */
|
||||
@@ -288,21 +287,19 @@ L(more_8x_vec):
|
||||
andq $-VEC_SIZE, %rdi
|
||||
/* Adjust because first 4x vec where check already. */
|
||||
subq $-(VEC_SIZE * 4), %rdi
|
||||
+
|
||||
.p2align 4
|
||||
L(loop_4x_vec):
|
||||
VMOVU (%rsi, %rdi), %YMM1
|
||||
vpxorq (%rdi), %YMM1, %YMM1
|
||||
-
|
||||
VMOVU VEC_SIZE(%rsi, %rdi), %YMM2
|
||||
vpxorq VEC_SIZE(%rdi), %YMM2, %YMM2
|
||||
-
|
||||
VMOVU (VEC_SIZE * 2)(%rsi, %rdi), %YMM3
|
||||
vpxorq (VEC_SIZE * 2)(%rdi), %YMM3, %YMM3
|
||||
- vpternlogd $0xfe, %YMM1, %YMM2, %YMM3
|
||||
-
|
||||
VMOVU (VEC_SIZE * 3)(%rsi, %rdi), %YMM4
|
||||
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM3, %YMM4
|
||||
- VPCMP $4, %YMM4, %YMM0, %k1
|
||||
+ vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||
+ vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||
+ VPTEST %YMM4, %YMM4, %k1
|
||||
kmovd %k1, %ecx
|
||||
testl %ecx, %ecx
|
||||
jnz L(8x_return_vec_0_1_2_3)
|
||||
@@ -319,28 +316,25 @@ L(loop_4x_vec):
|
||||
cmpl $(VEC_SIZE * 2), %edi
|
||||
jae L(8x_last_2x_vec)
|
||||
|
||||
+ vpxorq (VEC_SIZE * 2)(%rdx), %YMM3, %YMM3
|
||||
+
|
||||
VMOVU (%rsi, %rdx), %YMM1
|
||||
vpxorq (%rdx), %YMM1, %YMM1
|
||||
|
||||
VMOVU VEC_SIZE(%rsi, %rdx), %YMM2
|
||||
vpxorq VEC_SIZE(%rdx), %YMM2, %YMM2
|
||||
-
|
||||
- vpxorq (VEC_SIZE * 2)(%rdx), %YMM3, %YMM3
|
||||
- vpternlogd $0xfe, %YMM1, %YMM2, %YMM3
|
||||
-
|
||||
VMOVU (VEC_SIZE * 3)(%rsi, %rdx), %YMM4
|
||||
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdx), %YMM3, %YMM4
|
||||
- VPCMP $4, %YMM4, %YMM0, %k1
|
||||
+ vpternlogd $0xde, (VEC_SIZE * 3)(%rdx), %YMM1, %YMM4
|
||||
+ vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||
+ VPTEST %YMM4, %YMM4, %k1
|
||||
kmovd %k1, %ecx
|
||||
- /* Restore s1 pointer to rdi. */
|
||||
- movq %rdx, %rdi
|
||||
testl %ecx, %ecx
|
||||
- jnz L(8x_return_vec_0_1_2_3)
|
||||
+ jnz L(8x_end_return_vec_0_1_2_3)
|
||||
/* NB: eax must be zero to reach here. */
|
||||
ret
|
||||
|
||||
/* Only entry is from L(more_8x_vec). */
|
||||
- .p2align 4
|
||||
+ .p2align 4,, 10
|
||||
L(8x_last_2x_vec):
|
||||
VPCMP $4, (VEC_SIZE * 2)(%rdx), %YMM3, %k1
|
||||
kmovd %k1, %eax
|
||||
@@ -355,7 +349,31 @@ L(8x_last_1x_vec):
|
||||
jnz L(8x_return_vec_3)
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
+ /* Not ideally aligned (at offset +9 bytes in fetch block) but
|
||||
+ not aligning keeps it in the same cache line as
|
||||
+ L(8x_last_1x/2x_vec) so likely worth it. As well, saves code
|
||||
+ size. */
|
||||
+ .p2align 4,, 4
|
||||
+L(8x_return_vec_2):
|
||||
+ subq $VEC_SIZE, %rdx
|
||||
+L(8x_return_vec_3):
|
||||
+ bsfl %eax, %eax
|
||||
+# ifdef USE_AS_WMEMCMP
|
||||
+ leaq (%rdx, %rax, CHAR_SIZE), %rax
|
||||
+ movl (VEC_SIZE * 3)(%rax), %ecx
|
||||
+ xorl %edx, %edx
|
||||
+ cmpl (VEC_SIZE * 3)(%rsi, %rax), %ecx
|
||||
+ setg %dl
|
||||
+ leal -1(%rdx, %rdx), %eax
|
||||
+# else
|
||||
+ addq %rdx, %rax
|
||||
+ movzbl (VEC_SIZE * 3)(%rsi, %rax), %ecx
|
||||
+ movzbl (VEC_SIZE * 3)(%rax), %eax
|
||||
+ subl %ecx, %eax
|
||||
+# endif
|
||||
+ ret
|
||||
+
|
||||
+ .p2align 4,, 10
|
||||
L(last_2x_vec):
|
||||
/* Check second to last VEC. */
|
||||
VMOVU -(VEC_SIZE * 2)(%rsi, %rdx, CHAR_SIZE), %YMM1
|
||||
@@ -374,26 +392,49 @@ L(last_1x_vec):
|
||||
jnz L(return_vec_0_end)
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
-L(8x_return_vec_2):
|
||||
- subq $VEC_SIZE, %rdx
|
||||
-L(8x_return_vec_3):
|
||||
- tzcntl %eax, %eax
|
||||
+ .p2align 4,, 10
|
||||
+L(return_vec_1_end):
|
||||
+ /* Use bsf to save code size. This is necessary to have
|
||||
+ L(one_or_less) fit in aligning bytes between. */
|
||||
+ bsfl %eax, %eax
|
||||
+ addl %edx, %eax
|
||||
# ifdef USE_AS_WMEMCMP
|
||||
- leaq (%rdx, %rax, CHAR_SIZE), %rax
|
||||
- movl (VEC_SIZE * 3)(%rax), %ecx
|
||||
+ movl -(VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %ecx
|
||||
xorl %edx, %edx
|
||||
- cmpl (VEC_SIZE * 3)(%rsi, %rax), %ecx
|
||||
+ cmpl -(VEC_SIZE * 2)(%rsi, %rax, CHAR_SIZE), %ecx
|
||||
setg %dl
|
||||
leal -1(%rdx, %rdx), %eax
|
||||
# else
|
||||
- addq %rdx, %rax
|
||||
- movzbl (VEC_SIZE * 3)(%rsi, %rax), %ecx
|
||||
- movzbl (VEC_SIZE * 3)(%rax), %eax
|
||||
+ movzbl -(VEC_SIZE * 2)(%rsi, %rax), %ecx
|
||||
+ movzbl -(VEC_SIZE * 2)(%rdi, %rax), %eax
|
||||
subl %ecx, %eax
|
||||
# endif
|
||||
ret
|
||||
|
||||
+ /* NB: L(one_or_less) fits in alignment padding between
|
||||
+ L(return_vec_1_end) and L(return_vec_0_end). */
|
||||
+# ifdef USE_AS_WMEMCMP
|
||||
+L(one_or_less):
|
||||
+ jb L(zero)
|
||||
+ movl (%rdi), %ecx
|
||||
+ xorl %edx, %edx
|
||||
+ cmpl (%rsi), %ecx
|
||||
+ je L(zero)
|
||||
+ setg %dl
|
||||
+ leal -1(%rdx, %rdx), %eax
|
||||
+ ret
|
||||
+# else
|
||||
+L(one_or_less):
|
||||
+ jb L(zero)
|
||||
+ movzbl (%rsi), %ecx
|
||||
+ movzbl (%rdi), %eax
|
||||
+ subl %ecx, %eax
|
||||
+ ret
|
||||
+# endif
|
||||
+L(zero):
|
||||
+ xorl %eax, %eax
|
||||
+ ret
|
||||
+
|
||||
.p2align 4
|
||||
L(return_vec_0_end):
|
||||
tzcntl %eax, %eax
|
||||
@@ -412,23 +453,56 @@ L(return_vec_0_end):
|
||||
ret
|
||||
|
||||
.p2align 4
|
||||
-L(return_vec_1_end):
|
||||
+L(less_vec):
|
||||
+ /* Check if one or less CHAR. This is necessary for size == 0
|
||||
+ but is also faster for size == CHAR_SIZE. */
|
||||
+ cmpl $1, %edx
|
||||
+ jbe L(one_or_less)
|
||||
+
|
||||
+ /* Check if loading one VEC from either s1 or s2 could cause a
|
||||
+ page cross. This can have false positives but is by far the
|
||||
+ fastest method. */
|
||||
+ movl %edi, %eax
|
||||
+ orl %esi, %eax
|
||||
+ andl $(PAGE_SIZE - 1), %eax
|
||||
+ cmpl $(PAGE_SIZE - VEC_SIZE), %eax
|
||||
+ jg L(page_cross_less_vec)
|
||||
+
|
||||
+ /* No page cross possible. */
|
||||
+ VMOVU (%rsi), %YMM2
|
||||
+ VPCMP $4, (%rdi), %YMM2, %k1
|
||||
+ kmovd %k1, %eax
|
||||
+ /* Check if any matches where in bounds. Intentionally not
|
||||
+ storing result in eax to limit dependency chain if it goes to
|
||||
+ L(return_vec_0_lv). */
|
||||
+ bzhil %edx, %eax, %edx
|
||||
+ jnz L(return_vec_0_lv)
|
||||
+ xorl %eax, %eax
|
||||
+ ret
|
||||
+
|
||||
+ /* Essentially duplicate of L(return_vec_0). Ends up not costing
|
||||
+ any code as shrinks L(less_vec) by allowing 2-byte encoding of
|
||||
+ the jump and ends up fitting in aligning bytes. As well fits on
|
||||
+ same cache line as L(less_vec) so also saves a line from having
|
||||
+ to be fetched on cold calls to memcmp. */
|
||||
+ .p2align 4,, 4
|
||||
+L(return_vec_0_lv):
|
||||
tzcntl %eax, %eax
|
||||
- addl %edx, %eax
|
||||
# ifdef USE_AS_WMEMCMP
|
||||
- movl -(VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %ecx
|
||||
+ movl (%rdi, %rax, CHAR_SIZE), %ecx
|
||||
xorl %edx, %edx
|
||||
- cmpl -(VEC_SIZE * 2)(%rsi, %rax, CHAR_SIZE), %ecx
|
||||
+ cmpl (%rsi, %rax, CHAR_SIZE), %ecx
|
||||
+ /* NB: no partial register stall here because xorl zero idiom
|
||||
+ above. */
|
||||
setg %dl
|
||||
leal -1(%rdx, %rdx), %eax
|
||||
# else
|
||||
- movzbl -(VEC_SIZE * 2)(%rsi, %rax), %ecx
|
||||
- movzbl -(VEC_SIZE * 2)(%rdi, %rax), %eax
|
||||
+ movzbl (%rsi, %rax), %ecx
|
||||
+ movzbl (%rdi, %rax), %eax
|
||||
subl %ecx, %eax
|
||||
# endif
|
||||
ret
|
||||
|
||||
-
|
||||
.p2align 4
|
||||
L(page_cross_less_vec):
|
||||
/* if USE_AS_WMEMCMP it can only be 0, 4, 8, 12, 16, 20, 24, 28
|
||||
@@ -439,108 +513,84 @@ L(page_cross_less_vec):
|
||||
cmpl $8, %edx
|
||||
jae L(between_8_15)
|
||||
cmpl $4, %edx
|
||||
- jae L(between_4_7)
|
||||
-L(between_2_3):
|
||||
- /* Load as big endian to avoid branches. */
|
||||
- movzwl (%rdi), %eax
|
||||
- movzwl (%rsi), %ecx
|
||||
- shll $8, %eax
|
||||
- shll $8, %ecx
|
||||
- bswap %eax
|
||||
- bswap %ecx
|
||||
- movzbl -1(%rdi, %rdx), %edi
|
||||
- movzbl -1(%rsi, %rdx), %esi
|
||||
- orl %edi, %eax
|
||||
- orl %esi, %ecx
|
||||
- /* Subtraction is okay because the upper 8 bits are zero. */
|
||||
- subl %ecx, %eax
|
||||
- ret
|
||||
- .p2align 4
|
||||
-L(one_or_less):
|
||||
- jb L(zero)
|
||||
- movzbl (%rsi), %ecx
|
||||
- movzbl (%rdi), %eax
|
||||
- subl %ecx, %eax
|
||||
+ jb L(between_2_3)
|
||||
+
|
||||
+ /* Load as big endian with overlapping movbe to avoid branches.
|
||||
+ */
|
||||
+ movbe (%rdi), %eax
|
||||
+ movbe (%rsi), %ecx
|
||||
+ shlq $32, %rax
|
||||
+ shlq $32, %rcx
|
||||
+ movbe -4(%rdi, %rdx), %edi
|
||||
+ movbe -4(%rsi, %rdx), %esi
|
||||
+ orq %rdi, %rax
|
||||
+ orq %rsi, %rcx
|
||||
+ subq %rcx, %rax
|
||||
+ /* edx is guranteed to be positive int32 in range [4, 7]. */
|
||||
+ cmovne %edx, %eax
|
||||
+ /* ecx is -1 if rcx > rax. Otherwise 0. */
|
||||
+ sbbl %ecx, %ecx
|
||||
+ /* If rcx > rax, then ecx is 0 and eax is positive. If rcx ==
|
||||
+ rax then eax and ecx are zero. If rax < rax then ecx is -1 so
|
||||
+ eax doesn't matter. */
|
||||
+ orl %ecx, %eax
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
+ .p2align 4,, 8
|
||||
L(between_8_15):
|
||||
# endif
|
||||
/* If USE_AS_WMEMCMP fall through into 8-15 byte case. */
|
||||
- vmovq (%rdi), %XMM1
|
||||
- vmovq (%rsi), %XMM2
|
||||
- VPCMP $4, %XMM1, %XMM2, %k1
|
||||
+ vmovq (%rdi), %xmm1
|
||||
+ vmovq (%rsi), %xmm2
|
||||
+ VPCMP $4, %xmm1, %xmm2, %k1
|
||||
kmovd %k1, %eax
|
||||
testl %eax, %eax
|
||||
- jnz L(return_vec_0)
|
||||
+ jnz L(return_vec_0_lv)
|
||||
/* Use overlapping loads to avoid branches. */
|
||||
- leaq -8(%rdi, %rdx, CHAR_SIZE), %rdi
|
||||
- leaq -8(%rsi, %rdx, CHAR_SIZE), %rsi
|
||||
- vmovq (%rdi), %XMM1
|
||||
- vmovq (%rsi), %XMM2
|
||||
- VPCMP $4, %XMM1, %XMM2, %k1
|
||||
+ vmovq -8(%rdi, %rdx, CHAR_SIZE), %xmm1
|
||||
+ vmovq -8(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||
+ VPCMP $4, %xmm1, %xmm2, %k1
|
||||
+ addl $(CHAR_PER_VEC - (8 / CHAR_SIZE)), %edx
|
||||
kmovd %k1, %eax
|
||||
testl %eax, %eax
|
||||
- jnz L(return_vec_0)
|
||||
- ret
|
||||
-
|
||||
- .p2align 4
|
||||
-L(zero):
|
||||
- xorl %eax, %eax
|
||||
+ jnz L(return_vec_0_end)
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
+ .p2align 4,, 8
|
||||
L(between_16_31):
|
||||
/* From 16 to 31 bytes. No branch when size == 16. */
|
||||
- VMOVU (%rsi), %XMM2
|
||||
- VPCMP $4, (%rdi), %XMM2, %k1
|
||||
+
|
||||
+ /* Use movups to save code size. */
|
||||
+ movups (%rsi), %xmm2
|
||||
+ VPCMP $4, (%rdi), %xmm2, %k1
|
||||
kmovd %k1, %eax
|
||||
testl %eax, %eax
|
||||
- jnz L(return_vec_0)
|
||||
-
|
||||
+ jnz L(return_vec_0_lv)
|
||||
/* Use overlapping loads to avoid branches. */
|
||||
-
|
||||
- VMOVU -16(%rsi, %rdx, CHAR_SIZE), %XMM2
|
||||
- leaq -16(%rdi, %rdx, CHAR_SIZE), %rdi
|
||||
- leaq -16(%rsi, %rdx, CHAR_SIZE), %rsi
|
||||
- VPCMP $4, (%rdi), %XMM2, %k1
|
||||
+ movups -16(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||
+ VPCMP $4, -16(%rdi, %rdx, CHAR_SIZE), %xmm2, %k1
|
||||
+ addl $(CHAR_PER_VEC - (16 / CHAR_SIZE)), %edx
|
||||
kmovd %k1, %eax
|
||||
testl %eax, %eax
|
||||
- jnz L(return_vec_0)
|
||||
- ret
|
||||
-
|
||||
-# ifdef USE_AS_WMEMCMP
|
||||
- .p2align 4
|
||||
-L(one_or_less):
|
||||
- jb L(zero)
|
||||
- movl (%rdi), %ecx
|
||||
- xorl %edx, %edx
|
||||
- cmpl (%rsi), %ecx
|
||||
- je L(zero)
|
||||
- setg %dl
|
||||
- leal -1(%rdx, %rdx), %eax
|
||||
+ jnz L(return_vec_0_end)
|
||||
ret
|
||||
-# else
|
||||
|
||||
- .p2align 4
|
||||
-L(between_4_7):
|
||||
- /* Load as big endian with overlapping movbe to avoid branches.
|
||||
- */
|
||||
- movbe (%rdi), %eax
|
||||
- movbe (%rsi), %ecx
|
||||
- shlq $32, %rax
|
||||
- shlq $32, %rcx
|
||||
- movbe -4(%rdi, %rdx), %edi
|
||||
- movbe -4(%rsi, %rdx), %esi
|
||||
- orq %rdi, %rax
|
||||
- orq %rsi, %rcx
|
||||
- subq %rcx, %rax
|
||||
- jz L(zero_4_7)
|
||||
- sbbl %eax, %eax
|
||||
- orl $1, %eax
|
||||
-L(zero_4_7):
|
||||
+# ifndef USE_AS_WMEMCMP
|
||||
+L(between_2_3):
|
||||
+ /* Load as big endian to avoid branches. */
|
||||
+ movzwl (%rdi), %eax
|
||||
+ movzwl (%rsi), %ecx
|
||||
+ shll $8, %eax
|
||||
+ shll $8, %ecx
|
||||
+ bswap %eax
|
||||
+ bswap %ecx
|
||||
+ movzbl -1(%rdi, %rdx), %edi
|
||||
+ movzbl -1(%rsi, %rdx), %esi
|
||||
+ orl %edi, %eax
|
||||
+ orl %esi, %ecx
|
||||
+ /* Subtraction is okay because the upper 8 bits are zero. */
|
||||
+ subl %ecx, %eax
|
||||
ret
|
||||
# endif
|
||||
-
|
||||
END (MEMCMP)
|
||||
#endif
|
497
SOURCES/glibc-upstream-2.34-176.patch
Normal file
497
SOURCES/glibc-upstream-2.34-176.patch
Normal file
@ -0,0 +1,497 @@
|
||||
commit 6d18a93dbbde2958001d65dff3080beed7ae675a
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Mon Sep 20 16:20:15 2021 -0500
|
||||
|
||||
x86: Optimize memset-vec-unaligned-erms.S
|
||||
|
||||
No bug.
|
||||
|
||||
Optimization are
|
||||
|
||||
1. change control flow for L(more_2x_vec) to fall through to loop and
|
||||
jump for L(less_4x_vec) and L(less_8x_vec). This uses less code
|
||||
size and saves jumps for length > 4x VEC_SIZE.
|
||||
|
||||
2. For EVEX/AVX512 move L(less_vec) closer to entry.
|
||||
|
||||
3. Avoid complex address mode for length > 2x VEC_SIZE
|
||||
|
||||
4. Slightly better aligning code for the loop from the perspective of
|
||||
code size and uops.
|
||||
|
||||
5. Align targets so they make full use of their fetch block and if
|
||||
possible cache line.
|
||||
|
||||
6. Try and reduce total number of icache lines that will need to be
|
||||
pulled in for a given length.
|
||||
|
||||
7. Include "local" version of stosb target. For AVX2/EVEX/AVX512
|
||||
jumping to the stosb target in the sse2 code section will almost
|
||||
certainly be to a new page. The new version does increase code size
|
||||
marginally by duplicating the target but should get better iTLB
|
||||
behavior as a result.
|
||||
|
||||
test-memset, test-wmemset, and test-bzero are all passing.
|
||||
|
||||
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
(cherry picked from commit e59ced238482fd71f3e493717f14f6507346741e)
|
||||
|
||||
diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S
|
||||
index 7d4a327eba29ecb4..0137eba4cdd9f830 100644
|
||||
--- a/sysdeps/x86_64/memset.S
|
||||
+++ b/sysdeps/x86_64/memset.S
|
||||
@@ -18,13 +18,15 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sysdep.h>
|
||||
+#define USE_WITH_SSE2 1
|
||||
|
||||
#define VEC_SIZE 16
|
||||
+#define MOV_SIZE 3
|
||||
+#define RET_SIZE 1
|
||||
+
|
||||
#define VEC(i) xmm##i
|
||||
-/* Don't use movups and movaps since it will get larger nop paddings for
|
||||
- alignment. */
|
||||
-#define VMOVU movdqu
|
||||
-#define VMOVA movdqa
|
||||
+#define VMOVU movups
|
||||
+#define VMOVA movaps
|
||||
|
||||
#define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \
|
||||
movd d, %xmm0; \
|
||||
diff --git a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S
|
||||
index ae0860f36a47d594..1af668af0aeda59e 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S
|
||||
@@ -1,8 +1,14 @@
|
||||
#if IS_IN (libc)
|
||||
+# define USE_WITH_AVX2 1
|
||||
+
|
||||
# define VEC_SIZE 32
|
||||
+# define MOV_SIZE 4
|
||||
+# define RET_SIZE 4
|
||||
+
|
||||
# define VEC(i) ymm##i
|
||||
-# define VMOVU vmovdqu
|
||||
-# define VMOVA vmovdqa
|
||||
+
|
||||
+# define VMOVU vmovdqu
|
||||
+# define VMOVA vmovdqa
|
||||
|
||||
# define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \
|
||||
vmovd d, %xmm0; \
|
||||
diff --git a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S
|
||||
index 8ad842fc2f140527..f14d6f8493c21a36 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S
|
||||
@@ -1,11 +1,18 @@
|
||||
#if IS_IN (libc)
|
||||
+# define USE_WITH_AVX512 1
|
||||
+
|
||||
# define VEC_SIZE 64
|
||||
+# define MOV_SIZE 6
|
||||
+# define RET_SIZE 1
|
||||
+
|
||||
# define XMM0 xmm16
|
||||
# define YMM0 ymm16
|
||||
# define VEC0 zmm16
|
||||
# define VEC(i) VEC##i
|
||||
-# define VMOVU vmovdqu64
|
||||
-# define VMOVA vmovdqa64
|
||||
+
|
||||
+# define VMOVU vmovdqu64
|
||||
+# define VMOVA vmovdqa64
|
||||
+
|
||||
# define VZEROUPPER
|
||||
|
||||
# define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \
|
||||
diff --git a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S
|
||||
index 640f092903302ad0..64b09e77cc20cc42 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S
|
||||
@@ -1,11 +1,18 @@
|
||||
#if IS_IN (libc)
|
||||
+# define USE_WITH_EVEX 1
|
||||
+
|
||||
# define VEC_SIZE 32
|
||||
+# define MOV_SIZE 6
|
||||
+# define RET_SIZE 1
|
||||
+
|
||||
# define XMM0 xmm16
|
||||
# define YMM0 ymm16
|
||||
# define VEC0 ymm16
|
||||
# define VEC(i) VEC##i
|
||||
-# define VMOVU vmovdqu64
|
||||
-# define VMOVA vmovdqa64
|
||||
+
|
||||
+# define VMOVU vmovdqu64
|
||||
+# define VMOVA vmovdqa64
|
||||
+
|
||||
# define VZEROUPPER
|
||||
|
||||
# define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \
|
||||
diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
|
||||
index ff196844a093dc3b..e723413a664c088f 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
|
||||
@@ -63,8 +63,27 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+#if VEC_SIZE == 64
|
||||
+# define LOOP_4X_OFFSET (VEC_SIZE * 4)
|
||||
+#else
|
||||
+# define LOOP_4X_OFFSET (0)
|
||||
+#endif
|
||||
+
|
||||
+#if defined USE_WITH_EVEX || defined USE_WITH_AVX512
|
||||
+# define END_REG rcx
|
||||
+# define LOOP_REG rdi
|
||||
+#else
|
||||
+# define END_REG rdi
|
||||
+# define LOOP_REG rdx
|
||||
+#endif
|
||||
+
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
+/* Macro to calculate size of small memset block for aligning
|
||||
+ purposes. */
|
||||
+#define SMALL_MEMSET_ALIGN(mov_sz, ret_sz) (2 * (mov_sz) + (ret_sz) + 1)
|
||||
+
|
||||
+
|
||||
#ifndef SECTION
|
||||
# error SECTION is not defined!
|
||||
#endif
|
||||
@@ -74,6 +93,7 @@
|
||||
ENTRY (__bzero)
|
||||
mov %RDI_LP, %RAX_LP /* Set return value. */
|
||||
mov %RSI_LP, %RDX_LP /* Set n. */
|
||||
+ xorl %esi, %esi
|
||||
pxor %XMM0, %XMM0
|
||||
jmp L(entry_from_bzero)
|
||||
END (__bzero)
|
||||
@@ -158,7 +178,7 @@ ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms))
|
||||
END_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms))
|
||||
# endif
|
||||
|
||||
-ENTRY (MEMSET_SYMBOL (__memset, unaligned_erms))
|
||||
+ENTRY_P2ALIGN (MEMSET_SYMBOL (__memset, unaligned_erms), 6)
|
||||
MEMSET_VDUP_TO_VEC0_AND_SET_RETURN (%esi, %rdi)
|
||||
# ifdef __ILP32__
|
||||
/* Clear the upper 32 bits. */
|
||||
@@ -168,75 +188,43 @@ ENTRY (MEMSET_SYMBOL (__memset, unaligned_erms))
|
||||
jb L(less_vec)
|
||||
cmp $(VEC_SIZE * 2), %RDX_LP
|
||||
ja L(stosb_more_2x_vec)
|
||||
- /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */
|
||||
- VMOVU %VEC(0), -VEC_SIZE(%rdi,%rdx)
|
||||
- VMOVU %VEC(0), (%rdi)
|
||||
+ /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE.
|
||||
+ */
|
||||
+ VMOVU %VEC(0), (%rax)
|
||||
+ VMOVU %VEC(0), -VEC_SIZE(%rax, %rdx)
|
||||
VZEROUPPER_RETURN
|
||||
-
|
||||
- .p2align 4
|
||||
-L(stosb_more_2x_vec):
|
||||
- cmp __x86_rep_stosb_threshold(%rip), %RDX_LP
|
||||
- ja L(stosb)
|
||||
-#else
|
||||
- .p2align 4
|
||||
#endif
|
||||
-L(more_2x_vec):
|
||||
- /* Stores to first 2x VEC before cmp as any path forward will
|
||||
- require it. */
|
||||
- VMOVU %VEC(0), (%rdi)
|
||||
- VMOVU %VEC(0), VEC_SIZE(%rdi)
|
||||
- cmpq $(VEC_SIZE * 4), %rdx
|
||||
- ja L(loop_start)
|
||||
- VMOVU %VEC(0), -(VEC_SIZE * 2)(%rdi,%rdx)
|
||||
- VMOVU %VEC(0), -VEC_SIZE(%rdi,%rdx)
|
||||
-L(return):
|
||||
-#if VEC_SIZE > 16
|
||||
- ZERO_UPPER_VEC_REGISTERS_RETURN
|
||||
+
|
||||
+ .p2align 4,, 10
|
||||
+L(last_2x_vec):
|
||||
+#ifdef USE_LESS_VEC_MASK_STORE
|
||||
+ VMOVU %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%rcx)
|
||||
+ VMOVU %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%rcx)
|
||||
#else
|
||||
- ret
|
||||
+ VMOVU %VEC(0), (VEC_SIZE * -2)(%rdi)
|
||||
+ VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi)
|
||||
#endif
|
||||
+ VZEROUPPER_RETURN
|
||||
|
||||
-L(loop_start):
|
||||
- VMOVU %VEC(0), (VEC_SIZE * 2)(%rdi)
|
||||
- VMOVU %VEC(0), (VEC_SIZE * 3)(%rdi)
|
||||
- cmpq $(VEC_SIZE * 8), %rdx
|
||||
- jbe L(loop_end)
|
||||
- andq $-(VEC_SIZE * 2), %rdi
|
||||
- subq $-(VEC_SIZE * 4), %rdi
|
||||
- leaq -(VEC_SIZE * 4)(%rax, %rdx), %rcx
|
||||
- .p2align 4
|
||||
-L(loop):
|
||||
- VMOVA %VEC(0), (%rdi)
|
||||
- VMOVA %VEC(0), VEC_SIZE(%rdi)
|
||||
- VMOVA %VEC(0), (VEC_SIZE * 2)(%rdi)
|
||||
- VMOVA %VEC(0), (VEC_SIZE * 3)(%rdi)
|
||||
- subq $-(VEC_SIZE * 4), %rdi
|
||||
- cmpq %rcx, %rdi
|
||||
- jb L(loop)
|
||||
-L(loop_end):
|
||||
- /* NB: rax is set as ptr in MEMSET_VDUP_TO_VEC0_AND_SET_RETURN.
|
||||
- rdx as length is also unchanged. */
|
||||
- VMOVU %VEC(0), -(VEC_SIZE * 4)(%rax, %rdx)
|
||||
- VMOVU %VEC(0), -(VEC_SIZE * 3)(%rax, %rdx)
|
||||
- VMOVU %VEC(0), -(VEC_SIZE * 2)(%rax, %rdx)
|
||||
- VMOVU %VEC(0), -VEC_SIZE(%rax, %rdx)
|
||||
- VZEROUPPER_SHORT_RETURN
|
||||
-
|
||||
- .p2align 4
|
||||
+ /* If have AVX512 mask instructions put L(less_vec) close to
|
||||
+ entry as it doesn't take much space and is likely a hot target.
|
||||
+ */
|
||||
+#ifdef USE_LESS_VEC_MASK_STORE
|
||||
+ .p2align 4,, 10
|
||||
L(less_vec):
|
||||
/* Less than 1 VEC. */
|
||||
# if VEC_SIZE != 16 && VEC_SIZE != 32 && VEC_SIZE != 64
|
||||
# error Unsupported VEC_SIZE!
|
||||
# endif
|
||||
-# ifdef USE_LESS_VEC_MASK_STORE
|
||||
/* Clear high bits from edi. Only keeping bits relevant to page
|
||||
cross check. Note that we are using rax which is set in
|
||||
- MEMSET_VDUP_TO_VEC0_AND_SET_RETURN as ptr from here on out.
|
||||
- */
|
||||
+ MEMSET_VDUP_TO_VEC0_AND_SET_RETURN as ptr from here on out. */
|
||||
andl $(PAGE_SIZE - 1), %edi
|
||||
- /* Check if VEC_SIZE store cross page. Mask stores suffer serious
|
||||
- performance degradation when it has to fault supress. */
|
||||
+ /* Check if VEC_SIZE store cross page. Mask stores suffer
|
||||
+ serious performance degradation when it has to fault supress.
|
||||
+ */
|
||||
cmpl $(PAGE_SIZE - VEC_SIZE), %edi
|
||||
+ /* This is generally considered a cold target. */
|
||||
ja L(cross_page)
|
||||
# if VEC_SIZE > 32
|
||||
movq $-1, %rcx
|
||||
@@ -247,58 +235,185 @@ L(less_vec):
|
||||
bzhil %edx, %ecx, %ecx
|
||||
kmovd %ecx, %k1
|
||||
# endif
|
||||
- vmovdqu8 %VEC(0), (%rax) {%k1}
|
||||
+ vmovdqu8 %VEC(0), (%rax){%k1}
|
||||
VZEROUPPER_RETURN
|
||||
|
||||
+# if defined USE_MULTIARCH && IS_IN (libc)
|
||||
+ /* Include L(stosb_local) here if including L(less_vec) between
|
||||
+ L(stosb_more_2x_vec) and ENTRY. This is to cache align the
|
||||
+ L(stosb_more_2x_vec) target. */
|
||||
+ .p2align 4,, 10
|
||||
+L(stosb_local):
|
||||
+ movzbl %sil, %eax
|
||||
+ mov %RDX_LP, %RCX_LP
|
||||
+ mov %RDI_LP, %RDX_LP
|
||||
+ rep stosb
|
||||
+ mov %RDX_LP, %RAX_LP
|
||||
+ VZEROUPPER_RETURN
|
||||
+# endif
|
||||
+#endif
|
||||
+
|
||||
+#if defined USE_MULTIARCH && IS_IN (libc)
|
||||
.p2align 4
|
||||
-L(cross_page):
|
||||
+L(stosb_more_2x_vec):
|
||||
+ cmp __x86_rep_stosb_threshold(%rip), %RDX_LP
|
||||
+ ja L(stosb_local)
|
||||
+#endif
|
||||
+ /* Fallthrough goes to L(loop_4x_vec). Tests for memset (2x, 4x]
|
||||
+ and (4x, 8x] jump to target. */
|
||||
+L(more_2x_vec):
|
||||
+
|
||||
+ /* Two different methods of setting up pointers / compare. The
|
||||
+ two methods are based on the fact that EVEX/AVX512 mov
|
||||
+ instructions take more bytes then AVX2/SSE2 mov instructions. As
|
||||
+ well that EVEX/AVX512 machines also have fast LEA_BID. Both
|
||||
+ setup and END_REG to avoid complex address mode. For EVEX/AVX512
|
||||
+ this saves code size and keeps a few targets in one fetch block.
|
||||
+ For AVX2/SSE2 this helps prevent AGU bottlenecks. */
|
||||
+#if defined USE_WITH_EVEX || defined USE_WITH_AVX512
|
||||
+ /* If EVEX/AVX512 compute END_REG - (VEC_SIZE * 4 +
|
||||
+ LOOP_4X_OFFSET) with LEA_BID. */
|
||||
+
|
||||
+ /* END_REG is rcx for EVEX/AVX512. */
|
||||
+ leaq -(VEC_SIZE * 4 + LOOP_4X_OFFSET)(%rdi, %rdx), %END_REG
|
||||
+#endif
|
||||
+
|
||||
+ /* Stores to first 2x VEC before cmp as any path forward will
|
||||
+ require it. */
|
||||
+ VMOVU %VEC(0), (%rax)
|
||||
+ VMOVU %VEC(0), VEC_SIZE(%rax)
|
||||
+
|
||||
+
|
||||
+#if !(defined USE_WITH_EVEX || defined USE_WITH_AVX512)
|
||||
+ /* If AVX2/SSE2 compute END_REG (rdi) with ALU. */
|
||||
+ addq %rdx, %END_REG
|
||||
+#endif
|
||||
+
|
||||
+ cmpq $(VEC_SIZE * 4), %rdx
|
||||
+ jbe L(last_2x_vec)
|
||||
+
|
||||
+ /* Store next 2x vec regardless. */
|
||||
+ VMOVU %VEC(0), (VEC_SIZE * 2)(%rax)
|
||||
+ VMOVU %VEC(0), (VEC_SIZE * 3)(%rax)
|
||||
+
|
||||
+
|
||||
+#if defined USE_WITH_EVEX || defined USE_WITH_AVX512
|
||||
+ /* If LOOP_4X_OFFSET don't readjust LOOP_REG (rdi), just add
|
||||
+ extra offset to addresses in loop. Used for AVX512 to save space
|
||||
+ as no way to get (VEC_SIZE * 4) in imm8. */
|
||||
+# if LOOP_4X_OFFSET == 0
|
||||
+ subq $-(VEC_SIZE * 4), %LOOP_REG
|
||||
# endif
|
||||
-# if VEC_SIZE > 32
|
||||
- cmpb $32, %dl
|
||||
- jae L(between_32_63)
|
||||
+ /* Avoid imm32 compare here to save code size. */
|
||||
+ cmpq %rdi, %rcx
|
||||
+#else
|
||||
+ addq $-(VEC_SIZE * 4), %END_REG
|
||||
+ cmpq $(VEC_SIZE * 8), %rdx
|
||||
+#endif
|
||||
+ jbe L(last_4x_vec)
|
||||
+#if !(defined USE_WITH_EVEX || defined USE_WITH_AVX512)
|
||||
+ /* Set LOOP_REG (rdx). */
|
||||
+ leaq (VEC_SIZE * 4)(%rax), %LOOP_REG
|
||||
+#endif
|
||||
+ /* Align dst for loop. */
|
||||
+ andq $(VEC_SIZE * -2), %LOOP_REG
|
||||
+ .p2align 4
|
||||
+L(loop):
|
||||
+ VMOVA %VEC(0), LOOP_4X_OFFSET(%LOOP_REG)
|
||||
+ VMOVA %VEC(0), (VEC_SIZE + LOOP_4X_OFFSET)(%LOOP_REG)
|
||||
+ VMOVA %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%LOOP_REG)
|
||||
+ VMOVA %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%LOOP_REG)
|
||||
+ subq $-(VEC_SIZE * 4), %LOOP_REG
|
||||
+ cmpq %END_REG, %LOOP_REG
|
||||
+ jb L(loop)
|
||||
+ .p2align 4,, MOV_SIZE
|
||||
+L(last_4x_vec):
|
||||
+ VMOVU %VEC(0), LOOP_4X_OFFSET(%END_REG)
|
||||
+ VMOVU %VEC(0), (VEC_SIZE + LOOP_4X_OFFSET)(%END_REG)
|
||||
+ VMOVU %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%END_REG)
|
||||
+ VMOVU %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%END_REG)
|
||||
+L(return):
|
||||
+#if VEC_SIZE > 16
|
||||
+ ZERO_UPPER_VEC_REGISTERS_RETURN
|
||||
+#else
|
||||
+ ret
|
||||
+#endif
|
||||
+
|
||||
+ .p2align 4,, 10
|
||||
+#ifndef USE_LESS_VEC_MASK_STORE
|
||||
+# if defined USE_MULTIARCH && IS_IN (libc)
|
||||
+ /* If no USE_LESS_VEC_MASK put L(stosb_local) here. Will be in
|
||||
+ range for 2-byte jump encoding. */
|
||||
+L(stosb_local):
|
||||
+ movzbl %sil, %eax
|
||||
+ mov %RDX_LP, %RCX_LP
|
||||
+ mov %RDI_LP, %RDX_LP
|
||||
+ rep stosb
|
||||
+ mov %RDX_LP, %RAX_LP
|
||||
+ VZEROUPPER_RETURN
|
||||
# endif
|
||||
-# if VEC_SIZE > 16
|
||||
- cmpb $16, %dl
|
||||
+ /* Define L(less_vec) only if not otherwise defined. */
|
||||
+ .p2align 4
|
||||
+L(less_vec):
|
||||
+#endif
|
||||
+L(cross_page):
|
||||
+#if VEC_SIZE > 32
|
||||
+ cmpl $32, %edx
|
||||
+ jae L(between_32_63)
|
||||
+#endif
|
||||
+#if VEC_SIZE > 16
|
||||
+ cmpl $16, %edx
|
||||
jae L(between_16_31)
|
||||
-# endif
|
||||
- MOVQ %XMM0, %rcx
|
||||
- cmpb $8, %dl
|
||||
+#endif
|
||||
+ MOVQ %XMM0, %rdi
|
||||
+ cmpl $8, %edx
|
||||
jae L(between_8_15)
|
||||
- cmpb $4, %dl
|
||||
+ cmpl $4, %edx
|
||||
jae L(between_4_7)
|
||||
- cmpb $1, %dl
|
||||
+ cmpl $1, %edx
|
||||
ja L(between_2_3)
|
||||
- jb 1f
|
||||
- movb %cl, (%rax)
|
||||
-1:
|
||||
+ jb L(return)
|
||||
+ movb %sil, (%rax)
|
||||
VZEROUPPER_RETURN
|
||||
-# if VEC_SIZE > 32
|
||||
+
|
||||
+ /* Align small targets only if not doing so would cross a fetch
|
||||
+ line. */
|
||||
+#if VEC_SIZE > 32
|
||||
+ .p2align 4,, SMALL_MEMSET_ALIGN(MOV_SIZE, RET_SIZE)
|
||||
/* From 32 to 63. No branch when size == 32. */
|
||||
L(between_32_63):
|
||||
- VMOVU %YMM0, -32(%rax,%rdx)
|
||||
VMOVU %YMM0, (%rax)
|
||||
+ VMOVU %YMM0, -32(%rax, %rdx)
|
||||
VZEROUPPER_RETURN
|
||||
-# endif
|
||||
-# if VEC_SIZE > 16
|
||||
- /* From 16 to 31. No branch when size == 16. */
|
||||
+#endif
|
||||
+
|
||||
+#if VEC_SIZE >= 32
|
||||
+ .p2align 4,, SMALL_MEMSET_ALIGN(MOV_SIZE, RET_SIZE)
|
||||
L(between_16_31):
|
||||
- VMOVU %XMM0, -16(%rax,%rdx)
|
||||
+ /* From 16 to 31. No branch when size == 16. */
|
||||
VMOVU %XMM0, (%rax)
|
||||
+ VMOVU %XMM0, -16(%rax, %rdx)
|
||||
VZEROUPPER_RETURN
|
||||
-# endif
|
||||
- /* From 8 to 15. No branch when size == 8. */
|
||||
+#endif
|
||||
+
|
||||
+ .p2align 4,, SMALL_MEMSET_ALIGN(3, RET_SIZE)
|
||||
L(between_8_15):
|
||||
- movq %rcx, -8(%rax,%rdx)
|
||||
- movq %rcx, (%rax)
|
||||
+ /* From 8 to 15. No branch when size == 8. */
|
||||
+ movq %rdi, (%rax)
|
||||
+ movq %rdi, -8(%rax, %rdx)
|
||||
VZEROUPPER_RETURN
|
||||
+
|
||||
+ .p2align 4,, SMALL_MEMSET_ALIGN(2, RET_SIZE)
|
||||
L(between_4_7):
|
||||
/* From 4 to 7. No branch when size == 4. */
|
||||
- movl %ecx, -4(%rax,%rdx)
|
||||
- movl %ecx, (%rax)
|
||||
+ movl %edi, (%rax)
|
||||
+ movl %edi, -4(%rax, %rdx)
|
||||
VZEROUPPER_RETURN
|
||||
+
|
||||
+ .p2align 4,, SMALL_MEMSET_ALIGN(3, RET_SIZE)
|
||||
L(between_2_3):
|
||||
/* From 2 to 3. No branch when size == 2. */
|
||||
- movw %cx, -2(%rax,%rdx)
|
||||
- movw %cx, (%rax)
|
||||
+ movw %di, (%rax)
|
||||
+ movb %dil, -1(%rax, %rdx)
|
||||
VZEROUPPER_RETURN
|
||||
END (MEMSET_SYMBOL (__memset, unaligned_erms))
|
40
SOURCES/glibc-upstream-2.34-177.patch
Normal file
40
SOURCES/glibc-upstream-2.34-177.patch
Normal file
@ -0,0 +1,40 @@
|
||||
commit baf3ece63453adac59c5688930324a78ced5b2e4
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Sat Oct 23 01:26:47 2021 -0400
|
||||
|
||||
x86: Replace sse2 instructions with avx in memcmp-evex-movbe.S
|
||||
|
||||
This commit replaces two usages of SSE2 'movups' with AVX 'vmovdqu'.
|
||||
|
||||
it could potentially be dangerous to use SSE2 if this function is ever
|
||||
called without using 'vzeroupper' beforehand. While compilers appear
|
||||
to use 'vzeroupper' before function calls if AVX2 has been used, using
|
||||
SSE2 here is more brittle. Since it is not absolutely necessary it
|
||||
should be avoided.
|
||||
|
||||
It costs 2-extra bytes but the extra bytes should only eat into
|
||||
alignment padding.
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
(cherry picked from commit bad852b61b79503fcb3c5fc379c70f768df3e1fb)
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||
index 2761b54f2e7dea9f..640f6757fac8a356 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||
@@ -561,13 +561,13 @@ L(between_16_31):
|
||||
/* From 16 to 31 bytes. No branch when size == 16. */
|
||||
|
||||
/* Use movups to save code size. */
|
||||
- movups (%rsi), %xmm2
|
||||
+ vmovdqu (%rsi), %xmm2
|
||||
VPCMP $4, (%rdi), %xmm2, %k1
|
||||
kmovd %k1, %eax
|
||||
testl %eax, %eax
|
||||
jnz L(return_vec_0_lv)
|
||||
/* Use overlapping loads to avoid branches. */
|
||||
- movups -16(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||
+ vmovdqu -16(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||
VPCMP $4, -16(%rdi, %rdx, CHAR_SIZE), %xmm2, %k1
|
||||
addl $(CHAR_PER_VEC - (16 / CHAR_SIZE)), %edx
|
||||
kmovd %k1, %eax
|
690
SOURCES/glibc-upstream-2.34-178.patch
Normal file
690
SOURCES/glibc-upstream-2.34-178.patch
Normal file
@ -0,0 +1,690 @@
|
||||
commit f35ad30da4880a1574996df0674986ecf82fa7ae
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Fri Oct 29 12:40:20 2021 -0700
|
||||
|
||||
x86-64: Improve EVEX strcmp with masked load
|
||||
|
||||
In strcmp-evex.S, to compare 2 32-byte strings, replace
|
||||
|
||||
VMOVU (%rdi, %rdx), %YMM0
|
||||
VMOVU (%rsi, %rdx), %YMM1
|
||||
/* Each bit in K0 represents a mismatch in YMM0 and YMM1. */
|
||||
VPCMP $4, %YMM0, %YMM1, %k0
|
||||
VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||
VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||
/* Each bit in K1 represents a NULL in YMM0 or YMM1. */
|
||||
kord %k1, %k2, %k1
|
||||
/* Each bit in K1 represents a NULL or a mismatch. */
|
||||
kord %k0, %k1, %k1
|
||||
kmovd %k1, %ecx
|
||||
testl %ecx, %ecx
|
||||
jne L(last_vector)
|
||||
|
||||
with
|
||||
|
||||
VMOVU (%rdi, %rdx), %YMM0
|
||||
VPTESTM %YMM0, %YMM0, %k2
|
||||
/* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
in YMM0 and 32 bytes at (%rsi, %rdx). */
|
||||
VPCMP $0, (%rsi, %rdx), %YMM0, %k1{%k2}
|
||||
kmovd %k1, %ecx
|
||||
incl %ecx
|
||||
jne L(last_vector)
|
||||
|
||||
It makes EVEX strcmp faster than AVX2 strcmp by up to 40% on Tiger Lake
|
||||
and Ice Lake.
|
||||
|
||||
Co-Authored-By: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
(cherry picked from commit c46e9afb2df5fc9e39ff4d13777e4b4c26e04e55)
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||
index d5aa6daa46c7ed25..82f12ac89bcae20b 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||
@@ -41,6 +41,8 @@
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* Compare packed dwords. */
|
||||
# define VPCMP vpcmpd
|
||||
+# define VPMINU vpminud
|
||||
+# define VPTESTM vptestmd
|
||||
# define SHIFT_REG32 r8d
|
||||
# define SHIFT_REG64 r8
|
||||
/* 1 dword char == 4 bytes. */
|
||||
@@ -48,6 +50,8 @@
|
||||
# else
|
||||
/* Compare packed bytes. */
|
||||
# define VPCMP vpcmpb
|
||||
+# define VPMINU vpminub
|
||||
+# define VPTESTM vptestmb
|
||||
# define SHIFT_REG32 ecx
|
||||
# define SHIFT_REG64 rcx
|
||||
/* 1 byte char == 1 byte. */
|
||||
@@ -67,6 +71,9 @@
|
||||
# define YMM5 ymm22
|
||||
# define YMM6 ymm23
|
||||
# define YMM7 ymm24
|
||||
+# define YMM8 ymm25
|
||||
+# define YMM9 ymm26
|
||||
+# define YMM10 ymm27
|
||||
|
||||
/* Warning!
|
||||
wcscmp/wcsncmp have to use SIGNED comparison for elements.
|
||||
@@ -76,7 +83,7 @@
|
||||
/* The main idea of the string comparison (byte or dword) using 256-bit
|
||||
EVEX instructions consists of comparing (VPCMP) two ymm vectors. The
|
||||
latter can be on either packed bytes or dwords depending on
|
||||
- USE_AS_WCSCMP. In order to check the null char, algorithm keeps the
|
||||
+ USE_AS_WCSCMP. In order to check the null CHAR, algorithm keeps the
|
||||
matched bytes/dwords, requiring 5 EVEX instructions (3 VPCMP and 2
|
||||
KORD). In general, the costs of comparing VEC_SIZE bytes (32-bytes)
|
||||
are 3 VPCMP and 2 KORD instructions, together with VMOVU and ktestd
|
||||
@@ -123,27 +130,21 @@ ENTRY (STRCMP)
|
||||
jg L(cross_page)
|
||||
/* Start comparing 4 vectors. */
|
||||
VMOVU (%rdi), %YMM0
|
||||
- VMOVU (%rsi), %YMM1
|
||||
|
||||
- /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */
|
||||
- VPCMP $4, %YMM0, %YMM1, %k0
|
||||
+ /* Each bit set in K2 represents a non-null CHAR in YMM0. */
|
||||
+ VPTESTM %YMM0, %YMM0, %k2
|
||||
|
||||
- /* Check for NULL in YMM0. */
|
||||
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||
- /* Check for NULL in YMM1. */
|
||||
- VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||
- /* Each bit in K1 represents a NULL in YMM0 or YMM1. */
|
||||
- kord %k1, %k2, %k1
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in YMM0 and 32 bytes at (%rsi). */
|
||||
+ VPCMP $0, (%rsi), %YMM0, %k1{%k2}
|
||||
|
||||
- /* Each bit in K1 represents:
|
||||
- 1. A mismatch in YMM0 and YMM1. Or
|
||||
- 2. A NULL in YMM0 or YMM1.
|
||||
- */
|
||||
- kord %k0, %k1, %k1
|
||||
-
|
||||
- ktestd %k1, %k1
|
||||
- je L(next_3_vectors)
|
||||
kmovd %k1, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
+ je L(next_3_vectors)
|
||||
tzcntl %ecx, %edx
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||
@@ -172,9 +173,7 @@ L(return):
|
||||
# endif
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
L(return_vec_size):
|
||||
- kmovd %k1, %ecx
|
||||
tzcntl %ecx, %edx
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||
@@ -210,9 +209,7 @@ L(return_vec_size):
|
||||
# endif
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
L(return_2_vec_size):
|
||||
- kmovd %k1, %ecx
|
||||
tzcntl %ecx, %edx
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||
@@ -248,9 +245,7 @@ L(return_2_vec_size):
|
||||
# endif
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
L(return_3_vec_size):
|
||||
- kmovd %k1, %ecx
|
||||
tzcntl %ecx, %edx
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||
@@ -289,43 +284,45 @@ L(return_3_vec_size):
|
||||
.p2align 4
|
||||
L(next_3_vectors):
|
||||
VMOVU VEC_SIZE(%rdi), %YMM0
|
||||
- VMOVU VEC_SIZE(%rsi), %YMM1
|
||||
- /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */
|
||||
- VPCMP $4, %YMM0, %YMM1, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||
- /* Each bit in K1 represents a NULL in YMM0 or YMM1. */
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||
- kord %k0, %k1, %k1
|
||||
- ktestd %k1, %k1
|
||||
+ /* Each bit set in K2 represents a non-null CHAR in YMM0. */
|
||||
+ VPTESTM %YMM0, %YMM0, %k2
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in YMM0 and 32 bytes at VEC_SIZE(%rsi). */
|
||||
+ VPCMP $0, VEC_SIZE(%rsi), %YMM0, %k1{%k2}
|
||||
+ kmovd %k1, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
jne L(return_vec_size)
|
||||
|
||||
- VMOVU (VEC_SIZE * 2)(%rdi), %YMM2
|
||||
- VMOVU (VEC_SIZE * 3)(%rdi), %YMM3
|
||||
- VMOVU (VEC_SIZE * 2)(%rsi), %YMM4
|
||||
- VMOVU (VEC_SIZE * 3)(%rsi), %YMM5
|
||||
-
|
||||
- /* Each bit in K0 represents a mismatch in YMM2 and YMM4. */
|
||||
- VPCMP $4, %YMM2, %YMM4, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM2, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM4, %k2
|
||||
- /* Each bit in K1 represents a NULL in YMM2 or YMM4. */
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||
- kord %k0, %k1, %k1
|
||||
- ktestd %k1, %k1
|
||||
+ VMOVU (VEC_SIZE * 2)(%rdi), %YMM0
|
||||
+ /* Each bit set in K2 represents a non-null CHAR in YMM0. */
|
||||
+ VPTESTM %YMM0, %YMM0, %k2
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rsi). */
|
||||
+ VPCMP $0, (VEC_SIZE * 2)(%rsi), %YMM0, %k1{%k2}
|
||||
+ kmovd %k1, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
jne L(return_2_vec_size)
|
||||
|
||||
- /* Each bit in K0 represents a mismatch in YMM3 and YMM5. */
|
||||
- VPCMP $4, %YMM3, %YMM5, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM3, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM5, %k2
|
||||
- /* Each bit in K1 represents a NULL in YMM3 or YMM5. */
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||
- kord %k0, %k1, %k1
|
||||
- ktestd %k1, %k1
|
||||
+ VMOVU (VEC_SIZE * 3)(%rdi), %YMM0
|
||||
+ /* Each bit set in K2 represents a non-null CHAR in YMM0. */
|
||||
+ VPTESTM %YMM0, %YMM0, %k2
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rsi). */
|
||||
+ VPCMP $0, (VEC_SIZE * 3)(%rsi), %YMM0, %k1{%k2}
|
||||
+ kmovd %k1, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
jne L(return_3_vec_size)
|
||||
L(main_loop_header):
|
||||
leaq (VEC_SIZE * 4)(%rdi), %rdx
|
||||
@@ -375,56 +372,51 @@ L(back_to_loop):
|
||||
VMOVA VEC_SIZE(%rax), %YMM2
|
||||
VMOVA (VEC_SIZE * 2)(%rax), %YMM4
|
||||
VMOVA (VEC_SIZE * 3)(%rax), %YMM6
|
||||
- VMOVU (%rdx), %YMM1
|
||||
- VMOVU VEC_SIZE(%rdx), %YMM3
|
||||
- VMOVU (VEC_SIZE * 2)(%rdx), %YMM5
|
||||
- VMOVU (VEC_SIZE * 3)(%rdx), %YMM7
|
||||
-
|
||||
- VPCMP $4, %YMM0, %YMM1, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K4 represents a NULL or a mismatch in YMM0 and
|
||||
- YMM1. */
|
||||
- kord %k0, %k1, %k4
|
||||
-
|
||||
- VPCMP $4, %YMM2, %YMM3, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM2, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM3, %k2
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K5 represents a NULL or a mismatch in YMM2 and
|
||||
- YMM3. */
|
||||
- kord %k0, %k1, %k5
|
||||
-
|
||||
- VPCMP $4, %YMM4, %YMM5, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM4, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM5, %k2
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K6 represents a NULL or a mismatch in YMM4 and
|
||||
- YMM5. */
|
||||
- kord %k0, %k1, %k6
|
||||
-
|
||||
- VPCMP $4, %YMM6, %YMM7, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM6, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM7, %k2
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K7 represents a NULL or a mismatch in YMM6 and
|
||||
- YMM7. */
|
||||
- kord %k0, %k1, %k7
|
||||
-
|
||||
- kord %k4, %k5, %k0
|
||||
- kord %k6, %k7, %k1
|
||||
-
|
||||
- /* Test each mask (32 bits) individually because for VEC_SIZE
|
||||
- == 32 is not possible to OR the four masks and keep all bits
|
||||
- in a 64-bit integer register, differing from SSE2 strcmp
|
||||
- where ORing is possible. */
|
||||
- kortestd %k0, %k1
|
||||
- je L(loop)
|
||||
- ktestd %k4, %k4
|
||||
+
|
||||
+ VPMINU %YMM0, %YMM2, %YMM8
|
||||
+ VPMINU %YMM4, %YMM6, %YMM9
|
||||
+
|
||||
+ /* A zero CHAR in YMM8 means that there is a null CHAR. */
|
||||
+ VPMINU %YMM8, %YMM9, %YMM8
|
||||
+
|
||||
+ /* Each bit set in K1 represents a non-null CHAR in YMM8. */
|
||||
+ VPTESTM %YMM8, %YMM8, %k1
|
||||
+
|
||||
+ /* (YMM ^ YMM): A non-zero CHAR represents a mismatch. */
|
||||
+ vpxorq (%rdx), %YMM0, %YMM1
|
||||
+ vpxorq VEC_SIZE(%rdx), %YMM2, %YMM3
|
||||
+ vpxorq (VEC_SIZE * 2)(%rdx), %YMM4, %YMM5
|
||||
+ vpxorq (VEC_SIZE * 3)(%rdx), %YMM6, %YMM7
|
||||
+
|
||||
+ vporq %YMM1, %YMM3, %YMM9
|
||||
+ vporq %YMM5, %YMM7, %YMM10
|
||||
+
|
||||
+ /* A non-zero CHAR in YMM9 represents a mismatch. */
|
||||
+ vporq %YMM9, %YMM10, %YMM9
|
||||
+
|
||||
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR. */
|
||||
+ VPCMP $0, %YMMZERO, %YMM9, %k0{%k1}
|
||||
+ kmovd %k0, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
+ je L(loop)
|
||||
+
|
||||
+ /* Each bit set in K1 represents a non-null CHAR in YMM0. */
|
||||
+ VPTESTM %YMM0, %YMM0, %k1
|
||||
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR
|
||||
+ in YMM0 and (%rdx). */
|
||||
+ VPCMP $0, %YMMZERO, %YMM1, %k0{%k1}
|
||||
+ kmovd %k0, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
je L(test_vec)
|
||||
- kmovd %k4, %edi
|
||||
- tzcntl %edi, %ecx
|
||||
+ tzcntl %ecx, %ecx
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||
sall $2, %ecx
|
||||
@@ -466,9 +458,18 @@ L(test_vec):
|
||||
cmpq $VEC_SIZE, %r11
|
||||
jbe L(zero)
|
||||
# endif
|
||||
- ktestd %k5, %k5
|
||||
+ /* Each bit set in K1 represents a non-null CHAR in YMM2. */
|
||||
+ VPTESTM %YMM2, %YMM2, %k1
|
||||
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR
|
||||
+ in YMM2 and VEC_SIZE(%rdx). */
|
||||
+ VPCMP $0, %YMMZERO, %YMM3, %k0{%k1}
|
||||
+ kmovd %k0, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
je L(test_2_vec)
|
||||
- kmovd %k5, %ecx
|
||||
tzcntl %ecx, %edi
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||
@@ -512,9 +513,18 @@ L(test_2_vec):
|
||||
cmpq $(VEC_SIZE * 2), %r11
|
||||
jbe L(zero)
|
||||
# endif
|
||||
- ktestd %k6, %k6
|
||||
+ /* Each bit set in K1 represents a non-null CHAR in YMM4. */
|
||||
+ VPTESTM %YMM4, %YMM4, %k1
|
||||
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR
|
||||
+ in YMM4 and (VEC_SIZE * 2)(%rdx). */
|
||||
+ VPCMP $0, %YMMZERO, %YMM5, %k0{%k1}
|
||||
+ kmovd %k0, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
je L(test_3_vec)
|
||||
- kmovd %k6, %ecx
|
||||
tzcntl %ecx, %edi
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||
@@ -558,8 +568,18 @@ L(test_3_vec):
|
||||
cmpq $(VEC_SIZE * 3), %r11
|
||||
jbe L(zero)
|
||||
# endif
|
||||
- kmovd %k7, %esi
|
||||
- tzcntl %esi, %ecx
|
||||
+ /* Each bit set in K1 represents a non-null CHAR in YMM6. */
|
||||
+ VPTESTM %YMM6, %YMM6, %k1
|
||||
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR
|
||||
+ in YMM6 and (VEC_SIZE * 3)(%rdx). */
|
||||
+ VPCMP $0, %YMMZERO, %YMM7, %k0{%k1}
|
||||
+ kmovd %k0, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
+ tzcntl %ecx, %ecx
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||
sall $2, %ecx
|
||||
@@ -615,39 +635,51 @@ L(loop_cross_page):
|
||||
|
||||
VMOVU (%rax, %r10), %YMM2
|
||||
VMOVU VEC_SIZE(%rax, %r10), %YMM3
|
||||
- VMOVU (%rdx, %r10), %YMM4
|
||||
- VMOVU VEC_SIZE(%rdx, %r10), %YMM5
|
||||
-
|
||||
- VPCMP $4, %YMM4, %YMM2, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM2, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM4, %k2
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K1 represents a NULL or a mismatch in YMM2 and
|
||||
- YMM4. */
|
||||
- kord %k0, %k1, %k1
|
||||
-
|
||||
- VPCMP $4, %YMM5, %YMM3, %k3
|
||||
- VPCMP $0, %YMMZERO, %YMM3, %k4
|
||||
- VPCMP $0, %YMMZERO, %YMM5, %k5
|
||||
- kord %k4, %k5, %k4
|
||||
- /* Each bit in K3 represents a NULL or a mismatch in YMM3 and
|
||||
- YMM5. */
|
||||
- kord %k3, %k4, %k3
|
||||
+
|
||||
+ /* Each bit set in K2 represents a non-null CHAR in YMM2. */
|
||||
+ VPTESTM %YMM2, %YMM2, %k2
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in YMM2 and 32 bytes at (%rdx, %r10). */
|
||||
+ VPCMP $0, (%rdx, %r10), %YMM2, %k1{%k2}
|
||||
+ kmovd %k1, %r9d
|
||||
+ /* Don't use subl since it is the lower 16/32 bits of RDI
|
||||
+ below. */
|
||||
+ notl %r9d
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ /* Only last 8 bits are valid. */
|
||||
+ andl $0xff, %r9d
|
||||
+# endif
|
||||
+
|
||||
+ /* Each bit set in K4 represents a non-null CHAR in YMM3. */
|
||||
+ VPTESTM %YMM3, %YMM3, %k4
|
||||
+ /* Each bit cleared in K3 represents a mismatch or a null CHAR
|
||||
+ in YMM3 and 32 bytes at VEC_SIZE(%rdx, %r10). */
|
||||
+ VPCMP $0, VEC_SIZE(%rdx, %r10), %YMM3, %k3{%k4}
|
||||
+ kmovd %k3, %edi
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ /* Don't use subl since it is the upper 8 bits of EDI below. */
|
||||
+ notl %edi
|
||||
+ andl $0xff, %edi
|
||||
+# else
|
||||
+ incl %edi
|
||||
+# endif
|
||||
|
||||
# ifdef USE_AS_WCSCMP
|
||||
- /* NB: Each bit in K1/K3 represents 4-byte element. */
|
||||
- kshiftlw $8, %k3, %k2
|
||||
+ /* NB: Each bit in EDI/R9D represents 4-byte element. */
|
||||
+ sall $8, %edi
|
||||
/* NB: Divide shift count by 4 since each bit in K1 represent 4
|
||||
bytes. */
|
||||
movl %ecx, %SHIFT_REG32
|
||||
sarl $2, %SHIFT_REG32
|
||||
+
|
||||
+ /* Each bit in EDI represents a null CHAR or a mismatch. */
|
||||
+ orl %r9d, %edi
|
||||
# else
|
||||
- kshiftlq $32, %k3, %k2
|
||||
-# endif
|
||||
+ salq $32, %rdi
|
||||
|
||||
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||
- korq %k1, %k2, %k1
|
||||
- kmovq %k1, %rdi
|
||||
+ /* Each bit in RDI represents a null CHAR or a mismatch. */
|
||||
+ orq %r9, %rdi
|
||||
+# endif
|
||||
|
||||
/* Since ECX < VEC_SIZE * 2, simply skip the first ECX bytes. */
|
||||
shrxq %SHIFT_REG64, %rdi, %rdi
|
||||
@@ -692,35 +724,45 @@ L(loop_cross_page_2_vec):
|
||||
/* The first VEC_SIZE * 2 bytes match or are ignored. */
|
||||
VMOVU (VEC_SIZE * 2)(%rax, %r10), %YMM0
|
||||
VMOVU (VEC_SIZE * 3)(%rax, %r10), %YMM1
|
||||
- VMOVU (VEC_SIZE * 2)(%rdx, %r10), %YMM2
|
||||
- VMOVU (VEC_SIZE * 3)(%rdx, %r10), %YMM3
|
||||
-
|
||||
- VPCMP $4, %YMM0, %YMM2, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM2, %k2
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K1 represents a NULL or a mismatch in YMM0 and
|
||||
- YMM2. */
|
||||
- kord %k0, %k1, %k1
|
||||
-
|
||||
- VPCMP $4, %YMM1, %YMM3, %k3
|
||||
- VPCMP $0, %YMMZERO, %YMM1, %k4
|
||||
- VPCMP $0, %YMMZERO, %YMM3, %k5
|
||||
- kord %k4, %k5, %k4
|
||||
- /* Each bit in K3 represents a NULL or a mismatch in YMM1 and
|
||||
- YMM3. */
|
||||
- kord %k3, %k4, %k3
|
||||
|
||||
+ VPTESTM %YMM0, %YMM0, %k2
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rdx, %r10). */
|
||||
+ VPCMP $0, (VEC_SIZE * 2)(%rdx, %r10), %YMM0, %k1{%k2}
|
||||
+ kmovd %k1, %r9d
|
||||
+ /* Don't use subl since it is the lower 16/32 bits of RDI
|
||||
+ below. */
|
||||
+ notl %r9d
|
||||
# ifdef USE_AS_WCSCMP
|
||||
- /* NB: Each bit in K1/K3 represents 4-byte element. */
|
||||
- kshiftlw $8, %k3, %k2
|
||||
+ /* Only last 8 bits are valid. */
|
||||
+ andl $0xff, %r9d
|
||||
+# endif
|
||||
+
|
||||
+ VPTESTM %YMM1, %YMM1, %k4
|
||||
+ /* Each bit cleared in K3 represents a mismatch or a null CHAR
|
||||
+ in YMM1 and 32 bytes at (VEC_SIZE * 3)(%rdx, %r10). */
|
||||
+ VPCMP $0, (VEC_SIZE * 3)(%rdx, %r10), %YMM1, %k3{%k4}
|
||||
+ kmovd %k3, %edi
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ /* Don't use subl since it is the upper 8 bits of EDI below. */
|
||||
+ notl %edi
|
||||
+ andl $0xff, %edi
|
||||
# else
|
||||
- kshiftlq $32, %k3, %k2
|
||||
+ incl %edi
|
||||
# endif
|
||||
|
||||
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||
- korq %k1, %k2, %k1
|
||||
- kmovq %k1, %rdi
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ /* NB: Each bit in EDI/R9D represents 4-byte element. */
|
||||
+ sall $8, %edi
|
||||
+
|
||||
+ /* Each bit in EDI represents a null CHAR or a mismatch. */
|
||||
+ orl %r9d, %edi
|
||||
+# else
|
||||
+ salq $32, %rdi
|
||||
+
|
||||
+ /* Each bit in RDI represents a null CHAR or a mismatch. */
|
||||
+ orq %r9, %rdi
|
||||
+# endif
|
||||
|
||||
xorl %r8d, %r8d
|
||||
/* If ECX > VEC_SIZE * 2, skip ECX - (VEC_SIZE * 2) bytes. */
|
||||
@@ -729,12 +771,15 @@ L(loop_cross_page_2_vec):
|
||||
/* R8 has number of bytes skipped. */
|
||||
movl %ecx, %r8d
|
||||
# ifdef USE_AS_WCSCMP
|
||||
- /* NB: Divide shift count by 4 since each bit in K1 represent 4
|
||||
+ /* NB: Divide shift count by 4 since each bit in RDI represent 4
|
||||
bytes. */
|
||||
sarl $2, %ecx
|
||||
-# endif
|
||||
+ /* Skip ECX bytes. */
|
||||
+ shrl %cl, %edi
|
||||
+# else
|
||||
/* Skip ECX bytes. */
|
||||
shrq %cl, %rdi
|
||||
+# endif
|
||||
1:
|
||||
/* Before jumping back to the loop, set ESI to the number of
|
||||
VEC_SIZE * 4 blocks before page crossing. */
|
||||
@@ -818,7 +863,7 @@ L(cross_page_loop):
|
||||
movzbl (%rdi, %rdx), %eax
|
||||
movzbl (%rsi, %rdx), %ecx
|
||||
# endif
|
||||
- /* Check null char. */
|
||||
+ /* Check null CHAR. */
|
||||
testl %eax, %eax
|
||||
jne L(cross_page_loop)
|
||||
/* Since %eax == 0, subtract is OK for both SIGNED and UNSIGNED
|
||||
@@ -901,18 +946,17 @@ L(cross_page):
|
||||
jg L(cross_page_1_vector)
|
||||
L(loop_1_vector):
|
||||
VMOVU (%rdi, %rdx), %YMM0
|
||||
- VMOVU (%rsi, %rdx), %YMM1
|
||||
-
|
||||
- /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */
|
||||
- VPCMP $4, %YMM0, %YMM1, %k0
|
||||
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||
- VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||
- /* Each bit in K1 represents a NULL in YMM0 or YMM1. */
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||
- kord %k0, %k1, %k1
|
||||
+
|
||||
+ VPTESTM %YMM0, %YMM0, %k2
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in YMM0 and 32 bytes at (%rsi, %rdx). */
|
||||
+ VPCMP $0, (%rsi, %rdx), %YMM0, %k1{%k2}
|
||||
kmovd %k1, %ecx
|
||||
- testl %ecx, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xff, %ecx
|
||||
+# else
|
||||
+ incl %ecx
|
||||
+# endif
|
||||
jne L(last_vector)
|
||||
|
||||
addl $VEC_SIZE, %edx
|
||||
@@ -931,18 +975,17 @@ L(cross_page_1_vector):
|
||||
cmpl $(PAGE_SIZE - 16), %eax
|
||||
jg L(cross_page_1_xmm)
|
||||
VMOVU (%rdi, %rdx), %XMM0
|
||||
- VMOVU (%rsi, %rdx), %XMM1
|
||||
-
|
||||
- /* Each bit in K0 represents a mismatch in XMM0 and XMM1. */
|
||||
- VPCMP $4, %XMM0, %XMM1, %k0
|
||||
- VPCMP $0, %XMMZERO, %XMM0, %k1
|
||||
- VPCMP $0, %XMMZERO, %XMM1, %k2
|
||||
- /* Each bit in K1 represents a NULL in XMM0 or XMM1. */
|
||||
- korw %k1, %k2, %k1
|
||||
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||
- korw %k0, %k1, %k1
|
||||
- kmovw %k1, %ecx
|
||||
- testl %ecx, %ecx
|
||||
+
|
||||
+ VPTESTM %YMM0, %YMM0, %k2
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in XMM0 and 16 bytes at (%rsi, %rdx). */
|
||||
+ VPCMP $0, (%rsi, %rdx), %XMM0, %k1{%k2}
|
||||
+ kmovd %k1, %ecx
|
||||
+# ifdef USE_AS_WCSCMP
|
||||
+ subl $0xf, %ecx
|
||||
+# else
|
||||
+ subl $0xffff, %ecx
|
||||
+# endif
|
||||
jne L(last_vector)
|
||||
|
||||
addl $16, %edx
|
||||
@@ -965,25 +1008,16 @@ L(cross_page_1_xmm):
|
||||
vmovq (%rdi, %rdx), %XMM0
|
||||
vmovq (%rsi, %rdx), %XMM1
|
||||
|
||||
- /* Each bit in K0 represents a mismatch in XMM0 and XMM1. */
|
||||
- VPCMP $4, %XMM0, %XMM1, %k0
|
||||
- VPCMP $0, %XMMZERO, %XMM0, %k1
|
||||
- VPCMP $0, %XMMZERO, %XMM1, %k2
|
||||
- /* Each bit in K1 represents a NULL in XMM0 or XMM1. */
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||
- kord %k0, %k1, %k1
|
||||
- kmovd %k1, %ecx
|
||||
-
|
||||
+ VPTESTM %YMM0, %YMM0, %k2
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in XMM0 and XMM1. */
|
||||
+ VPCMP $0, %XMM1, %XMM0, %k1{%k2}
|
||||
+ kmovb %k1, %ecx
|
||||
# ifdef USE_AS_WCSCMP
|
||||
- /* Only last 2 bits are valid. */
|
||||
- andl $0x3, %ecx
|
||||
+ subl $0x3, %ecx
|
||||
# else
|
||||
- /* Only last 8 bits are valid. */
|
||||
- andl $0xff, %ecx
|
||||
+ subl $0xff, %ecx
|
||||
# endif
|
||||
-
|
||||
- testl %ecx, %ecx
|
||||
jne L(last_vector)
|
||||
|
||||
addl $8, %edx
|
||||
@@ -1002,25 +1036,16 @@ L(cross_page_8bytes):
|
||||
vmovd (%rdi, %rdx), %XMM0
|
||||
vmovd (%rsi, %rdx), %XMM1
|
||||
|
||||
- /* Each bit in K0 represents a mismatch in XMM0 and XMM1. */
|
||||
- VPCMP $4, %XMM0, %XMM1, %k0
|
||||
- VPCMP $0, %XMMZERO, %XMM0, %k1
|
||||
- VPCMP $0, %XMMZERO, %XMM1, %k2
|
||||
- /* Each bit in K1 represents a NULL in XMM0 or XMM1. */
|
||||
- kord %k1, %k2, %k1
|
||||
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||
- kord %k0, %k1, %k1
|
||||
+ VPTESTM %YMM0, %YMM0, %k2
|
||||
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||
+ in XMM0 and XMM1. */
|
||||
+ VPCMP $0, %XMM1, %XMM0, %k1{%k2}
|
||||
kmovd %k1, %ecx
|
||||
-
|
||||
# ifdef USE_AS_WCSCMP
|
||||
- /* Only the last bit is valid. */
|
||||
- andl $0x1, %ecx
|
||||
+ subl $0x1, %ecx
|
||||
# else
|
||||
- /* Only last 4 bits are valid. */
|
||||
- andl $0xf, %ecx
|
||||
+ subl $0xf, %ecx
|
||||
# endif
|
||||
-
|
||||
- testl %ecx, %ecx
|
||||
jne L(last_vector)
|
||||
|
||||
addl $4, %edx
|
85
SOURCES/glibc-upstream-2.34-179.patch
Normal file
85
SOURCES/glibc-upstream-2.34-179.patch
Normal file
@ -0,0 +1,85 @@
|
||||
commit a182bb7a3922404f79def09d79ef89678b4049f0
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Fri Oct 29 12:56:53 2021 -0700
|
||||
|
||||
x86-64: Remove Prefer_AVX2_STRCMP
|
||||
|
||||
Remove Prefer_AVX2_STRCMP to enable EVEX strcmp. When comparing 2 32-byte
|
||||
strings, EVEX strcmp has been improved to require 1 load, 1 VPTESTM, 1
|
||||
VPCMP, 1 KMOVD and 1 INCL instead of 2 loads, 3 VPCMPs, 2 KORDs, 1 KMOVD
|
||||
and 1 TESTL while AVX2 strcmp requires 1 load, 2 VPCMPEQs, 1 VPMINU, 1
|
||||
VPMOVMSKB and 1 TESTL. EVEX strcmp is now faster than AVX2 strcmp by up
|
||||
to 40% on Tiger Lake and Ice Lake.
|
||||
|
||||
(cherry picked from commit 14dbbf46a007ae5df36646b51ad0c9e5f5259f30)
|
||||
|
||||
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
|
||||
index de4e3c3b7258120d..f4d4049e391cbabd 100644
|
||||
--- a/sysdeps/x86/cpu-features.c
|
||||
+++ b/sysdeps/x86/cpu-features.c
|
||||
@@ -574,14 +574,6 @@ disable_tsx:
|
||||
if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
|
||||
cpu_features->preferred[index_arch_Prefer_No_VZEROUPPER]
|
||||
|= bit_arch_Prefer_No_VZEROUPPER;
|
||||
-
|
||||
- /* Since to compare 2 32-byte strings, 256-bit EVEX strcmp
|
||||
- requires 2 loads, 3 VPCMPs and 2 KORDs while AVX2 strcmp
|
||||
- requires 1 load, 2 VPCMPEQs, 1 VPMINU and 1 VPMOVMSKB,
|
||||
- AVX2 strcmp is faster than EVEX strcmp. */
|
||||
- if (CPU_FEATURE_USABLE_P (cpu_features, AVX2))
|
||||
- cpu_features->preferred[index_arch_Prefer_AVX2_STRCMP]
|
||||
- |= bit_arch_Prefer_AVX2_STRCMP;
|
||||
}
|
||||
|
||||
/* Avoid avoid short distance REP MOVSB on processor with FSRM. */
|
||||
diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
|
||||
index 58f2fad4323d5d91..957db3ad229ba39f 100644
|
||||
--- a/sysdeps/x86/cpu-tunables.c
|
||||
+++ b/sysdeps/x86/cpu-tunables.c
|
||||
@@ -239,8 +239,6 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
|
||||
CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
|
||||
Fast_Copy_Backward,
|
||||
disable, 18);
|
||||
- CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH
|
||||
- (n, cpu_features, Prefer_AVX2_STRCMP, AVX2, disable, 18);
|
||||
}
|
||||
break;
|
||||
case 19:
|
||||
diff --git a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||
index 3bdc76cf71007948..8250bfcbecd29a9f 100644
|
||||
--- a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||
+++ b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||
@@ -31,5 +31,4 @@ BIT (Prefer_ERMS)
|
||||
BIT (Prefer_No_AVX512)
|
||||
BIT (MathVec_Prefer_No_AVX512)
|
||||
BIT (Prefer_FSRM)
|
||||
-BIT (Prefer_AVX2_STRCMP)
|
||||
BIT (Avoid_Short_Distance_REP_MOVSB)
|
||||
diff --git a/sysdeps/x86_64/multiarch/strcmp.c b/sysdeps/x86_64/multiarch/strcmp.c
|
||||
index 62b7abeeee646ab4..7c2901bf44456259 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strcmp.c
|
||||
+++ b/sysdeps/x86_64/multiarch/strcmp.c
|
||||
@@ -43,8 +43,7 @@ IFUNC_SELECTOR (void)
|
||||
{
|
||||
if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
|
||||
&& CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
|
||||
- && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
|
||||
- && !CPU_FEATURES_ARCH_P (cpu_features, Prefer_AVX2_STRCMP))
|
||||
+ && CPU_FEATURE_USABLE_P (cpu_features, BMI2))
|
||||
return OPTIMIZE (evex);
|
||||
|
||||
if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
|
||||
diff --git a/sysdeps/x86_64/multiarch/strncmp.c b/sysdeps/x86_64/multiarch/strncmp.c
|
||||
index 60ba0fe356b31779..f94a421784bfe923 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strncmp.c
|
||||
+++ b/sysdeps/x86_64/multiarch/strncmp.c
|
||||
@@ -43,8 +43,7 @@ IFUNC_SELECTOR (void)
|
||||
{
|
||||
if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
|
||||
&& CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
|
||||
- && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
|
||||
- && !CPU_FEATURES_ARCH_P (cpu_features, Prefer_AVX2_STRCMP))
|
||||
+ && CPU_FEATURE_USABLE_P (cpu_features, BMI2))
|
||||
return OPTIMIZE (evex);
|
||||
|
||||
if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
|
48
SOURCES/glibc-upstream-2.34-180.patch
Normal file
48
SOURCES/glibc-upstream-2.34-180.patch
Normal file
@ -0,0 +1,48 @@
|
||||
commit 2e64237a8744dd50f9222293275fa52e7248ff76
|
||||
Author: Fangrui Song <maskray@google.com>
|
||||
Date: Tue Nov 2 20:59:52 2021 -0700
|
||||
|
||||
x86-64: Replace movzx with movzbl
|
||||
|
||||
Clang cannot assemble movzx in the AT&T dialect mode.
|
||||
|
||||
../sysdeps/x86_64/strcmp.S:2232:16: error: invalid operand for instruction
|
||||
movzx (%rsi), %ecx
|
||||
^~~~
|
||||
|
||||
Change movzx to movzbl, which follows the AT&T dialect and is used
|
||||
elsewhere in the file.
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
(cherry picked from commit 6720d36b6623c5e48c070d86acf61198b33e144e)
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/strcmp-sse42.S b/sysdeps/x86_64/multiarch/strcmp-sse42.S
|
||||
index bc19547b09639071..6197a723b9e0606e 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strcmp-sse42.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strcmp-sse42.S
|
||||
@@ -1771,8 +1771,8 @@ LABEL(strcmp_exitz):
|
||||
.p2align 4
|
||||
// XXX Same as code above
|
||||
LABEL(Byte0):
|
||||
- movzx (%rsi), %ecx
|
||||
- movzx (%rdi), %eax
|
||||
+ movzbl (%rsi), %ecx
|
||||
+ movzbl (%rdi), %eax
|
||||
|
||||
#if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
|
||||
leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
|
||||
diff --git a/sysdeps/x86_64/strcmp.S b/sysdeps/x86_64/strcmp.S
|
||||
index 824e648230a15739..7f8a1bc756f86aee 100644
|
||||
--- a/sysdeps/x86_64/strcmp.S
|
||||
+++ b/sysdeps/x86_64/strcmp.S
|
||||
@@ -2232,8 +2232,8 @@ LABEL(strcmp_exitz):
|
||||
|
||||
.p2align 4
|
||||
LABEL(Byte0):
|
||||
- movzx (%rsi), %ecx
|
||||
- movzx (%rdi), %eax
|
||||
+ movzbl (%rsi), %ecx
|
||||
+ movzbl (%rdi), %eax
|
||||
|
||||
#if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
|
||||
leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
|
843
SOURCES/glibc-upstream-2.34-181.patch
Normal file
843
SOURCES/glibc-upstream-2.34-181.patch
Normal file
@ -0,0 +1,843 @@
|
||||
commit a7392db2ff2b9dd906500941ac6361dbe2211b0d
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Mon Nov 1 00:49:51 2021 -0500
|
||||
|
||||
x86: Optimize memmove-vec-unaligned-erms.S
|
||||
|
||||
No bug.
|
||||
|
||||
The optimizations are as follows:
|
||||
|
||||
1) Always align entry to 64 bytes. This makes behavior more
|
||||
predictable and makes other frontend optimizations easier.
|
||||
|
||||
2) Make the L(more_8x_vec) cases 4k aliasing aware. This can have
|
||||
significant benefits in the case that:
|
||||
0 < (dst - src) < [256, 512]
|
||||
|
||||
3) Align before `rep movsb`. For ERMS this is roughly a [0, 30%]
|
||||
improvement and for FSRM [-10%, 25%].
|
||||
|
||||
In addition to these primary changes there is general cleanup
|
||||
throughout to optimize the aligning routines and control flow logic.
|
||||
|
||||
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
(cherry picked from commit a6b7502ec0c2da89a7437f43171f160d713e39c6)
|
||||
|
||||
diff --git a/sysdeps/x86_64/memmove.S b/sysdeps/x86_64/memmove.S
|
||||
index db106a7a1f23f268..b2b318084823dceb 100644
|
||||
--- a/sysdeps/x86_64/memmove.S
|
||||
+++ b/sysdeps/x86_64/memmove.S
|
||||
@@ -25,7 +25,7 @@
|
||||
/* Use movups and movaps for smaller code sizes. */
|
||||
#define VMOVU movups
|
||||
#define VMOVA movaps
|
||||
-
|
||||
+#define MOV_SIZE 3
|
||||
#define SECTION(p) p
|
||||
|
||||
#ifdef USE_MULTIARCH
|
||||
diff --git a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S
|
||||
index 1ec1962e861dbf63..67a55f0c85af841c 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S
|
||||
@@ -4,7 +4,7 @@
|
||||
# define VMOVNT vmovntdq
|
||||
# define VMOVU vmovdqu
|
||||
# define VMOVA vmovdqa
|
||||
-
|
||||
+# define MOV_SIZE 4
|
||||
# define ZERO_UPPER_VEC_REGISTERS_RETURN \
|
||||
ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S
|
||||
index e195e93f153c9512..975ae6c0515b83cb 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S
|
||||
@@ -4,7 +4,7 @@
|
||||
# define VMOVNT vmovntdq
|
||||
# define VMOVU vmovdqu
|
||||
# define VMOVA vmovdqa
|
||||
-
|
||||
+# define MOV_SIZE 4
|
||||
# define SECTION(p) p##.avx
|
||||
# define MEMMOVE_SYMBOL(p,s) p##_avx_##s
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S
|
||||
index 848848ab39ff9326..0fa7126830af7acb 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S
|
||||
@@ -25,7 +25,7 @@
|
||||
# define VMOVU vmovdqu64
|
||||
# define VMOVA vmovdqa64
|
||||
# define VZEROUPPER
|
||||
-
|
||||
+# define MOV_SIZE 6
|
||||
# define SECTION(p) p##.evex512
|
||||
# define MEMMOVE_SYMBOL(p,s) p##_avx512_##s
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S
|
||||
index 0cbce8f944da51a0..88715441feaaccf5 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S
|
||||
@@ -25,7 +25,7 @@
|
||||
# define VMOVU vmovdqu64
|
||||
# define VMOVA vmovdqa64
|
||||
# define VZEROUPPER
|
||||
-
|
||||
+# define MOV_SIZE 6
|
||||
# define SECTION(p) p##.evex
|
||||
# define MEMMOVE_SYMBOL(p,s) p##_evex_##s
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
|
||||
index abde8438d41f2320..7b27cbdda5fb99f7 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
|
||||
@@ -76,6 +76,25 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+/* Whether to align before movsb. Ultimately we want 64 byte
|
||||
+ align and not worth it to load 4x VEC for VEC_SIZE == 16. */
|
||||
+#define ALIGN_MOVSB (VEC_SIZE > 16)
|
||||
+/* Number of bytes to align movsb to. */
|
||||
+#define MOVSB_ALIGN_TO 64
|
||||
+
|
||||
+#define SMALL_MOV_SIZE (MOV_SIZE <= 4)
|
||||
+#define LARGE_MOV_SIZE (MOV_SIZE > 4)
|
||||
+
|
||||
+#if SMALL_MOV_SIZE + LARGE_MOV_SIZE != 1
|
||||
+# error MOV_SIZE Unknown
|
||||
+#endif
|
||||
+
|
||||
+#if LARGE_MOV_SIZE
|
||||
+# define SMALL_SIZE_OFFSET (4)
|
||||
+#else
|
||||
+# define SMALL_SIZE_OFFSET (0)
|
||||
+#endif
|
||||
+
|
||||
#ifndef PAGE_SIZE
|
||||
# define PAGE_SIZE 4096
|
||||
#endif
|
||||
@@ -199,25 +218,21 @@ L(start):
|
||||
# endif
|
||||
cmp $VEC_SIZE, %RDX_LP
|
||||
jb L(less_vec)
|
||||
+ /* Load regardless. */
|
||||
+ VMOVU (%rsi), %VEC(0)
|
||||
cmp $(VEC_SIZE * 2), %RDX_LP
|
||||
ja L(more_2x_vec)
|
||||
-#if !defined USE_MULTIARCH || !IS_IN (libc)
|
||||
-L(last_2x_vec):
|
||||
-#endif
|
||||
/* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */
|
||||
- VMOVU (%rsi), %VEC(0)
|
||||
VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(1)
|
||||
VMOVU %VEC(0), (%rdi)
|
||||
VMOVU %VEC(1), -VEC_SIZE(%rdi,%rdx)
|
||||
-#if !defined USE_MULTIARCH || !IS_IN (libc)
|
||||
-L(nop):
|
||||
- ret
|
||||
+#if !(defined USE_MULTIARCH && IS_IN (libc))
|
||||
+ ZERO_UPPER_VEC_REGISTERS_RETURN
|
||||
#else
|
||||
VZEROUPPER_RETURN
|
||||
#endif
|
||||
#if defined USE_MULTIARCH && IS_IN (libc)
|
||||
END (MEMMOVE_SYMBOL (__memmove, unaligned))
|
||||
-
|
||||
# if VEC_SIZE == 16
|
||||
ENTRY (__mempcpy_chk_erms)
|
||||
cmp %RDX_LP, %RCX_LP
|
||||
@@ -289,7 +304,7 @@ ENTRY (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned_erms))
|
||||
END (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned_erms))
|
||||
# endif
|
||||
|
||||
-ENTRY (MEMMOVE_SYMBOL (__memmove, unaligned_erms))
|
||||
+ENTRY_P2ALIGN (MEMMOVE_SYMBOL (__memmove, unaligned_erms), 6)
|
||||
movq %rdi, %rax
|
||||
L(start_erms):
|
||||
# ifdef __ILP32__
|
||||
@@ -298,310 +313,448 @@ L(start_erms):
|
||||
# endif
|
||||
cmp $VEC_SIZE, %RDX_LP
|
||||
jb L(less_vec)
|
||||
+ /* Load regardless. */
|
||||
+ VMOVU (%rsi), %VEC(0)
|
||||
cmp $(VEC_SIZE * 2), %RDX_LP
|
||||
ja L(movsb_more_2x_vec)
|
||||
-L(last_2x_vec):
|
||||
- /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */
|
||||
- VMOVU (%rsi), %VEC(0)
|
||||
- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(1)
|
||||
+ /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE.
|
||||
+ */
|
||||
+ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(1)
|
||||
VMOVU %VEC(0), (%rdi)
|
||||
- VMOVU %VEC(1), -VEC_SIZE(%rdi,%rdx)
|
||||
+ VMOVU %VEC(1), -VEC_SIZE(%rdi, %rdx)
|
||||
L(return):
|
||||
-#if VEC_SIZE > 16
|
||||
+# if VEC_SIZE > 16
|
||||
ZERO_UPPER_VEC_REGISTERS_RETURN
|
||||
-#else
|
||||
+# else
|
||||
ret
|
||||
+# endif
|
||||
#endif
|
||||
|
||||
-L(movsb):
|
||||
- cmp __x86_rep_movsb_stop_threshold(%rip), %RDX_LP
|
||||
- jae L(more_8x_vec)
|
||||
- cmpq %rsi, %rdi
|
||||
- jb 1f
|
||||
- /* Source == destination is less common. */
|
||||
- je L(nop)
|
||||
- leaq (%rsi,%rdx), %r9
|
||||
- cmpq %r9, %rdi
|
||||
- /* Avoid slow backward REP MOVSB. */
|
||||
- jb L(more_8x_vec_backward)
|
||||
-# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||
- testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||
- jz 3f
|
||||
- movq %rdi, %rcx
|
||||
- subq %rsi, %rcx
|
||||
- jmp 2f
|
||||
-# endif
|
||||
-1:
|
||||
-# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||
- testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||
- jz 3f
|
||||
- movq %rsi, %rcx
|
||||
- subq %rdi, %rcx
|
||||
-2:
|
||||
-/* Avoid "rep movsb" if RCX, the distance between source and destination,
|
||||
- is N*4GB + [1..63] with N >= 0. */
|
||||
- cmpl $63, %ecx
|
||||
- jbe L(more_2x_vec) /* Avoid "rep movsb" if ECX <= 63. */
|
||||
-3:
|
||||
-# endif
|
||||
- mov %RDX_LP, %RCX_LP
|
||||
- rep movsb
|
||||
-L(nop):
|
||||
+#if LARGE_MOV_SIZE
|
||||
+ /* If LARGE_MOV_SIZE this fits in the aligning bytes between the
|
||||
+ ENTRY block and L(less_vec). */
|
||||
+ .p2align 4,, 8
|
||||
+L(between_4_7):
|
||||
+ /* From 4 to 7. No branch when size == 4. */
|
||||
+ movl (%rsi), %ecx
|
||||
+ movl (%rsi, %rdx), %esi
|
||||
+ movl %ecx, (%rdi)
|
||||
+ movl %esi, (%rdi, %rdx)
|
||||
ret
|
||||
#endif
|
||||
|
||||
+ .p2align 4
|
||||
L(less_vec):
|
||||
/* Less than 1 VEC. */
|
||||
#if VEC_SIZE != 16 && VEC_SIZE != 32 && VEC_SIZE != 64
|
||||
# error Unsupported VEC_SIZE!
|
||||
#endif
|
||||
#if VEC_SIZE > 32
|
||||
- cmpb $32, %dl
|
||||
+ cmpl $32, %edx
|
||||
jae L(between_32_63)
|
||||
#endif
|
||||
#if VEC_SIZE > 16
|
||||
- cmpb $16, %dl
|
||||
+ cmpl $16, %edx
|
||||
jae L(between_16_31)
|
||||
#endif
|
||||
- cmpb $8, %dl
|
||||
+ cmpl $8, %edx
|
||||
jae L(between_8_15)
|
||||
- cmpb $4, %dl
|
||||
+#if SMALL_MOV_SIZE
|
||||
+ cmpl $4, %edx
|
||||
+#else
|
||||
+ subq $4, %rdx
|
||||
+#endif
|
||||
jae L(between_4_7)
|
||||
- cmpb $1, %dl
|
||||
- ja L(between_2_3)
|
||||
- jb 1f
|
||||
- movzbl (%rsi), %ecx
|
||||
+ cmpl $(1 - SMALL_SIZE_OFFSET), %edx
|
||||
+ jl L(copy_0)
|
||||
+ movb (%rsi), %cl
|
||||
+ je L(copy_1)
|
||||
+ movzwl (-2 + SMALL_SIZE_OFFSET)(%rsi, %rdx), %esi
|
||||
+ movw %si, (-2 + SMALL_SIZE_OFFSET)(%rdi, %rdx)
|
||||
+L(copy_1):
|
||||
movb %cl, (%rdi)
|
||||
-1:
|
||||
+L(copy_0):
|
||||
ret
|
||||
+
|
||||
+#if SMALL_MOV_SIZE
|
||||
+ .p2align 4,, 8
|
||||
+L(between_4_7):
|
||||
+ /* From 4 to 7. No branch when size == 4. */
|
||||
+ movl -4(%rsi, %rdx), %ecx
|
||||
+ movl (%rsi), %esi
|
||||
+ movl %ecx, -4(%rdi, %rdx)
|
||||
+ movl %esi, (%rdi)
|
||||
+ ret
|
||||
+#endif
|
||||
+
|
||||
+#if VEC_SIZE > 16
|
||||
+ /* From 16 to 31. No branch when size == 16. */
|
||||
+ .p2align 4,, 8
|
||||
+L(between_16_31):
|
||||
+ vmovdqu (%rsi), %xmm0
|
||||
+ vmovdqu -16(%rsi, %rdx), %xmm1
|
||||
+ vmovdqu %xmm0, (%rdi)
|
||||
+ vmovdqu %xmm1, -16(%rdi, %rdx)
|
||||
+ /* No ymm registers have been touched. */
|
||||
+ ret
|
||||
+#endif
|
||||
+
|
||||
#if VEC_SIZE > 32
|
||||
+ .p2align 4,, 10
|
||||
L(between_32_63):
|
||||
/* From 32 to 63. No branch when size == 32. */
|
||||
VMOVU (%rsi), %YMM0
|
||||
- VMOVU -32(%rsi,%rdx), %YMM1
|
||||
+ VMOVU -32(%rsi, %rdx), %YMM1
|
||||
VMOVU %YMM0, (%rdi)
|
||||
- VMOVU %YMM1, -32(%rdi,%rdx)
|
||||
- VZEROUPPER_RETURN
|
||||
-#endif
|
||||
-#if VEC_SIZE > 16
|
||||
- /* From 16 to 31. No branch when size == 16. */
|
||||
-L(between_16_31):
|
||||
- VMOVU (%rsi), %XMM0
|
||||
- VMOVU -16(%rsi,%rdx), %XMM1
|
||||
- VMOVU %XMM0, (%rdi)
|
||||
- VMOVU %XMM1, -16(%rdi,%rdx)
|
||||
+ VMOVU %YMM1, -32(%rdi, %rdx)
|
||||
VZEROUPPER_RETURN
|
||||
#endif
|
||||
+
|
||||
+ .p2align 4,, 10
|
||||
L(between_8_15):
|
||||
/* From 8 to 15. No branch when size == 8. */
|
||||
- movq -8(%rsi,%rdx), %rcx
|
||||
+ movq -8(%rsi, %rdx), %rcx
|
||||
movq (%rsi), %rsi
|
||||
- movq %rcx, -8(%rdi,%rdx)
|
||||
movq %rsi, (%rdi)
|
||||
+ movq %rcx, -8(%rdi, %rdx)
|
||||
ret
|
||||
-L(between_4_7):
|
||||
- /* From 4 to 7. No branch when size == 4. */
|
||||
- movl -4(%rsi,%rdx), %ecx
|
||||
- movl (%rsi), %esi
|
||||
- movl %ecx, -4(%rdi,%rdx)
|
||||
- movl %esi, (%rdi)
|
||||
- ret
|
||||
-L(between_2_3):
|
||||
- /* From 2 to 3. No branch when size == 2. */
|
||||
- movzwl -2(%rsi,%rdx), %ecx
|
||||
- movzwl (%rsi), %esi
|
||||
- movw %cx, -2(%rdi,%rdx)
|
||||
- movw %si, (%rdi)
|
||||
- ret
|
||||
|
||||
+ .p2align 4,, 10
|
||||
+L(last_4x_vec):
|
||||
+ /* Copy from 2 * VEC + 1 to 4 * VEC, inclusively. */
|
||||
+
|
||||
+ /* VEC(0) and VEC(1) have already been loaded. */
|
||||
+ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(2)
|
||||
+ VMOVU -(VEC_SIZE * 2)(%rsi, %rdx), %VEC(3)
|
||||
+ VMOVU %VEC(0), (%rdi)
|
||||
+ VMOVU %VEC(1), VEC_SIZE(%rdi)
|
||||
+ VMOVU %VEC(2), -VEC_SIZE(%rdi, %rdx)
|
||||
+ VMOVU %VEC(3), -(VEC_SIZE * 2)(%rdi, %rdx)
|
||||
+ VZEROUPPER_RETURN
|
||||
+
|
||||
+ .p2align 4
|
||||
#if defined USE_MULTIARCH && IS_IN (libc)
|
||||
L(movsb_more_2x_vec):
|
||||
cmp __x86_rep_movsb_threshold(%rip), %RDX_LP
|
||||
ja L(movsb)
|
||||
#endif
|
||||
L(more_2x_vec):
|
||||
- /* More than 2 * VEC and there may be overlap between destination
|
||||
- and source. */
|
||||
+ /* More than 2 * VEC and there may be overlap between
|
||||
+ destination and source. */
|
||||
cmpq $(VEC_SIZE * 8), %rdx
|
||||
ja L(more_8x_vec)
|
||||
+ /* Load VEC(1) regardless. VEC(0) has already been loaded. */
|
||||
+ VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||
cmpq $(VEC_SIZE * 4), %rdx
|
||||
jbe L(last_4x_vec)
|
||||
- /* Copy from 4 * VEC + 1 to 8 * VEC, inclusively. */
|
||||
- VMOVU (%rsi), %VEC(0)
|
||||
- VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||
+ /* Copy from 4 * VEC + 1 to 8 * VEC, inclusively. */
|
||||
VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2)
|
||||
VMOVU (VEC_SIZE * 3)(%rsi), %VEC(3)
|
||||
- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(4)
|
||||
- VMOVU -(VEC_SIZE * 2)(%rsi,%rdx), %VEC(5)
|
||||
- VMOVU -(VEC_SIZE * 3)(%rsi,%rdx), %VEC(6)
|
||||
- VMOVU -(VEC_SIZE * 4)(%rsi,%rdx), %VEC(7)
|
||||
+ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(4)
|
||||
+ VMOVU -(VEC_SIZE * 2)(%rsi, %rdx), %VEC(5)
|
||||
+ VMOVU -(VEC_SIZE * 3)(%rsi, %rdx), %VEC(6)
|
||||
+ VMOVU -(VEC_SIZE * 4)(%rsi, %rdx), %VEC(7)
|
||||
VMOVU %VEC(0), (%rdi)
|
||||
VMOVU %VEC(1), VEC_SIZE(%rdi)
|
||||
VMOVU %VEC(2), (VEC_SIZE * 2)(%rdi)
|
||||
VMOVU %VEC(3), (VEC_SIZE * 3)(%rdi)
|
||||
- VMOVU %VEC(4), -VEC_SIZE(%rdi,%rdx)
|
||||
- VMOVU %VEC(5), -(VEC_SIZE * 2)(%rdi,%rdx)
|
||||
- VMOVU %VEC(6), -(VEC_SIZE * 3)(%rdi,%rdx)
|
||||
- VMOVU %VEC(7), -(VEC_SIZE * 4)(%rdi,%rdx)
|
||||
- VZEROUPPER_RETURN
|
||||
-L(last_4x_vec):
|
||||
- /* Copy from 2 * VEC + 1 to 4 * VEC, inclusively. */
|
||||
- VMOVU (%rsi), %VEC(0)
|
||||
- VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||
- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(2)
|
||||
- VMOVU -(VEC_SIZE * 2)(%rsi,%rdx), %VEC(3)
|
||||
- VMOVU %VEC(0), (%rdi)
|
||||
- VMOVU %VEC(1), VEC_SIZE(%rdi)
|
||||
- VMOVU %VEC(2), -VEC_SIZE(%rdi,%rdx)
|
||||
- VMOVU %VEC(3), -(VEC_SIZE * 2)(%rdi,%rdx)
|
||||
+ VMOVU %VEC(4), -VEC_SIZE(%rdi, %rdx)
|
||||
+ VMOVU %VEC(5), -(VEC_SIZE * 2)(%rdi, %rdx)
|
||||
+ VMOVU %VEC(6), -(VEC_SIZE * 3)(%rdi, %rdx)
|
||||
+ VMOVU %VEC(7), -(VEC_SIZE * 4)(%rdi, %rdx)
|
||||
VZEROUPPER_RETURN
|
||||
|
||||
+ .p2align 4,, 4
|
||||
L(more_8x_vec):
|
||||
+ movq %rdi, %rcx
|
||||
+ subq %rsi, %rcx
|
||||
+ /* Go to backwards temporal copy if overlap no matter what as
|
||||
+ backward REP MOVSB is slow and we don't want to use NT stores if
|
||||
+ there is overlap. */
|
||||
+ cmpq %rdx, %rcx
|
||||
+ /* L(more_8x_vec_backward_check_nop) checks for src == dst. */
|
||||
+ jb L(more_8x_vec_backward_check_nop)
|
||||
/* Check if non-temporal move candidate. */
|
||||
#if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc)
|
||||
/* Check non-temporal store threshold. */
|
||||
- cmp __x86_shared_non_temporal_threshold(%rip), %RDX_LP
|
||||
+ cmp __x86_shared_non_temporal_threshold(%rip), %RDX_LP
|
||||
ja L(large_memcpy_2x)
|
||||
#endif
|
||||
- /* Entry if rdx is greater than non-temporal threshold but there
|
||||
- is overlap. */
|
||||
+ /* To reach this point there cannot be overlap and dst > src. So
|
||||
+ check for overlap and src > dst in which case correctness
|
||||
+ requires forward copy. Otherwise decide between backward/forward
|
||||
+ copy depending on address aliasing. */
|
||||
+
|
||||
+ /* Entry if rdx is greater than __x86_rep_movsb_stop_threshold
|
||||
+ but less than __x86_shared_non_temporal_threshold. */
|
||||
L(more_8x_vec_check):
|
||||
- cmpq %rsi, %rdi
|
||||
- ja L(more_8x_vec_backward)
|
||||
- /* Source == destination is less common. */
|
||||
- je L(nop)
|
||||
- /* Load the first VEC and last 4 * VEC to support overlapping
|
||||
- addresses. */
|
||||
- VMOVU (%rsi), %VEC(4)
|
||||
+ /* rcx contains dst - src. Add back length (rdx). */
|
||||
+ leaq (%rcx, %rdx), %r8
|
||||
+ /* If r8 has different sign than rcx then there is overlap so we
|
||||
+ must do forward copy. */
|
||||
+ xorq %rcx, %r8
|
||||
+ /* Isolate just sign bit of r8. */
|
||||
+ shrq $63, %r8
|
||||
+ /* Get 4k difference dst - src. */
|
||||
+ andl $(PAGE_SIZE - 256), %ecx
|
||||
+ /* If r8 is non-zero must do foward for correctness. Otherwise
|
||||
+ if ecx is non-zero there is 4k False Alaising so do backward
|
||||
+ copy. */
|
||||
+ addl %r8d, %ecx
|
||||
+ jz L(more_8x_vec_backward)
|
||||
+
|
||||
+ /* if rdx is greater than __x86_shared_non_temporal_threshold
|
||||
+ but there is overlap, or from short distance movsb. */
|
||||
+L(more_8x_vec_forward):
|
||||
+ /* Load first and last 4 * VEC to support overlapping addresses.
|
||||
+ */
|
||||
+
|
||||
+ /* First vec was already loaded into VEC(0). */
|
||||
VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(5)
|
||||
VMOVU -(VEC_SIZE * 2)(%rsi, %rdx), %VEC(6)
|
||||
+ /* Save begining of dst. */
|
||||
+ movq %rdi, %rcx
|
||||
+ /* Align dst to VEC_SIZE - 1. */
|
||||
+ orq $(VEC_SIZE - 1), %rdi
|
||||
VMOVU -(VEC_SIZE * 3)(%rsi, %rdx), %VEC(7)
|
||||
VMOVU -(VEC_SIZE * 4)(%rsi, %rdx), %VEC(8)
|
||||
- /* Save start and stop of the destination buffer. */
|
||||
- movq %rdi, %r11
|
||||
- leaq -VEC_SIZE(%rdi, %rdx), %rcx
|
||||
- /* Align destination for aligned stores in the loop. Compute
|
||||
- how much destination is misaligned. */
|
||||
- movq %rdi, %r8
|
||||
- andq $(VEC_SIZE - 1), %r8
|
||||
- /* Get the negative of offset for alignment. */
|
||||
- subq $VEC_SIZE, %r8
|
||||
- /* Adjust source. */
|
||||
- subq %r8, %rsi
|
||||
- /* Adjust destination which should be aligned now. */
|
||||
- subq %r8, %rdi
|
||||
- /* Adjust length. */
|
||||
- addq %r8, %rdx
|
||||
|
||||
- .p2align 4
|
||||
+ /* Subtract dst from src. Add back after dst aligned. */
|
||||
+ subq %rcx, %rsi
|
||||
+ /* Finish aligning dst. */
|
||||
+ incq %rdi
|
||||
+ /* Restore src adjusted with new value for aligned dst. */
|
||||
+ addq %rdi, %rsi
|
||||
+ /* Store end of buffer minus tail in rdx. */
|
||||
+ leaq (VEC_SIZE * -4)(%rcx, %rdx), %rdx
|
||||
+
|
||||
+ /* Dont use multi-byte nop to align. */
|
||||
+ .p2align 4,, 11
|
||||
L(loop_4x_vec_forward):
|
||||
/* Copy 4 * VEC a time forward. */
|
||||
- VMOVU (%rsi), %VEC(0)
|
||||
- VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||
- VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2)
|
||||
- VMOVU (VEC_SIZE * 3)(%rsi), %VEC(3)
|
||||
+ VMOVU (%rsi), %VEC(1)
|
||||
+ VMOVU VEC_SIZE(%rsi), %VEC(2)
|
||||
+ VMOVU (VEC_SIZE * 2)(%rsi), %VEC(3)
|
||||
+ VMOVU (VEC_SIZE * 3)(%rsi), %VEC(4)
|
||||
subq $-(VEC_SIZE * 4), %rsi
|
||||
- addq $-(VEC_SIZE * 4), %rdx
|
||||
- VMOVA %VEC(0), (%rdi)
|
||||
- VMOVA %VEC(1), VEC_SIZE(%rdi)
|
||||
- VMOVA %VEC(2), (VEC_SIZE * 2)(%rdi)
|
||||
- VMOVA %VEC(3), (VEC_SIZE * 3)(%rdi)
|
||||
+ VMOVA %VEC(1), (%rdi)
|
||||
+ VMOVA %VEC(2), VEC_SIZE(%rdi)
|
||||
+ VMOVA %VEC(3), (VEC_SIZE * 2)(%rdi)
|
||||
+ VMOVA %VEC(4), (VEC_SIZE * 3)(%rdi)
|
||||
subq $-(VEC_SIZE * 4), %rdi
|
||||
- cmpq $(VEC_SIZE * 4), %rdx
|
||||
+ cmpq %rdi, %rdx
|
||||
ja L(loop_4x_vec_forward)
|
||||
/* Store the last 4 * VEC. */
|
||||
- VMOVU %VEC(5), (%rcx)
|
||||
- VMOVU %VEC(6), -VEC_SIZE(%rcx)
|
||||
- VMOVU %VEC(7), -(VEC_SIZE * 2)(%rcx)
|
||||
- VMOVU %VEC(8), -(VEC_SIZE * 3)(%rcx)
|
||||
+ VMOVU %VEC(5), (VEC_SIZE * 3)(%rdx)
|
||||
+ VMOVU %VEC(6), (VEC_SIZE * 2)(%rdx)
|
||||
+ VMOVU %VEC(7), VEC_SIZE(%rdx)
|
||||
+ VMOVU %VEC(8), (%rdx)
|
||||
/* Store the first VEC. */
|
||||
- VMOVU %VEC(4), (%r11)
|
||||
+ VMOVU %VEC(0), (%rcx)
|
||||
+ /* Keep L(nop_backward) target close to jmp for 2-byte encoding.
|
||||
+ */
|
||||
+L(nop_backward):
|
||||
VZEROUPPER_RETURN
|
||||
|
||||
+ .p2align 4,, 8
|
||||
+L(more_8x_vec_backward_check_nop):
|
||||
+ /* rcx contains dst - src. Test for dst == src to skip all of
|
||||
+ memmove. */
|
||||
+ testq %rcx, %rcx
|
||||
+ jz L(nop_backward)
|
||||
L(more_8x_vec_backward):
|
||||
/* Load the first 4 * VEC and last VEC to support overlapping
|
||||
addresses. */
|
||||
- VMOVU (%rsi), %VEC(4)
|
||||
+
|
||||
+ /* First vec was also loaded into VEC(0). */
|
||||
VMOVU VEC_SIZE(%rsi), %VEC(5)
|
||||
VMOVU (VEC_SIZE * 2)(%rsi), %VEC(6)
|
||||
+ /* Begining of region for 4x backward copy stored in rcx. */
|
||||
+ leaq (VEC_SIZE * -4 + -1)(%rdi, %rdx), %rcx
|
||||
VMOVU (VEC_SIZE * 3)(%rsi), %VEC(7)
|
||||
- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(8)
|
||||
- /* Save stop of the destination buffer. */
|
||||
- leaq -VEC_SIZE(%rdi, %rdx), %r11
|
||||
- /* Align destination end for aligned stores in the loop. Compute
|
||||
- how much destination end is misaligned. */
|
||||
- leaq -VEC_SIZE(%rsi, %rdx), %rcx
|
||||
- movq %r11, %r9
|
||||
- movq %r11, %r8
|
||||
- andq $(VEC_SIZE - 1), %r8
|
||||
- /* Adjust source. */
|
||||
- subq %r8, %rcx
|
||||
- /* Adjust the end of destination which should be aligned now. */
|
||||
- subq %r8, %r9
|
||||
- /* Adjust length. */
|
||||
- subq %r8, %rdx
|
||||
-
|
||||
- .p2align 4
|
||||
+ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(8)
|
||||
+ /* Subtract dst from src. Add back after dst aligned. */
|
||||
+ subq %rdi, %rsi
|
||||
+ /* Align dst. */
|
||||
+ andq $-(VEC_SIZE), %rcx
|
||||
+ /* Restore src. */
|
||||
+ addq %rcx, %rsi
|
||||
+
|
||||
+ /* Don't use multi-byte nop to align. */
|
||||
+ .p2align 4,, 11
|
||||
L(loop_4x_vec_backward):
|
||||
/* Copy 4 * VEC a time backward. */
|
||||
- VMOVU (%rcx), %VEC(0)
|
||||
- VMOVU -VEC_SIZE(%rcx), %VEC(1)
|
||||
- VMOVU -(VEC_SIZE * 2)(%rcx), %VEC(2)
|
||||
- VMOVU -(VEC_SIZE * 3)(%rcx), %VEC(3)
|
||||
- addq $-(VEC_SIZE * 4), %rcx
|
||||
- addq $-(VEC_SIZE * 4), %rdx
|
||||
- VMOVA %VEC(0), (%r9)
|
||||
- VMOVA %VEC(1), -VEC_SIZE(%r9)
|
||||
- VMOVA %VEC(2), -(VEC_SIZE * 2)(%r9)
|
||||
- VMOVA %VEC(3), -(VEC_SIZE * 3)(%r9)
|
||||
- addq $-(VEC_SIZE * 4), %r9
|
||||
- cmpq $(VEC_SIZE * 4), %rdx
|
||||
- ja L(loop_4x_vec_backward)
|
||||
+ VMOVU (VEC_SIZE * 3)(%rsi), %VEC(1)
|
||||
+ VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2)
|
||||
+ VMOVU (VEC_SIZE * 1)(%rsi), %VEC(3)
|
||||
+ VMOVU (VEC_SIZE * 0)(%rsi), %VEC(4)
|
||||
+ addq $(VEC_SIZE * -4), %rsi
|
||||
+ VMOVA %VEC(1), (VEC_SIZE * 3)(%rcx)
|
||||
+ VMOVA %VEC(2), (VEC_SIZE * 2)(%rcx)
|
||||
+ VMOVA %VEC(3), (VEC_SIZE * 1)(%rcx)
|
||||
+ VMOVA %VEC(4), (VEC_SIZE * 0)(%rcx)
|
||||
+ addq $(VEC_SIZE * -4), %rcx
|
||||
+ cmpq %rcx, %rdi
|
||||
+ jb L(loop_4x_vec_backward)
|
||||
/* Store the first 4 * VEC. */
|
||||
- VMOVU %VEC(4), (%rdi)
|
||||
+ VMOVU %VEC(0), (%rdi)
|
||||
VMOVU %VEC(5), VEC_SIZE(%rdi)
|
||||
VMOVU %VEC(6), (VEC_SIZE * 2)(%rdi)
|
||||
VMOVU %VEC(7), (VEC_SIZE * 3)(%rdi)
|
||||
/* Store the last VEC. */
|
||||
- VMOVU %VEC(8), (%r11)
|
||||
+ VMOVU %VEC(8), -VEC_SIZE(%rdx, %rdi)
|
||||
+ VZEROUPPER_RETURN
|
||||
+
|
||||
+#if defined USE_MULTIARCH && IS_IN (libc)
|
||||
+ /* L(skip_short_movsb_check) is only used with ERMS. Not for
|
||||
+ FSRM. */
|
||||
+ .p2align 5,, 16
|
||||
+# if ALIGN_MOVSB
|
||||
+L(skip_short_movsb_check):
|
||||
+# if MOVSB_ALIGN_TO > VEC_SIZE
|
||||
+ VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||
+# endif
|
||||
+# if MOVSB_ALIGN_TO > (VEC_SIZE * 2)
|
||||
+# error Unsupported MOVSB_ALIGN_TO
|
||||
+# endif
|
||||
+ /* If CPU does not have FSRM two options for aligning. Align src
|
||||
+ if dst and src 4k alias. Otherwise align dst. */
|
||||
+ testl $(PAGE_SIZE - 512), %ecx
|
||||
+ jnz L(movsb_align_dst)
|
||||
+ /* Fall through. dst and src 4k alias. It's better to align src
|
||||
+ here because the bottleneck will be loads dues to the false
|
||||
+ dependency on dst. */
|
||||
+
|
||||
+ /* rcx already has dst - src. */
|
||||
+ movq %rcx, %r9
|
||||
+ /* Add src to len. Subtract back after src aligned. -1 because
|
||||
+ src is initially aligned to MOVSB_ALIGN_TO - 1. */
|
||||
+ leaq -1(%rsi, %rdx), %rcx
|
||||
+ /* Inclusively align src to MOVSB_ALIGN_TO - 1. */
|
||||
+ orq $(MOVSB_ALIGN_TO - 1), %rsi
|
||||
+ /* Restore dst and len adjusted with new values for aligned dst.
|
||||
+ */
|
||||
+ leaq 1(%rsi, %r9), %rdi
|
||||
+ subq %rsi, %rcx
|
||||
+ /* Finish aligning src. */
|
||||
+ incq %rsi
|
||||
+
|
||||
+ rep movsb
|
||||
+
|
||||
+ VMOVU %VEC(0), (%r8)
|
||||
+# if MOVSB_ALIGN_TO > VEC_SIZE
|
||||
+ VMOVU %VEC(1), VEC_SIZE(%r8)
|
||||
+# endif
|
||||
VZEROUPPER_RETURN
|
||||
+# endif
|
||||
+
|
||||
+ .p2align 4,, 12
|
||||
+L(movsb):
|
||||
+ movq %rdi, %rcx
|
||||
+ subq %rsi, %rcx
|
||||
+ /* Go to backwards temporal copy if overlap no matter what as
|
||||
+ backward REP MOVSB is slow and we don't want to use NT stores if
|
||||
+ there is overlap. */
|
||||
+ cmpq %rdx, %rcx
|
||||
+ /* L(more_8x_vec_backward_check_nop) checks for src == dst. */
|
||||
+ jb L(more_8x_vec_backward_check_nop)
|
||||
+# if ALIGN_MOVSB
|
||||
+ /* Save dest for storing aligning VECs later. */
|
||||
+ movq %rdi, %r8
|
||||
+# endif
|
||||
+ /* If above __x86_rep_movsb_stop_threshold most likely is
|
||||
+ candidate for NT moves aswell. */
|
||||
+ cmp __x86_rep_movsb_stop_threshold(%rip), %RDX_LP
|
||||
+ jae L(large_memcpy_2x_check)
|
||||
+# if AVOID_SHORT_DISTANCE_REP_MOVSB || ALIGN_MOVSB
|
||||
+ /* Only avoid short movsb if CPU has FSRM. */
|
||||
+ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||
+ jz L(skip_short_movsb_check)
|
||||
+# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||
+ /* Avoid "rep movsb" if RCX, the distance between source and
|
||||
+ destination, is N*4GB + [1..63] with N >= 0. */
|
||||
+
|
||||
+ /* ecx contains dst - src. Early check for backward copy
|
||||
+ conditions means only case of slow movsb with src = dst + [0,
|
||||
+ 63] is ecx in [-63, 0]. Use unsigned comparison with -64 check
|
||||
+ for that case. */
|
||||
+ cmpl $-64, %ecx
|
||||
+ ja L(more_8x_vec_forward)
|
||||
+# endif
|
||||
+# endif
|
||||
+# if ALIGN_MOVSB
|
||||
+# if MOVSB_ALIGN_TO > VEC_SIZE
|
||||
+ VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||
+# endif
|
||||
+# if MOVSB_ALIGN_TO > (VEC_SIZE * 2)
|
||||
+# error Unsupported MOVSB_ALIGN_TO
|
||||
+# endif
|
||||
+ /* Fall through means cpu has FSRM. In that case exclusively
|
||||
+ align destination. */
|
||||
+L(movsb_align_dst):
|
||||
+ /* Subtract dst from src. Add back after dst aligned. */
|
||||
+ subq %rdi, %rsi
|
||||
+ /* Exclusively align dst to MOVSB_ALIGN_TO (64). */
|
||||
+ addq $(MOVSB_ALIGN_TO - 1), %rdi
|
||||
+ /* Add dst to len. Subtract back after dst aligned. */
|
||||
+ leaq (%r8, %rdx), %rcx
|
||||
+ /* Finish aligning dst. */
|
||||
+ andq $-(MOVSB_ALIGN_TO), %rdi
|
||||
+ /* Restore src and len adjusted with new values for aligned dst.
|
||||
+ */
|
||||
+ addq %rdi, %rsi
|
||||
+ subq %rdi, %rcx
|
||||
+
|
||||
+ rep movsb
|
||||
+
|
||||
+ /* Store VECs loaded for aligning. */
|
||||
+ VMOVU %VEC(0), (%r8)
|
||||
+# if MOVSB_ALIGN_TO > VEC_SIZE
|
||||
+ VMOVU %VEC(1), VEC_SIZE(%r8)
|
||||
+# endif
|
||||
+ VZEROUPPER_RETURN
|
||||
+# else /* !ALIGN_MOVSB. */
|
||||
+L(skip_short_movsb_check):
|
||||
+ mov %RDX_LP, %RCX_LP
|
||||
+ rep movsb
|
||||
+ ret
|
||||
+# endif
|
||||
+#endif
|
||||
|
||||
+ .p2align 4,, 10
|
||||
#if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc)
|
||||
- .p2align 4
|
||||
+L(large_memcpy_2x_check):
|
||||
+ cmp __x86_rep_movsb_threshold(%rip), %RDX_LP
|
||||
+ jb L(more_8x_vec_check)
|
||||
L(large_memcpy_2x):
|
||||
- /* Compute absolute value of difference between source and
|
||||
- destination. */
|
||||
- movq %rdi, %r9
|
||||
- subq %rsi, %r9
|
||||
- movq %r9, %r8
|
||||
- leaq -1(%r9), %rcx
|
||||
- sarq $63, %r8
|
||||
- xorq %r8, %r9
|
||||
- subq %r8, %r9
|
||||
- /* Don't use non-temporal store if there is overlap between
|
||||
- destination and source since destination may be in cache when
|
||||
- source is loaded. */
|
||||
- cmpq %r9, %rdx
|
||||
- ja L(more_8x_vec_check)
|
||||
+ /* To reach this point it is impossible for dst > src and
|
||||
+ overlap. Remaining to check is src > dst and overlap. rcx
|
||||
+ already contains dst - src. Negate rcx to get src - dst. If
|
||||
+ length > rcx then there is overlap and forward copy is best. */
|
||||
+ negq %rcx
|
||||
+ cmpq %rcx, %rdx
|
||||
+ ja L(more_8x_vec_forward)
|
||||
|
||||
/* Cache align destination. First store the first 64 bytes then
|
||||
adjust alignments. */
|
||||
- VMOVU (%rsi), %VEC(8)
|
||||
-#if VEC_SIZE < 64
|
||||
- VMOVU VEC_SIZE(%rsi), %VEC(9)
|
||||
-#if VEC_SIZE < 32
|
||||
- VMOVU (VEC_SIZE * 2)(%rsi), %VEC(10)
|
||||
- VMOVU (VEC_SIZE * 3)(%rsi), %VEC(11)
|
||||
-#endif
|
||||
-#endif
|
||||
- VMOVU %VEC(8), (%rdi)
|
||||
-#if VEC_SIZE < 64
|
||||
- VMOVU %VEC(9), VEC_SIZE(%rdi)
|
||||
-#if VEC_SIZE < 32
|
||||
- VMOVU %VEC(10), (VEC_SIZE * 2)(%rdi)
|
||||
- VMOVU %VEC(11), (VEC_SIZE * 3)(%rdi)
|
||||
-#endif
|
||||
-#endif
|
||||
+
|
||||
+ /* First vec was also loaded into VEC(0). */
|
||||
+# if VEC_SIZE < 64
|
||||
+ VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||
+# if VEC_SIZE < 32
|
||||
+ VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2)
|
||||
+ VMOVU (VEC_SIZE * 3)(%rsi), %VEC(3)
|
||||
+# endif
|
||||
+# endif
|
||||
+ VMOVU %VEC(0), (%rdi)
|
||||
+# if VEC_SIZE < 64
|
||||
+ VMOVU %VEC(1), VEC_SIZE(%rdi)
|
||||
+# if VEC_SIZE < 32
|
||||
+ VMOVU %VEC(2), (VEC_SIZE * 2)(%rdi)
|
||||
+ VMOVU %VEC(3), (VEC_SIZE * 3)(%rdi)
|
||||
+# endif
|
||||
+# endif
|
||||
+
|
||||
/* Adjust source, destination, and size. */
|
||||
movq %rdi, %r8
|
||||
andq $63, %r8
|
||||
@@ -614,9 +767,13 @@ L(large_memcpy_2x):
|
||||
/* Adjust length. */
|
||||
addq %r8, %rdx
|
||||
|
||||
- /* Test if source and destination addresses will alias. If they do
|
||||
- the larger pipeline in large_memcpy_4x alleviated the
|
||||
+ /* Test if source and destination addresses will alias. If they
|
||||
+ do the larger pipeline in large_memcpy_4x alleviated the
|
||||
performance drop. */
|
||||
+
|
||||
+ /* ecx contains -(dst - src). not ecx will return dst - src - 1
|
||||
+ which works for testing aliasing. */
|
||||
+ notl %ecx
|
||||
testl $(PAGE_SIZE - VEC_SIZE * 8), %ecx
|
||||
jz L(large_memcpy_4x)
|
||||
|
||||
@@ -704,8 +861,8 @@ L(loop_large_memcpy_4x_outer):
|
||||
/* ecx stores inner loop counter. */
|
||||
movl $(PAGE_SIZE / LARGE_LOAD_SIZE), %ecx
|
||||
L(loop_large_memcpy_4x_inner):
|
||||
- /* Only one prefetch set per page as doing 4 pages give more time
|
||||
- for prefetcher to keep up. */
|
||||
+ /* Only one prefetch set per page as doing 4 pages give more
|
||||
+ time for prefetcher to keep up. */
|
||||
PREFETCH_ONE_SET(1, (%rsi), PREFETCHED_LOAD_SIZE)
|
||||
PREFETCH_ONE_SET(1, (%rsi), PAGE_SIZE + PREFETCHED_LOAD_SIZE)
|
||||
PREFETCH_ONE_SET(1, (%rsi), PAGE_SIZE * 2 + PREFETCHED_LOAD_SIZE)
|
131
SOURCES/glibc-upstream-2.34-182.patch
Normal file
131
SOURCES/glibc-upstream-2.34-182.patch
Normal file
@ -0,0 +1,131 @@
|
||||
commit cecbac52123456e2fbcff062a4165bf7b9174797
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Mon Nov 1 00:49:52 2021 -0500
|
||||
|
||||
x86: Double size of ERMS rep_movsb_threshold in dl-cacheinfo.h
|
||||
|
||||
No bug.
|
||||
|
||||
This patch doubles the rep_movsb_threshold when using ERMS. Based on
|
||||
benchmarks the vector copy loop, especially now that it handles 4k
|
||||
aliasing, is better for these medium ranged.
|
||||
|
||||
On Skylake with ERMS:
|
||||
|
||||
Size, Align1, Align2, dst>src,(rep movsb) / (vec copy)
|
||||
4096, 0, 0, 0, 0.975
|
||||
4096, 0, 0, 1, 0.953
|
||||
4096, 12, 0, 0, 0.969
|
||||
4096, 12, 0, 1, 0.872
|
||||
4096, 44, 0, 0, 0.979
|
||||
4096, 44, 0, 1, 0.83
|
||||
4096, 0, 12, 0, 1.006
|
||||
4096, 0, 12, 1, 0.989
|
||||
4096, 0, 44, 0, 0.739
|
||||
4096, 0, 44, 1, 0.942
|
||||
4096, 12, 12, 0, 1.009
|
||||
4096, 12, 12, 1, 0.973
|
||||
4096, 44, 44, 0, 0.791
|
||||
4096, 44, 44, 1, 0.961
|
||||
4096, 2048, 0, 0, 0.978
|
||||
4096, 2048, 0, 1, 0.951
|
||||
4096, 2060, 0, 0, 0.986
|
||||
4096, 2060, 0, 1, 0.963
|
||||
4096, 2048, 12, 0, 0.971
|
||||
4096, 2048, 12, 1, 0.941
|
||||
4096, 2060, 12, 0, 0.977
|
||||
4096, 2060, 12, 1, 0.949
|
||||
8192, 0, 0, 0, 0.85
|
||||
8192, 0, 0, 1, 0.845
|
||||
8192, 13, 0, 0, 0.937
|
||||
8192, 13, 0, 1, 0.939
|
||||
8192, 45, 0, 0, 0.932
|
||||
8192, 45, 0, 1, 0.927
|
||||
8192, 0, 13, 0, 0.621
|
||||
8192, 0, 13, 1, 0.62
|
||||
8192, 0, 45, 0, 0.53
|
||||
8192, 0, 45, 1, 0.516
|
||||
8192, 13, 13, 0, 0.664
|
||||
8192, 13, 13, 1, 0.659
|
||||
8192, 45, 45, 0, 0.593
|
||||
8192, 45, 45, 1, 0.575
|
||||
8192, 2048, 0, 0, 0.854
|
||||
8192, 2048, 0, 1, 0.834
|
||||
8192, 2061, 0, 0, 0.863
|
||||
8192, 2061, 0, 1, 0.857
|
||||
8192, 2048, 13, 0, 0.63
|
||||
8192, 2048, 13, 1, 0.629
|
||||
8192, 2061, 13, 0, 0.627
|
||||
8192, 2061, 13, 1, 0.62
|
||||
|
||||
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
(cherry picked from commit 475b63702ef38b69558fc3d31a0b66776a70f1d3)
|
||||
|
||||
diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
|
||||
index e6c94dfd023a25dc..2e43e67e4f4037d3 100644
|
||||
--- a/sysdeps/x86/dl-cacheinfo.h
|
||||
+++ b/sysdeps/x86/dl-cacheinfo.h
|
||||
@@ -866,12 +866,14 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
|
||||
/* NB: The REP MOVSB threshold must be greater than VEC_SIZE * 8. */
|
||||
unsigned int minimum_rep_movsb_threshold;
|
||||
#endif
|
||||
- /* NB: The default REP MOVSB threshold is 2048 * (VEC_SIZE / 16). */
|
||||
+ /* NB: The default REP MOVSB threshold is 4096 * (VEC_SIZE / 16) for
|
||||
+ VEC_SIZE == 64 or 32. For VEC_SIZE == 16, the default REP MOVSB
|
||||
+ threshold is 2048 * (VEC_SIZE / 16). */
|
||||
unsigned int rep_movsb_threshold;
|
||||
if (CPU_FEATURE_USABLE_P (cpu_features, AVX512F)
|
||||
&& !CPU_FEATURE_PREFERRED_P (cpu_features, Prefer_No_AVX512))
|
||||
{
|
||||
- rep_movsb_threshold = 2048 * (64 / 16);
|
||||
+ rep_movsb_threshold = 4096 * (64 / 16);
|
||||
#if HAVE_TUNABLES
|
||||
minimum_rep_movsb_threshold = 64 * 8;
|
||||
#endif
|
||||
@@ -879,7 +881,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
|
||||
else if (CPU_FEATURE_PREFERRED_P (cpu_features,
|
||||
AVX_Fast_Unaligned_Load))
|
||||
{
|
||||
- rep_movsb_threshold = 2048 * (32 / 16);
|
||||
+ rep_movsb_threshold = 4096 * (32 / 16);
|
||||
#if HAVE_TUNABLES
|
||||
minimum_rep_movsb_threshold = 32 * 8;
|
||||
#endif
|
||||
diff --git a/sysdeps/x86/dl-tunables.list b/sysdeps/x86/dl-tunables.list
|
||||
index dd6e1d65c9490d4f..419313804d49cf65 100644
|
||||
--- a/sysdeps/x86/dl-tunables.list
|
||||
+++ b/sysdeps/x86/dl-tunables.list
|
||||
@@ -32,17 +32,21 @@ glibc {
|
||||
}
|
||||
x86_rep_movsb_threshold {
|
||||
type: SIZE_T
|
||||
- # Since there is overhead to set up REP MOVSB operation, REP MOVSB
|
||||
- # isn't faster on short data. The memcpy micro benchmark in glibc
|
||||
- # shows that 2KB is the approximate value above which REP MOVSB
|
||||
- # becomes faster than SSE2 optimization on processors with Enhanced
|
||||
- # REP MOVSB. Since larger register size can move more data with a
|
||||
- # single load and store, the threshold is higher with larger register
|
||||
- # size. Note: Since the REP MOVSB threshold must be greater than 8
|
||||
- # times of vector size and the default value is 2048 * (vector size
|
||||
- # / 16), the default value and the minimum value must be updated at
|
||||
- # run-time. NB: Don't set the default value since we can't tell if
|
||||
- # the tunable value is set by user or not [BZ #27069].
|
||||
+ # Since there is overhead to set up REP MOVSB operation, REP
|
||||
+ # MOVSB isn't faster on short data. The memcpy micro benchmark
|
||||
+ # in glibc shows that 2KB is the approximate value above which
|
||||
+ # REP MOVSB becomes faster than SSE2 optimization on processors
|
||||
+ # with Enhanced REP MOVSB. Since larger register size can move
|
||||
+ # more data with a single load and store, the threshold is
|
||||
+ # higher with larger register size. Micro benchmarks show AVX
|
||||
+ # REP MOVSB becomes faster apprximately at 8KB. The AVX512
|
||||
+ # threshold is extrapolated to 16KB. For machines with FSRM the
|
||||
+ # threshold is universally set at 2112 bytes. Note: Since the
|
||||
+ # REP MOVSB threshold must be greater than 8 times of vector
|
||||
+ # size and the default value is 4096 * (vector size / 16), the
|
||||
+ # default value and the minimum value must be updated at
|
||||
+ # run-time. NB: Don't set the default value since we can't tell
|
||||
+ # if the tunable value is set by user or not [BZ #27069].
|
||||
minval: 1
|
||||
}
|
||||
x86_rep_stosb_threshold {
|
2423
SOURCES/glibc-upstream-2.34-183.patch
Normal file
2423
SOURCES/glibc-upstream-2.34-183.patch
Normal file
File diff suppressed because it is too large
Load Diff
104
SOURCES/glibc-upstream-2.34-184.patch
Normal file
104
SOURCES/glibc-upstream-2.34-184.patch
Normal file
@ -0,0 +1,104 @@
|
||||
commit 4bbd0f866ad0ff197f72346f776ebee9b7e1a706
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Fri Dec 3 15:29:25 2021 -0800
|
||||
|
||||
x86-64: Use notl in EVEX strcmp [BZ #28646]
|
||||
|
||||
Must use notl %edi here as lower bits are for CHAR comparisons
|
||||
potentially out of range thus can be 0 without indicating mismatch.
|
||||
This fixes BZ #28646.
|
||||
|
||||
Co-Authored-By: H.J. Lu <hjl.tools@gmail.com>
|
||||
(cherry picked from commit 4df1fa6ddc8925a75f3da644d5da3bb16eb33f02)
|
||||
|
||||
diff --git a/string/test-strcmp.c b/string/test-strcmp.c
|
||||
index 7feababf4ddc5603..a0255b9625fbcedd 100644
|
||||
--- a/string/test-strcmp.c
|
||||
+++ b/string/test-strcmp.c
|
||||
@@ -25,6 +25,7 @@
|
||||
# define TEST_NAME "strcmp"
|
||||
#endif
|
||||
#include "test-string.h"
|
||||
+#include <support/test-driver.h>
|
||||
|
||||
#ifdef WIDE
|
||||
# include <wchar.h>
|
||||
@@ -392,6 +393,32 @@ check2 (void)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+check3 (void)
|
||||
+{
|
||||
+ size_t size = 0xd000 + 0x4000;
|
||||
+ CHAR *s1, *s2;
|
||||
+ CHAR *buffer1 = mmap (NULL, size, PROT_READ | PROT_WRITE,
|
||||
+ MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
+ CHAR *buffer2 = mmap (NULL, size, PROT_READ | PROT_WRITE,
|
||||
+ MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
+ if (buffer1 == MAP_FAILED || buffer1 == MAP_FAILED)
|
||||
+ error (EXIT_UNSUPPORTED, errno, "mmap failed");
|
||||
+
|
||||
+ s1 = (CHAR *) (buffer1 + 0x8f8 / sizeof (CHAR));
|
||||
+ s2 = (CHAR *) (buffer2 + 0xcff3 / sizeof (CHAR));
|
||||
+
|
||||
+ STRCPY(s1, L("/export/redhat/rpms/BUILD/java-1.8.0-openjdk-1.8.0.312.b07-2.fc35.x86_64/openjdk/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java"));
|
||||
+ STRCPY(s2, L("/export/redhat/rpms/BUILD/java-1.8.0-openjdk-1.8.0.312.b07-2.fc35.x86_64/openjdk/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java"));
|
||||
+
|
||||
+ int exp_result = SIMPLE_STRCMP (s1, s2);
|
||||
+ FOR_EACH_IMPL (impl, 0)
|
||||
+ check_result (impl, s1, s2, exp_result);
|
||||
+
|
||||
+ munmap ((void *) buffer1, size);
|
||||
+ munmap ((void *) buffer2, size);
|
||||
+}
|
||||
+
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
@@ -400,6 +427,7 @@ test_main (void)
|
||||
test_init ();
|
||||
check();
|
||||
check2 ();
|
||||
+ check3 ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||
index 82f12ac89bcae20b..6f5c4bf984da2b80 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||
@@ -656,12 +656,13 @@ L(loop_cross_page):
|
||||
in YMM3 and 32 bytes at VEC_SIZE(%rdx, %r10). */
|
||||
VPCMP $0, VEC_SIZE(%rdx, %r10), %YMM3, %k3{%k4}
|
||||
kmovd %k3, %edi
|
||||
+ /* Must use notl %edi here as lower bits are for CHAR
|
||||
+ comparisons potentially out of range thus can be 0 without
|
||||
+ indicating mismatch. */
|
||||
+ notl %edi
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* Don't use subl since it is the upper 8 bits of EDI below. */
|
||||
- notl %edi
|
||||
andl $0xff, %edi
|
||||
-# else
|
||||
- incl %edi
|
||||
# endif
|
||||
|
||||
# ifdef USE_AS_WCSCMP
|
||||
@@ -743,12 +744,13 @@ L(loop_cross_page_2_vec):
|
||||
in YMM1 and 32 bytes at (VEC_SIZE * 3)(%rdx, %r10). */
|
||||
VPCMP $0, (VEC_SIZE * 3)(%rdx, %r10), %YMM1, %k3{%k4}
|
||||
kmovd %k3, %edi
|
||||
+ /* Must use notl %edi here as lower bits are for CHAR
|
||||
+ comparisons potentially out of range thus can be 0 without
|
||||
+ indicating mismatch. */
|
||||
+ notl %edi
|
||||
# ifdef USE_AS_WCSCMP
|
||||
/* Don't use subl since it is the upper 8 bits of EDI below. */
|
||||
- notl %edi
|
||||
andl $0xff, %edi
|
||||
-# else
|
||||
- incl %edi
|
||||
# endif
|
||||
|
||||
# ifdef USE_AS_WCSCMP
|
30
SOURCES/glibc-upstream-2.34-185.patch
Normal file
30
SOURCES/glibc-upstream-2.34-185.patch
Normal file
@ -0,0 +1,30 @@
|
||||
commit f3a99b2216114f89b20329ae7664b764248b4bbd
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Mon Dec 6 07:14:12 2021 -0800
|
||||
|
||||
x86: Don't set Prefer_No_AVX512 for processors with AVX512 and AVX-VNNI
|
||||
|
||||
Don't set Prefer_No_AVX512 on processors with AVX512 and AVX-VNNI since
|
||||
they won't lower CPU frequency when ZMM load and store instructions are
|
||||
used.
|
||||
|
||||
(cherry picked from commit ceeffe968c01b1202e482f4855cb6baf5c6cb713)
|
||||
|
||||
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
|
||||
index f4d4049e391cbabd..09590d8794b1c6fb 100644
|
||||
--- a/sysdeps/x86/cpu-features.c
|
||||
+++ b/sysdeps/x86/cpu-features.c
|
||||
@@ -566,8 +566,11 @@ disable_tsx:
|
||||
|= bit_arch_Prefer_No_VZEROUPPER;
|
||||
else
|
||||
{
|
||||
- cpu_features->preferred[index_arch_Prefer_No_AVX512]
|
||||
- |= bit_arch_Prefer_No_AVX512;
|
||||
+ /* Processors with AVX512 and AVX-VNNI won't lower CPU frequency
|
||||
+ when ZMM load and store instructions are used. */
|
||||
+ if (!CPU_FEATURES_CPU_P (cpu_features, AVX_VNNI))
|
||||
+ cpu_features->preferred[index_arch_Prefer_No_AVX512]
|
||||
+ |= bit_arch_Prefer_No_AVX512;
|
||||
|
||||
/* Avoid RTM abort triggered by VZEROUPPER inside a
|
||||
transactionally executing RTM region. */
|
384
SOURCES/glibc-upstream-2.34-186.patch
Normal file
384
SOURCES/glibc-upstream-2.34-186.patch
Normal file
@ -0,0 +1,384 @@
|
||||
commit c796418d00f65c8c5fbed477f3ba6da2bee64ece
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Fri Dec 24 18:54:41 2021 -0600
|
||||
|
||||
x86: Optimize L(less_vec) case in memcmp-evex-movbe.S
|
||||
|
||||
No bug.
|
||||
Optimizations are twofold.
|
||||
|
||||
1) Replace page cross and 0/1 checks with masked load instructions in
|
||||
L(less_vec). In applications this reduces branch-misses in the
|
||||
hot [0, 32] case.
|
||||
2) Change controlflow so that L(less_vec) case gets the fall through.
|
||||
|
||||
Change 2) helps copies in the [0, 32] size range but comes at the cost
|
||||
of copies in the [33, 64] size range. From profiles of GCC and
|
||||
Python3, 94%+ and 99%+ of calls are in the [0, 32] range so this
|
||||
appears to the the right tradeoff.
|
||||
|
||||
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
(cherry picked from commit abddd61de090ae84e380aff68a98bd94ef704667)
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||
index 640f6757fac8a356..d2899e7c7078cd41 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||
@@ -62,15 +62,18 @@ Latency:
|
||||
# define VMOVU vmovdqu64
|
||||
|
||||
# ifdef USE_AS_WMEMCMP
|
||||
+# define VMOVU_MASK vmovdqu32
|
||||
# define CHAR_SIZE 4
|
||||
# define VPCMP vpcmpd
|
||||
# define VPTEST vptestmd
|
||||
# else
|
||||
+# define VMOVU_MASK vmovdqu8
|
||||
# define CHAR_SIZE 1
|
||||
# define VPCMP vpcmpub
|
||||
# define VPTEST vptestmb
|
||||
# endif
|
||||
|
||||
+
|
||||
# define VEC_SIZE 32
|
||||
# define PAGE_SIZE 4096
|
||||
# define CHAR_PER_VEC (VEC_SIZE / CHAR_SIZE)
|
||||
@@ -102,12 +105,48 @@ ENTRY_P2ALIGN (MEMCMP, 6)
|
||||
movl %edx, %edx
|
||||
# endif
|
||||
cmp $CHAR_PER_VEC, %RDX_LP
|
||||
- jb L(less_vec)
|
||||
+ /* Fall through for [0, VEC_SIZE] as its the hottest. */
|
||||
+ ja L(more_1x_vec)
|
||||
+
|
||||
+ /* Create mask for CHAR's we want to compare. This allows us to
|
||||
+ avoid having to include page cross logic. */
|
||||
+ movl $-1, %ecx
|
||||
+ bzhil %edx, %ecx, %ecx
|
||||
+ kmovd %ecx, %k2
|
||||
+
|
||||
+ /* Safe to load full ymm with mask. */
|
||||
+ VMOVU_MASK (%rsi), %YMM2{%k2}
|
||||
+ VPCMP $4,(%rdi), %YMM2, %k1{%k2}
|
||||
+ kmovd %k1, %eax
|
||||
+ testl %eax, %eax
|
||||
+ jnz L(return_vec_0)
|
||||
+ ret
|
||||
|
||||
+ .p2align 4
|
||||
+L(return_vec_0):
|
||||
+ tzcntl %eax, %eax
|
||||
+# ifdef USE_AS_WMEMCMP
|
||||
+ movl (%rdi, %rax, CHAR_SIZE), %ecx
|
||||
+ xorl %edx, %edx
|
||||
+ cmpl (%rsi, %rax, CHAR_SIZE), %ecx
|
||||
+ /* NB: no partial register stall here because xorl zero idiom
|
||||
+ above. */
|
||||
+ setg %dl
|
||||
+ leal -1(%rdx, %rdx), %eax
|
||||
+# else
|
||||
+ movzbl (%rsi, %rax), %ecx
|
||||
+ movzbl (%rdi, %rax), %eax
|
||||
+ subl %ecx, %eax
|
||||
+# endif
|
||||
+ ret
|
||||
+
|
||||
+
|
||||
+ .p2align 4
|
||||
+L(more_1x_vec):
|
||||
/* From VEC to 2 * VEC. No branch when size == VEC_SIZE. */
|
||||
VMOVU (%rsi), %YMM1
|
||||
/* Use compare not equals to directly check for mismatch. */
|
||||
- VPCMP $4, (%rdi), %YMM1, %k1
|
||||
+ VPCMP $4,(%rdi), %YMM1, %k1
|
||||
kmovd %k1, %eax
|
||||
/* NB: eax must be destination register if going to
|
||||
L(return_vec_[0,2]). For L(return_vec_3) destination register
|
||||
@@ -131,13 +170,13 @@ ENTRY_P2ALIGN (MEMCMP, 6)
|
||||
|
||||
/* Check third and fourth VEC no matter what. */
|
||||
VMOVU (VEC_SIZE * 2)(%rsi), %YMM3
|
||||
- VPCMP $4, (VEC_SIZE * 2)(%rdi), %YMM3, %k1
|
||||
+ VPCMP $4,(VEC_SIZE * 2)(%rdi), %YMM3, %k1
|
||||
kmovd %k1, %eax
|
||||
testl %eax, %eax
|
||||
jnz L(return_vec_2)
|
||||
|
||||
VMOVU (VEC_SIZE * 3)(%rsi), %YMM4
|
||||
- VPCMP $4, (VEC_SIZE * 3)(%rdi), %YMM4, %k1
|
||||
+ VPCMP $4,(VEC_SIZE * 3)(%rdi), %YMM4, %k1
|
||||
kmovd %k1, %ecx
|
||||
testl %ecx, %ecx
|
||||
jnz L(return_vec_3)
|
||||
@@ -169,7 +208,7 @@ ENTRY_P2ALIGN (MEMCMP, 6)
|
||||
VMOVU (VEC_SIZE * 3)(%rsi), %YMM4
|
||||
/* Ternary logic to xor (VEC_SIZE * 3)(%rdi) with YMM4 while
|
||||
oring with YMM1. Result is stored in YMM4. */
|
||||
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||
+ vpternlogd $0xde,(VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||
|
||||
/* Or together YMM2, YMM3, and YMM4 into YMM4. */
|
||||
vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||
@@ -184,7 +223,8 @@ ENTRY_P2ALIGN (MEMCMP, 6)
|
||||
/* NB: eax must be zero to reach here. */
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
+
|
||||
+ .p2align 4,, 8
|
||||
L(8x_end_return_vec_0_1_2_3):
|
||||
movq %rdx, %rdi
|
||||
L(8x_return_vec_0_1_2_3):
|
||||
@@ -222,23 +262,6 @@ L(return_vec_3):
|
||||
# endif
|
||||
ret
|
||||
|
||||
- .p2align 4
|
||||
-L(return_vec_0):
|
||||
- tzcntl %eax, %eax
|
||||
-# ifdef USE_AS_WMEMCMP
|
||||
- movl (%rdi, %rax, CHAR_SIZE), %ecx
|
||||
- xorl %edx, %edx
|
||||
- cmpl (%rsi, %rax, CHAR_SIZE), %ecx
|
||||
- /* NB: no partial register stall here because xorl zero idiom
|
||||
- above. */
|
||||
- setg %dl
|
||||
- leal -1(%rdx, %rdx), %eax
|
||||
-# else
|
||||
- movzbl (%rsi, %rax), %ecx
|
||||
- movzbl (%rdi, %rax), %eax
|
||||
- subl %ecx, %eax
|
||||
-# endif
|
||||
- ret
|
||||
|
||||
.p2align 4
|
||||
L(return_vec_1):
|
||||
@@ -297,7 +320,7 @@ L(loop_4x_vec):
|
||||
VMOVU (VEC_SIZE * 2)(%rsi, %rdi), %YMM3
|
||||
vpxorq (VEC_SIZE * 2)(%rdi), %YMM3, %YMM3
|
||||
VMOVU (VEC_SIZE * 3)(%rsi, %rdi), %YMM4
|
||||
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||
+ vpternlogd $0xde,(VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||
vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||
VPTEST %YMM4, %YMM4, %k1
|
||||
kmovd %k1, %ecx
|
||||
@@ -324,7 +347,7 @@ L(loop_4x_vec):
|
||||
VMOVU VEC_SIZE(%rsi, %rdx), %YMM2
|
||||
vpxorq VEC_SIZE(%rdx), %YMM2, %YMM2
|
||||
VMOVU (VEC_SIZE * 3)(%rsi, %rdx), %YMM4
|
||||
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdx), %YMM1, %YMM4
|
||||
+ vpternlogd $0xde,(VEC_SIZE * 3)(%rdx), %YMM1, %YMM4
|
||||
vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||
VPTEST %YMM4, %YMM4, %k1
|
||||
kmovd %k1, %ecx
|
||||
@@ -336,14 +359,14 @@ L(loop_4x_vec):
|
||||
/* Only entry is from L(more_8x_vec). */
|
||||
.p2align 4,, 10
|
||||
L(8x_last_2x_vec):
|
||||
- VPCMP $4, (VEC_SIZE * 2)(%rdx), %YMM3, %k1
|
||||
+ VPCMP $4,(VEC_SIZE * 2)(%rdx), %YMM3, %k1
|
||||
kmovd %k1, %eax
|
||||
testl %eax, %eax
|
||||
jnz L(8x_return_vec_2)
|
||||
/* Naturally aligned to 16 bytes. */
|
||||
L(8x_last_1x_vec):
|
||||
VMOVU (VEC_SIZE * 3)(%rsi, %rdx), %YMM1
|
||||
- VPCMP $4, (VEC_SIZE * 3)(%rdx), %YMM1, %k1
|
||||
+ VPCMP $4,(VEC_SIZE * 3)(%rdx), %YMM1, %k1
|
||||
kmovd %k1, %eax
|
||||
testl %eax, %eax
|
||||
jnz L(8x_return_vec_3)
|
||||
@@ -392,7 +415,9 @@ L(last_1x_vec):
|
||||
jnz L(return_vec_0_end)
|
||||
ret
|
||||
|
||||
- .p2align 4,, 10
|
||||
+
|
||||
+ /* Don't align. Takes 2-fetch blocks either way and aligning
|
||||
+ will cause code to spill into another cacheline. */
|
||||
L(return_vec_1_end):
|
||||
/* Use bsf to save code size. This is necessary to have
|
||||
L(one_or_less) fit in aligning bytes between. */
|
||||
@@ -411,31 +436,8 @@ L(return_vec_1_end):
|
||||
# endif
|
||||
ret
|
||||
|
||||
- /* NB: L(one_or_less) fits in alignment padding between
|
||||
- L(return_vec_1_end) and L(return_vec_0_end). */
|
||||
-# ifdef USE_AS_WMEMCMP
|
||||
-L(one_or_less):
|
||||
- jb L(zero)
|
||||
- movl (%rdi), %ecx
|
||||
- xorl %edx, %edx
|
||||
- cmpl (%rsi), %ecx
|
||||
- je L(zero)
|
||||
- setg %dl
|
||||
- leal -1(%rdx, %rdx), %eax
|
||||
- ret
|
||||
-# else
|
||||
-L(one_or_less):
|
||||
- jb L(zero)
|
||||
- movzbl (%rsi), %ecx
|
||||
- movzbl (%rdi), %eax
|
||||
- subl %ecx, %eax
|
||||
- ret
|
||||
-# endif
|
||||
-L(zero):
|
||||
- xorl %eax, %eax
|
||||
- ret
|
||||
-
|
||||
- .p2align 4
|
||||
+ /* Don't align. Takes 2-fetch blocks either way and aligning
|
||||
+ will cause code to spill into another cacheline. */
|
||||
L(return_vec_0_end):
|
||||
tzcntl %eax, %eax
|
||||
addl %edx, %eax
|
||||
@@ -451,146 +453,7 @@ L(return_vec_0_end):
|
||||
subl %ecx, %eax
|
||||
# endif
|
||||
ret
|
||||
+ /* 1-byte until next cache line. */
|
||||
|
||||
- .p2align 4
|
||||
-L(less_vec):
|
||||
- /* Check if one or less CHAR. This is necessary for size == 0
|
||||
- but is also faster for size == CHAR_SIZE. */
|
||||
- cmpl $1, %edx
|
||||
- jbe L(one_or_less)
|
||||
-
|
||||
- /* Check if loading one VEC from either s1 or s2 could cause a
|
||||
- page cross. This can have false positives but is by far the
|
||||
- fastest method. */
|
||||
- movl %edi, %eax
|
||||
- orl %esi, %eax
|
||||
- andl $(PAGE_SIZE - 1), %eax
|
||||
- cmpl $(PAGE_SIZE - VEC_SIZE), %eax
|
||||
- jg L(page_cross_less_vec)
|
||||
-
|
||||
- /* No page cross possible. */
|
||||
- VMOVU (%rsi), %YMM2
|
||||
- VPCMP $4, (%rdi), %YMM2, %k1
|
||||
- kmovd %k1, %eax
|
||||
- /* Check if any matches where in bounds. Intentionally not
|
||||
- storing result in eax to limit dependency chain if it goes to
|
||||
- L(return_vec_0_lv). */
|
||||
- bzhil %edx, %eax, %edx
|
||||
- jnz L(return_vec_0_lv)
|
||||
- xorl %eax, %eax
|
||||
- ret
|
||||
-
|
||||
- /* Essentially duplicate of L(return_vec_0). Ends up not costing
|
||||
- any code as shrinks L(less_vec) by allowing 2-byte encoding of
|
||||
- the jump and ends up fitting in aligning bytes. As well fits on
|
||||
- same cache line as L(less_vec) so also saves a line from having
|
||||
- to be fetched on cold calls to memcmp. */
|
||||
- .p2align 4,, 4
|
||||
-L(return_vec_0_lv):
|
||||
- tzcntl %eax, %eax
|
||||
-# ifdef USE_AS_WMEMCMP
|
||||
- movl (%rdi, %rax, CHAR_SIZE), %ecx
|
||||
- xorl %edx, %edx
|
||||
- cmpl (%rsi, %rax, CHAR_SIZE), %ecx
|
||||
- /* NB: no partial register stall here because xorl zero idiom
|
||||
- above. */
|
||||
- setg %dl
|
||||
- leal -1(%rdx, %rdx), %eax
|
||||
-# else
|
||||
- movzbl (%rsi, %rax), %ecx
|
||||
- movzbl (%rdi, %rax), %eax
|
||||
- subl %ecx, %eax
|
||||
-# endif
|
||||
- ret
|
||||
-
|
||||
- .p2align 4
|
||||
-L(page_cross_less_vec):
|
||||
- /* if USE_AS_WMEMCMP it can only be 0, 4, 8, 12, 16, 20, 24, 28
|
||||
- bytes. */
|
||||
- cmpl $(16 / CHAR_SIZE), %edx
|
||||
- jae L(between_16_31)
|
||||
-# ifndef USE_AS_WMEMCMP
|
||||
- cmpl $8, %edx
|
||||
- jae L(between_8_15)
|
||||
- cmpl $4, %edx
|
||||
- jb L(between_2_3)
|
||||
-
|
||||
- /* Load as big endian with overlapping movbe to avoid branches.
|
||||
- */
|
||||
- movbe (%rdi), %eax
|
||||
- movbe (%rsi), %ecx
|
||||
- shlq $32, %rax
|
||||
- shlq $32, %rcx
|
||||
- movbe -4(%rdi, %rdx), %edi
|
||||
- movbe -4(%rsi, %rdx), %esi
|
||||
- orq %rdi, %rax
|
||||
- orq %rsi, %rcx
|
||||
- subq %rcx, %rax
|
||||
- /* edx is guranteed to be positive int32 in range [4, 7]. */
|
||||
- cmovne %edx, %eax
|
||||
- /* ecx is -1 if rcx > rax. Otherwise 0. */
|
||||
- sbbl %ecx, %ecx
|
||||
- /* If rcx > rax, then ecx is 0 and eax is positive. If rcx ==
|
||||
- rax then eax and ecx are zero. If rax < rax then ecx is -1 so
|
||||
- eax doesn't matter. */
|
||||
- orl %ecx, %eax
|
||||
- ret
|
||||
-
|
||||
- .p2align 4,, 8
|
||||
-L(between_8_15):
|
||||
-# endif
|
||||
- /* If USE_AS_WMEMCMP fall through into 8-15 byte case. */
|
||||
- vmovq (%rdi), %xmm1
|
||||
- vmovq (%rsi), %xmm2
|
||||
- VPCMP $4, %xmm1, %xmm2, %k1
|
||||
- kmovd %k1, %eax
|
||||
- testl %eax, %eax
|
||||
- jnz L(return_vec_0_lv)
|
||||
- /* Use overlapping loads to avoid branches. */
|
||||
- vmovq -8(%rdi, %rdx, CHAR_SIZE), %xmm1
|
||||
- vmovq -8(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||
- VPCMP $4, %xmm1, %xmm2, %k1
|
||||
- addl $(CHAR_PER_VEC - (8 / CHAR_SIZE)), %edx
|
||||
- kmovd %k1, %eax
|
||||
- testl %eax, %eax
|
||||
- jnz L(return_vec_0_end)
|
||||
- ret
|
||||
-
|
||||
- .p2align 4,, 8
|
||||
-L(between_16_31):
|
||||
- /* From 16 to 31 bytes. No branch when size == 16. */
|
||||
-
|
||||
- /* Use movups to save code size. */
|
||||
- vmovdqu (%rsi), %xmm2
|
||||
- VPCMP $4, (%rdi), %xmm2, %k1
|
||||
- kmovd %k1, %eax
|
||||
- testl %eax, %eax
|
||||
- jnz L(return_vec_0_lv)
|
||||
- /* Use overlapping loads to avoid branches. */
|
||||
- vmovdqu -16(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||
- VPCMP $4, -16(%rdi, %rdx, CHAR_SIZE), %xmm2, %k1
|
||||
- addl $(CHAR_PER_VEC - (16 / CHAR_SIZE)), %edx
|
||||
- kmovd %k1, %eax
|
||||
- testl %eax, %eax
|
||||
- jnz L(return_vec_0_end)
|
||||
- ret
|
||||
-
|
||||
-# ifndef USE_AS_WMEMCMP
|
||||
-L(between_2_3):
|
||||
- /* Load as big endian to avoid branches. */
|
||||
- movzwl (%rdi), %eax
|
||||
- movzwl (%rsi), %ecx
|
||||
- shll $8, %eax
|
||||
- shll $8, %ecx
|
||||
- bswap %eax
|
||||
- bswap %ecx
|
||||
- movzbl -1(%rdi, %rdx), %edi
|
||||
- movzbl -1(%rsi, %rdx), %esi
|
||||
- orl %edi, %eax
|
||||
- orl %esi, %ecx
|
||||
- /* Subtraction is okay because the upper 8 bits are zero. */
|
||||
- subl %ecx, %eax
|
||||
- ret
|
||||
-# endif
|
||||
END (MEMCMP)
|
||||
#endif
|
42
SOURCES/glibc-upstream-2.34-187.patch
Normal file
42
SOURCES/glibc-upstream-2.34-187.patch
Normal file
@ -0,0 +1,42 @@
|
||||
commit 9681691402052b727e01ae3375c73e0f76566593
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Apr 27 13:59:26 2022 -0300
|
||||
|
||||
linux: Fix missing internal 64 bit time_t stat usage
|
||||
|
||||
These are two missing spots initially done by 52a5fe70a2c77935.
|
||||
|
||||
Checked on i686-linux-gnu.
|
||||
|
||||
(cherry picked from commit 834ddd0432f68d6dc85b6aac95065721af0d86e9)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/faccessat.c b/sysdeps/unix/sysv/linux/faccessat.c
|
||||
index 13160d32499c4e58..00e4ce7f80ee2dfe 100644
|
||||
--- a/sysdeps/unix/sysv/linux/faccessat.c
|
||||
+++ b/sysdeps/unix/sysv/linux/faccessat.c
|
||||
@@ -39,8 +39,8 @@ __faccessat (int fd, const char *file, int mode, int flag)
|
||||
if ((flag == 0 || ((flag & ~AT_EACCESS) == 0 && ! __libc_enable_secure)))
|
||||
return INLINE_SYSCALL (faccessat, 3, fd, file, mode);
|
||||
|
||||
- struct stat64 stats;
|
||||
- if (__fstatat64 (fd, file, &stats, flag & AT_SYMLINK_NOFOLLOW))
|
||||
+ struct __stat64_t64 stats;
|
||||
+ if (__fstatat64_time64 (fd, file, &stats, flag & AT_SYMLINK_NOFOLLOW))
|
||||
return -1;
|
||||
|
||||
mode &= (X_OK | W_OK | R_OK); /* Clear any bogus bits. */
|
||||
diff --git a/sysdeps/unix/sysv/linux/pathconf.c b/sysdeps/unix/sysv/linux/pathconf.c
|
||||
index b599a66c930cad4d..f79930303118ebcd 100644
|
||||
--- a/sysdeps/unix/sysv/linux/pathconf.c
|
||||
+++ b/sysdeps/unix/sysv/linux/pathconf.c
|
||||
@@ -110,8 +110,8 @@ distinguish_extX (const struct statfs *fsbuf, const char *file, int fd)
|
||||
&& strcmp (mntbuf.mnt_type, "ext4") != 0)
|
||||
continue;
|
||||
|
||||
- struct stat64 fsst;
|
||||
- if (__stat64 (mntbuf.mnt_dir, &fsst) >= 0
|
||||
+ struct __stat64_t64 fsst;
|
||||
+ if (__stat64_time64 (mntbuf.mnt_dir, &fsst) >= 0
|
||||
&& st.st_dev == fsst.st_dev)
|
||||
{
|
||||
if (strcmp (mntbuf.mnt_type, "ext4") == 0)
|
39
SOURCES/glibc-upstream-2.34-188.patch
Normal file
39
SOURCES/glibc-upstream-2.34-188.patch
Normal file
@ -0,0 +1,39 @@
|
||||
commit 55640ed3fde48360a8e8083be4843bd2dc7cecfe
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Tue Apr 26 10:52:41 2022 -0400
|
||||
|
||||
i386: Regenerate ulps
|
||||
|
||||
These failures were caught while building glibc master for Fedora
|
||||
Rawhide which is built with '-mtune=generic -msse2 -mfpmath=sse'
|
||||
using gcc 11.3 (gcc-11.3.1-2.fc35) on a Cascadelake Intel Xeon
|
||||
processor.
|
||||
|
||||
(cherry picked from commit e465d97653311c3687aee49de782177353acfe86)
|
||||
|
||||
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
|
||||
index 7601049110789201..84e6686eba5fe79a 100644
|
||||
--- a/sysdeps/i386/fpu/libm-test-ulps
|
||||
+++ b/sysdeps/i386/fpu/libm-test-ulps
|
||||
@@ -668,7 +668,7 @@ ldouble: 4
|
||||
|
||||
Function: Imaginary part of "clog10":
|
||||
double: 2
|
||||
-float: 1
|
||||
+float: 2
|
||||
float128: 2
|
||||
ldouble: 2
|
||||
|
||||
diff --git a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps
|
||||
index a39c89cec1141935..cc21e6907fe8b6a3 100644
|
||||
--- a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps
|
||||
+++ b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps
|
||||
@@ -668,7 +668,7 @@ ldouble: 4
|
||||
|
||||
Function: Imaginary part of "clog10":
|
||||
double: 2
|
||||
-float: 1
|
||||
+float: 2
|
||||
float128: 2
|
||||
ldouble: 2
|
||||
|
116
SOURCES/glibc-upstream-2.34-189.patch
Normal file
116
SOURCES/glibc-upstream-2.34-189.patch
Normal file
@ -0,0 +1,116 @@
|
||||
commit 88a8637cb4658cd91a002659db05867716b88b36
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Apr 27 13:40:30 2022 -0300
|
||||
|
||||
linux: Fix fchmodat with AT_SYMLINK_NOFOLLOW for 64 bit time_t (BZ#29097)
|
||||
|
||||
The AT_SYMLINK_NOFOLLOW emulation ues the default 32 bit stat internal
|
||||
calls, which fails with EOVERFLOW if the file constains timestamps
|
||||
beyond 2038.
|
||||
|
||||
Checked on i686-linux-gnu.
|
||||
|
||||
(cherry picked from commit 118a2aee07f64d605b6668cbe195c1f44eac6be6)
|
||||
|
||||
diff --git a/io/Makefile b/io/Makefile
|
||||
index 9871ecbc74020a6d..01968b81042e01e4 100644
|
||||
--- a/io/Makefile
|
||||
+++ b/io/Makefile
|
||||
@@ -81,16 +81,17 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
|
||||
tst-closefrom \
|
||||
|
||||
tests-time64 := \
|
||||
+ tst-fcntl-time64 \
|
||||
+ tst-fts-time64 \
|
||||
tst-futimens-time64 \
|
||||
tst-futimes-time64\
|
||||
- tst-fts-time64 \
|
||||
+ tst-futimesat-time64 \
|
||||
+ tst-lchmod-time64 \
|
||||
tst-lutimes-time64 \
|
||||
tst-stat-time64 \
|
||||
- tst-futimesat-time64 \
|
||||
tst-utime-time64 \
|
||||
tst-utimensat-time64 \
|
||||
tst-utimes-time64 \
|
||||
- tst-fcntl-time64 \
|
||||
# tests-time64
|
||||
|
||||
# Likewise for statx, but we do not need static linking here.
|
||||
@@ -134,6 +135,7 @@ CFLAGS-close.c += -fexceptions -fasynchronous-unwind-tables
|
||||
|
||||
CFLAGS-test-stat.c += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
|
||||
CFLAGS-test-lfs.c += -D_LARGEFILE64_SOURCE
|
||||
+CFLAGS-tst-lchmod.c += -D_FILE_OFFSET_BITS=64
|
||||
|
||||
test-stat2-ARGS = Makefile . $(objpfx)test-stat2
|
||||
|
||||
diff --git a/io/tst-lchmod-time64.c b/io/tst-lchmod-time64.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f2b7cc9d358f2a77
|
||||
--- /dev/null
|
||||
+++ b/io/tst-lchmod-time64.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define CHECK_TIME64
|
||||
+#include "tst-lchmod.c"
|
||||
diff --git a/io/tst-lchmod.c b/io/tst-lchmod.c
|
||||
index 0fe98e01b74b713d..472766b186975922 100644
|
||||
--- a/io/tst-lchmod.c
|
||||
+++ b/io/tst-lchmod.c
|
||||
@@ -66,10 +66,27 @@ select_path (bool do_relative_path, const char *full_path, const char *relative_
|
||||
return full_path;
|
||||
}
|
||||
|
||||
+static void
|
||||
+update_file_time_to_y2038 (const char *fname, int flags)
|
||||
+{
|
||||
+#ifdef CHECK_TIME64
|
||||
+ /* Y2038 threshold plus 1 second. */
|
||||
+ const struct timespec ts[] = { { 0x80000001LL, 0}, { 0x80000001LL } };
|
||||
+ TEST_VERIFY_EXIT (utimensat (AT_FDCWD, fname, ts, flags) == 0);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static void
|
||||
test_1 (bool do_relative_path, int (*chmod_func) (int fd, const char *, mode_t, int))
|
||||
{
|
||||
char *tempdir = support_create_temp_directory ("tst-lchmod-");
|
||||
+#ifdef CHECK_TIME64
|
||||
+ if (!support_path_support_time64 (tempdir))
|
||||
+ {
|
||||
+ puts ("info: test skipped, filesystem does not support 64 bit time_t");
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
char *path_dangling = xasprintf ("%s/dangling", tempdir);
|
||||
char *path_file = xasprintf ("%s/file", tempdir);
|
||||
@@ -93,9 +110,12 @@ test_1 (bool do_relative_path, int (*chmod_func) (int fd, const char *, mode_t,
|
||||
xsymlink ("loop", path_loop);
|
||||
xsymlink ("target-does-not-exist", path_dangling);
|
||||
|
||||
+ update_file_time_to_y2038 (path_file, 0);
|
||||
+ update_file_time_to_y2038 (path_to_file, AT_SYMLINK_NOFOLLOW);
|
||||
+
|
||||
/* Check that the modes do not collide with what we will use in the
|
||||
test. */
|
||||
- struct stat64 st;
|
||||
+ struct stat st;
|
||||
xstat (path_file, &st);
|
||||
TEST_VERIFY ((st.st_mode & 0777) != 1);
|
||||
xlstat (path_to_file, &st);
|
||||
diff --git a/sysdeps/unix/sysv/linux/fchmodat.c b/sysdeps/unix/sysv/linux/fchmodat.c
|
||||
index 5bd1eb96a5d78130..b0cf61949a9302d9 100644
|
||||
--- a/sysdeps/unix/sysv/linux/fchmodat.c
|
||||
+++ b/sysdeps/unix/sysv/linux/fchmodat.c
|
||||
@@ -48,8 +48,8 @@ fchmodat (int fd, const char *file, mode_t mode, int flag)
|
||||
|
||||
/* Use fstatat because fstat does not work on O_PATH descriptors
|
||||
before Linux 3.6. */
|
||||
- struct stat64 st;
|
||||
- if (__fstatat64 (pathfd, "", &st, AT_EMPTY_PATH) != 0)
|
||||
+ struct __stat64_t64 st;
|
||||
+ if (__fstatat64_time64 (pathfd, "", &st, AT_EMPTY_PATH) != 0)
|
||||
{
|
||||
__close_nocancel (pathfd);
|
||||
return -1;
|
189
SOURCES/glibc-upstream-2.34-190.patch
Normal file
189
SOURCES/glibc-upstream-2.34-190.patch
Normal file
@ -0,0 +1,189 @@
|
||||
commit c66c92181ddbd82306537a608e8c0282587131de
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Wed Mar 30 17:44:02 2022 -0400
|
||||
|
||||
posix/glob.c: update from gnulib
|
||||
|
||||
Copied from gnulib/lib/glob.c in order to fix rhbz 1982608
|
||||
Also fixes swbz 25659
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit 7c477b57a31487eda516db02b9e04f22d1a6e6af)
|
||||
|
||||
diff --git a/posix/glob.c b/posix/glob.c
|
||||
index 593a4c358f3d42e5..6af310a1aa31401a 100644
|
||||
--- a/posix/glob.c
|
||||
+++ b/posix/glob.c
|
||||
@@ -21,13 +21,14 @@
|
||||
optimizes away the pattern == NULL test below. */
|
||||
# define _GL_ARG_NONNULL(params)
|
||||
|
||||
-# include <config.h>
|
||||
+# include <libc-config.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdbool.h>
|
||||
@@ -56,6 +57,8 @@
|
||||
# define sysconf(id) __sysconf (id)
|
||||
# define closedir(dir) __closedir (dir)
|
||||
# define opendir(name) __opendir (name)
|
||||
+# undef dirfd
|
||||
+# define dirfd(str) __dirfd (str)
|
||||
# define readdir(str) __readdir64 (str)
|
||||
# define getpwnam_r(name, bufp, buf, len, res) \
|
||||
__getpwnam_r (name, bufp, buf, len, res)
|
||||
@@ -69,11 +72,8 @@
|
||||
# ifndef GLOB_LSTAT
|
||||
# define GLOB_LSTAT gl_lstat
|
||||
# endif
|
||||
-# ifndef GLOB_STAT64
|
||||
-# define GLOB_STAT64 __stat64
|
||||
-# endif
|
||||
-# ifndef GLOB_LSTAT64
|
||||
-# define GLOB_LSTAT64 __lstat64
|
||||
+# ifndef GLOB_FSTATAT64
|
||||
+# define GLOB_FSTATAT64 __fstatat64
|
||||
# endif
|
||||
# include <shlib-compat.h>
|
||||
#else /* !_LIBC */
|
||||
@@ -88,8 +88,7 @@
|
||||
# define struct_stat struct stat
|
||||
# define struct_stat64 struct stat
|
||||
# define GLOB_LSTAT gl_lstat
|
||||
-# define GLOB_STAT64 stat
|
||||
-# define GLOB_LSTAT64 lstat
|
||||
+# define GLOB_FSTATAT64 fstatat
|
||||
#endif /* _LIBC */
|
||||
|
||||
#include <fnmatch.h>
|
||||
@@ -215,7 +214,8 @@ glob_lstat (glob_t *pglob, int flags, const char *fullname)
|
||||
} ust;
|
||||
return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
|
||||
? pglob->GLOB_LSTAT (fullname, &ust.st)
|
||||
- : GLOB_LSTAT64 (fullname, &ust.st64));
|
||||
+ : GLOB_FSTATAT64 (AT_FDCWD, fullname, &ust.st64,
|
||||
+ AT_SYMLINK_NOFOLLOW));
|
||||
}
|
||||
|
||||
/* Set *R = A + B. Return true if the answer is mathematically
|
||||
@@ -257,7 +257,8 @@ is_dir (char const *filename, int flags, glob_t const *pglob)
|
||||
struct_stat64 st64;
|
||||
return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
|
||||
? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
|
||||
- : GLOB_STAT64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
|
||||
+ : (GLOB_FSTATAT64 (AT_FDCWD, filename, &st64, 0) == 0
|
||||
+ && S_ISDIR (st64.st_mode)));
|
||||
}
|
||||
|
||||
/* Find the end of the sub-pattern in a brace expression. */
|
||||
@@ -747,6 +748,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
|
||||
else
|
||||
{
|
||||
#ifndef WINDOWS32
|
||||
+ /* Recognize ~user as a shorthand for the specified user's home
|
||||
+ directory. */
|
||||
char *end_name = strchr (dirname, '/');
|
||||
char *user_name;
|
||||
int malloc_user_name = 0;
|
||||
@@ -885,7 +888,22 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
|
||||
}
|
||||
scratch_buffer_free (&pwtmpbuf);
|
||||
}
|
||||
-#endif /* !WINDOWS32 */
|
||||
+#else /* WINDOWS32 */
|
||||
+ /* On native Windows, access to a user's home directory
|
||||
+ (via GetUserProfileDirectory) or to a user's environment
|
||||
+ variables (via ExpandEnvironmentStringsForUser) requires
|
||||
+ the credentials of the user. Therefore we cannot support
|
||||
+ the ~user syntax on this platform.
|
||||
+ Handling ~user specially (and treat it like plain ~) if
|
||||
+ user is getenv ("USERNAME") would not be a good idea,
|
||||
+ since it would make people think that ~user is supported
|
||||
+ in general. */
|
||||
+ if (flags & GLOB_TILDE_CHECK)
|
||||
+ {
|
||||
+ retval = GLOB_NOMATCH;
|
||||
+ goto out;
|
||||
+ }
|
||||
+#endif /* WINDOWS32 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1266,6 +1284,8 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||
{
|
||||
size_t dirlen = strlen (directory);
|
||||
void *stream = NULL;
|
||||
+ struct scratch_buffer s;
|
||||
+ scratch_buffer_init (&s);
|
||||
# define GLOBNAMES_MEMBERS(nnames) \
|
||||
struct globnames *next; size_t count; char *name[nnames];
|
||||
struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
|
||||
@@ -1337,6 +1357,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||
}
|
||||
else
|
||||
{
|
||||
+ int dfd = dirfd (stream);
|
||||
int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
|
||||
| ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
|
||||
flags |= GLOB_MAGCHAR;
|
||||
@@ -1364,8 +1385,32 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||
if (flags & GLOB_ONLYDIR)
|
||||
switch (readdir_result_type (d))
|
||||
{
|
||||
- case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
|
||||
default: continue;
|
||||
+ case DT_DIR: break;
|
||||
+ case DT_LNK: case DT_UNKNOWN:
|
||||
+ /* The filesystem was too lazy to give us a hint,
|
||||
+ so we have to do it the hard way. */
|
||||
+ if (__glibc_unlikely (dfd < 0 || flags & GLOB_ALTDIRFUNC))
|
||||
+ {
|
||||
+ size_t namelen = strlen (d.name);
|
||||
+ size_t need = dirlen + 1 + namelen + 1;
|
||||
+ if (s.length < need
|
||||
+ && !scratch_buffer_set_array_size (&s, need, 1))
|
||||
+ goto memory_error;
|
||||
+ char *p = mempcpy (s.data, directory, dirlen);
|
||||
+ *p = '/';
|
||||
+ p += p[-1] != '/';
|
||||
+ memcpy (p, d.name, namelen + 1);
|
||||
+ if (! is_dir (s.data, flags, pglob))
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ struct_stat64 st64;
|
||||
+ if (! (GLOB_FSTATAT64 (dfd, d.name, &st64, 0) == 0
|
||||
+ && S_ISDIR (st64.st_mode)))
|
||||
+ continue;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (fnmatch (pattern, d.name, fnm_flags) == 0)
|
||||
@@ -1497,5 +1542,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||
__set_errno (save);
|
||||
}
|
||||
|
||||
+ scratch_buffer_free (&s);
|
||||
return result;
|
||||
}
|
||||
diff --git a/sysdeps/unix/sysv/linux/glob64-time64.c b/sysdeps/unix/sysv/linux/glob64-time64.c
|
||||
index a465f70905e5a8a3..95efe4c4f4624967 100644
|
||||
--- a/sysdeps/unix/sysv/linux/glob64-time64.c
|
||||
+++ b/sysdeps/unix/sysv/linux/glob64-time64.c
|
||||
@@ -37,6 +37,7 @@
|
||||
# define GLOB_LSTAT gl_lstat
|
||||
# define GLOB_STAT64 __stat64_time64
|
||||
# define GLOB_LSTAT64 __lstat64_time64
|
||||
+# define GLOB_FSTATAT64 __fstatat64_time64
|
||||
|
||||
# define COMPILE_GLOB64 1
|
||||
|
35
SOURCES/glibc-upstream-2.34-191.patch
Normal file
35
SOURCES/glibc-upstream-2.34-191.patch
Normal file
@ -0,0 +1,35 @@
|
||||
commit bc6fba3c8048b11c9f73db03339c97a2fec3f0cf
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Wed Nov 17 14:25:16 2021 +0000
|
||||
|
||||
Add PF_MCTP, AF_MCTP from Linux 5.15 to bits/socket.h
|
||||
|
||||
Linux 5.15 adds a new address / protocol family PF_MCTP / AF_MCTP; add
|
||||
these constants to bits/socket.h.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
(cherry picked from commit bdeb7a8fa9989d18dab6310753d04d908125dc1d)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
|
||||
index a011a8c0959b9970..7bb9e863d7329da9 100644
|
||||
--- a/sysdeps/unix/sysv/linux/bits/socket.h
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/socket.h
|
||||
@@ -86,7 +86,8 @@ typedef __socklen_t socklen_t;
|
||||
#define PF_QIPCRTR 42 /* Qualcomm IPC Router. */
|
||||
#define PF_SMC 43 /* SMC sockets. */
|
||||
#define PF_XDP 44 /* XDP sockets. */
|
||||
-#define PF_MAX 45 /* For now.. */
|
||||
+#define PF_MCTP 45 /* Management component transport protocol. */
|
||||
+#define PF_MAX 46 /* For now.. */
|
||||
|
||||
/* Address families. */
|
||||
#define AF_UNSPEC PF_UNSPEC
|
||||
@@ -137,6 +138,7 @@ typedef __socklen_t socklen_t;
|
||||
#define AF_QIPCRTR PF_QIPCRTR
|
||||
#define AF_SMC PF_SMC
|
||||
#define AF_XDP PF_XDP
|
||||
+#define AF_MCTP PF_MCTP
|
||||
#define AF_MAX PF_MAX
|
||||
|
||||
/* Socket level values. Others are defined in the appropriate headers.
|
27
SOURCES/glibc-upstream-2.34-192.patch
Normal file
27
SOURCES/glibc-upstream-2.34-192.patch
Normal file
@ -0,0 +1,27 @@
|
||||
commit fd5dbfd1cd98cb2f12f9e9f7004a4d25ab0c977f
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Nov 22 15:30:12 2021 +0000
|
||||
|
||||
Update kernel version to 5.15 in tst-mman-consts.py
|
||||
|
||||
This patch updates the kernel version in the test tst-mman-consts.py
|
||||
to 5.15. (There are no new MAP_* constants covered by this test in
|
||||
5.15 that need any other header changes.)
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
(cherry picked from commit 5c3ece451d46a7d8721311609bfcb6faafacb39e)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
index 810433c238f31c25..eeccdfd04dae57ab 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
@@ -33,7 +33,7 @@ def main():
|
||||
help='C compiler (including options) to use')
|
||||
args = parser.parse_args()
|
||||
linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
|
||||
- linux_version_glibc = (5, 14)
|
||||
+ linux_version_glibc = (5, 15)
|
||||
sys.exit(glibcextract.compare_macro_consts(
|
||||
'#define _GNU_SOURCE 1\n'
|
||||
'#include <sys/mman.h>\n',
|
28
SOURCES/glibc-upstream-2.34-193.patch
Normal file
28
SOURCES/glibc-upstream-2.34-193.patch
Normal file
@ -0,0 +1,28 @@
|
||||
commit 5146b73d72ced9bab125e986aa99ef5fe2f88475
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Dec 20 15:38:32 2021 +0000
|
||||
|
||||
Add ARPHRD_CAN, ARPHRD_MCTP to net/if_arp.h
|
||||
|
||||
Add the constant ARPHRD_MCTP, from Linux 5.15, to net/if_arp.h, along
|
||||
with ARPHRD_CAN which was added to Linux in version 2.6.25 (commit
|
||||
cd05acfe65ed2cf2db683fa9a6adb8d35635263b, "[CAN]: Allocate protocol
|
||||
numbers for PF_CAN") but apparently missed for glibc at the time.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
(cherry picked from commit a94d9659cd69dbc70d3494b1cbbbb5a1551675c5)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/net/if_arp.h b/sysdeps/unix/sysv/linux/net/if_arp.h
|
||||
index 2a8933cde7cf236d..42910b776660def1 100644
|
||||
--- a/sysdeps/unix/sysv/linux/net/if_arp.h
|
||||
+++ b/sysdeps/unix/sysv/linux/net/if_arp.h
|
||||
@@ -95,6 +95,8 @@ struct arphdr
|
||||
#define ARPHRD_ROSE 270
|
||||
#define ARPHRD_X25 271 /* CCITT X.25. */
|
||||
#define ARPHRD_HWX25 272 /* Boards with X.25 in firmware. */
|
||||
+#define ARPHRD_CAN 280 /* Controller Area Network. */
|
||||
+#define ARPHRD_MCTP 290
|
||||
#define ARPHRD_PPP 512
|
||||
#define ARPHRD_CISCO 513 /* Cisco HDLC. */
|
||||
#define ARPHRD_HDLC ARPHRD_CISCO
|
337
SOURCES/glibc-upstream-2.34-194.patch
Normal file
337
SOURCES/glibc-upstream-2.34-194.patch
Normal file
@ -0,0 +1,337 @@
|
||||
commit 6af165658d0999ac2c4e9ce88bee020fbc2ee49f
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Wed Mar 23 17:11:56 2022 +0000
|
||||
|
||||
Update syscall lists for Linux 5.17
|
||||
|
||||
Linux 5.17 has one new syscall, set_mempolicy_home_node. Update
|
||||
syscall-names.list and regenerate the arch-syscall.h headers with
|
||||
build-many-glibcs.py update-syscalls.
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
(cherry picked from commit 8ef9196b26793830515402ea95aca2629f7721ec)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||
index 9905ebedf298954c..4fcb6da80af37e9e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||
@@ -236,6 +236,7 @@
|
||||
#define __NR_sendmsg 211
|
||||
#define __NR_sendto 206
|
||||
#define __NR_set_mempolicy 237
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 99
|
||||
#define __NR_set_tid_address 96
|
||||
#define __NR_setdomainname 162
|
||||
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||
index ee8085be69958b25..0cf74c1a96bb1235 100644
|
||||
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||
@@ -391,6 +391,7 @@
|
||||
#define __NR_sendmsg 114
|
||||
#define __NR_sendto 133
|
||||
#define __NR_set_mempolicy 431
|
||||
+#define __NR_set_mempolicy_home_node 560
|
||||
#define __NR_set_robust_list 466
|
||||
#define __NR_set_tid_address 411
|
||||
#define __NR_setdomainname 166
|
||||
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||
index 1b626d97705d545a..c1207aaa12be6a51 100644
|
||||
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||
@@ -238,6 +238,7 @@
|
||||
#define __NR_sendmsg 211
|
||||
#define __NR_sendto 206
|
||||
#define __NR_set_mempolicy 237
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 99
|
||||
#define __NR_set_tid_address 96
|
||||
#define __NR_setdomainname 162
|
||||
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||
index 96ef8db9368e7de4..e7ba04c106d8af7d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||
@@ -302,6 +302,7 @@
|
||||
#define __NR_sendmsg 296
|
||||
#define __NR_sendto 290
|
||||
#define __NR_set_mempolicy 321
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 338
|
||||
#define __NR_set_tid_address 256
|
||||
#define __NR_set_tls 983045
|
||||
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||
index 96910154ed6a5c1b..dc9383758ebc641b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||
@@ -250,6 +250,7 @@
|
||||
#define __NR_sendmsg 211
|
||||
#define __NR_sendto 206
|
||||
#define __NR_set_mempolicy 237
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 99
|
||||
#define __NR_set_thread_area 244
|
||||
#define __NR_set_tid_address 96
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||
index 36675fd48e6f50c5..767f1287a30b473e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||
@@ -289,6 +289,7 @@
|
||||
#define __NR_sendmsg 183
|
||||
#define __NR_sendto 82
|
||||
#define __NR_set_mempolicy 262
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 289
|
||||
#define __NR_set_tid_address 237
|
||||
#define __NR_setdomainname 121
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||
index c86ccbda4681066c..1998f0d76a444cac 100644
|
||||
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||
@@ -323,6 +323,7 @@
|
||||
#define __NR_sendmsg 370
|
||||
#define __NR_sendto 369
|
||||
#define __NR_set_mempolicy 276
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 311
|
||||
#define __NR_set_thread_area 243
|
||||
#define __NR_set_tid_address 258
|
||||
diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
|
||||
index d898bce404955ef0..b2eab1b93d70b9de 100644
|
||||
--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
|
||||
@@ -272,6 +272,7 @@
|
||||
#define __NR_sendmsg 1205
|
||||
#define __NR_sendto 1199
|
||||
#define __NR_set_mempolicy 1261
|
||||
+#define __NR_set_mempolicy_home_node 1474
|
||||
#define __NR_set_robust_list 1298
|
||||
#define __NR_set_tid_address 1233
|
||||
#define __NR_setdomainname 1129
|
||||
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||
index fe721b809076abeb..5fc3723772f92516 100644
|
||||
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||
@@ -310,6 +310,7 @@
|
||||
#define __NR_sendmsg 367
|
||||
#define __NR_sendto 366
|
||||
#define __NR_set_mempolicy 270
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 304
|
||||
#define __NR_set_thread_area 334
|
||||
#define __NR_set_tid_address 253
|
||||
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||
index 6e10c3661db96a1e..b6e9b007e496cd80 100644
|
||||
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||
@@ -326,6 +326,7 @@
|
||||
#define __NR_sendmsg 360
|
||||
#define __NR_sendto 353
|
||||
#define __NR_set_mempolicy 276
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 311
|
||||
#define __NR_set_thread_area 243
|
||||
#define __NR_set_tid_address 258
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||
index 26a6d594a2222f15..b3a3871f8ab8a23e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||
@@ -308,6 +308,7 @@
|
||||
#define __NR_sendmsg 4179
|
||||
#define __NR_sendto 4180
|
||||
#define __NR_set_mempolicy 4270
|
||||
+#define __NR_set_mempolicy_home_node 4450
|
||||
#define __NR_set_robust_list 4309
|
||||
#define __NR_set_thread_area 4283
|
||||
#define __NR_set_tid_address 4252
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||
index 83e0d49c5e3ca1bc..b462182723aff286 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||
@@ -288,6 +288,7 @@
|
||||
#define __NR_sendmsg 6045
|
||||
#define __NR_sendto 6043
|
||||
#define __NR_set_mempolicy 6233
|
||||
+#define __NR_set_mempolicy_home_node 6450
|
||||
#define __NR_set_robust_list 6272
|
||||
#define __NR_set_thread_area 6246
|
||||
#define __NR_set_tid_address 6213
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||
index d6747c542f63202b..a9d6b94572e93001 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||
@@ -270,6 +270,7 @@
|
||||
#define __NR_sendmsg 5045
|
||||
#define __NR_sendto 5043
|
||||
#define __NR_set_mempolicy 5229
|
||||
+#define __NR_set_mempolicy_home_node 5450
|
||||
#define __NR_set_robust_list 5268
|
||||
#define __NR_set_thread_area 5242
|
||||
#define __NR_set_tid_address 5212
|
||||
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||
index 4ee209bc4475ea7d..809a219ef32a45ef 100644
|
||||
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||
@@ -250,6 +250,7 @@
|
||||
#define __NR_sendmsg 211
|
||||
#define __NR_sendto 206
|
||||
#define __NR_set_mempolicy 237
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 99
|
||||
#define __NR_set_tid_address 96
|
||||
#define __NR_setdomainname 162
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||
index 497299fbc47a708c..627831ebae1b9e90 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||
@@ -319,6 +319,7 @@
|
||||
#define __NR_sendmsg 341
|
||||
#define __NR_sendto 335
|
||||
#define __NR_set_mempolicy 261
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 300
|
||||
#define __NR_set_tid_address 232
|
||||
#define __NR_setdomainname 121
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||
index e840279f171b10b9..bae597199d79eaad 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||
@@ -298,6 +298,7 @@
|
||||
#define __NR_sendmsg 341
|
||||
#define __NR_sendto 335
|
||||
#define __NR_set_mempolicy 261
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 300
|
||||
#define __NR_set_tid_address 232
|
||||
#define __NR_setdomainname 121
|
||||
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||
index 73ef74c005e5a2bb..bf4be80f8d380963 100644
|
||||
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||
@@ -228,6 +228,7 @@
|
||||
#define __NR_sendmsg 211
|
||||
#define __NR_sendto 206
|
||||
#define __NR_set_mempolicy 237
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 99
|
||||
#define __NR_set_tid_address 96
|
||||
#define __NR_setdomainname 162
|
||||
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||
index 919a79ee91177459..d656aedcc2be6009 100644
|
||||
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||
@@ -235,6 +235,7 @@
|
||||
#define __NR_sendmsg 211
|
||||
#define __NR_sendto 206
|
||||
#define __NR_set_mempolicy 237
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 99
|
||||
#define __NR_set_tid_address 96
|
||||
#define __NR_setdomainname 162
|
||||
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||
index 005c0ada7aab85a1..57025107e82c9439 100644
|
||||
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||
@@ -311,6 +311,7 @@
|
||||
#define __NR_sendmsg 370
|
||||
#define __NR_sendto 369
|
||||
#define __NR_set_mempolicy 270
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 304
|
||||
#define __NR_set_tid_address 252
|
||||
#define __NR_setdomainname 121
|
||||
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||
index 9131fddcc16116e4..72e19c6d569fbf9b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||
@@ -278,6 +278,7 @@
|
||||
#define __NR_sendmsg 370
|
||||
#define __NR_sendto 369
|
||||
#define __NR_set_mempolicy 270
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 304
|
||||
#define __NR_set_tid_address 252
|
||||
#define __NR_setdomainname 121
|
||||
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||
index d8fb041568ecb4da..d52b522d9cac87ef 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||
@@ -303,6 +303,7 @@
|
||||
#define __NR_sendmsg 355
|
||||
#define __NR_sendto 349
|
||||
#define __NR_set_mempolicy 276
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 311
|
||||
#define __NR_set_tid_address 258
|
||||
#define __NR_setdomainname 121
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||
index 2bc014fe6a1a1f4a..d3f4d8aa3edb4795 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||
@@ -310,6 +310,7 @@
|
||||
#define __NR_sendmsg 114
|
||||
#define __NR_sendto 133
|
||||
#define __NR_set_mempolicy 305
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 300
|
||||
#define __NR_set_tid_address 166
|
||||
#define __NR_setdomainname 163
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||
index 76dbbe595ffe868f..2cc03d7a24453335 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||
@@ -286,6 +286,7 @@
|
||||
#define __NR_sendmsg 114
|
||||
#define __NR_sendto 133
|
||||
#define __NR_set_mempolicy 305
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 300
|
||||
#define __NR_set_tid_address 166
|
||||
#define __NR_setdomainname 163
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index 0bc2af37dfa1eeb5..e2743c649586d97a 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -21,8 +21,8 @@
|
||||
# This file can list all potential system calls. The names are only
|
||||
# used if the installed kernel headers also provide them.
|
||||
|
||||
-# The list of system calls is current as of Linux 5.16.
|
||||
-kernel 5.16
|
||||
+# The list of system calls is current as of Linux 5.17.
|
||||
+kernel 5.17
|
||||
|
||||
FAST_atomic_update
|
||||
FAST_cmpxchg
|
||||
@@ -523,6 +523,7 @@ sendmmsg
|
||||
sendmsg
|
||||
sendto
|
||||
set_mempolicy
|
||||
+set_mempolicy_home_node
|
||||
set_robust_list
|
||||
set_thread_area
|
||||
set_tid_address
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||
index 28558279b48a1ef4..b4ab892ec183e32d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||
@@ -278,6 +278,7 @@
|
||||
#define __NR_sendmsg 46
|
||||
#define __NR_sendto 44
|
||||
#define __NR_set_mempolicy 238
|
||||
+#define __NR_set_mempolicy_home_node 450
|
||||
#define __NR_set_robust_list 273
|
||||
#define __NR_set_thread_area 205
|
||||
#define __NR_set_tid_address 218
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||
index c1ab8ec45e8b8fd3..772559c87b3625b8 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||
@@ -270,6 +270,7 @@
|
||||
#define __NR_sendmsg 1073742342
|
||||
#define __NR_sendto 1073741868
|
||||
#define __NR_set_mempolicy 1073742062
|
||||
+#define __NR_set_mempolicy_home_node 1073742274
|
||||
#define __NR_set_robust_list 1073742354
|
||||
#define __NR_set_thread_area 1073742029
|
||||
#define __NR_set_tid_address 1073742042
|
27
SOURCES/glibc-upstream-2.34-195.patch
Normal file
27
SOURCES/glibc-upstream-2.34-195.patch
Normal file
@ -0,0 +1,27 @@
|
||||
commit 81181ba5d916fc49bd737f603e28a3c2dc8430b4
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Wed Feb 16 14:19:24 2022 +0000
|
||||
|
||||
Update kernel version to 5.16 in tst-mman-consts.py
|
||||
|
||||
This patch updates the kernel version in the test tst-mman-consts.py
|
||||
to 5.16. (There are no new MAP_* constants covered by this test in
|
||||
5.16 that need any other header changes.)
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
(cherry picked from commit 790a607e234aa10d4b977a1b80aebe8a2acac970)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
index eeccdfd04dae57ab..8102d80b6660e523 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
@@ -33,7 +33,7 @@ def main():
|
||||
help='C compiler (including options) to use')
|
||||
args = parser.parse_args()
|
||||
linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
|
||||
- linux_version_glibc = (5, 15)
|
||||
+ linux_version_glibc = (5, 16)
|
||||
sys.exit(glibcextract.compare_macro_consts(
|
||||
'#define _GNU_SOURCE 1\n'
|
||||
'#include <sys/mman.h>\n',
|
27
SOURCES/glibc-upstream-2.34-196.patch
Normal file
27
SOURCES/glibc-upstream-2.34-196.patch
Normal file
@ -0,0 +1,27 @@
|
||||
commit 0499c3a95fb864284fef36d3e9c5a54f6646b2db
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Thu Mar 24 15:35:27 2022 +0000
|
||||
|
||||
Update kernel version to 5.17 in tst-mman-consts.py
|
||||
|
||||
This patch updates the kernel version in the test tst-mman-consts.py
|
||||
to 5.17. (There are no new MAP_* constants covered by this test in
|
||||
5.17 that need any other header changes.)
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
(cherry picked from commit 23808a422e6036accaba7236fd3b9a0d7ab7e8ee)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
index 8102d80b6660e523..724c7375c3a1623b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
@@ -33,7 +33,7 @@ def main():
|
||||
help='C compiler (including options) to use')
|
||||
args = parser.parse_args()
|
||||
linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
|
||||
- linux_version_glibc = (5, 16)
|
||||
+ linux_version_glibc = (5, 17)
|
||||
sys.exit(glibcextract.compare_macro_consts(
|
||||
'#define _GNU_SOURCE 1\n'
|
||||
'#include <sys/mman.h>\n',
|
26
SOURCES/glibc-upstream-2.34-197.patch
Normal file
26
SOURCES/glibc-upstream-2.34-197.patch
Normal file
@ -0,0 +1,26 @@
|
||||
commit f858bc309315a03ff6b1a048f59405c159d23430
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Feb 21 22:49:36 2022 +0000
|
||||
|
||||
Add SOL_MPTCP, SOL_MCTP from Linux 5.16 to bits/socket.h
|
||||
|
||||
Linux 5.16 adds constants SOL_MPTCP and SOL_MCTP to the getsockopt /
|
||||
setsockopt levels; add these constants to bits/socket.h.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
(cherry picked from commit fdc1ae67fef27eea1445bab4bdfe2f0fb3bc7aa1)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
|
||||
index 7bb9e863d7329da9..c81fab840918924e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/bits/socket.h
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/socket.h
|
||||
@@ -169,6 +169,8 @@ typedef __socklen_t socklen_t;
|
||||
#define SOL_KCM 281
|
||||
#define SOL_TLS 282
|
||||
#define SOL_XDP 283
|
||||
+#define SOL_MPTCP 284
|
||||
+#define SOL_MCTP 285
|
||||
|
||||
/* Maximum queue length specifiable by listen. */
|
||||
#define SOMAXCONN 4096
|
21
SOURCES/glibc-upstream-2.34-198.patch
Normal file
21
SOURCES/glibc-upstream-2.34-198.patch
Normal file
@ -0,0 +1,21 @@
|
||||
commit c108e87026d61d6744e3e55704e0bea937243f5a
|
||||
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
Date: Tue Dec 14 11:15:07 2021 +0000
|
||||
|
||||
aarch64: Add HWCAP2_ECV from Linux 5.16
|
||||
|
||||
Indicates the availability of enhanced counter virtualization extension
|
||||
of armv8.6-a with self-synchronized virtual counter CNTVCTSS_EL0 usable
|
||||
in userspace.
|
||||
|
||||
(cherry picked from commit 5a1be8ebdf6f02d4efec6e5f12ad06db17511f90)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h
|
||||
index 30fda0a4a347695e..04cc762015a7230a 100644
|
||||
--- a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h
|
||||
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h
|
||||
@@ -74,3 +74,4 @@
|
||||
#define HWCAP2_RNG (1 << 16)
|
||||
#define HWCAP2_BTI (1 << 17)
|
||||
#define HWCAP2_MTE (1 << 18)
|
||||
+#define HWCAP2_ECV (1 << 19)
|
21
SOURCES/glibc-upstream-2.34-199.patch
Normal file
21
SOURCES/glibc-upstream-2.34-199.patch
Normal file
@ -0,0 +1,21 @@
|
||||
commit 97cb8227b864b8ea0d99a4a50e4163baad3e1c72
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Mar 28 13:16:48 2022 +0000
|
||||
|
||||
Add HWCAP2_AFP, HWCAP2_RPRES from Linux 5.17 to AArch64 bits/hwcap.h
|
||||
|
||||
Add the new HWCAP2_AFP and HWCAP2_RPRES constants from Linux 5.17.
|
||||
Tested with build-many-glibcs.py for aarch64-linux-gnu.
|
||||
|
||||
(cherry picked from commit 866c599182e87f116440b5d854f9e99533c48eb3)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h
|
||||
index 04cc762015a7230a..9a5c4116b3fe9903 100644
|
||||
--- a/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h
|
||||
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h
|
||||
@@ -75,3 +75,5 @@
|
||||
#define HWCAP2_BTI (1 << 17)
|
||||
#define HWCAP2_MTE (1 << 18)
|
||||
#define HWCAP2_ECV (1 << 19)
|
||||
+#define HWCAP2_AFP (1 << 20)
|
||||
+#define HWCAP2_RPRES (1 << 21)
|
29
SOURCES/glibc-upstream-2.34-200.patch
Normal file
29
SOURCES/glibc-upstream-2.34-200.patch
Normal file
@ -0,0 +1,29 @@
|
||||
commit 31af92b9c8cf753992d45c801a855a02060afc08
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Wed May 4 15:56:47 2022 +0530
|
||||
|
||||
manual: Clarify that abbreviations of long options are allowed
|
||||
|
||||
The man page and code comments clearly state that abbreviations of long
|
||||
option names are recognized correctly as long as they are unique.
|
||||
Document this fact in the glibc manual as well.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
|
||||
(cherry picked from commit db1efe02c9f15affc3908d6ae73875b82898a489)
|
||||
|
||||
diff --git a/manual/getopt.texi b/manual/getopt.texi
|
||||
index 5485fc46946631f7..b4c0b15ac2060560 100644
|
||||
--- a/manual/getopt.texi
|
||||
+++ b/manual/getopt.texi
|
||||
@@ -250,7 +250,8 @@ option, and stores the option's argument (if it has one) in @code{optarg}.
|
||||
|
||||
When @code{getopt_long} encounters a long option, it takes actions based
|
||||
on the @code{flag} and @code{val} fields of the definition of that
|
||||
-option.
|
||||
+option. The option name may be abbreviated as long as the abbreviation is
|
||||
+unique.
|
||||
|
||||
If @code{flag} is a null pointer, then @code{getopt_long} returns the
|
||||
contents of @code{val} to indicate which option it found. You should
|
1789
SOURCES/glibc-upstream-2.34-201.patch
Normal file
1789
SOURCES/glibc-upstream-2.34-201.patch
Normal file
File diff suppressed because it is too large
Load Diff
1987
SOURCES/glibc-upstream-2.34-202.patch
Normal file
1987
SOURCES/glibc-upstream-2.34-202.patch
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user