diff options
author | 2013-12-12 08:12:08 +0000 | |
---|---|---|
committer | 2013-12-12 08:12:08 +0000 | |
commit | 601355ee8401e35bb31c2066a5188e33c2d5ce90 (patch) | |
tree | 17fef858a7ad751dab0aa694638ad9d9a19eeb6e | |
parent | Set the d_off member as getdents() expects in ntfs_readdir() (diff) | |
download | wireguard-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.c | 7 | ||||
-rw-r--r-- | lib/csu/crt0.c | 7 | ||||
-rw-r--r-- | lib/librthread/rthread.c | 35 |
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"); |