[PATCH 4/9] msvcrt: Import _gnu_exception_handler() from MinGW.
Zebediah Figura
zfigura at codeweavers.com
Mon Nov 29 11:01:17 CST 2021
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 at 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 \
--
2.34.0
More information about the wine-devel
mailing list