[x86/Linux] Fix WIN64EXCEPTIONS build error (dotnet/coreclr#8629)
authorJonghyun Park <parjong@gmail.com>
Wed, 11 Jan 2017 00:48:43 +0000 (09:48 +0900)
committerJan Vorlicek <janvorli@microsoft.com>
Wed, 11 Jan 2017 00:48:43 +0000 (01:48 +0100)
* Move GetUnwindInfo and GetNumberOfUnwindInfos into the real code header

This commit fixes dotnet/coreclr#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 dotnet/coreclr@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

Commit migrated from https://github.com/dotnet/coreclr/commit/2fc44782c783f363c1a98e0767f6fa65b5548c95

38 files changed:
src/coreclr/src/ToolBox/SOS/Strike/disasmARM.cpp
src/coreclr/src/debug/daccess/enummem.cpp
src/coreclr/src/debug/di/rspriv.h
src/coreclr/src/debug/di/rsthread.cpp
src/coreclr/src/debug/inc/dbgipcevents.h
src/coreclr/src/inc/clrnt.h
src/coreclr/src/inc/corcompile.h
src/coreclr/src/inc/eetwain.h
src/coreclr/src/inc/gcinfodecoder.h
src/coreclr/src/inc/jithelpers.h
src/coreclr/src/inc/readytorun.h
src/coreclr/src/inc/regdisp.h
src/coreclr/src/inc/switches.h
src/coreclr/src/pal/inc/pal.h
src/coreclr/src/vm/CMakeLists.txt
src/coreclr/src/vm/codeman.cpp
src/coreclr/src/vm/codeman.h
src/coreclr/src/vm/eetwain.cpp
src/coreclr/src/vm/excep.cpp
src/coreclr/src/vm/excep.h
src/coreclr/src/vm/exceptionhandling.cpp
src/coreclr/src/vm/exinfo.cpp
src/coreclr/src/vm/exstate.cpp
src/coreclr/src/vm/exstatecommon.h
src/coreclr/src/vm/frames.h
src/coreclr/src/vm/gcenv.ee.cpp
src/coreclr/src/vm/i386/cgencpu.h
src/coreclr/src/vm/i386/cgenx86.cpp
src/coreclr/src/vm/i386/excepcpu.h
src/coreclr/src/vm/i386/excepx86.cpp
src/coreclr/src/vm/i386/jithelp.S
src/coreclr/src/vm/i386/unixstubs.cpp
src/coreclr/src/vm/jitinterface.cpp
src/coreclr/src/vm/jitinterface.h
src/coreclr/src/vm/stackwalk.cpp
src/coreclr/src/vm/threadsuspend.cpp
src/coreclr/src/zap/common.h
src/coreclr/src/zap/zapcode.cpp

index 8217355..cc80d77 100644 (file)
@@ -28,6 +28,7 @@
 namespace ARMGCDump
 {
 #undef _TARGET_X86_
+#define WIN64EXCEPTIONS
 #undef LIMITED_METHOD_CONTRACT
 #define LIMITED_METHOD_DAC_CONTRACT
 #define SUPPORTS_DAC
index d66af05..0f38aa5 100644 (file)
@@ -970,7 +970,7 @@ HRESULT ClrDataAccess::EnumMemWalkStackHelper(CLRDataEnumMemoryFlags flags,
                             // Pulls in sequence points and local variable info
                             DebugInfoManager::EnumMemoryRegionsForMethodDebugInfo(flags, pMethodDesc);
 
-#ifdef WIN64EXCEPTIONS
+#if defined(WIN64EXCEPTIONS) && defined(USE_GC_INFO_DECODER)
                           
                             if (addr != NULL)
                             {
@@ -988,7 +988,7 @@ HRESULT ClrDataAccess::EnumMemWalkStackHelper(CLRDataEnumMemoryFlags flags,
                                     DacEnumMemoryRegion(dac_cast<TADDR>(pGCInfo), gcDecoder.GetNumBytesRead(), true);
                                 }
                             }
-#endif // WIN64EXCEPTIONS
+#endif // WIN64EXCEPTIONS && USE_GC_INFO_DECODER
                         }
                         pMethodDefinition.Clear();
                     }
index 18920ad..8f369b7 100644 (file)
@@ -6929,11 +6929,11 @@ public:
     // new-style constructor
     CordbMiscFrame(DebuggerIPCE_JITFuncData * pJITFuncData);
 
-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
+#ifdef WIN64EXCEPTIONS
     SIZE_T             parentIP;
     FramePointer       fpParentOrSelf;
     bool               fIsFilterFunclet;
-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
+#endif // WIN64EXCEPTIONS
 };
 
 
index a4660be..02fae00 100644 (file)
@@ -5849,11 +5849,11 @@ CordbMiscFrame::CordbMiscFrame()
 // the real constructor which stores the funclet-related information in the CordbMiscFrame
 CordbMiscFrame::CordbMiscFrame(DebuggerIPCE_JITFuncData * pJITFuncData)
 {
-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
+#ifdef WIN64EXCEPTIONS
     this->parentIP       = pJITFuncData->parentNativeOffset;
     this->fpParentOrSelf = pJITFuncData->fpParentOrSelf;
     this->fIsFilterFunclet = (pJITFuncData->fIsFilterFrame == TRUE);
-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
+#endif // WIN64EXCEPTIONS
 }
 
 /* ------------------------------------------------------------------------- *
index 6ace36e..1b4dec7 100644 (file)
@@ -1355,11 +1355,11 @@ struct MSLAYOUT DebuggerIPCE_JITFuncData
     LSPTR_DJI   nativeCodeJITInfoToken;
     VMPTR_MethodDesc vmNativeCodeMethodDescToken;
 
-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
+#ifdef WIN64EXCEPTIONS
     BOOL         fIsFilterFrame;
     SIZE_T       parentNativeOffset;
     FramePointer fpParentOrSelf;
-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
+#endif // WIN64EXCEPTIONS
 
     // indicates if the MethodDesc is a generic function or a method inside a generic class (or
     // both!).
index 0e082c7..9a4601e 100644 (file)
@@ -837,6 +837,13 @@ RtlVirtualUnwind_Unsafe(
 
 #ifdef _TARGET_X86_
 #ifndef FEATURE_PAL
+//
+// x86 ABI does not define RUNTIME_FUNCTION. Define our own to allow unification between x86 and other platforms.
+//
+typedef struct _RUNTIME_FUNCTION {
+    DWORD BeginAddress;
+    DWORD UnwindData;
+} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
 
 typedef struct _DISPATCHER_CONTEXT {
     _EXCEPTION_REGISTRATION_RECORD* RegistrationPointer;
@@ -845,6 +852,43 @@ typedef struct _DISPATCHER_CONTEXT {
 #endif // !FEATURE_PAL
 
 #define RUNTIME_FUNCTION__BeginAddress(prf)             (prf)->BeginAddress
+#define RUNTIME_FUNCTION__SetBeginAddress(prf,addr)     ((prf)->BeginAddress = (addr))
+
+#ifdef WIN64EXCEPTIONS
+EXTERN_C ULONG
+RtlpGetFunctionEndAddress (
+    __in PT_RUNTIME_FUNCTION FunctionEntry,
+    __in ULONG ImageBase
+    );
+
+#define RUNTIME_FUNCTION__EndAddress(prf, ImageBase)   RtlpGetFunctionEndAddress(prf, ImageBase)
+
+#define RUNTIME_FUNCTION__GetUnwindInfoAddress(prf)    (prf)->UnwindData
+#define RUNTIME_FUNCTION__SetUnwindInfoAddress(prf, addr) do { (prf)->UnwindData = (addr); } while(0)
+
+#define UNW_FLAG_NHANDLER               0x0             /* any handler */
+#define UNW_FLAG_EHANDLER               0x1             /* filter handler */
+#define UNW_FLAG_UHANDLER               0x2             /* unwind handler */
+
+typedef struct _UNWIND_INFO {
+    // dummy
+} UNWIND_INFO, *PUNWIND_INFO;
+
+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
+    );
+#endif // WIN64EXCEPTIONS
 
 #endif // _TARGET_X86_
 
index 3b517ae..7346314 100644 (file)
 #error FEATURE_PREJIT is required for this file
 #endif // FEATURE_PREJIT
 
-#if !defined(_TARGET_X86_)
+#if !defined(_TARGET_X86_) || defined(FEATURE_PAL)
 #ifndef WIN64EXCEPTIONS
 #define WIN64EXCEPTIONS
 #endif
-#endif  // !_TARGET_X86_
+#endif  // !_TARGET_X86_ || FEATURE_PAL
 
 #include <cor.h>
 #include <corhdr.h>
@@ -72,16 +72,6 @@ typedef DPTR(struct CORCOMPILE_IMPORT_SECTION)
     PTR_CORCOMPILE_IMPORT_SECTION;
 
 #ifdef _TARGET_X86_
-#ifndef FEATURE_PAL
-//
-// x86 ABI does not define RUNTIME_FUNCTION. Define our own to allow unification between x86 and other platforms.
-//
-typedef struct _RUNTIME_FUNCTION {
-    DWORD BeginAddress;
-    DWORD UnwindData;
-} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
-
-#endif // !FEATURE_PAL
 
 typedef DPTR(RUNTIME_FUNCTION) PTR_RUNTIME_FUNCTION;
 
index 502d181..55cc905 100644 (file)
@@ -602,7 +602,7 @@ HRESULT FixContextForEnC(PCONTEXT        pCtx,
 
 #endif // #ifndef DACCESS_COMPILE
 
-#ifndef _TARGET_X86_
+#ifdef WIN64EXCEPTIONS
     static void EnsureCallerContextIsValid( PREGDISPLAY pRD, StackwalkCacheEntry* pCacheEntry, EECodeInfo * pCodeInfo = NULL );
     static size_t GetCallerSp( PREGDISPLAY  pRD );
 #endif
index 6d4850a..5151616 100644 (file)
@@ -451,6 +451,7 @@ private:
     GcSlotDesc* m_pLastSlot;
 };
 
+#ifdef USE_GC_INFO_DECODER
 class GcInfoDecoder
 {
 public:
@@ -678,6 +679,7 @@ private:
         }
     }
 };
+#endif // USE_GC_INFO_DECODER
 
 
 #endif // _GC_INFO_DECODER_
index f84db91..89d4be7 100644 (file)
     JITHELPER(CORINFO_HELP_FIELD_ACCESS_EXCEPTION,JIT_ThrowFieldAccessException, CORINFO_HELP_SIG_REG_ONLY)
     JITHELPER(CORINFO_HELP_CLASS_ACCESS_EXCEPTION,JIT_ThrowClassAccessException, CORINFO_HELP_SIG_REG_ONLY)
 
-#ifdef WIN64EXCEPTIONS
+// UNIXTODO: Disable JIT_EndCatch after revising the jitter not to use this (for x86/Linux)
+#ifndef _TARGET_X86_
     JITHELPER(CORINFO_HELP_ENDCATCH,            NULL,               CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
 #else
     JITHELPER(CORINFO_HELP_ENDCATCH,            JIT_EndCatch,       CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
index 9204862..ebc557b 100644 (file)
@@ -279,7 +279,7 @@ enum ReadyToRunHelper
     READYTORUN_HELPER_DblRound                  = 0xE2,
     READYTORUN_HELPER_FltRound                  = 0xE3,
 
-#ifndef _TARGET_X86_
+#ifdef WIN64EXCEPTIONS
     // Personality rountines
     READYTORUN_HELPER_PersonalityRoutine        = 0xF0,
     READYTORUN_HELPER_PersonalityRoutineFilterFunclet = 0xF1,
index 09a6a38..8114346 100644 (file)
@@ -18,10 +18,33 @@ struct REGDISPLAY {
                           // returned by GetContext or provided
                           // at exception time.
 
+#ifndef WIN64EXCEPTIONS
     // TODO: Unify with pCurrentContext / pCallerContext used on 64-bit
     PCONTEXT pContextForUnwind; // scratch context for unwinding
                                 // used to preserve context saved in the frame that 
                                 // could be otherwise wiped by the unwinding
+#else // !WIN64EXCEPTIONS
+    PT_CONTEXT pCurrentContext;   // [trashed] points to current Context of stackwalk
+    PT_CONTEXT pCallerContext;    // [trashed] points to the Context of the caller during stackwalk -- used for GC crawls
+
+    // [trashed] points to current context pointers of stackwalk
+    T_KNONVOLATILE_CONTEXT_POINTERS *pCurrentContextPointers;
+    // [trashed] points to the context pointers of the caller during stackwalk -- used for GC crawls
+    T_KNONVOLATILE_CONTEXT_POINTERS *pCallerContextPointers;
+
+    BOOL IsCallerContextValid;  // TRUE if pCallerContext really contains the caller's context
+    BOOL IsCallerSPValid;       // Don't add usage of this field.  This is only temporary.
+
+    T_CONTEXT  ctxOne;    // used by stackwalk
+    T_CONTEXT  ctxTwo;    // used by stackwalk
+
+    T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsOne;  // used by stackwalk
+    T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsTwo;  // used by stackwalk
+
+#ifdef DEBUG_REGDISPLAY
+    Thread *_pThread;
+#endif // DEBUG_REGDISPLAY
+#endif // !WIN64EXCEPTIONS
 
     DWORD * pEdi;
     DWORD * pEsi;
@@ -166,18 +189,6 @@ inline PCODE GetControlPC(REGDISPLAY *display) {
 void CheckRegDisplaySP (REGDISPLAY *pRD);
 #endif // DEBUG_REGDISPLAY
 
-inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD)
-{
-    LIMITED_METHOD_CONTRACT;
-
-    pRD->SP         = (INT_PTR)GetSP(pRD->pCurrentContext);
-
-#ifdef DEBUG_REGDISPLAY
-    CheckRegDisplaySP(pRD);
-#endif // DEBUG_REGDISPLAY
-
-    pRD->ControlPC  = INT_PTR(GetIP(pRD->pCurrentContext));
-}
 
 // This function tells us if the given stack pointer is in one of the frames of the functions called by the given frame
 inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer)
@@ -204,20 +215,6 @@ inline TADDR GetRegdisplayStackMark(REGDISPLAY *display)
 #endif // _TARGET_AMD64_
 }
 
-// This needs to be implemented for platforms that have funclets.
-inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display)
-{
-    LIMITED_METHOD_CONTRACT;
-
-#if defined(_TARGET_AMD64_)
-    return (LPVOID)display->pCurrentContext->Rax;
-#elif defined(_TARGET_ARM64_)
-    return (LPVOID)display->pCurrentContext->X0;
-#else
-    PORTABILITY_ASSERT("GetRegdisplayReturnValue NYI for this platform (Regdisp.h)");
-    return NULL;
-#endif
-}
 
 #elif defined(_TARGET_ARM_)
 
@@ -307,20 +304,7 @@ inline TADDR GetRegdisplayStackMark(REGDISPLAY *display) {
     return GetSP(display->pCallerContext);
 }
 
-inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD)
-{
-    LIMITED_METHOD_CONTRACT;
-    pRD->SP         = (DWORD)GetSP(pRD->pCurrentContext);
-    pRD->ControlPC  = (DWORD)GetIP(pRD->pCurrentContext);
-}
-
-// This needs to be implemented for platforms that have funclets.
-inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display)
-{
-    LIMITED_METHOD_CONTRACT;
 
-    return (LPVOID)display->pCurrentContext->R0;
-}
 
 #else // none of the above processors
 
@@ -359,6 +343,50 @@ inline LPVOID GetRegdisplayStackMark(REGDISPLAY *display) {
 
 #endif
 
+#if defined(_WIN64) || defined(_TARGET_ARM_) || (defined(_TARGET_X86_) && defined(WIN64EXCEPTIONS))
+// This needs to be implemented for platforms that have funclets.
+inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display)
+{
+    LIMITED_METHOD_CONTRACT;
+
+#if defined(_TARGET_AMD64_)
+    return (LPVOID)display->pCurrentContext->Rax;
+#elif defined(_TARGET_ARM64_)
+    return (LPVOID)display->pCurrentContext->X0;
+#elif defined(_TARGET_ARM_)
+    return (LPVOID)display->pCurrentContext->R0;
+#elif defined(_TARGET_X86_)
+    return (LPVOID)display->pCurrentContext->Eax;
+#else
+    PORTABILITY_ASSERT("GetRegdisplayReturnValue NYI for this platform (Regdisp.h)");
+    return NULL;
+#endif
+}
+
+inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD)
+{
+    LIMITED_METHOD_CONTRACT;
+
+#if defined(_WIN64)
+    pRD->SP         = (INT_PTR)GetSP(pRD->pCurrentContext);
+
+#ifdef DEBUG_REGDISPLAY
+    CheckRegDisplaySP(pRD);
+#endif // DEBUG_REGDISPLAY
+
+    pRD->ControlPC  = INT_PTR(GetIP(pRD->pCurrentContext));
+#elif defined(_TARGET_ARM_) // _WIN64
+    pRD->SP         = (DWORD)GetSP(pRD->pCurrentContext);
+    pRD->ControlPC  = (DWORD)GetIP(pRD->pCurrentContext);
+#elif defined(_TARGET_X86_) // _TARGET_ARM_
+    pRD->Esp        = (DWORD)GetSP(pRD->pCurrentContext);
+    pRD->ControlPC  = (DWORD)GetIP(pRD->pCurrentContext);
+#else // _TARGET_X86_
+    PORTABILITY_ASSERT("SyncRegDisplayToCurrentContext");
+#endif // _TARGET_ARM_ || _TARGET_X86_
+}
+#endif // _WIN64 || _TARGET_ARM_ || (_TARGET_X86_ && WIN64EXCEPTIONS)
+
 typedef REGDISPLAY *PREGDISPLAY;
 
 
@@ -368,6 +396,7 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
 
     SUPPORTS_DAC;
 
+#ifndef WIN64EXCEPTIONS
 #ifdef _TARGET_X86_
     pRD->pContext = pctx;
     pRD->pContextForUnwind = NULL;
@@ -381,57 +410,38 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
     pRD->Esp  = pctx->Esp;
     pRD->ControlPC = (PCODE)(pctx->Eip);
     pRD->PCTAddr = (UINT_PTR)&(pctx->Eip);
-#elif defined(_WIN64)
+#else // _TARGET_X86_
+    PORTABILITY_ASSERT("FillRegDisplay");
+#endif // _TARGET_???_ (ELSE)
+
+#else // !WIN64EXCEPTIONS
     pRD->pContext   = pctx;
 #ifdef _TARGET_AMD64_
     for (int i = 0; i < 16; i++)
     {
         *(&pRD->ctxPtrsOne.Rax + i) = (&pctx->Rax + i);
     }
-#elif defined(_TARGET_ARM64_)
+#elif defined(_TARGET_ARM64_) // _TARGET_AMD64_
     for (int i = 0; i < 12; i++)
     {
         *(&pRD->ctxPtrsOne.X19 + i) = (&pctx->X19 + i);
     }
-#endif // _TARGET_AMD64_
-
-    pRD->pCurrentContextPointers = &pRD->ctxPtrsOne;
-    pRD->pCallerContextPointers = &pRD->ctxPtrsTwo;
-
-    pRD->pCurrentContext = &(pRD->ctxOne);
-    pRD->pCallerContext  = &(pRD->ctxTwo);
-
-    // copy the active context to initialize our stackwalk
-    *(pRD->pCurrentContext)     = *(pctx);
-
-    // copy the caller context as well if it's specified
-    if (pCallerCtx == NULL)
-    {
-        pRD->IsCallerContextValid = FALSE;
-        pRD->IsCallerSPValid      = FALSE;        // Don't add usage of this field.  This is only temporary.
-    }
-    else
-    {
-        *(pRD->pCallerContext)    = *(pCallerCtx);
-        pRD->IsCallerContextValid = TRUE;
-        pRD->IsCallerSPValid      = TRUE;        // Don't add usage of this field.  This is only temporary.
-    }
-
-#ifdef DEBUG_REGDISPLAY
-    pRD->_pThread = NULL;
-#endif // DEBUG_REGDISPLAY
-
-    SyncRegDisplayToCurrentContext(pRD);
-#elif defined(_TARGET_ARM_)
-    pRD->pContext = pctx;
-
+#elif defined(_TARGET_ARM_) // _TARGET_ARM64_
     // Copy over the nonvolatile integer registers (R4-R11)
     for (int i = 0; i < 8; i++)
     {
         *(&pRD->ctxPtrsOne.R4 + i) = (&pctx->R4 + i);
     }
 
-    pRD->ctxPtrsOne.Lr = &pctx->Lr; 
+    pRD->ctxPtrsOne.Lr = &pctx->Lr;
+#elif defined(_TARGET_X86_) // _TARGET_ARM_
+    for (int i = 0; i < 4; ++i)
+    {
+        *(&pRD->ctxPtrsOne.Ebx + i) = (&pctx->Ebx + i);
+    }
+#else // _TARGET_X86_
+    PORTABILITY_ASSERT("FillRegDisplay");
+#endif // _TARGET_???_ (ELSE)
 
     // Setup the references
     pRD->pCurrentContextPointers = &pRD->ctxPtrsOne;
@@ -456,7 +466,9 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
         pRD->IsCallerSPValid      = TRUE;        // Don't add usage of this field.  This is only temporary.
     }
 
+#ifdef _TARGET_ARM_
     pRD->pPC = &pRD->pCurrentContext->Pc;
+#endif
 
 #ifdef DEBUG_REGDISPLAY
     pRD->_pThread = NULL;
@@ -464,9 +476,7 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
 
     // This will setup the PC and SP
     SyncRegDisplayToCurrentContext(pRD);
-#else
-    PORTABILITY_ASSERT("@NYI Platform - InitRegDisplay (Threads.cpp)");
-#endif
+#endif // !WIN64EXCEPTIONS
 }
 
 // Initialize a new REGDISPLAY/CONTEXT pair from an existing valid REGDISPLAY.
index f52f24b..bb3ca28 100644 (file)
@@ -37,7 +37,7 @@
     #define LOGGING
 #endif
 
-#if !defined(_TARGET_X86_)
+#if !defined(_TARGET_X86_) || defined(FEATURE_PAL)
 #define WIN64EXCEPTIONS
 #endif
 
index 51ac5b9..a449ba7 100644 (file)
@@ -6496,8 +6496,8 @@ public:
 
 typedef BOOL (PALAPI *PHARDWARE_EXCEPTION_HANDLER)(PAL_SEHException* ex);
 typedef BOOL (PALAPI *PHARDWARE_EXCEPTION_SAFETY_CHECK_FUNCTION)(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord);
-typedef VOID (PALAPI *PTERMINATION_REQUEST_HANDLER)();
-typedef DWORD (PALAPI *PGET_GCMARKER_EXCEPTION_CODE)(LPVOID ip);
+typedef VOID (*PTERMINATION_REQUEST_HANDLER)();
+typedef DWORD (*PGET_GCMARKER_EXCEPTION_CODE)(LPVOID ip);
 
 PALIMPORT
 VOID
index 9fdddd6..4a64fcf 100644 (file)
@@ -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
index cdb7cc8..c615d66 100644 (file)
@@ -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));
index 0fe261a..5fb8da1 100644 (file)
@@ -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;
index 2ce7b59..16b9de4 100644 (file)
@@ -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
 }
 
 
index 1d24237..cd154c0 100644 (file)
@@ -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)
index e50a770..53fa201 100644 (file)
@@ -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
 
index 56c784a..475bf3b 100644 (file)
@@ -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_)    
index 9e07ceb..1ae011e 100644 (file)
@@ -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
index bde71db..29c7a06 100644 (file)
@@ -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.
index 7c505b8..2702936 100644 (file)
@@ -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;
index 91ab3c3..e37f980 100644 (file)
@@ -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 ()
index 5fb83bf..792e748 100644 (file)
@@ -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(),
index 99f4eb4..38a88a7 100644 (file)
@@ -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
index 08ccd01..703968c 100644 (file)
@@ -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;
index ff540e7..d70c662 100644 (file)
@@ -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
index c6a95ef..0f05aa2 100644 (file)
@@ -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
index 66ae9fb..35a0261 100644 (file)
@@ -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
index 3252922..4025c26 100644 (file)
@@ -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;
+}
index 2f9db3d..9d57836 100644 (file)
@@ -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
 
index ee13b9c..6cc3a05 100644 (file)
@@ -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
 
index 18a8900..44e5f99 100644 (file)
@@ -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
             }
         }
 
index 2e6563d..18d04db 100644 (file)
@@ -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_
                 )
index 95655fd..b3db657 100644 (file)
 #include <float.h>
 #include <limits.h>
 
-#if !defined(_TARGET_X86_)
+#if !defined(_TARGET_X86_) || defined(FEATURE_PAL)
 #ifndef WIN64EXCEPTIONS
 #define WIN64EXCEPTIONS
 #endif
-#endif // !_TARGET_X86_
+#endif // !_TARGET_X86_ || FEATURE_PAL
 
 #include "utilcode.h"
 #include "corjit.h"
index 167c0ed..e54e884 100644 (file)
@@ -1130,7 +1130,7 @@ void ZapUnwindInfo::Save(ZapWriter * pZapWriter)
     pZapWriter->Write(&runtimeFunction, sizeof(runtimeFunction));
 }
 
-#if defined(WIN64EXCEPTIONS) && !defined(_TARGET_X86_)
+#if defined(WIN64EXCEPTIONS)
 // Compare the unwind infos by their offset
 int __cdecl ZapUnwindInfo::CompareUnwindInfo(const void* a_, const void* b_)
 {