/** * This file has no copyright assigned and is placed in the Public Domain. * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #include #include #include #include #define _DECL_DLLMAIN #include #include #ifndef _CRTIMP #define _CRTIMP __declspec(dllimport) #endif #include #include #if defined(__x86_64__) && !defined(__SEH__) extern int __mingw_init_ehandler (void); #endif extern void __main (); extern void _pei386_runtime_relocator (void); extern _PIFV __xi_a[]; extern _PIFV __xi_z[]; extern _PVFV __xc_a[]; extern _PVFV __xc_z[]; /* TLS initialization hook. */ extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback; static int __proc_attached = 0; static _onexit_table_t atexit_table; extern int __mingw_app_type; WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { if (dwReason == DLL_PROCESS_DETACH) { if (__proc_attached > 0) __proc_attached--; else return FALSE; } if (dwReason == DLL_PROCESS_ATTACH) { void *lock_free = NULL; void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase; BOOL nested = FALSE; int ret = 0; while ((lock_free = InterlockedCompareExchangePointer (&__native_startup_lock, fiberid, NULL)) != 0) { if (lock_free == fiberid) { nested = TRUE; break; } Sleep(1000); } if (__native_startup_state != __uninitialized) { _amsg_exit (31); } else { __native_startup_state = __initializing; _pei386_runtime_relocator (); #if defined(__x86_64__) && !defined(__SEH__) __mingw_init_ehandler (); #endif ret = _initialize_onexit_table (&atexit_table); if (ret != 0) goto i__leave; ret = _initterm_e (__xi_a, __xi_z); if (ret != 0) goto i__leave; _initterm (__xc_a, __xc_z); __main (); __native_startup_state = __initialized; } i__leave: if (! nested) { (void) InterlockedExchangePointer (&__native_startup_lock, NULL); } if (ret != 0) { return FALSE; } if (__dyn_tls_init_callback != NULL) { __dyn_tls_init_callback (hDllHandle, DLL_THREAD_ATTACH, lpreserved); } __proc_attached++; } else if (dwReason == DLL_PROCESS_DETACH) { void *lock_free = NULL; void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase; BOOL nested = FALSE; while ((lock_free = InterlockedCompareExchangePointer (&__native_startup_lock, fiberid, NULL)) != 0) { if (lock_free == fiberid) { nested = TRUE; break; } Sleep(1000); } if (__native_startup_state != __initialized) { _amsg_exit (31); } else { _execute_onexit_table(&atexit_table); __native_startup_state = __uninitialized; } if (! nested) { (void) InterlockedExchangePointer (&__native_startup_lock, NULL); } } return TRUE; } WINBOOL WINAPI DllMainCRTStartup (HANDLE, DWORD, LPVOID); #if defined(__i386__) || defined(_X86_) /* We need to make sure that we align the stack to 16 bytes for the sake of SSE opts in DllMain or in functions called from DllMain. */ __attribute__((force_align_arg_pointer)) #endif __attribute__((used)) /* required due to GNU LD bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30300 */ WINBOOL WINAPI DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { WINBOOL retcode = TRUE; __mingw_app_type = 0; __native_dllmain_reason = dwReason; if (dwReason == DLL_PROCESS_DETACH && __proc_attached <= 0) { retcode = FALSE; goto i__leave; } if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH) { retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved); if (!retcode) goto i__leave; } retcode = DllMain(hDllHandle,dwReason,lpreserved); if (dwReason == DLL_PROCESS_ATTACH && ! retcode) { DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved); _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved); } if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH) { retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved); } i__leave: __native_dllmain_reason = UINT_MAX; return retcode ; } int __cdecl atexit (_PVFV func) { /* Do not use msvcrt's atexit() or UCRT's _crt_atexit() function as it * cannot be called from DLL library which may be unloaded at runtime. */ return _register_onexit_function(&atexit_table, (_onexit_t)func); } char __mingw_module_is_dll = 1;