[v14,5/9] nptl: add rtld_hidden_proto to __rseq_size and __rseq_offset

Message ID 20241121190924.837446-6-mjeanson@efficios.com
State Under Review
Delegated to: Florian Weimer
Headers
Series Add rseq extensible ABI support |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent

Commit Message

Michael Jeanson Nov. 21, 2024, 7:08 p.m. UTC
  This allows accessing the internal aliases of __rseq_size and
__rseq_offset from ld.so without ifdefs and avoids a PLT entry in ld.so
for both variables.

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
 sysdeps/unix/sysv/linux/dl-rseq-symbols.S | 27 ++++++++++++++++-------
 sysdeps/unix/sysv/linux/rseq-internal.h   | 16 ++++++++------
 2 files changed, 28 insertions(+), 15 deletions(-)
  

Patch

diff --git a/sysdeps/unix/sysv/linux/dl-rseq-symbols.S b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S
index b4bba06a99..66b33c1096 100644
--- a/sysdeps/unix/sysv/linux/dl-rseq-symbols.S
+++ b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S
@@ -27,14 +27,18 @@ 
 /* Some targets define a macro to denote the zero register.  */
 #undef zero
 
-/* Define 2 symbols: '__rseq_size' is public const and '_rseq_size' (an
-   alias of '__rseq_size') is hidden and writable for internal use by the
-   dynamic linker which will initialize the value both symbols point to
-   before copy relocations take place. */
+/* Define 3 symbols: '__rseq_size' is public const and then '_rseq_size' and
+   '__GI___rseq_size' (both aliases of '__rseq_size') are hidden, '_rseq_size'
+   is writable for internal use by the dynamic linker which will initialize
+   the value the symbols point to before copy relocations take place.  */
 
 	.globl	__rseq_size
 	.type	__rseq_size, %object
 	.size	__rseq_size, 4
+	.hidden __GI___rseq_size
+	.globl	__GI___rseq_size
+	.type	__GI___rseq_size, %object
+	.size	__GI___rseq_size, 4
 	.hidden _rseq_size
 	.globl	_rseq_size
 	.type	_rseq_size, %object
@@ -42,17 +46,23 @@ 
 	.section .data.rel.ro
 	.balign 4
 __rseq_size:
+__GI___rseq_size:
 _rseq_size:
 	.zero	4
 
-/* Define 2 symbols: '__rseq_offset' is public const and '_rseq_offset' (an
-   alias of '__rseq_offset') is hidden and writable for internal use by the
-   dynamic linker which will initialize the value both symbols point to
-   before copy relocations take place. */
+/* Define 3 symbols: '__rseq_offset' is public const and then '_rseq_offset'
+   and '__GI___rseq_offset' (both aliases of '__rseq_offset') are hidden,
+   '_rseq_offset' is writable for internal use by the dynamic linker which will
+   initialize the value the symbols point to before copy relocations take
+   place.  */
 
 	.globl	__rseq_offset
 	.type	__rseq_offset, %object
 	.size	__rseq_offset, RSEQ_OFFSET_SIZE
+	.hidden __GI___rseq_offset
+	.globl	__GI___rseq_offset
+	.type	__GI___rseq_offset, %object
+	.size	__GI___rseq_offset, RSEQ_OFFSET_SIZE
 	.hidden _rseq_offset
 	.globl	_rseq_offset
 	.type	_rseq_offset, %object
@@ -60,5 +70,6 @@  _rseq_size:
 	.section .data.rel.ro
 	.balign RSEQ_OFFSET_SIZE
 __rseq_offset:
+__GI___rseq_offset:
 _rseq_offset:
 	.zero	RSEQ_OFFSET_SIZE
diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
index 7e0804ec52..30b3d5bb19 100644
--- a/sysdeps/unix/sysv/linux/rseq-internal.h
+++ b/sysdeps/unix/sysv/linux/rseq-internal.h
@@ -24,6 +24,7 @@ 
 #include <stdbool.h>
 #include <stdio.h>
 #include <sys/rseq.h>
+#include <ldsodefs.h>
 
 /* Minimum size of the rseq area allocation required by the syscall.  The
    actually used rseq feature size may be less (20 bytes initially).  */
@@ -52,19 +53,20 @@  extern unsigned int _rseq_size attribute_hidden;
    In .data.relro but not yet write-protected.  */
 extern ptrdiff_t _rseq_offset attribute_hidden;
 
+/* We want to use rtld_hidden_proto in order to call the internal aliases
+   of __rseq_size and __rseq_offset from ld.so.  This avoids a PLT entry in
+   ld.so for both variables.   */
+rtld_hidden_proto (__rseq_size)
+rtld_hidden_proto (__rseq_offset)
+
 #ifdef RSEQ_SIG
 static inline bool
 rseq_register_current_thread (struct pthread *self, bool do_rseq)
 {
   if (do_rseq)
     {
-      unsigned int size;
-#if IS_IN (rtld)
-      /* Use the hidden symbol in ld.so.  */
-      size = _rseq_size;
-#else
-      size = __rseq_size;
-#endif
+      unsigned int size =  __rseq_size;
+
       if (size < RSEQ_AREA_SIZE_INITIAL)
         /* The initial implementation used only 20 bytes out of 32,
            but still expected size 32.  */