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.PD within this package. 5 */ 6 7 #ifdef CRTDLL 8 #undef CRTDLL 9 #ifndef _DLL 10 #define _DLL 11 #endif 12 13 #include <oscalls.h> 14 #include <internal.h> 15 #include <stdlib.h> 16 //#include <windows.h> 17 #define _DECL_DLLMAIN 18 #include <process.h> 19 #include <crtdbg.h> 20 21 #ifndef _CRTIMP 22 #ifdef CRTDLL 23 #define _CRTIMP __declspec(dllexport) 24 #else 25 #ifdef _DLL 26 #define _CRTIMP __declspec(dllimport) 27 #else 28 #define _CRTIMP 29 #endif 30 #endif 31 #endif 32 #include <sect_attribs.h> 33 #include <locale.h> 34 35 extern void __cdecl _initterm(_PVFV *,_PVFV *); 36 extern void __main (); 37 extern void _pei386_runtime_relocator (void); 38 extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a[]; 39 extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[]; 40 extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[]; 41 extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[]; 42 43 /* TLS initialization hook. */ 44 extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback; 45 46 static int __proc_attached = 0; 47 48 extern _PVFV *__onexitbegin; 49 extern _PVFV *__onexitend; 50 51 extern int mingw_app_type; 52 53 extern WINBOOL WINAPI DllMain (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved); 54 55 extern WINBOOL WINAPI DllEntryPoint (HANDLE, DWORD, LPVOID); 56 57 static int __cdecl pre_c_init (void); 58 59 _CRTALLOC(".CRT$XIAA") _PIFV pcinit = pre_c_init; 60 61 static int 62 __cdecl 63 pre_c_init (void) 64 { 65 _PVFV *onexitbegin; 66 67 onexitbegin = (_PVFV *) malloc (32 * sizeof (_PVFV)); 68 __onexitend = __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin); 69 70 if (onexitbegin == NULL) 71 return 1; 72 *onexitbegin = (_PVFV) NULL; 73 return 0; 74 } 75 76 WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) 77 { 78 if (dwReason == DLL_PROCESS_DETACH) 79 { 80 if (__proc_attached > 0) 81 __proc_attached--; 82 else 83 return FALSE; 84 } 85 if (dwReason == DLL_PROCESS_ATTACH) 86 { 87 void *lock_free = NULL; 88 void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase; 89 int nested = FALSE; 90 91 while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock, 92 fiberid, 0)) != 0) 93 { 94 if (lock_free == fiberid) 95 { 96 nested = TRUE; 97 break; 98 } 99 Sleep(1000); 100 } 101 if (__native_startup_state == __initializing) 102 { 103 _amsg_exit (31); 104 } 105 else if (__native_startup_state == __uninitialized) 106 { 107 __native_startup_state = __initializing; 108 109 _initterm ((_PVFV *) (void *) __xi_a, (_PVFV *) (void *) __xi_z); 110 } 111 if (__native_startup_state == __initializing) 112 { 113 _initterm (__xc_a, __xc_z); 114 __native_startup_state = __initialized; 115 } 116 if (! nested) 117 { 118 (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); 119 } 120 if (__dyn_tls_init_callback != NULL) 121 { 122 __dyn_tls_init_callback (hDllHandle, DLL_THREAD_ATTACH, lpreserved); 123 } 124 __proc_attached++; 125 } 126 else if (dwReason == DLL_PROCESS_DETACH) 127 { 128 void *lock_free = NULL; 129 while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,(PVOID) 1, 0)) != 0) 130 { 131 Sleep(1000); 132 } 133 if (__native_startup_state != __initialized) 134 { 135 _amsg_exit (31); 136 } 137 else 138 { 139 _PVFV * onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); 140 if (onexitbegin) 141 { 142 _PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend); 143 while (--onexitend >= onexitbegin) 144 if (*onexitend != NULL) 145 (**onexitend) (); 146 free (onexitbegin); 147 __onexitbegin = __onexitend = (_PVFV *) NULL; 148 } 149 __native_startup_state = __uninitialized; 150 (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); 151 } 152 } 153 return TRUE; 154 } 155 156 static WINBOOL __DllMainCRTStartup (HANDLE, DWORD, LPVOID); 157 158 WINBOOL WINAPI DllMainCRTStartup (HANDLE, DWORD, LPVOID); 159 int __mingw_init_ehandler (void); 160 161 WINBOOL WINAPI 162 DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) 163 { 164 mingw_app_type = 0; 165 if (dwReason == DLL_PROCESS_ATTACH) 166 { 167 __security_init_cookie (); 168 #ifdef _WIN64 169 __mingw_init_ehandler (); 170 #endif 171 } 172 return __DllMainCRTStartup (hDllHandle, dwReason, lpreserved); 173 } 174 175 __declspec(noinline) WINBOOL 176 __DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) 177 { 178 WINBOOL retcode = TRUE; 179 180 __native_dllmain_reason = dwReason; 181 if (dwReason == DLL_PROCESS_DETACH && __proc_attached == 0) 182 { 183 retcode = FALSE; 184 goto i__leave; 185 } 186 _pei386_runtime_relocator (); 187 if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH) 188 { 189 retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved); 190 if (!retcode) 191 goto i__leave; 192 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved); 193 if (! retcode) 194 { 195 if (dwReason == DLL_PROCESS_ATTACH) 196 _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved); 197 goto i__leave; 198 } 199 } 200 if (dwReason == DLL_PROCESS_ATTACH) 201 __main (); 202 retcode = DllMain(hDllHandle,dwReason,lpreserved); 203 if (dwReason == DLL_PROCESS_ATTACH && ! retcode) 204 { 205 DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved); 206 DllEntryPoint (hDllHandle, DLL_PROCESS_DETACH, lpreserved); 207 _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved); 208 } 209 if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH) 210 { 211 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved); 212 if (_CRT_INIT (hDllHandle, dwReason, lpreserved) == FALSE) 213 retcode = FALSE; 214 } 215 i__leave: 216 __native_dllmain_reason = UINT_MAX; 217 return retcode ; 218 } 219 #endif 220