ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

kdbreak.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/kd64/kdbreak.c
00005  * PURPOSE:         KD64 Breakpoint Support
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  *                  Stefan Ginsberg (stefan.ginsberg@reactos.org)
00008  */
00009 
00010 /* INCLUDES ******************************************************************/
00011 
00012 #include <ntoskrnl.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* FUNCTIONS *****************************************************************/
00017 
00018 ULONG
00019 NTAPI
00020 KdpAddBreakpoint(IN PVOID Address)
00021 {
00022     KD_BREAKPOINT_TYPE Content;
00023     ULONG i;
00024     NTSTATUS Status;
00025 
00026     /* Loop current breakpoints */
00027     for (i = 0; i < KD_BREAKPOINT_MAX; i++)
00028     {
00029         /* Check if the breakpoint is valid */
00030         if ((KdpBreakpointTable[i].Flags & KdpBreakpointActive) &&
00031             (KdpBreakpointTable[i].Address == Address))
00032         {
00033             /* Check if it's pending */
00034             if ((KdpBreakpointTable[i].Flags & KdpBreakpointPending))
00035             {
00036                 /* It's not pending anymore now */
00037                 KdpBreakpointTable[i].Flags &= ~KdpBreakpointPending;
00038                 return i + 1;
00039             }
00040             else
00041             {
00042                 /* Fail */
00043                 return 0;
00044             }
00045         }
00046     }
00047 
00048     /* Find a free entry */
00049     for (i = 0; i < KD_BREAKPOINT_MAX; i++) if (!(KdpBreakpointTable[i].Flags)) break;
00050 
00051     /* Fail if no free entry was found */
00052     if (i == KD_BREAKPOINT_MAX) return 0;
00053 
00054     /* Save the old instruction */
00055     Status = KdpCopyMemoryChunks((ULONG_PTR)Address,
00056                                  &Content,
00057                                  KD_BREAKPOINT_SIZE,
00058                                  0,
00059                                  MMDBG_COPY_UNSAFE,
00060                                  NULL);
00061 
00062     if (!NT_SUCCESS(Status))
00063     {
00064         /* TODO: Set it as a owed breakpoint */
00065         KdpDprintf("Failed to set breakpoint at address 0x%p\n", Address);
00066         return 0;
00067     }
00068 
00069     /* Write the entry */
00070     KdpBreakpointTable[i].Address = Address;
00071     KdpBreakpointTable[i].Content = Content;
00072     KdpBreakpointTable[i].Flags = KdpBreakpointActive;
00073 
00074     /* Write the breakpoint */
00075     Status = KdpCopyMemoryChunks((ULONG_PTR)Address,
00076                                  &KdpBreakpointInstruction,
00077                                  KD_BREAKPOINT_SIZE,
00078                                  0,
00079                                  MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
00080                                  NULL);
00081     if (!NT_SUCCESS(Status))
00082     {
00083         /* This should never happen */
00084         KdpDprintf("Unable to write breakpoint to address 0x%p\n", Address);
00085     }
00086 
00087     /* Return the breakpoint handle */
00088     return i + 1;
00089 }
00090 
00091 BOOLEAN
00092 NTAPI
00093 KdpLowWriteContent(IN ULONG BpIndex)
00094 {
00095     NTSTATUS Status;
00096 
00097     /* Make sure that the breakpoint is actually active */
00098     if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointPending)
00099     {
00100         /* So we have a valid breakpoint, but it hasn't been used yet... */
00101         KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;
00102         return TRUE;
00103     }
00104 
00105     /* Is the original instruction a breakpoint anyway? */
00106     if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction)
00107     {
00108         /* Then leave it that way... */
00109         return TRUE;
00110     }
00111 
00112     /* We have an active breakpoint with an instruction to bring back. Do it. */
00113     Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
00114                                  Address,
00115                                  &KdpBreakpointTable[BpIndex].Content,
00116                                  KD_BREAKPOINT_SIZE,
00117                                  0,
00118                                  MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
00119                                  NULL);
00120     if (!NT_SUCCESS(Status))
00121     {
00122         /* TODO: Set it as a owed breakpoint */
00123         KdpDprintf("Failed to delete breakpoint at address 0x%p\n",
00124                    KdpBreakpointTable[BpIndex].Address);
00125         return FALSE;
00126     }
00127 
00128     /* Everything went fine, return */
00129     return TRUE;
00130 }
00131 
00132 BOOLEAN
00133 NTAPI
00134 KdpLowRestoreBreakpoint(IN ULONG BpIndex)
00135 {
00136     NTSTATUS Status;
00137 
00138     /* Were we not able to remove it earlier? */
00139     if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired)
00140     {
00141         /* Well then, we'll just re-use it and return success! */
00142         KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointExpired;
00143         return TRUE;
00144     }
00145 
00146     /* Are we merely writing a breakpoint on top of another breakpoint? */
00147     if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction)
00148     {
00149         /* Nothing to do then... */
00150         return TRUE;
00151     }
00152 
00153     /* Ok, we actually have to overwrite the instruction now */
00154     Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
00155                                  Address,
00156                                  &KdpBreakpointInstruction,
00157                                  KD_BREAKPOINT_SIZE,
00158                                  0,
00159                                  MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
00160                                  NULL);
00161     if (!NT_SUCCESS(Status))
00162     {
00163         /* FIXME: Set it as a owed breakpoint */
00164         KdpDprintf("Failed to restore breakpoint at address 0x%p\n",
00165                    KdpBreakpointTable[BpIndex].Address);
00166         return FALSE;
00167     }
00168 
00169     /* Clear any possible previous pending flag and return success */
00170     KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;
00171     return TRUE;
00172 }
00173 
00174 BOOLEAN
00175 NTAPI
00176 KdpDeleteBreakpoint(IN ULONG BpEntry)
00177 {
00178     ULONG BpIndex = BpEntry - 1;
00179 
00180     /* Check for invalid breakpoint entry */
00181     if (!(BpEntry) || (BpEntry > KD_BREAKPOINT_MAX)) return FALSE;
00182 
00183     /* If the specified breakpoint table entry is not valid, then return FALSE. */
00184     if (!KdpBreakpointTable[BpIndex].Flags) return FALSE;
00185 
00186     /* Check if the breakpoint is suspended */
00187     if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended)
00188     {
00189         /* Check if breakpoint is not ...? */
00190         if (!(KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired))
00191         {
00192             /* Invalidate it and return success */
00193             KdpBreakpointTable[BpIndex].Flags = 0;
00194             return TRUE;
00195         }
00196     }
00197 
00198     /* Restore original data, then invalidate it and return success */
00199     if (KdpLowWriteContent(BpIndex)) KdpBreakpointTable[BpIndex].Flags = 0;
00200     return TRUE;
00201 }
00202 
00203 BOOLEAN
00204 NTAPI
00205 KdpDeleteBreakpointRange(IN PVOID Base,
00206                          IN PVOID Limit)
00207 {
00208     ULONG BpIndex;
00209     BOOLEAN Return = FALSE;
00210 
00211     /* Loop the breakpoint table */
00212     for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++)
00213     {
00214         /* Make sure that the breakpoint is active and matches the range. */
00215         if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
00216             ((KdpBreakpointTable[BpIndex].Address >= Base) &&
00217              (KdpBreakpointTable[BpIndex].Address <= Limit)))
00218         {
00219             /* Delete it */
00220             Return = Return || KdpDeleteBreakpoint(BpIndex + 1);
00221         }
00222     }
00223 
00224     /* Return to caller */
00225     return Return;
00226 }
00227 
00228 VOID
00229 NTAPI
00230 KdpRestoreAllBreakpoints(VOID)
00231 {
00232     ULONG BpIndex;
00233 
00234     /* No more suspended Breakpoints */
00235     BreakpointsSuspended = FALSE;
00236 
00237     /* Loop the breakpoints */
00238     for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++)
00239     {
00240         /* Check if they are valid, suspended breakpoints */
00241         if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
00242             (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended))
00243         {
00244             /* Unsuspend them */
00245             KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointSuspended;
00246             KdpLowRestoreBreakpoint(BpIndex);
00247         }
00248     }
00249 }
00250 
00251 VOID
00252 NTAPI
00253 KdpSuspendBreakPoint(IN ULONG BpEntry)
00254 {
00255     ULONG BpIndex = BpEntry - 1;
00256 
00257     /* Check if this is a valid, unsuspended breakpoint */
00258     if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
00259         !(KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended))
00260     {
00261         /* Suspend it */
00262         KdpBreakpointTable[BpIndex].Flags |= KdpBreakpointSuspended;
00263         KdpLowWriteContent(BpIndex);
00264     }
00265 }
00266 
00267 VOID
00268 NTAPI
00269 KdpSuspendAllBreakPoints(VOID)
00270 {
00271     ULONG BpEntry;
00272 
00273     /* Breakpoints are suspended */
00274     BreakpointsSuspended = TRUE;
00275 
00276     /* Loop every breakpoint */
00277     for (BpEntry = 1; BpEntry <= KD_BREAKPOINT_MAX; BpEntry++)
00278     {
00279         /* Suspend it */
00280         KdpSuspendBreakPoint(BpEntry);
00281     }
00282 }

Generated on Sat May 26 2012 04:36:15 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.