summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoerg <joerg@NetBSD.org>2011-11-17 16:20:11 +0000
committerjoerg <joerg@NetBSD.org>2011-11-17 16:20:11 +0000
commit3de82d2d274750ab7ec74b759ff8d9c2cd9b080e (patch)
tree6c80c9eaff445830abb57fc53f99b17c5375b22b
parent7960eefa9186d680656e8ca93b01cd6be8ea55da (diff)
FreeBSD bug report 161344: TLS area for the main thread is set up to
early, if e.g. pointers to functions are used as initializers.
-rw-r--r--libexec/ld.elf_so/rtld.c17
-rw-r--r--tests/lib/libc/tls/dso/h_tls_dlopen.c10
-rw-r--r--tests/lib/libc/tls/t_tls_dlopen.c11
-rw-r--r--tests/lib/libc/tls/t_tls_dynamic.c13
-rw-r--r--tests/lib/libc/tls_dso/h_tls_dynamic.c7
5 files changed, 46 insertions, 12 deletions
diff --git a/libexec/ld.elf_so/rtld.c b/libexec/ld.elf_so/rtld.c
index 0adc9b81e4f..c33bbcd90ce 100644
--- a/libexec/ld.elf_so/rtld.c
+++ b/libexec/ld.elf_so/rtld.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.c,v 1.153 2011/10/23 21:06:07 christos Exp $ */
+/* $NetBSD: rtld.c,v 1.154 2011/11/17 16:20:11 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.153 2011/10/23 21:06:07 christos Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.154 2011/11/17 16:20:11 joerg Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -642,13 +642,12 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
}
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
- dbg(("initializing initial Thread Local Storage"));
+ dbg(("initializing initial Thread Local Storage offsets"));
/*
* All initial objects get the TLS space from the static block.
*/
for (obj = _rtld_objlist; obj != NULL; obj = obj->next)
_rtld_tls_offset_allocate(obj);
- _rtld_tls_initial_allocation();
#endif
dbg(("relocating objects"));
@@ -659,6 +658,16 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
if (_rtld_do_copy_relocations(_rtld_objmain) == -1)
_rtld_die();
+#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
+ dbg(("initializing Thread Local Storage for main thread"));
+ /*
+ * Set up TLS area for the main thread.
+ * This has to be done after all relocations are processed,
+ * since .tdata may contain relocations.
+ */
+ _rtld_tls_initial_allocation();
+#endif
+
/*
* Set the __progname, environ and, __mainprog_obj before
* calling anything that might use them.
diff --git a/tests/lib/libc/tls/dso/h_tls_dlopen.c b/tests/lib/libc/tls/dso/h_tls_dlopen.c
index 3ce994456c3..7daf74d50d9 100644
--- a/tests/lib/libc/tls/dso/h_tls_dlopen.c
+++ b/tests/lib/libc/tls/dso/h_tls_dlopen.c
@@ -1,4 +1,4 @@
-/* $NetBSD: h_tls_dlopen.c,v 1.1 2011/03/09 23:10:08 joerg Exp $ */
+/* $NetBSD: h_tls_dlopen.c,v 1.2 2011/11/17 16:20:11 joerg Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -32,8 +32,10 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: h_tls_dlopen.c,v 1.1 2011/03/09 23:10:08 joerg Exp $");
+__RCSID("$NetBSD: h_tls_dlopen.c,v 1.2 2011/11/17 16:20:11 joerg Exp $");
+#include <atf-c.h>
+#include <unistd.h>
#include <sys/tls.h>
#if !defined(__HAVE_TLS_VARIANT_I) && !defined(__HAVE_TLS_VARIANT_II)
@@ -42,6 +44,8 @@ __RCSID("$NetBSD: h_tls_dlopen.c,v 1.1 2011/03/09 23:10:08 joerg Exp $");
extern __thread int var1;
extern __thread int var2;
+extern __thread int *var3;
+__thread static pid_t (*local_var)(void) = getpid;
void testf_dso_helper(int x, int y);
@@ -50,4 +54,6 @@ testf_dso_helper(int x, int y)
{
var1 = x;
var2 = y;
+ var3 = &optind;
+ ATF_CHECK_EQ(local_var, getpid);
}
diff --git a/tests/lib/libc/tls/t_tls_dlopen.c b/tests/lib/libc/tls/t_tls_dlopen.c
index 3b814c4a241..2cab709fa20 100644
--- a/tests/lib/libc/tls/t_tls_dlopen.c
+++ b/tests/lib/libc/tls/t_tls_dlopen.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_tls_dlopen.c,v 1.1 2011/03/09 23:10:07 joerg Exp $ */
+/* $NetBSD: t_tls_dlopen.c,v 1.2 2011/11/17 16:20:11 joerg Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -32,11 +32,12 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_tls_dlopen.c,v 1.1 2011/03/09 23:10:07 joerg Exp $");
+__RCSID("$NetBSD: t_tls_dlopen.c,v 1.2 2011/11/17 16:20:11 joerg Exp $");
#include <atf-c.h>
#include <dlfcn.h>
#include <pthread.h>
+#include <unistd.h>
#include <sys/tls.h>
@@ -56,18 +57,24 @@ void (*testf_helper)(int, int);
__thread int var1 = 1;
__thread int var2;
+__thread int *var3 = &optind;
+int var4_helper;
+__thread int *var4 = &var4_helper;
static void *
testf(void *dummy)
{
ATF_CHECK_EQ(var1, 1);
ATF_CHECK_EQ(var2, 0);
+ ATF_CHECK_EQ(var3, &optind);
+ ATF_CHECK_EQ(var4, &var4_helper);
testf_helper(2, 2);
ATF_CHECK_EQ(var1, 2);
ATF_CHECK_EQ(var2, 2);
testf_helper(3, 3);
ATF_CHECK_EQ(var1, 3);
ATF_CHECK_EQ(var2, 3);
+ ATF_CHECK_EQ(var3, &optind);
return NULL;
}
diff --git a/tests/lib/libc/tls/t_tls_dynamic.c b/tests/lib/libc/tls/t_tls_dynamic.c
index 4c7310c6c90..ae1803068b8 100644
--- a/tests/lib/libc/tls/t_tls_dynamic.c
+++ b/tests/lib/libc/tls/t_tls_dynamic.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_tls_dynamic.c,v 1.1 2011/03/09 23:10:07 joerg Exp $ */
+/* $NetBSD: t_tls_dynamic.c,v 1.2 2011/11/17 16:20:11 joerg Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -32,10 +32,11 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_tls_dynamic.c,v 1.1 2011/03/09 23:10:07 joerg Exp $");
+__RCSID("$NetBSD: t_tls_dynamic.c,v 1.2 2011/11/17 16:20:11 joerg Exp $");
#include <atf-c.h>
#include <pthread.h>
+#include <unistd.h>
#include <sys/tls.h>
@@ -55,6 +56,11 @@ void testf_dso_helper(int, int);
extern __thread int var1;
extern __thread int var2;
+extern __thread pid_t (*dso_var1)(void);
+
+__thread int *var3 = &optind;
+int var4_helper;
+__thread int *var4 = &var4_helper;
static void *
testf(void *dummy)
@@ -67,6 +73,9 @@ testf(void *dummy)
testf_dso_helper(3, 3);
ATF_CHECK_EQ(var1, 3);
ATF_CHECK_EQ(var2, 3);
+ ATF_CHECK_EQ(var3, &optind);
+ ATF_CHECK_EQ(var4, &var4_helper);
+ ATF_CHECK_EQ(dso_var1, getpid);
return NULL;
}
diff --git a/tests/lib/libc/tls_dso/h_tls_dynamic.c b/tests/lib/libc/tls_dso/h_tls_dynamic.c
index 592e149e82b..b33380faee4 100644
--- a/tests/lib/libc/tls_dso/h_tls_dynamic.c
+++ b/tests/lib/libc/tls_dso/h_tls_dynamic.c
@@ -1,4 +1,4 @@
-/* $NetBSD: h_tls_dynamic.c,v 1.1 2011/03/09 23:10:08 joerg Exp $ */
+/* $NetBSD: h_tls_dynamic.c,v 1.2 2011/11/17 16:20:11 joerg Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -32,8 +32,9 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: h_tls_dynamic.c,v 1.1 2011/03/09 23:10:08 joerg Exp $");
+__RCSID("$NetBSD: h_tls_dynamic.c,v 1.2 2011/11/17 16:20:11 joerg Exp $");
+#include <unistd.h>
#include <sys/tls.h>
#if !defined(__HAVE_TLS_VARIANT_I) && !defined(__HAVE_TLS_VARIANT_II)
@@ -43,6 +44,8 @@ __RCSID("$NetBSD: h_tls_dynamic.c,v 1.1 2011/03/09 23:10:08 joerg Exp $");
__thread int var1 = 1;
__thread int var2;
+__thread pid_t (*dso_var1)(void) = getpid;
+
void testf_dso_helper(int x, int y);
void