summaryrefslogtreecommitdiff
path: root/src/vm/exceptionhandling.cpp
diff options
context:
space:
mode:
authorJonghyun Park <parjong@gmail.com>2017-03-01 18:13:40 +0900
committerJan Vorlicek <janvorli@microsoft.com>2017-03-01 10:13:40 +0100
commit6ed351c93499dfef402085727d574410ca79b561 (patch)
tree2aaad85af26f32cbd8b5f31e9e0d6df5e0666601 /src/vm/exceptionhandling.cpp
parentf6359b37c6f9db872f2c191ad7264637ea14f414 (diff)
downloadcoreclr-6ed351c93499dfef402085727d574410ca79b561.tar.gz
coreclr-6ed351c93499dfef402085727d574410ca79b561.tar.bz2
coreclr-6ed351c93499dfef402085727d574410ca79b561.zip
[x86/Linux] Use ESTABLISHER_FRAME_POINTER_IS_CALLER_SP (#9814)
* [x86/Linux] Introduce ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
Diffstat (limited to 'src/vm/exceptionhandling.cpp')
-rw-r--r--src/vm/exceptionhandling.cpp52
1 files changed, 25 insertions, 27 deletions
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index 706ec675bc..bb30ee4bbb 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -22,6 +22,11 @@
#define STACK_RANGE_BOUNDS_ARE_CALLER_SP
#define USE_FUNCLET_CALL_HELPER
#define USE_CALLER_SP_IN_FUNCLET
+// For ARM/ARM64, EstablisherFrame is Caller-SP (SP just before executing call instruction).
+// This has been confirmed by AaronGi from the kernel team for Windows.
+//
+// For x86/Linux, RtlVirtualUnwind sets EstablisherFrame as Caller-SP.
+#define ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
#endif // _TARGET_ARM_ || _TARGET_ARM64_ || _TARGET_X86_
#ifndef DACCESS_COMPILE
@@ -1292,12 +1297,12 @@ void ExceptionTracker::InitializeCurrentContextForCrawlFrame(CrawlFrame* pcfThis
pRD->SP = sfEstablisherFrame.SP;
pRD->ControlPC = pDispatcherContext->ControlPc;
-#ifdef USE_CALLER_SP_IN_FUNCLET
+#ifdef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
pcfThisFrame->pRD->IsCallerSPValid = TRUE;
// Assert our first pass assumptions for the Arm/Arm64
_ASSERTE(sfEstablisherFrame.SP == GetSP(pDispatcherContext->ContextRecord));
-#endif // USE_CALLER_SP_IN_FUNCLET
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
}
@@ -1391,19 +1396,23 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
{
pCurrentTracker->InitializeCurrentContextForCrawlFrame(pcfThisFrame, pDispatcherContext, sf);
}
-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
else
{
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
// See the comment above the call to InitRegDisplay for this assertion.
_ASSERTE(pDispatcherContext->ControlPc == GetIP(pDispatcherContext->ContextRecord));
+#endif // _TARGET_ARM_ || _TARGET_ARM64_
+#ifdef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
// Simply setup the callerSP during the second pass in the caller context.
// This is used in setting up the "EnclosingClauseCallerSP" in ExceptionTracker::ProcessManagedCallFrame
// when the termination handlers are invoked.
::SetSP(pcfThisFrame->pRD->pCallerContext, sf.SP);
pcfThisFrame->pRD->IsCallerSPValid = TRUE;
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
}
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
// Further below, we will adjust the ControlPC based upon whether we are at a callsite or not.
// We need to do this for "RegDisplay.ControlPC" field as well so that when data structures like
// EECodeInfo initialize themselves using this field, they will have the correct absolute value
@@ -1609,17 +1618,11 @@ CLRUnwindStatus ExceptionTracker::ProcessOSExceptionNotification(
ExceptionTracker::InitializeCrawlFrame(&cfThisFrame, pThread, sf, &regdisp, pDispatcherContext, ControlPc, &uMethodStartPC, this);
-#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
+#ifndef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
uCallerSP = EECodeManager::GetCallerSp(cfThisFrame.pRD);
-#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
- // On ARM & ARM64, the EstablisherFrame is the value of SP at the time a function was called and before it's prolog
- // executed. Effectively, it is the SP of the caller. This has been confirmed by AaronGi from the kernel
- // team.
+#else // !ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
uCallerSP = sf.SP;
-#else
- PORTABILITY_ASSERT("ExceptionTracker::ProcessOSExceptionNotification");
- uCallerSP = NULL;
-#endif // _TARGET_AMD64_
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
EH_LOG((LL_INFO100, "ProcessCrawlFrame: PSP: " FMT_ADDR " EstablisherFrame: " FMT_ADDR "\n", DBG_ADDR(uCallerSP), DBG_ADDR(sf.SP)));
@@ -1920,19 +1923,16 @@ lExit:
// in ExceptionTracker::ProcessManagedCallFrame.
if (m_fResetEnclosingClauseSPForCatchFunclet)
{
-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#ifdef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
// DispatcherContext->EstablisherFrame's value
// represents the CallerSP of the current frame.
UINT_PTR EnclosingClauseCallerSP = (UINT_PTR)pDispatcherContext->EstablisherFrame;
-#elif defined(_TARGET_AMD64_)
- // Extract the CallerSP from RegDisplay on AMD64
+#else // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
+ // Extract the CallerSP from RegDisplay
REGDISPLAY *pRD = cfThisFrame.GetRegisterSet();
_ASSERTE(pRD->IsCallerContextValid || pRD->IsCallerSPValid);
UINT_PTR EnclosingClauseCallerSP = (UINT_PTR)GetSP(pRD->pCallerContext);
-#else // !_ARM_ && !_AMD64_ && !_ARM64_
- PORTABILITY_ASSERT("ExceptionTracker::ProcessOSExceptionNotification");
- UINT_PTR EnclosingClauseCallerSP = NULL;
-#endif // defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#endif // !ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
m_EnclosingClauseInfo = EnclosingClauseInfo(false, cfThisFrame.GetRelOffset(), EnclosingClauseCallerSP);
}
m_fResetEnclosingClauseSPForCatchFunclet = FALSE;
@@ -2827,13 +2827,13 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
// executes.
m_dwIndexClauseForCatch = i + 1;
m_sfEstablisherOfActualHandlerFrame = sfEstablisherFrame;
-#ifdef _TARGET_AMD64_
+#ifndef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
m_sfCallerOfActualHandlerFrame = EECodeManager::GetCallerSp(pcfThisFrame->pRD);
-#else
+#else // !ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
// On ARM & ARM64, the EstablisherFrame is the value of SP at the time a function was called and before it's prolog
// executed. Effectively, it is the SP of the caller.
m_sfCallerOfActualHandlerFrame = sfEstablisherFrame.SP;
-#endif
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
ReturnStatus = FirstPassComplete;
}
@@ -3095,13 +3095,11 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
m_dwIndexClauseForCatch = i + 1;
m_sfEstablisherOfActualHandlerFrame = sfEstablisherFrame;
-#ifdef _TARGET_AMD64_
+#ifndef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
m_sfCallerOfActualHandlerFrame = EECodeManager::GetCallerSp(pcfThisFrame->pRD);
-#else
- // On ARM & ARM64, the EstablisherFrame is the value of SP at the time a function was called and before it's prolog
- // executed. Effectively, it is the SP of the caller.
+#else // !ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
m_sfCallerOfActualHandlerFrame = sfEstablisherFrame.SP;
-#endif
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
//
// END resume frame code
//