summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-10-08 12:39:47 +0000
committerkib <kib@FreeBSD.org>2011-10-08 12:39:47 +0000
commit85d4378ca8b2ee0b3c911448dbf9ef0978cbe1d7 (patch)
treeb03c113a0ed9438171ad08f452c83fd80bdbb10f /libexec
parent07ac74d257832436e5d62b6a367e914e7b885db8 (diff)
downloadFreeBSD-src-85d4378ca8b2ee0b3c911448dbf9ef0978cbe1d7.zip
FreeBSD-src-85d4378ca8b2ee0b3c911448dbf9ef0978cbe1d7.tar.gz
Setting up TLS block for the main thread must be done after the
relocations are processed, since tls initialization section might be itself subject for relocations. Only set up of the block is postponed, the tls block offsets are allocated before relocation processing, since TLS-related relocations may need offsets ready. Reported by: ale PR: threads/161344 Reviewed by: kan MFC after: 1 week
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/rtld.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 65eadb5..36102ba 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -495,8 +495,12 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
exit (0);
}
- /* setup TLS for main thread */
- dbg("initializing initial thread local storage");
+ /*
+ * Processing tls relocations requires having the tls offsets
+ * initialized. Prepare offsets before starting initial
+ * relocation processing.
+ */
+ dbg("initializing initial thread local storage offsets");
STAILQ_FOREACH(entry, &list_main, link) {
/*
* Allocate all the initial objects out of the static TLS
@@ -504,7 +508,6 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
*/
allocate_tls_offset(entry->obj);
}
- allocate_initial_tls(obj_list);
if (relocate_objects(obj_main,
ld_bind_now != NULL && *ld_bind_now != '\0', &obj_rtld, NULL) == -1)
@@ -519,6 +522,14 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
exit (0);
}
+ /*
+ * Setup TLS for main thread. This must be done after the
+ * relocations are processed, since tls initialization section
+ * might be the subject for relocations.
+ */
+ dbg("initializing initial thread local storage");
+ allocate_initial_tls(obj_list);
+
dbg("initializing key program variables");
set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : "");
set_program_var("environ", env);
OpenPOWER on IntegriCloud