mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
98 lines
2.9 KiB
C
98 lines
2.9 KiB
C
#include <precomp.h>
|
|
#include "internal/wine/msvcrt.h"
|
|
#include "internal/wine/cppexcept.h"
|
|
|
|
typedef void (*sighandler_t)(int);
|
|
static sighandler_t sighandlers[NSIG] = { SIG_DFL };
|
|
|
|
/* The exception codes are actually NTSTATUS values */
|
|
static const struct
|
|
{
|
|
NTSTATUS status;
|
|
int signal;
|
|
} float_exception_map[] = {
|
|
{ EXCEPTION_FLT_DENORMAL_OPERAND, _FPE_DENORMAL },
|
|
{ EXCEPTION_FLT_DIVIDE_BY_ZERO, _FPE_ZERODIVIDE },
|
|
{ EXCEPTION_FLT_INEXACT_RESULT, _FPE_INEXACT },
|
|
{ EXCEPTION_FLT_INVALID_OPERATION, _FPE_INVALID },
|
|
{ EXCEPTION_FLT_OVERFLOW, _FPE_OVERFLOW },
|
|
{ EXCEPTION_FLT_STACK_CHECK, _FPE_STACKOVERFLOW },
|
|
{ EXCEPTION_FLT_UNDERFLOW, _FPE_UNDERFLOW },
|
|
};
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
int CDECL
|
|
_XcptFilter(NTSTATUS ExceptionCode,
|
|
struct _EXCEPTION_POINTERS * except)
|
|
{
|
|
LONG ret = EXCEPTION_CONTINUE_SEARCH;
|
|
sighandler_t handler;
|
|
|
|
if (!except || !except->ExceptionRecord)
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
|
|
switch (except->ExceptionRecord->ExceptionCode)
|
|
{
|
|
case EXCEPTION_ACCESS_VIOLATION:
|
|
if ((handler = sighandlers[SIGSEGV]) != SIG_DFL)
|
|
{
|
|
if (handler != SIG_IGN)
|
|
{
|
|
sighandlers[SIGSEGV] = SIG_DFL;
|
|
handler(SIGSEGV);
|
|
}
|
|
ret = EXCEPTION_CONTINUE_EXECUTION;
|
|
}
|
|
break;
|
|
/* According to msdn,
|
|
* the FPE signal handler takes as a second argument the type of
|
|
* floating point exception.
|
|
*/
|
|
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
|
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
|
case EXCEPTION_FLT_INEXACT_RESULT:
|
|
case EXCEPTION_FLT_INVALID_OPERATION:
|
|
case EXCEPTION_FLT_OVERFLOW:
|
|
case EXCEPTION_FLT_STACK_CHECK:
|
|
case EXCEPTION_FLT_UNDERFLOW:
|
|
if ((handler = sighandlers[SIGFPE]) != SIG_DFL)
|
|
{
|
|
if (handler != SIG_IGN)
|
|
{
|
|
unsigned int i;
|
|
int float_signal = _FPE_INVALID;
|
|
|
|
sighandlers[SIGFPE] = SIG_DFL;
|
|
for (i = 0; i < sizeof(float_exception_map) /
|
|
sizeof(float_exception_map[0]); i++)
|
|
{
|
|
if (float_exception_map[i].status ==
|
|
except->ExceptionRecord->ExceptionCode)
|
|
{
|
|
float_signal = float_exception_map[i].signal;
|
|
break;
|
|
}
|
|
}
|
|
((float_handler)handler)(SIGFPE, float_signal);
|
|
}
|
|
ret = EXCEPTION_CONTINUE_EXECUTION;
|
|
}
|
|
break;
|
|
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
|
case EXCEPTION_PRIV_INSTRUCTION:
|
|
if ((handler = sighandlers[SIGILL]) != SIG_DFL)
|
|
{
|
|
if (handler != SIG_IGN)
|
|
{
|
|
sighandlers[SIGILL] = SIG_DFL;
|
|
handler(SIGILL);
|
|
}
|
|
ret = EXCEPTION_CONTINUE_EXECUTION;
|
|
}
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|