[PATCH 1/4] x86: Simplify TCB access expressions

Uros Bizjak ubizjak@gmail.com
Thu Sep 25 08:41:00 GMT 2025


Replace manual cast with a direct `(__typeof(*descr) __seg_gs *)0`
dereference to access `member`.  This avoids redundant
`offsetof(struct pthread, member)` and improves readability while
preserving semantics.

Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
---
 sysdeps/i386/nptl/tcb-access.h   | 16 ++++++----------
 sysdeps/i386/nptl/tls.h          |  5 ++---
 sysdeps/x86_64/nptl/tcb-access.h | 16 ++++++----------
 sysdeps/x86_64/nptl/tls.h        |  5 ++---
 4 files changed, 16 insertions(+), 26 deletions(-)

diff --git a/sysdeps/i386/nptl/tcb-access.h b/sysdeps/i386/nptl/tcb-access.h
index 2a7f9d2a57..fdd84bd942 100644
--- a/sysdeps/i386/nptl/tcb-access.h
+++ b/sysdeps/i386/nptl/tcb-access.h
@@ -23,8 +23,7 @@
 		     || sizeof (descr->member) == 4			      \
 		     || sizeof (descr->member) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(__typeof (descr->member) __seg_gs *)				      \
-      offsetof (struct pthread, member));				      \
+     ((__typeof (*descr) __seg_gs *)0)->member;				      \
   })
 
 #define THREAD_GETMEM_VOLATILE(descr, member) \
@@ -33,8 +32,8 @@
 		     || sizeof (descr->member) == 4			      \
 		     || sizeof (descr->member) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(volatile __typeof (descr->member) __seg_gs *)			      \
-      offsetof (struct pthread, member));				      \
+     *(volatile __typeof (descr->member) __seg_gs *)			      \
+       &((__typeof (*descr) __seg_gs *)0)->member;			      \
   })
 
 /* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
@@ -44,8 +43,7 @@
 		     || sizeof (descr->member[0]) == 4			      \
 		     || sizeof (descr->member[0]) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(__typeof (descr->member[0]) __seg_gs *)				      \
-      offsetof (struct pthread, member[idx]));				      \
+     ((__typeof (*descr) __seg_gs *)0)->member[idx];			      \
   })
 
 /* Set member of the thread descriptor directly.  */
@@ -55,8 +53,7 @@
 		     || sizeof (descr->member) == 4			      \
 		     || sizeof (descr->member) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(__typeof (descr->member) __seg_gs *)				      \
-      offsetof (struct pthread, member) = (value));			      \
+     ((__typeof (*descr) __seg_gs *)0)->member = (value);		      \
   })
 
 /* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
@@ -66,6 +63,5 @@
 		     || sizeof (descr->member[0]) == 4			      \
 		     || sizeof (descr->member[0]) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(__typeof (descr->member[0]) __seg_gs *)				      \
-      offsetof (struct pthread, member[idx]) = (value));		      \
+     ((__typeof (*descr) __seg_gs *)0)->member[idx] = (value);		      \
   })
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index 5c266c7191..7b297d4043 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -223,7 +223,7 @@ tls_fill_user_desc (union user_desc_init *desc,
 
 /* Return the thread descriptor for the current thread.  */
 # define THREAD_SELF \
-  (*(struct pthread *__seg_gs *) offsetof (struct pthread, header.self))
+  (*(struct pthread *__seg_gs *)&((struct pthread __seg_gs *)0)->header.self)
 
 /* Magic for libthread_db to know how to do THREAD_SELF.  */
 # define DB_THREAD_SELF \
@@ -257,8 +257,7 @@ tls_fill_user_desc (union user_desc_init *desc,
     { int __res;							      \
       asm volatile ("xchgl %1, %0"					      \
 		    : "=r" (__res)					      \
-		    : "m" (*(int __seg_gs *)				      \
-			   offsetof (struct pthread, header.gscope_flag)),    \
+		    : "m" (((struct pthread __seg_gs *)0)->header.gscope_flag), \
 		      "0" (THREAD_GSCOPE_FLAG_UNUSED));			      \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				      \
 	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);    \
diff --git a/sysdeps/x86_64/nptl/tcb-access.h b/sysdeps/x86_64/nptl/tcb-access.h
index 445f328ac2..92b2da6cc6 100644
--- a/sysdeps/x86_64/nptl/tcb-access.h
+++ b/sysdeps/x86_64/nptl/tcb-access.h
@@ -23,8 +23,7 @@
 		     || sizeof (descr->member) == 4			      \
 		     || sizeof (descr->member) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(__typeof (descr->member) __seg_fs *)				      \
-      offsetof (struct pthread, member));				      \
+     ((__typeof (*descr) __seg_fs *)0)->member;				      \
   })
 
 #define THREAD_GETMEM_VOLATILE(descr, member) \
@@ -33,8 +32,8 @@
 		     || sizeof (descr->member) == 4			      \
 		     || sizeof (descr->member) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(volatile __typeof (descr->member) __seg_fs *)			      \
-      offsetof (struct pthread, member));				      \
+     *(volatile __typeof (descr->member) __seg_fs *)			      \
+       &((__typeof (*descr) __seg_fs *)0)->member;			      \
   })
 
 /* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
@@ -44,8 +43,7 @@
 		     || sizeof (descr->member[0]) == 4			      \
 		     || sizeof (descr->member[0]) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(__typeof (descr->member[0]) __seg_fs *)				      \
-      offsetof (struct pthread, member[idx]));				      \
+     ((__typeof (*descr) __seg_fs *)0)->member[idx];			      \
   })
 
 /* Set member of the thread descriptor directly.  */
@@ -55,8 +53,7 @@
 		     || sizeof (descr->member) == 4			      \
 		     || sizeof (descr->member) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(__typeof (descr->member) __seg_fs *)				      \
-      offsetof (struct pthread, member) = (value));			      \
+     ((__typeof (*descr) __seg_fs *)0)->member = (value);		      \
   })
 
 /* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
@@ -66,6 +63,5 @@
 		     || sizeof (descr->member[0]) == 4			      \
 		     || sizeof (descr->member[0]) == 8,			      \
 		     "size of per-thread data");			      \
-     (*(__typeof (descr->member[0]) __seg_fs *)				      \
-      offsetof (struct pthread, member[idx]) = (value));		      \
+     ((__typeof (*descr) __seg_fs *)0)->member[idx] = (value);		      \
   })
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
index cf41430050..abfeb88054 100644
--- a/sysdeps/x86_64/nptl/tls.h
+++ b/sysdeps/x86_64/nptl/tls.h
@@ -170,7 +170,7 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
 
 /* Return the thread descriptor for the current thread.  */
 # define THREAD_SELF \
-  (*(struct pthread *__seg_fs *) offsetof (struct pthread, header.self))
+  (*(struct pthread *__seg_fs *)&((struct pthread __seg_fs *)0)->header.self)
 
 /* Magic for libthread_db to know how to do THREAD_SELF.  */
 # define DB_THREAD_SELF_INCLUDE  <sys/reg.h> /* For the FS constant.  */
@@ -203,8 +203,7 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
     { int __res;							      \
       asm volatile ("xchgl %1, %0"					      \
 		    : "=r" (__res)					      \
-		    : "m" (*(int __seg_fs *)				      \
-			   offsetof (struct pthread, header.gscope_flag)),    \
+		    : "m" (((struct pthread __seg_fs *)0)->header.gscope_flag), \
 		      "0" (THREAD_GSCOPE_FLAG_UNUSED));			      \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				      \
 	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);    \
-- 
2.51.0



More information about the Libc-alpha mailing list