mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 17:06:29 +00:00
- 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:
parent
24f9e136e6
commit
f3488993eb
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
149
reactos/ntoskrnl/kd64/kdbreak.c
Normal file
149
reactos/ntoskrnl/kd64/kdbreak.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue