summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vm/excep.cpp50
-rw-r--r--src/vm/excep.h4
-rw-r--r--src/vm/threadsuspend.cpp3
3 files changed, 41 insertions, 16 deletions
diff --git a/src/vm/excep.cpp b/src/vm/excep.cpp
index e5c024e89c..860e5171a5 100644
--- a/src/vm/excep.cpp
+++ b/src/vm/excep.cpp
@@ -7870,7 +7870,7 @@ BOOL IsIPInEE(void *ip)
}
}
-#if defined(_TARGET_AMD64_) && defined(FEATURE_HIJACK)
+#if defined(FEATURE_HIJACK) && (!defined(_TARGET_X86_) || defined(FEATURE_PAL))
// This function is used to check if the specified IP is in the prolog or not.
bool IsIPInProlog(EECodeInfo *pCodeInfo)
@@ -7887,6 +7887,9 @@ bool IsIPInProlog(EECodeInfo *pCodeInfo)
_ASSERTE(pCodeInfo->IsValid());
+#ifdef _TARGET_AMD64_
+
+ // Optimized version for AMD64 that doesn't need to go through the GC info decoding
PTR_RUNTIME_FUNCTION funcEntry = pCodeInfo->GetFunctionEntry();
// We should always get a function entry for a managed method
@@ -7896,8 +7899,31 @@ bool IsIPInProlog(EECodeInfo *pCodeInfo)
PUNWIND_INFO pUnwindInfo = (PUNWIND_INFO)(pCodeInfo->GetModuleBase() + funcEntry->UnwindData);
// Check if the specified IP is beyond the prolog or not.
- DWORD dwPrologLen = pUnwindInfo->SizeOfProlog;
- if (pCodeInfo->GetRelOffset() >= dwPrologLen)
+ DWORD prologLen = pUnwindInfo->SizeOfProlog;
+
+#else // _TARGET_AMD64_
+
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+
+#ifdef USE_GC_INFO_DECODER
+
+ GcInfoDecoder gcInfoDecoder(
+ gcInfoToken,
+ DECODE_PROLOG_LENGTH
+ );
+
+ DWORD prologLen = gcInfoDecoder.GetPrologSize();
+
+#else // USE_GC_INFO_DECODER
+
+ size_t prologLen;
+ pCodeInfo->GetCodeManager()->IsInPrologOrEpilog(0, gcInfoToken, &prologLen);
+
+#endif // USE_GC_INFO_DECODER
+
+#endif // _TARGET_AMD64_
+
+ if (pCodeInfo->GetRelOffset() >= prologLen)
{
fInsideProlog = false;
}
@@ -7920,11 +7946,11 @@ bool IsIPInEpilog(PTR_CONTEXT pContextToCheck, EECodeInfo *pCodeInfo, BOOL *pSaf
CONTRACTL_END;
TADDR ipToCheck = GetIP(pContextToCheck);
-
+
_ASSERTE(pCodeInfo->IsValid());
-
+
// The Codeinfo should correspond to the IP we are interested in.
- _ASSERTE(ipToCheck == pCodeInfo->GetCodeAddress());
+ _ASSERTE(PCODEToPINSTR(ipToCheck) == pCodeInfo->GetCodeAddress());
// By default, assume its safe to inject the abort.
*pSafeToInjectThreadAbort = TRUE;
@@ -7951,11 +7977,10 @@ bool IsIPInEpilog(PTR_CONTEXT pContextToCheck, EECodeInfo *pCodeInfo, BOOL *pSaf
// RtlVirtualUnwind against "ipToCheck" results in a NULL personality routine, it implies that we are inside
// the epilog.
- DWORD64 imageBase = 0;
- PUNWIND_INFO pUnwindInfo = NULL;
+ DWORD_PTR imageBase = 0;
CONTEXT tempContext;
PVOID HandlerData;
- DWORD64 establisherFrame = 0;
+ DWORD_PTR establisherFrame = 0;
PEXCEPTION_ROUTINE personalityRoutine = NULL;
// Lookup the function entry for the IP
@@ -7965,7 +7990,6 @@ bool IsIPInEpilog(PTR_CONTEXT pContextToCheck, EECodeInfo *pCodeInfo, BOOL *pSaf
_ASSERTE(funcEntry != NULL);
imageBase = pCodeInfo->GetModuleBase();
- pUnwindInfo = (PUNWIND_INFO)(imageBase+ funcEntry->UnwindData);
ZeroMemory(&tempContext, sizeof(CONTEXT));
CopyOSContext(&tempContext, pContextToCheck);
@@ -7988,13 +8012,15 @@ bool IsIPInEpilog(PTR_CONTEXT pContextToCheck, EECodeInfo *pCodeInfo, BOOL *pSaf
// We are in epilog.
fIsInEpilog = true;
+#ifdef _TARGET_AMD64_
// Check if context pointers has returned the address of the stack location in the hijacked function
// from where RBP was restored. If the address is NULL, then it implies that RBP has been popped off.
// Since JIT64 ensures that pop of RBP is the last instruction before ret/jmp, it implies its not safe
// to inject an abort @ this point as EstablisherFrame (which will be based
// of RBP for managed code since that is the FramePointer register, as indicated in the UnwindInfo)
// will be off and can result in bad managed exception dispatch.
- if (ctxPtrs.Rbp == NULL)
+ if (ctxPtrs.Rbp == NULL)
+#endif
{
*pSafeToInjectThreadAbort = FALSE;
}
@@ -8003,7 +8029,7 @@ bool IsIPInEpilog(PTR_CONTEXT pContextToCheck, EECodeInfo *pCodeInfo, BOOL *pSaf
return fIsInEpilog;
}
-#endif // defined(_TARGET_AMD64_) && defined(FEATURE_HIJACK)
+#endif // FEATURE_HIJACK && (!_TARGET_X86_ || FEATURE_PAL)
#define EXCEPTION_VISUALCPP_DEBUGGER ((DWORD) (1<<30 | 0x6D<<16 | 5000))
diff --git a/src/vm/excep.h b/src/vm/excep.h
index 6df9a98452..c2984b5720 100644
--- a/src/vm/excep.h
+++ b/src/vm/excep.h
@@ -25,13 +25,13 @@ class Thread;
BOOL IsExceptionFromManagedCode(const EXCEPTION_RECORD * pExceptionRecord);
bool IsIPInMarkedJitHelper(UINT_PTR uControlPc);
-#if defined(_TARGET_AMD64_) && defined(FEATURE_HIJACK)
+#if defined(FEATURE_HIJACK) && (!defined(_TARGET_X86_) || defined(FEATURE_PAL))
// General purpose functions for use on an IP in jitted code.
bool IsIPInProlog(EECodeInfo *pCodeInfo);
bool IsIPInEpilog(PTR_CONTEXT pContextToCheck, EECodeInfo *pCodeInfo, BOOL *pSafeToInjectThreadAbort);
-#endif // defined(_TARGET_AMD64_) && defined(FEATURE_HIJACK)
+#endif // FEATURE_HIJACK && (!_TARGET_X86_ || FEATURE_PAL)
void RaiseFailFastExceptionOnWin7(PEXCEPTION_RECORD pExceptionRecord, PT_CONTEXT pContext);
diff --git a/src/vm/threadsuspend.cpp b/src/vm/threadsuspend.cpp
index 12fbc901a9..0f3ff6bec9 100644
--- a/src/vm/threadsuspend.cpp
+++ b/src/vm/threadsuspend.cpp
@@ -7467,10 +7467,9 @@ void HandleGCSuspensionForInterruptedThread(CONTEXT *interruptedContext)
pThread->InitRegDisplay(&regDisplay, interruptedContext, true /* validContext */);
BOOL unused;
-#if defined(_TARGET_AMD64_)
+
if (IsIPInEpilog(interruptedContext, &codeInfo, &unused))
return;
-#endif
// Use StackWalkFramesEx to find the location of the return address. This will locate the
// return address by checking relative to the caller frame's SP, which is preferable to