e294e127a81a770086f808f673d96e621aa745aa
[reactos.git] / reactos / lib / sdk / crt / except / xcptfil.c
1 #include <precomp.h>
2 #include "internal/wine/msvcrt.h"
3 #include "internal/wine/cppexcept.h"
4
5 typedef void (*sighandler_t)(int);
6 static sighandler_t sighandlers[NSIG] = { SIG_DFL };
7
8 /* The exception codes are actually NTSTATUS values */
9 static const struct
10 {
11 NTSTATUS status;
12 int signal;
13 } float_exception_map[] = {
14 { EXCEPTION_FLT_DENORMAL_OPERAND, _FPE_DENORMAL },
15 { EXCEPTION_FLT_DIVIDE_BY_ZERO, _FPE_ZERODIVIDE },
16 { EXCEPTION_FLT_INEXACT_RESULT, _FPE_INEXACT },
17 { EXCEPTION_FLT_INVALID_OPERATION, _FPE_INVALID },
18 { EXCEPTION_FLT_OVERFLOW, _FPE_OVERFLOW },
19 { EXCEPTION_FLT_STACK_CHECK, _FPE_STACKOVERFLOW },
20 { EXCEPTION_FLT_UNDERFLOW, _FPE_UNDERFLOW },
21 };
22
23 /*
24 * @implemented
25 */
26 int
27 _XcptFilter(DWORD ExceptionCode,
28 struct _EXCEPTION_POINTERS * except)
29 {
30 LONG ret = EXCEPTION_CONTINUE_SEARCH;
31 sighandler_t handler;
32
33 if (!except || !except->ExceptionRecord)
34 return EXCEPTION_CONTINUE_SEARCH;
35
36 switch (except->ExceptionRecord->ExceptionCode)
37 {
38 case EXCEPTION_ACCESS_VIOLATION:
39 if ((handler = sighandlers[SIGSEGV]) != SIG_DFL)
40 {
41 if (handler != SIG_IGN)
42 {
43 sighandlers[SIGSEGV] = SIG_DFL;
44 handler(SIGSEGV);
45 }
46 ret = EXCEPTION_CONTINUE_EXECUTION;
47 }
48 break;
49 /* According to msdn,
50 * the FPE signal handler takes as a second argument the type of
51 * floating point exception.
52 */
53 case EXCEPTION_FLT_DENORMAL_OPERAND:
54 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
55 case EXCEPTION_FLT_INEXACT_RESULT:
56 case EXCEPTION_FLT_INVALID_OPERATION:
57 case EXCEPTION_FLT_OVERFLOW:
58 case EXCEPTION_FLT_STACK_CHECK:
59 case EXCEPTION_FLT_UNDERFLOW:
60 if ((handler = sighandlers[SIGFPE]) != SIG_DFL)
61 {
62 if (handler != SIG_IGN)
63 {
64 int i, float_signal = _FPE_INVALID;
65
66 sighandlers[SIGFPE] = SIG_DFL;
67 for (i = 0; i < sizeof(float_exception_map) /
68 sizeof(float_exception_map[0]); i++)
69 {
70 if (float_exception_map[i].status ==
71 except->ExceptionRecord->ExceptionCode)
72 {
73 float_signal = float_exception_map[i].signal;
74 break;
75 }
76 }
77 ((float_handler)handler)(SIGFPE, float_signal);
78 }
79 ret = EXCEPTION_CONTINUE_EXECUTION;
80 }
81 break;
82 case EXCEPTION_ILLEGAL_INSTRUCTION:
83 if ((handler = sighandlers[SIGILL]) != SIG_DFL)
84 {
85 if (handler != SIG_IGN)
86 {
87 sighandlers[SIGILL] = SIG_DFL;
88 handler(SIGILL);
89 }
90 ret = EXCEPTION_CONTINUE_EXECUTION;
91 }
92 break;
93 }
94 return ret;
95 }
96
97 int CDECL __CppXcptFilter(unsigned long ex, PEXCEPTION_POINTERS ptr)
98 {
99 /* only filter c++ exceptions */
100 if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH;
101 return _XcptFilter( ex, ptr );
102 }
103
104
105
106
107