4b9b9af12f760e9eec0d349a555ae52e49827968
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/kd64/kdbreak.c
5 * PURPOSE: KD64 Breakpoint Support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 /* FUNCTIONS *****************************************************************/
19 KdpLowWriteContent(IN ULONG BpIndex
)
21 /* Make sure that the breakpoint is actually active */
22 if (KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointPending
)
24 /* So we have a valid breakpoint, but it hasn't been used yet... */
25 KdpBreakpointTable
[BpIndex
].Flags
&= ~KdpBreakpointPending
;
29 /* Is the original instruction an INT3 anyway? */
30 if (KdpBreakpointTable
[BpIndex
].Content
== KdpBreakpointInstruction
)
32 /* Then leave it that way... */
36 /* We have an active breakpoint with an instruction to bring back. Do it. */
37 RtlCopyMemory(KdpBreakpointTable
[BpIndex
].Address
,
38 &KdpBreakpointTable
[BpIndex
].Content
,
41 /* Everything went fine, return */
47 KdpLowRestoreBreakpoint(IN ULONG BpIndex
)
49 /* Were we not able to remove it earlier? */
50 if (KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointExpired
)
52 /* Well then, we'll just re-use it and return success! */
53 KdpBreakpointTable
[BpIndex
].Flags
&= ~KdpBreakpointExpired
;
57 /* Are we merely writing an INT3 on top of another INT3? */
58 if (KdpBreakpointTable
[BpIndex
].Content
== KdpBreakpointInstruction
)
60 /* Nothing to do then... */
64 /* Ok, we actually have to overwrite the instruction now */
65 RtlCopyMemory(KdpBreakpointTable
[BpIndex
].Address
,
66 &KdpBreakpointInstruction
,
69 /* Clear any possible previous pending flag and return success */
70 KdpBreakpointTable
[BpIndex
].Flags
&= ~KdpBreakpointPending
;
76 KdpDeleteBreakpoint(IN ULONG BpEntry
)
78 ULONG BpIndex
= BpEntry
- 1;
80 /* Check for invalid breakpoint entry */
81 if (!(BpEntry
) || (BpEntry
> 20)) return FALSE
;
83 /* If the specified breakpoint table entry is not valid, then return FALSE. */
84 if (!KdpBreakpointTable
[BpIndex
].Flags
) return FALSE
;
86 /* Check if the breakpoint is suspended */
87 if (KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointSuspended
)
89 /* Check if breakpoint is not ...? */
90 if (!(KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointExpired
))
92 /* Invalidate it and return success */
93 KdpBreakpointTable
[BpIndex
].Flags
= 0;
98 /* Restore original data, then invalidate it and return success */
99 if (KdpLowWriteContent(BpIndex
)) KdpBreakpointTable
[BpIndex
].Flags
= 0;
105 KdpDeleteBreakpointRange(IN PVOID Base
,
109 BOOLEAN Return
= FALSE
;
111 /* Loop the breakpoint table */
112 for (BpIndex
= 0; BpIndex
< 20; BpIndex
++)
114 /* Make sure that the breakpoint is active and matches the range. */
115 if ((KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointActive
) &&
116 ((KdpBreakpointTable
[BpIndex
].Address
>= Base
) &&
117 (KdpBreakpointTable
[BpIndex
].Address
<= Limit
)))
120 Return
= Return
|| KdpDeleteBreakpoint(BpIndex
+ 1);
124 /* Return to caller */
130 KdpRestoreAllBreakpoints(VOID
)
134 /* No more suspended Breakpoints */
135 BreakpointsSuspended
= FALSE
;
137 /* Loop the breakpoints */
138 for (BpIndex
= 0; BpIndex
< 20; BpIndex
++ )
140 /* Check if they are valid, suspended breakpoints */
141 if ((KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointActive
) &&
142 (KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointSuspended
))
145 KdpBreakpointTable
[BpIndex
].Flags
&= ~KdpBreakpointSuspended
;
146 KdpLowRestoreBreakpoint(BpIndex
);