Annotation of src/include/tib.h, Revision 1.8
1.8 ! kettenis 1: /* $OpenBSD: tib.h,v 1.7 2019/05/10 13:29:21 guenther Exp $ */
1.1 guenther 2: /*
3: * Copyright (c) 2011,2014 Philip Guenther <guenther@openbsd.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: /*
19: * Thread Information Block (TIB) and Thread Local Storage (TLS) handling
20: * (the TCB, Thread Control Block, is part of the TIB)
21: */
22:
23: #ifndef _TIB_H_
24: #define _TIB_H_
25:
26: #include <sys/types.h>
27: #include <machine/tcb.h>
28:
29: #include <stddef.h>
30:
31:
32: /*
33: * This header defines struct tib and at least eight macros:
34: * TLS_VARIANT
35: * Either 1 or 2 (Actually defined by <machine/tcb.h>)
36: *
37: * TCB_SET(tcb)
38: * Set the TCB pointer for this thread to 'tcb'
39: *
40: * TCB_GET()
41: * Return the TCB pointer for this thread
42: *
43: * TCB_TO_TIB(tcb)
44: * Given a TCB pointer, return the matching TIB pointer
45: *
46: * TIB_TO_TCB(tib)
47: * Given a TIB pointer, return the matching TCB pointer
48: *
1.3 guenther 49: * TIB_INIT(tib, dtv, thread)
1.1 guenther 50: * Initializes a TIB for a new thread, using the supplied
1.3 guenther 51: * values for its dtv and thread pointers
1.1 guenther 52: *
53: * TIB_GET()
54: * Short-hand for TCB_TO_TIB(TCB_GET())
55: *
56: * TIB_EXTRA_ALIGN
57: * On TLS varaint 2 archs, what alignment is sufficient
58: * for the extra space that will be used for struct pthread?
59: *
60: * The following functions are provided by either ld.so (dynamic) or
61: * libc (static) for allocating and freeing a common memory block that
62: * will hold both the TIB and the pthread structure:
1.3 guenther 63: * _dl_allocate_tib(sizeof(struct pthread))
1.1 guenther 64: * Allocates a combined TIB and pthread memory region.
1.3 guenther 65: * The argument is the amount of space to reserve
66: * for the pthread structure. Returns a pointer to
67: * the TIB inside the allocated block.
1.1 guenther 68: *
69: * _dl_free_tib(tib, sizeof(struct pthread))
70: * Frees a TIB and pthread block previously allocated
1.3 guenther 71: * with _dl_allocate_tib(). Must be passed the return
1.1 guenther 72: * value of that previous call.
73: */
74:
75: /*
76: * Regarding <machine/tcb.h>:
77: * - it must define the TLS_VARIANT macro
1.3 guenther 78: * - it may define TCB_OFFSET if the TCB address in the kernel and/or
79: * register is offset from the actual TCB address. TCB_OFFSET > 0
80: * means the kernel/register points to *after* the real data.
1.1 guenther 81: * - if there's a faster way to get or set the TCB pointer for the thread
82: * than the __{get,set}_tcb() syscalls, it should define either or both
83: * the TCB_{GET,SET} macros to do so.
84: */
85:
86:
1.4 visa 87: /* All archs but mips64 have fast TCB_GET() and don't need caching */
88: #ifndef __mips64__
1.2 guenther 89: # define TCB_HAVE_MD_GET 1
1.1 guenther 90: #endif
1.2 guenther 91: #ifdef TCB_SET
92: # define TCB_HAVE_MD_SET 1
93: #else
94: # define TCB_SET(tcb) __set_tcb(tcb)
1.1 guenther 95: #endif
1.3 guenther 96: #ifndef TCB_OFFSET
97: # define TCB_OFFSET 0
98: #endif
99:
100: /*
1.5 guenther 101: * tib_cantcancel values is non-zero if the thread should skip all
1.3 guenther 102: * cancellation processing
103: */
104: #define CANCEL_DISABLED 1
105: #define CANCEL_DYING 2
106:
107: /*
108: * tib_cancel_point is non-zero if we're in a cancel point; its modified
109: * by the cancel point code and read by the cancellation signal handler
110: */
111: #define CANCEL_POINT 1
112: #define CANCEL_POINT_DELAYED 2
1.1 guenther 113:
114:
115: #if TLS_VARIANT == 1
116: /*
117: * ABI specifies that the static TLS data starts two words after the
118: * (notional) thread pointer, with the first of those two words being
119: * the TLS dtv pointer. The other (second) word is reserved for the
1.3 guenther 120: * implementation, so we place the pointer to the thread structure there,
121: * but we place our actual thread bits before the TCB, at negative offsets
122: * from the TCB pointer. Ergo, memory is laid out, low to high, as:
1.1 guenther 123: *
1.2 guenther 124: * [pthread structure]
1.1 guenther 125: * TIB {
1.3 guenther 126: * ...cancelation and other int-sized info...
1.1 guenther 127: * int errno
1.2 guenther 128: * void *locale
1.3 guenther 129: * TCB (- TCB_OFFSET) {
1.1 guenther 130: * void *dtv
1.2 guenther 131: * struct pthread *thread
1.1 guenther 132: * }
133: * }
134: * static TLS data
135: */
136:
137: struct tib {
1.6 kettenis 138: void *tib_atexit;
1.3 guenther 139: int tib_thread_flags; /* internal to libpthread */
140: pid_t tib_tid;
141: int tib_cantcancel;
142: int tib_cancel_point;
143: int tib_canceled;
1.1 guenther 144: int tib_errno;
1.2 guenther 145: void *tib_locale;
1.8 ! kettenis 146: #ifdef __powerpc64__
! 147: void *tib_thread;
! 148: void *tib_dtv; /* internal to the runtime linker */
! 149: #else
1.1 guenther 150: void *tib_dtv; /* internal to the runtime linker */
1.2 guenther 151: void *tib_thread;
1.8 ! kettenis 152: #endif
1.1 guenther 153: };
154:
155:
156: #elif TLS_VARIANT == 2
157: /*
158: * ABI specifies that the static TLS data occupies the memory before
159: * the TCB pointer, at negative offsets, and that on i386 and amd64
160: * the word the TCB points to contains a pointer to itself. So,
161: * we place errno and our thread bits after that. Memory is laid
162: * out, low to high, as:
163: * static TLS data
164: * TIB {
1.3 guenther 165: * TCB (- TCB_OFFSET) {
1.1 guenther 166: * self pointer [i386/amd64 only]
167: * void *dtv
168: * }
1.2 guenther 169: * struct pthread *thread
1.1 guenther 170: * void *locale
171: * int errno
1.3 guenther 172: * ...cancelation and other int-sized info...
1.1 guenther 173: * }
1.2 guenther 174: * [pthread structure]
1.1 guenther 175: */
176:
177: struct tib {
178: #if defined(__i386) || defined(__amd64)
179: struct tib *__tib_self;
1.2 guenther 180: # define __tib_tcb __tib_self
1.1 guenther 181: #endif
182: void *tib_dtv; /* internal to the runtime linker */
1.2 guenther 183: void *tib_thread;
1.1 guenther 184: void *tib_locale;
185: int tib_errno;
1.3 guenther 186: int tib_canceled;
187: int tib_cancel_point;
188: int tib_cantcancel;
189: pid_t tib_tid;
190: int tib_thread_flags; /* internal to libpthread */
1.6 kettenis 191: void *tib_atexit;
1.1 guenther 192: };
193:
1.2 guenther 194: #if defined(__i386) || defined(__amd64)
195: # define _TIB_PREP(tib) \
1.3 guenther 196: ((void)((tib)->__tib_self = (tib)))
1.1 guenther 197: #endif
198:
199: #define TIB_EXTRA_ALIGN sizeof(void *)
200:
201: #else
202: # error "unknown TLS variant"
203: #endif
204:
205: /* nothing to do by default */
206: #ifndef _TIB_PREP
1.2 guenther 207: # define _TIB_PREP(tib) ((void)0)
1.1 guenther 208: #endif
209:
1.2 guenther 210: #define TIB_INIT(tib, dtv, thread) do { \
211: (tib)->tib_thread = (thread); \
1.6 kettenis 212: (tib)->tib_atexit = NULL; \
1.1 guenther 213: (tib)->tib_locale = NULL; \
1.3 guenther 214: (tib)->tib_cantcancel = 0; \
215: (tib)->tib_cancel_point = 0; \
216: (tib)->tib_canceled = 0; \
1.1 guenther 217: (tib)->tib_dtv = (dtv); \
218: (tib)->tib_errno = 0; \
219: _TIB_PREP(tib); \
220: } while (0)
221:
222: #ifndef __tib_tcb
1.2 guenther 223: # define __tib_tcb tib_dtv
1.1 guenther 224: #endif
1.3 guenther 225: #define _TIBO_TCB (offsetof(struct tib, __tib_tcb) + TCB_OFFSET)
1.1 guenther 226:
227: #define TCB_TO_TIB(tcb) ((struct tib *)((char *)(tcb) - _TIBO_TCB))
228: #define TIB_TO_TCB(tib) ((char *)(tib) + _TIBO_TCB)
229: #define TIB_GET() TCB_TO_TIB(TCB_GET())
230:
231:
232: __BEGIN_DECLS
1.7 guenther 233: struct dl_info;
234: struct dl_phdr_info;
235: struct dl_cb_0 {
236: void *(*dl_allocate_tib)(size_t);
237: void (*dl_free_tib)(void *, size_t);
238: void (*dl_clean_boot)(void);
239: void *(*dlopen)(const char *, int);
240: int (*dlclose)(void *);
241: void *(*dlsym)(void *, const char *);
242: int (*dladdr)(const void *, struct dl_info *);
243: int (*dlctl)(void *, int, void *);
244: char *(*dlerror)(void);
245: int (*dl_iterate_phdr)(int (*)(struct dl_phdr_info *,
246: size_t, void *), void *);
247: };
248:
249: #define DL_CB_CUR 0
250: typedef struct dl_cb_0 dl_cb;
251:
252: /* type of function passed to init functions that returns a dl_cb */
253: typedef const void *dl_cb_cb(int _version);
254:
1.2 guenther 255: void *_dl_allocate_tib(size_t _extra) __dso_public;
1.1 guenther 256: void _dl_free_tib(void *_tib, size_t _extra) __dso_public;
257:
258: /* The actual syscalls */
259: void *__get_tcb(void);
260: void __set_tcb(void *_tcb);
261: __END_DECLS
262:
263: #endif /* _TIB_H_ */