RTEMS
tls.h
Go to the documentation of this file.
1 
9 /*
10  * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
11  *
12  * embedded brains GmbH
13  * Dornierstr. 4
14  * 82178 Puchheim
15  * Germany
16  * <rtems@embedded-brains.de>
17  *
18  * The license and distribution terms for this file may be
19  * found in the file LICENSE in this distribution or at
20  * http://www.rtems.org/license/LICENSE.
21  */
22 
23 #ifndef _RTEMS_SCORE_TLS_H
24 #define _RTEMS_SCORE_TLS_H
25 
26 #include <rtems/score/cpu.h>
27 
28 #include <string.h>
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif /* __cplusplus */
33 
47 extern char _TLS_Data_begin[];
48 
49 extern char _TLS_Data_end[];
50 
51 extern char _TLS_Data_size[];
52 
53 extern char _TLS_BSS_begin[];
54 
55 extern char _TLS_BSS_end[];
56 
57 extern char _TLS_BSS_size[];
58 
59 extern char _TLS_Size[];
60 
71 extern char _TLS_Alignment[];
72 
73 typedef struct {
74  /*
75  * FIXME: Not sure if the generation number type is correct for all
76  * architectures.
77  */
78  uint32_t generation_number;
79 
80  void *tls_blocks[1];
82 
83 typedef struct TLS_Thread_control_block {
84 #ifdef __i386__
85  struct TLS_Thread_control_block *tcb;
86 #else /* !__i386__ */
88 /*
89  * GCC under AArch64/LP64 expects a 16 byte TCB at the beginning of the TLS
90  * data segment and indexes into it accordingly for TLS variable addresses.
91  */
92 #if CPU_SIZEOF_POINTER == 4 || defined(AARCH64_MULTILIB_ARCH_V8)
93  uintptr_t reserved;
94 #endif
95 #endif /* __i386__ */
97 
98 typedef struct {
99  uintptr_t module;
100  uintptr_t offset;
101 } TLS_Index;
102 
108 static inline uintptr_t _TLS_Get_size( void )
109 {
110  uintptr_t size;
111 
112  /*
113  * We must be careful with using _TLS_Size here since this could lead GCC to
114  * assume that this symbol is not 0 and the tests for 0 will be optimized
115  * away.
116  */
117  size = (uintptr_t) _TLS_Size;
118  RTEMS_OBFUSCATE_VARIABLE( size );
119  return size;
120 }
121 
129 static inline uintptr_t _TLS_Heap_align_up( uintptr_t val )
130 {
131  uintptr_t msk = CPU_HEAP_ALIGNMENT - 1;
132 
133  return (val + msk) & ~msk;
134 }
135 
145  uintptr_t alignment
146 )
147 {
148  return alignment <= sizeof(TLS_Thread_control_block) ?
149  sizeof(TLS_Thread_control_block) : alignment;
150 }
151 
157 uintptr_t _TLS_Get_allocation_size( void );
158 
167 static inline void *_TLS_Copy_and_clear( void *tls_area )
168 {
169  tls_area = memcpy(
170  tls_area,
171  _TLS_Data_begin,
172  (size_t) ((uintptr_t)_TLS_Data_size)
173  );
174 
175 
176  memset(
177  (char *) tls_area + (size_t)((intptr_t) _TLS_BSS_begin) -
178  (size_t)((intptr_t) _TLS_Data_begin),
179  0,
180  ((size_t) (intptr_t)_TLS_BSS_size)
181  );
182 
183  return tls_area;
184 }
185 
196 static inline void *_TLS_Initialize(
197  void *tls_block,
200 )
201 {
202 #ifdef __i386__
203  (void) dtv;
204  tcb->tcb = tcb;
205 #else
206  tcb->dtv = dtv;
207  dtv->generation_number = 1;
208  dtv->tls_blocks[0] = tls_block;
209 #endif
210 
211  return _TLS_Copy_and_clear( tls_block );
212 }
213 
225 static inline void *_TLS_TCB_at_area_begin_initialize( void *tls_area )
226 {
227  void *tls_block = (char *) tls_area
229  TLS_Thread_control_block *tcb = tls_area;
230  uintptr_t aligned_size = _TLS_Heap_align_up( (uintptr_t) _TLS_Size );
232  ((char *) tls_block + aligned_size);
233 
234  return _TLS_Initialize( tls_block, tcb, dtv );
235 }
236 
248 static inline void *_TLS_TCB_before_TLS_block_initialize( void *tls_area )
249 {
250  void *tls_block = (char *) tls_area
253  ((char *) tls_block - sizeof(*tcb));
254  uintptr_t aligned_size = _TLS_Heap_align_up( (uintptr_t) _TLS_Size );
256  ((char *) tls_block + aligned_size);
257 
258  return _TLS_Initialize( tls_block, tcb, dtv );
259 }
260 
272 static inline void *_TLS_TCB_after_TLS_block_initialize( void *tls_area )
273 {
274  uintptr_t size = (uintptr_t) _TLS_Size;
275  uintptr_t tls_align = (uintptr_t) _TLS_Alignment;
276  uintptr_t tls_mask = tls_align - 1;
277  uintptr_t heap_align = _TLS_Heap_align_up( tls_align );
278  uintptr_t heap_mask = heap_align - 1;
280  ((char *) tls_area + ((size + heap_mask) & ~heap_mask));
281  void *tls_block = (char *) tcb - ((size + tls_mask) & ~tls_mask);
283  ((char *) tcb + sizeof(*tcb));
284 
285  _TLS_Initialize( tls_block, tcb, dtv );
286 
287  return tcb;
288 }
289 
292 #ifdef __cplusplus
293 }
294 #endif /* __cplusplus */
295 
296 #endif /* _RTEMS_SCORE_TLS_H */
static void * _TLS_Initialize(void *tls_block, TLS_Thread_control_block *tcb, TLS_Dynamic_thread_vector *dtv)
Initializes the dynamic thread vector.
Definition: tls.h:196
uintptr_t _TLS_Get_allocation_size(void)
Return the TLS area allocation size.
Definition: tlsallocsize.c:38
char _TLS_Alignment[]
The TLS section alignment.
Definition: tls.h:98
static uintptr_t _TLS_Get_size(void)
Gets the TLS size.
Definition: tls.h:108
static void * _TLS_TCB_before_TLS_block_initialize(void *tls_area)
Initializes a dynamic thread vector with the area before a given starting address as thread control b...
Definition: tls.h:248
SPARC CPU Department Source.
#define CPU_HEAP_ALIGNMENT
Definition: cpu.h:755
static void * _TLS_TCB_at_area_begin_initialize(void *tls_area)
Initializes a dynamic thread vector beginning at the given starting address.
Definition: tls.h:225
#define RTEMS_OBFUSCATE_VARIABLE(_var)
Obfuscates the variable so that the compiler cannot perform optimizations based on the variable value...
Definition: basedefs.h:729
static uintptr_t _TLS_Heap_align_up(uintptr_t val)
Returns the value aligned up to the heap alignment.
Definition: tls.h:129
static void * _TLS_TCB_after_TLS_block_initialize(void *tls_area)
Initializes a dynamic thread vector with the area after a given starting address as thread control bl...
Definition: tls.h:272
static void * _TLS_Copy_and_clear(void *tls_area)
Copies TLS size bytes from the address tls_area and returns a pointer to the start of the area after ...
Definition: tls.h:167
static uintptr_t _TLS_Get_thread_control_block_area_size(uintptr_t alignment)
Returns the size of the thread control block area size for this alignment, or the minimum size if ali...
Definition: tls.h:144