summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2017-12-05 13:45:31 +0000
committerkettenis <kettenis@openbsd.org>2017-12-05 13:45:31 +0000
commit0afcdeda897cccf53b8f99c1eb030fd52ee9ee99 (patch)
treeae06143be769a47677266a3ccbc027b7cf3992e0
parentWhen sending out a proposal we create an SA/SPI for the Child SAs if we (diff)
downloadwireguard-openbsd-0afcdeda897cccf53b8f99c1eb030fd52ee9ee99.tar.xz
wireguard-openbsd-0afcdeda897cccf53b8f99c1eb030fd52ee9ee99.zip
Implement __cxa_thread_atexit to support C++11 thread_local scope. The
interface is also made available as __cxa_thread_atexit_impl to satisfy the needs of GNU libstdc++. ok guenther@, millert@
-rw-r--r--lib/libc/Symbols.list2
-rw-r--r--lib/libc/include/thread_private.h3
-rw-r--r--lib/libc/shlib_version2
-rw-r--r--lib/libc/stdlib/atexit.c54
-rw-r--r--lib/libc/stdlib/atexit.h4
-rw-r--r--lib/libc/thread/rthread.c3
6 files changed, 63 insertions, 5 deletions
diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list
index d6346040a78..63420faebdd 100644
--- a/lib/libc/Symbols.list
+++ b/lib/libc/Symbols.list
@@ -1466,6 +1466,8 @@ random
/* stdlib */
_Exit
__cxa_atexit
+__cxa_thread_atexit
+__cxa_thread_atexit_impl
__cxa_finalize
__isthreaded
a64l
diff --git a/lib/libc/include/thread_private.h b/lib/libc/include/thread_private.h
index fd530d7dff1..ae8d554a8ab 100644
--- a/lib/libc/include/thread_private.h
+++ b/lib/libc/include/thread_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: thread_private.h,v 1.32 2017/11/04 22:53:57 jca Exp $ */
+/* $OpenBSD: thread_private.h,v 1.33 2017/12/05 13:45:31 kettenis Exp $ */
/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
@@ -394,6 +394,7 @@ void _spinunlock(volatile _atomic_lock_t *);
void _rthread_debug(int, const char *, ...)
__attribute__((__format__ (printf, 2, 3)));
pid_t _thread_dofork(pid_t (*_sys_fork)(void));
+void _thread_finalize(void);
/*
* Threading syscalls not declared in system headers
diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version
index 7fe672d9c92..858859a0e22 100644
--- a/lib/libc/shlib_version
+++ b/lib/libc/shlib_version
@@ -1,4 +1,4 @@
major=92
-minor=0
+minor=1
# note: If changes were made to include/thread_private.h or if system
# calls were added/changed then librthread/shlib_version also be updated.
diff --git a/lib/libc/stdlib/atexit.c b/lib/libc/stdlib/atexit.c
index 83cc1282a98..dc117a37524 100644
--- a/lib/libc/stdlib/atexit.c
+++ b/lib/libc/stdlib/atexit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atexit.c,v 1.24 2015/11/10 04:14:03 guenther Exp $ */
+/* $OpenBSD: atexit.c,v 1.25 2017/12/05 13:45:31 kettenis Exp $ */
/*
* Copyright (c) 2002 Daniel Hartmeier
* All rights reserved.
@@ -31,12 +31,24 @@
#include <sys/types.h>
#include <sys/mman.h>
+#include <dlfcn.h>
+#include <elf.h>
+#pragma weak _DYNAMIC
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "atexit.h"
#include "atfork.h"
#include "thread_private.h"
+#include "tib.h"
+
+typeof(dlctl) dlctl asm("_dlctl") __attribute__((weak));
+
+struct thread_atexit_fn {
+ void (*func)(void *);
+ void *arg;
+ struct thread_atexit_fn *next;
+};
struct atexit *__atexit;
static int restartloop;
@@ -121,6 +133,43 @@ atexit(void (*fn)(void))
}
DEF_STRONG(atexit);
+__weak_alias(__cxa_thread_atexit, __cxa_thread_atexit_impl);
+
+int
+__cxa_thread_atexit_impl(void (*func)(void *), void *arg, void *dso)
+{
+ struct thread_atexit_fn *fnp;
+ struct tib *tib = TIB_GET();
+
+ fnp = calloc(1, sizeof(struct thread_atexit_fn));
+ if (fnp == NULL)
+ return -1;
+
+ if (_DYNAMIC)
+ dlctl(NULL, DL_REFERENCE, dso);
+
+ fnp->func = func;
+ fnp->arg = arg;
+ fnp->next = tib->tib_atexit;
+ tib->tib_atexit = fnp;
+
+ return 0;
+}
+DEF_STRONG(__cxa_thread_atexit_impl);
+
+void
+_thread_finalize(void)
+{
+ struct tib *tib = TIB_GET();
+
+ while (tib->tib_atexit) {
+ struct thread_atexit_fn *fnp = tib->tib_atexit;
+ tib->tib_atexit = fnp->next;
+ fnp->func(fnp->arg);
+ free(fnp);
+ }
+}
+
/*
* Call all handlers registered with __cxa_atexit() for the shared
* object owning 'dso'.
@@ -134,6 +183,9 @@ __cxa_finalize(void *dso)
int n, pgsize = getpagesize();
static int call_depth;
+ if (dso == NULL)
+ _thread_finalize();
+
_ATEXIT_LOCK();
call_depth++;
diff --git a/lib/libc/stdlib/atexit.h b/lib/libc/stdlib/atexit.h
index e2e821de04b..d9bfed852f6 100644
--- a/lib/libc/stdlib/atexit.h
+++ b/lib/libc/stdlib/atexit.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: atexit.h,v 1.10 2015/10/25 18:01:24 guenther Exp $ */
+/* $OpenBSD: atexit.h,v 1.11 2017/12/05 13:45:31 kettenis Exp $ */
/*
* Copyright (c) 2002 Daniel Hartmeier
@@ -46,7 +46,9 @@ extern struct atexit *__atexit; /* points to head of LIFO stack */
__END_HIDDEN_DECLS
int __cxa_atexit(void (*)(void *), void *, void *);
+int __cxa_thread_atexit(void (*)(void *), void *, void *);
void __cxa_finalize(void *);
PROTO_NORMAL(__cxa_atexit);
+PROTO_STD_DEPRECATED(__cxa_thread_atexit);
PROTO_NORMAL(__cxa_finalize);
diff --git a/lib/libc/thread/rthread.c b/lib/libc/thread/rthread.c
index 66405cf477a..f26e85ffd31 100644
--- a/lib/libc/thread/rthread.c
+++ b/lib/libc/thread/rthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.c,v 1.6 2017/11/04 22:53:57 jca Exp $ */
+/* $OpenBSD: rthread.c,v 1.7 2017/12/05 13:45:31 kettenis Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -137,6 +137,7 @@ pthread_exit(void *retval)
oclfn->fn(oclfn->arg);
free(oclfn);
}
+ _thread_finalize();
_rthread_tls_destructors(thread);
if (_thread_cb.tc_thread_release != NULL)