Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

exceptn.c File Reference

#include "ki.h"

Go to the source code of this file.

Defines

#define FN_BITS_PER_TAGWORD   16
#define FN_TAG_EMPTY   0x3
#define FN_TAG_MASK   0x3
#define FX_TAG_VALID   0x1
#define NUMBER_OF_FP_REGISTERS   8
#define BYTES_PER_FP_REGISTER   10
#define BYTES_PER_FX_REGISTER   16

Functions

VOID Ki386AdjustEsp0 (IN PKTRAP_FRAME TrapFrame)
BOOLEAN KiEm87StateToNpxFrame (OUT PFLOATING_SAVE_AREA NpxFrmae)
BOOLEAN KiNpxFrameToEm87State (IN PFLOATING_SAVE_AREA NpxFrmae)
ULONG KiEspFromTrapFrame (IN PKTRAP_FRAME TrapFrame)
VOID KiEspToTrapFrame (IN PKTRAP_FRAME TrapFrame, IN ULONG Esp)
ULONG KiSegSsFromTrapFrame (IN PKTRAP_FRAME TrapFrame)
VOID KiSegSsToTrapFrame (IN PKTRAP_FRAME TrapFrame, IN ULONG SegSs)
VOID KeContextFromKframes (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT ContextFrame)
VOID KeContextToKframes (IN OUT PKTRAP_FRAME TrapFrame, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN PCONTEXT ContextFrame, IN ULONG ContextFlags, IN KPROCESSOR_MODE PreviousMode)
VOID KiDispatchException (IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
ULONG KiCopyInformation (IN OUT PEXCEPTION_RECORD ExceptionRecord1, IN PEXCEPTION_RECORD ExceptionRecord2)
NTSTATUS KeRaiseUserException (IN NTSTATUS ExceptionCode)

Variables

UCHAR VdmUserCr0MapIn []
BOOLEAN KeI386FxsrPresent
BOOLEAN KeI386XMMIPresent


Define Documentation

#define BYTES_PER_FP_REGISTER   10
 

Definition at line 41 of file i386/exceptn.c.

Referenced by KeContextToKframes().

#define BYTES_PER_FX_REGISTER   16
 

Definition at line 42 of file i386/exceptn.c.

Referenced by KeContextToKframes().

#define FN_BITS_PER_TAGWORD   16
 

Definition at line 36 of file i386/exceptn.c.

Referenced by KeContextToKframes().

#define FN_TAG_EMPTY   0x3
 

Definition at line 37 of file i386/exceptn.c.

Referenced by KeContextToKframes().

#define FN_TAG_MASK   0x3
 

Definition at line 38 of file i386/exceptn.c.

Referenced by KeContextToKframes().

#define FX_TAG_VALID   0x1
 

Definition at line 39 of file i386/exceptn.c.

Referenced by KeContextToKframes().

#define NUMBER_OF_FP_REGISTERS   8
 

Definition at line 40 of file i386/exceptn.c.

Referenced by KeContextToKframes().


Function Documentation

VOID KeContextFromKframes IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN OUT PCONTEXT  ContextFrame
 

Definition at line 278 of file i386/exceptn.c.

References Buffer, CONTEXT_CONTROL, CONTEXT_FLOATING_POINT, CONTEXT_INTEGER, KeGetCurrentThread, KeI386FxsrPresent, KeI386NpxPresent, KernelMode, KiEm87StateToNpxFrame(), KiEspFromTrapFrame(), KiSegSsFromTrapFrame(), L, NULL, TRUE, and UserMode.

00286 : 00287 00288 This routine moves the selected contents of the specified trap and exception frames 00289 frames into the specified context frame according to the specified context 00290 flags. 00291 00292 Arguments: 00293 00294 TrapFrame - Supplies a pointer to a trap frame from which volatile context 00295 should be copied into the context record. 00296 00297 ExceptionFrame - Supplies a pointer to an exception frame from which context 00298 should be copied into the context record. This argument is ignored since 00299 there is no exception frame on NT386. 00300 00301 ContextFrame - Supplies a pointer to the context frame that receives the 00302 context copied from the trap and exception frames. 00303 00304 Return Value: 00305 00306 None. 00307 00308 --*/ 00309 00310 { 00311 00312 PFX_SAVE_AREA NpxFrame; 00313 BOOLEAN StateSaved; 00314 ULONG i; 00315 struct _FPSaveBuffer { 00316 UCHAR Buffer[15]; 00317 FLOATING_SAVE_AREA SaveArea; 00318 } FloatSaveBuffer; 00319 PFLOATING_SAVE_AREA PSaveArea; 00320 00321 UNREFERENCED_PARAMETER( ExceptionFrame ); 00322 00323 // 00324 // Set control information if specified. 00325 // 00326 00327 if ((ContextFrame->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) { 00328 00329 // 00330 // Set registers ebp, eip, cs, eflag, esp and ss. 00331 // 00332 00333 ContextFrame->Ebp = TrapFrame->Ebp; 00334 ContextFrame->Eip = TrapFrame->Eip; 00335 00336 if (((TrapFrame->SegCs & FRAME_EDITED) == 0) && 00337 ((TrapFrame->EFlags & EFLAGS_V86_MASK) == 0)) { 00338 ContextFrame->SegCs = TrapFrame->TempSegCs & SEGMENT_MASK; 00339 } else { 00340 ContextFrame->SegCs = TrapFrame->SegCs & SEGMENT_MASK; 00341 } 00342 ContextFrame->EFlags = TrapFrame->EFlags; 00343 ContextFrame->SegSs = KiSegSsFromTrapFrame(TrapFrame); 00344 ContextFrame->Esp = KiEspFromTrapFrame(TrapFrame); 00345 } 00346 00347 // 00348 // Set segment register contents if specified. 00349 // 00350 00351 if ((ContextFrame->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) { 00352 00353 // 00354 // Set segment registers gs, fs, es, ds. 00355 // 00356 // These values are junk most of the time, but useful 00357 // for debugging under certain conditions. Therefore, 00358 // we report whatever was in the frame. 00359 // 00360 if (TrapFrame->EFlags & EFLAGS_V86_MASK) { 00361 ContextFrame->SegGs = TrapFrame->V86Gs & SEGMENT_MASK; 00362 ContextFrame->SegFs = TrapFrame->V86Fs & SEGMENT_MASK; 00363 ContextFrame->SegEs = TrapFrame->V86Es & SEGMENT_MASK; 00364 ContextFrame->SegDs = TrapFrame->V86Ds & SEGMENT_MASK; 00365 } 00366 else { 00367 if (TrapFrame->SegCs == KGDT_R0_CODE) { 00368 // 00369 // Trap frames created from R0_CODE traps do not save 00370 // the following selectors. Set them in the frame now. 00371 // 00372 00373 TrapFrame->SegGs = 0; 00374 TrapFrame->SegFs = KGDT_R0_PCR; 00375 TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK; 00376 TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK; 00377 } 00378 00379 ContextFrame->SegGs = TrapFrame->SegGs & SEGMENT_MASK; 00380 ContextFrame->SegFs = TrapFrame->SegFs & SEGMENT_MASK; 00381 ContextFrame->SegEs = TrapFrame->SegEs & SEGMENT_MASK; 00382 ContextFrame->SegDs = TrapFrame->SegDs & SEGMENT_MASK; 00383 } 00384 00385 } 00386 00387 // 00388 // Set integer register contents if specified. 00389 // 00390 00391 if ((ContextFrame->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { 00392 00393 // 00394 // Set integer registers edi, esi, ebx, edx, ecx, eax 00395 // 00396 00397 ContextFrame->Edi = TrapFrame->Edi; 00398 ContextFrame->Esi = TrapFrame->Esi; 00399 ContextFrame->Ebx = TrapFrame->Ebx; 00400 ContextFrame->Ecx = TrapFrame->Ecx; 00401 ContextFrame->Edx = TrapFrame->Edx; 00402 ContextFrame->Eax = TrapFrame->Eax; 00403 } 00404 00405 if (((ContextFrame->ContextFlags & CONTEXT_EXTENDED_REGISTERS) == 00406 CONTEXT_EXTENDED_REGISTERS) && 00407 ((TrapFrame->SegCs & MODE_MASK) == UserMode)) { 00408 00409 // 00410 // This is the base TrapFrame, and the NpxFrame is on the base 00411 // of the kernel stack, just above it in memory. 00412 // 00413 00414 NpxFrame = (PFX_SAVE_AREA)(TrapFrame + 1); 00415 00416 if (KeI386NpxPresent) { 00417 KiFlushNPXState (NULL); 00418 RtlCopyMemory( (PVOID)&(ContextFrame->ExtendedRegisters[0]), 00419 (PVOID)&(NpxFrame->U.FxArea), 00420 MAXIMUM_SUPPORTED_EXTENSION 00421 ); 00422 } 00423 } 00424 00425 // 00426 // Fetch floating register contents if requested, and type of target 00427 // is user. (system frames have no fp state, so ignore request) 00428 // 00429 if ( ((ContextFrame->ContextFlags & CONTEXT_FLOATING_POINT) == 00430 CONTEXT_FLOATING_POINT) && 00431 ((TrapFrame->SegCs & MODE_MASK) == UserMode)) { 00432 00433 // 00434 // This is the base TrapFrame, and the NpxFrame is on the base 00435 // of the kernel stack, just above it in memory. 00436 // 00437 00438 NpxFrame = (PFX_SAVE_AREA)(TrapFrame + 1); 00439 00440 if (KeI386NpxPresent) { 00441 00442 // 00443 // Force the coprocessors state to the save area and copy it 00444 // to the context frame. 00445 // 00446 00447 if (KeI386FxsrPresent == TRUE) { 00448 00449 // 00450 // FP state save was done using fxsave. Get the save 00451 // area in fnsave format 00452 // 00453 // Save area must be 16 byte aligned so we cushion it with 00454 // 15 bytes (in the locals declaration above) and round 00455 // down to align. 00456 // 00457 00458 ULONG_PTR Temp; 00459 Temp = (ULONG_PTR)&FloatSaveBuffer.SaveArea; 00460 Temp &= ~0xf; 00461 PSaveArea = (PFLOATING_SAVE_AREA)Temp; 00462 KiFlushNPXState (PSaveArea); 00463 } else { 00464 00465 PSaveArea = (PFLOATING_SAVE_AREA)&(NpxFrame->U.FnArea); 00466 KiFlushNPXState (NULL); 00467 00468 } 00469 00470 ContextFrame->FloatSave.ControlWord = PSaveArea->ControlWord; 00471 ContextFrame->FloatSave.StatusWord = PSaveArea->StatusWord; 00472 ContextFrame->FloatSave.TagWord = PSaveArea->TagWord; 00473 ContextFrame->FloatSave.ErrorOffset = PSaveArea->ErrorOffset; 00474 ContextFrame->FloatSave.ErrorSelector = PSaveArea->ErrorSelector; 00475 ContextFrame->FloatSave.DataOffset = PSaveArea->DataOffset; 00476 ContextFrame->FloatSave.DataSelector = PSaveArea->DataSelector; 00477 ContextFrame->FloatSave.Cr0NpxState = NpxFrame->Cr0NpxState; 00478 00479 for (i = 0; i < SIZE_OF_80387_REGISTERS; i++) { 00480 ContextFrame->FloatSave.RegisterArea[i] = PSaveArea->RegisterArea[i]; 00481 } 00482 00483 } else { 00484 00485 // 00486 // The 80387 is being emulated by the R3 emulator. 00487 // ** The only time the Npx state is ever obtained or set is 00488 // ** for userlevel handling. Current Irql must be 0 or 1. 00489 // Go slurp the emulator's R3 data and generate the 00490 // floating point context 00491 // 00492 00493 StateSaved = KiEm87StateToNpxFrame(&ContextFrame->FloatSave); 00494 if (StateSaved) { 00495 ContextFrame->FloatSave.Cr0NpxState = NpxFrame->Cr0NpxState; 00496 } else { 00497 00498 // 00499 // The floatingpoint state can not be determined. 00500 // Remove the floatingpoint flag from the context frame flags. 00501 // 00502 00503 ContextFrame->ContextFlags &= (~CONTEXT_FLOATING_POINT) | CONTEXT_i386; 00504 } 00505 } 00506 } 00507 00508 // 00509 // Fetch Dr register contents if requested. Values may be trash. 00510 // 00511 00512 if ((ContextFrame->ContextFlags & CONTEXT_DEBUG_REGISTERS) == 00513 CONTEXT_DEBUG_REGISTERS) { 00514 00515 ContextFrame->Dr0 = TrapFrame->Dr0; 00516 ContextFrame->Dr1 = TrapFrame->Dr1; 00517 ContextFrame->Dr2 = TrapFrame->Dr2; 00518 ContextFrame->Dr3 = TrapFrame->Dr3; 00519 ContextFrame->Dr6 = TrapFrame->Dr6; 00520 00521 // 00522 // If it's a user mode frame, and the thread doesn't have DRs set, 00523 // and we just return the trash in the frame, we risk accidentally 00524 // making the thread active with trash values on a set. Therefore, 00525 // Dr7 must be set to 0 if we get a non-active user mode frame. 00526 // 00527 00528 if ((((TrapFrame->SegCs & MODE_MASK) != KernelMode) || 00529 ((TrapFrame->EFlags & EFLAGS_V86_MASK) != 0)) && 00530 (KeGetCurrentThread()->DebugActive == TRUE)) { 00531 00532 ContextFrame->Dr7 = TrapFrame->Dr7; 00533 00534 } else { 00535 00536 ContextFrame->Dr7 = 0L; 00537 00538 } 00539 } 00540 00541 }

VOID KeContextToKframes IN OUT PKTRAP_FRAME  TrapFrame,
IN OUT PKEXCEPTION_FRAME  ExceptionFrame,
IN PCONTEXT  ContextFrame,
IN ULONG  ContextFlags,
IN KPROCESSOR_MODE  PreviousMode
 

Definition at line 544 of file i386/exceptn.c.

References ASSERT, BYTES_PER_FP_REGISTER, BYTES_PER_FX_REGISTER, CONTEXT_CONTROL, CONTEXT_FLOATING_POINT, CONTEXT_INTEGER, FALSE, FN_BITS_PER_TAGWORD, FN_TAG_EMPTY, FN_TAG_MASK, FX_TAG_VALID, KeGetCurrentThread, KeGetPcr, KeI386FxsrPresent, KeI386NpxPresent, KeLowerIrql(), KernelMode, Ki386AdjustEsp0(), KiEspToTrapFrame(), KiNpxFrameToEm87State(), KiSegSsToTrapFrame(), NULL, NUMBER_OF_FP_REGISTERS, TRUE, UserMode, USHORT, and VdmUserCr0MapIn.

00554 : 00555 00556 This routine moves the selected contents of the specified context frame into 00557 the specified trap and exception frames according to the specified context 00558 flags. 00559 00560 Arguments: 00561 00562 TrapFrame - Supplies a pointer to a trap frame that receives the volatile 00563 context from the context record. 00564 00565 ExceptionFrame - Supplies a pointer to an exception frame that receives 00566 the nonvolatile context from the context record. This argument is 00567 ignored since there is no exception frame on NT386. 00568 00569 ContextFrame - Supplies a pointer to a context frame that contains the 00570 context that is to be copied into the trap and exception frames. 00571 00572 ContextFlags - Supplies the set of flags that specify which parts of the 00573 context frame are to be copied into the trap and exception frames. 00574 00575 PreviousMode - Supplies the processor mode for which the trap and exception 00576 frames are being built. 00577 00578 Return Value: 00579 00580 None. 00581 00582 --*/ 00583 00584 { 00585 00586 PFX_SAVE_AREA NpxFrame; 00587 ULONG i; 00588 ULONG j; 00589 ULONG TagWord; 00590 BOOLEAN StateSaved; 00591 BOOLEAN ModeChanged; 00592 #if DBG 00593 PKPCR Pcr; 00594 KIRQL OldIrql; 00595 #endif 00596 00597 UNREFERENCED_PARAMETER( ExceptionFrame ); 00598 00599 // 00600 // Set control information if specified. 00601 // 00602 00603 if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) { 00604 00605 if ((ContextFrame->EFlags & EFLAGS_V86_MASK) != 00606 (TrapFrame->EFlags & EFLAGS_V86_MASK)) { 00607 ModeChanged = TRUE; 00608 } else { 00609 ModeChanged = FALSE; 00610 } 00611 00612 00613 // 00614 // Set registers eflag, ebp, eip, cs, esp and ss. 00615 // Eflags is set first, so that the auxilliary routines 00616 // can check the v86 bit to determine as well as cs, to 00617 // determine if the frame is kernel or user mode. (v86 mode cs 00618 // can have any value) 00619 // 00620 00621 TrapFrame->EFlags = SANITIZE_FLAGS(ContextFrame->EFlags, PreviousMode); 00622 TrapFrame->Ebp = ContextFrame->Ebp; 00623 TrapFrame->Eip = ContextFrame->Eip; 00624 if (TrapFrame->EFlags & EFLAGS_V86_MASK) { 00625 TrapFrame->SegCs = ContextFrame->SegCs; 00626 } else { 00627 TrapFrame->SegCs = SANITIZE_SEG(ContextFrame->SegCs, PreviousMode); 00628 if (PreviousMode != KernelMode && TrapFrame->SegCs < 8) { 00629 00630 // 00631 // If user mode and the selector value is less than 8, we 00632 // know it is an invalid selector. Set it to flat user 00633 // mode selector. Another reason we need to check for this 00634 // is that any cs value less than 8 causes our exit kernel 00635 // macro to treat its exit trap fram as an edited frame. 00636 // 00637 00638 TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK; 00639 } 00640 } 00641 KiSegSsToTrapFrame(TrapFrame, ContextFrame->SegSs); 00642 KiEspToTrapFrame(TrapFrame, ContextFrame->Esp); 00643 if (ModeChanged) { 00644 Ki386AdjustEsp0(TrapFrame); // realign esp0 in the tss 00645 } 00646 } 00647 00648 // 00649 // Set segment register contents if specified. 00650 // 00651 00652 if ((ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) { 00653 00654 // 00655 // Set segment registers gs, fs, es, ds. 00656 // 00657 00658 // 00659 // There's only one legal value for DS and ES, so simply set it. 00660 // This allows KeContextFromKframes to report the real values in 00661 // the frame. (which are junk most of the time, but sometimes useful 00662 // for debugging.) 00663 // Only 2 legal values for FS, let either one be set. 00664 // Force GS to be 0 to deal with entry via SysCall and exit 00665 // via exception. 00666 // 00667 // For V86 mode, the FS, GS, DS, and ES registers must be properly 00668 // set from the supplied context. 00669 // 00670 00671 if (TrapFrame->EFlags & EFLAGS_V86_MASK) { 00672 TrapFrame->V86Fs = ContextFrame->SegFs; 00673 TrapFrame->V86Es = ContextFrame->SegEs; 00674 TrapFrame->V86Ds = ContextFrame->SegDs; 00675 TrapFrame->V86Gs = ContextFrame->SegGs; 00676 } else if (((TrapFrame->SegCs & MODE_MASK) == KernelMode)) { 00677 00678 // 00679 // set up the standard selectors 00680 // 00681 00682 TrapFrame->SegFs = SANITIZE_SEG(ContextFrame->SegFs, PreviousMode); 00683 TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK; 00684 TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK; 00685 TrapFrame->SegGs = 0; 00686 } else { 00687 00688 // 00689 // If user mode, we simply return whatever left in context frame 00690 // and let trap 0d handle it (if later we trap while popping the 00691 // trap frame.) V86 mode also get handled here. 00692 // 00693 00694 TrapFrame->SegFs = ContextFrame->SegFs; 00695 TrapFrame->SegEs = ContextFrame->SegEs; 00696 TrapFrame->SegDs = ContextFrame->SegDs; 00697 if (TrapFrame->SegCs == (KGDT_R3_CODE | RPL_MASK)) { 00698 TrapFrame->SegGs = 0; 00699 } else { 00700 TrapFrame->SegGs = ContextFrame->SegGs; 00701 } 00702 } 00703 } 00704 // 00705 // Set integer registers contents if specified. 00706 // 00707 00708 if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { 00709 00710 // 00711 // Set integer registers edi, esi, ebx, edx, ecx, eax. 00712 // 00713 // Can NOT call RtlMoveMemory here because the regs aren't 00714 // contiguous in pusha frame, and we don't want to export 00715 // bits of junk into context record. 00716 // 00717 00718 TrapFrame->Edi = ContextFrame->Edi; 00719 TrapFrame->Esi = ContextFrame->Esi; 00720 TrapFrame->Ebx = ContextFrame->Ebx; 00721 TrapFrame->Ecx = ContextFrame->Ecx; 00722 TrapFrame->Edx = ContextFrame->Edx; 00723 TrapFrame->Eax = ContextFrame->Eax; 00724 00725 } 00726 00727 // 00728 // Set extended register contents if requested, and type of target 00729 // is user. (system frames have no extended state, so ignore request) 00730 // 00731 00732 if (((ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS) && 00733 ((TrapFrame->SegCs & MODE_MASK) == UserMode)) { 00734 00735 // 00736 // This is the base TrapFrame, and the NpxFrame is on the base 00737 // of the kernel stack, just above it in memory. 00738 // 00739 00740 NpxFrame = (PFX_SAVE_AREA)(TrapFrame + 1); 00741 00742 if (KeI386NpxPresent) { 00743 KiFlushNPXState (NULL); 00744 RtlCopyMemory( (PVOID)&(NpxFrame->U.FxArea), 00745 (PVOID)&(ContextFrame->ExtendedRegisters[0]), 00746 MAXIMUM_SUPPORTED_EXTENSION 00747 ); 00748 // 00749 // Make sure only valid floating state bits are moved to Cr0NpxState. 00750 // 00751 00752 NpxFrame->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS); 00753 00754 // 00755 // Make sure all reserved bits are clear in MXCSR so we don't get a GP 00756 // fault when doing an FRSTOR on this state. 00757 // 00758 NpxFrame->U.FxArea.MXCsr = SANITIZE_MXCSR(NpxFrame->U.FxArea.MXCsr); 00759 00760 // 00761 // Only let VDMs turn on the EM bit. The kernel can't do 00762 // anything for FLAT apps 00763 // 00764 if (KeGetCurrentThread()->ApcState.Process->VdmFlag & 0xf) { 00765 NpxFrame->Cr0NpxState |= ContextFrame->FloatSave.Cr0NpxState & 00766 (CR0_EM | CR0_MP); 00767 } 00768 } 00769 } 00770 00771 // 00772 // Set floating register contents if requested, and type of target 00773 // is user. (system frames have no fp state, so ignore request) 00774 // 00775 00776 if (((ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) && 00777 ((TrapFrame->SegCs & MODE_MASK) == UserMode)) { 00778 00779 // 00780 // This is the base TrapFrame, and the NpxFrame is on the base 00781 // of the kernel stack, just above it in memory. 00782 // 00783 00784 NpxFrame = (PFX_SAVE_AREA)(TrapFrame + 1); 00785 00786 if (KeI386NpxPresent) { 00787 00788 // 00789 // Set coprocessor stack, control and status registers 00790 // 00791 00792 KiFlushNPXState (NULL); 00793 00794 if (KeI386FxsrPresent == TRUE) { 00795 00796 // 00797 // Restore FP state in the fxrstor format 00798 // 00799 00800 NpxFrame->U.FxArea.ControlWord = 00801 (USHORT)ContextFrame->FloatSave.ControlWord; 00802 NpxFrame->U.FxArea.StatusWord = 00803 (USHORT)ContextFrame->FloatSave.StatusWord; 00804 00805 // 00806 // Construct the tag word from fnsave format to fxsave format 00807 // 00808 00809 NpxFrame->U.FxArea.TagWord = 0; // Mark every register invalid 00810 00811 TagWord = ContextFrame->FloatSave.TagWord; 00812 00813 for (i = 0; i < FN_BITS_PER_TAGWORD; i+=2) { 00814 00815 if (((TagWord >> i) & FN_TAG_MASK) != FN_TAG_EMPTY) { 00816 00817 // 00818 // This register is valid 00819 // 00820 00821 NpxFrame->U.FxArea.TagWord |= (FX_TAG_VALID << (i/2)); 00822 } 00823 } 00824 00825 NpxFrame->U.FxArea.ErrorOffset = 00826 ContextFrame->FloatSave.ErrorOffset; 00827 NpxFrame->U.FxArea.ErrorSelector = 00828 (ContextFrame->FloatSave.ErrorSelector & 0xFFFF); 00829 NpxFrame->U.FxArea.ErrorOpcode = 00830 (USHORT)((ContextFrame->FloatSave.ErrorSelector >> 16) & 0xFFFF); 00831 NpxFrame->U.FxArea.DataOffset = 00832 ContextFrame->FloatSave.DataOffset; 00833 NpxFrame->U.FxArea.DataSelector = 00834 ContextFrame->FloatSave.DataSelector; 00835 00836 // 00837 // Fxrstor format has each FP register in 128 bits (16 bytes) 00838 // where as fnsave saves each FP register in 80 bits (10 bytes) 00839 // 00840 RtlZeroMemory ((PVOID)&NpxFrame->U.FxArea.RegisterArea[0], 00841 SIZE_OF_FX_REGISTERS 00842 ); 00843 00844 for (i = 0; i < NUMBER_OF_FP_REGISTERS; i++) { 00845 for (j = 0; j < BYTES_PER_FP_REGISTER; j++) { 00846 NpxFrame->U.FxArea.RegisterArea[i*BYTES_PER_FX_REGISTER+j] = 00847 ContextFrame->FloatSave.RegisterArea[i*BYTES_PER_FP_REGISTER+j]; 00848 } 00849 } 00850 00851 } else { 00852 NpxFrame->U.FnArea.ControlWord = 00853 ContextFrame->FloatSave.ControlWord; 00854 NpxFrame->U.FnArea.StatusWord = 00855 ContextFrame->FloatSave.StatusWord; 00856 NpxFrame->U.FnArea.TagWord = 00857 ContextFrame->FloatSave.TagWord; 00858 NpxFrame->U.FnArea.ErrorOffset = 00859 ContextFrame->FloatSave.ErrorOffset; 00860 NpxFrame->U.FnArea.ErrorSelector = 00861 ContextFrame->FloatSave.ErrorSelector; 00862 NpxFrame->U.FnArea.DataOffset = 00863 ContextFrame->FloatSave.DataOffset; 00864 NpxFrame->U.FnArea.DataSelector = 00865 ContextFrame->FloatSave.DataSelector; 00866 00867 for (i = 0; i < SIZE_OF_80387_REGISTERS; i++) { 00868 NpxFrame->U.FnArea.RegisterArea[i] = 00869 ContextFrame->FloatSave.RegisterArea[i]; 00870 } 00871 00872 } 00873 00874 // 00875 // Make sure only valid floating state bits are moved to Cr0NpxState. 00876 // 00877 00878 NpxFrame->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS); 00879 00880 // 00881 // Only let VDMs turn on the EM bit. The kernel can't do 00882 // anything for FLAT apps 00883 // 00884 if (KeGetCurrentThread()->ApcState.Process->VdmFlag & 0xf) { 00885 NpxFrame->Cr0NpxState |= ContextFrame->FloatSave.Cr0NpxState & 00886 (CR0_EM | CR0_MP); 00887 } 00888 00889 } else { 00890 00891 if (KeGetCurrentThread()->ApcState.Process->VdmFlag & 0xf) { 00892 00893 // 00894 // This is a special hack to allow SetContext for VDMs to 00895 // turn on/off it's CR0_EM bit. 00896 // 00897 00898 NpxFrame->Cr0NpxState &= ~(CR0_MP | CR0_TS | CR0_EM | CR0_PE); 00899 NpxFrame->Cr0NpxState |= 00900 VdmUserCr0MapIn[ContextFrame->FloatSave.Cr0NpxState & (CR0_EM | CR0_MP)]; 00901 00902 } else { 00903 00904 // 00905 // The 80387 is being emulated by the R3 emulator. 00906 // ** The only time the Npx state is ever obtained or set is 00907 // ** for userlevel handling. Current Irql must be 0 or 1. 00908 // And the context being set must be for the current thread. 00909 // Go smash the floatingpoint context into the R3 emulator's 00910 // data area. 00911 // 00912 #if DBG 00913 OldIrql = KeRaiseIrqlToSynchLevel(); 00914 Pcr = KeGetPcr(); 00915 ASSERT (Pcr->Prcb->CurrentThread->Teb == Pcr->NtTib.Self); 00916 KeLowerIrql (OldIrql); 00917 #endif 00918 00919 StateSaved = KiNpxFrameToEm87State(&ContextFrame->FloatSave); 00920 if (StateSaved) { 00921 00922 // 00923 // Make sure only valid floating state bits are moved to 00924 // Cr0NpxState. Since we are emulating, don't allow 00925 // resetting CR0_EM. 00926 // 00927 00928 NpxFrame->Cr0NpxState &= ~(CR0_MP | CR0_TS); 00929 NpxFrame->Cr0NpxState |= 00930 ContextFrame->FloatSave.Cr0NpxState & CR0_MP; 00931 } 00932 } 00933 } 00934 } 00935 00936 // 00937 // Set debug register state if specified. If previous mode is user 00938 // mode (i.e. it's a user frame we're setting) and if effect will be to 00939 // cause at least one of the LE (local enable) bits in Dr7 to be 00940 // set (i.e. at least one of Dr0,1,2,3 are active) then set DebugActive 00941 // in the thread object to true. Otherwise set it to false. 00942 // 00943 00944 if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS) { 00945 00946 TrapFrame->Dr0 = SANITIZE_DRADDR(ContextFrame->Dr0, PreviousMode); 00947 TrapFrame->Dr1 = SANITIZE_DRADDR(ContextFrame->Dr1, PreviousMode); 00948 TrapFrame->Dr2 = SANITIZE_DRADDR(ContextFrame->Dr2, PreviousMode); 00949 TrapFrame->Dr3 = SANITIZE_DRADDR(ContextFrame->Dr3, PreviousMode); 00950 TrapFrame->Dr6 = SANITIZE_DR6(ContextFrame->Dr6, PreviousMode); 00951 TrapFrame->Dr7 = SANITIZE_DR7(ContextFrame->Dr7, PreviousMode); 00952 00953 if (PreviousMode != KernelMode) { 00954 KeGetPcr()->DebugActive = KeGetCurrentThread()->DebugActive = 00955 (BOOLEAN)((ContextFrame->Dr7 & DR7_ACTIVE) != 0); 00956 } 00957 } 00958 00959 // 00960 // If thread is supposed to have IOPL, then force it on in eflags 00961 // 00962 if (KeGetCurrentThread()->Iopl) { 00963 TrapFrame->EFlags |= (EFLAGS_IOPL_MASK & -1); // IOPL = 3 00964 } 00965 00966 return; 00967 }

NTSTATUS KeRaiseUserException IN NTSTATUS  ExceptionCode  ) 
 

Definition at line 1394 of file i386/exceptn.c.

References ASSERT, EXCEPTION_EXECUTE_HANDLER, KeGetCurrentThread, KeRaiseUserExceptionDispatcher, NTSTATUS(), _KTHREAD::Teb, _KTHREAD::TrapFrame, and UserMode.

01400 : 01401 01402 This function causes an exception to be raised in the calling thread's user-mode 01403 context. It does this by editing the trap frame the kernel was entered with to 01404 point to trampoline code that raises the requested exception. 01405 01406 Arguments: 01407 01408 ExceptionCode - Supplies the status value to be used as the exception 01409 code for the exception that is to be raised. 01410 01411 Return Value: 01412 01413 The status value that should be returned by the caller. 01414 01415 --*/ 01416 01417 { 01418 PKTHREAD Thread; 01419 PKTRAP_FRAME TrapFrame; 01420 PTEB Teb; 01421 ULONG PreviousEip; 01422 01423 ASSERT(KeGetPreviousMode() == UserMode); 01424 01425 Thread = KeGetCurrentThread(); 01426 TrapFrame = Thread->TrapFrame; 01427 Teb = (PTEB)Thread->Teb; 01428 01429 // 01430 // In order to create the correct call stack, we return the previous 01431 // EIP as the status code. The usermode trampoline code will push this 01432 // onto the stack for use as the return address. The status code to 01433 // be raised is passed in the TEB. 01434 // 01435 01436 try { 01437 Teb->ExceptionCode = ExceptionCode; 01438 } except(EXCEPTION_EXECUTE_HANDLER) { 01439 return(ExceptionCode); 01440 } 01441 01442 PreviousEip = TrapFrame->Eip; 01443 TrapFrame->Eip = (ULONG)KeRaiseUserExceptionDispatcher; 01444 01445 return((NTSTATUS)PreviousEip); 01446 } }

VOID Ki386AdjustEsp0 IN PKTRAP_FRAME  TrapFrame  ) 
 

Referenced by KeContextToKframes().

ULONG KiCopyInformation IN OUT PEXCEPTION_RECORD  ExceptionRecord1,
IN PEXCEPTION_RECORD  ExceptionRecord2
 

Definition at line 1354 of file i386/exceptn.c.

References EXCEPTION_EXECUTE_HANDLER.

01361 : 01362 01363 This function is called from an exception filter to copy the exception 01364 information from one exception record to another when an exception occurs. 01365 01366 Arguments: 01367 01368 ExceptionRecord1 - Supplies a pointer to the destination exception record. 01369 01370 ExceptionRecord2 - Supplies a pointer to the source exception record. 01371 01372 Return Value: 01373 01374 A value of EXCEPTION_EXECUTE_HANDLER is returned as the function value. 01375 01376 --*/ 01377 01378 { 01379 01380 // 01381 // Copy one exception record to another and return value that causes 01382 // an exception handler to be executed. 01383 // 01384 01385 RtlMoveMemory((PVOID)ExceptionRecord1, 01386 (PVOID)ExceptionRecord2, 01387 sizeof(EXCEPTION_RECORD)); 01388 01389 return EXCEPTION_EXECUTE_HANDLER; 01390 }

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

Definition at line 970 of file i386/exceptn.c.

References ASSERT, CONTEXT_FLOATING_POINT, CONTEXT_FULL, DbgkForwardException(), ExRaiseException(), FALSE, KdIsThisAKdTrap(), KeBugCheckEx(), KeContextFromKframes(), KeContextToKframes(), KeGetCurrentPrcb, KeI386XMMIPresent, KernelMode, KeUserExceptionDispatcher, KiCopyInformation(), KiDebugRoutine, KiEspToTrapFrame(), KiSegSsToTrapFrame(), KMODE_EXCEPTION_NOT_HANDLED, NULL, ProbeForWrite(), PsGetCurrentProcess, RtlDispatchException(), TRUE, and UserMode.

00980 : 00981 00982 This function is called to dispatch an exception to the proper mode and 00983 to cause the exception dispatcher to be called. If the previous mode is 00984 kernel, then the exception dispatcher is called directly to process the 00985 exception. Otherwise the exception record, exception frame, and trap 00986 frame contents are copied to the user mode stack. The contents of the 00987 exception frame and trap are then modified such that when control is 00988 returned, execution will commense in user mode in a routine which will 00989 call the exception dispatcher. 00990 00991 Arguments: 00992 00993 ExceptionRecord - Supplies a pointer to an exception record. 00994 00995 ExceptionFrame - Supplies a pointer to an exception frame. For NT386, 00996 this should be NULL. 00997 00998 TrapFrame - Supplies a pointer to a trap frame. 00999 01000 PreviousMode - Supplies the previous processor mode. 01001 01002 FirstChance - Supplies a boolean value that specifies whether this is 01003 the first (TRUE) or second (FALSE) chance for the exception. 01004 01005 Return Value: 01006 01007 None. 01008 01009 --*/ 01010 01011 { 01012 CONTEXT ContextFrame; 01013 EXCEPTION_RECORD ExceptionRecord1, ExceptionRecord2; 01014 LONG Length; 01015 ULONG UserStack1; 01016 ULONG UserStack2; 01017 01018 // 01019 // Move machine state from trap and exception frames to a context frame, 01020 // and increment the number of exceptions dispatched. 01021 // 01022 01023 KeGetCurrentPrcb()->KeExceptionDispatchCount += 1; 01024 ContextFrame.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; 01025 if (PreviousMode == UserMode) { 01026 // 01027 // For usermode exceptions always try to dispatch the floating 01028 // point state. This allows expection handlers & debuggers to 01029 // examine/edit the npx context if required. Plus it allows 01030 // exception handlers to use fp instructions without detroying 01031 // the npx state at the time of the exception. 01032 // 01033 // Note: If there's no 80387, ContextTo/FromKFrames will use the 01034 // emulator's current state. If the emulator can not give the 01035 // current state, then the context_floating_point bit will be 01036 // turned off by ContextFromKFrames. 01037 // 01038 01039 ContextFrame.ContextFlags |= CONTEXT_FLOATING_POINT; 01040 if (KeI386XMMIPresent) { 01041 ContextFrame.ContextFlags |= CONTEXT_EXTENDED_REGISTERS; 01042 } 01043 } 01044 01045 KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextFrame); 01046 01047 // 01048 // if it is BREAK_POINT exception, we subtract 1 from EIP and report 01049 // the updated EIP to user. This is because Cruiser requires EIP 01050 // points to the int 3 instruction (not the instruction following int 3). 01051 // In this case, BreakPoint exception is fatal. Otherwise we will step 01052 // on the int 3 over and over again, if user does not handle it 01053 // 01054 // if the BREAK_POINT occured in V86 mode, the debugger running in the 01055 // VDM will expect CS:EIP to point after the exception (the way the 01056 // processor left it. this is also true for protected mode dos 01057 // app debuggers. We will need a way to detect this. 01058 // 01059 // 01060 01061 // if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && 01062 // !(ContextFrame.EFlags & EFLAGS_V86_MASK)) { 01063 01064 switch (ExceptionRecord->ExceptionCode) { 01065 case STATUS_BREAKPOINT: 01066 ContextFrame.Eip--; 01067 break; 01068 } 01069 01070 // 01071 // Select the method of handling the exception based on the previous mode. 01072 // 01073 01074 ASSERT (( 01075 !((PreviousMode == KernelMode) && 01076 (ContextFrame.EFlags & EFLAGS_V86_MASK)) 01077 )); 01078 01079 if (PreviousMode == KernelMode) { 01080 01081 // 01082 // Previous mode was kernel. 01083 // 01084 // If the kernel debugger is active, then give the kernel debugger the 01085 // first chance to handle the exception. If the kernel debugger handles 01086 // the exception, then continue execution. Else attempt to dispatch the 01087 // exception to a frame based handler. If a frame based handler handles 01088 // the exception, then continue execution. 01089 // 01090 // If a frame based handler does not handle the exception, 01091 // give the kernel debugger a second chance, if it's present. 01092 // 01093 // If the exception is still unhandled, call KeBugCheck(). 01094 // 01095 01096 if (FirstChance == TRUE) { 01097 01098 if ((KiDebugRoutine != NULL) && 01099 (((KiDebugRoutine) (TrapFrame, 01100 ExceptionFrame, 01101 ExceptionRecord, 01102 &ContextFrame, 01103 PreviousMode, 01104 FALSE)) != FALSE)) { 01105 01106 goto Handled1; 01107 } 01108 01109 // Kernel debugger didn't handle exception. 01110 01111 if (RtlDispatchException(ExceptionRecord, &ContextFrame) == TRUE) { 01112 goto Handled1; 01113 } 01114 } 01115 01116 // 01117 // This is the second chance to handle the exception. 01118 // 01119 01120 if ((KiDebugRoutine != NULL) && 01121 (((KiDebugRoutine) (TrapFrame, 01122 ExceptionFrame, 01123 ExceptionRecord, 01124 &ContextFrame, 01125 PreviousMode, 01126 TRUE)) != FALSE)) { 01127 01128 goto Handled1; 01129 } 01130 01131 KeBugCheckEx( 01132 KMODE_EXCEPTION_NOT_HANDLED, 01133 ExceptionRecord->ExceptionCode, 01134 (ULONG)ExceptionRecord->ExceptionAddress, 01135 ExceptionRecord->ExceptionInformation[0], 01136 ExceptionRecord->ExceptionInformation[1] 01137 ); 01138 01139 } else { 01140 01141 // 01142 // Previous mode was user. 01143 // 01144 // If this is the first chance and the current process has a debugger 01145 // port, then send a message to the debugger port and wait for a reply. 01146 // If the debugger handles the exception, then continue execution. Else 01147 // transfer the exception information to the user stack, transition to 01148 // user mode, and attempt to dispatch the exception to a frame based 01149 // handler. If a frame based handler handles the exception, then continue 01150 // execution with the continue system service. Else execute the 01151 // NtRaiseException system service with FirstChance == FALSE, which 01152 // will call this routine a second time to process the exception. 01153 // 01154 // If this is the second chance and the current process has a debugger 01155 // port, then send a message to the debugger port and wait for a reply. 01156 // If the debugger handles the exception, then continue execution. Else 01157 // if the current process has a subsystem port, then send a message to 01158 // the subsystem port and wait for a reply. If the subsystem handles the 01159 // exception, then continue execution. Else terminate the thread. 01160 // 01161 01162 01163 if (FirstChance == TRUE) { 01164 01165 // 01166 // This is the first chance to handle the exception. 01167 // 01168 01169 if ( PsGetCurrentProcess()->DebugPort ) { 01170 if ( (KiDebugRoutine != NULL) && 01171 KdIsThisAKdTrap(ExceptionRecord, &ContextFrame, UserMode) ) { 01172 01173 if ((((KiDebugRoutine) (TrapFrame, 01174 ExceptionFrame, 01175 ExceptionRecord, 01176 &ContextFrame, 01177 PreviousMode, 01178 FALSE)) != FALSE)) { 01179 01180 goto Handled1; 01181 } 01182 } 01183 } else { 01184 if ((KiDebugRoutine != NULL) && 01185 (((KiDebugRoutine) (TrapFrame, 01186 ExceptionFrame, 01187 ExceptionRecord, 01188 &ContextFrame, 01189 PreviousMode, 01190 FALSE)) != FALSE)) { 01191 01192 goto Handled1; 01193 } 01194 } 01195 01196 if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) { 01197 goto Handled2; 01198 } 01199 01200 // 01201 // Transfer exception information to the user stack, transition 01202 // to user mode, and attempt to dispatch the exception to a frame 01203 // based handler. 01204 01205 repeat: 01206 try { 01207 01208 // 01209 // If the SS segment is not 32 bit flat, there is no point 01210 // to dispatch exception to frame based exception handler. 01211 // 01212 01213 if (TrapFrame->HardwareSegSs != (KGDT_R3_DATA | RPL_MASK) || 01214 TrapFrame->EFlags & EFLAGS_V86_MASK ) { 01215 ExceptionRecord2.ExceptionCode = STATUS_ACCESS_VIOLATION; 01216 ExceptionRecord2.ExceptionFlags = 0; 01217 ExceptionRecord2.NumberParameters = 0; 01218 ExRaiseException(&ExceptionRecord2); 01219 } 01220 01221 // 01222 // Compute length of context record and new aligned user stack 01223 // pointer. 01224 // 01225 01226 Length = (sizeof(CONTEXT) + CONTEXT_ROUND) & ~CONTEXT_ROUND; 01227 UserStack1 = (ContextFrame.Esp & ~CONTEXT_ROUND) - Length; 01228 01229 // 01230 // Probe user stack area for writeability and then transfer the 01231 // context record to the user stack. 01232 // 01233 01234 ProbeForWrite((PCHAR)UserStack1, Length, CONTEXT_ALIGN); 01235 RtlMoveMemory((PULONG)UserStack1, &ContextFrame, sizeof(CONTEXT)); 01236 01237 // 01238 // Compute length of exception record and new aligned stack 01239 // address. 01240 // 01241 01242 Length = (sizeof(EXCEPTION_RECORD) - (EXCEPTION_MAXIMUM_PARAMETERS - 01243 ExceptionRecord->NumberParameters) * sizeof(ULONG) +3) & 01244 (~3); 01245 UserStack2 = UserStack1 - Length; 01246 01247 // 01248 // Probe user stack area for writeability and then transfer the 01249 // context record to the user stack area. 01250 // N.B. The probing length is Length+8 because there are two 01251 // arguments need to be pushed to user stack later. 01252 // 01253 01254 ProbeForWrite((PCHAR)(UserStack2 - 8), Length + 8, sizeof(ULONG)); 01255 RtlMoveMemory((PULONG)UserStack2, ExceptionRecord, Length); 01256 01257 // 01258 // Push address of exception record, context record to the 01259 // user stack. They are the two parameters required by 01260 // _KiUserExceptionDispatch. 01261 // 01262 01263 *(PULONG)(UserStack2 - sizeof(ULONG)) = UserStack1; 01264 *(PULONG)(UserStack2 - 2*sizeof(ULONG)) = UserStack2; 01265 01266 // 01267 // Set new stack pointer to the trap frame. 01268 // 01269 01270 KiSegSsToTrapFrame(TrapFrame, KGDT_R3_DATA); 01271 KiEspToTrapFrame(TrapFrame, (UserStack2 - sizeof(ULONG)*2)); 01272 01273 // 01274 // Force correct R3 selectors into TrapFrame. 01275 // 01276 01277 TrapFrame->SegCs = SANITIZE_SEG(KGDT_R3_CODE, PreviousMode); 01278 TrapFrame->SegDs = SANITIZE_SEG(KGDT_R3_DATA, PreviousMode); 01279 TrapFrame->SegEs = SANITIZE_SEG(KGDT_R3_DATA, PreviousMode); 01280 TrapFrame->SegFs = SANITIZE_SEG(KGDT_R3_TEB, PreviousMode); 01281 TrapFrame->SegGs = 0; 01282 01283 // 01284 // Set the address of the exception routine that will call the 01285 // exception dispatcher and then return to the trap handler. 01286 // The trap handler will restore the exception and trap frame 01287 // context and continue execution in the routine that will 01288 // call the exception dispatcher. 01289 // 01290 01291 TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher; 01292 return; 01293 01294 } except (KiCopyInformation(&ExceptionRecord1, 01295 (GetExceptionInformation())->ExceptionRecord)) { 01296 01297 // 01298 // If the exception is a stack overflow, then attempt 01299 // to raise the stack overflow exception. Otherwise, 01300 // the user's stack is not accessible, or is misaligned, 01301 // and second chance processing is performed. 01302 // 01303 01304 if (ExceptionRecord1.ExceptionCode == STATUS_STACK_OVERFLOW) { 01305 ExceptionRecord1.ExceptionAddress = ExceptionRecord->ExceptionAddress; 01306 RtlMoveMemory((PVOID)ExceptionRecord, 01307 &ExceptionRecord1, sizeof(EXCEPTION_RECORD)); 01308 goto repeat; 01309 } 01310 } 01311 } 01312 01313 // 01314 // This is the second chance to handle the exception. 01315 // 01316 01317 if (DbgkForwardException(ExceptionRecord, TRUE, TRUE)) { 01318 goto Handled2; 01319 } else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE)) { 01320 goto Handled2; 01321 } else { 01322 ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode); 01323 KeBugCheckEx( 01324 KMODE_EXCEPTION_NOT_HANDLED, 01325 ExceptionRecord->ExceptionCode, 01326 (ULONG)ExceptionRecord->ExceptionAddress, 01327 ExceptionRecord->ExceptionInformation[0], 01328 ExceptionRecord->ExceptionInformation[1] 01329 ); 01330 } 01331 } 01332 01333 // 01334 // Move machine state from context frame to trap and exception frames and 01335 // then return to continue execution with the restored state. 01336 // 01337 01338 Handled1: 01339 KeContextToKframes(TrapFrame, ExceptionFrame, &ContextFrame, 01340 ContextFrame.ContextFlags, PreviousMode); 01341 01342 // 01343 // Exception was handled by the debugger or the associated subsystem 01344 // and state was modified, if necessary, using the get state and set 01345 // state capabilities. Therefore the context frame does not need to 01346 // be transfered to the trap and exception frames. 01347 // 01348 01349 Handled2: 01350 return; 01351 }

BOOLEAN KiEm87StateToNpxFrame OUT PFLOATING_SAVE_AREA  NpxFrmae  ) 
 

Referenced by KeContextFromKframes().

ULONG KiEspFromTrapFrame IN PKTRAP_FRAME  TrapFrame  ) 
 

Definition at line 65 of file i386/exceptn.c.

References KernelMode.

Referenced by KeContextFromKframes(), and KiEspToTrapFrame().

00071 : 00072 00073 This routine fetches the correct esp from a trapframe, accounting 00074 for whether the frame is a user or kernel mode frame, and whether 00075 it has been edited. 00076 00077 Arguments: 00078 00079 TrapFrame - Supplies a pointer to a trap frame from which volatile context 00080 should be copied into the context record. 00081 00082 Return Value: 00083 00084 Value of Esp. 00085 00086 --*/ 00087 00088 { 00089 if (((TrapFrame->SegCs & MODE_MASK) != KernelMode) || 00090 (TrapFrame->EFlags & EFLAGS_V86_MASK)) { 00091 00092 // User mode frame, real value of Esp is always in HardwareEsp. 00093 00094 return TrapFrame->HardwareEsp; 00095 00096 } else { 00097 00098 if ((TrapFrame->SegCs & FRAME_EDITED) == 0) { 00099 00100 // Kernel mode frame which has had esp edited, 00101 // value of Esp is in TempEsp. 00102 00103 return TrapFrame->TempEsp; 00104 00105 } else { 00106 00107 // Kernel mode frame has has not had esp edited, compute esp. 00108 00109 return (ULONG)&TrapFrame->HardwareEsp; 00110 } 00111 } 00112 }

VOID KiEspToTrapFrame IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Esp
 

Definition at line 115 of file i386/exceptn.c.

References KeBugCheck(), KernelMode, and KiEspFromTrapFrame().

Referenced by KeContextToKframes(), and KiDispatchException().

00122 : 00123 00124 This routine sets the specified value Esp into the trap frame, 00125 accounting for whether the frame is a user or kernel mode frame, 00126 and whether it has been edited before. 00127 00128 Arguments: 00129 00130 TrapFrame - Supplies a pointer to a trap frame from which volatile context 00131 should be copied into the context record. 00132 00133 Esp - New value for Esp. 00134 00135 Return Value: 00136 00137 None. 00138 00139 --*/ 00140 { 00141 ULONG OldEsp; 00142 00143 OldEsp = KiEspFromTrapFrame(TrapFrame); 00144 00145 if (((TrapFrame->SegCs & MODE_MASK) != KernelMode) || 00146 (TrapFrame->EFlags & EFLAGS_V86_MASK)) { 00147 00148 // 00149 // User mode trap frame 00150 // 00151 00152 TrapFrame->HardwareEsp = Esp; 00153 00154 } else { 00155 00156 // 00157 // Kernel mode esp can't be lowered or iret emulation will fail 00158 // 00159 00160 if (Esp < OldEsp) 00161 KeBugCheck(SET_OF_INVALID_CONTEXT); 00162 00163 // 00164 // Edit frame, setting edit marker as needed. 00165 // 00166 00167 if ((TrapFrame->SegCs & FRAME_EDITED) == 0) { 00168 00169 // Kernel frame that has already been edited, 00170 // store value in TempEsp. 00171 00172 TrapFrame->TempEsp = Esp; 00173 00174 } else { 00175 00176 // Kernel frame for which Esp is being edited first time. 00177 // Save real SegCs, set marked in SegCs, save Esp value. 00178 00179 if (OldEsp != Esp) { 00180 TrapFrame->TempSegCs = TrapFrame->SegCs; 00181 TrapFrame->SegCs = TrapFrame->SegCs & ~FRAME_EDITED; 00182 TrapFrame->TempEsp = Esp; 00183 } 00184 } 00185 } 00186 }

BOOLEAN KiNpxFrameToEm87State IN PFLOATING_SAVE_AREA  NpxFrmae  ) 
 

Referenced by KeContextToKframes().

ULONG KiSegSsFromTrapFrame IN PKTRAP_FRAME  TrapFrame  ) 
 

Definition at line 189 of file i386/exceptn.c.

References KernelMode.

Referenced by KeContextFromKframes().

00195 : 00196 00197 This routine fetches the correct ss from a trapframe, accounting 00198 for whether the frame is a user or kernel mode frame. 00199 00200 Arguments: 00201 00202 TrapFrame - Supplies a pointer to a trap frame from which volatile context 00203 should be copied into the context record. 00204 00205 Return Value: 00206 00207 Value of SegSs. 00208 00209 --*/ 00210 00211 { 00212 if (TrapFrame->EFlags & EFLAGS_V86_MASK){ 00213 return TrapFrame->HardwareSegSs; 00214 } else if ((TrapFrame->SegCs & MODE_MASK) != KernelMode) { 00215 00216 // 00217 // It's user mode. The HardwareSegSs contains R3 data selector. 00218 // 00219 00220 return TrapFrame->HardwareSegSs | RPL_MASK; 00221 } else { 00222 return KGDT_R0_DATA; 00223 } 00224 }

VOID KiSegSsToTrapFrame IN PKTRAP_FRAME  TrapFrame,
IN ULONG  SegSs
 

Definition at line 227 of file i386/exceptn.c.

References UserMode.

Referenced by KeContextToKframes(), and KiDispatchException().

00234 : 00235 00236 It turns out that in a flat system there are only two legal values 00237 for SS. Therefore, this procedure forces the appropriate one 00238 of those values to be used. The legal SS value is a function of 00239 which CS value is already set. 00240 00241 Arguments: 00242 00243 TrapFrame - Supplies a pointer to a trap frame from which volatile context 00244 should be copied into the context record. 00245 00246 SegSs - value of SS caller would like to set. 00247 00248 Return Value: 00249 00250 Nothing. 00251 00252 --*/ 00253 00254 { 00255 SegSs &= SEGMENT_MASK; // Throw away the high order trash bits 00256 00257 if (TrapFrame->EFlags & EFLAGS_V86_MASK) { 00258 TrapFrame->HardwareSegSs = SegSs; 00259 } else if ((TrapFrame->SegCs & MODE_MASK) == UserMode) { 00260 00261 // 00262 // If user mode, we simply put SegSs to trapfram. If the SegSs 00263 // is a bogus value. The trap0d handler will be able to detect 00264 // this and handle it appropriately. 00265 // 00266 00267 TrapFrame->HardwareSegSs = SegSs | RPL_MASK; 00268 } 00269 00270 // 00271 // else { 00272 // The frame is a kernel mode frame, which does not have 00273 // a place to store SS. Therefore, do nothing. 00274 // 00275 }


Variable Documentation

BOOLEAN KeI386FxsrPresent
 

Definition at line 45 of file i386/exceptn.c.

BOOLEAN KeI386XMMIPresent
 

Definition at line 46 of file i386/exceptn.c.

Referenced by KeRestoreFloatingPointState(), KeSaveFloatingPointState(), KiDispatchException(), KiInitializeContextThread(), and KiInitializeKernel().

UCHAR VdmUserCr0MapIn[]
 

Definition at line 44 of file i386/exceptn.c.

Referenced by KeContextToKframes().


Generated on Sat May 15 19:43:34 2004 for test by doxygen 1.3.7