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 __onexitend = __onexitbegin = NULL; 66 67 return 0; 68 } 69 70 WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) 71 { 72 if (dwReason == DLL_PROCESS_DETACH) 73 { 74 if (__proc_attached > 0) 75 __proc_attached--; 76 else 77 return FALSE; 78 } 79 if (dwReason == DLL_PROCESS_ATTACH) 80 { 81 void *lock_free = NULL; 82 void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase; 83 int nested = FALSE; 84 85 while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock, 86 fiberid, 0)) != 0) 87 { 88 if (lock_free == fiberid) 89 { 90 nested = TRUE; 91 break; 92 } 93 Sleep(1000); 94 } 95 if (__native_startup_state == __initializing) 96 { 97 _amsg_exit (31); 98 } 99 else if (__native_startup_state == __uninitialized) 100 { 101 __native_startup_state = __initializing; 102 103 _initterm ((_PVFV *) (void *) __xi_a, (_PVFV *) (void *) __xi_z); 104 } 105 if (__native_startup_state == __initializing) 106 { 107 _initterm (__xc_a, __xc_z); 108 __native_startup_state = __initialized; 109 } 110 if (! nested) 111 { 112 (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); 113 } 114 if (__dyn_tls_init_callback != NULL) 115 { 116 __dyn_tls_init_callback (hDllHandle, DLL_THREAD_ATTACH, lpreserved); 117 } 118 __proc_attached++; 119 } 120 else if (dwReason == DLL_PROCESS_DETACH) 121 { 122 void *lock_free = NULL; 123 while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,(PVOID) 1, 0)) != 0) 124 { 125 Sleep(1000); 126 } 127 if (__native_startup_state != __initialized) 128 { 129 _amsg_exit (31); 130 } 131 else 132 { 133 if (__onexitbegin) 134 { 135 _PVFV *onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); 136 _PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend); 137 while (--onexitend >= onexitbegin) 138 if (*onexitend != NULL) 139 (**onexitend) (); 140 if (!lpreserved) 141 free(onexitbegin); 142 __onexitbegin = __onexitend = (_PVFV *) NULL; 143 } 144 __native_startup_state = __uninitialized; 145 (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); 146 } 147 } 148 return TRUE; 149 } 150 151 static WINBOOL __DllMainCRTStartup (HANDLE, DWORD, LPVOID); 152 153 WINBOOL WINAPI DllMainCRTStartup (HANDLE, DWORD, LPVOID); 154 int __mingw_init_ehandler (void); 155 156 WINBOOL WINAPI 157 DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) 158 { 159 mingw_app_type = 0; 160 if (dwReason == DLL_PROCESS_ATTACH) 161 { 162 __security_init_cookie (); 163 #ifdef _WIN64 164 __mingw_init_ehandler (); 165 #endif 166 } 167 return __DllMainCRTStartup (hDllHandle, dwReason, lpreserved); 168 } 169 170 __declspec(noinline) WINBOOL 171 __DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) 172 { 173 WINBOOL retcode = TRUE; 174 175 __native_dllmain_reason = dwReason; 176 if (dwReason == DLL_PROCESS_DETACH && __proc_attached == 0) 177 { 178 retcode = FALSE; 179 goto i__leave; 180 } 181 _pei386_runtime_relocator (); 182 if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH) 183 { 184 retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved); 185 if (!retcode) 186 goto i__leave; 187 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved); 188 if (! retcode) 189 { 190 if (dwReason == DLL_PROCESS_ATTACH) 191 _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved); 192 goto i__leave; 193 } 194 } 195 if (dwReason == DLL_PROCESS_ATTACH) 196 __main (); 197 retcode = DllMain(hDllHandle,dwReason,lpreserved); 198 if (dwReason == DLL_PROCESS_ATTACH && ! retcode) 199 { 200 DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved); 201 DllEntryPoint (hDllHandle, DLL_PROCESS_DETACH, lpreserved); 202 _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved); 203 } 204 if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH) 205 { 206 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved); 207 if (_CRT_INIT (hDllHandle, dwReason, lpreserved) == FALSE) 208 retcode = FALSE; 209 } 210 i__leave: 211 __native_dllmain_reason = UINT_MAX; 212 return retcode ; 213 } 214 #endif 215