[DDK]: Merge 46183 from header-branch.
[reactos.git] / reactos / lib / 3rdparty / mingw / tlssup.c
1 /**
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.
5 */
6
7 #ifdef CRTDLL
8 #undef CRTDLL
9 #endif
10
11 #include <internal.h>
12 #include <sect_attribs.h>
13 #include <windows.h>
14 #include <malloc.h>
15 #include <crtdbg.h>
16
17 #define FUNCS_PER_NODE 30
18
19 typedef struct TlsDtorNode {
20 int count;
21 struct TlsDtorNode *next;
22 _PVFV funcs[FUNCS_PER_NODE];
23 } TlsDtorNode;
24
25 ULONG _tls_index = 0;
26
27 _CRTALLOC(".tls") char _tls_start = 0;
28 _CRTALLOC(".tls$ZZZ") char _tls_end = 0;
29
30 _CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0;
31 _CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0;
32
33 #ifdef _WIN64
34 _CRTALLOC(".rdata$T") const IMAGE_TLS_DIRECTORY64 _tls_used = {
35 (ULONGLONG) &_tls_start, (ULONGLONG) &_tls_end, (ULONGLONG) &_tls_index,
36 (ULONGLONG) (&__xl_a+1), (ULONG) 0, (ULONG) 0
37 };
38 #else
39 _CRTALLOC(".rdata$T") const IMAGE_TLS_DIRECTORY _tls_used = {
40 (ULONG)(ULONG_PTR) &_tls_start, (ULONG)(ULONG_PTR) &_tls_end,
41 (ULONG)(ULONG_PTR) &_tls_index, (ULONG)(ULONG_PTR) (&__xl_a+1),
42 (ULONG) 0, (ULONG) 0
43 };
44 #endif
45
46 #ifndef __CRT_THREAD
47 #ifdef HAVE_ATTRIBUTE_THREAD
48 #define __CRT_THREAD __declspec(thread)
49 #else
50 #define __CRT_THREAD
51 #endif
52 #endif
53
54 static _CRTALLOC(".CRT$XDA") _PVFV __xd_a = 0;
55 static _CRTALLOC(".CRT$XDZ") _PVFV __xd_z = 0;
56 static __CRT_THREAD TlsDtorNode *dtor_list;
57 static __CRT_THREAD TlsDtorNode dtor_list_head;
58
59 BOOL WINAPI
60 __dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
61 {
62 _PVFV *pfunc;
63
64 if (dwReason != DLL_THREAD_ATTACH)
65 return TRUE;
66
67 for (pfunc = &__xd_a + 1; pfunc != &__xd_z; ++pfunc)
68 {
69 if (*pfunc != NULL)
70 (*pfunc)();
71 }
72
73 return TRUE;
74 }
75
76 const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback = (const PIMAGE_TLS_CALLBACK) __dyn_tls_init;
77 _CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c = (PIMAGE_TLS_CALLBACK) __dyn_tls_init;
78
79 int __cdecl
80 __tlregdtor (_PVFV func)
81 {
82 if (dtor_list == NULL)
83 {
84 dtor_list = &dtor_list_head;
85 dtor_list_head.count = 0;
86 }
87 else if (dtor_list->count == FUNCS_PER_NODE)
88 {
89 TlsDtorNode *pnode = (TlsDtorNode *) malloc (sizeof (TlsDtorNode));
90 if (pnode == NULL)
91 return -1;
92 pnode->count = 0;
93 pnode->next = dtor_list;
94 dtor_list = pnode;
95
96 dtor_list->count = 0;
97 }
98 dtor_list->funcs[dtor_list->count++] = func;
99 return 0;
100 }
101
102 static BOOL WINAPI
103 __dyn_tls_dtor (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
104 {
105 TlsDtorNode *pnode, *pnext;
106 int i;
107
108 if (dwReason != DLL_THREAD_DETACH && dwReason != DLL_PROCESS_DETACH)
109 return TRUE;
110
111 for (pnode = dtor_list; pnode != NULL; pnode = pnext)
112 {
113 for (i = pnode->count - 1; i >= 0; --i)
114 {
115 if (pnode->funcs[i] != NULL)
116 (*pnode->funcs[i])();
117 }
118 pnext = pnode->next;
119 if (pnext != NULL)
120 free ((void *) pnode);
121 }
122 return TRUE;
123 }
124
125 _CRTALLOC(".CRT$XLD") PIMAGE_TLS_CALLBACK __xl_d = (PIMAGE_TLS_CALLBACK) __dyn_tls_dtor;
126
127
128 int mingw_initltsdrot_force = 0;
129 int mingw_initltsdyn_force=0;
130 int mingw_initltssuo_force = 0;