blob: 7edf8360c91c182f8ec6e5a695c262332ee6c3ba [file]
/**
* 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.
*/
#ifndef _MINGW_DLL_
int __cdecl atexit (void (__cdecl *)(void));
#endif
typedef void (*func_ptr) (void);
extern func_ptr __CTOR_LIST__[];
extern func_ptr __DTOR_LIST__[];
#ifndef _MINGW_DLL_
/* WARNING: All these functions must be in one translation unit.
* Otherwise linker can throw error "multiple definitions of __do_global_dtors"
* when linking with static libgcc library which also provides these symbols.
*/
void __do_global_dtors (void);
void __do_global_ctors (void);
void __main (void);
#else
void __cdecl __mingw_dll_do_global_dtors (void);
void __cdecl __mingw_dll_do_global_ctors (void);
#endif
/* __do_global_dtors is gcc ABI function which has to be exported.
* It executes all gcc dtors from __DTOR_LIST__ list under guard
* which prevents duplicate execution.
*
* Same implementation of this __do_global_dtors function is provided also by
* the static libgcc library. They are interchangeable and EXE application can
* link to any of them.
*
* To prevent duplicate execution of __DTOR_LIST__ in EXE application,
* only this function with __do_global_dtors name should execute functions
* in the __DTOR_LIST__ list.
*
* WARNING: Do not change ABI, name or behavior of this function.
*/
#ifndef _MINGW_DLL_
void
__do_global_dtors (void)
#else
void __cdecl
__mingw_dll_do_global_dtors (void)
#endif
{
/* static initialization and incrementation before invocation of dtor
* ensures that repeated calls to __do_global_dtors() will not invoke
* any dtor function more times
*/
static func_ptr *p = __DTOR_LIST__ + 1;
while (*p)
{
p++;
(*(p-1)) ();
}
}
/* __do_global_ctors is gcc ABI function which has to be exported.
* It executes all gcc ctors from __CTOR_LIST__ list and schedules execution
* of __do_global_dtors via atexit(). If it is called multiple times then gcc
* ctors are executed multiple times but gcc dtors are executed only once.
* This is because __do_global_dtors contains guard which prevents executing
* dtors multiple times, even if registration of __do_global_dtors is done
* multiple times.
*
* Same implementation of this __do_global_ctors function is provided also by
* the static libgcc library. They are interchangeable and EXE application can
* link to any of them.
*
* WARNING: Do not change ABI, name or behavior of this function.
*/
#ifndef _MINGW_DLL_
void
__do_global_ctors (void)
#else
void __cdecl
__mingw_dll_do_global_ctors (void)
#endif
{
__SIZE_TYPE__ nptrs = (__SIZE_TYPE__) __CTOR_LIST__[0];
__SIZE_TYPE__ i;
#ifdef _MINGW_DLL_
/* Repeated calls to mingw DLL variant of this function
* does not invoke ctors functions multiple times.
*/
static int initialized = 0;
if (initialized)
return;
initialized = 1;
#endif
if (nptrs == (__SIZE_TYPE__) -1)
{
for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++);
}
for (i = nptrs; i >= 1; i--)
{
__CTOR_LIST__[i] ();
}
/* mingw DLL variant of this function does not schedule execution of
* __do_global_dtors. Instead mingw DLL startup code calls the
* __do_global_dtors explicitly.
*/
#ifndef _MINGW_DLL_
atexit (__do_global_dtors);
#endif
}
#ifndef _MINGW_DLL_
/* __main is gcc ABI function which has to be exported.
* It calls __do_global_ctors function under the guard.
*
* Same implementation of this __main function is provided also by
* the static libgcc library. They are interchangeable and EXE application can
* link to any of them.
*
* WARNING: Do not change ABI, name or behavior of this function.
*/
__attribute__((used)) /* required for gcc -flto -Ofast */
void
__main (void)
{
/* gcc during compilation of function named main() (but not wmain() or
* DllMain()) inserts at the beginning of the execution a call to the
* function __main(). gcc expects that the function __main() will execute
* all global C++ constructors which are emitted by gcc itself and will
* schedule calls for global C++ destructors.
*
* mingw-w64 runtime executes all gcc's global C++ constructors in mingw-w64
* startup code (in crtdll.c and crtexe.c) before executing function main(),
* wmain() or DllMain().
*
* So the function __main() should expects that constructors were already
* called and must prevent multiple execution of them.
*
* Also application or DLL library can be built with the custom entry point
* which does not call mingw-w64 startup code but calls this __main() function
* manually and therefore this __main() function has to execute all global
* C++ constructors and has to schedule calls for global C++ destructors.
*
* gcc ABI function __do_global_ctors() does that. But it does not contain a
* guard to prevent duplicate execution. On the other hand, gcc ABI function
* __main() can be called multiple times and will not call constructors or
* destructor multiple times. So call __do_global_ctors() under a local guard.
*/
static int initialized = 0;
if (!initialized)
{
initialized = 1;
__do_global_ctors ();
}
}
#endif