diff options
author | Igor Kulaychuk <igor.kulaychuk@gmail.com> | 2018-03-26 20:58:16 +0300 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2018-03-26 19:58:16 +0200 |
commit | 3ab87c22c28378f89d9b31d1f8ff1d2ecfae8291 (patch) | |
tree | e16705b7b2c20c97d16dfc14b2f25f48f2d212c9 /src/vm | |
parent | 67deb5a2e8c2a985f7d0c7554384355fc120a489 (diff) | |
download | coreclr-3ab87c22c28378f89d9b31d1f8ff1d2ecfae8291.tar.gz coreclr-3ab87c22c28378f89d9b31d1f8ff1d2ecfae8291.tar.bz2 coreclr-3ab87c22c28378f89d9b31d1f8ff1d2ecfae8291.zip |
Fix funclet unwinding on x86 Linux (#17144)
Diffstat (limited to 'src/vm')
-rw-r--r-- | src/vm/eetwain.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp index ed76facde3..fcaa010895 100644 --- a/src/vm/eetwain.cpp +++ b/src/vm/eetwain.cpp @@ -3851,8 +3851,27 @@ bool UnwindEbpDoubleAlignFrame( baseSP = curESP; // Set baseSP as initial SP baseSP += GetPushedArgSize(info, table, curOffs); + // 16-byte stack alignment padding (allocated in genFuncletProlog) - baseSP += 12; + // Current funclet frame layout (see CodeGen::genFuncletProlog() and genFuncletEpilog()): + // prolog: sub esp, 12 + // epilog: add esp, 12 + // ret + // SP alignment padding should be added for all instructions except the first one and the last one. + TADDR funcletStart = pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo); + + const ULONG32 funcletLastInstSize = 1; // 0xc3, ret + BOOL atFuncletLastInst = (pCodeInfo->GetRelOffset() + funcletLastInstSize) >= info->methodSize; + if (!atFuncletLastInst) + { + EECodeInfo nextCodeInfo; + nextCodeInfo.Init(pCodeInfo->GetCodeAddress() + funcletLastInstSize); + atFuncletLastInst = !nextCodeInfo.IsValid() || !nextCodeInfo.IsFunclet() || + nextCodeInfo.GetJitManager()->GetFuncletStartAddress(&nextCodeInfo) != funcletStart; + } + + if (!atFuncletLastInst && funcletStart != pCodeInfo->GetCodeAddress()) + baseSP += 12; pContext->PCTAddr = baseSP; pContext->ControlPC = *PTR_PCODE(pContext->PCTAddr); |