@@ -4,5 +4,8 @@
RSEQ_SIZE_SIZE sizeof (unsigned int)
RSEQ_SIZE_ALIGN __alignof (unsigned int)
+RSEQ_FEATURE_SIZE_SIZE sizeof (unsigned int)
+RSEQ_FEATURE_SIZE_ALIGN __alignof (unsigned int)
+
RSEQ_OFFSET_SIZE sizeof (ptrdiff_t)
RSEQ_OFFSET_ALIGN __alignof (ptrdiff_t)
@@ -38,6 +38,23 @@ __rseq_size:
_rseq_size:
.zero RSEQ_SIZE_SIZE
+/* Define 2 symbols, __rseq_feature_size is public const and
+ _rseq_feature_size, which is an alias of __rseq_feature_size, but hidden and
+ writable for internal use. */
+
+ .globl __rseq_feature_size
+ .type __rseq_feature_size, %object
+ .size __rseq_feature_size, RSEQ_FEATURE_SIZE_SIZE
+ .hidden _rseq_feature_size
+ .globl _rseq_feature_size
+ .type _rseq_feature_size, %object
+ .size _rseq_feature_size, RSEQ_FEATURE_SIZE_SIZE
+ .section .data.rel.ro
+ .balign RSEQ_FEATURE_SIZE_ALIGN
+__rseq_feature_size:
+_rseq_feature_size:
+ .zero RSEQ_FEATURE_SIZE_SIZE
+
/* Define 2 symbols, __rseq_offset is public const and _rseq_offset, which is an
alias of __rseq_offset, but hidden and writable for internal use. */
@@ -1011,6 +1011,14 @@ registration is successful, @code{__rseq_size} is at least 32 (the
initial size of @code{struct rseq}).
@end deftypevar
+@deftypevar {unsigned int} __rseq_feature_size
+@standards{Linux, sys/rseq.h}
+This variable is either zero (if restartable sequence registration
+failed or has been disabled) or the size of the restartable sequence
+features. If registration is successful, @code{__rseq_feature_size}
+is at least 20 (the initial feature size of @code{struct rseq}).
+@end deftypevar
+
@deftypevar {unsigned int} __rseq_flags
@standards{Linux, sys/rseq.h}
The flags used during restartable sequence registration with the kernel.
@@ -48,6 +48,7 @@ const unsigned int __rseq_flags;
/* The variables are in .data.relro but are not yet write-protected. */
extern unsigned int _rseq_size attribute_relro attribute_hidden;
+extern unsigned int _rseq_feature_size attribute_relro attribute_hidden;
extern ptrdiff_t _rseq_offset attribute_relro attribute_hidden;
void
@@ -108,6 +109,7 @@ __tls_init_tp (void)
if (rseq_register_current_thread (pd, do_rseq))
{
_rseq_size = GLRO (dl_tls_rseq_size);
+ _rseq_feature_size = GLRO (dl_tls_rseq_feature_size);
}
#ifdef RSEQ_SIG
@@ -356,6 +356,9 @@ ld {
__rseq_offset;
__rseq_size;
}
+ GLIBC_2.40 {
+ __rseq_feature_size;
+ }
GLIBC_PRIVATE {
__nptl_change_stack_perm;
}
@@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x8
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,4 +6,5 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x8
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __stack_chk_guard D 0x8
@@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -2,6 +2,7 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __libc_stack_end D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
GLIBC_2.4 __tls_get_addr F
@@ -2,6 +2,7 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __libc_stack_end D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
GLIBC_2.4 __tls_get_addr F
@@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,4 +6,5 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
@@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,3 +6,4 @@ GLIBC_2.36 __stack_chk_guard D 0x8
GLIBC_2.36 __tls_get_addr F
GLIBC_2.36 _dl_mcount F
GLIBC_2.36 _r_debug D 0x28
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -2,6 +2,7 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __libc_stack_end D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
GLIBC_2.4 __tls_get_addr F
@@ -6,4 +6,5 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
@@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,4 +6,5 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
@@ -6,4 +6,5 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
@@ -6,4 +6,5 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x8
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __stack_chk_guard D 0x8
@@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,3 +6,4 @@ GLIBC_2.35 __stack_chk_guard D 0x4
GLIBC_2.35 __tls_get_addr F
GLIBC_2.35 _dl_mcount F
GLIBC_2.35 _r_debug D 0x14
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -9,3 +9,4 @@ GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -9,3 +9,4 @@ GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x8
GLIBC_2.35 __rseq_size D 0x4
GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -9,3 +9,4 @@ GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x8
GLIBC_2.35 __rseq_size D 0x4
GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x8
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x8
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,4 +6,5 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
@@ -6,4 +6,5 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
GLIBC_2.4 __stack_chk_guard D 0x4
@@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x8
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -163,6 +163,10 @@ extern const ptrdiff_t __rseq_offset;
unsuccessful. */
extern const unsigned int __rseq_size;
+/* Size of the registered rseq features. 0 if the registration was
+ unsuccessful. */
+extern const unsigned int __rseq_feature_size;
+
/* Flags used during rseq registration. */
extern const unsigned int __rseq_flags;
@@ -39,6 +39,7 @@ check_rseq_disabled (void)
TEST_COMPARE (__rseq_flags, 0);
TEST_COMPARE (__rseq_size, 0);
+ TEST_COMPARE (__rseq_feature_size, 0);
TEST_COMPARE ((int) rseq_area->cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
TEST_COMPARE (sizeof (local_rseq), RSEQ_TEST_MIN_SIZE);
@@ -38,12 +38,14 @@ static void
do_rseq_main_test (void)
{
size_t rseq_align = MAX (getauxval (AT_RSEQ_ALIGN), RSEQ_TEST_MIN_ALIGN);
- size_t rseq_size = roundup (MAX (getauxval (AT_RSEQ_FEATURE_SIZE), RSEQ_TEST_MIN_SIZE), rseq_align);
+ size_t rseq_feature_size = MAX (getauxval (AT_RSEQ_FEATURE_SIZE), RSEQ_TEST_MIN_FEATURE_SIZE);
+ size_t rseq_size = roundup (MAX (rseq_feature_size, RSEQ_TEST_MIN_SIZE), rseq_align);
struct rseq *rseq = __thread_pointer () + __rseq_offset;
TEST_VERIFY_EXIT (rseq_thread_registered ());
TEST_COMPARE (__rseq_flags, 0);
TEST_COMPARE (__rseq_size, rseq_size);
+ TEST_COMPARE (__rseq_feature_size, rseq_feature_size);
/* The size of the rseq area must be a multiple of the alignment. */
TEST_VERIFY ((__rseq_size % rseq_align) == 0);
/* The rseq area address must be aligned. */
@@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x8
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
@@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
GLIBC_2.35 __rseq_flags D 0x4
GLIBC_2.35 __rseq_offset D 0x4
GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
Exposing this symbol allows applications wishing to use rseq features which are part of the extensible rseq ABI like 'node_id' and 'mm_cid' to test the two following conditions in a single load / conditional branch: - rseq is registered - the specific rseq feature is available This is useful as rseq is expected to be used in hot paths. This variable is either zero (if restartable sequence registration failed or has been disabled) or the size of the available restartable sequence features. Signed-off-by: Michael Jeanson <mjeanson@efficios.com> --- csu/rseq-sizes.sym | 3 +++ elf/dl-rseq-symbols.S | 17 +++++++++++++++++ manual/threads.texi | 8 ++++++++ sysdeps/nptl/dl-tls_init_tp.c | 2 ++ sysdeps/unix/sysv/linux/Versions | 3 +++ sysdeps/unix/sysv/linux/aarch64/ld.abilist | 1 + sysdeps/unix/sysv/linux/alpha/ld.abilist | 1 + sysdeps/unix/sysv/linux/arc/ld.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/ld.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/ld.abilist | 1 + sysdeps/unix/sysv/linux/csky/ld.abilist | 1 + sysdeps/unix/sysv/linux/hppa/ld.abilist | 1 + sysdeps/unix/sysv/linux/i386/ld.abilist | 1 + .../unix/sysv/linux/loongarch/lp64/ld.abilist | 1 + .../unix/sysv/linux/m68k/coldfire/ld.abilist | 1 + sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist | 1 + sysdeps/unix/sysv/linux/microblaze/ld.abilist | 1 + sysdeps/unix/sysv/linux/mips/mips32/ld.abilist | 1 + .../unix/sysv/linux/mips/mips64/n32/ld.abilist | 1 + .../unix/sysv/linux/mips/mips64/n64/ld.abilist | 1 + sysdeps/unix/sysv/linux/nios2/ld.abilist | 1 + sysdeps/unix/sysv/linux/or1k/ld.abilist | 1 + .../sysv/linux/powerpc/powerpc32/ld.abilist | 1 + .../sysv/linux/powerpc/powerpc64/be/ld.abilist | 1 + .../sysv/linux/powerpc/powerpc64/le/ld.abilist | 1 + sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist | 1 + sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist | 1 + sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist | 1 + sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/ld.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/ld.abilist | 1 + .../unix/sysv/linux/sparc/sparc32/ld.abilist | 1 + .../unix/sysv/linux/sparc/sparc64/ld.abilist | 1 + sysdeps/unix/sysv/linux/sys/rseq.h | 4 ++++ sysdeps/unix/sysv/linux/tst-rseq-disable.c | 1 + sysdeps/unix/sysv/linux/tst-rseq.c | 4 +++- sysdeps/unix/sysv/linux/x86_64/64/ld.abilist | 1 + sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist | 1 + 38 files changed, 71 insertions(+), 1 deletion(-)