[NTOS:INBV] Implement rotation bar for boot screen
[reactos.git] / ntoskrnl / kdbg / kdb.c
index 17f4c78..6b9d469 100644 (file)
@@ -38,6 +38,7 @@ static PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]; /* Ena
 static PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]; /* Enabled hardware breakpoints, orderless */
 static PKDB_BREAKPOINT KdbBreakPointToReenable = NULL; /* Set to a breakpoint struct when single stepping after
                                                           a software breakpoint was hit, to reenable it */
+static BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep;
 LONG KdbLastBreakPointNr = -1;  /* Index of the breakpoint which cause KDB to be entered */
 ULONG KdbNumSingleSteps = 0; /* How many single steps to do */
 BOOLEAN KdbSingleStepOver = FALSE; /* Whether to step over calls/reps. */
@@ -77,7 +78,7 @@ static KDB_ENTER_CONDITION KdbEnterConditions[][2] =
     { KdbDoNotEnter,      KdbEnterFromKmode },   /* 17: Alignment Check */
     { KdbDoNotEnter,      KdbEnterFromKmode },   /* 18: Machine Check */
     { KdbDoNotEnter,      KdbEnterFromKmode },   /* 19: SIMD fault */
-    { KdbEnterAlways,     KdbEnterAlways },      /* 20: Assertion failure */
+    { KdbEnterFromKmode,  KdbDoNotEnter },       /* 20: Assertion failure */
     { KdbDoNotEnter,      KdbEnterFromKmode }    /* Last entry: used for unknown exceptions */
 };
 
@@ -136,42 +137,15 @@ KdbpTrapFrameToKdbTrapFrame(
     PKTRAP_FRAME TrapFrame,
     PKDB_KTRAP_FRAME KdbTrapFrame)
 {
-    ULONG TrapCr0, TrapCr2, TrapCr3, TrapCr4;
-
     /* Copy the TrapFrame only up to Eflags and zero the rest*/
     RtlCopyMemory(&KdbTrapFrame->Tf, TrapFrame, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
     RtlZeroMemory((PVOID)((ULONG_PTR)&KdbTrapFrame->Tf + FIELD_OFFSET(KTRAP_FRAME, HardwareEsp)),
                   sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
 
-#ifndef _MSC_VER
-   asm volatile(
-      "movl %%cr0, %0"    "\n\t"
-      "movl %%cr2, %1"    "\n\t"
-      "movl %%cr3, %2"    "\n\t"
-      "movl %%cr4, %3"    "\n\t"
-      : "=r"(TrapCr0), "=r"(TrapCr2),
-        "=r"(TrapCr3), "=r"(TrapCr4));
-#else
-   __asm
-   {
-       mov eax, cr0;
-       mov TrapCr0, eax;
-
-       mov eax, cr2;
-       mov TrapCr2, eax;
-
-       mov eax, cr3;
-       mov TrapCr3, eax;
-/* FIXME: What's the problem with cr4? */
-       //mov eax, cr4;
-       //mov TrapCr4, eax;
-   }
-#endif
-
-    KdbTrapFrame->Cr0 = TrapCr0;
-    KdbTrapFrame->Cr2 = TrapCr2;
-    KdbTrapFrame->Cr3 = TrapCr3;
-    KdbTrapFrame->Cr4 = TrapCr4;
+    KdbTrapFrame->Cr0 = __readcr0();
+    KdbTrapFrame->Cr2 = __readcr2();
+    KdbTrapFrame->Cr3 = __readcr3();
+    KdbTrapFrame->Cr4 = __readcr4();
 
     KdbTrapFrame->Tf.HardwareEsp = KiEspFromTrapFrame(TrapFrame);
     KdbTrapFrame->Tf.HardwareSegSs = (USHORT)(KiSsFromTrapFrame(TrapFrame) & 0xFFFF);
@@ -1236,7 +1210,7 @@ KdbpCallMainLoop(VOID)
  * Disables interrupts, releases display ownership, ...
  */
 static VOID
-KdbpInternalEnter()
+KdbpInternalEnter(VOID)
 {
     PETHREAD Thread;
     PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
@@ -1371,8 +1345,12 @@ KdbEnterDebuggerException(
     KdbCurrentProcess = PsGetCurrentProcess();
 
     /* Set continue type to kdContinue for single steps and breakpoints */
-    if (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT)
+    if (ExceptionCode == STATUS_SINGLE_STEP ||
+        ExceptionCode == STATUS_BREAKPOINT ||
+        ExceptionCode == STATUS_ASSERTION_FAILURE)
+    {
         ContinueType = kdContinue;
+    }
 
     /* Check if we should handle the exception. */
     /* FIXME - won't get all exceptions here :( */
@@ -1403,6 +1381,15 @@ KdbEnterDebuggerException(
                 KdbpPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
                 KeBugCheck(0); // FIXME: Proper bugcode!
             }
+
+            /* Also since we are past the int3 now, decrement EIP in the
+               TrapFrame. This is only needed because KDBG insists on working
+               with the TrapFrame instead of with the Context, as it is supposed
+               to do. The context has already EIP point to the int3, since
+               KiDispatchException accounts for that. Whatever we do here with
+               the TrapFrame does not matter anyway, since KiDispatchException
+               will overwrite it with the values from the Context! */
+            TrapFrame->Eip--;
         }
 
         if ((BreakPoint->Type == KdbBreakPointHardware) &&
@@ -1424,8 +1411,6 @@ KdbEnterDebuggerException(
             /* Delete the temporary breakpoint which was used to step over or into the instruction. */
             KdbpDeleteBreakPoint(-1, BreakPoint);
 
-            TrapFrame->Eip--;
-
             if (--KdbNumSingleSteps > 0)
             {
                 if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
@@ -1516,9 +1501,15 @@ KdbEnterDebuggerException(
             if (KdbNumSingleSteps == 0)
                 Context->EFlags &= ~EFLAGS_TF;
 
-            goto continue_execution; /* return */
+            if (!KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep)
+            {
+                goto continue_execution; /* return */
+            }
         }
 
+        /* Quoth the raven, 'Nevermore!' */
+        KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = FALSE;
+
         /* Check if we expect a single step */
         if ((TrapFrame->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
         {
@@ -1641,6 +1632,9 @@ KdbEnterDebuggerException(
     /* Check if we should single step */
     if (KdbNumSingleSteps > 0)
     {
+        /* Variable explains itself! */
+        KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = TRUE;
+
         if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Tf.Eip)) ||
             (!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Tf.Eip)))
         {