Little KDB update ;-) If you have any problems and/or questions let me know. I hope it was tested enough and works well enough for everybody.

svn path=/trunk/; revision=13841
This commit is contained in:
Gregor Anich 2005-03-05 23:35:08 +00:00
parent ef8c905431
commit f3cea5b1a2
24 changed files with 5621 additions and 1814 deletions

View file

@ -216,6 +216,8 @@ bootcd_install_before:
$(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 @@ install_before:
$(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

View file

@ -38,6 +38,7 @@ static BYTE capsDown,numDown,scrollDown;
static DWORD ctrlKeyState;
static PKINTERRUPT KbdInterrupt;
static KDPC KbdDpc;
static PIO_WORKITEM KbdWorkItem = NULL;
static BOOLEAN AlreadyOpened = FALSE;
/*
@ -407,6 +408,24 @@ static WORD ScanToVirtual(BYTE scanCode)
}
/*
* 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
*/
@ -422,8 +441,15 @@ KbdDpcRoutine(PKDPC Dpc,
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;
}
@ -436,6 +462,7 @@ KbdDpcRoutine(PKDPC Dpc,
IoStartNextPacket(DeviceObject,FALSE);
}
static BOOLEAN STDCALL
KeyboardHandler(PKINTERRUPT Interrupt,
PVOID Context)
@ -538,7 +565,7 @@ KeyboardHandler(PKINTERRUPT Interrupt,
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 @@ static int InitializeKeyboard(PDEVICE_OBJECT DeviceObject)
KbdClearInput();
KeyboardConnectInterrupt(DeviceObject);
KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL);
KbdWorkItem = IoAllocateWorkItem(DeviceObject);
if (KbdWorkItem == NULL)
{
DPRINT("Warning: Couldn't allocate work item!\n");
}
return 0;
}

View file

@ -0,0 +1,15 @@
# Example KDB.init file
#
# The disassembly flavor is set to "intel" (default is "at&t") and the
#
# Set the disassembly flavor to "intel" (default is "at&t")
set syntax intel
# Change the condition to enter KDB on INT3 to "always" (default is "kmode")
set condition INT3 first always
# This is a special command available only in the KDB.init file - it breaks into
# KDB when it is interpreting the init file at startup.
#break

View file

@ -25,14 +25,10 @@ LINKER_SCRIPT := ntoskrnl.lnk
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

View file

@ -1,4 +1,4 @@
/* $Id:$
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -52,10 +52,10 @@ extern long MmSafeCopyFromUser(void *Dest, void *Src, unsigned long NumberOfByte
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 @@ KdbPrintDisasm(void* Ignored, const char* fmt, ...)
}
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 @@ KdbGetInstLength(unsigned int Address)
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 @@ KdbGetInstLength(unsigned int Address)
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 @@ KdbDisassemble(unsigned int Address)
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 @@ print_insn (pc, info)
#else
mode_64bit = 0;
priv.orig_sizeflag = AFLAG | DFLAG;
intel_syntax = 0;
/*intel_syntax = 0;*/
#endif
if (intel_syntax)

View file

@ -1,29 +1,19 @@
#include <internal/ke.h>
#include <internal/i386/segment.h>
.data
_KdbEipTemp:
.int 0
.text
.text
.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 @@ _KdbEnter:
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,13 +104,17 @@ _KdbEnter:
popl %edi /* Edi */
popl %esi /* Esi */
popl %ebx /* Ebx */
popl %ebp /* Ebp */
addl $4, %esp /* ErrorCode */
/*
* Record when we are in the debugger.
*/
decl _KdbEntryCount
/* 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 $12, %esp /* ErrorCode and SS:ESP */
/*
* Return to the caller.
@ -127,5 +122,26 @@ _KdbEnter:
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

View file

@ -0,0 +1,70 @@
.file "longjmp.S"
/*
* Copyright (C) 1998, 1999, Jonathan S. Shapiro.
*
* This file is part of the EROS Operating System.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* typedef struct {
* unsigned long ebx, esi, edi;
* unsigned long ebp;
* unsigned long sp;
* unsigned long pc;
* } jmp_buf[1];
*/
/*
* On entry, the stack to longjmp looks like:
*
* value
* ptr to jmp_buf
* return PC
*/
.globl _longjmp
_longjmp:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%ecx /* address of jmp_buf to ecx */
movl 12(%ebp),%eax /* return value to %eax */
testl %eax,%eax
jne 1f
incl %eax /* return 1 if handed 0 */
1:
movl (%ecx),%ebx /* restore %ebx */
movl 4(%ecx),%esi /* restore %esi */
movl 8(%ecx),%edi /* restore %edi */
/*
* From this instant on we are not running in a valid frame
*/
movl 12(%ecx),%ebp /* restore %ebp */
movl 16(%ecx),%esp /* restore %esp */
/* movl 20(%ecx),%eax return PC */
/*
* Since we are abandoning the stack in any case,
* there isn't much point in doing the usual return
* discipline.
*/
jmpl *20(%ecx)

View file

@ -0,0 +1,59 @@
.file "setjmp.S"
/*
* Copyright (C) 1998, 1999, Jonathan S. Shapiro.
*
* This file is part of the EROS Operating System.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* #include <eros/i486/asm.h> */
/*
* typedef struct {
* unsigned long ebx, esi, edi;
* unsigned long ebp;
* unsigned long sp;
* unsigned long pc;
* } jmp_buf[1];
*/
/*
* On entry, the stack to setjmp looks like:
*
* ptr to jmp_buf
* return PC
*/
.globl _setjmp
_setjmp:
pushl %ebp
movl %esp,%ebp
movl 0x8(%ebp),%eax /* address of jmp_buf to eax */
movl %ebx,(%eax) /* save %ebx */
movl %esi,4(%eax) /* save %esi */
movl %edi,8(%eax) /* save %edi */
leal 8(%ebp),%edx /* calling proc's esp, not ours! */
movl %edx,16(%eax)
movl 4(%ebp), %edx /* save return PC */
movl %edx,20(%eax)
movl 0(%ebp),%edx /* calling proc's ebp, not ours! */
movl %edx,12(%eax)
xorl %eax,%eax /* return 0 the first time */
leave
ret $4

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,82 @@
#ifndef NTOSKRNL_KDB_H
#define NTOSKRNL_KDB_H
/* INCLUDES ******************************************************************/
#define NTOS_MODE_KERNEL
#include <ntos.h>
#include <internal/ke.h>
/* DEFINES *******************************************************************/
#define TAG_KDBG (('K' << 24) | ('D' << 16) | ('B' << 8) | 'G')
#ifndef RTL_NUMBER_OF
# define RTL_NUMBER_OF(x) (sizeof(x) / sizeof((x)[0]))
#endif
/* TYPES *********************************************************************/
/* from kdb.c */
typedef struct _KDB_KTRAP_FRAME
{
KTRAP_FRAME Tf;
ULONG Cr0;
ULONG Cr1; /* reserved/unused */
ULONG Cr2;
ULONG Cr3;
ULONG Cr4;
} KDB_KTRAP_FRAME, *PKDB_KTRAP_FRAME;
typedef enum _KDB_BREAKPOINT_TYPE
{
KdbBreakPointNone = 0,
KdbBreakPointSoftware,
KdbBreakPointHardware,
KdbBreakPointTemporary
} KDB_BREAKPOINT_TYPE;
typedef enum _KDB_ACCESS_TYPE
{
KdbAccessRead,
KdbAccessWrite,
KdbAccessReadWrite,
KdbAccessExec
} KDB_ACCESS_TYPE;
typedef struct _KDB_BREAKPOINT
{
KDB_BREAKPOINT_TYPE Type; /* Type of breakpoint */
BOOLEAN Enabled; /* Whether the bp is enabled */
ULONG_PTR Address; /* Address of the breakpoint */
BOOLEAN Global; /* Whether the breakpoint is global or local to a process */
PEPROCESS Process; /* Owning process */
PCHAR ConditionExpression;
PVOID Condition;
union {
/* KdbBreakPointSoftware */
UCHAR SavedInstruction;
/* KdbBreakPointHardware */
struct {
UCHAR DebugReg : 2;
UCHAR Size : 3;
KDB_ACCESS_TYPE AccessType;
} Hw;
} Data;
} KDB_BREAKPOINT, *PKDB_BREAKPOINT;
typedef enum _KDB_ENTER_CONDITION
{
KdbDoNotEnter,
KdbEnterAlways,
KdbEnterFromKmode,
KdbEnterFromUmode
} KDB_ENTER_CONDITION;
/* from kdb_symbols.c */
typedef struct _KDB_MODULE_INFO
{
WCHAR Name[256];
@ -9,6 +85,74 @@ typedef struct _KDB_MODULE_INFO
PROSSYM_INFO RosSymInfo;
} KDB_MODULE_INFO, *PKDB_MODULE_INFO;
/* FUNCTIONS *****************************************************************/
/* from i386/i386-dis.c */
LONG
KdbpDisassemble(
IN ULONG Address,
IN ULONG IntelSyntax);
LONG
KdbpGetInstLength(
IN ULONG Address);
/* from i386/kdb_help.S */
STDCALL VOID
KdbpStackSwitchAndCall(
IN PVOID NewStack,
IN VOID (*Function)(VOID));
/* from kdb_cli.c */
extern PCHAR KdbInitFileBuffer;
VOID
KdbpCliInit();
VOID
KdbpCliMainLoop(
IN BOOLEAN EnteredOnSingleStep);
VOID
KdbpCliModuleLoaded(
IN PUNICODE_STRING Name);
VOID
KdbpCliInterpretInitFile();
VOID
KdbpPrint(
IN PCHAR Format,
IN ... OPTIONAL);
/* from kdb_expr.c */
BOOLEAN
KdbpRpnEvaluateExpression(
IN PCHAR Expression,
IN PKDB_KTRAP_FRAME TrapFrame,
OUT PULONGLONG Result,
OUT PLONG ErrOffset OPTIONAL,
OUT PCHAR ErrMsg OPTIONAL);
PVOID
KdbpRpnParseExpression(
IN PCHAR Expression,
OUT PLONG ErrOffset OPTIONAL,
OUT PCHAR ErrMsg OPTIONAL);
BOOLEAN
KdbpRpnEvaluateParsedExpression(
IN PVOID Expression,
IN PKDB_KTRAP_FRAME TrapFrame,
OUT PULONGLONG Result,
OUT PLONG ErrOffset OPTIONAL,
OUT PCHAR ErrMsg OPTIONAL);
/* from kdb_symbols.c */
BOOLEAN
@ -33,23 +177,86 @@ KdbSymGetAddressInformation(IN PROSSYM_INFO RosSymInfo,
OUT PCH FileName OPTIONAL,
OUT PCH FunctionName OPTIONAL);
/* other functions */
#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size)
#define KdbpSafeWriteMemory(dst, src, size) MmSafeCopyToUser(dst, src, size)
CHAR
KdbTryGetCharKeyboard(PULONG ScanCode);
ULONG
KdbTryGetCharSerial(VOID);
/* from kdb.c */
extern PEPROCESS KdbCurrentProcess;
extern PETHREAD KdbCurrentThread;
extern LONG KdbLastBreakPointNr;
extern ULONG KdbNumSingleSteps;
extern BOOLEAN KdbSingleStepOver;
extern PKDB_KTRAP_FRAME KdbCurrentTrapFrame;
VOID
KdbEnter(VOID);
KdbInit();
VOID
DbgRDebugInit(VOID);
VOID
DbgShowFiles(VOID);
VOID
DbgEnableFile(PCH Filename);
VOID
DbgDisableFile(PCH Filename);
KdbModuleLoaded(
IN PUNICODE_STRING Name);
LONG
KdbpGetNextBreakPointNr(
IN ULONG Start OPTIONAL);
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);
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 PULONG BreakPointNumber OPTIONAL);
BOOLEAN
KdbpDeleteBreakPoint(
IN LONG BreakPointNr OPTIONAL,
IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL);
BOOLEAN
KdbpEnableBreakPoint(
IN LONG BreakPointNr OPTIONAL,
IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL);
BOOLEAN
KdbpDisableBreakPoint(
IN LONG BreakPointNr OPTIONAL,
IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL);
BOOLEAN
KdbpGetEnterCondition(
IN LONG ExceptionNr,
IN BOOLEAN FirstChance,
OUT KDB_ENTER_CONDITION *Condition);
BOOLEAN
KdbpSetEnterCondition(
IN LONG ExceptionNr,
IN BOOLEAN FirstChance,
IN KDB_ENTER_CONDITION Condition);
BOOLEAN
KdbpAttachToThread(
PVOID ThreadId);
BOOLEAN
KdbpAttachToProcess(
PVOID ProcessId);
/* from profile.c */
VOID
KdbInitProfiling();
VOID
@ -61,13 +268,25 @@ KdbEnableProfiling();
VOID
KdbProfileInterrupt(ULONG_PTR Eip);
/* other functions */
#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size)
#define KdbpSafeWriteMemory(dst, src, size) MmSafeCopyToUser(dst, src, size)
CHAR
KdbpTryGetCharKeyboard(PULONG ScanCode);
ULONG
KdbpTryGetCharSerial(VOID);
VOID
KdbModuleLoaded(IN PUNICODE_STRING Name);
KdbEnter(VOID);
VOID
DbgRDebugInit(VOID);
VOID
DbgShowFiles(VOID);
VOID
DbgEnableFile(PCH Filename);
VOID
DbgDisableFile(PCH Filename);
struct KDB_BPINFO {
DWORD Addr;
DWORD Type;
DWORD Size;
DWORD Enabled;
};
#endif /* NTOSKRNL_KDB_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $Id:$
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -62,7 +62,7 @@ VOID KbdDisableMouse()
}
CHAR
KdbTryGetCharKeyboard(PULONG ScanCode)
KdbpTryGetCharKeyboard(PULONG ScanCode)
{
static byte_t last_key = 0;
static byte_t shift = 0;
@ -305,7 +305,7 @@ static char keymap[128][2] = {
* Yes, this is horrible.
*/
ULONG
KdbTryGetCharKeyboard(VOID)
KdbpTryGetCharKeyboard(VOID)
{
static unsigned shift_state, ctrl_state, meta_state;
unsigned scan_code, ch;

View file

@ -1,4 +1,4 @@
/* $Id:$
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -20,7 +20,7 @@ extern KD_PORT_INFORMATION LogPortInfo;
CHAR
KdbTryGetCharSerial()
KdbpTryGetCharSerial()
{
UCHAR Result;

View file

@ -0,0 +1,123 @@
/*
* ReactOS kernel
* Copyright (C) 2005 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id$
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb_string.c
* PURPOSE: Kernel debugger string functions
* PROGRAMMER: Gregor Anich (blight@blight.eu.org)
* UPDATE HISTORY:
* Created 17/01/2005
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
/* FUNCTIONS *****************************************************************/
#if 0
int
_stricmp(
const char *s1,
const char *s2)
{
char c1, c2;
for (;;)
{
c1 = tolower(*s1++);
c2 = tolower(*s2++);
if (c1 < c2)
return -1;
else if (c1 > c2)
return 1;
if (c1 == '\0')
break;
}
return 0;
}
#endif /* unused */
/*
* Convert a string to an unsigned long integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
unsigned long
strtoul(const char *nptr, char **endptr, int base)
{
const char *s = nptr;
unsigned long acc;
int c;
unsigned long cutoff;
int neg = 0, any, cutlim;
/*
* 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;
}

View file

@ -243,12 +243,12 @@ KdbSymPrintAddress(IN PVOID Address)
FunctionName);
if (NT_SUCCESS(Status))
{
DbgPrint("<%ws: %x (%s:%d (%s))>",
DbgPrint("<%ws:%x (%s:%d (%s))>",
Info.Name, RelativeAddress, FileName, LineNumber, FunctionName);
}
else
{
DbgPrint("<%ws: %x>", Info.Name, RelativeAddress);
DbgPrint("<%ws:%x>", Info.Name, RelativeAddress);
}
return TRUE;
@ -541,7 +541,7 @@ KdbSymFreeProcessSymbols(IN PEPROCESS Process)
CurrentProcess = PsGetCurrentProcess();
if (CurrentProcess != Process)
{
KeAttachProcess(&Process->Pcb);
KeAttachProcess(EPROCESS_TO_KPROCESS(Process));
}
Peb = Process->Peb;
ASSERT(Peb);

View file

@ -69,9 +69,11 @@
#define KTRAP_FRAME_RESERVED9 (0x8A)
#define KTRAP_FRAME_SIZE (0x8C)
#define X86_EFLAGS_TF 0x00000100 /* Trap flag */
#define X86_EFLAGS_IF 0x00000200 /* Interrupt Enable flag */
#define X86_EFLAGS_IOPL 0x00003000 /* I/O Privilege Level bits */
#define X86_EFLAGS_NT 0x00004000 /* Nested Task flag */
#define X86_EFLAGS_RF 0x00010000 /* Resume flag */
#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */

View file

@ -98,9 +98,6 @@ KdGdbDebugPrint (LPSTR Message);
VOID
KdDebugPrint (LPSTR Message);
VOID
KdbCreateThreadHook(PCONTEXT Context);
KD_CONTINUE_TYPE
KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
PCONTEXT Context,
@ -118,7 +115,7 @@ VOID KdPrintMda(PCH pch);
# define KDB_CREATE_THREAD_HOOK(CONTEXT) do { } while (0)
#else
# define KDB_LOADUSERMODULE_HOOK(LDRMOD) KdbSymLoadUserModuleSymbols(LDRMOD)
# define KDB_DELETEPROCESS_HOOK(PROCESS) KdbSymFreeProcessSymbols(PROCESS)
# define KDB_DELETEPROCESS_HOOK(PROCESS) KdbDeleteProcessHook(PROCESS)
# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE)
# define KDB_UNLOADDRIVER_HOOK(MODULE) KdbSymUnloadDriverSymbols(MODULE)
# define KDB_LOADERINIT_HOOK(NTOS, HAL) KdbSymInit(NTOS, HAL)
@ -126,6 +123,9 @@ VOID KdPrintMda(PCH pch);
/*#define KDB_CREATE_THREAD_HOOK(CONTEXT) \
KdbCreateThreadHook(CONTEXT)
*/
VOID
KdbDeleteProcessHook(IN PEPROCESS Process);
VOID
KdbSymLoadUserModuleSymbols(IN PLDR_MODULE LdrModule);
@ -155,7 +155,7 @@ KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
KPROCESSOR_MODE PreviousMode,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame,
BOOLEAN HandleAlways);
BOOLEAN FirstChance);
#endif /* KDBG || DBG */

View file

@ -81,7 +81,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
#ifdef KDBG
Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
Context, Tf, FALSE);
Context, Tf, TRUE);
if (Action == kdContinue)
{
return;
@ -131,7 +131,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
#ifdef KDBG
Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
Context, Tf, TRUE);
Context, Tf, FALSE);
if (Action == kdContinue)
{
return;
@ -147,7 +147,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
/* PreviousMode == KernelMode */
#ifdef KDBG
Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
Context, Tf, FALSE);
Context, Tf, TRUE);
if (Action == kdContinue)
{
return;
@ -168,7 +168,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
ExceptionRecord->ExceptionAddress );
#ifdef KDBG
Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
Context, Tf, TRUE);
Context, Tf, FALSE);
if (Action == kdContinue)
{
return;

View file

@ -26,7 +26,9 @@
/* INCLUDES ******************************************************************/
#include <roscfg.h>
#include <ddk/status.h>
#include <internal/i386/ke.h>
#include <internal/i386/segment.h>
#include <internal/ps.h>
#include <ddk/defines.h>
@ -74,6 +76,29 @@ _KiTrapRet:
popl %edi
popl %esi
popl %ebx
#ifdef DBG
/*
* Cleanup the stack which was used to setup a trapframe with SS:ESP when called
* from kmode.
*/
movw 0xC(%esp), %bp /* Get CS from trapframe */
cmpw $KERNEL_CS, %bp
jne 0f
/* Copy EBP, CS:EIP and EFLAGS from the trapframe back onto the top of our stack. */
movl 0x00(%esp), %ebp /* EBP */
movl %ebp, 0x24(%esp)
movl 0x08(%esp), %ebp /* EIP */
movl %ebp, 0x2C(%esp)
movl 0x0C(%esp), %ebp /* CS */
movl %ebp, 0x30(%esp)
movl 0x10(%esp), %ebp /* EFLAGS */
movl %ebp, 0x34(%esp)
addl $0x24, %esp
0:
#endif /* DBG */
popl %ebp
addl $0x4, %esp /* Ignore error code */
@ -81,6 +106,28 @@ _KiTrapRet:
.globl _KiTrapProlog
_KiTrapProlog:
#ifdef DBG
/*
* If we were called from kmode we start setting up a new trapframe (with SS:ESP at the end)
*/
movw 0x14(%esp), %bx /* Get old CS */
cmpw $KERNEL_CS, %bx
jne 0f
leal 0x1C(%esp), %ebp
pushl %ss /* Old SS */
pushl %ebp /* Old ESP */
pushl 0x20(%esp) /* Old EFLAGS */
pushl 0x20(%esp) /* Old CS */
pushl 0x20(%esp) /* Old EIP */
pushl 0x20(%esp) /* ErrorCode */
pushl 0x20(%esp) /* Ebp */
pushl 0x20(%esp) /* Ebx */
pushl 0x20(%esp) /* Esi */
0:
#endif /* DBG */
pushl %edi
pushl %fs

View file

@ -45,6 +45,10 @@ _Ki386ContextSwitch:
* Thread = Thread to switch to
* OldThread = Thread to switch from
*/
#ifdef KDBG
jmp SaveTrapFrameForKDB
SaveTrapFrameForKDB_Return:
#endif
pushl %ebp
movl %esp, %ebp
@ -218,3 +222,128 @@ _Ki386ContextSwitch:
ret
.endfunc
#ifdef KDBG
SaveTrapFrameForKDB:
/*
* Set up a trap frame.
*/
/* Ss - space already reserved by return EIP */
pushl %esp /* Esp */
pushfl /* Eflags */
pushl %cs /* Cs */
pushl 12(%esp) /* Eip */
movl %ss, 16(%esp) /* Save Ss */
pushl $0 /* ErrorCode */
pushl %ebp /* Ebp */
pushl %ebx /* Ebx */
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 breakpoint enables in dr7. */
andl $~0xffff, %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 */
pushl $0 /* TempEip */
pushl $0 /* TempCs */
pushl $0 /* DebugPointer */
pushl $0xffffffff /* DebugArgMark (Exception number) */
pushl 0x60(%esp) /* DebugEip */
pushl %ebp /* DebugEbp */
movl %esp, %ebp /* Save pointer to new TrapFrame */
/* Save the old trapframe and set pointer to the new one */
movl 0x80(%esp), %ebx /* Get pointer to OldThread */
pushl KTHREAD_TRAP_FRAME(%ebx)
movl %ebp, KTHREAD_TRAP_FRAME(%ebx)
/* Copy the arguments which were passed to Ki386ContextSwitch */
pushl 0x80(%ebp) /* OldThread */
pushl 0x7c(%ebp) /* NewThread */
pushl $RestoreTrapFrameForKDB /* Return address */
/* Restore clobbered registers */
movl KTRAP_FRAME_EBX(%ebp), %ebx
movl KTRAP_FRAME_EBP(%ebp), %ebp
/* Return */
jmp SaveTrapFrameForKDB_Return
RestoreTrapFrameForKDB:
addl $8, %esp /* Remove NewThread and OldThread arguments from the stack */
movl 0x84(%esp), %ebx /* Get pointer to OldThread */
/* Restore the old trapframe */
popl KTHREAD_TRAP_FRAME(%ebx)
/*
* Pop unused portions of the trap frame:
* DebugEbp
* DebugEip
* DebugArgMark
* DebugPointer
* TempCs
* TempEip
* Dr0-3
* Dr6-7
*/
addl $(12*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 $4, %esp /* PreviousMode */
addl $4, %esp /* ExceptionList */
popl %fs /* Fs */
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 $12, %esp /* ErrorCode and SS:ESP */
/*
* Return to the caller.
*/
iret
#endif /* KDBG */

View file

@ -236,10 +236,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->Alerted[0] = 0;
Thread->Alerted[1] = 0;
Thread->Iopl = 0;
/*
* FIXME: Think how this might work
*/
Thread->NpxState = 0;
Thread->NpxState = NPX_STATE_INVALID;
Thread->Saturation = 0;
Thread->Priority = Process->BasePriority;
@ -262,7 +259,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->DecrementCount = 0;
Thread->PriorityDecrement = 0;
Thread->Quantum = Process->ThreadQuantum;
memset(Thread->WaitBlock, 0, sizeof(KWAIT_BLOCK)*4);
RtlZeroMemory(Thread->WaitBlock, sizeof(KWAIT_BLOCK)*4);
Thread->LegoData = 0;
Thread->UserAffinity = Process->Affinity;
Thread->SystemAffinityActive = 0;
@ -271,7 +268,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->ServiceTable = KeServiceDescriptorTable;
Thread->Queue = NULL;
KeInitializeSpinLock(&Thread->ApcQueueLock);
memset(&Thread->Timer, 0, sizeof(KTIMER));
RtlZeroMemory(&Thread->Timer, sizeof(KTIMER));
KeInitializeTimer(&Thread->Timer);
Thread->QueueListEntry.Flink = NULL;
Thread->QueueListEntry.Blink = NULL;
@ -291,7 +288,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->PreviousMode = KernelMode;
Thread->KernelTime = 0;
Thread->UserTime = 0;
memset(&Thread->SavedApcState, 0, sizeof(KAPC_STATE));
RtlZeroMemory(&Thread->SavedApcState, sizeof(KAPC_STATE));
Thread->ApcStateIndex = OriginalApcEnvironment;
Thread->ApcQueueable = TRUE;

View file

@ -697,6 +697,7 @@ ExpInitializeExecutive(VOID)
}
#if defined(KDBG) || defined(DBG)
KdbInit();
KdbInitProfiling2();
#endif /* KDBG */

View file

@ -120,7 +120,7 @@ NtCallbackReturn (PVOID Result,
else
{
*CallerResultLength = min(ResultLength, *CallerResultLength);
memcpy(*CallerResult, Result, *CallerResultLength);
RtlCopyMemory(*CallerResult, Result, *CallerResultLength);
}
}
@ -131,9 +131,9 @@ NtCallbackReturn (PVOID Result,
if ((Thread->Tcb.NpxState & NPX_STATE_VALID) &&
ETHREAD_TO_KTHREAD(Thread) != KeGetCurrentKPCR()->PrcbData.NpxThread)
{
memcpy((char*)InitialStack - sizeof(FX_SAVE_AREA),
(char*)Thread->Tcb.InitialStack - sizeof(FX_SAVE_AREA),
sizeof(FX_SAVE_AREA));
RtlCopyMemory((char*)InitialStack - sizeof(FX_SAVE_AREA),
(char*)Thread->Tcb.InitialStack - sizeof(FX_SAVE_AREA),
sizeof(FX_SAVE_AREA));
}
Thread->Tcb.InitialStack = InitialStack;
Thread->Tcb.StackBase = StackBase;
@ -289,11 +289,11 @@ NtW32Call (IN ULONG RoutineIndex,
AssignedStack = CONTAINING_RECORD(StackEntry, NTW32CALL_CALLBACK_STACK,
ListEntry);
NewStack = AssignedStack->BaseAddress;
memset(NewStack, 0, StackSize);
RtlZeroMemory(NewStack, StackSize);
}
/* FIXME: Need to check whether we were interrupted from v86 mode. */
memcpy((char*)NewStack + StackSize - sizeof(KTRAP_FRAME) - sizeof(FX_SAVE_AREA),
Thread->Tcb.TrapFrame, sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD)));
RtlCopyMemory((char*)NewStack + StackSize - sizeof(KTRAP_FRAME) - sizeof(FX_SAVE_AREA),
Thread->Tcb.TrapFrame, sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD)));
NewFrame = (PKTRAP_FRAME)((char*)NewStack + StackSize - sizeof(KTRAP_FRAME) - sizeof(FX_SAVE_AREA));
/* We need the stack pointer to remain 4-byte aligned */
NewFrame->Esp -= (((ArgumentLength + 3) & (~ 0x3)) + (4 * sizeof(ULONG)));
@ -303,7 +303,7 @@ NtW32Call (IN ULONG RoutineIndex,
UserEsp[1] = RoutineIndex;
UserEsp[2] = (ULONG)&UserEsp[4];
UserEsp[3] = ArgumentLength;
memcpy((PVOID)&UserEsp[4], Argument, ArgumentLength);
RtlCopyMemory((PVOID)&UserEsp[4], Argument, ArgumentLength);
/* Switch to the new environment and return to user-mode. */
KeRaiseIrql(HIGH_LEVEL, &oldIrql);
@ -319,9 +319,9 @@ NtW32Call (IN ULONG RoutineIndex,
if ((Thread->Tcb.NpxState & NPX_STATE_VALID) &&
ETHREAD_TO_KTHREAD(Thread) != KeGetCurrentKPCR()->PrcbData.NpxThread)
{
memcpy((char*)NewStack + StackSize - sizeof(FX_SAVE_AREA),
(char*)SavedState.SavedInitialStack - sizeof(FX_SAVE_AREA),
sizeof(FX_SAVE_AREA));
RtlCopyMemory((char*)NewStack + StackSize - sizeof(FX_SAVE_AREA),
(char*)SavedState.SavedInitialStack - sizeof(FX_SAVE_AREA),
sizeof(FX_SAVE_AREA));
}
Thread->Tcb.InitialStack = Thread->Tcb.StackBase = (char*)NewStack + StackSize;
Thread->Tcb.StackLimit = (ULONG)NewStack;