mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 04:50:07 +00:00
x86: Fix THREAD_SELF definition to avoid ld.so crash (bug 27004)
The previous definition of THREAD_SELF did not tell the compiler that %fs (or %gs) usage is invalid for the !DL_LOOKUP_GSCOPE_LOCK case in _dl_lookup_symbol_x. As a result, ld.so could try to use the TCB before it was initialized. As the comment in tls.h explains, asm volatile is undesirable here. Using the __seg_fs (or __seg_gs) namespace does not interfere with optimization, and expresses that THREAD_SELF is potentially trapping.
This commit is contained in:
parent
7c33111697
commit
1d9cbb9608
@ -234,11 +234,16 @@ tls_fill_user_desc (union user_desc_init *desc,
|
|||||||
assignments like
|
assignments like
|
||||||
pthread_descr self = thread_self();
|
pthread_descr self = thread_self();
|
||||||
do not get optimized away. */
|
do not get optimized away. */
|
||||||
# define THREAD_SELF \
|
# if __GNUC_PREREQ (6, 0)
|
||||||
|
# define THREAD_SELF \
|
||||||
|
(*(struct pthread *__seg_gs *) offsetof (struct pthread, header.self))
|
||||||
|
# else
|
||||||
|
# define THREAD_SELF \
|
||||||
({ struct pthread *__self; \
|
({ struct pthread *__self; \
|
||||||
asm ("movl %%gs:%c1,%0" : "=r" (__self) \
|
asm ("movl %%gs:%c1,%0" : "=r" (__self) \
|
||||||
: "i" (offsetof (struct pthread, header.self))); \
|
: "i" (offsetof (struct pthread, header.self))); \
|
||||||
__self;})
|
__self;})
|
||||||
|
# endif
|
||||||
|
|
||||||
/* Magic for libthread_db to know how to do THREAD_SELF. */
|
/* Magic for libthread_db to know how to do THREAD_SELF. */
|
||||||
# define DB_THREAD_SELF \
|
# define DB_THREAD_SELF \
|
||||||
|
@ -180,11 +180,16 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
|
|||||||
assignments like
|
assignments like
|
||||||
pthread_descr self = thread_self();
|
pthread_descr self = thread_self();
|
||||||
do not get optimized away. */
|
do not get optimized away. */
|
||||||
# define THREAD_SELF \
|
# if __GNUC_PREREQ (6, 0)
|
||||||
|
# define THREAD_SELF \
|
||||||
|
(*(struct pthread *__seg_fs *) offsetof (struct pthread, header.self))
|
||||||
|
# else
|
||||||
|
# define THREAD_SELF \
|
||||||
({ struct pthread *__self; \
|
({ struct pthread *__self; \
|
||||||
asm ("mov %%fs:%c1,%0" : "=r" (__self) \
|
asm ("mov %%fs:%c1,%0" : "=r" (__self) \
|
||||||
: "i" (offsetof (struct pthread, header.self))); \
|
: "i" (offsetof (struct pthread, header.self))); \
|
||||||
__self;})
|
__self;})
|
||||||
|
# endif
|
||||||
|
|
||||||
/* Magic for libthread_db to know how to do THREAD_SELF. */
|
/* Magic for libthread_db to know how to do THREAD_SELF. */
|
||||||
# define DB_THREAD_SELF_INCLUDE <sys/reg.h> /* For the FS constant. */
|
# define DB_THREAD_SELF_INCLUDE <sys/reg.h> /* For the FS constant. */
|
||||||
|
Loading…
Reference in New Issue
Block a user