xref: /dflybsd-src/sys/cpu/x86_64/include/tls.h (revision 4c898ae594e26f4901a584d0cfe471cb018bea11)
1b2b3ffcdSSimon Schubert /*
2*4c898ae5SMatthew Dillon  * Copyright (c) 2005,2008,2020 The DragonFly Project.  All rights reserved.
3b2b3ffcdSSimon Schubert  *
4b2b3ffcdSSimon Schubert  * Redistribution and use in source and binary forms, with or without
5b2b3ffcdSSimon Schubert  * modification, are permitted provided that the following conditions
6b2b3ffcdSSimon Schubert  * are met:
7b2b3ffcdSSimon Schubert  *
8b2b3ffcdSSimon Schubert  * 1. Redistributions of source code must retain the above copyright
9b2b3ffcdSSimon Schubert  *    notice, this list of conditions and the following disclaimer.
10b2b3ffcdSSimon Schubert  * 2. Redistributions in binary form must reproduce the above copyright
11b2b3ffcdSSimon Schubert  *    notice, this list of conditions and the following disclaimer in
12b2b3ffcdSSimon Schubert  *    the documentation and/or other materials provided with the
13b2b3ffcdSSimon Schubert  *    distribution.
14b2b3ffcdSSimon Schubert  * 3. Neither the name of The DragonFly Project nor the names of its
15b2b3ffcdSSimon Schubert  *    contributors may be used to endorse or promote products derived
16b2b3ffcdSSimon Schubert  *    from this software without specific, prior written permission.
17b2b3ffcdSSimon Schubert  *
18b2b3ffcdSSimon Schubert  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19b2b3ffcdSSimon Schubert  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20b2b3ffcdSSimon Schubert  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21b2b3ffcdSSimon Schubert  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
22b2b3ffcdSSimon Schubert  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23b2b3ffcdSSimon Schubert  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24b2b3ffcdSSimon Schubert  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25b2b3ffcdSSimon Schubert  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26b2b3ffcdSSimon Schubert  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27b2b3ffcdSSimon Schubert  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28b2b3ffcdSSimon Schubert  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29b2b3ffcdSSimon Schubert  * SUCH DAMAGE.
30b2b3ffcdSSimon Schubert  */
31b2b3ffcdSSimon Schubert 
32b2b3ffcdSSimon Schubert #ifndef	_CPU_TLS_H_
33b2b3ffcdSSimon Schubert #define	_CPU_TLS_H_
34b2b3ffcdSSimon Schubert 
35b2b3ffcdSSimon Schubert #ifndef _SYS_TYPES_H_
36b2b3ffcdSSimon Schubert #include <sys/types.h>
37b2b3ffcdSSimon Schubert #endif
38b2b3ffcdSSimon Schubert #ifndef _SYS_TLS_H_
39b2b3ffcdSSimon Schubert #include <sys/tls.h>
40b2b3ffcdSSimon Schubert #endif
41b2b3ffcdSSimon Schubert 
42b2b3ffcdSSimon Schubert /*
43b2b3ffcdSSimon Schubert  * NOTE: the tcb_{self,dtv,pthread,errno) fields must be declared
44b2b3ffcdSSimon Schubert  * in the structure in the specified order as assembly will access the
45b2b3ffcdSSimon Schubert  * fields with a hardwired offset.
46b2b3ffcdSSimon Schubert  *
47b2b3ffcdSSimon Schubert  * Outside of this file, the system call layer generation will hardwire
48b2b3ffcdSSimon Schubert  * the offset for tcb_errno.
49b2b3ffcdSSimon Schubert  */
50b2b3ffcdSSimon Schubert struct tls_tcb {
51b2b3ffcdSSimon Schubert 	struct tls_tcb *tcb_self;	/* pointer to self*/
52b2b3ffcdSSimon Schubert 	void *tcb_dtv;			/* Dynamic Thread Vector */
53b2b3ffcdSSimon Schubert 	void *tcb_pthread;		/* thread library's data*/
54b2b3ffcdSSimon Schubert 	int *tcb_errno_p;		/* pointer to per-thread errno */
55166bae11SMichael Neumann 	void *tcb_segstack;		/* used for segmented stacks */
56166bae11SMichael Neumann 					/* e.g. by LLVM to store stack bound */
57e900a7a2SMichael Neumann 					/* NOTE: do not reorder this field */
58e900a7a2SMichael Neumann 					/* as LLVM uses a fixed offset (32) */
59166bae11SMichael Neumann 	void *tcb_unused[3];
60b2b3ffcdSSimon Schubert };
61b2b3ffcdSSimon Schubert 
62b2b3ffcdSSimon Schubert struct tls_dtv {
63b2b3ffcdSSimon Schubert 	uintptr_t dtv_generation;
64b2b3ffcdSSimon Schubert 	uintptr_t dtv_max_index;
65b2b3ffcdSSimon Schubert 	void *dtv_offset[__ARRAY_ZERO];
66b2b3ffcdSSimon Schubert };
67b2b3ffcdSSimon Schubert 
68e4f37b93SMatthew Dillon /*
69e4f37b93SMatthew Dillon  * NOTE: RTLD_STATIC_TLS_EXTRA_DEFAULT is set as the kernel's kern.tls_extra
70e4f37b93SMatthew Dillon  *	 default, generally made large enough to accomodate modern libraries
71e4f37b93SMatthew Dillon  *	 that desire to use static TLS sections.  Make it roughly 2048 bytes
72e4f37b93SMatthew Dillon  *	 smaller than a multiple of an aligned page for allocation efficiency.
73e4f37b93SMatthew Dillon  */
74b2b3ffcdSSimon Schubert #define	RTLD_TCB_HAS_SELF_POINTER
75b2b3ffcdSSimon Schubert #define	RTLD_STATIC_TLS_ALIGN           16
76b2b3ffcdSSimon Schubert #define	RTLD_STATIC_TLS_ALIGN_MASK      (RTLD_STATIC_TLS_ALIGN - 1)
77e4f37b93SMatthew Dillon #define RTLD_STATIC_TLS_EXTRA_MIN	2048
78e4f37b93SMatthew Dillon #define RTLD_STATIC_TLS_EXTRA_MAX	(1*1024*1024*1024)
79e4f37b93SMatthew Dillon #define RTLD_STATIC_TLS_EXTRA_DEFAULT	6144	/* sysctl kern.tls_extra */
80b2b3ffcdSSimon Schubert #define RTLD_STATIC_TLS_VARIANT_II
81b2b3ffcdSSimon Schubert 
82b2b3ffcdSSimon Schubert /* Get the current TCB. */
83b2b3ffcdSSimon Schubert static __inline struct tls_tcb *
tls_get_tcb(void)84b2b3ffcdSSimon Schubert tls_get_tcb(void)
85b2b3ffcdSSimon Schubert {
86b2b3ffcdSSimon Schubert 	void *self;
87b2b3ffcdSSimon Schubert 
88b2b3ffcdSSimon Schubert 	__asm __volatile ("movq %%fs:%1, %0"
89b2b3ffcdSSimon Schubert 	    : "=r" (self)
90b2b3ffcdSSimon Schubert 	    : "m" (((struct tls_tcb *)0)->tcb_self));
91b2b3ffcdSSimon Schubert 
92b2b3ffcdSSimon Schubert 	return(self);
93b2b3ffcdSSimon Schubert }
94b2b3ffcdSSimon Schubert 
95b2b3ffcdSSimon Schubert /* Get the current thread. */
96b2b3ffcdSSimon Schubert static __inline void *
tls_get_curthread(void)97b2b3ffcdSSimon Schubert tls_get_curthread(void)
98b2b3ffcdSSimon Schubert {
99b2b3ffcdSSimon Schubert 	void *self;
100b2b3ffcdSSimon Schubert 
101b2b3ffcdSSimon Schubert 	__asm __volatile ("movq %%fs:%1, %0"
102b2b3ffcdSSimon Schubert 	    : "=r" (self)
103b2b3ffcdSSimon Schubert 	    : "m" (((struct tls_tcb *)0)->tcb_pthread));
104b2b3ffcdSSimon Schubert 
105b2b3ffcdSSimon Schubert 	return(self);
106b2b3ffcdSSimon Schubert }
107b2b3ffcdSSimon Schubert 
108b2b3ffcdSSimon Schubert static __inline void
tls_set_tcb(struct tls_tcb * tcb)109b2b3ffcdSSimon Schubert tls_set_tcb(struct tls_tcb *tcb)
110b2b3ffcdSSimon Schubert {
111b2b3ffcdSSimon Schubert 	struct tls_info info;
112b2b3ffcdSSimon Schubert 	int seg;
113b2b3ffcdSSimon Schubert 
114b2b3ffcdSSimon Schubert 	info.base = tcb;
115b2b3ffcdSSimon Schubert 	info.size = -1;
116b2b3ffcdSSimon Schubert 	seg = set_tls_area(0, &info, sizeof(info));
117b2b3ffcdSSimon Schubert 	/*__asm __volatile("movl %0, %%fs" : : "r" (seg));*/
118b2b3ffcdSSimon Schubert }
119b2b3ffcdSSimon Schubert 
120a293ac08SJordan Gordeev static __inline void
tls_set_gs(void * base,size_t bytes)121a293ac08SJordan Gordeev tls_set_gs(void *base, size_t bytes)
122a293ac08SJordan Gordeev {
123a293ac08SJordan Gordeev 	struct tls_info info;
124a293ac08SJordan Gordeev 	int seg;
125a293ac08SJordan Gordeev 
126a293ac08SJordan Gordeev 	info.base = base;
127a293ac08SJordan Gordeev 	info.size = bytes;
128a293ac08SJordan Gordeev 	seg = set_tls_area(1, &info, sizeof(info));
129a293ac08SJordan Gordeev 	/*__asm __volatile("mov %0, %%fs" : : "g" (seg));*/
130a293ac08SJordan Gordeev }
131a293ac08SJordan Gordeev 
132a293ac08SJordan Gordeev #ifndef _KERNEL
133a293ac08SJordan Gordeev 
134b2b3ffcdSSimon Schubert struct tls_tcb	*_rtld_allocate_tls(void);
135b2b3ffcdSSimon Schubert struct tls_tcb	*_libc_allocate_tls(void);
136b2b3ffcdSSimon Schubert void		 _rtld_free_tls(struct tls_tcb *);
137b2b3ffcdSSimon Schubert void		 _libc_free_tls(struct tls_tcb *);
138b2b3ffcdSSimon Schubert void		 _rtld_call_init(void);
139b2b3ffcdSSimon Schubert struct tls_tcb	*_libc_init_tls(void);
140b2b3ffcdSSimon Schubert struct tls_tcb	*_init_tls(void);
141b2b3ffcdSSimon Schubert 
142b2b3ffcdSSimon Schubert #endif
143b2b3ffcdSSimon Schubert 
144b2b3ffcdSSimon Schubert #endif	/* !_CPU_TLS_H_ */
145