From bdfe163f816ce4a9f88ec774f4fc9c9bba89ac75 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 1 Mar 2022 08:08:09 -0500 Subject: [PATCH] import glibc-2.34-25.el9 --- SOURCES/glibc-c-utf8-locale-3.patch | 65 + SOURCES/glibc-c-utf8-locale-4.patch | 734 +++++++++ SOURCES/glibc-c-utf8-locale-5.patch | 691 +++++++++ SOURCES/glibc-rh2024347-1.patch | 98 ++ SOURCES/glibc-rh2024347-10.patch | 74 + SOURCES/glibc-rh2024347-11.patch | 592 ++++++++ SOURCES/glibc-rh2024347-12.patch | 73 + SOURCES/glibc-rh2024347-13.patch | 42 + SOURCES/glibc-rh2024347-2.patch | 259 ++++ SOURCES/glibc-rh2024347-3.patch | 150 ++ SOURCES/glibc-rh2024347-4.patch | 130 ++ SOURCES/glibc-rh2024347-5.patch | 904 +++++++++++ SOURCES/glibc-rh2024347-6.patch | 49 + SOURCES/glibc-rh2024347-7.patch | 1130 ++++++++++++++ SOURCES/glibc-rh2024347-8.patch | 43 + SOURCES/glibc-rh2024347-9.patch | 278 ++++ SOURCES/glibc-rh2032647-1.patch | 2024 +++++++++++++++++++++++++ SOURCES/glibc-rh2032647-2.patch | 585 +++++++ SOURCES/glibc-rh2032647-3.patch | 25 + SOURCES/glibc-rh2032647-4.patch | 189 +++ SOURCES/glibc-rh2032647-5.patch | 45 + SOURCES/glibc-rh2032647-6.patch | 49 + SOURCES/glibc-rh2040657-1.patch | 547 +++++++ SOURCES/glibc-rh2040657-10.patch | 73 + SOURCES/glibc-rh2040657-11.patch | 37 + SOURCES/glibc-rh2040657-12.patch | 158 ++ SOURCES/glibc-rh2040657-2.patch | 42 + SOURCES/glibc-rh2040657-3.patch | 171 +++ SOURCES/glibc-rh2040657-4.patch | 58 + SOURCES/glibc-rh2040657-5.patch | 32 + SOURCES/glibc-rh2040657-6.patch | 549 +++++++ SOURCES/glibc-rh2040657-7.patch | 633 ++++++++ SOURCES/glibc-rh2040657-8.patch | 146 ++ SOURCES/glibc-rh2040657-9.patch | 52 + SOURCES/glibc-upstream-2.34-100.patch | 95 ++ SOURCES/glibc-upstream-2.34-101.patch | 431 ++++++ SOURCES/glibc-upstream-2.34-102.patch | 485 ++++++ SOURCES/glibc-upstream-2.34-103.patch | 24 + SOURCES/glibc-upstream-2.34-104.patch | 26 + SOURCES/glibc-upstream-2.34-105.patch | 234 +++ SOURCES/glibc-upstream-2.34-106.patch | 44 + SOURCES/glibc-upstream-2.34-107.patch | 35 + SOURCES/glibc-upstream-2.34-54.patch | 32 + SOURCES/glibc-upstream-2.34-55.patch | 37 + SOURCES/glibc-upstream-2.34-56.patch | 65 + SOURCES/glibc-upstream-2.34-57.patch | 74 + SOURCES/glibc-upstream-2.34-58.patch | 35 + SOURCES/glibc-upstream-2.34-59.patch | 35 + SOURCES/glibc-upstream-2.34-60.patch | 32 + SOURCES/glibc-upstream-2.34-61.patch | 34 + SOURCES/glibc-upstream-2.34-62.patch | 21 + SOURCES/glibc-upstream-2.34-63.patch | 21 + SOURCES/glibc-upstream-2.34-64.patch | 81 + SOURCES/glibc-upstream-2.34-65.patch | 33 + SOURCES/glibc-upstream-2.34-66.patch | 37 + SOURCES/glibc-upstream-2.34-67.patch | 50 + SOURCES/glibc-upstream-2.34-68.patch | 27 + SOURCES/glibc-upstream-2.34-69.patch | 52 + SOURCES/glibc-upstream-2.34-70.patch | 130 ++ SOURCES/glibc-upstream-2.34-71.patch | 39 + SOURCES/glibc-upstream-2.34-72.patch | 377 +++++ SOURCES/glibc-upstream-2.34-73.patch | 442 ++++++ SOURCES/glibc-upstream-2.34-74.patch | 337 ++++ SOURCES/glibc-upstream-2.34-75.patch | 53 + SOURCES/glibc-upstream-2.34-76.patch | 165 ++ SOURCES/glibc-upstream-2.34-77.patch | 33 + SOURCES/glibc-upstream-2.34-78.patch | 82 + SOURCES/glibc-upstream-2.34-79.patch | 102 ++ SOURCES/glibc-upstream-2.34-80.patch | 56 + SOURCES/glibc-upstream-2.34-81.patch | 64 + SOURCES/glibc-upstream-2.34-82.patch | 276 ++++ SOURCES/glibc-upstream-2.34-83.patch | 121 ++ SOURCES/glibc-upstream-2.34-84.patch | 173 +++ SOURCES/glibc-upstream-2.34-85.patch | 109 ++ SOURCES/glibc-upstream-2.34-86.patch | 26 + SOURCES/glibc-upstream-2.34-87.patch | 329 ++++ SOURCES/glibc-upstream-2.34-88.patch | 28 + SOURCES/glibc-upstream-2.34-89.patch | 47 + SOURCES/glibc-upstream-2.34-91.patch | 36 + SOURCES/glibc-upstream-2.34-92.patch | 36 + SOURCES/glibc-upstream-2.34-97.patch | 360 +++++ SOURCES/glibc-upstream-2.34-98.patch | 62 + SOURCES/glibc-upstream-2.34-99.patch | 24 + SPECS/glibc.spec | 186 ++- 84 files changed, 16459 insertions(+), 1 deletion(-) create mode 100644 SOURCES/glibc-c-utf8-locale-3.patch create mode 100644 SOURCES/glibc-c-utf8-locale-4.patch create mode 100644 SOURCES/glibc-c-utf8-locale-5.patch create mode 100644 SOURCES/glibc-rh2024347-1.patch create mode 100644 SOURCES/glibc-rh2024347-10.patch create mode 100644 SOURCES/glibc-rh2024347-11.patch create mode 100644 SOURCES/glibc-rh2024347-12.patch create mode 100644 SOURCES/glibc-rh2024347-13.patch create mode 100644 SOURCES/glibc-rh2024347-2.patch create mode 100644 SOURCES/glibc-rh2024347-3.patch create mode 100644 SOURCES/glibc-rh2024347-4.patch create mode 100644 SOURCES/glibc-rh2024347-5.patch create mode 100644 SOURCES/glibc-rh2024347-6.patch create mode 100644 SOURCES/glibc-rh2024347-7.patch create mode 100644 SOURCES/glibc-rh2024347-8.patch create mode 100644 SOURCES/glibc-rh2024347-9.patch create mode 100644 SOURCES/glibc-rh2032647-1.patch create mode 100644 SOURCES/glibc-rh2032647-2.patch create mode 100644 SOURCES/glibc-rh2032647-3.patch create mode 100644 SOURCES/glibc-rh2032647-4.patch create mode 100644 SOURCES/glibc-rh2032647-5.patch create mode 100644 SOURCES/glibc-rh2032647-6.patch create mode 100644 SOURCES/glibc-rh2040657-1.patch create mode 100644 SOURCES/glibc-rh2040657-10.patch create mode 100644 SOURCES/glibc-rh2040657-11.patch create mode 100644 SOURCES/glibc-rh2040657-12.patch create mode 100644 SOURCES/glibc-rh2040657-2.patch create mode 100644 SOURCES/glibc-rh2040657-3.patch create mode 100644 SOURCES/glibc-rh2040657-4.patch create mode 100644 SOURCES/glibc-rh2040657-5.patch create mode 100644 SOURCES/glibc-rh2040657-6.patch create mode 100644 SOURCES/glibc-rh2040657-7.patch create mode 100644 SOURCES/glibc-rh2040657-8.patch create mode 100644 SOURCES/glibc-rh2040657-9.patch create mode 100644 SOURCES/glibc-upstream-2.34-100.patch create mode 100644 SOURCES/glibc-upstream-2.34-101.patch create mode 100644 SOURCES/glibc-upstream-2.34-102.patch create mode 100644 SOURCES/glibc-upstream-2.34-103.patch create mode 100644 SOURCES/glibc-upstream-2.34-104.patch create mode 100644 SOURCES/glibc-upstream-2.34-105.patch create mode 100644 SOURCES/glibc-upstream-2.34-106.patch create mode 100644 SOURCES/glibc-upstream-2.34-107.patch create mode 100644 SOURCES/glibc-upstream-2.34-54.patch create mode 100644 SOURCES/glibc-upstream-2.34-55.patch create mode 100644 SOURCES/glibc-upstream-2.34-56.patch create mode 100644 SOURCES/glibc-upstream-2.34-57.patch create mode 100644 SOURCES/glibc-upstream-2.34-58.patch create mode 100644 SOURCES/glibc-upstream-2.34-59.patch create mode 100644 SOURCES/glibc-upstream-2.34-60.patch create mode 100644 SOURCES/glibc-upstream-2.34-61.patch create mode 100644 SOURCES/glibc-upstream-2.34-62.patch create mode 100644 SOURCES/glibc-upstream-2.34-63.patch create mode 100644 SOURCES/glibc-upstream-2.34-64.patch create mode 100644 SOURCES/glibc-upstream-2.34-65.patch create mode 100644 SOURCES/glibc-upstream-2.34-66.patch create mode 100644 SOURCES/glibc-upstream-2.34-67.patch create mode 100644 SOURCES/glibc-upstream-2.34-68.patch create mode 100644 SOURCES/glibc-upstream-2.34-69.patch create mode 100644 SOURCES/glibc-upstream-2.34-70.patch create mode 100644 SOURCES/glibc-upstream-2.34-71.patch create mode 100644 SOURCES/glibc-upstream-2.34-72.patch create mode 100644 SOURCES/glibc-upstream-2.34-73.patch create mode 100644 SOURCES/glibc-upstream-2.34-74.patch create mode 100644 SOURCES/glibc-upstream-2.34-75.patch create mode 100644 SOURCES/glibc-upstream-2.34-76.patch create mode 100644 SOURCES/glibc-upstream-2.34-77.patch create mode 100644 SOURCES/glibc-upstream-2.34-78.patch create mode 100644 SOURCES/glibc-upstream-2.34-79.patch create mode 100644 SOURCES/glibc-upstream-2.34-80.patch create mode 100644 SOURCES/glibc-upstream-2.34-81.patch create mode 100644 SOURCES/glibc-upstream-2.34-82.patch create mode 100644 SOURCES/glibc-upstream-2.34-83.patch create mode 100644 SOURCES/glibc-upstream-2.34-84.patch create mode 100644 SOURCES/glibc-upstream-2.34-85.patch create mode 100644 SOURCES/glibc-upstream-2.34-86.patch create mode 100644 SOURCES/glibc-upstream-2.34-87.patch create mode 100644 SOURCES/glibc-upstream-2.34-88.patch create mode 100644 SOURCES/glibc-upstream-2.34-89.patch create mode 100644 SOURCES/glibc-upstream-2.34-91.patch create mode 100644 SOURCES/glibc-upstream-2.34-92.patch create mode 100644 SOURCES/glibc-upstream-2.34-97.patch create mode 100644 SOURCES/glibc-upstream-2.34-98.patch create mode 100644 SOURCES/glibc-upstream-2.34-99.patch diff --git a/SOURCES/glibc-c-utf8-locale-3.patch b/SOURCES/glibc-c-utf8-locale-3.patch new file mode 100644 index 0000000..3a90a47 --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-c-utf8-locale-4.patch b/SOURCES/glibc-c-utf8-locale-4.patch new file mode 100644 index 0000000..8e9ec4c --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-c-utf8-locale-5.patch b/SOURCES/glibc-c-utf8-locale-5.patch new file mode 100644 index 0000000..06144a4 --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-rh2024347-1.patch b/SOURCES/glibc-rh2024347-1.patch new file mode 100644 index 0000000..1c18bfa --- /dev/null +++ b/SOURCES/glibc-rh2024347-1.patch @@ -0,0 +1,98 @@ +commit 84a7eb1f87c1d01b58ad887a0ab5d87abbc1c772 +Author: H.J. Lu +Date: Fri Jul 30 19:07:30 2021 -0700 + + Use __executable_start as the lowest address for profiling [BZ #28153] + + Glibc assumes that ENTRY_POINT is the lowest address for which we need + to keep profiling records and BFD linker uses a linker script to place + the input sections. + + Starting from GCC 4.6, the main function is placed in .text.startup + section and starting from binutils 2.22, BFD linker with + + commit add44f8d5c5c05e08b11e033127a744d61c26aee + Author: Alan Modra + Date: Thu Nov 25 03:03:02 2010 +0000 + + * scripttempl/elf.sc: Group .text.exit, text.startup and .text.hot + sections. + + places .text.startup section before .text section, which leave the main + function out of profiling records. + + Starting from binutils 2.15, linker provides __executable_start to mark + the lowest address of the executable. Use __executable_start as the + lowest address to keep the main function in profiling records. This fixes + [BZ #28153]. + + Tested on Linux/x86-64, Linux/x32 and Linux/i686 as well as with + build-many-glibcs.py. + +diff --git a/csu/gmon-start.c b/csu/gmon-start.c +index b3432885b39071cc..344606a676c188d4 100644 +--- a/csu/gmon-start.c ++++ b/csu/gmon-start.c +@@ -52,6 +52,11 @@ extern char ENTRY_POINT[]; + #endif + extern char etext[]; + ++/* Use __executable_start as the lowest address to keep profiling records ++ if it provided by the linker. */ ++extern const char executable_start[] asm ("__executable_start") ++ __attribute__ ((weak, visibility ("hidden"))); ++ + #ifndef TEXT_START + # ifdef ENTRY_POINT_DECL + # define TEXT_START ENTRY_POINT +@@ -92,7 +97,10 @@ __gmon_start__ (void) + called = 1; + + /* Start keeping profiling records. */ +- __monstartup ((u_long) TEXT_START, (u_long) &etext); ++ if (&executable_start != NULL) ++ __monstartup ((u_long) &executable_start, (u_long) &etext); ++ else ++ __monstartup ((u_long) TEXT_START, (u_long) &etext); + + /* Call _mcleanup before exiting; it will write out gmon.out from the + collected data. */ +diff --git a/gmon/tst-gmon-gprof.sh b/gmon/tst-gmon-gprof.sh +index 9d371582b99677fa..dc0be021104f725d 100644 +--- a/gmon/tst-gmon-gprof.sh ++++ b/gmon/tst-gmon-gprof.sh +@@ -39,12 +39,14 @@ trap cleanup 0 + cat > "$expected" < "$expected_dot" < "$expected" < "$expected_dot" < +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: rseq failure after registration on main thread is fatal + + This simplifies the application programming model. + + Browser sandboxes have already been fixed: + + Sandbox is incompatible with rseq registration + + + Allow rseq in the Linux sandboxes. r=gcp + + + Sandbox needs to support rseq system call + + + Linux sandbox: Allow rseq(2) + + + Reviewed-by: Szabolcs Nagy + +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index f405fa356c2955ce..109c5e3dc78c9aa2 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -371,7 +371,8 @@ start_thread (void *arg) + /* Register rseq TLS to the kernel. */ + { + bool do_rseq = THREAD_GETMEM (pd, flags) & ATTR_FLAG_DO_RSEQ; +- rseq_register_current_thread (pd, do_rseq); ++ if (!rseq_register_current_thread (pd, do_rseq) && do_rseq) ++ __libc_fatal ("Fatal glibc error: rseq registration failed\n"); + } + + #ifndef __ASSUME_SET_ROBUST_LIST +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index 15bc7ffd6eda632d..6a3441f2cc49e7c4 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -26,7 +26,7 @@ + #include + + #ifdef RSEQ_SIG +-static inline void ++static inline bool + rseq_register_current_thread (struct pthread *self, bool do_rseq) + { + if (do_rseq) +@@ -35,15 +35,17 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq) + sizeof (self->rseq_area), + 0, RSEQ_SIG); + if (!INTERNAL_SYSCALL_ERROR_P (ret)) +- return; ++ return true; + } + THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++ return false; + } + #else /* RSEQ_SIG */ + static inline void + rseq_register_current_thread (struct pthread *self, bool do_rseq) + { + THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++ return false; + } + #endif /* RSEQ_SIG */ + diff --git a/SOURCES/glibc-rh2024347-11.patch b/SOURCES/glibc-rh2024347-11.patch new file mode 100644 index 0000000..3060a51 --- /dev/null +++ b/SOURCES/glibc-rh2024347-11.patch @@ -0,0 +1,592 @@ +commit 627f5ede70d70c77bdaf857db07404e8bf7f60af +Author: Florian Weimer +Date: Thu Dec 9 17:57:11 2021 +0100 + + Remove TLS_TCB_ALIGN and TLS_INIT_TCB_ALIGN + + TLS_INIT_TCB_ALIGN is not actually used. TLS_TCB_ALIGN was likely + introduced to support a configuration where the thread pointer + has not the same alignment as THREAD_SELF. Only ia64 seems to use + that, but for the stack/pointer guard, not for storing tcbhead_t. + Some ports use TLS_TCB_OFFSET and TLS_PRE_TCB_SIZE to shift + the thread pointer, potentially landing in a different residue class + modulo the alignment, but the changes should not impact that. + + In general, given that TLS variables have their own alignment + requirements, having different alignment for the (unshifted) thread + pointer and struct pthread would potentially result in dynamic + offsets, leading to more complexity. + + hppa had different values before: __alignof__ (tcbhead_t), which + seems to be 4, and __alignof__ (struct pthread), which was 8 + (old default) and is now 32. However, it defines THREAD_SELF as: + + /* Return the thread descriptor for the current thread. */ + # define THREAD_SELF \ + ({ struct pthread *__self; \ + __self = __get_cr27(); \ + __self - 1; \ + }) + + So the thread pointer points after struct pthread (hence __self - 1), + and they have to have the same alignment on hppa as well. + + Similarly, on ia64, the definitions were different. We have: + + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ + + (PTHREAD_STRUCT_END_PADDING < 2 * sizeof (uintptr_t) \ + ? ((2 * sizeof (uintptr_t) + __alignof__ (struct pthread) - 1) \ + & ~(__alignof__ (struct pthread) - 1)) \ + : 0)) + # define THREAD_SELF \ + ((struct pthread *) ((char *) __thread_self - TLS_PRE_TCB_SIZE)) + + And TLS_PRE_TCB_SIZE is a multiple of the struct pthread alignment + (confirmed by the new _Static_assert in sysdeps/ia64/libc-tls.c). + + On m68k, we have a larger gap between tcbhead_t and struct pthread. + But as far as I can tell, the port is fine with that. The definition + of TCB_OFFSET is sufficient to handle the shifted TCB scenario. + + This fixes commit 23c77f60181eb549f11ec2f913b4270af29eee38 + ("nptl: Increase default TCB alignment to 32"). + + Reviewed-by: H.J. Lu + +diff --git a/csu/libc-tls.c b/csu/libc-tls.c +index 5515204863218163..d83e69f6257ae981 100644 +--- a/csu/libc-tls.c ++++ b/csu/libc-tls.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #ifdef SHARED + #error makefile bug, this file is for static only +@@ -89,7 +90,7 @@ init_static_tls (size_t memsz, size_t align) + { + /* That is the size of the TLS memory for this object. */ + GL(dl_tls_static_size) = roundup (memsz + GLRO(dl_tls_static_surplus), +- TLS_TCB_ALIGN); ++ TCB_ALIGNMENT); + #if TLS_TCB_AT_TP + GL(dl_tls_static_size) += TLS_TCB_SIZE; + #endif +@@ -214,5 +215,5 @@ __libc_setup_tls (void) + memsz += tcb_offset; + #endif + +- init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align)); ++ init_static_tls (memsz, MAX (TCB_ALIGNMENT, max_align)); + } +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index 40263cf586e74c64..e2012d0cd515103b 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -219,7 +219,7 @@ _dl_count_modids (void) + void + _dl_determine_tlsoffset (void) + { +- size_t max_align = TLS_TCB_ALIGN; ++ size_t max_align = TCB_ALIGNMENT; + size_t freetop = 0; + size_t freebottom = 0; + +@@ -350,7 +350,7 @@ _dl_determine_tlsoffset (void) + + GL(dl_tls_static_used) = offset; + GLRO (dl_tls_static_size) = roundup (offset + GLRO(dl_tls_static_surplus), +- TLS_TCB_ALIGN); ++ TCB_ALIGNMENT); + #else + # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" + #endif +diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h +index cd9abb5d1d073593..75c469d51b532a89 100644 +--- a/sysdeps/aarch64/nptl/tls.h ++++ b/sysdeps/aarch64/nptl/tls.h +@@ -52,18 +52,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(tcbp, dtvp) \ +diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h +index 5f4843b28e7f1ad1..c0b6c93891546480 100644 +--- a/sysdeps/alpha/nptl/tls.h ++++ b/sysdeps/alpha/nptl/tls.h +@@ -46,18 +46,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN 16 +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN 16 +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(tcbp, dtvp) \ +diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h +index d9ada2f38089e6cd..d5d282297d12ec98 100644 +--- a/sysdeps/arc/nptl/tls.h ++++ b/sysdeps/arc/nptl/tls.h +@@ -48,17 +48,11 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + #ifndef TLS_TCB_SIZE + # define TLS_TCB_SIZE sizeof (tcbhead_t) + #endif + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h +index 354aae3318291395..8475c66588f99cae 100644 +--- a/sysdeps/arm/nptl/tls.h ++++ b/sysdeps/arm/nptl/tls.h +@@ -50,18 +50,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN 16 +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN 16 +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(tcbp, dtvp) \ +diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h +index f3fa3fcb02748776..e81d4552d27e0378 100644 +--- a/sysdeps/csky/nptl/tls.h ++++ b/sysdeps/csky/nptl/tls.h +@@ -61,15 +61,9 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN 8 +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN 8 +- + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +diff --git a/sysdeps/generic/tls.h b/sysdeps/generic/tls.h +index e86d70e6cebba5c8..9214ed39b6383e8c 100644 +--- a/sysdeps/generic/tls.h ++++ b/sysdeps/generic/tls.h +@@ -19,6 +19,11 @@ + /* An architecture-specific version of this file has to defined a + number of symbols: + ++ TCB_ALIGNMENT ++ ++ Alignment of THREAD_SELF (struct pthread *) and the thread ++ pointer. ++ + TLS_TCB_AT_TP or TLS_DTV_AT_TP + + The presence of one of these symbols signals which variant of +@@ -43,15 +48,6 @@ + dynamic linker itself. There are no threads in use at that time. + + +- TLS_TCB_ALIGN +- +- Alignment requirements for the TCB structure. +- +- TLS_INIT_TCB_ALIGN +- +- Similarly, but for the structure used at startup time. +- +- + INSTALL_DTV(tcb, init_dtv) + + This macro must install the given initial DTV into the thread control +diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h +index f0e274c45fb5e91e..88a6b902c0b7e2fd 100644 +--- a/sysdeps/hppa/nptl/tls.h ++++ b/sysdeps/hppa/nptl/tls.h +@@ -52,15 +52,9 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h +index 111c9ee59df30bc3..06ab9784a5358b0b 100644 +--- a/sysdeps/i386/nptl/tls.h ++++ b/sysdeps/i386/nptl/tls.h +@@ -102,15 +102,9 @@ union user_desc_init + struct pthread even when not linked with -lpthread. */ + # define TLS_INIT_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ + # define TLS_TCB_AT_TP 1 +diff --git a/sysdeps/ia64/libc-tls.c b/sysdeps/ia64/libc-tls.c +index a01edceab36d375e..ede1e8f463b135b4 100644 +--- a/sysdeps/ia64/libc-tls.c ++++ b/sysdeps/ia64/libc-tls.c +@@ -18,6 +18,9 @@ + + #include + ++_Static_assert (TLS_PRE_TCB_SIZE % __alignof (struct pthread) == 0, ++ "__thread_self and THREAD_SELF have same alignment"); ++ + /* On IA-64, as it lacks linker optimizations, __tls_get_addr can be + called even in statically linked binaries. + In this case module must be always 1 and PT_TLS segment +diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h +index 26fe555cb4b5e164..ca8f1280aeeed3d5 100644 +--- a/sysdeps/ia64/nptl/tls.h ++++ b/sysdeps/ia64/nptl/tls.h +@@ -53,9 +53,6 @@ register struct pthread *__thread_self __asm__("r13"); + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + +@@ -70,9 +67,6 @@ register struct pthread *__thread_self __asm__("r13"); + & ~(__alignof__ (struct pthread) - 1)) \ + : 0)) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The DTV is allocated at the TP; the TCB is placed elsewhere. */ + # define TLS_DTV_AT_TP 1 + # define TLS_TCB_AT_TP 0 +diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h +index 9f562c38288df200..b88ef0c9c74ae0b0 100644 +--- a/sysdeps/m68k/nptl/tls.h ++++ b/sysdeps/m68k/nptl/tls.h +@@ -54,20 +54,15 @@ typedef struct + pointer, we don't need this. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB - actually, it includes the TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The thread pointer (TP) points to the end of the + TCB + 0x7000, as for PowerPC and MIPS. This implies that TCB address is +diff --git a/sysdeps/mach/hurd/tls.h b/sysdeps/mach/hurd/tls.h +index f83956d3d7ca4f9f..773a2a0c36d5d57d 100644 +--- a/sysdeps/mach/hurd/tls.h ++++ b/sysdeps/mach/hurd/tls.h +@@ -29,20 +29,12 @@ + # include + # include + +- + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE TLS_INIT_TCB_SIZE /* XXX */ + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN TLS_INIT_TCB_ALIGN /* XXX */ +- +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(descr, dtvp) \ +diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h +index bfa6efa78049bb2d..b69d7b4f28f3b757 100644 +--- a/sysdeps/microblaze/nptl/tls.h ++++ b/sysdeps/microblaze/nptl/tls.h +@@ -56,18 +56,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ + # define INSTALL_DTV(tcbp, dtvp) \ +diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h +index ef99aa646c898e76..6ccaf9804a68634a 100644 +--- a/sysdeps/mips/nptl/tls.h ++++ b/sysdeps/mips/nptl/tls.h +@@ -83,20 +83,15 @@ typedef struct + pointer, we don't need this. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB - actually, it includes the TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The thread pointer (in hardware register $29) points to the end of + the TCB + 0x7000, as for PowerPC. The pthread_descr structure is +diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h +index 7110cfccad7131f4..6ab6bd27b00a70ee 100644 +--- a/sysdeps/nios2/nptl/tls.h ++++ b/sysdeps/nios2/nptl/tls.h +@@ -59,20 +59,15 @@ register struct pthread *__thread_self __asm__("r23"); + pointer, we don't need this. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB - actually, it includes the TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The thread pointer (in hardware register r23) points to the end of + the TCB + 0x7000, as for PowerPC and MIPS. */ +diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h +index 110d085d30c86302..e194b334216eaa02 100644 +--- a/sysdeps/powerpc/nptl/tls.h ++++ b/sysdeps/powerpc/nptl/tls.h +@@ -108,19 +108,14 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The following assumes that TP (R2 or R13) points to the end of the + TCB + 0x7000 (per the ABI). This implies that TCB address is +diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h +index bdc0a3a6f91b51e8..8c12d8f971adeddb 100644 +--- a/sysdeps/riscv/nptl/tls.h ++++ b/sysdeps/riscv/nptl/tls.h +@@ -50,20 +50,15 @@ typedef struct + pointer, we don't need this. */ + # define TLS_INIT_TCB_SIZE 0 + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ + # define TLS_TCB_SIZE 0 + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size we need before TCB - actually, it includes the TCB. */ + # define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ +- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \ ++ & ~(__alignof (struct pthread) - 1))) + + /* The thread pointer tp points to the end of the TCB. + The pthread_descr structure is immediately in front of the TCB. */ +diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h +index 2cdd18eb2907c060..3b4c0ab32a9439a3 100644 +--- a/sysdeps/s390/nptl/tls.h ++++ b/sysdeps/s390/nptl/tls.h +@@ -66,15 +66,9 @@ typedef struct + struct pthread even when not linked with -lpthread. */ + # define TLS_INIT_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ + # define TLS_TCB_AT_TP 1 +diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h +index 390640020e45f716..3e4d480b35951253 100644 +--- a/sysdeps/sh/nptl/tls.h ++++ b/sysdeps/sh/nptl/tls.h +@@ -51,18 +51,12 @@ typedef struct + /* This is the size of the initial TCB. */ + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) + + /* This is the size we need before TCB. */ + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TLS blocks start right after the TCB. */ + # define TLS_DTV_AT_TP 1 + # define TLS_TCB_AT_TP 0 +diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h +index 376d729989e35660..3fb4ce6e6dacf28c 100644 +--- a/sysdeps/sparc/nptl/tls.h ++++ b/sysdeps/sparc/nptl/tls.h +@@ -63,15 +63,9 @@ register struct pthread *__thread_self __asm__("%g7"); + struct pthread even when not linked with -lpthread. */ + # define TLS_INIT_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ + # define TLS_TCB_AT_TP 1 +diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h +index 3af1836e28b26fdb..50f7e8b544f9e6fc 100644 +--- a/sysdeps/x86_64/nptl/tls.h ++++ b/sysdeps/x86_64/nptl/tls.h +@@ -106,15 +106,9 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80, + struct pthread even when not linked with -lpthread. */ + # define TLS_INIT_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) +- + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (struct pthread) + +-/* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (struct pthread) +- + /* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ + # define TLS_TCB_AT_TP 1 diff --git a/SOURCES/glibc-rh2024347-12.patch b/SOURCES/glibc-rh2024347-12.patch new file mode 100644 index 0000000..02a9cea --- /dev/null +++ b/SOURCES/glibc-rh2024347-12.patch @@ -0,0 +1,73 @@ +commit cb976fba4c51ede7bf8cee5035888527c308dfbc +Author: Florian Weimer +Date: Wed Dec 15 16:06:25 2021 +0100 + + powerpc: Use global register variable in + + A local register variable is merely a compiler hint, and so not + appropriate in this context. Move the global register variable into + and include it from , as there can only + be one global definition for one particular register. + + Fixes commit 8dbeb0561eeb876f557ac9eef5721912ec074ea5 + ("nptl: Add for defining __thread_pointer"). + + Reported-by: Mathieu Desnoyers + Reviewed-by: Raphael M Zinsly + +diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h +index 8fd5ba671f6f5e64..4feba5961062cfaf 100644 +--- a/sysdeps/powerpc/nptl/thread_pointer.h ++++ b/sysdeps/powerpc/nptl/thread_pointer.h +@@ -19,15 +19,16 @@ + #ifndef _SYS_THREAD_POINTER_H + #define _SYS_THREAD_POINTER_H + +-static inline void * +-__thread_pointer (void) +-{ + #ifdef __powerpc64__ +- register void *__result asm ("r13"); ++register void *__thread_register asm ("r13"); + #else +- register void *__result asm ("r2"); ++register void *__thread_register asm ("r2"); + #endif +- return __result; ++ ++static inline void * ++__thread_pointer (void) ++{ ++ return __thread_register; + } + + #endif /* _SYS_THREAD_POINTER_H */ +diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h +index e194b334216eaa02..050beb06a8f7de65 100644 +--- a/sysdeps/powerpc/nptl/tls.h ++++ b/sysdeps/powerpc/nptl/tls.h +@@ -26,6 +26,7 @@ + # include + # include + # include ++# include + + #else /* __ASSEMBLER__ */ + # include +@@ -36,16 +37,10 @@ + #ifndef __powerpc64__ + /* Register r2 (tp) is reserved by the ABI as "thread pointer". */ + # define PT_THREAD_POINTER PT_R2 +-# ifndef __ASSEMBLER__ +-register void *__thread_register __asm__ ("r2"); +-# endif + + #else /* __powerpc64__ */ + /* Register r13 (tp) is reserved by the ABI as "thread pointer". */ + # define PT_THREAD_POINTER PT_R13 +-# ifndef __ASSEMBLER__ +-register void *__thread_register __asm__ ("r13"); +-# endif + #endif /* __powerpc64__ */ + + #ifndef __ASSEMBLER__ diff --git a/SOURCES/glibc-rh2024347-13.patch b/SOURCES/glibc-rh2024347-13.patch new file mode 100644 index 0000000..f002a78 --- /dev/null +++ b/SOURCES/glibc-rh2024347-13.patch @@ -0,0 +1,42 @@ +Downstream-only patch to disable rseq by default. This is necessary +because CRIU does not yet support rseq: + + criu: Implement rseq support + + +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 28ff502990c2a10f..f559c44dcec4624b 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -425,11 +425,13 @@ The value is measured in bytes. The default is @samp{41943040} + @end deftp + + @deftp Tunable glibc.pthread.rseq +-The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable +-restartable sequences support in @theglibc{}. This enables applications +-to perform direct restartable sequence registration with the kernel. +-The default is @samp{1}, which means that @theglibc{} performs +-registration on behalf of the application. ++The @code{glibc.pthread.rseq} tunable can be set to @samp{1}, to enable ++restartable sequences support. @Theglibc{} uses this to optimize the ++@code{sched_getcpu} function. ++ ++The default is @samp{0}, which means that applications can perform ++restartable sequences registration, but @code{sched_getcpu} is not ++accelerated. + + Restartable sequences are a Linux-specific extension. + @end deftp +diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list +index d24f4be0d08ba407..df2a39ce01858d3b 100644 +--- a/sysdeps/nptl/dl-tunables.list ++++ b/sysdeps/nptl/dl-tunables.list +@@ -31,7 +31,7 @@ glibc { + type: INT_32 + minval: 0 + maxval: 1 +- default: 1 ++ default: 0 + } + } + } diff --git a/SOURCES/glibc-rh2024347-2.patch b/SOURCES/glibc-rh2024347-2.patch new file mode 100644 index 0000000..71613f3 --- /dev/null +++ b/SOURCES/glibc-rh2024347-2.patch @@ -0,0 +1,259 @@ +commit 23c77f60181eb549f11ec2f913b4270af29eee38 +Author: Florian Weimer +Date: Fri Dec 3 16:28:07 2021 +0100 + + nptl: Increase default TCB alignment to 32 + + rseq support will use a 32-byte aligned field in struct pthread, + so the whole struct needs to have at least that alignment. + + nptl/tst-tls3mod.c uses TCB_ALIGNMENT, therefore include + to obtain the fallback definition. + + Reviewed-by: H.J. Lu + +diff --git a/nptl/descr.h b/nptl/descr.h +index 4de84138fb960fa4..57be5b4fef564b36 100644 +--- a/nptl/descr.h ++++ b/nptl/descr.h +@@ -37,7 +37,9 @@ + #include + + #ifndef TCB_ALIGNMENT +-# define TCB_ALIGNMENT sizeof (double) ++# define TCB_ALIGNMENT 32 ++#elif TCB_ALIGNMENT < 32 ++# error TCB_ALIGNMENT must be at least 32 + #endif + + +diff --git a/nptl/tst-tls3mod.c b/nptl/tst-tls3mod.c +index cfd13aace1affcd5..77dcc550fc3b5017 100644 +--- a/nptl/tst-tls3mod.c ++++ b/nptl/tst-tls3mod.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + + extern pthread_barrier_t b; +diff --git a/sysdeps/aarch64/nptl/pthreaddef.h b/sysdeps/aarch64/nptl/pthreaddef.h +index 4d5ecf6661fd0fe6..8d9a10622d132a7a 100644 +--- a/sysdeps/aarch64/nptl/pthreaddef.h ++++ b/sysdeps/aarch64/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/alpha/nptl/pthreaddef.h b/sysdeps/alpha/nptl/pthreaddef.h +index 25edb5093e095548..660e5694a25ec60f 100644 +--- a/sysdeps/alpha/nptl/pthreaddef.h ++++ b/sysdeps/alpha/nptl/pthreaddef.h +@@ -27,8 +27,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 4096 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/arc/nptl/pthreaddef.h b/sysdeps/arc/nptl/pthreaddef.h +index 873b9d149ac46a62..d4dbe9e079445353 100644 +--- a/sysdeps/arc/nptl/pthreaddef.h ++++ b/sysdeps/arc/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 4 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/arm/nptl/pthreaddef.h b/sysdeps/arm/nptl/pthreaddef.h +index 332f4079c4c3f2bf..13769f5ae270b0ca 100644 +--- a/sysdeps/arm/nptl/pthreaddef.h ++++ b/sysdeps/arm/nptl/pthreaddef.h +@@ -28,9 +28,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. + +diff --git a/sysdeps/csky/nptl/pthreaddef.h b/sysdeps/csky/nptl/pthreaddef.h +index e78bc0016b43b450..7dde9131b9b1a6b0 100644 +--- a/sysdeps/csky/nptl/pthreaddef.h ++++ b/sysdeps/csky/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 8 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/ia64/nptl/pthreaddef.h b/sysdeps/ia64/nptl/pthreaddef.h +index 3a0f6daf9ad871aa..c7420fd1e4ee6081 100644 +--- a/sysdeps/ia64/nptl/pthreaddef.h ++++ b/sysdeps/ia64/nptl/pthreaddef.h +@@ -30,9 +30,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 16384 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __stack_pointer +diff --git a/sysdeps/m68k/nptl/pthreaddef.h b/sysdeps/m68k/nptl/pthreaddef.h +index 13e785a86bbf47b4..ce9511cb02da69fd 100644 +--- a/sysdeps/m68k/nptl/pthreaddef.h ++++ b/sysdeps/m68k/nptl/pthreaddef.h +@@ -28,9 +28,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/microblaze/nptl/pthreaddef.h b/sysdeps/microblaze/nptl/pthreaddef.h +index 517157444da556ad..19d7235782afde53 100644 +--- a/sysdeps/microblaze/nptl/pthreaddef.h ++++ b/sysdeps/microblaze/nptl/pthreaddef.h +@@ -31,8 +31,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/mips/nptl/pthreaddef.h b/sysdeps/mips/nptl/pthreaddef.h +index a7bccef6e512438f..322591c293ce5e15 100644 +--- a/sysdeps/mips/nptl/pthreaddef.h ++++ b/sysdeps/mips/nptl/pthreaddef.h +@@ -27,9 +27,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/nios2/nptl/pthreaddef.h b/sysdeps/nios2/nptl/pthreaddef.h +index e01a0e6df72c089a..aa0709d0dc69f251 100644 +--- a/sysdeps/nios2/nptl/pthreaddef.h ++++ b/sysdeps/nios2/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 4 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/powerpc/nptl/pthreaddef.h b/sysdeps/powerpc/nptl/pthreaddef.h +index ef5310e6315fde2c..117c35229ea68f48 100644 +--- a/sysdeps/powerpc/nptl/pthreaddef.h ++++ b/sysdeps/powerpc/nptl/pthreaddef.h +@@ -28,9 +28,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 4096 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/riscv/nptl/pthreaddef.h b/sysdeps/riscv/nptl/pthreaddef.h +index 7bf93d6a63fdecd2..0f33cc48fe4fc728 100644 +--- a/sysdeps/riscv/nptl/pthreaddef.h ++++ b/sysdeps/riscv/nptl/pthreaddef.h +@@ -28,8 +28,5 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/s390/nptl/pthreaddef.h b/sysdeps/s390/nptl/pthreaddef.h +index 091f82df24a4024c..0e32bd862f7fea48 100644 +--- a/sysdeps/s390/nptl/pthreaddef.h ++++ b/sysdeps/s390/nptl/pthreaddef.h +@@ -28,9 +28,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/sh/nptl/pthreaddef.h b/sysdeps/sh/nptl/pthreaddef.h +index 3fa3d189ef969c90..f4e3a290df4ee6e6 100644 +--- a/sysdeps/sh/nptl/pthreaddef.h ++++ b/sysdeps/sh/nptl/pthreaddef.h +@@ -29,9 +29,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 8 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/sparc/sparc32/pthreaddef.h b/sysdeps/sparc/sparc32/pthreaddef.h +index 6526fb3d6e7e1448..7a0a04789dac478e 100644 +--- a/sysdeps/sparc/sparc32/pthreaddef.h ++++ b/sysdeps/sparc/sparc32/pthreaddef.h +@@ -27,9 +27,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 2048 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- + + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME (stack_pointer + (2 * 64)) +diff --git a/sysdeps/sparc/sparc64/pthreaddef.h b/sysdeps/sparc/sparc64/pthreaddef.h +index 3da9d7afc8054598..103842856d40432b 100644 +--- a/sysdeps/sparc/sparc64/pthreaddef.h ++++ b/sysdeps/sparc/sparc64/pthreaddef.h +@@ -27,10 +27,6 @@ + /* Minimal stack size after allocating thread descriptor and guard size. */ + #define MINIMAL_REST_STACK 4096 + +-/* Alignment requirement for TCB. */ +-#define TCB_ALIGNMENT 16 +- +- + /* Location of current stack frame. */ + #define CURRENT_STACK_FRAME (stack_pointer + (2 * 128)) + register char *stack_pointer __asm__("%sp"); diff --git a/SOURCES/glibc-rh2024347-3.patch b/SOURCES/glibc-rh2024347-3.patch new file mode 100644 index 0000000..08e30f7 --- /dev/null +++ b/SOURCES/glibc-rh2024347-3.patch @@ -0,0 +1,150 @@ +commit 4fb4e7e821e36180835bf88e363f9f13b5797e3a +Author: Florian Weimer +Date: Sun Dec 5 13:50:17 2021 +0100 + + csu: Always use __executable_start in gmon-start.c + + Current binutils defines __executable_start as the lowest text + address, so using the entry point address as a fallback is no + longer necessary. As a result, overriding is only + necessary if the entry point is not called _start. + + The previous approach to define __ASSEMBLY__ to suppress the + declaration breaks if headers included by are not + compatible with __ASSEMBLY__. This happens with rseq integration + because it is necessary to include kernel headers in more places. + + Reviewed-by: H.J. Lu + +diff --git a/csu/gmon-start.c b/csu/gmon-start.c +index 344606a676c188d4..260c7613e291a32d 100644 +--- a/csu/gmon-start.c ++++ b/csu/gmon-start.c +@@ -38,32 +38,12 @@ + #include + #include + #include +-#define __ASSEMBLY__ +-#include +- +-/* Beginning and end of our code segment. We cannot declare them +- as the external functions since we want the addresses of those +- labels. Taking the address of a function may have different +- meanings on different platforms. */ +-#ifdef ENTRY_POINT_DECL +-ENTRY_POINT_DECL(extern) +-#else +-extern char ENTRY_POINT[]; +-#endif +-extern char etext[]; + + /* Use __executable_start as the lowest address to keep profiling records + if it provided by the linker. */ +-extern const char executable_start[] asm ("__executable_start") +- __attribute__ ((weak, visibility ("hidden"))); ++extern const char __executable_start[] __attribute__ ((visibility ("hidden"))); + +-#ifndef TEXT_START +-# ifdef ENTRY_POINT_DECL +-# define TEXT_START ENTRY_POINT +-# else +-# define TEXT_START &ENTRY_POINT +-# endif +-#endif ++extern char etext[]; + + #if !ELF_INITFINI + /* Instead of defining __gmon_start__ globally in gcrt1.o, we make it +@@ -97,10 +77,7 @@ __gmon_start__ (void) + called = 1; + + /* Start keeping profiling records. */ +- if (&executable_start != NULL) +- __monstartup ((u_long) &executable_start, (u_long) &etext); +- else +- __monstartup ((u_long) TEXT_START, (u_long) &etext); ++ __monstartup ((u_long) &__executable_start, (u_long) &etext); + + /* Call _mcleanup before exiting; it will write out gmon.out from the + collected data. */ +diff --git a/sysdeps/hppa/entry.h b/sysdeps/hppa/entry.h +deleted file mode 100644 +index 5ea5b47448ceb2e7..0000000000000000 +--- a/sysdeps/hppa/entry.h ++++ /dev/null +@@ -1,13 +0,0 @@ +-#ifndef __ASSEMBLY__ +-extern void _start (void); +-#endif +- +-/* Lives in libgcc.so and canonicalizes function pointers for comparison. */ +-extern unsigned int __canonicalize_funcptr_for_compare (unsigned int fptr); +- +-/* The function's entry point is stored in the first word of the +- function descriptor (plabel) of _start(). */ +-#define ENTRY_POINT __canonicalize_funcptr_for_compare((unsigned int)_start) +- +-/* We have to provide a special declaration. */ +-#define ENTRY_POINT_DECL(class) class void _start (void); +diff --git a/sysdeps/ia64/entry.h b/sysdeps/ia64/entry.h +deleted file mode 100644 +index e11b49fc53602eb8..0000000000000000 +--- a/sysdeps/ia64/entry.h ++++ /dev/null +@@ -1,13 +0,0 @@ +-#include +-#include +- +-#ifndef __ASSEMBLY__ +-extern void _start (void); +-#endif +- +-/* The function's entry point is stored in the first word of the +- function descriptor (plabel) of _start(). */ +-#define ENTRY_POINT ELF_PTR_TO_FDESC (_start)->ip +- +-/* We have to provide a special declaration. */ +-#define ENTRY_POINT_DECL(class) class void _start (void); +diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h +deleted file mode 100644 +index 99c81cb9820d188d..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/entry.h ++++ /dev/null +@@ -1,37 +0,0 @@ +-/* Finding the entry point and start of text. PowerPC64 version. +- Copyright (C) 2002-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#ifndef __ASSEMBLY__ +-extern void _start (void); +-#endif +- +-#define ENTRY_POINT _start +- +-#if _CALL_ELF != 2 +-/* We have to provide a special declaration. */ +-#define ENTRY_POINT_DECL(class) class void _start (void); +- +-/* Use the address of ._start as the lowest address for which we need +- to keep profiling records. We can't copy the ia64 scheme as our +- entry poiny address is really the address of the function +- descriptor, not the actual function entry. */ +-#define TEXT_START \ +- ({ extern unsigned long int _start_as_data[] asm ("_start"); \ +- _start_as_data[0]; }) +-#endif diff --git a/SOURCES/glibc-rh2024347-4.patch b/SOURCES/glibc-rh2024347-4.patch new file mode 100644 index 0000000..a49f626 --- /dev/null +++ b/SOURCES/glibc-rh2024347-4.patch @@ -0,0 +1,130 @@ +commit 8dbeb0561eeb876f557ac9eef5721912ec074ea5 +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Add for defining __thread_pointer + + already contains a definition that is quite similar, + but it is not consistent across architectures. + + Only architectures for which rseq support is added are covered. + + Reviewed-by: Szabolcs Nagy + +diff --git a/sysdeps/nptl/thread_pointer.h b/sysdeps/nptl/thread_pointer.h +new file mode 100644 +index 0000000000000000..92f2f3093eba55bb +--- /dev/null ++++ b/sysdeps/nptl/thread_pointer.h +@@ -0,0 +1,28 @@ ++/* __thread_pointer definition. Generic version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _SYS_THREAD_POINTER_H ++#define _SYS_THREAD_POINTER_H ++ ++static inline void * ++__thread_pointer (void) ++{ ++ return __builtin_thread_pointer (); ++} ++ ++#endif /* _SYS_THREAD_POINTER_H */ +diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h +new file mode 100644 +index 0000000000000000..8fd5ba671f6f5e64 +--- /dev/null ++++ b/sysdeps/powerpc/nptl/thread_pointer.h +@@ -0,0 +1,33 @@ ++/* __thread_pointer definition. powerpc version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _SYS_THREAD_POINTER_H ++#define _SYS_THREAD_POINTER_H ++ ++static inline void * ++__thread_pointer (void) ++{ ++#ifdef __powerpc64__ ++ register void *__result asm ("r13"); ++#else ++ register void *__result asm ("r2"); ++#endif ++ return __result; ++} ++ ++#endif /* _SYS_THREAD_POINTER_H */ +diff --git a/sysdeps/x86/nptl/thread_pointer.h b/sysdeps/x86/nptl/thread_pointer.h +new file mode 100644 +index 0000000000000000..6b71b6f7e1401e4c +--- /dev/null ++++ b/sysdeps/x86/nptl/thread_pointer.h +@@ -0,0 +1,38 @@ ++/* __thread_pointer definition. x86 version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _SYS_THREAD_POINTER_H ++#define _SYS_THREAD_POINTER_H ++ ++static inline void * ++__thread_pointer (void) ++{ ++#if __GNUC_PREREQ (11, 1) ++ return __builtin_thread_pointer (); ++#else ++ void *__result; ++# ifdef __x86_64__ ++ __asm__ ("mov %%fs:0, %0" : "=r" (__result)); ++# else ++ __asm__ ("mov %%gs:0, %0" : "=r" (__result)); ++# endif ++ return __result; ++#endif /* !GCC 11 */ ++} ++ ++#endif /* _SYS_THREAD_POINTER_H */ diff --git a/SOURCES/glibc-rh2024347-5.patch b/SOURCES/glibc-rh2024347-5.patch new file mode 100644 index 0000000..36b1db1 --- /dev/null +++ b/SOURCES/glibc-rh2024347-5.patch @@ -0,0 +1,904 @@ +commit ce2248ab91b2ea09a378f85012f251f31ac65e31 +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Introduce for THREAD_* accessors + + These are common between most architectures. Only the x86 targets + are outliers. + + Reviewed-by: Szabolcs Nagy + +diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h +index 6e896207a659514f..cd9abb5d1d073593 100644 +--- a/sysdeps/aarch64/nptl/tls.h ++++ b/sysdeps/aarch64/nptl/tls.h +@@ -98,15 +98,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (64, sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + # define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h +index 4dbccc5249539325..5f4843b28e7f1ad1 100644 +--- a/sysdeps/alpha/nptl/tls.h ++++ b/sysdeps/alpha/nptl/tls.h +@@ -92,15 +92,7 @@ typedef struct + # define DB_THREAD_SELF \ + REGISTER (64, 64, 32 * 8, -sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + #define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h +index 95300fdd2159dc53..d9ada2f38089e6cd 100644 +--- a/sysdeps/arc/nptl/tls.h ++++ b/sysdeps/arc/nptl/tls.h +@@ -100,15 +100,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + #define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h +index 1bd11307ce0a7f0a..354aae3318291395 100644 +--- a/sysdeps/arm/nptl/tls.h ++++ b/sysdeps/arm/nptl/tls.h +@@ -89,15 +89,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + #define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h +index 7a234041ed0bff39..f3fa3fcb02748776 100644 +--- a/sysdeps/csky/nptl/tls.h ++++ b/sysdeps/csky/nptl/tls.h +@@ -116,15 +116,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + # define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h +index 857003a7d35073eb..f0e274c45fb5e91e 100644 +--- a/sysdeps/hppa/nptl/tls.h ++++ b/sysdeps/hppa/nptl/tls.h +@@ -107,15 +107,7 @@ typedef struct + # define DB_THREAD_SELF \ + REGISTER (32, 32, 53 * 4, -sizeof (struct pthread)) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + static inline struct pthread *__get_cr27(void) + { +diff --git a/sysdeps/i386/nptl/tcb-access.h b/sysdeps/i386/nptl/tcb-access.h +new file mode 100644 +index 0000000000000000..6c6d561e394817c7 +--- /dev/null ++++ b/sysdeps/i386/nptl/tcb-access.h +@@ -0,0 +1,123 @@ ++/* THREAD_* accessors. i386 version. ++ Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Read member of the thread descriptor directly. */ ++#define THREAD_GETMEM(descr, member) \ ++ ({ __typeof (descr->member) __value; \ ++ _Static_assert (sizeof (__value) == 1 \ ++ || sizeof (__value) == 4 \ ++ || sizeof (__value) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (__value) == 1) \ ++ asm volatile ("movb %%gs:%P2,%b0" \ ++ : "=q" (__value) \ ++ : "0" (0), "i" (offsetof (struct pthread, member))); \ ++ else if (sizeof (__value) == 4) \ ++ asm volatile ("movl %%gs:%P1,%0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member))); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movl %%gs:%P1,%%eax\n\t" \ ++ "movl %%gs:%P2,%%edx" \ ++ : "=A" (__value) \ ++ : "i" (offsetof (struct pthread, member)), \ ++ "i" (offsetof (struct pthread, member) + 4)); \ ++ } \ ++ __value; }) ++ ++ ++/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ ++#define THREAD_GETMEM_NC(descr, member, idx) \ ++ ({ __typeof (descr->member[0]) __value; \ ++ _Static_assert (sizeof (__value) == 1 \ ++ || sizeof (__value) == 4 \ ++ || sizeof (__value) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (__value) == 1) \ ++ asm volatile ("movb %%gs:%P2(%3),%b0" \ ++ : "=q" (__value) \ ++ : "0" (0), "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else if (sizeof (__value) == 4) \ ++ asm volatile ("movl %%gs:%P1(,%2,4),%0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \ ++ "movl %%gs:4+%P1(,%2,8),%%edx" \ ++ : "=&A" (__value) \ ++ : "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ } \ ++ __value; }) ++ ++ ++ ++/* Set member of the thread descriptor directly. */ ++#define THREAD_SETMEM(descr, member, value) \ ++ ({ \ ++ _Static_assert (sizeof (descr->member) == 1 \ ++ || sizeof (descr->member) == 4 \ ++ || sizeof (descr->member) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (descr->member) == 1) \ ++ asm volatile ("movb %b0,%%gs:%P1" : \ ++ : "iq" (value), \ ++ "i" (offsetof (struct pthread, member))); \ ++ else if (sizeof (descr->member) == 4) \ ++ asm volatile ("movl %0,%%gs:%P1" : \ ++ : "ir" (value), \ ++ "i" (offsetof (struct pthread, member))); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movl %%eax,%%gs:%P1\n\t" \ ++ "movl %%edx,%%gs:%P2" : \ ++ : "A" ((uint64_t) cast_to_integer (value)), \ ++ "i" (offsetof (struct pthread, member)), \ ++ "i" (offsetof (struct pthread, member) + 4)); \ ++ }}) ++ ++ ++/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ ++#define THREAD_SETMEM_NC(descr, member, idx, value) \ ++ ({ \ ++ _Static_assert (sizeof (descr->member[0]) == 1 \ ++ || sizeof (descr->member[0]) == 4 \ ++ || sizeof (descr->member[0]) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (descr->member[0]) == 1) \ ++ asm volatile ("movb %b0,%%gs:%P1(%2)" : \ ++ : "iq" (value), \ ++ "i" (offsetof (struct pthread, member)), \ ++ "r" (idx)); \ ++ else if (sizeof (descr->member[0]) == 4) \ ++ asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \ ++ : "ir" (value), \ ++ "i" (offsetof (struct pthread, member)), \ ++ "r" (idx)); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \ ++ "movl %%edx,%%gs:4+%P1(,%2,8)" : \ ++ : "A" ((uint64_t) cast_to_integer (value)), \ ++ "i" (offsetof (struct pthread, member)), \ ++ "r" (idx)); \ ++ }}) +diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h +index 86ee1ef30270f960..111c9ee59df30bc3 100644 +--- a/sysdeps/i386/nptl/tls.h ++++ b/sysdeps/i386/nptl/tls.h +@@ -250,113 +250,7 @@ tls_fill_user_desc (union user_desc_init *desc, + REGISTER_THREAD_AREA (32, offsetof (struct user_regs_struct, xgs), 3) \ + REGISTER_THREAD_AREA (64, 26 * 8, 3) /* x86-64's user_regs_struct->gs */ + +- +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) \ +- ({ __typeof (descr->member) __value; \ +- _Static_assert (sizeof (__value) == 1 \ +- || sizeof (__value) == 4 \ +- || sizeof (__value) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (__value) == 1) \ +- asm volatile ("movb %%gs:%P2,%b0" \ +- : "=q" (__value) \ +- : "0" (0), "i" (offsetof (struct pthread, member))); \ +- else if (sizeof (__value) == 4) \ +- asm volatile ("movl %%gs:%P1,%0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member))); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movl %%gs:%P1,%%eax\n\t" \ +- "movl %%gs:%P2,%%edx" \ +- : "=A" (__value) \ +- : "i" (offsetof (struct pthread, member)), \ +- "i" (offsetof (struct pthread, member) + 4)); \ +- } \ +- __value; }) +- +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- ({ __typeof (descr->member[0]) __value; \ +- _Static_assert (sizeof (__value) == 1 \ +- || sizeof (__value) == 4 \ +- || sizeof (__value) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (__value) == 1) \ +- asm volatile ("movb %%gs:%P2(%3),%b0" \ +- : "=q" (__value) \ +- : "0" (0), "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else if (sizeof (__value) == 4) \ +- asm volatile ("movl %%gs:%P1(,%2,4),%0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \ +- "movl %%gs:4+%P1(,%2,8),%%edx" \ +- : "=&A" (__value) \ +- : "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- } \ +- __value; }) +- +- +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- ({ \ +- _Static_assert (sizeof (descr->member) == 1 \ +- || sizeof (descr->member) == 4 \ +- || sizeof (descr->member) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (descr->member) == 1) \ +- asm volatile ("movb %b0,%%gs:%P1" : \ +- : "iq" (value), \ +- "i" (offsetof (struct pthread, member))); \ +- else if (sizeof (descr->member) == 4) \ +- asm volatile ("movl %0,%%gs:%P1" : \ +- : "ir" (value), \ +- "i" (offsetof (struct pthread, member))); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movl %%eax,%%gs:%P1\n\t" \ +- "movl %%edx,%%gs:%P2" : \ +- : "A" ((uint64_t) cast_to_integer (value)), \ +- "i" (offsetof (struct pthread, member)), \ +- "i" (offsetof (struct pthread, member) + 4)); \ +- }}) +- +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- ({ \ +- _Static_assert (sizeof (descr->member[0]) == 1 \ +- || sizeof (descr->member[0]) == 4 \ +- || sizeof (descr->member[0]) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (descr->member[0]) == 1) \ +- asm volatile ("movb %b0,%%gs:%P1(%2)" : \ +- : "iq" (value), \ +- "i" (offsetof (struct pthread, member)), \ +- "r" (idx)); \ +- else if (sizeof (descr->member[0]) == 4) \ +- asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \ +- : "ir" (value), \ +- "i" (offsetof (struct pthread, member)), \ +- "r" (idx)); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \ +- "movl %%edx,%%gs:4+%P1(,%2,8)" : \ +- : "A" ((uint64_t) cast_to_integer (value)), \ +- "i" (offsetof (struct pthread, member)), \ +- "r" (idx)); \ +- }}) +- ++# include + + /* Set the stack guard field in TCB head. */ + #define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h +index 66d9bf3189f0b727..26fe555cb4b5e164 100644 +--- a/sysdeps/ia64/nptl/tls.h ++++ b/sysdeps/ia64/nptl/tls.h +@@ -128,15 +128,7 @@ register struct pthread *__thread_self __asm__("r13"); + /* Magic for libthread_db to know how to do THREAD_SELF. */ + # define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -TLS_PRE_TCB_SIZE) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Set the stack guard field in TCB head. */ + #define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h +index cfcd6d2b7b59321c..9f562c38288df200 100644 +--- a/sysdeps/m68k/nptl/tls.h ++++ b/sysdeps/m68k/nptl/tls.h +@@ -118,15 +118,7 @@ extern void * __m68k_read_tp (void); + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* l_tls_offset == 0 is perfectly valid on M68K, so we have to use some + different value to mean unset l_tls_offset. */ +diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h +index c93d90b11bfe4c74..bfa6efa78049bb2d 100644 +--- a/sysdeps/microblaze/nptl/tls.h ++++ b/sysdeps/microblaze/nptl/tls.h +@@ -100,20 +100,7 @@ typedef struct + # define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, sizeof (struct pthread)) + +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) (descr->member) +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- (descr->member[idx]) +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- (descr->member = (value)) +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- (descr->member[idx] = (value)) ++# include + + /* Get and set the global scope generation counter in struct pthread. */ + # define THREAD_GSCOPE_IN_TCB 1 +diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h +index c09f49071cf3b5b9..ef99aa646c898e76 100644 +--- a/sysdeps/mips/nptl/tls.h ++++ b/sysdeps/mips/nptl/tls.h +@@ -144,14 +144,7 @@ typedef struct + CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE) + + /* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* l_tls_offset == 0 is perfectly valid on MIPS, so we have to use some + different value to mean unset l_tls_offset. */ +diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h +index 02a05b4e741092bf..7110cfccad7131f4 100644 +--- a/sysdeps/nios2/nptl/tls.h ++++ b/sysdeps/nios2/nptl/tls.h +@@ -112,15 +112,7 @@ register struct pthread *__thread_self __asm__("r23"); + # define DB_THREAD_SELF \ + REGISTER (32, 32, 23 * 4, -TLS_PRE_TCB_SIZE - TLS_TCB_OFFSET) + +-/* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + # define THREAD_GET_POINTER_GUARD() \ + (((tcbhead_t *) (READ_THREAD_POINTER () \ +diff --git a/sysdeps/nptl/tcb-access.h b/sysdeps/nptl/tcb-access.h +new file mode 100644 +index 0000000000000000..b4137b8ab8067915 +--- /dev/null ++++ b/sysdeps/nptl/tcb-access.h +@@ -0,0 +1,30 @@ ++/* THREAD_* accessors. Generic version based on struct pthread pointers. ++ Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Note: These are for accessing the TCB of the *current* thread. ++ descr can be disregarded on some targets as an optimization. See ++ i386 for an example. */ ++ ++#define THREAD_GETMEM(descr, member) \ ++ descr->member ++#define THREAD_GETMEM_NC(descr, member, idx) \ ++ descr->member[idx] ++#define THREAD_SETMEM(descr, member, value) \ ++ descr->member = (value) ++#define THREAD_SETMEM_NC(descr, member, idx, value) \ ++ descr->member[idx] = (value) +diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h +index 6c779b6609147d54..110d085d30c86302 100644 +--- a/sysdeps/powerpc/nptl/tls.h ++++ b/sysdeps/powerpc/nptl/tls.h +@@ -176,20 +176,7 @@ typedef struct + REGISTER (64, 64, PT_THREAD_POINTER * 8, \ + - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) + +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member) +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- ((void)(descr), (THREAD_SELF)->member[idx]) +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- ((void)(descr), (THREAD_SELF)->member = (value)) +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- ((void)(descr), (THREAD_SELF)->member[idx] = (value)) ++# include + + /* Set the stack guard field in TCB head. */ + # define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h +index 5350bcc0498bab69..bdc0a3a6f91b51e8 100644 +--- a/sysdeps/riscv/nptl/tls.h ++++ b/sysdeps/riscv/nptl/tls.h +@@ -105,14 +105,7 @@ typedef struct + REGISTER (64, 64, 4 * 8, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) + + /* Access to data in the thread descriptor is easy. */ +-# define THREAD_GETMEM(descr, member) \ +- descr->member +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* l_tls_offset == 0 is perfectly valid, so we have to use some different + value to mean unset l_tls_offset. */ +diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h +index efb52515e05c06a9..2cdd18eb2907c060 100644 +--- a/sysdeps/s390/nptl/tls.h ++++ b/sysdeps/s390/nptl/tls.h +@@ -135,15 +135,7 @@ typedef struct + # define DB_THREAD_SELF REGISTER (32, 32, 18 * 4, 0) \ + REGISTER (64, __WORDSIZE, 18 * 8, 0) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Set the stack guard field in TCB head. */ + #define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h +index ac3c9a9e856ee686..390640020e45f716 100644 +--- a/sysdeps/sh/nptl/tls.h ++++ b/sysdeps/sh/nptl/tls.h +@@ -113,19 +113,7 @@ typedef struct + # define DB_THREAD_SELF \ + REGISTER (32, 32, REG_GBR * 4, -sizeof (struct pthread)) + +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) (descr->member) +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) (descr->member[idx]) +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + #define THREAD_GET_POINTER_GUARD() \ + ({ tcbhead_t *__tcbp; \ +diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h +index dd1eb82a595619a9..376d729989e35660 100644 +--- a/sysdeps/sparc/nptl/tls.h ++++ b/sysdeps/sparc/nptl/tls.h +@@ -112,15 +112,7 @@ register struct pthread *__thread_self __asm__("%g7"); + REGISTER (32, 32, 10 * 4, 0) \ + REGISTER (64, __WORDSIZE, (6 * 8) + (__WORDSIZE==64?0:4), 0) + +-/* Access to data in the thread descriptor is easy. */ +-#define THREAD_GETMEM(descr, member) \ +- descr->member +-#define THREAD_GETMEM_NC(descr, member, idx) \ +- descr->member[idx] +-#define THREAD_SETMEM(descr, member, value) \ +- descr->member = (value) +-#define THREAD_SETMEM_NC(descr, member, idx, value) \ +- descr->member[idx] = (value) ++# include + + /* Set the stack guard field in TCB head. */ + #define THREAD_SET_STACK_GUARD(value) \ +diff --git a/sysdeps/x86_64/nptl/tcb-access.h b/sysdeps/x86_64/nptl/tcb-access.h +new file mode 100644 +index 0000000000000000..18848a729d16a4f5 +--- /dev/null ++++ b/sysdeps/x86_64/nptl/tcb-access.h +@@ -0,0 +1,130 @@ ++/* THREAD_* accessors. x86_64 version. ++ Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Read member of the thread descriptor directly. */ ++# define THREAD_GETMEM(descr, member) \ ++ ({ __typeof (descr->member) __value; \ ++ _Static_assert (sizeof (__value) == 1 \ ++ || sizeof (__value) == 4 \ ++ || sizeof (__value) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (__value) == 1) \ ++ asm volatile ("movb %%fs:%P2,%b0" \ ++ : "=q" (__value) \ ++ : "0" (0), "i" (offsetof (struct pthread, member))); \ ++ else if (sizeof (__value) == 4) \ ++ asm volatile ("movl %%fs:%P1,%0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member))); \ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movq %%fs:%P1,%q0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member))); \ ++ } \ ++ __value; }) ++ ++ ++/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ ++# define THREAD_GETMEM_NC(descr, member, idx) \ ++ ({ __typeof (descr->member[0]) __value; \ ++ _Static_assert (sizeof (__value) == 1 \ ++ || sizeof (__value) == 4 \ ++ || sizeof (__value) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (__value) == 1) \ ++ asm volatile ("movb %%fs:%P2(%q3),%b0" \ ++ : "=q" (__value) \ ++ : "0" (0), "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else if (sizeof (__value) == 4) \ ++ asm volatile ("movl %%fs:%P1(,%q2,4),%0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member[0])), "r" (idx));\ ++ else /* 8 */ \ ++ { \ ++ asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \ ++ : "=r" (__value) \ ++ : "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ } \ ++ __value; }) ++ ++ ++/* Loading addresses of objects on x86-64 needs to be treated special ++ when generating PIC code. */ ++#ifdef __pic__ ++# define IMM_MODE "nr" ++#else ++# define IMM_MODE "ir" ++#endif ++ ++ ++/* Set member of the thread descriptor directly. */ ++# define THREAD_SETMEM(descr, member, value) \ ++ ({ \ ++ _Static_assert (sizeof (descr->member) == 1 \ ++ || sizeof (descr->member) == 4 \ ++ || sizeof (descr->member) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (descr->member) == 1) \ ++ asm volatile ("movb %b0,%%fs:%P1" : \ ++ : "iq" (value), \ ++ "i" (offsetof (struct pthread, member))); \ ++ else if (sizeof (descr->member) == 4) \ ++ asm volatile ("movl %0,%%fs:%P1" : \ ++ : IMM_MODE (value), \ ++ "i" (offsetof (struct pthread, member))); \ ++ else /* 8 */ \ ++ { \ ++ /* Since movq takes a signed 32-bit immediate or a register source \ ++ operand, use "er" constraint for 32-bit signed integer constant \ ++ or register. */ \ ++ asm volatile ("movq %q0,%%fs:%P1" : \ ++ : "er" ((uint64_t) cast_to_integer (value)), \ ++ "i" (offsetof (struct pthread, member))); \ ++ }}) ++ ++ ++/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ ++# define THREAD_SETMEM_NC(descr, member, idx, value) \ ++ ({ \ ++ _Static_assert (sizeof (descr->member[0]) == 1 \ ++ || sizeof (descr->member[0]) == 4 \ ++ || sizeof (descr->member[0]) == 8, \ ++ "size of per-thread data"); \ ++ if (sizeof (descr->member[0]) == 1) \ ++ asm volatile ("movb %b0,%%fs:%P1(%q2)" : \ ++ : "iq" (value), \ ++ "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else if (sizeof (descr->member[0]) == 4) \ ++ asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \ ++ : IMM_MODE (value), \ ++ "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ else /* 8 */ \ ++ { \ ++ /* Since movq takes a signed 32-bit immediate or a register source \ ++ operand, use "er" constraint for 32-bit signed integer constant \ ++ or register. */ \ ++ asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \ ++ : "er" ((uint64_t) cast_to_integer (value)), \ ++ "i" (offsetof (struct pthread, member[0])), \ ++ "r" (idx)); \ ++ }}) +diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h +index a78c4f4d016002fa..3af1836e28b26fdb 100644 +--- a/sysdeps/x86_64/nptl/tls.h ++++ b/sysdeps/x86_64/nptl/tls.h +@@ -195,119 +195,7 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80, + # define DB_THREAD_SELF_INCLUDE /* For the FS constant. */ + # define DB_THREAD_SELF CONST_THREAD_AREA (64, FS) + +-/* Read member of the thread descriptor directly. */ +-# define THREAD_GETMEM(descr, member) \ +- ({ __typeof (descr->member) __value; \ +- _Static_assert (sizeof (__value) == 1 \ +- || sizeof (__value) == 4 \ +- || sizeof (__value) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (__value) == 1) \ +- asm volatile ("movb %%fs:%P2,%b0" \ +- : "=q" (__value) \ +- : "0" (0), "i" (offsetof (struct pthread, member))); \ +- else if (sizeof (__value) == 4) \ +- asm volatile ("movl %%fs:%P1,%0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member))); \ +- else /* 8 */ \ +- { \ +- asm volatile ("movq %%fs:%P1,%q0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member))); \ +- } \ +- __value; }) +- +- +-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +-# define THREAD_GETMEM_NC(descr, member, idx) \ +- ({ __typeof (descr->member[0]) __value; \ +- _Static_assert (sizeof (__value) == 1 \ +- || sizeof (__value) == 4 \ +- || sizeof (__value) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (__value) == 1) \ +- asm volatile ("movb %%fs:%P2(%q3),%b0" \ +- : "=q" (__value) \ +- : "0" (0), "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else if (sizeof (__value) == 4) \ +- asm volatile ("movl %%fs:%P1(,%q2,4),%0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member[0])), "r" (idx));\ +- else /* 8 */ \ +- { \ +- asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \ +- : "=r" (__value) \ +- : "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- } \ +- __value; }) +- +- +-/* Loading addresses of objects on x86-64 needs to be treated special +- when generating PIC code. */ +-#ifdef __pic__ +-# define IMM_MODE "nr" +-#else +-# define IMM_MODE "ir" +-#endif +- +- +-/* Set member of the thread descriptor directly. */ +-# define THREAD_SETMEM(descr, member, value) \ +- ({ \ +- _Static_assert (sizeof (descr->member) == 1 \ +- || sizeof (descr->member) == 4 \ +- || sizeof (descr->member) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (descr->member) == 1) \ +- asm volatile ("movb %b0,%%fs:%P1" : \ +- : "iq" (value), \ +- "i" (offsetof (struct pthread, member))); \ +- else if (sizeof (descr->member) == 4) \ +- asm volatile ("movl %0,%%fs:%P1" : \ +- : IMM_MODE (value), \ +- "i" (offsetof (struct pthread, member))); \ +- else /* 8 */ \ +- { \ +- /* Since movq takes a signed 32-bit immediate or a register source \ +- operand, use "er" constraint for 32-bit signed integer constant \ +- or register. */ \ +- asm volatile ("movq %q0,%%fs:%P1" : \ +- : "er" ((uint64_t) cast_to_integer (value)), \ +- "i" (offsetof (struct pthread, member))); \ +- }}) +- +- +-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +-# define THREAD_SETMEM_NC(descr, member, idx, value) \ +- ({ \ +- _Static_assert (sizeof (descr->member[0]) == 1 \ +- || sizeof (descr->member[0]) == 4 \ +- || sizeof (descr->member[0]) == 8, \ +- "size of per-thread data"); \ +- if (sizeof (descr->member[0]) == 1) \ +- asm volatile ("movb %b0,%%fs:%P1(%q2)" : \ +- : "iq" (value), \ +- "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else if (sizeof (descr->member[0]) == 4) \ +- asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \ +- : IMM_MODE (value), \ +- "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- else /* 8 */ \ +- { \ +- /* Since movq takes a signed 32-bit immediate or a register source \ +- operand, use "er" constraint for 32-bit signed integer constant \ +- or register. */ \ +- asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \ +- : "er" ((uint64_t) cast_to_integer (value)), \ +- "i" (offsetof (struct pthread, member[0])), \ +- "r" (idx)); \ +- }}) +- ++# include + + /* Set the stack guard field in TCB head. */ + # define THREAD_SET_STACK_GUARD(value) \ diff --git a/SOURCES/glibc-rh2024347-6.patch b/SOURCES/glibc-rh2024347-6.patch new file mode 100644 index 0000000..4782cdf --- /dev/null +++ b/SOURCES/glibc-rh2024347-6.patch @@ -0,0 +1,49 @@ +commit 8d1927d8dc5aad0f01c929123086be3a5b799d18 +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Introduce THREAD_GETMEM_VOLATILE + + This will be needed for rseq TCB access. + + Reviewed-by: Szabolcs Nagy + +diff --git a/sysdeps/i386/nptl/tcb-access.h b/sysdeps/i386/nptl/tcb-access.h +index 6c6d561e394817c7..5ddd83224bc8eb77 100644 +--- a/sysdeps/i386/nptl/tcb-access.h ++++ b/sysdeps/i386/nptl/tcb-access.h +@@ -41,6 +41,8 @@ + } \ + __value; }) + ++/* THREAD_GETMEM already forces a read. */ ++#define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member) + + /* Same as THREAD_GETMEM, but the member offset can be non-constant. */ + #define THREAD_GETMEM_NC(descr, member, idx) \ +diff --git a/sysdeps/nptl/tcb-access.h b/sysdeps/nptl/tcb-access.h +index b4137b8ab8067915..bbe20b7225b060fd 100644 +--- a/sysdeps/nptl/tcb-access.h ++++ b/sysdeps/nptl/tcb-access.h +@@ -22,6 +22,8 @@ + + #define THREAD_GETMEM(descr, member) \ + descr->member ++#define THREAD_GETMEM_VOLATILE(descr, member) \ ++ (*(volatile __typeof (descr->member) *)&descr->member) + #define THREAD_GETMEM_NC(descr, member, idx) \ + descr->member[idx] + #define THREAD_SETMEM(descr, member, value) \ +diff --git a/sysdeps/x86_64/nptl/tcb-access.h b/sysdeps/x86_64/nptl/tcb-access.h +index 18848a729d16a4f5..e4d2d07a9b218025 100644 +--- a/sysdeps/x86_64/nptl/tcb-access.h ++++ b/sysdeps/x86_64/nptl/tcb-access.h +@@ -39,6 +39,8 @@ + } \ + __value; }) + ++/* THREAD_GETMEM already forces a read. */ ++#define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member) + + /* Same as THREAD_GETMEM, but the member offset can be non-constant. */ + # define THREAD_GETMEM_NC(descr, member, idx) \ diff --git a/SOURCES/glibc-rh2024347-7.patch b/SOURCES/glibc-rh2024347-7.patch new file mode 100644 index 0000000..b0d158b --- /dev/null +++ b/SOURCES/glibc-rh2024347-7.patch @@ -0,0 +1,1130 @@ +commit 95e114a0919d844d8fe07839cb6538b7f5ee920e +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Add rseq registration + + The rseq area is placed directly into struct pthread. rseq + registration failure is not treated as an error, so it is possible + that threads run with inconsistent registration status. + + is not yet installed as a public header. + + Co-Authored-By: Mathieu Desnoyers + Reviewed-by: Szabolcs Nagy + Reviewed-by: Siddhesh Poyarekar + +diff --git a/nptl/descr.h b/nptl/descr.h +index 57be5b4fef564b36..dabf980e29615db3 100644 +--- a/nptl/descr.h ++++ b/nptl/descr.h +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + #ifndef TCB_ALIGNMENT + # define TCB_ALIGNMENT 32 +@@ -407,6 +408,9 @@ struct pthread + /* Used on strsignal. */ + struct tls_internal_t tls_state; + ++ /* rseq area registered with the kernel. */ ++ struct rseq rseq_area; ++ + /* This member must be last. */ + char end_padding[]; + +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index 3db0c9fdf40ae2bf..d2b40924dafad316 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include "libioP.h" + #include + #include +@@ -367,6 +368,9 @@ start_thread (void *arg) + /* Initialize pointers to locale data. */ + __ctype_init (); + ++ /* Register rseq TLS to the kernel. */ ++ rseq_register_current_thread (pd); ++ + #ifndef __ASSUME_SET_ROBUST_LIST + if (__nptl_set_robust_list_avail) + #endif +@@ -572,6 +576,15 @@ out: + process is really dead since 'clone' got passed the CLONE_CHILD_CLEARTID + flag. The 'tid' field in the TCB will be set to zero. + ++ rseq TLS is still registered at this point. Rely on implicit ++ unregistration performed by the kernel on thread teardown. This is not a ++ problem because the rseq TLS lives on the stack, and the stack outlives ++ the thread. If TCB allocation is ever changed, additional steps may be ++ required, such as performing explicit rseq unregistration before ++ reclaiming the rseq TLS area memory. It is NOT sufficient to block ++ signals because the kernel may write to the rseq area even without ++ signals. ++ + The exit code is zero since in case all threads exit by calling + 'pthread_exit' the exit status must be 0 (zero). */ + while (1) +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index ca494dd3a52c4ebf..fedb876fdb2642d2 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #ifndef __ASSUME_SET_ROBUST_LIST + bool __nptl_set_robust_list_avail; +@@ -57,11 +58,12 @@ __tls_pre_init_tp (void) + void + __tls_init_tp (void) + { ++ struct pthread *pd = THREAD_SELF; ++ + /* Set up thread stack list management. */ +- list_add (&THREAD_SELF->list, &GL (dl_stack_user)); ++ list_add (&pd->list, &GL (dl_stack_user)); + + /* Early initialization of the TCB. */ +- struct pthread *pd = THREAD_SELF; + pd->tid = INTERNAL_SYSCALL_CALL (set_tid_address, &pd->tid); + THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]); + THREAD_SETMEM (pd, user_stack, true); +@@ -90,6 +92,8 @@ __tls_init_tp (void) + } + } + ++ rseq_register_current_thread (pd); ++ + /* Set initial thread's stack block from 0 up to __libc_stack_end. + It will be bigger than it actually is, but for unwind.c/pt-longjmp.c + purposes this is good enough. */ +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 76ad06361c4323d7..f84ccd6bbb3b16ad 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -130,7 +130,10 @@ ifeq ($(have-GLIBC_2.27)$(build-shared),yesyes) + tests += tst-ofdlocks-compat + endif + +-tests-internal += tst-sigcontext-get_pc ++tests-internal += \ ++ tst-rseq \ ++ tst-sigcontext-get_pc \ ++ # tests-internal + + tests-time64 += \ + tst-adjtimex-time64 \ +@@ -356,4 +359,8 @@ endif + + ifeq ($(subdir),nptl) + tests += tst-align-clone tst-getpid1 ++ ++# tst-rseq-nptl is an internal test because it requires a definition of ++# __NR_rseq from the internal system call list. ++tests-internal += tst-rseq-nptl + endif +diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/rseq.h b/sysdeps/unix/sysv/linux/aarch64/bits/rseq.h +new file mode 100644 +index 0000000000000000..9ba92725c76b9d4f +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/aarch64/bits/rseq.h +@@ -0,0 +1,43 @@ ++/* Restartable Sequences Linux aarch64 architecture header. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ aarch64 -mbig-endian generates mixed endianness code vs data: ++ little-endian code and big-endian data. Ensure the RSEQ_SIG signature ++ matches code endianness. */ ++ ++#define RSEQ_SIG_CODE 0xd428bc00 /* BRK #0x45E0. */ ++ ++#ifdef __AARCH64EB__ ++# define RSEQ_SIG_DATA 0x00bc28d4 /* BRK #0x45E0. */ ++#else ++# define RSEQ_SIG_DATA RSEQ_SIG_CODE ++#endif ++ ++#define RSEQ_SIG RSEQ_SIG_DATA +diff --git a/sysdeps/unix/sysv/linux/arm/bits/rseq.h b/sysdeps/unix/sysv/linux/arm/bits/rseq.h +new file mode 100644 +index 0000000000000000..0542b26f6a023dec +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/arm/bits/rseq.h +@@ -0,0 +1,83 @@ ++/* Restartable Sequences Linux arm architecture header. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* ++ RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ - ARM little endian ++ ++ RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand ++ value 0x5de3. This traps if user-space reaches this instruction by mistake, ++ and the uncommon operand ensures the kernel does not move the instruction ++ pointer to attacker-controlled code on rseq abort. ++ ++ The instruction pattern in the A32 instruction set is: ++ ++ e7f5def3 udf #24035 ; 0x5de3 ++ ++ This translates to the following instruction pattern in the T16 instruction ++ set: ++ ++ little endian: ++ def3 udf #243 ; 0xf3 ++ e7f5 b.n <7f5> ++ ++ - ARMv6+ big endian (BE8): ++ ++ ARMv6+ -mbig-endian generates mixed endianness code vs data: little-endian ++ code and big-endian data. The data value of the signature needs to have its ++ byte order reversed to generate the trap instruction: ++ ++ Data: 0xf3def5e7 ++ ++ Translates to this A32 instruction pattern: ++ ++ e7f5def3 udf #24035 ; 0x5de3 ++ ++ Translates to this T16 instruction pattern: ++ ++ def3 udf #243 ; 0xf3 ++ e7f5 b.n <7f5> ++ ++ - Prior to ARMv6 big endian (BE32): ++ ++ Prior to ARMv6, -mbig-endian generates big-endian code and data ++ (which match), so the endianness of the data representation of the ++ signature should not be reversed. However, the choice between BE32 ++ and BE8 is done by the linker, so we cannot know whether code and ++ data endianness will be mixed before the linker is invoked. So rather ++ than try to play tricks with the linker, the rseq signature is simply ++ data (not a trap instruction) prior to ARMv6 on big endian. This is ++ why the signature is expressed as data (.word) rather than as ++ instruction (.inst) in assembler. */ ++ ++#ifdef __ARMEB__ ++# define RSEQ_SIG 0xf3def5e7 /* udf #24035 ; 0x5de3 (ARMv6+) */ ++#else ++# define RSEQ_SIG 0xe7f5def3 /* udf #24035 ; 0x5de3 */ ++#endif +diff --git a/sysdeps/unix/sysv/linux/bits/rseq.h b/sysdeps/unix/sysv/linux/bits/rseq.h +new file mode 100644 +index 0000000000000000..46cf5d1c743f25eb +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/bits/rseq.h +@@ -0,0 +1,29 @@ ++/* Restartable Sequences architecture header. Stub version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. */ +diff --git a/sysdeps/unix/sysv/linux/mips/bits/rseq.h b/sysdeps/unix/sysv/linux/mips/bits/rseq.h +new file mode 100644 +index 0000000000000000..a9defee568ae04a5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/mips/bits/rseq.h +@@ -0,0 +1,62 @@ ++/* Restartable Sequences Linux mips architecture header. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ RSEQ_SIG uses the break instruction. The instruction pattern is: ++ ++ On MIPS: ++ 0350000d break 0x350 ++ ++ On nanoMIPS: ++ 00100350 break 0x350 ++ ++ On microMIPS: ++ 0000d407 break 0x350 ++ ++ For nanoMIPS32 and microMIPS, the instruction stream is encoded as ++ 16-bit halfwords, so the signature halfwords need to be swapped ++ accordingly for little-endian. */ ++ ++#if defined (__nanomips__) ++# ifdef __MIPSEL__ ++# define RSEQ_SIG 0x03500010 ++# else ++# define RSEQ_SIG 0x00100350 ++# endif ++#elif defined (__mips_micromips) ++# ifdef __MIPSEL__ ++# define RSEQ_SIG 0xd4070000 ++# else ++# define RSEQ_SIG 0x0000d407 ++# endif ++#elif defined (__mips__) ++# define RSEQ_SIG 0x0350000d ++#else ++/* Unknown MIPS architecture. */ ++#endif +diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/rseq.h b/sysdeps/unix/sysv/linux/powerpc/bits/rseq.h +new file mode 100644 +index 0000000000000000..05b3cf7b8fe75b92 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/powerpc/bits/rseq.h +@@ -0,0 +1,37 @@ ++/* Restartable Sequences Linux powerpc architecture header. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ RSEQ_SIG uses the following trap instruction: ++ ++ powerpc-be: 0f e5 00 0b twui r5,11 ++ powerpc64-le: 0b 00 e5 0f twui r5,11 ++ powerpc64-be: 0f e5 00 0b twui r5,11 */ ++ ++#define RSEQ_SIG 0x0fe5000b +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +new file mode 100644 +index 0000000000000000..909f5478251d3d13 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -0,0 +1,45 @@ ++/* Restartable Sequences internal API. Linux implementation. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef RSEQ_INTERNAL_H ++#define RSEQ_INTERNAL_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef RSEQ_SIG ++static inline void ++rseq_register_current_thread (struct pthread *self) ++{ ++ int ret = INTERNAL_SYSCALL_CALL (rseq, ++ &self->rseq_area, sizeof (self->rseq_area), ++ 0, RSEQ_SIG); ++ if (INTERNAL_SYSCALL_ERROR_P (ret)) ++ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++} ++#else /* RSEQ_SIG */ ++static inline void ++rseq_register_current_thread (struct pthread *self) ++{ ++ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++} ++#endif /* RSEQ_SIG */ ++ ++#endif /* rseq-internal.h */ +diff --git a/sysdeps/unix/sysv/linux/s390/bits/rseq.h b/sysdeps/unix/sysv/linux/s390/bits/rseq.h +new file mode 100644 +index 0000000000000000..3030e38f403784b3 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/s390/bits/rseq.h +@@ -0,0 +1,37 @@ ++/* Restartable Sequences Linux s390 architecture header. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ It is a 32-bit value that maps to actual architecture code compiled ++ into applications and libraries. It needs to be defined for each ++ architecture. When choosing this value, it needs to be taken into ++ account that generating invalid instructions may have ill effects on ++ tools like objdump, and may also have impact on the CPU speculative ++ execution efficiency in some cases. ++ ++ RSEQ_SIG uses the trap4 instruction. As Linux does not make use of the ++ access-register mode nor the linkage stack this instruction will always ++ cause a special-operation exception (the trap-enabled bit in the DUCT ++ is and will stay 0). The instruction pattern is ++ b2 ff 0f ff trap4 4095(%r0) */ ++ ++#define RSEQ_SIG 0xB2FF0FFF +diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h +new file mode 100644 +index 0000000000000000..c8edff50d40e29b6 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sys/rseq.h +@@ -0,0 +1,174 @@ ++/* Restartable Sequences exported symbols. Linux header. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++#define _SYS_RSEQ_H 1 ++ ++/* Architecture-specific rseq signature. */ ++#include ++ ++#include ++#include ++#include ++ ++#ifdef __has_include ++# if __has_include ("linux/rseq.h") ++# define __GLIBC_HAVE_KERNEL_RSEQ ++# endif ++#else ++# include ++# if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 18, 0) ++# define __GLIBC_HAVE_KERNEL_RSEQ ++# endif ++#endif ++ ++#ifdef __GLIBC_HAVE_KERNEL_RSEQ ++/* We use the structures declarations from the kernel headers. */ ++# include ++#else /* __GLIBC_HAVE_KERNEL_RSEQ */ ++/* We use a copy of the include/uapi/linux/rseq.h kernel header. */ ++ ++enum rseq_cpu_id_state ++ { ++ RSEQ_CPU_ID_UNINITIALIZED = -1, ++ RSEQ_CPU_ID_REGISTRATION_FAILED = -2, ++ }; ++ ++enum rseq_flags ++ { ++ RSEQ_FLAG_UNREGISTER = (1 << 0), ++ }; ++ ++enum rseq_cs_flags_bit ++ { ++ RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0, ++ RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1, ++ RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2, ++ }; ++ ++enum rseq_cs_flags ++ { ++ RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = ++ (1U << RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT), ++ RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = ++ (1U << RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT), ++ RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = ++ (1U << RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT), ++ }; ++ ++/* struct rseq_cs is aligned on 32 bytes to ensure it is always ++ contained within a single cache-line. It is usually declared as ++ link-time constant data. */ ++struct rseq_cs ++ { ++ /* Version of this structure. */ ++ uint32_t version; ++ /* enum rseq_cs_flags. */ ++ uint32_t flags; ++ uint64_t start_ip; ++ /* Offset from start_ip. */ ++ uint64_t post_commit_offset; ++ uint64_t abort_ip; ++ } __attribute__ ((__aligned__ (32))); ++ ++/* struct rseq is aligned on 32 bytes to ensure it is always ++ contained within a single cache-line. ++ ++ A single struct rseq per thread is allowed. */ ++struct rseq ++ { ++ /* Restartable sequences cpu_id_start field. Updated by the ++ kernel. Read by user-space with single-copy atomicity ++ semantics. This field should only be read by the thread which ++ registered this data structure. Aligned on 32-bit. Always ++ contains a value in the range of possible CPUs, although the ++ value may not be the actual current CPU (e.g. if rseq is not ++ initialized). This CPU number value should always be compared ++ against the value of the cpu_id field before performing a rseq ++ commit or returning a value read from a data structure indexed ++ using the cpu_id_start value. */ ++ uint32_t cpu_id_start; ++ /* Restartable sequences cpu_id field. Updated by the kernel. ++ Read by user-space with single-copy atomicity semantics. This ++ field should only be read by the thread which registered this ++ data structure. Aligned on 32-bit. Values ++ RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED ++ have a special semantic: the former means "rseq uninitialized", ++ and latter means "rseq initialization failed". This value is ++ meant to be read within rseq critical sections and compared ++ with the cpu_id_start value previously read, before performing ++ the commit instruction, or read and compared with the ++ cpu_id_start value before returning a value loaded from a data ++ structure indexed using the cpu_id_start value. */ ++ uint32_t cpu_id; ++ /* Restartable sequences rseq_cs field. ++ ++ Contains NULL when no critical section is active for the current ++ thread, or holds a pointer to the currently active struct rseq_cs. ++ ++ Updated by user-space, which sets the address of the currently ++ active rseq_cs at the beginning of assembly instruction sequence ++ block, and set to NULL by the kernel when it restarts an assembly ++ instruction sequence block, as well as when the kernel detects that ++ it is preempting or delivering a signal outside of the range ++ targeted by the rseq_cs. Also needs to be set to NULL by user-space ++ before reclaiming memory that contains the targeted struct rseq_cs. ++ ++ Read and set by the kernel. Set by user-space with single-copy ++ atomicity semantics. This field should only be updated by the ++ thread which registered this data structure. Aligned on 64-bit. */ ++ union ++ { ++ uint64_t ptr64; ++# ifdef __LP64__ ++ uint64_t ptr; ++# else /* __LP64__ */ ++ struct ++ { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ uint32_t padding; /* Initialized to zero. */ ++ uint32_t ptr32; ++# else /* LITTLE */ ++ uint32_t ptr32; ++ uint32_t padding; /* Initialized to zero. */ ++# endif /* ENDIAN */ ++ } ptr; ++# endif /* __LP64__ */ ++ } rseq_cs; ++ ++ /* Restartable sequences flags field. ++ ++ This field should only be updated by the thread which ++ registered this data structure. Read by the kernel. ++ Mainly used for single-stepping through rseq critical sections ++ with debuggers. ++ ++ - RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT ++ Inhibit instruction sequence block restart on preemption ++ for this thread. ++ - RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL ++ Inhibit instruction sequence block restart on signal ++ delivery for this thread. ++ - RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE ++ Inhibit instruction sequence block restart on migration for ++ this thread. */ ++ uint32_t flags; ++ } __attribute__ ((__aligned__ (32))); ++ ++#endif /* __GLIBC_HAVE_KERNEL_RSEQ */ ++ ++#endif /* sys/rseq.h */ +diff --git a/sysdeps/unix/sysv/linux/tst-rseq-nptl.c b/sysdeps/unix/sysv/linux/tst-rseq-nptl.c +new file mode 100644 +index 0000000000000000..d31d94445caa9ee3 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-rseq-nptl.c +@@ -0,0 +1,260 @@ ++/* Restartable Sequences NPTL test. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* These tests validate that rseq is registered from various execution ++ contexts (main thread, destructor, other threads, other threads created ++ from destructor, forked process (without exec), pthread_atfork handlers, ++ pthread setspecific destructors, signal handlers, atexit handlers). ++ ++ See the Linux kernel selftests for extensive rseq stress-tests. */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef RSEQ_SIG ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include "tst-rseq.h" ++ ++static pthread_key_t rseq_test_key; ++ ++static void ++atfork_prepare (void) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in pthread atfork prepare\n"); ++ support_record_failure (); ++ } ++} ++ ++static void ++atfork_parent (void) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in pthread atfork parent\n"); ++ support_record_failure (); ++ } ++} ++ ++static void ++atfork_child (void) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in pthread atfork child\n"); ++ support_record_failure (); ++ } ++} ++ ++static void ++rseq_key_destructor (void *arg) ++{ ++ /* Cannot use deferred failure reporting after main returns. */ ++ if (!rseq_thread_registered ()) ++ FAIL_EXIT1 ("rseq not registered in pthread key destructor"); ++} ++ ++static void ++atexit_handler (void) ++{ ++ /* Cannot use deferred failure reporting after main returns. */ ++ if (!rseq_thread_registered ()) ++ FAIL_EXIT1 ("rseq not registered in atexit handler"); ++} ++ ++/* Used to avoid -Werror=stringop-overread warning with ++ pthread_setspecific and GCC 11. */ ++static char one = 1; ++ ++static void ++do_rseq_main_test (void) ++{ ++ TEST_COMPARE (atexit (atexit_handler), 0); ++ rseq_test_key = xpthread_key_create (rseq_key_destructor); ++ TEST_COMPARE (pthread_atfork (atfork_prepare, atfork_parent, atfork_child), 0); ++ xraise (SIGUSR1); ++ TEST_COMPARE (pthread_setspecific (rseq_test_key, &one), 0); ++ TEST_VERIFY_EXIT (rseq_thread_registered ()); ++} ++ ++static void ++cancel_routine (void *arg) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in cancel routine\n"); ++ support_record_failure (); ++ } ++} ++ ++static pthread_barrier_t cancel_thread_barrier; ++static pthread_cond_t cancel_thread_cond = PTHREAD_COND_INITIALIZER; ++static pthread_mutex_t cancel_thread_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++static void ++test_cancel_thread (void) ++{ ++ pthread_cleanup_push (cancel_routine, NULL); ++ (void) xpthread_barrier_wait (&cancel_thread_barrier); ++ /* Wait forever until cancellation. */ ++ xpthread_cond_wait (&cancel_thread_cond, &cancel_thread_mutex); ++ pthread_cleanup_pop (0); ++} ++ ++static void * ++thread_function (void * arg) ++{ ++ int i = (int) (intptr_t) arg; ++ ++ xraise (SIGUSR1); ++ if (i == 0) ++ test_cancel_thread (); ++ TEST_COMPARE (pthread_setspecific (rseq_test_key, &one), 0); ++ return rseq_thread_registered () ? NULL : (void *) 1l; ++} ++ ++static void ++sighandler (int sig) ++{ ++ if (!rseq_thread_registered ()) ++ { ++ printf ("error: rseq not registered in signal handler\n"); ++ support_record_failure (); ++ } ++} ++ ++static void ++setup_signals (void) ++{ ++ struct sigaction sa; ++ ++ sigemptyset (&sa.sa_mask); ++ sigaddset (&sa.sa_mask, SIGUSR1); ++ sa.sa_flags = 0; ++ sa.sa_handler = sighandler; ++ xsigaction (SIGUSR1, &sa, NULL); ++} ++ ++static int ++do_rseq_threads_test (int nr_threads) ++{ ++ pthread_t th[nr_threads]; ++ int i; ++ int result = 0; ++ ++ xpthread_barrier_init (&cancel_thread_barrier, NULL, 2); ++ ++ for (i = 0; i < nr_threads; ++i) ++ th[i] = xpthread_create (NULL, thread_function, ++ (void *) (intptr_t) i); ++ ++ (void) xpthread_barrier_wait (&cancel_thread_barrier); ++ ++ xpthread_cancel (th[0]); ++ ++ for (i = 0; i < nr_threads; ++i) ++ { ++ void *v; ++ ++ v = xpthread_join (th[i]); ++ if (i != 0 && v != NULL) ++ { ++ printf ("error: join %d successful, but child failed\n", i); ++ result = 1; ++ } ++ else if (i == 0 && v == NULL) ++ { ++ printf ("error: join %d successful, child did not fail as expected\n", i); ++ result = 1; ++ } ++ } ++ ++ xpthread_barrier_destroy (&cancel_thread_barrier); ++ ++ return result; ++} ++ ++static void ++subprocess_callback (void *closure) ++{ ++ do_rseq_main_test (); ++} ++ ++static void ++do_rseq_fork_test (void) ++{ ++ support_isolate_in_subprocess (subprocess_callback, NULL); ++} ++ ++static int ++do_rseq_test (void) ++{ ++ int t[] = { 1, 2, 6, 5, 4, 3, 50 }; ++ int i, result = 0; ++ ++ if (!rseq_available ()) ++ FAIL_UNSUPPORTED ("kernel does not support rseq, skipping test"); ++ setup_signals (); ++ xraise (SIGUSR1); ++ do_rseq_main_test (); ++ for (i = 0; i < array_length (t); i++) ++ if (do_rseq_threads_test (t[i])) ++ result = 1; ++ do_rseq_fork_test (); ++ return result; ++} ++ ++static void __attribute__ ((destructor)) ++do_rseq_destructor_test (void) ++{ ++ /* Cannot use deferred failure reporting after main returns. */ ++ if (do_rseq_test ()) ++ FAIL_EXIT1 ("rseq not registered within destructor"); ++ xpthread_key_delete (rseq_test_key); ++} ++ ++#else /* RSEQ_SIG */ ++static int ++do_rseq_test (void) ++{ ++ FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test"); ++ return 0; ++} ++#endif /* RSEQ_SIG */ ++ ++static int ++do_test (void) ++{ ++ return do_rseq_test (); ++} ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c +new file mode 100644 +index 0000000000000000..926376b6a5446ece +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-rseq.c +@@ -0,0 +1,64 @@ ++/* Restartable Sequences single-threaded tests. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* These tests validate that rseq is registered from main in an executable ++ not linked against libpthread. */ ++ ++#include ++#include ++#include ++#include ++ ++#ifdef RSEQ_SIG ++# include ++# include ++# include ++# include ++# include ++# include "tst-rseq.h" ++ ++static void ++do_rseq_main_test (void) ++{ ++ TEST_VERIFY_EXIT (rseq_thread_registered ()); ++} ++ ++static void ++do_rseq_test (void) ++{ ++ if (!rseq_available ()) ++ { ++ FAIL_UNSUPPORTED ("kernel does not support rseq, skipping test"); ++ } ++ do_rseq_main_test (); ++} ++#else /* RSEQ_SIG */ ++static void ++do_rseq_test (void) ++{ ++ FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test"); ++} ++#endif /* RSEQ_SIG */ ++ ++static int ++do_test (void) ++{ ++ do_rseq_test (); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.h b/sysdeps/unix/sysv/linux/tst-rseq.h +new file mode 100644 +index 0000000000000000..a476c316fc2671a0 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-rseq.h +@@ -0,0 +1,57 @@ ++/* Restartable Sequences tests header. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static inline bool ++rseq_thread_registered (void) ++{ ++ return THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id) >= 0; ++} ++ ++static inline int ++sys_rseq (struct rseq *rseq_abi, uint32_t rseq_len, int flags, uint32_t sig) ++{ ++ return syscall (__NR_rseq, rseq_abi, rseq_len, flags, sig); ++} ++ ++static inline bool ++rseq_available (void) ++{ ++ int rc; ++ ++ rc = sys_rseq (NULL, 0, 0, 0); ++ if (rc != -1) ++ FAIL_EXIT1 ("Unexpected rseq return value %d", rc); ++ switch (errno) ++ { ++ case ENOSYS: ++ return false; ++ case EINVAL: ++ /* rseq is implemented, but detected an invalid rseq_len parameter. */ ++ return true; ++ default: ++ FAIL_EXIT1 ("Unexpected rseq error %s", strerror (errno)); ++ } ++} +diff --git a/sysdeps/unix/sysv/linux/x86/bits/rseq.h b/sysdeps/unix/sysv/linux/x86/bits/rseq.h +new file mode 100644 +index 0000000000000000..9fc909e7c8a25bbb +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86/bits/rseq.h +@@ -0,0 +1,30 @@ ++/* Restartable Sequences Linux x86 architecture header. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_RSEQ_H ++# error "Never use directly; include instead." ++#endif ++ ++/* RSEQ_SIG is a signature required before each abort handler code. ++ ++ RSEQ_SIG is used with the following reserved undefined instructions, which ++ trap in user-space: ++ ++ x86-32: 0f b9 3d 53 30 05 53 ud1 0x53053053,%edi ++ x86-64: 0f b9 3d 53 30 05 53 ud1 0x53053053(%rip),%edi */ ++ ++#define RSEQ_SIG 0x53053053 diff --git a/SOURCES/glibc-rh2024347-8.patch b/SOURCES/glibc-rh2024347-8.patch new file mode 100644 index 0000000..1436fe1 --- /dev/null +++ b/SOURCES/glibc-rh2024347-8.patch @@ -0,0 +1,43 @@ +commit 1d350aa06091211863e41169729cee1bca39f72f +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + Linux: Use rseq to accelerate sched_getcpu + + Co-Authored-By: Mathieu Desnoyers + Reviewed-by: Szabolcs Nagy + +diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c +index c41e986f2cab5e42..6f78edaea1495342 100644 +--- a/sysdeps/unix/sysv/linux/sched_getcpu.c ++++ b/sysdeps/unix/sysv/linux/sched_getcpu.c +@@ -20,8 +20,8 @@ + #include + #include + +-int +-sched_getcpu (void) ++static int ++vsyscall_sched_getcpu (void) + { + unsigned int cpu; + int r = -1; +@@ -32,3 +32,18 @@ sched_getcpu (void) + #endif + return r == -1 ? r : cpu; + } ++ ++#ifdef RSEQ_SIG ++int ++sched_getcpu (void) ++{ ++ int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id); ++ return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu (); ++} ++#else /* RSEQ_SIG */ ++int ++sched_getcpu (void) ++{ ++ return vsyscall_sched_getcpu (); ++} ++#endif /* RSEQ_SIG */ diff --git a/SOURCES/glibc-rh2024347-9.patch b/SOURCES/glibc-rh2024347-9.patch new file mode 100644 index 0000000..af25983 --- /dev/null +++ b/SOURCES/glibc-rh2024347-9.patch @@ -0,0 +1,278 @@ +commit e3e589829d16af9f7e73c7b70f74f3c5d5003e45 +Author: Florian Weimer +Date: Thu Dec 9 09:49:32 2021 +0100 + + nptl: Add glibc.pthread.rseq tunable to control rseq registration + + This tunable allows applications to register the rseq area instead + of glibc. + + Reviewed-by: Szabolcs Nagy + Reviewed-by: Siddhesh Poyarekar + +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 658547c6137bf177..1f5c410288eeecec 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -413,6 +413,16 @@ The value is measured in bytes. The default is @samp{41943040} + (fourty mibibytes). + @end deftp + ++@deftp Tunable glibc.pthread.rseq ++The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable ++restartable sequences support in @theglibc{}. This enables applications ++to perform direct restartable sequence registration with the kernel. ++The default is @samp{1}, which means that @theglibc{} performs ++registration on behalf of the application. ++ ++Restartable sequences are a Linux-specific extension. ++@end deftp ++ + @node Hardware Capability Tunables + @section Hardware Capability Tunables + @cindex hardware capability tunables +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index d2b40924dafad316..f405fa356c2955ce 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -369,7 +369,10 @@ start_thread (void *arg) + __ctype_init (); + + /* Register rseq TLS to the kernel. */ +- rseq_register_current_thread (pd); ++ { ++ bool do_rseq = THREAD_GETMEM (pd, flags) & ATTR_FLAG_DO_RSEQ; ++ rseq_register_current_thread (pd, do_rseq); ++ } + + #ifndef __ASSUME_SET_ROBUST_LIST + if (__nptl_set_robust_list_avail) +@@ -678,6 +681,11 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr, + pd->flags = ((iattr->flags & ~(ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)) + | (self->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))); + ++ /* Inherit rseq registration state. Without seccomp filters, rseq ++ registration will either always fail or always succeed. */ ++ if ((int) THREAD_GETMEM_VOLATILE (self, rseq_area.cpu_id) >= 0) ++ pd->flags |= ATTR_FLAG_DO_RSEQ; ++ + /* Initialize the field for the ID of the thread which is waiting + for us. This is a self-reference in case the thread is created + detached. */ +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index fedb876fdb2642d2..b39dfbff2c6678d5 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -23,6 +23,9 @@ + #include + #include + ++#define TUNABLE_NAMESPACE pthread ++#include ++ + #ifndef __ASSUME_SET_ROBUST_LIST + bool __nptl_set_robust_list_avail; + rtld_hidden_data_def (__nptl_set_robust_list_avail) +@@ -92,7 +95,13 @@ __tls_init_tp (void) + } + } + +- rseq_register_current_thread (pd); ++ { ++ bool do_rseq = true; ++#if HAVE_TUNABLES ++ do_rseq = TUNABLE_GET (rseq, int, NULL); ++#endif ++ rseq_register_current_thread (pd, do_rseq); ++ } + + /* Set initial thread's stack block from 0 up to __libc_stack_end. + It will be bigger than it actually is, but for unwind.c/pt-longjmp.c +diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list +index ac5d053298725468..d24f4be0d08ba407 100644 +--- a/sysdeps/nptl/dl-tunables.list ++++ b/sysdeps/nptl/dl-tunables.list +@@ -27,5 +27,11 @@ glibc { + type: SIZE_T + default: 41943040 + } ++ rseq { ++ type: INT_32 ++ minval: 0 ++ maxval: 1 ++ default: 1 ++ } + } + } +diff --git a/sysdeps/nptl/internaltypes.h b/sysdeps/nptl/internaltypes.h +index 50a2ad19ae7210ae..8205c6d15a918952 100644 +--- a/sysdeps/nptl/internaltypes.h ++++ b/sysdeps/nptl/internaltypes.h +@@ -49,6 +49,7 @@ struct pthread_attr + #define ATTR_FLAG_OLDATTR 0x0010 + #define ATTR_FLAG_SCHED_SET 0x0020 + #define ATTR_FLAG_POLICY_SET 0x0040 ++#define ATTR_FLAG_DO_RSEQ 0x0080 + + /* Used to allocate a pthread_attr_t object which is also accessed + internally. */ +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index f84ccd6bbb3b16ad..d30d21898b402d1e 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -135,6 +135,12 @@ tests-internal += \ + tst-sigcontext-get_pc \ + # tests-internal + ++ifneq (no,$(have-tunables)) ++tests-internal += \ ++ tst-rseq-disable \ ++ # tests-internal $(have-tunables) ++endif ++ + tests-time64 += \ + tst-adjtimex-time64 \ + tst-clock_adjtime-time64 \ +@@ -226,6 +232,8 @@ $(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-consts.py + < /dev/null > $@ 2>&1; $(evaluate-test) + $(objpfx)tst-mman-consts.out: $(sysdeps-linux-python-deps) + ++tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0 ++ + endif # $(subdir) == misc + + ifeq ($(subdir),time) +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index 909f5478251d3d13..15bc7ffd6eda632d 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -21,22 +21,27 @@ + #include + #include + #include ++#include + #include + #include + + #ifdef RSEQ_SIG + static inline void +-rseq_register_current_thread (struct pthread *self) ++rseq_register_current_thread (struct pthread *self, bool do_rseq) + { +- int ret = INTERNAL_SYSCALL_CALL (rseq, +- &self->rseq_area, sizeof (self->rseq_area), +- 0, RSEQ_SIG); +- if (INTERNAL_SYSCALL_ERROR_P (ret)) +- THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++ if (do_rseq) ++ { ++ int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area, ++ sizeof (self->rseq_area), ++ 0, RSEQ_SIG); ++ if (!INTERNAL_SYSCALL_ERROR_P (ret)) ++ return; ++ } ++ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); + } + #else /* RSEQ_SIG */ + static inline void +-rseq_register_current_thread (struct pthread *self) ++rseq_register_current_thread (struct pthread *self, bool do_rseq) + { + THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); + } +diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c +new file mode 100644 +index 0000000000000000..000e351872fc2f76 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c +@@ -0,0 +1,89 @@ ++/* Test disabling of rseq registration via tunable. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef RSEQ_SIG ++ ++/* Check that rseq can be registered and has not been taken by glibc. */ ++static void ++check_rseq_disabled (void) ++{ ++ struct pthread *pd = THREAD_SELF; ++ TEST_COMPARE ((int) pd->rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); ++ ++ int ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area), ++ 0, RSEQ_SIG); ++ if (ret == 0) ++ { ++ ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area), ++ RSEQ_FLAG_UNREGISTER, RSEQ_SIG); ++ TEST_COMPARE (ret, 0); ++ pd->rseq_area.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; ++ } ++ else ++ { ++ TEST_VERIFY (errno != -EINVAL); ++ TEST_VERIFY (errno != -EBUSY); ++ } ++} ++ ++static void * ++thread_func (void *ignored) ++{ ++ check_rseq_disabled (); ++ return NULL; ++} ++ ++static void ++proc_func (void *ignored) ++{ ++ check_rseq_disabled (); ++} ++ ++static int ++do_test (void) ++{ ++ puts ("info: checking main thread"); ++ check_rseq_disabled (); ++ ++ puts ("info: checking main thread (2)"); ++ check_rseq_disabled (); ++ ++ puts ("info: checking new thread"); ++ xpthread_join (xpthread_create (NULL, thread_func, NULL)); ++ ++ puts ("info: checking subprocess"); ++ support_isolate_in_subprocess (proc_func, NULL); ++ ++ return 0; ++} ++#else /* !RSEQ_SIG */ ++static int ++do_test (void) ++{ ++ FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test"); ++} ++#endif ++ ++#include diff --git a/SOURCES/glibc-rh2032647-1.patch b/SOURCES/glibc-rh2032647-1.patch new file mode 100644 index 0000000..ebc11b1 --- /dev/null +++ b/SOURCES/glibc-rh2032647-1.patch @@ -0,0 +1,2024 @@ +commit e6fd79f3795d46dfb583e124be49fc063bc3d58b +Author: Chung-Lin Tang +Date: Thu Oct 21 21:41:21 2021 +0800 + + elf: Testing infrastructure for ld.so DSO sorting (BZ #17645) + + This is the first of a 2-part patch set that fixes slow DSO sorting behavior in + the dynamic loader, as reported in BZ #17645. In order to facilitate such a + large modification to the dynamic loader, this first patch implements a testing + framework for validating shared object sorting behavior, to enable comparison + between old/new sorting algorithms, and any later enhancements. + + This testing infrastructure consists of a Python script + scripts/dso-ordering-test.py' which takes in a description language, consisting + of strings that describe a set of link dependency relations between DSOs, and + generates testcase programs and Makefile fragments to automatically test the + described situation, for example: + + a->b->c->d # four objects linked one after another + + a->[bc]->d;b->c # a depends on b and c, which both depend on d, + # b depends on c (b,c linked to object a in fixed order) + + a->b->c;{+a;%a;-a} # a, b, c serially dependent, main program uses + # dlopen/dlsym/dlclose on object a + + a->b->c;{}!->[abc] # a, b, c serially dependent; multiple tests generated + # to test all permutations of a, b, c ordering linked + # to main program + + (Above is just a short description of what the script can do, more + documentation is in the script comments.) + + Two files containing several new tests, elf/dso-sort-tests-[12].def are added, + including test scenarios for BZ #15311 and Redhat issue #1162810 [1]. + + Due to the nature of dynamic loader tests, where the sorting behavior and test + output occurs before/after main(), generating testcases to use + support/test-driver.c does not suffice to control meaningful timeout for ld.so. + Therefore a new utility program 'support/test-run-command', based on + test-driver.c/support_test_main.c has been added. This does the same testcase + control, but for a program specified through a command-line rather than at the + source code level. This utility is used to run the dynamic loader testcases + generated by dso-ordering-test.py. + + [1] https://bugzilla.redhat.com/show_bug.cgi?id=1162810 + + Signed-off-by: Chung-Lin Tang + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/Makefile b/elf/Makefile +index 3e7debdd81baafe0..8dd2b24328113536 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -471,6 +471,21 @@ tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \ + $(objpfx)tst-unused-dep-cmp.out + endif + ++# DSO sorting tests: ++# The dso-ordering-test.py script generates testcase source files in $(objpfx), ++# creating a $(objpfx)-dir for each testcase, and creates a ++# Makefile fragment to be included. ++define include_dsosort_tests ++$(objpfx)$(1).generated-makefile: $(1) ++ $(PYTHON) $(..)scripts/dso-ordering-test.py \ ++ --description-file $$< --objpfx $(objpfx) --output-makefile $$@ ++include $(objpfx)$(1).generated-makefile ++endef ++ ++# Generate from each testcase description file ++$(eval $(call include_dsosort_tests,dso-sort-tests-1.def)) ++$(eval $(call include_dsosort_tests,dso-sort-tests-2.def)) ++ + check-abi: $(objpfx)check-abi-ld.out + tests-special += $(objpfx)check-abi-ld.out + update-abi: update-abi-ld +diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def +new file mode 100644 +index 0000000000000000..873ddf55d91155c6 +--- /dev/null ++++ b/elf/dso-sort-tests-1.def +@@ -0,0 +1,66 @@ ++# DSO sorting test descriptions. ++# This file is to be processed by ../scripts/dso-ordering-test.py, see usage ++# in elf/Makefile for how it is executed. ++ ++# We test both dynamic loader sorting algorithms ++tunable_option: glibc.rtld.dynamic_sort=1 ++tunable_option: glibc.rtld.dynamic_sort=2 ++ ++# Sequence of single dependencies with no cycles. ++tst-dso-ordering1: a->b->c ++output: c>b>a>{}b->[cd]->e ++output: e>d>c>b>a>{}[bc]->[def]->[gh]->i ++output: i>h>g>f>e>d>c>b>a>{}b->[de];a->c->d->e ++output: e>d>c>b>a>{}c cross link is respected correctly ++tst-dso-ordering5: a!->[bc]->d;b->c ++output: d>c>b>a>{}[bcde]->f ++output: f>e>d>c>b>a>{}[bc];b->[cde];e->f ++output: f>e>d>c>b>a>{}b->c=>a;{}->[ba] ++output: c>b>a>{}b->c->d->e;{}!->[abcde] ++output: e>d>c>b>a>{}a->b->c;soname({})=c ++output: b>a>{}b->c->d order). ++# The older dynamic_sort=1 algorithm does not achieve this, while the DFS-based ++# dynamic_sort=2 algorithm does, although it is still arguable whether going ++# beyond spec to do this is the right thing to do. ++# The below expected outputs are what the two algorithms currently produce ++# respectively, for regression testing purposes. ++tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c ++xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[A101 ++{}->* ++A101->(B101 B163 B122 B181) ++A102->(B102 B140 B199 B158) ++A103->(B103 B117 B176 B135) ++A104->(B104 B194 B153 B112) ++A105->(B105 B171 B130 B189) ++A106->(B106 B148 B107 B166) ++A107->(B107 B125 B184 B143) ++A108->(B108 B102 B161 B120) ++A109->(B109 B179 B138 B197) ++A110->(B110 B156 B115 B174) ++A111->(B111 B133 B192 B151) ++A112->(B112 B110 B169 B128) ++A113->(B113 B187 B146 B105) ++A114->(B114 B164 B123 B182) ++A115->(B115 B141 B200 B159) ++A116->(B116 B118 B177 B136) ++A117->(B117 B195 B154 B113) ++A118->(B118 B172 B131 B190) ++A119->(B119 B149 B108 B167) ++A120->(B120 B126 B185 B144) ++A121->(B121 B103 B162) ++A122->(B122 B180 B139 B198) ++A123->(B123 B157 B116 B175) ++A124->(B124 B134 B193 B152) ++A125->(B125 B111 B170 B129) ++A126->(B126 B188 B147 B106) ++A127->(B127 B165 B124 B183) ++A128->(B128 B142 B101 B160) ++A129->(B129 B119 B178 B137) ++A130->(B130 B196 B155 B114) ++A131->(B131 B173 B132 B191) ++A132->(B132 B150 B109 B168) ++A133->(B133 B127 B186 B145) ++A134->(B134 B104 B163 B122) ++A135->(B135 B181 B140 B199) ++A136->(B136 B158 B117 B176) ++A137->(B137 B135 B194 B153) ++A138->(B138 B112 B171 B130) ++A139->(B139 B189 B148 B107) ++A140->(B140 B166 B125 B184) ++A141->(B141 B143 B102 B161) ++A142->(B142 B120 B179 B138) ++A143->(B143 B197 B156 B115) ++A144->(B144 B174 B133 B192) ++A145->(B145 B151 B110 B169) ++A146->(B146 B128 B187) ++A147->(B147 B105 B164 B123) ++A148->(B148 B182 B141 B200) ++A149->(B149 B159 B118 B177) ++A150->(B150 B136 B195 B154) ++A151->(B151 B113 B172 B131) ++A152->(B152 B190 B149 B108) ++A153->(B153 B167 B126 B185) ++A154->(B154 B144 B103 B162) ++A155->(B155 B121 B180 B139) ++A156->(B156 B198 B157 B116) ++A157->(B157 B175 B134 B193) ++A158->(B158 B152 B111 B170) ++A159->(B159 B129 B188 B147) ++A160->(B160 B106 B165 B124) ++A161->(B161 B183 B142 B101) ++A162->(B162 B160 B119 B178) ++A163->(B163 B137 B196 B155) ++A164->(B164 B114 B173 B132) ++A165->(B165 B191 B150 B109) ++A166->(B166 B168 B127 B186) ++A167->(B167 B145 B104 B163) ++A168->(B168 B122 B181 B140) ++A169->(B169 B199 B158 B117) ++A170->(B170 B176 B135 B194) ++A171->(B171 B153 B112) ++A172->(B172 B130 B189 B148) ++A173->(B173 B107 B166 B125) ++A174->(B174 B184 B143 B102) ++A175->(B175 B161 B120 B179) ++A176->(B176 B138 B197 B156) ++A177->(B177 B115 B174 B133) ++A178->(B178 B192 B151 B110) ++A179->(B179 B169 B128 B187) ++A180->(B180 B146 B105 B164) ++A181->(B181 B123 B182 B141) ++A182->(B182 B200 B159 B118) ++A183->(B183 B177 B136 B195) ++A184->(B184 B154 B113 B172) ++A185->(B185 B131 B190 B149) ++A186->(B186 B108 B167 B126) ++A187->(B187 B185 B144 B103) ++A188->(B188 B162 B121 B180) ++A189->(B189 B139 B198 B157) ++A190->(B190 B116 B175 B134) ++A191->(B191 B193 B152 B111) ++A192->(B192 B170 B129 B188) ++A193->(B193 B147 B106 B165) ++A194->(B194 B124 B183 B142) ++A195->(B195 B101 B160 B119) ++A196->(B196 B178 B137) ++A197->(B197 B155 B114 B173) ++A198->(B198 B132 B191 B150) ++A199->(B199 B109 B168 B127) ++A200->(B200 B186 B145 B104) ++B101->(C101 C164 C123 C182) ++B102->(C102 C141 C200 C159) ++B103->(C103 C118 C177 C136) ++B104->(C104 C195 C154 C113) ++B105->(C105 C172 C131 C190) ++B106->(C106 C149 C108 C167) ++B107->(C107 C126 C185 C144) ++B108->(C108 C103 C162 C121) ++B109->(C109 C180 C139 C198) ++B110->(C110 C157 C116 C175) ++B111->(C111 C134 C193 C152) ++B112->(C112 C111 C170 C129) ++B113->(C113 C188 C147 C106) ++B114->(C114 C165 C124 C183) ++B115->(C115 C142 C101 C160) ++B116->(C116 C119 C178 C137) ++B117->(C117 C196 C155 C114) ++B118->(C118 C173 C132 C191) ++B119->(C119 C150 C109 C168) ++B120->(C120 C127 C186 C145) ++B121->(C121 C104 C163 C122) ++B122->(C122 C181 C140 C199) ++B123->(C123 C158 C117 C176) ++B124->(C124 C135 C194 C153) ++B125->(C125 C112 C171 C130) ++B126->(C126 C189 C148 C107) ++B127->(C127 C166 C125 C184) ++B128->(C128 C143 C102 C161) ++B129->(C129 C120 C179 C138) ++B130->(C130 C197 C156 C115) ++B131->(C131 C174 C133 C192) ++B132->(C132 C151 C110 C169) ++B133->(C133 C128 C187 C146) ++B134->(C134 C105 C164 C123) ++B135->(C135 C182 C141 C200) ++B136->(C136 C159 C118 C177) ++B137->(C137 C136 C195 C154) ++B138->(C138 C113 C172 C131) ++B139->(C139 C190 C149 C108) ++B140->(C140 C167 C126 C185) ++B141->(C141 C144 C103 C162) ++B142->(C142 C121 C180 C139) ++B143->(C143 C198 C157 C116) ++B144->(C144 C175 C134 C193) ++B145->(C145 C152 C111 C170) ++B146->(C146 C129 C188 C147) ++B147->(C147 C106 C165 C124) ++B148->(C148 C183 C142 C101) ++B149->(C149 C160 C119 C178) ++B150->(C150 C137 C196 C155) ++B151->(C151 C114 C173 C132) ++B152->(C152 C191 C150 C109) ++B153->(C153 C168 C127 C186) ++B154->(C154 C145 C104 C163) ++B155->(C155 C122 C181 C140) ++B156->(C156 C199 C158 C117) ++B157->(C157 C176 C135 C194) ++B158->(C158 C153 C112 C171) ++B159->(C159 C130 C189 C148) ++B160->(C160 C107 C166 C125) ++B161->(C161 C184 C143 C102) ++B162->(C162 C161 C120 C179) ++B163->(C163 C138 C197 C156) ++B164->(C164 C115 C174 C133) ++B165->(C165 C192 C151 C110) ++B166->(C166 C169 C128 C187) ++B167->(C167 C146 C105 C164) ++B168->(C168 C123 C182 C141) ++B169->(C169 C200 C159 C118) ++B170->(C170 C177 C136 C195) ++B171->(C171 C154 C113 C172) ++B172->(C172 C131 C190 C149) ++B173->(C173 C108 C167 C126) ++B174->(C174 C185 C144 C103) ++B175->(C175 C162 C121 C180) ++B176->(C176 C139 C198 C157) ++B177->(C177 C116 C175 C134) ++B178->(C178 C193 C152 C111) ++B179->(C179 C170 C129 C188) ++B180->(C180 C147 C106 C165) ++B181->(C181 C124 C183 C142) ++B182->(C182 C101 C160 C119) ++B183->(C183 C178 C137 C196) ++B184->(C184 C155 C114 C173) ++B185->(C185 C132 C191 C150) ++B186->(C186 C109 C168 C127) ++B187->(C187 C186 C145 C104) ++B188->(C188 C163 C122 C181) ++B189->(C189 C140 C199 C158) ++B190->(C190 C117 C176 C135) ++B191->(C191 C194 C153 C112) ++B192->(C192 C171 C130 C189) ++B193->(C193 C148 C107 C166) ++B194->(C194 C125 C184 C143) ++B195->(C195 C102 C161 C120) ++B196->(C196 C179 C138 C197) ++B197->(C197 C156 C115 C174) ++B198->(C198 C133 C192 C151) ++B199->(C199 C110 C169 C128) ++B200->(C200 C187 C146 C105) ++C101->(A165 A124) ++C102->(A183 A142) ++C103->(A101 A160) ++C104->(A119 A178) ++C105->(A137 A196) ++C106->(A155 A114) ++C107->(A173 A132) ++C108->(A191 A150) ++C109->(A109 A168) ++C110->(A127 A186) ++C111->(A145 A104) ++C112->(A163 A122) ++C113->(A181 A140) ++C114->(A199 A158) ++C115->(A117 A176) ++C116->(A135 A194) ++C117->(A153 A112) ++C118->(A171 A130) ++C119->(A189 A148) ++C120->(A107 A166) ++C121->(A125 A184) ++C122->(A143 A102) ++C123->(A161 A120) ++C124->(A179 A138) ++C125->(A197 A156) ++C126->(A115 A174) ++C127->(A133 A192) ++C128->(A151 A110) ++C129->(A169 A128) ++C130->(A187 A146) ++C131->(A105 A164) ++C132->(A123 A182) ++C133->(A141 A200) ++C134->(A159 A118) ++C135->(A177 A136) ++C136->(A195 A154) ++C137->(A113 A172) ++C138->(A131 A190) ++C139->(A149 A108) ++C140->(A167 A126) ++C141->(A185 A144) ++C142->(A103 A162) ++C143->(A121 A180) ++C144->(A139 A198) ++C145->(A157 A116) ++C146->(A175 A134) ++C147->(A193 A152) ++C148->(A111 A170) ++C149->(A129 A188) ++C150->(A147 A106) ++C151->(A165 A124) ++C152->(A183 A142) ++C153->(A101 A160) ++C154->(A119 A178) ++C155->(A137 A196) ++C156->(A155 A114) ++C157->(A173 A132) ++C158->(A191 A150) ++C159->(A109 A168) ++C160->(A127 A186) ++C161->(A145 A104) ++C162->(A163 A122) ++C163->(A181 A140) ++C164->(A199 A158) ++C165->(A117 A176) ++C166->(A135 A194) ++C167->(A153 A112) ++C168->(A171 A130) ++C169->(A189 A148) ++C170->(A107 A166) ++C171->(A125 A184) ++C172->(A143 A102) ++C173->(A161 A120) ++C174->(A179 A138) ++C175->(A197 A156) ++C176->(A115 A174) ++C177->(A133 A192) ++C178->(A151 A110) ++C179->(A169 A128) ++C180->(A187 A146) ++C181->(A105 A164) ++C182->(A123 A182) ++C183->(A141 A200) ++C184->(A159 A118) ++C185->(A177 A136) ++C186->(A195 A154) ++C187->(A113 A172) ++C188->(A131 A190) ++C189->(A149 A108) ++C190->(A167 A126) ++C191->(A185 A144) ++C192->(A103 A162) ++C193->(A121 A180) ++C194->(A139 A198) ++C195->(A157 A116) ++C196->(A175 A134) ++C197->(A193 A152) ++C198->(A111 A170) ++C199->(A129 A188) ++C200->(A147 A106) ++M11X11->(M13X14 M12X13 M12X12 M12X11) ++M11X12->(M13X25 M12X24 M12X23 M12X22) ++M11X13->(M13X21 M12X20 M12X19 M12X18) ++M11X14->(M13X17 M12X16 M12X15 M12X14) ++M11X15->(M13X13 M12X12 M12X11 M12X25) ++M11X16->(M13X24 M12X23 M12X22 M12X21) ++M11X17->(M13X20 M12X19 M12X18 M12X17) ++M11X18->(M13X16 M12X15 M12X14 M12X13) ++M11X19->(M13X12 M12X11 M12X25 M12X24) ++M11X20->(M13X23 M12X22 M12X21 M12X20) ++M11X21->(M13X19 M12X18 M12X17 M12X16) ++M11X22->(M13X15 M12X14 M12X13 M12X12) ++M11X23->(M13X11 M12X25 M12X24 M12X23) ++M11X24->(M13X22 M12X21 M12X20 M12X19) ++M11X25->(M13X18 M12X17 M12X16 M12X15) ++M12X11->(M14X14 M13X13 M13X12 M13X11) ++M12X12->(M14X25 M13X24 M13X23 M13X22) ++M12X13->(M14X21 M13X20 M13X19 M13X18) ++M12X14->(M14X17 M13X16 M13X15 M13X14) ++M12X15->(M14X13 M13X12 M13X11 M13X25) ++M12X16->(M14X24 M13X23 M13X22 M13X21) ++M12X17->(M14X20 M13X19 M13X18 M13X17) ++M12X18->(M14X16 M13X15 M13X14 M13X13) ++M12X19->(M14X12 M13X11 M13X25 M13X24) ++M12X20->(M14X23 M13X22 M13X21 M13X20) ++M12X21->(M14X19 M13X18 M13X17 M13X16) ++M12X22->(M14X15 M13X14 M13X13 M13X12) ++M12X23->(M14X11 M13X25 M13X24 M13X23) ++M12X24->(M14X22 M13X21 M13X20 M13X19) ++M12X25->(M14X18 M13X17 M13X16 M13X15) ++M13X11->(M15X14 M14X13 M14X12 M14X11) ++M13X12->(M15X25 M14X24 M14X23 M14X22) ++M13X13->(M15X21 M14X20 M14X19 M14X18) ++M13X14->(M15X17 M14X16 M14X15 M14X14) ++M13X15->(M15X13 M14X12 M14X11 M14X25) ++M13X16->(M15X24 M14X23 M14X22 M14X21) ++M13X17->(M15X20 M14X19 M14X18 M14X17) ++M13X18->(M15X16 M14X15 M14X14 M14X13) ++M13X19->(M15X12 M14X11 M14X25 M14X24) ++M13X20->(M15X23 M14X22 M14X21 M14X20) ++M13X21->(M15X19 M14X18 M14X17 M14X16) ++M13X22->(M15X15 M14X14 M14X13 M14X12) ++M13X23->(M15X11 M14X25 M14X24 M14X23) ++M13X24->(M15X22 M14X21 M14X20 M14X19) ++M13X25->(M15X18 M14X17 M14X16 M14X15) ++M14X11->(M16X14 M15X13 M15X12 M15X11) ++M14X12->(M16X25 M15X24 M15X23 M15X22) ++M14X13->(M16X21 M15X20 M15X19 M15X18) ++M14X14->(M16X17 M15X16 M15X15 M15X14) ++M14X15->(M16X13 M15X12 M15X11 M15X25) ++M14X16->(M16X24 M15X23 M15X22 M15X21) ++M14X17->(M16X20 M15X19 M15X18 M15X17) ++M14X18->(M16X16 M15X15 M15X14 M15X13) ++M14X19->(M16X12 M15X11 M15X25 M15X24) ++M14X20->(M16X23 M15X22 M15X21 M15X20) ++M14X21->(M16X19 M15X18 M15X17 M15X16) ++M14X22->(M16X15 M15X14 M15X13 M15X12) ++M14X23->(M16X11 M15X25 M15X24 M15X23) ++M14X24->(M16X22 M15X21 M15X20 M15X19) ++M14X25->(M16X18 M15X17 M15X16 M15X15) ++M15X11->(M17X14 M16X13 M16X12 M16X11) ++M15X12->(M17X25 M16X24 M16X23 M16X22) ++M15X13->(M17X21 M16X20 M16X19 M16X18) ++M15X14->(M17X17 M16X16 M16X15 M16X14) ++M15X15->(M17X13 M16X12 M16X11 M16X25) ++M15X16->(M17X24 M16X23 M16X22 M16X21) ++M15X17->(M17X20 M16X19 M16X18 M16X17) ++M15X18->(M17X16 M16X15 M16X14 M16X13) ++M15X19->(M17X12 M16X11 M16X25 M16X24) ++M15X20->(M17X23 M16X22 M16X21 M16X20) ++M15X21->(M17X19 M16X18 M16X17 M16X16) ++M15X22->(M17X15 M16X14 M16X13 M16X12) ++M15X23->(M17X11 M16X25 M16X24 M16X23) ++M15X24->(M17X22 M16X21 M16X20 M16X19) ++M15X25->(M17X18 M16X17 M16X16 M16X15) ++M16X11->(M18X14 M17X13 M17X12 M17X11) ++M16X12->(M18X25 M17X24 M17X23 M17X22) ++M16X13->(M18X21 M17X20 M17X19 M17X18) ++M16X14->(M18X17 M17X16 M17X15 M17X14) ++M16X15->(M18X13 M17X12 M17X11 M17X25) ++M16X16->(M18X24 M17X23 M17X22 M17X21) ++M16X17->(M18X20 M17X19 M17X18 M17X17) ++M16X18->(M18X16 M17X15 M17X14 M17X13) ++M16X19->(M18X12 M17X11 M17X25 M17X24) ++M16X20->(M18X23 M17X22 M17X21 M17X20) ++M16X21->(M18X19 M17X18 M17X17 M17X16) ++M16X22->(M18X15 M17X14 M17X13 M17X12) ++M16X23->(M18X11 M17X25 M17X24 M17X23) ++M16X24->(M18X22 M17X21 M17X20 M17X19) ++M16X25->(M18X18 M17X17 M17X16 M17X15) ++M17X11->(M19X14 M18X13 M18X12 M18X11) ++M17X12->(M19X25 M18X24 M18X23 M18X22) ++M17X13->(M19X21 M18X20 M18X19 M18X18) ++M17X14->(M19X17 M18X16 M18X15 M18X14) ++M17X15->(M19X13 M18X12 M18X11 M18X25) ++M17X16->(M19X24 M18X23 M18X22 M18X21) ++M17X17->(M19X20 M18X19 M18X18 M18X17) ++M17X18->(M19X16 M18X15 M18X14 M18X13) ++M17X19->(M19X12 M18X11 M18X25 M18X24) ++M17X20->(M19X23 M18X22 M18X21 M18X20) ++M17X21->(M19X19 M18X18 M18X17 M18X16) ++M17X22->(M19X15 M18X14 M18X13 M18X12) ++M17X23->(M19X11 M18X25 M18X24 M18X23) ++M17X24->(M19X22 M18X21 M18X20 M18X19) ++M17X25->(M19X18 M18X17 M18X16 M18X15) ++M18X11->(M20X14 M19X13 M19X12 M19X11) ++M18X12->(M20X25 M19X24 M19X23 M19X22) ++M18X13->(M20X21 M19X20 M19X19 M19X18) ++M18X14->(M20X17 M19X16 M19X15 M19X14) ++M18X15->(M20X13 M19X12 M19X11 M19X25) ++M18X16->(M20X24 M19X23 M19X22 M19X21) ++M18X17->(M20X20 M19X19 M19X18 M19X17) ++M18X18->(M20X16 M19X15 M19X14 M19X13) ++M18X19->(M20X12 M19X11 M19X25 M19X24) ++M18X20->(M20X23 M19X22 M19X21 M19X20) ++M18X21->(M20X19 M19X18 M19X17 M19X16) ++M18X22->(M20X15 M19X14 M19X13 M19X12) ++M18X23->(M20X11 M19X25 M19X24 M19X23) ++M18X24->(M20X22 M19X21 M19X20 M19X19) ++M18X25->(M20X18 M19X17 M19X16 M19X15) ++M19X11->(M21X14 M20X13 M20X12 M20X11) ++M19X12->(M21X25 M20X24 M20X23 M20X22) ++M19X13->(M21X21 M20X20 M20X19 M20X18) ++M19X14->(M21X17 M20X16 M20X15 M20X14) ++M19X15->(M21X13 M20X12 M20X11 M20X25) ++M19X16->(M21X24 M20X23 M20X22 M20X21) ++M19X17->(M21X20 M20X19 M20X18 M20X17) ++M19X18->(M21X16 M20X15 M20X14 M20X13) ++M19X19->(M21X12 M20X11 M20X25 M20X24) ++M19X20->(M21X23 M20X22 M20X21 M20X20) ++M19X21->(M21X19 M20X18 M20X17 M20X16) ++M19X22->(M21X15 M20X14 M20X13 M20X12) ++M19X23->(M21X11 M20X25 M20X24 M20X23) ++M19X24->(M21X22 M20X21 M20X20 M20X19) ++M19X25->(M21X18 M20X17 M20X16 M20X15) ++M20X11->(M22X14 M21X13 M21X12 M21X11) ++M20X12->(M22X25 M21X24 M21X23 M21X22) ++M20X13->(M22X21 M21X20 M21X19 M21X18) ++M20X14->(M22X17 M21X16 M21X15 M21X14) ++M20X15->(M22X13 M21X12 M21X11 M21X25) ++M20X16->(M22X24 M21X23 M21X22 M21X21) ++M20X17->(M22X20 M21X19 M21X18 M21X17) ++M20X18->(M22X16 M21X15 M21X14 M21X13) ++M20X19->(M22X12 M21X11 M21X25 M21X24) ++M20X20->(M22X23 M21X22 M21X21 M21X20) ++M20X21->(M22X19 M21X18 M21X17 M21X16) ++M20X22->(M22X15 M21X14 M21X13 M21X12) ++M20X23->(M22X11 M21X25 M21X24 M21X23) ++M20X24->(M22X22 M21X21 M21X20 M21X19) ++M20X25->(M22X18 M21X17 M21X16 M21X15) ++M21X11->(M23X15 M22X14 M22X13 M22X12) ++M21X12->(M11X11 M23X25 M22X24 M22X23 M22X22) ++M21X13->(M23X21 M22X20 M22X19 M22X18) ++M21X14->(M23X17 M22X16 M22X15 M22X14) ++M21X15->(M23X13 M22X12 M22X11 M22X25) ++M21X16->(M23X24 M22X23 M22X22 M22X21) ++M21X17->(M23X20 M22X19 M22X18 M22X17) ++M21X18->(M23X16 M22X15 M22X14 M22X13) ++M21X19->(M23X12 M22X11 M22X25 M22X24) ++M21X20->(M23X23 M22X22 M22X21 M22X20) ++M21X21->(M23X19 M22X18 M22X17 M22X16) ++M21X22->(M23X15 M22X14 M22X13 M22X12) ++M21X23->(M23X11 M22X25 M22X24 M22X23) ++M21X24->(M23X22 M22X21 M22X20 M22X19) ++M21X25->(M23X18 M22X17 M22X16 M22X15) ++M22X11->(M24X16 M23X15 M23X14 M23X13) ++M22X12->(M12X12 M24X11 M23X25 M23X24 M23X23) ++M22X13->(M24X22 M23X21 M23X20 M23X19) ++M22X14->(M24X18 M23X17 M23X16 M23X15) ++M22X15->(M24X14 M23X13 M23X12 M23X11) ++M22X16->(M24X25 M23X24 M23X23 M23X22) ++M22X17->(M24X21 M23X20 M23X19 M23X18) ++M22X18->(M24X17 M23X16 M23X15 M23X14) ++M22X19->(M24X13 M23X12 M23X11 M23X25) ++M22X20->(M24X24 M23X23 M23X22 M23X21) ++M22X21->(M24X20 M23X19 M23X18 M23X17) ++M22X22->(M24X16 M23X15 M23X14 M23X13) ++M22X23->(M24X12 M23X11 M23X25 M23X24) ++M22X24->(M24X23 M23X22 M23X21 M23X20) ++M22X25->(M24X19 M23X18 M23X17 M23X16) ++M23X11->(M25X17 M24X16 M24X15 M24X14) ++M23X12->(M13X13 M25X12 M24X11 M24X25 M24X24) ++M23X13->(M25X23 M24X22 M24X21 M24X20) ++M23X14->(M25X19 M24X18 M24X17 M24X16) ++M23X15->(M25X15 M24X14 M24X13 M24X12) ++M23X16->(M25X11 M24X25 M24X24 M24X23) ++M23X17->(M25X22 M24X21 M24X20 M24X19) ++M23X18->(M25X18 M24X17 M24X16 M24X15) ++M23X19->(M25X14 M24X13 M24X12 M24X11) ++M23X20->(M25X25 M24X24 M24X23 M24X22) ++M23X21->(M25X21 M24X20 M24X19 M24X18) ++M23X22->(M25X17 M24X16 M24X15 M24X14) ++M23X23->(M25X13 M24X12 M24X11 M24X25) ++M23X24->(M25X24 M24X23 M24X22 M24X21) ++M23X25->(M25X20 M24X19 M24X18 M24X17) ++M24X11->(M26X18 M25X17 M25X16 M25X15) ++M24X12->(M14X14 M26X13 M25X12 M25X11 M25X25) ++M24X13->(M26X24 M25X23 M25X22 M25X21) ++M24X14->(M26X20 M25X19 M25X18 M25X17) ++M24X15->(M26X16 M25X15 M25X14 M25X13) ++M24X16->(M26X12 M25X11 M25X25 M25X24) ++M24X17->(M26X23 M25X22 M25X21 M25X20) ++M24X18->(M26X19 M25X18 M25X17 M25X16) ++M24X19->(M26X15 M25X14 M25X13 M25X12) ++M24X20->(M26X11 M25X25 M25X24 M25X23) ++M24X21->(M26X22 M25X21 M25X20 M25X19) ++M24X22->(M26X18 M25X17 M25X16 M25X15) ++M24X23->(M26X14 M25X13 M25X12 M25X11) ++M24X24->(M26X25 M25X24 M25X23 M25X22) ++M24X25->(M26X21 M25X20 M25X19 M25X18) ++M25X11->(M27X19 M26X18 M26X17 M26X16) ++M25X12->(M15X15 M27X14 M26X13 M26X12 M26X11) ++M25X13->(M27X25 M26X24 M26X23 M26X22) ++M25X14->(M27X21 M26X20 M26X19 M26X18) ++M25X15->(M27X17 M26X16 M26X15 M26X14) ++M25X16->(M27X13 M26X12 M26X11 M26X25) ++M25X17->(M27X24 M26X23 M26X22 M26X21) ++M25X18->(M27X20 M26X19 M26X18 M26X17) ++M25X19->(M27X16 M26X15 M26X14 M26X13) ++M25X20->(M27X12 M26X11 M26X25 M26X24) ++M25X21->(M27X23 M26X22 M26X21 M26X20) ++M25X22->(M27X19 M26X18 M26X17 M26X16) ++M25X23->(M27X15 M26X14 M26X13 M26X12) ++M25X24->(M27X11 M26X25 M26X24 M26X23) ++M25X25->(M27X22 M26X21 M26X20 M26X19) ++M26X11->(M28X20 M27X19 M27X18 M27X17) ++M26X12->(M16X16 M28X15 M27X14 M27X13 M27X12) ++M26X13->(M28X11 M27X25 M27X24 M27X23) ++M26X14->(M28X22 M27X21 M27X20 M27X19) ++M26X15->(M28X18 M27X17 M27X16 M27X15) ++M26X16->(M28X14 M27X13 M27X12 M27X11) ++M26X17->(M28X25 M27X24 M27X23 M27X22) ++M26X18->(M28X21 M27X20 M27X19 M27X18) ++M26X19->(M28X17 M27X16 M27X15 M27X14) ++M26X20->(M28X13 M27X12 M27X11 M27X25) ++M26X21->(M28X24 M27X23 M27X22 M27X21) ++M26X22->(M28X20 M27X19 M27X18 M27X17) ++M26X23->(M28X16 M27X15 M27X14 M27X13) ++M26X24->(M28X12 M27X11 M27X25 M27X24) ++M26X25->(M28X23 M27X22 M27X21 M27X20) ++M27X11->(M29X21 M28X20 M28X19 M28X18) ++M27X12->(M17X17 M29X16 M28X15 M28X14 M28X13) ++M27X13->(M29X12 M28X11 M28X25 M28X24) ++M27X14->(M29X23 M28X22 M28X21 M28X20) ++M27X15->(M29X19 M28X18 M28X17 M28X16) ++M27X16->(M29X15 M28X14 M28X13 M28X12) ++M27X17->(M29X11 M28X25 M28X24 M28X23) ++M27X18->(M29X22 M28X21 M28X20 M28X19) ++M27X19->(M29X18 M28X17 M28X16 M28X15) ++M27X20->(M29X14 M28X13 M28X12 M28X11) ++M27X21->(M29X25 M28X24 M28X23 M28X22) ++M27X22->(M29X21 M28X20 M28X19 M28X18) ++M27X23->(M29X17 M28X16 M28X15 M28X14) ++M27X24->(M29X13 M28X12 M28X11 M28X25) ++M27X25->(M29X24 M28X23 M28X22 M28X21) ++M28X11->(M30X22 M29X21 M29X20 M29X19) ++M28X12->(M18X18 M30X17 M29X16 M29X15 M29X14) ++M28X13->(M30X13 M29X12 M29X11 M29X25) ++M28X14->(M30X24 M29X23 M29X22 M29X21) ++M28X15->(M30X20 M29X19 M29X18 M29X17) ++M28X16->(M30X16 M29X15 M29X14 M29X13) ++M28X17->(M30X12 M29X11 M29X25 M29X24) ++M28X18->(M30X23 M29X22 M29X21 M29X20) ++M28X19->(M30X19 M29X18 M29X17 M29X16) ++M28X20->(M30X15 M29X14 M29X13 M29X12) ++M28X21->(M30X11 M29X25 M29X24 M29X23) ++M28X22->(M30X22 M29X21 M29X20 M29X19) ++M28X23->(M30X18 M29X17 M29X16 M29X15) ++M28X24->(M30X14 M29X13 M29X12 M29X11) ++M28X25->(M30X25 M29X24 M29X23 M29X22) ++M29X11->(M30X22 M30X21 M30X20) ++M29X12->(M30X17 M30X16 M30X15) ++M29X13->(M30X13 M30X12 M30X11) ++M29X14->(M30X24 M30X23 M30X22) ++M29X15->(M30X20 M30X19 M30X18) ++M29X16->(M30X16 M30X15 M30X14) ++M29X17->(M30X12 M30X11 M30X25) ++M29X18->(M30X23 M30X22 M30X21) ++M29X19->(M30X19 M30X18 M30X17) ++M29X20->(M30X15 M30X14 M30X13) ++M29X21->(M30X11 M30X25 M30X24) ++M29X22->(M30X22 M30X21 M30X20) ++M29X23->(M30X18 M30X17 M30X16) ++M29X24->(M30X14 M30X13 M30X12) ++M29X25->(M30X25 M30X24 M30X23) ++M30X11 ++M30X12 ++M30X13 ++M30X14 ++M30X15 ++M30X16 ++M30X17 ++M30X18 ++M30X19 ++M30X20 ++M30X21 ++M30X22 ++M30X23 ++M30X24 ++M30X25 ++xfail_output(glibc.rtld.dynamic_sort=1): M30X19>M30X15>M30X16>M30X11>M30X12>M30X17>M30X13>M30X14>M29X20>M30X23>M30X24>M30X20>M30X18>M29X15>M29X12>M30X22>M30X21>M29X22>M30X25>M29X19>M29X23>M29X16>M29X24>M29X13>M29X17>M29X18>M28X19>M29X21>M29X25>M29X14>M28X20>M28X15>M28X16>M28X21>M27X18>M29X11>M28X17>M28X11>M28X22>M27X14>M28X18>M27X15>M28X13>M27X11>M28X23>M27X25>M28X14>M28X25>M27X23>M27X22>M28X24>M27X21>M27X13>M27X19>M27X17>M26X11>M26X23>M26X21>M26X22>M26X20>M26X16>M25X21>M17X22>M15X15>M20X14>M20X16>M18X18>M28X12>M27X24>M25X17>M27X20>M26X18>M26X17>M27X16>M26X19>M25X18>M26X24>M25X20>M24X17>M23X18>M25X13>M26X13>M17X23>M16X16>M26X12>M25X12>M26X15>M24X19>M25X23>M25X24>M25X25>M24X20>M25X19>M24X21>M23X17>M22X21>M24X14>M23X22>M24X24>M22X20>M24X13>M25X11>M24X12>M25X15>M23X15>M25X16>M24X22>M23X13>M24X18>M23X14>M22X22>M21X20>M24X25>M23X16>M22X25>M21X19>M22X14>M23X11>M22X15>M21X18>M22X19>M21X17>M20X17>M19X17>M21X24>M21X12>M20X22>M19X16>M18X25>M19X21>M19X20>M18X24>M20X12>M19X11>M23X20>M22X24>M22X16>M21X21>M25X14>M23X19>M23X24>M20X24>M19X12>M18X15>M17X14>M16X18>M14X25>M16X22>M16X20>M17X17>M22X12>M21X11>M20X15>M18X22>M19X24>M19X18>M18X21>M17X16>M17X18>M16X21>M15X20>M19X22>M18X20>M18X11>M17X19>M16X17>M15X21>M16X14>M16X13>M15X22>M14X20>M17X25>M16X19>M14X21>M13X24>M12X12>M16X24>M15X23>M14X16>M16X15>M15X25>M15X11>M15X12>M14X15>M13X14>M14X22>M13X20>M12X13>M11X11>M22X23>M21X15>M21X16>M20X21>M20X20>M18X17>M19X25>M18X23>M21X13>M15X17>M15X18>M18X19>M17X24>M16X12>M17X13>M20X25>M19X23>M15X19>M14X13>M13X18>M15X13>M17X12>M16X11>M18X13>M18X12>M14X11>M14X24>M13X19>M15X14>M17X20>M20X11>M20X13>M21X14>M15X24>M14X12>M13X22>M14X23>M13X23>M14X19>M17X15>M16X25>M17X11>M18X14>M19X19>M21X25>M13X12>M13X11>M14X18>M13X13>M12X11>M15X16>M14X14>M27X12>M17X21>M20X23>M22X13>M21X22>M24X16>M24X15>M26X25>M23X25>M26X14>M23X12>M22X18>M24X11>M16X23>M19X14>M19X13>M21X23>M22X17>M23X23>M23X21>M25X22>M18X16>M19X15>M20X18>M20X19>M22X11>M24X23>C156>C118>C143>C137>C147>C106>C168>C113>C163>C155>C105>C146>C187>A150>C139>C180>C164>C193>C157>A191>C158>B188>A159>C184>C121>C154>B171>A105>C131>C104>B104>C161>C111>B145>C160>B155>A163>C112>C142>B148>C133>B198>A198>A115>C114>B157>A156>C175>B144>A120>C173>B184>A174>C126>B107>A139>C194>B194>A194>C116>B116>C166>B160>B110>A110>C128>B128>A128>C179>B162>A154>C186>B187>A179>C124>B181>A101>C153>B158>A136>C135>C176>A192>B133>A133>C177>B177>A177>C185>C103>B141>A141>C183>A162>C192>C129>B179>C144>B124>B183>C127>B127>A127>B108>A112>B153>A153>C167>B167>A186>A122>C162>A144>B149>C174>B131>A185>C141>B106>A126>A167>C140>B122>A170>C198>B143>C117>C123>B123>A147>A106>C200>B169>C191>B175>A123>B118>A182>C132>B151>A145>A104>A109>C159>C150>B119>A119>A178>B164>B114>A164>C181>A102>C122>B134>A157>A116>C195>B191>B111>C172>B172>A118>B129>A129>C149>A107>C170>B197>A197>A173>B168>A132>C107>B165>A160>A131>C188>A168>B109>C178>A189>A148>C119>C190>C120>B166>B176>C108>B135>B139>A103>B178>A169>B132>C125>C138>B163>A111>B170>C110>A165>C151>C169>C199>A138>C182>A135>B101>B142>C101>C148>B193>B152>A158>A199>C136>B137>A161>B120>A108>A149>A125>B113>A184>C171>A134>A175>A124>B150>B161>B102>A146>A187>C130>B192>B200>A200>A142>A183>C102>B105>B156>A176>C165>B147>A137>A196>B190>A190>B125>C134>C189>B126>B186>A166>B136>B195>A195>B154>B138>B112>B173>A117>B159>B182>A181>A140>C145>B117>A152>A193>C197>B130>A172>A113>A151>B115>A143>B140>B185>B103>A121>A180>A130>A171>B199>C196>B146>B180>C115>B174>B121>A188>B196>B189>C152>C109>A155>A114>M14X17>M13X15>M13X16>M13X17>M12X17>M12X21>M12X25>M12X14>M13X25>M12X15>M13X21>M12X16>M12X18>M12X19>M12X20>M12X22>M12X23>M12X24>M11X25>M11X24>M11X23>M11X22>M11X21>M11X20>M11X19>M11X18>M11X17>M11X16>M11X15>M11X14>M11X13>M11X12>{}M30X15>M30X16>M30X11>M30X12>M30X17>M30X13>M30X14>M29X20>M30X23>M30X24>M30X20>M30X18>M29X15>M29X12>M30X22>M30X21>M29X22>M30X25>M29X19>M29X23>M29X16>M29X24>M29X13>M29X17>M29X18>M28X19>M29X21>M29X25>M29X14>M28X20>M28X15>M28X16>M28X21>M27X18>M29X11>M28X17>M28X11>M28X22>M28X24>M28X23>M27X21>M28X13>M27X20>M27X19>M26X14>M27X25>M28X18>M27X11>M28X25>M27X24>M26X24>M27X15>M27X14>M27X13>M26X23>M27X17>M26X22>M25X13>M28X14>M27X16>M26X19>M26X18>M27X23>M27X22>M26X17>M25X18>M26X21>M25X17>M26X20>M26X15>M26X13>M25X19>M24X14>M25X23>M26X11>M26X25>M25X16>M25X15>M24X22>M25X21>M25X20>M24X21>M25X25>M25X24>M24X20>M23X13>M22X15>M25X14>M24X19>M23X17>M24X25>M23X24>M24X13>M23X15>M24X18>M23X14>M22X11>M24X15>M23X22>M24X11>M23X19>M22X21>M24X24>M23X21>M22X20>M23X25>M22X19>M21X24>M20X23>M22X22>M25X11>M23X16>M22X18>M23X20>M22X17>M21X21>M21X20>M20X24>M22X14>M22X13>M21X11>M21X17>M22X23>M21X16>M20X25>M19X23>M18X16>M21X22>M20X20>M20X19>M21X13>M20X18>M19X13>M21X18>M20X21>M19X24>M18X12>M20X14>M20X13>M22X25>M20X12>M20X15>M19X14>M18X22>M19X18>M20X17>M19X17>M19X16>M18X21>M17X20>M19X19>M18X13>M17X11>M18X17>M19X25>M18X15>M17X25>M18X19>M17X24>M16X19>M15X17>M17X21>M16X24>M18X23>M17X16>M16X25>M19X15>M18X25>M17X23>M16X23>M15X23>M18X14>M17X14>M16X14>M17X18>M16X13>M17X22>M16X12>M15X22>M14X16>M17X12>M16X22>M15X12>M16X11>M15X11>M16X15>M15X25>M14X15>M13X14>M15X18>M16X21>M15X16>M14X21>M15X14>M16X20>M15X13>M14X22>M15X20>M14X20>M13X20>M14X11>M15X19>M14X24>M13X19>M14X13>M13X18>M12X13>M15X24>M14X23>M13X12>M14X12>M13X11>M12X11>M11X11>M21X12>M20X11>M19X11>M18X11>M17X15>M16X18>M14X25>M14X19>M13X24>M13X23>M13X22>M12X12>M22X12>M21X15>M19X22>M18X20>M16X17>M14X14>M24X12>M23X23>M22X16>M21X14>M20X22>M18X24>M16X16>M26X12>M24X16>M23X11>M21X23>M19X20>M17X17>M27X12>M26X16>M25X22>M24X17>M23X18>M21X25>M19X12>M17X19>M15X21>M14X18>M13X13>M23X12>M21X19>M19X21>M17X13>M15X15>M25X12>M24X23>M22X24>M20X16>M18X18>M28X12>A150>C158>B112>A112>C167>B146>A146>C180>B180>A180>C143>B143>A115>C126>B126>A126>C190>B190>A190>C138>B138>A138>C174>B174>A102>C122>B122>A122>C162>B162>A162>C142>B142>A142>C102>B102>A174>C176>B176>A176>C115>B115>A143>C172>B172>A172>C187>B187>A187>C130>B130>A130>C118>B118>A118>C184>B184>A184>C171>B171>A171>C168>B182>A182>C182>B168>A168>C109>B109>A109>C159>B159>A159>C134>B134>A134>C146>B167>A167>C140>B140>A140>C163>B163>A163>C112>B158>A158>C164>B164>A164>C131>B131>A131>C188>B188>A188>C199>B199>A199>C114>B114>A114>C106>B106>A106>C200>B200>A200>C183>B183>A183>C152>B152>A152>C147>B147>A147>C150>B150>A198>C144>B144>A144>C191>B191>A191>C108>B108>A108>C139>B139>A139>C194>B194>A194>C166>B166>A166>C120>B120>A120>C123>B123>A123>C132>B132>A132>C107>B107>A107>C170>B170>A170>C198>B198>A156>C125>B125>A125>C121>B121>A121>C193>B193>A193>C197>B197>A197>C175>B175>A175>C196>B196>A196>C105>B105>A105>C181>B181>A181>C113>B113>A113>C137>B137>A137>C155>B155>A155>C156>B156>A110>C128>B128>A128>C179>B179>A179>C124>B124>A124>C151>B151>A151>C178>B178>A178>C104>B104>A104>C111>B111>A111>C148>B148>A148>C169>B169>A169>C129>B129>A129>C149>B149>A149>C189>B189>A189>C119>B119>A119>C154>B154>A154>C136>B136>A136>C135>B135>A135>C116>B116>A116>C145>B145>A145>C161>B161>A161>C173>B173>A173>C157>B157>A157>C195>B195>A195>C186>B186>A186>C160>B160>A160>C153>B153>A153>C117>B117>A117>C165>B165>A165>C101>B101>A101>C103>B103>A103>C192>B192>A192>C177>B177>A177>C185>B185>A185>C141>B141>A141>C133>B133>A133>C127>B127>A127>C110>B110>M14X17>M13X15>M13X16>M13X17>M12X17>M12X21>M12X25>M12X14>M13X25>M12X15>M13X21>M12X16>M12X18>M12X19>M12X20>M12X22>M12X23>M12X24>M11X25>M11X24>M11X23>M11X22>M11X21>M11X20>M11X19>M11X18>M11X17>M11X16>M11X15>M11X14>M11X13>M11X12>{}. ++ ++"""Generate testcase files and Makefile fragments for DSO sorting test ++ ++This script takes a small description string language, and generates ++testcases for displaying the ELF dynamic linker's dependency sorting ++behavior, allowing verification. ++ ++Testcase descriptions are semicolon-separated description strings, and ++this tool generates a testcase from the description, including main program, ++associated modules, and Makefile fragments for including into elf/Makefile. ++ ++This allows automation of what otherwise would be very laborous manual ++construction of complex dependency cases, however it must be noted that this ++is only a tool to speed up testcase construction, and thus the generation ++features are largely mechanical in nature; inconsistencies or errors may occur ++if the input description was itself erroneous or have unforeseen interactions. ++ ++The format of the input test description files are: ++ ++ # Each test description has a name, lines of description, ++ # and an expected output specification. Comments use '#'. ++ testname1: ++ output: ++ ++ # Tests can be marked to be XFAIL by using 'xfail_output' instead ++ testname2: ++ xfail_output: ++ ++ # A default set of GLIBC_TUNABLES tunables can be specified, for which ++ # all following tests will run multiple times, once for each of the ++ # GLIBC_TUNABLES=... strings set by the 'tunable_option' command. ++ tunable_option: ++ tunable_option: ++ ++ # Test descriptions can use multiple lines, which will all be merged ++ # together, so order is not important. ++ testname3: ++ ++ ++ ... ++ output: ++ ++ # 'testname3' will be run and compared two times, for both ++ # GLIBC_TUNABLES= and ++ # GLIBC_TUNABLES=. This can be cleared and reset by the ++ # 'clear_tunables' command: ++ clear_tunables ++ ++ # Multiple expected outputs can also be specified, with an associated ++ # tunable option in (), which multiple tests will be run with each ++ # GLIBC_TUNABLES=... option tried. ++ testname4: ++ ++ ... ++ output(): ++ output(): ++ # Individual tunable output cases can be XFAILed, though note that ++ # this will have the effect of XFAILing the entire 'testname4' test ++ # in the final top-level tests.sum summary. ++ xfail_output(): ++ ++ # When multiple outputs (with specific tunable strings) are specified, ++ # these take priority over any active 'tunable_option' settings. ++ ++ # When a test is meant to be placed under 'xtests' (not run under ++ # "make check", but only when "make xtests" is used), the testcase name can be ++ # declared using 'xtest()': ++ ... ++ xtest(test-too-big1): ++ output: ++ ... ++ ++ # Do note that under current elf/Makefile organization, for such a xtest case, ++ # while the test execution is only run under 'make xtests', the associated ++ # DSOs are always built even under 'make check'. ++ ++On the description language used, an example description line string: ++ ++ a->b!->[cdef];c=>g=>h;{+c;%c;-c}->a ++ ++Each identifier represents a shared object module, currently sequences of ++letters/digits are allowed, case-sensitive. ++ ++All such shared objects have a constructor/destructor generated for them ++that emits its name followed by a '>' for constructors, and '<' followed by ++its name for destructors, e.g. if the name is 'obj1', then "obj1>" and " operator specifies a link time dependency, these can be chained for ++convenience (e.g. a->b->c->d). ++ ++The => operator creates a call-reference, e.g. for a=>b, an fn_a() function ++is created inside module 'a', which calls fn_b() in module 'b'. ++These module functions emit 'name()' output in nested form, ++e.g. a=>b emits 'a(b())' ++ ++For single character object names, square brackets [] in the description ++allows specifying multiple objects; e.g. a->[bcd]->e is equivalent to ++ a->b->e;a->c->e;a->d->e ++ ++The () parenthesis construct with space separated names is also allowed for ++specifying objects. For names with integer suffixes a range can also be used, ++e.g. (foo1 bar2-5), specifies DSOs foo1, bar2, bar2, bar3, bar4, bar5. ++ ++A {} construct specifies the main test program, and its link dependencies ++are also specified using ->. Inside {}, a few ;-separated constructs are ++allowed: ++ +a Loads module a using dlopen(RTLD_LAZY|RTLD_GLOBAL) ++ ^a Loads module a using dlopen(RTLD_LAZY) ++ %a Use dlsym() to load and call fn_a() ++ @a Calls fn_a() directly. ++ -a Unloads module a using dlclose() ++ ++The generated main program outputs '{' '}' with all output from above ++constructs in between. The other output before/after {} are the ordered ++constructor/destructor output. ++ ++If no {} construct is present, a default empty main program is linked ++against all objects which have no dependency linked to it. e.g. for ++'[ab]->c;d->e', the default main program is equivalent to '{}->[abd]' ++ ++Sometimes for very complex or large testcases, besides specifying a ++few explicit dependencies from main{}, the above default dependency ++behavior is still useful to automatically have, but is turned off ++upon specifying a single explicit {}->dso_name. ++In this case, add {}->* to explicitly add this generation behavior: ++ ++ # Main program links to 'foo', and all other objects which have no ++ # dependency linked to it. ++ {}->foo,{}->* ++ ++Note that '*' works not only on main{}, but can be used as the ++dependency target of any object. Note that it only works as a target, ++not a dependency source. ++ ++The '!' operator after object names turns on permutation of its ++dependencies, e.g. while a->[bcd] only generates one set of objects, ++with 'a.so' built with a link line of "b.so c.so d.so", for a!->[bcd] ++permutations of a's dependencies creates multiple testcases with ++different link line orders: "b.so c.so d.so", "c.so b.so d.so", ++"b.so d.so c.so", etc. Note that for a specified on ++the script command-line, multiple , , etc. ++tests will be generated (e.g. for a!->[bc]!->[de], eight tests with ++different link orders for a, b, and c will be generated) ++ ++It is possible to specify the ELF soname field for an object or the ++main program: ++ # DSO 'a' will be linked with the appropriate -Wl,-soname=x setting ++ a->b->c;soname(a)=x ++ # The the main program can also have a soname specified ++ soname({})=y ++ ++This can be used to test how ld.so behaves when objects and/or the ++main program have such a field set. ++ ++ ++Strings Output by Generated Testcase Programs ++ ++The text output produced by a generated testcase consists of three main ++parts: ++ 1. The constructors' output ++ 2. Output from the main program ++ 3. Destructors' output ++ ++To see by example, a simple test description "a->b->c" generates a testcase ++that when run, outputs: "c>b>a>{}' character, ++and the "c>b>a" part above is the full constructor output by all DSOs, the ++order indicating that DSO 'c', which does not depend on any other DSO, has ++its constructor run first, followed by 'b' and then 'a'. ++ ++Destructor output for each DSO is a '<' character followed by its name, ++reflecting its reverse nature of constructors. In the above example, the ++destructor output part is "g=>h;{+c;%c;-c}->a->h ++ ++This produces a testcase, that when executed outputs: ++ h>a>{+c[g>c>];%c();-c[h dependency as expected. ++Inside the main program, the "+c" action triggers a dlopen() of DSO 'c', ++causing another chain of constructors "g>c>" to be triggered. Here it is ++displayed inside [] brackets for each dlopen call. The same is done for "-c", ++a dlclose() of 'c'. ++ ++The "%c" output is due to calling to fn_c() inside DSO 'c', this comprises ++of two parts: the '%' character is printed by the caller, here it is the main ++program. The 'c' character is printed from inside fn_c(). The '%' character ++indicates that this is called by a dlsym() of "fn_c". A '@' character would ++mean a direct call (with a symbol reference). These can all be controlled ++by the main test program constructs documented earlier. ++ ++The output strings described here is the exact same form placed in ++test description files' "output: " line. ++""" ++ ++import sys ++import re ++import os ++import subprocess ++import argparse ++from collections import OrderedDict ++import itertools ++ ++# BUILD_GCC is only used under the --build option, ++# which builds the generated testcase, including DSOs using BUILD_GCC. ++# Mainly for testing purposes, especially debugging of this script, ++# and can be changed here to another toolchain path if needed. ++build_gcc = "gcc" ++ ++def get_parser(): ++ parser = argparse.ArgumentParser("") ++ parser.add_argument("description", ++ help="Description string of DSO dependency test to be " ++ "generated (see script source for documentation of " ++ "description language), either specified here as " ++ "command line argument, or by input file using " ++ "-f/--description-file option", ++ nargs="?", default="") ++ parser.add_argument("test_name", ++ help="Identifier for testcase being generated", ++ nargs="?", default="") ++ parser.add_argument("--objpfx", ++ help="Path to place generated files, defaults to " ++ "current directory if none specified", ++ nargs="?", default="./") ++ parser.add_argument("-m", "--output-makefile", ++ help="File to write Makefile fragment to, defaults to " ++ "stdout when option not present", ++ nargs="?", default="") ++ parser.add_argument("-f", "--description-file", ++ help="Input file containing testcase descriptions", ++ nargs="?", default="") ++ parser.add_argument("--build", help="After C testcase generated, build it " ++ "using gcc (for manual testing purposes)", ++ action="store_true") ++ parser.add_argument("--debug-output", ++ help="Prints some internal data " ++ "structures; used for debugging of this script", ++ action="store_true") ++ return parser ++ ++# Main script starts here. ++cmdlineargs = get_parser().parse_args() ++test_name = cmdlineargs.test_name ++description = cmdlineargs.description ++objpfx = cmdlineargs.objpfx ++description_file = cmdlineargs.description_file ++output_makefile = cmdlineargs.output_makefile ++makefile = "" ++default_tunable_options = [] ++ ++current_input_lineno = 0 ++def error(msg): ++ global current_input_lineno ++ print("Error: %s%s" % ((("Line %d, " % current_input_lineno) ++ if current_input_lineno != 0 else ""), ++ msg)) ++ exit(1) ++ ++if(test_name or description) and description_file: ++ error("both command-line testcase and input file specified") ++if test_name and not description: ++ error("command-line testcase name without description string") ++ ++# Main class type describing a testcase. ++class TestDescr: ++ def __init__(self): ++ self.objs = [] # list of all DSO objects ++ self.deps = OrderedDict() # map of DSO object -> list of dependencies ++ ++ # map of DSO object -> list of call refs ++ self.callrefs = OrderedDict() ++ ++ # map of DSO object -> list of permutations of dependencies ++ self.dep_permutations = OrderedDict() ++ ++ # map of DSO object -> SONAME of object (if one is specified) ++ self.soname_map = OrderedDict() ++ ++ # list of main program operations ++ self.main_program = [] ++ # set if default dependencies added to main ++ self.main_program_default_deps = True ++ ++ self.test_name = "" # name of testcase ++ self.expected_outputs = OrderedDict() # expected outputs of testcase ++ self.xfail = False # set if this is a XFAIL testcase ++ self.xtest = False # set if this is put under 'xtests' ++ ++ # Add 'object -> [object, object, ...]' relations to CURR_MAP ++ def __add_deps_internal(self, src_objs, dst_objs, curr_map): ++ for src in src_objs: ++ for dst in dst_objs: ++ if not src in curr_map: ++ curr_map[src] = [] ++ if not dst in curr_map[src]: ++ curr_map[src].append(dst) ++ def add_deps(self, src_objs, dst_objs): ++ self.__add_deps_internal(src_objs, dst_objs, self.deps) ++ def add_callrefs(self, src_objs, dst_objs): ++ self.__add_deps_internal(src_objs, dst_objs, self.callrefs) ++ ++# Process commands inside the {} construct. ++# Note that throughout this script, the main program object is represented ++# by the '#' string. ++def process_main_program(test_descr, mainprog_str): ++ if mainprog_str: ++ test_descr.main_program = mainprog_str.split(';') ++ for s in test_descr.main_program: ++ m = re.match(r"^([+\-%^@])([0-9a-zA-Z]+)$", s) ++ if not m: ++ error("'%s' is not recognized main program operation" % (s)) ++ opr = m.group(1) ++ obj = m.group(2) ++ if not obj in test_descr.objs: ++ test_descr.objs.append(obj) ++ if opr == '%' or opr == '@': ++ test_descr.add_callrefs(['#'], [obj]) ++ # We have a main program specified, turn this off ++ test_descr.main_program_default_deps = False ++ ++# For(a1 a2 b1-12) object set descriptions, expand into an object list ++def expand_object_set_string(descr_str): ++ obj_list = [] ++ descr_list = descr_str.split() ++ for descr in descr_list: ++ m = re.match(r"^([a-zA-Z][0-9a-zA-Z]*)(-[0-9]+)?$", descr) ++ if not m: ++ error("'%s' is not a valid object set description" % (descr)) ++ obj = m.group(1) ++ idx_end = m.group(2) ++ if not idx_end: ++ if not obj in obj_list: ++ obj_list.append(obj) ++ else: ++ idx_end = int(idx_end[1:]) ++ m = re.match(r"^([0-9a-zA-Z][a-zA-Z]*)([0-9]+)$", obj) ++ if not m: ++ error("object description '%s' is malformed" % (obj)) ++ obj_name = m.group(1) ++ idx_start = int(m.group (2)) ++ if idx_start > idx_end: ++ error("index range %s-%s invalid" % (idx_start, idx_end)) ++ for i in range(idx_start, idx_end + 1): ++ o = obj_name + str(i) ++ if not o in obj_list: ++ obj_list.append(o) ++ return obj_list ++ ++# Lexer for tokens ++tokenspec = [ ("SONAME", r"soname\(([0-9a-zA-Z{}]+)\)=([0-9a-zA-Z]+)"), ++ ("OBJ", r"([0-9a-zA-Z]+)"), ++ ("DEP", r"->"), ++ ("CALLREF", r"=>"), ++ ("OBJSET", r"\[([0-9a-zA-Z]+)\]"), ++ ("OBJSET2", r"\(([0-9a-zA-Z \-]+)\)"), ++ ("OBJSET3", r"\*"), ++ ("PROG", r"{([0-9a-zA-Z;+^\-%@]*)}"), ++ ("PERMUTE", r"!"), ++ ("SEMICOL", r";"), ++ ("ERROR", r".") ] ++tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tokenspec) ++ ++# Main line parser of description language ++def parse_description_string(t, descr_str): ++ # State used when parsing dependencies ++ curr_objs = [] ++ in_dep = False ++ in_callref = False ++ def clear_dep_state(): ++ nonlocal in_dep, in_callref ++ in_dep = in_callref = False ++ ++ for m in re.finditer(tok_re, descr_str): ++ kind = m.lastgroup ++ value = m.group() ++ if kind == "SONAME": ++ s = re.match(r"soname\(([0-9a-zA-Z{}]+)\)=([0-9a-zA-Z]+)", value) ++ obj = s.group(1) ++ val = s.group(2) ++ if obj == "{}": ++ if '#' in t.soname_map: ++ error("soname of main program already set") ++ # Adjust to internal name ++ obj = '#' ++ else: ++ if re.match(r"[{}]", obj): ++ error("invalid object name '%s'" % (obj)) ++ if not obj in t.objs: ++ error("'%s' is not name of already defined object" % (obj)) ++ if obj in t.soname_map: ++ error("'%s' already has soname of '%s' set" ++ % (obj, t.soname_map[obj])) ++ t.soname_map[obj] = val ++ ++ elif kind == "OBJ": ++ if in_dep: ++ t.add_deps(curr_objs, [value]) ++ elif in_callref: ++ t.add_callrefs(curr_objs, [value]) ++ clear_dep_state() ++ curr_objs = [value] ++ if not value in t.objs: ++ t.objs.append(value) ++ ++ elif kind == "OBJSET": ++ objset = value[1:len(value)-1] ++ if in_dep: ++ t.add_deps(curr_objs, list (objset)) ++ elif in_callref: ++ t.add_callrefs(curr_objs, list (objset)) ++ clear_dep_state() ++ curr_objs = list(objset) ++ for o in list(objset): ++ if not o in t.objs: ++ t.objs.append(o) ++ ++ elif kind == "OBJSET2": ++ descr_str = value[1:len(value)-1] ++ descr_str.strip() ++ objs = expand_object_set_string(descr_str) ++ if not objs: ++ error("empty object set '%s'" % (value)) ++ if in_dep: ++ t.add_deps(curr_objs, objs) ++ elif in_callref: ++ t.add_callrefs(curr_objs, objs) ++ clear_dep_state() ++ curr_objs = objs ++ for o in objs: ++ if not o in t.objs: ++ t.objs.append(o) ++ ++ elif kind == "OBJSET3": ++ if in_dep: ++ t.add_deps(curr_objs, ['*']) ++ elif in_callref: ++ t.add_callrefs(curr_objs, ['*']) ++ else: ++ error("non-dependence target set '*' can only be used " ++ "as target of ->/=> operations") ++ clear_dep_state() ++ curr_objs = ['*'] ++ ++ elif kind == "PERMUTE": ++ if in_dep or in_callref: ++ error("syntax error, permute operation invalid here") ++ if not curr_objs: ++ error("syntax error, no objects to permute here") ++ ++ for obj in curr_objs: ++ if not obj in t.dep_permutations: ++ # Signal this object has permuted dependencies ++ t.dep_permutations[obj] = [] ++ ++ elif kind == "PROG": ++ if t.main_program: ++ error("cannot have more than one main program") ++ if in_dep: ++ error("objects cannot have dependency on main program") ++ if in_callref: ++ # TODO: A DSO can resolve to a symbol in the main binary, ++ # which we syntactically allow here, but haven't yet ++ # implemented. ++ t.add_callrefs(curr_objs, ["#"]) ++ process_main_program(t, value[1:len(value)-1]) ++ clear_dep_state() ++ curr_objs = ["#"] ++ ++ elif kind == "DEP": ++ if in_dep or in_callref: ++ error("syntax error, multiple contiguous ->,=> operations") ++ if '*' in curr_objs: ++ error("non-dependence target set '*' can only be used " ++ "as target of ->/=> operations") ++ in_dep = True ++ ++ elif kind == "CALLREF": ++ if in_dep or in_callref: ++ error("syntax error, multiple contiguous ->,=> operations") ++ if '*' in curr_objs: ++ error("non-dependence target set '*' can only be used " ++ "as target of ->/=> operations") ++ in_callref = True ++ ++ elif kind == "SEMICOL": ++ curr_objs = [] ++ clear_dep_state() ++ ++ else: ++ error("unknown token '%s'" % (value)) ++ return t ++ ++# Main routine to process each testcase description ++def process_testcase(t): ++ global objpfx ++ assert t.test_name ++ ++ base_test_name = t.test_name ++ test_subdir = base_test_name + "-dir" ++ testpfx = objpfx + test_subdir + "/" ++ ++ if not os.path.exists(testpfx): ++ os.mkdir(testpfx) ++ ++ def find_objs_not_depended_on(t): ++ objs_not_depended_on = [] ++ for obj in t.objs: ++ skip = False ++ for r in t.deps.items(): ++ if obj in r[1]: ++ skip = True ++ break ++ if not skip: ++ objs_not_depended_on.append(obj) ++ return objs_not_depended_on ++ ++ non_dep_tgt_objs = find_objs_not_depended_on(t) ++ for obj in t.objs: ++ if obj in t.deps: ++ deps = t.deps[obj] ++ if '*' in deps: ++ t.deps[obj].remove('*') ++ t.add_deps([obj], non_dep_tgt_objs) ++ if obj in t.callrefs: ++ deps = t.callrefs[obj] ++ if '*' in deps: ++ t.deps[obj].remove('*') ++ t.add_callrefs([obj], non_dep_tgt_objs) ++ if "#" in t.deps: ++ deps = t.deps["#"] ++ if '*' in deps: ++ t.deps["#"].remove('*') ++ t.add_deps(["#"], non_dep_tgt_objs) ++ ++ # If no main program was specified in dependency description, make a ++ # default main program with deps pointing to all DSOs which are not ++ # depended by another DSO. ++ if t.main_program_default_deps: ++ main_deps = non_dep_tgt_objs ++ if not main_deps: ++ error("no objects for default main program to point " ++ "dependency to(all objects strongly connected?)") ++ t.add_deps(["#"], main_deps) ++ ++ # Some debug output ++ if cmdlineargs.debug_output: ++ print("Testcase: %s" % (t.test_name)) ++ print("All objects: %s" % (t.objs)) ++ print("--- Static link dependencies ---") ++ for r in t.deps.items(): ++ print("%s -> %s" % (r[0], r[1])) ++ print("--- Objects whose dependencies are to be permuted ---") ++ for r in t.dep_permutations.items(): ++ print("%s" % (r[0])) ++ print("--- Call reference dependencies ---") ++ for r in t.callrefs.items(): ++ print("%s => %s" % (r[0], r[1])) ++ print("--- main program ---") ++ print(t.main_program) ++ ++ # Main testcase generation routine, does Makefile fragment generation, ++ # testcase source generation, and if --build specified builds testcase. ++ def generate_testcase(test_descr, test_suffix): ++ ++ test_name = test_descr.test_name + test_suffix ++ ++ # Print out needed Makefile fragments for use in glibc/elf/Makefile. ++ module_names = "" ++ for o in test_descr.objs: ++ module_names += " " + test_subdir + "/" + test_name + "-" + o ++ makefile.write("modules-names +=%s\n" % (module_names)) ++ ++ # Depth-first traversal, executing FN(OBJ) in post-order ++ def dfs(t, fn): ++ def dfs_rec(obj, fn, obj_visited): ++ if obj in obj_visited: ++ return ++ obj_visited[obj] = True ++ if obj in t.deps: ++ for dep in t.deps[obj]: ++ dfs_rec(dep, fn, obj_visited) ++ fn(obj) ++ ++ obj_visited = {} ++ for obj in t.objs: ++ dfs_rec(obj, fn, obj_visited) ++ ++ # Generate link dependencies for all DSOs, done in a DFS fashion. ++ # Usually this doesn't need to be this complex, just listing the direct ++ # dependencies is enough. However to support creating circular ++ # dependency situations, traversing it by DFS and tracking processing ++ # status is the natural way to do it. ++ obj_processed = {} ++ fake_created = {} ++ def gen_link_deps(obj): ++ if obj in test_descr.deps: ++ dso = test_subdir + "/" + test_name + "-" + obj + ".so" ++ dependencies = "" ++ for dep in test_descr.deps[obj]: ++ if dep in obj_processed: ++ depstr = (" $(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".so") ++ else: ++ # A circular dependency is satisfied by making a ++ # fake DSO tagged with the correct SONAME ++ depstr = (" $(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".FAKE.so") ++ # Create empty C file and Makefile fragments for fake ++ # object. This only needs to be done at most once for ++ # an object name. ++ if not dep in fake_created: ++ f = open(testpfx + test_name + "-" + dep ++ + ".FAKE.c", "w") ++ f.write(" \n") ++ f.close() ++ # Generate rule to create fake object ++ makefile.write \ ++ ("LDFLAGS-%s = -Wl,--no-as-needed " ++ "-Wl,-soname=%s\n" ++ % (test_name + "-" + dep + ".FAKE.so", ++ ("$(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".so"))) ++ makefile.write \ ++ ("modules-names += %s\n" ++ % (test_subdir + "/" ++ + test_name + "-" + dep + ".FAKE")) ++ fake_created[dep] = True ++ dependencies += depstr ++ makefile.write("$(objpfx)%s:%s\n" % (dso, dependencies)) ++ # Mark obj as processed ++ obj_processed[obj] = True ++ ++ dfs(test_descr, gen_link_deps) ++ ++ # Print LDFLAGS-* and *-no-z-defs ++ for o in test_descr.objs: ++ dso = test_name + "-" + o + ".so" ++ ldflags = "-Wl,--no-as-needed" ++ if o in test_descr.soname_map: ++ soname = ("$(objpfx)" + test_subdir + "/" ++ + test_name + "-" ++ + test_descr.soname_map[o] + ".so") ++ ldflags += (" -Wl,-soname=" + soname) ++ makefile.write("LDFLAGS-%s = %s\n" % (dso, ldflags)) ++ if o in test_descr.callrefs: ++ makefile.write("%s-no-z-defs = yes\n" % (dso)) ++ ++ # Print dependencies for main test program. ++ depstr = "" ++ if '#' in test_descr.deps: ++ for o in test_descr.deps['#']: ++ depstr += (" $(objpfx)" + test_subdir + "/" ++ + test_name + "-" + o + ".so") ++ makefile.write("$(objpfx)%s/%s:%s\n" % (test_subdir, test_name, depstr)) ++ ldflags = "-Wl,--no-as-needed" ++ if '#' in test_descr.soname_map: ++ soname = ("$(objpfx)" + test_subdir + "/" ++ + test_name + "-" ++ + test_descr.soname_map['#'] + ".so") ++ ldflags += (" -Wl,-soname=" + soname) ++ makefile.write("LDFLAGS-%s = %s\n" % (test_name, ldflags)) ++ ++ not_depended_objs = find_objs_not_depended_on(test_descr) ++ if not_depended_objs: ++ depstr = "" ++ for dep in not_depended_objs: ++ depstr += (" $(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".so") ++ makefile.write("$(objpfx)%s.out:%s\n" % (base_test_name, depstr)) ++ ++ # Add main executable to test-srcs ++ makefile.write("test-srcs += %s/%s\n" % (test_subdir, test_name)) ++ # Add dependency on main executable of test ++ makefile.write("$(objpfx)%s.out: $(objpfx)%s/%s\n" ++ % (base_test_name, test_subdir, test_name)) ++ ++ for r in test_descr.expected_outputs.items(): ++ tunable_options = [] ++ specific_tunable = r[0] ++ xfail = r[1][1] ++ if specific_tunable != "": ++ tunable_options = [specific_tunable] ++ else: ++ tunable_options = default_tunable_options ++ if not tunable_options: ++ tunable_options = [""] ++ ++ for tunable in tunable_options: ++ tunable_env = "" ++ tunable_sfx = "" ++ exp_tunable_sfx = "" ++ if tunable: ++ tunable_env = "GLIBC_TUNABLES=%s " % tunable ++ tunable_sfx = "-" + tunable.replace("=","_") ++ if specific_tunable: ++ tunable_sfx = "-" + specific_tunable.replace("=","_") ++ exp_tunable_sfx = tunable_sfx ++ tunable_descr = ("(%s)" % tunable_env.strip() ++ if tunable_env else "") ++ # Write out fragment of shell script for this single test. ++ test_descr.sh.write \ ++ ("%s${test_wrapper_env} ${run_program_env} \\\n" ++ "${common_objpfx}support/test-run-command \\\n" ++ "${common_objpfx}elf/ld.so \\\n" ++ "--library-path ${common_objpfx}elf/%s:" ++ "${common_objpfx}elf:${common_objpfx}.:" ++ "${common_objpfx}dlfcn \\\n" ++ "${common_objpfx}elf/%s/%s > \\\n" ++ " ${common_objpfx}elf/%s/%s%s.output\n" ++ % (tunable_env ,test_subdir, ++ test_subdir, test_name, test_subdir, test_name, ++ tunable_sfx)) ++ # Generate a run of each test and compare with expected out ++ test_descr.sh.write \ ++ ("if [ $? -ne 0 ]; then\n" ++ " echo '%sFAIL: %s%s execution test'\n" ++ " something_failed=true\n" ++ "else\n" ++ " diff -wu ${common_objpfx}elf/%s/%s%s.output \\\n" ++ " ${common_objpfx}elf/%s/%s%s.exp\n" ++ " if [ $? -ne 0 ]; then\n" ++ " echo '%sFAIL: %s%s expected output comparison'\n" ++ " something_failed=true\n" ++ " fi\n" ++ "fi\n" ++ % (("X" if xfail else ""), test_name, tunable_descr, ++ test_subdir, test_name, tunable_sfx, ++ test_subdir, base_test_name, exp_tunable_sfx, ++ ("X" if xfail else ""), test_name, tunable_descr)) ++ ++ # Generate C files according to dependency and calling relations from ++ # description string. ++ for obj in test_descr.objs: ++ src_name = test_name + "-" + obj + ".c" ++ f = open(testpfx + src_name, "w") ++ if obj in test_descr.callrefs: ++ called_objs = test_descr.callrefs[obj] ++ for callee in called_objs: ++ f.write("extern void fn_%s (void);\n" % (callee)) ++ if len(obj) == 1: ++ f.write("extern int putchar(int);\n") ++ f.write("static void __attribute__((constructor)) " + ++ "init(void){putchar('%s');putchar('>');}\n" % (obj)) ++ f.write("static void __attribute__((destructor)) " + ++ "fini(void){putchar('<');putchar('%s');}\n" % (obj)) ++ else: ++ f.write('extern int printf(const char *, ...);\n') ++ f.write('static void __attribute__((constructor)) ' + ++ 'init(void){printf("%s>");}\n' % (obj)) ++ f.write('static void __attribute__((destructor)) ' + ++ 'fini(void){printf("<%s");}\n' % (obj)) ++ if obj in test_descr.callrefs: ++ called_objs = test_descr.callrefs[obj] ++ if len(obj) != 1: ++ f.write("extern int putchar(int);\n") ++ f.write("void fn_%s (void) {\n" % (obj)) ++ if len(obj) == 1: ++ f.write(" putchar ('%s');\n" % (obj)); ++ f.write(" putchar ('(');\n"); ++ else: ++ f.write(' printf ("%s(");\n' % (obj)); ++ for callee in called_objs: ++ f.write(" fn_%s ();\n" % (callee)) ++ f.write(" putchar (')');\n"); ++ f.write("}\n") ++ else: ++ for callref in test_descr.callrefs.items(): ++ if obj in callref[1]: ++ if len(obj) == 1: ++ # We need to declare printf here in this case. ++ f.write('extern int printf(const char *, ...);\n') ++ f.write("void fn_%s (void) {\n" % (obj)) ++ f.write(' printf ("%s()");\n' % (obj)) ++ f.write("}\n") ++ break ++ f.close() ++ ++ # Open C file for writing main program ++ f = open(testpfx + test_name + ".c", "w") ++ ++ # if there are some operations in main(), it means we need -ldl ++ f.write("#include \n") ++ f.write("#include \n") ++ f.write("#include \n") ++ for s in test_descr.main_program: ++ if s[0] == '@': ++ f.write("extern void fn_%s (void);\n" % (s[1:])); ++ f.write("int main (void) {\n") ++ f.write(" putchar('{');\n") ++ ++ # Helper routine for generating sanity checking code. ++ def put_fail_check(fail_cond, action_desc): ++ f.write(' if (%s) { printf ("\\n%s failed: %%s\\n", ' ++ 'dlerror()); exit (1);}\n' % (fail_cond, action_desc)) ++ i = 0 ++ while i < len(test_descr.main_program): ++ s = test_descr.main_program[i] ++ obj = s[1:] ++ dso = test_name + "-" + obj ++ if s[0] == '+' or s[0] == '^': ++ if s[0] == '+': ++ dlopen_flags = "RTLD_LAZY|RTLD_GLOBAL" ++ f.write(" putchar('+');\n"); ++ else: ++ dlopen_flags = "RTLD_LAZY" ++ f.write(" putchar(':');\n"); ++ if len(obj) == 1: ++ f.write(" putchar('%s');\n" % (obj)); ++ else: ++ f.write(' printf("%s");\n' % (obj)); ++ f.write(" putchar('[');\n"); ++ f.write(' void *%s = dlopen ("%s.so", %s);\n' ++ % (obj, dso, dlopen_flags)) ++ put_fail_check("!%s" % (obj), ++ "%s.so dlopen" % (dso)) ++ f.write(" putchar(']');\n"); ++ elif s[0] == '-': ++ f.write(" putchar('-');\n"); ++ if len(obj) == 1: ++ f.write(" putchar('%s');\n" % (obj)); ++ else: ++ f.write(' printf("%s");\n' % (obj)); ++ f.write(" putchar('[');\n"); ++ put_fail_check("dlclose (%s) != 0" % (obj), ++ "%s.so dlclose" % (dso)) ++ f.write(" putchar(']');\n"); ++ elif s[0] == '%': ++ f.write(" putchar('%');\n"); ++ f.write(' void (*fn_%s)(void) = dlsym (%s, "fn_%s");\n' ++ % (obj, obj, obj)) ++ put_fail_check("!fn_%s" % (obj), ++ "dlsym(fn_%s) from %s.so" % (obj, dso)) ++ f.write(" fn_%s ();\n" % (obj)) ++ elif s[0] == '@': ++ f.write(" putchar('@');\n"); ++ f.write(" fn_%s ();\n" % (obj)) ++ f.write(" putchar(';');\n"); ++ i += 1 ++ f.write(" putchar('}');\n") ++ f.write(" return 0;\n") ++ f.write("}\n") ++ f.close() ++ ++ # --build option processing: build generated sources using 'build_gcc' ++ if cmdlineargs.build: ++ # Helper routine to run a shell command, for running GCC below ++ def run_cmd(args): ++ cmd = str.join(' ', args) ++ if cmdlineargs.debug_output: ++ print(cmd) ++ p = subprocess.Popen(args) ++ p.wait() ++ if p.returncode != 0: ++ error("error running command: %s" % (cmd)) ++ ++ # Compile individual .os files ++ for obj in test_descr.objs: ++ src_name = test_name + "-" + obj + ".c" ++ obj_name = test_name + "-" + obj + ".os" ++ run_cmd([build_gcc, "-c", "-fPIC", testpfx + src_name, ++ "-o", testpfx + obj_name]) ++ ++ obj_processed = {} ++ fake_created = {} ++ # Function to create -.so ++ def build_dso(obj): ++ obj_name = test_name + "-" + obj + ".os" ++ dso_name = test_name + "-" + obj + ".so" ++ deps = [] ++ if obj in test_descr.deps: ++ for dep in test_descr.deps[obj]: ++ if dep in obj_processed: ++ deps.append(dep) ++ else: ++ deps.append(dep + ".FAKE") ++ if not dep in fake_created: ++ base_name = testpfx + test_name + "-" + dep ++ cmd = [build_gcc, "-Wl,--no-as-needed", ++ ("-Wl,-soname=" + base_name + ".so"), ++ "-shared", base_name + ".FAKE.c", ++ "-o", base_name + ".FAKE.so"] ++ run_cmd(cmd) ++ fake_created[dep] = True ++ dso_deps = map(lambda d: testpfx + test_name + "-" + d + ".so", ++ deps) ++ cmd = [build_gcc, "-shared", "-o", testpfx + dso_name, ++ testpfx + obj_name, "-Wl,--no-as-needed"] ++ if obj in test_descr.soname_map: ++ soname = ("-Wl,-soname=" + testpfx + test_name + "-" ++ + test_descr.soname_map[obj] + ".so") ++ cmd += [soname] ++ cmd += list(dso_deps) ++ run_cmd(cmd) ++ obj_processed[obj] = True ++ ++ # Build all DSOs, this needs to be in topological dependency order, ++ # or link will fail ++ dfs(test_descr, build_dso) ++ ++ # Build main program ++ deps = [] ++ if '#' in test_descr.deps: ++ deps = test_descr.deps['#'] ++ main_deps = map(lambda d: testpfx + test_name + "-" + d + ".so", ++ deps) ++ cmd = [build_gcc, "-Wl,--no-as-needed", "-o", testpfx + test_name, ++ testpfx + test_name + ".c", "-L%s" % (os.getcwd()), ++ "-Wl,-rpath-link=%s" % (os.getcwd())] ++ if '#' in test_descr.soname_map: ++ soname = ("-Wl,-soname=" + testpfx + test_name + "-" ++ + test_descr.soname_map['#'] + ".so") ++ cmd += [soname] ++ cmd += list(main_deps) ++ run_cmd(cmd) ++ ++ # Check if we need to enumerate permutations of dependencies ++ need_permutation_processing = False ++ if t.dep_permutations: ++ # Adjust dep_permutations into map of object -> dependency permutations ++ for r in t.dep_permutations.items(): ++ obj = r[0] ++ if obj in t.deps and len(t.deps[obj]) > 1: ++ deps = t.deps[obj] ++ t.dep_permutations[obj] = list(itertools.permutations (deps)) ++ need_permutation_processing = True ++ ++ def enum_permutations(t, perm_list): ++ test_subindex = 1 ++ curr_perms = [] ++ def enum_permutations_rec(t, perm_list): ++ nonlocal test_subindex, curr_perms ++ if len(perm_list) >= 1: ++ curr = perm_list[0] ++ obj = curr[0] ++ perms = curr[1] ++ if not perms: ++ # This may be an empty list if no multiple dependencies to ++ # permute were found, skip to next in this case ++ enum_permutations_rec(t, perm_list[1:]) ++ else: ++ for deps in perms: ++ t.deps[obj] = deps ++ permstr = "" if obj == "#" else obj + "_" ++ permstr += str.join('', deps) ++ curr_perms.append(permstr) ++ enum_permutations_rec(t, perm_list[1:]) ++ curr_perms = curr_perms[0:len(curr_perms)-1] ++ else: ++ # t.deps is now instantiated with one dependency order ++ # permutation(across all objects that have multiple ++ # permutations), now process a testcase ++ generate_testcase(t, ("_" + str (test_subindex) ++ + "-" + str.join('-', curr_perms))) ++ test_subindex += 1 ++ enum_permutations_rec(t, perm_list) ++ ++ # Create *.exp files with expected outputs ++ for r in t.expected_outputs.items(): ++ sfx = "" ++ if r[0] != "": ++ sfx = "-" + r[0].replace("=","_") ++ f = open(testpfx + t.test_name + sfx + ".exp", "w") ++ (output, xfail) = r[1] ++ f.write('%s' % output) ++ f.close() ++ ++ # Create header part of top-level testcase shell script, to wrap execution ++ # and output comparison together. ++ t.sh = open(testpfx + t.test_name + ".sh", "w") ++ t.sh.write("#!/bin/sh\n") ++ t.sh.write("# Test driver for %s, generated by " ++ "dso-ordering-test.py\n" % (t.test_name)) ++ t.sh.write("common_objpfx=$1\n") ++ t.sh.write("test_wrapper_env=$2\n") ++ t.sh.write("run_program_env=$3\n") ++ t.sh.write("something_failed=false\n") ++ ++ # Starting part of Makefile fragment ++ makefile.write("ifeq (yes,$(build-shared))\n") ++ ++ if need_permutation_processing: ++ enum_permutations(t, list (t.dep_permutations.items())) ++ else: ++ # We have no permutations to enumerate, just process testcase normally ++ generate_testcase(t, "") ++ ++ # If testcase is XFAIL, indicate so ++ if t.xfail: ++ makefile.write("test-xfail-%s = yes\n" % t.test_name) ++ ++ # Output end part of Makefile fragment ++ expected_output_files = "" ++ for r in t.expected_outputs.items(): ++ sfx = "" ++ if r[0] != "": ++ sfx = "-" + r[0].replace("=","_") ++ expected_output_files += " $(objpfx)%s/%s%s.exp" % (test_subdir, ++ t.test_name, sfx) ++ makefile.write \ ++ ("$(objpfx)%s.out: $(objpfx)%s/%s.sh%s " ++ "$(common-objpfx)support/test-run-command\n" ++ % (t.test_name, test_subdir, t.test_name, ++ expected_output_files)) ++ makefile.write("\t$(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' " ++ "'$(run-program-env)' > $@; $(evaluate-test)\n") ++ makefile.write("ifeq ($(run-built-tests),yes)\n") ++ if t.xtest: ++ makefile.write("xtests-special += $(objpfx)%s.out\n" % (t.test_name)) ++ else: ++ makefile.write("tests-special += $(objpfx)%s.out\n" % (t.test_name)) ++ makefile.write("endif\n") ++ makefile.write("endif\n") ++ ++ # Write ending part of shell script generation ++ t.sh.write("if $something_failed; then\n" ++ " exit 1\n" ++ "else\n" ++ " echo '%sPASS: all tests for %s succeeded'\n" ++ " exit 0\n" ++ "fi\n" % (("X" if t.xfail else ""), ++ t.test_name)) ++ t.sh.close() ++ ++# Decription file parsing ++def parse_description_file(filename): ++ global default_tunable_options ++ global current_input_lineno ++ f = open(filename) ++ if not f: ++ error("cannot open description file %s" % (filename)) ++ descrfile_lines = f.readlines() ++ t = None ++ for line in descrfile_lines: ++ p = re.compile(r"#.*$") ++ line = p.sub("", line) # Filter out comments ++ line = line.strip() # Remove excess whitespace ++ current_input_lineno += 1 ++ ++ m = re.match(r"^tunable_option:\s*(.*)$", line) ++ if m: ++ if m.group(1) == "": ++ error("tunable option cannot be empty") ++ default_tunable_options.append(m.group (1)) ++ continue ++ ++ m = re.match(r"^clear_tunables$", line) ++ if m: ++ default_tunable_options = [] ++ continue ++ ++ m = re.match(r"^([^:]+):\s*(.*)$", line) ++ if m: ++ lhs = m.group(1) ++ o = re.match(r"^output(.*)$", lhs) ++ xfail = False ++ if not o: ++ o = re.match(r"^xfail_output(.*)$", lhs) ++ if o: ++ xfail = True; ++ if o: ++ if not t: ++ error("output specification without testcase description") ++ tsstr = "" ++ if o.group(1): ++ ts = re.match(r"^\(([a-zA-Z0-9_.=]*)\)$", o.group (1)) ++ if not ts: ++ error("tunable option malformed '%s'" % o.group(1)) ++ tsstr = ts.group(1) ++ t.expected_outputs[tsstr] = (m.group(2), xfail) ++ # Any tunable option XFAILed means entire testcase ++ # is XFAIL/XPASS ++ t.xfail |= xfail ++ else: ++ if t: ++ # Starting a new test description, end and process ++ # current one. ++ process_testcase(t) ++ t = TestDescr() ++ x = re.match(r"^xtest\((.*)\)$", lhs) ++ if x: ++ t.xtest = True ++ t.test_name = x.group(1) ++ else: ++ t.test_name = lhs ++ descr_string = m.group(2) ++ parse_description_string(t, descr_string) ++ continue ++ else: ++ if line: ++ if not t: ++ error("no active testcase description") ++ parse_description_string(t, line) ++ # Process last completed test description ++ if t: ++ process_testcase(t) ++ ++# Setup Makefile output to file or stdout as selected ++if output_makefile: ++ output_makefile_dir = os.path.dirname(output_makefile) ++ if output_makefile_dir: ++ os.makedirs(output_makefile_dir, exist_ok = True) ++ makefile = open(output_makefile, "w") ++else: ++ makefile = open(sys.stdout.fileno (), "w") ++ ++# Finally, the main top-level calling of above parsing routines. ++if description_file: ++ parse_description_file(description_file) ++else: ++ t = TestDescr() ++ t.test_name = test_name ++ parse_description_string(t, description) ++ process_testcase(t) ++ ++# Close Makefile fragment output ++makefile.close() +diff --git a/support/Depend b/support/Depend +new file mode 100644 +index 0000000000000000..7e7d5dc67c13e669 +--- /dev/null ++++ b/support/Depend +@@ -0,0 +1 @@ ++elf +diff --git a/support/Makefile b/support/Makefile +index 2a0731796fdb3f2d..75bad6715ac3d08c 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -254,10 +254,16 @@ others-noinstall += shell-container echo-container true-container + others += $(LINKS_DSO_PROGRAM) + others-noinstall += $(LINKS_DSO_PROGRAM) + ++others += test-run-command ++others-static += test-run-command ++others-noinstall += test-run-command ++LDLIBS-test-run-command = $(libsupport) ++ + $(objpfx)test-container : $(libsupport) + $(objpfx)shell-container : $(libsupport) + $(objpfx)echo-container : $(libsupport) + $(objpfx)true-container : $(libsupport) ++$(objpfx)test-run-command : $(libsupport) $(common-objpfx)elf/static-stubs.o + + tests = \ + README-testing \ +diff --git a/support/support_test_main.c b/support/support_test_main.c +index 07e3cdd173cecfc0..66a754b84fbb79ad 100644 +--- a/support/support_test_main.c ++++ b/support/support_test_main.c +@@ -228,6 +228,18 @@ run_test_function (int argc, char **argv, const struct test_config *config) + while (wait_for_debugger) + usleep (1000); + ++ if (config->run_command_mode) ++ { ++ /* In run-command-mode, the child process executes the command line ++ arguments as a new program. */ ++ char **argv_ = xmalloc (sizeof (char *) * argc); ++ memcpy (argv_, &argv[1], sizeof (char *) * (argc - 1)); ++ argv_[argc - 1] = NULL; ++ execv (argv_[0], argv_); ++ printf ("error: should not return here\n"); ++ exit (1); ++ } ++ + if (config->test_function != NULL) + return config->test_function (); + else if (config->test_function_argv != NULL) +diff --git a/support/test-driver.c b/support/test-driver.c +index b0bea46deeb41b3b..1552f62c9b5d0f7b 100644 +--- a/support/test-driver.c ++++ b/support/test-driver.c +@@ -116,7 +116,9 @@ main (int argc, char **argv) + #if defined (TEST_FUNCTION) && defined (TEST_FUNCTON_ARGV) + # error TEST_FUNCTION and TEST_FUNCTION_ARGV cannot be defined at the same time + #endif +-#if defined (TEST_FUNCTION) ++#ifdef RUN_COMMAND_MODE ++ test_config.run_command_mode = 1; ++#elif defined (TEST_FUNCTION) + test_config.test_function = TEST_FUNCTION; + #elif defined (TEST_FUNCTION_ARGV) + test_config.test_function_argv = TEST_FUNCTION_ARGV; +diff --git a/support/test-driver.h b/support/test-driver.h +index 8d4f38275d219de0..b44c0ff03326fca4 100644 +--- a/support/test-driver.h ++++ b/support/test-driver.h +@@ -36,6 +36,7 @@ struct test_config + int expected_signal; /* If non-zero, expect termination by signal. */ + char no_mallopt; /* Boolean flag to disable mallopt. */ + char no_setvbuf; /* Boolean flag to disable setvbuf. */ ++ char run_command_mode; /* Boolean flag to indicate run-command-mode. */ + const char *optstring; /* Short command line options. */ + }; + +diff --git a/support/test-run-command.c b/support/test-run-command.c +new file mode 100644 +index 0000000000000000..61560d7bfb1686a8 +--- /dev/null ++++ b/support/test-run-command.c +@@ -0,0 +1,22 @@ ++/* Main program for test-run-command support utility. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This is basically a configuration of test-driver.c into a general ++ command-line program runner. */ ++#define RUN_COMMAND_MODE ++#include diff --git a/SOURCES/glibc-rh2032647-2.patch b/SOURCES/glibc-rh2032647-2.patch new file mode 100644 index 0000000..4ac1d1a --- /dev/null +++ b/SOURCES/glibc-rh2032647-2.patch @@ -0,0 +1,585 @@ +commit 15a0c5730d1d5aeb95f50c9ec7470640084feae8 +Author: Chung-Lin Tang +Date: Thu Oct 21 21:41:22 2021 +0800 + + elf: Fix slow DSO sorting behavior in dynamic loader (BZ #17645) + + This second patch contains the actual implementation of a new sorting algorithm + for shared objects in the dynamic loader, which solves the slow behavior that + the current "old" algorithm falls into when the DSO set contains circular + dependencies. + + The new algorithm implemented here is simply depth-first search (DFS) to obtain + the Reverse-Post Order (RPO) sequence, a topological sort. A new l_visited:1 + bitfield is added to struct link_map to more elegantly facilitate such a search. + + The DFS algorithm is applied to the input maps[nmap-1] backwards towards + maps[0]. This has the effect of a more "shallow" recursion depth in general + since the input is in BFS. Also, when combined with the natural order of + processing l_initfini[] at each node, this creates a resulting output sorting + closer to the intuitive "left-to-right" order in most cases. + + Another notable implementation adjustment related to this _dl_sort_maps change + is the removing of two char arrays 'used' and 'done' in _dl_close_worker to + represent two per-map attributes. This has been changed to simply use two new + bit-fields l_map_used:1, l_map_done:1 added to struct link_map. This also allows + discarding the clunky 'used' array sorting that _dl_sort_maps had to sometimes + do along the way. + + Tunable support for switching between different sorting algorithms at runtime is + also added. A new tunable 'glibc.rtld.dynamic_sort' with current valid values 1 + (old algorithm) and 2 (new DFS algorithm) has been added. At time of commit + of this patch, the default setting is 1 (old algorithm). + + Signed-off-by: Chung-Lin Tang + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/dl-close.c b/elf/dl-close.c +index cd7b9c9fe83a1a44..f6fbf9de7d78555b 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -167,8 +167,6 @@ _dl_close_worker (struct link_map *map, bool force) + + bool any_tls = false; + const unsigned int nloaded = ns->_ns_nloaded; +- char used[nloaded]; +- char done[nloaded]; + struct link_map *maps[nloaded]; + + /* Run over the list and assign indexes to the link maps and enter +@@ -176,24 +174,21 @@ _dl_close_worker (struct link_map *map, bool force) + int idx = 0; + for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next) + { ++ l->l_map_used = 0; ++ l->l_map_done = 0; + l->l_idx = idx; + maps[idx] = l; + ++idx; +- + } + assert (idx == nloaded); + +- /* Prepare the bitmaps. */ +- memset (used, '\0', sizeof (used)); +- memset (done, '\0', sizeof (done)); +- + /* Keep track of the lowest index link map we have covered already. */ + int done_index = -1; + while (++done_index < nloaded) + { + struct link_map *l = maps[done_index]; + +- if (done[done_index]) ++ if (l->l_map_done) + /* Already handled. */ + continue; + +@@ -204,12 +199,12 @@ _dl_close_worker (struct link_map *map, bool force) + /* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why + acquire is sufficient and correct. */ + && atomic_load_acquire (&l->l_tls_dtor_count) == 0 +- && !used[done_index]) ++ && !l->l_map_used) + continue; + + /* We need this object and we handle it now. */ +- done[done_index] = 1; +- used[done_index] = 1; ++ l->l_map_used = 1; ++ l->l_map_done = 1; + /* Signal the object is still needed. */ + l->l_idx = IDX_STILL_USED; + +@@ -225,9 +220,9 @@ _dl_close_worker (struct link_map *map, bool force) + { + assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded); + +- if (!used[(*lp)->l_idx]) ++ if (!(*lp)->l_map_used) + { +- used[(*lp)->l_idx] = 1; ++ (*lp)->l_map_used = 1; + /* If we marked a new object as used, and we've + already processed it, then we need to go back + and process again from that point forward to +@@ -250,9 +245,9 @@ _dl_close_worker (struct link_map *map, bool force) + { + assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded); + +- if (!used[jmap->l_idx]) ++ if (!jmap->l_map_used) + { +- used[jmap->l_idx] = 1; ++ jmap->l_map_used = 1; + if (jmap->l_idx - 1 < done_index) + done_index = jmap->l_idx - 1; + } +@@ -262,8 +257,7 @@ _dl_close_worker (struct link_map *map, bool force) + + /* Sort the entries. We can skip looking for the binary itself which is + at the front of the search list for the main namespace. */ +- _dl_sort_maps (maps + (nsid == LM_ID_BASE), nloaded - (nsid == LM_ID_BASE), +- used + (nsid == LM_ID_BASE), true); ++ _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true); + + /* Call all termination functions at once. */ + #ifdef SHARED +@@ -280,7 +274,7 @@ _dl_close_worker (struct link_map *map, bool force) + /* All elements must be in the same namespace. */ + assert (imap->l_ns == nsid); + +- if (!used[i]) ++ if (!imap->l_map_used) + { + assert (imap->l_type == lt_loaded && !imap->l_nodelete_active); + +@@ -333,7 +327,7 @@ _dl_close_worker (struct link_map *map, bool force) + if (i < first_loaded) + first_loaded = i; + } +- /* Else used[i]. */ ++ /* Else imap->l_map_used. */ + else if (imap->l_type == lt_loaded) + { + struct r_scope_elem *new_list = NULL; +@@ -560,7 +554,7 @@ _dl_close_worker (struct link_map *map, bool force) + for (unsigned int i = first_loaded; i < nloaded; ++i) + { + struct link_map *imap = maps[i]; +- if (!used[i]) ++ if (!imap->l_map_used) + { + assert (imap->l_type == lt_loaded); + +diff --git a/elf/dl-deps.c b/elf/dl-deps.c +index 087a49b212a96920..237d9636c5be780c 100644 +--- a/elf/dl-deps.c ++++ b/elf/dl-deps.c +@@ -613,10 +613,9 @@ Filters not supported with LD_TRACE_PRELINKING")); + + /* If libc.so.6 is the main map, it participates in the sort, so + that the relocation order is correct regarding libc.so.6. */ +- if (l_initfini[0] == GL (dl_ns)[l_initfini[0]->l_ns].libc_map) +- _dl_sort_maps (l_initfini, nlist, NULL, false); +- else +- _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false); ++ _dl_sort_maps (l_initfini, nlist, ++ (l_initfini[0] != GL (dl_ns)[l_initfini[0]->l_ns].libc_map), ++ false); + + /* Terminate the list of dependencies. */ + l_initfini[nlist] = NULL; +diff --git a/elf/dl-fini.c b/elf/dl-fini.c +index 6dbdfe4b3ebbeb89..c683884c355dfd52 100644 +--- a/elf/dl-fini.c ++++ b/elf/dl-fini.c +@@ -92,8 +92,7 @@ _dl_fini (void) + /* Now we have to do the sorting. We can skip looking for the + binary itself which is at the front of the search list for + the main namespace. */ +- _dl_sort_maps (maps + (ns == LM_ID_BASE), nmaps - (ns == LM_ID_BASE), +- NULL, true); ++ _dl_sort_maps (maps, nmaps, (ns == LM_ID_BASE), true); + + /* We do not rely on the linked list of loaded object anymore + from this point on. We have our own list here (maps). The +diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c +index d21770267a37e128..a274ed66cc987735 100644 +--- a/elf/dl-sort-maps.c ++++ b/elf/dl-sort-maps.c +@@ -16,16 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include ++#include + ++/* Note: this is the older, "original" sorting algorithm, being used as ++ default up to 2.35. + +-/* Sort array MAPS according to dependencies of the contained objects. +- Array USED, if non-NULL, is permutated along MAPS. If FOR_FINI this is +- called for finishing an object. */ +-void +-_dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, +- bool for_fini) ++ Sort array MAPS according to dependencies of the contained objects. ++ If FOR_FINI is true, this is called for finishing an object. */ ++static void ++_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps, ++ unsigned int skip, bool for_fini) + { ++ /* Allows caller to do the common optimization of skipping the first map, ++ usually the main binary. */ ++ maps += skip; ++ nmaps -= skip; ++ + /* A list of one element need not be sorted. */ + if (nmaps <= 1) + return; +@@ -66,14 +74,6 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, + (k - i) * sizeof (maps[0])); + maps[k] = thisp; + +- if (used != NULL) +- { +- char here_used = used[i]; +- memmove (&used[i], &used[i + 1], +- (k - i) * sizeof (used[0])); +- used[k] = here_used; +- } +- + if (seen[i + 1] > nmaps - i) + { + ++i; +@@ -120,3 +120,183 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, + next:; + } + } ++ ++#if !HAVE_TUNABLES ++/* In this case, just default to the original algorithm. */ ++strong_alias (_dl_sort_maps_original, _dl_sort_maps); ++#else ++ ++/* We use a recursive function due to its better clarity and ease of ++ implementation, as well as faster execution speed. We already use ++ alloca() for list allocation during the breadth-first search of ++ dependencies in _dl_map_object_deps(), and this should be on the ++ same order of worst-case stack usage. ++ ++ Note: the '*rpo' parameter is supposed to point to one past the ++ last element of the array where we save the sort results, and is ++ decremented before storing the current map at each level. */ ++ ++static void ++dfs_traversal (struct link_map ***rpo, struct link_map *map, ++ bool *do_reldeps) ++{ ++ if (map->l_visited) ++ return; ++ ++ map->l_visited = 1; ++ ++ if (map->l_initfini) ++ { ++ for (int i = 0; map->l_initfini[i] != NULL; i++) ++ { ++ struct link_map *dep = map->l_initfini[i]; ++ if (dep->l_visited == 0 ++ && dep->l_main_map == 0) ++ dfs_traversal (rpo, dep, do_reldeps); ++ } ++ } ++ ++ if (__glibc_unlikely (do_reldeps != NULL && map->l_reldeps != NULL)) ++ { ++ /* Indicate that we encountered relocation dependencies during ++ traversal. */ ++ *do_reldeps = true; ++ ++ for (int m = map->l_reldeps->act - 1; m >= 0; m--) ++ { ++ struct link_map *dep = map->l_reldeps->list[m]; ++ if (dep->l_visited == 0 ++ && dep->l_main_map == 0) ++ dfs_traversal (rpo, dep, do_reldeps); ++ } ++ } ++ ++ *rpo -= 1; ++ **rpo = map; ++} ++ ++/* Topologically sort array MAPS according to dependencies of the contained ++ objects. */ ++ ++static void ++_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps, ++ unsigned int skip __attribute__ ((unused)), bool for_fini) ++{ ++ for (int i = nmaps - 1; i >= 0; i--) ++ maps[i]->l_visited = 0; ++ ++ /* We apply DFS traversal for each of maps[i] until the whole total order ++ is found and we're at the start of the Reverse-Postorder (RPO) sequence, ++ which is a topological sort. ++ ++ We go from maps[nmaps - 1] backwards towards maps[0] at this level. ++ Due to the breadth-first search (BFS) ordering we receive, going ++ backwards usually gives a more shallow depth-first recursion depth, ++ adding more stack usage safety. Also, combined with the natural ++ processing order of l_initfini[] at each node during DFS, this maintains ++ an ordering closer to the original link ordering in the sorting results ++ under most simpler cases. ++ ++ Another reason we order the top level backwards, it that maps[0] is ++ usually exactly the main object of which we're in the midst of ++ _dl_map_object_deps() processing, and maps[0]->l_initfini[] is still ++ blank. If we start the traversal from maps[0], since having no ++ dependencies yet filled in, maps[0] will always be immediately ++ incorrectly placed at the last place in the order (first in reverse). ++ Adjusting the order so that maps[0] is last traversed naturally avoids ++ this problem. ++ ++ Further, the old "optimization" of skipping the main object at maps[0] ++ from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general ++ no longer valid, since traversing along object dependency-links ++ may "find" the main object even when it is not included in the initial ++ order (e.g. a dlopen()'ed shared object can have circular dependencies ++ linked back to itself). In such a case, traversing N-1 objects will ++ create a N-object result, and raise problems. ++ ++ To summarize, just passing in the full list, and iterating from back ++ to front makes things much more straightforward. */ ++ ++ /* Array to hold RPO sorting results, before we copy back to maps[]. */ ++ struct link_map *rpo[nmaps]; ++ ++ /* The 'head' position during each DFS iteration. Note that we start at ++ one past the last element due to first-decrement-then-store (see the ++ bottom of above dfs_traversal() routine). */ ++ struct link_map **rpo_head = &rpo[nmaps]; ++ ++ bool do_reldeps = false; ++ bool *do_reldeps_ref = (for_fini ? &do_reldeps : NULL); ++ ++ for (int i = nmaps - 1; i >= 0; i--) ++ { ++ dfs_traversal (&rpo_head, maps[i], do_reldeps_ref); ++ ++ /* We can break early if all objects are already placed. */ ++ if (rpo_head == rpo) ++ goto end; ++ } ++ assert (rpo_head == rpo); ++ ++ end: ++ /* Here we may do a second pass of sorting, using only l_initfini[] ++ static dependency links. This is avoided if !FOR_FINI or if we didn't ++ find any reldeps in the first DFS traversal. ++ ++ The reason we do this is: while it is unspecified how circular ++ dependencies should be handled, the presumed reasonable behavior is to ++ have destructors to respect static dependency links as much as possible, ++ overriding reldeps if needed. And the first sorting pass, which takes ++ l_initfini/l_reldeps links equally, may not preserve this priority. ++ ++ Hence we do a 2nd sorting pass, taking only DT_NEEDED links into account ++ (see how the do_reldeps argument to dfs_traversal() is NULL below). */ ++ if (do_reldeps) ++ { ++ for (int i = nmaps - 1; i >= 0; i--) ++ rpo[i]->l_visited = 0; ++ ++ struct link_map **maps_head = &maps[nmaps]; ++ for (int i = nmaps - 1; i >= 0; i--) ++ { ++ dfs_traversal (&maps_head, rpo[i], NULL); ++ ++ /* We can break early if all objects are already placed. ++ The below memcpy is not needed in the do_reldeps case here, ++ since we wrote back to maps[] during DFS traversal. */ ++ if (maps_head == maps) ++ return; ++ } ++ assert (maps_head == maps); ++ return; ++ } ++ ++ memcpy (maps, rpo, sizeof (struct link_map *) * nmaps); ++} ++ ++void ++_dl_sort_maps_init (void) ++{ ++ int32_t algorithm = TUNABLE_GET (glibc, rtld, dynamic_sort, int32_t, NULL); ++ GLRO(dl_dso_sort_algo) = algorithm == 1 ? dso_sort_algorithm_original ++ : dso_sort_algorithm_dfs; ++} ++ ++void ++_dl_sort_maps (struct link_map **maps, unsigned int nmaps, ++ unsigned int skip, bool for_fini) ++{ ++ /* It can be tempting to use a static function pointer to store and call ++ the current selected sorting algorithm routine, but experimentation ++ shows that current processors still do not handle indirect branches ++ that efficiently, plus a static function pointer will involve ++ PTR_MANGLE/DEMANGLE, further impairing performance of small, common ++ input cases. A simple if-case with direct function calls appears to ++ be the fastest. */ ++ if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original)) ++ _dl_sort_maps_original (maps, nmaps, skip, for_fini); ++ else ++ _dl_sort_maps_dfs (maps, nmaps, skip, for_fini); ++} ++ ++#endif /* HAVE_TUNABLES. */ +diff --git a/elf/dl-support.c b/elf/dl-support.c +index d8c06ba7eb4c76ea..c5ee5d33aa7e1d65 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -166,6 +166,8 @@ size_t _dl_phnum; + uint64_t _dl_hwcap; + uint64_t _dl_hwcap2; + ++enum dso_sort_algorithm _dl_dso_sort_algo; ++ + /* The value of the FPU control word the kernel will preset in hardware. */ + fpu_control_t _dl_fpu_control = _FPU_DEFAULT; + +diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c +index 2c684c2db2a1f59b..4dc366eea445e974 100644 +--- a/elf/dl-sysdep.c ++++ b/elf/dl-sysdep.c +@@ -231,6 +231,9 @@ _dl_sysdep_start (void **start_argptr, + + __tunables_init (_environ); + ++ /* Initialize DSO sorting algorithm after tunables. */ ++ _dl_sort_maps_init (); ++ + #ifdef DL_SYSDEP_INIT + DL_SYSDEP_INIT; + #endif +diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list +index 8ddd4a23142a941b..46ffb2378416f90f 100644 +--- a/elf/dl-tunables.list ++++ b/elf/dl-tunables.list +@@ -156,4 +156,13 @@ glibc { + security_level: SXID_IGNORE + } + } ++ ++ rtld { ++ dynamic_sort { ++ type: INT_32 ++ minval: 1 ++ maxval: 2 ++ default: 1 ++ } ++ } + } +diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def +index 873ddf55d91155c6..5f7f18ef270bc12d 100644 +--- a/elf/dso-sort-tests-1.def ++++ b/elf/dso-sort-tests-1.def +@@ -62,5 +62,5 @@ output: b>a>{}b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c +-xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[l_name = (char *) ""; + *user_entry = main_map->l_entry; + ++ /* Set bit indicating this is the main program map. */ ++ main_map->l_main_map = 1; ++ + #ifdef HAVE_AUX_VECTOR + /* Adjust the on-stack auxiliary vector so that it looks like the + binary was executed directly. */ +diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp +index 9f66c528855fb21d..9bf572715f996ca6 100644 +--- a/elf/tst-rtld-list-tunables.exp ++++ b/elf/tst-rtld-list-tunables.exp +@@ -10,5 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+) ++glibc.rtld.dynamic_sort: 1 (min: 1, max: 2) + glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10) + glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+) +diff --git a/include/link.h b/include/link.h +index c46aced9f7b43ba0..4dcf01d8aea90bc2 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -181,6 +181,11 @@ struct link_map + unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ + unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */ + unsigned int l_reserved:2; /* Reserved for internal use. */ ++ unsigned int l_main_map:1; /* Nonzero for the map of the main program. */ ++ unsigned int l_visited:1; /* Used internally for map dependency ++ graph traversal. */ ++ unsigned int l_map_used:1; /* These two bits are used during traversal */ ++ unsigned int l_map_done:1; /* of maps in _dl_close_worker. */ + unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed + to by `l_phdr' is allocated. */ + unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 658547c6137bf177..10f4d75993f9940f 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -309,6 +309,17 @@ changed once allocated at process startup. The default allocation of + optional static TLS is 512 bytes and is allocated in every thread. + @end deftp + ++@deftp Tunable glibc.rtld.dynamic_sort ++Sets the algorithm to use for DSO sorting, valid values are @samp{1} and ++@samp{2}. For value of @samp{1}, an older O(n^3) algorithm is used, which is ++long time tested, but may have performance issues when dependencies between ++shared objects contain cycles due to circular dependencies. When set to the ++value of @samp{2}, a different algorithm is used, which implements a ++topological sort through depth-first search, and does not exhibit the ++performance issues of @samp{1}. ++ ++The default value of this tunable is @samp{1}. ++@end deftp + + @node Elision Tunables + @section Elision Tunables +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index fcbbf6974827cdf1..bcf1f199c5985c65 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -245,6 +245,13 @@ enum allowmask + }; + + ++/* DSO sort algorithm to use (check dl-sort-maps.c). */ ++enum dso_sort_algorithm ++ { ++ dso_sort_algorithm_original, ++ dso_sort_algorithm_dfs ++ }; ++ + struct audit_ifaces + { + void (*activity) (uintptr_t *, unsigned int); +@@ -672,6 +679,8 @@ struct rtld_global_ro + platforms. */ + EXTERN uint64_t _dl_hwcap2; + ++ EXTERN enum dso_sort_algorithm _dl_dso_sort_algo; ++ + #ifdef SHARED + /* We add a function table to _rtld_global which is then used to + call the function instead of going through the PLT. The result +@@ -1098,7 +1107,7 @@ extern void _dl_fini (void) attribute_hidden; + + /* Sort array MAPS according to dependencies of the contained objects. */ + extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps, +- char *used, bool for_fini) attribute_hidden; ++ unsigned int skip, bool for_fini) attribute_hidden; + + /* The dynamic linker calls this function before and having changing + any shared object mappings. The `r_state' member of `struct r_debug' +@@ -1225,6 +1234,9 @@ extern struct link_map * _dl_get_dl_main_map (void) + # endif + #endif + ++/* Initialize the DSO sort algorithm to use. */ ++extern void _dl_sort_maps_init (void) attribute_hidden; ++ + /* Initialization of libpthread for statically linked applications. + If libpthread is not linked in, this is an empty function. */ + void __pthread_initialize_minimal (void) weak_function; diff --git a/SOURCES/glibc-rh2032647-3.patch b/SOURCES/glibc-rh2032647-3.patch new file mode 100644 index 0000000..789e644 --- /dev/null +++ b/SOURCES/glibc-rh2032647-3.patch @@ -0,0 +1,25 @@ +commit d3bf2f5927d51258a51ac7fde04f4805f8ee294a +Author: Adhemerval Zanella +Date: Wed Nov 3 09:19:30 2021 -0300 + + elf: Do not run DSO sorting if tunables is not enabled + + Since the argorithm selection requires tunables. + + Checked on x86_64-linux-gnu with --enable-tunables=no. + +diff --git a/elf/Makefile b/elf/Makefile +index 8dd2b24328113536..02ee834fdaf00a26 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -483,8 +483,10 @@ include $(objpfx)$(1).generated-makefile + endef + + # Generate from each testcase description file ++ifeq (yes,$(have-tunables)) + $(eval $(call include_dsosort_tests,dso-sort-tests-1.def)) + $(eval $(call include_dsosort_tests,dso-sort-tests-2.def)) ++endif + + check-abi: $(objpfx)check-abi-ld.out + tests-special += $(objpfx)check-abi-ld.out diff --git a/SOURCES/glibc-rh2032647-4.patch b/SOURCES/glibc-rh2032647-4.patch new file mode 100644 index 0000000..1c415d4 --- /dev/null +++ b/SOURCES/glibc-rh2032647-4.patch @@ -0,0 +1,189 @@ +commit b4bbedb1e75737a80bcc3d53d6eef1fbe0b5f4d5 +Author: H.J. Lu +Date: Sat Nov 6 14:13:27 2021 -0700 + + dso-ordering-test.py: Put all sources in one directory [BZ #28550] + + Put all sources for DSO sorting tests in the dso-sort-tests-src directory + and compile test relocatable objects with + + $(objpfx)tst-dso-ordering1-dir/tst-dso-ordering1-a.os: $(objpfx)dso-sort-tests-src/tst-dso-ordering1-a.c + $(compile.c) $(OUTPUT_OPTION) + + to avoid random $< values from $(before-compile) when compiling test + relocatable objects with + + $(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c) + compile-command.c = $(compile.c) $(OUTPUT_OPTION) $(compile-mkdep-flags) + compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS) + + for 3 "make -j 28" parallel builds on a machine with 112 cores at the + same time. + + This partially fixes BZ #28550. + + Reviewed-by: Adhemerval Zanella + +diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py +index 944ee740527d60fd..bde0406be9da14fc 100644 +--- a/scripts/dso-ordering-test.py ++++ b/scripts/dso-ordering-test.py +@@ -526,9 +526,13 @@ def process_testcase(t): + base_test_name = t.test_name + test_subdir = base_test_name + "-dir" + testpfx = objpfx + test_subdir + "/" ++ test_srcdir = "dso-sort-tests-src/" ++ testpfx_src = objpfx + test_srcdir + + if not os.path.exists(testpfx): + os.mkdir(testpfx) ++ if not os.path.exists(testpfx_src): ++ os.mkdir(testpfx_src) + + def find_objs_not_depended_on(t): + objs_not_depended_on = [] +@@ -595,6 +599,11 @@ def process_testcase(t): + # Print out needed Makefile fragments for use in glibc/elf/Makefile. + module_names = "" + for o in test_descr.objs: ++ rule = ("$(objpfx)" + test_subdir + "/" + test_name ++ + "-" + o + ".os: $(objpfx)" + test_srcdir ++ + test_name + "-" + o + ".c\n" ++ "\t$(compile.c) $(OUTPUT_OPTION)\n") ++ makefile.write (rule) + module_names += " " + test_subdir + "/" + test_name + "-" + o + makefile.write("modules-names +=%s\n" % (module_names)) + +@@ -637,7 +646,7 @@ def process_testcase(t): + # object. This only needs to be done at most once for + # an object name. + if not dep in fake_created: +- f = open(testpfx + test_name + "-" + dep ++ f = open(testpfx_src + test_name + "-" + dep + + ".FAKE.c", "w") + f.write(" \n") + f.close() +@@ -648,6 +657,12 @@ def process_testcase(t): + % (test_name + "-" + dep + ".FAKE.so", + ("$(objpfx)" + test_subdir + "/" + + test_name + "-" + dep + ".so"))) ++ rule = ("$(objpfx)" + test_subdir + "/" ++ + test_name + "-" + dep + ".FAKE.os: " ++ "$(objpfx)" + test_srcdir ++ + test_name + "-" + dep + ".FAKE.c\n" ++ "\t$(compile.c) $(OUTPUT_OPTION)\n") ++ makefile.write (rule) + makefile.write \ + ("modules-names += %s\n" + % (test_subdir + "/" +@@ -687,6 +702,10 @@ def process_testcase(t): + + test_descr.soname_map['#'] + ".so") + ldflags += (" -Wl,-soname=" + soname) + makefile.write("LDFLAGS-%s = %s\n" % (test_name, ldflags)) ++ rule = ("$(objpfx)" + test_subdir + "/" + test_name + ".o: " ++ "$(objpfx)" + test_srcdir + test_name + ".c\n" ++ "\t$(compile.c) $(OUTPUT_OPTION)\n") ++ makefile.write (rule) + + not_depended_objs = find_objs_not_depended_on(test_descr) + if not_depended_objs: +@@ -745,7 +764,7 @@ def process_testcase(t): + " something_failed=true\n" + "else\n" + " diff -wu ${common_objpfx}elf/%s/%s%s.output \\\n" +- " ${common_objpfx}elf/%s/%s%s.exp\n" ++ " ${common_objpfx}elf/%s%s%s.exp\n" + " if [ $? -ne 0 ]; then\n" + " echo '%sFAIL: %s%s expected output comparison'\n" + " something_failed=true\n" +@@ -753,14 +772,14 @@ def process_testcase(t): + "fi\n" + % (("X" if xfail else ""), test_name, tunable_descr, + test_subdir, test_name, tunable_sfx, +- test_subdir, base_test_name, exp_tunable_sfx, ++ test_srcdir, base_test_name, exp_tunable_sfx, + ("X" if xfail else ""), test_name, tunable_descr)) + + # Generate C files according to dependency and calling relations from + # description string. + for obj in test_descr.objs: + src_name = test_name + "-" + obj + ".c" +- f = open(testpfx + src_name, "w") ++ f = open(testpfx_src + src_name, "w") + if obj in test_descr.callrefs: + called_objs = test_descr.callrefs[obj] + for callee in called_objs: +@@ -804,7 +823,7 @@ def process_testcase(t): + f.close() + + # Open C file for writing main program +- f = open(testpfx + test_name + ".c", "w") ++ f = open(testpfx_src + test_name + ".c", "w") + + # if there are some operations in main(), it means we need -ldl + f.write("#include \n") +@@ -885,7 +904,7 @@ def process_testcase(t): + for obj in test_descr.objs: + src_name = test_name + "-" + obj + ".c" + obj_name = test_name + "-" + obj + ".os" +- run_cmd([build_gcc, "-c", "-fPIC", testpfx + src_name, ++ run_cmd([build_gcc, "-c", "-fPIC", testpfx_src + src_name, + "-o", testpfx + obj_name]) + + obj_processed = {} +@@ -903,10 +922,12 @@ def process_testcase(t): + deps.append(dep + ".FAKE") + if not dep in fake_created: + base_name = testpfx + test_name + "-" + dep ++ src_base_name = (testpfx_src + test_name ++ + "-" + dep) + cmd = [build_gcc, "-Wl,--no-as-needed", + ("-Wl,-soname=" + base_name + ".so"), + "-shared", base_name + ".FAKE.c", +- "-o", base_name + ".FAKE.so"] ++ "-o", src_base_name + ".FAKE.so"] + run_cmd(cmd) + fake_created[dep] = True + dso_deps = map(lambda d: testpfx + test_name + "-" + d + ".so", +@@ -932,7 +953,7 @@ def process_testcase(t): + main_deps = map(lambda d: testpfx + test_name + "-" + d + ".so", + deps) + cmd = [build_gcc, "-Wl,--no-as-needed", "-o", testpfx + test_name, +- testpfx + test_name + ".c", "-L%s" % (os.getcwd()), ++ testpfx_src + test_name + ".c", "-L%s" % (os.getcwd()), + "-Wl,-rpath-link=%s" % (os.getcwd())] + if '#' in test_descr.soname_map: + soname = ("-Wl,-soname=" + testpfx + test_name + "-" +@@ -987,14 +1008,14 @@ def process_testcase(t): + sfx = "" + if r[0] != "": + sfx = "-" + r[0].replace("=","_") +- f = open(testpfx + t.test_name + sfx + ".exp", "w") ++ f = open(testpfx_src + t.test_name + sfx + ".exp", "w") + (output, xfail) = r[1] + f.write('%s' % output) + f.close() + + # Create header part of top-level testcase shell script, to wrap execution + # and output comparison together. +- t.sh = open(testpfx + t.test_name + ".sh", "w") ++ t.sh = open(testpfx_src + t.test_name + ".sh", "w") + t.sh.write("#!/bin/sh\n") + t.sh.write("# Test driver for %s, generated by " + "dso-ordering-test.py\n" % (t.test_name)) +@@ -1022,12 +1043,12 @@ def process_testcase(t): + sfx = "" + if r[0] != "": + sfx = "-" + r[0].replace("=","_") +- expected_output_files += " $(objpfx)%s/%s%s.exp" % (test_subdir, ++ expected_output_files += " $(objpfx)%s%s%s.exp" % (test_srcdir, + t.test_name, sfx) + makefile.write \ +- ("$(objpfx)%s.out: $(objpfx)%s/%s.sh%s " ++ ("$(objpfx)%s.out: $(objpfx)%s%s.sh%s " + "$(common-objpfx)support/test-run-command\n" +- % (t.test_name, test_subdir, t.test_name, ++ % (t.test_name, test_srcdir, t.test_name, + expected_output_files)) + makefile.write("\t$(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' " + "'$(run-program-env)' > $@; $(evaluate-test)\n") diff --git a/SOURCES/glibc-rh2032647-5.patch b/SOURCES/glibc-rh2032647-5.patch new file mode 100644 index 0000000..308d831 --- /dev/null +++ b/SOURCES/glibc-rh2032647-5.patch @@ -0,0 +1,45 @@ +commit 1f67d8286b5da9266a138198ef1f15c27cbb0010 +Author: H.J. Lu +Date: Mon Nov 15 16:28:39 2021 -0800 + + elf: Use a temporary file to generate Makefile fragments [BZ #28550] + + 1. Use a temporary file to generate Makefile fragments for DSO sorting + tests and use -include on them. + 2. Add Makefile fragments to postclean-generated so that a "make clean" + removes the autogenerated fragments and a subsequent "make" regenerates + them. + + This partially fixes BZ #28550. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/Makefile b/elf/Makefile +index 02ee834fdaf00a26..535ba4260fb98e64 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -471,6 +471,7 @@ tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \ + $(objpfx)tst-unused-dep-cmp.out + endif + ++ifndef avoid-generated + # DSO sorting tests: + # The dso-ordering-test.py script generates testcase source files in $(objpfx), + # creating a $(objpfx)-dir for each testcase, and creates a +@@ -478,9 +479,14 @@ endif + define include_dsosort_tests + $(objpfx)$(1).generated-makefile: $(1) + $(PYTHON) $(..)scripts/dso-ordering-test.py \ +- --description-file $$< --objpfx $(objpfx) --output-makefile $$@ +-include $(objpfx)$(1).generated-makefile ++ --description-file $$< --objpfx $(objpfx) --output-makefile $$@T ++ mv $$@T $$@ ++-include $(objpfx)$(1).generated-makefile + endef ++endif ++ ++postclean-generated += $(objpfx)/dso-sort-tests-2.generated-makefile \ ++ $(objpfx)/dso-sort-tests-2.generated-makefile + + # Generate from each testcase description file + ifeq (yes,$(have-tunables)) diff --git a/SOURCES/glibc-rh2032647-6.patch b/SOURCES/glibc-rh2032647-6.patch new file mode 100644 index 0000000..6dcaccd --- /dev/null +++ b/SOURCES/glibc-rh2032647-6.patch @@ -0,0 +1,49 @@ +commit 0884724a95b60452ad483dbe086d237d02ba624d +Author: Florian Weimer +Date: Tue Dec 14 12:37:44 2021 +0100 + + elf: Use new dependency sorting algorithm by default + + The default has to change eventually, and there are no known failures + that require a delay. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list +index 46ffb2378416f90f..ffcd7f18d4fafb91 100644 +--- a/elf/dl-tunables.list ++++ b/elf/dl-tunables.list +@@ -162,7 +162,7 @@ glibc { + type: INT_32 + minval: 1 + maxval: 2 +- default: 1 ++ default: 2 + } + } + } +diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp +index 9bf572715f996ca6..44e4834cfb431633 100644 +--- a/elf/tst-rtld-list-tunables.exp ++++ b/elf/tst-rtld-list-tunables.exp +@@ -10,6 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+) + glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+) +-glibc.rtld.dynamic_sort: 1 (min: 1, max: 2) ++glibc.rtld.dynamic_sort: 2 (min: 1, max: 2) + glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10) + glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+) +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 10f4d75993f9940f..7c3b28d029410a6f 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -318,7 +318,7 @@ value of @samp{2}, a different algorithm is used, which implements a + topological sort through depth-first search, and does not exhibit the + performance issues of @samp{1}. + +-The default value of this tunable is @samp{1}. ++The default value of this tunable is @samp{2}. + @end deftp + + @node Elision Tunables diff --git a/SOURCES/glibc-rh2040657-1.patch b/SOURCES/glibc-rh2040657-1.patch new file mode 100644 index 0000000..4a25277 --- /dev/null +++ b/SOURCES/glibc-rh2040657-1.patch @@ -0,0 +1,547 @@ +commit 28713c06129f8f64f88c423266e6ff2880216509 +Author: H.J. Lu +Date: Mon Dec 13 09:43:52 2021 -0800 + + elf: Sort tests and modules-names + + Sort tests and modules-names to reduce future conflicts. + +Conflicts: + elf/Makefile + (Usual backport differences. Recreated tests and module-names + from scratch. Note that the upstream sort order is difficult + to fathom.) + +diff --git a/elf/Makefile b/elf/Makefile +index 535ba4260fb98e64..33df5b4714176adc 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -193,40 +193,134 @@ static-dlopen-environment = \ + tst-tls9-static-ENV = $(static-dlopen-environment) + tst-single_threaded-static-dlopen-ENV = $(static-dlopen-environment) + +-tests += restest1 preloadtest loadfail multiload origtest resolvfail \ +- constload1 order noload filter \ +- reldep reldep2 reldep3 reldep4 nodelete nodelete2 \ +- nodlopen nodlopen2 lateglobal initfirst global \ +- restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ +- tst-tls4 tst-tls5 \ +- tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \ +- tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \ +- tst-align tst-align2 \ +- tst-dlmodcount tst-dlopenrpath tst-deep1 \ +- tst-dlmopen1 tst-dlmopen3 \ +- unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \ +- tst-audit1 tst-audit2 tst-audit8 tst-audit9 \ +- tst-addr1 tst-thrlock \ +- tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \ +- tst-nodelete tst-dlopen-nodelete-reloc) \ +- tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \ +- tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \ +- tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ +- tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ +- tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ +- tst-unwind-ctor tst-unwind-main tst-audit13 \ +- tst-sonamemove-link tst-sonamemove-dlopen tst-dlopen-tlsmodid \ +- tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail \ +- tst-dlopenfail-2 \ +- tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen \ +- tst-audit14 tst-audit15 tst-audit16 tst-audit17 \ +- tst-single_threaded tst-single_threaded-pthread \ +- tst-tls-ie tst-tls-ie-dlmopen argv0test \ +- tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \ +- tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \ +- tst-dl-is_dso tst-ro-dynamic \ +- tst-rtld-run-static \ ++tests += \ ++ argv0test \ ++ constload1 \ ++ dblload \ ++ dblunload \ ++ filter \ ++ global \ ++ initfirst \ ++ lateglobal \ ++ loadfail \ ++ multiload \ ++ next \ ++ nodelete \ ++ nodelete2 \ ++ nodlopen \ ++ nodlopen2 \ ++ noload \ ++ order \ ++ order2 \ ++ origtest \ ++ preloadtest \ ++ reldep \ ++ reldep2 \ ++ reldep3 \ ++ reldep4 \ ++ reldep5 \ ++ reldep6 \ ++ reldep7 \ ++ reldep8 \ ++ resolvfail \ ++ restest1 \ ++ restest2 \ ++ tst-absolute-sym \ ++ tst-absolute-zero \ ++ tst-addr1 \ ++ tst-align \ ++ tst-align2 \ ++ tst-audit1 \ ++ tst-audit2 \ ++ tst-audit8 \ ++ tst-audit9 \ ++ tst-audit11 \ ++ tst-audit12 \ ++ tst-audit13 \ ++ tst-audit14 \ ++ tst-audit15 \ ++ tst-audit16 \ ++ tst-audit17 \ ++ tst-auditmany \ ++ tst-auxobj \ ++ tst-auxobj-dlopen \ ++ tst-big-note \ ++ tst-debug1 \ ++ tst-deep1 \ ++ tst-dl-is_dso \ ++ tst-dlmodcount \ ++ tst-dlmopen1 \ ++ tst-dlmopen3 \ ++ tst-dlmopen-dlerror \ ++ tst-dlmopen-gethostbyname \ ++ tst-dlopenfail \ ++ tst-dlopenfail-2 \ ++ tst-dlopenrpath \ ++ tst-dlopen-self \ ++ tst-dlopen-tlsmodid \ ++ tst-dlsym-error \ ++ tst-filterobj \ ++ tst-filterobj-dlopen \ ++ tst-glibc-hwcaps \ ++ tst-glibc-hwcaps-mask \ ++ tst-glibc-hwcaps-prepend \ ++ tst-global1 \ ++ tst-initfinilazyfail \ ++ tst-initorder \ ++ tst-initorder2 \ ++ tst-latepthread \ ++ tst-main1 \ ++ tst-nodelete2 \ ++ tst-nodelete-dlclose \ ++ tst-nodelete-opened \ ++ tst-noload \ ++ tst-null-argv \ ++ tst-relsort1 \ ++ tst-ro-dynamic \ ++ tst-rtld-run-static \ ++ tst-single_threaded \ ++ tst-single_threaded-pthread \ ++ tst-sonamemove-dlopen \ ++ tst-sonamemove-link \ ++ tst-thrlock \ ++ tst-tls10 \ ++ tst-tls11 \ ++ tst-tls12 \ ++ tst-tls13 \ ++ tst-tls14 \ ++ tst-tls15 \ ++ tst-tls16 \ ++ tst-tls17 \ ++ tst-tls18 \ ++ tst-tls19 \ ++ tst-tls20 \ ++ tst-tls21 \ ++ tst-tls4 \ ++ tst-tls5 \ ++ tst-tlsalign \ ++ tst-tlsalign-extern \ ++ tst-tls-dlinfo \ ++ tst-tls-ie \ ++ tst-tls-ie-dlmopen \ ++ tst-tls-manydynamic \ ++ tst-unique1 \ ++ tst-unique2 \ ++ tst-unwind-ctor \ ++ tst-unwind-main \ ++ unload3 \ ++ unload4 \ ++ unload5 \ ++ unload6 \ ++ unload7 \ ++ unload8 \ + # reldep9 ++tests-cxx = \ ++ tst-dlopen-nodelete-reloc \ ++ tst-nodelete \ ++ tst-unique3 \ ++ tst-unique4 \ ++ ++tests += $(if $(CXX),$(tests-cxx)) + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ + tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \ +@@ -264,101 +358,265 @@ tst-tls-many-dynamic-modules-dep-bad = \ + extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \ + tst-tlsalign-vars.o + test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars +-modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ +- testobj1_1 failobj constload2 constload3 unloadmod \ +- dep1 dep2 dep3 dep4 vismod1 vismod2 vismod3 \ +- nodelmod1 nodelmod2 nodelmod3 nodelmod4 \ +- nodel2mod1 nodel2mod2 nodel2mod3 \ +- nodlopenmod nodlopenmod2 filtmod1 filtmod2 \ +- reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \ +- reldep4mod1 reldep4mod2 reldep4mod3 reldep4mod4 \ +- neededobj1 neededobj2 neededobj3 neededobj4 \ +- neededobj5 neededobj6 firstobj globalmod1 \ +- unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \ +- dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \ +- reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \ +- reldep7mod1 reldep7mod2 \ +- tst-tlsmod1 tst-tlsmod2 tst-tlsmod3 tst-tlsmod4 \ +- tst-tlsmod5 tst-tlsmod6 tst-tlsmod7 tst-tlsmod8 \ +- tst-tlsmod9 tst-tlsmod10 tst-tlsmod11 tst-tlsmod12 \ +- tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \ +- tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \ +- $(tlsmod17a-modules) tst-tlsmod17b $(tlsmod18a-modules) \ +- tst-tls19mod1 tst-tls19mod2 tst-tls19mod3 \ +- circlemod1 circlemod1a circlemod2 circlemod2a \ +- circlemod3 circlemod3a \ +- reldep8mod1 reldep8mod2 reldep8mod3 \ +- reldep9mod1 reldep9mod2 reldep9mod3 \ +- tst-alignmod tst-alignmod2 \ +- $(modules-execstack-$(have-z-execstack)) \ +- tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \ +- tst-dlmopen1mod tst-auditmod1 \ +- unload3mod1 unload3mod2 unload3mod3 unload3mod4 \ +- unload4mod1 unload4mod2 unload4mod3 unload4mod4 \ +- unload6mod1 unload6mod2 unload6mod3 \ +- unload7mod1 unload7mod2 \ +- unload8mod1 unload8mod1x unload8mod2 unload8mod3 \ +- order2mod1 order2mod2 order2mod3 order2mod4 \ +- tst-unique1mod1 tst-unique1mod2 \ +- tst-unique2mod1 tst-unique2mod2 \ +- tst-auditmod9a tst-auditmod9b \ +- $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ +- tst-nodelete-uniquemod tst-nodelete-rtldmod \ +- tst-nodelete-zmod \ +- tst-dlopen-nodelete-reloc-mod1 \ +- tst-dlopen-nodelete-reloc-mod2 \ +- tst-dlopen-nodelete-reloc-mod3 \ +- tst-dlopen-nodelete-reloc-mod4 \ +- tst-dlopen-nodelete-reloc-mod5 \ +- tst-dlopen-nodelete-reloc-mod6 \ +- tst-dlopen-nodelete-reloc-mod7 \ +- tst-dlopen-nodelete-reloc-mod8 \ +- tst-dlopen-nodelete-reloc-mod9 \ +- tst-dlopen-nodelete-reloc-mod10 \ +- tst-dlopen-nodelete-reloc-mod11 \ +- tst-dlopen-nodelete-reloc-mod12 \ +- tst-dlopen-nodelete-reloc-mod13 \ +- tst-dlopen-nodelete-reloc-mod14 \ +- tst-dlopen-nodelete-reloc-mod15 \ +- tst-dlopen-nodelete-reloc-mod16 \ +- tst-dlopen-nodelete-reloc-mod17) \ +- tst-initordera1 tst-initorderb1 \ +- tst-initordera2 tst-initorderb2 \ +- tst-initordera3 tst-initordera4 \ +- tst-initorder2a tst-initorder2b tst-initorder2c \ +- tst-initorder2d \ +- tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \ +- tst-array5dep tst-null-argv-lib \ +- tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \ +- tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \ +- tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \ +- tst-latepthreadmod $(tst-tls-many-dynamic-modules) \ +- $(tst-tls-many-dynamic-modules-dep) \ +- $(tst-tls-many-dynamic-modules-dep-bad) \ +- tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \ +- tst-main1mod tst-absolute-sym-lib \ +- tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib \ +- tst-audit13mod1 tst-sonamemove-linkmod1 \ +- tst-sonamemove-runmod1 tst-sonamemove-runmod2 \ +- tst-auditmanymod1 tst-auditmanymod2 tst-auditmanymod3 \ +- tst-auditmanymod4 tst-auditmanymod5 tst-auditmanymod6 \ +- tst-auditmanymod7 tst-auditmanymod8 tst-auditmanymod9 \ +- tst-initlazyfailmod tst-finilazyfailmod \ +- tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \ +- tst-dlopenfailmod3 tst-dlopenfailnodelmod tst-ldconfig-ld-mod \ +- tst-filterobj-flt tst-filterobj-aux tst-filterobj-filtee \ +- tst-auditlogmod-1 tst-auditlogmod-2 tst-auditlogmod-3 \ +- tst-single_threaded-mod1 tst-single_threaded-mod2 \ +- tst-single_threaded-mod3 tst-single_threaded-mod4 \ +- tst-tls-ie-mod0 tst-tls-ie-mod1 tst-tls-ie-mod2 \ +- tst-tls-ie-mod3 tst-tls-ie-mod4 tst-tls-ie-mod5 \ +- tst-tls-ie-mod6 libmarkermod1-1 libmarkermod1-2 libmarkermod1-3 \ +- libmarkermod2-1 libmarkermod2-2 \ +- libmarkermod3-1 libmarkermod3-2 libmarkermod3-3 \ +- libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \ +- tst-tls20mod-bad tst-tls21mod tst-dlmopen-dlerror-mod \ +- tst-auxvalmod \ +- tst-dlmopen-gethostbyname-mod tst-ro-dynamic-mod \ ++modules-names = \ ++ circlemod1 \ ++ circlemod1a \ ++ circlemod2 \ ++ circlemod2a \ ++ circlemod3 \ ++ circlemod3a \ ++ constload2 \ ++ constload3 \ ++ dblloadmod1 \ ++ dblloadmod2 \ ++ dblloadmod3 \ ++ dep1 \ ++ dep2 \ ++ dep3 \ ++ dep4 \ ++ failobj \ ++ filtmod1 \ ++ filtmod2 \ ++ firstobj \ ++ globalmod1 \ ++ libmarkermod1-1 \ ++ libmarkermod1-2 \ ++ libmarkermod1-3 \ ++ libmarkermod2-1 \ ++ libmarkermod2-2 \ ++ libmarkermod3-1 \ ++ libmarkermod3-2 \ ++ libmarkermod3-3 \ ++ libmarkermod4-1 \ ++ libmarkermod4-2 \ ++ libmarkermod4-3 \ ++ libmarkermod4-4 \ ++ ltglobmod1 \ ++ ltglobmod2 \ ++ neededobj1 \ ++ neededobj2 \ ++ neededobj3 \ ++ neededobj4 \ ++ neededobj5 \ ++ neededobj6 \ ++ nextmod1 \ ++ nextmod2 \ ++ nodel2mod1 \ ++ nodel2mod2 \ ++ nodel2mod3 \ ++ nodelmod1 \ ++ nodelmod2 \ ++ nodelmod3 \ ++ nodelmod4 \ ++ nodlopenmod \ ++ nodlopenmod2 \ ++ order2mod1 \ ++ order2mod2 \ ++ order2mod3 \ ++ order2mod4 \ ++ pathoptobj \ ++ reldep4mod1 \ ++ reldep4mod2 \ ++ reldep4mod3 \ ++ reldep4mod4 \ ++ reldep6mod0 \ ++ reldep6mod1 \ ++ reldep6mod2 \ ++ reldep6mod3 \ ++ reldep6mod4 \ ++ reldep7mod1 \ ++ reldep7mod2 \ ++ reldep8mod1 \ ++ reldep8mod2 \ ++ reldep8mod3 \ ++ reldep9mod1 \ ++ reldep9mod2 \ ++ reldep9mod3 \ ++ reldepmod1 \ ++ reldepmod2 \ ++ reldepmod3 \ ++ reldepmod4 \ ++ reldepmod5 \ ++ reldepmod6 \ ++ testobj1 \ ++ testobj1_1 \ ++ testobj2 \ ++ testobj3 \ ++ testobj4 \ ++ testobj5 \ ++ testobj6 \ ++ tst-absolute-sym-lib \ ++ tst-absolute-zero-lib \ ++ tst-alignmod \ ++ tst-alignmod2 \ ++ tst-array2dep \ ++ tst-array5dep \ ++ tst-audit11mod1 \ ++ tst-audit11mod2 \ ++ tst-audit12mod1 \ ++ tst-audit12mod2 \ ++ tst-audit12mod3 \ ++ tst-audit13mod1 \ ++ tst-auditlogmod-1 \ ++ tst-auditlogmod-2 \ ++ tst-auditlogmod-3 \ ++ tst-auditmanymod1 \ ++ tst-auditmanymod2 \ ++ tst-auditmanymod3 \ ++ tst-auditmanymod4 \ ++ tst-auditmanymod5 \ ++ tst-auditmanymod6 \ ++ tst-auditmanymod7 \ ++ tst-auditmanymod8 \ ++ tst-auditmanymod9 \ ++ tst-auditmod1 \ ++ tst-auditmod9a \ ++ tst-auditmod9b \ ++ tst-auditmod11 \ ++ tst-auditmod12 \ ++ tst-auxvalmod \ ++ tst-big-note-lib \ ++ tst-deep1mod1 \ ++ tst-deep1mod2 \ ++ tst-deep1mod3 \ ++ tst-dlmopen1mod \ ++ tst-dlmopen-dlerror-mod \ ++ tst-dlmopen-gethostbyname-mod \ ++ tst-dlopenfaillinkmod \ ++ tst-dlopenfailmod1 \ ++ tst-dlopenfailmod2 \ ++ tst-dlopenfailmod3 \ ++ tst-dlopenfailnodelmod \ ++ tst-dlopenrpathmod \ ++ tst-filterobj-aux \ ++ tst-filterobj-filtee \ ++ tst-filterobj-flt \ ++ tst-finilazyfailmod \ ++ tst-initlazyfailmod \ ++ tst-initorder2a \ ++ tst-initorder2b \ ++ tst-initorder2c \ ++ tst-initorder2d \ ++ tst-initordera1 \ ++ tst-initordera2 \ ++ tst-initordera3 \ ++ tst-initordera4 \ ++ tst-initorderb1 \ ++ tst-initorderb2 \ ++ tst-latepthreadmod \ ++ tst-ldconfig-ld-mod \ ++ tst-main1mod \ ++ tst-nodelete2mod \ ++ tst-nodelete-dlclose-dso \ ++ tst-nodelete-dlclose-plugin \ ++ tst-nodelete-opened-lib \ ++ tst-null-argv-lib \ ++ tst-relsort1mod1 \ ++ tst-relsort1mod2 \ ++ tst-ro-dynamic-mod \ ++ tst-single_threaded-mod1 \ ++ tst-single_threaded-mod2 \ ++ tst-single_threaded-mod3 \ ++ tst-single_threaded-mod4 \ ++ tst-sonamemove-linkmod1 \ ++ tst-sonamemove-runmod1 \ ++ tst-sonamemove-runmod2 \ ++ tst-tls19mod1 \ ++ tst-tls19mod2 \ ++ tst-tls19mod3 \ ++ tst-tls20mod-bad \ ++ tst-tls21mod \ ++ tst-tlsalign-lib \ ++ tst-tls-ie-mod0 \ ++ tst-tls-ie-mod1 \ ++ tst-tls-ie-mod2 \ ++ tst-tls-ie-mod3 \ ++ tst-tls-ie-mod4 \ ++ tst-tls-ie-mod5 \ ++ tst-tls-ie-mod6 \ ++ tst-tlsmod1 \ ++ tst-tlsmod10 \ ++ tst-tlsmod11 \ ++ tst-tlsmod12 \ ++ tst-tlsmod13 \ ++ tst-tlsmod13a \ ++ tst-tlsmod14a \ ++ tst-tlsmod14b \ ++ tst-tlsmod15a \ ++ tst-tlsmod15b \ ++ tst-tlsmod16a \ ++ tst-tlsmod16b \ ++ tst-tlsmod17b \ ++ tst-tlsmod2 \ ++ tst-tlsmod3 \ ++ tst-tlsmod4 \ ++ tst-tlsmod5 \ ++ tst-tlsmod6 \ ++ tst-tlsmod7 \ ++ tst-tlsmod8 \ ++ tst-tlsmod9 \ ++ tst-unique1mod1 \ ++ tst-unique1mod2 \ ++ tst-unique2mod1 \ ++ tst-unique2mod2 \ ++ tst-unwind-ctor-lib \ ++ unload2dep \ ++ unload2mod \ ++ unload3mod1 \ ++ unload3mod2 \ ++ unload3mod3 \ ++ unload3mod4 \ ++ unload4mod1 \ ++ unload4mod2 \ ++ unload4mod3 \ ++ unload4mod4 \ ++ unload6mod1 \ ++ unload6mod2 \ ++ unload6mod3 \ ++ unload7mod1 \ ++ unload7mod2 \ ++ unload8mod1 \ ++ unload8mod1x \ ++ unload8mod2 \ ++ unload8mod3 \ ++ unloadmod \ ++ vismod1 \ ++ vismod2 \ ++ vismod3 \ ++ ++modules-names-cxx = \ ++ tst-dlopen-nodelete-reloc-mod1 \ ++ tst-dlopen-nodelete-reloc-mod10 \ ++ tst-dlopen-nodelete-reloc-mod11 \ ++ tst-dlopen-nodelete-reloc-mod12 \ ++ tst-dlopen-nodelete-reloc-mod13 \ ++ tst-dlopen-nodelete-reloc-mod14 \ ++ tst-dlopen-nodelete-reloc-mod15 \ ++ tst-dlopen-nodelete-reloc-mod16 \ ++ tst-dlopen-nodelete-reloc-mod17 \ ++ tst-dlopen-nodelete-reloc-mod2 \ ++ tst-dlopen-nodelete-reloc-mod3 \ ++ tst-dlopen-nodelete-reloc-mod4 \ ++ tst-dlopen-nodelete-reloc-mod5 \ ++ tst-dlopen-nodelete-reloc-mod6 \ ++ tst-dlopen-nodelete-reloc-mod7 \ ++ tst-dlopen-nodelete-reloc-mod8 \ ++ tst-dlopen-nodelete-reloc-mod9 \ ++ tst-nodelete-rtldmod \ ++ tst-nodelete-uniquemod \ ++ tst-nodelete-zmod \ ++ tst-unique3lib \ ++ tst-unique3lib2 \ ++ tst-unique4lib \ ++ ++modules-names += \ ++ $(if $(CXX),$(modules-names-cxx)) \ ++ $(modules-execstack-$(have-z-execstack)) \ ++ $(tst-tls-many-dynamic-modules) \ ++ $(tst-tls-many-dynamic-modules-dep) \ ++ $(tst-tls-many-dynamic-modules-dep-bad) \ ++ $(tlsmod17a-modules) \ ++ $(tlsmod18a-modules) \ + + # Most modules build with _ISOMAC defined, but those filtered out + # depend on internal headers. diff --git a/SOURCES/glibc-rh2040657-10.patch b/SOURCES/glibc-rh2040657-10.patch new file mode 100644 index 0000000..cff581f --- /dev/null +++ b/SOURCES/glibc-rh2040657-10.patch @@ -0,0 +1,73 @@ +commit 990c953bce06d77360d2e933faa9a008e2c55405 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + x86: Add x86-64-vN check to early startup + + This ISA level covers the glibc build itself. + cannot be used because this check (by design) happens before + DL_PLATFORM_INIT and the x86 CPU flags initialization. + + Reviewed-by: H.J. Lu + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 5ee06f94735e5189..36ca1a7126047b86 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -7,6 +7,7 @@ sysdep_routines += get-cpuid-feature-leaf + sysdep-dl-routines += dl-get-cpu-features + sysdep_headers += sys/platform/x86.h bits/platform/x86.h + ++CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags) + CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector) + + tests += tst-get-cpu-features tst-get-cpu-features-static \ +diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c +index 839803c746f408ed..6ccde4404b13a725 100644 +--- a/sysdeps/x86/dl-get-cpu-features.c ++++ b/sysdeps/x86/dl-get-cpu-features.c +@@ -20,6 +20,7 @@ + + #ifdef SHARED + # include ++# include + + /* NB: Normally, DL_PLATFORM_INIT calls init_cpu_features to initialize + CPU features in dynamic executable. But when loading ld.so inside of +@@ -36,7 +37,35 @@ _dl_x86_init_cpu_features (void) + { + struct cpu_features *cpu_features = __get_cpu_features (); + if (cpu_features->basic.kind == arch_kind_unknown) +- init_cpu_features (cpu_features); ++ { ++ init_cpu_features (cpu_features); ++ ++# if IS_IN (rtld) ++ /* See isa-level.c. */ ++# if defined GCCMACRO__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \ ++ && defined HAVE_X86_LAHF_SAHF && defined GCCMACRO__POPCNT__ \ ++ && defined GCCMACRO__SSE3__ && defined GCCMACRO__SSSE3__ \ ++ && defined GCCMACRO__SSE4_1__ && defined GCCMACRO__SSE4_2__ ++ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V2)) ++ _dl_fatal_printf ("\ ++Fatal glibc error: CPU does not support x86-64-v%d\n", 2); ++# if defined GCCMACRO__AVX__ && defined GCCMACRO__AVX2__ \ ++ && defined GCCMACRO__F16C__ && defined GCCMACRO__FMA__ \ ++ && defined GCCMACRO__LZCNT__ && defined HAVE_X86_MOVBE ++ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V3)) ++ _dl_fatal_printf ("\ ++Fatal glibc error: CPU does not support x86-64-v%d\n", 3); ++# if defined GCCMACRO__AVX512F__ && defined GCCMACRO__AVX512BW__ \ ++ && defined GCCMACRO__AVX512CD__ && defined GCCMACRO__AVX512DQ__ \ ++ && defined GCCMACRO__AVX512VL__ ++ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V4)) ++ _dl_fatal_printf ("\ ++Fatal glibc error: CPU does not support x86-64-v%d\n", 4); ++# endif /* ISA level 4 */ ++# endif /* ISA level 3 */ ++# endif /* ISA level 2 */ ++# endif /* IS_IN (rtld) */ ++ } + } + + __ifunc (__x86_cpu_features, __x86_cpu_features, NULL, void, diff --git a/SOURCES/glibc-rh2040657-11.patch b/SOURCES/glibc-rh2040657-11.patch new file mode 100644 index 0000000..1ca3409 --- /dev/null +++ b/SOURCES/glibc-rh2040657-11.patch @@ -0,0 +1,37 @@ +commit f01d482f0355a7029d0715ace0ccf3323e7e94bc +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + s390x: Use in early HWCAP check + + This is required so that the checks still work if $(early-cflags) + selects a different ISA level. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + +diff --git a/sysdeps/s390/s390-64/dl-hwcap-check.h b/sysdeps/s390/s390-64/dl-hwcap-check.h +index 87e18be6bd0c512b..27f7e245b1d1a9e9 100644 +--- a/sysdeps/s390/s390-64/dl-hwcap-check.h ++++ b/sysdeps/s390/s390-64/dl-hwcap-check.h +@@ -19,17 +19,18 @@ + #ifndef _DL_HWCAP_CHECK_H + #define _DL_HWCAP_CHECK_H + ++#include + #include + + static inline void + dl_hwcap_check (void) + { + #if defined __ARCH__ +-# if __ARCH__ >= 13 ++# if GCCMACRO__ARCH__ >= 13 + if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_EXT2)) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks VXRS_EXT2 support (z15 or later required)\n"); +-# elif __ARCH__ >= 12 ++# elif GCCMACRO__ARCH__ >= 12 + if (!(GLRO(dl_hwcap) & HWCAP_S390_VXE)) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks VXE support (z14 or later required)\n"); diff --git a/SOURCES/glibc-rh2040657-12.patch b/SOURCES/glibc-rh2040657-12.patch new file mode 100644 index 0000000..592c08c --- /dev/null +++ b/SOURCES/glibc-rh2040657-12.patch @@ -0,0 +1,158 @@ +commit c90363403b57b3b7919061851cb3e6d9c85e784a +Author: Florian Weimer +Date: Tue Jan 18 13:53:11 2022 +0100 + + elf: Move _dl_setup_hash to its own file + + And compile it with the early CFLAGS. _dl_setup_hash is called + very early for the ld.so link map, so it should be compiled + differently. + + Reviewed-by: Stefan Liebler + Tested-by: Stefan Liebler + +diff --git a/elf/Makefile b/elf/Makefile +index 778e393395fc5248..948296dc2437e9a1 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -69,6 +69,7 @@ dl-routines = \ + dl-reloc \ + dl-runtime \ + dl-scope \ ++ dl-setup_hash \ + dl-sort-maps \ + dl-thread_gscope_wait \ + dl-tls \ +@@ -154,6 +155,7 @@ CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines)) + + # Add the requested compiler flags to the early startup code. + CFLAGS-dl-printf.os += $(rtld-early-cflags) ++CFLAGS-dl-setup_hash.os += $(rtld-early-cflags) + CFLAGS-dl-sysdep.os += $(rtld-early-cflags) + CFLAGS-dl-tunables.os += $(rtld-early-cflags) + CFLAGS-dl-write.os += $(rtld-early-cflags) +diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c +index eea217eb2833164c..3391a990c8d288e5 100644 +--- a/elf/dl-lookup.c ++++ b/elf/dl-lookup.c +@@ -948,51 +948,6 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, + } + + +-/* Cache the location of MAP's hash table. */ +- +-void +-_dl_setup_hash (struct link_map *map) +-{ +- Elf_Symndx *hash; +- +- if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL)) +- { +- Elf32_Word *hash32 +- = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]); +- map->l_nbuckets = *hash32++; +- Elf32_Word symbias = *hash32++; +- Elf32_Word bitmask_nwords = *hash32++; +- /* Must be a power of two. */ +- assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0); +- map->l_gnu_bitmask_idxbits = bitmask_nwords - 1; +- map->l_gnu_shift = *hash32++; +- +- map->l_gnu_bitmask = (ElfW(Addr) *) hash32; +- hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords; +- +- map->l_gnu_buckets = hash32; +- hash32 += map->l_nbuckets; +- map->l_gnu_chain_zero = hash32 - symbias; +- +- /* Initialize MIPS xhash translation table. */ +- ELF_MACHINE_XHASH_SETUP (hash32, symbias, map); +- +- return; +- } +- +- if (!map->l_info[DT_HASH]) +- return; +- hash = (void *) D_PTR (map, l_info[DT_HASH]); +- +- map->l_nbuckets = *hash++; +- /* Skip nchain. */ +- hash++; +- map->l_buckets = hash; +- hash += map->l_nbuckets; +- map->l_chain = hash; +-} +- +- + static void + _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, + const ElfW(Sym) **ref, struct sym_val *value, +diff --git a/elf/dl-setup_hash.c b/elf/dl-setup_hash.c +new file mode 100644 +index 0000000000000000..6dd57c5c94e541c2 +--- /dev/null ++++ b/elf/dl-setup_hash.c +@@ -0,0 +1,63 @@ ++/* Cache the location of a link map hash table. ++ Copyright (C) 1995-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void ++_dl_setup_hash (struct link_map *map) ++{ ++ Elf_Symndx *hash; ++ ++ if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL)) ++ { ++ Elf32_Word *hash32 ++ = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]); ++ map->l_nbuckets = *hash32++; ++ Elf32_Word symbias = *hash32++; ++ Elf32_Word bitmask_nwords = *hash32++; ++ /* Must be a power of two. */ ++ assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0); ++ map->l_gnu_bitmask_idxbits = bitmask_nwords - 1; ++ map->l_gnu_shift = *hash32++; ++ ++ map->l_gnu_bitmask = (ElfW(Addr) *) hash32; ++ hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords; ++ ++ map->l_gnu_buckets = hash32; ++ hash32 += map->l_nbuckets; ++ map->l_gnu_chain_zero = hash32 - symbias; ++ ++ /* Initialize MIPS xhash translation table. */ ++ ELF_MACHINE_XHASH_SETUP (hash32, symbias, map); ++ ++ return; ++ } ++ ++ if (!map->l_info[DT_HASH]) ++ return; ++ hash = (void *) D_PTR (map, l_info[DT_HASH]); ++ ++ map->l_nbuckets = *hash++; ++ /* Skip nchain. */ ++ hash++; ++ map->l_buckets = hash; ++ hash += map->l_nbuckets; ++ map->l_chain = hash; ++} diff --git a/SOURCES/glibc-rh2040657-2.patch b/SOURCES/glibc-rh2040657-2.patch new file mode 100644 index 0000000..02b8953 --- /dev/null +++ b/SOURCES/glibc-rh2040657-2.patch @@ -0,0 +1,42 @@ +commit f4f70c2895e3d325188a42c10eb7bb4335be6773 +Author: H.J. Lu +Date: Tue Jan 4 06:58:34 2022 -0800 + + elf: Add a comment after trailing backslashes + +diff --git a/elf/Makefile b/elf/Makefile +index 0cfcf0a61a442c9f..5b9c36bc6f0a3ee5 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -319,6 +319,7 @@ tests-cxx = \ + tst-nodelete \ + tst-unique3 \ + tst-unique4 \ ++# tests-cxx + + tests += $(if $(CXX),$(tests-cxx)) + tests-internal += loadtest unload unload2 circleload1 \ +@@ -583,6 +584,7 @@ modules-names = \ + vismod1 \ + vismod2 \ + vismod3 \ ++# modules-names + + modules-names-cxx = \ + tst-dlopen-nodelete-reloc-mod1 \ +@@ -608,6 +610,7 @@ modules-names-cxx = \ + tst-unique3lib \ + tst-unique3lib2 \ + tst-unique4lib \ ++# modules-names-cxx + + modules-names += \ + $(if $(CXX),$(modules-names-cxx)) \ +@@ -617,6 +620,7 @@ modules-names += \ + $(tst-tls-many-dynamic-modules-dep-bad) \ + $(tlsmod17a-modules) \ + $(tlsmod18a-modules) \ ++# modules-names + + # Most modules build with _ISOMAC defined, but those filtered out + # depend on internal headers. diff --git a/SOURCES/glibc-rh2040657-3.patch b/SOURCES/glibc-rh2040657-3.patch new file mode 100644 index 0000000..5c63516 --- /dev/null +++ b/SOURCES/glibc-rh2040657-3.patch @@ -0,0 +1,171 @@ +commit 0835c0f0bad351117154b815f34f8af19ea7e325 +Author: Matt Whitlock +Date: Wed Jun 16 23:40:47 2021 -0400 + + x86: fix Autoconf caching of instruction support checks [BZ #27991] + + The Autoconf documentation for the AC_CACHE_CHECK macro states: + + The commands-to-set-it must have no side effects except for setting + the variable cache-id, see below. + + However, the tests for support of -msahf and -mmovbe were embedded in + the commands-to-set-it for lib_cv_include_x86_isa_level. This had the + consequence that libc_cv_have_x86_lahf_sahf and libc_cv_have_x86_movbe + were not defined whenever lib_cv_include_x86_isa_level was read from + cache. These variables' being undefined meant that their unquoted use + in later test expressions led to the 'test' built-in's misparsing its + arguments and emitting errors like "test: =: unexpected operator" or + "test: =: unary operator expected", depending on the particular shell. + + This commit refactors the tests for LAHF/SAHF and MOVBE instruction + support into their own AC_CACHE_CHECK macro invocations to obey the + rule that the commands-to-set-it must have no side effects other than + setting the variable named by cache-id. + + Signed-off-by: Matt Whitlock + Reviewed-by: Adhemerval Zanella + +diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure +index ead1295c38cf5f4e..62676bb686850938 100644 +--- a/sysdeps/x86/configure ++++ b/sysdeps/x86/configure +@@ -126,8 +126,6 @@ cat > conftest2.S <&5 + (eval $ac_try) 2>&5 +@@ -137,9 +135,22 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest c + count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l` + if test "$count" = 1; then + libc_cv_include_x86_isa_level=yes +- cat > conftest.c <&5 ++$as_echo "$libc_cv_include_x86_isa_level" >&6; } ++if test $libc_cv_include_x86_isa_level = yes; then ++ $as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LAHF/SAHF instruction support" >&5 ++$as_echo_n "checking for LAHF/SAHF instruction support... " >&6; } ++if ${libc_cv_have_x86_lahf_sahf+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ libc_cv_have_x86_lahf_sahf=no ++ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -147,7 +158,20 @@ EOF + test $ac_status = 0; }; } | grep -q "\-msahf"; then + libc_cv_have_x86_lahf_sahf=yes + fi +- if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c' ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_lahf_sahf" >&5 ++$as_echo "$libc_cv_have_x86_lahf_sahf" >&6; } ++ if test $libc_cv_have_x86_lahf_sahf = yes; then ++ $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h ++ ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MOVBE instruction support" >&5 ++$as_echo_n "checking for MOVBE instruction support... " >&6; } ++if ${libc_cv_have_x86_movbe+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ libc_cv_have_x86_movbe=no ++ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -155,23 +179,13 @@ EOF + test $ac_status = 0; }; } | grep -q "\-mmovbe"; then + libc_cv_have_x86_movbe=yes + fi +- fi +-fi +-rm -f conftest* +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_include_x86_isa_level" >&5 +-$as_echo "$libc_cv_include_x86_isa_level" >&6; } +-if test $libc_cv_include_x86_isa_level = yes; then +- $as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h +- + fi +-if test $libc_cv_have_x86_lahf_sahf = yes; then +- $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h +- +-fi +-if test $libc_cv_have_x86_movbe = yes; then +- $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_movbe" >&5 ++$as_echo "$libc_cv_have_x86_movbe" >&6; } ++ if test $libc_cv_have_x86_movbe = yes; then ++ $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h + ++ fi + fi + config_vars="$config_vars + enable-x86-isa-level = $libc_cv_include_x86_isa_level" +diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac +index bca97fdc2f1ac1a7..04a12ab68048cd66 100644 +--- a/sysdeps/x86/configure.ac ++++ b/sysdeps/x86/configure.ac +@@ -98,30 +98,32 @@ cat > conftest2.S < conftest.c < +Date: Fri Jan 14 16:09:20 2022 +0100 + + x86: HAVE_X86_LAHF_SAHF, HAVE_X86_MOVBE and -march=x86-64-vN (bug 28782) + + HAVE_X86_LAHF_SAHF is implied by x86-64-v2, and HAVE_X86_MOVBE by + x86-64-v3. + + The individual flag does not appear in -fverbose-asm flag output + even if the ISA level implies it. + + Reviewed-by: H.J. Lu + +diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure +index 62676bb686850938..7bdbfdc6dc2ad38f 100644 +--- a/sysdeps/x86/configure ++++ b/sysdeps/x86/configure +@@ -155,7 +155,7 @@ else + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; } | grep -q "\-msahf"; then ++ test $ac_status = 0; }; } | grep -qE '(-msahf\b|-march=x86-64-v)'; then + libc_cv_have_x86_lahf_sahf=yes + fi + fi +@@ -176,7 +176,7 @@ else + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; } | grep -q "\-mmovbe"; then ++ test $ac_status = 0; }; } | grep -qE '(-mmovbe\b|-march=x86-64-v([3-9]|[1-9][0-9]))'; then + libc_cv_have_x86_movbe=yes + fi + fi +diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac +index 04a12ab68048cd66..10d5c2e0e555fc79 100644 +--- a/sysdeps/x86/configure.ac ++++ b/sysdeps/x86/configure.ac +@@ -110,7 +110,7 @@ if test $libc_cv_include_x86_isa_level = yes; then + AC_CACHE_CHECK([for LAHF/SAHF instruction support], + libc_cv_have_x86_lahf_sahf, [dnl + libc_cv_have_x86_lahf_sahf=no +- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-msahf"; then ++ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -qE '(-msahf\b|-march=x86-64-v)'; then + libc_cv_have_x86_lahf_sahf=yes + fi]) + if test $libc_cv_have_x86_lahf_sahf = yes; then +@@ -119,7 +119,7 @@ if test $libc_cv_include_x86_isa_level = yes; then + AC_CACHE_CHECK([for MOVBE instruction support], + libc_cv_have_x86_movbe, [dnl + libc_cv_have_x86_movbe=no +- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-mmovbe"; then ++ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -qE '(-mmovbe\b|-march=x86-64-v(@<:@3-9@:>@|@<:@1-9@:>@@<:@0-9@:>@))'; then + libc_cv_have_x86_movbe=yes + fi]) + if test $libc_cv_have_x86_movbe = yes; then diff --git a/SOURCES/glibc-rh2040657-5.patch b/SOURCES/glibc-rh2040657-5.patch new file mode 100644 index 0000000..bf5343e --- /dev/null +++ b/SOURCES/glibc-rh2040657-5.patch @@ -0,0 +1,32 @@ +commit ef7c6d42fe163a5e49a478c43e655ce4633fa5ba +Author: Florian Weimer +Date: Fri Jan 14 16:09:20 2022 +0100 + + Generate gcc-macros.h + + The file can be used to check the effect of the default compiler + flags on code generation even in areas of the build that uses + non-default compiler flags. + + Reviewed-by: H.J. Lu + +diff --git a/Makeconfig b/Makeconfig +index 8bc5540292c7b6fa..99898a632a64be91 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -1202,6 +1202,15 @@ $(common-objpfx)dl-tunable-list.stmp: \ + touch $@ + endif + ++# Dump the GCC macros used by the default compiler flags to a header ++# file, so that they can be inspected when using different compiler ++# flags. Add the GCCMACRO prefix to make these macro names unique. ++$(common-objpfx)gcc-macros.h.in: $(common-objpfx)config.status ++ $(CC) $(CFLAGS) $(CPPFLAGS) -E -dM -x c -o $@ /dev/null ++$(common-objpfx)gcc-macros.h: $(common-objpfx)gcc-macros.h.in ++ sed 's/^#define /#define GCCMACRO/' < $< > $@ ++before-compile += $(common-objpfx)gcc-macros.h ++ + # Generate version maps, but wait until sysdep-subdirs is known + ifeq ($(sysd-sorted-done),t) + ifeq ($(build-shared),yes) diff --git a/SOURCES/glibc-rh2040657-6.patch b/SOURCES/glibc-rh2040657-6.patch new file mode 100644 index 0000000..15caf1d --- /dev/null +++ b/SOURCES/glibc-rh2040657-6.patch @@ -0,0 +1,549 @@ +commit 7de01e60c200c431d3469deb784da8fd4508fc15 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + elf/Makefile: Reflow and sort most variable assignments + + Reviewed-by: H.J. Lu + +Conflicts: + elf/Makefile + (Usual backporting differences. LLD support is missing + downstream.) + +diff --git a/elf/Makefile b/elf/Makefile +index 5b9c36bc6f0a3ee5..124905f96c88ab53 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -21,21 +21,62 @@ subdir := elf + + include ../Makeconfig + +-headers = elf.h bits/elfclass.h link.h bits/link.h +-routines = $(all-dl-routines) dl-support dl-iteratephdr \ +- dl-addr dl-addr-obj enbl-secure dl-profstub \ +- dl-origin dl-libc dl-sym dl-sysdep dl-error \ +- dl-reloc-static-pie libc_early_init rtld_static_init ++headers = \ ++ bits/elfclass.h \ ++ bits/link.h \ ++ elf.h \ ++ link.h \ ++ # headers ++ ++routines = \ ++ $(all-dl-routines) \ ++ dl-addr \ ++ dl-addr-obj \ ++ dl-error \ ++ dl-iteratephdr \ ++ dl-libc \ ++ dl-origin \ ++ dl-profstub \ ++ dl-reloc-static-pie \ ++ dl-support \ ++ dl-sym \ ++ dl-sysdep \ ++ enbl-secure \ ++ libc_early_init \ ++ rtld_static_init \ ++ # routines + + # The core dynamic linking functions are in libc for the static and + # profiled libraries. +-dl-routines = $(addprefix dl-,load lookup object reloc deps \ +- runtime init fini debug misc \ +- version profile tls origin scope \ +- execstack open close trampoline \ +- exception sort-maps lookup-direct \ +- call-libc-early-init write \ +- thread_gscope_wait tls_init_tp) ++dl-routines = \ ++ dl-call-libc-early-init \ ++ dl-close \ ++ dl-debug \ ++ dl-deps \ ++ dl-exception \ ++ dl-execstack \ ++ dl-fini \ ++ dl-init \ ++ dl-load \ ++ dl-lookup \ ++ dl-lookup-direct \ ++ dl-misc \ ++ dl-object \ ++ dl-open \ ++ dl-origin \ ++ dl-profile \ ++ dl-reloc \ ++ dl-runtime \ ++ dl-scope \ ++ dl-sort-maps \ ++ dl-thread_gscope_wait \ ++ dl-tls \ ++ dl-tls_init_tp \ ++ dl-trampoline \ ++ dl-version \ ++ dl-write \ ++ # dl-routines ++ + ifeq (yes,$(use-ldconfig)) + dl-routines += dl-cache + endif +@@ -58,16 +99,38 @@ endif + + all-dl-routines = $(dl-routines) $(sysdep-dl-routines) + # But they are absent from the shared libc, because that code is in ld.so. +-elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \ +- dl-sysdep dl-exception dl-reloc-static-pie \ +- thread_gscope_wait rtld_static_init ++elide-routines.os = \ ++ $(all-dl-routines) \ ++ dl-exception \ ++ dl-origin \ ++ dl-reloc-static-pie \ ++ dl-support \ ++ dl-sysdep \ ++ enbl-secure \ ++ rtld_static_init \ ++ thread_gscope_wait \ ++ # elide-routines.os + + # ld.so uses those routines, plus some special stuff for being the program + # interpreter and operating independent of libc. +-rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal \ +- dl-error-minimal dl-conflict dl-hwcaps dl-hwcaps_split dl-hwcaps-subdirs \ +- dl-usage dl-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu \ +- dl-mutex ++rtld-routines = \ ++ $(all-dl-routines) \ ++ dl-conflict \ ++ dl-diagnostics \ ++ dl-diagnostics-cpu \ ++ dl-diagnostics-kernel \ ++ dl-environ \ ++ dl-error-minimal \ ++ dl-hwcaps \ ++ dl-hwcaps-subdirs \ ++ dl-hwcaps_split \ ++ dl-minimal \ ++ dl-mutex \ ++ dl-sysdep \ ++ dl-usage \ ++ rtld \ ++ # rtld-routines ++ + all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines) + + CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables +@@ -102,8 +165,16 @@ ld-map = $(common-objpfx)ld.map + endif + + ifeq (yes,$(build-shared)) +-extra-objs = $(all-rtld-routines:%=%.os) sofini.os interp.os +-generated += librtld.os dl-allobjs.os ld.so ldd ++extra-objs = \ ++ $(all-rtld-routines:%=%.os) \ ++ sofini.os \ ++ interp.os \ ++ # extra-objs ++generated += \ ++ dl-allobjs.os \ ++ ld.so ldd \ ++ librtld.os \ ++ # generated + install-others = $(inst_rtlddir)/$(rtld-installed-name) $(inst_bindir)/ld.so + install-bin-script = ldd + endif +@@ -121,8 +192,15 @@ others-static += ldconfig + others += ldconfig + install-rootsbin += ldconfig + +-ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon static-stubs \ +- stringtable ++ldconfig-modules := \ ++ cache \ ++ chroot_canon \ ++ readlib \ ++ static-stubs \ ++ stringtable \ ++ xmalloc \ ++ xstrdup \ ++ # ldconfig-modules + extra-objs += $(ldconfig-modules:=.o) + others-extras = $(ldconfig-modules) + endif +@@ -156,23 +234,36 @@ $(inst_auditdir)/sotruss-lib.so: $(objpfx)sotruss-lib.so $(+force) + $(do-install-program) + endif + +-tests-static-normal := tst-array1-static tst-array5-static \ +- tst-dl-iter-static \ +- tst-tlsalign-static tst-tlsalign-extern-static \ +- tst-linkall-static tst-env-setuid tst-env-setuid-tunables \ +- tst-single_threaded-static tst-single_threaded-pthread-static \ +- tst-dst-static tst-getauxval-static +- +-tests-static-internal := tst-tls1-static tst-tls2-static \ +- tst-ptrguard1-static tst-stackguard1-static \ +- tst-tls1-static-non-pie ++tests-static-normal := \ ++ tst-array1-static \ ++ tst-array5-static \ ++ tst-dl-iter-static \ ++ tst-dst-static \ ++ tst-env-setuid \ ++ tst-env-setuid-tunables \ ++ tst-getauxval-static \ ++ tst-linkall-static \ ++ tst-single_threaded-pthread-static \ ++ tst-single_threaded-static \ ++ tst-tlsalign-extern-static \ ++ tst-tlsalign-static \ ++ # tests-static-normal ++ ++tests-static-internal := \ ++ tst-ptrguard1-static \ ++ tst-stackguard1-static \ ++ tst-tls1-static \ ++ tst-tls2-static \ ++ tst-tls1-static-non-pie \ ++ # tests-static-internal + + CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o + tst-tls1-static-non-pie-no-pie = yes + + tests-container := \ +- tst-ldconfig-bad-aux-cache \ +- tst-ldconfig-ld_so_conf-update ++ tst-ldconfig-bad-aux-cache \ ++ tst-ldconfig-ld_so_conf-update \ ++ # tests-container + + ifeq (no,$(build-hardcoded-path-in-tests)) + # This is an ld.so.cache test, and RPATH/RUNPATH in the executable +@@ -180,14 +271,32 @@ ifeq (no,$(build-hardcoded-path-in-tests)) + tests-container += tst-glibc-hwcaps-prepend-cache + endif + +-tests := tst-tls9 tst-leaks1 \ +- tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \ +- tst-auxv tst-stringtable +-tests-internal := tst-tls1 tst-tls2 $(tests-static-internal) ++tests := \ ++ tst-array1 \ ++ tst-array2 \ ++ tst-array3 \ ++ tst-array4 \ ++ tst-array5 \ ++ tst-auxv \ ++ tst-leaks1 \ ++ tst-stringtable \ ++ tst-tls9 \ ++ # tests ++ ++tests-internal := \ ++ $(tests-static-internal) \ ++ tst-tls1 \ ++ tst-tls2 \ ++ # tests-internal ++ + tests-static := $(tests-static-normal) $(tests-static-internal) + + ifeq (yes,$(build-shared)) +-tests-static += tst-tls9-static tst-single_threaded-static-dlopen ++tests-static += \ ++ tst-single_threaded-static-dlopen \ ++ tst-tls9-static \ ++ # tests-static ++ + static-dlopen-environment = \ + LD_LIBRARY_PATH=$(ld-library-path):$(common-objpfx)dlfcn + tst-tls9-static-ENV = $(static-dlopen-environment) +@@ -313,33 +422,69 @@ tests += \ + unload6 \ + unload7 \ + unload8 \ +-# reldep9 ++ # tests + tests-cxx = \ + tst-dlopen-nodelete-reloc \ + tst-nodelete \ + tst-unique3 \ + tst-unique4 \ +-# tests-cxx ++ # tests-cxx + + tests += $(if $(CXX),$(tests-cxx)) +-tests-internal += loadtest unload unload2 circleload1 \ +- neededtest neededtest2 neededtest3 neededtest4 \ +- tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \ +- tst-ptrguard1 tst-stackguard1 \ +- tst-create_format1 tst-tls-surplus tst-dl-hwcaps_split +-tests-container += tst-pldd tst-dlopen-tlsmodid-container \ +- tst-dlopen-self-container tst-preload-pthread-libc +-test-srcs = tst-pathopt ++ ++tests-internal += \ ++ circleload1 \ ++ loadtest \ ++ neededtest \ ++ neededtest2 \ ++ neededtest3 \ ++ neededtest4 \ ++ tst-create_format1 \ ++ tst-dl-hwcaps_split \ ++ tst-dlmopen2 \ ++ tst-ptrguard1 \ ++ tst-stackguard1 \ ++ tst-tls-surplus \ ++ tst-tls3 \ ++ tst-tls6 \ ++ tst-tls7 \ ++ tst-tls8 \ ++ unload \ ++ unload2 \ ++ # tests-internal ++ ++tests-container += \ ++ tst-dlopen-self-container \ ++ tst-dlopen-tlsmodid-container \ ++ tst-pldd \ ++ tst-preload-pthread-libc \ ++ # tests-container ++ ++test-srcs = \ ++ tst-pathopt \ ++ # tests-srcs ++ ++ifeq (yes,$(have-fpie)) ++tests-pie += tst-align3 ++endif + selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) ++ + ifneq ($(selinux-enabled),1) +-tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog ++tests-execstack-yes = \ ++ tst-execstack \ ++ tst-execstack-needed \ ++ tst-execstack-prog \ ++ # tests-execstack-yes + endif + endif + tests += $(tests-execstack-$(have-z-execstack)) + ifeq ($(run-built-tests),yes) +-tests-special += $(objpfx)tst-leaks1-mem.out \ +- $(objpfx)noload-mem.out \ +- $(objpfx)tst-ldconfig-X.out $(objpfx)tst-rtld-help.out ++tests-special += \ ++ $(objpfx)noload-mem.out \ ++ $(objpfx)tst-ldconfig-X.out \ ++ $(objpfx)tst-leaks1-mem.out \ ++ $(objpfx)tst-rtld-help.out \ ++ # tests-special + endif + tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 + tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 +@@ -356,9 +501,16 @@ tst-tls-many-dynamic-modules-dep = \ + tst-tls-many-dynamic-modules-dep-bad-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + tst-tls-many-dynamic-modules-dep-bad = \ + $(foreach n,$(tst-tls-many-dynamic-modules-dep-bad-suffixes),tst-tls-manydynamic$(n)mod-dep-bad) +-extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \ +- tst-tlsalign-vars.o +-test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars ++extra-test-objs += \ ++ $(tlsmod17a-modules:=.os) \ ++ $(tlsmod18a-modules:=.os) \ ++ tst-tlsalign-vars.o \ ++ # extra-test-objs ++test-extras += \ ++ tst-tlsalign-vars \ ++ tst-tlsmod17a \ ++ tst-tlsmod18a \ ++ # test-extras + modules-names = \ + circlemod1 \ + circlemod1a \ +@@ -610,17 +762,17 @@ modules-names-cxx = \ + tst-unique3lib \ + tst-unique3lib2 \ + tst-unique4lib \ +-# modules-names-cxx ++ # modules-names-cxx + + modules-names += \ + $(if $(CXX),$(modules-names-cxx)) \ + $(modules-execstack-$(have-z-execstack)) \ ++ $(tlsmod17a-modules) \ ++ $(tlsmod18a-modules) \ + $(tst-tls-many-dynamic-modules) \ + $(tst-tls-many-dynamic-modules-dep) \ + $(tst-tls-many-dynamic-modules-dep-bad) \ +- $(tlsmod17a-modules) \ +- $(tlsmod18a-modules) \ +-# modules-names ++ # modules-names + + # Most modules build with _ISOMAC defined, but those filtered out + # depend on internal headers. +@@ -669,35 +821,70 @@ modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod + tests += $(tests-static) + + ifeq (yes,$(have-ifunc)) +-tests-ifuncstatic := ifuncmain1static ifuncmain1picstatic \ +- ifuncmain2static ifuncmain2picstatic \ +- ifuncmain4static ifuncmain4picstatic \ +- ifuncmain5static ifuncmain5picstatic \ +- ifuncmain7static ifuncmain7picstatic ++tests-ifuncstatic := \ ++ ifuncmain1static \ ++ ifuncmain1picstatic \ ++ ifuncmain2static \ ++ ifuncmain2picstatic \ ++ ifuncmain4static \ ++ ifuncmain4picstatic \ ++ ifuncmain5static \ ++ ifuncmain5picstatic \ ++ ifuncmain7static \ ++ ifuncmain7picstatic \ ++ # tests-ifuncstatic + ifeq (yes,$(have-gcc-ifunc)) + tests-ifuncstatic += ifuncmain9static ifuncmain9picstatic + endif + tests-static += $(tests-ifuncstatic) + tests-internal += $(tests-ifuncstatic) + ifeq (yes,$(build-shared)) +-tests += tst-ifunc-fault-lazy tst-ifunc-fault-bindnow ++tests += \ ++ tst-ifunc-fault-bindnow \ ++ tst-ifunc-fault-lazy \ ++ # tests + # Note: sysdeps/x86_64/ifuncmain8.c uses ifuncmain8. + tests-internal += \ +- ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \ +- ifuncmain1staticpic \ +- ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \ +- ifuncmain5 ifuncmain5pic ifuncmain5staticpic \ +- ifuncmain7 ifuncmain7pic ++ ifuncmain1 \ ++ ifuncmain1pic \ ++ ifuncmain1staticpic \ ++ ifuncmain1vis \ ++ ifuncmain1vispic \ ++ ifuncmain2 \ ++ ifuncmain2pic \ ++ ifuncmain3 \ ++ ifuncmain4 \ ++ ifuncmain5 \ ++ ifuncmain5pic \ ++ ifuncmain5staticpic \ ++ ifuncmain7 \ ++ ifuncmain7pic \ ++ # tests-internal + ifeq (yes,$(have-gcc-ifunc)) +-tests-internal += ifuncmain9 ifuncmain9pic ++tests-internal += \ ++ ifuncmain9 \ ++ ifuncmain9pic \ ++ # tests-internal + endif +-ifunc-test-modules = ifuncdep1 ifuncdep1pic ifuncdep2 ifuncdep2pic \ +- ifuncdep5 ifuncdep5pic ++ifunc-test-modules = \ ++ ifuncdep1 \ ++ ifuncdep1pic \ ++ ifuncdep2 \ ++ ifuncdep2pic \ ++ ifuncdep5 \ ++ ifuncdep5pic \ ++ # ifunc-test-modules + extra-test-objs += $(ifunc-test-modules:=.o) + test-internal-extras += $(ifunc-test-modules) + ifeq (yes,$(have-fpie)) +-ifunc-pie-tests = ifuncmain1pie ifuncmain1vispie ifuncmain1staticpie \ +- ifuncmain5pie ifuncmain6pie ifuncmain7pie ++ifunc-pie-tests = \ ++ ifuncmain1pie \ ++ ifuncmain1staticpie \ ++ ifuncmain1vispie \ ++ ifuncmain5pie \ ++ ifuncmain6pie \ ++ ifuncmain7pie \ ++ # ifunc-pie-tests + ifeq (yes,$(have-gcc-ifunc)) + ifunc-pie-tests += ifuncmain9pie + endif +@@ -707,30 +894,50 @@ endif + tests-internal += $(ifunc-pie-tests) + tests-pie += $(ifunc-pie-tests) + endif +-modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6 ++modules-names += \ ++ ifuncmod1 \ ++ ifuncmod3 \ ++ ifuncmod5 \ ++ ifuncmod6 \ ++ # module-names + endif + endif + + ifeq (yes,$(build-shared)) + ifeq ($(run-built-tests),yes) +-tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \ +- $(objpfx)tst-rtld-preload.out $(objpfx)argv0test.out \ +- $(objpfx)tst-rtld-help.out ++tests-special += \ ++ $(objpfx)argv0test.out \ ++ $(objpfx)tst-pathopt.out \ ++ $(objpfx)tst-rtld-help.out \ ++ $(objpfx)tst-rtld-load-self.out \ ++ $(objpfx)tst-rtld-preload.out \ ++ # tests-special + endif +-tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \ +- $(objpfx)check-wx-segment.out \ +- $(objpfx)check-localplt.out $(objpfx)check-initfini.out ++tests-special += \ ++ $(objpfx)check-execstack.out \ ++ $(objpfx)check-initfini.out \ ++ $(objpfx)check-localplt.out \ ++ $(objpfx)check-textrel.out \ ++ $(objpfx)check-wx-segment.out \ ++ # tests-special + endif + + ifeq ($(run-built-tests),yes) +-tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \ +- $(objpfx)tst-array1-static-cmp.out \ +- $(objpfx)tst-array2-cmp.out $(objpfx)tst-array3-cmp.out \ +- $(objpfx)tst-array4-cmp.out $(objpfx)tst-array5-cmp.out \ +- $(objpfx)tst-array5-static-cmp.out $(objpfx)order2-cmp.out \ +- $(objpfx)tst-initorder-cmp.out \ +- $(objpfx)tst-initorder2-cmp.out $(objpfx)tst-unused-dep.out \ +- $(objpfx)tst-unused-dep-cmp.out ++tests-special += \ ++ $(objpfx)order-cmp.out \ ++ $(objpfx)order2-cmp.out \ ++ $(objpfx)tst-array1-cmp.out \ ++ $(objpfx)tst-array1-static-cmp.out \ ++ $(objpfx)tst-array2-cmp.out \ ++ $(objpfx)tst-array3-cmp.out \ ++ $(objpfx)tst-array4-cmp.out \ ++ $(objpfx)tst-array5-cmp.out \ ++ $(objpfx)tst-array5-static-cmp.out \ ++ $(objpfx)tst-initorder-cmp.out \ ++ $(objpfx)tst-initorder2-cmp.out \ ++ $(objpfx)tst-unused-dep-cmp.out \ ++ $(objpfx)tst-unused-dep.out \ ++ # tests-special + endif + + ifndef avoid-generated +@@ -835,6 +1042,7 @@ rtld-stubbed-symbols = \ + free \ + malloc \ + realloc \ ++ # rtld-stubbed-symbols + + ifeq ($(have-ssp),yes) + # rtld is not built with the stack protector, so these references will diff --git a/SOURCES/glibc-rh2040657-7.patch b/SOURCES/glibc-rh2040657-7.patch new file mode 100644 index 0000000..1189326 --- /dev/null +++ b/SOURCES/glibc-rh2040657-7.patch @@ -0,0 +1,633 @@ +commit b693d75f0c611bce9b0ad984bad306121d42c535 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + elf: Split dl-printf.c from dl-misc.c + + This allows to use different compiler flags for the diagnostics + code. + + Reviewed-by: H.J. Lu + +diff --git a/elf/Makefile b/elf/Makefile +index 124905f96c88ab53..52aafc89cec835ab 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -64,6 +64,7 @@ dl-routines = \ + dl-object \ + dl-open \ + dl-origin \ ++ dl-printf \ + dl-profile \ + dl-reloc \ + dl-runtime \ +diff --git a/elf/dl-misc.c b/elf/dl-misc.c +index b256d792c6198683..f17140b129343f7b 100644 +--- a/elf/dl-misc.c ++++ b/elf/dl-misc.c +@@ -16,24 +16,16 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#include <_itoa.h> + #include + #include +-#include + #include +-#include +-#include +-#include +-#include ++#include + #include ++#include + #include +-#include + #include +-#include +-#include +-#include <_itoa.h> +-#include +-#include ++#include + + /* Read the whole contents of FILE into new mmap'd space with given + protections. *SIZEP gets the size of the file. On error MAP_FAILED +@@ -70,270 +62,6 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) + return result; + } + +- +-/* Bare-bones printf implementation. This function only knows about +- the formats and flags needed and can handle only up to 64 stripes in +- the output. */ +-static void +-_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg) +-{ +-# define NIOVMAX 64 +- struct iovec iov[NIOVMAX]; +- int niov = 0; +- pid_t pid = 0; +- char pidbuf[12]; +- +- while (*fmt != '\0') +- { +- const char *startp = fmt; +- +- if (tag_p > 0) +- { +- /* Generate the tag line once. It consists of the PID and a +- colon followed by a tab. */ +- if (pid == 0) +- { +- char *p; +- pid = __getpid (); +- assert (pid >= 0 && sizeof (pid_t) <= 4); +- p = _itoa (pid, &pidbuf[10], 10, 0); +- while (p > pidbuf) +- *--p = ' '; +- pidbuf[10] = ':'; +- pidbuf[11] = '\t'; +- } +- +- /* Append to the output. */ +- assert (niov < NIOVMAX); +- iov[niov].iov_len = 12; +- iov[niov++].iov_base = pidbuf; +- +- /* No more tags until we see the next newline. */ +- tag_p = -1; +- } +- +- /* Skip everything except % and \n (if tags are needed). */ +- while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n')) +- ++fmt; +- +- /* Append constant string. */ +- assert (niov < NIOVMAX); +- if ((iov[niov].iov_len = fmt - startp) != 0) +- iov[niov++].iov_base = (char *) startp; +- +- if (*fmt == '%') +- { +- /* It is a format specifier. */ +- char fill = ' '; +- int width = -1; +- int prec = -1; +-#if LONG_MAX != INT_MAX +- int long_mod = 0; +-#endif +- +- /* Recognize zero-digit fill flag. */ +- if (*++fmt == '0') +- { +- fill = '0'; +- ++fmt; +- } +- +- /* See whether with comes from a parameter. Note that no other +- way to specify the width is implemented. */ +- if (*fmt == '*') +- { +- width = va_arg (arg, int); +- ++fmt; +- } +- +- /* Handle precision. */ +- if (*fmt == '.' && fmt[1] == '*') +- { +- prec = va_arg (arg, int); +- fmt += 2; +- } +- +- /* Recognize the l modifier. It is only important on some +- platforms where long and int have a different size. We +- can use the same code for size_t. */ +- if (*fmt == 'l' || *fmt == 'Z') +- { +-#if LONG_MAX != INT_MAX +- long_mod = 1; +-#endif +- ++fmt; +- } +- +- switch (*fmt) +- { +- /* Integer formatting. */ +- case 'd': +- case 'u': +- case 'x': +- { +- /* We have to make a difference if long and int have a +- different size. */ +-#if LONG_MAX != INT_MAX +- unsigned long int num = (long_mod +- ? va_arg (arg, unsigned long int) +- : va_arg (arg, unsigned int)); +-#else +- unsigned long int num = va_arg (arg, unsigned int); +-#endif +- bool negative = false; +- if (*fmt == 'd') +- { +-#if LONG_MAX != INT_MAX +- if (long_mod) +- { +- if ((long int) num < 0) +- negative = true; +- } +- else +- { +- if ((int) num < 0) +- { +- num = (unsigned int) num; +- negative = true; +- } +- } +-#else +- if ((int) num < 0) +- negative = true; +-#endif +- } +- +- /* We use alloca() to allocate the buffer with the most +- pessimistic guess for the size. Using alloca() allows +- having more than one integer formatting in a call. */ +- char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int)); +- char *endp = &buf[1 + 3 * sizeof (unsigned long int)]; +- char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0); +- +- /* Pad to the width the user specified. */ +- if (width != -1) +- while (endp - cp < width) +- *--cp = fill; +- +- if (negative) +- *--cp = '-'; +- +- iov[niov].iov_base = cp; +- iov[niov].iov_len = endp - cp; +- ++niov; +- } +- break; +- +- case 's': +- /* Get the string argument. */ +- iov[niov].iov_base = va_arg (arg, char *); +- iov[niov].iov_len = strlen (iov[niov].iov_base); +- if (prec != -1) +- iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len); +- ++niov; +- break; +- +- case '%': +- iov[niov].iov_base = (void *) fmt; +- iov[niov].iov_len = 1; +- ++niov; +- break; +- +- default: +- assert (! "invalid format specifier"); +- } +- ++fmt; +- } +- else if (*fmt == '\n') +- { +- /* See whether we have to print a single newline character. */ +- if (fmt == startp) +- { +- iov[niov].iov_base = (char *) startp; +- iov[niov++].iov_len = 1; +- } +- else +- /* No, just add it to the rest of the string. */ +- ++iov[niov - 1].iov_len; +- +- /* Next line, print a tag again. */ +- tag_p = 1; +- ++fmt; +- } +- } +- +- /* Finally write the result. */ +- _dl_writev (fd, iov, niov); +-} +- +- +-/* Write to debug file. */ +-void +-_dl_debug_printf (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg); +- va_end (arg); +-} +- +- +-/* Write to debug file but don't start with a tag. */ +-void +-_dl_debug_printf_c (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg); +- va_end (arg); +-} +- +- +-/* Write the given file descriptor. */ +-void +-_dl_dprintf (int fd, const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (fd, 0, fmt, arg); +- va_end (arg); +-} +- +-void +-_dl_printf (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg); +- va_end (arg); +-} +- +-void +-_dl_error_printf (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg); +- va_end (arg); +-} +- +-void +-_dl_fatal_printf (const char *fmt, ...) +-{ +- va_list arg; +- +- va_start (arg, fmt); +- _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg); +- va_end (arg); +- _exit (127); +-} +-rtld_hidden_def (_dl_fatal_printf) +- + /* Test whether given NAME matches any of the names of the given object. */ + int + _dl_name_match_p (const char *name, const struct link_map *map) +@@ -354,7 +82,6 @@ _dl_name_match_p (const char *name, const struct link_map *map) + return 0; + } + +- + unsigned long int + _dl_higher_prime_number (unsigned long int n) + { +diff --git a/elf/dl-printf.c b/elf/dl-printf.c +new file mode 100644 +index 0000000000000000..d3264ba96cd959bf +--- /dev/null ++++ b/elf/dl-printf.c +@@ -0,0 +1,292 @@ ++/* printf implementation for the dynamic loader. ++ Copyright (C) 1997-2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include <_itoa.h> ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Bare-bones printf implementation. This function only knows about ++ the formats and flags needed and can handle only up to 64 stripes in ++ the output. */ ++static void ++_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg) ++{ ++# define NIOVMAX 64 ++ struct iovec iov[NIOVMAX]; ++ int niov = 0; ++ pid_t pid = 0; ++ char pidbuf[12]; ++ ++ while (*fmt != '\0') ++ { ++ const char *startp = fmt; ++ ++ if (tag_p > 0) ++ { ++ /* Generate the tag line once. It consists of the PID and a ++ colon followed by a tab. */ ++ if (pid == 0) ++ { ++ char *p; ++ pid = __getpid (); ++ assert (pid >= 0 && sizeof (pid_t) <= 4); ++ p = _itoa (pid, &pidbuf[10], 10, 0); ++ while (p > pidbuf) ++ *--p = ' '; ++ pidbuf[10] = ':'; ++ pidbuf[11] = '\t'; ++ } ++ ++ /* Append to the output. */ ++ assert (niov < NIOVMAX); ++ iov[niov].iov_len = 12; ++ iov[niov++].iov_base = pidbuf; ++ ++ /* No more tags until we see the next newline. */ ++ tag_p = -1; ++ } ++ ++ /* Skip everything except % and \n (if tags are needed). */ ++ while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n')) ++ ++fmt; ++ ++ /* Append constant string. */ ++ assert (niov < NIOVMAX); ++ if ((iov[niov].iov_len = fmt - startp) != 0) ++ iov[niov++].iov_base = (char *) startp; ++ ++ if (*fmt == '%') ++ { ++ /* It is a format specifier. */ ++ char fill = ' '; ++ int width = -1; ++ int prec = -1; ++#if LONG_MAX != INT_MAX ++ int long_mod = 0; ++#endif ++ ++ /* Recognize zero-digit fill flag. */ ++ if (*++fmt == '0') ++ { ++ fill = '0'; ++ ++fmt; ++ } ++ ++ /* See whether with comes from a parameter. Note that no other ++ way to specify the width is implemented. */ ++ if (*fmt == '*') ++ { ++ width = va_arg (arg, int); ++ ++fmt; ++ } ++ ++ /* Handle precision. */ ++ if (*fmt == '.' && fmt[1] == '*') ++ { ++ prec = va_arg (arg, int); ++ fmt += 2; ++ } ++ ++ /* Recognize the l modifier. It is only important on some ++ platforms where long and int have a different size. We ++ can use the same code for size_t. */ ++ if (*fmt == 'l' || *fmt == 'Z') ++ { ++#if LONG_MAX != INT_MAX ++ long_mod = 1; ++#endif ++ ++fmt; ++ } ++ ++ switch (*fmt) ++ { ++ /* Integer formatting. */ ++ case 'd': ++ case 'u': ++ case 'x': ++ { ++ /* We have to make a difference if long and int have a ++ different size. */ ++#if LONG_MAX != INT_MAX ++ unsigned long int num = (long_mod ++ ? va_arg (arg, unsigned long int) ++ : va_arg (arg, unsigned int)); ++#else ++ unsigned long int num = va_arg (arg, unsigned int); ++#endif ++ bool negative = false; ++ if (*fmt == 'd') ++ { ++#if LONG_MAX != INT_MAX ++ if (long_mod) ++ { ++ if ((long int) num < 0) ++ negative = true; ++ } ++ else ++ { ++ if ((int) num < 0) ++ { ++ num = (unsigned int) num; ++ negative = true; ++ } ++ } ++#else ++ if ((int) num < 0) ++ negative = true; ++#endif ++ } ++ ++ /* We use alloca() to allocate the buffer with the most ++ pessimistic guess for the size. Using alloca() allows ++ having more than one integer formatting in a call. */ ++ char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int)); ++ char *endp = &buf[1 + 3 * sizeof (unsigned long int)]; ++ char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0); ++ ++ /* Pad to the width the user specified. */ ++ if (width != -1) ++ while (endp - cp < width) ++ *--cp = fill; ++ ++ if (negative) ++ *--cp = '-'; ++ ++ iov[niov].iov_base = cp; ++ iov[niov].iov_len = endp - cp; ++ ++niov; ++ } ++ break; ++ ++ case 's': ++ /* Get the string argument. */ ++ iov[niov].iov_base = va_arg (arg, char *); ++ iov[niov].iov_len = strlen (iov[niov].iov_base); ++ if (prec != -1) ++ iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len); ++ ++niov; ++ break; ++ ++ case '%': ++ iov[niov].iov_base = (void *) fmt; ++ iov[niov].iov_len = 1; ++ ++niov; ++ break; ++ ++ default: ++ assert (! "invalid format specifier"); ++ } ++ ++fmt; ++ } ++ else if (*fmt == '\n') ++ { ++ /* See whether we have to print a single newline character. */ ++ if (fmt == startp) ++ { ++ iov[niov].iov_base = (char *) startp; ++ iov[niov++].iov_len = 1; ++ } ++ else ++ /* No, just add it to the rest of the string. */ ++ ++iov[niov - 1].iov_len; ++ ++ /* Next line, print a tag again. */ ++ tag_p = 1; ++ ++fmt; ++ } ++ } ++ ++ /* Finally write the result. */ ++ _dl_writev (fd, iov, niov); ++} ++ ++ ++/* Write to debug file. */ ++void ++_dl_debug_printf (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg); ++ va_end (arg); ++} ++ ++ ++/* Write to debug file but don't start with a tag. */ ++void ++_dl_debug_printf_c (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg); ++ va_end (arg); ++} ++ ++ ++/* Write the given file descriptor. */ ++void ++_dl_dprintf (int fd, const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (fd, 0, fmt, arg); ++ va_end (arg); ++} ++ ++void ++_dl_printf (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg); ++ va_end (arg); ++} ++ ++void ++_dl_error_printf (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg); ++ va_end (arg); ++} ++ ++void ++_dl_fatal_printf (const char *fmt, ...) ++{ ++ va_list arg; ++ ++ va_start (arg, fmt); ++ _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg); ++ va_end (arg); ++ _exit (127); ++} ++rtld_hidden_def (_dl_fatal_printf) diff --git a/SOURCES/glibc-rh2040657-8.patch b/SOURCES/glibc-rh2040657-8.patch new file mode 100644 index 0000000..7eabbc4 --- /dev/null +++ b/SOURCES/glibc-rh2040657-8.patch @@ -0,0 +1,146 @@ +commit 9ba202c78f0aa39f49929eee63c367847da72ee4 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + Add --with-rtld-early-cflags configure option + + Reviewed-by: H.J. Lu + Reviewed-by: Carlos O'Donell + +Conflicts: + INSTALL + configure + manual/install.texi + (Missing --with-timeout-factor downstream.) + +diff --git a/INSTALL b/INSTALL +index d6d93ec9be4262d7..d8d4e9f155f56616 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -106,6 +106,14 @@ if 'CFLAGS' is specified it must enable optimization. For example: + particular case and potentially change debugging information and + metadata only). + ++'--with-rtld-early-cflags=CFLAGS' ++ Use additional compiler flags CFLAGS to build the early startup ++ code of the dynamic linker. These flags can be used to enable ++ early dynamic linker diagnostics to run on CPUs which are not ++ compatible with the rest of the GNU C Library, for example, due to ++ compiler flags which target a later instruction set architecture ++ (ISA). ++ + '--disable-shared' + Don't build shared libraries even if it is possible. Not all + systems support shared libraries; you need ELF support and +diff --git a/config.make.in b/config.make.in +index e8630a8d0ccf874d..6d43e691f7823262 100644 +--- a/config.make.in ++++ b/config.make.in +@@ -110,6 +110,7 @@ CFLAGS = @CFLAGS@ + CPPFLAGS-config = @CPPFLAGS@ + CPPUNDEFS = @CPPUNDEFS@ + extra-nonshared-cflags = @extra_nonshared_cflags@ ++rtld-early-cflags = @rtld_early_cflags@ + ASFLAGS-config = @ASFLAGS_config@ + AR = @AR@ + NM = @NM@ +diff --git a/configure b/configure +index e9d2b1f398c4dba0..03f4e59e754b5463 100755 +--- a/configure ++++ b/configure +@@ -681,6 +681,7 @@ force_install + bindnow + hardcoded_path_in_tests + enable_timezone_tools ++rtld_early_cflags + extra_nonshared_cflags + use_default_link + sysheaders +@@ -761,6 +762,7 @@ with_selinux + with_headers + with_default_link + with_nonshared_cflags ++with_rtld_early_cflags + enable_sanity_checks + enable_shared + enable_profile +@@ -1479,6 +1481,8 @@ Optional Packages: + --with-default-link do not use explicit linker scripts + --with-nonshared-cflags=CFLAGS + build nonshared libraries with additional CFLAGS ++ --with-rtld-early-cflags=CFLAGS ++ build early initialization with additional CFLAGS + --with-cpu=CPU select code for CPU variant + + Some influential environment variables: +@@ -3383,6 +3387,16 @@ fi + + + ++# Check whether --with-rtld-early-cflags was given. ++if test "${with_rtld_early_cflags+set}" = set; then : ++ withval=$with_rtld_early_cflags; rtld_early_cflags=$withval ++else ++ rtld_early_cflags= ++fi ++ ++ ++ ++ + # Check whether --enable-sanity-checks was given. + if test "${enable_sanity_checks+set}" = set; then : + enableval=$enable_sanity_checks; enable_sanity=$enableval +diff --git a/configure.ac b/configure.ac +index 79f6822d29ce21cf..eb9431875fae1b0e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -162,6 +162,12 @@ AC_ARG_WITH([nonshared-cflags], + [extra_nonshared_cflags=$withval], + [extra_nonshared_cflags=]) + AC_SUBST(extra_nonshared_cflags) ++AC_ARG_WITH([rtld-early-cflags], ++ AS_HELP_STRING([--with-rtld-early-cflags=CFLAGS], ++ [build early initialization with additional CFLAGS]), ++ [rtld_early_cflags=$withval], ++ [rtld_early_cflags=]) ++AC_SUBST(rtld_early_cflags) + + AC_ARG_ENABLE([sanity-checks], + AS_HELP_STRING([--disable-sanity-checks], +diff --git a/elf/Makefile b/elf/Makefile +index 52aafc89cec835ab..778e393395fc5248 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -152,6 +152,14 @@ CFLAGS-.o += $(call elide-stack-protector,.o,$(elide-routines.os)) + CFLAGS-.op += $(call elide-stack-protector,.op,$(elide-routines.os)) + CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines)) + ++# Add the requested compiler flags to the early startup code. ++CFLAGS-dl-printf.os += $(rtld-early-cflags) ++CFLAGS-dl-sysdep.os += $(rtld-early-cflags) ++CFLAGS-dl-tunables.os += $(rtld-early-cflags) ++CFLAGS-dl-write.os += $(rtld-early-cflags) ++CFLAGS-dl-writev.os += $(rtld-early-cflags) ++CFLAGS-rtld.os += $(rtld-early-cflags) ++ + ifeq ($(unwind-find-fde),yes) + routines += unwind-dw2-fde-glibc + shared-only-routines += unwind-dw2-fde-glibc +diff --git a/manual/install.texi b/manual/install.texi +index 1320ac69b3c645f2..816b77a0a25a88a7 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -131,6 +131,13 @@ that the objects in @file{libc_nonshared.a} are compiled with this flag + (although this will not affect the generated code in this particular + case and potentially change debugging information and metadata only). + ++@item --with-rtld-early-cflags=@var{cflags} ++Use additional compiler flags @var{cflags} to build the early startup ++code of the dynamic linker. These flags can be used to enable early ++dynamic linker diagnostics to run on CPUs which are not compatible with ++the rest of @theglibc{}, for example, due to compiler flags which target ++a later instruction set architecture (ISA). ++ + @c disable static doesn't work currently + @c @item --disable-static + @c Don't build static libraries. Static libraries aren't that useful these diff --git a/SOURCES/glibc-rh2040657-9.patch b/SOURCES/glibc-rh2040657-9.patch new file mode 100644 index 0000000..1908c6f --- /dev/null +++ b/SOURCES/glibc-rh2040657-9.patch @@ -0,0 +1,52 @@ +commit 550116486692efc394d03befee19f7e9c17d5044 +Author: Florian Weimer +Date: Fri Jan 14 20:16:05 2022 +0100 + + powerpc64le: Use in early HWCAP check + + This is required so that the checks still work if $(early-cflags) + selects a different ISA level. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + +diff --git a/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h +index 0437ae4d522fb36d..899c74f880e6f5f0 100644 +--- a/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h ++++ b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h +@@ -19,17 +19,18 @@ + #ifndef _DL_HWCAP_CHECK_H + #define _DL_HWCAP_CHECK_H + ++#include + #include + + static inline void + dl_hwcap_check (void) + { +-#ifdef _ARCH_PWR9 ++#ifdef GCCMACRO_ARCH_PWR9 + if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_00) == 0) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks ISA 3.00 support (POWER9 or later required)\n"); + #endif +-#ifdef __FLOAT128_HARDWARE__ ++#ifdef GCCMACRO__FLOAT128_HARDWARE__ + if ((GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_IEEE128) == 0) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks float128 support (POWER 9 or later required)\n"); +@@ -37,12 +38,12 @@ Fatal glibc error: CPU lacks float128 support (POWER 9 or later required)\n"); + /* This check is not actually reached when building for POWER10 and + running on POWER9 because there are faulting PCREL instructions + before this point. */ +-#if defined _ARCH_PWR10 || defined __PCREL__ ++#if defined GCCMACRO_ARCH_PWR10 || defined GCCMACRO__PCREL__ + if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_1) == 0) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks ISA 3.10 support (POWER10 or later required)\n"); + #endif +-#ifdef __MMA__ ++#ifdef GCCMACRO__MMA__ + if ((GLRO (dl_hwcap2) & PPC_FEATURE2_MMA) == 0) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks MMA support (POWER10 or later required)\n"); diff --git a/SOURCES/glibc-upstream-2.34-100.patch b/SOURCES/glibc-upstream-2.34-100.patch new file mode 100644 index 0000000..d797f77 --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-upstream-2.34-101.patch b/SOURCES/glibc-upstream-2.34-101.patch new file mode 100644 index 0000000..b318a81 --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-upstream-2.34-102.patch b/SOURCES/glibc-upstream-2.34-102.patch new file mode 100644 index 0000000..928856e --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-upstream-2.34-103.patch b/SOURCES/glibc-upstream-2.34-103.patch new file mode 100644 index 0000000..1605e95 --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-upstream-2.34-104.patch b/SOURCES/glibc-upstream-2.34-104.patch new file mode 100644 index 0000000..4ae7486 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-104.patch @@ -0,0 +1,26 @@ +commit 05c83ccaf50aef2dd30d92cbb814383f6bddea2c +Author: Gleb Fotengauer-Malinovskiy +Date: Tue Feb 1 22:39:02 2022 +0000 + + linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage [BZ #28850] + + Pass the actual number of bytes returned by the kernel. + + Fixes: 33099d72e41c ("linux: Simplify get_nprocs") + Reviewed-by: Dmitry V. Levin + + (cherry picked from commit 97ba273b505763325efd802dc3a9562dbba79579) + +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index 7fc6521942e87293..7babd947aa902e77 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -45,7 +45,7 @@ __get_nprocs_sched (void) + int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size, + cpu_bits); + if (r > 0) +- return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits); ++ return CPU_COUNT_S (r, (cpu_set_t*) cpu_bits); + else if (r == -EINVAL) + /* The input buffer is still not enough to store the number of cpus. This + is an arbitrary values assuming such systems should be rare and there diff --git a/SOURCES/glibc-upstream-2.34-105.patch b/SOURCES/glibc-upstream-2.34-105.patch new file mode 100644 index 0000000..423f65f --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-105.patch @@ -0,0 +1,234 @@ +commit ad615b59c78d6d37fee921fb2b2ae6b72c930625 +Author: Florian Weimer +Date: Tue Sep 28 18:55:49 2021 +0200 + + Linux: Simplify __opensock and fix race condition [BZ #28353] + + AF_NETLINK support is not quite optional on modern Linux systems + anymore, so it is likely that the first attempt will always succeed. + Consequently, there is no need to cache the result. Keep AF_UNIX + and the Internet address families as a fallback, for the rare case + that AF_NETLINK is missing. The other address families previously + probed are totally obsolete be now, so remove them. + + Use this simplified version as the generic implementation, disabling + Netlink support as needed. + + (cherry picked from commit 5bf07e1b3a74232bfb8332275110be1a5da50f83) + +diff --git a/socket/opensock.c b/socket/opensock.c +index 37148d4743343ff4..ff94d27a61bd3889 100644 +--- a/socket/opensock.c ++++ b/socket/opensock.c +@@ -1,4 +1,5 @@ +-/* Copyright (C) 1999-2021 Free Software Foundation, Inc. ++/* Create socket with an unspecified address family for use with ioctl. ++ Copyright (C) 1999-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -15,56 +16,34 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#include + #include +-#include + + /* Return a socket of any type. The socket can be used in subsequent + ioctl calls to talk to the kernel. */ + int + __opensock (void) + { +- /* Cache the last AF that worked, to avoid many redundant calls to +- socket(). */ +- static int sock_af = -1; +- int fd = -1; +- __libc_lock_define_initialized (static, lock); +- +- if (sock_af != -1) +- { +- fd = __socket (sock_af, SOCK_DGRAM, 0); +- if (fd != -1) +- return fd; +- } +- +- __libc_lock_lock (lock); +- +- if (sock_af != -1) +- fd = __socket (sock_af, SOCK_DGRAM, 0); +- +- if (fd == -1) +- { +-#ifdef AF_INET +- fd = __socket (sock_af = AF_INET, SOCK_DGRAM, 0); +-#endif +-#ifdef AF_INET6 +- if (fd < 0) +- fd = __socket (sock_af = AF_INET6, SOCK_DGRAM, 0); +-#endif +-#ifdef AF_IPX +- if (fd < 0) +- fd = __socket (sock_af = AF_IPX, SOCK_DGRAM, 0); +-#endif +-#ifdef AF_AX25 +- if (fd < 0) +- fd = __socket (sock_af = AF_AX25, SOCK_DGRAM, 0); +-#endif +-#ifdef AF_APPLETALK +- if (fd < 0) +- fd = __socket (sock_af = AF_APPLETALK, SOCK_DGRAM, 0); ++ /* SOCK_DGRAM is supported by all address families. (Netlink does ++ not support SOCK_STREAM.) */ ++ int type = SOCK_DGRAM | SOCK_CLOEXEC; ++ int fd; ++ ++#ifdef AF_NETLINK ++ fd = __socket (AF_NETLINK, type, 0); ++ if (fd >= 0) ++ return fd; + #endif +- } + +- __libc_lock_unlock (lock); ++ fd = __socket (AF_UNIX, type, 0); ++ if (fd >= 0) ++ return fd; ++ fd = __socket (AF_INET, type, 0); ++ if (fd >= 0) ++ return fd; ++ fd = __socket (AF_INET6, type, 0); ++ if (fd >= 0) ++ return fd; ++ __set_errno (ENOENT); + return fd; + } +diff --git a/sysdeps/unix/sysv/linux/opensock.c b/sysdeps/unix/sysv/linux/opensock.c +deleted file mode 100644 +index e87d6e58b0b84f82..0000000000000000 +--- a/sysdeps/unix/sysv/linux/opensock.c ++++ /dev/null +@@ -1,114 +0,0 @@ +-/* Copyright (C) 1999-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* Return a socket of any type. The socket can be used in subsequent +- ioctl calls to talk to the kernel. */ +-int +-__opensock (void) +-{ +- static int last_family; /* Available socket family we will use. */ +- static int last_type; +- static const struct +- { +- int family; +- const char procname[15]; +- } afs[] = +- { +- { AF_UNIX, "net/unix" }, +- { AF_INET, "" }, +- { AF_INET6, "net/if_inet6" }, +- { AF_AX25, "net/ax25" }, +- { AF_NETROM, "net/nr" }, +- { AF_ROSE, "net/rose" }, +- { AF_IPX, "net/ipx" }, +- { AF_APPLETALK, "net/appletalk" }, +- { AF_ECONET, "sys/net/econet" }, +- { AF_ASH, "sys/net/ash" }, +- { AF_X25, "net/x25" }, +-#ifdef NEED_AF_IUCV +- { AF_IUCV, "net/iucv" } +-#endif +- }; +-#define nafs (sizeof (afs) / sizeof (afs[0])) +- char fname[sizeof "/proc/" + 14]; +- int result; +- int has_proc; +- size_t cnt; +- +- /* We already know which family to use from the last call. Use it +- again. */ +- if (last_family != 0) +- { +- assert (last_type != 0); +- +- result = __socket (last_family, last_type | SOCK_CLOEXEC, 0); +- if (result != -1 || errno != EAFNOSUPPORT) +- /* Maybe the socket type isn't supported anymore (module is +- unloaded). In this case again try to find the type. */ +- return result; +- +- /* Reset the values. They seem not valid anymore. */ +- last_family = 0; +- last_type = 0; +- } +- +- /* Check whether the /proc filesystem is available. */ +- has_proc = __access ("/proc/net", R_OK) != -1; +- strcpy (fname, "/proc/"); +- +- /* Iterate over the interface families and find one which is +- available. */ +- for (cnt = 0; cnt < nafs; ++cnt) +- { +- int type = SOCK_DGRAM; +- +- if (has_proc && afs[cnt].procname[0] != '\0') +- { +- strcpy (fname + 6, afs[cnt].procname); +- if (__access (fname, R_OK) == -1) +- /* The /proc entry is not available. I.e., we cannot +- create a socket of this type (without loading the +- module). Don't look for it since this might trigger +- loading the module. */ +- continue; +- } +- +- if (afs[cnt].family == AF_NETROM || afs[cnt].family == AF_X25) +- type = SOCK_SEQPACKET; +- +- result = __socket (afs[cnt].family, type | SOCK_CLOEXEC, 0); +- if (result != -1) +- { +- /* Found an available family. */ +- last_type = type; +- last_family = afs[cnt].family; +- return result; +- } +- } +- +- /* None of the protocol families is available. It is unclear what kind +- of error is returned. ENOENT seems like a reasonable choice. */ +- __set_errno (ENOENT); +- return -1; +-} +diff --git a/sysdeps/unix/sysv/linux/s390/opensock.c b/sysdeps/unix/sysv/linux/s390/opensock.c +deleted file mode 100644 +index f099d651ff04d211..0000000000000000 +--- a/sysdeps/unix/sysv/linux/s390/opensock.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define NEED_AF_IUCV 1 +-#include "../opensock.c" diff --git a/SOURCES/glibc-upstream-2.34-106.patch b/SOURCES/glibc-upstream-2.34-106.patch new file mode 100644 index 0000000..296f32a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-106.patch @@ -0,0 +1,44 @@ +commit d8302ba2da1e5ac59a1c4dc1c1207a10fdafdb08 +Author: Samuel Thibault +Date: Mon Oct 18 01:39:02 2021 +0200 + + hurd if_index: Explicitly use AF_INET for if index discovery + + 5bf07e1b3a74 ("Linux: Simplify __opensock and fix race condition [BZ #28353]") + made __opensock try NETLINK then UNIX then INET. On the Hurd, only INET + knows about network interfaces, so better actually specify that in + if_index. + + (cherry picked from commit 1d3decee997ba2fc24af81803299b2f4f3c47063) + +diff --git a/sysdeps/mach/hurd/if_index.c b/sysdeps/mach/hurd/if_index.c +index 0eab510453c9e861..e785ac15aa6a1002 100644 +--- a/sysdeps/mach/hurd/if_index.c ++++ b/sysdeps/mach/hurd/if_index.c +@@ -32,7 +32,7 @@ unsigned int + __if_nametoindex (const char *ifname) + { + struct ifreq ifr; +- int fd = __opensock (); ++ int fd = __socket (AF_INET, SOCK_DGRAM, 0); + + if (fd < 0) + return 0; +@@ -84,7 +84,7 @@ __if_nameindex (void) + error_t err = 0; + char data[2048]; + file_t server; +- int fd = __opensock (); ++ int fd = __socket (AF_INET, SOCK_DGRAM, 0); + struct ifconf ifc; + unsigned int nifs, i; + struct if_nameindex *idx = NULL; +@@ -169,7 +169,7 @@ char * + __if_indextoname (unsigned int ifindex, char ifname[IF_NAMESIZE]) + { + struct ifreq ifr; +- int fd = __opensock (); ++ int fd = __socket (AF_INET, SOCK_DGRAM, 0); + + if (fd < 0) + return NULL; diff --git a/SOURCES/glibc-upstream-2.34-107.patch b/SOURCES/glibc-upstream-2.34-107.patch new file mode 100644 index 0000000..650aa2b --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-107.patch @@ -0,0 +1,35 @@ +commit 6eaf10cbb78d22eae7999d9de55f6b93999e0860 +Author: Florian Weimer +Date: Mon Nov 22 14:41:14 2021 +0100 + + socket: Do not use AF_NETLINK in __opensock + + It is not possible to use interface ioctls with netlink sockets + on all Linux kernels. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 3d981795cd00cc9b73c3ee5087c308361acd62e5) + +diff --git a/socket/opensock.c b/socket/opensock.c +index ff94d27a61bd3889..3e35821f91643456 100644 +--- a/socket/opensock.c ++++ b/socket/opensock.c +@@ -24,17 +24,10 @@ + int + __opensock (void) + { +- /* SOCK_DGRAM is supported by all address families. (Netlink does +- not support SOCK_STREAM.) */ ++ /* SOCK_DGRAM is supported by all address families. */ + int type = SOCK_DGRAM | SOCK_CLOEXEC; + int fd; + +-#ifdef AF_NETLINK +- fd = __socket (AF_NETLINK, type, 0); +- if (fd >= 0) +- return fd; +-#endif +- + fd = __socket (AF_UNIX, type, 0); + if (fd >= 0) + return fd; diff --git a/SOURCES/glibc-upstream-2.34-54.patch b/SOURCES/glibc-upstream-2.34-54.patch new file mode 100644 index 0000000..fec14bf --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-54.patch @@ -0,0 +1,32 @@ +commit 7af07fe795f43e53d31be1c6f9adba7e05f87b0b +Author: Xi Ruoyao +Date: Thu Aug 12 20:31:59 2021 +0000 + + mips: align stack in clone [BZ #28223] + + The MIPS O32 ABI requires 4 byte aligned stack, and the MIPS N64 and N32 + ABI require 8 byte aligned stack. Previously if the caller passed an + unaligned stack to clone the the child misbehaved. + + Fixes bug 28223. + + (cherry picked from commit 1f51cd9a860ee45eee8a56fb2ba925267a2a7bfe) + +diff --git a/sysdeps/unix/sysv/linux/mips/clone.S b/sysdeps/unix/sysv/linux/mips/clone.S +index 71d9dba8bd9e8f9e..43a5ad3a400d9504 100644 +--- a/sysdeps/unix/sysv/linux/mips/clone.S ++++ b/sysdeps/unix/sysv/linux/mips/clone.S +@@ -55,6 +55,13 @@ NESTED(__clone,4*SZREG,sp) + .set at + #endif + ++ /* Align stack to 4/8 bytes per the ABI. */ ++#if _MIPS_SIM == _ABIO32 ++ li t0,-4 ++#else ++ li t0,-8 ++#endif ++ and a1,a1,t0 + + /* Sanity check arguments. */ + li v0,EINVAL diff --git a/SOURCES/glibc-upstream-2.34-55.patch b/SOURCES/glibc-upstream-2.34-55.patch new file mode 100644 index 0000000..9746705 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-55.patch @@ -0,0 +1,37 @@ +commit 4db172a54d43f9b7fd17e66fc44a34efb3cab1e1 +Author: Xi Ruoyao +Date: Fri Aug 13 16:01:14 2021 +0000 + + mips: increase stack alignment in clone to match the ABI + + In "mips: align stack in clone [BZ #28223]" + (commit 1f51cd9a860ee45eee8a56fb2ba925267a2a7bfe) I made a mistake: I + misbelieved one "word" was 2-byte and "doubleword" should be 4-byte. + But in MIPS ABI one "word" is defined 32-bit (4-byte), so "doubleword" is + 8-byte [1], and "quadword" is 16-byte [2]. + + [1]: "System V Application Binary Interface: MIPS(R) RISC Processor + Supplement, 3rd edition", page 3-31 + [2]: "MIPSpro(TM) 64-Bit Porting and Transition Guide", page 23 + + (cherry picked from commit 0f62fe053273ff6c62ac95c59b7687c964737b00) + +diff --git a/sysdeps/unix/sysv/linux/mips/clone.S b/sysdeps/unix/sysv/linux/mips/clone.S +index 43a5ad3a400d9504..fd71b5ca2eb86089 100644 +--- a/sysdeps/unix/sysv/linux/mips/clone.S ++++ b/sysdeps/unix/sysv/linux/mips/clone.S +@@ -55,11 +55,11 @@ NESTED(__clone,4*SZREG,sp) + .set at + #endif + +- /* Align stack to 4/8 bytes per the ABI. */ ++ /* Align stack to 8/16 bytes per the ABI. */ + #if _MIPS_SIM == _ABIO32 +- li t0,-4 +-#else + li t0,-8 ++#else ++ li t0,-16 + #endif + and a1,a1,t0 + diff --git a/SOURCES/glibc-upstream-2.34-56.patch b/SOURCES/glibc-upstream-2.34-56.patch new file mode 100644 index 0000000..ee2ad63 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-56.patch @@ -0,0 +1,65 @@ +commit 93aabf891e96e93f100081ee07989c23d7107d17 +Author: Florian Weimer +Date: Fri Dec 17 11:48:41 2021 +0100 + + arm: Guard ucontext _rtld_global_ro access by SHARED, not PIC macro + + Due to PIE-by-default, PIC is now defined in more cases. libc.a + does not have _rtld_global_ro, and statically linking setcontext + fails. SHARED is the right condition to use, so that libc.a + references _dl_hwcap instead of _rtld_global_ro. + + For static PIE support, the !SHARED case would still have to be made + PIC. This patch does not achieve that. + + Fixes commit 23645707f12f2dd9d80b51effb2d9618a7b65565 + ("Replace --enable-static-pie with --disable-default-pie"). + + Reviewed-by: Siddhesh Poyarekar + Reviewed-by: Szabolcs Nagy + (cherry picked from commit ce1e5b11229f19820b86f8b19d651f16009552b0) + +diff --git a/sysdeps/unix/sysv/linux/arm/getcontext.S b/sysdeps/unix/sysv/linux/arm/getcontext.S +index 3aa581c4da6d1166..11bfcbe5f53afc6e 100644 +--- a/sysdeps/unix/sysv/linux/arm/getcontext.S ++++ b/sysdeps/unix/sysv/linux/arm/getcontext.S +@@ -50,7 +50,7 @@ ENTRY(__getcontext) + + /* Store FP regs. Much of the FP code is copied from arm/setjmp.S. */ + +-#ifdef PIC ++#ifdef SHARED + ldr r2, 1f + ldr r1, .Lrtld_global_ro + 0: add r2, pc, r2 +@@ -102,7 +102,7 @@ ENTRY(__getcontext) + + END(__getcontext) + +-#ifdef PIC ++#ifdef SHARED + 1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS + .Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +diff --git a/sysdeps/unix/sysv/linux/arm/setcontext.S b/sysdeps/unix/sysv/linux/arm/setcontext.S +index 8be8beefea13883e..4c7c6e550944138c 100644 +--- a/sysdeps/unix/sysv/linux/arm/setcontext.S ++++ b/sysdeps/unix/sysv/linux/arm/setcontext.S +@@ -32,7 +32,7 @@ ENTRY(__setcontext) + add r0, r0, #UCONTEXT_REGSPACE + + /* Restore the VFP registers. Copied from arm/__longjmp.S. */ +-#ifdef PIC ++#ifdef SHARED + ldr r2, 1f + ldr r1, .Lrtld_global_ro + 0: add r2, pc, r2 +@@ -101,7 +101,7 @@ ENTRY(__startcontext) + .fnend + END(__startcontext) + +-#ifdef PIC ++#ifdef SHARED + 1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS + .Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) diff --git a/SOURCES/glibc-upstream-2.34-57.patch b/SOURCES/glibc-upstream-2.34-57.patch new file mode 100644 index 0000000..c8523f9 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-57.patch @@ -0,0 +1,74 @@ +commit dc9b69d5331dcdca4547c0490cb9fefbd89e40f6 +Author: Florian Weimer +Date: Fri Dec 17 12:01:20 2021 +0100 + + nss: Use "files dns" as the default for the hosts database (bug 28700) + + This matches what is currently in nss/nsswitch.conf. The new ordering + matches what most distributions use in their installed configuration + files. + + It is common to add localhost to /etc/hosts because the name does not + exist in the DNS, but is commonly used as a host name. + + With the built-in "dns [!UNAVAIL=return] files" default, dns is + searched first and provides an answer for "localhost" (NXDOMAIN). + We never look at the files database as a result, so the contents of + /etc/hosts is ignored. This means that "getent hosts localhost" + fail without a /etc/nsswitch.conf file, even though the host name + is listed in /etc/hosts. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit b99b0f93ee8762fe53ff65802deb6f00700b9924) + +diff --git a/manual/nss.texi b/manual/nss.texi +index 3aaa7786f8cf3168..524d22ad1e7f8ca0 100644 +--- a/manual/nss.texi ++++ b/manual/nss.texi +@@ -324,9 +324,8 @@ missing. + + @cindex default value, and NSS + For the @code{hosts} and @code{networks} databases the default value is +-@code{dns [!UNAVAIL=return] files}. I.e., the system is prepared for +-the DNS service not to be available but if it is available the answer it +-returns is definitive. ++@code{files dns}. I.e., local configuration will override the contents ++of the domain name system (DNS). + + The @code{passwd}, @code{group}, and @code{shadow} databases was + traditionally handled in a special way. The appropriate files in the +diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c +index f1c97f7c8e9d7378..dbc87868dd408d9f 100644 +--- a/nss/XXX-lookup.c ++++ b/nss/XXX-lookup.c +@@ -29,7 +29,7 @@ + |* ALTERNATE_NAME - name of another service which is examined in *| + |* case DATABASE_NAME is not found *| + |* *| +-|* DEFAULT_CONFIG - string for default conf (e.g. "dns files") *| ++|* DEFAULT_CONFIG - string for default conf (e.g. "files dns") *| + |* *| + \*******************************************************************/ + +diff --git a/nss/nss_database.c b/nss/nss_database.c +index ab121cb371c087e9..54561f03287db2e4 100644 +--- a/nss/nss_database.c ++++ b/nss/nss_database.c +@@ -80,7 +80,7 @@ enum nss_database_default + { + nss_database_default_defconfig = 0, /* "nis [NOTFOUND=return] files". */ + nss_database_default_compat, /* "compat [NOTFOUND=return] files". */ +- nss_database_default_dns, /* "dns [!UNAVAIL=return] files". */ ++ nss_database_default_dns, /* "files dns". */ + nss_database_default_files, /* "files". */ + nss_database_default_nis, /* "nis". */ + nss_database_default_nis_nisplus, /* "nis nisplus". */ +@@ -133,7 +133,7 @@ nss_database_select_default (struct nss_database_default_cache *cache, + #endif + + case nss_database_default_dns: +- line = "dns [!UNAVAIL=return] files"; ++ line = "files dns"; + break; + + case nss_database_default_files: diff --git a/SOURCES/glibc-upstream-2.34-58.patch b/SOURCES/glibc-upstream-2.34-58.patch new file mode 100644 index 0000000..d95112e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-58.patch @@ -0,0 +1,35 @@ +commit 03de6917bd11c0591867607ce74ef658f76eabb9 +Author: Aurelien Jarno +Date: Wed Dec 15 23:46:19 2021 +0100 + + elf: Fix tst-cpu-features-cpuinfo for KVM guests on some AMD systems [BZ #28704] + + On KVM guests running on some AMD systems, the IBRS feature is reported + as a synthetic feature using the Intel feature, while the cpuinfo entry + keeps the same. Handle that by first checking the presence of the Intel + feature on AMD systems. + + Fixes bug 28704. + + (cherry picked from commit 94058f6cde8b887178885954740ac6c866d25eab) + +diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo.c b/sysdeps/x86/tst-cpu-features-cpuinfo.c +index 2d4927f5e52dc260..830aaca2ecae971b 100644 +--- a/sysdeps/x86/tst-cpu-features-cpuinfo.c ++++ b/sysdeps/x86/tst-cpu-features-cpuinfo.c +@@ -169,7 +169,14 @@ do_test (int argc, char **argv) + else if (cpu_features->basic.kind == arch_kind_amd) + { + fails += CHECK_PROC (ibpb, AMD_IBPB); +- fails += CHECK_PROC (ibrs, AMD_IBRS); ++ ++ /* The IBRS feature on AMD processors is reported using the Intel feature ++ * on KVM guests (synthetic bit). In both cases the cpuinfo entry is the ++ * same. */ ++ if (HAS_CPU_FEATURE (IBRS_IBPB)) ++ fails += CHECK_PROC (ibrs, IBRS_IBPB); ++ else ++ fails += CHECK_PROC (ibrs, AMD_IBRS); + fails += CHECK_PROC (stibp, AMD_STIBP); + } + fails += CHECK_PROC (ibt, IBT); diff --git a/SOURCES/glibc-upstream-2.34-59.patch b/SOURCES/glibc-upstream-2.34-59.patch new file mode 100644 index 0000000..b0ea00c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-59.patch @@ -0,0 +1,35 @@ +commit 5daf13b1e637eec0f7a2de05b177cb0d76479aa2 +Author: Matheus Castanho +Date: Wed Dec 1 11:14:40 2021 -0300 + + powerpc64[le]: Allocate extra stack frame on syscall.S + + The syscall function does not allocate the extra stack frame for scv like other + assembly syscalls using DO_CALL_SCV. So after commit d120fb9941 changed the + offset that is used to save LR, syscall ended up using an invalid offset, + causing regressions on powerpc64. So make sure the extra stack frame is + allocated in syscall.S as well to make it consistent with other uses of + DO_CALL_SCV and avoid similar issues in the future. + + Tested on powerpc, powerpc64, and powerpc64le (with and without scv) + + Reviewed-by: Raphael M Zinsly + + (cherry picked from commit ae91d3df24a4a1b1f264d101a71a298bff310d14) + +diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S +index a29652feaf6764cf..a5497c8370982fe3 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/syscall.S ++++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S +@@ -27,7 +27,11 @@ ENTRY (syscall) + mr r8,r9 + #if defined(USE_PPC_SCV) && !IS_IN(rtld) && (defined(__PPC64__) || defined(__powerpc64__)) + CHECK_SCV_SUPPORT r9 0f ++ stdu r1,-SCV_FRAME_SIZE(r1) ++ cfi_adjust_cfa_offset(SCV_FRAME_SIZE) + DO_CALL_SCV ++ addi r1,r1,SCV_FRAME_SIZE ++ cfi_adjust_cfa_offset(-SCV_FRAME_SIZE) + RET_SCV + b 1f + #endif diff --git a/SOURCES/glibc-upstream-2.34-60.patch b/SOURCES/glibc-upstream-2.34-60.patch new file mode 100644 index 0000000..60d2765 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-60.patch @@ -0,0 +1,32 @@ +commit 9de8011c328021f10588a8acb418daf5121d5f3d +Author: Aurelien Jarno +Date: Tue Dec 14 22:44:35 2021 +0100 + + riscv: align stack in clone [BZ #28702] + + The RISC-V ABI [1] mandates that "the stack pointer shall be aligned to + a 128-bit boundary upon procedure entry". This as not the case in clone. + + This fixes the misc/tst-misalign-clone-internal and + misc/tst-misalign-clone tests. + + Fixes bug 28702. + + [1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc + + (cherry picked from commit d2e594d71509faf36cf851a69370db34a4f5fa65) + +diff --git a/sysdeps/unix/sysv/linux/riscv/clone.S b/sysdeps/unix/sysv/linux/riscv/clone.S +index 12f91a20d3bb34f5..161e83c7e3786b8d 100644 +--- a/sysdeps/unix/sysv/linux/riscv/clone.S ++++ b/sysdeps/unix/sysv/linux/riscv/clone.S +@@ -32,6 +32,9 @@ + .text + LEAF (__clone) + ++ /* Align stack to a 128-bit boundary as per RISC-V ABI. */ ++ andi a1,a1,ALMASK ++ + /* Sanity check arguments. */ + beqz a0,L (invalid) /* No NULL function pointers. */ + beqz a1,L (invalid) /* No NULL stack pointers. */ diff --git a/SOURCES/glibc-upstream-2.34-61.patch b/SOURCES/glibc-upstream-2.34-61.patch new file mode 100644 index 0000000..82214de --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-61.patch @@ -0,0 +1,34 @@ +commit aa3a97496c82a8443039248ebee650322c9480f4 +Author: Aurelien Jarno +Date: Thu Dec 16 00:06:28 2021 +0100 + + riscv: align stack before calling _dl_init [BZ #28703] + + Align the stack pointer to 128 bits during the call to _dl_init() as + specified by the RISC-V ABI [1]. This fixes the elf/tst-align2 test. + + Fixes bug 28703. + + [1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc + + (cherry picked from commit 225da459cebef1037dcd78b56471edc0721e1c41) + +diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h +index aedf69fcdd8aff50..951268923da26a37 100644 +--- a/sysdeps/riscv/dl-machine.h ++++ b/sysdeps/riscv/dl-machine.h +@@ -127,8 +127,14 @@ elf_machine_load_address (void) + sll a3, a1, " STRINGXP (PTRLOG) "\n\ + add a3, a3, a2\n\ + add a3, a3, " STRINGXP (SZREG) "\n\ ++ # Stash the stack pointer in s1.\n\ ++ mv s1, sp\n\ ++ # Align stack to 128 bits for the _dl_init call.\n\ ++ andi sp, sp,-16\n\ + # Call the function to run the initializers.\n\ + jal _dl_init\n\ ++ # Restore the stack pointer for _start.\n\ ++ mv sp, s1\n\ + # Pass our finalizer function to _start.\n\ + lla a0, _dl_fini\n\ + # Jump to the user entry point.\n\ diff --git a/SOURCES/glibc-upstream-2.34-62.patch b/SOURCES/glibc-upstream-2.34-62.patch new file mode 100644 index 0000000..656bcfb --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-62.patch @@ -0,0 +1,21 @@ +commit 4029747c592cb2d59805b3a4e7a8963fcdcdbeb1 +Author: John David Anglin +Date: Mon Sep 6 17:37:29 2021 +0000 + + Update hppa libm-test-ulps + + (cherry picked from commit d8cf84ac7e504663dfeb2bb45d8d48ae81effe05) + +diff --git a/sysdeps/hppa/fpu/libm-test-ulps b/sysdeps/hppa/fpu/libm-test-ulps +index 90e16a72692e9199..3d60fc25a14d053f 100644 +--- a/sysdeps/hppa/fpu/libm-test-ulps ++++ b/sysdeps/hppa/fpu/libm-test-ulps +@@ -1104,7 +1104,7 @@ float: 8 + ldouble: 1 + + Function: "tgamma_downward": +-double: 8 ++double: 9 + float: 7 + + Function: "tgamma_towardzero": diff --git a/SOURCES/glibc-upstream-2.34-63.patch b/SOURCES/glibc-upstream-2.34-63.patch new file mode 100644 index 0000000..e0944e1 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-63.patch @@ -0,0 +1,21 @@ +commit e94544c82f4ac37017589d8d83156d72388fc4af +Author: Adhemerval Zanella +Date: Wed Aug 4 21:40:32 2021 +0300 + + Update sparc libm-test-ulps + + (cherry picked from commit c52eb066bc634a79e4194457362384abe5b43b3a) + +diff --git a/sysdeps/sparc/fpu/libm-test-ulps b/sysdeps/sparc/fpu/libm-test-ulps +index c2e4649524aa3a44..f34bbe6c592814d0 100644 +--- a/sysdeps/sparc/fpu/libm-test-ulps ++++ b/sysdeps/sparc/fpu/libm-test-ulps +@@ -1346,7 +1346,7 @@ float: 8 + ldouble: 4 + + Function: "tgamma_downward": +-double: 8 ++double: 9 + float: 7 + ldouble: 5 + diff --git a/SOURCES/glibc-upstream-2.34-64.patch b/SOURCES/glibc-upstream-2.34-64.patch new file mode 100644 index 0000000..54ae960 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-64.patch @@ -0,0 +1,81 @@ +commit 1d9764aba8c00754fbf8299e48afbe222245ee3e +Author: Adhemerval Zanella +Date: Wed Aug 4 21:34:12 2021 +0300 + + linux: Add sparck brk implementation + + It turned that the generic implementation of brk() does not work + for sparc, since on failure kernel will just return the previous + input value without setting the conditional register. + + This patches adds back a sparc32 and sparc64 implementation removed + by 720480934ab9107. + + Checked on sparc64-linux-gnu and sparcv9-linux-gnu. + + (cherry picked from commit 5b86241a032c50462988bdd1439e078384690d34) + +diff --git a/sysdeps/unix/sysv/linux/sparc/brk.c b/sysdeps/unix/sysv/linux/sparc/brk.c +new file mode 100644 +index 0000000000000000..aafe9673e3062cf8 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sparc/brk.c +@@ -0,0 +1,58 @@ ++/* Change data segment. Linux SPARC version. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* This must be initialized data because commons can't have aliases. */ ++void *__curbrk = 0; ++ ++#if HAVE_INTERNAL_BRK_ADDR_SYMBOL ++/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt ++ to work around different old braindamage in the old Linux ELF dynamic ++ linker. */ ++weak_alias (__curbrk, ___brk_addr) ++#endif ++ ++#ifdef __arch64__ ++# define SYSCALL_NUM "0x6d" ++#else ++# define SYSCALL_NUM "0x10" ++#endif ++ ++int ++__brk (void *addr) ++{ ++ register long int g1 asm ("g1") = __NR_brk; ++ register long int o0 asm ("o0") = (long int) addr; ++ asm volatile ("ta " SYSCALL_NUM ++ : "=r"(o0) ++ : "r"(g1), "0"(o0) ++ : "cc"); ++ __curbrk = (void *) o0; ++ ++ if (__curbrk < addr) ++ { ++ __set_errno (ENOMEM); ++ return -1; ++ } ++ ++ return 0; ++} ++weak_alias (__brk, brk) diff --git a/SOURCES/glibc-upstream-2.34-65.patch b/SOURCES/glibc-upstream-2.34-65.patch new file mode 100644 index 0000000..6644c9d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-65.patch @@ -0,0 +1,33 @@ +commit 8ad6d6d8ed33631bd2ca5d1112e6da2f92731432 +Author: maminjie +Date: Mon Dec 20 19:36:32 2021 +0800 + + Linux: Fix 32-bit vDSO for clock_gettime on powerpc32 + + When the clock_id is CLOCK_PROCESS_CPUTIME_ID or CLOCK_THREAD_CPUTIME_ID, + on the 5.10 kernel powerpc 32-bit, the 32-bit vDSO is executed successfully ( + because the __kernel_clock_gettime in arch/powerpc/kernel/vdso32/gettimeofday.S + does not support these two IDs, the 32-bit time_t syscall will be used), + but tp32.tv_sec is equal to 0, causing the 64-bit time_t syscall to continue to be used, + resulting in two system calls. + + Fix commit 72e84d1db22203e01a43268de71ea8669eca2863. + + Signed-off-by: maminjie + Reviewed-by: Adhemerval Zanella + + (cherry picked from commit e0fc721ce600038dd390e77cfe52440707ef574d) + +diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c +index 91df6b3d967bf945..9c7d9073254843c7 100644 +--- a/sysdeps/unix/sysv/linux/clock_gettime.c ++++ b/sysdeps/unix/sysv/linux/clock_gettime.c +@@ -53,7 +53,7 @@ __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp) + { + struct timespec tp32; + r = INTERNAL_VSYSCALL_CALL (vdso_time, 2, clock_id, &tp32); +- if (r == 0 && tp32.tv_sec > 0) ++ if (r == 0 && tp32.tv_sec >= 0) + { + *tp = valid_timespec_to_timespec64 (tp32); + return 0; diff --git a/SOURCES/glibc-upstream-2.34-66.patch b/SOURCES/glibc-upstream-2.34-66.patch new file mode 100644 index 0000000..9619100 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-66.patch @@ -0,0 +1,37 @@ +commit 41fddc064ded5c9a36d8ffaad59a85407a22a535 +Author: Andrea Monaco +Date: Sun Dec 12 10:24:28 2021 +0100 + + intl/plural.y: Avoid conflicting declarations of yyerror and yylex + + bison-3.8 includes these lines in the generated intl/plural.c: + + #if !defined __gettexterror && !defined YYERROR_IS_DECLARED + void __gettexterror (struct parse_args *arg, const char *msg); + #endif + #if !defined __gettextlex && !defined YYLEX_IS_DECLARED + int __gettextlex (YYSTYPE *yylvalp, struct parse_args *arg); + #endif + + Those default prototypes provided by bison conflict with the + declarations later on in plural.y. This patch solves the issue. + + Reviewed-by: Arjun Shankar + (cherry picked from commit c6d7d6312c21bbcfb236d48bb7c11cedb234389f) + +diff --git a/intl/plural.y b/intl/plural.y +index e02e74541c4574eb..2ee128ba01b5820d 100644 +--- a/intl/plural.y ++++ b/intl/plural.y +@@ -40,6 +40,11 @@ + # define __gettextparse PLURAL_PARSE + #endif + ++/* Later we provide those prototypes. Without these macros, bison may ++ generate its own prototypes with possible conflicts. */ ++#define YYLEX_IS_DECLARED ++#define YYERROR_IS_DECLARED ++ + %} + %parse-param {struct parse_args *arg} + %lex-param {struct parse_args *arg} diff --git a/SOURCES/glibc-upstream-2.34-67.patch b/SOURCES/glibc-upstream-2.34-67.patch new file mode 100644 index 0000000..2ee0841 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-67.patch @@ -0,0 +1,50 @@ +commit 217b84127b3a6590afcc7e198e6c3f665935e8f4 +Author: Wilco Dijkstra +Date: Thu Jan 6 14:36:28 2022 +0000 + + AArch64: Check for SVE in ifuncs [BZ #28744] + + Add a check for SVE in the A64FX ifuncs for memcpy, memset and memmove. + This fixes BZ #28744. + + (cherry picked from commit e5fa62b8db546f8792ec9e5c61e6419f4f8e3f4d) + +diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c +index 25e0081eeb51727c..b6703af44b3f1a3d 100644 +--- a/sysdeps/aarch64/multiarch/memcpy.c ++++ b/sysdeps/aarch64/multiarch/memcpy.c +@@ -48,7 +48,7 @@ libc_ifunc (__libc_memcpy, + || IS_NEOVERSE_V1 (midr) + ? __memcpy_simd + # if HAVE_AARCH64_SVE_ASM +- : (IS_A64FX (midr) ++ : (IS_A64FX (midr) && sve + ? __memcpy_a64fx + : __memcpy_generic)))))); + # else +diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c +index d0adefc547f60030..d2339ff34ff7b3e5 100644 +--- a/sysdeps/aarch64/multiarch/memmove.c ++++ b/sysdeps/aarch64/multiarch/memmove.c +@@ -48,7 +48,7 @@ libc_ifunc (__libc_memmove, + || IS_NEOVERSE_V1 (midr) + ? __memmove_simd + # if HAVE_AARCH64_SVE_ASM +- : (IS_A64FX (midr) ++ : (IS_A64FX (midr) && sve + ? __memmove_a64fx + : __memmove_generic)))))); + # else +diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c +index d7d9bbbda095e051..3d839bc02e96380d 100644 +--- a/sysdeps/aarch64/multiarch/memset.c ++++ b/sysdeps/aarch64/multiarch/memset.c +@@ -44,7 +44,7 @@ libc_ifunc (__libc_memset, + : (IS_EMAG (midr) && zva_size == 64 + ? __memset_emag + # if HAVE_AARCH64_SVE_ASM +- : (IS_A64FX (midr) ++ : (IS_A64FX (midr) && sve + ? __memset_a64fx + : __memset_generic)))); + # else diff --git a/SOURCES/glibc-upstream-2.34-68.patch b/SOURCES/glibc-upstream-2.34-68.patch new file mode 100644 index 0000000..935e4f0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-68.patch @@ -0,0 +1,27 @@ +commit 515a6f53cd984d5e6e374fbee52772f967fc3c73 +Author: Paul Eggert +Date: Mon Sep 13 22:49:45 2021 -0700 + + Fix subscript error with odd TZif file [BZ #28338] + + * time/tzfile.c (__tzfile_compute): Fix unlikely off-by-one bug + that accessed before start of an array when an oddball-but-valid + TZif file was queried with an unusual time_t value. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 645277434a42efc547d2cac8bfede4da10b4049f) + +diff --git a/time/tzfile.c b/time/tzfile.c +index 4377018a55936389..190a777152b31cee 100644 +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -765,8 +765,7 @@ __tzfile_compute (__time64_t timer, int use_localtime, + *leap_correct = leaps[i].change; + + if (timer == leaps[i].transition /* Exactly at the transition time. */ +- && ((i == 0 && leaps[i].change > 0) +- || leaps[i].change > leaps[i - 1].change)) ++ && (leaps[i].change > (i == 0 ? 0 : leaps[i - 1].change))) + { + *leap_hit = 1; + while (i > 0 diff --git a/SOURCES/glibc-upstream-2.34-69.patch b/SOURCES/glibc-upstream-2.34-69.patch new file mode 100644 index 0000000..1346263 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-69.patch @@ -0,0 +1,52 @@ +commit 85b24f9694e21f1d2f2d8b80d3bf690687723347 +Author: Hans-Peter Nilsson +Date: Fri Dec 17 21:38:00 2021 +0100 + + timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707) + + When using a timezone file with a truncated starting time, + generated by the zic in IANA tzcode-2021d a.k.a. tzlib-2021d + (also in tzlib-2021e; current as of this writing), glibc + asserts in __tzfile_read (on e.g. tzset() for this file) and + you may find lines matching "tzfile.c:435: __tzfile_read: + Assertion `num_types == 1' failed" in your syslog. + + One example of such a file is the tzfile for Asuncion + generated by tzlib-2021e as follows, using the tzlib-2021e zic: + "zic -d DEST -r @1546300800 -L /dev/null -b slim + SOURCE/southamerica". Note that in its type 2 header, it has + two entries in its "time-types" array (types), but only one + entry in its "transition types" array (type_idxs). + + This is valid and expected already in the published RFC8536, and + not even frowned upon: "Local time for timestamps before the + first transition is specified by the first time type (time type + 0)" ... "every nonzero local time type index SHOULD appear at + least once in the transition type array". Note the "nonzero ... + index". Until the 2021d zic, index 0 has been shared by the + first valid transition but with 2021d it's separate, set apart + as a placeholder and only "implicitly" indexed. (A draft update + of the RFC mandates that the entry at index 0 is a placeholder + in this case, hence can no longer be shared.) + + * time/tzfile.c (__tzfile_read): Don't assert when no transitions + are found. + + Co-authored-by: Christopher Wong + (cherry picked from commit c36f64aa6dff13b12a1e03a185e75a50fa9f6a4c) + +diff --git a/time/tzfile.c b/time/tzfile.c +index 190a777152b31cee..8668392ad387af05 100644 +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -431,8 +431,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + if (__tzname[0] == NULL) + { + /* This should only happen if there are no transition rules. +- In this case there should be only one single type. */ +- assert (num_types == 1); ++ In this case there's usually only one single type, unless ++ e.g. the data file has a truncated time-range. */ + __tzname[0] = __tzstring (zone_names); + } + if (__tzname[1] == NULL) diff --git a/SOURCES/glibc-upstream-2.34-70.patch b/SOURCES/glibc-upstream-2.34-70.patch new file mode 100644 index 0000000..b83ae03 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-70.patch @@ -0,0 +1,130 @@ +commit d5ba02f67dd62a63e29c29eebd6c543722aa6b5b +Author: Hans-Peter Nilsson +Date: Fri Dec 17 21:45:54 2021 +0100 + + timezone: test-case for BZ #28707 + + This test-case is the tzfile for Asuncion generated by + tzlib-2021e as follows, using the tzlib-2021e zic: "zic -d + DEST -r @1546300800 -L /dev/null -b slim + SOURCE/southamerica". Note that in its type 2 header, it + has two entries in its "time-types" array (types), but only + one entry in its "transition types" array (type_idxs). + + * timezone/Makefile, timezone/tst-pr28707.c, + timezone/testdata/gen-XT5.sh: New test. + + Co-authored-by: Christopher Wong + (cherry picked from commit ebe899af0dc3215159a9c896ac6f35b72a18cb6e) + +diff --git a/timezone/Makefile b/timezone/Makefile +index c624a189b322cb5f..f091663b8bbbceda 100644 +--- a/timezone/Makefile ++++ b/timezone/Makefile +@@ -23,7 +23,7 @@ subdir := timezone + include ../Makeconfig + + others := zdump zic +-tests := test-tz tst-timezone tst-tzset ++tests := test-tz tst-timezone tst-tzset tst-bz28707 + + generated-dirs += testdata + +@@ -85,10 +85,12 @@ $(objpfx)tst-timezone.out: $(addprefix $(testdata)/, \ + America/Sao_Paulo Asia/Tokyo \ + Europe/London) + $(objpfx)tst-tzset.out: $(addprefix $(testdata)/XT, 1 2 3 4) ++$(objpfx)tst-bz28707.out: $(testdata)/XT5 + + test-tz-ENV = TZDIR=$(testdata) + tst-timezone-ENV = TZDIR=$(testdata) + tst-tzset-ENV = TZDIR=$(testdata) ++tst-bz28707-ENV = TZDIR=$(testdata) + + # Note this must come second in the deps list for $(built-program-cmd) to work. + zic-deps = $(objpfx)zic $(leapseconds) yearistype +@@ -122,6 +124,10 @@ $(testdata)/XT%: testdata/XT% + $(make-target-directory) + cp $< $@ + ++$(testdata)/XT%: testdata/gen-XT%.sh ++ $(SHELL) $< > $@.tmp ++ mv $@.tmp $@ ++ + $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make + sed -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \ + -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \ +diff --git a/timezone/testdata/gen-XT5.sh b/timezone/testdata/gen-XT5.sh +new file mode 100755 +index 0000000000000000..3cea0569eb5a6a57 +--- /dev/null ++++ b/timezone/testdata/gen-XT5.sh +@@ -0,0 +1,16 @@ ++#! /bin/sh ++ ++# This test-case is the tzfile for America/Asuncion ++# generated by tzlib-2021e as follows, using the tzlib-2021e ++# zic: "zic -d DEST -r @1546300800 -L /dev/null -b slim ++# SOURCE/southamerica". Note that in its type 2 header, it ++# has two entries in its "time-types" array (types), but ++# only one entry in its "transition types" array ++# (type_idxs). ++ ++printf \ ++'TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'\ ++'\0\0\0\0\0\0\0\1\0\0\0\1\0\0\0\0\0\0\0TZif2\0\0\0\0\0\0\0\0'\ ++'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\2\0\0\0\b\0'\ ++'\0\0\0\*\255\200\1\0\0\0\0\0\0\377\377\325\320\1\4-00\0-03\0\n'\ ++'<-04>4<-03>,M10.1.0/0,M3.4.0/0\n' +diff --git a/timezone/tst-bz28707.c b/timezone/tst-bz28707.c +new file mode 100644 +index 0000000000000000..0a9df1e9a094f1e9 +--- /dev/null ++++ b/timezone/tst-bz28707.c +@@ -0,0 +1,46 @@ ++/* Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* Test that we can use a truncated timezone-file, where the time-type ++ at index 0 is not indexed by the transition-types array (and the ++ transition-types array does not contain at least both one DST and one ++ normal time members). */ ++ ++static int ++do_test (void) ++{ ++ if (setenv ("TZ", "XT5", 1)) ++ { ++ puts ("setenv failed."); ++ return 1; ++ } ++ ++ tzset (); ++ ++ return ++ /* Sanity-check that we got the right timezone-name for DST. For ++ normal time, we're likely to get "-00" (the "unspecified" marker), ++ even though the POSIX timezone string says "-04". Let's not test ++ that. */ ++ !(strcmp (tzname[1], "-03") == 0); ++} ++#include diff --git a/SOURCES/glibc-upstream-2.34-71.patch b/SOURCES/glibc-upstream-2.34-71.patch new file mode 100644 index 0000000..4e534ed --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-71.patch @@ -0,0 +1,39 @@ +commit e64235ff4266e87b20505101877fe57350ab69ab +Author: Paul A. Clarke +Date: Tue Sep 14 13:13:33 2021 -0500 + + powerpc: Fix unrecognized instruction errors with recent GCC + + Recent binutils commit b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a + changes the behavior of `.machine` directives to override, rather + than augment, the base CPU. This can result in _reduced_ functionality + when, for example, compiling for default machine "power8", but explicitly + asking for ".machine power5", which loses Altivec instructions. + + In tst-ucontext-ppc64-vscr.c, while the instructions provoking the new + error messages are bracketed by ".machine power5", which is ostensibly + Power ISA 2.03 (POWER5), the POWER5 processor did not support the + VSX subset, so these instructions are not recognized as "power5". + + Error: unrecognized opcode: `vspltisb' + Error: unrecognized opcode: `vpkuwus' + Error: unrecognized opcode: `mfvscr' + Error: unrecognized opcode: `stvx' + + Manually adding the VSX subset via ".machine altivec" is sufficient. + + Reviewed-by: Tulio Magno Quites Machado Filho + (cherry picked from commit 064b475a2e5662b6b3973fabf505eade86e61510) + +diff --git a/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c b/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c +index 28c87fcef72bded6..d3fc4ab589f4752a 100644 +--- a/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c ++++ b/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c +@@ -50,6 +50,7 @@ do_test (void) + /* Set SAT bit in VSCR register. */ + asm volatile (".machine push;\n" + ".machine \"power5\";\n" ++ ".machine altivec;\n" + "vspltisb %0,0;\n" + "vspltisb %1,-1;\n" + "vpkuwus %0,%0,%1;\n" diff --git a/SOURCES/glibc-upstream-2.34-72.patch b/SOURCES/glibc-upstream-2.34-72.patch new file mode 100644 index 0000000..548e54e --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-72.patch @@ -0,0 +1,377 @@ +commit 73558ffe841cf4c60ccb4c71cf6dcebf84f2b736 +Author: Joseph Myers +Date: Wed Nov 10 15:21:19 2021 +0000 + + Update syscall lists for Linux 5.15 + + Linux 5.15 has one new syscall, process_mrelease (and also enables the + clone3 syscall for RV32). It also has a macro __NR_SYSCALL_MASK for + Arm, which is not a syscall but matches the pattern used for syscall + macro names. + + Add __NR_SYSCALL_MASK to the names filtered out in the code dealing + with syscall lists, update syscall-names.list for the new syscall and + regenerate the arch-syscall.h headers with build-many-glibcs.py + update-syscalls. + + Tested with build-many-glibcs.py. + + (cherry picked from commit 3387c40a8bbad5faf85b1feb56429cb20feaa640) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +index bedab1abbac7f6c1..74a809561a45edc4 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +@@ -180,6 +180,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6 72 +diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +index 91354ed9e29b8d15..6fc0a23504c3b53d 100644 +--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +@@ -328,6 +328,7 @@ + #define __NR_preadv2 520 + #define __NR_prlimit64 496 + #define __NR_process_madvise 550 ++#define __NR_process_mrelease 558 + #define __NR_process_vm_readv 504 + #define __NR_process_vm_writev 505 + #define __NR_pselect6 463 +diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +index ff5c7eb36db89494..0c66762bf868a992 100644 +--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +@@ -182,6 +182,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6_time64 413 +diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +index 5772333ceef6ce59..c41a864c6d530eb0 100644 +--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +@@ -235,6 +235,7 @@ + #define __NR_preadv2 392 + #define __NR_prlimit64 369 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 376 + #define __NR_process_vm_writev 377 + #define __NR_pselect6 335 +diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +index 4af6d6202f6df7ae..863ffa3e0cd34d3e 100644 +--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +@@ -190,6 +190,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6 72 +diff --git a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk +index dddfd517471e5cc9..85b017918ef20736 100644 +--- a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk ++++ b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk +@@ -22,7 +22,7 @@ + } + + # Skip pseudo-system calls which describe ranges. +-/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) / { ++/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE|SYSCALL_MASK) / { + next; + } + /^#define __NR_(|64_|[NO]32_)Linux(_syscalls)? / { +diff --git a/sysdeps/unix/sysv/linux/glibcsyscalls.py b/sysdeps/unix/sysv/linux/glibcsyscalls.py +index 621a202ed75cd725..fe7896eebe74cdf4 100644 +--- a/sysdeps/unix/sysv/linux/glibcsyscalls.py ++++ b/sysdeps/unix/sysv/linux/glibcsyscalls.py +@@ -41,7 +41,7 @@ RE_PSEUDO_SYSCALL = re.compile(r"""__NR_( + (unused|reserved)[0-9]+ + + # Pseudo-system call which describes a range. +- |(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) ++ |(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE|SYSCALL_MASK) + |(|64_|[NO]32_)Linux(_syscalls)? + )""", re.X) + +diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +index b07fc8549de34157..6cf27cd17c1ad0c0 100644 +--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +@@ -222,6 +222,7 @@ + #define __NR_preadv2 347 + #define __NR_prlimit64 321 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 330 + #define __NR_process_vm_writev 331 + #define __NR_pselect6 273 +diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +index 6e4264698b5ce480..2512508b7daa8ed2 100644 +--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +@@ -254,6 +254,7 @@ + #define __NR_preadv2 378 + #define __NR_prlimit64 340 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 347 + #define __NR_process_vm_writev 348 + #define __NR_prof 44 +diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +index 1ca706d7216a3902..4a0c737369217367 100644 +--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +@@ -209,6 +209,7 @@ + #define __NR_preadv2 1348 + #define __NR_prlimit64 1325 + #define __NR_process_madvise 1464 ++#define __NR_process_mrelease 1472 + #define __NR_process_vm_readv 1332 + #define __NR_process_vm_writev 1333 + #define __NR_pselect6 1294 +diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +index 2f10f71f90d225ff..e310eb5075fb22d8 100644 +--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +@@ -243,6 +243,7 @@ + #define __NR_preadv2 377 + #define __NR_prlimit64 339 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 345 + #define __NR_process_vm_writev 346 + #define __NR_pselect6 301 +diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +index 0607a4dfa6adaa23..b4ecad010c2a6abf 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +@@ -253,6 +253,7 @@ + #define __NR_preadv2 393 + #define __NR_prlimit64 370 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 377 + #define __NR_process_vm_writev 378 + #define __NR_prof 44 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +index 0055eec0b169ba96..7e3d138ba969c57b 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +@@ -238,6 +238,7 @@ + #define __NR_preadv2 4361 + #define __NR_prlimit64 4338 + #define __NR_process_madvise 4440 ++#define __NR_process_mrelease 4448 + #define __NR_process_vm_readv 4345 + #define __NR_process_vm_writev 4346 + #define __NR_prof 4044 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +index 8e8e9f91ccfebfab..7e9e232e5256bc89 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +@@ -221,6 +221,7 @@ + #define __NR_preadv2 6325 + #define __NR_prlimit64 6302 + #define __NR_process_madvise 6440 ++#define __NR_process_mrelease 6448 + #define __NR_process_vm_readv 6309 + #define __NR_process_vm_writev 6310 + #define __NR_pselect6 6264 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +index ebd1545f806564bb..f9e7ef72b0aa1749 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +@@ -209,6 +209,7 @@ + #define __NR_preadv2 5321 + #define __NR_prlimit64 5297 + #define __NR_process_madvise 5440 ++#define __NR_process_mrelease 5448 + #define __NR_process_vm_readv 5304 + #define __NR_process_vm_writev 5305 + #define __NR_pselect6 5260 +diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +index 2b530b1f88e4c52a..afd73fc1daca1fb4 100644 +--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +@@ -189,6 +189,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6 72 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +index a32984a9c17315ee..0ac2992028eda27e 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +@@ -247,6 +247,7 @@ + #define __NR_preadv2 380 + #define __NR_prlimit64 325 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 351 + #define __NR_process_vm_writev 352 + #define __NR_prof 44 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +index b01e464fb906d632..c890bc644e14fe06 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +@@ -231,6 +231,7 @@ + #define __NR_preadv2 380 + #define __NR_prlimit64 325 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 351 + #define __NR_process_vm_writev 352 + #define __NR_prof 44 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index 24d0a2c455caa630..cd336d755a42598a 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -16,6 +16,7 @@ + #define __NR_clock_nanosleep_time64 407 + #define __NR_clock_settime64 404 + #define __NR_clone 220 ++#define __NR_clone3 435 + #define __NR_close 57 + #define __NR_close_range 436 + #define __NR_connect 203 +@@ -171,6 +172,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6_time64 413 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index e526c89ae7b285cc..8edd21620bb4ef64 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -179,6 +179,7 @@ + #define __NR_preadv2 286 + #define __NR_prlimit64 261 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 270 + #define __NR_process_vm_writev 271 + #define __NR_pselect6 72 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +index d4c7b101b64c010f..1a4873f505765617 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +@@ -240,6 +240,7 @@ + #define __NR_preadv2 376 + #define __NR_prlimit64 334 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 340 + #define __NR_process_vm_writev 341 + #define __NR_pselect6 301 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +index bd8c78d7059a0f31..2af4607c1d36d173 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +@@ -211,6 +211,7 @@ + #define __NR_preadv2 376 + #define __NR_prlimit64 334 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 340 + #define __NR_process_vm_writev 341 + #define __NR_pselect6 301 +diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +index 3b6ac3d084d74638..7b422ce268ba14d0 100644 +--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +@@ -237,6 +237,7 @@ + #define __NR_preadv2 381 + #define __NR_prlimit64 339 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 365 + #define __NR_process_vm_writev 366 + #define __NR_pselect6 308 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +index 35221a707e4d4a7c..77c3cc64f95ea7f3 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +@@ -242,6 +242,7 @@ + #define __NR_preadv2 358 + #define __NR_prlimit64 331 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 338 + #define __NR_process_vm_writev 339 + #define __NR_pselect6 297 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +index 5ba2b2050924df1c..7ad50bc4ad6cef04 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +@@ -222,6 +222,7 @@ + #define __NR_preadv2 358 + #define __NR_prlimit64 331 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 338 + #define __NR_process_vm_writev 339 + #define __NR_pselect6 297 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index fd98893b0e44a606..1a74d090b72f4d61 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.14. +-kernel 5.14 ++# The list of system calls is current as of Linux 5.15. ++kernel 5.15 + + FAST_atomic_update + FAST_cmpxchg +@@ -440,6 +440,7 @@ preadv + preadv2 + prlimit64 + process_madvise ++process_mrelease + process_vm_readv + process_vm_writev + prof +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +index 26d6ac68a651ec98..3ce2a1fcfc1c15f2 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +@@ -215,6 +215,7 @@ + #define __NR_preadv2 327 + #define __NR_prlimit64 302 + #define __NR_process_madvise 440 ++#define __NR_process_mrelease 448 + #define __NR_process_vm_readv 310 + #define __NR_process_vm_writev 311 + #define __NR_pselect6 270 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index 36847783f6b91d5e..9e87e89baccc397c 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -208,6 +208,7 @@ + #define __NR_preadv2 1073742370 + #define __NR_prlimit64 1073742126 + #define __NR_process_madvise 1073742264 ++#define __NR_process_mrelease 1073742272 + #define __NR_process_vm_readv 1073742363 + #define __NR_process_vm_writev 1073742364 + #define __NR_pselect6 1073742094 diff --git a/SOURCES/glibc-upstream-2.34-73.patch b/SOURCES/glibc-upstream-2.34-73.patch new file mode 100644 index 0000000..5081674 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-73.patch @@ -0,0 +1,442 @@ +commit 2fe2af88abd13ae5636881da2e26f461ecb7dfb5 +Author: Florian Weimer +Date: Thu Jan 13 14:59:29 2022 +0100 + + i386: Remove broken CAN_USE_REGISTER_ASM_EBP (bug 28771) + + The configure check for CAN_USE_REGISTER_ASM_EBP tried to compile a + simple function that uses %ebp as an inline assembly operand. If + compilation failed, CAN_USE_REGISTER_ASM_EBP was set 0, which + eventually had these consequences: + + (1) %ebx was avoided as an inline assembly operand, with an + assembler macro hack to avoid unnecessary register moves. + (2) %ebp was avoided as an inline assembly operand, using an + out-of-line syscall function for 6-argument system calls. + + (1) is no longer needed for any GCC version that is supported for + building glibc. %ebx can be used directly as a register operand. + Therefore, this commit removes the %ebx avoidance completely. This + avoids the assembler macro hack, which turns out to be incompatible + with the current Systemtap probe macros (which switch to .altmacro + unconditionally). + + (2) is still needed in many build configurations. The existing + configure check cannot really capture that because the simple function + succeeds to compile, while the full glibc build still fails. + Therefore, this commit removes the check, the CAN_USE_REGISTER_ASM_EBP + macro, and uses the out-of-line syscall function for 6-argument system + calls unconditionally. + + Reviewed-by: H.J. Lu + (cherry picked from commit a78e6a10d0b50d0ca80309775980fc99944b1727) + +diff --git a/config.h.in b/config.h.in +index 458342887e4e9380..790038fec60eb049 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -286,10 +286,6 @@ + /* Define if static PIE is enabled. */ + #define ENABLE_STATIC_PIE 0 + +-/* Some compiler options may now allow to use ebp in __asm__ (used mainly +- in i386 6 argument syscall issue). */ +-#define CAN_USE_REGISTER_ASM_EBP 0 +- + /* The default value of x86 CET control. */ + #define DEFAULT_DL_X86_CET_CONTROL cet_elf_property + +diff --git a/sysdeps/unix/sysv/linux/i386/configure b/sysdeps/unix/sysv/linux/i386/configure +index 0327590486c80777..f119e62fc31903b3 100644 +--- a/sysdeps/unix/sysv/linux/i386/configure ++++ b/sysdeps/unix/sysv/linux/i386/configure +@@ -1,44 +1,5 @@ + # This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/unix/sysv/linux/i386. + +-# Check if CFLAGS allows compiler to use ebp register in inline assembly. +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler flags allows ebp in inline assembly" >&5 +-$as_echo_n "checking if compiler flags allows ebp in inline assembly... " >&6; } +-if ${libc_cv_can_use_register_asm_ebp+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- void foo (int i) +- { +- register int reg asm ("ebp") = i; +- asm ("# %0" : : "r" (reg)); +- } +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- libc_cv_can_use_register_asm_ebp=yes +-else +- libc_cv_can_use_register_asm_ebp=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_can_use_register_asm_ebp" >&5 +-$as_echo "$libc_cv_can_use_register_asm_ebp" >&6; } +-if test $libc_cv_can_use_register_asm_ebp = yes; then +- $as_echo "#define CAN_USE_REGISTER_ASM_EBP 1" >>confdefs.h +- +-fi +- + libc_cv_gcc_unwind_find_fde=yes + ldd_rewrite_script=sysdeps/unix/sysv/linux/ldd-rewrite.sed +diff --git a/sysdeps/unix/sysv/linux/i386/configure.ac b/sysdeps/unix/sysv/linux/i386/configure.ac +index 9e980784bb826463..64ab2cc2c8f9deec 100644 +--- a/sysdeps/unix/sysv/linux/i386/configure.ac ++++ b/sysdeps/unix/sysv/linux/i386/configure.ac +@@ -1,22 +1,5 @@ + GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + # Local configure fragment for sysdeps/unix/sysv/linux/i386. + +-# Check if CFLAGS allows compiler to use ebp register in inline assembly. +-AC_CACHE_CHECK([if compiler flags allows ebp in inline assembly], +- libc_cv_can_use_register_asm_ebp, [ +-AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM([ +- void foo (int i) +- { +- register int reg asm ("ebp") = i; +- asm ("# %0" : : "r" (reg)); +- }])], +- [libc_cv_can_use_register_asm_ebp=yes], +- [libc_cv_can_use_register_asm_ebp=no]) +-]) +-if test $libc_cv_can_use_register_asm_ebp = yes; then +- AC_DEFINE(CAN_USE_REGISTER_ASM_EBP) +-fi +- + libc_cv_gcc_unwind_find_fde=yes + ldd_rewrite_script=sysdeps/unix/sysv/linux/ldd-rewrite.sed +diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h +index 8a9911b7acd9e692..39d6a3c13427abb5 100644 +--- a/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ b/sysdeps/unix/sysv/linux/i386/sysdep.h +@@ -43,15 +43,6 @@ + # endif + #endif + +-/* Since GCC 5 and above can properly spill %ebx with PIC when needed, +- we can inline syscalls with 6 arguments if GCC 5 or above is used +- to compile glibc. Disable GCC 5 optimization when compiling for +- profiling or when -fno-omit-frame-pointer is used since asm ("ebp") +- can't be used to put the 6th argument in %ebp for syscall. */ +-#if !defined PROF && CAN_USE_REGISTER_ASM_EBP +-# define OPTIMIZE_FOR_GCC_5 +-#endif +- + #ifdef __ASSEMBLER__ + + /* Linux uses a negative return value to indicate syscall errors, +@@ -239,36 +230,6 @@ + extern int __syscall_error (int) + attribute_hidden __attribute__ ((__regparm__ (1))); + +-#ifndef OPTIMIZE_FOR_GCC_5 +-/* We need some help from the assembler to generate optimal code. We +- define some macros here which later will be used. */ +-asm (".L__X'%ebx = 1\n\t" +- ".L__X'%ecx = 2\n\t" +- ".L__X'%edx = 2\n\t" +- ".L__X'%eax = 3\n\t" +- ".L__X'%esi = 3\n\t" +- ".L__X'%edi = 3\n\t" +- ".L__X'%ebp = 3\n\t" +- ".L__X'%esp = 3\n\t" +- ".macro bpushl name reg\n\t" +- ".if 1 - \\name\n\t" +- ".if 2 - \\name\n\t" +- "error\n\t" +- ".else\n\t" +- "xchgl \\reg, %ebx\n\t" +- ".endif\n\t" +- ".endif\n\t" +- ".endm\n\t" +- ".macro bpopl name reg\n\t" +- ".if 1 - \\name\n\t" +- ".if 2 - \\name\n\t" +- "error\n\t" +- ".else\n\t" +- "xchgl \\reg, %ebx\n\t" +- ".endif\n\t" +- ".endif\n\t" +- ".endm\n\t"); +- + /* Six-argument syscalls use an out-of-line helper, because an inline + asm using all registers apart from %esp cannot work reliably and + the assembler does not support describing an asm that saves and +@@ -279,7 +240,6 @@ struct libc_do_syscall_args + { + int ebx, edi, ebp; + }; +-#endif + + # define VDSO_NAME "LINUX_2.6" + # define VDSO_HASH 61765110 +@@ -332,14 +292,8 @@ struct libc_do_syscall_args + + /* Each object using 6-argument inline syscalls must include a + definition of __libc_do_syscall. */ +-#ifdef OPTIMIZE_FOR_GCC_5 +-# define INTERNAL_SYSCALL_MAIN_6(name, args...) \ +- INTERNAL_SYSCALL_MAIN_INLINE(name, 6, args) +-# define INTERNAL_SYSCALL_MAIN_NCS_6(name, args...) \ +- INTERNAL_SYSCALL_MAIN_NCS(name, 6, args) +-#else /* GCC 5 */ +-# define INTERNAL_SYSCALL_MAIN_6(name, arg1, arg2, arg3, \ +- arg4, arg5, arg6) \ ++#define INTERNAL_SYSCALL_MAIN_6(name, arg1, arg2, arg3, \ ++ arg4, arg5, arg6) \ + struct libc_do_syscall_args _xv = \ + { \ + (int) (arg1), \ +@@ -352,8 +306,8 @@ struct libc_do_syscall_args + : "=a" (resultvar) \ + : "i" (__NR_##name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \ + : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS_6(name, arg1, arg2, arg3, \ +- arg4, arg5, arg6) \ ++#define INTERNAL_SYSCALL_MAIN_NCS_6(name, arg1, arg2, arg3, \ ++ arg4, arg5, arg6) \ + struct libc_do_syscall_args _xv = \ + { \ + (int) (arg1), \ +@@ -366,7 +320,6 @@ struct libc_do_syscall_args + : "=a" (resultvar) \ + : "a" (name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \ + : "memory", "cc") +-#endif /* GCC 5 */ + + #define INTERNAL_SYSCALL(name, nr, args...) \ + ({ \ +@@ -380,193 +333,72 @@ struct libc_do_syscall_args + (int) resultvar; }) + + #if I386_USE_SYSENTER +-# ifdef OPTIMIZE_FOR_GCC_5 +-# ifdef PIC +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ ++# ifdef PIC ++# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "call *%%gs:%P2" \ + : "=a" (resultvar) \ + : "a" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \ + ASMARGS_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ ++# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "call *%%gs:%P2" \ + : "=a" (resultvar) \ + : "a" (name), "i" (offsetof (tcbhead_t, sysinfo)) \ + ASMARGS_##nr(args) : "memory", "cc") +-# else +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ ++# else /* I386_USE_SYSENTER && !PIC */ ++# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "call *_dl_sysinfo" \ + : "=a" (resultvar) \ + : "a" (__NR_##name) ASMARGS_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ ++# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "call *_dl_sysinfo" \ + : "=a" (resultvar) \ + : "a" (name) ASMARGS_##nr(args) : "memory", "cc") +-# endif +-# else /* GCC 5 */ +-# ifdef PIC +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "movl %1, %%eax\n\t" \ +- "call *%%gs:%P2\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \ +- ASMFMT_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "call *%%gs:%P2\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \ +- ASMFMT_##nr(args) : "memory", "cc") +-# else +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "movl %1, %%eax\n\t" \ +- "call *_dl_sysinfo\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "call *_dl_sysinfo\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "0" (name) ASMFMT_##nr(args) : "memory", "cc") +-# endif +-# endif /* GCC 5 */ +-#else +-# ifdef OPTIMIZE_FOR_GCC_5 +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ ++# endif /* I386_USE_SYSENTER && !PIC */ ++#else /* !I386_USE_SYSENTER */ ++# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "int $0x80" \ + : "=a" (resultvar) \ + : "a" (__NR_##name) ASMARGS_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ ++# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ + LOADREGS_##nr(args) \ + asm volatile ( \ + "int $0x80" \ + : "=a" (resultvar) \ + : "a" (name) ASMARGS_##nr(args) : "memory", "cc") +-# else /* GCC 5 */ +-# define INTERNAL_SYSCALL_MAIN_INLINE(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "movl %1, %%eax\n\t" \ +- "int $0x80\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc") +-# define INTERNAL_SYSCALL_MAIN_NCS(name, nr, args...) \ +- EXTRAVAR_##nr \ +- asm volatile ( \ +- LOADARGS_##nr \ +- "int $0x80\n\t" \ +- RESTOREARGS_##nr \ +- : "=a" (resultvar) \ +- : "0" (name) ASMFMT_##nr(args) : "memory", "cc") +-# endif /* GCC 5 */ +-#endif +- +-#define LOADARGS_0 +-#ifdef __PIC__ +-# if I386_USE_SYSENTER && defined PIC +-# define LOADARGS_1 \ +- "bpushl .L__X'%k3, %k3\n\t" +-# define LOADARGS_5 \ +- "movl %%ebx, %4\n\t" \ +- "movl %3, %%ebx\n\t" +-# else +-# define LOADARGS_1 \ +- "bpushl .L__X'%k2, %k2\n\t" +-# define LOADARGS_5 \ +- "movl %%ebx, %3\n\t" \ +- "movl %2, %%ebx\n\t" +-# endif +-# define LOADARGS_2 LOADARGS_1 +-# define LOADARGS_3 \ +- "xchgl %%ebx, %%edi\n\t" +-# define LOADARGS_4 LOADARGS_3 +-#else +-# define LOADARGS_1 +-# define LOADARGS_2 +-# define LOADARGS_3 +-# define LOADARGS_4 +-# define LOADARGS_5 +-#endif +- +-#define RESTOREARGS_0 +-#ifdef __PIC__ +-# if I386_USE_SYSENTER && defined PIC +-# define RESTOREARGS_1 \ +- "bpopl .L__X'%k3, %k3\n\t" +-# define RESTOREARGS_5 \ +- "movl %4, %%ebx" +-# else +-# define RESTOREARGS_1 \ +- "bpopl .L__X'%k2, %k2\n\t" +-# define RESTOREARGS_5 \ +- "movl %3, %%ebx" +-# endif +-# define RESTOREARGS_2 RESTOREARGS_1 +-# define RESTOREARGS_3 \ +- "xchgl %%edi, %%ebx\n\t" +-# define RESTOREARGS_4 RESTOREARGS_3 +-#else +-# define RESTOREARGS_1 +-# define RESTOREARGS_2 +-# define RESTOREARGS_3 +-# define RESTOREARGS_4 +-# define RESTOREARGS_5 +-#endif ++#endif /* !I386_USE_SYSENTER */ + +-#ifdef OPTIMIZE_FOR_GCC_5 +-# define LOADREGS_0() +-# define ASMARGS_0() +-# define LOADREGS_1(arg1) \ ++#define LOADREGS_0() ++#define ASMARGS_0() ++#define LOADREGS_1(arg1) \ + LOADREGS_0 () +-# define ASMARGS_1(arg1) \ ++#define ASMARGS_1(arg1) \ + ASMARGS_0 (), "b" ((unsigned int) (arg1)) +-# define LOADREGS_2(arg1, arg2) \ ++#define LOADREGS_2(arg1, arg2) \ + LOADREGS_1 (arg1) +-# define ASMARGS_2(arg1, arg2) \ ++#define ASMARGS_2(arg1, arg2) \ + ASMARGS_1 (arg1), "c" ((unsigned int) (arg2)) +-# define LOADREGS_3(arg1, arg2, arg3) \ ++#define LOADREGS_3(arg1, arg2, arg3) \ + LOADREGS_2 (arg1, arg2) +-# define ASMARGS_3(arg1, arg2, arg3) \ ++#define ASMARGS_3(arg1, arg2, arg3) \ + ASMARGS_2 (arg1, arg2), "d" ((unsigned int) (arg3)) +-# define LOADREGS_4(arg1, arg2, arg3, arg4) \ ++#define LOADREGS_4(arg1, arg2, arg3, arg4) \ + LOADREGS_3 (arg1, arg2, arg3) +-# define ASMARGS_4(arg1, arg2, arg3, arg4) \ ++#define ASMARGS_4(arg1, arg2, arg3, arg4) \ + ASMARGS_3 (arg1, arg2, arg3), "S" ((unsigned int) (arg4)) +-# define LOADREGS_5(arg1, arg2, arg3, arg4, arg5) \ ++#define LOADREGS_5(arg1, arg2, arg3, arg4, arg5) \ + LOADREGS_4 (arg1, arg2, arg3, arg4) +-# define ASMARGS_5(arg1, arg2, arg3, arg4, arg5) \ ++#define ASMARGS_5(arg1, arg2, arg3, arg4, arg5) \ + ASMARGS_4 (arg1, arg2, arg3, arg4), "D" ((unsigned int) (arg5)) +-# define LOADREGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \ +- register unsigned int _a6 asm ("ebp") = (unsigned int) (arg6); \ +- LOADREGS_5 (arg1, arg2, arg3, arg4, arg5) +-# define ASMARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \ +- ASMARGS_5 (arg1, arg2, arg3, arg4, arg5), "r" (_a6) +-#endif /* GCC 5 */ + + #define ASMFMT_0() + #ifdef __PIC__ diff --git a/SOURCES/glibc-upstream-2.34-74.patch b/SOURCES/glibc-upstream-2.34-74.patch new file mode 100644 index 0000000..15d3b62 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-74.patch @@ -0,0 +1,337 @@ +commit 705f1e4606aa78f4e861b4e3346725bf5f083a56 +Author: Joseph Myers +Date: Thu Jan 13 22:18:13 2022 +0000 + + Update syscall lists for Linux 5.16 + + Linux 5.16 has one new syscall, futex_waitv. Update + syscall-names.list and regenerate the arch-syscall.h headers with + build-many-glibcs.py update-syscalls. + + Tested with build-many-glibcs.py. + + (cherry picked from commit 4997a533ae4b51ef66a6b68862b7578a7acb82df) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +index 74a809561a45edc4..9905ebedf298954c 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +@@ -62,6 +62,7 @@ + #define __NR_fsync 82 + #define __NR_ftruncate 46 + #define __NR_futex 98 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +index 6fc0a23504c3b53d..ee8085be69958b25 100644 +--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +@@ -78,6 +78,7 @@ + #define __NR_fsync 95 + #define __NR_ftruncate 130 + #define __NR_futex 394 ++#define __NR_futex_waitv 559 + #define __NR_futimesat 454 + #define __NR_get_kernel_syms 309 + #define __NR_get_mempolicy 430 +diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +index 0c66762bf868a992..1b626d97705d545a 100644 +--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +@@ -65,6 +65,7 @@ + #define __NR_fsync 82 + #define __NR_ftruncate64 46 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +index c41a864c6d530eb0..96ef8db9368e7de4 100644 +--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +@@ -90,6 +90,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 240 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 326 + #define __NR_get_mempolicy 320 + #define __NR_get_robust_list 339 +diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +index 863ffa3e0cd34d3e..96910154ed6a5c1b 100644 +--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +@@ -70,6 +70,7 @@ + #define __NR_ftruncate64 46 + #define __NR_futex 98 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +index 6cf27cd17c1ad0c0..36675fd48e6f50c5 100644 +--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +@@ -87,6 +87,7 @@ + #define __NR_ftruncate64 200 + #define __NR_futex 210 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 279 + #define __NR_get_mempolicy 261 + #define __NR_get_robust_list 290 +diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +index 2512508b7daa8ed2..c86ccbda4681066c 100644 +--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +@@ -94,6 +94,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 240 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 299 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 275 +diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +index 4a0c737369217367..d898bce404955ef0 100644 +--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +@@ -74,6 +74,7 @@ + #define __NR_fsync 1051 + #define __NR_ftruncate 1098 + #define __NR_futex 1230 ++#define __NR_futex_waitv 1473 + #define __NR_futimesat 1285 + #define __NR_get_mempolicy 1260 + #define __NR_get_robust_list 1299 +diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +index e310eb5075fb22d8..fe721b809076abeb 100644 +--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +@@ -93,6 +93,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 235 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 292 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 269 +diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +index b4ecad010c2a6abf..6e10c3661db96a1e 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +@@ -94,6 +94,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 240 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 299 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 275 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +index 7e3d138ba969c57b..26a6d594a2222f15 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +@@ -93,6 +93,7 @@ + #define __NR_ftruncate64 4212 + #define __NR_futex 4238 + #define __NR_futex_time64 4422 ++#define __NR_futex_waitv 4449 + #define __NR_futimesat 4292 + #define __NR_get_kernel_syms 4130 + #define __NR_get_mempolicy 4269 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +index 7e9e232e5256bc89..83e0d49c5e3ca1bc 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +@@ -86,6 +86,7 @@ + #define __NR_ftruncate 6075 + #define __NR_futex 6194 + #define __NR_futex_time64 6422 ++#define __NR_futex_waitv 6449 + #define __NR_futimesat 6255 + #define __NR_get_kernel_syms 6170 + #define __NR_get_mempolicy 6232 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +index f9e7ef72b0aa1749..d6747c542f63202b 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +@@ -78,6 +78,7 @@ + #define __NR_fsync 5072 + #define __NR_ftruncate 5075 + #define __NR_futex 5194 ++#define __NR_futex_waitv 5449 + #define __NR_futimesat 5251 + #define __NR_get_kernel_syms 5170 + #define __NR_get_mempolicy 5228 +diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +index afd73fc1daca1fb4..4ee209bc4475ea7d 100644 +--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +@@ -69,6 +69,7 @@ + #define __NR_ftruncate64 46 + #define __NR_futex 98 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +index 0ac2992028eda27e..497299fbc47a708c 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +@@ -92,6 +92,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 221 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 290 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 260 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +index c890bc644e14fe06..e840279f171b10b9 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +@@ -81,6 +81,7 @@ + #define __NR_ftime 35 + #define __NR_ftruncate 93 + #define __NR_futex 221 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 290 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 260 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index cd336d755a42598a..73ef74c005e5a2bb 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -60,6 +60,7 @@ + #define __NR_fsync 82 + #define __NR_ftruncate64 46 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index 8edd21620bb4ef64..919a79ee91177459 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -62,6 +62,7 @@ + #define __NR_fsync 82 + #define __NR_ftruncate 46 + #define __NR_futex 98 ++#define __NR_futex_waitv 449 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +index 1a4873f505765617..005c0ada7aab85a1 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +@@ -91,6 +91,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 238 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 292 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 269 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +index 2af4607c1d36d173..9131fddcc16116e4 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +@@ -76,6 +76,7 @@ + #define __NR_fsync 118 + #define __NR_ftruncate 93 + #define __NR_futex 238 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 292 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 269 +diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +index 7b422ce268ba14d0..d8fb041568ecb4da 100644 +--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +@@ -90,6 +90,7 @@ + #define __NR_ftruncate64 194 + #define __NR_futex 240 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 299 + #define __NR_get_mempolicy 275 + #define __NR_get_robust_list 312 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +index 77c3cc64f95ea7f3..2bc014fe6a1a1f4a 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +@@ -92,6 +92,7 @@ + #define __NR_ftruncate64 84 + #define __NR_futex 142 + #define __NR_futex_time64 422 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 288 + #define __NR_get_kernel_syms 223 + #define __NR_get_mempolicy 304 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +index 7ad50bc4ad6cef04..76dbbe595ffe868f 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +@@ -82,6 +82,7 @@ + #define __NR_fsync 95 + #define __NR_ftruncate 130 + #define __NR_futex 142 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 288 + #define __NR_get_kernel_syms 223 + #define __NR_get_mempolicy 304 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 1a74d090b72f4d61..0bc2af37dfa1eeb5 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.15. +-kernel 5.15 ++# The list of system calls is current as of Linux 5.16. ++kernel 5.16 + + FAST_atomic_update + FAST_cmpxchg +@@ -146,6 +146,7 @@ ftruncate + ftruncate64 + futex + futex_time64 ++futex_waitv + futimesat + get_kernel_syms + get_mempolicy +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +index 3ce2a1fcfc1c15f2..28558279b48a1ef4 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +@@ -78,6 +78,7 @@ + #define __NR_fsync 74 + #define __NR_ftruncate 77 + #define __NR_futex 202 ++#define __NR_futex_waitv 449 + #define __NR_futimesat 261 + #define __NR_get_kernel_syms 177 + #define __NR_get_mempolicy 239 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index 9e87e89baccc397c..c1ab8ec45e8b8fd3 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -74,6 +74,7 @@ + #define __NR_fsync 1073741898 + #define __NR_ftruncate 1073741901 + #define __NR_futex 1073742026 ++#define __NR_futex_waitv 1073742273 + #define __NR_futimesat 1073742085 + #define __NR_get_mempolicy 1073742063 + #define __NR_get_robust_list 1073742355 diff --git a/SOURCES/glibc-upstream-2.34-75.patch b/SOURCES/glibc-upstream-2.34-75.patch new file mode 100644 index 0000000..7fada18 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-75.patch @@ -0,0 +1,53 @@ +commit 03e6e02e6a216cfb913f49b3be80d5088603864f +Author: H.J. Lu +Date: Sun Jan 9 09:06:15 2022 -0800 + + Disable debuginfod in printer tests [BZ #28757] + + With gdb-11.1-6.fc35.x86_64, I got + + FAIL: nptl/test-cond-printers + FAIL: nptl/test-condattr-printers + FAIL: nptl/test-mutex-printers + FAIL: nptl/test-mutexattr-printers + FAIL: nptl/test-rwlock-printers + FAIL: nptl/test-rwlockattr-printers + + $ cat nptl/test-condattr-printers.out + Error: Response does not match the expected pattern. + Command: start + Expected pattern: main + Response: Temporary breakpoint 1 at 0x11d5: file test-condattr-printers.c, line 43. + Starting program: /export/build/gnu/tools-build/glibc-cet-gitlab/build-x86_64-linux/nptl/test-condattr-printers + + This GDB supports auto-downloading debuginfo from the following URLs: + https://debuginfod.fedoraproject.org/ + Enable debuginfod for this session? (y or [n]) + + Disable debuginfod to avoid GDB messages. This fixes BZ #28757. + + Reviewed-by: Florian Weimer + (cherry picked from commit 7de501f9418bf099e7104b63b0e4423257981b14) + +diff --git a/scripts/test_printers_common.py b/scripts/test_printers_common.py +index 34a3df6e6bd8b363..53b6d30d40ce2622 100644 +--- a/scripts/test_printers_common.py ++++ b/scripts/test_printers_common.py +@@ -161,6 +161,17 @@ def init_test(test_bin, printer_files, printer_names): + printer files. + """ + ++ # Disable debuginfod to avoid GDB messages like: ++ # ++ # This GDB supports auto-downloading debuginfo from the following URLs: ++ # https://debuginfod.fedoraproject.org/ ++ # Enable debuginfod for this session? (y or [n]) ++ # ++ try: ++ test('set debuginfod enabled off') ++ except Exception: ++ pass ++ + # Load all the pretty printer files. We're assuming these are safe. + for printer_file in printer_files: + test('source {0}'.format(printer_file)) diff --git a/SOURCES/glibc-upstream-2.34-76.patch b/SOURCES/glibc-upstream-2.34-76.patch new file mode 100644 index 0000000..3d669c3 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-76.patch @@ -0,0 +1,165 @@ +commit 5575daae5099e779bb860b566b4d608418a5b832 +Author: Florian Weimer +Date: Mon Jan 17 10:21:34 2022 +0100 + + socket: Add the __sockaddr_un_set function + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit e368b12f6c16b6888dda99ba641e999b9c9643c8) + +diff --git a/include/sys/un.h b/include/sys/un.h +index bdbee999806930f4..152afd9fc7426d8b 100644 +--- a/include/sys/un.h ++++ b/include/sys/un.h +@@ -1 +1,13 @@ + #include ++ ++#ifndef _ISOMAC ++ ++/* Set ADDR->sun_family to AF_UNIX and ADDR->sun_path to PATHNAME. ++ Return 0 on success or -1 on failure (due to overlong PATHNAME). ++ The caller should always use sizeof (struct sockaddr_un) as the ++ socket address length, disregaring the length of PATHNAME. ++ Only concrete (non-abstract) pathnames are supported. */ ++int __sockaddr_un_set (struct sockaddr_un *addr, const char *pathname) ++ attribute_hidden; ++ ++#endif /* _ISOMAC */ +diff --git a/socket/Makefile b/socket/Makefile +index 375957601024c12e..c2de11d73ca1e324 100644 +--- a/socket/Makefile ++++ b/socket/Makefile +@@ -29,13 +29,17 @@ headers := sys/socket.h sys/un.h bits/sockaddr.h bits/socket.h \ + routines := accept bind connect getpeername getsockname getsockopt \ + listen recv recvfrom recvmsg send sendmsg sendto \ + setsockopt shutdown socket socketpair isfdtype opensock \ +- sockatmark accept4 recvmmsg sendmmsg ++ sockatmark accept4 recvmmsg sendmmsg sockaddr_un_set + + tests := \ + tst-accept4 \ + tst-sockopt \ + # tests + ++tests-internal := \ ++ tst-sockaddr_un_set \ ++ # tests-internal ++ + tests-time64 := \ + tst-sockopt-time64 \ + # tests +diff --git a/socket/sockaddr_un_set.c b/socket/sockaddr_un_set.c +new file mode 100644 +index 0000000000000000..0bd40dc34e3d7efc +--- /dev/null ++++ b/socket/sockaddr_un_set.c +@@ -0,0 +1,41 @@ ++/* Set the sun_path member of struct sockaddr_un. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++int ++__sockaddr_un_set (struct sockaddr_un *addr, const char *pathname) ++{ ++ size_t name_length = strlen (pathname); ++ ++ /* The kernel supports names of exactly sizeof (addr->sun_path) ++ bytes, without a null terminator, but userspace does not; see the ++ SUN_LEN macro. */ ++ if (name_length >= sizeof (addr->sun_path)) ++ { ++ __set_errno (EINVAL); /* Error code used by the kernel. */ ++ return -1; ++ } ++ ++ addr->sun_family = AF_UNIX; ++ memcpy (addr->sun_path, pathname, name_length + 1); ++ return 0; ++} +diff --git a/socket/tst-sockaddr_un_set.c b/socket/tst-sockaddr_un_set.c +new file mode 100644 +index 0000000000000000..29c2a81afda81b5e +--- /dev/null ++++ b/socket/tst-sockaddr_un_set.c +@@ -0,0 +1,62 @@ ++/* Test the __sockaddr_un_set function. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Re-compile the function because the version in libc is not ++ exported. */ ++#include "sockaddr_un_set.c" ++ ++#include ++ ++static int ++do_test (void) ++{ ++ struct sockaddr_un sun; ++ ++ memset (&sun, 0xcc, sizeof (sun)); ++ __sockaddr_un_set (&sun, ""); ++ TEST_COMPARE (sun.sun_family, AF_UNIX); ++ TEST_COMPARE (__sockaddr_un_set (&sun, ""), 0); ++ ++ memset (&sun, 0xcc, sizeof (sun)); ++ TEST_COMPARE (__sockaddr_un_set (&sun, "/example"), 0); ++ TEST_COMPARE_STRING (sun.sun_path, "/example"); ++ ++ { ++ char pathname[108]; /* Length of sun_path (ABI constant). */ ++ memset (pathname, 'x', sizeof (pathname)); ++ pathname[sizeof (pathname) - 1] = '\0'; ++ memset (&sun, 0xcc, sizeof (sun)); ++ TEST_COMPARE (__sockaddr_un_set (&sun, pathname), 0); ++ TEST_COMPARE (sun.sun_family, AF_UNIX); ++ TEST_COMPARE_STRING (sun.sun_path, pathname); ++ } ++ ++ { ++ char pathname[109]; ++ memset (pathname, 'x', sizeof (pathname)); ++ pathname[sizeof (pathname) - 1] = '\0'; ++ memset (&sun, 0xcc, sizeof (sun)); ++ errno = 0; ++ TEST_COMPARE (__sockaddr_un_set (&sun, pathname), -1); ++ TEST_COMPARE (errno, EINVAL); ++ } ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-77.patch b/SOURCES/glibc-upstream-2.34-77.patch new file mode 100644 index 0000000..752a81a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-77.patch @@ -0,0 +1,33 @@ +commit 7b5d433fd097b8ed74e458eca33597290e07b974 +Author: Florian Weimer +Date: Mon Jan 17 10:21:34 2022 +0100 + + CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542) + + Processing an overlong pathname in the sunrpc clnt_create function + results in a stack-based buffer overflow. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 226b46770c82899b555986583294b049c6ec9b40) + +diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c +index 13ced8994e49d4ee..b44357cd88e60599 100644 +--- a/sunrpc/clnt_gen.c ++++ b/sunrpc/clnt_gen.c +@@ -57,9 +57,13 @@ clnt_create (const char *hostname, u_long prog, u_long vers, + + if (strcmp (proto, "unix") == 0) + { +- memset ((char *)&sun, 0, sizeof (sun)); +- sun.sun_family = AF_UNIX; +- strcpy (sun.sun_path, hostname); ++ if (__sockaddr_un_set (&sun, hostname) < 0) ++ { ++ struct rpc_createerr *ce = &get_rpc_createerr (); ++ ce->cf_stat = RPC_SYSTEMERROR; ++ ce->cf_error.re_errno = errno; ++ return NULL; ++ } + sock = RPC_ANYSOCK; + client = clntunix_create (&sun, prog, vers, &sock, 0, 0); + if (client == NULL) diff --git a/SOURCES/glibc-upstream-2.34-78.patch b/SOURCES/glibc-upstream-2.34-78.patch new file mode 100644 index 0000000..cfd76f0 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-78.patch @@ -0,0 +1,82 @@ +commit 1081f1d3dd7c84ba3416b5198d47a4df2b70185d +Author: Martin Sebor +Date: Mon Jan 17 10:21:34 2022 +0100 + + sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542) + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit ef972a4c50014a16132b5c75571cfb6b30bef136) + +diff --git a/sunrpc/Makefile b/sunrpc/Makefile +index 7e5bbfd951b1e835..a4281b18d04c78e9 100644 +--- a/sunrpc/Makefile ++++ b/sunrpc/Makefile +@@ -65,7 +65,8 @@ shared-only-routines = $(routines) + endif + + tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \ +- tst-udp-nonblocking ++ tst-udp-nonblocking tst-bug22542 ++ + xtests := tst-getmyaddr + + ifeq ($(have-thread-library),yes) +@@ -110,6 +111,8 @@ $(objpfx)tst-udp-nonblocking: $(common-objpfx)linkobj/libc.so + $(objpfx)tst-udp-garbage: \ + $(common-objpfx)linkobj/libc.so $(shared-thread-library) + ++$(objpfx)tst-bug22542: $(common-objpfx)linkobj/libc.so ++ + else # !have-GLIBC_2.31 + + routines = $(routines-for-nss) +diff --git a/sunrpc/tst-bug22542.c b/sunrpc/tst-bug22542.c +new file mode 100644 +index 0000000000000000..d6cd79787bdef21d +--- /dev/null ++++ b/sunrpc/tst-bug22542.c +@@ -0,0 +1,44 @@ ++/* Test to verify that overlong hostname is rejected by clnt_create ++ and doesn't cause a buffer overflow (bug 22542). ++ ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ /* Create an arbitrary hostname that's longer than fits in sun_path. */ ++ char name [sizeof ((struct sockaddr_un*)0)->sun_path * 2]; ++ memset (name, 'x', sizeof name - 1); ++ name [sizeof name - 1] = '\0'; ++ ++ errno = 0; ++ CLIENT *clnt = clnt_create (name, 0, 0, "unix"); ++ ++ TEST_VERIFY (clnt == NULL); ++ TEST_COMPARE (errno, EINVAL); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-79.patch b/SOURCES/glibc-upstream-2.34-79.patch new file mode 100644 index 0000000..84f34f8 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-79.patch @@ -0,0 +1,102 @@ +commit 6890b8a3ae40ab9d4c96024ab95b04816fcc8a4a +Author: Florian Weimer +Date: Mon Jan 17 11:49:25 2022 +0100 + + CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768) + + The sunrpc function svcunix_create suffers from a stack-based buffer + overflow with overlong pathname arguments. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit f545ad4928fa1f27a3075265182b38a4f939a5f7) + +diff --git a/sunrpc/Makefile b/sunrpc/Makefile +index a4281b18d04c78e9..6408ab5c073538e9 100644 +--- a/sunrpc/Makefile ++++ b/sunrpc/Makefile +@@ -65,7 +65,7 @@ shared-only-routines = $(routines) + endif + + tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \ +- tst-udp-nonblocking tst-bug22542 ++ tst-udp-nonblocking tst-bug22542 tst-bug28768 + + xtests := tst-getmyaddr + +diff --git a/sunrpc/svc_unix.c b/sunrpc/svc_unix.c +index 679fbe9cb69587bd..46f8d16fe94a3d4f 100644 +--- a/sunrpc/svc_unix.c ++++ b/sunrpc/svc_unix.c +@@ -154,7 +154,10 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path) + SVCXPRT *xprt; + struct unix_rendezvous *r; + struct sockaddr_un addr; +- socklen_t len = sizeof (struct sockaddr_in); ++ socklen_t len = sizeof (addr); ++ ++ if (__sockaddr_un_set (&addr, path) < 0) ++ return NULL; + + if (sock == RPC_ANYSOCK) + { +@@ -165,12 +168,6 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path) + } + madesock = TRUE; + } +- memset (&addr, '\0', sizeof (addr)); +- addr.sun_family = AF_UNIX; +- len = strlen (path) + 1; +- memcpy (addr.sun_path, path, len); +- len += sizeof (addr.sun_family); +- + __bind (sock, (struct sockaddr *) &addr, len); + + if (__getsockname (sock, (struct sockaddr *) &addr, &len) != 0 +diff --git a/sunrpc/tst-bug28768.c b/sunrpc/tst-bug28768.c +new file mode 100644 +index 0000000000000000..35a4b7b0b3d34350 +--- /dev/null ++++ b/sunrpc/tst-bug28768.c +@@ -0,0 +1,42 @@ ++/* Test to verify that long path is rejected by svcunix_create (bug 28768). ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* svcunix_create does not have a default version in linkobj/libc.so. */ ++compat_symbol_reference (libc, svcunix_create, svcunix_create, GLIBC_2_1); ++ ++static int ++do_test (void) ++{ ++ char pathname[109]; ++ memset (pathname, 'x', sizeof (pathname)); ++ pathname[sizeof (pathname) - 1] = '\0'; ++ ++ errno = 0; ++ TEST_VERIFY (svcunix_create (RPC_ANYSOCK, 4096, 4096, pathname) == NULL); ++ TEST_COMPARE (errno, EINVAL); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-80.patch b/SOURCES/glibc-upstream-2.34-80.patch new file mode 100644 index 0000000..fec92e2 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-80.patch @@ -0,0 +1,56 @@ +commit 1d401d1fccb85046402089268b94d86d822070e6 +Author: Aurelien Jarno +Date: Mon Jan 17 19:41:40 2022 +0100 + + x86: use default cache size if it cannot be determined [BZ #28784] + + In some cases (e.g QEMU, non-Intel/AMD CPU) the cache information can + not be retrieved and the corresponding values are set to 0. + + Commit 2d651eb9265d ("x86: Move x86 processor cache info to + cpu_features") changed the behaviour in such case by defining the + __x86_shared_cache_size and __x86_data_cache_size variables to 0 instead + of using the default values. This cause an issue with the i686 SSE2 + optimized bzero/routine which assumes that the cache size is at least + 128 bytes, and otherwise tries to zero/set the whole address space minus + 128 bytes. + + Fix that by restoring the original code to only update + __x86_shared_cache_size and __x86_data_cache_size variables if the + corresponding cache sizes are not zero. + + Fixes bug 28784 + Fixes commit 2d651eb9265d + + Reviewed-by: H.J. Lu + (cherry picked from commit c242fcce06e3102ca663b2f992611d0bda4f2668) + +diff --git a/sysdeps/x86/cacheinfo.h b/sysdeps/x86/cacheinfo.h +index 41d2c81369840ada..63f36877e3f35d99 100644 +--- a/sysdeps/x86/cacheinfo.h ++++ b/sysdeps/x86/cacheinfo.h +@@ -61,14 +61,20 @@ init_cacheinfo (void) + long int data = cpu_features->data_cache_size; + /* Round data cache size to multiple of 256 bytes. */ + data = data & ~255L; +- __x86_data_cache_size_half = data / 2; +- __x86_data_cache_size = data; ++ if (data > 0) ++ { ++ __x86_data_cache_size_half = data / 2; ++ __x86_data_cache_size = data; ++ } + + long int shared = cpu_features->shared_cache_size; + /* Round shared cache size to multiple of 256 bytes. */ + shared = shared & ~255L; +- __x86_shared_cache_size_half = shared / 2; +- __x86_shared_cache_size = shared; ++ if (shared > 0) ++ { ++ __x86_shared_cache_size_half = shared / 2; ++ __x86_shared_cache_size = shared; ++ } + + __x86_shared_non_temporal_threshold + = cpu_features->non_temporal_threshold; diff --git a/SOURCES/glibc-upstream-2.34-81.patch b/SOURCES/glibc-upstream-2.34-81.patch new file mode 100644 index 0000000..3fcbbf4 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-81.patch @@ -0,0 +1,64 @@ +commit 82b1acd9de9796298a230d7484f26fe9a7756d18 +Author: Paul A. Clarke +Date: Sat Sep 25 09:57:15 2021 -0500 + + powerpc: Fix unrecognized instruction errors with recent binutils + + Recent versions of binutils (with commit + b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a) stopped preserving "sticky" + options across a base `.machine` directive, nullifying the use of + passing "-many" through GCC to the assembler. As a result, some + instructions which were recognized even under older, more stringent + `.machine` directives become unrecognized instructions in that + context. + + In `sysdeps/powerpc/tst-set_ppr.c`, the use of the `mfppr32` extended + mnemonic became unrecognized, as the default compilation with GCC for + 32bit powerpc adds a `.machine ppc` in the resulting assembly, so the + command line option `-Wa,-many` is essentially ignored, and the ISA 2.06 + instructions and mnemonics, like `mfppr32`, are unrecognized. + + The compilation of `sysdeps/powerpc/tst-set_ppr.c` fails with: + Error: unrecognized opcode: `mfppr32' + + Add appropriate `.machine` directives in the assembly to bracket the + `mfppr32` instruction. + + Part of a 2019 fix (commit 9250e6610fdb0f3a6f238d2813e319a41fb7a810) to + the above test's Makefile to add `-many` to the compilation when GCC + itself stopped passing `-many` to the assember no longer has any effect, + so remove that. + + Reported-by: Joseph Myers + (cherry picked from commit ee874f44fd55988808a4a162ef21bfa2cc8dc6f7) + +diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile +index 09860ffc0155d765..5e6cb07ce66decfa 100644 +--- a/sysdeps/powerpc/Makefile ++++ b/sysdeps/powerpc/Makefile +@@ -61,11 +61,6 @@ ifeq ($(subdir),misc) + sysdep_headers += sys/platform/ppc.h + tests += test-gettimebase + tests += tst-set_ppr +- +-# This test is expected to run and exit with EXIT_UNSUPPORTED on +-# processors that do not implement the Power ISA 2.06 or greater. +-# But the test makes use of instructions from Power ISA 2.06 and 2.07. +-CFLAGS-tst-set_ppr.c += -Wa,-many + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/powerpc/tst-set_ppr.c b/sysdeps/powerpc/tst-set_ppr.c +index 7684f5d6ea905c60..e80da15320635585 100644 +--- a/sysdeps/powerpc/tst-set_ppr.c ++++ b/sysdeps/powerpc/tst-set_ppr.c +@@ -44,7 +44,8 @@ get_thread_priority (void) + { + /* Read the PPR. */ + ppr_t ppr; +- asm volatile (MFPPR" %0" : "=r"(ppr)); ++ asm volatile (".machine push; .machine power7; "MFPPR" %0; .machine pop" ++ : "=r"(ppr)); + /* Return the thread priority value. */ + return EXTRACT_THREAD_PRIORITY (ppr); + } diff --git a/SOURCES/glibc-upstream-2.34-82.patch b/SOURCES/glibc-upstream-2.34-82.patch new file mode 100644 index 0000000..1f522aa --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-82.patch @@ -0,0 +1,276 @@ +commit 062ff490c1467059f6cd64bb9c3d85f6cc6cf97a +Author: Siddhesh Poyarekar +Date: Tue Jan 18 13:29:36 2022 +0530 + + support: Add helpers to create paths longer than PATH_MAX + + Add new helpers support_create_and_chdir_toolong_temp_directory and + support_chdir_toolong_temp_directory to create and descend into + directory trees longer than PATH_MAX. + + Reviewed-by: Adhemerval Zanella + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit fb7bff12e81c677a6622f724edd4d4987dd9d971) + +diff --git a/support/temp_file.c b/support/temp_file.c +index c6df641876285bb2..e41128c2d43fe903 100644 +--- a/support/temp_file.c ++++ b/support/temp_file.c +@@ -1,5 +1,6 @@ + /* Temporary file handling for tests. +- Copyright (C) 1998-2021 Free Software Foundation, Inc. ++ Copyright (C) 1998-2022 Free Software Foundation, Inc. ++ Copyright The GNU Tools Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -20,15 +21,17 @@ + some 32-bit platforms. */ + #define _FILE_OFFSET_BITS 64 + ++#include + #include + #include + #include + ++#include + #include + #include + #include + #include +-#include ++#include + + /* List of temporary files. */ + static struct temp_name_list +@@ -36,14 +39,20 @@ static struct temp_name_list + struct temp_name_list *next; + char *name; + pid_t owner; ++ bool toolong; + } *temp_name_list; + + /* Location of the temporary files. Set by the test skeleton via + support_set_test_dir. The string is not be freed. */ + static const char *test_dir = _PATH_TMP; + +-void +-add_temp_file (const char *name) ++/* Name of subdirectories in a too long temporary directory tree. */ ++static char toolong_subdir[NAME_MAX + 1]; ++static bool toolong_initialized; ++static size_t toolong_path_max; ++ ++static void ++add_temp_file_internal (const char *name, bool toolong) + { + struct temp_name_list *newp + = (struct temp_name_list *) xcalloc (sizeof (*newp), 1); +@@ -53,12 +62,19 @@ add_temp_file (const char *name) + newp->name = newname; + newp->next = temp_name_list; + newp->owner = getpid (); ++ newp->toolong = toolong; + temp_name_list = newp; + } + else + free (newp); + } + ++void ++add_temp_file (const char *name) ++{ ++ add_temp_file_internal (name, false); ++} ++ + int + create_temp_file_in_dir (const char *base, const char *dir, char **filename) + { +@@ -90,8 +106,8 @@ create_temp_file (const char *base, char **filename) + return create_temp_file_in_dir (base, test_dir, filename); + } + +-char * +-support_create_temp_directory (const char *base) ++static char * ++create_temp_directory_internal (const char *base, bool toolong) + { + char *path = xasprintf ("%s/%sXXXXXX", test_dir, base); + if (mkdtemp (path) == NULL) +@@ -99,16 +115,132 @@ support_create_temp_directory (const char *base) + printf ("error: mkdtemp (\"%s\"): %m", path); + exit (1); + } +- add_temp_file (path); ++ add_temp_file_internal (path, toolong); + return path; + } + +-/* Helper functions called by the test skeleton follow. */ ++char * ++support_create_temp_directory (const char *base) ++{ ++ return create_temp_directory_internal (base, false); ++} ++ ++static void ++ensure_toolong_initialized (void) ++{ ++ if (!toolong_initialized) ++ FAIL_EXIT1 ("uninitialized toolong directory tree\n"); ++} ++ ++static void ++initialize_toolong (const char *base) ++{ ++ long name_max = pathconf (base, _PC_NAME_MAX); ++ name_max = (name_max < 0 ? 64 ++ : (name_max < sizeof (toolong_subdir) ? name_max ++ : sizeof (toolong_subdir) - 1)); ++ ++ long path_max = pathconf (base, _PC_PATH_MAX); ++ path_max = (path_max < 0 ? 1024 ++ : path_max <= PTRDIFF_MAX ? path_max : PTRDIFF_MAX); ++ ++ /* Sanity check to ensure that the test does not create temporary directories ++ in different filesystems because this API doesn't support it. */ ++ if (toolong_initialized) ++ { ++ if (name_max != strlen (toolong_subdir)) ++ FAIL_UNSUPPORTED ("name_max: Temporary directories in different" ++ " filesystems not supported yet\n"); ++ if (path_max != toolong_path_max) ++ FAIL_UNSUPPORTED ("path_max: Temporary directories in different" ++ " filesystems not supported yet\n"); ++ return; ++ } ++ ++ toolong_path_max = path_max; ++ ++ size_t len = name_max; ++ memset (toolong_subdir, 'X', len); ++ toolong_initialized = true; ++} ++ ++char * ++support_create_and_chdir_toolong_temp_directory (const char *basename) ++{ ++ char *base = create_temp_directory_internal (basename, true); ++ xchdir (base); ++ ++ initialize_toolong (base); ++ ++ size_t sz = strlen (toolong_subdir); ++ ++ /* Create directories and descend into them so that the final path is larger ++ than PATH_MAX. */ ++ for (size_t i = 0; i <= toolong_path_max / sz; i++) ++ { ++ int ret = mkdir (toolong_subdir, S_IRWXU); ++ if (ret != 0 && errno == ENAMETOOLONG) ++ FAIL_UNSUPPORTED ("Filesystem does not support creating too long " ++ "directory trees\n"); ++ else if (ret != 0) ++ FAIL_EXIT1 ("Failed to create directory tree: %m\n"); ++ xchdir (toolong_subdir); ++ } ++ return base; ++} + + void +-support_set_test_dir (const char *path) ++support_chdir_toolong_temp_directory (const char *base) + { +- test_dir = path; ++ ensure_toolong_initialized (); ++ ++ xchdir (base); ++ ++ size_t sz = strlen (toolong_subdir); ++ for (size_t i = 0; i <= toolong_path_max / sz; i++) ++ xchdir (toolong_subdir); ++} ++ ++/* Helper functions called by the test skeleton follow. */ ++ ++static void ++remove_toolong_subdirs (const char *base) ++{ ++ ensure_toolong_initialized (); ++ ++ if (chdir (base) != 0) ++ { ++ printf ("warning: toolong cleanup base failed: chdir (\"%s\"): %m\n", ++ base); ++ return; ++ } ++ ++ /* Descend. */ ++ int levels = 0; ++ size_t sz = strlen (toolong_subdir); ++ for (levels = 0; levels <= toolong_path_max / sz; levels++) ++ if (chdir (toolong_subdir) != 0) ++ { ++ printf ("warning: toolong cleanup failed: chdir (\"%s\"): %m\n", ++ toolong_subdir); ++ break; ++ } ++ ++ /* Ascend and remove. */ ++ while (--levels >= 0) ++ { ++ if (chdir ("..") != 0) ++ { ++ printf ("warning: toolong cleanup failed: chdir (\"..\"): %m\n"); ++ return; ++ } ++ if (remove (toolong_subdir) != 0) ++ { ++ printf ("warning: could not remove subdirectory: %s: %m\n", ++ toolong_subdir); ++ return; ++ } ++ } + } + + void +@@ -123,6 +255,9 @@ support_delete_temp_files (void) + around, to prevent PID reuse.) */ + if (temp_name_list->owner == pid) + { ++ if (temp_name_list->toolong) ++ remove_toolong_subdirs (temp_name_list->name); ++ + if (remove (temp_name_list->name) != 0) + printf ("warning: could not remove temporary file: %s: %m\n", + temp_name_list->name); +@@ -147,3 +282,9 @@ support_print_temp_files (FILE *f) + fprintf (f, ")\n"); + } + } ++ ++void ++support_set_test_dir (const char *path) ++{ ++ test_dir = path; ++} +diff --git a/support/temp_file.h b/support/temp_file.h +index f3a7fb6f9ca44d19..a22964c6fa11abd2 100644 +--- a/support/temp_file.h ++++ b/support/temp_file.h +@@ -44,6 +44,15 @@ int create_temp_file_in_dir (const char *base, const char *dir, + returns. The caller should free this string. */ + char *support_create_temp_directory (const char *base); + ++/* Create a temporary directory tree that is longer than PATH_MAX and schedule ++ it for deletion. BASENAME is used as a prefix for the unique directory ++ name, which the function returns. The caller should free this string. */ ++char *support_create_and_chdir_toolong_temp_directory (const char *basename); ++ ++/* Change into the innermost directory of the directory tree BASE, which was ++ created using support_create_and_chdir_toolong_temp_directory. */ ++void support_chdir_toolong_temp_directory (const char *base); ++ + __END_DECLS + + #endif /* SUPPORT_TEMP_FILE_H */ diff --git a/SOURCES/glibc-upstream-2.34-83.patch b/SOURCES/glibc-upstream-2.34-83.patch new file mode 100644 index 0000000..4a37c4d --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-83.patch @@ -0,0 +1,121 @@ +commit 269eb9d930546ce57e83b56c44c430f154684a23 +Author: Siddhesh Poyarekar +Date: Thu Jan 13 10:34:37 2022 +0530 + + stdlib: Sort tests in Makefile + + Put one test per line and sort them. + + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 5b766603efa727c236a5f0cdcf09b71ff60b7584) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 7c15549cafa8e397..6a1c3580bd1648ee 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -65,30 +65,81 @@ aux = grouping groupingwc tens_in_limb + static-only-routines = atexit at_quick_exit + + test-srcs := tst-fmtmsg +-tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ +- test-canon test-canon2 tst-strtoll tst-environ \ +- tst-xpg-basename tst-random tst-random2 tst-bsearch \ +- tst-limits tst-rand48 bug-strtod tst-setcontext \ +- tst-setcontext2 test-a64l tst-qsort testmb2 \ +- bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 \ +- tst-rand48-2 tst-makecontext tst-strtod5 \ +- tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \ +- tst-makecontext3 bug-getcontext bug-fmtmsg1 \ +- tst-secure-getenv tst-strtod-overflow tst-strtod-round \ +- tst-tininess tst-strtod-underflow tst-setcontext3 \ +- tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l \ +- tst-quick_exit tst-thread-quick_exit tst-width \ +- tst-width-stdint tst-strfrom tst-strfrom-locale \ +- tst-getrandom tst-atexit tst-at_quick_exit \ +- tst-cxa_atexit tst-on_exit test-atexit-race \ +- test-at_quick_exit-race test-cxa_atexit-race \ +- test-cxa_atexit-race2 \ +- test-on_exit-race test-dlclose-exit-race \ +- tst-makecontext-align test-bz22786 tst-strtod-nan-sign \ +- tst-swapcontext1 tst-setcontext4 tst-setcontext5 \ +- tst-setcontext6 tst-setcontext7 tst-setcontext8 \ +- tst-setcontext9 tst-bz20544 tst-canon-bz26341 \ +- tst-realpath ++tests := bug-fmtmsg1 \ ++ bug-getcontext \ ++ bug-strtod \ ++ bug-strtod2 \ ++ test-a64l \ ++ test-at_quick_exit-race \ ++ test-atexit-race \ ++ test-bz22786 \ ++ test-canon \ ++ test-canon2 \ ++ test-cxa_atexit-race \ ++ test-cxa_atexit-race2 \ ++ test-dlclose-exit-race \ ++ test-on_exit-race \ ++ testdiv \ ++ testmb \ ++ testmb2 \ ++ testrand \ ++ testsort \ ++ tst-at_quick_exit \ ++ tst-atexit \ ++ tst-atof1 \ ++ tst-atof2 \ ++ tst-bsearch \ ++ tst-bz20544 \ ++ tst-canon-bz26341 \ ++ tst-cxa_atexit \ ++ tst-environ \ ++ tst-getrandom \ ++ tst-limits \ ++ tst-makecontext \ ++ tst-makecontext-align \ ++ tst-makecontext2 \ ++ tst-makecontext3 \ ++ tst-on_exit \ ++ tst-qsort \ ++ tst-qsort2 \ ++ tst-quick_exit \ ++ tst-rand48 \ ++ tst-rand48-2 \ ++ tst-random \ ++ tst-random2 \ ++ tst-realpath \ ++ tst-secure-getenv \ ++ tst-setcontext \ ++ tst-setcontext2 \ ++ tst-setcontext3 \ ++ tst-setcontext4 \ ++ tst-setcontext5 \ ++ tst-setcontext6 \ ++ tst-setcontext7 \ ++ tst-setcontext8 \ ++ tst-setcontext9 \ ++ tst-strfmon_l \ ++ tst-strfrom \ ++ tst-strfrom-locale \ ++ tst-strtod \ ++ tst-strtod-nan-locale \ ++ tst-strtod-nan-sign \ ++ tst-strtod-overflow \ ++ tst-strtod-round \ ++ tst-strtod-underflow \ ++ tst-strtod2 \ ++ tst-strtod5 \ ++ tst-strtod6 \ ++ tst-strtol \ ++ tst-strtol-locale \ ++ tst-strtoll \ ++ tst-swapcontext1 \ ++ tst-thread-quick_exit \ ++ tst-tininess \ ++ tst-unsetenv1 \ ++ tst-width \ ++ tst-width-stdint \ ++ tst-xpg-basename + + tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ + tst-tls-atexit tst-tls-atexit-nodelete diff --git a/SOURCES/glibc-upstream-2.34-84.patch b/SOURCES/glibc-upstream-2.34-84.patch new file mode 100644 index 0000000..e97805a --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-84.patch @@ -0,0 +1,173 @@ +commit 73c362840c4efde45125a6c27bf41726397f4038 +Author: Siddhesh Poyarekar +Date: Thu Jan 13 18:50:55 2022 +0530 + + stdlib: Fix formatting of tests list in Makefile + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Florian Weimer + (cherry picked from commit f9dab1b5f23d0fb008a56c7c6c8919adb49d3611) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 6a1c3580bd1648ee..9bb5c221e8be3288 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -65,81 +65,83 @@ aux = grouping groupingwc tens_in_limb + static-only-routines = atexit at_quick_exit + + test-srcs := tst-fmtmsg +-tests := bug-fmtmsg1 \ +- bug-getcontext \ +- bug-strtod \ +- bug-strtod2 \ +- test-a64l \ +- test-at_quick_exit-race \ +- test-atexit-race \ +- test-bz22786 \ +- test-canon \ +- test-canon2 \ +- test-cxa_atexit-race \ +- test-cxa_atexit-race2 \ +- test-dlclose-exit-race \ +- test-on_exit-race \ +- testdiv \ +- testmb \ +- testmb2 \ +- testrand \ +- testsort \ +- tst-at_quick_exit \ +- tst-atexit \ +- tst-atof1 \ +- tst-atof2 \ +- tst-bsearch \ +- tst-bz20544 \ +- tst-canon-bz26341 \ +- tst-cxa_atexit \ +- tst-environ \ +- tst-getrandom \ +- tst-limits \ +- tst-makecontext \ +- tst-makecontext-align \ +- tst-makecontext2 \ +- tst-makecontext3 \ +- tst-on_exit \ +- tst-qsort \ +- tst-qsort2 \ +- tst-quick_exit \ +- tst-rand48 \ +- tst-rand48-2 \ +- tst-random \ +- tst-random2 \ +- tst-realpath \ +- tst-secure-getenv \ +- tst-setcontext \ +- tst-setcontext2 \ +- tst-setcontext3 \ +- tst-setcontext4 \ +- tst-setcontext5 \ +- tst-setcontext6 \ +- tst-setcontext7 \ +- tst-setcontext8 \ +- tst-setcontext9 \ +- tst-strfmon_l \ +- tst-strfrom \ +- tst-strfrom-locale \ +- tst-strtod \ +- tst-strtod-nan-locale \ +- tst-strtod-nan-sign \ +- tst-strtod-overflow \ +- tst-strtod-round \ +- tst-strtod-underflow \ +- tst-strtod2 \ +- tst-strtod5 \ +- tst-strtod6 \ +- tst-strtol \ +- tst-strtol-locale \ +- tst-strtoll \ +- tst-swapcontext1 \ +- tst-thread-quick_exit \ +- tst-tininess \ +- tst-unsetenv1 \ +- tst-width \ +- tst-width-stdint \ +- tst-xpg-basename ++tests := \ ++ bug-fmtmsg1 \ ++ bug-getcontext \ ++ bug-strtod \ ++ bug-strtod2 \ ++ test-a64l \ ++ test-at_quick_exit-race \ ++ test-atexit-race \ ++ test-bz22786 \ ++ test-canon \ ++ test-canon2 \ ++ test-cxa_atexit-race \ ++ test-cxa_atexit-race2 \ ++ test-dlclose-exit-race \ ++ test-on_exit-race \ ++ testdiv \ ++ testmb \ ++ testmb2 \ ++ testrand \ ++ testsort \ ++ tst-at_quick_exit \ ++ tst-atexit \ ++ tst-atof1 \ ++ tst-atof2 \ ++ tst-bsearch \ ++ tst-bz20544 \ ++ tst-canon-bz26341 \ ++ tst-cxa_atexit \ ++ tst-environ \ ++ tst-getrandom \ ++ tst-limits \ ++ tst-makecontext \ ++ tst-makecontext-align \ ++ tst-makecontext2 \ ++ tst-makecontext3 \ ++ tst-on_exit \ ++ tst-qsort \ ++ tst-qsort2 \ ++ tst-quick_exit \ ++ tst-rand48 \ ++ tst-rand48-2 \ ++ tst-random \ ++ tst-random2 \ ++ tst-realpath \ ++ tst-secure-getenv \ ++ tst-setcontext \ ++ tst-setcontext2 \ ++ tst-setcontext3 \ ++ tst-setcontext4 \ ++ tst-setcontext5 \ ++ tst-setcontext6 \ ++ tst-setcontext7 \ ++ tst-setcontext8 \ ++ tst-setcontext9 \ ++ tst-strfmon_l \ ++ tst-strfrom \ ++ tst-strfrom-locale \ ++ tst-strtod \ ++ tst-strtod-nan-locale \ ++ tst-strtod-nan-sign \ ++ tst-strtod-overflow \ ++ tst-strtod-round \ ++ tst-strtod-underflow \ ++ tst-strtod2 \ ++ tst-strtod5 \ ++ tst-strtod6 \ ++ tst-strtol \ ++ tst-strtol-locale \ ++ tst-strtoll \ ++ tst-swapcontext1 \ ++ tst-thread-quick_exit \ ++ tst-tininess \ ++ tst-unsetenv1 \ ++ tst-width \ ++ tst-width-stdint \ ++ tst-xpg-basename \ ++# tests + + tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ + tst-tls-atexit tst-tls-atexit-nodelete diff --git a/SOURCES/glibc-upstream-2.34-85.patch b/SOURCES/glibc-upstream-2.34-85.patch new file mode 100644 index 0000000..3ea12aa --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-85.patch @@ -0,0 +1,109 @@ +commit f7a79879c0b2bef0dadd6caaaeeb0d26423e04e5 +Author: Siddhesh Poyarekar +Date: Thu Jan 13 11:28:36 2022 +0530 + + realpath: Set errno to ENAMETOOLONG for result larger than PATH_MAX [BZ #28770] + + realpath returns an allocated string when the result exceeds PATH_MAX, + which is unexpected when its second argument is not NULL. This results + in the second argument (resolved) being uninitialized and also results + in a memory leak since the caller expects resolved to be the same as the + returned value. + + Return NULL and set errno to ENAMETOOLONG if the result exceeds + PATH_MAX. This fixes [BZ #28770], which is CVE-2021-3998. + + Reviewed-by: Adhemerval Zanella + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit ee8d5e33adb284601c00c94687bc907e10aec9bb) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 9bb5c221e8be3288..a4ac30d1f6359561 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -109,6 +109,7 @@ tests := \ + tst-random \ + tst-random2 \ + tst-realpath \ ++ tst-realpath-toolong \ + tst-secure-getenv \ + tst-setcontext \ + tst-setcontext2 \ +diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c +index 698f9ede25570ef2..7a23a51b3a395eb3 100644 +--- a/stdlib/canonicalize.c ++++ b/stdlib/canonicalize.c +@@ -400,8 +400,16 @@ realpath_stk (const char *name, char *resolved, + + error: + *dest++ = '\0'; +- if (resolved != NULL && dest - rname <= get_path_max ()) +- rname = strcpy (resolved, rname); ++ if (resolved != NULL) ++ { ++ if (dest - rname <= get_path_max ()) ++ rname = strcpy (resolved, rname); ++ else ++ { ++ failed = true; ++ __set_errno (ENAMETOOLONG); ++ } ++ } + + error_nomem: + scratch_buffer_free (&extra_buffer); +diff --git a/stdlib/tst-realpath-toolong.c b/stdlib/tst-realpath-toolong.c +new file mode 100644 +index 0000000000000000..8bed772460b37571 +--- /dev/null ++++ b/stdlib/tst-realpath-toolong.c +@@ -0,0 +1,49 @@ ++/* Verify that realpath returns NULL with ENAMETOOLONG if the result exceeds ++ NAME_MAX. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define BASENAME "tst-realpath-toolong." ++ ++int ++do_test (void) ++{ ++ char *base = support_create_and_chdir_toolong_temp_directory (BASENAME); ++ ++ char buf[PATH_MAX + 1]; ++ const char *res = realpath (".", buf); ++ ++ /* canonicalize.c states that if the real path is >= PATH_MAX, then ++ realpath returns NULL and sets ENAMETOOLONG. */ ++ TEST_VERIFY (res == NULL); ++ TEST_VERIFY (errno == ENAMETOOLONG); ++ ++ free (base); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-upstream-2.34-86.patch b/SOURCES/glibc-upstream-2.34-86.patch new file mode 100644 index 0000000..1885d41 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-86.patch @@ -0,0 +1,26 @@ +commit 8c8a71c85f2ed5cc90d08d82ce645513fc907cb6 +Author: Siddhesh Poyarekar +Date: Mon Jan 24 10:57:09 2022 +0530 + + tst-realpath-toolong: Fix hurd build + + Define PATH_MAX to a constant if it isn't already defined, like in hurd. + + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 976db046bc3a3738f69255ae00b0a09b8e77fd9c) + +diff --git a/stdlib/tst-realpath-toolong.c b/stdlib/tst-realpath-toolong.c +index 8bed772460b37571..4388890294374601 100644 +--- a/stdlib/tst-realpath-toolong.c ++++ b/stdlib/tst-realpath-toolong.c +@@ -29,6 +29,10 @@ + + #define BASENAME "tst-realpath-toolong." + ++#ifndef PATH_MAX ++# define PATH_MAX 1024 ++#endif ++ + int + do_test (void) + { diff --git a/SOURCES/glibc-upstream-2.34-87.patch b/SOURCES/glibc-upstream-2.34-87.patch new file mode 100644 index 0000000..a696584 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-87.patch @@ -0,0 +1,329 @@ +commit 472e799a5f2102bc0c3206dbd5a801765fceb39c +Author: Siddhesh Poyarekar +Date: Fri Jan 21 23:32:56 2022 +0530 + + getcwd: Set errno to ERANGE for size == 1 (CVE-2021-3999) + + No valid path returned by getcwd would fit into 1 byte, so reject the + size early and return NULL with errno set to ERANGE. This change is + prompted by CVE-2021-3999, which describes a single byte buffer + underflow and overflow when all of the following conditions are met: + + - The buffer size (i.e. the second argument of getcwd) is 1 byte + - The current working directory is too long + - '/' is also mounted on the current working directory + + Sequence of events: + + - In sysdeps/unix/sysv/linux/getcwd.c, the syscall returns ENAMETOOLONG + because the linux kernel checks for name length before it checks + buffer size + + - The code falls back to the generic getcwd in sysdeps/posix + + - In the generic func, the buf[0] is set to '\0' on line 250 + + - this while loop on line 262 is bypassed: + + while (!(thisdev == rootdev && thisino == rootino)) + + since the rootfs (/) is bind mounted onto the directory and the flow + goes on to line 449, where it puts a '/' in the byte before the + buffer. + + - Finally on line 458, it moves 2 bytes (the underflowed byte and the + '\0') to the buf[0] and buf[1], resulting in a 1 byte buffer overflow. + + - buf is returned on line 469 and errno is not set. + + This resolves BZ #28769. + + Reviewed-by: Andreas Schwab + Reviewed-by: Adhemerval Zanella + Signed-off-by: Qualys Security Advisory + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 23e0e8f5f1fb5ed150253d986ecccdc90c2dcd5e) + +diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c +index 13680026ffecbd51..b6984a382c3e1711 100644 +--- a/sysdeps/posix/getcwd.c ++++ b/sysdeps/posix/getcwd.c +@@ -187,6 +187,13 @@ __getcwd_generic (char *buf, size_t size) + size_t allocated = size; + size_t used; + ++ /* A size of 1 byte is never useful. */ ++ if (allocated == 1) ++ { ++ __set_errno (ERANGE); ++ return NULL; ++ } ++ + #if HAVE_MINIMALLY_WORKING_GETCWD + /* If AT_FDCWD is not defined, the algorithm below is O(N**2) and + this is much slower than the system getcwd (at least on +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index d30d21898b402d1e..cdc01a3f023ec09a 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -342,7 +342,12 @@ sysdep_routines += xstatconv internal_statvfs \ + + sysdep_headers += bits/fcntl-linux.h + +-tests += tst-fallocate tst-fallocate64 tst-o_path-locks ++tests += \ ++ tst-fallocate \ ++ tst-fallocate64 \ ++ tst-getcwd-smallbuff \ ++ tst-o_path-locks \ ++# tests + endif + + ifeq ($(subdir),elf) +diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c +new file mode 100644 +index 0000000000000000..d460d6e7662dc5e4 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c +@@ -0,0 +1,241 @@ ++/* Verify that getcwd returns ERANGE for size 1 byte and does not underflow ++ buffer when the CWD is too long and is also a mount target of /. See bug ++ #28769 or CVE-2021-3999 for more context. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static char *base; ++#define BASENAME "tst-getcwd-smallbuff" ++#define MOUNT_NAME "mpoint" ++static int sockfd[2]; ++ ++static void ++do_cleanup (void) ++{ ++ support_chdir_toolong_temp_directory (base); ++ TEST_VERIFY_EXIT (rmdir (MOUNT_NAME) == 0); ++ free (base); ++} ++ ++static void ++send_fd (const int sock, const int fd) ++{ ++ struct msghdr msg = {0}; ++ union ++ { ++ struct cmsghdr hdr; ++ char buf[CMSG_SPACE (sizeof (int))]; ++ } cmsgbuf = {0}; ++ struct cmsghdr *cmsg; ++ struct iovec vec; ++ char ch = 'A'; ++ ssize_t n; ++ ++ msg.msg_control = &cmsgbuf.buf; ++ msg.msg_controllen = sizeof (cmsgbuf.buf); ++ ++ cmsg = CMSG_FIRSTHDR (&msg); ++ cmsg->cmsg_len = CMSG_LEN (sizeof (int)); ++ cmsg->cmsg_level = SOL_SOCKET; ++ cmsg->cmsg_type = SCM_RIGHTS; ++ memcpy (CMSG_DATA (cmsg), &fd, sizeof (fd)); ++ ++ vec.iov_base = &ch; ++ vec.iov_len = 1; ++ msg.msg_iov = &vec; ++ msg.msg_iovlen = 1; ++ ++ while ((n = sendmsg (sock, &msg, 0)) == -1 && errno == EINTR); ++ ++ TEST_VERIFY_EXIT (n == 1); ++} ++ ++static int ++recv_fd (const int sock) ++{ ++ struct msghdr msg = {0}; ++ union ++ { ++ struct cmsghdr hdr; ++ char buf[CMSG_SPACE(sizeof(int))]; ++ } cmsgbuf = {0}; ++ struct cmsghdr *cmsg; ++ struct iovec vec; ++ ssize_t n; ++ char ch = '\0'; ++ int fd = -1; ++ ++ vec.iov_base = &ch; ++ vec.iov_len = 1; ++ msg.msg_iov = &vec; ++ msg.msg_iovlen = 1; ++ ++ msg.msg_control = &cmsgbuf.buf; ++ msg.msg_controllen = sizeof (cmsgbuf.buf); ++ ++ while ((n = recvmsg (sock, &msg, 0)) == -1 && errno == EINTR); ++ if (n != 1 || ch != 'A') ++ return -1; ++ ++ cmsg = CMSG_FIRSTHDR (&msg); ++ if (cmsg == NULL) ++ return -1; ++ if (cmsg->cmsg_type != SCM_RIGHTS) ++ return -1; ++ memcpy (&fd, CMSG_DATA (cmsg), sizeof (fd)); ++ if (fd < 0) ++ return -1; ++ return fd; ++} ++ ++static int ++child_func (void * const arg) ++{ ++ xclose (sockfd[0]); ++ const int sock = sockfd[1]; ++ char ch; ++ ++ TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1); ++ TEST_VERIFY_EXIT (ch == '1'); ++ ++ if (mount ("/", MOUNT_NAME, NULL, MS_BIND | MS_REC, NULL)) ++ FAIL_EXIT1 ("mount failed: %m\n"); ++ const int fd = xopen ("mpoint", ++ O_RDONLY | O_PATH | O_DIRECTORY | O_NOFOLLOW, 0); ++ ++ send_fd (sock, fd); ++ xclose (fd); ++ ++ TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1); ++ TEST_VERIFY_EXIT (ch == 'a'); ++ ++ xclose (sock); ++ return 0; ++} ++ ++static void ++update_map (char * const mapping, const char * const map_file) ++{ ++ const size_t map_len = strlen (mapping); ++ ++ const int fd = xopen (map_file, O_WRONLY, 0); ++ xwrite (fd, mapping, map_len); ++ xclose (fd); ++} ++ ++static void ++proc_setgroups_write (const long child_pid, const char * const str) ++{ ++ const size_t str_len = strlen(str); ++ ++ char setgroups_path[sizeof ("/proc//setgroups") + INT_STRLEN_BOUND (long)]; ++ ++ snprintf (setgroups_path, sizeof (setgroups_path), ++ "/proc/%ld/setgroups", child_pid); ++ ++ const int fd = open (setgroups_path, O_WRONLY); ++ ++ if (fd < 0) ++ { ++ TEST_VERIFY_EXIT (errno == ENOENT); ++ FAIL_UNSUPPORTED ("/proc/%ld/setgroups not found\n", child_pid); ++ } ++ ++ xwrite (fd, str, str_len); ++ xclose(fd); ++} ++ ++static char child_stack[1024 * 1024]; ++ ++int ++do_test (void) ++{ ++ base = support_create_and_chdir_toolong_temp_directory (BASENAME); ++ ++ xmkdir (MOUNT_NAME, S_IRWXU); ++ atexit (do_cleanup); ++ ++ TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0); ++ pid_t child_pid = xclone (child_func, NULL, child_stack, ++ sizeof (child_stack), ++ CLONE_NEWUSER | CLONE_NEWNS | SIGCHLD); ++ ++ xclose (sockfd[1]); ++ const int sock = sockfd[0]; ++ ++ char map_path[sizeof ("/proc//uid_map") + INT_STRLEN_BOUND (long)]; ++ char map_buf[sizeof ("0 1") + INT_STRLEN_BOUND (long)]; ++ ++ snprintf (map_path, sizeof (map_path), "/proc/%ld/uid_map", ++ (long) child_pid); ++ snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getuid()); ++ update_map (map_buf, map_path); ++ ++ proc_setgroups_write ((long) child_pid, "deny"); ++ snprintf (map_path, sizeof (map_path), "/proc/%ld/gid_map", ++ (long) child_pid); ++ snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getgid()); ++ update_map (map_buf, map_path); ++ ++ TEST_VERIFY_EXIT (send (sock, "1", 1, MSG_NOSIGNAL) == 1); ++ const int fd = recv_fd (sock); ++ TEST_VERIFY_EXIT (fd >= 0); ++ TEST_VERIFY_EXIT (fchdir (fd) == 0); ++ ++ static char buf[2 * 10 + 1]; ++ memset (buf, 'A', sizeof (buf)); ++ ++ /* Finally, call getcwd and check if it resulted in a buffer underflow. */ ++ char * cwd = getcwd (buf + sizeof (buf) / 2, 1); ++ TEST_VERIFY (cwd == NULL); ++ TEST_VERIFY (errno == ERANGE); ++ ++ for (int i = 0; i < sizeof (buf); i++) ++ if (buf[i] != 'A') ++ { ++ printf ("buf[%d] = %02x\n", i, (unsigned int) buf[i]); ++ support_record_failure (); ++ } ++ ++ TEST_VERIFY_EXIT (send (sock, "a", 1, MSG_NOSIGNAL) == 1); ++ xclose (sock); ++ TEST_VERIFY_EXIT (xwaitpid (child_pid, NULL, 0) == child_pid); ++ ++ return 0; ++} ++ ++#define CLEANUP_HANDLER do_cleanup ++#include diff --git a/SOURCES/glibc-upstream-2.34-88.patch b/SOURCES/glibc-upstream-2.34-88.patch new file mode 100644 index 0000000..d741c3c --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-88.patch @@ -0,0 +1,28 @@ +commit d084965adc7baa8ea804427cccf973cea556d697 +Author: Siddhesh Poyarekar +Date: Mon Jan 24 21:36:41 2022 +0530 + + realpath: Avoid overwriting preexisting error (CVE-2021-3998) + + Set errno and failure for paths that are too long only if no other error + occurred earlier. + + Related: BZ #28770 + + Reviewed-by: Andreas Schwab + Signed-off-by: Siddhesh Poyarekar + (cherry picked from commit 84d2d0fe20bdf94feed82b21b4d7d136db471f03) + +diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c +index 7a23a51b3a395eb3..e2d4244fc7b8fa25 100644 +--- a/stdlib/canonicalize.c ++++ b/stdlib/canonicalize.c +@@ -404,7 +404,7 @@ error: + { + if (dest - rname <= get_path_max ()) + rname = strcpy (resolved, rname); +- else ++ else if (!failed) + { + failed = true; + __set_errno (ENAMETOOLONG); diff --git a/SOURCES/glibc-upstream-2.34-89.patch b/SOURCES/glibc-upstream-2.34-89.patch new file mode 100644 index 0000000..37ddc35 --- /dev/null +++ b/SOURCES/glibc-upstream-2.34-89.patch @@ -0,0 +1,47 @@ +commit 3438bbca90895d32825a52e31a77dc44d273c1c1 +Author: Florian Weimer +Date: Mon Jan 24 18:14:24 2022 +0100 + + Linux: Detect user namespace support in io/tst-getcwd-smallbuff + + Otherwise the test fails with certain container runtimes. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 5b8e7980c5dabd9aaefeba4f0208baa8cf7653ee) + +diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c +index d460d6e7662dc5e4..55362f6060a2b3be 100644 +--- a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c ++++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -188,6 +189,23 @@ do_test (void) + xmkdir (MOUNT_NAME, S_IRWXU); + atexit (do_cleanup); + ++ /* Check whether user namespaces are supported. */ ++ { ++ pid_t pid = xfork (); ++ if (pid == 0) ++ { ++ if (unshare (CLONE_NEWUSER | CLONE_NEWNS) != 0) ++ _exit (EXIT_UNSUPPORTED); ++ else ++ _exit (0); ++ } ++ int status; ++ xwaitpid (pid, &status, 0); ++ TEST_VERIFY_EXIT (WIFEXITED (status)); ++ if (WEXITSTATUS (status) != 0) ++ return WEXITSTATUS (status); ++ } ++ + TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0); + pid_t child_pid = xclone (child_func, NULL, child_stack, + sizeof (child_stack), diff --git a/SOURCES/glibc-upstream-2.34-91.patch b/SOURCES/glibc-upstream-2.34-91.patch new file mode 100644 index 0000000..f577e34 --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-upstream-2.34-92.patch b/SOURCES/glibc-upstream-2.34-92.patch new file mode 100644 index 0000000..03a51c6 --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-upstream-2.34-97.patch b/SOURCES/glibc-upstream-2.34-97.patch new file mode 100644 index 0000000..e9adea4 --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-upstream-2.34-98.patch b/SOURCES/glibc-upstream-2.34-98.patch new file mode 100644 index 0000000..adbb154 --- /dev/null +++ b/SOURCES/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/SOURCES/glibc-upstream-2.34-99.patch b/SOURCES/glibc-upstream-2.34-99.patch new file mode 100644 index 0000000..7df75d8 --- /dev/null +++ b/SOURCES/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/SPECS/glibc.spec b/SPECS/glibc.spec index 110f94e..fca6312 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -148,7 +148,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 16%{?dist} +Release: 25%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -287,6 +287,94 @@ Patch87: glibc-upstream-2.34-51.patch Patch88: glibc-upstream-2.34-52.patch Patch89: glibc-upstream-2.34-53.patch Patch90: glibc-rh1988382.patch +Patch91: glibc-upstream-2.34-54.patch +Patch92: glibc-upstream-2.34-55.patch +Patch93: glibc-upstream-2.34-56.patch +Patch94: glibc-upstream-2.34-57.patch +Patch95: glibc-upstream-2.34-58.patch +Patch96: glibc-upstream-2.34-59.patch +Patch97: glibc-upstream-2.34-60.patch +Patch98: glibc-upstream-2.34-61.patch +Patch99: glibc-upstream-2.34-62.patch +Patch100: glibc-upstream-2.34-63.patch +Patch101: glibc-upstream-2.34-64.patch +Patch102: glibc-upstream-2.34-65.patch +Patch103: glibc-upstream-2.34-66.patch +Patch104: glibc-upstream-2.34-67.patch +Patch105: glibc-upstream-2.34-68.patch +Patch106: glibc-upstream-2.34-69.patch +Patch107: glibc-upstream-2.34-70.patch +Patch108: glibc-upstream-2.34-71.patch +Patch109: glibc-upstream-2.34-72.patch +Patch110: glibc-upstream-2.34-73.patch +Patch111: glibc-rh2032647-1.patch +Patch112: glibc-rh2032647-2.patch +Patch113: glibc-rh2032647-3.patch +Patch114: glibc-rh2032647-4.patch +Patch115: glibc-rh2032647-5.patch +Patch116: glibc-rh2032647-6.patch +Patch117: glibc-rh2024347-1.patch +Patch118: glibc-rh2024347-2.patch +Patch119: glibc-rh2024347-3.patch +Patch120: glibc-rh2024347-4.patch +Patch121: glibc-rh2024347-5.patch +Patch122: glibc-rh2024347-6.patch +Patch123: glibc-rh2024347-7.patch +Patch124: glibc-rh2024347-8.patch +Patch125: glibc-rh2024347-9.patch +Patch126: glibc-rh2024347-10.patch +Patch127: glibc-rh2024347-11.patch +Patch128: glibc-rh2024347-12.patch +Patch129: glibc-rh2024347-13.patch +Patch130: glibc-rh2040657-1.patch +Patch131: glibc-rh2040657-2.patch +Patch132: glibc-rh2040657-3.patch +Patch133: glibc-rh2040657-4.patch +Patch134: glibc-rh2040657-5.patch +Patch135: glibc-rh2040657-6.patch +Patch136: glibc-rh2040657-7.patch +Patch137: glibc-rh2040657-8.patch +Patch138: glibc-rh2040657-9.patch +Patch139: glibc-rh2040657-10.patch +Patch140: glibc-rh2040657-11.patch +Patch141: glibc-rh2040657-12.patch +Patch142: glibc-upstream-2.34-74.patch +Patch143: glibc-upstream-2.34-75.patch +Patch144: glibc-upstream-2.34-76.patch +Patch145: glibc-upstream-2.34-77.patch +Patch146: glibc-upstream-2.34-78.patch +Patch147: glibc-upstream-2.34-79.patch +Patch148: glibc-upstream-2.34-80.patch +Patch149: glibc-upstream-2.34-81.patch +Patch150: glibc-upstream-2.34-82.patch +Patch151: glibc-upstream-2.34-83.patch +Patch152: glibc-upstream-2.34-84.patch +Patch153: glibc-upstream-2.34-85.patch +Patch154: glibc-upstream-2.34-86.patch +Patch155: glibc-upstream-2.34-87.patch +Patch156: glibc-upstream-2.34-88.patch +Patch157: glibc-upstream-2.34-89.patch +# glibc-2.34-90-g1b9cd6a721 only changes NEWS. +Patch158: glibc-upstream-2.34-91.patch +Patch159: glibc-upstream-2.34-92.patch +# glibc-2.34-93-g72123e1b56 only changes NEWS. +# glibc-2.34-94-g31186e2cb7 is glibc-rh2040657-1.patch. +# glibc-2.34-95-g511b244cc5 is glibc-rh2040657-2.patch. +# glibc-2.34-96-gde6cdd6875 is glibc-rh2040657-6.patch. +Patch160: glibc-upstream-2.34-97.patch +Patch161: glibc-upstream-2.34-98.patch +Patch162: glibc-upstream-2.34-99.patch +Patch163: glibc-c-utf8-locale-3.patch +Patch164: glibc-c-utf8-locale-4.patch +Patch165: glibc-c-utf8-locale-5.patch +Patch166: glibc-upstream-2.34-100.patch +Patch167: glibc-upstream-2.34-101.patch +Patch168: glibc-upstream-2.34-102.patch +Patch169: glibc-upstream-2.34-103.patch +Patch170: glibc-upstream-2.34-104.patch +Patch171: glibc-upstream-2.34-105.patch +Patch172: glibc-upstream-2.34-106.patch +Patch173: glibc-upstream-2.34-107.patch ############################################################################## # Continued list of core "glibc" package information: @@ -1203,6 +1291,20 @@ rpm_inherit_flags \ "-mtune=zEC12" \ "-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1" \ +# Use the RHEL 8 baseline for the early dynamic loader code, so that +# running on too old CPUs results in a diagnostic. +%if 0%{?rhel} >= 9 +%ifarch ppc64le +%define glibc_rtld_early_cflags -mcpu=power8 +%endif +%ifarch s390x +%define glibc_rtld_early_cflags -march=z13 +%endif +%ifarch x86_64 +%define glibc_rtld_early_cflags -march=x86-64 +%endif +%endif + # libc_nonshared.a cannot be built with the default hardening flags # because the glibc build system is incompatible with # -D_FORTIFY_SOURCE. The object files need to be marked as to be @@ -1249,6 +1351,7 @@ build() --enable-tunables \ --enable-systemtap \ ${core_with_options} \ + %{?glibc_rtld_early_cflags:--with-rtld-early-cflags=%glibc_rtld_early_cflags} \ %ifarch x86_64 %{ix86} --enable-cet \ %endif @@ -2315,6 +2418,87 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Thu Feb 3 2022 Florian Weimer - 2.34-25 +- Sync with upstream branch release/2.34/master, + commit 6eaf10cbb78d22eae7999d9de55f6b93999e0860: +- socket: Do not use AF_NETLINK in __opensock +- hurd if_index: Explicitly use AF_INET for if index discovery +- Linux: Simplify __opensock and fix race condition [BZ #28353] +- linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage [BZ #28850] + +* Tue Feb 1 2022 Florian Weimer - 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: +- Linux: Detect user namespace support in io/tst-getcwd-smallbuff +- realpath: Avoid overwriting preexisting error +- CVE-2021-3999: getcwd: Set errno to ERANGE for size == 1 +- tst-realpath-toolong: Fix hurd build +- CVE-2021-3998: realpath: ENAMETOOLONG for result larger than PATH_MAX +- stdlib: Fix formatting of tests list in Makefile +- stdlib: Sort tests in Makefile +- support: Add helpers to create paths longer than PATH_MAX +- powerpc: Fix unrecognized instruction errors with recent binutils +- x86: use default cache size if it cannot be determined [BZ #28784] +- CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768) +- sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542) +- CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542) +- socket: Add the __sockaddr_un_set function +- Disable debuginfod in printer tests [BZ #28757] +- Update syscall lists for Linux 5.16 + +* Wed Jan 19 2022 Florian Weimer - 2.34-20 +- More reliable CPU compatibility diagnostics (#2040657) + +* Fri Jan 14 2022 Florian Weimer - 2.34-19 +- Optionally accelerate sched_getcpu using rseq (#2024347) + +* Thu Jan 13 2022 Florian Weimer - 2.34-18 +- Backport optimized ELF dependency sorting algorithm (#2032647) + +* Thu Jan 13 2022 Florian Weimer - 2.34-17 +- Sync with upstream branch release/2.34/master, + commit 2fe2af88abd13ae5636881da2e26f461ecb7dfb5 +- i386: Remove broken CAN_USE_REGISTER_ASM_EBP (bug 28771) +- Update syscall lists for Linux 5.15 +- powerpc: Fix unrecognized instruction errors with recent GCC +- timezone: test-case for BZ #28707 +- timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707) +- Fix subscript error with odd TZif file [BZ #28338] +- AArch64: Check for SVE in ifuncs [BZ #28744] +- intl/plural.y: Avoid conflicting declarations of yyerror and yylex +- Linux: Fix 32-bit vDSO for clock_gettime on powerpc32 +- linux: Add sparck brk implementation +- Update sparc libm-test-ulps +- Update hppa libm-test-ulps +- riscv: align stack before calling _dl_init [BZ #28703] +- riscv: align stack in clone [BZ #28702] +- powerpc64[le]: Allocate extra stack frame on syscall.S +- elf: Fix tst-cpu-features-cpuinfo for KVM guests on some AMD systems [BZ #28704] +- nss: Use "files dns" as the default for the hosts database (bug 28700) +- arm: Guard ucontext _rtld_global_ro access by SHARED, not PIC macro +- mips: increase stack alignment in clone to match the ABI +- mips: align stack in clone [BZ #28223] + * Tue Dec 14 2021 Siddhesh Poyarekar - 2.34-16 - Enable PIE by default on all architectures (#1988382)