[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