Reflects PR feedback.
virtual size_t GetFunctionSize(GCInfoToken gcInfoToken) = 0;
/*
-Returns the ReturnKind of a given function as reported in the GC info.
+* Get information necessary for return address hijacking of the method represented by the gcInfoToken.
+* If it can be hijacked, it sets the returnKind output parameter to the kind of the return value and
+* returns true.
+* If hijacking is not possible for some reason, it return false.
*/
-
-virtual ReturnKind GetReturnKind(GCInfoToken gcInfotoken) = 0;
+virtual bool GetReturnAddressHijackInfo(GCInfoToken gcInfoToken, ReturnKind * returnKind) = 0;
#ifndef USE_GC_INFO_DECODER
/*
size_t GetFunctionSize(GCInfoToken gcInfoToken);
/*
-Returns the ReturnKind of a given function.
+* Get information necessary for return address hijacking of the method represented by the gcInfoToken.
+* If it can be hijacked, it sets the returnKind output parameter to the kind of the return value and
+* returns true.
+* If hijacking is not possible for some reason, it return false.
*/
-virtual ReturnKind GetReturnKind(GCInfoToken gcInfotoken);
+virtual bool GetReturnAddressHijackInfo(GCInfoToken gcInfoToken, ReturnKind * returnKind);
#ifndef USE_GC_INFO_DECODER
/*
/*****************************************************************************
*
-* Returns the size of a given function.
+* Get information necessary for return address hijacking of the method represented by the gcInfoToken.
+* If it can be hijacked, it sets the returnKind output parameter to the kind of the return value and
+* returns true.
+* If hijacking is not possible for some reason, it return false.
*/
-ReturnKind EECodeManager::GetReturnKind(GCInfoToken gcInfoToken)
+bool EECodeManager::GetReturnAddressHijackInfo(GCInfoToken gcInfoToken, ReturnKind * returnKind)
{
CONTRACTL{
NOTHROW;
DecodeGCHdrInfo(gcInfoToken, 0, &info);
- return info.returnKind;
+ *returnKind = info.returnKind;
+ return true;
#else // !USE_GC_INFO_DECODER
- GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_RETURN_KIND);
- return gcInfoDecoder.GetReturnKind();
+ GcInfoDecoder gcInfoDecoder(gcInfoToken, GcInfoDecoderFlags(DECODE_RETURN_KIND | DECODE_REVERSE_PINVOKE_VAR));
+
+ if (gcInfoDecoder.GetReversePInvokeFrameStackSlot() != NO_REVERSE_PINVOKE_FRAME)
+ {
+ // Hijacking of NativeCallable method is not allowed
+ return false;
+ }
+ *returnKind = gcInfoDecoder.GetReturnKind();
+ return true;
#endif // USE_GC_INFO_DECODER
}
#endif // HIJACK_NONINTERRUPTIBLE_THREADS
}
-ReturnKind GetReturnKind(Thread *pThread, EECodeInfo *codeInfo)
+bool GetReturnAddressHijackInfo(Thread *pThread, EECodeInfo *codeInfo, void** hijackAddress)
{
+ ReturnKind returnKind;
GCInfoToken gcInfoToken = codeInfo->GetGCInfoToken();
- ReturnKind returnKind = codeInfo->GetCodeManager()->GetReturnKind(gcInfoToken);
- _ASSERTE(IsValidReturnKind(returnKind));
- return returnKind;
-}
+ if (!codeInfo->GetCodeManager()->GetReturnAddressHijackInfo(gcInfoToken, &returnKind))
+ {
+ return false;
+ }
-VOID * GetHijackAddr(Thread *pThread, EECodeInfo *codeInfo)
-{
- ReturnKind returnKind = GetReturnKind(pThread, codeInfo);
+ _ASSERTE(IsValidReturnKind(returnKind));
pThread->SetHijackReturnKind(returnKind);
#ifdef TARGET_X86
if (returnKind == RT_Float)
{
- return reinterpret_cast<VOID *>(OnHijackFPTripThread);
+ *hijackAddress = reinterpret_cast<VOID *>(OnHijackFPTripThread);
}
#endif // TARGET_X86
- return reinterpret_cast<VOID *>(OnHijackTripThread);
+ *hijackAddress = reinterpret_cast<VOID *>(OnHijackTripThread);
+
+ return true;
}
#ifndef TARGET_UNIX
// it or not.
EECodeInfo codeInfo(ip);
- GcInfoDecoder gcInfoDecoder(codeInfo.GetGCInfoToken(), DECODE_REVERSE_PINVOKE_VAR);
+ VOID *pvHijackAddr;
- if (gcInfoDecoder.GetReversePInvokeFrameStackSlot() == NO_REVERSE_PINVOKE_FRAME)
+ if (GetReturnAddressHijackInfo(this, &codeInfo, &pvHijackAddr))
{
- VOID *pvHijackAddr = GetHijackAddr(this, &codeInfo);
#ifdef FEATURE_ENABLE_GCPOLL
// On platforms that support both hijacking and GC polling