DECLSPEC_NORETURN VOID FASTCALL KiTrap03Handler(IN PKTRAP_FRAME TrapFrame) { /* Save trap frame */ KiEnterTrap(TrapFrame); /* Continue with the common handler */ KiDebugHandler(TrapFrame, BREAKPOINT_BREAK, 0, 0); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap0CHandler(IN PKTRAP_FRAME TrapFrame) { /* Save trap frame */ KiEnterTrap(TrapFrame); /* FIXME: Kill the system */ UNIMPLEMENTED; KiSystemFatalException(EXCEPTION_STACK_FAULT, TrapFrame); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap09Handler(IN PKTRAP_FRAME TrapFrame) { /* Save trap frame */ KiEnterTrap(TrapFrame); /* Enable interrupts and kill the system */ _enable(); KiSystemFatalException(EXCEPTION_NPX_OVERRUN, TrapFrame); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap0AHandler(IN PKTRAP_FRAME TrapFrame) { /* Save trap frame */ KiEnterTrap(TrapFrame); /* Check for VDM trap */ ASSERT((KiVdmTrap(TrapFrame)) == FALSE); /* Kill the system */ KiSystemFatalException(EXCEPTION_INVALID_TSS, TrapFrame); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap04Handler(IN PKTRAP_FRAME TrapFrame) { /* Save trap frame */ KiEnterTrap(TrapFrame); /* Check for VDM trap */ ASSERT((KiVdmTrap(TrapFrame)) == FALSE); /* Enable interrupts */ _enable(); /* Dispatch the exception */ KiDispatchException0Args(STATUS_INTEGER_OVERFLOW, TrapFrame->Eip - 1, TrapFrame); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap01Handler(IN PKTRAP_FRAME TrapFrame) { /* Save trap frame */ KiEnterTrap(TrapFrame); /* Check for VDM trap */ ASSERT((KiVdmTrap(TrapFrame)) == FALSE); /* Enable interrupts if the trap came from user-mode */ if (KiUserTrap(TrapFrame)) _enable(); /* Mask out trap flag and dispatch the exception */ TrapFrame->EFlags &= ~EFLAGS_TF; KiDispatchException0Args(STATUS_SINGLE_STEP, TrapFrame->Eip, TrapFrame); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap05Handler(IN PKTRAP_FRAME TrapFrame) { /* Save trap frame */ KiEnterTrap(TrapFrame); /* Check for VDM trap */ ASSERT((KiVdmTrap(TrapFrame)) == FALSE); /* Check for kernel-mode fault */ if (!KiUserTrap(TrapFrame)) KiSystemFatalException(EXCEPTION_BOUND_CHECK, TrapFrame); /* Enable interrupts */ _enable(); /* Dispatch the exception */ KiDispatchException0Args(STATUS_ARRAY_BOUNDS_EXCEEDED, TrapFrame->Eip, TrapFrame); }
DECLSPEC_NORETURN VOID FASTCALL HalpTrap0DHandler(IN PKTRAP_FRAME TrapFrame) { /* Enter the trap */ KiEnterTrap(TrapFrame); /* Check if this is a V86 trap */ if (TrapFrame->EFlags & EFLAGS_V86_MASK) { /* Dispatch the opcode and exit the trap */ HalpDispatchV86Opcode(TrapFrame); KiEoiHelper(TrapFrame); } /* Strange, it isn't! This can happen during NMI */ DPRINT1("HAL: Trap0D while not in V86 mode\n"); KiDumpTrapFrame(TrapFrame); ERROR_FATAL(); while (TRUE); /* 'noreturn' function */ }
DECLSPEC_NORETURN VOID FASTCALL KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame) { ULONG i, j, Iopl; BOOLEAN Privileged = FALSE; PUCHAR Instructions; UCHAR Instruction = 0; KIRQL OldIrql; /* Check for V86 GPF */ if (__builtin_expect(KiV86Trap(TrapFrame), 1)) { /* Enter V86 trap */ KiEnterV86Trap(TrapFrame); /* Must be a VDM process */ if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0)) { /* Enable interrupts */ _enable(); /* Setup illegal instruction fault */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); } /* Go to APC level */ OldIrql = KfRaiseIrql(APC_LEVEL); _enable(); /* Handle the V86 opcode */ if (__builtin_expect(Ki386HandleOpcodeV86(TrapFrame) == 0xFF, 0)) { /* Should only happen in VDM mode */ UNIMPLEMENTED; while (TRUE); } /* Bring IRQL back */ KfLowerIrql(OldIrql); _disable(); /* Do a quick V86 exit if possible */ KiExitV86Trap(TrapFrame); } /* Save trap frame */ KiEnterTrap(TrapFrame); /* Check for user-mode GPF */ if (KiUserTrap(TrapFrame)) { /* Should not be VDM */ ASSERT(KiVdmTrap(TrapFrame) == FALSE); /* Enable interrupts and check error code */ _enable(); if (!TrapFrame->ErrCode) { /* FIXME: Use SEH */ Instructions = (PUCHAR)TrapFrame->Eip; /* Scan next 15 bytes */ for (i = 0; i < 15; i++) { /* Skip prefix instructions */ for (j = 0; j < sizeof(KiTrapPrefixTable); j++) { /* Is this a prefix instruction? */ if (Instructions[i] == KiTrapPrefixTable[j]) { /* Stop looking */ break; } } /* Is this NOT any prefix instruction? */ if (j == sizeof(KiTrapPrefixTable)) { /* We can go ahead and handle the fault now */ Instruction = Instructions[i]; break; } } /* If all we found was prefixes, then this instruction is too long */ if (i == 15) { /* Setup illegal instruction fault */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); } /* Check for privileged instructions */ if (Instruction == 0xF4) // HLT { /* HLT is privileged */ Privileged = TRUE; } else if (Instruction == 0x0F) { /* Test if it's any of the privileged two-byte opcodes */ if (((Instructions[i + 1] == 0x00) && // LLDT or LTR (((Instructions[i + 2] & 0x38) == 0x10) || // LLDT (Instructions[i + 2] == 0x18))) || // LTR ((Instructions[i + 1] == 0x01) && // LGDT or LIDT or LMSW (((Instructions[i + 2] & 0x38) == 0x10) || // LGDT (Instructions[i + 2] == 0x18) || // LIDT (Instructions[i + 2] == 0x30))) || // LMSW (Instructions[i + 1] == 0x08) || // INVD (Instructions[i + 1] == 0x09) || // WBINVD (Instructions[i + 1] == 0x35) || // SYSEXIT (Instructions[i + 1] == 0x26) || // MOV DR, XXX (Instructions[i + 1] == 0x06) || // CLTS (Instructions[i + 1] == 0x20) || // MOV CR, XXX (Instructions[i + 1] == 0x24) || // MOV YYY, DR (Instructions[i + 1] == 0x30) || // WRMSR (Instructions[i + 1] == 0x33)) // RDPMC // INVLPG, INVLPGA, SYSRET { /* These are all privileged */ Privileged = TRUE; } } else { /* Get the IOPL and compare with the RPL mask */ Iopl = (TrapFrame->EFlags & EFLAGS_IOPL) >> 12; if ((TrapFrame->SegCs & RPL_MASK) > Iopl) { /* I/O privilege error -- check for known instructions */ if ((Instruction == 0xFA) || (Instruction == 0xFB)) // CLI or STI { /* These are privileged */ Privileged = TRUE; } else { /* Last hope: an IN/OUT instruction */ for (j = 0; j < sizeof(KiTrapIoTable); j++) { /* Is this an I/O instruction? */ if (Instruction == KiTrapIoTable[j]) { /* Then it's privileged */ Privileged = TRUE; break; } } } } } /* So now... was the instruction privileged or not? */ if (Privileged) { /* Whew! We have a privileged instruction, so dispatch the fault */ KiDispatchException0Args(STATUS_PRIVILEGED_INSTRUCTION, TrapFrame->Eip, TrapFrame); } } /* If we got here, send an access violation */ KiDispatchException2Args(STATUS_ACCESS_VIOLATION, TrapFrame->Eip, 0, 0xFFFFFFFF, TrapFrame); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap07Handler(IN PKTRAP_FRAME TrapFrame) { PKTHREAD Thread, NpxThread; PFX_SAVE_AREA SaveArea, NpxSaveArea; ULONG Cr0; /* Save trap frame */ KiEnterTrap(TrapFrame); /* Try to handle NPX delay load */ while (TRUE) { /* Get the current thread */ Thread = KeGetCurrentThread(); /* Get the NPX frame */ SaveArea = KiGetThreadNpxArea(Thread); /* Check if emulation is enabled */ if (SaveArea->Cr0NpxState & CR0_EM) { /* Not implemented */ UNIMPLEMENTED; while (TRUE); } /* Save CR0 and check NPX state */ Cr0 = __readcr0(); if (Thread->NpxState != NPX_STATE_LOADED) { /* Update CR0 */ Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS); __writecr0(Cr0); /* Get the NPX thread */ NpxThread = KeGetCurrentPrcb()->NpxThread; if (NpxThread) { /* Get the NPX frame */ NpxSaveArea = KiGetThreadNpxArea(NpxThread); /* Save FPU state */ DPRINT("FIXME: Save FPU state: %p\n", NpxSaveArea); //Ke386SaveFpuState(NpxSaveArea); /* Update NPX state */ Thread->NpxState = NPX_STATE_NOT_LOADED; } /* Load FPU state */ //Ke386LoadFpuState(SaveArea); /* Update NPX state */ Thread->NpxState = NPX_STATE_LOADED; KeGetCurrentPrcb()->NpxThread = Thread; /* Enable interrupts */ _enable(); /* Check if CR0 needs to be reloaded due to context switch */ if (!SaveArea->Cr0NpxState) KiEoiHelper(TrapFrame); /* Otherwise, we need to reload CR0, disable interrupts */ _disable(); /* Reload CR0 */ Cr0 = __readcr0(); Cr0 |= SaveArea->Cr0NpxState; __writecr0(Cr0); /* Now restore interrupts and check for TS */ _enable(); if (Cr0 & CR0_TS) KiEoiHelper(TrapFrame); /* We're still here -- clear TS and try again */ __writecr0(__readcr0() &~ CR0_TS); _disable(); } else { /* This is an actual fault, not a lack of FPU state */ break; } } /* TS should not be set */ if (Cr0 & CR0_TS) { /* * If it's incorrectly set, then maybe the state is actually still valid * but we could've lock track of that due to a BIOS call. * Make sure MP is still set, which should verify the theory. */ if (Cr0 & CR0_MP) { /* Indeed, the state is actually still valid, so clear TS */ __writecr0(__readcr0() &~ CR0_TS); KiEoiHelper(TrapFrame); } /* Otherwise, something strange is going on */ KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 2, Cr0, 0, 0, TrapFrame); } /* It's not a delayed load, so process this trap as an NPX fault */ KiNpxHandler(TrapFrame, Thread, SaveArea); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap06Handler(IN PKTRAP_FRAME TrapFrame) { PUCHAR Instruction; ULONG i; KIRQL OldIrql; /* Check for V86 GPF */ if (__builtin_expect(KiV86Trap(TrapFrame), 1)) { /* Enter V86 trap */ KiEnterV86Trap(TrapFrame); /* Must be a VDM process */ if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0)) { /* Enable interrupts */ _enable(); /* Setup illegal instruction fault */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); } /* Go to APC level */ OldIrql = KfRaiseIrql(APC_LEVEL); _enable(); /* Check for BOP */ if (!VdmDispatchBop(TrapFrame)) { /* Should only happen in VDM mode */ UNIMPLEMENTED; while (TRUE); } /* Bring IRQL back */ KfLowerIrql(OldIrql); _disable(); /* Do a quick V86 exit if possible */ KiExitV86Trap(TrapFrame); } /* Save trap frame */ KiEnterTrap(TrapFrame); /* Enable interrupts */ Instruction = (PUCHAR)TrapFrame->Eip; _enable(); /* Check for user trap */ if (KiUserTrap(TrapFrame)) { /* FIXME: Use SEH */ /* Scan next 4 opcodes */ for (i = 0; i < 4; i++) { /* Check for LOCK instruction */ if (Instruction[i] == 0xF0) { /* Send invalid lock sequence exception */ KiDispatchException0Args(STATUS_INVALID_LOCK_SEQUENCE, TrapFrame->Eip, TrapFrame); } } /* FIXME: SEH ends here */ } /* Kernel-mode or user-mode fault (but not LOCK) */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); }