Merge with blight's rewrite
Modified: branches/alex_devel_branch/reactos/Makefile
Modified:
branches/alex_devel_branch/reactos/drivers/input/keyboard/keyboard.c
Added: branches/alex_devel_branch/reactos/media/drivers/etc/KDB.init
Modified: branches/alex_devel_branch/reactos/ntoskrnl/Makefile
Modified:
branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/i386-dis.c
Modified:
branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/kdb_help.S
Added: branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/longjmp.S
Added: branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/setjmp.S
Modified: branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb.h
Added: branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb_cli.c
Added: branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb_expr.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb_keyboard.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb_serial.c
Added: branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb_string.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb_symbols.c
Modified:
branches/alex_devel_branch/reactos/ntoskrnl/include/internal/i386/ke.h
Modified:
branches/alex_devel_branch/reactos/ntoskrnl/include/internal/kd.h
Modified: branches/alex_devel_branch/reactos/ntoskrnl/io/iomgr.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/catch.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/i386/trap.s
Modified:
branches/alex_devel_branch/reactos/ntoskrnl/ke/i386/tskswitch.S
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/kthread.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/main.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ps/w32call.c
_____
Modified: branches/alex_devel_branch/reactos/Makefile
--- branches/alex_devel_branch/reactos/Makefile 2005-03-05 23:35:08 UTC
(rev 13841)
+++ branches/alex_devel_branch/reactos/Makefile 2005-03-05 23:58:25 UTC
(rev 13842)
@@ -216,6 +216,8 @@
$(CP) media/nls/l_intl.nls $(BOOTCD_DIR)/reactos/l_intl.nls
$(HALFVERBOSEECHO) [COPY] media/drivers/etc/services to
$(BOOTCD_DIR)/reactos/services
$(CP) media/drivers/etc/services $(BOOTCD_DIR)/reactos/services
+ $(HALFVERBOSEECHO) [COPY] media/drivers/etc/KDB.init to
$(BOOTCD_DIR)/reactos/KDB.init
+ $(CP) media/drivers/etc/KDB.init $(BOOTCD_DIR)/reactos/KDB.init
bootcd_basic: bootcd_directory_layout bootcd_bootstrap_files
bootcd_install_before
@@ -1043,6 +1045,8 @@
$(CP) media/nls/l_intl.nls $(INSTALL_DIR)/system32/casemap.nls
$(HALFVERBOSEECHO) [INSTALL] media/drivers/etc/services to
$(INSTALL_DIR)/system32/drivers/etc/services
$(CP) media/drivers/etc/services
$(INSTALL_DIR)/system32/drivers/etc/services
+ $(HALFVERBOSEECHO) [INSTALL] media/drivers/etc/KDB.init to
$(INSTALL_DIR)/system32/drivers/etc/KDB.init
+ $(CP) media/drivers/etc/KDB.init
$(INSTALL_DIR)/system32/drivers/etc/KDB.init
.PHONY: install_clean install_dirs install_before
_____
Modified:
branches/alex_devel_branch/reactos/drivers/input/keyboard/keyboard.c
--- branches/alex_devel_branch/reactos/drivers/input/keyboard/keyboard.c
2005-03-05 23:35:08 UTC (rev 13841)
+++ branches/alex_devel_branch/reactos/drivers/input/keyboard/keyboard.c
2005-03-05 23:58:25 UTC (rev 13842)
@@ -38,6 +38,7 @@
static DWORD ctrlKeyState;
static PKINTERRUPT KbdInterrupt;
static KDPC KbdDpc;
+static PIO_WORKITEM KbdWorkItem = NULL;
static BOOLEAN AlreadyOpened = FALSE;
/*
@@ -408,6 +409,24 @@
/*
+ * Debug request handler
+ */
+
+static VOID STDCALL
+KbdWorkItemRoutine(IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context)
+{
+ LONG Debug;
+
+ Debug = InterlockedExchange(&DoSystemDebug, -1);
+ if (Debug != -1)
+ {
+ KdSystemDebugControl(Debug);
+ }
+}
+
+
+/*
* Keyboard IRQ handler
*/
@@ -419,14 +438,21 @@
{
PIRP Irp = (PIRP)SystemArgument2;
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)SystemArgument1;
-
+
if (SystemArgument1 == NULL && DoSystemDebug != -1)
{
- KdSystemDebugControl(DoSystemDebug);
- DoSystemDebug = -1;
+ if (KbdWorkItem != NULL)
+ {
+ IoQueueWorkItem(KbdWorkItem,
(PIO_WORKITEM_ROUTINE)KbdWorkItemRoutine, DelayedWorkQueue, NULL);
+ }
+ else
+ {
+ KdSystemDebugControl(DoSystemDebug);
+ DoSystemDebug = -1;
+ }
return;
}
-
+
CHECKPOINT;
DPRINT("KbdDpcRoutine(DeviceObject %x, Irp %x)\n",
DeviceObject,Irp);
@@ -436,6 +462,7 @@
IoStartNextPacket(DeviceObject,FALSE);
}
+
static BOOLEAN STDCALL
KeyboardHandler(PKINTERRUPT Interrupt,
PVOID Context)
@@ -538,7 +565,7 @@
else if (InSysRq == TRUE && ScanToVirtual(thisKey) >= VK_A &&
ScanToVirtual(thisKey) <= VK_Z && isDown)
{
- DoSystemDebug = ScanToVirtual(thisKey) - VK_A;
+ InterlockedExchange(&DoSystemDebug, ScanToVirtual(thisKey) -
VK_A);
KeInsertQueueDpc(&KbdDpc, NULL, NULL);
return(TRUE);
}
@@ -659,6 +686,11 @@
KbdClearInput();
KeyboardConnectInterrupt(DeviceObject);
KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL);
+ KbdWorkItem = IoAllocateWorkItem(DeviceObject);
+ if (KbdWorkItem == NULL)
+ {
+ DPRINT("Warning: Couldn't allocate work item!\n");
+ }
return 0;
}
_____
Copied: branches/alex_devel_branch/reactos/media/drivers/etc/KDB.init
(from rev 13841, trunk/reactos/media/drivers/etc/KDB.init)
_____
Modified: branches/alex_devel_branch/reactos/ntoskrnl/Makefile
--- branches/alex_devel_branch/reactos/ntoskrnl/Makefile
2005-03-05 23:35:08 UTC (rev 13841)
+++ branches/alex_devel_branch/reactos/ntoskrnl/Makefile
2005-03-05 23:58:25 UTC (rev 13842)
@@ -25,14 +25,10 @@
STRIP_FLAGS := -Wl,-s
ifeq ($(KDBG), 1)
-OBJECTS_KDBG := dbg/kdb.o dbg/kdb_serial.o dbg/kdb_keyboard.o
dbg/rdebug.o \
- dbg/i386/kdb_help.o \
- ../dk/w32/lib/libkjs.a dbg/i386/i386-dis.o
-CFLAGS_KDBG := -I../lib/kjs/include
+OBJECTS_KDBG := dbg/kdb.o dbg/kdb_cli.o dbg/kdb_expr.o
dbg/kdb_keyboard.o \
+ dbg/kdb_serial.o dbg/kdb_string.o dbg/rdebug.o
dbg/i386/kdb_help.o \
+ dbg/i386/i386-dis.o dbg/i386/longjmp.o
dbg/i386/setjmp.o
preall: all
-
-../dk/w32/lib/libkjs.a:
- $(MAKE) -C ../lib/kjs
else
OBJECTS_KDBG :=
endif
_____
Modified:
branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/i386-dis.c
--- branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/i386-dis.c
2005-03-05 23:35:08 UTC (rev 13841)
+++ branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/i386-dis.c
2005-03-05 23:58:25 UTC (rev 13842)
@@ -1,4 +1,4 @@
-/* $Id:$
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -52,10 +52,10 @@
int
-print_insn_i386_att (bfd_vma pc, struct disassemble_info *info);
+print_insn_i386 (bfd_vma pc, struct disassemble_info *info);
int
-KdbPrintDisasm(void* Ignored, const char* fmt, ...)
+KdbpPrintDisasm(void* Ignored, const char* fmt, ...)
{
va_list ap;
static char buffer[256];
@@ -69,46 +69,46 @@
}
int
-KdbNopPrintDisasm(void* Ignored, const char* fmt, ...)
+KdbpNopPrintDisasm(void* Ignored, const char* fmt, ...)
{
return(0);
}
int static
-KdbReadMemory(unsigned int Addr, unsigned char* Data, unsigned int
Length,
- struct disassemble_info * Ignored)
+KdbpReadMemory(unsigned int Addr, unsigned char* Data, unsigned int
Length,
+ struct disassemble_info * Ignored)
{
return KdbpSafeReadMemory(Data, (void *)Addr, Length); /* 0 means no
error */
}
void static
-KdbMemoryError(int Status, unsigned int Addr,
- struct disassemble_info * Ignored)
+KdbpMemoryError(int Status, unsigned int Addr,
+ struct disassemble_info * Ignored)
{
}
void static
-KdbPrintAddressInCode(unsigned int Addr, struct disassemble_info *
Ignored)
+KdbpPrintAddressInCode(unsigned int Addr, struct disassemble_info *
Ignored)
{
if (!KdbSymPrintAddress((void*)Addr))
{
- DbgPrint("<0x%X>", Addr);
+ DbgPrint("<%08x>", Addr);
}
}
void static
-KdbNopPrintAddress(unsigned int Addr, struct disassemble_info *
Ignored)
+KdbpNopPrintAddress(unsigned int Addr, struct disassemble_info *
Ignored)
{
}
#include "dis-asm.h"
long
-KdbGetInstLength(unsigned int Address)
+KdbpGetInstLength(unsigned int Address)
{
disassemble_info info;
- info.fprintf_func = KdbNopPrintDisasm;
+ info.fprintf_func = KdbpNopPrintDisasm;
info.stream = NULL;
info.application_data = NULL;
info.flavour = bfd_target_unknown_flavour;
@@ -116,9 +116,9 @@
info.mach = bfd_mach_i386_i386;
info.insn_sets = 0;
info.flags = 0;
- info.read_memory_func = KdbReadMemory;
- info.memory_error_func = KdbMemoryError;
- info.print_address_func = KdbNopPrintAddress;
+ info.read_memory_func = KdbpReadMemory;
+ info.memory_error_func = KdbpMemoryError;
+ info.print_address_func = KdbpNopPrintAddress;
info.symbol_at_address_func = NULL;
info.buffer = NULL;
info.buffer_vma = info.buffer_length = 0;
@@ -126,25 +126,25 @@
info.display_endian = BIG_ENDIAN_LITTLE;
info.disassembler_options = NULL;
- return(print_insn_i386_att(Address, &info));
+ return(print_insn_i386(Address, &info));
}
long
-KdbDisassemble(unsigned int Address)
+KdbpDisassemble(unsigned int Address, unsigned long IntelSyntax)
{
disassemble_info info;
- info.fprintf_func = KdbPrintDisasm;
+ info.fprintf_func = KdbpPrintDisasm;
info.stream = NULL;
info.application_data = NULL;
info.flavour = bfd_target_unknown_flavour;
info.arch = bfd_arch_i386;
- info.mach = bfd_mach_i386_i386;
+ info.mach = IntelSyntax ? bfd_mach_i386_i386_intel_syntax :
bfd_mach_i386_i386;
info.insn_sets = 0;
info.flags = 0;
- info.read_memory_func = KdbReadMemory;
- info.memory_error_func = KdbMemoryError;
- info.print_address_func = KdbPrintAddressInCode;
+ info.read_memory_func = KdbpReadMemory;
+ info.memory_error_func = KdbpMemoryError;
+ info.print_address_func = KdbpPrintAddressInCode;
info.symbol_at_address_func = NULL;
info.buffer = NULL;
info.buffer_vma = info.buffer_length = 0;
@@ -152,7 +152,7 @@
info.display_endian = BIG_ENDIAN_LITTLE;
info.disassembler_options = NULL;
- return(print_insn_i386_att(Address, &info));
+ return(print_insn_i386(Address, &info));
}
/* Print i386 instructions for GDB, the GNU debugger.
@@ -2113,7 +2113,7 @@
#else
mode_64bit = 0;
priv.orig_sizeflag = AFLAG | DFLAG;
- intel_syntax = 0;
+ /*intel_syntax = 0;*/
#endif
if (intel_syntax)
_____
Modified:
branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/kdb_help.S
--- branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/kdb_help.S
2005-03-05 23:35:08 UTC (rev 13841)
+++ branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/kdb_help.S
2005-03-05 23:58:25 UTC (rev 13842)
@@ -1,29 +1,19 @@
#include <internal/ke.h>
#include <internal/i386/segment.h>
- .data
-_KdbEipTemp:
- .int 0
+.text
- .text
-.globl _KdbEnter
+.globl _KdbEnter
_KdbEnter:
/*
- * Record when we are inside the debugger.
- */
- incl _KdbEntryCount
-
- /*
- * Save the callers eip.
- */
- popl _KdbEipTemp
-
- /*
* Set up a trap frame
*/
+ /* Ss - space already reserved by
return EIP */
+ pushl %esp /* Esp */
pushfl /* Eflags */
pushl %cs /* Cs */
- pushl _KdbEipTemp /* Eip */
+ pushl 12(%esp) /* Eip */
+ movl %ss, 16(%esp) /* Save Ss */
pushl $0 /* ErrorCode */
pushl %ebp /* Ebp */
pushl %ebx /* Ebx */
@@ -56,34 +46,35 @@
pushl $0 /* TempEip */
pushl $0 /* TempCs */
pushl $0 /* DebugPointer */
- pushl $0 /* DebugArgMark */
- pushl _KdbEipTemp /* DebugEip */
+ pushl $3 /* DebugArgMark (Exception number) */
+ pushl 0x60(%esp) /* DebugEip */
pushl %ebp /* DebugEbp */
/*
- * Push a pointer to the trap frame
- */
- pushl %esp
-
- /*
* Call KDB
*/
- call _KdbInternalEnter
+ 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
/*
- * Pop the argument
+ * Pop the arguments and unused portions of the trap frame:
+ * DebugEbp
+ * DebugEip
+ * DebugArgMark
+ * DebugPointer
+ * TempCs
+ * TempEip
*/
- popl %eax
+ addl $(11*4), %esp
/*
- * Ignore unused portions of the trap frame.
+ * Restore/update debugging registers.
*/
- popl %eax /* DebugEbp */
- popl %eax /* DebugEip */
- popl %eax /* DebugArgMark */
- popl %eax /* DebugPointer */
- popl %eax /* TempCs */
- popl %eax /* TempEip */
popl %eax /* Dr0 */
movl %eax, %dr0
popl %eax /* Dr1 */
@@ -113,19 +104,44 @@
popl %edi /* Edi */
popl %esi /* Esi */
popl %ebx /* Ebx */
+
+ /* Remove SS:ESP from the stack */
+ movl 16(%esp), %ebp
+ movl %ebp, 24(%esp)
+ movl 12(%esp), %ebp
+ movl %ebp, 20(%esp)
+ movl 8(%esp), %ebp
+ movl %ebp, 16(%esp)
+
popl %ebp /* Ebp */
- addl $4, %esp /* ErrorCode */
+ addl $12, %esp /* ErrorCode and SS:ESP */
/*
- * Record when we are in the debugger.
- */
- decl _KdbEntryCount
-
- /*
* 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 */
-
+ /* Switch stack */
+ movl %eax, %esp
+ pushl %edx
+
+ /* Call function */
+ call *%ecx
+
+ /* Switch back to old stack */
+ popl %esp
+
+ /* Return */
+ popl %ebp
+ ret $8
+
_____
Copied: branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/longjmp.S
(from rev 13841, trunk/reactos/ntoskrnl/dbg/i386/longjmp.S)
_____
Copied: branches/alex_devel_branch/reactos/ntoskrnl/dbg/i386/setjmp.S
(from rev 13841, trunk/reactos/ntoskrnl/dbg/i386/setjmp.S)
_____
Modified: branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb.c
--- branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb.c
2005-03-05 23:35:08 UTC (rev 13841)
+++ branches/alex_devel_branch/reactos/ntoskrnl/dbg/kdb.c
2005-03-05 23:58:25 UTC (rev 13842)
@@ -12,1786 +12,1495 @@
#include <ntoskrnl.h>
#include "kdb.h"
-#include "kjs.h"
#define NDEBUG
#include <internal/debug.h>
/* TYPES
*********************************************************************/
-/* GLOBALS
*******************************************************************/
+/* DEFINES
*******************************************************************/
-#define BS 8
-#define DEL 127
+#define KDB_STACK_SIZE (4096*3)
+#define KDB_MAXIMUM_BREAKPOINT_COUNT 256
+#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT 4
+#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT 256
-BOOL KbdEchoOn = TRUE;
+#define __STRING(x) #x
+#define _STRING(x) __STRING(x)
-typedef struct
-{
- BOOLEAN Enabled;
- BOOLEAN Temporary;
- BOOLEAN Assigned;
- ULONG Address;
- UCHAR SavedInst;
-} KDB_ACTIVE_BREAKPOINT;
+/* GLOBALS
*******************************************************************/
-#define KDB_MAXIMUM_BREAKPOINT_COUNT (255)
+STATIC LONG KdbEntryCount = 0;
+STATIC CHAR KdbStack[KDB_STACK_SIZE];
-static ULONG KdbBreakPointCount = 0;
-static KDB_ACTIVE_BREAKPOINT
- KdbActiveBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT];
+STATIC ULONG KdbBreakPointCount = 0; /* Number of used breakpoints in
the array */
+STATIC KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT] =
{{0}}; /* Breakpoint array */
+STATIC ULONG KdbSwBreakPointCount = 0; /* Number of enabled software
breakpoints */
+STATIC ULONG KdbHwBreakPointCount = 0; /* Number of enabled hardware
breakpoints */
+STATIC PKDB_BREAKPOINT
KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]; /* Enabled software
breakpoints, orderless */
+STATIC PKDB_BREAKPOINT
KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]; /* Enabled hardware
breakpoints, orderless */
+STATIC PKDB_BREAKPOINT KdbBreakPointToReenable = NULL; /* Set to a
breakpoint struct when single stepping after
+ a software
breakpoint was hit, to reenable it */
+LONG KdbLastBreakPointNr = -1; /* Index of the breakpoint which cause
KDB to be entered */
+ULONG KdbNumSingleSteps = 0; /* How many single steps to do */
+BOOLEAN KdbSingleStepOver = FALSE; /* Whether to step over calls/reps.
*/
-static BOOLEAN KdbHandleUmode = FALSE;
-static BOOLEAN KdbHandleHandled = FALSE;
-static BOOLEAN KdbBreakOnModuleLoad = FALSE;
+STATIC BOOLEAN KdbEnteredOnSingleStep = FALSE; /* Set to true when KDB
was entered because of single step */
+PEPROCESS KdbCurrentProcess = NULL; /* The current process context in
which KDB runs */
+PEPROCESS KdbOriginalProcess = NULL; /* The process in whichs context
KDB was intered */
+PETHREAD KdbCurrentThread = NULL; /* The current thread context in
which KDB runs */
+PETHREAD KdbOriginalThread = NULL; /* The thread in whichs context KDB
was entered */
+PKDB_KTRAP_FRAME KdbCurrentTrapFrame = NULL; /* Pointer to the current
trapframe */
+STATIC KDB_KTRAP_FRAME KdbTrapFrame = { { 0 } }; /* The trapframe
which was passed to KdbEnterDebuggerException */
+STATIC KDB_KTRAP_FRAME KdbThreadTrapFrame = { { 0 } }; /* The trapframe
of the current thread (KdbCurrentThread) */
+STATIC KAPC_STATE KdbApcState;
-static BOOLEAN KdbIgnoreNextSingleStep = FALSE;
-static ULONG KdbLastSingleStepFrom = 0xFFFFFFFF;
-static BOOLEAN KdbEnteredOnSingleStep = FALSE;
-
-ULONG KdbEntryCount = 0;
-
-int isalpha( int );
-VOID
-PsDumpThreads(BOOLEAN System);
-ULONG
-DbgContCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgStopCondition(ULONG Aargc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgModuleLoadedAction(ULONG Aargc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgEchoToggle(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgDRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgCRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgBugCheckCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgBackTraceCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgAddrCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgXCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgScriptCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgThreadListCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgProcessListCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgProcessHelpCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgShowFilesCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgEnableFileCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgDisableFileCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgDisassemble(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgSetBreakPoint(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgDeleteBreakPoint(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgSetMemoryBreakPoint(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgStep(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgStepOver(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgFinish(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-
-struct
+/* Array of conditions when to enter KDB */
+STATIC KDB_ENTER_CONDITION KdbEnterConditions[][2] =
{
- PCH Name;
- PCH Syntax;
- PCH Help;
- ULONG (*Fn)(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-} DebuggerCommands[] = {
- {"cont", "cont", "Exit the debugger", DbgContCommand},
- {"echo", "echo", "Toggle serial echo", DbgEchoToggle},
- {"condition", "condition [all|umode|kmode]", "Kdbg enter
condition",
DbgStopCondition},
- {"module-loaded", "module-loaded [break|continue]",
"Module-loaded
action", DbgModuleLoadedAction},
+ /* First chance Last chance */
+ { KdbDoNotEnter, KdbEnterFromKmode }, /* Zero devide */
+ { KdbEnterAlways, 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 */
+};
- {"regs", "regs", "Display general purpose registers",
DbgRegsCommand},
- {"dregs", "dregs", "Display debug registers",
DbgDRegsCommand},
- {"cregs", "cregs", "Display control registers",
DbgCRegsCommand},
- {"bugcheck", "bugcheck", "Bugcheck the system",
DbgBugCheckCommand},
- {"bt", "bt [*frame-address]|[thread-id]","Do a
backtrace",
DbgBackTraceCommand},
- {"addr", "addr <address>", "Displays symbol info",
DbgAddrCommand},
- {"x", "x <addr> <words>", "Displays <addr>
for <words>",
DbgXCommand},
- {"plist", "plist", "Display processes in the system",
DbgProcessListCommand},
- {"tlist", "tlist [sys]", "Display threads in the
system",
DbgThreadListCommand},
- {"sfiles", "sfiles", "Show files that print debug
prints",
DbgShowFilesCommand},
- {"efile", "efile <filename>", "Enable debug prints from
file",
DbgEnableFileCommand},
- {"dfile", "dfile <filename>", "Disable debug prints from
file",
DbgDisableFileCommand},
- {"js", "js", "Script mode", DbgScriptCommand},
- {"disasm", "disasm <address>", "Disables 10 instructions
at <address>
or "
- "eip", DbgDisassemble},
- {"bp", "bp <address>", "Sets an int3 breakpoint at a
given address",
- DbgSetBreakPoint},
- {"bc", "bc <breakpoint number>", "Deletes a
breakpoint",
- DbgDeleteBreakPoint},
- {"ba", "ba <debug register> <access type> <length>
<address>",
- "Sets a breakpoint using a debug register", DbgSetMemoryBreakPoint},
- {"t", "t", "Steps forward a single instructions",
DbgStep},
- {"p", "p", "Steps forward a single instructions skipping
calls",
- DbgStepOver},
- {"finish", "finish", "Runs until the current function
exits",
DbgFinish},
- {"help", "help", "Display help screen",
DbgProcessHelpCommand},
- {NULL, NULL, NULL}
+/* Exception descriptions */
+STATIC CONST PCHAR 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"
};
-static const char *ExceptionTypeStrings[] =
- {
- "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"
- };
-
-volatile DWORD x_dr0 = 0, x_dr1 = 0, x_dr2 = 0, x_dr3 = 0, x_dr7 = 0;
-
-extern LONG KdbDisassemble(ULONG Address);
-extern LONG KdbGetInstLength(ULONG Address);
-
/* FUNCTIONS
*****************************************************************/
-/*
- * Convert a string to an unsigned long integer.
+/*!\brief Overwrites the instruction at \a Address with \a NewInst and
stores
+ * the old instruction in *OldInst.
*
- * Ignores `locale' stuff. Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
+ * \param Process Process in which's context to overwrite the
instruction.
+ * \param Address Address at which to overwrite the instruction.
+ * \param NewInst New instruction (written to \a Address)
+ * \param OldInst Old instruction (read from \a Address)
+ *
+ * \returns NTSTATUS
*/
-unsigned long
-strtoul(const char *nptr, char **endptr, int base)
+STATIC NTSTATUS
+KdbpOverwriteInstruction(
+ IN PEPROCESS Process,
+ IN ULONG_PTR Address,
+ IN UCHAR NewInst,
+ OUT PUCHAR OldInst OPTIONAL)
{
- const char *s = nptr;
- unsigned long acc;
- int c;
- unsigned long cutoff;
- int neg = 0, any, cutlim;
+ NTSTATUS Status;
+ ULONG Protect;
+ PEPROCESS CurrentProcess = PsGetCurrentProcess();
+ KAPC_STATE ApcState;
- /*
- * See strtol for comments as to the logic used.
- */
- do {
- c = *s++;
- } while (isspace(c));
- if (c == '-')
- {
- neg = 1;
- c = *s++;
- }
- else if (c == '+')
- c = *s++;
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X'))
- {
- c = s[1];
- s += 2;
- base = 16;
- }
- if (base == 0)
- base = c == '0' ? 8 : 10;
- cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
- cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
- for (acc = 0, any = 0;; c = *s++)
- {
- if (isdigit(c))
- c -= '0';
- else if (isalpha(c))
- c -= isupper(c) ? 'A' - 10 : 'a' - 10;
- else
- break;
- if (c >= base)
- break;
- if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
- any = -1;
- else {
- any = 1;
- acc *= base;
- acc += c;
- }
- }
- if (any < 0)
- {
- acc = ULONG_MAX;
- }
- else if (neg)
- acc = -acc;
- if (endptr != 0)
- *endptr = any ? (char *)s - 1 : (char *)nptr;
- return acc;
-}
+ /* 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;
+ }
+
+ /* Attach to the process */
+ if (CurrentProcess != Process)
+ {
+ KeStackAttachProcess(EPROCESS_TO_KPROCESS(Process), &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);
+ }
+
+ /* 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 new instruction in its place. */
+ Status = KdbpSafeWriteMemory((PUCHAR)Address, &NewInst, 1);
+
+ /* 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);
+ }
-char*
-strpbrk(const char* s, const char* accept)
-{
- int i;
- for (; (*s) != 0; s++)
- {
- for (i = 0; accept[i] != 0; i++)
- {
- if (accept[i] == (*s))
- {
- return((char *)s);
- }
- }
- }
- return(NULL);
+ return Status;
}
-
-#if 0
-NTSTATUS
-KdbpSafeReadMemory(PVOID dst, PVOID src, INT size)
+/*!\brief Checks whether the given instruction can be single stepped or
has to be
+ * stepped over using a temporary breakpoint.
+ *
+ * \retval TRUE Instruction is a call.
+ * \retval FALSE Instruction is not a call.
+ */
+BOOLEAN
+KdbpShouldStepOverInstruction(ULONG_PTR Eip)
{
- INT page, page_end;
-
- /* check source */
- page_end = (((ULONG_PTR)src + size) / PAGE_SIZE);
- for (page = ((ULONG_PTR)src / PAGE_SIZE); page <= page_end; page++)
- {
- if (!MmIsPagePresent(NULL, (PVOID)(page * PAGE_SIZE)))
- return STATUS_UNSUCCESSFUL;
- }
+ UCHAR Mem[3];
+ INT i = 0;
- /* copy memory */
- RtlCopyMemory(dst, src, size);
- return STATUS_SUCCESS;
+ if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
+ {
+ KdbpPrint("Couldn't access memory at 0x%x\n", (UINT)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;
}
-
-NTSTATUS
-KdbpSafeWriteMemory(PVOID dst, PVOID src, INT size)
+/*!\brief Steps over an instruction
+ *
+ * If the given instruction should be stepped over, this function
inserts a
+ * temporary breakpoint after the instruction and returns TRUE,
otherwise it
+ * returns FALSE.
+ *
+ * \retval TRUE Temporary breakpoint set after instruction.
+ * \retval FALSE No breakpoint was set.
+ */
+BOOLEAN
+KdbpStepOverInstruction(ULONG_PTR Eip)
{
- return KdbpSafeWriteMemory(dst, src, size);
- INT page, page_end;
+ LONG InstLen;
- /* check destination */
- page_end = (((ULONG_PTR)dst + size) / PAGE_SIZE);
- for (page = ((ULONG_PTR)dst / PAGE_SIZE); page <= page_end; page++)
- {
- if (!MmIsPagePresent(NULL, (PVOID)(page * PAGE_SIZE)))
- return STATUS_UNSUCCESSFUL;
- }
+ if (!KdbpShouldStepOverInstruction(Eip))
+ return FALSE;
- /* copy memory */
- RtlCopyMemory(dst, src, size);
- return STATUS_SUCCESS;
-}
-#endif /* unused */
+ InstLen = KdbpGetInstLength(Eip);
+ if (InstLen < 1)
+ return FALSE;
+ if (!NT_SUCCESS(KdbpInsertBreakPoint(Eip + InstLen,
KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
+ return FALSE;
-VOID
-KdbGetCommand(PCH Buffer)
-{
- CHAR Key;
- PCH Orig = Buffer;
- static CHAR LastCommand[256] = "";
- ULONG ScanCode = 0;
- static CHAR LastKey = '\0';
-
- KbdEchoOn = !((KdDebugState & KD_DEBUG_KDNOECHO) != 0);
-
- for (;;)
- {
- if (KdDebugState & KD_DEBUG_KDSERIAL)
- while ((Key = KdbTryGetCharSerial()) == -1);
- else
- while ((Key = KdbTryGetCharKeyboard(&ScanCode)) == -1);
-
- if (Key == '\n' && LastKey == '\r')
- {
- /* Ignore this key... */
- }
- else if (Key == '\r' || Key == '\n')
- {
- DbgPrint("\n");
- /*
- Repeat the last command if the user presses enter. Reduces
the
- risk of RSI when single-stepping.
- */
- if (Buffer == Orig)
- {
- strcpy(Buffer, LastCommand);
- }
- else
- {
- *Buffer = 0;
- strcpy(LastCommand, Orig);
- }
- LastKey = Key;
- return;
- }
- else if (Key == BS || Key == DEL)
- {
- if (Buffer > Orig)
- {
- Buffer--;
- *Buffer = 0;
- if (KbdEchoOn)
- DbgPrint("%c %c", BS, BS);
- else
- DbgPrint(" %c", BS);
- }
- }
- else if (ScanCode == 72)
- {
- ULONG i;
- while (Buffer > Orig)
- {
- Buffer--;
- *Buffer = 0;
- if (KbdEchoOn)
- DbgPrint("%c %c", BS, BS);
- else
- DbgPrint(" %c", BS);
- }
- for (i = 0; LastCommand[i] != 0; i++)
- {
- if (KbdEchoOn)
- DbgPrint("%c", LastCommand[i]);
- *Buffer = LastCommand[i];
- Buffer++;
- }
- }
- else
- {
[truncated at 1000 lines; 3359 more skipped]