97cad5113b
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 |
||
---|---|---|
.. | ||
aarch64 | ||
alpha | ||
arm | ||
generic | ||
linux | ||
posix | ||
powerpc | ||
s390 | ||
sh | ||
sparc | ||
x86 |