From 822e96824b59b7f15ba05ddcfa818496cf8c378b Mon Sep 17 00:00:00 2001 From: Jonghyun Park Date: Wed, 19 Apr 2017 03:27:29 +0900 Subject: [PATCH] [x86/Linux] EH Support for Per-Frame P/Invoke Init (dotnet/coreclr#10966) Commit migrated from https://github.com/dotnet/coreclr/commit/98a41f0a8711e0d0f3cb0d56adc6f8d0c36c11d2 --- src/coreclr/src/vm/exceptionhandling.cpp | 32 +++++++++++++++++++++----------- src/coreclr/src/vm/exceptionhandling.h | 11 ++++++++++- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/coreclr/src/vm/exceptionhandling.cpp b/src/coreclr/src/vm/exceptionhandling.cpp index 31b85bd..ee0ff29 100644 --- a/src/coreclr/src/vm/exceptionhandling.cpp +++ b/src/coreclr/src/vm/exceptionhandling.cpp @@ -1071,9 +1071,11 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord CLRUnwindStatus status; +#ifdef USE_PER_FRAME_PINVOKE_INIT // Refer to comment in ProcessOSExceptionNotification about ICF and codegen difference. - ARM_ONLY(InlinedCallFrame *pICFSetAsLimitFrame = NULL;) - + InlinedCallFrame *pICFSetAsLimitFrame = NULL; +#endif // USE_PER_FRAME_PINVOKE_INIT + status = pTracker->ProcessOSExceptionNotification( pExceptionRecord, pContextRecord, @@ -1081,7 +1083,11 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord dwExceptionFlags, sf, pThread, - STState ARM_ARG((PVOID)pICFSetAsLimitFrame)); + STState +#ifdef USE_PER_FRAME_PINVOKE_INIT + , (PVOID)pICFSetAsLimitFrame +#endif // USE_PER_FRAME_PINVOKE_INIT + ); if (FirstPassComplete == status) { @@ -1184,7 +1190,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord CONSISTENCY_CHECK(pLimitFrame > dac_cast(GetSP(pContextRecord))); -#if defined(_TARGET_ARM_) +#ifdef USE_PER_FRAME_PINVOKE_INIT if (pICFSetAsLimitFrame != NULL) { _ASSERTE(pICFSetAsLimitFrame == pLimitFrame); @@ -1196,7 +1202,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord // the next pinvoke callsite does not see the frame as active. pICFSetAsLimitFrame->Reset(); } -#endif // defined(_TARGET_ARM_) +#endif // USE_PER_FRAME_PINVOKE_INIT pThread->SetFrame(pLimitFrame); @@ -1653,7 +1659,11 @@ CLRUnwindStatus ExceptionTracker::ProcessOSExceptionNotification( DWORD dwExceptionFlags, StackFrame sf, Thread* pThread, - StackTraceState STState ARM_ARG(PVOID pICFSetAsLimitFrame)) + StackTraceState STState +#ifdef USE_PER_FRAME_PINVOKE_INIT + , PVOID pICFSetAsLimitFrame +#endif // USE_PER_FRAME_PINVOKE_INIT +) { CONTRACTL { @@ -1719,10 +1729,10 @@ CLRUnwindStatus ExceptionTracker::ProcessOSExceptionNotification( this->m_EnclosingClauseInfoForGCReporting.SetEnclosingClauseCallerSP(uCallerSP); } -#if defined(_TARGET_ARM_) +#ifdef USE_PER_FRAME_PINVOKE_INIT // Refer to detailed comment below. PTR_Frame pICFForUnwindTarget = NULL; -#endif // defined(_TARGET_ARM_) +#endif // USE_PER_FRAME_PINVOKE_INIT CheckForRudeAbort(pThread, fIsFirstPass); @@ -1751,7 +1761,7 @@ CLRUnwindStatus ExceptionTracker::ProcessOSExceptionNotification( while (((UINT_PTR)pFrame) < uCallerSP) { -#if defined(_TARGET_ARM_) +#ifdef USE_PER_FRAME_PINVOKE_INIT // InlinedCallFrames (ICF) are allocated, initialized and linked to the Frame chain // by the code generated by the JIT for a method containing a PInvoke. // @@ -1956,7 +1966,7 @@ lExit: if (fTargetUnwind && (status == SecondPassComplete)) { -#if defined(_TARGET_ARM_) +#ifdef USE_PER_FRAME_PINVOKE_INIT // If we have got a ICF to set as the LimitFrame, do that now. // The Frame chain is still intact and would be updated using // the LimitFrame (done after the catch handler returns). @@ -1968,7 +1978,7 @@ lExit: m_pLimitFrame = pICFForUnwindTarget; pICFSetAsLimitFrame = (PVOID)pICFForUnwindTarget; } -#endif // _TARGET_ARM_ +#endif // USE_PER_FRAME_PINVOKE_INIT // Since second pass is complete and we have reached // the frame containing the catch funclet, reset the enclosing diff --git a/src/coreclr/src/vm/exceptionhandling.h b/src/coreclr/src/vm/exceptionhandling.h index 97f1526..6d1f2b4 100644 --- a/src/coreclr/src/vm/exceptionhandling.h +++ b/src/coreclr/src/vm/exceptionhandling.h @@ -10,6 +10,11 @@ #ifdef WIN64EXCEPTIONS +#if defined(_TARGET_ARM_) || defined(_TARGET_X86_) +#define USE_PER_FRAME_PINVOKE_INIT +#endif // _TARGET_ARM_ || _TARGET_X86_ + + // This address lies in the NULL pointer partition of the process memory. // Accessing it will result in AV. #define INVALID_RESUME_ADDRESS 0x000000000000bad0 @@ -203,7 +208,11 @@ public: DWORD dwExceptionFlags, StackFrame sf, Thread* pThread, - StackTraceState STState ARM_ARG(PVOID pICFSetAsLimitFrame)); + StackTraceState STState +#ifdef USE_PER_FRAME_PINVOKE_INIT + , PVOID pICFSetAsLimitFrame +#endif // USE_PER_FRAME_PINVOKE_INIT + ); CLRUnwindStatus ProcessExplicitFrame( CrawlFrame* pcfThisFrame, -- 2.7.4