2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the w64 mingw-runtime package.
4 * No warranty is given; refer to the file DISCLAIMER within this package.
12 #include <sect_attribs.h>
17 extern BOOL
__mingw_TLScallback (HANDLE hDllHandle
, DWORD reason
, LPVOID reserved
);
19 #define FUNCS_PER_NODE 30
21 typedef struct TlsDtorNode
{
23 struct TlsDtorNode
*next
;
24 _PVFV funcs
[FUNCS_PER_NODE
];
29 /* TLS raw template data start and end. */
30 _CRTALLOC(".tls$AAA") char _tls_start
= 0;
31 _CRTALLOC(".tls$ZZZ") char _tls_end
= 0;
33 _CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a
= 0;
34 _CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z
= 0;
37 _CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY64 _tls_used
= {
38 (ULONGLONG
) &_tls_start
+1, (ULONGLONG
) &_tls_end
, (ULONGLONG
) &_tls_index
,
39 (ULONGLONG
) (&__xl_a
+1), (ULONG
) 0, (ULONG
) 0
42 _CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY _tls_used
= {
43 (ULONG
)(ULONG_PTR
) &_tls_start
+1, (ULONG
)(ULONG_PTR
) &_tls_end
,
44 (ULONG
)(ULONG_PTR
) &_tls_index
, (ULONG
)(ULONG_PTR
) (&__xl_a
+1),
50 #ifdef HAVE_ATTRIBUTE_THREAD
51 #define __CRT_THREAD __declspec(thread)
53 #define __CRT_THREAD __thread
57 #define DISABLE_MS_TLS 1
59 static _CRTALLOC(".CRT$XDA") _PVFV __xd_a
= 0;
60 static _CRTALLOC(".CRT$XDZ") _PVFV __xd_z
= 0;
62 #if !defined (DISABLE_MS_TLS)
63 static __CRT_THREAD TlsDtorNode
*dtor_list
;
64 static __CRT_THREAD TlsDtorNode dtor_list_head
;
69 BOOL WINAPI
__dyn_tls_init (HANDLE
, DWORD
, LPVOID
);
72 __dyn_tls_init (HANDLE hDllHandle
, DWORD dwReason
, LPVOID lpreserved
)
76 /* We don't let us trick here. */
80 if (dwReason
!= DLL_THREAD_ATTACH
)
82 if (dwReason
== DLL_PROCESS_ATTACH
)
83 __mingw_TLScallback (hDllHandle
, dwReason
, lpreserved
);
87 for (pfunc
= &__xd_a
+ 1; pfunc
!= &__xd_z
; ++pfunc
)
95 const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback
= (const PIMAGE_TLS_CALLBACK
) __dyn_tls_init
;
96 _CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c
= (PIMAGE_TLS_CALLBACK
) __dyn_tls_init
;
98 int __cdecl
__tlregdtor (_PVFV
);
101 __tlregdtor (_PVFV func
)
105 #if !defined (DISABLE_MS_TLS)
106 if (dtor_list
== NULL
)
108 dtor_list
= &dtor_list_head
;
109 dtor_list_head
.count
= 0;
111 else if (dtor_list
->count
== FUNCS_PER_NODE
)
113 TlsDtorNode
*pnode
= (TlsDtorNode
*) malloc (sizeof (TlsDtorNode
));
117 pnode
->next
= dtor_list
;
120 dtor_list
->count
= 0;
122 dtor_list
->funcs
[dtor_list
->count
++] = func
;
128 __dyn_tls_dtor (HANDLE hDllHandle
, DWORD dwReason
, LPVOID lpreserved
)
130 #if !defined (DISABLE_MS_TLS)
131 TlsDtorNode
*pnode
, *pnext
;
135 if (dwReason
!= DLL_THREAD_DETACH
&& dwReason
!= DLL_PROCESS_DETACH
)
137 /* As TLS variables are detroyed already by DLL_THREAD_DETACH
138 call, we have to avoid access on the possible DLL_PROCESS_DETACH
139 call the already destroyed TLS vars.
140 TODO: The used local thread based variables have to be handled
141 manually, so that we can control their lifetime here. */
142 #if !defined (DISABLE_MS_TLS)
143 if (dwReason
!= DLL_PROCESS_DETACH
)
145 for (pnode
= dtor_list
; pnode
!= NULL
; pnode
= pnext
)
147 for (i
= pnode
->count
- 1; i
>= 0; --i
)
149 if (pnode
->funcs
[i
] != NULL
)
150 (*pnode
->funcs
[i
])();
154 free ((void *) pnode
);
158 __mingw_TLScallback (hDllHandle
, dwReason
, lpreserved
);
162 _CRTALLOC(".CRT$XLD") PIMAGE_TLS_CALLBACK __xl_d
= (PIMAGE_TLS_CALLBACK
) __dyn_tls_dtor
;
165 int mingw_initltsdrot_force
= 0;
166 int mingw_initltsdyn_force
=0;
167 int mingw_initltssuo_force
= 0;