diff options
author | Jonghyun Park <parjong@gmail.com> | 2017-04-13 07:09:33 +0900 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2017-04-13 00:09:33 +0200 |
commit | 03d0d244bca38053d54eef6f4b6db51ae87f7700 (patch) | |
tree | 3f7062cd229b5b76d33b277885b25eb19b3f3b4f /src/vm | |
parent | cebfa42d658e9ab39f189aeb01baeb266ed1190a (diff) | |
download | coreclr-03d0d244bca38053d54eef6f4b6db51ae87f7700.tar.gz coreclr-03d0d244bca38053d54eef6f4b6db51ae87f7700.tar.bz2 coreclr-03d0d244bca38053d54eef6f4b6db51ae87f7700.zip |
[x86/Linux] Fix ResumeEsp before resume (#10749)
* [x86/Linux] Correctly unwind FCALL frames
* Fix Up ResumeEsp inside ProcessCLRException
* Fix Context Before PC Update
Diffstat (limited to 'src/vm')
-rw-r--r-- | src/vm/eetwain.cpp | 48 | ||||
-rw-r--r-- | src/vm/exceptionhandling.cpp | 21 |
2 files changed, 69 insertions, 0 deletions
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<PTR_CBYTE>(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 diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp index 7e82cce604..31b85bdb0a 100644 --- a/src/vm/exceptionhandling.cpp +++ b/src/vm/exceptionhandling.cpp @@ -123,6 +123,24 @@ bool FixNonvolatileRegisters(UINT_PTR uOriginalSP, bool fAborting ); +void FixContext(PCONTEXT pContextRecord) +{ +#define FIXUPREG(reg, value) \ + do { \ + STRESS_LOG2(LF_GCROOTS, LL_INFO100, "Updating " #reg " %p to %p\n", \ + pContextRecord->reg, \ + (value)); \ + pContextRecord->reg = (value); \ + } while (0) + +#ifdef _TARGET_X86_ + size_t resumeSp = EECodeManager::GetResumeSp(pContextRecord); + FIXUPREG(ResumeEsp, resumeSp); +#endif // _TARGET_X86_ + +#undef FIXUPREG +} + MethodDesc * GetUserMethodForILStub(Thread * pThread, UINT_PTR uStubSP, MethodDesc * pILStubMD, Frame ** ppFrameOut); #ifdef FEATURE_PAL @@ -441,6 +459,7 @@ void ExceptionTracker::UpdateNonvolatileRegisters(CONTEXT *pContextRecord, REGDI } \ } while (0) + #if defined(_TARGET_X86_) UPDATEREG(Ebx); @@ -1181,6 +1200,8 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord pThread->SetFrame(pLimitFrame); + FixContext(pContextRecord); + SetIP(pContextRecord, (PCODE)uResumePC); } |