about summary refs log tree commit diff
path: root/src/ldso/dynlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ldso/dynlink.c')
-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;
 }