Author: ion
Date: Sat Mar 3 07:39:25 2007
New Revision: 25965
URL:
http://svn.reactos.org/svn/reactos?rev=25965&view=rev
Log:
- Remove KD APIs from stub HAL, they've been in kdcom for a while (merge from
kd-branch).
- DebugPrint/DebugPrompt should have an int3 after the int2d, and the int2d handler should
++ the trap frame's EIP to compensate (merge from kd-branch).
- Remove KDB symbol hooks (merge from kd-branch).
- Make PSEH compialble in MSVC again after Greatlord's break.
- Fix KiSaveProcessorControlState/KiRestoreProcessorControlState (merge from kd-branch).
- Disable GDB hook/hacks (merge from kd-branch).
- Add KD64 directory from kd-branch with SharedUserData access enabled (no other code
changed). It's not currently compiled though, just putting it here.
Added:
trunk/reactos/ntoskrnl/kd64/
trunk/reactos/ntoskrnl/kd64/kdapi.c
trunk/reactos/ntoskrnl/kd64/kdbreak.c
trunk/reactos/ntoskrnl/kd64/kddata.c
trunk/reactos/ntoskrnl/kd64/kdinit.c
trunk/reactos/ntoskrnl/kd64/kdlock.c
trunk/reactos/ntoskrnl/kd64/kdprint.c
trunk/reactos/ntoskrnl/kd64/kdtrap.c
Modified:
trunk/reactos/hal/hal/hal.c
trunk/reactos/hal/halx86/generic/misc.c
trunk/reactos/include/reactos/libs/pseh/framebased.h
trunk/reactos/lib/rtl/debug.c
trunk/reactos/lib/rtl/i386/debug_asm.S
trunk/reactos/ntoskrnl/include/internal/ke.h
trunk/reactos/ntoskrnl/io/iomgr/driver.c
trunk/reactos/ntoskrnl/ke/i386/cpu.c
trunk/reactos/ntoskrnl/ke/i386/exp.c
trunk/reactos/ntoskrnl/ke/i386/trap.s
trunk/reactos/ntoskrnl/mm/rmap.c
trunk/reactos/ntoskrnl/mm/sysldr.c
trunk/reactos/ntoskrnl/ps/kill.c
Modified: trunk/reactos/hal/hal/hal.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/hal/hal.c?rev=25965&am…
==============================================================================
--- trunk/reactos/hal/hal/hal.c (original)
+++ trunk/reactos/hal/hal/hal.c Sat Mar 3 07:39:25 2007
@@ -17,7 +17,6 @@
#include <ndk/halfuncs.h>
#include <ndk/iofuncs.h>
#include <ndk/kdfuncs.h>
-#include <internal/kd.h>
#define NDEBUG
#include <debug.h>
@@ -727,132 +726,6 @@
}
-BOOLEAN
-NTAPI
-KdPortGetByte(
- PUCHAR ByteRecieved)
-{
- UNIMPLEMENTED;
-
- return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortGetByteEx(
- PKD_PORT_INFORMATION PortInformation,
- PUCHAR ByteRecieved)
-{
- UNIMPLEMENTED;
-
- return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortInitialize(
- PKD_PORT_INFORMATION PortInformation,
- ULONG Unknown1,
- ULONG Unknown2)
-{
- UNIMPLEMENTED;
-
- return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortInitializeEx(
- PKD_PORT_INFORMATION PortInformation,
- ULONG Unknown1,
- ULONG Unknown2)
-{
- UNIMPLEMENTED;
-
- return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortPollByte(
- PUCHAR ByteRecieved)
-{
- UNIMPLEMENTED;
-
- return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortPollByteEx(
- PKD_PORT_INFORMATION PortInformation,
- PUCHAR ByteRecieved)
-{
- UNIMPLEMENTED;
-
- return TRUE;
-}
-
-
-VOID
-NTAPI
-KdPortPutByte(
- UCHAR ByteToSend)
-{
- UNIMPLEMENTED;
-}
-
-
-VOID
-NTAPI
-KdPortPutByteEx(
- PKD_PORT_INFORMATION PortInformation,
- UCHAR ByteToSend)
-{
- UNIMPLEMENTED;
-}
-
-
-VOID
-NTAPI
-KdPortRestore(VOID)
-{
- UNIMPLEMENTED;
-}
-
-
-VOID
-NTAPI
-KdPortSave(VOID)
-{
- UNIMPLEMENTED;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortDisableInterrupts()
-{
- UNIMPLEMENTED;
-
- return FALSE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortEnableInterrupts()
-{
- UNIMPLEMENTED;
-
- return FALSE;
-}
-
#undef KeAcquireSpinLock
VOID
NTAPI
Modified: trunk/reactos/hal/halx86/generic/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/misc.c?…
==============================================================================
--- trunk/reactos/hal/halx86/generic/misc.c (original)
+++ trunk/reactos/hal/halx86/generic/misc.c Sat Mar 3 07:39:25 2007
@@ -77,7 +77,7 @@
/* Halt the system */
HalDisplayString("\n*** The system has halted ***\n");
- KeEnterKernelDebugger();
+ //KeEnterKernelDebugger();
}
/*
Modified: trunk/reactos/include/reactos/libs/pseh/framebased.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/pseh/…
==============================================================================
--- trunk/reactos/include/reactos/libs/pseh/framebased.h (original)
+++ trunk/reactos/include/reactos/libs/pseh/framebased.h Sat Mar 3 07:39:25 2007
@@ -73,14 +73,8 @@
_SEHPortableTryLevel_t * trylevel
)
{
- /*
- * help detetct if pseh going into endless loop
- * if we see this debug msg repet never break
- * we known something cause pseh going into
- * endless loop, but it should never happen
- */
+ _SEHTryLevel_t * mytrylevel;
DbgPrint("_SEHCompilerSpecificHandler(%p)\n", trylevel);
- _SEHTryLevel_t * mytrylevel;
mytrylevel = _SEH_CONTAINING_RECORD(trylevel, _SEHTryLevel_t, ST_Header);
_SEHLongJmp(mytrylevel->ST_JmpBuf, 1);
}
Modified: trunk/reactos/lib/rtl/debug.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/debug.c?rev=25965&…
==============================================================================
--- trunk/reactos/lib/rtl/debug.c (original)
+++ trunk/reactos/lib/rtl/debug.c Sat Mar 3 07:39:25 2007
@@ -23,6 +23,7 @@
IN ULONG Level)
{
/* Call the INT2D Service */
+ //return STATUS_SUCCESS;
return DebugService(BREAKPOINT_PRINT,
DebugString->Buffer,
DebugString->Length,
Modified: trunk/reactos/lib/rtl/i386/debug_asm.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/i386/debug_asm.S?r…
==============================================================================
--- trunk/reactos/lib/rtl/i386/debug_asm.S (original)
+++ trunk/reactos/lib/rtl/i386/debug_asm.S Sat Mar 3 07:39:25 2007
@@ -54,7 +54,7 @@
mov ecx, [ebp+8]
mov edx, [ebp+12]
int 0x2D
- //int 3
+ int 3
/* Restore stack */
pop ebp
@@ -82,7 +82,7 @@
mov ebx, [ebp+20]
mov edi, [ebp+24]
int 0x2D
- //int 3
+ int 3
/* Restore registers */
pop ebx
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h Sat Mar 3 07:39:25 2007
@@ -151,6 +151,7 @@
extern UCHAR KiDebugRegisterContextOffsets[9];
extern ULONG KeTimeIncrement;
extern ULONG_PTR KiBugCheckData[5];
+extern ULONG KiFreezeFlag;
/* MACROS *************************************************************************/
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/driver.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/driver.c Sat Mar 3 07:39:25 2007
@@ -874,9 +874,6 @@
}
#endif
- /* Load symbols */
- KDB_SYMBOLFILE_HOOK(ModuleName);
-
/*
* Strip the file extension from ServiceName
*/
@@ -926,9 +923,6 @@
{
PLIST_ENTRY ListHead, NextEntry;
PLDR_DATA_TABLE_ENTRY LdrEntry;
-#ifdef DBG
- UNICODE_STRING NtosSymName = RTL_CONSTANT_STRING(L"ntoskrnl.sym");
-#endif
PDEVICE_NODE DeviceNode;
PDRIVER_OBJECT DriverObject;
LDR_DATA_TABLE_ENTRY ModuleObject;
@@ -973,9 +967,6 @@
IopFreeDeviceNode(DeviceNode);
return;
}
-
- /* Hack for NTOSKRNL.SYM */
- KDB_SYMBOLFILE_HOOK(&NtosSymName);
/* Loop the boot modules */
ListHead = &KeLoaderBlock->LoadOrderListHead;
Added: trunk/reactos/ntoskrnl/kd64/kdapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdapi.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdapi.c (added)
+++ trunk/reactos/ntoskrnl/kd64/kdapi.c Sat Mar 3 07:39:25 2007
@@ -1,0 +1,1158 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/kd64/kdapi.c
+ * PURPOSE: KD64 Public Routines and Internal Support
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+KdpGetStateChange(IN PDBGKD_MANIPULATE_STATE64 State,
+ IN PCONTEXT Context)
+{
+ PKPRCB Prcb;
+ ULONG i;
+
+ /* Check for success */
+ if (NT_SUCCESS(State->u.Continue2.ContinueStatus))
+ {
+ /* Check if we're tracing */
+ if (State->u.Continue2.ControlSet.TraceFlag)
+ {
+ /* Enable TF */
+ Context->EFlags |= EFLAGS_TF;
+ }
+ else
+ {
+ /* Remove it */
+ Context->EFlags &= ~EFLAGS_TF;
+ }
+
+ /* Loop all processors */
+ for (i = 0; i < KeNumberProcessors; i++)
+ {
+ /* Get the PRCB and update DR7 and DR6 */
+ Prcb = KiProcessorBlock[i];
+ Prcb->ProcessorState.SpecialRegisters.KernelDr7 =
+ State->u.Continue2.ControlSet.Dr7;
+ Prcb->ProcessorState.SpecialRegisters.KernelDr6 = 0;
+ }
+
+ /* Check if we have new symbol information */
+ if (State->u.Continue2.ControlSet.CurrentSymbolStart != 1)
+ {
+ /* Update it */
+ KdpCurrentSymbolStart =
+ State->u.Continue2.ControlSet.CurrentSymbolStart;
+ KdpCurrentSymbolEnd= State->u.Continue2.ControlSet.CurrentSymbolEnd;
+ }
+ }
+}
+
+VOID
+NTAPI
+KdpSetCommonState(IN ULONG NewState,
+ IN PCONTEXT Context,
+ IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange)
+{
+ USHORT InstructionCount;
+ BOOLEAN HadBreakpoints;
+
+ /* Setup common stuff available for all CPU architectures */
+ WaitStateChange->NewState = NewState;
+ WaitStateChange->ProcessorLevel = KeProcessorLevel;
+ WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number;
+ WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors;
+ WaitStateChange->Thread = (ULONG)(LONG_PTR)KeGetCurrentThread();
+ WaitStateChange->ProgramCounter = (ULONG)(LONG_PTR)Context->Eip;
+
+ /* Zero out the Control Report */
+ RtlZeroMemory(&WaitStateChange->ControlReport,
+ sizeof(DBGKD_CONTROL_REPORT));
+
+ /* Now copy the instruction stream and set the count */
+ RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
+ (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
+ DBGKD_MAXSTREAM);
+ InstructionCount = DBGKD_MAXSTREAM;
+ WaitStateChange->ControlReport.InstructionCount = InstructionCount;
+
+ /* Clear all the breakpoints in this region */
+ HadBreakpoints = FALSE;
+#if 0
+ KdpDeleteBreakpointRange((PVOID)WaitStateChange->ProgramCounter,
+ (PVOID)(WaitStateChange->ProgramCounter +
+ WaitStateChange->ControlReport.
+ InstructionCount - 1));
+#endif
+ if (HadBreakpoints)
+ {
+ /* Copy the instruction stream again, this time without breakpoints */
+ RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
+ (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
+ WaitStateChange->ControlReport.InstructionCount);
+ }
+}
+
+VOID
+NTAPI
+KdpSetContextState(IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange,
+ IN PCONTEXT Context)
+{
+ PKPRCB Prcb = KeGetCurrentPrcb();
+
+ /* Copy i386 specific debug registers */
+ WaitStateChange->ControlReport.Dr6 = Prcb->ProcessorState.SpecialRegisters.
+ KernelDr6;
+ WaitStateChange->ControlReport.Dr7 = Prcb->ProcessorState.SpecialRegisters.
+ KernelDr7;
+
+ /* Copy i386 specific segments */
+ WaitStateChange->ControlReport.SegCs = (USHORT)Context->SegCs;
+ WaitStateChange->ControlReport.SegDs = (USHORT)Context->SegDs;
+ WaitStateChange->ControlReport.SegEs = (USHORT)Context->SegEs;
+ WaitStateChange->ControlReport.SegFs = (USHORT)Context->SegFs;
+
+ /* Copy EFlags */
+ WaitStateChange->ControlReport.EFlags = Context->EFlags;
+
+ /* Set Report Flags */
+ WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS;
+ if (WaitStateChange->ControlReport.SegCs == KGDT_R0_CODE)
+ {
+ WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_CS;
+ }
+}
+
+VOID
+NTAPI
+KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version)
+{
+ /* Copy the version block */
+ RtlCopyMemory(Version, &KdVersionBlock, sizeof(DBGKD_GET_VERSION64));
+}
+
+VOID
+NTAPI
+KdpGetVersion(IN PDBGKD_MANIPULATE_STATE64 State)
+{
+ STRING Header;
+
+ /* Fill out the header */
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
+ Header.Buffer = (PCHAR)State;
+
+ /* Get the version block */
+ KdpSysGetVersion(&State->u.GetVersion64);
+
+ /* Fill out the state */
+ State->ApiNumber = DbgKdGetVersionApi;
+ State->ReturnStatus = STATUS_SUCCESS;
+
+ /* Send the packet */
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
+ &Header,
+ NULL,
+ &KdpContext);
+}
+
+VOID
+NTAPI
+KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
+ IN PSTRING Data,
+ IN PCONTEXT Context)
+{
+ STRING Header;
+ ULONG Length = State->u.ReadMemory.TransferCount;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /* Validate length */
+ if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
+ {
+ /* Overflow, set it to maximum possible */
+ Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
+ }
+
+#if 0
+ if (!MmIsAddressValid((PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress))
+ {
+ Ke386SetCr2(State->u.ReadMemory.TargetBaseAddress);
+ while (TRUE);
+ }
+#endif
+
+ if ((ULONG_PTR)State->u.ReadMemory.TargetBaseAddress < KSEG0_BASE)
+ {
+ Length = 0;
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ else if ((ULONG_PTR)State->u.ReadMemory.TargetBaseAddress >=
(ULONG_PTR)SharedUserData)
+ {
+ Length = 0;
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ RtlCopyMemory(Data->Buffer,
+ (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress,
+ Length);
+ }
+
+ /* Fill out the header */
+ Data->Length = Length;
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
+ Header.Buffer = (PCHAR)State;
+
+ /* Fill out the state */
+ State->ReturnStatus = Status;
+ State->u.ReadMemory.ActualBytesRead = Length;
+
+ /* Send the packet */
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
+ &Header,
+ Data,
+ &KdpContext);
+}
+
+VOID
+NTAPI
+KdpReadControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
+ IN PSTRING Data,
+ IN PCONTEXT Context)
+{
+ PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
+ STRING Header;
+ ULONG Length, RealLength;
+ PVOID ControlStart;
+
+ /* Setup the header */
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
+ Header.Buffer = (PCHAR)State;
+ ASSERT(Data->Length == 0);
+
+ /* Check the length requested */
+ Length = ReadMemory->TransferCount;
+ if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
+ {
+ /* Use maximum allowed */
+ Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
+ }
+
+ /* Make sure that this is a valid request */
+ if (((ULONG)ReadMemory->TargetBaseAddress < sizeof(KPROCESSOR_STATE))
&&
+ (State->Processor < KeNumberProcessors))
+ {
+ /* Get the actual length */
+ RealLength = sizeof(KPROCESSOR_STATE) -
+ (ULONG_PTR)ReadMemory->TargetBaseAddress;
+ if (RealLength < Length) Length = RealLength;
+
+ /* Set the proper address */
+ ControlStart = (PVOID)((ULONG_PTR)ReadMemory->TargetBaseAddress +
+
(ULONG_PTR)&KiProcessorBlock[State->Processor]->
+ ProcessorState);
+
+ /* Copy the memory */
+ RtlCopyMemory(Data->Buffer, ControlStart, Length);
+ Data->Length = Length;
+
+ /* Finish up */
+ State->ReturnStatus = STATUS_SUCCESS;
+ ReadMemory->ActualBytesRead = Data->Length;
+ }
+ else
+ {
+ /* Invalid request */
+ Data->Length = 0;
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;
+ ReadMemory->ActualBytesRead = 0;
+ }
+
+ /* Send the reply */
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
+ &Header,
+ Data,
+ &KdpContext);
+}
+
+VOID
+NTAPI
+KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
+ IN PSTRING Data,
+ IN PCONTEXT Context)
+{
+ PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
+ STRING Header;
+ ULONG Length;
+ PVOID ControlStart;
+
+ /* Setup the header */
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
+ Header.Buffer = (PCHAR)State;
+
+ /* Make sure that this is a valid request */
+ Length = WriteMemory->TransferCount;
+ if ((((ULONG)WriteMemory->TargetBaseAddress + Length) <=
+ sizeof(KPROCESSOR_STATE)) &&
+ (State->Processor < KeNumberProcessors))
+ {
+ /* Set the proper address */
+ ControlStart = (PVOID)((ULONG_PTR)WriteMemory->TargetBaseAddress +
+
(ULONG_PTR)&KiProcessorBlock[State->Processor]->
+ ProcessorState);
+
+ /* Copy the memory */
+ RtlCopyMemory(ControlStart, Data->Buffer, Data->Length);
+ Length = Data->Length;
+
+ /* Finish up */
+ State->ReturnStatus = STATUS_SUCCESS;
+ WriteMemory->ActualBytesWritten = Length;
+ }
+ else
+ {
+ /* Invalid request */
+ Data->Length = 0;
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;
+ WriteMemory->ActualBytesWritten = 0;
+ }
+
+ /* Send the reply */
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
+ &Header,
+ Data,
+ &KdpContext);
+}
+
+VOID
+NTAPI
+KdpRestoreBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
+ IN PSTRING Data,
+ IN PCONTEXT Context)
+{
+ PDBGKD_RESTORE_BREAKPOINT RestoreBp = &State->u.RestoreBreakPoint;
+ STRING Header;
+
+ /* Fill out the header */
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
+ Header.Buffer = (PCHAR)State;
+ ASSERT(Data->Length == 0);
+
+ /* Get the version block */
+ if (KdpDeleteBreakpoint(RestoreBp->BreakPointHandle))
+ {
+ /* We're all good */
+ State->ReturnStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* We failed */
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ /* Send the packet */
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
+ &Header,
+ NULL,
+ &KdpContext);
+}
+
+VOID
+NTAPI
+KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State,
+ IN PSTRING Data,
+ IN PCONTEXT Context)
+{
+ STRING Header;
+ PVOID ControlStart;
+
+ /* Setup the header */
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
+ Header.Buffer = (PCHAR)State;
+ ASSERT(Data->Length == 0);
+
+ /* Make sure that this is a valid request */
+ if (State->Processor < KeNumberProcessors)
+ {
+ /* Check if the request is for this CPU */
+ if (State->Processor == KeGetCurrentPrcb()->Number)
+ {
+ /* We're just copying our own context */
+ ControlStart = Context;
+ }
+ else
+ {
+ /* SMP not yet handled */
+ ControlStart = NULL;
+ while (TRUE);
+ }
+
+ /* Copy the memory */
+ RtlCopyMemory(Data->Buffer, ControlStart, sizeof(CONTEXT));
+ Data->Length = sizeof(CONTEXT);
+
+ /* Finish up */
+ State->ReturnStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* Invalid request */
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ /* Send the reply */
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
+ &Header,
+ Data,
+ &KdpContext);
+}
+
+VOID
+NTAPI
+KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State,
+ IN PSTRING Data,
+ IN PCONTEXT Context)
+{
+ STRING Header;
+ PVOID ControlStart;
+
+ /* Setup the header */
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
+ Header.Buffer = (PCHAR)State;
+ ASSERT(Data->Length == sizeof(CONTEXT));
+
+ /* Make sure that this is a valid request */
+ if (State->Processor < KeNumberProcessors)
+ {
+ /* Check if the request is for this CPU */
+ if (State->Processor == KeGetCurrentPrcb()->Number)
+ {
+ /* We're just copying our own context */
+ ControlStart = Context;
+ }
+ else
+ {
+ /* SMP not yet handled */
+ ControlStart = NULL;
+ while (TRUE);
+ }
+
+ /* Copy the memory */
+ RtlCopyMemory(ControlStart, Data->Buffer, sizeof(CONTEXT));
+
+ /* Finish up */
+ State->ReturnStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* Invalid request */
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ /* Send the reply */
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
+ &Header,
+ Data,
+ &KdpContext);
+}
+
+KCONTINUE_STATUS
+NTAPI
+KdpSendWaitContinue(IN ULONG PacketType,
+ IN PSTRING SendHeader,
+ IN PSTRING SendData OPTIONAL,
+ IN OUT PCONTEXT Context)
+{
+ STRING Data, Header;
+ DBGKD_MANIPULATE_STATE64 ManipulateState;
+ ULONG Length;
+ KDSTATUS RecvCode;
+
+ /* Setup the Manipulate State structure */
+ Header.MaximumLength = sizeof(DBGKD_MANIPULATE_STATE64);
+ Header.Buffer = (PCHAR)&ManipulateState;
+ Data.MaximumLength = sizeof(KdpMessageBuffer);
+ Data.Buffer = KdpMessageBuffer;
+ //KdpContextSent = FALSE;
+
+SendPacket:
+ /* Send the Packet */
+ KdSendPacket(PacketType, SendHeader, SendData, &KdpContext);
+
+ /* If the debugger isn't present anymore, just return success */
+ if (KdDebuggerNotPresent) return ContinueSuccess;
+
+ /* Main processing Loop */
+ for (;;)
+ {
+ /* Receive Loop */
+ do
+ {
+ /* Wait to get a reply to our packet */
+ RecvCode = KdReceivePacket(PACKET_TYPE_KD_STATE_MANIPULATE,
+ &Header,
+ &Data,
+ &Length,
+ &KdpContext);
+
+ /* If we got a resend request, do it */
+ if (RecvCode == KdPacketNeedsResend) goto SendPacket;
+ } while (RecvCode == KdPacketTimedOut);
+
+ /* Now check what API we got */
+ switch (ManipulateState.ApiNumber)
+ {
+ case DbgKdReadVirtualMemoryApi:
+
+ /* Read virtual memory */
+ KdpReadVirtualMemory(&ManipulateState, &Data, Context);
+ break;
+
+ case DbgKdWriteVirtualMemoryApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdWriteVirtualMemoryApi);
+ while (TRUE);
+ break;
+
+ case DbgKdGetContextApi:
+
+ /* Get the current context */
+ KdpGetContext(&ManipulateState, &Data, Context);
+ break;
+
+ case DbgKdSetContextApi:
+
+ /* Set a new context */
+ KdpSetContext(&ManipulateState, &Data, Context);
+ break;
+
+ case DbgKdWriteBreakPointApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdWriteBreakPointApi);
+ while (TRUE);
+ break;
+
+ case DbgKdRestoreBreakPointApi:
+
+ /* FIXME: TODO */
+ KdpRestoreBreakpoint(&ManipulateState, &Data, Context);
+ break;
+
+ case DbgKdContinueApi:
+
+ /* Simply continue */
+ return NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus);
+
+ case DbgKdReadControlSpaceApi:
+
+ /* Read control space */
+ KdpReadControlSpace(&ManipulateState, &Data, Context);
+ break;
+
+ case DbgKdWriteControlSpaceApi:
+
+ /* FIXME: TODO */
+ KdpWriteControlSpace(&ManipulateState, &Data, Context);
+ break;
+
+ case DbgKdReadIoSpaceApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdReadIoSpaceApi);
+ while (TRUE);
+ break;
+
+ case DbgKdWriteIoSpaceApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdWriteIoSpaceApi);
+ while (TRUE);
+ break;
+
+ case DbgKdRebootApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdRebootApi);
+ while (TRUE);
+ break;
+
+ case DbgKdContinueApi2:
+
+ /* Check if caller reports success */
+ if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus))
+ {
+ /* Update the state */
+ KdpGetStateChange(&ManipulateState, Context);
+ return ContinueSuccess;
+ }
+ else
+ {
+ /* Return an error */
+ return ContinueError;
+ }
+ break;
+
+ case DbgKdReadPhysicalMemoryApi:
+
+ /* FIXME: TODO */
+ goto fail;
+ Ke386SetCr2(DbgKdReadPhysicalMemoryApi);
+ while (TRUE);
+ break;
+
+ case DbgKdWritePhysicalMemoryApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdWritePhysicalMemoryApi);
+ while (TRUE);
+ break;
+
+ case DbgKdQuerySpecialCallsApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdQuerySpecialCallsApi);
+ while (TRUE);
+ break;
+
+ case DbgKdSetSpecialCallApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdSetSpecialCallApi);
+ while (TRUE);
+ break;
+
+ case DbgKdClearSpecialCallsApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdClearSpecialCallsApi);
+ while (TRUE);
+ break;
+
+ case DbgKdSetInternalBreakPointApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdSetInternalBreakPointApi);
+ while (TRUE);
+ break;
+
+ case DbgKdGetInternalBreakPointApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdGetInternalBreakPointApi);
+ while (TRUE);
+ break;
+
+ case DbgKdReadIoSpaceExtendedApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdReadIoSpaceExtendedApi);
+ while (TRUE);
+ break;
+
+ case DbgKdWriteIoSpaceExtendedApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdWriteIoSpaceExtendedApi);
+ while (TRUE);
+ break;
+
+ case DbgKdGetVersionApi:
+
+ /* Get version data */
+ KdpGetVersion(&ManipulateState);
+ break;
+
+ case DbgKdWriteBreakPointExApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdWriteBreakPointExApi);
+ while (TRUE);
+ break;
+
+ case DbgKdRestoreBreakPointExApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdRestoreBreakPointExApi);
+ while (TRUE);
+ break;
+
+ case DbgKdCauseBugCheckApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdCauseBugCheckApi);
+ while (TRUE);
+ break;
+
+ case DbgKdSwitchProcessor:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdSwitchProcessor);
+ while (TRUE);
+ break;
+
+ case DbgKdPageInApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdPageInApi);
+ while (TRUE);
+ break;
+
+ case DbgKdReadMachineSpecificRegister:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdReadMachineSpecificRegister);
+ while (TRUE);
+ break;
+
+ case DbgKdWriteMachineSpecificRegister:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdWriteMachineSpecificRegister);
+ while (TRUE);
+ break;
+
+ case OldVlm1:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(OldVlm1);
+ while (TRUE);
+ break;
+
+ case OldVlm2:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(OldVlm2);
+ while (TRUE);
+ break;
+
+ case DbgKdSearchMemoryApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdSearchMemoryApi);
+ while (TRUE);
+ break;
+
+ case DbgKdGetBusDataApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdGetBusDataApi);
+ while (TRUE);
+ break;
+
+ case DbgKdSetBusDataApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdSetBusDataApi);
+ while (TRUE);
+ break;
+
+ case DbgKdCheckLowMemoryApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdCheckLowMemoryApi);
+ while (TRUE);
+ break;
+
+ case DbgKdClearAllInternalBreakpointsApi:
+
+ /* Just clear the counter */
+ KdpNumInternalBreakpoints = 0;
+ break;
+
+ case DbgKdFillMemoryApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdFillMemoryApi);
+ while (TRUE);
+ break;
+
+ case DbgKdQueryMemoryApi:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdQueryMemoryApi);
+ while (TRUE);
+ break;
+
+ case DbgKdSwitchPartition:
+
+ /* FIXME: TODO */
+ Ke386SetCr2(DbgKdSwitchPartition);
+ while (TRUE);
+ break;
+
+ /* Unsupported Message */
+ default:
+
+ /* Setup an empty message, with failure */
+ while (TRUE);
+fail:
+ Data.Length = 0;
+ ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;
+
+ /* Send it */
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
+ &Header,
+ &Data,
+ &KdpContext);
+ break;
+ }
+ }
+}
+
+BOOLEAN
+NTAPI
+KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
+ IN PKD_SYMBOLS_INFO SymbolInfo,
+ IN BOOLEAN Unload,
+ IN OUT PCONTEXT Context)
+{
+ PSTRING ExtraData;
+ STRING Data, Header;
+ DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;
+ KCONTINUE_STATUS Status;
+
+ /* Start wait loop */
+ do
+ {
+ /* Build the architecture common parts of the message */
+ KdpSetCommonState(DbgKdLoadSymbolsStateChange,
+ Context,
+ &WaitStateChange);
+
+ /* Now finish creating the structure */
+ KdpSetContextState(&WaitStateChange, Context);
+
+ /* Fill out load data */
+ WaitStateChange.u.LoadSymbols.UnloadSymbols = Unload;
+ WaitStateChange.u.LoadSymbols.BaseOfDll =
(ULONGLONG)(LONG_PTR)SymbolInfo->BaseOfDll;
+ WaitStateChange.u.LoadSymbols.ProcessId = SymbolInfo->ProcessId;
+ WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
+ WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
+
+ /* Check if we have a symbol name */
+ if (PathName)
+ {
+ /* Setup the information */
+ WaitStateChange.u.LoadSymbols.PathNameLength = PathName->Length;
+ RtlCopyMemory(KdpPathBuffer, PathName->Buffer, PathName->Length);
+ Data.Buffer = KdpPathBuffer;
+ Data.Length = WaitStateChange.u.LoadSymbols.PathNameLength;
+ ExtraData = &Data;
+ }
+ else
+ {
+ /* No name */
+ WaitStateChange.u.LoadSymbols.PathNameLength = 0;
+ ExtraData = NULL;
+ }
+
+ /* Setup the header */
+ Header.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64);
+ Header.Buffer = (PCHAR)&WaitStateChange;
+
+ /* Send the packet */
+ Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
+ &Header,
+ ExtraData,
+ Context);
+ } while(Status == ContinueProcessorReselected);
+
+ /* Return status */
+ return Status;
+}
+
+BOOLEAN
+NTAPI
+KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
+ IN OUT PCONTEXT Context,
+ IN BOOLEAN SecondChanceException)
+{
+ STRING Header, Data;
+ DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;
+ BOOLEAN Status;
+
+ /* Start report loop */
+ do
+ {
+ /* Build the architecture common parts of the message */
+ KdpSetCommonState(DbgKdExceptionStateChange, Context, &WaitStateChange);
+
+ /* Convert the exception record to 64-bits and set First Chance flag */
+ ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord,
+ &WaitStateChange.u.Exception.ExceptionRecord);
+ WaitStateChange.u.Exception.FirstChance = !SecondChanceException;
+
+ /* Now finish creating the structure */
+ KdpSetContextState(&WaitStateChange, Context);
+
+ /* Setup the actual header to send to KD */
+ Header.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64);
+ Header.Buffer = (PCHAR)&WaitStateChange;
+
+ /* Send State Change packet and wait for a reply */
+ Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
+ &Header,
+ &Data,
+ Context);
+ } while (Status == KdPacketNeedsResend);
+
+ /* Return */
+ return Status;
+}
+
+VOID
+NTAPI
+KdpTimeSlipDpcRoutine(IN PKDPC Dpc,
+ IN PVOID DeferredContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2)
+{
+ LONG OldSlip, NewSlip, PendingSlip;
+
+ /* Get the current pending slip */
+ PendingSlip = KdpTimeSlipPending;
+ do
+ {
+ /* Save the old value and either disable or enable it now. */
+ OldSlip = PendingSlip;
+ NewSlip = OldSlip > 1 ? 1 : 0;
+
+ /* Try to change the value */
+ } while (InterlockedCompareExchange(&KdpTimeSlipPending,
+ NewSlip,
+ OldSlip) != OldSlip);
+
+ /* If the New Slip value is 1, then do the Time Slipping */
+ if (NewSlip) ExQueueWorkItem(&KdpTimeSlipWorkItem, DelayedWorkQueue);
+}
+
+VOID
+NTAPI
+KdpTimeSlipWork(IN PVOID Context)
+{
+ KIRQL OldIrql;
+ LARGE_INTEGER DueTime;
+
+ /* Update the System time from the CMOS */
+ ExAcquireTimeRefreshLock(FALSE);
+ ExUpdateSystemTimeFromCmos(FALSE, 0);
+ ExReleaseTimeRefreshLock();
+
+ /* Check if we have a registered Time Slip Event and signal it */
+ KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql);
+ if (KdpTimeSlipEvent) KeSetEvent(KdpTimeSlipEvent, 0, FALSE);
+ KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql);
+
+ /* Delay the DPC until it runs next time */
+ DueTime.QuadPart = -1800000000;
+ KeSetTimer(&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc);
+}
+
+BOOLEAN
+NTAPI
+KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord,
+ IN OUT PCONTEXT ContextRecord,
+ IN BOOLEAN SecondChanceException)
+{
+ BOOLEAN Status;
+
+ /* Save the port data */
+ KdSave(FALSE);
+
+ /* Report a state change */
+#if 0
+ Status = KdpReportExceptionStateChange(ExceptionRecord,
+ ContextRecord,
+ SecondChanceException);
+#else
+ Status = FALSE;
+#endif
+
+ /* Restore the port data and return */
+ KdRestore(FALSE);
+ return Status;
+}
+
+LARGE_INTEGER
+NTAPI
+KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)
+{
+ LARGE_INTEGER Null = {{0}};
+
+ /* Check if interrupts were disabled */
+ if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
+ {
+ /* Nothing to return */
+ return Null;
+ }
+
+ /* Otherwise, do the call */
+ return KeQueryPerformanceCounter(NULL);
+}
+
+BOOLEAN
+NTAPI
+KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame)
+{
+ BOOLEAN Entered;
+
+ /* Check if we have a trap frame */
+ if (TrapFrame)
+ {
+ /* Calculate the time difference for the enter */
+ KdTimerStop = KdpQueryPerformanceCounter(TrapFrame);
+ KdTimerDifference.QuadPart = KdTimerStop.QuadPart -
+ KdTimerStart.QuadPart;
+ }
+ else
+ {
+ /* No trap frame, so can't calculate */
+ KdTimerStop.QuadPart = 0;
+ }
+
+ /* Save the current IRQL */
+ KeGetCurrentPrcb()->DebuggerSavedIRQL = KeGetCurrentIrql();
+
+ /* Freeze all CPUs */
+ Entered = KeFreezeExecution(TrapFrame, ExceptionFrame);
+
+ /* Lock the port, save the state and set debugger entered */
+ KdpPortLocked = KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock);
+ KdSave(FALSE);
+ KdEnteredDebugger = TRUE;
+
+ /* Check freeze flag */
+ if (KiFreezeFlag & 1)
+ {
+ /* Print out errror */
+ DbgPrint("FreezeLock was jammed! Backup SpinLock was used!\n");
+ }
+
+ /* Check processor state */
+ if (KiFreezeFlag & 2)
+ {
+ /* Print out errror */
+ DbgPrint("Some processors not frozen in debugger!\n");
+ }
+
+ /* Make sure we acquired the port */
+ if (!KdpPortLocked) DbgPrint("Port lock was not acquired!\n");
+
+ /* Return enter state */
+ return Entered;
+}
+
+VOID
+NTAPI
+KdExitDebugger(IN BOOLEAN Entered)
+{
+ ULONG TimeSlip;
+
+ /* Restore the state and unlock the port */
+ KdRestore(FALSE);
+ if (KdpPortLocked) KdpPortUnlock();
+
+ /* Unfreeze the CPUs */
+ KeThawExecution(Entered);
+
+ /* Compare time with the one from KdEnterDebugger */
+ if (!KdTimerStop.QuadPart)
+ {
+ /* We didn't get a trap frame earlier in so never got the time */
+ KdTimerStart = KdTimerStop;
+ }
+ else
+ {
+ /* Query the timer */
+ KdTimerStart = KeQueryPerformanceCounter(NULL);
+ }
+
+ /* Check if a Time Slip was on queue */
+ TimeSlip = InterlockedIncrement(&KdpTimeSlipPending);
+ if (TimeSlip == 1)
+ {
+ /* Queue a DPC for the time slip */
+ InterlockedIncrement(&KdpTimeSlipPending);
+ KeInsertQueueDpc(&KdpTimeSlipDpc, NULL, NULL);
+ }
+}
+
+NTSTATUS
+NTAPI
+KdEnableDebuggerWithLock(BOOLEAN NeedLock)
+{
+ KIRQL OldIrql = PASSIVE_LEVEL;
+
+ /* Check if we need to acquire the lock */
+ if (NeedLock)
+ {
+ /* Lock the port */
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+ KdpPortLock();
+ }
+
+ /* Check if we're not disabled */
+ if (!KdDisableCount)
+ {
+ /* Check if we had locked the port before */
+ if (NeedLock)
+ {
+ /* Do the unlock */
+ KeLowerIrql(OldIrql);
+ KdpPortUnlock();
+ }
+
+ /* Fail: We're already enabled */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Decrease the disable count */
+ if (!(--KdDisableCount))
+ {
+ /* We're now enabled again! Were we enabled before, too? */
+ if (KdPreviouslyEnabled)
+ {
+ /* Reinitialize the Debugger */
+ KdInitSystem(0, NULL) ;
+ KdpRestoreAllBreakpoints();
+ }
+ }
+
+ /* Check if we had locked the port before */
+ if (NeedLock)
+ {
+ /* Yes, now unlock it */
+ KeLowerIrql(OldIrql);
+ KdpPortUnlock();
+ }
+
+ /* We're done */
+ return STATUS_SUCCESS;
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+KdEnableDebugger(VOID)
+{
+ /* Use the internal routine */
+ while (TRUE);
+ return KdEnableDebuggerWithLock(TRUE);
+}
+
Added: trunk/reactos/ntoskrnl/kd64/kdbreak.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdbreak.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdbreak.c (added)
+++ trunk/reactos/ntoskrnl/kd64/kdbreak.c Sat Mar 3 07:39:25 2007
@@ -1,0 +1,149 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/kd64/kdbreak.c
+ * PURPOSE: KD64 Breakpoint Support
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+BOOLEAN
+NTAPI
+KdpLowWriteContent(IN ULONG BpIndex)
+{
+ /* Make sure that the breakpoint is actually active */
+ if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointPending)
+ {
+ /* So we have a valid breakpoint, but it hasn't been used yet... */
+ KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;
+ return TRUE;
+ }
+
+ /* Is the original instruction an INT3 anyway? */
+ if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction)
+ {
+ /* Then leave it that way... */
+ return TRUE;
+ }
+
+ /* We have an active breakpoint with an instruction to bring back. Do it. */
+ RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,
+ &KdpBreakpointTable[BpIndex].Content,
+ sizeof(UCHAR));
+
+ /* Everything went fine, return */
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+KdpLowRestoreBreakpoint(IN ULONG BpIndex)
+{
+ /* Were we not able to remove it earlier? */
+ if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired)
+ {
+ /* Well then, we'll just re-use it and return success! */
+ KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointExpired;
+ return TRUE;
+ }
+
+ /* Are we merely writing an INT3 on top of another INT3? */
+ if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction)
+ {
+ /* Nothing to do then... */
+ return TRUE;
+ }
+
+ /* Ok, we actually have to overwrite the instruction now */
+ RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,
+ &KdpBreakpointInstruction,
+ sizeof(UCHAR));
+
+ /* Clear any possible previous pending flag and return success */
+ KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+KdpDeleteBreakpoint(IN ULONG BpEntry)
+{
+ ULONG BpIndex = BpEntry - 1;
+
+ /* Check for invalid breakpoint entry */
+ if (!(BpEntry) || (BpEntry > 20)) return FALSE;
+
+ /* If the specified breakpoint table entry is not valid, then return FALSE. */
+ if (!KdpBreakpointTable[BpIndex].Flags) return FALSE;
+
+ /* Check if the breakpoint is suspended */
+ if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended)
+ {
+ /* Check if breakpoint is not ...? */
+ if (!(KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired))
+ {
+ /* Invalidate it and return success */
+ KdpBreakpointTable[BpIndex].Flags = 0;
+ return TRUE;
+ }
+ }
+
+ /* Restore original data, then invalidate it and return success */
+ if (KdpLowWriteContent(BpIndex)) KdpBreakpointTable[BpIndex].Flags = 0;
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+KdpDeleteBreakpointRange(IN PVOID Base,
+ IN PVOID Limit)
+{
+ ULONG BpIndex;
+ BOOLEAN Return = FALSE;
+
+ /* Loop the breakpoint table */
+ for (BpIndex = 0; BpIndex < 20; BpIndex++)
+ {
+ /* Make sure that the breakpoint is active and matches the range. */
+ if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
+ ((KdpBreakpointTable[BpIndex].Address >= Base) &&
+ (KdpBreakpointTable[BpIndex].Address <= Limit)))
+ {
+ /* Delete it */
+ Return = Return || KdpDeleteBreakpoint(BpIndex + 1);
+ }
+ }
+
+ /* Return to caller */
+ return Return;
+}
+
+VOID
+NTAPI
+KdpRestoreAllBreakpoints(VOID)
+{
+ ULONG BpIndex;
+
+ /* No more suspended Breakpoints */
+ BreakpointsSuspended = FALSE;
+
+ /* Loop the breakpoints */
+ for (BpIndex = 0; BpIndex < 20; BpIndex++ )
+ {
+ /* Check if they are valid, suspended breakpoints */
+ if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
+ (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended))
+ {
+ /* Unsuspend them */
+ KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointSuspended;
+ KdpLowRestoreBreakpoint(BpIndex);
+ }
+ }
+}
Added: trunk/reactos/ntoskrnl/kd64/kddata.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kddata.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kddata.c (added)
+++ trunk/reactos/ntoskrnl/kd64/kddata.c Sat Mar 3 07:39:25 2007
@@ -1,0 +1,467 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/kd64/kddata.c
+ * PURPOSE: Contains all global variables and settings for KD64
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+VOID NTAPI RtlpBreakWithStatusInstruction(VOID);
+
+/* GLOBALS *******************************************************************/
+
+//
+// Debugger State
+//
+KD_CONTEXT KdpContext;
+BOOLEAN KdpControlCPressed;
+BOOLEAN KdpControlCWaiting;
+BOOLEAN KdpPortLocked;
+KSPIN_LOCK KdpDebuggerLock;
+
+//
+// Debug Trap Handlers
+//
+PKDEBUG_ROUTINE KiDebugRoutine = KdpStub;
+PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
+
+//
+// Debugger Configuration Settings
+//
+BOOLEAN KdBreakAfterSymbolLoad;
+BOOLEAN KdPitchDebugger;
+BOOLEAN _KdDebuggerNotPresent;
+BOOLEAN _KdDebuggerEnabled;
+BOOLEAN KdAutoEnableOnEvent;
+BOOLEAN KdPreviouslyEnabled;
+BOOLEAN KdpDebuggerStructuresInitialized;
+BOOLEAN KdEnteredDebugger;
+ULONG KdDisableCount;
+LARGE_INTEGER KdPerformanceCounterRate;
+
+//
+// Breakpoint Data
+//
+BREAKPOINT_ENTRY KdpBreakpointTable[20];
+ULONG KdpBreakpointInstruction = 0xCC;
+BOOLEAN KdpOweBreakpoint;
+BOOLEAN BreakpointsSuspended;
+ULONG KdpNumInternalBreakpoints;
+
+ULONG KdpCurrentSymbolStart, KdpCurrentSymbolEnd;
+
+//
+// Time Slip Support
+//
+KDPC KdpTimeSlipDpc;
+KTIMER KdpTimeSlipTimer;
+WORK_QUEUE_ITEM KdpTimeSlipWorkItem;
+LONG KdpTimeSlipPending = 1;
+PKEVENT KdpTimeSlipEvent;
+KSPIN_LOCK KdpTimeSlipEventLock;
+LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;
+
+//
+// Buffers
+//
+CHAR KdpMessageBuffer[4096];
+CHAR KdpPathBuffer[4096];
+
+//
+// KdPrint Buffers
+//
+CHAR KdPrintDefaultCircularBuffer[0x8000];
+PCHAR KdPrintWritePointer = KdPrintDefaultCircularBuffer;
+ULONG KdPrintRolloverCount;
+PCHAR KdPrintCircularBuffer = KdPrintDefaultCircularBuffer;
+ULONG KdPrintBufferSize = sizeof(KdPrintDefaultCircularBuffer);
+ULONG KdPrintBufferChanges = 0;
+
+//
+// Debug Filter Masks
+//
+ULONG Kd_WIN2000_Mask = 1;
+ULONG Kd_SYSTEM_Mask;
+ULONG Kd_SMSS_Mask;
+ULONG Kd_SETUP_Mask;
+ULONG Kd_NTFS_Mask;
+ULONG Kd_FSTUB_Mask;
+ULONG Kd_CRASHDUMP_Mask;
+ULONG Kd_CDAUDIO_Mask;
+ULONG Kd_CDROM_Mask;
+ULONG Kd_CLASSPNP_Mask;
+ULONG Kd_DISK_Mask;
+ULONG Kd_REDBOOK_Mask;
+ULONG Kd_STORPROP_Mask;
+ULONG Kd_SCSIPORT_Mask;
+ULONG Kd_SCSIMINIPORT_Mask;
+ULONG Kd_CONFIG_Mask;
+ULONG Kd_I8042PRT_Mask;
+ULONG Kd_SERMOUSE_Mask;
+ULONG Kd_LSERMOUS_Mask;
+ULONG Kd_KBDHID_Mask;
+ULONG Kd_MOUHID_Mask;
+ULONG Kd_KBDCLASS_Mask;
+ULONG Kd_MOUCLASS_Mask;
+ULONG Kd_TWOTRACK_Mask;
+ULONG Kd_WMILIB_Mask;
+ULONG Kd_ACPI_Mask;
+ULONG Kd_AMLI_Mask;
+ULONG Kd_HALIA64_Mask;
+ULONG Kd_VIDEO_Mask;
+ULONG Kd_SVCHOST_Mask;
+ULONG Kd_VIDEOPRT_Mask;
+ULONG Kd_TCPIP_Mask;
+ULONG Kd_DMSYNTH_Mask;
+ULONG Kd_NTOSPNP_Mask;
+ULONG Kd_FASTFAT_Mask;
+ULONG Kd_SAMSS_Mask;
+ULONG Kd_PNPMGR_Mask;
+ULONG Kd_NETAPI_Mask;
+ULONG Kd_SCSERVER_Mask;
+ULONG Kd_SCCLIENT_Mask;
+ULONG Kd_SERIAL_Mask;
+ULONG Kd_SERENUM_Mask;
+ULONG Kd_UHCD_Mask;
+ULONG Kd_RPCPROXY_Mask;
+ULONG Kd_AUTOCHK_Mask;
+ULONG Kd_DCOMSS_Mask;
+ULONG Kd_UNIMODEM_Mask;
+ULONG Kd_SIS_Mask;
+ULONG Kd_FLTMGR_Mask;
+ULONG Kd_WMICORE_Mask;
+ULONG Kd_BURNENG_Mask;
+ULONG Kd_IMAPI_Mask;
+ULONG Kd_SXS_Mask;
+ULONG Kd_FUSION_Mask;
+ULONG Kd_IDLETASK_Mask;
+ULONG Kd_SOFTPCI_Mask;
+ULONG Kd_TAPE_Mask;
+ULONG Kd_MCHGR_Mask;
+ULONG Kd_IDEP_Mask;
+ULONG Kd_PCIIDE_Mask;
+ULONG Kd_FLOPPY_Mask;
+ULONG Kd_FDC_Mask;
+ULONG Kd_TERMSRV_Mask;
+ULONG Kd_W32TIME_Mask;
+ULONG Kd_PREFETCHER_Mask;
+ULONG Kd_RSFILTER_Mask;
+ULONG Kd_FCPORT_Mask;
+ULONG Kd_PCI_Mask;
+ULONG Kd_DMIO_Mask;
+ULONG Kd_DMCONFIG_Mask;
+ULONG Kd_DMADMIN_Mask;
+ULONG Kd_WSOCKTRANSPORT_Mask;
+ULONG Kd_VSS_Mask;
+ULONG Kd_PNPMEM_Mask;
+ULONG Kd_PROCESSOR_Mask;
+ULONG Kd_DMSERVER_Mask;
+ULONG Kd_SR_Mask;
+ULONG Kd_INFINIBAND_Mask;
+ULONG Kd_IHVDRIVER_Mask;
+ULONG Kd_IHVVIDEO_Mask;
+ULONG Kd_IHVAUDIO_Mask;
+ULONG Kd_IHVNETWORK_Mask;
+ULONG Kd_IHVSTREAMING_Mask;
+ULONG Kd_IHVBUS_Mask;
+ULONG Kd_HPS_Mask;
+ULONG Kd_RTLTHREADPOOL_Mask;
+ULONG Kd_LDR_Mask;
+ULONG Kd_TCPIP6_Mask;
+ULONG Kd_ISAPNP_Mask;
+ULONG Kd_SHPC_Mask;
+ULONG Kd_STORPORT_Mask;
+ULONG Kd_STORMINIPORT_Mask;
+ULONG Kd_PRINTSPOOLER_Mask;
+ULONG Kd_VSSDYNDISK_Mask;
+ULONG Kd_VERIFIER_Mask;
+ULONG Kd_VDS_Mask;
+ULONG Kd_VDSBAS_Mask;
+ULONG Kd_VDSDYNDR_Mask;
+ULONG Kd_VDSUTIL_Mask;
+ULONG Kd_DFRGIFC_Mask;
+ULONG Kd_DEFAULT_Mask;
+ULONG Kd_MM_Mask;
+ULONG Kd_DFSC_Mask;
+ULONG Kd_WOW64_Mask;
+ULONG Kd_ENDOFTABLE_Mask;
+
+//
+// Debug Filter Component Table
+//
+PULONG KdComponentTable[104] =
+{
+ &Kd_SYSTEM_Mask,
+ &Kd_SMSS_Mask,
+ &Kd_SETUP_Mask,
+ &Kd_NTFS_Mask,
+ &Kd_FSTUB_Mask,
+ &Kd_CRASHDUMP_Mask,
+ &Kd_CDAUDIO_Mask,
+ &Kd_CDROM_Mask,
+ &Kd_CLASSPNP_Mask,
+ &Kd_DISK_Mask,
+ &Kd_REDBOOK_Mask,
+ &Kd_STORPROP_Mask,
+ &Kd_SCSIPORT_Mask,
+ &Kd_SCSIMINIPORT_Mask,
+ &Kd_CONFIG_Mask,
+ &Kd_I8042PRT_Mask,
+ &Kd_SERMOUSE_Mask,
+ &Kd_LSERMOUS_Mask,
+ &Kd_KBDHID_Mask,
+ &Kd_MOUHID_Mask,
+ &Kd_KBDCLASS_Mask,
+ &Kd_MOUCLASS_Mask,
+ &Kd_TWOTRACK_Mask,
+ &Kd_WMILIB_Mask,
+ &Kd_ACPI_Mask,
+ &Kd_AMLI_Mask,
+ &Kd_HALIA64_Mask,
+ &Kd_VIDEO_Mask,
+ &Kd_SVCHOST_Mask,
+ &Kd_VIDEOPRT_Mask,
+ &Kd_TCPIP_Mask,
+ &Kd_DMSYNTH_Mask,
+ &Kd_NTOSPNP_Mask,
+ &Kd_FASTFAT_Mask,
+ &Kd_SAMSS_Mask,
+ &Kd_PNPMGR_Mask,
+ &Kd_NETAPI_Mask,
+ &Kd_SCSERVER_Mask,
+ &Kd_SCCLIENT_Mask,
+ &Kd_SERIAL_Mask,
+ &Kd_SERENUM_Mask,
+ &Kd_UHCD_Mask,
+ &Kd_RPCPROXY_Mask,
+ &Kd_AUTOCHK_Mask,
+ &Kd_DCOMSS_Mask,
+ &Kd_UNIMODEM_Mask,
+ &Kd_SIS_Mask,
+ &Kd_FLTMGR_Mask,
+ &Kd_WMICORE_Mask,
+ &Kd_BURNENG_Mask,
+ &Kd_IMAPI_Mask,
+ &Kd_SXS_Mask,
+ &Kd_FUSION_Mask,
+ &Kd_IDLETASK_Mask,
+ &Kd_SOFTPCI_Mask,
+ &Kd_TAPE_Mask,
+ &Kd_MCHGR_Mask,
+ &Kd_IDEP_Mask,
+ &Kd_PCIIDE_Mask,
+ &Kd_FLOPPY_Mask,
+ &Kd_FDC_Mask,
+ &Kd_TERMSRV_Mask,
+ &Kd_W32TIME_Mask,
+ &Kd_PREFETCHER_Mask,
+ &Kd_RSFILTER_Mask,
+ &Kd_FCPORT_Mask,
+ &Kd_PCI_Mask,
+ &Kd_DMIO_Mask,
+ &Kd_DMCONFIG_Mask,
+ &Kd_DMADMIN_Mask,
+ &Kd_WSOCKTRANSPORT_Mask,
+ &Kd_VSS_Mask,
+ &Kd_PNPMEM_Mask,
+ &Kd_PROCESSOR_Mask,
+ &Kd_DMSERVER_Mask,
+ &Kd_SR_Mask,
+ &Kd_INFINIBAND_Mask,
+ &Kd_IHVDRIVER_Mask,
+ &Kd_IHVVIDEO_Mask,
+ &Kd_IHVAUDIO_Mask,
+ &Kd_IHVNETWORK_Mask,
+ &Kd_IHVSTREAMING_Mask,
+ &Kd_IHVBUS_Mask,
+ &Kd_HPS_Mask,
+ &Kd_RTLTHREADPOOL_Mask,
+ &Kd_LDR_Mask,
+ &Kd_TCPIP6_Mask,
+ &Kd_ISAPNP_Mask,
+ &Kd_SHPC_Mask,
+ &Kd_STORPORT_Mask,
+ &Kd_STORMINIPORT_Mask,
+ &Kd_PRINTSPOOLER_Mask,
+ &Kd_VSSDYNDISK_Mask,
+ &Kd_VERIFIER_Mask,
+ &Kd_VDS_Mask,
+ &Kd_VDSBAS_Mask,
+ &Kd_VDSDYNDR_Mask,
+ &Kd_VDSUTIL_Mask,
+ &Kd_DFRGIFC_Mask,
+ &Kd_DEFAULT_Mask,
+ &Kd_MM_Mask,
+ &Kd_DFSC_Mask,
+ &Kd_WOW64_Mask,
+ &Kd_ENDOFTABLE_Mask,
+};
+
+ULONG KdComponentTableSize = sizeof(KdComponentTable);
+
+//
+// Debugger Data
+//
+LIST_ENTRY KdpDebuggerDataListHead;
+KSPIN_LOCK KdpDataSpinLock;
+
+//
+// Debugger Version and Data Block
+//
+DBGKD_GET_VERSION64 KdVersionBlock =
+{
+ 0,
+ 0,
+ DBGKD_64BIT_PROTOCOL_VERSION2,
+ KD_SECONDARY_VERSION_DEFAULT,
+ DBGKD_VERS_FLAG_DATA,
+ IMAGE_FILE_MACHINE_I386,
+ PACKET_TYPE_MAX,
+ 0,
+ 0,
+ DBGKD_SIMULATION_NONE,
+ {0},
+ 0,
+ 0,
+ 0
+};
+KDDEBUGGER_DATA64 KdDebuggerDataBlock =
+{
+ {{0}},
+ 0,
+ {PtrToUlong(RtlpBreakWithStatusInstruction)},
+ 0,
+ FIELD_OFFSET(KTHREAD, CallbackStack),
+ CBSTACK_CALLBACK_STACK,
+ CBSTACK_EBP,
+ 0,
+ {PtrToUlong(KiCallUserMode)},
+ {0},
+ {PtrToUlong(&PsLoadedModuleList)},
+ {PtrToUlong(&PsActiveProcessHead)},
+ {PtrToUlong(&PspCidTable)},
+ {PtrToUlong(&ExpSystemResourcesList)},
+ {0}, //
ExpPagedPoolDescriptor
+ {0}, // ExpNumberOfPagedPools
+ {PtrToUlong(&KeTimeIncrement)},
+ {PtrToUlong(&KeBugcheckCallbackListHead)},
+ {PtrToUlong(KiBugCheckData)},
+ {PtrToUlong(&IopErrorLogListHead)},
+ {PtrToUlong(&ObpRootDirectoryObject)},
+ {PtrToUlong(&ObpTypeObjectType)},
+ {0}, // MmSystemCacheStart
+ {0}, // MmSystemCacheEnd
+ {0}, // MmSystemCacheWs
+ {0}, // MmPfnDatabase
+ {0}, // MmSystemPtesStart
+ {0}, // MmSystemPtesEnd
+ {0}, // MmSubsectionBase
+ {0}, // MmNumberOfPagingFiles
+ {0}, // MmLowestPhysicalPage
+ {0}, // MmHighestPhysicalPage
+ {0}, //
MmNumberOfPhysicalPages
+ {0}, //
MmMaximumNonPagedPoolInBytes
+ {0}, // MmNonPagedSystemStart
+ {0}, // MmNonPagedPoolStart
+ {0}, // MmNonPagedPoolEnd
+ {0}, // MmPagedPoolStart
+ {0}, // MmPagedPoolEnd
+ {0}, // MmPagedPoolInfo
+ PAGE_SIZE,
+ {0}, //
MmSizeOfPagedPoolInBytes
+ {0}, // MmTotalCommitLimit
+ {0}, // MmTotalCommittedPages
+ {0}, // MmSharedCommit
+ {0}, // MmDriverCommit
+ {0}, // MmProcessCommit
+ {0}, // MmPagedPoolCommit
+ {0},
+ {0}, // MmZeroedPageListHead
+ {0}, // MmFreePageListHead
+ {0}, // MmStandbyPageListHead
+ {0}, //
MmModifiedPageListHead
+ {0}, //
MmModifiedNoWritePageListHead
+ {0}, // MmAvailablePages
+ {0}, //
MmResidentAvailablePages
+ {0}, // PoolTrackTable
+ {0}, //
NonPagedPoolDescriptor
+ {PtrToUlong(&MmHighestUserAddress)},
+ {PtrToUlong(&MmSystemRangeStart)},
+ {PtrToUlong(&MmUserProbeAddress)},
+ {PtrToUlong(KdPrintDefaultCircularBuffer)},
+ {PtrToUlong(KdPrintDefaultCircularBuffer + 1)},
+ {PtrToUlong(&KdPrintWritePointer)},
+ {PtrToUlong(&KdPrintRolloverCount)},
+ {0}, // MmLoadedUserImageList
+ {PtrToUlong(&NtBuildLab)},
+ {0},
+ {PtrToUlong(KiProcessorBlock)},
+ {0}, // MmUnloadedDrivers
+ {0}, // MmLastUnloadedDrivers
+ {0}, // MmTriageActionTaken
+ {0}, // MmSpecialPoolTag
+ {0}, // KernelVerifier
+ {0}, // MmVerifierData
+ {0}, //
MmAllocatedNonPagedPool
+ {0}, // MmPeakCommitment
+ {0}, //
MmtotalCommitLimitMaximum
+ {PtrToUlong(&CmNtCSDVersion)},
+ {0}, // MmPhysicalMemoryBlock
+ {0}, // MmSessionBase
+ {0}, // MmSessionSize
+ {0},
+ {0},
+ FIELD_OFFSET(KTHREAD, NextProcessor),
+ FIELD_OFFSET(KTHREAD, Teb),
+ FIELD_OFFSET(KTHREAD, KernelStack),
+ FIELD_OFFSET(KTHREAD, InitialStack),
+ FIELD_OFFSET(KTHREAD, ApcState.Process),
+ FIELD_OFFSET(KTHREAD, State),
+ 0,
+ 0,
+ sizeof(EPROCESS),
+ FIELD_OFFSET(EPROCESS, Peb),
+ FIELD_OFFSET(EPROCESS, InheritedFromUniqueProcessId),
+ FIELD_OFFSET(EPROCESS, Pcb.DirectoryTableBase),
+ sizeof(KPRCB),
+ FIELD_OFFSET(KPRCB, DpcRoutineActive),
+ FIELD_OFFSET(KPRCB, CurrentThread),
+ FIELD_OFFSET(KPRCB, MHz),
+ FIELD_OFFSET(KPRCB, CpuType),
+ FIELD_OFFSET(KPRCB, VendorString),
+ FIELD_OFFSET(KPRCB, ProcessorState.ContextFrame),
+ FIELD_OFFSET(KPRCB, Number),
+ sizeof(ETHREAD),
+ {PtrToUlong(KdPrintDefaultCircularBuffer)},
+ {PtrToUlong(&KdPrintBufferSize)},
+ {PtrToUlong(&KeLoaderBlock)},
+ sizeof(KIPCR) + sizeof(KPRCB),
+ FIELD_OFFSET(KIPCR, Self),
+ FIELD_OFFSET(KPCR, Prcb),
+ FIELD_OFFSET(KIPCR, PrcbData),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ FIELD_OFFSET(KIPCR, PrcbData) +
+ FIELD_OFFSET(KPRCB, ProcessorState.SpecialRegisters),
+ KGDT_R0_CODE,
+ KGDT_R0_DATA,
+ KGDT_R0_PCR,
+ KGDT_R3_CODE,
+ KGDT_R3_DATA,
+ KGDT_R3_TEB,
+ KGDT_LDT,
+ KGDT_TSS,
+ 0,
+ 0,
+ {0}, //
IopNumTriagDumpDataBlocks
+ {0}, //
IopTriageDumpDataBlocks
+};
Added: trunk/reactos/ntoskrnl/kd64/kdinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdinit.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdinit.c (added)
+++ trunk/reactos/ntoskrnl/kd64/kdinit.c Sat Mar 3 07:39:25 2007
@@ -1,0 +1,267 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/kd64/kdinit.c
+ * PURPOSE: KD64 Initialization Code
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+BOOLEAN
+NTAPI
+KdRegisterDebuggerDataBlock(IN ULONG Tag,
+ IN PDBGKD_DEBUG_DATA_HEADER64 DataHeader,
+ IN ULONG Size)
+{
+ KIRQL OldIrql;
+ PLIST_ENTRY NextEntry;
+ PDBGKD_DEBUG_DATA_HEADER64 CurrentHeader;
+
+ /* Acquire the Data Lock */
+ KeAcquireSpinLock(&KdpDataSpinLock, &OldIrql);
+
+ /* Loop the debugger data list */
+ NextEntry = KdpDebuggerDataListHead.Flink;
+ while (NextEntry != &KdpDebuggerDataListHead)
+ {
+ /* Get the header for this entry */
+ CurrentHeader = CONTAINING_RECORD(NextEntry,
+ DBGKD_DEBUG_DATA_HEADER64,
+ List);
+
+ /* Move to the next one */
+ NextEntry = NextEntry->Flink;
+
+ /* Check if we already have this data block */
+ if ((CurrentHeader == DataHeader) || (CurrentHeader->OwnerTag == Tag))
+ {
+ /* Release the lock and fail */
+ KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);
+ return FALSE;
+ }
+ }
+
+ /* Setup the header */
+ DataHeader->OwnerTag = Tag;
+ DataHeader->Size = Size;
+
+ /* Insert it into the list and release the lock */
+ InsertTailList(&KdpDebuggerDataListHead, (PLIST_ENTRY)&DataHeader->List);
+ KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+KdInitSystem(IN ULONG BootPhase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ BOOLEAN EnableKd;
+ LPSTR CommandLine, DebugLine;
+ ANSI_STRING ImageName;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+ PLIST_ENTRY NextEntry;
+ ULONG i, j, Length;
+ CHAR NameBuffer[256];
+ PWCHAR Name;
+
+ /* Check if this is Phase 1 */
+ if (BootPhase)
+ {
+ /* Just query the performance counter */
+ KeQueryPerformanceCounter(&KdPerformanceCounterRate);
+ return TRUE;
+ }
+
+ /* Check if we already initialized once */
+ if (KdDebuggerEnabled) return TRUE;
+
+ /* Set the Debug Routine as the Stub for now */
+ KiDebugRoutine = KdpStub;
+
+ /* Disable break after symbol load for now */
+ KdBreakAfterSymbolLoad = FALSE;
+
+ /* Check if the Debugger Data Block was already initialized */
+ if (!KdpDebuggerDataListHead.Flink)
+ {
+ /* It wasn't...Initialize the KD Data Listhead */
+ InitializeListHead(&KdpDebuggerDataListHead);
+
+ /* Register the Debugger Data Block */
+ KdRegisterDebuggerDataBlock(KDBG_TAG,
+ &KdDebuggerDataBlock.Header,
+ sizeof(KdDebuggerDataBlock));
+
+ /* Fill out the KD Version Block */
+ KdVersionBlock.MajorVersion = (USHORT)(NtBuildNumber >> 28);
+ KdVersionBlock.MinorVersion = (USHORT)(NtBuildNumber & 0xFFFF);
+
+#ifdef CONFIG_SMP
+ /* This is an MP Build */
+ KdVersionBlock.Flags |= DBGKD_VERS_FLAG_MP;
+#endif
+
+ /* Save Pointers to Loaded Module List and Debugger Data */
+ KdVersionBlock.PsLoadedModuleList =
(ULONGLONG)(LONG_PTR)&PsLoadedModuleList;
+ KdVersionBlock.DebuggerDataList =
(ULONGLONG)(LONG_PTR)&KdpDebuggerDataListHead;
+
+ /* Set protocol limits */
+ KdVersionBlock.MaxStateChange = DbgKdMaximumStateChange -
+ DbgKdMinimumStateChange;
+ KdVersionBlock.MaxManipulate = DbgKdMaximumManipulate -
+ DbgKdMinimumManipulate;
+ KdVersionBlock.Unused[0] = 0;
+
+ /* Link us in the KPCR */
+ KeGetPcr()->KdVersionBlock = &KdVersionBlock;
+ }
+
+ /* Check if we have a loader block */
+ if (LoaderBlock)
+ {
+ /* Get the image entry */
+ LdrEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+
+ /* Save the Kernel Base */
+ PsNtosImageBase = (ULONG)LdrEntry->DllBase;
+ KdVersionBlock.KernBase = (ULONGLONG)(LONG_PTR)LdrEntry->DllBase;
+
+ /* Check if we have a command line */
+ CommandLine = LoaderBlock->LoadOptions;
+ if (CommandLine)
+ {
+ /* Upcase it */
+ _strupr(CommandLine);
+
+ /* Assume we'll disable KD */
+ EnableKd = FALSE;
+
+ /* Check for CRASHDEBUG and NODEBUG */
+ if (strstr(CommandLine, "CRASHDEBUG")) KdPitchDebugger = FALSE;
+ if (strstr(CommandLine, "NODEBUG")) KdPitchDebugger = TRUE;
+
+ /* Check if DEBUG was on */
+ DebugLine = strstr(CommandLine, "DEBUG");
+ if (DebugLine)
+ {
+ /* Enable KD */
+ EnableKd = TRUE;
+
+ /* Check if there was additional data */
+ if (DebugLine[5] == '=')
+ {
+ /* FIXME: Check for NOUMEX, DISABLE, AUTOENABLE */
+ }
+ }
+ }
+ else
+ {
+ /* No command line options? Disable debugger by default */
+ KdPitchDebugger = TRUE;
+ EnableKd = FALSE;
+ }
+ }
+ else
+ {
+ /* Called from a bugcheck...Save the Kernel Base */
+ KdVersionBlock.KernBase = (ULONGLONG)(LONG_PTR)PsNtosImageBase;
+
+ /* Unconditionally enable KD */
+ EnableKd = TRUE;
+ }
+
+ /* Set the Kernel Base in the Data Block */
+ KdDebuggerDataBlock.KernBase = (ULONGLONG)(LONG_PTR)KdVersionBlock.KernBase;
+
+ /* Initialize the debugger if requested */
+ if ((EnableKd) && (NT_SUCCESS(KdDebuggerInitialize0(LoaderBlock))))
+ {
+ /* Now set our real KD routine */
+ KiDebugRoutine = KdpTrap;
+
+ /* Check if we've already initialized our structures */
+ if (!KdpDebuggerStructuresInitialized)
+ {
+ /* Set the Debug Switch Routine and Retries*/
+ KdpContext.KdpDefaultRetries = 20;
+ KiDebugSwitchRoutine = KdpSwitchProcessor;
+
+ /* Initialize the Time Slip DPC */
+ KeInitializeDpc(&KdpTimeSlipDpc, KdpTimeSlipDpcRoutine, NULL);
+ KeInitializeTimer(&KdpTimeSlipTimer);
+ ExInitializeWorkItem(&KdpTimeSlipWorkItem, KdpTimeSlipWork, NULL);
+
+ /* First-time initialization done! */
+ KdpDebuggerStructuresInitialized = TRUE;
+ }
+
+ /* Initialize the timer */
+ KdTimerStart.QuadPart = 0;
+
+ /* Officially enable KD */
+ KdPitchDebugger = FALSE;
+ KdDebuggerEnabled = TRUE;
+
+ /* Let user-mode know that it's enabled as well */
+#undef KdDebuggerEnabled
+ SharedUserData->KdDebuggerEnabled = TRUE;
+#define KdDebuggerEnabled _KdDebuggerEnabled
+
+ /* Check if we have a loader block */
+ if (LoaderBlock)
+ {
+ /* Loop boot images */
+ NextEntry = LoaderBlock->LoadOrderListHead.Flink;
+ i = 0;
+ while ((NextEntry != &LoaderBlock->LoadOrderListHead) && (i
< 2))
+ {
+ /* Get the image entry */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+
+ /* Generate the image name */
+ Name = LdrEntry->FullDllName.Buffer;
+ Length = LdrEntry->FullDllName.Length / sizeof(WCHAR);
+ j = 0;
+ do
+ {
+ /* Do cheap Unicode to ANSI conversion */
+ NameBuffer[j++] = (CHAR)*Name++;
+ } while (j < Length);
+
+ /* Null-terminate */
+ NameBuffer[j] = ANSI_NULL;
+
+ /* Load symbols for image */
+ RtlInitAnsiString(&ImageName, NameBuffer);
+ DbgLoadImageSymbols(&ImageName, LdrEntry->DllBase, -1);
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+ i++;
+ }
+ }
+
+ /* Check for incoming breakin and break on symbol load if we have it*/
+ KdBreakAfterSymbolLoad = KdPollBreakIn();
+ }
+ else
+ {
+ /* Disable debugger */
+ KdDebuggerNotPresent = TRUE;
+ }
+
+ /* Return initialized */
+ return TRUE;
+}
Added: trunk/reactos/ntoskrnl/kd64/kdlock.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdlock.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdlock.c (added)
+++ trunk/reactos/ntoskrnl/kd64/kdlock.c Sat Mar 3 07:39:25 2007
@@ -1,0 +1,125 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/kd64/kdlock.c
+ * PURPOSE: KD64 Port Lock and Breakin Support
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+KdpPortLock(VOID)
+{
+ /* Acquire the lock */
+ KiAcquireSpinLock(&KdpDebuggerLock);
+}
+
+VOID
+NTAPI
+KdpPortUnlock(VOID)
+{
+ /* Release the lock */
+ KiReleaseSpinLock(&KdpDebuggerLock);
+}
+
+BOOLEAN
+NTAPI
+KdpPollBreakInWithPortLock(VOID)
+{
+ BOOLEAN DoBreak = FALSE;
+
+ /* First make sure that KD is enabled */
+ if (KdDebuggerEnabled)
+ {
+ /* Check if a CTRL-C is in the queue */
+ if (KdpContext.KdpControlCPending)
+ {
+ /* Set it and prepare for break */
+ DoBreak = TRUE;
+ KdpContext.KdpControlCPending = FALSE;
+ }
+ else
+ {
+ /* Now get a packet */
+ if (!KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,
+ NULL,
+ NULL,
+ NULL,
+ NULL))
+ {
+ /* Successful breakin */
+ DoBreak = TRUE;
+ }
+ }
+ }
+
+ /* Tell the caller to do a break */
+ return DoBreak;
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+KdPollBreakIn(VOID)
+{
+ BOOLEAN DoBreak = FALSE;
+ ULONG Flags = 0;
+
+ /* First make sure that KD is enabled */
+ if (KdDebuggerEnabled)
+ {
+ /* Disable interrupts */
+ Ke386SaveFlags(Flags);
+ //Flags = __getcallerseflags();
+ _disable();
+
+ /* Check if a CTRL-C is in the queue */
+ if (KdpControlCWaiting)
+ {
+ /* Set it and prepare for break */
+ KdpControlCPressed = TRUE;
+ DoBreak = TRUE;
+ KdpControlCWaiting = FALSE;
+ }
+ else
+ {
+ /* Try to acquire the lock */
+ if (KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock))
+ {
+ /* Now get a packet */
+ if (!KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,
+ NULL,
+ NULL,
+ NULL,
+ NULL))
+ {
+ /* Successful breakin */
+ DoBreak = TRUE;
+ KdpControlCPressed = TRUE;
+ }
+
+ /* Let go of the port */
+ KdpPortUnlock();
+ }
+ }
+
+ /* Re-enable interrupts if they were disabled */
+ if (Flags & EFLAGS_INTERRUPT_MASK) _enable();
+ }
+
+ /* Tell the caller to do a break */
+ return DoBreak;
+}
+
Added: trunk/reactos/ntoskrnl/kd64/kdprint.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdprint.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdprint.c (added)
+++ trunk/reactos/ntoskrnl/kd64/kdprint.c Sat Mar 3 07:39:25 2007
@@ -1,0 +1,198 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/kd64/kdprint.c
+ * PURPOSE: KD64 Trap Handler Routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+BOOLEAN
+NTAPI
+KdpPrintString(IN PSTRING Output)
+{
+ STRING Data, Header;
+ DBGKD_DEBUG_IO DebugIo;
+ ULONG Length = Output->Length;
+
+ /* Copy the string */
+ RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length);
+
+ /* Make sure we don't exceed the KD Packet size */
+ if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
+ {
+ /* Normalize length */
+ Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);
+ }
+
+ /* Build the packet header */
+ DebugIo.ApiNumber = DbgKdPrintStringApi;
+ DebugIo.ProcessorLevel = KeProcessorLevel;
+ DebugIo.Processor = KeGetCurrentPrcb()->Number;
+ DebugIo.u.PrintString.LengthOfString = Length;
+ Header.Length = sizeof(DBGKD_DEBUG_IO);
+ Header.Buffer = (PCHAR)&DebugIo;
+
+ /* Build the data */
+ Data.Length = Length;
+ Data.Buffer = KdpMessageBuffer;
+
+ /* Send the packet */
+ KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext);
+
+ /* Check if the user pressed CTRL+C */
+ return KdpPollBreakInWithPortLock();
+}
+
+ULONG
+NTAPI
+KdpCommandString(IN ULONG Length,
+ IN LPSTR String,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN PCONTEXT ContextRecord,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame)
+{
+ /* FIXME */
+ return FALSE;
+}
+
+ULONG
+NTAPI
+KdpSymbol(IN PSTRING DllPath,
+ IN PKD_SYMBOLS_INFO DllBase,
+ IN BOOLEAN Unload,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN PCONTEXT ContextRecord,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame)
+{
+ BOOLEAN Entered;
+ PKPRCB Prcb = KeGetCurrentPrcb();
+ ULONG Status;
+
+ /* Check if we need to do anything */
+ if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return 0;
+
+ /* Enter the debugger */
+ Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
+
+ /* Save the CPU Control State and save the context */
+ KiSaveProcessorControlState(&Prcb->ProcessorState);
+ RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
+ ContextRecord,
+ sizeof(CONTEXT));
+
+ /* Report the new state */
+ Status = KdpReportLoadSymbolsStateChange(DllPath,
+ DllBase,
+ Unload,
+ &Prcb->ProcessorState.
+ ContextFrame);
+
+ /* Now restore the processor state, manually again. */
+ RtlCopyMemory(ContextRecord,
+ &Prcb->ProcessorState.ContextFrame,
+ sizeof(CONTEXT));
+ //KiRestoreProcessorControlState(&Prcb->ProcessorState);
+
+ /* Exit the debugger and clear the CTRL-C state */
+ KdExitDebugger(Entered);
+ return 0;
+}
+
+ULONG
+NTAPI
+KdpPrompt(IN LPSTR InString,
+ IN ULONG InStringLength,
+ OUT LPSTR OutString,
+ IN ULONG OutStringLength,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame)
+{
+ /* FIXME */
+ return FALSE;
+}
+
+ULONG
+NTAPI
+KdpPrint(IN ULONG ComponentId,
+ IN ULONG ComponentMask,
+ IN LPSTR String,
+ IN ULONG Length,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ OUT PBOOLEAN Status)
+{
+ NTSTATUS ReturnValue;
+ BOOLEAN Entered;
+ ANSI_STRING AnsiString;
+
+ /* Assume failure */
+ *Status = FALSE;
+
+ /* Validate the mask */
+ if (ComponentMask <= 0x1F) ComponentMask = 1 << ComponentMask;
+ if (!(Kd_WIN2000_Mask & ComponentMask) ||
+ ((ComponentId < KdComponentTableSize) &&
+ !(*KdComponentTable[ComponentId] & ComponentMask)))
+ {
+ /* Mask validation failed */
+ *Status = TRUE;
+ return FALSE;
+ }
+
+ /* Normalize the length */
+ Length = min(Length, 512);
+
+ /* Check if we need to verify the buffer */
+ if (PreviousMode != KernelMode)
+ {
+ /* FIXME: Support user-mode */
+ }
+
+ /* Setup the ANSI string */
+ AnsiString.Buffer = String;
+ AnsiString.Length = (USHORT)Length;
+
+ /* Log the print */
+ //KdLogDbgPrint(&AnsiString);
+
+ /* Check for a debugger */
+ if (KdDebuggerNotPresent)
+ {
+ /* Fail */
+ *Status = TRUE;
+ return (ULONG)STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ /* Enter the debugger */
+ Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
+
+ /* Print the string */
+ if (KdpPrintString(&AnsiString))
+ {
+ /* User pressed CTRL-C, breakpoint on return */
+ ReturnValue = STATUS_BREAKPOINT;
+ }
+ else
+ {
+ /* String was printed */
+ ReturnValue = STATUS_SUCCESS;
+ }
+
+ /* Exit the debugger and return */
+ KdExitDebugger(Entered);
+ *Status = TRUE;
+ return ReturnValue;
+}
+
Added: trunk/reactos/ntoskrnl/kd64/kdtrap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdtrap.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdtrap.c (added)
+++ trunk/reactos/ntoskrnl/kd64/kdtrap.c Sat Mar 3 07:39:25 2007
@@ -1,0 +1,239 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/kd64/kdtrap.c
+ * PURPOSE: KD64 Trap Handlers
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+BOOLEAN
+NTAPI
+KdpReport(IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT ContextRecord,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN BOOLEAN SecondChanceException)
+{
+ BOOLEAN Entered, Status;
+ PKPRCB Prcb;
+ NTSTATUS ExceptionCode = ExceptionRecord->ExceptionCode;
+
+ /* Check if this is INT1 or 3, or if we're forced to handle it */
+ if ((ExceptionCode == STATUS_BREAKPOINT) ||
+ (ExceptionCode == STATUS_SINGLE_STEP) ||
+ //(ExceptionCode == STATUS_ASSERTION_FAILURE) ||
+ (NtGlobalFlag & FLG_STOP_ON_EXCEPTION))
+ {
+ /* Check if we can't really handle this */
+ if ((SecondChanceException) ||
+ (ExceptionCode == STATUS_PORT_DISCONNECTED) ||
+ (NT_SUCCESS(ExceptionCode)))
+ {
+ /* Return false to have someone else take care of the exception */
+ return FALSE;
+ }
+ }
+ else if (SecondChanceException)
+ {
+ /* We won't bother unless this is second chance */
+ return FALSE;
+ }
+
+ /* Enter the debugger */
+ Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
+
+ /*
+ * Get the KPRCB and save the CPU Control State manually instead of
+ * using KiSaveProcessorState, since we already have a valid CONTEXT.
+ */
+ Prcb = KeGetCurrentPrcb();
+ KiSaveProcessorControlState(&Prcb->ProcessorState);
+ RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
+ ContextRecord,
+ sizeof(CONTEXT));
+
+ /* Report the new state */
+ Status = KdpReportExceptionStateChange(ExceptionRecord,
+ &Prcb->ProcessorState.
+ ContextFrame,
+ SecondChanceException);
+
+ /* Now restore the processor state, manually again. */
+ RtlCopyMemory(ContextRecord,
+ &Prcb->ProcessorState.ContextFrame,
+ sizeof(CONTEXT));
+ //KiRestoreProcessorControlState(&Prcb->ProcessorState);
+
+ /* Exit the debugger and clear the CTRL-C state */
+ KdExitDebugger(Entered);
+ KdpControlCPressed = FALSE;
+ return Status;
+}
+
+BOOLEAN
+NTAPI
+KdpTrap(IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT ContextRecord,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN BOOLEAN SecondChanceException)
+{
+ BOOLEAN Unload = FALSE;
+ ULONG Eip, Eax;
+ BOOLEAN Status = FALSE;
+
+ /*
+ * Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or
+ * Load/Unload symbols.
+ */
+ if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
+ (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))
+ {
+ /* Save EIP */
+ Eip = ContextRecord->Eip;
+
+ /* Check what kind of operation was requested from us */
+ switch (ExceptionRecord->ExceptionInformation[0])
+ {
+ /* DbgPrint */
+ case BREAKPOINT_PRINT:
+
+ /* Call the worker routine */
+ Eax = KdpPrint(ContextRecord->Ebx,
+ ContextRecord->Edi,
+ (LPSTR)ExceptionRecord->ExceptionInformation[1],
+ (ULONG)ExceptionRecord->ExceptionInformation[2],
+ PreviousMode,
+ TrapFrame,
+ ExceptionFrame,
+ &Status);
+
+ /* Update the return value for the caller */
+ ContextRecord->Eax = Eax;
+ break;
+
+ /* DbgPrompt */
+ case BREAKPOINT_PROMPT:
+
+ /* Call the worker routine */
+ while (TRUE);
+ Eax = 0;
+ Status = TRUE;
+
+ /* Update the return value for the caller */
+ ContextRecord->Eax = Eax;
+ break;
+
+ /* DbgUnloadSymbols */
+ case BREAKPOINT_UNLOAD_SYMBOLS:
+
+ /* Drop into the load case below, with the unload parameter */
+ Unload = TRUE;
+
+ /* DbgLoadSymbols */
+ case BREAKPOINT_LOAD_SYMBOLS:
+
+ /* Call the worker routine */
+ KdpSymbol((PVOID)ExceptionRecord->ExceptionInformation[1],
+ (PVOID)ExceptionRecord->ExceptionInformation[2],
+ Unload,
+ PreviousMode,
+ ContextRecord,
+ TrapFrame,
+ ExceptionFrame);
+ Status = TRUE;
+ break;
+
+ /* DbgCommandString*/
+ case BREAKPOINT_COMMAND_STRING:
+
+ /* Call the worker routine */
+ while (TRUE);
+ Status = TRUE;
+
+ /* Anything else, do nothing */
+ default:
+
+ /* Get out */
+ break;
+ }
+
+ /*
+ * If EIP was not updated, we'll increment it ourselves so execution
+ * continues past the breakpoint.
+ */
+ if (ContextRecord->Eip == Eip) ContextRecord->Eip++;
+ }
+ else
+ {
+ /* Call the worker routine */
+ Status = KdpReport(TrapFrame,
+ ExceptionFrame,
+ ExceptionRecord,
+ ContextRecord,
+ PreviousMode,
+ SecondChanceException);
+ }
+
+ /* Return TRUE or FALSE to caller */
+ return Status;
+}
+
+BOOLEAN
+NTAPI
+KdpStub(IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT ContextRecord,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN BOOLEAN SecondChanceException)
+{
+ ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];
+
+ /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
+ if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
+ (ExceptionRecord->NumberParameters > 0) &&
+ ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||
+ (ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) ||
+ (ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||
+ (ExceptionCommand == BREAKPOINT_PRINT)))
+ {
+ /* This we can handle: simply bump EIP */
+ ContextRecord->Eip++;
+ return TRUE;
+ }
+ else if (KdPitchDebugger)
+ {
+ /* There's no debugger, fail. */
+ return FALSE;
+ }
+ else if ((KdAutoEnableOnEvent) &&
+ (KdPreviouslyEnabled) &&
+ !(KdDebuggerEnabled) &&
+ (KdEnableDebugger()) &&
+ (KdDebuggerEnabled))
+ {
+ /* Debugging was Auto-Enabled. We can now send this to KD. */
+ return KdpTrap(TrapFrame,
+ ExceptionFrame,
+ ExceptionRecord,
+ ContextRecord,
+ PreviousMode,
+ SecondChanceException);
+ }
+ else
+ {
+ /* FIXME: All we can do in this case is trace this exception */
+ return FALSE;
+ }
+}
Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/cpu.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/cpu.c Sat Mar 3 07:39:25 2007
@@ -697,8 +697,8 @@
//
// Restore GDT, IDT, LDT and TSS
//
- Ke386SetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr);
- Ke386SetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr);
+ Ke386SetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr.Base);
+ Ke386SetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr.Base);
Ke386SetTr(ProcessorState->SpecialRegisters.Tr);
Ke386SetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
}
@@ -724,8 +724,8 @@
Ke386SetDr7(0);
/* Save GDT, IDT, LDT and TSS */
- Ke386GetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr);
- Ke386GetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr);
+ Ke386GetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr.Base);
+ Ke386GetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr.Base);
Ke386GetTr(ProcessorState->SpecialRegisters.Tr);
Ke386GetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
}
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/exp.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/exp.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c Sat Mar 3 07:39:25 2007
@@ -800,7 +800,7 @@
/* Set the context flags */
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
- /* Check if User Mode or if the debugger isenabled */
+ /* Check if User Mode or if the debugger is enabled */
if ((PreviousMode == UserMode) || (KdDebuggerEnabled))
{
/* Add the FPU Flag */
@@ -846,9 +846,6 @@
goto Handled;
}
- /* HACK: GDB Entry */
- if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled;
-
/* If the Debugger couldn't handle it, dispatch the exception */
if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled;
}
@@ -893,9 +890,6 @@
/* Exception was handled */
goto Handled;
}
-
- /* HACK: GDB Entry */
- if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled;
/* Forward exception to user mode debugger */
if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) goto Exit;
@@ -1045,4 +1039,3 @@
/* Return the old EIP */
return (NTSTATUS)OldEip;
}
-
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s Sat Mar 3 07:39:25 2007
@@ -228,22 +228,6 @@
/* Copy the parameters */
rep movsd
-#ifdef DBG
- /*
- * The following lines are for the benefit of GDB. It will see the return
- * address of the "call ebx" below, find the last label before it and
- * thinks that that's the start of the function. It will then check to see
- * if it starts with a standard function prolog (push ebp, mov ebp,esp1).
- * When that standard function prolog is not found, it will stop the
- * stack backtrace. Since we do want to backtrace into usermode, let's
- * make GDB happy and create a standard prolog.
- */
-KiSystemService:
- push ebp
- mov ebp,esp
- pop ebp
-#endif
-
/* Do the System Call */
call ebx
@@ -482,7 +466,7 @@
TRAP_PROLOG kids
/* Increase EIP so we skip the INT3 */
- //inc dword ptr [ebp+KTRAP_FRAME_EIP]
+ inc dword ptr [ebp+KTRAP_FRAME_EIP]
/* Call debug service dispatcher */
mov eax, [ebp+KTRAP_FRAME_EAX]
@@ -821,7 +805,11 @@
/* Enter trap */
TRAP_PROLOG kit3
+ /* Set status code */
+ mov eax, 0 //STATUS_SUCCESS
+
/* Check for V86 */
+PrepareInt3:
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Int3
Modified: trunk/reactos/ntoskrnl/mm/rmap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/rmap.c?rev=259…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/rmap.c (original)
+++ trunk/reactos/ntoskrnl/mm/rmap.c Sat Mar 3 07:39:25 2007
@@ -432,9 +432,9 @@
{
DbgPrint("MmInsertRmap tries to add a second rmap entry for address %p\n
current caller ",
current_entry->Address);
- KeRosPrintAddress(new_entry->Caller);
+ DbgPrint("%p", new_entry->Caller);
DbgPrint("\n previous caller ");
- KeRosPrintAddress(current_entry->Caller);
+ DbgPrint("%p", current_entry->Caller);
DbgPrint("\n");
KeBugCheck(0);
}
Modified: trunk/reactos/ntoskrnl/mm/sysldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/sysldr.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/sysldr.c (original)
+++ trunk/reactos/ntoskrnl/mm/sysldr.c Sat Mar 3 07:39:25 2007
@@ -1752,9 +1752,6 @@
if (ModuleObject) *ModuleObject = LdrEntry;
if (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase;
- /* Hook for KDB on loading a driver. */
- KDB_LOADDRIVER_HOOK(FileName, LdrEntry);
-
Quickie:
/* If we have a file handle, close it */
if (FileHandle) ZwClose(FileHandle);
Modified: trunk/reactos/ntoskrnl/ps/kill.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/kill.c?rev=259…
==============================================================================
--- trunk/reactos/ntoskrnl/ps/kill.c (original)
+++ trunk/reactos/ntoskrnl/ps/kill.c Sat Mar 3 07:39:25 2007
@@ -286,9 +286,6 @@
/* Detach */
KeUnstackDetachProcess(&ApcState);
}
-
- /* KDB hook */
- KDB_DELETEPROCESS_HOOK(Process);
/* Check if we have an address space, and clean it */
if (Process->HasAddressSpace)