ReactOS  r75907
exp.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ke/i386/exp.c
5  * PURPOSE: Exception Dispatching and Context<->Trap Frame Conversion
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Gregor Anich
8  * Skywing (skywing@valhallalegends.com)
9  */
10 
11 /* INCLUDES ******************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
17 
18 /* FUNCTIONS *****************************************************************/
19 
20 VOID
22 NTAPI
24 {
25  ULONG i;
26  USHORT FlippedSelector;
27 
28  /* Loop the IDT */
29  for (i = 0; i <= MAXIMUM_IDTVECTOR; i++)
30  {
31  /* Save the current Selector */
32  FlippedSelector = KiIdt[i].Selector;
33 
34  /* Flip Selector and Extended Offset */
36  KiIdt[i].ExtendedOffset = FlippedSelector;
37  }
38 }
39 
40 ULONG
43 {
44  ULONG DebugMask = KeGetCurrentThread()->Header.DebugActive;
45 
46  /* Check if debugging is enabled */
47  if (DebugMask & DR_MASK(DR7_OVERRIDE_V))
48  {
49  /* Sanity checks */
50  ASSERT((DebugMask & DR_REG_MASK) != 0);
52  return 0;
53  }
54 
55  /* Return DR7 itself */
56  return Dr7;
57 }
58 
59 BOOLEAN
62  OUT PULONG DrMask)
63 {
64  ULONG NewMask, Mask;
65  UCHAR Result;
66 
67  /* Check if the caller gave us a mask */
68  if (!DrMask)
69  {
70  /* He didn't, use the one from the thread */
71  Mask = KeGetCurrentThread()->Header.DebugActive;
72  }
73  else
74  {
75  /* He did, read it */
76  Mask = *DrMask;
77  }
78 
79  /* Sanity check */
80  ASSERT((*Dr7Ptr & DR7_RESERVED_MASK) == 0);
81 
82  /* Check if DR7 is empty */
83  NewMask = Mask;
84  if (!(*Dr7Ptr))
85  {
86  /* Assume failure */
87  Result = FALSE;
88 
89  /* Check the DR mask */
90  NewMask &= ~(DR_MASK(7));
91  if (NewMask & DR_REG_MASK)
92  {
93  /* Set the active mask */
94  NewMask |= DR_MASK(DR7_OVERRIDE_V);
95 
96  /* Set DR7 override */
97  *Dr7Ptr |= DR7_OVERRIDE_MASK;
98  }
99  else
100  {
101  /* Sanity check */
102  ASSERT(NewMask == 0);
103  }
104  }
105  else
106  {
107  /* Check if we have a mask or not */
108  Result = NewMask ? TRUE: FALSE;
109 
110  /* Update the mask to disable debugging */
111  NewMask &= ~(DR_MASK(DR7_OVERRIDE_V));
112  NewMask |= DR_MASK(7);
113  }
114 
115  /* Check if caller wants the new mask */
116  if (DrMask)
117  {
118  /* Update it */
119  *DrMask = NewMask;
120  }
121  else
122  {
123  /* Check if the mask changed */
124  if (Mask != NewMask)
125  {
126  /* Update it */
127  KeGetCurrentThread()->Header.DebugActive = (UCHAR)NewMask;
128  }
129  }
130 
131  /* Return the result */
132  return Result;
133 }
134 
135 ULONG
136 NTAPI
138 {
139  /* Check if this is user-mode or V86 */
140  if (KiUserTrap(TrapFrame) ||
141  (TrapFrame->EFlags & EFLAGS_V86_MASK))
142  {
143  /* Return it directly */
144  return TrapFrame->HardwareEsp;
145  }
146  else
147  {
148  /* Edited frame */
149  if (!(TrapFrame->SegCs & FRAME_EDITED))
150  {
151  /* Return edited value */
152  return TrapFrame->TempEsp;
153  }
154  else
155  {
156  /* Virgin frame, calculate */
157  return (ULONG)&TrapFrame->HardwareEsp;
158  }
159  }
160 }
161 
162 VOID
163 NTAPI
165  IN ULONG Esp)
166 {
167  KIRQL OldIrql;
168  ULONG Previous;
169 
170  /* Raise to APC_LEVEL if needed */
171  OldIrql = KeGetCurrentIrql();
172  if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
173 
174  /* Get the old ESP */
175  Previous = KiEspFromTrapFrame(TrapFrame);
176 
177  /* Check if this is user-mode or V86 */
178  if (KiUserTrap(TrapFrame) ||
179  (TrapFrame->EFlags & EFLAGS_V86_MASK))
180  {
181  /* Write it directly */
182  TrapFrame->HardwareEsp = Esp;
183  }
184  else
185  {
186  /* Don't allow ESP to be lowered, this is illegal */
187  if (Esp < Previous) KeBugCheckEx(SET_OF_INVALID_CONTEXT,
188  Esp,
189  Previous,
190  (ULONG_PTR)TrapFrame,
191  0);
192 
193  /* Create an edit frame, check if it was alrady */
194  if (!(TrapFrame->SegCs & FRAME_EDITED))
195  {
196  /* Update the value */
197  TrapFrame->TempEsp = Esp;
198  }
199  else
200  {
201  /* Check if ESP changed */
202  if (Previous != Esp)
203  {
204  /* Save CS */
205  TrapFrame->TempSegCs = TrapFrame->SegCs;
206  TrapFrame->SegCs &= ~FRAME_EDITED;
207 
208  /* Save ESP */
209  TrapFrame->TempEsp = Esp;
210  }
211  }
212  }
213 
214  /* Restore IRQL */
215  if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
216 }
217 
218 ULONG
219 NTAPI
221 {
222  /* Check if this was V86 Mode */
223  if (TrapFrame->EFlags & EFLAGS_V86_MASK)
224  {
225  /* Just return it */
226  return TrapFrame->HardwareSegSs;
227  }
228  else if (KiUserTrap(TrapFrame))
229  {
230  /* User mode, return the User SS */
231  return TrapFrame->HardwareSegSs | RPL_MASK;
232  }
233  else
234  {
235  /* Kernel mode */
236  return KGDT_R0_DATA;
237  }
238 }
239 
240 VOID
241 NTAPI
243  IN ULONG Ss)
244 {
245  /* Remove the high-bits */
246  Ss &= 0xFFFF;
247 
248  /* If this was V86 Mode */
249  if (TrapFrame->EFlags & EFLAGS_V86_MASK)
250  {
251  /* Just write it */
252  TrapFrame->HardwareSegSs = Ss;
253  }
254  else if (KiUserTrap(TrapFrame))
255  {
256  /* Usermode, save the User SS */
257  TrapFrame->HardwareSegSs = Ss | RPL_MASK;
258  }
259 }
260 
261 USHORT
262 NTAPI
264 {
265  INT FxTagWord = ~TagWord;
266 
267  /*
268  * Empty is now 00, any 2 bits containing 1 mean valid
269  * Now convert the rest (11->0 and the rest to 1)
270  */
271  FxTagWord = (FxTagWord | (FxTagWord >> 1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
272  FxTagWord = (FxTagWord | (FxTagWord >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
273  FxTagWord = (FxTagWord | (FxTagWord >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
274  FxTagWord = (FxTagWord | (FxTagWord >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
275  return FxTagWord;
276 }
277 
278 VOID
279 NTAPI
281 {
283  ULONG_PTR Stack;
284  ULONG EFlags;
285 
286  /* Get the current thread's stack */
287  Thread = KeGetCurrentThread();
288  Stack = (ULONG_PTR)Thread->InitialStack;
289 
290  /* Check if we are in V8086 mode */
291  if (!(TrapFrame->EFlags & EFLAGS_V86_MASK))
292  {
293  /* Bias the stack for the V86 segments */
294  Stack -= (FIELD_OFFSET(KTRAP_FRAME, V86Gs) -
295  FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs));
296  }
297 
298  /* Bias the stack for the FPU area */
299  Stack -= sizeof(FX_SAVE_AREA);
300 
301  /* Disable interrupts */
302  EFlags = __readeflags();
303  _disable();
304 
305  /* Set new ESP0 value in the TSS */
306  KeGetPcr()->TSS->Esp0 = Stack;
307 
308  /* Restore old interrupt state */
309  __writeeflags(EFlags);
310 }
311 
312 VOID
313 NTAPI
315  IN OUT PKEXCEPTION_FRAME ExceptionFrame,
316  IN OUT PKTRAP_FRAME TrapFrame,
317  IN ULONG ContextFlags,
319 {
320  PFX_SAVE_AREA FxSaveArea;
321  ULONG i;
322  BOOLEAN V86Switch = FALSE;
323  KIRQL OldIrql;
324  ULONG DrMask = 0;
325 
326  /* Do this at APC_LEVEL */
327  OldIrql = KeGetCurrentIrql();
328  if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
329 
330  /* Start with the basic Registers */
331  if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
332  {
333  /* Check if we went through a V86 switch */
334  if ((Context->EFlags & EFLAGS_V86_MASK) !=
335  (TrapFrame->EFlags & EFLAGS_V86_MASK))
336  {
337  /* We did, remember this for later */
338  V86Switch = TRUE;
339  }
340 
341  /* Copy EFLAGS and sanitize them*/
342  TrapFrame->EFlags = Ke386SanitizeFlags(Context->EFlags, PreviousMode);
343 
344  /* Copy EBP and EIP */
345  TrapFrame->Ebp = Context->Ebp;
346  TrapFrame->Eip = Context->Eip;
347 
348  /* Check if we were in V86 Mode */
349  if (TrapFrame->EFlags & EFLAGS_V86_MASK)
350  {
351  /* Simply copy the CS value */
352  TrapFrame->SegCs = Context->SegCs;
353  }
354  else
355  {
356  /* We weren't in V86, so sanitize the CS */
357  TrapFrame->SegCs = Ke386SanitizeSeg(Context->SegCs, PreviousMode);
358 
359  /* Don't let it under 8, that's invalid */
360  if ((PreviousMode != KernelMode) && (TrapFrame->SegCs < 8))
361  {
362  /* Force it to User CS */
363  TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
364  }
365  }
366 
367  /* Handle SS Specially for validation */
368  KiSsToTrapFrame(TrapFrame, Context->SegSs);
369 
370  /* Write ESP back; take into account Edited Trap Frames */
371  KiEspToTrapFrame(TrapFrame, Context->Esp);
372 
373  /* Handle our V86 Bias if we went through a switch */
374  if (V86Switch) Ki386AdjustEsp0(TrapFrame);
375  }
376 
377  /* Process the Integer Registers */
378  if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
379  {
380  /* Copy them manually */
381  TrapFrame->Eax = Context->Eax;
382  TrapFrame->Ebx = Context->Ebx;
383  TrapFrame->Ecx = Context->Ecx;
384  TrapFrame->Edx = Context->Edx;
385  TrapFrame->Esi = Context->Esi;
386  TrapFrame->Edi = Context->Edi;
387  }
388 
389  /* Process the Context Segments */
390  if ((ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
391  {
392  /* Check if we were in V86 Mode */
393  if (TrapFrame->EFlags & EFLAGS_V86_MASK)
394  {
395  /* Copy the V86 Segments directly */
396  TrapFrame->V86Ds = Context->SegDs;
397  TrapFrame->V86Es = Context->SegEs;
398  TrapFrame->V86Fs = Context->SegFs;
399  TrapFrame->V86Gs = Context->SegGs;
400  }
401  else if (!KiUserTrap(TrapFrame))
402  {
403  /* For kernel mode, write the standard values */
404  TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
405  TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
406  TrapFrame->SegFs = Ke386SanitizeSeg(Context->SegFs, PreviousMode);
407  TrapFrame->SegGs = 0;
408  }
409  else
410  {
411  /* For user mode, return the values directly */
412  TrapFrame->SegDs = Context->SegDs;
413  TrapFrame->SegEs = Context->SegEs;
414  TrapFrame->SegFs = Context->SegFs;
415 
416  /* Handle GS specially */
417  if (TrapFrame->SegCs == (KGDT_R3_CODE | RPL_MASK))
418  {
419  /* Don't use it, if user */
420  TrapFrame->SegGs = 0;
421  }
422  else
423  {
424  /* Copy it if kernel */
425  TrapFrame->SegGs = Context->SegGs;
426  }
427  }
428  }
429 
430  /* Handle the extended registers */
431  if (((ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
432  CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame))
433  {
434  /* Get the FX Area */
435  FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
436 
437  /* Check if NPX is present */
438  if (KeI386NpxPresent)
439  {
440  /* Flush the NPX State */
442 
443  /* Copy the FX State */
444  RtlCopyMemory(&FxSaveArea->U.FxArea,
445  &Context->ExtendedRegisters[0],
447 
448  /* Remove reserved bits from MXCSR */
449  FxSaveArea->U.FxArea.MXCsr &= KiMXCsrMask;
450 
451  /* Mask out any invalid flags */
452  FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
453 
454  /* Check if this is a VDM app */
455  if (PsGetCurrentProcess()->VdmObjects)
456  {
457  /* Allow the EM flag */
458  FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
459  (CR0_EM | CR0_MP);
460  }
461  }
462  }
463 
464  /* Handle the floating point state */
465  if (((ContextFlags & CONTEXT_FLOATING_POINT) ==
466  CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame))
467  {
468  /* Get the FX Area */
469  FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
470 
471  /* Check if NPX is present */
472  if (KeI386NpxPresent)
473  {
474  /* Flush the NPX State */
476 
477  /* Check if we have Fxsr support */
478  if (KeI386FxsrPresent)
479  {
480  /* Convert the Fn Floating Point state to Fx */
481  FxSaveArea->U.FxArea.ControlWord =
482  (USHORT)Context->FloatSave.ControlWord;
483  FxSaveArea->U.FxArea.StatusWord =
484  (USHORT)Context->FloatSave.StatusWord;
485  FxSaveArea->U.FxArea.TagWord =
486  KiTagWordFnsaveToFxsave((USHORT)Context->FloatSave.TagWord);
487  FxSaveArea->U.FxArea.ErrorOpcode =
488  (USHORT)((Context->FloatSave.ErrorSelector >> 16) & 0xFFFF);
489  FxSaveArea->U.FxArea.ErrorOffset =
490  Context->FloatSave.ErrorOffset;
491  FxSaveArea->U.FxArea.ErrorSelector =
492  Context->FloatSave.ErrorSelector & 0xFFFF;
493  FxSaveArea->U.FxArea.DataOffset =
494  Context->FloatSave.DataOffset;
495  FxSaveArea->U.FxArea.DataSelector =
496  Context->FloatSave.DataSelector;
497 
498  /* Clear out the Register Area */
499  RtlZeroMemory(&FxSaveArea->U.FxArea.RegisterArea[0],
501 
502  /* Loop the 8 floating point registers */
503  for (i = 0; i < 8; i++)
504  {
505  /* Copy from Fn to Fx */
506  RtlCopyMemory(FxSaveArea->U.FxArea.RegisterArea + (i * 16),
507  Context->FloatSave.RegisterArea + (i * 10),
508  10);
509  }
510  }
511  else
512  {
513  /* Copy the structure */
514  FxSaveArea->U.FnArea.ControlWord = Context->FloatSave.
515  ControlWord;
516  FxSaveArea->U.FnArea.StatusWord = Context->FloatSave.
517  StatusWord;
518  FxSaveArea->U.FnArea.TagWord = Context->FloatSave.TagWord;
519  FxSaveArea->U.FnArea.ErrorOffset = Context->FloatSave.
520  ErrorOffset;
521  FxSaveArea->U.FnArea.ErrorSelector = Context->FloatSave.
522  ErrorSelector;
523  FxSaveArea->U.FnArea.DataOffset = Context->FloatSave.
524  DataOffset;
525  FxSaveArea->U.FnArea.DataSelector = Context->FloatSave.
526  DataSelector;
527 
528  /* Loop registers */
529  for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
530  {
531  /* Copy registers */
532  FxSaveArea->U.FnArea.RegisterArea[i] =
533  Context->FloatSave.RegisterArea[i];
534  }
535  }
536 
537  /* Mask out any invalid flags */
538  FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
539 
540  /* Check if this is a VDM app */
541  if (PsGetCurrentProcess()->VdmObjects)
542  {
543  /* Allow the EM flag */
544  FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
545  (CR0_EM | CR0_MP);
546  }
547  }
548  else
549  {
550  /* FIXME: Handle FPU Emulation */
551  //ASSERT(FALSE);
553  }
554  }
555 
556  /* Handle the Debug Registers */
557  if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
558  {
559  /* Copy Dr0 - Dr4 */
560  TrapFrame->Dr0 = Context->Dr0;
561  TrapFrame->Dr1 = Context->Dr1;
562  TrapFrame->Dr2 = Context->Dr2;
563  TrapFrame->Dr3 = Context->Dr3;
564 
565  /* If we're in user-mode */
566  if (PreviousMode != KernelMode)
567  {
568  /* Make sure, no Dr address is above user space */
569  if (Context->Dr0 > (ULONG)MmHighestUserAddress) TrapFrame->Dr0 = 0;
570  if (Context->Dr1 > (ULONG)MmHighestUserAddress) TrapFrame->Dr1 = 0;
571  if (Context->Dr2 > (ULONG)MmHighestUserAddress) TrapFrame->Dr2 = 0;
572  if (Context->Dr3 > (ULONG)MmHighestUserAddress) TrapFrame->Dr3 = 0;
573  }
574 
575  /* Now sanitize and save DR6 */
576  TrapFrame->Dr6 = Context->Dr6 & DR6_LEGAL;
577 
578  /* Update the Dr active mask */
579  if (TrapFrame->Dr0) DrMask |= DR_MASK(0);
580  if (TrapFrame->Dr1) DrMask |= DR_MASK(1);
581  if (TrapFrame->Dr2) DrMask |= DR_MASK(2);
582  if (TrapFrame->Dr3) DrMask |= DR_MASK(3);
583  if (TrapFrame->Dr6) DrMask |= DR_MASK(6);
584 
585  /* Sanitize and save DR7 */
586  TrapFrame->Dr7 = Context->Dr7 & DR7_LEGAL;
587  KiRecordDr7(&TrapFrame->Dr7, &DrMask);
588 
589  /* If we're in user-mode */
590  if (PreviousMode != KernelMode)
591  {
592  /* Save the mask */
593  KeGetCurrentThread()->Header.DebugActive = (UCHAR)DrMask;
594  }
595  }
596 
597  /* Check if thread has IOPL and force it enabled if so */
598  if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL;
599 
600  /* Restore IRQL */
601  if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
602 }
603 
604 VOID
605 NTAPI
607  IN PKEXCEPTION_FRAME ExceptionFrame,
609 {
610  PFX_SAVE_AREA FxSaveArea;
611  struct _AlignHack
612  {
613  UCHAR Hack[15];
614  FLOATING_SAVE_AREA UnalignedArea;
615  } FloatSaveBuffer;
616  FLOATING_SAVE_AREA *FloatSaveArea;
617  KIRQL OldIrql;
618  ULONG i;
619 
620  /* Do this at APC_LEVEL */
621  OldIrql = KeGetCurrentIrql();
622  if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
623 
624  /* Start with the Control flags */
625  if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
626  {
627  /* EBP, EIP and EFLAGS */
628  Context->Ebp = TrapFrame->Ebp;
629  Context->Eip = TrapFrame->Eip;
630  Context->EFlags = TrapFrame->EFlags;
631 
632  /* Return the correct CS */
633  if (!(TrapFrame->SegCs & FRAME_EDITED) &&
634  !(TrapFrame->EFlags & EFLAGS_V86_MASK))
635  {
636  /* Get it from the Temp location */
637  Context->SegCs = TrapFrame->TempSegCs & 0xFFFF;
638  }
639  else
640  {
641  /* Return it directly */
642  Context->SegCs = TrapFrame->SegCs & 0xFFFF;
643  }
644 
645  /* Get the Ss and ESP */
646  Context->SegSs = KiSsFromTrapFrame(TrapFrame);
647  Context->Esp = KiEspFromTrapFrame(TrapFrame);
648  }
649 
650  /* Handle the Segments */
651  if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
652  {
653  /* Do V86 Mode first */
654  if (TrapFrame->EFlags & EFLAGS_V86_MASK)
655  {
656  /* Return from the V86 location */
657  Context->SegGs = TrapFrame->V86Gs & 0xFFFF;
658  Context->SegFs = TrapFrame->V86Fs & 0xFFFF;
659  Context->SegEs = TrapFrame->V86Es & 0xFFFF;
660  Context->SegDs = TrapFrame->V86Ds & 0xFFFF;
661  }
662  else
663  {
664  /* Check if this was a Kernel Trap */
665  if (TrapFrame->SegCs == KGDT_R0_CODE)
666  {
667  /* Set valid selectors */
668  TrapFrame->SegGs = 0;
669  TrapFrame->SegFs = KGDT_R0_PCR;
670  TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
671  TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
672  }
673 
674  /* Return the segments */
675  Context->SegGs = TrapFrame->SegGs & 0xFFFF;
676  Context->SegFs = TrapFrame->SegFs & 0xFFFF;
677  Context->SegEs = TrapFrame->SegEs & 0xFFFF;
678  Context->SegDs = TrapFrame->SegDs & 0xFFFF;
679  }
680  }
681 
682  /* Handle the simple registers */
683  if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
684  {
685  /* Return them directly */
686  Context->Eax = TrapFrame->Eax;
687  Context->Ebx = TrapFrame->Ebx;
688  Context->Ecx = TrapFrame->Ecx;
689  Context->Edx = TrapFrame->Edx;
690  Context->Esi = TrapFrame->Esi;
691  Context->Edi = TrapFrame->Edi;
692  }
693 
694  /* Handle extended registers */
695  if (((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
696  CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame))
697  {
698  /* Get the FX Save Area */
699  FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
700 
701  /* Make sure NPX is present */
702  if (KeI386NpxPresent)
703  {
704  /* Flush the NPX State */
706 
707  /* Copy the registers */
708  RtlCopyMemory(&Context->ExtendedRegisters[0],
709  &FxSaveArea->U.FxArea,
711  }
712  }
713 
714  /* Handle Floating Point */
715  if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
716  CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame))
717  {
718  /* Get the FX Save Area */
719  FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
720 
721  /* Make sure we have an NPX */
722  if (KeI386NpxPresent)
723  {
724  /* Check if we have Fxsr support */
725  if (KeI386FxsrPresent)
726  {
727  /* Align the floating area to 16-bytes */
728  FloatSaveArea = (FLOATING_SAVE_AREA*)
729  ((ULONG_PTR)&FloatSaveBuffer.UnalignedArea &~ 0xF);
730 
731  /* Get the State */
732  KiFlushNPXState(FloatSaveArea);
733  }
734  else
735  {
736  /* We don't, use the FN area and flush the NPX State */
737  FloatSaveArea = (FLOATING_SAVE_AREA*)&FxSaveArea->U.FnArea;
739  }
740 
741  /* Copy structure */
742  Context->FloatSave.ControlWord = FloatSaveArea->ControlWord;
743  Context->FloatSave.StatusWord = FloatSaveArea->StatusWord;
744  Context->FloatSave.TagWord = FloatSaveArea->TagWord;
745  Context->FloatSave.ErrorOffset = FloatSaveArea->ErrorOffset;
746  Context->FloatSave.ErrorSelector = FloatSaveArea->ErrorSelector;
747  Context->FloatSave.DataOffset = FloatSaveArea->DataOffset;
748  Context->FloatSave.DataSelector = FloatSaveArea->DataSelector;
749  Context->FloatSave.Cr0NpxState = FxSaveArea->Cr0NpxState;
750 
751  /* Loop registers */
752  for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
753  {
754  /* Copy them */
755  Context->FloatSave.RegisterArea[i] =
756  FloatSaveArea->RegisterArea[i];
757  }
758  }
759  else
760  {
761  /* FIXME: Handle Emulation */
762  ASSERT(FALSE);
763  }
764  }
765 
766  /* Handle debug registers */
767  if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
769  {
770  /* Make sure DR7 is valid */
771  if (TrapFrame->Dr7 & ~DR7_RESERVED_MASK)
772  {
773  /* Copy the debug registers */
774  Context->Dr0 = TrapFrame->Dr0;
775  Context->Dr1 = TrapFrame->Dr1;
776  Context->Dr2 = TrapFrame->Dr2;
777  Context->Dr3 = TrapFrame->Dr3;
778  Context->Dr6 = TrapFrame->Dr6;
779 
780  /* Update DR7 */
781  Context->Dr7 = KiUpdateDr7(TrapFrame->Dr7);
782  }
783  else
784  {
785  /* Otherwise clear DR registers */
786  Context->Dr0 =
787  Context->Dr1 =
788  Context->Dr2 =
789  Context->Dr3 =
790  Context->Dr6 =
791  Context->Dr7 = 0;
792  }
793  }
794 
795  /* Restore IRQL */
796  if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
797 }
798 
799 BOOLEAN
800 FASTCALL
802 {
803  ULONG Eip;
804  PKTRAP_FRAME TrapFrame = TrapInformation;
806 
807  /* Don't do anything if we didn't get a trap frame */
808  if (!TrapInformation) return FALSE;
809 
810  /* Check where we came from */
811  switch (TrapFrame->SegCs)
812  {
813  /* Kernel mode */
814  case KGDT_R0_CODE:
815 
816  /* Allow S-LIST Routine to fail */
817  Eip = (ULONG)&ExpInterlockedPopEntrySListFault;
818  break;
819 
820  /* User code */
821  case KGDT_R3_CODE | RPL_MASK:
822 
823  /* Allow S-LIST Routine to fail */
824  //Eip = (ULONG)KeUserPopEntrySListFault;
825  Eip = 0;
826  break;
827 
828  default:
829 
830  /* Anything else gets a bugcheck */
831  Eip = 0;
832  }
833 
834  /* Return TRUE if we want to keep the system up */
835  return (TrapFrame->Eip == Eip) ? TRUE : FALSE;
836 }
837 
838 VOID
839 NTAPI
841  IN PKEXCEPTION_FRAME ExceptionFrame,
842  IN PKTRAP_FRAME TrapFrame,
844  IN BOOLEAN FirstChance)
845 {
847  EXCEPTION_RECORD LocalExceptRecord;
848 
849  /* Increase number of Exception Dispatches */
850  KeGetCurrentPrcb()->KeExceptionDispatchCount++;
851 
852  /* Set the context flags */
854 
855  /* Check if User Mode or if the kernel debugger is enabled */
856  if ((PreviousMode == UserMode) || (KeGetPcr()->KdVersionBlock))
857  {
858  /* Add the FPU Flag */
860 
861  /* Check for NPX Support */
862  if (KeI386FxsrPresent)
863  {
864  /* Save those too */
866  }
867  }
868 
869  /* Get a Context */
870  KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
871 
872  /* Look at our exception code */
873  switch (ExceptionRecord->ExceptionCode)
874  {
875  /* Breakpoint */
876  case STATUS_BREAKPOINT:
877 
878  /* Decrement EIP by one */
879  Context.Eip--;
880  break;
881 
882  /* Internal exception */
884 
885  /* Set correct code */
886  ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
887  if (PreviousMode == UserMode)
888  {
889  /* FIXME: Handle no execute */
890  }
891  break;
892  }
893 
894  /* Sanity check */
895  ASSERT(!((PreviousMode == KernelMode) &&
896  (Context.EFlags & EFLAGS_V86_MASK)));
897 
898  /* Handle kernel-mode first, it's simpler */
899  if (PreviousMode == KernelMode)
900  {
901  /* Check if this is a first-chance exception */
902  if (FirstChance != FALSE)
903  {
904  /* Break into the debugger for the first time */
905  if (KiDebugRoutine(TrapFrame,
906  ExceptionFrame,
907  ExceptionRecord,
908  &Context,
909  PreviousMode,
910  FALSE))
911  {
912  /* Exception was handled */
913  goto Handled;
914  }
915 
916  /* If the Debugger couldn't handle it, dispatch the exception */
917  if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled;
918  }
919 
920  /* This is a second-chance exception, only for the debugger */
921  if (KiDebugRoutine(TrapFrame,
922  ExceptionFrame,
923  ExceptionRecord,
924  &Context,
925  PreviousMode,
926  TRUE))
927  {
928  /* Exception was handled */
929  goto Handled;
930  }
931 
932  /* Third strike; you're out */
933  KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
934  ExceptionRecord->ExceptionCode,
935  (ULONG_PTR)ExceptionRecord->ExceptionAddress,
936  (ULONG_PTR)TrapFrame,
937  0);
938  }
939  else
940  {
941  /* User mode exception, was it first-chance? */
942  if (FirstChance)
943  {
944  /*
945  * Break into the kernel debugger unless a user mode debugger
946  * is present or user mode exceptions are ignored, except if this
947  * is a debug service which we must always pass to KD
948  */
949  if ((!(PsGetCurrentProcess()->DebugPort) &&
950  !(KdIgnoreUmExceptions)) ||
951  (KdIsThisAKdTrap(ExceptionRecord,
952  &Context,
953  PreviousMode)))
954  {
955  /* Call the kernel debugger */
956  if (KiDebugRoutine(TrapFrame,
957  ExceptionFrame,
958  ExceptionRecord,
959  &Context,
960  PreviousMode,
961  FALSE))
962  {
963  /* Exception was handled */
964  goto Handled;
965  }
966  }
967 
968  /* Forward exception to user mode debugger */
969  if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) return;
970 
971  /* Set up the user-stack */
972 DispatchToUser:
973  _SEH2_TRY
974  {
975  ULONG Size;
976  ULONG_PTR Stack, NewStack;
977 
978  /* Make sure we have a valid SS and that this isn't V86 mode */
979  if ((TrapFrame->HardwareSegSs != (KGDT_R3_DATA | RPL_MASK)) ||
980  (TrapFrame->EFlags & EFLAGS_V86_MASK))
981  {
982  /* Raise an exception instead */
983  LocalExceptRecord.ExceptionCode = STATUS_ACCESS_VIOLATION;
984  LocalExceptRecord.ExceptionFlags = 0;
985  LocalExceptRecord.NumberParameters = 0;
986  RtlRaiseException(&LocalExceptRecord);
987  }
988 
989  /* Align context size and get stack pointer */
990  Size = (sizeof(CONTEXT) + 3) & ~3;
991  Stack = (Context.Esp & ~3) - Size;
992 
993  /* Probe stack and copy Context */
994  ProbeForWrite((PVOID)Stack, Size, sizeof(ULONG));
995  RtlCopyMemory((PVOID)Stack, &Context, sizeof(CONTEXT));
996 
997  /* Align exception record size and get stack pointer */
998  Size = (sizeof(EXCEPTION_RECORD) -
1000  ExceptionRecord->NumberParameters) *
1001  sizeof(ULONG) + 3) & ~3;
1002  NewStack = Stack - Size;
1003 
1004  /* Probe stack and copy exception record */
1005  ProbeForWrite((PVOID)(NewStack - 2 * sizeof(ULONG_PTR)),
1006  Size + 2 * sizeof(ULONG_PTR),
1007  sizeof(ULONG));
1008  RtlCopyMemory((PVOID)NewStack, ExceptionRecord, Size);
1009 
1010  /* Now write the two params for the user-mode dispatcher */
1011  *(PULONG_PTR)(NewStack - 1 * sizeof(ULONG_PTR)) = Stack;
1012  *(PULONG_PTR)(NewStack - 2 * sizeof(ULONG_PTR)) = NewStack;
1013 
1014  /* Set new Stack Pointer */
1015  KiSsToTrapFrame(TrapFrame, KGDT_R3_DATA);
1016  KiEspToTrapFrame(TrapFrame, NewStack - 2 * sizeof(ULONG_PTR));
1017 
1018  /* Force correct segments */
1019  TrapFrame->SegCs = Ke386SanitizeSeg(KGDT_R3_CODE, PreviousMode);
1020  TrapFrame->SegDs = Ke386SanitizeSeg(KGDT_R3_DATA, PreviousMode);
1021  TrapFrame->SegEs = Ke386SanitizeSeg(KGDT_R3_DATA, PreviousMode);
1022  TrapFrame->SegFs = Ke386SanitizeSeg(KGDT_R3_TEB, PreviousMode);
1023  TrapFrame->SegGs = 0;
1024 
1025  /* Set EIP to the User-mode Dispatcher */
1026  TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
1027 
1028  /* Dispatch exception to user-mode */
1029  _SEH2_YIELD(return);
1030  }
1031  _SEH2_EXCEPT((RtlCopyMemory(&LocalExceptRecord, _SEH2_GetExceptionInformation()->ExceptionRecord, sizeof(EXCEPTION_RECORD)), EXCEPTION_EXECUTE_HANDLER))
1032  {
1033  /* Check if we got a stack overflow and raise that instead */
1034  if ((NTSTATUS)LocalExceptRecord.ExceptionCode ==
1036  {
1037  /* Copy the exception address and record */
1038  LocalExceptRecord.ExceptionAddress =
1039  ExceptionRecord->ExceptionAddress;
1040  RtlCopyMemory(ExceptionRecord,
1041  (PVOID)&LocalExceptRecord,
1042  sizeof(EXCEPTION_RECORD));
1043 
1044  /* Do the exception again */
1045  _SEH2_YIELD(goto DispatchToUser);
1046  }
1047  }
1048  _SEH2_END;
1049 
1050  DPRINT("First chance exception in %.16s, ExceptionCode: %lx, ExceptionAddress: %p, P0: %lx, P1: %lx\n",
1051  PsGetCurrentProcess()->ImageFileName,
1052  ExceptionRecord->ExceptionCode,
1053  ExceptionRecord->ExceptionAddress,
1054  ExceptionRecord->ExceptionInformation[0],
1055  ExceptionRecord->ExceptionInformation[1]);
1056  }
1057 
1058  /* Try second chance */
1059  if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
1060  {
1061  /* Handled, get out */
1062  return;
1063  }
1064  else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
1065  {
1066  /* Handled, get out */
1067  return;
1068  }
1069 
1070  /* 3rd strike, kill the process */
1071  DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %p, BaseAddress: %p, P0: %lx, P1: %lx\n",
1072  PsGetCurrentProcess()->ImageFileName,
1073  ExceptionRecord->ExceptionCode,
1074  ExceptionRecord->ExceptionAddress,
1075  PsGetCurrentProcess()->SectionBaseAddress,
1076  ExceptionRecord->ExceptionInformation[0],
1077  ExceptionRecord->ExceptionInformation[1]);
1078 
1079  ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
1080  KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
1081  ExceptionRecord->ExceptionCode,
1082  (ULONG_PTR)ExceptionRecord->ExceptionAddress,
1083  (ULONG_PTR)TrapFrame,
1084  0);
1085  }
1086 
1087 Handled:
1088  /* Convert the context back into Trap/Exception Frames */
1089  KeContextToTrapFrame(&Context,
1090  ExceptionFrame,
1091  TrapFrame,
1092  Context.ContextFlags,
1093  PreviousMode);
1094  return;
1095 }
1096 
1098 VOID
1099 NTAPI
1101  IN ULONG Flags,
1103  IN ULONG ParameterCount,
1104  IN ULONG_PTR Parameter1,
1105  IN ULONG_PTR Parameter2,
1106  IN ULONG_PTR Parameter3,
1107  IN PKTRAP_FRAME TrapFrame)
1108 {
1109  EXCEPTION_RECORD ExceptionRecord;
1110 
1111  /* Build the exception record */
1112  ExceptionRecord.ExceptionCode = Code;
1113  ExceptionRecord.ExceptionFlags = Flags;
1114  ExceptionRecord.ExceptionRecord = NULL;
1115  ExceptionRecord.ExceptionAddress = (PVOID)Address;
1116  ExceptionRecord.NumberParameters = ParameterCount;
1117  if (ParameterCount)
1118  {
1119  /* Copy extra parameters */
1120  ExceptionRecord.ExceptionInformation[0] = Parameter1;
1121  ExceptionRecord.ExceptionInformation[1] = Parameter2;
1122  ExceptionRecord.ExceptionInformation[2] = Parameter3;
1123  }
1124 
1125  /* Now go dispatch the exception */
1126  KiDispatchException(&ExceptionRecord,
1127  NULL,
1128  TrapFrame,
1129  TrapFrame->EFlags & EFLAGS_V86_MASK ?
1130  -1 : KiUserTrap(TrapFrame),
1131  TRUE);
1132 
1133  /* Return from this trap */
1134  KiEoiHelper(TrapFrame);
1135 }
1136 
1138 VOID
1139 FASTCALL
1141  IN PKTRAP_FRAME TrapFrame)
1142 {
1143  /* Bugcheck the system */
1144  KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
1145  ExceptionCode,
1146  0,
1147  0,
1148  0,
1149  TrapFrame);
1150 }
1151 
1152 /* PUBLIC FUNCTIONS ***********************************************************/
1153 
1154 /*
1155  * @implemented
1156  */
1157 NTSTATUS
1158 NTAPI
1160 {
1161  ULONG OldEip;
1162  PTEB Teb = KeGetCurrentThread()->Teb;
1163  PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
1164 
1165  /* Make sure we can access the TEB */
1166  _SEH2_TRY
1167  {
1168  /* Set the exception code */
1169  Teb->ExceptionCode = ExceptionCode;
1170  }
1172  {
1173  /* Return the exception code */
1175  }
1176  _SEH2_END;
1177 
1178  /* Get the old EIP */
1179  OldEip = TrapFrame->Eip;
1180 
1181  /* Change it to the user-mode dispatcher */
1183 
1184  /* Return the old EIP */
1185  return (NTSTATUS)OldEip;
1186 }
#define CR0_MP
Definition: asm.h:246
DWORD *typedef PVOID
Definition: winlogon.h:52
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define SIZE_OF_FX_REGISTERS
Definition: ketypes.h:194
#define IN
Definition: typedefs.h:39
struct _CONTEXT CONTEXT
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
DBGKD_GET_VERSION64 KdVersionBlock
Definition: kddata.c:371
PVOID ULONG Address
Definition: oprghdlr.h:14
VOID NTAPI Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:280
#define CONTEXT_EXTENDED_REGISTERS
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
ULONG DataSelector
Definition: ketypes.h:419
ULONG Esp
Definition: nt_native.h:1479
union _FX_SAVE_AREA::@2190 U
ULONG Eip
Definition: nt_native.h:1476
PKDEBUG_ROUTINE KiDebugRoutine
Definition: kdmain.c:471
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
ULONG NTAPI KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:220
ULONG FASTCALL KiUpdateDr7(IN ULONG Dr7)
Definition: exp.c:42
ULONG TagWord
Definition: ketypes.h:415
ULONG MXCsr
Definition: ketypes.h:433
FORCEINLINE ULONG Ke386SanitizeFlags(IN ULONG Eflags, IN KPROCESSOR_MODE Mode)
Definition: ke.h:610
ULONG ErrorSelector
Definition: ketypes.h:430
USHORT ControlWord
Definition: ketypes.h:425
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1054
#define DR7_RESERVED_MASK
Definition: asm.h:511
BOOLEAN FASTCALL KiRecordDr7(OUT PULONG Dr7Ptr, OUT PULONG DrMask)
Definition: exp.c:61
#define CR0_TS
Definition: asm.h:248
#define KGDT_R0_CODE
Definition: ketypes.h:74
VOID INIT_FUNCTION NTAPI KeInitExceptions(VOID)
Definition: exp.c:23
#define EXCEPTION_MAXIMUM_PARAMETERS
Definition: compat.h:194
ULONG KeI386NpxPresent
Definition: cpu.c:31
#define CONTEXT_FULL
Definition: compat.h:270
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
USHORT StatusWord
Definition: ketypes.h:426
#define FASTCALL
Definition: nt_native.h:50
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
int32_t INT
Definition: typedefs.h:57
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:168
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define KeGetPcr()
Definition: ke.h:25
ULONG KeI386FxsrPresent
Definition: cpu.c:31
PVOID ExceptionAddress
Definition: compat.h:199
USHORT NTAPI KiTagWordFnsaveToFxsave(USHORT TagWord)
Definition: exp.c:263
#define EFLAGS_V86_MASK
Definition: ketypes.h:129
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define DR_REG_MASK
Definition: ke.h:11
DWORD ExceptionCode
Definition: compat.h:196
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLenum GLclampf GLint i
Definition: glfuncs.h:14
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1456
ULONG NTAPI KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:137
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
PVOID KeRaiseUserExceptionDispatcher
Definition: ke.h:133
VOID NTAPI KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame, IN ULONG Ss)
Definition: exp.c:242
ULONG ErrorOffset
Definition: ketypes.h:416
#define _SEH2_END
Definition: pseh2_64.h:7
struct _EXCEPTION_RECORD EXCEPTION_RECORD
VOID NTAPI KeContextToTrapFrame(IN PCONTEXT Context, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame, IN ULONG ContextFlags, IN KPROCESSOR_MODE PreviousMode)
Definition: exp.c:19
DECLSPEC_NORETURN VOID NTAPI KeBugCheckWithTf(ULONG BugCheckCode, ULONG_PTR BugCheckParameter1, ULONG_PTR BugCheckParameter2, ULONG_PTR BugCheckParameter3, ULONG_PTR BugCheckParameter4, PKTRAP_FRAME Tf)
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define DR7_OVERRIDE_V
Definition: asm.h:510
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define RPL_MASK
Definition: ketypes.h:69
smooth NULL
Definition: ftsmooth.c:513
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
USHORT SegCs
Definition: ketypes.h:380
UCHAR RegisterArea[80]
Definition: ketypes.h:420
void DPRINT(...)
Definition: polytest.cpp:61
ULONG Cr0NpxState
Definition: ketypes.h:449
UCHAR RegisterArea[SIZE_OF_FX_REGISTERS]
Definition: ketypes.h:435
USHORT TagWord
Definition: ketypes.h:427
#define KGDT_R3_DATA
Definition: ketypes.h:77
ULONG EFlags
Definition: nt_native.h:1478
#define MAXIMUM_IDTVECTOR
Definition: asm.h:277
ULONG KiMXCsrMask
Definition: cpu.c:28
VOID NTAPI ExpInterlockedPopEntrySListFault(VOID)
ULONG ContextFlags
Definition: compat.h:331
#define NtCurrentProcess()
Definition: nt_native.h:1657
UINTN Size
Definition: acefiex.h:555
#define Code
Definition: deflate.h:80
VOID NTAPI KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
Definition: exp.c:151
UCHAR RegisterArea[SIZE_OF_80387_REGISTERS]
Definition: nt_native.h:1390
NTSYSAPI BOOLEAN NTAPI RtlDispatchException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context)
Definition: except.c:34
unsigned char BOOLEAN
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define CONTEXT_CONTROL
Definition: compat.h:265
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:201
struct _FX_SAVE_AREA FX_SAVE_AREA
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
BOOLEAN NTAPI DbgkForwardException(IN PEXCEPTION_RECORD ExceptionRecord, IN BOOLEAN DebugPort, IN BOOLEAN SecondChance)
Definition: dbgkobj.c:317
if(!(yy_init))
Definition: macro.lex.yy.c:704
_In_ BOOLEAN Handled
Definition: ketypes.h:337
#define KGDT_R0_DATA
Definition: ketypes.h:75
#define DR7_OVERRIDE_MASK
Definition: asm.h:512
ULONG DataOffset
Definition: ketypes.h:431
ULONG ErrorSelector
Definition: ketypes.h:417
#define KGDT_R3_TEB
Definition: ketypes.h:80
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
LONG ExceptionCode
Definition: compat.h:502
BOOLEAN NTAPI KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN KPROCESSOR_MODE PreviousMode)
Definition: kdmain.c:259
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
NTSTATUS NTAPI KeRaiseUserException(_In_ NTSTATUS ExceptionCode)
Definition: exp.c:266
#define KGDT_R0_PCR
Definition: ketypes.h:79
#define DR6_LEGAL
Definition: asm.h:507
USHORT ExtendedOffset
Definition: ketypes.h:387
PVOID KeUserExceptionDispatcher
Definition: ke.h:132
ULONG ControlWord
Definition: ketypes.h:413
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: exp.c:86
unsigned char UCHAR
Definition: xmlstorage.h:181
ULONG DataSelector
Definition: ketypes.h:432
#define EFLAGS_IOPL
Definition: cpu.c:17
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1451
BOOLEAN FASTCALL KeInvalidAccessAllowed(IN PVOID TrapInformation OPTIONAL)
Definition: exp.c:801
VOID NTAPI KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame, IN ULONG Esp)
Definition: exp.c:164
DECLSPEC_NORETURN VOID NTAPI KiDispatchExceptionFromTrapFrame(IN NTSTATUS Code, IN ULONG Flags, IN ULONG_PTR Address, IN ULONG ParameterCount, IN ULONG_PTR Parameter1, IN ULONG_PTR Parameter2, IN ULONG_PTR Parameter3, IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:1100
ULONG Eip
Definition: ketypes.h:265
ULONG ErrorOffset
Definition: ketypes.h:429
DECLSPEC_NORETURN VOID FASTCALL KiSystemFatalException(IN ULONG ExceptionCode, IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:1140
FORCEINLINE ULONG Ke386SanitizeSeg(IN ULONG Cs, IN KPROCESSOR_MODE Mode)
Definition: ke.h:593
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:198
KIDTENTRY KiIdt[MAXIMUM_IDTVECTOR+1]
Definition: except.c:50
ULONG StatusWord
Definition: ketypes.h:414
Definition: compat.h:484
LONG NTSTATUS
Definition: DriverTester.h:11
struct _FX_SAVE_AREA * PFX_SAVE_AREA
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
unsigned short USHORT
Definition: pedump.c:61
#define CONTEXT_FLOATING_POINT
Definition: compat.h:267
#define MAXIMUM_SUPPORTED_EXTENSION
Definition: x86context.h:35
#define _SEH2_TRY
Definition: pseh2_64.h:5
BOOLEAN KdIgnoreUmExceptions
Definition: kdmain.c:22
VOID NTAPI KiFlushNPXState(IN FLOATING_SAVE_AREA *SaveArea)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
USHORT ErrorOpcode
Definition: ketypes.h:428
unsigned int * PULONG
Definition: retypes.h:1
PVOID MmHighestUserAddress
Definition: rtlcompat.c:26
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:475
ULONG DataOffset
Definition: ketypes.h:418
FNSAVE_FORMAT FnArea
Definition: ketypes.h:445
#define DPRINT1
Definition: precomp.h:8
#define KGDT_R3_CODE
Definition: ketypes.h:76
#define OUT
Definition: typedefs.h:40
void __cdecl _disable(void)
Definition: intrin_arm.h:365
struct tagContext Context
Definition: acpixf.h:1014
unsigned int ULONG
Definition: retypes.h:1
#define DR_MASK(x)
Definition: ke.h:10
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
DWORD ExceptionFlags
Definition: compat.h:197
uint32_t * PULONG_PTR
Definition: typedefs.h:64
#define FRAME_EDITED
Definition: ke.h:40
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
DWORD NumberParameters
Definition: compat.h:200
#define KeGetCurrentThread
Definition: hal.h:44
#define SIZE_OF_80387_REGISTERS
Definition: nt_native.h:1356
FXSAVE_FORMAT FxArea
Definition: ketypes.h:446
PVOID InitialStack
Definition: ketypes.h:937
USHORT Selector
Definition: ketypes.h:385
#define APC_LEVEL
Definition: env_spec_w32.h:695
IN HDEVINFO IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
Definition: devinst.c:44
#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:90
#define CONTEXT_INTEGER
Definition: compat.h:266
#define CONTEXT_DEBUG_REGISTERS
Definition: compat.h:268
#define CR0_EM
Definition: asm.h:247
BOOLEAN FORCEINLINE KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:281
#define DR7_LEGAL
Definition: ketypes.h:100
#define INIT_FUNCTION
Definition: ntoskrnl.h:11