diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2016-05-07 19:05:25 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2016-05-07 19:05:25 +0000 |
commit | be4e94637d7117375492627b79c41629c7da9bc3 (patch) | |
tree | 61a9fabcc07d38d2720bbb937e83103928286550 /include | |
parent | 33d8693716b4a6d503e0ba97f94a783905b87f28 (diff) |
Use a Thread Information Block in both single and multi-threaded programs.
This stores errno, the cancelation flags, and related bits for each thread
and is allocated by ld.so or libc.a. This is an ABI break from 5.9-stable!
Make libpthread dlopen'able by moving the cancelation wrappers into libc
and doing locking and fork/errno handling via callbacks that libpthread
registers when it first initializes. 'errno' *must* be declared via
<errno.h> now!
Clean up libpthread's symbol exports like libc.
On powerpc, offset the TIB/TCB/TLS data from the register per the ELF spec.
Testing by various, particularly sthen@ and patrick@
ok kettenis@
Diffstat (limited to 'include')
-rw-r--r-- | include/Makefile | 4 | ||||
-rw-r--r-- | include/tib.h | 99 |
2 files changed, 54 insertions, 49 deletions
diff --git a/include/Makefile b/include/Makefile index 72a1af0d831..b10865bdf30 100644 --- a/include/Makefile +++ b/include/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.210 2016/03/09 16:28:46 deraadt Exp $ +# $OpenBSD: Makefile,v 1.211 2016/05/07 19:05:21 guenther Exp $ # $NetBSD: Makefile,v 1.59 1996/05/15 21:36:43 jtc Exp $ # @(#)Makefile 5.45.1.1 (Berkeley) 5/6/91 @@ -18,7 +18,7 @@ FILES= a.out.h ar.h asr.h assert.h bitstring.h blf.h bsd_auth.h \ nlist.h nl_types.h paths.h poll.h pwd.h ranlib.h readpassphrase.h \ regex.h resolv.h rmd160.h search.h setjmp.h sha1.h sha2.h signal.h \ siphash.h sndio.h spawn.h stdbool.h stddef.h stdio.h stdlib.h \ - string.h strings.h struct.h sysexits.h tar.h tgmath.h time.h \ + string.h strings.h struct.h sysexits.h tar.h tgmath.h tib.h time.h \ ttyent.h unistd.h utime.h utmp.h uuid.h vis.h wchar.h wctype.h MFILES= frame.h diff --git a/include/tib.h b/include/tib.h index 74459f9c7dd..7dff1168ec9 100644 --- a/include/tib.h +++ b/include/tib.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tib.h,v 1.2 2016/03/20 02:30:28 guenther Exp $ */ +/* $OpenBSD: tib.h,v 1.3 2016/05/07 19:05:21 guenther Exp $ */ /* * Copyright (c) 2011,2014 Philip Guenther <guenther@openbsd.org> * @@ -46,19 +46,13 @@ * TIB_TO_TCB(tib) * Given a TIB pointer, return the matching TCB pointer * - * TIB_INIT(tib, dtv) + * TIB_INIT(tib, dtv, thread) * Initializes a TIB for a new thread, using the supplied - * value for the dtv pointer - * - * TIB_TO_THREAD(tib) - * Given a TIB pointer, return a pointer to the struct pthread + * values for its dtv and thread pointers * * TIB_GET() * Short-hand for TCB_TO_TIB(TCB_GET()) * - * TIB_THREAD() - * Returns a pointer to this thread's struct pthread - * * TIB_EXTRA_ALIGN * On TLS varaint 2 archs, what alignment is sufficient * for the extra space that will be used for struct pthread? @@ -66,24 +60,24 @@ * The following functions are provided by either ld.so (dynamic) or * libc (static) for allocating and freeing a common memory block that * will hold both the TIB and the pthread structure: - * _dl_allocate_tib(sizeof(struct pthread), flags) + * _dl_allocate_tib(sizeof(struct pthread)) * Allocates a combined TIB and pthread memory region. - * The first argument is the amount of space to reserve - * for the pthread structure; the second argument is - * either zero or DAT_UPDATE_CURRENT, the latter meaning - * this call is to update/replace the current thread's - * TIB. Returns a pointer to the TIB inside the - * allocated block. + * The argument is the amount of space to reserve + * for the pthread structure. Returns a pointer to + * the TIB inside the allocated block. * * _dl_free_tib(tib, sizeof(struct pthread)) * Frees a TIB and pthread block previously allocated - * with _dl_allocate_tls(). Must be passed the return + * with _dl_allocate_tib(). Must be passed the return * value of that previous call. */ /* * Regarding <machine/tcb.h>: * - it must define the TLS_VARIANT macro + * - it may define TCB_OFFSET if the TCB address in the kernel and/or + * register is offset from the actual TCB address. TCB_OFFSET > 0 + * means the kernel/register points to *after* the real data. * - if there's a faster way to get or set the TCB pointer for the thread * than the __{get,set}_tcb() syscalls, it should define either or both * the TCB_{GET,SET} macros to do so. @@ -101,6 +95,23 @@ #else # define TCB_SET(tcb) __set_tcb(tcb) #endif +#ifndef TCB_OFFSET +# define TCB_OFFSET 0 +#endif + +/* + * tib_cantcancel values is non-zero is the thread should skip all + * cancellation processing + */ +#define CANCEL_DISABLED 1 +#define CANCEL_DYING 2 + +/* + * tib_cancel_point is non-zero if we're in a cancel point; its modified + * by the cancel point code and read by the cancellation signal handler + */ +#define CANCEL_POINT 1 +#define CANCEL_POINT_DELAYED 2 #if TLS_VARIANT == 1 @@ -108,17 +119,16 @@ * ABI specifies that the static TLS data starts two words after the * (notional) thread pointer, with the first of those two words being * the TLS dtv pointer. The other (second) word is reserved for the - * implementation, so we place the thread's locale there, but we place - * our thread bits before the TCB, at negative offsets from the - * TCB pointer. Ergo, memory is laid out, low to high, as: + * implementation, so we place the pointer to the thread structure there, + * but we place our actual thread bits before the TCB, at negative offsets + * from the TCB pointer. Ergo, memory is laid out, low to high, as: * * [pthread structure] * TIB { - * int cancel_flags - * int cancel_requested + * ...cancelation and other int-sized info... * int errno * void *locale - * TCB { + * TCB (- TCB_OFFSET) { * void *dtv * struct pthread *thread * } @@ -127,21 +137,17 @@ */ struct tib { -#ifdef __LP64__ - int __tib_padding; /* padding for 8byte alignment */ -#endif - int tib_cancel_flags; - int tib_cancel; + int tib_thread_flags; /* internal to libpthread */ + pid_t tib_tid; + int tib_cantcancel; + int tib_cancel_point; + int tib_canceled; int tib_errno; void *tib_locale; void *tib_dtv; /* internal to the runtime linker */ void *tib_thread; }; -#ifdef __LP64__ -# define _TIB_PREP(tib) ((void)((tib)->__tib_padding = 0)) -#endif -#define _TIBO_PTHREAD (- _ALIGN(sizeof(struct pthread))) #elif TLS_VARIANT == 2 /* @@ -152,15 +158,14 @@ struct tib { * out, low to high, as: * static TLS data * TIB { - * TCB { + * TCB (- TCB_OFFSET) { * self pointer [i386/amd64 only] * void *dtv * } * struct pthread *thread * void *locale * int errno - * int cancel_count_flags - * int cancel_requested + * ...cancelation and other int-sized info... * } * [pthread structure] */ @@ -174,19 +179,20 @@ struct tib { void *tib_thread; void *tib_locale; int tib_errno; - int tib_cancel; /* set to request cancelation */ - int tib_cancel_flags; -#if defined(__LP64__) || defined(__i386) + int tib_canceled; + int tib_cancel_point; + int tib_cantcancel; + pid_t tib_tid; + int tib_thread_flags; /* internal to libpthread */ +#if !defined(__LP64__) && !defined(__i386) int __tib_padding; /* padding for 8byte alignment */ #endif }; -#define _TIBO_PTHREAD _ALIGN(sizeof(struct tib)) - #if defined(__i386) || defined(__amd64) # define _TIB_PREP(tib) \ - ((void)((tib)->__tib_self = (tib), (tib)->__tib_padding = 0)) -#elif defined(__LP64__) + ((void)((tib)->__tib_self = (tib))) +#elif !defined(__LP64__) && !defined(__i386) # define _TIB_PREP(tib) ((void)((tib)->__tib_padding = 0)) #endif @@ -204,8 +210,9 @@ struct tib { #define TIB_INIT(tib, dtv, thread) do { \ (tib)->tib_thread = (thread); \ (tib)->tib_locale = NULL; \ - (tib)->tib_cancel_flags = 0; \ - (tib)->tib_cancel = 0; \ + (tib)->tib_cantcancel = 0; \ + (tib)->tib_cancel_point = 0; \ + (tib)->tib_canceled = 0; \ (tib)->tib_dtv = (dtv); \ (tib)->tib_errno = 0; \ _TIB_PREP(tib); \ @@ -214,13 +221,11 @@ struct tib { #ifndef __tib_tcb # define __tib_tcb tib_dtv #endif -#define _TIBO_TCB offsetof(struct tib, __tib_tcb) +#define _TIBO_TCB (offsetof(struct tib, __tib_tcb) + TCB_OFFSET) #define TCB_TO_TIB(tcb) ((struct tib *)((char *)(tcb) - _TIBO_TCB)) #define TIB_TO_TCB(tib) ((char *)(tib) + _TIBO_TCB) -#define TIB_TO_THREAD(tib) ((struct pthread *)(tib)->tib_thread) #define TIB_GET() TCB_TO_TIB(TCB_GET()) -#define TCB_THREAD() TIB_TO_THREAD(TIB_GET()) __BEGIN_DECLS |