summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kvochko <kvochko@users.noreply.github.com>2018-12-18 08:28:32 +0300
committerJan Kotas <jkotas@microsoft.com>2018-12-17 21:28:32 -0800
commit33987e98a992e8843b109c90b22c16c85469051c (patch)
tree7c7f35688baafdb4007c4958650abc1c86e8f443
parent779c45746b7cb7a5ea2b83e686d7e9e8e8e98817 (diff)
downloadcoreclr-33987e98a992e8843b109c90b22c16c85469051c.tar.gz
coreclr-33987e98a992e8843b109c90b22c16c85469051c.tar.bz2
coreclr-33987e98a992e8843b109c90b22c16c85469051c.zip
Generate ARM CFIs in prolog (#21505)
-rw-r--r--src/jit/compiler.h4
-rw-r--r--src/jit/unwind.cpp65
-rw-r--r--src/jit/unwindarm.cpp21
3 files changed, 27 insertions, 63 deletions
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 7b91d39e2a..8a8a328d8c 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -7487,10 +7487,6 @@ private:
DWORD cfiCodeBytes,
const CFI_CODE* const pCfiCode);
#endif
-#if defined(_TARGET_ARM_)
- bool unwindCfiEpilogFormed; // Avoid duplicated unwind info for methods with multiple epilogs (we expect and require
- // all the epilogs to be precisely the same)
-#endif
#endif // _TARGET_UNIX_
diff --git a/src/jit/unwind.cpp b/src/jit/unwind.cpp
index f27a8479dc..07296480be 100644
--- a/src/jit/unwind.cpp
+++ b/src/jit/unwind.cpp
@@ -122,56 +122,39 @@ void Compiler::unwindGetFuncLocations(FuncInfoDsc* func,
void Compiler::createCfiCode(FuncInfoDsc* func, UCHAR codeOffset, UCHAR cfiOpcode, USHORT dwarfReg, INT offset)
{
-#if defined(_TARGET_ARM_)
- if (compGeneratingEpilog && unwindCfiEpilogFormed)
- return;
-#endif
CFI_CODE cfiEntry(codeOffset, cfiOpcode, dwarfReg, offset);
func->cfiCodes->push_back(cfiEntry);
}
void Compiler::unwindPushPopCFI(regNumber reg)
{
-#if defined(_TARGET_ARM_)
- assert(compGeneratingEpilog);
-#else
assert(compGeneratingProlog);
-#endif
FuncInfoDsc* func = funCurrentFunc();
- unsigned int cbProlog = 0;
- if (compGeneratingProlog)
- {
- cbProlog = unwindGetCurrentOffset(func);
- noway_assert((BYTE)cbProlog == cbProlog);
-
- createCfiCode(func, cbProlog, CFI_ADJUST_CFA_OFFSET, DWARF_REG_ILLEGAL, REGSIZE_BYTES == 8 ? 8 : 4);
- }
-
- if ((RBM_CALLEE_SAVED & genRegMask(reg))
-#if defined(UNIX_AMD64_ABI)
-#if ETW_EBP_FRAMED
- // In case of ETW_EBP_FRAMED defined the REG_FPBASE (RBP)
- // is excluded from the callee-save register list.
- // Make sure the register gets PUSH unwind info in this case,
- // since it is pushed as a frame register.
- || (reg == REG_FPBASE)
-#endif // ETW_EBP_FRAMED
-#endif // UNIX_AMD64_ABI
+ unsigned int cbProlog = unwindGetCurrentOffset(func);
+ noway_assert((BYTE)cbProlog == cbProlog);
+
+ regMaskTP relOffsetMask = RBM_CALLEE_SAVED
+#if defined(UNIX_AMD64_ABI) && ETW_EBP_FRAMED
+ // In case of ETW_EBP_FRAMED defined the REG_FPBASE (RBP)
+ // is excluded from the callee-save register list.
+ // Make sure the register gets PUSH unwind info in this case,
+ // since it is pushed as a frame register.
+ | RBM_FPBASE
+#endif
#if defined(_TARGET_ARM_)
- || (reg == REG_R11) || (reg == REG_LR) || (reg == REG_PC)
-#endif // _TARGET_ARM_
- )
+ | RBM_R11 | RBM_LR | RBM_PC
+#endif
+ ;
+
+ if (relOffsetMask & genRegMask(reg))
{
createCfiCode(func, cbProlog, CFI_REL_OFFSET, mapRegNumToDwarfReg(reg));
}
-#if defined(_TARGET_ARM_)
- // The non-callee-saved registers are for stack space allocation only
else
{
createCfiCode(func, cbProlog, CFI_ADJUST_CFA_OFFSET, DWARF_REG_ILLEGAL, REGSIZE_BYTES);
}
-#endif // _TARGET_ARM_
}
typedef jitstd::vector<CFI_CODE> CFICodeVector;
@@ -218,11 +201,7 @@ void Compiler::unwindPushPopMaskCFI(regMaskTP regMask, bool isFloat)
void Compiler::unwindAllocStackCFI(unsigned size)
{
-#if defined(_TARGET_ARM_)
- assert(compGeneratingEpilog);
-#else
assert(compGeneratingProlog);
-#endif
FuncInfoDsc* func = funCurrentFunc();
unsigned int cbProlog = 0;
if (compGeneratingProlog)
@@ -242,18 +221,10 @@ void Compiler::unwindAllocStackCFI(unsigned size)
//
void Compiler::unwindSetFrameRegCFI(regNumber reg, unsigned offset)
{
-#if defined(_TARGET_ARM_)
- assert(compGeneratingEpilog);
-#else
assert(compGeneratingProlog);
-#endif
FuncInfoDsc* func = funCurrentFunc();
- unsigned int cbProlog = 0;
- if (compGeneratingProlog)
- {
- cbProlog = unwindGetCurrentOffset(func);
- noway_assert((BYTE)cbProlog == cbProlog);
- }
+ unsigned int cbProlog = unwindGetCurrentOffset(func);
+ noway_assert((BYTE)cbProlog == cbProlog);
createCfiCode(func, cbProlog, CFI_DEF_CFA_REGISTER, mapRegNumToDwarfReg(reg));
if (offset != 0)
diff --git a/src/jit/unwindarm.cpp b/src/jit/unwindarm.cpp
index cfd729091b..4a2b838258 100644
--- a/src/jit/unwindarm.cpp
+++ b/src/jit/unwindarm.cpp
@@ -194,9 +194,6 @@ void Compiler::unwindBegProlog()
if (generateCFIUnwindCodes())
{
unwindBegPrologCFI();
-#if defined(_TARGET_ARM_)
- unwindCfiEpilogFormed = false;
-#endif
return;
}
#endif // _TARGET_UNIX_
@@ -238,11 +235,6 @@ void Compiler::unwindBegEpilog()
void Compiler::unwindEndEpilog()
{
assert(compGeneratingEpilog);
-#if defined(_TARGET_UNIX_)
-#if defined(_TARGET_ARM_)
- unwindCfiEpilogFormed = true;
-#endif
-#endif // _TARGET_UNIX_
}
#if defined(_TARGET_ARM_)
@@ -379,6 +371,12 @@ void Compiler::unwindPushMaskInt(regMaskTP maskInt)
#if defined(_TARGET_UNIX_)
if (generateCFIUnwindCodes())
{
+ // If we are pushing LR, we should give unwind codes in terms of caller's PC
+ if (maskInt & RBM_LR)
+ {
+ maskInt = (maskInt & ~RBM_LR) | RBM_PC;
+ }
+ unwindPushPopMaskCFI(maskInt, false);
return;
}
#endif // _TARGET_UNIX_
@@ -395,6 +393,7 @@ void Compiler::unwindPushMaskFloat(regMaskTP maskFloat)
#if defined(_TARGET_UNIX_)
if (generateCFIUnwindCodes())
{
+ unwindPushPopMaskCFI(maskFloat, true);
return;
}
#endif // _TARGET_UNIX_
@@ -407,7 +406,6 @@ void Compiler::unwindPopMaskInt(regMaskTP maskInt)
#if defined(_TARGET_UNIX_)
if (generateCFIUnwindCodes())
{
- unwindPushPopMaskCFI(maskInt, false);
return;
}
#endif // _TARGET_UNIX_
@@ -436,7 +434,6 @@ void Compiler::unwindPopMaskFloat(regMaskTP maskFloat)
#if defined(_TARGET_UNIX_)
if (generateCFIUnwindCodes())
{
- unwindPushPopMaskCFI(maskFloat, true);
return;
}
#endif // _TARGET_UNIX_
@@ -451,7 +448,7 @@ void Compiler::unwindAllocStack(unsigned size)
#if defined(_TARGET_UNIX_)
if (generateCFIUnwindCodes())
{
- if (compGeneratingEpilog)
+ if (compGeneratingProlog)
{
unwindAllocStackCFI(size);
}
@@ -505,7 +502,7 @@ void Compiler::unwindSetFrameReg(regNumber reg, unsigned offset)
#if defined(_TARGET_UNIX_)
if (generateCFIUnwindCodes())
{
- if (compGeneratingEpilog)
+ if (compGeneratingProlog)
{
unwindSetFrameRegCFI(reg, offset);
}