[PATCH] x32: Fix, optimize and cleanup RSEQ_* accessors

Uros Bizjak ubizjak@gmail.com
Sun Aug 24 18:07:50 GMT 2025


Add missing "memory" clobber to accessors.

Use MOVZBL instead of MOVB to read 1-byte memory location to
a register.

Change %P asm operand modifiers to %c.

Add explicit casts instead of using %b and %q asm operand modifiers.

No functional changes intended.

Tested-by: H.J. Lu <hjl.tools@gmail.com>
Co-Authored-By: H.J. Lu <hjl.tools@gmail.com>
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Cc: Florian Weimer <fweimer@redhat.com>
Cc: Carlos O'Donell <carlos@redhat.com>
---
v2: Also add missing "memory" clobber to accessors
---
 sysdeps/x86_64/x32/nptl/rseq-access.h | 70 +++++++++++++++------------
 1 file changed, 39 insertions(+), 31 deletions(-)

diff --git a/sysdeps/x86_64/x32/nptl/rseq-access.h b/sysdeps/x86_64/x32/nptl/rseq-access.h
index 8386ebd4bf..d9bb215c35 100644
--- a/sysdeps/x86_64/x32/nptl/rseq-access.h
+++ b/sysdeps/x86_64/x32/nptl/rseq-access.h
@@ -18,29 +18,32 @@
 
 /* Read member of the RSEQ area directly, with single-copy atomicity semantics.  */
 #define RSEQ_GETMEM_ONCE(member) \
-  ({ __typeof (RSEQ_SELF()->member) __value;				      \
+  ({									      \
+     __typeof (RSEQ_SELF()->member) __value;				      \
      _Static_assert (sizeof (__value) == 1				      \
 		     || sizeof (__value) == 4				      \
 		     || sizeof (__value) == 8,				      \
-		     "size of rseq data");			      \
+		     "size of rseq data");				      \
      if (sizeof (__value) == 1)						      \
-       asm volatile ("movb %%fs:%P2(%q3),%b0"				      \
-		     : "=q" (__value)					      \
-		     : "0" (0), "i" (offsetof (struct rseq_area, member)),    \
-		       "r" ((long long int) __rseq_offset));		      \
+       asm volatile ("movzbl %%fs:%c1(%2),%k0"				      \
+		     : "=r" (__value)					      \
+		     : "i" (offsetof (struct rseq_area, member)),	      \
+		       "r" ((long long int) __rseq_offset)		      \
+		     : "memory" );					      \
      else if (sizeof (__value) == 4)					      \
-       asm volatile ("movl %%fs:%P1(%q2),%0"				      \
+       asm volatile ("movl %%fs:%c1(%2),%0"				      \
 		     : "=r" (__value)					      \
 		     : "i" (offsetof (struct rseq_area, member)),	      \
-		       "r" ((long long int) __rseq_offset));		      \
+		       "r" ((long long int) __rseq_offset)		      \
+		     : "memory");					      \
      else /* 8 */							      \
-       {								      \
-	 asm volatile ("movq %%fs:%P1(%q2),%q0"				      \
-		       : "=r" (__value)					      \
-		       : "i" (offsetof (struct rseq_area, member)),	      \
-		         "r" ((long long int) __rseq_offset));		      \
-       }								      \
-     __value; })
+       asm volatile ("movq %%fs:%c1(%2),%0"				      \
+		     : "=r" (__value)					      \
+		     : "i" (offsetof (struct rseq_area, member)),	      \
+		       "r" ((long long int) __rseq_offset)		      \
+		     : "memory");					      \
+     __value;								      \
+  })
 
 /* Read member of the RSEQ area directly.  */
 #define RSEQ_GETMEM(member) RSEQ_GETMEM_ONCE(member)
@@ -59,27 +62,32 @@
      _Static_assert (sizeof (RSEQ_SELF()->member) == 1			      \
 		     || sizeof (RSEQ_SELF()->member) == 4		      \
 		     || sizeof (RSEQ_SELF()->member) == 8,		      \
-		     "size of rseq data");			      \
+		     "size of rseq data");				      \
      if (sizeof (RSEQ_SELF()->member) == 1)				      \
-       asm volatile ("movb %b0,%%fs:%P1(%q2)" :				      \
-		     : "iq" (value),					      \
+       asm volatile ("movb %0,%%fs:%c1(%2)"				      \
+		     :							      \
+		     : "iq" ((uint8_t) cast_to_integer (value)),	      \
 		       "i" (offsetof (struct rseq_area, member)),	      \
-		       "r" ((long long int) __rseq_offset));		      \
+		       "r" ((long long int) __rseq_offset)		      \
+		     : "memory");					      \
      else if (sizeof (RSEQ_SELF()->member) == 4)			      \
-       asm volatile ("movl %0,%%fs:%P1(%q2)" :				      \
-		     : IMM_MODE (value),				      \
+       asm volatile ("movl %0,%%fs:%c1(%2)"				      \
+		     :							      \
+		     : IMM_MODE ((uint32_t) cast_to_integer (value)),	      \
 		       "i" (offsetof (struct rseq_area, member)),	      \
-		       "r" ((long long int) __rseq_offset));		      \
+		       "r" ((long long int) __rseq_offset)		      \
+		     : "memory");					      \
      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)" :			      \
-		       : "er" ((uint64_t) cast_to_integer (value)),	      \
-			 "i" (offsetof (struct rseq_area, member)),	      \
-		         "r" ((long long int) __rseq_offset));		      \
-       }})
+       /* 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 %0,%%fs:%c1(%2)"				      \
+		     :							      \
+		     : "er" ((uint64_t) cast_to_integer (value)),	      \
+		       "i" (offsetof (struct rseq_area, member)),	      \
+		       "r" ((long long int) __rseq_offset)		      \
+		     : "memory");					      \
+  })
 
 /* Set member of the RSEQ area directly.  */
 #define RSEQ_SETMEM(member, value) RSEQ_SETMEM_ONCE(member, value)
-- 
2.50.1



More information about the Libc-alpha mailing list