[NTOSKRNL]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Thu, 29 Apr 2010 16:39:52 +0000 (16:39 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Thu, 29 Apr 2010 16:39:52 +0000 (16:39 +0000)
- On backtraces, print the address of the call instruction (assumed 5 bytes lentgh) instead of the return address, which in many cases does not make sense. (WinDbg does it this way, too)
- Fix Ke386SaveFpuState to store the fpu state in the buffer, but in the pointer to the buffer
- Anable Ke386SaveFpuState to save the floating point state in KiNpxHandler and KiTrap13Handler, so we know what error we got.
- Disable saving debug registers in the trap frame, as long as the kernel doesn't support this
- Fixes ntdll_winetest exception / OllyDbg freeze/reboot

See issue #5301 for more details.

svn path=/trunk/; revision=47060

reactos/ntoskrnl/include/internal/i386/intrin_i.h
reactos/ntoskrnl/kdbg/kdb_cli.c
reactos/ntoskrnl/ke/i386/exp.c
reactos/ntoskrnl/ke/i386/traphdlr.c

index 9450184..6cb2a7c 100644 (file)
@@ -42,11 +42,11 @@ Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
     extern ULONG KeI386FxsrPresent;
     if (KeI386FxsrPresent)
     {
-        __asm__ __volatile__ ("fxsave %0\n" : : "m"(SaveArea));
+        __asm__ __volatile__ ("fxsave %0\n" : : "m"(*SaveArea));
     }
     else
     {
-        __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(SaveArea));
+        __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(*SaveArea));
     }
 }
 
index fa42826..4c469fd 100644 (file)
@@ -823,7 +823,8 @@ KdbpCmdBackTrace(
             break;
         }
 
-        if (!KdbSymPrintAddress((PVOID)Address))
+        /* Print the location of the call instruction */
+        if (!KdbSymPrintAddress((PVOID)(Address - 5)))
             KdbpPrint("<%08x>\n", Address);
         else
             KdbpPrint("\n");
index 284ff19..38dded7 100644 (file)
@@ -584,7 +584,7 @@ KeContextToTrapFrame(IN PCONTEXT Context,
     }
 
     /* Handle the Debug Registers */
-    if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
+    if (0 && (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
     {
         /* Loop DR registers */
         for (i = 0; i < 4; i++)
index f9a954e..b9033c2 100644 (file)
@@ -240,7 +240,7 @@ KiNpxHandler(IN PKTRAP_FRAME TrapFrame,
     }
 
     /* User or kernel trap -- get ready to issue an exception */
-    if (Thread->NpxState == NPX_STATE_NOT_LOADED)
+    //if (Thread->NpxState == NPX_STATE_NOT_LOADED)
     {
         /* Update CR0 */
         Cr0 = __readcr0();
@@ -248,7 +248,7 @@ KiNpxHandler(IN PKTRAP_FRAME TrapFrame,
         __writecr0(Cr0);
 
         /* Save FPU state */
-        //Ke386SaveFpuState(SaveArea);
+        Ke386SaveFpuState(SaveArea);
 
         /* Mark CR0 state dirty */
         Cr0 |= NPX_STATE_NOT_LOADED;
@@ -1082,64 +1082,64 @@ KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
      * we should probably table this for now since it's not a "real" issue.
      */
      
-     /*
-      * NOTE2: Another scenario is the IRET during a V8086 restore (BIOS Call)
-      * which will cause a GPF since the trap frame is a total mess (on purpose)
-      * as built in KiEnterV86Mode.
-      *
-      * The idea is to scan for IRET, scan for the known EIP adress, validate CS
-      * and then manually issue a jump to the V8086 return EIP.
-      */
-     Instructions = (PUCHAR)TrapFrame->Eip;
-     if (Instructions[0] == 0xCF)
-     {
-         /*
-          * Some evil shit is going on here -- this is not the SS:ESP you're 
-          * looking for! Instead, this is actually CS:EIP you're looking at!
-          * Why? Because part of the trap frame actually corresponds to the IRET
-          * stack during the trap exit!
-          */
-          if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) &&
-              (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK)))
-          {
-              /* Exit the V86 trap! */
-              Ki386BiosCallReturnAddress(TrapFrame);
-          }
-          else
-          {
-              /* Otherwise, this is another kind of IRET fault */
-              UNIMPLEMENTED;
-              while (TRUE);
-          }
-     }
+    /*
+     * NOTE2: Another scenario is the IRET during a V8086 restore (BIOS Call)
+     * which will cause a GPF since the trap frame is a total mess (on purpose)
+     * as built in KiEnterV86Mode.
+     *
+     * The idea is to scan for IRET, scan for the known EIP adress, validate CS
+     * and then manually issue a jump to the V8086 return EIP.
+     */
+    Instructions = (PUCHAR)TrapFrame->Eip;
+    if (Instructions[0] == 0xCF)
+    {
+        /*
+         * Some evil shit is going on here -- this is not the SS:ESP you're 
+         * looking for! Instead, this is actually CS:EIP you're looking at!
+         * Why? Because part of the trap frame actually corresponds to the IRET
+         * stack during the trap exit!
+         */
+        if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) &&
+            (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK)))
+        {
+            /* Exit the V86 trap! */
+            Ki386BiosCallReturnAddress(TrapFrame);
+        }
+        else
+        {
+            /* Otherwise, this is another kind of IRET fault */
+            UNIMPLEMENTED;
+            while (TRUE);
+        }
+    }
      
      /* So since we're not dealing with the above case, check for RDMSR/WRMSR */
-     if ((Instructions[0] == 0xF) &&            // 2-byte opcode
+    if ((Instructions[0] == 0xF) &&            // 2-byte opcode
         (((Instructions[1] >> 8) == 0x30) ||        // RDMSR
          ((Instructions[2] >> 8) == 0x32)))         // WRMSR
-     {
+    {
         /* Unknown CPU MSR, so raise an access violation */
         KiDispatchException0Args(STATUS_ACCESS_VIOLATION,
                                  TrapFrame->Eip,
                                  TrapFrame);
-     }
-
-     /* Check for lazy segment load */
-     if (TrapFrame->SegDs != (KGDT_R3_DATA | RPL_MASK))
-     {
-         /* Fix it */
-         TrapFrame->SegDs = (KGDT_R3_DATA | RPL_MASK);
-     }
-     else if (TrapFrame->SegEs != (KGDT_R3_DATA | RPL_MASK))
-     {
+    }
+
+    /* Check for lazy segment load */
+    if (TrapFrame->SegDs != (KGDT_R3_DATA | RPL_MASK))
+    {
+        /* Fix it */
+        TrapFrame->SegDs = (KGDT_R3_DATA | RPL_MASK);
+    }
+    else if (TrapFrame->SegEs != (KGDT_R3_DATA | RPL_MASK))
+    {
         /* Fix it */
         TrapFrame->SegEs = (KGDT_R3_DATA | RPL_MASK);
-     }
-     else
-     {
-         /* Whatever it is, we can't handle it */
-         KiSystemFatalException(EXCEPTION_GP_FAULT, TrapFrame);
-     }
+    }
+    else
+    {
+        /* Whatever it is, we can't handle it */
+        KiSystemFatalException(EXCEPTION_GP_FAULT, TrapFrame);
+    }
     
     /* Return to where we came from */
     KiTrapReturn(TrapFrame);
@@ -1353,7 +1353,7 @@ KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
     __writecr0(Cr0);
     
     /* Save FPU state */
-    //Ke386SaveFpuState(SaveArea);
+    Ke386SaveFpuState(SaveArea);
     
     /* Mark CR0 state dirty */
     Cr0 |= NPX_STATE_NOT_LOADED;
@@ -1379,7 +1379,7 @@ KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
                                                 FSW_UNDERFLOW |
                                                 FSW_PRECISION);
     Error &= MxCsrMask;
-    
+
     /* Now handle any of those legal errors */
     if (Error & (FSW_INVALID_OPERATION |
                  FSW_DENORMAL |