import glibc-2.34-25.el9

This commit is contained in:
CentOS Sources 2022-03-01 08:08:09 -05:00 committed by Stepan Oksanichenko
parent 1f31ebdabf
commit bdfe163f81
84 changed files with 16459 additions and 1 deletions

View File

@ -0,0 +1,65 @@
commit 1d8e3a2c6636cf0b1b8fa2f869cef6ec10726933
Author: Carlos O'Donell <carlos@redhat.com>
Date: Mon Jan 31 00:34:41 2022 -0500
localedef: Fix handling of empty mon_decimal_point (Bug 28847)
The handling of mon_decimal_point is incorrect when it comes to
handling the empty "" value. The existing parser in monetary_read()
will correctly handle setting the non-wide-character value and the
wide-character value e.g. STR_ELEM_WC(mon_decimal_point) if they are
set in the locale definition. However, in monetary_finish() we have
conflicting TEST_ELEM() which sets a default value (if the locale
definition doesn't include one), and subsequent code which looks for
mon_decimal_point to be NULL to issue a specific error message and set
the defaults. The latter is unused because TEST_ELEM() always sets a
default. The simplest solution is to remove the TEST_ELEM() check,
and allow the existing check to look to see if mon_decimal_point is
NULL and set an appropriate default. The final fix is to move the
setting of mon_decimal_point_wc so it occurs only when
mon_decimal_point is being set to a default, keeping both values
consistent. There is no way to tell the difference between
mon_decimal_point_wc having been set to the empty string and not
having been defined at all, for that distinction we must use
mon_decimal_point being NULL or "", and so we must logically set
the default together with mon_decimal_point.
Lastly, there are more fixes similar to this that could be made to
ld-monetary.c, but we avoid that in order to fix just the code
required for mon_decimal_point, which impacts the ability for C.UTF-8
to set mon_decimal_point to "", since without this fix we end up with
an inconsistent setting of mon_decimal_point set to "", but
mon_decimal_point_wc set to "." which is incorrect.
Tested on x86_64 and i686 without regression.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c
index e1e45a3409123bf4..9b9a55bb4766dfcf 100644
--- a/locale/programs/ld-monetary.c
+++ b/locale/programs/ld-monetary.c
@@ -208,7 +208,6 @@ No definition for %s category found"), "LC_MONETARY");
TEST_ELEM (int_curr_symbol, "");
TEST_ELEM (currency_symbol, "");
- TEST_ELEM (mon_decimal_point, ".");
TEST_ELEM (mon_thousands_sep, "");
TEST_ELEM (positive_sign, "");
TEST_ELEM (negative_sign, "");
@@ -258,6 +257,7 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
record_error (0, 0, _("%s: field `%s' not defined"),
"LC_MONETARY", "mon_decimal_point");
monetary->mon_decimal_point = ".";
+ monetary->mon_decimal_point_wc = L'.';
}
else if (monetary->mon_decimal_point[0] == '\0' && ! be_quiet && ! nothing)
{
@@ -265,8 +265,6 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
%s: value for field `%s' must not be an empty string"),
"LC_MONETARY", "mon_decimal_point");
}
- if (monetary->mon_decimal_point_wc == L'\0')
- monetary->mon_decimal_point_wc = L'.';
if (monetary->mon_grouping_len == 0)
{

View File

@ -0,0 +1,734 @@
commit de82cb0da4b8fa5b3d56c457438d2568c67ab1b1
Author: Joseph Myers <joseph@codesourcery.com>
Date: Tue Oct 12 13:48:39 2021 +0000
Add TEST_COMPARE_STRING_WIDE to support/check.h
I'd like to be able to test narrow and wide string interfaces, with
the narrow string tests using TEST_COMPARE_STRING and the wide string
tests using something analogous (possibly generated using macros from
a common test template for both the narrow and wide string tests where
appropriate).
Add such a TEST_COMPARE_STRING_WIDE, along with functions
support_quote_blob_wide and support_test_compare_string_wide that it
builds on. Those functions are built using macros from common
templates shared by the narrow and wide string implementations, though
I didn't do that for the tests of test functions. In
support_quote_blob_wide, I chose to use the \x{} delimited escape
sequence syntax proposed for C2X in N2785, rather than e.g. trying to
generate the end of a string and the start of a new string when
ambiguity would result from undelimited \x (when the next character
after such an escape sequence is valid hex) or forcing an escape
sequence to be used for the next character in the case of such
ambiguity.
Tested for x86_64.
diff --git a/support/Makefile b/support/Makefile
index 75bad6715ac3d08c..3c941e1ba9e29aa4 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -70,6 +70,7 @@ libsupport-routines = \
support_openpty \
support_paths \
support_quote_blob \
+ support_quote_blob_wide \
support_quote_string \
support_record_failure \
support_run_diff \
@@ -83,6 +84,7 @@ libsupport-routines = \
support_test_compare_blob \
support_test_compare_failure \
support_test_compare_string \
+ support_test_compare_string_wide \
support_test_main \
support_test_verify_impl \
support_wait_for_thread_exit \
@@ -275,11 +277,13 @@ tests = \
tst-support-open-dev-null-range \
tst-support-process_state \
tst-support_quote_blob \
+ tst-support_quote_blob_wide \
tst-support_quote_string \
tst-support_record_failure \
tst-test_compare \
tst-test_compare_blob \
tst-test_compare_string \
+ tst-test_compare_string_wide \
tst-timespec \
tst-xreadlink \
tst-xsigstack \
diff --git a/support/check.h b/support/check.h
index 83662b2d10c8cf58..9b1844352f32513a 100644
--- a/support/check.h
+++ b/support/check.h
@@ -20,6 +20,7 @@
#define SUPPORT_CHECK_H
#include <sys/cdefs.h>
+#include <stddef.h>
__BEGIN_DECLS
@@ -171,11 +172,25 @@ void support_test_compare_blob (const void *left,
(support_test_compare_string (left, right, __FILE__, __LINE__, \
#left, #right))
+/* Compare the wide strings LEFT and RIGHT and report a test failure
+ if they are different. Also report failure if one of the arguments
+ is a null pointer and the other is not. The strings should be
+ reasonably short because on mismatch, both are printed. */
+#define TEST_COMPARE_STRING_WIDE(left, right) \
+ (support_test_compare_string_wide (left, right, __FILE__, __LINE__, \
+ #left, #right))
+
void support_test_compare_string (const char *left, const char *right,
const char *file, int line,
const char *left_expr,
const char *right_expr);
+void support_test_compare_string_wide (const wchar_t *left,
+ const wchar_t *right,
+ const char *file, int line,
+ const char *left_expr,
+ const char *right_expr);
+
/* Internal function called by the test driver. */
int support_report_failure (int status)
__attribute__ ((weak, warn_unused_result));
diff --git a/support/support.h b/support/support.h
index c219e0d9d1aef046..29d56c7c891ee34b 100644
--- a/support/support.h
+++ b/support/support.h
@@ -73,6 +73,12 @@ void support_write_file_string (const char *path, const char *contents);
the result). */
char *support_quote_blob (const void *blob, size_t length);
+/* Quote the contents of the wide character array starting at BLOB, of
+ LENGTH wide characters, in such a way that the result string can be
+ included in a C wide string literal (in single/double quotes,
+ without putting the quotes into the result). */
+char *support_quote_blob_wide (const void *blob, size_t length);
+
/* Quote the contents of the string, in such a way that the result
string can be included in a C literal (in single/double quotes,
without putting the quotes into the result). */
diff --git a/support/support_quote_blob.c b/support/support_quote_blob.c
index b5e70125f13eb081..611980c9a2108670 100644
--- a/support/support_quote_blob.c
+++ b/support/support_quote_blob.c
@@ -1,4 +1,4 @@
-/* Quote a blob so that it can be used in C literals.
+/* Quote a narrow string blob so that it can be used in C literals.
Copyright (C) 2018-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,68 +16,9 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <support/support.h>
-#include <support/xmemstream.h>
+#define CHAR unsigned char
+#define L_(C) C
+#define SUPPORT_QUOTE_BLOB support_quote_blob
+#define WIDE 0
-char *
-support_quote_blob (const void *blob, size_t length)
-{
- struct xmemstream out;
- xopen_memstream (&out);
-
- const unsigned char *p = blob;
- for (size_t i = 0; i < length; ++i)
- {
- unsigned char ch = p[i];
-
- /* Use C backslash escapes for those control characters for
- which they are defined. */
- switch (ch)
- {
- case '\a':
- putc_unlocked ('\\', out.out);
- putc_unlocked ('a', out.out);
- break;
- case '\b':
- putc_unlocked ('\\', out.out);
- putc_unlocked ('b', out.out);
- break;
- case '\f':
- putc_unlocked ('\\', out.out);
- putc_unlocked ('f', out.out);
- break;
- case '\n':
- putc_unlocked ('\\', out.out);
- putc_unlocked ('n', out.out);
- break;
- case '\r':
- putc_unlocked ('\\', out.out);
- putc_unlocked ('r', out.out);
- break;
- case '\t':
- putc_unlocked ('\\', out.out);
- putc_unlocked ('t', out.out);
- break;
- case '\v':
- putc_unlocked ('\\', out.out);
- putc_unlocked ('v', out.out);
- break;
- case '\\':
- case '\'':
- case '\"':
- putc_unlocked ('\\', out.out);
- putc_unlocked (ch, out.out);
- break;
- default:
- if (ch < ' ' || ch > '~')
- /* Use octal sequences because they are fixed width,
- unlike hexadecimal sequences. */
- fprintf (out.out, "\\%03o", ch);
- else
- putc_unlocked (ch, out.out);
- }
- }
-
- xfclose_memstream (&out);
- return out.buffer;
-}
+#include "support_quote_blob_main.c"
diff --git a/support/support_quote_blob_main.c b/support/support_quote_blob_main.c
new file mode 100644
index 0000000000000000..19ccfad59311bfee
--- /dev/null
+++ b/support/support_quote_blob_main.c
@@ -0,0 +1,88 @@
+/* Quote a blob so that it can be used in C literals.
+ Copyright (C) 2018-2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <support/support.h>
+#include <support/xmemstream.h>
+
+char *
+SUPPORT_QUOTE_BLOB (const void *blob, size_t length)
+{
+ struct xmemstream out;
+ xopen_memstream (&out);
+
+ const CHAR *p = blob;
+ for (size_t i = 0; i < length; ++i)
+ {
+ CHAR ch = p[i];
+
+ /* Use C backslash escapes for those control characters for
+ which they are defined. */
+ switch (ch)
+ {
+ case L_('\a'):
+ putc_unlocked ('\\', out.out);
+ putc_unlocked ('a', out.out);
+ break;
+ case L_('\b'):
+ putc_unlocked ('\\', out.out);
+ putc_unlocked ('b', out.out);
+ break;
+ case L_('\f'):
+ putc_unlocked ('\\', out.out);
+ putc_unlocked ('f', out.out);
+ break;
+ case L_('\n'):
+ putc_unlocked ('\\', out.out);
+ putc_unlocked ('n', out.out);
+ break;
+ case L_('\r'):
+ putc_unlocked ('\\', out.out);
+ putc_unlocked ('r', out.out);
+ break;
+ case L_('\t'):
+ putc_unlocked ('\\', out.out);
+ putc_unlocked ('t', out.out);
+ break;
+ case L_('\v'):
+ putc_unlocked ('\\', out.out);
+ putc_unlocked ('v', out.out);
+ break;
+ case L_('\\'):
+ case L_('\''):
+ case L_('\"'):
+ putc_unlocked ('\\', out.out);
+ putc_unlocked (ch, out.out);
+ break;
+ default:
+ if (ch < L_(' ') || ch > L_('~'))
+ /* For narrow characters, use octal sequences because they
+ are fixed width, unlike hexadecimal sequences. For
+ wide characters, use N2785 delimited escape
+ sequences. */
+ if (WIDE)
+ fprintf (out.out, "\\x{%x}", (unsigned int) ch);
+ else
+ fprintf (out.out, "\\%03o", (unsigned int) ch);
+ else
+ putc_unlocked (ch, out.out);
+ }
+ }
+
+ xfclose_memstream (&out);
+ return out.buffer;
+}
diff --git a/support/support_quote_blob_wide.c b/support/support_quote_blob_wide.c
new file mode 100644
index 0000000000000000..c451ed889c21c626
--- /dev/null
+++ b/support/support_quote_blob_wide.c
@@ -0,0 +1,24 @@
+/* Quote a wide string blob so that it can be used in C literals.
+ Copyright (C) 2018-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/>. */
+
+#define CHAR wchar_t
+#define L_(C) L ## C
+#define SUPPORT_QUOTE_BLOB support_quote_blob_wide
+#define WIDE 1
+
+#include "support_quote_blob_main.c"
diff --git a/support/support_test_compare_string.c b/support/support_test_compare_string.c
index cbeaf7b1eeea8ca8..12bafe43d44ae3d7 100644
--- a/support/support_test_compare_string.c
+++ b/support/support_test_compare_string.c
@@ -16,76 +16,13 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <support/check.h>
-#include <support/support.h>
-#include <support/xmemstream.h>
-
-static void
-report_length (const char *what, const char *str, size_t length)
-{
- if (str == NULL)
- printf (" %s string: NULL\n", what);
- else
- printf (" %s string: %zu bytes\n", what, length);
-}
-
-static void
-report_string (const char *what, const unsigned char *blob,
- size_t length, const char *expr)
-{
- if (length > 0)
- {
- printf (" %s (evaluated from %s):\n", what, expr);
- char *quoted = support_quote_blob (blob, length);
- printf (" \"%s\"\n", quoted);
- free (quoted);
-
- fputs (" ", stdout);
- for (size_t i = 0; i < length; ++i)
- printf (" %02X", blob[i]);
- putc ('\n', stdout);
- }
-}
-
-static size_t
-string_length_or_zero (const char *str)
-{
- if (str == NULL)
- return 0;
- else
- return strlen (str);
-}
-
-void
-support_test_compare_string (const char *left, const char *right,
- const char *file, int line,
- const char *left_expr, const char *right_expr)
-{
- /* Two null pointers are accepted. */
- if (left == NULL && right == NULL)
- return;
-
- size_t left_length = string_length_or_zero (left);
- size_t right_length = string_length_or_zero (right);
-
- if (left_length != right_length || left == NULL || right == NULL
- || memcmp (left, right, left_length) != 0)
- {
- support_record_failure ();
- printf ("%s:%d: error: string comparison failed\n", file, line);
- if (left_length == right_length && right != NULL && left != NULL)
- printf (" string length: %zu bytes\n", left_length);
- else
- {
- report_length ("left", left, left_length);
- report_length ("right", right, right_length);
- }
- report_string ("left", (const unsigned char *) left,
- left_length, left_expr);
- report_string ("right", (const unsigned char *) right,
- right_length, right_expr);
- }
-}
+#define CHAR char
+#define UCHAR unsigned char
+#define LPREFIX ""
+#define STRLEN strlen
+#define MEMCMP memcmp
+#define SUPPORT_QUOTE_BLOB support_quote_blob
+#define SUPPORT_TEST_COMPARE_STRING support_test_compare_string
+#define WIDE 0
+
+#include "support_test_compare_string_main.c"
diff --git a/support/support_test_compare_string_main.c b/support/support_test_compare_string_main.c
new file mode 100644
index 0000000000000000..0edc0ca97d79d71e
--- /dev/null
+++ b/support/support_test_compare_string_main.c
@@ -0,0 +1,94 @@
+/* Check two strings for equality.
+ Copyright (C) 2018-2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xmemstream.h>
+
+static void
+report_length (const char *what, const CHAR *str, size_t length)
+{
+ if (str == NULL)
+ printf (" %s string: NULL\n", what);
+ else
+ printf (" %s string: %zu %s\n", what, length,
+ WIDE ? "wide characters" : "bytes");
+}
+
+static void
+report_string (const char *what, const UCHAR *blob,
+ size_t length, const char *expr)
+{
+ if (length > 0)
+ {
+ printf (" %s (evaluated from %s):\n", what, expr);
+ char *quoted = SUPPORT_QUOTE_BLOB (blob, length);
+ printf (" %s\"%s\"\n", LPREFIX, quoted);
+ free (quoted);
+
+ fputs (" ", stdout);
+ for (size_t i = 0; i < length; ++i)
+ printf (" %02X", (unsigned int) blob[i]);
+ putc ('\n', stdout);
+ }
+}
+
+static size_t
+string_length_or_zero (const CHAR *str)
+{
+ if (str == NULL)
+ return 0;
+ else
+ return STRLEN (str);
+}
+
+void
+SUPPORT_TEST_COMPARE_STRING (const CHAR *left, const CHAR *right,
+ const char *file, int line,
+ const char *left_expr, const char *right_expr)
+{
+ /* Two null pointers are accepted. */
+ if (left == NULL && right == NULL)
+ return;
+
+ size_t left_length = string_length_or_zero (left);
+ size_t right_length = string_length_or_zero (right);
+
+ if (left_length != right_length || left == NULL || right == NULL
+ || MEMCMP (left, right, left_length) != 0)
+ {
+ support_record_failure ();
+ printf ("%s:%d: error: string comparison failed\n", file, line);
+ if (left_length == right_length && right != NULL && left != NULL)
+ printf (" string length: %zu %s\n", left_length,
+ WIDE ? "wide characters" : "bytes");
+ else
+ {
+ report_length ("left", left, left_length);
+ report_length ("right", right, right_length);
+ }
+ report_string ("left", (const UCHAR *) left,
+ left_length, left_expr);
+ report_string ("right", (const UCHAR *) right,
+ right_length, right_expr);
+ }
+}
diff --git a/support/support_test_compare_string_wide.c b/support/support_test_compare_string_wide.c
new file mode 100644
index 0000000000000000..88b560b142a3c356
--- /dev/null
+++ b/support/support_test_compare_string_wide.c
@@ -0,0 +1,28 @@
+/* Check two wide strings for equality.
+ Copyright (C) 2018-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/>. */
+
+#define CHAR wchar_t
+#define UCHAR wchar_t
+#define LPREFIX "L"
+#define STRLEN wcslen
+#define MEMCMP wmemcmp
+#define SUPPORT_QUOTE_BLOB support_quote_blob_wide
+#define SUPPORT_TEST_COMPARE_STRING support_test_compare_string_wide
+#define WIDE 1
+
+#include "support_test_compare_string_main.c"
diff --git a/support/tst-support_quote_blob_wide.c b/support/tst-support_quote_blob_wide.c
new file mode 100644
index 0000000000000000..ea71a1f7f873b23a
--- /dev/null
+++ b/support/tst-support_quote_blob_wide.c
@@ -0,0 +1,66 @@
+/* Test the support_quote_blob_wide function.
+ Copyright (C) 2018-2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/support.h>
+#include <string.h>
+#include <stdlib.h>
+
+static int
+do_test (void)
+{
+ /* Check handling of the empty blob, both with and without trailing
+ NUL byte. */
+ char *p = support_quote_blob_wide (L"", 0);
+ TEST_COMPARE (strlen (p), 0);
+ free (p);
+ p = support_quote_blob_wide (L"X", 0);
+ TEST_COMPARE (strlen (p), 0);
+ free (p);
+
+ /* Check escaping of backslash-escaped characters, and lack of
+ escaping for other shell meta-characters. */
+ p = support_quote_blob_wide (L"$()*?`@[]{}~\'\"X", 14);
+ TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\""), 0);
+ free (p);
+
+ /* Check lack of escaping for letters and digits. */
+#define LETTERS_AND_DIGTS \
+ "abcdefghijklmnopqrstuvwxyz" \
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+ "0123456789"
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define WLETTERS_AND_DIGTS CONCAT (L, LETTERS_AND_DIGTS)
+ p = support_quote_blob_wide (WLETTERS_AND_DIGTS "@", 2 * 26 + 10);
+ TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS), 0);
+ free (p);
+
+ /* Check escaping of control characters and other non-printable
+ characters. */
+ p = support_quote_blob_wide (L"\r\n\t\a\b\f\v\1\177\200\377"
+ "\x123\x76543210\xfedcba98\0@", 17);
+ TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\x{1}"
+ "\\x{7f}\\x{80}\\x{ff}\\x{123}\\x{76543210}"
+ "\\x{fedcba98}\\x{0}@\\x{0}"), 0);
+ free (p);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/support/tst-test_compare_string_wide.c b/support/tst-test_compare_string_wide.c
new file mode 100644
index 0000000000000000..548f7dcdc60b82d8
--- /dev/null
+++ b/support/tst-test_compare_string_wide.c
@@ -0,0 +1,107 @@
+/* Basic test for the TEST_COMPARE_STRING_WIDE macro.
+ Copyright (C) 2018-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 <string.h>
+#include <support/check.h>
+#include <support/capture_subprocess.h>
+
+static void
+subprocess (void *closure)
+{
+ /* These tests should fail. They were chosen to cover differences
+ in length (with the same contents), single-bit mismatches, and
+ mismatching null pointers. */
+ TEST_COMPARE_STRING_WIDE (L"", NULL); /* Line 29. */
+ TEST_COMPARE_STRING_WIDE (L"X", L""); /* Line 30. */
+ TEST_COMPARE_STRING_WIDE (NULL, L"X"); /* Line 31. */
+ TEST_COMPARE_STRING_WIDE (L"abcd", L"abcD"); /* Line 32. */
+ TEST_COMPARE_STRING_WIDE (L"abcd", NULL); /* Line 33. */
+ TEST_COMPARE_STRING_WIDE (NULL, L"abcd"); /* Line 34. */
+}
+
+/* Same contents, different addresses. */
+wchar_t buffer_abc_1[] = L"abc";
+wchar_t buffer_abc_2[] = L"abc";
+
+static int
+do_test (void)
+{
+ /* This should succeed. Even if the pointers and array contents are
+ different, zero-length inputs are not different. */
+ TEST_COMPARE_STRING_WIDE (NULL, NULL);
+ TEST_COMPARE_STRING_WIDE (L"", L"");
+ TEST_COMPARE_STRING_WIDE (buffer_abc_1, buffer_abc_2);
+ TEST_COMPARE_STRING_WIDE (buffer_abc_1, L"abc");
+
+ struct support_capture_subprocess proc = support_capture_subprocess
+ (&subprocess, NULL);
+
+ /* Discard the reported error. */
+ support_record_failure_reset ();
+
+ puts ("info: *** subprocess output starts ***");
+ fputs (proc.out.buffer, stdout);
+ puts ("info: *** subprocess output ends ***");
+
+ TEST_VERIFY
+ (strcmp (proc.out.buffer,
+"tst-test_compare_string_wide.c:29: error: string comparison failed\n"
+" left string: 0 wide characters\n"
+" right string: NULL\n"
+"tst-test_compare_string_wide.c:30: error: string comparison failed\n"
+" left string: 1 wide characters\n"
+" right string: 0 wide characters\n"
+" left (evaluated from L\"X\"):\n"
+" L\"X\"\n"
+" 58\n"
+"tst-test_compare_string_wide.c:31: error: string comparison failed\n"
+" left string: NULL\n"
+" right string: 1 wide characters\n"
+" right (evaluated from L\"X\"):\n"
+" L\"X\"\n"
+" 58\n"
+"tst-test_compare_string_wide.c:32: error: string comparison failed\n"
+" string length: 4 wide characters\n"
+" left (evaluated from L\"abcd\"):\n"
+" L\"abcd\"\n"
+" 61 62 63 64\n"
+" right (evaluated from L\"abcD\"):\n"
+" L\"abcD\"\n"
+" 61 62 63 44\n"
+"tst-test_compare_string_wide.c:33: error: string comparison failed\n"
+" left string: 4 wide characters\n"
+" right string: NULL\n"
+" left (evaluated from L\"abcd\"):\n"
+" L\"abcd\"\n"
+" 61 62 63 64\n"
+"tst-test_compare_string_wide.c:34: error: string comparison failed\n"
+" left string: NULL\n"
+" right string: 4 wide characters\n"
+" right (evaluated from L\"abcd\"):\n"
+" L\"abcd\"\n"
+" 61 62 63 64\n"
+ ) == 0);
+
+ /* Check that there is no output on standard error. */
+ support_capture_subprocess_check (&proc, "TEST_COMPARE_STRING_WIDE",
+ 0, sc_allow_stdout);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -0,0 +1,691 @@
commit 7e0ad15c0fbfe25435c1acd0ed3e9cedfbff2488
Author: Carlos O'Donell <carlos@redhat.com>
Date: Mon Jan 31 00:34:42 2022 -0500
localedata: Adjust C.UTF-8 to align with C/POSIX.
We have had one downstream report from Canonical [1] that
an rrdtool test was broken by the differences in LC_TIME
that we had in the non-builtin C locale (C.UTF-8). If one
application has an issue there are going to be others, and
so with this commit we review and fix all the issues that
cause the builtin C locale to be different from C.UTF-8,
which includes:
* mon_decimal_point should be empty e.g. ""
- Depends on mon_decimal_point_wc fix.
* negative_sign should be empty e.g. ""
* week should be aligned with the builtin C/POSIX locale
* d_fmt corrected with escaped slashes e.g. "%m//%d//%y"
* yesstr and nostr should be empty e.g. ""
* country_ab2 and country_ab3 should be empty e.g. ""
We bump LC_IDENTIFICATION version and adjust the date to
indicate the change in the locale.
A new tst-c-utf8-consistency test is added to ensure
consistency between C/POSIX and C.UTF-8.
Tested on x86_64 and i686 without regression.
[1] https://sourceware.org/pipermail/libc-alpha/2022-January/135703.html
Co-authored-by: Florian Weimer <fweimer@redhat.com>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
diff --git a/localedata/Makefile b/localedata/Makefile
index c9dd5a954e8194cc..5830b9d05141cccd 100644
--- a/localedata/Makefile
+++ b/localedata/Makefile
@@ -155,11 +155,31 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl \
tst_wcsxfrm tst_wctob tst_wctomb tst_wctrans \
tst_wctype tst_wcwidth
-tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
- tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \
- tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
- tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \
- tst-wctype tst-iconv-math-trans
+tests = \
+ $(locale_test_suite) \
+ bug-iconv-trans \
+ bug-setlocale1 \
+ bug-usesetlocale \
+ tst-c-utf8-consistency \
+ tst-digits \
+ tst-iconv-math-trans \
+ tst-leaks \
+ tst-mbswcs1 \
+ tst-mbswcs2 \
+ tst-mbswcs3 \
+ tst-mbswcs4 \
+ tst-mbswcs5 \
+ tst-mbswcs6 \
+ tst-setlocale \
+ tst-setlocale2 \
+ tst-setlocale3 \
+ tst-sscanf \
+ tst-strfmon1 \
+ tst-wctype \
+ tst-xlocale1 \
+ tst-xlocale2 \
+ # tests
+
tests-static = bug-setlocale1-static
tests += $(tests-static)
ifeq (yes,$(build-shared))
diff --git a/localedata/locales/C b/localedata/locales/C
index ca801c79cf7e953e..fc0614e551519c6b 100644
--- a/localedata/locales/C
+++ b/localedata/locales/C
@@ -12,8 +12,8 @@ tel ""
fax ""
language ""
territory ""
-revision "2.0"
-date "2020-06-28"
+revision "2.1"
+date "2022-01-30"
category "i18n:2012";LC_IDENTIFICATION
category "i18n:2012";LC_CTYPE
category "i18n:2012";LC_COLLATE
@@ -68,11 +68,11 @@ LC_MONETARY
% glibc/locale/C-monetary.c.).
int_curr_symbol ""
currency_symbol ""
-mon_decimal_point "."
+mon_decimal_point ""
mon_thousands_sep ""
mon_grouping -1
positive_sign ""
-negative_sign "-"
+negative_sign ""
int_frac_digits -1
frac_digits -1
p_cs_precedes -1
@@ -121,7 +121,9 @@ mon "January";"February";"March";"April";"May";"June";"July";/
%
% ISO 8601 conforming applications should use the values 7, 19971201 (a
% Monday), and 4 (Thursday), respectively.
-week 7;19971201;4
+%
+% This field is consciously aligned with the builtin C/POSIX locale.
+week 7;19971130;4
first_weekday 1
first_workday 2
@@ -129,7 +131,7 @@ first_workday 2
d_t_fmt "%a %b %e %H:%M:%S %Y"
% Appropriate date representation (%x)
-d_fmt "%m/%d/%y"
+d_fmt "%m//%d//%y"
% Appropriate time representation (%X)
t_fmt "%H:%M:%S"
@@ -150,8 +152,8 @@ LC_MESSAGES
%
yesexpr "^[yY]"
noexpr "^[nN]"
-yesstr "Yes"
-nostr "No"
+yesstr ""
+nostr ""
END LC_MESSAGES
LC_PAPER
@@ -175,6 +177,10 @@ LC_ADDRESS
% the LC_ADDRESS category.
% (also used in the built in C/POSIX locale in glibc/locale/C-address.c)
postal_fmt "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N"
+% The abbreviated 2 char and 3 char should be set to empty strings to
+% match the C/POSIX locale.
+country_ab2 ""
+country_ab3 ""
END LC_ADDRESS
LC_TELEPHONE
diff --git a/localedata/tst-c-utf8-consistency.c b/localedata/tst-c-utf8-consistency.c
new file mode 100644
index 0000000000000000..50feed3090df0ff1
--- /dev/null
+++ b/localedata/tst-c-utf8-consistency.c
@@ -0,0 +1,539 @@
+/* Test that C/POSIX and C.UTF-8 are consistent.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <langinfo.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <support/check.h>
+
+/* Initialized by do_test using newlocale. */
+static locale_t c_utf8;
+
+/* Set to true for second pass. */
+static bool use_nl_langinfo_l;
+
+static void
+switch_to_c (void)
+{
+ if (setlocale (LC_ALL, "C") == NULL)
+ FAIL_EXIT1 ("setlocale (LC_ALL, \"C\")");
+}
+
+static void
+switch_to_c_utf8 (void)
+{
+ if (setlocale (LC_ALL, "C.UTF-8") == NULL)
+ FAIL_EXIT1 ("setlocale (LC_ALL, \"C.UTF-8\")");
+}
+
+static char *
+str (nl_item item)
+{
+ if (!use_nl_langinfo_l)
+ switch_to_c ();
+ return nl_langinfo (item);
+}
+
+static char *
+str_utf8 (nl_item item)
+{
+ if (use_nl_langinfo_l)
+ return nl_langinfo_l (item, c_utf8);
+ else
+ {
+ switch_to_c_utf8 ();
+ return nl_langinfo (item);
+ }
+}
+
+static wchar_t *
+wstr (nl_item item)
+{
+ return (wchar_t *) str (item);
+}
+
+static wchar_t *
+wstr_utf8 (nl_item item)
+{
+ return (wchar_t *) str_utf8 (item);
+}
+
+static int
+byte (nl_item item)
+{
+ return (signed char) *str (item);
+}
+
+static int
+byte_utf8 (nl_item item)
+{
+ return (signed char) *str_utf8 (item);
+}
+
+static int
+word (nl_item item)
+{
+ union
+ {
+ char *ptr;
+ int word;
+ } u;
+ u.ptr = str (item);
+ return u.word;
+}
+
+static int
+word_utf8 (nl_item item)
+{
+ union
+ {
+ char *ptr;
+ int word;
+ } u;
+ u.ptr = str_utf8 (item);
+ return u.word;
+}
+
+static void
+one_pass (void)
+{
+ /* LC_TIME. */
+ TEST_COMPARE_STRING (str (ABDAY_1), str_utf8 (ABDAY_1));
+ TEST_COMPARE_STRING (str (ABDAY_2), str_utf8 (ABDAY_2));
+ TEST_COMPARE_STRING (str (ABDAY_3), str_utf8 (ABDAY_3));
+ TEST_COMPARE_STRING (str (ABDAY_4), str_utf8 (ABDAY_4));
+ TEST_COMPARE_STRING (str (ABDAY_5), str_utf8 (ABDAY_5));
+ TEST_COMPARE_STRING (str (ABDAY_6), str_utf8 (ABDAY_6));
+ TEST_COMPARE_STRING (str (ABDAY_7), str_utf8 (ABDAY_7));
+
+ TEST_COMPARE_STRING (str (DAY_1), str_utf8 (DAY_1));
+ TEST_COMPARE_STRING (str (DAY_2), str_utf8 (DAY_2));
+ TEST_COMPARE_STRING (str (DAY_3), str_utf8 (DAY_3));
+ TEST_COMPARE_STRING (str (DAY_4), str_utf8 (DAY_4));
+ TEST_COMPARE_STRING (str (DAY_5), str_utf8 (DAY_5));
+ TEST_COMPARE_STRING (str (DAY_6), str_utf8 (DAY_6));
+ TEST_COMPARE_STRING (str (DAY_7), str_utf8 (DAY_7));
+
+ TEST_COMPARE_STRING (str (ABMON_1), str_utf8 (ABMON_1));
+ TEST_COMPARE_STRING (str (ABMON_2), str_utf8 (ABMON_2));
+ TEST_COMPARE_STRING (str (ABMON_3), str_utf8 (ABMON_3));
+ TEST_COMPARE_STRING (str (ABMON_4), str_utf8 (ABMON_4));
+ TEST_COMPARE_STRING (str (ABMON_5), str_utf8 (ABMON_5));
+ TEST_COMPARE_STRING (str (ABMON_6), str_utf8 (ABMON_6));
+ TEST_COMPARE_STRING (str (ABMON_7), str_utf8 (ABMON_7));
+ TEST_COMPARE_STRING (str (ABMON_8), str_utf8 (ABMON_8));
+ TEST_COMPARE_STRING (str (ABMON_9), str_utf8 (ABMON_9));
+ TEST_COMPARE_STRING (str (ABMON_10), str_utf8 (ABMON_10));
+ TEST_COMPARE_STRING (str (ABMON_11), str_utf8 (ABMON_11));
+ TEST_COMPARE_STRING (str (ABMON_12), str_utf8 (ABMON_12));
+
+ TEST_COMPARE_STRING (str (MON_1), str_utf8 (MON_1));
+ TEST_COMPARE_STRING (str (MON_2), str_utf8 (MON_2));
+ TEST_COMPARE_STRING (str (MON_3), str_utf8 (MON_3));
+ TEST_COMPARE_STRING (str (MON_4), str_utf8 (MON_4));
+ TEST_COMPARE_STRING (str (MON_5), str_utf8 (MON_5));
+ TEST_COMPARE_STRING (str (MON_6), str_utf8 (MON_6));
+ TEST_COMPARE_STRING (str (MON_7), str_utf8 (MON_7));
+ TEST_COMPARE_STRING (str (MON_8), str_utf8 (MON_8));
+ TEST_COMPARE_STRING (str (MON_9), str_utf8 (MON_9));
+ TEST_COMPARE_STRING (str (MON_10), str_utf8 (MON_10));
+ TEST_COMPARE_STRING (str (MON_11), str_utf8 (MON_11));
+ TEST_COMPARE_STRING (str (MON_12), str_utf8 (MON_12));
+
+ TEST_COMPARE_STRING (str (AM_STR), str_utf8 (AM_STR));
+ TEST_COMPARE_STRING (str (PM_STR), str_utf8 (PM_STR));
+
+ TEST_COMPARE_STRING (str (D_T_FMT), str_utf8 (D_T_FMT));
+ TEST_COMPARE_STRING (str (D_FMT), str_utf8 (D_FMT));
+ TEST_COMPARE_STRING (str (T_FMT), str_utf8 (T_FMT));
+ TEST_COMPARE_STRING (str (T_FMT_AMPM),
+ str_utf8 (T_FMT_AMPM));
+
+ TEST_COMPARE_STRING (str (ERA), str_utf8 (ERA));
+ TEST_COMPARE_STRING (str (ERA_YEAR), str_utf8 (ERA_YEAR));
+ TEST_COMPARE_STRING (str (ERA_D_FMT), str_utf8 (ERA_D_FMT));
+ TEST_COMPARE_STRING (str (ALT_DIGITS), str_utf8 (ALT_DIGITS));
+ TEST_COMPARE_STRING (str (ERA_D_T_FMT), str_utf8 (ERA_D_T_FMT));
+ TEST_COMPARE_STRING (str (ERA_T_FMT), str_utf8 (ERA_T_FMT));
+ TEST_COMPARE (word (_NL_TIME_ERA_NUM_ENTRIES),
+ word_utf8 (_NL_TIME_ERA_NUM_ENTRIES));
+ /* No array elements, so nothing to compare for _NL_TIME_ERA_ENTRIES. */
+ TEST_COMPARE (word (_NL_TIME_ERA_NUM_ENTRIES), 0);
+
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_1), wstr_utf8 (_NL_WABDAY_1));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_2), wstr_utf8 (_NL_WABDAY_2));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_3), wstr_utf8 (_NL_WABDAY_3));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_4), wstr_utf8 (_NL_WABDAY_4));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_5), wstr_utf8 (_NL_WABDAY_5));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_6), wstr_utf8 (_NL_WABDAY_6));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_7), wstr_utf8 (_NL_WABDAY_7));
+
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_1), wstr_utf8 (_NL_WDAY_1));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_2), wstr_utf8 (_NL_WDAY_2));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_3), wstr_utf8 (_NL_WDAY_3));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_4), wstr_utf8 (_NL_WDAY_4));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_5), wstr_utf8 (_NL_WDAY_5));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_6), wstr_utf8 (_NL_WDAY_6));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_7), wstr_utf8 (_NL_WDAY_7));
+
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_1), wstr_utf8 (_NL_WABMON_1));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_2), wstr_utf8 (_NL_WABMON_2));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_3), wstr_utf8 (_NL_WABMON_3));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_4), wstr_utf8 (_NL_WABMON_4));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_5), wstr_utf8 (_NL_WABMON_5));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_6), wstr_utf8 (_NL_WABMON_6));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_7), wstr_utf8 (_NL_WABMON_7));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_8), wstr_utf8 (_NL_WABMON_8));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_9), wstr_utf8 (_NL_WABMON_9));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_10), wstr_utf8 (_NL_WABMON_10));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_11), wstr_utf8 (_NL_WABMON_11));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_12), wstr_utf8 (_NL_WABMON_12));
+
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_1), wstr_utf8 (_NL_WMON_1));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_2), wstr_utf8 (_NL_WMON_2));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_3), wstr_utf8 (_NL_WMON_3));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_4), wstr_utf8 (_NL_WMON_4));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_5), wstr_utf8 (_NL_WMON_5));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_6), wstr_utf8 (_NL_WMON_6));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_7), wstr_utf8 (_NL_WMON_7));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_8), wstr_utf8 (_NL_WMON_8));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_9), wstr_utf8 (_NL_WMON_9));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_10), wstr_utf8 (_NL_WMON_10));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_11), wstr_utf8 (_NL_WMON_11));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_12), wstr_utf8 (_NL_WMON_12));
+
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WAM_STR), wstr_utf8 (_NL_WAM_STR));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WPM_STR), wstr_utf8 (_NL_WPM_STR));
+
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WD_T_FMT), wstr_utf8 (_NL_WD_T_FMT));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WD_FMT), wstr_utf8 (_NL_WD_FMT));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WT_FMT), wstr_utf8 (_NL_WT_FMT));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WT_FMT_AMPM),
+ wstr_utf8 (_NL_WT_FMT_AMPM));
+
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_YEAR), wstr_utf8 (_NL_WERA_YEAR));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_D_FMT), wstr_utf8 (_NL_WERA_D_FMT));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALT_DIGITS),
+ wstr_utf8 (_NL_WALT_DIGITS));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_D_T_FMT),
+ wstr_utf8 (_NL_WERA_D_T_FMT));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_T_FMT), wstr_utf8 (_NL_WERA_T_FMT));
+
+ /* This is somewhat inconsistent, but see locale/categories.def. */
+ TEST_COMPARE (byte (_NL_TIME_WEEK_NDAYS), byte_utf8 (_NL_TIME_WEEK_NDAYS));
+ TEST_COMPARE (word (_NL_TIME_WEEK_1STDAY),
+ word_utf8 (_NL_TIME_WEEK_1STDAY));
+ TEST_COMPARE (byte (_NL_TIME_WEEK_1STWEEK),
+ byte_utf8 (_NL_TIME_WEEK_1STWEEK));
+ TEST_COMPARE (byte (_NL_TIME_FIRST_WEEKDAY),
+ byte_utf8 (_NL_TIME_FIRST_WEEKDAY));
+ TEST_COMPARE (byte (_NL_TIME_FIRST_WORKDAY),
+ byte_utf8 (_NL_TIME_FIRST_WORKDAY));
+ TEST_COMPARE (byte (_NL_TIME_CAL_DIRECTION),
+ byte_utf8 (_NL_TIME_CAL_DIRECTION));
+ TEST_COMPARE_STRING (str (_NL_TIME_TIMEZONE), str_utf8 (_NL_TIME_TIMEZONE));
+
+ TEST_COMPARE_STRING (str (_DATE_FMT), str_utf8 (_DATE_FMT));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_W_DATE_FMT), wstr_utf8 (_NL_W_DATE_FMT));
+
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_TIME_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_TIME_CODESET), "UTF-8");
+
+ TEST_COMPARE_STRING (str (ALTMON_1), str_utf8 (ALTMON_1));
+ TEST_COMPARE_STRING (str (ALTMON_2), str_utf8 (ALTMON_2));
+ TEST_COMPARE_STRING (str (ALTMON_3), str_utf8 (ALTMON_3));
+ TEST_COMPARE_STRING (str (ALTMON_4), str_utf8 (ALTMON_4));
+ TEST_COMPARE_STRING (str (ALTMON_5), str_utf8 (ALTMON_5));
+ TEST_COMPARE_STRING (str (ALTMON_6), str_utf8 (ALTMON_6));
+ TEST_COMPARE_STRING (str (ALTMON_7), str_utf8 (ALTMON_7));
+ TEST_COMPARE_STRING (str (ALTMON_8), str_utf8 (ALTMON_8));
+ TEST_COMPARE_STRING (str (ALTMON_9), str_utf8 (ALTMON_9));
+ TEST_COMPARE_STRING (str (ALTMON_10), str_utf8 (ALTMON_10));
+ TEST_COMPARE_STRING (str (ALTMON_11), str_utf8 (ALTMON_11));
+ TEST_COMPARE_STRING (str (ALTMON_12), str_utf8 (ALTMON_12));
+
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_1), wstr_utf8 (_NL_WALTMON_1));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_2), wstr_utf8 (_NL_WALTMON_2));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_3), wstr_utf8 (_NL_WALTMON_3));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_4), wstr_utf8 (_NL_WALTMON_4));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_5), wstr_utf8 (_NL_WALTMON_5));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_6), wstr_utf8 (_NL_WALTMON_6));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_7), wstr_utf8 (_NL_WALTMON_7));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_8), wstr_utf8 (_NL_WALTMON_8));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_9), wstr_utf8 (_NL_WALTMON_9));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_10), wstr_utf8 (_NL_WALTMON_10));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_11), wstr_utf8 (_NL_WALTMON_11));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_12), wstr_utf8 (_NL_WALTMON_12));
+
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_1), str_utf8 (_NL_ABALTMON_1));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_2), str_utf8 (_NL_ABALTMON_2));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_3), str_utf8 (_NL_ABALTMON_3));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_4), str_utf8 (_NL_ABALTMON_4));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_5), str_utf8 (_NL_ABALTMON_5));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_6), str_utf8 (_NL_ABALTMON_6));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_7), str_utf8 (_NL_ABALTMON_7));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_8), str_utf8 (_NL_ABALTMON_8));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_9), str_utf8 (_NL_ABALTMON_9));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_10), str_utf8 (_NL_ABALTMON_10));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_11), str_utf8 (_NL_ABALTMON_11));
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_12), str_utf8 (_NL_ABALTMON_12));
+
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_1),
+ wstr_utf8 (_NL_WABALTMON_1));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_2),
+ wstr_utf8 (_NL_WABALTMON_2));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_3),
+ wstr_utf8 (_NL_WABALTMON_3));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_4),
+ wstr_utf8 (_NL_WABALTMON_4));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_5),
+ wstr_utf8 (_NL_WABALTMON_5));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_6),
+ wstr_utf8 (_NL_WABALTMON_6));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_7),
+ wstr_utf8 (_NL_WABALTMON_7));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_8),
+ wstr_utf8 (_NL_WABALTMON_8));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_9),
+ wstr_utf8 (_NL_WABALTMON_9));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_10),
+ wstr_utf8 (_NL_WABALTMON_10));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_11),
+ wstr_utf8 (_NL_WABALTMON_11));
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_12),
+ wstr_utf8 (_NL_WABALTMON_12));
+
+ /* LC_COLLATE. Mostly untested, only expected differences. */
+ TEST_COMPARE_STRING (str (_NL_COLLATE_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_COLLATE_CODESET), "UTF-8");
+
+ /* LC_CTYPE. Mostly untested, only expected differences. */
+ TEST_COMPARE_STRING (str (CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (CODESET), "UTF-8");
+
+ /* LC_MONETARY. */
+ TEST_COMPARE_STRING (str (INT_CURR_SYMBOL), str_utf8 (INT_CURR_SYMBOL));
+ TEST_COMPARE_STRING (str (CURRENCY_SYMBOL), str_utf8 (CURRENCY_SYMBOL));
+ TEST_COMPARE_STRING (str (MON_DECIMAL_POINT), str_utf8 (MON_DECIMAL_POINT));
+ TEST_COMPARE_STRING (str (MON_THOUSANDS_SEP), str_utf8 (MON_THOUSANDS_SEP));
+ TEST_COMPARE_STRING (str (MON_GROUPING), str_utf8 (MON_GROUPING));
+ TEST_COMPARE_STRING (str (POSITIVE_SIGN), str_utf8 (POSITIVE_SIGN));
+ TEST_COMPARE_STRING (str (NEGATIVE_SIGN), str_utf8 (NEGATIVE_SIGN));
+ TEST_COMPARE (byte (INT_FRAC_DIGITS), byte_utf8 (INT_FRAC_DIGITS));
+ TEST_COMPARE (byte (FRAC_DIGITS), byte_utf8 (FRAC_DIGITS));
+ TEST_COMPARE (byte (P_CS_PRECEDES), byte_utf8 (P_CS_PRECEDES));
+ TEST_COMPARE (byte (P_SEP_BY_SPACE), byte_utf8 (P_SEP_BY_SPACE));
+ TEST_COMPARE (byte (N_CS_PRECEDES), byte_utf8 (N_CS_PRECEDES));
+ TEST_COMPARE (byte (N_SEP_BY_SPACE), byte_utf8 (N_SEP_BY_SPACE));
+ TEST_COMPARE (byte (P_SIGN_POSN), byte_utf8 (P_SIGN_POSN));
+ TEST_COMPARE (byte (N_SIGN_POSN), byte_utf8 (N_SIGN_POSN));
+ TEST_COMPARE_STRING (str (CRNCYSTR), str_utf8 (CRNCYSTR));
+ TEST_COMPARE (byte (INT_P_CS_PRECEDES), byte_utf8 (INT_P_CS_PRECEDES));
+ TEST_COMPARE (byte (INT_P_SEP_BY_SPACE), byte_utf8 (INT_P_SEP_BY_SPACE));
+ TEST_COMPARE (byte (INT_N_CS_PRECEDES), byte_utf8 (INT_N_CS_PRECEDES));
+ TEST_COMPARE (byte (INT_N_SEP_BY_SPACE), byte_utf8 (INT_N_SEP_BY_SPACE));
+ TEST_COMPARE (byte (INT_P_SIGN_POSN), byte_utf8 (INT_P_SIGN_POSN));
+ TEST_COMPARE (byte (INT_N_SIGN_POSN), byte_utf8 (INT_N_SIGN_POSN));
+ TEST_COMPARE_STRING (str (_NL_MONETARY_DUO_INT_CURR_SYMBOL),
+ str_utf8 (_NL_MONETARY_DUO_INT_CURR_SYMBOL));
+ TEST_COMPARE_STRING (str (_NL_MONETARY_DUO_CURRENCY_SYMBOL),
+ str_utf8 (_NL_MONETARY_DUO_CURRENCY_SYMBOL));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_FRAC_DIGITS),
+ byte_utf8 (_NL_MONETARY_DUO_INT_FRAC_DIGITS));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_FRAC_DIGITS),
+ byte_utf8 (_NL_MONETARY_DUO_FRAC_DIGITS));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_P_CS_PRECEDES),
+ byte_utf8 (_NL_MONETARY_DUO_P_CS_PRECEDES));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_P_SEP_BY_SPACE),
+ byte_utf8 (_NL_MONETARY_DUO_P_SEP_BY_SPACE));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_N_CS_PRECEDES),
+ byte_utf8 (_NL_MONETARY_DUO_N_CS_PRECEDES));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_N_SEP_BY_SPACE),
+ byte_utf8 (_NL_MONETARY_DUO_N_SEP_BY_SPACE));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_CS_PRECEDES),
+ byte_utf8 (_NL_MONETARY_DUO_INT_P_CS_PRECEDES));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_SEP_BY_SPACE),
+ byte_utf8 (_NL_MONETARY_DUO_INT_P_SEP_BY_SPACE));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_CS_PRECEDES),
+ byte_utf8 (_NL_MONETARY_DUO_INT_N_CS_PRECEDES));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_SEP_BY_SPACE),
+ byte_utf8 (_NL_MONETARY_DUO_INT_N_SEP_BY_SPACE));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_SIGN_POSN),
+ byte_utf8 (_NL_MONETARY_DUO_INT_P_SIGN_POSN));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_SIGN_POSN),
+ byte_utf8 (_NL_MONETARY_DUO_INT_N_SIGN_POSN));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_P_SIGN_POSN),
+ byte_utf8 (_NL_MONETARY_DUO_P_SIGN_POSN));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_N_SIGN_POSN),
+ byte_utf8 (_NL_MONETARY_DUO_N_SIGN_POSN));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_SIGN_POSN),
+ byte_utf8 (_NL_MONETARY_DUO_INT_P_SIGN_POSN));
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_SIGN_POSN),
+ byte_utf8 (_NL_MONETARY_DUO_INT_N_SIGN_POSN));
+ TEST_COMPARE (word (_NL_MONETARY_UNO_VALID_FROM),
+ word_utf8 (_NL_MONETARY_UNO_VALID_FROM));
+ TEST_COMPARE (word (_NL_MONETARY_UNO_VALID_TO),
+ word_utf8 (_NL_MONETARY_UNO_VALID_TO));
+ TEST_COMPARE (word (_NL_MONETARY_DUO_VALID_FROM),
+ word_utf8 (_NL_MONETARY_DUO_VALID_FROM));
+ TEST_COMPARE (word (_NL_MONETARY_DUO_VALID_TO),
+ word_utf8 (_NL_MONETARY_DUO_VALID_TO));
+ /* _NL_MONETARY_CONVERSION_RATE cannot be tested (word array). */
+ TEST_COMPARE (word (_NL_MONETARY_DECIMAL_POINT_WC),
+ word_utf8 (_NL_MONETARY_DECIMAL_POINT_WC));
+ TEST_COMPARE (word (_NL_MONETARY_THOUSANDS_SEP_WC),
+ word_utf8 (_NL_MONETARY_THOUSANDS_SEP_WC));
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_MONETARY_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_MONETARY_CODESET), "UTF-8");
+
+ /* LC_NUMERIC. */
+
+ TEST_COMPARE_STRING (str (DECIMAL_POINT), str_utf8 (DECIMAL_POINT));
+ TEST_COMPARE_STRING (str (RADIXCHAR), str_utf8 (RADIXCHAR));
+ TEST_COMPARE_STRING (str (THOUSANDS_SEP), str_utf8 (THOUSANDS_SEP));
+ TEST_COMPARE_STRING (str (THOUSEP), str_utf8 (THOUSEP));
+ TEST_COMPARE_STRING (str (GROUPING), str_utf8 (GROUPING));
+ TEST_COMPARE (word (_NL_NUMERIC_DECIMAL_POINT_WC),
+ word_utf8 (_NL_NUMERIC_DECIMAL_POINT_WC));
+ TEST_COMPARE (word (_NL_NUMERIC_THOUSANDS_SEP_WC),
+ word_utf8 (_NL_NUMERIC_THOUSANDS_SEP_WC));
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_NUMERIC_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_NUMERIC_CODESET), "UTF-8");
+
+ /* LC_MESSAGES. */
+
+ TEST_COMPARE_STRING (str (YESEXPR), str_utf8 (YESEXPR));
+ TEST_COMPARE_STRING (str (NOEXPR), str_utf8 (NOEXPR));
+ TEST_COMPARE_STRING (str (YESSTR), str_utf8 (YESSTR));
+ TEST_COMPARE_STRING (str (NOSTR), str_utf8 (NOSTR));
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_MESSAGES_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_MESSAGES_CODESET), "UTF-8");
+
+ /* LC_PAPER. */
+
+ TEST_COMPARE (word (_NL_PAPER_HEIGHT), word_utf8 (_NL_PAPER_HEIGHT));
+ TEST_COMPARE (word (_NL_PAPER_WIDTH), word_utf8 (_NL_PAPER_WIDTH));
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_PAPER_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_PAPER_CODESET), "UTF-8");
+
+ /* LC_NAME. */
+
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_FMT),
+ str_utf8 (_NL_NAME_NAME_FMT));
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_GEN),
+ str_utf8 (_NL_NAME_NAME_GEN));
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MR),
+ str_utf8 (_NL_NAME_NAME_MR));
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MRS),
+ str_utf8 (_NL_NAME_NAME_MRS));
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MISS),
+ str_utf8 (_NL_NAME_NAME_MISS));
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MS),
+ str_utf8 (_NL_NAME_NAME_MS));
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_NAME_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_NAME_CODESET), "UTF-8");
+
+ /* LC_ADDRESS. */
+
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_POSTAL_FMT),
+ str_utf8 (_NL_ADDRESS_POSTAL_FMT));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_NAME),
+ str_utf8 (_NL_ADDRESS_COUNTRY_NAME));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_POST),
+ str_utf8 (_NL_ADDRESS_COUNTRY_POST));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_AB2),
+ str_utf8 (_NL_ADDRESS_COUNTRY_AB2));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_AB3),
+ str_utf8 (_NL_ADDRESS_COUNTRY_AB3));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_CAR),
+ str_utf8 (_NL_ADDRESS_COUNTRY_CAR));
+ TEST_COMPARE (word (_NL_ADDRESS_COUNTRY_NUM),
+ word_utf8 (_NL_ADDRESS_COUNTRY_NUM));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_ISBN),
+ str_utf8 (_NL_ADDRESS_COUNTRY_ISBN));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_NAME),
+ str_utf8 (_NL_ADDRESS_LANG_NAME));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_AB),
+ str_utf8 (_NL_ADDRESS_LANG_AB));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_TERM),
+ str_utf8 (_NL_ADDRESS_LANG_TERM));
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_LIB),
+ str_utf8 (_NL_ADDRESS_LANG_LIB));
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_ADDRESS_CODESET), "UTF-8");
+
+ /* LC_TELEPHONE. */
+
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_TEL_INT_FMT),
+ str_utf8 (_NL_TELEPHONE_TEL_INT_FMT));
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_TEL_DOM_FMT),
+ str_utf8 (_NL_TELEPHONE_TEL_DOM_FMT));
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_INT_SELECT),
+ str_utf8 (_NL_TELEPHONE_INT_SELECT));
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_INT_PREFIX),
+ str_utf8 (_NL_TELEPHONE_INT_PREFIX));
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_TELEPHONE_CODESET), "UTF-8");
+
+ /* LC_MEASUREMENT. */
+
+ TEST_COMPARE (byte (_NL_MEASUREMENT_MEASUREMENT),
+ byte_utf8 (_NL_MEASUREMENT_MEASUREMENT));
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_MEASUREMENT_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_MEASUREMENT_CODESET), "UTF-8");
+
+ /* LC_IDENTIFICATION is skipped since C.UTF-8 is distinct from C. */
+
+ /* _NL_IDENTIFICATION_CATEGORY cannot be tested because it is a
+ string array. */
+ /* Expected difference. */
+ TEST_COMPARE_STRING (str (_NL_IDENTIFICATION_CODESET), "ANSI_X3.4-1968");
+ TEST_COMPARE_STRING (str_utf8 (_NL_IDENTIFICATION_CODESET), "UTF-8");
+}
+
+static int
+do_test (void)
+{
+ puts ("info: using setlocale and nl_langinfo");
+ one_pass ();
+
+ puts ("info: using nl_langinfo_l");
+
+ c_utf8 = newlocale (LC_ALL_MASK, "C.UTF-8", (locale_t) 0);
+ TEST_VERIFY_EXIT (c_utf8 != (locale_t) 0);
+
+ switch_to_c ();
+ use_nl_langinfo_l = true;
+ one_pass ();
+
+ freelocale (c_utf8);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -0,0 +1,98 @@
commit 84a7eb1f87c1d01b58ad887a0ab5d87abbc1c772
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Fri Jul 30 19:07:30 2021 -0700
Use __executable_start as the lowest address for profiling [BZ #28153]
Glibc assumes that ENTRY_POINT is the lowest address for which we need
to keep profiling records and BFD linker uses a linker script to place
the input sections.
Starting from GCC 4.6, the main function is placed in .text.startup
section and starting from binutils 2.22, BFD linker with
commit add44f8d5c5c05e08b11e033127a744d61c26aee
Author: Alan Modra <amodra@gmail.com>
Date: Thu Nov 25 03:03:02 2010 +0000
* scripttempl/elf.sc: Group .text.exit, text.startup and .text.hot
sections.
places .text.startup section before .text section, which leave the main
function out of profiling records.
Starting from binutils 2.15, linker provides __executable_start to mark
the lowest address of the executable. Use __executable_start as the
lowest address to keep the main function in profiling records. This fixes
[BZ #28153].
Tested on Linux/x86-64, Linux/x32 and Linux/i686 as well as with
build-many-glibcs.py.
diff --git a/csu/gmon-start.c b/csu/gmon-start.c
index b3432885b39071cc..344606a676c188d4 100644
--- a/csu/gmon-start.c
+++ b/csu/gmon-start.c
@@ -52,6 +52,11 @@ extern char ENTRY_POINT[];
#endif
extern char etext[];
+/* Use __executable_start as the lowest address to keep profiling records
+ if it provided by the linker. */
+extern const char executable_start[] asm ("__executable_start")
+ __attribute__ ((weak, visibility ("hidden")));
+
#ifndef TEXT_START
# ifdef ENTRY_POINT_DECL
# define TEXT_START ENTRY_POINT
@@ -92,7 +97,10 @@ __gmon_start__ (void)
called = 1;
/* Start keeping profiling records. */
- __monstartup ((u_long) TEXT_START, (u_long) &etext);
+ if (&executable_start != NULL)
+ __monstartup ((u_long) &executable_start, (u_long) &etext);
+ else
+ __monstartup ((u_long) TEXT_START, (u_long) &etext);
/* Call _mcleanup before exiting; it will write out gmon.out from the
collected data. */
diff --git a/gmon/tst-gmon-gprof.sh b/gmon/tst-gmon-gprof.sh
index 9d371582b99677fa..dc0be021104f725d 100644
--- a/gmon/tst-gmon-gprof.sh
+++ b/gmon/tst-gmon-gprof.sh
@@ -39,12 +39,14 @@ trap cleanup 0
cat > "$expected" <<EOF
f1 2000
f2 1000
+f3 1
EOF
# Special version for powerpc with function descriptors.
cat > "$expected_dot" <<EOF
.f1 2000
.f2 1000
+.f3 1
EOF
"$GPROF" -C "$program" "$data" \
diff --git a/gmon/tst-gmon-static-gprof.sh b/gmon/tst-gmon-static-gprof.sh
index 79218df967f9387f..4cc99c80d0115271 100644
--- a/gmon/tst-gmon-static-gprof.sh
+++ b/gmon/tst-gmon-static-gprof.sh
@@ -39,6 +39,7 @@ trap cleanup 0
cat > "$expected" <<EOF
f1 2000
f2 1000
+f3 1
main 1
EOF
@@ -46,6 +47,7 @@ EOF
cat > "$expected_dot" <<EOF
.f1 2000
.f2 1000
+.f3 1
.main 1
EOF

View File

@ -0,0 +1,74 @@
Downstream adjustment: Change return type of
rseq_register_current_thread to bool. Upstream, this was part of the
commit that introduced the ABI symbols.
commit a41c8e92350e744a4bc639df5025153d05263e7f
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Dec 9 09:49:32 2021 +0100
nptl: rseq failure after registration on main thread is fatal
This simplifies the application programming model.
Browser sandboxes have already been fixed:
Sandbox is incompatible with rseq registration
<https://bugzilla.mozilla.org/show_bug.cgi?id=1651701>
Allow rseq in the Linux sandboxes. r=gcp
<https://hg.mozilla.org/mozilla-central/rev/042425712eb1>
Sandbox needs to support rseq system call
<https://bugs.chromium.org/p/chromium/issues/detail?id=1104160>
Linux sandbox: Allow rseq(2)
<https://chromium.googlesource.com/chromium/src.git/+/230675d9ac8f1>
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index f405fa356c2955ce..109c5e3dc78c9aa2 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -371,7 +371,8 @@ start_thread (void *arg)
/* Register rseq TLS to the kernel. */
{
bool do_rseq = THREAD_GETMEM (pd, flags) & ATTR_FLAG_DO_RSEQ;
- rseq_register_current_thread (pd, do_rseq);
+ if (!rseq_register_current_thread (pd, do_rseq) && do_rseq)
+ __libc_fatal ("Fatal glibc error: rseq registration failed\n");
}
#ifndef __ASSUME_SET_ROBUST_LIST
diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
index 15bc7ffd6eda632d..6a3441f2cc49e7c4 100644
--- a/sysdeps/unix/sysv/linux/rseq-internal.h
+++ b/sysdeps/unix/sysv/linux/rseq-internal.h
@@ -26,7 +26,7 @@
#include <sys/rseq.h>
#ifdef RSEQ_SIG
-static inline void
+static inline bool
rseq_register_current_thread (struct pthread *self, bool do_rseq)
{
if (do_rseq)
@@ -35,15 +35,17 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq)
sizeof (self->rseq_area),
0, RSEQ_SIG);
if (!INTERNAL_SYSCALL_ERROR_P (ret))
- return;
+ return true;
}
THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
+ return false;
}
#else /* RSEQ_SIG */
static inline void
rseq_register_current_thread (struct pthread *self, bool do_rseq)
{
THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
+ return false;
}
#endif /* RSEQ_SIG */

View File

@ -0,0 +1,592 @@
commit 627f5ede70d70c77bdaf857db07404e8bf7f60af
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Dec 9 17:57:11 2021 +0100
Remove TLS_TCB_ALIGN and TLS_INIT_TCB_ALIGN
TLS_INIT_TCB_ALIGN is not actually used. TLS_TCB_ALIGN was likely
introduced to support a configuration where the thread pointer
has not the same alignment as THREAD_SELF. Only ia64 seems to use
that, but for the stack/pointer guard, not for storing tcbhead_t.
Some ports use TLS_TCB_OFFSET and TLS_PRE_TCB_SIZE to shift
the thread pointer, potentially landing in a different residue class
modulo the alignment, but the changes should not impact that.
In general, given that TLS variables have their own alignment
requirements, having different alignment for the (unshifted) thread
pointer and struct pthread would potentially result in dynamic
offsets, leading to more complexity.
hppa had different values before: __alignof__ (tcbhead_t), which
seems to be 4, and __alignof__ (struct pthread), which was 8
(old default) and is now 32. However, it defines THREAD_SELF as:
/* Return the thread descriptor for the current thread. */
# define THREAD_SELF \
({ struct pthread *__self; \
__self = __get_cr27(); \
__self - 1; \
})
So the thread pointer points after struct pthread (hence __self - 1),
and they have to have the same alignment on hppa as well.
Similarly, on ia64, the definitions were different. We have:
# define TLS_PRE_TCB_SIZE \
(sizeof (struct pthread) \
+ (PTHREAD_STRUCT_END_PADDING < 2 * sizeof (uintptr_t) \
? ((2 * sizeof (uintptr_t) + __alignof__ (struct pthread) - 1) \
& ~(__alignof__ (struct pthread) - 1)) \
: 0))
# define THREAD_SELF \
((struct pthread *) ((char *) __thread_self - TLS_PRE_TCB_SIZE))
And TLS_PRE_TCB_SIZE is a multiple of the struct pthread alignment
(confirmed by the new _Static_assert in sysdeps/ia64/libc-tls.c).
On m68k, we have a larger gap between tcbhead_t and struct pthread.
But as far as I can tell, the port is fine with that. The definition
of TCB_OFFSET is sufficient to handle the shifted TCB scenario.
This fixes commit 23c77f60181eb549f11ec2f913b4270af29eee38
("nptl: Increase default TCB alignment to 32").
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index 5515204863218163..d83e69f6257ae981 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <sys/param.h>
#include <array_length.h>
+#include <pthreadP.h>
#ifdef SHARED
#error makefile bug, this file is for static only
@@ -89,7 +90,7 @@ init_static_tls (size_t memsz, size_t align)
{
/* That is the size of the TLS memory for this object. */
GL(dl_tls_static_size) = roundup (memsz + GLRO(dl_tls_static_surplus),
- TLS_TCB_ALIGN);
+ TCB_ALIGNMENT);
#if TLS_TCB_AT_TP
GL(dl_tls_static_size) += TLS_TCB_SIZE;
#endif
@@ -214,5 +215,5 @@ __libc_setup_tls (void)
memsz += tcb_offset;
#endif
- init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align));
+ init_static_tls (memsz, MAX (TCB_ALIGNMENT, max_align));
}
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 40263cf586e74c64..e2012d0cd515103b 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -219,7 +219,7 @@ _dl_count_modids (void)
void
_dl_determine_tlsoffset (void)
{
- size_t max_align = TLS_TCB_ALIGN;
+ size_t max_align = TCB_ALIGNMENT;
size_t freetop = 0;
size_t freebottom = 0;
@@ -350,7 +350,7 @@ _dl_determine_tlsoffset (void)
GL(dl_tls_static_used) = offset;
GLRO (dl_tls_static_size) = roundup (offset + GLRO(dl_tls_static_surplus),
- TLS_TCB_ALIGN);
+ TCB_ALIGNMENT);
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h
index cd9abb5d1d073593..75c469d51b532a89 100644
--- a/sysdeps/aarch64/nptl/tls.h
+++ b/sysdeps/aarch64/nptl/tls.h
@@ -52,18 +52,12 @@ typedef struct
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */
# define INSTALL_DTV(tcbp, dtvp) \
diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h
index 5f4843b28e7f1ad1..c0b6c93891546480 100644
--- a/sysdeps/alpha/nptl/tls.h
+++ b/sysdeps/alpha/nptl/tls.h
@@ -46,18 +46,12 @@ typedef struct
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN 16
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN 16
-
/* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */
# define INSTALL_DTV(tcbp, dtvp) \
diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h
index d9ada2f38089e6cd..d5d282297d12ec98 100644
--- a/sysdeps/arc/nptl/tls.h
+++ b/sysdeps/arc/nptl/tls.h
@@ -48,17 +48,11 @@ typedef struct
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. */
#ifndef TLS_TCB_SIZE
# define TLS_TCB_SIZE sizeof (tcbhead_t)
#endif
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h
index 354aae3318291395..8475c66588f99cae 100644
--- a/sysdeps/arm/nptl/tls.h
+++ b/sysdeps/arm/nptl/tls.h
@@ -50,18 +50,12 @@ typedef struct
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN 16
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN 16
-
/* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */
# define INSTALL_DTV(tcbp, dtvp) \
diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h
index f3fa3fcb02748776..e81d4552d27e0378 100644
--- a/sysdeps/csky/nptl/tls.h
+++ b/sysdeps/csky/nptl/tls.h
@@ -61,15 +61,9 @@ typedef struct
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN 8
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN 8
-
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
diff --git a/sysdeps/generic/tls.h b/sysdeps/generic/tls.h
index e86d70e6cebba5c8..9214ed39b6383e8c 100644
--- a/sysdeps/generic/tls.h
+++ b/sysdeps/generic/tls.h
@@ -19,6 +19,11 @@
/* An architecture-specific version of this file has to defined a
number of symbols:
+ TCB_ALIGNMENT
+
+ Alignment of THREAD_SELF (struct pthread *) and the thread
+ pointer.
+
TLS_TCB_AT_TP or TLS_DTV_AT_TP
The presence of one of these symbols signals which variant of
@@ -43,15 +48,6 @@
dynamic linker itself. There are no threads in use at that time.
- TLS_TCB_ALIGN
-
- Alignment requirements for the TCB structure.
-
- TLS_INIT_TCB_ALIGN
-
- Similarly, but for the structure used at startup time.
-
-
INSTALL_DTV(tcb, init_dtv)
This macro must install the given initial DTV into the thread control
diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h
index f0e274c45fb5e91e..88a6b902c0b7e2fd 100644
--- a/sysdeps/hppa/nptl/tls.h
+++ b/sysdeps/hppa/nptl/tls.h
@@ -52,15 +52,9 @@ typedef struct
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size we need before TCB */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index 111c9ee59df30bc3..06ab9784a5358b0b 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -102,15 +102,9 @@ union user_desc_init
struct pthread even when not linked with -lpthread. */
# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* The TCB can have any size and the memory following the address the
thread pointer points to is unspecified. Allocate the TCB there. */
# define TLS_TCB_AT_TP 1
diff --git a/sysdeps/ia64/libc-tls.c b/sysdeps/ia64/libc-tls.c
index a01edceab36d375e..ede1e8f463b135b4 100644
--- a/sysdeps/ia64/libc-tls.c
+++ b/sysdeps/ia64/libc-tls.c
@@ -18,6 +18,9 @@
#include <csu/libc-tls.c>
+_Static_assert (TLS_PRE_TCB_SIZE % __alignof (struct pthread) == 0,
+ "__thread_self and THREAD_SELF have same alignment");
+
/* On IA-64, as it lacks linker optimizations, __tls_get_addr can be
called even in statically linked binaries.
In this case module must be always 1 and PT_TLS segment
diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h
index 26fe555cb4b5e164..ca8f1280aeeed3d5 100644
--- a/sysdeps/ia64/nptl/tls.h
+++ b/sysdeps/ia64/nptl/tls.h
@@ -53,9 +53,6 @@ register struct pthread *__thread_self __asm__("r13");
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
@@ -70,9 +67,6 @@ register struct pthread *__thread_self __asm__("r13");
& ~(__alignof__ (struct pthread) - 1)) \
: 0))
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* The DTV is allocated at the TP; the TCB is placed elsewhere. */
# define TLS_DTV_AT_TP 1
# define TLS_TCB_AT_TP 0
diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h
index 9f562c38288df200..b88ef0c9c74ae0b0 100644
--- a/sysdeps/m68k/nptl/tls.h
+++ b/sysdeps/m68k/nptl/tls.h
@@ -54,20 +54,15 @@ typedef struct
pointer, we don't need this. */
# define TLS_INIT_TCB_SIZE 0
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. Because our TCB is before the thread
pointer, we don't need this. */
# define TLS_TCB_SIZE 0
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size we need before TCB - actually, it includes the TCB. */
# define TLS_PRE_TCB_SIZE \
(sizeof (struct pthread) \
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
+ & ~(__alignof (struct pthread) - 1)))
/* The thread pointer (TP) points to the end of the
TCB + 0x7000, as for PowerPC and MIPS. This implies that TCB address is
diff --git a/sysdeps/mach/hurd/tls.h b/sysdeps/mach/hurd/tls.h
index f83956d3d7ca4f9f..773a2a0c36d5d57d 100644
--- a/sysdeps/mach/hurd/tls.h
+++ b/sysdeps/mach/hurd/tls.h
@@ -29,20 +29,12 @@
# include <mach.h>
# include <atomic.h>
-
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE TLS_INIT_TCB_SIZE /* XXX */
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN TLS_INIT_TCB_ALIGN /* XXX */
-
-
/* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */
# define INSTALL_DTV(descr, dtvp) \
diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h
index bfa6efa78049bb2d..b69d7b4f28f3b757 100644
--- a/sysdeps/microblaze/nptl/tls.h
+++ b/sysdeps/microblaze/nptl/tls.h
@@ -56,18 +56,12 @@ typedef struct
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */
# define INSTALL_DTV(tcbp, dtvp) \
diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h
index ef99aa646c898e76..6ccaf9804a68634a 100644
--- a/sysdeps/mips/nptl/tls.h
+++ b/sysdeps/mips/nptl/tls.h
@@ -83,20 +83,15 @@ typedef struct
pointer, we don't need this. */
# define TLS_INIT_TCB_SIZE 0
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. Because our TCB is before the thread
pointer, we don't need this. */
# define TLS_TCB_SIZE 0
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size we need before TCB - actually, it includes the TCB. */
# define TLS_PRE_TCB_SIZE \
(sizeof (struct pthread) \
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
+ & ~(__alignof (struct pthread) - 1)))
/* The thread pointer (in hardware register $29) points to the end of
the TCB + 0x7000, as for PowerPC. The pthread_descr structure is
diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h
index 7110cfccad7131f4..6ab6bd27b00a70ee 100644
--- a/sysdeps/nios2/nptl/tls.h
+++ b/sysdeps/nios2/nptl/tls.h
@@ -59,20 +59,15 @@ register struct pthread *__thread_self __asm__("r23");
pointer, we don't need this. */
# define TLS_INIT_TCB_SIZE 0
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. Because our TCB is before the thread
pointer, we don't need this. */
# define TLS_TCB_SIZE 0
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size we need before TCB - actually, it includes the TCB. */
# define TLS_PRE_TCB_SIZE \
(sizeof (struct pthread) \
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
+ & ~(__alignof (struct pthread) - 1)))
/* The thread pointer (in hardware register r23) points to the end of
the TCB + 0x7000, as for PowerPC and MIPS. */
diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
index 110d085d30c86302..e194b334216eaa02 100644
--- a/sysdeps/powerpc/nptl/tls.h
+++ b/sysdeps/powerpc/nptl/tls.h
@@ -108,19 +108,14 @@ typedef struct
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE 0
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE 0
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE \
(sizeof (struct pthread) \
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
+ & ~(__alignof (struct pthread) - 1)))
/* The following assumes that TP (R2 or R13) points to the end of the
TCB + 0x7000 (per the ABI). This implies that TCB address is
diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h
index bdc0a3a6f91b51e8..8c12d8f971adeddb 100644
--- a/sysdeps/riscv/nptl/tls.h
+++ b/sysdeps/riscv/nptl/tls.h
@@ -50,20 +50,15 @@ typedef struct
pointer, we don't need this. */
# define TLS_INIT_TCB_SIZE 0
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. Because our TCB is before the thread
pointer, we don't need this. */
# define TLS_TCB_SIZE 0
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size we need before TCB - actually, it includes the TCB. */
# define TLS_PRE_TCB_SIZE \
(sizeof (struct pthread) \
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
+ & ~(__alignof (struct pthread) - 1)))
/* The thread pointer tp points to the end of the TCB.
The pthread_descr structure is immediately in front of the TCB. */
diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h
index 2cdd18eb2907c060..3b4c0ab32a9439a3 100644
--- a/sysdeps/s390/nptl/tls.h
+++ b/sysdeps/s390/nptl/tls.h
@@ -66,15 +66,9 @@ typedef struct
struct pthread even when not linked with -lpthread. */
# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* The TCB can have any size and the memory following the address the
thread pointer points to is unspecified. Allocate the TCB there. */
# define TLS_TCB_AT_TP 1
diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h
index 390640020e45f716..3e4d480b35951253 100644
--- a/sysdeps/sh/nptl/tls.h
+++ b/sysdeps/sh/nptl/tls.h
@@ -51,18 +51,12 @@ typedef struct
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* The TLS blocks start right after the TCB. */
# define TLS_DTV_AT_TP 1
# define TLS_TCB_AT_TP 0
diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h
index 376d729989e35660..3fb4ce6e6dacf28c 100644
--- a/sysdeps/sparc/nptl/tls.h
+++ b/sysdeps/sparc/nptl/tls.h
@@ -63,15 +63,9 @@ register struct pthread *__thread_self __asm__("%g7");
struct pthread even when not linked with -lpthread. */
# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* The TCB can have any size and the memory following the address the
thread pointer points to is unspecified. Allocate the TCB there. */
# define TLS_TCB_AT_TP 1
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
index 3af1836e28b26fdb..50f7e8b544f9e6fc 100644
--- a/sysdeps/x86_64/nptl/tls.h
+++ b/sysdeps/x86_64/nptl/tls.h
@@ -106,15 +106,9 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
struct pthread even when not linked with -lpthread. */
# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
-
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (struct pthread)
-/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
-
/* The TCB can have any size and the memory following the address the
thread pointer points to is unspecified. Allocate the TCB there. */
# define TLS_TCB_AT_TP 1

View File

@ -0,0 +1,73 @@
commit cb976fba4c51ede7bf8cee5035888527c308dfbc
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Dec 15 16:06:25 2021 +0100
powerpc: Use global register variable in <thread_pointer.h>
A local register variable is merely a compiler hint, and so not
appropriate in this context. Move the global register variable into
<thread_pointer.h> and include it from <tls.h>, as there can only
be one global definition for one particular register.
Fixes commit 8dbeb0561eeb876f557ac9eef5721912ec074ea5
("nptl: Add <thread_pointer.h> for defining __thread_pointer").
Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Reviewed-by: Raphael M Zinsly <rzinsly@linux.ibm.com>
diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h
index 8fd5ba671f6f5e64..4feba5961062cfaf 100644
--- a/sysdeps/powerpc/nptl/thread_pointer.h
+++ b/sysdeps/powerpc/nptl/thread_pointer.h
@@ -19,15 +19,16 @@
#ifndef _SYS_THREAD_POINTER_H
#define _SYS_THREAD_POINTER_H
-static inline void *
-__thread_pointer (void)
-{
#ifdef __powerpc64__
- register void *__result asm ("r13");
+register void *__thread_register asm ("r13");
#else
- register void *__result asm ("r2");
+register void *__thread_register asm ("r2");
#endif
- return __result;
+
+static inline void *
+__thread_pointer (void)
+{
+ return __thread_register;
}
#endif /* _SYS_THREAD_POINTER_H */
diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
index e194b334216eaa02..050beb06a8f7de65 100644
--- a/sysdeps/powerpc/nptl/tls.h
+++ b/sysdeps/powerpc/nptl/tls.h
@@ -26,6 +26,7 @@
# include <stddef.h>
# include <stdint.h>
# include <dl-dtv.h>
+# include <thread_pointer.h>
#else /* __ASSEMBLER__ */
# include <tcb-offsets.h>
@@ -36,16 +37,10 @@
#ifndef __powerpc64__
/* Register r2 (tp) is reserved by the ABI as "thread pointer". */
# define PT_THREAD_POINTER PT_R2
-# ifndef __ASSEMBLER__
-register void *__thread_register __asm__ ("r2");
-# endif
#else /* __powerpc64__ */
/* Register r13 (tp) is reserved by the ABI as "thread pointer". */
# define PT_THREAD_POINTER PT_R13
-# ifndef __ASSEMBLER__
-register void *__thread_register __asm__ ("r13");
-# endif
#endif /* __powerpc64__ */
#ifndef __ASSEMBLER__

View File

@ -0,0 +1,42 @@
Downstream-only patch to disable rseq by default. This is necessary
because CRIU does not yet support rseq:
criu: Implement rseq support
<https://bugzilla.redhat.com/show_bug.cgi?id=2033446>
diff --git a/manual/tunables.texi b/manual/tunables.texi
index 28ff502990c2a10f..f559c44dcec4624b 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -425,11 +425,13 @@ The value is measured in bytes. The default is @samp{41943040}
@end deftp
@deftp Tunable glibc.pthread.rseq
-The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable
-restartable sequences support in @theglibc{}. This enables applications
-to perform direct restartable sequence registration with the kernel.
-The default is @samp{1}, which means that @theglibc{} performs
-registration on behalf of the application.
+The @code{glibc.pthread.rseq} tunable can be set to @samp{1}, to enable
+restartable sequences support. @Theglibc{} uses this to optimize the
+@code{sched_getcpu} function.
+
+The default is @samp{0}, which means that applications can perform
+restartable sequences registration, but @code{sched_getcpu} is not
+accelerated.
Restartable sequences are a Linux-specific extension.
@end deftp
diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list
index d24f4be0d08ba407..df2a39ce01858d3b 100644
--- a/sysdeps/nptl/dl-tunables.list
+++ b/sysdeps/nptl/dl-tunables.list
@@ -31,7 +31,7 @@ glibc {
type: INT_32
minval: 0
maxval: 1
- default: 1
+ default: 0
}
}
}

View File

@ -0,0 +1,259 @@
commit 23c77f60181eb549f11ec2f913b4270af29eee38
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Dec 3 16:28:07 2021 +0100
nptl: Increase default TCB alignment to 32
rseq support will use a 32-byte aligned field in struct pthread,
so the whole struct needs to have at least that alignment.
nptl/tst-tls3mod.c uses TCB_ALIGNMENT, therefore include <descr.h>
to obtain the fallback definition.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
diff --git a/nptl/descr.h b/nptl/descr.h
index 4de84138fb960fa4..57be5b4fef564b36 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -37,7 +37,9 @@
#include <tls-internal-struct.h>
#ifndef TCB_ALIGNMENT
-# define TCB_ALIGNMENT sizeof (double)
+# define TCB_ALIGNMENT 32
+#elif TCB_ALIGNMENT < 32
+# error TCB_ALIGNMENT must be at least 32
#endif
diff --git a/nptl/tst-tls3mod.c b/nptl/tst-tls3mod.c
index cfd13aace1affcd5..77dcc550fc3b5017 100644
--- a/nptl/tst-tls3mod.c
+++ b/nptl/tst-tls3mod.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <pthreaddef.h>
+#include <descr.h>
extern pthread_barrier_t b;
diff --git a/sysdeps/aarch64/nptl/pthreaddef.h b/sysdeps/aarch64/nptl/pthreaddef.h
index 4d5ecf6661fd0fe6..8d9a10622d132a7a 100644
--- a/sysdeps/aarch64/nptl/pthreaddef.h
+++ b/sysdeps/aarch64/nptl/pthreaddef.h
@@ -28,8 +28,5 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/alpha/nptl/pthreaddef.h b/sysdeps/alpha/nptl/pthreaddef.h
index 25edb5093e095548..660e5694a25ec60f 100644
--- a/sysdeps/alpha/nptl/pthreaddef.h
+++ b/sysdeps/alpha/nptl/pthreaddef.h
@@ -27,8 +27,5 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 4096
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/arc/nptl/pthreaddef.h b/sysdeps/arc/nptl/pthreaddef.h
index 873b9d149ac46a62..d4dbe9e079445353 100644
--- a/sysdeps/arc/nptl/pthreaddef.h
+++ b/sysdeps/arc/nptl/pthreaddef.h
@@ -28,8 +28,5 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 4
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/arm/nptl/pthreaddef.h b/sysdeps/arm/nptl/pthreaddef.h
index 332f4079c4c3f2bf..13769f5ae270b0ca 100644
--- a/sysdeps/arm/nptl/pthreaddef.h
+++ b/sysdeps/arm/nptl/pthreaddef.h
@@ -28,9 +28,6 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame.
diff --git a/sysdeps/csky/nptl/pthreaddef.h b/sysdeps/csky/nptl/pthreaddef.h
index e78bc0016b43b450..7dde9131b9b1a6b0 100644
--- a/sysdeps/csky/nptl/pthreaddef.h
+++ b/sysdeps/csky/nptl/pthreaddef.h
@@ -28,8 +28,5 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 8
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/ia64/nptl/pthreaddef.h b/sysdeps/ia64/nptl/pthreaddef.h
index 3a0f6daf9ad871aa..c7420fd1e4ee6081 100644
--- a/sysdeps/ia64/nptl/pthreaddef.h
+++ b/sysdeps/ia64/nptl/pthreaddef.h
@@ -30,9 +30,6 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 16384
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __stack_pointer
diff --git a/sysdeps/m68k/nptl/pthreaddef.h b/sysdeps/m68k/nptl/pthreaddef.h
index 13e785a86bbf47b4..ce9511cb02da69fd 100644
--- a/sysdeps/m68k/nptl/pthreaddef.h
+++ b/sysdeps/m68k/nptl/pthreaddef.h
@@ -28,9 +28,6 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/microblaze/nptl/pthreaddef.h b/sysdeps/microblaze/nptl/pthreaddef.h
index 517157444da556ad..19d7235782afde53 100644
--- a/sysdeps/microblaze/nptl/pthreaddef.h
+++ b/sysdeps/microblaze/nptl/pthreaddef.h
@@ -31,8 +31,5 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/mips/nptl/pthreaddef.h b/sysdeps/mips/nptl/pthreaddef.h
index a7bccef6e512438f..322591c293ce5e15 100644
--- a/sysdeps/mips/nptl/pthreaddef.h
+++ b/sysdeps/mips/nptl/pthreaddef.h
@@ -27,9 +27,6 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/nios2/nptl/pthreaddef.h b/sysdeps/nios2/nptl/pthreaddef.h
index e01a0e6df72c089a..aa0709d0dc69f251 100644
--- a/sysdeps/nios2/nptl/pthreaddef.h
+++ b/sysdeps/nios2/nptl/pthreaddef.h
@@ -28,8 +28,5 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 4
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/powerpc/nptl/pthreaddef.h b/sysdeps/powerpc/nptl/pthreaddef.h
index ef5310e6315fde2c..117c35229ea68f48 100644
--- a/sysdeps/powerpc/nptl/pthreaddef.h
+++ b/sysdeps/powerpc/nptl/pthreaddef.h
@@ -28,9 +28,6 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 4096
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/riscv/nptl/pthreaddef.h b/sysdeps/riscv/nptl/pthreaddef.h
index 7bf93d6a63fdecd2..0f33cc48fe4fc728 100644
--- a/sysdeps/riscv/nptl/pthreaddef.h
+++ b/sysdeps/riscv/nptl/pthreaddef.h
@@ -28,8 +28,5 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/s390/nptl/pthreaddef.h b/sysdeps/s390/nptl/pthreaddef.h
index 091f82df24a4024c..0e32bd862f7fea48 100644
--- a/sysdeps/s390/nptl/pthreaddef.h
+++ b/sysdeps/s390/nptl/pthreaddef.h
@@ -28,9 +28,6 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/sh/nptl/pthreaddef.h b/sysdeps/sh/nptl/pthreaddef.h
index 3fa3d189ef969c90..f4e3a290df4ee6e6 100644
--- a/sysdeps/sh/nptl/pthreaddef.h
+++ b/sysdeps/sh/nptl/pthreaddef.h
@@ -29,9 +29,6 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 8
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/sparc/sparc32/pthreaddef.h b/sysdeps/sparc/sparc32/pthreaddef.h
index 6526fb3d6e7e1448..7a0a04789dac478e 100644
--- a/sysdeps/sparc/sparc32/pthreaddef.h
+++ b/sysdeps/sparc/sparc32/pthreaddef.h
@@ -27,9 +27,6 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME (stack_pointer + (2 * 64))
diff --git a/sysdeps/sparc/sparc64/pthreaddef.h b/sysdeps/sparc/sparc64/pthreaddef.h
index 3da9d7afc8054598..103842856d40432b 100644
--- a/sysdeps/sparc/sparc64/pthreaddef.h
+++ b/sysdeps/sparc/sparc64/pthreaddef.h
@@ -27,10 +27,6 @@
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 4096
-/* Alignment requirement for TCB. */
-#define TCB_ALIGNMENT 16
-
-
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME (stack_pointer + (2 * 128))
register char *stack_pointer __asm__("%sp");

View File

@ -0,0 +1,150 @@
commit 4fb4e7e821e36180835bf88e363f9f13b5797e3a
Author: Florian Weimer <fweimer@redhat.com>
Date: Sun Dec 5 13:50:17 2021 +0100
csu: Always use __executable_start in gmon-start.c
Current binutils defines __executable_start as the lowest text
address, so using the entry point address as a fallback is no
longer necessary. As a result, overriding <entry.h> is only
necessary if the entry point is not called _start.
The previous approach to define __ASSEMBLY__ to suppress the
declaration breaks if headers included by <entry.h> are not
compatible with __ASSEMBLY__. This happens with rseq integration
because it is necessary to include kernel headers in more places.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
diff --git a/csu/gmon-start.c b/csu/gmon-start.c
index 344606a676c188d4..260c7613e291a32d 100644
--- a/csu/gmon-start.c
+++ b/csu/gmon-start.c
@@ -38,32 +38,12 @@
#include <stdlib.h>
#include <unistd.h>
#include <elf-initfini.h>
-#define __ASSEMBLY__
-#include <entry.h>
-
-/* Beginning and end of our code segment. We cannot declare them
- as the external functions since we want the addresses of those
- labels. Taking the address of a function may have different
- meanings on different platforms. */
-#ifdef ENTRY_POINT_DECL
-ENTRY_POINT_DECL(extern)
-#else
-extern char ENTRY_POINT[];
-#endif
-extern char etext[];
/* Use __executable_start as the lowest address to keep profiling records
if it provided by the linker. */
-extern const char executable_start[] asm ("__executable_start")
- __attribute__ ((weak, visibility ("hidden")));
+extern const char __executable_start[] __attribute__ ((visibility ("hidden")));
-#ifndef TEXT_START
-# ifdef ENTRY_POINT_DECL
-# define TEXT_START ENTRY_POINT
-# else
-# define TEXT_START &ENTRY_POINT
-# endif
-#endif
+extern char etext[];
#if !ELF_INITFINI
/* Instead of defining __gmon_start__ globally in gcrt1.o, we make it
@@ -97,10 +77,7 @@ __gmon_start__ (void)
called = 1;
/* Start keeping profiling records. */
- if (&executable_start != NULL)
- __monstartup ((u_long) &executable_start, (u_long) &etext);
- else
- __monstartup ((u_long) TEXT_START, (u_long) &etext);
+ __monstartup ((u_long) &__executable_start, (u_long) &etext);
/* Call _mcleanup before exiting; it will write out gmon.out from the
collected data. */
diff --git a/sysdeps/hppa/entry.h b/sysdeps/hppa/entry.h
deleted file mode 100644
index 5ea5b47448ceb2e7..0000000000000000
--- a/sysdeps/hppa/entry.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __ASSEMBLY__
-extern void _start (void);
-#endif
-
-/* Lives in libgcc.so and canonicalizes function pointers for comparison. */
-extern unsigned int __canonicalize_funcptr_for_compare (unsigned int fptr);
-
-/* The function's entry point is stored in the first word of the
- function descriptor (plabel) of _start(). */
-#define ENTRY_POINT __canonicalize_funcptr_for_compare((unsigned int)_start)
-
-/* We have to provide a special declaration. */
-#define ENTRY_POINT_DECL(class) class void _start (void);
diff --git a/sysdeps/ia64/entry.h b/sysdeps/ia64/entry.h
deleted file mode 100644
index e11b49fc53602eb8..0000000000000000
--- a/sysdeps/ia64/entry.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <link.h>
-#include <dl-fptr.h>
-
-#ifndef __ASSEMBLY__
-extern void _start (void);
-#endif
-
-/* The function's entry point is stored in the first word of the
- function descriptor (plabel) of _start(). */
-#define ENTRY_POINT ELF_PTR_TO_FDESC (_start)->ip
-
-/* We have to provide a special declaration. */
-#define ENTRY_POINT_DECL(class) class void _start (void);
diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h
deleted file mode 100644
index 99c81cb9820d188d..0000000000000000
--- a/sysdeps/powerpc/powerpc64/entry.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Finding the entry point and start of text. PowerPC64 version.
- Copyright (C) 2002-2021 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-
-#ifndef __ASSEMBLY__
-extern void _start (void);
-#endif
-
-#define ENTRY_POINT _start
-
-#if _CALL_ELF != 2
-/* We have to provide a special declaration. */
-#define ENTRY_POINT_DECL(class) class void _start (void);
-
-/* Use the address of ._start as the lowest address for which we need
- to keep profiling records. We can't copy the ia64 scheme as our
- entry poiny address is really the address of the function
- descriptor, not the actual function entry. */
-#define TEXT_START \
- ({ extern unsigned long int _start_as_data[] asm ("_start"); \
- _start_as_data[0]; })
-#endif

View File

@ -0,0 +1,130 @@
commit 8dbeb0561eeb876f557ac9eef5721912ec074ea5
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Dec 9 09:49:32 2021 +0100
nptl: Add <thread_pointer.h> for defining __thread_pointer
<tls.h> already contains a definition that is quite similar,
but it is not consistent across architectures.
Only architectures for which rseq support is added are covered.
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
diff --git a/sysdeps/nptl/thread_pointer.h b/sysdeps/nptl/thread_pointer.h
new file mode 100644
index 0000000000000000..92f2f3093eba55bb
--- /dev/null
+++ b/sysdeps/nptl/thread_pointer.h
@@ -0,0 +1,28 @@
+/* __thread_pointer definition. Generic version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_THREAD_POINTER_H
+#define _SYS_THREAD_POINTER_H
+
+static inline void *
+__thread_pointer (void)
+{
+ return __builtin_thread_pointer ();
+}
+
+#endif /* _SYS_THREAD_POINTER_H */
diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h
new file mode 100644
index 0000000000000000..8fd5ba671f6f5e64
--- /dev/null
+++ b/sysdeps/powerpc/nptl/thread_pointer.h
@@ -0,0 +1,33 @@
+/* __thread_pointer definition. powerpc version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_THREAD_POINTER_H
+#define _SYS_THREAD_POINTER_H
+
+static inline void *
+__thread_pointer (void)
+{
+#ifdef __powerpc64__
+ register void *__result asm ("r13");
+#else
+ register void *__result asm ("r2");
+#endif
+ return __result;
+}
+
+#endif /* _SYS_THREAD_POINTER_H */
diff --git a/sysdeps/x86/nptl/thread_pointer.h b/sysdeps/x86/nptl/thread_pointer.h
new file mode 100644
index 0000000000000000..6b71b6f7e1401e4c
--- /dev/null
+++ b/sysdeps/x86/nptl/thread_pointer.h
@@ -0,0 +1,38 @@
+/* __thread_pointer definition. x86 version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_THREAD_POINTER_H
+#define _SYS_THREAD_POINTER_H
+
+static inline void *
+__thread_pointer (void)
+{
+#if __GNUC_PREREQ (11, 1)
+ return __builtin_thread_pointer ();
+#else
+ void *__result;
+# ifdef __x86_64__
+ __asm__ ("mov %%fs:0, %0" : "=r" (__result));
+# else
+ __asm__ ("mov %%gs:0, %0" : "=r" (__result));
+# endif
+ return __result;
+#endif /* !GCC 11 */
+}
+
+#endif /* _SYS_THREAD_POINTER_H */

View File

@ -0,0 +1,904 @@
commit ce2248ab91b2ea09a378f85012f251f31ac65e31
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Dec 9 09:49:32 2021 +0100
nptl: Introduce <tcb-access.h> for THREAD_* accessors
These are common between most architectures. Only the x86 targets
are outliers.
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h
index 6e896207a659514f..cd9abb5d1d073593 100644
--- a/sysdeps/aarch64/nptl/tls.h
+++ b/sysdeps/aarch64/nptl/tls.h
@@ -98,15 +98,7 @@ typedef struct
# define DB_THREAD_SELF \
CONST_THREAD_AREA (64, sizeof (struct pthread))
-/* Access to data in the thread descriptor is easy. */
-# define THREAD_GETMEM(descr, member) \
- descr->member
-# define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-# define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* Get and set the global scope generation counter in struct pthread. */
# define THREAD_GSCOPE_IN_TCB 1
diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h
index 4dbccc5249539325..5f4843b28e7f1ad1 100644
--- a/sysdeps/alpha/nptl/tls.h
+++ b/sysdeps/alpha/nptl/tls.h
@@ -92,15 +92,7 @@ typedef struct
# define DB_THREAD_SELF \
REGISTER (64, 64, 32 * 8, -sizeof (struct pthread))
-/* Access to data in the thread descriptor is easy. */
-#define THREAD_GETMEM(descr, member) \
- descr->member
-#define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-#define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* Get and set the global scope generation counter in struct pthread. */
#define THREAD_GSCOPE_IN_TCB 1
diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h
index 95300fdd2159dc53..d9ada2f38089e6cd 100644
--- a/sysdeps/arc/nptl/tls.h
+++ b/sysdeps/arc/nptl/tls.h
@@ -100,15 +100,7 @@ typedef struct
# define DB_THREAD_SELF \
CONST_THREAD_AREA (32, sizeof (struct pthread))
-/* Access to data in the thread descriptor is easy. */
-# define THREAD_GETMEM(descr, member) \
- descr->member
-# define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-# define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* Get and set the global scope generation counter in struct pthread. */
#define THREAD_GSCOPE_IN_TCB 1
diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h
index 1bd11307ce0a7f0a..354aae3318291395 100644
--- a/sysdeps/arm/nptl/tls.h
+++ b/sysdeps/arm/nptl/tls.h
@@ -89,15 +89,7 @@ typedef struct
# define DB_THREAD_SELF \
CONST_THREAD_AREA (32, sizeof (struct pthread))
-/* Access to data in the thread descriptor is easy. */
-#define THREAD_GETMEM(descr, member) \
- descr->member
-#define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-#define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* Get and set the global scope generation counter in struct pthread. */
#define THREAD_GSCOPE_IN_TCB 1
diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h
index 7a234041ed0bff39..f3fa3fcb02748776 100644
--- a/sysdeps/csky/nptl/tls.h
+++ b/sysdeps/csky/nptl/tls.h
@@ -116,15 +116,7 @@ typedef struct
# define DB_THREAD_SELF \
CONST_THREAD_AREA (32, sizeof (struct pthread))
-/* Access to data in the thread descriptor is easy. */
-# define THREAD_GETMEM(descr, member) \
- descr->member
-# define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-# define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* Get and set the global scope generation counter in struct pthread. */
# define THREAD_GSCOPE_IN_TCB 1
diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h
index 857003a7d35073eb..f0e274c45fb5e91e 100644
--- a/sysdeps/hppa/nptl/tls.h
+++ b/sysdeps/hppa/nptl/tls.h
@@ -107,15 +107,7 @@ typedef struct
# define DB_THREAD_SELF \
REGISTER (32, 32, 53 * 4, -sizeof (struct pthread))
-/* Access to data in the thread descriptor is easy. */
-# define THREAD_GETMEM(descr, member) \
- descr->member
-# define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-# define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
static inline struct pthread *__get_cr27(void)
{
diff --git a/sysdeps/i386/nptl/tcb-access.h b/sysdeps/i386/nptl/tcb-access.h
new file mode 100644
index 0000000000000000..6c6d561e394817c7
--- /dev/null
+++ b/sysdeps/i386/nptl/tcb-access.h
@@ -0,0 +1,123 @@
+/* THREAD_* accessors. i386 version.
+ Copyright (C) 2002-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/>. */
+
+/* Read member of the thread descriptor directly. */
+#define THREAD_GETMEM(descr, member) \
+ ({ __typeof (descr->member) __value; \
+ _Static_assert (sizeof (__value) == 1 \
+ || sizeof (__value) == 4 \
+ || sizeof (__value) == 8, \
+ "size of per-thread data"); \
+ if (sizeof (__value) == 1) \
+ asm volatile ("movb %%gs:%P2,%b0" \
+ : "=q" (__value) \
+ : "0" (0), "i" (offsetof (struct pthread, member))); \
+ else if (sizeof (__value) == 4) \
+ asm volatile ("movl %%gs:%P1,%0" \
+ : "=r" (__value) \
+ : "i" (offsetof (struct pthread, member))); \
+ else /* 8 */ \
+ { \
+ asm volatile ("movl %%gs:%P1,%%eax\n\t" \
+ "movl %%gs:%P2,%%edx" \
+ : "=A" (__value) \
+ : "i" (offsetof (struct pthread, member)), \
+ "i" (offsetof (struct pthread, member) + 4)); \
+ } \
+ __value; })
+
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
+#define THREAD_GETMEM_NC(descr, member, idx) \
+ ({ __typeof (descr->member[0]) __value; \
+ _Static_assert (sizeof (__value) == 1 \
+ || sizeof (__value) == 4 \
+ || sizeof (__value) == 8, \
+ "size of per-thread data"); \
+ if (sizeof (__value) == 1) \
+ asm volatile ("movb %%gs:%P2(%3),%b0" \
+ : "=q" (__value) \
+ : "0" (0), "i" (offsetof (struct pthread, member[0])), \
+ "r" (idx)); \
+ else if (sizeof (__value) == 4) \
+ asm volatile ("movl %%gs:%P1(,%2,4),%0" \
+ : "=r" (__value) \
+ : "i" (offsetof (struct pthread, member[0])), \
+ "r" (idx)); \
+ else /* 8 */ \
+ { \
+ asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \
+ "movl %%gs:4+%P1(,%2,8),%%edx" \
+ : "=&A" (__value) \
+ : "i" (offsetof (struct pthread, member[0])), \
+ "r" (idx)); \
+ } \
+ __value; })
+
+
+
+/* Set member of the thread descriptor directly. */
+#define THREAD_SETMEM(descr, member, value) \
+ ({ \
+ _Static_assert (sizeof (descr->member) == 1 \
+ || sizeof (descr->member) == 4 \
+ || sizeof (descr->member) == 8, \
+ "size of per-thread data"); \
+ if (sizeof (descr->member) == 1) \
+ asm volatile ("movb %b0,%%gs:%P1" : \
+ : "iq" (value), \
+ "i" (offsetof (struct pthread, member))); \
+ else if (sizeof (descr->member) == 4) \
+ asm volatile ("movl %0,%%gs:%P1" : \
+ : "ir" (value), \
+ "i" (offsetof (struct pthread, member))); \
+ else /* 8 */ \
+ { \
+ asm volatile ("movl %%eax,%%gs:%P1\n\t" \
+ "movl %%edx,%%gs:%P2" : \
+ : "A" ((uint64_t) cast_to_integer (value)), \
+ "i" (offsetof (struct pthread, member)), \
+ "i" (offsetof (struct pthread, member) + 4)); \
+ }})
+
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
+#define THREAD_SETMEM_NC(descr, member, idx, value) \
+ ({ \
+ _Static_assert (sizeof (descr->member[0]) == 1 \
+ || sizeof (descr->member[0]) == 4 \
+ || sizeof (descr->member[0]) == 8, \
+ "size of per-thread data"); \
+ if (sizeof (descr->member[0]) == 1) \
+ asm volatile ("movb %b0,%%gs:%P1(%2)" : \
+ : "iq" (value), \
+ "i" (offsetof (struct pthread, member)), \
+ "r" (idx)); \
+ else if (sizeof (descr->member[0]) == 4) \
+ asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \
+ : "ir" (value), \
+ "i" (offsetof (struct pthread, member)), \
+ "r" (idx)); \
+ else /* 8 */ \
+ { \
+ asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \
+ "movl %%edx,%%gs:4+%P1(,%2,8)" : \
+ : "A" ((uint64_t) cast_to_integer (value)), \
+ "i" (offsetof (struct pthread, member)), \
+ "r" (idx)); \
+ }})
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index 86ee1ef30270f960..111c9ee59df30bc3 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -250,113 +250,7 @@ tls_fill_user_desc (union user_desc_init *desc,
REGISTER_THREAD_AREA (32, offsetof (struct user_regs_struct, xgs), 3) \
REGISTER_THREAD_AREA (64, 26 * 8, 3) /* x86-64's user_regs_struct->gs */
-
-/* Read member of the thread descriptor directly. */
-# define THREAD_GETMEM(descr, member) \
- ({ __typeof (descr->member) __value; \
- _Static_assert (sizeof (__value) == 1 \
- || sizeof (__value) == 4 \
- || sizeof (__value) == 8, \
- "size of per-thread data"); \
- if (sizeof (__value) == 1) \
- asm volatile ("movb %%gs:%P2,%b0" \
- : "=q" (__value) \
- : "0" (0), "i" (offsetof (struct pthread, member))); \
- else if (sizeof (__value) == 4) \
- asm volatile ("movl %%gs:%P1,%0" \
- : "=r" (__value) \
- : "i" (offsetof (struct pthread, member))); \
- else /* 8 */ \
- { \
- asm volatile ("movl %%gs:%P1,%%eax\n\t" \
- "movl %%gs:%P2,%%edx" \
- : "=A" (__value) \
- : "i" (offsetof (struct pthread, member)), \
- "i" (offsetof (struct pthread, member) + 4)); \
- } \
- __value; })
-
-
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
-# define THREAD_GETMEM_NC(descr, member, idx) \
- ({ __typeof (descr->member[0]) __value; \
- _Static_assert (sizeof (__value) == 1 \
- || sizeof (__value) == 4 \
- || sizeof (__value) == 8, \
- "size of per-thread data"); \
- if (sizeof (__value) == 1) \
- asm volatile ("movb %%gs:%P2(%3),%b0" \
- : "=q" (__value) \
- : "0" (0), "i" (offsetof (struct pthread, member[0])), \
- "r" (idx)); \
- else if (sizeof (__value) == 4) \
- asm volatile ("movl %%gs:%P1(,%2,4),%0" \
- : "=r" (__value) \
- : "i" (offsetof (struct pthread, member[0])), \
- "r" (idx)); \
- else /* 8 */ \
- { \
- asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \
- "movl %%gs:4+%P1(,%2,8),%%edx" \
- : "=&A" (__value) \
- : "i" (offsetof (struct pthread, member[0])), \
- "r" (idx)); \
- } \
- __value; })
-
-
-
-/* Set member of the thread descriptor directly. */
-# define THREAD_SETMEM(descr, member, value) \
- ({ \
- _Static_assert (sizeof (descr->member) == 1 \
- || sizeof (descr->member) == 4 \
- || sizeof (descr->member) == 8, \
- "size of per-thread data"); \
- if (sizeof (descr->member) == 1) \
- asm volatile ("movb %b0,%%gs:%P1" : \
- : "iq" (value), \
- "i" (offsetof (struct pthread, member))); \
- else if (sizeof (descr->member) == 4) \
- asm volatile ("movl %0,%%gs:%P1" : \
- : "ir" (value), \
- "i" (offsetof (struct pthread, member))); \
- else /* 8 */ \
- { \
- asm volatile ("movl %%eax,%%gs:%P1\n\t" \
- "movl %%edx,%%gs:%P2" : \
- : "A" ((uint64_t) cast_to_integer (value)), \
- "i" (offsetof (struct pthread, member)), \
- "i" (offsetof (struct pthread, member) + 4)); \
- }})
-
-
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- ({ \
- _Static_assert (sizeof (descr->member[0]) == 1 \
- || sizeof (descr->member[0]) == 4 \
- || sizeof (descr->member[0]) == 8, \
- "size of per-thread data"); \
- if (sizeof (descr->member[0]) == 1) \
- asm volatile ("movb %b0,%%gs:%P1(%2)" : \
- : "iq" (value), \
- "i" (offsetof (struct pthread, member)), \
- "r" (idx)); \
- else if (sizeof (descr->member[0]) == 4) \
- asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \
- : "ir" (value), \
- "i" (offsetof (struct pthread, member)), \
- "r" (idx)); \
- else /* 8 */ \
- { \
- asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \
- "movl %%edx,%%gs:4+%P1(,%2,8)" : \
- : "A" ((uint64_t) cast_to_integer (value)), \
- "i" (offsetof (struct pthread, member)), \
- "r" (idx)); \
- }})
-
+# include <tcb-access.h>
/* Set the stack guard field in TCB head. */
#define THREAD_SET_STACK_GUARD(value) \
diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h
index 66d9bf3189f0b727..26fe555cb4b5e164 100644
--- a/sysdeps/ia64/nptl/tls.h
+++ b/sysdeps/ia64/nptl/tls.h
@@ -128,15 +128,7 @@ register struct pthread *__thread_self __asm__("r13");
/* Magic for libthread_db to know how to do THREAD_SELF. */
# define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -TLS_PRE_TCB_SIZE)
-/* Access to data in the thread descriptor is easy. */
-#define THREAD_GETMEM(descr, member) \
- descr->member
-#define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-#define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* Set the stack guard field in TCB head. */
#define THREAD_SET_STACK_GUARD(value) \
diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h
index cfcd6d2b7b59321c..9f562c38288df200 100644
--- a/sysdeps/m68k/nptl/tls.h
+++ b/sysdeps/m68k/nptl/tls.h
@@ -118,15 +118,7 @@ extern void * __m68k_read_tp (void);
# define DB_THREAD_SELF \
CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
-/* Access to data in the thread descriptor is easy. */
-# define THREAD_GETMEM(descr, member) \
- descr->member
-# define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-# define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* l_tls_offset == 0 is perfectly valid on M68K, so we have to use some
different value to mean unset l_tls_offset. */
diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h
index c93d90b11bfe4c74..bfa6efa78049bb2d 100644
--- a/sysdeps/microblaze/nptl/tls.h
+++ b/sysdeps/microblaze/nptl/tls.h
@@ -100,20 +100,7 @@ typedef struct
# define DB_THREAD_SELF \
CONST_THREAD_AREA (32, sizeof (struct pthread))
-/* Read member of the thread descriptor directly. */
-# define THREAD_GETMEM(descr, member) (descr->member)
-
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
-# define THREAD_GETMEM_NC(descr, member, idx) \
- (descr->member[idx])
-
-/* Set member of the thread descriptor directly. */
-# define THREAD_SETMEM(descr, member, value) \
- (descr->member = (value))
-
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- (descr->member[idx] = (value))
+# include <tcb-access.h>
/* Get and set the global scope generation counter in struct pthread. */
# define THREAD_GSCOPE_IN_TCB 1
diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h
index c09f49071cf3b5b9..ef99aa646c898e76 100644
--- a/sysdeps/mips/nptl/tls.h
+++ b/sysdeps/mips/nptl/tls.h
@@ -144,14 +144,7 @@ typedef struct
CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
/* Access to data in the thread descriptor is easy. */
-# define THREAD_GETMEM(descr, member) \
- descr->member
-# define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-# define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* l_tls_offset == 0 is perfectly valid on MIPS, so we have to use some
different value to mean unset l_tls_offset. */
diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h
index 02a05b4e741092bf..7110cfccad7131f4 100644
--- a/sysdeps/nios2/nptl/tls.h
+++ b/sysdeps/nios2/nptl/tls.h
@@ -112,15 +112,7 @@ register struct pthread *__thread_self __asm__("r23");
# define DB_THREAD_SELF \
REGISTER (32, 32, 23 * 4, -TLS_PRE_TCB_SIZE - TLS_TCB_OFFSET)
-/* Access to data in the thread descriptor is easy. */
-# define THREAD_GETMEM(descr, member) \
- descr->member
-# define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-# define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
# define THREAD_GET_POINTER_GUARD() \
(((tcbhead_t *) (READ_THREAD_POINTER () \
diff --git a/sysdeps/nptl/tcb-access.h b/sysdeps/nptl/tcb-access.h
new file mode 100644
index 0000000000000000..b4137b8ab8067915
--- /dev/null
+++ b/sysdeps/nptl/tcb-access.h
@@ -0,0 +1,30 @@
+/* THREAD_* accessors. Generic version based on struct pthread pointers.
+ Copyright (C) 2002-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/>. */
+
+/* Note: These are for accessing the TCB of the *current* thread.
+ descr can be disregarded on some targets as an optimization. See
+ i386 for an example. */
+
+#define THREAD_GETMEM(descr, member) \
+ descr->member
+#define THREAD_GETMEM_NC(descr, member, idx) \
+ descr->member[idx]
+#define THREAD_SETMEM(descr, member, value) \
+ descr->member = (value)
+#define THREAD_SETMEM_NC(descr, member, idx, value) \
+ descr->member[idx] = (value)
diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
index 6c779b6609147d54..110d085d30c86302 100644
--- a/sysdeps/powerpc/nptl/tls.h
+++ b/sysdeps/powerpc/nptl/tls.h
@@ -176,20 +176,7 @@ typedef struct
REGISTER (64, 64, PT_THREAD_POINTER * 8, \
- TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
-/* Read member of the thread descriptor directly. */
-# define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member)
-
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
-# define THREAD_GETMEM_NC(descr, member, idx) \
- ((void)(descr), (THREAD_SELF)->member[idx])
-
-/* Set member of the thread descriptor directly. */
-# define THREAD_SETMEM(descr, member, value) \
- ((void)(descr), (THREAD_SELF)->member = (value))
-
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- ((void)(descr), (THREAD_SELF)->member[idx] = (value))
+# include <tcb-access.h>
/* Set the stack guard field in TCB head. */
# define THREAD_SET_STACK_GUARD(value) \
diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h
index 5350bcc0498bab69..bdc0a3a6f91b51e8 100644
--- a/sysdeps/riscv/nptl/tls.h
+++ b/sysdeps/riscv/nptl/tls.h
@@ -105,14 +105,7 @@ typedef struct
REGISTER (64, 64, 4 * 8, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
/* Access to data in the thread descriptor is easy. */
-# define THREAD_GETMEM(descr, member) \
- descr->member
-# define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-# define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* l_tls_offset == 0 is perfectly valid, so we have to use some different
value to mean unset l_tls_offset. */
diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h
index efb52515e05c06a9..2cdd18eb2907c060 100644
--- a/sysdeps/s390/nptl/tls.h
+++ b/sysdeps/s390/nptl/tls.h
@@ -135,15 +135,7 @@ typedef struct
# define DB_THREAD_SELF REGISTER (32, 32, 18 * 4, 0) \
REGISTER (64, __WORDSIZE, 18 * 8, 0)
-/* Access to data in the thread descriptor is easy. */
-#define THREAD_GETMEM(descr, member) \
- descr->member
-#define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-#define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* Set the stack guard field in TCB head. */
#define THREAD_SET_STACK_GUARD(value) \
diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h
index ac3c9a9e856ee686..390640020e45f716 100644
--- a/sysdeps/sh/nptl/tls.h
+++ b/sysdeps/sh/nptl/tls.h
@@ -113,19 +113,7 @@ typedef struct
# define DB_THREAD_SELF \
REGISTER (32, 32, REG_GBR * 4, -sizeof (struct pthread))
-/* Read member of the thread descriptor directly. */
-# define THREAD_GETMEM(descr, member) (descr->member)
-
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
-# define THREAD_GETMEM_NC(descr, member, idx) (descr->member[idx])
-
-/* Set member of the thread descriptor directly. */
-# define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
#define THREAD_GET_POINTER_GUARD() \
({ tcbhead_t *__tcbp; \
diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h
index dd1eb82a595619a9..376d729989e35660 100644
--- a/sysdeps/sparc/nptl/tls.h
+++ b/sysdeps/sparc/nptl/tls.h
@@ -112,15 +112,7 @@ register struct pthread *__thread_self __asm__("%g7");
REGISTER (32, 32, 10 * 4, 0) \
REGISTER (64, __WORDSIZE, (6 * 8) + (__WORDSIZE==64?0:4), 0)
-/* Access to data in the thread descriptor is easy. */
-#define THREAD_GETMEM(descr, member) \
- descr->member
-#define THREAD_GETMEM_NC(descr, member, idx) \
- descr->member[idx]
-#define THREAD_SETMEM(descr, member, value) \
- descr->member = (value)
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
- descr->member[idx] = (value)
+# include <tcb-access.h>
/* Set the stack guard field in TCB head. */
#define THREAD_SET_STACK_GUARD(value) \
diff --git a/sysdeps/x86_64/nptl/tcb-access.h b/sysdeps/x86_64/nptl/tcb-access.h
new file mode 100644
index 0000000000000000..18848a729d16a4f5
--- /dev/null
+++ b/sysdeps/x86_64/nptl/tcb-access.h
@@ -0,0 +1,130 @@
+/* THREAD_* accessors. x86_64 version.
+ Copyright (C) 2002-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/>. */
+
+/* Read member of the thread descriptor directly. */
+# define THREAD_GETMEM(descr, member) \
+ ({ __typeof (descr->member) __value; \
+ _Static_assert (sizeof (__value) == 1 \
+ || sizeof (__value) == 4 \
+ || sizeof (__value) == 8, \
+ "size of per-thread data"); \
+ if (sizeof (__value) == 1) \
+ asm volatile ("movb %%fs:%P2,%b0" \
+ : "=q" (__value) \
+ : "0" (0), "i" (offsetof (struct pthread, member))); \
+ else if (sizeof (__value) == 4) \
+ asm volatile ("movl %%fs:%P1,%0" \
+ : "=r" (__value) \
+ : "i" (offsetof (struct pthread, member))); \
+ else /* 8 */ \
+ { \
+ asm volatile ("movq %%fs:%P1,%q0" \
+ : "=r" (__value) \
+ : "i" (offsetof (struct pthread, member))); \
+ } \
+ __value; })
+
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
+# define THREAD_GETMEM_NC(descr, member, idx) \
+ ({ __typeof (descr->member[0]) __value; \
+ _Static_assert (sizeof (__value) == 1 \
+ || sizeof (__value) == 4 \
+ || sizeof (__value) == 8, \
+ "size of per-thread data"); \
+ if (sizeof (__value) == 1) \
+ asm volatile ("movb %%fs:%P2(%q3),%b0" \
+ : "=q" (__value) \
+ : "0" (0), "i" (offsetof (struct pthread, member[0])), \
+ "r" (idx)); \
+ else if (sizeof (__value) == 4) \
+ asm volatile ("movl %%fs:%P1(,%q2,4),%0" \
+ : "=r" (__value) \
+ : "i" (offsetof (struct pthread, member[0])), "r" (idx));\
+ else /* 8 */ \
+ { \
+ asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \
+ : "=r" (__value) \
+ : "i" (offsetof (struct pthread, member[0])), \
+ "r" (idx)); \
+ } \
+ __value; })
+
+
+/* Loading addresses of objects on x86-64 needs to be treated special
+ when generating PIC code. */
+#ifdef __pic__
+# define IMM_MODE "nr"
+#else
+# define IMM_MODE "ir"
+#endif
+
+
+/* Set member of the thread descriptor directly. */
+# define THREAD_SETMEM(descr, member, value) \
+ ({ \
+ _Static_assert (sizeof (descr->member) == 1 \
+ || sizeof (descr->member) == 4 \
+ || sizeof (descr->member) == 8, \
+ "size of per-thread data"); \
+ if (sizeof (descr->member) == 1) \
+ asm volatile ("movb %b0,%%fs:%P1" : \
+ : "iq" (value), \
+ "i" (offsetof (struct pthread, member))); \
+ else if (sizeof (descr->member) == 4) \
+ asm volatile ("movl %0,%%fs:%P1" : \
+ : IMM_MODE (value), \
+ "i" (offsetof (struct pthread, member))); \
+ else /* 8 */ \
+ { \
+ /* Since movq takes a signed 32-bit immediate or a register source \
+ operand, use "er" constraint for 32-bit signed integer constant \
+ or register. */ \
+ asm volatile ("movq %q0,%%fs:%P1" : \
+ : "er" ((uint64_t) cast_to_integer (value)), \
+ "i" (offsetof (struct pthread, member))); \
+ }})
+
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+ ({ \
+ _Static_assert (sizeof (descr->member[0]) == 1 \
+ || sizeof (descr->member[0]) == 4 \
+ || sizeof (descr->member[0]) == 8, \
+ "size of per-thread data"); \
+ if (sizeof (descr->member[0]) == 1) \
+ asm volatile ("movb %b0,%%fs:%P1(%q2)" : \
+ : "iq" (value), \
+ "i" (offsetof (struct pthread, member[0])), \
+ "r" (idx)); \
+ else if (sizeof (descr->member[0]) == 4) \
+ asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \
+ : IMM_MODE (value), \
+ "i" (offsetof (struct pthread, member[0])), \
+ "r" (idx)); \
+ else /* 8 */ \
+ { \
+ /* Since movq takes a signed 32-bit immediate or a register source \
+ operand, use "er" constraint for 32-bit signed integer constant \
+ or register. */ \
+ asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \
+ : "er" ((uint64_t) cast_to_integer (value)), \
+ "i" (offsetof (struct pthread, member[0])), \
+ "r" (idx)); \
+ }})
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
index a78c4f4d016002fa..3af1836e28b26fdb 100644
--- a/sysdeps/x86_64/nptl/tls.h
+++ b/sysdeps/x86_64/nptl/tls.h
@@ -195,119 +195,7 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
# define DB_THREAD_SELF_INCLUDE <sys/reg.h> /* For the FS constant. */
# define DB_THREAD_SELF CONST_THREAD_AREA (64, FS)
-/* Read member of the thread descriptor directly. */
-# define THREAD_GETMEM(descr, member) \
- ({ __typeof (descr->member) __value; \
- _Static_assert (sizeof (__value) == 1 \
- || sizeof (__value) == 4 \
- || sizeof (__value) == 8, \
- "size of per-thread data"); \
- if (sizeof (__value) == 1) \
- asm volatile ("movb %%fs:%P2,%b0" \
- : "=q" (__value) \
- : "0" (0), "i" (offsetof (struct pthread, member))); \
- else if (sizeof (__value) == 4) \
- asm volatile ("movl %%fs:%P1,%0" \
- : "=r" (__value) \
- : "i" (offsetof (struct pthread, member))); \
- else /* 8 */ \
- { \
- asm volatile ("movq %%fs:%P1,%q0" \
- : "=r" (__value) \
- : "i" (offsetof (struct pthread, member))); \
- } \
- __value; })
-
-
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
-# define THREAD_GETMEM_NC(descr, member, idx) \
- ({ __typeof (descr->member[0]) __value; \
- _Static_assert (sizeof (__value) == 1 \
- || sizeof (__value) == 4 \
- || sizeof (__value) == 8, \
- "size of per-thread data"); \
- if (sizeof (__value) == 1) \
- asm volatile ("movb %%fs:%P2(%q3),%b0" \
- : "=q" (__value) \
- : "0" (0), "i" (offsetof (struct pthread, member[0])), \
- "r" (idx)); \
- else if (sizeof (__value) == 4) \
- asm volatile ("movl %%fs:%P1(,%q2,4),%0" \
- : "=r" (__value) \
- : "i" (offsetof (struct pthread, member[0])), "r" (idx));\
- else /* 8 */ \
- { \
- asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \
- : "=r" (__value) \
- : "i" (offsetof (struct pthread, member[0])), \
- "r" (idx)); \
- } \
- __value; })
-
-
-/* Loading addresses of objects on x86-64 needs to be treated special
- when generating PIC code. */
-#ifdef __pic__
-# define IMM_MODE "nr"
-#else
-# define IMM_MODE "ir"
-#endif
-
-
-/* Set member of the thread descriptor directly. */
-# define THREAD_SETMEM(descr, member, value) \
- ({ \
- _Static_assert (sizeof (descr->member) == 1 \
- || sizeof (descr->member) == 4 \
- || sizeof (descr->member) == 8, \
- "size of per-thread data"); \
- if (sizeof (descr->member) == 1) \
- asm volatile ("movb %b0,%%fs:%P1" : \
- : "iq" (value), \
- "i" (offsetof (struct pthread, member))); \
- else if (sizeof (descr->member) == 4) \
- asm volatile ("movl %0,%%fs:%P1" : \
- : IMM_MODE (value), \
- "i" (offsetof (struct pthread, member))); \
- else /* 8 */ \
- { \
- /* Since movq takes a signed 32-bit immediate or a register source \
- operand, use "er" constraint for 32-bit signed integer constant \
- or register. */ \
- asm volatile ("movq %q0,%%fs:%P1" : \
- : "er" ((uint64_t) cast_to_integer (value)), \
- "i" (offsetof (struct pthread, member))); \
- }})
-
-
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
- ({ \
- _Static_assert (sizeof (descr->member[0]) == 1 \
- || sizeof (descr->member[0]) == 4 \
- || sizeof (descr->member[0]) == 8, \
- "size of per-thread data"); \
- if (sizeof (descr->member[0]) == 1) \
- asm volatile ("movb %b0,%%fs:%P1(%q2)" : \
- : "iq" (value), \
- "i" (offsetof (struct pthread, member[0])), \
- "r" (idx)); \
- else if (sizeof (descr->member[0]) == 4) \
- asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \
- : IMM_MODE (value), \
- "i" (offsetof (struct pthread, member[0])), \
- "r" (idx)); \
- else /* 8 */ \
- { \
- /* Since movq takes a signed 32-bit immediate or a register source \
- operand, use "er" constraint for 32-bit signed integer constant \
- or register. */ \
- asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \
- : "er" ((uint64_t) cast_to_integer (value)), \
- "i" (offsetof (struct pthread, member[0])), \
- "r" (idx)); \
- }})
-
+# include <tcb-access.h>
/* Set the stack guard field in TCB head. */
# define THREAD_SET_STACK_GUARD(value) \

View File

@ -0,0 +1,49 @@
commit 8d1927d8dc5aad0f01c929123086be3a5b799d18
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Dec 9 09:49:32 2021 +0100
nptl: Introduce THREAD_GETMEM_VOLATILE
This will be needed for rseq TCB access.
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
diff --git a/sysdeps/i386/nptl/tcb-access.h b/sysdeps/i386/nptl/tcb-access.h
index 6c6d561e394817c7..5ddd83224bc8eb77 100644
--- a/sysdeps/i386/nptl/tcb-access.h
+++ b/sysdeps/i386/nptl/tcb-access.h
@@ -41,6 +41,8 @@
} \
__value; })
+/* THREAD_GETMEM already forces a read. */
+#define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member)
/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
#define THREAD_GETMEM_NC(descr, member, idx) \
diff --git a/sysdeps/nptl/tcb-access.h b/sysdeps/nptl/tcb-access.h
index b4137b8ab8067915..bbe20b7225b060fd 100644
--- a/sysdeps/nptl/tcb-access.h
+++ b/sysdeps/nptl/tcb-access.h
@@ -22,6 +22,8 @@
#define THREAD_GETMEM(descr, member) \
descr->member
+#define THREAD_GETMEM_VOLATILE(descr, member) \
+ (*(volatile __typeof (descr->member) *)&descr->member)
#define THREAD_GETMEM_NC(descr, member, idx) \
descr->member[idx]
#define THREAD_SETMEM(descr, member, value) \
diff --git a/sysdeps/x86_64/nptl/tcb-access.h b/sysdeps/x86_64/nptl/tcb-access.h
index 18848a729d16a4f5..e4d2d07a9b218025 100644
--- a/sysdeps/x86_64/nptl/tcb-access.h
+++ b/sysdeps/x86_64/nptl/tcb-access.h
@@ -39,6 +39,8 @@
} \
__value; })
+/* THREAD_GETMEM already forces a read. */
+#define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member)
/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
# define THREAD_GETMEM_NC(descr, member, idx) \

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
commit 1d350aa06091211863e41169729cee1bca39f72f
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Dec 9 09:49:32 2021 +0100
Linux: Use rseq to accelerate sched_getcpu
Co-Authored-By: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c
index c41e986f2cab5e42..6f78edaea1495342 100644
--- a/sysdeps/unix/sysv/linux/sched_getcpu.c
+++ b/sysdeps/unix/sysv/linux/sched_getcpu.c
@@ -20,8 +20,8 @@
#include <sysdep.h>
#include <sysdep-vdso.h>
-int
-sched_getcpu (void)
+static int
+vsyscall_sched_getcpu (void)
{
unsigned int cpu;
int r = -1;
@@ -32,3 +32,18 @@ sched_getcpu (void)
#endif
return r == -1 ? r : cpu;
}
+
+#ifdef RSEQ_SIG
+int
+sched_getcpu (void)
+{
+ int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id);
+ return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu ();
+}
+#else /* RSEQ_SIG */
+int
+sched_getcpu (void)
+{
+ return vsyscall_sched_getcpu ();
+}
+#endif /* RSEQ_SIG */

View File

@ -0,0 +1,278 @@
commit e3e589829d16af9f7e73c7b70f74f3c5d5003e45
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Dec 9 09:49:32 2021 +0100
nptl: Add glibc.pthread.rseq tunable to control rseq registration
This tunable allows applications to register the rseq area instead
of glibc.
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
diff --git a/manual/tunables.texi b/manual/tunables.texi
index 658547c6137bf177..1f5c410288eeecec 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -413,6 +413,16 @@ The value is measured in bytes. The default is @samp{41943040}
(fourty mibibytes).
@end deftp
+@deftp Tunable glibc.pthread.rseq
+The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable
+restartable sequences support in @theglibc{}. This enables applications
+to perform direct restartable sequence registration with the kernel.
+The default is @samp{1}, which means that @theglibc{} performs
+registration on behalf of the application.
+
+Restartable sequences are a Linux-specific extension.
+@end deftp
+
@node Hardware Capability Tunables
@section Hardware Capability Tunables
@cindex hardware capability tunables
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index d2b40924dafad316..f405fa356c2955ce 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -369,7 +369,10 @@ start_thread (void *arg)
__ctype_init ();
/* Register rseq TLS to the kernel. */
- rseq_register_current_thread (pd);
+ {
+ bool do_rseq = THREAD_GETMEM (pd, flags) & ATTR_FLAG_DO_RSEQ;
+ rseq_register_current_thread (pd, do_rseq);
+ }
#ifndef __ASSUME_SET_ROBUST_LIST
if (__nptl_set_robust_list_avail)
@@ -678,6 +681,11 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
pd->flags = ((iattr->flags & ~(ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))
| (self->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)));
+ /* Inherit rseq registration state. Without seccomp filters, rseq
+ registration will either always fail or always succeed. */
+ if ((int) THREAD_GETMEM_VOLATILE (self, rseq_area.cpu_id) >= 0)
+ pd->flags |= ATTR_FLAG_DO_RSEQ;
+
/* Initialize the field for the ID of the thread which is waiting
for us. This is a self-reference in case the thread is created
detached. */
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
index fedb876fdb2642d2..b39dfbff2c6678d5 100644
--- a/sysdeps/nptl/dl-tls_init_tp.c
+++ b/sysdeps/nptl/dl-tls_init_tp.c
@@ -23,6 +23,9 @@
#include <tls.h>
#include <rseq-internal.h>
+#define TUNABLE_NAMESPACE pthread
+#include <dl-tunables.h>
+
#ifndef __ASSUME_SET_ROBUST_LIST
bool __nptl_set_robust_list_avail;
rtld_hidden_data_def (__nptl_set_robust_list_avail)
@@ -92,7 +95,13 @@ __tls_init_tp (void)
}
}
- rseq_register_current_thread (pd);
+ {
+ bool do_rseq = true;
+#if HAVE_TUNABLES
+ do_rseq = TUNABLE_GET (rseq, int, NULL);
+#endif
+ rseq_register_current_thread (pd, do_rseq);
+ }
/* Set initial thread's stack block from 0 up to __libc_stack_end.
It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list
index ac5d053298725468..d24f4be0d08ba407 100644
--- a/sysdeps/nptl/dl-tunables.list
+++ b/sysdeps/nptl/dl-tunables.list
@@ -27,5 +27,11 @@ glibc {
type: SIZE_T
default: 41943040
}
+ rseq {
+ type: INT_32
+ minval: 0
+ maxval: 1
+ default: 1
+ }
}
}
diff --git a/sysdeps/nptl/internaltypes.h b/sysdeps/nptl/internaltypes.h
index 50a2ad19ae7210ae..8205c6d15a918952 100644
--- a/sysdeps/nptl/internaltypes.h
+++ b/sysdeps/nptl/internaltypes.h
@@ -49,6 +49,7 @@ struct pthread_attr
#define ATTR_FLAG_OLDATTR 0x0010
#define ATTR_FLAG_SCHED_SET 0x0020
#define ATTR_FLAG_POLICY_SET 0x0040
+#define ATTR_FLAG_DO_RSEQ 0x0080
/* Used to allocate a pthread_attr_t object which is also accessed
internally. */
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index f84ccd6bbb3b16ad..d30d21898b402d1e 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -135,6 +135,12 @@ tests-internal += \
tst-sigcontext-get_pc \
# tests-internal
+ifneq (no,$(have-tunables))
+tests-internal += \
+ tst-rseq-disable \
+ # tests-internal $(have-tunables)
+endif
+
tests-time64 += \
tst-adjtimex-time64 \
tst-clock_adjtime-time64 \
@@ -226,6 +232,8 @@ $(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-consts.py
< /dev/null > $@ 2>&1; $(evaluate-test)
$(objpfx)tst-mman-consts.out: $(sysdeps-linux-python-deps)
+tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0
+
endif # $(subdir) == misc
ifeq ($(subdir),time)
diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
index 909f5478251d3d13..15bc7ffd6eda632d 100644
--- a/sysdeps/unix/sysv/linux/rseq-internal.h
+++ b/sysdeps/unix/sysv/linux/rseq-internal.h
@@ -21,22 +21,27 @@
#include <sysdep.h>
#include <errno.h>
#include <kernel-features.h>
+#include <stdbool.h>
#include <stdio.h>
#include <sys/rseq.h>
#ifdef RSEQ_SIG
static inline void
-rseq_register_current_thread (struct pthread *self)
+rseq_register_current_thread (struct pthread *self, bool do_rseq)
{
- int ret = INTERNAL_SYSCALL_CALL (rseq,
- &self->rseq_area, sizeof (self->rseq_area),
- 0, RSEQ_SIG);
- if (INTERNAL_SYSCALL_ERROR_P (ret))
- THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
+ if (do_rseq)
+ {
+ int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area,
+ sizeof (self->rseq_area),
+ 0, RSEQ_SIG);
+ if (!INTERNAL_SYSCALL_ERROR_P (ret))
+ return;
+ }
+ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
}
#else /* RSEQ_SIG */
static inline void
-rseq_register_current_thread (struct pthread *self)
+rseq_register_current_thread (struct pthread *self, bool do_rseq)
{
THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
}
diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
new file mode 100644
index 0000000000000000..000e351872fc2f76
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
@@ -0,0 +1,89 @@
+/* Test disabling of rseq registration via tunable.
+ Copyright (C) 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/>. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/xthread.h>
+#include <sysdep.h>
+#include <unistd.h>
+
+#ifdef RSEQ_SIG
+
+/* Check that rseq can be registered and has not been taken by glibc. */
+static void
+check_rseq_disabled (void)
+{
+ struct pthread *pd = THREAD_SELF;
+ TEST_COMPARE ((int) pd->rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
+
+ int ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area),
+ 0, RSEQ_SIG);
+ if (ret == 0)
+ {
+ ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area),
+ RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
+ TEST_COMPARE (ret, 0);
+ pd->rseq_area.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
+ }
+ else
+ {
+ TEST_VERIFY (errno != -EINVAL);
+ TEST_VERIFY (errno != -EBUSY);
+ }
+}
+
+static void *
+thread_func (void *ignored)
+{
+ check_rseq_disabled ();
+ return NULL;
+}
+
+static void
+proc_func (void *ignored)
+{
+ check_rseq_disabled ();
+}
+
+static int
+do_test (void)
+{
+ puts ("info: checking main thread");
+ check_rseq_disabled ();
+
+ puts ("info: checking main thread (2)");
+ check_rseq_disabled ();
+
+ puts ("info: checking new thread");
+ xpthread_join (xpthread_create (NULL, thread_func, NULL));
+
+ puts ("info: checking subprocess");
+ support_isolate_in_subprocess (proc_func, NULL);
+
+ return 0;
+}
+#else /* !RSEQ_SIG */
+static int
+do_test (void)
+{
+ FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test");
+}
+#endif
+
+#include <support/test-driver.c>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,585 @@
commit 15a0c5730d1d5aeb95f50c9ec7470640084feae8
Author: Chung-Lin Tang <cltang@codesourcery.com>
Date: Thu Oct 21 21:41:22 2021 +0800
elf: Fix slow DSO sorting behavior in dynamic loader (BZ #17645)
This second patch contains the actual implementation of a new sorting algorithm
for shared objects in the dynamic loader, which solves the slow behavior that
the current "old" algorithm falls into when the DSO set contains circular
dependencies.
The new algorithm implemented here is simply depth-first search (DFS) to obtain
the Reverse-Post Order (RPO) sequence, a topological sort. A new l_visited:1
bitfield is added to struct link_map to more elegantly facilitate such a search.
The DFS algorithm is applied to the input maps[nmap-1] backwards towards
maps[0]. This has the effect of a more "shallow" recursion depth in general
since the input is in BFS. Also, when combined with the natural order of
processing l_initfini[] at each node, this creates a resulting output sorting
closer to the intuitive "left-to-right" order in most cases.
Another notable implementation adjustment related to this _dl_sort_maps change
is the removing of two char arrays 'used' and 'done' in _dl_close_worker to
represent two per-map attributes. This has been changed to simply use two new
bit-fields l_map_used:1, l_map_done:1 added to struct link_map. This also allows
discarding the clunky 'used' array sorting that _dl_sort_maps had to sometimes
do along the way.
Tunable support for switching between different sorting algorithms at runtime is
also added. A new tunable 'glibc.rtld.dynamic_sort' with current valid values 1
(old algorithm) and 2 (new DFS algorithm) has been added. At time of commit
of this patch, the default setting is 1 (old algorithm).
Signed-off-by: Chung-Lin Tang <cltang@codesourcery.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/elf/dl-close.c b/elf/dl-close.c
index cd7b9c9fe83a1a44..f6fbf9de7d78555b 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -167,8 +167,6 @@ _dl_close_worker (struct link_map *map, bool force)
bool any_tls = false;
const unsigned int nloaded = ns->_ns_nloaded;
- char used[nloaded];
- char done[nloaded];
struct link_map *maps[nloaded];
/* Run over the list and assign indexes to the link maps and enter
@@ -176,24 +174,21 @@ _dl_close_worker (struct link_map *map, bool force)
int idx = 0;
for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next)
{
+ l->l_map_used = 0;
+ l->l_map_done = 0;
l->l_idx = idx;
maps[idx] = l;
++idx;
-
}
assert (idx == nloaded);
- /* Prepare the bitmaps. */
- memset (used, '\0', sizeof (used));
- memset (done, '\0', sizeof (done));
-
/* Keep track of the lowest index link map we have covered already. */
int done_index = -1;
while (++done_index < nloaded)
{
struct link_map *l = maps[done_index];
- if (done[done_index])
+ if (l->l_map_done)
/* Already handled. */
continue;
@@ -204,12 +199,12 @@ _dl_close_worker (struct link_map *map, bool force)
/* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why
acquire is sufficient and correct. */
&& atomic_load_acquire (&l->l_tls_dtor_count) == 0
- && !used[done_index])
+ && !l->l_map_used)
continue;
/* We need this object and we handle it now. */
- done[done_index] = 1;
- used[done_index] = 1;
+ l->l_map_used = 1;
+ l->l_map_done = 1;
/* Signal the object is still needed. */
l->l_idx = IDX_STILL_USED;
@@ -225,9 +220,9 @@ _dl_close_worker (struct link_map *map, bool force)
{
assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded);
- if (!used[(*lp)->l_idx])
+ if (!(*lp)->l_map_used)
{
- used[(*lp)->l_idx] = 1;
+ (*lp)->l_map_used = 1;
/* If we marked a new object as used, and we've
already processed it, then we need to go back
and process again from that point forward to
@@ -250,9 +245,9 @@ _dl_close_worker (struct link_map *map, bool force)
{
assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded);
- if (!used[jmap->l_idx])
+ if (!jmap->l_map_used)
{
- used[jmap->l_idx] = 1;
+ jmap->l_map_used = 1;
if (jmap->l_idx - 1 < done_index)
done_index = jmap->l_idx - 1;
}
@@ -262,8 +257,7 @@ _dl_close_worker (struct link_map *map, bool force)
/* Sort the entries. We can skip looking for the binary itself which is
at the front of the search list for the main namespace. */
- _dl_sort_maps (maps + (nsid == LM_ID_BASE), nloaded - (nsid == LM_ID_BASE),
- used + (nsid == LM_ID_BASE), true);
+ _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
/* Call all termination functions at once. */
#ifdef SHARED
@@ -280,7 +274,7 @@ _dl_close_worker (struct link_map *map, bool force)
/* All elements must be in the same namespace. */
assert (imap->l_ns == nsid);
- if (!used[i])
+ if (!imap->l_map_used)
{
assert (imap->l_type == lt_loaded && !imap->l_nodelete_active);
@@ -333,7 +327,7 @@ _dl_close_worker (struct link_map *map, bool force)
if (i < first_loaded)
first_loaded = i;
}
- /* Else used[i]. */
+ /* Else imap->l_map_used. */
else if (imap->l_type == lt_loaded)
{
struct r_scope_elem *new_list = NULL;
@@ -560,7 +554,7 @@ _dl_close_worker (struct link_map *map, bool force)
for (unsigned int i = first_loaded; i < nloaded; ++i)
{
struct link_map *imap = maps[i];
- if (!used[i])
+ if (!imap->l_map_used)
{
assert (imap->l_type == lt_loaded);
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 087a49b212a96920..237d9636c5be780c 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -613,10 +613,9 @@ Filters not supported with LD_TRACE_PRELINKING"));
/* If libc.so.6 is the main map, it participates in the sort, so
that the relocation order is correct regarding libc.so.6. */
- if (l_initfini[0] == GL (dl_ns)[l_initfini[0]->l_ns].libc_map)
- _dl_sort_maps (l_initfini, nlist, NULL, false);
- else
- _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
+ _dl_sort_maps (l_initfini, nlist,
+ (l_initfini[0] != GL (dl_ns)[l_initfini[0]->l_ns].libc_map),
+ false);
/* Terminate the list of dependencies. */
l_initfini[nlist] = NULL;
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index 6dbdfe4b3ebbeb89..c683884c355dfd52 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -92,8 +92,7 @@ _dl_fini (void)
/* Now we have to do the sorting. We can skip looking for the
binary itself which is at the front of the search list for
the main namespace. */
- _dl_sort_maps (maps + (ns == LM_ID_BASE), nmaps - (ns == LM_ID_BASE),
- NULL, true);
+ _dl_sort_maps (maps, nmaps, (ns == LM_ID_BASE), true);
/* We do not rely on the linked list of loaded object anymore
from this point on. We have our own list here (maps). The
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
index d21770267a37e128..a274ed66cc987735 100644
--- a/elf/dl-sort-maps.c
+++ b/elf/dl-sort-maps.c
@@ -16,16 +16,24 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <assert.h>
#include <ldsodefs.h>
+#include <elf/dl-tunables.h>
+/* Note: this is the older, "original" sorting algorithm, being used as
+ default up to 2.35.
-/* Sort array MAPS according to dependencies of the contained objects.
- Array USED, if non-NULL, is permutated along MAPS. If FOR_FINI this is
- called for finishing an object. */
-void
-_dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
- bool for_fini)
+ Sort array MAPS according to dependencies of the contained objects.
+ If FOR_FINI is true, this is called for finishing an object. */
+static void
+_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
+ unsigned int skip, bool for_fini)
{
+ /* Allows caller to do the common optimization of skipping the first map,
+ usually the main binary. */
+ maps += skip;
+ nmaps -= skip;
+
/* A list of one element need not be sorted. */
if (nmaps <= 1)
return;
@@ -66,14 +74,6 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
(k - i) * sizeof (maps[0]));
maps[k] = thisp;
- if (used != NULL)
- {
- char here_used = used[i];
- memmove (&used[i], &used[i + 1],
- (k - i) * sizeof (used[0]));
- used[k] = here_used;
- }
-
if (seen[i + 1] > nmaps - i)
{
++i;
@@ -120,3 +120,183 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
next:;
}
}
+
+#if !HAVE_TUNABLES
+/* In this case, just default to the original algorithm. */
+strong_alias (_dl_sort_maps_original, _dl_sort_maps);
+#else
+
+/* We use a recursive function due to its better clarity and ease of
+ implementation, as well as faster execution speed. We already use
+ alloca() for list allocation during the breadth-first search of
+ dependencies in _dl_map_object_deps(), and this should be on the
+ same order of worst-case stack usage.
+
+ Note: the '*rpo' parameter is supposed to point to one past the
+ last element of the array where we save the sort results, and is
+ decremented before storing the current map at each level. */
+
+static void
+dfs_traversal (struct link_map ***rpo, struct link_map *map,
+ bool *do_reldeps)
+{
+ if (map->l_visited)
+ return;
+
+ map->l_visited = 1;
+
+ if (map->l_initfini)
+ {
+ for (int i = 0; map->l_initfini[i] != NULL; i++)
+ {
+ struct link_map *dep = map->l_initfini[i];
+ if (dep->l_visited == 0
+ && dep->l_main_map == 0)
+ dfs_traversal (rpo, dep, do_reldeps);
+ }
+ }
+
+ if (__glibc_unlikely (do_reldeps != NULL && map->l_reldeps != NULL))
+ {
+ /* Indicate that we encountered relocation dependencies during
+ traversal. */
+ *do_reldeps = true;
+
+ for (int m = map->l_reldeps->act - 1; m >= 0; m--)
+ {
+ struct link_map *dep = map->l_reldeps->list[m];
+ if (dep->l_visited == 0
+ && dep->l_main_map == 0)
+ dfs_traversal (rpo, dep, do_reldeps);
+ }
+ }
+
+ *rpo -= 1;
+ **rpo = map;
+}
+
+/* Topologically sort array MAPS according to dependencies of the contained
+ objects. */
+
+static void
+_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
+ unsigned int skip __attribute__ ((unused)), bool for_fini)
+{
+ for (int i = nmaps - 1; i >= 0; i--)
+ maps[i]->l_visited = 0;
+
+ /* We apply DFS traversal for each of maps[i] until the whole total order
+ is found and we're at the start of the Reverse-Postorder (RPO) sequence,
+ which is a topological sort.
+
+ We go from maps[nmaps - 1] backwards towards maps[0] at this level.
+ Due to the breadth-first search (BFS) ordering we receive, going
+ backwards usually gives a more shallow depth-first recursion depth,
+ adding more stack usage safety. Also, combined with the natural
+ processing order of l_initfini[] at each node during DFS, this maintains
+ an ordering closer to the original link ordering in the sorting results
+ under most simpler cases.
+
+ Another reason we order the top level backwards, it that maps[0] is
+ usually exactly the main object of which we're in the midst of
+ _dl_map_object_deps() processing, and maps[0]->l_initfini[] is still
+ blank. If we start the traversal from maps[0], since having no
+ dependencies yet filled in, maps[0] will always be immediately
+ incorrectly placed at the last place in the order (first in reverse).
+ Adjusting the order so that maps[0] is last traversed naturally avoids
+ this problem.
+
+ Further, the old "optimization" of skipping the main object at maps[0]
+ from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general
+ no longer valid, since traversing along object dependency-links
+ may "find" the main object even when it is not included in the initial
+ order (e.g. a dlopen()'ed shared object can have circular dependencies
+ linked back to itself). In such a case, traversing N-1 objects will
+ create a N-object result, and raise problems.
+
+ To summarize, just passing in the full list, and iterating from back
+ to front makes things much more straightforward. */
+
+ /* Array to hold RPO sorting results, before we copy back to maps[]. */
+ struct link_map *rpo[nmaps];
+
+ /* The 'head' position during each DFS iteration. Note that we start at
+ one past the last element due to first-decrement-then-store (see the
+ bottom of above dfs_traversal() routine). */
+ struct link_map **rpo_head = &rpo[nmaps];
+
+ bool do_reldeps = false;
+ bool *do_reldeps_ref = (for_fini ? &do_reldeps : NULL);
+
+ for (int i = nmaps - 1; i >= 0; i--)
+ {
+ dfs_traversal (&rpo_head, maps[i], do_reldeps_ref);
+
+ /* We can break early if all objects are already placed. */
+ if (rpo_head == rpo)
+ goto end;
+ }
+ assert (rpo_head == rpo);
+
+ end:
+ /* Here we may do a second pass of sorting, using only l_initfini[]
+ static dependency links. This is avoided if !FOR_FINI or if we didn't
+ find any reldeps in the first DFS traversal.
+
+ The reason we do this is: while it is unspecified how circular
+ dependencies should be handled, the presumed reasonable behavior is to
+ have destructors to respect static dependency links as much as possible,
+ overriding reldeps if needed. And the first sorting pass, which takes
+ l_initfini/l_reldeps links equally, may not preserve this priority.
+
+ Hence we do a 2nd sorting pass, taking only DT_NEEDED links into account
+ (see how the do_reldeps argument to dfs_traversal() is NULL below). */
+ if (do_reldeps)
+ {
+ for (int i = nmaps - 1; i >= 0; i--)
+ rpo[i]->l_visited = 0;
+
+ struct link_map **maps_head = &maps[nmaps];
+ for (int i = nmaps - 1; i >= 0; i--)
+ {
+ dfs_traversal (&maps_head, rpo[i], NULL);
+
+ /* We can break early if all objects are already placed.
+ The below memcpy is not needed in the do_reldeps case here,
+ since we wrote back to maps[] during DFS traversal. */
+ if (maps_head == maps)
+ return;
+ }
+ assert (maps_head == maps);
+ return;
+ }
+
+ memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
+}
+
+void
+_dl_sort_maps_init (void)
+{
+ int32_t algorithm = TUNABLE_GET (glibc, rtld, dynamic_sort, int32_t, NULL);
+ GLRO(dl_dso_sort_algo) = algorithm == 1 ? dso_sort_algorithm_original
+ : dso_sort_algorithm_dfs;
+}
+
+void
+_dl_sort_maps (struct link_map **maps, unsigned int nmaps,
+ unsigned int skip, bool for_fini)
+{
+ /* It can be tempting to use a static function pointer to store and call
+ the current selected sorting algorithm routine, but experimentation
+ shows that current processors still do not handle indirect branches
+ that efficiently, plus a static function pointer will involve
+ PTR_MANGLE/DEMANGLE, further impairing performance of small, common
+ input cases. A simple if-case with direct function calls appears to
+ be the fastest. */
+ if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original))
+ _dl_sort_maps_original (maps, nmaps, skip, for_fini);
+ else
+ _dl_sort_maps_dfs (maps, nmaps, skip, for_fini);
+}
+
+#endif /* HAVE_TUNABLES. */
diff --git a/elf/dl-support.c b/elf/dl-support.c
index d8c06ba7eb4c76ea..c5ee5d33aa7e1d65 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -166,6 +166,8 @@ size_t _dl_phnum;
uint64_t _dl_hwcap;
uint64_t _dl_hwcap2;
+enum dso_sort_algorithm _dl_dso_sort_algo;
+
/* The value of the FPU control word the kernel will preset in hardware. */
fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index 2c684c2db2a1f59b..4dc366eea445e974 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -231,6 +231,9 @@ _dl_sysdep_start (void **start_argptr,
__tunables_init (_environ);
+ /* Initialize DSO sorting algorithm after tunables. */
+ _dl_sort_maps_init ();
+
#ifdef DL_SYSDEP_INIT
DL_SYSDEP_INIT;
#endif
diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
index 8ddd4a23142a941b..46ffb2378416f90f 100644
--- a/elf/dl-tunables.list
+++ b/elf/dl-tunables.list
@@ -156,4 +156,13 @@ glibc {
security_level: SXID_IGNORE
}
}
+
+ rtld {
+ dynamic_sort {
+ type: INT_32
+ minval: 1
+ maxval: 2
+ default: 1
+ }
+ }
}
diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
index 873ddf55d91155c6..5f7f18ef270bc12d 100644
--- a/elf/dso-sort-tests-1.def
+++ b/elf/dso-sort-tests-1.def
@@ -62,5 +62,5 @@ output: b>a>{}<a<b
# The below expected outputs are what the two algorithms currently produce
# respectively, for regression testing purposes.
tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
-xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
+output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
diff --git a/elf/rtld.c b/elf/rtld.c
index 6bbb373c5743cb99..84eac9a8df7125a6 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1426,6 +1426,9 @@ dl_main (const ElfW(Phdr) *phdr,
main_map->l_name = (char *) "";
*user_entry = main_map->l_entry;
+ /* Set bit indicating this is the main program map. */
+ main_map->l_main_map = 1;
+
#ifdef HAVE_AUX_VECTOR
/* Adjust the on-stack auxiliary vector so that it looks like the
binary was executed directly. */
diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
index 9f66c528855fb21d..9bf572715f996ca6 100644
--- a/elf/tst-rtld-list-tunables.exp
+++ b/elf/tst-rtld-list-tunables.exp
@@ -10,5 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+)
glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+)
glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+)
glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+)
+glibc.rtld.dynamic_sort: 1 (min: 1, max: 2)
glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+)
diff --git a/include/link.h b/include/link.h
index c46aced9f7b43ba0..4dcf01d8aea90bc2 100644
--- a/include/link.h
+++ b/include/link.h
@@ -181,6 +181,11 @@ struct link_map
unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
unsigned int l_reserved:2; /* Reserved for internal use. */
+ unsigned int l_main_map:1; /* Nonzero for the map of the main program. */
+ unsigned int l_visited:1; /* Used internally for map dependency
+ graph traversal. */
+ unsigned int l_map_used:1; /* These two bits are used during traversal */
+ unsigned int l_map_done:1; /* of maps in _dl_close_worker. */
unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed
to by `l_phdr' is allocated. */
unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in
diff --git a/manual/tunables.texi b/manual/tunables.texi
index 658547c6137bf177..10f4d75993f9940f 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -309,6 +309,17 @@ changed once allocated at process startup. The default allocation of
optional static TLS is 512 bytes and is allocated in every thread.
@end deftp
+@deftp Tunable glibc.rtld.dynamic_sort
+Sets the algorithm to use for DSO sorting, valid values are @samp{1} and
+@samp{2}. For value of @samp{1}, an older O(n^3) algorithm is used, which is
+long time tested, but may have performance issues when dependencies between
+shared objects contain cycles due to circular dependencies. When set to the
+value of @samp{2}, a different algorithm is used, which implements a
+topological sort through depth-first search, and does not exhibit the
+performance issues of @samp{1}.
+
+The default value of this tunable is @samp{1}.
+@end deftp
@node Elision Tunables
@section Elision Tunables
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index fcbbf6974827cdf1..bcf1f199c5985c65 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -245,6 +245,13 @@ enum allowmask
};
+/* DSO sort algorithm to use (check dl-sort-maps.c). */
+enum dso_sort_algorithm
+ {
+ dso_sort_algorithm_original,
+ dso_sort_algorithm_dfs
+ };
+
struct audit_ifaces
{
void (*activity) (uintptr_t *, unsigned int);
@@ -672,6 +679,8 @@ struct rtld_global_ro
platforms. */
EXTERN uint64_t _dl_hwcap2;
+ EXTERN enum dso_sort_algorithm _dl_dso_sort_algo;
+
#ifdef SHARED
/* We add a function table to _rtld_global which is then used to
call the function instead of going through the PLT. The result
@@ -1098,7 +1107,7 @@ extern void _dl_fini (void) attribute_hidden;
/* Sort array MAPS according to dependencies of the contained objects. */
extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
- char *used, bool for_fini) attribute_hidden;
+ unsigned int skip, bool for_fini) attribute_hidden;
/* The dynamic linker calls this function before and having changing
any shared object mappings. The `r_state' member of `struct r_debug'
@@ -1225,6 +1234,9 @@ extern struct link_map * _dl_get_dl_main_map (void)
# endif
#endif
+/* Initialize the DSO sort algorithm to use. */
+extern void _dl_sort_maps_init (void) attribute_hidden;
+
/* Initialization of libpthread for statically linked applications.
If libpthread is not linked in, this is an empty function. */
void __pthread_initialize_minimal (void) weak_function;

View File

@ -0,0 +1,25 @@
commit d3bf2f5927d51258a51ac7fde04f4805f8ee294a
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed Nov 3 09:19:30 2021 -0300
elf: Do not run DSO sorting if tunables is not enabled
Since the argorithm selection requires tunables.
Checked on x86_64-linux-gnu with --enable-tunables=no.
diff --git a/elf/Makefile b/elf/Makefile
index 8dd2b24328113536..02ee834fdaf00a26 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -483,8 +483,10 @@ include $(objpfx)$(1).generated-makefile
endef
# Generate from each testcase description file
+ifeq (yes,$(have-tunables))
$(eval $(call include_dsosort_tests,dso-sort-tests-1.def))
$(eval $(call include_dsosort_tests,dso-sort-tests-2.def))
+endif
check-abi: $(objpfx)check-abi-ld.out
tests-special += $(objpfx)check-abi-ld.out

View File

@ -0,0 +1,189 @@
commit b4bbedb1e75737a80bcc3d53d6eef1fbe0b5f4d5
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Sat Nov 6 14:13:27 2021 -0700
dso-ordering-test.py: Put all sources in one directory [BZ #28550]
Put all sources for DSO sorting tests in the dso-sort-tests-src directory
and compile test relocatable objects with
$(objpfx)tst-dso-ordering1-dir/tst-dso-ordering1-a.os: $(objpfx)dso-sort-tests-src/tst-dso-ordering1-a.c
$(compile.c) $(OUTPUT_OPTION)
to avoid random $< values from $(before-compile) when compiling test
relocatable objects with
$(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c)
compile-command.c = $(compile.c) $(OUTPUT_OPTION) $(compile-mkdep-flags)
compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS)
for 3 "make -j 28" parallel builds on a machine with 112 cores at the
same time.
This partially fixes BZ #28550.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
index 944ee740527d60fd..bde0406be9da14fc 100644
--- a/scripts/dso-ordering-test.py
+++ b/scripts/dso-ordering-test.py
@@ -526,9 +526,13 @@ def process_testcase(t):
base_test_name = t.test_name
test_subdir = base_test_name + "-dir"
testpfx = objpfx + test_subdir + "/"
+ test_srcdir = "dso-sort-tests-src/"
+ testpfx_src = objpfx + test_srcdir
if not os.path.exists(testpfx):
os.mkdir(testpfx)
+ if not os.path.exists(testpfx_src):
+ os.mkdir(testpfx_src)
def find_objs_not_depended_on(t):
objs_not_depended_on = []
@@ -595,6 +599,11 @@ def process_testcase(t):
# Print out needed Makefile fragments for use in glibc/elf/Makefile.
module_names = ""
for o in test_descr.objs:
+ rule = ("$(objpfx)" + test_subdir + "/" + test_name
+ + "-" + o + ".os: $(objpfx)" + test_srcdir
+ + test_name + "-" + o + ".c\n"
+ "\t$(compile.c) $(OUTPUT_OPTION)\n")
+ makefile.write (rule)
module_names += " " + test_subdir + "/" + test_name + "-" + o
makefile.write("modules-names +=%s\n" % (module_names))
@@ -637,7 +646,7 @@ def process_testcase(t):
# object. This only needs to be done at most once for
# an object name.
if not dep in fake_created:
- f = open(testpfx + test_name + "-" + dep
+ f = open(testpfx_src + test_name + "-" + dep
+ ".FAKE.c", "w")
f.write(" \n")
f.close()
@@ -648,6 +657,12 @@ def process_testcase(t):
% (test_name + "-" + dep + ".FAKE.so",
("$(objpfx)" + test_subdir + "/"
+ test_name + "-" + dep + ".so")))
+ rule = ("$(objpfx)" + test_subdir + "/"
+ + test_name + "-" + dep + ".FAKE.os: "
+ "$(objpfx)" + test_srcdir
+ + test_name + "-" + dep + ".FAKE.c\n"
+ "\t$(compile.c) $(OUTPUT_OPTION)\n")
+ makefile.write (rule)
makefile.write \
("modules-names += %s\n"
% (test_subdir + "/"
@@ -687,6 +702,10 @@ def process_testcase(t):
+ test_descr.soname_map['#'] + ".so")
ldflags += (" -Wl,-soname=" + soname)
makefile.write("LDFLAGS-%s = %s\n" % (test_name, ldflags))
+ rule = ("$(objpfx)" + test_subdir + "/" + test_name + ".o: "
+ "$(objpfx)" + test_srcdir + test_name + ".c\n"
+ "\t$(compile.c) $(OUTPUT_OPTION)\n")
+ makefile.write (rule)
not_depended_objs = find_objs_not_depended_on(test_descr)
if not_depended_objs:
@@ -745,7 +764,7 @@ def process_testcase(t):
" something_failed=true\n"
"else\n"
" diff -wu ${common_objpfx}elf/%s/%s%s.output \\\n"
- " ${common_objpfx}elf/%s/%s%s.exp\n"
+ " ${common_objpfx}elf/%s%s%s.exp\n"
" if [ $? -ne 0 ]; then\n"
" echo '%sFAIL: %s%s expected output comparison'\n"
" something_failed=true\n"
@@ -753,14 +772,14 @@ def process_testcase(t):
"fi\n"
% (("X" if xfail else ""), test_name, tunable_descr,
test_subdir, test_name, tunable_sfx,
- test_subdir, base_test_name, exp_tunable_sfx,
+ test_srcdir, base_test_name, exp_tunable_sfx,
("X" if xfail else ""), test_name, tunable_descr))
# Generate C files according to dependency and calling relations from
# description string.
for obj in test_descr.objs:
src_name = test_name + "-" + obj + ".c"
- f = open(testpfx + src_name, "w")
+ f = open(testpfx_src + src_name, "w")
if obj in test_descr.callrefs:
called_objs = test_descr.callrefs[obj]
for callee in called_objs:
@@ -804,7 +823,7 @@ def process_testcase(t):
f.close()
# Open C file for writing main program
- f = open(testpfx + test_name + ".c", "w")
+ f = open(testpfx_src + test_name + ".c", "w")
# if there are some operations in main(), it means we need -ldl
f.write("#include <stdio.h>\n")
@@ -885,7 +904,7 @@ def process_testcase(t):
for obj in test_descr.objs:
src_name = test_name + "-" + obj + ".c"
obj_name = test_name + "-" + obj + ".os"
- run_cmd([build_gcc, "-c", "-fPIC", testpfx + src_name,
+ run_cmd([build_gcc, "-c", "-fPIC", testpfx_src + src_name,
"-o", testpfx + obj_name])
obj_processed = {}
@@ -903,10 +922,12 @@ def process_testcase(t):
deps.append(dep + ".FAKE")
if not dep in fake_created:
base_name = testpfx + test_name + "-" + dep
+ src_base_name = (testpfx_src + test_name
+ + "-" + dep)
cmd = [build_gcc, "-Wl,--no-as-needed",
("-Wl,-soname=" + base_name + ".so"),
"-shared", base_name + ".FAKE.c",
- "-o", base_name + ".FAKE.so"]
+ "-o", src_base_name + ".FAKE.so"]
run_cmd(cmd)
fake_created[dep] = True
dso_deps = map(lambda d: testpfx + test_name + "-" + d + ".so",
@@ -932,7 +953,7 @@ def process_testcase(t):
main_deps = map(lambda d: testpfx + test_name + "-" + d + ".so",
deps)
cmd = [build_gcc, "-Wl,--no-as-needed", "-o", testpfx + test_name,
- testpfx + test_name + ".c", "-L%s" % (os.getcwd()),
+ testpfx_src + test_name + ".c", "-L%s" % (os.getcwd()),
"-Wl,-rpath-link=%s" % (os.getcwd())]
if '#' in test_descr.soname_map:
soname = ("-Wl,-soname=" + testpfx + test_name + "-"
@@ -987,14 +1008,14 @@ def process_testcase(t):
sfx = ""
if r[0] != "":
sfx = "-" + r[0].replace("=","_")
- f = open(testpfx + t.test_name + sfx + ".exp", "w")
+ f = open(testpfx_src + t.test_name + sfx + ".exp", "w")
(output, xfail) = r[1]
f.write('%s' % output)
f.close()
# Create header part of top-level testcase shell script, to wrap execution
# and output comparison together.
- t.sh = open(testpfx + t.test_name + ".sh", "w")
+ t.sh = open(testpfx_src + t.test_name + ".sh", "w")
t.sh.write("#!/bin/sh\n")
t.sh.write("# Test driver for %s, generated by "
"dso-ordering-test.py\n" % (t.test_name))
@@ -1022,12 +1043,12 @@ def process_testcase(t):
sfx = ""
if r[0] != "":
sfx = "-" + r[0].replace("=","_")
- expected_output_files += " $(objpfx)%s/%s%s.exp" % (test_subdir,
+ expected_output_files += " $(objpfx)%s%s%s.exp" % (test_srcdir,
t.test_name, sfx)
makefile.write \
- ("$(objpfx)%s.out: $(objpfx)%s/%s.sh%s "
+ ("$(objpfx)%s.out: $(objpfx)%s%s.sh%s "
"$(common-objpfx)support/test-run-command\n"
- % (t.test_name, test_subdir, t.test_name,
+ % (t.test_name, test_srcdir, t.test_name,
expected_output_files))
makefile.write("\t$(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' "
"'$(run-program-env)' > $@; $(evaluate-test)\n")

View File

@ -0,0 +1,45 @@
commit 1f67d8286b5da9266a138198ef1f15c27cbb0010
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Mon Nov 15 16:28:39 2021 -0800
elf: Use a temporary file to generate Makefile fragments [BZ #28550]
1. Use a temporary file to generate Makefile fragments for DSO sorting
tests and use -include on them.
2. Add Makefile fragments to postclean-generated so that a "make clean"
removes the autogenerated fragments and a subsequent "make" regenerates
them.
This partially fixes BZ #28550.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/elf/Makefile b/elf/Makefile
index 02ee834fdaf00a26..535ba4260fb98e64 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -471,6 +471,7 @@ tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \
$(objpfx)tst-unused-dep-cmp.out
endif
+ifndef avoid-generated
# DSO sorting tests:
# The dso-ordering-test.py script generates testcase source files in $(objpfx),
# creating a $(objpfx)<testcase-name>-dir for each testcase, and creates a
@@ -478,9 +479,14 @@ endif
define include_dsosort_tests
$(objpfx)$(1).generated-makefile: $(1)
$(PYTHON) $(..)scripts/dso-ordering-test.py \
- --description-file $$< --objpfx $(objpfx) --output-makefile $$@
-include $(objpfx)$(1).generated-makefile
+ --description-file $$< --objpfx $(objpfx) --output-makefile $$@T
+ mv $$@T $$@
+-include $(objpfx)$(1).generated-makefile
endef
+endif
+
+postclean-generated += $(objpfx)/dso-sort-tests-2.generated-makefile \
+ $(objpfx)/dso-sort-tests-2.generated-makefile
# Generate from each testcase description file
ifeq (yes,$(have-tunables))

View File

@ -0,0 +1,49 @@
commit 0884724a95b60452ad483dbe086d237d02ba624d
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Dec 14 12:37:44 2021 +0100
elf: Use new dependency sorting algorithm by default
The default has to change eventually, and there are no known failures
that require a delay.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
index 46ffb2378416f90f..ffcd7f18d4fafb91 100644
--- a/elf/dl-tunables.list
+++ b/elf/dl-tunables.list
@@ -162,7 +162,7 @@ glibc {
type: INT_32
minval: 1
maxval: 2
- default: 1
+ default: 2
}
}
}
diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
index 9bf572715f996ca6..44e4834cfb431633 100644
--- a/elf/tst-rtld-list-tunables.exp
+++ b/elf/tst-rtld-list-tunables.exp
@@ -10,6 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+)
glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+)
glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+)
glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+)
-glibc.rtld.dynamic_sort: 1 (min: 1, max: 2)
+glibc.rtld.dynamic_sort: 2 (min: 1, max: 2)
glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+)
diff --git a/manual/tunables.texi b/manual/tunables.texi
index 10f4d75993f9940f..7c3b28d029410a6f 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -318,7 +318,7 @@ value of @samp{2}, a different algorithm is used, which implements a
topological sort through depth-first search, and does not exhibit the
performance issues of @samp{1}.
-The default value of this tunable is @samp{1}.
+The default value of this tunable is @samp{2}.
@end deftp
@node Elision Tunables

View File

@ -0,0 +1,547 @@
commit 28713c06129f8f64f88c423266e6ff2880216509
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Mon Dec 13 09:43:52 2021 -0800
elf: Sort tests and modules-names
Sort tests and modules-names to reduce future conflicts.
Conflicts:
elf/Makefile
(Usual backport differences. Recreated tests and module-names
from scratch. Note that the upstream sort order is difficult
to fathom.)
diff --git a/elf/Makefile b/elf/Makefile
index 535ba4260fb98e64..33df5b4714176adc 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -193,40 +193,134 @@ static-dlopen-environment = \
tst-tls9-static-ENV = $(static-dlopen-environment)
tst-single_threaded-static-dlopen-ENV = $(static-dlopen-environment)
-tests += restest1 preloadtest loadfail multiload origtest resolvfail \
- constload1 order noload filter \
- reldep reldep2 reldep3 reldep4 nodelete nodelete2 \
- nodlopen nodlopen2 lateglobal initfirst global \
- restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
- tst-tls4 tst-tls5 \
- tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \
- tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \
- tst-align tst-align2 \
- tst-dlmodcount tst-dlopenrpath tst-deep1 \
- tst-dlmopen1 tst-dlmopen3 \
- unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
- tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
- tst-addr1 tst-thrlock \
- tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \
- tst-nodelete tst-dlopen-nodelete-reloc) \
- tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
- tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
- tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
- tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
- tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \
- tst-unwind-ctor tst-unwind-main tst-audit13 \
- tst-sonamemove-link tst-sonamemove-dlopen tst-dlopen-tlsmodid \
- tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail \
- tst-dlopenfail-2 \
- tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen \
- tst-audit14 tst-audit15 tst-audit16 tst-audit17 \
- tst-single_threaded tst-single_threaded-pthread \
- tst-tls-ie tst-tls-ie-dlmopen argv0test \
- tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
- tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \
- tst-dl-is_dso tst-ro-dynamic \
- tst-rtld-run-static \
+tests += \
+ argv0test \
+ constload1 \
+ dblload \
+ dblunload \
+ filter \
+ global \
+ initfirst \
+ lateglobal \
+ loadfail \
+ multiload \
+ next \
+ nodelete \
+ nodelete2 \
+ nodlopen \
+ nodlopen2 \
+ noload \
+ order \
+ order2 \
+ origtest \
+ preloadtest \
+ reldep \
+ reldep2 \
+ reldep3 \
+ reldep4 \
+ reldep5 \
+ reldep6 \
+ reldep7 \
+ reldep8 \
+ resolvfail \
+ restest1 \
+ restest2 \
+ tst-absolute-sym \
+ tst-absolute-zero \
+ tst-addr1 \
+ tst-align \
+ tst-align2 \
+ tst-audit1 \
+ tst-audit2 \
+ tst-audit8 \
+ tst-audit9 \
+ tst-audit11 \
+ tst-audit12 \
+ tst-audit13 \
+ tst-audit14 \
+ tst-audit15 \
+ tst-audit16 \
+ tst-audit17 \
+ tst-auditmany \
+ tst-auxobj \
+ tst-auxobj-dlopen \
+ tst-big-note \
+ tst-debug1 \
+ tst-deep1 \
+ tst-dl-is_dso \
+ tst-dlmodcount \
+ tst-dlmopen1 \
+ tst-dlmopen3 \
+ tst-dlmopen-dlerror \
+ tst-dlmopen-gethostbyname \
+ tst-dlopenfail \
+ tst-dlopenfail-2 \
+ tst-dlopenrpath \
+ tst-dlopen-self \
+ tst-dlopen-tlsmodid \
+ tst-dlsym-error \
+ tst-filterobj \
+ tst-filterobj-dlopen \
+ tst-glibc-hwcaps \
+ tst-glibc-hwcaps-mask \
+ tst-glibc-hwcaps-prepend \
+ tst-global1 \
+ tst-initfinilazyfail \
+ tst-initorder \
+ tst-initorder2 \
+ tst-latepthread \
+ tst-main1 \
+ tst-nodelete2 \
+ tst-nodelete-dlclose \
+ tst-nodelete-opened \
+ tst-noload \
+ tst-null-argv \
+ tst-relsort1 \
+ tst-ro-dynamic \
+ tst-rtld-run-static \
+ tst-single_threaded \
+ tst-single_threaded-pthread \
+ tst-sonamemove-dlopen \
+ tst-sonamemove-link \
+ tst-thrlock \
+ tst-tls10 \
+ tst-tls11 \
+ tst-tls12 \
+ tst-tls13 \
+ tst-tls14 \
+ tst-tls15 \
+ tst-tls16 \
+ tst-tls17 \
+ tst-tls18 \
+ tst-tls19 \
+ tst-tls20 \
+ tst-tls21 \
+ tst-tls4 \
+ tst-tls5 \
+ tst-tlsalign \
+ tst-tlsalign-extern \
+ tst-tls-dlinfo \
+ tst-tls-ie \
+ tst-tls-ie-dlmopen \
+ tst-tls-manydynamic \
+ tst-unique1 \
+ tst-unique2 \
+ tst-unwind-ctor \
+ tst-unwind-main \
+ unload3 \
+ unload4 \
+ unload5 \
+ unload6 \
+ unload7 \
+ unload8 \
# reldep9
+tests-cxx = \
+ tst-dlopen-nodelete-reloc \
+ tst-nodelete \
+ tst-unique3 \
+ tst-unique4 \
+
+tests += $(if $(CXX),$(tests-cxx))
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
@@ -264,101 +358,265 @@ tst-tls-many-dynamic-modules-dep-bad = \
extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \
tst-tlsalign-vars.o
test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars
-modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
- testobj1_1 failobj constload2 constload3 unloadmod \
- dep1 dep2 dep3 dep4 vismod1 vismod2 vismod3 \
- nodelmod1 nodelmod2 nodelmod3 nodelmod4 \
- nodel2mod1 nodel2mod2 nodel2mod3 \
- nodlopenmod nodlopenmod2 filtmod1 filtmod2 \
- reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \
- reldep4mod1 reldep4mod2 reldep4mod3 reldep4mod4 \
- neededobj1 neededobj2 neededobj3 neededobj4 \
- neededobj5 neededobj6 firstobj globalmod1 \
- unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \
- dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \
- reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \
- reldep7mod1 reldep7mod2 \
- tst-tlsmod1 tst-tlsmod2 tst-tlsmod3 tst-tlsmod4 \
- tst-tlsmod5 tst-tlsmod6 tst-tlsmod7 tst-tlsmod8 \
- tst-tlsmod9 tst-tlsmod10 tst-tlsmod11 tst-tlsmod12 \
- tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \
- tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \
- $(tlsmod17a-modules) tst-tlsmod17b $(tlsmod18a-modules) \
- tst-tls19mod1 tst-tls19mod2 tst-tls19mod3 \
- circlemod1 circlemod1a circlemod2 circlemod2a \
- circlemod3 circlemod3a \
- reldep8mod1 reldep8mod2 reldep8mod3 \
- reldep9mod1 reldep9mod2 reldep9mod3 \
- tst-alignmod tst-alignmod2 \
- $(modules-execstack-$(have-z-execstack)) \
- tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \
- tst-dlmopen1mod tst-auditmod1 \
- unload3mod1 unload3mod2 unload3mod3 unload3mod4 \
- unload4mod1 unload4mod2 unload4mod3 unload4mod4 \
- unload6mod1 unload6mod2 unload6mod3 \
- unload7mod1 unload7mod2 \
- unload8mod1 unload8mod1x unload8mod2 unload8mod3 \
- order2mod1 order2mod2 order2mod3 order2mod4 \
- tst-unique1mod1 tst-unique1mod2 \
- tst-unique2mod1 tst-unique2mod2 \
- tst-auditmod9a tst-auditmod9b \
- $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \
- tst-nodelete-uniquemod tst-nodelete-rtldmod \
- tst-nodelete-zmod \
- tst-dlopen-nodelete-reloc-mod1 \
- tst-dlopen-nodelete-reloc-mod2 \
- tst-dlopen-nodelete-reloc-mod3 \
- tst-dlopen-nodelete-reloc-mod4 \
- tst-dlopen-nodelete-reloc-mod5 \
- tst-dlopen-nodelete-reloc-mod6 \
- tst-dlopen-nodelete-reloc-mod7 \
- tst-dlopen-nodelete-reloc-mod8 \
- tst-dlopen-nodelete-reloc-mod9 \
- tst-dlopen-nodelete-reloc-mod10 \
- tst-dlopen-nodelete-reloc-mod11 \
- tst-dlopen-nodelete-reloc-mod12 \
- tst-dlopen-nodelete-reloc-mod13 \
- tst-dlopen-nodelete-reloc-mod14 \
- tst-dlopen-nodelete-reloc-mod15 \
- tst-dlopen-nodelete-reloc-mod16 \
- tst-dlopen-nodelete-reloc-mod17) \
- tst-initordera1 tst-initorderb1 \
- tst-initordera2 tst-initorderb2 \
- tst-initordera3 tst-initordera4 \
- tst-initorder2a tst-initorder2b tst-initorder2c \
- tst-initorder2d \
- tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
- tst-array5dep tst-null-argv-lib \
- tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \
- tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
- tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
- tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
- $(tst-tls-many-dynamic-modules-dep) \
- $(tst-tls-many-dynamic-modules-dep-bad) \
- tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
- tst-main1mod tst-absolute-sym-lib \
- tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib \
- tst-audit13mod1 tst-sonamemove-linkmod1 \
- tst-sonamemove-runmod1 tst-sonamemove-runmod2 \
- tst-auditmanymod1 tst-auditmanymod2 tst-auditmanymod3 \
- tst-auditmanymod4 tst-auditmanymod5 tst-auditmanymod6 \
- tst-auditmanymod7 tst-auditmanymod8 tst-auditmanymod9 \
- tst-initlazyfailmod tst-finilazyfailmod \
- tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \
- tst-dlopenfailmod3 tst-dlopenfailnodelmod tst-ldconfig-ld-mod \
- tst-filterobj-flt tst-filterobj-aux tst-filterobj-filtee \
- tst-auditlogmod-1 tst-auditlogmod-2 tst-auditlogmod-3 \
- tst-single_threaded-mod1 tst-single_threaded-mod2 \
- tst-single_threaded-mod3 tst-single_threaded-mod4 \
- tst-tls-ie-mod0 tst-tls-ie-mod1 tst-tls-ie-mod2 \
- tst-tls-ie-mod3 tst-tls-ie-mod4 tst-tls-ie-mod5 \
- tst-tls-ie-mod6 libmarkermod1-1 libmarkermod1-2 libmarkermod1-3 \
- libmarkermod2-1 libmarkermod2-2 \
- libmarkermod3-1 libmarkermod3-2 libmarkermod3-3 \
- libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
- tst-tls20mod-bad tst-tls21mod tst-dlmopen-dlerror-mod \
- tst-auxvalmod \
- tst-dlmopen-gethostbyname-mod tst-ro-dynamic-mod \
+modules-names = \
+ circlemod1 \
+ circlemod1a \
+ circlemod2 \
+ circlemod2a \
+ circlemod3 \
+ circlemod3a \
+ constload2 \
+ constload3 \
+ dblloadmod1 \
+ dblloadmod2 \
+ dblloadmod3 \
+ dep1 \
+ dep2 \
+ dep3 \
+ dep4 \
+ failobj \
+ filtmod1 \
+ filtmod2 \
+ firstobj \
+ globalmod1 \
+ libmarkermod1-1 \
+ libmarkermod1-2 \
+ libmarkermod1-3 \
+ libmarkermod2-1 \
+ libmarkermod2-2 \
+ libmarkermod3-1 \
+ libmarkermod3-2 \
+ libmarkermod3-3 \
+ libmarkermod4-1 \
+ libmarkermod4-2 \
+ libmarkermod4-3 \
+ libmarkermod4-4 \
+ ltglobmod1 \
+ ltglobmod2 \
+ neededobj1 \
+ neededobj2 \
+ neededobj3 \
+ neededobj4 \
+ neededobj5 \
+ neededobj6 \
+ nextmod1 \
+ nextmod2 \
+ nodel2mod1 \
+ nodel2mod2 \
+ nodel2mod3 \
+ nodelmod1 \
+ nodelmod2 \
+ nodelmod3 \
+ nodelmod4 \
+ nodlopenmod \
+ nodlopenmod2 \
+ order2mod1 \
+ order2mod2 \
+ order2mod3 \
+ order2mod4 \
+ pathoptobj \
+ reldep4mod1 \
+ reldep4mod2 \
+ reldep4mod3 \
+ reldep4mod4 \
+ reldep6mod0 \
+ reldep6mod1 \
+ reldep6mod2 \
+ reldep6mod3 \
+ reldep6mod4 \
+ reldep7mod1 \
+ reldep7mod2 \
+ reldep8mod1 \
+ reldep8mod2 \
+ reldep8mod3 \
+ reldep9mod1 \
+ reldep9mod2 \
+ reldep9mod3 \
+ reldepmod1 \
+ reldepmod2 \
+ reldepmod3 \
+ reldepmod4 \
+ reldepmod5 \
+ reldepmod6 \
+ testobj1 \
+ testobj1_1 \
+ testobj2 \
+ testobj3 \
+ testobj4 \
+ testobj5 \
+ testobj6 \
+ tst-absolute-sym-lib \
+ tst-absolute-zero-lib \
+ tst-alignmod \
+ tst-alignmod2 \
+ tst-array2dep \
+ tst-array5dep \
+ tst-audit11mod1 \
+ tst-audit11mod2 \
+ tst-audit12mod1 \
+ tst-audit12mod2 \
+ tst-audit12mod3 \
+ tst-audit13mod1 \
+ tst-auditlogmod-1 \
+ tst-auditlogmod-2 \
+ tst-auditlogmod-3 \
+ tst-auditmanymod1 \
+ tst-auditmanymod2 \
+ tst-auditmanymod3 \
+ tst-auditmanymod4 \
+ tst-auditmanymod5 \
+ tst-auditmanymod6 \
+ tst-auditmanymod7 \
+ tst-auditmanymod8 \
+ tst-auditmanymod9 \
+ tst-auditmod1 \
+ tst-auditmod9a \
+ tst-auditmod9b \
+ tst-auditmod11 \
+ tst-auditmod12 \
+ tst-auxvalmod \
+ tst-big-note-lib \
+ tst-deep1mod1 \
+ tst-deep1mod2 \
+ tst-deep1mod3 \
+ tst-dlmopen1mod \
+ tst-dlmopen-dlerror-mod \
+ tst-dlmopen-gethostbyname-mod \
+ tst-dlopenfaillinkmod \
+ tst-dlopenfailmod1 \
+ tst-dlopenfailmod2 \
+ tst-dlopenfailmod3 \
+ tst-dlopenfailnodelmod \
+ tst-dlopenrpathmod \
+ tst-filterobj-aux \
+ tst-filterobj-filtee \
+ tst-filterobj-flt \
+ tst-finilazyfailmod \
+ tst-initlazyfailmod \
+ tst-initorder2a \
+ tst-initorder2b \
+ tst-initorder2c \
+ tst-initorder2d \
+ tst-initordera1 \
+ tst-initordera2 \
+ tst-initordera3 \
+ tst-initordera4 \
+ tst-initorderb1 \
+ tst-initorderb2 \
+ tst-latepthreadmod \
+ tst-ldconfig-ld-mod \
+ tst-main1mod \
+ tst-nodelete2mod \
+ tst-nodelete-dlclose-dso \
+ tst-nodelete-dlclose-plugin \
+ tst-nodelete-opened-lib \
+ tst-null-argv-lib \
+ tst-relsort1mod1 \
+ tst-relsort1mod2 \
+ tst-ro-dynamic-mod \
+ tst-single_threaded-mod1 \
+ tst-single_threaded-mod2 \
+ tst-single_threaded-mod3 \
+ tst-single_threaded-mod4 \
+ tst-sonamemove-linkmod1 \
+ tst-sonamemove-runmod1 \
+ tst-sonamemove-runmod2 \
+ tst-tls19mod1 \
+ tst-tls19mod2 \
+ tst-tls19mod3 \
+ tst-tls20mod-bad \
+ tst-tls21mod \
+ tst-tlsalign-lib \
+ tst-tls-ie-mod0 \
+ tst-tls-ie-mod1 \
+ tst-tls-ie-mod2 \
+ tst-tls-ie-mod3 \
+ tst-tls-ie-mod4 \
+ tst-tls-ie-mod5 \
+ tst-tls-ie-mod6 \
+ tst-tlsmod1 \
+ tst-tlsmod10 \
+ tst-tlsmod11 \
+ tst-tlsmod12 \
+ tst-tlsmod13 \
+ tst-tlsmod13a \
+ tst-tlsmod14a \
+ tst-tlsmod14b \
+ tst-tlsmod15a \
+ tst-tlsmod15b \
+ tst-tlsmod16a \
+ tst-tlsmod16b \
+ tst-tlsmod17b \
+ tst-tlsmod2 \
+ tst-tlsmod3 \
+ tst-tlsmod4 \
+ tst-tlsmod5 \
+ tst-tlsmod6 \
+ tst-tlsmod7 \
+ tst-tlsmod8 \
+ tst-tlsmod9 \
+ tst-unique1mod1 \
+ tst-unique1mod2 \
+ tst-unique2mod1 \
+ tst-unique2mod2 \
+ tst-unwind-ctor-lib \
+ unload2dep \
+ unload2mod \
+ unload3mod1 \
+ unload3mod2 \
+ unload3mod3 \
+ unload3mod4 \
+ unload4mod1 \
+ unload4mod2 \
+ unload4mod3 \
+ unload4mod4 \
+ unload6mod1 \
+ unload6mod2 \
+ unload6mod3 \
+ unload7mod1 \
+ unload7mod2 \
+ unload8mod1 \
+ unload8mod1x \
+ unload8mod2 \
+ unload8mod3 \
+ unloadmod \
+ vismod1 \
+ vismod2 \
+ vismod3 \
+
+modules-names-cxx = \
+ tst-dlopen-nodelete-reloc-mod1 \
+ tst-dlopen-nodelete-reloc-mod10 \
+ tst-dlopen-nodelete-reloc-mod11 \
+ tst-dlopen-nodelete-reloc-mod12 \
+ tst-dlopen-nodelete-reloc-mod13 \
+ tst-dlopen-nodelete-reloc-mod14 \
+ tst-dlopen-nodelete-reloc-mod15 \
+ tst-dlopen-nodelete-reloc-mod16 \
+ tst-dlopen-nodelete-reloc-mod17 \
+ tst-dlopen-nodelete-reloc-mod2 \
+ tst-dlopen-nodelete-reloc-mod3 \
+ tst-dlopen-nodelete-reloc-mod4 \
+ tst-dlopen-nodelete-reloc-mod5 \
+ tst-dlopen-nodelete-reloc-mod6 \
+ tst-dlopen-nodelete-reloc-mod7 \
+ tst-dlopen-nodelete-reloc-mod8 \
+ tst-dlopen-nodelete-reloc-mod9 \
+ tst-nodelete-rtldmod \
+ tst-nodelete-uniquemod \
+ tst-nodelete-zmod \
+ tst-unique3lib \
+ tst-unique3lib2 \
+ tst-unique4lib \
+
+modules-names += \
+ $(if $(CXX),$(modules-names-cxx)) \
+ $(modules-execstack-$(have-z-execstack)) \
+ $(tst-tls-many-dynamic-modules) \
+ $(tst-tls-many-dynamic-modules-dep) \
+ $(tst-tls-many-dynamic-modules-dep-bad) \
+ $(tlsmod17a-modules) \
+ $(tlsmod18a-modules) \
# Most modules build with _ISOMAC defined, but those filtered out
# depend on internal headers.

View File

@ -0,0 +1,73 @@
commit 990c953bce06d77360d2e933faa9a008e2c55405
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Jan 14 20:16:05 2022 +0100
x86: Add x86-64-vN check to early startup
This ISA level covers the glibc build itself. <dl-hwcap-check.h>
cannot be used because this check (by design) happens before
DL_PLATFORM_INIT and the x86 CPU flags initialization.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index 5ee06f94735e5189..36ca1a7126047b86 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -7,6 +7,7 @@ sysdep_routines += get-cpuid-feature-leaf
sysdep-dl-routines += dl-get-cpu-features
sysdep_headers += sys/platform/x86.h bits/platform/x86.h
+CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags)
CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector)
tests += tst-get-cpu-features tst-get-cpu-features-static \
diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c
index 839803c746f408ed..6ccde4404b13a725 100644
--- a/sysdeps/x86/dl-get-cpu-features.c
+++ b/sysdeps/x86/dl-get-cpu-features.c
@@ -20,6 +20,7 @@
#ifdef SHARED
# include <cpu-features.c>
+# include <gcc-macros.h>
/* NB: Normally, DL_PLATFORM_INIT calls init_cpu_features to initialize
CPU features in dynamic executable. But when loading ld.so inside of
@@ -36,7 +37,35 @@ _dl_x86_init_cpu_features (void)
{
struct cpu_features *cpu_features = __get_cpu_features ();
if (cpu_features->basic.kind == arch_kind_unknown)
- init_cpu_features (cpu_features);
+ {
+ init_cpu_features (cpu_features);
+
+# if IS_IN (rtld)
+ /* See isa-level.c. */
+# if defined GCCMACRO__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \
+ && defined HAVE_X86_LAHF_SAHF && defined GCCMACRO__POPCNT__ \
+ && defined GCCMACRO__SSE3__ && defined GCCMACRO__SSSE3__ \
+ && defined GCCMACRO__SSE4_1__ && defined GCCMACRO__SSE4_2__
+ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V2))
+ _dl_fatal_printf ("\
+Fatal glibc error: CPU does not support x86-64-v%d\n", 2);
+# if defined GCCMACRO__AVX__ && defined GCCMACRO__AVX2__ \
+ && defined GCCMACRO__F16C__ && defined GCCMACRO__FMA__ \
+ && defined GCCMACRO__LZCNT__ && defined HAVE_X86_MOVBE
+ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V3))
+ _dl_fatal_printf ("\
+Fatal glibc error: CPU does not support x86-64-v%d\n", 3);
+# if defined GCCMACRO__AVX512F__ && defined GCCMACRO__AVX512BW__ \
+ && defined GCCMACRO__AVX512CD__ && defined GCCMACRO__AVX512DQ__ \
+ && defined GCCMACRO__AVX512VL__
+ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V4))
+ _dl_fatal_printf ("\
+Fatal glibc error: CPU does not support x86-64-v%d\n", 4);
+# endif /* ISA level 4 */
+# endif /* ISA level 3 */
+# endif /* ISA level 2 */
+# endif /* IS_IN (rtld) */
+ }
}
__ifunc (__x86_cpu_features, __x86_cpu_features, NULL, void,

View File

@ -0,0 +1,37 @@
commit f01d482f0355a7029d0715ace0ccf3323e7e94bc
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Jan 14 20:16:05 2022 +0100
s390x: Use <gcc-macros.h> in early HWCAP check
This is required so that the checks still work if $(early-cflags)
selects a different ISA level.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
diff --git a/sysdeps/s390/s390-64/dl-hwcap-check.h b/sysdeps/s390/s390-64/dl-hwcap-check.h
index 87e18be6bd0c512b..27f7e245b1d1a9e9 100644
--- a/sysdeps/s390/s390-64/dl-hwcap-check.h
+++ b/sysdeps/s390/s390-64/dl-hwcap-check.h
@@ -19,17 +19,18 @@
#ifndef _DL_HWCAP_CHECK_H
#define _DL_HWCAP_CHECK_H
+#include <gcc-macros.h>
#include <ldsodefs.h>
static inline void
dl_hwcap_check (void)
{
#if defined __ARCH__
-# if __ARCH__ >= 13
+# if GCCMACRO__ARCH__ >= 13
if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_EXT2))
_dl_fatal_printf ("\
Fatal glibc error: CPU lacks VXRS_EXT2 support (z15 or later required)\n");
-# elif __ARCH__ >= 12
+# elif GCCMACRO__ARCH__ >= 12
if (!(GLRO(dl_hwcap) & HWCAP_S390_VXE))
_dl_fatal_printf ("\
Fatal glibc error: CPU lacks VXE support (z14 or later required)\n");

View File

@ -0,0 +1,158 @@
commit c90363403b57b3b7919061851cb3e6d9c85e784a
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Jan 18 13:53:11 2022 +0100
elf: Move _dl_setup_hash to its own file
And compile it with the early CFLAGS. _dl_setup_hash is called
very early for the ld.so link map, so it should be compiled
differently.
Reviewed-by: Stefan Liebler <stli@linux.ibm.com>
Tested-by: Stefan Liebler <stli@linux.ibm.com>
diff --git a/elf/Makefile b/elf/Makefile
index 778e393395fc5248..948296dc2437e9a1 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -69,6 +69,7 @@ dl-routines = \
dl-reloc \
dl-runtime \
dl-scope \
+ dl-setup_hash \
dl-sort-maps \
dl-thread_gscope_wait \
dl-tls \
@@ -154,6 +155,7 @@ CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines))
# Add the requested compiler flags to the early startup code.
CFLAGS-dl-printf.os += $(rtld-early-cflags)
+CFLAGS-dl-setup_hash.os += $(rtld-early-cflags)
CFLAGS-dl-sysdep.os += $(rtld-early-cflags)
CFLAGS-dl-tunables.os += $(rtld-early-cflags)
CFLAGS-dl-write.os += $(rtld-early-cflags)
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index eea217eb2833164c..3391a990c8d288e5 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -948,51 +948,6 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
}
-/* Cache the location of MAP's hash table. */
-
-void
-_dl_setup_hash (struct link_map *map)
-{
- Elf_Symndx *hash;
-
- if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL))
- {
- Elf32_Word *hash32
- = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]);
- map->l_nbuckets = *hash32++;
- Elf32_Word symbias = *hash32++;
- Elf32_Word bitmask_nwords = *hash32++;
- /* Must be a power of two. */
- assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
- map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
- map->l_gnu_shift = *hash32++;
-
- map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
- hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
-
- map->l_gnu_buckets = hash32;
- hash32 += map->l_nbuckets;
- map->l_gnu_chain_zero = hash32 - symbias;
-
- /* Initialize MIPS xhash translation table. */
- ELF_MACHINE_XHASH_SETUP (hash32, symbias, map);
-
- return;
- }
-
- if (!map->l_info[DT_HASH])
- return;
- hash = (void *) D_PTR (map, l_info[DT_HASH]);
-
- map->l_nbuckets = *hash++;
- /* Skip nchain. */
- hash++;
- map->l_buckets = hash;
- hash += map->l_nbuckets;
- map->l_chain = hash;
-}
-
-
static void
_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
const ElfW(Sym) **ref, struct sym_val *value,
diff --git a/elf/dl-setup_hash.c b/elf/dl-setup_hash.c
new file mode 100644
index 0000000000000000..6dd57c5c94e541c2
--- /dev/null
+++ b/elf/dl-setup_hash.c
@@ -0,0 +1,63 @@
+/* Cache the location of a link map hash table.
+ Copyright (C) 1995-2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <link.h>
+#include <ldsodefs.h>
+
+void
+_dl_setup_hash (struct link_map *map)
+{
+ Elf_Symndx *hash;
+
+ if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL))
+ {
+ Elf32_Word *hash32
+ = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]);
+ map->l_nbuckets = *hash32++;
+ Elf32_Word symbias = *hash32++;
+ Elf32_Word bitmask_nwords = *hash32++;
+ /* Must be a power of two. */
+ assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
+ map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
+ map->l_gnu_shift = *hash32++;
+
+ map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
+ hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
+
+ map->l_gnu_buckets = hash32;
+ hash32 += map->l_nbuckets;
+ map->l_gnu_chain_zero = hash32 - symbias;
+
+ /* Initialize MIPS xhash translation table. */
+ ELF_MACHINE_XHASH_SETUP (hash32, symbias, map);
+
+ return;
+ }
+
+ if (!map->l_info[DT_HASH])
+ return;
+ hash = (void *) D_PTR (map, l_info[DT_HASH]);
+
+ map->l_nbuckets = *hash++;
+ /* Skip nchain. */
+ hash++;
+ map->l_buckets = hash;
+ hash += map->l_nbuckets;
+ map->l_chain = hash;
+}

View File

@ -0,0 +1,42 @@
commit f4f70c2895e3d325188a42c10eb7bb4335be6773
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Tue Jan 4 06:58:34 2022 -0800
elf: Add a comment after trailing backslashes
diff --git a/elf/Makefile b/elf/Makefile
index 0cfcf0a61a442c9f..5b9c36bc6f0a3ee5 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -319,6 +319,7 @@ tests-cxx = \
tst-nodelete \
tst-unique3 \
tst-unique4 \
+# tests-cxx
tests += $(if $(CXX),$(tests-cxx))
tests-internal += loadtest unload unload2 circleload1 \
@@ -583,6 +584,7 @@ modules-names = \
vismod1 \
vismod2 \
vismod3 \
+# modules-names
modules-names-cxx = \
tst-dlopen-nodelete-reloc-mod1 \
@@ -608,6 +610,7 @@ modules-names-cxx = \
tst-unique3lib \
tst-unique3lib2 \
tst-unique4lib \
+# modules-names-cxx
modules-names += \
$(if $(CXX),$(modules-names-cxx)) \
@@ -617,6 +620,7 @@ modules-names += \
$(tst-tls-many-dynamic-modules-dep-bad) \
$(tlsmod17a-modules) \
$(tlsmod18a-modules) \
+# modules-names
# Most modules build with _ISOMAC defined, but those filtered out
# depend on internal headers.

View File

@ -0,0 +1,171 @@
commit 0835c0f0bad351117154b815f34f8af19ea7e325
Author: Matt Whitlock <sourceware@mattwhitlock.name>
Date: Wed Jun 16 23:40:47 2021 -0400
x86: fix Autoconf caching of instruction support checks [BZ #27991]
The Autoconf documentation for the AC_CACHE_CHECK macro states:
The commands-to-set-it must have no side effects except for setting
the variable cache-id, see below.
However, the tests for support of -msahf and -mmovbe were embedded in
the commands-to-set-it for lib_cv_include_x86_isa_level. This had the
consequence that libc_cv_have_x86_lahf_sahf and libc_cv_have_x86_movbe
were not defined whenever lib_cv_include_x86_isa_level was read from
cache. These variables' being undefined meant that their unquoted use
in later test expressions led to the 'test' built-in's misparsing its
arguments and emitting errors like "test: =: unexpected operator" or
"test: =: unary operator expected", depending on the particular shell.
This commit refactors the tests for LAHF/SAHF and MOVBE instruction
support into their own AC_CACHE_CHECK macro invocations to obey the
rule that the commands-to-set-it must have no side effects other than
setting the variable named by cache-id.
Signed-off-by: Matt Whitlock <sourceware@mattwhitlock.name>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
index ead1295c38cf5f4e..62676bb686850938 100644
--- a/sysdeps/x86/configure
+++ b/sysdeps/x86/configure
@@ -126,8 +126,6 @@ cat > conftest2.S <<EOF
4:
EOF
libc_cv_include_x86_isa_level=no
-libc_cv_have_x86_lahf_sahf=no
-libc_cv_have_x86_movbe=no
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest conftest1.S conftest2.S'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
@@ -137,9 +135,22 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest c
count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l`
if test "$count" = 1; then
libc_cv_include_x86_isa_level=yes
- cat > conftest.c <<EOF
-EOF
- if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c'
+ fi
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_include_x86_isa_level" >&5
+$as_echo "$libc_cv_include_x86_isa_level" >&6; }
+if test $libc_cv_include_x86_isa_level = yes; then
+ $as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LAHF/SAHF instruction support" >&5
+$as_echo_n "checking for LAHF/SAHF instruction support... " >&6; }
+if ${libc_cv_have_x86_lahf_sahf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ libc_cv_have_x86_lahf_sahf=no
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -147,7 +158,20 @@ EOF
test $ac_status = 0; }; } | grep -q "\-msahf"; then
libc_cv_have_x86_lahf_sahf=yes
fi
- if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_lahf_sahf" >&5
+$as_echo "$libc_cv_have_x86_lahf_sahf" >&6; }
+ if test $libc_cv_have_x86_lahf_sahf = yes; then
+ $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MOVBE instruction support" >&5
+$as_echo_n "checking for MOVBE instruction support... " >&6; }
+if ${libc_cv_have_x86_movbe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ libc_cv_have_x86_movbe=no
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -155,23 +179,13 @@ EOF
test $ac_status = 0; }; } | grep -q "\-mmovbe"; then
libc_cv_have_x86_movbe=yes
fi
- fi
-fi
-rm -f conftest*
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_include_x86_isa_level" >&5
-$as_echo "$libc_cv_include_x86_isa_level" >&6; }
-if test $libc_cv_include_x86_isa_level = yes; then
- $as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h
-
fi
-if test $libc_cv_have_x86_lahf_sahf = yes; then
- $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h
-
-fi
-if test $libc_cv_have_x86_movbe = yes; then
- $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_movbe" >&5
+$as_echo "$libc_cv_have_x86_movbe" >&6; }
+ if test $libc_cv_have_x86_movbe = yes; then
+ $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h
+ fi
fi
config_vars="$config_vars
enable-x86-isa-level = $libc_cv_include_x86_isa_level"
diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
index bca97fdc2f1ac1a7..04a12ab68048cd66 100644
--- a/sysdeps/x86/configure.ac
+++ b/sysdeps/x86/configure.ac
@@ -98,30 +98,32 @@ cat > conftest2.S <<EOF
4:
EOF
libc_cv_include_x86_isa_level=no
-libc_cv_have_x86_lahf_sahf=no
-libc_cv_have_x86_movbe=no
if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest conftest1.S conftest2.S); then
count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l`
if test "$count" = 1; then
libc_cv_include_x86_isa_level=yes
- cat > conftest.c <<EOF
-EOF
- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c) | grep -q "\-msahf"; then
- libc_cv_have_x86_lahf_sahf=yes
- fi
- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c) | grep -q "\-mmovbe"; then
- libc_cv_have_x86_movbe=yes
- fi
fi
fi
rm -f conftest*])
if test $libc_cv_include_x86_isa_level = yes; then
AC_DEFINE(INCLUDE_X86_ISA_LEVEL)
-fi
-if test $libc_cv_have_x86_lahf_sahf = yes; then
- AC_DEFINE(HAVE_X86_LAHF_SAHF)
-fi
-if test $libc_cv_have_x86_movbe = yes; then
- AC_DEFINE(HAVE_X86_MOVBE)
+ AC_CACHE_CHECK([for LAHF/SAHF instruction support],
+ libc_cv_have_x86_lahf_sahf, [dnl
+ libc_cv_have_x86_lahf_sahf=no
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-msahf"; then
+ libc_cv_have_x86_lahf_sahf=yes
+ fi])
+ if test $libc_cv_have_x86_lahf_sahf = yes; then
+ AC_DEFINE(HAVE_X86_LAHF_SAHF)
+ fi
+ AC_CACHE_CHECK([for MOVBE instruction support],
+ libc_cv_have_x86_movbe, [dnl
+ libc_cv_have_x86_movbe=no
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-mmovbe"; then
+ libc_cv_have_x86_movbe=yes
+ fi])
+ if test $libc_cv_have_x86_movbe = yes; then
+ AC_DEFINE(HAVE_X86_MOVBE)
+ fi
fi
LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])

View File

@ -0,0 +1,58 @@
commit 5732a881aad24fac876f5505a212395048a7a483
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Jan 14 16:09:20 2022 +0100
x86: HAVE_X86_LAHF_SAHF, HAVE_X86_MOVBE and -march=x86-64-vN (bug 28782)
HAVE_X86_LAHF_SAHF is implied by x86-64-v2, and HAVE_X86_MOVBE by
x86-64-v3.
The individual flag does not appear in -fverbose-asm flag output
even if the ISA level implies it.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
index 62676bb686850938..7bdbfdc6dc2ad38f 100644
--- a/sysdeps/x86/configure
+++ b/sysdeps/x86/configure
@@ -155,7 +155,7 @@ else
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; } | grep -q "\-msahf"; then
+ test $ac_status = 0; }; } | grep -qE '(-msahf\b|-march=x86-64-v)'; then
libc_cv_have_x86_lahf_sahf=yes
fi
fi
@@ -176,7 +176,7 @@ else
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; } | grep -q "\-mmovbe"; then
+ test $ac_status = 0; }; } | grep -qE '(-mmovbe\b|-march=x86-64-v([3-9]|[1-9][0-9]))'; then
libc_cv_have_x86_movbe=yes
fi
fi
diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
index 04a12ab68048cd66..10d5c2e0e555fc79 100644
--- a/sysdeps/x86/configure.ac
+++ b/sysdeps/x86/configure.ac
@@ -110,7 +110,7 @@ if test $libc_cv_include_x86_isa_level = yes; then
AC_CACHE_CHECK([for LAHF/SAHF instruction support],
libc_cv_have_x86_lahf_sahf, [dnl
libc_cv_have_x86_lahf_sahf=no
- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-msahf"; then
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -qE '(-msahf\b|-march=x86-64-v)'; then
libc_cv_have_x86_lahf_sahf=yes
fi])
if test $libc_cv_have_x86_lahf_sahf = yes; then
@@ -119,7 +119,7 @@ if test $libc_cv_include_x86_isa_level = yes; then
AC_CACHE_CHECK([for MOVBE instruction support],
libc_cv_have_x86_movbe, [dnl
libc_cv_have_x86_movbe=no
- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-mmovbe"; then
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -qE '(-mmovbe\b|-march=x86-64-v(@<:@3-9@:>@|@<:@1-9@:>@@<:@0-9@:>@))'; then
libc_cv_have_x86_movbe=yes
fi])
if test $libc_cv_have_x86_movbe = yes; then

View File

@ -0,0 +1,32 @@
commit ef7c6d42fe163a5e49a478c43e655ce4633fa5ba
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Jan 14 16:09:20 2022 +0100
Generate gcc-macros.h
The file can be used to check the effect of the default compiler
flags on code generation even in areas of the build that uses
non-default compiler flags.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
diff --git a/Makeconfig b/Makeconfig
index 8bc5540292c7b6fa..99898a632a64be91 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -1202,6 +1202,15 @@ $(common-objpfx)dl-tunable-list.stmp: \
touch $@
endif
+# Dump the GCC macros used by the default compiler flags to a header
+# file, so that they can be inspected when using different compiler
+# flags. Add the GCCMACRO prefix to make these macro names unique.
+$(common-objpfx)gcc-macros.h.in: $(common-objpfx)config.status
+ $(CC) $(CFLAGS) $(CPPFLAGS) -E -dM -x c -o $@ /dev/null
+$(common-objpfx)gcc-macros.h: $(common-objpfx)gcc-macros.h.in
+ sed 's/^#define /#define GCCMACRO/' < $< > $@
+before-compile += $(common-objpfx)gcc-macros.h
+
# Generate version maps, but wait until sysdep-subdirs is known
ifeq ($(sysd-sorted-done),t)
ifeq ($(build-shared),yes)

View File

@ -0,0 +1,549 @@
commit 7de01e60c200c431d3469deb784da8fd4508fc15
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Jan 14 20:16:05 2022 +0100
elf/Makefile: Reflow and sort most variable assignments
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
Conflicts:
elf/Makefile
(Usual backporting differences. LLD support is missing
downstream.)
diff --git a/elf/Makefile b/elf/Makefile
index 5b9c36bc6f0a3ee5..124905f96c88ab53 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -21,21 +21,62 @@ subdir := elf
include ../Makeconfig
-headers = elf.h bits/elfclass.h link.h bits/link.h
-routines = $(all-dl-routines) dl-support dl-iteratephdr \
- dl-addr dl-addr-obj enbl-secure dl-profstub \
- dl-origin dl-libc dl-sym dl-sysdep dl-error \
- dl-reloc-static-pie libc_early_init rtld_static_init
+headers = \
+ bits/elfclass.h \
+ bits/link.h \
+ elf.h \
+ link.h \
+ # headers
+
+routines = \
+ $(all-dl-routines) \
+ dl-addr \
+ dl-addr-obj \
+ dl-error \
+ dl-iteratephdr \
+ dl-libc \
+ dl-origin \
+ dl-profstub \
+ dl-reloc-static-pie \
+ dl-support \
+ dl-sym \
+ dl-sysdep \
+ enbl-secure \
+ libc_early_init \
+ rtld_static_init \
+ # routines
# The core dynamic linking functions are in libc for the static and
# profiled libraries.
-dl-routines = $(addprefix dl-,load lookup object reloc deps \
- runtime init fini debug misc \
- version profile tls origin scope \
- execstack open close trampoline \
- exception sort-maps lookup-direct \
- call-libc-early-init write \
- thread_gscope_wait tls_init_tp)
+dl-routines = \
+ dl-call-libc-early-init \
+ dl-close \
+ dl-debug \
+ dl-deps \
+ dl-exception \
+ dl-execstack \
+ dl-fini \
+ dl-init \
+ dl-load \
+ dl-lookup \
+ dl-lookup-direct \
+ dl-misc \
+ dl-object \
+ dl-open \
+ dl-origin \
+ dl-profile \
+ dl-reloc \
+ dl-runtime \
+ dl-scope \
+ dl-sort-maps \
+ dl-thread_gscope_wait \
+ dl-tls \
+ dl-tls_init_tp \
+ dl-trampoline \
+ dl-version \
+ dl-write \
+ # dl-routines
+
ifeq (yes,$(use-ldconfig))
dl-routines += dl-cache
endif
@@ -58,16 +99,38 @@ endif
all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
# But they are absent from the shared libc, because that code is in ld.so.
-elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \
- dl-sysdep dl-exception dl-reloc-static-pie \
- thread_gscope_wait rtld_static_init
+elide-routines.os = \
+ $(all-dl-routines) \
+ dl-exception \
+ dl-origin \
+ dl-reloc-static-pie \
+ dl-support \
+ dl-sysdep \
+ enbl-secure \
+ rtld_static_init \
+ thread_gscope_wait \
+ # elide-routines.os
# ld.so uses those routines, plus some special stuff for being the program
# interpreter and operating independent of libc.
-rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal \
- dl-error-minimal dl-conflict dl-hwcaps dl-hwcaps_split dl-hwcaps-subdirs \
- dl-usage dl-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu \
- dl-mutex
+rtld-routines = \
+ $(all-dl-routines) \
+ dl-conflict \
+ dl-diagnostics \
+ dl-diagnostics-cpu \
+ dl-diagnostics-kernel \
+ dl-environ \
+ dl-error-minimal \
+ dl-hwcaps \
+ dl-hwcaps-subdirs \
+ dl-hwcaps_split \
+ dl-minimal \
+ dl-mutex \
+ dl-sysdep \
+ dl-usage \
+ rtld \
+ # rtld-routines
+
all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables
@@ -102,8 +165,16 @@ ld-map = $(common-objpfx)ld.map
endif
ifeq (yes,$(build-shared))
-extra-objs = $(all-rtld-routines:%=%.os) sofini.os interp.os
-generated += librtld.os dl-allobjs.os ld.so ldd
+extra-objs = \
+ $(all-rtld-routines:%=%.os) \
+ sofini.os \
+ interp.os \
+ # extra-objs
+generated += \
+ dl-allobjs.os \
+ ld.so ldd \
+ librtld.os \
+ # generated
install-others = $(inst_rtlddir)/$(rtld-installed-name) $(inst_bindir)/ld.so
install-bin-script = ldd
endif
@@ -121,8 +192,15 @@ others-static += ldconfig
others += ldconfig
install-rootsbin += ldconfig
-ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon static-stubs \
- stringtable
+ldconfig-modules := \
+ cache \
+ chroot_canon \
+ readlib \
+ static-stubs \
+ stringtable \
+ xmalloc \
+ xstrdup \
+ # ldconfig-modules
extra-objs += $(ldconfig-modules:=.o)
others-extras = $(ldconfig-modules)
endif
@@ -156,23 +234,36 @@ $(inst_auditdir)/sotruss-lib.so: $(objpfx)sotruss-lib.so $(+force)
$(do-install-program)
endif
-tests-static-normal := tst-array1-static tst-array5-static \
- tst-dl-iter-static \
- tst-tlsalign-static tst-tlsalign-extern-static \
- tst-linkall-static tst-env-setuid tst-env-setuid-tunables \
- tst-single_threaded-static tst-single_threaded-pthread-static \
- tst-dst-static tst-getauxval-static
-
-tests-static-internal := tst-tls1-static tst-tls2-static \
- tst-ptrguard1-static tst-stackguard1-static \
- tst-tls1-static-non-pie
+tests-static-normal := \
+ tst-array1-static \
+ tst-array5-static \
+ tst-dl-iter-static \
+ tst-dst-static \
+ tst-env-setuid \
+ tst-env-setuid-tunables \
+ tst-getauxval-static \
+ tst-linkall-static \
+ tst-single_threaded-pthread-static \
+ tst-single_threaded-static \
+ tst-tlsalign-extern-static \
+ tst-tlsalign-static \
+ # tests-static-normal
+
+tests-static-internal := \
+ tst-ptrguard1-static \
+ tst-stackguard1-static \
+ tst-tls1-static \
+ tst-tls2-static \
+ tst-tls1-static-non-pie \
+ # tests-static-internal
CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o
tst-tls1-static-non-pie-no-pie = yes
tests-container := \
- tst-ldconfig-bad-aux-cache \
- tst-ldconfig-ld_so_conf-update
+ tst-ldconfig-bad-aux-cache \
+ tst-ldconfig-ld_so_conf-update \
+ # tests-container
ifeq (no,$(build-hardcoded-path-in-tests))
# This is an ld.so.cache test, and RPATH/RUNPATH in the executable
@@ -180,14 +271,32 @@ ifeq (no,$(build-hardcoded-path-in-tests))
tests-container += tst-glibc-hwcaps-prepend-cache
endif
-tests := tst-tls9 tst-leaks1 \
- tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \
- tst-auxv tst-stringtable
-tests-internal := tst-tls1 tst-tls2 $(tests-static-internal)
+tests := \
+ tst-array1 \
+ tst-array2 \
+ tst-array3 \
+ tst-array4 \
+ tst-array5 \
+ tst-auxv \
+ tst-leaks1 \
+ tst-stringtable \
+ tst-tls9 \
+ # tests
+
+tests-internal := \
+ $(tests-static-internal) \
+ tst-tls1 \
+ tst-tls2 \
+ # tests-internal
+
tests-static := $(tests-static-normal) $(tests-static-internal)
ifeq (yes,$(build-shared))
-tests-static += tst-tls9-static tst-single_threaded-static-dlopen
+tests-static += \
+ tst-single_threaded-static-dlopen \
+ tst-tls9-static \
+ # tests-static
+
static-dlopen-environment = \
LD_LIBRARY_PATH=$(ld-library-path):$(common-objpfx)dlfcn
tst-tls9-static-ENV = $(static-dlopen-environment)
@@ -313,33 +422,69 @@ tests += \
unload6 \
unload7 \
unload8 \
-# reldep9
+ # tests
tests-cxx = \
tst-dlopen-nodelete-reloc \
tst-nodelete \
tst-unique3 \
tst-unique4 \
-# tests-cxx
+ # tests-cxx
tests += $(if $(CXX),$(tests-cxx))
-tests-internal += loadtest unload unload2 circleload1 \
- neededtest neededtest2 neededtest3 neededtest4 \
- tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
- tst-ptrguard1 tst-stackguard1 \
- tst-create_format1 tst-tls-surplus tst-dl-hwcaps_split
-tests-container += tst-pldd tst-dlopen-tlsmodid-container \
- tst-dlopen-self-container tst-preload-pthread-libc
-test-srcs = tst-pathopt
+
+tests-internal += \
+ circleload1 \
+ loadtest \
+ neededtest \
+ neededtest2 \
+ neededtest3 \
+ neededtest4 \
+ tst-create_format1 \
+ tst-dl-hwcaps_split \
+ tst-dlmopen2 \
+ tst-ptrguard1 \
+ tst-stackguard1 \
+ tst-tls-surplus \
+ tst-tls3 \
+ tst-tls6 \
+ tst-tls7 \
+ tst-tls8 \
+ unload \
+ unload2 \
+ # tests-internal
+
+tests-container += \
+ tst-dlopen-self-container \
+ tst-dlopen-tlsmodid-container \
+ tst-pldd \
+ tst-preload-pthread-libc \
+ # tests-container
+
+test-srcs = \
+ tst-pathopt \
+ # tests-srcs
+
+ifeq (yes,$(have-fpie))
+tests-pie += tst-align3
+endif
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
+
ifneq ($(selinux-enabled),1)
-tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
+tests-execstack-yes = \
+ tst-execstack \
+ tst-execstack-needed \
+ tst-execstack-prog \
+ # tests-execstack-yes
endif
endif
tests += $(tests-execstack-$(have-z-execstack))
ifeq ($(run-built-tests),yes)
-tests-special += $(objpfx)tst-leaks1-mem.out \
- $(objpfx)noload-mem.out \
- $(objpfx)tst-ldconfig-X.out $(objpfx)tst-rtld-help.out
+tests-special += \
+ $(objpfx)noload-mem.out \
+ $(objpfx)tst-ldconfig-X.out \
+ $(objpfx)tst-leaks1-mem.out \
+ $(objpfx)tst-rtld-help.out \
+ # tests-special
endif
tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
@@ -356,9 +501,16 @@ tst-tls-many-dynamic-modules-dep = \
tst-tls-many-dynamic-modules-dep-bad-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
tst-tls-many-dynamic-modules-dep-bad = \
$(foreach n,$(tst-tls-many-dynamic-modules-dep-bad-suffixes),tst-tls-manydynamic$(n)mod-dep-bad)
-extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \
- tst-tlsalign-vars.o
-test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars
+extra-test-objs += \
+ $(tlsmod17a-modules:=.os) \
+ $(tlsmod18a-modules:=.os) \
+ tst-tlsalign-vars.o \
+ # extra-test-objs
+test-extras += \
+ tst-tlsalign-vars \
+ tst-tlsmod17a \
+ tst-tlsmod18a \
+ # test-extras
modules-names = \
circlemod1 \
circlemod1a \
@@ -610,17 +762,17 @@ modules-names-cxx = \
tst-unique3lib \
tst-unique3lib2 \
tst-unique4lib \
-# modules-names-cxx
+ # modules-names-cxx
modules-names += \
$(if $(CXX),$(modules-names-cxx)) \
$(modules-execstack-$(have-z-execstack)) \
+ $(tlsmod17a-modules) \
+ $(tlsmod18a-modules) \
$(tst-tls-many-dynamic-modules) \
$(tst-tls-many-dynamic-modules-dep) \
$(tst-tls-many-dynamic-modules-dep-bad) \
- $(tlsmod17a-modules) \
- $(tlsmod18a-modules) \
-# modules-names
+ # modules-names
# Most modules build with _ISOMAC defined, but those filtered out
# depend on internal headers.
@@ -669,35 +821,70 @@ modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod
tests += $(tests-static)
ifeq (yes,$(have-ifunc))
-tests-ifuncstatic := ifuncmain1static ifuncmain1picstatic \
- ifuncmain2static ifuncmain2picstatic \
- ifuncmain4static ifuncmain4picstatic \
- ifuncmain5static ifuncmain5picstatic \
- ifuncmain7static ifuncmain7picstatic
+tests-ifuncstatic := \
+ ifuncmain1static \
+ ifuncmain1picstatic \
+ ifuncmain2static \
+ ifuncmain2picstatic \
+ ifuncmain4static \
+ ifuncmain4picstatic \
+ ifuncmain5static \
+ ifuncmain5picstatic \
+ ifuncmain7static \
+ ifuncmain7picstatic \
+ # tests-ifuncstatic
ifeq (yes,$(have-gcc-ifunc))
tests-ifuncstatic += ifuncmain9static ifuncmain9picstatic
endif
tests-static += $(tests-ifuncstatic)
tests-internal += $(tests-ifuncstatic)
ifeq (yes,$(build-shared))
-tests += tst-ifunc-fault-lazy tst-ifunc-fault-bindnow
+tests += \
+ tst-ifunc-fault-bindnow \
+ tst-ifunc-fault-lazy \
+ # tests
# Note: sysdeps/x86_64/ifuncmain8.c uses ifuncmain8.
tests-internal += \
- ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
- ifuncmain1staticpic \
- ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \
- ifuncmain5 ifuncmain5pic ifuncmain5staticpic \
- ifuncmain7 ifuncmain7pic
+ ifuncmain1 \
+ ifuncmain1pic \
+ ifuncmain1staticpic \
+ ifuncmain1vis \
+ ifuncmain1vispic \
+ ifuncmain2 \
+ ifuncmain2pic \
+ ifuncmain3 \
+ ifuncmain4 \
+ ifuncmain5 \
+ ifuncmain5pic \
+ ifuncmain5staticpic \
+ ifuncmain7 \
+ ifuncmain7pic \
+ # tests-internal
ifeq (yes,$(have-gcc-ifunc))
-tests-internal += ifuncmain9 ifuncmain9pic
+tests-internal += \
+ ifuncmain9 \
+ ifuncmain9pic \
+ # tests-internal
endif
-ifunc-test-modules = ifuncdep1 ifuncdep1pic ifuncdep2 ifuncdep2pic \
- ifuncdep5 ifuncdep5pic
+ifunc-test-modules = \
+ ifuncdep1 \
+ ifuncdep1pic \
+ ifuncdep2 \
+ ifuncdep2pic \
+ ifuncdep5 \
+ ifuncdep5pic \
+ # ifunc-test-modules
extra-test-objs += $(ifunc-test-modules:=.o)
test-internal-extras += $(ifunc-test-modules)
ifeq (yes,$(have-fpie))
-ifunc-pie-tests = ifuncmain1pie ifuncmain1vispie ifuncmain1staticpie \
- ifuncmain5pie ifuncmain6pie ifuncmain7pie
+ifunc-pie-tests = \
+ ifuncmain1pie \
+ ifuncmain1staticpie \
+ ifuncmain1vispie \
+ ifuncmain5pie \
+ ifuncmain6pie \
+ ifuncmain7pie \
+ # ifunc-pie-tests
ifeq (yes,$(have-gcc-ifunc))
ifunc-pie-tests += ifuncmain9pie
endif
@@ -707,30 +894,50 @@ endif
tests-internal += $(ifunc-pie-tests)
tests-pie += $(ifunc-pie-tests)
endif
-modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6
+modules-names += \
+ ifuncmod1 \
+ ifuncmod3 \
+ ifuncmod5 \
+ ifuncmod6 \
+ # module-names
endif
endif
ifeq (yes,$(build-shared))
ifeq ($(run-built-tests),yes)
-tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \
- $(objpfx)tst-rtld-preload.out $(objpfx)argv0test.out \
- $(objpfx)tst-rtld-help.out
+tests-special += \
+ $(objpfx)argv0test.out \
+ $(objpfx)tst-pathopt.out \
+ $(objpfx)tst-rtld-help.out \
+ $(objpfx)tst-rtld-load-self.out \
+ $(objpfx)tst-rtld-preload.out \
+ # tests-special
endif
-tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \
- $(objpfx)check-wx-segment.out \
- $(objpfx)check-localplt.out $(objpfx)check-initfini.out
+tests-special += \
+ $(objpfx)check-execstack.out \
+ $(objpfx)check-initfini.out \
+ $(objpfx)check-localplt.out \
+ $(objpfx)check-textrel.out \
+ $(objpfx)check-wx-segment.out \
+ # tests-special
endif
ifeq ($(run-built-tests),yes)
-tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \
- $(objpfx)tst-array1-static-cmp.out \
- $(objpfx)tst-array2-cmp.out $(objpfx)tst-array3-cmp.out \
- $(objpfx)tst-array4-cmp.out $(objpfx)tst-array5-cmp.out \
- $(objpfx)tst-array5-static-cmp.out $(objpfx)order2-cmp.out \
- $(objpfx)tst-initorder-cmp.out \
- $(objpfx)tst-initorder2-cmp.out $(objpfx)tst-unused-dep.out \
- $(objpfx)tst-unused-dep-cmp.out
+tests-special += \
+ $(objpfx)order-cmp.out \
+ $(objpfx)order2-cmp.out \
+ $(objpfx)tst-array1-cmp.out \
+ $(objpfx)tst-array1-static-cmp.out \
+ $(objpfx)tst-array2-cmp.out \
+ $(objpfx)tst-array3-cmp.out \
+ $(objpfx)tst-array4-cmp.out \
+ $(objpfx)tst-array5-cmp.out \
+ $(objpfx)tst-array5-static-cmp.out \
+ $(objpfx)tst-initorder-cmp.out \
+ $(objpfx)tst-initorder2-cmp.out \
+ $(objpfx)tst-unused-dep-cmp.out \
+ $(objpfx)tst-unused-dep.out \
+ # tests-special
endif
ifndef avoid-generated
@@ -835,6 +1042,7 @@ rtld-stubbed-symbols = \
free \
malloc \
realloc \
+ # rtld-stubbed-symbols
ifeq ($(have-ssp),yes)
# rtld is not built with the stack protector, so these references will

View File

@ -0,0 +1,633 @@
commit b693d75f0c611bce9b0ad984bad306121d42c535
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Jan 14 20:16:05 2022 +0100
elf: Split dl-printf.c from dl-misc.c
This allows to use different compiler flags for the diagnostics
code.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
diff --git a/elf/Makefile b/elf/Makefile
index 124905f96c88ab53..52aafc89cec835ab 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -64,6 +64,7 @@ dl-routines = \
dl-object \
dl-open \
dl-origin \
+ dl-printf \
dl-profile \
dl-reloc \
dl-runtime \
diff --git a/elf/dl-misc.c b/elf/dl-misc.c
index b256d792c6198683..f17140b129343f7b 100644
--- a/elf/dl-misc.c
+++ b/elf/dl-misc.c
@@ -16,24 +16,16 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <assert.h>
+#include <_itoa.h>
#include <fcntl.h>
#include <ldsodefs.h>
-#include <limits.h>
#include <link.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
+#include <not-cancel.h>
#include <stdint.h>
+#include <stdlib.h>
#include <sys/mman.h>
-#include <sys/param.h>
#include <sys/stat.h>
-#include <sys/uio.h>
-#include <sysdep.h>
-#include <_itoa.h>
-#include <dl-writev.h>
-#include <not-cancel.h>
+#include <unistd.h>
/* Read the whole contents of FILE into new mmap'd space with given
protections. *SIZEP gets the size of the file. On error MAP_FAILED
@@ -70,270 +62,6 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
return result;
}
-
-/* Bare-bones printf implementation. This function only knows about
- the formats and flags needed and can handle only up to 64 stripes in
- the output. */
-static void
-_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
-{
-# define NIOVMAX 64
- struct iovec iov[NIOVMAX];
- int niov = 0;
- pid_t pid = 0;
- char pidbuf[12];
-
- while (*fmt != '\0')
- {
- const char *startp = fmt;
-
- if (tag_p > 0)
- {
- /* Generate the tag line once. It consists of the PID and a
- colon followed by a tab. */
- if (pid == 0)
- {
- char *p;
- pid = __getpid ();
- assert (pid >= 0 && sizeof (pid_t) <= 4);
- p = _itoa (pid, &pidbuf[10], 10, 0);
- while (p > pidbuf)
- *--p = ' ';
- pidbuf[10] = ':';
- pidbuf[11] = '\t';
- }
-
- /* Append to the output. */
- assert (niov < NIOVMAX);
- iov[niov].iov_len = 12;
- iov[niov++].iov_base = pidbuf;
-
- /* No more tags until we see the next newline. */
- tag_p = -1;
- }
-
- /* Skip everything except % and \n (if tags are needed). */
- while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
- ++fmt;
-
- /* Append constant string. */
- assert (niov < NIOVMAX);
- if ((iov[niov].iov_len = fmt - startp) != 0)
- iov[niov++].iov_base = (char *) startp;
-
- if (*fmt == '%')
- {
- /* It is a format specifier. */
- char fill = ' ';
- int width = -1;
- int prec = -1;
-#if LONG_MAX != INT_MAX
- int long_mod = 0;
-#endif
-
- /* Recognize zero-digit fill flag. */
- if (*++fmt == '0')
- {
- fill = '0';
- ++fmt;
- }
-
- /* See whether with comes from a parameter. Note that no other
- way to specify the width is implemented. */
- if (*fmt == '*')
- {
- width = va_arg (arg, int);
- ++fmt;
- }
-
- /* Handle precision. */
- if (*fmt == '.' && fmt[1] == '*')
- {
- prec = va_arg (arg, int);
- fmt += 2;
- }
-
- /* Recognize the l modifier. It is only important on some
- platforms where long and int have a different size. We
- can use the same code for size_t. */
- if (*fmt == 'l' || *fmt == 'Z')
- {
-#if LONG_MAX != INT_MAX
- long_mod = 1;
-#endif
- ++fmt;
- }
-
- switch (*fmt)
- {
- /* Integer formatting. */
- case 'd':
- case 'u':
- case 'x':
- {
- /* We have to make a difference if long and int have a
- different size. */
-#if LONG_MAX != INT_MAX
- unsigned long int num = (long_mod
- ? va_arg (arg, unsigned long int)
- : va_arg (arg, unsigned int));
-#else
- unsigned long int num = va_arg (arg, unsigned int);
-#endif
- bool negative = false;
- if (*fmt == 'd')
- {
-#if LONG_MAX != INT_MAX
- if (long_mod)
- {
- if ((long int) num < 0)
- negative = true;
- }
- else
- {
- if ((int) num < 0)
- {
- num = (unsigned int) num;
- negative = true;
- }
- }
-#else
- if ((int) num < 0)
- negative = true;
-#endif
- }
-
- /* We use alloca() to allocate the buffer with the most
- pessimistic guess for the size. Using alloca() allows
- having more than one integer formatting in a call. */
- char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int));
- char *endp = &buf[1 + 3 * sizeof (unsigned long int)];
- char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
-
- /* Pad to the width the user specified. */
- if (width != -1)
- while (endp - cp < width)
- *--cp = fill;
-
- if (negative)
- *--cp = '-';
-
- iov[niov].iov_base = cp;
- iov[niov].iov_len = endp - cp;
- ++niov;
- }
- break;
-
- case 's':
- /* Get the string argument. */
- iov[niov].iov_base = va_arg (arg, char *);
- iov[niov].iov_len = strlen (iov[niov].iov_base);
- if (prec != -1)
- iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
- ++niov;
- break;
-
- case '%':
- iov[niov].iov_base = (void *) fmt;
- iov[niov].iov_len = 1;
- ++niov;
- break;
-
- default:
- assert (! "invalid format specifier");
- }
- ++fmt;
- }
- else if (*fmt == '\n')
- {
- /* See whether we have to print a single newline character. */
- if (fmt == startp)
- {
- iov[niov].iov_base = (char *) startp;
- iov[niov++].iov_len = 1;
- }
- else
- /* No, just add it to the rest of the string. */
- ++iov[niov - 1].iov_len;
-
- /* Next line, print a tag again. */
- tag_p = 1;
- ++fmt;
- }
- }
-
- /* Finally write the result. */
- _dl_writev (fd, iov, niov);
-}
-
-
-/* Write to debug file. */
-void
-_dl_debug_printf (const char *fmt, ...)
-{
- va_list arg;
-
- va_start (arg, fmt);
- _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
- va_end (arg);
-}
-
-
-/* Write to debug file but don't start with a tag. */
-void
-_dl_debug_printf_c (const char *fmt, ...)
-{
- va_list arg;
-
- va_start (arg, fmt);
- _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
- va_end (arg);
-}
-
-
-/* Write the given file descriptor. */
-void
-_dl_dprintf (int fd, const char *fmt, ...)
-{
- va_list arg;
-
- va_start (arg, fmt);
- _dl_debug_vdprintf (fd, 0, fmt, arg);
- va_end (arg);
-}
-
-void
-_dl_printf (const char *fmt, ...)
-{
- va_list arg;
-
- va_start (arg, fmt);
- _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg);
- va_end (arg);
-}
-
-void
-_dl_error_printf (const char *fmt, ...)
-{
- va_list arg;
-
- va_start (arg, fmt);
- _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
- va_end (arg);
-}
-
-void
-_dl_fatal_printf (const char *fmt, ...)
-{
- va_list arg;
-
- va_start (arg, fmt);
- _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
- va_end (arg);
- _exit (127);
-}
-rtld_hidden_def (_dl_fatal_printf)
-
/* Test whether given NAME matches any of the names of the given object. */
int
_dl_name_match_p (const char *name, const struct link_map *map)
@@ -354,7 +82,6 @@ _dl_name_match_p (const char *name, const struct link_map *map)
return 0;
}
-
unsigned long int
_dl_higher_prime_number (unsigned long int n)
{
diff --git a/elf/dl-printf.c b/elf/dl-printf.c
new file mode 100644
index 0000000000000000..d3264ba96cd959bf
--- /dev/null
+++ b/elf/dl-printf.c
@@ -0,0 +1,292 @@
+/* printf implementation for the dynamic loader.
+ Copyright (C) 1997-2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <_itoa.h>
+#include <assert.h>
+#include <dl-writev.h>
+#include <ldsodefs.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+/* Bare-bones printf implementation. This function only knows about
+ the formats and flags needed and can handle only up to 64 stripes in
+ the output. */
+static void
+_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
+{
+# define NIOVMAX 64
+ struct iovec iov[NIOVMAX];
+ int niov = 0;
+ pid_t pid = 0;
+ char pidbuf[12];
+
+ while (*fmt != '\0')
+ {
+ const char *startp = fmt;
+
+ if (tag_p > 0)
+ {
+ /* Generate the tag line once. It consists of the PID and a
+ colon followed by a tab. */
+ if (pid == 0)
+ {
+ char *p;
+ pid = __getpid ();
+ assert (pid >= 0 && sizeof (pid_t) <= 4);
+ p = _itoa (pid, &pidbuf[10], 10, 0);
+ while (p > pidbuf)
+ *--p = ' ';
+ pidbuf[10] = ':';
+ pidbuf[11] = '\t';
+ }
+
+ /* Append to the output. */
+ assert (niov < NIOVMAX);
+ iov[niov].iov_len = 12;
+ iov[niov++].iov_base = pidbuf;
+
+ /* No more tags until we see the next newline. */
+ tag_p = -1;
+ }
+
+ /* Skip everything except % and \n (if tags are needed). */
+ while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
+ ++fmt;
+
+ /* Append constant string. */
+ assert (niov < NIOVMAX);
+ if ((iov[niov].iov_len = fmt - startp) != 0)
+ iov[niov++].iov_base = (char *) startp;
+
+ if (*fmt == '%')
+ {
+ /* It is a format specifier. */
+ char fill = ' ';
+ int width = -1;
+ int prec = -1;
+#if LONG_MAX != INT_MAX
+ int long_mod = 0;
+#endif
+
+ /* Recognize zero-digit fill flag. */
+ if (*++fmt == '0')
+ {
+ fill = '0';
+ ++fmt;
+ }
+
+ /* See whether with comes from a parameter. Note that no other
+ way to specify the width is implemented. */
+ if (*fmt == '*')
+ {
+ width = va_arg (arg, int);
+ ++fmt;
+ }
+
+ /* Handle precision. */
+ if (*fmt == '.' && fmt[1] == '*')
+ {
+ prec = va_arg (arg, int);
+ fmt += 2;
+ }
+
+ /* Recognize the l modifier. It is only important on some
+ platforms where long and int have a different size. We
+ can use the same code for size_t. */
+ if (*fmt == 'l' || *fmt == 'Z')
+ {
+#if LONG_MAX != INT_MAX
+ long_mod = 1;
+#endif
+ ++fmt;
+ }
+
+ switch (*fmt)
+ {
+ /* Integer formatting. */
+ case 'd':
+ case 'u':
+ case 'x':
+ {
+ /* We have to make a difference if long and int have a
+ different size. */
+#if LONG_MAX != INT_MAX
+ unsigned long int num = (long_mod
+ ? va_arg (arg, unsigned long int)
+ : va_arg (arg, unsigned int));
+#else
+ unsigned long int num = va_arg (arg, unsigned int);
+#endif
+ bool negative = false;
+ if (*fmt == 'd')
+ {
+#if LONG_MAX != INT_MAX
+ if (long_mod)
+ {
+ if ((long int) num < 0)
+ negative = true;
+ }
+ else
+ {
+ if ((int) num < 0)
+ {
+ num = (unsigned int) num;
+ negative = true;
+ }
+ }
+#else
+ if ((int) num < 0)
+ negative = true;
+#endif
+ }
+
+ /* We use alloca() to allocate the buffer with the most
+ pessimistic guess for the size. Using alloca() allows
+ having more than one integer formatting in a call. */
+ char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int));
+ char *endp = &buf[1 + 3 * sizeof (unsigned long int)];
+ char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
+
+ /* Pad to the width the user specified. */
+ if (width != -1)
+ while (endp - cp < width)
+ *--cp = fill;
+
+ if (negative)
+ *--cp = '-';
+
+ iov[niov].iov_base = cp;
+ iov[niov].iov_len = endp - cp;
+ ++niov;
+ }
+ break;
+
+ case 's':
+ /* Get the string argument. */
+ iov[niov].iov_base = va_arg (arg, char *);
+ iov[niov].iov_len = strlen (iov[niov].iov_base);
+ if (prec != -1)
+ iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
+ ++niov;
+ break;
+
+ case '%':
+ iov[niov].iov_base = (void *) fmt;
+ iov[niov].iov_len = 1;
+ ++niov;
+ break;
+
+ default:
+ assert (! "invalid format specifier");
+ }
+ ++fmt;
+ }
+ else if (*fmt == '\n')
+ {
+ /* See whether we have to print a single newline character. */
+ if (fmt == startp)
+ {
+ iov[niov].iov_base = (char *) startp;
+ iov[niov++].iov_len = 1;
+ }
+ else
+ /* No, just add it to the rest of the string. */
+ ++iov[niov - 1].iov_len;
+
+ /* Next line, print a tag again. */
+ tag_p = 1;
+ ++fmt;
+ }
+ }
+
+ /* Finally write the result. */
+ _dl_writev (fd, iov, niov);
+}
+
+
+/* Write to debug file. */
+void
+_dl_debug_printf (const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start (arg, fmt);
+ _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
+ va_end (arg);
+}
+
+
+/* Write to debug file but don't start with a tag. */
+void
+_dl_debug_printf_c (const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start (arg, fmt);
+ _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
+ va_end (arg);
+}
+
+
+/* Write the given file descriptor. */
+void
+_dl_dprintf (int fd, const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start (arg, fmt);
+ _dl_debug_vdprintf (fd, 0, fmt, arg);
+ va_end (arg);
+}
+
+void
+_dl_printf (const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start (arg, fmt);
+ _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg);
+ va_end (arg);
+}
+
+void
+_dl_error_printf (const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start (arg, fmt);
+ _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
+ va_end (arg);
+}
+
+void
+_dl_fatal_printf (const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start (arg, fmt);
+ _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
+ va_end (arg);
+ _exit (127);
+}
+rtld_hidden_def (_dl_fatal_printf)

View File

@ -0,0 +1,146 @@
commit 9ba202c78f0aa39f49929eee63c367847da72ee4
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Jan 14 20:16:05 2022 +0100
Add --with-rtld-early-cflags configure option
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Conflicts:
INSTALL
configure
manual/install.texi
(Missing --with-timeout-factor downstream.)
diff --git a/INSTALL b/INSTALL
index d6d93ec9be4262d7..d8d4e9f155f56616 100644
--- a/INSTALL
+++ b/INSTALL
@@ -106,6 +106,14 @@ if 'CFLAGS' is specified it must enable optimization. For example:
particular case and potentially change debugging information and
metadata only).
+'--with-rtld-early-cflags=CFLAGS'
+ Use additional compiler flags CFLAGS to build the early startup
+ code of the dynamic linker. These flags can be used to enable
+ early dynamic linker diagnostics to run on CPUs which are not
+ compatible with the rest of the GNU C Library, for example, due to
+ compiler flags which target a later instruction set architecture
+ (ISA).
+
'--disable-shared'
Don't build shared libraries even if it is possible. Not all
systems support shared libraries; you need ELF support and
diff --git a/config.make.in b/config.make.in
index e8630a8d0ccf874d..6d43e691f7823262 100644
--- a/config.make.in
+++ b/config.make.in
@@ -110,6 +110,7 @@ CFLAGS = @CFLAGS@
CPPFLAGS-config = @CPPFLAGS@
CPPUNDEFS = @CPPUNDEFS@
extra-nonshared-cflags = @extra_nonshared_cflags@
+rtld-early-cflags = @rtld_early_cflags@
ASFLAGS-config = @ASFLAGS_config@
AR = @AR@
NM = @NM@
diff --git a/configure b/configure
index e9d2b1f398c4dba0..03f4e59e754b5463 100755
--- a/configure
+++ b/configure
@@ -681,6 +681,7 @@ force_install
bindnow
hardcoded_path_in_tests
enable_timezone_tools
+rtld_early_cflags
extra_nonshared_cflags
use_default_link
sysheaders
@@ -761,6 +762,7 @@ with_selinux
with_headers
with_default_link
with_nonshared_cflags
+with_rtld_early_cflags
enable_sanity_checks
enable_shared
enable_profile
@@ -1479,6 +1481,8 @@ Optional Packages:
--with-default-link do not use explicit linker scripts
--with-nonshared-cflags=CFLAGS
build nonshared libraries with additional CFLAGS
+ --with-rtld-early-cflags=CFLAGS
+ build early initialization with additional CFLAGS
--with-cpu=CPU select code for CPU variant
Some influential environment variables:
@@ -3383,6 +3387,16 @@ fi
+# Check whether --with-rtld-early-cflags was given.
+if test "${with_rtld_early_cflags+set}" = set; then :
+ withval=$with_rtld_early_cflags; rtld_early_cflags=$withval
+else
+ rtld_early_cflags=
+fi
+
+
+
+
# Check whether --enable-sanity-checks was given.
if test "${enable_sanity_checks+set}" = set; then :
enableval=$enable_sanity_checks; enable_sanity=$enableval
diff --git a/configure.ac b/configure.ac
index 79f6822d29ce21cf..eb9431875fae1b0e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -162,6 +162,12 @@ AC_ARG_WITH([nonshared-cflags],
[extra_nonshared_cflags=$withval],
[extra_nonshared_cflags=])
AC_SUBST(extra_nonshared_cflags)
+AC_ARG_WITH([rtld-early-cflags],
+ AS_HELP_STRING([--with-rtld-early-cflags=CFLAGS],
+ [build early initialization with additional CFLAGS]),
+ [rtld_early_cflags=$withval],
+ [rtld_early_cflags=])
+AC_SUBST(rtld_early_cflags)
AC_ARG_ENABLE([sanity-checks],
AS_HELP_STRING([--disable-sanity-checks],
diff --git a/elf/Makefile b/elf/Makefile
index 52aafc89cec835ab..778e393395fc5248 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -152,6 +152,14 @@ CFLAGS-.o += $(call elide-stack-protector,.o,$(elide-routines.os))
CFLAGS-.op += $(call elide-stack-protector,.op,$(elide-routines.os))
CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines))
+# Add the requested compiler flags to the early startup code.
+CFLAGS-dl-printf.os += $(rtld-early-cflags)
+CFLAGS-dl-sysdep.os += $(rtld-early-cflags)
+CFLAGS-dl-tunables.os += $(rtld-early-cflags)
+CFLAGS-dl-write.os += $(rtld-early-cflags)
+CFLAGS-dl-writev.os += $(rtld-early-cflags)
+CFLAGS-rtld.os += $(rtld-early-cflags)
+
ifeq ($(unwind-find-fde),yes)
routines += unwind-dw2-fde-glibc
shared-only-routines += unwind-dw2-fde-glibc
diff --git a/manual/install.texi b/manual/install.texi
index 1320ac69b3c645f2..816b77a0a25a88a7 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -131,6 +131,13 @@ that the objects in @file{libc_nonshared.a} are compiled with this flag
(although this will not affect the generated code in this particular
case and potentially change debugging information and metadata only).
+@item --with-rtld-early-cflags=@var{cflags}
+Use additional compiler flags @var{cflags} to build the early startup
+code of the dynamic linker. These flags can be used to enable early
+dynamic linker diagnostics to run on CPUs which are not compatible with
+the rest of @theglibc{}, for example, due to compiler flags which target
+a later instruction set architecture (ISA).
+
@c disable static doesn't work currently
@c @item --disable-static
@c Don't build static libraries. Static libraries aren't that useful these

View File

@ -0,0 +1,52 @@
commit 550116486692efc394d03befee19f7e9c17d5044
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Jan 14 20:16:05 2022 +0100
powerpc64le: Use <gcc-macros.h> in early HWCAP check
This is required so that the checks still work if $(early-cflags)
selects a different ISA level.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
diff --git a/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h
index 0437ae4d522fb36d..899c74f880e6f5f0 100644
--- a/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h
+++ b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h
@@ -19,17 +19,18 @@
#ifndef _DL_HWCAP_CHECK_H
#define _DL_HWCAP_CHECK_H
+#include <gcc-macros.h>
#include <ldsodefs.h>
static inline void
dl_hwcap_check (void)
{
-#ifdef _ARCH_PWR9
+#ifdef GCCMACRO_ARCH_PWR9
if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_00) == 0)
_dl_fatal_printf ("\
Fatal glibc error: CPU lacks ISA 3.00 support (POWER9 or later required)\n");
#endif
-#ifdef __FLOAT128_HARDWARE__
+#ifdef GCCMACRO__FLOAT128_HARDWARE__
if ((GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_IEEE128) == 0)
_dl_fatal_printf ("\
Fatal glibc error: CPU lacks float128 support (POWER 9 or later required)\n");
@@ -37,12 +38,12 @@ Fatal glibc error: CPU lacks float128 support (POWER 9 or later required)\n");
/* This check is not actually reached when building for POWER10 and
running on POWER9 because there are faulting PCREL instructions
before this point. */
-#if defined _ARCH_PWR10 || defined __PCREL__
+#if defined GCCMACRO_ARCH_PWR10 || defined GCCMACRO__PCREL__
if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_1) == 0)
_dl_fatal_printf ("\
Fatal glibc error: CPU lacks ISA 3.10 support (POWER10 or later required)\n");
#endif
-#ifdef __MMA__
+#ifdef GCCMACRO__MMA__
if ((GLRO (dl_hwcap2) & PPC_FEATURE2_MMA) == 0)
_dl_fatal_printf ("\
Fatal glibc error: CPU lacks MMA support (POWER10 or later required)\n");

View File

@ -0,0 +1,95 @@
commit e09e7b1492b2d5c2f68ddf81f8f58e093dd4df6d
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Mon Dec 13 11:36:42 2021 -0300
support: Add support_socket_so_timestamp_time64
Check if the socket support 64-bit network packages timestamps
(SO_TIMESTAMP and SO_TIMESTAMPNS). This will be used on recvmsg
and recvmmsg tests to check if the timestamp should be generated.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from 38bc0f4e78934aab455b31af05cefcbf3c22bece)
diff --git a/support/Makefile b/support/Makefile
index 3c941e1ba9e29aa4..6a5fc9faf2ca2e2d 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -79,6 +79,7 @@ libsupport-routines = \
support_set_small_thread_stack_size \
support_shared_allocate \
support_small_stack_thread_attribute \
+ support_socket_so_timestamp_time64 \
support_stat_nanoseconds \
support_subprocess \
support_test_compare_blob \
diff --git a/support/support.h b/support/support.h
index 29d56c7c891ee34b..ecfc9a336d272a30 100644
--- a/support/support.h
+++ b/support/support.h
@@ -170,6 +170,10 @@ extern bool support_select_modifies_timeout (void);
tv_usec larger than 1000000. */
extern bool support_select_normalizes_timeout (void);
+/* Return true if socket FD supports 64-bit timestamps with the SOL_SOCKET
+ and SO_TIMESTAMP/SO_TIMESTAMPNS. */
+extern bool support_socket_so_timestamp_time64 (int fd);
+
/* Create a timer that trigger after SEC seconds and NSEC nanoseconds. If
REPEAT is true the timer will repeat indefinitely. If CALLBACK is not
NULL, the function will be called when the timer expires; otherwise a
diff --git a/support/support_socket_so_timestamp_time64.c b/support/support_socket_so_timestamp_time64.c
new file mode 100644
index 0000000000000000..54bf3f42724566f5
--- /dev/null
+++ b/support/support_socket_so_timestamp_time64.c
@@ -0,0 +1,48 @@
+/* Return whether socket supports 64-bit timestamps.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/socket.h>
+#include <support/support.h>
+#ifdef __linux__
+# include <socket-constants-time64.h>
+#endif
+
+bool
+support_socket_so_timestamp_time64 (int fd)
+{
+#ifdef __linux__
+# if __LINUX_KERNEL_VERSION >= 0x050100 \
+ || __WORDSIZE == 64 \
+ || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64)
+ return true;
+# else
+ int level = SOL_SOCKET;
+ int optname = COMPAT_SO_TIMESTAMP_NEW;
+ int optval;
+ socklen_t len = sizeof (optval);
+
+ int r = syscall (__NR_getsockopt, fd, level, optname, &optval, &len);
+ return r != -1;
+# endif
+#else
+ return false;
+#endif
+}

View File

@ -0,0 +1,431 @@
commit e098446037da532d4a250efac9a813bc22f3669f
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Mon Jan 24 08:55:53 2022 -0300
linux: Fix ancillary 64-bit time timestamp conversion (BZ #28349, BZ#28350)
The __convert_scm_timestamps only updates the control message last
pointer for SOL_SOCKET type, so if the message control buffer contains
multiple ancillary message types the converted timestamp one might
overwrite a valid message.
The test checks if the extra ancillary space is correctly handled
by recvmsg/recvmmsg, where if there is no extra space for the 64-bit
time_t converted message the control buffer should be marked with
MSG_TRUNC. It also check if recvmsg/recvmmsg handle correctly multiple
ancillary data.
Checked on x86_64-linux and on i686-linux-gnu on both 5.11 and
4.15 kernel.
Co-authored-by: Fabian Vogt <fvogt@suse.de>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 8fba672472ae0055387e9315fc2eddfa6775ca79)
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index cdc01a3f023ec09a..7c75e22c6d0e9ff5 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -273,6 +273,9 @@ sysdep_routines += cmsg_nxthdr
CFLAGS-recvmmsg.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-sendmmsg.c = -fexceptions -fasynchronous-unwind-tables
+tests += tst-socket-timestamp
+tests-time64 += tst-socket-timestamp-time64
+
tests-special += $(objpfx)tst-socket-consts.out
$(objpfx)tst-socket-consts.out: ../sysdeps/unix/sysv/linux/tst-socket-consts.py
PYTHONPATH=../scripts \
diff --git a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
index 00c934c4135f0d42..5d3c4199e0b32944 100644
--- a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
+++ b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
@@ -54,6 +54,8 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
cmsg != NULL;
cmsg = CMSG_NXTHDR (msg, cmsg))
{
+ last = cmsg;
+
if (cmsg->cmsg_level != SOL_SOCKET)
continue;
@@ -75,11 +77,9 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
tvts[1] = tmp[1];
break;
}
-
- last = cmsg;
}
- if (last == NULL || type == 0)
+ if (type == 0)
return;
if (CMSG_SPACE (sizeof tvts) > msgsize - msg->msg_controllen)
@@ -88,10 +88,12 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
return;
}
+ /* Zero memory for the new cmsghdr, so reading cmsg_len field
+ by CMSG_NXTHDR does not trigger UB. */
+ memset (msg->msg_control + msg->msg_controllen, 0,
+ CMSG_SPACE (sizeof tvts));
msg->msg_controllen += CMSG_SPACE (sizeof tvts);
- cmsg = CMSG_NXTHDR(msg, last);
- if (cmsg == NULL)
- return;
+ cmsg = CMSG_NXTHDR (msg, last);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = type;
cmsg->cmsg_len = CMSG_LEN (sizeof tvts);
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-time64.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-time64.c
new file mode 100644
index 0000000000000000..ae424c2a70026cf5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-time64.c
@@ -0,0 +1 @@
+#include "tst-socket-timestamp.c"
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp.c
new file mode 100644
index 0000000000000000..9c2e76f7e27bd312
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp.c
@@ -0,0 +1,336 @@
+/* Check recvmsg/recvmmsg 64-bit timestamp support.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <array_length.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <support/check.h>
+#include <support/next_to_fault.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+#include <support/xsocket.h>
+#include <sys/mman.h>
+
+/* Some extra space added for ancillary data, it might be used to convert
+ 32-bit timestamp to 64-bit for _TIME_BITS=64. */
+enum { slack_max_size = 64 };
+static const int slack[] = { 0, 4, 8, 16, 32, slack_max_size };
+
+static bool support_64_timestamp;
+/* AF_INET socket and address used to receive data. */
+static int srv;
+static struct sockaddr_in srv_addr;
+
+static int
+do_sendto (const struct sockaddr_in *addr, int nmsgs)
+{
+ int s = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ xconnect (s, (const struct sockaddr *) addr, sizeof (*addr));
+
+ for (int i = 0; i < nmsgs; i++)
+ xsendto (s, &i, sizeof (i), 0, (const struct sockaddr *) addr,
+ sizeof (*addr));
+
+ xclose (s);
+
+ return 0;
+}
+
+static void
+do_recvmsg_slack_ancillary (bool use_multi_call, int s, void *cmsg,
+ size_t slack, size_t tsize, int exp_payload)
+{
+ int payload;
+ struct iovec iov =
+ {
+ .iov_base = &payload,
+ .iov_len = sizeof (payload)
+ };
+ size_t msg_controllen = CMSG_SPACE (tsize) + slack;
+ char *msg_control = cmsg - msg_controllen;
+ memset (msg_control, 0x55, msg_controllen);
+ struct mmsghdr mmhdr =
+ {
+ .msg_hdr =
+ {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = msg_control,
+ .msg_controllen = msg_controllen
+ },
+ };
+
+ int r;
+ if (use_multi_call)
+ {
+ r = recvmmsg (s, &mmhdr, 1, 0, NULL);
+ if (r >= 0)
+ r = mmhdr.msg_len;
+ }
+ else
+ r = recvmsg (s, &mmhdr.msg_hdr, 0);
+ TEST_COMPARE (r, sizeof (int));
+ TEST_COMPARE (payload, exp_payload);
+
+ if (cmsg == NULL)
+ return;
+
+ /* A timestamp is expected if 32-bit timestamp are used (support in every
+ configuration) or if underlying kernel support 64-bit timestamps.
+ Otherwise recvmsg will need extra space do add the 64-bit timestamp. */
+ bool exp_timestamp;
+ if (sizeof (time_t) == 4 || support_64_timestamp)
+ exp_timestamp = true;
+ else
+ exp_timestamp = slack >= CMSG_SPACE (tsize);
+
+ bool timestamp = false;
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET)
+ continue;
+ if (cmsg->cmsg_type == SCM_TIMESTAMP
+ && cmsg->cmsg_len == CMSG_LEN (sizeof (struct timeval)))
+ {
+ struct timeval tv;
+ memcpy (&tv, CMSG_DATA (cmsg), sizeof (tv));
+ if (test_verbose)
+ printf ("SCM_TIMESTAMP: {%jd, %jd}\n", (intmax_t)tv.tv_sec,
+ (intmax_t)tv.tv_usec);
+ timestamp = true;
+ }
+ else if (cmsg->cmsg_type == SCM_TIMESTAMPNS
+ && cmsg->cmsg_len == CMSG_LEN (sizeof (struct timespec)))
+ {
+ struct timespec ts;
+ memcpy (&ts, CMSG_DATA (cmsg), sizeof (ts));
+ if (test_verbose)
+ printf ("SCM_TIMESTAMPNS: {%jd, %jd}\n", (intmax_t)ts.tv_sec,
+ (intmax_t)ts.tv_nsec);
+ timestamp = true;
+ }
+ }
+
+ TEST_COMPARE (timestamp, exp_timestamp);
+}
+
+/* Check if the extra ancillary space is correctly handled by recvmsg and
+ recvmmsg with different extra space for the ancillaty buffer. */
+static void
+do_test_slack_space (void)
+{
+ /* Setup the ancillary data buffer with an extra page with PROT_NONE to
+ check the possible timestamp conversion on some systems. */
+ struct support_next_to_fault nf =
+ support_next_to_fault_allocate (slack_max_size);
+ void *msgbuf = nf.buffer + slack_max_size;
+
+ /* Enable the timestamp using struct timeval precision. */
+ {
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP, &(int){1},
+ sizeof (int));
+ TEST_VERIFY_EXIT (r != -1);
+ }
+ /* Check recvmsg. */
+ do_sendto (&srv_addr, array_length (slack));
+ for (int s = 0; s < array_length (slack); s++)
+ {
+ memset (nf.buffer, 0x55, nf.length);
+ do_recvmsg_slack_ancillary (false, srv, msgbuf, slack[s],
+ sizeof (struct timeval), s);
+ }
+ /* Check recvmmsg. */
+ do_sendto (&srv_addr, array_length (slack));
+ for (int s = 0; s < array_length (slack); s++)
+ {
+ memset (nf.buffer, 0x55, nf.length);
+ do_recvmsg_slack_ancillary (true, srv, msgbuf, slack[s],
+ sizeof (struct timeval), s);
+ }
+
+ /* Now enable timestamp using a higher precision, it overwrites the previous
+ precision. */
+ {
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMPNS, &(int){1},
+ sizeof (int));
+ TEST_VERIFY_EXIT (r != -1);
+ }
+ /* Check recvmsg. */
+ do_sendto (&srv_addr, array_length (slack));
+ for (int s = 0; s < array_length (slack); s++)
+ do_recvmsg_slack_ancillary (false, srv, msgbuf, slack[s],
+ sizeof (struct timespec), s);
+ /* Check recvmmsg. */
+ do_sendto (&srv_addr, array_length (slack));
+ for (int s = 0; s < array_length (slack); s++)
+ do_recvmsg_slack_ancillary (true, srv, msgbuf, slack[s],
+ sizeof (struct timespec), s);
+
+ support_next_to_fault_free (&nf);
+}
+
+/* Check if the converted 64-bit timestamp is correctly appended when there
+ are multiple ancillary messages. */
+static void
+do_recvmsg_multiple_ancillary (bool use_multi_call, int s, void *cmsg,
+ size_t cmsgsize, int exp_msg)
+{
+ int msg;
+ struct iovec iov =
+ {
+ .iov_base = &msg,
+ .iov_len = sizeof (msg)
+ };
+ size_t msgs = cmsgsize;
+ struct mmsghdr mmhdr =
+ {
+ .msg_hdr =
+ {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_controllen = msgs,
+ .msg_control = cmsg,
+ },
+ };
+
+ int r;
+ if (use_multi_call)
+ {
+ r = recvmmsg (s, &mmhdr, 1, 0, NULL);
+ if (r >= 0)
+ r = mmhdr.msg_len;
+ }
+ else
+ r = recvmsg (s, &mmhdr.msg_hdr, 0);
+ TEST_COMPARE (r, sizeof (int));
+ TEST_COMPARE (msg, exp_msg);
+
+ if (cmsg == NULL)
+ return;
+
+ bool timestamp = false;
+ bool origdstaddr = false;
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
+ {
+ if (cmsg->cmsg_level == SOL_IP
+ && cmsg->cmsg_type == IP_ORIGDSTADDR
+ && cmsg->cmsg_len >= CMSG_LEN (sizeof (struct sockaddr_in)))
+ {
+ struct sockaddr_in sa;
+ memcpy (&sa, CMSG_DATA (cmsg), sizeof (sa));
+ if (test_verbose)
+ {
+ char str[INET_ADDRSTRLEN];
+ inet_ntop (AF_INET, &sa.sin_addr, str, INET_ADDRSTRLEN);
+ printf ("IP_ORIGDSTADDR: %s:%d\n", str, ntohs (sa.sin_port));
+ }
+ origdstaddr = sa.sin_addr.s_addr == srv_addr.sin_addr.s_addr
+ && sa.sin_port == srv_addr.sin_port;
+ }
+ if (cmsg->cmsg_level == SOL_SOCKET
+ && cmsg->cmsg_type == SCM_TIMESTAMP
+ && cmsg->cmsg_len >= CMSG_LEN (sizeof (struct timeval)))
+ {
+ struct timeval tv;
+ memcpy (&tv, CMSG_DATA (cmsg), sizeof (tv));
+ if (test_verbose)
+ printf ("SCM_TIMESTAMP: {%jd, %jd}\n", (intmax_t)tv.tv_sec,
+ (intmax_t)tv.tv_usec);
+ timestamp = true;
+ }
+ }
+
+ TEST_COMPARE (timestamp, true);
+ TEST_COMPARE (origdstaddr, true);
+}
+
+static void
+do_test_multiple_ancillary (void)
+{
+ {
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP, &(int){1},
+ sizeof (int));
+ TEST_VERIFY_EXIT (r != -1);
+ }
+ {
+ int r = setsockopt (srv, IPPROTO_IP, IP_RECVORIGDSTADDR, &(int){1},
+ sizeof (int));
+ TEST_VERIFY_EXIT (r != -1);
+ }
+
+ /* Enougth data for default SO_TIMESTAMP, the IP_RECVORIGDSTADDR, and the
+ extra 64-bit SO_TIMESTAMP. */
+ enum { msgbuflen = CMSG_SPACE (2 * sizeof (uint64_t))
+ + CMSG_SPACE (sizeof (struct sockaddr_in))
+ + CMSG_SPACE (2 * sizeof (uint64_t)) };
+ char msgbuf[msgbuflen];
+
+ enum { nmsgs = 8 };
+ /* Check recvmsg. */
+ do_sendto (&srv_addr, nmsgs);
+ for (int s = 0; s < nmsgs; s++)
+ do_recvmsg_multiple_ancillary (false, srv, msgbuf, msgbuflen, s);
+ /* Check recvmmsg. */
+ do_sendto (&srv_addr, nmsgs);
+ for (int s = 0; s < nmsgs; s++)
+ do_recvmsg_multiple_ancillary (true, srv, msgbuf, msgbuflen, s);
+}
+
+static int
+do_test (void)
+{
+ srv = xsocket (AF_INET, SOCK_DGRAM, 0);
+ srv_addr = (struct sockaddr_in) {
+ .sin_family = AF_INET,
+ .sin_addr = {.s_addr = htonl (INADDR_LOOPBACK) },
+ };
+ xbind (srv, (struct sockaddr *) &srv_addr, sizeof (srv_addr));
+ {
+ socklen_t sa_len = sizeof (srv_addr);
+ xgetsockname (srv, (struct sockaddr *) &srv_addr, &sa_len);
+ TEST_VERIFY (sa_len == sizeof (srv_addr));
+ }
+
+ TEST_COMPARE (recvmsg (-1, NULL, 0), -1);
+ TEST_COMPARE (errno, EBADF);
+ TEST_COMPARE (recvmmsg (-1, NULL, 0, 0, NULL), -1);
+ TEST_COMPARE (errno, EBADF);
+
+ /* If underlying kernel does not support */
+ support_64_timestamp = support_socket_so_timestamp_time64 (srv);
+
+ do_test_slack_space ();
+ do_test_multiple_ancillary ();
+
+ xclose (srv);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -0,0 +1,485 @@
commit 489d0b8b32548bc569cd3067aebf98b030720753
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Thu Jan 27 16:45:18 2022 -0300
Linux: Only generate 64 bit timestamps for 64 bit time_t recvmsg/recvmmsg
The timestamps created by __convert_scm_timestamps only make sense for
64 bit time_t programs, 32 bit time_t programs will ignore 64 bit time_t
timestamps since SO_TIMESTAMP will be defined to old values (either by
glibc or kernel headers).
Worse, if the buffer is not suffice MSG_CTRUNC is set to indicate it
(which breaks some programs [1]).
This patch makes only 64 bit time_t recvmsg and recvmmsg to call
__convert_scm_timestamps. Also, the assumption to called it is changed
from __ASSUME_TIME64_SYSCALLS to __TIMESIZE != 64 since the setsockopt
might be called by libraries built without __TIME_BITS=64. The
MSG_CTRUNC is only set for the 64 bit symbols, it should happen only
if 64 bit time_t programs run older kernels.
Checked on x86_64-linux-gnu and i686-linux-gnu.
[1] https://github.com/systemd/systemd/pull/20567
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 948ce73b31fdb0860bcec4b8e62b14e88234f98a)
diff --git a/include/sys/socket.h b/include/sys/socket.h
index a1d749f9fa7b9257..6e4cf5077fb885a9 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -98,15 +98,21 @@ extern int __sendmmsg (int __fd, struct mmsghdr *__vmessages,
libc_hidden_proto (__sendmmsg)
#endif
-/* Receive a message as described by MESSAGE from socket FD.
- Returns the number of bytes read or -1 for errors. */
extern ssize_t __libc_recvmsg (int __fd, struct msghdr *__message,
int __flags);
extern ssize_t __recvmsg (int __fd, struct msghdr *__message,
int __flags) attribute_hidden;
#if __TIMESIZE == 64
+# define __libc_recvmsg64 __libc_recvmsg
+# define __recvmsg64 __recvmsg
# define __recvmmsg64 __recvmmsg
#else
+extern ssize_t __libc_recvmsg64 (int __fd, struct msghdr *__message,
+ int __flags);
+extern ssize_t __recvmsg64 (int __fd, struct msghdr *__message,
+ int __flags);
+/* Receive a message as described by MESSAGE from socket FD.
+ Returns the number of bytes read or -1 for errors. */
extern int __recvmmsg64 (int __fd, struct mmsghdr *vmessages,
unsigned int vlen, int flags,
struct __timespec64 *timeout);
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 7c75e22c6d0e9ff5..0657f4003e7116c6 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -273,8 +273,14 @@ sysdep_routines += cmsg_nxthdr
CFLAGS-recvmmsg.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-sendmmsg.c = -fexceptions -fasynchronous-unwind-tables
-tests += tst-socket-timestamp
-tests-time64 += tst-socket-timestamp-time64
+tests += \
+ tst-socket-timestamp \
+ tst-socket-timestamp-compat \
+ # tests
+tests-time64 += \
+ tst-socket-timestamp-time64 \
+ tst-socket-timestamp-compat-time64
+ # tests-time64
tests-special += $(objpfx)tst-socket-consts.out
$(objpfx)tst-socket-consts.out: ../sysdeps/unix/sysv/linux/tst-socket-consts.py
diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
index 5cd107ffa9be0699..fca9f6582db67fd7 100644
--- a/sysdeps/unix/sysv/linux/recvmmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmmsg.c
@@ -20,9 +20,9 @@
#include <sysdep.h>
#include <socketcall.h>
-int
-__recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
- struct __timespec64 *timeout)
+static int
+recvmmsg_syscall (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+ int flags, struct __timespec64 *timeout)
{
#ifndef __NR_recvmmsg_time64
# define __NR_recvmmsg_time64 __NR_recvmmsg
@@ -45,12 +45,6 @@ __recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
pts32 = &ts32;
}
- socklen_t csize[IOV_MAX];
- if (vlen > IOV_MAX)
- vlen = IOV_MAX;
- for (int i = 0; i < vlen; i++)
- csize[i] = vmessages[i].msg_hdr.msg_controllen;
-
# ifdef __ASSUME_RECVMMSG_SYSCALL
r = SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
# else
@@ -60,11 +54,31 @@ __recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
{
if (timeout != NULL)
*timeout = valid_timespec_to_timespec64 (ts32);
+ }
+#endif
+ return r;
+}
+
+int
+__recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
+ struct __timespec64 *timeout)
+{
+#if __TIMESIZE != 64
+ socklen_t csize[IOV_MAX];
+ if (vlen > IOV_MAX)
+ vlen = IOV_MAX;
+ for (int i = 0; i < vlen; i++)
+ csize[i] = vmessages[i].msg_hdr.msg_controllen;
+#endif
+ int r = recvmmsg_syscall (fd, vmessages, vlen, flags, timeout);
+#if __TIMESIZE != 64
+ if (r > 0)
+ {
for (int i=0; i < r; i++)
__convert_scm_timestamps (&vmessages[i].msg_hdr, csize[i]);
}
-#endif /* __ASSUME_TIME64_SYSCALLS */
+#endif
return r;
}
#if __TIMESIZE != 64
@@ -80,7 +94,7 @@ __recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
ts64 = valid_timespec_to_timespec64 (*timeout);
pts64 = &ts64;
}
- int r = __recvmmsg64 (fd, vmessages, vlen, flags, pts64);
+ int r = recvmmsg_syscall (fd, vmessages, vlen, flags, pts64);
if (r >= 0 && timeout != NULL)
/* The remanining timeout will be always less the input TIMEOUT. */
*timeout = valid_timespec64_to_timespec (ts64);
diff --git a/sysdeps/unix/sysv/linux/recvmsg.c b/sysdeps/unix/sysv/linux/recvmsg.c
index 07212f7c8641a921..c4b4704fd65d80c1 100644
--- a/sysdeps/unix/sysv/linux/recvmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmsg.c
@@ -20,29 +20,41 @@
#include <sysdep-cancel.h>
#include <socketcall.h>
+static int
+__recvmsg_syscall (int fd, struct msghdr *msg, int flags)
+{
+#ifdef __ASSUME_RECVMSG_SYSCALL
+ return SYSCALL_CANCEL (recvmsg, fd, msg, flags);
+#else
+ return SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
+#endif
+}
+
ssize_t
-__libc_recvmsg (int fd, struct msghdr *msg, int flags)
+__libc_recvmsg64 (int fd, struct msghdr *msg, int flags)
{
ssize_t r;
-#ifndef __ASSUME_TIME64_SYSCALLS
+#if __TIMESIZE != 64
socklen_t orig_controllen = msg != NULL ? msg->msg_controllen : 0;
#endif
-#ifdef __ASSUME_RECVMSG_SYSCALL
- r = SYSCALL_CANCEL (recvmsg, fd, msg, flags);
-#else
- r = SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
-#endif
+ r = __recvmsg_syscall (fd, msg, flags);
-#ifndef __ASSUME_TIME64_SYSCALLS
+#if __TIMESIZE != 64
if (r >= 0 && orig_controllen != 0)
__convert_scm_timestamps (msg, orig_controllen);
#endif
return r;
}
-weak_alias (__libc_recvmsg, recvmsg)
-weak_alias (__libc_recvmsg, __recvmsg)
#if __TIMESIZE != 64
-weak_alias (__recvmsg, __recvmsg64)
+weak_alias (__libc_recvmsg64, __recvmsg64)
+
+ssize_t
+__libc_recvmsg (int fd, struct msghdr *msg, int flags)
+{
+ return __recvmsg_syscall (fd, msg, flags);
+}
#endif
+weak_alias (__libc_recvmsg, recvmsg)
+weak_alias (__libc_recvmsg, __recvmsg)
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat-time64.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat-time64.c
new file mode 100644
index 0000000000000000..96a0bef0bf4a908b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat-time64.c
@@ -0,0 +1 @@
+#include "tst-socket-timestamp-compat.c"
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
new file mode 100644
index 0000000000000000..de261dae5a6385cf
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
@@ -0,0 +1,265 @@
+/* Check recvmsg/recvmmsg 64-bit timestamp support.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/inet.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/xsocket.h>
+#include <support/xunistd.h>
+#include <stdbool.h>
+
+/* AF_INET socket and address used to receive data. */
+static int srv;
+static struct sockaddr_in srv_addr;
+
+static int
+do_sendto (const struct sockaddr_in *addr, int payload)
+{
+ int s = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ xconnect (s, (const struct sockaddr *) addr, sizeof (*addr));
+
+ xsendto (s, &payload, sizeof (payload), 0, (const struct sockaddr *) addr,
+ sizeof (*addr));
+
+ xclose (s);
+
+ return 0;
+}
+
+static void
+do_recvmsg_ancillary (bool use_multi_call, struct mmsghdr *mmhdr,
+ void *msgbuf, size_t msgbuflen, int exp_payload)
+{
+ int payload;
+ struct iovec iov =
+ {
+ .iov_base = &payload,
+ .iov_len = sizeof (payload)
+ };
+ mmhdr->msg_hdr.msg_name = NULL;
+ mmhdr->msg_hdr.msg_iov = &iov;
+ mmhdr->msg_hdr.msg_iovlen = 1;
+ mmhdr->msg_hdr.msg_control = msgbuf;
+ mmhdr->msg_hdr.msg_controllen = msgbuflen;
+
+ int r;
+ if (use_multi_call)
+ {
+ r = recvmmsg (srv, mmhdr, 1, 0, NULL);
+ if (r >= 0)
+ r = mmhdr->msg_len;
+ }
+ else
+ r = recvmsg (srv, &mmhdr->msg_hdr, 0);
+ TEST_COMPARE (r, sizeof (int));
+ TEST_COMPARE (payload, exp_payload);
+}
+
+/* Check if recvmsg create the additional 64 bit timestamp if only 32 bit
+ is enabled for 64 bit recvmsg symbol. */
+static void
+do_test_large_buffer (bool mc)
+{
+ struct mmsghdr mmhdr = { 0 };
+ /* It should be large enought for either timeval/timespec and the
+ 64 time type as well. */
+
+ union
+ {
+ struct cmsghdr cmsghdr;
+ char msgbuf[512];
+ } control;
+
+ /* Enable 32 bit timeval precision and check if no 64 bit timeval stamp
+ is created. */
+ {
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP_OLD, &(int){1},
+ sizeof (int));
+ TEST_VERIFY_EXIT (r != -1);
+
+ do_sendto (&srv_addr, 42);
+ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42);
+
+ bool found_timestamp = false;
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET)
+ continue;
+
+ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMP_NEW)
+ found_timestamp = true;
+ else
+ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMP_NEW);
+ }
+
+ TEST_COMPARE (found_timestamp, sizeof (time_t) > 4);
+ }
+
+ /* Same as before, but for timespec. */
+ {
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMPNS_OLD, &(int){1},
+ sizeof (int));
+ TEST_VERIFY_EXIT (r != -1);
+
+ do_sendto (&srv_addr, 42);
+ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42);
+
+ bool found_timestamp = false;
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET)
+ continue;
+
+ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMPNS_NEW)
+ found_timestamp = true;
+ else
+ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMPNS_NEW);
+ }
+
+ TEST_COMPARE (found_timestamp, sizeof (time_t) > 4);
+ }
+}
+
+/* Check if recvmsg does not create the additional 64 bit timestamp if
+ only 32 bit timestamp is enabled if the ancillary buffer is not large
+ enought. Also checks if MSG_CTRUNC is set iff for 64 bit recvmsg
+ symbol. */
+static void
+do_test_small_buffer (bool mc)
+{
+ struct mmsghdr mmhdr = { 0 };
+
+ /* Enable 32 bit timeval precision and check if no 64 bit timeval stamp
+ is created. */
+ {
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP_OLD, &(int){1},
+ sizeof (int));
+ TEST_VERIFY_EXIT (r != -1);
+
+ union
+ {
+ struct cmsghdr cmsghdr;
+ char msgbuf[CMSG_SPACE (sizeof (struct timeval))];
+ } control;
+
+ do_sendto (&srv_addr, 42);
+ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42);
+
+ bool found_timestamp = false;
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET)
+ continue;
+
+ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMP_NEW)
+ found_timestamp = true;
+ else
+ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMP_NEW);
+ }
+
+ if (sizeof (time_t) > 4)
+ {
+ TEST_VERIFY ((mmhdr.msg_hdr.msg_flags & MSG_CTRUNC));
+ TEST_COMPARE (found_timestamp, 0);
+ }
+ else
+ {
+ TEST_VERIFY (!(mmhdr.msg_hdr.msg_flags & MSG_CTRUNC));
+ TEST_COMPARE (found_timestamp, 0);
+ }
+ }
+
+ /* Same as before, but for timespec. */
+ {
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMPNS_OLD, &(int){1},
+ sizeof (int));
+ TEST_VERIFY_EXIT (r != -1);
+
+ union
+ {
+ struct cmsghdr cmsghdr;
+ char msgbuf[CMSG_SPACE (sizeof (struct timespec))];
+ } control;
+
+ do_sendto (&srv_addr, 42);
+ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42);
+
+ bool found_timestamp = false;
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET)
+ continue;
+
+ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMPNS_NEW)
+ found_timestamp = true;
+ else
+ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMPNS_NEW);
+ }
+
+ if (sizeof (time_t) > 4)
+ {
+ TEST_VERIFY ((mmhdr.msg_hdr.msg_flags & MSG_CTRUNC));
+ TEST_COMPARE (found_timestamp, 0);
+ }
+ else
+ {
+ TEST_VERIFY ((mmhdr.msg_hdr.msg_flags & MSG_CTRUNC) == 0);
+ TEST_COMPARE (found_timestamp, 0);
+ }
+ }
+}
+
+static int
+do_test (void)
+{
+ /* This test only make sense for ABIs that support 32 bit time_t socket
+ timestampss. */
+ if (sizeof (time_t) > 4 && __WORDSIZE == 64)
+ return 0;
+
+ srv = xsocket (AF_INET, SOCK_DGRAM, 0);
+ srv_addr = (struct sockaddr_in) {
+ .sin_family = AF_INET,
+ .sin_addr = {.s_addr = htonl (INADDR_LOOPBACK) },
+ };
+ xbind (srv, (struct sockaddr *) &srv_addr, sizeof (srv_addr));
+ {
+ socklen_t sa_len = sizeof (srv_addr);
+ xgetsockname (srv, (struct sockaddr *) &srv_addr, &sa_len);
+ TEST_VERIFY (sa_len == sizeof (srv_addr));
+ }
+
+ /* Check recvmsg; */
+ do_test_large_buffer (false);
+ do_test_small_buffer (false);
+ /* Check recvmmsg. */
+ do_test_large_buffer (true);
+ do_test_small_buffer (true);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -0,0 +1,24 @@
commit 008003dc6e83439c5e04a744b7fd8197df19096e
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Sat Jan 29 05:22:31 2022 -0800
tst-socket-timestamp-compat.c: Check __TIMESIZE [BZ #28837]
time_t size is defined by __TIMESIZE, not __WORDSIZE. Check __TIMESIZE,
instead of __WORDSIZE, for time_t size. This fixes BZ #28837.
(cherry pick from commit 77a602ebb0769e7ccc5f9f8e06f7fffe66f69dfc)
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
index de261dae5a6385cf..0ff1a214e605105b 100644
--- a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
@@ -237,7 +237,7 @@ do_test (void)
{
/* This test only make sense for ABIs that support 32 bit time_t socket
timestampss. */
- if (sizeof (time_t) > 4 && __WORDSIZE == 64)
+ if (sizeof (time_t) > 4 && __TIMESIZE == 64)
return 0;
srv = xsocket (AF_INET, SOCK_DGRAM, 0);

View File

@ -0,0 +1,26 @@
commit 05c83ccaf50aef2dd30d92cbb814383f6bddea2c
Author: Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
Date: Tue Feb 1 22:39:02 2022 +0000
linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage [BZ #28850]
Pass the actual number of bytes returned by the kernel.
Fixes: 33099d72e41c ("linux: Simplify get_nprocs")
Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>
(cherry picked from commit 97ba273b505763325efd802dc3a9562dbba79579)
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index 7fc6521942e87293..7babd947aa902e77 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -45,7 +45,7 @@ __get_nprocs_sched (void)
int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size,
cpu_bits);
if (r > 0)
- return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits);
+ return CPU_COUNT_S (r, (cpu_set_t*) cpu_bits);
else if (r == -EINVAL)
/* The input buffer is still not enough to store the number of cpus. This
is an arbitrary values assuming such systems should be rare and there

View File

@ -0,0 +1,234 @@
commit ad615b59c78d6d37fee921fb2b2ae6b72c930625
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Sep 28 18:55:49 2021 +0200
Linux: Simplify __opensock and fix race condition [BZ #28353]
AF_NETLINK support is not quite optional on modern Linux systems
anymore, so it is likely that the first attempt will always succeed.
Consequently, there is no need to cache the result. Keep AF_UNIX
and the Internet address families as a fallback, for the rare case
that AF_NETLINK is missing. The other address families previously
probed are totally obsolete be now, so remove them.
Use this simplified version as the generic implementation, disabling
Netlink support as needed.
(cherry picked from commit 5bf07e1b3a74232bfb8332275110be1a5da50f83)
diff --git a/socket/opensock.c b/socket/opensock.c
index 37148d4743343ff4..ff94d27a61bd3889 100644
--- a/socket/opensock.c
+++ b/socket/opensock.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1999-2021 Free Software Foundation, Inc.
+/* Create socket with an unspecified address family for use with ioctl.
+ Copyright (C) 1999-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -15,56 +16,34 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <stdio.h>
+#include <errno.h>
#include <sys/socket.h>
-#include <libc-lock.h>
/* Return a socket of any type. The socket can be used in subsequent
ioctl calls to talk to the kernel. */
int
__opensock (void)
{
- /* Cache the last AF that worked, to avoid many redundant calls to
- socket(). */
- static int sock_af = -1;
- int fd = -1;
- __libc_lock_define_initialized (static, lock);
-
- if (sock_af != -1)
- {
- fd = __socket (sock_af, SOCK_DGRAM, 0);
- if (fd != -1)
- return fd;
- }
-
- __libc_lock_lock (lock);
-
- if (sock_af != -1)
- fd = __socket (sock_af, SOCK_DGRAM, 0);
-
- if (fd == -1)
- {
-#ifdef AF_INET
- fd = __socket (sock_af = AF_INET, SOCK_DGRAM, 0);
-#endif
-#ifdef AF_INET6
- if (fd < 0)
- fd = __socket (sock_af = AF_INET6, SOCK_DGRAM, 0);
-#endif
-#ifdef AF_IPX
- if (fd < 0)
- fd = __socket (sock_af = AF_IPX, SOCK_DGRAM, 0);
-#endif
-#ifdef AF_AX25
- if (fd < 0)
- fd = __socket (sock_af = AF_AX25, SOCK_DGRAM, 0);
-#endif
-#ifdef AF_APPLETALK
- if (fd < 0)
- fd = __socket (sock_af = AF_APPLETALK, SOCK_DGRAM, 0);
+ /* SOCK_DGRAM is supported by all address families. (Netlink does
+ not support SOCK_STREAM.) */
+ int type = SOCK_DGRAM | SOCK_CLOEXEC;
+ int fd;
+
+#ifdef AF_NETLINK
+ fd = __socket (AF_NETLINK, type, 0);
+ if (fd >= 0)
+ return fd;
#endif
- }
- __libc_lock_unlock (lock);
+ fd = __socket (AF_UNIX, type, 0);
+ if (fd >= 0)
+ return fd;
+ fd = __socket (AF_INET, type, 0);
+ if (fd >= 0)
+ return fd;
+ fd = __socket (AF_INET6, type, 0);
+ if (fd >= 0)
+ return fd;
+ __set_errno (ENOENT);
return fd;
}
diff --git a/sysdeps/unix/sysv/linux/opensock.c b/sysdeps/unix/sysv/linux/opensock.c
deleted file mode 100644
index e87d6e58b0b84f82..0000000000000000
--- a/sysdeps/unix/sysv/linux/opensock.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Copyright (C) 1999-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 <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-
-/* Return a socket of any type. The socket can be used in subsequent
- ioctl calls to talk to the kernel. */
-int
-__opensock (void)
-{
- static int last_family; /* Available socket family we will use. */
- static int last_type;
- static const struct
- {
- int family;
- const char procname[15];
- } afs[] =
- {
- { AF_UNIX, "net/unix" },
- { AF_INET, "" },
- { AF_INET6, "net/if_inet6" },
- { AF_AX25, "net/ax25" },
- { AF_NETROM, "net/nr" },
- { AF_ROSE, "net/rose" },
- { AF_IPX, "net/ipx" },
- { AF_APPLETALK, "net/appletalk" },
- { AF_ECONET, "sys/net/econet" },
- { AF_ASH, "sys/net/ash" },
- { AF_X25, "net/x25" },
-#ifdef NEED_AF_IUCV
- { AF_IUCV, "net/iucv" }
-#endif
- };
-#define nafs (sizeof (afs) / sizeof (afs[0]))
- char fname[sizeof "/proc/" + 14];
- int result;
- int has_proc;
- size_t cnt;
-
- /* We already know which family to use from the last call. Use it
- again. */
- if (last_family != 0)
- {
- assert (last_type != 0);
-
- result = __socket (last_family, last_type | SOCK_CLOEXEC, 0);
- if (result != -1 || errno != EAFNOSUPPORT)
- /* Maybe the socket type isn't supported anymore (module is
- unloaded). In this case again try to find the type. */
- return result;
-
- /* Reset the values. They seem not valid anymore. */
- last_family = 0;
- last_type = 0;
- }
-
- /* Check whether the /proc filesystem is available. */
- has_proc = __access ("/proc/net", R_OK) != -1;
- strcpy (fname, "/proc/");
-
- /* Iterate over the interface families and find one which is
- available. */
- for (cnt = 0; cnt < nafs; ++cnt)
- {
- int type = SOCK_DGRAM;
-
- if (has_proc && afs[cnt].procname[0] != '\0')
- {
- strcpy (fname + 6, afs[cnt].procname);
- if (__access (fname, R_OK) == -1)
- /* The /proc entry is not available. I.e., we cannot
- create a socket of this type (without loading the
- module). Don't look for it since this might trigger
- loading the module. */
- continue;
- }
-
- if (afs[cnt].family == AF_NETROM || afs[cnt].family == AF_X25)
- type = SOCK_SEQPACKET;
-
- result = __socket (afs[cnt].family, type | SOCK_CLOEXEC, 0);
- if (result != -1)
- {
- /* Found an available family. */
- last_type = type;
- last_family = afs[cnt].family;
- return result;
- }
- }
-
- /* None of the protocol families is available. It is unclear what kind
- of error is returned. ENOENT seems like a reasonable choice. */
- __set_errno (ENOENT);
- return -1;
-}
diff --git a/sysdeps/unix/sysv/linux/s390/opensock.c b/sysdeps/unix/sysv/linux/s390/opensock.c
deleted file mode 100644
index f099d651ff04d211..0000000000000000
--- a/sysdeps/unix/sysv/linux/s390/opensock.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define NEED_AF_IUCV 1
-#include "../opensock.c"

View File

@ -0,0 +1,44 @@
commit d8302ba2da1e5ac59a1c4dc1c1207a10fdafdb08
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Mon Oct 18 01:39:02 2021 +0200
hurd if_index: Explicitly use AF_INET for if index discovery
5bf07e1b3a74 ("Linux: Simplify __opensock and fix race condition [BZ #28353]")
made __opensock try NETLINK then UNIX then INET. On the Hurd, only INET
knows about network interfaces, so better actually specify that in
if_index.
(cherry picked from commit 1d3decee997ba2fc24af81803299b2f4f3c47063)
diff --git a/sysdeps/mach/hurd/if_index.c b/sysdeps/mach/hurd/if_index.c
index 0eab510453c9e861..e785ac15aa6a1002 100644
--- a/sysdeps/mach/hurd/if_index.c
+++ b/sysdeps/mach/hurd/if_index.c
@@ -32,7 +32,7 @@ unsigned int
__if_nametoindex (const char *ifname)
{
struct ifreq ifr;
- int fd = __opensock ();
+ int fd = __socket (AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
return 0;
@@ -84,7 +84,7 @@ __if_nameindex (void)
error_t err = 0;
char data[2048];
file_t server;
- int fd = __opensock ();
+ int fd = __socket (AF_INET, SOCK_DGRAM, 0);
struct ifconf ifc;
unsigned int nifs, i;
struct if_nameindex *idx = NULL;
@@ -169,7 +169,7 @@ char *
__if_indextoname (unsigned int ifindex, char ifname[IF_NAMESIZE])
{
struct ifreq ifr;
- int fd = __opensock ();
+ int fd = __socket (AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
return NULL;

View File

@ -0,0 +1,35 @@
commit 6eaf10cbb78d22eae7999d9de55f6b93999e0860
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon Nov 22 14:41:14 2021 +0100
socket: Do not use AF_NETLINK in __opensock
It is not possible to use interface ioctls with netlink sockets
on all Linux kernels.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit 3d981795cd00cc9b73c3ee5087c308361acd62e5)
diff --git a/socket/opensock.c b/socket/opensock.c
index ff94d27a61bd3889..3e35821f91643456 100644
--- a/socket/opensock.c
+++ b/socket/opensock.c
@@ -24,17 +24,10 @@
int
__opensock (void)
{
- /* SOCK_DGRAM is supported by all address families. (Netlink does
- not support SOCK_STREAM.) */
+ /* SOCK_DGRAM is supported by all address families. */
int type = SOCK_DGRAM | SOCK_CLOEXEC;
int fd;
-#ifdef AF_NETLINK
- fd = __socket (AF_NETLINK, type, 0);
- if (fd >= 0)
- return fd;
-#endif
-
fd = __socket (AF_UNIX, type, 0);
if (fd >= 0)
return fd;

View File

@ -0,0 +1,32 @@
commit 7af07fe795f43e53d31be1c6f9adba7e05f87b0b
Author: Xi Ruoyao <xry111@mengyan1223.wang>
Date: Thu Aug 12 20:31:59 2021 +0000
mips: align stack in clone [BZ #28223]
The MIPS O32 ABI requires 4 byte aligned stack, and the MIPS N64 and N32
ABI require 8 byte aligned stack. Previously if the caller passed an
unaligned stack to clone the the child misbehaved.
Fixes bug 28223.
(cherry picked from commit 1f51cd9a860ee45eee8a56fb2ba925267a2a7bfe)
diff --git a/sysdeps/unix/sysv/linux/mips/clone.S b/sysdeps/unix/sysv/linux/mips/clone.S
index 71d9dba8bd9e8f9e..43a5ad3a400d9504 100644
--- a/sysdeps/unix/sysv/linux/mips/clone.S
+++ b/sysdeps/unix/sysv/linux/mips/clone.S
@@ -55,6 +55,13 @@ NESTED(__clone,4*SZREG,sp)
.set at
#endif
+ /* Align stack to 4/8 bytes per the ABI. */
+#if _MIPS_SIM == _ABIO32
+ li t0,-4
+#else
+ li t0,-8
+#endif
+ and a1,a1,t0
/* Sanity check arguments. */
li v0,EINVAL

View File

@ -0,0 +1,37 @@
commit 4db172a54d43f9b7fd17e66fc44a34efb3cab1e1
Author: Xi Ruoyao <xry111@mengyan1223.wang>
Date: Fri Aug 13 16:01:14 2021 +0000
mips: increase stack alignment in clone to match the ABI
In "mips: align stack in clone [BZ #28223]"
(commit 1f51cd9a860ee45eee8a56fb2ba925267a2a7bfe) I made a mistake: I
misbelieved one "word" was 2-byte and "doubleword" should be 4-byte.
But in MIPS ABI one "word" is defined 32-bit (4-byte), so "doubleword" is
8-byte [1], and "quadword" is 16-byte [2].
[1]: "System V Application Binary Interface: MIPS(R) RISC Processor
Supplement, 3rd edition", page 3-31
[2]: "MIPSpro(TM) 64-Bit Porting and Transition Guide", page 23
(cherry picked from commit 0f62fe053273ff6c62ac95c59b7687c964737b00)
diff --git a/sysdeps/unix/sysv/linux/mips/clone.S b/sysdeps/unix/sysv/linux/mips/clone.S
index 43a5ad3a400d9504..fd71b5ca2eb86089 100644
--- a/sysdeps/unix/sysv/linux/mips/clone.S
+++ b/sysdeps/unix/sysv/linux/mips/clone.S
@@ -55,11 +55,11 @@ NESTED(__clone,4*SZREG,sp)
.set at
#endif
- /* Align stack to 4/8 bytes per the ABI. */
+ /* Align stack to 8/16 bytes per the ABI. */
#if _MIPS_SIM == _ABIO32
- li t0,-4
-#else
li t0,-8
+#else
+ li t0,-16
#endif
and a1,a1,t0

View File

@ -0,0 +1,65 @@
commit 93aabf891e96e93f100081ee07989c23d7107d17
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Dec 17 11:48:41 2021 +0100
arm: Guard ucontext _rtld_global_ro access by SHARED, not PIC macro
Due to PIE-by-default, PIC is now defined in more cases. libc.a
does not have _rtld_global_ro, and statically linking setcontext
fails. SHARED is the right condition to use, so that libc.a
references _dl_hwcap instead of _rtld_global_ro.
For static PIE support, the !SHARED case would still have to be made
PIC. This patch does not achieve that.
Fixes commit 23645707f12f2dd9d80b51effb2d9618a7b65565
("Replace --enable-static-pie with --disable-default-pie").
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
(cherry picked from commit ce1e5b11229f19820b86f8b19d651f16009552b0)
diff --git a/sysdeps/unix/sysv/linux/arm/getcontext.S b/sysdeps/unix/sysv/linux/arm/getcontext.S
index 3aa581c4da6d1166..11bfcbe5f53afc6e 100644
--- a/sysdeps/unix/sysv/linux/arm/getcontext.S
+++ b/sysdeps/unix/sysv/linux/arm/getcontext.S
@@ -50,7 +50,7 @@ ENTRY(__getcontext)
/* Store FP regs. Much of the FP code is copied from arm/setjmp.S. */
-#ifdef PIC
+#ifdef SHARED
ldr r2, 1f
ldr r1, .Lrtld_global_ro
0: add r2, pc, r2
@@ -102,7 +102,7 @@ ENTRY(__getcontext)
END(__getcontext)
-#ifdef PIC
+#ifdef SHARED
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS
.Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
diff --git a/sysdeps/unix/sysv/linux/arm/setcontext.S b/sysdeps/unix/sysv/linux/arm/setcontext.S
index 8be8beefea13883e..4c7c6e550944138c 100644
--- a/sysdeps/unix/sysv/linux/arm/setcontext.S
+++ b/sysdeps/unix/sysv/linux/arm/setcontext.S
@@ -32,7 +32,7 @@ ENTRY(__setcontext)
add r0, r0, #UCONTEXT_REGSPACE
/* Restore the VFP registers. Copied from arm/__longjmp.S. */
-#ifdef PIC
+#ifdef SHARED
ldr r2, 1f
ldr r1, .Lrtld_global_ro
0: add r2, pc, r2
@@ -101,7 +101,7 @@ ENTRY(__startcontext)
.fnend
END(__startcontext)
-#ifdef PIC
+#ifdef SHARED
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS
.Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)

View File

@ -0,0 +1,74 @@
commit dc9b69d5331dcdca4547c0490cb9fefbd89e40f6
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Dec 17 12:01:20 2021 +0100
nss: Use "files dns" as the default for the hosts database (bug 28700)
This matches what is currently in nss/nsswitch.conf. The new ordering
matches what most distributions use in their installed configuration
files.
It is common to add localhost to /etc/hosts because the name does not
exist in the DNS, but is commonly used as a host name.
With the built-in "dns [!UNAVAIL=return] files" default, dns is
searched first and provides an answer for "localhost" (NXDOMAIN).
We never look at the files database as a result, so the contents of
/etc/hosts is ignored. This means that "getent hosts localhost"
fail without a /etc/nsswitch.conf file, even though the host name
is listed in /etc/hosts.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit b99b0f93ee8762fe53ff65802deb6f00700b9924)
diff --git a/manual/nss.texi b/manual/nss.texi
index 3aaa7786f8cf3168..524d22ad1e7f8ca0 100644
--- a/manual/nss.texi
+++ b/manual/nss.texi
@@ -324,9 +324,8 @@ missing.
@cindex default value, and NSS
For the @code{hosts} and @code{networks} databases the default value is
-@code{dns [!UNAVAIL=return] files}. I.e., the system is prepared for
-the DNS service not to be available but if it is available the answer it
-returns is definitive.
+@code{files dns}. I.e., local configuration will override the contents
+of the domain name system (DNS).
The @code{passwd}, @code{group}, and @code{shadow} databases was
traditionally handled in a special way. The appropriate files in the
diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c
index f1c97f7c8e9d7378..dbc87868dd408d9f 100644
--- a/nss/XXX-lookup.c
+++ b/nss/XXX-lookup.c
@@ -29,7 +29,7 @@
|* ALTERNATE_NAME - name of another service which is examined in *|
|* case DATABASE_NAME is not found *|
|* *|
-|* DEFAULT_CONFIG - string for default conf (e.g. "dns files") *|
+|* DEFAULT_CONFIG - string for default conf (e.g. "files dns") *|
|* *|
\*******************************************************************/
diff --git a/nss/nss_database.c b/nss/nss_database.c
index ab121cb371c087e9..54561f03287db2e4 100644
--- a/nss/nss_database.c
+++ b/nss/nss_database.c
@@ -80,7 +80,7 @@ enum nss_database_default
{
nss_database_default_defconfig = 0, /* "nis [NOTFOUND=return] files". */
nss_database_default_compat, /* "compat [NOTFOUND=return] files". */
- nss_database_default_dns, /* "dns [!UNAVAIL=return] files". */
+ nss_database_default_dns, /* "files dns". */
nss_database_default_files, /* "files". */
nss_database_default_nis, /* "nis". */
nss_database_default_nis_nisplus, /* "nis nisplus". */
@@ -133,7 +133,7 @@ nss_database_select_default (struct nss_database_default_cache *cache,
#endif
case nss_database_default_dns:
- line = "dns [!UNAVAIL=return] files";
+ line = "files dns";
break;
case nss_database_default_files:

View File

@ -0,0 +1,35 @@
commit 03de6917bd11c0591867607ce74ef658f76eabb9
Author: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed Dec 15 23:46:19 2021 +0100
elf: Fix tst-cpu-features-cpuinfo for KVM guests on some AMD systems [BZ #28704]
On KVM guests running on some AMD systems, the IBRS feature is reported
as a synthetic feature using the Intel feature, while the cpuinfo entry
keeps the same. Handle that by first checking the presence of the Intel
feature on AMD systems.
Fixes bug 28704.
(cherry picked from commit 94058f6cde8b887178885954740ac6c866d25eab)
diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo.c b/sysdeps/x86/tst-cpu-features-cpuinfo.c
index 2d4927f5e52dc260..830aaca2ecae971b 100644
--- a/sysdeps/x86/tst-cpu-features-cpuinfo.c
+++ b/sysdeps/x86/tst-cpu-features-cpuinfo.c
@@ -169,7 +169,14 @@ do_test (int argc, char **argv)
else if (cpu_features->basic.kind == arch_kind_amd)
{
fails += CHECK_PROC (ibpb, AMD_IBPB);
- fails += CHECK_PROC (ibrs, AMD_IBRS);
+
+ /* The IBRS feature on AMD processors is reported using the Intel feature
+ * on KVM guests (synthetic bit). In both cases the cpuinfo entry is the
+ * same. */
+ if (HAS_CPU_FEATURE (IBRS_IBPB))
+ fails += CHECK_PROC (ibrs, IBRS_IBPB);
+ else
+ fails += CHECK_PROC (ibrs, AMD_IBRS);
fails += CHECK_PROC (stibp, AMD_STIBP);
}
fails += CHECK_PROC (ibt, IBT);

View File

@ -0,0 +1,35 @@
commit 5daf13b1e637eec0f7a2de05b177cb0d76479aa2
Author: Matheus Castanho <msc@linux.ibm.com>
Date: Wed Dec 1 11:14:40 2021 -0300
powerpc64[le]: Allocate extra stack frame on syscall.S
The syscall function does not allocate the extra stack frame for scv like other
assembly syscalls using DO_CALL_SCV. So after commit d120fb9941 changed the
offset that is used to save LR, syscall ended up using an invalid offset,
causing regressions on powerpc64. So make sure the extra stack frame is
allocated in syscall.S as well to make it consistent with other uses of
DO_CALL_SCV and avoid similar issues in the future.
Tested on powerpc, powerpc64, and powerpc64le (with and without scv)
Reviewed-by: Raphael M Zinsly <rzinsly@linux.ibm.com>
(cherry picked from commit ae91d3df24a4a1b1f264d101a71a298bff310d14)
diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S
index a29652feaf6764cf..a5497c8370982fe3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/syscall.S
+++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S
@@ -27,7 +27,11 @@ ENTRY (syscall)
mr r8,r9
#if defined(USE_PPC_SCV) && !IS_IN(rtld) && (defined(__PPC64__) || defined(__powerpc64__))
CHECK_SCV_SUPPORT r9 0f
+ stdu r1,-SCV_FRAME_SIZE(r1)
+ cfi_adjust_cfa_offset(SCV_FRAME_SIZE)
DO_CALL_SCV
+ addi r1,r1,SCV_FRAME_SIZE
+ cfi_adjust_cfa_offset(-SCV_FRAME_SIZE)
RET_SCV
b 1f
#endif

View File

@ -0,0 +1,32 @@
commit 9de8011c328021f10588a8acb418daf5121d5f3d
Author: Aurelien Jarno <aurelien@aurel32.net>
Date: Tue Dec 14 22:44:35 2021 +0100
riscv: align stack in clone [BZ #28702]
The RISC-V ABI [1] mandates that "the stack pointer shall be aligned to
a 128-bit boundary upon procedure entry". This as not the case in clone.
This fixes the misc/tst-misalign-clone-internal and
misc/tst-misalign-clone tests.
Fixes bug 28702.
[1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc
(cherry picked from commit d2e594d71509faf36cf851a69370db34a4f5fa65)
diff --git a/sysdeps/unix/sysv/linux/riscv/clone.S b/sysdeps/unix/sysv/linux/riscv/clone.S
index 12f91a20d3bb34f5..161e83c7e3786b8d 100644
--- a/sysdeps/unix/sysv/linux/riscv/clone.S
+++ b/sysdeps/unix/sysv/linux/riscv/clone.S
@@ -32,6 +32,9 @@
.text
LEAF (__clone)
+ /* Align stack to a 128-bit boundary as per RISC-V ABI. */
+ andi a1,a1,ALMASK
+
/* Sanity check arguments. */
beqz a0,L (invalid) /* No NULL function pointers. */
beqz a1,L (invalid) /* No NULL stack pointers. */

View File

@ -0,0 +1,34 @@
commit aa3a97496c82a8443039248ebee650322c9480f4
Author: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu Dec 16 00:06:28 2021 +0100
riscv: align stack before calling _dl_init [BZ #28703]
Align the stack pointer to 128 bits during the call to _dl_init() as
specified by the RISC-V ABI [1]. This fixes the elf/tst-align2 test.
Fixes bug 28703.
[1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc
(cherry picked from commit 225da459cebef1037dcd78b56471edc0721e1c41)
diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
index aedf69fcdd8aff50..951268923da26a37 100644
--- a/sysdeps/riscv/dl-machine.h
+++ b/sysdeps/riscv/dl-machine.h
@@ -127,8 +127,14 @@ elf_machine_load_address (void)
sll a3, a1, " STRINGXP (PTRLOG) "\n\
add a3, a3, a2\n\
add a3, a3, " STRINGXP (SZREG) "\n\
+ # Stash the stack pointer in s1.\n\
+ mv s1, sp\n\
+ # Align stack to 128 bits for the _dl_init call.\n\
+ andi sp, sp,-16\n\
# Call the function to run the initializers.\n\
jal _dl_init\n\
+ # Restore the stack pointer for _start.\n\
+ mv sp, s1\n\
# Pass our finalizer function to _start.\n\
lla a0, _dl_fini\n\
# Jump to the user entry point.\n\

View File

@ -0,0 +1,21 @@
commit 4029747c592cb2d59805b3a4e7a8963fcdcdbeb1
Author: John David Anglin <danglin@gcc.gnu.org>
Date: Mon Sep 6 17:37:29 2021 +0000
Update hppa libm-test-ulps
(cherry picked from commit d8cf84ac7e504663dfeb2bb45d8d48ae81effe05)
diff --git a/sysdeps/hppa/fpu/libm-test-ulps b/sysdeps/hppa/fpu/libm-test-ulps
index 90e16a72692e9199..3d60fc25a14d053f 100644
--- a/sysdeps/hppa/fpu/libm-test-ulps
+++ b/sysdeps/hppa/fpu/libm-test-ulps
@@ -1104,7 +1104,7 @@ float: 8
ldouble: 1
Function: "tgamma_downward":
-double: 8
+double: 9
float: 7
Function: "tgamma_towardzero":

View File

@ -0,0 +1,21 @@
commit e94544c82f4ac37017589d8d83156d72388fc4af
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed Aug 4 21:40:32 2021 +0300
Update sparc libm-test-ulps
(cherry picked from commit c52eb066bc634a79e4194457362384abe5b43b3a)
diff --git a/sysdeps/sparc/fpu/libm-test-ulps b/sysdeps/sparc/fpu/libm-test-ulps
index c2e4649524aa3a44..f34bbe6c592814d0 100644
--- a/sysdeps/sparc/fpu/libm-test-ulps
+++ b/sysdeps/sparc/fpu/libm-test-ulps
@@ -1346,7 +1346,7 @@ float: 8
ldouble: 4
Function: "tgamma_downward":
-double: 8
+double: 9
float: 7
ldouble: 5

View File

@ -0,0 +1,81 @@
commit 1d9764aba8c00754fbf8299e48afbe222245ee3e
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed Aug 4 21:34:12 2021 +0300
linux: Add sparck brk implementation
It turned that the generic implementation of brk() does not work
for sparc, since on failure kernel will just return the previous
input value without setting the conditional register.
This patches adds back a sparc32 and sparc64 implementation removed
by 720480934ab9107.
Checked on sparc64-linux-gnu and sparcv9-linux-gnu.
(cherry picked from commit 5b86241a032c50462988bdd1439e078384690d34)
diff --git a/sysdeps/unix/sysv/linux/sparc/brk.c b/sysdeps/unix/sysv/linux/sparc/brk.c
new file mode 100644
index 0000000000000000..aafe9673e3062cf8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/brk.c
@@ -0,0 +1,58 @@
+/* Change data segment. Linux SPARC version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sysdep.h>
+
+/* This must be initialized data because commons can't have aliases. */
+void *__curbrk = 0;
+
+#if HAVE_INTERNAL_BRK_ADDR_SYMBOL
+/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
+ to work around different old braindamage in the old Linux ELF dynamic
+ linker. */
+weak_alias (__curbrk, ___brk_addr)
+#endif
+
+#ifdef __arch64__
+# define SYSCALL_NUM "0x6d"
+#else
+# define SYSCALL_NUM "0x10"
+#endif
+
+int
+__brk (void *addr)
+{
+ register long int g1 asm ("g1") = __NR_brk;
+ register long int o0 asm ("o0") = (long int) addr;
+ asm volatile ("ta " SYSCALL_NUM
+ : "=r"(o0)
+ : "r"(g1), "0"(o0)
+ : "cc");
+ __curbrk = (void *) o0;
+
+ if (__curbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias (__brk, brk)

View File

@ -0,0 +1,33 @@
commit 8ad6d6d8ed33631bd2ca5d1112e6da2f92731432
Author: maminjie <maminjie2@huawei.com>
Date: Mon Dec 20 19:36:32 2021 +0800
Linux: Fix 32-bit vDSO for clock_gettime on powerpc32
When the clock_id is CLOCK_PROCESS_CPUTIME_ID or CLOCK_THREAD_CPUTIME_ID,
on the 5.10 kernel powerpc 32-bit, the 32-bit vDSO is executed successfully (
because the __kernel_clock_gettime in arch/powerpc/kernel/vdso32/gettimeofday.S
does not support these two IDs, the 32-bit time_t syscall will be used),
but tp32.tv_sec is equal to 0, causing the 64-bit time_t syscall to continue to be used,
resulting in two system calls.
Fix commit 72e84d1db22203e01a43268de71ea8669eca2863.
Signed-off-by: maminjie <maminjie2@huawei.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit e0fc721ce600038dd390e77cfe52440707ef574d)
diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index 91df6b3d967bf945..9c7d9073254843c7 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -53,7 +53,7 @@ __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
{
struct timespec tp32;
r = INTERNAL_VSYSCALL_CALL (vdso_time, 2, clock_id, &tp32);
- if (r == 0 && tp32.tv_sec > 0)
+ if (r == 0 && tp32.tv_sec >= 0)
{
*tp = valid_timespec_to_timespec64 (tp32);
return 0;

View File

@ -0,0 +1,37 @@
commit 41fddc064ded5c9a36d8ffaad59a85407a22a535
Author: Andrea Monaco <andrea.monaco@autistici.org>
Date: Sun Dec 12 10:24:28 2021 +0100
intl/plural.y: Avoid conflicting declarations of yyerror and yylex
bison-3.8 includes these lines in the generated intl/plural.c:
#if !defined __gettexterror && !defined YYERROR_IS_DECLARED
void __gettexterror (struct parse_args *arg, const char *msg);
#endif
#if !defined __gettextlex && !defined YYLEX_IS_DECLARED
int __gettextlex (YYSTYPE *yylvalp, struct parse_args *arg);
#endif
Those default prototypes provided by bison conflict with the
declarations later on in plural.y. This patch solves the issue.
Reviewed-by: Arjun Shankar <arjun@redhat.com>
(cherry picked from commit c6d7d6312c21bbcfb236d48bb7c11cedb234389f)
diff --git a/intl/plural.y b/intl/plural.y
index e02e74541c4574eb..2ee128ba01b5820d 100644
--- a/intl/plural.y
+++ b/intl/plural.y
@@ -40,6 +40,11 @@
# define __gettextparse PLURAL_PARSE
#endif
+/* Later we provide those prototypes. Without these macros, bison may
+ generate its own prototypes with possible conflicts. */
+#define YYLEX_IS_DECLARED
+#define YYERROR_IS_DECLARED
+
%}
%parse-param {struct parse_args *arg}
%lex-param {struct parse_args *arg}

View File

@ -0,0 +1,50 @@
commit 217b84127b3a6590afcc7e198e6c3f665935e8f4
Author: Wilco Dijkstra <wdijkstr@arm.com>
Date: Thu Jan 6 14:36:28 2022 +0000
AArch64: Check for SVE in ifuncs [BZ #28744]
Add a check for SVE in the A64FX ifuncs for memcpy, memset and memmove.
This fixes BZ #28744.
(cherry picked from commit e5fa62b8db546f8792ec9e5c61e6419f4f8e3f4d)
diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
index 25e0081eeb51727c..b6703af44b3f1a3d 100644
--- a/sysdeps/aarch64/multiarch/memcpy.c
+++ b/sysdeps/aarch64/multiarch/memcpy.c
@@ -48,7 +48,7 @@ libc_ifunc (__libc_memcpy,
|| IS_NEOVERSE_V1 (midr)
? __memcpy_simd
# if HAVE_AARCH64_SVE_ASM
- : (IS_A64FX (midr)
+ : (IS_A64FX (midr) && sve
? __memcpy_a64fx
: __memcpy_generic))))));
# else
diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
index d0adefc547f60030..d2339ff34ff7b3e5 100644
--- a/sysdeps/aarch64/multiarch/memmove.c
+++ b/sysdeps/aarch64/multiarch/memmove.c
@@ -48,7 +48,7 @@ libc_ifunc (__libc_memmove,
|| IS_NEOVERSE_V1 (midr)
? __memmove_simd
# if HAVE_AARCH64_SVE_ASM
- : (IS_A64FX (midr)
+ : (IS_A64FX (midr) && sve
? __memmove_a64fx
: __memmove_generic))))));
# else
diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c
index d7d9bbbda095e051..3d839bc02e96380d 100644
--- a/sysdeps/aarch64/multiarch/memset.c
+++ b/sysdeps/aarch64/multiarch/memset.c
@@ -44,7 +44,7 @@ libc_ifunc (__libc_memset,
: (IS_EMAG (midr) && zva_size == 64
? __memset_emag
# if HAVE_AARCH64_SVE_ASM
- : (IS_A64FX (midr)
+ : (IS_A64FX (midr) && sve
? __memset_a64fx
: __memset_generic))));
# else

View File

@ -0,0 +1,27 @@
commit 515a6f53cd984d5e6e374fbee52772f967fc3c73
Author: Paul Eggert <eggert@cs.ucla.edu>
Date: Mon Sep 13 22:49:45 2021 -0700
Fix subscript error with odd TZif file [BZ #28338]
* time/tzfile.c (__tzfile_compute): Fix unlikely off-by-one bug
that accessed before start of an array when an oddball-but-valid
TZif file was queried with an unusual time_t value.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit 645277434a42efc547d2cac8bfede4da10b4049f)
diff --git a/time/tzfile.c b/time/tzfile.c
index 4377018a55936389..190a777152b31cee 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -765,8 +765,7 @@ __tzfile_compute (__time64_t timer, int use_localtime,
*leap_correct = leaps[i].change;
if (timer == leaps[i].transition /* Exactly at the transition time. */
- && ((i == 0 && leaps[i].change > 0)
- || leaps[i].change > leaps[i - 1].change))
+ && (leaps[i].change > (i == 0 ? 0 : leaps[i - 1].change)))
{
*leap_hit = 1;
while (i > 0

View File

@ -0,0 +1,52 @@
commit 85b24f9694e21f1d2f2d8b80d3bf690687723347
Author: Hans-Peter Nilsson <hp@axis.com>
Date: Fri Dec 17 21:38:00 2021 +0100
timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707)
When using a timezone file with a truncated starting time,
generated by the zic in IANA tzcode-2021d a.k.a. tzlib-2021d
(also in tzlib-2021e; current as of this writing), glibc
asserts in __tzfile_read (on e.g. tzset() for this file) and
you may find lines matching "tzfile.c:435: __tzfile_read:
Assertion `num_types == 1' failed" in your syslog.
One example of such a file is the tzfile for Asuncion
generated by tzlib-2021e as follows, using the tzlib-2021e zic:
"zic -d DEST -r @1546300800 -L /dev/null -b slim
SOURCE/southamerica". Note that in its type 2 header, it has
two entries in its "time-types" array (types), but only one
entry in its "transition types" array (type_idxs).
This is valid and expected already in the published RFC8536, and
not even frowned upon: "Local time for timestamps before the
first transition is specified by the first time type (time type
0)" ... "every nonzero local time type index SHOULD appear at
least once in the transition type array". Note the "nonzero ...
index". Until the 2021d zic, index 0 has been shared by the
first valid transition but with 2021d it's separate, set apart
as a placeholder and only "implicitly" indexed. (A draft update
of the RFC mandates that the entry at index 0 is a placeholder
in this case, hence can no longer be shared.)
* time/tzfile.c (__tzfile_read): Don't assert when no transitions
are found.
Co-authored-by: Christopher Wong <Christopher.Wong@axis.com>
(cherry picked from commit c36f64aa6dff13b12a1e03a185e75a50fa9f6a4c)
diff --git a/time/tzfile.c b/time/tzfile.c
index 190a777152b31cee..8668392ad387af05 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -431,8 +431,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
if (__tzname[0] == NULL)
{
/* This should only happen if there are no transition rules.
- In this case there should be only one single type. */
- assert (num_types == 1);
+ In this case there's usually only one single type, unless
+ e.g. the data file has a truncated time-range. */
__tzname[0] = __tzstring (zone_names);
}
if (__tzname[1] == NULL)

View File

@ -0,0 +1,130 @@
commit d5ba02f67dd62a63e29c29eebd6c543722aa6b5b
Author: Hans-Peter Nilsson <hp@axis.com>
Date: Fri Dec 17 21:45:54 2021 +0100
timezone: test-case for BZ #28707
This test-case is the tzfile for Asuncion generated by
tzlib-2021e as follows, using the tzlib-2021e zic: "zic -d
DEST -r @1546300800 -L /dev/null -b slim
SOURCE/southamerica". Note that in its type 2 header, it
has two entries in its "time-types" array (types), but only
one entry in its "transition types" array (type_idxs).
* timezone/Makefile, timezone/tst-pr28707.c,
timezone/testdata/gen-XT5.sh: New test.
Co-authored-by: Christopher Wong <Christopher.Wong@axis.com>
(cherry picked from commit ebe899af0dc3215159a9c896ac6f35b72a18cb6e)
diff --git a/timezone/Makefile b/timezone/Makefile
index c624a189b322cb5f..f091663b8bbbceda 100644
--- a/timezone/Makefile
+++ b/timezone/Makefile
@@ -23,7 +23,7 @@ subdir := timezone
include ../Makeconfig
others := zdump zic
-tests := test-tz tst-timezone tst-tzset
+tests := test-tz tst-timezone tst-tzset tst-bz28707
generated-dirs += testdata
@@ -85,10 +85,12 @@ $(objpfx)tst-timezone.out: $(addprefix $(testdata)/, \
America/Sao_Paulo Asia/Tokyo \
Europe/London)
$(objpfx)tst-tzset.out: $(addprefix $(testdata)/XT, 1 2 3 4)
+$(objpfx)tst-bz28707.out: $(testdata)/XT5
test-tz-ENV = TZDIR=$(testdata)
tst-timezone-ENV = TZDIR=$(testdata)
tst-tzset-ENV = TZDIR=$(testdata)
+tst-bz28707-ENV = TZDIR=$(testdata)
# Note this must come second in the deps list for $(built-program-cmd) to work.
zic-deps = $(objpfx)zic $(leapseconds) yearistype
@@ -122,6 +124,10 @@ $(testdata)/XT%: testdata/XT%
$(make-target-directory)
cp $< $@
+$(testdata)/XT%: testdata/gen-XT%.sh
+ $(SHELL) $< > $@.tmp
+ mv $@.tmp $@
+
$(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
sed -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
-e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
diff --git a/timezone/testdata/gen-XT5.sh b/timezone/testdata/gen-XT5.sh
new file mode 100755
index 0000000000000000..3cea0569eb5a6a57
--- /dev/null
+++ b/timezone/testdata/gen-XT5.sh
@@ -0,0 +1,16 @@
+#! /bin/sh
+
+# This test-case is the tzfile for America/Asuncion
+# generated by tzlib-2021e as follows, using the tzlib-2021e
+# zic: "zic -d DEST -r @1546300800 -L /dev/null -b slim
+# SOURCE/southamerica". Note that in its type 2 header, it
+# has two entries in its "time-types" array (types), but
+# only one entry in its "transition types" array
+# (type_idxs).
+
+printf \
+'TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'\
+'\0\0\0\0\0\0\0\1\0\0\0\1\0\0\0\0\0\0\0TZif2\0\0\0\0\0\0\0\0'\
+'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\2\0\0\0\b\0'\
+'\0\0\0\*\255\200\1\0\0\0\0\0\0\377\377\325\320\1\4-00\0-03\0\n'\
+'<-04>4<-03>,M10.1.0/0,M3.4.0/0\n'
diff --git a/timezone/tst-bz28707.c b/timezone/tst-bz28707.c
new file mode 100644
index 0000000000000000..0a9df1e9a094f1e9
--- /dev/null
+++ b/timezone/tst-bz28707.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Test that we can use a truncated timezone-file, where the time-type
+ at index 0 is not indexed by the transition-types array (and the
+ transition-types array does not contain at least both one DST and one
+ normal time members). */
+
+static int
+do_test (void)
+{
+ if (setenv ("TZ", "XT5", 1))
+ {
+ puts ("setenv failed.");
+ return 1;
+ }
+
+ tzset ();
+
+ return
+ /* Sanity-check that we got the right timezone-name for DST. For
+ normal time, we're likely to get "-00" (the "unspecified" marker),
+ even though the POSIX timezone string says "-04". Let's not test
+ that. */
+ !(strcmp (tzname[1], "-03") == 0);
+}
+#include <support/test-driver.c>

View File

@ -0,0 +1,39 @@
commit e64235ff4266e87b20505101877fe57350ab69ab
Author: Paul A. Clarke <pc@us.ibm.com>
Date: Tue Sep 14 13:13:33 2021 -0500
powerpc: Fix unrecognized instruction errors with recent GCC
Recent binutils commit b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a
changes the behavior of `.machine` directives to override, rather
than augment, the base CPU. This can result in _reduced_ functionality
when, for example, compiling for default machine "power8", but explicitly
asking for ".machine power5", which loses Altivec instructions.
In tst-ucontext-ppc64-vscr.c, while the instructions provoking the new
error messages are bracketed by ".machine power5", which is ostensibly
Power ISA 2.03 (POWER5), the POWER5 processor did not support the
VSX subset, so these instructions are not recognized as "power5".
Error: unrecognized opcode: `vspltisb'
Error: unrecognized opcode: `vpkuwus'
Error: unrecognized opcode: `mfvscr'
Error: unrecognized opcode: `stvx'
Manually adding the VSX subset via ".machine altivec" is sufficient.
Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
(cherry picked from commit 064b475a2e5662b6b3973fabf505eade86e61510)
diff --git a/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c b/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c
index 28c87fcef72bded6..d3fc4ab589f4752a 100644
--- a/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c
+++ b/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c
@@ -50,6 +50,7 @@ do_test (void)
/* Set SAT bit in VSCR register. */
asm volatile (".machine push;\n"
".machine \"power5\";\n"
+ ".machine altivec;\n"
"vspltisb %0,0;\n"
"vspltisb %1,-1;\n"
"vpkuwus %0,%0,%1;\n"

View File

@ -0,0 +1,377 @@
commit 73558ffe841cf4c60ccb4c71cf6dcebf84f2b736
Author: Joseph Myers <joseph@codesourcery.com>
Date: Wed Nov 10 15:21:19 2021 +0000
Update syscall lists for Linux 5.15
Linux 5.15 has one new syscall, process_mrelease (and also enables the
clone3 syscall for RV32). It also has a macro __NR_SYSCALL_MASK for
Arm, which is not a syscall but matches the pattern used for syscall
macro names.
Add __NR_SYSCALL_MASK to the names filtered out in the code dealing
with syscall lists, update syscall-names.list for the new syscall and
regenerate the arch-syscall.h headers with build-many-glibcs.py
update-syscalls.
Tested with build-many-glibcs.py.
(cherry picked from commit 3387c40a8bbad5faf85b1feb56429cb20feaa640)
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
index bedab1abbac7f6c1..74a809561a45edc4 100644
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
@@ -180,6 +180,7 @@
#define __NR_preadv2 286
#define __NR_prlimit64 261
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 270
#define __NR_process_vm_writev 271
#define __NR_pselect6 72
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
index 91354ed9e29b8d15..6fc0a23504c3b53d 100644
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
@@ -328,6 +328,7 @@
#define __NR_preadv2 520
#define __NR_prlimit64 496
#define __NR_process_madvise 550
+#define __NR_process_mrelease 558
#define __NR_process_vm_readv 504
#define __NR_process_vm_writev 505
#define __NR_pselect6 463
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
index ff5c7eb36db89494..0c66762bf868a992 100644
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
@@ -182,6 +182,7 @@
#define __NR_preadv2 286
#define __NR_prlimit64 261
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 270
#define __NR_process_vm_writev 271
#define __NR_pselect6_time64 413
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
index 5772333ceef6ce59..c41a864c6d530eb0 100644
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
@@ -235,6 +235,7 @@
#define __NR_preadv2 392
#define __NR_prlimit64 369
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 376
#define __NR_process_vm_writev 377
#define __NR_pselect6 335
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
index 4af6d6202f6df7ae..863ffa3e0cd34d3e 100644
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
@@ -190,6 +190,7 @@
#define __NR_preadv2 286
#define __NR_prlimit64 261
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 270
#define __NR_process_vm_writev 271
#define __NR_pselect6 72
diff --git a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
index dddfd517471e5cc9..85b017918ef20736 100644
--- a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
+++ b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
@@ -22,7 +22,7 @@
}
# Skip pseudo-system calls which describe ranges.
-/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) / {
+/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE|SYSCALL_MASK) / {
next;
}
/^#define __NR_(|64_|[NO]32_)Linux(_syscalls)? / {
diff --git a/sysdeps/unix/sysv/linux/glibcsyscalls.py b/sysdeps/unix/sysv/linux/glibcsyscalls.py
index 621a202ed75cd725..fe7896eebe74cdf4 100644
--- a/sysdeps/unix/sysv/linux/glibcsyscalls.py
+++ b/sysdeps/unix/sysv/linux/glibcsyscalls.py
@@ -41,7 +41,7 @@ RE_PSEUDO_SYSCALL = re.compile(r"""__NR_(
(unused|reserved)[0-9]+
# Pseudo-system call which describes a range.
- |(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE)
+ |(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE|SYSCALL_MASK)
|(|64_|[NO]32_)Linux(_syscalls)?
)""", re.X)
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
index b07fc8549de34157..6cf27cd17c1ad0c0 100644
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
@@ -222,6 +222,7 @@
#define __NR_preadv2 347
#define __NR_prlimit64 321
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 330
#define __NR_process_vm_writev 331
#define __NR_pselect6 273
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
index 6e4264698b5ce480..2512508b7daa8ed2 100644
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
@@ -254,6 +254,7 @@
#define __NR_preadv2 378
#define __NR_prlimit64 340
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 347
#define __NR_process_vm_writev 348
#define __NR_prof 44
diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
index 1ca706d7216a3902..4a0c737369217367 100644
--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
@@ -209,6 +209,7 @@
#define __NR_preadv2 1348
#define __NR_prlimit64 1325
#define __NR_process_madvise 1464
+#define __NR_process_mrelease 1472
#define __NR_process_vm_readv 1332
#define __NR_process_vm_writev 1333
#define __NR_pselect6 1294
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
index 2f10f71f90d225ff..e310eb5075fb22d8 100644
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
@@ -243,6 +243,7 @@
#define __NR_preadv2 377
#define __NR_prlimit64 339
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 345
#define __NR_process_vm_writev 346
#define __NR_pselect6 301
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
index 0607a4dfa6adaa23..b4ecad010c2a6abf 100644
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
@@ -253,6 +253,7 @@
#define __NR_preadv2 393
#define __NR_prlimit64 370
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 377
#define __NR_process_vm_writev 378
#define __NR_prof 44
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
index 0055eec0b169ba96..7e3d138ba969c57b 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
@@ -238,6 +238,7 @@
#define __NR_preadv2 4361
#define __NR_prlimit64 4338
#define __NR_process_madvise 4440
+#define __NR_process_mrelease 4448
#define __NR_process_vm_readv 4345
#define __NR_process_vm_writev 4346
#define __NR_prof 4044
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 8e8e9f91ccfebfab..7e9e232e5256bc89 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
@@ -221,6 +221,7 @@
#define __NR_preadv2 6325
#define __NR_prlimit64 6302
#define __NR_process_madvise 6440
+#define __NR_process_mrelease 6448
#define __NR_process_vm_readv 6309
#define __NR_process_vm_writev 6310
#define __NR_pselect6 6264
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 ebd1545f806564bb..f9e7ef72b0aa1749 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
@@ -209,6 +209,7 @@
#define __NR_preadv2 5321
#define __NR_prlimit64 5297
#define __NR_process_madvise 5440
+#define __NR_process_mrelease 5448
#define __NR_process_vm_readv 5304
#define __NR_process_vm_writev 5305
#define __NR_pselect6 5260
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
index 2b530b1f88e4c52a..afd73fc1daca1fb4 100644
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
@@ -189,6 +189,7 @@
#define __NR_preadv2 286
#define __NR_prlimit64 261
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 270
#define __NR_process_vm_writev 271
#define __NR_pselect6 72
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
index a32984a9c17315ee..0ac2992028eda27e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
@@ -247,6 +247,7 @@
#define __NR_preadv2 380
#define __NR_prlimit64 325
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 351
#define __NR_process_vm_writev 352
#define __NR_prof 44
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
index b01e464fb906d632..c890bc644e14fe06 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
@@ -231,6 +231,7 @@
#define __NR_preadv2 380
#define __NR_prlimit64 325
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 351
#define __NR_process_vm_writev 352
#define __NR_prof 44
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
index 24d0a2c455caa630..cd336d755a42598a 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
@@ -16,6 +16,7 @@
#define __NR_clock_nanosleep_time64 407
#define __NR_clock_settime64 404
#define __NR_clone 220
+#define __NR_clone3 435
#define __NR_close 57
#define __NR_close_range 436
#define __NR_connect 203
@@ -171,6 +172,7 @@
#define __NR_preadv2 286
#define __NR_prlimit64 261
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 270
#define __NR_process_vm_writev 271
#define __NR_pselect6_time64 413
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
index e526c89ae7b285cc..8edd21620bb4ef64 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
@@ -179,6 +179,7 @@
#define __NR_preadv2 286
#define __NR_prlimit64 261
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 270
#define __NR_process_vm_writev 271
#define __NR_pselect6 72
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 d4c7b101b64c010f..1a4873f505765617 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
@@ -240,6 +240,7 @@
#define __NR_preadv2 376
#define __NR_prlimit64 334
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 340
#define __NR_process_vm_writev 341
#define __NR_pselect6 301
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 bd8c78d7059a0f31..2af4607c1d36d173 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
@@ -211,6 +211,7 @@
#define __NR_preadv2 376
#define __NR_prlimit64 334
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 340
#define __NR_process_vm_writev 341
#define __NR_pselect6 301
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
index 3b6ac3d084d74638..7b422ce268ba14d0 100644
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
@@ -237,6 +237,7 @@
#define __NR_preadv2 381
#define __NR_prlimit64 339
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 365
#define __NR_process_vm_writev 366
#define __NR_pselect6 308
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
index 35221a707e4d4a7c..77c3cc64f95ea7f3 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
@@ -242,6 +242,7 @@
#define __NR_preadv2 358
#define __NR_prlimit64 331
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 338
#define __NR_process_vm_writev 339
#define __NR_pselect6 297
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
index 5ba2b2050924df1c..7ad50bc4ad6cef04 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
@@ -222,6 +222,7 @@
#define __NR_preadv2 358
#define __NR_prlimit64 331
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 338
#define __NR_process_vm_writev 339
#define __NR_pselect6 297
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index fd98893b0e44a606..1a74d090b72f4d61 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.14.
-kernel 5.14
+# The list of system calls is current as of Linux 5.15.
+kernel 5.15
FAST_atomic_update
FAST_cmpxchg
@@ -440,6 +440,7 @@ preadv
preadv2
prlimit64
process_madvise
+process_mrelease
process_vm_readv
process_vm_writev
prof
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 26d6ac68a651ec98..3ce2a1fcfc1c15f2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
@@ -215,6 +215,7 @@
#define __NR_preadv2 327
#define __NR_prlimit64 302
#define __NR_process_madvise 440
+#define __NR_process_mrelease 448
#define __NR_process_vm_readv 310
#define __NR_process_vm_writev 311
#define __NR_pselect6 270
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 36847783f6b91d5e..9e87e89baccc397c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
@@ -208,6 +208,7 @@
#define __NR_preadv2 1073742370
#define __NR_prlimit64 1073742126
#define __NR_process_madvise 1073742264
+#define __NR_process_mrelease 1073742272
#define __NR_process_vm_readv 1073742363
#define __NR_process_vm_writev 1073742364
#define __NR_pselect6 1073742094

View File

@ -0,0 +1,442 @@
commit 2fe2af88abd13ae5636881da2e26f461ecb7dfb5
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Jan 13 14:59:29 2022 +0100
i386: Remove broken CAN_USE_REGISTER_ASM_EBP (bug 28771)
The configure check for CAN_USE_REGISTER_ASM_EBP tried to compile a
simple function that uses %ebp as an inline assembly operand. If
compilation failed, CAN_USE_REGISTER_ASM_EBP was set 0, which
eventually had these consequences:
(1) %ebx was avoided as an inline assembly operand, with an
assembler macro hack to avoid unnecessary register moves.
(2) %ebp was avoided as an inline assembly operand, using an
out-of-line syscall function for 6-argument system calls.
(1) is no longer needed for any GCC version that is supported for
building glibc. %ebx can be used directly as a register operand.
Therefore, this commit removes the %ebx avoidance completely. This
avoids the assembler macro hack, which turns out to be incompatible
with the current Systemtap probe macros (which switch to .altmacro
unconditionally).
(2) is still needed in many build configurations. The existing
configure check cannot really capture that because the simple function
succeeds to compile, while the full glibc build still fails.
Therefore, this commit removes the check, the CAN_USE_REGISTER_ASM_EBP
macro, and uses the out-of-line syscall function for 6-argument system
calls unconditionally.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit a78e6a10d0b50d0ca80309775980fc99944b1727)
diff --git a/config.h.in b/config.h.in
index 458342887e4e9380..790038fec60eb049 100644
--- a/config.h.in
+++ b/config.h.in
@@ -286,10 +286,6 @@
/* Define if static PIE is enabled. */
#define ENABLE_STATIC_PIE 0
-/* Some compiler options may now allow to use ebp in __asm__ (used mainly
- in i386 6 argument syscall issue). */
-#define CAN_USE_REGISTER_ASM_EBP 0
-
/* The default value of x86 CET control. */
#define DEFAULT_DL_X86_CET_CONTROL cet_elf_property
diff --git a/sysdeps/unix/sysv/linux/i386/configure b/sysdeps/unix/sysv/linux/i386/configure
index 0327590486c80777..f119e62fc31903b3 100644
--- a/sysdeps/unix/sysv/linux/i386/configure
+++ b/sysdeps/unix/sysv/linux/i386/configure
@@ -1,44 +1,5 @@
# This file is generated from configure.ac by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/unix/sysv/linux/i386.
-# Check if CFLAGS allows compiler to use ebp register in inline assembly.
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler flags allows ebp in inline assembly" >&5
-$as_echo_n "checking if compiler flags allows ebp in inline assembly... " >&6; }
-if ${libc_cv_can_use_register_asm_ebp+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
- void foo (int i)
- {
- register int reg asm ("ebp") = i;
- asm ("# %0" : : "r" (reg));
- }
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- libc_cv_can_use_register_asm_ebp=yes
-else
- libc_cv_can_use_register_asm_ebp=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_can_use_register_asm_ebp" >&5
-$as_echo "$libc_cv_can_use_register_asm_ebp" >&6; }
-if test $libc_cv_can_use_register_asm_ebp = yes; then
- $as_echo "#define CAN_USE_REGISTER_ASM_EBP 1" >>confdefs.h
-
-fi
-
libc_cv_gcc_unwind_find_fde=yes
ldd_rewrite_script=sysdeps/unix/sysv/linux/ldd-rewrite.sed
diff --git a/sysdeps/unix/sysv/linux/i386/configure.ac b/sysdeps/unix/sysv/linux/i386/configure.ac
index 9e980784bb826463..64ab2cc2c8f9deec 100644
--- a/sysdeps/unix/sysv/linux/i386/configure.ac
+++ b/sysdeps/unix/sysv/linux/i386/configure.ac
@@ -1,22 +1,5 @@
GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
# Local configure fragment for sysdeps/unix/sysv/linux/i386.
-# Check if CFLAGS allows compiler to use ebp register in inline assembly.
-AC_CACHE_CHECK([if compiler flags allows ebp in inline assembly],
- libc_cv_can_use_register_asm_ebp, [
-AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM([
- void foo (int i)
- {
- register int reg asm ("ebp") = i;
- asm ("# %0" : : "r" (reg));
- }])],
- [libc_cv_can_use_register_asm_ebp=yes],
- [libc_cv_can_use_register_asm_ebp=no])
-])
-if test $libc_cv_can_use_register_asm_ebp = yes; then
- AC_DEFINE(CAN_USE_REGISTER_ASM_EBP)
-fi
-
libc_cv_gcc_unwind_find_fde=yes
ldd_rewrite_script=sysdeps/unix/sysv/linux/ldd-rewrite.sed
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 8a9911b7acd9e692..39d6a3c13427abb5 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -43,15 +43,6 @@
# endif
#endif
-/* Since GCC 5 and above can properly spill %ebx with PIC when needed,
- we can inline syscalls with 6 arguments if GCC 5 or above is used
- to compile glibc. Disable GCC 5 optimization when compiling for
- profiling or when -fno-omit-frame-pointer is used since asm ("ebp")
- can't be used to put the 6th argument in %ebp for syscall. */
-#if !defined PROF && CAN_USE_REGISTER_ASM_EBP
-# define OPTIMIZE_FOR_GCC_5
-#endif
-
#ifdef __ASSEMBLER__
/* Linux uses a negative return value to indicate syscall errors,
@@ -239,36 +230,6 @@
extern int __syscall_error (int)
attribute_hidden __attribute__ ((__regparm__ (1)));
-#ifndef OPTIMIZE_FOR_GCC_5
-/* We need some help from the assembler to generate optimal code. We
- define some macros here which later will be used. */
-asm (".L__X'%ebx = 1\n\t"
- ".L__X'%ecx = 2\n\t"
- ".L__X'%edx = 2\n\t"
- ".L__X'%eax = 3\n\t"
- ".L__X'%esi = 3\n\t"
- ".L__X'%edi = 3\n\t"
- ".L__X'%ebp = 3\n\t"
- ".L__X'%esp = 3\n\t"
- ".macro bpushl name reg\n\t"
- ".if 1 - \\name\n\t"
- ".if 2 - \\name\n\t"
- "error\n\t"
- ".else\n\t"
- "xchgl \\reg, %ebx\n\t"
- ".endif\n\t"
- ".endif\n\t"
- ".endm\n\t"
- ".macro bpopl name reg\n\t"
- ".if 1 - \\name\n\t"
- ".if 2 - \\name\n\t"
- "error\n\t"
- ".else\n\t"
- "xchgl \\reg, %ebx\n\t"
- ".endif\n\t"
- ".endif\n\t"
- ".endm\n\t");
-
/* Six-argument syscalls use an out-of-line helper, because an inline
asm using all registers apart from %esp cannot work reliably and
the assembler does not support describing an asm that saves and
@@ -279,7 +240,6 @@ struct libc_do_syscall_args
{
int ebx, edi, ebp;
};
-#endif
# define VDSO_NAME "LINUX_2.6"
# define VDSO_HASH 61765110
@@ -332,14 +292,8 @@ struct libc_do_syscall_args
/* Each object using 6-argument inline syscalls must include a
definition of __libc_do_syscall. */
-#ifdef OPTIMIZE_FOR_GCC_5
-# define INTERNAL_SYSCALL_MAIN_6(name, args...) \
- INTERNAL_SYSCALL_MAIN_INLINE(name, 6, args)
-# define INTERNAL_SYSCALL_MAIN_NCS_6(name, args...) \
- INTERNAL_SYSCALL_MAIN_NCS(name, 6, args)
-#else /* GCC 5 */
-# define INTERNAL_SYSCALL_MAIN_6(name, arg1, arg2, arg3, \
- arg4, arg5, arg6) \
+#define INTERNAL_SYSCALL_MAIN_6(name, arg1, arg2, arg3, \
+ arg4, arg5, arg6) \
struct libc_do_syscall_args _xv = \
{ \
(int) (arg1), \
@@ -352,8 +306,8 @@ struct libc_do_syscall_args
: "=a" (resultvar) \
: "i" (__NR_##name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \
: "memory", "cc")
-# define INTERNAL_SYSCALL_MAIN_NCS_6(name, arg1, arg2, arg3, \
- arg4, arg5, arg6) \
+#define INTERNAL_SYSCALL_MAIN_NCS_6(name, arg1, arg2, arg3, \
+ arg4, arg5, arg6) \
struct libc_do_syscall_args _xv = \
{ \
(int) (arg1), \
@@ -366,7 +320,6 @@ struct libc_do_syscall_args
: "=a" (resultvar) \
: "a" (name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \
: "memory", "cc")
-#endif /* GCC 5 */
#define INTERNAL_SYSCALL(name, nr, args...) \
({ \
@@ -380,193 +333,72 @@ struct libc_do_syscall_args
(int) resultvar; })
#if I386_USE_SYSENTER
-# ifdef OPTIMIZE_FOR_GCC_5
-# ifdef PIC
-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \
+# ifdef PIC
+# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \
LOADREGS_##nr(args) \
asm volatile ( \
"call *%%gs:%P2" \
: "=a" (resultvar) \
: "a" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMARGS_##nr(args) : "memory", "cc")
-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \
+# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \
LOADREGS_##nr(args) \
asm volatile ( \
"call *%%gs:%P2" \
: "=a" (resultvar) \
: "a" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMARGS_##nr(args) : "memory", "cc")
-# else
-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \
+# else /* I386_USE_SYSENTER && !PIC */
+# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \
LOADREGS_##nr(args) \
asm volatile ( \
"call *_dl_sysinfo" \
: "=a" (resultvar) \
: "a" (__NR_##name) ASMARGS_##nr(args) : "memory", "cc")
-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \
+# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \
LOADREGS_##nr(args) \
asm volatile ( \
"call *_dl_sysinfo" \
: "=a" (resultvar) \
: "a" (name) ASMARGS_##nr(args) : "memory", "cc")
-# endif
-# else /* GCC 5 */
-# ifdef PIC
-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \
- EXTRAVAR_##nr \
- asm volatile ( \
- LOADARGS_##nr \
- "movl %1, %%eax\n\t" \
- "call *%%gs:%P2\n\t" \
- RESTOREARGS_##nr \
- : "=a" (resultvar) \
- : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \
- ASMFMT_##nr(args) : "memory", "cc")
-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \
- EXTRAVAR_##nr \
- asm volatile ( \
- LOADARGS_##nr \
- "call *%%gs:%P2\n\t" \
- RESTOREARGS_##nr \
- : "=a" (resultvar) \
- : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
- ASMFMT_##nr(args) : "memory", "cc")
-# else
-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \
- EXTRAVAR_##nr \
- asm volatile ( \
- LOADARGS_##nr \
- "movl %1, %%eax\n\t" \
- "call *_dl_sysinfo\n\t" \
- RESTOREARGS_##nr \
- : "=a" (resultvar) \
- : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc")
-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \
- EXTRAVAR_##nr \
- asm volatile ( \
- LOADARGS_##nr \
- "call *_dl_sysinfo\n\t" \
- RESTOREARGS_##nr \
- : "=a" (resultvar) \
- : "0" (name) ASMFMT_##nr(args) : "memory", "cc")
-# endif
-# endif /* GCC 5 */
-#else
-# ifdef OPTIMIZE_FOR_GCC_5
-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \
+# endif /* I386_USE_SYSENTER && !PIC */
+#else /* !I386_USE_SYSENTER */
+# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \
LOADREGS_##nr(args) \
asm volatile ( \
"int $0x80" \
: "=a" (resultvar) \
: "a" (__NR_##name) ASMARGS_##nr(args) : "memory", "cc")
-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \
+# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \
LOADREGS_##nr(args) \
asm volatile ( \
"int $0x80" \
: "=a" (resultvar) \
: "a" (name) ASMARGS_##nr(args) : "memory", "cc")
-# else /* GCC 5 */
-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \
- EXTRAVAR_##nr \
- asm volatile ( \
- LOADARGS_##nr \
- "movl %1, %%eax\n\t" \
- "int $0x80\n\t" \
- RESTOREARGS_##nr \
- : "=a" (resultvar) \
- : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc")
-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \
- EXTRAVAR_##nr \
- asm volatile ( \
- LOADARGS_##nr \
- "int $0x80\n\t" \
- RESTOREARGS_##nr \
- : "=a" (resultvar) \
- : "0" (name) ASMFMT_##nr(args) : "memory", "cc")
-# endif /* GCC 5 */
-#endif
-
-#define LOADARGS_0
-#ifdef __PIC__
-# if I386_USE_SYSENTER && defined PIC
-# define LOADARGS_1 \
- "bpushl .L__X'%k3, %k3\n\t"
-# define LOADARGS_5 \
- "movl %%ebx, %4\n\t" \
- "movl %3, %%ebx\n\t"
-# else
-# define LOADARGS_1 \
- "bpushl .L__X'%k2, %k2\n\t"
-# define LOADARGS_5 \
- "movl %%ebx, %3\n\t" \
- "movl %2, %%ebx\n\t"
-# endif
-# define LOADARGS_2 LOADARGS_1
-# define LOADARGS_3 \
- "xchgl %%ebx, %%edi\n\t"
-# define LOADARGS_4 LOADARGS_3
-#else
-# define LOADARGS_1
-# define LOADARGS_2
-# define LOADARGS_3
-# define LOADARGS_4
-# define LOADARGS_5
-#endif
-
-#define RESTOREARGS_0
-#ifdef __PIC__
-# if I386_USE_SYSENTER && defined PIC
-# define RESTOREARGS_1 \
- "bpopl .L__X'%k3, %k3\n\t"
-# define RESTOREARGS_5 \
- "movl %4, %%ebx"
-# else
-# define RESTOREARGS_1 \
- "bpopl .L__X'%k2, %k2\n\t"
-# define RESTOREARGS_5 \
- "movl %3, %%ebx"
-# endif
-# define RESTOREARGS_2 RESTOREARGS_1
-# define RESTOREARGS_3 \
- "xchgl %%edi, %%ebx\n\t"
-# define RESTOREARGS_4 RESTOREARGS_3
-#else
-# define RESTOREARGS_1
-# define RESTOREARGS_2
-# define RESTOREARGS_3
-# define RESTOREARGS_4
-# define RESTOREARGS_5
-#endif
+#endif /* !I386_USE_SYSENTER */
-#ifdef OPTIMIZE_FOR_GCC_5
-# define LOADREGS_0()
-# define ASMARGS_0()
-# define LOADREGS_1(arg1) \
+#define LOADREGS_0()
+#define ASMARGS_0()
+#define LOADREGS_1(arg1) \
LOADREGS_0 ()
-# define ASMARGS_1(arg1) \
+#define ASMARGS_1(arg1) \
ASMARGS_0 (), "b" ((unsigned int) (arg1))
-# define LOADREGS_2(arg1, arg2) \
+#define LOADREGS_2(arg1, arg2) \
LOADREGS_1 (arg1)
-# define ASMARGS_2(arg1, arg2) \
+#define ASMARGS_2(arg1, arg2) \
ASMARGS_1 (arg1), "c" ((unsigned int) (arg2))
-# define LOADREGS_3(arg1, arg2, arg3) \
+#define LOADREGS_3(arg1, arg2, arg3) \
LOADREGS_2 (arg1, arg2)
-# define ASMARGS_3(arg1, arg2, arg3) \
+#define ASMARGS_3(arg1, arg2, arg3) \
ASMARGS_2 (arg1, arg2), "d" ((unsigned int) (arg3))
-# define LOADREGS_4(arg1, arg2, arg3, arg4) \
+#define LOADREGS_4(arg1, arg2, arg3, arg4) \
LOADREGS_3 (arg1, arg2, arg3)
-# define ASMARGS_4(arg1, arg2, arg3, arg4) \
+#define ASMARGS_4(arg1, arg2, arg3, arg4) \
ASMARGS_3 (arg1, arg2, arg3), "S" ((unsigned int) (arg4))
-# define LOADREGS_5(arg1, arg2, arg3, arg4, arg5) \
+#define LOADREGS_5(arg1, arg2, arg3, arg4, arg5) \
LOADREGS_4 (arg1, arg2, arg3, arg4)
-# define ASMARGS_5(arg1, arg2, arg3, arg4, arg5) \
+#define ASMARGS_5(arg1, arg2, arg3, arg4, arg5) \
ASMARGS_4 (arg1, arg2, arg3, arg4), "D" ((unsigned int) (arg5))
-# define LOADREGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
- register unsigned int _a6 asm ("ebp") = (unsigned int) (arg6); \
- LOADREGS_5 (arg1, arg2, arg3, arg4, arg5)
-# define ASMARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
- ASMARGS_5 (arg1, arg2, arg3, arg4, arg5), "r" (_a6)
-#endif /* GCC 5 */
#define ASMFMT_0()
#ifdef __PIC__

View File

@ -0,0 +1,337 @@
commit 705f1e4606aa78f4e861b4e3346725bf5f083a56
Author: Joseph Myers <joseph@codesourcery.com>
Date: Thu Jan 13 22:18:13 2022 +0000
Update syscall lists for Linux 5.16
Linux 5.16 has one new syscall, futex_waitv. Update
syscall-names.list and regenerate the arch-syscall.h headers with
build-many-glibcs.py update-syscalls.
Tested with build-many-glibcs.py.
(cherry picked from commit 4997a533ae4b51ef66a6b68862b7578a7acb82df)
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
index 74a809561a45edc4..9905ebedf298954c 100644
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
@@ -62,6 +62,7 @@
#define __NR_fsync 82
#define __NR_ftruncate 46
#define __NR_futex 98
+#define __NR_futex_waitv 449
#define __NR_get_mempolicy 236
#define __NR_get_robust_list 100
#define __NR_getcpu 168
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
index 6fc0a23504c3b53d..ee8085be69958b25 100644
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
@@ -78,6 +78,7 @@
#define __NR_fsync 95
#define __NR_ftruncate 130
#define __NR_futex 394
+#define __NR_futex_waitv 559
#define __NR_futimesat 454
#define __NR_get_kernel_syms 309
#define __NR_get_mempolicy 430
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
index 0c66762bf868a992..1b626d97705d545a 100644
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
@@ -65,6 +65,7 @@
#define __NR_fsync 82
#define __NR_ftruncate64 46
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_get_mempolicy 236
#define __NR_get_robust_list 100
#define __NR_getcpu 168
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
index c41a864c6d530eb0..96ef8db9368e7de4 100644
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
@@ -90,6 +90,7 @@
#define __NR_ftruncate64 194
#define __NR_futex 240
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_futimesat 326
#define __NR_get_mempolicy 320
#define __NR_get_robust_list 339
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
index 863ffa3e0cd34d3e..96910154ed6a5c1b 100644
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
@@ -70,6 +70,7 @@
#define __NR_ftruncate64 46
#define __NR_futex 98
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_get_mempolicy 236
#define __NR_get_robust_list 100
#define __NR_getcpu 168
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
index 6cf27cd17c1ad0c0..36675fd48e6f50c5 100644
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
@@ -87,6 +87,7 @@
#define __NR_ftruncate64 200
#define __NR_futex 210
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_futimesat 279
#define __NR_get_mempolicy 261
#define __NR_get_robust_list 290
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
index 2512508b7daa8ed2..c86ccbda4681066c 100644
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
@@ -94,6 +94,7 @@
#define __NR_ftruncate64 194
#define __NR_futex 240
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_futimesat 299
#define __NR_get_kernel_syms 130
#define __NR_get_mempolicy 275
diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
index 4a0c737369217367..d898bce404955ef0 100644
--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
@@ -74,6 +74,7 @@
#define __NR_fsync 1051
#define __NR_ftruncate 1098
#define __NR_futex 1230
+#define __NR_futex_waitv 1473
#define __NR_futimesat 1285
#define __NR_get_mempolicy 1260
#define __NR_get_robust_list 1299
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
index e310eb5075fb22d8..fe721b809076abeb 100644
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
@@ -93,6 +93,7 @@
#define __NR_ftruncate64 194
#define __NR_futex 235
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_futimesat 292
#define __NR_get_kernel_syms 130
#define __NR_get_mempolicy 269
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
index b4ecad010c2a6abf..6e10c3661db96a1e 100644
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
@@ -94,6 +94,7 @@
#define __NR_ftruncate64 194
#define __NR_futex 240
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_futimesat 299
#define __NR_get_kernel_syms 130
#define __NR_get_mempolicy 275
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
index 7e3d138ba969c57b..26a6d594a2222f15 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
@@ -93,6 +93,7 @@
#define __NR_ftruncate64 4212
#define __NR_futex 4238
#define __NR_futex_time64 4422
+#define __NR_futex_waitv 4449
#define __NR_futimesat 4292
#define __NR_get_kernel_syms 4130
#define __NR_get_mempolicy 4269
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 7e9e232e5256bc89..83e0d49c5e3ca1bc 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
@@ -86,6 +86,7 @@
#define __NR_ftruncate 6075
#define __NR_futex 6194
#define __NR_futex_time64 6422
+#define __NR_futex_waitv 6449
#define __NR_futimesat 6255
#define __NR_get_kernel_syms 6170
#define __NR_get_mempolicy 6232
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 f9e7ef72b0aa1749..d6747c542f63202b 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
@@ -78,6 +78,7 @@
#define __NR_fsync 5072
#define __NR_ftruncate 5075
#define __NR_futex 5194
+#define __NR_futex_waitv 5449
#define __NR_futimesat 5251
#define __NR_get_kernel_syms 5170
#define __NR_get_mempolicy 5228
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
index afd73fc1daca1fb4..4ee209bc4475ea7d 100644
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
@@ -69,6 +69,7 @@
#define __NR_ftruncate64 46
#define __NR_futex 98
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_get_mempolicy 236
#define __NR_get_robust_list 100
#define __NR_getcpu 168
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
index 0ac2992028eda27e..497299fbc47a708c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
@@ -92,6 +92,7 @@
#define __NR_ftruncate64 194
#define __NR_futex 221
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_futimesat 290
#define __NR_get_kernel_syms 130
#define __NR_get_mempolicy 260
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
index c890bc644e14fe06..e840279f171b10b9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
@@ -81,6 +81,7 @@
#define __NR_ftime 35
#define __NR_ftruncate 93
#define __NR_futex 221
+#define __NR_futex_waitv 449
#define __NR_futimesat 290
#define __NR_get_kernel_syms 130
#define __NR_get_mempolicy 260
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
index cd336d755a42598a..73ef74c005e5a2bb 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
@@ -60,6 +60,7 @@
#define __NR_fsync 82
#define __NR_ftruncate64 46
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_get_mempolicy 236
#define __NR_get_robust_list 100
#define __NR_getcpu 168
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
index 8edd21620bb4ef64..919a79ee91177459 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
@@ -62,6 +62,7 @@
#define __NR_fsync 82
#define __NR_ftruncate 46
#define __NR_futex 98
+#define __NR_futex_waitv 449
#define __NR_get_mempolicy 236
#define __NR_get_robust_list 100
#define __NR_getcpu 168
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 1a4873f505765617..005c0ada7aab85a1 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
@@ -91,6 +91,7 @@
#define __NR_ftruncate64 194
#define __NR_futex 238
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_futimesat 292
#define __NR_get_kernel_syms 130
#define __NR_get_mempolicy 269
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 2af4607c1d36d173..9131fddcc16116e4 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
@@ -76,6 +76,7 @@
#define __NR_fsync 118
#define __NR_ftruncate 93
#define __NR_futex 238
+#define __NR_futex_waitv 449
#define __NR_futimesat 292
#define __NR_get_kernel_syms 130
#define __NR_get_mempolicy 269
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
index 7b422ce268ba14d0..d8fb041568ecb4da 100644
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
@@ -90,6 +90,7 @@
#define __NR_ftruncate64 194
#define __NR_futex 240
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_futimesat 299
#define __NR_get_mempolicy 275
#define __NR_get_robust_list 312
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
index 77c3cc64f95ea7f3..2bc014fe6a1a1f4a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
@@ -92,6 +92,7 @@
#define __NR_ftruncate64 84
#define __NR_futex 142
#define __NR_futex_time64 422
+#define __NR_futex_waitv 449
#define __NR_futimesat 288
#define __NR_get_kernel_syms 223
#define __NR_get_mempolicy 304
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
index 7ad50bc4ad6cef04..76dbbe595ffe868f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
@@ -82,6 +82,7 @@
#define __NR_fsync 95
#define __NR_ftruncate 130
#define __NR_futex 142
+#define __NR_futex_waitv 449
#define __NR_futimesat 288
#define __NR_get_kernel_syms 223
#define __NR_get_mempolicy 304
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 1a74d090b72f4d61..0bc2af37dfa1eeb5 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.15.
-kernel 5.15
+# The list of system calls is current as of Linux 5.16.
+kernel 5.16
FAST_atomic_update
FAST_cmpxchg
@@ -146,6 +146,7 @@ ftruncate
ftruncate64
futex
futex_time64
+futex_waitv
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 3ce2a1fcfc1c15f2..28558279b48a1ef4 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
@@ -78,6 +78,7 @@
#define __NR_fsync 74
#define __NR_ftruncate 77
#define __NR_futex 202
+#define __NR_futex_waitv 449
#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 9e87e89baccc397c..c1ab8ec45e8b8fd3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
@@ -74,6 +74,7 @@
#define __NR_fsync 1073741898
#define __NR_ftruncate 1073741901
#define __NR_futex 1073742026
+#define __NR_futex_waitv 1073742273
#define __NR_futimesat 1073742085
#define __NR_get_mempolicy 1073742063
#define __NR_get_robust_list 1073742355

View File

@ -0,0 +1,53 @@
commit 03e6e02e6a216cfb913f49b3be80d5088603864f
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Sun Jan 9 09:06:15 2022 -0800
Disable debuginfod in printer tests [BZ #28757]
With gdb-11.1-6.fc35.x86_64, I got
FAIL: nptl/test-cond-printers
FAIL: nptl/test-condattr-printers
FAIL: nptl/test-mutex-printers
FAIL: nptl/test-mutexattr-printers
FAIL: nptl/test-rwlock-printers
FAIL: nptl/test-rwlockattr-printers
$ cat nptl/test-condattr-printers.out
Error: Response does not match the expected pattern.
Command: start
Expected pattern: main
Response: Temporary breakpoint 1 at 0x11d5: file test-condattr-printers.c, line 43.
Starting program: /export/build/gnu/tools-build/glibc-cet-gitlab/build-x86_64-linux/nptl/test-condattr-printers
This GDB supports auto-downloading debuginfo from the following URLs:
https://debuginfod.fedoraproject.org/
Enable debuginfod for this session? (y or [n])
Disable debuginfod to avoid GDB messages. This fixes BZ #28757.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 7de501f9418bf099e7104b63b0e4423257981b14)
diff --git a/scripts/test_printers_common.py b/scripts/test_printers_common.py
index 34a3df6e6bd8b363..53b6d30d40ce2622 100644
--- a/scripts/test_printers_common.py
+++ b/scripts/test_printers_common.py
@@ -161,6 +161,17 @@ def init_test(test_bin, printer_files, printer_names):
printer files.
"""
+ # Disable debuginfod to avoid GDB messages like:
+ #
+ # This GDB supports auto-downloading debuginfo from the following URLs:
+ # https://debuginfod.fedoraproject.org/
+ # Enable debuginfod for this session? (y or [n])
+ #
+ try:
+ test('set debuginfod enabled off')
+ except Exception:
+ pass
+
# Load all the pretty printer files. We're assuming these are safe.
for printer_file in printer_files:
test('source {0}'.format(printer_file))

View File

@ -0,0 +1,165 @@
commit 5575daae5099e779bb860b566b4d608418a5b832
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon Jan 17 10:21:34 2022 +0100
socket: Add the __sockaddr_un_set function
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit e368b12f6c16b6888dda99ba641e999b9c9643c8)
diff --git a/include/sys/un.h b/include/sys/un.h
index bdbee999806930f4..152afd9fc7426d8b 100644
--- a/include/sys/un.h
+++ b/include/sys/un.h
@@ -1 +1,13 @@
#include <socket/sys/un.h>
+
+#ifndef _ISOMAC
+
+/* Set ADDR->sun_family to AF_UNIX and ADDR->sun_path to PATHNAME.
+ Return 0 on success or -1 on failure (due to overlong PATHNAME).
+ The caller should always use sizeof (struct sockaddr_un) as the
+ socket address length, disregaring the length of PATHNAME.
+ Only concrete (non-abstract) pathnames are supported. */
+int __sockaddr_un_set (struct sockaddr_un *addr, const char *pathname)
+ attribute_hidden;
+
+#endif /* _ISOMAC */
diff --git a/socket/Makefile b/socket/Makefile
index 375957601024c12e..c2de11d73ca1e324 100644
--- a/socket/Makefile
+++ b/socket/Makefile
@@ -29,13 +29,17 @@ headers := sys/socket.h sys/un.h bits/sockaddr.h bits/socket.h \
routines := accept bind connect getpeername getsockname getsockopt \
listen recv recvfrom recvmsg send sendmsg sendto \
setsockopt shutdown socket socketpair isfdtype opensock \
- sockatmark accept4 recvmmsg sendmmsg
+ sockatmark accept4 recvmmsg sendmmsg sockaddr_un_set
tests := \
tst-accept4 \
tst-sockopt \
# tests
+tests-internal := \
+ tst-sockaddr_un_set \
+ # tests-internal
+
tests-time64 := \
tst-sockopt-time64 \
# tests
diff --git a/socket/sockaddr_un_set.c b/socket/sockaddr_un_set.c
new file mode 100644
index 0000000000000000..0bd40dc34e3d7efc
--- /dev/null
+++ b/socket/sockaddr_un_set.c
@@ -0,0 +1,41 @@
+/* Set the sun_path member of struct sockaddr_un.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+int
+__sockaddr_un_set (struct sockaddr_un *addr, const char *pathname)
+{
+ size_t name_length = strlen (pathname);
+
+ /* The kernel supports names of exactly sizeof (addr->sun_path)
+ bytes, without a null terminator, but userspace does not; see the
+ SUN_LEN macro. */
+ if (name_length >= sizeof (addr->sun_path))
+ {
+ __set_errno (EINVAL); /* Error code used by the kernel. */
+ return -1;
+ }
+
+ addr->sun_family = AF_UNIX;
+ memcpy (addr->sun_path, pathname, name_length + 1);
+ return 0;
+}
diff --git a/socket/tst-sockaddr_un_set.c b/socket/tst-sockaddr_un_set.c
new file mode 100644
index 0000000000000000..29c2a81afda81b5e
--- /dev/null
+++ b/socket/tst-sockaddr_un_set.c
@@ -0,0 +1,62 @@
+/* Test the __sockaddr_un_set function.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+/* Re-compile the function because the version in libc is not
+ exported. */
+#include "sockaddr_un_set.c"
+
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ struct sockaddr_un sun;
+
+ memset (&sun, 0xcc, sizeof (sun));
+ __sockaddr_un_set (&sun, "");
+ TEST_COMPARE (sun.sun_family, AF_UNIX);
+ TEST_COMPARE (__sockaddr_un_set (&sun, ""), 0);
+
+ memset (&sun, 0xcc, sizeof (sun));
+ TEST_COMPARE (__sockaddr_un_set (&sun, "/example"), 0);
+ TEST_COMPARE_STRING (sun.sun_path, "/example");
+
+ {
+ char pathname[108]; /* Length of sun_path (ABI constant). */
+ memset (pathname, 'x', sizeof (pathname));
+ pathname[sizeof (pathname) - 1] = '\0';
+ memset (&sun, 0xcc, sizeof (sun));
+ TEST_COMPARE (__sockaddr_un_set (&sun, pathname), 0);
+ TEST_COMPARE (sun.sun_family, AF_UNIX);
+ TEST_COMPARE_STRING (sun.sun_path, pathname);
+ }
+
+ {
+ char pathname[109];
+ memset (pathname, 'x', sizeof (pathname));
+ pathname[sizeof (pathname) - 1] = '\0';
+ memset (&sun, 0xcc, sizeof (sun));
+ errno = 0;
+ TEST_COMPARE (__sockaddr_un_set (&sun, pathname), -1);
+ TEST_COMPARE (errno, EINVAL);
+ }
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -0,0 +1,33 @@
commit 7b5d433fd097b8ed74e458eca33597290e07b974
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon Jan 17 10:21:34 2022 +0100
CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542)
Processing an overlong pathname in the sunrpc clnt_create function
results in a stack-based buffer overflow.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 226b46770c82899b555986583294b049c6ec9b40)
diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c
index 13ced8994e49d4ee..b44357cd88e60599 100644
--- a/sunrpc/clnt_gen.c
+++ b/sunrpc/clnt_gen.c
@@ -57,9 +57,13 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
if (strcmp (proto, "unix") == 0)
{
- memset ((char *)&sun, 0, sizeof (sun));
- sun.sun_family = AF_UNIX;
- strcpy (sun.sun_path, hostname);
+ if (__sockaddr_un_set (&sun, hostname) < 0)
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ ce->cf_stat = RPC_SYSTEMERROR;
+ ce->cf_error.re_errno = errno;
+ return NULL;
+ }
sock = RPC_ANYSOCK;
client = clntunix_create (&sun, prog, vers, &sock, 0, 0);
if (client == NULL)

View File

@ -0,0 +1,82 @@
commit 1081f1d3dd7c84ba3416b5198d47a4df2b70185d
Author: Martin Sebor <msebor@redhat.com>
Date: Mon Jan 17 10:21:34 2022 +0100
sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542)
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit ef972a4c50014a16132b5c75571cfb6b30bef136)
diff --git a/sunrpc/Makefile b/sunrpc/Makefile
index 7e5bbfd951b1e835..a4281b18d04c78e9 100644
--- a/sunrpc/Makefile
+++ b/sunrpc/Makefile
@@ -65,7 +65,8 @@ shared-only-routines = $(routines)
endif
tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \
- tst-udp-nonblocking
+ tst-udp-nonblocking tst-bug22542
+
xtests := tst-getmyaddr
ifeq ($(have-thread-library),yes)
@@ -110,6 +111,8 @@ $(objpfx)tst-udp-nonblocking: $(common-objpfx)linkobj/libc.so
$(objpfx)tst-udp-garbage: \
$(common-objpfx)linkobj/libc.so $(shared-thread-library)
+$(objpfx)tst-bug22542: $(common-objpfx)linkobj/libc.so
+
else # !have-GLIBC_2.31
routines = $(routines-for-nss)
diff --git a/sunrpc/tst-bug22542.c b/sunrpc/tst-bug22542.c
new file mode 100644
index 0000000000000000..d6cd79787bdef21d
--- /dev/null
+++ b/sunrpc/tst-bug22542.c
@@ -0,0 +1,44 @@
+/* Test to verify that overlong hostname is rejected by clnt_create
+ and doesn't cause a buffer overflow (bug 22542).
+
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <rpc/clnt.h>
+#include <string.h>
+#include <support/check.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+static int
+do_test (void)
+{
+ /* Create an arbitrary hostname that's longer than fits in sun_path. */
+ char name [sizeof ((struct sockaddr_un*)0)->sun_path * 2];
+ memset (name, 'x', sizeof name - 1);
+ name [sizeof name - 1] = '\0';
+
+ errno = 0;
+ CLIENT *clnt = clnt_create (name, 0, 0, "unix");
+
+ TEST_VERIFY (clnt == NULL);
+ TEST_COMPARE (errno, EINVAL);
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -0,0 +1,102 @@
commit 6890b8a3ae40ab9d4c96024ab95b04816fcc8a4a
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon Jan 17 11:49:25 2022 +0100
CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768)
The sunrpc function svcunix_create suffers from a stack-based buffer
overflow with overlong pathname arguments.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit f545ad4928fa1f27a3075265182b38a4f939a5f7)
diff --git a/sunrpc/Makefile b/sunrpc/Makefile
index a4281b18d04c78e9..6408ab5c073538e9 100644
--- a/sunrpc/Makefile
+++ b/sunrpc/Makefile
@@ -65,7 +65,7 @@ shared-only-routines = $(routines)
endif
tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \
- tst-udp-nonblocking tst-bug22542
+ tst-udp-nonblocking tst-bug22542 tst-bug28768
xtests := tst-getmyaddr
diff --git a/sunrpc/svc_unix.c b/sunrpc/svc_unix.c
index 679fbe9cb69587bd..46f8d16fe94a3d4f 100644
--- a/sunrpc/svc_unix.c
+++ b/sunrpc/svc_unix.c
@@ -154,7 +154,10 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
SVCXPRT *xprt;
struct unix_rendezvous *r;
struct sockaddr_un addr;
- socklen_t len = sizeof (struct sockaddr_in);
+ socklen_t len = sizeof (addr);
+
+ if (__sockaddr_un_set (&addr, path) < 0)
+ return NULL;
if (sock == RPC_ANYSOCK)
{
@@ -165,12 +168,6 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
}
madesock = TRUE;
}
- memset (&addr, '\0', sizeof (addr));
- addr.sun_family = AF_UNIX;
- len = strlen (path) + 1;
- memcpy (addr.sun_path, path, len);
- len += sizeof (addr.sun_family);
-
__bind (sock, (struct sockaddr *) &addr, len);
if (__getsockname (sock, (struct sockaddr *) &addr, &len) != 0
diff --git a/sunrpc/tst-bug28768.c b/sunrpc/tst-bug28768.c
new file mode 100644
index 0000000000000000..35a4b7b0b3d34350
--- /dev/null
+++ b/sunrpc/tst-bug28768.c
@@ -0,0 +1,42 @@
+/* Test to verify that long path is rejected by svcunix_create (bug 28768).
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <rpc/svc.h>
+#include <shlib-compat.h>
+#include <string.h>
+#include <support/check.h>
+
+/* svcunix_create does not have a default version in linkobj/libc.so. */
+compat_symbol_reference (libc, svcunix_create, svcunix_create, GLIBC_2_1);
+
+static int
+do_test (void)
+{
+ char pathname[109];
+ memset (pathname, 'x', sizeof (pathname));
+ pathname[sizeof (pathname) - 1] = '\0';
+
+ errno = 0;
+ TEST_VERIFY (svcunix_create (RPC_ANYSOCK, 4096, 4096, pathname) == NULL);
+ TEST_COMPARE (errno, EINVAL);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -0,0 +1,56 @@
commit 1d401d1fccb85046402089268b94d86d822070e6
Author: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon Jan 17 19:41:40 2022 +0100
x86: use default cache size if it cannot be determined [BZ #28784]
In some cases (e.g QEMU, non-Intel/AMD CPU) the cache information can
not be retrieved and the corresponding values are set to 0.
Commit 2d651eb9265d ("x86: Move x86 processor cache info to
cpu_features") changed the behaviour in such case by defining the
__x86_shared_cache_size and __x86_data_cache_size variables to 0 instead
of using the default values. This cause an issue with the i686 SSE2
optimized bzero/routine which assumes that the cache size is at least
128 bytes, and otherwise tries to zero/set the whole address space minus
128 bytes.
Fix that by restoring the original code to only update
__x86_shared_cache_size and __x86_data_cache_size variables if the
corresponding cache sizes are not zero.
Fixes bug 28784
Fixes commit 2d651eb9265d
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit c242fcce06e3102ca663b2f992611d0bda4f2668)
diff --git a/sysdeps/x86/cacheinfo.h b/sysdeps/x86/cacheinfo.h
index 41d2c81369840ada..63f36877e3f35d99 100644
--- a/sysdeps/x86/cacheinfo.h
+++ b/sysdeps/x86/cacheinfo.h
@@ -61,14 +61,20 @@ init_cacheinfo (void)
long int data = cpu_features->data_cache_size;
/* Round data cache size to multiple of 256 bytes. */
data = data & ~255L;
- __x86_data_cache_size_half = data / 2;
- __x86_data_cache_size = data;
+ if (data > 0)
+ {
+ __x86_data_cache_size_half = data / 2;
+ __x86_data_cache_size = data;
+ }
long int shared = cpu_features->shared_cache_size;
/* Round shared cache size to multiple of 256 bytes. */
shared = shared & ~255L;
- __x86_shared_cache_size_half = shared / 2;
- __x86_shared_cache_size = shared;
+ if (shared > 0)
+ {
+ __x86_shared_cache_size_half = shared / 2;
+ __x86_shared_cache_size = shared;
+ }
__x86_shared_non_temporal_threshold
= cpu_features->non_temporal_threshold;

View File

@ -0,0 +1,64 @@
commit 82b1acd9de9796298a230d7484f26fe9a7756d18
Author: Paul A. Clarke <pc@us.ibm.com>
Date: Sat Sep 25 09:57:15 2021 -0500
powerpc: Fix unrecognized instruction errors with recent binutils
Recent versions of binutils (with commit
b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a) stopped preserving "sticky"
options across a base `.machine` directive, nullifying the use of
passing "-many" through GCC to the assembler. As a result, some
instructions which were recognized even under older, more stringent
`.machine` directives become unrecognized instructions in that
context.
In `sysdeps/powerpc/tst-set_ppr.c`, the use of the `mfppr32` extended
mnemonic became unrecognized, as the default compilation with GCC for
32bit powerpc adds a `.machine ppc` in the resulting assembly, so the
command line option `-Wa,-many` is essentially ignored, and the ISA 2.06
instructions and mnemonics, like `mfppr32`, are unrecognized.
The compilation of `sysdeps/powerpc/tst-set_ppr.c` fails with:
Error: unrecognized opcode: `mfppr32'
Add appropriate `.machine` directives in the assembly to bracket the
`mfppr32` instruction.
Part of a 2019 fix (commit 9250e6610fdb0f3a6f238d2813e319a41fb7a810) to
the above test's Makefile to add `-many` to the compilation when GCC
itself stopped passing `-many` to the assember no longer has any effect,
so remove that.
Reported-by: Joseph Myers <joseph@codesourcery.com>
(cherry picked from commit ee874f44fd55988808a4a162ef21bfa2cc8dc6f7)
diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
index 09860ffc0155d765..5e6cb07ce66decfa 100644
--- a/sysdeps/powerpc/Makefile
+++ b/sysdeps/powerpc/Makefile
@@ -61,11 +61,6 @@ ifeq ($(subdir),misc)
sysdep_headers += sys/platform/ppc.h
tests += test-gettimebase
tests += tst-set_ppr
-
-# This test is expected to run and exit with EXIT_UNSUPPORTED on
-# processors that do not implement the Power ISA 2.06 or greater.
-# But the test makes use of instructions from Power ISA 2.06 and 2.07.
-CFLAGS-tst-set_ppr.c += -Wa,-many
endif
ifeq ($(subdir),wcsmbs)
diff --git a/sysdeps/powerpc/tst-set_ppr.c b/sysdeps/powerpc/tst-set_ppr.c
index 7684f5d6ea905c60..e80da15320635585 100644
--- a/sysdeps/powerpc/tst-set_ppr.c
+++ b/sysdeps/powerpc/tst-set_ppr.c
@@ -44,7 +44,8 @@ get_thread_priority (void)
{
/* Read the PPR. */
ppr_t ppr;
- asm volatile (MFPPR" %0" : "=r"(ppr));
+ asm volatile (".machine push; .machine power7; "MFPPR" %0; .machine pop"
+ : "=r"(ppr));
/* Return the thread priority value. */
return EXTRACT_THREAD_PRIORITY (ppr);
}

View File

@ -0,0 +1,276 @@
commit 062ff490c1467059f6cd64bb9c3d85f6cc6cf97a
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Tue Jan 18 13:29:36 2022 +0530
support: Add helpers to create paths longer than PATH_MAX
Add new helpers support_create_and_chdir_toolong_temp_directory and
support_chdir_toolong_temp_directory to create and descend into
directory trees longer than PATH_MAX.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit fb7bff12e81c677a6622f724edd4d4987dd9d971)
diff --git a/support/temp_file.c b/support/temp_file.c
index c6df641876285bb2..e41128c2d43fe903 100644
--- a/support/temp_file.c
+++ b/support/temp_file.c
@@ -1,5 +1,6 @@
/* Temporary file handling for tests.
- Copyright (C) 1998-2021 Free Software Foundation, Inc.
+ Copyright (C) 1998-2022 Free Software Foundation, Inc.
+ Copyright The GNU Tools Authors.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,15 +21,17 @@
some 32-bit platforms. */
#define _FILE_OFFSET_BITS 64
+#include <support/check.h>
#include <support/temp_file.h>
#include <support/temp_file-internal.h>
#include <support/support.h>
+#include <errno.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
+#include <xunistd.h>
/* List of temporary files. */
static struct temp_name_list
@@ -36,14 +39,20 @@ static struct temp_name_list
struct temp_name_list *next;
char *name;
pid_t owner;
+ bool toolong;
} *temp_name_list;
/* Location of the temporary files. Set by the test skeleton via
support_set_test_dir. The string is not be freed. */
static const char *test_dir = _PATH_TMP;
-void
-add_temp_file (const char *name)
+/* Name of subdirectories in a too long temporary directory tree. */
+static char toolong_subdir[NAME_MAX + 1];
+static bool toolong_initialized;
+static size_t toolong_path_max;
+
+static void
+add_temp_file_internal (const char *name, bool toolong)
{
struct temp_name_list *newp
= (struct temp_name_list *) xcalloc (sizeof (*newp), 1);
@@ -53,12 +62,19 @@ add_temp_file (const char *name)
newp->name = newname;
newp->next = temp_name_list;
newp->owner = getpid ();
+ newp->toolong = toolong;
temp_name_list = newp;
}
else
free (newp);
}
+void
+add_temp_file (const char *name)
+{
+ add_temp_file_internal (name, false);
+}
+
int
create_temp_file_in_dir (const char *base, const char *dir, char **filename)
{
@@ -90,8 +106,8 @@ create_temp_file (const char *base, char **filename)
return create_temp_file_in_dir (base, test_dir, filename);
}
-char *
-support_create_temp_directory (const char *base)
+static char *
+create_temp_directory_internal (const char *base, bool toolong)
{
char *path = xasprintf ("%s/%sXXXXXX", test_dir, base);
if (mkdtemp (path) == NULL)
@@ -99,16 +115,132 @@ support_create_temp_directory (const char *base)
printf ("error: mkdtemp (\"%s\"): %m", path);
exit (1);
}
- add_temp_file (path);
+ add_temp_file_internal (path, toolong);
return path;
}
-/* Helper functions called by the test skeleton follow. */
+char *
+support_create_temp_directory (const char *base)
+{
+ return create_temp_directory_internal (base, false);
+}
+
+static void
+ensure_toolong_initialized (void)
+{
+ if (!toolong_initialized)
+ FAIL_EXIT1 ("uninitialized toolong directory tree\n");
+}
+
+static void
+initialize_toolong (const char *base)
+{
+ long name_max = pathconf (base, _PC_NAME_MAX);
+ name_max = (name_max < 0 ? 64
+ : (name_max < sizeof (toolong_subdir) ? name_max
+ : sizeof (toolong_subdir) - 1));
+
+ long path_max = pathconf (base, _PC_PATH_MAX);
+ path_max = (path_max < 0 ? 1024
+ : path_max <= PTRDIFF_MAX ? path_max : PTRDIFF_MAX);
+
+ /* Sanity check to ensure that the test does not create temporary directories
+ in different filesystems because this API doesn't support it. */
+ if (toolong_initialized)
+ {
+ if (name_max != strlen (toolong_subdir))
+ FAIL_UNSUPPORTED ("name_max: Temporary directories in different"
+ " filesystems not supported yet\n");
+ if (path_max != toolong_path_max)
+ FAIL_UNSUPPORTED ("path_max: Temporary directories in different"
+ " filesystems not supported yet\n");
+ return;
+ }
+
+ toolong_path_max = path_max;
+
+ size_t len = name_max;
+ memset (toolong_subdir, 'X', len);
+ toolong_initialized = true;
+}
+
+char *
+support_create_and_chdir_toolong_temp_directory (const char *basename)
+{
+ char *base = create_temp_directory_internal (basename, true);
+ xchdir (base);
+
+ initialize_toolong (base);
+
+ size_t sz = strlen (toolong_subdir);
+
+ /* Create directories and descend into them so that the final path is larger
+ than PATH_MAX. */
+ for (size_t i = 0; i <= toolong_path_max / sz; i++)
+ {
+ int ret = mkdir (toolong_subdir, S_IRWXU);
+ if (ret != 0 && errno == ENAMETOOLONG)
+ FAIL_UNSUPPORTED ("Filesystem does not support creating too long "
+ "directory trees\n");
+ else if (ret != 0)
+ FAIL_EXIT1 ("Failed to create directory tree: %m\n");
+ xchdir (toolong_subdir);
+ }
+ return base;
+}
void
-support_set_test_dir (const char *path)
+support_chdir_toolong_temp_directory (const char *base)
{
- test_dir = path;
+ ensure_toolong_initialized ();
+
+ xchdir (base);
+
+ size_t sz = strlen (toolong_subdir);
+ for (size_t i = 0; i <= toolong_path_max / sz; i++)
+ xchdir (toolong_subdir);
+}
+
+/* Helper functions called by the test skeleton follow. */
+
+static void
+remove_toolong_subdirs (const char *base)
+{
+ ensure_toolong_initialized ();
+
+ if (chdir (base) != 0)
+ {
+ printf ("warning: toolong cleanup base failed: chdir (\"%s\"): %m\n",
+ base);
+ return;
+ }
+
+ /* Descend. */
+ int levels = 0;
+ size_t sz = strlen (toolong_subdir);
+ for (levels = 0; levels <= toolong_path_max / sz; levels++)
+ if (chdir (toolong_subdir) != 0)
+ {
+ printf ("warning: toolong cleanup failed: chdir (\"%s\"): %m\n",
+ toolong_subdir);
+ break;
+ }
+
+ /* Ascend and remove. */
+ while (--levels >= 0)
+ {
+ if (chdir ("..") != 0)
+ {
+ printf ("warning: toolong cleanup failed: chdir (\"..\"): %m\n");
+ return;
+ }
+ if (remove (toolong_subdir) != 0)
+ {
+ printf ("warning: could not remove subdirectory: %s: %m\n",
+ toolong_subdir);
+ return;
+ }
+ }
}
void
@@ -123,6 +255,9 @@ support_delete_temp_files (void)
around, to prevent PID reuse.) */
if (temp_name_list->owner == pid)
{
+ if (temp_name_list->toolong)
+ remove_toolong_subdirs (temp_name_list->name);
+
if (remove (temp_name_list->name) != 0)
printf ("warning: could not remove temporary file: %s: %m\n",
temp_name_list->name);
@@ -147,3 +282,9 @@ support_print_temp_files (FILE *f)
fprintf (f, ")\n");
}
}
+
+void
+support_set_test_dir (const char *path)
+{
+ test_dir = path;
+}
diff --git a/support/temp_file.h b/support/temp_file.h
index f3a7fb6f9ca44d19..a22964c6fa11abd2 100644
--- a/support/temp_file.h
+++ b/support/temp_file.h
@@ -44,6 +44,15 @@ int create_temp_file_in_dir (const char *base, const char *dir,
returns. The caller should free this string. */
char *support_create_temp_directory (const char *base);
+/* Create a temporary directory tree that is longer than PATH_MAX and schedule
+ it for deletion. BASENAME is used as a prefix for the unique directory
+ name, which the function returns. The caller should free this string. */
+char *support_create_and_chdir_toolong_temp_directory (const char *basename);
+
+/* Change into the innermost directory of the directory tree BASE, which was
+ created using support_create_and_chdir_toolong_temp_directory. */
+void support_chdir_toolong_temp_directory (const char *base);
+
__END_DECLS
#endif /* SUPPORT_TEMP_FILE_H */

View File

@ -0,0 +1,121 @@
commit 269eb9d930546ce57e83b56c44c430f154684a23
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Thu Jan 13 10:34:37 2022 +0530
stdlib: Sort tests in Makefile
Put one test per line and sort them.
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 5b766603efa727c236a5f0cdcf09b71ff60b7584)
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 7c15549cafa8e397..6a1c3580bd1648ee 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -65,30 +65,81 @@ aux = grouping groupingwc tens_in_limb
static-only-routines = atexit at_quick_exit
test-srcs := tst-fmtmsg
-tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
- test-canon test-canon2 tst-strtoll tst-environ \
- tst-xpg-basename tst-random tst-random2 tst-bsearch \
- tst-limits tst-rand48 bug-strtod tst-setcontext \
- tst-setcontext2 test-a64l tst-qsort testmb2 \
- bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 \
- tst-rand48-2 tst-makecontext tst-strtod5 \
- tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \
- tst-makecontext3 bug-getcontext bug-fmtmsg1 \
- tst-secure-getenv tst-strtod-overflow tst-strtod-round \
- tst-tininess tst-strtod-underflow tst-setcontext3 \
- tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l \
- tst-quick_exit tst-thread-quick_exit tst-width \
- tst-width-stdint tst-strfrom tst-strfrom-locale \
- tst-getrandom tst-atexit tst-at_quick_exit \
- tst-cxa_atexit tst-on_exit test-atexit-race \
- test-at_quick_exit-race test-cxa_atexit-race \
- test-cxa_atexit-race2 \
- test-on_exit-race test-dlclose-exit-race \
- tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
- tst-swapcontext1 tst-setcontext4 tst-setcontext5 \
- tst-setcontext6 tst-setcontext7 tst-setcontext8 \
- tst-setcontext9 tst-bz20544 tst-canon-bz26341 \
- tst-realpath
+tests := bug-fmtmsg1 \
+ bug-getcontext \
+ bug-strtod \
+ bug-strtod2 \
+ test-a64l \
+ test-at_quick_exit-race \
+ test-atexit-race \
+ test-bz22786 \
+ test-canon \
+ test-canon2 \
+ test-cxa_atexit-race \
+ test-cxa_atexit-race2 \
+ test-dlclose-exit-race \
+ test-on_exit-race \
+ testdiv \
+ testmb \
+ testmb2 \
+ testrand \
+ testsort \
+ tst-at_quick_exit \
+ tst-atexit \
+ tst-atof1 \
+ tst-atof2 \
+ tst-bsearch \
+ tst-bz20544 \
+ tst-canon-bz26341 \
+ tst-cxa_atexit \
+ tst-environ \
+ tst-getrandom \
+ tst-limits \
+ tst-makecontext \
+ tst-makecontext-align \
+ tst-makecontext2 \
+ tst-makecontext3 \
+ tst-on_exit \
+ tst-qsort \
+ tst-qsort2 \
+ tst-quick_exit \
+ tst-rand48 \
+ tst-rand48-2 \
+ tst-random \
+ tst-random2 \
+ tst-realpath \
+ tst-secure-getenv \
+ tst-setcontext \
+ tst-setcontext2 \
+ tst-setcontext3 \
+ tst-setcontext4 \
+ tst-setcontext5 \
+ tst-setcontext6 \
+ tst-setcontext7 \
+ tst-setcontext8 \
+ tst-setcontext9 \
+ tst-strfmon_l \
+ tst-strfrom \
+ tst-strfrom-locale \
+ tst-strtod \
+ tst-strtod-nan-locale \
+ tst-strtod-nan-sign \
+ tst-strtod-overflow \
+ tst-strtod-round \
+ tst-strtod-underflow \
+ tst-strtod2 \
+ tst-strtod5 \
+ tst-strtod6 \
+ tst-strtol \
+ tst-strtol-locale \
+ tst-strtoll \
+ tst-swapcontext1 \
+ tst-thread-quick_exit \
+ tst-tininess \
+ tst-unsetenv1 \
+ tst-width \
+ tst-width-stdint \
+ tst-xpg-basename
tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
tst-tls-atexit tst-tls-atexit-nodelete

View File

@ -0,0 +1,173 @@
commit 73c362840c4efde45125a6c27bf41726397f4038
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Thu Jan 13 18:50:55 2022 +0530
stdlib: Fix formatting of tests list in Makefile
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit f9dab1b5f23d0fb008a56c7c6c8919adb49d3611)
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 6a1c3580bd1648ee..9bb5c221e8be3288 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -65,81 +65,83 @@ aux = grouping groupingwc tens_in_limb
static-only-routines = atexit at_quick_exit
test-srcs := tst-fmtmsg
-tests := bug-fmtmsg1 \
- bug-getcontext \
- bug-strtod \
- bug-strtod2 \
- test-a64l \
- test-at_quick_exit-race \
- test-atexit-race \
- test-bz22786 \
- test-canon \
- test-canon2 \
- test-cxa_atexit-race \
- test-cxa_atexit-race2 \
- test-dlclose-exit-race \
- test-on_exit-race \
- testdiv \
- testmb \
- testmb2 \
- testrand \
- testsort \
- tst-at_quick_exit \
- tst-atexit \
- tst-atof1 \
- tst-atof2 \
- tst-bsearch \
- tst-bz20544 \
- tst-canon-bz26341 \
- tst-cxa_atexit \
- tst-environ \
- tst-getrandom \
- tst-limits \
- tst-makecontext \
- tst-makecontext-align \
- tst-makecontext2 \
- tst-makecontext3 \
- tst-on_exit \
- tst-qsort \
- tst-qsort2 \
- tst-quick_exit \
- tst-rand48 \
- tst-rand48-2 \
- tst-random \
- tst-random2 \
- tst-realpath \
- tst-secure-getenv \
- tst-setcontext \
- tst-setcontext2 \
- tst-setcontext3 \
- tst-setcontext4 \
- tst-setcontext5 \
- tst-setcontext6 \
- tst-setcontext7 \
- tst-setcontext8 \
- tst-setcontext9 \
- tst-strfmon_l \
- tst-strfrom \
- tst-strfrom-locale \
- tst-strtod \
- tst-strtod-nan-locale \
- tst-strtod-nan-sign \
- tst-strtod-overflow \
- tst-strtod-round \
- tst-strtod-underflow \
- tst-strtod2 \
- tst-strtod5 \
- tst-strtod6 \
- tst-strtol \
- tst-strtol-locale \
- tst-strtoll \
- tst-swapcontext1 \
- tst-thread-quick_exit \
- tst-tininess \
- tst-unsetenv1 \
- tst-width \
- tst-width-stdint \
- tst-xpg-basename
+tests := \
+ bug-fmtmsg1 \
+ bug-getcontext \
+ bug-strtod \
+ bug-strtod2 \
+ test-a64l \
+ test-at_quick_exit-race \
+ test-atexit-race \
+ test-bz22786 \
+ test-canon \
+ test-canon2 \
+ test-cxa_atexit-race \
+ test-cxa_atexit-race2 \
+ test-dlclose-exit-race \
+ test-on_exit-race \
+ testdiv \
+ testmb \
+ testmb2 \
+ testrand \
+ testsort \
+ tst-at_quick_exit \
+ tst-atexit \
+ tst-atof1 \
+ tst-atof2 \
+ tst-bsearch \
+ tst-bz20544 \
+ tst-canon-bz26341 \
+ tst-cxa_atexit \
+ tst-environ \
+ tst-getrandom \
+ tst-limits \
+ tst-makecontext \
+ tst-makecontext-align \
+ tst-makecontext2 \
+ tst-makecontext3 \
+ tst-on_exit \
+ tst-qsort \
+ tst-qsort2 \
+ tst-quick_exit \
+ tst-rand48 \
+ tst-rand48-2 \
+ tst-random \
+ tst-random2 \
+ tst-realpath \
+ tst-secure-getenv \
+ tst-setcontext \
+ tst-setcontext2 \
+ tst-setcontext3 \
+ tst-setcontext4 \
+ tst-setcontext5 \
+ tst-setcontext6 \
+ tst-setcontext7 \
+ tst-setcontext8 \
+ tst-setcontext9 \
+ tst-strfmon_l \
+ tst-strfrom \
+ tst-strfrom-locale \
+ tst-strtod \
+ tst-strtod-nan-locale \
+ tst-strtod-nan-sign \
+ tst-strtod-overflow \
+ tst-strtod-round \
+ tst-strtod-underflow \
+ tst-strtod2 \
+ tst-strtod5 \
+ tst-strtod6 \
+ tst-strtol \
+ tst-strtol-locale \
+ tst-strtoll \
+ tst-swapcontext1 \
+ tst-thread-quick_exit \
+ tst-tininess \
+ tst-unsetenv1 \
+ tst-width \
+ tst-width-stdint \
+ tst-xpg-basename \
+# tests
tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
tst-tls-atexit tst-tls-atexit-nodelete

View File

@ -0,0 +1,109 @@
commit f7a79879c0b2bef0dadd6caaaeeb0d26423e04e5
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Thu Jan 13 11:28:36 2022 +0530
realpath: Set errno to ENAMETOOLONG for result larger than PATH_MAX [BZ #28770]
realpath returns an allocated string when the result exceeds PATH_MAX,
which is unexpected when its second argument is not NULL. This results
in the second argument (resolved) being uninitialized and also results
in a memory leak since the caller expects resolved to be the same as the
returned value.
Return NULL and set errno to ENAMETOOLONG if the result exceeds
PATH_MAX. This fixes [BZ #28770], which is CVE-2021-3998.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit ee8d5e33adb284601c00c94687bc907e10aec9bb)
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 9bb5c221e8be3288..a4ac30d1f6359561 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -109,6 +109,7 @@ tests := \
tst-random \
tst-random2 \
tst-realpath \
+ tst-realpath-toolong \
tst-secure-getenv \
tst-setcontext \
tst-setcontext2 \
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index 698f9ede25570ef2..7a23a51b3a395eb3 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -400,8 +400,16 @@ realpath_stk (const char *name, char *resolved,
error:
*dest++ = '\0';
- if (resolved != NULL && dest - rname <= get_path_max ())
- rname = strcpy (resolved, rname);
+ if (resolved != NULL)
+ {
+ if (dest - rname <= get_path_max ())
+ rname = strcpy (resolved, rname);
+ else
+ {
+ failed = true;
+ __set_errno (ENAMETOOLONG);
+ }
+ }
error_nomem:
scratch_buffer_free (&extra_buffer);
diff --git a/stdlib/tst-realpath-toolong.c b/stdlib/tst-realpath-toolong.c
new file mode 100644
index 0000000000000000..8bed772460b37571
--- /dev/null
+++ b/stdlib/tst-realpath-toolong.c
@@ -0,0 +1,49 @@
+/* Verify that realpath returns NULL with ENAMETOOLONG if the result exceeds
+ NAME_MAX.
+ 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 <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <support/check.h>
+#include <support/temp_file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define BASENAME "tst-realpath-toolong."
+
+int
+do_test (void)
+{
+ char *base = support_create_and_chdir_toolong_temp_directory (BASENAME);
+
+ char buf[PATH_MAX + 1];
+ const char *res = realpath (".", buf);
+
+ /* canonicalize.c states that if the real path is >= PATH_MAX, then
+ realpath returns NULL and sets ENAMETOOLONG. */
+ TEST_VERIFY (res == NULL);
+ TEST_VERIFY (errno == ENAMETOOLONG);
+
+ free (base);
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -0,0 +1,26 @@
commit 8c8a71c85f2ed5cc90d08d82ce645513fc907cb6
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Mon Jan 24 10:57:09 2022 +0530
tst-realpath-toolong: Fix hurd build
Define PATH_MAX to a constant if it isn't already defined, like in hurd.
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 976db046bc3a3738f69255ae00b0a09b8e77fd9c)
diff --git a/stdlib/tst-realpath-toolong.c b/stdlib/tst-realpath-toolong.c
index 8bed772460b37571..4388890294374601 100644
--- a/stdlib/tst-realpath-toolong.c
+++ b/stdlib/tst-realpath-toolong.c
@@ -29,6 +29,10 @@
#define BASENAME "tst-realpath-toolong."
+#ifndef PATH_MAX
+# define PATH_MAX 1024
+#endif
+
int
do_test (void)
{

View File

@ -0,0 +1,329 @@
commit 472e799a5f2102bc0c3206dbd5a801765fceb39c
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Fri Jan 21 23:32:56 2022 +0530
getcwd: Set errno to ERANGE for size == 1 (CVE-2021-3999)
No valid path returned by getcwd would fit into 1 byte, so reject the
size early and return NULL with errno set to ERANGE. This change is
prompted by CVE-2021-3999, which describes a single byte buffer
underflow and overflow when all of the following conditions are met:
- The buffer size (i.e. the second argument of getcwd) is 1 byte
- The current working directory is too long
- '/' is also mounted on the current working directory
Sequence of events:
- In sysdeps/unix/sysv/linux/getcwd.c, the syscall returns ENAMETOOLONG
because the linux kernel checks for name length before it checks
buffer size
- The code falls back to the generic getcwd in sysdeps/posix
- In the generic func, the buf[0] is set to '\0' on line 250
- this while loop on line 262 is bypassed:
while (!(thisdev == rootdev && thisino == rootino))
since the rootfs (/) is bind mounted onto the directory and the flow
goes on to line 449, where it puts a '/' in the byte before the
buffer.
- Finally on line 458, it moves 2 bytes (the underflowed byte and the
'\0') to the buf[0] and buf[1], resulting in a 1 byte buffer overflow.
- buf is returned on line 469 and errno is not set.
This resolves BZ #28769.
Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Signed-off-by: Qualys Security Advisory <qsa@qualys.com>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 23e0e8f5f1fb5ed150253d986ecccdc90c2dcd5e)
diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
index 13680026ffecbd51..b6984a382c3e1711 100644
--- a/sysdeps/posix/getcwd.c
+++ b/sysdeps/posix/getcwd.c
@@ -187,6 +187,13 @@ __getcwd_generic (char *buf, size_t size)
size_t allocated = size;
size_t used;
+ /* A size of 1 byte is never useful. */
+ if (allocated == 1)
+ {
+ __set_errno (ERANGE);
+ return NULL;
+ }
+
#if HAVE_MINIMALLY_WORKING_GETCWD
/* If AT_FDCWD is not defined, the algorithm below is O(N**2) and
this is much slower than the system getcwd (at least on
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index d30d21898b402d1e..cdc01a3f023ec09a 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -342,7 +342,12 @@ sysdep_routines += xstatconv internal_statvfs \
sysdep_headers += bits/fcntl-linux.h
-tests += tst-fallocate tst-fallocate64 tst-o_path-locks
+tests += \
+ tst-fallocate \
+ tst-fallocate64 \
+ tst-getcwd-smallbuff \
+ tst-o_path-locks \
+# tests
endif
ifeq ($(subdir),elf)
diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
new file mode 100644
index 0000000000000000..d460d6e7662dc5e4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
@@ -0,0 +1,241 @@
+/* Verify that getcwd returns ERANGE for size 1 byte and does not underflow
+ buffer when the CWD is too long and is also a mount target of /. See bug
+ #28769 or CVE-2021-3999 for more context.
+ 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 <errno.h>
+#include <fcntl.h>
+#include <intprops.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <support/check.h>
+#include <support/temp_file.h>
+#include <support/xsched.h>
+#include <support/xunistd.h>
+
+static char *base;
+#define BASENAME "tst-getcwd-smallbuff"
+#define MOUNT_NAME "mpoint"
+static int sockfd[2];
+
+static void
+do_cleanup (void)
+{
+ support_chdir_toolong_temp_directory (base);
+ TEST_VERIFY_EXIT (rmdir (MOUNT_NAME) == 0);
+ free (base);
+}
+
+static void
+send_fd (const int sock, const int fd)
+{
+ struct msghdr msg = {0};
+ union
+ {
+ struct cmsghdr hdr;
+ char buf[CMSG_SPACE (sizeof (int))];
+ } cmsgbuf = {0};
+ struct cmsghdr *cmsg;
+ struct iovec vec;
+ char ch = 'A';
+ ssize_t n;
+
+ msg.msg_control = &cmsgbuf.buf;
+ msg.msg_controllen = sizeof (cmsgbuf.buf);
+
+ cmsg = CMSG_FIRSTHDR (&msg);
+ cmsg->cmsg_len = CMSG_LEN (sizeof (int));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ memcpy (CMSG_DATA (cmsg), &fd, sizeof (fd));
+
+ vec.iov_base = &ch;
+ vec.iov_len = 1;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+
+ while ((n = sendmsg (sock, &msg, 0)) == -1 && errno == EINTR);
+
+ TEST_VERIFY_EXIT (n == 1);
+}
+
+static int
+recv_fd (const int sock)
+{
+ struct msghdr msg = {0};
+ union
+ {
+ struct cmsghdr hdr;
+ char buf[CMSG_SPACE(sizeof(int))];
+ } cmsgbuf = {0};
+ struct cmsghdr *cmsg;
+ struct iovec vec;
+ ssize_t n;
+ char ch = '\0';
+ int fd = -1;
+
+ vec.iov_base = &ch;
+ vec.iov_len = 1;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+
+ msg.msg_control = &cmsgbuf.buf;
+ msg.msg_controllen = sizeof (cmsgbuf.buf);
+
+ while ((n = recvmsg (sock, &msg, 0)) == -1 && errno == EINTR);
+ if (n != 1 || ch != 'A')
+ return -1;
+
+ cmsg = CMSG_FIRSTHDR (&msg);
+ if (cmsg == NULL)
+ return -1;
+ if (cmsg->cmsg_type != SCM_RIGHTS)
+ return -1;
+ memcpy (&fd, CMSG_DATA (cmsg), sizeof (fd));
+ if (fd < 0)
+ return -1;
+ return fd;
+}
+
+static int
+child_func (void * const arg)
+{
+ xclose (sockfd[0]);
+ const int sock = sockfd[1];
+ char ch;
+
+ TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1);
+ TEST_VERIFY_EXIT (ch == '1');
+
+ if (mount ("/", MOUNT_NAME, NULL, MS_BIND | MS_REC, NULL))
+ FAIL_EXIT1 ("mount failed: %m\n");
+ const int fd = xopen ("mpoint",
+ O_RDONLY | O_PATH | O_DIRECTORY | O_NOFOLLOW, 0);
+
+ send_fd (sock, fd);
+ xclose (fd);
+
+ TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1);
+ TEST_VERIFY_EXIT (ch == 'a');
+
+ xclose (sock);
+ return 0;
+}
+
+static void
+update_map (char * const mapping, const char * const map_file)
+{
+ const size_t map_len = strlen (mapping);
+
+ const int fd = xopen (map_file, O_WRONLY, 0);
+ xwrite (fd, mapping, map_len);
+ xclose (fd);
+}
+
+static void
+proc_setgroups_write (const long child_pid, const char * const str)
+{
+ const size_t str_len = strlen(str);
+
+ char setgroups_path[sizeof ("/proc//setgroups") + INT_STRLEN_BOUND (long)];
+
+ snprintf (setgroups_path, sizeof (setgroups_path),
+ "/proc/%ld/setgroups", child_pid);
+
+ const int fd = open (setgroups_path, O_WRONLY);
+
+ if (fd < 0)
+ {
+ TEST_VERIFY_EXIT (errno == ENOENT);
+ FAIL_UNSUPPORTED ("/proc/%ld/setgroups not found\n", child_pid);
+ }
+
+ xwrite (fd, str, str_len);
+ xclose(fd);
+}
+
+static char child_stack[1024 * 1024];
+
+int
+do_test (void)
+{
+ base = support_create_and_chdir_toolong_temp_directory (BASENAME);
+
+ xmkdir (MOUNT_NAME, S_IRWXU);
+ atexit (do_cleanup);
+
+ TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0);
+ pid_t child_pid = xclone (child_func, NULL, child_stack,
+ sizeof (child_stack),
+ CLONE_NEWUSER | CLONE_NEWNS | SIGCHLD);
+
+ xclose (sockfd[1]);
+ const int sock = sockfd[0];
+
+ char map_path[sizeof ("/proc//uid_map") + INT_STRLEN_BOUND (long)];
+ char map_buf[sizeof ("0 1") + INT_STRLEN_BOUND (long)];
+
+ snprintf (map_path, sizeof (map_path), "/proc/%ld/uid_map",
+ (long) child_pid);
+ snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getuid());
+ update_map (map_buf, map_path);
+
+ proc_setgroups_write ((long) child_pid, "deny");
+ snprintf (map_path, sizeof (map_path), "/proc/%ld/gid_map",
+ (long) child_pid);
+ snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getgid());
+ update_map (map_buf, map_path);
+
+ TEST_VERIFY_EXIT (send (sock, "1", 1, MSG_NOSIGNAL) == 1);
+ const int fd = recv_fd (sock);
+ TEST_VERIFY_EXIT (fd >= 0);
+ TEST_VERIFY_EXIT (fchdir (fd) == 0);
+
+ static char buf[2 * 10 + 1];
+ memset (buf, 'A', sizeof (buf));
+
+ /* Finally, call getcwd and check if it resulted in a buffer underflow. */
+ char * cwd = getcwd (buf + sizeof (buf) / 2, 1);
+ TEST_VERIFY (cwd == NULL);
+ TEST_VERIFY (errno == ERANGE);
+
+ for (int i = 0; i < sizeof (buf); i++)
+ if (buf[i] != 'A')
+ {
+ printf ("buf[%d] = %02x\n", i, (unsigned int) buf[i]);
+ support_record_failure ();
+ }
+
+ TEST_VERIFY_EXIT (send (sock, "a", 1, MSG_NOSIGNAL) == 1);
+ xclose (sock);
+ TEST_VERIFY_EXIT (xwaitpid (child_pid, NULL, 0) == child_pid);
+
+ return 0;
+}
+
+#define CLEANUP_HANDLER do_cleanup
+#include <support/test-driver.c>

View File

@ -0,0 +1,28 @@
commit d084965adc7baa8ea804427cccf973cea556d697
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Mon Jan 24 21:36:41 2022 +0530
realpath: Avoid overwriting preexisting error (CVE-2021-3998)
Set errno and failure for paths that are too long only if no other error
occurred earlier.
Related: BZ #28770
Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 84d2d0fe20bdf94feed82b21b4d7d136db471f03)
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index 7a23a51b3a395eb3..e2d4244fc7b8fa25 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -404,7 +404,7 @@ error:
{
if (dest - rname <= get_path_max ())
rname = strcpy (resolved, rname);
- else
+ else if (!failed)
{
failed = true;
__set_errno (ENAMETOOLONG);

View File

@ -0,0 +1,47 @@
commit 3438bbca90895d32825a52e31a77dc44d273c1c1
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon Jan 24 18:14:24 2022 +0100
Linux: Detect user namespace support in io/tst-getcwd-smallbuff
Otherwise the test fails with certain container runtimes.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 5b8e7980c5dabd9aaefeba4f0208baa8cf7653ee)
diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
index d460d6e7662dc5e4..55362f6060a2b3be 100644
--- a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
+++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
@@ -34,6 +34,7 @@
#include <sys/un.h>
#include <support/check.h>
#include <support/temp_file.h>
+#include <support/test-driver.h>
#include <support/xsched.h>
#include <support/xunistd.h>
@@ -188,6 +189,23 @@ do_test (void)
xmkdir (MOUNT_NAME, S_IRWXU);
atexit (do_cleanup);
+ /* Check whether user namespaces are supported. */
+ {
+ pid_t pid = xfork ();
+ if (pid == 0)
+ {
+ if (unshare (CLONE_NEWUSER | CLONE_NEWNS) != 0)
+ _exit (EXIT_UNSUPPORTED);
+ else
+ _exit (0);
+ }
+ int status;
+ xwaitpid (pid, &status, 0);
+ TEST_VERIFY_EXIT (WIFEXITED (status));
+ if (WEXITSTATUS (status) != 0)
+ return WEXITSTATUS (status);
+ }
+
TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0);
pid_t child_pid = xclone (child_func, NULL, child_stack,
sizeof (child_stack),

View File

@ -0,0 +1,36 @@
commit b50d5b746cc0af5ad52164dcb0d3628f08b05a0d
Author: Noah Goldstein <goldstein.w.n@gmail.com>
Date: Sun Jan 9 16:02:21 2022 -0600
x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755]
Fixes [BZ# 28755] for wcsncmp by redirecting length >= 2^56 to
__wcscmp_avx2. For x86_64 this covers the entire address range so any
length larger could not possibly be used to bound `s1` or `s2`.
test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass.
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit ddf0992cf57a93200e0c782e2a94d0733a5a0b87)
diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
index 40333010a65650f9..3dfcb1bf803cf9ec 100644
--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
+++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S
@@ -87,6 +87,16 @@ ENTRY (STRCMP)
je L(char0)
jb L(zero)
# ifdef USE_AS_WCSCMP
+# ifndef __ILP32__
+ movq %rdx, %rcx
+ /* Check if length could overflow when multiplied by
+ sizeof(wchar_t). Checking top 8 bits will cover all potential
+ overflow cases as well as redirect cases where its impossible to
+ length to bound a valid memory region. In these cases just use
+ 'wcscmp'. */
+ shrq $56, %rcx
+ jnz __wcscmp_avx2
+# endif
/* Convert units: from wide to byte char. */
shl $2, %RDX_LP
# endif

View File

@ -0,0 +1,36 @@
commit 08beb3a3f4f46e306fffe184a08c5664bf0e13d6
Author: Noah Goldstein <goldstein.w.n@gmail.com>
Date: Sun Jan 9 16:02:28 2022 -0600
x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755]
Fixes [BZ# 28755] for wcsncmp by redirecting length >= 2^56 to
__wcscmp_evex. For x86_64 this covers the entire address range so any
length larger could not possibly be used to bound `s1` or `s2`.
test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass.
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit 7e08db3359c86c94918feb33a1182cd0ff3bb10b)
diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S
index 459eeed09f5e276e..d5aa6daa46c7ed25 100644
--- a/sysdeps/x86_64/multiarch/strcmp-evex.S
+++ b/sysdeps/x86_64/multiarch/strcmp-evex.S
@@ -97,6 +97,16 @@ ENTRY (STRCMP)
je L(char0)
jb L(zero)
# ifdef USE_AS_WCSCMP
+# ifndef __ILP32__
+ movq %rdx, %rcx
+ /* Check if length could overflow when multiplied by
+ sizeof(wchar_t). Checking top 8 bits will cover all potential
+ overflow cases as well as redirect cases where its impossible to
+ length to bound a valid memory region. In these cases just use
+ 'wcscmp'. */
+ shrq $56, %rcx
+ jnz __wcscmp_evex
+# endif
/* Convert units: from wide to byte char. */
shl $2, %RDX_LP
# endif

View File

@ -0,0 +1,360 @@
commit 948ebc098ed3cd928ea10997f990115e7770bda3
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Jan 27 16:03:58 2022 +0100
Fix glibc 2.34 ABI omission (missing GLIBC_2.34 in dynamic loader)
The glibc 2.34 release really should have added a GLIBC_2.34
symbol to the dynamic loader. With it, we could move functions such
as dlopen or pthread_key_create that work on process-global state
into the dynamic loader (once we have fixed a longstanding issue
with static linking). Without the GLIBC_2.34 symbol, yet another
new symbol version would be needed because old glibc will fail to
load binaries due to the missing symbol version in ld.so that newly
linked programs will require.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit af121ae3e7cd12628c91ecfc46a9d65313a6e972)
diff --git a/elf/Makefile b/elf/Makefile
index 11ff0aa8438de4e4..cd8725c76f4cfb48 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -117,6 +117,7 @@ elide-routines.os = \
# interpreter and operating independent of libc.
rtld-routines = \
$(all-dl-routines) \
+ dl-compat \
dl-conflict \
dl-diagnostics \
dl-diagnostics-cpu \
diff --git a/elf/Versions b/elf/Versions
index 775aab62af500f6c..2af210b8f771c950 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -48,6 +48,9 @@ ld {
# stack canary
__stack_chk_guard;
}
+ GLIBC_2.34 {
+ __rtld_version_placeholder;
+ }
GLIBC_PRIVATE {
# Those are in the dynamic linker, but used by libc.so.
__libc_enable_secure;
diff --git a/elf/dl-compat.c b/elf/dl-compat.c
new file mode 100644
index 0000000000000000..cc560c515930f59a
--- /dev/null
+++ b/elf/dl-compat.c
@@ -0,0 +1,32 @@
+/* Placeholder compatibility symbols.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <shlib-compat.h>
+#include <sys/cdefs.h>
+
+/* GLIBC_2.34 placeholder for future symbol moves. */
+
+void
+attribute_compat_text_section
+__attribute_used__
+__rtld_version_placeholder_1 (void)
+{
+}
+
+compat_symbol (ld, __rtld_version_placeholder_1,
+ __rtld_version_placeholder, GLIBC_2_34);
diff --git a/sysdeps/mach/hurd/i386/ld.abilist b/sysdeps/mach/hurd/i386/ld.abilist
index 7e20c5e7ce8a7a5e..ebba31f7706d854d 100644
--- a/sysdeps/mach/hurd/i386/ld.abilist
+++ b/sysdeps/mach/hurd/i386/ld.abilist
@@ -16,3 +16,4 @@ GLIBC_2.2.6 _r_debug D 0x14
GLIBC_2.2.6 abort F
GLIBC_2.3 ___tls_get_addr F
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/aarch64/ld.abilist b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
index 80b2fe672541c6e9..b7196a80e2df8efc 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
@@ -3,3 +3,4 @@ GLIBC_2.17 __stack_chk_guard D 0x8
GLIBC_2.17 __tls_get_addr F
GLIBC_2.17 _dl_mcount F
GLIBC_2.17 _r_debug D 0x28
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/alpha/ld.abilist b/sysdeps/unix/sysv/linux/alpha/ld.abilist
index 98a03f611f98f3a4..13f7fc74af62941d 100644
--- a/sysdeps/unix/sysv/linux/alpha/ld.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/ld.abilist
@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x28
GLIBC_2.1 __libc_stack_end D 0x8
GLIBC_2.1 _dl_mcount F
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __stack_chk_guard D 0x8
diff --git a/sysdeps/unix/sysv/linux/arc/ld.abilist b/sysdeps/unix/sysv/linux/arc/ld.abilist
index 048f17c8486f3d54..7284383a6bea8e64 100644
--- a/sysdeps/unix/sysv/linux/arc/ld.abilist
+++ b/sysdeps/unix/sysv/linux/arc/ld.abilist
@@ -3,3 +3,4 @@ GLIBC_2.32 __stack_chk_guard D 0x4
GLIBC_2.32 __tls_get_addr F
GLIBC_2.32 _dl_mcount F
GLIBC_2.32 _r_debug D 0x14
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/arm/be/ld.abilist b/sysdeps/unix/sysv/linux/arm/be/ld.abilist
index cc8825c3bc68ad4a..7987bbae1112aa3d 100644
--- a/sysdeps/unix/sysv/linux/arm/be/ld.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/ld.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __libc_stack_end D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
GLIBC_2.4 __tls_get_addr F
diff --git a/sysdeps/unix/sysv/linux/arm/le/ld.abilist b/sysdeps/unix/sysv/linux/arm/le/ld.abilist
index cc8825c3bc68ad4a..7987bbae1112aa3d 100644
--- a/sysdeps/unix/sysv/linux/arm/le/ld.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/ld.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __libc_stack_end D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
GLIBC_2.4 __tls_get_addr F
diff --git a/sysdeps/unix/sysv/linux/csky/ld.abilist b/sysdeps/unix/sysv/linux/csky/ld.abilist
index 564ac09737d6d8d5..4939b20631dc6c54 100644
--- a/sysdeps/unix/sysv/linux/csky/ld.abilist
+++ b/sysdeps/unix/sysv/linux/csky/ld.abilist
@@ -3,3 +3,4 @@ GLIBC_2.29 __stack_chk_guard D 0x4
GLIBC_2.29 __tls_get_addr F
GLIBC_2.29 _dl_mcount F
GLIBC_2.29 _r_debug D 0x14
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/hppa/ld.abilist b/sysdeps/unix/sysv/linux/hppa/ld.abilist
index d155a59843df9091..7cc9ebd792c2aadc 100644
--- a/sysdeps/unix/sysv/linux/hppa/ld.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/ld.abilist
@@ -2,4 +2,5 @@ GLIBC_2.2 __libc_stack_end D 0x4
GLIBC_2.2 _dl_mcount F
GLIBC_2.2 _r_debug D 0x14
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __stack_chk_guard D 0x4
diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist
index 0478e220712a55e6..e8d187b14d722a64 100644
--- a/sysdeps/unix/sysv/linux/i386/ld.abilist
+++ b/sysdeps/unix/sysv/linux/i386/ld.abilist
@@ -3,3 +3,4 @@ GLIBC_2.1 __libc_stack_end D 0x4
GLIBC_2.1 _dl_mcount F
GLIBC_2.3 ___tls_get_addr F
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/ia64/ld.abilist b/sysdeps/unix/sysv/linux/ia64/ld.abilist
index 33f91199bfa516fb..be5122650ae2b327 100644
--- a/sysdeps/unix/sysv/linux/ia64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/ld.abilist
@@ -2,3 +2,4 @@ GLIBC_2.2 __libc_stack_end D 0x8
GLIBC_2.2 _dl_mcount F
GLIBC_2.2 _r_debug D 0x28
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
index cc8825c3bc68ad4a..7987bbae1112aa3d 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __libc_stack_end D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
GLIBC_2.4 __tls_get_addr F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
index 3ba474c27f62fb10..4f2854edf7746958 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x14
GLIBC_2.1 __libc_stack_end D 0x4
GLIBC_2.1 _dl_mcount F
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __stack_chk_guard D 0x4
diff --git a/sysdeps/unix/sysv/linux/microblaze/ld.abilist b/sysdeps/unix/sysv/linux/microblaze/ld.abilist
index a4933c3541119538..9f0fdeca38890a34 100644
--- a/sysdeps/unix/sysv/linux/microblaze/ld.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/ld.abilist
@@ -3,3 +3,4 @@ GLIBC_2.18 __stack_chk_guard D 0x4
GLIBC_2.18 __tls_get_addr F
GLIBC_2.18 _dl_mcount F
GLIBC_2.18 _r_debug D 0x14
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
index be09641a48962434..f750067d5c34bf42 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x14
GLIBC_2.2 __libc_stack_end D 0x4
GLIBC_2.2 _dl_mcount F
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __stack_chk_guard D 0x4
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
index be09641a48962434..f750067d5c34bf42 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x14
GLIBC_2.2 __libc_stack_end D 0x4
GLIBC_2.2 _dl_mcount F
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __stack_chk_guard D 0x4
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
index 1ea36e13f294a249..2fba6a9b6ec92e47 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
@@ -2,4 +2,5 @@ GLIBC_2.0 _r_debug D 0x28
GLIBC_2.2 __libc_stack_end D 0x8
GLIBC_2.2 _dl_mcount F
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __stack_chk_guard D 0x8
diff --git a/sysdeps/unix/sysv/linux/nios2/ld.abilist b/sysdeps/unix/sysv/linux/nios2/ld.abilist
index 52178802dd82b59a..57dfad5a53b739e8 100644
--- a/sysdeps/unix/sysv/linux/nios2/ld.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/ld.abilist
@@ -3,3 +3,4 @@ GLIBC_2.21 __stack_chk_guard D 0x4
GLIBC_2.21 __tls_get_addr F
GLIBC_2.21 _dl_mcount F
GLIBC_2.21 _r_debug D 0x14
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
index 4bbfba7a61c7a5ef..e89660739262c6ab 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
@@ -4,3 +4,4 @@ GLIBC_2.1 _dl_mcount F
GLIBC_2.22 __tls_get_addr_opt F
GLIBC_2.23 __parse_hwcap_and_convert_at_platform F
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
index 283fb4510bea40ba..ce0bc639597c4bd9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
@@ -4,3 +4,4 @@ GLIBC_2.3 __libc_stack_end D 0x8
GLIBC_2.3 __tls_get_addr F
GLIBC_2.3 _dl_mcount F
GLIBC_2.3 _r_debug D 0x28
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
index b1f313c7cd33defc..65b22674d2462e96 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
@@ -4,3 +4,4 @@ GLIBC_2.17 _dl_mcount F
GLIBC_2.17 _r_debug D 0x28
GLIBC_2.22 __tls_get_addr_opt F
GLIBC_2.23 __parse_hwcap_and_convert_at_platform F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
index 94ca64c43db63b2a..5ad4c81d12d7a612 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
@@ -3,3 +3,4 @@ GLIBC_2.33 __stack_chk_guard D 0x4
GLIBC_2.33 __tls_get_addr F
GLIBC_2.33 _dl_mcount F
GLIBC_2.33 _r_debug D 0x14
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
index 845f356c3c3fad54..479efdea9bb654bb 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
@@ -3,3 +3,4 @@ GLIBC_2.27 __stack_chk_guard D 0x8
GLIBC_2.27 __tls_get_addr F
GLIBC_2.27 _dl_mcount F
GLIBC_2.27 _r_debug D 0x28
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
index b56f005bebd3baf1..d5ecb636bb792bdf 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
@@ -2,3 +2,4 @@ GLIBC_2.0 _r_debug D 0x14
GLIBC_2.1 __libc_stack_end D 0x4
GLIBC_2.1 _dl_mcount F
GLIBC_2.3 __tls_get_offset F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
index 6f788a086d68aaa5..62a5e1d99a2e6f42 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
@@ -2,3 +2,4 @@ GLIBC_2.2 __libc_stack_end D 0x8
GLIBC_2.2 _dl_mcount F
GLIBC_2.2 _r_debug D 0x28
GLIBC_2.3 __tls_get_offset F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/sh/be/ld.abilist b/sysdeps/unix/sysv/linux/sh/be/ld.abilist
index d155a59843df9091..7cc9ebd792c2aadc 100644
--- a/sysdeps/unix/sysv/linux/sh/be/ld.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/ld.abilist
@@ -2,4 +2,5 @@ GLIBC_2.2 __libc_stack_end D 0x4
GLIBC_2.2 _dl_mcount F
GLIBC_2.2 _r_debug D 0x14
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __stack_chk_guard D 0x4
diff --git a/sysdeps/unix/sysv/linux/sh/le/ld.abilist b/sysdeps/unix/sysv/linux/sh/le/ld.abilist
index d155a59843df9091..7cc9ebd792c2aadc 100644
--- a/sysdeps/unix/sysv/linux/sh/le/ld.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/ld.abilist
@@ -2,4 +2,5 @@ GLIBC_2.2 __libc_stack_end D 0x4
GLIBC_2.2 _dl_mcount F
GLIBC_2.2 _r_debug D 0x14
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.4 __stack_chk_guard D 0x4
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
index 0c6610e3c2f00cf3..2e6054349871e7d5 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
@@ -2,3 +2,4 @@ GLIBC_2.0 _r_debug D 0x14
GLIBC_2.1 __libc_stack_end D 0x4
GLIBC_2.1 _dl_mcount F
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
index 33f91199bfa516fb..be5122650ae2b327 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
@@ -2,3 +2,4 @@ GLIBC_2.2 __libc_stack_end D 0x8
GLIBC_2.2 _dl_mcount F
GLIBC_2.2 _r_debug D 0x28
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
index d3cdf7611eb9cab3..afddaec57c11f837 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
@@ -2,3 +2,4 @@ GLIBC_2.2.5 __libc_stack_end D 0x8
GLIBC_2.2.5 _dl_mcount F
GLIBC_2.2.5 _r_debug D 0x28
GLIBC_2.3 __tls_get_addr F
+GLIBC_2.34 __rtld_version_placeholder F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
index c70bccf78245a552..defc488d137c61c3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
@@ -2,3 +2,4 @@ GLIBC_2.16 __libc_stack_end D 0x4
GLIBC_2.16 __tls_get_addr F
GLIBC_2.16 _dl_mcount F
GLIBC_2.16 _r_debug D 0x14
+GLIBC_2.34 __rtld_version_placeholder F

View File

@ -0,0 +1,62 @@
commit b952c25dc7adf0684c53ad72d1d667da0348c929
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Fri Jan 14 14:48:01 2022 -0800
x86: Black list more Intel CPUs for TSX [BZ #27398]
Disable TSX and enable RTM_ALWAYS_ABORT for Intel CPUs listed in:
https://www.intel.com/content/www/us/en/support/articles/000059422/processors.html
This fixes BZ #27398.
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit 1e000d3d33211d5a954300e2a69b90f93f18a1a1)
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 645bba63147f6589..de4e3c3b7258120d 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -507,11 +507,39 @@ init_cpu_features (struct cpu_features *cpu_features)
break;
}
- /* Disable TSX on some Haswell processors to avoid TSX on kernels that
- weren't updated with the latest microcode package (which disables
- broken feature by default). */
+ /* Disable TSX on some processors to avoid TSX on kernels that
+ weren't updated with the latest microcode package (which
+ disables broken feature by default). */
switch (model)
{
+ case 0x55:
+ if (stepping <= 5)
+ goto disable_tsx;
+ break;
+ case 0x8e:
+ /* NB: Although the errata documents that for model == 0x8e,
+ only 0xb stepping or lower are impacted, the intention of
+ the errata was to disable TSX on all client processors on
+ all steppings. Include 0xc stepping which is an Intel
+ Core i7-8665U, a client mobile processor. */
+ case 0x9e:
+ if (stepping > 0xc)
+ break;
+ /* Fall through. */
+ case 0x4e:
+ case 0x5e:
+ {
+ /* Disable Intel TSX and enable RTM_ALWAYS_ABORT for
+ processors listed in:
+
+https://www.intel.com/content/www/us/en/support/articles/000059422/processors.html
+ */
+disable_tsx:
+ CPU_FEATURE_UNSET (cpu_features, HLE);
+ CPU_FEATURE_UNSET (cpu_features, RTM);
+ CPU_FEATURE_SET (cpu_features, RTM_ALWAYS_ABORT);
+ }
+ break;
case 0x3f:
/* Xeon E7 v3 with stepping >= 4 has working TSX. */
if (stepping >= 4)

View File

@ -0,0 +1,24 @@
commit aa601d024424c40ae9a69b0c4e394a70ea0570c8
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Mon Jan 24 19:33:43 2022 -0800
x86: Use CHECK_FEATURE_PRESENT to check HLE [BZ #27398]
HLE is disabled on blacklisted CPUs. Use CHECK_FEATURE_PRESENT, instead
of CHECK_FEATURE_ACTIVE, to check HLE.
(cherry picked from commit 501246c5e2dfcc278f0ebbdb72345cdd239521c7)
diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c
index 9d76e6bd3f8db024..faa5091b78431487 100644
--- a/sysdeps/x86/tst-cpu-features-supports.c
+++ b/sysdeps/x86/tst-cpu-features-supports.c
@@ -130,7 +130,7 @@ do_test (int argc, char **argv)
fails += CHECK_FEATURE_ACTIVE (gfni, GFNI);
#endif
#if __GNUC_PREREQ (11, 0)
- fails += CHECK_FEATURE_ACTIVE (hle, HLE);
+ fails += CHECK_FEATURE_PRESENT (hle, HLE);
fails += CHECK_FEATURE_PRESENT (ibt, IBT);
fails += CHECK_FEATURE_ACTIVE (lahf_lm, LAHF64_SAHF64);
fails += CHECK_FEATURE_PRESENT (lm, LM);

View File

@ -148,7 +148,7 @@ end \
Summary: The GNU libc libraries
Name: glibc
Version: %{glibcversion}
Release: 16%{?dist}
Release: 25%{?dist}
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
# libraries.
@ -287,6 +287,94 @@ Patch87: glibc-upstream-2.34-51.patch
Patch88: glibc-upstream-2.34-52.patch
Patch89: glibc-upstream-2.34-53.patch
Patch90: glibc-rh1988382.patch
Patch91: glibc-upstream-2.34-54.patch
Patch92: glibc-upstream-2.34-55.patch
Patch93: glibc-upstream-2.34-56.patch
Patch94: glibc-upstream-2.34-57.patch
Patch95: glibc-upstream-2.34-58.patch
Patch96: glibc-upstream-2.34-59.patch
Patch97: glibc-upstream-2.34-60.patch
Patch98: glibc-upstream-2.34-61.patch
Patch99: glibc-upstream-2.34-62.patch
Patch100: glibc-upstream-2.34-63.patch
Patch101: glibc-upstream-2.34-64.patch
Patch102: glibc-upstream-2.34-65.patch
Patch103: glibc-upstream-2.34-66.patch
Patch104: glibc-upstream-2.34-67.patch
Patch105: glibc-upstream-2.34-68.patch
Patch106: glibc-upstream-2.34-69.patch
Patch107: glibc-upstream-2.34-70.patch
Patch108: glibc-upstream-2.34-71.patch
Patch109: glibc-upstream-2.34-72.patch
Patch110: glibc-upstream-2.34-73.patch
Patch111: glibc-rh2032647-1.patch
Patch112: glibc-rh2032647-2.patch
Patch113: glibc-rh2032647-3.patch
Patch114: glibc-rh2032647-4.patch
Patch115: glibc-rh2032647-5.patch
Patch116: glibc-rh2032647-6.patch
Patch117: glibc-rh2024347-1.patch
Patch118: glibc-rh2024347-2.patch
Patch119: glibc-rh2024347-3.patch
Patch120: glibc-rh2024347-4.patch
Patch121: glibc-rh2024347-5.patch
Patch122: glibc-rh2024347-6.patch
Patch123: glibc-rh2024347-7.patch
Patch124: glibc-rh2024347-8.patch
Patch125: glibc-rh2024347-9.patch
Patch126: glibc-rh2024347-10.patch
Patch127: glibc-rh2024347-11.patch
Patch128: glibc-rh2024347-12.patch
Patch129: glibc-rh2024347-13.patch
Patch130: glibc-rh2040657-1.patch
Patch131: glibc-rh2040657-2.patch
Patch132: glibc-rh2040657-3.patch
Patch133: glibc-rh2040657-4.patch
Patch134: glibc-rh2040657-5.patch
Patch135: glibc-rh2040657-6.patch
Patch136: glibc-rh2040657-7.patch
Patch137: glibc-rh2040657-8.patch
Patch138: glibc-rh2040657-9.patch
Patch139: glibc-rh2040657-10.patch
Patch140: glibc-rh2040657-11.patch
Patch141: glibc-rh2040657-12.patch
Patch142: glibc-upstream-2.34-74.patch
Patch143: glibc-upstream-2.34-75.patch
Patch144: glibc-upstream-2.34-76.patch
Patch145: glibc-upstream-2.34-77.patch
Patch146: glibc-upstream-2.34-78.patch
Patch147: glibc-upstream-2.34-79.patch
Patch148: glibc-upstream-2.34-80.patch
Patch149: glibc-upstream-2.34-81.patch
Patch150: glibc-upstream-2.34-82.patch
Patch151: glibc-upstream-2.34-83.patch
Patch152: glibc-upstream-2.34-84.patch
Patch153: glibc-upstream-2.34-85.patch
Patch154: glibc-upstream-2.34-86.patch
Patch155: glibc-upstream-2.34-87.patch
Patch156: glibc-upstream-2.34-88.patch
Patch157: glibc-upstream-2.34-89.patch
# glibc-2.34-90-g1b9cd6a721 only changes NEWS.
Patch158: glibc-upstream-2.34-91.patch
Patch159: glibc-upstream-2.34-92.patch
# glibc-2.34-93-g72123e1b56 only changes NEWS.
# glibc-2.34-94-g31186e2cb7 is glibc-rh2040657-1.patch.
# glibc-2.34-95-g511b244cc5 is glibc-rh2040657-2.patch.
# glibc-2.34-96-gde6cdd6875 is glibc-rh2040657-6.patch.
Patch160: glibc-upstream-2.34-97.patch
Patch161: glibc-upstream-2.34-98.patch
Patch162: glibc-upstream-2.34-99.patch
Patch163: glibc-c-utf8-locale-3.patch
Patch164: glibc-c-utf8-locale-4.patch
Patch165: glibc-c-utf8-locale-5.patch
Patch166: glibc-upstream-2.34-100.patch
Patch167: glibc-upstream-2.34-101.patch
Patch168: glibc-upstream-2.34-102.patch
Patch169: glibc-upstream-2.34-103.patch
Patch170: glibc-upstream-2.34-104.patch
Patch171: glibc-upstream-2.34-105.patch
Patch172: glibc-upstream-2.34-106.patch
Patch173: glibc-upstream-2.34-107.patch
##############################################################################
# Continued list of core "glibc" package information:
@ -1203,6 +1291,20 @@ rpm_inherit_flags \
"-mtune=zEC12" \
"-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1" \
# Use the RHEL 8 baseline for the early dynamic loader code, so that
# running on too old CPUs results in a diagnostic.
%if 0%{?rhel} >= 9
%ifarch ppc64le
%define glibc_rtld_early_cflags -mcpu=power8
%endif
%ifarch s390x
%define glibc_rtld_early_cflags -march=z13
%endif
%ifarch x86_64
%define glibc_rtld_early_cflags -march=x86-64
%endif
%endif
# libc_nonshared.a cannot be built with the default hardening flags
# because the glibc build system is incompatible with
# -D_FORTIFY_SOURCE. The object files need to be marked as to be
@ -1249,6 +1351,7 @@ build()
--enable-tunables \
--enable-systemtap \
${core_with_options} \
%{?glibc_rtld_early_cflags:--with-rtld-early-cflags=%glibc_rtld_early_cflags} \
%ifarch x86_64 %{ix86}
--enable-cet \
%endif
@ -2315,6 +2418,87 @@ fi
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
%changelog
* Thu Feb 3 2022 Florian Weimer <fweimer@redhat.com> - 2.34-25
- Sync with upstream branch release/2.34/master,
commit 6eaf10cbb78d22eae7999d9de55f6b93999e0860:
- socket: Do not use AF_NETLINK in __opensock
- hurd if_index: Explicitly use AF_INET for if index discovery
- Linux: Simplify __opensock and fix race condition [BZ #28353]
- linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage [BZ #28850]
* Tue Feb 1 2022 Florian Weimer <fweimer@redhat.com> - 2.34-24
- Sync with upstream branch release/2.34/master,
commit 008003dc6e83439c5e04a744b7fd8197df19096e:
- tst-socket-timestamp-compat.c: Check __TIMESIZE [BZ #28837]
- Linux: Only generate 64 bit timestamps for 64 bit time_t recvmsg/recvmmsg
- linux: Fix ancillary 64-bit time timestamp conversion (BZ #28349, BZ#28350)
- support: Add support_socket_so_timestamp_time64
* Tue Feb 1 2022 Florian Weimer <fweimer@redhat.com> - 2.34-23
- Align with glibc 2.35 version of C.UTF-8
* Tue Feb 1 2022 Florian Weimer <fweimer@redhat.com> - 2.34-22
- Sync with upstream branch release/2.34/master,
commit aa601d024424c40ae9a69b0c4e394a70ea0570c8:
- x86: Use CHECK_FEATURE_PRESENT to check HLE [BZ #27398]
- x86: Filter out more Intel CPUs for TSX [BZ #27398]
- Fix glibc 2.34 ABI omission (missing GLIBC_2.34 in dynamic loader)
- x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755]
- x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755]
* Mon Jan 24 2022 Florian Weimer <fweimer@redhat.com> - 2.34-21
- Sync with upstream branch release/2.34/master,
commit 3438bbca90895d32825a52e31a77dc44d273c1c1:
- Linux: Detect user namespace support in io/tst-getcwd-smallbuff
- realpath: Avoid overwriting preexisting error
- CVE-2021-3999: getcwd: Set errno to ERANGE for size == 1
- tst-realpath-toolong: Fix hurd build
- CVE-2021-3998: realpath: ENAMETOOLONG for result larger than PATH_MAX
- stdlib: Fix formatting of tests list in Makefile
- stdlib: Sort tests in Makefile
- support: Add helpers to create paths longer than PATH_MAX
- powerpc: Fix unrecognized instruction errors with recent binutils
- x86: use default cache size if it cannot be determined [BZ #28784]
- CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768)
- sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542)
- CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542)
- socket: Add the __sockaddr_un_set function
- Disable debuginfod in printer tests [BZ #28757]
- Update syscall lists for Linux 5.16
* Wed Jan 19 2022 Florian Weimer <fweimer@redhat.com> - 2.34-20
- More reliable CPU compatibility diagnostics (#2040657)
* Fri Jan 14 2022 Florian Weimer <fweimer@redhat.com> - 2.34-19
- Optionally accelerate sched_getcpu using rseq (#2024347)
* Thu Jan 13 2022 Florian Weimer <fweimer@redhat.com> - 2.34-18
- Backport optimized ELF dependency sorting algorithm (#2032647)
* Thu Jan 13 2022 Florian Weimer <fweimer@redhat.com> - 2.34-17
- Sync with upstream branch release/2.34/master,
commit 2fe2af88abd13ae5636881da2e26f461ecb7dfb5
- i386: Remove broken CAN_USE_REGISTER_ASM_EBP (bug 28771)
- Update syscall lists for Linux 5.15
- powerpc: Fix unrecognized instruction errors with recent GCC
- timezone: test-case for BZ #28707
- timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707)
- Fix subscript error with odd TZif file [BZ #28338]
- AArch64: Check for SVE in ifuncs [BZ #28744]
- intl/plural.y: Avoid conflicting declarations of yyerror and yylex
- Linux: Fix 32-bit vDSO for clock_gettime on powerpc32
- linux: Add sparck brk implementation
- Update sparc libm-test-ulps
- Update hppa libm-test-ulps
- riscv: align stack before calling _dl_init [BZ #28703]
- riscv: align stack in clone [BZ #28702]
- powerpc64[le]: Allocate extra stack frame on syscall.S
- elf: Fix tst-cpu-features-cpuinfo for KVM guests on some AMD systems [BZ #28704]
- nss: Use "files dns" as the default for the hosts database (bug 28700)
- arm: Guard ucontext _rtld_global_ro access by SHARED, not PIC macro
- mips: increase stack alignment in clone to match the ABI
- mips: align stack in clone [BZ #28223]
* Tue Dec 14 2021 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.34-16
- Enable PIE by default on all architectures (#1988382)