diff options
author | Rich Felker <dalias@aerifal.cx> | 2014-06-19 02:59:44 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2014-06-19 02:59:44 -0400 |
commit | 5ba238e1e48d2fe4107e09903b26b2b36aa9e9ff (patch) | |
tree | 2933bdc33c131122acea9b188186443da2e6a37b /src/ldso | |
parent | 4e0b4a5de735ecb241fadb1e15381c947e16e71f (diff) | |
download | musl-5ba238e1e48d2fe4107e09903b26b2b36aa9e9ff.tar.gz musl-5ba238e1e48d2fe4107e09903b26b2b36aa9e9ff.tar.bz2 musl-5ba238e1e48d2fe4107e09903b26b2b36aa9e9ff.tar.xz musl-5ba238e1e48d2fe4107e09903b26b2b36aa9e9ff.zip |
separate __tls_get_addr implementation from dynamic linker/init_tls
such separation serves multiple purposes:
- by having the common path for __tls_get_addr alone in its own
function with a tail call to the slow case, code generation is
greatly improved.
- by having __tls_get_addr in it own file, it can be replaced on a
per-arch basis as needed, for optimization or ABI-specific purposes.
- by removing __tls_get_addr from __init_tls.c, a few bytes of code
are shaved off of static binaries (which are unlikely to use this
function unless the linker messed up).
Diffstat (limited to 'src/ldso')
-rw-r--r-- | src/ldso/dynlink.c | 12 |
1 files changed, 6 insertions, 6 deletions
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; |