diff options
author | Jonghyun Park <parjong@gmail.com> | 2017-01-11 09:48:43 +0900 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2017-01-11 01:48:43 +0100 |
commit | 2fc44782c783f363c1a98e0767f6fa65b5548c95 (patch) | |
tree | e188a27a929664f93481f395ca7c4b18c794167d /src/vm | |
parent | 09c95bfa26420b7f29d04b5d47a06cf52f430ffe (diff) | |
download | coreclr-2fc44782c783f363c1a98e0767f6fa65b5548c95.tar.gz coreclr-2fc44782c783f363c1a98e0767f6fa65b5548c95.tar.bz2 coreclr-2fc44782c783f363c1a98e0767f6fa65b5548c95.zip |
[x86/Linux] Fix WIN64EXCEPTIONS build error (#8629)
* Move GetUnwindInfo and GetNumberOfUnwindInfos into the real code header
This commit fixes #8342.
* Use WIN64EXCEPTIONS instead of _TARGET_X86_
* Revise FaultingExceptionFrame
This commit revises FaultingExceptionFrame to support WIN64EXCEPTIONS in
x86/Linux port.
* Add RUNTIME_FUNCTION__EndAddress as NYI
* Revise regdisp.h
* Revise eetwain.h
* Comment out exinfo.cpp if WIN64EXCEPTIONS is defined
* Revises excep.cpp
* Fix mistmatch in ThrowControlForThread defintion
* Revises cgenx86.cpp
* Disable SEH-based exception handlers when WIN64EXCEPTIONS is defined
* Revise stackwalk.cpp
* Revise jitinterface.cpp
* Revise readytorun.h
* Revise dbgipcevents.h
* Revise zapcode.cpp
* Revise clrnt.h
* Fix Windows build error
* Mark FaultingExceptionFrame::UpdateRegDisplay as NYI
* Revise per feedback
* Revert #if defined(..) as #ifdef
* Fix style changes
* Fix style changes
* Remove #undef _TARGET_X86_
* 2nd attempt to fix Windows build error
* Revise per feedback
* Revert the chagnes in clrdefinitions.cmake and add BIT32 in CMakeLists.txt
* Use !BIT64 instead of BIT32
* Include exceptionhandling.cpp and gcinfodecoder.cpp in build
This commit includes exceptionhandling.cpp and gcinfodecoder.cpp in
build, and fixes related compile errors.
* Fix COMPlus_EndCatch undefined reference
* Fix build error
* Fix GcInfoDecoder-related undefined references
* Fix AdjustContextForVirtualStub undefined reference
* Fix GetCallerSP undefined reference
* Fix ResetThreadAbortState undefined reference
* Attempt to fix Windows build error
* Fix CLRNoCatchHandler undefined reference
* Another attemp to fix Windows build error
* Fix GetXXXFromRedirectedStubStackFrame undefined references
* Fix Windows Build Error
* Add RtlpGetFunctionEndAddress and RtlVirtualUnwind as NYI
* Fix undefined references on JIT helpers
* Enable Dummy Application Run with WIN64EXCEPTIONS
* Revert "Move GetUnwindInfo and GetNumberOfUnwindInfos into the real code header"
This reverts commit c2bad85ac1136be3c6fb6ad7eedc5b3814b2ab29.
* Use indirect code header when WIN64EXCEPTIONS is enabled
* Port 'SyncRegDisplayToCurrentContext' and 'FillRegDisplay'
* Revise style 'RUNTIME_FUNCTION__SetUnwindInfoAddress'
* Extract out HandlerData from #ifdef region
* Add UNIXTODO
* Add UNIXTODO
* Port 'GetRegdisplayReturnValue'
* Fix incorrect comment
* Remove messages that mentions WIN32EXCEPTIONS
* Revise AdjustContextForWriteBarrier
* Port 'FaultingExceptionFrame::UpdateRegDisplay'
* Extract out 'AdjustContextForVirtualStub' and 'CLRNoCatchHandler' from #ifdef region
* Merge two #ifdef regions
* Set WIN64EXCEPTIONS as a default for x86/Linux
* Remove unnecessary #ifdef from ThrowControlForThread
* Remove unnecessary stubs
* Add Dependency Check between Compile Flags
* Revise per feedback
Diffstat (limited to 'src/vm')
-rw-r--r-- | src/vm/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/vm/codeman.cpp | 2 | ||||
-rw-r--r-- | src/vm/codeman.h | 4 | ||||
-rw-r--r-- | src/vm/eetwain.cpp | 9 | ||||
-rw-r--r-- | src/vm/excep.cpp | 51 | ||||
-rw-r--r-- | src/vm/excep.h | 12 | ||||
-rw-r--r-- | src/vm/exceptionhandling.cpp | 4 | ||||
-rw-r--r-- | src/vm/exinfo.cpp | 2 | ||||
-rw-r--r-- | src/vm/exstate.cpp | 8 | ||||
-rw-r--r-- | src/vm/exstatecommon.h | 16 | ||||
-rw-r--r-- | src/vm/frames.h | 20 | ||||
-rw-r--r-- | src/vm/gcenv.ee.cpp | 9 | ||||
-rw-r--r-- | src/vm/i386/cgencpu.h | 4 | ||||
-rw-r--r-- | src/vm/i386/cgenx86.cpp | 20 | ||||
-rw-r--r-- | src/vm/i386/excepcpu.h | 38 | ||||
-rw-r--r-- | src/vm/i386/excepx86.cpp | 80 | ||||
-rw-r--r-- | src/vm/i386/jithelp.S | 4 | ||||
-rw-r--r-- | src/vm/i386/unixstubs.cpp | 56 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 2 | ||||
-rw-r--r-- | src/vm/jitinterface.h | 3 | ||||
-rw-r--r-- | src/vm/stackwalk.cpp | 18 | ||||
-rw-r--r-- | src/vm/threadsuspend.cpp | 4 |
22 files changed, 214 insertions, 154 deletions
diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index 9fdddd6c26..4a64fcf10b 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -432,6 +432,8 @@ elseif(CLR_CMAKE_TARGET_ARCH_I386) set(VM_SOURCES_WKS_ARCH ${ARCH_SOURCES_DIR}/jitinterfacex86.cpp ${ARCH_SOURCES_DIR}/profiler.cpp + exceptionhandling.cpp + gcinfodecoder.cpp ) elseif(CLR_CMAKE_TARGET_ARCH_ARM) set(VM_SOURCES_DAC_AND_WKS_ARCH diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp index cdb7cc89aa..c615d668cb 100644 --- a/src/vm/codeman.cpp +++ b/src/vm/codeman.cpp @@ -3020,7 +3020,7 @@ void * EEJitManager::allocCodeFragmentBlock(size_t blockSize, unsigned alignment { CrstHolder ch(&m_CodeHeapCritSec); - mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(TADDR), blockSize, alignment, &pCodeHeap); + mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), blockSize, alignment, &pCodeHeap); // CodeHeader comes immediately before the block CodeHeader * pCodeHdr = (CodeHeader *) (mem - sizeof(CodeHeader)); diff --git a/src/vm/codeman.h b/src/vm/codeman.h index 0fe261a92f..5fb8da1e47 100644 --- a/src/vm/codeman.h +++ b/src/vm/codeman.h @@ -69,6 +69,10 @@ Abstract: #include "pedecoder.h" #include "gcinfo.h" +#if defined(WIN64EXCEPTIONS) && !defined(USE_INDIRECT_CODEHEADER) +#error "WIN64EXCEPTIONS requires USE_INDIRECT_CODEHEADER" +#endif // WIN64EXCEPTIONS && !USE_INDIRECT_CODEHEADER + class MethodDesc; class ICorJitCompiler; class IJitManager; diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp index 2ce7b59578..16b9de457f 100644 --- a/src/vm/eetwain.cpp +++ b/src/vm/eetwain.cpp @@ -3048,7 +3048,7 @@ unsigned SKIP_ALLOC_FRAME(int size, PTR_CBYTE base, unsigned offset) #endif // !USE_GC_INFO_DECODER -#if !defined(_TARGET_X86_) && !defined(CROSSGEN_COMPILE) +#if defined(WIN64EXCEPTIONS) && !defined(CROSSGEN_COMPILE) void EECodeManager::EnsureCallerContextIsValid( PREGDISPLAY pRD, StackwalkCacheEntry* pCacheEntry, EECodeInfo * pCodeInfo /*= NULL*/ ) { @@ -3105,7 +3105,7 @@ size_t EECodeManager::GetCallerSp( PREGDISPLAY pRD ) return (size_t) (GetSP(pRD->pCallerContext)); } -#endif // !defined(_TARGET_X86_) && !defined(CROSSGEN_COMPILE) +#endif // WIN64EXCEPTIONS && !CROSSGEN_COMPILE /* * Light unwind the current stack frame, using provided cache entry. @@ -5360,6 +5360,7 @@ PTR_VOID EECodeManager::GetExactGenericsToken(SIZE_T baseStackSlot, { LIMITED_METHOD_DAC_CONTRACT; +#ifdef USE_GC_INFO_DECODER GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); GcInfoDecoder gcInfoDecoder( @@ -5409,6 +5410,10 @@ PTR_VOID EECodeManager::GetExactGenericsToken(SIZE_T baseStackSlot, return PTR_VOID(taExactGenericsToken); } return NULL; +#else // USE_GC_INFO_DECODER + PORTABILITY_ASSERT("EECodeManager::GetExactGenericsToken"); + return NULL; +#endif // USE_GC_INFO_DECODER } diff --git a/src/vm/excep.cpp b/src/vm/excep.cpp index 1d24237c02..cd154c0618 100644 --- a/src/vm/excep.cpp +++ b/src/vm/excep.cpp @@ -7264,11 +7264,13 @@ IsDebuggerFault(EXCEPTION_RECORD *pExceptionRecord, #ifdef WIN64EXCEPTIONS +#ifndef _TARGET_X86_ EXTERN_C void JIT_MemSet_End(); EXTERN_C void JIT_MemCpy_End(); EXTERN_C void JIT_WriteBarrier_End(); EXTERN_C void JIT_CheckedWriteBarrier_End(); +#endif // _TARGET_X86_ #if defined(_TARGET_AMD64_) && defined(_DEBUG) EXTERN_C void JIT_WriteBarrier_Debug(); @@ -7288,11 +7290,13 @@ bool IsIPInMarkedJitHelper(UINT_PTR uControlPc) #define CHECK_RANGE(name) \ if (GetEEFuncEntryPoint(name) <= uControlPc && uControlPc < GetEEFuncEntryPoint(name##_End)) return true; +#ifndef _TARGET_X86_ CHECK_RANGE(JIT_MemSet) CHECK_RANGE(JIT_MemCpy) CHECK_RANGE(JIT_WriteBarrier) CHECK_RANGE(JIT_CheckedWriteBarrier) +#endif // _TARGET_X86_ #if defined(_TARGET_AMD64_) && defined(_DEBUG) CHECK_RANGE(JIT_WriteBarrier_Debug) @@ -7314,8 +7318,7 @@ AdjustContextForWriteBarrier( { WRAPPER_NO_CONTRACT; -#ifdef _TARGET_X86_ - +#if defined(_TARGET_X86_) && !defined(PLATFORM_UNIX) void* f_IP = (void *)GetIP(pContext); if (((f_IP >= (void *) JIT_WriteBarrierStart) && (f_IP <= (void *) JIT_WriteBarrierLast)) || @@ -7329,11 +7332,8 @@ AdjustContextForWriteBarrier( // put ESP back to what it was before the call. SetSP(pContext, PCODE((BYTE*)GetSP(pContext) + sizeof(void*))); } - return FALSE; - -#elif defined(WIN64EXCEPTIONS) - +#elif defined(WIN64EXCEPTIONS) // _TARGET_X86_ && !PLATFORM_UNIX void* f_IP = dac_cast<PTR_VOID>(GetIP(pContext)); CONTEXT tempContext; @@ -7377,7 +7377,7 @@ AdjustContextForWriteBarrier( // Now we save the address back into the context so that it gets used // as the faulting address. SetIP(pContext, ControlPCPostAdjustment); -#endif // _TARGET_ARM_ +#endif // _TARGET_ARM_ || _TARGET_ARM64_ // Unwind the frame chain - On Win64, this is required since we may handle the managed fault and to do so, // we will replace the exception context with the managed context and "continue execution" there. Thus, we do not @@ -7399,13 +7399,10 @@ AdjustContextForWriteBarrier( } return FALSE; - -#else // ! _X86_ && !WIN64EXCEPTIONS - - PORTABILITY_WARNING("AdjustContextForWriteBarrier() not implemented on this platform"); +#else // WIN64EXCEPTIONS + PORTABILITY_ASSERT("AdjustContextForWriteBarrier"); return FALSE; - -#endif +#endif // ELSE } struct SavedExceptionInfo @@ -7556,7 +7553,8 @@ void InitSavedExceptionInfo() void FaultingExceptionFrame::Init(CONTEXT *pContext) { WRAPPER_NO_CONTRACT; -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS +#ifdef _TARGET_X86_ CalleeSavedRegisters *pRegs = GetCalleeSavedRegisters(); pRegs->ebp = pContext->Ebp; pRegs->ebx = pContext->Ebx; @@ -7564,12 +7562,13 @@ void FaultingExceptionFrame::Init(CONTEXT *pContext) pRegs->edi = pContext->Edi; m_ReturnAddress = ::GetIP(pContext); m_Esp = (DWORD)GetSP(pContext); -#elif defined(WIN64EXCEPTIONS) +#else // _TARGET_X86_ + PORTABILITY_ASSERT("FaultingExceptionFrame::Init"); +#endif // _TARGET_???_ (ELSE) +#else // !WIN64EXCEPTIONS m_ReturnAddress = ::GetIP(pContext); CopyOSContext(&m_ctx, pContext); -#else - PORTABILITY_ASSERT("FaultingExceptionFrame::InitAndLink"); -#endif +#endif // !WIN64EXCEPTIONS } // @@ -13113,9 +13112,9 @@ StackWalkAction TAResetStateCallback(CrawlFrame* pCf, void* data) // there is no more managed code on the stack. // // Note: This function should be invoked ONLY during unwind. -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS void ResetThreadAbortState(PTR_Thread pThread, void *pEstablisherFrame) -#elif defined(WIN64EXCEPTIONS) +#else void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCurrentStackFrame) #endif { @@ -13125,9 +13124,9 @@ void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCur GC_NOTRIGGER; MODE_ANY; PRECONDITION(pThread != NULL); -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS PRECONDITION(pEstablisherFrame != NULL); -#elif defined(WIN64EXCEPTIONS) +#else PRECONDITION(pCf != NULL); PRECONDITION(!sfCurrentStackFrame.IsNull()); #endif @@ -13138,14 +13137,14 @@ void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCur if (pThread->IsAbortRequested()) { -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS if (GetNextCOMPlusSEHRecord(static_cast<EXCEPTION_REGISTRATION_RECORD *>(pEstablisherFrame)) == EXCEPTION_CHAIN_END) { // Topmost handler and abort requested. fResetThreadAbortState = TRUE; LOG((LF_EH, LL_INFO100, "ResetThreadAbortState: Topmost handler resets abort as no more managed code beyond %p.\n", pEstablisherFrame)); } -#elif defined(WIN64EXCEPTIONS) +#else // !WIN64EXCEPTIONS // Get the active exception tracker PTR_ExceptionTracker pCurEHTracker = pThread->GetExceptionState()->GetCurrentExceptionTracker(); _ASSERTE(pCurEHTracker != NULL); @@ -13200,9 +13199,7 @@ void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCur LOG((LF_EH, LL_INFO100, "ResetThreadAbortState: Resetting thread abort state since there is no more managed code beyond stack frames:\n")); LOG((LF_EH, LL_INFO100, "sf.SP = %p ", dataCallback.sfSeedCrawlFrame.SP)); } -#else // WIN64EXCEPTIONS -#error Unsupported platform -#endif // WIN64EXCEPTIONS +#endif // !WIN64EXCEPTIONS } if (fResetThreadAbortState) diff --git a/src/vm/excep.h b/src/vm/excep.h index e50a770e27..53fa20160a 100644 --- a/src/vm/excep.h +++ b/src/vm/excep.h @@ -415,7 +415,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowInvalidCastException(TypeHandle thCastFro VOID DECLSPEC_NORETURN RealCOMPlusThrowInvalidCastException(OBJECTREF *pObj, TypeHandle thCastTo); -#ifdef _TARGET_X86_ +#ifndef WIN64EXCEPTIONS #include "eexcp.h" #include "exinfo.h" @@ -454,7 +454,7 @@ struct NestedHandlerExRecord : public FrameHandlerExRecord } }; -#endif // _TARGET_X86_ +#endif // !WIN64EXCEPTIONS #if defined(ENABLE_CONTRACTS_IMPL) @@ -520,10 +520,6 @@ extern "C" BOOL ExceptionIsOfRightType(TypeHandle clauseType, TypeHandle thrownT // The stuff below is what works "behind the scenes" of the public macros. //========================================================================== -#ifdef _TARGET_X86_ -LPVOID COMPlusEndCatchWorker(Thread *pCurThread); -EXTERN_C LPVOID STDCALL COMPlusEndCatch(LPVOID ebp, DWORD ebx, DWORD edi, DWORD esi, LPVOID* pRetAddress); -#endif // Specify NULL for uTryCatchResumeAddress when not checking for a InducedThreadRedirectAtEndOfCatch EXTERN_C LPVOID COMPlusCheckForAbort(UINT_PTR uTryCatchResumeAddress = NULL); @@ -946,9 +942,9 @@ public: #ifndef DACCESS_COMPILE -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS void ResetThreadAbortState(PTR_Thread pThread, void *pEstablisherFrame); -#elif defined(WIN64EXCEPTIONS) +#else void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCurrentStackFrame); #endif diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp index 56c784a37f..475bf3be09 100644 --- a/src/vm/exceptionhandling.cpp +++ b/src/vm/exceptionhandling.cpp @@ -1293,7 +1293,11 @@ void ExceptionTracker::InitializeCurrentContextForCrawlFrame(CrawlFrame* pcfThis *(pRD->pCallerContext) = *(pDispatcherContext->ContextRecord); pRD->IsCallerContextValid = TRUE; +#ifndef _TARGET_X86_ pRD->SP = sfEstablisherFrame.SP; +#else + pRD->Esp = sfEstablisherFrame.SP; +#endif pRD->ControlPC = pDispatcherContext->ControlPc; #if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) diff --git a/src/vm/exinfo.cpp b/src/vm/exinfo.cpp index 9e07cebaf3..1ae011e85a 100644 --- a/src/vm/exinfo.cpp +++ b/src/vm/exinfo.cpp @@ -9,6 +9,7 @@ #include "exinfo.h" #include "dbginterface.h" +#ifndef WIN64EXCEPTIONS #ifndef DACCESS_COMPILE // // Destroy the handle within an ExInfo. This respects the fact that we can have preallocated global handles living @@ -312,3 +313,4 @@ void ExInfo::SetExceptionCode(const EXCEPTION_RECORD *pCER) DacError(E_UNEXPECTED); #endif // !DACCESS_COMPILE } +#endif // !WIN64EXCEPTIONS diff --git a/src/vm/exstate.cpp b/src/vm/exstate.cpp index bde71db884..29c7a063f5 100644 --- a/src/vm/exstate.cpp +++ b/src/vm/exstate.cpp @@ -498,7 +498,7 @@ BOOL DebuggerExState::SetDebuggerInterceptInfo(IJitManager *pJitManager, int nestingLevel = 0; -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS // // Get the SEH frame that covers this location on the stack. Note: we pass a skip count of 1. We know that when // this is called, there is a nested exception handler on pThread's stack that is only there during exception @@ -517,11 +517,7 @@ BOOL DebuggerExState::SetDebuggerInterceptInfo(IJitManager *pJitManager, nestingLevel = ComputeEnclosingHandlerNestingLevel(pJitManager, methodToken, natOffset); -#elif !defined(WIN64EXCEPTIONS) - // !_TARGET_X86_ && !WIN64EXCEPTIONS - PORTABILITY_ASSERT("SetDebuggerInterceptInfo() (ExState.cpp) - continuable exceptions NYI\n"); - return FALSE; -#endif // !_TARGET_X86_ +#endif // !WIN64EXCEPTIONS // // These values will override the normal information used by the EH subsystem to handle the exception. diff --git a/src/vm/exstatecommon.h b/src/vm/exstatecommon.h index 7c505b8bac..270293669d 100644 --- a/src/vm/exstatecommon.h +++ b/src/vm/exstatecommon.h @@ -51,10 +51,10 @@ public: m_pDebuggerContext = NULL; m_pDebuggerInterceptNativeOffset = 0; + #ifndef WIN64EXCEPTIONS // x86-specific fields - #if defined(_TARGET_X86_) m_pDebuggerInterceptFrame = EXCEPTION_CHAIN_END; - #endif // defined(_TARGET_X86_) + #endif // !WIN64EXCEPTIONS m_dDebuggerInterceptHandlerDepth = 0; } @@ -133,9 +133,9 @@ public: // void GetDebuggerInterceptInfo( - #if defined(_TARGET_X86_) + #ifndef WIN64EXCEPTIONS PEXCEPTION_REGISTRATION_RECORD *pEstablisherFrame, - #endif // _TARGET_X86_ + #endif // !WIN64EXCEPTIONS MethodDesc **ppFunc, int *pdHandler, BYTE **ppStack, @@ -144,12 +144,12 @@ public: { LIMITED_METHOD_CONTRACT; -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS if (pEstablisherFrame != NULL) { *pEstablisherFrame = m_pDebuggerInterceptFrame; } -#endif // _TARGET_X86_ +#endif // !WIN64EXCEPTIONS if (ppFunc != NULL) { @@ -195,10 +195,10 @@ private: ULONG_PTR m_pDebuggerInterceptNativeOffset; // The remaining fields are only used on x86. -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS // the exception registration record covering the stack range containing the interception point PEXCEPTION_REGISTRATION_RECORD m_pDebuggerInterceptFrame; -#endif // defined(_TARGET_X86_) +#endif // !WIN64EXCEPTIONS // the nesting level at which we want to resume execution int m_dDebuggerInterceptHandlerDepth; diff --git a/src/vm/frames.h b/src/vm/frames.h index 91ab3c3e5f..e37f980b9f 100644 --- a/src/vm/frames.h +++ b/src/vm/frames.h @@ -1114,17 +1114,19 @@ class FaultingExceptionFrame : public Frame { friend class CheckAsmOffsets; -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS +#ifdef _TARGET_X86_ DWORD m_Esp; CalleeSavedRegisters m_regs; TADDR m_ReturnAddress; -#endif - -#ifdef WIN64EXCEPTIONS +#else // _TARGET_X86_ + #error "Unsupported architecture" +#endif // _TARGET_X86_ +#else // WIN64EXCEPTIONS BOOL m_fFilterExecuted; // Flag for FirstCallToHandler TADDR m_ReturnAddress; T_CONTEXT m_ctx; -#endif // WIN64EXCEPTIONS +#endif // !WIN64EXCEPTIONS VPTR_VTABLE_CLASS(FaultingExceptionFrame, Frame) @@ -1156,13 +1158,17 @@ public: return FRAME_ATTR_EXCEPTION | FRAME_ATTR_FAULTED; } -#if defined(_TARGET_X86_) +#ifndef WIN64EXCEPTIONS CalleeSavedRegisters *GetCalleeSavedRegisters() { +#ifdef _TARGET_X86_ LIMITED_METHOD_DAC_CONTRACT; return &m_regs; +#else + PORTABILITY_ASSERT("GetCalleeSavedRegisters"); +#endif // _TARGET_X86_ } -#endif +#endif // WIN64EXCEPTIONS #ifdef WIN64EXCEPTIONS T_CONTEXT *GetExceptionContext () diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp index 5fb83bfa04..792e748f9d 100644 --- a/src/vm/gcenv.ee.cpp +++ b/src/vm/gcenv.ee.cpp @@ -204,6 +204,7 @@ bool FindFirstInterruptiblePointStateCB( // the end is exclusive). Return -1 if no such point exists. unsigned FindFirstInterruptiblePoint(CrawlFrame* pCF, unsigned offs, unsigned endOffs) { +#ifdef USE_GC_INFO_DECODER GCInfoToken gcInfoToken = pCF->GetGCInfoToken(); GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_FOR_RANGES_CALLBACK); @@ -215,6 +216,10 @@ unsigned FindFirstInterruptiblePoint(CrawlFrame* pCF, unsigned offs, unsigned en gcInfoDecoder.EnumerateInterruptibleRanges(&FindFirstInterruptiblePointStateCB, &state); return state.returnOffs; +#else + PORTABILITY_ASSERT("FindFirstInterruptiblePoint"); + return -1; +#endif // USE_GC_INFO_DECODER } #endif // WIN64EXCEPTIONS @@ -283,7 +288,7 @@ StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData) #endif // _DEBUG DWORD relOffsetOverride = NO_OVERRIDE_OFFSET; -#if defined(WIN64EXCEPTIONS) +#if defined(WIN64EXCEPTIONS) && defined(USE_GC_INFO_DECODER) if (pCF->ShouldParentToFuncletUseUnwindTargetLocationForGCReporting()) { GCInfoToken gcInfoToken = pCF->GetGCInfoToken(); @@ -313,7 +318,7 @@ StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData) } } -#endif // WIN64EXCEPTIONS +#endif // WIN64EXCEPTIONS && USE_GC_INFO_DECODER pCM->EnumGcRefs(pCF->GetRegisterSet(), pCF->GetCodeInfo(), diff --git a/src/vm/i386/cgencpu.h b/src/vm/i386/cgencpu.h index 99f4eb498f..38a88a7401 100644 --- a/src/vm/i386/cgencpu.h +++ b/src/vm/i386/cgencpu.h @@ -86,6 +86,10 @@ BOOL Runtime_Test_For_SSE2(); #define JUMP_ALLOCATE_SIZE 8 // # bytes to allocate for a jump instruction #define BACK_TO_BACK_JUMP_ALLOCATE_SIZE 8 // # bytes to allocate for a back to back jump instruction +#ifdef WIN64EXCEPTIONS +#define USE_INDIRECT_CODEHEADER +#endif // WIN64EXCEPTIONS + #define HAS_COMPACT_ENTRYPOINTS 1 // Needed for PInvoke inlining in ngened images diff --git a/src/vm/i386/cgenx86.cpp b/src/vm/i386/cgenx86.cpp index 08ccd01086..703968c888 100644 --- a/src/vm/i386/cgenx86.cpp +++ b/src/vm/i386/cgenx86.cpp @@ -509,6 +509,7 @@ void FaultingExceptionFrame::UpdateRegDisplay(const PREGDISPLAY pRD) } CONTRACT_END; +#ifndef WIN64EXCEPTIONS CalleeSavedRegisters* regs = GetCalleeSavedRegisters(); // reset pContext; it's only valid for active (top-most) frame @@ -518,9 +519,24 @@ void FaultingExceptionFrame::UpdateRegDisplay(const PREGDISPLAY pRD) pRD->pEsi = (DWORD*) ®s->esi; pRD->pEbx = (DWORD*) ®s->ebx; pRD->pEbp = (DWORD*) ®s->ebp; + pRD->Esp = m_Esp; pRD->PCTAddr = GetReturnAddressPtr(); pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr); - pRD->Esp = m_Esp; +#else + memcpy(pRD->pCurrentContext, &m_ctx, sizeof(CONTEXT)); + + pRD->ControlPC = m_ctx.Eip; + + pRD->Esp = m_ctx.Esp; + + pRD->pCurrentContextPointers->Ebx = &m_ctx.Ebx; + pRD->pCurrentContextPointers->Edi = &m_ctx.Edi; + pRD->pCurrentContextPointers->Esi = &m_ctx.Esi; + pRD->pCurrentContextPointers->Ebp = &m_ctx.Ebp; + + pRD->IsCallerContextValid = FALSE; + pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. +#endif // WIN64EXCEPTIONS RETURN; } @@ -606,6 +622,7 @@ void ResumableFrame::UpdateRegDisplay(const PREGDISPLAY pRD) CONTEXT* pUnwoundContext = m_Regs; +#ifndef WIN64EXCEPTIONS #if !defined(DACCESS_COMPILE) // "pContextForUnwind" field is only used on X86 since not only is it initialized just for it, // but its used only under the confines of STACKWALKER_MAY_POP_FRAMES preprocessor define, @@ -625,6 +642,7 @@ void ResumableFrame::UpdateRegDisplay(const PREGDISPLAY pRD) pUnwoundContext->Eip = m_Regs->Eip; } #endif // !defined(DACCESS_COMPILE) +#endif // !WIN64EXCEPTIONS pRD->pEax = &pUnwoundContext->Eax; pRD->pEcx = &pUnwoundContext->Ecx; diff --git a/src/vm/i386/excepcpu.h b/src/vm/i386/excepcpu.h index ff540e784b..d70c6620a1 100644 --- a/src/vm/i386/excepcpu.h +++ b/src/vm/i386/excepcpu.h @@ -21,6 +21,7 @@ #define STATUS_CLR_GCCOVER_CODE STATUS_PRIVILEGED_INSTRUCTION +#ifndef WIN64EXCEPTIONS class Thread; #if defined(_MSC_VER) @@ -28,19 +29,6 @@ class Thread; // Actually, the handler getting set is properly registered #endif -#ifdef FEATURE_PAL - -extern VOID SetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record); -extern VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record); - -#define INSTALL_SEH_RECORD(record) \ - SetSEHRecord(record); \ - -#define UNINSTALL_SEH_RECORD(record) \ - ResetSEHRecord(record); - -#else // FEATURE_PAL - #define INSTALL_SEH_RECORD(record) \ { \ (record)->Next = (PEXCEPTION_REGISTRATION_RECORD)__readfsdword(0); \ @@ -52,8 +40,6 @@ extern VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record); __writefsdword(0, (DWORD) ((record)->Next)); \ } -#endif // FEATURE_PAL - #define INSTALL_EXCEPTION_HANDLING_RECORD(record) \ { \ PEXCEPTION_REGISTRATION_RECORD __record = (record); \ @@ -90,14 +76,32 @@ extern VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record); #endif + +PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord(); +PEXCEPTION_REGISTRATION_RECORD GetFirstCOMPlusSEHRecord(Thread*); + +LPVOID COMPlusEndCatchWorker(Thread *pCurThread); +EXTERN_C LPVOID STDCALL COMPlusEndCatch(LPVOID ebp, DWORD ebx, DWORD edi, DWORD esi, LPVOID* pRetAddress); + +#else // WIN64EXCEPTIONS +#define INSTALL_EXCEPTION_HANDLING_RECORD(record) +#define UNINSTALL_EXCEPTION_HANDLING_RECORD(record) +#define DECLARE_CPFH_EH_RECORD(pCurThread) + +#endif // WIN64EXCEPTIONS + // // Retrieves the redirected CONTEXT* from the stack frame of one of the // RedirectedHandledJITCaseForXXX_Stub's. // PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(CONTEXT * pContext); +#ifdef WIN64EXCEPTIONS +PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_DISPATCHER_CONTEXT * pDispatcherContext); -PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord(); -PEXCEPTION_REGISTRATION_RECORD GetFirstCOMPlusSEHRecord(Thread*); +class FaultingExceptionFrame; + +FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame (DISPATCHER_CONTEXT *pDispatcherContext); +#endif // WIN64EXCEPTIONS // Determine the address of the instruction that made the current call. inline diff --git a/src/vm/i386/excepx86.cpp b/src/vm/i386/excepx86.cpp index c6a95ef555..0f05aa29cd 100644 --- a/src/vm/i386/excepx86.cpp +++ b/src/vm/i386/excepx86.cpp @@ -38,6 +38,7 @@ #include "asmconstants.h" #include "virtualcallstub.h" +#ifndef WIN64EXCEPTIONS MethodDesc * GetUserMethodForILStub(Thread * pThread, UINT_PTR uStubSP, MethodDesc * pILStubMD, Frame ** ppFrameOut); #if !defined(DACCESS_COMPILE) @@ -2018,20 +2019,6 @@ PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord() return (EXCEPTION_REGISTRATION_RECORD*) fs0; } -#ifdef FEATURE_PAL -VOID SetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record) -{ - WRAPPER_NO_CONTRACT; - record->Next = CurrentSEHRecord; - CurrentSEHRecord = record; -} - -VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record) -{ - CurrentSEHRecord = record->Next; -} -#endif // FEATURE_PAL - PEXCEPTION_REGISTRATION_RECORD GetFirstCOMPlusSEHRecord(Thread *pThread) { WRAPPER_NO_CONTRACT; #ifndef FEATURE_PAL @@ -3622,33 +3609,11 @@ EXCEPTION_HANDLER_IMPL(UMThunkPrestubHandler) return retval; } -LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv) -{ - WRAPPER_NO_CONTRACT; - STATIC_CONTRACT_ENTRY_POINT; - - LONG result = EXCEPTION_CONTINUE_SEARCH; - - // This function can be called during the handling of a SO - //BEGIN_ENTRYPOINT_VOIDRET; - - result = CLRVectoredExceptionHandler(pExceptionInfo); - - if (EXCEPTION_EXECUTE_HANDLER == result) - { - result = EXCEPTION_CONTINUE_SEARCH; - } - - //END_ENTRYPOINT_VOIDRET; - - return result; -} - #ifdef FEATURE_COMINTEROP // The reverse COM interop path needs to be sure to pop the ComMethodFrame that is pushed, but we do not want -// to have an additional FS:0 handler between the COM callsite and the call into managed. So we push this -// FS:0 handler, which will defer to the usual COMPlusFrameHandler and then perform the cleanup of the -// ComMethodFrame, if needed. +// to have an additional FS:0 handler between the COM callsite and the call into managed. So we push this +// FS:0 handler, which will defer to the usual COMPlusFrameHandler and then perform the cleanup of the +// ComMethodFrame, if needed. EXCEPTION_HANDLER_IMPL(COMPlusFrameHandlerRevCom) { STATIC_CONTRACT_THROWS; @@ -3667,7 +3632,36 @@ EXCEPTION_HANDLER_IMPL(COMPlusFrameHandlerRevCom) return result; } #endif // FEATURE_COMINTEROP +#endif // !DACCESS_COMPILE +#endif // !WIN64EXCEPTIONS + +#ifndef DACCESS_COMPILE +LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv) +{ +#ifndef WIN64EXCEPTIONS + WRAPPER_NO_CONTRACT; + STATIC_CONTRACT_ENTRY_POINT; + + LONG result = EXCEPTION_CONTINUE_SEARCH; + + // This function can be called during the handling of a SO + //BEGIN_ENTRYPOINT_VOIDRET; + + result = CLRVectoredExceptionHandler(pExceptionInfo); + + if (EXCEPTION_EXECUTE_HANDLER == result) + { + result = EXCEPTION_CONTINUE_SEARCH; + } + //END_ENTRYPOINT_VOIDRET; + + return result; +#else // !WIN64EXCEPTIONS + return EXCEPTION_CONTINUE_SEARCH; +#endif // !WIN64EXCEPTIONS +} +#endif // !DACCESS_COMPILE // Returns TRUE if caller should resume execution. BOOL @@ -3724,11 +3718,3 @@ AdjustContextForVirtualStub( return TRUE; } - -#ifdef FEATURE_PAL -VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHardwareException) -{ - UNREACHABLE(); -} -#endif -#endif // !DACCESS_COMPILE diff --git a/src/vm/i386/jithelp.S b/src/vm/i386/jithelp.S index 66ae9fb451..35a02613ea 100644 --- a/src/vm/i386/jithelp.S +++ b/src/vm/i386/jithelp.S @@ -727,6 +727,7 @@ LEAF_END JIT_PatchedCodeEnd, _TEXT // debugger may need additional support. // void __stdcall JIT_EndCatch(); NESTED_ENTRY JIT_EndCatch, _TEXT, NoHandler +#ifndef WIN64EXCEPTIONS // make temp storage for return address, and push the address of that // as the last arg to COMPlusEndCatch mov ecx, [esp] @@ -746,4 +747,7 @@ NESTED_ENTRY JIT_EndCatch, _TEXT, NoHandler pop edx // edx = new eip mov esp, eax // esp = new esp jmp edx // eip = new eip +#else + int3 +#endif NESTED_END JIT_EndCatch, _TEXT diff --git a/src/vm/i386/unixstubs.cpp b/src/vm/i386/unixstubs.cpp index 3252922249..4025c26216 100644 --- a/src/vm/i386/unixstubs.cpp +++ b/src/vm/i386/unixstubs.cpp @@ -6,7 +6,7 @@ extern "C" { - void ThrowControlForThread() + void ThrowControlForThread(FaultingExceptionFrame *pfef) { PORTABILITY_ASSERT("Implement for PAL"); } @@ -45,19 +45,6 @@ extern "C" { } - _Unwind_Reason_Code - UnhandledExceptionHandlerUnix( - IN int version, - IN _Unwind_Action action, - IN uint64_t exceptionClass, - IN struct _Unwind_Exception *exception, - IN struct _Unwind_Context *context - ) - { - PORTABILITY_ASSERT("UnhandledExceptionHandlerUnix"); - return _URC_FATAL_PHASE1_ERROR; - } - BOOL CallRtlUnwind() { PORTABILITY_ASSERT("CallRtlUnwind"); @@ -94,3 +81,44 @@ EXTERN_C VOID JIT_TailCallLeave() { PORTABILITY_ASSERT("JIT_TailCallLeave"); } + +PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_DISPATCHER_CONTEXT * pDispatcherContext) +{ + PORTABILITY_ASSERT("GetCONTEXTFromRedirectedStubStackFrame"); + return NULL; +} + +FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame(DISPATCHER_CONTEXT *pDispatcherContext) +{ + PORTABILITY_ASSERT("GetFrameFromRedirectedStubStackFrame"); + return NULL; +} + +EXTERN_C ULONG +RtlpGetFunctionEndAddress ( + __in PT_RUNTIME_FUNCTION FunctionEntry, + __in ULONG ImageBase + ) +{ + PORTABILITY_ASSERT("RtlpGetFunctionEndAddress"); + return 0; +} + +EXTERN_C +NTSYSAPI +PEXCEPTION_ROUTINE +NTAPI +RtlVirtualUnwind ( + __in DWORD HandlerType, + __in DWORD ImageBase, + __in DWORD ControlPc, + __in PRUNTIME_FUNCTION FunctionEntry, + __inout PT_CONTEXT ContextRecord, + __out PVOID *HandlerData, + __out PDWORD EstablisherFrame, + __inout_opt PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers + ) +{ + PORTABILITY_ASSERT("RtlVirtualUnwind"); + return NULL; +} diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index 2f9db3d596..9d57836bac 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -11082,7 +11082,7 @@ void CEEJitInfo::allocUnwindInfo ( RUNTIME_FUNCTION__SetBeginAddress(pRuntimeFunction, currentCodeOffset + startOffset); -#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) +#if defined(_TARGET_AMD64_) pRuntimeFunction->EndAddress = currentCodeOffset + endOffset; #endif diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h index ee13b9cec6..6cc3a05fba 100644 --- a/src/vm/jitinterface.h +++ b/src/vm/jitinterface.h @@ -391,7 +391,10 @@ void ValidateWriteBarrierHelpers(); extern "C" { +#ifdef _TARGET_X86_ + // UNIXTODO: Disable JIT_EndCatch after revising the jitter not to use this (for x86/Linux) void STDCALL JIT_EndCatch(); // JIThelp.asm/JIThelp.s +#endif // _TARGET_X86_ void STDCALL JIT_ByRefWriteBarrier(); // JIThelp.asm/JIThelp.s diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp index 18a8900039..44e5f99640 100644 --- a/src/vm/stackwalk.cpp +++ b/src/vm/stackwalk.cpp @@ -555,11 +555,9 @@ UINT_PTR Thread::VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo* pCodeInfo / pRD->pCurrentContext = pRD->pCallerContext; pRD->pCallerContext = temp; -#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) PT_KNONVOLATILE_CONTEXT_POINTERS tempPtrs = pRD->pCurrentContextPointers; pRD->pCurrentContextPointers = pRD->pCallerContextPointers; pRD->pCallerContextPointers = tempPtrs; -#endif // defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) } else { @@ -722,15 +720,12 @@ PCODE Thread::VirtualUnwindNonLeafCallFrame(T_CONTEXT* pContext, KNONVOLATILE_CO CONTRACTL_END; PCODE uControlPc = GetIP(pContext); -#if defined(_WIN64) +#ifdef BIT64 UINT64 EstablisherFrame; - PVOID HandlerData; -#elif defined(_TARGET_ARM_) +#else // BIT64 DWORD EstablisherFrame; +#endif // BIT64 PVOID HandlerData; -#else - _ASSERTE(!"nyi platform stackwalking"); -#endif if (NULL == pFunctionEntry) { @@ -893,7 +888,7 @@ StackWalkAction Thread::MakeStackwalkerCallback( } -#if !defined(DACCESS_COMPILE) && defined(_TARGET_X86_) +#if !defined(DACCESS_COMPILE) && defined(_TARGET_X86_) && !defined(WIN64EXCEPTIONS) #define STACKWALKER_MAY_POP_FRAMES #endif @@ -2677,9 +2672,10 @@ StackWalkAction StackFrameIterator::NextRaw(void) // We are transitioning from unmanaged code to managed code... lets do some validation of our // EH mechanism on platforms that we can. -#if defined(_DEBUG) && !defined(DACCESS_COMPILE) && (defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)) +#if defined(_DEBUG) && !defined(DACCESS_COMPILE) && (defined(_TARGET_X86_) && !defined(FEATURE_PAL)) && !defined(WIN64EXCEPTIONS) + // TODO: Revise this once we enable WIN64EXCEPTIONS for x86/Linux VerifyValidTransitionFromManagedCode(m_crawl.pThread, &m_crawl); -#endif // _DEBUG && !DACCESS_COMPILE && _TARGET_X86_ +#endif // _DEBUG && !DACCESS_COMPILE && _TARGET_X86_ && !WIN64EXCEPTIONS } } diff --git a/src/vm/threadsuspend.cpp b/src/vm/threadsuspend.cpp index 2e6563da1e..18d04db42b 100644 --- a/src/vm/threadsuspend.cpp +++ b/src/vm/threadsuspend.cpp @@ -2190,7 +2190,7 @@ LRetry: | TS_Detached | TS_Unstarted))); -#ifdef _TARGET_X86_ +#if defined(_TARGET_X86_) && !defined(WIN64EXCEPTIONS) // TODO WIN64: consider this if there is a way to detect of managed code on stack. if ((m_pFrame == FRAME_TOP) && (GetFirstCOMPlusSEHRecord(this) == EXCEPTION_CHAIN_END) @@ -2213,7 +2213,7 @@ LRetry: if (!m_fPreemptiveGCDisabled) { if ((m_pFrame != FRAME_TOP) && m_pFrame->IsTransitionToNativeFrame() -#ifdef _TARGET_X86_ +#if defined(_TARGET_X86_) && !defined(WIN64EXCEPTIONS) && ((size_t) GetFirstCOMPlusSEHRecord(this) > ((size_t) m_pFrame) - 20) #endif // _TARGET_X86_ ) |