From 234a1c0ad2aeac75515a6e6c788d04c36e0fa20b Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Tue, 1 Feb 2022 21:15:30 +0100 Subject: [PATCH] Import glibc-2.34-24.fc35 from f35 * Tue Feb 1 2022 Florian Weimer - 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 - 2.34-23 - Align with glibc 2.35 version of C.UTF-8 * Tue Feb 1 2022 Florian Weimer - 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 --- glibc-c-utf8-locale-3.patch | 65 +++ glibc-c-utf8-locale-4.patch | 734 ++++++++++++++++++++++++++++++++++ glibc-c-utf8-locale-5.patch | 691 ++++++++++++++++++++++++++++++++ glibc-upstream-2.34-100.patch | 95 +++++ glibc-upstream-2.34-101.patch | 431 ++++++++++++++++++++ glibc-upstream-2.34-102.patch | 485 ++++++++++++++++++++++ glibc-upstream-2.34-103.patch | 24 ++ glibc-upstream-2.34-91.patch | 36 ++ glibc-upstream-2.34-92.patch | 36 ++ glibc-upstream-2.34-97.patch | 360 +++++++++++++++++ glibc-upstream-2.34-98.patch | 62 +++ glibc-upstream-2.34-99.patch | 24 ++ glibc.spec | 39 +- 13 files changed, 3081 insertions(+), 1 deletion(-) create mode 100644 glibc-c-utf8-locale-3.patch create mode 100644 glibc-c-utf8-locale-4.patch create mode 100644 glibc-c-utf8-locale-5.patch create mode 100644 glibc-upstream-2.34-100.patch create mode 100644 glibc-upstream-2.34-101.patch create mode 100644 glibc-upstream-2.34-102.patch create mode 100644 glibc-upstream-2.34-103.patch create mode 100644 glibc-upstream-2.34-91.patch create mode 100644 glibc-upstream-2.34-92.patch create mode 100644 glibc-upstream-2.34-97.patch create mode 100644 glibc-upstream-2.34-98.patch create mode 100644 glibc-upstream-2.34-99.patch diff --git a/glibc-c-utf8-locale-3.patch b/glibc-c-utf8-locale-3.patch new file mode 100644 index 0000000..3a90a47 --- /dev/null +++ b/glibc-c-utf8-locale-3.patch @@ -0,0 +1,65 @@ +commit 1d8e3a2c6636cf0b1b8fa2f869cef6ec10726933 +Author: Carlos O'Donell +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 + +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) + { diff --git a/glibc-c-utf8-locale-4.patch b/glibc-c-utf8-locale-4.patch new file mode 100644 index 0000000..8e9ec4c --- /dev/null +++ b/glibc-c-utf8-locale-4.patch @@ -0,0 +1,734 @@ +commit de82cb0da4b8fa5b3d56c457438d2568c67ab1b1 +Author: Joseph Myers +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 ++#include + + __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 + . */ + +-#include +-#include ++#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 ++ . */ ++ ++#include ++#include ++ ++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 ++ . */ ++ ++#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 + . */ + +-#include +-#include +-#include +-#include +-#include +-#include +- +-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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 ++ . */ ++ ++#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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++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 +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 ++ . */ ++ ++#include ++#include ++#include ++ ++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 diff --git a/glibc-c-utf8-locale-5.patch b/glibc-c-utf8-locale-5.patch new file mode 100644 index 0000000..06144a4 --- /dev/null +++ b/glibc-c-utf8-locale-5.patch @@ -0,0 +1,691 @@ +commit 7e0ad15c0fbfe25435c1acd0ed3e9cedfbff2488 +Author: Carlos O'Donell +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 + Reviewed-by: Florian Weimer + +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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* 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 diff --git a/glibc-upstream-2.34-100.patch b/glibc-upstream-2.34-100.patch new file mode 100644 index 0000000..d797f77 --- /dev/null +++ b/glibc-upstream-2.34-100.patch @@ -0,0 +1,95 @@ +commit e09e7b1492b2d5c2f68ddf81f8f58e093dd4df6d +Author: Adhemerval Zanella +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 + + (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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#ifdef __linux__ ++# include ++#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 ++} diff --git a/glibc-upstream-2.34-101.patch b/glibc-upstream-2.34-101.patch new file mode 100644 index 0000000..b318a81 --- /dev/null +++ b/glibc-upstream-2.34-101.patch @@ -0,0 +1,431 @@ +commit e098446037da532d4a250efac9a813bc22f3669f +Author: Adhemerval Zanella +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 + + Reviewed-by: Florian Weimer + + (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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* 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 diff --git a/glibc-upstream-2.34-102.patch b/glibc-upstream-2.34-102.patch new file mode 100644 index 0000000..928856e --- /dev/null +++ b/glibc-upstream-2.34-102.patch @@ -0,0 +1,485 @@ +commit 489d0b8b32548bc569cd3067aebf98b030720753 +Author: Adhemerval Zanella +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 + + (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 + #include + +-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 + #include + ++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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* 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 diff --git a/glibc-upstream-2.34-103.patch b/glibc-upstream-2.34-103.patch new file mode 100644 index 0000000..1605e95 --- /dev/null +++ b/glibc-upstream-2.34-103.patch @@ -0,0 +1,24 @@ +commit 008003dc6e83439c5e04a744b7fd8197df19096e +Author: H.J. Lu +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); diff --git a/glibc-upstream-2.34-91.patch b/glibc-upstream-2.34-91.patch new file mode 100644 index 0000000..f577e34 --- /dev/null +++ b/glibc-upstream-2.34-91.patch @@ -0,0 +1,36 @@ +commit b50d5b746cc0af5ad52164dcb0d3628f08b05a0d +Author: Noah Goldstein +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 + (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 diff --git a/glibc-upstream-2.34-92.patch b/glibc-upstream-2.34-92.patch new file mode 100644 index 0000000..03a51c6 --- /dev/null +++ b/glibc-upstream-2.34-92.patch @@ -0,0 +1,36 @@ +commit 08beb3a3f4f46e306fffe184a08c5664bf0e13d6 +Author: Noah Goldstein +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 + (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 diff --git a/glibc-upstream-2.34-97.patch b/glibc-upstream-2.34-97.patch new file mode 100644 index 0000000..e9adea4 --- /dev/null +++ b/glibc-upstream-2.34-97.patch @@ -0,0 +1,360 @@ +commit 948ebc098ed3cd928ea10997f990115e7770bda3 +Author: Florian Weimer +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 + (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 ++ . */ ++ ++#include ++#include ++ ++/* 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 diff --git a/glibc-upstream-2.34-98.patch b/glibc-upstream-2.34-98.patch new file mode 100644 index 0000000..adbb154 --- /dev/null +++ b/glibc-upstream-2.34-98.patch @@ -0,0 +1,62 @@ +commit b952c25dc7adf0684c53ad72d1d667da0348c929 +Author: H.J. Lu +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 + (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) diff --git a/glibc-upstream-2.34-99.patch b/glibc-upstream-2.34-99.patch new file mode 100644 index 0000000..7df75d8 --- /dev/null +++ b/glibc-upstream-2.34-99.patch @@ -0,0 +1,24 @@ +commit aa601d024424c40ae9a69b0c4e394a70ea0570c8 +Author: H.J. Lu +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); diff --git a/glibc.spec b/glibc.spec index 2677cb3..654c2d2 100644 --- a/glibc.spec +++ b/glibc.spec @@ -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 - 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 - 2.34-23 +- Align with glibc 2.35 version of C.UTF-8 + +* Tue Feb 1 2022 Florian Weimer - 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 - 2.34-21 - Sync with upstream branch release/2.34/master, commit 3438bbca90895d32825a52e31a77dc44d273c1c1: