mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
Merge my current work done on the kd++ branch:
- FreeLdr is able now to load personalized Kernel Debugger Transport DLLs by reading at the kernel command line and interpreting the /DEBUGPORT=xxx entry (--> loads KDxxx.DLL dll in \SystemRoot\System32\). Therefore we can not only load the "default" kdcom.dll, but also 3rd-party ones such as kdbazis.dll from VirtualKD (from revision 58902). - The GCC-compiled-only version of kdcom, containing legacy COM code, was removed and put directly along KDBG. It remains only a stub / template for future kdcom-like dlls. The MSVC-version remains untouched. - Make those functions ^ use directly the CPORTLIB library. svn path=/trunk/; revision=58974
This commit is contained in:
commit
91ef640fe5
27 changed files with 876 additions and 440 deletions
|
@ -1568,7 +1568,7 @@ LoadBootDeviceDriver(VOID)
|
|||
ULONG ImportTableSize;
|
||||
PLDR_DATA_TABLE_ENTRY BootDdDTE, FreeldrDTE;
|
||||
CHAR NtBootDdPath[MAX_PATH];
|
||||
PVOID ImageBase;
|
||||
PVOID ImageBase = NULL;
|
||||
ULONG (NTAPI *EntryPoint)(IN PVOID DriverObject, IN PVOID RegistryPath);
|
||||
BOOLEAN Status;
|
||||
|
||||
|
|
|
@ -255,11 +255,12 @@ WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* WinLdrLoadImage loads the specified image from the file (it doesn't
|
||||
perform any additional operations on the filename, just directly
|
||||
calls the file I/O routines), and relocates it so that it's ready
|
||||
to be used when paging is enabled.
|
||||
Addressing mode: physical
|
||||
/*
|
||||
* WinLdrLoadImage loads the specified image from the file (it doesn't
|
||||
* perform any additional operations on the filename, just directly
|
||||
* calls the file I/O routines), and relocates it so that it's ready
|
||||
* to be used when paging is enabled.
|
||||
* Addressing mode: physical
|
||||
*/
|
||||
BOOLEAN
|
||||
WinLdrLoadImage(IN PCHAR FileName,
|
||||
|
@ -430,7 +431,6 @@ WinLdrLoadImage(IN PCHAR FileName,
|
|||
if (Status != ESUCCESS)
|
||||
return FALSE;
|
||||
|
||||
|
||||
/* Relocate the image, if it needs it */
|
||||
if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
|
||||
{
|
||||
|
@ -756,7 +756,7 @@ WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead,
|
|||
{
|
||||
CHAR FullDllName[256];
|
||||
BOOLEAN Status;
|
||||
PVOID BasePA;
|
||||
PVOID BasePA = NULL;
|
||||
|
||||
/* Prepare the full path to the file to be loaded */
|
||||
strcpy(FullDllName, DirectoryPath);
|
||||
|
@ -781,7 +781,7 @@ WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead,
|
|||
DataTableEntry);
|
||||
if (!Status)
|
||||
{
|
||||
ERR("WinLdrAllocateDataTableEntry() failed with Status=0x%X\n", Status);
|
||||
ERR("WinLdrAllocateDataTableEntry() failed\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -791,7 +791,7 @@ WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead,
|
|||
Status = WinLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
|
||||
if (!Status)
|
||||
{
|
||||
ERR("WinLdrScanImportDescriptorTable() failed with Status=0x%X\n", Status);
|
||||
ERR("WinLdrScanImportDescriptorTable() failed\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|||
|
||||
static BOOLEAN
|
||||
WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
|
||||
LPSTR BootPath,
|
||||
LPCSTR BootPath,
|
||||
PUNICODE_STRING FilePath,
|
||||
ULONG Flags,
|
||||
PLDR_DATA_TABLE_ENTRY *DriverDTE)
|
||||
|
@ -237,7 +237,7 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
|
|||
CHAR DllName[1024];
|
||||
PCHAR DriverNamePos;
|
||||
BOOLEAN Status;
|
||||
PVOID DriverBase;
|
||||
PVOID DriverBase = NULL;
|
||||
|
||||
// Separate the path to file name and directory path
|
||||
_snprintf(DriverPath, sizeof(DriverPath), "%wZ", FilePath);
|
||||
|
@ -259,7 +259,6 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
|
|||
|
||||
TRACE("DriverPath: %s, DllName: %s, LPB\n", DriverPath, DllName);
|
||||
|
||||
|
||||
// Check if driver is already loaded
|
||||
Status = WinLdrCheckForLoadedDll(LoadOrderListHead, DllName, DriverDTE);
|
||||
if (Status)
|
||||
|
@ -299,7 +298,7 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
|
|||
|
||||
BOOLEAN
|
||||
WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
LPSTR BootPath)
|
||||
LPCSTR BootPath)
|
||||
{
|
||||
PLIST_ENTRY NextBd;
|
||||
PBOOT_DRIVER_LIST_ENTRY BootDriver;
|
||||
|
@ -318,8 +317,11 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|||
// Paths are relative (FIXME: Are they always relative?)
|
||||
|
||||
// Load it
|
||||
Status = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead, BootPath, &BootDriver->FilePath,
|
||||
0, &BootDriver->LdrEntry);
|
||||
Status = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead,
|
||||
BootPath,
|
||||
&BootDriver->FilePath,
|
||||
0,
|
||||
&BootDriver->LdrEntry);
|
||||
|
||||
// If loading failed - cry loudly
|
||||
//FIXME: Maybe remove it from the list and try to continue?
|
||||
|
@ -340,8 +342,10 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size,
|
||||
TYPE_OF_MEMORY MemoryType)
|
||||
PVOID
|
||||
WinLdrLoadModule(PCSTR ModuleName,
|
||||
ULONG *Size,
|
||||
TYPE_OF_MEMORY MemoryType)
|
||||
{
|
||||
ULONG FileId;
|
||||
PVOID PhysicalBase;
|
||||
|
@ -398,7 +402,6 @@ PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size,
|
|||
return PhysicalBase;
|
||||
}
|
||||
|
||||
|
||||
USHORT
|
||||
WinLdrDetectVersion()
|
||||
{
|
||||
|
@ -420,19 +423,20 @@ WinLdrDetectVersion()
|
|||
}
|
||||
|
||||
static
|
||||
PVOID
|
||||
BOOLEAN
|
||||
LoadModule(
|
||||
PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
PCCH Path,
|
||||
PCCH File,
|
||||
TYPE_OF_MEMORY MemoryType,
|
||||
PLDR_DATA_TABLE_ENTRY *Dte,
|
||||
BOOLEAN IsKdTransportDll,
|
||||
ULONG Percentage)
|
||||
{
|
||||
BOOLEAN Status;
|
||||
CHAR FullFileName[MAX_PATH];
|
||||
CHAR ProgressString[256];
|
||||
NTSTATUS Status;
|
||||
PVOID BaseAdress;
|
||||
PVOID BaseAdress = NULL;
|
||||
|
||||
UiDrawBackdrop();
|
||||
sprintf(ProgressString, "Loading %s...", File);
|
||||
|
@ -443,15 +447,146 @@ LoadModule(
|
|||
strcat(FullFileName, File);
|
||||
|
||||
Status = WinLdrLoadImage(FullFileName, MemoryType, &BaseAdress);
|
||||
TRACE("%s loaded with status %d at %p\n",
|
||||
File, Status, BaseAdress);
|
||||
if (!Status)
|
||||
{
|
||||
TRACE("Loading %s failed\n", File);
|
||||
return FALSE;
|
||||
}
|
||||
TRACE("%s loaded successfully at %p\n", File, BaseAdress);
|
||||
|
||||
strcpy(FullFileName, "WINDOWS\\SYSTEM32\\");
|
||||
strcat(FullFileName, File);
|
||||
WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead, File,
|
||||
FullFileName, BaseAdress, Dte);
|
||||
/*
|
||||
* Cheat about the base DLL name if we are loading
|
||||
* the Kernel Debugger Transport DLL, to make the
|
||||
* PE loader happy.
|
||||
*/
|
||||
Status = WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
|
||||
(IsKdTransportDll ? "KDCOM.DLL" : File),
|
||||
FullFileName,
|
||||
BaseAdress,
|
||||
Dte);
|
||||
|
||||
return BaseAdress;
|
||||
return Status;
|
||||
}
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
LoadWindowsCore(IN USHORT OperatingSystemVersion,
|
||||
IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
IN LPCSTR BootOptions,
|
||||
IN LPCSTR BootPath,
|
||||
IN OUT PLDR_DATA_TABLE_ENTRY* KernelDTE)
|
||||
{
|
||||
BOOLEAN Status;
|
||||
CHAR DirPath[MAX_PATH];
|
||||
CHAR KdTransportDllName[MAX_PATH];
|
||||
PLDR_DATA_TABLE_ENTRY HalDTE, KdComDTE = NULL;
|
||||
|
||||
if (!KernelDTE) return FALSE;
|
||||
|
||||
/* Load the Kernel */
|
||||
LoadModule(LoaderBlock, BootPath, "NTOSKRNL.EXE", LoaderSystemCode, KernelDTE, FALSE, 30);
|
||||
|
||||
/* Load the HAL */
|
||||
LoadModule(LoaderBlock, BootPath, "HAL.DLL", LoaderHalCode, &HalDTE, FALSE, 45);
|
||||
|
||||
/* Load the Kernel Debugger Transport DLL */
|
||||
if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
|
||||
{
|
||||
/*
|
||||
* According to http://www.nynaeve.net/?p=173 :
|
||||
* "[...] Another enhancement that could be done Microsoft-side would be
|
||||
* a better interface for replacing KD transport modules. Right now, due
|
||||
* to the fact that ntoskrnl is static linked to KDCOM.DLL, the OS loader
|
||||
* has a hardcoded hack that interprets the KD type in the OS loader options,
|
||||
* loads one of the (hardcoded filenames) "kdcom.dll", "kd1394.dll", or
|
||||
* "kdusb2.dll" modules, and inserts them into the loaded module list under
|
||||
* the name "kdcom.dll". [...]"
|
||||
*/
|
||||
|
||||
/*
|
||||
* This loop replaces a dumb call to strstr(..., "DEBUGPORT=").
|
||||
* Indeed I want it to be case-insensitive to allow "debugport="
|
||||
* or "DeBuGpOrT=" or... , and I don't want it to match malformed
|
||||
* command-line options, such as:
|
||||
*
|
||||
* "...foo DEBUGPORT=xxx bar..."
|
||||
* "...foo/DEBUGPORT=xxx bar..."
|
||||
* "...foo/DEBUGPORT=bar..."
|
||||
*
|
||||
* i.e. the "DEBUGPORT=" switch must start with a slash and be separated
|
||||
* from the rest by whitespace, unless it begins the command-line, e.g.:
|
||||
*
|
||||
* "/DEBUGPORT=COM1 foo...bar..."
|
||||
* "...foo /DEBUGPORT=USB bar..."
|
||||
* or:
|
||||
* "...foo /DEBUGPORT= bar..."
|
||||
* (in that case, we default the port to COM).
|
||||
*/
|
||||
while (BootOptions)
|
||||
{
|
||||
/* Skip possible initial whitespace */
|
||||
BootOptions += strspn(BootOptions, " \t");
|
||||
|
||||
/* Check whether a new commutator starts and it is the DEBUGPORT one */
|
||||
if (*BootOptions != '/' || _strnicmp(++BootOptions, "DEBUGPORT=", 10) != 0)
|
||||
{
|
||||
/* Search for another whitespace */
|
||||
BootOptions = strpbrk(BootOptions, " \t");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We found the DEBUGPORT commutator. Move to the port name. */
|
||||
BootOptions += 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (BootOptions)
|
||||
{
|
||||
/*
|
||||
* We have found the DEBUGPORT commutator. Parse the port name.
|
||||
* Format: /DEBUGPORT=COM1 or /DEBUGPORT=FILE:\Device\HarddiskX\PartitionY\debug.log or /DEBUGPORT=FOO
|
||||
* If we only have /DEBUGPORT= (i.e. without any port name), defaults it to "COM".
|
||||
*/
|
||||
strcpy(KdTransportDllName, "KD");
|
||||
if (_strnicmp(BootOptions, "COM", 3) == 0 && '0' <= BootOptions[3] && BootOptions[3] <= '9')
|
||||
{
|
||||
strncat(KdTransportDllName, BootOptions, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i = strcspn(BootOptions, " \t:"); /* Skip valid separators: whitespace or colon */
|
||||
if (i == 0)
|
||||
strcat(KdTransportDllName, "COM");
|
||||
else
|
||||
strncat(KdTransportDllName, BootOptions, i);
|
||||
}
|
||||
strcat(KdTransportDllName, ".DLL");
|
||||
_strupr(KdTransportDllName);
|
||||
|
||||
/*
|
||||
* Load the transport DLL. Specify it to LoadModule so that it can
|
||||
* change the base DLL name of the loaded transport DLL to the default
|
||||
* "KDCOM.DLL" name, to make the PE loader happy.
|
||||
*/
|
||||
LoadModule(LoaderBlock, BootPath, KdTransportDllName, LoaderSystemCode, &KdComDTE, TRUE, 60);
|
||||
}
|
||||
}
|
||||
|
||||
/* Load all referenced DLLs for Kernel, HAL and Kernel Debugger Transport DLL */
|
||||
strcpy(DirPath, BootPath);
|
||||
strcat(DirPath, "system32\\");
|
||||
Status = WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, *KernelDTE);
|
||||
Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
|
||||
if (KdComDTE)
|
||||
{
|
||||
Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, KdComDTE);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -496,7 +631,7 @@ LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
|
|||
strcat(BootPath, FileName);
|
||||
}
|
||||
|
||||
/* append a backslash */
|
||||
/* Append a backslash */
|
||||
if ((strlen(BootPath)==0) || BootPath[strlen(BootPath)] != '\\')
|
||||
strcat(BootPath, "\\");
|
||||
|
||||
|
@ -547,13 +682,13 @@ LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
|
|||
UiDrawBackdrop();
|
||||
UiDrawProgressBarCenter(15, 100, "Loading system hive...");
|
||||
Status = WinLdrInitSystemHive(LoaderBlock, BootPath);
|
||||
TRACE("SYSTEM hive loaded with status %d\n", Status);
|
||||
TRACE("SYSTEM hive %s\n", (Status ? "loaded" : "not loaded"));
|
||||
|
||||
/* Load NLS data, OEM font, and prepare boot drivers list */
|
||||
Status = WinLdrScanSystemHive(LoaderBlock, BootPath);
|
||||
TRACE("SYSTEM hive scanned with status %d\n", Status);
|
||||
|
||||
TRACE("SYSTEM hive %s\n", (Status ? "scanned" : "not scanned"));
|
||||
|
||||
/* Finish loading */
|
||||
LoadAndBootWindowsCommon(OperatingSystemVersion,
|
||||
LoaderBlock,
|
||||
BootOptions,
|
||||
|
@ -571,8 +706,7 @@ LoadAndBootWindowsCommon(
|
|||
{
|
||||
PLOADER_PARAMETER_BLOCK LoaderBlockVA;
|
||||
BOOLEAN Status;
|
||||
CHAR FileName[MAX_PATH];
|
||||
PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL;
|
||||
PLDR_DATA_TABLE_ENTRY KernelDTE;
|
||||
KERNEL_ENTRY_POINT KiSystemStartup;
|
||||
LPCSTR SystemRoot;
|
||||
TRACE("LoadAndBootWindowsCommon()\n");
|
||||
|
@ -586,40 +720,30 @@ LoadAndBootWindowsCommon(
|
|||
if (OperatingSystemVersion == 0)
|
||||
OperatingSystemVersion = WinLdrDetectVersion();
|
||||
|
||||
/* Load kernel */
|
||||
LoadModule(LoaderBlock, BootPath, "NTOSKRNL.EXE", LoaderSystemCode, &KernelDTE, 30);
|
||||
|
||||
/* Load HAL */
|
||||
LoadModule(LoaderBlock, BootPath, "HAL.DLL", LoaderHalCode, &HalDTE, 45);
|
||||
|
||||
/* Load kernel-debugger support dll */
|
||||
if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
|
||||
{
|
||||
LoadModule(LoaderBlock, BootPath, "KDCOM.DLL", LoaderSystemCode, &KdComDTE, 60);
|
||||
}
|
||||
|
||||
/* Load all referenced DLLs for kernel, HAL and kdcom.dll */
|
||||
strcpy(FileName, BootPath);
|
||||
strcat(FileName, "system32\\");
|
||||
Status = WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, FileName, KernelDTE);
|
||||
Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, FileName, HalDTE);
|
||||
if (KdComDTE)
|
||||
Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, FileName, KdComDTE);
|
||||
|
||||
/* Load the operating system core: the Kernel, the HAL and the Kernel Debugger Transport DLL */
|
||||
Status = LoadWindowsCore(OperatingSystemVersion,
|
||||
LoaderBlock,
|
||||
BootOptions,
|
||||
BootPath,
|
||||
&KernelDTE);
|
||||
if (!Status)
|
||||
{
|
||||
UiMessageBox("Error loading imported dll.");
|
||||
UiMessageBox("Error loading NTOS core.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load boot drivers */
|
||||
UiDrawBackdrop();
|
||||
UiDrawProgressBarCenter(100, 100, "Loading boot drivers...");
|
||||
Status = WinLdrLoadBootDrivers(LoaderBlock, (PCHAR)BootPath);
|
||||
Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
|
||||
TRACE("Boot drivers loaded with status %d\n", Status);
|
||||
|
||||
/* Initialize Phase 1 - no drivers loading anymore */
|
||||
WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemRoot, BootPath, OperatingSystemVersion);
|
||||
WinLdrInitializePhase1(LoaderBlock,
|
||||
BootOptions,
|
||||
SystemRoot,
|
||||
BootPath,
|
||||
OperatingSystemVersion);
|
||||
|
||||
/* Save entry-point pointer and Loader block VAs */
|
||||
KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
|
||||
|
@ -644,7 +768,7 @@ LoadAndBootWindowsCommon(
|
|||
LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
|
||||
|
||||
TRACE("Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
|
||||
KiSystemStartup, LoaderBlockVA);
|
||||
KiSystemStartup, LoaderBlockVA);
|
||||
|
||||
// Zero KI_USER_SHARED_DATA page
|
||||
memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE);
|
||||
|
@ -722,5 +846,3 @@ WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
NextBd = ArcDisk->ListEntry.Flink;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,9 +3,10 @@ add_subdirectory(beep)
|
|||
add_subdirectory(bootvid)
|
||||
|
||||
if(_WINKD_)
|
||||
add_subdirectory(kddll)
|
||||
else()
|
||||
add_subdirectory(kdcom)
|
||||
else()
|
||||
add_subdirectory(kdrosdbg)
|
||||
endif()
|
||||
|
||||
add_subdirectory(nmidebug)
|
||||
add_subdirectory(null)
|
||||
|
|
|
@ -1,19 +1,13 @@
|
|||
|
||||
spec2def(kdcom.dll kdcom.spec ADD_IMPORTLIB)
|
||||
|
||||
if(ARCH STREQUAL "i386")
|
||||
list(APPEND SOURCE i386/kdbg.c)
|
||||
elseif(ARCH STREQUAL "amd64")
|
||||
list(APPEND SOURCE i386/kdbg.c)
|
||||
elseif(ARCH STREQUAL "arm")
|
||||
list(APPEND SOURCE arm/kdbg.c)
|
||||
endif(ARCH STREQUAL "i386")
|
||||
list(APPEND SOURCE
|
||||
add_library(kdcom SHARED
|
||||
kdcom.c
|
||||
kddll.c
|
||||
kdserial.c
|
||||
kdcom.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kdcom.def)
|
||||
|
||||
add_library(kdcom SHARED ${SOURCE})
|
||||
|
||||
set_entrypoint(kdcom 0)
|
||||
set_subsystem(kdcom native)
|
||||
set_image_base(kdcom 0x00010000)
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
#define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
|
||||
#define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
|
||||
|
||||
#define DEFAULT_BAUD_RATE 19200
|
||||
|
||||
#define DEFAULT_BAUD_RATE 19200
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS KDBG COM Library"
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Kernel Debugger COM Extension DLL"
|
||||
#define REACTOS_STR_INTERNAL_NAME "kdcom"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "kdcom.dll"
|
||||
#include <reactos/version.rc>
|
||||
|
|
|
@ -1,21 +1,8 @@
|
|||
; Old KD
|
||||
@ stdcall KdPortGetByte(ptr)
|
||||
@ stdcall KdPortGetByteEx(ptr ptr)
|
||||
@ stdcall KdPortInitialize(ptr long long)
|
||||
@ stdcall KdPortInitializeEx(ptr long long)
|
||||
@ stdcall KdPortPollByte(ptr)
|
||||
@ stdcall KdPortPollByteEx(ptr ptr)
|
||||
@ stdcall KdPortPutByte(long)
|
||||
@ stdcall KdPortPutByteEx(ptr long)
|
||||
@ stdcall KdPortRestore()
|
||||
@ stdcall KdPortSave()
|
||||
@ stdcall KdPortDisableInterrupts()
|
||||
@ stdcall KdPortEnableInterrupts()
|
||||
|
||||
; New KD
|
||||
@ stdcall KdD0Transition()
|
||||
@ stdcall KdD3Transition()
|
||||
@ stdcall KdDebuggerInitialize0(ptr)
|
||||
@ stdcall KdDebuggerInitialize1(ptr)
|
||||
@ stdcall KdSave(long)
|
||||
@ stdcall KdRestore(long)
|
||||
@ stdcall KdReceivePacket(long ptr ptr ptr ptr)
|
||||
@ stdcall KdRestore(long)
|
||||
@ stdcall KdSave(long)
|
||||
@ stdcall KdSendPacket(long ptr ptr ptr)
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
@ stdcall KdD0Transition()
|
||||
@ stdcall KdD3Transition()
|
||||
@ stdcall KdDebuggerInitialize0(ptr)
|
||||
@ stdcall KdDebuggerInitialize1(ptr)
|
||||
@ stdcall KdReceivePacket(long ptr ptr ptr ptr)
|
||||
@ stdcall KdRestore(long)
|
||||
@ stdcall KdSave(long)
|
||||
@ stdcall KdSendPacket(long ptr ptr ptr)
|
|
@ -1,13 +1,13 @@
|
|||
|
||||
spec2def(kdcom.dll kdcom.spec ADD_IMPORTLIB)
|
||||
spec2def(kdcom.dll kdrosdbg.spec ADD_IMPORTLIB)
|
||||
|
||||
add_library(kdcom SHARED
|
||||
kdcom.c
|
||||
kddll.c
|
||||
kdserial.c
|
||||
kdcom.rc
|
||||
list(APPEND SOURCE
|
||||
kdrosdbg.c
|
||||
kdrosdbg.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kdcom.def)
|
||||
|
||||
add_library(kdcom SHARED ${SOURCE})
|
||||
|
||||
set_entrypoint(kdcom 0)
|
||||
set_subsystem(kdcom native)
|
||||
set_image_base(kdcom 0x00010000)
|
116
reactos/drivers/base/kdrosdbg/kdrosdbg.c
Normal file
116
reactos/drivers/base/kdrosdbg/kdrosdbg.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/base/kdcom/kdbg.c
|
||||
* PURPOSE: Serial i/o functions for the kernel debugger.
|
||||
* PROGRAMMER: Alex Ionescu
|
||||
* Hervé Poussineau
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#define NOEXTAPI
|
||||
#include <ntifs.h>
|
||||
#include <halfuncs.h>
|
||||
#include <stdio.h>
|
||||
#include <arc/arc.h>
|
||||
#include <windbgkd.h>
|
||||
#include <kddll.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize0(
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize1(
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdD0Transition(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdD3Transition(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdSave(
|
||||
IN BOOLEAN SleepTransition)
|
||||
{
|
||||
/* Nothing to do on COM ports */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdRestore(
|
||||
IN BOOLEAN SleepTransition)
|
||||
{
|
||||
/* Nothing to do on COM ports */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KdSendPacket(
|
||||
IN ULONG PacketType,
|
||||
IN PSTRING MessageHeader,
|
||||
IN PSTRING MessageData,
|
||||
IN OUT PKD_CONTEXT Context)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
KDSTATUS
|
||||
NTAPI
|
||||
KdReceivePacket(
|
||||
IN ULONG PacketType,
|
||||
OUT PSTRING MessageHeader,
|
||||
OUT PSTRING MessageData,
|
||||
OUT PULONG DataLength,
|
||||
IN OUT PKD_CONTEXT Context)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Kernel Debugger COM Extension DLL"
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS KDBG COM Library"
|
||||
#define REACTOS_STR_INTERNAL_NAME "kdcom"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "kdcom.dll"
|
||||
#include <reactos/version.rc>
|
|
@ -451,7 +451,7 @@ typedef struct _DBGKD_WAIT_STATE_CHANGE32
|
|||
ULONG Thread;
|
||||
ULONG ProgramCounter;
|
||||
union
|
||||
{
|
||||
{
|
||||
DBGKM_EXCEPTION32 Exception;
|
||||
DBGKD_LOAD_SYMBOLS32 LoadSymbols;
|
||||
} u;
|
||||
|
@ -481,13 +481,13 @@ typedef struct _DBGKD_ANY_WAIT_STATE_CHANGE
|
|||
ULONG64 Thread;
|
||||
ULONG64 ProgramCounter;
|
||||
union
|
||||
{
|
||||
{
|
||||
DBGKM_EXCEPTION64 Exception;
|
||||
DBGKD_LOAD_SYMBOLS64 LoadSymbols;
|
||||
DBGKD_COMMAND_STRING CommandString;
|
||||
} u;
|
||||
union
|
||||
{
|
||||
{
|
||||
DBGKD_CONTROL_REPORT ControlReport;
|
||||
DBGKD_ANY_CONTROL_REPORT AnyControlReport;
|
||||
};
|
||||
|
@ -814,7 +814,7 @@ typedef struct _DBGKD_FILE_IO
|
|||
ULONG ApiNumber;
|
||||
ULONG Status;
|
||||
union
|
||||
{
|
||||
{
|
||||
ULONG64 ReserveSpace[7];
|
||||
DBGKD_CREATE_FILE CreateFile;
|
||||
DBGKD_READ_FILE ReadFile;
|
||||
|
@ -843,7 +843,7 @@ typedef struct _DBGKD_CONTROL_REQUEST
|
|||
{
|
||||
ULONG ApiNumber;
|
||||
union
|
||||
{
|
||||
{
|
||||
DBGKD_REQUEST_BREAKPOINT RequestBreakpoint;
|
||||
DBGKD_RELEASE_BREAKPOINT ReleaseBreakpoint;
|
||||
} u;
|
||||
|
|
|
@ -363,6 +363,7 @@ endif()
|
|||
if(NOT _WINKD_)
|
||||
if(ARCH STREQUAL "i386")
|
||||
list(APPEND SOURCE
|
||||
kd/i386/kdbg.c
|
||||
kd/i386/kdmemsup.c
|
||||
kd/wrappers/gdbstub.c)
|
||||
if(KDBG)
|
||||
|
@ -372,6 +373,7 @@ if(NOT _WINKD_)
|
|||
elseif(ARCH STREQUAL "amd64")
|
||||
list(APPEND SOURCE
|
||||
kd/amd64/kd.c
|
||||
kd/i386/kdbg.c # Use the x86 file
|
||||
kd/amd64/kdmemsup.c)
|
||||
if(KDBG)
|
||||
list(APPEND ASM_SOURCE kdbg/amd64/kdb_help.S)
|
||||
|
@ -379,6 +381,8 @@ if(NOT _WINKD_)
|
|||
kdbg/amd64/i386-dis.c
|
||||
kdbg/amd64/kdb.c)
|
||||
endif()
|
||||
elseif(ARCH STREQUAL "arm")
|
||||
list(APPEND SOURCE kd/arm/kdbg.c)
|
||||
elseif(ARCH STREQUAL "powerpc")
|
||||
list(APPEND SOURCE kd/wrappers/gdbstub_powerpc.c)
|
||||
endif()
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <cportlib/cportlib.h>
|
||||
|
||||
#ifdef _M_PPC
|
||||
#define KdDebuggerEnabled _KdDebuggerEnabled
|
||||
#define KdDebuggerNotPresent _KdDebuggerNotPresent
|
||||
|
@ -8,58 +10,31 @@
|
|||
//
|
||||
// Kernel Debugger Port Definition
|
||||
//
|
||||
typedef struct _KD_PORT_INFORMATION
|
||||
{
|
||||
ULONG ComPort;
|
||||
ULONG BaudRate;
|
||||
ULONG BaseAddress;
|
||||
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
|
||||
|
||||
struct _KD_DISPATCH_TABLE;
|
||||
extern KD_PORT_INFORMATION GdbPortInfo;
|
||||
extern CPPORT GdbPortInfo;
|
||||
extern BOOLEAN _KdDebuggerEnabled;
|
||||
extern BOOLEAN _KdDebuggerNotPresent;
|
||||
extern BOOLEAN KdBreakAfterSymbolLoad;
|
||||
extern BOOLEAN KdPitchDebugger;
|
||||
extern BOOLEAN KdIgnoreUmExceptions;
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortInitialize(
|
||||
PKD_PORT_INFORMATION PortInformation,
|
||||
ULONG Unknown1,
|
||||
ULONG Unknown2
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortInitializeEx(
|
||||
PKD_PORT_INFORMATION PortInformation,
|
||||
ULONG Unknown1,
|
||||
ULONG Unknown2
|
||||
PCPPORT PortInformation,
|
||||
ULONG ComPortNumber
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortGetByte(
|
||||
PUCHAR ByteReceived);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortGetByteEx(
|
||||
PKD_PORT_INFORMATION PortInformation,
|
||||
PCPPORT PortInformation,
|
||||
PUCHAR ByteReceived);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortPutByte(
|
||||
UCHAR ByteToSend
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortPutByteEx(
|
||||
PKD_PORT_INFORMATION PortInformation,
|
||||
PCPPORT PortInformation,
|
||||
UCHAR ByteToSend
|
||||
);
|
||||
|
||||
|
@ -359,7 +334,8 @@ extern ULONG KdpPortIrq;
|
|||
extern ULONG KdpPort;
|
||||
|
||||
/* Port Information for the Serial Native Mode */
|
||||
extern KD_PORT_INFORMATION SerialPortInfo;
|
||||
extern ULONG SerialPortNumber;
|
||||
extern CPPORT SerialPortInfo;
|
||||
|
||||
/* Init Functions for Native Providers */
|
||||
extern PKDP_INIT_ROUTINE InitRoutines[KdMax];
|
||||
|
|
|
@ -95,10 +95,6 @@
|
|||
#define TAG_VPB ' BPV'
|
||||
#define TAG_SYSB 'BSYS'
|
||||
|
||||
/* formerly located in kdbg/kdb_symbols.c */
|
||||
#define TAG_KDBS 'SBDK'
|
||||
#define TAG_KDBG 'GBDK'
|
||||
|
||||
/* formerly located in ldr/loader.c */
|
||||
#define TAG_DRIVER_MEM 'MVRD' /* drvm */
|
||||
#define TAG_MODULE_OBJECT 'omlk' /* klmo - kernel ldr module object */
|
||||
|
|
112
reactos/ntoskrnl/kd/arm/kdbg.c
Normal file
112
reactos/ntoskrnl/kd/arm/kdbg.c
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/base/kdcom/arm/kdbg.c
|
||||
* PURPOSE: Serial Port Kernel Debugging Transport Library
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#include <arm/peripherals/pl011.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
CPPORT DefaultPort = {0, 0, 0};
|
||||
|
||||
//
|
||||
// We need to build this in the configuration root and use KeFindConfigurationEntry
|
||||
// to recover it later.
|
||||
//
|
||||
#define HACK 24000000
|
||||
|
||||
/* REACTOS FUNCTIONS **********************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortInitializeEx(IN PCPPORT PortInformation,
|
||||
IN ULONG ComPortNumber)
|
||||
{
|
||||
ULONG Divider, Remainder, Fraction;
|
||||
ULONG Baudrate = PortInformation->BaudRate;
|
||||
|
||||
//
|
||||
// Calculate baudrate clock divider and remainder
|
||||
//
|
||||
Divider = HACK / (16 * Baudrate);
|
||||
Remainder = HACK % (16 * Baudrate);
|
||||
|
||||
//
|
||||
// Calculate the fractional part
|
||||
//
|
||||
Fraction = (8 * Remainder / Baudrate) >> 1;
|
||||
Fraction += (8 * Remainder / Baudrate) & 1;
|
||||
|
||||
//
|
||||
// Disable interrupts
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL011_CR, 0);
|
||||
|
||||
//
|
||||
// Set the baud rate
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL011_IBRD, Divider);
|
||||
WRITE_REGISTER_ULONG(UART_PL011_FBRD, Fraction);
|
||||
|
||||
//
|
||||
// Set 8 bits for data, 1 stop bit, no parity, FIFO enabled
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL011_LCRH,
|
||||
UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN);
|
||||
|
||||
//
|
||||
// Clear and enable FIFO
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL011_CR,
|
||||
UART_PL011_CR_UARTEN |
|
||||
UART_PL011_CR_TXE |
|
||||
UART_PL011_CR_RXE);
|
||||
|
||||
//
|
||||
// Done
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortGetByteEx(IN PCPPORT PortInformation,
|
||||
OUT PUCHAR ByteReceived)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortPutByteEx(IN PCPPORT PortInformation,
|
||||
IN UCHAR ByteToSend)
|
||||
{
|
||||
//
|
||||
// Wait for ready
|
||||
//
|
||||
while ((READ_REGISTER_ULONG(UART_PL01x_FR) & UART_PL01x_FR_TXFF) != 0);
|
||||
|
||||
//
|
||||
// Send the character
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL01x_DR, ByteToSend);
|
||||
}
|
||||
|
||||
/* EOF */
|
151
reactos/ntoskrnl/kd/i386/kdbg.c
Normal file
151
reactos/ntoskrnl/kd/i386/kdbg.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/base/kdcom/kdbg.c
|
||||
* PURPOSE: Serial i/o functions for the kernel debugger.
|
||||
* PROGRAMMER: Alex Ionescu
|
||||
* Hervé Poussineau
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
#define DEFAULT_BAUD_RATE 19200
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
||||
#elif defined(_M_PPC)
|
||||
const ULONG BaseArray[] = {0, 0x800003F8};
|
||||
#elif defined(_M_MIPS)
|
||||
const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
|
||||
#elif defined(_M_ARM)
|
||||
const ULONG BaseArray[] = {0, 0xF1012000};
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
/* STATIC VARIABLES ***********************************************************/
|
||||
|
||||
// static CPPORT DefaultPort = {0, 0, 0};
|
||||
|
||||
/* The COM port must only be initialized once! */
|
||||
// static BOOLEAN PortInitialized = FALSE;
|
||||
|
||||
|
||||
/* REACTOS FUNCTIONS **********************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize1(
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortInitializeEx(
|
||||
IN PCPPORT PortInformation,
|
||||
IN ULONG ComPortNumber)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
CHAR buffer[80];
|
||||
|
||||
#if 0 // Deactivated because never used in fact (was in KdPortInitialize but we use KdPortInitializeEx)
|
||||
/*
|
||||
* Find the port if needed
|
||||
*/
|
||||
SIZE_T i;
|
||||
|
||||
if (!PortInitialized)
|
||||
{
|
||||
DefaultPort.BaudRate = PortInformation->BaudRate;
|
||||
|
||||
if (ComPortNumber == 0)
|
||||
{
|
||||
/*
|
||||
* Start enumerating COM ports from the last one to the first one,
|
||||
* and break when we find a valid port.
|
||||
* If we reach the first element of the list, the invalid COM port,
|
||||
* then it means that no valid port was found.
|
||||
*/
|
||||
for (i = sizeof(BaseArray) / sizeof(BaseArray[0]) - 1; i > 0; i--)
|
||||
{
|
||||
if (CpDoesPortExist(UlongToPtr(BaseArray[i])))
|
||||
{
|
||||
PortInformation->Address = DefaultPort.Address = BaseArray[i];
|
||||
ComPortNumber = (ULONG)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ComPortNumber == 0)
|
||||
{
|
||||
sprintf(buffer,
|
||||
"\nKernel Debugger: No COM port found!\n\n");
|
||||
HalDisplayString(buffer);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PortInitialized = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize the port
|
||||
*/
|
||||
Status = CpInitialize(PortInformation,
|
||||
(ComPortNumber == 0 ? PortInformation->Address
|
||||
: UlongToPtr(BaseArray[ComPortNumber])),
|
||||
(PortInformation->BaudRate == 0 ? DEFAULT_BAUD_RATE
|
||||
: PortInformation->BaudRate));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
sprintf(buffer,
|
||||
"\nKernel Debugger: Serial port not found!\n\n");
|
||||
HalDisplayString(buffer);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
/* Print message to blue screen */
|
||||
sprintf(buffer,
|
||||
"\nKernel Debugger: Serial port found: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
|
||||
ComPortNumber,
|
||||
PortInformation->Address,
|
||||
PortInformation->BaudRate);
|
||||
HalDisplayString(buffer);
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#if 0
|
||||
/* Set global info */
|
||||
KdComPortInUse = DefaultPort.Address;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortGetByteEx(
|
||||
IN PCPPORT PortInformation,
|
||||
OUT PUCHAR ByteReceived)
|
||||
{
|
||||
return (CpGetByte(PortInformation, ByteReceived, FALSE) == CP_GET_SUCCESS);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortPutByteEx(
|
||||
IN PCPPORT PortInformation,
|
||||
IN UCHAR ByteToSend)
|
||||
{
|
||||
CpPutByte(PortInformation, ByteToSend);
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -16,7 +16,8 @@
|
|||
|
||||
/* VARIABLES ***************************************************************/
|
||||
|
||||
KD_PORT_INFORMATION PortInfo = {DEFAULT_DEBUG_PORT, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||
ULONG PortNumber = DEFAULT_DEBUG_PORT;
|
||||
CPPORT PortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||
ULONG KdpPortIrq;
|
||||
#ifdef AUTO_ENABLE_BOCHS
|
||||
KDP_DEBUG_MODE KdpDebugMode = {{{.Bochs=TRUE}}};
|
||||
|
@ -68,7 +69,7 @@ KdpGetDebugMode(PCHAR Currentp2)
|
|||
KdpDebugMode.Serial = TRUE;
|
||||
|
||||
/* Set the port to use */
|
||||
SerialPortInfo.ComPort = Value;
|
||||
SerialPortNumber = Value;
|
||||
KdpPort = Value;
|
||||
}
|
||||
}
|
||||
|
@ -78,8 +79,8 @@ KdpGetDebugMode(PCHAR Currentp2)
|
|||
if (Value)
|
||||
{
|
||||
KdpDebugMode.Serial = TRUE;
|
||||
SerialPortInfo.BaseAddress = Value;
|
||||
SerialPortInfo.ComPort = 0;
|
||||
SerialPortInfo.Address = UlongToPtr(Value);
|
||||
SerialPortNumber = 0;
|
||||
KdpPort = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ HANDLE KdpLogFileHandle;
|
|||
ANSI_STRING KdpLogFileName = RTL_CONSTANT_STRING("\\SystemRoot\\debug.log");
|
||||
|
||||
KSPIN_LOCK KdpSerialSpinLock;
|
||||
KD_PORT_INFORMATION SerialPortInfo = { DEFAULT_DEBUG_PORT, DEFAULT_DEBUG_BAUD_RATE, 0 };
|
||||
ULONG SerialPortNumber = DEFAULT_DEBUG_PORT;
|
||||
CPPORT SerialPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||
|
||||
/* Current Port in use. FIXME: Do we support more then one? */
|
||||
ULONG KdpPort;
|
||||
|
@ -358,12 +359,12 @@ KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable,
|
|||
DispatchTable->KdpPrintRoutine = KdpSerialDebugPrint;
|
||||
|
||||
/* Initialize the Port */
|
||||
if (!KdPortInitializeEx(&SerialPortInfo, 0, 0))
|
||||
if (!KdPortInitializeEx(&SerialPortInfo, SerialPortNumber))
|
||||
{
|
||||
KdpDebugMode.Serial = FALSE;
|
||||
return;
|
||||
}
|
||||
KdComPortInUse = (PUCHAR)(ULONG_PTR)SerialPortInfo.BaseAddress;
|
||||
KdComPortInUse = SerialPortInfo.Address;
|
||||
|
||||
/* Initialize spinlock */
|
||||
KeInitializeSpinLock(&KdpSerialSpinLock);
|
||||
|
|
|
@ -44,7 +44,8 @@ static FAST_MUTEX GspLock;
|
|||
extern LIST_ENTRY PsActiveProcessHead;
|
||||
|
||||
/* FIXME hardcoded for COM2, 115200 baud */
|
||||
KD_PORT_INFORMATION GdbPortInfo = { 2, 115200, 0 };
|
||||
ULONG GdbPortNumber = DEFAULT_DEBUG_PORT;
|
||||
CPPORT GdbPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||
|
||||
static CHAR GspInBuffer[1000];
|
||||
static CHAR GspOutBuffer[1000];
|
||||
|
@ -126,9 +127,7 @@ GdbGetChar(VOID)
|
|||
{
|
||||
UCHAR Value;
|
||||
|
||||
while (!KdPortGetByteEx(&GdbPortInfo, &Value))
|
||||
;
|
||||
|
||||
while (!KdPortGetByteEx(&GdbPortInfo, &Value)) ;
|
||||
return Value;
|
||||
}
|
||||
|
||||
|
@ -145,8 +144,7 @@ GspGetPacket()
|
|||
while (TRUE)
|
||||
{
|
||||
/* wait around for the start character, ignore all other characters */
|
||||
while ((ch = GdbGetChar()) != '$')
|
||||
;
|
||||
while ((ch = GdbGetChar()) != '$') ;
|
||||
|
||||
retry:
|
||||
Checksum = 0;
|
||||
|
@ -784,7 +782,6 @@ GspQuery(PCHAR Request)
|
|||
}
|
||||
else if (strncmp(Request, "Rcmd,", 5) == 0)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -943,12 +940,14 @@ GspFindSwBreakpoint(ULONG_PTR Address, PULONG PIndex)
|
|||
ULONG Index;
|
||||
|
||||
for (Index = 0; Index < GspSwBreakpointCount; Index++)
|
||||
{
|
||||
if (GspSwBreakpoints[Index].Address == Address)
|
||||
{
|
||||
if (PIndex)
|
||||
*PIndex = Index;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1569,7 +1568,7 @@ KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable, ULONG BootPhase)
|
|||
WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
|
||||
|
||||
/* Initialize the Port */
|
||||
KdPortInitializeEx(&GdbPortInfo, 0, 0);
|
||||
KdPortInitializeEx(&GdbPortInfo, GdbPortNumber);
|
||||
}
|
||||
else if (BootPhase == 1)
|
||||
{
|
||||
|
|
|
@ -88,12 +88,8 @@
|
|||
#include <debug.h>
|
||||
|
||||
/************************************************************************/
|
||||
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
|
||||
/* at least NUMREGBYTES*2 are needed for register packets */
|
||||
#define BUFMAX 1000
|
||||
|
||||
static BOOLEAN GspInitialized;
|
||||
|
||||
static BOOLEAN GspRemoteDebug;
|
||||
|
||||
static CONST CHAR HexChars[]="0123456789abcdef";
|
||||
|
@ -107,25 +103,32 @@ static FAST_MUTEX GspLock;
|
|||
extern LIST_ENTRY PsActiveProcessHead;
|
||||
|
||||
/* FIXME hardcoded for COM2, 115200 baud */
|
||||
KD_PORT_INFORMATION GdbPortInfo = { 2, 115200, 0 };
|
||||
ULONG GdbPortNumber = DEFAULT_DEBUG_PORT;
|
||||
CPPORT GdbPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||
|
||||
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
|
||||
/* at least NUMREGBYTES*2 are needed for register packets */
|
||||
#define BUFMAX 1000
|
||||
static CHAR GspInBuffer[BUFMAX];
|
||||
static CHAR GspOutBuffer[BUFMAX];
|
||||
|
||||
/* Number of Registers. */
|
||||
#define NUMREGS 16
|
||||
|
||||
enum REGISTER_NAMES
|
||||
{
|
||||
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
|
||||
PC /* also known as eip */,
|
||||
PS /* also known as eflags */,
|
||||
CS, SS, DS, ES, FS, GS
|
||||
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
|
||||
PC /* also known as eip */,
|
||||
PS /* also known as eflags */,
|
||||
CS, SS, DS, ES, FS, GS
|
||||
};
|
||||
|
||||
typedef struct _CPU_REGISTER
|
||||
{
|
||||
ULONG Size;
|
||||
ULONG OffsetInTF;
|
||||
ULONG OffsetInContext;
|
||||
BOOLEAN SetInContext;
|
||||
ULONG Size;
|
||||
ULONG OffsetInTF;
|
||||
ULONG OffsetInContext;
|
||||
BOOLEAN SetInContext;
|
||||
} CPU_REGISTER, *PCPU_REGISTER;
|
||||
|
||||
static CPU_REGISTER GspRegisters[NUMREGS] =
|
||||
|
@ -134,54 +137,45 @@ static CPU_REGISTER GspRegisters[NUMREGS] =
|
|||
|
||||
static PCHAR GspThreadStates[DeferredReady+1] =
|
||||
{
|
||||
"Initialized",
|
||||
"Ready",
|
||||
"Running",
|
||||
"Standby",
|
||||
"Terminated",
|
||||
"Waiting",
|
||||
"Transition",
|
||||
"DeferredReady"
|
||||
"Initialized",
|
||||
"Ready",
|
||||
"Running",
|
||||
"Standby",
|
||||
"Terminated",
|
||||
"Waiting",
|
||||
"Transition",
|
||||
"DeferredReady"
|
||||
};
|
||||
|
||||
|
||||
LONG
|
||||
HexValue(CHAR ch)
|
||||
{
|
||||
if ((ch >= '0') && (ch <= '9'))
|
||||
{
|
||||
return (ch - '0');
|
||||
}
|
||||
if ((ch >= 'a') && (ch <= 'f'))
|
||||
{
|
||||
return (ch - 'a' + 10);
|
||||
}
|
||||
if ((ch >= 'A') && (ch <= 'F'))
|
||||
{
|
||||
return (ch - 'A' + 10);
|
||||
}
|
||||
if ((ch >= '0') && (ch <= '9'))
|
||||
return (ch - '0');
|
||||
|
||||
return -1;
|
||||
if ((ch >= 'a') && (ch <= 'f'))
|
||||
return (ch - 'a' + 10);
|
||||
|
||||
if ((ch >= 'A') && (ch <= 'F'))
|
||||
return (ch - 'A' + 10);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static CHAR GspInBuffer[BUFMAX];
|
||||
static CHAR GspOutBuffer[BUFMAX];
|
||||
|
||||
VOID
|
||||
GdbPutChar(UCHAR Value)
|
||||
{
|
||||
KdPortPutByteEx(&GdbPortInfo, Value);
|
||||
KdPortPutByteEx(&GdbPortInfo, Value);
|
||||
}
|
||||
|
||||
UCHAR
|
||||
GdbGetChar(VOID)
|
||||
{
|
||||
UCHAR Value;
|
||||
UCHAR Value;
|
||||
|
||||
while (!KdPortGetByteEx(&GdbPortInfo, &Value))
|
||||
;
|
||||
|
||||
return Value;
|
||||
while (!KdPortGetByteEx(&GdbPortInfo, &Value)) ;
|
||||
return Value;
|
||||
}
|
||||
|
||||
/* scan for the sequence $<data>#<Checksum> */
|
||||
|
@ -189,57 +183,53 @@ GdbGetChar(VOID)
|
|||
PCHAR
|
||||
GspGetPacket()
|
||||
{
|
||||
PCHAR Buffer = &GspInBuffer[0];
|
||||
CHAR Checksum;
|
||||
CHAR XmitChecksum;
|
||||
ULONG Count;
|
||||
CHAR ch;
|
||||
PCHAR Buffer = &GspInBuffer[0];
|
||||
CHAR Checksum;
|
||||
CHAR XmitChecksum;
|
||||
ULONG Count;
|
||||
CHAR ch;
|
||||
|
||||
while (TRUE)
|
||||
while (TRUE)
|
||||
{
|
||||
/* wait around for the start character, ignore all other characters */
|
||||
while ((ch = GdbGetChar ()) != '$')
|
||||
;
|
||||
/* wait around for the start character, ignore all other characters */
|
||||
while ((ch = GdbGetChar ()) != '$') ;
|
||||
|
||||
retry:
|
||||
Checksum = 0;
|
||||
XmitChecksum = -1;
|
||||
Count = 0;
|
||||
retry:
|
||||
Checksum = 0;
|
||||
XmitChecksum = -1;
|
||||
Count = 0;
|
||||
|
||||
/* now, read until a # or end of Buffer is found */
|
||||
while (Count < BUFMAX)
|
||||
/* now, read until a # or end of Buffer is found */
|
||||
while (Count < BUFMAX)
|
||||
{
|
||||
ch = GdbGetChar();
|
||||
if (ch == '$')
|
||||
{
|
||||
goto retry;
|
||||
}
|
||||
if (ch == '#')
|
||||
{
|
||||
break;
|
||||
}
|
||||
Checksum = Checksum + ch;
|
||||
Buffer[Count] = ch;
|
||||
Count = Count + 1;
|
||||
ch = GdbGetChar();
|
||||
if (ch == '$')
|
||||
goto retry;
|
||||
|
||||
if (ch == '#')
|
||||
break;
|
||||
|
||||
Checksum = Checksum + ch;
|
||||
Buffer[Count] = ch;
|
||||
Count = Count + 1;
|
||||
}
|
||||
Buffer[Count] = 0;
|
||||
Buffer[Count] = 0;
|
||||
|
||||
if (ch == '#')
|
||||
if (ch == '#')
|
||||
{
|
||||
ch = GdbGetChar();
|
||||
XmitChecksum = (CHAR)(HexValue(ch) << 4);
|
||||
ch = GdbGetChar();
|
||||
XmitChecksum += (CHAR)(HexValue(ch));
|
||||
ch = GdbGetChar();
|
||||
XmitChecksum = (CHAR)(HexValue(ch) << 4);
|
||||
ch = GdbGetChar();
|
||||
XmitChecksum += (CHAR)(HexValue(ch));
|
||||
|
||||
if (Checksum != XmitChecksum)
|
||||
if (Checksum != XmitChecksum)
|
||||
{
|
||||
GdbPutChar('-'); /* failed checksum */
|
||||
GdbPutChar('-'); /* failed checksum */
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
GdbPutChar('+'); /* successful transfer */
|
||||
|
||||
return &Buffer[0];
|
||||
GdbPutChar('+'); /* successful transfer */
|
||||
return &Buffer[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,54 +240,54 @@ GspGetPacket()
|
|||
VOID
|
||||
GspPutPacket(PCHAR Buffer)
|
||||
{
|
||||
CHAR Checksum;
|
||||
LONG Count;
|
||||
CHAR ch;
|
||||
CHAR Checksum;
|
||||
LONG Count;
|
||||
CHAR ch;
|
||||
|
||||
/* $<packet info>#<Checksum>. */
|
||||
do
|
||||
/* $<packet info>#<Checksum>. */
|
||||
do
|
||||
{
|
||||
GdbPutChar('$');
|
||||
Checksum = 0;
|
||||
Count = 0;
|
||||
GdbPutChar('$');
|
||||
Checksum = 0;
|
||||
Count = 0;
|
||||
|
||||
while ((ch = Buffer[Count]))
|
||||
while ((ch = Buffer[Count]))
|
||||
{
|
||||
GdbPutChar(ch);
|
||||
Checksum += ch;
|
||||
Count += 1;
|
||||
GdbPutChar(ch);
|
||||
Checksum += ch;
|
||||
Count += 1;
|
||||
}
|
||||
|
||||
GdbPutChar('#');
|
||||
GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
|
||||
GdbPutChar(HexChars[Checksum & 0xf]);
|
||||
GdbPutChar('#');
|
||||
GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
|
||||
GdbPutChar(HexChars[Checksum & 0xf]);
|
||||
}
|
||||
while (GdbGetChar() != '+');
|
||||
while (GdbGetChar() != '+');
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
GspPutPacketNoWait(PCHAR Buffer)
|
||||
{
|
||||
CHAR Checksum;
|
||||
LONG Count;
|
||||
CHAR ch;
|
||||
CHAR Checksum;
|
||||
LONG Count;
|
||||
CHAR ch;
|
||||
|
||||
/* $<packet info>#<Checksum>. */
|
||||
GdbPutChar('$');
|
||||
Checksum = 0;
|
||||
Count = 0;
|
||||
/* $<packet info>#<Checksum>. */
|
||||
GdbPutChar('$');
|
||||
Checksum = 0;
|
||||
Count = 0;
|
||||
|
||||
while ((ch = Buffer[Count]))
|
||||
while ((ch = Buffer[Count]))
|
||||
{
|
||||
GdbPutChar(ch);
|
||||
Checksum += ch;
|
||||
Count += 1;
|
||||
GdbPutChar(ch);
|
||||
Checksum += ch;
|
||||
Count += 1;
|
||||
}
|
||||
|
||||
GdbPutChar('#');
|
||||
GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
|
||||
GdbPutChar(HexChars[Checksum & 0xf]);
|
||||
GdbPutChar('#');
|
||||
GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
|
||||
GdbPutChar(HexChars[Checksum & 0xf]);
|
||||
}
|
||||
|
||||
/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an
|
||||
|
@ -308,19 +298,33 @@ static volatile void *GspAccessLocation = NULL;
|
|||
static CHAR
|
||||
GspReadMemSafe(PCHAR Address)
|
||||
{
|
||||
CHAR ch;
|
||||
CHAR ch;
|
||||
|
||||
if (NULL == Address)
|
||||
if (NULL == Address)
|
||||
{
|
||||
GspMemoryError = TRUE;
|
||||
return '\0';
|
||||
GspMemoryError = TRUE;
|
||||
return '\0';
|
||||
}
|
||||
|
||||
GspAccessLocation = Address;
|
||||
ch = *Address;
|
||||
GspAccessLocation = NULL;
|
||||
GspAccessLocation = Address;
|
||||
ch = *Address;
|
||||
GspAccessLocation = NULL;
|
||||
|
||||
return ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
static CHAR
|
||||
GspWriteMemSafeGetContent(PVOID Context, ULONG Offset)
|
||||
{
|
||||
ASSERT(0 == Offset);
|
||||
return *((PCHAR) Context);
|
||||
}
|
||||
|
||||
static void
|
||||
GspWriteMemSafe(PCHAR Address,
|
||||
CHAR Ch)
|
||||
{
|
||||
GspWriteMem(Address, 1, TRUE, GspWriteMemSafeGetContent, &Ch);
|
||||
}
|
||||
|
||||
/* Convert the memory pointed to by Address into hex, placing result in Buffer */
|
||||
|
@ -329,131 +333,110 @@ GspReadMemSafe(PCHAR Address)
|
|||
a fault; if FALSE treat a fault like any other fault in the stub. */
|
||||
static PCHAR
|
||||
GspMem2Hex(PCHAR Address,
|
||||
PCHAR Buffer,
|
||||
LONG Count,
|
||||
BOOLEAN MayFault)
|
||||
PCHAR Buffer,
|
||||
LONG Count,
|
||||
BOOLEAN MayFault)
|
||||
{
|
||||
ULONG i;
|
||||
CHAR ch;
|
||||
ULONG i;
|
||||
CHAR ch;
|
||||
|
||||
for (i = 0; i < (ULONG) Count; i++)
|
||||
for (i = 0; i < (ULONG) Count; i++)
|
||||
{
|
||||
if (MayFault)
|
||||
if (MayFault)
|
||||
{
|
||||
ch = GspReadMemSafe(Address);
|
||||
if (GspMemoryError)
|
||||
{
|
||||
return Buffer;
|
||||
}
|
||||
ch = GspReadMemSafe(Address);
|
||||
if (GspMemoryError)
|
||||
return Buffer;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
ch = *Address;
|
||||
ch = *Address;
|
||||
}
|
||||
*Buffer++ = HexChars[(ch >> 4) & 0xf];
|
||||
*Buffer++ = HexChars[ch & 0xf];
|
||||
Address++;
|
||||
*Buffer++ = HexChars[(ch >> 4) & 0xf];
|
||||
*Buffer++ = HexChars[ch & 0xf];
|
||||
Address++;
|
||||
}
|
||||
|
||||
*Buffer = 0;
|
||||
return Buffer;
|
||||
*Buffer = 0;
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
static ULONG
|
||||
GspWriteMem(PCHAR Address,
|
||||
ULONG Count,
|
||||
BOOLEAN MayFault,
|
||||
CHAR (*GetContent)(PVOID Context, ULONG Offset),
|
||||
PVOID Context)
|
||||
ULONG Count,
|
||||
BOOLEAN MayFault,
|
||||
CHAR (*GetContent)(PVOID Context, ULONG Offset),
|
||||
PVOID Context)
|
||||
{
|
||||
PCHAR Current;
|
||||
PCHAR Page;
|
||||
ULONG CountInPage;
|
||||
ULONG i;
|
||||
CHAR ch;
|
||||
ULONG OldProt = 0;
|
||||
PCHAR Current;
|
||||
PCHAR Page;
|
||||
ULONG CountInPage;
|
||||
ULONG i;
|
||||
CHAR ch;
|
||||
ULONG OldProt = 0;
|
||||
|
||||
Current = Address;
|
||||
while (Current < Address + Count)
|
||||
Current = Address;
|
||||
while (Current < Address + Count)
|
||||
{
|
||||
Page = (PCHAR)PAGE_ROUND_DOWN(Current);
|
||||
if (Address + Count <= Page + PAGE_SIZE)
|
||||
Page = (PCHAR)PAGE_ROUND_DOWN(Current);
|
||||
if (Address + Count <= Page + PAGE_SIZE)
|
||||
{
|
||||
/* Fits in this page */
|
||||
CountInPage = Count;
|
||||
/* Fits in this page */
|
||||
CountInPage = Count;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
/* Flows into next page, handle only current page in this iteration */
|
||||
CountInPage = PAGE_SIZE - (Address - Page);
|
||||
/* Flows into next page, handle only current page in this iteration */
|
||||
CountInPage = PAGE_SIZE - (Address - Page);
|
||||
}
|
||||
if (MayFault)
|
||||
if (MayFault)
|
||||
{
|
||||
OldProt = MmGetPageProtect(NULL, Address);
|
||||
MmSetPageProtect(NULL, Address, PAGE_EXECUTE_READWRITE);
|
||||
OldProt = MmGetPageProtect(NULL, Address);
|
||||
MmSetPageProtect(NULL, Address, PAGE_EXECUTE_READWRITE);
|
||||
}
|
||||
|
||||
for (i = 0; i < CountInPage && ! GspMemoryError; i++)
|
||||
for (i = 0; i < CountInPage && ! GspMemoryError; i++)
|
||||
{
|
||||
ch = (*GetContent)(Context, Current - Address);
|
||||
ch = (*GetContent)(Context, Current - Address);
|
||||
|
||||
if (MayFault)
|
||||
{
|
||||
GspAccessLocation = Current;
|
||||
}
|
||||
*Current = ch;
|
||||
if (MayFault)
|
||||
{
|
||||
GspAccessLocation = NULL;
|
||||
}
|
||||
Current++;
|
||||
if (MayFault)
|
||||
GspAccessLocation = Current;
|
||||
|
||||
*Current = ch;
|
||||
|
||||
if (MayFault)
|
||||
GspAccessLocation = NULL;
|
||||
|
||||
Current++;
|
||||
}
|
||||
if (MayFault)
|
||||
if (MayFault)
|
||||
{
|
||||
MmSetPageProtect(NULL, Page, OldProt);
|
||||
if (GspMemoryError)
|
||||
{
|
||||
return Current - Address;
|
||||
}
|
||||
MmSetPageProtect(NULL, Page, OldProt);
|
||||
if (GspMemoryError)
|
||||
return Current - Address;
|
||||
}
|
||||
}
|
||||
|
||||
return Current - Address;
|
||||
return Current - Address;
|
||||
}
|
||||
|
||||
static CHAR
|
||||
GspHex2MemGetContent(PVOID Context, ULONG Offset)
|
||||
{
|
||||
return (CHAR)((HexValue(*((PCHAR) Context + 2 * Offset)) << 4) +
|
||||
HexValue(*((PCHAR) Context + 2 * Offset + 1)));
|
||||
return (CHAR)((HexValue(*((PCHAR) Context + 2 * Offset)) << 4) +
|
||||
HexValue(*((PCHAR) Context + 2 * Offset + 1)));
|
||||
}
|
||||
|
||||
/* Convert the hex array pointed to by Buffer into binary to be placed at Address */
|
||||
/* Return a pointer to the character AFTER the last byte read from Buffer */
|
||||
static PCHAR
|
||||
GspHex2Mem(PCHAR Buffer,
|
||||
PCHAR Address,
|
||||
ULONG Count,
|
||||
BOOLEAN MayFault)
|
||||
PCHAR Address,
|
||||
ULONG Count,
|
||||
BOOLEAN MayFault)
|
||||
{
|
||||
Count = GspWriteMem(Address, Count, MayFault, GspHex2MemGetContent, Buffer);
|
||||
|
||||
return Buffer + 2 * Count;
|
||||
}
|
||||
|
||||
static CHAR
|
||||
GspWriteMemSafeGetContent(PVOID Context, ULONG Offset)
|
||||
{
|
||||
ASSERT(0 == Offset);
|
||||
|
||||
return *((PCHAR) Context);
|
||||
}
|
||||
|
||||
static void
|
||||
GspWriteMemSafe(PCHAR Address,
|
||||
CHAR Ch)
|
||||
{
|
||||
GspWriteMem(Address, 1, TRUE, GspWriteMemSafeGetContent, &Ch);
|
||||
Count = GspWriteMem(Address, Count, MayFault, GspHex2MemGetContent, Buffer);
|
||||
return Buffer + 2 * Count;
|
||||
}
|
||||
|
||||
|
||||
|
@ -462,33 +445,38 @@ GspWriteMemSafe(PCHAR Address,
|
|||
ULONG
|
||||
GspComputeSignal(NTSTATUS ExceptionCode)
|
||||
{
|
||||
ULONG SigVal;
|
||||
ULONG SigVal;
|
||||
|
||||
switch (ExceptionCode)
|
||||
switch (ExceptionCode)
|
||||
{
|
||||
case STATUS_INTEGER_DIVIDE_BY_ZERO:
|
||||
SigVal = 8; /* divide by zero */
|
||||
break;
|
||||
case STATUS_SINGLE_STEP:
|
||||
case STATUS_BREAKPOINT:
|
||||
SigVal = 5; /* breakpoint */
|
||||
break;
|
||||
case STATUS_INTEGER_OVERFLOW:
|
||||
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
||||
SigVal = 16; /* bound instruction */
|
||||
break;
|
||||
case STATUS_ILLEGAL_INSTRUCTION:
|
||||
SigVal = 4; /* Invalid opcode */
|
||||
break;
|
||||
case STATUS_STACK_OVERFLOW:
|
||||
case STATUS_DATATYPE_MISALIGNMENT:
|
||||
case STATUS_ACCESS_VIOLATION:
|
||||
SigVal = 11; /* access violation */
|
||||
break;
|
||||
default:
|
||||
SigVal = 7; /* "software generated" */
|
||||
case STATUS_INTEGER_DIVIDE_BY_ZERO:
|
||||
SigVal = 8; /* divide by zero */
|
||||
break;
|
||||
|
||||
case STATUS_SINGLE_STEP:
|
||||
case STATUS_BREAKPOINT:
|
||||
SigVal = 5; /* breakpoint */
|
||||
break;
|
||||
|
||||
case STATUS_INTEGER_OVERFLOW:
|
||||
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
||||
SigVal = 16; /* bound instruction */
|
||||
break;
|
||||
|
||||
case STATUS_ILLEGAL_INSTRUCTION:
|
||||
SigVal = 4; /* Invalid opcode */
|
||||
break;
|
||||
|
||||
case STATUS_STACK_OVERFLOW:
|
||||
case STATUS_DATATYPE_MISALIGNMENT:
|
||||
case STATUS_ACCESS_VIOLATION:
|
||||
SigVal = 11; /* access violation */
|
||||
break;
|
||||
|
||||
default:
|
||||
SigVal = 7; /* "software generated" */
|
||||
}
|
||||
return SigVal;
|
||||
return SigVal;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1626,43 +1614,39 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
BOOLEAN
|
||||
NTAPI
|
||||
GspBreakIn(PKINTERRUPT Interrupt,
|
||||
PVOID ServiceContext)
|
||||
PVOID ServiceContext)
|
||||
{
|
||||
PKTRAP_FRAME TrapFrame;
|
||||
BOOLEAN DoBreakIn;
|
||||
CONTEXT Context;
|
||||
KIRQL OldIrql;
|
||||
UCHAR Value;
|
||||
PKTRAP_FRAME TrapFrame;
|
||||
BOOLEAN DoBreakIn;
|
||||
CONTEXT Context;
|
||||
KIRQL OldIrql;
|
||||
UCHAR Value;
|
||||
|
||||
DPRINT("Break In\n");
|
||||
DPRINT("Break In\n");
|
||||
|
||||
DoBreakIn = FALSE;
|
||||
while (KdPortGetByteEx(&GdbPortInfo, &Value))
|
||||
DoBreakIn = FALSE;
|
||||
while (KdPortGetByteEx(&GdbPortInfo, &Value))
|
||||
{
|
||||
if (Value == 0x03)
|
||||
{
|
||||
DoBreakIn = TRUE;
|
||||
}
|
||||
if (Value == 0x03)
|
||||
DoBreakIn = TRUE;
|
||||
}
|
||||
|
||||
if (!DoBreakIn)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (!DoBreakIn)
|
||||
return TRUE;
|
||||
|
||||
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||||
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||||
|
||||
TrapFrame = PsGetCurrentThread()->Tcb.TrapFrame;
|
||||
TrapFrame = PsGetCurrentThread()->Tcb.TrapFrame;
|
||||
|
||||
KeTrapFrameToContext(TrapFrame, NULL, &Context);
|
||||
KeTrapFrameToContext(TrapFrame, NULL, &Context);
|
||||
|
||||
KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
|
||||
KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
|
||||
|
||||
KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags, KernelMode);
|
||||
KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags, KernelMode);
|
||||
|
||||
KeLowerIrql(OldIrql);
|
||||
KeLowerIrql(OldIrql);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -1677,39 +1661,36 @@ NTAPI
|
|||
KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable,
|
||||
ULONG BootPhase)
|
||||
{
|
||||
if (!KdDebuggerEnabled || !KdpDebugMode.Gdb)
|
||||
if (!KdDebuggerEnabled || !KdpDebugMode.Gdb)
|
||||
return;
|
||||
|
||||
if (BootPhase == 0)
|
||||
{
|
||||
return;
|
||||
ExInitializeFastMutex(&GspLock);
|
||||
|
||||
/* Write out the functions that we support for now */
|
||||
WrapperTable->KdpInitRoutine = KdpGdbStubInit;
|
||||
WrapperTable->KdpPrintRoutine = KdpGdbDebugPrint;
|
||||
WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
|
||||
|
||||
/* Initialize the Port */
|
||||
KdPortInitializeEx(&GdbPortInfo, GdbPortNumber);
|
||||
// KdpPort = GdbPortInfo.ComPort;
|
||||
}
|
||||
|
||||
if (BootPhase == 0)
|
||||
else if (BootPhase == 1)
|
||||
{
|
||||
ExInitializeFastMutex(&GspLock);
|
||||
GspInitialized = TRUE;
|
||||
|
||||
/* Write out the functions that we support for now */
|
||||
WrapperTable->KdpInitRoutine = KdpGdbStubInit;
|
||||
WrapperTable->KdpPrintRoutine = KdpGdbDebugPrint;
|
||||
WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
|
||||
GspRunThread = NULL;
|
||||
GspDbgThread = NULL;
|
||||
GspEnumThread = NULL;
|
||||
|
||||
/* Initialize the Port */
|
||||
KdPortInitializeEx(&GdbPortInfo, 0, 0);
|
||||
|
||||
KdpPort = GdbPortInfo.ComPort;
|
||||
HalDisplayString("Waiting for GDB to attach\n");
|
||||
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
|
||||
}
|
||||
else if (BootPhase == 1)
|
||||
else if (BootPhase == 2)
|
||||
{
|
||||
GspInitialized = TRUE;
|
||||
|
||||
GspRunThread = NULL;
|
||||
GspDbgThread = NULL;
|
||||
GspEnumThread = NULL;
|
||||
|
||||
HalDisplayString("Waiting for GDB to attach\n");
|
||||
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
|
||||
}
|
||||
else if (BootPhase == 2)
|
||||
{
|
||||
HalDisplayString("\n GDB debugging enabled\n\n");
|
||||
HalDisplayString("\n GDB debugging enabled\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
# define RTL_NUMBER_OF(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/* formerly located in kdbg/kdb_symbols.c */
|
||||
#define TAG_KDBS 'SBDK'
|
||||
#define TAG_KDBG 'GBDK'
|
||||
|
||||
/* TYPES *********************************************************************/
|
||||
|
||||
/* from kdb.c */
|
||||
|
|
Loading…
Reference in a new issue