Import glibc-2.34-19.fc35 from f35

* Fri Jan 14 2022 Florian Weimer <fweimer@redhat.com> - 2.34-19
- Optionally accelerate sched_getcpu using rseq (#2024347)

Resolves: #2024347
This commit is contained in:
Florian Weimer 2022-01-19 11:35:37 +01:00
parent c2879fd933
commit c77b926c9d
14 changed files with 3839 additions and 1 deletions

98
glibc-rh2024347-1.patch Normal file
View File

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

74
glibc-rh2024347-10.patch Normal file
View File

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

592
glibc-rh2024347-11.patch Normal file
View File

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

73
glibc-rh2024347-12.patch Normal file
View File

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

42
glibc-rh2024347-13.patch Normal file
View File

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

259
glibc-rh2024347-2.patch Normal file
View File

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

150
glibc-rh2024347-3.patch Normal file
View File

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

130
glibc-rh2024347-4.patch Normal file
View File

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

904
glibc-rh2024347-5.patch Normal file
View File

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

49
glibc-rh2024347-6.patch Normal file
View File

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

1130
glibc-rh2024347-7.patch Normal file

File diff suppressed because it is too large Load Diff

43
glibc-rh2024347-8.patch Normal file
View File

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

278
glibc-rh2024347-9.patch Normal file
View File

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

View File

@ -148,7 +148,7 @@ end \
Summary: The GNU libc libraries
Name: glibc
Version: %{glibcversion}
Release: 18%{?dist}
Release: 19%{?dist}
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
# libraries.
@ -313,6 +313,19 @@ 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
##############################################################################
# Continued list of core "glibc" package information:
@ -2341,6 +2354,9 @@ fi
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
%changelog
* Fri Jan 14 2022 Florian Weimer <fweimer@redhat.com> - 2.34-19
- Optionally accelerate sched_getcpu using rseq (#2024347)
* Thu Jan 13 2022 Florian Weimer <fweimer@redhat.com> - 2.34-18
- Backport optimized ELF dependency sorting algorithm (#2032647)