From 03d0d244bca38053d54eef6f4b6db51ae87f7700 Mon Sep 17 00:00:00 2001 From: Jonghyun Park Date: Thu, 13 Apr 2017 07:09:33 +0900 Subject: [x86/Linux] Fix ResumeEsp before resume (#10749) * [x86/Linux] Correctly unwind FCALL frames * Fix Up ResumeEsp inside ProcessCLRException * Fix Context Before PC Update --- src/vm/eetwain.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/vm/eetwain.cpp') diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp index 2c9059bca1..2886daa8f6 100644 --- a/src/vm/eetwain.cpp +++ b/src/vm/eetwain.cpp @@ -4048,6 +4048,54 @@ bool UnwindStackFrame(PREGDISPLAY pContext, #endif // _TARGET_X86_ +#ifdef WIN64EXCEPTIONS +#ifdef _TARGET_X86_ +size_t EECodeManager::GetResumeSp( PCONTEXT pContext ) +{ + PCODE currentPc = PCODE(pContext->Eip); + + _ASSERTE(ExecutionManager::IsManagedCode(currentPc)); + + EECodeInfo codeInfo(currentPc); + + PTR_CBYTE methodStart = PTR_CBYTE(codeInfo.GetSavedMethodCode()); + + GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken(); + PTR_VOID methodInfoPtr = gcInfoToken.Info; + DWORD curOffs = codeInfo.GetRelOffset(); + + CodeManStateBuf stateBuf; + + stateBuf.hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, + curOffs, + &stateBuf.hdrInfoBody); + + PTR_CBYTE table = dac_cast(methodInfoPtr) + stateBuf.hdrInfoSize; + + hdrInfo *info = &stateBuf.hdrInfoBody; + + _ASSERTE(info->epilogOffs == hdrInfo::NOT_IN_EPILOG && info->prologOffs == hdrInfo::NOT_IN_PROLOG); + + bool isESPFrame = !info->ebpFrame && !info->doubleAlign; + + if (codeInfo.IsFunclet()) + { + // Treat funclet's frame as ESP frame + isESPFrame = true; + } + + if (isESPFrame) + { + const size_t curESP = (size_t)(pContext->Esp); + return curESP + GetPushedArgSize(info, table, curOffs); + } + + const size_t curEBP = (size_t)(pContext->Ebp); + return GetOutermostBaseFP(curEBP, info); +} +#endif // _TARGET_X86_ +#endif // WIN64EXCEPTIONS + #ifndef CROSSGEN_COMPILE #ifndef WIN64EXCEPTIONS -- cgit v1.2.3