1 /*=============================================================================
2 init.c : tinycrt initialization (tiny crt)
4 DO NOT use ltcg optimizations in this file under penalty of death
6 =============================================================================*/
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)
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 ///////////////////////////////////////////////////////////////////////////////
43 #pragma data_seg(".tls")
44 #if defined (_M_IA64) || defined (_M_AMD64)
50 #pragma data_seg(".tls$ZZZ")
51 #if defined (_M_IA64) || defined (_M_AMD64)
59 _CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a
= 0;
60 _CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z
= 0;
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
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
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
{
92 struct TlsDtorNode
*next
;
93 _PVFV funcs
[FUNCS_PER_NODE
];
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
)
106 if (reason
!= DLL_THREAD_ATTACH
) {
110 #pragma warning(push)
111 #pragma warning(disable:26000)
112 for(pfunc
= &__xd_a
+ 1; pfunc
!= &__xd_z
; ++pfunc
) {
113 if (*pfunc
!= NULL
) {
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
));
133 pnode
->next
= dtor_list
;
135 dtor_list
->count
= 0;
137 dtor_list
->funcs
[dtor_list
->count
++] = func
;
141 static BOOL WINAPI
__dyn_tls_dtor(HANDLE handle
, DWORD reason
, LPVOID reserved
)
143 TlsDtorNode
*pnode
, *pnext
;
146 if (reason
!= DLL_THREAD_DETACH
&& reason
!= DLL_PROCESS_DETACH
) {
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
])();
165 static void __atexit(void)
167 atexit_entry
* next
= g_atexit_list
;
169 while (next
!= NULL
) {
173 if (g_tcrt_sigaction_slot
[SIGTERM
].sa_handler
!= SIG_DFL
)
174 g_tcrt_sigaction_slot
[SIGTERM
].sa_handler(SIGTERM
);
177 ///////////////////////////////////////////////////////////////////////////////
184 __dyn_tls_init(NULL
, DLL_THREAD_ATTACH
, NULL
);
185 for(ii
= __xi_a
; ii
< __xi_z
; ii
++) {
194 for(ic
= __xc_a
; ic
< __xc_z
; ic
++) {
206 for(ip
= __xp_a
; ip
< __xp_z
; ip
++) {
212 for(it
= __xt_a
; it
< __xt_z
; it
++) {
221 // EOF ////////////////////////////////////////////////////////////////////////