summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2013-12-12 08:12:08 +0000
committerguenther <guenther@openbsd.org>2013-12-12 08:12:08 +0000
commit601355ee8401e35bb31c2066a5188e33c2d5ce90 (patch)
tree17fef858a7ad751dab0aa694638ad9d9a19eeb6e
parentSet the d_off member as getdents() expects in ntfs_readdir() (diff)
downloadwireguard-openbsd-601355ee8401e35bb31c2066a5188e33c2d5ce90.tar.xz
wireguard-openbsd-601355ee8401e35bb31c2066a5188e33c2d5ce90.zip
Fix static linking of libpthread: have crt0 invoke __init_tcb() if it's
defined and we don't think ld.so has already done the TCB setup. ok and much discussion miod@
-rw-r--r--lib/csu/common_elf/crt0.c7
-rw-r--r--lib/csu/crt0.c7
-rw-r--r--lib/librthread/rthread.c35
3 files changed, 41 insertions, 8 deletions
diff --git a/lib/csu/common_elf/crt0.c b/lib/csu/common_elf/crt0.c
index 32cbe4c1f87..aaef64a7a57 100644
--- a/lib/csu/common_elf/crt0.c
+++ b/lib/csu/common_elf/crt0.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crt0.c,v 1.1 2013/12/03 06:21:40 guenther Exp $ */
+/* $OpenBSD: crt0.c,v 1.2 2013/12/12 08:12:08 guenther Exp $ */
/*
* Copyright (c) 1995 Christopher G. Demetriou
@@ -49,6 +49,8 @@ static void ___start(MD_START_ARGS) __used;
#define MD_EPROL_LABEL __asm(" .text\n_eprol:")
#endif
+void __init_tcb(char **_envp);
+#pragma weak __init_tcb
static char *_strrchr(char *, char);
@@ -91,7 +93,10 @@ MD_START(MD_START_ARGS)
#ifndef MD_NO_CLEANUP
if (cleanup != NULL)
atexit(cleanup);
+ else
#endif
+ if (__init_tcb != NULL)
+ __init_tcb(envp);
#ifdef MCRT0
atexit(_mcleanup);
diff --git a/lib/csu/crt0.c b/lib/csu/crt0.c
index 32cbe4c1f87..aaef64a7a57 100644
--- a/lib/csu/crt0.c
+++ b/lib/csu/crt0.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crt0.c,v 1.1 2013/12/03 06:21:40 guenther Exp $ */
+/* $OpenBSD: crt0.c,v 1.2 2013/12/12 08:12:08 guenther Exp $ */
/*
* Copyright (c) 1995 Christopher G. Demetriou
@@ -49,6 +49,8 @@ static void ___start(MD_START_ARGS) __used;
#define MD_EPROL_LABEL __asm(" .text\n_eprol:")
#endif
+void __init_tcb(char **_envp);
+#pragma weak __init_tcb
static char *_strrchr(char *, char);
@@ -91,7 +93,10 @@ MD_START(MD_START_ARGS)
#ifndef MD_NO_CLEANUP
if (cleanup != NULL)
atexit(cleanup);
+ else
#endif
+ if (__init_tcb != NULL)
+ __init_tcb(envp);
#ifdef MCRT0
atexit(_mcleanup);
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c
index 710a3a97448..fa2a28d7ac7 100644
--- a/lib/librthread/rthread.c
+++ b/lib/librthread/rthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.c,v 1.75 2013/11/29 16:27:40 guenther Exp $ */
+/* $OpenBSD: rthread.c,v 1.76 2013/12/12 08:12:08 guenther Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -104,13 +104,34 @@ _spinunlock(volatile struct _spinlock *lock)
* this is handled by __tfork_thread()
*/
void _rthread_initlib(void) __attribute__((constructor));
-void _rthread_initlib(void)
+void
+_rthread_initlib(void)
{
- struct thread_control_block *tcb = &_initial_thread_tcb;
+ static int tcb_set;
+ struct thread_control_block *tcb;
+
+ if (__predict_false(tcb_set == 0) && __get_tcb() == NULL) {
+ tcb_set = 1;
- /* use libc's errno for the main thread */
- TCB_INIT(tcb, &_initial_thread, ___errno());
- TCB_SET(tcb);
+ /* use libc's errno for the main thread */
+ tcb = &_initial_thread_tcb;
+ TCB_INIT(tcb, &_initial_thread, ___errno());
+ TCB_SET(tcb);
+ }
+}
+
+/*
+ * This is invoked by ___start() in crt0. Eventually, when ld.so handles
+ * TCB setup for dynamic executables, this will only be called to handle
+ * the TCB setup for static executables and may migrate to libc. The
+ * envp argument is so that it can (someday) use that to find the Auxinfo
+ * array and thus the ELF phdr and the PT_TLS info.
+ */
+void __init_tcb(char **_envp);
+void
+__init_tcb(__unused char **envp)
+{
+ _rthread_initlib();
}
int *
@@ -181,6 +202,8 @@ _rthread_init(void)
_thread_pagesize = (size_t)sysconf(_SC_PAGESIZE);
_rthread_attr_default.guard_size = _thread_pagesize;
+ _rthread_initlib();
+
_threads_ready = 1;
_rthread_debug(1, "rthread init\n");