From 3e4016ea24e2f8f5384bd6c13631aceb81045507 Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Wed, 9 Sep 2009 13:49:04 +0000 Subject: [PATCH] [FORMATTING] Fix the indentation mess in KDBG and use a consistent 4 spaces indentation. svn path=/trunk/; revision=43014 --- reactos/ntoskrnl/include/internal/kd.h | 79 +- reactos/ntoskrnl/kdbg/i386/kdb_help.S | 239 +- reactos/ntoskrnl/kdbg/kdb.c | 2272 +++++++------ reactos/ntoskrnl/kdbg/kdb_cli.c | 4248 +++++++++++++----------- reactos/ntoskrnl/kdbg/kdb_expr.c | 1607 ++++----- reactos/ntoskrnl/kdbg/kdb_keyboard.c | 88 +- reactos/ntoskrnl/kdbg/kdb_serial.c | 12 +- reactos/ntoskrnl/kdbg/kdb_symbols.c | 571 ++-- 8 files changed, 4758 insertions(+), 4358 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/kd.h b/reactos/ntoskrnl/include/internal/kd.h index 3002bad4189..da2b5c653bf 100644 --- a/reactos/ntoskrnl/include/internal/kd.h +++ b/reactos/ntoskrnl/include/internal/kd.h @@ -69,10 +69,12 @@ KdPortPutByteEx( #if defined(KDBG) || DBG VOID -KdbSymLoadUserModuleSymbols(IN PLDR_DATA_TABLE_ENTRY LdrModule); +KdbSymLoadUserModuleSymbols( + IN PLDR_DATA_TABLE_ENTRY LdrModule); VOID -KdbSymFreeProcessSymbols(IN PEPROCESS Process); +KdbSymFreeProcessSymbols( + IN PEPROCESS Process); VOID KdbSymLoadDriverSymbols( @@ -81,21 +83,27 @@ KdbSymLoadDriverSymbols( ); VOID -KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject); +KdbSymUnloadDriverSymbols( + IN PLDR_DATA_TABLE_ENTRY ModuleObject); VOID -KdbSymProcessBootSymbols(IN PANSI_STRING AnsiFileName, - IN BOOLEAN FullName, - IN BOOLEAN LoadFromFile); +KdbSymProcessBootSymbols( + IN PANSI_STRING AnsiFileName, + IN BOOLEAN FullName, + IN BOOLEAN LoadFromFile); VOID -KdbSymProcessSymbols(IN PANSI_STRING FileName, IN PKD_SYMBOLS_INFO SymbolInfo); +KdbSymProcessSymbols( + IN PANSI_STRING FileName, + IN PKD_SYMBOLS_INFO SymbolInfo); BOOLEAN -KdbSymPrintAddress(IN PVOID Address); +KdbSymPrintAddress( + IN PVOID Address); VOID -KdbDeleteProcessHook(IN PEPROCESS Process); +KdbDeleteProcessHook( + IN PEPROCESS Process); NTSTATUS KdbSymGetAddressInformation( @@ -112,38 +120,39 @@ typedef struct _KDB_MODULE_INFO ULONG_PTR Base; ULONG Size; PROSSYM_INFO RosSymInfo; -} KDB_MODULE_INFO, *PKDB_MODULE_INFO; +} +KDB_MODULE_INFO, *PKDB_MODULE_INFO; /* MACROS FOR NON-KDBG BUILDS ************************************************/ -# define KDB_LOADUSERMODULE_HOOK(LDRMOD) KdbSymLoadUserModuleSymbols(LDRMOD) -# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE) -# define KDB_UNLOADDRIVER_HOOK(MODULE) KdbSymUnloadDriverSymbols(MODULE) -# define KDB_SYMBOLFILE_HOOK(FILENAME, SYMBOLINFO) KdbSymProcessSymbols((FILENAME), (SYMBOLINFO)) +# define KDB_LOADUSERMODULE_HOOK(LDRMOD) KdbSymLoadUserModuleSymbols(LDRMOD) +# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE) +# define KDB_UNLOADDRIVER_HOOK(MODULE) KdbSymUnloadDriverSymbols(MODULE) +# define KDB_SYMBOLFILE_HOOK(FILENAME, SYMBOLINFO) KdbSymProcessSymbols((FILENAME), (SYMBOLINFO)) #else -# define KDB_LOADUSERMODULE_HOOK(LDRMOD) do { } while (0) -# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) do { } while (0) -# define KDB_UNLOADDRIVER_HOOK(MODULE) do { } while (0) -# define KDB_SYMBOLFILE_HOOK(FILENAME, SYMBOLINFO) do { } while (0) -# define KDB_CREATE_THREAD_HOOK(CONTEXT) do { } while (0) +# define KDB_LOADUSERMODULE_HOOK(LDRMOD) do { } while (0) +# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) do { } while (0) +# define KDB_UNLOADDRIVER_HOOK(MODULE) do { } while (0) +# define KDB_SYMBOLFILE_HOOK(FILENAME, SYMBOLINFO) do { } while (0) +# define KDB_CREATE_THREAD_HOOK(CONTEXT) do { } while (0) #endif #if defined(KDBG) || DBG -# define KeRosPrintAddress(ADDRESS) KdbSymPrintAddress(ADDRESS) +# define KeRosPrintAddress(ADDRESS) KdbSymPrintAddress(ADDRESS) #else -# define KeRosPrintAddress(ADDRESS) KiRosPrintAddress(ADDRESS) +# define KeRosPrintAddress(ADDRESS) KiRosPrintAddress(ADDRESS) #endif #ifdef KDBG -# define KdbInit() KdbpCliInit() -# define KdbModuleLoaded(FILENAME) KdbpCliModuleLoaded(FILENAME) -# define KDB_DELETEPROCESS_HOOK(PROCESS) KdbDeleteProcessHook(PROCESS) +# define KdbInit() KdbpCliInit() +# define KdbModuleLoaded(FILENAME) KdbpCliModuleLoaded(FILENAME) +# define KDB_DELETEPROCESS_HOOK(PROCESS) KdbDeleteProcessHook(PROCESS) #else -# define KdbEnterDebuggerException(ER, PM, C, TF, F) kdHandleException -# define KdbInit() do { } while (0) -# define KdbEnter() do { } while (0) -# define KdbModuleLoaded(X) do { } while (0) -# define KDB_DELETEPROCESS_HOOK(PROCESS) do { } while (0) +# define KdbEnterDebuggerException(ER, PM, C, TF, F) kdHandleException +# define KdbInit() do { } while (0) +# define KdbEnter() do { } while (0) +# define KdbModuleLoaded(X) do { } while (0) +# define KDB_DELETEPROCESS_HOOK(PROCESS) do { } while (0) #endif /* KD ROUTINES ***************************************************************/ @@ -153,7 +162,8 @@ typedef enum _KD_CONTINUE_TYPE kdContinue = 0, kdDoNotHandleException, kdHandleException -} KD_CONTINUE_TYPE; +} +KD_CONTINUE_TYPE; typedef VOID @@ -327,7 +337,8 @@ typedef struct _KDP_DEBUG_MODE /* Generic Value */ ULONG Value; }; -} KDP_DEBUG_MODE; +} +KDP_DEBUG_MODE; /* KD Internal Debug Services */ typedef enum _KDP_DEBUG_SERVICE @@ -344,7 +355,8 @@ typedef enum _KDP_DEBUG_SERVICE KdSpare3 = 0x24, /* j */ EnterDebugger = 0x25, /* k */ ThatsWhatSheSaid = 69 /* FIGURE IT OUT */ -} KDP_DEBUG_SERVICE; +} +KDP_DEBUG_SERVICE; /* Dispatch Table for Wrapper Functions */ typedef struct _KD_DISPATCH_TABLE @@ -354,7 +366,8 @@ typedef struct _KD_DISPATCH_TABLE PKDP_PRINT_ROUTINE KdpPrintRoutine; PKDP_PROMPT_ROUTINE KdpPromptRoutine; PKDP_EXCEPTION_ROUTINE KdpExceptionRoutine; -} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE; +} +KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE; /* The current Debugging Mode */ extern KDP_DEBUG_MODE KdpDebugMode; diff --git a/reactos/ntoskrnl/kdbg/i386/kdb_help.S b/reactos/ntoskrnl/kdbg/i386/kdb_help.S index e0ae7968541..00cb522c17c 100644 --- a/reactos/ntoskrnl/kdbg/i386/kdb_help.S +++ b/reactos/ntoskrnl/kdbg/i386/kdb_help.S @@ -4,136 +4,137 @@ .globl _KdbEnter _KdbEnter: - /* - * Set up a trap frame - */ - pushfl /* Eflags */ - pushl %cs /* Cs */ - pushl $0 /* ErrorCode */ - pushl %ebp /* Ebp */ - pushl %ebx /* Ebx */ - movl 20(%esp), %ebp /* Eip */ - movl 16(%esp), %ebx /* Eflags */ - movl %ebx, 20(%esp) - movl 12(%esp), %ebx /* Cs */ - movl %ebx, 16(%esp) - movl %ebp, 12(%esp) - pushl %esi /* Esi */ - pushl %edi /* Edi */ - pushl %fs /* Fs */ - pushl $0 /* ExceptionList */ - pushl $0 /* PreviousMode */ - pushl %eax /* Eax */ - pushl %ecx /* Ecx */ - pushl %edx /* Edx */ - pushl %ds /* Ds */ - pushl %es /* Es */ - pushl %gs /* Gs */ - movl %dr7, %eax - pushl %eax /* Dr7 */ - /* Clear all breakpoint enables in dr7. */ - andl $0xFFFF0000, %eax - movl %eax, %dr7 - movl %dr6, %eax - pushl %eax /* Dr6 */ - movl %dr3, %eax - pushl %eax /* Dr3 */ - movl %dr2, %eax - pushl %eax /* Dr2 */ - movl %dr1, %eax - pushl %eax /* Dr1 */ - movl %dr0, %eax - pushl %eax /* Dr0 */ - leal 0x58(%esp), %eax - pushl %eax /* TempEsp */ - pushl %ss /* TempSegSs */ - pushl $0 /* DebugPointer */ - pushl $3 /* DebugArgMark (Exception number) */ - pushl 0x60(%esp) /* DebugEip */ - pushl %ebp /* DebugEbp */ + /* + * Set up a trap frame + */ + pushfl /* Eflags */ + pushl %cs /* Cs */ + pushl $0 /* ErrorCode */ + pushl %ebp /* Ebp */ + pushl %ebx /* Ebx */ + movl 20(%esp), %ebp /* Eip */ + movl 16(%esp), %ebx /* Eflags */ + movl %ebx, 20(%esp) + movl 12(%esp), %ebx /* Cs */ + movl %ebx, 16(%esp) + movl %ebp, 12(%esp) + pushl %esi /* Esi */ + pushl %edi /* Edi */ + pushl %fs /* Fs */ + pushl $0 /* ExceptionList */ + pushl $0 /* PreviousMode */ + pushl %eax /* Eax */ + pushl %ecx /* Ecx */ + pushl %edx /* Edx */ + pushl %ds /* Ds */ + pushl %es /* Es */ + pushl %gs /* Gs */ + movl %dr7, %eax + pushl %eax /* Dr7 */ - /* - * Call KDB - */ - movl %esp, %eax - pushl $1 /* FirstChance */ - pushl %eax /* Push a pointer to the trap frame */ - pushl $0 /* Context */ - pushl $0 /* PreviousMode (KernelMode) */ - pushl $0 /* ExceptionRecord */ - call _KdbEnterDebuggerException + /* Clear all breakpoint enables in dr7. */ + andl $0xFFFF0000, %eax + movl %eax, %dr7 + movl %dr6, %eax + pushl %eax /* Dr6 */ + movl %dr3, %eax + pushl %eax /* Dr3 */ + movl %dr2, %eax + pushl %eax /* Dr2 */ + movl %dr1, %eax + pushl %eax /* Dr1 */ + movl %dr0, %eax + pushl %eax /* Dr0 */ + leal 0x58(%esp), %eax + pushl %eax /* TempEsp */ + pushl %ss /* TempSegSs */ + pushl $0 /* DebugPointer */ + pushl $3 /* DebugArgMark (Exception number) */ + pushl 0x60(%esp) /* DebugEip */ + pushl %ebp /* DebugEbp */ - /* - * Pop the arguments and unused portions of the trap frame: - * DebugEbp - * DebugEip - * DebugArgMark - * DebugPointer - * TempSegSs - * TempEsp - */ - addl $(11*4), %esp + /* + * Call KDB + */ + movl %esp, %eax + pushl $1 /* FirstChance */ + pushl %eax /* Push a pointer to the trap frame */ + pushl $0 /* Context */ + pushl $0 /* PreviousMode (KernelMode) */ + pushl $0 /* ExceptionRecord */ + call _KdbEnterDebuggerException - /* - * Restore/update debugging registers. - */ - popl %eax /* Dr0 */ - movl %eax, %dr0 - popl %eax /* Dr1 */ - movl %eax, %dr1 - popl %eax /* Dr2 */ - movl %eax, %dr2 - popl %eax /* Dr3 */ - movl %eax, %dr3 - popl %eax /* Dr6 */ - movl %eax, %dr6 - popl %eax /* Dr7 */ - movl %eax, %dr7 + /* + * Pop the arguments and unused portions of the trap frame: + * DebugEbp + * DebugEip + * DebugArgMark + * DebugPointer + * TempSegSs + * TempEsp + */ + addl $(11*4), %esp - /* - * Restore registers including any that might have been changed - * inside the debugger. - */ - popl %gs /* Gs */ - popl %es /* Es */ - popl %ds /* Ds */ - popl %edx /* Edx */ - popl %ecx /* Ecx */ - popl %eax /* Eax */ - addl $8, %esp /* PreviousMode, ExceptionList */ - popl %fs /* Fs */ - popl %edi /* Edi */ - popl %esi /* Esi */ - popl %ebx /* Ebx */ - popl %ebp /* Ebp */ - addl $4, %esp /* ErrorCode */ + /* + * Restore/update debugging registers. + */ + popl %eax /* Dr0 */ + movl %eax, %dr0 + popl %eax /* Dr1 */ + movl %eax, %dr1 + popl %eax /* Dr2 */ + movl %eax, %dr2 + popl %eax /* Dr3 */ + movl %eax, %dr3 + popl %eax /* Dr6 */ + movl %eax, %dr6 + popl %eax /* Dr7 */ + movl %eax, %dr7 - /* - * Return to the caller. - */ - iret + /* + * Restore registers including any that might have been changed + * inside the debugger. + */ + popl %gs /* Gs */ + popl %es /* Es */ + popl %ds /* Ds */ + popl %edx /* Edx */ + popl %ecx /* Ecx */ + popl %eax /* Eax */ + addl $8, %esp /* PreviousMode, ExceptionList */ + popl %fs /* Fs */ + popl %edi /* Edi */ + popl %esi /* Esi */ + popl %ebx /* Ebx */ + popl %ebp /* Ebp */ + addl $4, %esp /* ErrorCode */ + + /* + * Return to the caller. + */ + iret .globl _KdbpStackSwitchAndCall@8 _KdbpStackSwitchAndCall@8: - pushl %ebp - movl %esp, %ebp - - movl 0x8(%esp), %eax /* New stack */ - movl 0xC(%esp), %ecx /* Function to call */ - movl %esp, %edx /* Old stack */ + pushl %ebp + movl %esp, %ebp - /* Switch stack */ - movl %eax, %esp - pushl %edx + movl 0x8(%esp), %eax /* New stack */ + movl 0xC(%esp), %ecx /* Function to call */ + movl %esp, %edx /* Old stack */ - /* Call function */ - call *%ecx + /* Switch stack */ + movl %eax, %esp + pushl %edx - /* Switch back to old stack */ - popl %esp + /* Call function */ + call *%ecx - /* Return */ - popl %ebp - ret $8 + /* Switch back to old stack */ + popl %esp + + /* Return */ + popl %ebp + ret $8 diff --git a/reactos/ntoskrnl/kdbg/kdb.c b/reactos/ntoskrnl/kdbg/kdb.c index 00fb9d5f12b..1888515a1f7 100644 --- a/reactos/ntoskrnl/kdbg/kdb.c +++ b/reactos/ntoskrnl/kdbg/kdb.c @@ -56,92 +56,96 @@ extern BOOLEAN KdbpBugCheckRequested; /* 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( @@ -177,44 +181,47 @@ KdbpTrapFrameToKdbTrapFrame(PKTRAP_FRAME TrapFrame, PKDB_KTRAP_FRAME KdbTrapFram 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; + 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; + 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??? */ + /* FIXME: what about the other registers??? */ } /*!\brief Overwrites the instruction at \a Address with \a NewInst and stores @@ -229,73 +236,75 @@ KdbpKdbTrapFrameFromKernelStack(PVOID KernelStack, */ 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 @@ -305,28 +314,32 @@ KdbpOverwriteInstruction( * \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 @@ -339,21 +352,22 @@ KdbpShouldStepOverInstruction(ULONG_PTR Eip) * \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) @@ -366,78 +380,79 @@ KdbpStepOverInstruction(ULONG_PTR Eip) * \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; + /* 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; - } + 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. @@ -448,14 +463,15 @@ KdbpStepIntoInstruction(ULONG_PTR Eip) */ 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. @@ -474,49 +490,57 @@ KdbpGetNextBreakPointNr( */ 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; + bp = KdbBreakPoints + BreakPointNr; + if (Address) + *Address = bp->Address; - return TRUE; + 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. @@ -535,112 +559,115 @@ KdbpGetBreakPointInfo( */ 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; - } + if (KdbBreakPointCount == KDB_MAXIMUM_BREAKPOINT_COUNT) + { + return STATUS_UNSUCCESSFUL; + } - i = strlen(ConditionExpression) + 1; - ConditionExpressionDup = ExAllocatePoolWithTag(NonPagedPool, i, TAG_KDBG); - RtlCopyMemory(ConditionExpressionDup, ConditionExpression, i); + /* 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); - } - else - { - Condition = NULL; - ConditionExpressionDup = NULL; - } + return STATUS_UNSUCCESSFUL; + } - /* 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)); + i = strlen(ConditionExpression) + 1; + ConditionExpressionDup = ExAllocatePoolWithTag(NonPagedPool, i, TAG_KDBG); + RtlCopyMemory(ConditionExpressionDup, ConditionExpression, i); + } + else + { + Condition = NULL; + ConditionExpressionDup = NULL; + } - /* 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) - { + /* 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; + } + } - KdbBreakPoints[i].Data.Hw.Size = Size; - KdbBreakPoints[i].Data.Hw.AccessType = AccessType; - } - KdbBreakPointCount++; + ASSERT(i < (LONG)RTL_NUMBER_OF(KdbBreakPoints)); - if (Type != KdbBreakPointTemporary) - KdbpPrint("Breakpoint %d inserted.\n", 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; - /* Try to enable the breakpoint */ - KdbpEnableBreakPoint(i, NULL); + if (Type == KdbBreakPointHardware) + { + KdbBreakPoints[i].Data.Hw.Size = Size; + KdbBreakPoints[i].Data.Hw.AccessType = AccessType; + } - /* Return the breakpoint number */ - if (BreakPointNr != NULL) - *BreakPointNr = i; + KdbBreakPointCount++; - return STATUS_SUCCESS; + 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 @@ -653,39 +680,42 @@ KdbpInsertBreakPoint( */ 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 (BreakPoint->Enabled && - !KdbpDisableBreakPoint(-1, BreakPoint)) - return FALSE; + if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT) + { + KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr); + return FALSE; + } - if (BreakPoint->Type != KdbBreakPointTemporary) - KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr); - BreakPoint->Type = KdbBreakPointNone; - KdbBreakPointCount--; + if (!BreakPoint) + { + BreakPoint = KdbBreakPoints + BreakPointNr; + } - return TRUE; + if (BreakPoint->Type == KdbBreakPointNone) + { + KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr); + return FALSE; + } + + 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 @@ -700,42 +730,45 @@ KdbpDeleteBreakPoint( */ 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); - return -1; + 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; } /*!\brief Enables a breakpoint. @@ -750,148 +783,159 @@ KdbpIsBreakPointOurs( */ 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; - } + if (!BreakPoint) + { + BreakPoint = KdbBreakPoints + BreakPointNr; + } - /* 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); + if (BreakPoint->Type == KdbBreakPointNone) + { + KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr); + return FALSE; + } - /* 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; - } + if (BreakPoint->Enabled) + { + KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr); + return TRUE; + } - /* Enable the global breakpoint */ - KdbTrapFrame.Tf.Dr7 |= (0x2 << (i * 2)); + 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; + } - /* Enable the exact match bits. */ - KdbTrapFrame.Tf.Dr7 |= 0x00000300; + 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; + } - /* Clear existing state. */ - KdbTrapFrame.Tf.Dr7 &= ~(0xF << (16 + (i * 4))); + KdbSwBreakPoints[KdbSwBreakPointCount++] = BreakPoint; + } + else + { + if (BreakPoint->Data.Hw.AccessType == KdbAccessExec) + ASSERT(BreakPoint->Data.Hw.Size == 1); - /* 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))); + ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0); - /* Set the breakpoint length. */ - KdbTrapFrame.Tf.Dr7 |= ((BreakPoint->Data.Hw.Size - 1) << (18 + (i * 4))); + 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); - /* 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; - } + return FALSE; + } - BreakPoint->Data.Hw.DebugReg = i; - KdbHwBreakPoints[KdbHwBreakPointCount++] = BreakPoint; - } + /* 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; + } - BreakPoint->Enabled = TRUE; - if (BreakPoint->Type != KdbBreakPointTemporary) - KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr); - return TRUE; + 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; + } + + BreakPoint->Enabled = TRUE; + if (BreakPoint->Type != KdbBreakPointTemporary) + KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr); + + return TRUE; } /*!\brief Disables a breakpoint. @@ -906,93 +950,98 @@ KdbpEnableBreakPoint( */ 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; - } + if (!BreakPoint) + { + BreakPoint = KdbBreakPoints + BreakPointNr; + } - 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); + if (BreakPoint->Type == KdbBreakPointNone) + { + KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr); + return FALSE; + } - /* 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; - } + if (BreakPoint->Enabled == FALSE) + { + KdbpPrint("Breakpoint %d is not enabled.\n", BreakPointNr); + return TRUE; + } - 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->Type == KdbBreakPointSoftware || + BreakPoint->Type == KdbBreakPointTemporary) + { + ASSERT(KdbSwBreakPointCount > 0); + Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address, + BreakPoint->Data.SavedInstruction, NULL); - BreakPoint->Enabled = FALSE; - if (BreakPoint->Type != KdbBreakPointTemporary) - KdbpPrint("Breakpoint %d disabled.\n", BreakPointNr); - return TRUE; + 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 @@ -1006,15 +1055,15 @@ KdbpDisableBreakPoint( */ 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 @@ -1028,33 +1077,36 @@ KdbpGetEnterCondition( */ 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 @@ -1066,73 +1118,74 @@ KdbpSetEnterCondition( */ 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); + } - ObDereferenceObject(Thread); - return TRUE; + if (KdbOriginalProcess != Process) + { + KeStackAttachProcess(&Process->Pcb, &KdbApcState); + } + + KdbCurrentProcess = Process; + } + + ObDereferenceObject(Thread); + return TRUE; } /*!\brief Switches to another process/thread context @@ -1146,38 +1199,38 @@ KdbpAttachToThread( */ 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. @@ -1187,39 +1240,40 @@ KdbpCallMainLoop(VOID) 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; + /* 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);*/ + /*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); + 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(); + 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; @@ -1282,368 +1336,367 @@ KdbpGetExceptionNumberFromStatus(IN NTSTATUS ExceptionCode) */ 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; + 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); + ExceptionCode = (ExceptionRecord ? ExceptionRecord->ExceptionCode : STATUS_BREAKPOINT); - KdbCurrentProcess = PsGetCurrentProcess(); + KdbCurrentProcess = PsGetCurrentProcess(); - /* Set continue type to kdContinue for single steps and breakpoints */ - if (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT) - ContinueType = kdContinue; + /* 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; - } + /* 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 (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 (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! } - goto continue_execution; /* return */ - } + } - KdbEnteredOnSingleStep = TRUE; - } + if ((BreakPoint->Type == KdbBreakPointHardware) && + (BreakPoint->Data.Hw.AccessType == KdbAccessExec)) + { + Resume = TRUE; /* Set the resume flag when continuing execution */ + } - /* - * 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; - } + /* + * 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); - /* - * Make sure that the breakpoint should be triggered in this context - */ - if (!BreakPoint->Global && BreakPoint->Process != KdbCurrentProcess) - { - goto continue_execution; /* return */ - } + /* Delete the temporary breakpoint which was used to step over or into the instruction. */ + KdbpDeleteBreakPoint(-1, BreakPoint); - /* - * 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 */ - { - 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))) + if (--KdbNumSingleSteps > 0) { - Context->EFlags &= ~EFLAGS_TF; + 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 */ + } + + /* 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 */ + } + + /* 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))) + { + 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"); + 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; - } + 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; - 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; #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; @@ -1668,49 +1721,54 @@ KdbpGetCommandLineSettings(PCHAR p1) } 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; diff --git a/reactos/ntoskrnl/kdbg/kdb_cli.c b/reactos/ntoskrnl/kdbg/kdb_cli.c index b06fd94ef08..163f9fda1cd 100644 --- a/reactos/ntoskrnl/kdbg/kdb_cli.c +++ b/reactos/ntoskrnl/kdbg/kdb_cli.c @@ -103,54 +103,54 @@ BOOLEAN KdbpBugCheckRequested = 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 }, + /* 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 }, + /* 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 }, + /* 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 }, + /* 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 } + /* 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 *****************************************************************/ @@ -165,120 +165,125 @@ static const struct */ static BOOLEAN KdbpGetComponentId( - IN PCCH ComponentName, - OUT PULONG ComponentId) + IN PCCH ComponentName, + OUT PULONG ComponentId) { - ULONG i; + 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 }, + 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... @@ -295,97 +300,108 @@ KdbpGetComponentId( */ 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; + 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); - } + Ok = KdbpRpnEvaluateExpression(Expression, KdbCurrentTrapFrame, Result, + &ExpressionErrOffset, ErrMsgBuffer + 2); + if (!Ok) + { + if (ExpressionErrOffset >= 0) + ExpressionErrOffset += ErrOffset; + else + ErrMsg += 2; - return Ok; + 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; + ULONG i, len; + ULONGLONG Result = 0; + ULONG ul; + LONG l = 0; + BOOLEAN Ok; - if (Argc < 2) - { - KdbpPrint("?: Argument required\n"); - return TRUE; - } + 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] = ' '; - } + /* 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); - } - } + /* 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; - return TRUE; + 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 }, @@ -456,512 +472,555 @@ KdbpCmdFilter(ULONG Argc, PCHAR Argv[]) * 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; + 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 (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--; - } - } + 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++; - } + /* 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("\n"); + /* 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("\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" }; + 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 }; + 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); - Cr0 = KdbCurrentTrapFrame->Cr0; - Cr2 = KdbCurrentTrapFrame->Cr2; - Cr3 = KdbCurrentTrapFrame->Cr3; - Cr4 = KdbCurrentTrapFrame->Cr4; + 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]); + } + } - /* Get descriptor table regs */ - Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&Gdtr.Limit); - Ke386GetLocalDescriptorTable(Ldtr.Limit); - Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Idtr.Limit); + 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 }; - /* Get the task register */ - Ke386GetTr(Tr); + Cr0 = KdbCurrentTrapFrame->Cr0; + Cr2 = KdbCurrentTrapFrame->Cr2; + Cr3 = KdbCurrentTrapFrame->Cr3; + Cr4 = KdbCurrentTrapFrame->Cr4; - /* 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]); - } + /* Get descriptor table regs */ + Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&Gdtr.Limit); + Ke386GetLocalDescriptorTable(Ldtr.Limit); + Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Idtr.Limit); - /* 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; + /* 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; + 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--; - } - } + if (Argc >= 2) + { + /* Check for [L count] part */ + ul = 0; - /* Put the remaining arguments back together */ - Argc--; - for (ul = 1; ul < Argc; ul++) - { - Argv[ul][strlen(Argv[ul])] = ' '; - } - Argc++; - } + 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--; + } + } - /* 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)) + /* 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 - { + } + } + else + { + KdbpPrint("Eip:\n"); - 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"); - } + /* 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; - } - } + KdbpPrint("Frames:\n"); + for (;;) + { + if (Frame == 0) + break; - return TRUE; + 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; + 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 (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; + if (Argv[0][0] == 'n') + KdbSingleStepOver = TRUE; + else + KdbSingleStepOver = FALSE; - /* Set the number of single steps and return to the interrupted code. */ - KdbNumSingleSteps = Count; + /* Set the number of single steps and return to the interrupted code. */ + KdbNumSingleSteps = Count; - return FALSE; + 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]; + 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; - } + 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; - } + 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 (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 (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"), + 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 - { - 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); + } + 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; + PCHAR pend; + ULONG BreakPointNr; - if (Argc < 2) - { - KdbpPrint("%s: argument required\n", Argv[0]); - return TRUE; - } + 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; - } + 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); - } + 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; + return TRUE; } /*!\brief Sets a software or hardware (memory) breakpoint at the given address. @@ -969,934 +1028,1019 @@ KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[]) 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; + 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]); + 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; + AddressArgIndex = 1; + Type = KdbBreakPointSoftware; + } + else /* memory breakpoint */ + { + ASSERT(Argv[0][2] == 'm'); - KdbpInsertBreakPoint(Address, Type, Size, AccessType, - (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex], - Global, NULL); + if (Argc < 2) + { + KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n"); + return TRUE; + } - 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]); + 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[]) +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); + 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" + }; - if (Argc >= 2 && _stricmp(Argv[1], "list") == 0) - { - Process = KdbCurrentProcess; + ASSERT(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; - } + if (Argc >= 2 && _stricmp(Argv[1], "list") == 0) + { + Process = KdbCurrentProcess; - 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; - } + 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; + } - KdbpPrint(" TID State Prior. Affinity EBP EIP\n"); - do - { - Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry); + if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ul, &Process))) + { + KdbpPrint("thread: Invalid process id!\n"); + return TRUE; + } - if (Thread == KdbCurrentThread) - { - str1 = "\x1b[1m*"; - str2 = "\x1b[0m"; - } - else - { - str1 = " "; - str2 = ""; - } + /* Remember our reference */ + ReferencedProcess = TRUE; + } - if (Thread->Tcb.TrapFrame != NULL) - { - if (Thread->Tcb.TrapFrame->PreviousPreviousMode == KernelMode) - Esp = (PULONG)Thread->Tcb.TrapFrame->TempEsp; + 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)) + 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) + { + 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; + } + + 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 + 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); + 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); - Entry = Entry->Flink; - } - while (Entry != &Process->ThreadListHead); + /* Release our reference if we had one */ + if (ReferencedThread) + ObDereferenceObject(Thread); + } - /* 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"); - 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; + 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; + 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]); + if (Argc >= 2 && _stricmp(Argv[1], "list") == 0) + { + Entry = PsActiveProcessHead.Flink; + if (!Entry || Entry == &PsActiveProcessHead) + { + KdbpPrint("No processes in the system!\n"); 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); + 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]); + 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; + 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])] = ' '; + 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; + /* Evaluate the expression */ + if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result)) + { + return TRUE; + } - 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; - } + if (Result > (ULONGLONG)(~((ULONG_PTR)0))) + KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]); - KdbpPrint(" Base Size Name\n"); - for (;;) - { - KdbpPrint(" %08x %08x %ws\n", Info.Base, Info.Size, Info.Name); + Address = (ULONG_PTR)Result; - if ((!DisplayOnlyOneModule && !KdbpSymFindModuleByIndex(i++, &Info)) || - DisplayOnlyOneModule) - { - break; - } - } + if (!KdbpSymFindModuleByAddress((PVOID)Address, &Info)) + { + KdbpPrint("No module containing address 0x%p found!\n", Address); + return TRUE; + } - 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; + 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 (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); + if (Reg.Limit < 7) + { + KdbpPrint("Interrupt descriptor table is empty.\n"); 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"; + KdbpPrint("IDT Base: 0x%08x Limit: 0x%04x\n", Reg.Base, Reg.Limit); + KdbpPrint(" Idx Type Seg. Sel. Offset DPL\n"); - 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; - } + 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; + } - 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); + 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; - } - 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++; - } + 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"); - if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */ - { - switch (Type) + for (; (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); + 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) { - SegBase = 0; - SegLimit = 0; + SegLimit *= 4096; + SegLimit += 4095; } - } - else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */ - { - if ((SegDesc[1] & (1 << 22)) != 0) - SegType = "DATA32"; else - SegType = "DATA16"; + { + SegLimit++; + } - } - else /* Code segment */ - { - if ((SegDesc[1] & (1 << 22)) != 0) - SegType = "CODE32"; - 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); 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(); + 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); + 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; + return TRUE; } /*!\brief Displays the TSS */ static BOOLEAN -KdbpCmdTss(ULONG Argc, PCHAR Argv[]) +KdbpCmdTss( + ULONG Argc, + PCHAR Argv[]) { - KTSS *Tss = KeGetPcr()->TSS; + 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; + 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" }; + "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], + 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]) + 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)); - } - 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) + } + else + { + if (Argc >= 5 && strcmp(Argv[2], "*") == 0) /* Allow * only when setting condition */ { - 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)) - { - KdbpPrint("Unknown exception '%s'.\n", Argv[2]); - return TRUE; - } - } - if (Argc > 4) - { - 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)) - { - 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)); + l = -1; } 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]); + l = strtoul(Argv[2], &pend, 0); - return TRUE; + 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 (Argc > 4) + { + 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)) + { + 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("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; + 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; - } + 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; + } - return TRUE; + KdbpPrint(" %-20s - %s\n", + KdbDebuggerCommands[i].Syntax, + KdbDebuggerCommands[i].Help); + } + + return TRUE; } /*!\brief Prints the given string with printf-like formatting. @@ -1909,213 +2053,228 @@ KdbpCmdHelp(ULONG Argc, PCHAR Argv[]) */ 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; + 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; + /* Check if the user has aborted output of the current command */ + if (KdbOutputAborted) + return; - /* Initialize the terminal */ - if (!TerminalInitialized) - { - DbgPrint("\x1b[7h"); /* Enable linewrap */ + /* Initialize the terminal */ + if (!TerminalInitialized) + { + DbgPrint("\x1b[7h"); /* Enable linewrap */ - /* Query terminal type */ - /*DbgPrint("\x1b[Z");*/ - DbgPrint("\x05"); + /* Query terminal type */ + /*DbgPrint("\x1b[Z");*/ + DbgPrint("\x05"); - TerminalInitialized = TRUE; - Length = 0; - KeStallExecutionProcessor(100000); + 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) - { + 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; - } - } + 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); + /* 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"); + 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++; + /* 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; - /*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/ + 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 ---"); - /* 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 (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; - } + c = KdbpGetCharKeyboard(&ScanCode); - /* 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] == '[') + 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') { - strcpy(p2, p2 + 1); + KdbOutputAborted = TRUE; + return; } - } - } - DbgPrint("%s", p); + KdbNumberOfRowsPrinted = 0; + KdbNumberOfColsPrinted = 0; + } - if (c != '\0') - p[i + 1] = c; + /* 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'; + } - /* 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; - } + /* Remove escape sequences from the line if there's no terminal connected */ + if (!TerminalConnected) + { + while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */ + { + 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; + } } /*!\brief Appends a command to the command history @@ -2124,67 +2283,69 @@ KdbpPrint( */ static VOID KdbpCommandHistoryAppend( - IN PCHAR Command) + IN PCHAR Command) { - ULONG Length1 = strlen(Command) + 1; - ULONG Length2 = 0; - INT i; - PCHAR Buffer; + ULONG Length1 = strlen(Command) + 1; + ULONG Length2 = 0; + INT i; + PCHAR Buffer; - ASSERT(Length1 <= RTL_NUMBER_OF(KdbCommandHistoryBuffer)); + ASSERT(Length1 <= RTL_NUMBER_OF(KdbCommandHistoryBuffer)); - if (Length1 <= 1 || - (KdbCommandHistory[KdbCommandHistoryIndex] != NULL && - strcmp(KdbCommandHistory[KdbCommandHistoryIndex], Command) == 0)) - { - return; - } + 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; - } + /* 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; - } + /* 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; + } - /* Make sure the new command history entry is free */ - KdbCommandHistoryIndex++; - KdbCommandHistoryIndex %= RTL_NUMBER_OF(KdbCommandHistory); - if (KdbCommandHistory[KdbCommandHistoryIndex] != NULL) - { - KdbCommandHistory[KdbCommandHistoryIndex] = NULL; - } + i--; + if (i < 0) + i = RTL_NUMBER_OF(KdbCommandHistory) - 1; - /* 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); - } + 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. @@ -2196,174 +2357,192 @@ KdbpCommandHistoryAppend( */ 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; + 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); + 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 == '[') - { - 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 */ + for (;;) + { + if (KdbDebugState & KD_DEBUG_KDSERIAL) + { + Key = (NextKey == '\0') ? KdbpGetCharSerial() : 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; - else - Print = FALSE; - } - if (Print && KdbCommandHistory[CmdHistIndex] != NULL) - { - while (Buffer > Orig) + ScanCode = 0; + if (Key == KEY_ESC) /* ESC */ { - 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 (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) - { - 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); + Key = KdbpGetCharSerial(); + if (Key == '[') + { + Key = KdbpGetCharSerial(); - *Buffer = Key; - Buffer++; - } - } + 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 */ + 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] && 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); + } + } + 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]) + { + 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++; + } + } } /*!\brief Parses command line and executes command if found @@ -2375,50 +2554,54 @@ KdbpReadCommand( */ static BOOLEAN KdbpDoCommand( - IN PCHAR Command) + IN PCHAR Command) { - ULONG i; - PCHAR p; - ULONG Argc; - static PCH Argv[256]; - static CHAR OrigCommand[1024]; + 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'; + 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; + Argc = 0; + p = Command; - i = strcspn(p, "\t "); - Argv[Argc++] = p; - p += i; - if (*p == '\0') - break; - *p = '\0'; - p++; - } - if (Argc < 1) - return TRUE; + for (;;) + { + while (*p == '\t' || *p == ' ') + p++; - for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++) - { - if (KdbDebuggerCommands[i].Name == NULL) - continue; + if (*p == '\0') + break; - if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0) - { - return KdbDebuggerCommands[i].Fn(Argc, Argv); - } - } + i = strcspn(p, "\t "); + Argv[Argc++] = p; + p += i; + if (*p == '\0') + break; - KdbpPrint("Command '%s' is unknown.\n", OrigCommand); - return TRUE; + *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. @@ -2427,53 +2610,55 @@ KdbpDoCommand( */ VOID KdbpCliMainLoop( - IN BOOLEAN EnteredOnSingleStep) + IN BOOLEAN EnteredOnSingleStep) { - static CHAR Command[1024]; - BOOLEAN 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(""); - } - KdbpPrint("\n"); - } + if (EnteredOnSingleStep) + { + if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip)) + { + KdbpPrint("<%x>", KdbCurrentTrapFrame->Tf.Eip); + } - /* Flush the input buffer */ - if (KdbDebugState & KD_DEBUG_KDSERIAL) - { - while (KdbpTryGetCharSerial(1) != -1); - } - else - { - ULONG ScanCode; - while (KdbpTryGetCharKeyboard(&ScanCode, 1) != -1); - } + KdbpPrint(": "); + if (KdbpDisassemble(KdbCurrentTrapFrame->Tf.Eip, KdbUseIntelSyntax) < 0) + { + KdbpPrint(""); + } + KdbpPrint("\n"); + } - /* Main loop */ - do - { - /* Print the prompt */ - KdbpPrint("kdb:> "); + /* Flush the input buffer */ + if (KdbDebugState & KD_DEBUG_KDSERIAL) + { + while (KdbpTryGetCharSerial(1) != -1); + } + else + { + ULONG ScanCode; + while (KdbpTryGetCharKeyboard(&ScanCode, 1) != -1); + } - /* Read a command and remember it */ - KdbpReadCommand(Command, sizeof (Command)); - KdbpCommandHistoryAppend(Command); + /* Main loop */ + do + { + /* Print the prompt */ + KdbpPrint("kdb:> "); - /* Reset the number of rows/cols printed and output aborted state */ - KdbNumberOfRowsPrinted = KdbNumberOfColsPrinted = 0; - KdbOutputAborted = FALSE; + /* Read a command and remember it */ + KdbpReadCommand(Command, sizeof (Command)); + KdbpCommandHistoryAppend(Command); - /* Call the command */ - Continue = KdbpDoCommand(Command); - } while (Continue); + /* 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. @@ -2481,13 +2666,14 @@ KdbpCliMainLoop( * \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... @@ -2499,43 +2685,46 @@ KdbpCliModuleLoaded(IN PUNICODE_STRING Name) VOID KdbpCliInterpretInitFile() { - PCHAR p1, p2; - INT i; - CHAR c; + 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'; + /* 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); - } + /* Look for "break" command and comments */ + p2 = p1; - p1[i] = c; - } - p1 += i; - while (p1[0] == '\r' || p1[0] == '\n') - p1++; - } - DPRINT("KDB: KDBinit executed\n"); + 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 @@ -2545,74 +2734,75 @@ KdbpCliInterpretInitFile() 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; + 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); + /* 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; - } + /* 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; + /* 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; - } + /* 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'; + /* Load file into memory */ + Status = ZwReadFile(hFile, 0, 0, 0, &Iosb, FileBuffer, FileSize, 0, 0); + ZwClose(hFile); - /* Enter critical section */ - Ke386SaveFlags(OldEflags); - _disable(); + 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; + } - /* Interpret the init file... */ - KdbInitFileBuffer = FileBuffer; - KdbEnter(); - KdbInitFileBuffer = NULL; + FileSize = min(FileSize, (INT)Iosb.Information); + FileBuffer[FileSize] = '\0'; - /* Leave critical section */ - Ke386RestoreFlags(OldEflags); + /* Enter critical section */ + Ke386SaveFlags(OldEflags); + _disable(); - ExFreePool(FileBuffer); + /* Interpret the init file... */ + KdbInitFileBuffer = FileBuffer; + KdbEnter(); + KdbInitFileBuffer = NULL; + + /* Leave critical section */ + Ke386RestoreFlags(OldEflags); + + ExFreePool(FileBuffer); } - diff --git a/reactos/ntoskrnl/kdbg/kdb_expr.c b/reactos/ntoskrnl/kdbg/kdb_expr.c index 456ae809af2..1c29a126052 100644 --- a/reactos/ntoskrnl/kdbg/kdb_expr.c +++ b/reactos/ntoskrnl/kdbg/kdb_expr.c @@ -40,38 +40,42 @@ /* TYPES *********************************************************************/ typedef enum _RPN_OP_TYPE { - RpnOpNop, - RpnOpBinaryOperator, - RpnOpUnaryOperator, - RpnOpImmediate, - RpnOpRegister, - RpnOpDereference + RpnOpNop, + RpnOpBinaryOperator, + RpnOpUnaryOperator, + RpnOpImmediate, + RpnOpRegister, + RpnOpDereference } RPN_OP_TYPE; typedef ULONGLONG (*RPN_BINARY_OPERATOR)(ULONGLONG a, ULONGLONG b); typedef struct _RPN_OP { - RPN_OP_TYPE Type; - ULONG CharacterOffset; - union { - /* RpnOpBinaryOperator */ - RPN_BINARY_OPERATOR BinaryOperator; - /* RpnOpImmediate */ - ULONGLONG Immediate; - /* RpnOpRegister */ - UCHAR Register; - /* RpnOpDereference */ - UCHAR DerefMemorySize; - } Data; -} RPN_OP, *PRPN_OP; + RPN_OP_TYPE Type; + ULONG CharacterOffset; + union + { + /* RpnOpBinaryOperator */ + RPN_BINARY_OPERATOR BinaryOperator; + /* RpnOpImmediate */ + ULONGLONG Immediate; + /* RpnOpRegister */ + UCHAR Register; + /* RpnOpDereference */ + UCHAR DerefMemorySize; + } + Data; +} +RPN_OP, *PRPN_OP; typedef struct _RPN_STACK { - ULONG Size; /* Number of RPN_OPs on Ops */ - ULONG Sp; /* Stack pointer */ - RPN_OP Ops[1]; /* Array of RPN_OPs */ -} RPN_STACK, *PRPN_STACK; + ULONG Size; /* Number of RPN_OPs on Ops */ + ULONG Sp; /* Stack pointer */ + RPN_OP Ops[1]; /* Array of RPN_OPs */ +} +RPN_STACK, *PRPN_STACK; /* DEFINES *******************************************************************/ #define stricmp _stricmp @@ -81,113 +85,149 @@ typedef struct _RPN_STACK #endif #define CONST_STRCPY(dst, src) \ - do { if ((dst) != NULL) { memcpy(dst, src, sizeof(src)); } } while (0); + do { if ((dst)) { memcpy(dst, src, sizeof(src)); } } while (0); #define RPN_OP_STACK_SIZE 256 #define RPN_VALUE_STACK_SIZE 256 /* GLOBALS *******************************************************************/ -static struct { ULONG Size; ULONG Sp; RPN_OP Ops[RPN_OP_STACK_SIZE]; } RpnStack = { RPN_OP_STACK_SIZE, 0 }; - -static const struct { PCHAR Name; UCHAR Offset; UCHAR Size; } RegisterToTrapFrame[] = +static struct { - {"eip", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eip), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eip)}, - {"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.EFlags)}, - {"eax", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eax), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eax)}, - {"ebx", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebx)}, - {"ecx", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ecx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ecx)}, - {"edx", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edx)}, - {"esi", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Esi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Esi)}, - {"edi", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edi)}, - {"esp", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.HardwareEsp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.HardwareEsp)}, - {"ebp", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebp)}, - {"cs", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegCs), 2 }, /* Use only the lower 2 bytes */ - {"ds", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegDs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegDs)}, - {"es", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegEs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegEs)}, - {"fs", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegFs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegFs)}, - {"gs", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegGs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegGs)}, - {"ss", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.HardwareSegSs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.HardwareSegSs)}, - {"dr0", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr0), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr0)}, - {"dr1", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr1), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr1)}, - {"dr2", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr2), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr2)}, - {"dr3", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr3), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr3)}, - {"dr6", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr6), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr6)}, - {"dr7", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr7), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr7)}, - {"cr0", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr0), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr0)}, - {"cr2", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr2), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr2)}, - {"cr3", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr3), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr3)}, - {"cr4", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr4), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr4)} + ULONG Size; + ULONG Sp; + RPN_OP Ops[RPN_OP_STACK_SIZE]; +} +RpnStack = +{ + RPN_OP_STACK_SIZE, + 0 }; -static const INT RegisterToTrapFrameCount = - sizeof (RegisterToTrapFrame) / sizeof (RegisterToTrapFrame[0]); + +static const struct +{ + PCHAR Name; + UCHAR Offset; + UCHAR Size; +} +RegisterToTrapFrame[] = +{ + {"eip", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eip), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eip)}, + {"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.EFlags)}, + {"eax", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eax), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eax)}, + {"ebx", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebx)}, + {"ecx", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ecx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ecx)}, + {"edx", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edx)}, + {"esi", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Esi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Esi)}, + {"edi", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edi)}, + {"esp", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.HardwareEsp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.HardwareEsp)}, + {"ebp", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebp)}, + {"cs", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegCs), 2 }, /* Use only the lower 2 bytes */ + {"ds", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegDs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegDs)}, + {"es", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegEs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegEs)}, + {"fs", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegFs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegFs)}, + {"gs", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegGs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegGs)}, + {"ss", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.HardwareSegSs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.HardwareSegSs)}, + {"dr0", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr0), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr0)}, + {"dr1", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr1), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr1)}, + {"dr2", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr2), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr2)}, + {"dr3", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr3), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr3)}, + {"dr6", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr6), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr6)}, + {"dr7", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr7), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr7)}, + {"cr0", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr0), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr0)}, + {"cr2", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr2), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr2)}, + {"cr3", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr3), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr3)}, + {"cr4", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr4), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr4)} +}; +static const INT RegisterToTrapFrameCount = sizeof (RegisterToTrapFrame) / sizeof (RegisterToTrapFrame[0]); /* FUNCTIONS *****************************************************************/ ULONGLONG -RpnBinaryOperatorAdd(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorAdd( + ULONGLONG a, + ULONGLONG b) { - return a + b; + return a + b; } ULONGLONG -RpnBinaryOperatorSub(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorSub( + ULONGLONG a, + ULONGLONG b) { - return a - b; + return a - b; } ULONGLONG -RpnBinaryOperatorMul(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorMul( + ULONGLONG a, + ULONGLONG b) { - return a * b; + return a * b; } ULONGLONG -RpnBinaryOperatorDiv(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorDiv( + ULONGLONG a, + ULONGLONG b) { - - return a / b; + return a / b; } ULONGLONG -RpnBinaryOperatorMod(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorMod( + ULONGLONG a, + ULONGLONG b) { - return a % b; + return a % b; } ULONGLONG -RpnBinaryOperatorEquals(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorEquals( + ULONGLONG a, + ULONGLONG b) { - return (a == b); + return (a == b); } ULONGLONG -RpnBinaryOperatorNotEquals(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorNotEquals( + ULONGLONG a, + ULONGLONG b) { - return (a != b); + return (a != b); } ULONGLONG -RpnBinaryOperatorLessThan(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorLessThan( + ULONGLONG a, + ULONGLONG b) { - return (a < b); + return (a < b); } ULONGLONG -RpnBinaryOperatorLessThanOrEquals(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorLessThanOrEquals( + ULONGLONG a, + ULONGLONG b) { - return (a <= b); + return (a <= b); } ULONGLONG -RpnBinaryOperatorGreaterThan(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorGreaterThan( + ULONGLONG a, + ULONGLONG b) { - return (a > b); + return (a > b); } ULONGLONG -RpnBinaryOperatorGreaterThanOrEquals(ULONGLONG a, ULONGLONG b) +RpnBinaryOperatorGreaterThanOrEquals( + ULONGLONG a, + ULONGLONG b) { - return (a >= b); + return (a >= b); } /*!\brief Dumps the given RPN stack content @@ -196,72 +236,73 @@ RpnBinaryOperatorGreaterThanOrEquals(ULONGLONG a, ULONGLONG b) */ VOID RpnpDumpStack( - IN PRPN_STACK Stack) + IN PRPN_STACK Stack) { - ULONG ul; + ULONG ul; - ASSERT(Stack != NULL); - DbgPrint("\nStack size: %ld\n", Stack->Sp); - for (ul = 0; ul < Stack->Sp; ul++) - { - PRPN_OP Op = Stack->Ops + ul; - switch (Op->Type) - { - case RpnOpNop: - DbgPrint("NOP,"); - break; + ASSERT(Stack); + DbgPrint("\nStack size: %ld\n", Stack->Sp); - case RpnOpImmediate: - DbgPrint("0x%I64x,", Op->Data.Immediate); - break; + for (ul = 0; ul < Stack->Sp; ul++) + { + PRPN_OP Op = Stack->Ops + ul; + switch (Op->Type) + { + case RpnOpNop: + DbgPrint("NOP,"); + break; - case RpnOpBinaryOperator: - if (Op->Data.BinaryOperator == RpnBinaryOperatorAdd) - DbgPrint("+,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorSub) - DbgPrint("-,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorMul) - DbgPrint("*,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorDiv) - DbgPrint("/,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorMod) - DbgPrint("%%,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorEquals) - DbgPrint("==,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorNotEquals) - DbgPrint("!=,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorLessThan) - DbgPrint("<,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorLessThanOrEquals) - DbgPrint("<=,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorGreaterThan) - DbgPrint(">,"); - else if (Op->Data.BinaryOperator == RpnBinaryOperatorGreaterThanOrEquals) - DbgPrint(">=,"); - else - DbgPrint("UNKNOWN OP,"); - break; + case RpnOpImmediate: + DbgPrint("0x%I64x,", Op->Data.Immediate); + break; - case RpnOpRegister: - DbgPrint("%s,", RegisterToTrapFrame[Op->Data.Register].Name); - break; + case RpnOpBinaryOperator: + if (Op->Data.BinaryOperator == RpnBinaryOperatorAdd) + DbgPrint("+,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorSub) + DbgPrint("-,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorMul) + DbgPrint("*,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorDiv) + DbgPrint("/,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorMod) + DbgPrint("%%,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorEquals) + DbgPrint("==,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorNotEquals) + DbgPrint("!=,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorLessThan) + DbgPrint("<,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorLessThanOrEquals) + DbgPrint("<=,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorGreaterThan) + DbgPrint(">,"); + else if (Op->Data.BinaryOperator == RpnBinaryOperatorGreaterThanOrEquals) + DbgPrint(">=,"); + else + DbgPrint("UNKNOWN OP,"); - case RpnOpDereference: - DbgPrint("[%s],", - (Op->Data.DerefMemorySize == 1) ? ("byte") : - ((Op->Data.DerefMemorySize == 2) ? ("word") : - ((Op->Data.DerefMemorySize == 4) ? ("dword") : ("qword")) - ) - ); - break; + break; - default: - DbgPrint("\nUnsupported Type: %d\n", Op->Type); - ul = Stack->Sp; - break; - } - } - DbgPrint("\n"); + case RpnOpRegister: + DbgPrint("%s,", RegisterToTrapFrame[Op->Data.Register].Name); + break; + + case RpnOpDereference: + DbgPrint("[%s],", + (Op->Data.DerefMemorySize == 1) ? ("byte") : + ((Op->Data.DerefMemorySize == 2) ? ("word") : + ((Op->Data.DerefMemorySize == 4) ? ("dword") : ("qword")))); + break; + + default: + DbgPrint("\nUnsupported Type: %d\n", Op->Type); + ul = Stack->Sp; + break; + } + } + + DbgPrint("\n"); } /*!\brief Clears the given RPN stack. @@ -270,10 +311,10 @@ RpnpDumpStack( */ static VOID RpnpClearStack( - OUT PRPN_STACK Stack) + OUT PRPN_STACK Stack) { - ASSERT(Stack != NULL); - Stack->Sp = 0; + ASSERT(Stack); + Stack->Sp = 0; } /*!\brief Pushes an RPN_OP onto the stack. @@ -283,18 +324,19 @@ RpnpClearStack( */ static BOOLEAN RpnpPushStack( - IN OUT PRPN_STACK Stack, - IN PRPN_OP Op) + IN OUT PRPN_STACK Stack, + IN PRPN_OP Op) { - ASSERT(Stack != NULL); - ASSERT(Op != NULL); + ASSERT(Stack); + ASSERT(Op); - if (Stack->Sp >= Stack->Size) - return FALSE; + if (Stack->Sp >= Stack->Size) + return FALSE; - memcpy(Stack->Ops + Stack->Sp, Op, sizeof (RPN_OP)); - Stack->Sp++; - return TRUE; + memcpy(Stack->Ops + Stack->Sp, Op, sizeof (RPN_OP)); + Stack->Sp++; + + return TRUE; } /*!\brief Pops the top op from the stack. @@ -307,18 +349,19 @@ RpnpPushStack( */ static BOOLEAN RpnpPopStack( - IN OUT PRPN_STACK Stack, - OUT PRPN_OP Op OPTIONAL) + IN OUT PRPN_STACK Stack, + OUT PRPN_OP Op OPTIONAL) { - ASSERT(Stack != NULL); + ASSERT(Stack); - if (Stack->Sp == 0) - return FALSE; + if (Stack->Sp == 0) + return FALSE; - Stack->Sp--; - if (Op != NULL) - memcpy(Op, Stack->Ops + Stack->Sp, sizeof (RPN_OP)); - return TRUE; + Stack->Sp--; + if (Op) + memcpy(Op, Stack->Ops + Stack->Sp, sizeof (RPN_OP)); + + return TRUE; } /*!\brief Gets the top op from the stack (not popping it) @@ -331,17 +374,18 @@ RpnpPopStack( */ static BOOLEAN RpnpTopStack( - IN PRPN_STACK Stack, - OUT PRPN_OP Op) + IN PRPN_STACK Stack, + OUT PRPN_OP Op) { - ASSERT(Stack != NULL); - ASSERT(Op != NULL); + ASSERT(Stack); + ASSERT(Op); - if (Stack->Sp == 0) - return FALSE; + if (Stack->Sp == 0) + return FALSE; - memcpy(Op, Stack->Ops + Stack->Sp - 1, sizeof (RPN_OP)); - return TRUE; + memcpy(Op, Stack->Ops + Stack->Sp - 1, sizeof (RPN_OP)); + + return TRUE; } /*!\brief Parses an expression. @@ -364,414 +408,463 @@ RpnpTopStack( */ static BOOLEAN RpnpParseExpression( - IN PRPN_STACK Stack, - IN PCHAR Expression, - OUT PCHAR *End OPTIONAL, - IN ULONG CharacterOffset, - OUT PLONG ErrOffset OPTIONAL, - OUT PCHAR ErrMsg OPTIONAL) + IN PRPN_STACK Stack, + IN PCHAR Expression, + OUT PCHAR *End OPTIONAL, + IN ULONG CharacterOffset, + OUT PLONG ErrOffset OPTIONAL, + OUT PCHAR ErrMsg OPTIONAL) { - PCHAR p = Expression; - PCHAR pend; - PCHAR Operator = NULL; - LONG OperatorOffset = -1; - RPN_OP RpnOp; - RPN_OP PoppedOperator; - BOOLEAN HavePoppedOperator = FALSE; - RPN_OP ComparativeOp; - BOOLEAN ComparativeOpFilled = FALSE; - BOOLEAN IsComparativeOp; - INT i, i2; - ULONG ul; - UCHAR MemorySize; - CHAR Buffer[16]; - BOOLEAN First; + PCHAR p = Expression; + PCHAR pend; + PCHAR Operator = NULL; + LONG OperatorOffset = -1; + RPN_OP RpnOp; + RPN_OP PoppedOperator; + BOOLEAN HavePoppedOperator = FALSE; + RPN_OP ComparativeOp; + BOOLEAN ComparativeOpFilled = FALSE; + BOOLEAN IsComparativeOp; + INT i, i2; + ULONG ul; + UCHAR MemorySize; + CHAR Buffer[16]; + BOOLEAN First; - ASSERT(Stack != NULL); - ASSERT(Expression != NULL); + ASSERT(Stack); + ASSERT(Expression); - First = TRUE; - for (;;) - { - /* Skip whitespace */ - while (isspace(*p)) - { - p++; - CharacterOffset++; - } - - /* Check for end of expression */ - if (p[0] == '\0' || p[0] == ')' || p[0] == ']') - break; - - if (!First) - { - /* Remember operator */ - Operator = p++; - OperatorOffset = CharacterOffset++; - - /* Pop operator (to get the right operator precedence) */ - HavePoppedOperator = FALSE; - if (*Operator == '*' || *Operator == '/' || *Operator == '%') - { - if (RpnpTopStack(Stack, &PoppedOperator) && - PoppedOperator.Type == RpnOpBinaryOperator && - (PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorAdd || - PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorSub)) - { - RpnpPopStack(Stack, NULL); - HavePoppedOperator = TRUE; - } - else if (PoppedOperator.Type == RpnOpNop) - { - RpnpPopStack(Stack, NULL); - /* Discard the NOP - it was only pushed to indicate there was a - * closing brace, so the previous operator shouldn't be popped. - */ - } - } - else if ((Operator[0] == '=' && Operator[1] == '=') || - (Operator[0] == '!' && Operator[1] == '=') || - Operator[0] == '<' || Operator[0] == '>') - { - if (Operator[0] == '=' || Operator[0] == '!' || - (Operator[0] == '<' && Operator[1] == '=') || - (Operator[0] == '>' && Operator[1] == '=')) - { - p++; - CharacterOffset++; - } -#if 0 - /* Parse rest of expression */ - if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1, - ErrOffset, ErrMsg)) - { - return FALSE; - } - else if (pend == p + 1) - { - CONST_STRCPY(ErrMsg, "Expression expected"); - if (ErrOffset != NULL) - *ErrOffset = CharacterOffset + 1; - return FALSE; - } - goto end_of_expression; /* return */ -#endif - } - else if (Operator[0] != '+' && Operator[0] != '-') - { - CONST_STRCPY(ErrMsg, "Operator expected"); - if (ErrOffset != NULL) - *ErrOffset = OperatorOffset; - return FALSE; - } - - /* Skip whitespace */ - while (isspace(*p)) - { + First = TRUE; + for (;;) + { + /* Skip whitespace */ + while (isspace(*p)) + { p++; CharacterOffset++; - } - } + } + + /* Check for end of expression */ + if (p[0] == '\0' || p[0] == ')' || p[0] == ']') + break; + + if (!First) + { + /* Remember operator */ + Operator = p++; + OperatorOffset = CharacterOffset++; + + /* Pop operator (to get the right operator precedence) */ + HavePoppedOperator = FALSE; + if (*Operator == '*' || *Operator == '/' || *Operator == '%') + { + if (RpnpTopStack(Stack, &PoppedOperator) && + PoppedOperator.Type == RpnOpBinaryOperator && + (PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorAdd || + PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorSub)) + { + RpnpPopStack(Stack, NULL); + HavePoppedOperator = TRUE; + } + else if (PoppedOperator.Type == RpnOpNop) + { + RpnpPopStack(Stack, NULL); + /* Discard the NOP - it was only pushed to indicate there was a + * closing brace, so the previous operator shouldn't be popped. + */ + } + } + else if ((Operator[0] == '=' && Operator[1] == '=') || + (Operator[0] == '!' && Operator[1] == '=') || + Operator[0] == '<' || Operator[0] == '>') + { + if (Operator[0] == '=' || Operator[0] == '!' || + (Operator[0] == '<' && Operator[1] == '=') || + (Operator[0] == '>' && Operator[1] == '=')) + { + p++; + CharacterOffset++; + } +#if 0 + /* Parse rest of expression */ + if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1, + ErrOffset, ErrMsg)) + { + return FALSE; + } + else if (pend == p + 1) + { + CONST_STRCPY(ErrMsg, "Expression expected"); + + if (ErrOffset) + *ErrOffset = CharacterOffset + 1; + + return FALSE; + } + + goto end_of_expression; /* return */ +#endif + } + else if (Operator[0] != '+' && Operator[0] != '-') + { + CONST_STRCPY(ErrMsg, "Operator expected"); + + if (ErrOffset) + *ErrOffset = OperatorOffset; + + return FALSE; + } + + /* Skip whitespace */ + while (isspace(*p)) + { + p++; + CharacterOffset++; + } + } + + /* Get operand */ + MemorySize = sizeof(ULONG_PTR); /* default to pointer size */ - /* Get operand */ - MemorySize = sizeof(ULONG_PTR); /* default to pointer size */ get_operand: - i = strcspn(p, "+-*/%()[]<>!="); - if (i > 0) - { - i2 = i; + i = strcspn(p, "+-*/%()[]<>!="); + if (i > 0) + { + i2 = i; - /* Copy register name/memory size */ - while (isspace(p[--i2])); - i2 = min(i2 + 1, (INT)sizeof (Buffer) - 1); - strncpy(Buffer, p, i2); - Buffer[i2] = '\0'; + /* Copy register name/memory size */ + while (isspace(p[--i2])); - /* Memory size prefix */ - if (p[i] == '[') - { - if (stricmp(Buffer, "byte") == 0) - MemorySize = 1; - else if (stricmp(Buffer, "word") == 0) - MemorySize = 2; - else if (stricmp(Buffer, "dword") == 0) - MemorySize = 4; - else if (stricmp(Buffer, "qword") == 0) - MemorySize = 8; - else + i2 = min(i2 + 1, (INT)sizeof (Buffer) - 1); + strncpy(Buffer, p, i2); + Buffer[i2] = '\0'; + + /* Memory size prefix */ + if (p[i] == '[') { - CONST_STRCPY(ErrMsg, "Invalid memory size prefix"); - if (ErrOffset != NULL) - *ErrOffset = CharacterOffset; - return FALSE; + if (stricmp(Buffer, "byte") == 0) + MemorySize = 1; + else if (stricmp(Buffer, "word") == 0) + MemorySize = 2; + else if (stricmp(Buffer, "dword") == 0) + MemorySize = 4; + else if (stricmp(Buffer, "qword") == 0) + MemorySize = 8; + else + { + CONST_STRCPY(ErrMsg, "Invalid memory size prefix"); + + if (ErrOffset) + *ErrOffset = CharacterOffset; + + return FALSE; + } + + p += i; + CharacterOffset += i; + goto get_operand; } - p += i; - CharacterOffset += i; - goto get_operand; - } - - /* Try to find register */ - for (i = 0; i < RegisterToTrapFrameCount; i++) - { - if (stricmp(RegisterToTrapFrame[i].Name, Buffer) == 0) - break; - } - if (i < RegisterToTrapFrameCount) - { - RpnOp.Type = RpnOpRegister; - RpnOp.CharacterOffset = CharacterOffset; - RpnOp.Data.Register = i; - i = strlen(RegisterToTrapFrame[i].Name); - CharacterOffset += i; - p += i; - } - else - { - /* Immediate value */ - /* FIXME: Need string to ULONGLONG function */ - ul = strtoul(p, &pend, 0); - if (p != pend) + /* Try to find register */ + for (i = 0; i < RegisterToTrapFrameCount; i++) { - RpnOp.Type = RpnOpImmediate; - RpnOp.CharacterOffset = CharacterOffset; - RpnOp.Data.Immediate = (ULONGLONG)ul; - CharacterOffset += pend - p; - p = pend; + if (stricmp(RegisterToTrapFrame[i].Name, Buffer) == 0) + break; + } + + if (i < RegisterToTrapFrameCount) + { + RpnOp.Type = RpnOpRegister; + RpnOp.CharacterOffset = CharacterOffset; + RpnOp.Data.Register = i; + i = strlen(RegisterToTrapFrame[i].Name); + CharacterOffset += i; + p += i; } else { - CONST_STRCPY(ErrMsg, "Operand expected"); - if (ErrOffset != NULL) - *ErrOffset = CharacterOffset; - return FALSE; - } - } + /* Immediate value */ + /* FIXME: Need string to ULONGLONG function */ + ul = strtoul(p, &pend, 0); + if (p != pend) + { + RpnOp.Type = RpnOpImmediate; + RpnOp.CharacterOffset = CharacterOffset; + RpnOp.Data.Immediate = (ULONGLONG)ul; + CharacterOffset += pend - p; + p = pend; + } + else + { + CONST_STRCPY(ErrMsg, "Operand expected"); - /* Push operand */ - if (!RpnpPushStack(Stack, &RpnOp)) - { - CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } - } - else if (i == 0) - { - if (p[0] == '(' || p[0] == '[') /* subexpression */ - { - if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1, - ErrOffset, ErrMsg)) - { - return FALSE; - } - else if (pend == p + 1) - { - CONST_STRCPY(ErrMsg, "Expression expected"); - if (ErrOffset != NULL) - *ErrOffset = CharacterOffset + 1; - return FALSE; + if (ErrOffset) + *ErrOffset = CharacterOffset; + + return FALSE; + } } - if (p[0] == '[') /* dereference */ - { - ASSERT(MemorySize == 1 || MemorySize == 2 || - MemorySize == 4 || MemorySize == 8); - if (pend[0] != ']') - { - CONST_STRCPY(ErrMsg, "']' expected"); - if (ErrOffset != NULL) - *ErrOffset = CharacterOffset + (pend - p); - return FALSE; - } - RpnOp.Type = RpnOpDereference; - RpnOp.CharacterOffset = CharacterOffset; - RpnOp.Data.DerefMemorySize = MemorySize; - if (!RpnpPushStack(Stack, &RpnOp)) - { - CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } - } - else /* p[0] == '(' */ - { - if (pend[0] != ')') - { - CONST_STRCPY(ErrMsg, "')' expected"); - if (ErrOffset != NULL) - *ErrOffset = CharacterOffset + (pend - p); - return FALSE; - } - } - - /* Push a "nop" to prevent popping of the + operator (which would - * result in (10+10)/2 beeing evaluated as 15) - */ - RpnOp.Type = RpnOpNop; + /* Push operand */ if (!RpnpPushStack(Stack, &RpnOp)) { - CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; + CONST_STRCPY(ErrMsg, "RPN op stack overflow"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; } - - /* Skip closing brace/bracket */ - pend++; - - CharacterOffset += pend - p; - p = pend; - } - else if (First && p[0] == '-') /* Allow expressions like "- eax" */ - { - RpnOp.Type = RpnOpImmediate; - RpnOp.CharacterOffset = CharacterOffset; - RpnOp.Data.Immediate = 0; - if (!RpnpPushStack(Stack, &RpnOp)) + } + else if (i == 0) + { + if (p[0] == '(' || p[0] == '[') /* subexpression */ { - CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; + if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1, + ErrOffset, ErrMsg)) + { + return FALSE; + } + else if (pend == p + 1) + { + CONST_STRCPY(ErrMsg, "Expression expected"); + + if (ErrOffset) + *ErrOffset = CharacterOffset + 1; + + return FALSE; + } + + if (p[0] == '[') /* dereference */ + { + ASSERT(MemorySize == 1 || MemorySize == 2 || + MemorySize == 4 || MemorySize == 8); + + if (pend[0] != ']') + { + CONST_STRCPY(ErrMsg, "']' expected"); + + if (ErrOffset) + *ErrOffset = CharacterOffset + (pend - p); + + return FALSE; + } + + RpnOp.Type = RpnOpDereference; + RpnOp.CharacterOffset = CharacterOffset; + RpnOp.Data.DerefMemorySize = MemorySize; + + if (!RpnpPushStack(Stack, &RpnOp)) + { + CONST_STRCPY(ErrMsg, "RPN op stack overflow"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; + } + } + else /* p[0] == '(' */ + { + if (pend[0] != ')') + { + CONST_STRCPY(ErrMsg, "')' expected"); + + if (ErrOffset) + *ErrOffset = CharacterOffset + (pend - p); + + return FALSE; + } + } + + /* Push a "nop" to prevent popping of the + operator (which would + * result in (10+10)/2 beeing evaluated as 15) + */ + RpnOp.Type = RpnOpNop; + if (!RpnpPushStack(Stack, &RpnOp)) + { + CONST_STRCPY(ErrMsg, "RPN op stack overflow"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; + } + + /* Skip closing brace/bracket */ + pend++; + + CharacterOffset += pend - p; + p = pend; } - } - else - { - CONST_STRCPY(ErrMsg, "Operand expected"); - if (ErrOffset != NULL) - *ErrOffset = CharacterOffset; - return FALSE; - } - } - else - { - CONST_STRCPY(ErrMsg, "strcspn() failed"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } + else if (First && p[0] == '-') /* Allow expressions like "- eax" */ + { + RpnOp.Type = RpnOpImmediate; + RpnOp.CharacterOffset = CharacterOffset; + RpnOp.Data.Immediate = 0; - if (!First) - { - /* Push operator */ - RpnOp.CharacterOffset = OperatorOffset; - RpnOp.Type = RpnOpBinaryOperator; - IsComparativeOp = FALSE; - switch (*Operator) - { - case '+': - RpnOp.Data.BinaryOperator = RpnBinaryOperatorAdd; - break; + if (!RpnpPushStack(Stack, &RpnOp)) + { + CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - case '-': - RpnOp.Data.BinaryOperator = RpnBinaryOperatorSub; - break; + if (ErrOffset) + *ErrOffset = -1; - case '*': - RpnOp.Data.BinaryOperator = RpnBinaryOperatorMul; - break; - - case '/': - RpnOp.Data.BinaryOperator = RpnBinaryOperatorDiv; - break; - - case '%': - RpnOp.Data.BinaryOperator = RpnBinaryOperatorMod; - break; - - case '=': - ASSERT(Operator[1] == '='); - IsComparativeOp = TRUE; - RpnOp.Data.BinaryOperator = RpnBinaryOperatorEquals; - break; - - case '!': - ASSERT(Operator[1] == '='); - IsComparativeOp = TRUE; - RpnOp.Data.BinaryOperator = RpnBinaryOperatorNotEquals; - break; - - case '<': - IsComparativeOp = TRUE; - if (Operator[1] == '=') - RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThanOrEquals; + return FALSE; + } + } else - RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThan; - break; - - case '>': - IsComparativeOp = TRUE; - if (Operator[1] == '=') - RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThanOrEquals; - else - RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThan; - break; - - default: - ASSERT(0); - break; - } - if (IsComparativeOp) - { - if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp)) { - CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; + CONST_STRCPY(ErrMsg, "Operand expected"); + + if (ErrOffset) + *ErrOffset = CharacterOffset; + + return FALSE; } - memcpy(&ComparativeOp, &RpnOp, sizeof(RPN_OP)); - ComparativeOpFilled = TRUE; - } - else if (!RpnpPushStack(Stack, &RpnOp)) - { - CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; + } + else + { + CONST_STRCPY(ErrMsg, "strcspn() failed"); + + if (ErrOffset) + *ErrOffset = -1; + return FALSE; - } + } - /* Push popped operator */ - if (HavePoppedOperator) - { - if (!RpnpPushStack(Stack, &PoppedOperator)) + if (!First) + { + /* Push operator */ + RpnOp.CharacterOffset = OperatorOffset; + RpnOp.Type = RpnOpBinaryOperator; + IsComparativeOp = FALSE; + + switch (*Operator) { - CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } - } - } + case '+': + RpnOp.Data.BinaryOperator = RpnBinaryOperatorAdd; + break; - First = FALSE; - } + case '-': + RpnOp.Data.BinaryOperator = RpnBinaryOperatorSub; + break; + + case '*': + RpnOp.Data.BinaryOperator = RpnBinaryOperatorMul; + break; + + case '/': + RpnOp.Data.BinaryOperator = RpnBinaryOperatorDiv; + break; + + case '%': + RpnOp.Data.BinaryOperator = RpnBinaryOperatorMod; + break; + + case '=': + ASSERT(Operator[1] == '='); + IsComparativeOp = TRUE; + RpnOp.Data.BinaryOperator = RpnBinaryOperatorEquals; + break; + + case '!': + ASSERT(Operator[1] == '='); + IsComparativeOp = TRUE; + RpnOp.Data.BinaryOperator = RpnBinaryOperatorNotEquals; + break; + + case '<': + IsComparativeOp = TRUE; + + if (Operator[1] == '=') + RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThanOrEquals; + else + RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThan; + + break; + + case '>': + IsComparativeOp = TRUE; + + if (Operator[1] == '=') + RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThanOrEquals; + else + RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThan; + + break; + + default: + ASSERT(0); + break; + } + + if (IsComparativeOp) + { + if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp)) + { + CONST_STRCPY(ErrMsg, "RPN op stack overflow"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; + } + + memcpy(&ComparativeOp, &RpnOp, sizeof(RPN_OP)); + ComparativeOpFilled = TRUE; + } + else if (!RpnpPushStack(Stack, &RpnOp)) + { + CONST_STRCPY(ErrMsg, "RPN op stack overflow"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; + } + + /* Push popped operator */ + if (HavePoppedOperator) + { + if (!RpnpPushStack(Stack, &PoppedOperator)) + { + CONST_STRCPY(ErrMsg, "RPN op stack overflow"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; + } + } + } + + First = FALSE; + } //end_of_expression: - if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp)) - { - CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } + if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp)) + { + CONST_STRCPY(ErrMsg, "RPN op stack overflow"); - /* Skip whitespace */ - while (isspace(*p)) - { - p++; - CharacterOffset++; - } + if (ErrOffset) + *ErrOffset = -1; - if (End != NULL) - *End = p; + return FALSE; + } - return TRUE; + /* Skip whitespace */ + while (isspace(*p)) + { + p++; + CharacterOffset++; + } + + if (End) + *End = p; + + return TRUE; } /*!\brief Evaluates the RPN op stack and returns the result. @@ -787,171 +880,201 @@ get_operand: */ static BOOLEAN RpnpEvaluateStack( - IN PRPN_STACK Stack, - IN PKDB_KTRAP_FRAME TrapFrame, - OUT PULONGLONG Result, - OUT PLONG ErrOffset OPTIONAL, - OUT PCHAR ErrMsg OPTIONAL) + IN PRPN_STACK Stack, + IN PKDB_KTRAP_FRAME TrapFrame, + OUT PULONGLONG Result, + OUT PLONG ErrOffset OPTIONAL, + OUT PCHAR ErrMsg OPTIONAL) { - ULONGLONG ValueStack[RPN_VALUE_STACK_SIZE]; - ULONG ValueStackPointer = 0; - ULONG index; - ULONGLONG ull; - ULONG ul; - USHORT us; - UCHAR uc; - PVOID p; - BOOLEAN Ok; + ULONGLONG ValueStack[RPN_VALUE_STACK_SIZE]; + ULONG ValueStackPointer = 0; + ULONG index; + ULONGLONG ull; + ULONG ul; + USHORT us; + UCHAR uc; + PVOID p; + BOOLEAN Ok; #ifdef DEBUG_RPN - ULONG ValueStackPointerMax = 0; + ULONG ValueStackPointerMax = 0; #endif - ASSERT(Stack != NULL); - ASSERT(TrapFrame != NULL); - ASSERT(Result != NULL); + ASSERT(Stack); + ASSERT(TrapFrame); + ASSERT(Result); - for (index = 0; index < Stack->Sp; index++) - { - PRPN_OP Op = Stack->Ops + index; + for (index = 0; index < Stack->Sp; index++) + { + PRPN_OP Op = Stack->Ops + index; #ifdef DEBUG_RPN - ValueStackPointerMax = max(ValueStackPointerMax, ValueStackPointer); + ValueStackPointerMax = max(ValueStackPointerMax, ValueStackPointer); #endif - switch (Op->Type) - { - case RpnOpNop: - /* No operation */ - break; + switch (Op->Type) + { + case RpnOpNop: + /* No operation */ + break; - case RpnOpImmediate: - if (ValueStackPointer == RPN_VALUE_STACK_SIZE) - { - CONST_STRCPY(ErrMsg, "Value stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } - ValueStack[ValueStackPointer++] = Op->Data.Immediate; - break; + case RpnOpImmediate: + if (ValueStackPointer == RPN_VALUE_STACK_SIZE) + { + CONST_STRCPY(ErrMsg, "Value stack overflow"); - case RpnOpRegister: - if (ValueStackPointer == RPN_VALUE_STACK_SIZE) - { - CONST_STRCPY(ErrMsg, "Value stack overflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } - ul = Op->Data.Register; - p = (PVOID)((ULONG_PTR)TrapFrame + RegisterToTrapFrame[ul].Offset); - switch (RegisterToTrapFrame[ul].Size) - { - case 1: ull = (ULONGLONG)(*(PUCHAR)p); break; - case 2: ull = (ULONGLONG)(*(PUSHORT)p); break; - case 4: ull = (ULONGLONG)(*(PULONG)p); break; - case 8: ull = (ULONGLONG)(*(PULONGLONG)p); break; - default: ASSERT(0); return FALSE; break; - } - ValueStack[ValueStackPointer++] = ull; - break; + if (ErrOffset) + *ErrOffset = -1; - case RpnOpDereference: - if (ValueStackPointer < 1) - { - CONST_STRCPY(ErrMsg, "Value stack underflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } + return FALSE; + } - /* FIXME: Print a warning when address is out of range */ - p = (PVOID)(ULONG_PTR)ValueStack[ValueStackPointer - 1]; - Ok = FALSE; - switch (Op->Data.DerefMemorySize) - { - case 1: - if (NT_SUCCESS(KdbpSafeReadMemory(&uc, p, sizeof (uc)))) - { - Ok = TRUE; - ull = (ULONGLONG)uc; - } - break; - case 2: - if (NT_SUCCESS(KdbpSafeReadMemory(&us, p, sizeof (us)))) - { - Ok = TRUE; - ull = (ULONGLONG)us; - } - break; - case 4: - if (NT_SUCCESS(KdbpSafeReadMemory(&ul, p, sizeof (ul)))) - { - Ok = TRUE; - ull = (ULONGLONG)ul; - } - break; - case 8: - if (NT_SUCCESS(KdbpSafeReadMemory(&ull, p, sizeof (ull)))) - { - Ok = TRUE; - } - break; - default: - ASSERT(0); - return FALSE; - break; - } - if (!Ok) - { - _snprintf(ErrMsg, 128, "Couldn't access memory at 0x%lx", (ULONG)p); - if (ErrOffset != NULL) - *ErrOffset = Op->CharacterOffset; - return FALSE; - } - ValueStack[ValueStackPointer - 1] = ull; - break; + ValueStack[ValueStackPointer++] = Op->Data.Immediate; + break; - case RpnOpBinaryOperator: - if (ValueStackPointer < 2) - { - CONST_STRCPY(ErrMsg, "Value stack underflow"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } - ValueStackPointer--; - ull = ValueStack[ValueStackPointer]; - if (ull == 0 && (Op->Data.BinaryOperator == RpnBinaryOperatorDiv || - Op->Data.BinaryOperator == RpnBinaryOperatorDiv)) - { - CONST_STRCPY(ErrMsg, "Devision by zero"); - if (ErrOffset != NULL) - *ErrOffset = Op->CharacterOffset; - return FALSE; - } - ull = Op->Data.BinaryOperator(ValueStack[ValueStackPointer - 1], ull); - ValueStack[ValueStackPointer - 1] = ull; - break; + case RpnOpRegister: + if (ValueStackPointer == RPN_VALUE_STACK_SIZE) + { + CONST_STRCPY(ErrMsg, "Value stack overflow"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; + } + + ul = Op->Data.Register; + p = (PVOID)((ULONG_PTR)TrapFrame + RegisterToTrapFrame[ul].Offset); + + switch (RegisterToTrapFrame[ul].Size) + { + case 1: ull = (ULONGLONG)(*(PUCHAR)p); break; + case 2: ull = (ULONGLONG)(*(PUSHORT)p); break; + case 4: ull = (ULONGLONG)(*(PULONG)p); break; + case 8: ull = (ULONGLONG)(*(PULONGLONG)p); break; + default: ASSERT(0); return FALSE; break; + } + + ValueStack[ValueStackPointer++] = ull; + break; + + case RpnOpDereference: + if (ValueStackPointer < 1) + { + CONST_STRCPY(ErrMsg, "Value stack underflow"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; + } + + /* FIXME: Print a warning when address is out of range */ + p = (PVOID)(ULONG_PTR)ValueStack[ValueStackPointer - 1]; + Ok = FALSE; + + switch (Op->Data.DerefMemorySize) + { + case 1: + if (NT_SUCCESS(KdbpSafeReadMemory(&uc, p, sizeof (uc)))) + { + Ok = TRUE; + ull = (ULONGLONG)uc; + } + break; + + case 2: + if (NT_SUCCESS(KdbpSafeReadMemory(&us, p, sizeof (us)))) + { + Ok = TRUE; + ull = (ULONGLONG)us; + } + break; + + case 4: + if (NT_SUCCESS(KdbpSafeReadMemory(&ul, p, sizeof (ul)))) + { + Ok = TRUE; + ull = (ULONGLONG)ul; + } + break; + + case 8: + if (NT_SUCCESS(KdbpSafeReadMemory(&ull, p, sizeof (ull)))) + { + Ok = TRUE; + } + break; + + default: + ASSERT(0); + return FALSE; + break; + } + + if (!Ok) + { + _snprintf(ErrMsg, 128, "Couldn't access memory at 0x%lx", (ULONG)p); + + if (ErrOffset) + *ErrOffset = Op->CharacterOffset; + + return FALSE; + } + + ValueStack[ValueStackPointer - 1] = ull; + break; + + case RpnOpBinaryOperator: + if (ValueStackPointer < 2) + { + CONST_STRCPY(ErrMsg, "Value stack underflow"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; + } + + ValueStackPointer--; + ull = ValueStack[ValueStackPointer]; + + if (ull == 0 && (Op->Data.BinaryOperator == RpnBinaryOperatorDiv || + Op->Data.BinaryOperator == RpnBinaryOperatorDiv)) + { + CONST_STRCPY(ErrMsg, "Devision by zero"); + + if (ErrOffset) + *ErrOffset = Op->CharacterOffset; + + return FALSE; + } + + ull = Op->Data.BinaryOperator(ValueStack[ValueStackPointer - 1], ull); + ValueStack[ValueStackPointer - 1] = ull; + break; + + default: + ASSERT(0); + return FALSE; + } + } - default: - ASSERT(0); - return FALSE; - } - } #ifdef DEBUG_RPN - DPRINT1("Max value stack pointer: %d\n", ValueStackPointerMax); + DPRINT1("Max value stack pointer: %d\n", ValueStackPointerMax); #endif - if (ValueStackPointer != 1) - { - CONST_STRCPY(ErrMsg, "Stack not empty after evaluation"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return FALSE; - } - *Result = ValueStack[0]; - return TRUE; + if (ValueStackPointer != 1) + { + CONST_STRCPY(ErrMsg, "Stack not empty after evaluation"); + + if (ErrOffset) + *ErrOffset = -1; + + return FALSE; + } + + *Result = ValueStack[0]; + return TRUE; } /*!\brief Evaluates the given expression @@ -967,35 +1090,32 @@ RpnpEvaluateStack( */ BOOLEAN KdbpRpnEvaluateExpression( - IN PCHAR Expression, - IN PKDB_KTRAP_FRAME TrapFrame, - OUT PULONGLONG Result, - OUT PLONG ErrOffset OPTIONAL, - OUT PCHAR ErrMsg OPTIONAL) + IN PCHAR Expression, + IN PKDB_KTRAP_FRAME TrapFrame, + OUT PULONGLONG Result, + OUT PLONG ErrOffset OPTIONAL, + OUT PCHAR ErrMsg OPTIONAL) { - PRPN_STACK Stack = (PRPN_STACK)&RpnStack; + PRPN_STACK Stack = (PRPN_STACK)&RpnStack; - ASSERT(Expression != NULL); - ASSERT(TrapFrame != NULL); - ASSERT(Result != NULL); + ASSERT(Expression); + ASSERT(TrapFrame); + ASSERT(Result); + + /* Clear the stack and parse the expression */ + RpnpClearStack(Stack); + if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg)) + return FALSE; - /* Clear the stack and parse the expression */ - RpnpClearStack(Stack); - if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg)) - { - return FALSE; - } #ifdef DEBUG_RPN - RpnpDumpStack(Stack); + RpnpDumpStack(Stack); #endif - /* Evaluate the stack */ - if (!RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg)) - { - return FALSE; - } + /* Evaluate the stack */ + if (!RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg)) + return FALSE; - return TRUE; + return TRUE; } /*!\brief Parses the given expression and returns a "handle" to it. @@ -1010,41 +1130,44 @@ KdbpRpnEvaluateExpression( */ PVOID KdbpRpnParseExpression( - IN PCHAR Expression, - OUT PLONG ErrOffset OPTIONAL, - OUT PCHAR ErrMsg OPTIONAL) + IN PCHAR Expression, + OUT PLONG ErrOffset OPTIONAL, + OUT PCHAR ErrMsg OPTIONAL) { - LONG Size; - PRPN_STACK Stack = (PRPN_STACK)&RpnStack; - PRPN_STACK NewStack; + LONG Size; + PRPN_STACK Stack = (PRPN_STACK)&RpnStack; + PRPN_STACK NewStack; - ASSERT(Expression != NULL); + ASSERT(Expression); + + /* Clear the stack and parse the expression */ + RpnpClearStack(Stack); + if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg)) + return FALSE; - /* Clear the stack and parse the expression */ - RpnpClearStack(Stack); - if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg)) - { - return FALSE; - } #ifdef DEBUG_RPN - RpnpDumpStack(Stack); + RpnpDumpStack(Stack); #endif - /* Duplicate the stack and return a pointer/handle to it */ - ASSERT(Stack->Sp >= 1); - Size = sizeof (RPN_STACK) + (RTL_FIELD_SIZE(RPN_STACK, Ops[0]) * (Stack->Sp - 1)); - NewStack = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_KDBG); - if (NewStack == NULL) - { - CONST_STRCPY(ErrMsg, "Out of memory"); - if (ErrOffset != NULL) - *ErrOffset = -1; - return NULL; - } - memcpy(NewStack, Stack, Size); - NewStack->Size = NewStack->Sp; + /* Duplicate the stack and return a pointer/handle to it */ + ASSERT(Stack->Sp >= 1); + Size = sizeof (RPN_STACK) + (RTL_FIELD_SIZE(RPN_STACK, Ops[0]) * (Stack->Sp - 1)); + NewStack = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_KDBG); - return NewStack; + if (!NewStack) + { + CONST_STRCPY(ErrMsg, "Out of memory"); + + if (ErrOffset) + *ErrOffset = -1; + + return NULL; + } + + memcpy(NewStack, Stack, Size); + NewStack->Size = NewStack->Sp; + + return NewStack; } /*!\brief Evaluates the given expression and returns the result. @@ -1061,19 +1184,19 @@ KdbpRpnParseExpression( */ BOOLEAN KdbpRpnEvaluateParsedExpression( - IN PVOID Expression, - IN PKDB_KTRAP_FRAME TrapFrame, - OUT PULONGLONG Result, - OUT PLONG ErrOffset OPTIONAL, - OUT PCHAR ErrMsg OPTIONAL) + IN PVOID Expression, + IN PKDB_KTRAP_FRAME TrapFrame, + OUT PULONGLONG Result, + OUT PLONG ErrOffset OPTIONAL, + OUT PCHAR ErrMsg OPTIONAL) { - PRPN_STACK Stack = (PRPN_STACK)Expression; + PRPN_STACK Stack = (PRPN_STACK)Expression; - ASSERT(Expression != NULL); - ASSERT(TrapFrame != NULL); - ASSERT(Result != NULL); + ASSERT(Expression); + ASSERT(TrapFrame); + ASSERT(Result); - /* Evaluate the stack */ - return RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg); + /* Evaluate the stack */ + return RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg); } diff --git a/reactos/ntoskrnl/kdbg/kdb_keyboard.c b/reactos/ntoskrnl/kdbg/kdb_keyboard.c index 9abf9f310d2..dbad52e396d 100644 --- a/reactos/ntoskrnl/kdbg/kdb_keyboard.c +++ b/reactos/ntoskrnl/kdbg/kdb_keyboard.c @@ -37,21 +37,21 @@ static unsigned char keyb_layout[2][128] = { - "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ - "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ - "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ - "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ - "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ - "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ - "\r\000/" /* 0x60 - 0x6f */ - , - "\000\033!@#$%^&*()_+\177\t" /* 0x00 - 0x0f */ - "QWERTYUIOP{}\r\000AS" /* 0x10 - 0x1f */ - "DFGHJKL:\"`\000\\ZXCV" /* 0x20 - 0x2f */ - "BNM<>?\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ - "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ - "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ - "\r\000/" /* 0x60 - 0x6f */ + "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ + "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ + "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ + "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ + "\r\000/" /* 0x60 - 0x6f */ + , + "\000\033!@#$%^&*()_+\177\t" /* 0x00 - 0x0f */ + "QWERTYUIOP{}\r\000AS" /* 0x10 - 0x1f */ + "DFGHJKL:\"`\000\\ZXCV" /* 0x20 - 0x2f */ + "BNM<>?\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ + "\r\000/" /* 0x60 - 0x6f */ }; typedef UCHAR byte_t; @@ -86,6 +86,7 @@ KbdSendCommandToMouse(UCHAR Command) KeStallExecutionProcessor(50); if (kbd_read_input() != MOUSE_ACK) { ; } + return; } @@ -108,29 +109,40 @@ KdbpTryGetCharKeyboard(PULONG ScanCode, ULONG Retry) static byte_t shift = 0; char c; BOOLEAN KeepRetrying = (Retry == 0); - while (KeepRetrying || Retry-- > 0) { - unsigned char status = kbd_read_status(); - while (status & KBD_STAT_OBF) { - byte_t scancode; - scancode = kbd_read_input(); - /* check for SHIFT-keys */ - if (((scancode & 0x7F) == 42) || ((scancode & 0x7F) == 54)) - { - shift = !(scancode & 0x80); - continue; - } - /* ignore all other RELEASED-codes */ - if (scancode & 0x80) - last_key = 0; - else if (last_key != scancode) - { - //printf("kbd: %d, %d, %c\n", scancode, last_key, keyb_layout[shift][scancode]); - last_key = scancode; - c = keyb_layout[shift][scancode]; - *ScanCode = scancode; - if (c > 0) return c; - } - } + + while (KeepRetrying || Retry-- > 0) + { + unsigned char status = kbd_read_status(); + + while (status & KBD_STAT_OBF) + { + byte_t scancode; + + scancode = kbd_read_input(); + + /* check for SHIFT-keys */ + if (((scancode & 0x7F) == 42) || ((scancode & 0x7F) == 54)) + { + shift = !(scancode & 0x80); + continue; + } + + /* ignore all other RELEASED-codes */ + if (scancode & 0x80) + { + last_key = 0; + } + else if (last_key != scancode) + { + //printf("kbd: %d, %d, %c\n", scancode, last_key, keyb_layout[shift][scancode]); + last_key = scancode; + c = keyb_layout[shift][scancode]; + *ScanCode = scancode; + + if (c > 0) + return c; + } + } } return -1; diff --git a/reactos/ntoskrnl/kdbg/kdb_serial.c b/reactos/ntoskrnl/kdbg/kdb_serial.c index 6ccd460f6f8..e625c951c04 100644 --- a/reactos/ntoskrnl/kdbg/kdb_serial.c +++ b/reactos/ntoskrnl/kdbg/kdb_serial.c @@ -18,12 +18,12 @@ CHAR KdbpTryGetCharSerial(ULONG Retry) { - CHAR Result = -1; + CHAR Result = -1; - if (Retry == 0) - while (!KdPortGetByteEx(&SerialPortInfo, (PUCHAR)&Result)); - else - while (!KdPortGetByteEx(&SerialPortInfo, (PUCHAR)&Result) && Retry-- > 0); + if (Retry == 0) + while (!KdPortGetByteEx(&SerialPortInfo, (PUCHAR)&Result)); + else + while (!KdPortGetByteEx(&SerialPortInfo, (PUCHAR)&Result) && Retry-- > 0); - return Result; + return Result; } diff --git a/reactos/ntoskrnl/kdbg/kdb_symbols.c b/reactos/ntoskrnl/kdbg/kdb_symbols.c index 17879bf5aac..218bc6eb783 100644 --- a/reactos/ntoskrnl/kdbg/kdb_symbols.c +++ b/reactos/ntoskrnl/kdbg/kdb_symbols.c @@ -16,12 +16,14 @@ /* GLOBALS ******************************************************************/ -typedef struct _IMAGE_SYMBOL_INFO_CACHE { - LIST_ENTRY ListEntry; - ULONG RefCount; - UNICODE_STRING FileName; - PROSSYM_INFO RosSymInfo; -} IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE; +typedef struct _IMAGE_SYMBOL_INFO_CACHE +{ + LIST_ENTRY ListEntry; + ULONG RefCount; + UNICODE_STRING FileName; + PROSSYM_INFO RosSymInfo; +} +IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE; static BOOLEAN LoadSymbols; static LIST_ENTRY SymbolFileListHead; @@ -45,55 +47,52 @@ BOOLEAN KdbpSymbolsInitialized = FALSE; * \sa KdbpSymFindModule */ static BOOLEAN -KdbpSymFindUserModule(IN PVOID Address OPTIONAL, - IN LPCWSTR Name OPTIONAL, - IN INT Index OPTIONAL, - OUT PKDB_MODULE_INFO pInfo) +KdbpSymFindUserModule( + IN PVOID Address OPTIONAL, + IN LPCWSTR Name OPTIONAL, + IN INT Index OPTIONAL, + OUT PKDB_MODULE_INFO pInfo) { - PLIST_ENTRY current_entry; - PLDR_DATA_TABLE_ENTRY current; - PEPROCESS CurrentProcess; - PPEB Peb = NULL; - INT Count = 0; - INT Length; + PLIST_ENTRY current_entry; + PLDR_DATA_TABLE_ENTRY current; + PEPROCESS CurrentProcess; + PPEB Peb = NULL; + INT Count = 0; + INT Length; - if (!KdbpSymbolsInitialized) - return FALSE; + if (!KdbpSymbolsInitialized) + return FALSE; - CurrentProcess = PsGetCurrentProcess(); - if (CurrentProcess != NULL) + CurrentProcess = PsGetCurrentProcess(); + if (CurrentProcess) + Peb = CurrentProcess->Peb; + + if (!Peb || !Peb->Ldr) + return FALSE; + + current_entry = Peb->Ldr->InLoadOrderModuleList.Flink; + + while (current_entry != &Peb->Ldr->InLoadOrderModuleList && current_entry) { - Peb = CurrentProcess->Peb; - } - - if (Peb == NULL || Peb->Ldr == NULL) - { - return FALSE; - } - - current_entry = Peb->Ldr->InLoadOrderModuleList.Flink; - - while (current_entry != &Peb->Ldr->InLoadOrderModuleList && - current_entry != NULL) - { - current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - Length = min(current->BaseDllName.Length / sizeof(WCHAR), 255); - if ((Address != NULL && (Address >= (PVOID)current->DllBase && - Address < (PVOID)((char *)current->DllBase + current->SizeOfImage))) || - (Name != NULL && _wcsnicmp(current->BaseDllName.Buffer, Name, Length) == 0) || - (Index >= 0 && Count++ == Index)) + current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + Length = min(current->BaseDllName.Length / sizeof(WCHAR), 255); + if ((Address && (Address >= (PVOID)current->DllBase && + Address < (PVOID)((char *)current->DllBase + current->SizeOfImage))) || + (Name && _wcsnicmp(current->BaseDllName.Buffer, Name, Length) == 0) || + (Index >= 0 && Count++ == Index)) { - wcsncpy(pInfo->Name, current->BaseDllName.Buffer, Length); - pInfo->Name[Length] = L'\0'; - pInfo->Base = (ULONG_PTR)current->DllBase; - pInfo->Size = current->SizeOfImage; - pInfo->RosSymInfo = current->PatchInformation; - return TRUE; + wcsncpy(pInfo->Name, current->BaseDllName.Buffer, Length); + pInfo->Name[Length] = L'\0'; + pInfo->Base = (ULONG_PTR)current->DllBase; + pInfo->Size = current->SizeOfImage; + pInfo->RosSymInfo = current->PatchInformation; + return TRUE; } - current_entry = current_entry->Flink; + + current_entry = current_entry->Flink; } - return FALSE; + return FALSE; } /*! \brief Find a kernel-mode module... @@ -103,42 +102,44 @@ KdbpSymFindUserModule(IN PVOID Address OPTIONAL, * \sa KdbpSymFindUserModule */ static BOOLEAN -KdbpSymFindModule(IN PVOID Address OPTIONAL, - IN LPCWSTR Name OPTIONAL, - IN INT Index OPTIONAL, - OUT PKDB_MODULE_INFO pInfo) +KdbpSymFindModule( + IN PVOID Address OPTIONAL, + IN LPCWSTR Name OPTIONAL, + IN INT Index OPTIONAL, + OUT PKDB_MODULE_INFO pInfo) { - PLIST_ENTRY current_entry; - PLDR_DATA_TABLE_ENTRY current; - INT Count = 0; - INT Length; + PLIST_ENTRY current_entry; + PLDR_DATA_TABLE_ENTRY current; + INT Count = 0; + INT Length; - if (!KdbpSymbolsInitialized) - return FALSE; + if (!KdbpSymbolsInitialized) + return FALSE; - current_entry = PsLoadedModuleList.Flink; + current_entry = PsLoadedModuleList.Flink; - while (current_entry != &PsLoadedModuleList) + while (current_entry != &PsLoadedModuleList) { - current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - Length = min(current->BaseDllName.Length / sizeof(WCHAR), 255); - if ((Address != NULL && (Address >= (PVOID)current->DllBase && - Address < (PVOID)((ULONG_PTR)current->DllBase + current->SizeOfImage))) || - (Name != NULL && _wcsnicmp(current->BaseDllName.Buffer, Name, Length) == 0) || + Length = min(current->BaseDllName.Length / sizeof(WCHAR), 255); + if ((Address && (Address >= (PVOID)current->DllBase && + Address < (PVOID)((ULONG_PTR)current->DllBase + current->SizeOfImage))) || + (Name && _wcsnicmp(current->BaseDllName.Buffer, Name, Length) == 0) || (Index >= 0 && Count++ == Index)) { - wcsncpy(pInfo->Name, current->BaseDllName.Buffer, Length); - pInfo->Name[Length] = L'\0'; - pInfo->Base = (ULONG_PTR)current->DllBase; - pInfo->Size = current->SizeOfImage; - pInfo->RosSymInfo = current->PatchInformation; - return TRUE; + wcsncpy(pInfo->Name, current->BaseDllName.Buffer, Length); + pInfo->Name[Length] = L'\0'; + pInfo->Base = (ULONG_PTR)current->DllBase; + pInfo->Size = current->SizeOfImage; + pInfo->RosSymInfo = current->PatchInformation; + return TRUE; } - current_entry = current_entry->Flink; + + current_entry = current_entry->Flink; } - return KdbpSymFindUserModule(Address, Name, Index-Count, pInfo); + return KdbpSymFindUserModule(Address, Name, Index-Count, pInfo); } /*! \brief Find module by address... @@ -154,10 +155,11 @@ KdbpSymFindModule(IN PVOID Address OPTIONAL, * \sa KdbpSymFindModuleByIndex */ BOOLEAN -KdbpSymFindModuleByAddress(IN PVOID Address, - OUT PKDB_MODULE_INFO pInfo) +KdbpSymFindModuleByAddress( + IN PVOID Address, + OUT PKDB_MODULE_INFO pInfo) { - return KdbpSymFindModule(Address, NULL, -1, pInfo); + return KdbpSymFindModule(Address, NULL, -1, pInfo); } /*! \brief Find module by name... @@ -173,10 +175,11 @@ KdbpSymFindModuleByAddress(IN PVOID Address, * \sa KdbpSymFindModuleByIndex */ BOOLEAN -KdbpSymFindModuleByName(IN LPCWSTR Name, - OUT PKDB_MODULE_INFO pInfo) +KdbpSymFindModuleByName( + IN LPCWSTR Name, + OUT PKDB_MODULE_INFO pInfo) { - return KdbpSymFindModule(NULL, Name, -1, pInfo); + return KdbpSymFindModule(NULL, Name, -1, pInfo); } /*! \brief Find module by index... @@ -192,10 +195,11 @@ KdbpSymFindModuleByName(IN LPCWSTR Name, * \sa KdbpSymFindModuleByAddress */ BOOLEAN -KdbpSymFindModuleByIndex(IN INT Index, - OUT PKDB_MODULE_INFO pInfo) +KdbpSymFindModuleByIndex( + IN INT Index, + OUT PKDB_MODULE_INFO pInfo) { - return KdbpSymFindModule(NULL, NULL, Index, pInfo); + return KdbpSymFindModule(NULL, NULL, Index, pInfo); } /*! \brief Print address... @@ -210,35 +214,36 @@ KdbpSymFindModuleByIndex(IN INT Index, * \retval FALSE No module containing \a Address was found, nothing was printed. */ BOOLEAN -KdbSymPrintAddress(IN PVOID Address) +KdbSymPrintAddress( + IN PVOID Address) { - KDB_MODULE_INFO Info; - ULONG_PTR RelativeAddress; - NTSTATUS Status; - ULONG LineNumber; - CHAR FileName[256]; - CHAR FunctionName[256]; + KDB_MODULE_INFO Info; + ULONG_PTR RelativeAddress; + NTSTATUS Status; + ULONG LineNumber; + CHAR FileName[256]; + CHAR FunctionName[256]; - if (!KdbpSymbolsInitialized || !KdbpSymFindModuleByAddress(Address, &Info)) - return FALSE; + if (!KdbpSymbolsInitialized || !KdbpSymFindModuleByAddress(Address, &Info)) + return FALSE; - RelativeAddress = (ULONG_PTR) Address - Info.Base; - Status = KdbSymGetAddressInformation(Info.RosSymInfo, - RelativeAddress, - &LineNumber, - FileName, - FunctionName); - if (NT_SUCCESS(Status)) + RelativeAddress = (ULONG_PTR) Address - Info.Base; + Status = KdbSymGetAddressInformation(Info.RosSymInfo, + RelativeAddress, + &LineNumber, + FileName, + FunctionName); + if (NT_SUCCESS(Status)) { - DbgPrint("<%ws:%x (%s:%d (%s))>", - Info.Name, RelativeAddress, FileName, LineNumber, FunctionName); + DbgPrint("<%ws:%x (%s:%d (%s))>", + Info.Name, RelativeAddress, FileName, LineNumber, FunctionName); } - else + else { - DbgPrint("<%ws:%x>", Info.Name, RelativeAddress); + DbgPrint("<%ws:%x>", Info.Name, RelativeAddress); } - return TRUE; + return TRUE; } @@ -259,29 +264,21 @@ KdbSymPrintAddress(IN PVOID Address) * \retval STATUS_UNSUCCESSFUL None of the requested information was found. */ NTSTATUS -KdbSymGetAddressInformation(IN PROSSYM_INFO RosSymInfo, - IN ULONG_PTR RelativeAddress, - OUT PULONG LineNumber OPTIONAL, - OUT PCH FileName OPTIONAL, - OUT PCH FunctionName OPTIONAL) +KdbSymGetAddressInformation( + IN PROSSYM_INFO RosSymInfo, + IN ULONG_PTR RelativeAddress, + OUT PULONG LineNumber OPTIONAL, + OUT PCH FileName OPTIONAL, + OUT PCH FunctionName OPTIONAL) { - if (!KdbpSymbolsInitialized) + if (!KdbpSymbolsInitialized || + !RosSymInfo || + !RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineNumber, FileName, FunctionName)) { - return STATUS_UNSUCCESSFUL; - } - - if (NULL == RosSymInfo) - { - return STATUS_UNSUCCESSFUL; + return STATUS_UNSUCCESSFUL; } - if (! RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineNumber, - FileName, FunctionName)) - { - return STATUS_UNSUCCESSFUL; - } - - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /*! \brief Find cached symbol file. @@ -297,37 +294,38 @@ KdbSymGetAddressInformation(IN PROSSYM_INFO RosSymInfo, * \sa KdbpSymAddCachedFile */ static PROSSYM_INFO -KdbpSymFindCachedFile(IN PUNICODE_STRING FileName) +KdbpSymFindCachedFile( + IN PUNICODE_STRING FileName) { - PIMAGE_SYMBOL_INFO_CACHE Current; - PLIST_ENTRY CurrentEntry; - KIRQL Irql; + PIMAGE_SYMBOL_INFO_CACHE Current; + PLIST_ENTRY CurrentEntry; + KIRQL Irql; - DPRINT("Looking for cached symbol file %wZ\n", FileName); + DPRINT("Looking for cached symbol file %wZ\n", FileName); - KeAcquireSpinLock(&SymbolFileListLock, &Irql); + KeAcquireSpinLock(&SymbolFileListLock, &Irql); - CurrentEntry = SymbolFileListHead.Flink; - while (CurrentEntry != (&SymbolFileListHead)) + CurrentEntry = SymbolFileListHead.Flink; + while (CurrentEntry != (&SymbolFileListHead)) { - Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry); + Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry); - DPRINT("Current->FileName %wZ FileName %wZ\n", &Current->FileName, FileName); - if (RtlEqualUnicodeString(&Current->FileName, FileName, TRUE)) + DPRINT("Current->FileName %wZ FileName %wZ\n", &Current->FileName, FileName); + if (RtlEqualUnicodeString(&Current->FileName, FileName, TRUE)) { - Current->RefCount++; - KeReleaseSpinLock(&SymbolFileListLock, Irql); - DPRINT("Found cached file!\n"); - return Current->RosSymInfo; + Current->RefCount++; + KeReleaseSpinLock(&SymbolFileListLock, Irql); + DPRINT("Found cached file!\n"); + return Current->RosSymInfo; } - CurrentEntry = CurrentEntry->Flink; + CurrentEntry = CurrentEntry->Flink; } - KeReleaseSpinLock(&SymbolFileListLock, Irql); + KeReleaseSpinLock(&SymbolFileListLock, Irql); - DPRINT("Cached file not found!\n"); - return NULL; + DPRINT("Cached file not found!\n"); + return NULL; } /*! \brief Add a symbol file to the cache. @@ -338,27 +336,28 @@ KdbpSymFindCachedFile(IN PUNICODE_STRING FileName) * \sa KdbpSymRemoveCachedFile */ static VOID -KdbpSymAddCachedFile(IN PUNICODE_STRING FileName, - IN PROSSYM_INFO RosSymInfo) +KdbpSymAddCachedFile( + IN PUNICODE_STRING FileName, + IN PROSSYM_INFO RosSymInfo) { - PIMAGE_SYMBOL_INFO_CACHE CacheEntry; + PIMAGE_SYMBOL_INFO_CACHE CacheEntry; - DPRINT("Adding symbol file: RosSymInfo = %p\n", RosSymInfo); + DPRINT("Adding symbol file: RosSymInfo = %p\n", RosSymInfo); - /* allocate entry */ - CacheEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE), TAG_KDBS); - ASSERT(CacheEntry); - RtlZeroMemory(CacheEntry, sizeof (IMAGE_SYMBOL_INFO_CACHE)); + /* allocate entry */ + CacheEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE), TAG_KDBS); + ASSERT(CacheEntry); + RtlZeroMemory(CacheEntry, sizeof (IMAGE_SYMBOL_INFO_CACHE)); - /* fill entry */ - CacheEntry->FileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, - FileName->Length, - TAG_KDBS); - RtlCopyUnicodeString(&CacheEntry->FileName, FileName); - ASSERT(CacheEntry->FileName.Buffer); - CacheEntry->RefCount = 1; - CacheEntry->RosSymInfo = RosSymInfo; - InsertTailList(&SymbolFileListHead, &CacheEntry->ListEntry); /* FIXME: Lock list? */ + /* fill entry */ + CacheEntry->FileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, + FileName->Length, + TAG_KDBS); + RtlCopyUnicodeString(&CacheEntry->FileName, FileName); + ASSERT(CacheEntry->FileName.Buffer); + CacheEntry->RefCount = 1; + CacheEntry->RosSymInfo = RosSymInfo; + InsertTailList(&SymbolFileListHead, &CacheEntry->ListEntry); /* FIXME: Lock list? */ } /*! \brief Remove a symbol file (reference) from the cache. @@ -372,38 +371,40 @@ KdbpSymAddCachedFile(IN PUNICODE_STRING FileName, * \sa KdbpSymAddCachedFile */ static VOID -KdbpSymRemoveCachedFile(IN PROSSYM_INFO RosSymInfo) +KdbpSymRemoveCachedFile( + IN PROSSYM_INFO RosSymInfo) { - PIMAGE_SYMBOL_INFO_CACHE Current; - PLIST_ENTRY CurrentEntry; - KIRQL Irql; + PIMAGE_SYMBOL_INFO_CACHE Current; + PLIST_ENTRY CurrentEntry; + KIRQL Irql; - KeAcquireSpinLock(&SymbolFileListLock, &Irql); + KeAcquireSpinLock(&SymbolFileListLock, &Irql); - CurrentEntry = SymbolFileListHead.Flink; - while (CurrentEntry != (&SymbolFileListHead)) + CurrentEntry = SymbolFileListHead.Flink; + while (CurrentEntry != (&SymbolFileListHead)) { - Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry); + Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry); - if (Current->RosSymInfo == RosSymInfo) /* found */ + if (Current->RosSymInfo == RosSymInfo) /* found */ { - ASSERT(Current->RefCount > 0); - Current->RefCount--; - if (Current->RefCount < 1) + ASSERT(Current->RefCount > 0); + Current->RefCount--; + if (Current->RefCount < 1) { - RemoveEntryList(&Current->ListEntry); - RosSymDelete(Current->RosSymInfo); - ExFreePool(Current); + RemoveEntryList(&Current->ListEntry); + RosSymDelete(Current->RosSymInfo); + ExFreePool(Current); } - KeReleaseSpinLock(&SymbolFileListLock, Irql); - return; + + KeReleaseSpinLock(&SymbolFileListLock, Irql); + return; } - CurrentEntry = CurrentEntry->Flink; + CurrentEntry = CurrentEntry->Flink; } - KeReleaseSpinLock(&SymbolFileListLock, Irql); - DPRINT1("Warning: Removing unknown symbol file: RosSymInfo = %p\n", RosSymInfo); + KeReleaseSpinLock(&SymbolFileListLock, Irql); + DPRINT1("Warning: Removing unknown symbol file: RosSymInfo = %p\n", RosSymInfo); } /*! \brief Loads a symbol file. @@ -414,68 +415,69 @@ KdbpSymRemoveCachedFile(IN PROSSYM_INFO RosSymInfo) * \sa KdbpSymUnloadModuleSymbols */ static VOID -KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName, - OUT PROSSYM_INFO *RosSymInfo) +KdbpSymLoadModuleSymbols( + IN PUNICODE_STRING FileName, + OUT PROSSYM_INFO *RosSymInfo) { - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE FileHandle; - NTSTATUS Status; - IO_STATUS_BLOCK IoStatusBlock; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE FileHandle; + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; - /* Allow KDB to break on module load */ - KdbModuleLoaded(FileName); + /* Allow KDB to break on module load */ + KdbModuleLoaded(FileName); - if (! LoadSymbols) + if (!LoadSymbols) { - *RosSymInfo = NULL; - return; + *RosSymInfo = NULL; + return; } - /* Try to find cached (already loaded) symbol file */ - *RosSymInfo = KdbpSymFindCachedFile(FileName); - if (*RosSymInfo != NULL) + /* Try to find cached (already loaded) symbol file */ + *RosSymInfo = KdbpSymFindCachedFile(FileName); + if (*RosSymInfo) { - DPRINT("Found cached symbol file %wZ\n", FileName); - return; + DPRINT("Found cached symbol file %wZ\n", FileName); + return; } - /* Open the file */ - InitializeObjectAttributes(&ObjectAttributes, - FileName, - 0, - NULL, - NULL); + /* Open the file */ + InitializeObjectAttributes(&ObjectAttributes, + FileName, + 0, + NULL, + NULL); - DPRINT("Attempting to open image: %wZ\n", FileName); + DPRINT("Attempting to open image: %wZ\n", FileName); - Status = ZwOpenFile(&FileHandle, - FILE_READ_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) + Status = ZwOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) { - DPRINT("Could not open image file: %wZ\n", FileName); - return; + DPRINT("Could not open image file: %wZ\n", FileName); + return; } - DPRINT("Loading symbols from %wZ...\n", FileName); + DPRINT("Loading symbols from %wZ...\n", FileName); - if (! RosSymCreateFromFile(&FileHandle, RosSymInfo)) + if (!RosSymCreateFromFile(&FileHandle, RosSymInfo)) { - DPRINT("Failed to load symbols from %wZ\n", FileName); - return; + DPRINT("Failed to load symbols from %wZ\n", FileName); + return; } - ZwClose(FileHandle); + ZwClose(FileHandle); - DPRINT("Symbols loaded.\n"); + DPRINT("Symbols loaded.\n"); - /* add file to cache */ - KdbpSymAddCachedFile(FileName, *RosSymInfo); + /* add file to cache */ + KdbpSymAddCachedFile(FileName, *RosSymInfo); - DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo); + DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo); } /*! \brief Unloads symbol info. @@ -485,14 +487,13 @@ KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName, * \sa KdbpSymLoadModuleSymbols */ static VOID -KdbpSymUnloadModuleSymbols(IN PROSSYM_INFO RosSymInfo) +KdbpSymUnloadModuleSymbols( + IN PROSSYM_INFO RosSymInfo) { - DPRINT("Unloading symbols\n"); + DPRINT("Unloading symbols\n"); - if (RosSymInfo != NULL) - { - KdbpSymRemoveCachedFile(RosSymInfo); - } + if (RosSymInfo) + KdbpSymRemoveCachedFile(RosSymInfo); } /*! \brief Load symbol info for a user module. @@ -500,29 +501,29 @@ KdbpSymUnloadModuleSymbols(IN PROSSYM_INFO RosSymInfo) * \param LdrModule Pointer to the module to load symbols for. */ VOID -KdbSymLoadUserModuleSymbols(IN PLDR_DATA_TABLE_ENTRY LdrModule) +KdbSymLoadUserModuleSymbols( + IN PLDR_DATA_TABLE_ENTRY LdrModule) { - static WCHAR Prefix[] = L"\\??\\"; - UNICODE_STRING KernelName; - DPRINT("LdrModule %p\n", LdrModule); + static WCHAR Prefix[] = L"\\??\\"; + UNICODE_STRING KernelName; + DPRINT("LdrModule %p\n", LdrModule); - LdrModule->PatchInformation = NULL; + LdrModule->PatchInformation = NULL; - KernelName.MaximumLength = sizeof(Prefix) + LdrModule->FullDllName.Length; - KernelName.Length = KernelName.MaximumLength - sizeof(WCHAR); - KernelName.Buffer = ExAllocatePoolWithTag(NonPagedPool, KernelName.MaximumLength, TAG_KDBS); - if (NULL == KernelName.Buffer) - { - return; - } - memcpy(KernelName.Buffer, Prefix, sizeof(Prefix) - sizeof(WCHAR)); - memcpy(KernelName.Buffer + sizeof(Prefix) / sizeof(WCHAR) - 1, LdrModule->FullDllName.Buffer, - LdrModule->FullDllName.Length); - KernelName.Buffer[KernelName.Length / sizeof(WCHAR)] = L'\0'; + KernelName.MaximumLength = sizeof(Prefix) + LdrModule->FullDllName.Length; + KernelName.Length = KernelName.MaximumLength - sizeof(WCHAR); + KernelName.Buffer = ExAllocatePoolWithTag(NonPagedPool, KernelName.MaximumLength, TAG_KDBS); - KdbpSymLoadModuleSymbols(&KernelName, (PROSSYM_INFO*)&LdrModule->PatchInformation); + if (!KernelName.Buffer) + return; - ExFreePool(KernelName.Buffer); + memcpy(KernelName.Buffer, Prefix, sizeof(Prefix) - sizeof(WCHAR)); + memcpy(KernelName.Buffer + sizeof(Prefix) / sizeof(WCHAR) - 1, LdrModule->FullDllName.Buffer, LdrModule->FullDllName.Length); + KernelName.Buffer[KernelName.Length / sizeof(WCHAR)] = L'\0'; + + KdbpSymLoadModuleSymbols(&KernelName, (PROSSYM_INFO*)&LdrModule->PatchInformation); + + ExFreePool(KernelName.Buffer); } /*! \brief Frees all symbols loaded for a process. @@ -530,36 +531,33 @@ KdbSymLoadUserModuleSymbols(IN PLDR_DATA_TABLE_ENTRY LdrModule) * \param Process Pointer to a process. */ VOID -KdbSymFreeProcessSymbols(IN PEPROCESS Process) +KdbSymFreeProcessSymbols( + IN PEPROCESS Process) { - PLIST_ENTRY CurrentEntry; - PLDR_DATA_TABLE_ENTRY Current; - PEPROCESS CurrentProcess; - PPEB Peb; + PLIST_ENTRY CurrentEntry; + PLDR_DATA_TABLE_ENTRY Current; + PEPROCESS CurrentProcess; + PPEB Peb; - CurrentProcess = PsGetCurrentProcess(); - if (CurrentProcess != Process) - { - KeAttachProcess(&Process->Pcb); - } - Peb = Process->Peb; - ASSERT(Peb); - ASSERT(Peb->Ldr); + CurrentProcess = PsGetCurrentProcess(); + if (CurrentProcess != Process) + KeAttachProcess(&Process->Pcb); - CurrentEntry = Peb->Ldr->InLoadOrderModuleList.Flink; - while (CurrentEntry != &Peb->Ldr->InLoadOrderModuleList && - CurrentEntry != NULL) + Peb = Process->Peb; + ASSERT(Peb); + ASSERT(Peb->Ldr); + + CurrentEntry = Peb->Ldr->InLoadOrderModuleList.Flink; + while (CurrentEntry != &Peb->Ldr->InLoadOrderModuleList && CurrentEntry) { - Current = CONTAINING_RECORD(CurrentEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + Current = CONTAINING_RECORD(CurrentEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + KdbpSymUnloadModuleSymbols(Current->PatchInformation); - KdbpSymUnloadModuleSymbols(Current->PatchInformation); - - CurrentEntry = CurrentEntry->Flink; + CurrentEntry = CurrentEntry->Flink; } - if (CurrentProcess != Process) - { - KeDetachProcess(); - } + + if (CurrentProcess != Process) + KeDetachProcess(); } /*! \brief Load symbol info for a driver. @@ -568,15 +566,16 @@ KdbSymFreeProcessSymbols(IN PEPROCESS Process) * \param Module Pointer to the driver LDR_DATA_TABLE_ENTRY. */ VOID -KdbSymLoadDriverSymbols(IN PUNICODE_STRING Filename, - IN PLDR_DATA_TABLE_ENTRY Module) +KdbSymLoadDriverSymbols( + IN PUNICODE_STRING Filename, + IN PLDR_DATA_TABLE_ENTRY Module) { - /* Load symbols for the image if available */ - DPRINT("Loading driver %wZ symbols (driver @ %08x)\n", Filename, Module->DllBase); + /* Load symbols for the image if available */ + DPRINT("Loading driver %wZ symbols (driver @ %08x)\n", Filename, Module->DllBase); - Module->PatchInformation = NULL; + Module->PatchInformation = NULL; - KdbpSymLoadModuleSymbols(Filename, (PROSSYM_INFO*)&Module->PatchInformation); + KdbpSymLoadModuleSymbols(Filename, (PROSSYM_INFO*)&Module->PatchInformation); } /*! \brief Unloads symbol info for a driver. @@ -584,15 +583,18 @@ KdbSymLoadDriverSymbols(IN PUNICODE_STRING Filename, * \param ModuleObject Pointer to the driver LDR_DATA_TABLE_ENTRY. */ VOID -KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject) +KdbSymUnloadDriverSymbols( + IN PLDR_DATA_TABLE_ENTRY ModuleObject) { - /* Unload symbols for module if available */ - KdbpSymUnloadModuleSymbols(ModuleObject->PatchInformation); - ModuleObject->PatchInformation = NULL; + /* Unload symbols for module if available */ + KdbpSymUnloadModuleSymbols(ModuleObject->PatchInformation); + ModuleObject->PatchInformation = NULL; } VOID -KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName, IN PKD_SYMBOLS_INFO SymbolInfo) +KdbSymProcessSymbols( + IN PANSI_STRING AnsiFileName, + IN PKD_SYMBOLS_INFO SymbolInfo) { BOOLEAN Found = FALSE; PLIST_ENTRY ListHead, NextEntry; @@ -635,10 +637,8 @@ KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName, IN PKD_SYMBOLS_INFO SymbolInf } /* Remove symbol info if it already exists */ - if (LdrEntry->PatchInformation != NULL) - { + if (LdrEntry->PatchInformation) KdbpSymRemoveCachedFile(LdrEntry->PatchInformation); - } /* Load new symbol information */ if (! RosSymCreateFromMem(LdrEntry->DllBase, @@ -667,7 +667,9 @@ KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName, IN PKD_SYMBOLS_INFO SymbolInf VOID NTAPI -KdbDebugPrint(PCH Message, ULONG Length) +KdbDebugPrint( + PCH Message, + ULONG Length) { /* Nothing here */ } @@ -680,8 +682,9 @@ KdbDebugPrint(PCH Message, ULONG Length) */ VOID NTAPI -KdbInitialize(PKD_DISPATCH_TABLE DispatchTable, - ULONG BootPhase) +KdbInitialize( + PKD_DISPATCH_TABLE DispatchTable, + ULONG BootPhase) { PCHAR p1, p2; SHORT Found = FALSE; @@ -785,7 +788,7 @@ KdbInitialize(PKD_DISPATCH_TABLE DispatchTable, SymbolsInfo.SizeOfImage = DataTableEntry->SizeOfImage; KdbSymProcessSymbols(NULL, &SymbolsInfo); - KdbpSymbolsInitialized = TRUE; + KdbpSymbolsInitialized = TRUE; } }