23#if !defined(__arm__) && !defined(__aarch64__)
30#define __ImageBase __MINGW_LSYMBOL(_image_base__)
37#define SPACECHAR _T(' ')
38#define DQUOTECHAR _T('\"')
40extern int _dowildcard;
42extern _CRTIMP void __cdecl _initterm(_PVFV *, _PVFV *);
44static int __cdecl check_managed_app (void);
46extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a[];
47extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];
48extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
49extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];
51/* TLS initialization hook. */
52extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
54extern _PVFV *__onexitbegin;
55extern _PVFV *__onexitend;
57extern int mingw_app_type;
59HINSTANCE __mingw_winmain_hInstance;
60_TCHAR *__mingw_winmain_lpCmdLine;
61DWORD __mingw_winmain_nShowCmd;
64extern void __main(void);
76static int has_cctor = 0;
77static _startupinfo startinfo;
78extern LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler;
80extern void _pei386_runtime_relocator (void);
81long CALLBACK _gnu_exception_handler (EXCEPTION_POINTERS * exception_data);
83static void duplicate_ppstrings (int ac, wchar_t ***av);
85static void duplicate_ppstrings (int ac, char ***av);
88static int __cdecl pre_c_init (void);
89static void __cdecl pre_cpp_init (void);
90static void __cdecl __mingw_prepare_except_for_msvcr80_and_higher (void);
91_CRTALLOC(".CRT$XIAA") _PIFV mingw_pcinit = pre_c_init;
92_CRTALLOC(".CRT$XCAA") _PVFV mingw_pcppinit = pre_cpp_init;
94extern int _MINGW_INSTALL_DEBUG_MATHERR;
97extern void __do_global_dtors(void);
103 managedapp = check_managed_app ();
105 __set_app_type(_GUI_APP);
107 __set_app_type (_CONSOLE_APP);
108 __onexitbegin = __onexitend = (_PVFV *)(-1);
115 if (_MINGW_INSTALL_DEBUG_MATHERR == 1)
117 __setusermatherr (_matherr);
119#if !defined(__clang__) && (!defined(_M_ARM64) || (_MSC_VER < 1930)) /* FIXME: CORE-14042 */
120 if (__globallocalestatus == -1)
130 startinfo.newmode = _newmode;
133 argret = __wgetmainargs(&argc,&argv,&envp,_dowildcard,&startinfo);
135 argret = __getmainargs(&argc,&argv,&envp,_dowildcard,&startinfo);
139static int __cdecl __tmainCRTStartup (void);
141int __cdecl WinMainCRTStartup (void);
143int __cdecl WinMainCRTStartup (void)
147 asm ("\t.l_startw:\n"
148 "\t.seh_handler __C_specific_handler, @except\n"
149 "\t.seh_handlerdata\n"
151 "\t.rva .l_startw, .l_endw, _gnu_exception_handler ,.l_endw\n"
156 __security_init_cookie ();
157 ret = __tmainCRTStartup ();
165int __cdecl mainCRTStartup (void);
166BOOL crt_process_init(void);
169int __mingw_init_ehandler (void);
172int __cdecl mainCRTStartup (void)
176 if (!crt_process_init())
183 "\t.seh_handler __C_specific_handler, @except\n"
184 "\t.seh_handlerdata\n"
186 "\t.rva .l_start, .l_end, _gnu_exception_handler ,.l_end\n"
191 __security_init_cookie ();
192 ret = __tmainCRTStartup ();
203__tmainCRTStartup (void)
205 _TCHAR *lpszCommandLine = NULL;
206 STARTUPINFO StartupInfo;
207 WINBOOL inDoubleQuote = FALSE;
208 memset (&StartupInfo, 0, sizeof (STARTUPINFO));
211 /* We need to make sure that this function is build with frame-pointer
212 and that we align the stack to 16 bytes for the sake of SSE ops in main
213 or in functions inlined into main. */
214 lpszCommandLine = (_TCHAR *) _alloca (32);
215 memset (lpszCommandLine, 0xcc, 32);
217 asm __volatile__ ("andl $-16, %%esp" : : : "%esp");
222 GetStartupInfo (&StartupInfo);
224 void *lock_free = NULL;
225 void *fiberid = ((PNT_TIB)NtCurrentTeb())->StackBase;
227 while((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,
230 if (lock_free == fiberid)
237 if (__native_startup_state == __initializing)
241 else if (__native_startup_state == __uninitialized)
243 __native_startup_state = __initializing;
244 _initterm ((_PVFV *)(void *)__xi_a, (_PVFV *)(void *) __xi_z);
249 if (__native_startup_state == __initializing)
251 _initterm (__xc_a, __xc_z);
252 __native_startup_state = __initialized;
254 _ASSERTE(__native_startup_state == __initialized);
256 (VOID)InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
258 if (__dyn_tls_init_callback != NULL)
259 __dyn_tls_init_callback (NULL, DLL_THREAD_ATTACH, NULL);
261 _pei386_runtime_relocator ();
262 __mingw_oldexcpt_handler = SetUnhandledExceptionFilter (_gnu_exception_handler);
264 __mingw_init_ehandler ();
266 __mingw_prepare_except_for_msvcr80_and_higher ();
273 lpszCommandLine = (_TCHAR *) _wcmdln;
275 lpszCommandLine = (char *) _acmdln;
277 while (*lpszCommandLine > SPACECHAR || (*lpszCommandLine && inDoubleQuote))
279 if (*lpszCommandLine == DQUOTECHAR)
280 inDoubleQuote = !inDoubleQuote;
282 if (_ismbblead (*lpszCommandLine))
284 if (lpszCommandLine) /* FIXME: Why this check? Should I check for *lpszCommandLine != 0 too? */
290 while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
293 __mingw_winmain_hInstance = (HINSTANCE) &__ImageBase;
294 __mingw_winmain_lpCmdLine = lpszCommandLine;
295 __mingw_winmain_nShowCmd = StartupInfo.dwFlags & STARTF_USESHOWWINDOW ?
296 StartupInfo.wShowWindow : SW_SHOWDEFAULT;
298 duplicate_ppstrings (argc, &argv);
301#if !defined(__arm__) && !defined(__aarch64__)
304 /* C++ initialization.
305 gcc inserts this call automatically for a function called main, but not for wmain. */
306 mainret = wmain (argc, argv, envp);
308#if !defined(__arm__) && !defined(__aarch64__)
311 mainret = main (argc, argv, envp);
327extern int mingw_initltsdrot_force;
328extern int mingw_initltsdyn_force;
329extern int mingw_initltssuo_force;
330extern int mingw_initcharmax;
333check_managed_app (void)
335 PIMAGE_DOS_HEADER pDOSHeader;
336 PIMAGE_NT_HEADERS pPEHeader;
337 PIMAGE_OPTIONAL_HEADER32 pNTHeader32;
338 PIMAGE_OPTIONAL_HEADER64 pNTHeader64;
340 /* Force to be linked. */
341 mingw_initltsdrot_force=1;
342 mingw_initltsdyn_force=1;
343 mingw_initltssuo_force=1;
346 pDOSHeader = (PIMAGE_DOS_HEADER) &__ImageBase;
347 if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
350 pPEHeader = (PIMAGE_NT_HEADERS)((char *)pDOSHeader + pDOSHeader->e_lfanew);
351 if (pPEHeader->Signature != IMAGE_NT_SIGNATURE)
354 pNTHeader32 = (PIMAGE_OPTIONAL_HEADER32) &pPEHeader->OptionalHeader;
355 switch (pNTHeader32->Magic)
357 case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
358 if (pNTHeader32->NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
360 return !! pNTHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
361 case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
362 pNTHeader64 = (PIMAGE_OPTIONAL_HEADER64)pNTHeader32;
363 if (pNTHeader64->NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
365 return !! pNTHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
371static size_t wbytelen(const wchar_t *p)
379static void duplicate_ppstrings (int ac, wchar_t ***av)
383 wchar_t **n = (wchar_t **) malloc (sizeof (wchar_t *) * (ac + 1));
386 for (i=0; i < ac; i++)
388 size_t l = wbytelen (avl[i]);
389 n[i] = (wchar_t *) malloc (l);
390 memcpy (n[i], avl[i], l);
396static void duplicate_ppstrings (int ac, char ***av)
400 char **n = (char **) malloc (sizeof (char *) * (ac + 1));
403 for (i=0; i < ac; i++)
405 size_t l = strlen (avl[i]) + 1;
406 n[i] = (char *) malloc (l);
407 memcpy (n[i], avl[i], l);
414#ifdef __MINGW_SHOW_INVALID_PARAMETER_EXCEPTION
415#define __UNUSED_PARAM_1(x) x
417#define __UNUSED_PARAM_1 __UNUSED_PARAM
420__mingw_invalidParameterHandler (const wchar_t * __UNUSED_PARAM_1(expression),
421 const wchar_t * __UNUSED_PARAM_1(function),
422 const wchar_t * __UNUSED_PARAM_1(file),
423 unsigned int __UNUSED_PARAM_1(line),
424 uintptr_t __UNUSED_PARAM(pReserved))
426#ifdef __MINGW_SHOW_INVALID_PARAMETER_EXCEPTION
427 wprintf(L"Invalid parameter detected in function %s. File: %s Line: %u\n", function, file, line);
428 wprintf(L"Expression: %s\n", expression);
432HANDLE __mingw_get_msvcrt_handle(void);
435__mingw_prepare_except_for_msvcr80_and_higher (void)
437 _invalid_parameter_handler (*fIPH)(_invalid_parameter_handler) = NULL;
439 fIPH = (void*)GetProcAddress (__mingw_get_msvcrt_handle(), "_set_invalid_parameter_handler");
441 (*fIPH)(__mingw_invalidParameterHandler);
_CRTIMP wchar_t ** __winitenv
void __cdecl _fpreset(void)
IMAGE_DOS_HEADER __ImageBase
_CRTIMP char ** __initenv