ReactOS 0.4.15-dev-7674-gc0b4db1
SetUnhandledExceptionFilter.c File Reference
#include "precomp.h"
#include <xmmintrin.h>
Include dependency graph for SetUnhandledExceptionFilter.c:

Go to the source code of this file.

Functions

LONG WINAPI Filter1 (LPEXCEPTION_POINTERS p)
 
LONG WINAPI Filter2 (LPEXCEPTION_POINTERS p)
 
static VOID TestSetUnhandledExceptionFilter (VOID)
 
static LONG WINAPI ExceptionFilterSSESupport (LPEXCEPTION_POINTERS exp)
 
static LONG WINAPI ExceptionFilterSSEException (LPEXCEPTION_POINTERS exp)
 
static VOID TestSSEExceptions (VOID)
 
 START_TEST (SetUnhandledExceptionFilter)
 

Variables

static BOOL ExceptionCaught = FALSE
 

Function Documentation

◆ ExceptionFilterSSEException()

static LONG WINAPI ExceptionFilterSSEException ( LPEXCEPTION_POINTERS  exp)
static

Definition at line 70 of file SetUnhandledExceptionFilter.c.

71{
72 PEXCEPTION_RECORD rec = exp->ExceptionRecord;
73 PCONTEXT ctx = exp->ContextRecord;
74#ifdef _M_AMD64
75 ULONG ExpectedExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
76#else
77 ULONG ExpectedExceptionCode = STATUS_FLOAT_MULTIPLE_TRAPS;
78#endif
79
80 trace("Exception raised while dividing by 0.\n");
81
82 ok(rec->ExceptionCode == ExpectedExceptionCode, "Exception code is 0x%08x.\n", (unsigned int)rec->ExceptionCode);
83
84 if(rec->ExceptionCode != ExpectedExceptionCode)
85 {
86 trace("Unexpected exception code, terminating!\n");
88 }
89
90 ok((ctx->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL, "Context does not contain control register.\n");
91
93
94#ifdef _M_IX86
95 ctx->Eip += 3;
96#elif defined(_M_AMD64)
97 ctx->Rip += 3;
98#else
99#error Architecture not handled
100#endif
101
103}
static BOOL ExceptionCaught
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define TRUE
Definition: types.h:120
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87
DWORD exp
Definition: msg.c:16058
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
#define STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:378
#define STATUS_FLOAT_MULTIPLE_TRAPS
Definition: ntstatus.h:808
DWORD ExceptionCode
Definition: compat.h:208
uint32_t ULONG
Definition: typedefs.h:59

Referenced by TestSSEExceptions().

◆ ExceptionFilterSSESupport()

static LONG WINAPI ExceptionFilterSSESupport ( LPEXCEPTION_POINTERS  exp)
static

Definition at line 40 of file SetUnhandledExceptionFilter.c.

41{
42 PEXCEPTION_RECORD rec = exp->ExceptionRecord;
43 PCONTEXT ctx = exp->ContextRecord;
44
45 trace("Exception raised while using SSE instructions.\n");
46
47 ok(rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION, "Exception code is 0x%08x.\n", (unsigned int)rec->ExceptionCode);
48
50 {
51 trace("Unexpected exception code, terminating!\n");
53 }
54
55 ok((ctx->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL, "Context does not contain control register.\n");
56
57#ifdef _M_IX86
58 ctx->Eip += 3;
59#elif defined(_M_AMD64)
60 ctx->Rip += 3;
61#else
62#error Architecture not handled
63#endif
64
66}
#define EXCEPTION_ILLEGAL_INSTRUCTION
Definition: winbase.h:327

Referenced by TestSSEExceptions().

◆ Filter1()

Definition at line 16 of file SetUnhandledExceptionFilter.c.

16{ return 0; }

Referenced by TestSetUnhandledExceptionFilter().

◆ Filter2()

Definition at line 17 of file SetUnhandledExceptionFilter.c.

17{ return 1; }

Referenced by TestSetUnhandledExceptionFilter().

◆ START_TEST()

START_TEST ( SetUnhandledExceptionFilter  )

Definition at line 200 of file SetUnhandledExceptionFilter.c.

201{
204}
static VOID TestSetUnhandledExceptionFilter(VOID)
static VOID TestSSEExceptions(VOID)

◆ TestSetUnhandledExceptionFilter()

static VOID TestSetUnhandledExceptionFilter ( VOID  )
static

Definition at line 26 of file SetUnhandledExceptionFilter.c.

27{
31 ok(p1 != Filter1, "SetUnhandledExceptionFilter returned what was set, not prev\n");
32 ok(p2 != Filter2, "SetUnhandledExceptionFilter returned what was set, not prev\n");
33 ok(p2 == Filter1, "SetUnhandledExceptionFilter didn't return previous filter\n");
34 ok(p1 != p2, "SetUnhandledExceptionFilter seems to return random stuff\n");
35
37 ok(p1 == Filter2, "SetUnhandledExceptionFilter didn't return previous filter\n");
38}
LONG WINAPI Filter1(LPEXCEPTION_POINTERS p)
LONG WINAPI Filter2(LPEXCEPTION_POINTERS p)
#define NULL
Definition: types.h:112
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI DECLSPEC_HOTPATCH SetUnhandledExceptionFilter(IN LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
Definition: except.c:790
PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER
Definition: winbase.h:1453

Referenced by START_TEST().

◆ TestSSEExceptions()

static VOID TestSSEExceptions ( VOID  )
static

Definition at line 109 of file SetUnhandledExceptionFilter.c.

110{
112 unsigned int csr;
113
114 /* Test SSE support for the CPU */
116 ok(p == NULL, "Previous filter should be NULL\n");
117
118#if !defined(_M_AMD64)
119 {
120 BOOL supportsSSE = FALSE;
121#ifdef _MSC_VER
122 __asm
123 {
124 xorps xmm0, xmm0
125 mov supportsSSE, 0x1
126 }
127#else
128 __asm__(
129 "xorps %%xmm0, %%xmm0\n"
130 "movl $1, %0\n"
131 : "=r"(supportsSSE)
132 );
133#endif /* _MSC_VER */
134
135 if(!supportsSSE)
136 {
137 skip("CPU doesn't support SSE instructions.\n");
139 return;
140 }
141 }
142#endif /* !defined(_M_AMD64) */
143
144 /* Deliberately throw a divide by 0 exception */
146 ok(p == ExceptionFilterSSESupport, "Unexpected old filter : 0x%p", p);
147
148 /* Unmask divide by 0 exception */
149 csr = _mm_getcsr();
150 _mm_setcsr(csr & 0xFFFFFDFF);
151
152 /* We can't use _mm_div_ps, as it masks the exception before performing anything*/
153#if defined(_MSC_VER)
154#if defined(_M_AMD64)
155 {
156 __m128 xmm1 = { { 1., 1. } }, xmm2 = { { 0 } };
157 /* Wait, aren't exceptions masked? Yes, but actually no. */
158 xmm1 = _mm_div_ps(xmm1, xmm2);
159 }
160#else
161 __asm
162 {
163 xorps xmm0, xmm0
164 push 0x3f800000
165 push 0x3f800000
166 push 0x3f800000
167 push 0x3f800000
168
169 movups xmm1, [esp]
170
171 /* Divide by 0 */
172 divps xmm1, xmm0
173
174 /* Clean up */
175 add esp, 16
176 }
177#endif
178#else
179 ULONG zeros[4] = {0, 0, 0, 0};
180 ULONG ones[4] = {0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000};
181 __asm__ (
182 "movups (%0), %%xmm0\n"
183 "movups (%1), %%xmm1\n"
184 /* Divide by 0 */
185 "divps %%xmm0, %%xmm1\n"
186
187 : : "r"(&zeros), "r"(&ones) : "xmm0", "xmm1"
188 );
189#endif /* _MSC_VER */
190
191 /* Restore mxcsr */
192 _mm_setcsr(csr);
193
194 ok(ExceptionCaught, "The exception was not caught.\n");
195
197 ok(p == ExceptionFilterSSEException, "Unexpected old filter : 0x%p", p);
198}
static LONG WINAPI ExceptionFilterSSESupport(LPEXCEPTION_POINTERS exp)
static LONG WINAPI ExceptionFilterSSEException(LPEXCEPTION_POINTERS exp)
#define skip(...)
Definition: atltest.h:64
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
GLfloat GLfloat p
Definition: glext.h:8902
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tmov %rdx, %rbp\n" "\tjmp *%rax\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
static void push(calc_node_t *op)
Definition: rpn_ieee.c:113
void _mm_setcsr(unsigned int a)
Definition: xmmintrin.h:542
__m128 _mm_div_ps(__m128 a, __m128 b)
Definition: xmmintrin.h:587
unsigned int _mm_getcsr(void)
Definition: xmmintrin.h:535

Referenced by START_TEST().

Variable Documentation

◆ ExceptionCaught

BOOL ExceptionCaught = FALSE
static

Definition at line 68 of file SetUnhandledExceptionFilter.c.

Referenced by ExceptionFilterSSEException(), and TestSSEExceptions().