about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/env/__init_tls.c2
-rw-r--r--src/internal/pthread_impl.h1
-rw-r--r--src/ldso/dynlink.c6
3 files changed, 5 insertions, 4 deletions
diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
index b0dad429..e651c7a7 100644
--- a/src/env/__init_tls.c
+++ b/src/env/__init_tls.c
@@ -54,7 +54,7 @@ void *__copy_tls(unsigned char *mem)
 	td = (pthread_t)mem;
 	mem -= T.size;
 #endif
-	td->dtv = dtv;
+	td->dtv = td->dtv_copy = dtv;
 	dtv[1] = mem;
 	memcpy(mem, T.image, T.len);
 	return td;
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
index 441b075f..7c352bc4 100644
--- a/src/internal/pthread_impl.h
+++ b/src/internal/pthread_impl.h
@@ -45,6 +45,7 @@ struct pthread {
 	volatile int startlock[2];
 	unsigned long sigmask[_NSIG/8/sizeof(long)];
 	void *stdio_locks;
+	void **dtv_copy;
 };
 
 struct __timer {
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index ca101993..b0d5ff46 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -1015,7 +1015,7 @@ void *__copy_tls(unsigned char *mem)
 	dtv[0] = (void *)tls_cnt;
 	if (!tls_cnt) {
 		td = (void *)(dtv+1);
-		td->dtv = dtv;
+		td->dtv = td->dtv_copy = dtv;
 		return td;
 	}
 
@@ -1041,7 +1041,7 @@ void *__copy_tls(unsigned char *mem)
 		memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
 	}
 #endif
-	td->dtv = dtv;
+	td->dtv = td->dtv_copy = dtv;
 	return td;
 }
 
@@ -1071,7 +1071,7 @@ void *__tls_get_new(size_t *v)
 		memcpy(newdtv, self->dtv,
 			((size_t)self->dtv[0]+1) * sizeof(void *));
 		newdtv[0] = (void *)v[0];
-		self->dtv = newdtv;
+		self->dtv = self->dtv_copy = newdtv;
 	}
 
 	/* Get new TLS memory from all new DSOs up to the requested one */