summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorJonghyun Park <parjong@gmail.com>2017-01-11 09:48:43 +0900
committerJan Vorlicek <janvorli@microsoft.com>2017-01-11 01:48:43 +0100
commit2fc44782c783f363c1a98e0767f6fa65b5548c95 (patch)
treee188a27a929664f93481f395ca7c4b18c794167d /src/vm
parent09c95bfa26420b7f29d04b5d47a06cf52f430ffe (diff)
downloadcoreclr-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.txt2
-rw-r--r--src/vm/codeman.cpp2
-rw-r--r--src/vm/codeman.h4
-rw-r--r--src/vm/eetwain.cpp9
-rw-r--r--src/vm/excep.cpp51
-rw-r--r--src/vm/excep.h12
-rw-r--r--src/vm/exceptionhandling.cpp4
-rw-r--r--src/vm/exinfo.cpp2
-rw-r--r--src/vm/exstate.cpp8
-rw-r--r--src/vm/exstatecommon.h16
-rw-r--r--src/vm/frames.h20
-rw-r--r--src/vm/gcenv.ee.cpp9
-rw-r--r--src/vm/i386/cgencpu.h4
-rw-r--r--src/vm/i386/cgenx86.cpp20
-rw-r--r--src/vm/i386/excepcpu.h38
-rw-r--r--src/vm/i386/excepx86.cpp80
-rw-r--r--src/vm/i386/jithelp.S4
-rw-r--r--src/vm/i386/unixstubs.cpp56
-rw-r--r--src/vm/jitinterface.cpp2
-rw-r--r--src/vm/jitinterface.h3
-rw-r--r--src/vm/stackwalk.cpp18
-rw-r--r--src/vm/threadsuspend.cpp4
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*) &regs->esi;
pRD->pEbx = (DWORD*) &regs->ebx;
pRD->pEbp = (DWORD*) &regs->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_
)