- Delete KD/KDBG directories.

svn path=/branches/alex-kd-branch/; revision=25823
This commit is contained in:
Alex Ionescu 2007-02-16 18:44:32 +00:00
parent 55c1c01e88
commit c9a0a6228b
18 changed files with 0 additions and 14351 deletions

View file

@ -1,267 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/kd/kdinit.c
* PURPOSE: Kernel Debugger Initializtion
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, KdInitSystem)
#endif
/* Make bochs debug output in the very early boot phase available */
//#define AUTO_ENABLE_BOCHS
/* VARIABLES ***************************************************************/
KD_PORT_INFORMATION PortInfo = {DEFAULT_DEBUG_PORT, DEFAULT_DEBUG_BAUD_RATE, 0};
ULONG KdpPortIrq;
#ifdef AUTO_ENABLE_BOCHS
KDP_DEBUG_MODE KdpDebugMode = {{{.Bochs=TRUE}}};;
#else
KDP_DEBUG_MODE KdpDebugMode;
#endif
PKDP_INIT_ROUTINE WrapperInitRoutine;
KD_DISPATCH_TABLE WrapperTable;
BOOLEAN KdpEarlyBreak = FALSE;
LIST_ENTRY KdProviders = {&KdProviders, &KdProviders};
KD_DISPATCH_TABLE DispatchTable[KdMax];
PKDP_INIT_ROUTINE InitRoutines[KdMax] = {KdpScreenInit,
KdpSerialInit,
KdpInitDebugLog,
KdpBochsInit};
/* PRIVATE FUNCTIONS *********************************************************/
PCHAR
STDCALL
KdpGetWrapperDebugMode(PCHAR Currentp2,
PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PCHAR p2 = Currentp2;
/* Check for GDB Debugging */
if (!_strnicmp(p2, "GDB", 3))
{
/* Enable it */
p2 += 3;
KdpDebugMode.Gdb = TRUE;
/* Enable Debugging */
KdDebuggerEnabled = TRUE;
KdDebuggerNotPresent = FALSE;
WrapperInitRoutine = KdpGdbStubInit;
}
/* Check for PICE Debugging */
else if (!_strnicmp(p2, "PICE", 4))
{
/* Enable it */
p2 += 4;
KdpDebugMode.Pice = TRUE;
/* Enable Debugging */
KdDebuggerEnabled = TRUE;
KdDebuggerNotPresent = FALSE;
}
#ifdef KDBG
/* Get the KDBG Settings and enable it */
KdDebuggerEnabled = TRUE;
KdDebuggerNotPresent = FALSE;
KdbpGetCommandLineSettings(LoaderBlock->LoadOptions);
#endif
return p2;
}
PCHAR
STDCALL
KdpGetDebugMode(PCHAR Currentp2)
{
PCHAR p2 = Currentp2;
ULONG Value;
/* Check for Screen Debugging */
if (!_strnicmp(p2, "SCREEN", 6))
{
/* Enable It */
p2 += 6;
KdpDebugMode.Screen = TRUE;
}
/* Check for Serial Debugging */
else if (!_strnicmp(p2, "COM", 3))
{
/* Gheck for a valid Serial Port */
p2 += 3;
Value = (ULONG)atol(p2);
if (Value > 0 && Value < 5)
{
/* Valid port found, enable Serial Debugging */
KdpDebugMode.Serial = TRUE;
/* Set the port to use */
SerialPortInfo.ComPort = Value;
KdpPort = Value;
}
}
/* Check for Debug Log Debugging */
else if (!_strnicmp(p2, "FILE", 4))
{
/* Enable It */
p2 += 4;
KdpDebugMode.File = TRUE;
}
/* Check for BOCHS Debugging */
else if (!_strnicmp(p2, "BOCHS", 5))
{
/* Enable It */
p2 += 5;
KdpDebugMode.Bochs = TRUE;
}
return p2;
}
VOID
STDCALL
KdpCallInitRoutine(ULONG BootPhase)
{
PLIST_ENTRY CurrentEntry;
PKD_DISPATCH_TABLE CurrentTable;
/* Call the registered handlers */
CurrentEntry = KdProviders.Flink;
while (CurrentEntry != &KdProviders)
{
/* Get the current table */
CurrentTable = CONTAINING_RECORD(CurrentEntry,
KD_DISPATCH_TABLE,
KdProvidersList);
/* Call it */
CurrentTable->KdpInitRoutine(CurrentTable, BootPhase);
/* Next Table */
CurrentEntry = CurrentEntry->Flink;
}
/* Call the Wrapper Init Routine */
if (WrapperInitRoutine)
WrapperTable.KdpInitRoutine(&WrapperTable, BootPhase);
}
BOOLEAN
INIT_FUNCTION
NTAPI
KdInitSystem(ULONG BootPhase,
PLOADER_PARAMETER_BLOCK LoaderBlock)
{
ULONG Value;
ULONG i;
PCHAR CommandLine, Port, BaudRate, Irq;
/* Set Default Port Options */
if (BootPhase == 0)
{
/* Get the Command Line */
CommandLine = LoaderBlock->LoadOptions;
/* Upcase it */
_strupr(CommandLine);
/* Check for settings that we support */
if (strstr(CommandLine, "BREAK")) KdpEarlyBreak = TRUE;
if (strstr(CommandLine, "NODEBUG")) KdDebuggerEnabled = FALSE;
if (strstr(CommandLine, "CRASHDEBUG")) KdDebuggerEnabled = FALSE;
if (strstr(CommandLine, "DEBUG"))
{
/* Enable on the serial port */
KdDebuggerEnabled = TRUE;
KdpDebugMode.Serial = TRUE;
}
/* Get the port and baud rate */
Port = strstr(CommandLine, "DEBUGPORT");
BaudRate = strstr(CommandLine, "BAUDRATE");
Irq = strstr(CommandLine, "IRQ");
/* Check if we got the /DEBUGPORT parameter */
if (Port)
{
/* Move past the actual string, to reach the port*/
Port += strlen("DEBUGPORT");
/* Now get past any spaces and skip the equal sign */
while (*Port == ' ') Port++;
Port++;
/* Get the debug mode and wrapper */
Port = KdpGetDebugMode(Port);
Port = KdpGetWrapperDebugMode(Port, LoaderBlock);
KdDebuggerEnabled = TRUE;
}
/* Check if we got a baud rate */
if (BaudRate)
{
/* Move past the actual string, to reach the rate */
BaudRate += strlen("BAUDRATE");
/* Now get past any spaces */
while (*BaudRate == ' ') BaudRate++;
/* And make sure we have a rate */
if (*BaudRate)
{
/* Read and set it */
Value = atol(BaudRate + 1);
if (Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value;
}
}
/* Check Serial Port Settings [IRQ] */
if (Irq)
{
/* Move past the actual string, to reach the rate */
Irq += strlen("IRQ");
/* Now get past any spaces */
while (*Irq == ' ') Irq++;
/* And make sure we have an IRQ */
if (*Irq)
{
/* Read and set it */
Value = atol(Irq + 1);
if (Value) KdpPortIrq = Value;
}
}
/* Call Providers at Phase 0 */
for (i = 0; i < KdMax; i++)
{
InitRoutines[i](&DispatchTable[i], 0);
}
/* Call Wrapper at Phase 0 */
if (WrapperInitRoutine) WrapperInitRoutine(&WrapperTable, 0);
return TRUE;
}
/* Call the Initialization Routines of the Registered Providers */
KdpCallInitRoutine(BootPhase);
/* Return success */
return TRUE;
}
/* EOF */

View file

@ -1,313 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/kd/kdio.c
* PURPOSE: NT Kernel Debugger Input/Output Functions
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#include <internal/debug.h>
/* GLOBALS *******************************************************************/
#define BufferSize 32*1024
HANDLE KdbLogFileHandle;
BOOLEAN KdpLogInitialized;
CHAR DebugBuffer[BufferSize];
ULONG CurrentPosition;
WORK_QUEUE_ITEM KdpDebugLogQueue;
BOOLEAN ItemQueued;
KD_PORT_INFORMATION SerialPortInfo = {DEFAULT_DEBUG_PORT, DEFAULT_DEBUG_BAUD_RATE, 0};
/* Current Port in use. FIXME: Do we support more then one? */
ULONG KdpPort;
/* If serial debugging is enabled, is pointing to the UART base address. */
PUCHAR *KdComPortInUse;
/* DEBUG LOG FUNCTIONS *******************************************************/
VOID
STDCALL
KdpPrintToLogInternal(PVOID Context)
{
IO_STATUS_BLOCK Iosb;
/* Write to the Debug Log */
NtWriteFile(KdbLogFileHandle,
NULL,
NULL,
NULL,
&Iosb,
DebugBuffer,
CurrentPosition,
NULL,
NULL);
/* Clear the Current Position */
CurrentPosition = 0;
/* A new item can be queued now */
ItemQueued = FALSE;
}
VOID
STDCALL
KdpPrintToLog(PCH String,
ULONG StringLength)
{
/* Don't overflow */
if ((CurrentPosition + StringLength) > BufferSize) return;
/* Add the string to the buffer */
RtlCopyMemory(&DebugBuffer[CurrentPosition], String, StringLength);
/* Update the Current Position */
CurrentPosition += StringLength;
/* Make sure we are initialized and can queue */
if (!KdpLogInitialized || (ItemQueued)) return;
/*
* Queue the work item
* Note that we don't want to queue if we are > DISPATCH_LEVEL...
* The message is in the buffer and will simply be taken care of at
* the next time we are at <= DISPATCH, so it won't be lost.
*/
if (KeGetCurrentIrql() <= DISPATCH_LEVEL)
{
ExQueueWorkItem(&KdpDebugLogQueue, HyperCriticalWorkQueue);
ItemQueued = TRUE;
}
}
VOID
STDCALL
KdpInitDebugLog(PKD_DISPATCH_TABLE DispatchTable,
ULONG BootPhase)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING FileName;
IO_STATUS_BLOCK Iosb;
if (!KdpDebugMode.File) return;
if (BootPhase == 0)
{
KdComPortInUse = NULL;
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpInitDebugLog;
DispatchTable->KdpPrintRoutine = KdpPrintToLog;
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
/* Display separator + ReactOS version at start of the debug log */
DPRINT1("---------------------------------------------------------------\n");
DPRINT1("ReactOS "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n");
}
else if (BootPhase == 2)
{
HalDisplayString("\n File log debugging enabled\n\n");
}
else if (BootPhase == 3)
{
/* Setup the Log Name */
RtlInitUnicodeString(&FileName, L"\\SystemRoot\\debug.log");
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
0,
NULL,
NULL);
/* Create the Log File */
Status = NtCreateFile(&KdbLogFileHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&Iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_SUPERSEDE,
FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
/* Allow it to be used */
ExInitializeWorkItem(&KdpDebugLogQueue, &KdpPrintToLogInternal, NULL);
KdpLogInitialized = TRUE;
}
}
/* SERIAL FUNCTIONS **********************************************************/
VOID
STDCALL
KdpSerialDebugPrint(LPSTR Message,
ULONG Length)
{
PCHAR pch = (PCHAR) Message;
while (*pch != 0)
{
if (*pch == '\n')
{
KdPortPutByteEx(&SerialPortInfo, '\r');
}
KdPortPutByteEx(&SerialPortInfo, *pch);
pch++;
}
}
VOID
STDCALL
KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable,
ULONG BootPhase)
{
if (!KdpDebugMode.Serial) return;
if (BootPhase == 0)
{
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpSerialInit;
DispatchTable->KdpPrintRoutine = KdpSerialDebugPrint;
/* Initialize the Port */
if (!KdPortInitializeEx(&SerialPortInfo, 0, 0))
{
KdpDebugMode.Serial = FALSE;
return;
}
KdComPortInUse = (PUCHAR*)&SerialPortInfo.BaseAddress;
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
/* Display separator + ReactOS version at start of the debug log */
DPRINT1("-----------------------------------------------------\n");
DPRINT1("ReactOS "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n");
DPRINT1("Command Line: %s\n", KeLoaderBlock->LoadOptions);
DPRINT1("ARC Paths: %s %s %s %s\n", KeLoaderBlock->ArcBootDeviceName,
KeLoaderBlock->NtHalPathName,
KeLoaderBlock->ArcHalDeviceName,
KeLoaderBlock->NtBootPathName);
}
else if (BootPhase == 2)
{
HalDisplayString("\n Serial debugging enabled\n\n");
}
}
/* SCREEN FUNCTIONS **********************************************************/
VOID
STDCALL
KdpScreenPrint(LPSTR Message,
ULONG Length)
{
/* Call HAL */
HalDisplayString(Message);
}
VOID
STDCALL
KdpScreenInit(PKD_DISPATCH_TABLE DispatchTable,
ULONG BootPhase)
{
if (!KdpDebugMode.Screen) return;
if (BootPhase == 0)
{
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpScreenInit;
DispatchTable->KdpPrintRoutine = KdpScreenPrint;
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
}
else if (BootPhase == 2)
{
HalDisplayString("\n Screen debugging enabled\n\n");
}
}
/* GENERAL FUNCTIONS *********************************************************/
BOOLEAN
STDCALL
KdpDetectConflicts(PCM_RESOURCE_LIST DriverList)
{
ULONG ComPortBase = 0;
ULONG i;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
/* Select the COM Port Base */
switch (KdpPort)
{
case 1: ComPortBase = 0x3f8; break;
case 2: ComPortBase = 0x2f8; break;
case 3: ComPortBase = 0x3e8; break;
case 4: ComPortBase = 0x2e8; break;
}
/* search for this port address in DriverList */
for (i = 0; i < DriverList->List[0].PartialResourceList.Count; i++)
{
ResourceDescriptor = &DriverList->List[0].PartialResourceList.PartialDescriptors[i];
if (ResourceDescriptor->Type == CmResourceTypePort)
{
if ((ResourceDescriptor->u.Port.Start.u.LowPart <= ComPortBase) &&
(ResourceDescriptor->u.Port.Start.u.LowPart +
ResourceDescriptor->u.Port.Length > ComPortBase))
{
/* Conflict found */
return TRUE;
}
}
}
/* No Conflicts */
return FALSE;
}
ULONG
STDCALL
KdpPrintString(LPSTR String,
ULONG Length)
{
PLIST_ENTRY CurrentEntry;
PKD_DISPATCH_TABLE CurrentTable;
if (!KdpDebugMode.Value) return 0;
/* Call the registered handlers */
CurrentEntry = KdProviders.Flink;
while (CurrentEntry != &KdProviders)
{
/* Get the current table */
CurrentTable = CONTAINING_RECORD(CurrentEntry,
KD_DISPATCH_TABLE,
KdProvidersList);
/* Call it */
CurrentTable->KdpPrintRoutine(String, Length);
/* Next Table */
CurrentEntry = CurrentEntry->Flink;
}
/* Call the Wrapper Routine */
if (WrapperInitRoutine) WrapperTable.KdpPrintRoutine(String, Length);
/* Return the Length */
return Length;
}
/* EOF */

View file

@ -1,313 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/kd/kdinit.c
* PURPOSE: Kernel Debugger Initializtion
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* VARIABLES ***************************************************************/
BOOLEAN KdDebuggerEnabled = FALSE;
BOOLEAN KdEnteredDebugger = FALSE;
BOOLEAN KdDebuggerNotPresent = TRUE;
BOOLEAN KiEnableTimerWatchdog = FALSE;
BOOLEAN KdBreakAfterSymbolLoad = FALSE;
ULONG KiBugCheckData;
BOOLEAN KdpBreakPending;
VOID STDCALL PspDumpThreads(BOOLEAN SystemThreads);
typedef struct
{
ULONG ComponentId;
ULONG Level;
} KD_COMPONENT_DATA;
#define MAX_KD_COMPONENT_TABLE_ENTRIES 128
KD_COMPONENT_DATA KdComponentTable[MAX_KD_COMPONENT_TABLE_ENTRIES];
ULONG KdComponentTableEntries = 0;
/* PRIVATE FUNCTIONS *********************************************************/
ULONG
STDCALL
KdpServiceDispatcher(ULONG Service,
PVOID Buffer1,
ULONG Buffer1Length)
{
ULONG Result = 0;
switch (Service)
{
case BREAKPOINT_PRINT: /* DbgPrint */
Result = KdpPrintString(Buffer1, Buffer1Length);
break;
#ifdef DBG
case TAG('R', 'o', 's', ' '): /* ROS-INTERNAL */
{
switch ((ULONG)Buffer1)
{
case DumpNonPagedPool:
MiDebugDumpNonPagedPool(FALSE);
break;
case ManualBugCheck:
KEBUGCHECK(MANUALLY_INITIATED_CRASH);
break;
case DumpNonPagedPoolStats:
MiDebugDumpNonPagedPoolStats(FALSE);
break;
case DumpNewNonPagedPool:
MiDebugDumpNonPagedPool(TRUE);
break;
case DumpNewNonPagedPoolStats:
MiDebugDumpNonPagedPoolStats(TRUE);
break;
case DumpAllThreads:
PspDumpThreads(TRUE);
break;
case DumpUserThreads:
PspDumpThreads(FALSE);
break;
case EnterDebugger:
DbgBreakPoint();
break;
default:
break;
}
}
#endif
default:
HalDisplayString ("Invalid debug service call!\n");
break;
}
return Result;
}
BOOLEAN
NTAPI
KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context,
IN KPROCESSOR_MODE PreviousMode,
IN BOOLEAN SecondChance)
{
KD_CONTINUE_TYPE Return;
/* HACK (just like all this routine */
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) Context->Eip++;
/* Get out of here if the Debugger isn't connected */
if (KdDebuggerNotPresent) return FALSE;
/* Call KDBG if available */
Return = KdbEnterDebuggerException(ExceptionRecord,
PreviousMode,
Context,
TrapFrame,
!SecondChance);
/* Convert return to BOOLEAN */
if (Return == kdContinue) return TRUE;
return FALSE;
}
BOOLEAN
NTAPI
KdpCallGdb(IN PKTRAP_FRAME TrapFrame,
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context)
{
KD_CONTINUE_TYPE Return = kdDoNotHandleException;
/* Get out of here if the Debugger isn't connected */
if (KdDebuggerNotPresent) return FALSE;
/* FIXME:
* Right now, the GDB wrapper seems to handle exceptions differntly
* from KDGB and both are called at different times, while the GDB
* one is only called once and that's it. I don't really have the knowledge
* to fix the GDB stub, so until then, we'll be using this hack
*/
if (WrapperInitRoutine)
{
Return = WrapperTable.KdpExceptionRoutine(ExceptionRecord,
Context,
TrapFrame);
}
/* Convert return to BOOLEAN */
if (Return == kdContinue) return TRUE;
return FALSE;
}
/* PUBLIC FUNCTIONS *********************************************************/
/*
* @implemented
*/
NTSTATUS
STDCALL
KdDisableDebugger(VOID)
{
KIRQL OldIrql;
/* Raise IRQL */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
/* TODO: Disable any breakpoints */
/* Disable the Debugger */
KdDebuggerEnabled = FALSE;
/* Lower the IRQL */
KeLowerIrql(OldIrql);
/* Return success */
return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS
STDCALL
KdEnableDebugger(VOID)
{
KIRQL OldIrql;
/* Raise IRQL */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
/* TODO: Re-enable any breakpoints */
/* Enable the Debugger */
KdDebuggerEnabled = TRUE;
/* Lower the IRQL */
KeLowerIrql(OldIrql);
/* Return success */
return STATUS_SUCCESS;
}
/*
* @implemented
*/
BOOLEAN
STDCALL
KdPollBreakIn(VOID)
{
return KdpBreakPending;
}
/*
* @implemented
*/
VOID
STDCALL
KeEnterKernelDebugger(VOID)
{
HalDisplayString("\n\n *** Entered kernel debugger ***\n");
/* Set the Variable */
KdEnteredDebugger = TRUE;
/* Halt the CPU */
for (;;) Ke386HaltProcessor();
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
KdPowerTransition(ULONG PowerState)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
*/
VOID
STDCALL
KdChangeOption(IN KD_OPTION Option,
IN ULONG InBufferLength OPTIONAL,
IN PVOID InBuffer,
IN ULONG OutBufferLength OPTIONAL,
OUT PVOID OutBuffer,
OUT PULONG OutBufferRequiredLength OPTIONAL)
{
UNIMPLEMENTED;
}
NTSTATUS
STDCALL
NtQueryDebugFilterState(IN ULONG ComponentId,
IN ULONG Level)
{
unsigned int i;
/* convert Level to mask if it isn't already one */
if ( Level < 32 )
Level = 1 << Level;
for ( i = 0; i < KdComponentTableEntries; i++ )
{
if ( ComponentId == KdComponentTable[i].ComponentId )
{
if ( Level & KdComponentTable[i].Level )
return TRUE;
break;
}
}
return FALSE;
}
NTSTATUS
STDCALL
NtSetDebugFilterState(IN ULONG ComponentId,
IN ULONG Level,
IN BOOLEAN State)
{
unsigned int i;
for ( i = 0; i < KdComponentTableEntries; i++ )
{
if ( ComponentId == KdComponentTable[i].ComponentId )
break;
}
if ( i == KdComponentTableEntries )
{
if ( i == MAX_KD_COMPONENT_TABLE_ENTRIES )
return STATUS_INVALID_PARAMETER_1;
++KdComponentTableEntries;
KdComponentTable[i].ComponentId = ComponentId;
KdComponentTable[i].Level = 0;
}
if ( State )
KdComponentTable[i].Level |= Level;
else
KdComponentTable[i].Level &= ~Level;
return STATUS_SUCCESS;
}
PKDEBUG_ROUTINE KiDebugRoutine = KdpEnterDebuggerException;
/* EOF */

View file

@ -1,67 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/kd/wrappers/bochs.c
* PURPOSE: BOCHS Wrapper for Kd
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* bochs debug output */
#define BOCHS_LOGGER_PORT (0xe9)
/* FUNCTIONS *****************************************************************/
VOID
STDCALL
KdpBochsDebugPrint(IN PCH Message,
IN ULONG Length)
{
if (!KdpDebugMode.Bochs) return;
while (*Message != 0)
{
if (*Message == '\n')
{
__outbyte(BOCHS_LOGGER_PORT, '\r');
}
__outbyte(BOCHS_LOGGER_PORT, *Message);
Message++;
}
}
VOID
STDCALL
KdpBochsInit(PKD_DISPATCH_TABLE DispatchTable,
ULONG BootPhase)
{
UCHAR Value;
if (!KdpDebugMode.Bochs) return;
if (BootPhase == 0)
{
Value = __inbyte(BOCHS_LOGGER_PORT);
if (Value != BOCHS_LOGGER_PORT)
{
KdpDebugMode.Bochs = FALSE;
return;
}
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpBochsInit;
DispatchTable->KdpPrintRoutine = KdpBochsDebugPrint;
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
}
else if (BootPhase == 2)
{
HalDisplayString("\n Bochs debugging enabled\n\n");
}
}
/* EOF */

File diff suppressed because it is too large Load diff

View file

@ -1,331 +0,0 @@
/* Interface between the opcode library and its callers.
Copyright 2001, 2002 Free Software Foundation, Inc.
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, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Written by Cygnus Support, 1993.
The opcode library (libopcodes.a) provides instruction decoders for
a large variety of instruction sets, callable with an identical
interface, for making instruction-processing programs more independent
of the instruction set being processed. */
#ifndef DIS_ASM_H
#define DIS_ASM_H
#ifdef __cplusplus
extern "C" {
#endif
#if 0
/* #include <stdio.h> */
/* #include "bfd.h" */
#endif
typedef int (*fprintf_ftype) PARAMS((PTR, const char*, ...));
enum dis_insn_type {
dis_noninsn, /* Not a valid instruction */
dis_nonbranch, /* Not a branch instruction */
dis_branch, /* Unconditional branch */
dis_condbranch, /* Conditional branch */
dis_jsr, /* Jump to subroutine */
dis_condjsr, /* Conditional jump to subroutine */
dis_dref, /* Data reference instruction */
dis_dref2 /* Two data references in instruction */
};
/* This struct is passed into the instruction decoding routine,
and is passed back out into each callback. The various fields are used
for conveying information from your main routine into your callbacks,
for passing information into the instruction decoders (such as the
addresses of the callback functions), or for passing information
back from the instruction decoders to their callers.
It must be initialized before it is first passed; this can be done
by hand, or using one of the initialization macros below. */
typedef struct disassemble_info {
fprintf_ftype fprintf_func;
PTR stream;
PTR application_data;
/* Target description. We could replace this with a pointer to the bfd,
but that would require one. There currently isn't any such requirement
so to avoid introducing one we record these explicitly. */
/* The bfd_flavour. This can be bfd_target_unknown_flavour. */
enum bfd_flavour flavour;
/* The bfd_arch value. */
enum bfd_architecture arch;
/* The bfd_mach value. */
unsigned long mach;
#if 0
enum bfd_endian endian;
#endif
/* An arch/mach-specific bitmask of selected instruction subsets, mainly
for processors with run-time-switchable instruction sets. The default,
zero, means that there is no constraint. CGEN-based opcodes ports
may use ISA_foo masks. */
unsigned long insn_sets;
#if 0
/* Some targets need information about the current section to accurately
display insns. If this is NULL, the target disassembler function
will have to make its best guess. */
asection *section;
/* An array of pointers to symbols either at the location being disassembled
or at the start of the function being disassembled. The array is sorted
so that the first symbol is intended to be the one used. The others are
present for any misc. purposes. This is not set reliably, but if it is
not NULL, it is correct. */
asymbol **symbols;
/* Number of symbols in array. */
int num_symbols;
#endif
/* For use by the disassembler.
The top 16 bits are reserved for public use (and are documented here).
The bottom 16 bits are for the internal use of the disassembler. */
unsigned long flags;
#define INSN_HAS_RELOC 0x80000000
PTR private_data;
/* Function used to get bytes to disassemble. MEMADDR is the
address of the stuff to be disassembled, MYADDR is the address to
put the bytes in, and LENGTH is the number of bytes to read.
INFO is a pointer to this struct.
Returns an errno value or 0 for success. */
int (*read_memory_func)
PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
struct disassemble_info *info));
/* Function which should be called if we get an error that we can't
recover from. STATUS is the errno value from read_memory_func and
MEMADDR is the address that we were trying to read. INFO is a
pointer to this struct. */
void (*memory_error_func)
PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
/* Function called to print ADDR. */
void (*print_address_func)
PARAMS ((bfd_vma addr, struct disassemble_info *info));
/* Function called to determine if there is a symbol at the given ADDR.
If there is, the function returns 1, otherwise it returns 0.
This is used by ports which support an overlay manager where
the overlay number is held in the top part of an address. In
some circumstances we want to include the overlay number in the
address, (normally because there is a symbol associated with
that address), but sometimes we want to mask out the overlay bits. */
int (* symbol_at_address_func)
PARAMS ((bfd_vma addr, struct disassemble_info * info));
/* These are for buffer_read_memory. */
bfd_byte *buffer;
bfd_vma buffer_vma;
unsigned int buffer_length;
/* This variable may be set by the instruction decoder. It suggests
the number of bytes objdump should display on a single line. If
the instruction decoder sets this, it should always set it to
the same value in order to get reasonable looking output. */
int bytes_per_line;
/* the next two variables control the way objdump displays the raw data */
/* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
/* output will look like this:
00: 00000000 00000000
with the chunks displayed according to "display_endian". */
int bytes_per_chunk;
enum bfd_endian display_endian;
/* Number of octets per incremented target address
Normally one, but some DSPs have byte sizes of 16 or 32 bits. */
unsigned int octets_per_byte;
/* Results from instruction decoders. Not all decoders yet support
this information. This info is set each time an instruction is
decoded, and is only valid for the last such instruction.
To determine whether this decoder supports this information, set
insn_info_valid to 0, decode an instruction, then check it. */
char insn_info_valid; /* Branch info has been set. */
char branch_delay_insns; /* How many sequential insn's will run before
a branch takes effect. (0 = normal) */
char data_size; /* Size of data reference in insn, in bytes */
enum dis_insn_type insn_type; /* Type of instruction */
bfd_vma target; /* Target address of branch or dref, if known;
zero if unknown. */
bfd_vma target2; /* Second target address for dref2 */
/* Command line options specific to the target disassembler. */
char * disassembler_options;
} disassemble_info;
/* Standard disassemblers. Disassemble one instruction at the given
target address. Return number of octets processed. */
typedef int (*disassembler_ftype)
PARAMS((bfd_vma, disassemble_info *));
extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info *));
extern int print_insn_i386_att PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_i386_intel PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_ia64 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_i370 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_m68hc11 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_m68hc12 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_h8300s PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_big_arm PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_little_arm PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_avr PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_d10v PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_d30v PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_dlx PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_fr30 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_i860 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_ip2k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_m32r PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_mcore PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_mmix PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_mn10200 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_mn10300 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_msp430 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_openrisc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_big_or32 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_little_or32 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_pdp11 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_pj PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_s390 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_tic4x PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_tic54x PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_tic80 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_vax PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_w65 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_xstormy16 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_sh64 PARAMS ((bfd_vma, disassemble_info *));
extern int print_insn_sh64x_media PARAMS ((bfd_vma, disassemble_info *));
extern int print_insn_frv PARAMS ((bfd_vma, disassemble_info *));
extern int print_insn_iq2000 PARAMS ((bfd_vma, disassemble_info *));
extern disassembler_ftype arc_get_disassembler PARAMS ((void *));
extern disassembler_ftype cris_get_disassembler PARAMS ((bfd *));
extern void print_mips_disassembler_options PARAMS ((FILE *));
extern void print_ppc_disassembler_options PARAMS ((FILE *));
extern void print_arm_disassembler_options PARAMS ((FILE *));
extern void parse_arm_disassembler_option PARAMS ((char *));
extern int get_arm_regname_num_options PARAMS ((void));
extern int set_arm_regname_option PARAMS ((int));
extern int get_arm_regnames PARAMS ((int, const char **, const char **, const char ***));
/* Fetch the disassembler for a given BFD, if that support is available. */
extern disassembler_ftype disassembler PARAMS ((bfd *));
/* Document any target specific options available from the disassembler. */
extern void disassembler_usage PARAMS ((FILE *));
/* This block of definitions is for particular callers who read instructions
into a buffer before calling the instruction decoder. */
/* Here is a function which callers may wish to use for read_memory_func.
It gets bytes from a buffer. */
extern int buffer_read_memory
PARAMS ((bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *));
/* This function goes with buffer_read_memory.
It prints a message using info->fprintf_func and info->stream. */
extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
/* Just print the address in hex. This is included for completeness even
though both GDB and objdump provide their own (to print symbolic
addresses). */
extern void generic_print_address
PARAMS ((bfd_vma, struct disassemble_info *));
/* Always true. */
extern int generic_symbol_at_address
PARAMS ((bfd_vma, struct disassemble_info *));
/* Macro to initialize a disassemble_info struct. This should be called
by all applications creating such a struct. */
#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
(INFO).flavour = bfd_target_unknown_flavour, \
(INFO).arch = bfd_arch_unknown, \
(INFO).mach = 0, \
(INFO).insn_sets = 0, \
(INFO).endian = BFD_ENDIAN_UNKNOWN, \
(INFO).octets_per_byte = 1, \
INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC)
/* Call this macro to initialize only the internal variables for the
disassembler. Architecture dependent things such as byte order, or machine
variant are not touched by this macro. This makes things much easier for
GDB which must initialize these things separately. */
#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \
(INFO).fprintf_func = (fprintf_ftype)(FPRINTF_FUNC), \
(INFO).stream = (PTR)(STREAM), \
(INFO).section = NULL, \
(INFO).symbols = NULL, \
(INFO).num_symbols = 0, \
(INFO).private_data = NULL, \
(INFO).buffer = NULL, \
(INFO).buffer_vma = 0, \
(INFO).buffer_length = 0, \
(INFO).read_memory_func = buffer_read_memory, \
(INFO).memory_error_func = perror_memory, \
(INFO).print_address_func = generic_print_address, \
(INFO).symbol_at_address_func = generic_symbol_at_address, \
(INFO).flags = 0, \
(INFO).bytes_per_line = 0, \
(INFO).bytes_per_chunk = 0, \
(INFO).display_endian = BFD_ENDIAN_UNKNOWN, \
(INFO).disassembler_options = NULL, \
(INFO).insn_info_valid = 0
#ifdef __cplusplus
}
#endif
#endif /* ! defined (DIS_ASM_H) */

File diff suppressed because it is too large Load diff

View file

@ -1,139 +0,0 @@
#include <ndk/asm.h>
.text
.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 */
/*
* 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
/*
* Pop the arguments and unused portions of the trap frame:
* DebugEbp
* DebugEip
* DebugArgMark
* DebugPointer
* TempSegSs
* TempEsp
*/
addl $(11*4), %esp
/*
* 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
/*
* 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 */
/* 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

@ -1,70 +0,0 @@
.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

@ -1,61 +0,0 @@
.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
.globl __setjmp
_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

File diff suppressed because it is too large Load diff

View file

@ -1,274 +0,0 @@
#ifndef NTOSKRNL_KDB_H
#define NTOSKRNL_KDB_H
/* DEFINES *******************************************************************/
#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;
/* These values MUST be nonzero. They're used as bit masks. */
typedef enum _KDB_OUTPUT_SETTINGS
{
KD_DEBUG_KDSERIAL = 1,
KD_DEBUG_KDNOECHO = 2
} KDB_OUTPUT_SETTINGS;
/* FUNCTIONS *****************************************************************/
/* from i386/i386-dis.c */
LONG
KdbpDisassemble(
IN ULONG Address,
IN ULONG IntelSyntax);
LONG
KdbpGetInstLength(
IN ULONG Address);
/* from i386/kdb_help.S */
VOID STDCALL
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
KdbpSymFindModuleByAddress(IN PVOID Address,
OUT PKDB_MODULE_INFO pInfo);
BOOLEAN
KdbpSymFindModuleByName(IN LPCWSTR Name,
OUT PKDB_MODULE_INFO pInfo);
BOOLEAN
KdbpSymFindModuleByIndex(IN INT Index,
OUT PKDB_MODULE_INFO pInfo);
/* from kdb.c */
extern PEPROCESS KdbCurrentProcess;
extern PETHREAD KdbCurrentThread;
extern LONG KdbLastBreakPointNr;
extern ULONG KdbNumSingleSteps;
extern BOOLEAN KdbSingleStepOver;
extern PKDB_KTRAP_FRAME KdbCurrentTrapFrame;
extern ULONG KdbDebugState;
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);
VOID
STDCALL
KdbpGetCommandLineSettings(PCHAR p1);
KD_CONTINUE_TYPE
KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
KPROCESSOR_MODE PreviousMode,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame,
BOOLEAN FirstChance);
/* other functions */
NTSTATUS
KdbpSafeReadMemory(OUT PVOID Dest,
IN PVOID Src,
IN ULONG Bytes);
NTSTATUS
KdbpSafeWriteMemory(OUT PVOID Dest,
IN PVOID Src,
IN ULONG Bytes);
#define KdbpGetCharKeyboard(ScanCode) KdbpTryGetCharKeyboard(ScanCode, 0)
CHAR
KdbpTryGetCharKeyboard(PULONG ScanCode, UINT Retry);
#define KdbpGetCharSerial() KdbpTryGetCharSerial(0)
CHAR
KdbpTryGetCharSerial(UINT Retry);
VOID
KdbEnter(VOID);
VOID
DbgRDebugInit(VOID);
VOID
DbgShowFiles(VOID);
VOID
DbgEnableFile(PCH Filename);
VOID
DbgDisableFile(PCH Filename);
VOID
KbdDisableMouse();
VOID
KbdEnableMouse();
#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,353 +0,0 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb_keyboard.c
* PURPOSE: Keyboard driver
*
* PROGRAMMERS: Victor Kirhenshtein (sauros@iname.com)
* Jason Filby (jasonfilby@yahoo.com)
*/
/* INCLUDES ****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#if 1
#define KBD_STATUS_REG 0x64
#define KBD_CNTL_REG 0x64
#define KBD_DATA_REG 0x60
#define KBD_DISABLE_MOUSE 0xA7
#define KBD_ENABLE_MOUSE 0xA8
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
#define kbd_write_command(cmd) WRITE_PORT_UCHAR((PUCHAR)KBD_STATUS_REG,cmd)
#define kbd_read_input() READ_PORT_UCHAR((PUCHAR)KBD_DATA_REG)
#define kbd_read_status() READ_PORT_UCHAR((PUCHAR)KBD_STATUS_REG)
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 */
};
typedef BYTE byte_t;
VOID KbdEnableMouse()
{
kbd_write_command(KBD_ENABLE_MOUSE);
}
VOID KbdDisableMouse()
{
kbd_write_command(KBD_DISABLE_MOUSE);
}
CHAR
KdbpTryGetCharKeyboard(PULONG ScanCode, UINT Retry)
{
static byte_t last_key = 0;
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;
}
}
}
return -1;
}
#endif
#if 0
/* GLOBALS *******************************************************************/
/*
* Keyboard I/O ports.
*/
#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
#define K_STATUS 0x64 /* keybd status (read-only) */
#define K_CMD 0x64 /* keybd ctlr command (write-only) */
/*
* Bit definitions for K_STATUS port.
*/
#define K_OBUF_FUL 0x01 /* output (from keybd) buffer full */
#define K_IBUF_FUL 0x02 /* input (to keybd) buffer full */
#define K_SYSFLAG 0x04 /* "System Flag" */
#define K_CMD_DATA 0x08 /* 1 = input buf has cmd, 0 = data */
#define K_KBD_INHIBIT 0x10 /* 0 if keyboard inhibited */
#define K_AUX_OBUF_FUL 0x20 /* 1 = obuf holds aux device data */
#define K_TIMEOUT 0x40 /* timout error flag */
#define K_PARITY_ERROR 0x80 /* parity error flag */
/*
* Keyboard controller commands (sent to K_CMD port).
*/
#define KC_CMD_READ 0x20 /* read controller command byte */
#define KC_CMD_WRITE 0x60 /* write controller command byte */
#define KC_CMD_DIS_AUX 0xa7 /* disable auxiliary device */
#define KC_CMD_ENB_AUX 0xa8 /* enable auxiliary device */
#define KC_CMD_TEST_AUX 0xa9 /* test auxiliary device interface */
#define KC_CMD_SELFTEST 0xaa /* keyboard controller self-test */
#define KC_CMD_TEST 0xab /* test keyboard interface */
#define KC_CMD_DUMP 0xac /* diagnostic dump */
#define KC_CMD_DISABLE 0xad /* disable keyboard */
#define KC_CMD_ENABLE 0xae /* enable keyboard */
#define KC_CMD_RDKBD 0xc4 /* read keyboard ID */
#define KC_CMD_WIN 0xd0 /* read output port */
#define KC_CMD_WOUT 0xd1 /* write output port */
#define KC_CMD_ECHO 0xee /* used for diagnostic testing */
#define KC_CMD_PULSE 0xff /* pulse bits 3-0 based on low nybble */
/*
* Keyboard commands (send to K_RDWR).
*/
#define K_CMD_LEDS 0xed /* set status LEDs (caps lock, etc.) */
#define K_CMD_TYPEMATIC 0xf3 /* set key repeat and delay */
/*
* Bit definitions for controller command byte (sent following
* KC_CMD_WRITE command).
*
* Bits 0x02 and 0x80 unused, always set to 0.
*/
#define K_CB_ENBLIRQ 0x01 /* enable data-ready intrpt */
#define K_CB_SETSYSF 0x04 /* Set System Flag */
#define K_CB_INHBOVR 0x08 /* Inhibit Override */
#define K_CB_DISBLE 0x10 /* disable keyboard */
#define K_CB_IGNPARITY 0x20 /* ignore parity from keyboard */
#define K_CB_SCAN 0x40 /* standard scan conversion */
/*
* Bit definitions for "Indicator Status Byte" (sent after a
* K_CMD_LEDS command). If the bit is on, the LED is on. Undefined
* bit positions must be 0.
*/
#define K_LED_SCRLLK 0x1 /* scroll lock */
#define K_LED_NUMLK 0x2 /* num lock */
#define K_LED_CAPSLK 0x4 /* caps lock */
/*
* Bit definitions for "Miscellaneous port B" (K_PORTB).
*/
/* read/write */
#define K_ENABLETMR2 0x01 /* enable output from timer 2 */
#define K_SPKRDATA 0x02 /* direct input to speaker */
#define K_ENABLEPRTB 0x04 /* "enable" port B */
#define K_EIOPRTB 0x08 /* enable NMI on parity error */
/* read-only */
#define K_REFRESHB 0x10 /* refresh flag from INLTCONT PAL */
#define K_OUT2B 0x20 /* timer 2 output */
#define K_ICKB 0x40 /* I/O channel check (parity error) */
/*
* Bit definitions for the keyboard controller's output port.
*/
#define KO_SYSRESET 0x01 /* processor reset */
#define KO_GATE20 0x02 /* A20 address line enable */
#define KO_AUX_DATA_OUT 0x04 /* output data to auxiliary device */
#define KO_AUX_CLOCK 0x08 /* auxiliary device clock */
#define KO_OBUF_FUL 0x10 /* keyboard output buffer full */
#define KO_AUX_OBUF_FUL 0x20 /* aux device output buffer full */
#define KO_CLOCK 0x40 /* keyboard clock */
#define KO_DATA_OUT 0x80 /* output data to keyboard */
/*
* Keyboard return codes.
*/
#define K_RET_RESET_DONE 0xaa /* BAT complete */
#define K_RET_ECHO 0xee /* echo after echo command */
#define K_RET_ACK 0xfa /* ack */
#define K_RET_RESET_FAIL 0xfc /* BAT error */
#define K_RET_RESEND 0xfe /* resend request */
#define SHIFT -1
#define CTRL -2
#define META -3
static char keymap[128][2] = {
{0}, /* 0 */
{27, 27}, /* 1 - ESC */
{'1', '!'}, /* 2 */
{'2', '@'},
{'3', '#'},
{'4', '$'},
{'5', '%'},
{'6', '^'},
{'7', '&'},
{'8', '*'},
{'9', '('},
{'0', ')'},
{'-', '_'},
{'=', '+'},
{8, 8}, /* 14 - Backspace */
{'\t', '\t'}, /* 15 */
{'q', 'Q'},
{'w', 'W'},
{'e', 'E'},
{'r', 'R'},
{'t', 'T'},
{'y', 'Y'},
{'u', 'U'},
{'i', 'I'},
{'o', 'O'},
{'p', 'P'},
{'[', '{'},
{']', '}'}, /* 27 */
{'\r', '\r'}, /* 28 - Enter */
{CTRL, CTRL}, /* 29 - Ctrl */
{'a', 'A'}, /* 30 */
{'s', 'S'},
{'d', 'D'},
{'f', 'F'},
{'g', 'G'},
{'h', 'H'},
{'j', 'J'},
{'k', 'K'},
{'l', 'L'},
{';', ':'},
{'\'', '"'}, /* 40 */
{'`', '~'}, /* 41 */
{SHIFT, SHIFT}, /* 42 - Left Shift */
{'\\', '|'}, /* 43 */
{'z', 'Z'}, /* 44 */
{'x', 'X'},
{'c', 'C'},
{'v', 'V'},
{'b', 'B'},
{'n', 'N'},
{'m', 'M'},
{',', '<'},
{'.', '>'},
{'/', '?'}, /* 53 */
{SHIFT, SHIFT}, /* 54 - Right Shift */
{0, 0}, /* 55 - Print Screen */
{META, META}, /* 56 - Alt */
{' ', ' '}, /* 57 - Space bar */
{0, 0}, /* 58 - Caps Lock */
{0, 0}, /* 59 - F1 */
{0, 0}, /* 60 - F2 */
{0, 0}, /* 61 - F3 */
{0, 0}, /* 62 - F4 */
{0, 0}, /* 63 - F5 */
{0, 0}, /* 64 - F6 */
{0, 0}, /* 65 - F7 */
{0, 0}, /* 66 - F8 */
{0, 0}, /* 67 - F9 */
{0, 0}, /* 68 - F10 */
{0, 0}, /* 69 - Num Lock */
{0, 0}, /* 70 - Scroll Lock */
{'7', '7'}, /* 71 - Numeric keypad 7 */
{'8', '8'}, /* 72 - Numeric keypad 8 */
{'9', '9'}, /* 73 - Numeric keypad 9 */
{'-', '-'}, /* 74 - Numeric keypad '-' */
{'4', '4'}, /* 75 - Numeric keypad 4 */
{'5', '5'}, /* 76 - Numeric keypad 5 */
{'6', '6'}, /* 77 - Numeric keypad 6 */
{'+', '+'}, /* 78 - Numeric keypad '+' */
{'1', '1'}, /* 79 - Numeric keypad 1 */
{'2', '2'}, /* 80 - Numeric keypad 2 */
{'3', '3'}, /* 81 - Numeric keypad 3 */
{'0', '0'}, /* 82 - Numeric keypad 0 */
{'.', '.'}, /* 83 - Numeric keypad '.' */
};
/* FUNCTIONS *****************************************************************/
/*
* Quick poll for a pending input character.
* Returns a character if available, -1 otherwise. This routine can return
* false negatives in the following cases:
*
* - a valid character is in transit from the keyboard when called
* - a key release is received (from a previous key press)
* - a SHIFT key press is received (shift state is recorded however)
* - a key press for a multi-character sequence is received
*
* Yes, this is horrible.
*/
ULONG
KdbpTryGetCharKeyboard(VOID)
{
static unsigned shift_state, ctrl_state, meta_state;
unsigned scan_code, ch;
/* See if a scan code is ready, returning if none. */
if ((READ_PORT_UCHAR((PUCHAR)K_STATUS) & K_OBUF_FUL) == 0) {
return -1;
}
scan_code = READ_PORT_UCHAR((PUCHAR)K_RDWR);
/* Handle key releases - only release of SHIFT is important. */
if (scan_code & 0x80) {
scan_code &= 0x7f;
if (keymap[scan_code][0] == SHIFT)
shift_state = 0;
else if (keymap[scan_code][0] == CTRL)
ctrl_state = 0;
else if (keymap[scan_code][0] == META)
meta_state = 0;
ch = -1;
} else {
/* Translate the character through the keymap. */
ch = keymap[scan_code][shift_state] | meta_state;
if (ch == SHIFT) {
shift_state = 1;
ch = -1;
} else if (ch == CTRL) {
ctrl_state = 1;
ch = -1;
} else if (ch == META) {
meta_state = 0200;
ch = -1;
} else if (ch == 0)
ch = -1;
else if (ctrl_state)
ch = (keymap[scan_code][1] - '@') | meta_state;
}
return ch;
}
#endif

View file

@ -1,30 +0,0 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb_serial.c
* PURPOSE: Serial driver
*
* PROGRAMMERS: Victor Kirhenshtein (sauros@iname.com)
* Jason Filby (jasonfilby@yahoo.com)
* arty
*/
/* INCLUDES ****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
CHAR
KdbpTryGetCharSerial(UINT Retry)
{
CHAR Result = -1;
if (Retry == 0)
while (!KdPortGetByteEx(&SerialPortInfo, (PUCHAR)&Result));
else
while (!KdPortGetByteEx(&SerialPortInfo, (PUCHAR)&Result) && Retry-- > 0);
return Result;
}

View file

@ -1,124 +0,0 @@
/*
* 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>
#include <ctype.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)0xffffffff / (unsigned long)base;
cutlim = (unsigned long)0xffffffff % (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 = 0xffffffff;
}
else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = any ? (char *)((size_t)(s - 1)) : (char *)((size_t)nptr);
return acc;
}

View file

@ -1,749 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb_symbols.c
* PURPOSE: Getting symbol information...
*
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* 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;
static BOOLEAN LoadSymbols;
static LIST_ENTRY SymbolFileListHead;
static KSPIN_LOCK SymbolFileListLock;
/* FUNCTIONS ****************************************************************/
/*! \brief Find a user-mode module...
*
* \param Address If \a Address is not NULL the module containing \a Address
* is searched.
* \param Name If \a Name is not NULL the module named \a Name will be
* searched.
* \param Index If \a Index is >= 0 the Index'th module will be returned.
* \param pInfo Pointer to a KDB_MODULE_INFO which is filled.
*
* \retval TRUE Module was found, \a pInfo was filled.
* \retval FALSE No module was found.
*
* \sa KdbpSymFindModule
*/
STATIC BOOLEAN
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;
CurrentProcess = PsGetCurrentProcess();
if (CurrentProcess != NULL)
{
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))
{
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;
}
return FALSE;
}
/*! \brief Find a kernel-mode module...
*
* Works like \a KdbpSymFindUserModule.
*
* \sa KdbpSymFindUserModule
*/
STATIC BOOLEAN
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;
extern LIST_ENTRY ModuleListHead;
INT Count = 0;
INT Length;
current_entry = ModuleListHead.Flink;
while (current_entry != &ModuleListHead)
{
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) ||
(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;
}
current_entry = current_entry->Flink;
}
return KdbpSymFindUserModule(Address, Name, Index-Count, pInfo);
}
/*! \brief Find module by address...
*
* \param Address Any address inside the module to look for.
* \param pInfo Pointer to a KDB_MODULE_INFO struct which is filled on
* success.
*
* \retval TRUE Success - module found.
* \retval FALSE Failure - module not found.
*
* \sa KdbpSymFindModuleByName
* \sa KdbpSymFindModuleByIndex
*/
BOOLEAN
KdbpSymFindModuleByAddress(IN PVOID Address,
OUT PKDB_MODULE_INFO pInfo)
{
return KdbpSymFindModule(Address, NULL, -1, pInfo);
}
/*! \brief Find module by name...
*
* \param Name Name of the module to look for.
* \param pInfo Pointer to a KDB_MODULE_INFO struct which is filled on
* success.
*
* \retval TRUE Success - module found.
* \retval FALSE Failure - module not found.
*
* \sa KdbpSymFindModuleByAddress
* \sa KdbpSymFindModuleByIndex
*/
BOOLEAN
KdbpSymFindModuleByName(IN LPCWSTR Name,
OUT PKDB_MODULE_INFO pInfo)
{
return KdbpSymFindModule(NULL, Name, -1, pInfo);
}
/*! \brief Find module by index...
*
* \param Index Index of the module to return.
* \param pInfo Pointer to a KDB_MODULE_INFO struct which is filled on
* success.
*
* \retval TRUE Success - module found.
* \retval FALSE Failure - module not found.
*
* \sa KdbpSymFindModuleByName
* \sa KdbpSymFindModuleByAddress
*/
BOOLEAN
KdbpSymFindModuleByIndex(IN INT Index,
OUT PKDB_MODULE_INFO pInfo)
{
return KdbpSymFindModule(NULL, NULL, Index, pInfo);
}
/*! \brief Print address...
*
* Tries to lookup line number, file name and function name for the given
* address and prints it.
* If no such information is found the address is printed in the format
* <module: offset>, otherwise the format will be
* <module: offset (filename:linenumber (functionname))>
*
* \retval TRUE Module containing \a Address was found, \a Address was printed.
* \retval FALSE No module containing \a Address was found, nothing was printed.
*/
BOOLEAN
KdbSymPrintAddress(IN PVOID Address)
{
KDB_MODULE_INFO Info;
ULONG_PTR RelativeAddress;
NTSTATUS Status;
ULONG LineNumber;
CHAR FileName[256];
CHAR FunctionName[256];
if (!KdbpSymFindModuleByAddress(Address, &Info))
return FALSE;
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);
}
else
{
DbgPrint("<%ws:%x>", Info.Name, RelativeAddress);
}
return TRUE;
}
/*! \brief Get information for an address (source file, line number,
* function name)
*
* \param SymbolInfo Pointer to ROSSYM_INFO.
* \param RelativeAddress Relative address to look up.
* \param LineNumber Pointer to an ULONG which is filled with the line
* number (can be NULL)
* \param FileName Pointer to an array of CHARs which gets filled with
* the filename (can be NULL)
* \param FunctionName Pointer to an array of CHARs which gets filled with
* the function name (can be NULL)
*
* \returns NTSTATUS error code.
* \retval STATUS_SUCCESS At least one of the requested informations was found.
* \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)
{
if (NULL == RosSymInfo)
{
return STATUS_UNSUCCESSFUL;
}
if (! RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineNumber,
FileName, FunctionName))
{
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
/*! \brief Find cached symbol file.
*
* Looks through the list of cached symbol files and tries to find an already
* loaded one.
*
* \param FileName FileName of the symbol file to look for.
*
* \returns A pointer to the cached symbol info.
* \retval NULL No cached info found.
*
* \sa KdbpSymAddCachedFile
*/
STATIC PROSSYM_INFO
KdbpSymFindCachedFile(IN PUNICODE_STRING FileName)
{
PIMAGE_SYMBOL_INFO_CACHE Current;
PLIST_ENTRY CurrentEntry;
KIRQL Irql;
DPRINT("Looking for cached symbol file %wZ\n", FileName);
KeAcquireSpinLock(&SymbolFileListLock, &Irql);
CurrentEntry = SymbolFileListHead.Flink;
while (CurrentEntry != (&SymbolFileListHead))
{
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))
{
Current->RefCount++;
KeReleaseSpinLock(&SymbolFileListLock, Irql);
DPRINT("Found cached file!\n");
return Current->RosSymInfo;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&SymbolFileListLock, Irql);
DPRINT("Cached file not found!\n");
return NULL;
}
/*! \brief Add a symbol file to the cache.
*
* \param FileName Filename of the symbol file.
* \param RosSymInfo Pointer to the symbol info.
*
* \sa KdbpSymRemoveCachedFile
*/
STATIC VOID
KdbpSymAddCachedFile(IN PUNICODE_STRING FileName,
IN PROSSYM_INFO RosSymInfo)
{
PIMAGE_SYMBOL_INFO_CACHE CacheEntry;
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));
/* fill entry */
RtlCreateUnicodeString(&CacheEntry->FileName, FileName->Buffer);
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.
*
* Tries to find a cache entry matching the given symbol info and decreases
* it's reference count. If the refcount is 0 after decreasing it the cache
* entry will be removed from the list and freed.
*
* \param RosSymInfo Pointer to the symbol info.
*
* \sa KdbpSymAddCachedFile
*/
STATIC VOID
KdbpSymRemoveCachedFile(IN PROSSYM_INFO RosSymInfo)
{
PIMAGE_SYMBOL_INFO_CACHE Current;
PLIST_ENTRY CurrentEntry;
KIRQL Irql;
KeAcquireSpinLock(&SymbolFileListLock, &Irql);
CurrentEntry = SymbolFileListHead.Flink;
while (CurrentEntry != (&SymbolFileListHead))
{
Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry);
if (Current->RosSymInfo == RosSymInfo) /* found */
{
ASSERT(Current->RefCount > 0);
Current->RefCount--;
if (Current->RefCount < 1)
{
RemoveEntryList(&Current->ListEntry);
RosSymDelete(Current->RosSymInfo);
ExFreePool(Current);
}
KeReleaseSpinLock(&SymbolFileListLock, Irql);
return;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&SymbolFileListLock, Irql);
DPRINT1("Warning: Removing unknown symbol file: RosSymInfo = %p\n", RosSymInfo);
}
/*! \brief Loads a symbol file.
*
* \param FileName Filename of the symbol file to load.
* \param RosSymInfo Pointer to a ROSSYM_INFO which gets filled.
*
* \sa KdbpSymUnloadModuleSymbols
*/
STATIC VOID
KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
OUT PROSSYM_INFO *RosSymInfo)
{
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE FileHandle;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
/* Allow KDB to break on module load */
KdbModuleLoaded(FileName);
if (! LoadSymbols)
{
*RosSymInfo = NULL;
return;
}
/* Try to find cached (already loaded) symbol file */
*RosSymInfo = KdbpSymFindCachedFile(FileName);
if (*RosSymInfo != NULL)
{
DPRINT("Found cached symbol file %wZ\n", FileName);
return;
}
/* Open the file */
InitializeObjectAttributes(&ObjectAttributes,
FileName,
0,
NULL,
NULL);
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))
{
DPRINT("Could not open image file: %wZ\n", &FileName);
return;
}
DPRINT("Loading symbols from %wZ...\n", FileName);
if (! RosSymCreateFromFile(&FileHandle, RosSymInfo))
{
DPRINT("Failed to load symbols from %wZ\n", FileName);
return;
}
ZwClose(FileHandle);
DPRINT("Symbols loaded.\n");
/* add file to cache */
KdbpSymAddCachedFile(FileName, *RosSymInfo);
DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo);
}
/*! \brief Unloads symbol info.
*
* \param RosSymInfo Pointer to the symbol info to unload.
*
* \sa KdbpSymLoadModuleSymbols
*/
STATIC VOID
KdbpSymUnloadModuleSymbols(IN PROSSYM_INFO RosSymInfo)
{
DPRINT("Unloading symbols\n");
if (RosSymInfo != NULL)
{
KdbpSymRemoveCachedFile(RosSymInfo);
}
}
/*! \brief Load symbol info for a user module.
*
* \param LdrModule Pointer to the module to load symbols for.
*/
VOID
KdbSymLoadUserModuleSymbols(IN PLDR_DATA_TABLE_ENTRY LdrModule)
{
static WCHAR Prefix[] = L"\\??\\";
UNICODE_STRING KernelName;
DPRINT("LdrModule %p\n", LdrModule);
LdrModule->PatchInformation = NULL;
KernelName.MaximumLength = sizeof(Prefix) + LdrModule->FullDllName.Length;
KernelName.Length = KernelName.MaximumLength - sizeof(WCHAR);
KernelName.Buffer = ExAllocatePoolWithTag(PagedPool, 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';
KdbpSymLoadModuleSymbols(&KernelName, (PROSSYM_INFO*)&LdrModule->PatchInformation);
ExFreePool(KernelName.Buffer);
}
/*! \brief Frees all symbols loaded for a process.
*
* \param Process Pointer to a process.
*/
VOID
KdbSymFreeProcessSymbols(IN PEPROCESS Process)
{
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);
CurrentEntry = Peb->Ldr->InLoadOrderModuleList.Flink;
while (CurrentEntry != &Peb->Ldr->InLoadOrderModuleList &&
CurrentEntry != NULL)
{
Current = CONTAINING_RECORD(CurrentEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
KdbpSymUnloadModuleSymbols(Current->PatchInformation);
CurrentEntry = CurrentEntry->Flink;
}
if (CurrentProcess != Process)
{
KeDetachProcess();
}
}
/*! \brief Load symbol info for a driver.
*
* \param Filename Filename of the driver.
* \param Module Pointer to the driver LDR_DATA_TABLE_ENTRY.
*/
VOID
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);
Module->PatchInformation = NULL;
KdbpSymLoadModuleSymbols(Filename, (PROSSYM_INFO*)&Module->PatchInformation);
}
/*! \brief Unloads symbol info for a driver.
*
* \param ModuleObject Pointer to the driver LDR_DATA_TABLE_ENTRY.
*/
VOID
KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject)
{
/* Unload symbols for module if available */
KdbpSymUnloadModuleSymbols(ModuleObject->PatchInformation);
ModuleObject->PatchInformation = NULL;
}
/*! \brief Called when a symbol file is loaded by the loader?
*
* Tries to find a driver (.sys) or executable (.exe) with the same base name
* as the symbol file and sets the drivers/exes symbol info to the loaded
* module.
* Used to load ntoskrnl and hal symbols before the SystemRoot is available to us.
*
* \param FileName Filename for which the symbols are loaded.
*/
VOID
KdbSymProcessBootSymbols(IN PUNICODE_STRING FileName)
{
PLDR_DATA_TABLE_ENTRY ModuleObject;
BOOLEAN Found = FALSE;
BOOLEAN IsRaw;
PLIST_ENTRY ListHead, NextEntry;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PUNICODE_STRING ModuleName = FileName;
UNICODE_STRING NtosSymName = RTL_CONSTANT_STRING(L"ntoskrnl.sym");
UNICODE_STRING NtosName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
if (RtlEqualUnicodeString(FileName, &NtosSymName, TRUE))
{
ModuleName = &NtosName;
IsRaw = TRUE;
}
else
{
IsRaw = FALSE;
}
ModuleObject = LdrGetModuleObject(ModuleName);
if (ModuleObject != NULL)
{
if (! LoadSymbols)
{
ModuleObject->PatchInformation = NULL;
return;
}
ListHead = &KeLoaderBlock->LoadOrderListHead;
NextEntry = ListHead->Flink;
while (ListHead != NextEntry)
{
/* Get the entry */
LdrEntry = CONTAINING_RECORD(NextEntry,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
if (RtlEqualUnicodeString(FileName, &LdrEntry->BaseDllName, TRUE))
{
Found = TRUE;
break;
}
/* Go to the next one */
NextEntry = NextEntry->Flink;
}
if (Found)
{
if (ModuleObject->PatchInformation != NULL)
{
KdbpSymRemoveCachedFile(ModuleObject->PatchInformation);
}
if (IsRaw)
{
DPRINT("Data: %p %p %wZ\n", LdrEntry->DllBase, LdrEntry->SizeOfImage, &LdrEntry->FullDllName);
if (! RosSymCreateFromRaw(LdrEntry->DllBase,
LdrEntry->SizeOfImage,
(PROSSYM_INFO*)&ModuleObject->PatchInformation))
{
return;
}
}
else
{
if (! RosSymCreateFromMem(LdrEntry->DllBase,
LdrEntry->SizeOfImage,
(PROSSYM_INFO*)&ModuleObject->PatchInformation))
{
return;
}
}
/* add file to cache */
KdbpSymAddCachedFile(FileName, ModuleObject->PatchInformation);
DPRINT("Installed symbols: %wZ@%08x-%08x %p\n",
FileName,
ModuleObject->DllBase,
ModuleObject->SizeOfImage + (ULONG)ModuleObject->DllBase,
ModuleObject->PatchInformation);
}
}
}
/*! \brief Initializes the KDB symbols implementation.
*
* \param NtoskrnlModuleObject LDR_DATA_TABLE_ENTRY of ntoskrnl.exe
* \param LdrHalModuleObject LDR_DATA_TABLE_ENTRY of hal.sys
*/
VOID
KdbSymInit(IN PLDR_DATA_TABLE_ENTRY NtoskrnlModuleObject,
IN PLDR_DATA_TABLE_ENTRY LdrHalModuleObject)
{
PCHAR p1, p2;
int Found;
char YesNo;
NtoskrnlModuleObject->PatchInformation = NULL;
LdrHalModuleObject->PatchInformation = NULL;
InitializeListHead(&SymbolFileListHead);
KeInitializeSpinLock(&SymbolFileListLock);
#ifdef DBG
LoadSymbols = TRUE;
#else
LoadSymbols = FALSE;
#endif
/* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS,
* /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */
p1 = KeLoaderBlock->LoadOptions;
while('\0' != *p1 && NULL != (p2 = strchr(p1, '/')))
{
p2++;
Found = 0;
if (0 == _strnicmp(p2, "LOADSYMBOLS", 11))
{
Found = +1;
p2 += 11;
}
else if (0 == _strnicmp(p2, "NOLOADSYMBOLS", 13))
{
Found = -1;
p2 += 13;
}
if (0 != Found)
{
while (isspace(*p2))
{
p2++;
}
if ('=' == *p2)
{
p2++;
while (isspace(*p2))
{
p2++;
}
YesNo = toupper(*p2);
if ('N' == YesNo || 'F' == YesNo || '0' == YesNo)
{
Found = -1 * Found;
}
}
LoadSymbols = (0 < Found);
}
p1 = p2;
}
RosSymInitKernelMode();
}
/* EOF */