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 KdpAddBreakpoint(IN PVOID Address
)
24 /* Loop current breakpoints */
25 for (i
= 0; i
< 20; i
++)
27 /* Check if the breakpoint is valid */
28 if ((KdpBreakpointTable
[i
].Flags
& KdpBreakpointActive
) &&
29 (KdpBreakpointTable
[i
].Address
== Address
))
31 /* Check if it's pending */
32 if ((KdpBreakpointTable
[i
].Flags
& KdpBreakpointPending
))
34 /* It's not pending anymore now */
35 KdpBreakpointTable
[i
].Flags
&= ~KdpBreakpointPending
;
46 /* Find a free entry */
47 for (i
= 0; i
< 20; i
++) if (!(KdpBreakpointTable
[i
].Flags
)) break;
49 /* Fail if no free entry was found */
50 if (i
== 20) return 0;
52 /* Save the old instruction */
53 RtlCopyMemory(&Content
, Address
, sizeof(UCHAR
));
56 KdpBreakpointTable
[i
].Address
= Address
;
57 KdpBreakpointTable
[i
].Content
= Content
;
58 KdpBreakpointTable
[i
].Flags
= KdpBreakpointActive
;
60 /* Write the INT3 and return the handle */
61 RtlCopyMemory(Address
, &KdpBreakpointInstruction
, sizeof(UCHAR
));
67 KdpLowWriteContent(IN ULONG BpIndex
)
69 /* Make sure that the breakpoint is actually active */
70 if (KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointPending
)
72 /* So we have a valid breakpoint, but it hasn't been used yet... */
73 KdpBreakpointTable
[BpIndex
].Flags
&= ~KdpBreakpointPending
;
77 /* Is the original instruction an INT3 anyway? */
78 if (KdpBreakpointTable
[BpIndex
].Content
== KdpBreakpointInstruction
)
80 /* Then leave it that way... */
84 /* We have an active breakpoint with an instruction to bring back. Do it. */
85 RtlCopyMemory(KdpBreakpointTable
[BpIndex
].Address
,
86 &KdpBreakpointTable
[BpIndex
].Content
,
89 /* Everything went fine, return */
95 KdpLowRestoreBreakpoint(IN ULONG BpIndex
)
97 /* Were we not able to remove it earlier? */
98 if (KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointExpired
)
100 /* Well then, we'll just re-use it and return success! */
101 KdpBreakpointTable
[BpIndex
].Flags
&= ~KdpBreakpointExpired
;
105 /* Are we merely writing an INT3 on top of another INT3? */
106 if (KdpBreakpointTable
[BpIndex
].Content
== KdpBreakpointInstruction
)
108 /* Nothing to do then... */
112 /* Ok, we actually have to overwrite the instruction now */
113 RtlCopyMemory(KdpBreakpointTable
[BpIndex
].Address
,
114 &KdpBreakpointInstruction
,
117 /* Clear any possible previous pending flag and return success */
118 KdpBreakpointTable
[BpIndex
].Flags
&= ~KdpBreakpointPending
;
124 KdpDeleteBreakpoint(IN ULONG BpEntry
)
126 ULONG BpIndex
= BpEntry
- 1;
128 /* Check for invalid breakpoint entry */
129 if (!(BpEntry
) || (BpEntry
> 20)) return FALSE
;
131 /* If the specified breakpoint table entry is not valid, then return FALSE. */
132 if (!KdpBreakpointTable
[BpIndex
].Flags
) return FALSE
;
134 /* Check if the breakpoint is suspended */
135 if (KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointSuspended
)
137 /* Check if breakpoint is not ...? */
138 if (!(KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointExpired
))
140 /* Invalidate it and return success */
141 KdpBreakpointTable
[BpIndex
].Flags
= 0;
146 /* Restore original data, then invalidate it and return success */
147 if (KdpLowWriteContent(BpIndex
)) KdpBreakpointTable
[BpIndex
].Flags
= 0;
153 KdpDeleteBreakpointRange(IN PVOID Base
,
157 BOOLEAN Return
= FALSE
;
159 /* Loop the breakpoint table */
160 for (BpIndex
= 0; BpIndex
< 20; BpIndex
++)
162 /* Make sure that the breakpoint is active and matches the range. */
163 if ((KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointActive
) &&
164 ((KdpBreakpointTable
[BpIndex
].Address
>= Base
) &&
165 (KdpBreakpointTable
[BpIndex
].Address
<= Limit
)))
168 Return
= Return
|| KdpDeleteBreakpoint(BpIndex
+ 1);
172 /* Return to caller */
178 KdpRestoreAllBreakpoints(VOID
)
182 /* No more suspended Breakpoints */
183 BreakpointsSuspended
= FALSE
;
185 /* Loop the breakpoints */
186 for (BpIndex
= 0; BpIndex
< 20; BpIndex
++ )
188 /* Check if they are valid, suspended breakpoints */
189 if ((KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointActive
) &&
190 (KdpBreakpointTable
[BpIndex
].Flags
& KdpBreakpointSuspended
))
193 KdpBreakpointTable
[BpIndex
].Flags
&= ~KdpBreakpointSuspended
;
194 KdpLowRestoreBreakpoint(BpIndex
);