From 5a4d6041ce9c1dc2569265023891b1e1ab0b89d7 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 19 Apr 2021 20:59:20 +0200 Subject: [PATCH] Fix contract violation when reporting tailcall stub loader (#51485) Fix #51476 --- src/coreclr/vm/gcenv.ee.cpp | 2 +- src/coreclr/vm/method.cpp | 44 +++++++++++++++++++++++-------------- src/coreclr/vm/method.hpp | 1 + 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/coreclr/vm/gcenv.ee.cpp b/src/coreclr/vm/gcenv.ee.cpp index ea327cc73d800..9efb8648a92b9 100644 --- a/src/coreclr/vm/gcenv.ee.cpp +++ b/src/coreclr/vm/gcenv.ee.cpp @@ -165,7 +165,7 @@ static void ScanTailCallArgBufferRoots(Thread* pThread, promote_func* fn, ScanCo const PortableTailCallFrame* frame = tls->GetFrame(); if (frame->NextCall != NULL) { - MethodDesc* pMD = Entry2MethodDesc((PCODE)frame->NextCall, NULL); + MethodDesc* pMD = NonVirtualEntry2MethodDesc((PCODE)frame->NextCall); if (pMD != NULL) GcReportLoaderAllocator(fn, sc, pMD->GetLoaderAllocator()); } diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 6b07924ba0f5f..ddbb47779c252 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -2229,6 +2229,31 @@ PCODE MethodDesc::GetCallTarget(OBJECTREF* pThisObj, TypeHandle ownerType) return pTarget; } +MethodDesc* NonVirtualEntry2MethodDesc(PCODE entryPoint) +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } + CONTRACTL_END + + RangeSection* pRS = ExecutionManager::FindCodeRange(entryPoint, ExecutionManager::GetScanFlags()); + if (pRS == NULL) + return NULL; + + MethodDesc* pMD; + if (pRS->pjit->JitCodeToMethodInfo(pRS, entryPoint, &pMD, NULL)) + return pMD; + + if (pRS->pjit->GetStubCodeBlockKind(pRS, entryPoint) == STUB_CODE_BLOCK_PRECODE) + return MethodDesc::GetMethodDescFromStubAddr(entryPoint); + + // We should never get here + _ASSERTE(!"NonVirtualEntry2MethodDesc failed for RangeSection"); + return NULL; +} + //******************************************************************************* // convert an entry point into a method desc MethodDesc* Entry2MethodDesc(PCODE entryPoint, MethodTable *pMT) @@ -2242,27 +2267,14 @@ MethodDesc* Entry2MethodDesc(PCODE entryPoint, MethodTable *pMT) } CONTRACT_END - MethodDesc * pMD; - - RangeSection * pRS = ExecutionManager::FindCodeRange(entryPoint, ExecutionManager::GetScanFlags()); - if (pRS != NULL) - { - if (pRS->pjit->JitCodeToMethodInfo(pRS, entryPoint, &pMD, NULL)) - RETURN(pMD); - - if (pRS->pjit->GetStubCodeBlockKind(pRS, entryPoint) == STUB_CODE_BLOCK_PRECODE) - RETURN(MethodDesc::GetMethodDescFromStubAddr(entryPoint)); - - // We should never get here - _ASSERTE(!"Entry2MethodDesc failed for RangeSection"); - RETURN (NULL); - } + MethodDesc* pMD = NonVirtualEntry2MethodDesc(entryPoint); + if (pMD != NULL) + RETURN(pMD); pMD = VirtualCallStubManagerManager::Entry2MethodDesc(entryPoint, pMT); if (pMD != NULL) RETURN(pMD); - // Is it an FCALL? pMD = ECall::MapTargetBackToMethod(entryPoint); if (pMD != NULL) diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 5bdea982a7591..60ca2e4b9fb49 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -2579,6 +2579,7 @@ inline MethodDescChunk *MethodDesc::GetMethodDescChunk() const (sizeof(MethodDescChunk) + (GetMethodDescIndex() * MethodDesc::ALIGNMENT))); } +MethodDesc* NonVirtualEntry2MethodDesc(PCODE entryPoint); // convert an entry point into a MethodDesc MethodDesc* Entry2MethodDesc(PCODE entryPoint, MethodTable *pMT);