diff options
author | Sergey Bugaev <bugaevc@gmail.com> | 2023-02-14 20:37:20 +0300 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-02-14 20:27:11 +0100 |
commit | 748511f0bb61785f976e18843d707a8ba8fffe29 (patch) | |
tree | 42f62a9054a9fe8c91476d67dd92bea8642d2ff1 /sysdeps | |
parent | e7223fa1e8e0673440cc62364b67d55afc78123a (diff) | |
download | glibc-748511f0bb61785f976e18843d707a8ba8fffe29.zip glibc-748511f0bb61785f976e18843d707a8ba8fffe29.tar.gz glibc-748511f0bb61785f976e18843d707a8ba8fffe29.tar.bz2 |
hurd: i386 TLS tweaks
* Micro-optimize TLS access using GCC's native support for gs-based
addressing when available;
* Just use THREAD_GETMEM and THREAD_SETMEM instead of more inline
assembly;
* Sync tcbhead_t layout with NPTL, in particular update/fix __private_ss
offset;
* Statically assert that the two offsets that are a part of ABI are what
we expect them to be.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-Id: <20230214173722.428140-2-bugaevc@gmail.com>
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/mach/hurd/i386/tls.h | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h index a6ff010..dc43d4c 100644 --- a/sysdeps/mach/hurd/i386/tls.h +++ b/sysdeps/mach/hurd/i386/tls.h @@ -38,11 +38,12 @@ typedef struct uintptr_t stack_guard; uintptr_t pointer_guard; int gscope_flag; - int private_futex; + unsigned int feature_1; /* Reservation of some values for the TM ABI. */ - void *__private_tm[4]; + void *__private_tm[3]; /* GCC split stack support. */ void *__private_ss; + void *__glibc_padding1; /* Keep these fields last, so offsets of fields above can continue being compatible with the i386 Linux version. */ @@ -53,6 +54,13 @@ typedef struct struct rtld_catch *rtld_catch; } tcbhead_t; +/* GCC generates %gs:0x14 to access the stack guard. */ +_Static_assert (offsetof (tcbhead_t, stack_guard) == 0x14, + "stack guard offset"); +/* libgcc uses %gs:0x30 to access the split stack pointer. */ +_Static_assert (offsetof (tcbhead_t, __private_ss) == 0x30, + "split stack pointer offset"); + /* Return tcbhead_t from a TLS segment descriptor. */ # define HURD_DESC_TLS(desc) \ ({ \ @@ -166,8 +174,25 @@ out: # define TLS_INIT_TP(descr) \ _hurd_tls_init ((tcbhead_t *) (descr)) +# if __GNUC_PREREQ (6, 0) + +# define THREAD_SELF \ + (*(tcbhead_t * __seg_gs *) offsetof (tcbhead_t, tcb)) +# define THREAD_GETMEM(descr, member) \ + (*(__typeof (descr->member) __seg_gs *) offsetof (tcbhead_t, member)) +# define THREAD_GETMEM_NC(descr, member, idx) \ + (*(__typeof (descr->member[0]) __seg_gs *) \ + (offsetof (tcbhead_t, member) + (idx) * sizeof (descr->member[0]))) +# define THREAD_SETMEM(descr, member, value) \ + (*(__typeof (descr->member) __seg_gs *) offsetof (tcbhead_t, member) = value) +# define THREAD_SETMEM_NC(descr, member, index, value) \ + (*(__typeof (descr->member[0]) __seg_gs *) \ + (offsetof (tcbhead_t, member) + (idx) * sizeof (descr->member[0]))) + +# else + /* Return the TCB address of the current thread. */ -# define THREAD_SELF \ +# define THREAD_SELF \ ({ tcbhead_t *__tcb; \ __asm__ ("movl %%gs:%c1,%0" : "=r" (__tcb) \ : "i" (offsetof (tcbhead_t, tcb))); \ @@ -200,7 +225,7 @@ out: /* Same as THREAD_GETMEM, but the member offset can be non-constant. */ -# define THREAD_GETMEM_NC(descr, member, idx) \ +# define THREAD_GETMEM_NC(descr, member, idx) \ ({ __typeof (descr->member[0]) __value; \ _Static_assert (sizeof (__value) == 1 \ || sizeof (__value) == 4 \ @@ -229,7 +254,7 @@ out: /* Set member of the thread descriptor directly. */ -# define THREAD_SETMEM(descr, member, value) \ +# define THREAD_SETMEM(descr, member, value) \ ({ \ _Static_assert (sizeof (descr->member) == 1 \ || sizeof (descr->member) == 4 \ @@ -254,7 +279,7 @@ out: /* Same as THREAD_SETMEM, but the member offset can be non-constant. */ -# define THREAD_SETMEM_NC(descr, member, idx, value) \ +# define THREAD_SETMEM_NC(descr, member, idx, value) \ ({ \ _Static_assert (sizeof (descr->member[0]) == 1 \ || sizeof (descr->member[0]) == 4 \ @@ -279,6 +304,8 @@ out: "r" (idx)); \ }}) +# endif /* __GNUC_PREREQ (6, 0) */ + /* Return the TCB address of a thread given its state. Note: this is expensive. */ # define THREAD_TCB(thread, thread_state) \ @@ -295,15 +322,10 @@ out: HURD_DESC_TLS (___desc);}) /* Install new dtv for current thread. */ -# define INSTALL_NEW_DTV(dtvp) \ - ({ asm volatile ("movl %0,%%gs:%P1" \ - : : "ir" (dtvp), "i" (offsetof (tcbhead_t, dtv))); }) +# define INSTALL_NEW_DTV(dtvp) THREAD_SETMEM (THREAD_SELF, dtv, dtvp) /* Return the address of the dtv for the current thread. */ -# define THREAD_DTV() \ - ({ dtv_t *_dtv; \ - asm ("movl %%gs:%P1,%0" : "=q" (_dtv) : "i" (offsetof (tcbhead_t, dtv)));\ - _dtv; }) +# define THREAD_DTV() THREAD_GETMEM (THREAD_SELF, dtv) /* Set the stack guard field in TCB head. */ |