From 33987e98a992e8843b109c90b22c16c85469051c Mon Sep 17 00:00:00 2001 From: Andrey Kvochko Date: Tue, 18 Dec 2018 08:28:32 +0300 Subject: [PATCH] Generate ARM CFIs in prolog (#21505) --- src/jit/compiler.h | 4 ---- src/jit/unwind.cpp | 65 ++++++++++++++------------------------------------- src/jit/unwindarm.cpp | 21 +++++++---------- 3 files changed, 27 insertions(+), 63 deletions(-) diff --git a/src/jit/compiler.h b/src/jit/compiler.h index 7b91d39..8a8a328 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 f27a847..0729648 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 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 cfd7290..4a2b838 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); } -- 2.7.4