Import glibc-2.34-24.fc35 from f35

* 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]

Resolves: #2037056
This commit is contained in:
Florian Weimer 2022-02-01 21:15:30 +01:00
parent db9712052c
commit 234a1c0ad2
13 changed files with 3081 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)
{

734
glibc-c-utf8-locale-4.patch Normal file
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>

691
glibc-c-utf8-locale-5.patch Normal file
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,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,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: 21%{?dist}
Release: 24%{?dist}
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
# libraries.
@ -354,6 +354,23 @@ 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
##############################################################################
# Continued list of core "glibc" package information:
@ -2397,6 +2414,26 @@ fi
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
%changelog
* 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: