[NTOSKRNL]

- 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
This commit is contained in:
Timo Kreuzer 2010-04-29 16:39:52 +00:00
parent d34a8d86bc
commit 91a35b7ec1
4 changed files with 56 additions and 55 deletions

View 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));
}
}

View 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");

View 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++)

View 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;