📄 exceptcommon.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++
Module Name:
ExceptCommon.cpp
Abstract:
Save the exception context for use by FlexiPTMI and PackData.
--*/
#include "osaxs_p.h"
#ifdef SHx
// for SR_DSP_ENABLED and SR_FPU_DISABLED
#include "shx.h"
#endif
CONTEXT *g_pExceptionCtx = NULL;
SAVED_THREAD_STATE * g_psvdThread = NULL;
/*++
Routine Name:
GetThreadProgramCounter
Argument:
pth - pointer to thread structure / thread representation
--*/
DWORD GetThreadProgramCounter (const THREAD *pth)
{
if (! OsAxsIsCurThread (pth))
{
return GetThreadIP (pth);
}
return CONTEXT_TO_PROGRAM_COUNTER (g_pExceptionCtx);
}
#if defined(x86)
VOID FPUFlushContextx86(IN CONTEXT* pCtx)
{
PFXSAVE_AREA FxArea;
PFLOATING_SAVE_AREA FnArea;
DWORD i, j;
if (*g_OsaxsData.ppCurFPUOwner)
{
KCall ((PKFN) g_OsaxsData.FPUFlushContext, 0, 0, 0);
if ((*g_OsaxsData.pdwProcessorFeatures) & CPUID_FXSR)
{
FxArea = (PFXSAVE_AREA) PTH_TO_FLTSAVEAREAPTR(pCurThread);
FnArea = &pCtx->FloatSave;
FnArea->ControlWord = FxArea->ControlWord;
FnArea->StatusWord = FxArea->StatusWord;
FnArea->TagWord = 0;
for (i = 0; i < FN_BITS_PER_TAGWORD; i+=2) {
if (((FxArea->TagWord >> (i/2)) & FX_TAG_VALID) != FX_TAG_VALID)
FnArea->TagWord |= (FN_TAG_EMPTY << i);
}
FnArea->ErrorOffset = FxArea->ErrorOffset;
FnArea->ErrorSelector = FxArea->ErrorSelector & 0xFFFF;
FnArea->ErrorSelector |= (((DWORD)FxArea->ErrorOpcode) << 16);
FnArea->DataOffset = FxArea->DataOffset;
FnArea->DataSelector = FxArea->DataSelector;
memset(&FnArea->RegisterArea[0], 0, SIZE_OF_80387_REGISTERS);
for (i = 0; i < NUMBER_OF_FP_REGISTERS; i++) {
for (j = 0; j < BYTES_PER_FP_REGISTER; j++) {
FnArea->RegisterArea[i*BYTES_PER_FP_REGISTER+j] =
FxArea->RegisterArea[i*BYTES_PER_FX_REGISTER+j];
}
}
}
else
{
pCtx->FloatSave = *(PTH_TO_FLTSAVEAREAPTR(pCurThread));
}
}
}
#endif
BOOL KdpFlushExtendedContext(CONTEXT* pCtx)
/*++
Routine Description:
For CPUs that support it, this function retrieves the extended portion of the context
that is only backed up when used by a thread.
Arguments:
pCtx - Supplies the exception context to be updated.
Return Value:
TRUE if the current thread was the owner of the extended context
--*/
{
BOOL fOwner = FALSE;
// FPU/DSPFlushContext code. Calling these functions alters the state of the g_CurFPUOwner
// thread in that it disables the FPU/DSP (ExceptionDispatch will reenable in on the next
// access). For SHx, the disable alters the context, so we update the exception context
// to reflect the change. See also: KdpTrap, KdpSetContext.
//
//
#if defined(SHx) && !defined(SH4) && !defined(SH3e)
// copy over the DSP registers from the thread context
fOwner = (pCurThread == g_CurDSPOwner);
g_OsaxsData.DSPFlushContext ();
// if DSPFlushContext updated pCurThread's PSR, keep exception context in sync
if (fOwner) pCtx->Psr &= ~SR_DSP_ENABLED;
memcpy (&(pCtx->DSR), &(pCurThread->ctx.DSR), sizeof (DWORD) * 13);
#endif
// Get the floating point registers from the thread context
#if defined(SH4)
fOwner = (pCurThread == g_CurFPUOwner);
g_OsaxsData.FPUFlushContext ();
// if FPUFlushContext updated pCurThread's PSR, keep exception context in sync
if (fOwner) pCtx->Psr |= SR_FPU_DISABLED;
memcpy (&(pCtx->Fpscr), &(pCurThread->ctx.Fpscr), sizeof (DWORD) * 34);
#elif defined(MIPS_HAS_FPU)
g_OsaxsData.FPUFlushContext ();
pCtx->Fsr = pCurThread->ctx.Fsr;
memcpy (&(pCtx->FltF0), &(pCurThread->ctx.FltF0), sizeof (FREG_TYPE) * 32);
#elif defined(ARM)
// FPUFlushContext might modify FpExc, but apparently it can't be restored, so we shouldn't bother
// trying update our context with it
g_OsaxsData.FPUFlushContext ();
memcpy (&(pCtx->Fpscr), &(pCurThread->ctx.Fpscr), sizeof (DWORD) * 43);
#elif defined(x86)
FPUFlushContextx86(pCtx);
#endif
return fOwner;
}
/*++
Routine Name:
SaveExceptionContext
Routine Description:
Save the pointer to the exception context and saved thread state.
--*/
HRESULT SaveExceptionContext (CONTEXT * pCtx,
SAVED_THREAD_STATE * psvdThread,
CONTEXT ** ppCtxSave,
SAVED_THREAD_STATE ** ppsvdThreadSave)
{
if (ppCtxSave)
{
*ppCtxSave = g_pExceptionCtx;
}
if (ppsvdThreadSave)
{
*ppsvdThreadSave = g_psvdThread;
}
g_pExceptionCtx = pCtx;
g_psvdThread = psvdThread;
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -