diff options
-rw-r--r-- | src/env/__init_tls.c | 5 | ||||
-rw-r--r-- | src/ldso/dynlink.c | 12 | ||||
-rw-r--r-- | src/thread/__tls_get_addr.c | 17 |
3 files changed, 23 insertions, 11 deletions
diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c index f7eab8d6..13cf2eea 100644 --- a/src/env/__init_tls.c +++ b/src/env/__init_tls.c @@ -53,11 +53,6 @@ void *__copy_tls(unsigned char *mem) return td; } -void *__tls_get_addr(size_t *v) -{ - return (char *)__pthread_self()->dtv[1]+v[1]; -} - #if ULONG_MAX == 0xffffffff typedef Elf32_Phdr Phdr; #else diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 2b6f0c94..bc4f2f6f 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -1031,17 +1031,15 @@ void *__copy_tls(unsigned char *mem) return td; } -void *__tls_get_addr(size_t *v) +void *__tls_get_new(size_t *v) { pthread_t self = __pthread_self(); - if (v[0]<=(size_t)self->dtv[0]) - return (char *)self->dtv[v[0]]+v[1]; /* Block signals to make accessing new TLS async-signal-safe */ sigset_t set; - pthread_sigmask(SIG_BLOCK, SIGALL_SET, &set); + __block_all_sigs(&set); if (v[0]<=(size_t)self->dtv[0]) { - pthread_sigmask(SIG_SETMASK, &set, 0); + __restore_sigs(&set); return (char *)self->dtv[v[0]]+v[1]; } @@ -1074,7 +1072,7 @@ void *__tls_get_addr(size_t *v) memcpy(mem, p->tls_image, p->tls_len); if (p->tls_id == v[0]) break; } - pthread_sigmask(SIG_SETMASK, &set, 0); + __restore_sigs(&set); return mem + v[1]; } @@ -1442,6 +1440,8 @@ static int invalid_dso_handle(void *h) return 1; } +void *__tls_get_addr(size_t *); + static void *do_dlsym(struct dso *p, const char *s, void *ra) { size_t i; diff --git a/src/thread/__tls_get_addr.c b/src/thread/__tls_get_addr.c new file mode 100644 index 00000000..28ec7f02 --- /dev/null +++ b/src/thread/__tls_get_addr.c @@ -0,0 +1,17 @@ +#include <stddef.h> +#include "pthread_impl.h" +#include "libc.h" + +void *__tls_get_new(size_t *) ATTR_LIBC_VISIBILITY; + +void *__tls_get_addr(size_t *v) +{ + pthread_t self = __pthread_self(); +#ifdef SHARED + if (v[0]<=(size_t)self->dtv[0]) + return (char *)self->dtv[v[0]]+v[1]; + return __tls_get_new(v); +#else + return (char *)self->dtv[1]+v[1]; +#endif +} |