summaryrefslogtreecommitdiff
path: root/src/ldso
diff options
context:
space:
mode:
Diffstat (limited to 'src/ldso')
-rw-r--r--src/ldso/dynlink.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index 1008e3ea..b049142b 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -1025,17 +1025,11 @@ void *__copy_tls(unsigned char *mem)
{
pthread_t td;
struct dso *p;
-
- void **dtv = (void *)mem;
- dtv[0] = (void *)tls_cnt;
- if (!tls_cnt) {
- td = (void *)(dtv+1);
- td->dtv = td->dtv_copy = dtv;
- return td;
- }
+ void **dtv;
#ifdef TLS_ABOVE_TP
- mem += sizeof(void *) * (tls_cnt+1);
+ dtv = (void **)(mem + libc.tls_size) - (tls_cnt + 1);
+
mem += -((uintptr_t)mem + sizeof(struct pthread)) & (tls_align-1);
td = (pthread_t)mem;
mem += sizeof(struct pthread);
@@ -1046,6 +1040,8 @@ void *__copy_tls(unsigned char *mem)
memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
}
#else
+ dtv = (void **)mem;
+
mem += libc.tls_size - sizeof(struct pthread);
mem -= (uintptr_t)mem & (tls_align-1);
td = (pthread_t)mem;
@@ -1056,6 +1052,7 @@ void *__copy_tls(unsigned char *mem)
memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
}
#endif
+ dtv[0] = (void *)tls_cnt;
td->dtv = td->dtv_copy = dtv;
return td;
}