about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/env/__init_tls.c16
-rw-r--r--src/env/__reset_tls.c9
-rw-r--r--src/internal/pthread_impl.h5
-rw-r--r--src/thread/__tls_get_addr.c4
4 files changed, 17 insertions, 17 deletions
diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
index 96d0e284..842886f6 100644
--- a/src/env/__init_tls.c
+++ b/src/env/__init_tls.c
@@ -36,32 +36,32 @@ void *__copy_tls(unsigned char *mem)
 	pthread_t td;
 	struct tls_module *p;
 	size_t i;
-	void **dtv;
+	uintptr_t *dtv;
 
 #ifdef TLS_ABOVE_TP
-	dtv = (void **)(mem + libc.tls_size) - (libc.tls_cnt + 1);
+	dtv = (uintptr_t*)(mem + libc.tls_size) - (libc.tls_cnt + 1);
 
 	mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1);
 	td = (pthread_t)mem;
 	mem += sizeof(struct pthread);
 
 	for (i=1, p=libc.tls_head; p; i++, p=p->next) {
-		dtv[i] = mem + p->offset;
-		memcpy(dtv[i], p->image, p->len);
+		dtv[i] = (uintptr_t)(mem + p->offset) + DTP_OFFSET;
+		memcpy(mem + p->offset, p->image, p->len);
 	}
 #else
-	dtv = (void **)mem;
+	dtv = (uintptr_t *)mem;
 
 	mem += libc.tls_size - sizeof(struct pthread);
 	mem -= (uintptr_t)mem & (libc.tls_align-1);
 	td = (pthread_t)mem;
 
 	for (i=1, p=libc.tls_head; p; i++, p=p->next) {
-		dtv[i] = mem - p->offset;
-		memcpy(dtv[i], p->image, p->len);
+		dtv[i] = (uintptr_t)(mem - p->offset) + DTP_OFFSET;
+		memcpy(mem - p->offset, p->image, p->len);
 	}
 #endif
-	dtv[0] = (void *)libc.tls_cnt;
+	dtv[0] = libc.tls_cnt;
 	td->dtv = td->dtv_copy = dtv;
 	return td;
 }
diff --git a/src/env/__reset_tls.c b/src/env/__reset_tls.c
index 677e57f5..15685bc6 100644
--- a/src/env/__reset_tls.c
+++ b/src/env/__reset_tls.c
@@ -6,11 +6,10 @@ void __reset_tls()
 {
 	pthread_t self = __pthread_self();
 	struct tls_module *p;
-	size_t i, n = (size_t)self->dtv[0];
+	size_t i, n = self->dtv[0];
 	if (n) for (p=libc.tls_head, i=1; i<=n; i++, p=p->next) {
-		if (!self->dtv[i]) continue;
-		memcpy(self->dtv[i], p->image, p->len);
-		memset((char *)self->dtv[i]+p->len, 0,
-			p->size - p->len);
+		char *mem = (char *)(self->dtv[i] - DTP_OFFSET);
+		memcpy(mem, p->image, p->len);
+		memset(mem+p->len, 0, p->size - p->len);
 	}
 }
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
index d491f975..7a25b88e 100644
--- a/src/internal/pthread_impl.h
+++ b/src/internal/pthread_impl.h
@@ -17,7 +17,8 @@ struct pthread {
 	/* Part 1 -- these fields may be external or
 	 * internal (accessed via asm) ABI. Do not change. */
 	struct pthread *self;
-	void **dtv, *unused1, *unused2;
+	uintptr_t *dtv;
+	void *unused1, *unused2;
 	uintptr_t sysinfo;
 	uintptr_t canary, canary2;
 
@@ -54,7 +55,7 @@ struct pthread {
 	/* Part 3 -- the positions of these fields relative to
 	 * the end of the structure is external and internal ABI. */
 	uintptr_t canary_at_end;
-	void **dtv_copy;
+	uintptr_t *dtv_copy;
 };
 
 struct start_sched_args {
diff --git a/src/thread/__tls_get_addr.c b/src/thread/__tls_get_addr.c
index 34fbc46c..d7afdabd 100644
--- a/src/thread/__tls_get_addr.c
+++ b/src/thread/__tls_get_addr.c
@@ -4,8 +4,8 @@
 void *__tls_get_addr(tls_mod_off_t *v)
 {
 	pthread_t self = __pthread_self();
-	if (v[0]<=(size_t)self->dtv[0])
-		return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
+	if (v[0] <= self->dtv[0])
+		return (void *)(self->dtv[v[0]] + v[1]);
 	return __tls_get_new(v);
 }