mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
275 lines
5.8 KiB
275 lines
5.8 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
trapc.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the specific exception handlers for EM
|
|
exceptions. Called by the BdGenericExceptionHandler.
|
|
|
|
Author:
|
|
|
|
Bernard Lint 4-Apr-96
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "bd.h"
|
|
|
|
|
|
typedef struct _BREAK_INST {
|
|
union {
|
|
struct {
|
|
ULONGLONG qp: 6;
|
|
ULONGLONG imm20: 20;
|
|
ULONGLONG x: 1;
|
|
ULONGLONG x6: 6;
|
|
ULONGLONG x3: 3;
|
|
ULONGLONG i: 1;
|
|
ULONGLONG Op: 4;
|
|
ULONGLONG Rsv: 23;
|
|
} i_field;
|
|
ULONGLONG Ulong64;
|
|
} u;
|
|
} BREAK_INST;
|
|
|
|
ULONG
|
|
BdExtractImmediate (
|
|
IN ULONGLONG Iip,
|
|
IN ULONG SlotNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Extract immediate operand from break instruction.
|
|
|
|
Arguments:
|
|
|
|
Iip - Bundle address of instruction
|
|
|
|
SlotNumber - Slot of break instruction within bundle
|
|
|
|
Return Value:
|
|
|
|
Value of immediate operand.
|
|
|
|
--*/
|
|
|
|
{
|
|
PULONGLONG BundleAddress;
|
|
ULONGLONG BundleLow;
|
|
ULONGLONG BundleHigh;
|
|
BREAK_INST BreakInst;
|
|
ULONG Imm21;
|
|
|
|
BundleAddress = (PULONGLONG)Iip;
|
|
|
|
BundleLow = *BundleAddress;
|
|
BundleHigh = *(BundleAddress+1);
|
|
|
|
//
|
|
// Align instruction
|
|
//
|
|
|
|
switch (SlotNumber) {
|
|
case 0:
|
|
BreakInst.u.Ulong64 = BundleLow >> 5;
|
|
break;
|
|
|
|
case 1:
|
|
BreakInst.u.Ulong64 = (BundleLow >> 46) | (BundleHigh << 18);
|
|
break;
|
|
|
|
case 2:
|
|
BreakInst.u.Ulong64 = (BundleHigh >> 23);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Extract immediate value
|
|
//
|
|
|
|
Imm21 = (ULONG)(BreakInst.u.i_field.i<<20) | (ULONG)(BreakInst.u.i_field.imm20);
|
|
|
|
return Imm21;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
BdOtherBreakException (
|
|
IN PKTRAP_FRAME TrapFrame
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handler for break exception other than the ones for fast and
|
|
normal system calls. This includes debug break points.
|
|
|
|
Arguments:
|
|
|
|
TrapFrame - Pointer to the trap frame.
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
PEXCEPTION_RECORD ExceptionRecord;
|
|
ULONG BreakImmediate;
|
|
ISR Isr;
|
|
|
|
BreakImmediate = (ULONG)(TrapFrame->StIIM);
|
|
|
|
//
|
|
// Handle break.b case
|
|
//
|
|
if (BreakImmediate == 0) {
|
|
Isr.ull = TrapFrame->StISR;
|
|
BreakImmediate = BdExtractImmediate(TrapFrame->StIIP,
|
|
(ULONG)Isr.sb.isr_ei);
|
|
TrapFrame->StIIM = BreakImmediate;
|
|
}
|
|
|
|
//
|
|
// Initialize exception record
|
|
//
|
|
|
|
ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
|
|
ExceptionRecord->ExceptionAddress =
|
|
(PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
|
|
((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
|
|
|
|
ExceptionRecord->ExceptionFlags = 0;
|
|
ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)NULL;
|
|
|
|
ExceptionRecord->NumberParameters = 5;
|
|
ExceptionRecord->ExceptionInformation[0] = 0;
|
|
ExceptionRecord->ExceptionInformation[1] = 0;
|
|
ExceptionRecord->ExceptionInformation[2] = 0;
|
|
ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
|
|
ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
|
|
|
|
switch (BreakImmediate) {
|
|
|
|
case KERNEL_BREAKPOINT:
|
|
case USER_BREAKPOINT:
|
|
case BREAKPOINT_PRINT:
|
|
case BREAKPOINT_PROMPT:
|
|
case BREAKPOINT_STOP:
|
|
case BREAKPOINT_LOAD_SYMBOLS:
|
|
case BREAKPOINT_UNLOAD_SYMBOLS:
|
|
case BREAKPOINT_BREAKIN:
|
|
ExceptionRecord->ExceptionCode = STATUS_BREAKPOINT;
|
|
ExceptionRecord->ExceptionInformation[0] = BreakImmediate;
|
|
break;
|
|
|
|
case INTEGER_DIVIDE_BY_ZERO_BREAK:
|
|
ExceptionRecord->ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
|
|
break;
|
|
|
|
case INTEGER_OVERFLOW_BREAK:
|
|
ExceptionRecord->ExceptionCode = STATUS_INTEGER_OVERFLOW;
|
|
break;
|
|
|
|
case MISALIGNED_DATA_BREAK:
|
|
ExceptionRecord->ExceptionCode = STATUS_DATATYPE_MISALIGNMENT;
|
|
break;
|
|
|
|
case RANGE_CHECK_BREAK:
|
|
case NULL_POINTER_DEFERENCE_BREAK:
|
|
case DECIMAL_OVERFLOW_BREAK:
|
|
case DECIMAL_DIVIDE_BY_ZERO_BREAK:
|
|
case PACKED_DECIMAL_ERROR_BREAK:
|
|
case INVALID_ASCII_DIGIT_BREAK:
|
|
case INVALID_DECIMAL_DIGIT_BREAK:
|
|
case PARAGRAPH_STACK_OVERFLOW_BREAK:
|
|
|
|
default:
|
|
#if 0
|
|
#if DBG
|
|
InbvDisplayString ("BdOtherBreakException: Unknown break code.\n");
|
|
#endif // DBG
|
|
#endif
|
|
ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
BdSingleStep (
|
|
IN PKTRAP_FRAME TrapFrame
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handler for single step trap. An instruction was successfully
|
|
executed and the PSR.ss bit is 1.
|
|
|
|
Arguments:
|
|
|
|
TrapFrame - Pointer to the trap frame.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
ISR.ei bits indicate which instruction caused the exception.
|
|
|
|
ISR.code{3:0} = 1000
|
|
|
|
--*/
|
|
|
|
{
|
|
PEXCEPTION_RECORD ExceptionRecord;
|
|
ULONG IpsrRi;
|
|
|
|
//
|
|
// Initialize the exception record
|
|
//
|
|
|
|
ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
|
|
|
|
//
|
|
// We only want the low order 2 bits so typecast to ULONG
|
|
//
|
|
IpsrRi = (ULONG)(TrapFrame->StIPSR >> PSR_RI) & 0x3;
|
|
|
|
ExceptionRecord->ExceptionAddress =
|
|
(PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP, IpsrRi);
|
|
|
|
ExceptionRecord->ExceptionFlags = 0;
|
|
ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)NULL;
|
|
|
|
ExceptionRecord->NumberParameters = 5;
|
|
ExceptionRecord->ExceptionInformation[0] = 0;
|
|
ExceptionRecord->ExceptionInformation[1] = 0; // 0 for traps
|
|
ExceptionRecord->ExceptionInformation[2] = 0;
|
|
ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
|
|
ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
|
|
|
|
ExceptionRecord->ExceptionCode = STATUS_SINGLE_STEP;
|
|
|
|
return TRUE;
|
|
}
|