Compare commits
No commits in common. 'i10c-beta' and 'c9' have entirely different histories.
@ -1 +1,3 @@
|
|||||||
SOURCES/glibc-2.39.tar.xz
|
SOURCES/glibc-2.34.tar.xz
|
||||||
|
SOURCES/glibc-c-utf8-locale-2.patch
|
||||||
|
SOURCES/glibc-upstream-2.34-373.patch
|
||||||
|
@ -1 +1,3 @@
|
|||||||
4b043eaba31efbdfc92c85d062e975141870295e SOURCES/glibc-2.39.tar.xz
|
7c3b8890a6346793b6334cc5f2fea5d437d307b8 SOURCES/glibc-2.34.tar.xz
|
||||||
|
47cf1a27ae2e86b37e44c49f6bf4630a1adabd9a SOURCES/glibc-c-utf8-locale-2.patch
|
||||||
|
6022f103e5596ad229f22bc966327d71208f7016 SOURCES/glibc-upstream-2.34-373.patch
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,79 +0,0 @@
|
|||||||
commit 95f61610f3e481d191b6184432342236fd59186d
|
|
||||||
Author: Florian Weimer <fweimer@redhat.com>
|
|
||||||
Date: Wed Jul 24 12:06:47 2024 +0200
|
|
||||||
|
|
||||||
resolv: Support clearing option flags with a “-” prefix (bug 14799)
|
|
||||||
|
|
||||||
I think using a “-” prefix is less confusing than introducing
|
|
||||||
double-negation construct (“no-no-tld-query”).
|
|
||||||
|
|
||||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/resolv/res_init.c b/resolv/res_init.c
|
|
||||||
index 263263d474721545..243532b3ade338d8 100644
|
|
||||||
--- a/resolv/res_init.c
|
|
||||||
+++ b/resolv/res_init.c
|
|
||||||
@@ -682,27 +682,29 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options)
|
|
||||||
{
|
|
||||||
char str[22];
|
|
||||||
uint8_t len;
|
|
||||||
- uint8_t clear;
|
|
||||||
unsigned long int flag;
|
|
||||||
} options[] = {
|
|
||||||
#define STRnLEN(str) str, sizeof (str) - 1
|
|
||||||
- { STRnLEN ("rotate"), 0, RES_ROTATE },
|
|
||||||
- { STRnLEN ("edns0"), 0, RES_USE_EDNS0 },
|
|
||||||
- { STRnLEN ("single-request-reopen"), 0, RES_SNGLKUPREOP },
|
|
||||||
- { STRnLEN ("single-request"), 0, RES_SNGLKUP },
|
|
||||||
- { STRnLEN ("no_tld_query"), 0, RES_NOTLDQUERY },
|
|
||||||
- { STRnLEN ("no-tld-query"), 0, RES_NOTLDQUERY },
|
|
||||||
- { STRnLEN ("no-reload"), 0, RES_NORELOAD },
|
|
||||||
- { STRnLEN ("use-vc"), 0, RES_USEVC },
|
|
||||||
- { STRnLEN ("trust-ad"), 0, RES_TRUSTAD },
|
|
||||||
- { STRnLEN ("no-aaaa"), 0, RES_NOAAAA },
|
|
||||||
+ { STRnLEN ("rotate"), RES_ROTATE },
|
|
||||||
+ { STRnLEN ("edns0"), RES_USE_EDNS0 },
|
|
||||||
+ { STRnLEN ("single-request-reopen"), RES_SNGLKUPREOP },
|
|
||||||
+ { STRnLEN ("single-request"), RES_SNGLKUP },
|
|
||||||
+ { STRnLEN ("no_tld_query"), RES_NOTLDQUERY },
|
|
||||||
+ { STRnLEN ("no-tld-query"), RES_NOTLDQUERY },
|
|
||||||
+ { STRnLEN ("no-reload"), RES_NORELOAD },
|
|
||||||
+ { STRnLEN ("use-vc"), RES_USEVC },
|
|
||||||
+ { STRnLEN ("trust-ad"), RES_TRUSTAD },
|
|
||||||
+ { STRnLEN ("no-aaaa"), RES_NOAAAA },
|
|
||||||
};
|
|
||||||
#define noptions (sizeof (options) / sizeof (options[0]))
|
|
||||||
+ bool negate_option = *cp == '-';
|
|
||||||
+ if (negate_option)
|
|
||||||
+ ++cp;
|
|
||||||
for (int i = 0; i < noptions; ++i)
|
|
||||||
if (strncmp (cp, options[i].str, options[i].len) == 0)
|
|
||||||
{
|
|
||||||
- if (options[i].clear)
|
|
||||||
- parser->template.options &= options[i].flag;
|
|
||||||
+ if (negate_option)
|
|
||||||
+ parser->template.options &= ~options[i].flag;
|
|
||||||
else
|
|
||||||
parser->template.options |= options[i].flag;
|
|
||||||
break;
|
|
||||||
diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c
|
|
||||||
index 6bef62cde2cbf8cd..d3a19eb305d41467 100644
|
|
||||||
--- a/resolv/tst-resolv-res_init-skeleton.c
|
|
||||||
+++ b/resolv/tst-resolv-res_init-skeleton.c
|
|
||||||
@@ -679,6 +679,16 @@ struct test_case test_cases[] =
|
|
||||||
"; nameserver[0]: [192.0.2.1]:53\n",
|
|
||||||
.res_options = "attempts:5 ndots:3 edns0 ",
|
|
||||||
},
|
|
||||||
+ {.name = "RES_OPTIONS can clear flags",
|
|
||||||
+ .conf = "options ndots:2 use-vc no-aaaa edns0\n"
|
|
||||||
+ "nameserver 192.0.2.1\n",
|
|
||||||
+ .expected = "options ndots:3 use-vc\n"
|
|
||||||
+ "search example.com\n"
|
|
||||||
+ "; search[0]: example.com\n"
|
|
||||||
+ "nameserver 192.0.2.1\n"
|
|
||||||
+ "; nameserver[0]: [192.0.2.1]:53\n",
|
|
||||||
+ .res_options = "ndots:3 -edns0 -no-aaaa",
|
|
||||||
+ },
|
|
||||||
{.name = "many search list entries (bug 19569)",
|
|
||||||
.conf = "nameserver 192.0.2.1\n"
|
|
||||||
"search corp.example.com support.example.com"
|
|
@ -1,204 +0,0 @@
|
|||||||
commit 765325951ac5c7d072278c9424930b29657e9758
|
|
||||||
Author: Florian Weimer <fweimer@redhat.com>
|
|
||||||
Date: Wed Jul 24 12:06:47 2024 +0200
|
|
||||||
|
|
||||||
resolv: Implement strict-error stub resolver option (bug 27929)
|
|
||||||
|
|
||||||
For now, do not enable this mode by default due to the potential
|
|
||||||
impact on compatibility with existing deployments.
|
|
||||||
|
|
||||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/resolv/res_init.c b/resolv/res_init.c
|
|
||||||
index 243532b3ade338d8..b838dc70642e1935 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 ("use-vc"), RES_USEVC },
|
|
||||||
{ STRnLEN ("trust-ad"), RES_TRUSTAD },
|
|
||||||
{ STRnLEN ("no-aaaa"), RES_NOAAAA },
|
|
||||||
+ { STRnLEN ("strict-error"), RES_STRICTERR },
|
|
||||||
};
|
|
||||||
#define noptions (sizeof (options) / sizeof (options[0]))
|
|
||||||
bool negate_option = *cp == '-';
|
|
||||||
diff --git a/resolv/res_send.c b/resolv/res_send.c
|
|
||||||
index 9c77613f374e5469..9a284ed44aa8cc2e 100644
|
|
||||||
--- a/resolv/res_send.c
|
|
||||||
+++ b/resolv/res_send.c
|
|
||||||
@@ -1234,21 +1234,38 @@ send_dg(res_state statp,
|
|
||||||
|
|
||||||
if (thisansp_error) {
|
|
||||||
next_ns:
|
|
||||||
- if (recvresp1 || (buf2 != NULL && recvresp2)) {
|
|
||||||
- *resplen2 = 0;
|
|
||||||
- return resplen;
|
|
||||||
- }
|
|
||||||
- if (buf2 != NULL && !single_request)
|
|
||||||
+ /* Outside of strict-error mode, use the first
|
|
||||||
+ response even if the second response is an
|
|
||||||
+ error. This allows parallel resolution to
|
|
||||||
+ succeed even if the recursive resolver
|
|
||||||
+ always answers with SERVFAIL for AAAA
|
|
||||||
+ queries (which still happens in practice
|
|
||||||
+ unfortunately).
|
|
||||||
+
|
|
||||||
+ In strict-error mode, always switch to the
|
|
||||||
+ next server and try to get a response from
|
|
||||||
+ there. */
|
|
||||||
+ if ((statp->options & RES_STRICTERR) == 0)
|
|
||||||
{
|
|
||||||
- /* No data from the first reply. */
|
|
||||||
- resplen = 0;
|
|
||||||
- /* We are waiting for a possible second reply. */
|
|
||||||
- if (matching_query == 1)
|
|
||||||
- recvresp1 = 1;
|
|
||||||
- else
|
|
||||||
- recvresp2 = 1;
|
|
||||||
-
|
|
||||||
- goto wait;
|
|
||||||
+ if (recvresp1 || (buf2 != NULL && recvresp2))
|
|
||||||
+ {
|
|
||||||
+ *resplen2 = 0;
|
|
||||||
+ return resplen;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (buf2 != NULL && !single_request)
|
|
||||||
+ {
|
|
||||||
+ /* No data from the first reply. */
|
|
||||||
+ resplen = 0;
|
|
||||||
+ /* We are waiting for a possible
|
|
||||||
+ second reply. */
|
|
||||||
+ if (matching_query == 1)
|
|
||||||
+ recvresp1 = 1;
|
|
||||||
+ else
|
|
||||||
+ recvresp2 = 1;
|
|
||||||
+
|
|
||||||
+ goto wait;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't retry if called from dig */
|
|
||||||
diff --git a/resolv/resolv.h b/resolv/resolv.h
|
|
||||||
index f40d6c58cee0f585..b8a0f66a5fd50e22 100644
|
|
||||||
--- a/resolv/resolv.h
|
|
||||||
+++ b/resolv/resolv.h
|
|
||||||
@@ -133,6 +133,7 @@ struct res_sym {
|
|
||||||
#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_STRICTERR 0x10000000 /* Report more DNS errors as errors. */
|
|
||||||
|
|
||||||
#define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH)
|
|
||||||
|
|
||||||
diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c
|
|
||||||
index d3a19eb305d41467..e41bcebd9d9a8024 100644
|
|
||||||
--- a/resolv/tst-resolv-res_init-skeleton.c
|
|
||||||
+++ b/resolv/tst-resolv-res_init-skeleton.c
|
|
||||||
@@ -129,6 +129,7 @@ print_resp (FILE *fp, res_state resp)
|
|
||||||
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");
|
|
||||||
+ print_option_flag (fp, &options, RES_STRICTERR, "strict-error");
|
|
||||||
fputc ('\n', fp);
|
|
||||||
if (options != 0)
|
|
||||||
fprintf (fp, "; error: unresolved option bits: 0x%x\n", options);
|
|
||||||
@@ -741,6 +742,15 @@ struct test_case test_cases[] =
|
|
||||||
"nameserver 192.0.2.1\n"
|
|
||||||
"; nameserver[0]: [192.0.2.1]:53\n"
|
|
||||||
},
|
|
||||||
+ {.name = "strict-error flag",
|
|
||||||
+ .conf = "options strict-error\n"
|
|
||||||
+ "nameserver 192.0.2.1\n",
|
|
||||||
+ .expected = "options strict-error\n"
|
|
||||||
+ "search example.com\n"
|
|
||||||
+ "; search[0]: example.com\n"
|
|
||||||
+ "nameserver 192.0.2.1\n"
|
|
||||||
+ "; nameserver[0]: [192.0.2.1]:53\n"
|
|
||||||
+ },
|
|
||||||
{ NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/resolv/tst-resolv-semi-failure.c b/resolv/tst-resolv-semi-failure.c
|
|
||||||
index aa9798b5a7dfaa88..b7681210f450bb5a 100644
|
|
||||||
--- a/resolv/tst-resolv-semi-failure.c
|
|
||||||
+++ b/resolv/tst-resolv-semi-failure.c
|
|
||||||
@@ -67,6 +67,9 @@ response (const struct resolv_response_context *ctx,
|
|
||||||
resolv_response_close_record (b);
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* Set to 1 if strict error checking is enabled. */
|
|
||||||
+static int do_strict_error;
|
|
||||||
+
|
|
||||||
static void
|
|
||||||
check_one (void)
|
|
||||||
{
|
|
||||||
@@ -83,7 +86,10 @@ check_one (void)
|
|
||||||
struct addrinfo *ai;
|
|
||||||
int ret = getaddrinfo ("www.example", "80", &hints, &ai);
|
|
||||||
const char *expected;
|
|
||||||
- if (ret == 0 && ai->ai_next != NULL)
|
|
||||||
+ /* In strict-error mode, a switch to the second name server
|
|
||||||
+ happens, and both responses are received, so a single
|
|
||||||
+ response is a bug. */
|
|
||||||
+ if (do_strict_error || (ret == 0 && ai->ai_next != NULL))
|
|
||||||
expected = ("address: STREAM/TCP 192.0.2.17 80\n"
|
|
||||||
"address: STREAM/TCP 2001:db8::1 80\n");
|
|
||||||
else
|
|
||||||
@@ -99,33 +105,36 @@ check_one (void)
|
|
||||||
static int
|
|
||||||
do_test (void)
|
|
||||||
{
|
|
||||||
- for (int do_single_lookup = 0; do_single_lookup < 2; ++do_single_lookup)
|
|
||||||
- {
|
|
||||||
- struct resolv_test *aux = resolv_test_start
|
|
||||||
- ((struct resolv_redirect_config)
|
|
||||||
- {
|
|
||||||
- .response_callback = response,
|
|
||||||
- });
|
|
||||||
+ for (do_strict_error = 0; do_strict_error < 2; ++do_strict_error)
|
|
||||||
+ for (int do_single_lookup = 0; do_single_lookup < 2; ++do_single_lookup)
|
|
||||||
+ {
|
|
||||||
+ struct resolv_test *aux = resolv_test_start
|
|
||||||
+ ((struct resolv_redirect_config)
|
|
||||||
+ {
|
|
||||||
+ .response_callback = response,
|
|
||||||
+ });
|
|
||||||
|
|
||||||
- if (do_single_lookup)
|
|
||||||
- _res.options |= RES_SNGLKUP;
|
|
||||||
+ if (do_strict_error)
|
|
||||||
+ _res.options |= RES_STRICTERR;
|
|
||||||
+ if (do_single_lookup)
|
|
||||||
+ _res.options |= RES_SNGLKUP;
|
|
||||||
|
|
||||||
- for (int do_fail_aaaa = 0; do_fail_aaaa < 2; ++do_fail_aaaa)
|
|
||||||
- {
|
|
||||||
- fail_aaaa = do_fail_aaaa;
|
|
||||||
+ for (int do_fail_aaaa = 0; do_fail_aaaa < 2; ++do_fail_aaaa)
|
|
||||||
+ {
|
|
||||||
+ fail_aaaa = do_fail_aaaa;
|
|
||||||
|
|
||||||
- rcode = 2; /* SERVFAIL. */
|
|
||||||
- check_one ();
|
|
||||||
+ rcode = 2; /* SERVFAIL. */
|
|
||||||
+ check_one ();
|
|
||||||
|
|
||||||
- rcode = 4; /* NOTIMP. */
|
|
||||||
- check_one ();
|
|
||||||
+ rcode = 4; /* NOTIMP. */
|
|
||||||
+ check_one ();
|
|
||||||
|
|
||||||
- rcode = 5; /* REFUSED. */
|
|
||||||
- check_one ();
|
|
||||||
- }
|
|
||||||
+ rcode = 5; /* REFUSED. */
|
|
||||||
+ check_one ();
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- resolv_test_end (aux);
|
|
||||||
- }
|
|
||||||
+ resolv_test_end (aux);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -0,0 +1,432 @@
|
|||||||
|
From e4ca6de1bc5e4ba3f94cf0c501a293c5bc827b10 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anton Blanchard <anton@ozlabs.org>
|
||||||
|
Date: Tue, 27 Jul 2021 15:47:49 +1000
|
||||||
|
Subject: powerpc64: Replace some PPC_FEATURE_HAS_VSX with
|
||||||
|
PPC_FEATURE_ARCH_2_06
|
||||||
|
|
||||||
|
We use PPC_FEATURE_HAS_VSX to select a number of POWER7 optimised
|
||||||
|
functions. These functions don't use any VSX instructions, so
|
||||||
|
PPC_FEATURE_ARCH_2_06 seems like a better fit.
|
||||||
|
|
||||||
|
Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
index 0acdf22ba3..32564c8f1f 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
@@ -95,7 +95,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__memset_power8)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__memset_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05,
|
||||||
|
__memset_power6)
|
||||||
|
@@ -139,7 +139,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strlen_power8)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strlen_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strlen, 1,
|
||||||
|
__strlen_ppc))
|
||||||
|
@@ -152,7 +152,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strncmp_power8)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strncmp_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_POWER4,
|
||||||
|
__strncmp_power4)
|
||||||
|
@@ -165,7 +165,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strchr_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strchr,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strchr_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strchr, 1,
|
||||||
|
__strchr_ppc))
|
||||||
|
@@ -176,7 +176,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strchrnul_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strchrnul,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strchrnul_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strchrnul, 1,
|
||||||
|
__strchrnul_ppc))
|
||||||
|
@@ -192,7 +192,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, memcmp, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__memcmp_power8)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__memcmp_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_POWER4,
|
||||||
|
__memcmp_power4)
|
||||||
|
@@ -244,7 +244,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__memchr_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memchr,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__memchr_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memchr, 1,
|
||||||
|
__memchr_ppc))
|
||||||
|
@@ -255,7 +255,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__memrchr_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memrchr,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__memrchr_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memrchr, 1,
|
||||||
|
__memrchr_ppc))
|
||||||
|
@@ -272,7 +272,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
__rawmemchr_power9)
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, rawmemchr,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__rawmemchr_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, rawmemchr, 1,
|
||||||
|
__rawmemchr_ppc))
|
||||||
|
@@ -282,7 +282,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strnlen,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strnlen_power8)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strnlen, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strnlen, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strnlen_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strnlen, 1,
|
||||||
|
__strnlen_ppc))
|
||||||
|
@@ -293,14 +293,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strcasecmp_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcasecmp,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strcasecmp_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ppc))
|
||||||
|
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c. */
|
||||||
|
IFUNC_IMPL (i, name, strcasecmp_l,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcasecmp_l,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strcasecmp_l_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
|
||||||
|
__strcasecmp_l_ppc))
|
||||||
|
@@ -311,14 +311,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strncasecmp_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncasecmp,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strncasecmp_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncasecmp, 1, __strncasecmp_ppc))
|
||||||
|
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strncase_l.c. */
|
||||||
|
IFUNC_IMPL (i, name, strncasecmp_l,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncasecmp_l,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strncasecmp_l_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
|
||||||
|
__strncasecmp_l_ppc))
|
||||||
|
@@ -329,7 +329,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strrchr_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strrchr,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strrchr_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strrchr, 1,
|
||||||
|
__strrchr_ppc))
|
||||||
|
@@ -357,7 +357,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strncpy_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncpy,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strncpy_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncpy, 1,
|
||||||
|
__strncpy_ppc))
|
||||||
|
@@ -374,7 +374,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__stpncpy_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, stpncpy,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__stpncpy_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, stpncpy, 1,
|
||||||
|
__stpncpy_ppc))
|
||||||
|
@@ -390,7 +390,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strcmp_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcmp,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strcmp_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcmp, 1,
|
||||||
|
__strcmp_ppc))
|
||||||
|
@@ -425,7 +425,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strstr.c. */
|
||||||
|
IFUNC_IMPL (i, name, strstr,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strstr,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strstr_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strstr, 1,
|
||||||
|
__strstr_ppc))
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr.c b/sysdeps/powerpc/powerpc64/multiarch/memchr.c
|
||||||
|
index 0c718d4f15..c24186689e 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memchr.c
|
||||||
|
@@ -30,7 +30,7 @@ extern __typeof (__memchr) __memchr_power8 attribute_hidden;
|
||||||
|
libc_ifunc (__memchr,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __memchr_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __memchr_power7
|
||||||
|
: __memchr_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
|
||||||
|
index 4fd089aba7..99559bce26 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
|
||||||
|
@@ -40,7 +40,7 @@ libc_ifunc_redirected (__redirect_memcmp, memcmp,
|
||||||
|
#endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __memcmp_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __memcmp_power7
|
||||||
|
: (hwcap & PPC_FEATURE_POWER4)
|
||||||
|
? __memcmp_power4
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memrchr.c b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c
|
||||||
|
index e06d6468b8..16bb6f0042 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memrchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c
|
||||||
|
@@ -30,7 +30,7 @@ extern __typeof (__memrchr) __memrchr_power8 attribute_hidden;
|
||||||
|
libc_ifunc (__memrchr,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __memrchr_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __memrchr_power7
|
||||||
|
: __memrchr_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c
|
||||||
|
index 5994bf02e6..c1aa143f60 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memset.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c
|
||||||
|
@@ -48,7 +48,7 @@ libc_ifunc (__libc_memset,
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __memset_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __memset_power7 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_05)
|
||||||
|
? __memset_power6 :
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
|
||||||
|
index c0ffea2b93..b5d2d3a635 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
|
||||||
|
@@ -41,7 +41,7 @@ libc_ifunc_redirected (__redirect___rawmemchr, __rawmemchr,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_3_00)
|
||||||
|
? __rawmemchr_power9 :
|
||||||
|
# endif
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __rawmemchr_power7
|
||||||
|
: __rawmemchr_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
|
||||||
|
index bebd377fd9..e7035761a7 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
|
||||||
|
@@ -40,7 +40,7 @@ libc_ifunc_redirected (__redirect___stpncpy, __stpncpy,
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __stpncpy_power8
|
||||||
|
- : (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ : (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __stpncpy_power7
|
||||||
|
: __stpncpy_ppc);
|
||||||
|
weak_alias (__stpncpy, stpncpy)
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c
|
||||||
|
index dcd7774403..55ca6c85c4 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c
|
||||||
|
@@ -29,7 +29,7 @@ extern __typeof (__strcasecmp) __strcasecmp_power8 attribute_hidden;
|
||||||
|
libc_ifunc (__libc_strcasecmp,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strcasecmp_power8:
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strcasecmp_power7
|
||||||
|
: __strcasecmp_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c
|
||||||
|
index 96a70b8b11..1afee5d7fd 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c
|
||||||
|
@@ -32,7 +32,7 @@ extern __typeof (__strcasecmp_l) __strcasecmp_l_power7 attribute_hidden;
|
||||||
|
|
||||||
|
extern __typeof (__strcasecmp_l) __libc_strcasecmp_l;
|
||||||
|
libc_ifunc (__libc_strcasecmp_l,
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strcasecmp_l_power7
|
||||||
|
: __strcasecmp_l_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
|
||||||
|
index ea9ac1134f..27c794c6b7 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
|
||||||
|
@@ -35,7 +35,7 @@ extern __typeof (strchr) __strchr_power8 attribute_hidden;
|
||||||
|
libc_ifunc_redirected (__redirect_strchr, strchr,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strchr_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strchr_power7
|
||||||
|
: __strchr_ppc);
|
||||||
|
weak_alias (strchr, index)
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c
|
||||||
|
index 4688e7c3f0..4a07b4a242 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c
|
||||||
|
@@ -30,7 +30,7 @@ extern __typeof (__strchrnul) __strchrnul_power8 attribute_hidden;
|
||||||
|
libc_ifunc (__strchrnul,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strchrnul_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strchrnul_power7
|
||||||
|
: __strchrnul_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
|
||||||
|
index 72f9a639bf..4b0b25fff6 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
|
||||||
|
@@ -40,7 +40,7 @@ libc_ifunc_redirected (__redirect_strcmp, strcmp,
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strcmp_power8
|
||||||
|
- : (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ : (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strcmp_power7
|
||||||
|
: __strcmp_ppc);
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen.c b/sysdeps/powerpc/powerpc64/multiarch/strlen.c
|
||||||
|
index 109c8a90bd..0cd1c6faff 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strlen.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strlen.c
|
||||||
|
@@ -42,7 +42,7 @@ libc_ifunc (__libc_strlen,
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strlen_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strlen_power7
|
||||||
|
: __strlen_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase.c b/sysdeps/powerpc/powerpc64/multiarch/strncase.c
|
||||||
|
index 2013a5d75a..644046bd74 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncase.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncase.c
|
||||||
|
@@ -29,7 +29,7 @@ extern __typeof (__strncasecmp) __strncasecmp_power8 attribute_hidden;
|
||||||
|
libc_ifunc (__libc_strncasecmp,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strncasecmp_power8:
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strncasecmp_power7
|
||||||
|
: __strncasecmp_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c b/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c
|
||||||
|
index cad6da302d..d2d761af72 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c
|
||||||
|
@@ -34,7 +34,7 @@ extern __typeof (__strncasecmp_l) __strncasecmp_l_power7 attribute_hidden;
|
||||||
|
ifunc symbol properly. */
|
||||||
|
extern __typeof (__strncasecmp_l) __libc_strncasecmp_l;
|
||||||
|
libc_ifunc (__libc_strncasecmp_l,
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strncasecmp_l_power7
|
||||||
|
: __strncasecmp_l_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
index eef524ddfb..1f689e5c05 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
@@ -43,7 +43,7 @@ libc_ifunc_redirected (__redirect_strncmp, strncmp,
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strncmp_power8
|
||||||
|
- : (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ : (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strncmp_power7
|
||||||
|
: (hwcap & PPC_FEATURE_POWER4)
|
||||||
|
? __strncmp_power4
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
|
||||||
|
index 7da9def358..d4d3463bd1 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
|
||||||
|
@@ -43,7 +43,7 @@ libc_ifunc_redirected (__redirect_strncpy, strncpy,
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strncpy_power8
|
||||||
|
- : (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ : (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strncpy_power7
|
||||||
|
: __strncpy_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
|
||||||
|
index 264b7a752d..baf375a75a 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
|
||||||
|
@@ -31,7 +31,7 @@ extern __typeof (__strnlen) __strnlen_power8 attribute_hidden;
|
||||||
|
libc_ifunc_redirected (__redirect___strnlen, __strnlen,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strnlen_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strnlen_power7
|
||||||
|
: __strnlen_ppc);
|
||||||
|
weak_alias (__strnlen, strnlen)
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
|
||||||
|
index bb06b93d19..1c9eea1817 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
|
||||||
|
@@ -33,7 +33,7 @@ extern __typeof (strrchr) __strrchr_power8 attribute_hidden;
|
||||||
|
libc_ifunc_redirected (__redirect_strrchr, strrchr,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strrchr_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strrchr_power7
|
||||||
|
: __strrchr_ppc);
|
||||||
|
weak_alias (strrchr, rindex)
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr.c b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
|
||||||
|
index bb0588844e..6582798dda 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strstr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
|
||||||
|
@@ -30,7 +30,7 @@ extern __typeof (strstr) __strstr_power7 attribute_hidden;
|
||||||
|
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||||
|
ifunc symbol properly. */
|
||||||
|
libc_ifunc_redirected (__redirect_strstr, strstr,
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strstr_power7
|
||||||
|
: __strstr_ppc);
|
||||||
|
#endif
|
@ -0,0 +1,83 @@
|
|||||||
|
From f2a15dd668913c5a1388ba7e1131b25162b2ea75 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anton Blanchard <anton@ozlabs.org>
|
||||||
|
Date: Tue, 27 Jul 2021 15:47:50 +1000
|
||||||
|
Subject: powerpc64: Check cacheline size before using optimised memset
|
||||||
|
routines
|
||||||
|
|
||||||
|
A number of optimised memset routines assume the cacheline size is 128B,
|
||||||
|
so we better check before using them.
|
||||||
|
|
||||||
|
Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
index 32564c8f1f..a3fdcd43bd 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
@@ -35,6 +35,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
|
||||||
|
unsigned long int hwcap = GLRO(dl_hwcap);
|
||||||
|
unsigned long int hwcap2 = GLRO(dl_hwcap2);
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ int cacheline_size = GLRO(dl_cache_line_size);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/* hwcap contains only the latest supported ISA, the code checks which is
|
||||||
|
and fills the previous supported ones. */
|
||||||
|
@@ -90,16 +93,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
IFUNC_IMPL_ADD (array, i, memset,
|
||||||
|
hwcap2 & PPC_FEATURE2_ARCH_3_1
|
||||||
|
&& hwcap2 & PPC_FEATURE2_HAS_ISEL
|
||||||
|
- && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX
|
||||||
|
+ && cacheline_size == 128,
|
||||||
|
__memset_power10)
|
||||||
|
#endif
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && cacheline_size == 128,
|
||||||
|
__memset_power8)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && cacheline_size == 128,
|
||||||
|
__memset_power7)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05
|
||||||
|
+ && cacheline_size == 128,
|
||||||
|
__memset_power6)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_POWER4,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_POWER4
|
||||||
|
+ && cacheline_size == 128,
|
||||||
|
__memset_power4)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ppc))
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c
|
||||||
|
index c1aa143f60..056e911699 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memset.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c
|
||||||
|
@@ -43,16 +43,21 @@ libc_ifunc (__libc_memset,
|
||||||
|
# ifdef __LITTLE_ENDIAN__
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_3_1
|
||||||
|
&& hwcap2 & PPC_FEATURE2_HAS_ISEL
|
||||||
|
- && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX
|
||||||
|
+ && GLRO(dl_cache_line_size) == 128)
|
||||||
|
? __memset_power10 :
|
||||||
|
# endif
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && GLRO(dl_cache_line_size) == 128)
|
||||||
|
? __memset_power8 :
|
||||||
|
- (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && GLRO(dl_cache_line_size) == 128)
|
||||||
|
? __memset_power7 :
|
||||||
|
- (hwcap & PPC_FEATURE_ARCH_2_05)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_05
|
||||||
|
+ && GLRO(dl_cache_line_size) == 128)
|
||||||
|
? __memset_power6 :
|
||||||
|
- (hwcap & PPC_FEATURE_POWER4)
|
||||||
|
+ (hwcap & PPC_FEATURE_POWER4
|
||||||
|
+ && GLRO(dl_cache_line_size) == 128)
|
||||||
|
? __memset_power4
|
||||||
|
: __memset_ppc);
|
||||||
|
|
@ -0,0 +1,703 @@
|
|||||||
|
From 60b4dd25790342b40e8942e3a4115f511a6b6911 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anton Blanchard <anton@ozlabs.org>
|
||||||
|
Date: Tue, 27 Jul 2021 15:47:51 +1000
|
||||||
|
Subject: powerpc64: Add checks for Altivec and VSX in ifunc selection
|
||||||
|
|
||||||
|
We'd like to support processors without Altivec or VSX, so check
|
||||||
|
the relevant hwcap bits before selecting them.
|
||||||
|
|
||||||
|
Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/bzero.c b/sysdeps/powerpc/powerpc64/multiarch/bzero.c
|
||||||
|
index 660d7dc686..c8ffbea01c 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/bzero.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/bzero.c
|
||||||
|
@@ -38,11 +38,13 @@ libc_ifunc (__bzero,
|
||||||
|
&& hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __bzero_power10 :
|
||||||
|
# endif
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __bzero_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __bzero_power7 :
|
||||||
|
- (hwcap & PPC_FEATURE_ARCH_2_05)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_05
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __bzero_power6 :
|
||||||
|
(hwcap & PPC_FEATURE_POWER4)
|
||||||
|
? __bzero_power4
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
index a3fdcd43bd..c3e25c5981 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
@@ -60,9 +60,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
&& hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__memcpy_power10)
|
||||||
|
#endif
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__memcpy_power8_cached)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__memcpy_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__memcpy_a2)
|
||||||
|
@@ -83,7 +85,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
&& hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__memmove_power10)
|
||||||
|
#endif
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memmove, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memmove, hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__memmove_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ppc))
|
||||||
|
|
||||||
|
@@ -98,6 +101,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
__memset_power10)
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC
|
||||||
|
&& cacheline_size == 128,
|
||||||
|
__memset_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
@@ -114,12 +118,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strcpy.c. */
|
||||||
|
IFUNC_IMPL (i, name, strcpy,
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strcpy, hwcap2 & PPC_FEATURE2_ARCH_3_00,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strcpy, hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strcpy_power9)
|
||||||
|
#endif
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strcpy_power8)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strcpy, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strcpy, hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strcpy_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcpy, 1,
|
||||||
|
__strcpy_ppc))
|
||||||
|
@@ -127,12 +134,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/stpcpy.c. */
|
||||||
|
IFUNC_IMPL (i, name, stpcpy,
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
|
- IFUNC_IMPL_ADD (array, i, stpcpy, hwcap2 & PPC_FEATURE2_ARCH_3_00,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, stpcpy, hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__stpcpy_power9)
|
||||||
|
#endif
|
||||||
|
- IFUNC_IMPL_ADD (array, i, stpcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, stpcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__stpcpy_power8)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, stpcpy, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, stpcpy, hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__stpcpy_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, stpcpy, 1,
|
||||||
|
__stpcpy_ppc))
|
||||||
|
@@ -140,12 +150,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strlen.c. */
|
||||||
|
IFUNC_IMPL (i, name, strlen,
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_3_1,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_3_1
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strlen_power10)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_3_00,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strlen_power9)
|
||||||
|
#endif
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strlen_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strlen_power7)
|
||||||
|
@@ -155,7 +168,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strncmp.c. */
|
||||||
|
IFUNC_IMPL (i, name, strncmp,
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_3_00,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strncmp_power9)
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
@@ -170,7 +184,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strchr.c. */
|
||||||
|
IFUNC_IMPL (i, name, strchr,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strchr,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strchr_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strchr,
|
||||||
|
hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
@@ -181,7 +196,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strchrnul.c. */
|
||||||
|
IFUNC_IMPL (i, name, strchrnul,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strchrnul,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strchrnul_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strchrnul,
|
||||||
|
hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
@@ -198,7 +214,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
&& hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__memcmp_power10)
|
||||||
|
#endif
|
||||||
|
- IFUNC_IMPL_ADD (array, i, memcmp, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, memcmp, hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__memcmp_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__memcmp_power7)
|
||||||
|
@@ -215,11 +232,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
&& hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__bzero_power10)
|
||||||
|
#endif
|
||||||
|
- IFUNC_IMPL_ADD (array, i, bzero, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, bzero, hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__bzero_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__bzero_power7)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_ARCH_2_05,
|
||||||
|
+ IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_ARCH_2_05
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__bzero_power6)
|
||||||
|
IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_POWER4,
|
||||||
|
__bzero_power4)
|
||||||
|
@@ -241,7 +260,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/mempcpy.c. */
|
||||||
|
IFUNC_IMPL (i, name, mempcpy,
|
||||||
|
IFUNC_IMPL_ADD (array, i, mempcpy,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__mempcpy_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, mempcpy, 1,
|
||||||
|
__mempcpy_ppc))
|
||||||
|
@@ -249,7 +269,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/memchr.c. */
|
||||||
|
IFUNC_IMPL (i, name, memchr,
|
||||||
|
IFUNC_IMPL_ADD (array, i, memchr,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__memchr_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memchr,
|
||||||
|
hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
@@ -260,7 +281,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/memrchr.c. */
|
||||||
|
IFUNC_IMPL (i, name, memrchr,
|
||||||
|
IFUNC_IMPL_ADD (array, i, memrchr,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__memrchr_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, memrchr,
|
||||||
|
hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
@@ -276,7 +298,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
&& (hwcap & PPC_FEATURE_HAS_VSX),
|
||||||
|
__rawmemchr_power10)
|
||||||
|
IFUNC_IMPL_ADD (array, i, rawmemchr,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_3_00,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__rawmemchr_power9)
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, rawmemchr,
|
||||||
|
@@ -288,7 +311,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strnlen.c. */
|
||||||
|
IFUNC_IMPL (i, name, strnlen,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strnlen,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strnlen_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strnlen, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strnlen_power7)
|
||||||
|
@@ -298,7 +322,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c. */
|
||||||
|
IFUNC_IMPL (i, name, strcasecmp,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcasecmp,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strcasecmp_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcasecmp,
|
||||||
|
hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
@@ -316,7 +341,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strncase.c. */
|
||||||
|
IFUNC_IMPL (i, name, strncasecmp,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncasecmp,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strncasecmp_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncasecmp,
|
||||||
|
hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
@@ -334,7 +360,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strrchr.c. */
|
||||||
|
IFUNC_IMPL (i, name, strrchr,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strrchr,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strrchr_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strrchr,
|
||||||
|
hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
@@ -345,10 +372,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strncat.c. */
|
||||||
|
IFUNC_IMPL (i, name, strncat,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncat,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strncat_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncat,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strncat_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncat, 1,
|
||||||
|
__strncat_ppc))
|
||||||
|
@@ -391,7 +420,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
IFUNC_IMPL (i, name, strcmp,
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcmp,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_3_00,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strcmp_power9)
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcmp,
|
||||||
|
@@ -406,10 +436,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strcat.c. */
|
||||||
|
IFUNC_IMPL (i, name, strcat,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcat,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strcat_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcat,
|
||||||
|
- hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
+ hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strcat_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcat, 1,
|
||||||
|
__strcat_ppc))
|
||||||
|
@@ -417,7 +449,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strspn.c. */
|
||||||
|
IFUNC_IMPL (i, name, strspn,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strspn,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strspn_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strspn, 1,
|
||||||
|
__strspn_ppc))
|
||||||
|
@@ -425,7 +458,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strcspn.c. */
|
||||||
|
IFUNC_IMPL (i, name, strcspn,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcspn,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||||
|
__strcspn_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcspn, 1,
|
||||||
|
__strcspn_ppc))
|
||||||
|
@@ -442,7 +476,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
/* Support sysdeps/powerpc/powerpc64/multiarch/strcasestr.c. */
|
||||||
|
IFUNC_IMPL (i, name, strcasestr,
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcasestr,
|
||||||
|
- hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
+ hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||||
|
__strcasestr_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strcasestr, 1,
|
||||||
|
__strcasestr_ppc))
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr.c b/sysdeps/powerpc/powerpc64/multiarch/memchr.c
|
||||||
|
index c24186689e..f40013e061 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memchr.c
|
||||||
|
@@ -28,7 +28,8 @@ extern __typeof (__memchr) __memchr_power8 attribute_hidden;
|
||||||
|
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||||
|
ifunc symbol properly. */
|
||||||
|
libc_ifunc (__memchr,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __memchr_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __memchr_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
|
||||||
|
index 99559bce26..89b56c103b 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
|
||||||
|
@@ -38,7 +38,8 @@ libc_ifunc_redirected (__redirect_memcmp, memcmp,
|
||||||
|
&& hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __memcmp_power10 :
|
||||||
|
#endif
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __memcmp_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __memcmp_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy.c b/sysdeps/powerpc/powerpc64/multiarch/memcpy.c
|
||||||
|
index 53ab32ef26..684ee064f2 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy.c
|
||||||
|
@@ -45,9 +45,12 @@ libc_ifunc (__libc_memcpy,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_3_1 && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __memcpy_power10 :
|
||||||
|
# endif
|
||||||
|
- ((hwcap2 & PPC_FEATURE2_ARCH_2_07) && use_cached_memopt)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC
|
||||||
|
+ && use_cached_memopt)
|
||||||
|
? __memcpy_power8_cached :
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __memcpy_power7 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __memcpy_a2 :
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memmove.c b/sysdeps/powerpc/powerpc64/multiarch/memmove.c
|
||||||
|
index 637b2cbf7f..50253b4554 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memmove.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memmove.c
|
||||||
|
@@ -41,7 +41,8 @@ libc_ifunc (__libc_memmove,
|
||||||
|
&& hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __memmove_power10 :
|
||||||
|
#endif
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __memmove_power7
|
||||||
|
: __memmove_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
|
||||||
|
index b37e0f35b5..563095a5ec 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
|
||||||
|
@@ -33,7 +33,8 @@ extern __typeof (__mempcpy) __mempcpy_power7 attribute_hidden;
|
||||||
|
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||||
|
ifunc symbol properly. */
|
||||||
|
libc_ifunc_redirected (__redirect___mempcpy, __mempcpy,
|
||||||
|
- (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ (hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __mempcpy_power7
|
||||||
|
: __mempcpy_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memrchr.c b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c
|
||||||
|
index 16bb6f0042..a8b985b06a 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memrchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c
|
||||||
|
@@ -28,7 +28,8 @@ extern __typeof (__memrchr) __memrchr_power8 attribute_hidden;
|
||||||
|
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||||
|
ifunc symbol properly. */
|
||||||
|
libc_ifunc (__memrchr,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __memrchr_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __memrchr_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c
|
||||||
|
index 056e911699..a2bc223bcc 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/memset.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c
|
||||||
|
@@ -48,6 +48,7 @@ libc_ifunc (__libc_memset,
|
||||||
|
? __memset_power10 :
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC
|
||||||
|
&& GLRO(dl_cache_line_size) == 128)
|
||||||
|
? __memset_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
|
||||||
|
index b5d2d3a635..43eb459e02 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
|
||||||
|
@@ -38,7 +38,8 @@ libc_ifunc_redirected (__redirect___rawmemchr, __rawmemchr,
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_3_1)
|
||||||
|
&& (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __rawmemchr_power10 :
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_3_00)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __rawmemchr_power9 :
|
||||||
|
# endif
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
|
||||||
|
index d4eb4285fc..5be413405e 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
|
||||||
|
@@ -32,12 +32,15 @@ extern __typeof (__stpcpy) __stpcpy_power9 attribute_hidden;
|
||||||
|
|
||||||
|
libc_ifunc_hidden (__stpcpy, __stpcpy,
|
||||||
|
# ifdef __LITTLE_ENDIAN__
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_3_00)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __stpcpy_power9 :
|
||||||
|
# endif
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __stpcpy_power8
|
||||||
|
- : (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ : (hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __stpcpy_power7
|
||||||
|
: __stpcpy_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c
|
||||||
|
index 55ca6c85c4..21ce2d279b 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c
|
||||||
|
@@ -27,7 +27,8 @@ extern __typeof (__strcasecmp) __strcasecmp_power7 attribute_hidden;
|
||||||
|
extern __typeof (__strcasecmp) __strcasecmp_power8 attribute_hidden;
|
||||||
|
|
||||||
|
libc_ifunc (__libc_strcasecmp,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strcasecmp_power8:
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strcasecmp_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c b/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c
|
||||||
|
index 7e4bd3b5ac..5bb3016022 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c
|
||||||
|
@@ -27,7 +27,8 @@ extern __typeof (__strcasestr) __strcasestr_power8 attribute_hidden;
|
||||||
|
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||||
|
ifunc symbol properly. */
|
||||||
|
libc_ifunc (__strcasestr,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strcasestr_power8
|
||||||
|
: __strcasestr_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
|
||||||
|
index 6d342324c4..d8d9870824 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strcat.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
|
||||||
|
@@ -28,9 +28,11 @@ extern __typeof (strcat) __strcat_power8 attribute_hidden;
|
||||||
|
# undef strcat
|
||||||
|
|
||||||
|
libc_ifunc_redirected (__redirect_strcat, strcat,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strcat_power8
|
||||||
|
- : (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ : (hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strcat_power7
|
||||||
|
: __strcat_ppc);
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
|
||||||
|
index 27c794c6b7..62b202baf9 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
|
||||||
|
@@ -33,7 +33,8 @@ extern __typeof (strchr) __strchr_power8 attribute_hidden;
|
||||||
|
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||||
|
ifunc symbol properly. */
|
||||||
|
libc_ifunc_redirected (__redirect_strchr, strchr,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strchr_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strchr_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c
|
||||||
|
index 4a07b4a242..40e529b9d9 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c
|
||||||
|
@@ -28,7 +28,8 @@ extern __typeof (__strchrnul) __strchrnul_power8 attribute_hidden;
|
||||||
|
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||||
|
ifunc symbol properly. */
|
||||||
|
libc_ifunc (__strchrnul,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strchrnul_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strchrnul_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
|
||||||
|
index 4b0b25fff6..8132682a99 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
|
||||||
|
@@ -35,7 +35,8 @@ extern __typeof (strcmp) __strcmp_power9 attribute_hidden;
|
||||||
|
|
||||||
|
libc_ifunc_redirected (__redirect_strcmp, strcmp,
|
||||||
|
# ifdef __LITTLE_ENDIAN__
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_3_00)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strcmp_power9 :
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
|
||||||
|
index b733fa5a23..5af1d45cc1 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
|
||||||
|
@@ -32,12 +32,15 @@ extern __typeof (strcpy) __strcpy_power9 attribute_hidden;
|
||||||
|
|
||||||
|
libc_ifunc_redirected (__redirect_strcpy, strcpy,
|
||||||
|
# ifdef __LITTLE_ENDIAN__
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_3_00)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strcpy_power9 :
|
||||||
|
# endif
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strcpy_power8
|
||||||
|
- : (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ : (hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strcpy_power7
|
||||||
|
: __strcpy_ppc);
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcspn.c b/sysdeps/powerpc/powerpc64/multiarch/strcspn.c
|
||||||
|
index 683aa104d7..8ba01c13b1 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strcspn.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcspn.c
|
||||||
|
@@ -27,7 +27,8 @@ extern __typeof (strcspn) __strcspn_ppc attribute_hidden;
|
||||||
|
extern __typeof (strcspn) __strcspn_power8 attribute_hidden;
|
||||||
|
|
||||||
|
libc_ifunc (__libc_strcspn,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strcspn_power8
|
||||||
|
: __strcspn_ppc);
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen.c b/sysdeps/powerpc/powerpc64/multiarch/strlen.c
|
||||||
|
index 0cd1c6faff..f1e28414e0 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strlen.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strlen.c
|
||||||
|
@@ -35,12 +35,15 @@ extern __typeof (__redirect_strlen) __strlen_power10 attribute_hidden;
|
||||||
|
|
||||||
|
libc_ifunc (__libc_strlen,
|
||||||
|
# ifdef __LITTLE_ENDIAN__
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_3_1)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_3_1
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strlen_power10 :
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_3_00)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strlen_power9 :
|
||||||
|
# endif
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strlen_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strlen_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase.c b/sysdeps/powerpc/powerpc64/multiarch/strncase.c
|
||||||
|
index 644046bd74..2802cf2c3f 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncase.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncase.c
|
||||||
|
@@ -27,7 +27,8 @@ extern __typeof (__strncasecmp) __strncasecmp_power7 attribute_hidden;
|
||||||
|
extern __typeof (__strncasecmp) __strncasecmp_power8 attribute_hidden;
|
||||||
|
|
||||||
|
libc_ifunc (__libc_strncasecmp,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strncasecmp_power8:
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strncasecmp_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncat.c b/sysdeps/powerpc/powerpc64/multiarch/strncat.c
|
||||||
|
index 0036fca91a..9ea294a72d 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncat.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncat.c
|
||||||
|
@@ -26,9 +26,11 @@ extern __typeof (strncat) __strncat_power7 attribute_hidden;
|
||||||
|
extern __typeof (strncat) __strncat_power8 attribute_hidden;
|
||||||
|
|
||||||
|
libc_ifunc (strncat,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strncat_power8
|
||||||
|
- : (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ : (hwcap & PPC_FEATURE_ARCH_2_06
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strncat_power7
|
||||||
|
: __strncat_ppc);
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
index 1f689e5c05..2d21122854 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
@@ -38,7 +38,8 @@ extern __typeof (strncmp) __strncmp_power9 attribute_hidden;
|
||||||
|
ifunc symbol properly. */
|
||||||
|
libc_ifunc_redirected (__redirect_strncmp, strncmp,
|
||||||
|
# ifdef __LITTLE_ENDIAN__
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_3_00)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strncmp_power9 :
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
|
||||||
|
index baf375a75a..e68e9d9f88 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
|
||||||
|
@@ -29,7 +29,8 @@ extern __typeof (__strnlen) __strnlen_power8 attribute_hidden;
|
||||||
|
# undef strnlen
|
||||||
|
# undef __strnlen
|
||||||
|
libc_ifunc_redirected (__redirect___strnlen, __strnlen,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strnlen_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strnlen_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
|
||||||
|
index 1c9eea1817..7f0cf2a1b7 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
|
||||||
|
@@ -31,7 +31,8 @@ extern __typeof (strrchr) __strrchr_power8 attribute_hidden;
|
||||||
|
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||||
|
ifunc symbol properly. */
|
||||||
|
libc_ifunc_redirected (__redirect_strrchr, strrchr,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
? __strrchr_power8 :
|
||||||
|
(hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strrchr_power7
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strspn.c b/sysdeps/powerpc/powerpc64/multiarch/strspn.c
|
||||||
|
index 70167a176b..7613ab3d55 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strspn.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strspn.c
|
||||||
|
@@ -27,7 +27,8 @@ extern __typeof (strspn) __strspn_ppc attribute_hidden;
|
||||||
|
extern __typeof (strspn) __strspn_power8 attribute_hidden;
|
||||||
|
|
||||||
|
libc_ifunc (__libc_strspn,
|
||||||
|
- (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||||
|
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
? __strspn_power8
|
||||||
|
: __strspn_ppc);
|
||||||
|
|
@ -0,0 +1,652 @@
|
|||||||
|
From 21841f0d562f0e944c4d267a28cc3ebd19c847e9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mahesh Bodapati <bmahi496@linux.ibm.com>
|
||||||
|
Date: Tue, 1 Aug 2023 07:41:17 -0500
|
||||||
|
Subject: PowerPC: Influence cpu/arch hwcap features via GLIBC_TUNABLES
|
||||||
|
|
||||||
|
This patch enables the option to influence hwcaps used by PowerPC.
|
||||||
|
The environment variable, GLIBC_TUNABLES=glibc.cpu.hwcaps=-xxx,yyy,-zzz....,
|
||||||
|
can be used to enable CPU/ARCH feature yyy, disable CPU/ARCH feature xxx
|
||||||
|
and zzz, where the feature name is case-sensitive and has to match the ones
|
||||||
|
mentioned in the file{sysdeps/powerpc/dl-procinfo.c}.
|
||||||
|
|
||||||
|
Note that the hwcap tunables only used in the IFUNC selection.
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
[rebased to c9s by DJ]
|
||||||
|
|
||||||
|
diff -rupN a/manual/tunables.texi b/manual/tunables.texi
|
||||||
|
--- a/manual/tunables.texi 2023-09-13 01:16:19.979884270 -0400
|
||||||
|
+++ b/manual/tunables.texi 2023-09-13 01:17:19.217179994 -0400
|
||||||
|
@@ -476,7 +476,10 @@ On s390x, the supported HWCAP and STFLE
|
||||||
|
@code{sysdeps/s390/cpu-features.c}. In addition the user can also set
|
||||||
|
a CPU arch-level like @code{z13} instead of single HWCAP and STFLE features.
|
||||||
|
|
||||||
|
-This tunable is specific to i386, x86-64 and s390x.
|
||||||
|
+On powerpc, the supported HWCAP and HWCAP2 features can be found in
|
||||||
|
+@code{sysdeps/powerpc/dl-procinfo.c}.
|
||||||
|
+
|
||||||
|
+This tunable is specific to i386, x86-64, s390x and powerpc.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp Tunable glibc.cpu.cached_memopt
|
||||||
|
diff -rupN a/sysdeps/powerpc/cpu-features.c b/sysdeps/powerpc/cpu-features.c
|
||||||
|
--- a/sysdeps/powerpc/cpu-features.c 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/powerpc/cpu-features.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
@@ -1,39 +0,0 @@
|
||||||
|
-/* Initialize cpu feature data. PowerPC version.
|
||||||
|
- Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||||
|
- This file is part of the GNU C Library.
|
||||||
|
-
|
||||||
|
- The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
- modify it under the terms of the GNU Lesser General Public
|
||||||
|
- License as published by the Free Software Foundation; either
|
||||||
|
- version 2.1 of the License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
- Lesser General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Lesser General Public
|
||||||
|
- License along with the GNU C Library; if not, see
|
||||||
|
- <https://www.gnu.org/licenses/>. */
|
||||||
|
-
|
||||||
|
-#include <stdint.h>
|
||||||
|
-#include <cpu-features.h>
|
||||||
|
-
|
||||||
|
-#if HAVE_TUNABLES
|
||||||
|
-# include <elf/dl-tunables.h>
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-static inline void
|
||||||
|
-init_cpu_features (struct cpu_features *cpu_features)
|
||||||
|
-{
|
||||||
|
- /* Default is to use aligned memory access on optimized function unless
|
||||||
|
- tunables is enable, since for this case user can explicit disable
|
||||||
|
- unaligned optimizations. */
|
||||||
|
-#if HAVE_TUNABLES
|
||||||
|
- int32_t cached_memfunc = TUNABLE_GET (glibc, cpu, cached_memopt, int32_t,
|
||||||
|
- NULL);
|
||||||
|
- cpu_features->use_cached_memopt = (cached_memfunc > 0);
|
||||||
|
-#else
|
||||||
|
- cpu_features->use_cached_memopt = false;
|
||||||
|
-#endif
|
||||||
|
-}
|
||||||
|
diff -rupN a/sysdeps/powerpc/cpu-features.h b/sysdeps/powerpc/cpu-features.h
|
||||||
|
--- a/sysdeps/powerpc/cpu-features.h 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/powerpc/cpu-features.h 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
@@ -1,28 +0,0 @@
|
||||||
|
-/* Initialize cpu feature data. PowerPC version.
|
||||||
|
- Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||||
|
-
|
||||||
|
- The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
- modify it under the terms of the GNU Lesser General Public
|
||||||
|
- License as published by the Free Software Foundation; either
|
||||||
|
- version 2.1 of the License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
- Lesser General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Lesser General Public
|
||||||
|
- License along with the GNU C Library; if not, see
|
||||||
|
- <https://www.gnu.org/licenses/>. */
|
||||||
|
-
|
||||||
|
-#ifndef __CPU_FEATURES_POWERPC_H
|
||||||
|
-# define __CPU_FEATURES_POWERPC_H
|
||||||
|
-
|
||||||
|
-#include <stdbool.h>
|
||||||
|
-
|
||||||
|
-struct cpu_features
|
||||||
|
-{
|
||||||
|
- bool use_cached_memopt;
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-#endif /* __CPU_FEATURES_H */
|
||||||
|
diff -rupN a/sysdeps/powerpc/dl-tunables.list b/sysdeps/powerpc/dl-tunables.list
|
||||||
|
--- a/sysdeps/powerpc/dl-tunables.list 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/powerpc/dl-tunables.list 2023-09-13 01:17:19.226180343 -0400
|
||||||
|
@@ -24,5 +24,8 @@ glibc {
|
||||||
|
maxval: 1
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
+ hwcaps {
|
||||||
|
+ type: STRING
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff -rupN a/sysdeps/powerpc/hwcapinfo.c b/sysdeps/powerpc/hwcapinfo.c
|
||||||
|
--- a/sysdeps/powerpc/hwcapinfo.c 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/powerpc/hwcapinfo.c 2023-09-13 01:17:19.229180459 -0400
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <shlib-compat.h>
|
||||||
|
#include <dl-procinfo.h>
|
||||||
|
+#include <cpu-features.c>
|
||||||
|
|
||||||
|
uint64_t __tcb_hwcap __attribute__ ((visibility ("hidden")));
|
||||||
|
uint32_t __tcb_platform __attribute__ ((visibility ("hidden")));
|
||||||
|
@@ -64,6 +65,9 @@ __tcb_parse_hwcap_and_convert_at_platfor
|
||||||
|
else if (h1 & PPC_FEATURE_POWER5)
|
||||||
|
h1 |= PPC_FEATURE_POWER4;
|
||||||
|
|
||||||
|
+ uint64_t array_hwcaps[] = { h1, h2 };
|
||||||
|
+ init_cpu_features (&GLRO(dl_powerpc_cpu_features), array_hwcaps);
|
||||||
|
+
|
||||||
|
/* Consolidate both HWCAP and HWCAP2 into a single doubleword so that
|
||||||
|
we can read both in a single load later. */
|
||||||
|
__tcb_hwcap = h2;
|
||||||
|
diff -rupN a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c
|
||||||
|
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c 2023-09-13 01:17:19.232180575 -0400
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
#include <ifunc-impl-list.h>
|
||||||
|
+#include <cpu-features.h>
|
||||||
|
|
||||||
|
/* Maximum number of IFUNC implementations. */
|
||||||
|
#define MAX_IFUNC 6
|
||||||
|
@@ -33,7 +34,8 @@ __libc_ifunc_impl_list (const char *name
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
- unsigned long int hwcap = GLRO(dl_hwcap);
|
||||||
|
+ const struct cpu_features *features = &GLRO(dl_powerpc_cpu_features);
|
||||||
|
+ unsigned long int hwcap = features->hwcap;
|
||||||
|
/* hwcap contains only the latest supported ISA, the code checks which is
|
||||||
|
and fills the previous supported ones. */
|
||||||
|
if (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
diff -rupN a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
|
||||||
|
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h 2023-09-13 01:17:19.232180575 -0400
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
+#include <cpu-features.h>
|
||||||
|
|
||||||
|
/* The code checks if _rtld_global_ro was realocated before trying to access
|
||||||
|
the dl_hwcap field. The assembly is to make the compiler not optimize the
|
||||||
|
@@ -32,11 +33,12 @@
|
||||||
|
# define __GLRO(value) GLRO(value)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-/* dl_hwcap contains only the latest supported ISA, the macro checks which is
|
||||||
|
- and fills the previous ones. */
|
||||||
|
+/* Get the hardware information post the tunables set, the macro checks
|
||||||
|
+ it and fills the previous ones. */
|
||||||
|
#define INIT_ARCH() \
|
||||||
|
- unsigned long int hwcap = __GLRO(dl_hwcap); \
|
||||||
|
- unsigned long int __attribute__((unused)) hwcap2 = __GLRO(dl_hwcap2); \
|
||||||
|
+ const struct cpu_features *features = &GLRO(dl_powerpc_cpu_features); \
|
||||||
|
+ unsigned long int hwcap = features->hwcap; \
|
||||||
|
+ unsigned long int __attribute__((unused)) hwcap2 = features->hwcap2; \
|
||||||
|
bool __attribute__((unused)) use_cached_memopt = \
|
||||||
|
__GLRO(dl_powerpc_cpu_features.use_cached_memopt); \
|
||||||
|
if (hwcap & PPC_FEATURE_ARCH_2_06) \
|
||||||
|
diff -rupN a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/dl-machine.h 2023-09-13 01:16:17.582791395 -0400
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h 2023-09-13 01:17:19.236180730 -0400
|
||||||
|
@@ -27,7 +27,6 @@
|
||||||
|
#include <dl-tls.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <hwcapinfo.h>
|
||||||
|
-#include <cpu-features.c>
|
||||||
|
#include <dl-static-tls.h>
|
||||||
|
#include <dl-funcdesc.h>
|
||||||
|
#include <dl-machine-rel.h>
|
||||||
|
@@ -293,7 +292,6 @@ static inline void __attribute__ ((unuse
|
||||||
|
dl_platform_init (void)
|
||||||
|
{
|
||||||
|
__tcb_parse_hwcap_and_convert_at_platform ();
|
||||||
|
- init_cpu_features (&GLRO(dl_powerpc_cpu_features));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff -rupN a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c 2023-09-13 01:16:20.219893569 -0400
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c 2023-09-13 01:19:17.169756083 -0400
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
+#include <cpu-features.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
@@ -32,9 +33,9 @@ __libc_ifunc_impl_list (const char *name
|
||||||
|
assert (max >= MAX_IFUNC);
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
-
|
||||||
|
- unsigned long int hwcap = GLRO(dl_hwcap);
|
||||||
|
- unsigned long int hwcap2 = GLRO(dl_hwcap2);
|
||||||
|
+ const struct cpu_features *features = &GLRO(dl_powerpc_cpu_features);
|
||||||
|
+ unsigned long int hwcap = features->hwcap;
|
||||||
|
+ unsigned long int hwcap2 = features->hwcap2;
|
||||||
|
#ifdef SHARED
|
||||||
|
int cacheline_size = GLRO(dl_cache_line_size);
|
||||||
|
#endif
|
||||||
|
diff -rupN a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile 2023-09-13 01:17:19.243181002 -0400
|
||||||
|
@@ -21,7 +21,12 @@ ifeq ($(subdir),misc)
|
||||||
|
sysdep_headers += bits/ppc.h
|
||||||
|
sysdep_routines += get_timebase_freq
|
||||||
|
tests-static += test-gettimebasefreq-static
|
||||||
|
-tests += $(tests-static)
|
||||||
|
-tests += test-gettimebasefreq
|
||||||
|
-tests += test-powerpc-linux-sysconf
|
||||||
|
+tests += \
|
||||||
|
+ $(tests-static) \
|
||||||
|
+ test-gettimebasefreq \
|
||||||
|
+ test-powerpc-linux-sysconf \
|
||||||
|
+ tst-hwcap-tunables \
|
||||||
|
+ # tests
|
||||||
|
+
|
||||||
|
+tst-hwcap-tunables-ARGS = -- $(host-test-program-cmd)
|
||||||
|
endif
|
||||||
|
diff -rupN a/sysdeps/unix/sysv/linux/powerpc/cpu-features.c b/sysdeps/unix/sysv/linux/powerpc/cpu-features.c
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/cpu-features.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/cpu-features.c 2023-09-13 01:17:19.247181157 -0400
|
||||||
|
@@ -0,0 +1,124 @@
|
||||||
|
+/* Initialize cpu feature data. PowerPC version.
|
||||||
|
+ Copyright (C) 2017-2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <array_length.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <cpu-features.h>
|
||||||
|
+#include <elf/dl-tunables.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
|
||||||
|
+{
|
||||||
|
+ /* The current IFUNC selection is always using the most recent
|
||||||
|
+ features which are available via AT_HWCAP or AT_HWCAP2. But in
|
||||||
|
+ some scenarios it is useful to adjust this selection.
|
||||||
|
+
|
||||||
|
+ The environment variable:
|
||||||
|
+
|
||||||
|
+ GLIBC_TUNABLES=glibc.cpu.hwcaps=-xxx,yyy,....
|
||||||
|
+
|
||||||
|
+ Can be used to enable HWCAP/HWCAP2 feature yyy, disable HWCAP/HWCAP2
|
||||||
|
+ feature xxx, where the feature name is case-sensitive and has to match
|
||||||
|
+ the ones mentioned in the file{sysdeps/powerpc/dl-procinfo.c}. */
|
||||||
|
+
|
||||||
|
+ /* Copy the features from dl_powerpc_cpu_features, which contains the
|
||||||
|
+ features provided by AT_HWCAP and AT_HWCAP2. */
|
||||||
|
+ struct cpu_features *cpu_features = &GLRO(dl_powerpc_cpu_features);
|
||||||
|
+ unsigned long int tcbv_hwcap = cpu_features->hwcap;
|
||||||
|
+ unsigned long int tcbv_hwcap2 = cpu_features->hwcap2;
|
||||||
|
+ const char *token = valp->strval;
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ const char *token_end, *feature;
|
||||||
|
+ bool disable;
|
||||||
|
+ size_t token_len, i, feature_len, offset = 0;
|
||||||
|
+ /* Find token separator or end of string. */
|
||||||
|
+ for (token_end = token; *token_end != ','; token_end++)
|
||||||
|
+ if (*token_end == '\0')
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ /* Determine feature. */
|
||||||
|
+ token_len = token_end - token;
|
||||||
|
+ if (*token == '-')
|
||||||
|
+ {
|
||||||
|
+ disable = true;
|
||||||
|
+ feature = token + 1;
|
||||||
|
+ feature_len = token_len - 1;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ disable = false;
|
||||||
|
+ feature = token;
|
||||||
|
+ feature_len = token_len;
|
||||||
|
+ }
|
||||||
|
+ for (i = 0; i < array_length (hwcap_tunables); ++i)
|
||||||
|
+ {
|
||||||
|
+ const char *hwcap_name = hwcap_names + offset;
|
||||||
|
+ size_t hwcap_name_len = strlen (hwcap_name);
|
||||||
|
+ /* Check the tunable name on the supported list. */
|
||||||
|
+ if (hwcap_name_len == feature_len
|
||||||
|
+ && memcmp (feature, hwcap_name, feature_len) == 0)
|
||||||
|
+ {
|
||||||
|
+ /* Update the hwcap and hwcap2 bits. */
|
||||||
|
+ if (disable)
|
||||||
|
+ {
|
||||||
|
+ /* Id is 1 for hwcap2 tunable. */
|
||||||
|
+ if (hwcap_tunables[i].id)
|
||||||
|
+ cpu_features->hwcap2 &= ~(hwcap_tunables[i].mask);
|
||||||
|
+ else
|
||||||
|
+ cpu_features->hwcap &= ~(hwcap_tunables[i].mask);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* Enable the features and also check that no unsupported
|
||||||
|
+ features were enabled by user. */
|
||||||
|
+ if (hwcap_tunables[i].id)
|
||||||
|
+ cpu_features->hwcap2 |= (tcbv_hwcap2 & hwcap_tunables[i].mask);
|
||||||
|
+ else
|
||||||
|
+ cpu_features->hwcap |= (tcbv_hwcap & hwcap_tunables[i].mask);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ offset += hwcap_name_len + 1;
|
||||||
|
+ }
|
||||||
|
+ token += token_len;
|
||||||
|
+ /* ... and skip token separator for next round. */
|
||||||
|
+ if (*token == ',')
|
||||||
|
+ token++;
|
||||||
|
+ }
|
||||||
|
+ while (*token != '\0');
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void
|
||||||
|
+init_cpu_features (struct cpu_features *cpu_features, uint64_t hwcaps[])
|
||||||
|
+{
|
||||||
|
+ /* Fill the cpu_features with the supported hwcaps
|
||||||
|
+ which are set by __tcb_parse_hwcap_and_convert_at_platform. */
|
||||||
|
+ cpu_features->hwcap = hwcaps[0];
|
||||||
|
+ cpu_features->hwcap2 = hwcaps[1];
|
||||||
|
+ /* Default is to use aligned memory access on optimized function unless
|
||||||
|
+ tunables is enable, since for this case user can explicit disable
|
||||||
|
+ unaligned optimizations. */
|
||||||
|
+ int32_t cached_memfunc = TUNABLE_GET (glibc, cpu, cached_memopt, int32_t,
|
||||||
|
+ NULL);
|
||||||
|
+ cpu_features->use_cached_memopt = (cached_memfunc > 0);
|
||||||
|
+ TUNABLE_GET (glibc, cpu, hwcaps, tunable_val_t *,
|
||||||
|
+ TUNABLE_CALLBACK (set_hwcaps));
|
||||||
|
+}
|
||||||
|
diff -rupN a/sysdeps/unix/sysv/linux/powerpc/cpu-features.h b/sysdeps/unix/sysv/linux/powerpc/cpu-features.h
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/cpu-features.h 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/cpu-features.h 2023-09-13 01:17:19.251181312 -0400
|
||||||
|
@@ -0,0 +1,130 @@
|
||||||
|
+/* Initialize cpu feature data. PowerPC version.
|
||||||
|
+ Copyright (C) 2017-2023 Free Software Foundation, Inc.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#ifndef __CPU_FEATURES_POWERPC_H
|
||||||
|
+# define __CPU_FEATURES_POWERPC_H
|
||||||
|
+
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+
|
||||||
|
+struct cpu_features
|
||||||
|
+{
|
||||||
|
+ bool use_cached_memopt;
|
||||||
|
+ unsigned long int hwcap;
|
||||||
|
+ unsigned long int hwcap2;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const char hwcap_names[] = {
|
||||||
|
+ "4xxmac\0"
|
||||||
|
+ "altivec\0"
|
||||||
|
+ "arch_2_05\0"
|
||||||
|
+ "arch_2_06\0"
|
||||||
|
+ "archpmu\0"
|
||||||
|
+ "booke\0"
|
||||||
|
+ "cellbe\0"
|
||||||
|
+ "dfp\0"
|
||||||
|
+ "efpdouble\0"
|
||||||
|
+ "efpsingle\0"
|
||||||
|
+ "fpu\0"
|
||||||
|
+ "ic_snoop\0"
|
||||||
|
+ "mmu\0"
|
||||||
|
+ "notb\0"
|
||||||
|
+ "pa6t\0"
|
||||||
|
+ "power4\0"
|
||||||
|
+ "power5\0"
|
||||||
|
+ "power5+\0"
|
||||||
|
+ "power6x\0"
|
||||||
|
+ "ppc32\0"
|
||||||
|
+ "ppc601\0"
|
||||||
|
+ "ppc64\0"
|
||||||
|
+ "ppcle\0"
|
||||||
|
+ "smt\0"
|
||||||
|
+ "spe\0"
|
||||||
|
+ "true_le\0"
|
||||||
|
+ "ucache\0"
|
||||||
|
+ "vsx\0"
|
||||||
|
+ "arch_2_07\0"
|
||||||
|
+ "dscr\0"
|
||||||
|
+ "ebb\0"
|
||||||
|
+ "htm\0"
|
||||||
|
+ "htm-nosc\0"
|
||||||
|
+ "htm-no-suspend\0"
|
||||||
|
+ "isel\0"
|
||||||
|
+ "tar\0"
|
||||||
|
+ "vcrypto\0"
|
||||||
|
+ "arch_3_00\0"
|
||||||
|
+ "ieee128\0"
|
||||||
|
+ "darn\0"
|
||||||
|
+ "scv\0"
|
||||||
|
+ "arch_3_1\0"
|
||||||
|
+ "mma\0"
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const struct
|
||||||
|
+{
|
||||||
|
+ unsigned int mask;
|
||||||
|
+ bool id;
|
||||||
|
+} hwcap_tunables[] = {
|
||||||
|
+ /* AT_HWCAP tunable masks. */
|
||||||
|
+ { PPC_FEATURE_HAS_4xxMAC, 0 },
|
||||||
|
+ { PPC_FEATURE_HAS_ALTIVEC, 0 },
|
||||||
|
+ { PPC_FEATURE_ARCH_2_05, 0 },
|
||||||
|
+ { PPC_FEATURE_ARCH_2_06, 0 },
|
||||||
|
+ { PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0 },
|
||||||
|
+ { PPC_FEATURE_BOOKE, 0 },
|
||||||
|
+ { PPC_FEATURE_CELL_BE, 0 },
|
||||||
|
+ { PPC_FEATURE_HAS_DFP, 0 },
|
||||||
|
+ { PPC_FEATURE_HAS_EFP_DOUBLE, 0 },
|
||||||
|
+ { PPC_FEATURE_HAS_EFP_SINGLE, 0 },
|
||||||
|
+ { PPC_FEATURE_HAS_FPU, 0 },
|
||||||
|
+ { PPC_FEATURE_ICACHE_SNOOP, 0 },
|
||||||
|
+ { PPC_FEATURE_HAS_MMU, 0 },
|
||||||
|
+ { PPC_FEATURE_NO_TB, 0 },
|
||||||
|
+ { PPC_FEATURE_PA6T, 0 },
|
||||||
|
+ { PPC_FEATURE_POWER4, 0 },
|
||||||
|
+ { PPC_FEATURE_POWER5, 0 },
|
||||||
|
+ { PPC_FEATURE_POWER5_PLUS, 0 },
|
||||||
|
+ { PPC_FEATURE_POWER6_EXT, 0 },
|
||||||
|
+ { PPC_FEATURE_32, 0 },
|
||||||
|
+ { PPC_FEATURE_601_INSTR, 0 },
|
||||||
|
+ { PPC_FEATURE_64, 0 },
|
||||||
|
+ { PPC_FEATURE_PPC_LE, 0 },
|
||||||
|
+ { PPC_FEATURE_SMT, 0 },
|
||||||
|
+ { PPC_FEATURE_HAS_SPE, 0 },
|
||||||
|
+ { PPC_FEATURE_TRUE_LE, 0 },
|
||||||
|
+ { PPC_FEATURE_UNIFIED_CACHE, 0 },
|
||||||
|
+ { PPC_FEATURE_HAS_VSX, 0 },
|
||||||
|
+
|
||||||
|
+ /* AT_HWCAP2 tunable masks. */
|
||||||
|
+ { PPC_FEATURE2_ARCH_2_07, 1 },
|
||||||
|
+ { PPC_FEATURE2_HAS_DSCR, 1 },
|
||||||
|
+ { PPC_FEATURE2_HAS_EBB, 1 },
|
||||||
|
+ { PPC_FEATURE2_HAS_HTM, 1 },
|
||||||
|
+ { PPC_FEATURE2_HTM_NOSC, 1 },
|
||||||
|
+ { PPC_FEATURE2_HTM_NO_SUSPEND, 1 },
|
||||||
|
+ { PPC_FEATURE2_HAS_ISEL, 1 },
|
||||||
|
+ { PPC_FEATURE2_HAS_TAR, 1 },
|
||||||
|
+ { PPC_FEATURE2_HAS_VEC_CRYPTO, 1 },
|
||||||
|
+ { PPC_FEATURE2_ARCH_3_00, 1 },
|
||||||
|
+ { PPC_FEATURE2_HAS_IEEE128, 1 },
|
||||||
|
+ { PPC_FEATURE2_DARN, 1 },
|
||||||
|
+ { PPC_FEATURE2_SCV, 1 },
|
||||||
|
+ { PPC_FEATURE2_ARCH_3_1, 1 },
|
||||||
|
+ { PPC_FEATURE2_MMA, 1 },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif /* __CPU_FEATURES_H */
|
||||||
|
diff -rupN a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list 2023-09-13 01:16:19.989884657 -0400
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list 2023-09-13 01:17:19.254181428 -0400
|
||||||
|
@@ -28,3 +28,4 @@
|
||||||
|
@order glibc.malloc.check
|
||||||
|
@order glibc.gmon.minarcs
|
||||||
|
@order glibc.gmon.maxarcs
|
||||||
|
+@order glibc.cpu.hwcaps
|
||||||
|
diff -rupN a/sysdeps/unix/sysv/linux/powerpc/tst-hwcap-tunables.c b/sysdeps/unix/sysv/linux/powerpc/tst-hwcap-tunables.c
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/tst-hwcap-tunables.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/tst-hwcap-tunables.c 2023-09-13 01:17:19.258181583 -0400
|
||||||
|
@@ -0,0 +1,128 @@
|
||||||
|
+/* Tests for powerpc GLIBC_TUNABLES=glibc.cpu.hwcaps filter.
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <array_length.h>
|
||||||
|
+#include <getopt.h>
|
||||||
|
+#include <ifunc-impl-list.h>
|
||||||
|
+#include <spawn.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+#include <support/xunistd.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+
|
||||||
|
+/* Nonzero if the program gets called via `exec'. */
|
||||||
|
+#define CMDLINE_OPTIONS \
|
||||||
|
+ { "restart", no_argument, &restart, 1 },
|
||||||
|
+static int restart;
|
||||||
|
+
|
||||||
|
+/* Hold the four initial argument used to respawn the process, plus the extra
|
||||||
|
+ '--direct', '--restart', and the function to check */
|
||||||
|
+static char *spargs[8];
|
||||||
|
+static int fc;
|
||||||
|
+
|
||||||
|
+/* Called on process re-execution. */
|
||||||
|
+_Noreturn static void
|
||||||
|
+handle_restart (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ TEST_VERIFY_EXIT (argc == 1);
|
||||||
|
+ const char *funcname = argv[0];
|
||||||
|
+
|
||||||
|
+ struct libc_ifunc_impl impls[32];
|
||||||
|
+ int cnt = __libc_ifunc_impl_list ("memcpy", impls, array_length (impls));
|
||||||
|
+ if (cnt == 0)
|
||||||
|
+ _exit (EXIT_SUCCESS);
|
||||||
|
+ TEST_VERIFY_EXIT (cnt >= 1);
|
||||||
|
+ for (int i = 0; i < cnt; i++) {
|
||||||
|
+ if (strcmp (impls[i].name, funcname) == 0)
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (impls[i].usable, false);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _exit (EXIT_SUCCESS);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+run_test (const char *filter, const char *funcname)
|
||||||
|
+{
|
||||||
|
+ printf ("info: checking filter %s (expect %s ifunc selection to be removed)\n",
|
||||||
|
+ filter, funcname);
|
||||||
|
+ char *tunable = xasprintf ("GLIBC_TUNABLES=glibc.cpu.hwcaps=%s", filter);
|
||||||
|
+ char *const newenvs[] = { (char*) tunable, NULL };
|
||||||
|
+ spargs[fc] = (char *) funcname;
|
||||||
|
+
|
||||||
|
+ pid_t pid;
|
||||||
|
+ TEST_COMPARE (posix_spawn (&pid, spargs[0], NULL, NULL, spargs, newenvs), 0);
|
||||||
|
+ int status;
|
||||||
|
+ TEST_COMPARE (xwaitpid (pid, &status, 0), pid);
|
||||||
|
+ TEST_VERIFY (WIFEXITED (status));
|
||||||
|
+ TEST_VERIFY (!WIFSIGNALED (status));
|
||||||
|
+ TEST_COMPARE (WEXITSTATUS (status), 0);
|
||||||
|
+
|
||||||
|
+ free (tunable);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ if (restart)
|
||||||
|
+ handle_restart (argc - 1, &argv[1]);
|
||||||
|
+
|
||||||
|
+ TEST_VERIFY_EXIT (argc == 2 || argc == 5);
|
||||||
|
+
|
||||||
|
+ int i;
|
||||||
|
+ for (i = 0; i < argc - 1; i++)
|
||||||
|
+ spargs[i] = argv[i + 1];
|
||||||
|
+ spargs[i++] = (char *) "--direct";
|
||||||
|
+ spargs[i++] = (char *) "--restart";
|
||||||
|
+ fc = i++;
|
||||||
|
+ spargs[i] = NULL;
|
||||||
|
+
|
||||||
|
+ unsigned long int hwcap = getauxval (AT_HWCAP);
|
||||||
|
+ unsigned long int hwcap2 = getauxval (AT_HWCAP2);
|
||||||
|
+ if (__WORDSIZE == 64)
|
||||||
|
+ {
|
||||||
|
+ if (hwcap2 & PPC_FEATURE2_ARCH_3_1)
|
||||||
|
+ run_test ("-arch_3_1", "__memcpy_power10");
|
||||||
|
+ if (hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
+ run_test ("-arch_2_07", "__memcpy_power8_cached");
|
||||||
|
+ if (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
+ run_test ("-arch_2_06", "__memcpy_power7");
|
||||||
|
+ if (hwcap & PPC_FEATURE_ARCH_2_05)
|
||||||
|
+ run_test ("-arch_2_06,-arch_2_05","__memcpy_power6");
|
||||||
|
+ run_test ("-arch_2_06,-arch_2_05,-power5+,-power5,-power4", "__memcpy_power4");
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ if (hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
|
+ run_test ("-vsx", "__memcpy_power7");
|
||||||
|
+ if (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
+ run_test ("-arch_2_06", "__memcpy_a2");
|
||||||
|
+ if (hwcap & PPC_FEATURE_ARCH_2_05)
|
||||||
|
+ run_test ("-arch_2_05", "__memcpy_power6");
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION_ARGV do_test
|
||||||
|
+#include <support/test-driver.c>
|
@ -0,0 +1,69 @@
|
|||||||
|
commit 1493622f4f9048ffede3fbedb64695efa49d662a
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Mon Aug 28 12:08:14 2023 -0700
|
||||||
|
|
||||||
|
x86: Check the lower byte of EAX of CPUID leaf 2 [BZ #30643]
|
||||||
|
|
||||||
|
The old Intel software developer manual specified that the low byte of
|
||||||
|
EAX of CPUID leaf 2 returned 1 which indicated the number of rounds of
|
||||||
|
CPUDID leaf 2 was needed to retrieve the complete cache information. The
|
||||||
|
newer Intel manual has been changed to that it should always return 1
|
||||||
|
and be ignored. If the lower byte isn't 1, CPUID leaf 2 can't be used.
|
||||||
|
In this case, we ignore CPUID leaf 2 and use CPUID leaf 4 instead. If
|
||||||
|
CPUID leaf 4 doesn't contain the cache information, cache information
|
||||||
|
isn't available at all. This addresses BZ #30643.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
|
||||||
|
index f950e488cfbe42dd..bd2f2b65f78056ca 100644
|
||||||
|
--- a/sysdeps/x86/dl-cacheinfo.h
|
||||||
|
+++ b/sysdeps/x86/dl-cacheinfo.h
|
||||||
|
@@ -187,7 +187,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2,
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
/* There is no other cache information anywhere else. */
|
||||||
|
- break;
|
||||||
|
+ return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@@ -257,28 +257,23 @@ handle_intel (int name, const struct cpu_features *cpu_features)
|
||||||
|
|
||||||
|
/* OK, we can use the CPUID instruction to get all info about the
|
||||||
|
caches. */
|
||||||
|
- unsigned int cnt = 0;
|
||||||
|
- unsigned int max = 1;
|
||||||
|
long int result = 0;
|
||||||
|
bool no_level_2_or_3 = false;
|
||||||
|
bool has_level_2 = false;
|
||||||
|
+ unsigned int eax;
|
||||||
|
+ unsigned int ebx;
|
||||||
|
+ unsigned int ecx;
|
||||||
|
+ unsigned int edx;
|
||||||
|
+ __cpuid (2, eax, ebx, ecx, edx);
|
||||||
|
|
||||||
|
- while (cnt++ < max)
|
||||||
|
+ /* The low byte of EAX of CPUID leaf 2 should always return 1 and it
|
||||||
|
+ should be ignored. If it isn't 1, use CPUID leaf 4 instead. */
|
||||||
|
+ if ((eax & 0xff) != 1)
|
||||||
|
+ return intel_check_word (name, 0xff, &has_level_2, &no_level_2_or_3,
|
||||||
|
+ cpu_features);
|
||||||
|
+ else
|
||||||
|
{
|
||||||
|
- unsigned int eax;
|
||||||
|
- unsigned int ebx;
|
||||||
|
- unsigned int ecx;
|
||||||
|
- unsigned int edx;
|
||||||
|
- __cpuid (2, eax, ebx, ecx, edx);
|
||||||
|
-
|
||||||
|
- /* The low byte of EAX in the first round contain the number of
|
||||||
|
- rounds we have to make. At least one, the one we are already
|
||||||
|
- doing. */
|
||||||
|
- if (cnt == 1)
|
||||||
|
- {
|
||||||
|
- max = eax & 0xff;
|
||||||
|
- eax &= 0xffffff00;
|
||||||
|
- }
|
||||||
|
+ eax &= 0xffffff00;
|
||||||
|
|
||||||
|
/* Process the individual registers' value. */
|
||||||
|
result = intel_check_word (name, eax, &has_level_2,
|
@ -0,0 +1,72 @@
|
|||||||
|
commit 2aa0974d2573441bffd596b07bff8698b1f2f18c
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Fri Oct 20 14:29:50 2023 +0200
|
||||||
|
|
||||||
|
elf: ldconfig should skip temporary files created by package managers
|
||||||
|
|
||||||
|
This avoids crashes due to partially written files, after a package
|
||||||
|
update is interrupted.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/ldconfig.c
|
||||||
|
(missing alloca removal downstream)
|
||||||
|
|
||||||
|
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
|
||||||
|
index be47ad8c2d7f89f3..f0c811001965cc46 100644
|
||||||
|
--- a/elf/ldconfig.c
|
||||||
|
+++ b/elf/ldconfig.c
|
||||||
|
@@ -778,6 +778,31 @@ struct dlib_entry
|
||||||
|
struct dlib_entry *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* Skip some temporary DSO files. These files may be partially written
|
||||||
|
+ and lead to ldconfig crashes when examined. */
|
||||||
|
+static bool
|
||||||
|
+skip_dso_based_on_name (const char *name, size_t len)
|
||||||
|
+{
|
||||||
|
+ /* Skip temporary files created by the prelink program. Files with
|
||||||
|
+ names like these are never really DSOs we want to look at. */
|
||||||
|
+ if (len >= sizeof (".#prelink#") - 1)
|
||||||
|
+ {
|
||||||
|
+ if (strcmp (name + len - sizeof (".#prelink#") + 1,
|
||||||
|
+ ".#prelink#") == 0)
|
||||||
|
+ return true;
|
||||||
|
+ if (len >= sizeof (".#prelink#.XXXXXX") - 1
|
||||||
|
+ && memcmp (name + len - sizeof (".#prelink#.XXXXXX")
|
||||||
|
+ + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ /* Skip temporary files created by RPM. */
|
||||||
|
+ if (memchr (name, len, ';') != NULL)
|
||||||
|
+ return true;
|
||||||
|
+ /* Skip temporary files created by dpkg. */
|
||||||
|
+ if (len > 4 && memcmp (name + len - 4, ".tmp", 4) == 0)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
|
||||||
|
static void
|
||||||
|
search_dir (const struct dir_entry *entry)
|
||||||
|
@@ -854,18 +879,8 @@ search_dir (const struct dir_entry *entry)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
size_t len = strlen (direntry->d_name);
|
||||||
|
- /* Skip temporary files created by the prelink program. Files with
|
||||||
|
- names like these are never really DSOs we want to look at. */
|
||||||
|
- if (len >= sizeof (".#prelink#") - 1)
|
||||||
|
- {
|
||||||
|
- if (strcmp (direntry->d_name + len - sizeof (".#prelink#") + 1,
|
||||||
|
- ".#prelink#") == 0)
|
||||||
|
- continue;
|
||||||
|
- if (len >= sizeof (".#prelink#.XXXXXX") - 1
|
||||||
|
- && memcmp (direntry->d_name + len - sizeof (".#prelink#.XXXXXX")
|
||||||
|
- + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
+ if (skip_dso_based_on_name (direntry->d_name, len))
|
||||||
|
+ continue;
|
||||||
|
len += strlen (entry->path) + 2;
|
||||||
|
if (len > file_name_len)
|
||||||
|
{
|
@ -0,0 +1,61 @@
|
|||||||
|
commit cfb5a97a93ea656e3b2263e42142a4032986d9ba
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Oct 23 12:53:16 2023 +0200
|
||||||
|
|
||||||
|
ldconfig: Fixes for skipping temporary files.
|
||||||
|
|
||||||
|
Arguments to a memchr call were swapped, causing incorrect skipping
|
||||||
|
of files.
|
||||||
|
|
||||||
|
Files related to dpkg have different names: they actually end in
|
||||||
|
.dpkg-new and .dpkg-tmp, not .tmp as I mistakenly assumed.
|
||||||
|
|
||||||
|
Fixes commit 2aa0974d2573441bffd59 ("elf: ldconfig should skip
|
||||||
|
temporary files created by package managers").
|
||||||
|
|
||||||
|
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
|
||||||
|
index f0c811001965cc46..4a96c409994d96c8 100644
|
||||||
|
--- a/elf/ldconfig.c
|
||||||
|
+++ b/elf/ldconfig.c
|
||||||
|
@@ -778,6 +778,17 @@ struct dlib_entry
|
||||||
|
struct dlib_entry *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* Return true if the N bytes at NAME end with with the characters in
|
||||||
|
+ the string SUFFIX. (NAME[N + 1] does not have to be a null byte.)
|
||||||
|
+ Expected to be called with a string literal for SUFFIX. */
|
||||||
|
+static inline bool
|
||||||
|
+endswithn (const char *name, size_t n, const char *suffix)
|
||||||
|
+{
|
||||||
|
+ return (n >= strlen (suffix)
|
||||||
|
+ && memcmp (name + n - strlen (suffix), suffix,
|
||||||
|
+ strlen (suffix)) == 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Skip some temporary DSO files. These files may be partially written
|
||||||
|
and lead to ldconfig crashes when examined. */
|
||||||
|
static bool
|
||||||
|
@@ -787,8 +798,7 @@ skip_dso_based_on_name (const char *name, size_t len)
|
||||||
|
names like these are never really DSOs we want to look at. */
|
||||||
|
if (len >= sizeof (".#prelink#") - 1)
|
||||||
|
{
|
||||||
|
- if (strcmp (name + len - sizeof (".#prelink#") + 1,
|
||||||
|
- ".#prelink#") == 0)
|
||||||
|
+ if (endswithn (name, len, ".#prelink#"))
|
||||||
|
return true;
|
||||||
|
if (len >= sizeof (".#prelink#.XXXXXX") - 1
|
||||||
|
&& memcmp (name + len - sizeof (".#prelink#.XXXXXX")
|
||||||
|
@@ -796,10 +806,11 @@ skip_dso_based_on_name (const char *name, size_t len)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/* Skip temporary files created by RPM. */
|
||||||
|
- if (memchr (name, len, ';') != NULL)
|
||||||
|
+ if (memchr (name, ';', len) != NULL)
|
||||||
|
return true;
|
||||||
|
/* Skip temporary files created by dpkg. */
|
||||||
|
- if (len > 4 && memcmp (name + len - 4, ".tmp", 4) == 0)
|
||||||
|
+ if (endswithn (name, len, ".dpkg-new")
|
||||||
|
+ || endswithn (name, len, ".dpkg-tmp"))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
commit 1626d8a521c7c771d4118b1328421fea113cab64
|
||||||
|
Author: Joe Simmons-Talbott <josimmon@redhat.com>
|
||||||
|
Date: Fri Apr 21 09:24:22 2023 -0400
|
||||||
|
|
||||||
|
string: Allow use of test-string.h for non-ifunc implementations.
|
||||||
|
|
||||||
|
Mark two variables as unused to silence warning when using
|
||||||
|
test-string.h for non-ifunc implementations.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/string/test-string.h b/string/test-string.h
|
||||||
|
index 41de973479..8bcb8afd0a 100644
|
||||||
|
--- a/string/test-string.h
|
||||||
|
+++ b/string/test-string.h
|
||||||
|
@@ -130,8 +130,8 @@ cmdline_process_function (int c)
|
||||||
|
/* Increase size of FUNC_LIST if assert is triggered at run-time. */
|
||||||
|
static struct libc_ifunc_impl func_list[32];
|
||||||
|
static int func_count;
|
||||||
|
-static int impl_count = -1;
|
||||||
|
-static impl_t *impl_array;
|
||||||
|
+static int impl_count __attribute__ ((unused)) = -1;
|
||||||
|
+static impl_t *impl_array __attribute__ ((unused));
|
||||||
|
|
||||||
|
# define FOR_EACH_IMPL(impl, notall) \
|
||||||
|
impl_t *impl; \
|
@ -0,0 +1,233 @@
|
|||||||
|
commit eaaad78db41724e5a18a42becb238bfc4e683998
|
||||||
|
Author: Joe Simmons-Talbott <josimmon@redhat.com>
|
||||||
|
Date: Fri Apr 21 09:24:23 2023 -0400
|
||||||
|
|
||||||
|
string: Add tests for strdup (BZ #30266)
|
||||||
|
|
||||||
|
Copy strcpy tests for strdup. Covers some basic testcases with random
|
||||||
|
strings. Add a zero-length string testcase.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Conflicts:
|
||||||
|
string/Makefile
|
||||||
|
(different test backport order)
|
||||||
|
|
||||||
|
|
||||||
|
diff -Nrup a/string/Makefile b/string/Makefile
|
||||||
|
--- a/string/Makefile 2023-11-30 10:59:16.400251685 -0500
|
||||||
|
+++ b/string/Makefile 2023-11-30 11:16:42.829613344 -0500
|
||||||
|
@@ -63,7 +63,8 @@ tests := tester inl-tester noinl-tester
|
||||||
|
tst-strtok_r bug-strcoll2 tst-cmp tst-xbzero-opt \
|
||||||
|
test-endian-types test-endian-file-scope \
|
||||||
|
test-endian-sign-conversion tst-memmove-overflow \
|
||||||
|
- test-sig_np tst-strerror-fail
|
||||||
|
+ test-sig_np tst-strerror-fail \
|
||||||
|
+ test-strdup
|
||||||
|
|
||||||
|
# Both tests require the .mo translation files generated by msgfmt.
|
||||||
|
tests-translation := tst-strsignal \
|
||||||
|
diff -Nrup a/string/test-strdup.c b/string/test-strdup.c
|
||||||
|
--- a/string/test-strdup.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/string/test-strdup.c 2023-11-30 11:11:32.850447614 -0500
|
||||||
|
@@ -0,0 +1,201 @@
|
||||||
|
+/* Test and measure strdup functions.
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have 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>
|
||||||
|
+
|
||||||
|
+#ifdef WIDE
|
||||||
|
+# include <wchar.h>
|
||||||
|
+# define CHAR wchar_t
|
||||||
|
+# define sfmt "ls"
|
||||||
|
+# define BIG_CHAR WCHAR_MAX
|
||||||
|
+# define SMALL_CHAR 1273
|
||||||
|
+# define STRCMP wcscmp
|
||||||
|
+# define MEMCMP wmemcmp
|
||||||
|
+# define MEMSET wmemset
|
||||||
|
+# define TCS TEST_COMPARE_STRING_WIDE
|
||||||
|
+#else
|
||||||
|
+# define CHAR char
|
||||||
|
+# define sfmt "s"
|
||||||
|
+# define BIG_CHAR CHAR_MAX
|
||||||
|
+# define SMALL_CHAR 127
|
||||||
|
+# define STRCMP strcmp
|
||||||
|
+# define MEMCMP memcmp
|
||||||
|
+# define MEMSET memset
|
||||||
|
+# define TCS TEST_COMPARE_STRING
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef STRDUP_RESULT
|
||||||
|
+# define STRDUP_RESULT(dst, len) dst
|
||||||
|
+# define TEST_MAIN
|
||||||
|
+# ifndef WIDE
|
||||||
|
+# define TEST_NAME "strdup"
|
||||||
|
+# else
|
||||||
|
+# define TEST_NAME "wcsdup"
|
||||||
|
+# endif
|
||||||
|
+# include "test-string.h"
|
||||||
|
+# ifndef WIDE
|
||||||
|
+# define STRDUP strdup
|
||||||
|
+# else
|
||||||
|
+# define STRDUP wcsdup
|
||||||
|
+# endif
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+typedef CHAR *(*proto_t) (const CHAR *);
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_zero_len_test (void)
|
||||||
|
+{
|
||||||
|
+ CHAR src[1] = { '\0' };
|
||||||
|
+ CHAR *dst = STRDUP (src);
|
||||||
|
+
|
||||||
|
+ TCS (dst, src);
|
||||||
|
+ free (dst);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_one_test (const CHAR *src,
|
||||||
|
+ size_t len __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ CHAR *dst = STRDUP (src);
|
||||||
|
+
|
||||||
|
+ if (STRCMP (dst, src) != 0)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0,
|
||||||
|
+ "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
|
||||||
|
+ TEST_NAME, dst, src);
|
||||||
|
+ ret = 1;
|
||||||
|
+ free (dst);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ free (dst);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_test (size_t align1, size_t align2, size_t len, int max_char)
|
||||||
|
+{
|
||||||
|
+ size_t i;
|
||||||
|
+ CHAR *s1;
|
||||||
|
+/* For wcsdup: align1 and align2 here mean alignment not in bytes,
|
||||||
|
+ but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
|
||||||
|
+ len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
|
||||||
|
+ align1 &= 7;
|
||||||
|
+ if ((align1 + len) * sizeof (CHAR) >= page_size)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ align2 &= 7;
|
||||||
|
+ if ((align2 + len) * sizeof (CHAR) >= page_size)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ s1 = (CHAR *) (buf1) + align1;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < len; i++)
|
||||||
|
+ s1[i] = 32 + 23 * i % (max_char - 32);
|
||||||
|
+ s1[len] = 0;
|
||||||
|
+
|
||||||
|
+ do_one_test (s1, len);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_random_tests (void)
|
||||||
|
+{
|
||||||
|
+ size_t i, j, n, align1, align2, len;
|
||||||
|
+ CHAR *p1 = (CHAR *)(buf1 + page_size) - 512;
|
||||||
|
+ CHAR *res;
|
||||||
|
+
|
||||||
|
+ for (n = 0; n < ITERATIONS; n++)
|
||||||
|
+ {
|
||||||
|
+ /* align1 and align2 are expressed as wchar_t and not in bytes for wide
|
||||||
|
+ char test, and thus it will be equal to align times wchar_t size.
|
||||||
|
+
|
||||||
|
+ For non wide version we need to check all alignments from 0 to 63
|
||||||
|
+ since some assembly implementations have separate prolog for alignments
|
||||||
|
+ more 48. */
|
||||||
|
+
|
||||||
|
+ align1 = random () & (63 / sizeof (CHAR));
|
||||||
|
+ if (random () & 1)
|
||||||
|
+ align2 = random () & (63 / sizeof (CHAR));
|
||||||
|
+ else
|
||||||
|
+ align2 = align1 + (random () & 24);
|
||||||
|
+ len = random () & 511;
|
||||||
|
+ j = align1;
|
||||||
|
+ if (align2 > j)
|
||||||
|
+ j = align2;
|
||||||
|
+ if (len + j >= 511)
|
||||||
|
+ len = 510 - j - (random () & 7);
|
||||||
|
+ j = len + align1 + 64;
|
||||||
|
+ if (j > 512)
|
||||||
|
+ j = 512;
|
||||||
|
+ for (i = 0; i < j; i++)
|
||||||
|
+ {
|
||||||
|
+ if (i == len + align1)
|
||||||
|
+ p1[i] = 0;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ p1[i] = random () & BIG_CHAR;
|
||||||
|
+ if (i >= align1 && i < len + align1 && !p1[i])
|
||||||
|
+ p1[i] = (random () & SMALL_CHAR) + 3;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ res = STRDUP(p1 + align1);
|
||||||
|
+ TCS (res, (p1 + align1));
|
||||||
|
+ free (res);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+test_main (void)
|
||||||
|
+{
|
||||||
|
+ size_t i;
|
||||||
|
+
|
||||||
|
+ test_init ();
|
||||||
|
+
|
||||||
|
+ printf ("%23s", "");
|
||||||
|
+ printf ("\t%s", TEST_NAME);
|
||||||
|
+ putchar ('\n');
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < 16; ++i)
|
||||||
|
+ {
|
||||||
|
+ do_test (0, 0, i, SMALL_CHAR);
|
||||||
|
+ do_test (0, 0, i, BIG_CHAR);
|
||||||
|
+ do_test (0, i, i, SMALL_CHAR);
|
||||||
|
+ do_test (i, 0, i, BIG_CHAR);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 1; i < 8; ++i)
|
||||||
|
+ {
|
||||||
|
+ do_test (0, 0, 8 << i, SMALL_CHAR);
|
||||||
|
+ do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 1; i < 8; ++i)
|
||||||
|
+ {
|
||||||
|
+ do_test (i, 2 * i, 8 << i, SMALL_CHAR);
|
||||||
|
+ do_test (2 * i, i, 8 << i, BIG_CHAR);
|
||||||
|
+ do_test (i, i, 8 << i, SMALL_CHAR);
|
||||||
|
+ do_test (i, i, 8 << i, BIG_CHAR);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ do_zero_len_test ();
|
||||||
|
+ do_random_tests ();
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
@ -0,0 +1,232 @@
|
|||||||
|
commit 0c48aa0551151ea201f7f528492e89a0b08a6890
|
||||||
|
Author: Joe Simmons-Talbott <josimmon@redhat.com>
|
||||||
|
Date: Fri Apr 21 09:24:24 2023 -0400
|
||||||
|
|
||||||
|
string: Add tests for strndup (BZ #30266)
|
||||||
|
|
||||||
|
Copy strncpy tests for strndup. Covers some basic testcases with random
|
||||||
|
strings. Remove tests that set the destination's bytes and checked the
|
||||||
|
resulting buffer's bytes. Remove wide character test support since
|
||||||
|
wcsndup() doesn't exist.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Conflicts:
|
||||||
|
string/Makefile
|
||||||
|
(different test backport order)
|
||||||
|
|
||||||
|
diff -Nrup a/string/Makefile b/string/Makefile
|
||||||
|
--- a/string/Makefile 2023-11-30 11:55:02.263010916 -0500
|
||||||
|
+++ b/string/Makefile 2023-11-30 11:58:29.238954539 -0500
|
||||||
|
@@ -64,7 +64,7 @@ tests := tester inl-tester noinl-tester
|
||||||
|
test-endian-types test-endian-file-scope \
|
||||||
|
test-endian-sign-conversion tst-memmove-overflow \
|
||||||
|
test-sig_np tst-strerror-fail \
|
||||||
|
- test-strdup
|
||||||
|
+ test-strdup test-strndup
|
||||||
|
|
||||||
|
# Both tests require the .mo translation files generated by msgfmt.
|
||||||
|
tests-translation := tst-strsignal \
|
||||||
|
diff -Nrup a/string/test-strndup.c b/string/test-strndup.c
|
||||||
|
--- a/string/test-strndup.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/string/test-strndup.c 2023-11-30 11:56:24.986388053 -0500
|
||||||
|
@@ -0,0 +1,200 @@
|
||||||
|
+/* Test strndup functions.
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have 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>
|
||||||
|
+
|
||||||
|
+#define TEST_MAIN
|
||||||
|
+#include "test-string.h"
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_one_test (const char *src, size_t len, size_t n)
|
||||||
|
+{
|
||||||
|
+ char *dst = strndup (src, n);
|
||||||
|
+ size_t s = (len > n ? n: len) * sizeof (char);
|
||||||
|
+
|
||||||
|
+ TEST_COMPARE_BLOB (dst, s, src, s);
|
||||||
|
+
|
||||||
|
+ free (dst);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
|
||||||
|
+{
|
||||||
|
+ size_t i;
|
||||||
|
+ char *s1;
|
||||||
|
+
|
||||||
|
+ align1 &= 7;
|
||||||
|
+ if ((align1 + len) * sizeof (char) >= page_size)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ align2 &= 7;
|
||||||
|
+ if ((align2 + len) * sizeof (char) >= page_size)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ s1 = (char *) (buf1) + align1;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < len; ++i)
|
||||||
|
+ s1[i] = 32 + 23 * i % (max_char - 32);
|
||||||
|
+ s1[len] = 0;
|
||||||
|
+ for (i = len + 1; (i + align1) * sizeof (char) < page_size && i < len + 64;
|
||||||
|
+ ++i)
|
||||||
|
+ s1[i] = 32 + 32 * i % (max_char - 32);
|
||||||
|
+
|
||||||
|
+ do_one_test (s1, len, n);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_page_tests (void)
|
||||||
|
+{
|
||||||
|
+ char *s1;
|
||||||
|
+ const size_t maxoffset = 64;
|
||||||
|
+
|
||||||
|
+ /* Put s1 at the maxoffset from the edge of buf1's last page. */
|
||||||
|
+ s1 = (char *) buf1 + BUF1PAGES * page_size / sizeof (char) - maxoffset;
|
||||||
|
+
|
||||||
|
+ memset (s1, 'a', maxoffset - 1);
|
||||||
|
+ s1[maxoffset - 1] = '\0';
|
||||||
|
+
|
||||||
|
+ /* Both strings are bounded to a page with read/write access and the next
|
||||||
|
+ page is protected with PROT_NONE (meaning that any access outside of the
|
||||||
|
+ page regions will trigger an invalid memory access).
|
||||||
|
+
|
||||||
|
+ The loop copies the string s1 for all possible offsets up to maxoffset
|
||||||
|
+ for both inputs with a size larger than s1 (so memory access outside the
|
||||||
|
+ expected memory regions might trigger invalid access). */
|
||||||
|
+
|
||||||
|
+ for (size_t off1 = 0; off1 < maxoffset; off1++)
|
||||||
|
+ for (size_t off2 = 0; off2 < maxoffset; off2++)
|
||||||
|
+ do_one_test (s1 + off1, maxoffset - off1 - 1,
|
||||||
|
+ maxoffset + (maxoffset - off2));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_random_tests (void)
|
||||||
|
+{
|
||||||
|
+ size_t i, j, n, align1, align2, len, size, mode;
|
||||||
|
+ char *p1 = (char *) (buf1 + page_size) - 512;
|
||||||
|
+ char *res;
|
||||||
|
+
|
||||||
|
+ for (n = 0; n < ITERATIONS; n++)
|
||||||
|
+ {
|
||||||
|
+ mode = random ();
|
||||||
|
+ if (mode & 1)
|
||||||
|
+ {
|
||||||
|
+ size = random () & 255;
|
||||||
|
+ align1 = 512 - size - (random () & 15);
|
||||||
|
+ if (mode & 2)
|
||||||
|
+ align2 = align1 - (random () & 24);
|
||||||
|
+ else
|
||||||
|
+ align2 = align1 - (random () & 31);
|
||||||
|
+ if (mode & 4)
|
||||||
|
+ {
|
||||||
|
+ j = align1;
|
||||||
|
+ align1 = align2;
|
||||||
|
+ align2 = j;
|
||||||
|
+ }
|
||||||
|
+ if (mode & 8)
|
||||||
|
+ len = size - (random () & 31);
|
||||||
|
+ else
|
||||||
|
+ len = 512;
|
||||||
|
+ if (len >= 512)
|
||||||
|
+ len = random () & 511;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ align1 = random () & 31;
|
||||||
|
+ if (mode & 2)
|
||||||
|
+ align2 = random () & 31;
|
||||||
|
+ else
|
||||||
|
+ align2 = align1 + (random () & 24);
|
||||||
|
+ len = random () & 511;
|
||||||
|
+ j = align1;
|
||||||
|
+ if (align2 > j)
|
||||||
|
+ j = align2;
|
||||||
|
+ if (mode & 4)
|
||||||
|
+ {
|
||||||
|
+ size = random () & 511;
|
||||||
|
+ if (size + j > 512)
|
||||||
|
+ size = 512 - j - (random () & 31);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ size = 512 - j;
|
||||||
|
+ if ((mode & 8) && len + j >= 512)
|
||||||
|
+ len = 512 - j - (random () & 7);
|
||||||
|
+ }
|
||||||
|
+ j = len + align1 + 64;
|
||||||
|
+ if (j > 512)
|
||||||
|
+ j = 512;
|
||||||
|
+ for (i = 0; i < j; i++)
|
||||||
|
+ {
|
||||||
|
+ if (i == len + align1)
|
||||||
|
+ p1[i] = 0;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ p1[i] = random () & CHAR_MAX;
|
||||||
|
+ if (i >= align1 && i < len + align1 && !p1[i])
|
||||||
|
+ p1[i] = (random () & 127) + 3;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ res = (char *) strndup ((char *) (p1 + align1), size);
|
||||||
|
+ j = len + 1;
|
||||||
|
+ if (size < j)
|
||||||
|
+ j = size;
|
||||||
|
+ TEST_COMPARE_BLOB (res, j, (char *) (p1 + align1), j);
|
||||||
|
+ free (res);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+test_main (void)
|
||||||
|
+{
|
||||||
|
+ size_t i;
|
||||||
|
+
|
||||||
|
+ test_init ();
|
||||||
|
+
|
||||||
|
+ printf ("%28s", "");
|
||||||
|
+ printf ("\t%s", "strndup");
|
||||||
|
+ putchar ('\n');
|
||||||
|
+
|
||||||
|
+ for (i = 1; i < 8; ++i)
|
||||||
|
+ {
|
||||||
|
+ do_test (i, i, 16, 16, 127);
|
||||||
|
+ do_test (i, i, 16, 16, CHAR_MAX);
|
||||||
|
+ do_test (i, 2 * i, 16, 16, 127);
|
||||||
|
+ do_test (2 * i, i, 16, 16, CHAR_MAX);
|
||||||
|
+ do_test (8 - i, 2 * i, 1 << i, 2 << i, 127);
|
||||||
|
+ do_test (2 * i, 8 - i, 2 << i, 1 << i, 127);
|
||||||
|
+ do_test (8 - i, 2 * i, 1 << i, 2 << i, CHAR_MAX);
|
||||||
|
+ do_test (2 * i, 8 - i, 2 << i, 1 << i, CHAR_MAX);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 1; i < 8; ++i)
|
||||||
|
+ {
|
||||||
|
+ do_test (0, 0, 4 << i, 8 << i, 127);
|
||||||
|
+ do_test (0, 0, 16 << i, 8 << i, 127);
|
||||||
|
+ do_test (8 - i, 2 * i, 4 << i, 8 << i, 127);
|
||||||
|
+ do_test (8 - i, 2 * i, 16 << i, 8 << i, 127);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ do_random_tests ();
|
||||||
|
+ do_page_tests ();
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
@ -0,0 +1,33 @@
|
|||||||
|
commit 0aa5b28a504c6f1f17b387d8147715d1496fff62
|
||||||
|
Author: Joe Simmons-Talbott <josimmon@redhat.com>
|
||||||
|
Date: Fri Apr 21 09:24:25 2023 -0400
|
||||||
|
|
||||||
|
wcsmbs: Add wcsdup() tests. (BZ #30266)
|
||||||
|
|
||||||
|
Enable wide character testcases for wcsdup().
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Conflicts:
|
||||||
|
wcsmbs/Makefile
|
||||||
|
(different test backport order)
|
||||||
|
|
||||||
|
|
||||||
|
diff -Nrup a/wcsmbs/Makefile b/wcsmbs/Makefile
|
||||||
|
--- a/wcsmbs/Makefile 2023-11-30 14:14:18.755010508 -0500
|
||||||
|
+++ b/wcsmbs/Makefile 2023-11-30 14:38:18.511131851 -0500
|
||||||
|
@@ -53,7 +53,8 @@ tests := tst-wcstof wcsmbs-tst1 tst-wcsn
|
||||||
|
tst-c16c32-1 wcsatcliff tst-wcstol-locale tst-wcstod-nan-locale \
|
||||||
|
tst-wcstod-round test-char-types tst-fgetwc-after-eof \
|
||||||
|
tst-wcstod-nan-sign tst-c16-surrogate tst-c32-state \
|
||||||
|
- $(addprefix test-,$(strop-tests)) tst-mbstowcs
|
||||||
|
+ $(addprefix test-,$(strop-tests)) tst-mbstowcs \
|
||||||
|
+ test-wcsdup
|
||||||
|
|
||||||
|
include ../Rules
|
||||||
|
|
||||||
|
diff -Nrup a/wcsmbs/test-wcsdup.c b/wcsmbs/test-wcsdup.c
|
||||||
|
--- a/wcsmbs/test-wcsdup.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/wcsmbs/test-wcsdup.c 2023-11-30 14:14:48.869138712 -0500
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+#define WIDE 1
|
||||||
|
+#include "../string/test-strdup.c"
|
@ -0,0 +1,26 @@
|
|||||||
|
commit 919b9bfaa969c9517fe86c753c001b96ee4ea840
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Wed Oct 5 14:33:14 2022 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.0
|
||||||
|
|
||||||
|
Linux 6.0 has no new syscalls. Update the version number in
|
||||||
|
syscall-names.list to reflect that it is still current for 6.0.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 028ad3107a..4a78258646 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.19.
|
||||||
|
-kernel 5.19
|
||||||
|
+# The list of system calls is current as of Linux 6.0.
|
||||||
|
+kernel 6.0
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
@ -0,0 +1,24 @@
|
|||||||
|
commit 5ab9b2c92411eb52f7b7a8e6074f0740d9bd727b
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Tue Dec 20 15:24:29 2022 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.1
|
||||||
|
|
||||||
|
Linux 6.1 has no new syscalls. Update the version number in
|
||||||
|
syscall-names.list to reflect that it is still current for 6.1.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 4a78258646..1274d9cd4a 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 6.0.
|
||||||
|
-kernel 6.0
|
||||||
|
+# The list of system calls is current as of Linux 6.1.
|
||||||
|
+kernel 6.1
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
@ -0,0 +1,26 @@
|
|||||||
|
commit f8e8effa2629c74769a3552aba33175746b710bb
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Thu Feb 23 22:53:17 2023 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.2
|
||||||
|
|
||||||
|
Linux 6.2 has no new syscalls. Update the version number in
|
||||||
|
syscall-names.list to reflect that it is still current for 6.2.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 822498d3e3..5d27b5279c 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 6.1.
|
||||||
|
-kernel 6.1
|
||||||
|
+# The list of system calls is current as of Linux 6.2.
|
||||||
|
+kernel 6.2
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
@ -0,0 +1,26 @@
|
|||||||
|
commit eeef96f56ce399f2c3fc1d93c0ba1dde34f3ae41
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Mon May 15 22:26:56 2023 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.3
|
||||||
|
|
||||||
|
Linux 6.3 has no new syscalls. Update the version number in
|
||||||
|
syscall-names.list to reflect that it is still current for 6.3.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 5d27b5279c..72fe1d5efe 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 6.2.
|
||||||
|
-kernel 6.2
|
||||||
|
+# The list of system calls is current as of Linux 6.3.
|
||||||
|
+kernel 6.3
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
@ -0,0 +1,83 @@
|
|||||||
|
commit 1a21693e16a3f3d10f41c486b97fbecb53dd2087
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Wed Jun 28 21:22:14 2023 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.4
|
||||||
|
|
||||||
|
Linux 6.4 adds the riscv_hwprobe syscall on riscv and enables
|
||||||
|
memfd_secret on s390. Update syscall-names.list and regenerate the
|
||||||
|
arch-syscall.h headers with build-many-glibcs.py update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
index 202520ee25..2416e041c8 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
@@ -198,6 +198,7 @@
|
||||||
|
#define __NR_request_key 218
|
||||||
|
#define __NR_restart_syscall 128
|
||||||
|
#define __NR_riscv_flush_icache 259
|
||||||
|
+#define __NR_riscv_hwprobe 258
|
||||||
|
#define __NR_rseq 293
|
||||||
|
#define __NR_rt_sigaction 134
|
||||||
|
#define __NR_rt_sigpending 136
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
index 4e65f337d4..a32bc82f60 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
@@ -205,6 +205,7 @@
|
||||||
|
#define __NR_request_key 218
|
||||||
|
#define __NR_restart_syscall 128
|
||||||
|
#define __NR_riscv_flush_icache 259
|
||||||
|
+#define __NR_riscv_hwprobe 258
|
||||||
|
#define __NR_rseq 293
|
||||||
|
#define __NR_rt_sigaction 134
|
||||||
|
#define __NR_rt_sigpending 136
|
||||||
|
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 57025107e8..2288f20e45 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
@@ -178,6 +178,7 @@
|
||||||
|
#define __NR_mbind 268
|
||||||
|
#define __NR_membarrier 356
|
||||||
|
#define __NR_memfd_create 350
|
||||||
|
+#define __NR_memfd_secret 447
|
||||||
|
#define __NR_migrate_pages 287
|
||||||
|
#define __NR_mincore 218
|
||||||
|
#define __NR_mkdir 39
|
||||||
|
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 72e19c6d56..05e6d8428e 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
@@ -152,6 +152,7 @@
|
||||||
|
#define __NR_mbind 268
|
||||||
|
#define __NR_membarrier 356
|
||||||
|
#define __NR_memfd_create 350
|
||||||
|
+#define __NR_memfd_secret 447
|
||||||
|
#define __NR_migrate_pages 287
|
||||||
|
#define __NR_mincore 218
|
||||||
|
#define __NR_mkdir 39
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 72fe1d5efe..5b69106434 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 6.3.
|
||||||
|
-kernel 6.3
|
||||||
|
+# The list of system calls is current as of Linux 6.4.
|
||||||
|
+kernel 6.4
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -477,6 +477,7 @@ renameat2
|
||||||
|
request_key
|
||||||
|
restart_syscall
|
||||||
|
riscv_flush_icache
|
||||||
|
+riscv_hwprobe
|
||||||
|
rmdir
|
||||||
|
rseq
|
||||||
|
rt_sigaction
|
@ -0,0 +1,338 @@
|
|||||||
|
commit 72511f539cc34681ec61c6a0dc2fe6d684760ffe
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Tue Sep 12 14:08:53 2023 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.5
|
||||||
|
|
||||||
|
Linux 6.5 has one new syscall, cachestat, and also enables the
|
||||||
|
cacheflush syscall for hppa. Update syscall-names.list and regenerate
|
||||||
|
the arch-syscall.h headers with build-many-glibcs.py update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Conflicts: Removed loongarch, or1k
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
index 4fcb6da80a..8f21ee66a0 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
@@ -7,6 +7,7 @@
|
||||||
|
#define __NR_bind 200
|
||||||
|
#define __NR_bpf 280
|
||||||
|
#define __NR_brk 214
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 90
|
||||||
|
#define __NR_capset 91
|
||||||
|
#define __NR_chdir 49
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
index 0cf74c1a96..c5802a5fec 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#define __NR_bind 104
|
||||||
|
#define __NR_bpf 515
|
||||||
|
#define __NR_brk 17
|
||||||
|
+#define __NR_cachestat 561
|
||||||
|
#define __NR_capget 368
|
||||||
|
#define __NR_capset 369
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
index c1207aaa12..f23f9e1154 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#define __NR_bpf 280
|
||||||
|
#define __NR_brk 214
|
||||||
|
#define __NR_cacheflush 244
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 90
|
||||||
|
#define __NR_capset 91
|
||||||
|
#define __NR_chdir 49
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
index e7ba04c106..7edf574899 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#define __NR_bpf 386
|
||||||
|
#define __NR_brk 45
|
||||||
|
#define __NR_cacheflush 983042
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 184
|
||||||
|
#define __NR_capset 185
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
index dc9383758e..d74a06e063 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
@@ -8,6 +8,7 @@
|
||||||
|
#define __NR_bpf 280
|
||||||
|
#define __NR_brk 214
|
||||||
|
#define __NR_cacheflush 245
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 90
|
||||||
|
#define __NR_capset 91
|
||||||
|
#define __NR_chdir 49
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
index 767f1287a3..5568b94cd3 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
@@ -13,6 +13,8 @@
|
||||||
|
#define __NR_bind 22
|
||||||
|
#define __NR_bpf 341
|
||||||
|
#define __NR_brk 45
|
||||||
|
+#define __NR_cacheflush 356
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 106
|
||||||
|
#define __NR_capset 107
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
index 1998f0d76a..3af21a15cb 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#define __NR_bpf 357
|
||||||
|
#define __NR_break 17
|
||||||
|
#define __NR_brk 45
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 184
|
||||||
|
#define __NR_capset 185
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
|
||||||
|
index b2eab1b93d..39b270e642 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#define __NR_bind 1191
|
||||||
|
#define __NR_bpf 1341
|
||||||
|
#define __NR_brk 1060
|
||||||
|
+#define __NR_cachestat 1475
|
||||||
|
#define __NR_capget 1185
|
||||||
|
#define __NR_capset 1186
|
||||||
|
#define __NR_chdir 1034
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
index 5fc3723772..315e49cd33 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#define __NR_bpf 354
|
||||||
|
#define __NR_brk 45
|
||||||
|
#define __NR_cacheflush 123
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 184
|
||||||
|
#define __NR_capset 185
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
index b6e9b007e4..54af12780c 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#define __NR_bpf 387
|
||||||
|
#define __NR_break 17
|
||||||
|
#define __NR_brk 45
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 184
|
||||||
|
#define __NR_capset 185
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
index b3a3871f8a..a2aa1ffa1b 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
#define __NR_brk 4045
|
||||||
|
#define __NR_cachectl 4148
|
||||||
|
#define __NR_cacheflush 4147
|
||||||
|
+#define __NR_cachestat 4451
|
||||||
|
#define __NR_capget 4204
|
||||||
|
#define __NR_capset 4205
|
||||||
|
#define __NR_chdir 4012
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||||
|
index b462182723..5bec858040 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#define __NR_brk 6012
|
||||||
|
#define __NR_cachectl 6198
|
||||||
|
#define __NR_cacheflush 6197
|
||||||
|
+#define __NR_cachestat 6451
|
||||||
|
#define __NR_capget 6123
|
||||||
|
#define __NR_capset 6124
|
||||||
|
#define __NR_chdir 6078
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||||
|
index a9d6b94572..0166371ee2 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#define __NR_brk 5012
|
||||||
|
#define __NR_cachectl 5198
|
||||||
|
#define __NR_cacheflush 5197
|
||||||
|
+#define __NR_cachestat 5451
|
||||||
|
#define __NR_capget 5123
|
||||||
|
#define __NR_capset 5124
|
||||||
|
#define __NR_chdir 5078
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
index 809a219ef3..29a4cfa988 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
@@ -8,6 +8,7 @@
|
||||||
|
#define __NR_bpf 280
|
||||||
|
#define __NR_brk 214
|
||||||
|
#define __NR_cacheflush 244
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 90
|
||||||
|
#define __NR_capset 91
|
||||||
|
#define __NR_chdir 49
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
index 627831ebae..3a212a0269 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#define __NR_bpf 361
|
||||||
|
#define __NR_break 17
|
||||||
|
#define __NR_brk 45
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 183
|
||||||
|
#define __NR_capset 184
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
index bae597199d..1038ead227 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#define __NR_bpf 361
|
||||||
|
#define __NR_break 17
|
||||||
|
#define __NR_brk 45
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 183
|
||||||
|
#define __NR_capset 184
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
index 2416e041c8..57b043ffb5 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
#define __NR_bind 200
|
||||||
|
#define __NR_bpf 280
|
||||||
|
#define __NR_brk 214
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 90
|
||||||
|
#define __NR_capset 91
|
||||||
|
#define __NR_chdir 49
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
index a32bc82f60..1041a0f8c9 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
@@ -7,6 +7,7 @@
|
||||||
|
#define __NR_bind 200
|
||||||
|
#define __NR_bpf 280
|
||||||
|
#define __NR_brk 214
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 90
|
||||||
|
#define __NR_capset 91
|
||||||
|
#define __NR_chdir 49
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
index 2288f20e45..70d4c6782e 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
@@ -13,6 +13,7 @@
|
||||||
|
#define __NR_bind 361
|
||||||
|
#define __NR_bpf 351
|
||||||
|
#define __NR_brk 45
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 184
|
||||||
|
#define __NR_capset 185
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
index 05e6d8428e..65a8a9e316 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#define __NR_bind 361
|
||||||
|
#define __NR_bpf 351
|
||||||
|
#define __NR_brk 45
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 184
|
||||||
|
#define __NR_capset 185
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
index d52b522d9c..94aad0f119 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#define __NR_bpf 375
|
||||||
|
#define __NR_brk 45
|
||||||
|
#define __NR_cacheflush 123
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 184
|
||||||
|
#define __NR_capset 185
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
index d3f4d8aa3e..d630306c75 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#define __NR_bind 353
|
||||||
|
#define __NR_bpf 349
|
||||||
|
#define __NR_brk 17
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 21
|
||||||
|
#define __NR_capset 22
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
index 2cc03d7a24..930f29b4d2 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#define __NR_bind 353
|
||||||
|
#define __NR_bpf 349
|
||||||
|
#define __NR_brk 17
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 21
|
||||||
|
#define __NR_capset 22
|
||||||
|
#define __NR_chdir 12
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 5b69106434..cf6f70ecd9 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 6.4.
|
||||||
|
-kernel 6.4
|
||||||
|
+# The list of system calls is current as of Linux 6.5.
|
||||||
|
+kernel 6.5
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -58,6 +58,7 @@ breakpoint
|
||||||
|
brk
|
||||||
|
cachectl
|
||||||
|
cacheflush
|
||||||
|
+cachestat
|
||||||
|
capget
|
||||||
|
capset
|
||||||
|
chdir
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
index b4ab892ec1..58646cf0bd 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#define __NR_bind 49
|
||||||
|
#define __NR_bpf 321
|
||||||
|
#define __NR_brk 12
|
||||||
|
+#define __NR_cachestat 451
|
||||||
|
#define __NR_capget 125
|
||||||
|
#define __NR_capset 126
|
||||||
|
#define __NR_chdir 80
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
index 772559c87b..604bcdfa5b 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#define __NR_bind 1073741873
|
||||||
|
#define __NR_bpf 1073742145
|
||||||
|
#define __NR_brk 1073741836
|
||||||
|
+#define __NR_cachestat 1073742275
|
||||||
|
#define __NR_capget 1073741949
|
||||||
|
#define __NR_capset 1073741950
|
||||||
|
#define __NR_chdir 1073741904
|
@ -0,0 +1,350 @@
|
|||||||
|
commit 582383b37d95b133c1ee6855ffaa2b1f5cb3d3b8
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Oct 31 13:32:33 2023 -0300
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.6
|
||||||
|
|
||||||
|
Linux 6.6 has one new syscall for all architectures, fchmodat2, and
|
||||||
|
the map_shadow_stack on x86_64.
|
||||||
|
|
||||||
|
Conflicts: Removed loongarch, or1k
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
index 8f21ee66a0..746991aa2f 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
@@ -44,6 +44,7 @@
|
||||||
|
#define __NR_fchdir 50
|
||||||
|
#define __NR_fchmod 52
|
||||||
|
#define __NR_fchmodat 53
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 55
|
||||||
|
#define __NR_fchownat 54
|
||||||
|
#define __NR_fcntl 25
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
index c5802a5fec..32efe51267 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
@@ -56,6 +56,7 @@
|
||||||
|
#define __NR_fchdir 13
|
||||||
|
#define __NR_fchmod 124
|
||||||
|
#define __NR_fchmodat 461
|
||||||
|
+#define __NR_fchmodat2 562
|
||||||
|
#define __NR_fchown 123
|
||||||
|
#define __NR_fchownat 453
|
||||||
|
#define __NR_fcntl 92
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
index f23f9e1154..1d2879e877 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
@@ -48,6 +48,7 @@
|
||||||
|
#define __NR_fchdir 50
|
||||||
|
#define __NR_fchmod 52
|
||||||
|
#define __NR_fchmodat 53
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 55
|
||||||
|
#define __NR_fchownat 54
|
||||||
|
#define __NR_fcntl64 25
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
index 7edf574899..6711981e78 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
@@ -64,6 +64,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 333
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 95
|
||||||
|
#define __NR_fchown32 207
|
||||||
|
#define __NR_fchownat 325
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
index d74a06e063..92d9a703ea 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
@@ -50,6 +50,7 @@
|
||||||
|
#define __NR_fchdir 50
|
||||||
|
#define __NR_fchmod 52
|
||||||
|
#define __NR_fchmodat 53
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 55
|
||||||
|
#define __NR_fchownat 54
|
||||||
|
#define __NR_fcntl64 25
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
index 5568b94cd3..fbac124b70 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
@@ -63,6 +63,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 286
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 95
|
||||||
|
#define __NR_fchownat 278
|
||||||
|
#define __NR_fcntl 55
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
index 3af21a15cb..8961788a96 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
@@ -67,6 +67,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 306
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 95
|
||||||
|
#define __NR_fchown32 207
|
||||||
|
#define __NR_fchownat 298
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
|
||||||
|
index 39b270e642..1ef762d693 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
|
||||||
|
@@ -55,6 +55,7 @@
|
||||||
|
#define __NR_fchdir 1035
|
||||||
|
#define __NR_fchmod 1099
|
||||||
|
#define __NR_fchmodat 1292
|
||||||
|
+#define __NR_fchmodat2 1476
|
||||||
|
#define __NR_fchown 1100
|
||||||
|
#define __NR_fchownat 1284
|
||||||
|
#define __NR_fcntl 1066
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
index 315e49cd33..2053d5d392 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
@@ -67,6 +67,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 299
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 95
|
||||||
|
#define __NR_fchown32 207
|
||||||
|
#define __NR_fchownat 291
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
index 54af12780c..6865b1693c 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
@@ -67,6 +67,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 306
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 95
|
||||||
|
#define __NR_fchown32 207
|
||||||
|
#define __NR_fchownat 298
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
index a2aa1ffa1b..b13ace8e1c 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
@@ -67,6 +67,7 @@
|
||||||
|
#define __NR_fchdir 4133
|
||||||
|
#define __NR_fchmod 4094
|
||||||
|
#define __NR_fchmodat 4299
|
||||||
|
+#define __NR_fchmodat2 4452
|
||||||
|
#define __NR_fchown 4095
|
||||||
|
#define __NR_fchownat 4291
|
||||||
|
#define __NR_fcntl 4055
|
||||||
|
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 5bec858040..b7a7c0dfa7 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||||
|
@@ -64,6 +64,7 @@
|
||||||
|
#define __NR_fchdir 6079
|
||||||
|
#define __NR_fchmod 6089
|
||||||
|
#define __NR_fchmodat 6262
|
||||||
|
+#define __NR_fchmodat2 6452
|
||||||
|
#define __NR_fchown 6091
|
||||||
|
#define __NR_fchownat 6254
|
||||||
|
#define __NR_fcntl 6070
|
||||||
|
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 0166371ee2..e5d7f91f48 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||||
|
@@ -59,6 +59,7 @@
|
||||||
|
#define __NR_fchdir 5079
|
||||||
|
#define __NR_fchmod 5089
|
||||||
|
#define __NR_fchmodat 5258
|
||||||
|
+#define __NR_fchmodat2 5452
|
||||||
|
#define __NR_fchown 5091
|
||||||
|
#define __NR_fchownat 5250
|
||||||
|
#define __NR_fcntl 5070
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
index 29a4cfa988..89950cc33a 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
@@ -49,6 +49,7 @@
|
||||||
|
#define __NR_fchdir 50
|
||||||
|
#define __NR_fchmod 52
|
||||||
|
#define __NR_fchmodat 53
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 55
|
||||||
|
#define __NR_fchownat 54
|
||||||
|
#define __NR_fcntl64 25
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
index 3a212a0269..64683bcb76 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
@@ -66,6 +66,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 297
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 95
|
||||||
|
#define __NR_fchownat 289
|
||||||
|
#define __NR_fcntl 55
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
index 1038ead227..af1bbf32e8 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
@@ -60,6 +60,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 297
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 95
|
||||||
|
#define __NR_fchownat 289
|
||||||
|
#define __NR_fcntl 55
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
index 57b043ffb5..56e3088cbf 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
@@ -43,6 +43,7 @@
|
||||||
|
#define __NR_fchdir 50
|
||||||
|
#define __NR_fchmod 52
|
||||||
|
#define __NR_fchmodat 53
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 55
|
||||||
|
#define __NR_fchownat 54
|
||||||
|
#define __NR_fcntl64 25
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
index 1041a0f8c9..508161b47a 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
@@ -44,6 +44,7 @@
|
||||||
|
#define __NR_fchdir 50
|
||||||
|
#define __NR_fchmod 52
|
||||||
|
#define __NR_fchmodat 53
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 55
|
||||||
|
#define __NR_fchownat 54
|
||||||
|
#define __NR_fcntl 25
|
||||||
|
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 70d4c6782e..1498ebf42e 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
@@ -65,6 +65,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 299
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 95
|
||||||
|
#define __NR_fchown32 207
|
||||||
|
#define __NR_fchownat 291
|
||||||
|
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 65a8a9e316..624d71b56d 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
@@ -56,6 +56,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 299
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 207
|
||||||
|
#define __NR_fchownat 291
|
||||||
|
#define __NR_fcntl 55
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
index 94aad0f119..37211f5f8c 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
@@ -64,6 +64,7 @@
|
||||||
|
#define __NR_fchdir 133
|
||||||
|
#define __NR_fchmod 94
|
||||||
|
#define __NR_fchmodat 306
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 95
|
||||||
|
#define __NR_fchown32 207
|
||||||
|
#define __NR_fchownat 298
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
index d630306c75..8093abcc9c 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
@@ -66,6 +66,7 @@
|
||||||
|
#define __NR_fchdir 176
|
||||||
|
#define __NR_fchmod 124
|
||||||
|
#define __NR_fchmodat 295
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 123
|
||||||
|
#define __NR_fchown32 32
|
||||||
|
#define __NR_fchownat 287
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
index 930f29b4d2..d25ccfb571 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
@@ -60,6 +60,7 @@
|
||||||
|
#define __NR_fchdir 176
|
||||||
|
#define __NR_fchmod 124
|
||||||
|
#define __NR_fchmodat 295
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 123
|
||||||
|
#define __NR_fchownat 287
|
||||||
|
#define __NR_fcntl 92
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index cf6f70ecd9..c3627fcd7f 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 6.5.
|
||||||
|
-kernel 6.5
|
||||||
|
+# The list of system calls is current as of Linux 6.6.
|
||||||
|
+kernel 6.6
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -117,6 +117,7 @@ fanotify_mark
|
||||||
|
fchdir
|
||||||
|
fchmod
|
||||||
|
fchmodat
|
||||||
|
+fchmodat2
|
||||||
|
fchown
|
||||||
|
fchown32
|
||||||
|
fchownat
|
||||||
|
@@ -246,6 +247,7 @@ lsetxattr
|
||||||
|
lstat
|
||||||
|
lstat64
|
||||||
|
madvise
|
||||||
|
+map_shadow_stack
|
||||||
|
mbind
|
||||||
|
membarrier
|
||||||
|
memfd_create
|
||||||
|
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 58646cf0bd..5e4c9e901c 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
@@ -59,6 +59,7 @@
|
||||||
|
#define __NR_fchdir 81
|
||||||
|
#define __NR_fchmod 91
|
||||||
|
#define __NR_fchmodat 268
|
||||||
|
+#define __NR_fchmodat2 452
|
||||||
|
#define __NR_fchown 93
|
||||||
|
#define __NR_fchownat 260
|
||||||
|
#define __NR_fcntl 72
|
||||||
|
@@ -153,6 +154,7 @@
|
||||||
|
#define __NR_lsetxattr 189
|
||||||
|
#define __NR_lstat 6
|
||||||
|
#define __NR_madvise 28
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 237
|
||||||
|
#define __NR_membarrier 324
|
||||||
|
#define __NR_memfd_create 319
|
||||||
|
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 604bcdfa5b..dd5e196272 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
@@ -55,6 +55,7 @@
|
||||||
|
#define __NR_fchdir 1073741905
|
||||||
|
#define __NR_fchmod 1073741915
|
||||||
|
#define __NR_fchmodat 1073742092
|
||||||
|
+#define __NR_fchmodat2 1073742276
|
||||||
|
#define __NR_fchown 1073741917
|
||||||
|
#define __NR_fchownat 1073742084
|
||||||
|
#define __NR_fcntl 1073741896
|
@ -0,0 +1,16 @@
|
|||||||
|
Downstream-only patch to refer to /run instead of the legacy /var/run
|
||||||
|
directory in the downstream nscd systemd socket file.
|
||||||
|
|
||||||
|
diff --git a/nscd/nscd.socket b/nscd/nscd.socket
|
||||||
|
index 7e512d5339fa1136..52a67608c7c55475 100644
|
||||||
|
--- a/nscd/nscd.socket
|
||||||
|
+++ b/nscd/nscd.socket
|
||||||
|
@@ -2,7 +2,7 @@
|
||||||
|
Description=Name Service Cache Daemon Socket
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
-ListenDatagram=/var/run/nscd/socket
|
||||||
|
+ListenDatagram=/run/nscd/socket
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=sockets.target
|
@ -0,0 +1,211 @@
|
|||||||
|
commit 06890c7ba553e82393413c59bb3131db5815a337
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue Jul 27 22:49:53 2021 +0530
|
||||||
|
|
||||||
|
gaiconf_init: Refactor some bits for readability
|
||||||
|
|
||||||
|
Split out line processing for `label`, `precedence` and `scopev4` into
|
||||||
|
separate functions instead of the gotos.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index d6046a707f1d742a..3bf9a8bae16a5b02 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -1858,6 +1858,66 @@ scopecmp (const void *p1, const void *p2)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool
|
||||||
|
+add_prefixlist (struct prefixlist **listp, size_t *lenp, bool *nullbitsp,
|
||||||
|
+ char *val1, char *val2, char **pos)
|
||||||
|
+{
|
||||||
|
+ struct in6_addr prefix;
|
||||||
|
+ unsigned long int bits;
|
||||||
|
+ unsigned long int val;
|
||||||
|
+ char *endp;
|
||||||
|
+
|
||||||
|
+ bits = 128;
|
||||||
|
+ __set_errno (0);
|
||||||
|
+ char *cp = strchr (val1, '/');
|
||||||
|
+ if (cp != NULL)
|
||||||
|
+ *cp++ = '\0';
|
||||||
|
+ *pos = cp;
|
||||||
|
+ if (inet_pton (AF_INET6, val1, &prefix)
|
||||||
|
+ && (cp == NULL
|
||||||
|
+ || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
||||||
|
+ || errno != ERANGE)
|
||||||
|
+ && *endp == '\0'
|
||||||
|
+ && bits <= 128
|
||||||
|
+ && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
||||||
|
+ || errno != ERANGE)
|
||||||
|
+ && *endp == '\0'
|
||||||
|
+ && val <= INT_MAX)
|
||||||
|
+ {
|
||||||
|
+ struct prefixlist *newp = malloc (sizeof (*newp));
|
||||||
|
+ if (newp == NULL)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
|
||||||
|
+ newp->entry.bits = bits;
|
||||||
|
+ newp->entry.val = val;
|
||||||
|
+ newp->next = *listp;
|
||||||
|
+ *listp = newp;
|
||||||
|
+ ++*lenp;
|
||||||
|
+ *nullbitsp |= bits == 0;
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool
|
||||||
|
+add_scopelist (struct scopelist **listp, size_t *lenp, bool *nullbitsp,
|
||||||
|
+ const struct in6_addr *prefixp, unsigned long int bits,
|
||||||
|
+ unsigned long int val)
|
||||||
|
+{
|
||||||
|
+ struct scopelist *newp = malloc (sizeof (*newp));
|
||||||
|
+ if (newp == NULL)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ newp->entry.netmask = htonl (bits != 96 ? (0xffffffff << (128 - bits)) : 0);
|
||||||
|
+ newp->entry.addr32 = (prefixp->s6_addr32[3] & newp->entry.netmask);
|
||||||
|
+ newp->entry.scope = val;
|
||||||
|
+ newp->next = *listp;
|
||||||
|
+ *listp = newp;
|
||||||
|
+ ++*lenp;
|
||||||
|
+ *nullbitsp |= bits == 96;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gaiconf_init (void)
|
||||||
|
@@ -1933,55 +1993,17 @@ gaiconf_init (void)
|
||||||
|
/* Ignore the rest of the line. */
|
||||||
|
*cp = '\0';
|
||||||
|
|
||||||
|
- struct prefixlist **listp;
|
||||||
|
- size_t *lenp;
|
||||||
|
- bool *nullbitsp;
|
||||||
|
switch (cmdlen)
|
||||||
|
{
|
||||||
|
case 5:
|
||||||
|
if (strcmp (cmd, "label") == 0)
|
||||||
|
{
|
||||||
|
- struct in6_addr prefix;
|
||||||
|
- unsigned long int bits;
|
||||||
|
- unsigned long int val;
|
||||||
|
- char *endp;
|
||||||
|
-
|
||||||
|
- listp = &labellist;
|
||||||
|
- lenp = &nlabellist;
|
||||||
|
- nullbitsp = &labellist_nullbits;
|
||||||
|
-
|
||||||
|
- new_elem:
|
||||||
|
- bits = 128;
|
||||||
|
- __set_errno (0);
|
||||||
|
- cp = strchr (val1, '/');
|
||||||
|
- if (cp != NULL)
|
||||||
|
- *cp++ = '\0';
|
||||||
|
- if (inet_pton (AF_INET6, val1, &prefix)
|
||||||
|
- && (cp == NULL
|
||||||
|
- || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
||||||
|
- || errno != ERANGE)
|
||||||
|
- && *endp == '\0'
|
||||||
|
- && bits <= 128
|
||||||
|
- && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
||||||
|
- || errno != ERANGE)
|
||||||
|
- && *endp == '\0'
|
||||||
|
- && val <= INT_MAX)
|
||||||
|
+ if (!add_prefixlist (&labellist, &nlabellist,
|
||||||
|
+ &labellist_nullbits, val1, val2, &cp))
|
||||||
|
{
|
||||||
|
- struct prefixlist *newp = malloc (sizeof (*newp));
|
||||||
|
- if (newp == NULL)
|
||||||
|
- {
|
||||||
|
- free (line);
|
||||||
|
- fclose (fp);
|
||||||
|
- goto no_file;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
|
||||||
|
- newp->entry.bits = bits;
|
||||||
|
- newp->entry.val = val;
|
||||||
|
- newp->next = *listp;
|
||||||
|
- *listp = newp;
|
||||||
|
- ++*lenp;
|
||||||
|
- *nullbitsp |= bits == 0;
|
||||||
|
+ free (line);
|
||||||
|
+ fclose (fp);
|
||||||
|
+ goto no_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
@@ -2023,27 +2045,14 @@ gaiconf_init (void)
|
||||||
|
&& *endp == '\0'
|
||||||
|
&& val <= INT_MAX)
|
||||||
|
{
|
||||||
|
- struct scopelist *newp;
|
||||||
|
- new_scope:
|
||||||
|
- newp = malloc (sizeof (*newp));
|
||||||
|
- if (newp == NULL)
|
||||||
|
+ if (!add_scopelist (&scopelist, &nscopelist,
|
||||||
|
+ &scopelist_nullbits, &prefix,
|
||||||
|
+ bits, val))
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
fclose (fp);
|
||||||
|
goto no_file;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- newp->entry.netmask = htonl (bits != 96
|
||||||
|
- ? (0xffffffff
|
||||||
|
- << (128 - bits))
|
||||||
|
- : 0);
|
||||||
|
- newp->entry.addr32 = (prefix.s6_addr32[3]
|
||||||
|
- & newp->entry.netmask);
|
||||||
|
- newp->entry.scope = val;
|
||||||
|
- newp->next = scopelist;
|
||||||
|
- scopelist = newp;
|
||||||
|
- ++nscopelist;
|
||||||
|
- scopelist_nullbits |= bits == 96;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
|
||||||
|
@@ -2057,8 +2066,14 @@ gaiconf_init (void)
|
||||||
|
&& *endp == '\0'
|
||||||
|
&& val <= INT_MAX)
|
||||||
|
{
|
||||||
|
- bits += 96;
|
||||||
|
- goto new_scope;
|
||||||
|
+ if (!add_scopelist (&scopelist, &nscopelist,
|
||||||
|
+ &scopelist_nullbits, &prefix,
|
||||||
|
+ bits + 96, val))
|
||||||
|
+ {
|
||||||
|
+ free (line);
|
||||||
|
+ fclose (fp);
|
||||||
|
+ goto no_file;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
@@ -2066,10 +2081,14 @@ gaiconf_init (void)
|
||||||
|
case 10:
|
||||||
|
if (strcmp (cmd, "precedence") == 0)
|
||||||
|
{
|
||||||
|
- listp = &precedencelist;
|
||||||
|
- lenp = &nprecedencelist;
|
||||||
|
- nullbitsp = &precedencelist_nullbits;
|
||||||
|
- goto new_elem;
|
||||||
|
+ if (!add_prefixlist (&precedencelist, &nprecedencelist,
|
||||||
|
+ &precedencelist_nullbits, val1, val2,
|
||||||
|
+ &cp))
|
||||||
|
+ {
|
||||||
|
+ free (line);
|
||||||
|
+ fclose (fp);
|
||||||
|
+ goto no_file;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
@ -0,0 +1,584 @@
|
|||||||
|
commit bc0d18d873abf2cda6842ad8bb4df2a31dc0fbac
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue Aug 3 21:29:23 2021 +0530
|
||||||
|
|
||||||
|
gai_init: Avoid jumping from if condition to its else counterpart
|
||||||
|
|
||||||
|
Clean up another antipattern where code flows from an if condition to
|
||||||
|
its else counterpart with a goto.
|
||||||
|
|
||||||
|
Most of the change in this patch is whitespace-only; a `git diff -b`
|
||||||
|
ought to show the actual logic changes.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 3bf9a8bae16a5b02..1635a09837351068 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -1933,142 +1933,122 @@ gaiconf_init (void)
|
||||||
|
bool scopelist_nullbits = false;
|
||||||
|
|
||||||
|
FILE *fp = fopen (GAICONF_FNAME, "rce");
|
||||||
|
- if (fp != NULL)
|
||||||
|
+ if (fp == NULL)
|
||||||
|
+ goto no_file;
|
||||||
|
+
|
||||||
|
+ struct __stat64_t64 st;
|
||||||
|
+ if (__fstat64_time64 (fileno (fp), &st) != 0)
|
||||||
|
{
|
||||||
|
- struct __stat64_t64 st;
|
||||||
|
- if (__fstat64_time64 (fileno (fp), &st) != 0)
|
||||||
|
- {
|
||||||
|
- fclose (fp);
|
||||||
|
- goto no_file;
|
||||||
|
- }
|
||||||
|
+ fclose (fp);
|
||||||
|
+ goto no_file;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- char *line = NULL;
|
||||||
|
- size_t linelen = 0;
|
||||||
|
+ char *line = NULL;
|
||||||
|
+ size_t linelen = 0;
|
||||||
|
|
||||||
|
- __fsetlocking (fp, FSETLOCKING_BYCALLER);
|
||||||
|
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
|
||||||
|
|
||||||
|
- while (!feof_unlocked (fp))
|
||||||
|
- {
|
||||||
|
- ssize_t n = __getline (&line, &linelen, fp);
|
||||||
|
- if (n <= 0)
|
||||||
|
- break;
|
||||||
|
+ while (!feof_unlocked (fp))
|
||||||
|
+ {
|
||||||
|
+ ssize_t n = __getline (&line, &linelen, fp);
|
||||||
|
+ if (n <= 0)
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- /* Handle comments. No escaping possible so this is easy. */
|
||||||
|
- char *cp = strchr (line, '#');
|
||||||
|
- if (cp != NULL)
|
||||||
|
- *cp = '\0';
|
||||||
|
+ /* Handle comments. No escaping possible so this is easy. */
|
||||||
|
+ char *cp = strchr (line, '#');
|
||||||
|
+ if (cp != NULL)
|
||||||
|
+ *cp = '\0';
|
||||||
|
|
||||||
|
- cp = line;
|
||||||
|
- while (isspace (*cp))
|
||||||
|
- ++cp;
|
||||||
|
+ cp = line;
|
||||||
|
+ while (isspace (*cp))
|
||||||
|
+ ++cp;
|
||||||
|
|
||||||
|
- char *cmd = cp;
|
||||||
|
- while (*cp != '\0' && !isspace (*cp))
|
||||||
|
- ++cp;
|
||||||
|
- size_t cmdlen = cp - cmd;
|
||||||
|
+ char *cmd = cp;
|
||||||
|
+ while (*cp != '\0' && !isspace (*cp))
|
||||||
|
+ ++cp;
|
||||||
|
+ size_t cmdlen = cp - cmd;
|
||||||
|
|
||||||
|
- if (*cp != '\0')
|
||||||
|
- *cp++ = '\0';
|
||||||
|
- while (isspace (*cp))
|
||||||
|
- ++cp;
|
||||||
|
+ if (*cp != '\0')
|
||||||
|
+ *cp++ = '\0';
|
||||||
|
+ while (isspace (*cp))
|
||||||
|
+ ++cp;
|
||||||
|
|
||||||
|
- char *val1 = cp;
|
||||||
|
- while (*cp != '\0' && !isspace (*cp))
|
||||||
|
- ++cp;
|
||||||
|
- size_t val1len = cp - cmd;
|
||||||
|
+ char *val1 = cp;
|
||||||
|
+ while (*cp != '\0' && !isspace (*cp))
|
||||||
|
+ ++cp;
|
||||||
|
+ size_t val1len = cp - cmd;
|
||||||
|
|
||||||
|
- /* We always need at least two values. */
|
||||||
|
- if (val1len == 0)
|
||||||
|
- continue;
|
||||||
|
+ /* We always need at least two values. */
|
||||||
|
+ if (val1len == 0)
|
||||||
|
+ continue;
|
||||||
|
|
||||||
|
- if (*cp != '\0')
|
||||||
|
- *cp++ = '\0';
|
||||||
|
- while (isspace (*cp))
|
||||||
|
- ++cp;
|
||||||
|
+ if (*cp != '\0')
|
||||||
|
+ *cp++ = '\0';
|
||||||
|
+ while (isspace (*cp))
|
||||||
|
+ ++cp;
|
||||||
|
|
||||||
|
- char *val2 = cp;
|
||||||
|
- while (*cp != '\0' && !isspace (*cp))
|
||||||
|
- ++cp;
|
||||||
|
+ char *val2 = cp;
|
||||||
|
+ while (*cp != '\0' && !isspace (*cp))
|
||||||
|
+ ++cp;
|
||||||
|
|
||||||
|
- /* Ignore the rest of the line. */
|
||||||
|
- *cp = '\0';
|
||||||
|
+ /* Ignore the rest of the line. */
|
||||||
|
+ *cp = '\0';
|
||||||
|
|
||||||
|
- switch (cmdlen)
|
||||||
|
+ switch (cmdlen)
|
||||||
|
+ {
|
||||||
|
+ case 5:
|
||||||
|
+ if (strcmp (cmd, "label") == 0)
|
||||||
|
{
|
||||||
|
- case 5:
|
||||||
|
- if (strcmp (cmd, "label") == 0)
|
||||||
|
+ if (!add_prefixlist (&labellist, &nlabellist,
|
||||||
|
+ &labellist_nullbits, val1, val2, &cp))
|
||||||
|
{
|
||||||
|
- if (!add_prefixlist (&labellist, &nlabellist,
|
||||||
|
- &labellist_nullbits, val1, val2, &cp))
|
||||||
|
- {
|
||||||
|
- free (line);
|
||||||
|
- fclose (fp);
|
||||||
|
- goto no_file;
|
||||||
|
- }
|
||||||
|
+ free (line);
|
||||||
|
+ fclose (fp);
|
||||||
|
+ goto no_file;
|
||||||
|
}
|
||||||
|
- break;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- case 6:
|
||||||
|
- if (strcmp (cmd, "reload") == 0)
|
||||||
|
- {
|
||||||
|
- gaiconf_reload_flag = strcmp (val1, "yes") == 0;
|
||||||
|
- if (gaiconf_reload_flag)
|
||||||
|
- gaiconf_reload_flag_ever_set = 1;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
+ case 6:
|
||||||
|
+ if (strcmp (cmd, "reload") == 0)
|
||||||
|
+ {
|
||||||
|
+ gaiconf_reload_flag = strcmp (val1, "yes") == 0;
|
||||||
|
+ if (gaiconf_reload_flag)
|
||||||
|
+ gaiconf_reload_flag_ever_set = 1;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- case 7:
|
||||||
|
- if (strcmp (cmd, "scopev4") == 0)
|
||||||
|
+ case 7:
|
||||||
|
+ if (strcmp (cmd, "scopev4") == 0)
|
||||||
|
+ {
|
||||||
|
+ struct in6_addr prefix;
|
||||||
|
+ unsigned long int bits;
|
||||||
|
+ unsigned long int val;
|
||||||
|
+ char *endp;
|
||||||
|
+
|
||||||
|
+ bits = 32;
|
||||||
|
+ __set_errno (0);
|
||||||
|
+ cp = strchr (val1, '/');
|
||||||
|
+ if (cp != NULL)
|
||||||
|
+ *cp++ = '\0';
|
||||||
|
+ if (inet_pton (AF_INET6, val1, &prefix))
|
||||||
|
{
|
||||||
|
- struct in6_addr prefix;
|
||||||
|
- unsigned long int bits;
|
||||||
|
- unsigned long int val;
|
||||||
|
- char *endp;
|
||||||
|
-
|
||||||
|
- bits = 32;
|
||||||
|
- __set_errno (0);
|
||||||
|
- cp = strchr (val1, '/');
|
||||||
|
- if (cp != NULL)
|
||||||
|
- *cp++ = '\0';
|
||||||
|
- if (inet_pton (AF_INET6, val1, &prefix))
|
||||||
|
- {
|
||||||
|
- bits = 128;
|
||||||
|
- if (IN6_IS_ADDR_V4MAPPED (&prefix)
|
||||||
|
- && (cp == NULL
|
||||||
|
- || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
||||||
|
- || errno != ERANGE)
|
||||||
|
- && *endp == '\0'
|
||||||
|
- && bits >= 96
|
||||||
|
- && bits <= 128
|
||||||
|
- && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
||||||
|
- || errno != ERANGE)
|
||||||
|
- && *endp == '\0'
|
||||||
|
- && val <= INT_MAX)
|
||||||
|
- {
|
||||||
|
- if (!add_scopelist (&scopelist, &nscopelist,
|
||||||
|
- &scopelist_nullbits, &prefix,
|
||||||
|
- bits, val))
|
||||||
|
- {
|
||||||
|
- free (line);
|
||||||
|
- fclose (fp);
|
||||||
|
- goto no_file;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
|
||||||
|
- && (cp == NULL
|
||||||
|
- || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
||||||
|
- || errno != ERANGE)
|
||||||
|
- && *endp == '\0'
|
||||||
|
- && bits <= 32
|
||||||
|
- && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
||||||
|
- || errno != ERANGE)
|
||||||
|
- && *endp == '\0'
|
||||||
|
- && val <= INT_MAX)
|
||||||
|
+ bits = 128;
|
||||||
|
+ if (IN6_IS_ADDR_V4MAPPED (&prefix)
|
||||||
|
+ && (cp == NULL
|
||||||
|
+ || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
||||||
|
+ || errno != ERANGE)
|
||||||
|
+ && *endp == '\0'
|
||||||
|
+ && bits >= 96
|
||||||
|
+ && bits <= 128
|
||||||
|
+ && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
||||||
|
+ || errno != ERANGE)
|
||||||
|
+ && *endp == '\0'
|
||||||
|
+ && val <= INT_MAX)
|
||||||
|
{
|
||||||
|
if (!add_scopelist (&scopelist, &nscopelist,
|
||||||
|
&scopelist_nullbits, &prefix,
|
||||||
|
- bits + 96, val))
|
||||||
|
+ bits, val))
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
fclose (fp);
|
||||||
|
@@ -2076,173 +2056,191 @@ gaiconf_init (void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- case 10:
|
||||||
|
- if (strcmp (cmd, "precedence") == 0)
|
||||||
|
+ else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
|
||||||
|
+ && (cp == NULL
|
||||||
|
+ || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
||||||
|
+ || errno != ERANGE)
|
||||||
|
+ && *endp == '\0'
|
||||||
|
+ && bits <= 32
|
||||||
|
+ && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
||||||
|
+ || errno != ERANGE)
|
||||||
|
+ && *endp == '\0'
|
||||||
|
+ && val <= INT_MAX)
|
||||||
|
{
|
||||||
|
- if (!add_prefixlist (&precedencelist, &nprecedencelist,
|
||||||
|
- &precedencelist_nullbits, val1, val2,
|
||||||
|
- &cp))
|
||||||
|
+ if (!add_scopelist (&scopelist, &nscopelist,
|
||||||
|
+ &scopelist_nullbits, &prefix,
|
||||||
|
+ bits + 96, val))
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
fclose (fp);
|
||||||
|
goto no_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- free (line);
|
||||||
|
-
|
||||||
|
- fclose (fp);
|
||||||
|
-
|
||||||
|
- /* Create the array for the labels. */
|
||||||
|
- struct prefixentry *new_labels;
|
||||||
|
- if (nlabellist > 0)
|
||||||
|
- {
|
||||||
|
- if (!labellist_nullbits)
|
||||||
|
- ++nlabellist;
|
||||||
|
- new_labels = malloc (nlabellist * sizeof (*new_labels));
|
||||||
|
- if (new_labels == NULL)
|
||||||
|
- goto no_file;
|
||||||
|
-
|
||||||
|
- int i = nlabellist;
|
||||||
|
- if (!labellist_nullbits)
|
||||||
|
- {
|
||||||
|
- --i;
|
||||||
|
- memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
|
||||||
|
- new_labels[i].bits = 0;
|
||||||
|
- new_labels[i].val = 1;
|
||||||
|
}
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- struct prefixlist *l = labellist;
|
||||||
|
- while (i-- > 0)
|
||||||
|
+ case 10:
|
||||||
|
+ if (strcmp (cmd, "precedence") == 0)
|
||||||
|
{
|
||||||
|
- new_labels[i] = l->entry;
|
||||||
|
- l = l->next;
|
||||||
|
+ if (!add_prefixlist (&precedencelist, &nprecedencelist,
|
||||||
|
+ &precedencelist_nullbits, val1, val2,
|
||||||
|
+ &cp))
|
||||||
|
+ {
|
||||||
|
+ free (line);
|
||||||
|
+ fclose (fp);
|
||||||
|
+ goto no_file;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- free_prefixlist (labellist);
|
||||||
|
- labellist = NULL;
|
||||||
|
-
|
||||||
|
- /* Sort the entries so that the most specific ones are at
|
||||||
|
- the beginning. */
|
||||||
|
- qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
- new_labels = (struct prefixentry *) default_labels;
|
||||||
|
-
|
||||||
|
- struct prefixentry *new_precedence;
|
||||||
|
- if (nprecedencelist > 0)
|
||||||
|
- {
|
||||||
|
- if (!precedencelist_nullbits)
|
||||||
|
- ++nprecedencelist;
|
||||||
|
- new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
|
||||||
|
- if (new_precedence == NULL)
|
||||||
|
- {
|
||||||
|
- if (new_labels != default_labels)
|
||||||
|
- free (new_labels);
|
||||||
|
- goto no_file;
|
||||||
|
- }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- int i = nprecedencelist;
|
||||||
|
- if (!precedencelist_nullbits)
|
||||||
|
- {
|
||||||
|
- --i;
|
||||||
|
- memset (&new_precedence[i].prefix, '\0',
|
||||||
|
- sizeof (struct in6_addr));
|
||||||
|
- new_precedence[i].bits = 0;
|
||||||
|
- new_precedence[i].val = 40;
|
||||||
|
- }
|
||||||
|
+ free (line);
|
||||||
|
|
||||||
|
- struct prefixlist *l = precedencelist;
|
||||||
|
- while (i-- > 0)
|
||||||
|
- {
|
||||||
|
- new_precedence[i] = l->entry;
|
||||||
|
- l = l->next;
|
||||||
|
- }
|
||||||
|
- free_prefixlist (precedencelist);
|
||||||
|
- precedencelist = NULL;
|
||||||
|
+ fclose (fp);
|
||||||
|
|
||||||
|
- /* Sort the entries so that the most specific ones are at
|
||||||
|
- the beginning. */
|
||||||
|
- qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
|
||||||
|
- prefixcmp);
|
||||||
|
+ /* Create the array for the labels. */
|
||||||
|
+ struct prefixentry *new_labels;
|
||||||
|
+ if (nlabellist > 0)
|
||||||
|
+ {
|
||||||
|
+ if (!labellist_nullbits)
|
||||||
|
+ ++nlabellist;
|
||||||
|
+ new_labels = malloc (nlabellist * sizeof (*new_labels));
|
||||||
|
+ if (new_labels == NULL)
|
||||||
|
+ goto no_file;
|
||||||
|
+
|
||||||
|
+ int i = nlabellist;
|
||||||
|
+ if (!labellist_nullbits)
|
||||||
|
+ {
|
||||||
|
+ --i;
|
||||||
|
+ memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
|
||||||
|
+ new_labels[i].bits = 0;
|
||||||
|
+ new_labels[i].val = 1;
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
- new_precedence = (struct prefixentry *) default_precedence;
|
||||||
|
|
||||||
|
- struct scopeentry *new_scopes;
|
||||||
|
- if (nscopelist > 0)
|
||||||
|
+ struct prefixlist *l = labellist;
|
||||||
|
+ while (i-- > 0)
|
||||||
|
{
|
||||||
|
- if (!scopelist_nullbits)
|
||||||
|
- ++nscopelist;
|
||||||
|
- new_scopes = malloc (nscopelist * sizeof (*new_scopes));
|
||||||
|
- if (new_scopes == NULL)
|
||||||
|
- {
|
||||||
|
- if (new_labels != default_labels)
|
||||||
|
- free (new_labels);
|
||||||
|
- if (new_precedence != default_precedence)
|
||||||
|
- free (new_precedence);
|
||||||
|
- goto no_file;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- int i = nscopelist;
|
||||||
|
- if (!scopelist_nullbits)
|
||||||
|
- {
|
||||||
|
- --i;
|
||||||
|
- new_scopes[i].addr32 = 0;
|
||||||
|
- new_scopes[i].netmask = 0;
|
||||||
|
- new_scopes[i].scope = 14;
|
||||||
|
- }
|
||||||
|
+ new_labels[i] = l->entry;
|
||||||
|
+ l = l->next;
|
||||||
|
+ }
|
||||||
|
+ free_prefixlist (labellist);
|
||||||
|
+ labellist = NULL;
|
||||||
|
|
||||||
|
- struct scopelist *l = scopelist;
|
||||||
|
- while (i-- > 0)
|
||||||
|
- {
|
||||||
|
- new_scopes[i] = l->entry;
|
||||||
|
- l = l->next;
|
||||||
|
- }
|
||||||
|
- free_scopelist (scopelist);
|
||||||
|
+ /* Sort the entries so that the most specific ones are at
|
||||||
|
+ the beginning. */
|
||||||
|
+ qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ new_labels = (struct prefixentry *) default_labels;
|
||||||
|
|
||||||
|
- /* Sort the entries so that the most specific ones are at
|
||||||
|
- the beginning. */
|
||||||
|
- qsort (new_scopes, nscopelist, sizeof (*new_scopes),
|
||||||
|
- scopecmp);
|
||||||
|
+ struct prefixentry *new_precedence;
|
||||||
|
+ if (nprecedencelist > 0)
|
||||||
|
+ {
|
||||||
|
+ if (!precedencelist_nullbits)
|
||||||
|
+ ++nprecedencelist;
|
||||||
|
+ new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
|
||||||
|
+ if (new_precedence == NULL)
|
||||||
|
+ {
|
||||||
|
+ if (new_labels != default_labels)
|
||||||
|
+ free (new_labels);
|
||||||
|
+ goto no_file;
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
- new_scopes = (struct scopeentry *) default_scopes;
|
||||||
|
-
|
||||||
|
- /* Now we are ready to replace the values. */
|
||||||
|
- const struct prefixentry *old = labels;
|
||||||
|
- labels = new_labels;
|
||||||
|
- if (old != default_labels)
|
||||||
|
- free ((void *) old);
|
||||||
|
|
||||||
|
- old = precedence;
|
||||||
|
- precedence = new_precedence;
|
||||||
|
- if (old != default_precedence)
|
||||||
|
- free ((void *) old);
|
||||||
|
+ int i = nprecedencelist;
|
||||||
|
+ if (!precedencelist_nullbits)
|
||||||
|
+ {
|
||||||
|
+ --i;
|
||||||
|
+ memset (&new_precedence[i].prefix, '\0',
|
||||||
|
+ sizeof (struct in6_addr));
|
||||||
|
+ new_precedence[i].bits = 0;
|
||||||
|
+ new_precedence[i].val = 40;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- const struct scopeentry *oldscope = scopes;
|
||||||
|
- scopes = new_scopes;
|
||||||
|
- if (oldscope != default_scopes)
|
||||||
|
- free ((void *) oldscope);
|
||||||
|
+ struct prefixlist *l = precedencelist;
|
||||||
|
+ while (i-- > 0)
|
||||||
|
+ {
|
||||||
|
+ new_precedence[i] = l->entry;
|
||||||
|
+ l = l->next;
|
||||||
|
+ }
|
||||||
|
+ free_prefixlist (precedencelist);
|
||||||
|
+ precedencelist = NULL;
|
||||||
|
|
||||||
|
- save_gaiconf_mtime (&st);
|
||||||
|
+ /* Sort the entries so that the most specific ones are at
|
||||||
|
+ the beginning. */
|
||||||
|
+ qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
|
||||||
|
+ prefixcmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
+ new_precedence = (struct prefixentry *) default_precedence;
|
||||||
|
+
|
||||||
|
+ struct scopeentry *new_scopes;
|
||||||
|
+ if (nscopelist > 0)
|
||||||
|
{
|
||||||
|
- no_file:
|
||||||
|
- free_prefixlist (labellist);
|
||||||
|
- free_prefixlist (precedencelist);
|
||||||
|
+ if (!scopelist_nullbits)
|
||||||
|
+ ++nscopelist;
|
||||||
|
+ new_scopes = malloc (nscopelist * sizeof (*new_scopes));
|
||||||
|
+ if (new_scopes == NULL)
|
||||||
|
+ {
|
||||||
|
+ if (new_labels != default_labels)
|
||||||
|
+ free (new_labels);
|
||||||
|
+ if (new_precedence != default_precedence)
|
||||||
|
+ free (new_precedence);
|
||||||
|
+ goto no_file;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int i = nscopelist;
|
||||||
|
+ if (!scopelist_nullbits)
|
||||||
|
+ {
|
||||||
|
+ --i;
|
||||||
|
+ new_scopes[i].addr32 = 0;
|
||||||
|
+ new_scopes[i].netmask = 0;
|
||||||
|
+ new_scopes[i].scope = 14;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ struct scopelist *l = scopelist;
|
||||||
|
+ while (i-- > 0)
|
||||||
|
+ {
|
||||||
|
+ new_scopes[i] = l->entry;
|
||||||
|
+ l = l->next;
|
||||||
|
+ }
|
||||||
|
free_scopelist (scopelist);
|
||||||
|
|
||||||
|
- /* If we previously read the file but it is gone now, free the
|
||||||
|
- old data and use the builtin one. Leave the reload flag
|
||||||
|
- alone. */
|
||||||
|
- fini ();
|
||||||
|
+ /* Sort the entries so that the most specific ones are at
|
||||||
|
+ the beginning. */
|
||||||
|
+ qsort (new_scopes, nscopelist, sizeof (*new_scopes),
|
||||||
|
+ scopecmp);
|
||||||
|
}
|
||||||
|
+ else
|
||||||
|
+ new_scopes = (struct scopeentry *) default_scopes;
|
||||||
|
+
|
||||||
|
+ /* Now we are ready to replace the values. */
|
||||||
|
+ const struct prefixentry *old = labels;
|
||||||
|
+ labels = new_labels;
|
||||||
|
+ if (old != default_labels)
|
||||||
|
+ free ((void *) old);
|
||||||
|
+
|
||||||
|
+ old = precedence;
|
||||||
|
+ precedence = new_precedence;
|
||||||
|
+ if (old != default_precedence)
|
||||||
|
+ free ((void *) old);
|
||||||
|
+
|
||||||
|
+ const struct scopeentry *oldscope = scopes;
|
||||||
|
+ scopes = new_scopes;
|
||||||
|
+ if (oldscope != default_scopes)
|
||||||
|
+ free ((void *) oldscope);
|
||||||
|
+
|
||||||
|
+ save_gaiconf_mtime (&st);
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+no_file:
|
||||||
|
+ free_prefixlist (labellist);
|
||||||
|
+ free_prefixlist (precedencelist);
|
||||||
|
+ free_scopelist (scopelist);
|
||||||
|
+
|
||||||
|
+ /* If we previously read the file but it is gone now, free the old data and
|
||||||
|
+ use the builtin one. Leave the reload flag alone. */
|
||||||
|
+ fini ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
|||||||
|
commit d3f2c2c8b57bdf9d963db8fa2372d6c1b86a337e
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue Mar 22 22:40:05 2022 +0530
|
||||||
|
|
||||||
|
getaddrinfo: Refactor code for readability
|
||||||
|
|
||||||
|
The close_retry goto jump is confusing and clumsy to read, so refactor
|
||||||
|
the code a bit to make it easier to follow.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 1635a09837351068..5e9bd17eb949974c 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -2253,6 +2253,36 @@ gaiconf_reload (void)
|
||||||
|
gaiconf_init ();
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool
|
||||||
|
+try_connect (int *fdp, int *afp, struct sockaddr_in6 *source_addrp,
|
||||||
|
+ const struct sockaddr *addr, socklen_t addrlen, int family)
|
||||||
|
+{
|
||||||
|
+ int fd = *fdp;
|
||||||
|
+ int af = *afp;
|
||||||
|
+ socklen_t sl = sizeof (*source_addrp);
|
||||||
|
+
|
||||||
|
+ while (true)
|
||||||
|
+ {
|
||||||
|
+ if (fd != -1 && __connect (fd, addr, addrlen) == 0
|
||||||
|
+ && __getsockname (fd, (struct sockaddr *) source_addrp, &sl) == 0)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ if (errno == EAFNOSUPPORT && af == AF_INET6 && family == AF_INET)
|
||||||
|
+ {
|
||||||
|
+ /* This could mean IPv6 sockets are IPv6-only. */
|
||||||
|
+ if (fd != -1)
|
||||||
|
+ __close_nocancel_nostatus (fd);
|
||||||
|
+ *afp = af = AF_INET;
|
||||||
|
+ *fdp = fd = __socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC,
|
||||||
|
+ IPPROTO_IP);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ __builtin_unreachable ();
|
||||||
|
+}
|
||||||
|
|
||||||
|
int
|
||||||
|
getaddrinfo (const char *name, const char *service,
|
||||||
|
@@ -2443,7 +2473,6 @@ getaddrinfo (const char *name, const char *service,
|
||||||
|
if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
|
||||||
|
{
|
||||||
|
if (fd != -1)
|
||||||
|
- close_retry:
|
||||||
|
__close_nocancel_nostatus (fd);
|
||||||
|
af = q->ai_family;
|
||||||
|
fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
|
||||||
|
@@ -2455,14 +2484,10 @@ getaddrinfo (const char *name, const char *service,
|
||||||
|
__connect (fd, &sa, sizeof (sa));
|
||||||
|
}
|
||||||
|
|
||||||
|
- socklen_t sl = sizeof (results[i].source_addr);
|
||||||
|
- if (fd != -1
|
||||||
|
- && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
|
||||||
|
- && __getsockname (fd,
|
||||||
|
- (struct sockaddr *) &results[i].source_addr,
|
||||||
|
- &sl) == 0)
|
||||||
|
+ if (try_connect (&fd, &af, &results[i].source_addr, q->ai_addr,
|
||||||
|
+ q->ai_addrlen, q->ai_family))
|
||||||
|
{
|
||||||
|
- results[i].source_addr_len = sl;
|
||||||
|
+ results[i].source_addr_len = sizeof (results[i].source_addr);
|
||||||
|
results[i].got_source_addr = true;
|
||||||
|
|
||||||
|
if (in6ai != NULL)
|
||||||
|
@@ -2527,10 +2552,6 @@ getaddrinfo (const char *name, const char *service,
|
||||||
|
results[i].source_addr_len = sizeof (struct sockaddr_in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- else if (errno == EAFNOSUPPORT && af == AF_INET6
|
||||||
|
- && q->ai_family == AF_INET)
|
||||||
|
- /* This could mean IPv6 sockets are IPv6-only. */
|
||||||
|
- goto close_retry;
|
||||||
|
else
|
||||||
|
/* Just make sure that if we have to process the same
|
||||||
|
address again we do not copy any memory. */
|
@ -0,0 +1,32 @@
|
|||||||
|
commit c9226c03da0276593a0918eaa9a14835183343e8
|
||||||
|
Author: Jörg Sonnenberger <joerg@bec.de>
|
||||||
|
Date: Mon Sep 26 13:59:16 2022 -0400
|
||||||
|
|
||||||
|
get_nscd_addresses: Fix subscript typos [BZ #29605]
|
||||||
|
|
||||||
|
Fix the subscript on air->family, which was accidentally set to COUNT
|
||||||
|
when it should have remained as I.
|
||||||
|
|
||||||
|
Resolves: BZ #29605
|
||||||
|
|
||||||
|
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 5e9bd17eb949974c..40a32a3de30cb294 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -549,11 +549,11 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
|
||||||
|
at[count].addr[2] = htonl (0xffff);
|
||||||
|
}
|
||||||
|
else if (req->ai_family == AF_UNSPEC
|
||||||
|
- || air->family[count] == req->ai_family)
|
||||||
|
+ || air->family[i] == req->ai_family)
|
||||||
|
{
|
||||||
|
- at[count].family = air->family[count];
|
||||||
|
+ at[count].family = air->family[i];
|
||||||
|
memcpy (at[count].addr, addrs, size);
|
||||||
|
- if (air->family[count] == AF_INET6)
|
||||||
|
+ if (air->family[i] == AF_INET6)
|
||||||
|
res->got_ipv6 = true;
|
||||||
|
}
|
||||||
|
at[count].next = at + count + 1;
|
@ -0,0 +1,25 @@
|
|||||||
|
commit 3bf7bab88b0da01d4f5ef20afbbb45203185501e
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue Sep 5 17:04:05 2023 -0400
|
||||||
|
|
||||||
|
getcanonname: Fix a typo
|
||||||
|
|
||||||
|
This code is generally unused in practice since there don't seem to be
|
||||||
|
any NSS modules that only implement _nss_MOD_gethostbyname2_r and not
|
||||||
|
_nss_MOD_gethostbyname3_r.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 40a32a3de30cb294..e9f47aea358a3351 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -346,7 +346,7 @@ getcanonname (nss_action_list nip, const char *hname, const char *name)
|
||||||
|
string. */
|
||||||
|
s = (char *) name;
|
||||||
|
}
|
||||||
|
- return __strdup (name);
|
||||||
|
+ return __strdup (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process looked up canonical name and if necessary, decode to IDNA. Result
|
@ -0,0 +1,23 @@
|
|||||||
|
commit 61bac1a9d2ab80ebcbc51484722e6ea43414bec7
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Wed Dec 20 16:14:33 2023 +0100
|
||||||
|
|
||||||
|
nss: Remove unused allocation from get_nscd_addresses in getaddrinfo
|
||||||
|
|
||||||
|
No bug because this is not visible if glibc is built with
|
||||||
|
optimization. Otherwise this would be a critical resource leak.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index e9f47aea358a3351..321a6679d46494a3 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -514,7 +514,6 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
|
||||||
|
int result = 0;
|
||||||
|
char *addrs = air->addrs;
|
||||||
|
|
||||||
|
- struct gaih_addrtuple *addrfree = calloc (air->naddrs, sizeof (*addrfree));
|
||||||
|
struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at));
|
||||||
|
if (at == NULL)
|
||||||
|
{
|
@ -0,0 +1,35 @@
|
|||||||
|
commit b893410be304ddcea0bd43f537a13e8b18d37cf2
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Nov 27 11:28:07 2023 +0100
|
||||||
|
|
||||||
|
elf: In _dl_relocate_object, skip processing if object is relocated
|
||||||
|
|
||||||
|
This is just a minor optimization. It also makes it more obvious that
|
||||||
|
_dl_relocate_object can be called multiple times.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
|
||||||
|
index be3e09e36835ed23..0254e589c06fbf4c 100644
|
||||||
|
--- a/elf/dl-reloc.c
|
||||||
|
+++ b/elf/dl-reloc.c
|
||||||
|
@@ -192,6 +192,9 @@ void
|
||||||
|
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
int reloc_mode, int consider_profiling)
|
||||||
|
{
|
||||||
|
+ if (l->l_relocated)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
struct textrels
|
||||||
|
{
|
||||||
|
caddr_t start;
|
||||||
|
@@ -229,9 +232,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
# define consider_symbind 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- if (l->l_relocated)
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
/* If DT_BIND_NOW is set relocate all references in this object. We
|
||||||
|
do not do this if we are profiling, of course. */
|
||||||
|
// XXX Correct for auditing?
|
@ -0,0 +1,121 @@
|
|||||||
|
commit a74c2e1cbc8673dd7e97aae2f2705392e2ccc3f6
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Nov 27 11:28:10 2023 +0100
|
||||||
|
|
||||||
|
elf: Introduce the _dl_open_relocate_one_object function
|
||||||
|
|
||||||
|
It is extracted from dl_open_worker_begin.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index c8a5d88161441031..cf3baccccb461878 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -467,6 +467,50 @@ activate_nodelete (struct link_map *new)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Relocate the object L. *RELOCATION_IN_PROGRESS controls whether
|
||||||
|
+ the debugger is notified of the start of relocation processing. */
|
||||||
|
+static void
|
||||||
|
+_dl_open_relocate_one_object (struct dl_open_args *args, struct r_debug *r,
|
||||||
|
+ struct link_map *l, int reloc_mode,
|
||||||
|
+ bool *relocation_in_progress)
|
||||||
|
+{
|
||||||
|
+ if (l->l_real->l_relocated)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (!*relocation_in_progress)
|
||||||
|
+ {
|
||||||
|
+ /* Notify the debugger that relocations are about to happen. */
|
||||||
|
+ LIBC_PROBE (reloc_start, 2, args->nsid, r);
|
||||||
|
+ *relocation_in_progress = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ if (__glibc_unlikely (GLRO(dl_profile) != NULL))
|
||||||
|
+ {
|
||||||
|
+ /* If this here is the shared object which we want to profile
|
||||||
|
+ make sure the profile is started. We can find out whether
|
||||||
|
+ this is necessary or not by observing the `_dl_profile_map'
|
||||||
|
+ variable. If it was NULL but is not NULL afterwards we must
|
||||||
|
+ start the profiling. */
|
||||||
|
+ struct link_map *old_profile_map = GL(dl_profile_map);
|
||||||
|
+
|
||||||
|
+ _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
|
||||||
|
+
|
||||||
|
+ if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
|
||||||
|
+ {
|
||||||
|
+ /* We must prepare the profiling. */
|
||||||
|
+ _dl_start_profile ();
|
||||||
|
+
|
||||||
|
+ /* Prevent unloading the object. */
|
||||||
|
+ GL(dl_profile_map)->l_nodelete_active = true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+#endif
|
||||||
|
+ _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/* struct dl_init_args and call_dl_init are used to call _dl_init with
|
||||||
|
exception handling disabled. */
|
||||||
|
struct dl_init_args
|
||||||
|
@@ -651,7 +695,7 @@ dl_open_worker_begin (void *a)
|
||||||
|
}
|
||||||
|
while (l != NULL);
|
||||||
|
|
||||||
|
- int relocation_in_progress = 0;
|
||||||
|
+ bool relocation_in_progress = false;
|
||||||
|
|
||||||
|
/* Perform relocation. This can trigger lazy binding in IFUNC
|
||||||
|
resolvers. For NODELETE mappings, these dependencies are not
|
||||||
|
@@ -662,44 +706,8 @@ dl_open_worker_begin (void *a)
|
||||||
|
are undefined anyway, so this is not a problem. */
|
||||||
|
|
||||||
|
for (unsigned int i = last; i-- > first; )
|
||||||
|
- {
|
||||||
|
- l = new->l_initfini[i];
|
||||||
|
-
|
||||||
|
- if (l->l_real->l_relocated)
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- if (! relocation_in_progress)
|
||||||
|
- {
|
||||||
|
- /* Notify the debugger that relocations are about to happen. */
|
||||||
|
- LIBC_PROBE (reloc_start, 2, args->nsid, r);
|
||||||
|
- relocation_in_progress = 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-#ifdef SHARED
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_profile) != NULL))
|
||||||
|
- {
|
||||||
|
- /* If this here is the shared object which we want to profile
|
||||||
|
- make sure the profile is started. We can find out whether
|
||||||
|
- this is necessary or not by observing the `_dl_profile_map'
|
||||||
|
- variable. If it was NULL but is not NULL afterwards we must
|
||||||
|
- start the profiling. */
|
||||||
|
- struct link_map *old_profile_map = GL(dl_profile_map);
|
||||||
|
-
|
||||||
|
- _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
|
||||||
|
-
|
||||||
|
- if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
|
||||||
|
- {
|
||||||
|
- /* We must prepare the profiling. */
|
||||||
|
- _dl_start_profile ();
|
||||||
|
-
|
||||||
|
- /* Prevent unloading the object. */
|
||||||
|
- GL(dl_profile_map)->l_nodelete_active = true;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
-#endif
|
||||||
|
- _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
|
||||||
|
- }
|
||||||
|
+ _dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
|
||||||
|
+ &relocation_in_progress);
|
||||||
|
|
||||||
|
/* This only performs the memory allocations. The actual update of
|
||||||
|
the scopes happens below, after failure is impossible. */
|
@ -0,0 +1,224 @@
|
|||||||
|
commit 78ca44da0160a0b442f0ca1f253e3360f044b2ec
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Nov 27 11:28:13 2023 +0100
|
||||||
|
|
||||||
|
elf: Relocate libc.so early during startup and dlmopen (bug 31083)
|
||||||
|
|
||||||
|
This makes it more likely that objects without dependencies can
|
||||||
|
use IFUNC resolvers in libc.so.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
(test backport differences)
|
||||||
|
elf/rtld.c
|
||||||
|
(prelink support was removed upstream)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 8e1f91bcd917fd4e..7b7c6c171ce23247 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -419,6 +419,8 @@ tests += \
|
||||||
|
tst-nodelete2 \
|
||||||
|
tst-nodelete-dlclose \
|
||||||
|
tst-nodelete-opened \
|
||||||
|
+ tst-nodeps1 \
|
||||||
|
+ tst-nodeps2 \
|
||||||
|
tst-noload \
|
||||||
|
tst-null-argv \
|
||||||
|
tst-relsort1 \
|
||||||
|
@@ -777,6 +779,8 @@ modules-names = \
|
||||||
|
tst-nodelete-dlclose-dso \
|
||||||
|
tst-nodelete-dlclose-plugin \
|
||||||
|
tst-nodelete-opened-lib \
|
||||||
|
+ tst-nodeps1-mod \
|
||||||
|
+ tst-nodeps2-mod \
|
||||||
|
tst-null-argv-lib \
|
||||||
|
tst-relsort1mod1 \
|
||||||
|
tst-relsort1mod2 \
|
||||||
|
@@ -931,8 +935,15 @@ 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
|
||||||
|
+modules-names-nobuild += \
|
||||||
|
+ filtmod1 \
|
||||||
|
+ tst-audit24bmod1 \
|
||||||
|
+ tst-audit24bmod2 \
|
||||||
|
+ tst-big-note-lib \
|
||||||
|
+ tst-nodeps1-mod \
|
||||||
|
+ tst-nodeps2-mod \
|
||||||
|
+ tst-ro-dynamic-mod \
|
||||||
|
+ # modules-names-nobuild
|
||||||
|
|
||||||
|
tests += $(tests-static)
|
||||||
|
|
||||||
|
@@ -2684,3 +2695,18 @@ LDFLAGS-tst-dlclose-lazy-mod1.so = -Wl,-z,lazy,--no-as-needed
|
||||||
|
$(objpfx)tst-dlclose-lazy-mod1.so: $(objpfx)tst-dlclose-lazy-mod2.so
|
||||||
|
$(objpfx)tst-dlclose-lazy.out: \
|
||||||
|
$(objpfx)tst-dlclose-lazy-mod1.so $(objpfx)tst-dlclose-lazy-mod2.so
|
||||||
|
+
|
||||||
|
+# The object tst-nodeps1-mod.so has no explicit dependencies on libc.so.
|
||||||
|
+$(objpfx)tst-nodeps1-mod.so: $(objpfx)tst-nodeps1-mod.os
|
||||||
|
+ $(LINK.o) -nostartfiles -nostdlib -shared -o $@ $^
|
||||||
|
+tst-nodeps1.so-no-z-defs = yes
|
||||||
|
+# Link libc.so before the test module with the IFUNC resolver reference.
|
||||||
|
+LDFLAGS-tst-nodeps1 = $(common-objpfx)libc.so $(objpfx)tst-nodeps1-mod.so
|
||||||
|
+$(objpfx)tst-nodeps1: $(objpfx)tst-nodeps1-mod.so
|
||||||
|
+# Reuse the tst-nodeps1 module. Link libc.so before the test module
|
||||||
|
+# with the IFUNC resolver reference.
|
||||||
|
+$(objpfx)tst-nodeps2-mod.so: $(common-objpfx)libc.so \
|
||||||
|
+ $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.os
|
||||||
|
+ $(LINK.o) -Wl,--no-as-needed -nostartfiles -nostdlib -shared -o $@ $^
|
||||||
|
+$(objpfx)tst-nodeps2.out: \
|
||||||
|
+ $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.so
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index cf3baccccb461878..4b58bdd668634130 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -705,6 +705,17 @@ dl_open_worker_begin (void *a)
|
||||||
|
them. However, such relocation dependencies in IFUNC resolvers
|
||||||
|
are undefined anyway, so this is not a problem. */
|
||||||
|
|
||||||
|
+ /* Ensure that libc is relocated first. This helps with the
|
||||||
|
+ execution of IFUNC resolvers in libc, and matters only to newly
|
||||||
|
+ created dlmopen namespaces. Do not do this for static dlopen
|
||||||
|
+ because libc has relocations against ld.so, which may not have
|
||||||
|
+ been relocated at this point. */
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ if (GL(dl_ns)[args->nsid].libc_map != NULL)
|
||||||
|
+ _dl_open_relocate_one_object (args, r, GL(dl_ns)[args->nsid].libc_map,
|
||||||
|
+ reloc_mode, &relocation_in_progress);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
for (unsigned int i = last; i-- > first; )
|
||||||
|
_dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
|
||||||
|
&relocation_in_progress);
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 9de53ccaed420a57..a638d14e77745baa 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -2421,11 +2421,17 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
objects. We do not re-relocate the dynamic linker itself in this
|
||||||
|
loop because that could result in the GOT entries for functions we
|
||||||
|
call being changed, and that would break us. It is safe to relocate
|
||||||
|
- the dynamic linker out of order because it has no copy relocs (we
|
||||||
|
- know that because it is self-contained). */
|
||||||
|
+ the dynamic linker out of order because it has no copy relocations.
|
||||||
|
+ Likewise for libc, which is relocated early to ensure that IFUNC
|
||||||
|
+ resolvers in libc work. */
|
||||||
|
|
||||||
|
int consider_profiling = GLRO(dl_profile) != NULL;
|
||||||
|
|
||||||
|
+ if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
|
||||||
|
+ _dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map,
|
||||||
|
+ GL(dl_ns)[LM_ID_BASE].libc_map->l_scope,
|
||||||
|
+ GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling);
|
||||||
|
+
|
||||||
|
/* If we are profiling we also must do lazy reloaction. */
|
||||||
|
GLRO(dl_lazy) |= consider_profiling;
|
||||||
|
|
||||||
|
diff --git a/elf/tst-nodeps1-mod.c b/elf/tst-nodeps1-mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..45c8e3c631251a89
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-nodeps1-mod.c
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* Test module with no libc.so dependency and string function references.
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+/* Some references to libc symbols which are likely to have IFUNC
|
||||||
|
+ resolvers. If they do not, this module does not exercise bug 31083. */
|
||||||
|
+void *memcpy_pointer = memcpy;
|
||||||
|
+void *memmove_pointer = memmove;
|
||||||
|
+void *memset_pointer = memset;
|
||||||
|
diff --git a/elf/tst-nodeps1.c b/elf/tst-nodeps1.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..1a8bde36cdb71446
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-nodeps1.c
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+/* Test initially loaded module with implicit libc.so dependency (bug 31083).
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+/* Testing happens before main. */
|
||||||
|
+int
|
||||||
|
+main (void)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-nodeps2-mod.c b/elf/tst-nodeps2-mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..4913feee9b56e0e1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-nodeps2-mod.c
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+/* Empty test module which depends on tst-nodeps1-mod.so. */
|
||||||
|
diff --git a/elf/tst-nodeps2.c b/elf/tst-nodeps2.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..0bdc8eeb8cba3a99
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-nodeps2.c
|
||||||
|
@@ -0,0 +1,29 @@
|
||||||
|
+/* Test dlmopen with implicit libc.so dependency (bug 31083).
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ void *handle = xdlmopen (LM_ID_NEWLM, "tst-nodeps2-mod.so", RTLD_NOW);
|
||||||
|
+ xdlclose (handle);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
@ -0,0 +1,41 @@
|
|||||||
|
commit b3bee76c5f59498b9c189608f0a3132e2013fa1a
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Fri Dec 8 09:51:34 2023 +0100
|
||||||
|
|
||||||
|
elf: Initialize GLRO(dl_lazy) before relocating libc in dynamic startup
|
||||||
|
|
||||||
|
GLRO(dl_lazy) is used to set the parameters for the early
|
||||||
|
_dl_relocate_object call, so the consider_profiling setting has to
|
||||||
|
be applied before the call.
|
||||||
|
|
||||||
|
Fixes commit 78ca44da0160a0b442f0ca1f253e3360f044b2ec ("elf: Relocate
|
||||||
|
libc.so early during startup and dlmopen (bug 31083)").
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/rtld.c
|
||||||
|
(prelink was removed upstream)
|
||||||
|
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index a638d14e77745baa..d973c385b312ea16 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -2427,14 +2427,14 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
|
||||||
|
int consider_profiling = GLRO(dl_profile) != NULL;
|
||||||
|
|
||||||
|
+ /* If we are profiling we also must do lazy reloaction. */
|
||||||
|
+ GLRO(dl_lazy) |= consider_profiling;
|
||||||
|
+
|
||||||
|
if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
|
||||||
|
_dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map,
|
||||||
|
GL(dl_ns)[LM_ID_BASE].libc_map->l_scope,
|
||||||
|
GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling);
|
||||||
|
|
||||||
|
- /* If we are profiling we also must do lazy reloaction. */
|
||||||
|
- GLRO(dl_lazy) |= consider_profiling;
|
||||||
|
-
|
||||||
|
RTLD_TIMING_VAR (start);
|
||||||
|
rtld_timer_start (&start);
|
||||||
|
unsigned i = main_map->l_searchlist.r_nlist;
|
@ -0,0 +1,47 @@
|
|||||||
|
commit 3921c5b40f293c57cb326f58713c924b0662ef59
|
||||||
|
Author: Hector Martin <marcan@marcan.st>
|
||||||
|
Date: Tue Nov 28 15:23:07 2023 +0900
|
||||||
|
|
||||||
|
elf: Fix TLS modid reuse generation assignment (BZ 29039)
|
||||||
|
|
||||||
|
_dl_assign_tls_modid() assigns a slotinfo entry for a new module, but
|
||||||
|
does *not* do anything to the generation counter. The first time this
|
||||||
|
happens, the generation is zero and map_generation() returns the current
|
||||||
|
generation to be used during relocation processing. However, if
|
||||||
|
a slotinfo entry is later reused, it will already have a generation
|
||||||
|
assigned. If this generation has fallen behind the current global max
|
||||||
|
generation, then this causes an obsolete generation to be assigned
|
||||||
|
during relocation processing, as map_generation() returns this
|
||||||
|
generation if nonzero. _dl_add_to_slotinfo() eventually resets the
|
||||||
|
generation, but by then it is too late. This causes DTV updates to be
|
||||||
|
skipped, leading to NULL or broken TLS slot pointers and segfaults.
|
||||||
|
|
||||||
|
Fix this by resetting the generation to zero in _dl_assign_tls_modid(),
|
||||||
|
so it behaves the same as the first time a slot is assigned.
|
||||||
|
_dl_add_to_slotinfo() will still assign the correct static generation
|
||||||
|
later during module load, but relocation processing will no longer use
|
||||||
|
an obsolete generation.
|
||||||
|
|
||||||
|
Note that slotinfo entry (aka modid) reuse typically happens after a
|
||||||
|
dlclose and only TLS access via dynamic tlsdesc is affected. Because
|
||||||
|
tlsdesc is optimized to use the optional part of static TLS, dynamic
|
||||||
|
tlsdesc can be avoided by increasing the glibc.rtld.optional_static_tls
|
||||||
|
tunable to a large enough value, or by LD_PRELOAD-ing the affected
|
||||||
|
modules.
|
||||||
|
|
||||||
|
Fixes bug 29039.
|
||||||
|
|
||||||
|
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||||
|
index b8ada16f1637c910..b9dc56e81a3b43db 100644
|
||||||
|
--- a/elf/dl-tls.c
|
||||||
|
+++ b/elf/dl-tls.c
|
||||||
|
@@ -160,6 +160,7 @@ _dl_assign_tls_modid (struct link_map *l)
|
||||||
|
{
|
||||||
|
/* Mark the entry as used, so any dependency see it. */
|
||||||
|
atomic_store_relaxed (&runp->slotinfo[result - disp].map, l);
|
||||||
|
+ atomic_store_relaxed (&runp->slotinfo[result - disp].gen, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,198 @@
|
|||||||
|
commit 980450f12685326729d63ff72e93a996113bf073
|
||||||
|
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
Date: Wed Nov 29 11:31:37 2023 +0000
|
||||||
|
|
||||||
|
elf: Add TLS modid reuse test for bug 29039
|
||||||
|
|
||||||
|
This is a minimal regression test for bug 29039 which only affects
|
||||||
|
targets with TLSDESC and a reproducer requires that
|
||||||
|
|
||||||
|
1) Have modid gaps (closed modules) with old generation.
|
||||||
|
2) Update a DTV to a newer generation (needs a newer dlopen).
|
||||||
|
3) But do not update the closed gap entry in that DTV.
|
||||||
|
4) Reuse the modid gap for a new module (another dlopen).
|
||||||
|
5) Use dynamic TLSDESC in that new module with old generation (bug).
|
||||||
|
6) Access TLS via this TLSDESC and the now outdated DTV.
|
||||||
|
|
||||||
|
However step (3) in practice rarely happens: during DTV update the
|
||||||
|
entries for closed modids are initialized to "unallocated" and then
|
||||||
|
dynamic TLSDESC calls __tls_get_addr independently of its generation.
|
||||||
|
The only exception to this is DTV setup at thread creation (gaps are
|
||||||
|
initialized to NULL instead of unallocated) or DTV resize where the
|
||||||
|
gap entries are outside the previous DTV array (again NULL instead
|
||||||
|
of unallocated, and this requires loading > DTV_SURPLUS modules).
|
||||||
|
|
||||||
|
So the bug can only cause NULL (+ offset) dereference, not use after
|
||||||
|
free. And the easiest way to get (3) is via thread creation.
|
||||||
|
|
||||||
|
Note that step (5) requires that the newly loaded module has larger
|
||||||
|
TLS than the remaining optional static TLS. And for (6) there cannot
|
||||||
|
be other TLS access or dlopen in the thread that updates the DTV.
|
||||||
|
|
||||||
|
Tested on aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
(Resolve test case ordering conflict.)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 7b7c6c171ce23247..7d55e68a55b54bd6 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -447,6 +447,7 @@ tests += \
|
||||||
|
tst-tls5 \
|
||||||
|
tst-tlsalign \
|
||||||
|
tst-tlsalign-extern \
|
||||||
|
+ tst-tlsgap \
|
||||||
|
tst-tls-dlinfo \
|
||||||
|
tst-tls-ie \
|
||||||
|
tst-tls-ie-dlmopen \
|
||||||
|
@@ -798,6 +799,9 @@ modules-names = \
|
||||||
|
tst-tls20mod-bad \
|
||||||
|
tst-tls21mod \
|
||||||
|
tst-tlsalign-lib \
|
||||||
|
+ tst-tlsgap-mod0 \
|
||||||
|
+ tst-tlsgap-mod1 \
|
||||||
|
+ tst-tlsgap-mod2 \
|
||||||
|
tst-tls-ie-mod0 \
|
||||||
|
tst-tls-ie-mod1 \
|
||||||
|
tst-tls-ie-mod2 \
|
||||||
|
@@ -2710,3 +2714,14 @@ $(objpfx)tst-nodeps2-mod.so: $(common-objpfx)libc.so \
|
||||||
|
$(LINK.o) -Wl,--no-as-needed -nostartfiles -nostdlib -shared -o $@ $^
|
||||||
|
$(objpfx)tst-nodeps2.out: \
|
||||||
|
$(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.so
|
||||||
|
+
|
||||||
|
+$(objpfx)tst-tlsgap: $(shared-thread-library)
|
||||||
|
+$(objpfx)tst-tlsgap.out: \
|
||||||
|
+ $(objpfx)tst-tlsgap-mod0.so \
|
||||||
|
+ $(objpfx)tst-tlsgap-mod1.so \
|
||||||
|
+ $(objpfx)tst-tlsgap-mod2.so
|
||||||
|
+ifeq (yes,$(have-mtls-dialect-gnu2))
|
||||||
|
+CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2
|
||||||
|
+CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2
|
||||||
|
+CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2
|
||||||
|
+endif
|
||||||
|
diff --git a/elf/tst-tlsgap-mod0.c b/elf/tst-tlsgap-mod0.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..1478b0beac5faf98
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-tlsgap-mod0.c
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+int __thread tls0;
|
||||||
|
+int *f0(void) { return &tls0; }
|
||||||
|
diff --git a/elf/tst-tlsgap-mod1.c b/elf/tst-tlsgap-mod1.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..b10fc3702c43e478
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-tlsgap-mod1.c
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+int __thread tls1[100]; /* Size > glibc.rtld.optional_static_tls / 2. */
|
||||||
|
+int *f1(void) { return tls1; }
|
||||||
|
diff --git a/elf/tst-tlsgap-mod2.c b/elf/tst-tlsgap-mod2.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..166c27d7f3fac252
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-tlsgap-mod2.c
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+int __thread tls2;
|
||||||
|
+int *f2(void) { return &tls2; }
|
||||||
|
diff --git a/elf/tst-tlsgap.c b/elf/tst-tlsgap.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..49328850769c5609
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-tlsgap.c
|
||||||
|
@@ -0,0 +1,92 @@
|
||||||
|
+/* TLS modid gap reuse regression test for bug 29039.
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+#include <pthread.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+static void *mod[3];
|
||||||
|
+#define MOD(i) "tst-tlsgap-mod" #i ".so"
|
||||||
|
+static const char *modname[3] = { MOD(0), MOD(1), MOD(2) };
|
||||||
|
+#undef MOD
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+open_mod (int i)
|
||||||
|
+{
|
||||||
|
+ mod[i] = xdlopen (modname[i], RTLD_LAZY);
|
||||||
|
+ printf ("open %s\n", modname[i]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+close_mod (int i)
|
||||||
|
+{
|
||||||
|
+ xdlclose (mod[i]);
|
||||||
|
+ mod[i] = NULL;
|
||||||
|
+ printf ("close %s\n", modname[i]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+access_mod (int i, const char *sym)
|
||||||
|
+{
|
||||||
|
+ int *(*f) (void) = xdlsym (mod[i], sym);
|
||||||
|
+ int *p = f ();
|
||||||
|
+ printf ("access %s: %s() = %p\n", modname[i], sym, p);
|
||||||
|
+ TEST_VERIFY_EXIT (p != NULL);
|
||||||
|
+ ++*p;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+start (void *arg)
|
||||||
|
+{
|
||||||
|
+ /* The DTV generation is at the last dlopen of mod0 and the
|
||||||
|
+ entry for mod1 is NULL. */
|
||||||
|
+
|
||||||
|
+ open_mod (1); /* Reuse modid of mod1. Uses dynamic TLS. */
|
||||||
|
+
|
||||||
|
+ /* DTV is unchanged: dlopen only updates the DTV to the latest
|
||||||
|
+ generation if static TLS is allocated for a loaded module.
|
||||||
|
+
|
||||||
|
+ With bug 29039, the TLSDESC relocation in mod1 uses the old
|
||||||
|
+ dlclose generation of mod1 instead of the new dlopen one so
|
||||||
|
+ DTV is not updated on TLS access. */
|
||||||
|
+
|
||||||
|
+ access_mod (1, "f1");
|
||||||
|
+
|
||||||
|
+ return arg;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ open_mod (0);
|
||||||
|
+ open_mod (1);
|
||||||
|
+ open_mod (2);
|
||||||
|
+ close_mod (0);
|
||||||
|
+ close_mod (1); /* Create modid gap at mod1. */
|
||||||
|
+ open_mod (0); /* Reuse modid of mod0, bump generation count. */
|
||||||
|
+
|
||||||
|
+ /* Create a thread where DTV of mod1 is NULL. */
|
||||||
|
+ pthread_t t = xpthread_create (NULL, start, NULL);
|
||||||
|
+ xpthread_join (t);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
@ -0,0 +1,29 @@
|
|||||||
|
commit 5eabdb6a6ac1599d23dd5966a37417215950245f
|
||||||
|
Author: Andreas Schwab <schwab@suse.de>
|
||||||
|
Date: Wed Dec 6 14:48:22 2023 +0100
|
||||||
|
|
||||||
|
getaddrinfo: translate ENOMEM to EAI_MEMORY (bug 31163)
|
||||||
|
|
||||||
|
When __resolv_context_get returns NULL due to out of memory, translate it
|
||||||
|
to a return value of EAI_MEMORY.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 321a6679d46494a3..8fe879c5420337a4 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -615,7 +615,14 @@ get_nss_addresses (const char *name, const struct addrinfo *req,
|
||||||
|
function variant. */
|
||||||
|
res_ctx = __resolv_context_get ();
|
||||||
|
if (res_ctx == NULL)
|
||||||
|
- no_more = 1;
|
||||||
|
+ {
|
||||||
|
+ if (errno == ENOMEM)
|
||||||
|
+ {
|
||||||
|
+ result = -EAI_MEMORY;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ no_more = 1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
while (!no_more)
|
||||||
|
{
|
@ -0,0 +1,27 @@
|
|||||||
|
commit ecc7c3deb9f347649c2078fcc0f94d4cedf92d60
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue Jan 2 14:36:17 2024 +0100
|
||||||
|
|
||||||
|
libio: Check remaining buffer size in _IO_wdo_write (bug 31183)
|
||||||
|
|
||||||
|
The multibyte character needs to fit into the remaining buffer space,
|
||||||
|
not the already-written buffer space. Without the fix, we were never
|
||||||
|
moving the write pointer from the start of the buffer, always using
|
||||||
|
the single-character fallback buffer.
|
||||||
|
|
||||||
|
Fixes commit 04b76b5aa8b2d1d19066e42dd1 ("Don't error out writing
|
||||||
|
a multibyte character to an unbuffered stream (bug 17522)").
|
||||||
|
|
||||||
|
diff --git a/libio/wfileops.c b/libio/wfileops.c
|
||||||
|
index 37f44780f811bd38..6cbc3c7c968f9136 100644
|
||||||
|
--- a/libio/wfileops.c
|
||||||
|
+++ b/libio/wfileops.c
|
||||||
|
@@ -57,7 +57,7 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do)
|
||||||
|
char mb_buf[MB_LEN_MAX];
|
||||||
|
char *write_base, *write_ptr, *buf_end;
|
||||||
|
|
||||||
|
- if (fp->_IO_write_ptr - fp->_IO_write_base < sizeof (mb_buf))
|
||||||
|
+ if (fp->_IO_buf_end - fp->_IO_write_ptr < sizeof (mb_buf))
|
||||||
|
{
|
||||||
|
/* Make sure we have room for at least one multibyte
|
||||||
|
character. */
|
@ -0,0 +1,369 @@
|
|||||||
|
From 317f1c0a8a71a862b1e600ff5386b08e02cf4b95 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||||
|
Date: Thu, 26 Jan 2023 08:26:18 -0800
|
||||||
|
Subject: [PATCH] x86-64: Add glibc.cpu.prefer_map_32bit_exec [BZ #28656]
|
||||||
|
Content-type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
Crossing 2GB boundaries with indirect calls and jumps can use more
|
||||||
|
branch prediction resources on Intel Golden Cove CPU (see the
|
||||||
|
"Misprediction for Branches >2GB" section in Intel 64 and IA-32
|
||||||
|
Architectures Optimization Reference Manual.) There is visible
|
||||||
|
performance improvement on workloads with many PLT calls when executable
|
||||||
|
and shared libraries are mmapped below 2GB. Add the Prefer_MAP_32BIT_EXEC
|
||||||
|
bit so that mmap will try to map executable or denywrite pages in shared
|
||||||
|
libraries with MAP_32BIT first.
|
||||||
|
|
||||||
|
NB: Prefer_MAP_32BIT_EXEC reduces bits available for address space
|
||||||
|
layout randomization (ASLR), which is always disabled for SUID programs
|
||||||
|
and can only be enabled by the tunable, glibc.cpu.prefer_map_32bit_exec,
|
||||||
|
or the environment variable, LD_PREFER_MAP_32BIT_EXEC. This works only
|
||||||
|
between shared libraries or between shared libraries and executables with
|
||||||
|
addresses below 2GB. PIEs are usually loaded at a random address above
|
||||||
|
4GB by the kernel.
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
manual/tunables.texi
|
||||||
|
(line numbers)
|
||||||
|
sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list
|
||||||
|
(merged local @order list)
|
||||||
|
sysdeps/x86/cpu-features.c
|
||||||
|
(line numbers)
|
||||||
|
|
||||||
|
---
|
||||||
|
manual/tunables.texi | 33 ++++++++++----
|
||||||
|
sysdeps/unix/sysv/linux/x86_64/64/Makefile | 25 +++++++++++
|
||||||
|
.../sysv/linux/x86_64/64/dl-tunables.list | 29 +++++++++++++
|
||||||
|
.../unix/sysv/linux/x86_64/64/mmap_internal.h | 43 +++++++++++++++++++
|
||||||
|
.../sysv/linux/x86_64/64/tst-map-32bit-1a.c | 34 +++++++++++++++
|
||||||
|
.../sysv/linux/x86_64/64/tst-map-32bit-1b.c | 1 +
|
||||||
|
.../sysv/linux/x86_64/64/tst-map-32bit-mod.c | 33 ++++++++++++++
|
||||||
|
sysdeps/x86/cpu-features.c | 15 +++++++
|
||||||
|
...cpu-features-preferred_feature_index_1.def | 1 +
|
||||||
|
9 files changed, 205 insertions(+), 9 deletions(-)
|
||||||
|
create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list
|
||||||
|
create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h
|
||||||
|
create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-1a.c
|
||||||
|
create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-1b.c
|
||||||
|
create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-mod.c
|
||||||
|
|
||||||
|
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||||
|
index 0be7231e36..c76c5c53cd 100644
|
||||||
|
--- a/manual/tunables.texi
|
||||||
|
+++ b/manual/tunables.texi
|
||||||
|
@@ -35,27 +35,32 @@ tunables with minimum and maximum values:
|
||||||
|
@example
|
||||||
|
$ /lib64/ld-linux-x86-64.so.2 --list-tunables
|
||||||
|
glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
|
||||||
|
-glibc.elision.skip_lock_after_retries: 3 (min: -2147483648, max: 2147483647)
|
||||||
|
+glibc.elision.skip_lock_after_retries: 3 (min: 0, max: 2147483647)
|
||||||
|
glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
glibc.malloc.perturb: 0 (min: 0, max: 255)
|
||||||
|
glibc.cpu.x86_shared_cache_size: 0x100000 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
+glibc.pthread.rseq: 1 (min: 0, max: 1)
|
||||||
|
+glibc.cpu.prefer_map_32bit_exec: 0 (min: 0, max: 1)
|
||||||
|
glibc.mem.tagging: 0 (min: 0, max: 255)
|
||||||
|
-glibc.elision.tries: 3 (min: -2147483648, max: 2147483647)
|
||||||
|
+glibc.elision.tries: 3 (min: 0, max: 2147483647)
|
||||||
|
glibc.elision.enable: 0 (min: 0, max: 1)
|
||||||
|
-glibc.cpu.x86_rep_movsb_threshold: 0x1000 (min: 0x100, max: 0xffffffffffffffff)
|
||||||
|
+glibc.malloc.hugetlb: 0x0 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
+glibc.cpu.x86_rep_movsb_threshold: 0x2000 (min: 0x100, max: 0xffffffffffffffff)
|
||||||
|
glibc.malloc.mxfast: 0x0 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
-glibc.elision.skip_lock_busy: 3 (min: -2147483648, max: 2147483647)
|
||||||
|
-glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
+glibc.rtld.dynamic_sort: 2 (min: 1, max: 2)
|
||||||
|
+glibc.elision.skip_lock_busy: 3 (min: 0, max: 2147483647)
|
||||||
|
+glibc.malloc.top_pad: 0x20000 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
glibc.cpu.x86_rep_stosb_threshold: 0x800 (min: 0x1, max: 0xffffffffffffffff)
|
||||||
|
-glibc.cpu.x86_non_temporal_threshold: 0xc0000 (min: 0x4040, max: 0x0fffffffffffffff)
|
||||||
|
+glibc.cpu.x86_non_temporal_threshold: 0xc0000 (min: 0x4040, max: 0xfffffffffffffff)
|
||||||
|
glibc.cpu.x86_shstk:
|
||||||
|
+glibc.pthread.stack_cache_size: 0x2800000 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
glibc.cpu.hwcap_mask: 0x6 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
-glibc.malloc.mmap_max: 0 (min: -2147483648, max: 2147483647)
|
||||||
|
-glibc.elision.skip_trylock_internal_abort: 3 (min: -2147483648, max: 2147483647)
|
||||||
|
+glibc.malloc.mmap_max: 0 (min: 0, max: 2147483647)
|
||||||
|
+glibc.elision.skip_trylock_internal_abort: 3 (min: 0, max: 2147483647)
|
||||||
|
glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
glibc.cpu.x86_ibt:
|
||||||
|
glibc.cpu.hwcaps:
|
||||||
|
-glibc.elision.skip_lock_internal_abort: 3 (min: -2147483648, max: 2147483647)
|
||||||
|
+glibc.elision.skip_lock_internal_abort: 3 (min: 0, max: 2147483647)
|
||||||
|
glibc.malloc.arena_max: 0x0 (min: 0x1, max: 0xffffffffffffffff)
|
||||||
|
glibc.malloc.mmap_threshold: 0x0 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
glibc.cpu.x86_data_cache_size: 0x8000 (min: 0x0, max: 0xffffffffffffffff)
|
||||||
|
@@ -569,6 +574,16 @@ instead.
|
||||||
|
This tunable is specific to i386 and x86-64.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
+@deftp Tunable glibc.cpu.prefer_map_32bit_exec
|
||||||
|
+When this tunable is set to \code{1}, shared libraries of non-setuid
|
||||||
|
+programs will be loaded below 2GB with MAP_32BIT.
|
||||||
|
+
|
||||||
|
+Note that the @env{LD_PREFER_MAP_32BIT_EXEC} environment is an alias of
|
||||||
|
+this tunable.
|
||||||
|
+
|
||||||
|
+This tunable is specific to 64-bit x86-64.
|
||||||
|
+@end deftp
|
||||||
|
+
|
||||||
|
@node Memory Related Tunables
|
||||||
|
@section Memory Related Tunables
|
||||||
|
@cindex memory related tunables
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/Makefile b/sysdeps/unix/sysv/linux/x86_64/64/Makefile
|
||||||
|
index a7b6dc5a53..8ff4f27786 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/64/Makefile
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/Makefile
|
||||||
|
@@ -1,2 +1,27 @@
|
||||||
|
# The default ABI is 64.
|
||||||
|
default-abi := 64
|
||||||
|
+
|
||||||
|
+ifeq ($(subdir),elf)
|
||||||
|
+ifneq ($(have-tunables),no)
|
||||||
|
+
|
||||||
|
+tests-map-32bit = \
|
||||||
|
+ tst-map-32bit-1a \
|
||||||
|
+ tst-map-32bit-1b \
|
||||||
|
+# tests-map-32bit
|
||||||
|
+tst-map-32bit-1a-no-pie = yes
|
||||||
|
+tst-map-32bit-1b-no-pie = yes
|
||||||
|
+tests += $(tests-map-32bit)
|
||||||
|
+
|
||||||
|
+modules-map-32bit = \
|
||||||
|
+ tst-map-32bit-mod \
|
||||||
|
+# modules-map-32bit
|
||||||
|
+modules-names += $(modules-map-32bit)
|
||||||
|
+
|
||||||
|
+$(objpfx)tst-map-32bit-mod.so: $(libsupport)
|
||||||
|
+tst-map-32bit-1a-ENV = LD_PREFER_MAP_32BIT_EXEC=1
|
||||||
|
+$(objpfx)tst-map-32bit-1a: $(objpfx)tst-map-32bit-mod.so
|
||||||
|
+tst-map-32bit-1b-ENV = GLIBC_TUNABLES=glibc.cpu.prefer_map_32bit_exec=1
|
||||||
|
+$(objpfx)tst-map-32bit-1b: $(objpfx)tst-map-32bit-mod.so
|
||||||
|
+
|
||||||
|
+endif
|
||||||
|
+endif
|
||||||
|
diff -rup a/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list 2024-03-06 17:52:50.968514369 -0500
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list 2024-03-06 17:55:48.778264896 -0500
|
||||||
|
@@ -1,3 +1,33 @@
|
||||||
|
+# x86-64 specific tunables.
|
||||||
|
+# Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+# This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+# The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+# modify it under the terms of the GNU Lesser General Public
|
||||||
|
+# License as published by the Free Software Foundation; either
|
||||||
|
+# version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+# The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+# Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+# You should have received a copy of the GNU Lesser General Public
|
||||||
|
+# License along with the GNU C Library; if not, see
|
||||||
|
+# <https://www.gnu.org/licenses/>.
|
||||||
|
+
|
||||||
|
+glibc {
|
||||||
|
+ cpu {
|
||||||
|
+ prefer_map_32bit_exec {
|
||||||
|
+ type: INT_32
|
||||||
|
+ minval: 0
|
||||||
|
+ maxval: 1
|
||||||
|
+ env_alias: LD_PREFER_MAP_32BIT_EXEC
|
||||||
|
+ security_level: SXID_IGNORE
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
# Order of tunables in RHEL 9.1.z.
|
||||||
|
@order glibc.rtld.nns
|
||||||
|
@order glibc.elision.skip_lock_after_retries
|
||||||
|
@@ -35,3 +65,5 @@
|
||||||
|
@order glibc.malloc.check
|
||||||
|
@order glibc.gmon.minarcs
|
||||||
|
@order glibc.gmon.maxarcs
|
||||||
|
+# Order of tunables in RHEL 9.5.z
|
||||||
|
+@order glibc.cpu.prefer_map_32bit_exec
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h b/sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..33dec3f805
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h
|
||||||
|
@@ -0,0 +1,43 @@
|
||||||
|
+/* Linux mmap system call. x86-64 version.
|
||||||
|
+ Copyright (C) 2015-2023 Free Software Foundation, Inc.
|
||||||
|
+
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public License as
|
||||||
|
+ published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
+ License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have 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 MMAP_X86_64_INTERNAL_H
|
||||||
|
+#define MMAP_X86_64_INTERNAL_H
|
||||||
|
+
|
||||||
|
+#include <ldsodefs.h>
|
||||||
|
+
|
||||||
|
+/* If the Prefer_MAP_32BIT_EXEC bit is set, try to map executable or
|
||||||
|
+ denywrite pages with MAP_32BIT first. */
|
||||||
|
+#define MMAP_PREPARE(addr, len, prot, flags, fd, offset) \
|
||||||
|
+ if ((addr) == NULL \
|
||||||
|
+ && (((prot) & PROT_EXEC) != 0 \
|
||||||
|
+ || ((flags) & MAP_DENYWRITE) != 0) \
|
||||||
|
+ && HAS_ARCH_FEATURE (Prefer_MAP_32BIT_EXEC)) \
|
||||||
|
+ { \
|
||||||
|
+ void *ret = (void*) INLINE_SYSCALL_CALL (mmap, (addr), (len), \
|
||||||
|
+ (prot), \
|
||||||
|
+ (flags) | MAP_32BIT, \
|
||||||
|
+ (fd), (offset)); \
|
||||||
|
+ if (ret != MAP_FAILED) \
|
||||||
|
+ return ret; \
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#include_next <mmap_internal.h>
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-1a.c b/sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-1a.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..abc396589e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-1a.c
|
||||||
|
@@ -0,0 +1,34 @@
|
||||||
|
+/* Check that LD_PREFER_MAP_32BIT_EXEC works in PDE and shared library.
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have 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 <stdint.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+extern void dso_check_map_32bit (void);
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ printf ("do_test: %p\n", do_test);
|
||||||
|
+ TEST_VERIFY ((uintptr_t) do_test < 0xffffffffUL);
|
||||||
|
+ dso_check_map_32bit ();
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-1b.c b/sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-1b.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..34ab01c773
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-1b.c
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+#include "tst-map-32bit-1a.c"
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-mod.c b/sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..78d4b6133c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/tst-map-32bit-mod.c
|
||||||
|
@@ -0,0 +1,33 @@
|
||||||
|
+/* Check that LD_PREFER_MAP_32BIT_EXEC works in shared library.
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have 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 <stdint.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+dso_do_test (void)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dso_check_map_32bit (void)
|
||||||
|
+{
|
||||||
|
+ printf ("dso_do_test: %p\n", dso_do_test);
|
||||||
|
+ TEST_VERIFY ((uintptr_t) dso_do_test < 0xffffffffUL);
|
||||||
|
+}
|
||||||
|
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
|
||||||
|
index a2197ed211..822688e21f 100644
|
||||||
|
--- a/sysdeps/x86/cpu-features.c
|
||||||
|
+++ b/sysdeps/x86/cpu-features.c
|
||||||
|
@@ -27,6 +27,16 @@
|
||||||
|
extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
+# ifdef __LP64__
|
||||||
|
+static void
|
||||||
|
+TUNABLE_CALLBACK (set_prefer_map_32bit_exec) (tunable_val_t *valp)
|
||||||
|
+{
|
||||||
|
+ if (valp->numval)
|
||||||
|
+ GLRO(dl_x86_cpu_features).preferred[index_arch_Prefer_MAP_32BIT_EXEC]
|
||||||
|
+ |= bit_arch_Prefer_MAP_32BIT_EXEC;
|
||||||
|
+}
|
||||||
|
+# endif
|
||||||
|
+
|
||||||
|
# if CET_ENABLED
|
||||||
|
extern void TUNABLE_CALLBACK (set_x86_ibt) (tunable_val_t *)
|
||||||
|
attribute_hidden;
|
||||||
|
@@ -949,6 +959,11 @@ no_cpuid:
|
||||||
|
#if HAVE_TUNABLES
|
||||||
|
TUNABLE_GET (hwcaps, tunable_val_t *, TUNABLE_CALLBACK (set_hwcaps));
|
||||||
|
|
||||||
|
+# ifdef __LP64__
|
||||||
|
+ TUNABLE_GET (prefer_map_32bit_exec, tunable_val_t *,
|
||||||
|
+ TUNABLE_CALLBACK (set_prefer_map_32bit_exec));
|
||||||
|
+# endif
|
||||||
|
+
|
||||||
|
bool disable_xsave_features = false;
|
||||||
|
|
||||||
|
if (!CPU_FEATURE_USABLE_P (cpu_features, OSXSAVE))
|
||||||
|
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 e45f9cb159..d20c5b3196 100644
|
||||||
|
--- a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||||
|
+++ b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||||
|
@@ -26,6 +26,7 @@ BIT (I586)
|
||||||
|
BIT (I686)
|
||||||
|
BIT (Slow_SSE4_2)
|
||||||
|
BIT (AVX_Fast_Unaligned_Load)
|
||||||
|
+BIT (Prefer_MAP_32BIT_EXEC)
|
||||||
|
BIT (Prefer_No_VZEROUPPER)
|
||||||
|
BIT (Prefer_ERMS)
|
||||||
|
BIT (Prefer_No_AVX512)
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From 188ecdb7774145050a6e167a277f45f03dac5fe8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||||
|
Date: Wed, 22 Feb 2023 20:04:26 -0800
|
||||||
|
Subject: [PATCH] tunables.texi: Change \code{1} to @code{1}
|
||||||
|
Content-type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
Update
|
||||||
|
|
||||||
|
317f1c0a8a x86-64: Add glibc.cpu.prefer_map_32bit_exec [BZ #28656]
|
||||||
|
---
|
||||||
|
manual/tunables.texi | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||||
|
index c76c5c53cd..70dd2264c5 100644
|
||||||
|
--- a/manual/tunables.texi
|
||||||
|
+++ b/manual/tunables.texi
|
||||||
|
@@ -589,7 +589,7 @@ This tunable is specific to i386 and x86-64.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp Tunable glibc.cpu.prefer_map_32bit_exec
|
||||||
|
-When this tunable is set to \code{1}, shared libraries of non-setuid
|
||||||
|
+When this tunable is set to @code{1}, shared libraries of non-setuid
|
||||||
|
programs will be loaded below 2GB with MAP_32BIT.
|
||||||
|
|
||||||
|
Note that the @env{LD_PREFER_MAP_32BIT_EXEC} environment is an alias of
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
@ -0,0 +1,317 @@
|
|||||||
|
commit d2123d68275acc0f061e73d5f86ca504e0d5a344
|
||||||
|
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
Date: Tue Feb 16 12:55:13 2021 +0000
|
||||||
|
|
||||||
|
elf: Fix slow tls access after dlopen [BZ #19924]
|
||||||
|
|
||||||
|
In short: __tls_get_addr checks the global generation counter and if
|
||||||
|
the current dtv is older then _dl_update_slotinfo updates dtv up to the
|
||||||
|
generation of the accessed module. So if the global generation is newer
|
||||||
|
than generation of the module then __tls_get_addr keeps hitting the
|
||||||
|
slow dtv update path. The dtv update path includes a number of checks
|
||||||
|
to see if any update is needed and this already causes measurable tls
|
||||||
|
access slow down after dlopen.
|
||||||
|
|
||||||
|
It may be possible to detect up-to-date dtv faster. But if there are
|
||||||
|
many modules loaded (> TLS_SLOTINFO_SURPLUS) then this requires at
|
||||||
|
least walking the slotinfo list.
|
||||||
|
|
||||||
|
This patch tries to update the dtv to the global generation instead, so
|
||||||
|
after a dlopen the tls access slow path is only hit once. The modules
|
||||||
|
with larger generation than the accessed one were not necessarily
|
||||||
|
synchronized before, so additional synchronization is needed.
|
||||||
|
|
||||||
|
This patch uses acquire/release synchronization when accessing the
|
||||||
|
generation counter.
|
||||||
|
|
||||||
|
Note: in the x86_64 version of dl-tls.c the generation is only loaded
|
||||||
|
once, since relaxed mo is not faster than acquire mo load.
|
||||||
|
|
||||||
|
I have not benchmarked this. Tested by Adhemerval Zanella on aarch64,
|
||||||
|
powerpc, sparc, x86 who reported that it fixes the performance issue
|
||||||
|
of bug 19924.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||||
|
index 985cd4e2821436af..95a03c9616c6a786 100644
|
||||||
|
--- a/elf/dl-close.c
|
||||||
|
+++ b/elf/dl-close.c
|
||||||
|
@@ -739,7 +739,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
if (__glibc_unlikely (newgen == 0))
|
||||||
|
_dl_fatal_printf ("TLS generation counter wrapped! Please report as described in "REPORT_BUGS_TO".\n");
|
||||||
|
/* Can be read concurrently. */
|
||||||
|
- atomic_store_relaxed (&GL(dl_tls_generation), newgen);
|
||||||
|
+ atomic_store_release (&GL(dl_tls_generation), newgen);
|
||||||
|
|
||||||
|
if (tls_free_end == GL(dl_tls_static_used))
|
||||||
|
GL(dl_tls_static_used) = tls_free_start;
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index 633b047ad2497296..c8a5d88161441031 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -404,7 +404,7 @@ update_tls_slotinfo (struct link_map *new)
|
||||||
|
_dl_fatal_printf (N_("\
|
||||||
|
TLS generation counter wrapped! Please report this."));
|
||||||
|
/* Can be read concurrently. */
|
||||||
|
- atomic_store_relaxed (&GL(dl_tls_generation), newgen);
|
||||||
|
+ atomic_store_release (&GL(dl_tls_generation), newgen);
|
||||||
|
|
||||||
|
/* We need a second pass for static tls data, because
|
||||||
|
_dl_update_slotinfo must not be run while calls to
|
||||||
|
@@ -421,8 +421,8 @@ TLS generation counter wrapped! Please report this."));
|
||||||
|
now, but we can delay updating the DTV. */
|
||||||
|
imap->l_need_tls_init = 0;
|
||||||
|
#ifdef SHARED
|
||||||
|
- /* Update the slot information data for at least the
|
||||||
|
- generation of the DSO we are allocating data for. */
|
||||||
|
+ /* Update the slot information data for the current
|
||||||
|
+ generation. */
|
||||||
|
|
||||||
|
/* FIXME: This can terminate the process on memory
|
||||||
|
allocation failure. It is not possible to raise
|
||||||
|
@@ -430,7 +430,7 @@ TLS generation counter wrapped! Please report this."));
|
||||||
|
_dl_update_slotinfo would have to be split into two
|
||||||
|
operations, similar to resize_scopes and update_scopes
|
||||||
|
above. This is related to bug 16134. */
|
||||||
|
- _dl_update_slotinfo (imap->l_tls_modid);
|
||||||
|
+ _dl_update_slotinfo (imap->l_tls_modid, newgen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dl_init_static_tls (imap);
|
||||||
|
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
|
||||||
|
index 5b69321bda1f2b27..be3e09e36835ed23 100644
|
||||||
|
--- a/elf/dl-reloc.c
|
||||||
|
+++ b/elf/dl-reloc.c
|
||||||
|
@@ -111,11 +111,11 @@ _dl_try_allocate_static_tls (struct link_map *map, bool optional)
|
||||||
|
if (map->l_real->l_relocated)
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
+ /* Update the DTV of the current thread. Note: GL(dl_load_tls_lock)
|
||||||
|
+ is held here so normal load of the generation counter is valid. */
|
||||||
|
if (__builtin_expect (THREAD_DTV()[0].counter != GL(dl_tls_generation),
|
||||||
|
0))
|
||||||
|
- /* Update the slot information data for at least the generation of
|
||||||
|
- the DSO we are allocating data for. */
|
||||||
|
- (void) _dl_update_slotinfo (map->l_tls_modid);
|
||||||
|
+ (void) _dl_update_slotinfo (map->l_tls_modid, GL(dl_tls_generation));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dl_init_static_tls (map);
|
||||||
|
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||||
|
index fab6546e2d31edd4..b8ada16f1637c910 100644
|
||||||
|
--- a/elf/dl-tls.c
|
||||||
|
+++ b/elf/dl-tls.c
|
||||||
|
@@ -721,57 +721,57 @@ allocate_and_init (struct link_map *map)
|
||||||
|
|
||||||
|
|
||||||
|
struct link_map *
|
||||||
|
-_dl_update_slotinfo (unsigned long int req_modid)
|
||||||
|
+_dl_update_slotinfo (unsigned long int req_modid, size_t new_gen)
|
||||||
|
{
|
||||||
|
struct link_map *the_map = NULL;
|
||||||
|
dtv_t *dtv = THREAD_DTV ();
|
||||||
|
|
||||||
|
- /* The global dl_tls_dtv_slotinfo array contains for each module
|
||||||
|
- index the generation counter current when the entry was created.
|
||||||
|
+ /* CONCURRENCY NOTES:
|
||||||
|
+
|
||||||
|
+ The global dl_tls_dtv_slotinfo_list array contains for each module
|
||||||
|
+ index the generation counter current when that entry was updated.
|
||||||
|
This array never shrinks so that all module indices which were
|
||||||
|
- valid at some time can be used to access it. Before the first
|
||||||
|
- use of a new module index in this function the array was extended
|
||||||
|
- appropriately. Access also does not have to be guarded against
|
||||||
|
- modifications of the array. It is assumed that pointer-size
|
||||||
|
- values can be read atomically even in SMP environments. It is
|
||||||
|
- possible that other threads at the same time dynamically load
|
||||||
|
- code and therefore add to the slotinfo list. This is a problem
|
||||||
|
- since we must not pick up any information about incomplete work.
|
||||||
|
- The solution to this is to ignore all dtv slots which were
|
||||||
|
- created after the one we are currently interested. We know that
|
||||||
|
- dynamic loading for this module is completed and this is the last
|
||||||
|
- load operation we know finished. */
|
||||||
|
- unsigned long int idx = req_modid;
|
||||||
|
+ valid at some time can be used to access it. Concurrent loading
|
||||||
|
+ and unloading of modules can update slotinfo entries or extend
|
||||||
|
+ the array. The updates happen under the GL(dl_load_tls_lock) and
|
||||||
|
+ finish with the release store of the generation counter to
|
||||||
|
+ GL(dl_tls_generation) which is synchronized with the load of
|
||||||
|
+ new_gen in the caller. So updates up to new_gen are synchronized
|
||||||
|
+ but updates for later generations may not be.
|
||||||
|
+
|
||||||
|
+ Here we update the thread dtv from old_gen (== dtv[0].counter) to
|
||||||
|
+ new_gen generation. For this, each dtv[i] entry is either set to
|
||||||
|
+ an unallocated state (set), or left unmodified (nop). Where (set)
|
||||||
|
+ may resize the dtv first if modid i >= dtv[-1].counter. The rules
|
||||||
|
+ for the decision between (set) and (nop) are
|
||||||
|
+
|
||||||
|
+ (1) If slotinfo entry i is concurrently updated then either (set)
|
||||||
|
+ or (nop) is valid: TLS access cannot use dtv[i] unless it is
|
||||||
|
+ synchronized with a generation > new_gen.
|
||||||
|
+
|
||||||
|
+ Otherwise, if the generation of slotinfo entry i is gen and the
|
||||||
|
+ loaded module for this entry is map then
|
||||||
|
+
|
||||||
|
+ (2) If gen <= old_gen then do (nop).
|
||||||
|
+
|
||||||
|
+ (3) If old_gen < gen <= new_gen then
|
||||||
|
+ (3.1) if map != 0 then (set)
|
||||||
|
+ (3.2) if map == 0 then either (set) or (nop).
|
||||||
|
+
|
||||||
|
+ Note that (1) cannot be reliably detected, but since both actions
|
||||||
|
+ are valid it does not have to be. Only (2) and (3.1) cases need
|
||||||
|
+ to be distinguished for which relaxed mo access of gen and map is
|
||||||
|
+ enough: their value is synchronized when it matters.
|
||||||
|
+
|
||||||
|
+ Note that a relaxed mo load may give an out-of-thin-air value since
|
||||||
|
+ it is used in decisions that can affect concurrent stores. But this
|
||||||
|
+ should only happen if the OOTA value causes UB that justifies the
|
||||||
|
+ concurrent store of the value. This is not expected to be an issue
|
||||||
|
+ in practice. */
|
||||||
|
struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list);
|
||||||
|
|
||||||
|
- while (idx >= listp->len)
|
||||||
|
+ if (dtv[0].counter < new_gen)
|
||||||
|
{
|
||||||
|
- idx -= listp->len;
|
||||||
|
- listp = listp->next;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (dtv[0].counter < listp->slotinfo[idx].gen)
|
||||||
|
- {
|
||||||
|
- /* CONCURRENCY NOTES:
|
||||||
|
-
|
||||||
|
- Here the dtv needs to be updated to new_gen generation count.
|
||||||
|
-
|
||||||
|
- This code may be called during TLS access when GL(dl_load_tls_lock)
|
||||||
|
- is not held. In that case the user code has to synchronize with
|
||||||
|
- dlopen and dlclose calls of relevant modules. A module m is
|
||||||
|
- relevant if the generation of m <= new_gen and dlclose of m is
|
||||||
|
- synchronized: a memory access here happens after the dlopen and
|
||||||
|
- before the dlclose of relevant modules. The dtv entries for
|
||||||
|
- relevant modules need to be updated, other entries can be
|
||||||
|
- arbitrary.
|
||||||
|
-
|
||||||
|
- This e.g. means that the first part of the slotinfo list can be
|
||||||
|
- accessed race free, but the tail may be concurrently extended.
|
||||||
|
- Similarly relevant slotinfo entries can be read race free, but
|
||||||
|
- other entries are racy. However updating a non-relevant dtv
|
||||||
|
- entry does not affect correctness. For a relevant module m,
|
||||||
|
- max_modid >= modid of m. */
|
||||||
|
- size_t new_gen = listp->slotinfo[idx].gen;
|
||||||
|
size_t total = 0;
|
||||||
|
size_t max_modid = atomic_load_relaxed (&GL(dl_tls_max_dtv_idx));
|
||||||
|
assert (max_modid >= req_modid);
|
||||||
|
@@ -784,31 +784,33 @@ _dl_update_slotinfo (unsigned long int req_modid)
|
||||||
|
{
|
||||||
|
size_t modid = total + cnt;
|
||||||
|
|
||||||
|
- /* Later entries are not relevant. */
|
||||||
|
+ /* Case (1) for all later modids. */
|
||||||
|
if (modid > max_modid)
|
||||||
|
break;
|
||||||
|
|
||||||
|
size_t gen = atomic_load_relaxed (&listp->slotinfo[cnt].gen);
|
||||||
|
|
||||||
|
+ /* Case (1). */
|
||||||
|
if (gen > new_gen)
|
||||||
|
- /* Not relevant. */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- /* If the entry is older than the current dtv layout we
|
||||||
|
- know we don't have to handle it. */
|
||||||
|
+ /* Case (2) or (1). */
|
||||||
|
if (gen <= dtv[0].counter)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ /* Case (3) or (1). */
|
||||||
|
+
|
||||||
|
/* If there is no map this means the entry is empty. */
|
||||||
|
struct link_map *map
|
||||||
|
= atomic_load_relaxed (&listp->slotinfo[cnt].map);
|
||||||
|
/* Check whether the current dtv array is large enough. */
|
||||||
|
if (dtv[-1].counter < modid)
|
||||||
|
{
|
||||||
|
+ /* Case (3.2) or (1). */
|
||||||
|
if (map == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- /* Resize the dtv. */
|
||||||
|
+ /* Resizing the dtv aborts on failure: bug 16134. */
|
||||||
|
dtv = _dl_resize_dtv (dtv, max_modid);
|
||||||
|
|
||||||
|
assert (modid <= dtv[-1].counter);
|
||||||
|
@@ -819,7 +821,7 @@ _dl_update_slotinfo (unsigned long int req_modid)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there is currently memory allocate for this
|
||||||
|
- dtv entry free it. */
|
||||||
|
+ dtv entry free it. Note: this is not AS-safe. */
|
||||||
|
/* XXX Ideally we will at some point create a memory
|
||||||
|
pool. */
|
||||||
|
free (dtv[modid].pointer.to_free);
|
||||||
|
@@ -914,9 +916,9 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
|
||||||
|
|
||||||
|
static struct link_map *
|
||||||
|
__attribute_noinline__
|
||||||
|
-update_get_addr (GET_ADDR_ARGS)
|
||||||
|
+update_get_addr (GET_ADDR_ARGS, size_t gen)
|
||||||
|
{
|
||||||
|
- struct link_map *the_map = _dl_update_slotinfo (GET_ADDR_MODULE);
|
||||||
|
+ struct link_map *the_map = _dl_update_slotinfo (GET_ADDR_MODULE, gen);
|
||||||
|
dtv_t *dtv = THREAD_DTV ();
|
||||||
|
|
||||||
|
void *p = dtv[GET_ADDR_MODULE].pointer.val;
|
||||||
|
@@ -946,12 +948,17 @@ __tls_get_addr (GET_ADDR_ARGS)
|
||||||
|
dtv_t *dtv = THREAD_DTV ();
|
||||||
|
|
||||||
|
/* Update is needed if dtv[0].counter < the generation of the accessed
|
||||||
|
- module. The global generation counter is used here as it is easier
|
||||||
|
- to check. Synchronization for the relaxed MO access is guaranteed
|
||||||
|
- by user code, see CONCURRENCY NOTES in _dl_update_slotinfo. */
|
||||||
|
+ module, but the global generation counter is easier to check (which
|
||||||
|
+ must be synchronized up to the generation of the accessed module by
|
||||||
|
+ user code doing the TLS access so relaxed mo read is enough). */
|
||||||
|
size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
|
||||||
|
if (__glibc_unlikely (dtv[0].counter != gen))
|
||||||
|
- return update_get_addr (GET_ADDR_PARAM);
|
||||||
|
+ {
|
||||||
|
+ /* Update DTV up to the global generation, see CONCURRENCY NOTES
|
||||||
|
+ in _dl_update_slotinfo. */
|
||||||
|
+ gen = atomic_load_acquire (&GL(dl_tls_generation));
|
||||||
|
+ return update_get_addr (GET_ADDR_PARAM, gen);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
void *p = dtv[GET_ADDR_MODULE].pointer.val;
|
||||||
|
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 8c0fe98f69a88f1e..7964e133e4930e88 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1304,7 +1304,8 @@ extern void _dl_add_to_slotinfo (struct link_map *l, bool do_add)
|
||||||
|
|
||||||
|
/* Update slot information data for at least the generation of the
|
||||||
|
module with the given index. */
|
||||||
|
-extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid)
|
||||||
|
+extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid,
|
||||||
|
+ size_t gen)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
/* Look up the module's TLS block as for __tls_get_addr,
|
||||||
|
diff --git a/sysdeps/x86_64/dl-tls.c b/sysdeps/x86_64/dl-tls.c
|
||||||
|
index 24ef560b718275a2..4ded8dd6b94edc81 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-tls.c
|
||||||
|
+++ b/sysdeps/x86_64/dl-tls.c
|
||||||
|
@@ -40,9 +40,9 @@ __tls_get_addr_slow (GET_ADDR_ARGS)
|
||||||
|
{
|
||||||
|
dtv_t *dtv = THREAD_DTV ();
|
||||||
|
|
||||||
|
- size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
|
||||||
|
+ size_t gen = atomic_load_acquire (&GL(dl_tls_generation));
|
||||||
|
if (__glibc_unlikely (dtv[0].counter != gen))
|
||||||
|
- return update_get_addr (GET_ADDR_PARAM);
|
||||||
|
+ return update_get_addr (GET_ADDR_PARAM, gen);
|
||||||
|
|
||||||
|
return tls_get_addr_tail (GET_ADDR_PARAM, dtv, NULL);
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
commit c06c8aeb61708249d8eb0b17a676d16771ea640b
|
||||||
|
Author: Dennis Brendel <dbrendel@redhat.com>
|
||||||
|
Date: Mon Jan 15 09:55:37 2024 +0100
|
||||||
|
|
||||||
|
manual: fix order of arguments of memalign and aligned_alloc (Bug 27547)
|
||||||
|
|
||||||
|
On the summary page the order of the function arguments was reversed, but it is
|
||||||
|
in correct order in the other places of the manual.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/manual/memory.texi b/manual/memory.texi
|
||||||
|
index fb875f4c3c..3710d7ec66 100644
|
||||||
|
--- a/manual/memory.texi
|
||||||
|
+++ b/manual/memory.texi
|
||||||
|
@@ -1502,7 +1502,7 @@ Space}.
|
||||||
|
Allocate a block of @var{size} bytes, starting on a page boundary.
|
||||||
|
@xref{Aligned Memory Blocks}.
|
||||||
|
|
||||||
|
-@item void *aligned_alloc (size_t @var{size}, size_t @var{alignment})
|
||||||
|
+@item void *aligned_alloc (size_t @var{alignment}, size_t @var{size})
|
||||||
|
Allocate a block of @var{size} bytes, starting on an address that is a
|
||||||
|
multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
|
||||||
|
|
||||||
|
@@ -1510,7 +1510,7 @@ multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
|
||||||
|
Allocate a block of @var{size} bytes, starting on an address that is a
|
||||||
|
multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
|
||||||
|
|
||||||
|
-@item void *memalign (size_t @var{size}, size_t @var{boundary})
|
||||||
|
+@item void *memalign (size_t @var{boundary}, size_t @var{size})
|
||||||
|
Allocate a block of @var{size} bytes, starting on an address that is a
|
||||||
|
multiple of @var{boundary}. @xref{Aligned Memory Blocks}.
|
||||||
|
|
@ -0,0 +1,73 @@
|
|||||||
|
commit 85860ad6eaf4c9739318f6b2a1ff7c2fa6b12ab5
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Aug 15 16:45:40 2022 +0200
|
||||||
|
|
||||||
|
malloc: Do not use MAP_NORESERVE to allocate heap segments
|
||||||
|
|
||||||
|
Address space for heap segments is reserved in a mmap call with
|
||||||
|
MAP_ANONYMOUS | MAP_PRIVATE and protection flags PROT_NONE. This
|
||||||
|
reservation does not count against the RSS limit of the process or
|
||||||
|
system. Backing memory is allocated using mprotect in alloc_new_heap
|
||||||
|
and grow_heap, and at this point, the allocator expects the kernel
|
||||||
|
to provide memory (subject to memory overcommit).
|
||||||
|
|
||||||
|
The SIGSEGV that might generate due to MAP_NORESERVE (according to
|
||||||
|
the mmap manual page) does not seem to occur in practice, it's always
|
||||||
|
SIGKILL from the OOM killer. Even if there is a way that SIGSEGV
|
||||||
|
could be generated, it is confusing to applications that this only
|
||||||
|
happens for secondary heaps, not for large mmap-based allocations,
|
||||||
|
and not for the main arena.
|
||||||
|
|
||||||
|
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
malloc/arena.c
|
||||||
|
(huge page support was added upstream)
|
||||||
|
|
||||||
|
diff --git a/malloc/arena.c b/malloc/arena.c
|
||||||
|
index 667484630ed0afa5..2852783355d3d869 100644
|
||||||
|
--- a/malloc/arena.c
|
||||||
|
+++ b/malloc/arena.c
|
||||||
|
@@ -466,8 +466,7 @@ new_heap (size_t size, size_t top_pad)
|
||||||
|
p2 = MAP_FAILED;
|
||||||
|
if (aligned_heap_area)
|
||||||
|
{
|
||||||
|
- p2 = (char *) MMAP (aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE,
|
||||||
|
- MAP_NORESERVE);
|
||||||
|
+ p2 = (char *) MMAP (aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE, 0);
|
||||||
|
aligned_heap_area = NULL;
|
||||||
|
if (p2 != MAP_FAILED && ((unsigned long) p2 & (HEAP_MAX_SIZE - 1)))
|
||||||
|
{
|
||||||
|
@@ -477,7 +476,7 @@ new_heap (size_t size, size_t top_pad)
|
||||||
|
}
|
||||||
|
if (p2 == MAP_FAILED)
|
||||||
|
{
|
||||||
|
- p1 = (char *) MMAP (0, HEAP_MAX_SIZE << 1, PROT_NONE, MAP_NORESERVE);
|
||||||
|
+ p1 = (char *) MMAP (0, HEAP_MAX_SIZE << 1, PROT_NONE, 0);
|
||||||
|
if (p1 != MAP_FAILED)
|
||||||
|
{
|
||||||
|
p2 = (char *) (((unsigned long) p1 + (HEAP_MAX_SIZE - 1))
|
||||||
|
@@ -493,7 +492,7 @@ new_heap (size_t size, size_t top_pad)
|
||||||
|
{
|
||||||
|
/* Try to take the chance that an allocation of only HEAP_MAX_SIZE
|
||||||
|
is already aligned. */
|
||||||
|
- p2 = (char *) MMAP (0, HEAP_MAX_SIZE, PROT_NONE, MAP_NORESERVE);
|
||||||
|
+ p2 = (char *) MMAP (0, HEAP_MAX_SIZE, PROT_NONE, 0);
|
||||||
|
if (p2 == MAP_FAILED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 375f50f5db13e234..fe80b8239756a7c9 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -1112,10 +1112,6 @@ static mchunkptr mremap_chunk(mchunkptr p, size_t new_size);
|
||||||
|
# define MAP_ANONYMOUS MAP_ANON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#ifndef MAP_NORESERVE
|
||||||
|
-# define MAP_NORESERVE 0
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
#define MMAP(addr, size, prot, flags) \
|
||||||
|
__mmap((addr), (size), (prot), (flags)|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0)
|
||||||
|
|
@ -0,0 +1,229 @@
|
|||||||
|
commit f21962ddfc8bb23e92597da1f98e313dbde11cc1
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Fri Aug 25 14:15:28 2023 +0200
|
||||||
|
|
||||||
|
manual: Document ld.so --list-diagnostics output
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/manual/dynlink.texi b/manual/dynlink.texi
|
||||||
|
index 45bf5a5b55..df41c56bfc 100644
|
||||||
|
--- a/manual/dynlink.texi
|
||||||
|
+++ b/manual/dynlink.texi
|
||||||
|
@@ -13,9 +13,216 @@ as plugins) later at run time.
|
||||||
|
Dynamic linkers are sometimes called @dfn{dynamic loaders}.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
+* Dynamic Linker Invocation:: Explicit invocation of the dynamic linker.
|
||||||
|
* Dynamic Linker Introspection:: Interfaces for querying mapping information.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
+@node Dynamic Linker Invocation
|
||||||
|
+
|
||||||
|
+@cindex program interpreter
|
||||||
|
+When a dynamically linked program starts, the operating system
|
||||||
|
+automatically loads the dynamic linker along with the program.
|
||||||
|
+@Theglibc{} also supports invoking the dynamic linker explicitly to
|
||||||
|
+launch a program. This command uses the implied dynamic linker
|
||||||
|
+(also sometimes called the @dfn{program interpreter}):
|
||||||
|
+
|
||||||
|
+@smallexample
|
||||||
|
+sh -c 'echo "Hello, world!"'
|
||||||
|
+@end smallexample
|
||||||
|
+
|
||||||
|
+This command specifies the dynamic linker explicitly:
|
||||||
|
+
|
||||||
|
+@smallexample
|
||||||
|
+ld.so /bin/sh -c 'echo "Hello, world!"'
|
||||||
|
+@end smallexample
|
||||||
|
+
|
||||||
|
+Note that @command{ld.so} does not search the @env{PATH} environment
|
||||||
|
+variable, so the full file name of the executable needs to be specified.
|
||||||
|
+
|
||||||
|
+The @command{ld.so} program supports various options. Options start
|
||||||
|
+@samp{--} and need to come before the program that is being launched.
|
||||||
|
+Some of the supported options are listed below.
|
||||||
|
+
|
||||||
|
+@table @code
|
||||||
|
+@item --list-diagnostics
|
||||||
|
+Print system diagnostic information in a machine-readable format.
|
||||||
|
+@xref{Dynamic Linker Diagnostics}.
|
||||||
|
+@end table
|
||||||
|
+
|
||||||
|
+@menu
|
||||||
|
+* Dynamic Linker Diagnostics:: Obtaining system diagnostic information.
|
||||||
|
+@end menu
|
||||||
|
+
|
||||||
|
+@node Dynamic Linker Diagnostics
|
||||||
|
+@section Dynamic Linker Diagnostics
|
||||||
|
+@cindex diagnostics (dynamic linker)
|
||||||
|
+
|
||||||
|
+The @samp{ld.so --list-diagnostics} produces machine-readable
|
||||||
|
+diagnostics output. This output contains system data that affects the
|
||||||
|
+behavior of @theglibc{}, and potentially application behavior as well.
|
||||||
|
+
|
||||||
|
+The exact set of diagnostic items can change between releases of
|
||||||
|
+@theglibc{}. The output format itself is not expected to change
|
||||||
|
+radically.
|
||||||
|
+
|
||||||
|
+The following table shows some example lines that can be written by the
|
||||||
|
+diagnostics command.
|
||||||
|
+
|
||||||
|
+@table @code
|
||||||
|
+@item dl_pagesize=0x1000
|
||||||
|
+The system page size is 4096 bytes.
|
||||||
|
+
|
||||||
|
+@item env[0x14]="LANG=en_US.UTF-8"
|
||||||
|
+This item indicates that the 21st environment variable at process
|
||||||
|
+startup contains a setting for @code{LANG}.
|
||||||
|
+
|
||||||
|
+@item env_filtered[0x22]="DISPLAY"
|
||||||
|
+The 35th environment variable is @code{DISPLAY}. Its value is not
|
||||||
|
+included in the output for privacy reasons because it is not recognized
|
||||||
|
+as harmless by the diagnostics code.
|
||||||
|
+
|
||||||
|
+@item path.prefix="/usr"
|
||||||
|
+This means that @theglibc{} was configured with @code{--prefix=/usr}.
|
||||||
|
+
|
||||||
|
+@item path.system_dirs[0x0]="/lib64/"
|
||||||
|
+@itemx path.system_dirs[0x1]="/usr/lib64/"
|
||||||
|
+The built-in dynamic linker search path contains two directories,
|
||||||
|
+@code{/lib64} and @code{/usr/lib64}.
|
||||||
|
+@end table
|
||||||
|
+
|
||||||
|
+@subsection Dynamic Linker Diagnostics Output Format
|
||||||
|
+
|
||||||
|
+As seen above, diagnostic lines assign values (integers or strings) to a
|
||||||
|
+sequence of labeled subscripts, separated by @samp{.}. Some subscripts
|
||||||
|
+have integer indices associated with them. The subscript indices are
|
||||||
|
+not necessarily contiguous or small, so an associative array should be
|
||||||
|
+used to store them. Currently, all integers fit into the 64-bit
|
||||||
|
+unsigned integer range. Every access path to a value has a fixed type
|
||||||
|
+(string or integer) independent of subscript index values. Likewise,
|
||||||
|
+whether a subscript is indexed does not depend on previous indices (but
|
||||||
|
+may depend on previous subscript labels).
|
||||||
|
+
|
||||||
|
+A syntax description in ABNF (RFC 5234) follows. Note that
|
||||||
|
+@code{%x30-39} denotes the range of decimal digits. Diagnostic output
|
||||||
|
+lines are expected to match the @code{line} production.
|
||||||
|
+
|
||||||
|
+@c ABNF-START
|
||||||
|
+@smallexample
|
||||||
|
+HEXDIG = %x30-39 / %x61-6f ; lowercase a-f only
|
||||||
|
+ALPHA = %x41-5a / %x61-7a / %x7f ; letters and underscore
|
||||||
|
+ALPHA-NUMERIC = ALPHA / %x30-39 / "_"
|
||||||
|
+DQUOTE = %x22 ; "
|
||||||
|
+
|
||||||
|
+; Numbers are always hexadecimal and use a 0x prefix.
|
||||||
|
+hex-value-prefix = %x30 %x78
|
||||||
|
+hex-value = hex-value-prefix 1*HEXDIG
|
||||||
|
+
|
||||||
|
+; Strings use octal escape sequences and \\, \".
|
||||||
|
+string-char = %x20-21 / %x23-5c / %x5d-7e ; printable but not "\
|
||||||
|
+string-quoted-octal = %x30-33 2*2%x30-37
|
||||||
|
+string-quoted = "\" ("\" / DQUOTE / string-quoted-octal)
|
||||||
|
+string-value = DQUOTE *(string-char / string-quoted) DQUOTE
|
||||||
|
+
|
||||||
|
+value = hex-value / string-value
|
||||||
|
+
|
||||||
|
+label = ALPHA *ALPHA-NUMERIC
|
||||||
|
+index = "[" hex-value "]"
|
||||||
|
+subscript = label [index]
|
||||||
|
+
|
||||||
|
+line = subscript *("." subscript) "=" value
|
||||||
|
+@end smallexample
|
||||||
|
+
|
||||||
|
+@subsection Dynamic Linker Diagnostics Values
|
||||||
|
+
|
||||||
|
+As mentioned above, the set of diagnostics may change between
|
||||||
|
+@theglibc{} releases. Nevertheless, the following table documents a few
|
||||||
|
+common diagnostic items. All numbers are in hexadecimal, with a
|
||||||
|
+@samp{0x} prefix.
|
||||||
|
+
|
||||||
|
+@table @code
|
||||||
|
+@item dl_dst_lib=@var{string}
|
||||||
|
+The @code{$LIB} dynamic string token expands to @var{string}.
|
||||||
|
+
|
||||||
|
+@cindex HWCAP (diagnostics)
|
||||||
|
+@item dl_hwcap=@var{integer}
|
||||||
|
+@itemx dl_hwcap2=@var{integer}
|
||||||
|
+The HWCAP and HWCAP2 values, as returned for @code{getauxval}, and as
|
||||||
|
+used in other places depending on the architecture.
|
||||||
|
+
|
||||||
|
+@cindex page size (diagnostics)
|
||||||
|
+@item dl_pagesize=@var{integer}
|
||||||
|
+The system page size is @var{integer} bytes.
|
||||||
|
+
|
||||||
|
+@item dl_platform=@var{string}
|
||||||
|
+The @code{$PLATFORM} dynamic string token expands to @var{string}.
|
||||||
|
+
|
||||||
|
+@item dso.libc=@var{string}
|
||||||
|
+This is the soname of the shared @code{libc} object that is part of
|
||||||
|
+@theglibc{}. On most architectures, this is @code{libc.so.6}.
|
||||||
|
+
|
||||||
|
+@item env[@var{index}]=@var{string}
|
||||||
|
+@itemx env_filtered[@var{index}]=@var{string}
|
||||||
|
+An environment variable from the process environment. The integer
|
||||||
|
+@var{index} is the array index in the environment array. Variables
|
||||||
|
+under @code{env} include the variable value after the @samp{=} (assuming
|
||||||
|
+that it was present), variables under @code{env_filtered} do not.
|
||||||
|
+
|
||||||
|
+@item path.prefix=@var{string}
|
||||||
|
+This indicates that @theglibc{} was configured using
|
||||||
|
+@samp{--prefix=@var{string}}.
|
||||||
|
+
|
||||||
|
+@item path.sysconfdir=@var{string}
|
||||||
|
+@Theglibc{} was configured (perhaps implicitly) with
|
||||||
|
+@samp{--sysconfdir=@var{string}} (typically @code{/etc}).
|
||||||
|
+
|
||||||
|
+@item path.system_dirs[@var{index}]=@var{string}
|
||||||
|
+These items list the elements of the built-in array that describes the
|
||||||
|
+default library search path. The value @var{string} is a directory file
|
||||||
|
+name with a trailing @samp{/}.
|
||||||
|
+
|
||||||
|
+@item path.rtld=@var{string}
|
||||||
|
+This string indicates the application binary interface (ABI) file name
|
||||||
|
+of the run-time dynamic linker.
|
||||||
|
+
|
||||||
|
+@item version.release="stable"
|
||||||
|
+@itemx version.release="development"
|
||||||
|
+The value @code{"stable"} indicates that this build of @theglibc{} is
|
||||||
|
+from a release branch. Releases labeled as @code{"development"} are
|
||||||
|
+unreleased development versions.
|
||||||
|
+
|
||||||
|
+@cindex version (diagnostics)
|
||||||
|
+@item version.version="@var{major}.@var{minor}"
|
||||||
|
+@itemx version.version="@var{major}.@var{minor}.9000"
|
||||||
|
+@Theglibc{} version. Development releases end in @samp{.9000}.
|
||||||
|
+
|
||||||
|
+@cindex auxiliary vector (diagnostics)
|
||||||
|
+@item auxv[@var{index}].a_type=@var{type}
|
||||||
|
+@itemx auxv[@var{index}].a_val=@var{integer}
|
||||||
|
+@itemx auxv[@var{index}].a_val_string=@var{string}
|
||||||
|
+An entry in the auxiliary vector (specific to Linux). The values
|
||||||
|
+@var{type} (an integer) and @var{integer} correspond to the members of
|
||||||
|
+@code{struct auxv}. If the value is a string, @code{a_val_string} is
|
||||||
|
+used instead of @code{a_val}, so that values have consistent types.
|
||||||
|
+
|
||||||
|
+The @code{AT_HWCAP} and @code{AT_HWCAP2} values in this output do not
|
||||||
|
+reflect adjustment by @theglibc{}.
|
||||||
|
+
|
||||||
|
+@item uname.sysname=@var{string}
|
||||||
|
+@itemx uname.nodename=@var{string}
|
||||||
|
+@itemx uname.release=@var{string}
|
||||||
|
+@itemx uname.version=@var{string}
|
||||||
|
+@itemx uname.machine=@var{string}
|
||||||
|
+@itemx uname.domain=@var{string}
|
||||||
|
+These Linux-specific items show the values of @code{struct utsname}, as
|
||||||
|
+reported by the @code{uname} function. @xref{Platform Type}.
|
||||||
|
+
|
||||||
|
+@cindex CPUID (diagnostics)
|
||||||
|
+@item x86.cpu_features.@dots{}
|
||||||
|
+These items are specific to the i386 and x86-64 architectures. They
|
||||||
|
+reflect supported CPU features and information on cache geometry, mostly
|
||||||
|
+collected using the @code{CPUID} instruction.
|
||||||
|
+@end table
|
||||||
|
+
|
||||||
|
@node Dynamic Linker Introspection
|
||||||
|
@section Dynamic Linker Introspection
|
||||||
|
|
@ -0,0 +1,74 @@
|
|||||||
|
commit d99609a3eb8bc96c3af841fd35294a679e0fea7f
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Wed Sep 6 18:37:21 2023 +0200
|
||||||
|
|
||||||
|
manual: Fix ld.so diagnostics menu/section structure
|
||||||
|
|
||||||
|
And shorten the section/node names a bit, so that the menu
|
||||||
|
entries become easier to read.
|
||||||
|
|
||||||
|
Texinfo 6.5 fails to process the previous structure:
|
||||||
|
|
||||||
|
./dynlink.texi:56: warning: node `Dynamic Linker Introspection' is
|
||||||
|
next for `Dynamic Linker Diagnostics' in sectioning but not in menu
|
||||||
|
./dynlink.texi:56: warning: node up `Dynamic Linker Diagnostics'
|
||||||
|
in menu `Dynamic Linker Invocation' and
|
||||||
|
in sectioning `Dynamic Linker' differ
|
||||||
|
./dynlink.texi:1: node `Dynamic Linker' lacks menu item for
|
||||||
|
`Dynamic Linker Diagnostics' despite being its Up target
|
||||||
|
./dynlink.texi:226: warning: node prev `Dynamic Linker Introspection' in menu `Dynamic Linker Invocation'
|
||||||
|
and in sectioning `Dynamic Linker Diagnostics' differ
|
||||||
|
|
||||||
|
Texinfo 7.0.2 does not report an error.
|
||||||
|
|
||||||
|
This fixes commit f21962ddfc8bb23e92597da1f98e313dbde11cc1
|
||||||
|
("manual: Document ld.so --list-diagnostics output").
|
||||||
|
|
||||||
|
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
|
||||||
|
diff --git a/manual/dynlink.texi b/manual/dynlink.texi
|
||||||
|
index df41c56bfc..06a6c15533 100644
|
||||||
|
--- a/manual/dynlink.texi
|
||||||
|
+++ b/manual/dynlink.texi
|
||||||
|
@@ -18,6 +18,7 @@ Dynamic linkers are sometimes called @dfn{dynamic loaders}.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Dynamic Linker Invocation
|
||||||
|
+@section Dynamic Linker Invocation
|
||||||
|
|
||||||
|
@cindex program interpreter
|
||||||
|
When a dynamically linked program starts, the operating system
|
||||||
|
@@ -54,7 +55,7 @@ Print system diagnostic information in a machine-readable format.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Dynamic Linker Diagnostics
|
||||||
|
-@section Dynamic Linker Diagnostics
|
||||||
|
+@subsection Dynamic Linker Diagnostics
|
||||||
|
@cindex diagnostics (dynamic linker)
|
||||||
|
|
||||||
|
The @samp{ld.so --list-diagnostics} produces machine-readable
|
||||||
|
@@ -90,7 +91,13 @@ The built-in dynamic linker search path contains two directories,
|
||||||
|
@code{/lib64} and @code{/usr/lib64}.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
-@subsection Dynamic Linker Diagnostics Output Format
|
||||||
|
+@menu
|
||||||
|
+* Dynamic Linker Diagnostics Format:: Format of ld.so output.
|
||||||
|
+* Dynamic Linker Diagnostics Values:: Data contain in ld.so output.
|
||||||
|
+@end menu
|
||||||
|
+
|
||||||
|
+@node Dynamic Linker Diagnostics Format
|
||||||
|
+@subsubsection Dynamic Linker Diagnostics Format
|
||||||
|
|
||||||
|
As seen above, diagnostic lines assign values (integers or strings) to a
|
||||||
|
sequence of labeled subscripts, separated by @samp{.}. Some subscripts
|
||||||
|
@@ -132,7 +139,8 @@ subscript = label [index]
|
||||||
|
line = subscript *("." subscript) "=" value
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
-@subsection Dynamic Linker Diagnostics Values
|
||||||
|
+@node Dynamic Linker Diagnostics Values
|
||||||
|
+@subsubsection Dynamic Linker Diagnostics Values
|
||||||
|
|
||||||
|
As mentioned above, the set of diagnostics may change between
|
||||||
|
@theglibc{} releases. Nevertheless, the following table documents a few
|
@ -0,0 +1,144 @@
|
|||||||
|
commit f8d8b1b1e6d3b8b93f224efc796b7ea083fdb83f
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Apr 8 16:48:55 2024 +0200
|
||||||
|
|
||||||
|
aarch64: Enhanced CPU diagnostics for ld.so
|
||||||
|
|
||||||
|
This prints some information from struct cpu_features, and the midr_el1
|
||||||
|
and dczid_el0 system register contents on every CPU.
|
||||||
|
|
||||||
|
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
|
||||||
|
Modified for RHEL by: Patsy Griffin <patsy@redhat.com>
|
||||||
|
Diagnostics for the cpu_features mops and prefer_sve_ifuncs are not
|
||||||
|
currently supported on aarch64.
|
||||||
|
|
||||||
|
diff -Nrup a/manual/dynlink.texi b/manual/dynlink.texi
|
||||||
|
--- a/manual/dynlink.texi 2024-05-31 20:55:08.238959456 -0400
|
||||||
|
+++ b/manual/dynlink.texi 2024-05-31 20:55:41.298121623 -0400
|
||||||
|
@@ -224,6 +224,40 @@ reflect adjustment by @theglibc{}.
|
||||||
|
These Linux-specific items show the values of @code{struct utsname}, as
|
||||||
|
reported by the @code{uname} function. @xref{Platform Type}.
|
||||||
|
|
||||||
|
+@item aarch64.cpu_features.@dots{}
|
||||||
|
+These items are specific to the AArch64 architectures. They report data
|
||||||
|
+@theglibc{} uses to activate conditionally supported features such as
|
||||||
|
+BTI and MTE, and to select alternative function implementations.
|
||||||
|
+
|
||||||
|
+@item aarch64.processor[@var{index}].@dots{}
|
||||||
|
+These are additional items for the AArch64 architecture and are
|
||||||
|
+described below.
|
||||||
|
+
|
||||||
|
+@item aarch64.processor[@var{index}].requested=@var{kernel-cpu}
|
||||||
|
+The kernel is told to run the subsequent probing on the CPU numbered
|
||||||
|
+@var{kernel-cpu}. The values @var{kernel-cpu} and @var{index} can be
|
||||||
|
+distinct if there are gaps in the process CPU affinity mask. This line
|
||||||
|
+is not included if CPU affinity mask information is not available.
|
||||||
|
+
|
||||||
|
+@item aarch64.processor[@var{index}].observed=@var{kernel-cpu}
|
||||||
|
+This line reports the kernel CPU number @var{kernel-cpu} on which the
|
||||||
|
+probing code initially ran. If the CPU number cannot be obtained,
|
||||||
|
+this line is not printed.
|
||||||
|
+
|
||||||
|
+@item aarch64.processor[@var{index}].observed_node=@var{node}
|
||||||
|
+This reports the observed NUMA node number, as reported by the
|
||||||
|
+@code{getcpu} system call. If this information cannot be obtained, this
|
||||||
|
+line is not printed.
|
||||||
|
+
|
||||||
|
+@item aarch64.processor[@var{index}].midr_el1=@var{value}
|
||||||
|
+The value of the @code{midr_el1} system register on the processor
|
||||||
|
+@var{index}. This line is only printed if the kernel indicates that
|
||||||
|
+this system register is supported.
|
||||||
|
+
|
||||||
|
+@item aarch64.processor[@var{index}].dczid_el0=@var{value}
|
||||||
|
+The value of the @code{dczid_el0} system register on the processor
|
||||||
|
+@var{index}.
|
||||||
|
+
|
||||||
|
@cindex CPUID (diagnostics)
|
||||||
|
@item x86.cpu_features.@dots{}
|
||||||
|
These items are specific to the i386 and x86-64 architectures. They
|
||||||
|
diff -Nrup a/sysdeps/aarch64/dl-diagnostics-cpu.c b/sysdeps/aarch64/dl-diagnostics-cpu.c
|
||||||
|
--- a/sysdeps/aarch64/dl-diagnostics-cpu.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/sysdeps/aarch64/dl-diagnostics-cpu.c 2024-05-31 20:57:23.536623129 -0400
|
||||||
|
@@ -0,0 +1,81 @@
|
||||||
|
+/* Print CPU diagnostics data in ld.so. AArch64 version.
|
||||||
|
+ Copyright (C) 2021-2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <dl-diagnostics.h>
|
||||||
|
+
|
||||||
|
+#include <cpu-features.h>
|
||||||
|
+#include <dl-iterate_cpu.h>
|
||||||
|
+#include <ldsodefs.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+print_cpu_features_value (const char *label, uint64_t value)
|
||||||
|
+{
|
||||||
|
+ _dl_printf ("aarch64.cpu_features.");
|
||||||
|
+ _dl_diagnostics_print_labeled_value (label, value);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+print_per_cpu_value (const struct dl_iterate_cpu *dic,
|
||||||
|
+ const char *label, uint64_t value)
|
||||||
|
+{
|
||||||
|
+ _dl_printf ("aarch64.processor[0x%x].", dic->processor_index);
|
||||||
|
+ _dl_diagnostics_print_labeled_value (label, value);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_diagnostics_cpu (void)
|
||||||
|
+{
|
||||||
|
+ print_cpu_features_value ("bti", GLRO (dl_aarch64_cpu_features).bti);
|
||||||
|
+ print_cpu_features_value ("midr_el1",
|
||||||
|
+ GLRO (dl_aarch64_cpu_features).midr_el1);
|
||||||
|
+ print_cpu_features_value ("mte_state",
|
||||||
|
+ GLRO (dl_aarch64_cpu_features).mte_state);
|
||||||
|
+ print_cpu_features_value ("sve", GLRO (dl_aarch64_cpu_features).sve);
|
||||||
|
+ print_cpu_features_value ("zva_size",
|
||||||
|
+ GLRO (dl_aarch64_cpu_features).zva_size);
|
||||||
|
+
|
||||||
|
+ struct dl_iterate_cpu dic;
|
||||||
|
+ _dl_iterate_cpu_init (&dic);
|
||||||
|
+
|
||||||
|
+ while (_dl_iterate_cpu_next (&dic))
|
||||||
|
+ {
|
||||||
|
+ if (dic.requested_cpu >= 0)
|
||||||
|
+ _dl_printf ("aarch64.processor[0x%x].requested=0x%x\n",
|
||||||
|
+ dic.processor_index, dic.requested_cpu);
|
||||||
|
+ if (dic.actual_cpu >= 0)
|
||||||
|
+ _dl_printf ("aarch64.processor[0x%x].observed=0x%x\n",
|
||||||
|
+ dic.processor_index, dic.actual_cpu);
|
||||||
|
+ if (dic.actual_node >= 0)
|
||||||
|
+ _dl_printf ("aarch64.processor[0x%x].observed_node=0x%x\n",
|
||||||
|
+ dic.processor_index, dic.actual_node);
|
||||||
|
+
|
||||||
|
+ if (GLRO (dl_hwcap) & HWCAP_CPUID)
|
||||||
|
+ {
|
||||||
|
+ uint64_t midr_el1;
|
||||||
|
+ asm ("mrs %0, midr_el1" : "=r" (midr_el1));
|
||||||
|
+ print_per_cpu_value (&dic, "midr_el1", midr_el1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ uint64_t dczid_el0;
|
||||||
|
+ asm ("mrs %0, dczid_el0" : "=r" (dczid_el0));
|
||||||
|
+ print_per_cpu_value (&dic, "dczid_el0", dczid_el0);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
@ -0,0 +1,510 @@
|
|||||||
|
commit 7a430f40c46acfa7ce4c3bff193b278c190b2efc
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Apr 8 16:48:55 2024 +0200
|
||||||
|
|
||||||
|
x86: Add generic CPUID data dumper to ld.so --list-diagnostics
|
||||||
|
|
||||||
|
This is surprisingly difficult to implement if the goal is to produce
|
||||||
|
reasonably sized output. With the current approaches to output
|
||||||
|
compression (suppressing zeros and repeated results between CPUs,
|
||||||
|
folding ranges of identical subleaves, dealing with the %ecx
|
||||||
|
reflection issue), the output is less than 600 KiB even for systems
|
||||||
|
with 256 logical CPUs.
|
||||||
|
|
||||||
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
|
||||||
|
diff -Nrup a/manual/dynlink.texi b/manual/dynlink.texi
|
||||||
|
--- a/manual/dynlink.texi 2024-06-03 08:42:17.011026573 -0400
|
||||||
|
+++ b/manual/dynlink.texi 2024-06-03 08:55:18.607771972 -0400
|
||||||
|
@@ -262,7 +262,90 @@ The value of the @code{dczid_el0} system
|
||||||
|
@item x86.cpu_features.@dots{}
|
||||||
|
These items are specific to the i386 and x86-64 architectures. They
|
||||||
|
reflect supported CPU features and information on cache geometry, mostly
|
||||||
|
-collected using the @code{CPUID} instruction.
|
||||||
|
+collected using the CPUID instruction.
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].@dots{}
|
||||||
|
+These are additional items for the i386 and x86-64 architectures, as
|
||||||
|
+described below. They mostly contain raw data from the CPUID
|
||||||
|
+instruction. The probes are performed for each active CPU for the
|
||||||
|
+@code{ld.so} process, and data for different probed CPUs receives a
|
||||||
|
+uniqe @var{index} value. Some CPUID data is expected to differ from CPU
|
||||||
|
+core to CPU core. In some cases, CPUs are not correctly initialized and
|
||||||
|
+indicate the presence of different feature sets.
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].requested=@var{kernel-cpu}
|
||||||
|
+The kernel is told to run the subsequent probing on the CPU numbered
|
||||||
|
+@var{kernel-cpu}. The values @var{kernel-cpu} and @var{index} can be
|
||||||
|
+distinct if there are gaps in the process CPU affinity mask. This line
|
||||||
|
+is not included if CPU affinity mask information is not available.
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].observed=@var{kernel-cpu}
|
||||||
|
+This line reports the kernel CPU number @var{kernel-cpu} on which the
|
||||||
|
+probing code initially ran. If the CPU number cannot be obtained,
|
||||||
|
+this line is not printed.
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].observed_node=@var{node}
|
||||||
|
+This reports the observed NUMA node number, as reported by the
|
||||||
|
+@code{getcpu} system call. If this information cannot be obtained, this
|
||||||
|
+line is not printed.
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].cpuid_leaves=@var{count}
|
||||||
|
+This line indicates that @var{count} distinct CPUID leaves were
|
||||||
|
+encountered. (This reflects internal @code{ld.so} storage space, it
|
||||||
|
+does not directly correspond to @code{CPUID} enumeration ranges.)
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].ecx_limit=@var{value}
|
||||||
|
+The CPUID data extraction code uses a brute-force approach to enumerate
|
||||||
|
+subleaves (see the @samp{.subleaf_eax} lines below). The last
|
||||||
|
+@code{%rcx} value used in a CPUID query on this probed CPU was
|
||||||
|
+@var{value}.
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].cpuid.eax[@var{query_eax}].eax=@var{eax}
|
||||||
|
+@itemx x86.processor[@var{index}].cpuid.eax[@var{query_eax}].ebx=@var{ebx}
|
||||||
|
+@itemx x86.processor[@var{index}].cpuid.eax[@var{query_eax}].ecx=@var{ecx}
|
||||||
|
+@itemx x86.processor[@var{index}].cpuid.eax[@var{query_eax}].edx=@var{edx}
|
||||||
|
+These lines report the register contents after executing the CPUID
|
||||||
|
+instruction with @samp{%rax == @var{query_eax}} and @samp{%rcx == 0} (a
|
||||||
|
+@dfn{leaf}). For the first probed CPU (with a zero @var{index}), only
|
||||||
|
+leaves with non-zero register contents are reported. For subsequent
|
||||||
|
+CPUs, only leaves whose register contents differs from the previously
|
||||||
|
+probed CPUs (with @var{index} one less) are reported.
|
||||||
|
+
|
||||||
|
+Basic and extended leaves are reported using the same syntax. This
|
||||||
|
+means there is a large jump in @var{query_eax} for the first reported
|
||||||
|
+extended leaf.
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].cpuid.subleaf_eax[@var{query_eax}].ecx[@var{query_ecx}].eax=@var{eax}
|
||||||
|
+@itemx x86.processor[@var{index}].cpuid.subleaf_eax[@var{query_eax}].ecx[@var{query_ecx}].ebx=@var{ebx}
|
||||||
|
+@itemx x86.processor[@var{index}].cpuid.subleaf_eax[@var{query_eax}].ecx[@var{query_ecx}].ecx=@var{ecx}
|
||||||
|
+@itemx x86.processor[@var{index}].cpuid.subleaf_eax[@var{query_eax}].ecx[@var{query_ecx}].edx=@var{edx}
|
||||||
|
+This is similar to the leaves above, but for a @dfn{subleaf}. For
|
||||||
|
+subleaves, the CPUID instruction is executed with @samp{%rax ==
|
||||||
|
+@var{query_eax}} and @samp{%rcx == @var{query_ecx}}, so the result
|
||||||
|
+depends on both register values. The same rules about filtering zero
|
||||||
|
+and identical results apply.
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].cpuid.subleaf_eax[@var{query_eax}].ecx[@var{query_ecx}].until_ecx=@var{ecx_limit}
|
||||||
|
+Some CPUID results are the same regardless the @var{query_ecx} value.
|
||||||
|
+If this situation is detected, a line with the @samp{.until_ecx}
|
||||||
|
+selector ins included, and this indicates that the CPUID register
|
||||||
|
+contents is the same for @code{%rcx} values between @var{query_ecx}
|
||||||
|
+and @var{ecx_limit} (inclusive).
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].cpuid.subleaf_eax[@var{query_eax}].ecx[@var{query_ecx}].ecx_query_mask=0xff
|
||||||
|
+This line indicates that in an @samp{.until_ecx} range, the CPUID
|
||||||
|
+instruction preserved the lowested 8 bits of the input @code{%rcx} in
|
||||||
|
+the output @code{%rcx} registers. Otherwise, the subleaves in the range
|
||||||
|
+have identical values. This special treatment is necessary to report
|
||||||
|
+compact range information in case such copying occurs (because the
|
||||||
|
+subleaves would otherwise be all different).
|
||||||
|
+
|
||||||
|
+@item x86.processor[@var{index}].xgetbv.ecx[@var{query_ecx}]=@var{result}
|
||||||
|
+This line shows the 64-bit @var{result} value in the @code{%rdx:%rax}
|
||||||
|
+register pair after executing the XGETBV instruction with @code{%rcx}
|
||||||
|
+set to @var{query_ecx}. Zero values and values matching the previously
|
||||||
|
+probed CPU are omitted. Nothing is printed if the system does not
|
||||||
|
+support the XGETBV instruction.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@node Dynamic Linker Introspection
|
||||||
|
diff -Nrup a/sysdeps/x86/dl-diagnostics-cpu.c b/sysdeps/x86/dl-diagnostics-cpu.c
|
||||||
|
--- a/sysdeps/x86/dl-diagnostics-cpu.c 2024-06-03 08:42:16.825025689 -0400
|
||||||
|
+++ b/sysdeps/x86/dl-diagnostics-cpu.c 2024-06-03 09:49:47.528510916 -0400
|
||||||
|
@@ -17,7 +17,18 @@
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <dl-diagnostics.h>
|
||||||
|
+
|
||||||
|
+#include <array_length.h>
|
||||||
|
+#include <cpu-features.h>
|
||||||
|
+#include <cpuid.h>
|
||||||
|
+#include <dl-iterate_cpu.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sysdep.h>
|
||||||
|
+
|
||||||
|
+/* The generic CPUID dumping code. */
|
||||||
|
+static void _dl_diagnostics_cpuid (void);
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_cpu_features_value (const char *label, uint64_t value)
|
||||||
|
@@ -119,4 +130,377 @@ _dl_diagnostics_cpu (void)
|
||||||
|
"last cpu_features field has been printed");
|
||||||
|
print_cpu_features_value ("cachesize_non_temporal_divisor",
|
||||||
|
__rtld_global_ro_cachesize_non_temporal_divisor);
|
||||||
|
+
|
||||||
|
+ _dl_diagnostics_cpuid ();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* The following code implements a generic CPUID dumper that tries to
|
||||||
|
+ gather CPUID data without knowing about CPUID implementation
|
||||||
|
+ details. */
|
||||||
|
+
|
||||||
|
+/* Register arguments to CPUID. Multiple ECX subleaf values yielding
|
||||||
|
+ the same result are combined, to shorten the output. Both
|
||||||
|
+ identical matches (EAX to EDX are the same) and matches where EAX,
|
||||||
|
+ EBX, EDX, and ECX are equal except in the lower byte, which must
|
||||||
|
+ match the query ECX value. The latter is needed to compress ranges
|
||||||
|
+ on CPUs which preserve the lowest byte in ECX if an unknown leaf is
|
||||||
|
+ queried. */
|
||||||
|
+struct cpuid_query
|
||||||
|
+{
|
||||||
|
+ unsigned int eax;
|
||||||
|
+ unsigned ecx_first;
|
||||||
|
+ unsigned ecx_last;
|
||||||
|
+ bool ecx_preserves_query_byte;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* Single integer value that can be used for sorting/ordering
|
||||||
|
+ comparisons. Uses Q->eax and Q->ecx_first only because ecx_last is
|
||||||
|
+ always greater than the previous ecx_first value and less than the
|
||||||
|
+ subsequent one. */
|
||||||
|
+static inline unsigned long long int
|
||||||
|
+cpuid_query_combined (struct cpuid_query *q)
|
||||||
|
+{
|
||||||
|
+ /* ecx can be -1 (that is, ~0U). If this happens, this the only ecx
|
||||||
|
+ value for this eax value, so the ordering does not matter. */
|
||||||
|
+ return ((unsigned long long int) q->eax << 32) | (unsigned int) q->ecx_first;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* Used for differential reporting of zero/non-zero values. */
|
||||||
|
+static const struct cpuid_registers cpuid_registers_zero;
|
||||||
|
+
|
||||||
|
+/* Register arguments to CPUID paired with the results that came back. */
|
||||||
|
+struct cpuid_query_result
|
||||||
|
+{
|
||||||
|
+ struct cpuid_query q;
|
||||||
|
+ struct cpuid_registers r;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* During a first enumeration pass, we try to collect data for
|
||||||
|
+ cpuid_initial_subleaf_limit subleaves per leaf/EAX value. If we run
|
||||||
|
+ out of space, we try once more with applying the lower limit. */
|
||||||
|
+enum { cpuid_main_leaf_limit = 128 };
|
||||||
|
+enum { cpuid_initial_subleaf_limit = 512 };
|
||||||
|
+enum { cpuid_subleaf_limit = 32 };
|
||||||
|
+
|
||||||
|
+/* Offset of the extended leaf area. */
|
||||||
|
+enum {cpuid_extended_leaf_offset = 0x80000000 };
|
||||||
|
+
|
||||||
|
+/* Collected CPUID data. Everything is stored in a statically sized
|
||||||
|
+ array that is sized so that the second pass will collect some data
|
||||||
|
+ for all leaves, after the limit is applied. On the second pass,
|
||||||
|
+ ecx_limit is set to cpuid_subleaf_limit. */
|
||||||
|
+struct cpuid_collected_data
|
||||||
|
+{
|
||||||
|
+ unsigned int used;
|
||||||
|
+ unsigned int ecx_limit;
|
||||||
|
+ uint64_t xgetbv_ecx_0;
|
||||||
|
+ struct cpuid_query_result qr[cpuid_main_leaf_limit
|
||||||
|
+ * 2 * cpuid_subleaf_limit];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* Fill in the result of a CPUID query. Returns true if there is
|
||||||
|
+ room, false if nothing could be stored. */
|
||||||
|
+static bool
|
||||||
|
+_dl_diagnostics_cpuid_store (struct cpuid_collected_data *ccd,
|
||||||
|
+ unsigned eax, int ecx)
|
||||||
|
+{
|
||||||
|
+ if (ccd->used >= array_length (ccd->qr))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ /* Tentatively fill in the next value. */
|
||||||
|
+ __cpuid_count (eax, ecx,
|
||||||
|
+ ccd->qr[ccd->used].r.eax,
|
||||||
|
+ ccd->qr[ccd->used].r.ebx,
|
||||||
|
+ ccd->qr[ccd->used].r.ecx,
|
||||||
|
+ ccd->qr[ccd->used].r.edx);
|
||||||
|
+
|
||||||
|
+ /* If the ECX subleaf is next subleaf after the previous one (for
|
||||||
|
+ the same leaf), and the values are the same, merge the result
|
||||||
|
+ with the already-stored one. Do this before skipping zero
|
||||||
|
+ leaves, which avoids artifiacts for ECX == 256 queries. */
|
||||||
|
+ if (ccd->used > 0
|
||||||
|
+ && ccd->qr[ccd->used - 1].q.eax == eax
|
||||||
|
+ && ccd->qr[ccd->used - 1].q.ecx_last + 1 == ecx)
|
||||||
|
+ {
|
||||||
|
+ /* Exact match of the previous result. Ignore the value of
|
||||||
|
+ ecx_preserves_query_byte if this is a singleton range so far
|
||||||
|
+ because we can treat ECX as fixed if the same value repeats. */
|
||||||
|
+ if ((!ccd->qr[ccd->used - 1].q.ecx_preserves_query_byte
|
||||||
|
+ || (ccd->qr[ccd->used - 1].q.ecx_first
|
||||||
|
+ == ccd->qr[ccd->used - 1].q.ecx_last))
|
||||||
|
+ && memcmp (&ccd->qr[ccd->used - 1].r, &ccd->qr[ccd->used].r,
|
||||||
|
+ sizeof (ccd->qr[ccd->used].r)) == 0)
|
||||||
|
+ {
|
||||||
|
+ ccd->qr[ccd->used - 1].q.ecx_last = ecx;
|
||||||
|
+ /* ECX is now fixed because the same value has been observed
|
||||||
|
+ twice, even if we had a low-byte match before. */
|
||||||
|
+ ccd->qr[ccd->used - 1].q.ecx_preserves_query_byte = false;
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ /* Match except for the low byte in ECX, which must match the
|
||||||
|
+ incoming ECX value. */
|
||||||
|
+ if (ccd->qr[ccd->used - 1].q.ecx_preserves_query_byte
|
||||||
|
+ && (ecx & 0xff) == (ccd->qr[ccd->used].r.ecx & 0xff)
|
||||||
|
+ && ccd->qr[ccd->used].r.eax == ccd->qr[ccd->used - 1].r.eax
|
||||||
|
+ && ccd->qr[ccd->used].r.ebx == ccd->qr[ccd->used - 1].r.ebx
|
||||||
|
+ && ((ccd->qr[ccd->used].r.ecx & 0xffffff00)
|
||||||
|
+ == (ccd->qr[ccd->used - 1].r.ecx & 0xffffff00))
|
||||||
|
+ && ccd->qr[ccd->used].r.edx == ccd->qr[ccd->used - 1].r.edx)
|
||||||
|
+ {
|
||||||
|
+ ccd->qr[ccd->used - 1].q.ecx_last = ecx;
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Do not store zero results. All-zero values usually mean that the
|
||||||
|
+ subleaf is unsupported. */
|
||||||
|
+ if (ccd->qr[ccd->used].r.eax == 0
|
||||||
|
+ && ccd->qr[ccd->used].r.ebx == 0
|
||||||
|
+ && ccd->qr[ccd->used].r.ecx == 0
|
||||||
|
+ && ccd->qr[ccd->used].r.edx == 0)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ /* The result needs to be stored. Fill in the query parameters and
|
||||||
|
+ consume the storage. */
|
||||||
|
+ ccd->qr[ccd->used].q.eax = eax;
|
||||||
|
+ ccd->qr[ccd->used].q.ecx_first = ecx;
|
||||||
|
+ ccd->qr[ccd->used].q.ecx_last = ecx;
|
||||||
|
+ ccd->qr[ccd->used].q.ecx_preserves_query_byte
|
||||||
|
+ = (ecx & 0xff) == (ccd->qr[ccd->used].r.ecx & 0xff);
|
||||||
|
+ ++ccd->used;
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Collected CPUID data into *CCD. If LIMIT, apply per-leaf limits to
|
||||||
|
+ avoid exceeding the pre-allocated space. Return true if all data
|
||||||
|
+ could be stored, false if the retrying without a limit is
|
||||||
|
+ requested. */
|
||||||
|
+static bool
|
||||||
|
+_dl_diagnostics_cpuid_collect_1 (struct cpuid_collected_data *ccd, bool limit)
|
||||||
|
+{
|
||||||
|
+ ccd->used = 0;
|
||||||
|
+ ccd->ecx_limit
|
||||||
|
+ = (limit ? cpuid_subleaf_limit : cpuid_initial_subleaf_limit) - 1;
|
||||||
|
+ _dl_diagnostics_cpuid_store (ccd, 0x00, 0x00);
|
||||||
|
+ if (ccd->used == 0)
|
||||||
|
+ /* CPUID reported all 0. Should not happen. */
|
||||||
|
+ return true;
|
||||||
|
+ unsigned int maximum_leaf = ccd->qr[0x00].r.eax;
|
||||||
|
+ if (limit && maximum_leaf >= cpuid_main_leaf_limit)
|
||||||
|
+ maximum_leaf = cpuid_main_leaf_limit - 1;
|
||||||
|
+
|
||||||
|
+ for (unsigned int eax = 1; eax <= maximum_leaf; ++eax)
|
||||||
|
+ {
|
||||||
|
+ for (unsigned int ecx = 0; ecx <= ccd->ecx_limit; ++ecx)
|
||||||
|
+ if (!_dl_diagnostics_cpuid_store (ccd, eax, ecx))
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!_dl_diagnostics_cpuid_store (ccd, cpuid_extended_leaf_offset, 0x00))
|
||||||
|
+ return false;
|
||||||
|
+ maximum_leaf = ccd->qr[ccd->used - 1].r.eax;
|
||||||
|
+ if (maximum_leaf < cpuid_extended_leaf_offset)
|
||||||
|
+ /* No extended CPUID information. */
|
||||||
|
+ return true;
|
||||||
|
+ if (limit
|
||||||
|
+ && maximum_leaf - cpuid_extended_leaf_offset >= cpuid_main_leaf_limit)
|
||||||
|
+ maximum_leaf = cpuid_extended_leaf_offset + cpuid_main_leaf_limit - 1;
|
||||||
|
+ for (unsigned int eax = cpuid_extended_leaf_offset + 1;
|
||||||
|
+ eax <= maximum_leaf; ++eax)
|
||||||
|
+ {
|
||||||
|
+ for (unsigned int ecx = 0; ecx <= ccd->ecx_limit; ++ecx)
|
||||||
|
+ if (!_dl_diagnostics_cpuid_store (ccd, eax, ecx))
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Call _dl_diagnostics_cpuid_collect_1 twice if necessary, the
|
||||||
|
+ second time with the limit applied. */
|
||||||
|
+static void
|
||||||
|
+_dl_diagnostics_cpuid_collect (struct cpuid_collected_data *ccd)
|
||||||
|
+{
|
||||||
|
+ if (!_dl_diagnostics_cpuid_collect_1 (ccd, false))
|
||||||
|
+ _dl_diagnostics_cpuid_collect_1 (ccd, true);
|
||||||
|
+
|
||||||
|
+ /* Re-use the result of the official feature probing here. */
|
||||||
|
+ const struct cpu_features *cpu_features = __get_cpu_features ();
|
||||||
|
+ if (CPU_FEATURES_CPU_P (cpu_features, OSXSAVE))
|
||||||
|
+ {
|
||||||
|
+ unsigned int xcrlow;
|
||||||
|
+ unsigned int xcrhigh;
|
||||||
|
+ asm ("xgetbv" : "=a" (xcrlow), "=d" (xcrhigh) : "c" (0));
|
||||||
|
+ ccd->xgetbv_ecx_0 = ((uint64_t) xcrhigh << 32) + xcrlow;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ ccd->xgetbv_ecx_0 = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Print a CPUID register value (passed as REG_VALUE) if it differs
|
||||||
|
+ from the expected REG_REFERENCE value. PROCESSOR_INDEX is the
|
||||||
|
+ process sequence number (always starting at zero; not a kernel ID). */
|
||||||
|
+static void
|
||||||
|
+_dl_diagnostics_cpuid_print_reg (unsigned int processor_index,
|
||||||
|
+ const struct cpuid_query *q,
|
||||||
|
+ const char *reg_label, unsigned int reg_value,
|
||||||
|
+ bool subleaf)
|
||||||
|
+{
|
||||||
|
+ if (subleaf)
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].cpuid.subleaf_eax[0x%x]"
|
||||||
|
+ ".ecx[0x%x].%s=0x%x\n",
|
||||||
|
+ processor_index, q->eax, q->ecx_first, reg_label, reg_value);
|
||||||
|
+ else
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].cpuid.eax[0x%x].%s=0x%x\n",
|
||||||
|
+ processor_index, q->eax, reg_label, reg_value);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Print CPUID result values in *RESULT for the query in
|
||||||
|
+ CCD->qr[CCD_IDX]. PROCESSOR_INDEX is the process sequence number
|
||||||
|
+ (always starting at zero; not a kernel ID). */
|
||||||
|
+static void
|
||||||
|
+_dl_diagnostics_cpuid_print_query (unsigned int processor_index,
|
||||||
|
+ struct cpuid_collected_data *ccd,
|
||||||
|
+ unsigned int ccd_idx,
|
||||||
|
+ const struct cpuid_registers *result)
|
||||||
|
+{
|
||||||
|
+ /* Treat this as a value if subleaves if ecx isn't zero (maybe
|
||||||
|
+ within the [ecx_fist, ecx_last] range), or if eax matches its
|
||||||
|
+ neighbors. If the range is [0, ecx_limit], then the subleaves
|
||||||
|
+ are not distinct (independently of ecx_preserves_query_byte),
|
||||||
|
+ so do not report them separately. */
|
||||||
|
+ struct cpuid_query *q = &ccd->qr[ccd_idx].q;
|
||||||
|
+ bool subleaf = (q->ecx_first > 0
|
||||||
|
+ || (q->ecx_first != q->ecx_last
|
||||||
|
+ && !(q->ecx_first == 0 && q->ecx_last == ccd->ecx_limit))
|
||||||
|
+ || (ccd_idx > 0 && q->eax == ccd->qr[ccd_idx - 1].q.eax)
|
||||||
|
+ || (ccd_idx + 1 < ccd->used
|
||||||
|
+ && q->eax == ccd->qr[ccd_idx + 1].q.eax));
|
||||||
|
+ _dl_diagnostics_cpuid_print_reg (processor_index, q, "eax", result->eax,
|
||||||
|
+ subleaf);
|
||||||
|
+ _dl_diagnostics_cpuid_print_reg (processor_index, q, "ebx", result->ebx,
|
||||||
|
+ subleaf);
|
||||||
|
+ _dl_diagnostics_cpuid_print_reg (processor_index, q, "ecx", result->ecx,
|
||||||
|
+ subleaf);
|
||||||
|
+ _dl_diagnostics_cpuid_print_reg (processor_index, q, "edx", result->edx,
|
||||||
|
+ subleaf);
|
||||||
|
+
|
||||||
|
+ if (subleaf && q->ecx_first != q->ecx_last)
|
||||||
|
+ {
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].cpuid.subleaf_eax[0x%x]"
|
||||||
|
+ ".ecx[0x%x].until_ecx=0x%x\n",
|
||||||
|
+ processor_index, q->eax, q->ecx_first, q->ecx_last);
|
||||||
|
+ if (q->ecx_preserves_query_byte)
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].cpuid.subleaf_eax[0x%x]"
|
||||||
|
+ ".ecx[0x%x].ecx_query_mask=0xff\n",
|
||||||
|
+ processor_index, q->eax, q->ecx_first);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Perform differential reporting of the data in *CURRENT against
|
||||||
|
+ *BASE. REQUESTED_CPU is the kernel CPU ID the thread was
|
||||||
|
+ configured to run on, or -1 if no configuration was possible.
|
||||||
|
+ PROCESSOR_INDEX is the process sequence number (always starting at
|
||||||
|
+ zero; not a kernel ID). */
|
||||||
|
+static void
|
||||||
|
+_dl_diagnostics_cpuid_report (struct dl_iterate_cpu *dci,
|
||||||
|
+ struct cpuid_collected_data *current,
|
||||||
|
+ struct cpuid_collected_data *base)
|
||||||
|
+{
|
||||||
|
+ if (dci->requested_cpu >= 0)
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].requested=0x%x\n",
|
||||||
|
+ dci->processor_index, dci->requested_cpu);
|
||||||
|
+ if (dci->actual_cpu >= 0)
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].observed=0x%x\n",
|
||||||
|
+ dci->processor_index, dci->actual_cpu);
|
||||||
|
+ if (dci->actual_node >= 0)
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].observed_node=0x%x\n",
|
||||||
|
+ dci->processor_index, dci->actual_node);
|
||||||
|
+
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].cpuid_leaves=0x%x\n",
|
||||||
|
+ dci->processor_index, current->used);
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].ecx_limit=0x%x\n",
|
||||||
|
+ dci->processor_index, current->ecx_limit);
|
||||||
|
+
|
||||||
|
+ unsigned int base_idx = 0;
|
||||||
|
+ for (unsigned int current_idx = 0; current_idx < current->used;
|
||||||
|
+ ++current_idx)
|
||||||
|
+ {
|
||||||
|
+ /* Report missing data on the current CPU as 0. */
|
||||||
|
+ unsigned long long int current_query
|
||||||
|
+ = cpuid_query_combined (¤t->qr[current_idx].q);
|
||||||
|
+ while (base_idx < base->used
|
||||||
|
+ && cpuid_query_combined (&base->qr[base_idx].q) < current_query)
|
||||||
|
+ {
|
||||||
|
+ _dl_diagnostics_cpuid_print_query (dci->processor_index,
|
||||||
|
+ base, base_idx,
|
||||||
|
+ &cpuid_registers_zero);
|
||||||
|
+ ++base_idx;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (base_idx < base->used
|
||||||
|
+ && cpuid_query_combined (&base->qr[base_idx].q) == current_query)
|
||||||
|
+ {
|
||||||
|
+ _Static_assert (sizeof (struct cpuid_registers) == 4 * 4,
|
||||||
|
+ "no padding in struct cpuid_registers");
|
||||||
|
+ if (current->qr[current_idx].q.ecx_last
|
||||||
|
+ != base->qr[base_idx].q.ecx_last
|
||||||
|
+ || memcmp (¤t->qr[current_idx].r,
|
||||||
|
+ &base->qr[base_idx].r,
|
||||||
|
+ sizeof (struct cpuid_registers)) != 0)
|
||||||
|
+ /* The ECX range or the values have changed. Show the
|
||||||
|
+ new values. */
|
||||||
|
+ _dl_diagnostics_cpuid_print_query (dci->processor_index,
|
||||||
|
+ current, current_idx,
|
||||||
|
+ ¤t->qr[current_idx].r);
|
||||||
|
+ ++base_idx;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ /* Data is absent in the base reference. Report the new data. */
|
||||||
|
+ _dl_diagnostics_cpuid_print_query (dci->processor_index,
|
||||||
|
+ current, current_idx,
|
||||||
|
+ ¤t->qr[current_idx].r);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (current->xgetbv_ecx_0 != base->xgetbv_ecx_0)
|
||||||
|
+ {
|
||||||
|
+ /* Re-use the 64-bit printing routine. */
|
||||||
|
+ _dl_printf ("x86.processor[0x%x].", dci->processor_index);
|
||||||
|
+ _dl_diagnostics_print_labeled_value ("xgetbv.ecx[0x0]",
|
||||||
|
+ current->xgetbv_ecx_0);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+_dl_diagnostics_cpuid (void)
|
||||||
|
+{
|
||||||
|
+#if !HAS_CPUID
|
||||||
|
+ /* CPUID is not supported, so there is nothing to dump. */
|
||||||
|
+ if (__get_cpuid_max (0, 0) == 0)
|
||||||
|
+ return;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ struct dl_iterate_cpu dic;
|
||||||
|
+ _dl_iterate_cpu_init (&dic);
|
||||||
|
+
|
||||||
|
+ /* Two copies of the data are used. Data is written to the index
|
||||||
|
+ (dic.processor_index & 1). The previous version against which the
|
||||||
|
+ data dump is reported is at index !(processor_index & 1). */
|
||||||
|
+ struct cpuid_collected_data ccd[2];
|
||||||
|
+
|
||||||
|
+ /* The initial data is presumed to be all zero. Zero results are
|
||||||
|
+ not recorded. */
|
||||||
|
+ ccd[1].used = 0;
|
||||||
|
+ ccd[1].xgetbv_ecx_0 = 0;
|
||||||
|
+
|
||||||
|
+ /* Run the CPUID probing on a specific CPU. There are expected
|
||||||
|
+ differences for encoding core IDs and topology information in
|
||||||
|
+ CPUID output, but some firmware/kernel bugs also may result in
|
||||||
|
+ asymmetric data across CPUs in some cases. */
|
||||||
|
+ while (_dl_iterate_cpu_next (&dic))
|
||||||
|
+ {
|
||||||
|
+ _dl_diagnostics_cpuid_collect (&ccd[dic.processor_index & 1]);
|
||||||
|
+ _dl_diagnostics_cpuid_report
|
||||||
|
+ (&dic, &ccd[dic.processor_index & 1],
|
||||||
|
+ &ccd[!(dic.processor_index & 1)]);
|
||||||
|
+ }
|
||||||
|
}
|
@ -0,0 +1,262 @@
|
|||||||
|
commit 5653ccd847f0cd3a98906e44c97c71d68652d326
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Apr 8 16:48:55 2024 +0200
|
||||||
|
|
||||||
|
elf: Add CPU iteration support for future use in ld.so diagnostics
|
||||||
|
|
||||||
|
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-iterate_cpu.h b/elf/dl-iterate_cpu.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..60db167b13
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/dl-iterate_cpu.h
|
||||||
|
@@ -0,0 +1,136 @@
|
||||||
|
+/* Iterate over all CPUs, for CPU-specific diagnostics.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#ifndef DL_ITERATE_CPU_H
|
||||||
|
+#define DL_ITERATE_CPU_H
|
||||||
|
+
|
||||||
|
+#include <dl-affinity.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+
|
||||||
|
+struct dl_iterate_cpu
|
||||||
|
+{
|
||||||
|
+ /* Sequential iteration count, starting at 0. */
|
||||||
|
+ unsigned int processor_index;
|
||||||
|
+
|
||||||
|
+ /* Requested CPU. Can be -1 if affinity could not be set. */
|
||||||
|
+ int requested_cpu;
|
||||||
|
+
|
||||||
|
+ /* Observed current CPU. -1 if unavailable. */
|
||||||
|
+ int actual_cpu;
|
||||||
|
+
|
||||||
|
+ /* Observed node ID for the CPU. -1 if unavailable. */
|
||||||
|
+ int actual_node;
|
||||||
|
+
|
||||||
|
+ /* Internal fields to implement the iteration. */
|
||||||
|
+
|
||||||
|
+ /* Affinity as obtained by _dl_iterate_cpu_init, using
|
||||||
|
+ _dl_getaffinity. Space for 8,192 CPUs. */
|
||||||
|
+ unsigned long int mask_reference[8192 / sizeof (unsigned long int) / 8];
|
||||||
|
+
|
||||||
|
+ /* This array is used by _dl_setaffinity calls. */
|
||||||
|
+ unsigned long int mask_request[8192 / sizeof (unsigned long int) / 8];
|
||||||
|
+
|
||||||
|
+ /* Return value from the initial _dl_getaffinity call. */
|
||||||
|
+ int length_reference;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+_dl_iterate_cpu_init (struct dl_iterate_cpu *dic)
|
||||||
|
+{
|
||||||
|
+ dic->length_reference
|
||||||
|
+ = _dl_getaffinity (dic->mask_reference, sizeof (dic->mask_reference));
|
||||||
|
+ /* Prepare for the first _dl_iterate_cpu_next call. */
|
||||||
|
+ dic->processor_index = -1;
|
||||||
|
+ dic->requested_cpu = -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool
|
||||||
|
+_dl_iterate_cpu_next (struct dl_iterate_cpu *dic)
|
||||||
|
+{
|
||||||
|
+ ++dic->processor_index;
|
||||||
|
+
|
||||||
|
+ if (dic->length_reference > 0)
|
||||||
|
+ {
|
||||||
|
+ /* Search for the next CPU to switch to. */
|
||||||
|
+ while (true)
|
||||||
|
+ {
|
||||||
|
+ ++dic->requested_cpu;
|
||||||
|
+
|
||||||
|
+ /* Array index and bit number within the array. */
|
||||||
|
+ unsigned int long_index
|
||||||
|
+ = dic->requested_cpu / sizeof (unsigned long int) / 8;
|
||||||
|
+ unsigned int bit_index
|
||||||
|
+ = dic->requested_cpu % (sizeof (unsigned long int) * 8);
|
||||||
|
+
|
||||||
|
+ if (long_index * sizeof (unsigned long int) >= dic->length_reference)
|
||||||
|
+ /* All possible CPUs have been covered. */
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ unsigned long int bit = 1UL << bit_index;
|
||||||
|
+ if (dic->mask_reference[long_index] & bit)
|
||||||
|
+ {
|
||||||
|
+ /* The CPU is available. Try to select it. */
|
||||||
|
+ dic->mask_request[long_index] = bit;
|
||||||
|
+ if (_dl_setaffinity (dic->mask_request,
|
||||||
|
+ (long_index + 1)
|
||||||
|
+ * sizeof (unsigned long int)) < 0)
|
||||||
|
+ {
|
||||||
|
+ /* Record that we could not perform a CPU request. */
|
||||||
|
+ dic->length_reference = -1;
|
||||||
|
+
|
||||||
|
+ if (dic->processor_index > 0)
|
||||||
|
+ /* We already reported something. There is no need to
|
||||||
|
+ continue because the new data is probably not useful. */
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Clear the bit in case the next iteration switches to the
|
||||||
|
+ next long value. */
|
||||||
|
+ dic->mask_request[long_index] = 0;
|
||||||
|
+
|
||||||
|
+ /* We found a CPU to run on. */
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* No way to set CPU affinity. Iterate just once. */
|
||||||
|
+ if (dic->processor_index > 0)
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Fill in the actual CPU information. CPU pinning may not actually
|
||||||
|
+ be effective, depending on the container host. */
|
||||||
|
+ unsigned int cpu, node;
|
||||||
|
+ if (_dl_getcpu (&cpu, &node) < 0)
|
||||||
|
+ {
|
||||||
|
+ /* No CPU information available. */
|
||||||
|
+ dic->actual_cpu = -1;
|
||||||
|
+ dic->actual_node = -1;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ dic->actual_cpu = cpu;
|
||||||
|
+ dic->actual_node = node;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* DL_ITERATE_CPU_H */
|
||||||
|
diff --git a/sysdeps/generic/dl-affinity.h b/sysdeps/generic/dl-affinity.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..d117f737e9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/generic/dl-affinity.h
|
||||||
|
@@ -0,0 +1,54 @@
|
||||||
|
+/* CPU affinity handling for the dynamic linker. Stub version.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#ifndef DL_AFFINITY_H
|
||||||
|
+#define DL_AFFINITY_H
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+
|
||||||
|
+/* On success, write the current CPU ID to *CPU, and the current node
|
||||||
|
+ ID to *NODE, and return 0. Return a negative error code on
|
||||||
|
+ failure. */
|
||||||
|
+static inline int
|
||||||
|
+_dl_getcpu (unsigned int *cpu, unsigned int *node)
|
||||||
|
+{
|
||||||
|
+ return -ENOSYS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* On success, write CPU ID affinity bits for the current thread to
|
||||||
|
+ *BITS, which must be SIZE bytes long, and return the number of
|
||||||
|
+ bytes updated, a multiple of sizeof (unsigned long int). On
|
||||||
|
+ failure, return a negative error code. */
|
||||||
|
+static int
|
||||||
|
+_dl_getaffinity (unsigned long int *bits, size_t size)
|
||||||
|
+{
|
||||||
|
+ return -ENOSYS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Set the CPU affinity mask for the current thread to *BITS, using
|
||||||
|
+ the SIZE bytes from that array, which should be a multiple of
|
||||||
|
+ sizeof (unsigned long int). Return 0 on success, and a negative
|
||||||
|
+ error code on failure. */
|
||||||
|
+static int
|
||||||
|
+_dl_setaffinity (const unsigned long int *bits, size_t size)
|
||||||
|
+{
|
||||||
|
+ return -ENOSYS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* DL_AFFINITY_H */
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/dl-affinity.h b/sysdeps/unix/sysv/linux/dl-affinity.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..bbfede7750
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/dl-affinity.h
|
||||||
|
@@ -0,0 +1,46 @@
|
||||||
|
+/* CPU affinity handling for the dynamic linker. Linux version.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+/* See sysdeps/generic/dl-affinity.h for documentation of these interfaces. */
|
||||||
|
+
|
||||||
|
+#ifndef DL_AFFINITY_H
|
||||||
|
+#define DL_AFFINITY_H
|
||||||
|
+
|
||||||
|
+#include <sysdep.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+static inline int
|
||||||
|
+_dl_getcpu (unsigned int *cpu, unsigned int *node)
|
||||||
|
+{
|
||||||
|
+ return INTERNAL_SYSCALL_CALL (getcpu, cpu, node);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+_dl_getaffinity (unsigned long int *bits, size_t size)
|
||||||
|
+{
|
||||||
|
+ return INTERNAL_SYSCALL_CALL (sched_getaffinity, /* TID */ 0, size, bits);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+_dl_setaffinity (const unsigned long int *bits, size_t size)
|
||||||
|
+{
|
||||||
|
+ return INTERNAL_SYSCALL_CALL (sched_setaffinity, /* TID */ 0, size, bits);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* DL_AFFINITY_H */
|
@ -1,121 +0,0 @@
|
|||||||
commit 5361ad3910c257bc327567be76fde532ed238e42
|
|
||||||
Author: Florian Weimer <fweimer@redhat.com>
|
|
||||||
Date: Fri Apr 19 14:38:17 2024 +0200
|
|
||||||
|
|
||||||
login: Use unsigned 32-bit types for seconds-since-epoch
|
|
||||||
|
|
||||||
These fields store timestamps when the system was running. No Linux
|
|
||||||
systems existed before 1970, so these values are unused. Switching
|
|
||||||
to unsigned types allows continued use of the existing struct layouts
|
|
||||||
beyond the year 2038.
|
|
||||||
|
|
||||||
The intent is to give distributions more time to switch to improved
|
|
||||||
interfaces that also avoid locking/data corruption issues.
|
|
||||||
|
|
||||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
|
||||||
|
|
||||||
diff --git a/bits/utmp.h b/bits/utmp.h
|
|
||||||
index f2d1c13d8cd205b2..27cb536800c46d67 100644
|
|
||||||
--- a/bits/utmp.h
|
|
||||||
+++ b/bits/utmp.h
|
|
||||||
@@ -36,7 +36,7 @@
|
|
||||||
struct lastlog
|
|
||||||
{
|
|
||||||
#if __WORDSIZE_TIME64_COMPAT32
|
|
||||||
- int32_t ll_time;
|
|
||||||
+ __uint32_t ll_time;
|
|
||||||
#else
|
|
||||||
__time_t ll_time;
|
|
||||||
#endif
|
|
||||||
@@ -76,7 +76,7 @@ struct utmp
|
|
||||||
int32_t ut_session; /* Session ID, used for windowing. */
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
- int32_t tv_sec; /* Seconds. */
|
|
||||||
+ __uint32_t tv_sec; /* Seconds. */
|
|
||||||
int32_t tv_usec; /* Microseconds. */
|
|
||||||
} ut_tv; /* Time entry was made. */
|
|
||||||
#else
|
|
||||||
diff --git a/login/Makefile b/login/Makefile
|
|
||||||
index f91190e3dcd1e6c6..84563230ef665f9c 100644
|
|
||||||
--- a/login/Makefile
|
|
||||||
+++ b/login/Makefile
|
|
||||||
@@ -44,9 +44,11 @@ subdir-dirs = programs
|
|
||||||
vpath %.c programs
|
|
||||||
|
|
||||||
tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
|
|
||||||
- tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size tst-utmp-size-64
|
|
||||||
+ tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size tst-utmp-size-64 \
|
|
||||||
+ tst-utmp-unsigned tst-utmp-unsigned-64
|
|
||||||
|
|
||||||
CFLAGS-tst-utmp-size-64.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
|
||||||
+CFLAGS-tst-utmp-unsigned-64.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
|
||||||
|
|
||||||
# Empty compatibility library for old binaries.
|
|
||||||
extra-libs := libutil
|
|
||||||
diff --git a/login/tst-utmp-unsigned-64.c b/login/tst-utmp-unsigned-64.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000..940e7654f8dc5fd6
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/login/tst-utmp-unsigned-64.c
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+#include "tst-utmp-unsigned.c"
|
|
||||||
diff --git a/login/tst-utmp-unsigned.c b/login/tst-utmp-unsigned.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000..27ad03a7d608e83d
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/login/tst-utmp-unsigned.c
|
|
||||||
@@ -0,0 +1,40 @@
|
|
||||||
+/* Check that struct utmp, struct utmpx, struct lastlog use unsigned epoch.
|
|
||||||
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
|
||||||
+ This file is part of the GNU C Library.
|
|
||||||
+
|
|
||||||
+ The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
+ modify it under the terms of the GNU Lesser General Public
|
|
||||||
+ License as published by the Free Software Foundation; either
|
|
||||||
+ version 2.1 of the License, or (at your option) any later version.
|
|
||||||
+
|
|
||||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
||||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
+ Lesser General Public License for more details.
|
|
||||||
+
|
|
||||||
+ You should have received a copy of the GNU Lesser General Public
|
|
||||||
+ License along with the GNU C Library; if not, see
|
|
||||||
+ <https://www.gnu.org/licenses/>. */
|
|
||||||
+
|
|
||||||
+#include <utmp.h>
|
|
||||||
+#include <utmpx.h>
|
|
||||||
+#include <utmp-size.h>
|
|
||||||
+
|
|
||||||
+/* Undefined. Used to check that the conditions below are optimized away. */
|
|
||||||
+void link_failure_utmp (void);
|
|
||||||
+void link_failure_utmpx (void);
|
|
||||||
+void link_failure_lastlog (void);
|
|
||||||
+
|
|
||||||
+static int
|
|
||||||
+do_test (void)
|
|
||||||
+{
|
|
||||||
+ if ((struct utmp) { .ut_tv = { 0x80000000U, }, }.ut_tv.tv_sec <= 0)
|
|
||||||
+ link_failure_utmp ();
|
|
||||||
+ if ((struct utmpx) { .ut_tv = { 0x80000000U, }, }.ut_tv.tv_sec <= 0)
|
|
||||||
+ link_failure_utmpx ();
|
|
||||||
+ if ((struct lastlog) { .ll_time = 0x80000000U, }.ll_time <= 0)
|
|
||||||
+ link_failure_lastlog ();
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#include <support/test-driver.c>
|
|
||||||
diff --git a/sysdeps/gnu/bits/utmpx.h b/sysdeps/gnu/bits/utmpx.h
|
|
||||||
index 34b4afbc6ac25968..ed0df9bd8141d4e6 100644
|
|
||||||
--- a/sysdeps/gnu/bits/utmpx.h
|
|
||||||
+++ b/sysdeps/gnu/bits/utmpx.h
|
|
||||||
@@ -74,7 +74,7 @@ struct utmpx
|
|
||||||
__int32_t ut_session; /* Session ID, used for windowing. */
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
- __int32_t tv_sec; /* Seconds. */
|
|
||||||
+ __uint32_t tv_sec; /* Seconds. */
|
|
||||||
__int32_t tv_usec; /* Microseconds. */
|
|
||||||
} ut_tv; /* Time entry was made. */
|
|
||||||
#else
|
|
@ -0,0 +1,47 @@
|
|||||||
|
commit c3b023a7822185c9176cfb96eeca4ada3d662c4b
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Nov 24 12:57:57 2021 -0300
|
||||||
|
|
||||||
|
linux: Only build fstatat fallback if required
|
||||||
|
|
||||||
|
For 32-bit architecture with __ASSUME_STATX there is no need to
|
||||||
|
build fstatat64_time64_stat.
|
||||||
|
|
||||||
|
Checked on i686-linux-gnu.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
index f968e4ef0594852e..50ae5ad74832efe1 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
@@ -74,6 +74,17 @@ fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if (__WORDSIZE == 32 \
|
||||||
|
+ && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
|
||||||
|
+ || defined STAT_HAS_TIME32
|
||||||
|
+# define FSTATAT_USE_STATX 1
|
||||||
|
+#else
|
||||||
|
+# define FSTATAT_USE_STATX 0
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/* Only statx supports 64-bit timestamps for 32-bit architectures with
|
||||||
|
+ __ASSUME_STATX, so there is no point in building the fallback. */
|
||||||
|
+#if !FSTATAT_USE_STATX || (FSTATAT_USE_STATX && !defined __ASSUME_STATX)
|
||||||
|
static inline int
|
||||||
|
fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
|
||||||
|
int flag)
|
||||||
|
@@ -134,13 +145,6 @@ fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
-#if (__WORDSIZE == 32 \
|
||||||
|
- && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
|
||||||
|
- || defined STAT_HAS_TIME32
|
||||||
|
-# define FSTATAT_USE_STATX 1
|
||||||
|
-#else
|
||||||
|
-# define FSTATAT_USE_STATX 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
@ -0,0 +1,36 @@
|
|||||||
|
commit c7f05bd5342517f3f751e6ea8dec1916b80bee8a
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Mar 9 18:35:39 2022 -0300
|
||||||
|
|
||||||
|
Fix ununsed fstatat64_time64_statx
|
||||||
|
|
||||||
|
It is only called for legacy ABIs.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
index 50ae5ad74832efe1..45221bbdf901fa47 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
@@ -40,6 +40,11 @@ _Static_assert (sizeof (__blkcnt_t) == sizeof (__blkcnt64_t),
|
||||||
|
"__blkcnt_t and __blkcnt64_t must match");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#if (__WORDSIZE == 32 \
|
||||||
|
+ && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
|
||||||
|
+ || defined STAT_HAS_TIME32
|
||||||
|
+# define FSTATAT_USE_STATX 1
|
||||||
|
+
|
||||||
|
static inline int
|
||||||
|
fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
|
||||||
|
int flag)
|
||||||
|
@@ -73,11 +78,6 @@ fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
-#if (__WORDSIZE == 32 \
|
||||||
|
- && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
|
||||||
|
- || defined STAT_HAS_TIME32
|
||||||
|
-# define FSTATAT_USE_STATX 1
|
||||||
|
#else
|
||||||
|
# define FSTATAT_USE_STATX 0
|
||||||
|
#endif
|
@ -0,0 +1,30 @@
|
|||||||
|
commit e6547d635b991651600fab31f788ed5facd77610
|
||||||
|
Author: WANG Xuerui <git@xen0n.name>
|
||||||
|
Date: Wed Jun 1 10:12:28 2022 +0800
|
||||||
|
|
||||||
|
linux: use statx for fstat if neither newfstatat nor fstatat64 is present
|
||||||
|
|
||||||
|
LoongArch is going to be the first architecture supported by Linux that
|
||||||
|
has neither fstat* nor newfstatat [1], instead exclusively relying on
|
||||||
|
statx. So in fstatat64's implementation, we need to also enable statx
|
||||||
|
usage if neither fstatat64 nor newfstatat is present, to prepare for
|
||||||
|
this new case of kernel ABI.
|
||||||
|
|
||||||
|
[1]: https://lore.kernel.org/all/20220518092619.1269111-1-chenhuacai@loongson.cn/
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
index 45221bbdf901fa47..ded431257bf3450f 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
@@ -42,7 +42,8 @@ _Static_assert (sizeof (__blkcnt_t) == sizeof (__blkcnt64_t),
|
||||||
|
|
||||||
|
#if (__WORDSIZE == 32 \
|
||||||
|
&& (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
|
||||||
|
- || defined STAT_HAS_TIME32
|
||||||
|
+ || defined STAT_HAS_TIME32 \
|
||||||
|
+ || (!defined __NR_newfstatat && !defined __NR_fstatat64)
|
||||||
|
# define FSTATAT_USE_STATX 1
|
||||||
|
|
||||||
|
static inline int
|
@ -0,0 +1,157 @@
|
|||||||
|
commit 551101e8240b7514fc646d1722f8b79c90362b8f
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Sep 11 10:25:48 2023 -0300
|
||||||
|
|
||||||
|
io: Do not implement fstat with fstatat
|
||||||
|
|
||||||
|
AT_EMPTY_PATH is a requirement to implement fstat over fstatat,
|
||||||
|
however it does not prevent the kernel to read the path argument.
|
||||||
|
It is not an issue, but on x86-64 with SMAP-capable CPUs the kernel is
|
||||||
|
forced to perform expensive user memory access. After that regular
|
||||||
|
lookup is performed which adds even more overhead.
|
||||||
|
|
||||||
|
Instead, issue the fstat syscall directly on LFS fstat implementation
|
||||||
|
(32 bit architectures will still continue to use statx, which is
|
||||||
|
required to have 64 bit time_t support). it should be even a
|
||||||
|
small performance gain on non x86_64, since there is no need
|
||||||
|
to handle the path argument.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/fstat64.c b/sysdeps/unix/sysv/linux/fstat64.c
|
||||||
|
index 46de80b663b9c1c4..fe4f57065f8713d2 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/fstat64.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/fstat64.c
|
||||||
|
@@ -19,20 +19,53 @@
|
||||||
|
#define __fstat __redirect___fstat
|
||||||
|
#define fstat __redirect_fstat
|
||||||
|
#include <sys/stat.h>
|
||||||
|
+#undef __fstat
|
||||||
|
+#undef fstat
|
||||||
|
#include <fcntl.h>
|
||||||
|
-#include <kernel_stat.h>
|
||||||
|
-#include <stat_t64_cp.h>
|
||||||
|
+#include <internal-stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
__fstat64_time64 (int fd, struct __stat64_t64 *buf)
|
||||||
|
{
|
||||||
|
+#if !FSTATAT_USE_STATX
|
||||||
|
+# if XSTAT_IS_XSTAT64
|
||||||
|
+# ifdef __NR_fstat
|
||||||
|
+ /* 64-bit kABI, e.g. aarch64, ia64, powerpc64*, s390x, riscv64, and
|
||||||
|
+ x86_64. */
|
||||||
|
+ return INLINE_SYSCALL_CALL (fstat, fd, buf);
|
||||||
|
+# elif defined __NR_fstat64
|
||||||
|
+# if STAT64_IS_KERNEL_STAT64
|
||||||
|
+ /* 64-bit kABI outlier, e.g. alpha */
|
||||||
|
+ return INLINE_SYSCALL_CALL (fstat64, fd, buf);
|
||||||
|
+# else
|
||||||
|
+ /* 64-bit kABI outlier, e.g. sparc64. */
|
||||||
|
+ struct kernel_stat64 kst64;
|
||||||
|
+ int r = INLINE_SYSCALL_CALL (fstat64, fd, &kst64);
|
||||||
|
+ if (r == 0)
|
||||||
|
+ __cp_stat64_kstat64 (buf, &kst64);
|
||||||
|
+ return r;
|
||||||
|
+# endif /* STAT64_IS_KERNEL_STAT64 */
|
||||||
|
+# endif
|
||||||
|
+# else /* XSTAT_IS_XSTAT64 */
|
||||||
|
+ /* 64-bit kabi outlier, e.g. mips64 and mips64-n32. */
|
||||||
|
+ struct kernel_stat kst;
|
||||||
|
+ int r = INLINE_SYSCALL_CALL (fstat, fd, &kst);
|
||||||
|
+ if (r == 0)
|
||||||
|
+ __cp_kstat_stat64_t64 (&kst, buf);
|
||||||
|
+ return r;
|
||||||
|
+# endif
|
||||||
|
+#else /* !FSTATAT_USE_STATX */
|
||||||
|
+ /* All kABIs with non-LFS support and with old 32-bit time_t support
|
||||||
|
+ e.g. arm, csky, i386, hppa, m68k, microblaze, nios2, sh, powerpc32,
|
||||||
|
+ and sparc32. */
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
__set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return __fstatat64_time64 (fd, "", buf, AT_EMPTY_PATH);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
#if __TIMESIZE != 64
|
||||||
|
hidden_def (__fstat64_time64)
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
index ded431257bf3450f..8e9db7b11f0e1cf3 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
|
||||||
|
@@ -21,12 +21,10 @@
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
-#include <kernel_stat.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <time.h>
|
||||||
|
-#include <kstat_cp.h>
|
||||||
|
-#include <stat_t64_cp.h>
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
|
+#include <internal-stat.h>
|
||||||
|
|
||||||
|
#if __TIMESIZE == 64 \
|
||||||
|
&& (__WORDSIZE == 32 \
|
||||||
|
@@ -40,11 +38,7 @@ _Static_assert (sizeof (__blkcnt_t) == sizeof (__blkcnt64_t),
|
||||||
|
"__blkcnt_t and __blkcnt64_t must match");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#if (__WORDSIZE == 32 \
|
||||||
|
- && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
|
||||||
|
- || defined STAT_HAS_TIME32 \
|
||||||
|
- || (!defined __NR_newfstatat && !defined __NR_fstatat64)
|
||||||
|
-# define FSTATAT_USE_STATX 1
|
||||||
|
+#if FSTATAT_USE_STATX
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
|
||||||
|
@@ -79,8 +73,6 @@ fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
-#else
|
||||||
|
-# define FSTATAT_USE_STATX 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Only statx supports 64-bit timestamps for 32-bit architectures with
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/internal-stat.h b/sysdeps/unix/sysv/linux/internal-stat.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..e3b05698532fb185
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/internal-stat.h
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+/* Internal stat definitions.
|
||||||
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have 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 <stat_t64_cp.h>
|
||||||
|
+#include <kernel_stat.h>
|
||||||
|
+#include <kstat_cp.h>
|
||||||
|
+
|
||||||
|
+#if (__WORDSIZE == 32 \
|
||||||
|
+ && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
|
||||||
|
+ || defined STAT_HAS_TIME32 \
|
||||||
|
+ || (!defined __NR_newfstatat && !defined __NR_fstatat64)
|
||||||
|
+# define FSTATAT_USE_STATX 1
|
||||||
|
+#else
|
||||||
|
+# define FSTATAT_USE_STATX 0
|
||||||
|
+#endif
|
@ -0,0 +1,140 @@
|
|||||||
|
commit 6a04404521ac4119ae36827eeb288ea84eee7cf6
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Sat Feb 17 09:17:04 2024 +0100
|
||||||
|
|
||||||
|
Linux: Switch back to assembly syscall wrapper for prctl (bug 29770)
|
||||||
|
|
||||||
|
Commit ff026950e280bc3e9487b41b460fb31bc5b57721 ("Add a C wrapper for
|
||||||
|
prctl [BZ #25896]") replaced the assembler wrapper with a C function.
|
||||||
|
However, on powerpc64le-linux-gnu, the C variadic function
|
||||||
|
implementation requires extra work in the caller to set up the
|
||||||
|
parameter save area. Calling a function that needs a parameter save
|
||||||
|
area without one (because the prototype used indicates the function is
|
||||||
|
not variadic) corrupts the caller's stack. The Linux manual pages
|
||||||
|
project documents prctl as a non-variadic function. This has resulted
|
||||||
|
in various projects over the years using non-variadic prototypes,
|
||||||
|
including the sanitizer libraries in LLVm and GCC (GCC PR 113728).
|
||||||
|
|
||||||
|
This commit switches back to the assembler implementation on most
|
||||||
|
targets and only keeps the C implementation for x86-64 x32.
|
||||||
|
|
||||||
|
Also add the __prctl_time64 alias from commit
|
||||||
|
b39ffab860cd743a82c91946619f1b8158b0b65e ("Linux: Add time64 alias for
|
||||||
|
prctl") to sysdeps/unix/sysv/linux/syscalls.list; it was not yet
|
||||||
|
present in commit ff026950e280bc3e9487b41b460fb31bc5b57721.
|
||||||
|
|
||||||
|
This restores the old ABI on powerpc64le-linux-gnu, thus fixing
|
||||||
|
bug 29770.
|
||||||
|
|
||||||
|
Reviewed-By: Simon Chopin <simon.chopin@canonical.com>
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
sysdeps/unix/sysv/linux/syscalls.list
|
||||||
|
sysdeps/unix/sysv/linux/x86_64/x32/prctl.c
|
||||||
|
|
||||||
|
diff -Nrup a/sysdeps/unix/sysv/linux/prctl.c b/sysdeps/unix/sysv/linux/prctl.c
|
||||||
|
--- a/sysdeps/unix/sysv/linux/prctl.c 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/prctl.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
@@ -1,45 +0,0 @@
|
||||||
|
-/* prctl - Linux specific syscall.
|
||||||
|
- Copyright (C) 2020-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 <sysdep.h>
|
||||||
|
-#include <stdarg.h>
|
||||||
|
-#include <sys/prctl.h>
|
||||||
|
-
|
||||||
|
-/* Unconditionally read all potential arguments. This may pass
|
||||||
|
- garbage values to the kernel, but avoids the need for teaching
|
||||||
|
- glibc the argument counts of individual options (including ones
|
||||||
|
- that are added to the kernel in the future). */
|
||||||
|
-
|
||||||
|
-int
|
||||||
|
-__prctl (int option, ...)
|
||||||
|
-{
|
||||||
|
- va_list arg;
|
||||||
|
- va_start (arg, option);
|
||||||
|
- unsigned long int arg2 = va_arg (arg, unsigned long int);
|
||||||
|
- unsigned long int arg3 = va_arg (arg, unsigned long int);
|
||||||
|
- unsigned long int arg4 = va_arg (arg, unsigned long int);
|
||||||
|
- unsigned long int arg5 = va_arg (arg, unsigned long int);
|
||||||
|
- va_end (arg);
|
||||||
|
- return INLINE_SYSCALL_CALL (prctl, option, arg2, arg3, arg4, arg5);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-libc_hidden_def (__prctl)
|
||||||
|
-weak_alias (__prctl, prctl)
|
||||||
|
-#if __TIMESIZE != 64
|
||||||
|
-weak_alias (__prctl, __prctl_time64)
|
||||||
|
-#endif
|
||||||
|
diff -Nrup a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscalls.list 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscalls.list 2024-02-27 14:33:01.594782897 -0500
|
||||||
|
@@ -41,6 +41,7 @@ munlockall - munlockall i: munlockall
|
||||||
|
nfsservctl EXTRA nfsservctl i:ipp __compat_nfsservctl nfsservctl@GLIBC_2.0:GLIBC_2.28
|
||||||
|
pipe - pipe i:f __pipe pipe
|
||||||
|
pipe2 - pipe2 i:fi __pipe2 pipe2
|
||||||
|
+prctl EXTRA prctl i:iiiii __prctl prctl __prctl_time64
|
||||||
|
pivot_root EXTRA pivot_root i:ss pivot_root
|
||||||
|
query_module EXTRA query_module i:sipip __compat_query_module query_module@GLIBC_2.0:GLIBC_2.23
|
||||||
|
quotactl EXTRA quotactl i:isip quotactl
|
||||||
|
diff -Nrup a/sysdeps/unix/sysv/linux/x86_64/x32/prctl.c b/sysdeps/unix/sysv/linux/x86_64/x32/prctl.c
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/x32/prctl.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/prctl.c 2024-02-27 14:35:03.388602623 -0500
|
||||||
|
@@ -0,0 +1,42 @@
|
||||||
|
+/* prctl - Linux specific syscall. x86-64 x32 version.
|
||||||
|
+ Copyright (C) 2020-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 <sysdep.h>
|
||||||
|
+#include <stdarg.h>
|
||||||
|
+#include <sys/prctl.h>
|
||||||
|
+
|
||||||
|
+/* Unconditionally read all potential arguments. This may pass
|
||||||
|
+ garbage values to the kernel, but avoids the need for teaching
|
||||||
|
+ glibc the argument counts of individual options (including ones
|
||||||
|
+ that are added to the kernel in the future). */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+__prctl (int option, ...)
|
||||||
|
+{
|
||||||
|
+ va_list arg;
|
||||||
|
+ va_start (arg, option);
|
||||||
|
+ unsigned long int arg2 = va_arg (arg, unsigned long int);
|
||||||
|
+ unsigned long int arg3 = va_arg (arg, unsigned long int);
|
||||||
|
+ unsigned long int arg4 = va_arg (arg, unsigned long int);
|
||||||
|
+ unsigned long int arg5 = va_arg (arg, unsigned long int);
|
||||||
|
+ va_end (arg);
|
||||||
|
+ return INLINE_SYSCALL_CALL (prctl, option, arg2, arg3, arg4, arg5);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+libc_hidden_def (__prctl)
|
||||||
|
+weak_alias (__prctl, prctl)
|
@ -0,0 +1,41 @@
|
|||||||
|
commit 01671608a3bddde369cdd42aed12e1c019b87158
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed Aug 4 02:21:01 2021 +0530
|
||||||
|
|
||||||
|
gethosts: Remove unused argument _type
|
||||||
|
|
||||||
|
The generated code is unchanged.
|
||||||
|
|
||||||
|
(cherry picked from commit b17e842a60819098d2a203ecc8b8371b7e1d6c65)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index f391dc0a59849aab..702d8a50e0c218d2 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -239,7 +239,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define gethosts(_family, _type) \
|
||||||
|
+#define gethosts(_family) \
|
||||||
|
{ \
|
||||||
|
struct hostent th; \
|
||||||
|
char *localcanon = NULL; \
|
||||||
|
@@ -864,7 +864,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
if (req->ai_family == AF_INET6
|
||||||
|
|| req->ai_family == AF_UNSPEC)
|
||||||
|
{
|
||||||
|
- gethosts (AF_INET6, struct in6_addr);
|
||||||
|
+ gethosts (AF_INET6);
|
||||||
|
no_inet6_data = no_data;
|
||||||
|
inet6_status = status;
|
||||||
|
}
|
||||||
|
@@ -876,7 +876,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
know we are not going to need them. */
|
||||||
|
&& ((req->ai_flags & AI_ALL) || !got_ipv6)))
|
||||||
|
{
|
||||||
|
- gethosts (AF_INET, struct in_addr);
|
||||||
|
+ gethosts (AF_INET);
|
||||||
|
|
||||||
|
if (req->ai_family == AF_INET)
|
||||||
|
{
|
@ -0,0 +1,178 @@
|
|||||||
|
commit 6e3fed9d20d6b7ef4b69dd7cfcdd7bbaf1c9a9cb
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Mon Mar 7 20:24:37 2022 +0530
|
||||||
|
|
||||||
|
gaih_inet: split loopback lookup into its own function
|
||||||
|
|
||||||
|
Flatten the condition nesting and replace the alloca for RET.AT/ATR with
|
||||||
|
a single array LOCAL_AT[2]. This gets rid of alloca and alloca
|
||||||
|
accounting.
|
||||||
|
|
||||||
|
`git diff -b` is probably the best way to view this change since much of
|
||||||
|
the diff is whitespace changes.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit 657472b2a50f67b12e5bbe5827582c9c2bb82dc3)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 6be109d07f7fcce0..827c43b369836de9 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -1004,6 +1004,32 @@ try_simple_gethostbyname (const char *name, const struct addrinfo *req,
|
||||||
|
return -EAI_NODATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Add local address information into RES. RES->AT is assumed to have enough
|
||||||
|
+ space for two tuples and is zeroed out. */
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+get_local_addresses (const struct addrinfo *req, struct gaih_result *res)
|
||||||
|
+{
|
||||||
|
+ struct gaih_addrtuple *atr = res->at;
|
||||||
|
+ if (req->ai_family == AF_UNSPEC)
|
||||||
|
+ res->at->next = res->at + 1;
|
||||||
|
+
|
||||||
|
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||||||
|
+ {
|
||||||
|
+ res->at->family = AF_INET6;
|
||||||
|
+ if ((req->ai_flags & AI_PASSIVE) == 0)
|
||||||
|
+ memcpy (res->at->addr, &in6addr_loopback, sizeof (struct in6_addr));
|
||||||
|
+ atr = res->at->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
|
||||||
|
+ {
|
||||||
|
+ atr->family = AF_INET;
|
||||||
|
+ if ((req->ai_flags & AI_PASSIVE) == 0)
|
||||||
|
+ atr->addr[0] = htonl (INADDR_LOOPBACK);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
const struct addrinfo *req, struct addrinfo **pai,
|
||||||
|
@@ -1014,10 +1040,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
|
const char *orig_name = name;
|
||||||
|
|
||||||
|
- /* Reserve stack memory for the scratch buffer in the getaddrinfo
|
||||||
|
- function. */
|
||||||
|
- size_t alloca_used = sizeof (struct scratch_buffer);
|
||||||
|
-
|
||||||
|
int rc;
|
||||||
|
if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0)
|
||||||
|
return rc;
|
||||||
|
@@ -1027,76 +1049,51 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
struct gaih_result res = {0};
|
||||||
|
- if (name != NULL)
|
||||||
|
+ struct gaih_addrtuple local_at[2] = {0};
|
||||||
|
+
|
||||||
|
+ res.at = local_at;
|
||||||
|
+
|
||||||
|
+ if (__glibc_unlikely (name == NULL))
|
||||||
|
{
|
||||||
|
- if (req->ai_flags & AI_IDN)
|
||||||
|
- {
|
||||||
|
- char *out;
|
||||||
|
- result = __idna_to_dns_encoding (name, &out);
|
||||||
|
- if (result != 0)
|
||||||
|
- return -result;
|
||||||
|
- name = out;
|
||||||
|
- malloc_name = true;
|
||||||
|
- }
|
||||||
|
+ get_local_addresses (req, &res);
|
||||||
|
+ goto process_list;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- res.at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||||||
|
- res.at->scopeid = 0;
|
||||||
|
- res.at->next = NULL;
|
||||||
|
+ if (req->ai_flags & AI_IDN)
|
||||||
|
+ {
|
||||||
|
+ char *out;
|
||||||
|
+ result = __idna_to_dns_encoding (name, &out);
|
||||||
|
+ if (result != 0)
|
||||||
|
+ return -result;
|
||||||
|
+ name = out;
|
||||||
|
+ malloc_name = true;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if ((result = text_to_binary_address (name, req, &res)) != 0)
|
||||||
|
- goto free_and_return;
|
||||||
|
- else if (res.at != NULL)
|
||||||
|
- goto process_list;
|
||||||
|
+ if ((result = text_to_binary_address (name, req, &res)) != 0)
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ else if (res.at != NULL)
|
||||||
|
+ goto process_list;
|
||||||
|
|
||||||
|
- if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0)
|
||||||
|
- goto free_and_return;
|
||||||
|
- else if (res.at != NULL)
|
||||||
|
- goto process_list;
|
||||||
|
+ if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0)
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ else if (res.at != NULL)
|
||||||
|
+ goto process_list;
|
||||||
|
|
||||||
|
#ifdef USE_NSCD
|
||||||
|
- if ((result = get_nscd_addresses (name, req, &res)) != 0)
|
||||||
|
- goto free_and_return;
|
||||||
|
- else if (res.at != NULL)
|
||||||
|
- goto process_list;
|
||||||
|
+ if ((result = get_nscd_addresses (name, req, &res)) != 0)
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ else if (res.at != NULL)
|
||||||
|
+ goto process_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0)
|
||||||
|
- goto free_and_return;
|
||||||
|
- else if (res.at != NULL)
|
||||||
|
- goto process_list;
|
||||||
|
-
|
||||||
|
- /* None of the lookups worked, so name not found. */
|
||||||
|
- result = -EAI_NONAME;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- struct gaih_addrtuple *atr;
|
||||||
|
- atr = res.at = alloca_account (sizeof (struct gaih_addrtuple),
|
||||||
|
- alloca_used);
|
||||||
|
- memset (res.at, '\0', sizeof (struct gaih_addrtuple));
|
||||||
|
-
|
||||||
|
- if (req->ai_family == AF_UNSPEC)
|
||||||
|
- {
|
||||||
|
- res.at->next = __alloca (sizeof (struct gaih_addrtuple));
|
||||||
|
- memset (res.at->next, '\0', sizeof (struct gaih_addrtuple));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||||||
|
- {
|
||||||
|
- res.at->family = AF_INET6;
|
||||||
|
- if ((req->ai_flags & AI_PASSIVE) == 0)
|
||||||
|
- memcpy (res.at->addr, &in6addr_loopback, sizeof (struct in6_addr));
|
||||||
|
- atr = res.at->next;
|
||||||
|
- }
|
||||||
|
+ if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0)
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ else if (res.at != NULL)
|
||||||
|
+ goto process_list;
|
||||||
|
|
||||||
|
- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
|
||||||
|
- {
|
||||||
|
- atr->family = AF_INET;
|
||||||
|
- if ((req->ai_flags & AI_PASSIVE) == 0)
|
||||||
|
- atr->addr[0] = htonl (INADDR_LOOPBACK);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ /* None of the lookups worked, so name not found. */
|
||||||
|
+ result = -EAI_NONAME;
|
||||||
|
+ goto free_and_return;
|
||||||
|
|
||||||
|
process_list:
|
||||||
|
{
|
@ -0,0 +1,208 @@
|
|||||||
|
commit 92478a808f477480adbc5ca3d9a4a1bc27fc13ae
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Mon Mar 7 20:38:31 2022 +0530
|
||||||
|
|
||||||
|
gaih_inet: Split result generation into its own function
|
||||||
|
|
||||||
|
Simplify the loop a wee bit and clean up variable names too.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit ac4653ef503d1e87893d1a6714748a1cdf4bf7ad)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 827c43b369836de9..1008f247365ea009 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -1030,6 +1030,87 @@ get_local_addresses (const struct addrinfo *req, struct gaih_result *res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Generate results in PAI and its count in NADDRS. Return 0 on success or an
|
||||||
|
+ error code on failure. */
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+generate_addrinfo (const struct addrinfo *req, struct gaih_result *res,
|
||||||
|
+ const struct gaih_servtuple *st, struct addrinfo **pai,
|
||||||
|
+ unsigned int *naddrs)
|
||||||
|
+{
|
||||||
|
+ size_t socklen;
|
||||||
|
+ sa_family_t family;
|
||||||
|
+
|
||||||
|
+ /* Buffer is the size of an unformatted IPv6 address in printable format. */
|
||||||
|
+ for (struct gaih_addrtuple *at = res->at; at != NULL; at = at->next)
|
||||||
|
+ {
|
||||||
|
+ family = at->family;
|
||||||
|
+ if (family == AF_INET6)
|
||||||
|
+ {
|
||||||
|
+ socklen = sizeof (struct sockaddr_in6);
|
||||||
|
+
|
||||||
|
+ /* If we looked up IPv4 mapped address discard them here if
|
||||||
|
+ the caller isn't interested in all address and we have
|
||||||
|
+ found at least one IPv6 address. */
|
||||||
|
+ if (res->got_ipv6
|
||||||
|
+ && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
|
||||||
|
+ && IN6_IS_ADDR_V4MAPPED (at->addr))
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ socklen = sizeof (struct sockaddr_in);
|
||||||
|
+
|
||||||
|
+ for (int i = 0; st[i].set; i++)
|
||||||
|
+ {
|
||||||
|
+ struct addrinfo *ai;
|
||||||
|
+ ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
|
||||||
|
+ if (ai == NULL)
|
||||||
|
+ return -EAI_MEMORY;
|
||||||
|
+
|
||||||
|
+ ai->ai_flags = req->ai_flags;
|
||||||
|
+ ai->ai_family = family;
|
||||||
|
+ ai->ai_socktype = st[i].socktype;
|
||||||
|
+ ai->ai_protocol = st[i].protocol;
|
||||||
|
+ ai->ai_addrlen = socklen;
|
||||||
|
+ ai->ai_addr = (void *) (ai + 1);
|
||||||
|
+
|
||||||
|
+ /* We only add the canonical name once. */
|
||||||
|
+ ai->ai_canonname = res->canon;
|
||||||
|
+ res->canon = NULL;
|
||||||
|
+
|
||||||
|
+#ifdef _HAVE_SA_LEN
|
||||||
|
+ ai->ai_addr->sa_len = socklen;
|
||||||
|
+#endif /* _HAVE_SA_LEN */
|
||||||
|
+ ai->ai_addr->sa_family = family;
|
||||||
|
+
|
||||||
|
+ /* In case of an allocation error the list must be NULL
|
||||||
|
+ terminated. */
|
||||||
|
+ ai->ai_next = NULL;
|
||||||
|
+
|
||||||
|
+ if (family == AF_INET6)
|
||||||
|
+ {
|
||||||
|
+ struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) ai->ai_addr;
|
||||||
|
+ sin6p->sin6_port = st[i].port;
|
||||||
|
+ sin6p->sin6_flowinfo = 0;
|
||||||
|
+ memcpy (&sin6p->sin6_addr, at->addr, sizeof (struct in6_addr));
|
||||||
|
+ sin6p->sin6_scope_id = at->scopeid;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ struct sockaddr_in *sinp = (struct sockaddr_in *) ai->ai_addr;
|
||||||
|
+ sinp->sin_port = st[i].port;
|
||||||
|
+ memcpy (&sinp->sin_addr, at->addr, sizeof (struct in_addr));
|
||||||
|
+ memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pai = &(ai->ai_next);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ++*naddrs;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
const struct addrinfo *req, struct addrinfo **pai,
|
||||||
|
@@ -1096,98 +1177,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
goto free_and_return;
|
||||||
|
|
||||||
|
process_list:
|
||||||
|
- {
|
||||||
|
- /* Set up the canonical name if we need it. */
|
||||||
|
- if ((result = process_canonname (req, orig_name, &res)) != 0)
|
||||||
|
- goto free_and_return;
|
||||||
|
-
|
||||||
|
- struct gaih_addrtuple *at2 = res.at;
|
||||||
|
- size_t socklen;
|
||||||
|
- sa_family_t family;
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- buffer is the size of an unformatted IPv6 address in printable format.
|
||||||
|
- */
|
||||||
|
- while (at2 != NULL)
|
||||||
|
- {
|
||||||
|
- family = at2->family;
|
||||||
|
- if (family == AF_INET6)
|
||||||
|
- {
|
||||||
|
- socklen = sizeof (struct sockaddr_in6);
|
||||||
|
-
|
||||||
|
- /* If we looked up IPv4 mapped address discard them here if
|
||||||
|
- the caller isn't interested in all address and we have
|
||||||
|
- found at least one IPv6 address. */
|
||||||
|
- if (res.got_ipv6
|
||||||
|
- && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
|
||||||
|
- && IN6_IS_ADDR_V4MAPPED (at2->addr))
|
||||||
|
- goto ignore;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- socklen = sizeof (struct sockaddr_in);
|
||||||
|
-
|
||||||
|
- for (int i = 0; st[i].set; i++)
|
||||||
|
- {
|
||||||
|
- struct addrinfo *ai;
|
||||||
|
- ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
|
||||||
|
- if (ai == NULL)
|
||||||
|
- {
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ai->ai_flags = req->ai_flags;
|
||||||
|
- ai->ai_family = family;
|
||||||
|
- ai->ai_socktype = st[i].socktype;
|
||||||
|
- ai->ai_protocol = st[i].protocol;
|
||||||
|
- ai->ai_addrlen = socklen;
|
||||||
|
- ai->ai_addr = (void *) (ai + 1);
|
||||||
|
-
|
||||||
|
- /* We only add the canonical name once. */
|
||||||
|
- ai->ai_canonname = res.canon;
|
||||||
|
- res.canon = NULL;
|
||||||
|
-
|
||||||
|
-#ifdef _HAVE_SA_LEN
|
||||||
|
- ai->ai_addr->sa_len = socklen;
|
||||||
|
-#endif /* _HAVE_SA_LEN */
|
||||||
|
- ai->ai_addr->sa_family = family;
|
||||||
|
-
|
||||||
|
- /* In case of an allocation error the list must be NULL
|
||||||
|
- terminated. */
|
||||||
|
- ai->ai_next = NULL;
|
||||||
|
-
|
||||||
|
- if (family == AF_INET6)
|
||||||
|
- {
|
||||||
|
- struct sockaddr_in6 *sin6p =
|
||||||
|
- (struct sockaddr_in6 *) ai->ai_addr;
|
||||||
|
-
|
||||||
|
- sin6p->sin6_port = st[i].port;
|
||||||
|
- sin6p->sin6_flowinfo = 0;
|
||||||
|
- memcpy (&sin6p->sin6_addr,
|
||||||
|
- at2->addr, sizeof (struct in6_addr));
|
||||||
|
- sin6p->sin6_scope_id = at2->scopeid;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- struct sockaddr_in *sinp =
|
||||||
|
- (struct sockaddr_in *) ai->ai_addr;
|
||||||
|
- sinp->sin_port = st[i].port;
|
||||||
|
- memcpy (&sinp->sin_addr,
|
||||||
|
- at2->addr, sizeof (struct in_addr));
|
||||||
|
- memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- pai = &(ai->ai_next);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ++*naddrs;
|
||||||
|
+ /* Set up the canonical name if we need it. */
|
||||||
|
+ if ((result = process_canonname (req, orig_name, &res)) != 0)
|
||||||
|
+ goto free_and_return;
|
||||||
|
|
||||||
|
- ignore:
|
||||||
|
- at2 = at2->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ result = generate_addrinfo (req, &res, st, pai, naddrs);
|
||||||
|
|
||||||
|
- free_and_return:
|
||||||
|
+free_and_return:
|
||||||
|
if (malloc_name)
|
||||||
|
free ((char *) name);
|
||||||
|
free (addrmem);
|
@ -0,0 +1,34 @@
|
|||||||
|
commit cc4544ef8069a14c67a46b7e8e28eff1dc102050
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed Mar 2 11:45:29 2022 +0530
|
||||||
|
|
||||||
|
gethosts: Return EAI_MEMORY on allocation failure
|
||||||
|
|
||||||
|
All other cases of failures due to lack of memory return EAI_MEMORY, so
|
||||||
|
it seems wrong to return EAI_SYSTEM here. The only reason
|
||||||
|
convert_hostent_to_gaih_addrtuple could fail is on calloc failure.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit b587456c0e7b59dcfdbd2d44db000a3bc8244e57)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 1008f247365ea009..37260d6e6f292186 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -303,13 +303,13 @@ gethosts (nss_gethostbyname3_r fct, int family, const char *name,
|
||||||
|
else if (status == NSS_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
if (!convert_hostent_to_gaih_addrtuple (req, family, &th, res))
|
||||||
|
- return -EAI_SYSTEM;
|
||||||
|
+ return -EAI_MEMORY;
|
||||||
|
|
||||||
|
if (localcanon != NULL && res->canon == NULL)
|
||||||
|
{
|
||||||
|
char *canonbuf = __strdup (localcanon);
|
||||||
|
if (canonbuf == NULL)
|
||||||
|
- return -EAI_SYSTEM;
|
||||||
|
+ return -EAI_MEMORY;
|
||||||
|
res->canon = canonbuf;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,316 @@
|
|||||||
|
commit e09ee267c03e3150c2c9ba28625ab130705a485e
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Fri Sep 15 13:51:12 2023 -0400
|
||||||
|
|
||||||
|
getaddrinfo: Fix use after free in getcanonname (CVE-2023-4806)
|
||||||
|
|
||||||
|
When an NSS plugin only implements the _gethostbyname2_r and
|
||||||
|
_getcanonname_r callbacks, getaddrinfo could use memory that was freed
|
||||||
|
during tmpbuf resizing, through h_name in a previous query response.
|
||||||
|
|
||||||
|
The backing store for res->at->name when doing a query with
|
||||||
|
gethostbyname3_r or gethostbyname2_r is tmpbuf, which is reallocated in
|
||||||
|
gethosts during the query. For AF_INET6 lookup with AI_ALL |
|
||||||
|
AI_V4MAPPED, gethosts gets called twice, once for a v6 lookup and second
|
||||||
|
for a v4 lookup. In this case, if the first call reallocates tmpbuf
|
||||||
|
enough number of times, resulting in a malloc, th->h_name (that
|
||||||
|
res->at->name refers to) ends up on a heap allocated storage in tmpbuf.
|
||||||
|
Now if the second call to gethosts also causes the plugin callback to
|
||||||
|
return NSS_STATUS_TRYAGAIN, tmpbuf will get freed, resulting in a UAF
|
||||||
|
reference in res->at->name. This then gets dereferenced in the
|
||||||
|
getcanonname_r plugin call, resulting in the use after free.
|
||||||
|
|
||||||
|
Fix this by copying h_name over and freeing it at the end. This
|
||||||
|
resolves BZ #30843, which is assigned CVE-2023-4806.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
(cherry picked from commit 973fe93a5675c42798b2161c6f29c01b0e243994)
|
||||||
|
|
||||||
|
diff --git a/nss/Makefile b/nss/Makefile
|
||||||
|
index 333edb1588ede881..64b29745131d3cf5 100644
|
||||||
|
--- a/nss/Makefile
|
||||||
|
+++ b/nss/Makefile
|
||||||
|
@@ -81,6 +81,7 @@ tests-container := \
|
||||||
|
tst-nss-test3 \
|
||||||
|
tst-reload1 \
|
||||||
|
tst-reload2 \
|
||||||
|
+ tst-nss-gai-hv2-canonname \
|
||||||
|
# tests-container
|
||||||
|
|
||||||
|
# Tests which need libdl
|
||||||
|
@@ -144,7 +145,8 @@ libnss_compat-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||||
|
ifeq ($(build-static-nss),yes)
|
||||||
|
tests-static += tst-nss-static
|
||||||
|
endif
|
||||||
|
-extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os
|
||||||
|
+extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os \
|
||||||
|
+ nss_test_gai_hv2_canonname.os
|
||||||
|
|
||||||
|
include ../Rules
|
||||||
|
|
||||||
|
@@ -179,12 +181,16 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
|
||||||
|
libof-nss_test1 = extramodules
|
||||||
|
libof-nss_test2 = extramodules
|
||||||
|
libof-nss_test_errno = extramodules
|
||||||
|
+libof-nss_test_gai_hv2_canonname = extramodules
|
||||||
|
$(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps)
|
||||||
|
$(build-module)
|
||||||
|
$(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps)
|
||||||
|
$(build-module)
|
||||||
|
$(objpfx)/libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps)
|
||||||
|
$(build-module)
|
||||||
|
+$(objpfx)/libnss_test_gai_hv2_canonname.so: \
|
||||||
|
+ $(objpfx)nss_test_gai_hv2_canonname.os $(link-libc-deps)
|
||||||
|
+ $(build-module)
|
||||||
|
$(objpfx)nss_test2.os : nss_test1.c
|
||||||
|
# Use the nss_files suffix for these objects as well.
|
||||||
|
$(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so
|
||||||
|
@@ -194,10 +200,14 @@ $(objpfx)/libnss_test2.so$(libnss_files.so-version): $(objpfx)/libnss_test2.so
|
||||||
|
$(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \
|
||||||
|
$(objpfx)/libnss_test_errno.so
|
||||||
|
$(make-link)
|
||||||
|
+$(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): \
|
||||||
|
+ $(objpfx)/libnss_test_gai_hv2_canonname.so
|
||||||
|
+ $(make-link)
|
||||||
|
$(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \
|
||||||
|
$(objpfx)/libnss_test1.so$(libnss_files.so-version) \
|
||||||
|
$(objpfx)/libnss_test2.so$(libnss_files.so-version) \
|
||||||
|
- $(objpfx)/libnss_test_errno.so$(libnss_files.so-version)
|
||||||
|
+ $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) \
|
||||||
|
+ $(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version)
|
||||||
|
|
||||||
|
ifeq (yes,$(have-thread-library))
|
||||||
|
$(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library)
|
||||||
|
diff --git a/nss/nss_test_gai_hv2_canonname.c b/nss/nss_test_gai_hv2_canonname.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..4439c83c9f40cf43
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nss/nss_test_gai_hv2_canonname.c
|
||||||
|
@@ -0,0 +1,56 @@
|
||||||
|
+/* NSS service provider that only provides gethostbyname2_r.
|
||||||
|
+ Copyright The GNU Toolchain Authors.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <nss.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include "nss/tst-nss-gai-hv2-canonname.h"
|
||||||
|
+
|
||||||
|
+/* Catch misnamed and functions. */
|
||||||
|
+#pragma GCC diagnostic error "-Wmissing-prototypes"
|
||||||
|
+NSS_DECLARE_MODULE_FUNCTIONS (test_gai_hv2_canonname)
|
||||||
|
+
|
||||||
|
+extern enum nss_status _nss_files_gethostbyname2_r (const char *, int,
|
||||||
|
+ struct hostent *, char *,
|
||||||
|
+ size_t, int *, int *);
|
||||||
|
+
|
||||||
|
+enum nss_status
|
||||||
|
+_nss_test_gai_hv2_canonname_gethostbyname2_r (const char *name, int af,
|
||||||
|
+ struct hostent *result,
|
||||||
|
+ char *buffer, size_t buflen,
|
||||||
|
+ int *errnop, int *herrnop)
|
||||||
|
+{
|
||||||
|
+ return _nss_files_gethostbyname2_r (name, af, result, buffer, buflen, errnop,
|
||||||
|
+ herrnop);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+enum nss_status
|
||||||
|
+_nss_test_gai_hv2_canonname_getcanonname_r (const char *name, char *buffer,
|
||||||
|
+ size_t buflen, char **result,
|
||||||
|
+ int *errnop, int *h_errnop)
|
||||||
|
+{
|
||||||
|
+ /* We expect QUERYNAME, which is a small enough string that it shouldn't fail
|
||||||
|
+ the test. */
|
||||||
|
+ if (memcmp (QUERYNAME, name, sizeof (QUERYNAME))
|
||||||
|
+ || buflen < sizeof (QUERYNAME))
|
||||||
|
+ abort ();
|
||||||
|
+
|
||||||
|
+ strncpy (buffer, name, buflen);
|
||||||
|
+ *result = buffer;
|
||||||
|
+ return NSS_STATUS_SUCCESS;
|
||||||
|
+}
|
||||||
|
diff --git a/nss/tst-nss-gai-hv2-canonname.c b/nss/tst-nss-gai-hv2-canonname.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..d5f10c07d6a90773
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nss/tst-nss-gai-hv2-canonname.c
|
||||||
|
@@ -0,0 +1,63 @@
|
||||||
|
+/* Test NSS query path for plugins that only implement gethostbyname2
|
||||||
|
+ (#30843).
|
||||||
|
+ Copyright The GNU Toolchain Authors.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <nss.h>
|
||||||
|
+#include <netdb.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include "nss/tst-nss-gai-hv2-canonname.h"
|
||||||
|
+
|
||||||
|
+#define PREPARE do_prepare
|
||||||
|
+
|
||||||
|
+static void do_prepare (int a, char **av)
|
||||||
|
+{
|
||||||
|
+ FILE *hosts = xfopen ("/etc/hosts", "w");
|
||||||
|
+ for (unsigned i = 2; i < 255; i++)
|
||||||
|
+ {
|
||||||
|
+ fprintf (hosts, "ff01::ff02:ff03:%u:2\ttest.example.com\n", i);
|
||||||
|
+ fprintf (hosts, "192.168.0.%u\ttest.example.com\n", i);
|
||||||
|
+ }
|
||||||
|
+ xfclose (hosts);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ __nss_configure_lookup ("hosts", "test_gai_hv2_canonname");
|
||||||
|
+
|
||||||
|
+ struct addrinfo hints = {};
|
||||||
|
+ struct addrinfo *result = NULL;
|
||||||
|
+
|
||||||
|
+ hints.ai_family = AF_INET6;
|
||||||
|
+ hints.ai_flags = AI_ALL | AI_V4MAPPED | AI_CANONNAME;
|
||||||
|
+
|
||||||
|
+ int ret = getaddrinfo (QUERYNAME, NULL, &hints, &result);
|
||||||
|
+
|
||||||
|
+ if (ret != 0)
|
||||||
|
+ FAIL_EXIT1 ("getaddrinfo failed: %s\n", gai_strerror (ret));
|
||||||
|
+
|
||||||
|
+ TEST_COMPARE_STRING (result->ai_canonname, QUERYNAME);
|
||||||
|
+
|
||||||
|
+ freeaddrinfo(result);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/nss/tst-nss-gai-hv2-canonname.h b/nss/tst-nss-gai-hv2-canonname.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..14f2a9cb0867dff9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nss/tst-nss-gai-hv2-canonname.h
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+#define QUERYNAME "test.example.com"
|
||||||
|
diff --git a/nss/tst-nss-gai-hv2-canonname.root/postclean.req b/nss/tst-nss-gai-hv2-canonname.root/postclean.req
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..e69de29bb2d1d643
|
||||||
|
diff --git a/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..31848b4a28524af6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+cp $B/nss/libnss_test_gai_hv2_canonname.so $L/libnss_test_gai_hv2_canonname.so.2
|
||||||
|
+su
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 37260d6e6f292186..10dc63542f337693 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -120,6 +120,7 @@ struct gaih_result
|
||||||
|
{
|
||||||
|
struct gaih_addrtuple *at;
|
||||||
|
char *canon;
|
||||||
|
+ char *h_name;
|
||||||
|
bool free_at;
|
||||||
|
bool got_ipv6;
|
||||||
|
};
|
||||||
|
@@ -165,6 +166,7 @@ gaih_result_reset (struct gaih_result *res)
|
||||||
|
if (res->free_at)
|
||||||
|
free (res->at);
|
||||||
|
free (res->canon);
|
||||||
|
+ free (res->h_name);
|
||||||
|
memset (res, 0, sizeof (*res));
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -203,9 +205,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Convert struct hostent to a list of struct gaih_addrtuple objects. h_name
|
||||||
|
- is not copied, and the struct hostent object must not be deallocated
|
||||||
|
- prematurely. The new addresses are appended to the tuple array in RES. */
|
||||||
|
+/* Convert struct hostent to a list of struct gaih_addrtuple objects. The new
|
||||||
|
+ addresses are appended to the tuple array in RES. */
|
||||||
|
static bool
|
||||||
|
convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
|
||||||
|
struct hostent *h, struct gaih_result *res)
|
||||||
|
@@ -238,6 +239,15 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
|
||||||
|
res->at = array;
|
||||||
|
res->free_at = true;
|
||||||
|
|
||||||
|
+ /* Duplicate h_name because it may get reclaimed when the underlying storage
|
||||||
|
+ is freed. */
|
||||||
|
+ if (res->h_name == NULL)
|
||||||
|
+ {
|
||||||
|
+ res->h_name = __strdup (h->h_name);
|
||||||
|
+ if (res->h_name == NULL)
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Update the next pointers on reallocation. */
|
||||||
|
for (size_t i = 0; i < old; i++)
|
||||||
|
array[i].next = array + i + 1;
|
||||||
|
@@ -262,7 +272,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
|
||||||
|
}
|
||||||
|
array[i].next = array + i + 1;
|
||||||
|
}
|
||||||
|
- array[0].name = h->h_name;
|
||||||
|
array[count - 1].next = NULL;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
@@ -324,15 +333,15 @@ gethosts (nss_gethostbyname3_r fct, int family, const char *name,
|
||||||
|
memory allocation failure. The returned string is allocated on the
|
||||||
|
heap; the caller has to free it. */
|
||||||
|
static char *
|
||||||
|
-getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
|
||||||
|
+getcanonname (nss_action_list nip, const char *hname, const char *name)
|
||||||
|
{
|
||||||
|
nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
|
||||||
|
char *s = (char *) name;
|
||||||
|
if (cfct != NULL)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
- if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
|
||||||
|
- &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
|
||||||
|
+ if (DL_CALL_FCT (cfct, (hname ?: name, buf, sizeof (buf), &s, &errno,
|
||||||
|
+ &h_errno)) != NSS_STATUS_SUCCESS)
|
||||||
|
/* If the canonical name cannot be determined, use the passed
|
||||||
|
string. */
|
||||||
|
s = (char *) name;
|
||||||
|
@@ -771,7 +780,7 @@ get_nss_addresses (const char *name, const struct addrinfo *req,
|
||||||
|
if ((req->ai_flags & AI_CANONNAME) != 0
|
||||||
|
&& res->canon == NULL)
|
||||||
|
{
|
||||||
|
- char *canonbuf = getcanonname (nip, res->at, name);
|
||||||
|
+ char *canonbuf = getcanonname (nip, res->h_name, name);
|
||||||
|
if (canonbuf == NULL)
|
||||||
|
{
|
||||||
|
__resolv_context_put (res_ctx);
|
@ -0,0 +1,37 @@
|
|||||||
|
commit 57e349b1b0df1aee2dcd19dae1f324bde25ff8f0
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Wed Dec 8 07:02:27 2021 -0800
|
||||||
|
|
||||||
|
Disable DT_RUNPATH on NSS tests [BZ #28455]
|
||||||
|
|
||||||
|
The glibc internal NSS functions should always load NSS modules from
|
||||||
|
the system. For testing purpose, disable DT_RUNPATH on NSS tests so
|
||||||
|
that the glibc internal NSS functions can load testing NSS modules
|
||||||
|
via DT_RPATH.
|
||||||
|
|
||||||
|
This partially fixes BZ #28455.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
nss/Makefile
|
||||||
|
(different test backport order)
|
||||||
|
|
||||||
|
diff --git a/nss/Makefile b/nss/Makefile
|
||||||
|
index 64b29745131d3cf5..9af46fb3a8195809 100644
|
||||||
|
--- a/nss/Makefile
|
||||||
|
+++ b/nss/Makefile
|
||||||
|
@@ -215,3 +215,13 @@ endif
|
||||||
|
|
||||||
|
$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so
|
||||||
|
$(objpfx)tst-nss-files-alias-truncated.out: $(objpfx)/libnss_files.so
|
||||||
|
+
|
||||||
|
+# Disable DT_RUNPATH on NSS tests so that the glibc internal NSS
|
||||||
|
+# functions can load testing NSS modules via DT_RPATH.
|
||||||
|
+LDFLAGS-tst-nss-test1 = -Wl,--disable-new-dtags
|
||||||
|
+LDFLAGS-tst-nss-test2 = -Wl,--disable-new-dtags
|
||||||
|
+LDFLAGS-tst-nss-test3 = -Wl,--disable-new-dtags
|
||||||
|
+LDFLAGS-tst-nss-test4 = -Wl,--disable-new-dtags
|
||||||
|
+LDFLAGS-tst-nss-test5 = -Wl,--disable-new-dtags
|
||||||
|
+LDFLAGS-tst-nss-test_errno = -Wl,--disable-new-dtags
|
||||||
|
+LDFLAGS-tst-nss-test_gai_hv2_canonname = -Wl,--disable-new-dtags
|
@ -0,0 +1,84 @@
|
|||||||
|
commit ec6b95c3303c700eb89eebeda2d7264cc184a796
|
||||||
|
Author: Romain Geissler <romain.geissler@amadeus.com>
|
||||||
|
Date: Mon Sep 25 01:21:51 2023 +0100
|
||||||
|
|
||||||
|
Fix leak in getaddrinfo introduced by the fix for CVE-2023-4806 [BZ #30843]
|
||||||
|
|
||||||
|
This patch fixes a very recently added leak in getaddrinfo.
|
||||||
|
|
||||||
|
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
|
||||||
|
diff --git a/nss/Makefile b/nss/Makefile
|
||||||
|
index 9af46fb3a8195809..62a68880198c243c 100644
|
||||||
|
--- a/nss/Makefile
|
||||||
|
+++ b/nss/Makefile
|
||||||
|
@@ -148,6 +148,15 @@ endif
|
||||||
|
extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os \
|
||||||
|
nss_test_gai_hv2_canonname.os
|
||||||
|
|
||||||
|
+ifeq ($(run-built-tests),yes)
|
||||||
|
+ifneq (no,$(PERL))
|
||||||
|
+tests-special += $(objpfx)mtrace-tst-nss-gai-hv2-canonname.out
|
||||||
|
+endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
+generated += mtrace-tst-nss-gai-hv2-canonname.out \
|
||||||
|
+ tst-nss-gai-hv2-canonname.mtrace
|
||||||
|
+
|
||||||
|
include ../Rules
|
||||||
|
|
||||||
|
ifeq (yes,$(have-selinux))
|
||||||
|
@@ -216,6 +225,17 @@ endif
|
||||||
|
$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so
|
||||||
|
$(objpfx)tst-nss-files-alias-truncated.out: $(objpfx)/libnss_files.so
|
||||||
|
|
||||||
|
+tst-nss-gai-hv2-canonname-ENV = \
|
||||||
|
+ MALLOC_TRACE=$(objpfx)tst-nss-gai-hv2-canonname.mtrace \
|
||||||
|
+ LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
|
||||||
|
+$(objpfx)mtrace-tst-nss-gai-hv2-canonname.out: \
|
||||||
|
+ $(objpfx)tst-nss-gai-hv2-canonname.out
|
||||||
|
+ { test -r $(objpfx)tst-nss-gai-hv2-canonname.mtrace \
|
||||||
|
+ || ( echo "tst-nss-gai-hv2-canonname.mtrace does not exist"; exit 77; ) \
|
||||||
|
+ && $(common-objpfx)malloc/mtrace \
|
||||||
|
+ $(objpfx)tst-nss-gai-hv2-canonname.mtrace; } > $@; \
|
||||||
|
+ $(evaluate-test)
|
||||||
|
+
|
||||||
|
# Disable DT_RUNPATH on NSS tests so that the glibc internal NSS
|
||||||
|
# functions can load testing NSS modules via DT_RPATH.
|
||||||
|
LDFLAGS-tst-nss-test1 = -Wl,--disable-new-dtags
|
||||||
|
diff --git a/nss/tst-nss-gai-hv2-canonname.c b/nss/tst-nss-gai-hv2-canonname.c
|
||||||
|
index d5f10c07d6a90773..7db53cf09da8dcb6 100644
|
||||||
|
--- a/nss/tst-nss-gai-hv2-canonname.c
|
||||||
|
+++ b/nss/tst-nss-gai-hv2-canonname.c
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
+#include <mcheck.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
#include <support/xstdio.h>
|
||||||
|
#include "nss/tst-nss-gai-hv2-canonname.h"
|
||||||
|
@@ -41,6 +42,8 @@ static void do_prepare (int a, char **av)
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
+ mtrace ();
|
||||||
|
+
|
||||||
|
__nss_configure_lookup ("hosts", "test_gai_hv2_canonname");
|
||||||
|
|
||||||
|
struct addrinfo hints = {};
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 10dc63542f337693..d6046a707f1d742a 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -1196,9 +1196,7 @@ free_and_return:
|
||||||
|
if (malloc_name)
|
||||||
|
free ((char *) name);
|
||||||
|
free (addrmem);
|
||||||
|
- if (res.free_at)
|
||||||
|
- free (res.at);
|
||||||
|
- free (res.canon);
|
||||||
|
+ gaih_result_reset (&res);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
@ -0,0 +1,248 @@
|
|||||||
|
commit b195fd86c616b147dad3a63498b79e0dedb4662b
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Mon Mar 7 22:17:36 2022 +0530
|
||||||
|
|
||||||
|
gaih_inet: Simplify canon name resolution
|
||||||
|
|
||||||
|
Simplify logic for allocation of canon to remove the canonbuf variable;
|
||||||
|
canon now always points to an allocated block. Also pull the canon name
|
||||||
|
set into a separate function.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit d01411f6bc61429fc027c38827bf3103b48eef2e)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 702d8a50e0c218d2..5c0d873e1d766099 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -285,7 +285,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
\
|
||||||
|
if (localcanon != NULL && canon == NULL) \
|
||||||
|
{ \
|
||||||
|
- canonbuf = __strdup (localcanon); \
|
||||||
|
+ char *canonbuf = __strdup (localcanon); \
|
||||||
|
if (canonbuf == NULL) \
|
||||||
|
{ \
|
||||||
|
__resolv_context_put (res_ctx); \
|
||||||
|
@@ -323,6 +323,41 @@ getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
|
||||||
|
return __strdup (name);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Process looked up canonical name and if necessary, decode to IDNA. Result
|
||||||
|
+ is a new string written to CANONP and the earlier string is freed. */
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+process_canonname (const struct addrinfo *req, const char *orig_name,
|
||||||
|
+ char **canonp)
|
||||||
|
+{
|
||||||
|
+ char *canon = *canonp;
|
||||||
|
+
|
||||||
|
+ if ((req->ai_flags & AI_CANONNAME) != 0)
|
||||||
|
+ {
|
||||||
|
+ bool do_idn = req->ai_flags & AI_CANONIDN;
|
||||||
|
+ if (do_idn)
|
||||||
|
+ {
|
||||||
|
+ char *out;
|
||||||
|
+ int rc = __idna_from_dns_encoding (canon ?: orig_name, &out);
|
||||||
|
+ if (rc == 0)
|
||||||
|
+ {
|
||||||
|
+ free (canon);
|
||||||
|
+ canon = out;
|
||||||
|
+ }
|
||||||
|
+ else if (rc == EAI_IDN_ENCODE)
|
||||||
|
+ /* Use the punycode name as a fallback. */
|
||||||
|
+ do_idn = false;
|
||||||
|
+ else
|
||||||
|
+ return -rc;
|
||||||
|
+ }
|
||||||
|
+ if (!do_idn && canon == NULL && (canon = __strdup (orig_name)) == NULL)
|
||||||
|
+ return -EAI_MEMORY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *canonp = canon;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
const struct addrinfo *req, struct addrinfo **pai,
|
||||||
|
@@ -332,7 +367,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
|
||||||
|
struct gaih_addrtuple *at = NULL;
|
||||||
|
bool got_ipv6 = false;
|
||||||
|
- const char *canon = NULL;
|
||||||
|
+ char *canon = NULL;
|
||||||
|
const char *orig_name = name;
|
||||||
|
|
||||||
|
/* Reserve stack memory for the scratch buffer in the getaddrinfo
|
||||||
|
@@ -453,7 +488,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
|
bool malloc_name = false;
|
||||||
|
struct gaih_addrtuple *addrmem = NULL;
|
||||||
|
- char *canonbuf = NULL;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
@@ -495,7 +529,15 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->ai_flags & AI_CANONNAME)
|
||||||
|
- canon = name;
|
||||||
|
+ {
|
||||||
|
+ char *canonbuf = __strdup (name);
|
||||||
|
+ if (canonbuf == NULL)
|
||||||
|
+ {
|
||||||
|
+ result = -EAI_MEMORY;
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ }
|
||||||
|
+ canon = canonbuf;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
goto process_list;
|
||||||
|
}
|
||||||
|
@@ -545,7 +587,15 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->ai_flags & AI_CANONNAME)
|
||||||
|
- canon = name;
|
||||||
|
+ {
|
||||||
|
+ char *canonbuf = __strdup (name);
|
||||||
|
+ if (canonbuf == NULL)
|
||||||
|
+ {
|
||||||
|
+ result = -EAI_MEMORY;
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ }
|
||||||
|
+ canon = canonbuf;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
goto process_list;
|
||||||
|
}
|
||||||
|
@@ -676,9 +726,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
(*pat)->next = NULL;
|
||||||
|
if (added_canon || air->canon == NULL)
|
||||||
|
(*pat)->name = NULL;
|
||||||
|
- else if (canonbuf == NULL)
|
||||||
|
+ else if (canon == NULL)
|
||||||
|
{
|
||||||
|
- canonbuf = __strdup (air->canon);
|
||||||
|
+ char *canonbuf = __strdup (air->canon);
|
||||||
|
if (canonbuf == NULL)
|
||||||
|
{
|
||||||
|
result = -EAI_MEMORY;
|
||||||
|
@@ -748,9 +798,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
/* Always start afresh; continue should discard previous results
|
||||||
|
and the hosts database does not support merge. */
|
||||||
|
at = NULL;
|
||||||
|
- free (canonbuf);
|
||||||
|
+ free (canon);
|
||||||
|
free (addrmem);
|
||||||
|
- canon = canonbuf = NULL;
|
||||||
|
+ canon = NULL;
|
||||||
|
addrmem = NULL;
|
||||||
|
got_ipv6 = false;
|
||||||
|
|
||||||
|
@@ -805,7 +855,16 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
no_data = 1;
|
||||||
|
|
||||||
|
if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
|
||||||
|
- canon = at->name;
|
||||||
|
+ {
|
||||||
|
+ char *canonbuf = __strdup (at->name);
|
||||||
|
+ if (canonbuf == NULL)
|
||||||
|
+ {
|
||||||
|
+ __resolv_context_put (res_ctx);
|
||||||
|
+ result = -EAI_MEMORY;
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ }
|
||||||
|
+ canon = canonbuf;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
struct gaih_addrtuple **pat = &at;
|
||||||
|
|
||||||
|
@@ -893,7 +952,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
if ((req->ai_flags & AI_CANONNAME) != 0
|
||||||
|
&& canon == NULL)
|
||||||
|
{
|
||||||
|
- canonbuf = getcanonname (nip, at, name);
|
||||||
|
+ char *canonbuf = getcanonname (nip, at, name);
|
||||||
|
if (canonbuf == NULL)
|
||||||
|
{
|
||||||
|
__resolv_context_put (res_ctx);
|
||||||
|
@@ -1004,6 +1063,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
+ /* Set up the canonical name if we need it. */
|
||||||
|
+ if ((result = process_canonname (req, orig_name, &canon)) != 0)
|
||||||
|
+ goto free_and_return;
|
||||||
|
+
|
||||||
|
struct gaih_servtuple *st2;
|
||||||
|
struct gaih_addrtuple *at2 = at;
|
||||||
|
size_t socklen;
|
||||||
|
@@ -1014,48 +1077,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
*/
|
||||||
|
while (at2 != NULL)
|
||||||
|
{
|
||||||
|
- /* Only the first entry gets the canonical name. */
|
||||||
|
- if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
|
||||||
|
- {
|
||||||
|
- if (canon == NULL)
|
||||||
|
- /* If the canonical name cannot be determined, use
|
||||||
|
- the passed in string. */
|
||||||
|
- canon = orig_name;
|
||||||
|
-
|
||||||
|
- bool do_idn = req->ai_flags & AI_CANONIDN;
|
||||||
|
- if (do_idn)
|
||||||
|
- {
|
||||||
|
- char *out;
|
||||||
|
- int rc = __idna_from_dns_encoding (canon, &out);
|
||||||
|
- if (rc == 0)
|
||||||
|
- canon = out;
|
||||||
|
- else if (rc == EAI_IDN_ENCODE)
|
||||||
|
- /* Use the punycode name as a fallback. */
|
||||||
|
- do_idn = false;
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- result = -rc;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if (!do_idn)
|
||||||
|
- {
|
||||||
|
- if (canonbuf != NULL)
|
||||||
|
- /* We already allocated the string using malloc, but
|
||||||
|
- the buffer is now owned by canon. */
|
||||||
|
- canonbuf = NULL;
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- canon = __strdup (canon);
|
||||||
|
- if (canon == NULL)
|
||||||
|
- {
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
family = at2->family;
|
||||||
|
if (family == AF_INET6)
|
||||||
|
{
|
||||||
|
@@ -1078,7 +1099,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
|
||||||
|
if (ai == NULL)
|
||||||
|
{
|
||||||
|
- free ((char *) canon);
|
||||||
|
result = -EAI_MEMORY;
|
||||||
|
goto free_and_return;
|
||||||
|
}
|
||||||
|
@@ -1138,7 +1158,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
if (malloc_name)
|
||||||
|
free ((char *) name);
|
||||||
|
free (addrmem);
|
||||||
|
- free (canonbuf);
|
||||||
|
+ free (canon);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
commit f7efb43738f255db32cfa4e84a491c09f6da66e2
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Thu Mar 3 23:07:42 2022 +0530
|
||||||
|
|
||||||
|
getaddrinfo: Fix leak with AI_ALL [BZ #28852]
|
||||||
|
|
||||||
|
Use realloc in convert_hostent_to_gaih_addrtuple and fix up pointers in
|
||||||
|
the result list so that a single block is maintained for
|
||||||
|
hostbyname3_r/hostbyname2_r and freed in gaih_inet. This result is
|
||||||
|
never merged with any other results, since the hosts database does not
|
||||||
|
permit merging.
|
||||||
|
|
||||||
|
Resolves BZ #28852.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit 300460460706ce3ffe29a7df8966e68323ec5bf1)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 5c0d873e1d766099..ed70e6cb3944d219 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -189,19 +189,16 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Convert struct hostent to a list of struct gaih_addrtuple objects.
|
||||||
|
- h_name is not copied, and the struct hostent object must not be
|
||||||
|
- deallocated prematurely. *RESULT must be NULL or a pointer to a
|
||||||
|
- linked-list. The new addresses are appended at the end. */
|
||||||
|
+/* Convert struct hostent to a list of struct gaih_addrtuple objects. h_name
|
||||||
|
+ is not copied, and the struct hostent object must not be deallocated
|
||||||
|
+ prematurely. The new addresses are appended to the tuple array in
|
||||||
|
+ RESULT. */
|
||||||
|
static bool
|
||||||
|
convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
int family,
|
||||||
|
struct hostent *h,
|
||||||
|
struct gaih_addrtuple **result)
|
||||||
|
{
|
||||||
|
- while (*result)
|
||||||
|
- result = &(*result)->next;
|
||||||
|
-
|
||||||
|
/* Count the number of addresses in h->h_addr_list. */
|
||||||
|
size_t count = 0;
|
||||||
|
for (char **p = h->h_addr_list; *p != NULL; ++p)
|
||||||
|
@@ -212,10 +209,30 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
- struct gaih_addrtuple *array = calloc (count, sizeof (*array));
|
||||||
|
+ struct gaih_addrtuple *array = *result;
|
||||||
|
+ size_t old = 0;
|
||||||
|
+
|
||||||
|
+ while (array != NULL)
|
||||||
|
+ {
|
||||||
|
+ old++;
|
||||||
|
+ array = array->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ array = realloc (*result, (old + count) * sizeof (*array));
|
||||||
|
+
|
||||||
|
if (array == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
+ *result = array;
|
||||||
|
+
|
||||||
|
+ /* Update the next pointers on reallocation. */
|
||||||
|
+ for (size_t i = 0; i < old; i++)
|
||||||
|
+ array[i].next = array + i + 1;
|
||||||
|
+
|
||||||
|
+ array += old;
|
||||||
|
+
|
||||||
|
+ memset (array, 0, count * sizeof (*array));
|
||||||
|
+
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (family == AF_INET && req->ai_family == AF_INET6)
|
||||||
|
@@ -235,7 +252,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
array[0].name = h->h_name;
|
||||||
|
array[count - 1].next = NULL;
|
||||||
|
|
||||||
|
- *result = array;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,285 @@
|
|||||||
|
commit e05e5889b8a307fe4be55b03bcbd7a1c62fc2f2d
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Thu Feb 10 13:27:11 2022 +0530
|
||||||
|
|
||||||
|
gaih_inet: Simplify service resolution
|
||||||
|
|
||||||
|
Refactor the code to split out the service resolution code into a
|
||||||
|
separate function. Allocate the service tuples array just once to the
|
||||||
|
size of the typeproto array, thus avoiding the unnecessary pointer
|
||||||
|
chasing and stack allocations.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit 8d6cf99f2fb81a097f9334c125e5c23604af1a98)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index ed70e6cb3944d219..8c78ef9570fe0f58 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -100,14 +100,12 @@ struct gaih_service
|
||||||
|
|
||||||
|
struct gaih_servtuple
|
||||||
|
{
|
||||||
|
- struct gaih_servtuple *next;
|
||||||
|
int socktype;
|
||||||
|
int protocol;
|
||||||
|
int port;
|
||||||
|
+ bool set;
|
||||||
|
};
|
||||||
|
|
||||||
|
-static const struct gaih_servtuple nullserv;
|
||||||
|
-
|
||||||
|
|
||||||
|
struct gaih_typeproto
|
||||||
|
{
|
||||||
|
@@ -180,11 +178,11 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||||
|
}
|
||||||
|
while (r);
|
||||||
|
|
||||||
|
- st->next = NULL;
|
||||||
|
st->socktype = tp->socktype;
|
||||||
|
st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
|
||||||
|
? req->ai_protocol : tp->protocol);
|
||||||
|
st->port = s->s_port;
|
||||||
|
+ st->set = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -375,20 +373,11 @@ process_canonname (const struct addrinfo *req, const char *orig_name,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
- const struct addrinfo *req, struct addrinfo **pai,
|
||||||
|
- unsigned int *naddrs, struct scratch_buffer *tmpbuf)
|
||||||
|
+get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
|
||||||
|
+ struct gaih_servtuple *st, struct scratch_buffer *tmpbuf)
|
||||||
|
{
|
||||||
|
+ int i;
|
||||||
|
const struct gaih_typeproto *tp = gaih_inet_typeproto;
|
||||||
|
- struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
|
||||||
|
- struct gaih_addrtuple *at = NULL;
|
||||||
|
- bool got_ipv6 = false;
|
||||||
|
- char *canon = NULL;
|
||||||
|
- const char *orig_name = name;
|
||||||
|
-
|
||||||
|
- /* Reserve stack memory for the scratch buffer in the getaddrinfo
|
||||||
|
- function. */
|
||||||
|
- size_t alloca_used = sizeof (struct scratch_buffer);
|
||||||
|
|
||||||
|
if (req->ai_protocol || req->ai_socktype)
|
||||||
|
{
|
||||||
|
@@ -410,98 +399,88 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- int port = 0;
|
||||||
|
- if (service != NULL)
|
||||||
|
+ if (service != NULL && (tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
|
||||||
|
+ return -EAI_SERVICE;
|
||||||
|
+
|
||||||
|
+ if (service == NULL || service->num >= 0)
|
||||||
|
{
|
||||||
|
- if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
|
||||||
|
- return -EAI_SERVICE;
|
||||||
|
+ int port = service != NULL ? htons (service->num) : 0;
|
||||||
|
|
||||||
|
- if (service->num < 0)
|
||||||
|
+ if (req->ai_socktype || req->ai_protocol)
|
||||||
|
{
|
||||||
|
- if (tp->name[0])
|
||||||
|
- {
|
||||||
|
- st = (struct gaih_servtuple *)
|
||||||
|
- alloca_account (sizeof (struct gaih_servtuple), alloca_used);
|
||||||
|
-
|
||||||
|
- int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf);
|
||||||
|
- if (__glibc_unlikely (rc != 0))
|
||||||
|
- return rc;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- struct gaih_servtuple **pst = &st;
|
||||||
|
- for (tp++; tp->name[0]; tp++)
|
||||||
|
- {
|
||||||
|
- struct gaih_servtuple *newp;
|
||||||
|
+ st[0].socktype = tp->socktype;
|
||||||
|
+ st[0].protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
|
||||||
|
+ ? req->ai_protocol : tp->protocol);
|
||||||
|
+ st[0].port = port;
|
||||||
|
+ st[0].set = true;
|
||||||
|
|
||||||
|
- if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
|
||||||
|
- continue;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (req->ai_socktype != 0
|
||||||
|
- && req->ai_socktype != tp->socktype)
|
||||||
|
- continue;
|
||||||
|
- if (req->ai_protocol != 0
|
||||||
|
- && !(tp->protoflag & GAI_PROTO_PROTOANY)
|
||||||
|
- && req->ai_protocol != tp->protocol)
|
||||||
|
- continue;
|
||||||
|
+ /* Neither socket type nor protocol is set. Return all socket types
|
||||||
|
+ we know about. */
|
||||||
|
+ for (i = 0, ++tp; tp->name[0]; ++tp)
|
||||||
|
+ if (tp->defaultflag)
|
||||||
|
+ {
|
||||||
|
+ st[i].socktype = tp->socktype;
|
||||||
|
+ st[i].protocol = tp->protocol;
|
||||||
|
+ st[i].port = port;
|
||||||
|
+ st[i++].set = true;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- newp = (struct gaih_servtuple *)
|
||||||
|
- alloca_account (sizeof (struct gaih_servtuple),
|
||||||
|
- alloca_used);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (gaih_inet_serv (service->name,
|
||||||
|
- tp, req, newp, tmpbuf) != 0)
|
||||||
|
- continue;
|
||||||
|
+ if (tp->name[0])
|
||||||
|
+ return gaih_inet_serv (service->name, tp, req, st, tmpbuf);
|
||||||
|
|
||||||
|
- *pst = newp;
|
||||||
|
- pst = &(newp->next);
|
||||||
|
- }
|
||||||
|
- if (st == (struct gaih_servtuple *) &nullserv)
|
||||||
|
- return -EAI_SERVICE;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- port = htons (service->num);
|
||||||
|
- goto got_port;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
+ for (i = 0, tp++; tp->name[0]; tp++)
|
||||||
|
{
|
||||||
|
- got_port:
|
||||||
|
+ if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
|
||||||
|
+ continue;
|
||||||
|
|
||||||
|
- if (req->ai_socktype || req->ai_protocol)
|
||||||
|
- {
|
||||||
|
- st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
|
||||||
|
- st->next = NULL;
|
||||||
|
- st->socktype = tp->socktype;
|
||||||
|
- st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
|
||||||
|
- ? req->ai_protocol : tp->protocol);
|
||||||
|
- st->port = port;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- /* Neither socket type nor protocol is set. Return all socket types
|
||||||
|
- we know about. */
|
||||||
|
- struct gaih_servtuple **lastp = &st;
|
||||||
|
- for (++tp; tp->name[0]; ++tp)
|
||||||
|
- if (tp->defaultflag)
|
||||||
|
- {
|
||||||
|
- struct gaih_servtuple *newp;
|
||||||
|
+ if (req->ai_socktype != 0
|
||||||
|
+ && req->ai_socktype != tp->socktype)
|
||||||
|
+ continue;
|
||||||
|
+ if (req->ai_protocol != 0
|
||||||
|
+ && !(tp->protoflag & GAI_PROTO_PROTOANY)
|
||||||
|
+ && req->ai_protocol != tp->protocol)
|
||||||
|
+ continue;
|
||||||
|
|
||||||
|
- newp = alloca_account (sizeof (struct gaih_servtuple),
|
||||||
|
- alloca_used);
|
||||||
|
- newp->next = NULL;
|
||||||
|
- newp->socktype = tp->socktype;
|
||||||
|
- newp->protocol = tp->protocol;
|
||||||
|
- newp->port = port;
|
||||||
|
+ if (gaih_inet_serv (service->name,
|
||||||
|
+ tp, req, &st[i], tmpbuf) != 0)
|
||||||
|
+ continue;
|
||||||
|
|
||||||
|
- *lastp = newp;
|
||||||
|
- lastp = &newp->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!st[0].set)
|
||||||
|
+ return -EAI_SERVICE;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
+ const struct addrinfo *req, struct addrinfo **pai,
|
||||||
|
+ unsigned int *naddrs, struct scratch_buffer *tmpbuf)
|
||||||
|
+{
|
||||||
|
+ struct gaih_servtuple st[sizeof (gaih_inet_typeproto)
|
||||||
|
+ / sizeof (struct gaih_typeproto)] = {0};
|
||||||
|
+
|
||||||
|
+ struct gaih_addrtuple *at = NULL;
|
||||||
|
+ bool got_ipv6 = false;
|
||||||
|
+ char *canon = NULL;
|
||||||
|
+ const char *orig_name = name;
|
||||||
|
+
|
||||||
|
+ /* Reserve stack memory for the scratch buffer in the getaddrinfo
|
||||||
|
+ function. */
|
||||||
|
+ size_t alloca_used = sizeof (struct scratch_buffer);
|
||||||
|
+
|
||||||
|
+ int rc;
|
||||||
|
+ if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0)
|
||||||
|
+ return rc;
|
||||||
|
+
|
||||||
|
bool malloc_name = false;
|
||||||
|
struct gaih_addrtuple *addrmem = NULL;
|
||||||
|
int result = 0;
|
||||||
|
@@ -1083,7 +1062,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
if ((result = process_canonname (req, orig_name, &canon)) != 0)
|
||||||
|
goto free_and_return;
|
||||||
|
|
||||||
|
- struct gaih_servtuple *st2;
|
||||||
|
struct gaih_addrtuple *at2 = at;
|
||||||
|
size_t socklen;
|
||||||
|
sa_family_t family;
|
||||||
|
@@ -1109,7 +1087,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
else
|
||||||
|
socklen = sizeof (struct sockaddr_in);
|
||||||
|
|
||||||
|
- for (st2 = st; st2 != NULL; st2 = st2->next)
|
||||||
|
+ for (int i = 0; st[i].set; i++)
|
||||||
|
{
|
||||||
|
struct addrinfo *ai;
|
||||||
|
ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
|
||||||
|
@@ -1121,8 +1099,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
|
ai->ai_flags = req->ai_flags;
|
||||||
|
ai->ai_family = family;
|
||||||
|
- ai->ai_socktype = st2->socktype;
|
||||||
|
- ai->ai_protocol = st2->protocol;
|
||||||
|
+ ai->ai_socktype = st[i].socktype;
|
||||||
|
+ ai->ai_protocol = st[i].protocol;
|
||||||
|
ai->ai_addrlen = socklen;
|
||||||
|
ai->ai_addr = (void *) (ai + 1);
|
||||||
|
|
||||||
|
@@ -1144,7 +1122,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
struct sockaddr_in6 *sin6p =
|
||||||
|
(struct sockaddr_in6 *) ai->ai_addr;
|
||||||
|
|
||||||
|
- sin6p->sin6_port = st2->port;
|
||||||
|
+ sin6p->sin6_port = st[i].port;
|
||||||
|
sin6p->sin6_flowinfo = 0;
|
||||||
|
memcpy (&sin6p->sin6_addr,
|
||||||
|
at2->addr, sizeof (struct in6_addr));
|
||||||
|
@@ -1154,7 +1132,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
{
|
||||||
|
struct sockaddr_in *sinp =
|
||||||
|
(struct sockaddr_in *) ai->ai_addr;
|
||||||
|
- sinp->sin_port = st2->port;
|
||||||
|
+ sinp->sin_port = st[i].port;
|
||||||
|
memcpy (&sinp->sin_addr,
|
||||||
|
at2->addr, sizeof (struct in_addr));
|
||||||
|
memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,179 @@
|
|||||||
|
commit 3b5a3e5009088a029525277f36228eeb95032358
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Fri Mar 4 14:57:12 2022 +0530
|
||||||
|
|
||||||
|
gaih_inet: Split simple gethostbyname into its own function
|
||||||
|
|
||||||
|
Add a free_at flag in gaih_result to indicate if res.at needs to be
|
||||||
|
freed by the caller.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit b44389cb7fa28a59804571dac09cc32ebfac03d1)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 57b6834c8bb3887c..3870b2dc2edc89cd 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -120,6 +120,7 @@ struct gaih_result
|
||||||
|
{
|
||||||
|
struct gaih_addrtuple *at;
|
||||||
|
char *canon;
|
||||||
|
+ bool free_at;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Values for `protoflag'. */
|
||||||
|
@@ -565,6 +566,62 @@ out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* If possible, call the simple, old functions, which do not support IPv6 scope
|
||||||
|
+ ids, nor retrieving the canonical name. */
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+try_simple_gethostbyname (const char *name, const struct addrinfo *req,
|
||||||
|
+ struct scratch_buffer *tmpbuf,
|
||||||
|
+ struct gaih_result *res)
|
||||||
|
+{
|
||||||
|
+ res->at = NULL;
|
||||||
|
+
|
||||||
|
+ if (req->ai_family != AF_INET || (req->ai_flags & AI_CANONNAME) != 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ int rc;
|
||||||
|
+ struct hostent th;
|
||||||
|
+ struct hostent *h;
|
||||||
|
+
|
||||||
|
+ while (1)
|
||||||
|
+ {
|
||||||
|
+ rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf->data,
|
||||||
|
+ tmpbuf->length, &h, &h_errno);
|
||||||
|
+ if (rc != ERANGE || h_errno != NETDB_INTERNAL)
|
||||||
|
+ break;
|
||||||
|
+ if (!scratch_buffer_grow (tmpbuf))
|
||||||
|
+ return -EAI_MEMORY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (rc == 0)
|
||||||
|
+ {
|
||||||
|
+ if (h != NULL)
|
||||||
|
+ {
|
||||||
|
+ /* We found data, convert it. RES->AT from the conversion will
|
||||||
|
+ either be an allocated block or NULL, both of which are safe to
|
||||||
|
+ pass to free (). */
|
||||||
|
+ if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, &res->at))
|
||||||
|
+ return -EAI_MEMORY;
|
||||||
|
+
|
||||||
|
+ res->free_at = true;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ if (h_errno == NO_DATA)
|
||||||
|
+ return -EAI_NODATA;
|
||||||
|
+
|
||||||
|
+ return -EAI_NONAME;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (h_errno == NETDB_INTERNAL)
|
||||||
|
+ return -EAI_SYSTEM;
|
||||||
|
+ if (h_errno == TRY_AGAIN)
|
||||||
|
+ return -EAI_AGAIN;
|
||||||
|
+
|
||||||
|
+ /* We made requests but they turned out no data.
|
||||||
|
+ The name is known, though. */
|
||||||
|
+ return -EAI_NODATA;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
const struct addrinfo *req, struct addrinfo **pai,
|
||||||
|
@@ -610,6 +667,11 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
else if (res.at != NULL)
|
||||||
|
goto process_list;
|
||||||
|
|
||||||
|
+ if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0)
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ else if (res.at != NULL)
|
||||||
|
+ goto process_list;
|
||||||
|
+
|
||||||
|
int no_data = 0;
|
||||||
|
int no_inet6_data = 0;
|
||||||
|
nss_action_list nip;
|
||||||
|
@@ -619,69 +681,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
struct resolv_context *res_ctx = NULL;
|
||||||
|
bool do_merge = false;
|
||||||
|
|
||||||
|
- /* If we do not have to look for IPv6 addresses or the canonical
|
||||||
|
- name, use the simple, old functions, which do not support
|
||||||
|
- IPv6 scope ids, nor retrieving the canonical name. */
|
||||||
|
- if (req->ai_family == AF_INET
|
||||||
|
- && (req->ai_flags & AI_CANONNAME) == 0)
|
||||||
|
- {
|
||||||
|
- int rc;
|
||||||
|
- struct hostent th;
|
||||||
|
- struct hostent *h;
|
||||||
|
-
|
||||||
|
- while (1)
|
||||||
|
- {
|
||||||
|
- rc = __gethostbyname2_r (name, AF_INET, &th,
|
||||||
|
- tmpbuf->data, tmpbuf->length,
|
||||||
|
- &h, &h_errno);
|
||||||
|
- if (rc != ERANGE || h_errno != NETDB_INTERNAL)
|
||||||
|
- break;
|
||||||
|
- if (!scratch_buffer_grow (tmpbuf))
|
||||||
|
- {
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (rc == 0)
|
||||||
|
- {
|
||||||
|
- if (h != NULL)
|
||||||
|
- {
|
||||||
|
- /* We found data, convert it. */
|
||||||
|
- if (!convert_hostent_to_gaih_addrtuple
|
||||||
|
- (req, AF_INET, h, &addrmem))
|
||||||
|
- {
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- res.at = addrmem;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- if (h_errno == NO_DATA)
|
||||||
|
- result = -EAI_NODATA;
|
||||||
|
- else
|
||||||
|
- result = -EAI_NONAME;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- if (h_errno == NETDB_INTERNAL)
|
||||||
|
- result = -EAI_SYSTEM;
|
||||||
|
- else if (h_errno == TRY_AGAIN)
|
||||||
|
- result = -EAI_AGAIN;
|
||||||
|
- else
|
||||||
|
- /* We made requests but they turned out no data.
|
||||||
|
- The name is known, though. */
|
||||||
|
- result = -EAI_NODATA;
|
||||||
|
-
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- goto process_list;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
#ifdef USE_NSCD
|
||||||
|
if (__nss_not_use_nscd_hosts > 0
|
||||||
|
&& ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
|
||||||
|
@@ -1165,6 +1164,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
if (malloc_name)
|
||||||
|
free ((char *) name);
|
||||||
|
free (addrmem);
|
||||||
|
+ if (res.free_at)
|
||||||
|
+ free (res.at);
|
||||||
|
free (res.canon);
|
||||||
|
|
||||||
|
return result;
|
@ -0,0 +1,328 @@
|
|||||||
|
commit 5914a1d55b468ccf0fb6d997a7a4e378339df735
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Mon Mar 7 15:53:45 2022 +0530
|
||||||
|
|
||||||
|
gaih_inet: Split nscd lookup code into its own function.
|
||||||
|
|
||||||
|
Add a new member got_ipv6 to indicate if the results have an IPv6
|
||||||
|
result and use it instead of the local got_ipv6.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit e7e5315b7fa065a9c8bf525ca9a32f46fa4837e5)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 3870b2dc2edc89cd..7c497a88f8b5b9f8 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -121,6 +121,7 @@ struct gaih_result
|
||||||
|
struct gaih_addrtuple *at;
|
||||||
|
char *canon;
|
||||||
|
bool free_at;
|
||||||
|
+ bool got_ipv6;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Values for `protoflag'. */
|
||||||
|
@@ -316,7 +317,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
res.canon = canonbuf; \
|
||||||
|
} \
|
||||||
|
if (_family == AF_INET6 && *pat != NULL) \
|
||||||
|
- got_ipv6 = true; \
|
||||||
|
+ res.got_ipv6 = true; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -467,6 +468,128 @@ get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef USE_NSCD
|
||||||
|
+/* Query addresses from nscd cache, returning a non-zero value on error.
|
||||||
|
+ RES members have the lookup result; RES->AT is NULL if there were no errors
|
||||||
|
+ but also no results. */
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+get_nscd_addresses (const char *name, const struct addrinfo *req,
|
||||||
|
+ struct gaih_result *res)
|
||||||
|
+{
|
||||||
|
+ if (__nss_not_use_nscd_hosts > 0
|
||||||
|
+ && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
|
||||||
|
+ __nss_not_use_nscd_hosts = 0;
|
||||||
|
+
|
||||||
|
+ res->at = NULL;
|
||||||
|
+
|
||||||
|
+ if (__nss_not_use_nscd_hosts || __nss_database_custom[NSS_DBSIDX_hosts])
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* Try to use nscd. */
|
||||||
|
+ struct nscd_ai_result *air = NULL;
|
||||||
|
+ int err = __nscd_getai (name, &air, &h_errno);
|
||||||
|
+
|
||||||
|
+ if (__glibc_unlikely (air == NULL))
|
||||||
|
+ {
|
||||||
|
+ /* The database contains a negative entry. */
|
||||||
|
+ if (err == 0)
|
||||||
|
+ return -EAI_NONAME;
|
||||||
|
+ if (__nss_not_use_nscd_hosts == 0)
|
||||||
|
+ {
|
||||||
|
+ if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
|
||||||
|
+ return -EAI_MEMORY;
|
||||||
|
+ if (h_errno == TRY_AGAIN)
|
||||||
|
+ return -EAI_AGAIN;
|
||||||
|
+ return -EAI_SYSTEM;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Transform into gaih_addrtuple list. */
|
||||||
|
+ int result = 0;
|
||||||
|
+ char *addrs = air->addrs;
|
||||||
|
+
|
||||||
|
+ struct gaih_addrtuple *addrfree = calloc (air->naddrs, sizeof (*addrfree));
|
||||||
|
+ struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at));
|
||||||
|
+ if (at == NULL)
|
||||||
|
+ {
|
||||||
|
+ result = -EAI_MEMORY;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ res->free_at = true;
|
||||||
|
+
|
||||||
|
+ int count = 0;
|
||||||
|
+ for (int i = 0; i < air->naddrs; ++i)
|
||||||
|
+ {
|
||||||
|
+ socklen_t size = (air->family[i] == AF_INET
|
||||||
|
+ ? INADDRSZ : IN6ADDRSZ);
|
||||||
|
+
|
||||||
|
+ if (!((air->family[i] == AF_INET
|
||||||
|
+ && req->ai_family == AF_INET6
|
||||||
|
+ && (req->ai_flags & AI_V4MAPPED) != 0)
|
||||||
|
+ || req->ai_family == AF_UNSPEC
|
||||||
|
+ || air->family[i] == req->ai_family))
|
||||||
|
+ {
|
||||||
|
+ /* Skip over non-matching result. */
|
||||||
|
+ addrs += size;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (air->family[i] == AF_INET && req->ai_family == AF_INET6
|
||||||
|
+ && (req->ai_flags & AI_V4MAPPED))
|
||||||
|
+ {
|
||||||
|
+ at[count].family = AF_INET6;
|
||||||
|
+ at[count].addr[3] = *(uint32_t *) addrs;
|
||||||
|
+ at[count].addr[2] = htonl (0xffff);
|
||||||
|
+ }
|
||||||
|
+ else if (req->ai_family == AF_UNSPEC
|
||||||
|
+ || air->family[count] == req->ai_family)
|
||||||
|
+ {
|
||||||
|
+ at[count].family = air->family[count];
|
||||||
|
+ memcpy (at[count].addr, addrs, size);
|
||||||
|
+ if (air->family[count] == AF_INET6)
|
||||||
|
+ res->got_ipv6 = true;
|
||||||
|
+ }
|
||||||
|
+ at[count].next = at + count + 1;
|
||||||
|
+ count++;
|
||||||
|
+ addrs += size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((req->ai_flags & AI_CANONNAME) && air->canon != NULL)
|
||||||
|
+ {
|
||||||
|
+ char *canonbuf = __strdup (air->canon);
|
||||||
|
+ if (canonbuf == NULL)
|
||||||
|
+ {
|
||||||
|
+ result = -EAI_MEMORY;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ res->canon = canonbuf;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (count == 0)
|
||||||
|
+ {
|
||||||
|
+ result = -EAI_NONAME;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ at[count - 1].next = NULL;
|
||||||
|
+
|
||||||
|
+ res->at = at;
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ free (air);
|
||||||
|
+ if (result != 0)
|
||||||
|
+ {
|
||||||
|
+ free (at);
|
||||||
|
+ res->free_at = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Convert numeric addresses to binary into RES. On failure, RES->AT is set to
|
||||||
|
NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and
|
||||||
|
the function cannot determine a result, RES->AT is set to NULL and 0
|
||||||
|
@@ -630,7 +753,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
struct gaih_servtuple st[sizeof (gaih_inet_typeproto)
|
||||||
|
/ sizeof (struct gaih_typeproto)] = {0};
|
||||||
|
|
||||||
|
- bool got_ipv6 = false;
|
||||||
|
const char *orig_name = name;
|
||||||
|
|
||||||
|
/* Reserve stack memory for the scratch buffer in the getaddrinfo
|
||||||
|
@@ -672,6 +794,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
else if (res.at != NULL)
|
||||||
|
goto process_list;
|
||||||
|
|
||||||
|
+#ifdef USE_NSCD
|
||||||
|
+ if ((result = get_nscd_addresses (name, req, &res)) != 0)
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ else if (res.at != NULL)
|
||||||
|
+ goto process_list;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
int no_data = 0;
|
||||||
|
int no_inet6_data = 0;
|
||||||
|
nss_action_list nip;
|
||||||
|
@@ -681,115 +810,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
struct resolv_context *res_ctx = NULL;
|
||||||
|
bool do_merge = false;
|
||||||
|
|
||||||
|
-#ifdef USE_NSCD
|
||||||
|
- if (__nss_not_use_nscd_hosts > 0
|
||||||
|
- && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
|
||||||
|
- __nss_not_use_nscd_hosts = 0;
|
||||||
|
-
|
||||||
|
- if (!__nss_not_use_nscd_hosts
|
||||||
|
- && !__nss_database_custom[NSS_DBSIDX_hosts])
|
||||||
|
- {
|
||||||
|
- /* Try to use nscd. */
|
||||||
|
- struct nscd_ai_result *air = NULL;
|
||||||
|
- int err = __nscd_getai (name, &air, &h_errno);
|
||||||
|
- if (air != NULL)
|
||||||
|
- {
|
||||||
|
- /* Transform into gaih_addrtuple list. */
|
||||||
|
- bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
|
||||||
|
- char *addrs = air->addrs;
|
||||||
|
-
|
||||||
|
- addrmem = calloc (air->naddrs, sizeof (*addrmem));
|
||||||
|
- if (addrmem == NULL)
|
||||||
|
- {
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- struct gaih_addrtuple *addrfree = addrmem;
|
||||||
|
- struct gaih_addrtuple **pat = &res.at;
|
||||||
|
-
|
||||||
|
- for (int i = 0; i < air->naddrs; ++i)
|
||||||
|
- {
|
||||||
|
- socklen_t size = (air->family[i] == AF_INET
|
||||||
|
- ? INADDRSZ : IN6ADDRSZ);
|
||||||
|
-
|
||||||
|
- if (!((air->family[i] == AF_INET
|
||||||
|
- && req->ai_family == AF_INET6
|
||||||
|
- && (req->ai_flags & AI_V4MAPPED) != 0)
|
||||||
|
- || req->ai_family == AF_UNSPEC
|
||||||
|
- || air->family[i] == req->ai_family))
|
||||||
|
- {
|
||||||
|
- /* Skip over non-matching result. */
|
||||||
|
- addrs += size;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (*pat == NULL)
|
||||||
|
- {
|
||||||
|
- *pat = addrfree++;
|
||||||
|
- (*pat)->scopeid = 0;
|
||||||
|
- }
|
||||||
|
- uint32_t *pataddr = (*pat)->addr;
|
||||||
|
- (*pat)->next = NULL;
|
||||||
|
- if (added_canon || air->canon == NULL)
|
||||||
|
- (*pat)->name = NULL;
|
||||||
|
- else if (res.canon == NULL)
|
||||||
|
- {
|
||||||
|
- char *canonbuf = __strdup (air->canon);
|
||||||
|
- if (canonbuf == NULL)
|
||||||
|
- {
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- res.canon = (*pat)->name = canonbuf;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (air->family[i] == AF_INET
|
||||||
|
- && req->ai_family == AF_INET6
|
||||||
|
- && (req->ai_flags & AI_V4MAPPED))
|
||||||
|
- {
|
||||||
|
- (*pat)->family = AF_INET6;
|
||||||
|
- pataddr[3] = *(uint32_t *) addrs;
|
||||||
|
- pataddr[2] = htonl (0xffff);
|
||||||
|
- pataddr[1] = 0;
|
||||||
|
- pataddr[0] = 0;
|
||||||
|
- pat = &((*pat)->next);
|
||||||
|
- added_canon = true;
|
||||||
|
- }
|
||||||
|
- else if (req->ai_family == AF_UNSPEC
|
||||||
|
- || air->family[i] == req->ai_family)
|
||||||
|
- {
|
||||||
|
- (*pat)->family = air->family[i];
|
||||||
|
- memcpy (pataddr, addrs, size);
|
||||||
|
- pat = &((*pat)->next);
|
||||||
|
- added_canon = true;
|
||||||
|
- if (air->family[i] == AF_INET6)
|
||||||
|
- got_ipv6 = true;
|
||||||
|
- }
|
||||||
|
- addrs += size;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- free (air);
|
||||||
|
-
|
||||||
|
- goto process_list;
|
||||||
|
- }
|
||||||
|
- else if (err == 0)
|
||||||
|
- /* The database contains a negative entry. */
|
||||||
|
- goto free_and_return;
|
||||||
|
- else if (__nss_not_use_nscd_hosts == 0)
|
||||||
|
- {
|
||||||
|
- if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- else if (h_errno == TRY_AGAIN)
|
||||||
|
- result = -EAI_AGAIN;
|
||||||
|
- else
|
||||||
|
- result = -EAI_SYSTEM;
|
||||||
|
-
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
no_more = !__nss_database_get (nss_database_hosts, &nip);
|
||||||
|
|
||||||
|
/* If we are looking for both IPv4 and IPv6 address we don't
|
||||||
|
@@ -897,7 +917,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
|
no_data = 0;
|
||||||
|
if (req->ai_family == AF_INET6)
|
||||||
|
- got_ipv6 = true;
|
||||||
|
+ res.got_ipv6 = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*pat = ((*pat)->next);
|
||||||
|
@@ -940,7 +960,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
&& (req->ai_flags & AI_V4MAPPED)
|
||||||
|
/* Avoid generating the mapped addresses if we
|
||||||
|
know we are not going to need them. */
|
||||||
|
- && ((req->ai_flags & AI_ALL) || !got_ipv6)))
|
||||||
|
+ && ((req->ai_flags & AI_ALL) || !res.got_ipv6)))
|
||||||
|
{
|
||||||
|
gethosts (AF_INET);
|
||||||
|
|
||||||
|
@@ -1091,7 +1111,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
/* If we looked up IPv4 mapped address discard them here if
|
||||||
|
the caller isn't interested in all address and we have
|
||||||
|
found at least one IPv6 address. */
|
||||||
|
- if (got_ipv6
|
||||||
|
+ if (res.got_ipv6
|
||||||
|
&& (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
|
||||||
|
&& IN6_IS_ADDR_V4MAPPED (at2->addr))
|
||||||
|
goto ignore;
|
@ -0,0 +1,673 @@
|
|||||||
|
commit ec71cb961121760f81e55af5489e658dc89e96e6
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Mon Mar 7 15:56:22 2022 +0530
|
||||||
|
|
||||||
|
gaih_inet: separate nss lookup loop into its own function
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit 906cecbe0889e601c91d9aba738049c73ebe4dd2)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 7c497a88f8b5b9f8..145ea6fa381ad14b 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -159,6 +159,14 @@ static const struct addrinfo default_hints =
|
||||||
|
.ai_next = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+gaih_result_reset (struct gaih_result *res)
|
||||||
|
+{
|
||||||
|
+ if (res->free_at)
|
||||||
|
+ free (res->at);
|
||||||
|
+ free (res->canon);
|
||||||
|
+ memset (res, 0, sizeof (*res));
|
||||||
|
+}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||||
|
@@ -197,13 +205,10 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||||
|
|
||||||
|
/* Convert struct hostent to a list of struct gaih_addrtuple objects. h_name
|
||||||
|
is not copied, and the struct hostent object must not be deallocated
|
||||||
|
- prematurely. The new addresses are appended to the tuple array in
|
||||||
|
- RESULT. */
|
||||||
|
+ prematurely. The new addresses are appended to the tuple array in RES. */
|
||||||
|
static bool
|
||||||
|
-convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
- int family,
|
||||||
|
- struct hostent *h,
|
||||||
|
- struct gaih_addrtuple **result)
|
||||||
|
+convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
|
||||||
|
+ struct hostent *h, struct gaih_result *res)
|
||||||
|
{
|
||||||
|
/* Count the number of addresses in h->h_addr_list. */
|
||||||
|
size_t count = 0;
|
||||||
|
@@ -215,7 +220,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
- struct gaih_addrtuple *array = *result;
|
||||||
|
+ struct gaih_addrtuple *array = res->at;
|
||||||
|
size_t old = 0;
|
||||||
|
|
||||||
|
while (array != NULL)
|
||||||
|
@@ -224,12 +229,14 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
array = array->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
- array = realloc (*result, (old + count) * sizeof (*array));
|
||||||
|
+ array = realloc (res->at, (old + count) * sizeof (*array));
|
||||||
|
|
||||||
|
if (array == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
- *result = array;
|
||||||
|
+ res->got_ipv6 = family == AF_INET6;
|
||||||
|
+ res->at = array;
|
||||||
|
+ res->free_at = true;
|
||||||
|
|
||||||
|
/* Update the next pointers on reallocation. */
|
||||||
|
for (size_t i = 0; i < old; i++)
|
||||||
|
@@ -278,7 +285,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
{ \
|
||||||
|
__resolv_context_put (res_ctx); \
|
||||||
|
result = -EAI_MEMORY; \
|
||||||
|
- goto free_and_return; \
|
||||||
|
+ goto out; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
if (status == NSS_STATUS_NOTFOUND \
|
||||||
|
@@ -288,7 +295,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
{ \
|
||||||
|
__resolv_context_put (res_ctx); \
|
||||||
|
result = -EAI_SYSTEM; \
|
||||||
|
- goto free_and_return; \
|
||||||
|
+ goto out; \
|
||||||
|
} \
|
||||||
|
if (h_errno == TRY_AGAIN) \
|
||||||
|
no_data = EAI_AGAIN; \
|
||||||
|
@@ -297,27 +304,24 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
} \
|
||||||
|
else if (status == NSS_STATUS_SUCCESS) \
|
||||||
|
{ \
|
||||||
|
- if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
|
||||||
|
+ if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, res)) \
|
||||||
|
{ \
|
||||||
|
__resolv_context_put (res_ctx); \
|
||||||
|
result = -EAI_SYSTEM; \
|
||||||
|
- goto free_and_return; \
|
||||||
|
+ goto out; \
|
||||||
|
} \
|
||||||
|
- *pat = addrmem; \
|
||||||
|
\
|
||||||
|
- if (localcanon != NULL && res.canon == NULL) \
|
||||||
|
+ if (localcanon != NULL && res->canon == NULL) \
|
||||||
|
{ \
|
||||||
|
char *canonbuf = __strdup (localcanon); \
|
||||||
|
if (canonbuf == NULL) \
|
||||||
|
{ \
|
||||||
|
__resolv_context_put (res_ctx); \
|
||||||
|
result = -EAI_SYSTEM; \
|
||||||
|
- goto free_and_return; \
|
||||||
|
+ goto out; \
|
||||||
|
} \
|
||||||
|
- res.canon = canonbuf; \
|
||||||
|
+ res->canon = canonbuf; \
|
||||||
|
} \
|
||||||
|
- if (_family == AF_INET6 && *pat != NULL) \
|
||||||
|
- res.got_ipv6 = true; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -590,6 +594,260 @@ out:
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+get_nss_addresses (const char *name, const struct addrinfo *req,
|
||||||
|
+ struct scratch_buffer *tmpbuf, struct gaih_result *res)
|
||||||
|
+{
|
||||||
|
+ int no_data = 0;
|
||||||
|
+ int no_inet6_data = 0;
|
||||||
|
+ nss_action_list nip;
|
||||||
|
+ enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
|
||||||
|
+ enum nss_status status = NSS_STATUS_UNAVAIL;
|
||||||
|
+ int no_more;
|
||||||
|
+ struct resolv_context *res_ctx = NULL;
|
||||||
|
+ bool do_merge = false;
|
||||||
|
+ int result = 0;
|
||||||
|
+
|
||||||
|
+ no_more = !__nss_database_get (nss_database_hosts, &nip);
|
||||||
|
+
|
||||||
|
+ /* If we are looking for both IPv4 and IPv6 address we don't
|
||||||
|
+ want the lookup functions to automatically promote IPv4
|
||||||
|
+ addresses to IPv6 addresses, so we use the no_inet6
|
||||||
|
+ function variant. */
|
||||||
|
+ res_ctx = __resolv_context_get ();
|
||||||
|
+ if (res_ctx == NULL)
|
||||||
|
+ no_more = 1;
|
||||||
|
+
|
||||||
|
+ while (!no_more)
|
||||||
|
+ {
|
||||||
|
+ /* Always start afresh; continue should discard previous results
|
||||||
|
+ and the hosts database does not support merge. */
|
||||||
|
+ gaih_result_reset (res);
|
||||||
|
+
|
||||||
|
+ if (do_merge)
|
||||||
|
+ {
|
||||||
|
+ __set_h_errno (NETDB_INTERNAL);
|
||||||
|
+ __set_errno (EBUSY);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ no_data = 0;
|
||||||
|
+ nss_gethostbyname4_r *fct4 = NULL;
|
||||||
|
+
|
||||||
|
+ /* gethostbyname4_r sends out parallel A and AAAA queries and
|
||||||
|
+ is thus only suitable for PF_UNSPEC. */
|
||||||
|
+ if (req->ai_family == PF_UNSPEC)
|
||||||
|
+ fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
|
||||||
|
+
|
||||||
|
+ if (fct4 != NULL)
|
||||||
|
+ {
|
||||||
|
+ while (1)
|
||||||
|
+ {
|
||||||
|
+ status = DL_CALL_FCT (fct4, (name, &res->at,
|
||||||
|
+ tmpbuf->data, tmpbuf->length,
|
||||||
|
+ &errno, &h_errno,
|
||||||
|
+ NULL));
|
||||||
|
+ if (status == NSS_STATUS_SUCCESS)
|
||||||
|
+ break;
|
||||||
|
+ /* gethostbyname4_r may write into AT, so reset it. */
|
||||||
|
+ res->at = NULL;
|
||||||
|
+ if (status != NSS_STATUS_TRYAGAIN
|
||||||
|
+ || errno != ERANGE || h_errno != NETDB_INTERNAL)
|
||||||
|
+ {
|
||||||
|
+ if (h_errno == TRY_AGAIN)
|
||||||
|
+ no_data = EAI_AGAIN;
|
||||||
|
+ else
|
||||||
|
+ no_data = h_errno == NO_DATA;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!scratch_buffer_grow (tmpbuf))
|
||||||
|
+ {
|
||||||
|
+ __resolv_context_put (res_ctx);
|
||||||
|
+ result = -EAI_MEMORY;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (status == NSS_STATUS_SUCCESS)
|
||||||
|
+ {
|
||||||
|
+ assert (!no_data);
|
||||||
|
+ no_data = 1;
|
||||||
|
+
|
||||||
|
+ if ((req->ai_flags & AI_CANONNAME) != 0 && res->canon == NULL)
|
||||||
|
+ {
|
||||||
|
+ char *canonbuf = __strdup (res->at->name);
|
||||||
|
+ if (canonbuf == NULL)
|
||||||
|
+ {
|
||||||
|
+ __resolv_context_put (res_ctx);
|
||||||
|
+ result = -EAI_MEMORY;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ res->canon = canonbuf;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ struct gaih_addrtuple **pat = &res->at;
|
||||||
|
+
|
||||||
|
+ while (*pat != NULL)
|
||||||
|
+ {
|
||||||
|
+ if ((*pat)->family == AF_INET
|
||||||
|
+ && req->ai_family == AF_INET6
|
||||||
|
+ && (req->ai_flags & AI_V4MAPPED) != 0)
|
||||||
|
+ {
|
||||||
|
+ uint32_t *pataddr = (*pat)->addr;
|
||||||
|
+ (*pat)->family = AF_INET6;
|
||||||
|
+ pataddr[3] = pataddr[0];
|
||||||
|
+ pataddr[2] = htonl (0xffff);
|
||||||
|
+ pataddr[1] = 0;
|
||||||
|
+ pataddr[0] = 0;
|
||||||
|
+ pat = &((*pat)->next);
|
||||||
|
+ no_data = 0;
|
||||||
|
+ }
|
||||||
|
+ else if (req->ai_family == AF_UNSPEC
|
||||||
|
+ || (*pat)->family == req->ai_family)
|
||||||
|
+ {
|
||||||
|
+ pat = &((*pat)->next);
|
||||||
|
+
|
||||||
|
+ no_data = 0;
|
||||||
|
+ if (req->ai_family == AF_INET6)
|
||||||
|
+ res->got_ipv6 = true;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ *pat = ((*pat)->next);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ no_inet6_data = no_data;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ nss_gethostbyname3_r *fct = NULL;
|
||||||
|
+ if (req->ai_flags & AI_CANONNAME)
|
||||||
|
+ /* No need to use this function if we do not look for
|
||||||
|
+ the canonical name. The function does not exist in
|
||||||
|
+ all NSS modules and therefore the lookup would
|
||||||
|
+ often fail. */
|
||||||
|
+ fct = __nss_lookup_function (nip, "gethostbyname3_r");
|
||||||
|
+ if (fct == NULL)
|
||||||
|
+ /* We are cheating here. The gethostbyname2_r
|
||||||
|
+ function does not have the same interface as
|
||||||
|
+ gethostbyname3_r but the extra arguments the
|
||||||
|
+ latter takes are added at the end. So the
|
||||||
|
+ gethostbyname2_r code will just ignore them. */
|
||||||
|
+ fct = __nss_lookup_function (nip, "gethostbyname2_r");
|
||||||
|
+
|
||||||
|
+ if (fct != NULL)
|
||||||
|
+ {
|
||||||
|
+ if (req->ai_family == AF_INET6
|
||||||
|
+ || req->ai_family == AF_UNSPEC)
|
||||||
|
+ {
|
||||||
|
+ gethosts (AF_INET6);
|
||||||
|
+ no_inet6_data = no_data;
|
||||||
|
+ inet6_status = status;
|
||||||
|
+ }
|
||||||
|
+ if (req->ai_family == AF_INET
|
||||||
|
+ || req->ai_family == AF_UNSPEC
|
||||||
|
+ || (req->ai_family == AF_INET6
|
||||||
|
+ && (req->ai_flags & AI_V4MAPPED)
|
||||||
|
+ /* Avoid generating the mapped addresses if we
|
||||||
|
+ know we are not going to need them. */
|
||||||
|
+ && ((req->ai_flags & AI_ALL) || !res->got_ipv6)))
|
||||||
|
+ {
|
||||||
|
+ gethosts (AF_INET);
|
||||||
|
+
|
||||||
|
+ if (req->ai_family == AF_INET)
|
||||||
|
+ {
|
||||||
|
+ no_inet6_data = no_data;
|
||||||
|
+ inet6_status = status;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* If we found one address for AF_INET or AF_INET6,
|
||||||
|
+ don't continue the search. */
|
||||||
|
+ if (inet6_status == NSS_STATUS_SUCCESS
|
||||||
|
+ || status == NSS_STATUS_SUCCESS)
|
||||||
|
+ {
|
||||||
|
+ if ((req->ai_flags & AI_CANONNAME) != 0
|
||||||
|
+ && res->canon == NULL)
|
||||||
|
+ {
|
||||||
|
+ char *canonbuf = getcanonname (nip, res->at, name);
|
||||||
|
+ if (canonbuf == NULL)
|
||||||
|
+ {
|
||||||
|
+ __resolv_context_put (res_ctx);
|
||||||
|
+ result = -EAI_MEMORY;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ res->canon = canonbuf;
|
||||||
|
+ }
|
||||||
|
+ status = NSS_STATUS_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* We can have different states for AF_INET and
|
||||||
|
+ AF_INET6. Try to find a useful one for both. */
|
||||||
|
+ if (inet6_status == NSS_STATUS_TRYAGAIN)
|
||||||
|
+ status = NSS_STATUS_TRYAGAIN;
|
||||||
|
+ else if (status == NSS_STATUS_UNAVAIL
|
||||||
|
+ && inet6_status != NSS_STATUS_UNAVAIL)
|
||||||
|
+ status = inet6_status;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* Could not locate any of the lookup functions.
|
||||||
|
+ The NSS lookup code does not consistently set
|
||||||
|
+ errno, so we need to supply our own error
|
||||||
|
+ code here. The root cause could either be a
|
||||||
|
+ resource allocation failure, or a missing
|
||||||
|
+ service function in the DSO (so it should not
|
||||||
|
+ be listed in /etc/nsswitch.conf). Assume the
|
||||||
|
+ former, and return EBUSY. */
|
||||||
|
+ status = NSS_STATUS_UNAVAIL;
|
||||||
|
+ __set_h_errno (NETDB_INTERNAL);
|
||||||
|
+ __set_errno (EBUSY);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ /* The hosts database does not support MERGE. */
|
||||||
|
+ if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
|
||||||
|
+ do_merge = true;
|
||||||
|
+
|
||||||
|
+ nip++;
|
||||||
|
+ if (nip->module == NULL)
|
||||||
|
+ no_more = -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ __resolv_context_put (res_ctx);
|
||||||
|
+
|
||||||
|
+ /* If we have a failure which sets errno, report it using
|
||||||
|
+ EAI_SYSTEM. */
|
||||||
|
+ if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
|
||||||
|
+ && h_errno == NETDB_INTERNAL)
|
||||||
|
+ {
|
||||||
|
+ result = -EAI_SYSTEM;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (no_data != 0 && no_inet6_data != 0)
|
||||||
|
+ {
|
||||||
|
+ /* If both requests timed out report this. */
|
||||||
|
+ if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
|
||||||
|
+ result = -EAI_AGAIN;
|
||||||
|
+ else
|
||||||
|
+ /* We made requests but they turned out no data. The name
|
||||||
|
+ is known, though. */
|
||||||
|
+ result = -EAI_NODATA;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ if (result != 0)
|
||||||
|
+ gaih_result_reset (res);
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Convert numeric addresses to binary into RES. On failure, RES->AT is set to
|
||||||
|
NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and
|
||||||
|
the function cannot determine a result, RES->AT is set to NULL and 0
|
||||||
|
@@ -723,7 +981,7 @@ try_simple_gethostbyname (const char *name, const struct addrinfo *req,
|
||||||
|
/* We found data, convert it. RES->AT from the conversion will
|
||||||
|
either be an allocated block or NULL, both of which are safe to
|
||||||
|
pass to free (). */
|
||||||
|
- if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, &res->at))
|
||||||
|
+ if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, res))
|
||||||
|
return -EAI_MEMORY;
|
||||||
|
|
||||||
|
res->free_at = true;
|
||||||
|
@@ -801,264 +1059,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
goto process_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- int no_data = 0;
|
||||||
|
- int no_inet6_data = 0;
|
||||||
|
- nss_action_list nip;
|
||||||
|
- enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
|
||||||
|
- enum nss_status status = NSS_STATUS_UNAVAIL;
|
||||||
|
- int no_more;
|
||||||
|
- struct resolv_context *res_ctx = NULL;
|
||||||
|
- bool do_merge = false;
|
||||||
|
-
|
||||||
|
- no_more = !__nss_database_get (nss_database_hosts, &nip);
|
||||||
|
-
|
||||||
|
- /* If we are looking for both IPv4 and IPv6 address we don't
|
||||||
|
- want the lookup functions to automatically promote IPv4
|
||||||
|
- addresses to IPv6 addresses, so we use the no_inet6
|
||||||
|
- function variant. */
|
||||||
|
- res_ctx = __resolv_context_get ();
|
||||||
|
- if (res_ctx == NULL)
|
||||||
|
- no_more = 1;
|
||||||
|
-
|
||||||
|
- while (!no_more)
|
||||||
|
- {
|
||||||
|
- /* Always start afresh; continue should discard previous results
|
||||||
|
- and the hosts database does not support merge. */
|
||||||
|
- res.at = NULL;
|
||||||
|
- free (res.canon);
|
||||||
|
- free (addrmem);
|
||||||
|
- res.canon = NULL;
|
||||||
|
- addrmem = NULL;
|
||||||
|
- got_ipv6 = false;
|
||||||
|
-
|
||||||
|
- if (do_merge)
|
||||||
|
- {
|
||||||
|
- __set_h_errno (NETDB_INTERNAL);
|
||||||
|
- __set_errno (EBUSY);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- no_data = 0;
|
||||||
|
- nss_gethostbyname4_r *fct4 = NULL;
|
||||||
|
-
|
||||||
|
- /* gethostbyname4_r sends out parallel A and AAAA queries and
|
||||||
|
- is thus only suitable for PF_UNSPEC. */
|
||||||
|
- if (req->ai_family == PF_UNSPEC)
|
||||||
|
- fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
|
||||||
|
-
|
||||||
|
- if (fct4 != NULL)
|
||||||
|
- {
|
||||||
|
- while (1)
|
||||||
|
- {
|
||||||
|
- status = DL_CALL_FCT (fct4, (name, &res.at,
|
||||||
|
- tmpbuf->data, tmpbuf->length,
|
||||||
|
- &errno, &h_errno,
|
||||||
|
- NULL));
|
||||||
|
- if (status == NSS_STATUS_SUCCESS)
|
||||||
|
- break;
|
||||||
|
- /* gethostbyname4_r may write into AT, so reset it. */
|
||||||
|
- res.at = NULL;
|
||||||
|
- if (status != NSS_STATUS_TRYAGAIN
|
||||||
|
- || errno != ERANGE || h_errno != NETDB_INTERNAL)
|
||||||
|
- {
|
||||||
|
- if (h_errno == TRY_AGAIN)
|
||||||
|
- no_data = EAI_AGAIN;
|
||||||
|
- else
|
||||||
|
- no_data = h_errno == NO_DATA;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!scratch_buffer_grow (tmpbuf))
|
||||||
|
- {
|
||||||
|
- __resolv_context_put (res_ctx);
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (status == NSS_STATUS_SUCCESS)
|
||||||
|
- {
|
||||||
|
- assert (!no_data);
|
||||||
|
- no_data = 1;
|
||||||
|
-
|
||||||
|
- if ((req->ai_flags & AI_CANONNAME) != 0 && res.canon == NULL)
|
||||||
|
- {
|
||||||
|
- char *canonbuf = __strdup (res.at->name);
|
||||||
|
- if (canonbuf == NULL)
|
||||||
|
- {
|
||||||
|
- __resolv_context_put (res_ctx);
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- res.canon = canonbuf;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- struct gaih_addrtuple **pat = &res.at;
|
||||||
|
-
|
||||||
|
- while (*pat != NULL)
|
||||||
|
- {
|
||||||
|
- if ((*pat)->family == AF_INET
|
||||||
|
- && req->ai_family == AF_INET6
|
||||||
|
- && (req->ai_flags & AI_V4MAPPED) != 0)
|
||||||
|
- {
|
||||||
|
- uint32_t *pataddr = (*pat)->addr;
|
||||||
|
- (*pat)->family = AF_INET6;
|
||||||
|
- pataddr[3] = pataddr[0];
|
||||||
|
- pataddr[2] = htonl (0xffff);
|
||||||
|
- pataddr[1] = 0;
|
||||||
|
- pataddr[0] = 0;
|
||||||
|
- pat = &((*pat)->next);
|
||||||
|
- no_data = 0;
|
||||||
|
- }
|
||||||
|
- else if (req->ai_family == AF_UNSPEC
|
||||||
|
- || (*pat)->family == req->ai_family)
|
||||||
|
- {
|
||||||
|
- pat = &((*pat)->next);
|
||||||
|
-
|
||||||
|
- no_data = 0;
|
||||||
|
- if (req->ai_family == AF_INET6)
|
||||||
|
- res.got_ipv6 = true;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- *pat = ((*pat)->next);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- no_inet6_data = no_data;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- nss_gethostbyname3_r *fct = NULL;
|
||||||
|
- if (req->ai_flags & AI_CANONNAME)
|
||||||
|
- /* No need to use this function if we do not look for
|
||||||
|
- the canonical name. The function does not exist in
|
||||||
|
- all NSS modules and therefore the lookup would
|
||||||
|
- often fail. */
|
||||||
|
- fct = __nss_lookup_function (nip, "gethostbyname3_r");
|
||||||
|
- if (fct == NULL)
|
||||||
|
- /* We are cheating here. The gethostbyname2_r
|
||||||
|
- function does not have the same interface as
|
||||||
|
- gethostbyname3_r but the extra arguments the
|
||||||
|
- latter takes are added at the end. So the
|
||||||
|
- gethostbyname2_r code will just ignore them. */
|
||||||
|
- fct = __nss_lookup_function (nip, "gethostbyname2_r");
|
||||||
|
-
|
||||||
|
- if (fct != NULL)
|
||||||
|
- {
|
||||||
|
- struct gaih_addrtuple **pat = &res.at;
|
||||||
|
-
|
||||||
|
- if (req->ai_family == AF_INET6
|
||||||
|
- || req->ai_family == AF_UNSPEC)
|
||||||
|
- {
|
||||||
|
- gethosts (AF_INET6);
|
||||||
|
- no_inet6_data = no_data;
|
||||||
|
- inet6_status = status;
|
||||||
|
- }
|
||||||
|
- if (req->ai_family == AF_INET
|
||||||
|
- || req->ai_family == AF_UNSPEC
|
||||||
|
- || (req->ai_family == AF_INET6
|
||||||
|
- && (req->ai_flags & AI_V4MAPPED)
|
||||||
|
- /* Avoid generating the mapped addresses if we
|
||||||
|
- know we are not going to need them. */
|
||||||
|
- && ((req->ai_flags & AI_ALL) || !res.got_ipv6)))
|
||||||
|
- {
|
||||||
|
- gethosts (AF_INET);
|
||||||
|
-
|
||||||
|
- if (req->ai_family == AF_INET)
|
||||||
|
- {
|
||||||
|
- no_inet6_data = no_data;
|
||||||
|
- inet6_status = status;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* If we found one address for AF_INET or AF_INET6,
|
||||||
|
- don't continue the search. */
|
||||||
|
- if (inet6_status == NSS_STATUS_SUCCESS
|
||||||
|
- || status == NSS_STATUS_SUCCESS)
|
||||||
|
- {
|
||||||
|
- if ((req->ai_flags & AI_CANONNAME) != 0
|
||||||
|
- && res.canon == NULL)
|
||||||
|
- {
|
||||||
|
- char *canonbuf = getcanonname (nip, res.at, name);
|
||||||
|
- if (canonbuf == NULL)
|
||||||
|
- {
|
||||||
|
- __resolv_context_put (res_ctx);
|
||||||
|
- result = -EAI_MEMORY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
- res.canon = canonbuf;
|
||||||
|
- }
|
||||||
|
- status = NSS_STATUS_SUCCESS;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- /* We can have different states for AF_INET and
|
||||||
|
- AF_INET6. Try to find a useful one for both. */
|
||||||
|
- if (inet6_status == NSS_STATUS_TRYAGAIN)
|
||||||
|
- status = NSS_STATUS_TRYAGAIN;
|
||||||
|
- else if (status == NSS_STATUS_UNAVAIL
|
||||||
|
- && inet6_status != NSS_STATUS_UNAVAIL)
|
||||||
|
- status = inet6_status;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- /* Could not locate any of the lookup functions.
|
||||||
|
- The NSS lookup code does not consistently set
|
||||||
|
- errno, so we need to supply our own error
|
||||||
|
- code here. The root cause could either be a
|
||||||
|
- resource allocation failure, or a missing
|
||||||
|
- service function in the DSO (so it should not
|
||||||
|
- be listed in /etc/nsswitch.conf). Assume the
|
||||||
|
- former, and return EBUSY. */
|
||||||
|
- status = NSS_STATUS_UNAVAIL;
|
||||||
|
- __set_h_errno (NETDB_INTERNAL);
|
||||||
|
- __set_errno (EBUSY);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- /* The hosts database does not support MERGE. */
|
||||||
|
- if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
|
||||||
|
- do_merge = true;
|
||||||
|
-
|
||||||
|
- nip++;
|
||||||
|
- if (nip->module == NULL)
|
||||||
|
- no_more = -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- __resolv_context_put (res_ctx);
|
||||||
|
-
|
||||||
|
- /* If we have a failure which sets errno, report it using
|
||||||
|
- EAI_SYSTEM. */
|
||||||
|
- if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
|
||||||
|
- && h_errno == NETDB_INTERNAL)
|
||||||
|
- {
|
||||||
|
- result = -EAI_SYSTEM;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (no_data != 0 && no_inet6_data != 0)
|
||||||
|
- {
|
||||||
|
- /* If both requests timed out report this. */
|
||||||
|
- if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
|
||||||
|
- result = -EAI_AGAIN;
|
||||||
|
- else
|
||||||
|
- /* We made requests but they turned out no data. The name
|
||||||
|
- is known, though. */
|
||||||
|
- result = -EAI_NODATA;
|
||||||
|
-
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
+ if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0)
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ else if (res.at != NULL)
|
||||||
|
+ goto process_list;
|
||||||
|
|
||||||
|
- process_list:
|
||||||
|
- if (res.at == NULL)
|
||||||
|
- {
|
||||||
|
- result = -EAI_NONAME;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
+ /* None of the lookups worked, so name not found. */
|
||||||
|
+ result = -EAI_NONAME;
|
||||||
|
+ goto free_and_return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@@ -1089,6 +1097,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+process_list:
|
||||||
|
{
|
||||||
|
/* Set up the canonical name if we need it. */
|
||||||
|
if ((result = process_canonname (req, orig_name, &res)) != 0)
|
@ -0,0 +1,156 @@
|
|||||||
|
commit 4d59769087f2143f619b4b38bf93590a86f5c806
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Mon Mar 7 19:48:48 2022 +0530
|
||||||
|
|
||||||
|
gaih_inet: make gethosts into a function
|
||||||
|
|
||||||
|
The macro is quite a pain to debug, so make gethosts into a function to
|
||||||
|
make it easier to maintain.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit cfa3bd48cb19a70e4367a9978dbba09d9df27a72)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 145ea6fa381ad14b..6be109d07f7fcce0 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -268,63 +268,54 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define gethosts(_family) \
|
||||||
|
- { \
|
||||||
|
- struct hostent th; \
|
||||||
|
- char *localcanon = NULL; \
|
||||||
|
- no_data = 0; \
|
||||||
|
- while (1) \
|
||||||
|
- { \
|
||||||
|
- status = DL_CALL_FCT (fct, (name, _family, &th, \
|
||||||
|
- tmpbuf->data, tmpbuf->length, \
|
||||||
|
- &errno, &h_errno, NULL, &localcanon)); \
|
||||||
|
- if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
|
||||||
|
- || errno != ERANGE) \
|
||||||
|
- break; \
|
||||||
|
- if (!scratch_buffer_grow (tmpbuf)) \
|
||||||
|
- { \
|
||||||
|
- __resolv_context_put (res_ctx); \
|
||||||
|
- result = -EAI_MEMORY; \
|
||||||
|
- goto out; \
|
||||||
|
- } \
|
||||||
|
- } \
|
||||||
|
- if (status == NSS_STATUS_NOTFOUND \
|
||||||
|
- || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
|
||||||
|
- { \
|
||||||
|
- if (h_errno == NETDB_INTERNAL) \
|
||||||
|
- { \
|
||||||
|
- __resolv_context_put (res_ctx); \
|
||||||
|
- result = -EAI_SYSTEM; \
|
||||||
|
- goto out; \
|
||||||
|
- } \
|
||||||
|
- if (h_errno == TRY_AGAIN) \
|
||||||
|
- no_data = EAI_AGAIN; \
|
||||||
|
- else \
|
||||||
|
- no_data = h_errno == NO_DATA; \
|
||||||
|
- } \
|
||||||
|
- else if (status == NSS_STATUS_SUCCESS) \
|
||||||
|
- { \
|
||||||
|
- if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, res)) \
|
||||||
|
- { \
|
||||||
|
- __resolv_context_put (res_ctx); \
|
||||||
|
- result = -EAI_SYSTEM; \
|
||||||
|
- goto out; \
|
||||||
|
- } \
|
||||||
|
- \
|
||||||
|
- if (localcanon != NULL && res->canon == NULL) \
|
||||||
|
- { \
|
||||||
|
- char *canonbuf = __strdup (localcanon); \
|
||||||
|
- if (canonbuf == NULL) \
|
||||||
|
- { \
|
||||||
|
- __resolv_context_put (res_ctx); \
|
||||||
|
- result = -EAI_SYSTEM; \
|
||||||
|
- goto out; \
|
||||||
|
- } \
|
||||||
|
- res->canon = canonbuf; \
|
||||||
|
- } \
|
||||||
|
- } \
|
||||||
|
- }
|
||||||
|
+static int
|
||||||
|
+gethosts (nss_gethostbyname3_r fct, int family, const char *name,
|
||||||
|
+ const struct addrinfo *req, struct scratch_buffer *tmpbuf,
|
||||||
|
+ struct gaih_result *res, enum nss_status *statusp, int *no_datap)
|
||||||
|
+{
|
||||||
|
+ struct hostent th;
|
||||||
|
+ char *localcanon = NULL;
|
||||||
|
+ enum nss_status status;
|
||||||
|
+
|
||||||
|
+ *no_datap = 0;
|
||||||
|
+ while (1)
|
||||||
|
+ {
|
||||||
|
+ *statusp = status = DL_CALL_FCT (fct, (name, family, &th,
|
||||||
|
+ tmpbuf->data, tmpbuf->length,
|
||||||
|
+ &errno, &h_errno, NULL,
|
||||||
|
+ &localcanon));
|
||||||
|
+ if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL
|
||||||
|
+ || errno != ERANGE)
|
||||||
|
+ break;
|
||||||
|
+ if (!scratch_buffer_grow (tmpbuf))
|
||||||
|
+ return -EAI_MEMORY;
|
||||||
|
+ }
|
||||||
|
+ if (status == NSS_STATUS_NOTFOUND
|
||||||
|
+ || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
|
||||||
|
+ {
|
||||||
|
+ if (h_errno == NETDB_INTERNAL)
|
||||||
|
+ return -EAI_SYSTEM;
|
||||||
|
+ if (h_errno == TRY_AGAIN)
|
||||||
|
+ *no_datap = EAI_AGAIN;
|
||||||
|
+ else
|
||||||
|
+ *no_datap = h_errno == NO_DATA;
|
||||||
|
+ }
|
||||||
|
+ else if (status == NSS_STATUS_SUCCESS)
|
||||||
|
+ {
|
||||||
|
+ if (!convert_hostent_to_gaih_addrtuple (req, family, &th, res))
|
||||||
|
+ return -EAI_SYSTEM;
|
||||||
|
+
|
||||||
|
+ if (localcanon != NULL && res->canon == NULL)
|
||||||
|
+ {
|
||||||
|
+ char *canonbuf = __strdup (localcanon);
|
||||||
|
+ if (canonbuf == NULL)
|
||||||
|
+ return -EAI_SYSTEM;
|
||||||
|
+ res->canon = canonbuf;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
|
||||||
|
/* This function is called if a canonical name is requested, but if
|
||||||
|
the service function did not provide it. It tries to obtain the
|
||||||
|
@@ -741,7 +732,12 @@ get_nss_addresses (const char *name, const struct addrinfo *req,
|
||||||
|
if (req->ai_family == AF_INET6
|
||||||
|
|| req->ai_family == AF_UNSPEC)
|
||||||
|
{
|
||||||
|
- gethosts (AF_INET6);
|
||||||
|
+ if ((result = gethosts (fct, AF_INET6, name, req, tmpbuf,
|
||||||
|
+ res, &status, &no_data)) != 0)
|
||||||
|
+ {
|
||||||
|
+ __resolv_context_put (res_ctx);
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
no_inet6_data = no_data;
|
||||||
|
inet6_status = status;
|
||||||
|
}
|
||||||
|
@@ -753,7 +749,12 @@ get_nss_addresses (const char *name, const struct addrinfo *req,
|
||||||
|
know we are not going to need them. */
|
||||||
|
&& ((req->ai_flags & AI_ALL) || !res->got_ipv6)))
|
||||||
|
{
|
||||||
|
- gethosts (AF_INET);
|
||||||
|
+ if ((result = gethosts (fct, AF_INET, name, req, tmpbuf,
|
||||||
|
+ res, &status, &no_data)) != 0)
|
||||||
|
+ {
|
||||||
|
+ __resolv_context_put (res_ctx);
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (req->ai_family == AF_INET)
|
||||||
|
{
|
@ -0,0 +1,973 @@
|
|||||||
|
commit 1c37b8022e8763fedbb3f79c02e05c6acfe5a215
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Thu Mar 17 11:44:34 2022 +0530
|
||||||
|
|
||||||
|
Simplify allocations and fix merge and continue actions [BZ #28931]
|
||||||
|
|
||||||
|
Allocations for address tuples is currently a bit confusing because of
|
||||||
|
the pointer chasing through PAT, making it hard to observe the sequence
|
||||||
|
in which allocations have been made. Narrow scope of the pointer
|
||||||
|
chasing through PAT so that it is only used where necessary.
|
||||||
|
|
||||||
|
This also tightens actions behaviour with the hosts database in
|
||||||
|
getaddrinfo to comply with the manual text. The "continue" action
|
||||||
|
discards previous results and the "merge" action results in an immedate
|
||||||
|
lookup failure. Consequently, chaining of allocations across modules is
|
||||||
|
no longer necessary, thus opening up cleanup opportunities.
|
||||||
|
|
||||||
|
A test has been added that checks some combinations to ensure that they
|
||||||
|
work correctly.
|
||||||
|
|
||||||
|
Resolves: BZ #28931
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
nss/Makefile
|
||||||
|
(Tests applied in different order from upstream)
|
||||||
|
|
||||||
|
diff --git a/nss/Makefile b/nss/Makefile
|
||||||
|
index f01674a16e720b88..333edb1588ede881 100644
|
||||||
|
--- a/nss/Makefile
|
||||||
|
+++ b/nss/Makefile
|
||||||
|
@@ -77,6 +77,7 @@ tests-container := \
|
||||||
|
tst-nss-db-endpwent \
|
||||||
|
tst-nss-files-hosts-long \
|
||||||
|
tst-nss-files-hosts-v4mapped \
|
||||||
|
+ tst-nss-gai-actions \
|
||||||
|
tst-nss-test3 \
|
||||||
|
tst-reload1 \
|
||||||
|
tst-reload2 \
|
||||||
|
diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..efca6cd1837a172a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nss/tst-nss-gai-actions.c
|
||||||
|
@@ -0,0 +1,149 @@
|
||||||
|
+/* Test continue and merge NSS actions for getaddrinfo.
|
||||||
|
+ Copyright The GNU Toolchain Authors.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+#include <gnu/lib-names.h>
|
||||||
|
+#include <nss.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/format_nss.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <support/xunistd.h>
|
||||||
|
+
|
||||||
|
+enum
|
||||||
|
+{
|
||||||
|
+ ACTION_MERGE = 0,
|
||||||
|
+ ACTION_CONTINUE,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const char *
|
||||||
|
+family_str (int family)
|
||||||
|
+{
|
||||||
|
+ switch (family)
|
||||||
|
+ {
|
||||||
|
+ case AF_UNSPEC:
|
||||||
|
+ return "AF_UNSPEC";
|
||||||
|
+ case AF_INET:
|
||||||
|
+ return "AF_INET";
|
||||||
|
+ default:
|
||||||
|
+ __builtin_unreachable ();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const char *
|
||||||
|
+action_str (int action)
|
||||||
|
+{
|
||||||
|
+ switch (action)
|
||||||
|
+ {
|
||||||
|
+ case ACTION_MERGE:
|
||||||
|
+ return "merge";
|
||||||
|
+ case ACTION_CONTINUE:
|
||||||
|
+ return "continue";
|
||||||
|
+ default:
|
||||||
|
+ __builtin_unreachable ();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_one_test (int action, int family, bool canon)
|
||||||
|
+{
|
||||||
|
+ struct addrinfo hints =
|
||||||
|
+ {
|
||||||
|
+ .ai_family = family,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ struct addrinfo *ai;
|
||||||
|
+
|
||||||
|
+ if (canon)
|
||||||
|
+ hints.ai_flags = AI_CANONNAME;
|
||||||
|
+
|
||||||
|
+ printf ("***** Testing \"files [SUCCESS=%s] files\" for family %s, %s\n",
|
||||||
|
+ action_str (action), family_str (family),
|
||||||
|
+ canon ? "AI_CANONNAME" : "");
|
||||||
|
+
|
||||||
|
+ int ret = getaddrinfo ("example.org", "80", &hints, &ai);
|
||||||
|
+
|
||||||
|
+ switch (action)
|
||||||
|
+ {
|
||||||
|
+ case ACTION_MERGE:
|
||||||
|
+ if (ret == 0)
|
||||||
|
+ {
|
||||||
|
+ char *formatted = support_format_addrinfo (ai, ret);
|
||||||
|
+
|
||||||
|
+ printf ("merge unexpectedly succeeded:\n %s\n", formatted);
|
||||||
|
+ support_record_failure ();
|
||||||
|
+ free (formatted);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ return;
|
||||||
|
+ case ACTION_CONTINUE:
|
||||||
|
+ {
|
||||||
|
+ char *formatted = support_format_addrinfo (ai, ret);
|
||||||
|
+
|
||||||
|
+ /* Verify that the result appears exactly once. */
|
||||||
|
+ const char *expected = "address: STREAM/TCP 192.0.0.1 80\n"
|
||||||
|
+ "address: DGRAM/UDP 192.0.0.1 80\n"
|
||||||
|
+ "address: RAW/IP 192.0.0.1 80\n";
|
||||||
|
+
|
||||||
|
+ const char *contains = strstr (formatted, expected);
|
||||||
|
+ const char *contains2 = NULL;
|
||||||
|
+
|
||||||
|
+ if (contains != NULL)
|
||||||
|
+ contains2 = strstr (contains + strlen (expected), expected);
|
||||||
|
+
|
||||||
|
+ if (contains == NULL || contains2 != NULL)
|
||||||
|
+ {
|
||||||
|
+ printf ("continue failed:\n%s\n", formatted);
|
||||||
|
+ support_record_failure ();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free (formatted);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ default:
|
||||||
|
+ __builtin_unreachable ();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_one_test_set (int action)
|
||||||
|
+{
|
||||||
|
+ char buf[32];
|
||||||
|
+
|
||||||
|
+ snprintf (buf, sizeof (buf), "files [SUCCESS=%s] files",
|
||||||
|
+ action_str (action));
|
||||||
|
+ __nss_configure_lookup ("hosts", buf);
|
||||||
|
+
|
||||||
|
+ do_one_test (action, AF_UNSPEC, false);
|
||||||
|
+ do_one_test (action, AF_INET, false);
|
||||||
|
+ do_one_test (action, AF_INET, true);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ do_one_test_set (ACTION_CONTINUE);
|
||||||
|
+ do_one_test_set (ACTION_MERGE);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/nss/tst-nss-gai-actions.root/etc/host.conf b/nss/tst-nss-gai-actions.root/etc/host.conf
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..d1a59f73a90f2993
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nss/tst-nss-gai-actions.root/etc/host.conf
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+multi on
|
||||||
|
diff --git a/nss/tst-nss-gai-actions.root/etc/hosts b/nss/tst-nss-gai-actions.root/etc/hosts
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..50ce9774dc2c21d9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nss/tst-nss-gai-actions.root/etc/hosts
|
||||||
|
@@ -0,0 +1,508 @@
|
||||||
|
+192.0.0.1 example.org
|
||||||
|
+192.0.0.2 example.org
|
||||||
|
+192.0.0.3 example.org
|
||||||
|
+192.0.0.4 example.org
|
||||||
|
+192.0.0.5 example.org
|
||||||
|
+192.0.0.6 example.org
|
||||||
|
+192.0.0.7 example.org
|
||||||
|
+192.0.0.8 example.org
|
||||||
|
+192.0.0.9 example.org
|
||||||
|
+192.0.0.10 example.org
|
||||||
|
+192.0.0.11 example.org
|
||||||
|
+192.0.0.12 example.org
|
||||||
|
+192.0.0.13 example.org
|
||||||
|
+192.0.0.14 example.org
|
||||||
|
+192.0.0.15 example.org
|
||||||
|
+192.0.0.16 example.org
|
||||||
|
+192.0.0.17 example.org
|
||||||
|
+192.0.0.18 example.org
|
||||||
|
+192.0.0.19 example.org
|
||||||
|
+192.0.0.20 example.org
|
||||||
|
+192.0.0.21 example.org
|
||||||
|
+192.0.0.22 example.org
|
||||||
|
+192.0.0.23 example.org
|
||||||
|
+192.0.0.24 example.org
|
||||||
|
+192.0.0.25 example.org
|
||||||
|
+192.0.0.26 example.org
|
||||||
|
+192.0.0.27 example.org
|
||||||
|
+192.0.0.28 example.org
|
||||||
|
+192.0.0.29 example.org
|
||||||
|
+192.0.0.30 example.org
|
||||||
|
+192.0.0.31 example.org
|
||||||
|
+192.0.0.32 example.org
|
||||||
|
+192.0.0.33 example.org
|
||||||
|
+192.0.0.34 example.org
|
||||||
|
+192.0.0.35 example.org
|
||||||
|
+192.0.0.36 example.org
|
||||||
|
+192.0.0.37 example.org
|
||||||
|
+192.0.0.38 example.org
|
||||||
|
+192.0.0.39 example.org
|
||||||
|
+192.0.0.40 example.org
|
||||||
|
+192.0.0.41 example.org
|
||||||
|
+192.0.0.42 example.org
|
||||||
|
+192.0.0.43 example.org
|
||||||
|
+192.0.0.44 example.org
|
||||||
|
+192.0.0.45 example.org
|
||||||
|
+192.0.0.46 example.org
|
||||||
|
+192.0.0.47 example.org
|
||||||
|
+192.0.0.48 example.org
|
||||||
|
+192.0.0.49 example.org
|
||||||
|
+192.0.0.50 example.org
|
||||||
|
+192.0.0.51 example.org
|
||||||
|
+192.0.0.52 example.org
|
||||||
|
+192.0.0.53 example.org
|
||||||
|
+192.0.0.54 example.org
|
||||||
|
+192.0.0.55 example.org
|
||||||
|
+192.0.0.56 example.org
|
||||||
|
+192.0.0.57 example.org
|
||||||
|
+192.0.0.58 example.org
|
||||||
|
+192.0.0.59 example.org
|
||||||
|
+192.0.0.60 example.org
|
||||||
|
+192.0.0.61 example.org
|
||||||
|
+192.0.0.62 example.org
|
||||||
|
+192.0.0.63 example.org
|
||||||
|
+192.0.0.64 example.org
|
||||||
|
+192.0.0.65 example.org
|
||||||
|
+192.0.0.66 example.org
|
||||||
|
+192.0.0.67 example.org
|
||||||
|
+192.0.0.68 example.org
|
||||||
|
+192.0.0.69 example.org
|
||||||
|
+192.0.0.70 example.org
|
||||||
|
+192.0.0.71 example.org
|
||||||
|
+192.0.0.72 example.org
|
||||||
|
+192.0.0.73 example.org
|
||||||
|
+192.0.0.74 example.org
|
||||||
|
+192.0.0.75 example.org
|
||||||
|
+192.0.0.76 example.org
|
||||||
|
+192.0.0.77 example.org
|
||||||
|
+192.0.0.78 example.org
|
||||||
|
+192.0.0.79 example.org
|
||||||
|
+192.0.0.80 example.org
|
||||||
|
+192.0.0.81 example.org
|
||||||
|
+192.0.0.82 example.org
|
||||||
|
+192.0.0.83 example.org
|
||||||
|
+192.0.0.84 example.org
|
||||||
|
+192.0.0.85 example.org
|
||||||
|
+192.0.0.86 example.org
|
||||||
|
+192.0.0.87 example.org
|
||||||
|
+192.0.0.88 example.org
|
||||||
|
+192.0.0.89 example.org
|
||||||
|
+192.0.0.90 example.org
|
||||||
|
+192.0.0.91 example.org
|
||||||
|
+192.0.0.92 example.org
|
||||||
|
+192.0.0.93 example.org
|
||||||
|
+192.0.0.94 example.org
|
||||||
|
+192.0.0.95 example.org
|
||||||
|
+192.0.0.96 example.org
|
||||||
|
+192.0.0.97 example.org
|
||||||
|
+192.0.0.98 example.org
|
||||||
|
+192.0.0.99 example.org
|
||||||
|
+192.0.0.100 example.org
|
||||||
|
+192.0.0.101 example.org
|
||||||
|
+192.0.0.102 example.org
|
||||||
|
+192.0.0.103 example.org
|
||||||
|
+192.0.0.104 example.org
|
||||||
|
+192.0.0.105 example.org
|
||||||
|
+192.0.0.106 example.org
|
||||||
|
+192.0.0.107 example.org
|
||||||
|
+192.0.0.108 example.org
|
||||||
|
+192.0.0.109 example.org
|
||||||
|
+192.0.0.110 example.org
|
||||||
|
+192.0.0.111 example.org
|
||||||
|
+192.0.0.112 example.org
|
||||||
|
+192.0.0.113 example.org
|
||||||
|
+192.0.0.114 example.org
|
||||||
|
+192.0.0.115 example.org
|
||||||
|
+192.0.0.116 example.org
|
||||||
|
+192.0.0.117 example.org
|
||||||
|
+192.0.0.118 example.org
|
||||||
|
+192.0.0.119 example.org
|
||||||
|
+192.0.0.120 example.org
|
||||||
|
+192.0.0.121 example.org
|
||||||
|
+192.0.0.122 example.org
|
||||||
|
+192.0.0.123 example.org
|
||||||
|
+192.0.0.124 example.org
|
||||||
|
+192.0.0.125 example.org
|
||||||
|
+192.0.0.126 example.org
|
||||||
|
+192.0.0.127 example.org
|
||||||
|
+192.0.0.128 example.org
|
||||||
|
+192.0.0.129 example.org
|
||||||
|
+192.0.0.130 example.org
|
||||||
|
+192.0.0.131 example.org
|
||||||
|
+192.0.0.132 example.org
|
||||||
|
+192.0.0.133 example.org
|
||||||
|
+192.0.0.134 example.org
|
||||||
|
+192.0.0.135 example.org
|
||||||
|
+192.0.0.136 example.org
|
||||||
|
+192.0.0.137 example.org
|
||||||
|
+192.0.0.138 example.org
|
||||||
|
+192.0.0.139 example.org
|
||||||
|
+192.0.0.140 example.org
|
||||||
|
+192.0.0.141 example.org
|
||||||
|
+192.0.0.142 example.org
|
||||||
|
+192.0.0.143 example.org
|
||||||
|
+192.0.0.144 example.org
|
||||||
|
+192.0.0.145 example.org
|
||||||
|
+192.0.0.146 example.org
|
||||||
|
+192.0.0.147 example.org
|
||||||
|
+192.0.0.148 example.org
|
||||||
|
+192.0.0.149 example.org
|
||||||
|
+192.0.0.150 example.org
|
||||||
|
+192.0.0.151 example.org
|
||||||
|
+192.0.0.152 example.org
|
||||||
|
+192.0.0.153 example.org
|
||||||
|
+192.0.0.154 example.org
|
||||||
|
+192.0.0.155 example.org
|
||||||
|
+192.0.0.156 example.org
|
||||||
|
+192.0.0.157 example.org
|
||||||
|
+192.0.0.158 example.org
|
||||||
|
+192.0.0.159 example.org
|
||||||
|
+192.0.0.160 example.org
|
||||||
|
+192.0.0.161 example.org
|
||||||
|
+192.0.0.162 example.org
|
||||||
|
+192.0.0.163 example.org
|
||||||
|
+192.0.0.164 example.org
|
||||||
|
+192.0.0.165 example.org
|
||||||
|
+192.0.0.166 example.org
|
||||||
|
+192.0.0.167 example.org
|
||||||
|
+192.0.0.168 example.org
|
||||||
|
+192.0.0.169 example.org
|
||||||
|
+192.0.0.170 example.org
|
||||||
|
+192.0.0.171 example.org
|
||||||
|
+192.0.0.172 example.org
|
||||||
|
+192.0.0.173 example.org
|
||||||
|
+192.0.0.174 example.org
|
||||||
|
+192.0.0.175 example.org
|
||||||
|
+192.0.0.176 example.org
|
||||||
|
+192.0.0.177 example.org
|
||||||
|
+192.0.0.178 example.org
|
||||||
|
+192.0.0.179 example.org
|
||||||
|
+192.0.0.180 example.org
|
||||||
|
+192.0.0.181 example.org
|
||||||
|
+192.0.0.182 example.org
|
||||||
|
+192.0.0.183 example.org
|
||||||
|
+192.0.0.184 example.org
|
||||||
|
+192.0.0.185 example.org
|
||||||
|
+192.0.0.186 example.org
|
||||||
|
+192.0.0.187 example.org
|
||||||
|
+192.0.0.188 example.org
|
||||||
|
+192.0.0.189 example.org
|
||||||
|
+192.0.0.190 example.org
|
||||||
|
+192.0.0.191 example.org
|
||||||
|
+192.0.0.192 example.org
|
||||||
|
+192.0.0.193 example.org
|
||||||
|
+192.0.0.194 example.org
|
||||||
|
+192.0.0.195 example.org
|
||||||
|
+192.0.0.196 example.org
|
||||||
|
+192.0.0.197 example.org
|
||||||
|
+192.0.0.198 example.org
|
||||||
|
+192.0.0.199 example.org
|
||||||
|
+192.0.0.200 example.org
|
||||||
|
+192.0.0.201 example.org
|
||||||
|
+192.0.0.202 example.org
|
||||||
|
+192.0.0.203 example.org
|
||||||
|
+192.0.0.204 example.org
|
||||||
|
+192.0.0.205 example.org
|
||||||
|
+192.0.0.206 example.org
|
||||||
|
+192.0.0.207 example.org
|
||||||
|
+192.0.0.208 example.org
|
||||||
|
+192.0.0.209 example.org
|
||||||
|
+192.0.0.210 example.org
|
||||||
|
+192.0.0.211 example.org
|
||||||
|
+192.0.0.212 example.org
|
||||||
|
+192.0.0.213 example.org
|
||||||
|
+192.0.0.214 example.org
|
||||||
|
+192.0.0.215 example.org
|
||||||
|
+192.0.0.216 example.org
|
||||||
|
+192.0.0.217 example.org
|
||||||
|
+192.0.0.218 example.org
|
||||||
|
+192.0.0.219 example.org
|
||||||
|
+192.0.0.220 example.org
|
||||||
|
+192.0.0.221 example.org
|
||||||
|
+192.0.0.222 example.org
|
||||||
|
+192.0.0.223 example.org
|
||||||
|
+192.0.0.224 example.org
|
||||||
|
+192.0.0.225 example.org
|
||||||
|
+192.0.0.226 example.org
|
||||||
|
+192.0.0.227 example.org
|
||||||
|
+192.0.0.228 example.org
|
||||||
|
+192.0.0.229 example.org
|
||||||
|
+192.0.0.230 example.org
|
||||||
|
+192.0.0.231 example.org
|
||||||
|
+192.0.0.232 example.org
|
||||||
|
+192.0.0.233 example.org
|
||||||
|
+192.0.0.234 example.org
|
||||||
|
+192.0.0.235 example.org
|
||||||
|
+192.0.0.236 example.org
|
||||||
|
+192.0.0.237 example.org
|
||||||
|
+192.0.0.238 example.org
|
||||||
|
+192.0.0.239 example.org
|
||||||
|
+192.0.0.240 example.org
|
||||||
|
+192.0.0.241 example.org
|
||||||
|
+192.0.0.242 example.org
|
||||||
|
+192.0.0.243 example.org
|
||||||
|
+192.0.0.244 example.org
|
||||||
|
+192.0.0.245 example.org
|
||||||
|
+192.0.0.246 example.org
|
||||||
|
+192.0.0.247 example.org
|
||||||
|
+192.0.0.248 example.org
|
||||||
|
+192.0.0.249 example.org
|
||||||
|
+192.0.0.250 example.org
|
||||||
|
+192.0.0.251 example.org
|
||||||
|
+192.0.0.252 example.org
|
||||||
|
+192.0.0.253 example.org
|
||||||
|
+192.0.0.254 example.org
|
||||||
|
+192.0.1.1 example.org
|
||||||
|
+192.0.1.2 example.org
|
||||||
|
+192.0.1.3 example.org
|
||||||
|
+192.0.1.4 example.org
|
||||||
|
+192.0.1.5 example.org
|
||||||
|
+192.0.1.6 example.org
|
||||||
|
+192.0.1.7 example.org
|
||||||
|
+192.0.1.8 example.org
|
||||||
|
+192.0.1.9 example.org
|
||||||
|
+192.0.1.10 example.org
|
||||||
|
+192.0.1.11 example.org
|
||||||
|
+192.0.1.12 example.org
|
||||||
|
+192.0.1.13 example.org
|
||||||
|
+192.0.1.14 example.org
|
||||||
|
+192.0.1.15 example.org
|
||||||
|
+192.0.1.16 example.org
|
||||||
|
+192.0.1.17 example.org
|
||||||
|
+192.0.1.18 example.org
|
||||||
|
+192.0.1.19 example.org
|
||||||
|
+192.0.1.20 example.org
|
||||||
|
+192.0.1.21 example.org
|
||||||
|
+192.0.1.22 example.org
|
||||||
|
+192.0.1.23 example.org
|
||||||
|
+192.0.1.24 example.org
|
||||||
|
+192.0.1.25 example.org
|
||||||
|
+192.0.1.26 example.org
|
||||||
|
+192.0.1.27 example.org
|
||||||
|
+192.0.1.28 example.org
|
||||||
|
+192.0.1.29 example.org
|
||||||
|
+192.0.1.30 example.org
|
||||||
|
+192.0.1.31 example.org
|
||||||
|
+192.0.1.32 example.org
|
||||||
|
+192.0.1.33 example.org
|
||||||
|
+192.0.1.34 example.org
|
||||||
|
+192.0.1.35 example.org
|
||||||
|
+192.0.1.36 example.org
|
||||||
|
+192.0.1.37 example.org
|
||||||
|
+192.0.1.38 example.org
|
||||||
|
+192.0.1.39 example.org
|
||||||
|
+192.0.1.40 example.org
|
||||||
|
+192.0.1.41 example.org
|
||||||
|
+192.0.1.42 example.org
|
||||||
|
+192.0.1.43 example.org
|
||||||
|
+192.0.1.44 example.org
|
||||||
|
+192.0.1.45 example.org
|
||||||
|
+192.0.1.46 example.org
|
||||||
|
+192.0.1.47 example.org
|
||||||
|
+192.0.1.48 example.org
|
||||||
|
+192.0.1.49 example.org
|
||||||
|
+192.0.1.50 example.org
|
||||||
|
+192.0.1.51 example.org
|
||||||
|
+192.0.1.52 example.org
|
||||||
|
+192.0.1.53 example.org
|
||||||
|
+192.0.1.54 example.org
|
||||||
|
+192.0.1.55 example.org
|
||||||
|
+192.0.1.56 example.org
|
||||||
|
+192.0.1.57 example.org
|
||||||
|
+192.0.1.58 example.org
|
||||||
|
+192.0.1.59 example.org
|
||||||
|
+192.0.1.60 example.org
|
||||||
|
+192.0.1.61 example.org
|
||||||
|
+192.0.1.62 example.org
|
||||||
|
+192.0.1.63 example.org
|
||||||
|
+192.0.1.64 example.org
|
||||||
|
+192.0.1.65 example.org
|
||||||
|
+192.0.1.66 example.org
|
||||||
|
+192.0.1.67 example.org
|
||||||
|
+192.0.1.68 example.org
|
||||||
|
+192.0.1.69 example.org
|
||||||
|
+192.0.1.70 example.org
|
||||||
|
+192.0.1.71 example.org
|
||||||
|
+192.0.1.72 example.org
|
||||||
|
+192.0.1.73 example.org
|
||||||
|
+192.0.1.74 example.org
|
||||||
|
+192.0.1.75 example.org
|
||||||
|
+192.0.1.76 example.org
|
||||||
|
+192.0.1.77 example.org
|
||||||
|
+192.0.1.78 example.org
|
||||||
|
+192.0.1.79 example.org
|
||||||
|
+192.0.1.80 example.org
|
||||||
|
+192.0.1.81 example.org
|
||||||
|
+192.0.1.82 example.org
|
||||||
|
+192.0.1.83 example.org
|
||||||
|
+192.0.1.84 example.org
|
||||||
|
+192.0.1.85 example.org
|
||||||
|
+192.0.1.86 example.org
|
||||||
|
+192.0.1.87 example.org
|
||||||
|
+192.0.1.88 example.org
|
||||||
|
+192.0.1.89 example.org
|
||||||
|
+192.0.1.90 example.org
|
||||||
|
+192.0.1.91 example.org
|
||||||
|
+192.0.1.92 example.org
|
||||||
|
+192.0.1.93 example.org
|
||||||
|
+192.0.1.94 example.org
|
||||||
|
+192.0.1.95 example.org
|
||||||
|
+192.0.1.96 example.org
|
||||||
|
+192.0.1.97 example.org
|
||||||
|
+192.0.1.98 example.org
|
||||||
|
+192.0.1.99 example.org
|
||||||
|
+192.0.1.100 example.org
|
||||||
|
+192.0.1.101 example.org
|
||||||
|
+192.0.1.102 example.org
|
||||||
|
+192.0.1.103 example.org
|
||||||
|
+192.0.1.104 example.org
|
||||||
|
+192.0.1.105 example.org
|
||||||
|
+192.0.1.106 example.org
|
||||||
|
+192.0.1.107 example.org
|
||||||
|
+192.0.1.108 example.org
|
||||||
|
+192.0.1.109 example.org
|
||||||
|
+192.0.1.110 example.org
|
||||||
|
+192.0.1.111 example.org
|
||||||
|
+192.0.1.112 example.org
|
||||||
|
+192.0.1.113 example.org
|
||||||
|
+192.0.1.114 example.org
|
||||||
|
+192.0.1.115 example.org
|
||||||
|
+192.0.1.116 example.org
|
||||||
|
+192.0.1.117 example.org
|
||||||
|
+192.0.1.118 example.org
|
||||||
|
+192.0.1.119 example.org
|
||||||
|
+192.0.1.120 example.org
|
||||||
|
+192.0.1.121 example.org
|
||||||
|
+192.0.1.122 example.org
|
||||||
|
+192.0.1.123 example.org
|
||||||
|
+192.0.1.124 example.org
|
||||||
|
+192.0.1.125 example.org
|
||||||
|
+192.0.1.126 example.org
|
||||||
|
+192.0.1.127 example.org
|
||||||
|
+192.0.1.128 example.org
|
||||||
|
+192.0.1.129 example.org
|
||||||
|
+192.0.1.130 example.org
|
||||||
|
+192.0.1.131 example.org
|
||||||
|
+192.0.1.132 example.org
|
||||||
|
+192.0.1.133 example.org
|
||||||
|
+192.0.1.134 example.org
|
||||||
|
+192.0.1.135 example.org
|
||||||
|
+192.0.1.136 example.org
|
||||||
|
+192.0.1.137 example.org
|
||||||
|
+192.0.1.138 example.org
|
||||||
|
+192.0.1.139 example.org
|
||||||
|
+192.0.1.140 example.org
|
||||||
|
+192.0.1.141 example.org
|
||||||
|
+192.0.1.142 example.org
|
||||||
|
+192.0.1.143 example.org
|
||||||
|
+192.0.1.144 example.org
|
||||||
|
+192.0.1.145 example.org
|
||||||
|
+192.0.1.146 example.org
|
||||||
|
+192.0.1.147 example.org
|
||||||
|
+192.0.1.148 example.org
|
||||||
|
+192.0.1.149 example.org
|
||||||
|
+192.0.1.150 example.org
|
||||||
|
+192.0.1.151 example.org
|
||||||
|
+192.0.1.152 example.org
|
||||||
|
+192.0.1.153 example.org
|
||||||
|
+192.0.1.154 example.org
|
||||||
|
+192.0.1.155 example.org
|
||||||
|
+192.0.1.156 example.org
|
||||||
|
+192.0.1.157 example.org
|
||||||
|
+192.0.1.158 example.org
|
||||||
|
+192.0.1.159 example.org
|
||||||
|
+192.0.1.160 example.org
|
||||||
|
+192.0.1.161 example.org
|
||||||
|
+192.0.1.162 example.org
|
||||||
|
+192.0.1.163 example.org
|
||||||
|
+192.0.1.164 example.org
|
||||||
|
+192.0.1.165 example.org
|
||||||
|
+192.0.1.166 example.org
|
||||||
|
+192.0.1.167 example.org
|
||||||
|
+192.0.1.168 example.org
|
||||||
|
+192.0.1.169 example.org
|
||||||
|
+192.0.1.170 example.org
|
||||||
|
+192.0.1.171 example.org
|
||||||
|
+192.0.1.172 example.org
|
||||||
|
+192.0.1.173 example.org
|
||||||
|
+192.0.1.174 example.org
|
||||||
|
+192.0.1.175 example.org
|
||||||
|
+192.0.1.176 example.org
|
||||||
|
+192.0.1.177 example.org
|
||||||
|
+192.0.1.178 example.org
|
||||||
|
+192.0.1.179 example.org
|
||||||
|
+192.0.1.180 example.org
|
||||||
|
+192.0.1.181 example.org
|
||||||
|
+192.0.1.182 example.org
|
||||||
|
+192.0.1.183 example.org
|
||||||
|
+192.0.1.184 example.org
|
||||||
|
+192.0.1.185 example.org
|
||||||
|
+192.0.1.186 example.org
|
||||||
|
+192.0.1.187 example.org
|
||||||
|
+192.0.1.188 example.org
|
||||||
|
+192.0.1.189 example.org
|
||||||
|
+192.0.1.190 example.org
|
||||||
|
+192.0.1.191 example.org
|
||||||
|
+192.0.1.192 example.org
|
||||||
|
+192.0.1.193 example.org
|
||||||
|
+192.0.1.194 example.org
|
||||||
|
+192.0.1.195 example.org
|
||||||
|
+192.0.1.196 example.org
|
||||||
|
+192.0.1.197 example.org
|
||||||
|
+192.0.1.198 example.org
|
||||||
|
+192.0.1.199 example.org
|
||||||
|
+192.0.1.200 example.org
|
||||||
|
+192.0.1.201 example.org
|
||||||
|
+192.0.1.202 example.org
|
||||||
|
+192.0.1.203 example.org
|
||||||
|
+192.0.1.204 example.org
|
||||||
|
+192.0.1.205 example.org
|
||||||
|
+192.0.1.206 example.org
|
||||||
|
+192.0.1.207 example.org
|
||||||
|
+192.0.1.208 example.org
|
||||||
|
+192.0.1.209 example.org
|
||||||
|
+192.0.1.210 example.org
|
||||||
|
+192.0.1.211 example.org
|
||||||
|
+192.0.1.212 example.org
|
||||||
|
+192.0.1.213 example.org
|
||||||
|
+192.0.1.214 example.org
|
||||||
|
+192.0.1.215 example.org
|
||||||
|
+192.0.1.216 example.org
|
||||||
|
+192.0.1.217 example.org
|
||||||
|
+192.0.1.218 example.org
|
||||||
|
+192.0.1.219 example.org
|
||||||
|
+192.0.1.220 example.org
|
||||||
|
+192.0.1.221 example.org
|
||||||
|
+192.0.1.222 example.org
|
||||||
|
+192.0.1.223 example.org
|
||||||
|
+192.0.1.224 example.org
|
||||||
|
+192.0.1.225 example.org
|
||||||
|
+192.0.1.226 example.org
|
||||||
|
+192.0.1.227 example.org
|
||||||
|
+192.0.1.228 example.org
|
||||||
|
+192.0.1.229 example.org
|
||||||
|
+192.0.1.230 example.org
|
||||||
|
+192.0.1.231 example.org
|
||||||
|
+192.0.1.232 example.org
|
||||||
|
+192.0.1.233 example.org
|
||||||
|
+192.0.1.234 example.org
|
||||||
|
+192.0.1.235 example.org
|
||||||
|
+192.0.1.236 example.org
|
||||||
|
+192.0.1.237 example.org
|
||||||
|
+192.0.1.238 example.org
|
||||||
|
+192.0.1.239 example.org
|
||||||
|
+192.0.1.240 example.org
|
||||||
|
+192.0.1.241 example.org
|
||||||
|
+192.0.1.242 example.org
|
||||||
|
+192.0.1.243 example.org
|
||||||
|
+192.0.1.244 example.org
|
||||||
|
+192.0.1.245 example.org
|
||||||
|
+192.0.1.246 example.org
|
||||||
|
+192.0.1.247 example.org
|
||||||
|
+192.0.1.248 example.org
|
||||||
|
+192.0.1.249 example.org
|
||||||
|
+192.0.1.250 example.org
|
||||||
|
+192.0.1.251 example.org
|
||||||
|
+192.0.1.252 example.org
|
||||||
|
+192.0.1.253 example.org
|
||||||
|
+192.0.1.254 example.org
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 43dfc6739e350a58..f391dc0a59849aab 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -458,11 +458,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
{
|
||||||
|
- at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||||||
|
- at->family = AF_UNSPEC;
|
||||||
|
- at->scopeid = 0;
|
||||||
|
- at->next = NULL;
|
||||||
|
-
|
||||||
|
if (req->ai_flags & AI_IDN)
|
||||||
|
{
|
||||||
|
char *out;
|
||||||
|
@@ -473,13 +468,21 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
malloc_name = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
|
||||||
|
+ uint32_t addr[4];
|
||||||
|
+ if (__inet_aton_exact (name, (struct in_addr *) addr) != 0)
|
||||||
|
{
|
||||||
|
+ at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||||||
|
+ at->scopeid = 0;
|
||||||
|
+ at->next = NULL;
|
||||||
|
+
|
||||||
|
if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
|
||||||
|
- at->family = AF_INET;
|
||||||
|
+ {
|
||||||
|
+ memcpy (at->addr, addr, sizeof (at->addr));
|
||||||
|
+ at->family = AF_INET;
|
||||||
|
+ }
|
||||||
|
else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
|
||||||
|
{
|
||||||
|
- at->addr[3] = at->addr[0];
|
||||||
|
+ at->addr[3] = addr[0];
|
||||||
|
at->addr[2] = htonl (0xffff);
|
||||||
|
at->addr[1] = 0;
|
||||||
|
at->addr[0] = 0;
|
||||||
|
@@ -493,49 +496,62 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
|
if (req->ai_flags & AI_CANONNAME)
|
||||||
|
canon = name;
|
||||||
|
+
|
||||||
|
+ goto process_list;
|
||||||
|
}
|
||||||
|
- else if (at->family == AF_UNSPEC)
|
||||||
|
+
|
||||||
|
+ char *scope_delim = strchr (name, SCOPE_DELIMITER);
|
||||||
|
+ int e;
|
||||||
|
+
|
||||||
|
+ if (scope_delim == NULL)
|
||||||
|
+ e = inet_pton (AF_INET6, name, addr);
|
||||||
|
+ else
|
||||||
|
+ e = __inet_pton_length (AF_INET6, name, scope_delim - name, addr);
|
||||||
|
+
|
||||||
|
+ if (e > 0)
|
||||||
|
{
|
||||||
|
- char *scope_delim = strchr (name, SCOPE_DELIMITER);
|
||||||
|
- int e;
|
||||||
|
- if (scope_delim == NULL)
|
||||||
|
- e = inet_pton (AF_INET6, name, at->addr);
|
||||||
|
+ at = alloca_account (sizeof (struct gaih_addrtuple),
|
||||||
|
+ alloca_used);
|
||||||
|
+ at->scopeid = 0;
|
||||||
|
+ at->next = NULL;
|
||||||
|
+
|
||||||
|
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||||||
|
+ {
|
||||||
|
+ memcpy (at->addr, addr, sizeof (at->addr));
|
||||||
|
+ at->family = AF_INET6;
|
||||||
|
+ }
|
||||||
|
+ else if (req->ai_family == AF_INET
|
||||||
|
+ && IN6_IS_ADDR_V4MAPPED (addr))
|
||||||
|
+ {
|
||||||
|
+ at->addr[0] = addr[3];
|
||||||
|
+ at->addr[1] = addr[1];
|
||||||
|
+ at->addr[2] = addr[2];
|
||||||
|
+ at->addr[3] = addr[3];
|
||||||
|
+ at->family = AF_INET;
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
- e = __inet_pton_length (AF_INET6, name, scope_delim - name,
|
||||||
|
- at->addr);
|
||||||
|
- if (e > 0)
|
||||||
|
{
|
||||||
|
- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||||||
|
- at->family = AF_INET6;
|
||||||
|
- else if (req->ai_family == AF_INET
|
||||||
|
- && IN6_IS_ADDR_V4MAPPED (at->addr))
|
||||||
|
- {
|
||||||
|
- at->addr[0] = at->addr[3];
|
||||||
|
- at->family = AF_INET;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- result = -EAI_ADDRFAMILY;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (scope_delim != NULL
|
||||||
|
- && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
|
||||||
|
- scope_delim + 1,
|
||||||
|
- &at->scopeid) != 0)
|
||||||
|
- {
|
||||||
|
- result = -EAI_NONAME;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
+ result = -EAI_ADDRFAMILY;
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (req->ai_flags & AI_CANONNAME)
|
||||||
|
- canon = name;
|
||||||
|
+ if (scope_delim != NULL
|
||||||
|
+ && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
|
||||||
|
+ scope_delim + 1,
|
||||||
|
+ &at->scopeid) != 0)
|
||||||
|
+ {
|
||||||
|
+ result = -EAI_NONAME;
|
||||||
|
+ goto free_and_return;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (req->ai_flags & AI_CANONNAME)
|
||||||
|
+ canon = name;
|
||||||
|
+
|
||||||
|
+ goto process_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
|
||||||
|
+ if ((req->ai_flags & AI_NUMERICHOST) == 0)
|
||||||
|
{
|
||||||
|
- struct gaih_addrtuple **pat = &at;
|
||||||
|
int no_data = 0;
|
||||||
|
int no_inet6_data = 0;
|
||||||
|
nss_action_list nip;
|
||||||
|
@@ -543,6 +559,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
enum nss_status status = NSS_STATUS_UNAVAIL;
|
||||||
|
int no_more;
|
||||||
|
struct resolv_context *res_ctx = NULL;
|
||||||
|
+ bool do_merge = false;
|
||||||
|
|
||||||
|
/* If we do not have to look for IPv6 addresses or the canonical
|
||||||
|
name, use the simple, old functions, which do not support
|
||||||
|
@@ -579,7 +596,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
result = -EAI_MEMORY;
|
||||||
|
goto free_and_return;
|
||||||
|
}
|
||||||
|
- *pat = addrmem;
|
||||||
|
+ at = addrmem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@@ -632,6 +649,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gaih_addrtuple *addrfree = addrmem;
|
||||||
|
+ struct gaih_addrtuple **pat = &at;
|
||||||
|
+
|
||||||
|
for (int i = 0; i < air->naddrs; ++i)
|
||||||
|
{
|
||||||
|
socklen_t size = (air->family[i] == AF_INET
|
||||||
|
@@ -695,12 +714,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
|
free (air);
|
||||||
|
|
||||||
|
- if (at->family == AF_UNSPEC)
|
||||||
|
- {
|
||||||
|
- result = -EAI_NONAME;
|
||||||
|
- goto free_and_return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
goto process_list;
|
||||||
|
}
|
||||||
|
else if (err == 0)
|
||||||
|
@@ -732,6 +745,22 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
|
while (!no_more)
|
||||||
|
{
|
||||||
|
+ /* Always start afresh; continue should discard previous results
|
||||||
|
+ and the hosts database does not support merge. */
|
||||||
|
+ at = NULL;
|
||||||
|
+ free (canonbuf);
|
||||||
|
+ free (addrmem);
|
||||||
|
+ canon = canonbuf = NULL;
|
||||||
|
+ addrmem = NULL;
|
||||||
|
+ got_ipv6 = false;
|
||||||
|
+
|
||||||
|
+ if (do_merge)
|
||||||
|
+ {
|
||||||
|
+ __set_h_errno (NETDB_INTERNAL);
|
||||||
|
+ __set_errno (EBUSY);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
no_data = 0;
|
||||||
|
nss_gethostbyname4_r *fct4 = NULL;
|
||||||
|
|
||||||
|
@@ -744,12 +773,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
- status = DL_CALL_FCT (fct4, (name, pat,
|
||||||
|
+ status = DL_CALL_FCT (fct4, (name, &at,
|
||||||
|
tmpbuf->data, tmpbuf->length,
|
||||||
|
&errno, &h_errno,
|
||||||
|
NULL));
|
||||||
|
if (status == NSS_STATUS_SUCCESS)
|
||||||
|
break;
|
||||||
|
+ /* gethostbyname4_r may write into AT, so reset it. */
|
||||||
|
+ at = NULL;
|
||||||
|
if (status != NSS_STATUS_TRYAGAIN
|
||||||
|
|| errno != ERANGE || h_errno != NETDB_INTERNAL)
|
||||||
|
{
|
||||||
|
@@ -774,7 +805,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
no_data = 1;
|
||||||
|
|
||||||
|
if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
|
||||||
|
- canon = (*pat)->name;
|
||||||
|
+ canon = at->name;
|
||||||
|
+
|
||||||
|
+ struct gaih_addrtuple **pat = &at;
|
||||||
|
|
||||||
|
while (*pat != NULL)
|
||||||
|
{
|
||||||
|
@@ -826,6 +859,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
|
if (fct != NULL)
|
||||||
|
{
|
||||||
|
+ struct gaih_addrtuple **pat = &at;
|
||||||
|
+
|
||||||
|
if (req->ai_family == AF_INET6
|
||||||
|
|| req->ai_family == AF_UNSPEC)
|
||||||
|
{
|
||||||
|
@@ -899,6 +934,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ /* The hosts database does not support MERGE. */
|
||||||
|
+ if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
|
||||||
|
+ do_merge = true;
|
||||||
|
+
|
||||||
|
nip++;
|
||||||
|
if (nip->module == NULL)
|
||||||
|
no_more = -1;
|
||||||
|
@@ -930,7 +969,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
}
|
||||||
|
|
||||||
|
process_list:
|
||||||
|
- if (at->family == AF_UNSPEC)
|
||||||
|
+ if (at == NULL)
|
||||||
|
{
|
||||||
|
result = -EAI_NONAME;
|
||||||
|
goto free_and_return;
|
@ -0,0 +1,112 @@
|
|||||||
|
commit 849274d48fc59bfa6db3c713c8ced8026b20f3b7
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Thu Nov 16 19:55:35 2023 +0100
|
||||||
|
|
||||||
|
elf: Fix force_first handling in dlclose (bug 30981)
|
||||||
|
|
||||||
|
The force_first parameter was ineffective because the dlclose'd
|
||||||
|
object was not necessarily the first in the maps array. Also
|
||||||
|
enable force_first handling unconditionally, regardless of namespace.
|
||||||
|
The initial object in a namespace should be destructed first, too.
|
||||||
|
|
||||||
|
The _dl_sort_maps_dfs function had early returns for relocation
|
||||||
|
dependency processing which broke force_first handling, too, and
|
||||||
|
this is fixed in this change as well.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||||
|
index 95a03c9616c6a786..9d158c25498fd8ae 100644
|
||||||
|
--- a/elf/dl-close.c
|
||||||
|
+++ b/elf/dl-close.c
|
||||||
|
@@ -182,6 +182,16 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
}
|
||||||
|
assert (idx == nloaded);
|
||||||
|
|
||||||
|
+ /* Put the dlclose'd map first, so that its destructor runs first.
|
||||||
|
+ The map variable is NULL after a retry. */
|
||||||
|
+ if (map != NULL)
|
||||||
|
+ {
|
||||||
|
+ maps[map->l_idx] = maps[0];
|
||||||
|
+ maps[map->l_idx]->l_idx = map->l_idx;
|
||||||
|
+ maps[0] = map;
|
||||||
|
+ maps[0]->l_idx = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Keep track of the lowest index link map we have covered already. */
|
||||||
|
int done_index = -1;
|
||||||
|
while (++done_index < nloaded)
|
||||||
|
@@ -255,9 +265,10 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Sort the entries. We can skip looking for the binary itself which is
|
||||||
|
- at the front of the search list for the main namespace. */
|
||||||
|
- _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
|
||||||
|
+ /* Sort the entries. Unless retrying, the maps[0] object (the
|
||||||
|
+ original argument to dlclose) needs to remain first, so that its
|
||||||
|
+ destructor runs first. */
|
||||||
|
+ _dl_sort_maps (maps, nloaded, /* force_first */ map != NULL, true);
|
||||||
|
|
||||||
|
/* Call all termination functions at once. */
|
||||||
|
bool unload_any = false;
|
||||||
|
@@ -768,7 +779,11 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
/* Recheck if we need to retry, release the lock. */
|
||||||
|
out:
|
||||||
|
if (dl_close_state == rerun)
|
||||||
|
- goto retry;
|
||||||
|
+ {
|
||||||
|
+ /* The map may have been deallocated. */
|
||||||
|
+ map = NULL;
|
||||||
|
+ goto retry;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
dl_close_state = not_pending;
|
||||||
|
}
|
||||||
|
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||||
|
index e8ef5e8b3588ab53..937feb6e7008bc62 100644
|
||||||
|
--- a/elf/dl-sort-maps.c
|
||||||
|
+++ b/elf/dl-sort-maps.c
|
||||||
|
@@ -260,13 +260,12 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||||
|
The below memcpy is not needed in the do_reldeps case here,
|
||||||
|
since we wrote back to maps[] during DFS traversal. */
|
||||||
|
if (maps_head == maps)
|
||||||
|
- return;
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
assert (maps_head == maps);
|
||||||
|
- return;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
|
||||||
|
+ else
|
||||||
|
+ memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
|
||||||
|
|
||||||
|
/* Skipping the first object at maps[0] is not valid in general,
|
||||||
|
since traversing along object dependency-links may "find" that
|
||||||
|
diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
|
||||||
|
index 4bf9052db16fb352..cf6453e9eb85ac65 100644
|
||||||
|
--- a/elf/dso-sort-tests-1.def
|
||||||
|
+++ b/elf/dso-sort-tests-1.def
|
||||||
|
@@ -56,14 +56,16 @@ output: b>a>{}<a<b
|
||||||
|
# relocation(dynamic) dependencies. While this is technically unspecified, the
|
||||||
|
# presumed reasonable practical behavior is for the destructor order to respect
|
||||||
|
# the static DT_NEEDED links (here this means the a->b->c->d order).
|
||||||
|
-# The older dynamic_sort=1 algorithm does not achieve this, while the DFS-based
|
||||||
|
-# dynamic_sort=2 algorithm does, although it is still arguable whether going
|
||||||
|
-# beyond spec to do this is the right thing to do.
|
||||||
|
+# The older dynamic_sort=1 algorithm originally did not achieve this,
|
||||||
|
+# but this was a bug in the way _dl_sort_maps was called from _dl_close_worker,
|
||||||
|
+# effectively disabling proper force_first handling.
|
||||||
|
+# The new dynamic_sort=2 algorithm shows the effect of the simpler force_first
|
||||||
|
+# handling: the a object is simply moved to the front.
|
||||||
|
# The below expected outputs are what the two algorithms currently produce
|
||||||
|
# respectively, for regression testing purposes.
|
||||||
|
tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
|
||||||
|
-output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
|
||||||
|
-output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
|
||||||
|
+output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<b<c<d<g<f<e];}
|
||||||
|
+output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<g<f<b<c<d<e];}
|
||||||
|
|
||||||
|
# Test that even in the presence of dependency loops involving dlopen'ed
|
||||||
|
# object, that object is initialized last (and not unloaded prematurely).
|
@ -0,0 +1,26 @@
|
|||||||
|
From a07e000e82cb71238259e674529c37c12dc7d423 Mon Sep 17 00:00:00 2001
|
||||||
|
From: DJ Delorie <dj@redhat.com>
|
||||||
|
Date: Fri, 10 May 2024 17:34:29 -0400
|
||||||
|
Subject: manual: add dup3
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/manual/llio.texi b/manual/llio.texi
|
||||||
|
index fae49d1433..fe1807a849 100644
|
||||||
|
--- a/manual/llio.texi
|
||||||
|
+++ b/manual/llio.texi
|
||||||
|
@@ -3415,6 +3415,14 @@ middle of calling @code{dup2} at which @var{new} is closed and not yet a
|
||||||
|
duplicate of @var{old}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
+@deftypefun int dup3 (int @var{old}, int @var{new}, int @var{flags})
|
||||||
|
+@standards{Linux, unistd.h}
|
||||||
|
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
|
||||||
|
+This function is the same as @code{dup2} but creates the new
|
||||||
|
+descriptor as if it had been opened with flags @var{flags}. The only
|
||||||
|
+allowed flag is @code{O_CLOEXEC}.
|
||||||
|
+@end deftypefun
|
||||||
|
+
|
||||||
|
@deftypevr Macro int F_DUPFD
|
||||||
|
@standards{POSIX.1, fcntl.h}
|
||||||
|
This macro is used as the @var{command} argument to @code{fcntl}, to
|
@ -0,0 +1,341 @@
|
|||||||
|
From 6c0be74305745c8f78bcfb69442c8c379459d99b Mon Sep 17 00:00:00 2001
|
||||||
|
From: DJ Delorie <dj@redhat.com>
|
||||||
|
Date: Mon, 8 Jul 2024 17:52:15 -0400
|
||||||
|
Subject: manual: add syscalls
|
||||||
|
|
||||||
|
The purpose of this patch is to add some system calls that (1) aren't
|
||||||
|
otherwise documented, and (2) are merely redirected to the kernel, so
|
||||||
|
can refer to their documentation; and define a standard way of doing
|
||||||
|
so in the future. A more detailed explaination of how system calls
|
||||||
|
are wrapped is added along with reference to the Linux Man-Pages
|
||||||
|
project.
|
||||||
|
|
||||||
|
Default version of man-pages is in configure.ac but can be overridden
|
||||||
|
by --with-man-pages=X.Y
|
||||||
|
|
||||||
|
Reviewed-by: Alejandro Colomar <alx@kernel.org>
|
||||||
|
|
||||||
|
diff --git a/config.make.in b/config.make.in
|
||||||
|
index 55e8b7563b..36096881b7 100644
|
||||||
|
--- a/config.make.in
|
||||||
|
+++ b/config.make.in
|
||||||
|
@@ -101,6 +101,7 @@ build-hardcoded-path-in-tests= @hardcode
|
||||||
|
build-pt-chown = @build_pt_chown@
|
||||||
|
have-tunables = @have_tunables@
|
||||||
|
pthread-in-libc = @pthread_in_libc@
|
||||||
|
+man-pages-version = @man_pages_version@
|
||||||
|
|
||||||
|
# Build tools.
|
||||||
|
CC = @CC@
|
||||||
|
diff --git a/configure b/configure
|
||||||
|
index 55e8b7563b..36096881b7 100644
|
||||||
|
--- a/configure 2024-07-17 15:45:55.033649362 -0400
|
||||||
|
+++ b/configure 2024-07-17 15:47:44.281886629 -0400
|
||||||
|
@@ -681,6 +681,7 @@ force_install
|
||||||
|
bindnow
|
||||||
|
hardcoded_path_in_tests
|
||||||
|
enable_timezone_tools
|
||||||
|
+man_pages_version
|
||||||
|
rtld_early_cflags
|
||||||
|
extra_nonshared_cflags
|
||||||
|
use_default_link
|
||||||
|
@@ -763,6 +764,7 @@ with_headers
|
||||||
|
with_default_link
|
||||||
|
with_nonshared_cflags
|
||||||
|
with_rtld_early_cflags
|
||||||
|
+with_man_pages
|
||||||
|
enable_sanity_checks
|
||||||
|
enable_shared
|
||||||
|
enable_profile
|
||||||
|
@@ -1483,6 +1485,8 @@ Optional Packages:
|
||||||
|
build nonshared libraries with additional CFLAGS
|
||||||
|
--with-rtld-early-cflags=CFLAGS
|
||||||
|
build early initialization with additional CFLAGS
|
||||||
|
+ --with-man-pages=VERSION
|
||||||
|
+ tie manual to a specific man-pages version
|
||||||
|
--with-cpu=CPU select code for CPU variant
|
||||||
|
|
||||||
|
Some influential environment variables:
|
||||||
|
@@ -3396,6 +3400,15 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
+man_pages_version=6.9.1
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+# Check whether --with-man-pages was given.
|
||||||
|
+if test "${with_man_pages+set}" = set; then :
|
||||||
|
+ withval=$with_man_pages; man_pages_version=$withval
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+
|
||||||
|
|
||||||
|
# Check whether --enable-sanity-checks was given.
|
||||||
|
if test "${enable_sanity_checks+set}" = set; then :
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index e48957f318..9cbc0bf68f 100644
|
||||||
|
--- a/configure.ac 2024-07-17 15:45:52.181538742 -0400
|
||||||
|
+++ b/configure.ac 2024-07-17 15:46:29.885001095 -0400
|
||||||
|
@@ -169,6 +169,15 @@ AC_ARG_WITH([rtld-early-cflags],
|
||||||
|
[rtld_early_cflags=])
|
||||||
|
AC_SUBST(rtld_early_cflags)
|
||||||
|
|
||||||
|
+man_pages_version=6.9.1
|
||||||
|
+
|
||||||
|
+AC_ARG_WITH([man-pages],
|
||||||
|
+ AS_HELP_STRING([--with-man-pages=VERSION],
|
||||||
|
+ [tie manual to a specific man-pages version]),
|
||||||
|
+ [man_pages_version=$withval],
|
||||||
|
+ [])
|
||||||
|
+AC_SUBST(man_pages_version)
|
||||||
|
+
|
||||||
|
AC_ARG_ENABLE([sanity-checks],
|
||||||
|
AS_HELP_STRING([--disable-sanity-checks],
|
||||||
|
[really do not use threads (should not be used except in special situations) @<:@default=yes@:>@]),
|
||||||
|
diff --git a/manual/Makefile b/manual/Makefile
|
||||||
|
index b5fda4a7ae..a6c05db540 100644
|
||||||
|
--- a/manual/Makefile
|
||||||
|
+++ b/manual/Makefile
|
||||||
|
@@ -117,6 +117,7 @@ $(objpfx)stamp-pkgvers: $(common-objpfx)config.make
|
||||||
|
echo "@set PKGVERSION_DEFAULT" >> $(objpfx)pkgvers-tmp; \
|
||||||
|
fi
|
||||||
|
echo "@set REPORT_BUGS_TO $(REPORT_BUGS_TEXI)" >> $(objpfx)pkgvers-tmp
|
||||||
|
+ echo "@set man_pages_version $(man-pages-version)" >> $(objpfx)pkgvers-tmp; \
|
||||||
|
echo "@end ifclear" >> $(objpfx)pkgvers-tmp
|
||||||
|
$(move-if-change) $(objpfx)pkgvers-tmp $(objpfx)pkgvers.texi
|
||||||
|
touch $@
|
||||||
|
diff --git a/manual/intro.texi b/manual/intro.texi
|
||||||
|
index ff43c5a7fb..879c1b38d9 100644
|
||||||
|
--- a/manual/intro.texi
|
||||||
|
+++ b/manual/intro.texi
|
||||||
|
@@ -85,6 +85,7 @@ standards each function or symbol comes from.
|
||||||
|
* Berkeley Unix:: BSD and SunOS.
|
||||||
|
* SVID:: The System V Interface Description.
|
||||||
|
* XPG:: The X/Open Portability Guide.
|
||||||
|
+* Linux Kernel:: The Linux kernel.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node ISO C, POSIX, , Standards and Portability
|
||||||
|
@@ -941,7 +942,7 @@ inter-process communication and shared memory, the @code{hsearch} and
|
||||||
|
@code{drand48} families of functions, @code{fmtmsg} and several of the
|
||||||
|
mathematical functions.
|
||||||
|
|
||||||
|
-@node XPG, , SVID, Standards and Portability
|
||||||
|
+@node XPG, Linux Kernel, SVID, Standards and Portability
|
||||||
|
@subsection XPG (The X/Open Portability Guide)
|
||||||
|
|
||||||
|
The X/Open Portability Guide, published by the X/Open Company, Ltd., is
|
||||||
|
@@ -960,6 +961,20 @@ fulfilling the XPG standard with the Unix extensions is a
|
||||||
|
precondition for getting the Unix brand chances are good that the
|
||||||
|
functionality is available on commercial systems.
|
||||||
|
|
||||||
|
+@node Linux Kernel, , XPG, Standards and Portability
|
||||||
|
+@subsection Linux (The Linux Kernel)
|
||||||
|
+
|
||||||
|
+@Theglibc{} includes by reference the Linux man-pages
|
||||||
|
+@value{man_pages_version} documentation to document the listed
|
||||||
|
+syscalls for the Linux kernel. For reference purposes only the latest
|
||||||
|
+@uref{https://www.kernel.org/doc/man-pages/,Linux man-pages Project}
|
||||||
|
+documentation can be accessed from the
|
||||||
|
+@uref{https://www.kernel.org,Linux kernel} website. Where the syscall
|
||||||
|
+has more specific documentation in this manual that more specific
|
||||||
|
+documentation is considered authoritative.
|
||||||
|
+
|
||||||
|
+Additional details on the Linux system call interface can be found in
|
||||||
|
+@xref{System Calls}.
|
||||||
|
|
||||||
|
@node Using the Library, Roadmap to the Manual, Standards and Portability, Introduction
|
||||||
|
@section Using the Library
|
||||||
|
diff --git a/manual/llio.texi b/manual/llio.texi
|
||||||
|
index 78c7c79913..6f0a48609b 100644
|
||||||
|
--- a/manual/llio.texi
|
||||||
|
+++ b/manual/llio.texi
|
||||||
|
@@ -65,6 +65,7 @@ directly.)
|
||||||
|
* Interrupt Input:: Getting an asynchronous signal when
|
||||||
|
input arrives.
|
||||||
|
* IOCTLs:: Generic I/O Control operations.
|
||||||
|
+* Other Low-Level I/O APIs:: Other low-level-I/O-related functions.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2324,6 +2325,8 @@ file descriptor, or until the timeout period expires.
|
||||||
|
There is another example showing the use of @code{select} to multiplex
|
||||||
|
input from multiple sockets in @ref{Server Example}.
|
||||||
|
|
||||||
|
+For an alternate interface to this functionality, see @code{poll}
|
||||||
|
+(@pxref{Other Low-Level I/O APIs}).
|
||||||
|
|
||||||
|
@node Synchronizing I/O
|
||||||
|
@section Synchronizing I/O operations
|
||||||
|
@@ -3407,7 +3410,9 @@ require additional arguments to be supplied. These additional arguments
|
||||||
|
and the return value and error conditions are given in the detailed
|
||||||
|
descriptions of the individual commands.
|
||||||
|
|
||||||
|
-Briefly, here is a list of what the various commands are.
|
||||||
|
+Briefly, here is a list of what the various commands are. For an
|
||||||
|
+exhaustive list of kernel-specific options, please see @xref{System
|
||||||
|
+Calls}.
|
||||||
|
|
||||||
|
@vtable @code
|
||||||
|
@item F_DUPFD
|
||||||
|
@@ -4743,5 +4748,28 @@ Most IOCTLs are OS-specific and/or only used in special system utilities,
|
||||||
|
and are thus beyond the scope of this document. For an example of the use
|
||||||
|
of an IOCTL, see @ref{Out-of-Band Data}.
|
||||||
|
|
||||||
|
-@c FIXME this is undocumented:
|
||||||
|
-@c dup3
|
||||||
|
+@node Other Low-Level I/O APIs
|
||||||
|
+@section Other low-level-I/O-related functions
|
||||||
|
+
|
||||||
|
+@deftp {Data Type} {struct pollfd}
|
||||||
|
+@standards{POSIX.1,poll.h}
|
||||||
|
+@end deftp
|
||||||
|
+
|
||||||
|
+@deftp {Data Type} {struct epoll_event}
|
||||||
|
+@standards{Linux,sys/epoll.h}
|
||||||
|
+@end deftp
|
||||||
|
+
|
||||||
|
+@deftypefun int poll (struct pollfd *@var{fds}, nfds_t @var{nfds}, int @var{timeout})
|
||||||
|
+
|
||||||
|
+@manpagefunctionstub{poll,2}
|
||||||
|
+@end deftypefun
|
||||||
|
+
|
||||||
|
+@deftypefun int epoll_create(int @var{size})
|
||||||
|
+
|
||||||
|
+@manpagefunctionstub{epoll_create,2}
|
||||||
|
+@end deftypefun
|
||||||
|
+
|
||||||
|
+@deftypefun int epoll_wait(int @var{epfd}, struct epoll_event *@var{events}, int @var{maxevents}, int @var{timeout})
|
||||||
|
+
|
||||||
|
+@manpagefunctionstub{epoll_wait,2}
|
||||||
|
+@end deftypefun
|
||||||
|
diff --git a/manual/macros.texi b/manual/macros.texi
|
||||||
|
index 4a2e22f473..579da3fb81 100644
|
||||||
|
--- a/manual/macros.texi
|
||||||
|
+++ b/manual/macros.texi
|
||||||
|
@@ -282,4 +282,11 @@ cwd\comments\
|
||||||
|
@macro standardsx {element, standard, header}
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
+@macro manpagefunctionstub {func,sec}
|
||||||
|
+This documentation is a stub. For additional information on this
|
||||||
|
+function, consult the manual page
|
||||||
|
+@url{https://man7.org/linux/man-pages/man\sec\/\func\.\sec\.html}.
|
||||||
|
+@xref{Linux Kernel}.
|
||||||
|
+@end macro
|
||||||
|
+
|
||||||
|
@end ifclear
|
||||||
|
diff --git a/manual/socket.texi b/manual/socket.texi
|
||||||
|
index f0e35d9e13..8708cbb07c 100644
|
||||||
|
--- a/manual/socket.texi
|
||||||
|
+++ b/manual/socket.texi
|
||||||
|
@@ -41,6 +41,7 @@ aren't documented either so far.
|
||||||
|
is to make it work with Inetd.
|
||||||
|
* Socket Options:: Miscellaneous low-level socket options.
|
||||||
|
* Networks Database:: Accessing the database of network names.
|
||||||
|
+* Other Socket APIs:: Other socket-related functions.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Socket Concepts
|
||||||
|
@@ -3134,38 +3135,8 @@ You can use plain @code{recv} (@pxref{Receiving Data}) instead of
|
||||||
|
treat all possible senders alike). Even @code{read} can be used if
|
||||||
|
you don't want to specify @var{flags} (@pxref{I/O Primitives}).
|
||||||
|
|
||||||
|
-@ignore
|
||||||
|
-@c sendmsg and recvmsg are like readv and writev in that they
|
||||||
|
-@c use a series of buffers. It's not clear this is worth
|
||||||
|
-@c supporting or that we support them.
|
||||||
|
-@c !!! they can do more; it is hairy
|
||||||
|
-
|
||||||
|
-@deftp {Data Type} {struct msghdr}
|
||||||
|
-@standards{BSD, sys/socket.h}
|
||||||
|
-@end deftp
|
||||||
|
-
|
||||||
|
-@deftypefun ssize_t sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags})
|
||||||
|
-@standards{BSD, sys/socket.h}
|
||||||
|
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
|
||||||
|
-
|
||||||
|
-This function is defined as a cancellation point in multi-threaded
|
||||||
|
-programs, so one has to be prepared for this and make sure that
|
||||||
|
-allocated resources (like memory, files descriptors, semaphores or
|
||||||
|
-whatever) are freed even if the thread is cancel.
|
||||||
|
-@c @xref{pthread_cleanup_push}, for a method how to do this.
|
||||||
|
-@end deftypefun
|
||||||
|
-
|
||||||
|
-@deftypefun ssize_t recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags})
|
||||||
|
-@standards{BSD, sys/socket.h}
|
||||||
|
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
|
||||||
|
-
|
||||||
|
-This function is defined as a cancellation point in multi-threaded
|
||||||
|
-programs, so one has to be prepared for this and make sure that
|
||||||
|
-allocated resources (like memory, files descriptors, semaphores or
|
||||||
|
-whatever) are freed even if the thread is canceled.
|
||||||
|
-@c @xref{pthread_cleanup_push}, for a method how to do this.
|
||||||
|
-@end deftypefun
|
||||||
|
-@end ignore
|
||||||
|
+If you need more flexibility and/or control over sending and receiving
|
||||||
|
+packets, see @code{sendmsg} and @code{recvmsg} (@pxref{Other Socket APIs}).
|
||||||
|
|
||||||
|
@node Datagram Example
|
||||||
|
@subsection Datagram Socket Example
|
||||||
|
@@ -3664,3 +3635,20 @@ returns a null pointer if there are no more entries.
|
||||||
|
@c libc_lock_unlock @aculock
|
||||||
|
This function closes the networks database.
|
||||||
|
@end deftypefun
|
||||||
|
+
|
||||||
|
+@node Other Socket APIs
|
||||||
|
+@section Other Socket APIs
|
||||||
|
+
|
||||||
|
+@deftp {Data Type} {struct msghdr}
|
||||||
|
+@standards{BSD, sys/socket.h}
|
||||||
|
+@end deftp
|
||||||
|
+
|
||||||
|
+@deftypefun ssize_t sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags})
|
||||||
|
+
|
||||||
|
+@manpagefunctionstub{sendmsg,2}
|
||||||
|
+@end deftypefun
|
||||||
|
+
|
||||||
|
+@deftypefun ssize_t recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags})
|
||||||
|
+
|
||||||
|
+@manpagefunctionstub{recvmsg,2}
|
||||||
|
+@end deftypefun
|
||||||
|
diff --git a/manual/startup.texi b/manual/startup.texi
|
||||||
|
index 224dd98c1e..747beed4d9 100644
|
||||||
|
--- a/manual/startup.texi
|
||||||
|
+++ b/manual/startup.texi
|
||||||
|
@@ -689,7 +689,25 @@ you don't need to know about it because you can just use @theglibc{}'s
|
||||||
|
@code{chmod} function.
|
||||||
|
|
||||||
|
@cindex kernel call
|
||||||
|
-System calls are sometimes called kernel calls.
|
||||||
|
+System calls are sometimes called syscalls or kernel calls, and this
|
||||||
|
+interface is mostly a purely mechanical translation from the kernel's
|
||||||
|
+ABI to the C ABI. For the set of syscalls where we do not guarantee
|
||||||
|
+POSIX Thread cancellation the wrappers only organize the incoming
|
||||||
|
+arguments from the C calling convention to the calling convention of
|
||||||
|
+the target kernel. For the set of syscalls where we provided POSIX
|
||||||
|
+Thread cancellation the wrappers set some internal state in the
|
||||||
|
+library to support cancellation, but this does not impact the
|
||||||
|
+behaviour of the syscall provided by the kernel.
|
||||||
|
+
|
||||||
|
+In some cases, if @theglibc{} detects that a system call has been
|
||||||
|
+superseded by a more capable one, the wrapper may map the old call to
|
||||||
|
+the new one. For example, @code{dup2} is implemented via @code{dup3}
|
||||||
|
+by passing an additional empty flags argument, and @code{open} calls
|
||||||
|
+@code{openat} passing the additional @code{AT_FDCWD}. Sometimes even
|
||||||
|
+more is done, such as converting between 32-bit and 64-bit time
|
||||||
|
+values. In general, though, such processing is only to make the
|
||||||
|
+system call better match the C ABI, rather than change its
|
||||||
|
+functionality.
|
||||||
|
|
||||||
|
However, there are times when you want to make a system call explicitly,
|
||||||
|
and for that, @theglibc{} provides the @code{syscall} function.
|
||||||
|
@@ -711,6 +729,8 @@ we won't describe it here either because anyone who is coding
|
||||||
|
library source code as a specification of the interface between them
|
||||||
|
anyway.
|
||||||
|
|
||||||
|
+@code{syscall} does not provide cancellation logic, even if the system
|
||||||
|
+call you're calling is listed as cancellable above.
|
||||||
|
|
||||||
|
@code{syscall} is declared in @file{unistd.h}.
|
||||||
|
|
@ -0,0 +1,188 @@
|
|||||||
|
From a4c3f5f46e850c977cda81c251036475aab8313c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu, 23 Nov 2023 14:29:14 -0300
|
||||||
|
Subject: [PATCH] elf: Add a way to check if tunable is set (BZ 27069)
|
||||||
|
Content-type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
The patch adds two new macros, TUNABLE_GET_DEFAULT and TUNABLE_IS_INITIALIZED,
|
||||||
|
here the former get the default value with a signature similar to
|
||||||
|
TUNABLE_GET, while the later returns whether the tunable was set by
|
||||||
|
the environment variable.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu.
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Versions
|
||||||
|
(removed to preserve ABI)
|
||||||
|
elf/dl-tunable-types.h
|
||||||
|
(line numbers)
|
||||||
|
scripts/gen-tunables.awk
|
||||||
|
(account for missing TUNABLE_SECLEVEL patch)
|
||||||
|
|
||||||
|
---
|
||||||
|
elf/dl-tunable-types.h | 1 +
|
||||||
|
elf/dl-tunables.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||||
|
elf/dl-tunables.h | 28 ++++++++++++++++++++++++++++
|
||||||
|
elf/dl-tunables.list | 1 +
|
||||||
|
scripts/gen-tunables.awk | 4 ++--
|
||||||
|
6 files changed, 73 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff -rup a/elf/dl-tunable-types.h b/elf/dl-tunable-types.h
|
||||||
|
--- a/elf/dl-tunable-types.h 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/elf/dl-tunable-types.h 2024-03-26 18:23:22.211504813 -0400
|
||||||
|
@@ -61,6 +61,7 @@ struct _tunable
|
||||||
|
{
|
||||||
|
const char name[TUNABLE_NAME_MAX]; /* Internal name of the tunable. */
|
||||||
|
tunable_type_t type; /* Data type of the tunable. */
|
||||||
|
+ const tunable_val_t def; /* The value. */
|
||||||
|
tunable_val_t val; /* The value. */
|
||||||
|
bool initialized; /* Flag to indicate that the tunable is
|
||||||
|
initialized. */
|
||||||
|
diff -rup a/elf/dl-tunables.c b/elf/dl-tunables.c
|
||||||
|
--- a/elf/dl-tunables.c 2024-03-26 18:21:10.090681748 -0400
|
||||||
|
+++ b/elf/dl-tunables.c 2024-03-26 18:23:22.214504923 -0400
|
||||||
|
@@ -152,6 +152,13 @@ tunable_initialize (tunable_t *cur, cons
|
||||||
|
do_tunable_update_val (cur, &val, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool
|
||||||
|
+__tunable_is_initialized (tunable_id_t id)
|
||||||
|
+{
|
||||||
|
+ return tunable_list[id].initialized;
|
||||||
|
+}
|
||||||
|
+rtld_hidden_def (__tunable_is_initialized)
|
||||||
|
+
|
||||||
|
void
|
||||||
|
__tunable_set_val (tunable_id_t id, tunable_val_t *valp, tunable_num_t *minp,
|
||||||
|
tunable_num_t *maxp)
|
||||||
|
@@ -399,6 +406,39 @@ __tunables_print (void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+__tunable_get_default (tunable_id_t id, void *valp)
|
||||||
|
+{
|
||||||
|
+ tunable_t *cur = &tunable_list[id];
|
||||||
|
+
|
||||||
|
+ switch (cur->type.type_code)
|
||||||
|
+ {
|
||||||
|
+ case TUNABLE_TYPE_UINT_64:
|
||||||
|
+ {
|
||||||
|
+ *((uint64_t *) valp) = (uint64_t) cur->def.numval;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case TUNABLE_TYPE_INT_32:
|
||||||
|
+ {
|
||||||
|
+ *((int32_t *) valp) = (int32_t) cur->def.numval;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case TUNABLE_TYPE_SIZE_T:
|
||||||
|
+ {
|
||||||
|
+ *((size_t *) valp) = (size_t) cur->def.numval;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case TUNABLE_TYPE_STRING:
|
||||||
|
+ {
|
||||||
|
+ *((const char **)valp) = cur->def.strval;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ default:
|
||||||
|
+ __builtin_unreachable ();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+rtld_hidden_def (__tunable_get_default)
|
||||||
|
+
|
||||||
|
/* Set the tunable value. This is called by the module that the tunable exists
|
||||||
|
in. */
|
||||||
|
void
|
||||||
|
diff -rup a/elf/dl-tunables.h b/elf/dl-tunables.h
|
||||||
|
--- a/elf/dl-tunables.h 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/elf/dl-tunables.h 2024-03-26 18:23:22.217505032 -0400
|
||||||
|
@@ -53,18 +53,26 @@ typedef void (*tunable_callback_t) (tuna
|
||||||
|
|
||||||
|
extern void __tunables_init (char **);
|
||||||
|
extern void __tunables_print (void);
|
||||||
|
+extern bool __tunable_is_initialized (tunable_id_t);
|
||||||
|
extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t);
|
||||||
|
extern void __tunable_set_val (tunable_id_t, tunable_val_t *, tunable_num_t *,
|
||||||
|
tunable_num_t *);
|
||||||
|
+extern void __tunable_get_default (tunable_id_t id, void *valp);
|
||||||
|
rtld_hidden_proto (__tunables_init)
|
||||||
|
rtld_hidden_proto (__tunables_print)
|
||||||
|
+rtld_hidden_proto (__tunable_is_initialized)
|
||||||
|
rtld_hidden_proto (__tunable_get_val)
|
||||||
|
rtld_hidden_proto (__tunable_set_val)
|
||||||
|
+rtld_hidden_proto (__tunable_get_default)
|
||||||
|
|
||||||
|
/* Define TUNABLE_GET and TUNABLE_SET in short form if TOP_NAMESPACE and
|
||||||
|
TUNABLE_NAMESPACE are defined. This is useful shorthand to get and set
|
||||||
|
tunables within a module. */
|
||||||
|
#if defined TOP_NAMESPACE && defined TUNABLE_NAMESPACE
|
||||||
|
+# define TUNABLE_IS_INITIALIZED(__id) \
|
||||||
|
+ TUNABLE_IS_INITIALIZED_FULL(TOP_NAMESPACE, TUNABLE_NAMESPACE, __id)
|
||||||
|
+# define TUNABLE_GET_DEFAULT(__id, __type) \
|
||||||
|
+ TUNABLE_GET_DEFAULT_FULL(TOP_NAMESPACE, TUNABLE_NAMESPACE,__id, __type)
|
||||||
|
# define TUNABLE_GET(__id, __type, __cb) \
|
||||||
|
TUNABLE_GET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __cb)
|
||||||
|
# define TUNABLE_SET(__id, __val) \
|
||||||
|
@@ -73,6 +81,10 @@ rtld_hidden_proto (__tunable_set_val)
|
||||||
|
TUNABLE_SET_WITH_BOUNDS_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, \
|
||||||
|
__val, __min, __max)
|
||||||
|
#else
|
||||||
|
+# define TUNABLE_IS_INITIALIZED(__top, __ns, __id) \
|
||||||
|
+ TUNABLE_IS_INITIALIZED_FULL(__top, __ns, __id)
|
||||||
|
+# define TUNABLE_GET_DEFAULT(__top, __ns, __type) \
|
||||||
|
+ TUNABLE_GET_DEFAULT_FULL(__top, __ns, __id, __type)
|
||||||
|
# define TUNABLE_GET(__top, __ns, __id, __type, __cb) \
|
||||||
|
TUNABLE_GET_FULL (__top, __ns, __id, __type, __cb)
|
||||||
|
# define TUNABLE_SET(__top, __ns, __id, __val) \
|
||||||
|
@@ -81,6 +93,22 @@ rtld_hidden_proto (__tunable_set_val)
|
||||||
|
TUNABLE_SET_WITH_BOUNDS_FULL (__top, __ns, __id, __val, __min, __max)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+/* Return whether the tunable was initialized by the environment variable. */
|
||||||
|
+#define TUNABLE_IS_INITIALIZED_FULL(__top, __ns, __id) \
|
||||||
|
+({ \
|
||||||
|
+ tunable_id_t id = TUNABLE_ENUM_NAME (__top, __ns, __id); \
|
||||||
|
+ __tunable_is_initialized (id); \
|
||||||
|
+})
|
||||||
|
+
|
||||||
|
+/* Return the default value of the tunable. */
|
||||||
|
+#define TUNABLE_GET_DEFAULT_FULL(__top, __ns, __id, __type) \
|
||||||
|
+({ \
|
||||||
|
+ tunable_id_t id = TUNABLE_ENUM_NAME (__top, __ns, __id); \
|
||||||
|
+ __type __ret; \
|
||||||
|
+ __tunable_get_default (id, &__ret); \
|
||||||
|
+ __ret; \
|
||||||
|
+})
|
||||||
|
+
|
||||||
|
/* Get and return a tunable value. If the tunable was set externally and __CB
|
||||||
|
is defined then call __CB before returning the value. */
|
||||||
|
# define TUNABLE_GET_FULL(__top, __ns, __id, __type, __cb) \
|
||||||
|
diff -rup a/elf/dl-tunables.list b/elf/dl-tunables.list
|
||||||
|
--- a/elf/dl-tunables.list 2024-03-26 18:21:09.664666196 -0400
|
||||||
|
+++ b/elf/dl-tunables.list 2024-03-26 18:23:22.220505142 -0400
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
# type: Defaults to STRING
|
||||||
|
# minval: Optional minimum acceptable value
|
||||||
|
# maxval: Optional maximum acceptable value
|
||||||
|
+# default: Optional default value (if not specified it will be 0 or "")
|
||||||
|
# env_alias: An alias environment variable
|
||||||
|
# security_level: Specify security level of the tunable for AT_SECURE binaries.
|
||||||
|
# Valid values are:
|
||||||
|
diff -rup a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk
|
||||||
|
--- a/scripts/gen-tunables.awk 2024-03-26 18:21:09.523661049 -0400
|
||||||
|
+++ b/scripts/gen-tunables.awk 2024-03-26 18:34:45.385462341 -0400
|
||||||
|
@@ -236,8 +236,8 @@ END {
|
||||||
|
n = indices[2];
|
||||||
|
m = indices[3];
|
||||||
|
printf (" {TUNABLE_NAME_S(%s, %s, %s)", t, n, m)
|
||||||
|
- printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, NULL, TUNABLE_SECLEVEL_%s, %s},\n",
|
||||||
|
- types[t,n,m], minvals[t,n,m], maxvals[t,n,m],
|
||||||
|
+ printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, {%s}, NULL, TUNABLE_SECLEVEL_%s, %s},\n",
|
||||||
|
+ types[t,n,m], minvals[t,n,m], maxvals[t,n,m],default_val[t,n,m],
|
||||||
|
default_val[t,n,m], security_level[t,n,m], env_alias[t,n,m]);
|
||||||
|
}
|
||||||
|
print "};"
|
@ -0,0 +1,164 @@
|
|||||||
|
This patch was developed under embargo and cannot reference an upstream
|
||||||
|
commit. To find the associated commit please review the upstream git
|
||||||
|
log for CVE-2023-4911 to identify the relevant commits.
|
||||||
|
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
Date: Tue Sep 19 11:52:44 2023 -0400
|
||||||
|
|
||||||
|
tunables: Terminate if end of input is reached (CVE-2023-4911)
|
||||||
|
|
||||||
|
The string parsing routine may end up writing beyond bounds of tunestr
|
||||||
|
if the input tunable string is malformed, of the form name=name=val.
|
||||||
|
This gets processed twice, first as name=name=val and next as name=val,
|
||||||
|
resulting in tunestr being name=name=val:name=val, thus overflowing
|
||||||
|
tunestr.
|
||||||
|
|
||||||
|
Terminate the parsing loop at the first instance itself so that tunestr
|
||||||
|
does not overflow.
|
||||||
|
|
||||||
|
This also fixes up tst-env-setuid-tunables to actually handle failures
|
||||||
|
correct and add new tests to validate the fix for this CVE.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
---
|
||||||
|
Tested on x86_64.
|
||||||
|
|
||||||
|
NEWS | 5 +++++
|
||||||
|
elf/dl-tunables.c | 17 ++++++++++-------
|
||||||
|
elf/tst-env-setuid-tunables.c | 36 +++++++++++++++++++++++++++--------
|
||||||
|
3 files changed, 43 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
NEWS
|
||||||
|
(Dropped)
|
||||||
|
elf/tst-env-setuid-tunables.c
|
||||||
|
(Trivial HAVE_TUNABLES conflict)
|
||||||
|
|
||||||
|
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
|
||||||
|
index 8009e54ee5db32be..837474b5044cb5d7 100644
|
||||||
|
--- a/elf/dl-tunables.c
|
||||||
|
+++ b/elf/dl-tunables.c
|
||||||
|
@@ -188,11 +188,7 @@ parse_tunables (char *tunestr, char *valstring)
|
||||||
|
/* If we reach the end of the string before getting a valid name-value
|
||||||
|
pair, bail out. */
|
||||||
|
if (p[len] == '\0')
|
||||||
|
- {
|
||||||
|
- if (__libc_enable_secure)
|
||||||
|
- tunestr[off] = '\0';
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
/* We did not find a valid name-value pair before encountering the
|
||||||
|
colon. */
|
||||||
|
@@ -252,9 +248,16 @@ parse_tunables (char *tunestr, char *valstring)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (p[len] != '\0')
|
||||||
|
- p += len + 1;
|
||||||
|
+ /* We reached the end while processing the tunable string. */
|
||||||
|
+ if (p[len] == '\0')
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ p += len + 1;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* Terminate tunestr before we leave. */
|
||||||
|
+ if (__libc_enable_secure)
|
||||||
|
+ tunestr[off] = '\0';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
|
||||||
|
index 05619c9adc8b2698..cd4e84364074c613 100644
|
||||||
|
--- a/elf/tst-env-setuid-tunables.c
|
||||||
|
+++ b/elf/tst-env-setuid-tunables.c
|
||||||
|
@@ -52,6 +52,8 @@ const char *teststrings[] =
|
||||||
|
"glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
|
||||||
|
"glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096",
|
||||||
|
"not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
|
||||||
|
+ "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096",
|
||||||
|
+ "glibc.malloc.check=2",
|
||||||
|
"glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2",
|
||||||
|
"glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096",
|
||||||
|
":glibc.malloc.garbage=2:glibc.malloc.check=1",
|
||||||
|
@@ -70,6 +72,8 @@ const char *resultstrings[] =
|
||||||
|
"glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
|
||||||
|
"glibc.malloc.mmap_threshold=4096",
|
||||||
|
"glibc.malloc.mmap_threshold=4096",
|
||||||
|
+ "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096",
|
||||||
|
+ "",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
@@ -84,11 +88,18 @@ test_child (int off)
|
||||||
|
const char *val = getenv ("GLIBC_TUNABLES");
|
||||||
|
|
||||||
|
#if HAVE_TUNABLES
|
||||||
|
+ printf (" [%d] GLIBC_TUNABLES is %s\n", off, val);
|
||||||
|
+ fflush (stdout);
|
||||||
|
if (val != NULL && strcmp (val, resultstrings[off]) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (val != NULL)
|
||||||
|
- printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val);
|
||||||
|
+ printf (" [%d] Unexpected GLIBC_TUNABLES VALUE %s, expected %s\n",
|
||||||
|
+ off, val, resultstrings[off]);
|
||||||
|
+ else
|
||||||
|
+ printf (" [%d] GLIBC_TUNABLES environment variable absent\n", off);
|
||||||
|
+
|
||||||
|
+ fflush (stdout);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
@@ -117,21 +128,26 @@ do_test (int argc, char **argv)
|
||||||
|
if (ret != 0)
|
||||||
|
exit (1);
|
||||||
|
|
||||||
|
- exit (EXIT_SUCCESS);
|
||||||
|
+ /* Special return code to make sure that the child executed all the way
|
||||||
|
+ through. */
|
||||||
|
+ exit (42);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- int ret = 0;
|
||||||
|
-
|
||||||
|
/* Spawn tests. */
|
||||||
|
for (int i = 0; i < array_length (teststrings); i++)
|
||||||
|
{
|
||||||
|
char buf[INT_BUFSIZE_BOUND (int)];
|
||||||
|
|
||||||
|
- printf ("Spawned test for %s (%d)\n", teststrings[i], i);
|
||||||
|
+ printf ("[%d] Spawned test for %s\n", i, teststrings[i]);
|
||||||
|
snprintf (buf, sizeof (buf), "%d\n", i);
|
||||||
|
+ fflush (stdout);
|
||||||
|
if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
|
||||||
|
- exit (1);
|
||||||
|
+ {
|
||||||
|
+ printf (" [%d] Failed to set GLIBC_TUNABLES: %m", i);
|
||||||
|
+ support_record_failure ();
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
int status = support_capture_subprogram_self_sgid (buf);
|
||||||
|
|
||||||
|
@@ -139,9 +155,14 @@ do_test (int argc, char **argv)
|
||||||
|
if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
|
||||||
|
return EXIT_UNSUPPORTED;
|
||||||
|
|
||||||
|
- ret |= status;
|
||||||
|
+ if (WEXITSTATUS (status) != 42)
|
||||||
|
+ {
|
||||||
|
+ printf (" [%d] child failed with status %d\n", i,
|
||||||
|
+ WEXITSTATUS (status));
|
||||||
|
+ support_record_failure ();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- return ret;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,205 @@
|
|||||||
|
From dce754b1553b86fc6352636f1fa490a85b7cf0ff Mon Sep 17 00:00:00 2001
|
||||||
|
From: DJ Delorie <dj@redhat.com>
|
||||||
|
Date: Fri, 10 May 2024 14:52:09 -0400
|
||||||
|
Subject: Update mmap() flags and errors lists
|
||||||
|
|
||||||
|
Extend the list of MAP_* macros to include all macros available
|
||||||
|
to the average program (gcc -E -dM | grep MAP_*)
|
||||||
|
|
||||||
|
Extend the list of errno codes.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/manual/llio.texi b/manual/llio.texi
|
||||||
|
index fe1807a849..78c7c79913 100644
|
||||||
|
--- a/manual/llio.texi
|
||||||
|
+++ b/manual/llio.texi
|
||||||
|
@@ -1573,10 +1573,15 @@ permitted. They include @code{PROT_READ}, @code{PROT_WRITE}, and
|
||||||
|
of address space for future use. The @code{mprotect} function can be
|
||||||
|
used to change the protection flags. @xref{Memory Protection}.
|
||||||
|
|
||||||
|
-@var{flags} contains flags that control the nature of the map.
|
||||||
|
-One of @code{MAP_SHARED} or @code{MAP_PRIVATE} must be specified.
|
||||||
|
+The @var{flags} parameter contains flags that control the nature of
|
||||||
|
+the map. One of @code{MAP_SHARED}, @code{MAP_SHARED_VALIDATE}, or
|
||||||
|
+@code{MAP_PRIVATE} must be specified. Additional flags may be bitwise
|
||||||
|
+OR'd to further define the mapping.
|
||||||
|
|
||||||
|
-They include:
|
||||||
|
+Note that, aside from @code{MAP_PRIVATE} and @code{MAP_SHARED}, not
|
||||||
|
+all flags are supported on all versions of all operating systems.
|
||||||
|
+Consult the kernel-specific documentation for details. The flags
|
||||||
|
+include:
|
||||||
|
|
||||||
|
@vtable @code
|
||||||
|
@item MAP_PRIVATE
|
||||||
|
@@ -1598,9 +1603,19 @@ Note that actual writing may take place at any time. You need to use
|
||||||
|
@code{msync}, described below, if it is important that other processes
|
||||||
|
using conventional I/O get a consistent view of the file.
|
||||||
|
|
||||||
|
+@item MAP_SHARED_VALIDATE
|
||||||
|
+Similar to @code{MAP_SHARED} except that additional flags will be
|
||||||
|
+validated by the kernel, and the call will fail if an unrecognized
|
||||||
|
+flag is provided. With @code{MAP_SHARED} using a flag on a kernel
|
||||||
|
+that doesn't support it causes the flag to be ignored.
|
||||||
|
+@code{MAP_SHARED_VALIDATE} should be used when the behavior of all
|
||||||
|
+flags is required.
|
||||||
|
+
|
||||||
|
@item MAP_FIXED
|
||||||
|
This forces the system to use the exact mapping address specified in
|
||||||
|
-@var{address} and fail if it can't.
|
||||||
|
+@var{address} and fail if it can't. Note that if the new mapping
|
||||||
|
+would overlap an existing mapping, the overlapping portion of the
|
||||||
|
+existing map is unmapped.
|
||||||
|
|
||||||
|
@c One of these is official - the other is obviously an obsolete synonym
|
||||||
|
@c Which is which?
|
||||||
|
@@ -1641,10 +1656,73 @@ The @code{MAP_HUGETLB} flag is specific to Linux.
|
||||||
|
@c There is a mechanism to select different hugepage sizes; see
|
||||||
|
@c include/uapi/asm-generic/hugetlb_encode.h in the kernel sources.
|
||||||
|
|
||||||
|
-@c Linux has some other MAP_ options, which I have not discussed here.
|
||||||
|
-@c MAP_DENYWRITE, MAP_EXECUTABLE and MAP_GROWSDOWN don't seem applicable to
|
||||||
|
-@c user programs (and I don't understand the last two). MAP_LOCKED does
|
||||||
|
-@c not appear to be implemented.
|
||||||
|
+@item MAP_32BIT
|
||||||
|
+Require addresses that can be accessed with a signed 32 bit pointer,
|
||||||
|
+i.e., within the first 2 GiB. Ignored if MAP_FIXED is specified.
|
||||||
|
+
|
||||||
|
+@item MAP_DENYWRITE
|
||||||
|
+@itemx MAP_EXECUTABLE
|
||||||
|
+@itemx MAP_FILE
|
||||||
|
+
|
||||||
|
+Provided for compatibility. Ignored by the Linux kernel.
|
||||||
|
+
|
||||||
|
+@item MAP_FIXED_NOREPLACE
|
||||||
|
+Similar to @code{MAP_FIXED} except the call will fail with
|
||||||
|
+@code{EEXIST} if the new mapping would overwrite an existing mapping.
|
||||||
|
+To test for support for this flag, specify MAP_FIXED_NOREPLACE without
|
||||||
|
+MAP_FIXED, and (if the call was successful) check the actual address
|
||||||
|
+returned. If it does not match the address passed, then this flag is
|
||||||
|
+not supported.
|
||||||
|
+
|
||||||
|
+@item MAP_GROWSDOWN
|
||||||
|
+This flag is used to make stacks, and is typically only needed inside
|
||||||
|
+the program loader to set up the main stack for the running process.
|
||||||
|
+The mapping is created according to the other flags, except an
|
||||||
|
+additional page just prior to the mapping is marked as a ``guard
|
||||||
|
+page''. If a write is attempted inside this guard page, that page is
|
||||||
|
+mapped, the mapping is extended, and a new guard page is created.
|
||||||
|
+Thus, the mapping continues to grow towards lower addresses until it
|
||||||
|
+encounters some other mapping.
|
||||||
|
+
|
||||||
|
+Note that accessing memory beyond the guard page will not trigger this
|
||||||
|
+feature. In gcc, use @code{-fstack-clash-protection} to ensure the
|
||||||
|
+guard page is always touched.
|
||||||
|
+
|
||||||
|
+@item MAP_LOCKED
|
||||||
|
+A hint that requests that mapped pages are locked in memory (i.e. not
|
||||||
|
+paged out). Note that this is a request and not a requirement; use
|
||||||
|
+@code{mlock} if locking is required.
|
||||||
|
+
|
||||||
|
+@item MAP_POPULATE
|
||||||
|
+@itemx MAP_NONBLOCK
|
||||||
|
+@code{MAP_POPULATE} is a hint that requests that the kernel read-ahead
|
||||||
|
+a file-backed mapping, causing pages to be mapped before they're
|
||||||
|
+needed. @code{MAP_NONBLOCK} is a hint that requests that the kernel
|
||||||
|
+@emph{not} attempt such except for pages are already in memory. Note
|
||||||
|
+that neither of these hints affects future paging activity, use
|
||||||
|
+@code{mlock} if such needs to be controlled.
|
||||||
|
+
|
||||||
|
+@item MAP_NORESERVE
|
||||||
|
+Asks the kernel to not reserve physical backing (i.e. space in a swap
|
||||||
|
+device) for a mapping. This would be useful for, for example, a very
|
||||||
|
+large but sparsely used mapping which need not be limited in total
|
||||||
|
+length by available RAM, but with very few mapped pages. Note that
|
||||||
|
+writes to such a mapping may cause a @code{SIGSEGV} if the system is
|
||||||
|
+unable to map a page due to lack of resources.
|
||||||
|
+
|
||||||
|
+On Linux, this flag's behavior may be overwridden by
|
||||||
|
+@file{/proc/sys/vm/overcommit_memory} as documented in the proc(5) man
|
||||||
|
+page.
|
||||||
|
+
|
||||||
|
+@item MAP_STACK
|
||||||
|
+Ensures that the resulting mapping is suitable for use as a program
|
||||||
|
+stack. For example, the use of huge pages might be precluded.
|
||||||
|
+
|
||||||
|
+@item MAP_SYNC
|
||||||
|
+This is a special flag for DAX devices, which tells the kernel to
|
||||||
|
+write dirty metadata out whenever dirty data is written out. Unlike
|
||||||
|
+most other flags, this one will fail unless @code{MAP_SHARED_VALIDATE}
|
||||||
|
+is also given.
|
||||||
|
|
||||||
|
@end vtable
|
||||||
|
|
||||||
|
@@ -1655,6 +1733,24 @@ Possible errors include:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
+@item EACCES
|
||||||
|
+
|
||||||
|
+@var{filedes} was not open for the type of access specified in @var{protect}.
|
||||||
|
+
|
||||||
|
+@item EAGAIN
|
||||||
|
+
|
||||||
|
+The system has temporarily run out of resources.
|
||||||
|
+
|
||||||
|
+@item EBADF
|
||||||
|
+
|
||||||
|
+The @var{fd} passed is invalid, and a valid file descriptor is
|
||||||
|
+required (i.e. MAP_ANONYMOUS was not specified).
|
||||||
|
+
|
||||||
|
+@item EEXIST
|
||||||
|
+
|
||||||
|
+@code{MAP_FIXED_NOREPLACE} was specified and an existing mapping was
|
||||||
|
+found overlapping the requested address range.
|
||||||
|
+
|
||||||
|
@item EINVAL
|
||||||
|
|
||||||
|
Either @var{address} was unusable (because it is not a multiple of the
|
||||||
|
@@ -1663,23 +1759,37 @@ applicable page size), or inconsistent @var{flags} were given.
|
||||||
|
If @code{MAP_HUGETLB} was specified, the file or system does not support
|
||||||
|
large page sizes.
|
||||||
|
|
||||||
|
-@item EACCES
|
||||||
|
+@item ENODEV
|
||||||
|
|
||||||
|
-@var{filedes} was not open for the type of access specified in @var{protect}.
|
||||||
|
+This file is of a type that doesn't support mapping, the process has
|
||||||
|
+exceeded its data space limit, or the map request would exceed the
|
||||||
|
+process's virtual address space.
|
||||||
|
|
||||||
|
@item ENOMEM
|
||||||
|
|
||||||
|
-Either there is not enough memory for the operation, or the process is
|
||||||
|
-out of address space.
|
||||||
|
-
|
||||||
|
-@item ENODEV
|
||||||
|
-
|
||||||
|
-This file is of a type that doesn't support mapping.
|
||||||
|
+There is not enough memory for the operation, the process is out of
|
||||||
|
+address space, or there are too many mappings. On Linux, the maximum
|
||||||
|
+number of mappings can be controlled via
|
||||||
|
+@file{/proc/sys/vm/max_map_count} or, if your OS supports it, via
|
||||||
|
+the @code{vm.max_map_count} @code{sysctl} setting.
|
||||||
|
|
||||||
|
@item ENOEXEC
|
||||||
|
|
||||||
|
The file is on a filesystem that doesn't support mapping.
|
||||||
|
|
||||||
|
+@item EPERM
|
||||||
|
+
|
||||||
|
+@code{PROT_EXEC} was requested but the file is on a filesystem that
|
||||||
|
+was mounted with execution denied, a file seal prevented the mapping,
|
||||||
|
+or the caller set MAP_HUDETLB but does not have the required
|
||||||
|
+priviledges.
|
||||||
|
+
|
||||||
|
+@item EOVERFLOW
|
||||||
|
+
|
||||||
|
+Either the offset into the file plus the length of the mapping causes
|
||||||
|
+internal page counts to overflow, or the offset requested exceeds the
|
||||||
|
+length of the file.
|
||||||
|
+
|
||||||
|
@c On Linux, EAGAIN will appear if the file has a conflicting mandatory lock.
|
||||||
|
@c However mandatory locks are not discussed in this manual.
|
||||||
|
@c
|
@ -0,0 +1,83 @@
|
|||||||
|
commit c00b984fcd53f679ca2dafcd1aee2c89836e6e73
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue Aug 29 08:28:31 2023 +0200
|
||||||
|
|
||||||
|
nscd: Skip unusable entries in first pass in prune_cache (bug 30800)
|
||||||
|
|
||||||
|
Previously, if an entry was marked unusable for any reason, but had
|
||||||
|
not timed out yet, the assert would trigger.
|
||||||
|
|
||||||
|
One way to get into such state is if a data change is detected during
|
||||||
|
re-validation of an entry. This causes the entry to be marked as not
|
||||||
|
usable. If exits nscd soon after that, then the clock jumps
|
||||||
|
backwards, and nscd restarted, the cache re-validation run after
|
||||||
|
startup triggers the removed assert.
|
||||||
|
|
||||||
|
The change is more complicated than just the removal of the assert
|
||||||
|
because entries marked as not usable should be garbage-collected in
|
||||||
|
the second pass. To make this happen, it is necessary to update some
|
||||||
|
book-keeping data.
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/nscd/cache.c b/nscd/cache.c
|
||||||
|
index 78b2269788699e6f..ac5902ae10b791bb 100644
|
||||||
|
--- a/nscd/cache.c
|
||||||
|
+++ b/nscd/cache.c
|
||||||
|
@@ -371,8 +371,11 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||||
|
serv2str[runp->type], str, dh->timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Check whether the entry timed out. */
|
||||||
|
- if (dh->timeout < now)
|
||||||
|
+ /* Check whether the entry timed out. Timed out entries
|
||||||
|
+ will be revalidated. For unusable records, it is still
|
||||||
|
+ necessary to record that the bucket needs to be scanned
|
||||||
|
+ again below. */
|
||||||
|
+ if (dh->timeout < now || !dh->usable)
|
||||||
|
{
|
||||||
|
/* This hash bucket could contain entries which need to
|
||||||
|
be looked at. */
|
||||||
|
@@ -384,7 +387,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||||
|
/* We only have to look at the data of the first entries
|
||||||
|
since the count information is kept in the data part
|
||||||
|
which is shared. */
|
||||||
|
- if (runp->first)
|
||||||
|
+ if (runp->first && dh->usable)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* At this point there are two choices: we reload the
|
||||||
|
@@ -400,9 +403,6 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||||
|
{
|
||||||
|
/* Remove the value. */
|
||||||
|
dh->usable = false;
|
||||||
|
-
|
||||||
|
- /* We definitely have some garbage entries now. */
|
||||||
|
- any = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@@ -414,18 +414,15 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||||
|
|
||||||
|
time_t timeout = readdfcts[runp->type] (table, runp, dh);
|
||||||
|
next_timeout = MIN (next_timeout, timeout);
|
||||||
|
-
|
||||||
|
- /* If the entry has been replaced, we might need
|
||||||
|
- cleanup. */
|
||||||
|
- any |= !dh->usable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* If the entry has been replaced, we might need cleanup. */
|
||||||
|
+ any |= !dh->usable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- {
|
||||||
|
- assert (dh->usable);
|
||||||
|
- next_timeout = MIN (next_timeout, dh->timeout);
|
||||||
|
- }
|
||||||
|
+ /* Entry has not timed out and is usable. */
|
||||||
|
+ next_timeout = MIN (next_timeout, dh->timeout);
|
||||||
|
|
||||||
|
run = runp->next;
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
commit fe06fb313bddf7e4530056897d4a706606e49377
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Thu Aug 1 23:31:23 2024 +0200
|
||||||
|
|
||||||
|
elf: Clarify and invert second argument of _dl_allocate_tls_init
|
||||||
|
|
||||||
|
Also remove an outdated comment: _dl_allocate_tls_init is
|
||||||
|
called as part of pthread_create.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff -Nrup a/elf/dl-tls.c b/elf/dl-tls.c
|
||||||
|
--- a/elf/dl-tls.c 2024-08-27 22:51:44.720953314 -0400
|
||||||
|
+++ b/elf/dl-tls.c 2024-08-27 22:51:07.686759191 -0400
|
||||||
|
@@ -558,9 +558,14 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_m
|
||||||
|
/* 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. */
|
||||||
|
+ is taken when manipulating global TLS-related data in the loader.
|
||||||
|
+
|
||||||
|
+ If MAIN_THREAD, this is the first call during process
|
||||||
|
+ initialization. In this case, TLS initialization for secondary
|
||||||
|
+ (audit) namespaces is skipped because that has already been handled
|
||||||
|
+ by dlopen. */
|
||||||
|
void *
|
||||||
|
-_dl_allocate_tls_init (void *result, bool init_tls)
|
||||||
|
+_dl_allocate_tls_init (void *result, bool main_thread)
|
||||||
|
{
|
||||||
|
if (result == NULL)
|
||||||
|
/* The memory allocation failed. */
|
||||||
|
@@ -639,7 +644,7 @@ _dl_allocate_tls_init (void *result, boo
|
||||||
|
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)
|
||||||
|
+ if (map->l_ns != LM_ID_BASE && main_thread)
|
||||||
|
continue;
|
||||||
|
memset (__mempcpy (dest, map->l_tls_initimage,
|
||||||
|
map->l_tls_initimage_size), '\0',
|
||||||
|
@@ -667,7 +672,7 @@ _dl_allocate_tls (void *mem)
|
||||||
|
{
|
||||||
|
return _dl_allocate_tls_init (mem == NULL
|
||||||
|
? _dl_allocate_tls_storage ()
|
||||||
|
- : allocate_dtv (mem), true);
|
||||||
|
+ : allocate_dtv (mem), false);
|
||||||
|
}
|
||||||
|
rtld_hidden_def (_dl_allocate_tls)
|
||||||
|
|
||||||
|
diff -Nrup a/elf/rtld.c b/elf/rtld.c
|
||||||
|
--- a/elf/rtld.c 2024-08-27 22:51:44.720953314 -0400
|
||||||
|
+++ b/elf/rtld.c 2024-08-27 22:54:51.136930475 -0400
|
||||||
|
@@ -2485,7 +2485,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, false);
|
||||||
|
+ _dl_allocate_tls_init (tcbp, true);
|
||||||
|
|
||||||
|
/* And finally install it for the main thread. */
|
||||||
|
if (! tls_init_tp_called)
|
||||||
|
diff -Nrup a/nptl/allocatestack.c b/nptl/allocatestack.c
|
||||||
|
--- a/nptl/allocatestack.c 2024-08-27 22:51:43.922949131 -0400
|
||||||
|
+++ b/nptl/allocatestack.c 2024-08-27 22:51:07.687759197 -0400
|
||||||
|
@@ -137,7 +137,7 @@ get_cached_stack (size_t *sizep, void **
|
||||||
|
memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
|
||||||
|
|
||||||
|
/* Re-initialize the TLS. */
|
||||||
|
- _dl_allocate_tls_init (TLS_TPADJ (result), true);
|
||||||
|
+ _dl_allocate_tls_init (TLS_TPADJ (result), false);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
diff -Nrup a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h 2024-08-27 22:51:44.720953314 -0400
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h 2024-08-27 22:56:44.425524320 -0400
|
||||||
|
@@ -1258,10 +1258,8 @@ extern void _dl_get_tls_static_info (siz
|
||||||
|
|
||||||
|
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 *, bool);
|
||||||
|
+extern void *_dl_allocate_tls_init (void *result, bool main_thread);
|
||||||
|
rtld_hidden_proto (_dl_allocate_tls_init)
|
||||||
|
|
||||||
|
/* Deallocate memory allocated with _dl_allocate_tls. */
|
@ -0,0 +1,520 @@
|
|||||||
|
commit 5097cd344fd243fb8deb6dec96e8073753f962f9
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Thu Aug 1 23:31:30 2024 +0200
|
||||||
|
|
||||||
|
elf: Avoid re-initializing already allocated TLS in dlopen (bug 31717)
|
||||||
|
|
||||||
|
The old code used l_init_called as an indicator for whether TLS
|
||||||
|
initialization was complete. However, it is possible that
|
||||||
|
TLS for an object is initialized, written to, and then dlopen
|
||||||
|
for this object is called again, and l_init_called is not true at
|
||||||
|
this point. Previously, this resulted in TLS being initialized
|
||||||
|
twice, discarding any interim writes (technically introducing a
|
||||||
|
use-after-free bug even).
|
||||||
|
|
||||||
|
This commit introduces an explicit per-object flag, l_tls_in_slotinfo.
|
||||||
|
It indicates whether _dl_add_to_slotinfo has been called for this
|
||||||
|
object. This flag is used to avoid double-initialization of TLS.
|
||||||
|
In update_tls_slotinfo, the first_static_tls micro-optimization
|
||||||
|
is removed because preserving the initalization flag for subsequent
|
||||||
|
use by the second loop for static TLS is a bit complicated, and
|
||||||
|
another per-object flag does not seem to be worth it. Furthermore,
|
||||||
|
the l_init_called flag is dropped from the second loop (for static
|
||||||
|
TLS initialization) because l_need_tls_init on its own prevents
|
||||||
|
double-initialization.
|
||||||
|
|
||||||
|
The remaining l_init_called usage in resize_scopes and update_scopes
|
||||||
|
is just an optimization due to the use of scope_has_map, so it is
|
||||||
|
not changed in this commit.
|
||||||
|
|
||||||
|
The isupper check ensures that libc.so.6 is TLS is not reverted.
|
||||||
|
Such a revert happens if l_need_tls_init is not cleared in
|
||||||
|
_dl_allocate_tls_init for the main_thread case, now that
|
||||||
|
l_init_called is not checked anymore in update_tls_slotinfo
|
||||||
|
in elf/dl-open.c.
|
||||||
|
|
||||||
|
Reported-by: Jonathon Anderson <janderson@rice.edu>
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff -Nrup a/elf/Makefile b/elf/Makefile
|
||||||
|
--- a/elf/Makefile 2024-08-27 23:25:59.327755050 -0400
|
||||||
|
+++ b/elf/Makefile 2024-08-27 23:16:50.456864065 -0400
|
||||||
|
@@ -399,6 +399,10 @@ tests += \
|
||||||
|
tst-dlmopen-dlerror \
|
||||||
|
tst-dlmopen-gethostbyname \
|
||||||
|
tst-dlmopen-twice \
|
||||||
|
+ tst-dlopen-tlsreinit1 \
|
||||||
|
+ tst-dlopen-tlsreinit2 \
|
||||||
|
+ tst-dlopen-tlsreinit3 \
|
||||||
|
+ tst-dlopen-tlsreinit4 \
|
||||||
|
tst-dlopenfail \
|
||||||
|
tst-dlopenfail-2 \
|
||||||
|
tst-dlopenrpath \
|
||||||
|
@@ -753,6 +757,9 @@ modules-names = \
|
||||||
|
tst-dlmopen-gethostbyname-mod \
|
||||||
|
tst-dlmopen-twice-mod1 \
|
||||||
|
tst-dlmopen-twice-mod2 \
|
||||||
|
+ tst-dlopen-tlsreinitmod1 \
|
||||||
|
+ tst-dlopen-tlsreinitmod2 \
|
||||||
|
+ tst-dlopen-tlsreinitmod3 \
|
||||||
|
tst-dlopenfaillinkmod \
|
||||||
|
tst-dlopenfailmod1 \
|
||||||
|
tst-dlopenfailmod2 \
|
||||||
|
@@ -2751,3 +2758,26 @@ $(objpfx)tst-recursive-tls.out: \
|
||||||
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
|
||||||
|
$(objpfx)tst-recursive-tlsmod%.os: tst-recursive-tlsmodN.c
|
||||||
|
$(compile-command.c) -DVAR=thread_$* -DFUNC=get_threadvar_$*
|
||||||
|
+
|
||||||
|
+# Order matters here. The test needs the constructor for
|
||||||
|
+# tst-dlopen-tlsreinitmod2.so to be called first.
|
||||||
|
+LDFLAGS-tst-dlopen-tlsreinitmod1.so = -Wl,--no-as-needed
|
||||||
|
+$(objpfx)tst-dlopen-tlsreinitmod1.so: \
|
||||||
|
+ $(objpfx)tst-dlopen-tlsreinitmod3.so $(objpfx)tst-dlopen-tlsreinitmod2.so
|
||||||
|
+LDFLAGS-tst-dlopen-tlsreinit2 = -Wl,--no-as-needed
|
||||||
|
+$(objpfx)tst-dlopen-tlsreinit2: \
|
||||||
|
+ $(objpfx)tst-dlopen-tlsreinitmod3.so $(objpfx)tst-dlopen-tlsreinitmod2.so
|
||||||
|
+LDFLAGS-tst-dlopen-tlsreinit4 = -Wl,--no-as-needed
|
||||||
|
+$(objpfx)tst-dlopen-tlsreinit4: \
|
||||||
|
+ $(objpfx)tst-dlopen-tlsreinitmod3.so $(objpfx)tst-dlopen-tlsreinitmod2.so
|
||||||
|
+# tst-dlopen-tlsreinitmod2.so is underlinked and refers to
|
||||||
|
+# tst-dlopen-tlsreinitmod3.so. The dependency is provided via
|
||||||
|
+# $(objpfx)tst-dlopen-tlsreinitmod1.so.
|
||||||
|
+tst-dlopen-tlsreinitmod2.so-no-z-defs = yes
|
||||||
|
+$(objpfx)tst-dlopen-tlsreinit.out: $(objpfx)tst-dlopen-tlsreinitmod1.so \
|
||||||
|
+ $(objpfx)tst-dlopen-tlsreinitmod2.so $(objpfx)tst-dlopen-tlsreinitmod3.so
|
||||||
|
+# Reuse an audit module which provides ample debug logging.
|
||||||
|
+$(objpfx)tst-dlopen-tlsreinit3.out: $(objpfx)tst-auditmod1.so
|
||||||
|
+tst-dlopen-tlsreinit3-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
|
||||||
|
+$(objpfx)tst-dlopen-tlsreinit4.out: $(objpfx)tst-auditmod1.so
|
||||||
|
+tst-dlopen-tlsreinit4-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
|
||||||
|
diff -Nrup a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
--- a/elf/dl-open.c 2024-08-27 23:25:59.237754576 -0400
|
||||||
|
+++ b/elf/dl-open.c 2024-08-27 23:10:52.497978645 -0400
|
||||||
|
@@ -362,17 +362,8 @@ resize_tls_slotinfo (struct link_map *ne
|
||||||
|
{
|
||||||
|
bool any_tls = false;
|
||||||
|
for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||||
|
- {
|
||||||
|
- struct link_map *imap = new->l_searchlist.r_list[i];
|
||||||
|
-
|
||||||
|
- /* Only add TLS memory if this object is loaded now and
|
||||||
|
- therefore is not yet initialized. */
|
||||||
|
- if (! imap->l_init_called && imap->l_tls_blocksize > 0)
|
||||||
|
- {
|
||||||
|
- _dl_add_to_slotinfo (imap, false);
|
||||||
|
- any_tls = true;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ if (_dl_add_to_slotinfo (new->l_searchlist.r_list[i], false))
|
||||||
|
+ any_tls = true;
|
||||||
|
return any_tls;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -382,22 +373,8 @@ resize_tls_slotinfo (struct link_map *ne
|
||||||
|
static void
|
||||||
|
update_tls_slotinfo (struct link_map *new)
|
||||||
|
{
|
||||||
|
- unsigned int first_static_tls = new->l_searchlist.r_nlist;
|
||||||
|
for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||||
|
- {
|
||||||
|
- struct link_map *imap = new->l_searchlist.r_list[i];
|
||||||
|
-
|
||||||
|
- /* Only add TLS memory if this object is loaded now and
|
||||||
|
- therefore is not yet initialized. */
|
||||||
|
- if (! imap->l_init_called && imap->l_tls_blocksize > 0)
|
||||||
|
- {
|
||||||
|
- _dl_add_to_slotinfo (imap, true);
|
||||||
|
-
|
||||||
|
- if (imap->l_need_tls_init
|
||||||
|
- && first_static_tls == new->l_searchlist.r_nlist)
|
||||||
|
- first_static_tls = i;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_add_to_slotinfo (new->l_searchlist.r_list[i], true);
|
||||||
|
|
||||||
|
size_t newgen = GL(dl_tls_generation) + 1;
|
||||||
|
if (__glibc_unlikely (newgen == 0))
|
||||||
|
@@ -409,13 +386,11 @@ TLS generation counter wrapped! Please
|
||||||
|
/* We need a second pass for static tls data, because
|
||||||
|
_dl_update_slotinfo must not be run while calls to
|
||||||
|
_dl_add_to_slotinfo are still pending. */
|
||||||
|
- for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i)
|
||||||
|
+ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||||
|
{
|
||||||
|
struct link_map *imap = new->l_searchlist.r_list[i];
|
||||||
|
|
||||||
|
- if (imap->l_need_tls_init
|
||||||
|
- && ! imap->l_init_called
|
||||||
|
- && imap->l_tls_blocksize > 0)
|
||||||
|
+ if (imap->l_need_tls_init && imap->l_tls_blocksize > 0)
|
||||||
|
{
|
||||||
|
/* For static TLS we have to allocate the memory here and
|
||||||
|
now, but we can delay updating the DTV. */
|
||||||
|
diff -Nrup a/elf/dl-tls.c b/elf/dl-tls.c
|
||||||
|
--- a/elf/dl-tls.c 2024-08-27 23:25:59.358755213 -0400
|
||||||
|
+++ b/elf/dl-tls.c 2024-08-27 23:21:04.960204566 -0400
|
||||||
|
@@ -638,17 +638,21 @@ _dl_allocate_tls_init (void *result, boo
|
||||||
|
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. 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. */
|
||||||
|
+ /* 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, which uses the dlopen code and already
|
||||||
|
+ clears l_need_tls_init. Calls with !main_thread from
|
||||||
|
+ pthread_create need to initialze TLS for the current
|
||||||
|
+ thread regardless of namespace. */
|
||||||
|
if (map->l_ns != LM_ID_BASE && main_thread)
|
||||||
|
continue;
|
||||||
|
memset (__mempcpy (dest, map->l_tls_initimage,
|
||||||
|
map->l_tls_initimage_size), '\0',
|
||||||
|
map->l_tls_blocksize - map->l_tls_initimage_size);
|
||||||
|
+ if (main_thread)
|
||||||
|
+ map->l_need_tls_init = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
total += cnt;
|
||||||
|
@@ -1105,9 +1109,32 @@ _dl_tls_initial_modid_limit_setup (void)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-void
|
||||||
|
+/* Add module to slot information data. If DO_ADD is false, only the
|
||||||
|
+ required memory is allocated. Must be called with
|
||||||
|
+ GL (dl_load_tls_lock) acquired. If the function has already been
|
||||||
|
+ called for the link map L with !DO_ADD, then this function will not
|
||||||
|
+ raise an exception, otherwise it is possible that it encounters a
|
||||||
|
+ memory allocation failure.
|
||||||
|
+
|
||||||
|
+ Return false if L has already been added to the slotinfo data, or
|
||||||
|
+ if L has no TLS data. If the returned value is true, L has been
|
||||||
|
+ added with this call (DO_ADD), or has been added in a previous call
|
||||||
|
+ (!DO_ADD).
|
||||||
|
+
|
||||||
|
+ The expected usage is as follows: Call _dl_add_to_slotinfo for
|
||||||
|
+ several link maps with DO_ADD set to false, and record if any calls
|
||||||
|
+ result in a true result. If there was a true result, call
|
||||||
|
+ _dl_add_to_slotinfo again, this time with DO_ADD set to true. (For
|
||||||
|
+ simplicity, it's possible to call the function for link maps where
|
||||||
|
+ the previous result was false.) The return value from the second
|
||||||
|
+ round of calls can be ignored. If there was true result initially,
|
||||||
|
+ call _dl_update_slotinfo to update the TLS generation counter. */
|
||||||
|
+bool
|
||||||
|
_dl_add_to_slotinfo (struct link_map *l, bool do_add)
|
||||||
|
{
|
||||||
|
+ if (l->l_tls_blocksize == 0 || l->l_tls_in_slotinfo)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
/* Now that we know the object is loaded successfully add
|
||||||
|
modules containing TLS data to the dtv info table. We
|
||||||
|
might have to increase its size. */
|
||||||
|
@@ -1163,7 +1190,10 @@ cannot create TLS data structures"));
|
||||||
|
atomic_store_relaxed (&listp->slotinfo[idx].map, l);
|
||||||
|
atomic_store_relaxed (&listp->slotinfo[idx].gen,
|
||||||
|
GL(dl_tls_generation) + 1);
|
||||||
|
+ l->l_tls_in_slotinfo = true;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if THREAD_GSCOPE_IN_TCB
|
||||||
|
diff -Nrup a/elf/tst-dlopen-tlsreinit1.c b/elf/tst-dlopen-tlsreinit1.c
|
||||||
|
--- a/elf/tst-dlopen-tlsreinit1.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/elf/tst-dlopen-tlsreinit1.c 2024-08-27 23:10:52.497978645 -0400
|
||||||
|
@@ -0,0 +1,40 @@
|
||||||
|
+/* Test that dlopen preserves already accessed TLS (bug 31717).
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+#include <ctype.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ void *handle = xdlopen ("tst-dlopen-tlsreinitmod1.so", RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ bool *tlsreinitmod3_tested = xdlsym (handle, "tlsreinitmod3_tested");
|
||||||
|
+ TEST_VERIFY (*tlsreinitmod3_tested);
|
||||||
|
+
|
||||||
|
+ xdlclose (handle);
|
||||||
|
+
|
||||||
|
+ /* This crashes if the libc.so.6 TLS image has been reverted. */
|
||||||
|
+ TEST_VERIFY (!isupper ('@'));
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff -Nrup a/elf/tst-dlopen-tlsreinit2.c b/elf/tst-dlopen-tlsreinit2.c
|
||||||
|
--- a/elf/tst-dlopen-tlsreinit2.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/elf/tst-dlopen-tlsreinit2.c 2024-08-27 23:10:52.497978645 -0400
|
||||||
|
@@ -0,0 +1,39 @@
|
||||||
|
+/* Test that dlopen preserves already accessed TLS (bug 31717).
|
||||||
|
+ Variant with initially-linked modules.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <ctype.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ /* Defined in tst-dlopen-tlsreinitmod3.so. */
|
||||||
|
+ extern bool tlsreinitmod3_tested;
|
||||||
|
+ TEST_VERIFY (tlsreinitmod3_tested);
|
||||||
|
+
|
||||||
|
+ /* This crashes if the libc.so.6 TLS image has been reverted. */
|
||||||
|
+ TEST_VERIFY (!isupper ('@'));
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff -Nrup a/elf/tst-dlopen-tlsreinit3.c b/elf/tst-dlopen-tlsreinit3.c
|
||||||
|
--- a/elf/tst-dlopen-tlsreinit3.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/elf/tst-dlopen-tlsreinit3.c 2024-08-27 23:10:52.497978645 -0400
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+/* Same code, but run with LD_AUDIT=tst-auditmod1.so. */
|
||||||
|
+#include "tst-dlopen-tlsreinit1.c"
|
||||||
|
diff -Nrup a/elf/tst-dlopen-tlsreinit4.c b/elf/tst-dlopen-tlsreinit4.c
|
||||||
|
--- a/elf/tst-dlopen-tlsreinit4.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/elf/tst-dlopen-tlsreinit4.c 2024-08-27 23:10:52.497978645 -0400
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+/* Same code, but run with LD_AUDIT=tst-auditmod1.so. */
|
||||||
|
+#include "tst-dlopen-tlsreinit2.c"
|
||||||
|
diff -Nrup a/elf/tst-dlopen-tlsreinitmod1.c b/elf/tst-dlopen-tlsreinitmod1.c
|
||||||
|
--- a/elf/tst-dlopen-tlsreinitmod1.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/elf/tst-dlopen-tlsreinitmod1.c 2024-08-27 23:10:52.497978645 -0400
|
||||||
|
@@ -0,0 +1,20 @@
|
||||||
|
+/* Test that dlopen preserves already accessed TLS (bug 31717), module 1.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+/* This module triggers loading of tst-dlopen-tlsreinitmod2.so and
|
||||||
|
+ tst-dlopen-tlsreinitmod3.so. */
|
||||||
|
diff -Nrup a/elf/tst-dlopen-tlsreinitmod2.c b/elf/tst-dlopen-tlsreinitmod2.c
|
||||||
|
--- a/elf/tst-dlopen-tlsreinitmod2.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/elf/tst-dlopen-tlsreinitmod2.c 2024-08-27 23:10:52.497978645 -0400
|
||||||
|
@@ -0,0 +1,30 @@
|
||||||
|
+/* Test that dlopen preserves already accessed TLS (bug 31717), module 2.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+
|
||||||
|
+/* Defined in tst-dlopen-tlsreinitmod3.so. This an underlinked symbol
|
||||||
|
+ dependency. */
|
||||||
|
+extern void call_tlsreinitmod3 (void);
|
||||||
|
+
|
||||||
|
+static void __attribute__ ((constructor))
|
||||||
|
+tlsreinitmod2_init (void)
|
||||||
|
+{
|
||||||
|
+ puts ("info: constructor of tst-dlopen-tlsreinitmod2.so invoked");
|
||||||
|
+ call_tlsreinitmod3 ();
|
||||||
|
+}
|
||||||
|
diff -Nrup a/elf/tst-dlopen-tlsreinitmod3.c b/elf/tst-dlopen-tlsreinitmod3.c
|
||||||
|
--- a/elf/tst-dlopen-tlsreinitmod3.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/elf/tst-dlopen-tlsreinitmod3.c 2024-08-27 23:10:52.498978651 -0400
|
||||||
|
@@ -0,0 +1,102 @@
|
||||||
|
+/* Test that dlopen preserves already accessed TLS (bug 31717), module 3.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+/* Used to verify from the main program that the test ran. */
|
||||||
|
+bool tlsreinitmod3_tested;
|
||||||
|
+
|
||||||
|
+/* This TLS variable must not revert back to the initial state after
|
||||||
|
+ dlopen. */
|
||||||
|
+static __thread int tlsreinitmod3_state = 1;
|
||||||
|
+
|
||||||
|
+/* Set from the ELF constructor during dlopen. */
|
||||||
|
+static bool tlsreinitmod3_constructed;
|
||||||
|
+
|
||||||
|
+/* Second half of test, behind a compiler barrier. The compiler
|
||||||
|
+ barrier is necessary to prevent carrying over TLS address
|
||||||
|
+ information from call_tlsreinitmod3 to call_tlsreinitmod3_tail. */
|
||||||
|
+void call_tlsreinitmod3_tail (void *self) __attribute__ ((weak));
|
||||||
|
+
|
||||||
|
+/* Called from tst-dlopen-tlsreinitmod2.so. */
|
||||||
|
+void
|
||||||
|
+call_tlsreinitmod3 (void)
|
||||||
|
+{
|
||||||
|
+ printf ("info: call_tlsreinitmod3 invoked (state=%d)\n",
|
||||||
|
+ tlsreinitmod3_state);
|
||||||
|
+
|
||||||
|
+ if (tlsreinitmod3_constructed)
|
||||||
|
+ {
|
||||||
|
+ puts ("error: call_tlsreinitmod3 called after ELF constructor");
|
||||||
|
+ fflush (stdout);
|
||||||
|
+ /* Cannot rely on test harness due to dynamic linking. */
|
||||||
|
+ _exit (1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ tlsreinitmod3_state = 2;
|
||||||
|
+
|
||||||
|
+ /* Self-dlopen. This will run the ELF constructor. */
|
||||||
|
+ void *self = dlopen ("tst-dlopen-tlsreinitmod3.so", RTLD_NOW);
|
||||||
|
+ if (self == NULL)
|
||||||
|
+ {
|
||||||
|
+ printf ("error: dlopen: %s\n", dlerror ());
|
||||||
|
+ fflush (stdout);
|
||||||
|
+ /* Cannot rely on test harness due to dynamic linking. */
|
||||||
|
+ _exit (1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ call_tlsreinitmod3_tail (self);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+call_tlsreinitmod3_tail (void *self)
|
||||||
|
+{
|
||||||
|
+ printf ("info: dlopen returned in tlsreinitmod3 (state=%d)\n",
|
||||||
|
+ tlsreinitmod3_state);
|
||||||
|
+
|
||||||
|
+ if (!tlsreinitmod3_constructed)
|
||||||
|
+ {
|
||||||
|
+ puts ("error: dlopen did not call tlsreinitmod3 ELF constructor");
|
||||||
|
+ fflush (stdout);
|
||||||
|
+ /* Cannot rely on test harness due to dynamic linking. */
|
||||||
|
+ _exit (1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (tlsreinitmod3_state != 2)
|
||||||
|
+ {
|
||||||
|
+ puts ("error: TLS state reverted in tlsreinitmod3");
|
||||||
|
+ fflush (stdout);
|
||||||
|
+ /* Cannot rely on test harness due to dynamic linking. */
|
||||||
|
+ _exit (1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dlclose (self);
|
||||||
|
+
|
||||||
|
+ /* Signal test completion to the main program. */
|
||||||
|
+ tlsreinitmod3_tested = true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __attribute__ ((constructor))
|
||||||
|
+tlsreinitmod3_init (void)
|
||||||
|
+{
|
||||||
|
+ puts ("info: constructor of tst-dlopen-tlsreinitmod3.so invoked");
|
||||||
|
+ tlsreinitmod3_constructed = true;
|
||||||
|
+}
|
||||||
|
diff -Nrup a/include/link.h b/include/link.h
|
||||||
|
--- a/include/link.h 2024-08-27 23:25:58.503750710 -0400
|
||||||
|
+++ b/include/link.h 2024-08-27 23:23:42.209032820 -0400
|
||||||
|
@@ -211,6 +211,7 @@ struct link_map
|
||||||
|
freed, ie. not allocated with
|
||||||
|
the dummy malloc in ld.so. */
|
||||||
|
unsigned int l_ld_readonly:1; /* Nonzero if dynamic section is readonly. */
|
||||||
|
+ unsigned int l_tls_in_slotinfo:1; /* TLS slotinfo updated in dlopen. */
|
||||||
|
|
||||||
|
/* NODELETE status of the map. Only valid for maps of type
|
||||||
|
lt_loaded. Lazy binding sets l_nodelete_active directly,
|
||||||
|
diff -Nrup a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h 2024-08-27 23:25:59.359755218 -0400
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h 2024-08-27 23:10:52.498978651 -0400
|
||||||
|
@@ -1291,13 +1291,7 @@ extern void *_dl_open (const char *name,
|
||||||
|
extern int _dl_scope_free (void *) attribute_hidden;
|
||||||
|
|
||||||
|
|
||||||
|
-/* Add module to slot information data. If DO_ADD is false, only the
|
||||||
|
- required memory is allocated. Must be called with GL
|
||||||
|
- (dl_load_tls_lock) acquired. If the function has already been called
|
||||||
|
- for the link map L with !do_add, then this function will not raise
|
||||||
|
- an exception, otherwise it is possible that it encounters a memory
|
||||||
|
- allocation failure. */
|
||||||
|
-extern void _dl_add_to_slotinfo (struct link_map *l, bool do_add)
|
||||||
|
+extern bool _dl_add_to_slotinfo (struct link_map *l, bool do_add)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
/* Update slot information data for at least the generation of the
|
@ -0,0 +1,16 @@
|
|||||||
|
Author: Patsy Griffin <patsy@redhat.com>
|
||||||
|
|
||||||
|
Fix a typo in naming tst-dlopen-tlsreinit1.out
|
||||||
|
|
||||||
|
diff -Nrup a/elf/Makefile b/elf/Makefile
|
||||||
|
--- a/elf/Makefile 2024-08-16 13:27:00.700921146 -0400
|
||||||
|
+++ b/elf/Makefile 2024-08-16 13:29:12.951628406 -0400
|
||||||
|
@@ -2802,7 +2802,7 @@ $(objpfx)tst-dlopen-tlsreinit4: \
|
||||||
|
# tst-dlopen-tlsreinitmod3.so. The dependency is provided via
|
||||||
|
# $(objpfx)tst-dlopen-tlsreinitmod1.so.
|
||||||
|
tst-dlopen-tlsreinitmod2.so-no-z-defs = yes
|
||||||
|
-$(objpfx)tst-dlopen-tlsreinit.out: $(objpfx)tst-dlopen-tlsreinitmod1.so \
|
||||||
|
+$(objpfx)tst-dlopen-tlsreinit1.out: $(objpfx)tst-dlopen-tlsreinitmod1.so \
|
||||||
|
$(objpfx)tst-dlopen-tlsreinitmod2.so $(objpfx)tst-dlopen-tlsreinitmod3.so
|
||||||
|
# Reuse an audit module which provides ample debug logging.
|
||||||
|
$(objpfx)tst-dlopen-tlsreinit3.out: $(objpfx)tst-auditmod1.so
|
@ -0,0 +1,593 @@
|
|||||||
|
commit df11c05be91fda5ef490c76fd0d4a53821750116
|
||||||
|
Author: Joseph Myers <josmyers@redhat.com>
|
||||||
|
Date: Wed Jan 17 15:38:54 2024 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.7
|
||||||
|
|
||||||
|
Linux 6.7 adds the futex_requeue, futex_wait and futex_wake syscalls,
|
||||||
|
and enables map_shadow_stack for architectures previously missing it.
|
||||||
|
Update syscall-names.list and regenerate the arch-syscall.h headers
|
||||||
|
with build-many-glibcs.py update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified for RHEL by: Patsy Griffin <patsy@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
index 746991aa2f..1713897f85 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
@@ -64,7 +64,10 @@
|
||||||
|
#define __NR_fsync 82
|
||||||
|
#define __NR_ftruncate 46
|
||||||
|
#define __NR_futex 98
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_get_mempolicy 236
|
||||||
|
#define __NR_get_robust_list 100
|
||||||
|
#define __NR_getcpu 168
|
||||||
|
@@ -126,6 +129,7 @@
|
||||||
|
#define __NR_lseek 62
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
#define __NR_madvise 233
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
#define __NR_membarrier 283
|
||||||
|
#define __NR_memfd_create 279
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
index 32efe51267..5457d2d8ae 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
@@ -80,7 +80,10 @@
|
||||||
|
#define __NR_fsync 95
|
||||||
|
#define __NR_ftruncate 130
|
||||||
|
#define __NR_futex 394
|
||||||
|
+#define __NR_futex_requeue 566
|
||||||
|
+#define __NR_futex_wait 565
|
||||||
|
#define __NR_futex_waitv 559
|
||||||
|
+#define __NR_futex_wake 564
|
||||||
|
#define __NR_futimesat 454
|
||||||
|
#define __NR_get_kernel_syms 309
|
||||||
|
#define __NR_get_mempolicy 430
|
||||||
|
@@ -156,6 +159,7 @@
|
||||||
|
#define __NR_lstat 68
|
||||||
|
#define __NR_lstat64 426
|
||||||
|
#define __NR_madvise 75
|
||||||
|
+#define __NR_map_shadow_stack 563
|
||||||
|
#define __NR_mbind 429
|
||||||
|
#define __NR_membarrier 517
|
||||||
|
#define __NR_memfd_create 512
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
index 1d2879e877..a66471c83a 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
@@ -66,8 +66,11 @@
|
||||||
|
#define __NR_fstatfs64 44
|
||||||
|
#define __NR_fsync 82
|
||||||
|
#define __NR_ftruncate64 46
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_get_mempolicy 236
|
||||||
|
#define __NR_get_robust_list 100
|
||||||
|
#define __NR_getcpu 168
|
||||||
|
@@ -130,6 +133,7 @@
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
#define __NR_madvise 233
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
#define __NR_membarrier 283
|
||||||
|
#define __NR_memfd_create 279
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
index 6711981e78..74a57f4520 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
@@ -91,8 +91,11 @@
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_ftruncate64 194
|
||||||
|
#define __NR_futex 240
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 326
|
||||||
|
#define __NR_get_mempolicy 320
|
||||||
|
#define __NR_get_robust_list 339
|
||||||
|
@@ -170,6 +173,7 @@
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 220
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 319
|
||||||
|
#define __NR_membarrier 389
|
||||||
|
#define __NR_memfd_create 385
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
index 92d9a703ea..ba7632e018 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
@@ -71,8 +71,11 @@
|
||||||
|
#define __NR_fsync 82
|
||||||
|
#define __NR_ftruncate64 46
|
||||||
|
#define __NR_futex 98
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_get_mempolicy 236
|
||||||
|
#define __NR_get_robust_list 100
|
||||||
|
#define __NR_getcpu 168
|
||||||
|
@@ -135,6 +138,7 @@
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
#define __NR_madvise 233
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
#define __NR_membarrier 283
|
||||||
|
#define __NR_memfd_create 279
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
index fbac124b70..483706de9b 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
@@ -89,8 +89,11 @@
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_ftruncate64 200
|
||||||
|
#define __NR_futex 210
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 279
|
||||||
|
#define __NR_get_mempolicy 261
|
||||||
|
#define __NR_get_robust_list 290
|
||||||
|
@@ -161,6 +164,7 @@
|
||||||
|
#define __NR_lstat 84
|
||||||
|
#define __NR_lstat64 198
|
||||||
|
#define __NR_madvise 119
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 260
|
||||||
|
#define __NR_membarrier 343
|
||||||
|
#define __NR_memfd_create 340
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
index 8961788a96..21c1308bb3 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
@@ -95,8 +95,11 @@
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_ftruncate64 194
|
||||||
|
#define __NR_futex 240
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 299
|
||||||
|
#define __NR_get_kernel_syms 130
|
||||||
|
#define __NR_get_mempolicy 275
|
||||||
|
@@ -183,6 +186,7 @@
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 219
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 274
|
||||||
|
#define __NR_membarrier 375
|
||||||
|
#define __NR_memfd_create 356
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
index 2053d5d392..6d788e3440 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
@@ -94,8 +94,11 @@
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_ftruncate64 194
|
||||||
|
#define __NR_futex 235
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 292
|
||||||
|
#define __NR_get_kernel_syms 130
|
||||||
|
#define __NR_get_mempolicy 269
|
||||||
|
@@ -177,6 +180,7 @@
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 238
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 268
|
||||||
|
#define __NR_membarrier 374
|
||||||
|
#define __NR_memfd_create 353
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
index 6865b1693c..91e1630f7b 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
@@ -95,8 +95,11 @@
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_ftruncate64 194
|
||||||
|
#define __NR_futex 240
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 299
|
||||||
|
#define __NR_get_kernel_syms 130
|
||||||
|
#define __NR_get_mempolicy 275
|
||||||
|
@@ -183,6 +186,7 @@
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 219
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 274
|
||||||
|
#define __NR_membarrier 390
|
||||||
|
#define __NR_memfd_create 386
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
index b13ace8e1c..d75af97467 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
@@ -94,8 +94,11 @@
|
||||||
|
#define __NR_ftruncate 4093
|
||||||
|
#define __NR_ftruncate64 4212
|
||||||
|
#define __NR_futex 4238
|
||||||
|
+#define __NR_futex_requeue 4456
|
||||||
|
#define __NR_futex_time64 4422
|
||||||
|
+#define __NR_futex_wait 4455
|
||||||
|
#define __NR_futex_waitv 4449
|
||||||
|
+#define __NR_futex_wake 4454
|
||||||
|
#define __NR_futimesat 4292
|
||||||
|
#define __NR_get_kernel_syms 4130
|
||||||
|
#define __NR_get_mempolicy 4269
|
||||||
|
@@ -173,6 +176,7 @@
|
||||||
|
#define __NR_lstat 4107
|
||||||
|
#define __NR_lstat64 4214
|
||||||
|
#define __NR_madvise 4218
|
||||||
|
+#define __NR_map_shadow_stack 4453
|
||||||
|
#define __NR_mbind 4268
|
||||||
|
#define __NR_membarrier 4358
|
||||||
|
#define __NR_memfd_create 4354
|
||||||
|
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 b7a7c0dfa7..05bf7d251d 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||||
|
@@ -87,8 +87,11 @@
|
||||||
|
#define __NR_fsync 6072
|
||||||
|
#define __NR_ftruncate 6075
|
||||||
|
#define __NR_futex 6194
|
||||||
|
+#define __NR_futex_requeue 6456
|
||||||
|
#define __NR_futex_time64 6422
|
||||||
|
+#define __NR_futex_wait 6455
|
||||||
|
#define __NR_futex_waitv 6449
|
||||||
|
+#define __NR_futex_wake 6454
|
||||||
|
#define __NR_futimesat 6255
|
||||||
|
#define __NR_get_kernel_syms 6170
|
||||||
|
#define __NR_get_mempolicy 6232
|
||||||
|
@@ -159,6 +162,7 @@
|
||||||
|
#define __NR_lsetxattr 6181
|
||||||
|
#define __NR_lstat 6006
|
||||||
|
#define __NR_madvise 6027
|
||||||
|
+#define __NR_map_shadow_stack 6453
|
||||||
|
#define __NR_mbind 6231
|
||||||
|
#define __NR_membarrier 6322
|
||||||
|
#define __NR_memfd_create 6318
|
||||||
|
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 e5d7f91f48..41ffaf3255 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||||
|
@@ -80,7 +80,10 @@
|
||||||
|
#define __NR_fsync 5072
|
||||||
|
#define __NR_ftruncate 5075
|
||||||
|
#define __NR_futex 5194
|
||||||
|
+#define __NR_futex_requeue 5456
|
||||||
|
+#define __NR_futex_wait 5455
|
||||||
|
#define __NR_futex_waitv 5449
|
||||||
|
+#define __NR_futex_wake 5454
|
||||||
|
#define __NR_futimesat 5251
|
||||||
|
#define __NR_get_kernel_syms 5170
|
||||||
|
#define __NR_get_mempolicy 5228
|
||||||
|
@@ -150,6 +153,7 @@
|
||||||
|
#define __NR_lsetxattr 5181
|
||||||
|
#define __NR_lstat 5006
|
||||||
|
#define __NR_madvise 5027
|
||||||
|
+#define __NR_map_shadow_stack 5453
|
||||||
|
#define __NR_mbind 5227
|
||||||
|
#define __NR_membarrier 5318
|
||||||
|
#define __NR_memfd_create 5314
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
index 89950cc33a..d94e7e9ee9 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
@@ -70,8 +70,11 @@
|
||||||
|
#define __NR_fsync 82
|
||||||
|
#define __NR_ftruncate64 46
|
||||||
|
#define __NR_futex 98
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_get_mempolicy 236
|
||||||
|
#define __NR_get_robust_list 100
|
||||||
|
#define __NR_getcpu 168
|
||||||
|
@@ -134,6 +137,7 @@
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
#define __NR_madvise 233
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
#define __NR_membarrier 283
|
||||||
|
#define __NR_memfd_create 279
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
index 64683bcb76..b5522e8889 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
@@ -93,8 +93,11 @@
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_ftruncate64 194
|
||||||
|
#define __NR_futex 221
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 290
|
||||||
|
#define __NR_get_kernel_syms 130
|
||||||
|
#define __NR_get_mempolicy 260
|
||||||
|
@@ -173,6 +176,7 @@
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 205
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 259
|
||||||
|
#define __NR_membarrier 365
|
||||||
|
#define __NR_memfd_create 360
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
index af1bbf32e8..162d782ae6 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
@@ -83,7 +83,10 @@
|
||||||
|
#define __NR_ftime 35
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_futex 221
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 290
|
||||||
|
#define __NR_get_kernel_syms 130
|
||||||
|
#define __NR_get_mempolicy 260
|
||||||
|
@@ -160,6 +163,7 @@
|
||||||
|
#define __NR_lsetxattr 210
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_madvise 205
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 259
|
||||||
|
#define __NR_membarrier 365
|
||||||
|
#define __NR_memfd_create 360
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
index 56e3088cbf..013222e5de 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
@@ -61,8 +61,11 @@
|
||||||
|
#define __NR_fstatfs64 44
|
||||||
|
#define __NR_fsync 82
|
||||||
|
#define __NR_ftruncate64 46
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_get_mempolicy 236
|
||||||
|
#define __NR_get_robust_list 100
|
||||||
|
#define __NR_getcpu 168
|
||||||
|
@@ -121,6 +124,7 @@
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
#define __NR_madvise 233
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
#define __NR_membarrier 283
|
||||||
|
#define __NR_memfd_create 279
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
index 508161b47a..d03dad8200 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
@@ -64,7 +64,10 @@
|
||||||
|
#define __NR_fsync 82
|
||||||
|
#define __NR_ftruncate 46
|
||||||
|
#define __NR_futex 98
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_get_mempolicy 236
|
||||||
|
#define __NR_get_robust_list 100
|
||||||
|
#define __NR_getcpu 168
|
||||||
|
@@ -126,6 +129,7 @@
|
||||||
|
#define __NR_lseek 62
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
#define __NR_madvise 233
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
#define __NR_membarrier 283
|
||||||
|
#define __NR_memfd_create 279
|
||||||
|
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 1498ebf42e..98e6b68b31 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
@@ -92,8 +92,11 @@
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_ftruncate64 194
|
||||||
|
#define __NR_futex 238
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 292
|
||||||
|
#define __NR_get_kernel_syms 130
|
||||||
|
#define __NR_get_mempolicy 269
|
||||||
|
@@ -177,6 +180,7 @@
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 219
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 268
|
||||||
|
#define __NR_membarrier 356
|
||||||
|
#define __NR_memfd_create 350
|
||||||
|
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 624d71b56d..951fbd7c97 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
@@ -78,7 +78,10 @@
|
||||||
|
#define __NR_fsync 118
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_futex 238
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 292
|
||||||
|
#define __NR_get_kernel_syms 130
|
||||||
|
#define __NR_get_mempolicy 269
|
||||||
|
@@ -151,6 +154,7 @@
|
||||||
|
#define __NR_lsetxattr 225
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_madvise 219
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 268
|
||||||
|
#define __NR_membarrier 356
|
||||||
|
#define __NR_memfd_create 350
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
index 37211f5f8c..6b4418bcae 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
@@ -91,8 +91,11 @@
|
||||||
|
#define __NR_ftruncate 93
|
||||||
|
#define __NR_ftruncate64 194
|
||||||
|
#define __NR_futex 240
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 299
|
||||||
|
#define __NR_get_mempolicy 275
|
||||||
|
#define __NR_get_robust_list 312
|
||||||
|
@@ -170,6 +173,7 @@
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 219
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 274
|
||||||
|
#define __NR_membarrier 378
|
||||||
|
#define __NR_memfd_create 374
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
index 8093abcc9c..4f9460b1a3 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
@@ -93,8 +93,11 @@
|
||||||
|
#define __NR_ftruncate 130
|
||||||
|
#define __NR_ftruncate64 84
|
||||||
|
#define __NR_futex 142
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
#define __NR_futex_time64 422
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 288
|
||||||
|
#define __NR_get_kernel_syms 223
|
||||||
|
#define __NR_get_mempolicy 304
|
||||||
|
@@ -175,6 +178,7 @@
|
||||||
|
#define __NR_lstat 40
|
||||||
|
#define __NR_lstat64 132
|
||||||
|
#define __NR_madvise 75
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 303
|
||||||
|
#define __NR_membarrier 351
|
||||||
|
#define __NR_memfd_create 348
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
index d25ccfb571..129ce50646 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
@@ -84,7 +84,10 @@
|
||||||
|
#define __NR_fsync 95
|
||||||
|
#define __NR_ftruncate 130
|
||||||
|
#define __NR_futex 142
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 288
|
||||||
|
#define __NR_get_kernel_syms 223
|
||||||
|
#define __NR_get_mempolicy 304
|
||||||
|
@@ -158,6 +161,7 @@
|
||||||
|
#define __NR_lstat 40
|
||||||
|
#define __NR_lstat64 132
|
||||||
|
#define __NR_madvise 75
|
||||||
|
+#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 303
|
||||||
|
#define __NR_membarrier 351
|
||||||
|
#define __NR_memfd_create 348
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index c039d5c37f..aac065e7b3 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 6.6.
|
||||||
|
-kernel 6.6
|
||||||
|
+# The list of system calls is current as of Linux 6.7.
|
||||||
|
+kernel 6.7
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -147,8 +147,11 @@ ftime
|
||||||
|
ftruncate
|
||||||
|
ftruncate64
|
||||||
|
futex
|
||||||
|
+futex_requeue
|
||||||
|
futex_time64
|
||||||
|
+futex_wait
|
||||||
|
futex_waitv
|
||||||
|
+futex_wake
|
||||||
|
futimesat
|
||||||
|
get_kernel_syms
|
||||||
|
get_mempolicy
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
index 5e4c9e901c..4fa5b942c5 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
@@ -80,7 +80,10 @@
|
||||||
|
#define __NR_fsync 74
|
||||||
|
#define __NR_ftruncate 77
|
||||||
|
#define __NR_futex 202
|
||||||
|
+#define __NR_futex_requeue 456
|
||||||
|
+#define __NR_futex_wait 455
|
||||||
|
#define __NR_futex_waitv 449
|
||||||
|
+#define __NR_futex_wake 454
|
||||||
|
#define __NR_futimesat 261
|
||||||
|
#define __NR_get_kernel_syms 177
|
||||||
|
#define __NR_get_mempolicy 239
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
index dd5e196272..b9db8bc5be 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
@@ -76,7 +76,10 @@
|
||||||
|
#define __NR_fsync 1073741898
|
||||||
|
#define __NR_ftruncate 1073741901
|
||||||
|
#define __NR_futex 1073742026
|
||||||
|
+#define __NR_futex_requeue 1073742280
|
||||||
|
+#define __NR_futex_wait 1073742279
|
||||||
|
#define __NR_futex_waitv 1073742273
|
||||||
|
+#define __NR_futex_wake 1073742278
|
||||||
|
#define __NR_futimesat 1073742085
|
||||||
|
#define __NR_get_mempolicy 1073742063
|
||||||
|
#define __NR_get_robust_list 1073742355
|
@ -0,0 +1,756 @@
|
|||||||
|
commit 3de2f8755c6c036dcd0b1f4acd6bcdefe0e775c0
|
||||||
|
Author: Joseph Myers <josmyers@redhat.com>
|
||||||
|
Date: Wed Mar 13 13:57:56 2024 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.8
|
||||||
|
|
||||||
|
Linux 6.8 adds five new syscalls. Update syscall-names.list and
|
||||||
|
regenerate the arch-syscall.h headers with build-many-glibcs.py
|
||||||
|
update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified for RHEL by: Patsy Griffin <patsy@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
index 1713897f85..7ee8a2167a 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
|
||||||
|
@@ -122,12 +122,16 @@
|
||||||
|
#define __NR_lgetxattr 9
|
||||||
|
#define __NR_linkat 37
|
||||||
|
#define __NR_listen 201
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 11
|
||||||
|
#define __NR_llistxattr 12
|
||||||
|
#define __NR_lookup_dcookie 18
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lseek 62
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_madvise 233
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
@@ -276,6 +280,7 @@
|
||||||
|
#define __NR_socketpair 199
|
||||||
|
#define __NR_splice 76
|
||||||
|
#define __NR_statfs 43
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 291
|
||||||
|
#define __NR_swapoff 225
|
||||||
|
#define __NR_swapon 224
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
index 5457d2d8ae..0f4ea7670b 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
|
||||||
|
@@ -150,12 +150,16 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 458
|
||||||
|
#define __NR_listen 106
|
||||||
|
+#define __NR_listmount 568
|
||||||
|
#define __NR_listxattr 388
|
||||||
|
#define __NR_llistxattr 389
|
||||||
|
#define __NR_lookup_dcookie 406
|
||||||
|
#define __NR_lremovexattr 392
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 383
|
||||||
|
+#define __NR_lsm_get_self_attr 569
|
||||||
|
+#define __NR_lsm_list_modules 571
|
||||||
|
+#define __NR_lsm_set_self_attr 570
|
||||||
|
#define __NR_lstat 68
|
||||||
|
#define __NR_lstat64 426
|
||||||
|
#define __NR_madvise 75
|
||||||
|
@@ -441,6 +445,7 @@
|
||||||
|
#define __NR_stat64 425
|
||||||
|
#define __NR_statfs 328
|
||||||
|
#define __NR_statfs64 528
|
||||||
|
+#define __NR_statmount 567
|
||||||
|
#define __NR_statx 522
|
||||||
|
#define __NR_swapoff 304
|
||||||
|
#define __NR_swapon 322
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
index a66471c83a..90359482a8 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
|
||||||
|
@@ -126,12 +126,16 @@
|
||||||
|
#define __NR_lgetxattr 9
|
||||||
|
#define __NR_linkat 37
|
||||||
|
#define __NR_listen 201
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 11
|
||||||
|
#define __NR_llistxattr 12
|
||||||
|
#define __NR_llseek 62
|
||||||
|
#define __NR_lookup_dcookie 18
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_madvise 233
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
@@ -278,6 +282,7 @@
|
||||||
|
#define __NR_socketpair 199
|
||||||
|
#define __NR_splice 76
|
||||||
|
#define __NR_statfs64 43
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 291
|
||||||
|
#define __NR_swapoff 225
|
||||||
|
#define __NR_swapon 224
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
index 74a57f4520..4930167a03 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
|
||||||
|
@@ -164,12 +164,16 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 330
|
||||||
|
#define __NR_listen 284
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 232
|
||||||
|
#define __NR_llistxattr 233
|
||||||
|
#define __NR_lookup_dcookie 249
|
||||||
|
#define __NR_lremovexattr 236
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 227
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 220
|
||||||
|
@@ -361,6 +365,7 @@
|
||||||
|
#define __NR_stat64 195
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 266
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 397
|
||||||
|
#define __NR_swapoff 115
|
||||||
|
#define __NR_swapon 87
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
index ba7632e018..3f16a29f57 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
|
||||||
|
@@ -131,12 +131,16 @@
|
||||||
|
#define __NR_lgetxattr 9
|
||||||
|
#define __NR_linkat 37
|
||||||
|
#define __NR_listen 201
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 11
|
||||||
|
#define __NR_llistxattr 12
|
||||||
|
#define __NR_llseek 62
|
||||||
|
#define __NR_lookup_dcookie 18
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_madvise 233
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
@@ -291,6 +295,7 @@
|
||||||
|
#define __NR_socketpair 199
|
||||||
|
#define __NR_splice 76
|
||||||
|
#define __NR_statfs64 43
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 291
|
||||||
|
#define __NR_swapoff 225
|
||||||
|
#define __NR_swapon 224
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
index 483706de9b..a1b2c819d6 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
|
||||||
|
@@ -155,12 +155,16 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 283
|
||||||
|
#define __NR_listen 32
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 244
|
||||||
|
#define __NR_llistxattr 245
|
||||||
|
#define __NR_lookup_dcookie 223
|
||||||
|
#define __NR_lremovexattr 248
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 239
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 84
|
||||||
|
#define __NR_lstat64 198
|
||||||
|
#define __NR_madvise 119
|
||||||
|
@@ -339,6 +343,7 @@
|
||||||
|
#define __NR_stat64 101
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 298
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 349
|
||||||
|
#define __NR_stime 25
|
||||||
|
#define __NR_swapoff 115
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
index 21c1308bb3..cc775432d6 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
|
||||||
|
@@ -176,6 +176,7 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 303
|
||||||
|
#define __NR_listen 363
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 232
|
||||||
|
#define __NR_llistxattr 233
|
||||||
|
#define __NR_lock 53
|
||||||
|
@@ -183,6 +184,9 @@
|
||||||
|
#define __NR_lremovexattr 236
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 227
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 219
|
||||||
|
@@ -386,6 +390,7 @@
|
||||||
|
#define __NR_stat64 195
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 268
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 383
|
||||||
|
#define __NR_stime 25
|
||||||
|
#define __NR_stty 31
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
index 6d788e3440..79f277dd5b 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
|
||||||
|
@@ -171,12 +171,16 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 296
|
||||||
|
#define __NR_listen 360
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 229
|
||||||
|
#define __NR_llistxattr 230
|
||||||
|
#define __NR_lookup_dcookie 248
|
||||||
|
#define __NR_lremovexattr 233
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 224
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 238
|
||||||
|
@@ -373,6 +377,7 @@
|
||||||
|
#define __NR_stat64 195
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 263
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 379
|
||||||
|
#define __NR_stime 25
|
||||||
|
#define __NR_swapoff 115
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
index 91e1630f7b..779d5d5d70 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
|
||||||
|
@@ -176,6 +176,7 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 303
|
||||||
|
#define __NR_listen 348
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 232
|
||||||
|
#define __NR_llistxattr 233
|
||||||
|
#define __NR_lock 53
|
||||||
|
@@ -183,6 +184,9 @@
|
||||||
|
#define __NR_lremovexattr 236
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 227
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 219
|
||||||
|
@@ -389,6 +393,7 @@
|
||||||
|
#define __NR_stat64 195
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 268
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 398
|
||||||
|
#define __NR_stime 25
|
||||||
|
#define __NR_stty 31
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
index d75af97467..86ffd5ce84 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
|
||||||
|
@@ -166,6 +166,7 @@
|
||||||
|
#define __NR_link 4009
|
||||||
|
#define __NR_linkat 4296
|
||||||
|
#define __NR_listen 4174
|
||||||
|
+#define __NR_listmount 4458
|
||||||
|
#define __NR_listxattr 4230
|
||||||
|
#define __NR_llistxattr 4231
|
||||||
|
#define __NR_lock 4053
|
||||||
|
@@ -173,6 +174,9 @@
|
||||||
|
#define __NR_lremovexattr 4234
|
||||||
|
#define __NR_lseek 4019
|
||||||
|
#define __NR_lsetxattr 4225
|
||||||
|
+#define __NR_lsm_get_self_attr 4459
|
||||||
|
+#define __NR_lsm_list_modules 4461
|
||||||
|
+#define __NR_lsm_set_self_attr 4460
|
||||||
|
#define __NR_lstat 4107
|
||||||
|
#define __NR_lstat64 4214
|
||||||
|
#define __NR_madvise 4218
|
||||||
|
@@ -362,6 +366,7 @@
|
||||||
|
#define __NR_stat64 4213
|
||||||
|
#define __NR_statfs 4099
|
||||||
|
#define __NR_statfs64 4255
|
||||||
|
+#define __NR_statmount 4457
|
||||||
|
#define __NR_statx 4366
|
||||||
|
#define __NR_stime 4025
|
||||||
|
#define __NR_stty 4031
|
||||||
|
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 05bf7d251d..5d37a686e5 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
|
||||||
|
@@ -154,12 +154,16 @@
|
||||||
|
#define __NR_link 6084
|
||||||
|
#define __NR_linkat 6259
|
||||||
|
#define __NR_listen 6049
|
||||||
|
+#define __NR_listmount 6458
|
||||||
|
#define __NR_listxattr 6186
|
||||||
|
#define __NR_llistxattr 6187
|
||||||
|
#define __NR_lookup_dcookie 6206
|
||||||
|
#define __NR_lremovexattr 6190
|
||||||
|
#define __NR_lseek 6008
|
||||||
|
#define __NR_lsetxattr 6181
|
||||||
|
+#define __NR_lsm_get_self_attr 6459
|
||||||
|
+#define __NR_lsm_list_modules 6461
|
||||||
|
+#define __NR_lsm_set_self_attr 6460
|
||||||
|
#define __NR_lstat 6006
|
||||||
|
#define __NR_madvise 6027
|
||||||
|
#define __NR_map_shadow_stack 6453
|
||||||
|
@@ -332,6 +336,7 @@
|
||||||
|
#define __NR_stat 6004
|
||||||
|
#define __NR_statfs 6134
|
||||||
|
#define __NR_statfs64 6217
|
||||||
|
+#define __NR_statmount 6457
|
||||||
|
#define __NR_statx 6330
|
||||||
|
#define __NR_swapoff 6163
|
||||||
|
#define __NR_swapon 6162
|
||||||
|
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 41ffaf3255..9b1e846e76 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
|
||||||
|
@@ -145,12 +145,16 @@
|
||||||
|
#define __NR_link 5084
|
||||||
|
#define __NR_linkat 5255
|
||||||
|
#define __NR_listen 5049
|
||||||
|
+#define __NR_listmount 5458
|
||||||
|
#define __NR_listxattr 5186
|
||||||
|
#define __NR_llistxattr 5187
|
||||||
|
#define __NR_lookup_dcookie 5206
|
||||||
|
#define __NR_lremovexattr 5190
|
||||||
|
#define __NR_lseek 5008
|
||||||
|
#define __NR_lsetxattr 5181
|
||||||
|
+#define __NR_lsm_get_self_attr 5459
|
||||||
|
+#define __NR_lsm_list_modules 5461
|
||||||
|
+#define __NR_lsm_set_self_attr 5460
|
||||||
|
#define __NR_lstat 5006
|
||||||
|
#define __NR_madvise 5027
|
||||||
|
#define __NR_map_shadow_stack 5453
|
||||||
|
@@ -313,6 +317,7 @@
|
||||||
|
#define __NR_splice 5263
|
||||||
|
#define __NR_stat 5004
|
||||||
|
#define __NR_statfs 5134
|
||||||
|
+#define __NR_statmount 5457
|
||||||
|
#define __NR_statx 5326
|
||||||
|
#define __NR_swapoff 5163
|
||||||
|
#define __NR_swapon 5162
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
index d94e7e9ee9..abbc9ab6b0 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
|
||||||
|
@@ -130,12 +130,16 @@
|
||||||
|
#define __NR_lgetxattr 9
|
||||||
|
#define __NR_linkat 37
|
||||||
|
#define __NR_listen 201
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 11
|
||||||
|
#define __NR_llistxattr 12
|
||||||
|
#define __NR_llseek 62
|
||||||
|
#define __NR_lookup_dcookie 18
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_madvise 233
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
@@ -290,6 +294,7 @@
|
||||||
|
#define __NR_socketpair 199
|
||||||
|
#define __NR_splice 76
|
||||||
|
#define __NR_statfs64 43
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 291
|
||||||
|
#define __NR_swapoff 225
|
||||||
|
#define __NR_swapon 224
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
index b5522e8889..af0d2b121e 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
|
||||||
|
@@ -166,6 +166,7 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 294
|
||||||
|
#define __NR_listen 329
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 215
|
||||||
|
#define __NR_llistxattr 216
|
||||||
|
#define __NR_lock 53
|
||||||
|
@@ -173,6 +174,9 @@
|
||||||
|
#define __NR_lremovexattr 219
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 210
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 205
|
||||||
|
@@ -374,6 +378,7 @@
|
||||||
|
#define __NR_stat64 195
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 252
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 383
|
||||||
|
#define __NR_stime 25
|
||||||
|
#define __NR_stty 31
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
index 162d782ae6..a4c70aa7fe 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
|
||||||
|
@@ -154,6 +154,7 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 294
|
||||||
|
#define __NR_listen 329
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 215
|
||||||
|
#define __NR_llistxattr 216
|
||||||
|
#define __NR_lock 53
|
||||||
|
@@ -161,6 +162,9 @@
|
||||||
|
#define __NR_lremovexattr 219
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 210
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_madvise 205
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
@@ -352,6 +356,7 @@
|
||||||
|
#define __NR_stat 106
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 252
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 383
|
||||||
|
#define __NR_stime 25
|
||||||
|
#define __NR_stty 31
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
index 013222e5de..7315d164d6 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
|
||||||
|
@@ -117,12 +117,16 @@
|
||||||
|
#define __NR_lgetxattr 9
|
||||||
|
#define __NR_linkat 37
|
||||||
|
#define __NR_listen 201
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 11
|
||||||
|
#define __NR_llistxattr 12
|
||||||
|
#define __NR_llseek 62
|
||||||
|
#define __NR_lookup_dcookie 18
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_madvise 233
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
@@ -268,6 +272,7 @@
|
||||||
|
#define __NR_socketpair 199
|
||||||
|
#define __NR_splice 76
|
||||||
|
#define __NR_statfs64 43
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 291
|
||||||
|
#define __NR_swapoff 225
|
||||||
|
#define __NR_swapon 224
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
index d03dad8200..31a1130db9 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
|
||||||
|
@@ -122,12 +122,16 @@
|
||||||
|
#define __NR_lgetxattr 9
|
||||||
|
#define __NR_linkat 37
|
||||||
|
#define __NR_listen 201
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 11
|
||||||
|
#define __NR_llistxattr 12
|
||||||
|
#define __NR_lookup_dcookie 18
|
||||||
|
#define __NR_lremovexattr 15
|
||||||
|
#define __NR_lseek 62
|
||||||
|
#define __NR_lsetxattr 6
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_madvise 233
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
#define __NR_mbind 235
|
||||||
|
@@ -277,6 +281,7 @@
|
||||||
|
#define __NR_socketpair 199
|
||||||
|
#define __NR_splice 76
|
||||||
|
#define __NR_statfs 43
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 291
|
||||||
|
#define __NR_swapoff 225
|
||||||
|
#define __NR_swapon 224
|
||||||
|
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 98e6b68b31..cf8569304d 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
|
||||||
|
@@ -171,12 +171,16 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 296
|
||||||
|
#define __NR_listen 363
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 230
|
||||||
|
#define __NR_llistxattr 231
|
||||||
|
#define __NR_lookup_dcookie 110
|
||||||
|
#define __NR_lremovexattr 234
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 225
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 219
|
||||||
|
@@ -372,6 +376,7 @@
|
||||||
|
#define __NR_stat64 195
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 265
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 379
|
||||||
|
#define __NR_stime 25
|
||||||
|
#define __NR_swapoff 115
|
||||||
|
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 951fbd7c97..f3536ed03f 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
|
||||||
|
@@ -146,12 +146,16 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 296
|
||||||
|
#define __NR_listen 363
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 230
|
||||||
|
#define __NR_llistxattr 231
|
||||||
|
#define __NR_lookup_dcookie 110
|
||||||
|
#define __NR_lremovexattr 234
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 225
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_madvise 219
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
@@ -329,6 +333,7 @@
|
||||||
|
#define __NR_stat 106
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 265
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 379
|
||||||
|
#define __NR_swapoff 115
|
||||||
|
#define __NR_swapon 87
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
index 6b4418bcae..0c88bf10c7 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
|
||||||
|
@@ -164,12 +164,16 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 303
|
||||||
|
#define __NR_listen 343
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 232
|
||||||
|
#define __NR_llistxattr 233
|
||||||
|
#define __NR_lookup_dcookie 253
|
||||||
|
#define __NR_lremovexattr 236
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 227
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 107
|
||||||
|
#define __NR_lstat64 196
|
||||||
|
#define __NR_madvise 219
|
||||||
|
@@ -365,6 +369,7 @@
|
||||||
|
#define __NR_stat64 195
|
||||||
|
#define __NR_statfs 99
|
||||||
|
#define __NR_statfs64 268
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 383
|
||||||
|
#define __NR_stime 25
|
||||||
|
#define __NR_swapoff 115
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
index 4f9460b1a3..19fa614624 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
|
||||||
|
@@ -169,12 +169,16 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 292
|
||||||
|
#define __NR_listen 354
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 178
|
||||||
|
#define __NR_llistxattr 179
|
||||||
|
#define __NR_lookup_dcookie 208
|
||||||
|
#define __NR_lremovexattr 182
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 170
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 40
|
||||||
|
#define __NR_lstat64 132
|
||||||
|
#define __NR_madvise 75
|
||||||
|
@@ -370,6 +374,7 @@
|
||||||
|
#define __NR_stat64 139
|
||||||
|
#define __NR_statfs 157
|
||||||
|
#define __NR_statfs64 234
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 360
|
||||||
|
#define __NR_stime 233
|
||||||
|
#define __NR_swapoff 213
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
index 129ce50646..18516f20cb 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
|
||||||
|
@@ -152,12 +152,16 @@
|
||||||
|
#define __NR_link 9
|
||||||
|
#define __NR_linkat 292
|
||||||
|
#define __NR_listen 354
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 178
|
||||||
|
#define __NR_llistxattr 179
|
||||||
|
#define __NR_lookup_dcookie 208
|
||||||
|
#define __NR_lremovexattr 182
|
||||||
|
#define __NR_lseek 19
|
||||||
|
#define __NR_lsetxattr 170
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 40
|
||||||
|
#define __NR_lstat64 132
|
||||||
|
#define __NR_madvise 75
|
||||||
|
@@ -339,6 +343,7 @@
|
||||||
|
#define __NR_stat64 139
|
||||||
|
#define __NR_statfs 157
|
||||||
|
#define __NR_statfs64 234
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 360
|
||||||
|
#define __NR_stime 233
|
||||||
|
#define __NR_swapoff 213
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index aac065e7b3..6557bcfde4 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 6.7.
|
||||||
|
-kernel 6.7
|
||||||
|
+# The list of system calls is current as of Linux 6.8.
|
||||||
|
+kernel 6.8
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -239,6 +239,7 @@ lgetxattr
|
||||||
|
link
|
||||||
|
linkat
|
||||||
|
listen
|
||||||
|
+listmount
|
||||||
|
listxattr
|
||||||
|
llistxattr
|
||||||
|
llseek
|
||||||
|
@@ -247,6 +248,9 @@ lookup_dcookie
|
||||||
|
lremovexattr
|
||||||
|
lseek
|
||||||
|
lsetxattr
|
||||||
|
+lsm_get_self_attr
|
||||||
|
+lsm_list_modules
|
||||||
|
+lsm_set_self_attr
|
||||||
|
lstat
|
||||||
|
lstat64
|
||||||
|
madvise
|
||||||
|
@@ -593,6 +597,7 @@ stat
|
||||||
|
stat64
|
||||||
|
statfs
|
||||||
|
statfs64
|
||||||
|
+statmount
|
||||||
|
statx
|
||||||
|
stime
|
||||||
|
stty
|
||||||
|
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 4fa5b942c5..b122216013 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
|
||||||
|
@@ -149,12 +149,16 @@
|
||||||
|
#define __NR_link 86
|
||||||
|
#define __NR_linkat 265
|
||||||
|
#define __NR_listen 50
|
||||||
|
+#define __NR_listmount 458
|
||||||
|
#define __NR_listxattr 194
|
||||||
|
#define __NR_llistxattr 195
|
||||||
|
#define __NR_lookup_dcookie 212
|
||||||
|
#define __NR_lremovexattr 198
|
||||||
|
#define __NR_lseek 8
|
||||||
|
#define __NR_lsetxattr 189
|
||||||
|
+#define __NR_lsm_get_self_attr 459
|
||||||
|
+#define __NR_lsm_list_modules 461
|
||||||
|
+#define __NR_lsm_set_self_attr 460
|
||||||
|
#define __NR_lstat 6
|
||||||
|
#define __NR_madvise 28
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
@@ -321,6 +325,7 @@
|
||||||
|
#define __NR_splice 275
|
||||||
|
#define __NR_stat 4
|
||||||
|
#define __NR_statfs 137
|
||||||
|
+#define __NR_statmount 457
|
||||||
|
#define __NR_statx 332
|
||||||
|
#define __NR_swapoff 168
|
||||||
|
#define __NR_swapon 167
|
||||||
|
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 b9db8bc5be..3040a47d72 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
|
||||||
|
@@ -143,12 +143,16 @@
|
||||||
|
#define __NR_link 1073741910
|
||||||
|
#define __NR_linkat 1073742089
|
||||||
|
#define __NR_listen 1073741874
|
||||||
|
+#define __NR_listmount 1073742282
|
||||||
|
#define __NR_listxattr 1073742018
|
||||||
|
#define __NR_llistxattr 1073742019
|
||||||
|
#define __NR_lookup_dcookie 1073742036
|
||||||
|
#define __NR_lremovexattr 1073742022
|
||||||
|
#define __NR_lseek 1073741832
|
||||||
|
#define __NR_lsetxattr 1073742013
|
||||||
|
+#define __NR_lsm_get_self_attr 1073742283
|
||||||
|
+#define __NR_lsm_list_modules 1073742285
|
||||||
|
+#define __NR_lsm_set_self_attr 1073742284
|
||||||
|
#define __NR_lstat 1073741830
|
||||||
|
#define __NR_madvise 1073741852
|
||||||
|
#define __NR_mbind 1073742061
|
||||||
|
@@ -312,6 +316,7 @@
|
||||||
|
#define __NR_splice 1073742099
|
||||||
|
#define __NR_stat 1073741828
|
||||||
|
#define __NR_statfs 1073741961
|
||||||
|
+#define __NR_statmount 1073742281
|
||||||
|
#define __NR_statx 1073742156
|
||||||
|
#define __NR_swapoff 1073741992
|
||||||
|
#define __NR_swapon 1073741991
|
@ -0,0 +1,28 @@
|
|||||||
|
commit cf0ca8d52e1653d4aa4311a4649af8dc541ce6b4
|
||||||
|
Author: Joseph Myers <josmyers@redhat.com>
|
||||||
|
Date: Mon May 20 13:10:31 2024 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 6.9
|
||||||
|
|
||||||
|
Linux 6.9 has no new syscalls. Update the version number in
|
||||||
|
syscall-names.list to reflect that it is still current for 6.9.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified for RHEL by: Patsy Griffin <patsy@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 6557bcfde4..672d39eaad 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 6.8.
|
||||||
|
-kernel 6.8
|
||||||
|
+# The list of system calls is current as of Linux 6.9.
|
||||||
|
+kernel 6.9
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
@ -0,0 +1,26 @@
|
|||||||
|
From cb8c78b2ffa0b77ae453b2d328d7e2fe5186ef2a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue, 31 Oct 2023 13:32:35 -0300
|
||||||
|
Subject: linux: Add MMAP_ABOVE4G from Linux 6.6 to sys/mman.h
|
||||||
|
|
||||||
|
x86 added the flag (29f890d1050fc099f) for CET enabled.
|
||||||
|
|
||||||
|
Also update tst-mman-consts.py test.
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||||
|
(removed patch to keep alerting about kernel differences)
|
||||||
|
sysdeps/unix/sysv/linux/x86/bits/mman.h
|
||||||
|
(adapted to missing __USE_MISC conditional upstream)
|
||||||
|
|
||||||
|
diff -rup a/sysdeps/unix/sysv/linux/x86/bits/mman.h b/sysdeps/unix/sysv/linux/x86/bits/mman.h
|
||||||
|
--- a/sysdeps/unix/sysv/linux/x86/bits/mman.h 2021-08-01 21:33:43.000000000 -0400
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/x86/bits/mman.h 2024-05-29 14:03:12.426182715 -0400
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
/* Other flags. */
|
||||||
|
#ifdef __USE_MISC
|
||||||
|
# define MAP_32BIT 0x40 /* Only give out 32-bit addresses. */
|
||||||
|
+# define MAP_ABOVE4G 0x80 /* Only map above 4GB. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <bits/mman-map-flags-generic.h>
|
@ -0,0 +1,499 @@
|
|||||||
|
commit 018f0fc3b818d4d1460a4e2384c24802504b1d20
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Jul 1 17:42:04 2024 +0200
|
||||||
|
|
||||||
|
elf: Support recursive use of dynamic TLS in interposed malloc
|
||||||
|
|
||||||
|
It turns out that quite a few applications use bundled mallocs that
|
||||||
|
have been built to use global-dynamic TLS (instead of the recommended
|
||||||
|
initial-exec TLS). The previous workaround from
|
||||||
|
commit afe42e935b3ee97bac9a7064157587777259c60e ("elf: Avoid some
|
||||||
|
free (NULL) calls in _dl_update_slotinfo") does not fix all
|
||||||
|
encountered cases unfortunatelly.
|
||||||
|
|
||||||
|
This change avoids the TLS generation update for recursive use
|
||||||
|
of TLS from a malloc that was called during a TLS update. This
|
||||||
|
is possible because an interposed malloc has a fixed module ID and
|
||||||
|
TLS slot. (It cannot be unloaded.) If an initially-loaded module ID
|
||||||
|
is encountered in __tls_get_addr and the dynamic linker is already
|
||||||
|
in the middle of a TLS update, use the outdated DTV, thus avoiding
|
||||||
|
another call into malloc. It's still necessary to update the
|
||||||
|
DTV to the most recent generation, to get out of the slow path,
|
||||||
|
which is why the check for recursion is needed.
|
||||||
|
|
||||||
|
The bookkeeping is done using a global counter instead of per-thread
|
||||||
|
flag because TLS access in the dynamic linker is tricky.
|
||||||
|
|
||||||
|
All this will go away once the dynamic linker stops using malloc
|
||||||
|
for TLS, likely as part of a change that pre-allocates all TLS
|
||||||
|
during pthread_create/dlopen.
|
||||||
|
|
||||||
|
Fixes commit d2123d68275acc0f061e73d5f86ca504e0d5a344 ("elf: Fix slow
|
||||||
|
tls access after dlopen [BZ #19924]").
|
||||||
|
|
||||||
|
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
|
||||||
|
Reworked for RHEL by: Patsy Griffin <patsy@redhat.com>
|
||||||
|
|
||||||
|
diff -Nrup a/elf/Makefile b/elf/Makefile
|
||||||
|
--- a/elf/Makefile 2024-07-09 22:06:30.237752048 -0400
|
||||||
|
+++ b/elf/Makefile 2024-07-10 14:09:02.996759220 -0400
|
||||||
|
@@ -423,6 +423,7 @@ tests += \
|
||||||
|
tst-nodeps2 \
|
||||||
|
tst-noload \
|
||||||
|
tst-null-argv \
|
||||||
|
+ tst-recursive-tls \
|
||||||
|
tst-relsort1 \
|
||||||
|
tst-ro-dynamic \
|
||||||
|
tst-rtld-run-static \
|
||||||
|
@@ -783,6 +784,23 @@ modules-names = \
|
||||||
|
tst-nodeps1-mod \
|
||||||
|
tst-nodeps2-mod \
|
||||||
|
tst-null-argv-lib \
|
||||||
|
+ tst-recursive-tlsmallocmod \
|
||||||
|
+ tst-recursive-tlsmod0 \
|
||||||
|
+ tst-recursive-tlsmod1 \
|
||||||
|
+ tst-recursive-tlsmod2 \
|
||||||
|
+ tst-recursive-tlsmod3 \
|
||||||
|
+ tst-recursive-tlsmod4 \
|
||||||
|
+ tst-recursive-tlsmod5 \
|
||||||
|
+ tst-recursive-tlsmod6 \
|
||||||
|
+ tst-recursive-tlsmod7 \
|
||||||
|
+ tst-recursive-tlsmod8 \
|
||||||
|
+ tst-recursive-tlsmod9 \
|
||||||
|
+ tst-recursive-tlsmod10 \
|
||||||
|
+ tst-recursive-tlsmod11 \
|
||||||
|
+ tst-recursive-tlsmod12 \
|
||||||
|
+ tst-recursive-tlsmod13 \
|
||||||
|
+ tst-recursive-tlsmod14 \
|
||||||
|
+ tst-recursive-tlsmod15 \
|
||||||
|
tst-relsort1mod1 \
|
||||||
|
tst-relsort1mod2 \
|
||||||
|
tst-ro-dynamic-mod \
|
||||||
|
@@ -2725,3 +2743,11 @@ CFLAGS-tst-tlsgap-mod0.c += -mtls-dialec
|
||||||
|
CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2
|
||||||
|
CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2
|
||||||
|
endif
|
||||||
|
+
|
||||||
|
+$(objpfx)tst-recursive-tls: $(objpfx)tst-recursive-tlsmallocmod.so
|
||||||
|
+# More objects than DTV_SURPLUS, to trigger DTV reallocation.
|
||||||
|
+$(objpfx)tst-recursive-tls.out: \
|
||||||
|
+ $(patsubst %,$(objpfx)tst-recursive-tlsmod%.so, \
|
||||||
|
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
|
||||||
|
+$(objpfx)tst-recursive-tlsmod%.os: tst-recursive-tlsmodN.c
|
||||||
|
+ $(compile-command.c) -DVAR=thread_$* -DFUNC=get_threadvar_$*
|
||||||
|
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||||
|
index 670dbc42fc..3d221273f1 100644
|
||||||
|
--- a/elf/dl-tls.c
|
||||||
|
+++ b/elf/dl-tls.c
|
||||||
|
@@ -75,6 +75,31 @@
|
||||||
|
/* Default for dl_tls_static_optional. */
|
||||||
|
#define OPTIONAL_TLS 512
|
||||||
|
|
||||||
|
+/* Used to count the number of threads currently executing dynamic TLS
|
||||||
|
+ updates. Used to avoid recursive malloc calls in __tls_get_addr
|
||||||
|
+ for an interposed malloc that uses global-dynamic TLS (which is not
|
||||||
|
+ recommended); see _dl_tls_allocate_active checks. This could be a
|
||||||
|
+ per-thread flag, but would need TLS access in the dynamic linker. */
|
||||||
|
+unsigned int _dl_tls_threads_in_update;
|
||||||
|
+
|
||||||
|
+static inline void
|
||||||
|
+_dl_tls_allocate_begin (void)
|
||||||
|
+{
|
||||||
|
+ atomic_fetch_add_relaxed (&_dl_tls_threads_in_update, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void
|
||||||
|
+_dl_tls_allocate_end (void)
|
||||||
|
+{
|
||||||
|
+ atomic_fetch_add_relaxed (&_dl_tls_threads_in_update, -1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+_dl_tls_allocate_active (void)
|
||||||
|
+{
|
||||||
|
+ return atomic_load_relaxed (&_dl_tls_threads_in_update) > 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Compute the static TLS surplus based on the namespace count and the
|
||||||
|
TLS space that can be used for optimizations. */
|
||||||
|
static inline int
|
||||||
|
@@ -425,12 +450,18 @@ _dl_allocate_tls_storage (void)
|
||||||
|
size += TLS_PRE_TCB_SIZE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- /* Perform the allocation. Reserve space for the required alignment
|
||||||
|
- and the pointer to the original allocation. */
|
||||||
|
+ /* Reserve space for the required alignment and the pointer to the
|
||||||
|
+ original allocation. */
|
||||||
|
size_t alignment = GLRO (dl_tls_static_align);
|
||||||
|
+
|
||||||
|
+ /* Perform the allocation. */
|
||||||
|
+ _dl_tls_allocate_begin ();
|
||||||
|
void *allocated = malloc (size + alignment + sizeof (void *));
|
||||||
|
if (__glibc_unlikely (allocated == NULL))
|
||||||
|
- return NULL;
|
||||||
|
+ {
|
||||||
|
+ _dl_tls_allocate_end ();
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Perform alignment and allocate the DTV. */
|
||||||
|
#if TLS_TCB_AT_TP
|
||||||
|
@@ -466,6 +497,8 @@ _dl_allocate_tls_storage (void)
|
||||||
|
result = allocate_dtv (result);
|
||||||
|
if (result == NULL)
|
||||||
|
free (allocated);
|
||||||
|
+
|
||||||
|
+ _dl_tls_allocate_end ();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -483,6 +516,7 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
|
||||||
|
size_t newsize = max_modid + DTV_SURPLUS;
|
||||||
|
size_t oldsize = dtv[-1].counter;
|
||||||
|
|
||||||
|
+ _dl_tls_allocate_begin ();
|
||||||
|
if (dtv == GL(dl_initial_dtv))
|
||||||
|
{
|
||||||
|
/* This is the initial dtv that was either statically allocated in
|
||||||
|
@@ -502,6 +536,7 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
|
||||||
|
if (newp == NULL)
|
||||||
|
oom ();
|
||||||
|
}
|
||||||
|
+ _dl_tls_allocate_end ();
|
||||||
|
|
||||||
|
newp[0].counter = newsize;
|
||||||
|
|
||||||
|
@@ -676,7 +711,9 @@ allocate_dtv_entry (size_t alignment, size_t size)
|
||||||
|
if (powerof2 (alignment) && alignment <= _Alignof (max_align_t))
|
||||||
|
{
|
||||||
|
/* The alignment is supported by malloc. */
|
||||||
|
+ _dl_tls_allocate_begin ();
|
||||||
|
void *ptr = malloc (size);
|
||||||
|
+ _dl_tls_allocate_end ();
|
||||||
|
return (struct dtv_pointer) { ptr, ptr };
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -688,7 +725,10 @@ allocate_dtv_entry (size_t alignment, size_t size)
|
||||||
|
|
||||||
|
/* Perform the allocation. This is the pointer we need to free
|
||||||
|
later. */
|
||||||
|
+ _dl_tls_allocate_begin ();
|
||||||
|
void *start = malloc (alloc_size);
|
||||||
|
+ _dl_tls_allocate_end ();
|
||||||
|
+
|
||||||
|
if (start == NULL)
|
||||||
|
return (struct dtv_pointer) {};
|
||||||
|
|
||||||
|
@@ -826,7 +866,11 @@ _dl_update_slotinfo (unsigned long int req_modid, size_t new_gen)
|
||||||
|
free implementation. Checking here papers over at
|
||||||
|
least some dynamic TLS usage by interposed mallocs. */
|
||||||
|
if (dtv[modid].pointer.to_free != NULL)
|
||||||
|
- free (dtv[modid].pointer.to_free);
|
||||||
|
+ {
|
||||||
|
+ _dl_tls_allocate_begin ();
|
||||||
|
+ free (dtv[modid].pointer.to_free);
|
||||||
|
+ _dl_tls_allocate_end ();
|
||||||
|
+ }
|
||||||
|
dtv[modid].pointer.val = TLS_DTV_UNALLOCATED;
|
||||||
|
dtv[modid].pointer.to_free = NULL;
|
||||||
|
|
||||||
|
@@ -956,10 +1000,22 @@ __tls_get_addr (GET_ADDR_ARGS)
|
||||||
|
size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
|
||||||
|
if (__glibc_unlikely (dtv[0].counter != gen))
|
||||||
|
{
|
||||||
|
- /* Update DTV up to the global generation, see CONCURRENCY NOTES
|
||||||
|
- in _dl_update_slotinfo. */
|
||||||
|
- gen = atomic_load_acquire (&GL(dl_tls_generation));
|
||||||
|
- return update_get_addr (GET_ADDR_PARAM, gen);
|
||||||
|
+ if (_dl_tls_allocate_active ()
|
||||||
|
+ && GET_ADDR_MODULE < _dl_tls_initial_modid_limit)
|
||||||
|
+ /* This is a reentrant __tls_get_addr call, but we can
|
||||||
|
+ satisfy it because it's an initially-loaded module ID.
|
||||||
|
+ These TLS slotinfo slots do not change, so the
|
||||||
|
+ out-of-date generation counter does not matter. However,
|
||||||
|
+ if not in a TLS update, still update_get_addr below, to
|
||||||
|
+ get off the slow path eventually. */
|
||||||
|
+ ;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* Update DTV up to the global generation, see CONCURRENCY NOTES
|
||||||
|
+ in _dl_update_slotinfo. */
|
||||||
|
+ gen = atomic_load_acquire (&GL(dl_tls_generation));
|
||||||
|
+ return update_get_addr (GET_ADDR_PARAM, gen);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void *p = dtv[GET_ADDR_MODULE].pointer.val;
|
||||||
|
@@ -969,7 +1025,7 @@ __tls_get_addr (GET_ADDR_ARGS)
|
||||||
|
|
||||||
|
return (char *) p + GET_ADDR_OFFSET;
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
+#endif /* SHARED */
|
||||||
|
|
||||||
|
|
||||||
|
/* Look up the module's TLS block as for __tls_get_addr,
|
||||||
|
@@ -1018,6 +1074,25 @@ _dl_tls_get_addr_soft (struct link_map *l)
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
+size_t _dl_tls_initial_modid_limit;
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_tls_initial_modid_limit_setup (void)
|
||||||
|
+{
|
||||||
|
+ struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list);
|
||||||
|
+ size_t idx;
|
||||||
|
+ for (idx = 0; idx < listp->len; ++idx)
|
||||||
|
+ {
|
||||||
|
+ struct link_map *l = listp->slotinfo[idx].map;
|
||||||
|
+ if (l == NULL
|
||||||
|
+ /* The object can be unloaded, so its modid can be
|
||||||
|
+ reassociated. */
|
||||||
|
+ || !(l->l_type == lt_executable || l->l_type == lt_library))
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ _dl_tls_initial_modid_limit = idx;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
|
||||||
|
void
|
||||||
|
_dl_add_to_slotinfo (struct link_map *l, bool do_add)
|
||||||
|
@@ -1050,9 +1125,11 @@ _dl_add_to_slotinfo (struct link_map *l, bool do_add)
|
||||||
|
the first slot. */
|
||||||
|
assert (idx == 0);
|
||||||
|
|
||||||
|
+ _dl_tls_allocate_begin ();
|
||||||
|
listp = (struct dtv_slotinfo_list *)
|
||||||
|
malloc (sizeof (struct dtv_slotinfo_list)
|
||||||
|
+ TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
|
||||||
|
+ _dl_tls_allocate_end ();
|
||||||
|
if (listp == NULL)
|
||||||
|
{
|
||||||
|
/* We ran out of memory while resizing the dtv slotinfo list. */
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index e9525ea987..6352ba76c5 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -788,6 +788,8 @@ init_tls (size_t naudit)
|
||||||
|
_dl_fatal_printf ("\
|
||||||
|
cannot allocate TLS data structures for initial thread\n");
|
||||||
|
|
||||||
|
+ _dl_tls_initial_modid_limit_setup ();
|
||||||
|
+
|
||||||
|
/* Store for detection of the special case by __tls_get_addr
|
||||||
|
so it knows not to pass this dtv to the normal realloc. */
|
||||||
|
GL(dl_initial_dtv) = GET_DTV (tcbp);
|
||||||
|
diff --git a/elf/tst-recursive-tls.c b/elf/tst-recursive-tls.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..716d1f783a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-recursive-tls.c
|
||||||
|
@@ -0,0 +1,60 @@
|
||||||
|
+/* Test with interposed malloc with dynamic TLS.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <array_length.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+/* Defined in tst-recursive-tlsmallocmod.so. */
|
||||||
|
+extern __thread unsigned int malloc_subsytem_counter;
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ /* 16 is large enough to exercise the DTV resizing case. */
|
||||||
|
+ void *handles[16];
|
||||||
|
+
|
||||||
|
+ for (unsigned int i = 0; i < array_length (handles); ++i)
|
||||||
|
+ {
|
||||||
|
+ /* Re-use the TLS slot for module 0. */
|
||||||
|
+ if (i > 0)
|
||||||
|
+ xdlclose (handles[0]);
|
||||||
|
+
|
||||||
|
+ char soname[30];
|
||||||
|
+ snprintf (soname, sizeof (soname), "tst-recursive-tlsmod%u.so", i);
|
||||||
|
+ handles[i] = xdlopen (soname, RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ if (i > 0)
|
||||||
|
+ {
|
||||||
|
+ handles[0] = xdlopen ("tst-recursive-tlsmod0.so", RTLD_NOW);
|
||||||
|
+ int (*fptr) (void) = xdlsym (handles[0], "get_threadvar_0");
|
||||||
|
+ /* May trigger TLS storage allocation using malloc. */
|
||||||
|
+ TEST_COMPARE (fptr (), 0);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (unsigned int i = 0; i < array_length (handles); ++i)
|
||||||
|
+ xdlclose (handles[i]);
|
||||||
|
+
|
||||||
|
+ printf ("info: malloc subsystem calls: %u\n", malloc_subsytem_counter);
|
||||||
|
+ TEST_VERIFY (malloc_subsytem_counter > 0);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-recursive-tlsmallocmod.c b/elf/tst-recursive-tlsmallocmod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..c24e9945d1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-recursive-tlsmallocmod.c
|
||||||
|
@@ -0,0 +1,64 @@
|
||||||
|
+/* Interposed malloc with dynamic TLS.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+
|
||||||
|
+__thread unsigned int malloc_subsytem_counter;
|
||||||
|
+
|
||||||
|
+static __typeof (malloc) *malloc_fptr;
|
||||||
|
+static __typeof (free) *free_fptr;
|
||||||
|
+static __typeof (calloc) *calloc_fptr;
|
||||||
|
+static __typeof (realloc) *realloc_fptr;
|
||||||
|
+
|
||||||
|
+static void __attribute__ ((constructor))
|
||||||
|
+init (void)
|
||||||
|
+{
|
||||||
|
+ malloc_fptr = dlsym (RTLD_NEXT, "malloc");
|
||||||
|
+ free_fptr = dlsym (RTLD_NEXT, "free");
|
||||||
|
+ calloc_fptr = dlsym (RTLD_NEXT, "calloc");
|
||||||
|
+ realloc_fptr = dlsym (RTLD_NEXT, "realloc");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void *
|
||||||
|
+malloc (size_t size)
|
||||||
|
+{
|
||||||
|
+ ++malloc_subsytem_counter;
|
||||||
|
+ return malloc_fptr (size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+free (void *ptr)
|
||||||
|
+{
|
||||||
|
+ ++malloc_subsytem_counter;
|
||||||
|
+ return free_fptr (ptr);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void *
|
||||||
|
+calloc (size_t a, size_t b)
|
||||||
|
+{
|
||||||
|
+ ++malloc_subsytem_counter;
|
||||||
|
+ return calloc_fptr (a, b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void *
|
||||||
|
+realloc (void *ptr, size_t size)
|
||||||
|
+{
|
||||||
|
+ ++malloc_subsytem_counter;
|
||||||
|
+ return realloc_fptr (ptr, size);
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-recursive-tlsmodN.c b/elf/tst-recursive-tlsmodN.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..bb7592aee6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-recursive-tlsmodN.c
|
||||||
|
@@ -0,0 +1,28 @@
|
||||||
|
+/* Test module with global-dynamic TLS. Used to trigger DTV reallocation.
|
||||||
|
+ Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+/* Compiled with VAR and FUNC set via -D. FUNC requires some
|
||||||
|
+ relocation against TLS variable VAR. */
|
||||||
|
+
|
||||||
|
+__thread int VAR;
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+FUNC (void)
|
||||||
|
+{
|
||||||
|
+ return VAR;
|
||||||
|
+}
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 50f58a60e3..656e8a3fa0 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1256,6 +1256,20 @@ extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid,
|
||||||
|
size_t gen)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
+/* The last TLS module ID that is initially loaded, plus 1. TLS
|
||||||
|
+ addresses for modules with IDs lower than that can be obtained from
|
||||||
|
+ the DTV even if its generation is outdated. */
|
||||||
|
+extern size_t _dl_tls_initial_modid_limit attribute_hidden attribute_relro;
|
||||||
|
+
|
||||||
|
+/* Compute _dl_tls_initial_modid_limit. To be called after initial
|
||||||
|
+ relocation. */
|
||||||
|
+void _dl_tls_initial_modid_limit_setup (void) attribute_hidden;
|
||||||
|
+
|
||||||
|
+/* Number of threads currently in a TLS update. This is used to
|
||||||
|
+ detect reentrant __tls_get_addr calls without a per-thread
|
||||||
|
+ flag. */
|
||||||
|
+extern unsigned int _dl_tls_threads_in_update attribute_hidden;
|
||||||
|
+
|
||||||
|
/* Look up the module's TLS block as for __tls_get_addr,
|
||||||
|
but never touch anything. Return null if it's not allocated yet. */
|
||||||
|
extern void *_dl_tls_get_addr_soft (struct link_map *l) attribute_hidden;
|
||||||
|
diff --git a/sysdeps/x86_64/dl-tls.c b/sysdeps/x86_64/dl-tls.c
|
||||||
|
index 869023bbba..b3c1e4fcd7 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-tls.c
|
||||||
|
+++ b/sysdeps/x86_64/dl-tls.c
|
||||||
|
@@ -41,7 +41,10 @@ __tls_get_addr_slow (GET_ADDR_ARGS)
|
||||||
|
dtv_t *dtv = THREAD_DTV ();
|
||||||
|
|
||||||
|
size_t gen = atomic_load_acquire (&GL(dl_tls_generation));
|
||||||
|
- if (__glibc_unlikely (dtv[0].counter != gen))
|
||||||
|
+ if (__glibc_unlikely (dtv[0].counter != gen)
|
||||||
|
+ /* See comment in __tls_get_addr in elf/dl-tls.c. */
|
||||||
|
+ && !(_dl_tls_allocate_active ()
|
||||||
|
+ && GET_ADDR_MODULE < _dl_tls_initial_modid_limit))
|
||||||
|
return update_get_addr (GET_ADDR_PARAM, gen);
|
||||||
|
|
||||||
|
return tls_get_addr_tail (GET_ADDR_PARAM, dtv, NULL);
|
@ -0,0 +1,44 @@
|
|||||||
|
commit 0e16db440cc73d2cdd94e439c0efa1ec43d92b2a
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue Aug 13 15:52:34 2024 +0200
|
||||||
|
|
||||||
|
manual: Document generic printf error codes
|
||||||
|
|
||||||
|
Describe EOVERFLOW, ENOMEN, EILSEQ.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/manual/stdio.texi b/manual/stdio.texi
|
||||||
|
index 567f6780011f9db1..41298b87a4a6c7d9 100644
|
||||||
|
--- a/manual/stdio.texi
|
||||||
|
+++ b/manual/stdio.texi
|
||||||
|
@@ -2318,6 +2318,29 @@ the easiest way to make sure you have all the right prototypes is to
|
||||||
|
just include @file{stdio.h}.
|
||||||
|
@pindex stdio.h
|
||||||
|
|
||||||
|
+The @code{printf} family shares the error codes listed below.
|
||||||
|
+Individual functions may report additional @code{errno} values if they
|
||||||
|
+fail.
|
||||||
|
+
|
||||||
|
+@table @code
|
||||||
|
+@item EOVERFLOW
|
||||||
|
+The number of written bytes would have exceeded @code{INT_MAX}, and thus
|
||||||
|
+could not be represented in the return type @code{int}.
|
||||||
|
+
|
||||||
|
+@item ENOMEM
|
||||||
|
+The function could not allocate memory during processing. Long argument
|
||||||
|
+lists and certain floating point conversions may require memory
|
||||||
|
+allocation, as does initialization of an output stream upon first use.
|
||||||
|
+
|
||||||
|
+@item EILSEQ
|
||||||
|
+POSIX specifies this error code should be used if a wide character is
|
||||||
|
+encountered that does not have a matching valid character. @Theglibc{}
|
||||||
|
+always performs transliteration, using a replacement character if
|
||||||
|
+necessary, so this error condition cannot occur on output. However,
|
||||||
|
+@theglibc{} uses @code{EILSEQ} to indicate that an input character
|
||||||
|
+sequence (wide or multi-byte) could not be converted successfully.
|
||||||
|
+@end table
|
||||||
|
+
|
||||||
|
@deftypefun int printf (const char *@var{template}, @dots{})
|
||||||
|
@standards{ISO, stdio.h}
|
||||||
|
@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue