ReactOS 0.4.15-dev-8100-g1887773
UserModeException.c File Reference
#include "precomp.h"
#include <pseh/pseh2.h>
Include dependency graph for UserModeException.c:

Go to the source code of this file.

Classes

struct  _TEST_ENTRY
 

Macros

#define CPU_FEATURE_VMX   0x01
 
#define CPU_FEATURE_HV   0x02
 
#define FL_INVALID   0
 
#define FL_AMD   0x01
 
#define FL_INTEL   0x02
 
#define FL_CYRIX   0x04
 
#define FL_VIA   0x08
 
#define FL_TM   0x10
 
#define FL_ANY   (FL_AMD | FL_INTEL | FL_CYRIX | FL_VIA | FL_TM)
 
#define FL_VMX   0x20
 
#define FL_HV   0x40
 
#define FL_PRIV   0x100
 
#define FL_ACC   0x200
 
#define FL_INVLS   0x400
 

Typedefs

typedef enum _CPU_VENDOR CPU_VENDOR
 
typedef void(* PFUNC) (void)
 
typedef struct _TEST_ENTRY TEST_ENTRY
 
typedef struct _TEST_ENTRYPTEST_ENTRY
 

Enumerations

enum  _CPU_VENDOR {
  CPU_VENDOR_INTEL , CPU_VENDOR_AMD , CPU_VENDOR_CYRIX , CPU_VENDOR_VIA ,
  CPU_VENDOR_TRANSMETA , CPU_VENDOR_UNKNOWN
}
 

Functions

static CPU_VENDOR DetermineCpuVendor (void)
 
static void DetermineCpuFeatures (void)
 
void Test_SingleInstruction (PVOID RwxMemory, PTEST_ENTRY TestEntry)
 
static void Test_InstructionFaults (void)
 
 START_TEST (UserModeException)
 

Variables

CPU_VENDOR g_CpuVendor
 
ULONG g_CpuFeatures
 
TEST_ENTRY TestEntries []
 

Macro Definition Documentation

◆ CPU_FEATURE_HV

#define CPU_FEATURE_HV   0x02

Definition at line 25 of file UserModeException.c.

◆ CPU_FEATURE_VMX

#define CPU_FEATURE_VMX   0x01

Definition at line 24 of file UserModeException.c.

◆ FL_ACC

#define FL_ACC   0x200

Definition at line 41 of file UserModeException.c.

◆ FL_AMD

#define FL_AMD   0x01

Definition at line 30 of file UserModeException.c.

◆ FL_ANY

#define FL_ANY   (FL_AMD | FL_INTEL | FL_CYRIX | FL_VIA | FL_TM)

Definition at line 35 of file UserModeException.c.

◆ FL_CYRIX

#define FL_CYRIX   0x04

Definition at line 32 of file UserModeException.c.

◆ FL_HV

#define FL_HV   0x40

Definition at line 38 of file UserModeException.c.

◆ FL_INTEL

#define FL_INTEL   0x02

Definition at line 31 of file UserModeException.c.

◆ FL_INVALID

#define FL_INVALID   0

Definition at line 29 of file UserModeException.c.

◆ FL_INVLS

#define FL_INVLS   0x400

Definition at line 42 of file UserModeException.c.

◆ FL_PRIV

#define FL_PRIV   0x100

Definition at line 40 of file UserModeException.c.

◆ FL_TM

#define FL_TM   0x10

Definition at line 34 of file UserModeException.c.

◆ FL_VIA

#define FL_VIA   0x08

Definition at line 33 of file UserModeException.c.

◆ FL_VMX

#define FL_VMX   0x20

Definition at line 37 of file UserModeException.c.

Typedef Documentation

◆ CPU_VENDOR

◆ PFUNC

typedef void(* PFUNC) (void)

Definition at line 27 of file UserModeException.c.

◆ PTEST_ENTRY

◆ TEST_ENTRY

Enumeration Type Documentation

◆ _CPU_VENDOR

Enumerator
CPU_VENDOR_INTEL 
CPU_VENDOR_AMD 
CPU_VENDOR_CYRIX 
CPU_VENDOR_VIA 
CPU_VENDOR_TRANSMETA 
CPU_VENDOR_UNKNOWN 

Definition at line 11 of file UserModeException.c.

12{
@ CPU_VENDOR_CYRIX
@ CPU_VENDOR_TRANSMETA
@ CPU_VENDOR_INTEL
@ CPU_VENDOR_UNKNOWN
@ CPU_VENDOR_AMD
@ CPU_VENDOR_VIA
enum _CPU_VENDOR CPU_VENDOR

Function Documentation

◆ DetermineCpuFeatures()

static void DetermineCpuFeatures ( void  )
static

Definition at line 98 of file UserModeException.c.

99{
100 INT CpuInfo[4];
101 ULONG Features = 0;
102
104
105 __cpuid(CpuInfo, 1);
106 if (CpuInfo[2] & (1 << 5)) Features |= CPU_FEATURE_VMX;
107 if (CpuInfo[2] & (1 << 31)) Features |= CPU_FEATURE_HV;
108 trace("CPUID 1: 0x%x, 0x%x, 0x%x, 0x%x\n", CpuInfo[0], CpuInfo[1], CpuInfo[2], CpuInfo[3]);
109
110 g_CpuFeatures = Features;
111}
#define CPU_FEATURE_VMX
CPU_VENDOR g_CpuVendor
#define CPU_FEATURE_HV
static CPU_VENDOR DetermineCpuVendor(void)
ULONG g_CpuFeatures
#define trace
Definition: atltest.h:70
PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
Definition: intrin_ppc.h:682
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59

Referenced by START_TEST().

◆ DetermineCpuVendor()

static CPU_VENDOR DetermineCpuVendor ( void  )
static

Definition at line 54 of file UserModeException.c.

55{
56 INT CpuInfo[4];
57 union
58 {
59 INT ShuffledInts[3];
60 CHAR VendorString[13];
61 } Vendor;
62
63 __cpuid(CpuInfo, 0);
64 Vendor.ShuffledInts[0] = CpuInfo[1];
65 Vendor.ShuffledInts[1] = CpuInfo[3];
66 Vendor.ShuffledInts[2] = CpuInfo[2];
67 Vendor.VendorString[12] = 0;
68 trace("Vendor: %s\n", Vendor.VendorString);
69
70 if (strcmp(Vendor.VendorString, "GenuineIntel") == 0)
71 {
72 return CPU_VENDOR_INTEL;
73 }
74 else if (strcmp(Vendor.VendorString, "AuthenticAMD") == 0)
75 {
76 return CPU_VENDOR_AMD;
77 }
78 else if (strcmp(Vendor.VendorString, "CyrixInstead") == 0)
79 {
80 return CPU_VENDOR_CYRIX;
81 }
82 else if (strcmp(Vendor.VendorString, "CentaurHauls") == 0)
83 {
84 return CPU_VENDOR_VIA;
85 }
86 else if (strcmp(Vendor.VendorString, "GenuineTMx86") == 0)
87 {
89 }
90 else
91 {
92 return CPU_VENDOR_UNKNOWN;
93 }
94}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char CHAR
Definition: xmlstorage.h:175

Referenced by DetermineCpuFeatures().

◆ START_TEST()

START_TEST ( UserModeException  )

Definition at line 319 of file UserModeException.c.

320{
322
324}
static void DetermineCpuFeatures(void)
static void Test_InstructionFaults(void)

◆ Test_InstructionFaults()

static void Test_InstructionFaults ( void  )
static

Definition at line 294 of file UserModeException.c.

295{
296 PVOID RwxMemory;
297 ULONG i;
298
299 /* Allocate a page of RWX memory */
300 RwxMemory = VirtualAlloc(NULL,
301 PAGE_SIZE,
304 ok(RwxMemory != NULL, "Failed to allocate RWX memory!\n");
305 if (RwxMemory == NULL)
306 {
307 return;
308 }
309
310 for (i = 0; i < ARRAYSIZE(TestEntries); i++)
311 {
313 }
314
315 /* Clean up */
316 VirtualFree(RwxMemory, 0, MEM_RELEASE);
317}
TEST_ENTRY TestEntries[]
void Test_SingleInstruction(PVOID RwxMemory, PTEST_ENTRY TestEntry)
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define PAGE_SIZE
Definition: env_spec_w32.h:49
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MEM_RESERVE
Definition: nt_native.h:1314
#define MEM_RELEASE
Definition: nt_native.h:1316
#define MEM_COMMIT
Definition: nt_native.h:1313
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:65
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:119

Referenced by START_TEST().

◆ Test_SingleInstruction()

void Test_SingleInstruction ( PVOID  RwxMemory,
PTEST_ENTRY  TestEntry 
)

Definition at line 201 of file UserModeException.c.

204{
205 PEXCEPTION_POINTERS ExcPtrs;
206 EXCEPTION_RECORD ExceptionRecord;
207 NTSTATUS ExpectedStatus, Status = STATUS_SUCCESS;
208 PFUNC Func = (PFUNC)RwxMemory;
209 ULONG Flags;
210
211 RtlZeroMemory(&ExceptionRecord, sizeof(ExceptionRecord));
212
213 RtlCopyMemory(RwxMemory,
214 TestEntry->InstructionBytes,
215 sizeof(TestEntry->InstructionBytes));
216
218 {
219 Func();
220 }
222 ExceptionRecord = *ExcPtrs->ExceptionRecord,
224 {
226 }
227 _SEH2_END;
228
229 Flags = TestEntry->Flags;
230#ifdef _M_IX86
231 if (Flags & FL_INVLS)
232 {
233 ExpectedStatus = STATUS_INVALID_LOCK_SEQUENCE;
234 }
235 else
236#endif
237 if (((g_CpuVendor == CPU_VENDOR_INTEL) && !(Flags & FL_INTEL)) ||
238 ((g_CpuVendor == CPU_VENDOR_AMD) && !(Flags & FL_AMD)) ||
240 ((g_CpuVendor == CPU_VENDOR_VIA) && !(Flags & FL_VIA)))
241 {
242 ExpectedStatus = STATUS_ILLEGAL_INSTRUCTION;
243 }
244 else if (((Flags & FL_VMX) && !(g_CpuFeatures & CPU_FEATURE_VMX)) ||
246 {
247 ExpectedStatus = STATUS_ILLEGAL_INSTRUCTION;
248 }
249 else if (Flags & FL_PRIV)
250 {
251 ExpectedStatus = STATUS_PRIVILEGED_INSTRUCTION;
252 }
253 else if (Flags & FL_ACC)
254 {
255 ExpectedStatus = STATUS_ACCESS_VIOLATION;
256 }
257 else
258 {
259 ExpectedStatus = STATUS_SUCCESS;
260 }
261
262 ok_hex_(__FILE__, TestEntry->Line, Status, ExpectedStatus);
263 ok_hex_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionCode, Status);
264 ok_hex_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionFlags, 0);
265 ok_ptr_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionRecord, NULL);
266
267 if (Status == STATUS_SUCCESS)
268 {
269 ok_ptr_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionAddress, NULL);
270 }
271 else
272 {
273 ok_ptr_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionAddress, (PUCHAR)Func + TestEntry->ExpectedAddressOffset);
274 }
275
277 {
278 ok_dec_(__FILE__, TestEntry->Line, ExceptionRecord.NumberParameters, 2);
279 ok_size_t_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionInformation[0], 0);
280 ok_size_t_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionInformation[1], (LONG_PTR)-1);
281 }
282 else
283 {
284 ok_dec_(__FILE__, TestEntry->Line, ExceptionRecord.NumberParameters, 0);
285#if 0 // FIXME: These are inconsistent between Windows versions (simply uninitialized?)
286 ok_size_t_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionInformation[0], 0);
287 ok_size_t_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionInformation[1], 0);
288#endif
289 }
290}
#define ok_hex_(expression, result)
static void TestEntry(const ENTRY *pEntry)
#define FL_VIA
#define FL_AMD
#define FL_ACC
void(* PFUNC)(void)
#define FL_INTEL
#define FL_INVLS
#define FL_CYRIX
#define FL_VMX
#define FL_HV
#define FL_PRIV
LONG NTSTATUS
Definition: precomp.h:26
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define STATUS_ILLEGAL_INSTRUCTION
Definition: ntstatus.h:266
#define STATUS_PRIVILEGED_INSTRUCTION
Definition: ntstatus.h:386
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_INVALID_LOCK_SEQUENCE
Definition: ntstatus.h:267
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
void(* Func)(int)
#define ok_size_t_(file, line, expression, result)
Definition: test.h:970
#define ok_ptr_(file, line, expression, result)
Definition: test.h:961
#define ok_dec_(file, line, expression, result)
Definition: test.h:952
#define STATUS_SUCCESS
Definition: shellext.h:65
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
PVOID ExceptionAddress
Definition: compat.h:211
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by Test_InstructionFaults().

Variable Documentation

◆ g_CpuFeatures

ULONG g_CpuFeatures

Definition at line 22 of file UserModeException.c.

Referenced by DetermineCpuFeatures(), and Test_SingleInstruction().

◆ g_CpuVendor

CPU_VENDOR g_CpuVendor

Definition at line 21 of file UserModeException.c.

Referenced by DetermineCpuFeatures(), and Test_SingleInstruction().

◆ TestEntries

TEST_ENTRY TestEntries[]

Definition at line 113 of file UserModeException.c.

Referenced by Test_InstructionFaults().