Initial commit of visual studio 9 git build superproject.
[git-build-vc9.git] / tcrt / src / init.c
blob324590c03dc5be7489a7f2f430c2700daf44ba6e
1 /*=============================================================================
2 init.c : tinycrt initialization (tiny crt)
4 DO NOT use ltcg optimizations in this file under penalty of death
5 by TLS corruption.
6 =============================================================================*/
8 #include <signal.h>
9 #include <windows.h>
10 #include "init.h"
12 ///////////////////////////////////////////////////////////////////////////////
13 #pragma comment(linker, "/merge:.CRT=.rdata")
14 #pragma comment(linker, "/defaultlib:kernel32.lib")
15 #pragma comment(linker, "/disallowlib:libc.lib")
16 #pragma comment(linker, "/disallowlib:libcd.lib")
17 #pragma comment(linker, "/disallowlib:libcmt.lib")
18 #pragma comment(linker, "/disallowlib:libcmtd.lib")
19 #pragma comment(linker, "/disallowlib:msvcrt.lib")
20 #pragma comment(linker, "/disallowlib:msvcrtd.lib")
22 #if defined (_WIN64) && defined (_M_IA64)
23 # pragma section(".base", long, read)
24 _CRTALLOC(".base")
25 #endif
27 _CRTALLOC(".CRT$XIA") _PIFV __xi_a[] = { NULL };
28 _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[] = { NULL };
29 _CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = { NULL };
30 _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[] = { NULL };
31 _CRTALLOC(".CRT$XPA") _PVFV __xp_a[] = { NULL };
32 _CRTALLOC(".CRT$XPZ") _PVFV __xp_z[] = { NULL };
33 _CRTALLOC(".CRT$XTA") _PVFV __xt_a[] = { NULL };
34 _CRTALLOC(".CRT$XTZ") _PVFV __xt_z[] = { NULL };
36 ///////////////////////////////////////////////////////////////////////////////
37 static BOOL WINAPI __dyn_tls_dtor(HANDLE handle, DWORD reason, LPVOID reserved);
38 static BOOL WINAPI __dyn_tls_init(HANDLE handle, DWORD reason, LPVOID reserved);
40 ///////////////////////////////////////////////////////////////////////////////
41 ULONG _tls_index = 0;
43 #pragma data_seg(".tls")
44 #if defined (_M_IA64) || defined (_M_AMD64)
45 _CRTALLOC(".tls")
46 #endif
48 char _tls_start = 0;
50 #pragma data_seg(".tls$ZZZ")
51 #if defined (_M_IA64) || defined (_M_AMD64)
52 _CRTALLOC(".tls$ZZZ")
53 #endif
55 char _tls_end = 0;
57 #pragma data_seg()
59 _CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0;
60 _CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0;
62 #ifdef _WIN64
63 _CRTALLOC(".rdata$T") const IMAGE_TLS_DIRECTORY64 _tls_used = {
64 (ULONGLONG) &_tls_start, // start of tls data
65 (ULONGLONG) &_tls_end, // end of tls data
66 (ULONGLONG) &_tls_index, // address of tls_index
67 (ULONGLONG) (&__xl_a+1), // pointer to call back array
68 (ULONG) 0, // size of tls zero fill
69 (ULONG) 0 // characteristics
71 #else
72 _CRTALLOC(".rdata$T") const IMAGE_TLS_DIRECTORY _tls_used = {
73 (ULONG)(ULONG_PTR) &_tls_start, // start of tls data
74 (ULONG)(ULONG_PTR) &_tls_end, // end of tls data
75 (ULONG)(ULONG_PTR) &_tls_index, // address of tls_index
76 (ULONG)(ULONG_PTR) (&__xl_a+1), // pointer to call back array
77 (ULONG) 0, // size of tls zero fill
78 (ULONG) 0 // characteristics
80 #endif
82 static _CRTALLOC(".CRT$XDA") _PVFV __xd_a = 0;
83 static _CRTALLOC(".CRT$XDZ") _PVFV __xd_z = 0;
85 static _CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c = __dyn_tls_init;
86 static _CRTALLOC(".CRT$XLD") PIMAGE_TLS_CALLBACK __xl_d = __dyn_tls_dtor;
88 #define FUNCS_PER_NODE 30
90 typedef struct TlsDtorNode {
91 int count;
92 struct TlsDtorNode *next;
93 _PVFV funcs[FUNCS_PER_NODE];
94 } TlsDtorNode;
96 static __declspec(thread) TlsDtorNode* dtor_list;
97 static __declspec(thread) TlsDtorNode dtor_list_head;
99 atexit_entry* g_atexit_list;
101 ///////////////////////////////////////////////////////////////////////////////
102 static BOOL WINAPI __dyn_tls_init(HANDLE handle, DWORD reason, LPVOID reserved)
104 _PVFV *pfunc;
106 if (reason != DLL_THREAD_ATTACH) {
107 return TRUE;
110 #pragma warning(push)
111 #pragma warning(disable:26000)
112 for(pfunc = &__xd_a + 1; pfunc != &__xd_z; ++pfunc) {
113 if (*pfunc != NULL) {
114 (*pfunc)();
117 #pragma warning(pop)
119 return TRUE;
122 int __cdecl __tlregdtor(_PVFV func)
124 if (dtor_list == NULL) {
125 dtor_list = &dtor_list_head;
126 dtor_list_head.count = 0;
128 else if (dtor_list->count == FUNCS_PER_NODE) {
129 TlsDtorNode* pnode = (TlsDtorNode*) malloc(sizeof(TlsDtorNode));
130 if (pnode == NULL)
131 return -1;
132 pnode->count = 0;
133 pnode->next = dtor_list;
134 dtor_list = pnode;
135 dtor_list->count = 0;
137 dtor_list->funcs[dtor_list->count++] = func;
138 return 0;
141 static BOOL WINAPI __dyn_tls_dtor(HANDLE handle, DWORD reason, LPVOID reserved)
143 TlsDtorNode *pnode, *pnext;
144 int i;
146 if (reason != DLL_THREAD_DETACH && reason != DLL_PROCESS_DETACH) {
147 return TRUE;
150 for (pnode = dtor_list; pnode != NULL; pnode = pnext) {
151 for (i = pnode->count - 1; i >= 0; --i) {
152 if (pnode->funcs[i] != NULL) {
153 (*pnode->funcs[i])();
156 pnext = pnode->next;
157 if (pnext != NULL) {
158 free(pnode);
162 return TRUE;
165 static void __atexit(void)
167 atexit_entry* next = g_atexit_list;
169 while (next != NULL) {
170 next->fn();
171 next = next->next;
173 if (g_tcrt_sigaction_slot[SIGTERM].sa_handler != SIG_DFL)
174 g_tcrt_sigaction_slot[SIGTERM].sa_handler(SIGTERM);
177 ///////////////////////////////////////////////////////////////////////////////
178 void run_ctors(void)
180 _PIFV* ii;
181 _PVFV* ic;
182 int ret;
184 __dyn_tls_init(NULL, DLL_THREAD_ATTACH, NULL);
185 for(ii = __xi_a; ii < __xi_z; ii++) {
186 if( *ii != NULL ) {
187 ret = (**ii)();
188 if( ret != 0 ) {
189 ExitProcess(ret);
194 for(ic = __xc_a; ic < __xc_z; ic++) {
195 if( *ic != NULL ) {
196 (**ic)();
201 void run_dtors(void)
203 _PVFV* ip;
204 _PVFV* it;
206 for(ip = __xp_a; ip < __xp_z; ip++) {
207 if( *ip != NULL ) {
208 (**ip)();
212 for(it = __xt_a; it < __xt_z; it++) {
213 if( *it != NULL ) {
214 (**it)();
218 __atexit();
221 // EOF ////////////////////////////////////////////////////////////////////////