- Add kdbreak.c with the following APIs: KdpLowWriteContent, KdpLowRestoreBreakpoint, KdpDeleteBreakpoint, KdpDeleteBreakpointRange, KdpRestoreAllBreakpoints. Adding breakpoints not yet supported.

- Enable kdinit.c call to KdpRestoreAllBreakpoints.
- Add breakpoint table and data.
- Support DbgKdRestoreBreakpointApi. Now we get DbgKdClearAllInternalBreakpointsApi.

svn path=/branches/alex-kd-branch/; revision=25850
This commit is contained in:
Alex Ionescu 2007-02-20 02:00:01 +00:00
parent 24f9e136e6
commit f3488993eb
5 changed files with 225 additions and 3 deletions

View file

@ -1,3 +1,19 @@
typedef struct _BREAKPOINT_ENTRY
{
ULONG Flags;
PKPROCESS Process;
PVOID Address;
UCHAR Content;
} BREAKPOINT_ENTRY, *PBREAKPOINT_ENTRY;
typedef enum _KDP_BREAKPOINT_FLAGS
{
KdpBreakpointActive = 1,
KdpBreakpointPending = 2,
KdpBreakpointSuspended = 4,
KdpBreakpointExpired = 8
} KDP_BREAKPOINT_FLAGS;
typedef
BOOLEAN
(NTAPI *PKDEBUG_ROUTINE)(
@ -144,6 +160,18 @@ KdpReportLoadSymbolsStateChange(
IN OUT PCONTEXT Context
);
VOID
NTAPI
KdpRestoreAllBreakpoints(
VOID
);
BOOLEAN
NTAPI
KdpDeleteBreakpoint(
IN ULONG BpEntry
);
extern DBGKD_GET_VERSION64 KdVersionBlock;
extern KDDEBUGGER_DATA64 KdDebuggerDataBlock;
extern LIST_ENTRY KdpDebuggerDataListHead;
@ -177,3 +205,7 @@ extern ULONG KdComponentTableSize;
extern ULONG Kd_WIN2000_Mask;
extern PULONG KdComponentTable[104];
extern CHAR KdpMessageBuffer[4096], KdpPathBuffer[4096];
extern BREAKPOINT_ENTRY KdpBreakpointTable[20];
extern ULONG KdpBreakpointInstruction;
extern BOOLEAN KdpOweBreakpoint;
extern BOOLEAN BreakpointsSuspended;

View file

@ -243,6 +243,39 @@ KdpReadControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
&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);
}
KCONTINUE_STATUS
NTAPI
KdpSendWaitContinue(IN ULONG PacketType,
@ -327,8 +360,7 @@ SendPacket:
case DbgKdRestoreBreakPointApi:
/* FIXME: TODO */
Ke386SetCr2(DbgKdRestoreBreakPointApi);
while (TRUE);
KdpRestoreBreakpoint(&ManipulateState, &Data, Context);
break;
case DbgKdContinueApi:
@ -862,7 +894,7 @@ KdEnableDebuggerWithLock(BOOLEAN NeedLock)
{
/* Reinitialize the Debugger */
KdInitSystem(0, NULL) ;
//KdpRestoreAllBreakpoints();
KdpRestoreAllBreakpoints();
}
}

View file

@ -0,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@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);
}
}
}

View file

@ -45,6 +45,14 @@ BOOLEAN KdEnteredDebugger;
ULONG KdDisableCount;
LARGE_INTEGER KdPerformanceCounterRate;
//
// Breakpoint Data
//
BREAKPOINT_ENTRY KdpBreakpointTable[20];
ULONG KdpBreakpointInstruction = 0xCC;
BOOLEAN KdpOweBreakpoint;
BOOLEAN BreakpointsSuspended;
//
// Time Slip Support
//

View file

@ -195,6 +195,7 @@
</directory>
<directory name="kd64">
<file>kdapi.c</file>
<file>kdbreak.c</file>
<file>kddata.c</file>
<file>kdinit.c</file>
<file>kdlock.c</file>