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