mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
186 lines
4.5 KiB
C
Vendored
186 lines
4.5 KiB
C
Vendored
/**
|
|
* 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 <oscalls.h>
|
|
#include <internal.h>
|
|
#include <stdlib.h>
|
|
#include <windows.h>
|
|
#define _DECL_DLLMAIN
|
|
#include <process.h>
|
|
#include <crtdbg.h>
|
|
|
|
#ifndef _CRTIMP
|
|
#define _CRTIMP __declspec(dllimport)
|
|
#endif
|
|
#include <sect_attribs.h>
|
|
#include <locale.h>
|
|
|
|
#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;
|