From 97cad5113bf860876883a9911cbee4b9283d363f Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 12 Jun 2018 11:08:52 +0000 Subject: [PATCH] libitm/x86: Correct offsets of __private_tm and pointer_guard In glibc, sysdeps/i386/nptl/tls.h has typedef struct { void *tcb; /* Pointer to the TCB. Not necessarily the thread descriptor used by libpthread. */ dtv_t *dtv; void *self; /* Pointer to the thread descriptor. */ int multiple_threads; uintptr_t sysinfo; uintptr_t stack_guard; uintptr_t pointer_guard; int gscope_flag; int __glibc_reserved1; /* Reservation of some values for the TM ABI. */ void *__private_tm[4]; /* GCC split stack support. */ void *__private_ss; } tcbhead_t; and sysdeps/x86_64/nptl/tls.h has typedef struct { void *tcb; /* Pointer to the TCB. Not necessarily the thread descriptor used by libpthread. */ dtv_t *dtv; void *self; /* Pointer to the thread descriptor. */ int multiple_threads; int gscope_flag; uintptr_t sysinfo; uintptr_t stack_guard; uintptr_t pointer_guard; unsigned long int vgetcpu_cache[2]; int __glibc_reserved1; int __glibc_unused1; /* Reservation of some values for the TM ABI. */ void *__private_tm[4]; /* GCC split stack support. */ void *__private_ss; long int __glibc_reserved2; /* Must be kept even if it is no longer used by glibc since programs, like AddressSanitizer, depend on the size of tcbhead_t. */ __128bits __glibc_unused2[8][4] __attribute__ ((aligned (32))); void *__padding[8]; } tcbhead_t; The offsets of __private_tm are i386: 36 bytes x32: 48 bytes x86_64: 80 bytes and the offsets of pointer_guard are: i386: 24 bytes x32: 28 bytes x86_64: 48 bytes But config/linux/x86/tls.h had #ifdef __x86_64__ #ifdef __LP64__ # define SEG_READ(OFS) "movq\t%%fs:(" #OFS "*8),%0" # define SEG_WRITE(OFS) "movq\t%0,%%fs:(" #OFS "*8)" # define SEG_DECODE_READ(OFS) SEG_READ(OFS) "\n\t" \ "rorq\t$17,%0\n\t" \ "xorq\t%%fs:48,%0" # define SEG_ENCODE_WRITE(OFS) "xorq\t%%fs:48,%0\n\t" \ "rolq\t$17,%0\n\t" \ SEG_WRITE(OFS) #else // For X32. # define SEG_READ(OFS) "movl\t%%fs:(" #OFS "*4),%0" # define SEG_WRITE(OFS) "movl\t%0,%%fs:(" #OFS "*4)" # define SEG_DECODE_READ(OFS) SEG_READ(OFS) "\n\t" \ "rorl\t$9,%0\n\t" \ "xorl\t%%fs:24,%0" # define SEG_ENCODE_WRITE(OFS) "xorl\t%%fs:24,%0\n\t" \ "roll\t$9,%0\n\t" \ SEG_WRITE(OFS) #endif #else # define SEG_READ(OFS) "movl\t%%gs:(" #OFS "*4),%0" # define SEG_WRITE(OFS) "movl\t%0,%%gs:(" #OFS "*4)" # define SEG_DECODE_READ(OFS) SEG_READ(OFS) "\n\t" \ "rorl\t$9,%0\n\t" \ "xorl\t%%gs:24,%0" # define SEG_ENCODE_WRITE(OFS) "xorl\t%%gs:24,%0\n\t" \ "roll\t$9,%0\n\t" \ SEG_WRITE(OFS) #endif static inline struct gtm_thread *gtm_thr(void) { struct gtm_thread *r; asm volatile (SEG_READ(10) : "=r"(r)); return r; } static inline void set_gtm_thr(struct gtm_thread *x) { asm volatile (SEG_WRITE(10) : : "r"(x)); } static inline struct abi_dispatch *abi_disp(void) { struct abi_dispatch *r; asm volatile (SEG_DECODE_READ(11) : "=r"(r)); return r; } static inline void set_abi_disp(struct abi_dispatch *x) { void *scratch; asm volatile (SEG_ENCODE_WRITE(11) : "=r"(scratch) : "0"(x)); } SEG_READ, SEG_WRITE, SEG_DECODE_READ and SEG_ENCODE_WRITE were correct only for x86-64. Update SEG_READ and SEG_WRITE to use the offset of __private_tm as base and correct the offset of pointer_guard for x32. This patch doesn't change ABI of libitm. PR libitm/85988 * config/linux/x86/tls.h (SEG_READ): Use the offset of __private_tm as base. (SEG_WRITE): Likewise. (SEG_ENCODE_WRITE): Correct the offset of pointer_guard for x32. (gtm_thr): Replace SEG_READ(10) with SEG_READ(0). (set_gtm_thr): Replace SEG_WRITE(10) with SEG_WRITE(0). (abi_disp): Replace SEG_DECODE_READ(11) with SEG_DECODE_READ(1). (set_abi_disp): Replace SEG_ENCODE_WRITE(11) with SEG_ENCODE_WRITE(1). From-SVN: r261491 --- libitm/ChangeLog | 12 ++++++++++++ libitm/config/linux/x86/tls.h | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/libitm/ChangeLog b/libitm/ChangeLog index 7791d9e433f..729603a9721 100644 --- a/libitm/ChangeLog +++ b/libitm/ChangeLog @@ -1,3 +1,15 @@ +2018-06-12 H.J. Lu + + PR libitm/85988 + * config/linux/x86/tls.h (SEG_READ): Use the offset of + __private_tm as base. + (SEG_WRITE): Likewise. + (SEG_ENCODE_WRITE): Correct the offset of pointer_guard for x32. + (gtm_thr): Replace SEG_READ(10) with SEG_READ(0). + (set_gtm_thr): Replace SEG_WRITE(10) with SEG_WRITE(0). + (abi_disp): Replace SEG_DECODE_READ(11) with SEG_DECODE_READ(1). + (set_abi_disp): Replace SEG_ENCODE_WRITE(11) with + 2018-05-17 Jason Merrill * beginend.cc (save): Disable -Werror=deprecated-copy. diff --git a/libitm/config/linux/x86/tls.h b/libitm/config/linux/x86/tls.h index 5f3fd273c0e..ca6a5af3d4f 100644 --- a/libitm/config/linux/x86/tls.h +++ b/libitm/config/linux/x86/tls.h @@ -42,8 +42,8 @@ namespace GTM HIDDEN { #ifdef __x86_64__ #ifdef __LP64__ -# define SEG_READ(OFS) "movq\t%%fs:(" #OFS "*8),%0" -# define SEG_WRITE(OFS) "movq\t%0,%%fs:(" #OFS "*8)" +# define SEG_READ(OFS) "movq\t%%fs:(80+" #OFS "*8),%0" +# define SEG_WRITE(OFS) "movq\t%0,%%fs:(80+" #OFS "*8)" # define SEG_DECODE_READ(OFS) SEG_READ(OFS) "\n\t" \ "rorq\t$17,%0\n\t" \ "xorq\t%%fs:48,%0" @@ -52,18 +52,18 @@ namespace GTM HIDDEN { SEG_WRITE(OFS) #else // For X32. -# define SEG_READ(OFS) "movl\t%%fs:(" #OFS "*4),%0" -# define SEG_WRITE(OFS) "movl\t%0,%%fs:(" #OFS "*4)" +# define SEG_READ(OFS) "movl\t%%fs:(48+" #OFS "*4),%0" +# define SEG_WRITE(OFS) "movl\t%0,%%fs:(48+" #OFS "*4)" # define SEG_DECODE_READ(OFS) SEG_READ(OFS) "\n\t" \ "rorl\t$9,%0\n\t" \ - "xorl\t%%fs:24,%0" -# define SEG_ENCODE_WRITE(OFS) "xorl\t%%fs:24,%0\n\t" \ + "xorl\t%%fs:28,%0" +# define SEG_ENCODE_WRITE(OFS) "xorl\t%%fs:28,%0\n\t" \ "roll\t$9,%0\n\t" \ SEG_WRITE(OFS) #endif #else -# define SEG_READ(OFS) "movl\t%%gs:(" #OFS "*4),%0" -# define SEG_WRITE(OFS) "movl\t%0,%%gs:(" #OFS "*4)" +# define SEG_READ(OFS) "movl\t%%gs:(36+" #OFS "*4),%0" +# define SEG_WRITE(OFS) "movl\t%0,%%gs:(36+" #OFS "*4)" # define SEG_DECODE_READ(OFS) SEG_READ(OFS) "\n\t" \ "rorl\t$9,%0\n\t" \ "xorl\t%%gs:24,%0" @@ -75,26 +75,26 @@ namespace GTM HIDDEN { static inline struct gtm_thread *gtm_thr(void) { struct gtm_thread *r; - asm volatile (SEG_READ(10) : "=r"(r)); + asm volatile (SEG_READ(0) : "=r"(r)); return r; } static inline void set_gtm_thr(struct gtm_thread *x) { - asm volatile (SEG_WRITE(10) : : "r"(x)); + asm volatile (SEG_WRITE(0) : : "r"(x)); } static inline struct abi_dispatch *abi_disp(void) { struct abi_dispatch *r; - asm volatile (SEG_DECODE_READ(11) : "=r"(r)); + asm volatile (SEG_DECODE_READ(1) : "=r"(r)); return r; } static inline void set_abi_disp(struct abi_dispatch *x) { void *scratch; - asm volatile (SEG_ENCODE_WRITE(11) : "=r"(scratch) : "0"(x)); + asm volatile (SEG_ENCODE_WRITE(1) : "=r"(scratch) : "0"(x)); } #undef SEG_READ -- 2.30.2