/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the w64 mingw-runtime package.
- * No warranty is given; refer to the file DISCLAIMER within this package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#undef CRTDLL
#include <intrin.h>
#ifndef __winitenv
-extern wchar_t ***_imp____winitenv;
-#define __winitenv (*_imp____winitenv)
+extern wchar_t *** __MINGW_IMP_SYMBOL(__winitenv);
+#define __winitenv (* __MINGW_IMP_SYMBOL(__winitenv))
#endif
#ifndef __initenv
-extern char ***_imp____initenv;
-#define __initenv (*_imp____initenv)
+extern char *** __MINGW_IMP_SYMBOL(__initenv);
+#define __initenv (* __MINGW_IMP_SYMBOL(__initenv))
#endif
/* Hack, for bug in ld. Will be removed soon. */
-#define __ImageBase _image_base__
+#define __ImageBase __MINGW_LSYMBOL(_image_base__)
/* This symbol is defined by ld. */
extern IMAGE_DOS_HEADER __ImageBase;
__declspec(dllimport) void __setusermatherr(int (__cdecl *)(struct _exception *));
-extern int *_imp___fmode;
-extern int *_imp___commode;
+extern int * __MINGW_IMP_SYMBOL(_fmode);
+extern int * __MINGW_IMP_SYMBOL(_commode);
#undef _fmode
extern int _fmode;
-extern int *_imp___commode;
-#define _commode (*_imp___commode)
+extern int * __MINGW_IMP_SYMBOL(_commode);
+#define _commode (* __MINGW_IMP_SYMBOL(_commode))
extern int _dowildcard;
#if defined(__GNUC__)
extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];
+/* TLS initialization hook. */
extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
extern _PVFV *__onexitbegin;
extern int mingw_app_type;
+HINSTANCE __mingw_winmain_hInstance;
+_TCHAR *__mingw_winmain_lpCmdLine;
+DWORD __mingw_winmain_nShowCmd;
+
static int argc;
#ifdef WPRFLAG
extern void __main(void);
static int managedapp;
static int has_cctor = 0;
static _startupinfo startinfo;
+static LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler = NULL;
extern void _pei386_runtime_relocator (void);
static long CALLBACK _gnu_exception_handler (EXCEPTION_POINTERS * exception_data);
-//static LONG __mingw_vex(EXCEPTION_POINTERS * exception_data);
#ifdef WPRFLAG
static void duplicate_ppstrings (int ac, wchar_t ***av);
#else
static int __cdecl pre_c_init (void);
static void __cdecl pre_cpp_init (void);
-
+static void __cdecl __mingw_prepare_except_for_msvcr80_and_higher (void);
_CRTALLOC(".CRT$XIAA") _PIFV mingw_pcinit = pre_c_init;
_CRTALLOC(".CRT$XCAA") _PVFV mingw_pcppinit = pre_cpp_init;
__set_app_type (_CONSOLE_APP);
__onexitbegin = __onexitend = (_PVFV *) _encode_pointer ((_PVFV *)(-1));
- *_imp___fmode = _fmode;
- *_imp___commode = _commode;
+ * __MINGW_IMP_SYMBOL(_fmode) = _fmode;
+ * __MINGW_IMP_SYMBOL(_commode) = _commode;
#ifdef WPRFLAG
_wsetargv();
static int __tmainCRTStartup (void);
+int WinMainCRTStartup (void);
+
int WinMainCRTStartup (void)
{
mingw_app_type = 1;
return __tmainCRTStartup ();
}
+int mainCRTStartup (void);
+
+#ifdef _WIN64
+int __mingw_init_ehandler (void);
+#endif
+
int mainCRTStartup (void)
{
mingw_app_type = 0;
return __tmainCRTStartup ();
}
-
+static
__declspec(noinline) int
__tmainCRTStartup (void)
{
_TCHAR *lpszCommandLine = NULL;
STARTUPINFO StartupInfo;
- BOOL inDoubleQuote = FALSE;
+ WINBOOL inDoubleQuote = FALSE;
memset (&StartupInfo, 0, sizeof (STARTUPINFO));
-
+
if (mingw_app_type)
GetStartupInfo (&StartupInfo);
{
_ASSERTE(__native_startup_state == __initialized);
if (! nested)
(VOID)InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
-
- if (__dyn_tls_init_callback != NULL && _IsNonwritableInCurrentImage ((PBYTE) &__dyn_tls_init_callback))
+
+ if (__dyn_tls_init_callback != NULL)
__dyn_tls_init_callback (NULL, DLL_THREAD_ATTACH, NULL);
-
+
_pei386_runtime_relocator ();
-
-#if defined(__i386__) || defined(_M_IX86)
- __writefsdword(0, 0xffffffff);
+ __mingw_oldexcpt_handler = SetUnhandledExceptionFilter (_gnu_exception_handler);
+#ifdef _WIN64
+ __mingw_init_ehandler ();
#endif
- //AddVectoredExceptionHandler (0, (PVECTORED_EXCEPTION_HANDLER)__mingw_vex);
- SetUnhandledExceptionFilter (_gnu_exception_handler);
-
+ __mingw_prepare_except_for_msvcr80_and_higher ();
+
_fpreset ();
if (mingw_app_type)
#ifdef _MBCS
if (_ismbblead (*lpszCommandLine))
{
- if (lpszCommandLine)
+ if (lpszCommandLine) /* FIXME: Why this check? Should I check for *lpszCommandLine != 0 too? */
lpszCommandLine++;
}
#endif
while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
lpszCommandLine++;
-#ifdef WPRFLAG
- /* C++ initialization.
- gcc inserts this call automatically for a function called main, but not for wmain. */
- __main ();
- mainret = wmain (
- (int) (StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT),
- (wchar_t **) lpszCommandLine, (wchar_t **) (HINSTANCE) &__ImageBase);
-#else
- mainret = main (
- (int) (StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT),
- (char **) lpszCommandLine, (char **) (HINSTANCE) &__ImageBase);
-#endif
+ __mingw_winmain_hInstance = (HINSTANCE) &__ImageBase;
+ __mingw_winmain_lpCmdLine = lpszCommandLine;
+ __mingw_winmain_nShowCmd = StartupInfo.dwFlags & STARTF_USESHOWWINDOW ?
+ StartupInfo.wShowWindow : SW_SHOWDEFAULT;
}
- else
- {
duplicate_ppstrings (argc, &argv);
#ifdef WPRFLAG
__winitenv = envp;
__initenv = envp;
mainret = main (argc, argv, envp);
#endif
- }
if (!managedapp)
exit (mainret);
}
static long CALLBACK
-_gnu_exception_handler (EXCEPTION_POINTERS * exception_data)
+_gnu_exception_handler (EXCEPTION_POINTERS *exception_data)
{
void (*old_handler) (int);
long action = EXCEPTION_CONTINUE_SEARCH;
action = EXCEPTION_CONTINUE_EXECUTION;
}
break;
-
+#ifdef _WIN64
+ case EXCEPTION_DATATYPE_MISALIGNMENT:
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ case EXCEPTION_FLT_STACK_CHECK:
+ case EXCEPTION_INT_OVERFLOW:
+ case EXCEPTION_INVALID_HANDLE:
+ /*case EXCEPTION_POSSIBLE_DEADLOCK: */
+ action = EXCEPTION_CONTINUE_EXECUTION;
+ break;
+#endif
default:
break;
}
- return action;
-}
-#if 0
-static LONG __mingw_vex(EXCEPTION_POINTERS * exception_data)
-{
- /* TODO this is not chainablem, therefore need rewrite. Disabled the ill code. */
- #if 0
- #ifdef _WIN64
- __asm__ __volatile__ (
- "movq %gs:0,%rax" "\n\t"
- "orq %rax,%rax\n\t"
- "jz l1\n\t"
- "jmp *8(%rax)\n\r"
- "l1:\n\t"
- "nop\n");
-#else
- __asm__ __volatile__ (
- "movl %fs:0,%eax" "\n\t"
- "orl %eax,%eax\n\t"
- "jz l1\n\t"
- "jmp *4(%eax)\n\r"
- "l1:\n\t"
- "nop\n");
-#endif
-#endif
- return _gnu_exception_handler(exception_data);
+ if (action == EXCEPTION_CONTINUE_SEARCH && __mingw_oldexcpt_handler)
+ action = (*__mingw_oldexcpt_handler)(exception_data);
+ return action;
}
-#endif
#ifdef WPRFLAG
-
static size_t wbytelen(const wchar_t *p)
{
size_t ret = 1;
char **avl;
int i;
char **n = (char **) malloc (sizeof (char *) * (ac + 1));
-
+
avl=*av;
for (i=0; i < ac; i++)
{
*av = n;
}
#endif
+
+#ifdef __MINGW_SHOW_INVALID_PARAMETER_EXCEPTION
+#define __UNUSED_PARAM_1(x) x
+#else
+#define __UNUSED_PARAM_1 __UNUSED_PARAM
+#endif
+static void
+__mingw_invalidParameterHandler (const wchar_t * __UNUSED_PARAM_1(expression),
+ const wchar_t * __UNUSED_PARAM_1(function),
+ const wchar_t * __UNUSED_PARAM_1(file),
+ unsigned int __UNUSED_PARAM_1(line),
+ uintptr_t __UNUSED_PARAM(pReserved))
+{
+#ifdef __MINGW_SHOW_INVALID_PARAMETER_EXCEPTION
+ wprintf(L"Invalid parameter detected in function %s. File: %s Line: %d\n", function, file, line);
+ wprintf(L"Expression: %s\n", expression);
+#endif
+}
+
+static void __cdecl
+__mingw_prepare_except_for_msvcr80_and_higher (void)
+{
+ _invalid_parameter_handler (*fIPH)(_invalid_parameter_handler) = NULL;
+ HMODULE hmsv = GetModuleHandleA ("msvcr80.dll");
+ if(!hmsv)
+ hmsv = GetModuleHandleA ("msvcr70.dll");
+ if (!hmsv)
+ hmsv = GetModuleHandleA ("msvcrt.dll");
+ if (!hmsv)
+ hmsv = LoadLibraryA ("msvcrt.dll");
+ if (!hmsv)
+ return;
+ fIPH = (_invalid_parameter_handler (*)(_invalid_parameter_handler))
+ GetProcAddress (hmsv, "_set_invalid_parameter_handler");
+ if (fIPH)
+ (*fIPH)(__mingw_invalidParameterHandler);
+}