From 77f2ad4c07b24fcfe1298dd7cd260876ef46e6c3 Mon Sep 17 00:00:00 2001 From: Hanjoung Lee Date: Fri, 24 Feb 2017 16:02:21 +0900 Subject: [x86/Linux] Initial patch for EH funclet (#9601) - Generate a simple EH funclet frame and support SP-based stack unwinding for funclets. - Introduce assembly helpers : CallEHFunclet and CallEHFilterFunclet --- src/vm/eetwain.cpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'src/vm/eetwain.cpp') diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp index bf6e1c7aa5..989300d468 100644 --- a/src/vm/eetwain.cpp +++ b/src/vm/eetwain.cpp @@ -3786,10 +3786,11 @@ void UnwindEbpDoubleAlignFrameProlog( /*****************************************************************************/ bool UnwindEbpDoubleAlignFrame( - PREGDISPLAY pContext, - hdrInfo * info, - PTR_CBYTE methodStart, - unsigned flags, + PREGDISPLAY pContext, + EECodeInfo *pCodeInfo, + hdrInfo *info, + PTR_CBYTE methodStart, + unsigned flags, StackwalkCacheUnwindInfo *pUnwindInfo) // out-only, perf improvement { LIMITED_METHOD_CONTRACT; @@ -3806,6 +3807,25 @@ bool UnwindEbpDoubleAlignFrame( { TADDR baseSP; +#ifdef WIN64EXCEPTIONS + // Funclets' frame pointers(EBP) are always restored so they can access to main function's local variables. + // Therefore the value of EBP is invalid for unwinder so we should use ESP instead. + // TODO If funclet frame layout is changed from CodeGen::genFuncletProlog() and genFuncletEpilog(), + // we need to change here accordingly. It is likely to have changes when introducing PSPSym. + // TODO Currently we assume that ESP of funclet frames is always fixed but actually it could change. + if (pCodeInfo->IsFunclet()) + { + baseSP = curESP + 12; // padding for 16byte stack alignment allocated in genFuncletProlog() + + pContext->PCTAddr = baseSP; + pContext->ControlPC = *PTR_PCODE(pContext->PCTAddr); + + pContext->SP = (DWORD)(baseSP + sizeof(TADDR)); + + return true; + } +#else // WIN64EXCEPTIONS + FrameType frameType = GetHandlerFrameInfo(info, curEBP, curESP, (DWORD) IGNORE_VAL, &baseSP); @@ -3860,6 +3880,7 @@ bool UnwindEbpDoubleAlignFrame( return true; } +#endif // !WIN64EXCEPTIONS } // @@ -3990,7 +4011,7 @@ bool UnwindStackFrame(PREGDISPLAY pContext, * Now we know that have an EBP frame */ - if (!UnwindEbpDoubleAlignFrame(pContext, info, methodStart, flags, pUnwindInfo)) + if (!UnwindEbpDoubleAlignFrame(pContext, pCodeInfo, info, methodStart, flags, pUnwindInfo)) return false; } -- cgit v1.2.3