This is part of the MinGW runtime, but we compile DLLs without the runtime. Accordingly we will need this in order to bundle winpthreads.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/msvcrt/Makefile.in | 1 + dlls/msvcrt/crt_handler.c | 121 ++++++++++++++++++++++++++++++++++++++ dlls/ucrtbase/Makefile.in | 1 + 3 files changed, 123 insertions(+) create mode 100644 dlls/msvcrt/crt_handler.c
diff --git a/dlls/msvcrt/Makefile.in b/dlls/msvcrt/Makefile.in index e8a510d9937..c20ba7e0c07 100644 --- a/dlls/msvcrt/Makefile.in +++ b/dlls/msvcrt/Makefile.in @@ -9,6 +9,7 @@ C_SRCS = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_handler.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/msvcrt/crt_handler.c b/dlls/msvcrt/crt_handler.c new file mode 100644 index 00000000000..d4e397a739d --- /dev/null +++ b/dlls/msvcrt/crt_handler.c @@ -0,0 +1,121 @@ +/** + * 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. + */ + +#if 0 +#pragma makedep implib +#endif + +#include <float.h> +#include <signal.h> +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" + +LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler = NULL; + +long CALLBACK +_gnu_exception_handler (EXCEPTION_POINTERS *exception_data); + +#define GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C' | (1U << 29)) + +long CALLBACK +_gnu_exception_handler (EXCEPTION_POINTERS *exception_data) +{ + void (*old_handler) (int); + long action = EXCEPTION_CONTINUE_SEARCH; + int reset_fpu = 0; + +#ifdef __SEH__ + if ((exception_data->ExceptionRecord->ExceptionCode & 0x20ffffff) == GCC_MAGIC) + { + if ((exception_data->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) == 0) + return EXCEPTION_CONTINUE_EXECUTION; + } +#endif + + switch (exception_data->ExceptionRecord->ExceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + /* test if the user has set SIGSEGV */ + old_handler = signal (SIGSEGV, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGSEGV, SIG_IGN); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGSEGV); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: + /* test if the user has set SIGILL */ + old_handler = signal (SIGILL, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGILL, SIG_IGN); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGILL); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_UNDERFLOW: + case EXCEPTION_FLT_INEXACT_RESULT: + reset_fpu = 1; + /* fall through. */ + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + /* test if the user has set SIGFPE */ + old_handler = signal (SIGFPE, SIG_DFL); + if (old_handler == SIG_IGN) + { + signal (SIGFPE, SIG_IGN); + if (reset_fpu) + _fpreset (); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGFPE); + 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; + } + + if (action == EXCEPTION_CONTINUE_SEARCH && __mingw_oldexcpt_handler) + action = (*__mingw_oldexcpt_handler)(exception_data); + return action; +} diff --git a/dlls/ucrtbase/Makefile.in b/dlls/ucrtbase/Makefile.in index bf7f62ada8a..6683c71c3ec 100644 --- a/dlls/ucrtbase/Makefile.in +++ b/dlls/ucrtbase/Makefile.in @@ -9,6 +9,7 @@ C_SRCS = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_handler.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \