16 extern wchar_t ***_imp____winitenv
;
17 #define __winitenv (*_imp____winitenv)
21 extern char ***_imp____initenv
;
22 #define __initenv (*_imp____initenv)
25 /* Hack, for bug in ld. Will be removed soon. */
26 #define __ImageBase _image_base__
27 /* This symbol is defined by ld. */
28 extern IMAGE_DOS_HEADER __ImageBase
;
30 extern void _fpreset (void);
31 #define SPACECHAR _T(' ')
32 #define DQUOTECHAR _T('\"')
34 _CRTIMP
void __setusermatherr(int (__cdecl
*)(struct _exception
*));
36 extern int *_imp___fmode
;
37 extern int *_imp___commode
;
41 extern int *_imp___commode
;
42 #define _commode (*_imp___commode)
43 extern int _dowildcard
;
45 extern int __defaultmatherr
;
46 extern _CRTIMP
void __cdecl
_initterm(_PVFV
*, _PVFV
*);
48 static int __cdecl
check_managed_app (void);
50 extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a
[];
51 extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z
[];
52 extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a
[];
53 extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z
[];
55 extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback
;
57 extern _PVFV
*__onexitbegin
;
58 extern _PVFV
*__onexitend
;
60 extern int mingw_app_type
;
64 static wchar_t **argv
;
65 static wchar_t **envp
;
73 static int managedapp
=0;
74 static int has_cctor
= 0;
75 static _startupinfo startinfo
;
77 extern void _pei386_runtime_relocator (void);
78 static CALLBACK
long _gnu_exception_handler (EXCEPTION_POINTERS
* exception_data
);
79 //static LONG __mingw_vex(EXCEPTION_POINTERS * exception_data);
81 static void duplicate_ppstrings (int ac
, wchar_t ***av
);
83 static void duplicate_ppstrings (int ac
, char ***av
);
86 static int __cdecl
pre_c_init (void);
87 static void __cdecl
pre_cpp_init (void);
89 _CRTALLOC(".CRT$XIAA") _PIFV mingw_pcinit
= pre_c_init
;
90 _CRTALLOC(".CRT$XCAA") _PVFV mingw_pcppinit
= pre_cpp_init
;
95 managedapp
= check_managed_app ();
97 __set_app_type(_GUI_APP
);
99 __set_app_type (_CONSOLE_APP
);
100 __onexitbegin
= __onexitend
= (_PVFV
*) _encode_pointer ((_PVFV
*)(-1));
102 *_imp___fmode
= _fmode
;
103 *_imp___commode
= _commode
;
109 if (! __defaultmatherr
)
110 __setusermatherr (_matherr
);
112 if (__globallocalestatus
== -1)
121 startinfo
.newmode
= _newmode
;
123 argret
= __wgetmainargs(&argc
,&argv
,&envp
,_dowildcard
,&startinfo
);
125 argret
= __getmainargs(&argc
,&argv
,&envp
,_dowildcard
,&startinfo
);
130 static int __mingw_CRTStartup (void);
133 int wWinMainCRTStartup (void)
135 int WinMainCRTStartup (void)
139 __security_init_cookie ();
140 return __mingw_CRTStartup ();
144 int wmainCRTStartup (void)
146 int mainCRTStartup (void)
150 __security_init_cookie ();
151 return __mingw_CRTStartup ();
155 __declspec(noinline
) int
156 __mingw_CRTStartup (void)
158 _TCHAR
*lpszCommandLine
= NULL
;
159 STARTUPINFO StartupInfo
;
160 BOOL inDoubleQuote
= FALSE
;
161 memset (&StartupInfo
, 0, sizeof (STARTUPINFO
));
165 GetStartupInfo (&StartupInfo
);
167 #if 0 //not ready for this yet
168 void *lock_free
= NULL
;
169 void *fiberid
= ((PNT_TIB
)NtCurrentTeb())->StackBase
;
170 while((lock_free
= InterlockedCompareExchangePointer ((volatile PVOID
*) &__native_startup_lock
,
173 if (lock_free
== fiberid
)
181 if (__native_startup_state
== __initializing
)
185 else if (__native_startup_state
== __uninitialized
)
187 __native_startup_state
= __initializing
;
188 _initterm ((_PVFV
*)(void *)__xi_a
, (_PVFV
*)(void *) __xi_z
);
193 if (__native_startup_state
== __initializing
)
195 _initterm (__xc_a
, __xc_z
);
196 __native_startup_state
= __initialized
;
198 _ASSERTE(__native_startup_state
== __initialized
);
200 (VOID
)InterlockedExchangePointer ((volatile PVOID
*) &__native_startup_lock
, 0);
202 if (__dyn_tls_init_callback
!= NULL
&& _IsNonwritableInCurrentImage ((PBYTE
) &__dyn_tls_init_callback
))
203 __dyn_tls_init_callback (NULL
, DLL_THREAD_ATTACH
, NULL
);
205 #if defined(__i386__) || defined(__x86_64__)
206 _pei386_runtime_relocator ();
209 #if defined(__x86_64__)
210 __asm__
__volatile__ (
213 "movq %rax,%gs:0" "\n");
214 #elif defined(__i386__)
215 __asm__
__volatile__ (
218 "movl %eax,%fs:0" "\n");
220 //AddVectoredExceptionHandler (0, (PVECTORED_EXCEPTION_HANDLER)__mingw_vex);
221 SetUnhandledExceptionFilter (_gnu_exception_handler
);
228 lpszCommandLine
= (_TCHAR
*) _wcmdln
;
230 lpszCommandLine
= (char *) _acmdln
;
232 while (*lpszCommandLine
> SPACECHAR
|| (*lpszCommandLine
&& inDoubleQuote
))
234 if (*lpszCommandLine
== DQUOTECHAR
)
235 inDoubleQuote
= TRUE
;
237 if (_ismbblead (*lpszCommandLine
))
245 while (*lpszCommandLine
&& (*lpszCommandLine
<= SPACECHAR
))
250 (int) (StartupInfo
.dwFlags
& STARTF_USESHOWWINDOW
? StartupInfo
.wShowWindow
: SW_SHOWDEFAULT
),
251 (wchar_t **) lpszCommandLine
, (wchar_t **) (HINSTANCE
) &__ImageBase
);
254 (int) (StartupInfo
.dwFlags
& STARTF_USESHOWWINDOW
? StartupInfo
.wShowWindow
: SW_SHOWDEFAULT
),
255 (char **) lpszCommandLine
, (char **) (HINSTANCE
) &__ImageBase
);
260 duplicate_ppstrings (argc
, &argv
);
263 mainret
= wmain (argc
, argv
, envp
);
266 mainret
= main (argc
, argv
, envp
);
278 extern int mingw_initltsdrot_force
;
279 extern int mingw_initltsdyn_force
;
280 extern int mingw_initltssuo_force
;
281 extern int mingw_initcharmax
;
284 check_managed_app (void)
286 PIMAGE_DOS_HEADER pDOSHeader
;
287 PIMAGE_NT_HEADERS pPEHeader
;
288 PIMAGE_OPTIONAL_HEADER32 pNTHeader32
;
289 PIMAGE_OPTIONAL_HEADER64 pNTHeader64
;
291 /* Force to be linked. */
293 //mingw_initltsdrot_force=1;
294 //mingw_initltsdyn_force=1;
295 //mingw_initltssuo_force=1;
298 pDOSHeader
= (PIMAGE_DOS_HEADER
) &__ImageBase
;
299 if (pDOSHeader
->e_magic
!= IMAGE_DOS_SIGNATURE
)
302 pPEHeader
= (PIMAGE_NT_HEADERS
)((char *)pDOSHeader
+ pDOSHeader
->e_lfanew
);
303 if (pPEHeader
->Signature
!= IMAGE_NT_SIGNATURE
)
306 pNTHeader32
= (PIMAGE_OPTIONAL_HEADER32
) &pPEHeader
->OptionalHeader
;
307 switch (pNTHeader32
->Magic
)
309 case IMAGE_NT_OPTIONAL_HDR32_MAGIC
:
310 if (pNTHeader32
->NumberOfRvaAndSizes
<= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
)
312 return !! pNTHeader32
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].VirtualAddress
;
313 case IMAGE_NT_OPTIONAL_HDR64_MAGIC
:
314 pNTHeader64
= (PIMAGE_OPTIONAL_HEADER64
)pNTHeader32
;
315 if (pNTHeader64
->NumberOfRvaAndSizes
<= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
)
317 return !! pNTHeader64
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].VirtualAddress
;
322 int __defaultmatherr
;
325 _gnu_exception_handler (EXCEPTION_POINTERS
* exception_data
)
327 void (*old_handler
) (int);
328 long action
= EXCEPTION_CONTINUE_SEARCH
;
331 switch (exception_data
->ExceptionRecord
->ExceptionCode
)
333 case EXCEPTION_ACCESS_VIOLATION
:
334 /* test if the user has set SIGSEGV */
335 old_handler
= signal (SIGSEGV
, SIG_DFL
);
336 if (old_handler
== SIG_IGN
)
338 /* this is undefined if the signal was raised by anything other
340 signal (SIGSEGV
, SIG_IGN
);
341 action
= EXCEPTION_CONTINUE_EXECUTION
;
343 else if (old_handler
!= SIG_DFL
)
345 /* This means 'old' is a user defined function. Call it */
346 (*old_handler
) (SIGSEGV
);
347 action
= EXCEPTION_CONTINUE_EXECUTION
;
351 case EXCEPTION_ILLEGAL_INSTRUCTION
:
352 case EXCEPTION_PRIV_INSTRUCTION
:
353 /* test if the user has set SIGILL */
354 old_handler
= signal (SIGILL
, SIG_DFL
);
355 if (old_handler
== SIG_IGN
)
357 /* this is undefined if the signal was raised by anything other
359 signal (SIGILL
, SIG_IGN
);
360 action
= EXCEPTION_CONTINUE_EXECUTION
;
362 else if (old_handler
!= SIG_DFL
)
364 /* This means 'old' is a user defined function. Call it */
365 (*old_handler
) (SIGILL
);
366 action
= EXCEPTION_CONTINUE_EXECUTION
;
370 case EXCEPTION_FLT_INVALID_OPERATION
:
371 case EXCEPTION_FLT_DIVIDE_BY_ZERO
:
372 case EXCEPTION_FLT_DENORMAL_OPERAND
:
373 case EXCEPTION_FLT_OVERFLOW
:
374 case EXCEPTION_FLT_UNDERFLOW
:
375 case EXCEPTION_FLT_INEXACT_RESULT
:
379 case EXCEPTION_INT_DIVIDE_BY_ZERO
:
380 /* test if the user has set SIGFPE */
381 old_handler
= signal (SIGFPE
, SIG_DFL
);
382 if (old_handler
== SIG_IGN
)
384 signal (SIGFPE
, SIG_IGN
);
387 action
= EXCEPTION_CONTINUE_EXECUTION
;
389 else if (old_handler
!= SIG_DFL
)
391 /* This means 'old' is a user defined function. Call it */
392 (*old_handler
) (SIGFPE
);
393 action
= EXCEPTION_CONTINUE_EXECUTION
;
404 static LONG
__mingw_vex(EXCEPTION_POINTERS
* exception_data
)
406 /* TODO this is not chainablem, therefore need rewrite. Disabled the ill code. */
409 __asm__
__volatile__ (
410 "movq %gs:0,%rax" "\n\t"
417 __asm__
__volatile__ (
418 "movl %fs:0,%eax" "\n\t"
425 return _gnu_exception_handler(exception_data
);
431 static size_t wbytelen(const wchar_t *p
)
439 static void duplicate_ppstrings (int ac
, wchar_t ***av
)
443 wchar_t **n
= (wchar_t **) malloc (sizeof (wchar_t *) * (ac
+ 1));
446 for (i
=0; i
< ac
; i
++)
448 int l
= wbytelen (avl
[i
]);
449 n
[i
] = (wchar_t *) malloc (l
);
450 memcpy (n
[i
], avl
[i
], l
);
456 static void duplicate_ppstrings (int ac
, char ***av
)
460 char **n
= (char **) malloc (sizeof (char *) * (ac
+ 1));
463 for (i
=0; i
< ac
; i
++)
465 int l
= strlen (avl
[i
]) + 1;
466 n
[i
] = (char *) malloc (l
);
467 memcpy (n
[i
], avl
[i
], l
);