diff --git a/glibc-RHEL-58989-1.patch b/glibc-RHEL-58989-1.patch new file mode 100644 index 0000000..dd7bd38 --- /dev/null +++ b/glibc-RHEL-58989-1.patch @@ -0,0 +1,228 @@ +commit 3d53d18fc71c5d9ef4773b8bce04d54b80181926 +Author: Adhemerval Zanella +Date: Tue Mar 12 13:21:20 2024 -0300 + + elf: Enable TLS descriptor tests on aarch64 + + The aarch64 uses 'trad' for traditional tls and 'desc' for tls + descriptors, but unlike other targets it defaults to 'desc'. The + gnutls2 configure check does not set aarch64 as an ABI that uses + TLS descriptors, which then disable somes stests. + + Also rename the internal machinery fron gnu2 to tls descriptors. + + Checked on aarch64-linux-gnu. + Reviewed-by: H.J. Lu + + +Conflicts: + configure (regenerated) + configure.ac (fixed context) + elf/Makefile (fixed context) + sysdeps/arm/Makefile (fixed context) + +diff --git a/configure b/configure +index afa094324cdcf96d..605309159db1e2a0 100755 +--- a/configure ++++ b/configure +@@ -619,7 +619,7 @@ LIBGD + libc_cv_cc_loop_to_function + libc_cv_cc_submachine + libc_cv_cc_nofma +-libc_cv_mtls_dialect_gnu2 ++libc_cv_mtls_descriptor + fno_unit_at_a_time + libc_cv_has_glob_dat + libc_cv_hashstyle +@@ -3896,6 +3896,9 @@ libc_config_ok=no + # whether to use such directories. + with_fp_cond=1 + ++# A preconfigure script may define another name to TLS descriptor variant ++mtls_descriptor=gnu2 ++ + if frags=`ls -d $srcdir/sysdeps/*/preconfigure 2> /dev/null` + then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysdeps preconfigure fragments" >&5 +@@ -6162,9 +6165,9 @@ else + fi + + +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -mtls-dialect=gnu2" >&5 +-$as_echo_n "checking for -mtls-dialect=gnu2... " >&6; } +-if ${libc_cv_mtls_dialect_gnu2+:} false; then : ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tls descriptor support" >&5 ++$as_echo_n "checking for tls descriptor support... " >&6; } ++if ${libc_cv_mtls_descriptor+:} false; then : + $as_echo_n "(cached) " >&6 + else + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then +- libc_cv_mtls_dialect_gnu2=yes ++ libc_cv_mtls_descriptor=$mtls_descriptor + else +- libc_cv_mtls_dialect_gnu2=no ++ libc_cv_mtls_descriptor=no + fi + rm -f conftest* + fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mtls_dialect_gnu2" >&5 +-$as_echo "$libc_cv_mtls_dialect_gnu2" >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mtls_descriptor" >&5 ++$as_echo "$libc_cv_mtls_descriptor" >&6; } + + config_vars="$config_vars +-have-mtls-dialect-gnu2 = $libc_cv_mtls_dialect_gnu2" ++have-mtls-descriptor = $libc_cv_mtls_descriptor" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc puts quotes around section names" >&5 + $as_echo_n "checking whether cc puts quotes around section names... " >&6; } +diff --git a/configure.ac b/configure.ac +index 85ea64f9f5f4fd35..d18d8bdff9a7849d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -533,6 +533,9 @@ libc_config_ok=no + # whether to use such directories. + with_fp_cond=1 + ++# A preconfigure script may define another name to TLS descriptor variant ++mtls_descriptor=gnu2 ++ + dnl Let sysdeps/*/preconfigure act here. + LIBC_PRECONFIGURE([$srcdir], [for sysdeps]) + +@@ -1429,7 +1432,7 @@ else + fi + AC_SUBST(fno_unit_at_a_time) + +-AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2, ++AC_CACHE_CHECK([for tls descriptor support], libc_cv_mtls_descriptor, + [dnl + cat > conftest.c <&AS_MESSAGE_LOG_FD]) ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=$mtls_descriptor -nostdlib -nostartfiles ++ -shared conftest.c -o conftest 1>&AS_MESSAGE_LOG_FD]) + then +- libc_cv_mtls_dialect_gnu2=yes ++ libc_cv_mtls_descriptor=$mtls_descriptor + else +- libc_cv_mtls_dialect_gnu2=no ++ libc_cv_mtls_descriptor=no + fi + rm -f conftest*]) +-AC_SUBST(libc_cv_mtls_dialect_gnu2) +-LIBC_CONFIG_VAR([have-mtls-dialect-gnu2], [$libc_cv_mtls_dialect_gnu2]) ++AC_SUBST(libc_cv_mtls_descriptor) ++LIBC_CONFIG_VAR([have-mtls-descriptor], [$libc_cv_mtls_descriptor]) + + AC_CACHE_CHECK(whether cc puts quotes around section names, + libc_cv_have_section_quotes, +diff --git a/elf/Makefile b/elf/Makefile +index 7d686ca7d190c921..65eb3b9b28183821 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -944,13 +944,13 @@ modules-names-tests = $(filter-out ifuncmod% tst-tlsmod% \ + tst-hash-collision3-mod,\ + $(modules-names)) + +-ifeq (yes,$(have-mtls-dialect-gnu2)) ++ifneq (no,$(have-mtls-descriptor)) + tests += tst-gnu2-tls1 + modules-names += tst-gnu2-tls1mod + $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so + tst-gnu2-tls1mod.so-no-z-defs = yes +-CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 +-endif # $(have-mtls-dialect-gnu2) ++CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=$(have-mtls-descriptor) ++endif # $(have-mtls-descriptor) + + ifeq (yes,$(have-protected-data)) + modules-names += tst-protected1moda tst-protected1modb +@@ -2719,11 +2719,11 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: \ + $(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \ + $(objpfx)tst-audit-tlsdesc-mod2.so \ + $(shared-thread-library) +-ifeq (yes,$(have-mtls-dialect-gnu2)) ++ifneq (no,$(have-mtls-descriptor)) + # The test is valid for all TLS types, but we want to exercise GNU2 + # TLS if possible. +-CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2 +-CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2 ++CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=$(have-mtls-descriptor) + endif + $(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library) + $(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \ +@@ -2763,10 +2763,14 @@ $(objpfx)tst-tlsgap.out: \ + $(objpfx)tst-tlsgap-mod0.so \ + $(objpfx)tst-tlsgap-mod1.so \ + $(objpfx)tst-tlsgap-mod2.so +-ifeq (yes,$(have-mtls-dialect-gnu2)) +-CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2 +-CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2 +-CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2 ++ ++ifneq (no,$(have-mtls-descriptor)) ++CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-gnu2-tls2mod0.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-gnu2-tls2mod1.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-gnu2-tls2mod2.c += -mtls-dialect=$(have-mtls-descriptor) + endif + + $(objpfx)tst-recursive-tls: $(objpfx)tst-recursive-tlsmallocmod.so +diff --git a/sysdeps/aarch64/preconfigure b/sysdeps/aarch64/preconfigure +index d9bd1f8558a079cb..19657b627bc84c4e 100644 +--- a/sysdeps/aarch64/preconfigure ++++ b/sysdeps/aarch64/preconfigure +@@ -2,5 +2,6 @@ case "$machine" in + aarch64*) + base_machine=aarch64 + machine=aarch64 ++ mtls_descriptor=desc + ;; + esac +diff --git a/sysdeps/arm/Makefile b/sysdeps/arm/Makefile +index fb4164f0d9cf71fa..efe08b15e16ccda4 100644 +--- a/sysdeps/arm/Makefile ++++ b/sysdeps/arm/Makefile +@@ -18,15 +18,15 @@ $(objpfx)libgcc-stubs.a: $(objpfx)aeabi_unwind_cpp_pr1.os + lib-noranlib: $(objpfx)libgcc-stubs.a + + ifeq ($(build-shared),yes) +-ifeq ($(have-arm-tls-desc),yes) ++ifneq (no,$(have-mtls-descriptor)) + tests += tst-armtlsdescloc tst-armtlsdescextnow tst-armtlsdescextlazy + modules-names += tst-armtlsdesclocmod + modules-names += tst-armtlsdescextlazymod tst-armtlsdescextnowmod + CPPFLAGS-tst-armtlsdescextnowmod.c += -Dstatic= + CPPFLAGS-tst-armtlsdescextlazymod.c += -Dstatic= +-CFLAGS-tst-armtlsdesclocmod.c += -mtls-dialect=gnu2 +-CFLAGS-tst-armtlsdescextnowmod.c += -mtls-dialect=gnu2 +-CFLAGS-tst-armtlsdescextlazymod.c += -mtls-dialect=gnu2 ++CFLAGS-tst-armtlsdesclocmod.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-armtlsdescextnowmod.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-armtlsdescextlazymod.c += -mtls-dialect=$(have-mtls-descriptor) + LDFLAGS-tst-armtlsdescextnowmod.so += -Wl,-z,now + tst-armtlsdescloc-ENV = LD_BIND_NOW=1 + tst-armtlsdescextnow-ENV = LD_BIND_NOW=1 diff --git a/glibc-RHEL-58989-2.patch b/glibc-RHEL-58989-2.patch new file mode 100644 index 0000000..bbf813a --- /dev/null +++ b/glibc-RHEL-58989-2.patch @@ -0,0 +1,495 @@ +commit 9b5f2eb9fc5d3cf4b984f6002e69aac43296e922 +Author: Joseph Myers +Date: Thu Dec 5 09:53:47 2024 +0000 + + Add further test of TLS + + Add an additional test of TLS variables, with different alignment, + accessed from different modules. The idea of the alignment test is + similar to tst-tlsalign and the same code is shared for setting up + test variables, but unlike the tst-tlsalign code, there are multiple + threads and variables are accessed from multiple objects to verify + that they get a consistent notion of the address of an object within a + thread. Threads are repeatedly created and shut down to verify proper + initialization in each new thread. The test is also repeated with TLS + descriptors when supported. (However, only initial-exec TLS is + covered in this test.) + + Tested for x86_64. + +Conflicts: + elf/Makefile (fixup context) + +diff --git a/elf/Makefile b/elf/Makefile +index 4a9c983686126adf..9d48e408de0a67a4 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -454,6 +454,8 @@ tests += \ + tst-tls19 \ + tst-tls20 \ + tst-tls21 \ ++ tst-tls22 \ ++ tst-tls22-gnu2 \ + tst-tls4 \ + tst-tls5 \ + tst-tlsalign \ +@@ -592,9 +594,15 @@ tst-tls-many-dynamic-modules-dep-bad = \ + extra-test-objs += \ + $(tlsmod17a-modules:=.os) \ + $(tlsmod18a-modules:=.os) \ ++ tst-tls22-mod1-vars.os \ ++ tst-tls22-mod2-vars.os \ ++ tst-tls22-vars.o \ + tst-tlsalign-vars.o \ + # extra-test-objs + test-extras += \ ++ tst-tls22-mod1-vars \ ++ tst-tls22-mod2-vars \ ++ tst-tls22-vars \ + tst-tlsalign-vars \ + tst-tlsmod17a \ + tst-tlsmod18a \ +@@ -840,6 +848,10 @@ modules-names = \ + tst-tls19mod3 \ + tst-tls20mod-bad \ + tst-tls21mod \ ++ tst-tls22-mod1 \ ++ tst-tls22-mod1-gnu2 \ ++ tst-tls22-mod2 \ ++ tst-tls22-mod2-gnu2 \ + tst-tlsalign-lib \ + tst-tlsgap-mod0 \ + tst-tlsgap-mod1 \ +@@ -2822,3 +2834,27 @@ $(objpfx)tst-hash-collision2-sysv: $(objpfx)tst-hash-collision2-mod1-sysv.so \ + LDFLAGS-tst-hash-collision3-mod.so = \ + -Wl,--version-script=tst-hash-collision3-mod.map + $(objpfx)tst-hash-collision3: $(objpfx)tst-hash-collision3-mod.so ++ ++$(objpfx)tst-tls22: $(objpfx)tst-tls22-vars.o $(objpfx)tst-tls22-mod1.so \ ++ $(objpfx)tst-tls22-mod2.so $(shared-thread-library) ++$(objpfx)tst-tls22-mod1.so: $(objpfx)tst-tls22-mod1.os \ ++ $(objpfx)tst-tls22-mod1-vars.os $(objpfx)tst-tls22-mod2.so ++$(objpfx)tst-tls22-mod2.so: $(objpfx)tst-tls22-mod2.os \ ++ $(objpfx)tst-tls22-mod2-vars.os ++$(objpfx)tst-tls22-gnu2: $(objpfx)tst-tls22-vars.o \ ++ $(objpfx)tst-tls22-mod1-gnu2.so $(objpfx)tst-tls22-mod2-gnu2.so \ ++ $(shared-thread-library) ++$(objpfx)tst-tls22-mod1-gnu2.so: $(objpfx)tst-tls22-mod1-gnu2.os \ ++ $(objpfx)tst-tls22-mod1-vars.os $(objpfx)tst-tls22-mod2-gnu2.so ++$(objpfx)tst-tls22-mod2-gnu2.so: $(objpfx)tst-tls22-mod2-gnu2.os \ ++ $(objpfx)tst-tls22-mod2-vars.os ++ifneq (no,$(have-mtls-descriptor)) ++CFLAGS-tst-tls22-gnu2.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-tls22-mod1-gnu2.c += -mtls-dialect=$(have-mtls-descriptor) ++CFLAGS-tst-tls22-mod2-gnu2.c += -mtls-dialect=$(have-mtls-descriptor) ++endif ++# These reference symbols from the main executable. ++tst-tls22-mod1.so-no-z-defs = yes ++tst-tls22-mod1-gnu2.so-no-z-defs = yes ++tst-tls22-mod2.so-no-z-defs = yes ++tst-tls22-mod2-gnu2.so-no-z-defs = yes +diff --git a/elf/tst-tls22-gnu2.c b/elf/tst-tls22-gnu2.c +new file mode 100644 +index 0000000000000000..d9ce6df0b2bcc201 +--- /dev/null ++++ b/elf/tst-tls22-gnu2.c +@@ -0,0 +1 @@ ++#include +diff --git a/elf/tst-tls22-mod1-gnu2.c b/elf/tst-tls22-mod1-gnu2.c +new file mode 100644 +index 0000000000000000..0b085fe175b74962 +--- /dev/null ++++ b/elf/tst-tls22-mod1-gnu2.c +@@ -0,0 +1 @@ ++#include +diff --git a/elf/tst-tls22-mod1-vars.c b/elf/tst-tls22-mod1-vars.c +new file mode 100644 +index 0000000000000000..bdb7358287a325ee +--- /dev/null ++++ b/elf/tst-tls22-mod1-vars.c +@@ -0,0 +1,9 @@ ++#include ++ ++#define tdata1 mod1_tdata1 ++#define tdata2 mod1_tdata2 ++#define tdata3 mod1_tdata3 ++#define tbss1 mod1_tbss1 ++#define tbss2 mod1_tbss2 ++#define tbss3 mod1_tbss3 ++#include +diff --git a/elf/tst-tls22-mod1.c b/elf/tst-tls22-mod1.c +new file mode 100644 +index 0000000000000000..3a47d7bbc6cd16c2 +--- /dev/null ++++ b/elf/tst-tls22-mod1.c +@@ -0,0 +1,27 @@ ++/* Test TLS with varied alignment and multiple modules and threads. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++test_mod1 (struct one_thread_data *data, int base_val) ++{ ++ STORE_ADDRS (&data->mod1_self, mod1); ++ STORE_ADDRS (&data->exe_from_mod1, exe); ++ STORE_ADDRS (&data->mod2_from_mod1, mod2); ++} +diff --git a/elf/tst-tls22-mod2-gnu2.c b/elf/tst-tls22-mod2-gnu2.c +new file mode 100644 +index 0000000000000000..a5260e0616d8b595 +--- /dev/null ++++ b/elf/tst-tls22-mod2-gnu2.c +@@ -0,0 +1 @@ ++#include +diff --git a/elf/tst-tls22-mod2-vars.c b/elf/tst-tls22-mod2-vars.c +new file mode 100644 +index 0000000000000000..9ef3452bba56e829 +--- /dev/null ++++ b/elf/tst-tls22-mod2-vars.c +@@ -0,0 +1,9 @@ ++#include ++ ++#define tdata1 mod2_tdata1 ++#define tdata2 mod2_tdata2 ++#define tdata3 mod2_tdata3 ++#define tbss1 mod2_tbss1 ++#define tbss2 mod2_tbss2 ++#define tbss3 mod2_tbss3 ++#include +diff --git a/elf/tst-tls22-mod2.c b/elf/tst-tls22-mod2.c +new file mode 100644 +index 0000000000000000..5d26d592b0262b1e +--- /dev/null ++++ b/elf/tst-tls22-mod2.c +@@ -0,0 +1,26 @@ ++/* Test TLS with varied alignment and multiple modules and threads. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++test_mod2 (struct one_thread_data *data, int base_val) ++{ ++ STORE_ADDRS (&data->mod2_self, mod2); ++ STORE_ADDRS (&data->exe_from_mod2, exe); ++} +diff --git a/elf/tst-tls22-vars.c b/elf/tst-tls22-vars.c +new file mode 100644 +index 0000000000000000..2ad3ee7a3b6ac980 +--- /dev/null ++++ b/elf/tst-tls22-vars.c +@@ -0,0 +1,9 @@ ++#include ++ ++#define tdata1 exe_tdata1 ++#define tdata2 exe_tdata2 ++#define tdata3 exe_tdata3 ++#define tbss1 exe_tbss1 ++#define tbss2 exe_tbss2 ++#define tbss3 exe_tbss3 ++#include +diff --git a/elf/tst-tls22.c b/elf/tst-tls22.c +new file mode 100644 +index 0000000000000000..35a8cd82b22462ff +--- /dev/null ++++ b/elf/tst-tls22.c +@@ -0,0 +1,147 @@ ++/* Test TLS with varied alignment and multiple modules and threads. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static void ++check_addrs_align (const struct obj_addrs *addrs) ++{ ++ TEST_COMPARE (addrs->addr_tdata1 & (__alignof__ (int) - 1), 0); ++ TEST_COMPARE (addrs->addr_tdata2 & 0xf, 0); ++ TEST_COMPARE (addrs->addr_tdata3 & 0xfff, 0); ++ TEST_COMPARE (addrs->addr_tbss1 & (__alignof__ (int) - 1), 0); ++ TEST_COMPARE (addrs->addr_tbss2 & 0xf, 0); ++ TEST_COMPARE (addrs->addr_tbss3 & 0xfff, 0); ++} ++ ++static void ++check_addrs_same (const struct obj_addrs *addrs1, ++ const struct obj_addrs *addrs2) ++{ ++ TEST_COMPARE (addrs1->addr_tdata1, addrs2->addr_tdata1); ++ TEST_COMPARE (addrs1->addr_tdata2, addrs2->addr_tdata2); ++ TEST_COMPARE (addrs1->addr_tdata3, addrs2->addr_tdata3); ++ TEST_COMPARE (addrs1->addr_tbss1, addrs2->addr_tbss1); ++ TEST_COMPARE (addrs1->addr_tbss2, addrs2->addr_tbss2); ++ TEST_COMPARE (addrs1->addr_tbss3, addrs2->addr_tbss3); ++} ++ ++static void ++check_vals_before (const struct obj_values *vals) ++{ ++ TEST_COMPARE (vals->val_tdata1, 1); ++ TEST_COMPARE (vals->val_tdata2, 2); ++ TEST_COMPARE (vals->val_tdata3, 4); ++ TEST_COMPARE (vals->val_tbss1, 0); ++ TEST_COMPARE (vals->val_tbss2, 0); ++ TEST_COMPARE (vals->val_tbss3, 0); ++} ++ ++static void ++check_vals_after (const struct obj_values *vals, int base_val) ++{ ++ TEST_COMPARE (vals->val_tdata1, base_val); ++ TEST_COMPARE (vals->val_tdata2, base_val + 1); ++ TEST_COMPARE (vals->val_tdata3, base_val + 2); ++ TEST_COMPARE (vals->val_tbss1, base_val + 3); ++ TEST_COMPARE (vals->val_tbss2, base_val + 4); ++ TEST_COMPARE (vals->val_tbss3, base_val + 5); ++} ++ ++static void ++check_one_thread (const struct one_thread_data *data, int base_val) ++{ ++ check_vals_before (&data->exe_before); ++ check_vals_before (&data->mod1_before); ++ check_vals_before (&data->mod2_before); ++ check_vals_after (&data->exe_after, base_val); ++ check_vals_after (&data->mod1_after, base_val); ++ check_vals_after (&data->mod2_after, base_val); ++ check_addrs_align (&data->exe_self); ++ check_addrs_same (&data->exe_self, &data->exe_from_mod1); ++ check_addrs_same (&data->exe_self, &data->exe_from_mod2); ++ check_addrs_align (&data->mod1_self); ++ check_addrs_same (&data->mod1_self, &data->mod1_from_exe); ++ check_addrs_align (&data->mod2_self); ++ check_addrs_same (&data->mod2_self, &data->mod2_from_exe); ++ check_addrs_same (&data->mod2_self, &data->mod2_from_mod1); ++} ++ ++static void * ++thread_func (void *arg) ++{ ++ int base_val = (int) (intptr_t) arg + 10; ++ struct one_thread_data data; ++ /* Record the addresses of variables as seen from the main ++ executable (which should be the same as seen from the other ++ modules), and their initial values. */ ++ STORE_ADDRS (&data.exe_self, exe); ++ STORE_ADDRS (&data.mod1_from_exe, mod1); ++ STORE_ADDRS (&data.mod2_from_exe, mod2); ++ STORE_VALUES (&data.exe_before, exe); ++ STORE_VALUES (&data.mod1_before, mod1); ++ STORE_VALUES (&data.mod2_before, mod2); ++ /* Overwrite the value of variables. */ ++ OVERWRITE_VALUES (exe, base_val); ++ OVERWRITE_VALUES (mod1, base_val); ++ OVERWRITE_VALUES (mod2, base_val); ++ /* Record the addresses of variables as seen from other modules. */ ++ test_mod1 (&data, base_val); ++ test_mod2 (&data, base_val); ++ /* Record the overwritten values (thus making sure that no other ++ thread running in parallel has changed this thread's values). */ ++ STORE_VALUES (&data.exe_after, exe); ++ STORE_VALUES (&data.mod1_after, mod1); ++ STORE_VALUES (&data.mod2_after, mod2); ++ /* Check all the addresses and values recorded. */ ++ check_one_thread (&data, base_val); ++ return NULL; ++} ++ ++#define NUM_ITERS 50 ++#define NUM_THREADS 16 ++ ++/* For NUM_ITERS iterations, repeatedly create NUM_THREADS threads. ++ In each thread, we determine the addresses of TLS objects (both ++ from the module defining those objects and from other modules), and ++ their initial values, and store in values that are then read back; ++ we check that each object's address is the same regardless of the ++ module in which it is determined, that alignment of objects is as ++ required, and that the values of objects are as expected. */ ++ ++static int ++do_test (void) ++{ ++ for (size_t i = 0; i < NUM_ITERS; i++) ++ { ++ pthread_t threads[NUM_THREADS]; ++ for (size_t j = 0; j < NUM_THREADS; j++) ++ threads[j] = xpthread_create (NULL, thread_func, (void *) j); ++ /* Also run checks in the main thread, but only once because ++ those values don't get reinitialized. */ ++ if (i == 0) ++ thread_func ((void *) NUM_THREADS); ++ for (size_t j = 0; j < NUM_THREADS; j++) ++ xpthread_join (threads[j]); ++ } ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-tls22.h b/elf/tst-tls22.h +new file mode 100644 +index 0000000000000000..24b2e0a0b6af4d45 +--- /dev/null ++++ b/elf/tst-tls22.h +@@ -0,0 +1,115 @@ ++/* Test TLS with varied alignment and multiple modules and threads: header. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef TST_TLS22_H ++#define TST_TLS22_H ++ ++#include ++ ++extern __thread int exe_tdata1 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int exe_tdata2 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int exe_tdata3 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int exe_tbss1 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int exe_tbss2 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int exe_tbss3 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod1_tdata1 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod1_tdata2 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod1_tdata3 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod1_tbss1 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod1_tbss2 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod1_tbss3 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod2_tdata1 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod2_tdata2 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod2_tdata3 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod2_tbss1 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod2_tbss2 __attribute__ ((tls_model ("initial-exec"))); ++extern __thread int mod2_tbss3 __attribute__ ((tls_model ("initial-exec"))); ++ ++/* Structure to store the addresses of one set of TLS objects in one ++ thread, as seen by one module in the program. */ ++struct obj_addrs ++{ ++ uintptr_t addr_tdata1, addr_tdata2, addr_tdata3; ++ uintptr_t addr_tbss1, addr_tbss2, addr_tbss3; ++}; ++ ++/* Structure to store the values of one set of TLS objects in one ++ thread. */ ++struct obj_values ++{ ++ uintptr_t val_tdata1, val_tdata2, val_tdata3; ++ uintptr_t val_tbss1, val_tbss2, val_tbss3; ++}; ++ ++/* Structure to store all the data about TLS objects in one ++ thread. */ ++struct one_thread_data ++{ ++ struct obj_addrs exe_self, exe_from_mod1, exe_from_mod2; ++ struct obj_addrs mod1_self, mod1_from_exe; ++ struct obj_addrs mod2_self, mod2_from_exe, mod2_from_mod1; ++ struct obj_values exe_before, mod1_before, mod2_before; ++ struct obj_values exe_after, mod1_after, mod2_after; ++}; ++ ++/* Store the addresses of variables prefixed by PFX in the structure ++ pointed to by DST. */ ++#define STORE_ADDRS(DST, PFX) \ ++ do \ ++ { \ ++ (DST)->addr_tdata1 = (uintptr_t) &PFX ## _tdata1; \ ++ (DST)->addr_tdata2 = (uintptr_t) &PFX ## _tdata2; \ ++ (DST)->addr_tdata3 = (uintptr_t) &PFX ## _tdata3; \ ++ (DST)->addr_tbss1 = (uintptr_t) &PFX ## _tbss1; \ ++ (DST)->addr_tbss2 = (uintptr_t) &PFX ## _tbss2; \ ++ (DST)->addr_tbss3 = (uintptr_t) &PFX ## _tbss3; \ ++ } \ ++ while (0) ++ ++/* Store the values of variables prefixed by PFX in the structure ++ pointed to by DST. */ ++#define STORE_VALUES(DST, PFX) \ ++ do \ ++ { \ ++ (DST)->val_tdata1 = PFX ## _tdata1; \ ++ (DST)->val_tdata2 = PFX ## _tdata2; \ ++ (DST)->val_tdata3 = PFX ## _tdata3; \ ++ (DST)->val_tbss1 = PFX ## _tbss1; \ ++ (DST)->val_tbss2 = PFX ## _tbss2; \ ++ (DST)->val_tbss3 = PFX ## _tbss3; \ ++ } \ ++ while (0) ++ ++/* Overwrite the values of variables prefixed by PFX with values ++ starting with VAL. */ ++#define OVERWRITE_VALUES(PFX, VAL) \ ++ do \ ++ { \ ++ PFX ## _tdata1 = (VAL); \ ++ PFX ## _tdata2 = (VAL) + 1; \ ++ PFX ## _tdata3 = (VAL) + 2; \ ++ PFX ## _tbss1 = (VAL) + 3; \ ++ PFX ## _tbss2 = (VAL) + 4; \ ++ PFX ## _tbss3 = (VAL) + 5; \ ++ } \ ++ while (0) ++ ++void test_mod1 (struct one_thread_data *data, int base_val); ++void test_mod2 (struct one_thread_data *data, int base_val); ++ ++#endif /* TST_TLS22_H */ diff --git a/glibc.spec b/glibc.spec index ee09a78..b571ad0 100644 --- a/glibc.spec +++ b/glibc.spec @@ -157,7 +157,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 151%{?dist} +Release: 152%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1067,6 +1067,8 @@ Patch759: glibc-RHEL-65358-2.patch Patch760: glibc-RHEL-65358-3.patch Patch761: glibc-RHEL-65358-4.patch Patch762: glibc-RHEL-65358-5.patch +Patch763: glibc-RHEL-58989-1.patch +Patch764: glibc-RHEL-58989-2.patch ############################################################################## # Continued list of core "glibc" package information: @@ -3060,6 +3062,9 @@ update_gconv_modules_cache () %endif %changelog +* Fri Jan 10 2025 Frédéric Bérat - 2.34-152 +- Additional TLS test cases (RHEL-58989) + * Fri Jan 10 2025 Frédéric Bérat - 2.34-151 - Lock all stdio streams during exit - Support concurrent calls to exit (RHEL-65358)