summaryrefslogtreecommitdiff
path: root/src/vm/exceptionhandling.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/exceptionhandling.cpp')
-rw-r--r--src/vm/exceptionhandling.cpp131
1 files changed, 54 insertions, 77 deletions
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index ed155eb998..262d3526eb 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -7,10 +7,6 @@
#include "common.h"
-#ifndef FEATURE_PAL
-#include "securityprincipal.h"
-#endif // !FEATURE_PAL
-
#ifdef WIN64EXCEPTIONS
#include "exceptionhandling.h"
#include "dbginterface.h"
@@ -94,8 +90,8 @@ bool FixNonvolatileRegisters(UINT_PTR uOriginalSP,
MethodDesc * GetUserMethodForILStub(Thread * pThread, UINT_PTR uStubSP, MethodDesc * pILStubMD, Frame ** ppFrameOut);
#ifdef FEATURE_PAL
-BOOL PALAPI HandleHardwareException(PAL_SEHException* ex);
-BOOL PALAPI IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord);
+BOOL HandleHardwareException(PAL_SEHException* ex);
+BOOL IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord);
#endif // FEATURE_PAL
static ExceptionTracker* GetTrackerMemory()
@@ -393,7 +389,7 @@ void ExceptionTracker::UpdateNonvolatileRegisters(CONTEXT *pContextRecord, REGDI
do { \
if (pRegDisplay->pCurrentContextPointers->reg != NULL) \
{ \
- STRESS_LOG3(LF_GCROOTS, LL_INFO100, "Updating reg %p to %p from %p\n", \
+ STRESS_LOG3(LF_GCROOTS, LL_INFO100, "Updating " #reg " %p to %p from %p\n", \
pContextRecord->reg, \
*pRegDisplay->pCurrentContextPointers->reg, \
pRegDisplay->pCurrentContextPointers->reg); \
@@ -409,7 +405,14 @@ void ExceptionTracker::UpdateNonvolatileRegisters(CONTEXT *pContextRecord, REGDI
} \
} while (0)
-#if defined(_TARGET_AMD64_)
+#if defined(_TARGET_X86_)
+
+ UPDATEREG(Ebx);
+ UPDATEREG(Esi);
+ UPDATEREG(Edi);
+ UPDATEREG(Ebp);
+
+#elif defined(_TARGET_AMD64_)
UPDATEREG(Rbx);
UPDATEREG(Rbp);
@@ -1205,12 +1208,9 @@ bool FixNonvolatileRegisters(UINT_PTR uOriginalSP,
CONTRACTL_END;
CONTEXT _ctx = {0};
-#if defined(_TARGET_AMD64_)
- REGDISPLAY regdisp = {0};
-#else
+
// Ctor will initialize it to NULL
REGDISPLAY regdisp;
-#endif // _TARGET_AMD64_
pThread->FillRegDisplay(&regdisp, &_ctx);
@@ -1373,6 +1373,8 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
// </ARM and ARM64>
pThread->InitRegDisplay(pcfThisFrame->pRD, pDispatcherContext->ContextRecord, true);
+ bool fAdjustRegdisplayControlPC = false;
+
// The "if" check below is trying to determine when we have a valid current context in DC->ContextRecord and whether, or not,
// RegDisplay needs to be fixed up to set SP and ControlPC to have the values for the current frame for which personality routine
// is invoked.
@@ -1418,7 +1420,6 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
// However, we do this *only* when "ControlPCForEHSearch" is the same as "DispatcherContext->ControlPC",
// indicating we are not using the thread-abort reraise loop prevention logic.
//
- bool fAdjustRegdisplayControlPC = false;
if (pDispatcherContext->ControlPc == ControlPCForEHSearch)
{
// Since DispatcherContext->ControlPc is used to initialize the
@@ -1434,7 +1435,9 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
// Remove the Thumb bit
ControlPCForEHSearch = ThumbCodeToDataPointer<DWORD_PTR, DWORD_PTR>(ControlPCForEHSearch);
#endif
+#endif // _TARGET_ARM_ || _TARGET_ARM64_
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) || defined(_TARGET_X86_)
// If the OS indicated that the IP is a callsite, then adjust the ControlPC by decrementing it
// by two. This is done because unwinding at callsite will make ControlPC point to the
// instruction post the callsite. If a protected region ends "at" the callsite, then
@@ -1457,7 +1460,7 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
pcfThisFrame->isIPadjusted = true;
}
}
-#endif // _TARGET_ARM_ || _TARGET_ARM64_
+#endif // _TARGET_ARM_ || _TARGET_ARM64_ || _TARGET_X86_
pcfThisFrame->codeInfo.Init(ControlPCForEHSearch);
@@ -1614,7 +1617,7 @@ CLRUnwindStatus ExceptionTracker::ProcessOSExceptionNotification(
ExceptionTracker::InitializeCrawlFrame(&cfThisFrame, pThread, sf, &regdisp, pDispatcherContext, ControlPc, &uMethodStartPC, this);
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
uCallerSP = EECodeManager::GetCallerSp(cfThisFrame.pRD);
#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
// On ARM & ARM64, the EstablisherFrame is the value of SP at the time a function was called and before it's prolog
@@ -2871,28 +2874,6 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
// we probably don't want to be so strict in not calling handlers.
if (! IsStackOverflowException())
{
-#ifndef FEATURE_PAL
- // Check for any impersonation on the frame and save that for use during EH filter callbacks
- OBJECTREF* pRefSecDesc = pcfThisFrame->GetAddrOfSecurityObject();
- if (pRefSecDesc != NULL && *pRefSecDesc != NULL)
- {
- GCX_COOP();
- FRAMESECDESCREF fsdRef = (FRAMESECDESCREF)*pRefSecDesc;
- if (fsdRef->GetCallerToken() != NULL)
- {
- m_hCallerToken = fsdRef->GetCallerToken();
- STRESS_LOG1(LF_EH, LL_INFO100, "In COMPlusThrowCallback. Found non-NULL callertoken on FSD:%d\n",m_hCallerToken);
- if (!m_ExceptionFlags.ImpersonationTokenSet())
- {
- m_hImpersonationToken = fsdRef->GetImpersonationToken();
- STRESS_LOG1(LF_EH, LL_INFO100, "In COMPlusThrowCallback. Found non-NULL impersonationtoken on FSD:%d\n",m_hImpersonationToken);
- m_ExceptionFlags.SetImpersonationTokenSet();
- }
- }
- }
- BOOL impersonating = FALSE;
-#endif // !FEATURE_PAL
-
// Save the current EHClause Index and Establisher of the clause post which
// ThreadAbort was raised. This is done an exception handled inside a filter
// reset the state that was setup before the filter was invoked.
@@ -2905,16 +2886,6 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
EX_TRY
{
-#ifndef FEATURE_PAL
- if (m_hCallerToken != NULL)
- {
- STRESS_LOG1(LF_EH, LL_INFO100, "About to call filter with hCallerToken = %d\n",m_hCallerToken);
- // CLR_ImpersonateLoggedOnUser fails fast on error
- COMPrincipal::CLR_ImpersonateLoggedOnUser(m_hCallerToken);
- impersonating = TRUE;
- }
-#endif // !FEATURE_PAL
-
// We want to call filters even if the thread is aborting, so suppress abort
// checks while the filter runs.
ThreadPreventAsyncHolder preventAbort(TRUE);
@@ -2944,29 +2915,10 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
GCX_COOP();
dwResult = CallHandler(dwFilterStartPC, sf, &EHClause, pMD, Filter ARM_ARG(pCurRegDisplay->pCallerContext) ARM64_ARG(pCurRegDisplay->pCallerContext));
}
-
-#ifndef FEATURE_PAL
- if (impersonating)
- {
- STRESS_LOG1(LF_EH, LL_INFO100, "After calling filter, resetting to hImpersonationToken = %d\n",m_hImpersonationToken);
- // CLR_ImpersonateLoggedOnUser fails fast on error
- COMPrincipal::CLR_ImpersonateLoggedOnUser(m_hImpersonationToken);
- impersonating = FALSE;
- }
-#endif // !FEATURE_PAL
}
EX_CATCH
{
// We had an exception in filter invocation that remained unhandled.
-#ifndef FEATURE_PAL
- if (impersonating)
- {
- STRESS_LOG1(LF_EH, LL_INFO100, "Filter threw exception. In Catch. Resetting to hImpersonationToken = %d\n",m_hImpersonationToken);
- // CLR_ImpersonateLoggedOnUser fails fast on error
- COMPrincipal::CLR_ImpersonateLoggedOnUser(m_hImpersonationToken);
- impersonating = FALSE;
- }
-#endif // !FEATURE_PAL
// Sync managed exception state, for the managed thread, based upon the active exception tracker.
pThread->SyncManagedExceptionState(false);
@@ -4385,7 +4337,7 @@ VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartConte
dispatcherContext.FunctionEntry = codeInfo.GetFunctionEntry();
dispatcherContext.ControlPc = controlPc;
dispatcherContext.ImageBase = codeInfo.GetModuleBase();
-#if defined(_TARGET_ARM_)
+#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
dispatcherContext.ControlPcIsUnwound = !!(currentFrameContext->ContextFlags & CONTEXT_UNWOUND_TO_CALL);
#endif
// Check whether we have a function table entry for the current controlPC.
@@ -4536,7 +4488,7 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex, CONTEXT
dispatcherContext.FunctionEntry = codeInfo.GetFunctionEntry();
dispatcherContext.ControlPc = controlPc;
dispatcherContext.ImageBase = codeInfo.GetModuleBase();
-#if defined(_TARGET_ARM_)
+#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
dispatcherContext.ControlPcIsUnwound = !!(frameContext->ContextFlags & CONTEXT_UNWOUND_TO_CALL);
#endif
@@ -4717,6 +4669,7 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
ThreadExceptionState * pCurTES = pCurThread->GetExceptionState();
_ASSERTE(pCurTES != NULL);
+#ifdef FEATURE_CORRUPTING_EXCEPTIONS
ExceptionTracker* pEHTracker = pCurTES->GetCurrentExceptionTracker();
if (pEHTracker == NULL)
{
@@ -4728,12 +4681,13 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
pCurTES->SetLastActiveExceptionCorruptionSeverity(severity);
}
+#endif // FEATURE_CORRUPTING_EXCEPTIONS
}
throw std::move(ex);
}
-#ifdef _AMD64_
+#if defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
/*++
Function :
@@ -4750,8 +4704,29 @@ Return value :
--*/
VOID* GetRegisterAddressByIndex(PCONTEXT pContext, UINT index)
{
+#if defined(_TARGET_AMD64_)
_ASSERTE(index < 16);
return &((&pContext->Rax)[index]);
+#elif defined(_TARGET_X86_)
+ _ASSERTE(index < 8);
+
+ static const SIZE_T OFFSET_OF_REGISTERS[] =
+ {
+ offsetof(CONTEXT, Eax),
+ offsetof(CONTEXT, Ecx),
+ offsetof(CONTEXT, Edx),
+ offsetof(CONTEXT, Ebx),
+ offsetof(CONTEXT, Esp),
+ offsetof(CONTEXT, Ebp),
+ offsetof(CONTEXT, Esi),
+ offsetof(CONTEXT, Edi),
+ };
+
+ return (VOID*)(PBYTE(pContext) + OFFSET_OF_REGISTERS[index]);
+#else
+ PORTABILITY_ASSERT("GetRegisterAddressByIndex");
+ return NULL;
+#endif
}
/*++
@@ -5023,7 +4998,7 @@ Return value :
--*/
bool IsDivByZeroAnIntegerOverflow(PCONTEXT pContext)
{
- BYTE * ip = (BYTE*)pContext->Rip;
+ BYTE * ip = (BYTE *)GetIP(pContext);
BYTE rex = 0;
bool hasOpSizePrefix = false;
@@ -5055,7 +5030,7 @@ bool IsDivByZeroAnIntegerOverflow(PCONTEXT pContext)
// must have been an overflow.
return divisor != 0;
}
-#endif //_AMD64_
+#endif // _TARGET_AMD64_ || _TARGET_X86_
BOOL IsSafeToCallExecutionManager()
{
@@ -5073,7 +5048,7 @@ BOOL IsSafeToCallExecutionManager()
GCStress<cfg_instr_ngen>::IsEnabled();
}
-BOOL PALAPI IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord)
+BOOL IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord)
{
PCODE controlPc = GetIP(contextRecord);
return g_fEEStarted && (
@@ -5086,7 +5061,7 @@ BOOL PALAPI IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_R
IsIPInMarkedJitHelper(controlPc));
}
-BOOL PALAPI HandleHardwareException(PAL_SEHException* ex)
+BOOL HandleHardwareException(PAL_SEHException* ex)
{
_ASSERTE(IsSafeToHandleHardwareException(ex->GetContextRecord(), ex->GetExceptionRecord()));
@@ -5102,7 +5077,7 @@ BOOL PALAPI HandleHardwareException(PAL_SEHException* ex)
return TRUE;
}
-#ifdef _AMD64_
+#if defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
// It is possible that an overflow was mapped to a divide-by-zero exception.
// This happens when we try to divide the maximum negative value of a
// signed integer with -1.
@@ -5115,7 +5090,7 @@ BOOL PALAPI HandleHardwareException(PAL_SEHException* ex)
// The exception was an integer overflow, so augment the exception code.
ex->GetExceptionRecord()->ExceptionCode = EXCEPTION_INT_OVERFLOW;
}
-#endif //_AMD64_
+#endif // _TARGET_AMD64_ || _TARGET_X86_
// Create frame necessary for the exception handling
FrameWithCookie<FaultingExceptionFrame> fef;
@@ -7074,8 +7049,10 @@ void ExceptionTracker::ResetThreadAbortStatus(PTR_Thread pThread, CrawlFrame *pC
GC_NOTRIGGER;
MODE_ANY;
PRECONDITION(pThread != NULL);
- WIN64_ONLY(PRECONDITION(pCf != NULL);)
- WIN64_ONLY(PRECONDITION(!sfCurrentStackFrame.IsNull());)
+#ifdef WIN64EXCEPTIONS
+ PRECONDITION(pCf != NULL);
+ PRECONDITION(!sfCurrentStackFrame.IsNull());
+#endif // WIN64EXCEPTIONS
}
CONTRACTL_END;