276 lines
5.8 KiB
C
276 lines
5.8 KiB
C
/*++
|
||
|
||
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;
|
||
}
|