diff --git a/reactos/boot/freeldr/freeldr/disk/scsiport.c b/reactos/boot/freeldr/freeldr/disk/scsiport.c index 280a1c7bc8d..aaa9db9fdf2 100644 --- a/reactos/boot/freeldr/freeldr/disk/scsiport.c +++ b/reactos/boot/freeldr/freeldr/disk/scsiport.c @@ -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; diff --git a/reactos/boot/freeldr/freeldr/windows/peloader.c b/reactos/boot/freeldr/freeldr/windows/peloader.c index 90faea1f3b8..52aae9728ba 100644 --- a/reactos/boot/freeldr/freeldr/windows/peloader.c +++ b/reactos/boot/freeldr/freeldr/windows/peloader.c @@ -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; } diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index 4be74559783..130696327fb 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -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; } } - - diff --git a/reactos/drivers/base/CMakeLists.txt b/reactos/drivers/base/CMakeLists.txt index 9c5f5ee767b..af805ceb1da 100644 --- a/reactos/drivers/base/CMakeLists.txt +++ b/reactos/drivers/base/CMakeLists.txt @@ -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) diff --git a/reactos/drivers/base/kdcom/CMakeLists.txt b/reactos/drivers/base/kdcom/CMakeLists.txt index e8b25df67ac..448cd8f21e9 100644 --- a/reactos/drivers/base/kdcom/CMakeLists.txt +++ b/reactos/drivers/base/kdcom/CMakeLists.txt @@ -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) diff --git a/reactos/drivers/base/kddll/kdcom.c b/reactos/drivers/base/kdcom/kdcom.c similarity index 99% rename from reactos/drivers/base/kddll/kdcom.c rename to reactos/drivers/base/kdcom/kdcom.c index 3463fedfb5f..aa147f6bc30 100644 --- a/reactos/drivers/base/kddll/kdcom.c +++ b/reactos/drivers/base/kdcom/kdcom.c @@ -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}; diff --git a/reactos/drivers/base/kdcom/kdcom.rc b/reactos/drivers/base/kdcom/kdcom.rc index 4081286574c..514ce731597 100644 --- a/reactos/drivers/base/kdcom/kdcom.rc +++ b/reactos/drivers/base/kdcom/kdcom.rc @@ -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 diff --git a/reactos/drivers/base/kdcom/kdcom.spec b/reactos/drivers/base/kdcom/kdcom.spec index 64f642e2ae4..4098dd6e2ad 100644 --- a/reactos/drivers/base/kdcom/kdcom.spec +++ b/reactos/drivers/base/kdcom/kdcom.spec @@ -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) diff --git a/reactos/drivers/base/kddll/kddll.c b/reactos/drivers/base/kdcom/kddll.c similarity index 100% rename from reactos/drivers/base/kddll/kddll.c rename to reactos/drivers/base/kdcom/kddll.c diff --git a/reactos/drivers/base/kddll/kddll.h b/reactos/drivers/base/kdcom/kddll.h similarity index 100% rename from reactos/drivers/base/kddll/kddll.h rename to reactos/drivers/base/kdcom/kddll.h diff --git a/reactos/drivers/base/kddll/kdserial.c b/reactos/drivers/base/kdcom/kdserial.c similarity index 100% rename from reactos/drivers/base/kddll/kdserial.c rename to reactos/drivers/base/kdcom/kdserial.c diff --git a/reactos/drivers/base/kddll/kddll.spec b/reactos/drivers/base/kddll/kddll.spec deleted file mode 100644 index 4098dd6e2ad..00000000000 --- a/reactos/drivers/base/kddll/kddll.spec +++ /dev/null @@ -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) diff --git a/reactos/drivers/base/kddll/CMakeLists.txt b/reactos/drivers/base/kdrosdbg/CMakeLists.txt similarity index 69% rename from reactos/drivers/base/kddll/CMakeLists.txt rename to reactos/drivers/base/kdrosdbg/CMakeLists.txt index 448cd8f21e9..038ccdbb41b 100644 --- a/reactos/drivers/base/kddll/CMakeLists.txt +++ b/reactos/drivers/base/kdrosdbg/CMakeLists.txt @@ -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) diff --git a/reactos/drivers/base/kdrosdbg/kdrosdbg.c b/reactos/drivers/base/kdrosdbg/kdrosdbg.c new file mode 100644 index 00000000000..e8cccf93cc1 --- /dev/null +++ b/reactos/drivers/base/kdrosdbg/kdrosdbg.c @@ -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 +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +/* 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 */ diff --git a/reactos/drivers/base/kddll/kdcom.rc b/reactos/drivers/base/kdrosdbg/kdrosdbg.rc similarity index 65% rename from reactos/drivers/base/kddll/kdcom.rc rename to reactos/drivers/base/kdrosdbg/kdrosdbg.rc index 514ce731597..4081286574c 100644 --- a/reactos/drivers/base/kddll/kdcom.rc +++ b/reactos/drivers/base/kdrosdbg/kdrosdbg.rc @@ -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 diff --git a/reactos/drivers/base/kddll/kdcom.spec b/reactos/drivers/base/kdrosdbg/kdrosdbg.spec similarity index 100% rename from reactos/drivers/base/kddll/kdcom.spec rename to reactos/drivers/base/kdrosdbg/kdrosdbg.spec diff --git a/reactos/include/reactos/windbgkd.h b/reactos/include/reactos/windbgkd.h index 920f4ecddba..42e99f05964 100644 --- a/reactos/include/reactos/windbgkd.h +++ b/reactos/include/reactos/windbgkd.h @@ -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; diff --git a/reactos/ntoskrnl/CMakeLists.txt b/reactos/ntoskrnl/CMakeLists.txt index 381b7bcee59..391868aecd5 100644 --- a/reactos/ntoskrnl/CMakeLists.txt +++ b/reactos/ntoskrnl/CMakeLists.txt @@ -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() diff --git a/reactos/ntoskrnl/include/internal/kd.h b/reactos/ntoskrnl/include/internal/kd.h index 9e2d4361157..0943e546962 100644 --- a/reactos/ntoskrnl/include/internal/kd.h +++ b/reactos/ntoskrnl/include/internal/kd.h @@ -1,5 +1,7 @@ #pragma once +#include + #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]; diff --git a/reactos/ntoskrnl/include/internal/tag.h b/reactos/ntoskrnl/include/internal/tag.h index d2fd01d135c..2ab910d379f 100644 --- a/reactos/ntoskrnl/include/internal/tag.h +++ b/reactos/ntoskrnl/include/internal/tag.h @@ -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 */ diff --git a/reactos/ntoskrnl/kd/arm/kdbg.c b/reactos/ntoskrnl/kd/arm/kdbg.c new file mode 100644 index 00000000000..375ddcbf867 --- /dev/null +++ b/reactos/ntoskrnl/kd/arm/kdbg.c @@ -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 +#include +#define NDEBUG +#include + +/* 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 */ diff --git a/reactos/ntoskrnl/kd/i386/kdbg.c b/reactos/ntoskrnl/kd/i386/kdbg.c new file mode 100644 index 00000000000..93084d69b68 --- /dev/null +++ b/reactos/ntoskrnl/kd/i386/kdbg.c @@ -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 +#define NDEBUG +#include + + +#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 */ diff --git a/reactos/ntoskrnl/kd/kdinit.c b/reactos/ntoskrnl/kd/kdinit.c index ac493850554..7a455a888e5 100644 --- a/reactos/ntoskrnl/kd/kdinit.c +++ b/reactos/ntoskrnl/kd/kdinit.c @@ -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; } } diff --git a/reactos/ntoskrnl/kd/kdio.c b/reactos/ntoskrnl/kd/kdio.c index aaeefbfa302..6d775685580 100644 --- a/reactos/ntoskrnl/kd/kdio.c +++ b/reactos/ntoskrnl/kd/kdio.c @@ -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); diff --git a/reactos/ntoskrnl/kd/wrappers/gdbstub.c b/reactos/ntoskrnl/kd/wrappers/gdbstub.c index 1278484897d..a15f736828e 100644 --- a/reactos/ntoskrnl/kd/wrappers/gdbstub.c +++ b/reactos/ntoskrnl/kd/wrappers/gdbstub.c @@ -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) { diff --git a/reactos/ntoskrnl/kd/wrappers/gdbstub_powerpc.c b/reactos/ntoskrnl/kd/wrappers/gdbstub_powerpc.c index 83ce48aca05..a62bd9a6b10 100644 --- a/reactos/ntoskrnl/kd/wrappers/gdbstub_powerpc.c +++ b/reactos/ntoskrnl/kd/wrappers/gdbstub_powerpc.c @@ -88,12 +88,8 @@ #include /************************************************************************/ -/* 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 $# */ @@ -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; - /* $#. */ - do + /* $#. */ + 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; - /* $#. */ - 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]); } /* 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"); } } diff --git a/reactos/ntoskrnl/kdbg/kdb.h b/reactos/ntoskrnl/kdbg/kdb.h index 55c6698f29b..7d4b4623111 100644 --- a/reactos/ntoskrnl/kdbg/kdb.h +++ b/reactos/ntoskrnl/kdbg/kdb.h @@ -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 */