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.
12 #define SPECIAL_CRTEXE
21 #include <sect_attribs.h>
26 extern wchar_t *** __MINGW_IMP_SYMBOL(__winitenv
);
27 #define __winitenv (* __MINGW_IMP_SYMBOL(__winitenv))
31 extern char *** __MINGW_IMP_SYMBOL(__initenv
);
32 #define __initenv (* __MINGW_IMP_SYMBOL(__initenv))
35 /* Hack, for bug in ld. Will be removed soon. */
36 #define __ImageBase __MINGW_LSYMBOL(_image_base__)
37 /* This symbol is defined by ld. */
38 extern IMAGE_DOS_HEADER __ImageBase
;
40 extern void _fpreset (void);
41 #define SPACECHAR _T(' ')
42 #define DQUOTECHAR _T('\"')
44 __declspec(dllimport
) void __setusermatherr(int (__cdecl
*)(struct _exception
*));
46 extern int * __MINGW_IMP_SYMBOL(_fmode
);
47 extern int * __MINGW_IMP_SYMBOL(_commode
);
51 extern int * __MINGW_IMP_SYMBOL(_commode
);
52 #define _commode (* __MINGW_IMP_SYMBOL(_commode))
53 extern int _dowildcard
;
56 int _MINGW_INSTALL_DEBUG_MATHERR
__attribute__((weak
)) = 0;
58 int _MINGW_INSTALL_DEBUG_MATHERR
= 0;
60 extern int __defaultmatherr
;
61 extern _CRTIMP
void __cdecl
_initterm(_PVFV
*, _PVFV
*);
63 static int __cdecl
check_managed_app (void);
65 extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a
[];
66 extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z
[];
67 extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a
[];
68 extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z
[];
70 /* TLS initialization hook. */
71 extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback
;
73 extern _PVFV
*__onexitbegin
;
74 extern _PVFV
*__onexitend
;
76 extern int mingw_app_type
;
78 HINSTANCE __mingw_winmain_hInstance
;
79 _TCHAR
*__mingw_winmain_lpCmdLine
;
80 DWORD __mingw_winmain_nShowCmd
;
84 extern void __main(void);
85 static wchar_t **argv
;
86 static wchar_t **envp
;
94 static int managedapp
;
95 static int has_cctor
= 0;
96 static _startupinfo startinfo
;
97 static LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler
= NULL
;
99 extern void _pei386_runtime_relocator (void);
100 static long CALLBACK
_gnu_exception_handler (EXCEPTION_POINTERS
* exception_data
);
102 static void duplicate_ppstrings (int ac
, wchar_t ***av
);
104 static void duplicate_ppstrings (int ac
, char ***av
);
107 static int __cdecl
pre_c_init (void);
108 static void __cdecl
pre_cpp_init (void);
109 static void __cdecl
__mingw_prepare_except_for_msvcr80_and_higher (void);
110 _CRTALLOC(".CRT$XIAA") _PIFV mingw_pcinit
= pre_c_init
;
111 _CRTALLOC(".CRT$XCAA") _PVFV mingw_pcppinit
= pre_cpp_init
;
116 managedapp
= check_managed_app ();
118 __set_app_type(_GUI_APP
);
120 __set_app_type (_CONSOLE_APP
);
121 __onexitbegin
= __onexitend
= (_PVFV
*) _encode_pointer ((_PVFV
*)(-1));
123 * __MINGW_IMP_SYMBOL(_fmode
) = _fmode
;
124 * __MINGW_IMP_SYMBOL(_commode
) = _commode
;
131 if (_MINGW_INSTALL_DEBUG_MATHERR
)
133 if (! __defaultmatherr
)
135 __setusermatherr (_matherr
);
136 __defaultmatherr
= 1;
140 if (__globallocalestatus
== -1)
149 startinfo
.newmode
= _newmode
;
152 argret
= __wgetmainargs(&argc
,&argv
,&envp
,_dowildcard
,&startinfo
);
154 argret
= __getmainargs(&argc
,&argv
,&envp
,_dowildcard
,&startinfo
);
158 static int __tmainCRTStartup (void);
160 int WinMainCRTStartup (void);
162 int WinMainCRTStartup (void)
165 __security_init_cookie ();
166 return __tmainCRTStartup ();
169 int mainCRTStartup (void);
172 int __mingw_init_ehandler (void);
175 int mainCRTStartup (void)
178 __security_init_cookie ();
179 return __tmainCRTStartup ();
183 __declspec(noinline
) int
184 __tmainCRTStartup (void)
186 _TCHAR
*lpszCommandLine
= NULL
;
187 STARTUPINFO StartupInfo
;
188 WINBOOL inDoubleQuote
= FALSE
;
189 memset (&StartupInfo
, 0, sizeof (STARTUPINFO
));
192 GetStartupInfo (&StartupInfo
);
194 void *lock_free
= NULL
;
195 void *fiberid
= ((PNT_TIB
)NtCurrentTeb())->StackBase
;
197 while((lock_free
= InterlockedCompareExchangePointer ((volatile PVOID
*) &__native_startup_lock
,
200 if (lock_free
== fiberid
)
207 if (__native_startup_state
== __initializing
)
211 else if (__native_startup_state
== __uninitialized
)
213 __native_startup_state
= __initializing
;
214 _initterm ((_PVFV
*)(void *)__xi_a
, (_PVFV
*)(void *) __xi_z
);
219 if (__native_startup_state
== __initializing
)
221 _initterm (__xc_a
, __xc_z
);
222 __native_startup_state
= __initialized
;
224 _ASSERTE(__native_startup_state
== __initialized
);
226 (VOID
)InterlockedExchangePointer ((volatile PVOID
*) &__native_startup_lock
, 0);
228 if (__dyn_tls_init_callback
!= NULL
)
229 __dyn_tls_init_callback (NULL
, DLL_THREAD_ATTACH
, NULL
);
231 _pei386_runtime_relocator ();
232 __mingw_oldexcpt_handler
= SetUnhandledExceptionFilter (_gnu_exception_handler
);
234 __mingw_init_ehandler ();
236 __mingw_prepare_except_for_msvcr80_and_higher ();
243 lpszCommandLine
= (_TCHAR
*) _wcmdln
;
245 lpszCommandLine
= (char *) _acmdln
;
247 while (*lpszCommandLine
> SPACECHAR
|| (*lpszCommandLine
&&inDoubleQuote
))
249 if (*lpszCommandLine
== DQUOTECHAR
)
250 inDoubleQuote
= !inDoubleQuote
;
252 if (_ismbblead (*lpszCommandLine
))
254 if (*lpszCommandLine
)
260 while (*lpszCommandLine
&& (*lpszCommandLine
<= SPACECHAR
))
263 __mingw_winmain_hInstance
= (HINSTANCE
) &__ImageBase
;
264 __mingw_winmain_lpCmdLine
= lpszCommandLine
;
265 __mingw_winmain_nShowCmd
= StartupInfo
.dwFlags
& STARTF_USESHOWWINDOW
?
266 StartupInfo
.wShowWindow
: SW_SHOWDEFAULT
;
268 duplicate_ppstrings (argc
, &argv
);
271 /* C++ initialization.
272 gcc inserts this call automatically for a function called main, but not for wmain. */
274 mainret
= wmain (argc
, argv
, envp
);
277 mainret
= main (argc
, argv
, envp
);
288 extern int mingw_initltsdrot_force
;
289 extern int mingw_initltsdyn_force
;
290 extern int mingw_initltssuo_force
;
291 extern int mingw_initcharmax
;
294 check_managed_app (void)
296 PIMAGE_DOS_HEADER pDOSHeader
;
297 PIMAGE_NT_HEADERS pPEHeader
;
298 PIMAGE_OPTIONAL_HEADER32 pNTHeader32
;
299 PIMAGE_OPTIONAL_HEADER64 pNTHeader64
;
301 /* Force to be linked. */
302 mingw_initltsdrot_force
=1;
303 mingw_initltsdyn_force
=1;
304 mingw_initltssuo_force
=1;
307 pDOSHeader
= (PIMAGE_DOS_HEADER
) &__ImageBase
;
308 if (pDOSHeader
->e_magic
!= IMAGE_DOS_SIGNATURE
)
311 pPEHeader
= (PIMAGE_NT_HEADERS
)((char *)pDOSHeader
+ pDOSHeader
->e_lfanew
);
312 if (pPEHeader
->Signature
!= IMAGE_NT_SIGNATURE
)
315 pNTHeader32
= (PIMAGE_OPTIONAL_HEADER32
) &pPEHeader
->OptionalHeader
;
316 switch (pNTHeader32
->Magic
)
318 case IMAGE_NT_OPTIONAL_HDR32_MAGIC
:
319 if (pNTHeader32
->NumberOfRvaAndSizes
<= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
)
321 return !! pNTHeader32
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].VirtualAddress
;
322 case IMAGE_NT_OPTIONAL_HDR64_MAGIC
:
323 pNTHeader64
= (PIMAGE_OPTIONAL_HEADER64
)pNTHeader32
;
324 if (pNTHeader64
->NumberOfRvaAndSizes
<= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
)
326 return !! pNTHeader64
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].VirtualAddress
;
332 _gnu_exception_handler (EXCEPTION_POINTERS
*exception_data
)
334 void (*old_handler
) (int);
335 long action
= EXCEPTION_CONTINUE_SEARCH
;
338 switch (exception_data
->ExceptionRecord
->ExceptionCode
)
340 case EXCEPTION_ACCESS_VIOLATION
:
341 /* test if the user has set SIGSEGV */
342 old_handler
= signal (SIGSEGV
, SIG_DFL
);
343 if (old_handler
== SIG_IGN
)
345 /* this is undefined if the signal was raised by anything other
347 signal (SIGSEGV
, SIG_IGN
);
348 action
= EXCEPTION_CONTINUE_EXECUTION
;
350 else if (old_handler
!= SIG_DFL
)
352 /* This means 'old' is a user defined function. Call it */
353 (*old_handler
) (SIGSEGV
);
354 action
= EXCEPTION_CONTINUE_EXECUTION
;
358 case EXCEPTION_ILLEGAL_INSTRUCTION
:
359 case EXCEPTION_PRIV_INSTRUCTION
:
360 /* test if the user has set SIGILL */
361 old_handler
= signal (SIGILL
, SIG_DFL
);
362 if (old_handler
== SIG_IGN
)
364 /* this is undefined if the signal was raised by anything other
366 signal (SIGILL
, SIG_IGN
);
367 action
= EXCEPTION_CONTINUE_EXECUTION
;
369 else if (old_handler
!= SIG_DFL
)
371 /* This means 'old' is a user defined function. Call it */
372 (*old_handler
) (SIGILL
);
373 action
= EXCEPTION_CONTINUE_EXECUTION
;
377 case EXCEPTION_FLT_INVALID_OPERATION
:
378 case EXCEPTION_FLT_DIVIDE_BY_ZERO
:
379 case EXCEPTION_FLT_DENORMAL_OPERAND
:
380 case EXCEPTION_FLT_OVERFLOW
:
381 case EXCEPTION_FLT_UNDERFLOW
:
382 case EXCEPTION_FLT_INEXACT_RESULT
:
386 case EXCEPTION_INT_DIVIDE_BY_ZERO
:
387 /* test if the user has set SIGFPE */
388 old_handler
= signal (SIGFPE
, SIG_DFL
);
389 if (old_handler
== SIG_IGN
)
391 signal (SIGFPE
, SIG_IGN
);
394 action
= EXCEPTION_CONTINUE_EXECUTION
;
396 else if (old_handler
!= SIG_DFL
)
398 /* This means 'old' is a user defined function. Call it */
399 (*old_handler
) (SIGFPE
);
400 action
= EXCEPTION_CONTINUE_EXECUTION
;
404 case EXCEPTION_DATATYPE_MISALIGNMENT
:
405 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
406 case EXCEPTION_FLT_STACK_CHECK
:
407 case EXCEPTION_INT_OVERFLOW
:
408 case EXCEPTION_INVALID_HANDLE
:
409 /*case EXCEPTION_POSSIBLE_DEADLOCK: */
410 action
= EXCEPTION_CONTINUE_EXECUTION
;
417 if (action
== EXCEPTION_CONTINUE_SEARCH
&& __mingw_oldexcpt_handler
)
418 action
= (*__mingw_oldexcpt_handler
)(exception_data
);
423 static size_t wbytelen(const wchar_t *p
)
431 static void duplicate_ppstrings (int ac
, wchar_t ***av
)
435 wchar_t **n
= (wchar_t **) malloc (sizeof (wchar_t *) * (ac
+ 1));
438 for (i
=0; i
< ac
; i
++)
440 int l
= wbytelen (avl
[i
]);
441 n
[i
] = (wchar_t *) malloc (l
);
442 memcpy (n
[i
], avl
[i
], l
);
448 static void duplicate_ppstrings (int ac
, char ***av
)
452 char **n
= (char **) malloc (sizeof (char *) * (ac
+ 1));
455 for (i
=0; i
< ac
; i
++)
457 int l
= strlen (avl
[i
]) + 1;
458 n
[i
] = (char *) malloc (l
);
459 memcpy (n
[i
], avl
[i
], l
);
467 __mingw_invalidParameterHandler (const wchar_t *expression
__attribute__ ((__unused__
)),
468 const wchar_t *function
__attribute__ ((__unused__
)),
469 const wchar_t *file
__attribute__ ((__unused__
)),
470 unsigned int line
__attribute__ ((__unused__
)),
471 uintptr_t pReserved
__attribute__ ((__unused__
)))
473 #ifdef __MINGW_SHOW_INVALID_PARAMETER_EXCEPTION
474 wprintf(L
"Invalid parameter detected in function %s. File: %s Line: %d\n", function
, file
, line
);
475 wprintf(L
"Expression: %s\n", expression
);
480 __mingw_prepare_except_for_msvcr80_and_higher (void)
482 _invalid_parameter_handler (*fIPH
)(_invalid_parameter_handler
) = NULL
;
483 HMODULE hmsv
= GetModuleHandleA ("msvcr80.dll");
485 hmsv
= GetModuleHandleA ("msvcr70.dll");
487 hmsv
= GetModuleHandleA ("msvcrt.dll");
489 hmsv
= LoadLibraryA ("msvcrt.dll");
492 fIPH
= (_invalid_parameter_handler (*)(_invalid_parameter_handler
))
493 GetProcAddress (hmsv
, "_set_invalid_parameter_handler");
495 (*fIPH
)(__mingw_invalidParameterHandler
);