diff options
| author | 2013-12-12 08:12:08 +0000 | |
|---|---|---|
| committer | 2013-12-12 08:12:08 +0000 | |
| commit | 601355ee8401e35bb31c2066a5188e33c2d5ce90 (patch) | |
| tree | 17fef858a7ad751dab0aa694638ad9d9a19eeb6e /lib/librthread/rthread.c | |
| 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@
Diffstat (limited to 'lib/librthread/rthread.c')
| -rw-r--r-- | lib/librthread/rthread.c | 35 |
1 files changed, 29 insertions, 6 deletions
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"); |
