ReactOS  0.4.15-dev-5606-gf34e425
except.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for except.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI KeInitExceptions (VOID)
 
static VOID KiDispatchExceptionToUser (IN PKTRAP_FRAME TrapFrame, IN PCONTEXT Context, IN PEXCEPTION_RECORD ExceptionRecord)
 
static VOID KiPageInDirectory (PVOID ImageBase, USHORT Directory)
 
VOID KiPrepareUserDebugData (void)
 
VOID NTAPI KiDispatchException (IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
 
NTSTATUS NTAPI KeRaiseUserException (IN NTSTATUS ExceptionCode)
 
VOID DECLSPEC_NORETURN KiSystemFatalException (IN ULONG ExceptionCode, IN PKTRAP_FRAME TrapFrame)
 
NTSTATUS NTAPI KiNpxNotAvailableFaultHandler (IN PKTRAP_FRAME TrapFrame)
 
static BOOLEAN KiIsPrivilegedInstruction (PUCHAR Ip, BOOLEAN Wow64)
 
static NTSTATUS KiGeneralProtectionFaultUserMode (_In_ PKTRAP_FRAME TrapFrame)
 
NTSTATUS NTAPI KiGeneralProtectionFaultHandler (IN PKTRAP_FRAME TrapFrame)
 
NTSTATUS NTAPI KiXmmExceptionHandler (IN PKTRAP_FRAME TrapFrame)
 

Variables

KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange [256]
 
KIDT_INIT KiInterruptInitTable []
 
KIDTENTRY64 KiIdt [256]
 
KDESCRIPTOR KiIdtDescriptor = {{0}, sizeof(KiIdt) - 1, KiIdt}
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file except.c.

Function Documentation

◆ KeInitExceptions()

VOID NTAPI KeInitExceptions ( VOID  )

Definition at line 59 of file except.c.

60 {
61  int i, j;
62 
63  /* Initialize the Idt */
64  for (j = i = 0; i < 256; i++)
65  {
67 
68  if (KiInterruptInitTable[j].InterruptId == i)
69  {
73  j++;
74  }
75  else
76  {
77  Offset = (ULONG64)&KiUnexpectedRange[i]._Op_push;
78  KiIdt[i].Dpl = 0;
79  KiIdt[i].IstIndex = 0;
80  }
81  KiIdt[i].OffsetLow = Offset & 0xffff;
83  KiIdt[i].Type = 0x0e;
84  KiIdt[i].Reserved0 = 0;
85  KiIdt[i].Present = 1;
86  KiIdt[i].OffsetMiddle = (Offset >> 16) & 0xffff;
87  KiIdt[i].OffsetHigh = (Offset >> 32);
88  KiIdt[i].Reserved1 = 0;
89  }
90 
91  KeGetPcr()->IdtBase = KiIdt;
93 }
UCHAR IstIndex
Definition: ke.h:97
KIDTENTRY64 KiIdt[256]
Definition: except.c:50
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:2018
UCHAR Dpl
Definition: ke.h:96
#define KeGetPcr()
Definition: ke.h:26
USHORT Selector
Definition: ketypes.h:472
USHORT Limit
Definition: ketypes.h:490
USHORT OffsetLow
Definition: ketypes.h:471
USHORT Reserved0
Definition: ketypes.h:474
USHORT Type
Definition: ketypes.h:475
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 GLint GLint j
Definition: glfuncs.h:250
USHORT Present
Definition: ketypes.h:477
USHORT OffsetMiddle
Definition: ketypes.h:478
#define KGDT64_R0_CODE
Definition: ketypes.h:72
USHORT IstIndex
Definition: ketypes.h:473
unsigned __int64 ULONG64
Definition: imports.h:198
USHORT Dpl
Definition: ketypes.h:476
ULONG Reserved1
Definition: ketypes.h:480
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange[256]
KIDT_INIT KiInterruptInitTable[]
Definition: except.c:20
KDESCRIPTOR KiIdtDescriptor
Definition: except.c:51
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
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
ULONG OffsetHigh
Definition: ketypes.h:479
_In_ PKSERVICE_ROUTINE ServiceRoutine
Definition: iofuncs.h:800

◆ KeRaiseUserException()

NTSTATUS NTAPI KeRaiseUserException ( IN NTSTATUS  ExceptionCode)

Definition at line 409 of file except.c.

410 {
412  return STATUS_UNSUCCESSFUL;
413 }
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define UNIMPLEMENTED
Definition: debug.h:115

Referenced by ObpCloseHandle(), and ObpCloseHandleTableEntry().

◆ KiDispatchException()

VOID NTAPI KiDispatchException ( IN PEXCEPTION_RECORD  ExceptionRecord,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN KPROCESSOR_MODE  PreviousMode,
IN BOOLEAN  FirstChance 
)

Definition at line 248 of file except.c.

253 {
255 
256  /* Increase number of Exception Dispatches */
257  KeGetCurrentPrcb()->KeExceptionDispatchCount++;
258 
259  /* Zero out the context to avoid leaking kernel stack memor to user mode */
260  RtlZeroMemory(&Context, sizeof(Context));
261 
262  /* Set the context flags */
263  Context.ContextFlags = CONTEXT_ALL;
264 
265  /* Get the Context from the trap and exception frame */
266  KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
267 
268  /* Look at our exception code */
269  switch (ExceptionRecord->ExceptionCode)
270  {
271  /* Breakpoint */
272  case STATUS_BREAKPOINT:
273 
274  /* Decrement RIP by one */
275  Context.Rip--;
276  break;
277 
278  /* Internal exception */
280 
281  /* Set correct code */
282  ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
283  if (PreviousMode == UserMode)
284  {
285  /* FIXME: Handle no execute */
286  }
287  break;
288  }
289 
290  /* Handle kernel-mode first, it's simpler */
291  if (PreviousMode == KernelMode)
292  {
293  /* Check if this is a first-chance exception */
294  if (FirstChance)
295  {
296  /* Break into the debugger for the first time */
297  if (KiDebugRoutine(TrapFrame,
298  ExceptionFrame,
299  ExceptionRecord,
300  &Context,
301  PreviousMode,
302  FALSE))
303  {
304  /* Exception was handled */
305  goto Handled;
306  }
307 
308  /* If the Debugger couldn't handle it, dispatch the exception */
309  if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled;
310  }
311 
312  /* This is a second-chance exception, only for the debugger */
313  if (KiDebugRoutine(TrapFrame,
314  ExceptionFrame,
315  ExceptionRecord,
316  &Context,
317  PreviousMode,
318  TRUE))
319  {
320  /* Exception was handled */
321  goto Handled;
322  }
323 
324  /* Third strike; you're out */
325  KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
326  ExceptionRecord->ExceptionCode,
327  (ULONG_PTR)ExceptionRecord->ExceptionAddress,
328  (ULONG_PTR)TrapFrame,
329  0);
330  }
331  else
332  {
333  /* User mode exception, was it first-chance? */
334  if (FirstChance)
335  {
336  /*
337  * Break into the kernel debugger unless a user mode debugger
338  * is present or user mode exceptions are ignored, except if this
339  * is a debug service which we must always pass to KD
340  */
341  if ((!(PsGetCurrentProcess()->DebugPort) &&
342  !(KdIgnoreUmExceptions)) ||
343  (KdIsThisAKdTrap(ExceptionRecord, &Context, PreviousMode)))
344  {
345  /* Make sure the debugger can access debug directories */
347 
348  /* Call the kernel debugger */
349  if (KiDebugRoutine(TrapFrame,
350  ExceptionFrame,
351  ExceptionRecord,
352  &Context,
353  PreviousMode,
354  FALSE))
355  {
356  /* Exception was handled */
357  goto Handled;
358  }
359  }
360 
361  /* Forward exception to user mode debugger */
362  if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) return;
363 
364  /* Forward exception to user mode (does not return, if successful) */
365  KiDispatchExceptionToUser(TrapFrame, &Context, ExceptionRecord);
366 
367  /* Failed to dispatch, fall through for second chance handling */
368  }
369 
370  /* Try second chance */
371  if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
372  {
373  /* Handled, get out */
374  return;
375  }
376  else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
377  {
378  /* Handled, get out */
379  return;
380  }
381 
382  /* 3rd strike, kill the process */
383  DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx, BaseAddress: %lx\n",
384  PsGetCurrentProcess()->ImageFileName,
385  ExceptionRecord->ExceptionCode,
386  ExceptionRecord->ExceptionAddress,
387  PsGetCurrentProcess()->SectionBaseAddress);
388 
389  ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
390  KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
391  ExceptionRecord->ExceptionCode,
392  (ULONG_PTR)ExceptionRecord->ExceptionAddress,
393  (ULONG_PTR)TrapFrame,
394  0);
395  }
396 
397 Handled:
398  /* Convert the context back into Trap/Exception Frames */
400  ExceptionFrame,
401  TrapFrame,
402  Context.ContextFlags,
403  PreviousMode);
404  return;
405 }
VOID NTAPI KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame, ULONG ContextFlags, KPROCESSOR_MODE PreviousMode)
PKDEBUG_ROUTINE KiDebugRoutine
Definition: kddata.c:74
#define TRUE
Definition: types.h:120
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1080
static VOID KiDispatchExceptionToUser(IN PKTRAP_FRAME TrapFrame, IN PCONTEXT Context, IN PEXCEPTION_RECORD ExceptionRecord)
Definition: except.c:97
uint32_t ULONG_PTR
Definition: typedefs.h:65
VOID KiPrepareUserDebugData(void)
Definition: except.c:200
#define FALSE
Definition: types.h:117
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
#define NtCurrentProcess()
Definition: nt_native.h:1657
BOOLEAN KdIgnoreUmExceptions
Definition: kddata.c:86
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
BOOLEAN NTAPI DbgkForwardException(IN PEXCEPTION_RECORD ExceptionRecord, IN BOOLEAN DebugPort, IN BOOLEAN SecondChance)
Definition: dbgkobj.c:317
_In_ BOOLEAN Handled
Definition: ketypes.h:337
BOOLEAN NTAPI KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN KPROCESSOR_MODE PreviousMode)
Definition: kdtrap.c:317
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define DPRINT1
Definition: precomp.h:8
struct tagContext Context
Definition: acpixf.h:1038
BOOLEAN NTAPI RtlDispatchException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT ContextRecord)
Definition: except.c:87
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTEXT_ALL
#define KI_EXCEPTION_ACCESS_VIOLATION
Definition: ketypes.h:177
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108

Referenced by KiRaiseException().

◆ KiDispatchExceptionToUser()

static VOID KiDispatchExceptionToUser ( IN PKTRAP_FRAME  TrapFrame,
IN PCONTEXT  Context,
IN PEXCEPTION_RECORD  ExceptionRecord 
)
static

Definition at line 97 of file except.c.

101 {
102  EXCEPTION_RECORD LocalExceptRecord;
103  ULONG64 UserRsp;
104  PKUSER_EXCEPTION_STACK UserStack;
105 
106  /* Make sure we have a valid SS */
107  if (TrapFrame->SegSs != (KGDT64_R3_DATA | RPL_MASK))
108  {
109  /* Raise an access violation instead */
110  LocalExceptRecord.ExceptionCode = STATUS_ACCESS_VIOLATION;
111  LocalExceptRecord.ExceptionFlags = 0;
112  LocalExceptRecord.NumberParameters = 0;
113  ExceptionRecord = &LocalExceptRecord;
114  }
115 
116  /* Get new stack pointer and align it to 16 bytes */
117  UserRsp = (Context->Rsp - sizeof(KUSER_EXCEPTION_STACK)) & ~15;
118 
119  /* Get pointer to the usermode context, exception record and machine frame */
120  UserStack = (PKUSER_EXCEPTION_STACK)UserRsp;
121 
122  /* Enable interrupts */
123  _enable();
124 
125  /* Set up the user-stack */
126  _SEH2_TRY
127  {
128  /* Probe the user stack frame and zero it out */
129  ProbeForWrite(UserStack, sizeof(*UserStack), TYPE_ALIGNMENT(KUSER_EXCEPTION_STACK));
130  RtlZeroMemory(UserStack, sizeof(*UserStack));
131 
132  /* Copy Context and ExceptionFrame */
133  UserStack->Context = *Context;
134  UserStack->ExceptionRecord = *ExceptionRecord;
135 
136  /* Setup the machine frame */
137  UserStack->MachineFrame.Rip = Context->Rip;
138  UserStack->MachineFrame.SegCs = Context->SegCs;
139  UserStack->MachineFrame.EFlags = Context->EFlags;
140  UserStack->MachineFrame.Rsp = Context->Rsp;
141  UserStack->MachineFrame.SegSs = Context->SegSs;
142  }
143  _SEH2_EXCEPT((LocalExceptRecord = *_SEH2_GetExceptionInformation()->ExceptionRecord),
145  {
146  // FIXME: handle stack overflow
147 
148  /* Nothing we can do here */
149  _disable();
150  _SEH2_YIELD(return);
151  }
152  _SEH2_END;
153 
154  /* Now set the two params for the user-mode dispatcher */
155  TrapFrame->Rcx = (ULONG64)&UserStack->ExceptionRecord;
156  TrapFrame->Rdx = (ULONG64)&UserStack->Context;
157 
158  /* Set new Stack Pointer */
159  TrapFrame->Rsp = UserRsp;
160 
161  /* Force correct segments */
162  TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK;
163  TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
164  TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
165  TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
166  TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
167  TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK;
168 
169  /* Set RIP to the User-mode Dispatcher */
170  TrapFrame->Rip = (ULONG64)KeUserExceptionDispatcher;
171 
172  _disable();
173 
174  /* Exit to usermode */
175  KiServiceExit2(TrapFrame);
176 }
_SEH2_TRY
Definition: create.c:4226
#define KGDT64_R3_CODE
Definition: ketypes.h:76
#define TYPE_ALIGNMENT(t)
Definition: ntbasedef.h:117
struct _KUSER_EXCEPTION_STACK * PKUSER_EXCEPTION_STACK
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#define KGDT64_R3_CMTEB
Definition: ketypes.h:78
_SEH2_END
Definition: create.c:4400
USHORT SegSs
Definition: ketypes.h:982
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
DWORD ExceptionCode
Definition: compat.h:208
MACHINE_FRAME MachineFrame
Definition: ketypes.h:1015
#define KGDT64_R3_DATA
Definition: ketypes.h:75
EXCEPTION_RECORD ExceptionRecord
Definition: ketypes.h:1013
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define RPL_MASK
Definition: ketypes.h:69
ULONG SegCs
Definition: nt_native.h:1477
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
PVOID KeUserExceptionDispatcher
Definition: ke.h:144
unsigned __int64 ULONG64
Definition: imports.h:198
ULONG EFlags
Definition: ketypes.h:979
ULONG64 Rip
Definition: ketypes.h:976
ULONG64 Rsp
Definition: ketypes.h:981
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define KiServiceExit2
Definition: ke.h:5
USHORT SegCs
Definition: ketypes.h:977
struct _KUSER_EXCEPTION_STACK KUSER_EXCEPTION_STACK
struct tagContext Context
Definition: acpixf.h:1038
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
DWORD ExceptionFlags
Definition: compat.h:209
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
DWORD NumberParameters
Definition: compat.h:212

Referenced by KiDispatchException().

◆ KiGeneralProtectionFaultHandler()

NTSTATUS NTAPI KiGeneralProtectionFaultHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 621 of file except.c.

623 {
624  PUCHAR Instructions;
625 
626  /* Check for user-mode GPF */
627  if (TrapFrame->SegCs & 3)
628  {
629  return KiGeneralProtectionFaultUserMode(TrapFrame);
630  }
631 
632  /* Check for lazy segment load */
633  if (TrapFrame->SegDs != (KGDT64_R3_DATA | RPL_MASK))
634  {
635  /* Fix it */
636  TrapFrame->SegDs = (KGDT64_R3_DATA | RPL_MASK);
637  return STATUS_SUCCESS;
638  }
639  else if (TrapFrame->SegEs != (KGDT64_R3_DATA | RPL_MASK))
640  {
641  /* Fix it */
642  TrapFrame->SegEs = (KGDT64_R3_DATA | RPL_MASK);
643  return STATUS_SUCCESS;
644  }
645 
646  /* Get Instruction Pointer */
647  Instructions = (PUCHAR)TrapFrame->Rip;
648 
649  /* Check for IRET */
650  if (Instructions[0] == 0x48 && Instructions[1] == 0xCF)
651  {
652  /* Not implemented */
654  ASSERT(FALSE);
655  }
656 
657  /* Check for RDMSR/WRMSR */
658  if ((Instructions[0] == 0xF) && // 2-byte opcode
659  ((Instructions[1] == 0x30) || // RDMSR
660  (Instructions[1] == 0x32))) // WRMSR
661  {
662  /* Unknown CPU MSR, so raise an access violation */
664  }
665 
666  ASSERT(FALSE);
667  return STATUS_UNSUCCESSFUL;
668 }
unsigned char * PUCHAR
Definition: retypes.h:3
static NTSTATUS KiGeneralProtectionFaultUserMode(_In_ PKTRAP_FRAME TrapFrame)
Definition: except.c:585
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define FALSE
Definition: types.h:117
#define KGDT64_R3_DATA
Definition: ketypes.h:75
#define RPL_MASK
Definition: ketypes.h:69
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define UNIMPLEMENTED
Definition: debug.h:115
#define STATUS_SUCCESS
Definition: shellext.h:65

◆ KiGeneralProtectionFaultUserMode()

static NTSTATUS KiGeneralProtectionFaultUserMode ( _In_ PKTRAP_FRAME  TrapFrame)
static

Definition at line 585 of file except.c.

587 {
588  BOOLEAN Wow64 = TrapFrame->SegCs == KGDT64_R3_CMCODE;
589  PUCHAR InstructionPointer;
591 
592  /* We need to decode the instruction at RIP */
593  InstructionPointer = (PUCHAR)TrapFrame->Rip;
594 
595  _SEH2_TRY
596  {
597  /* Probe the instruction address */
598  ProbeForRead(InstructionPointer, 64, 1);
599 
600  /* Check if it's a privileged instruction */
601  if (KiIsPrivilegedInstruction(InstructionPointer, Wow64))
602  {
604  }
605  else
606  {
608  }
609  }
611  {
613  }
614  _SEH2_END
615 
616  return Status;
617 }
_SEH2_TRY
Definition: create.c:4226
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
_SEH2_END
Definition: create.c:4400
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define STATUS_PRIVILEGED_INSTRUCTION
Definition: ntstatus.h:386
static BOOLEAN KiIsPrivilegedInstruction(PUCHAR Ip, BOOLEAN Wow64)
Definition: except.c:442
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define KGDT64_R3_CMCODE
Definition: ketypes.h:74
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165

Referenced by KiGeneralProtectionFaultHandler().

◆ KiIsPrivilegedInstruction()

static BOOLEAN KiIsPrivilegedInstruction ( PUCHAR  Ip,
BOOLEAN  Wow64 
)
static

Definition at line 442 of file except.c.

443 {
444  ULONG i;
445 
446  /* Handle prefixes */
447  for (i = 0; i < 15; i++)
448  {
449  if (!Wow64)
450  {
451  /* Check for REX prefix */
452  if ((Ip[0] >= 0x40) && (Ip[0] <= 0x4F))
453  {
454  Ip++;
455  continue;
456  }
457  }
458 
459  switch (Ip[0])
460  {
461  /* Check prefixes */
462  case 0x26: // ES
463  case 0x2E: // CS / null
464  case 0x36: // SS
465  case 0x3E: // DS
466  case 0x64: // FS
467  case 0x65: // GS
468  case 0x66: // OP
469  case 0x67: // ADDR
470  case 0xF0: // LOCK
471  case 0xF2: // REP
472  case 0xF3: // REP INS/OUTS
473  Ip++;
474  continue;
475  }
476 
477  break;
478  }
479 
480  if (i == 15)
481  {
482  /* Too many prefixes. Should only happen, when the code was concurrently modified. */
483  return FALSE;
484  }
485 
486  switch (Ip[0])
487  {
488  case 0xF4: // HLT
489  case 0xFA: // CLI
490  case 0xFB: // STI
491  return TRUE;
492 
493  case 0x0F:
494  {
495  switch (Ip[1])
496  {
497  case 0x06: // CLTS
498  case 0x07: // SYSRET
499  case 0x08: // INVD
500  case 0x09: // WBINVD
501  case 0x20: // MOV CR, XXX
502  case 0x21: // MOV DR, XXX
503  case 0x22: // MOV XXX, CR
504  case 0x23: // MOV YYY, DR
505  case 0x30: // WRMSR
506  case 0x32: // RDMSR
507  case 0x33: // RDPMC
508  case 0x35: // SYSEXIT
509  case 0x78: // VMREAD
510  case 0x79: // VMWRITE
511  return TRUE;
512 
513  case 0x00:
514  {
515  /* Check MODRM Reg field */
516  switch ((Ip[2] >> 3) & 0x7)
517  {
518  case 2: // LLDT
519  case 3: // LTR
520  return TRUE;
521  }
522  break;
523  }
524 
525  case 0x01:
526  {
527  switch (Ip[2])
528  {
529  case 0xC1: // VMCALL
530  case 0xC2: // VMLAUNCH
531  case 0xC3: // VMRESUME
532  case 0xC4: // VMXOFF
533  case 0xC8: // MONITOR
534  case 0xC9: // MWAIT
535  case 0xD1: // XSETBV
536  case 0xF8: // SWAPGS
537  return TRUE;
538  }
539 
540  /* Check MODRM Reg field */
541  switch ((Ip[2] >> 3) & 0x7)
542  {
543  case 2: // LGDT
544  case 3: // LIDT
545  case 6: // LMSW
546  case 7: // INVLPG / SWAPGS / RDTSCP
547  return TRUE;
548  }
549  break;
550  }
551 
552  case 0x38:
553  {
554  switch (Ip[2])
555  {
556  case 0x80: // INVEPT
557  case 0x81: // INVVPID
558  return TRUE;
559  }
560  break;
561  }
562 
563  case 0xC7:
564  {
565  /* Check MODRM Reg field */
566  switch ((Ip[2] >> 3) & 0x7)
567  {
568  case 0x06: // VMPTRLD, VMCLEAR, VMXON
569  case 0x07: // VMPTRST
570  return TRUE;
571  }
572  break;
573  }
574  }
575 
576  break;
577  }
578  }
579 
580  return FALSE;
581 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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
unsigned int ULONG
Definition: retypes.h:1

Referenced by KiGeneralProtectionFaultUserMode().

◆ KiNpxNotAvailableFaultHandler()

NTSTATUS NTAPI KiNpxNotAvailableFaultHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 432 of file except.c.

434 {
436  KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 1, TrapFrame);
437  return -1;
438 }
DECLSPEC_NORETURN VOID NTAPI KeBugCheckWithTf(ULONG BugCheckCode, ULONG_PTR BugCheckParameter1, ULONG_PTR BugCheckParameter2, ULONG_PTR BugCheckParameter3, ULONG_PTR BugCheckParameter4, PKTRAP_FRAME Tf)
#define UNIMPLEMENTED
Definition: debug.h:115

◆ KiPageInDirectory()

static VOID KiPageInDirectory ( PVOID  ImageBase,
USHORT  Directory 
)
static

Definition at line 180 of file except.c.

181 {
182  volatile CHAR *Pointer;
183  ULONG Size;
184 
185  /* Get a pointer to the debug directory */
186  Pointer = RtlImageDirectoryEntryToData(ImageBase, 1, Directory, &Size);
187  if (!Pointer) return;
188 
189  /* Loop all pages */
190  while ((LONG)Size > 0)
191  {
192  /* Touch it, to page it in */
193  (void)*Pointer;
194  Pointer += PAGE_SIZE;
195  Size -= PAGE_SIZE;
196  }
197 }
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
char CHAR
Definition: xmlstorage.h:175
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
long LONG
Definition: pedump.c:60
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define PAGE_SIZE
Definition: env_spec_w32.h:49
unsigned int ULONG
Definition: retypes.h:1
base for all directory entries
Definition: entries.h:138

Referenced by KiPrepareUserDebugData().

◆ KiPrepareUserDebugData()

VOID KiPrepareUserDebugData ( void  )

Definition at line 200 of file except.c.

201 {
202  PLDR_DATA_TABLE_ENTRY LdrEntry;
204  PLIST_ENTRY ListEntry;
205  PTEB Teb;
206 
207  /* Get the Teb for this process */
208  Teb = KeGetCurrentThread()->Teb;
209  if (!Teb) return;
210 
211  /* Enable interrupts */
212  _enable();
213 
214  _SEH2_TRY
215  {
216  /* Get a pointer to the loader data */
218  if (!PebLdr) _SEH2_LEAVE;
219 
220  /* Now loop all entries in the module list */
221  for (ListEntry = PebLdr->InLoadOrderModuleList.Flink;
222  ListEntry != &PebLdr->InLoadOrderModuleList;
223  ListEntry = ListEntry->Flink)
224  {
225  /* Get the loader entry */
226  LdrEntry = CONTAINING_RECORD(ListEntry,
228  InLoadOrderLinks);
229 
230  KiPageInDirectory((PVOID)LdrEntry->DllBase,
232 
233  KiPageInDirectory((PVOID)LdrEntry->DllBase,
235  }
236 
237  }
239  {
240  }
241  _SEH2_END;
242 
243  _disable();
244 }
_SEH2_TRY
Definition: create.c:4226
PPEB ProcessEnvironmentBlock
Definition: ntddk_ex.h:337
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:120
void __cdecl _enable(void)
Definition: intrin_arm.h:373
_SEH2_END
Definition: create.c:4400
PVOID DllBase
Definition: btrfs_drv.h:1880
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PEB_LDR_DATA PebLdr
Definition: ldrinit.c:67
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
Definition: btrfs_drv.h:1876
Definition: typedefs.h:119
Definition: compat.h:835
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:152
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
static VOID KiPageInDirectory(PVOID ImageBase, USHORT Directory)
Definition: except.c:180
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_LEAVE
Definition: filesup.c:20
#define KeGetCurrentThread
Definition: hal.h:55
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION
Definition: pedump.c:262

Referenced by KiDispatchException().

◆ KiSystemFatalException()

VOID DECLSPEC_NORETURN KiSystemFatalException ( IN ULONG  ExceptionCode,
IN PKTRAP_FRAME  TrapFrame 
)

Definition at line 418 of file except.c.

420 {
421  /* Bugcheck the system */
422  KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
424  0,
425  0,
426  0,
427  TrapFrame);
428 }
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1772
DECLSPEC_NORETURN VOID NTAPI KeBugCheckWithTf(ULONG BugCheckCode, ULONG_PTR BugCheckParameter1, ULONG_PTR BugCheckParameter2, ULONG_PTR BugCheckParameter3, ULONG_PTR BugCheckParameter4, PKTRAP_FRAME Tf)

◆ KiXmmExceptionHandler()

NTSTATUS NTAPI KiXmmExceptionHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 672 of file except.c.

674 {
676 
677  if ((TrapFrame->MxCsr & _MM_EXCEPT_INVALID) &&
678  !(TrapFrame->MxCsr & _MM_MASK_INVALID))
679  {
680  /* Invalid operation */
682  }
683  else if ((TrapFrame->MxCsr & _MM_EXCEPT_DENORM) &&
684  !(TrapFrame->MxCsr & _MM_MASK_DENORM))
685  {
686  /* Denormalized operand. Yes, this is what Windows returns. */
688  }
689  else if ((TrapFrame->MxCsr & _MM_EXCEPT_DIV_ZERO) &&
690  !(TrapFrame->MxCsr & _MM_MASK_DIV_ZERO))
691  {
692  /* Divide by zero */
694  }
695  else if ((TrapFrame->MxCsr & _MM_EXCEPT_OVERFLOW) &&
696  !(TrapFrame->MxCsr & _MM_MASK_OVERFLOW))
697  {
698  /* Overflow */
700  }
701  else if ((TrapFrame->MxCsr & _MM_EXCEPT_UNDERFLOW) &&
702  !(TrapFrame->MxCsr & _MM_MASK_UNDERFLOW))
703  {
704  /* Underflow */
706  }
707  else if ((TrapFrame->MxCsr & _MM_EXCEPT_INEXACT) &&
708  !(TrapFrame->MxCsr & _MM_MASK_INEXACT))
709  {
710  /* Precision */
712  }
713  else
714  {
715  /* Should not happen */
716  ASSERT(FALSE);
717  }
718 
719  return ExceptionCode;
720 }
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1772
#define _MM_MASK_INEXACT
Definition: xmmintrin.h:107
#define _MM_EXCEPT_DIV_ZERO
Definition: xmmintrin.h:96
#define _MM_EXCEPT_DENORM
Definition: xmmintrin.h:95
#define STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:378
#define STATUS_FLOAT_INEXACT_RESULT
Definition: ntstatus.h:379
#define _MM_MASK_OVERFLOW
Definition: xmmintrin.h:105
#define STATUS_FLOAT_UNDERFLOW
Definition: ntstatus.h:383
#define STATUS_FLOAT_OVERFLOW
Definition: ntstatus.h:381
#define FALSE
Definition: types.h:117
#define _MM_MASK_INVALID
Definition: xmmintrin.h:102
#define _MM_MASK_UNDERFLOW
Definition: xmmintrin.h:106
#define _MM_EXCEPT_UNDERFLOW
Definition: xmmintrin.h:98
#define ASSERT(a)
Definition: mode.c:44
#define _MM_EXCEPT_INVALID
Definition: xmmintrin.h:94
#define _MM_MASK_DENORM
Definition: xmmintrin.h:103
#define _MM_MASK_DIV_ZERO
Definition: xmmintrin.h:104
#define _MM_EXCEPT_OVERFLOW
Definition: xmmintrin.h:97
unsigned int ULONG
Definition: retypes.h:1
#define _MM_EXCEPT_INEXACT
Definition: xmmintrin.h:99
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:380

Variable Documentation

◆ KiIdt

KIDTENTRY64 KiIdt[256]

Definition at line 50 of file except.c.

Referenced by KeInitExceptions().

◆ KiIdtDescriptor

KDESCRIPTOR KiIdtDescriptor = {{0}, sizeof(KiIdt) - 1, KiIdt}

Definition at line 51 of file except.c.

Referenced by KeInitExceptions(), and KiSystemStartup().

◆ KiInterruptInitTable

KIDT_INIT KiInterruptInitTable[]
Initial value:
=
{
{0x00, 0x00, 0x00, KiDivideErrorFault},
{0x01, 0x00, 0x00, KiDebugTrapOrFault},
{0x02, 0x00, 0x03, KiNmiInterrupt},
{0x03, 0x03, 0x00, KiBreakpointTrap},
{0x04, 0x03, 0x00, KiOverflowTrap},
{0x05, 0x00, 0x00, KiBoundFault},
{0x06, 0x00, 0x00, KiInvalidOpcodeFault},
{0x07, 0x00, 0x00, KiNpxNotAvailableFault},
{0x08, 0x00, 0x01, KiDoubleFaultAbort},
{0x09, 0x00, 0x00, KiNpxSegmentOverrunAbort},
{0x0A, 0x00, 0x00, KiInvalidTssFault},
{0x0B, 0x00, 0x00, KiSegmentNotPresentFault},
{0x0C, 0x00, 0x00, KiStackFault},
{0x0D, 0x00, 0x00, KiGeneralProtectionFault},
{0x0E, 0x00, 0x00, KiPageFault},
{0x10, 0x00, 0x00, KiFloatingErrorFault},
{0x11, 0x00, 0x00, KiAlignmentFault},
{0x12, 0x00, 0x02, KiMcheckAbort},
{0x13, 0x00, 0x00, KiXmmException},
{0x1F, 0x00, 0x00, KiApcInterrupt},
{0x2C, 0x03, 0x00, KiRaiseAssertion},
{0x2D, 0x03, 0x00, KiDebugServiceTrap},
{0x2F, 0x00, 0x00, KiDpcInterrupt},
{0xE1, 0x00, 0x00, KiIpiInterrupt},
{0, 0, 0, 0}
}
VOID KiSegmentNotPresentFault(VOID)
VOID KiMcheckAbort(VOID)
VOID KiPageFault(VOID)
VOID KiGeneralProtectionFault(VOID)
VOID KiDivideErrorFault(VOID)
VOID KiInvalidOpcodeFault(VOID)
VOID KiDebugTrapOrFault(VOID)
VOID KiBoundFault(VOID)
VOID KiApcInterrupt(VOID)
Definition: trapc.c:229
VOID KiNpxSegmentOverrunAbort(VOID)
VOID KiIpiInterrupt(VOID)
VOID KiDoubleFaultAbort(VOID)
VOID KiNmiInterrupt(VOID)
VOID KiInvalidTssFault(VOID)
VOID KiNpxNotAvailableFault(VOID)
VOID KiDpcInterrupt(VOID)
VOID KiStackFault(VOID)
VOID KiXmmException(VOID)
VOID KiAlignmentFault(VOID)
VOID KiBreakpointTrap(VOID)
VOID KiFloatingErrorFault(VOID)
VOID KiDebugServiceTrap(VOID)
VOID KiOverflowTrap(VOID)
VOID KiRaiseAssertion(VOID)

Definition at line 20 of file except.c.

Referenced by KeInitExceptions().

◆ KiUnexpectedRange

KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange[256]

Referenced by KeInitExceptions().