/* Array of conditions when to enter KDB */
static KDB_ENTER_CONDITION KdbEnterConditions[][2] =
{
- /* First chance Last chance */
- { KdbDoNotEnter, KdbEnterFromKmode }, /* Zero devide */
- { KdbEnterFromKmode, KdbDoNotEnter }, /* Debug trap */
- { KdbDoNotEnter, KdbEnterAlways }, /* NMI */
- { KdbEnterFromKmode, KdbDoNotEnter }, /* INT3 */
- { KdbDoNotEnter, KdbEnterFromKmode }, /* Overflow */
- { KdbDoNotEnter, KdbEnterFromKmode },
- { KdbDoNotEnter, KdbEnterFromKmode }, /* Invalid opcode */
- { KdbDoNotEnter, KdbEnterFromKmode }, /* No math coprocessor fault */
- { KdbEnterAlways, KdbEnterAlways },
- { KdbEnterAlways, KdbEnterAlways },
- { KdbDoNotEnter, KdbEnterFromKmode },
- { KdbDoNotEnter, KdbEnterFromKmode },
- { KdbDoNotEnter, KdbEnterFromKmode }, /* Stack fault */
- { KdbDoNotEnter, KdbEnterFromKmode }, /* General protection fault */
- { KdbDoNotEnter, KdbEnterFromKmode }, /* Page fault */
- { KdbEnterAlways, KdbEnterAlways }, /* Reserved (15) */
- { KdbDoNotEnter, KdbEnterFromKmode }, /* FPU fault */
- { KdbDoNotEnter, KdbEnterFromKmode },
- { KdbDoNotEnter, KdbEnterFromKmode },
- { KdbDoNotEnter, KdbEnterFromKmode }, /* SIMD fault */
- { KdbDoNotEnter, KdbEnterFromKmode } /* Last entry: used for unknown exceptions */
+ /* First chance Last chance */
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* Zero devide */
+ { KdbEnterFromKmode, KdbDoNotEnter }, /* Debug trap */
+ { KdbDoNotEnter, KdbEnterAlways }, /* NMI */
+ { KdbEnterFromKmode, KdbDoNotEnter }, /* INT3 */
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* Overflow */
+ { KdbDoNotEnter, KdbEnterFromKmode },
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* Invalid opcode */
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* No math coprocessor fault */
+ { KdbEnterAlways, KdbEnterAlways },
+ { KdbEnterAlways, KdbEnterAlways },
+ { KdbDoNotEnter, KdbEnterFromKmode },
+ { KdbDoNotEnter, KdbEnterFromKmode },
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* Stack fault */
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* General protection fault */
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* Page fault */
+ { KdbEnterAlways, KdbEnterAlways }, /* Reserved (15) */
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* FPU fault */
+ { KdbDoNotEnter, KdbEnterFromKmode },
+ { KdbDoNotEnter, KdbEnterFromKmode },
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* SIMD fault */
+ { KdbDoNotEnter, KdbEnterFromKmode } /* Last entry: used for unknown exceptions */
};
/* Exception descriptions */
static const CHAR *ExceptionNrToString[] =
{
- "Divide Error",
- "Debug Trap",
- "NMI",
- "Breakpoint",
- "Overflow",
- "BOUND range exceeded",
- "Invalid Opcode",
- "No Math Coprocessor",
- "Double Fault",
- "Unknown(9)",
- "Invalid TSS",
- "Segment Not Present",
- "Stack Segment Fault",
- "General Protection",
- "Page Fault",
- "Reserved(15)",
- "Math Fault",
- "Alignment Check",
- "Machine Check",
- "SIMD Fault"
+ "Divide Error",
+ "Debug Trap",
+ "NMI",
+ "Breakpoint",
+ "Overflow",
+ "BOUND range exceeded",
+ "Invalid Opcode",
+ "No Math Coprocessor",
+ "Double Fault",
+ "Unknown(9)",
+ "Invalid TSS",
+ "Segment Not Present",
+ "Stack Segment Fault",
+ "General Protection",
+ "Page Fault",
+ "Reserved(15)",
+ "Math Fault",
+ "Alignment Check",
+ "Machine Check",
+ "SIMD Fault"
};
ULONG
NTAPI
-KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame);
+KiSsFromTrapFrame(
+ IN PKTRAP_FRAME TrapFrame);
ULONG
NTAPI
-KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame);
+KiEspFromTrapFrame(
+ IN PKTRAP_FRAME TrapFrame);
VOID
NTAPI
-KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame,
- IN ULONG Ss);
+KiSsToTrapFrame(
+ IN PKTRAP_FRAME TrapFrame,
+ IN ULONG Ss);
VOID
NTAPI
-KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
- IN ULONG Esp);
+KiEspToTrapFrame(
+ IN PKTRAP_FRAME TrapFrame,
+ IN ULONG Esp);
/* ROS Internal. Please deprecate */
NTHALAPI
VOID
NTAPI
-HalReleaseDisplayOwnership(
- VOID
-);
+HalReleaseDisplayOwnership();
/* FUNCTIONS *****************************************************************/
static VOID
-KdbpTrapFrameToKdbTrapFrame(PKTRAP_FRAME TrapFrame, PKDB_KTRAP_FRAME KdbTrapFrame)
+KdbpTrapFrameToKdbTrapFrame(
+ PKTRAP_FRAME TrapFrame,
+ PKDB_KTRAP_FRAME KdbTrapFrame)
{
- ULONG TrapCr0, TrapCr2, TrapCr3, TrapCr4;
+ ULONG TrapCr0, TrapCr2, TrapCr3, TrapCr4;
- /* Copy the TrapFrame only up to Eflags and zero the rest*/
- RtlCopyMemory(&KdbTrapFrame->Tf, TrapFrame, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
- RtlZeroMemory((PVOID)((ULONG_PTR)&KdbTrapFrame->Tf + FIELD_OFFSET(KTRAP_FRAME, HardwareEsp)),
- sizeof (KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
+ /* Copy the TrapFrame only up to Eflags and zero the rest*/
+ RtlCopyMemory(&KdbTrapFrame->Tf, TrapFrame, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
+ RtlZeroMemory((PVOID)((ULONG_PTR)&KdbTrapFrame->Tf + FIELD_OFFSET(KTRAP_FRAME, HardwareEsp)),
+ sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
#ifndef _MSC_VER
asm volatile(
KdbTrapFrame->Tf.HardwareSegSs = (USHORT)(KiSsFromTrapFrame(TrapFrame) & 0xFFFF);
- /* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
+ /* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
}
static VOID
-KdbpKdbTrapFrameToTrapFrame(PKDB_KTRAP_FRAME KdbTrapFrame, PKTRAP_FRAME TrapFrame)
+KdbpKdbTrapFrameToTrapFrame(
+ PKDB_KTRAP_FRAME KdbTrapFrame,
+ PKTRAP_FRAME TrapFrame)
{
- /* Copy the TrapFrame only up to Eflags and zero the rest*/
- RtlCopyMemory(TrapFrame, &KdbTrapFrame->Tf, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
+ /* Copy the TrapFrame only up to Eflags and zero the rest*/
+ RtlCopyMemory(TrapFrame, &KdbTrapFrame->Tf, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
- /* FIXME: write cr0, cr2, cr3 and cr4 (not needed atm) */
+ /* FIXME: write cr0, cr2, cr3 and cr4 (not needed atm) */
KiSsToTrapFrame(TrapFrame, KdbTrapFrame->Tf.HardwareSegSs);
KiEspToTrapFrame(TrapFrame, KdbTrapFrame->Tf.HardwareEsp);
- /* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
+ /* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
}
static VOID
-KdbpKdbTrapFrameFromKernelStack(PVOID KernelStack,
- PKDB_KTRAP_FRAME KdbTrapFrame)
+KdbpKdbTrapFrameFromKernelStack(
+ PVOID KernelStack,
+ PKDB_KTRAP_FRAME KdbTrapFrame)
{
- ULONG_PTR *StackPtr;
-
- RtlZeroMemory(KdbTrapFrame, sizeof(KDB_KTRAP_FRAME));
- StackPtr = (ULONG_PTR *) KernelStack;
- KdbTrapFrame->Tf.Ebp = StackPtr[3];
- KdbTrapFrame->Tf.Edi = StackPtr[4];
- KdbTrapFrame->Tf.Esi = StackPtr[5];
- KdbTrapFrame->Tf.Ebx = StackPtr[6];
- KdbTrapFrame->Tf.Eip = StackPtr[7];
- KdbTrapFrame->Tf.HardwareEsp = (ULONG) (StackPtr + 8);
- KdbTrapFrame->Tf.HardwareSegSs = KGDT_R0_DATA;
- KdbTrapFrame->Tf.SegCs = KGDT_R0_CODE;
- KdbTrapFrame->Tf.SegDs = KGDT_R0_DATA;
- KdbTrapFrame->Tf.SegEs = KGDT_R0_DATA;
- KdbTrapFrame->Tf.SegGs = KGDT_R0_DATA;
-
- /* FIXME: what about the other registers??? */
+ ULONG_PTR *StackPtr;
+
+ RtlZeroMemory(KdbTrapFrame, sizeof(KDB_KTRAP_FRAME));
+ StackPtr = (ULONG_PTR *) KernelStack;
+ KdbTrapFrame->Tf.Ebp = StackPtr[3];
+ KdbTrapFrame->Tf.Edi = StackPtr[4];
+ KdbTrapFrame->Tf.Esi = StackPtr[5];
+ KdbTrapFrame->Tf.Ebx = StackPtr[6];
+ KdbTrapFrame->Tf.Eip = StackPtr[7];
+ KdbTrapFrame->Tf.HardwareEsp = (ULONG) (StackPtr + 8);
+ KdbTrapFrame->Tf.HardwareSegSs = KGDT_R0_DATA;
+ KdbTrapFrame->Tf.SegCs = KGDT_R0_CODE;
+ KdbTrapFrame->Tf.SegDs = KGDT_R0_DATA;
+ KdbTrapFrame->Tf.SegEs = KGDT_R0_DATA;
+ KdbTrapFrame->Tf.SegGs = KGDT_R0_DATA;
+
+ /* FIXME: what about the other registers??? */
}
/*!\brief Overwrites the instruction at \a Address with \a NewInst and stores
*/
static NTSTATUS
KdbpOverwriteInstruction(
- IN PEPROCESS Process,
- IN ULONG_PTR Address,
- IN UCHAR NewInst,
- OUT PUCHAR OldInst OPTIONAL)
+ IN PEPROCESS Process,
+ IN ULONG_PTR Address,
+ IN UCHAR NewInst,
+ OUT PUCHAR OldInst OPTIONAL)
{
- NTSTATUS Status;
- ULONG Protect;
- PEPROCESS CurrentProcess = PsGetCurrentProcess();
- KAPC_STATE ApcState;
+ NTSTATUS Status;
+ ULONG Protect;
+ PEPROCESS CurrentProcess = PsGetCurrentProcess();
+ KAPC_STATE ApcState;
- /* Get the protection for the address. */
- Protect = MmGetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address));
+ /* Get the protection for the address. */
+ Protect = MmGetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address));
- /* Return if that page isn't present. */
- if (Protect & PAGE_NOACCESS)
- {
- return STATUS_MEMORY_NOT_ALLOCATED;
- }
+ /* Return if that page isn't present. */
+ if (Protect & PAGE_NOACCESS)
+ {
+ return STATUS_MEMORY_NOT_ALLOCATED;
+ }
- /* Attach to the process */
- if (CurrentProcess != Process)
- {
- KeStackAttachProcess(&Process->Pcb, &ApcState);
- }
+ /* Attach to the process */
+ if (CurrentProcess != Process)
+ {
+ KeStackAttachProcess(&Process->Pcb, &ApcState);
+ }
- /* Make the page writeable if it is read only. */
- if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
- {
- MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address),
- (Protect & ~(PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ)) | PAGE_READWRITE);
- }
+ /* Make the page writeable if it is read only. */
+ if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
+ {
+ MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address),
+ (Protect & ~(PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ)) | PAGE_READWRITE);
+ }
- /* Copy the old instruction back to the caller. */
- if (OldInst != NULL)
- {
- Status = KdbpSafeReadMemory(OldInst, (PUCHAR)Address, 1);
- if (!NT_SUCCESS(Status))
- {
- if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
- {
- MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address), Protect);
- }
- /* Detach from process */
- if (CurrentProcess != Process)
- {
- KeDetachProcess();
- }
- return Status;
- }
- }
+ /* Copy the old instruction back to the caller. */
+ if (OldInst)
+ {
+ Status = KdbpSafeReadMemory(OldInst, (PUCHAR)Address, 1);
+ if (!NT_SUCCESS(Status))
+ {
+ if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
+ {
+ MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address), Protect);
+ }
- /* Copy the new instruction in its place. */
- Status = KdbpSafeWriteMemory((PUCHAR)Address, &NewInst, 1);
+ /* Detach from process */
+ if (CurrentProcess != Process)
+ {
+ KeDetachProcess();
+ }
- /* Restore the page protection. */
- if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
- {
- MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address), Protect);
- }
+ return Status;
+ }
+ }
- /* Detach from process */
- if (CurrentProcess != Process)
- {
- KeUnstackDetachProcess(&ApcState);
- }
+ /* Copy the new instruction in its place. */
+ Status = KdbpSafeWriteMemory((PUCHAR)Address, &NewInst, 1);
- return Status;
+ /* Restore the page protection. */
+ if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
+ {
+ MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address), Protect);
+ }
+
+ /* Detach from process */
+ if (CurrentProcess != Process)
+ {
+ KeUnstackDetachProcess(&ApcState);
+ }
+
+ return Status;
}
/*!\brief Checks whether the given instruction can be single stepped or has to be
* \retval FALSE Instruction is not a call.
*/
BOOLEAN
-KdbpShouldStepOverInstruction(ULONG_PTR Eip)
+KdbpShouldStepOverInstruction(
+ ULONG_PTR Eip)
{
- UCHAR Mem[3];
- ULONG i = 0;
+ UCHAR Mem[3];
+ ULONG i = 0;
- if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
- {
- KdbpPrint("Couldn't access memory at 0x%p\n", Eip);
- return FALSE;
- }
+ if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
+ {
+ KdbpPrint("Couldn't access memory at 0x%p\n", Eip);
+ return FALSE;
+ }
- /* Check if the current instruction is a call. */
- while ((i < sizeof (Mem)) && (Mem[i] == 0x66 || Mem[i] == 0x67))
- i++;
- if (i == sizeof (Mem))
- return FALSE;
- if (Mem[i] == 0xE8 || Mem[i] == 0x9A || Mem[i] == 0xF2 || Mem[i] == 0xF3 ||
- (((i + 1) < sizeof (Mem)) && Mem[i] == 0xFF && (Mem[i+1] & 0x38) == 0x10))
- {
- return TRUE;
- }
- return FALSE;
+ /* Check if the current instruction is a call. */
+ while ((i < sizeof (Mem)) && (Mem[i] == 0x66 || Mem[i] == 0x67))
+ i++;
+
+ if (i == sizeof (Mem))
+ return FALSE;
+
+ if (Mem[i] == 0xE8 || Mem[i] == 0x9A || Mem[i] == 0xF2 || Mem[i] == 0xF3 ||
+ (((i + 1) < sizeof (Mem)) && Mem[i] == 0xFF && (Mem[i+1] & 0x38) == 0x10))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
}
/*!\brief Steps over an instruction
* \retval FALSE No breakpoint was set.
*/
BOOLEAN
-KdbpStepOverInstruction(ULONG_PTR Eip)
+KdbpStepOverInstruction(
+ ULONG_PTR Eip)
{
- LONG InstLen;
+ LONG InstLen;
- if (!KdbpShouldStepOverInstruction(Eip))
- return FALSE;
+ if (!KdbpShouldStepOverInstruction(Eip))
+ return FALSE;
- InstLen = KdbpGetInstLength(Eip);
- if (InstLen < 1)
- return FALSE;
+ InstLen = KdbpGetInstLength(Eip);
+ if (InstLen < 1)
+ return FALSE;
- if (!NT_SUCCESS(KdbpInsertBreakPoint(Eip + InstLen, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
- return FALSE;
+ if (!NT_SUCCESS(KdbpInsertBreakPoint(Eip + InstLen, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
+ return FALSE;
- return TRUE;
+ return TRUE;
}
/*!\brief Steps into an instruction (interrupts)
* \retval FALSE No breakpoint was set.
*/
BOOLEAN
-KdbpStepIntoInstruction(ULONG_PTR Eip)
+KdbpStepIntoInstruction(
+ ULONG_PTR Eip)
{
KDESCRIPTOR Idtr = {0};
- UCHAR Mem[2];
- INT IntVect;
- ULONG IntDesc[2];
- ULONG_PTR TargetEip;
+ UCHAR Mem[2];
+ INT IntVect;
+ ULONG IntDesc[2];
+ ULONG_PTR TargetEip;
- /* Read memory */
- if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
- {
- /*KdbpPrint("Couldn't access memory at 0x%p\n", Eip);*/
- return FALSE;
- }
+ /* Read memory */
+ if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
+ {
+ /*KdbpPrint("Couldn't access memory at 0x%p\n", Eip);*/
+ return FALSE;
+ }
- /* Check for INT instruction */
- /* FIXME: Check for iret */
- if (Mem[0] == 0xcc)
- IntVect = 3;
- else if (Mem[0] == 0xcd)
- IntVect = Mem[1];
- else if (Mem[0] == 0xce && KdbCurrentTrapFrame->Tf.EFlags & (1<<11)) /* 1 << 11 is the overflow flag */
- IntVect = 4;
- else
- return FALSE;
-
- if (IntVect < 32) /* We should be informed about interrupts < 32 by the kernel, no need to breakpoint them */
- {
- return FALSE;
- }
+ /* Check for INT instruction */
+ /* FIXME: Check for iret */
+ if (Mem[0] == 0xcc)
+ IntVect = 3;
+ else if (Mem[0] == 0xcd)
+ IntVect = Mem[1];
+ else if (Mem[0] == 0xce && KdbCurrentTrapFrame->Tf.EFlags & (1<<11)) /* 1 << 11 is the overflow flag */
+ IntVect = 4;
+ else
+ return FALSE;
+
+ if (IntVect < 32) /* We should be informed about interrupts < 32 by the kernel, no need to breakpoint them */
+ {
+ return FALSE;
+ }
- /* Read the interrupt descriptor table register */
- Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Idtr.Limit);
- if (IntVect >= (Idtr.Limit + 1) / 8)
- {
- /*KdbpPrint("IDT does not contain interrupt vector %d\n.", IntVect);*/
- return TRUE;
- }
+ /* Read the interrupt descriptor table register */
+ Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Idtr.Limit);
+ if (IntVect >= (Idtr.Limit + 1) / 8)
+ {
+ /*KdbpPrint("IDT does not contain interrupt vector %d\n.", IntVect);*/
+ return TRUE;
+ }
- /* Get the interrupt descriptor */
- if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)(Idtr.Base + (IntVect * 8)), sizeof (IntDesc))))
- {
- /*KdbpPrint("Couldn't access memory at 0x%p\n", (ULONG_PTR)Idtr.Base + (IntVect * 8));*/
- return FALSE;
- }
+ /* Get the interrupt descriptor */
+ if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)(Idtr.Base + (IntVect * 8)), sizeof (IntDesc))))
+ {
+ /*KdbpPrint("Couldn't access memory at 0x%p\n", (ULONG_PTR)Idtr.Base + (IntVect * 8));*/
+ return FALSE;
+ }
- /* Check descriptor and get target eip (16 bit interrupt/trap gates not supported) */
- if ((IntDesc[1] & (1 << 15)) == 0) /* not present */
- {
- return FALSE;
- }
- if ((IntDesc[1] & 0x1f00) == 0x0500) /* Task gate */
- {
- /* FIXME: Task gates not supported */
- return FALSE;
- }
- else if (((IntDesc[1] & 0x1fe0) == 0x0e00) || /* 32 bit Interrupt gate */
- ((IntDesc[1] & 0x1fe0) == 0x0f00)) /* 32 bit Trap gate */
- {
- /* FIXME: Should the segment selector of the interrupt gate be checked? */
- TargetEip = (IntDesc[1] & 0xffff0000) | (IntDesc[0] & 0x0000ffff);
- }
- else
- {
- return FALSE;
- }
+ /* Check descriptor and get target eip (16 bit interrupt/trap gates not supported) */
+ if ((IntDesc[1] & (1 << 15)) == 0) /* not present */
+ {
+ return FALSE;
+ }
+ if ((IntDesc[1] & 0x1f00) == 0x0500) /* Task gate */
+ {
+ /* FIXME: Task gates not supported */
+ return FALSE;
+ }
+ else if (((IntDesc[1] & 0x1fe0) == 0x0e00) || /* 32 bit Interrupt gate */
+ ((IntDesc[1] & 0x1fe0) == 0x0f00)) /* 32 bit Trap gate */
+ {
+ /* FIXME: Should the segment selector of the interrupt gate be checked? */
+ TargetEip = (IntDesc[1] & 0xffff0000) | (IntDesc[0] & 0x0000ffff);
+ }
+ else
+ {
+ return FALSE;
+ }
- /* Insert breakpoint */
- if (!NT_SUCCESS(KdbpInsertBreakPoint(TargetEip, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
- return FALSE;
+ /* Insert breakpoint */
+ if (!NT_SUCCESS(KdbpInsertBreakPoint(TargetEip, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
+ return FALSE;
- return TRUE;
+ return TRUE;
}
/*!\brief Gets the number of the next breakpoint >= Start.
*/
LONG
KdbpGetNextBreakPointNr(
- IN ULONG Start OPTIONAL)
+ IN ULONG Start OPTIONAL)
{
- for (; Start < RTL_NUMBER_OF(KdbBreakPoints); Start++)
- {
- if (KdbBreakPoints[Start].Type != KdbBreakPointNone)
- return Start;
- }
- return -1;
+ for (; Start < RTL_NUMBER_OF(KdbBreakPoints); Start++)
+ {
+ if (KdbBreakPoints[Start].Type != KdbBreakPointNone)
+ return Start;
+ }
+
+ return -1;
}
/*!\brief Returns information of the specified breakpoint.
*/
BOOLEAN
KdbpGetBreakPointInfo(
- IN ULONG BreakPointNr,
- OUT ULONG_PTR *Address OPTIONAL,
- OUT KDB_BREAKPOINT_TYPE *Type OPTIONAL,
- OUT UCHAR *Size OPTIONAL,
- OUT KDB_ACCESS_TYPE *AccessType OPTIONAL,
- OUT UCHAR *DebugReg OPTIONAL,
- OUT BOOLEAN *Enabled OPTIONAL,
- OUT BOOLEAN *Global OPTIONAL,
- OUT PEPROCESS *Process OPTIONAL,
- OUT PCHAR *ConditionExpression OPTIONAL)
+ IN ULONG BreakPointNr,
+ OUT ULONG_PTR *Address OPTIONAL,
+ OUT KDB_BREAKPOINT_TYPE *Type OPTIONAL,
+ OUT UCHAR *Size OPTIONAL,
+ OUT KDB_ACCESS_TYPE *AccessType OPTIONAL,
+ OUT UCHAR *DebugReg OPTIONAL,
+ OUT BOOLEAN *Enabled OPTIONAL,
+ OUT BOOLEAN *Global OPTIONAL,
+ OUT PEPROCESS *Process OPTIONAL,
+ OUT PCHAR *ConditionExpression OPTIONAL)
{
- PKDB_BREAKPOINT bp;
+ PKDB_BREAKPOINT bp;
- if (BreakPointNr >= RTL_NUMBER_OF(KdbBreakPoints) ||
- KdbBreakPoints[BreakPointNr].Type == KdbBreakPointNone)
- {
- return FALSE;
- }
+ if (BreakPointNr >= RTL_NUMBER_OF(KdbBreakPoints) ||
+ KdbBreakPoints[BreakPointNr].Type == KdbBreakPointNone)
+ {
+ return FALSE;
+ }
- bp = KdbBreakPoints + BreakPointNr;
- if (Address != NULL)
- *Address = bp->Address;
- if (Type != NULL)
- *Type = bp->Type;
- if (bp->Type == KdbBreakPointHardware)
- {
- if (Size != NULL)
- *Size = bp->Data.Hw.Size;
- if (AccessType != NULL)
- *AccessType = bp->Data.Hw.AccessType;
- if (DebugReg != NULL && bp->Enabled)
- *DebugReg = bp->Data.Hw.DebugReg;
- }
- if (Enabled != NULL)
- *Enabled = bp->Enabled;
- if (Global != NULL)
- *Global = bp->Global;
- if (Process != NULL)
- *Process = bp->Process;
- if (ConditionExpression != NULL)
- *ConditionExpression = bp->ConditionExpression;
-
- return TRUE;
+ bp = KdbBreakPoints + BreakPointNr;
+ if (Address)
+ *Address = bp->Address;
+
+ if (Type)
+ *Type = bp->Type;
+
+ if (bp->Type == KdbBreakPointHardware)
+ {
+ if (Size)
+ *Size = bp->Data.Hw.Size;
+
+ if (AccessType)
+ *AccessType = bp->Data.Hw.AccessType;
+
+ if (DebugReg && bp->Enabled)
+ *DebugReg = bp->Data.Hw.DebugReg;
+ }
+
+ if (Enabled)
+ *Enabled = bp->Enabled;
+
+ if (Global)
+ *Global = bp->Global;
+
+ if (Process)
+ *Process = bp->Process;
+
+ if (ConditionExpression)
+ *ConditionExpression = bp->ConditionExpression;
+
+ return TRUE;
}
/*!\brief Inserts a breakpoint into the breakpoint array.
*/
NTSTATUS
KdbpInsertBreakPoint(
- IN ULONG_PTR Address,
- IN KDB_BREAKPOINT_TYPE Type,
- IN UCHAR Size OPTIONAL,
- IN KDB_ACCESS_TYPE AccessType OPTIONAL,
- IN PCHAR ConditionExpression OPTIONAL,
- IN BOOLEAN Global,
- OUT PLONG BreakPointNr OPTIONAL)
+ IN ULONG_PTR Address,
+ IN KDB_BREAKPOINT_TYPE Type,
+ IN UCHAR Size OPTIONAL,
+ IN KDB_ACCESS_TYPE AccessType OPTIONAL,
+ IN PCHAR ConditionExpression OPTIONAL,
+ IN BOOLEAN Global,
+ OUT PLONG BreakPointNr OPTIONAL)
{
- LONG i;
- PVOID Condition;
- PCHAR ConditionExpressionDup;
- LONG ErrOffset;
- CHAR ErrMsg[128];
+ LONG i;
+ PVOID Condition;
+ PCHAR ConditionExpressionDup;
+ LONG ErrOffset;
+ CHAR ErrMsg[128];
- ASSERT(Type != KdbBreakPointNone);
+ ASSERT(Type != KdbBreakPointNone);
- if (Type == KdbBreakPointHardware)
- {
- if ((Address % Size) != 0)
- {
- KdbpPrint("Address (0x%p) must be aligned to a multiple of the size (%d)\n", Address, Size);
- return STATUS_UNSUCCESSFUL;
- }
- if (AccessType == KdbAccessExec && Size != 1)
- {
- KdbpPrint("Size must be 1 for execution breakpoints.\n");
- return STATUS_UNSUCCESSFUL;
- }
- }
+ if (Type == KdbBreakPointHardware)
+ {
+ if ((Address % Size) != 0)
+ {
+ KdbpPrint("Address (0x%p) must be aligned to a multiple of the size (%d)\n", Address, Size);
+ return STATUS_UNSUCCESSFUL;
+ }
- if (KdbBreakPointCount == KDB_MAXIMUM_BREAKPOINT_COUNT)
- {
- return STATUS_UNSUCCESSFUL;
- }
+ if (AccessType == KdbAccessExec && Size != 1)
+ {
+ KdbpPrint("Size must be 1 for execution breakpoints.\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
- /* Parse conditon expression string and duplicate it */
- if (ConditionExpression != NULL)
- {
- Condition = KdbpRpnParseExpression(ConditionExpression, &ErrOffset, ErrMsg);
- if (Condition == NULL)
- {
- if (ErrOffset >= 0)
- KdbpPrint("Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
- else
- KdbpPrint("Couldn't parse expression: %s", ErrMsg);
- return STATUS_UNSUCCESSFUL;
- }
-
- i = strlen(ConditionExpression) + 1;
- ConditionExpressionDup = ExAllocatePoolWithTag(NonPagedPool, i, TAG_KDBG);
- RtlCopyMemory(ConditionExpressionDup, ConditionExpression, i);
+ if (KdbBreakPointCount == KDB_MAXIMUM_BREAKPOINT_COUNT)
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
- }
- else
- {
- Condition = NULL;
- ConditionExpressionDup = NULL;
- }
+ /* Parse conditon expression string and duplicate it */
+ if (ConditionExpression)
+ {
+ Condition = KdbpRpnParseExpression(ConditionExpression, &ErrOffset, ErrMsg);
+ if (!Condition)
+ {
+ if (ErrOffset >= 0)
+ KdbpPrint("Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
+ else
+ KdbpPrint("Couldn't parse expression: %s", ErrMsg);
- /* Find unused breakpoint */
- if (Type == KdbBreakPointTemporary)
- {
- for (i = RTL_NUMBER_OF(KdbBreakPoints) - 1; i >= 0; i--)
- {
- if (KdbBreakPoints[i].Type == KdbBreakPointNone)
- break;
- }
- }
- else
- {
- for (i = 0; i < (LONG)RTL_NUMBER_OF(KdbBreakPoints); i++)
- {
- if (KdbBreakPoints[i].Type == KdbBreakPointNone)
- break;
- }
- }
- ASSERT(i < (LONG)RTL_NUMBER_OF(KdbBreakPoints));
-
- /* Set the breakpoint */
- ASSERT(KdbCurrentProcess != NULL);
- KdbBreakPoints[i].Type = Type;
- KdbBreakPoints[i].Address = Address;
- KdbBreakPoints[i].Enabled = FALSE;
- KdbBreakPoints[i].Global = Global;
- KdbBreakPoints[i].Process = KdbCurrentProcess;
- KdbBreakPoints[i].ConditionExpression = ConditionExpressionDup;
- KdbBreakPoints[i].Condition = Condition;
- if (Type == KdbBreakPointHardware)
- {
+ return STATUS_UNSUCCESSFUL;
+ }
- KdbBreakPoints[i].Data.Hw.Size = Size;
- KdbBreakPoints[i].Data.Hw.AccessType = AccessType;
- }
- KdbBreakPointCount++;
+ i = strlen(ConditionExpression) + 1;
+ ConditionExpressionDup = ExAllocatePoolWithTag(NonPagedPool, i, TAG_KDBG);
+ RtlCopyMemory(ConditionExpressionDup, ConditionExpression, i);
+ }
+ else
+ {
+ Condition = NULL;
+ ConditionExpressionDup = NULL;
+ }
- if (Type != KdbBreakPointTemporary)
- KdbpPrint("Breakpoint %d inserted.\n", i);
+ /* Find unused breakpoint */
+ if (Type == KdbBreakPointTemporary)
+ {
+ for (i = RTL_NUMBER_OF(KdbBreakPoints) - 1; i >= 0; i--)
+ {
+ if (KdbBreakPoints[i].Type == KdbBreakPointNone)
+ break;
+ }
+ }
+ else
+ {
+ for (i = 0; i < (LONG)RTL_NUMBER_OF(KdbBreakPoints); i++)
+ {
+ if (KdbBreakPoints[i].Type == KdbBreakPointNone)
+ break;
+ }
+ }
- /* Try to enable the breakpoint */
- KdbpEnableBreakPoint(i, NULL);
+ ASSERT(i < (LONG)RTL_NUMBER_OF(KdbBreakPoints));
- /* Return the breakpoint number */
- if (BreakPointNr != NULL)
- *BreakPointNr = i;
+ /* Set the breakpoint */
+ ASSERT(KdbCurrentProcess);
+ KdbBreakPoints[i].Type = Type;
+ KdbBreakPoints[i].Address = Address;
+ KdbBreakPoints[i].Enabled = FALSE;
+ KdbBreakPoints[i].Global = Global;
+ KdbBreakPoints[i].Process = KdbCurrentProcess;
+ KdbBreakPoints[i].ConditionExpression = ConditionExpressionDup;
+ KdbBreakPoints[i].Condition = Condition;
- return STATUS_SUCCESS;
+ if (Type == KdbBreakPointHardware)
+ {
+ KdbBreakPoints[i].Data.Hw.Size = Size;
+ KdbBreakPoints[i].Data.Hw.AccessType = AccessType;
+ }
+
+ KdbBreakPointCount++;
+
+ if (Type != KdbBreakPointTemporary)
+ KdbpPrint("Breakpoint %d inserted.\n", i);
+
+ /* Try to enable the breakpoint */
+ KdbpEnableBreakPoint(i, NULL);
+
+ /* Return the breakpoint number */
+ if (BreakPointNr)
+ *BreakPointNr = i;
+
+ return STATUS_SUCCESS;
}
/*!\brief Deletes a breakpoint
*/
BOOLEAN
KdbpDeleteBreakPoint(
- IN LONG BreakPointNr OPTIONAL,
- IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
+ IN LONG BreakPointNr OPTIONAL,
+ IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
{
- if (BreakPointNr < 0)
- {
- ASSERT(BreakPoint != NULL);
- BreakPointNr = BreakPoint - KdbBreakPoints;
- }
- if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
- {
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
- return FALSE;
- }
- if (BreakPoint == NULL)
- {
- BreakPoint = KdbBreakPoints + BreakPointNr;
- }
- if (BreakPoint->Type == KdbBreakPointNone)
- {
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
- return FALSE;
- }
+ if (BreakPointNr < 0)
+ {
+ ASSERT(BreakPoint);
+ BreakPointNr = BreakPoint - KdbBreakPoints;
+ }
+
+ if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
+ {
+ KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ return FALSE;
+ }
- if (BreakPoint->Enabled &&
- !KdbpDisableBreakPoint(-1, BreakPoint))
- return FALSE;
+ if (!BreakPoint)
+ {
+ BreakPoint = KdbBreakPoints + BreakPointNr;
+ }
- if (BreakPoint->Type != KdbBreakPointTemporary)
- KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr);
- BreakPoint->Type = KdbBreakPointNone;
- KdbBreakPointCount--;
+ if (BreakPoint->Type == KdbBreakPointNone)
+ {
+ KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ return FALSE;
+ }
- return TRUE;
+ if (BreakPoint->Enabled && !KdbpDisableBreakPoint(-1, BreakPoint))
+ return FALSE;
+
+ if (BreakPoint->Type != KdbBreakPointTemporary)
+ KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr);
+
+ BreakPoint->Type = KdbBreakPointNone;
+ KdbBreakPointCount--;
+
+ return TRUE;
}
/*!\brief Checks if the breakpoint was set by the debugger
*/
static LONG
KdbpIsBreakPointOurs(
- IN NTSTATUS ExceptionCode,
- IN PKTRAP_FRAME TrapFrame)
+ IN NTSTATUS ExceptionCode,
+ IN PKTRAP_FRAME TrapFrame)
{
- ULONG i;
- ASSERT(ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT);
+ ULONG i;
+ ASSERT(ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT);
- if (ExceptionCode == STATUS_BREAKPOINT) /* Software interrupt */
- {
- ULONG_PTR BpEip = (ULONG_PTR)TrapFrame->Eip - 1; /* Get EIP of INT3 instruction */
- for (i = 0; i < KdbSwBreakPointCount; i++)
- {
- ASSERT((KdbSwBreakPoints[i]->Type == KdbBreakPointSoftware ||
- KdbSwBreakPoints[i]->Type == KdbBreakPointTemporary));
- ASSERT(KdbSwBreakPoints[i]->Enabled);
- if (KdbSwBreakPoints[i]->Address == BpEip)
- {
- return KdbSwBreakPoints[i] - KdbBreakPoints;
- }
- }
- }
- else if (ExceptionCode == STATUS_SINGLE_STEP) /* Hardware interrupt */
- {
- UCHAR DebugReg;
- for (i = 0; i < KdbHwBreakPointCount; i++)
- {
- ASSERT(KdbHwBreakPoints[i]->Type == KdbBreakPointHardware &&
- KdbHwBreakPoints[i]->Enabled);
- DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
- if ((TrapFrame->Dr6 & (1 << DebugReg)) != 0)
- {
- return KdbHwBreakPoints[i] - KdbBreakPoints;
- }
- }
- }
+ if (ExceptionCode == STATUS_BREAKPOINT) /* Software interrupt */
+ {
+ ULONG_PTR BpEip = (ULONG_PTR)TrapFrame->Eip - 1; /* Get EIP of INT3 instruction */
+ for (i = 0; i < KdbSwBreakPointCount; i++)
+ {
+ ASSERT((KdbSwBreakPoints[i]->Type == KdbBreakPointSoftware ||
+ KdbSwBreakPoints[i]->Type == KdbBreakPointTemporary));
+ ASSERT(KdbSwBreakPoints[i]->Enabled);
+
+ if (KdbSwBreakPoints[i]->Address == BpEip)
+ {
+ return KdbSwBreakPoints[i] - KdbBreakPoints;
+ }
+ }
+ }
+ else if (ExceptionCode == STATUS_SINGLE_STEP) /* Hardware interrupt */
+ {
+ UCHAR DebugReg;
+
+ for (i = 0; i < KdbHwBreakPointCount; i++)
+ {
+ ASSERT(KdbHwBreakPoints[i]->Type == KdbBreakPointHardware &&
+ KdbHwBreakPoints[i]->Enabled);
+ DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
+
+ if ((TrapFrame->Dr6 & (1 << DebugReg)) != 0)
+ {
+ return KdbHwBreakPoints[i] - KdbBreakPoints;
+ }
+ }
+ }
- return -1;
+ return -1;
}
/*!\brief Enables a breakpoint.
*/
BOOLEAN
KdbpEnableBreakPoint(
- IN LONG BreakPointNr OPTIONAL,
- IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
+ IN LONG BreakPointNr OPTIONAL,
+ IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
{
- NTSTATUS Status;
- INT i;
- ULONG ul;
+ NTSTATUS Status;
+ INT i;
+ ULONG ul;
- if (BreakPointNr < 0)
- {
- ASSERT(BreakPoint != NULL);
- BreakPointNr = BreakPoint - KdbBreakPoints;
- }
- if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
- {
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
- return FALSE;
- }
- if (BreakPoint == NULL)
- {
- BreakPoint = KdbBreakPoints + BreakPointNr;
- }
- if (BreakPoint->Type == KdbBreakPointNone)
- {
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
- return FALSE;
- }
+ if (BreakPointNr < 0)
+ {
+ ASSERT(BreakPoint);
+ BreakPointNr = BreakPoint - KdbBreakPoints;
+ }
- if (BreakPoint->Enabled == TRUE)
- {
- KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr);
- return TRUE;
- }
+ if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
+ {
+ KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ return FALSE;
+ }
- if (BreakPoint->Type == KdbBreakPointSoftware ||
- BreakPoint->Type == KdbBreakPointTemporary)
- {
- if (KdbSwBreakPointCount >= KDB_MAXIMUM_SW_BREAKPOINT_COUNT)
- {
- KdbpPrint("Maximum number of SW breakpoints (%d) used. "
- "Disable another breakpoint in order to enable this one.\n",
- KDB_MAXIMUM_SW_BREAKPOINT_COUNT);
- return FALSE;
- }
- Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
- 0xCC, &BreakPoint->Data.SavedInstruction);
- if (!NT_SUCCESS(Status))
- {
- KdbpPrint("Couldn't access memory at 0x%p\n", BreakPoint->Address);
- return FALSE;
- }
- KdbSwBreakPoints[KdbSwBreakPointCount++] = BreakPoint;
- }
- else
- {
- if (BreakPoint->Data.Hw.AccessType == KdbAccessExec)
- ASSERT(BreakPoint->Data.Hw.Size == 1);
- ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0);
- if (KdbHwBreakPointCount >= KDB_MAXIMUM_HW_BREAKPOINT_COUNT)
- {
- KdbpPrint("Maximum number of HW breakpoints (%d) already used. "
- "Disable another breakpoint in order to enable this one.\n",
- KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
- return FALSE;
- }
-
- /* Find unused hw breakpoint */
- ASSERT(KDB_MAXIMUM_HW_BREAKPOINT_COUNT == 4);
- for (i = 0; i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT; i++)
- {
- if ((KdbTrapFrame.Tf.Dr7 & (0x3 << (i * 2))) == 0)
- break;
- }
- ASSERT(i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
-
- /* Set the breakpoint address. */
- switch (i)
- {
- case 0:
- KdbTrapFrame.Tf.Dr0 = BreakPoint->Address;
- break;
- case 1:
- KdbTrapFrame.Tf.Dr1 = BreakPoint->Address;
- break;
- case 2:
- KdbTrapFrame.Tf.Dr2 = BreakPoint->Address;
- break;
- case 3:
- KdbTrapFrame.Tf.Dr3 = BreakPoint->Address;
- break;
- }
-
- /* Enable the global breakpoint */
- KdbTrapFrame.Tf.Dr7 |= (0x2 << (i * 2));
-
- /* Enable the exact match bits. */
- KdbTrapFrame.Tf.Dr7 |= 0x00000300;
-
- /* Clear existing state. */
- KdbTrapFrame.Tf.Dr7 &= ~(0xF << (16 + (i * 4)));
-
- /* Set the breakpoint type. */
- switch (BreakPoint->Data.Hw.AccessType)
- {
- case KdbAccessExec:
- ul = 0;
- break;
- case KdbAccessWrite:
- ul = 1;
- break;
- case KdbAccessRead:
- case KdbAccessReadWrite:
- ul = 3;
- break;
- default:
- ASSERT(0);
- return TRUE;
- break;
- }
- KdbTrapFrame.Tf.Dr7 |= (ul << (16 + (i * 4)));
-
- /* Set the breakpoint length. */
- KdbTrapFrame.Tf.Dr7 |= ((BreakPoint->Data.Hw.Size - 1) << (18 + (i * 4)));
-
- /* Update KdbCurrentTrapFrame - values are taken from there by the CLI */
- if (&KdbTrapFrame != KdbCurrentTrapFrame)
- {
- KdbCurrentTrapFrame->Tf.Dr0 = KdbTrapFrame.Tf.Dr0;
- KdbCurrentTrapFrame->Tf.Dr1 = KdbTrapFrame.Tf.Dr1;
- KdbCurrentTrapFrame->Tf.Dr2 = KdbTrapFrame.Tf.Dr2;
- KdbCurrentTrapFrame->Tf.Dr3 = KdbTrapFrame.Tf.Dr3;
- KdbCurrentTrapFrame->Tf.Dr6 = KdbTrapFrame.Tf.Dr6;
- KdbCurrentTrapFrame->Tf.Dr7 = KdbTrapFrame.Tf.Dr7;
- }
-
- BreakPoint->Data.Hw.DebugReg = i;
- KdbHwBreakPoints[KdbHwBreakPointCount++] = BreakPoint;
- }
+ if (!BreakPoint)
+ {
+ BreakPoint = KdbBreakPoints + BreakPointNr;
+ }
+
+ if (BreakPoint->Type == KdbBreakPointNone)
+ {
+ KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ return FALSE;
+ }
+
+ if (BreakPoint->Enabled)
+ {
+ KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr);
+ return TRUE;
+ }
+
+ if (BreakPoint->Type == KdbBreakPointSoftware ||
+ BreakPoint->Type == KdbBreakPointTemporary)
+ {
+ if (KdbSwBreakPointCount >= KDB_MAXIMUM_SW_BREAKPOINT_COUNT)
+ {
+ KdbpPrint("Maximum number of SW breakpoints (%d) used. "
+ "Disable another breakpoint in order to enable this one.\n",
+ KDB_MAXIMUM_SW_BREAKPOINT_COUNT);
+ return FALSE;
+ }
+
+ Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
+ 0xCC, &BreakPoint->Data.SavedInstruction);
+ if (!NT_SUCCESS(Status))
+ {
+ KdbpPrint("Couldn't access memory at 0x%p\n", BreakPoint->Address);
+ return FALSE;
+ }
+
+ KdbSwBreakPoints[KdbSwBreakPointCount++] = BreakPoint;
+ }
+ else
+ {
+ if (BreakPoint->Data.Hw.AccessType == KdbAccessExec)
+ ASSERT(BreakPoint->Data.Hw.Size == 1);
+
+ ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0);
+
+ if (KdbHwBreakPointCount >= KDB_MAXIMUM_HW_BREAKPOINT_COUNT)
+ {
+ KdbpPrint("Maximum number of HW breakpoints (%d) already used. "
+ "Disable another breakpoint in order to enable this one.\n",
+ KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
+
+ return FALSE;
+ }
+
+ /* Find unused hw breakpoint */
+ ASSERT(KDB_MAXIMUM_HW_BREAKPOINT_COUNT == 4);
+ for (i = 0; i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT; i++)
+ {
+ if ((KdbTrapFrame.Tf.Dr7 & (0x3 << (i * 2))) == 0)
+ break;
+ }
+
+ ASSERT(i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
+
+ /* Set the breakpoint address. */
+ switch (i)
+ {
+ case 0:
+ KdbTrapFrame.Tf.Dr0 = BreakPoint->Address;
+ break;
+ case 1:
+ KdbTrapFrame.Tf.Dr1 = BreakPoint->Address;
+ break;
+ case 2:
+ KdbTrapFrame.Tf.Dr2 = BreakPoint->Address;
+ break;
+ case 3:
+ KdbTrapFrame.Tf.Dr3 = BreakPoint->Address;
+ break;
+ }
+
+ /* Enable the global breakpoint */
+ KdbTrapFrame.Tf.Dr7 |= (0x2 << (i * 2));
+
+ /* Enable the exact match bits. */
+ KdbTrapFrame.Tf.Dr7 |= 0x00000300;
+
+ /* Clear existing state. */
+ KdbTrapFrame.Tf.Dr7 &= ~(0xF << (16 + (i * 4)));
+
+ /* Set the breakpoint type. */
+ switch (BreakPoint->Data.Hw.AccessType)
+ {
+ case KdbAccessExec:
+ ul = 0;
+ break;
+ case KdbAccessWrite:
+ ul = 1;
+ break;
+ case KdbAccessRead:
+ case KdbAccessReadWrite:
+ ul = 3;
+ break;
+ default:
+ ASSERT(0);
+ return TRUE;
+ break;
+ }
+
+ KdbTrapFrame.Tf.Dr7 |= (ul << (16 + (i * 4)));
+
+ /* Set the breakpoint length. */
+ KdbTrapFrame.Tf.Dr7 |= ((BreakPoint->Data.Hw.Size - 1) << (18 + (i * 4)));
+
+ /* Update KdbCurrentTrapFrame - values are taken from there by the CLI */
+ if (&KdbTrapFrame != KdbCurrentTrapFrame)
+ {
+ KdbCurrentTrapFrame->Tf.Dr0 = KdbTrapFrame.Tf.Dr0;
+ KdbCurrentTrapFrame->Tf.Dr1 = KdbTrapFrame.Tf.Dr1;
+ KdbCurrentTrapFrame->Tf.Dr2 = KdbTrapFrame.Tf.Dr2;
+ KdbCurrentTrapFrame->Tf.Dr3 = KdbTrapFrame.Tf.Dr3;
+ KdbCurrentTrapFrame->Tf.Dr6 = KdbTrapFrame.Tf.Dr6;
+ KdbCurrentTrapFrame->Tf.Dr7 = KdbTrapFrame.Tf.Dr7;
+ }
- BreakPoint->Enabled = TRUE;
- if (BreakPoint->Type != KdbBreakPointTemporary)
- KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr);
- return TRUE;
+ BreakPoint->Data.Hw.DebugReg = i;
+ KdbHwBreakPoints[KdbHwBreakPointCount++] = BreakPoint;
+ }
+
+ BreakPoint->Enabled = TRUE;
+ if (BreakPoint->Type != KdbBreakPointTemporary)
+ KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr);
+
+ return TRUE;
}
/*!\brief Disables a breakpoint.
*/
BOOLEAN
KdbpDisableBreakPoint(
- IN LONG BreakPointNr OPTIONAL,
- IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
+ IN LONG BreakPointNr OPTIONAL,
+ IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
{
- ULONG i;
- NTSTATUS Status;
+ ULONG i;
+ NTSTATUS Status;
- if (BreakPointNr < 0)
- {
- ASSERT(BreakPoint != NULL);
- BreakPointNr = BreakPoint - KdbBreakPoints;
- }
- if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
- {
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
- return FALSE;
- }
- if (BreakPoint == NULL)
- {
- BreakPoint = KdbBreakPoints + BreakPointNr;
- }
- if (BreakPoint->Type == KdbBreakPointNone)
- {
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
- return FALSE;
- }
+ if (BreakPointNr < 0)
+ {
+ ASSERT(BreakPoint);
+ BreakPointNr = BreakPoint - KdbBreakPoints;
+ }
- if (BreakPoint->Enabled == FALSE)
- {
- KdbpPrint("Breakpoint %d is not enabled.\n", BreakPointNr);
- return TRUE;
- }
+ if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
+ {
+ KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ return FALSE;
+ }
- if (BreakPoint->Type == KdbBreakPointSoftware ||
- BreakPoint->Type == KdbBreakPointTemporary)
- {
- ASSERT(KdbSwBreakPointCount > 0);
- Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
- BreakPoint->Data.SavedInstruction, NULL);
- if (!NT_SUCCESS(Status))
- {
- KdbpPrint("Couldn't restore original instruction.\n");
- return FALSE;
- }
-
- for (i = 0; i < KdbSwBreakPointCount; i++)
- {
- if (KdbSwBreakPoints[i] == BreakPoint)
- {
- KdbSwBreakPoints[i] = KdbSwBreakPoints[--KdbSwBreakPointCount];
- i = -1; /* if the last breakpoint is disabled dont break with i >= KdbSwBreakPointCount */
- break;
- }
- }
- if (i != (ULONG)-1) /* not found */
- ASSERT(0);
- }
- else
- {
- ASSERT(BreakPoint->Type == KdbBreakPointHardware);
-
- /* Clear the breakpoint. */
- KdbTrapFrame.Tf.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
- if ((KdbTrapFrame.Tf.Dr7 & 0xFF) == 0)
- {
- /*
- * If no breakpoints are enabled then clear the exact match flags.
- */
- KdbTrapFrame.Tf.Dr7 &= 0xFFFFFCFF;
- }
-
- for (i = 0; i < KdbHwBreakPointCount; i++)
- {
- if (KdbHwBreakPoints[i] == BreakPoint)
- {
- KdbHwBreakPoints[i] = KdbHwBreakPoints[--KdbHwBreakPointCount];
- i = -1; /* if the last breakpoint is disabled dont break with i >= KdbHwBreakPointCount */
- break;
- }
- }
- if (i != (ULONG)-1) /* not found */
- ASSERT(0);
- }
+ if (!BreakPoint)
+ {
+ BreakPoint = KdbBreakPoints + BreakPointNr;
+ }
+
+ if (BreakPoint->Type == KdbBreakPointNone)
+ {
+ KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ return FALSE;
+ }
+
+ if (BreakPoint->Enabled == FALSE)
+ {
+ KdbpPrint("Breakpoint %d is not enabled.\n", BreakPointNr);
+ return TRUE;
+ }
- BreakPoint->Enabled = FALSE;
- if (BreakPoint->Type != KdbBreakPointTemporary)
- KdbpPrint("Breakpoint %d disabled.\n", BreakPointNr);
- return TRUE;
+ if (BreakPoint->Type == KdbBreakPointSoftware ||
+ BreakPoint->Type == KdbBreakPointTemporary)
+ {
+ ASSERT(KdbSwBreakPointCount > 0);
+ Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
+ BreakPoint->Data.SavedInstruction, NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ KdbpPrint("Couldn't restore original instruction.\n");
+ return FALSE;
+ }
+
+ for (i = 0; i < KdbSwBreakPointCount; i++)
+ {
+ if (KdbSwBreakPoints[i] == BreakPoint)
+ {
+ KdbSwBreakPoints[i] = KdbSwBreakPoints[--KdbSwBreakPointCount];
+ i = -1; /* if the last breakpoint is disabled dont break with i >= KdbSwBreakPointCount */
+ break;
+ }
+ }
+
+ if (i != (ULONG)-1) /* not found */
+ ASSERT(0);
+ }
+ else
+ {
+ ASSERT(BreakPoint->Type == KdbBreakPointHardware);
+
+ /* Clear the breakpoint. */
+ KdbTrapFrame.Tf.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
+ if ((KdbTrapFrame.Tf.Dr7 & 0xFF) == 0)
+ {
+ /* If no breakpoints are enabled then clear the exact match flags. */
+ KdbTrapFrame.Tf.Dr7 &= 0xFFFFFCFF;
+ }
+
+ for (i = 0; i < KdbHwBreakPointCount; i++)
+ {
+ if (KdbHwBreakPoints[i] == BreakPoint)
+ {
+ KdbHwBreakPoints[i] = KdbHwBreakPoints[--KdbHwBreakPointCount];
+ i = -1; /* if the last breakpoint is disabled dont break with i >= KdbHwBreakPointCount */
+ break;
+ }
+ }
+
+ if (i != (ULONG)-1) /* not found */
+ ASSERT(0);
+ }
+
+ BreakPoint->Enabled = FALSE;
+ if (BreakPoint->Type != KdbBreakPointTemporary)
+ KdbpPrint("Breakpoint %d disabled.\n", BreakPointNr);
+
+ return TRUE;
}
/*!\brief Gets the first or last chance enter-condition for exception nr. \a ExceptionNr
*/
BOOLEAN
KdbpGetEnterCondition(
- IN LONG ExceptionNr,
- IN BOOLEAN FirstChance,
- OUT KDB_ENTER_CONDITION *Condition)
+ IN LONG ExceptionNr,
+ IN BOOLEAN FirstChance,
+ OUT KDB_ENTER_CONDITION *Condition)
{
- if (ExceptionNr >= (LONG)RTL_NUMBER_OF(KdbEnterConditions))
- return FALSE;
+ if (ExceptionNr >= (LONG)RTL_NUMBER_OF(KdbEnterConditions))
+ return FALSE;
- *Condition = KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1];
- return TRUE;
+ *Condition = KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1];
+ return TRUE;
}
/*!\brief Sets the first or last chance enter-condition for exception nr. \a ExceptionNr
*/
BOOLEAN
KdbpSetEnterCondition(
- IN LONG ExceptionNr,
- IN BOOLEAN FirstChance,
- IN KDB_ENTER_CONDITION Condition)
+ IN LONG ExceptionNr,
+ IN BOOLEAN FirstChance,
+ IN KDB_ENTER_CONDITION Condition)
{
- if (ExceptionNr < 0)
- {
- for (ExceptionNr = 0; ExceptionNr < (LONG)RTL_NUMBER_OF(KdbEnterConditions); ExceptionNr++)
- {
- if (ExceptionNr == 1 || ExceptionNr == 8 ||
- ExceptionNr == 9 || ExceptionNr == 15) /* Reserved exceptions */
- {
- continue;
- }
- KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
- }
- }
- else
- {
- if (ExceptionNr >= (LONG)RTL_NUMBER_OF(KdbEnterConditions) ||
- ExceptionNr == 1 || ExceptionNr == 8 || /* Do not allow changing of the debug */
- ExceptionNr == 9 || ExceptionNr == 15) /* trap or reserved exceptions */
- {
- return FALSE;
- }
- KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
- }
- return TRUE;
+ if (ExceptionNr < 0)
+ {
+ for (ExceptionNr = 0; ExceptionNr < (LONG)RTL_NUMBER_OF(KdbEnterConditions); ExceptionNr++)
+ {
+ if (ExceptionNr == 1 || ExceptionNr == 8 ||
+ ExceptionNr == 9 || ExceptionNr == 15) /* Reserved exceptions */
+ {
+ continue;
+ }
+
+ KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
+ }
+ }
+ else
+ {
+ if (ExceptionNr >= (LONG)RTL_NUMBER_OF(KdbEnterConditions) ||
+ ExceptionNr == 1 || ExceptionNr == 8 || /* Do not allow changing of the debug */
+ ExceptionNr == 9 || ExceptionNr == 15) /* trap or reserved exceptions */
+ {
+ return FALSE;
+ }
+
+ KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
+ }
+
+ return TRUE;
}
/*!\brief Switches to another thread context
*/
BOOLEAN
KdbpAttachToThread(
- PVOID ThreadId)
+ PVOID ThreadId)
{
- PETHREAD Thread = NULL;
- PEPROCESS Process;
+ PETHREAD Thread = NULL;
+ PEPROCESS Process;
- /* Get a pointer to the thread */
- if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &Thread)))
- {
- KdbpPrint("Invalid thread id: 0x%08x\n", (ULONG)ThreadId);
- return FALSE;
- }
- Process = Thread->ThreadsProcess;
+ /* Get a pointer to the thread */
+ if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &Thread)))
+ {
+ KdbpPrint("Invalid thread id: 0x%08x\n", (ULONG)ThreadId);
+ return FALSE;
+ }
+ Process = Thread->ThreadsProcess;
- if (KeIsExecutingDpc() && Process != KdbCurrentProcess)
- {
- KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
- ObDereferenceObject(Thread);
- return FALSE;
- }
+ if (KeIsExecutingDpc() && Process != KdbCurrentProcess)
+ {
+ KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
+ ObDereferenceObject(Thread);
+ return FALSE;
+ }
- /* Save the current thread's context (if we previously attached to a thread) */
- if (KdbCurrentThread != KdbOriginalThread)
- {
- ASSERT(KdbCurrentTrapFrame == &KdbThreadTrapFrame);
- /* Actually, we can't save the context, there's no guarantee that there
- * was a trap frame */
- }
- else
- {
- ASSERT(KdbCurrentTrapFrame == &KdbTrapFrame);
- }
+ /* Save the current thread's context (if we previously attached to a thread) */
+ if (KdbCurrentThread != KdbOriginalThread)
+ {
+ ASSERT(KdbCurrentTrapFrame == &KdbThreadTrapFrame);
+ /* Actually, we can't save the context, there's no guarantee that there was a trap frame */
+ }
+ else
+ {
+ ASSERT(KdbCurrentTrapFrame == &KdbTrapFrame);
+ }
- /* Switch to the thread's context */
- if (Thread != KdbOriginalThread)
- {
- /* The thread we're attaching to isn't the thread on which we entered
- * kdb and so the thread we're attaching to is not running. There
- * is no guarantee that it actually has a trap frame. So we have to
- * peek directly at the registers which were saved on the stack when the
- * thread was preempted in the scheduler */
- KdbpKdbTrapFrameFromKernelStack(Thread->Tcb.KernelStack,
- &KdbThreadTrapFrame);
- KdbCurrentTrapFrame = &KdbThreadTrapFrame;
- }
- else /* Switching back to original thread */
- {
- KdbCurrentTrapFrame = &KdbTrapFrame;
- }
- KdbCurrentThread = Thread;
+ /* Switch to the thread's context */
+ if (Thread != KdbOriginalThread)
+ {
+ /* The thread we're attaching to isn't the thread on which we entered
+ * kdb and so the thread we're attaching to is not running. There
+ * is no guarantee that it actually has a trap frame. So we have to
+ * peek directly at the registers which were saved on the stack when the
+ * thread was preempted in the scheduler */
+ KdbpKdbTrapFrameFromKernelStack(Thread->Tcb.KernelStack,
+ &KdbThreadTrapFrame);
+ KdbCurrentTrapFrame = &KdbThreadTrapFrame;
+ }
+ else /* Switching back to original thread */
+ {
+ KdbCurrentTrapFrame = &KdbTrapFrame;
+ }
+ KdbCurrentThread = Thread;
- /* Attach to the thread's process */
- ASSERT(KdbCurrentProcess == PsGetCurrentProcess());
- if (KdbCurrentProcess != Process)
- {
- if (KdbCurrentProcess != KdbOriginalProcess) /* detach from previously attached process */
- {
- KeUnstackDetachProcess(&KdbApcState);
- }
- if (KdbOriginalProcess != Process)
- {
- KeStackAttachProcess(&Process->Pcb, &KdbApcState);
- }
- KdbCurrentProcess = Process;
- }
+ /* Attach to the thread's process */
+ ASSERT(KdbCurrentProcess == PsGetCurrentProcess());
+ if (KdbCurrentProcess != Process)
+ {
+ if (KdbCurrentProcess != KdbOriginalProcess) /* detach from previously attached process */
+ {
+ KeUnstackDetachProcess(&KdbApcState);
+ }
+
+ if (KdbOriginalProcess != Process)
+ {
+ KeStackAttachProcess(&Process->Pcb, &KdbApcState);
+ }
+
+ KdbCurrentProcess = Process;
+ }
- ObDereferenceObject(Thread);
- return TRUE;
+ ObDereferenceObject(Thread);
+ return TRUE;
}
/*!\brief Switches to another process/thread context
*/
BOOLEAN
KdbpAttachToProcess(
- PVOID ProcessId)
+ PVOID ProcessId)
{
- PEPROCESS Process = NULL;
- PETHREAD Thread;
- PLIST_ENTRY Entry;
+ PEPROCESS Process = NULL;
+ PETHREAD Thread;
+ PLIST_ENTRY Entry;
- /* Get a pointer to the process */
- if (!NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)))
- {
- KdbpPrint("Invalid process id: 0x%08x\n", (ULONG)ProcessId);
- return FALSE;
- }
+ /* Get a pointer to the process */
+ if (!NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)))
+ {
+ KdbpPrint("Invalid process id: 0x%08x\n", (ULONG)ProcessId);
+ return FALSE;
+ }
- Entry = Process->ThreadListHead.Flink;
- ObDereferenceObject(Process);
- if (Entry == &KdbCurrentProcess->ThreadListHead)
- {
- KdbpPrint("No threads in process 0x%08x, cannot attach to process!\n", (ULONG)ProcessId);
- return FALSE;
- }
+ Entry = Process->ThreadListHead.Flink;
+ ObDereferenceObject(Process);
+ if (Entry == &KdbCurrentProcess->ThreadListHead)
+ {
+ KdbpPrint("No threads in process 0x%08x, cannot attach to process!\n", (ULONG)ProcessId);
+ return FALSE;
+ }
- Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
+ Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
- return KdbpAttachToThread(Thread->Cid.UniqueThread);
+ return KdbpAttachToThread(Thread->Cid.UniqueThread);
}
/*!\brief Calls the main loop ...
*/
static VOID
-KdbpCallMainLoop(VOID)
+KdbpCallMainLoop()
{
- KdbpCliMainLoop(KdbEnteredOnSingleStep);
+ KdbpCliMainLoop(KdbEnteredOnSingleStep);
}
/*!\brief Internal function to enter KDB.
static VOID
KdbpInternalEnter()
{
- PETHREAD Thread;
- PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
- ULONG SavedStackLimit;
+ PETHREAD Thread;
+ PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
+ ULONG SavedStackLimit;
- KbdDisableMouse();
- if (KdpDebugMode.Screen)
- {
- InbvAcquireDisplayOwnership();
- }
+ KbdDisableMouse();
+ if (KdpDebugMode.Screen)
+ {
+ InbvAcquireDisplayOwnership();
+ }
- /* Call the interface's main loop on a different stack */
- Thread = PsGetCurrentThread();
- SavedInitialStack = Thread->Tcb.InitialStack;
- SavedStackBase = Thread->Tcb.StackBase;
- SavedStackLimit = Thread->Tcb.StackLimit;
- SavedKernelStack = Thread->Tcb.KernelStack;
- Thread->Tcb.InitialStack = Thread->Tcb.StackBase = (char*)KdbStack + KDB_STACK_SIZE;
- Thread->Tcb.StackLimit = (ULONG)KdbStack;
- Thread->Tcb.KernelStack = (char*)KdbStack + KDB_STACK_SIZE;
-
- /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);*/
-
- KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - sizeof(ULONG), KdbpCallMainLoop);
-
- Thread->Tcb.InitialStack = SavedInitialStack;
- Thread->Tcb.StackBase = SavedStackBase;
- Thread->Tcb.StackLimit = SavedStackLimit;
- Thread->Tcb.KernelStack = SavedKernelStack;
- KbdEnableMouse();
+ /* Call the interface's main loop on a different stack */
+ Thread = PsGetCurrentThread();
+ SavedInitialStack = Thread->Tcb.InitialStack;
+ SavedStackBase = Thread->Tcb.StackBase;
+ SavedStackLimit = Thread->Tcb.StackLimit;
+ SavedKernelStack = Thread->Tcb.KernelStack;
+ Thread->Tcb.InitialStack = Thread->Tcb.StackBase = (char*)KdbStack + KDB_STACK_SIZE;
+ Thread->Tcb.StackLimit = (ULONG)KdbStack;
+ Thread->Tcb.KernelStack = (char*)KdbStack + KDB_STACK_SIZE;
+
+ /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);*/
+
+ KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - sizeof(ULONG), KdbpCallMainLoop);
+
+ Thread->Tcb.InitialStack = SavedInitialStack;
+ Thread->Tcb.StackBase = SavedStackBase;
+ Thread->Tcb.StackLimit = SavedStackLimit;
+ Thread->Tcb.KernelStack = SavedKernelStack;
+ KbdEnableMouse();
}
static ULONG
-KdbpGetExceptionNumberFromStatus(IN NTSTATUS ExceptionCode)
+KdbpGetExceptionNumberFromStatus(
+ IN NTSTATUS ExceptionCode)
{
ULONG Ret;
*/
KD_CONTINUE_TYPE
KdbEnterDebuggerException(
- IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
- IN KPROCESSOR_MODE PreviousMode,
- IN PCONTEXT Context,
- IN OUT PKTRAP_FRAME TrapFrame,
- IN BOOLEAN FirstChance)
+ IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN PCONTEXT Context,
+ IN OUT PKTRAP_FRAME TrapFrame,
+ IN BOOLEAN FirstChance)
{
- KDB_ENTER_CONDITION EnterCondition;
- KD_CONTINUE_TYPE ContinueType = kdHandleException;
- PKDB_BREAKPOINT BreakPoint;
- ULONG ExpNr;
- ULONGLONG ull;
- BOOLEAN Resume = FALSE;
- BOOLEAN EnterConditionMet = TRUE;
- ULONG OldEflags;
- NTSTATUS ExceptionCode;
-
- ExceptionCode = (ExceptionRecord != NULL ? ExceptionRecord->ExceptionCode : STATUS_BREAKPOINT);
-
- KdbCurrentProcess = PsGetCurrentProcess();
-
- /* Set continue type to kdContinue for single steps and breakpoints */
- if (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT)
- ContinueType = kdContinue;
-
- /* Check if we should handle the exception. */
- /* FIXME - won't get all exceptions here :( */
- ExpNr = KdbpGetExceptionNumberFromStatus(ExceptionCode);
- EnterCondition = KdbEnterConditions[ExpNr][FirstChance ? 0 : 1];
- if (EnterCondition == KdbDoNotEnter ||
- (EnterCondition == KdbEnterFromUmode && PreviousMode == KernelMode) ||
- (EnterCondition == KdbEnterFromKmode && PreviousMode != KernelMode))
- {
- EnterConditionMet = FALSE;
- }
+ KDB_ENTER_CONDITION EnterCondition;
+ KD_CONTINUE_TYPE ContinueType = kdHandleException;
+ PKDB_BREAKPOINT BreakPoint;
+ ULONG ExpNr;
+ ULONGLONG ull;
+ BOOLEAN Resume = FALSE;
+ BOOLEAN EnterConditionMet = TRUE;
+ ULONG OldEflags;
+ NTSTATUS ExceptionCode;
+
+ ExceptionCode = (ExceptionRecord ? ExceptionRecord->ExceptionCode : STATUS_BREAKPOINT);
+
+ KdbCurrentProcess = PsGetCurrentProcess();
+
+ /* Set continue type to kdContinue for single steps and breakpoints */
+ if (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT)
+ ContinueType = kdContinue;
+
+ /* Check if we should handle the exception. */
+ /* FIXME - won't get all exceptions here :( */
+ ExpNr = KdbpGetExceptionNumberFromStatus(ExceptionCode);
+ EnterCondition = KdbEnterConditions[ExpNr][FirstChance ? 0 : 1];
+ if (EnterCondition == KdbDoNotEnter ||
+ (EnterCondition == KdbEnterFromUmode && PreviousMode == KernelMode) ||
+ (EnterCondition == KdbEnterFromKmode && PreviousMode != KernelMode))
+ {
+ EnterConditionMet = FALSE;
+ }
- /* If we stopped on one of our breakpoints then let the user know. */
- KdbLastBreakPointNr = -1;
- KdbEnteredOnSingleStep = FALSE;
+ /* If we stopped on one of our breakpoints then let the user know. */
+ KdbLastBreakPointNr = -1;
+ KdbEnteredOnSingleStep = FALSE;
- if (FirstChance && (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT) &&
- (KdbLastBreakPointNr = KdbpIsBreakPointOurs(ExceptionCode, TrapFrame)) >= 0)
- {
- BreakPoint = KdbBreakPoints + KdbLastBreakPointNr;
-
- if (ExceptionCode == STATUS_BREAKPOINT)
- {
- /*
- * ... and restore the original instruction.
- */
- if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address,
- BreakPoint->Data.SavedInstruction, NULL)))
- {
- KdbpPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
- KeBugCheck(0); // FIXME: Proper bugcode!
- }
- }
-
- if ((BreakPoint->Type == KdbBreakPointHardware) &&
- (BreakPoint->Data.Hw.AccessType == KdbAccessExec))
- {
- Resume = TRUE; /* Set the resume flag when continuing execution */
- }
-
- /*
- * When a temporary breakpoint is hit we have to make sure that we are
- * in the same context in which it was set, otherwise it could happen
- * that another process/thread hits it before and it gets deleted.
- */
- else if (BreakPoint->Type == KdbBreakPointTemporary &&
- BreakPoint->Process == KdbCurrentProcess)
- {
- ASSERT((TrapFrame->EFlags & EFLAGS_TF) == 0);
-
- /*
- * Delete the temporary breakpoint which was used to step over or into the instruction.
- */
- KdbpDeleteBreakPoint(-1, BreakPoint);
-
- if (--KdbNumSingleSteps > 0)
- {
- if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
- (!KdbSingleStepOver && !KdbpStepIntoInstruction(TrapFrame->Eip)))
+ if (FirstChance && (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT) &&
+ (KdbLastBreakPointNr = KdbpIsBreakPointOurs(ExceptionCode, TrapFrame)) >= 0)
+ {
+ BreakPoint = KdbBreakPoints + KdbLastBreakPointNr;
+
+ if (ExceptionCode == STATUS_BREAKPOINT)
+ {
+ /* ... and restore the original instruction. */
+ if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address,
+ BreakPoint->Data.SavedInstruction, NULL)))
{
- Context->EFlags |= EFLAGS_TF;
+ KdbpPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
+ KeBugCheck(0); // FIXME: Proper bugcode!
}
+ }
+
+ if ((BreakPoint->Type == KdbBreakPointHardware) &&
+ (BreakPoint->Data.Hw.AccessType == KdbAccessExec))
+ {
+ Resume = TRUE; /* Set the resume flag when continuing execution */
+ }
+
+ /*
+ * When a temporary breakpoint is hit we have to make sure that we are
+ * in the same context in which it was set, otherwise it could happen
+ * that another process/thread hits it before and it gets deleted.
+ */
+ else if (BreakPoint->Type == KdbBreakPointTemporary &&
+ BreakPoint->Process == KdbCurrentProcess)
+ {
+ ASSERT((TrapFrame->EFlags & EFLAGS_TF) == 0);
+
+ /* Delete the temporary breakpoint which was used to step over or into the instruction. */
+ KdbpDeleteBreakPoint(-1, BreakPoint);
+
+ if (--KdbNumSingleSteps > 0)
+ {
+ if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
+ (!KdbSingleStepOver && !KdbpStepIntoInstruction(TrapFrame->Eip)))
+ {
+ Context->EFlags |= EFLAGS_TF;
+ }
+
+ goto continue_execution; /* return */
+ }
+
+ KdbEnteredOnSingleStep = TRUE;
+ }
+
+ /*
+ * If we hit a breakpoint set by the debugger we set the single step flag,
+ * ignore the next single step and reenable the breakpoint.
+ */
+ else if (BreakPoint->Type == KdbBreakPointSoftware ||
+ BreakPoint->Type == KdbBreakPointTemporary)
+ {
+ ASSERT(ExceptionCode == STATUS_BREAKPOINT);
+ Context->EFlags |= EFLAGS_TF;
+ KdbBreakPointToReenable = BreakPoint;
+ }
+
+ /* Make sure that the breakpoint should be triggered in this context */
+ if (!BreakPoint->Global && BreakPoint->Process != KdbCurrentProcess)
+ {
goto continue_execution; /* return */
- }
-
- KdbEnteredOnSingleStep = TRUE;
- }
-
- /*
- * If we hit a breakpoint set by the debugger we set the single step flag,
- * ignore the next single step and reenable the breakpoint.
- */
- else if (BreakPoint->Type == KdbBreakPointSoftware ||
- BreakPoint->Type == KdbBreakPointTemporary)
- {
- ASSERT(ExceptionCode == STATUS_BREAKPOINT);
- Context->EFlags |= EFLAGS_TF;
- KdbBreakPointToReenable = BreakPoint;
- }
-
- /*
- * Make sure that the breakpoint should be triggered in this context
- */
- if (!BreakPoint->Global && BreakPoint->Process != KdbCurrentProcess)
- {
- goto continue_execution; /* return */
- }
-
- /*
- * Check if the condition for the breakpoint is met.
- */
- if (BreakPoint->Condition != NULL)
- {
- /* Setup the KDB trap frame */
- KdbpTrapFrameToKdbTrapFrame(TrapFrame, &KdbTrapFrame);
-
- ull = 0;
- if (!KdbpRpnEvaluateParsedExpression(BreakPoint->Condition, &KdbTrapFrame, &ull, NULL, NULL))
- {
- /* FIXME: Print warning? */
- }
- else if (ull == 0) /* condition is not met */
- {
+ }
+
+ /* Check if the condition for the breakpoint is met. */
+ if (BreakPoint->Condition)
+ {
+ /* Setup the KDB trap frame */
+ KdbpTrapFrameToKdbTrapFrame(TrapFrame, &KdbTrapFrame);
+
+ ull = 0;
+ if (!KdbpRpnEvaluateParsedExpression(BreakPoint->Condition, &KdbTrapFrame, &ull, NULL, NULL))
+ {
+ /* FIXME: Print warning? */
+ }
+ else if (ull == 0) /* condition is not met */
+ {
+ goto continue_execution; /* return */
+ }
+ }
+
+ if (BreakPoint->Type == KdbBreakPointSoftware)
+ {
+ KdbpPrint("Entered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
+ KdbLastBreakPointNr, TrapFrame->SegCs & 0xffff, TrapFrame->Eip);
+ }
+ else if (BreakPoint->Type == KdbBreakPointHardware)
+ {
+ KdbpPrint("Entered debugger on breakpoint #%d: %s 0x%08x\n",
+ KdbLastBreakPointNr,
+ (BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
+ ((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
+ ((BreakPoint->Data.Hw.AccessType == KdbAccessReadWrite) ? "RDWR" : "EXEC")),
+ BreakPoint->Address);
+ }
+ }
+ else if (ExceptionCode == STATUS_SINGLE_STEP)
+ {
+ /* Silently ignore a debugger initiated single step. */
+ if ((TrapFrame->Dr6 & 0xf) == 0 && KdbBreakPointToReenable)
+ {
+ /* FIXME: Make sure that the breakpoint was really hit (check bp->Address vs. tf->Eip) */
+ BreakPoint = KdbBreakPointToReenable;
+ KdbBreakPointToReenable = NULL;
+ ASSERT(BreakPoint->Type == KdbBreakPointSoftware ||
+ BreakPoint->Type == KdbBreakPointTemporary);
+
+ /*
+ * Reenable the breakpoint we disabled to execute the breakpointed
+ * instruction.
+ */
+ if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address, 0xCC,
+ &BreakPoint->Data.SavedInstruction)))
+ {
+ KdbpPrint("Warning: Couldn't reenable breakpoint %d\n",
+ BreakPoint - KdbBreakPoints);
+ }
+
+ /* Unset TF if we are no longer single stepping. */
+ if (KdbNumSingleSteps == 0)
+ Context->EFlags &= ~EFLAGS_TF;
+
goto continue_execution; /* return */
- }
- }
-
- if (BreakPoint->Type == KdbBreakPointSoftware)
- {
- KdbpPrint("Entered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
- KdbLastBreakPointNr, TrapFrame->SegCs & 0xffff, TrapFrame->Eip);
- }
- else if (BreakPoint->Type == KdbBreakPointHardware)
- {
- KdbpPrint("Entered debugger on breakpoint #%d: %s 0x%08x\n",
- KdbLastBreakPointNr,
- (BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
- ((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
- ((BreakPoint->Data.Hw.AccessType == KdbAccessReadWrite) ? "RDWR" : "EXEC")
- ),
- BreakPoint->Address
- );
-
- }
- }
- else if (ExceptionCode == STATUS_SINGLE_STEP)
- {
- /* Silently ignore a debugger initiated single step. */
- if ((TrapFrame->Dr6 & 0xf) == 0 && KdbBreakPointToReenable != NULL)
- {
- /* FIXME: Make sure that the breakpoint was really hit (check bp->Address vs. tf->Eip) */
- BreakPoint = KdbBreakPointToReenable;
- KdbBreakPointToReenable = NULL;
- ASSERT(BreakPoint->Type == KdbBreakPointSoftware ||
- BreakPoint->Type == KdbBreakPointTemporary);
-
- /*
- * Reenable the breakpoint we disabled to execute the breakpointed
- * instruction.
- */
- if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address, 0xCC,
- &BreakPoint->Data.SavedInstruction)))
- {
- KdbpPrint("Warning: Couldn't reenable breakpoint %d\n",
- BreakPoint - KdbBreakPoints);
- }
-
- /* Unset TF if we are no longer single stepping. */
- if (KdbNumSingleSteps == 0)
- Context->EFlags &= ~EFLAGS_TF;
- goto continue_execution; /* return */
- }
-
- /* Check if we expect a single step */
- if ((TrapFrame->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
- {
- /*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
- if (--KdbNumSingleSteps > 0)
- {
- if ((KdbSingleStepOver && KdbpStepOverInstruction(TrapFrame->Eip)) ||
- (!KdbSingleStepOver && KdbpStepIntoInstruction(TrapFrame->Eip)))
+ }
+
+ /* Check if we expect a single step */
+ if ((TrapFrame->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
+ {
+ /*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
+ if (--KdbNumSingleSteps > 0)
{
- Context->EFlags &= ~EFLAGS_TF;
+ if ((KdbSingleStepOver && KdbpStepOverInstruction(TrapFrame->Eip)) ||
+ (!KdbSingleStepOver && KdbpStepIntoInstruction(TrapFrame->Eip)))
+ {
+ Context->EFlags &= ~EFLAGS_TF;
+ }
+ else
+ {
+ Context->EFlags |= EFLAGS_TF;
+ }
+
+ goto continue_execution; /* return */
}
else
{
- Context->EFlags |= EFLAGS_TF;
+ Context->EFlags &= ~EFLAGS_TF;
+ KdbEnteredOnSingleStep = TRUE;
}
- goto continue_execution; /* return */
- }
- else
- {
- Context->EFlags &= ~EFLAGS_TF;
- KdbEnteredOnSingleStep = TRUE;
- }
- }
- else
- {
- if (!EnterConditionMet)
- {
+ }
+ else
+ {
+ if (!EnterConditionMet)
+ {
+ return kdHandleException;
+ }
+
+ KdbpPrint("Entered debugger on unexpected debug trap!\n");
+ }
+ }
+ else if (ExceptionCode == STATUS_BREAKPOINT)
+ {
+ if (KdbInitFileBuffer)
+ {
+ KdbpCliInterpretInitFile();
+ EnterConditionMet = FALSE;
+ }
+ if (!EnterConditionMet)
+ {
return kdHandleException;
- }
- KdbpPrint("Entered debugger on unexpected debug trap!\n");
- }
- }
- else if (ExceptionCode == STATUS_BREAKPOINT)
- {
- if (KdbInitFileBuffer != NULL)
- {
- KdbpCliInterpretInitFile();
- EnterConditionMet = FALSE;
- }
- if (!EnterConditionMet)
- {
- return kdHandleException;
- }
-
- KdbpPrint("Entered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
- TrapFrame->SegCs & 0xffff, TrapFrame->Eip - 1);
- }
- else
- {
- const CHAR *ExceptionString = (ExpNr < RTL_NUMBER_OF(ExceptionNrToString)) ?
- (ExceptionNrToString[ExpNr]) :
- ("Unknown/User defined exception");
-
- if (!EnterConditionMet)
- {
- return ContinueType;
- }
-
- KdbpPrint("Entered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
- FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
- if (ExceptionCode == STATUS_ACCESS_VIOLATION &&
- ExceptionRecord != NULL && ExceptionRecord->NumberParameters != 0)
- {
- /* FIXME: Add noexec memory stuff */
- ULONG_PTR TrapCr2;
- ULONG Err;
+ }
+
+ KdbpPrint("Entered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
+ TrapFrame->SegCs & 0xffff, TrapFrame->Eip - 1);
+ }
+ else
+ {
+ const CHAR *ExceptionString = (ExpNr < RTL_NUMBER_OF(ExceptionNrToString)) ?
+ (ExceptionNrToString[ExpNr]) :
+ ("Unknown/User defined exception");
+
+ if (!EnterConditionMet)
+ {
+ return ContinueType;
+ }
+
+ KdbpPrint("Entered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
+ FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
+
+ if (ExceptionCode == STATUS_ACCESS_VIOLATION &&
+ ExceptionRecord && ExceptionRecord->NumberParameters != 0)
+ {
+ /* FIXME: Add noexec memory stuff */
+ ULONG_PTR TrapCr2;
+ ULONG Err;
+
#ifdef __GNUC__
- asm volatile("movl %%cr2, %0" : "=r"(TrapCr2));
+ asm volatile("movl %%cr2, %0" : "=r"(TrapCr2));
#elif _MSC_VER
- __asm mov eax, cr2;
- __asm mov TrapCr2, eax;
+ __asm mov eax, cr2;
+ __asm mov TrapCr2, eax;
#else
#error Unknown compiler for inline assembler
#endif
- Err = TrapFrame->ErrCode;
- KdbpPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
- if ((Err & (1 << 0)) == 0)
- KdbpPrint("Page not present.\n");
- else
- {
- if ((Err & (1 << 3)) != 0)
- KdbpPrint("Reserved bits in page directory set.\n");
+ Err = TrapFrame->ErrCode;
+ KdbpPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
+
+ if ((Err & (1 << 0)) == 0)
+ {
+ KdbpPrint("Page not present.\n");
+ }
else
- KdbpPrint("Page protection violation.\n");
- }
- }
- }
+ {
+ if ((Err & (1 << 3)) != 0)
+ KdbpPrint("Reserved bits in page directory set.\n");
+ else
+ KdbpPrint("Page protection violation.\n");
+ }
+ }
+ }
- /* Once we enter the debugger we do not expect any more single steps to happen */
- KdbNumSingleSteps = 0;
+ /* Once we enter the debugger we do not expect any more single steps to happen */
+ KdbNumSingleSteps = 0;
- /* Update the current process pointer */
- KdbCurrentProcess = KdbOriginalProcess = PsGetCurrentProcess();
- KdbCurrentThread = KdbOriginalThread = PsGetCurrentThread();
- KdbCurrentTrapFrame = &KdbTrapFrame;
+ /* Update the current process pointer */
+ KdbCurrentProcess = KdbOriginalProcess = PsGetCurrentProcess();
+ KdbCurrentThread = KdbOriginalThread = PsGetCurrentThread();
+ KdbCurrentTrapFrame = &KdbTrapFrame;
- /* Setup the KDB trap frame */
- KdbpTrapFrameToKdbTrapFrame(TrapFrame, &KdbTrapFrame);
+ /* Setup the KDB trap frame */
+ KdbpTrapFrameToKdbTrapFrame(TrapFrame, &KdbTrapFrame);
- /* Enter critical section */
- Ke386SaveFlags(OldEflags);
- _disable();
+ /* Enter critical section */
+ Ke386SaveFlags(OldEflags);
+ _disable();
- /* Exception inside the debugger? Game over. */
- if (InterlockedIncrement(&KdbEntryCount) > 1)
- {
- Ke386RestoreFlags(OldEflags);
- return kdHandleException;
- }
+ /* Exception inside the debugger? Game over. */
+ if (InterlockedIncrement(&KdbEntryCount) > 1)
+ {
+ Ke386RestoreFlags(OldEflags);
+ return kdHandleException;
+ }
- /* Call the main loop. */
- KdbpInternalEnter();
+ /* Call the main loop. */
+ KdbpInternalEnter();
- /* Check if we should single step */
- if (KdbNumSingleSteps > 0)
- {
- if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Tf.Eip)) ||
- (!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Tf.Eip)))
- {
- ASSERT((KdbCurrentTrapFrame->Tf.EFlags & EFLAGS_TF) == 0);
- /*KdbCurrentTrapFrame->Tf.EFlags &= ~EFLAGS_TF;*/
- }
- else
- {
- Context->EFlags |= EFLAGS_TF;
- }
- }
+ /* Check if we should single step */
+ if (KdbNumSingleSteps > 0)
+ {
+ if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Tf.Eip)) ||
+ (!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Tf.Eip)))
+ {
+ ASSERT((KdbCurrentTrapFrame->Tf.EFlags & EFLAGS_TF) == 0);
+ /*KdbCurrentTrapFrame->Tf.EFlags &= ~EFLAGS_TF;*/
+ }
+ else
+ {
+ Context->EFlags |= EFLAGS_TF;
+ }
+ }
- /* We can't update the current thread's trapframe 'cause it might not
- have one */
+ /* We can't update the current thread's trapframe 'cause it might not have one */
- /* Detach from attached process */
- if (KdbCurrentProcess != KdbOriginalProcess)
- {
- KeUnstackDetachProcess(&KdbApcState);
- }
+ /* Detach from attached process */
+ if (KdbCurrentProcess != KdbOriginalProcess)
+ {
+ KeUnstackDetachProcess(&KdbApcState);
+ }
- /* Update the exception TrapFrame */
- KdbpKdbTrapFrameToTrapFrame(&KdbTrapFrame, TrapFrame);
+ /* Update the exception TrapFrame */
+ KdbpKdbTrapFrameToTrapFrame(&KdbTrapFrame, TrapFrame);
- /* Decrement the entry count */
- InterlockedDecrement(&KdbEntryCount);
+ /* Decrement the entry count */
+ InterlockedDecrement(&KdbEntryCount);
- /* Leave critical section */
- Ke386RestoreFlags(OldEflags);
+ /* Leave critical section */
+ Ke386RestoreFlags(OldEflags);
- /* Check if user requested a bugcheck */
- if (KdbpBugCheckRequested)
- {
- /* Clear the flag and bugcheck the system */
- KdbpBugCheckRequested = FALSE;
- KeBugCheck(MANUALLY_INITIATED_CRASH);
- }
+ /* Check if user requested a bugcheck */
+ if (KdbpBugCheckRequested)
+ {
+ /* Clear the flag and bugcheck the system */
+ KdbpBugCheckRequested = FALSE;
+ KeBugCheck(MANUALLY_INITIATED_CRASH);
+ }
continue_execution:
- /* Clear debug status */
- if (ExceptionCode == STATUS_BREAKPOINT) /* FIXME: Why clear DR6 on INT3? */
- {
- /* Set the RF flag so we don't trigger the same breakpoint again. */
- if (Resume)
- {
- TrapFrame->EFlags |= EFLAGS_RF;
- }
+ /* Clear debug status */
+ if (ExceptionCode == STATUS_BREAKPOINT) /* FIXME: Why clear DR6 on INT3? */
+ {
+ /* Set the RF flag so we don't trigger the same breakpoint again. */
+ if (Resume)
+ {
+ TrapFrame->EFlags |= EFLAGS_RF;
+ }
- /* Clear dr6 status flags. */
- TrapFrame->Dr6 &= ~0x0000e00f;
+ /* Clear dr6 status flags. */
+ TrapFrame->Dr6 &= ~0x0000e00f;
- /* Skip the current instruction */
- Context->Eip++;
- }
+ /* Skip the current instruction */
+ Context->Eip++;
+ }
- return ContinueType;
+ return ContinueType;
}
VOID
-KdbDeleteProcessHook(IN PEPROCESS Process)
+KdbDeleteProcessHook(
+ IN PEPROCESS Process)
{
- KdbSymFreeProcessSymbols(Process);
+ KdbSymFreeProcessSymbols(Process);
- /* FIXME: Delete breakpoints for process */
+ /* FIXME: Delete breakpoints for process */
}
VOID
NTAPI
-KdbpGetCommandLineSettings(PCHAR p1)
+KdbpGetCommandLineSettings(
+ PCHAR p1)
{
PCHAR p2;
}
NTSTATUS
-KdbpSafeReadMemory(OUT PVOID Dest,
- IN PVOID Src,
- IN ULONG Bytes)
+KdbpSafeReadMemory(
+ OUT PVOID Dest,
+ IN PVOID Src,
+ IN ULONG Bytes)
{
BOOLEAN Result = TRUE;
switch (Bytes)
{
- case 1:
- case 2:
- case 4:
- case 8:
- Result = KdpSafeReadMemory((ULONG_PTR)Src, Bytes, Dest);
- break;
- default:
- {
- ULONG_PTR Start, End, Write;
- for (Start = (ULONG_PTR)Src,
- End = Start + Bytes,
- Write = (ULONG_PTR)Dest;
- Result && (Start < End);
- Start++, Write++)
- if (!KdpSafeReadMemory(Start, 1, (PVOID)Write))
- Result = FALSE;
- break;
- }
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ Result = KdpSafeReadMemory((ULONG_PTR)Src, Bytes, Dest);
+ break;
+
+ default:
+ {
+ ULONG_PTR Start, End, Write;
+
+ for (Start = (ULONG_PTR)Src,
+ End = Start + Bytes,
+ Write = (ULONG_PTR)Dest;
+ Result && (Start < End);
+ Start++, Write++)
+ if (!KdpSafeReadMemory(Start, 1, (PVOID)Write))
+ Result = FALSE;
+
+ break;
+ }
}
return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
}
NTSTATUS
-KdbpSafeWriteMemory(OUT PVOID Dest,
- IN PVOID Src,
- IN ULONG Bytes)
+KdbpSafeWriteMemory(
+ OUT PVOID Dest,
+ IN PVOID Src,
+ IN ULONG Bytes)
{
BOOLEAN Result = TRUE;
ULONG_PTR Start, End, Write;
- for (Start = (ULONG_PTR)Src,
- End = Start + Bytes,
- Write = (ULONG_PTR)Dest;
- Result && (Start < End);
+ for (Start = (ULONG_PTR)Src,
+ End = Start + Bytes,
+ Write = (ULONG_PTR)Dest;
+ Result && (Start < End);
Start++, Write++)
if (!KdpSafeWriteMemory(Write, 1, *((PCHAR)Start)))
Result = FALSE;
static const struct
{
- PCHAR Name;
- PCHAR Syntax;
- PCHAR Help;
- BOOLEAN (*Fn)(ULONG Argc, PCHAR Argv[]);
+ PCHAR Name;
+ PCHAR Syntax;
+ PCHAR Help;
+ BOOLEAN (*Fn)(ULONG Argc, PCHAR Argv[]);
} KdbDebuggerCommands[] = {
- /* Data */
- { NULL, NULL, "Data", NULL },
- { "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression },
- { "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX },
- { "x", "x [address] [L count]", "Display count dwords, starting at addr.", KdbpCmdDisassembleX },
- { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
- { "cregs", "cregs", "Display control registers.", KdbpCmdRegs },
- { "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
- { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
- { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame addr", KdbpCmdBackTrace },
-
- /* Flow control */
- { NULL, NULL, "Flow control", NULL },
- { "cont", "cont", "Continue execution (leave debugger)", KdbpCmdContinue },
- { "step", "step [count]", "Execute single instructions, stepping into interrupts.", KdbpCmdStep },
- { "next", "next [count]", "Execute single instructions, skipping calls and reps.", KdbpCmdStep },
- { "bl", "bl", "List breakpoints.", KdbpCmdBreakPointList },
- { "be", "be [breakpoint]", "Enable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
- { "bd", "bd [breakpoint]", "Disable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
- { "bc", "bc [breakpoint]", "Clear breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
- { "bpx", "bpx [address] [IF condition]", "Set software execution breakpoint at address.", KdbpCmdBreakPoint },
- { "bpm", "bpm [r|w|rw|x] [byte|word|dword] [address] [IF condition]", "Set memory breakpoint at address.", KdbpCmdBreakPoint },
-
- /* Process/Thread */
- { NULL, NULL, "Process/Thread", NULL },
- { "thread", "thread [list[ pid]|[attach ]tid]", "List threads in current or specified process, display thread with given id or attach to thread.", KdbpCmdThread },
- { "proc", "proc [list|[attach ]pid]", "List processes, display process with given id or attach to process.", KdbpCmdProc },
-
- /* System information */
- { NULL, NULL, "System info", NULL },
- { "mod", "mod [address]", "List all modules or the one containing address.", KdbpCmdMod },
- { "gdt", "gdt", "Display global descriptor table.", KdbpCmdGdtLdtIdt },
- { "ldt", "ldt", "Display local descriptor table.", KdbpCmdGdtLdtIdt },
- { "idt", "idt", "Display interrupt descriptor table.", KdbpCmdGdtLdtIdt },
- { "pcr", "pcr", "Display processor control region.", KdbpCmdPcr },
- { "tss", "tss", "Display task state segment.", KdbpCmdTss },
-
- /* Others */
- { NULL, NULL, "Others", NULL },
- { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck },
- { "filter", "filter [error|warning|trace|info|level]+|-[componentname|default]", "Enable/disable debug channels", KdbpCmdFilter },
- { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet },
- { "help", "help", "Display help screen.", KdbpCmdHelp }
+ /* Data */
+ { NULL, NULL, "Data", NULL },
+ { "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression },
+ { "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX },
+ { "x", "x [address] [L count]", "Display count dwords, starting at addr.", KdbpCmdDisassembleX },
+ { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
+ { "cregs", "cregs", "Display control registers.", KdbpCmdRegs },
+ { "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
+ { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
+ { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame addr", KdbpCmdBackTrace },
+
+ /* Flow control */
+ { NULL, NULL, "Flow control", NULL },
+ { "cont", "cont", "Continue execution (leave debugger)", KdbpCmdContinue },
+ { "step", "step [count]", "Execute single instructions, stepping into interrupts.", KdbpCmdStep },
+ { "next", "next [count]", "Execute single instructions, skipping calls and reps.", KdbpCmdStep },
+ { "bl", "bl", "List breakpoints.", KdbpCmdBreakPointList },
+ { "be", "be [breakpoint]", "Enable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
+ { "bd", "bd [breakpoint]", "Disable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
+ { "bc", "bc [breakpoint]", "Clear breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
+ { "bpx", "bpx [address] [IF condition]", "Set software execution breakpoint at address.", KdbpCmdBreakPoint },
+ { "bpm", "bpm [r|w|rw|x] [byte|word|dword] [address] [IF condition]", "Set memory breakpoint at address.", KdbpCmdBreakPoint },
+
+ /* Process/Thread */
+ { NULL, NULL, "Process/Thread", NULL },
+ { "thread", "thread [list[ pid]|[attach ]tid]", "List threads in current or specified process, display thread with given id or attach to thread.", KdbpCmdThread },
+ { "proc", "proc [list|[attach ]pid]", "List processes, display process with given id or attach to process.", KdbpCmdProc },
+
+ /* System information */
+ { NULL, NULL, "System info", NULL },
+ { "mod", "mod [address]", "List all modules or the one containing address.", KdbpCmdMod },
+ { "gdt", "gdt", "Display global descriptor table.", KdbpCmdGdtLdtIdt },
+ { "ldt", "ldt", "Display local descriptor table.", KdbpCmdGdtLdtIdt },
+ { "idt", "idt", "Display interrupt descriptor table.", KdbpCmdGdtLdtIdt },
+ { "pcr", "pcr", "Display processor control region.", KdbpCmdPcr },
+ { "tss", "tss", "Display task state segment.", KdbpCmdTss },
+
+ /* Others */
+ { NULL, NULL, "Others", NULL },
+ { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck },
+ { "filter", "filter [error|warning|trace|info|level]+|-[componentname|default]", "Enable/disable debug channels", KdbpCmdFilter },
+ { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet },
+ { "help", "help", "Display help screen.", KdbpCmdHelp }
};
/* FUNCTIONS *****************************************************************/
*/
static BOOLEAN
KdbpGetComponentId(
- IN PCCH ComponentName,
- OUT PULONG ComponentId)
+ IN PCCH ComponentName,
+ OUT PULONG ComponentId)
{
- ULONG i;
-
- static struct {
- PCCH Name;
- ULONG Id;
- } ComponentTable[] = {
- { "DEFAULT", DPFLTR_DEFAULT_ID },
- { "SYSTEM", DPFLTR_SYSTEM_ID },
- { "SMSS", DPFLTR_SMSS_ID },
- { "SETUP", DPFLTR_SETUP_ID },
- { "NTFS", DPFLTR_NTFS_ID },
- { "FSTUB", DPFLTR_FSTUB_ID },
- { "CRASHDUMP", DPFLTR_CRASHDUMP_ID },
- { "CDAUDIO", DPFLTR_CDAUDIO_ID },
- { "CDROM", DPFLTR_CDROM_ID },
- { "CLASSPNP", DPFLTR_CLASSPNP_ID },
- { "DISK", DPFLTR_DISK_ID },
- { "REDBOOK", DPFLTR_REDBOOK_ID },
- { "STORPROP", DPFLTR_STORPROP_ID },
- { "SCSIPORT", DPFLTR_SCSIPORT_ID },
- { "SCSIMINIPORT", DPFLTR_SCSIMINIPORT_ID },
- { "CONFIG", DPFLTR_CONFIG_ID },
- { "I8042PRT", DPFLTR_I8042PRT_ID },
- { "SERMOUSE", DPFLTR_SERMOUSE_ID },
- { "LSERMOUS", DPFLTR_LSERMOUS_ID },
- { "KBDHID", DPFLTR_KBDHID_ID },
- { "MOUHID", DPFLTR_MOUHID_ID },
- { "KBDCLASS", DPFLTR_KBDCLASS_ID },
- { "MOUCLASS", DPFLTR_MOUCLASS_ID },
- { "TWOTRACK", DPFLTR_TWOTRACK_ID },
- { "WMILIB", DPFLTR_WMILIB_ID },
- { "ACPI", DPFLTR_ACPI_ID },
- { "AMLI", DPFLTR_AMLI_ID },
- { "HALIA64", DPFLTR_HALIA64_ID },
- { "VIDEO", DPFLTR_VIDEO_ID },
- { "SVCHOST", DPFLTR_SVCHOST_ID },
- { "VIDEOPRT", DPFLTR_VIDEOPRT_ID },
- { "TCPIP", DPFLTR_TCPIP_ID },
- { "DMSYNTH", DPFLTR_DMSYNTH_ID },
- { "NTOSPNP", DPFLTR_NTOSPNP_ID },
- { "FASTFAT", DPFLTR_FASTFAT_ID },
- { "SAMSS", DPFLTR_SAMSS_ID },
- { "PNPMGR", DPFLTR_PNPMGR_ID },
- { "NETAPI", DPFLTR_NETAPI_ID },
- { "SCSERVER", DPFLTR_SCSERVER_ID },
- { "SCCLIENT", DPFLTR_SCCLIENT_ID },
- { "SERIAL", DPFLTR_SERIAL_ID },
- { "SERENUM", DPFLTR_SERENUM_ID },
- { "UHCD", DPFLTR_UHCD_ID },
- { "BOOTOK", DPFLTR_BOOTOK_ID },
- { "BOOTVRFY", DPFLTR_BOOTVRFY_ID },
- { "RPCPROXY", DPFLTR_RPCPROXY_ID },
- { "AUTOCHK", DPFLTR_AUTOCHK_ID },
- { "DCOMSS", DPFLTR_DCOMSS_ID },
- { "UNIMODEM", DPFLTR_UNIMODEM_ID },
- { "SIS", DPFLTR_SIS_ID },
- { "FLTMGR", DPFLTR_FLTMGR_ID },
- { "WMICORE", DPFLTR_WMICORE_ID },
- { "BURNENG", DPFLTR_BURNENG_ID },
- { "IMAPI", DPFLTR_IMAPI_ID },
- { "SXS", DPFLTR_SXS_ID },
- { "FUSION", DPFLTR_FUSION_ID },
- { "IDLETASK", DPFLTR_IDLETASK_ID },
- { "SOFTPCI", DPFLTR_SOFTPCI_ID },
- { "TAPE", DPFLTR_TAPE_ID },
- { "MCHGR", DPFLTR_MCHGR_ID },
- { "IDEP", DPFLTR_IDEP_ID },
- { "PCIIDE", DPFLTR_PCIIDE_ID },
- { "FLOPPY", DPFLTR_FLOPPY_ID },
- { "FDC", DPFLTR_FDC_ID },
- { "TERMSRV", DPFLTR_TERMSRV_ID },
- { "W32TIME", DPFLTR_W32TIME_ID },
- { "PREFETCHER", DPFLTR_PREFETCHER_ID },
- { "RSFILTER", DPFLTR_RSFILTER_ID },
- { "FCPORT", DPFLTR_FCPORT_ID },
- { "PCI", DPFLTR_PCI_ID },
- { "DMIO", DPFLTR_DMIO_ID },
- { "DMCONFIG", DPFLTR_DMCONFIG_ID },
- { "DMADMIN", DPFLTR_DMADMIN_ID },
- { "WSOCKTRANSPORT", DPFLTR_WSOCKTRANSPORT_ID },
- { "VSS", DPFLTR_VSS_ID },
- { "PNPMEM", DPFLTR_PNPMEM_ID },
- { "PROCESSOR", DPFLTR_PROCESSOR_ID },
- { "DMSERVER", DPFLTR_DMSERVER_ID },
- { "SR", DPFLTR_SR_ID },
- { "INFINIBAND", DPFLTR_INFINIBAND_ID },
- { "IHVDRIVER", DPFLTR_IHVDRIVER_ID },
- { "IHVVIDEO", DPFLTR_IHVVIDEO_ID },
- { "IHVAUDIO", DPFLTR_IHVAUDIO_ID },
- { "IHVNETWORK", DPFLTR_IHVNETWORK_ID },
- { "IHVSTREAMING", DPFLTR_IHVSTREAMING_ID },
- { "IHVBUS", DPFLTR_IHVBUS_ID },
- { "HPS", DPFLTR_HPS_ID },
- { "RTLTHREADPOOL", DPFLTR_RTLTHREADPOOL_ID },
- { "LDR", DPFLTR_LDR_ID },
- { "TCPIP6", DPFLTR_TCPIP6_ID },
- { "ISAPNP", DPFLTR_ISAPNP_ID },
- { "SHPC", DPFLTR_SHPC_ID },
- { "STORPORT", DPFLTR_STORPORT_ID },
- { "STORMINIPORT", DPFLTR_STORMINIPORT_ID },
- { "PRINTSPOOLER", DPFLTR_PRINTSPOOLER_ID },
+ ULONG i;
+
+ static struct
+ {
+ PCCH Name;
+ ULONG Id;
+ }
+ ComponentTable[] =
+ {
+ { "DEFAULT", DPFLTR_DEFAULT_ID },
+ { "SYSTEM", DPFLTR_SYSTEM_ID },
+ { "SMSS", DPFLTR_SMSS_ID },
+ { "SETUP", DPFLTR_SETUP_ID },
+ { "NTFS", DPFLTR_NTFS_ID },
+ { "FSTUB", DPFLTR_FSTUB_ID },
+ { "CRASHDUMP", DPFLTR_CRASHDUMP_ID },
+ { "CDAUDIO", DPFLTR_CDAUDIO_ID },
+ { "CDROM", DPFLTR_CDROM_ID },
+ { "CLASSPNP", DPFLTR_CLASSPNP_ID },
+ { "DISK", DPFLTR_DISK_ID },
+ { "REDBOOK", DPFLTR_REDBOOK_ID },
+ { "STORPROP", DPFLTR_STORPROP_ID },
+ { "SCSIPORT", DPFLTR_SCSIPORT_ID },
+ { "SCSIMINIPORT", DPFLTR_SCSIMINIPORT_ID },
+ { "CONFIG", DPFLTR_CONFIG_ID },
+ { "I8042PRT", DPFLTR_I8042PRT_ID },
+ { "SERMOUSE", DPFLTR_SERMOUSE_ID },
+ { "LSERMOUS", DPFLTR_LSERMOUS_ID },
+ { "KBDHID", DPFLTR_KBDHID_ID },
+ { "MOUHID", DPFLTR_MOUHID_ID },
+ { "KBDCLASS", DPFLTR_KBDCLASS_ID },
+ { "MOUCLASS", DPFLTR_MOUCLASS_ID },
+ { "TWOTRACK", DPFLTR_TWOTRACK_ID },
+ { "WMILIB", DPFLTR_WMILIB_ID },
+ { "ACPI", DPFLTR_ACPI_ID },
+ { "AMLI", DPFLTR_AMLI_ID },
+ { "HALIA64", DPFLTR_HALIA64_ID },
+ { "VIDEO", DPFLTR_VIDEO_ID },
+ { "SVCHOST", DPFLTR_SVCHOST_ID },
+ { "VIDEOPRT", DPFLTR_VIDEOPRT_ID },
+ { "TCPIP", DPFLTR_TCPIP_ID },
+ { "DMSYNTH", DPFLTR_DMSYNTH_ID },
+ { "NTOSPNP", DPFLTR_NTOSPNP_ID },
+ { "FASTFAT", DPFLTR_FASTFAT_ID },
+ { "SAMSS", DPFLTR_SAMSS_ID },
+ { "PNPMGR", DPFLTR_PNPMGR_ID },
+ { "NETAPI", DPFLTR_NETAPI_ID },
+ { "SCSERVER", DPFLTR_SCSERVER_ID },
+ { "SCCLIENT", DPFLTR_SCCLIENT_ID },
+ { "SERIAL", DPFLTR_SERIAL_ID },
+ { "SERENUM", DPFLTR_SERENUM_ID },
+ { "UHCD", DPFLTR_UHCD_ID },
+ { "BOOTOK", DPFLTR_BOOTOK_ID },
+ { "BOOTVRFY", DPFLTR_BOOTVRFY_ID },
+ { "RPCPROXY", DPFLTR_RPCPROXY_ID },
+ { "AUTOCHK", DPFLTR_AUTOCHK_ID },
+ { "DCOMSS", DPFLTR_DCOMSS_ID },
+ { "UNIMODEM", DPFLTR_UNIMODEM_ID },
+ { "SIS", DPFLTR_SIS_ID },
+ { "FLTMGR", DPFLTR_FLTMGR_ID },
+ { "WMICORE", DPFLTR_WMICORE_ID },
+ { "BURNENG", DPFLTR_BURNENG_ID },
+ { "IMAPI", DPFLTR_IMAPI_ID },
+ { "SXS", DPFLTR_SXS_ID },
+ { "FUSION", DPFLTR_FUSION_ID },
+ { "IDLETASK", DPFLTR_IDLETASK_ID },
+ { "SOFTPCI", DPFLTR_SOFTPCI_ID },
+ { "TAPE", DPFLTR_TAPE_ID },
+ { "MCHGR", DPFLTR_MCHGR_ID },
+ { "IDEP", DPFLTR_IDEP_ID },
+ { "PCIIDE", DPFLTR_PCIIDE_ID },
+ { "FLOPPY", DPFLTR_FLOPPY_ID },
+ { "FDC", DPFLTR_FDC_ID },
+ { "TERMSRV", DPFLTR_TERMSRV_ID },
+ { "W32TIME", DPFLTR_W32TIME_ID },
+ { "PREFETCHER", DPFLTR_PREFETCHER_ID },
+ { "RSFILTER", DPFLTR_RSFILTER_ID },
+ { "FCPORT", DPFLTR_FCPORT_ID },
+ { "PCI", DPFLTR_PCI_ID },
+ { "DMIO", DPFLTR_DMIO_ID },
+ { "DMCONFIG", DPFLTR_DMCONFIG_ID },
+ { "DMADMIN", DPFLTR_DMADMIN_ID },
+ { "WSOCKTRANSPORT", DPFLTR_WSOCKTRANSPORT_ID },
+ { "VSS", DPFLTR_VSS_ID },
+ { "PNPMEM", DPFLTR_PNPMEM_ID },
+ { "PROCESSOR", DPFLTR_PROCESSOR_ID },
+ { "DMSERVER", DPFLTR_DMSERVER_ID },
+ { "SR", DPFLTR_SR_ID },
+ { "INFINIBAND", DPFLTR_INFINIBAND_ID },
+ { "IHVDRIVER", DPFLTR_IHVDRIVER_ID },
+ { "IHVVIDEO", DPFLTR_IHVVIDEO_ID },
+ { "IHVAUDIO", DPFLTR_IHVAUDIO_ID },
+ { "IHVNETWORK", DPFLTR_IHVNETWORK_ID },
+ { "IHVSTREAMING", DPFLTR_IHVSTREAMING_ID },
+ { "IHVBUS", DPFLTR_IHVBUS_ID },
+ { "HPS", DPFLTR_HPS_ID },
+ { "RTLTHREADPOOL", DPFLTR_RTLTHREADPOOL_ID },
+ { "LDR", DPFLTR_LDR_ID },
+ { "TCPIP6", DPFLTR_TCPIP6_ID },
+ { "ISAPNP", DPFLTR_ISAPNP_ID },
+ { "SHPC", DPFLTR_SHPC_ID },
+ { "STORPORT", DPFLTR_STORPORT_ID },
+ { "STORMINIPORT", DPFLTR_STORMINIPORT_ID },
+ { "PRINTSPOOLER", DPFLTR_PRINTSPOOLER_ID },
};
- for (i = 0; i < sizeof(ComponentTable) / sizeof(ComponentTable[0]); i++)
- if (_stricmp(ComponentName, ComponentTable[i].Name) == 0)
- {
- *ComponentId = ComponentTable[i].Id;
- return TRUE;
- }
+ for (i = 0; i < sizeof(ComponentTable) / sizeof(ComponentTable[0]); i++)
+ {
+ if (_stricmp(ComponentName, ComponentTable[i].Name) == 0)
+ {
+ *ComponentId = ComponentTable[i].Id;
+ return TRUE;
+ }
+ }
- return FALSE;
+ return FALSE;
}
/*!\brief Evaluates an expression...
*/
static BOOLEAN
KdbpEvaluateExpression(
- IN PCHAR Expression,
- IN LONG ErrOffset,
- OUT PULONGLONG Result)
+ IN PCHAR Expression,
+ IN LONG ErrOffset,
+ OUT PULONGLONG Result)
{
- static CHAR ErrMsgBuffer[130] = "^ ";
- LONG ExpressionErrOffset = -1;
- PCHAR ErrMsg = ErrMsgBuffer;
- BOOLEAN Ok;
-
- Ok = KdbpRpnEvaluateExpression(Expression, KdbCurrentTrapFrame, Result,
- &ExpressionErrOffset, ErrMsgBuffer + 2);
- if (!Ok)
- {
- if (ExpressionErrOffset >= 0)
- ExpressionErrOffset += ErrOffset;
- else
- ErrMsg += 2;
- KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
- }
-
- return Ok;
+ static CHAR ErrMsgBuffer[130] = "^ ";
+ LONG ExpressionErrOffset = -1;
+ PCHAR ErrMsg = ErrMsgBuffer;
+ BOOLEAN Ok;
+
+ Ok = KdbpRpnEvaluateExpression(Expression, KdbCurrentTrapFrame, Result,
+ &ExpressionErrOffset, ErrMsgBuffer + 2);
+ if (!Ok)
+ {
+ if (ExpressionErrOffset >= 0)
+ ExpressionErrOffset += ErrOffset;
+ else
+ ErrMsg += 2;
+
+ KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
+ }
+
+ return Ok;
}
/*!\brief Evaluates an expression and displays the result.
*/
static BOOLEAN
-KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[])
+KdbpCmdEvalExpression(
+ ULONG Argc,
+ PCHAR Argv[])
{
- ULONG i, len;
- ULONGLONG Result = 0;
- ULONG ul;
- LONG l = 0;
- BOOLEAN Ok;
-
- if (Argc < 2)
- {
- KdbpPrint("?: Argument required\n");
- return TRUE;
- }
-
- /* Put the arguments back together */
- Argc--;
- for (i = 1; i < Argc; i++)
- {
- len = strlen(Argv[i]);
- Argv[i][len] = ' ';
- }
-
- /* Evaluate the expression */
- Ok = KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result);
- if (Ok)
- {
- if (Result > 0x00000000ffffffffLL)
- {
- if (Result & 0x8000000000000000LL)
- KdbpPrint("0x%016I64x %20I64u %20I64d\n", Result, Result, Result);
- else
- KdbpPrint("0x%016I64x %20I64u\n", Result, Result);
- }
- else
- {
- ul = (ULONG)Result;
- if (ul <= 0xff && ul >= 0x80)
- l = (LONG)((CHAR)ul);
- else if (ul <= 0xffff && ul >= 0x8000)
- l = (LONG)((SHORT)ul);
- else
- l = (LONG)ul;
- if (l < 0)
- KdbpPrint("0x%08lx %10lu %10ld\n", ul, ul, l);
- else
- KdbpPrint("0x%08lx %10lu\n", ul, ul);
- }
- }
-
- return TRUE;
+ ULONG i, len;
+ ULONGLONG Result = 0;
+ ULONG ul;
+ LONG l = 0;
+ BOOLEAN Ok;
+
+ if (Argc < 2)
+ {
+ KdbpPrint("?: Argument required\n");
+ return TRUE;
+ }
+
+ /* Put the arguments back together */
+ Argc--;
+ for (i = 1; i < Argc; i++)
+ {
+ len = strlen(Argv[i]);
+ Argv[i][len] = ' ';
+ }
+
+ /* Evaluate the expression */
+ Ok = KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result);
+ if (Ok)
+ {
+ if (Result > 0x00000000ffffffffLL)
+ {
+ if (Result & 0x8000000000000000LL)
+ KdbpPrint("0x%016I64x %20I64u %20I64d\n", Result, Result, Result);
+ else
+ KdbpPrint("0x%016I64x %20I64u\n", Result, Result);
+ }
+ else
+ {
+ ul = (ULONG)Result;
+
+ if (ul <= 0xff && ul >= 0x80)
+ l = (LONG)((CHAR)ul);
+ else if (ul <= 0xffff && ul >= 0x8000)
+ l = (LONG)((SHORT)ul);
+ else
+ l = (LONG)ul;
+
+ if (l < 0)
+ KdbpPrint("0x%08lx %10lu %10ld\n", ul, ul, l);
+ else
+ KdbpPrint("0x%08lx %10lu\n", ul, ul);
+ }
+ }
+
+ return TRUE;
}
/*!\brief Display list of active debug channels
*/
static BOOLEAN
-KdbpCmdFilter(ULONG Argc, PCHAR Argv[])
+KdbpCmdFilter(
+ ULONG Argc,
+ PCHAR Argv[])
{
ULONG i, j, ComponentId, Level;
ULONG set = DPFLTR_MASK, clear = DPFLTR_MASK;
PCHAR pend;
LPCSTR opt, p;
- static struct {
+
+ static struct
+ {
LPCSTR Name;
ULONG Level;
- } debug_classes[] = {
+ }
+ debug_classes[] =
+ {
{ "error", 1 << DPFLTR_ERROR_LEVEL },
{ "warning", 1 << DPFLTR_WARNING_LEVEL },
{ "trace", 1 << DPFLTR_TRACE_LEVEL },
* displays 16 dwords from memory at given address.
*/
static BOOLEAN
-KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[])
+KdbpCmdDisassembleX(
+ ULONG Argc,
+ PCHAR Argv[])
{
- ULONG Count;
- ULONG ul;
- INT i;
- ULONGLONG Result = 0;
- ULONG_PTR Address = KdbCurrentTrapFrame->Tf.Eip;
- LONG InstLen;
-
- if (Argv[0][0] == 'x') /* display memory */
- Count = 16;
- else /* disassemble */
- Count = 10;
-
- if (Argc >= 2)
- {
- /* Check for [L count] part */
- ul = 0;
- if (strcmp(Argv[Argc-2], "L") == 0)
- {
- ul = strtoul(Argv[Argc-1], NULL, 0);
- if (ul > 0)
- {
- Count = ul;
- Argc -= 2;
- }
- }
- else if (Argv[Argc-1][0] == 'L')
- {
- ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
- if (ul > 0)
- {
- Count = ul;
- Argc--;
- }
- }
-
- /* Put the remaining arguments back together */
- Argc--;
- for (ul = 1; ul < Argc; ul++)
- {
- Argv[ul][strlen(Argv[ul])] = ' ';
- }
- Argc++;
- }
-
- /* Evaluate the expression */
- if (Argc > 1)
- {
- if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
- return TRUE;
- if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
- KdbpPrint("Warning: Address %I64x is beeing truncated\n");
- Address = (ULONG_PTR)Result;
- }
- else if (Argv[0][0] == 'x')
- {
- KdbpPrint("x: Address argument required.\n");
- return TRUE;
- }
-
- if (Argv[0][0] == 'x')
- {
- /* Display dwords */
- ul = 0;
- while (Count > 0)
- {
- if (!KdbSymPrintAddress((PVOID)Address))
- KdbpPrint("<%x>:", Address);
- else
- KdbpPrint(":");
- i = min(4, Count);
- Count -= i;
- while (--i >= 0)
- {
- if (!NT_SUCCESS(KdbpSafeReadMemory(&ul, (PVOID)Address, sizeof(ul))))
- KdbpPrint(" ????????");
- else
- KdbpPrint(" %08x", ul);
- Address += sizeof(ul);
- }
- KdbpPrint("\n");
- }
- }
- else
- {
- /* Disassemble */
- while (Count-- > 0)
- {
- if (!KdbSymPrintAddress((PVOID)Address))
- KdbpPrint("<%08x>: ", Address);
- else
- KdbpPrint(": ");
- InstLen = KdbpDisassemble(Address, KdbUseIntelSyntax);
- if (InstLen < 0)
- {
- KdbpPrint("<INVALID>\n");
+ ULONG Count;
+ ULONG ul;
+ INT i;
+ ULONGLONG Result = 0;
+ ULONG_PTR Address = KdbCurrentTrapFrame->Tf.Eip;
+ LONG InstLen;
+
+ if (Argv[0][0] == 'x') /* display memory */
+ Count = 16;
+ else /* disassemble */
+ Count = 10;
+
+ if (Argc >= 2)
+ {
+ /* Check for [L count] part */
+ ul = 0;
+ if (strcmp(Argv[Argc-2], "L") == 0)
+ {
+ ul = strtoul(Argv[Argc-1], NULL, 0);
+ if (ul > 0)
+ {
+ Count = ul;
+ Argc -= 2;
+ }
+ }
+ else if (Argv[Argc-1][0] == 'L')
+ {
+ ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
+ if (ul > 0)
+ {
+ Count = ul;
+ Argc--;
+ }
+ }
+
+ /* Put the remaining arguments back together */
+ Argc--;
+ for (ul = 1; ul < Argc; ul++)
+ {
+ Argv[ul][strlen(Argv[ul])] = ' ';
+ }
+ Argc++;
+ }
+
+ /* Evaluate the expression */
+ if (Argc > 1)
+ {
+ if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
return TRUE;
- }
- KdbpPrint("\n");
- Address += InstLen;
- }
- }
- return TRUE;
+ if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
+ KdbpPrint("Warning: Address %I64x is beeing truncated\n");
+
+ Address = (ULONG_PTR)Result;
+ }
+ else if (Argv[0][0] == 'x')
+ {
+ KdbpPrint("x: Address argument required.\n");
+ return TRUE;
+ }
+
+ if (Argv[0][0] == 'x')
+ {
+ /* Display dwords */
+ ul = 0;
+
+ while (Count > 0)
+ {
+ if (!KdbSymPrintAddress((PVOID)Address))
+ KdbpPrint("<%x>:", Address);
+ else
+ KdbpPrint(":");
+
+ i = min(4, Count);
+ Count -= i;
+
+ while (--i >= 0)
+ {
+ if (!NT_SUCCESS(KdbpSafeReadMemory(&ul, (PVOID)Address, sizeof(ul))))
+ KdbpPrint(" ????????");
+ else
+ KdbpPrint(" %08x", ul);
+
+ Address += sizeof(ul);
+ }
+
+ KdbpPrint("\n");
+ }
+ }
+ else
+ {
+ /* Disassemble */
+ while (Count-- > 0)
+ {
+ if (!KdbSymPrintAddress((PVOID)Address))
+ KdbpPrint("<%08x>: ", Address);
+ else
+ KdbpPrint(": ");
+
+ InstLen = KdbpDisassemble(Address, KdbUseIntelSyntax);
+ if (InstLen < 0)
+ {
+ KdbpPrint("<INVALID>\n");
+ return TRUE;
+ }
+
+ KdbpPrint("\n");
+ Address += InstLen;
+ }
+ }
+
+ return TRUE;
}
/*!\brief Displays CPU registers.
*/
static BOOLEAN
-KdbpCmdRegs(ULONG Argc, PCHAR Argv[])
+KdbpCmdRegs(
+ ULONG Argc,
+ PCHAR Argv[])
{
- PKTRAP_FRAME Tf = &KdbCurrentTrapFrame->Tf;
- INT i;
- static const PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5",
- " ZF", " SF", " TF", " IF", " DF", " OF",
- NULL, NULL, " NT", " BIT15", " RF", " VF",
- " AC", " VIF", " VIP", " ID", " BIT22",
- " BIT23", " BIT24", " BIT25", " BIT26",
- " BIT27", " BIT28", " BIT29", " BIT30",
- " BIT31" };
-
- if (Argv[0][0] == 'r') /* regs */
- {
- KdbpPrint("CS:EIP 0x%04x:0x%08x\n"
- "SS:ESP 0x%04x:0x%08x\n"
- " EAX 0x%08x EBX 0x%08x\n"
- " ECX 0x%08x EDX 0x%08x\n"
- " ESI 0x%08x EDI 0x%08x\n"
- " EBP 0x%08x\n",
- Tf->SegCs & 0xFFFF, Tf->Eip,
- Tf->HardwareSegSs, Tf->HardwareEsp,
- Tf->Eax, Tf->Ebx,
- Tf->Ecx, Tf->Edx,
- Tf->Esi, Tf->Edi,
- Tf->Ebp);
- KdbpPrint("EFLAGS 0x%08x ", Tf->EFlags);
- for (i = 0; i < 32; i++)
- {
- if (i == 1)
- {
- if ((Tf->EFlags & (1 << 1)) == 0)
- KdbpPrint(" !BIT1");
- }
- else if (i == 12)
- {
- KdbpPrint(" IOPL%d", (Tf->EFlags >> 12) & 3);
- }
- else if (i == 13)
- {
- }
- else if ((Tf->EFlags & (1 << i)) != 0)
- KdbpPrint(EflagsBits[i]);
- }
- KdbpPrint("\n");
- }
- else if (Argv[0][0] == 'c') /* cregs */
- {
- ULONG Cr0, Cr2, Cr3, Cr4;
- KDESCRIPTOR Gdtr = {0}, Ldtr = {0}, Idtr = {0};
- ULONG Tr = 0;
- static const PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- " WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, " NW", " CD", " PG" };
- static const PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " PSE", " PAE", " MCE", " PGE",
- " PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-
- Cr0 = KdbCurrentTrapFrame->Cr0;
- Cr2 = KdbCurrentTrapFrame->Cr2;
- Cr3 = KdbCurrentTrapFrame->Cr3;
- Cr4 = KdbCurrentTrapFrame->Cr4;
-
- /* Get descriptor table regs */
- Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&Gdtr.Limit);
- Ke386GetLocalDescriptorTable(Ldtr.Limit);
- Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Idtr.Limit);
-
- /* Get the task register */
- Ke386GetTr(Tr);
-
- /* Display the control registers */
- KdbpPrint("CR0 0x%08x ", Cr0);
- for (i = 0; i < 32; i++)
- {
- if (Cr0Bits[i] == NULL)
- continue;
- if ((Cr0 & (1 << i)) != 0)
- KdbpPrint(Cr0Bits[i]);
- }
- KdbpPrint("\nCR2 0x%08x\n", Cr2);
- KdbpPrint("CR3 0x%08x Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 0xfffff000),
- (Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : "" );
- KdbpPrint("CR4 0x%08x ", Cr4);
- for (i = 0; i < 32; i++)
- {
- if (Cr4Bits[i] == NULL)
- continue;
- if ((Cr4 & (1 << i)) != 0)
- KdbpPrint(Cr4Bits[i]);
- }
-
- /* Display the descriptor table regs */
- KdbpPrint("\nGDTR Base 0x%08x Size 0x%04x\n", Gdtr.Base, Gdtr.Limit);
- KdbpPrint("LDTR Base 0x%08x Size 0x%04x\n", Ldtr.Base, Ldtr.Limit);
- KdbpPrint("IDTR Base 0x%08x Size 0x%04x\n", Idtr.Base, Idtr.Limit);
- }
- else if (Argv[0][0] == 's') /* sregs */
- {
- KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n",
- Tf->SegCs & 0xffff, (Tf->SegCs & 0xffff) >> 3,
- (Tf->SegCs & (1 << 2)) ? 'L' : 'G', Tf->SegCs & 3);
- KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n",
- Tf->SegDs, Tf->SegDs >> 3, (Tf->SegDs & (1 << 2)) ? 'L' : 'G', Tf->SegDs & 3);
- KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n",
- Tf->SegEs, Tf->SegEs >> 3, (Tf->SegEs & (1 << 2)) ? 'L' : 'G', Tf->SegEs & 3);
- KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n",
- Tf->SegFs, Tf->SegFs >> 3, (Tf->SegFs & (1 << 2)) ? 'L' : 'G', Tf->SegFs & 3);
- KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n",
- Tf->SegGs, Tf->SegGs >> 3, (Tf->SegGs & (1 << 2)) ? 'L' : 'G', Tf->SegGs & 3);
- KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n",
- Tf->HardwareSegSs, Tf->HardwareSegSs >> 3, (Tf->HardwareSegSs & (1 << 2)) ? 'L' : 'G', Tf->HardwareSegSs & 3);
- }
- else /* dregs */
- {
- ASSERT(Argv[0][0] == 'd');
- KdbpPrint("DR0 0x%08x\n"
- "DR1 0x%08x\n"
- "DR2 0x%08x\n"
- "DR3 0x%08x\n"
- "DR6 0x%08x\n"
- "DR7 0x%08x\n",
- Tf->Dr0, Tf->Dr1, Tf->Dr2, Tf->Dr3,
- Tf->Dr6, Tf->Dr7);
- }
- return TRUE;
+ PKTRAP_FRAME Tf = &KdbCurrentTrapFrame->Tf;
+ INT i;
+ static const PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5",
+ " ZF", " SF", " TF", " IF", " DF", " OF",
+ NULL, NULL, " NT", " BIT15", " RF", " VF",
+ " AC", " VIF", " VIP", " ID", " BIT22",
+ " BIT23", " BIT24", " BIT25", " BIT26",
+ " BIT27", " BIT28", " BIT29", " BIT30",
+ " BIT31" };
+
+ if (Argv[0][0] == 'r') /* regs */
+ {
+ KdbpPrint("CS:EIP 0x%04x:0x%08x\n"
+ "SS:ESP 0x%04x:0x%08x\n"
+ " EAX 0x%08x EBX 0x%08x\n"
+ " ECX 0x%08x EDX 0x%08x\n"
+ " ESI 0x%08x EDI 0x%08x\n"
+ " EBP 0x%08x\n",
+ Tf->SegCs & 0xFFFF, Tf->Eip,
+ Tf->HardwareSegSs, Tf->HardwareEsp,
+ Tf->Eax, Tf->Ebx,
+ Tf->Ecx, Tf->Edx,
+ Tf->Esi, Tf->Edi,
+ Tf->Ebp);
+ KdbpPrint("EFLAGS 0x%08x ", Tf->EFlags);
+
+ for (i = 0; i < 32; i++)
+ {
+ if (i == 1)
+ {
+ if ((Tf->EFlags & (1 << 1)) == 0)
+ KdbpPrint(" !BIT1");
+ }
+ else if (i == 12)
+ {
+ KdbpPrint(" IOPL%d", (Tf->EFlags >> 12) & 3);
+ }
+ else if (i == 13)
+ {
+ }
+ else if ((Tf->EFlags & (1 << i)) != 0)
+ {
+ KdbpPrint(EflagsBits[i]);
+ }
+ }
+
+ KdbpPrint("\n");
+ }
+ else if (Argv[0][0] == 'c') /* cregs */
+ {
+ ULONG Cr0, Cr2, Cr3, Cr4;
+ KDESCRIPTOR Gdtr = {0}, Ldtr = {0}, Idtr = {0};
+ ULONG Tr = 0;
+ static const PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ " WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, " NW", " CD", " PG" };
+ static const PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " PSE", " PAE", " MCE", " PGE",
+ " PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+
+ Cr0 = KdbCurrentTrapFrame->Cr0;
+ Cr2 = KdbCurrentTrapFrame->Cr2;
+ Cr3 = KdbCurrentTrapFrame->Cr3;
+ Cr4 = KdbCurrentTrapFrame->Cr4;
+
+ /* Get descriptor table regs */
+ Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&Gdtr.Limit);
+ Ke386GetLocalDescriptorTable(Ldtr.Limit);
+ Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Idtr.Limit);
+
+ /* Get the task register */
+ Ke386GetTr(Tr);
+
+ /* Display the control registers */
+ KdbpPrint("CR0 0x%08x ", Cr0);
+
+ for (i = 0; i < 32; i++)
+ {
+ if (!Cr0Bits[i])
+ continue;
+
+ if ((Cr0 & (1 << i)) != 0)
+ KdbpPrint(Cr0Bits[i]);
+ }
+
+ KdbpPrint("\nCR2 0x%08x\n", Cr2);
+ KdbpPrint("CR3 0x%08x Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 0xfffff000),
+ (Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : "" );
+ KdbpPrint("CR4 0x%08x ", Cr4);
+
+ for (i = 0; i < 32; i++)
+ {
+ if (!Cr4Bits[i])
+ continue;
+
+ if ((Cr4 & (1 << i)) != 0)
+ KdbpPrint(Cr4Bits[i]);
+ }
+
+ /* Display the descriptor table regs */
+ KdbpPrint("\nGDTR Base 0x%08x Size 0x%04x\n", Gdtr.Base, Gdtr.Limit);
+ KdbpPrint("LDTR Base 0x%08x Size 0x%04x\n", Ldtr.Base, Ldtr.Limit);
+ KdbpPrint("IDTR Base 0x%08x Size 0x%04x\n", Idtr.Base, Idtr.Limit);
+ }
+ else if (Argv[0][0] == 's') /* sregs */
+ {
+ KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n",
+ Tf->SegCs & 0xffff, (Tf->SegCs & 0xffff) >> 3,
+ (Tf->SegCs & (1 << 2)) ? 'L' : 'G', Tf->SegCs & 3);
+ KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n",
+ Tf->SegDs, Tf->SegDs >> 3, (Tf->SegDs & (1 << 2)) ? 'L' : 'G', Tf->SegDs & 3);
+ KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n",
+ Tf->SegEs, Tf->SegEs >> 3, (Tf->SegEs & (1 << 2)) ? 'L' : 'G', Tf->SegEs & 3);
+ KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n",
+ Tf->SegFs, Tf->SegFs >> 3, (Tf->SegFs & (1 << 2)) ? 'L' : 'G', Tf->SegFs & 3);
+ KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n",
+ Tf->SegGs, Tf->SegGs >> 3, (Tf->SegGs & (1 << 2)) ? 'L' : 'G', Tf->SegGs & 3);
+ KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n",
+ Tf->HardwareSegSs, Tf->HardwareSegSs >> 3, (Tf->HardwareSegSs & (1 << 2)) ? 'L' : 'G', Tf->HardwareSegSs & 3);
+ }
+ else /* dregs */
+ {
+ ASSERT(Argv[0][0] == 'd');
+ KdbpPrint("DR0 0x%08x\n"
+ "DR1 0x%08x\n"
+ "DR2 0x%08x\n"
+ "DR3 0x%08x\n"
+ "DR6 0x%08x\n"
+ "DR7 0x%08x\n",
+ Tf->Dr0, Tf->Dr1, Tf->Dr2, Tf->Dr3,
+ Tf->Dr6, Tf->Dr7);
+ }
+
+ return TRUE;
}
/*!\brief Displays a backtrace.
*/
static BOOLEAN
-KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[])
+KdbpCmdBackTrace(
+ ULONG Argc,
+ PCHAR Argv[])
{
- ULONG Count;
- ULONG ul;
- ULONGLONG Result = 0;
- ULONG_PTR Frame = KdbCurrentTrapFrame->Tf.Ebp;
- ULONG_PTR Address;
-
- if (Argc >= 2)
- {
- /* Check for [L count] part */
- ul = 0;
- if (strcmp(Argv[Argc-2], "L") == 0)
- {
- ul = strtoul(Argv[Argc-1], NULL, 0);
- if (ul > 0)
- {
- Count = ul;
- Argc -= 2;
- }
- }
- else if (Argv[Argc-1][0] == 'L')
- {
- ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
- if (ul > 0)
- {
- Count = ul;
- Argc--;
- }
- }
-
- /* Put the remaining arguments back together */
- Argc--;
- for (ul = 1; ul < Argc; ul++)
- {
- Argv[ul][strlen(Argv[ul])] = ' ';
- }
- Argc++;
- }
-
- /* Check if frame addr or thread id is given. */
- if (Argc > 1)
- {
- if (Argv[1][0] == '*')
- {
- Argv[1]++;
- /* Evaluate the expression */
- if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
+ ULONG Count;
+ ULONG ul;
+ ULONGLONG Result = 0;
+ ULONG_PTR Frame = KdbCurrentTrapFrame->Tf.Ebp;
+ ULONG_PTR Address;
+
+ if (Argc >= 2)
+ {
+ /* Check for [L count] part */
+ ul = 0;
+
+ if (strcmp(Argv[Argc-2], "L") == 0)
+ {
+ ul = strtoul(Argv[Argc-1], NULL, 0);
+ if (ul > 0)
+ {
+ Count = ul;
+ Argc -= 2;
+ }
+ }
+ else if (Argv[Argc-1][0] == 'L')
+ {
+ ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
+ if (ul > 0)
+ {
+ Count = ul;
+ Argc--;
+ }
+ }
+
+ /* Put the remaining arguments back together */
+ Argc--;
+ for (ul = 1; ul < Argc; ul++)
+ {
+ Argv[ul][strlen(Argv[ul])] = ' ';
+ }
+ Argc++;
+ }
+
+ /* Check if frame addr or thread id is given. */
+ if (Argc > 1)
+ {
+ if (Argv[1][0] == '*')
+ {
+ Argv[1]++;
+
+ /* Evaluate the expression */
+ if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
+ return TRUE;
+
+ if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
+ KdbpPrint("Warning: Address %I64x is beeing truncated\n");
+
+ Frame = (ULONG_PTR)Result;
+ }
+ else
+ {
+ KdbpPrint("Thread backtrace not supported yet!\n");
return TRUE;
- if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
- KdbpPrint("Warning: Address %I64x is beeing truncated\n");
- Frame = (ULONG_PTR)Result;
- }
- else
- {
-
- KdbpPrint("Thread backtrace not supported yet!\n");
- return TRUE;
- }
- }
- else
- {
- KdbpPrint("Eip:\n");
- /* Try printing the function at EIP */
- if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip))
- KdbpPrint("<%08x>\n", KdbCurrentTrapFrame->Tf.Eip);
- else
- KdbpPrint("\n");
- }
-
- KdbpPrint("Frames:\n");
- for (;;)
- {
- if (Frame == 0)
- break;
- if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof (ULONG_PTR))))
- {
- KdbpPrint("Couldn't access memory at 0x%p!\n", Frame + sizeof(ULONG_PTR));
- break;
- }
- if (!KdbSymPrintAddress((PVOID)Address))
- KdbpPrint("<%08x>\n", Address);
- else
- KdbpPrint("\n");
- if (Address == 0)
- break;
- if (!NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof (ULONG_PTR))))
- {
- KdbpPrint("Couldn't access memory at 0x%p!\n", Frame);
- break;
- }
- }
-
- return TRUE;
+ }
+ }
+ else
+ {
+ KdbpPrint("Eip:\n");
+
+ /* Try printing the function at EIP */
+ if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip))
+ KdbpPrint("<%08x>\n", KdbCurrentTrapFrame->Tf.Eip);
+ else
+ KdbpPrint("\n");
+ }
+
+ KdbpPrint("Frames:\n");
+ for (;;)
+ {
+ if (Frame == 0)
+ break;
+
+ if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof (ULONG_PTR))))
+ {
+ KdbpPrint("Couldn't access memory at 0x%p!\n", Frame + sizeof(ULONG_PTR));
+ break;
+ }
+
+ if (!KdbSymPrintAddress((PVOID)Address))
+ KdbpPrint("<%08x>\n", Address);
+ else
+ KdbpPrint("\n");
+
+ if (Address == 0)
+ break;
+
+ if (!NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof (ULONG_PTR))))
+ {
+ KdbpPrint("Couldn't access memory at 0x%p!\n", Frame);
+ break;
+ }
+ }
+
+ return TRUE;
}
/*!\brief Continues execution of the system/leaves KDB.
*/
static BOOLEAN
-KdbpCmdContinue(ULONG Argc, PCHAR Argv[])
+KdbpCmdContinue(
+ ULONG Argc,
+ PCHAR Argv[])
{
- /* Exit the main loop */
- return FALSE;
+ /* Exit the main loop */
+ return FALSE;
}
/*!\brief Continues execution of the system/leaves KDB.
*/
static BOOLEAN
-KdbpCmdStep(ULONG Argc, PCHAR Argv[])
+KdbpCmdStep(
+ ULONG Argc,
+ PCHAR Argv[])
{
- ULONG Count = 1;
-
- if (Argc > 1)
- {
- Count = strtoul(Argv[1], NULL, 0);
- if (Count == 0)
- {
- KdbpPrint("%s: Integer argument required\n", Argv[0]);
- return TRUE;
- }
- }
-
- if (Argv[0][0] == 'n')
- KdbSingleStepOver = TRUE;
- else
- KdbSingleStepOver = FALSE;
-
- /* Set the number of single steps and return to the interrupted code. */
- KdbNumSingleSteps = Count;
-
- return FALSE;
+ ULONG Count = 1;
+
+ if (Argc > 1)
+ {
+ Count = strtoul(Argv[1], NULL, 0);
+ if (Count == 0)
+ {
+ KdbpPrint("%s: Integer argument required\n", Argv[0]);
+ return TRUE;
+ }
+ }
+
+ if (Argv[0][0] == 'n')
+ KdbSingleStepOver = TRUE;
+ else
+ KdbSingleStepOver = FALSE;
+
+ /* Set the number of single steps and return to the interrupted code. */
+ KdbNumSingleSteps = Count;
+
+ return FALSE;
}
/*!\brief Lists breakpoints.
*/
static BOOLEAN
-KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[])
+KdbpCmdBreakPointList(
+ ULONG Argc,
+ PCHAR Argv[])
{
- LONG l;
- ULONG_PTR Address = 0;
- KDB_BREAKPOINT_TYPE Type = 0;
- KDB_ACCESS_TYPE AccessType = 0;
- UCHAR Size = 0;
- UCHAR DebugReg = 0;
- BOOLEAN Enabled = FALSE;
- BOOLEAN Global = FALSE;
- PEPROCESS Process = NULL;
- PCHAR str1, str2, ConditionExpr, GlobalOrLocal;
- CHAR Buffer[20];
-
- l = KdbpGetNextBreakPointNr(0);
- if (l < 0)
- {
- KdbpPrint("No breakpoints.\n");
- return TRUE;
- }
-
- KdbpPrint("Breakpoints:\n");
- do
- {
- if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg,
- &Enabled, &Global, &Process, &ConditionExpr))
- {
- continue;
- }
-
- if (l == KdbLastBreakPointNr)
- {
- str1 = "\x1b[1m*";
- str2 = "\x1b[0m";
- }
- else
- {
- str1 = " ";
- str2 = "";
- }
-
- if (Global)
- GlobalOrLocal = " global";
- else
- {
- GlobalOrLocal = Buffer;
- sprintf(Buffer, " PID 0x%08lx",
- (ULONG)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
- }
-
- if (Type == KdbBreakPointSoftware || Type == KdbBreakPointTemporary)
- {
- KdbpPrint(" %s%03d BPX 0x%08x%s%s%s%s%s\n",
- str1, l, Address,
- Enabled ? "" : " disabled",
- GlobalOrLocal,
- ConditionExpr ? " IF " : "",
- ConditionExpr ? ConditionExpr : "",
- str2);
- }
- else if (Type == KdbBreakPointHardware)
- {
- if (!Enabled)
- {
- KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s disabled%s%s%s%s\n", str1, l, Address,
- KDB_ACCESS_TYPE_TO_STRING(AccessType),
- Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
- GlobalOrLocal,
- ConditionExpr ? " IF " : "",
- ConditionExpr ? ConditionExpr : "",
- str2);
- }
- else
- {
- KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s DR%d%s%s%s%s\n", str1, l, Address,
- KDB_ACCESS_TYPE_TO_STRING(AccessType),
- Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
- DebugReg,
+ LONG l;
+ ULONG_PTR Address = 0;
+ KDB_BREAKPOINT_TYPE Type = 0;
+ KDB_ACCESS_TYPE AccessType = 0;
+ UCHAR Size = 0;
+ UCHAR DebugReg = 0;
+ BOOLEAN Enabled = FALSE;
+ BOOLEAN Global = FALSE;
+ PEPROCESS Process = NULL;
+ PCHAR str1, str2, ConditionExpr, GlobalOrLocal;
+ CHAR Buffer[20];
+
+ l = KdbpGetNextBreakPointNr(0);
+ if (l < 0)
+ {
+ KdbpPrint("No breakpoints.\n");
+ return TRUE;
+ }
+
+ KdbpPrint("Breakpoints:\n");
+ do
+ {
+ if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg,
+ &Enabled, &Global, &Process, &ConditionExpr))
+ {
+ continue;
+ }
+
+ if (l == KdbLastBreakPointNr)
+ {
+ str1 = "\x1b[1m*";
+ str2 = "\x1b[0m";
+ }
+ else
+ {
+ str1 = " ";
+ str2 = "";
+ }
+
+ if (Global)
+ {
+ GlobalOrLocal = " global";
+ }
+ else
+ {
+ GlobalOrLocal = Buffer;
+ sprintf(Buffer, " PID 0x%08lx",
+ (ULONG)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
+ }
+
+ if (Type == KdbBreakPointSoftware || Type == KdbBreakPointTemporary)
+ {
+ KdbpPrint(" %s%03d BPX 0x%08x%s%s%s%s%s\n",
+ str1, l, Address,
+ Enabled ? "" : " disabled",
GlobalOrLocal,
ConditionExpr ? " IF " : "",
ConditionExpr ? ConditionExpr : "",
str2);
- }
- }
- }
- while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0);
+ }
+ else if (Type == KdbBreakPointHardware)
+ {
+ if (!Enabled)
+ {
+ KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s disabled%s%s%s%s\n", str1, l, Address,
+ KDB_ACCESS_TYPE_TO_STRING(AccessType),
+ Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
+ GlobalOrLocal,
+ ConditionExpr ? " IF " : "",
+ ConditionExpr ? ConditionExpr : "",
+ str2);
+ }
+ else
+ {
+ KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s DR%d%s%s%s%s\n", str1, l, Address,
+ KDB_ACCESS_TYPE_TO_STRING(AccessType),
+ Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
+ DebugReg,
+ GlobalOrLocal,
+ ConditionExpr ? " IF " : "",
+ ConditionExpr ? ConditionExpr : "",
+ str2);
+ }
+ }
+ }
+ while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0);
- return TRUE;
+ return TRUE;
}
/*!\brief Enables, disables or clears a breakpoint.
*/
static BOOLEAN
-KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[])
+KdbpCmdEnableDisableClearBreakPoint(
+ ULONG Argc,
+ PCHAR Argv[])
{
- PCHAR pend;
- ULONG BreakPointNr;
-
- if (Argc < 2)
- {
- KdbpPrint("%s: argument required\n", Argv[0]);
- return TRUE;
- }
-
- pend = Argv[1];
- BreakPointNr = strtoul(Argv[1], &pend, 0);
- if (pend == Argv[1] || *pend != '\0')
- {
- KdbpPrint("%s: integer argument required\n", Argv[0]);
- return TRUE;
- }
-
- if (Argv[0][1] == 'e') /* enable */
- {
- KdbpEnableBreakPoint(BreakPointNr, NULL);
- }
- else if (Argv [0][1] == 'd') /* disable */
- {
- KdbpDisableBreakPoint(BreakPointNr, NULL);
- }
- else /* clear */
- {
- ASSERT(Argv[0][1] == 'c');
- KdbpDeleteBreakPoint(BreakPointNr, NULL);
- }
-
- return TRUE;
+ PCHAR pend;
+ ULONG BreakPointNr;
+
+ if (Argc < 2)
+ {
+ KdbpPrint("%s: argument required\n", Argv[0]);
+ return TRUE;
+ }
+
+ pend = Argv[1];
+ BreakPointNr = strtoul(Argv[1], &pend, 0);
+ if (pend == Argv[1] || *pend != '\0')
+ {
+ KdbpPrint("%s: integer argument required\n", Argv[0]);
+ return TRUE;
+ }
+
+ if (Argv[0][1] == 'e') /* enable */
+ {
+ KdbpEnableBreakPoint(BreakPointNr, NULL);
+ }
+ else if (Argv [0][1] == 'd') /* disable */
+ {
+ KdbpDisableBreakPoint(BreakPointNr, NULL);
+ }
+ else /* clear */
+ {
+ ASSERT(Argv[0][1] == 'c');
+ KdbpDeleteBreakPoint(BreakPointNr, NULL);
+ }
+
+ return TRUE;
}
/*!\brief Sets a software or hardware (memory) breakpoint at the given address.
static BOOLEAN
KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[])
{
- ULONGLONG Result = 0;
- ULONG_PTR Address;
- KDB_BREAKPOINT_TYPE Type;
- UCHAR Size = 0;
- KDB_ACCESS_TYPE AccessType = 0;
- ULONG AddressArgIndex, i;
- LONG ConditionArgIndex;
- BOOLEAN Global = TRUE;
-
- if (Argv[0][2] == 'x') /* software breakpoint */
- {
- if (Argc < 2)
- {
- KdbpPrint("bpx: Address argument required.\n");
- return TRUE;
- }
-
- AddressArgIndex = 1;
- Type = KdbBreakPointSoftware;
- }
- else /* memory breakpoint */
- {
- ASSERT(Argv[0][2] == 'm');
-
- if (Argc < 2)
- {
- KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
- return TRUE;
- }
-
- if (_stricmp(Argv[1], "x") == 0)
- AccessType = KdbAccessExec;
- else if (_stricmp(Argv[1], "r") == 0)
- AccessType = KdbAccessRead;
- else if (_stricmp(Argv[1], "w") == 0)
- AccessType = KdbAccessWrite;
- else if (_stricmp(Argv[1], "rw") == 0)
- AccessType = KdbAccessReadWrite;
- else
- {
- KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
- return TRUE;
- }
-
- if (Argc < 3)
- {
- KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
- return TRUE;
- }
- AddressArgIndex = 3;
- if (_stricmp(Argv[2], "byte") == 0)
- Size = 1;
- else if (_stricmp(Argv[2], "word") == 0)
- Size = 2;
- else if (_stricmp(Argv[2], "dword") == 0)
- Size = 4;
- else if (AccessType == KdbAccessExec)
- {
- Size = 1;
- AddressArgIndex--;
- }
- else
- {
- KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
- return TRUE;
- }
-
- if (Argc <= AddressArgIndex)
- {
- KdbpPrint("bpm: Address argument required.\n");
- return TRUE;
- }
-
- Type = KdbBreakPointHardware;
- }
-
- /* Put the arguments back together */
- ConditionArgIndex = -1;
- for (i = AddressArgIndex; i < (Argc-1); i++)
- {
- if (strcmp(Argv[i+1], "IF") == 0) /* IF found */
- {
- ConditionArgIndex = i + 2;
- if (ConditionArgIndex >= Argc)
- {
- KdbpPrint("%s: IF requires condition expression.\n", Argv[0]);
+ ULONGLONG Result = 0;
+ ULONG_PTR Address;
+ KDB_BREAKPOINT_TYPE Type;
+ UCHAR Size = 0;
+ KDB_ACCESS_TYPE AccessType = 0;
+ ULONG AddressArgIndex, i;
+ LONG ConditionArgIndex;
+ BOOLEAN Global = TRUE;
+
+ if (Argv[0][2] == 'x') /* software breakpoint */
+ {
+ if (Argc < 2)
+ {
+ KdbpPrint("bpx: Address argument required.\n");
return TRUE;
- }
- for (i = ConditionArgIndex; i < (Argc-1); i++)
- Argv[i][strlen(Argv[i])] = ' ';
- break;
- }
- Argv[i][strlen(Argv[i])] = ' ';
- }
-
- /* Evaluate the address expression */
- if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
- sizeof("kdb:> ")-1 + (Argv[AddressArgIndex]-Argv[0]),
- &Result))
- {
- return TRUE;
- }
- if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
- KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
- Address = (ULONG_PTR)Result;
-
- KdbpInsertBreakPoint(Address, Type, Size, AccessType,
- (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
- Global, NULL);
-
- return TRUE;
-}
+ }
-/*!\brief Lists threads or switches to another thread context.
- */
-static BOOLEAN
-KdbpCmdThread(ULONG Argc, PCHAR Argv[])
-{
- PLIST_ENTRY Entry;
- PETHREAD Thread = NULL;
- PEPROCESS Process = NULL;
- BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
- PULONG Esp;
- PULONG Ebp;
- ULONG Eip;
- ULONG ul = 0;
- PCHAR State, pend, str1, str2;
- static const PCHAR ThreadStateToString[DeferredReady+1] =
- { "Initialized", "Ready", "Running",
- "Standby", "Terminated", "Waiting",
- "Transition", "DeferredReady" };
- ASSERT(KdbCurrentProcess != NULL);
-
- if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
- {
- Process = KdbCurrentProcess;
-
- if (Argc >= 3)
- {
- ul = strtoul(Argv[2], &pend, 0);
- if (Argv[2] == pend)
- {
- KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
+ AddressArgIndex = 1;
+ Type = KdbBreakPointSoftware;
+ }
+ else /* memory breakpoint */
+ {
+ ASSERT(Argv[0][2] == 'm');
+
+ if (Argc < 2)
+ {
+ KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
return TRUE;
- }
- if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ul, &Process)))
- {
- KdbpPrint("thread: Invalid process id!\n");
+ }
+
+ if (_stricmp(Argv[1], "x") == 0)
+ AccessType = KdbAccessExec;
+ else if (_stricmp(Argv[1], "r") == 0)
+ AccessType = KdbAccessRead;
+ else if (_stricmp(Argv[1], "w") == 0)
+ AccessType = KdbAccessWrite;
+ else if (_stricmp(Argv[1], "rw") == 0)
+ AccessType = KdbAccessReadWrite;
+ else
+ {
+ KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
return TRUE;
- }
-
- /* Remember our reference */
- ReferencedProcess = TRUE;
- }
-
- Entry = Process->ThreadListHead.Flink;
- if (Entry == &Process->ThreadListHead)
- {
- if (Argc >= 3)
- KdbpPrint("No threads in process 0x%08x!\n", ul);
- else
- KdbpPrint("No threads in current process!\n");
- if (ReferencedProcess) ObDereferenceObject(Process);
- return TRUE;
- }
-
- KdbpPrint(" TID State Prior. Affinity EBP EIP\n");
- do
- {
- Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
-
- if (Thread == KdbCurrentThread)
- {
- str1 = "\x1b[1m*";
- str2 = "\x1b[0m";
- }
- else
- {
- str1 = " ";
- str2 = "";
- }
+ }
- if (Thread->Tcb.TrapFrame != NULL)
- {
- if (Thread->Tcb.TrapFrame->PreviousPreviousMode == KernelMode)
- Esp = (PULONG)Thread->Tcb.TrapFrame->TempEsp;
+ if (Argc < 3)
+ {
+ KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
+ return TRUE;
+ }
+
+ AddressArgIndex = 3;
+ if (_stricmp(Argv[2], "byte") == 0)
+ Size = 1;
+ else if (_stricmp(Argv[2], "word") == 0)
+ Size = 2;
+ else if (_stricmp(Argv[2], "dword") == 0)
+ Size = 4;
+ else if (AccessType == KdbAccessExec)
+ {
+ Size = 1;
+ AddressArgIndex--;
+ }
+ else
+ {
+ KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
+ return TRUE;
+ }
+
+ if (Argc <= AddressArgIndex)
+ {
+ KdbpPrint("bpm: Address argument required.\n");
+ return TRUE;
+ }
+
+ Type = KdbBreakPointHardware;
+ }
+
+ /* Put the arguments back together */
+ ConditionArgIndex = -1;
+ for (i = AddressArgIndex; i < (Argc-1); i++)
+ {
+ if (strcmp(Argv[i+1], "IF") == 0) /* IF found */
+ {
+ ConditionArgIndex = i + 2;
+ if (ConditionArgIndex >= Argc)
+ {
+ KdbpPrint("%s: IF requires condition expression.\n", Argv[0]);
+ return TRUE;
+ }
+
+ for (i = ConditionArgIndex; i < (Argc-1); i++)
+ Argv[i][strlen(Argv[i])] = ' ';
+
+ break;
+ }
+
+ Argv[i][strlen(Argv[i])] = ' ';
+ }
+
+ /* Evaluate the address expression */
+ if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
+ sizeof("kdb:> ")-1 + (Argv[AddressArgIndex]-Argv[0]),
+ &Result))
+ {
+ return TRUE;
+ }
+
+ if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
+ KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
+
+ Address = (ULONG_PTR)Result;
+
+ KdbpInsertBreakPoint(Address, Type, Size, AccessType,
+ (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
+ Global, NULL);
+
+ return TRUE;
+}
+
+/*!\brief Lists threads or switches to another thread context.
+ */
+static BOOLEAN
+KdbpCmdThread(
+ ULONG Argc,
+ PCHAR Argv[])
+{
+ PLIST_ENTRY Entry;
+ PETHREAD Thread = NULL;
+ PEPROCESS Process = NULL;
+ BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
+ PULONG Esp;
+ PULONG Ebp;
+ ULONG Eip;
+ ULONG ul = 0;
+ PCHAR State, pend, str1, str2;
+ static const PCHAR ThreadStateToString[DeferredReady+1] =
+ {
+ "Initialized", "Ready", "Running",
+ "Standby", "Terminated", "Waiting",
+ "Transition", "DeferredReady"
+ };
+
+ ASSERT(KdbCurrentProcess);
+
+ if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
+ {
+ Process = KdbCurrentProcess;
+
+ if (Argc >= 3)
+ {
+ ul = strtoul(Argv[2], &pend, 0);
+ if (Argv[2] == pend)
+ {
+ KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
+ return TRUE;
+ }
+
+ if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ul, &Process)))
+ {
+ KdbpPrint("thread: Invalid process id!\n");
+ return TRUE;
+ }
+
+ /* Remember our reference */
+ ReferencedProcess = TRUE;
+ }
+
+ Entry = Process->ThreadListHead.Flink;
+ if (Entry == &Process->ThreadListHead)
+ {
+ if (Argc >= 3)
+ KdbpPrint("No threads in process 0x%08x!\n", ul);
else
- Esp = (PULONG)Thread->Tcb.TrapFrame->HardwareEsp;
- Ebp = (PULONG)Thread->Tcb.TrapFrame->Ebp;
- Eip = Thread->Tcb.TrapFrame->Eip;
- }
- else
- {
- Esp = (PULONG)Thread->Tcb.KernelStack;
- Ebp = (PULONG)Esp[4];
- Eip = 0;
- if (Ebp != NULL) /* FIXME: Should we attach to the process to read Ebp[1]? */
- KdbpSafeReadMemory(&Eip, Ebp + 1, sizeof (Eip));
- }
- if (Thread->Tcb.State < (DeferredReady + 1))
- State = ThreadStateToString[Thread->Tcb.State];
- else
- State = "Unknown";
+ KdbpPrint("No threads in current process!\n");
+
+ if (ReferencedProcess)
+ ObDereferenceObject(Process);
- KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n",
- str1,
- Thread->Cid.UniqueThread,
- State,
- Thread->Tcb.Priority,
- Thread->Tcb.Affinity,
- Ebp,
- Eip,
- str2);
-
- Entry = Entry->Flink;
- }
- while (Entry != &Process->ThreadListHead);
-
- /* Release our reference, if any */
- if (ReferencedProcess) ObDereferenceObject(Process);
- }
- else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
- {
- if (Argc < 3)
- {
- KdbpPrint("thread attach: thread id argument required!\n");
- return TRUE;
- }
-
- ul = strtoul(Argv[2], &pend, 0);
- if (Argv[2] == pend)
- {
- KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
- return TRUE;
- }
- if (!KdbpAttachToThread((PVOID)ul))
- {
- return TRUE;
- }
- KdbpPrint("Attached to thread 0x%08x.\n", ul);
- }
- else
- {
- Thread = KdbCurrentThread;
-
- if (Argc >= 2)
- {
- ul = strtoul(Argv[1], &pend, 0);
- if (Argv[1] == pend)
- {
- KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
return TRUE;
- }
- if (!NT_SUCCESS(PsLookupThreadByThreadId((PVOID)ul, &Thread)))
- {
- KdbpPrint("thread: Invalid thread id!\n");
+ }
+
+ KdbpPrint(" TID State Prior. Affinity EBP EIP\n");
+ do
+ {
+ Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
+
+ if (Thread == KdbCurrentThread)
+ {
+ str1 = "\x1b[1m*";
+ str2 = "\x1b[0m";
+ }
+ else
+ {
+ str1 = " ";
+ str2 = "";
+ }
+
+ if (Thread->Tcb.TrapFrame)
+ {
+ if (Thread->Tcb.TrapFrame->PreviousPreviousMode == KernelMode)
+ Esp = (PULONG)Thread->Tcb.TrapFrame->TempEsp;
+ else
+ Esp = (PULONG)Thread->Tcb.TrapFrame->HardwareEsp;
+
+ Ebp = (PULONG)Thread->Tcb.TrapFrame->Ebp;
+ Eip = Thread->Tcb.TrapFrame->Eip;
+ }
+ else
+ {
+ Esp = (PULONG)Thread->Tcb.KernelStack;
+ Ebp = (PULONG)Esp[4];
+ Eip = 0;
+
+ if (Ebp) /* FIXME: Should we attach to the process to read Ebp[1]? */
+ KdbpSafeReadMemory(&Eip, Ebp + 1, sizeof (Eip));
+ }
+
+ if (Thread->Tcb.State < (DeferredReady + 1))
+ State = ThreadStateToString[Thread->Tcb.State];
+ else
+ State = "Unknown";
+
+ KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n",
+ str1,
+ Thread->Cid.UniqueThread,
+ State,
+ Thread->Tcb.Priority,
+ Thread->Tcb.Affinity,
+ Ebp,
+ Eip,
+ str2);
+
+ Entry = Entry->Flink;
+ }
+ while (Entry != &Process->ThreadListHead);
+
+ /* Release our reference, if any */
+ if (ReferencedProcess)
+ ObDereferenceObject(Process);
+ }
+ else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
+ {
+ if (Argc < 3)
+ {
+ KdbpPrint("thread attach: thread id argument required!\n");
+ return TRUE;
+ }
+
+ ul = strtoul(Argv[2], &pend, 0);
+ if (Argv[2] == pend)
+ {
+ KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
+ return TRUE;
+ }
+
+ if (!KdbpAttachToThread((PVOID)ul))
+ {
return TRUE;
- }
-
- /* Remember our reference */
- ReferencedThread = TRUE;
- }
-
- if (Thread->Tcb.State < (DeferredReady + 1))
- State = ThreadStateToString[Thread->Tcb.State];
- else
- State = "Unknown";
- KdbpPrint("%s"
- " TID: 0x%08x\n"
- " State: %s (0x%x)\n"
- " Priority: %d\n"
- " Affinity: 0x%08x\n"
- " Initial Stack: 0x%08x\n"
- " Stack Limit: 0x%08x\n"
- " Stack Base: 0x%08x\n"
- " Kernel Stack: 0x%08x\n"
- " Trap Frame: 0x%08x\n"
- " NPX State: %s (0x%x)\n",
- (Argc < 2) ? "Current Thread:\n" : "",
- Thread->Cid.UniqueThread,
- State, Thread->Tcb.State,
- Thread->Tcb.Priority,
- Thread->Tcb.Affinity,
- Thread->Tcb.InitialStack,
- Thread->Tcb.StackLimit,
- Thread->Tcb.StackBase,
- Thread->Tcb.KernelStack,
- Thread->Tcb.TrapFrame,
- NPX_STATE_TO_STRING(Thread->Tcb.NpxState), Thread->Tcb.NpxState);
-
- /* Release our reference if we had one */
- if (ReferencedThread) ObDereferenceObject(Thread);
- }
-
- return TRUE;
+ }
+
+ KdbpPrint("Attached to thread 0x%08x.\n", ul);
+ }
+ else
+ {
+ Thread = KdbCurrentThread;
+
+ if (Argc >= 2)
+ {
+ ul = strtoul(Argv[1], &pend, 0);
+ if (Argv[1] == pend)
+ {
+ KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
+ return TRUE;
+ }
+
+ if (!NT_SUCCESS(PsLookupThreadByThreadId((PVOID)ul, &Thread)))
+ {
+ KdbpPrint("thread: Invalid thread id!\n");
+ return TRUE;
+ }
+
+ /* Remember our reference */
+ ReferencedThread = TRUE;
+ }
+
+ if (Thread->Tcb.State < (DeferredReady + 1))
+ State = ThreadStateToString[Thread->Tcb.State];
+ else
+ State = "Unknown";
+
+ KdbpPrint("%s"
+ " TID: 0x%08x\n"
+ " State: %s (0x%x)\n"
+ " Priority: %d\n"
+ " Affinity: 0x%08x\n"
+ " Initial Stack: 0x%08x\n"
+ " Stack Limit: 0x%08x\n"
+ " Stack Base: 0x%08x\n"
+ " Kernel Stack: 0x%08x\n"
+ " Trap Frame: 0x%08x\n"
+ " NPX State: %s (0x%x)\n",
+ (Argc < 2) ? "Current Thread:\n" : "",
+ Thread->Cid.UniqueThread,
+ State, Thread->Tcb.State,
+ Thread->Tcb.Priority,
+ Thread->Tcb.Affinity,
+ Thread->Tcb.InitialStack,
+ Thread->Tcb.StackLimit,
+ Thread->Tcb.StackBase,
+ Thread->Tcb.KernelStack,
+ Thread->Tcb.TrapFrame,
+ NPX_STATE_TO_STRING(Thread->Tcb.NpxState), Thread->Tcb.NpxState);
+
+ /* Release our reference if we had one */
+ if (ReferencedThread)
+ ObDereferenceObject(Thread);
+ }
+
+ return TRUE;
}
/*!\brief Lists processes or switches to another process context.
*/
static BOOLEAN
-KdbpCmdProc(ULONG Argc, PCHAR Argv[])
+KdbpCmdProc(
+ ULONG Argc,
+ PCHAR Argv[])
{
- PLIST_ENTRY Entry;
- PEPROCESS Process;
- BOOLEAN ReferencedProcess = FALSE;
- PCHAR State, pend, str1, str2;
- ULONG ul;
- extern LIST_ENTRY PsActiveProcessHead;
-
- if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
- {
- Entry = PsActiveProcessHead.Flink;
- if (!Entry || Entry == &PsActiveProcessHead)
- {
- KdbpPrint("No processes in the system!\n");
- return TRUE;
- }
-
- KdbpPrint(" PID State Filename\n");
- do
- {
- Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
-
- if (Process == KdbCurrentProcess)
- {
- str1 = "\x1b[1m*";
- str2 = "\x1b[0m";
- }
- else
- {
- str1 = " ";
- str2 = "";
- }
-
- State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
- ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
-
- KdbpPrint(" %s0x%08x %-10s %s%s\n",
- str1,
- Process->UniqueProcessId,
- State,
- Process->ImageFileName,
- str2);
-
- Entry = Entry->Flink;
- }
- while(Entry != &PsActiveProcessHead);
- }
- else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
- {
- if (Argc < 3)
- {
- KdbpPrint("process attach: process id argument required!\n");
- return TRUE;
- }
-
- ul = strtoul(Argv[2], &pend, 0);
- if (Argv[2] == pend)
- {
- KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
- return TRUE;
- }
- if (!KdbpAttachToProcess((PVOID)ul))
- {
- return TRUE;
- }
- KdbpPrint("Attached to process 0x%08x, thread 0x%08x.\n", (ULONG)ul,
- (ULONG)KdbCurrentThread->Cid.UniqueThread);
- }
- else
- {
- Process = KdbCurrentProcess;
-
- if (Argc >= 2)
- {
- ul = strtoul(Argv[1], &pend, 0);
- if (Argv[1] == pend)
- {
- KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
+ PLIST_ENTRY Entry;
+ PEPROCESS Process;
+ BOOLEAN ReferencedProcess = FALSE;
+ PCHAR State, pend, str1, str2;
+ ULONG ul;
+ extern LIST_ENTRY PsActiveProcessHead;
+
+ if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
+ {
+ Entry = PsActiveProcessHead.Flink;
+ if (!Entry || Entry == &PsActiveProcessHead)
+ {
+ KdbpPrint("No processes in the system!\n");
+ return TRUE;
+ }
+
+ KdbpPrint(" PID State Filename\n");
+ do
+ {
+ Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
+
+ if (Process == KdbCurrentProcess)
+ {
+ str1 = "\x1b[1m*";
+ str2 = "\x1b[0m";
+ }
+ else
+ {
+ str1 = " ";
+ str2 = "";
+ }
+
+ State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
+ ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
+
+ KdbpPrint(" %s0x%08x %-10s %s%s\n",
+ str1,
+ Process->UniqueProcessId,
+ State,
+ Process->ImageFileName,
+ str2);
+
+ Entry = Entry->Flink;
+ }
+ while(Entry != &PsActiveProcessHead);
+ }
+ else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
+ {
+ if (Argc < 3)
+ {
+ KdbpPrint("process attach: process id argument required!\n");
+ return TRUE;
+ }
+
+ ul = strtoul(Argv[2], &pend, 0);
+ if (Argv[2] == pend)
+ {
+ KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
return TRUE;
- }
- if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ul, &Process)))
- {
- KdbpPrint("proc: Invalid process id!\n");
+ }
+
+ if (!KdbpAttachToProcess((PVOID)ul))
+ {
return TRUE;
- }
-
- /* Remember our reference */
- ReferencedProcess = TRUE;
- }
-
- State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
- ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
- KdbpPrint("%s"
- " PID: 0x%08x\n"
- " State: %s (0x%x)\n"
- " Image Filename: %s\n",
- (Argc < 2) ? "Current process:\n" : "",
- Process->UniqueProcessId,
- State, Process->Pcb.State,
- Process->ImageFileName);
+ }
+
+ KdbpPrint("Attached to process 0x%08x, thread 0x%08x.\n", (ULONG)ul,
+ (ULONG)KdbCurrentThread->Cid.UniqueThread);
+ }
+ else
+ {
+ Process = KdbCurrentProcess;
+
+ if (Argc >= 2)
+ {
+ ul = strtoul(Argv[1], &pend, 0);
+ if (Argv[1] == pend)
+ {
+ KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
+ return TRUE;
+ }
+
+ if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ul, &Process)))
+ {
+ KdbpPrint("proc: Invalid process id!\n");
+ return TRUE;
+ }
+
+ /* Remember our reference */
+ ReferencedProcess = TRUE;
+ }
+
+ State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
+ ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
+ KdbpPrint("%s"
+ " PID: 0x%08x\n"
+ " State: %s (0x%x)\n"
+ " Image Filename: %s\n",
+ (Argc < 2) ? "Current process:\n" : "",
+ Process->UniqueProcessId,
+ State, Process->Pcb.State,
+ Process->ImageFileName);
/* Release our reference, if any */
- if (ReferencedProcess) ObDereferenceObject(Process);
- }
+ if (ReferencedProcess)
+ ObDereferenceObject(Process);
+ }
- return TRUE;
+ return TRUE;
}
/*!\brief Lists loaded modules or the one containing the specified address.
*/
static BOOLEAN
-KdbpCmdMod(ULONG Argc, PCHAR Argv[])
+KdbpCmdMod(
+ ULONG Argc,
+ PCHAR Argv[])
{
- ULONGLONG Result = 0;
- ULONG_PTR Address;
- KDB_MODULE_INFO Info;
- BOOLEAN DisplayOnlyOneModule = FALSE;
- INT i = 0;
-
- if (Argc >= 2)
- {
- /* Put the arguments back together */
- Argc--;
- while (--Argc >= 1)
- Argv[Argc][strlen(Argv[Argc])] = ' ';
-
- /* Evaluate the expression */
- if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
- {
- return TRUE;
- }
- if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
- KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
- Address = (ULONG_PTR)Result;
-
- if (!KdbpSymFindModuleByAddress((PVOID)Address, &Info))
- {
- KdbpPrint("No module containing address 0x%p found!\n", Address);
- return TRUE;
- }
- DisplayOnlyOneModule = TRUE;
- }
- else
- {
- if (!KdbpSymFindModuleByIndex(0, &Info))
- {
- ULONG_PTR ntoskrnlBase = ((ULONG_PTR)KdbpCmdMod) & 0xfff00000;
- KdbpPrint(" Base Size Name\n");
- KdbpPrint(" %08x %08x %s\n", ntoskrnlBase, 0, "ntoskrnl.exe");
- return TRUE;
- }
- i = 1;
- }
-
- KdbpPrint(" Base Size Name\n");
- for (;;)
- {
- KdbpPrint(" %08x %08x %ws\n", Info.Base, Info.Size, Info.Name);
-
- if ((!DisplayOnlyOneModule && !KdbpSymFindModuleByIndex(i++, &Info)) ||
- DisplayOnlyOneModule)
- {
- break;
- }
- }
-
- return TRUE;
+ ULONGLONG Result = 0;
+ ULONG_PTR Address;
+ KDB_MODULE_INFO Info;
+ BOOLEAN DisplayOnlyOneModule = FALSE;
+ INT i = 0;
+
+ if (Argc >= 2)
+ {
+ /* Put the arguments back together */
+ Argc--;
+ while (--Argc >= 1)
+ Argv[Argc][strlen(Argv[Argc])] = ' ';
+
+ /* Evaluate the expression */
+ if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
+ {
+ return TRUE;
+ }
+
+ if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
+ KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
+
+ Address = (ULONG_PTR)Result;
+
+ if (!KdbpSymFindModuleByAddress((PVOID)Address, &Info))
+ {
+ KdbpPrint("No module containing address 0x%p found!\n", Address);
+ return TRUE;
+ }
+
+ DisplayOnlyOneModule = TRUE;
+ }
+ else
+ {
+ if (!KdbpSymFindModuleByIndex(0, &Info))
+ {
+ ULONG_PTR ntoskrnlBase = ((ULONG_PTR)KdbpCmdMod) & 0xfff00000;
+ KdbpPrint(" Base Size Name\n");
+ KdbpPrint(" %08x %08x %s\n", ntoskrnlBase, 0, "ntoskrnl.exe");
+ return TRUE;
+ }
+
+ i = 1;
+ }
+
+ KdbpPrint(" Base Size Name\n");
+ for (;;)
+ {
+ KdbpPrint(" %08x %08x %ws\n", Info.Base, Info.Size, Info.Name);
+
+ if ((!DisplayOnlyOneModule && !KdbpSymFindModuleByIndex(i++, &Info)) ||
+ DisplayOnlyOneModule)
+ {
+ break;
+ }
+ }
+
+ return TRUE;
}
/*!\brief Displays GDT, LDT or IDTd.
*/
static BOOLEAN
-KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[])
+KdbpCmdGdtLdtIdt(
+ ULONG Argc,
+ PCHAR Argv[])
{
- KDESCRIPTOR Reg = {0};
- ULONG SegDesc[2];
- ULONG SegBase;
- ULONG SegLimit;
- PCHAR SegType;
- USHORT SegSel;
- UCHAR Type, Dpl;
- INT i;
- ULONG ul;
-
- if (Argv[0][0] == 'i')
- {
- /* Read IDTR */
- Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Reg.Limit);
-
- if (Reg.Limit < 7)
- {
- KdbpPrint("Interrupt descriptor table is empty.\n");
- return TRUE;
- }
- KdbpPrint("IDT Base: 0x%08x Limit: 0x%04x\n", Reg.Base, Reg.Limit);
- KdbpPrint(" Idx Type Seg. Sel. Offset DPL\n");
- for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
- {
- if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)(Reg.Base + i), sizeof(SegDesc))))
- {
- KdbpPrint("Couldn't access memory at 0x%08x!\n", Reg.Base + i);
- return TRUE;
- }
-
- Dpl = ((SegDesc[1] >> 13) & 3);
- if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
- SegType = "TASKGATE";
- else if ((SegDesc[1] & 0x1fe0) == 0x0e00) /* 32 bit Interrupt gate */
- SegType = "INTGATE32";
- else if ((SegDesc[1] & 0x1fe0) == 0x0600) /* 16 bit Interrupt gate */
- SegType = "INTGATE16";
- else if ((SegDesc[1] & 0x1fe0) == 0x0f00) /* 32 bit Trap gate */
- SegType = "TRAPGATE32";
- else if ((SegDesc[1] & 0x1fe0) == 0x0700) /* 16 bit Trap gate */
- SegType = "TRAPGATE16";
- else
- SegType = "UNKNOWN";
-
- if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
- {
- KdbpPrint(" %03d %-10s [NP] [NP] %02d\n",
- i / 8, SegType, Dpl);
- }
- else if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
- {
- SegSel = SegDesc[0] >> 16;
- KdbpPrint(" %03d %-10s 0x%04x %02d\n",
- i / 8, SegType, SegSel, Dpl);
- }
- else
- {
- SegSel = SegDesc[0] >> 16;
- SegBase = (SegDesc[1] & 0xffff0000) | (SegDesc[0] & 0x0000ffff);
- KdbpPrint(" %03d %-10s 0x%04x 0x%08x %02d\n",
- i / 8, SegType, SegSel, SegBase, Dpl);
- }
- }
- }
- else
- {
- ul = 0;
- if (Argv[0][0] == 'g')
- {
- /* Read GDTR */
- Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&Reg.Limit);
- i = 8;
- }
- else
- {
- ASSERT(Argv[0][0] == 'l');
- /* Read LDTR */
- Ke386GetLocalDescriptorTable(Reg.Limit);
- i = 0;
- ul = 1 << 2;
- }
-
- if (Reg.Limit < 7)
- {
- KdbpPrint("%s descriptor table is empty.\n",
- Argv[0][0] == 'g' ? "Global" : "Local");
- return TRUE;
- }
- KdbpPrint("%cDT Base: 0x%08x Limit: 0x%04x\n",
- Argv[0][0] == 'g' ? 'G' : 'L', Reg.Base, Reg.Limit);
- KdbpPrint(" Idx Sel. Type Base Limit DPL Attribs\n");
- for ( ; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
- {
- if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)(Reg.Base + i), sizeof(SegDesc))))
- {
- KdbpPrint("Couldn't access memory at 0x%08x!\n", Reg.Base + i);
+ KDESCRIPTOR Reg = {0};
+ ULONG SegDesc[2];
+ ULONG SegBase;
+ ULONG SegLimit;
+ PCHAR SegType;
+ USHORT SegSel;
+ UCHAR Type, Dpl;
+ INT i;
+ ULONG ul;
+
+ if (Argv[0][0] == 'i')
+ {
+ /* Read IDTR */
+ Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Reg.Limit);
+
+ if (Reg.Limit < 7)
+ {
+ KdbpPrint("Interrupt descriptor table is empty.\n");
return TRUE;
- }
- Dpl = ((SegDesc[1] >> 13) & 3);
- Type = ((SegDesc[1] >> 8) & 0xf);
-
- SegBase = SegDesc[0] >> 16;
- SegBase |= (SegDesc[1] & 0xff) << 16;
- SegBase |= SegDesc[1] & 0xff000000;
- SegLimit = SegDesc[0] & 0x0000ffff;
- SegLimit |= (SegDesc[1] >> 16) & 0xf;
- if ((SegDesc[1] & (1 << 23)) != 0)
- {
- SegLimit *= 4096;
- SegLimit += 4095;
- }
- else
- {
- SegLimit++;
- }
-
- if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
- {
- switch (Type)
+ }
+
+ KdbpPrint("IDT Base: 0x%08x Limit: 0x%04x\n", Reg.Base, Reg.Limit);
+ KdbpPrint(" Idx Type Seg. Sel. Offset DPL\n");
+
+ for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
+ {
+ if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)(Reg.Base + i), sizeof(SegDesc))))
{
- case 1: SegType = "TSS16(Avl)"; break;
- case 2: SegType = "LDT"; break;
- case 3: SegType = "TSS16(Busy)"; break;
- case 4: SegType = "CALLGATE16"; break;
- case 5: SegType = "TASKGATE"; break;
- case 6: SegType = "INTGATE16"; break;
- case 7: SegType = "TRAPGATE16"; break;
- case 9: SegType = "TSS32(Avl)"; break;
- case 11: SegType = "TSS32(Busy)"; break;
- case 12: SegType = "CALLGATE32"; break;
- case 14: SegType = "INTGATE32"; break;
- case 15: SegType = "INTGATE32"; break;
- default: SegType = "UNKNOWN"; break;
+ KdbpPrint("Couldn't access memory at 0x%08x!\n", Reg.Base + i);
+ return TRUE;
}
- if (!(Type >= 1 && Type <= 3) &&
- Type != 9 && Type != 11)
+
+ Dpl = ((SegDesc[1] >> 13) & 3);
+ if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
+ SegType = "TASKGATE";
+ else if ((SegDesc[1] & 0x1fe0) == 0x0e00) /* 32 bit Interrupt gate */
+ SegType = "INTGATE32";
+ else if ((SegDesc[1] & 0x1fe0) == 0x0600) /* 16 bit Interrupt gate */
+ SegType = "INTGATE16";
+ else if ((SegDesc[1] & 0x1fe0) == 0x0f00) /* 32 bit Trap gate */
+ SegType = "TRAPGATE32";
+ else if ((SegDesc[1] & 0x1fe0) == 0x0700) /* 16 bit Trap gate */
+ SegType = "TRAPGATE16";
+ else
+ SegType = "UNKNOWN";
+
+ if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
+ {
+ KdbpPrint(" %03d %-10s [NP] [NP] %02d\n",
+ i / 8, SegType, Dpl);
+ }
+ else if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
{
- SegBase = 0;
- SegLimit = 0;
+ SegSel = SegDesc[0] >> 16;
+ KdbpPrint(" %03d %-10s 0x%04x %02d\n",
+ i / 8, SegType, SegSel, Dpl);
}
- }
- else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
- {
- if ((SegDesc[1] & (1 << 22)) != 0)
- SegType = "DATA32";
else
- SegType = "DATA16";
+ {
+ SegSel = SegDesc[0] >> 16;
+ SegBase = (SegDesc[1] & 0xffff0000) | (SegDesc[0] & 0x0000ffff);
+ KdbpPrint(" %03d %-10s 0x%04x 0x%08x %02d\n",
+ i / 8, SegType, SegSel, SegBase, Dpl);
+ }
+ }
+ }
+ else
+ {
+ ul = 0;
+
+ if (Argv[0][0] == 'g')
+ {
+ /* Read GDTR */
+ Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&Reg.Limit);
+ i = 8;
+ }
+ else
+ {
+ ASSERT(Argv[0][0] == 'l');
+
+ /* Read LDTR */
+ Ke386GetLocalDescriptorTable(Reg.Limit);
+ i = 0;
+ ul = 1 << 2;
+ }
+
+ if (Reg.Limit < 7)
+ {
+ KdbpPrint("%s descriptor table is empty.\n",
+ Argv[0][0] == 'g' ? "Global" : "Local");
+ return TRUE;
+ }
+
+ KdbpPrint("%cDT Base: 0x%08x Limit: 0x%04x\n",
+ Argv[0][0] == 'g' ? 'G' : 'L', Reg.Base, Reg.Limit);
+ KdbpPrint(" Idx Sel. Type Base Limit DPL Attribs\n");
+
+ for (; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
+ {
+ if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)(Reg.Base + i), sizeof(SegDesc))))
+ {
+ KdbpPrint("Couldn't access memory at 0x%08x!\n", Reg.Base + i);
+ return TRUE;
+ }
+
+ Dpl = ((SegDesc[1] >> 13) & 3);
+ Type = ((SegDesc[1] >> 8) & 0xf);
+
+ SegBase = SegDesc[0] >> 16;
+ SegBase |= (SegDesc[1] & 0xff) << 16;
+ SegBase |= SegDesc[1] & 0xff000000;
+ SegLimit = SegDesc[0] & 0x0000ffff;
+ SegLimit |= (SegDesc[1] >> 16) & 0xf;
- }
- else /* Code segment */
- {
- if ((SegDesc[1] & (1 << 22)) != 0)
- SegType = "CODE32";
+ if ((SegDesc[1] & (1 << 23)) != 0)
+ {
+ SegLimit *= 4096;
+ SegLimit += 4095;
+ }
else
- SegType = "CODE16";
- }
-
- if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
- {
- KdbpPrint(" %03d 0x%04x %-11s [NP] [NP] %02d NP\n",
- i / 8, i | Dpl | ul, SegType, Dpl);
- }
- else
- {
- KdbpPrint(" %03d 0x%04x %-11s 0x%08x 0x%08x %02d ",
- i / 8, i | Dpl | ul, SegType, SegBase, SegLimit, Dpl);
+ {
+ SegLimit++;
+ }
+
if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
{
- /* FIXME: Display system segment */
+ switch (Type)
+ {
+ case 1: SegType = "TSS16(Avl)"; break;
+ case 2: SegType = "LDT"; break;
+ case 3: SegType = "TSS16(Busy)"; break;
+ case 4: SegType = "CALLGATE16"; break;
+ case 5: SegType = "TASKGATE"; break;
+ case 6: SegType = "INTGATE16"; break;
+ case 7: SegType = "TRAPGATE16"; break;
+ case 9: SegType = "TSS32(Avl)"; break;
+ case 11: SegType = "TSS32(Busy)"; break;
+ case 12: SegType = "CALLGATE32"; break;
+ case 14: SegType = "INTGATE32"; break;
+ case 15: SegType = "INTGATE32"; break;
+ default: SegType = "UNKNOWN"; break;
+ }
+
+ if (!(Type >= 1 && Type <= 3) &&
+ Type != 9 && Type != 11)
+ {
+ SegBase = 0;
+ SegLimit = 0;
+ }
}
else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
{
- if ((SegDesc[1] & (1 << 10)) != 0) /* Expand-down */
- KdbpPrint(" E");
- KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/W" : " R");
- if ((SegDesc[1] & (1 << 8)) != 0)
- KdbpPrint(" A");
+ if ((SegDesc[1] & (1 << 22)) != 0)
+ SegType = "DATA32";
+ else
+ SegType = "DATA16";
}
else /* Code segment */
{
- if ((SegDesc[1] & (1 << 10)) != 0) /* Conforming */
- KdbpPrint(" C");
- KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/X" : " X");
- if ((SegDesc[1] & (1 << 8)) != 0)
- KdbpPrint(" A");
+ if ((SegDesc[1] & (1 << 22)) != 0)
+ SegType = "CODE32";
+ else
+ SegType = "CODE16";
}
- if ((SegDesc[1] & (1 << 20)) != 0)
- KdbpPrint(" AVL");
- KdbpPrint("\n");
- }
- }
- }
- return TRUE;
+ if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
+ {
+ KdbpPrint(" %03d 0x%04x %-11s [NP] [NP] %02d NP\n",
+ i / 8, i | Dpl | ul, SegType, Dpl);
+ }
+ else
+ {
+ KdbpPrint(" %03d 0x%04x %-11s 0x%08x 0x%08x %02d ",
+ i / 8, i | Dpl | ul, SegType, SegBase, SegLimit, Dpl);
+
+ if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
+ {
+ /* FIXME: Display system segment */
+ }
+ else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
+ {
+ if ((SegDesc[1] & (1 << 10)) != 0) /* Expand-down */
+ KdbpPrint(" E");
+
+ KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/W" : " R");
+
+ if ((SegDesc[1] & (1 << 8)) != 0)
+ KdbpPrint(" A");
+ }
+ else /* Code segment */
+ {
+ if ((SegDesc[1] & (1 << 10)) != 0) /* Conforming */
+ KdbpPrint(" C");
+
+ KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/X" : " X");
+
+ if ((SegDesc[1] & (1 << 8)) != 0)
+ KdbpPrint(" A");
+ }
+
+ if ((SegDesc[1] & (1 << 20)) != 0)
+ KdbpPrint(" AVL");
+
+ KdbpPrint("\n");
+ }
+ }
+ }
+
+ return TRUE;
}
/*!\brief Displays the KPCR
*/
static BOOLEAN
-KdbpCmdPcr(ULONG Argc, PCHAR Argv[])
+KdbpCmdPcr(
+ ULONG Argc,
+ PCHAR Argv[])
{
- PKIPCR Pcr = (PKIPCR)KeGetPcr();
-
- KdbpPrint("Current PCR is at 0x%08x.\n", (INT)Pcr);
- KdbpPrint(" Tib.ExceptionList: 0x%08x\n"
- " Tib.StackBase: 0x%08x\n"
- " Tib.StackLimit: 0x%08x\n"
- " Tib.SubSystemTib: 0x%08x\n"
- " Tib.FiberData/Version: 0x%08x\n"
- " Tib.ArbitraryUserPointer: 0x%08x\n"
- " Tib.Self: 0x%08x\n"
- " Self: 0x%08x\n"
- " PCRCB: 0x%08x\n"
- " Irql: 0x%02x\n"
- " IRR: 0x%08x\n"
- " IrrActive: 0x%08x\n"
- " IDR: 0x%08x\n"
- " KdVersionBlock: 0x%08x\n"
- " IDT: 0x%08x\n"
- " GDT: 0x%08x\n"
- " TSS: 0x%08x\n"
- " MajorVersion: 0x%04x\n"
- " MinorVersion: 0x%04x\n"
- " SetMember: 0x%08x\n"
- " StallScaleFactor: 0x%08x\n"
- " Number: 0x%02x\n"
- " L2CacheAssociativity: 0x%02x\n"
- " VdmAlert: 0x%08x\n"
- " L2CacheSize: 0x%08x\n"
- " InterruptMode: 0x%08x\n",
- Pcr->NtTib.ExceptionList, Pcr->NtTib.StackBase, Pcr->NtTib.StackLimit,
- Pcr->NtTib.SubSystemTib, Pcr->NtTib.FiberData, Pcr->NtTib.ArbitraryUserPointer,
- Pcr->NtTib.Self, Pcr->Self, Pcr->Prcb, Pcr->Irql, Pcr->IRR, Pcr->IrrActive,
- Pcr->IDR, Pcr->KdVersionBlock, Pcr->IDT, Pcr->GDT, Pcr->TSS,
- Pcr->MajorVersion, Pcr->MinorVersion, Pcr->SetMember, Pcr->StallScaleFactor,
- Pcr->Number, Pcr->L2CacheAssociativity,
- Pcr->VdmAlert, Pcr->SecondLevelCacheSize, Pcr->InterruptMode);
-
- return TRUE;
+ PKIPCR Pcr = (PKIPCR)KeGetPcr();
+
+ KdbpPrint("Current PCR is at 0x%08x.\n", (INT)Pcr);
+ KdbpPrint(" Tib.ExceptionList: 0x%08x\n"
+ " Tib.StackBase: 0x%08x\n"
+ " Tib.StackLimit: 0x%08x\n"
+ " Tib.SubSystemTib: 0x%08x\n"
+ " Tib.FiberData/Version: 0x%08x\n"
+ " Tib.ArbitraryUserPointer: 0x%08x\n"
+ " Tib.Self: 0x%08x\n"
+ " Self: 0x%08x\n"
+ " PCRCB: 0x%08x\n"
+ " Irql: 0x%02x\n"
+ " IRR: 0x%08x\n"
+ " IrrActive: 0x%08x\n"
+ " IDR: 0x%08x\n"
+ " KdVersionBlock: 0x%08x\n"
+ " IDT: 0x%08x\n"
+ " GDT: 0x%08x\n"
+ " TSS: 0x%08x\n"
+ " MajorVersion: 0x%04x\n"
+ " MinorVersion: 0x%04x\n"
+ " SetMember: 0x%08x\n"
+ " StallScaleFactor: 0x%08x\n"
+ " Number: 0x%02x\n"
+ " L2CacheAssociativity: 0x%02x\n"
+ " VdmAlert: 0x%08x\n"
+ " L2CacheSize: 0x%08x\n"
+ " InterruptMode: 0x%08x\n",
+ Pcr->NtTib.ExceptionList, Pcr->NtTib.StackBase, Pcr->NtTib.StackLimit,
+ Pcr->NtTib.SubSystemTib, Pcr->NtTib.FiberData, Pcr->NtTib.ArbitraryUserPointer,
+ Pcr->NtTib.Self, Pcr->Self, Pcr->Prcb, Pcr->Irql, Pcr->IRR, Pcr->IrrActive,
+ Pcr->IDR, Pcr->KdVersionBlock, Pcr->IDT, Pcr->GDT, Pcr->TSS,
+ Pcr->MajorVersion, Pcr->MinorVersion, Pcr->SetMember, Pcr->StallScaleFactor,
+ Pcr->Number, Pcr->L2CacheAssociativity,
+ Pcr->VdmAlert, Pcr->SecondLevelCacheSize, Pcr->InterruptMode);
+
+ return TRUE;
}
/*!\brief Displays the TSS
*/
static BOOLEAN
-KdbpCmdTss(ULONG Argc, PCHAR Argv[])
+KdbpCmdTss(
+ ULONG Argc,
+ PCHAR Argv[])
{
- KTSS *Tss = KeGetPcr()->TSS;
-
- KdbpPrint("Current TSS is at 0x%08x.\n", (INT)Tss);
- KdbpPrint(" Eip: 0x%08x\n"
- " Es: 0x%04x\n"
- " Cs: 0x%04x\n"
- " Ss: 0x%04x\n"
- " Ds: 0x%04x\n"
- " Fs: 0x%04x\n"
- " Gs: 0x%04x\n"
- " IoMapBase: 0x%04x\n",
- Tss->Eip, Tss->Es, Tss->Cs, Tss->Ds, Tss->Fs, Tss->Gs, Tss->IoMapBase);
- return TRUE;
+ KTSS *Tss = KeGetPcr()->TSS;
+
+ KdbpPrint("Current TSS is at 0x%08x.\n", (INT)Tss);
+ KdbpPrint(" Eip: 0x%08x\n"
+ " Es: 0x%04x\n"
+ " Cs: 0x%04x\n"
+ " Ss: 0x%04x\n"
+ " Ds: 0x%04x\n"
+ " Fs: 0x%04x\n"
+ " Gs: 0x%04x\n"
+ " IoMapBase: 0x%04x\n",
+ Tss->Eip, Tss->Es, Tss->Cs, Tss->Ds, Tss->Fs, Tss->Gs, Tss->IoMapBase);
+
+ return TRUE;
}
/*!\brief Bugchecks the system.
*/
static BOOLEAN
-KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[])
+KdbpCmdBugCheck(
+ ULONG Argc,
+ PCHAR Argv[])
{
- /* Set the flag and quit looping */
- KdbpBugCheckRequested = TRUE;
- return FALSE;
+ /* Set the flag and quit looping */
+ KdbpBugCheckRequested = TRUE;
+
+ return FALSE;
}
/*!\brief Sets or displays a config variables value.
*/
static BOOLEAN
-KdbpCmdSet(ULONG Argc, PCHAR Argv[])
+KdbpCmdSet(
+ ULONG Argc,
+ PCHAR Argv[])
{
- LONG l;
- BOOLEAN First;
- PCHAR pend = 0;
- KDB_ENTER_CONDITION ConditionFirst = KdbDoNotEnter;
- KDB_ENTER_CONDITION ConditionLast = KdbDoNotEnter;
- static const PCHAR ExceptionNames[21] =
- { "ZERODEVIDE", "DEBUGTRAP", "NMI", "INT3", "OVERFLOW", "BOUND", "INVALIDOP",
+ LONG l;
+ BOOLEAN First;
+ PCHAR pend = 0;
+ KDB_ENTER_CONDITION ConditionFirst = KdbDoNotEnter;
+ KDB_ENTER_CONDITION ConditionLast = KdbDoNotEnter;
+
+ static const PCHAR ExceptionNames[21] =
+ {
+ "ZERODEVIDE", "DEBUGTRAP", "NMI", "INT3", "OVERFLOW", "BOUND", "INVALIDOP",
"NOMATHCOP", "DOUBLEFAULT", "RESERVED(9)", "INVALIDTSS", "SEGMENTNOTPRESENT",
"STACKFAULT", "GPF", "PAGEFAULT", "RESERVED(15)", "MATHFAULT", "ALIGNMENTCHECK",
- "MACHINECHECK", "SIMDFAULT", "OTHERS" };
-
- if (Argc == 1)
- {
- KdbpPrint("Available settings:\n");
- KdbpPrint(" syntax [intel|at&t]\n");
- KdbpPrint(" condition [exception|*] [first|last] [never|always|kmode|umode]\n");
- KdbpPrint(" break_on_module_load [true|false]\n");
- }
- else if (strcmp(Argv[1], "syntax") == 0)
- {
- if (Argc == 2)
- KdbpPrint("syntax = %s\n", KdbUseIntelSyntax ? "intel" : "at&t");
- else if (Argc >= 3)
- {
- if (_stricmp(Argv[2], "intel") == 0)
- KdbUseIntelSyntax = TRUE;
- else if (_stricmp(Argv[2], "at&t") == 0)
- KdbUseIntelSyntax = FALSE;
- else
- KdbpPrint("Unknown syntax '%s'.\n", Argv[2]);
- }
- }
- else if (strcmp(Argv[1], "condition") == 0)
- {
- if (Argc == 2)
- {
- KdbpPrint("Conditions: (First) (Last)\n");
- for (l = 0; l < RTL_NUMBER_OF(ExceptionNames) - 1; l++)
- {
- if (ExceptionNames[l] == NULL)
- continue;
- if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
- ASSERT(0);
- if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
- ASSERT(0);
- KdbpPrint(" #%02d %-20s %-8s %-8s\n", l, ExceptionNames[l],
- KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
- KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
- }
- ASSERT(l == (RTL_NUMBER_OF(ExceptionNames) - 1));
- KdbpPrint(" %-20s %-8s %-8s\n", ExceptionNames[l],
- KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
- KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
- }
- else
- {
- if (Argc >= 5 && strcmp(Argv[2], "*") == 0) /* Allow * only when setting condition */
- l = -1;
- else
- {
- l = strtoul(Argv[2], &pend, 0);
- if (Argv[2] == pend)
- {
- for (l = 0; l < RTL_NUMBER_OF(ExceptionNames); l++)
- {
- if (ExceptionNames[l] == NULL)
- continue;
- if (_stricmp(ExceptionNames[l], Argv[2]) == 0)
- break;
- }
- }
- if (l >= RTL_NUMBER_OF(ExceptionNames))
+ "MACHINECHECK", "SIMDFAULT", "OTHERS"
+ };
+
+ if (Argc == 1)
+ {
+ KdbpPrint("Available settings:\n");
+ KdbpPrint(" syntax [intel|at&t]\n");
+ KdbpPrint(" condition [exception|*] [first|last] [never|always|kmode|umode]\n");
+ KdbpPrint(" break_on_module_load [true|false]\n");
+ }
+ else if (strcmp(Argv[1], "syntax") == 0)
+ {
+ if (Argc == 2)
+ {
+ KdbpPrint("syntax = %s\n", KdbUseIntelSyntax ? "intel" : "at&t");
+ }
+ else if (Argc >= 3)
+ {
+ if (_stricmp(Argv[2], "intel") == 0)
+ KdbUseIntelSyntax = TRUE;
+ else if (_stricmp(Argv[2], "at&t") == 0)
+ KdbUseIntelSyntax = FALSE;
+ else
+ KdbpPrint("Unknown syntax '%s'.\n", Argv[2]);
+ }
+ }
+ else if (strcmp(Argv[1], "condition") == 0)
+ {
+ if (Argc == 2)
+ {
+ KdbpPrint("Conditions: (First) (Last)\n");
+ for (l = 0; l < RTL_NUMBER_OF(ExceptionNames) - 1; l++)
{
- KdbpPrint("Unknown exception '%s'.\n", Argv[2]);
- return TRUE;
+ if (!ExceptionNames[l])
+ continue;
+
+ if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
+ ASSERT(0);
+
+ if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
+ ASSERT(0);
+
+ KdbpPrint(" #%02d %-20s %-8s %-8s\n", l, ExceptionNames[l],
+ KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
+ KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
}
- }
- if (Argc > 4)
- {
- if (_stricmp(Argv[3], "first") == 0)
- First = TRUE;
- else if (_stricmp(Argv[3], "last") == 0)
- First = FALSE;
- else
+
+ ASSERT(l == (RTL_NUMBER_OF(ExceptionNames) - 1));
+ KdbpPrint(" %-20s %-8s %-8s\n", ExceptionNames[l],
+ KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
+ KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
+ }
+ else
+ {
+ if (Argc >= 5 && strcmp(Argv[2], "*") == 0) /* Allow * only when setting condition */
{
- KdbpPrint("set condition: second argument must be 'first' or 'last'\n");
- return TRUE;
+ l = -1;
}
- if (_stricmp(Argv[4], "never") == 0)
- ConditionFirst = KdbDoNotEnter;
- else if (_stricmp(Argv[4], "always") == 0)
- ConditionFirst = KdbEnterAlways;
- else if (_stricmp(Argv[4], "umode") == 0)
- ConditionFirst = KdbEnterFromUmode;
- else if (_stricmp(Argv[4], "kmode") == 0)
- ConditionFirst = KdbEnterFromKmode;
else
{
- KdbpPrint("set condition: third argument must be 'never', 'always', 'umode' or 'kmode'\n");
- return TRUE;
+ l = strtoul(Argv[2], &pend, 0);
+
+ if (Argv[2] == pend)
+ {
+ for (l = 0; l < RTL_NUMBER_OF(ExceptionNames); l++)
+ {
+ if (!ExceptionNames[l])
+ continue;
+
+ if (_stricmp(ExceptionNames[l], Argv[2]) == 0)
+ break;
+ }
+ }
+
+ if (l >= RTL_NUMBER_OF(ExceptionNames))
+ {
+ KdbpPrint("Unknown exception '%s'.\n", Argv[2]);
+ return TRUE;
+ }
}
- if (!KdbpSetEnterCondition(l, First, ConditionFirst))
+
+ if (Argc > 4)
{
- if (l >= 0)
- KdbpPrint("Couldn't change condition for exception #%02d\n", l);
- else
- KdbpPrint("Couldn't change condition for all exceptions\n", l);
+ if (_stricmp(Argv[3], "first") == 0)
+ First = TRUE;
+ else if (_stricmp(Argv[3], "last") == 0)
+ First = FALSE;
+ else
+ {
+ KdbpPrint("set condition: second argument must be 'first' or 'last'\n");
+ return TRUE;
+ }
+
+ if (_stricmp(Argv[4], "never") == 0)
+ ConditionFirst = KdbDoNotEnter;
+ else if (_stricmp(Argv[4], "always") == 0)
+ ConditionFirst = KdbEnterAlways;
+ else if (_stricmp(Argv[4], "umode") == 0)
+ ConditionFirst = KdbEnterFromUmode;
+ else if (_stricmp(Argv[4], "kmode") == 0)
+ ConditionFirst = KdbEnterFromKmode;
+ else
+ {
+ KdbpPrint("set condition: third argument must be 'never', 'always', 'umode' or 'kmode'\n");
+ return TRUE;
+ }
+
+ if (!KdbpSetEnterCondition(l, First, ConditionFirst))
+ {
+ if (l >= 0)
+ KdbpPrint("Couldn't change condition for exception #%02d\n", l);
+ else
+ KdbpPrint("Couldn't change condition for all exceptions\n", l);
+ }
}
- }
- else /* Argc >= 3 */
- {
- if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
- ASSERT(0);
- if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
- ASSERT(0);
- if (l < (RTL_NUMBER_OF(ExceptionNames) - 1))
+ else /* Argc >= 3 */
{
- KdbpPrint("Condition for exception #%02d (%s): FirstChance %s LastChance %s\n",
- l, ExceptionNames[l],
- KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
- KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
+ if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
+ ASSERT(0);
+
+ if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
+ ASSERT(0);
+
+ if (l < (RTL_NUMBER_OF(ExceptionNames) - 1))
+ {
+ KdbpPrint("Condition for exception #%02d (%s): FirstChance %s LastChance %s\n",
+ l, ExceptionNames[l],
+ KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
+ KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
+ }
+ else
+ {
+ KdbpPrint("Condition for all other exceptions: FirstChance %s LastChance %s\n",
+ KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
+ KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
+ }
}
+ }
+ }
+ else if (strcmp(Argv[1], "break_on_module_load") == 0)
+ {
+ if (Argc == 2)
+ KdbpPrint("break_on_module_load = %s\n", KdbBreakOnModuleLoad ? "enabled" : "disabled");
+ else if (Argc >= 3)
+ {
+ if (_stricmp(Argv[2], "enable") == 0 || _stricmp(Argv[2], "enabled") == 0 || _stricmp(Argv[2], "true") == 0)
+ KdbBreakOnModuleLoad = TRUE;
+ else if (_stricmp(Argv[2], "disable") == 0 || _stricmp(Argv[2], "disabled") == 0 || _stricmp(Argv[2], "false") == 0)
+ KdbBreakOnModuleLoad = FALSE;
else
- {
- KdbpPrint("Condition for all other exceptions: FirstChance %s LastChance %s\n",
- KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
- KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
- }
- }
- }
- }
- else if (strcmp(Argv[1], "break_on_module_load") == 0)
- {
- if (Argc == 2)
- KdbpPrint("break_on_module_load = %s\n", KdbBreakOnModuleLoad ? "enabled" : "disabled");
- else if (Argc >= 3)
- {
- if (_stricmp(Argv[2], "enable") == 0 || _stricmp(Argv[2], "enabled") == 0 ||
- _stricmp(Argv[2], "true") == 0)
- KdbBreakOnModuleLoad = TRUE;
- else if (_stricmp(Argv[2], "disable") == 0 || _stricmp(Argv[2], "disabled") == 0 ||
- _stricmp(Argv[2], "false") == 0)
- KdbBreakOnModuleLoad = FALSE;
- else
- KdbpPrint("Unknown setting '%s'.\n", Argv[2]);
- }
- }
- else
- KdbpPrint("Unknown setting '%s'.\n", Argv[1]);
-
- return TRUE;
+ KdbpPrint("Unknown setting '%s'.\n", Argv[2]);
+ }
+ }
+ else
+ {
+ KdbpPrint("Unknown setting '%s'.\n", Argv[1]);
+ }
+
+ return TRUE;
}
/*!\brief Displays help screen.
*/
static BOOLEAN
-KdbpCmdHelp(ULONG Argc, PCHAR Argv[])
+KdbpCmdHelp(
+ ULONG Argc,
+ PCHAR Argv[])
{
- ULONG i;
-
- KdbpPrint("Kernel debugger commands:\n");
- for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
- {
- if (KdbDebuggerCommands[i].Syntax == NULL) /* Command group */
- {
- if (i > 0)
- KdbpPrint("\n");
- KdbpPrint("\x1b[7m* %s:\x1b[0m\n", KdbDebuggerCommands[i].Help);
- continue;
- }
+ ULONG i;
+
+ KdbpPrint("Kernel debugger commands:\n");
+ for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
+ {
+ if (!KdbDebuggerCommands[i].Syntax) /* Command group */
+ {
+ if (i > 0)
+ KdbpPrint("\n");
- KdbpPrint(" %-20s - %s\n",
- KdbDebuggerCommands[i].Syntax,
- KdbDebuggerCommands[i].Help);
- }
+ KdbpPrint("\x1b[7m* %s:\x1b[0m\n", KdbDebuggerCommands[i].Help);
+ continue;
+ }
+
+ KdbpPrint(" %-20s - %s\n",
+ KdbDebuggerCommands[i].Syntax,
+ KdbDebuggerCommands[i].Help);
+ }
- return TRUE;
+ return TRUE;
}
/*!\brief Prints the given string with printf-like formatting.
*/
VOID
KdbpPrint(
- IN PCHAR Format,
- IN ... OPTIONAL)
+ IN PCHAR Format,
+ IN ... OPTIONAL)
{
- static CHAR Buffer[4096];
- static BOOLEAN TerminalInitialized = FALSE;
- static BOOLEAN TerminalConnected = FALSE;
- static BOOLEAN TerminalReportsSize = TRUE;
- CHAR c = '\0';
- PCHAR p, p2;
- ULONG Length;
- ULONG i, j;
- LONG RowsPrintedByTerminal;
- ULONG ScanCode;
- va_list ap;
-
- /* Check if the user has aborted output of the current command */
- if (KdbOutputAborted)
- return;
-
- /* Initialize the terminal */
- if (!TerminalInitialized)
- {
- DbgPrint("\x1b[7h"); /* Enable linewrap */
-
- /* Query terminal type */
- /*DbgPrint("\x1b[Z");*/
- DbgPrint("\x05");
-
- TerminalInitialized = TRUE;
- Length = 0;
- KeStallExecutionProcessor(100000);
-
- for (;;)
- {
- c = KdbpTryGetCharSerial(5000);
- if (c == -1)
- break;
- Buffer[Length++] = c;
- if (Length >= (sizeof (Buffer) - 1))
- break;
- }
- Buffer[Length] = '\0';
- if (Length > 0)
- TerminalConnected = TRUE;
- }
-
- /* Get number of rows and columns in terminal */
- if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
- (KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of rows printed is 0 */
- {
- if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalConnected && TerminalReportsSize)
- {
- /* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */
- TerminalReportsSize = FALSE;
- KeStallExecutionProcessor(100000);
- DbgPrint("\x1b[18t");
- c = KdbpTryGetCharSerial(5000);
- if (c == KEY_ESC)
- {
+ static CHAR Buffer[4096];
+ static BOOLEAN TerminalInitialized = FALSE;
+ static BOOLEAN TerminalConnected = FALSE;
+ static BOOLEAN TerminalReportsSize = TRUE;
+ CHAR c = '\0';
+ PCHAR p, p2;
+ ULONG Length;
+ ULONG i, j;
+ LONG RowsPrintedByTerminal;
+ ULONG ScanCode;
+ va_list ap;
+
+ /* Check if the user has aborted output of the current command */
+ if (KdbOutputAborted)
+ return;
+
+ /* Initialize the terminal */
+ if (!TerminalInitialized)
+ {
+ DbgPrint("\x1b[7h"); /* Enable linewrap */
+
+ /* Query terminal type */
+ /*DbgPrint("\x1b[Z");*/
+ DbgPrint("\x05");
+
+ TerminalInitialized = TRUE;
+ Length = 0;
+ KeStallExecutionProcessor(100000);
+
+ for (;;)
+ {
c = KdbpTryGetCharSerial(5000);
- if (c == '[')
+ if (c == -1)
+ break;
+
+ Buffer[Length++] = c;
+ if (Length >= (sizeof (Buffer) - 1))
+ break;
+ }
+
+ Buffer[Length] = '\0';
+ if (Length > 0)
+ TerminalConnected = TRUE;
+ }
+
+ /* Get number of rows and columns in terminal */
+ if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
+ (KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of rows printed is 0 */
+ {
+ if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalConnected && TerminalReportsSize)
+ {
+ /* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */
+ TerminalReportsSize = FALSE;
+ KeStallExecutionProcessor(100000);
+ DbgPrint("\x1b[18t");
+ c = KdbpTryGetCharSerial(5000);
+
+ if (c == KEY_ESC)
{
- Length = 0;
- for (;;)
- {
- c = KdbpTryGetCharSerial(5000);
- if (c == -1)
- break;
- Buffer[Length++] = c;
- if (isalpha(c) || Length >= (sizeof (Buffer) - 1))
- break;
- }
- Buffer[Length] = '\0';
- if (Buffer[0] == '8' && Buffer[1] == ';')
- {
- for (i = 2; (i < Length) && (Buffer[i] != ';'); i++);
- if (Buffer[i] == ';')
- {
- Buffer[i++] = '\0';
- /* Number of rows is now at Buffer + 2 and number of cols at Buffer + i */
- KdbNumberOfRowsTerminal = strtoul(Buffer + 2, NULL, 0);
- KdbNumberOfColsTerminal = strtoul(Buffer + i, NULL, 0);
- TerminalReportsSize = TRUE;
- }
- }
+ c = KdbpTryGetCharSerial(5000);
+ if (c == '[')
+ {
+ Length = 0;
+
+ for (;;)
+ {
+ c = KdbpTryGetCharSerial(5000);
+ if (c == -1)
+ break;
+
+ Buffer[Length++] = c;
+ if (isalpha(c) || Length >= (sizeof (Buffer) - 1))
+ break;
+ }
+
+ Buffer[Length] = '\0';
+ if (Buffer[0] == '8' && Buffer[1] == ';')
+ {
+ for (i = 2; (i < Length) && (Buffer[i] != ';'); i++);
+
+ if (Buffer[i] == ';')
+ {
+ Buffer[i++] = '\0';
+
+ /* Number of rows is now at Buffer + 2 and number of cols at Buffer + i */
+ KdbNumberOfRowsTerminal = strtoul(Buffer + 2, NULL, 0);
+ KdbNumberOfColsTerminal = strtoul(Buffer + i, NULL, 0);
+ TerminalReportsSize = TRUE;
+ }
+ }
+ }
+ /* Clear further characters */
+ while ((c = KdbpTryGetCharSerial(5000)) != -1);
}
- /* Clear further characters */
- while ((c = KdbpTryGetCharSerial(5000)) != -1);
- }
- }
-
- if (KdbNumberOfRowsTerminal <= 0)
- {
- /* Set number of rows to the default. */
- KdbNumberOfRowsTerminal = 24;
- }
- else if (KdbNumberOfColsTerminal <= 0)
- {
- /* Set number of cols to the default. */
- KdbNumberOfColsTerminal = 80;
- }
- }
-
- /* Get the string */
- va_start(ap, Format);
- Length = _vsnprintf(Buffer, sizeof (Buffer) - 1, Format, ap);
- Buffer[Length] = '\0';
- va_end(ap);
-
- p = Buffer;
- while (p[0] != '\0')
- {
- i = strcspn(p, "\n");
-
- /* Calculate the number of lines which will be printed in the terminal
- * when outputting the current line
- */
- if (i > 0)
- RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdbNumberOfColsTerminal;
- else
- RowsPrintedByTerminal = 0;
- if (p[i] == '\n')
- RowsPrintedByTerminal++;
-
- /*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/
-
- /* Display a prompt if we printed one screen full of text */
- if (KdbNumberOfRowsTerminal > 0 &&
- (LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdbNumberOfRowsTerminal)
- {
- if (KdbNumberOfColsPrinted > 0)
- DbgPrint("\n");
- DbgPrint("--- Press q to abort, any other key to continue ---");
- if (KdbDebugState & KD_DEBUG_KDSERIAL)
- c = KdbpGetCharSerial();
- else
- c = KdbpGetCharKeyboard(&ScanCode);
- if (c == '\r')
- {
- /* Try to read '\n' which might follow '\r' - if \n is not received here
- * it will be interpreted as "return" when the next command should be read.
- */
+ }
+
+ if (KdbNumberOfRowsTerminal <= 0)
+ {
+ /* Set number of rows to the default. */
+ KdbNumberOfRowsTerminal = 24;
+ }
+ else if (KdbNumberOfColsTerminal <= 0)
+ {
+ /* Set number of cols to the default. */
+ KdbNumberOfColsTerminal = 80;
+ }
+ }
+
+ /* Get the string */
+ va_start(ap, Format);
+ Length = _vsnprintf(Buffer, sizeof (Buffer) - 1, Format, ap);
+ Buffer[Length] = '\0';
+ va_end(ap);
+
+ p = Buffer;
+ while (p[0] != '\0')
+ {
+ i = strcspn(p, "\n");
+
+ /* Calculate the number of lines which will be printed in the terminal
+ * when outputting the current line
+ */
+ if (i > 0)
+ RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdbNumberOfColsTerminal;
+ else
+ RowsPrintedByTerminal = 0;
+
+ if (p[i] == '\n')
+ RowsPrintedByTerminal++;
+
+ /*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/
+
+ /* Display a prompt if we printed one screen full of text */
+ if (KdbNumberOfRowsTerminal > 0 &&
+ (LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdbNumberOfRowsTerminal)
+ {
+ if (KdbNumberOfColsPrinted > 0)
+ DbgPrint("\n");
+
+ DbgPrint("--- Press q to abort, any other key to continue ---");
+
if (KdbDebugState & KD_DEBUG_KDSERIAL)
- c = KdbpTryGetCharSerial(5);
+ c = KdbpGetCharSerial();
else
- c = KdbpTryGetCharKeyboard(&ScanCode, 5);
- }
- DbgPrint("\n");
- if (c == 'q')
- {
- KdbOutputAborted = TRUE;
- return;
- }
- KdbNumberOfRowsPrinted = 0;
- KdbNumberOfColsPrinted = 0;
- }
-
- /* Insert a NUL after the line and print only the current line. */
- if (p[i] == '\n' && p[i + 1] != '\0')
- {
- c = p[i + 1];
- p[i + 1] = '\0';
- }
- else
- {
- c = '\0';
- }
-
- /* Remove escape sequences from the line if there's no terminal connected */
- if (!TerminalConnected)
- {
- while ((p2 = strrchr(p, '\x1b')) != NULL) /* Look for escape character */
- {
- if (p2[1] == '[')
+ c = KdbpGetCharKeyboard(&ScanCode);
+
+ if (c == '\r')
{
- j = 2;
- while (!isalpha(p2[j++]));
- strcpy(p2, p2 + j);
+ /* Try to read '\n' which might follow '\r' - if \n is not received here
+ * it will be interpreted as "return" when the next command should be read.
+ */
+ if (KdbDebugState & KD_DEBUG_KDSERIAL)
+ c = KdbpTryGetCharSerial(5);
+ else
+ c = KdbpTryGetCharKeyboard(&ScanCode, 5);
}
- else
+
+ DbgPrint("\n");
+ if (c == 'q')
+ {
+ KdbOutputAborted = TRUE;
+ return;
+ }
+
+ KdbNumberOfRowsPrinted = 0;
+ KdbNumberOfColsPrinted = 0;
+ }
+
+ /* Insert a NUL after the line and print only the current line. */
+ if (p[i] == '\n' && p[i + 1] != '\0')
+ {
+ c = p[i + 1];
+ p[i + 1] = '\0';
+ }
+ else
+ {
+ c = '\0';
+ }
+
+ /* Remove escape sequences from the line if there's no terminal connected */
+ if (!TerminalConnected)
+ {
+ while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */
{
- strcpy(p2, p2 + 1);
+ if (p2[1] == '[')
+ {
+ j = 2;
+ while (!isalpha(p2[j++]));
+ strcpy(p2, p2 + j);
+ }
+ else
+ {
+ strcpy(p2, p2 + 1);
+ }
}
- }
- }
-
- DbgPrint("%s", p);
-
- if (c != '\0')
- p[i + 1] = c;
-
- /* Set p to the start of the next line and
- * remember the number of rows/cols printed
- */
- p += i;
- if (p[0] == '\n')
- {
- p++;
- KdbNumberOfColsPrinted = 0;
- }
- else
- {
- ASSERT(p[0] == '\0');
- KdbNumberOfColsPrinted += i;
- }
- KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
- }
+ }
+
+ DbgPrint("%s", p);
+
+ if (c != '\0')
+ p[i + 1] = c;
+
+ /* Set p to the start of the next line and
+ * remember the number of rows/cols printed
+ */
+ p += i;
+ if (p[0] == '\n')
+ {
+ p++;
+ KdbNumberOfColsPrinted = 0;
+ }
+ else
+ {
+ ASSERT(p[0] == '\0');
+ KdbNumberOfColsPrinted += i;
+ }
+
+ KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
+ }
}
/*!\brief Appends a command to the command history
*/
static VOID
KdbpCommandHistoryAppend(
- IN PCHAR Command)
+ IN PCHAR Command)
{
- ULONG Length1 = strlen(Command) + 1;
- ULONG Length2 = 0;
- INT i;
- PCHAR Buffer;
-
- ASSERT(Length1 <= RTL_NUMBER_OF(KdbCommandHistoryBuffer));
-
- if (Length1 <= 1 ||
- (KdbCommandHistory[KdbCommandHistoryIndex] != NULL &&
- strcmp(KdbCommandHistory[KdbCommandHistoryIndex], Command) == 0))
- {
- return;
- }
-
- /* Calculate Length1 and Length2 */
- Buffer = KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex;
- KdbCommandHistoryBufferIndex += Length1;
- if (KdbCommandHistoryBufferIndex >= (LONG)RTL_NUMBER_OF(KdbCommandHistoryBuffer))
- {
- KdbCommandHistoryBufferIndex -= RTL_NUMBER_OF(KdbCommandHistoryBuffer);
- Length2 = KdbCommandHistoryBufferIndex;
- Length1 -= Length2;
- }
-
- /* Remove previous commands until there is enough space to append the new command */
- for (i = KdbCommandHistoryIndex; KdbCommandHistory[i] != NULL;)
- {
- if ((Length2 > 0 &&
- (KdbCommandHistory[i] >= Buffer ||
- KdbCommandHistory[i] < (KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex))) ||
- (Length2 <= 0 &&
- (KdbCommandHistory[i] >= Buffer &&
- KdbCommandHistory[i] < (KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex))))
- {
- KdbCommandHistory[i] = NULL;
- }
- i--;
- if (i < 0)
- i = RTL_NUMBER_OF(KdbCommandHistory) - 1;
- if (i == KdbCommandHistoryIndex)
- break;
- }
-
- /* Make sure the new command history entry is free */
- KdbCommandHistoryIndex++;
- KdbCommandHistoryIndex %= RTL_NUMBER_OF(KdbCommandHistory);
- if (KdbCommandHistory[KdbCommandHistoryIndex] != NULL)
- {
- KdbCommandHistory[KdbCommandHistoryIndex] = NULL;
- }
-
- /* Append command */
- KdbCommandHistory[KdbCommandHistoryIndex] = Buffer;
- ASSERT((KdbCommandHistory[KdbCommandHistoryIndex] + Length1) <= KdbCommandHistoryBuffer + RTL_NUMBER_OF(KdbCommandHistoryBuffer));
- memcpy(KdbCommandHistory[KdbCommandHistoryIndex], Command, Length1);
- if (Length2 > 0)
- {
- memcpy(KdbCommandHistoryBuffer, Command + Length1, Length2);
- }
+ ULONG Length1 = strlen(Command) + 1;
+ ULONG Length2 = 0;
+ INT i;
+ PCHAR Buffer;
+
+ ASSERT(Length1 <= RTL_NUMBER_OF(KdbCommandHistoryBuffer));
+
+ if (Length1 <= 1 ||
+ (KdbCommandHistory[KdbCommandHistoryIndex] &&
+ strcmp(KdbCommandHistory[KdbCommandHistoryIndex], Command) == 0))
+ {
+ return;
+ }
+
+ /* Calculate Length1 and Length2 */
+ Buffer = KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex;
+ KdbCommandHistoryBufferIndex += Length1;
+ if (KdbCommandHistoryBufferIndex >= (LONG)RTL_NUMBER_OF(KdbCommandHistoryBuffer))
+ {
+ KdbCommandHistoryBufferIndex -= RTL_NUMBER_OF(KdbCommandHistoryBuffer);
+ Length2 = KdbCommandHistoryBufferIndex;
+ Length1 -= Length2;
+ }
+
+ /* Remove previous commands until there is enough space to append the new command */
+ for (i = KdbCommandHistoryIndex; KdbCommandHistory[i];)
+ {
+ if ((Length2 > 0 &&
+ (KdbCommandHistory[i] >= Buffer ||
+ KdbCommandHistory[i] < (KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex))) ||
+ (Length2 <= 0 &&
+ (KdbCommandHistory[i] >= Buffer &&
+ KdbCommandHistory[i] < (KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex))))
+ {
+ KdbCommandHistory[i] = NULL;
+ }
+
+ i--;
+ if (i < 0)
+ i = RTL_NUMBER_OF(KdbCommandHistory) - 1;
+
+ if (i == KdbCommandHistoryIndex)
+ break;
+ }
+
+ /* Make sure the new command history entry is free */
+ KdbCommandHistoryIndex++;
+ KdbCommandHistoryIndex %= RTL_NUMBER_OF(KdbCommandHistory);
+ if (KdbCommandHistory[KdbCommandHistoryIndex])
+ {
+ KdbCommandHistory[KdbCommandHistoryIndex] = NULL;
+ }
+
+ /* Append command */
+ KdbCommandHistory[KdbCommandHistoryIndex] = Buffer;
+ ASSERT((KdbCommandHistory[KdbCommandHistoryIndex] + Length1) <= KdbCommandHistoryBuffer + RTL_NUMBER_OF(KdbCommandHistoryBuffer));
+ memcpy(KdbCommandHistory[KdbCommandHistoryIndex], Command, Length1);
+ if (Length2 > 0)
+ {
+ memcpy(KdbCommandHistoryBuffer, Command + Length1, Length2);
+ }
}
/*!\brief Reads a line of user-input.
*/
static VOID
KdbpReadCommand(
- OUT PCHAR Buffer,
- IN ULONG Size)
+ OUT PCHAR Buffer,
+ IN ULONG Size)
{
- CHAR Key;
- PCHAR Orig = Buffer;
- ULONG ScanCode = 0;
- BOOLEAN EchoOn;
- static CHAR LastCommand[1024] = "";
- static CHAR NextKey = '\0';
- INT CmdHistIndex = -1;
- INT i;
-
- EchoOn = !((KdbDebugState & KD_DEBUG_KDNOECHO) != 0);
-
- for (;;)
- {
- if (KdbDebugState & KD_DEBUG_KDSERIAL)
- {
- Key = (NextKey == '\0') ? KdbpGetCharSerial() : NextKey;
- NextKey = '\0';
- ScanCode = 0;
- if (Key == KEY_ESC) /* ESC */
- {
- Key = KdbpGetCharSerial();
- if (Key == '[')
+ CHAR Key;
+ PCHAR Orig = Buffer;
+ ULONG ScanCode = 0;
+ BOOLEAN EchoOn;
+ static CHAR LastCommand[1024] = "";
+ static CHAR NextKey = '\0';
+ INT CmdHistIndex = -1;
+ INT i;
+
+ EchoOn = !((KdbDebugState & KD_DEBUG_KDNOECHO) != 0);
+
+ for (;;)
+ {
+ if (KdbDebugState & KD_DEBUG_KDSERIAL)
+ {
+ Key = (NextKey == '\0') ? KdbpGetCharSerial() : NextKey;
+ NextKey = '\0';
+ ScanCode = 0;
+ if (Key == KEY_ESC) /* ESC */
{
- Key = KdbpGetCharSerial();
- switch (Key)
- {
- case 'A':
- ScanCode = KEY_SCAN_UP;
- break;
- case 'B':
- ScanCode = KEY_SCAN_DOWN;
- break;
- case 'C':
- break;
- case 'D':
- break;
- }
+ Key = KdbpGetCharSerial();
+ if (Key == '[')
+ {
+ Key = KdbpGetCharSerial();
+
+ switch (Key)
+ {
+ case 'A':
+ ScanCode = KEY_SCAN_UP;
+ break;
+ case 'B':
+ ScanCode = KEY_SCAN_DOWN;
+ break;
+ case 'C':
+ break;
+ case 'D':
+ break;
+ }
+ }
}
- }
- }
- else
- {
- ScanCode = 0;
- Key = (NextKey == '\0') ? KdbpGetCharKeyboard(&ScanCode) : NextKey;
- NextKey = '\0';
- }
-
- if ((ULONG)(Buffer - Orig) >= (Size - 1))
- {
- /* Buffer is full, accept only newlines */
- if (Key != '\n')
- continue;
- }
-
- if (Key == '\r')
- {
- /* Read the next char - this is to throw away a \n which most clients should
- * send after \r.
- */
- KeStallExecutionProcessor(100000);
- if (KdbDebugState & KD_DEBUG_KDSERIAL)
- NextKey = KdbpTryGetCharSerial(5);
- else
- NextKey = KdbpTryGetCharKeyboard(&ScanCode, 5);
- if (NextKey == '\n' || NextKey == -1) /* \n or no response at all */
+ }
+ else
+ {
+ ScanCode = 0;
+ Key = (NextKey == '\0') ? KdbpGetCharKeyboard(&ScanCode) : NextKey;
NextKey = '\0';
- KdbpPrint("\n");
- /*
- * Repeat the last command if the user presses enter. Reduces the
- * risk of RSI when single-stepping.
- */
- if (Buffer == Orig)
- {
- strncpy(Buffer, LastCommand, Size);
- Buffer[Size - 1] = '\0';
- }
- else
- {
- *Buffer = '\0';
- strncpy(LastCommand, Orig, sizeof (LastCommand));
- LastCommand[sizeof (LastCommand) - 1] = '\0';
- }
- return;
- }
- else if (Key == KEY_BS || Key == KEY_DEL)
- {
- if (Buffer > Orig)
- {
- Buffer--;
- *Buffer = 0;
- if (EchoOn)
- KdbpPrint("%c %c", KEY_BS, KEY_BS);
- else
- KdbpPrint(" %c", KEY_BS);
- }
- }
- else if (ScanCode == KEY_SCAN_UP)
- {
- BOOLEAN Print = TRUE;
- if (CmdHistIndex < 0)
- CmdHistIndex = KdbCommandHistoryIndex;
- else
- {
- i = CmdHistIndex - 1;
- if (i < 0)
- CmdHistIndex = RTL_NUMBER_OF(KdbCommandHistory) - 1;
- if (KdbCommandHistory[i] != NULL && i != KdbCommandHistoryIndex)
- CmdHistIndex = i;
+ }
+
+ if ((ULONG)(Buffer - Orig) >= (Size - 1))
+ {
+ /* Buffer is full, accept only newlines */
+ if (Key != '\n')
+ continue;
+ }
+
+ if (Key == '\r')
+ {
+ /* Read the next char - this is to throw away a \n which most clients should
+ * send after \r.
+ */
+ KeStallExecutionProcessor(100000);
+
+ if (KdbDebugState & KD_DEBUG_KDSERIAL)
+ NextKey = KdbpTryGetCharSerial(5);
+ else
+ NextKey = KdbpTryGetCharKeyboard(&ScanCode, 5);
+
+ if (NextKey == '\n' || NextKey == -1) /* \n or no response at all */
+ NextKey = '\0';
+
+ KdbpPrint("\n");
+
+ /*
+ * Repeat the last command if the user presses enter. Reduces the
+ * risk of RSI when single-stepping.
+ */
+ if (Buffer == Orig)
+ {
+ strncpy(Buffer, LastCommand, Size);
+ Buffer[Size - 1] = '\0';
+ }
+ else
+ {
+ *Buffer = '\0';
+ strncpy(LastCommand, Orig, sizeof (LastCommand));
+ LastCommand[sizeof (LastCommand) - 1] = '\0';
+ }
+
+ return;
+ }
+ else if (Key == KEY_BS || Key == KEY_DEL)
+ {
+ if (Buffer > Orig)
+ {
+ Buffer--;
+ *Buffer = 0;
+
+ if (EchoOn)
+ KdbpPrint("%c %c", KEY_BS, KEY_BS);
+ else
+ KdbpPrint(" %c", KEY_BS);
+ }
+ }
+ else if (ScanCode == KEY_SCAN_UP)
+ {
+ BOOLEAN Print = TRUE;
+
+ if (CmdHistIndex < 0)
+ {
+ CmdHistIndex = KdbCommandHistoryIndex;
+ }
else
- Print = FALSE;
- }
- if (Print && KdbCommandHistory[CmdHistIndex] != NULL)
- {
- while (Buffer > Orig)
{
- Buffer--;
- *Buffer = 0;
- if (EchoOn)
- KdbpPrint("%c %c", KEY_BS, KEY_BS);
- else
- KdbpPrint(" %c", KEY_BS);
+ i = CmdHistIndex - 1;
+
+ if (i < 0)
+ CmdHistIndex = RTL_NUMBER_OF(KdbCommandHistory) - 1;
+
+ if (KdbCommandHistory[i] && i != KdbCommandHistoryIndex)
+ CmdHistIndex = i;
+ else
+ Print = FALSE;
+ }
+
+ if (Print && KdbCommandHistory[CmdHistIndex])
+ {
+ while (Buffer > Orig)
+ {
+ Buffer--;
+ *Buffer = 0;
+
+ if (EchoOn)
+ KdbpPrint("%c %c", KEY_BS, KEY_BS);
+ else
+ KdbpPrint(" %c", KEY_BS);
+ }
+
+ i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
+ memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
+ Orig[i] = '\0';
+ Buffer = Orig + i;
+ KdbpPrint("%s", Orig);
}
- i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
- memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
- Orig[i] = '\0';
- Buffer = Orig + i;
- KdbpPrint("%s", Orig);
- }
- }
- else if (ScanCode == KEY_SCAN_DOWN)
- {
- if (CmdHistIndex > 0 && CmdHistIndex != KdbCommandHistoryIndex)
- {
- i = CmdHistIndex + 1;
- if (i >= (INT)RTL_NUMBER_OF(KdbCommandHistory))
- i = 0;
- if (KdbCommandHistory[i] != NULL)
+ }
+ else if (ScanCode == KEY_SCAN_DOWN)
+ {
+ if (CmdHistIndex > 0 && CmdHistIndex != KdbCommandHistoryIndex)
{
- CmdHistIndex = i;
- while (Buffer > Orig)
- {
- Buffer--;
- *Buffer = 0;
- if (EchoOn)
- KdbpPrint("%c %c", KEY_BS, KEY_BS);
- else
- KdbpPrint(" %c", KEY_BS);
- }
- i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
- memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
- Orig[i] = '\0';
- Buffer = Orig + i;
- KdbpPrint("%s", Orig);
+ i = CmdHistIndex + 1;
+ if (i >= (INT)RTL_NUMBER_OF(KdbCommandHistory))
+ i = 0;
+
+ if (KdbCommandHistory[i])
+ {
+ CmdHistIndex = i;
+ while (Buffer > Orig)
+ {
+ Buffer--;
+ *Buffer = 0;
+
+ if (EchoOn)
+ KdbpPrint("%c %c", KEY_BS, KEY_BS);
+ else
+ KdbpPrint(" %c", KEY_BS);
+ }
+
+ i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
+ memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
+ Orig[i] = '\0';
+ Buffer = Orig + i;
+ KdbpPrint("%s", Orig);
+ }
}
- }
- }
- else
- {
- if (EchoOn)
- KdbpPrint("%c", Key);
-
- *Buffer = Key;
- Buffer++;
- }
- }
+ }
+ else
+ {
+ if (EchoOn)
+ KdbpPrint("%c", Key);
+
+ *Buffer = Key;
+ Buffer++;
+ }
+ }
}
/*!\brief Parses command line and executes command if found
*/
static BOOLEAN
KdbpDoCommand(
- IN PCHAR Command)
+ IN PCHAR Command)
{
- ULONG i;
- PCHAR p;
- ULONG Argc;
- static PCH Argv[256];
- static CHAR OrigCommand[1024];
-
- strncpy(OrigCommand, Command, sizeof(OrigCommand) - 1);
- OrigCommand[sizeof(OrigCommand) - 1] = '\0';
-
- Argc = 0;
- p = Command;
- for (;;)
- {
- while (*p == '\t' || *p == ' ')
- p++;
- if (*p == '\0')
- break;
-
- i = strcspn(p, "\t ");
- Argv[Argc++] = p;
- p += i;
- if (*p == '\0')
- break;
- *p = '\0';
- p++;
- }
- if (Argc < 1)
- return TRUE;
-
- for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
- {
- if (KdbDebuggerCommands[i].Name == NULL)
- continue;
-
- if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0)
- {
- return KdbDebuggerCommands[i].Fn(Argc, Argv);
- }
- }
-
- KdbpPrint("Command '%s' is unknown.\n", OrigCommand);
- return TRUE;
+ ULONG i;
+ PCHAR p;
+ ULONG Argc;
+ static PCH Argv[256];
+ static CHAR OrigCommand[1024];
+
+ strncpy(OrigCommand, Command, sizeof(OrigCommand) - 1);
+ OrigCommand[sizeof(OrigCommand) - 1] = '\0';
+
+ Argc = 0;
+ p = Command;
+
+ for (;;)
+ {
+ while (*p == '\t' || *p == ' ')
+ p++;
+
+ if (*p == '\0')
+ break;
+
+ i = strcspn(p, "\t ");
+ Argv[Argc++] = p;
+ p += i;
+ if (*p == '\0')
+ break;
+
+ *p = '\0';
+ p++;
+ }
+
+ if (Argc < 1)
+ return TRUE;
+
+ for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
+ {
+ if (!KdbDebuggerCommands[i].Name)
+ continue;
+
+ if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0)
+ {
+ return KdbDebuggerCommands[i].Fn(Argc, Argv);
+ }
+ }
+
+ KdbpPrint("Command '%s' is unknown.\n", OrigCommand);
+ return TRUE;
}
/*!\brief KDB Main Loop.
*/
VOID
KdbpCliMainLoop(
- IN BOOLEAN EnteredOnSingleStep)
+ IN BOOLEAN EnteredOnSingleStep)
{
- static CHAR Command[1024];
- BOOLEAN Continue;
-
- if (EnteredOnSingleStep)
- {
- if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip))
- {
- KdbpPrint("<%x>", KdbCurrentTrapFrame->Tf.Eip);
- }
- KdbpPrint(": ");
- if (KdbpDisassemble(KdbCurrentTrapFrame->Tf.Eip, KdbUseIntelSyntax) < 0)
- {
- KdbpPrint("<INVALID>");
- }
- KdbpPrint("\n");
- }
-
- /* Flush the input buffer */
- if (KdbDebugState & KD_DEBUG_KDSERIAL)
- {
- while (KdbpTryGetCharSerial(1) != -1);
- }
- else
- {
- ULONG ScanCode;
- while (KdbpTryGetCharKeyboard(&ScanCode, 1) != -1);
- }
-
- /* Main loop */
- do
- {
- /* Print the prompt */
- KdbpPrint("kdb:> ");
-
- /* Read a command and remember it */
- KdbpReadCommand(Command, sizeof (Command));
- KdbpCommandHistoryAppend(Command);
-
- /* Reset the number of rows/cols printed and output aborted state */
- KdbNumberOfRowsPrinted = KdbNumberOfColsPrinted = 0;
- KdbOutputAborted = FALSE;
-
- /* Call the command */
- Continue = KdbpDoCommand(Command);
- } while (Continue);
+ static CHAR Command[1024];
+ BOOLEAN Continue;
+
+ if (EnteredOnSingleStep)
+ {
+ if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip))
+ {
+ KdbpPrint("<%x>", KdbCurrentTrapFrame->Tf.Eip);
+ }
+
+ KdbpPrint(": ");
+ if (KdbpDisassemble(KdbCurrentTrapFrame->Tf.Eip, KdbUseIntelSyntax) < 0)
+ {
+ KdbpPrint("<INVALID>");
+ }
+ KdbpPrint("\n");
+ }
+
+ /* Flush the input buffer */
+ if (KdbDebugState & KD_DEBUG_KDSERIAL)
+ {
+ while (KdbpTryGetCharSerial(1) != -1);
+ }
+ else
+ {
+ ULONG ScanCode;
+ while (KdbpTryGetCharKeyboard(&ScanCode, 1) != -1);
+ }
+
+ /* Main loop */
+ do
+ {
+ /* Print the prompt */
+ KdbpPrint("kdb:> ");
+
+ /* Read a command and remember it */
+ KdbpReadCommand(Command, sizeof (Command));
+ KdbpCommandHistoryAppend(Command);
+
+ /* Reset the number of rows/cols printed and output aborted state */
+ KdbNumberOfRowsPrinted = KdbNumberOfColsPrinted = 0;
+ KdbOutputAborted = FALSE;
+
+ /* Call the command */
+ Continue = KdbpDoCommand(Command);
+ }
+ while (Continue);
}
/*!\brief Called when a module is loaded.
* \param Name Filename of the module which was loaded.
*/
VOID
-KdbpCliModuleLoaded(IN PUNICODE_STRING Name)
+KdbpCliModuleLoaded(
+ IN PUNICODE_STRING Name)
{
- if (!KdbBreakOnModuleLoad)
- return;
+ if (!KdbBreakOnModuleLoad)
+ return;
- KdbpPrint("Module %wZ loaded.\n", Name);
- DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
+ KdbpPrint("Module %wZ loaded.\n", Name);
+ DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
}
/*!\brief This function is called by KdbEnterDebuggerException...
VOID
KdbpCliInterpretInitFile()
{
- PCHAR p1, p2;
- INT i;
- CHAR c;
-
- /* Execute the commands in the init file */
- DPRINT("KDB: Executing KDBinit file...\n");
- p1 = KdbInitFileBuffer;
- while (p1[0] != '\0')
- {
- i = strcspn(p1, "\r\n");
- if (i > 0)
- {
- c = p1[i];
- p1[i] = '\0';
-
- /* Look for "break" command and comments */
- p2 = p1;
- while (isspace(p2[0]))
- p2++;
- if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
- (p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
- {
- /* break into the debugger */
- KdbpCliMainLoop(FALSE);
- }
- else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
- {
- KdbpDoCommand(p1);
- }
-
- p1[i] = c;
- }
- p1 += i;
- while (p1[0] == '\r' || p1[0] == '\n')
- p1++;
- }
- DPRINT("KDB: KDBinit executed\n");
+ PCHAR p1, p2;
+ INT i;
+ CHAR c;
+
+ /* Execute the commands in the init file */
+ DPRINT("KDB: Executing KDBinit file...\n");
+ p1 = KdbInitFileBuffer;
+ while (p1[0] != '\0')
+ {
+ i = strcspn(p1, "\r\n");
+ if (i > 0)
+ {
+ c = p1[i];
+ p1[i] = '\0';
+
+ /* Look for "break" command and comments */
+ p2 = p1;
+
+ while (isspace(p2[0]))
+ p2++;
+
+ if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
+ (p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
+ {
+ /* break into the debugger */
+ KdbpCliMainLoop(FALSE);
+ }
+ else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
+ {
+ KdbpDoCommand(p1);
+ }
+
+ p1[i] = c;
+ }
+
+ p1 += i;
+ while (p1[0] == '\r' || p1[0] == '\n')
+ p1++;
+ }
+ DPRINT("KDB: KDBinit executed\n");
}
/*!\brief Called when KDB is initialized
VOID
KdbpCliInit()
{
- NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING FileName;
- IO_STATUS_BLOCK Iosb;
- FILE_STANDARD_INFORMATION FileStdInfo;
- HANDLE hFile = NULL;
- INT FileSize;
- PCHAR FileBuffer;
- ULONG OldEflags = 0;
-
- /* Initialize the object attributes */
- RtlInitUnicodeString(&FileName, L"\\SystemRoot\\system32\\drivers\\etc\\KDBinit");
- InitializeObjectAttributes(&ObjectAttributes, &FileName, 0, NULL, NULL);
-
- /* Open the file */
- Status = ZwOpenFile(&hFile, FILE_READ_DATA, &ObjectAttributes, &Iosb, 0,
- FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
- FILE_NO_INTERMEDIATE_BUFFERING);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Could not open \\SystemRoot\\system32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
- return;
- }
-
- /* Get the size of the file */
- Status = ZwQueryInformationFile(hFile, &Iosb, &FileStdInfo, sizeof (FileStdInfo),
- FileStandardInformation);
- if (!NT_SUCCESS(Status))
- {
- ZwClose(hFile);
- DPRINT("Could not query size of \\SystemRoot\\system32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
- return;
- }
- FileSize = FileStdInfo.EndOfFile.u.LowPart;
-
- /* Allocate memory for the file */
- FileBuffer = ExAllocatePool(PagedPool, FileSize + 1); /* add 1 byte for terminating '\0' */
- if (FileBuffer == NULL)
- {
- ZwClose(hFile);
- DPRINT("Could not allocate %d bytes for KDBinit file\n", FileSize);
- return;
- }
-
- /* Load file into memory */
- Status = ZwReadFile(hFile, 0, 0, 0, &Iosb, FileBuffer, FileSize, 0, 0);
- ZwClose(hFile);
- if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
- {
- ExFreePool(FileBuffer);
- DPRINT("Could not read KDBinit file into memory (Status 0x%lx)\n", Status);
- return;
- }
- FileSize = min(FileSize, (INT)Iosb.Information);
- FileBuffer[FileSize] = '\0';
-
- /* Enter critical section */
- Ke386SaveFlags(OldEflags);
- _disable();
-
- /* Interpret the init file... */
- KdbInitFileBuffer = FileBuffer;
- KdbEnter();
- KdbInitFileBuffer = NULL;
-
- /* Leave critical section */
- Ke386RestoreFlags(OldEflags);
-
- ExFreePool(FileBuffer);
-}
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING FileName;
+ IO_STATUS_BLOCK Iosb;
+ FILE_STANDARD_INFORMATION FileStdInfo;
+ HANDLE hFile = NULL;
+ INT FileSize;
+ PCHAR FileBuffer;
+ ULONG OldEflags = 0;
+
+ /* Initialize the object attributes */
+ RtlInitUnicodeString(&FileName, L"\\SystemRoot\\system32\\drivers\\etc\\KDBinit");
+ InitializeObjectAttributes(&ObjectAttributes, &FileName, 0, NULL, NULL);
+
+ /* Open the file */
+ Status = ZwOpenFile(&hFile, FILE_READ_DATA, &ObjectAttributes, &Iosb, 0,
+ FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
+ FILE_NO_INTERMEDIATE_BUFFERING);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Could not open \\SystemRoot\\system32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
+ return;
+ }
+
+ /* Get the size of the file */
+ Status = ZwQueryInformationFile(hFile, &Iosb, &FileStdInfo, sizeof (FileStdInfo),
+ FileStandardInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ ZwClose(hFile);
+ DPRINT("Could not query size of \\SystemRoot\\system32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
+ return;
+ }
+ FileSize = FileStdInfo.EndOfFile.u.LowPart;
+
+ /* Allocate memory for the file */
+ FileBuffer = ExAllocatePool(PagedPool, FileSize + 1); /* add 1 byte for terminating '\0' */
+ if (!FileBuffer)
+ {
+ ZwClose(hFile);
+ DPRINT("Could not allocate %d bytes for KDBinit file\n", FileSize);
+ return;
+ }
+
+ /* Load file into memory */
+ Status = ZwReadFile(hFile, 0, 0, 0, &Iosb, FileBuffer, FileSize, 0, 0);
+ ZwClose(hFile);
+ if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
+ {
+ ExFreePool(FileBuffer);
+ DPRINT("Could not read KDBinit file into memory (Status 0x%lx)\n", Status);
+ return;
+ }
+
+ FileSize = min(FileSize, (INT)Iosb.Information);
+ FileBuffer[FileSize] = '\0';
+
+ /* Enter critical section */
+ Ke386SaveFlags(OldEflags);
+ _disable();
+
+ /* Interpret the init file... */
+ KdbInitFileBuffer = FileBuffer;
+ KdbEnter();
+ KdbInitFileBuffer = NULL;
+
+ /* Leave critical section */
+ Ke386RestoreFlags(OldEflags);
+
+ ExFreePool(FileBuffer);
+}