summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonghyun Park <parjong@gmail.com>2017-01-23 19:46:37 +0900
committerJan Vorlicek <janvorli@microsoft.com>2017-01-23 11:46:37 +0100
commit347243f80d62d5aaa5359ef8c8d5331b6d8e4a63 (patch)
tree82fa5ea05a77885661cc070d4d84026bbb4d9536 /src
parent62ac5f04456e517b76bcfc3d386859a506eed6d1 (diff)
downloadcoreclr-347243f80d62d5aaa5359ef8c8d5331b6d8e4a63.tar.gz
coreclr-347243f80d62d5aaa5359ef8c8d5331b6d8e4a63.tar.bz2
coreclr-347243f80d62d5aaa5359ef8c8d5331b6d8e4a63.zip
[x86/Linux] Enable FEATURE_EH_FUNCLETS (#8889)
* [x86/Linux] (Partially) Enable FEATURE_EH_FUNCLETS * Update CLR ABI Document * Add TODO (for Funclet Prolog/Epilog Gen)
Diffstat (limited to 'src')
-rw-r--r--src/inc/clrnt.h22
-rw-r--r--src/inc/win64unwind.h9
-rw-r--r--src/jit/CMakeLists.txt1
-rw-r--r--src/jit/codegencommon.cpp60
-rw-r--r--src/jit/codegenxarch.cpp6
-rw-r--r--src/jit/compiler.h11
-rw-r--r--src/jit/target.h4
-rw-r--r--src/jit/unwind.cpp32
-rw-r--r--src/jit/unwindx86.cpp249
-rw-r--r--src/pal/inc/pal.h2
-rw-r--r--src/vm/i386/unixstubs.cpp10
-rw-r--r--src/vm/jitinterface.cpp88
12 files changed, 389 insertions, 105 deletions
diff --git a/src/inc/clrnt.h b/src/inc/clrnt.h
index 9a4601ebaf..08a93a4961 100644
--- a/src/inc/clrnt.h
+++ b/src/inc/clrnt.h
@@ -855,25 +855,25 @@ typedef struct _DISPATCHER_CONTEXT {
#define RUNTIME_FUNCTION__SetBeginAddress(prf,addr) ((prf)->BeginAddress = (addr))
#ifdef WIN64EXCEPTIONS
-EXTERN_C ULONG
+#include "win64unwind.h"
+
+FORCEINLINE
+DWORD
RtlpGetFunctionEndAddress (
__in PT_RUNTIME_FUNCTION FunctionEntry,
- __in ULONG ImageBase
- );
+ __in TADDR ImageBase
+ )
+{
+ PUNWIND_INFO pUnwindInfo = (PUNWIND_INFO)(ImageBase + FunctionEntry->UnwindData);
+
+ return FunctionEntry->BeginAddress + pUnwindInfo->FunctionLength;
+}
#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
diff --git a/src/inc/win64unwind.h b/src/inc/win64unwind.h
index 196052aca9..e4cea023b2 100644
--- a/src/inc/win64unwind.h
+++ b/src/inc/win64unwind.h
@@ -89,6 +89,14 @@ typedef union _UNWIND_CODE {
#define UNW_FLAG_UHANDLER 0x2
#define UNW_FLAG_CHAININFO 0x4
+#ifdef _TARGET_X86_
+
+typedef struct _UNWIND_INFO {
+ ULONG FunctionLength;
+} UNWIND_INFO, *PUNWIND_INFO;
+
+#else // _TARGET_X86_
+
typedef struct _UNWIND_INFO {
UCHAR Version : 3;
UCHAR Flags : 5;
@@ -114,4 +122,5 @@ typedef struct _UNWIND_INFO {
} UNWIND_INFO, *PUNWIND_INFO;
+#endif // _TARGET_X86_
#endif // _WIN64UNWIND_H_
diff --git a/src/jit/CMakeLists.txt b/src/jit/CMakeLists.txt
index 1184e69ff7..1fbbb355b0 100644
--- a/src/jit/CMakeLists.txt
+++ b/src/jit/CMakeLists.txt
@@ -104,6 +104,7 @@ elseif(CLR_CMAKE_TARGET_ARCH_I386)
simd.cpp
simdcodegenxarch.cpp
targetx86.cpp
+ unwindx86.cpp
)
elseif(CLR_CMAKE_TARGET_ARCH_ARM64)
set( ARCH_SOURCES
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index f42103ebce..0cc6995d18 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -10241,6 +10241,66 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
// Look in CodeGenArm64.cpp
+#elif defined(_TARGET_X86_)
+
+/*****************************************************************************
+ *
+ * Generates code for an EH funclet prolog.
+ */
+
+void CodeGen::genFuncletProlog(BasicBlock* block)
+{
+#ifdef DEBUG
+ if (verbose)
+ {
+ printf("*************** In genFuncletProlog()\n");
+ }
+#endif
+
+ ScopedSetVariable<bool> _setGeneratingProlog(&compiler->compGeneratingProlog, true);
+
+ compiler->unwindBegProlog();
+
+ // TODO Save callee-saved registers
+
+ // This is the end of the OS-reported prolog for purposes of unwinding
+ compiler->unwindEndProlog();
+}
+
+/*****************************************************************************
+ *
+ * Generates code for an EH funclet epilog.
+ */
+
+void CodeGen::genFuncletEpilog()
+{
+#ifdef DEBUG
+ if (verbose)
+ {
+ printf("*************** In genFuncletEpilog()\n");
+ }
+#endif
+
+ ScopedSetVariable<bool> _setGeneratingEpilog(&compiler->compGeneratingEpilog, true);
+
+ // TODO Restore callee-saved registers
+
+ instGen_Return(0);
+}
+
+/*****************************************************************************
+ *
+ * Capture the information used to generate the funclet prologs and epilogs.
+ */
+
+void CodeGen::genCaptureFuncletPrologEpilogInfo()
+{
+ if (!compiler->ehAnyFunclets())
+ {
+ return;
+ }
+}
+
#else // _TARGET_*
/*****************************************************************************
diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp
index 742edae298..c3774ea74a 100644
--- a/src/jit/codegenxarch.cpp
+++ b/src/jit/codegenxarch.cpp
@@ -263,10 +263,14 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block, BasicBlock* lblk)
}
else
{
+// TODO-Linux-x86: Do we need to handle the GC information for this NOP or JMP specially, as is done for other
+// architectures?
+#ifndef JIT32_GCENCODER
// Because of the way the flowgraph is connected, the liveness info for this one instruction
// after the call is not (can not be) correct in cases where a variable has a last use in the
// handler. So turn off GC reporting for this single instruction.
getEmitter()->emitDisableGC();
+#endif // JIT32_GCENCODER
// Now go to where the finally funclet needs to return to.
if (block->bbNext->bbJumpDest == block->bbNext->bbNext)
@@ -282,7 +286,9 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block, BasicBlock* lblk)
inst_JMP(EJ_jmp, block->bbNext->bbJumpDest);
}
+#ifndef JIT32_GCENCODER
getEmitter()->emitEnableGC();
+#endif // JIT32_GCENCODER
}
#else // !FEATURE_EH_FUNCLETS
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 19dfbda7c3..54079b945c 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -1769,7 +1769,11 @@ public:
// a PSPSym for functions with any EH.
bool ehNeedsPSPSym() const
{
+#ifdef _TARGET_X86_
+ return false;
+#else // _TARGET_X86_
return compHndBBtabCount > 0;
+#endif // _TARGET_X86_
}
bool ehAnyFunclets(); // Are there any funclets in this function?
@@ -6848,10 +6852,15 @@ private:
void unwindReserveFunc(FuncInfoDsc* func);
void unwindEmitFunc(FuncInfoDsc* func, void* pHotCode, void* pColdCode);
-#if defined(_TARGET_AMD64_)
+#if defined(_TARGET_AMD64_) || (defined(_TARGET_X86_) && FEATURE_EH_FUNCLETS)
void unwindReserveFuncHelper(FuncInfoDsc* func, bool isHotCode);
void unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pColdCode, bool isHotCode);
+
+#endif // _TARGET_AMD64_ || (_TARGET_X86_ && FEATURE_EH_FUNCLETS)
+
+#if defined(_TARGET_AMD64_)
+
UNATIVE_OFFSET unwindGetCurrentOffset(FuncInfoDsc* func);
void unwindBegPrologWindows();
diff --git a/src/jit/target.h b/src/jit/target.h
index 32eb16698c..6330d52889 100644
--- a/src/jit/target.h
+++ b/src/jit/target.h
@@ -409,7 +409,11 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
// target
#define FEATURE_EH 1 // To aid platform bring-up, eliminate exceptional EH clauses (catch, filter,
// filter-handler, fault) and directly execute 'finally' clauses.
+#if defined(FEATURE_PAL) && !defined(LEGACY_BACKEND)
+ #define FEATURE_EH_FUNCLETS 1
+#else // FEATURE_PAL && !LEGACY_BACKEND
#define FEATURE_EH_FUNCLETS 0
+#endif // FEATURE_PAL && !LEGACY_BACKEND
#define FEATURE_EH_CALLFINALLY_THUNKS 0 // Generate call-to-finally code in "thunks" in the enclosing EH region,
// protected by "cloned finally" clauses.
#ifndef LEGACY_BACKEND
diff --git a/src/jit/unwind.cpp b/src/jit/unwind.cpp
index 4568fed75a..b354504bb7 100644
--- a/src/jit/unwind.cpp
+++ b/src/jit/unwind.cpp
@@ -132,37 +132,7 @@ void Compiler::unwindGetFuncLocations(FuncInfoDsc* func,
#elif defined(_TARGET_X86_)
-// Stub routines that do nothing
-void Compiler::unwindBegProlog()
-{
-}
-void Compiler::unwindEndProlog()
-{
-}
-void Compiler::unwindBegEpilog()
-{
-}
-void Compiler::unwindEndEpilog()
-{
-}
-void Compiler::unwindReserve()
-{
-}
-void Compiler::unwindEmit(void* pHotCode, void* pColdCode)
-{
-}
-void Compiler::unwindPush(regNumber reg)
-{
-}
-void Compiler::unwindAllocStack(unsigned size)
-{
-}
-void Compiler::unwindSetFrameReg(regNumber reg, unsigned offset)
-{
-}
-void Compiler::unwindSaveReg(regNumber reg, unsigned offset)
-{
-}
+// See unwindX86.cpp
#else // _TARGET_*
diff --git a/src/jit/unwindx86.cpp b/src/jit/unwindx86.cpp
new file mode 100644
index 0000000000..516155c6a2
--- /dev/null
+++ b/src/jit/unwindx86.cpp
@@ -0,0 +1,249 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XX XX
+XX UnwindInfo XX
+XX XX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+*/
+
+#include "jitpch.h"
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#ifndef _TARGET_X86_
+#error "This should be included only for x86"
+#endif // _TARGET_X86_
+
+void Compiler::unwindBegProlog()
+{
+}
+
+void Compiler::unwindEndProlog()
+{
+}
+
+void Compiler::unwindBegEpilog()
+{
+}
+
+void Compiler::unwindEndEpilog()
+{
+}
+
+void Compiler::unwindPush(regNumber reg)
+{
+}
+
+void Compiler::unwindAllocStack(unsigned size)
+{
+}
+
+void Compiler::unwindSetFrameReg(regNumber reg, unsigned offset)
+{
+}
+
+void Compiler::unwindSaveReg(regNumber reg, unsigned offset)
+{
+}
+
+//------------------------------------------------------------------------
+// Compiler::unwindReserve: Ask the VM to reserve space for the unwind information
+// for the function and all its funclets. Called once, just before asking the VM
+// for memory and emitting the generated code. Calls unwindReserveFunc() to handle
+// the main function and each of the funclets, in turn.
+//
+void Compiler::unwindReserve()
+{
+#if FEATURE_EH_FUNCLETS
+ assert(!compGeneratingProlog);
+ assert(!compGeneratingEpilog);
+
+ assert(compFuncInfoCount > 0);
+ for (unsigned funcIdx = 0; funcIdx < compFuncInfoCount; funcIdx++)
+ {
+ unwindReserveFunc(funGetFunc(funcIdx));
+ }
+#endif
+}
+
+//------------------------------------------------------------------------
+// Compiler::unwindEmit: Report all the unwind information to the VM.
+//
+// Arguments:
+// pHotCode - Pointer to the beginning of the memory with the function and funclet hot code.
+// pColdCode - Pointer to the beginning of the memory with the function and funclet cold code.
+//
+void Compiler::unwindEmit(void* pHotCode, void* pColdCode)
+{
+#if FEATURE_EH_FUNCLETS
+ assert(!compGeneratingProlog);
+ assert(!compGeneratingEpilog);
+
+ assert(compFuncInfoCount > 0);
+ for (unsigned funcIdx = 0; funcIdx < compFuncInfoCount; funcIdx++)
+ {
+ unwindEmitFunc(funGetFunc(funcIdx), pHotCode, pColdCode);
+ }
+#endif // FEATURE_EH_FUNCLETS
+}
+
+#if FEATURE_EH_FUNCLETS
+//------------------------------------------------------------------------
+// Compiler::unwindReserveFunc: Reserve the unwind information from the VM for a
+// given main function or funclet.
+//
+// Arguments:
+// func - The main function or funclet to reserve unwind info for.
+//
+void Compiler::unwindReserveFunc(FuncInfoDsc* func)
+{
+ unwindReserveFuncHelper(func, true);
+
+ if (fgFirstColdBlock != nullptr)
+ {
+ unwindReserveFuncHelper(func, false);
+ }
+}
+
+//------------------------------------------------------------------------
+// Compiler::unwindReserveFuncHelper: Reserve the unwind information from the VM for a
+// given main function or funclet, for either the hot or the cold section.
+//
+// Arguments:
+// func - The main function or funclet to reserve unwind info for.
+// isHotCode - 'true' to reserve the hot section, 'false' to reserve the cold section.
+//
+void Compiler::unwindReserveFuncHelper(FuncInfoDsc* func, bool isHotCode)
+{
+ BOOL isFunclet = (func->funKind != FUNC_ROOT);
+ BOOL isColdCode = isHotCode ? FALSE : TRUE;
+
+ eeReserveUnwindInfo(isFunclet, isColdCode, sizeof(UNWIND_INFO));
+}
+
+//------------------------------------------------------------------------
+// Compiler::unwindEmitFunc: Report the unwind information to the VM for a
+// given main function or funclet. Reports the hot section, then the cold
+// section if necessary.
+//
+// Arguments:
+// func - The main function or funclet to reserve unwind info for.
+// pHotCode - Pointer to the beginning of the memory with the function and funclet hot code.
+// pColdCode - Pointer to the beginning of the memory with the function and funclet cold code.
+//
+void Compiler::unwindEmitFunc(FuncInfoDsc* func, void* pHotCode, void* pColdCode)
+{
+ // Verify that the JIT enum is in sync with the JIT-EE interface enum
+ static_assert_no_msg(FUNC_ROOT == (FuncKind)CORJIT_FUNC_ROOT);
+ static_assert_no_msg(FUNC_HANDLER == (FuncKind)CORJIT_FUNC_HANDLER);
+ static_assert_no_msg(FUNC_FILTER == (FuncKind)CORJIT_FUNC_FILTER);
+
+ unwindEmitFuncHelper(func, pHotCode, pColdCode, true);
+
+ if (pColdCode != nullptr)
+ {
+ unwindEmitFuncHelper(func, pHotCode, pColdCode, false);
+ }
+}
+
+//------------------------------------------------------------------------
+// Compiler::unwindEmitFuncHelper: Report the unwind information to the VM for a
+// given main function or funclet, for either the hot or cold section.
+//
+// Arguments:
+// func - The main function or funclet to reserve unwind info for.
+// pHotCode - Pointer to the beginning of the memory with the function and funclet hot code.
+// pColdCode - Pointer to the beginning of the memory with the function and funclet cold code.
+// Ignored if 'isHotCode' is true.
+// isHotCode - 'true' to report the hot section, 'false' to report the cold section.
+//
+void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pColdCode, bool isHotCode)
+{
+ UNATIVE_OFFSET startOffset;
+ UNATIVE_OFFSET endOffset;
+
+ if (isHotCode)
+ {
+ emitLocation* startLoc;
+ emitLocation* endLoc;
+
+ unwindGetFuncLocations(func, true, &startLoc, &endLoc);
+
+ if (startLoc == nullptr)
+ {
+ startOffset = 0;
+ }
+ else
+ {
+ startOffset = startLoc->CodeOffset(genEmitter);
+ }
+
+ if (endLoc == nullptr)
+ {
+ endOffset = info.compNativeCodeSize;
+ }
+ else
+ {
+ endOffset = endLoc->CodeOffset(genEmitter);
+ }
+ }
+ else
+ {
+ emitLocation* coldStartLoc;
+ emitLocation* coldEndLoc;
+
+ assert(fgFirstColdBlock != nullptr);
+ assert(func->funKind == FUNC_ROOT); // No splitting of funclets.
+
+ unwindGetFuncLocations(func, false, &coldStartLoc, &coldEndLoc);
+
+ if (coldStartLoc == nullptr)
+ {
+ startOffset = 0;
+ }
+ else
+ {
+ startOffset = coldStartLoc->CodeOffset(genEmitter);
+ }
+
+ if (coldEndLoc == nullptr)
+ {
+ endOffset = info.compNativeCodeSize;
+ }
+ else
+ {
+ endOffset = coldEndLoc->CodeOffset(genEmitter);
+ }
+ }
+
+ // Adjust for cold or hot code:
+ // 1. The VM doesn't want the cold code pointer unless this is cold code.
+ // 2. The startOffset and endOffset need to be from the base of the hot section for hot code
+ // and from the base of the cold section for cold code
+
+ if (isHotCode)
+ {
+ assert(endOffset <= info.compTotalHotCodeSize);
+ pColdCode = nullptr;
+ }
+ else
+ {
+ assert(startOffset >= info.compTotalHotCodeSize);
+ startOffset -= info.compTotalHotCodeSize;
+ endOffset -= info.compTotalHotCodeSize;
+ }
+
+ UNWIND_INFO unwindInfo;
+
+ unwindInfo.FunctionLength = (ULONG)(endOffset - startOffset);
+
+ eeAllocUnwindInfo((BYTE*)pHotCode, (BYTE*)pColdCode, startOffset, endOffset, sizeof(UNWIND_INFO),
+ (BYTE*)&unwindInfo, (CorJitFuncKind)func->funKind);
+}
+#endif // FEATURE_EH_FUNCLETS
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index 8a9972f57b..f9a33dcfcb 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -3896,7 +3896,7 @@ enum {
//
typedef struct _RUNTIME_FUNCTION {
DWORD BeginAddress;
-#ifdef _AMD64_
+#ifdef _TARGET_AMD64_
DWORD EndAddress;
#endif
DWORD UnwindData;
diff --git a/src/vm/i386/unixstubs.cpp b/src/vm/i386/unixstubs.cpp
index cb08f276fe..c0c0982e71 100644
--- a/src/vm/i386/unixstubs.cpp
+++ b/src/vm/i386/unixstubs.cpp
@@ -93,13 +93,3 @@ FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame(DISPATCHER_CONTEXT
PORTABILITY_ASSERT("GetFrameFromRedirectedStubStackFrame");
return NULL;
}
-
-EXTERN_C ULONG
-RtlpGetFunctionEndAddress (
- __in PT_RUNTIME_FUNCTION FunctionEntry,
- __in ULONG ImageBase
- )
-{
- PORTABILITY_ASSERT("RtlpGetFunctionEndAddress");
- return 0;
-}
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 75a228f40a..0b3c9f2605 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -10970,6 +10970,33 @@ void CEEJitInfo::CompressDebugInfo()
EE_TO_JIT_TRANSITION();
}
+void reservePersonalityRoutineSpace(ULONG &unwindSize)
+{
+#if defined(_TARGET_X86_)
+ // Do nothing
+#elif defined(_TARGET_AMD64_)
+ // Add space for personality routine, it must be 4-byte aligned.
+ // Everything in the UNWIND_INFO up to the variable-sized UnwindCodes
+ // array has already had its size included in unwindSize by the caller.
+ unwindSize += sizeof(ULONG);
+
+ // Note that the count of unwind codes (2 bytes each) is stored as a UBYTE
+ // So the largest size could be 510 bytes, plus the header and language
+ // specific stuff. This can't overflow.
+
+ _ASSERTE(FitsInU4(unwindSize + sizeof(ULONG)));
+ unwindSize = (ULONG)(ALIGN_UP(unwindSize, sizeof(ULONG)));
+#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+ // The JIT passes in a 4-byte aligned block of unwind data.
+ _ASSERTE(IS_ALIGNED(unwindSize, sizeof(ULONG)));
+
+ // Add space for personality routine, it must be 4-byte aligned.
+ unwindSize += sizeof(ULONG);
+#else
+ PORTABILITY_ASSERT("reservePersonalityRoutineSpace");
+#endif // !defined(_TARGET_AMD64_)
+
+}
// Reserve memory for the method/funclet's unwind information.
// Note that this must be called before allocMem. It should be
// called once for the main method, once for every funclet, and
@@ -11002,27 +11029,7 @@ void CEEJitInfo::reserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwind
ULONG currentSize = unwindSize;
-#if defined(_TARGET_AMD64_)
- // Add space for personality routine, it must be 4-byte aligned.
- // Everything in the UNWIND_INFO up to the variable-sized UnwindCodes
- // array has already had its size included in unwindSize by the caller.
- currentSize += sizeof(ULONG);
-
- // Note that the count of unwind codes (2 bytes each) is stored as a UBYTE
- // So the largest size could be 510 bytes, plus the header and language
- // specific stuff. This can't overflow.
-
- _ASSERTE(FitsInU4(currentSize + sizeof(ULONG)));
- currentSize = (ULONG)(ALIGN_UP(currentSize, sizeof(ULONG)));
-#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
- // The JIT passes in a 4-byte aligned block of unwind data.
- _ASSERTE(IS_ALIGNED(currentSize, sizeof(ULONG)));
-
- // Add space for personality routine, it must be 4-byte aligned.
- currentSize += sizeof(ULONG);
-#else
- PORTABILITY_ASSERT("CEEJitInfo::reserveUnwindInfo");
-#endif // !defined(_TARGET_AMD64_)
+ reservePersonalityRoutineSpace(currentSize);
m_totalUnwindSize += currentSize;
@@ -11107,27 +11114,7 @@ void CEEJitInfo::allocUnwindInfo (
UNWIND_INFO * pUnwindInfo = (UNWIND_INFO *) &(m_theUnwindBlock[m_usedUnwindSize]);
m_usedUnwindSize += unwindSize;
-#if defined(_TARGET_AMD64_)
- // Add space for personality routine, it must be 4-byte aligned.
- // Everything in the UNWIND_INFO up to the variable-sized UnwindCodes
- // array has already had its size included in unwindSize by the caller.
- m_usedUnwindSize += sizeof(ULONG);
-
- // Note that the count of unwind codes (2 bytes each) is stored as a UBYTE
- // So the largest size could be 510 bytes, plus the header and language
- // specific stuff. This can't overflow.
-
- _ASSERTE(FitsInU4(m_usedUnwindSize + sizeof(ULONG)));
- m_usedUnwindSize = (ULONG)(ALIGN_UP(m_usedUnwindSize,sizeof(ULONG)));
-#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
- // The JIT passes in a 4-byte aligned block of unwind data.
- _ASSERTE(IS_ALIGNED(m_usedUnwindSize, sizeof(ULONG)));
-
- // Add space for personality routine, it must be 4-byte aligned.
- m_usedUnwindSize += sizeof(ULONG);
-#else
- PORTABILITY_ASSERT("CEEJitInfo::reserveUnwindInfo");
-#endif
+ reservePersonalityRoutineSpace(m_usedUnwindSize);
_ASSERTE(m_usedUnwindSize <= m_totalUnwindSize);
@@ -11170,7 +11157,7 @@ void CEEJitInfo::allocUnwindInfo (
RUNTIME_FUNCTION__SetBeginAddress(pRuntimeFunction, currentCodeOffset + startOffset);
-#if defined(_TARGET_AMD64_)
+#ifdef _TARGET_AMD64_
pRuntimeFunction->EndAddress = currentCodeOffset + endOffset;
#endif
@@ -11190,11 +11177,15 @@ void CEEJitInfo::allocUnwindInfo (
}
#endif // _DEBUG
-#if defined(_TARGET_AMD64_)
-
/* Copy the UnwindBlock */
memcpy(pUnwindInfo, pUnwindBlock, unwindSize);
+#if defined(_TARGET_X86_)
+
+ // Do NOTHING
+
+#elif defined(_TARGET_AMD64_)
+
pUnwindInfo->Flags = UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER;
ULONG * pPersonalityRoutine = (ULONG*)ALIGN_UP(&(pUnwindInfo->UnwindCode[pUnwindInfo->CountOfUnwindCodes]), sizeof(ULONG));
@@ -11202,9 +11193,6 @@ void CEEJitInfo::allocUnwindInfo (
#elif defined(_TARGET_ARM64_)
- /* Copy the UnwindBlock */
- memcpy(pUnwindInfo, pUnwindBlock, unwindSize);
-
*(LONG *)pUnwindInfo |= (1 << 20); // X bit
ULONG * pPersonalityRoutine = (ULONG*)((BYTE *)pUnwindInfo + ALIGN_UP(unwindSize, sizeof(ULONG)));
@@ -11212,13 +11200,11 @@ void CEEJitInfo::allocUnwindInfo (
#elif defined(_TARGET_ARM_)
- /* Copy the UnwindBlock */
- memcpy(pUnwindInfo, pUnwindBlock, unwindSize);
-
*(LONG *)pUnwindInfo |= (1 << 20); // X bit
ULONG * pPersonalityRoutine = (ULONG*)((BYTE *)pUnwindInfo + ALIGN_UP(unwindSize, sizeof(ULONG)));
*pPersonalityRoutine = (TADDR)ProcessCLRException - baseAddress;
+
#endif
#if defined(_TARGET_AMD64_)