diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2017-02-10 20:35:12 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2017-02-10 20:35:12 +0900 |
commit | 4b11dc566a5bbfa1378d6266525c281b028abcc8 (patch) | |
tree | b48831a898906734f8884d08b6e18f1144ee2b82 /src/vm/exceptionhandling.cpp | |
parent | db20f3f1bb8595633a7e16c8900fd401a453a6b5 (diff) | |
download | coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.tar.gz coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.tar.bz2 coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.zip |
Imported Upstream version 1.0.0.9910upstream/1.0.0.9910
Diffstat (limited to 'src/vm/exceptionhandling.cpp')
-rw-r--r-- | src/vm/exceptionhandling.cpp | 131 |
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(®disp, &_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, ®disp, 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; |