Author: ion Date: Tue Feb 20 05:00:01 2007 New Revision: 25850
URL: http://svn.reactos.org/svn/reactos?rev=25850&view=rev Log: - 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.
Added: branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdbreak.c Modified: branches/alex-kd-branch/reactos/ntoskrnl/include/internal/kd.h branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdapi.c branches/alex-kd-branch/reactos/ntoskrnl/kd64/kddata.c branches/alex-kd-branch/reactos/ntoskrnl/ntoskrnl.rbuild
Modified: branches/alex-kd-branch/reactos/ntoskrnl/include/internal/kd.h URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/include/internal/kd.h (original) +++ branches/alex-kd-branch/reactos/ntoskrnl/include/internal/kd.h Tue Feb 20 05:00:01 2007 @@ -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)( @@ -142,6 +158,18 @@ IN PKD_SYMBOLS_INFO SymbolInfo, IN BOOLEAN Unload, IN OUT PCONTEXT Context +); + +VOID +NTAPI +KdpRestoreAllBreakpoints( + VOID +); + +BOOLEAN +NTAPI +KdpDeleteBreakpoint( + IN ULONG BpEntry );
extern DBGKD_GET_VERSION64 KdVersionBlock; @@ -177,3 +205,7 @@ 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;
Modified: branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdapi.c URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdapi.c (original) +++ branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdapi.c Tue Feb 20 05:00:01 2007 @@ -243,6 +243,39 @@ &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 @@ case DbgKdRestoreBreakPointApi:
/* FIXME: TODO */ - Ke386SetCr2(DbgKdRestoreBreakPointApi); - while (TRUE); + KdpRestoreBreakpoint(&ManipulateState, &Data, Context); break;
case DbgKdContinueApi: @@ -862,7 +894,7 @@ { /* Reinitialize the Debugger */ KdInitSystem(0, NULL) ; - //KdpRestoreAllBreakpoints(); + KdpRestoreAllBreakpoints(); } }
Added: branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdbreak.c URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdbreak.c (added) +++ branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdbreak.c Tue Feb 20 05:00:01 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@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); + } + } +}
Modified: branches/alex-kd-branch/reactos/ntoskrnl/kd64/kddata.c URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/kd64/kddata.c (original) +++ branches/alex-kd-branch/reactos/ntoskrnl/kd64/kddata.c Tue Feb 20 05:00:01 2007 @@ -44,6 +44,14 @@ BOOLEAN KdEnteredDebugger; ULONG KdDisableCount; LARGE_INTEGER KdPerformanceCounterRate; + +// +// Breakpoint Data +// +BREAKPOINT_ENTRY KdpBreakpointTable[20]; +ULONG KdpBreakpointInstruction = 0xCC; +BOOLEAN KdpOweBreakpoint; +BOOLEAN BreakpointsSuspended;
// // Time Slip Support
Modified: branches/alex-kd-branch/reactos/ntoskrnl/ntoskrnl.rbuild URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/ntoskrnl.rbuild (original) +++ branches/alex-kd-branch/reactos/ntoskrnl/ntoskrnl.rbuild Tue Feb 20 05:00:01 2007 @@ -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>