use secret sauce to clear MXCSR in win32 context, and handle secret STATUS_FLOAT_MULTIPLE_* SEH codes raised by SSE traps
parent
578c977a7e
commit
c1bc5f22e4
|
@ -4,4 +4,33 @@ namespace factor
|
|||
#define ESP Esp
|
||||
#define EIP Eip
|
||||
|
||||
typedef struct DECLSPEC_ALIGN(16) _M128A {
|
||||
ULONGLONG Low;
|
||||
LONGLONG High;
|
||||
} M128A, *PM128A;
|
||||
|
||||
/* The ExtendedRegisters field of the x86.32 CONTEXT structure uses this layout; however,
|
||||
* this structure is only made available from winnt.h on x86.64 */
|
||||
typedef struct _XMM_SAVE_AREA32 {
|
||||
WORD ControlWord; /* 000 */
|
||||
WORD StatusWord; /* 002 */
|
||||
BYTE TagWord; /* 004 */
|
||||
BYTE Reserved1; /* 005 */
|
||||
WORD ErrorOpcode; /* 006 */
|
||||
DWORD ErrorOffset; /* 008 */
|
||||
WORD ErrorSelector; /* 00c */
|
||||
WORD Reserved2; /* 00e */
|
||||
DWORD DataOffset; /* 010 */
|
||||
WORD DataSelector; /* 014 */
|
||||
WORD Reserved3; /* 016 */
|
||||
DWORD MxCsr; /* 018 */
|
||||
DWORD MxCsr_Mask; /* 01c */
|
||||
M128A FloatRegisters[8]; /* 020 */
|
||||
M128A XmmRegisters[16]; /* 0a0 */
|
||||
BYTE Reserved4[96]; /* 1a0 */
|
||||
} XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
|
||||
|
||||
#define X87SW(ctx) (ctx)->FloatSave.StatusWord
|
||||
#define MXCSR(ctx) ((XMM_SAVE_AREA32*)((ctx)->ExtendedRegisters))->MxCsr
|
||||
|
||||
}
|
||||
|
|
|
@ -4,4 +4,7 @@ namespace factor
|
|||
#define ESP Rsp
|
||||
#define EIP Rip
|
||||
|
||||
#define X87SW(ctx) (ctx)->FloatSave.StatusWord
|
||||
#define MXCSR(ctx) (ctx)->MxCsr
|
||||
|
||||
}
|
||||
|
|
|
@ -28,16 +28,18 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
|
|||
c->EIP = (cell)memory_signal_handler_impl;
|
||||
break;
|
||||
|
||||
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:
|
||||
/* XXX MxCsr is not available in CONTEXT structure on x86.32 */
|
||||
signal_fpu_status = c->FloatSave.StatusWord;
|
||||
c->FloatSave.StatusWord = 0;
|
||||
case STATUS_FLOAT_DENORMAL_OPERAND:
|
||||
case STATUS_FLOAT_DIVIDE_BY_ZERO:
|
||||
case STATUS_FLOAT_INEXACT_RESULT:
|
||||
case STATUS_FLOAT_INVALID_OPERATION:
|
||||
case STATUS_FLOAT_OVERFLOW:
|
||||
case STATUS_FLOAT_STACK_CHECK:
|
||||
case STATUS_FLOAT_UNDERFLOW:
|
||||
case STATUS_FLOAT_MULTIPLE_FAULTS:
|
||||
case STATUS_FLOAT_MULTIPLE_TRAPS:
|
||||
signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
|
||||
X87SW(c) = 0;
|
||||
MXCSR(c) &= 0xffffffc0;
|
||||
c->EIP = (cell)fp_signal_handler_impl;
|
||||
break;
|
||||
case 0x40010006:
|
||||
|
|
|
@ -23,4 +23,9 @@ void c_to_factor_toplevel(cell quot);
|
|||
FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe);
|
||||
void open_console();
|
||||
|
||||
// SSE traps raise these exception codes, which are defined in internal NT headers
|
||||
// but not winbase.h
|
||||
#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4
|
||||
#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue