Windows2000/private/ntos/kd64/kdp.h
2020-09-30 17:12:32 +02:00

389 lines
15 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
kdp.h
Abstract:
Private include file for the Kernel Debugger subcomponent of the NTOS project
Author:
Mike O'Leary (mikeol) 29-June-1989
*/
#include "ntos.h"
#include "ki.h"
#define NOEXTAPI
#include "wdbgexts.h"
#include "ntdbg.h"
#include "string.h"
#include "stdlib.h"
#if defined(_ALPHA_)
#include "alphaops.h"
// Define KD private PCR routines.
// Using the following private KD routines allows the kernel debugger to step over breakpoints in modules that call the standard PCR routines.
PKPCR KdpGetPcr();
ULONG KdpReadInternalProcessorState(PVOID, ULONG);
ULONG KdpReadInternalProcessorCounters(PVOID, ULONG);
struct _KPRCB * KdpGetCurrentPrcb();
struct _KTHREAD * KdpGetCurrentThread();
// Redefine the standard PCR routines
#undef KiPcr
#define KiPcr KdpGetPcr()
#undef KeGetPcr
#undef KeGetCurrentPrcb
#undef KeGetCurrentThread
#undef KeIsExecutingDpc
#define KeGetPcr() KdpGetPcr()
#define KeGetCurrentPrcb() KdpGetCurrentPrcb()
#define KeGetCurrentThread() KdpGetCurrentThread()
// Define TYPES
#define KDP_BREAKPOINT_TYPE ULONG
#define KDP_BREAKPOINT_ALIGN 3// longword aligned
#define KDP_BREAKPOINT_VALUE KBPT_FUNC// actual instruction is "call_pal kbpt"
#elif defined(_IA64_)
// IA64 instruction is in a 128-bit bundle. Each bundle consists of 3 instruction slots.
// Each instruction slot is 41-bit long.
// 127 87 86 46 45 5 4 1 0
// | slot 2 | slot 1 | slot 0 |template|S|
// 127 96 95 64 63 32 31 0
// | byte 3 | byte 2 | byte 1 | byte 0 |
// This presents two incompatibilities with conventional processors:
// 1. The IA64 IP address is at the bundle bundary. The instruction slot number is
// stored in ISR.ei at the time of exception.
// 2. The 41-bit instruction format is not byte-aligned.
// Break instruction insertion must be done with proper bit-shifting to align with the selected
// instruction slot. Further, to insert break instruction insertion at a specific slot, we must
// be able to specify instruction slot as part of the address. We therefore define an EM address as
// bundle address + slot number with the least significant two bit always zero:
// 31 4 3 2 1 0
// | bundle address |slot#|0 0|
// The EM address as defined is the byte-aligned address that is closest to the actual instruction slot.
// i.e., The EM instruction address of slot #0 is equal to bundle address.
// slot #1 is equal to bundle address + 4.
// slot #2 is equal to bundle address + 8.
// Upon exception, the bundle address is kept in IIP, and the instruction slot which caused
// the exception is in ISR.ei. Kernel exception handler will construct the flat address and
// export it in ExceptionRecord.ExceptionAddress.
#define KDP_BREAKPOINT_TYPE ULONGLONG // 64-bit ULONGLONG type is needed to cover 41-bit EM break instruction.
#define KDP_BREAKPOINT_ALIGN 0x3 // An EM address consists of bundle and slot number and is 32-bit aligned.
#define KDP_BREAKPOINT_VALUE (BREAK_INSTR | (DEBUG_STOP_BREAKPOINT << 6))
#elif defined(_X86_)
#define KDP_BREAKPOINT_TYPE UCHAR
#define KDP_BREAKPOINT_ALIGN 0
#define KDP_BREAKPOINT_VALUE 0xcc
#endif
// Define constants.
// Addresses above GLOBAL_BREAKPOINT_LIMIT are either in system space or part of dynlink, so we treat them as global.
#define GLOBAL_BREAKPOINT_LIMIT 1610612736L // 1.5gigabytes
// Define breakpoint table entry structure.
#define KD_BREAKPOINT_IN_USE 0x00000001
#define KD_BREAKPOINT_NEEDS_WRITE 0x00000002
#define KD_BREAKPOINT_SUSPENDED 0x00000004
#define KD_BREAKPOINT_NEEDS_REPLACE 0x00000008
// IA64 specific defines
#define KD_BREAKPOINT_STATE_MASK 0x0000000f
#define KD_BREAKPOINT_IA64_MASK 0x000f0000
#define KD_BREAKPOINT_IA64_MODE 0x00010000 // IA64 mode
#define KD_BREAKPOINT_IA64_MOVL 0x00020000 // MOVL instruction displaced
// status Constants for Packet waiting
#define KDP_PACKET_RECEIVED 0
#define KDP_PACKET_TIMEOUT 1
#define KDP_PACKET_RESEND 2
typedef struct _BREAKPOINT_ENTRY {
ULONG Flags;
ULONG_PTR DirectoryTableBase;
PVOID Address;
KDP_BREAKPOINT_TYPE Content;
} BREAKPOINT_ENTRY, *PBREAKPOINT_ENTRY;
// Misc defines
#define MAXIMUM_RETRIES 20
#define DBGKD_MAX_SPECIAL_CALLS 10
typedef struct _TRACE_DATA_SYM {
ULONG SymMin;
ULONG SymMax;
} TRACE_DATA_SYM, *PTRACE_DATA_SYM;
// Define function prototypes.
VOID KdpReboot (VOID);
BOOLEAN KdpPrintString (IN PSTRING Output);
BOOLEAN KdpPromptString (IN PSTRING Output, IN OUT PSTRING Input);
ULONG KdpAddBreakpoint (IN PVOID Address);
BOOLEAN KdpDeleteBreakpoint (IN ULONG Handle);
BOOLEAN KdpDeleteBreakpointRange (IN PVOID Lower, IN PVOID Upper);
#if defined(_IA64_)
BOOLEAN KdpSuspendBreakpointRange (IN PVOID Lower, IN PVOID Upper);
BOOLEAN KdpRestoreBreakpointRange (IN PVOID Lower, IN PVOID Upper);
#endif
#if i386
NTSTATUS KdGetTraceInformation (OUT PVOID TraceInformation, IN ULONG TraceInformationLength, OUT PULONG RequiredLength);
VOID KdSetInternalBreakpoint (IN PDBGKD_MANIPULATE_STATE64 m);
#endif
NTSTATUS KdQuerySpecialCalls (IN PDBGKD_MANIPULATE_STATE64 m, IN ULONG Length, OUT PULONG RequiredLength);
VOID KdSetSpecialCall (IN PDBGKD_MANIPULATE_STATE64 m, IN PCONTEXT ContextRecord);
VOID KdClearSpecialCalls (VOID);
ULONG KdpMoveMemory (IN PCHAR Destination, IN PCHAR Source, IN ULONG Length);
VOID KdpQuickMoveMemory (IN PCHAR Destination, IN PCHAR Source, IN ULONG Length);
ULONG KdpReceivePacket (IN ULONG ExpectedPacketType, OUT PSTRING MessageHeader, OUT PSTRING MessageData, OUT PULONG DataLength);
VOID KdpSetLoadState(IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange, IN PCONTEXT ContextRecord);
VOID KdpSetStateChange(IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN BOOLEAN SecondChance);
VOID KdpGetStateChange(IN PDBGKD_MANIPULATE_STATE64 ManipulateState, IN PCONTEXT ContextRecord);
VOID KdpSendPacket (IN ULONG PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData OPTIONAL);
BOOLEAN KdpStub (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord,
IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance);
BOOLEAN KdpTrap (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord64,
IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance);
BOOLEAN KdpSwitchProcessor (IN PEXCEPTION_RECORD ExceptionRecord, IN OUT PCONTEXT ContextRecord, IN BOOLEAN SecondChance);
BOOLEAN KdpReportExceptionStateChange (IN PEXCEPTION_RECORD ExceptionRecord, IN OUT PCONTEXT ContextRecord, IN BOOLEAN SecondChance);
BOOLEAN KdpReportLoadSymbolsStateChange (IN PSTRING PathName, IN PKD_SYMBOLS_INFO SymbolInfo, IN BOOLEAN UnloadSymbols, IN OUT PCONTEXT ContextRecord);
KCONTINUE_STATUS KdpSendWaitContinue(IN ULONG PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData OPTIONAL, IN OUT PCONTEXT ContextRecord);
VOID KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
#if 0
VOID KdpReadVirtualMemory64(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
#endif
VOID KdpWriteVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
#if 0
VOID KdpWriteVirtualMemory64(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
#endif
VOID KdpReadPhysicalMemory(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpWritePhysicalMemory(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpCheckLowMemory(IN PDBGKD_MANIPULATE_STATE64 m);
VOID KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpWriteBreakpoint(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpRestoreBreakpoint(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpReadControlSpace(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpReadIoSpace(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpReadMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpWriteIoSpace(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpWriteMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
#ifdef _ALPHA_
VOID KdpReadIoSpaceExtended (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpWriteIoSpaceExtended (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpGetBusData (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
VOID KdpSetBusData (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context);
#endif
VOID KdpSuspendBreakpoint (ULONG Handle);
VOID KdpSuspendAllBreakpoints (VOID);
VOID KdpRestoreAllBreakpoints (VOID);
VOID KdpTimeSlipDpcRoutine (PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
VOID KdpTimeSlipWork (IN PVOID Context);
// Define dummy prototype so the address of the standard breakpoint instruction can be captured.
// N.B. This function is NEVER called.
VOID RtlpBreakWithStatusInstruction (VOID);
// Define external references.
#define KDP_MESSAGE_BUFFER_SIZE 4096
extern BREAKPOINT_ENTRY KdpBreakpointTable[BREAKPOINT_TABLE_SIZE];
extern BOOLEAN KdpControlCPending;
extern KSPIN_LOCK KdpDebuggerLock;
extern PKDEBUG_ROUTINE KiDebugRoutine;
extern PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
extern KDP_BREAKPOINT_TYPE KdpBreakpointInstruction;
extern UCHAR KdpMessageBuffer[KDP_MESSAGE_BUFFER_SIZE];
extern UCHAR KdpPathBuffer[KDP_MESSAGE_BUFFER_SIZE];
extern ULONG KdpOweBreakpoint;
extern ULONG KdpNextPacketIdToSend;
extern ULONG KdpPacketIdExpected;
extern LARGE_INTEGER KdPerformanceCounterRate;
extern LARGE_INTEGER KdTimerStart;
extern LARGE_INTEGER KdTimerStop;
extern LARGE_INTEGER KdTimerDifference;
extern BOOLEAN BreakpointsSuspended;
extern PVOID KdpNtosImageBase;
extern LIST_ENTRY KdpDebuggerDataListHead;
typedef struct {
ULONG64 Addr; // pc address of breakpoint
ULONG Flags; // Flags bits
ULONG Calls; // # of times traced routine called
ULONG CallsLastCheck; // # of calls at last periodic (1s) check
ULONG MaxCallsPerPeriod;
ULONG MinInstructions; // largest number of instructions for 1 call
ULONG MaxInstructions; // smallest # of instructions for 1 call
ULONG TotalInstructions; // total instructions for all calls
ULONG Handle; // handle in (regular) bpt table
PVOID Thread; // Thread that's skipping this BP
ULONG64 ReturnAddress; // return address (if not COUNTONLY)
} DBGKD_INTERNAL_BREAKPOINT, *PDBGKD_INTERNAL_BREAKPOINT;
#define DBGKD_MAX_INTERNAL_BREAKPOINTS 20
extern DBGKD_INTERNAL_BREAKPOINT KdpInternalBPs[DBGKD_MAX_INTERNAL_BREAKPOINTS];
extern ULONG_PTR KdpCurrentSymbolStart;
extern ULONG_PTR KdpCurrentSymbolEnd;
extern LONG KdpNextCallLevelChange;
extern ULONG_PTR KdSpecialCalls[];
extern ULONG KdNumberOfSpecialCalls;
extern ULONG_PTR InitialSP;
extern ULONG KdpNumInternalBreakpoints;
extern KTIMER InternalBreakpointTimer;
extern KDPC InternalBreakpointCheckDpc;
extern BOOLEAN KdpPortLocked;
extern LARGE_INTEGER KdpTimeEntered;
extern DBGKD_TRACE_DATA TraceDataBuffer[];
extern ULONG TraceDataBufferPosition;
extern TRACE_DATA_SYM TraceDataSyms[];
extern UCHAR NextTraceDataSym;
extern UCHAR NumTraceDataSyms;
extern ULONG IntBPsSkipping;
extern BOOLEAN WatchStepOver;
extern PVOID WSOThread;
extern ULONG_PTR WSOEsp;
extern ULONG WatchStepOverHandle;
extern ULONG_PTR WatchStepOverBreakAddr;
extern BOOLEAN WatchStepOverSuspended;
extern ULONG InstructionsTraced;
extern BOOLEAN SymbolRecorded;
extern LONG CallLevelChange;
extern LONG_PTR oldpc;
extern BOOLEAN InstrCountInternal;
extern BOOLEAN BreakpointsSuspended;
extern BOOLEAN KdpControlCPending;
extern BOOLEAN KdpControlCPressed;
extern ULONG KdpRetryCount;
extern ULONG KdpNumberRetries;
extern ULONG KdpDefaultRetries;
extern KDP_BREAKPOINT_TYPE KdpBreakpointInstruction;
extern ULONG KdpOweBreakpoint;
extern ULONG KdpNextPacketIdToSend;
extern ULONG KdpPacketIdExpected;
extern PVOID KdpNtosImageBase;
extern UCHAR KdPrintCircularBuffer[KDPRINTBUFFERSIZE];
extern PUCHAR KdPrintWritePointer;
extern ULONG KdPrintRolloverCount;
extern KSPIN_LOCK KdpPrintSpinLock;
extern DEBUG_PARAMETERS KdDebugParameters;
extern KSPIN_LOCK KdpDataSpinLock;
extern LIST_ENTRY KdpDebuggerDataListHead;
extern KDDEBUGGER_DATA64 KdDebuggerDataBlock;
extern KDPC KdpTimeSlipDpc;
extern WORK_QUEUE_ITEM KdpTimeSlipWorkItem;
extern KTIMER KdpTimeSlipTimer;
extern ULONG KdpTimeSlipPending;
extern KSPIN_LOCK KdpTimeSlipEventLock;
extern PVOID KdpTimeSlipEvent;
extern BOOLEAN KdpDebuggerStructuresInitialized;
extern ULONG KdEnteredDebugger;
// !search support (page hit database)
// Hit database where search results are stored (kddata.c).
// The debugger extensions know how to extract the information from here.
// Note that the size of the hit database is large enough to
// accomodate any searches because the !search extension works
// in batches of pages < PAGE_SIZE and for every page we register only one hit.
#define SEARCH_PAGE_HIT_DATABASE_SIZE PAGE_SIZE
extern PFN_NUMBER KdpSearchPageHits[SEARCH_PAGE_HIT_DATABASE_SIZE];
extern ULONG KdpSearchPageHitOffsets[SEARCH_PAGE_HIT_DATABASE_SIZE];
extern ULONG KdpSearchPageHitIndex;
// Set to true while a physical memory search is in progress.
// Reset at the end of the search. This is done in the debugger
// extension and it is a flag used by KdpCheckLowMemory to get onto a different code path.
extern LOGICAL KdpSearchInProgress;
// These variables store the current state of the search operation.
// They can be used to restore an interrupted search.
extern PFN_NUMBER KdpSearchStartPageFrame;
extern PFN_NUMBER KdpSearchEndPageFrame;
extern ULONG_PTR KdpSearchAddressRangeStart;
extern ULONG_PTR KdpSearchAddressRangeEnd;
// Checkpoint variable used to test if we have the right debugging symbols.
#define KDP_SEARCH_SYMBOL_CHECK 0xABCDDCBA
extern ULONG KdpSearchCheckPoint;
// Page search flags
#define KDP_SEARCH_ALL_OFFSETS_IN_PAGE 0x0001
// Private procedure prototypes
VOID KdpInitCom(VOID);
VOID KdpPortLock(VOID);
VOID KdpPortUnlock(VOID);
BOOLEAN KdpPollBreakInWithPortLock(VOID);
USHORT KdpReceivePacketLeader (IN ULONG PacketType, OUT PULONG PacketLeader);
#if DBG
#include <stdio.h>
#define DPRINT(s) KdpDprintf s
VOID KdpDprintf(IN PCHAR f, ...);
#else
#define DPRINT(s)
#endif