From 19183a8e980b1d0811d5a392232ac6eddad84ffa Mon Sep 17 00:00:00 2001
From: Aaron R Robinson <arobins@microsoft.com>
Date: Fri, 18 Aug 2023 13:53:47 -0700
Subject: [PATCH 1/6] Events for IL methods without IL headers

Dynamically generated methods like UnsafeAccessor
functions are marked as IL, but don't contain an IL
header. The lack of header is an indication the IL must
be generated at runtime.
---
 src/coreclr/vm/eventtrace.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/coreclr/vm/eventtrace.cpp b/src/coreclr/vm/eventtrace.cpp
index b9a82cfb7c28e9..4f976238a17347 100644
--- a/src/coreclr/vm/eventtrace.cpp
+++ b/src/coreclr/vm/eventtrace.cpp
@@ -4566,9 +4566,13 @@ VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *n
                 ulMethodToken = (ULONG)0;
         }
         else
+        {
             ulMethodToken = (ULONG)pMethodDesc->GetMemberDef();
+        }
 
-        if(pMethodDesc->IsIL())
+        // An IL method that has no IL header can occur for dynamically
+        // generated code during JIT (for example, UnsafeAccessor).
+        if(pMethodDesc->IsIL() && pMethodDesc->GetILHeader() != NULL)
         {
             COR_ILMETHOD_DECODER::DecoderStatus decoderstatus = COR_ILMETHOD_DECODER::FORMAT_ERROR;
             COR_ILMETHOD_DECODER ILHeader(pMethodDesc->GetILHeader(), pMethodDesc->GetMDImport(), &decoderstatus);

From 616ae0bc7b6e6e465cf57be46a86d02437dd03fa Mon Sep 17 00:00:00 2001
From: Aaron R Robinson <arobins@microsoft.com>
Date: Fri, 18 Aug 2023 14:33:26 -0700
Subject: [PATCH 2/6] Debugger check for no IL header

---
 src/coreclr/debug/daccess/stack.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/coreclr/debug/daccess/stack.cpp b/src/coreclr/debug/daccess/stack.cpp
index 9402d529eb8ea3..8e836c852350e5 100644
--- a/src/coreclr/debug/daccess/stack.cpp
+++ b/src/coreclr/debug/daccess/stack.cpp
@@ -1253,7 +1253,10 @@ ClrDataFrame::GetLocalSig(MetaSig** sig,
     {
         // It turns out we cannot really get rid of this check.  Dynamic methods
         // (including IL stubs) do not have their local sig's available after JIT time.
-        if (!m_methodDesc->IsIL())
+        // IL Methods with dynamically generated IL (for example, UnsafeAccessors) can
+        // may have not have an IL header.
+        if (!m_methodDesc->IsIL()
+            || m_methodDesc->GetILHeader() == NULL)
         {
             *sig = NULL;
             *count = 0;

From 4586f5d2a3d789f9c3cb34346eee7bca834c3317 Mon Sep 17 00:00:00 2001
From: Aaron Robinson <arobins@microsoft.com>
Date: Fri, 18 Aug 2023 14:49:05 -0700
Subject: [PATCH 3/6] Update src/coreclr/debug/daccess/stack.cpp

Co-authored-by: Tlakaelel Axayakatl Ceja <tlakaelel.ceja@microsoft.com>
---
 src/coreclr/debug/daccess/stack.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/coreclr/debug/daccess/stack.cpp b/src/coreclr/debug/daccess/stack.cpp
index 8e836c852350e5..21dfaffbfd1e06 100644
--- a/src/coreclr/debug/daccess/stack.cpp
+++ b/src/coreclr/debug/daccess/stack.cpp
@@ -1253,8 +1253,8 @@ ClrDataFrame::GetLocalSig(MetaSig** sig,
     {
         // It turns out we cannot really get rid of this check.  Dynamic methods
         // (including IL stubs) do not have their local sig's available after JIT time.
-        // IL Methods with dynamically generated IL (for example, UnsafeAccessors) can
-        // may have not have an IL header.
+        // IL Methods with dynamically generated IL (for example, UnsafeAccessors) may
+        // not have an IL header.
         if (!m_methodDesc->IsIL()
             || m_methodDesc->GetILHeader() == NULL)
         {

From c9d9c6ac1996e2af9f98591a0636ac4c224379ab Mon Sep 17 00:00:00 2001
From: Aaron R Robinson <arobins@microsoft.com>
Date: Fri, 18 Aug 2023 15:37:49 -0700
Subject: [PATCH 4/6] Review feedback

---
 src/coreclr/inc/eventtracebase.h |   6 +-
 src/coreclr/vm/eventtrace.cpp    |  21 +++---
 src/coreclr/vm/jitinterface.cpp  |   2 +-
 src/coreclr/vm/method.hpp        |   2 +-
 src/coreclr/vm/prestub.cpp       | 116 +++++++++++++++----------------
 5 files changed, 73 insertions(+), 74 deletions(-)

diff --git a/src/coreclr/inc/eventtracebase.h b/src/coreclr/inc/eventtracebase.h
index 97c3135153038c..3648b1f3a72136 100644
--- a/src/coreclr/inc/eventtracebase.h
+++ b/src/coreclr/inc/eventtracebase.h
@@ -905,7 +905,7 @@ namespace ETW
             BOOL fSendRichDebugInfoEvent,
             BOOL fGetCodeIds);
         static VOID SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions);
-        static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
+        static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
         static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId);
         static VOID SendMethodRichDebugInfo(MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId, MethodDescSet* sentMethodDetailsSet);
         static VOID SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, PCODE pNativeCodeStartAddress = 0, PrepareCodeConfig *pConfig = NULL, MethodDescSet* sentMethodDetailsSet = NULL);
@@ -938,7 +938,7 @@ namespace ETW
 
         static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc);
         static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint);
-        static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
+        static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
         static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig);
         static VOID SendMethodDetailsEvent(MethodDesc *pMethodDesc);
         static VOID SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc, MethodDescSet* set);
@@ -952,7 +952,7 @@ namespace ETW
     public:
         static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc) {};
         static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint) {};
-        static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
+        static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
         static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig);
         static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName) {};
         static VOID StubsInitialized(PVOID *pHelperStartAddress, PVOID *pHelperNames, LONG ulNoOfHelpers) {};
diff --git a/src/coreclr/vm/eventtrace.cpp b/src/coreclr/vm/eventtrace.cpp
index 4f976238a17347..9498f00edf4329 100644
--- a/src/coreclr/vm/eventtrace.cpp
+++ b/src/coreclr/vm/eventtrace.cpp
@@ -3555,7 +3555,7 @@ VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrC
 /*************************************************/
 /* This is called by the runtime when method jitting started */
 /*************************************************/
-VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
+VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
 {
     CONTRACTL {
         NOTHROW;
@@ -3570,7 +3570,7 @@ VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOr
                                         CLR_JIT_KEYWORD))
         {
             pMethodDesc->GetMethodInfo(*namespaceOrClassName, *methodName, *methodSignature);
-            ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, namespaceOrClassName, methodName, methodSignature);
+            ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, methodDecoder, namespaceOrClassName, methodName, methodSignature);
         }
     } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
 }
@@ -4528,7 +4528,12 @@ VOID ETW::MethodLog::SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc,
 /*****************************************************************/
 /* This routine is used to send an ETW event just before a method starts jitting*/
 /*****************************************************************/
-VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
+VOID ETW::MethodLog::SendMethodJitStartEvent(
+    MethodDesc *pMethodDesc,
+    COR_ILMETHOD_DECODER* methodDecoder,
+    SString *namespaceOrClassName,
+    SString *methodName,
+    SString *methodSignature)
 {
     CONTRACTL {
         THROWS;
@@ -4570,14 +4575,8 @@ VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *n
             ulMethodToken = (ULONG)pMethodDesc->GetMemberDef();
         }
 
-        // An IL method that has no IL header can occur for dynamically
-        // generated code during JIT (for example, UnsafeAccessor).
-        if(pMethodDesc->IsIL() && pMethodDesc->GetILHeader() != NULL)
-        {
-            COR_ILMETHOD_DECODER::DecoderStatus decoderstatus = COR_ILMETHOD_DECODER::FORMAT_ERROR;
-            COR_ILMETHOD_DECODER ILHeader(pMethodDesc->GetILHeader(), pMethodDesc->GetMDImport(), &decoderstatus);
-            ulMethodILSize = (ULONG)ILHeader.GetCodeSize();
-        }
+        if (methodDecoder != NULL)
+            ulMethodILSize = methodDecoder->GetCodeSize();
 
         SString tNamespace, tMethodName, tMethodSignature;
         if(!namespaceOrClassName|| !methodName|| !methodSignature || (methodName->IsEmpty() && namespaceOrClassName->IsEmpty() && methodSignature->IsEmpty()))
diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp
index 1a3439bdd235ef..74ee2f7482e747 100644
--- a/src/coreclr/vm/jitinterface.cpp
+++ b/src/coreclr/vm/jitinterface.cpp
@@ -12286,7 +12286,7 @@ static CorJitResult CompileMethodWithEtwWrapper(EEJitManager *jitMgr,
 
     SString namespaceOrClassName, methodName, methodSignature;
     // Fire an ETW event to mark the beginning of JIT'ing
-    ETW::MethodLog::MethodJitting(reinterpret_cast<MethodDesc*>(info->ftn), &namespaceOrClassName, &methodName, &methodSignature);
+    ETW::MethodLog::MethodJitting(reinterpret_cast<MethodDesc*>(info->ftn), NULL, &namespaceOrClassName, &methodName, &methodSignature);
 
     CorJitResult ret = jitMgr->m_jit->compileMethod(comp, info, flags, nativeEntry, nativeSizeOfCode);
 
diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp
index 4b34045b57671e..e51d9f7453d35e 100644
--- a/src/coreclr/vm/method.hpp
+++ b/src/coreclr/vm/method.hpp
@@ -1819,7 +1819,7 @@ class MethodDesc
     PCODE GetMulticoreJitCode(PrepareCodeConfig* pConfig, bool* pWasTier0);
     PCODE JitCompileCode(PrepareCodeConfig* pConfig);
     PCODE JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry);
-    PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode);
+    PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode);
 
 public:
     bool TryGenerateUnsafeAccessor(DynamicResolver** resolver, COR_ILMETHOD_DECODER** methodILDecoder);
diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp
index 174e48565f31b8..32944952301648 100644
--- a/src/coreclr/vm/prestub.cpp
+++ b/src/coreclr/vm/prestub.cpp
@@ -709,6 +709,53 @@ PCODE MethodDesc::JitCompileCode(PrepareCodeConfig* pConfig)
     }
 }
 
+namespace
+{
+    COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory)
+    {
+        STANDARD_VM_CONTRACT;
+        _ASSERTE(pMD != NULL);
+        _ASSERTE(!pMD->IsNoMetadata());
+        _ASSERTE(pConfig != NULL);
+        _ASSERTE(pDecoderMemory != NULL);
+
+        COR_ILMETHOD_DECODER* pHeader = NULL;
+        COR_ILMETHOD* ilHeader = pConfig->GetILHeader();
+        if (ilHeader == NULL)
+            return NULL;
+
+        COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR;
+        {
+            // Decoder ctor can AV on a malformed method header
+            AVInRuntimeImplOkayHolder AVOkay;
+            pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status);
+        }
+
+        if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR)
+            COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL);
+
+        return pHeader;
+    }
+
+    COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory)
+    {
+        STANDARD_VM_CONTRACT;
+        _ASSERTE(pMD != NULL);
+        if (pMD->IsIL())
+        {
+            return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory);
+        }
+        else if (pMD->IsILStub())
+        {
+            ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver();
+            return pResolver->GetILHeader();
+        }
+
+        _ASSERTE(pMD->IsNoMetadata());
+        return NULL;
+    }
+}
+
 PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry)
 {
     STANDARD_VM_CONTRACT;
@@ -759,11 +806,18 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
     }
 #endif // PROFILING_SUPPORTED
 
+    // The profiler may have changed the code on the callback.  Need to
+    // pick up the new code.
+    //
+    // (don't want this for OSR, need to see how it works)
+    COR_ILMETHOD_DECODER ilDecoderTemp;
+    COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp);
+
     if (!ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context,
         TRACE_LEVEL_VERBOSE,
         CLR_JIT_KEYWORD))
     {
-        pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode);
+        pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode);
     }
     else
     {
@@ -778,12 +832,13 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
         // a small stub of native code but no native-IL mapping.
 #ifndef FEATURE_INTERPRETER
         ETW::MethodLog::MethodJitting(this,
+            pilHeader,
             &namespaceOrClassName,
             &methodName,
             &methodSignature);
 #endif
 
-        pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode);
+        pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode);
 
         // Interpretted methods skip this notification
 #ifdef FEATURE_INTERPRETER
@@ -869,66 +924,11 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
     return pCode;
 }
 
-namespace
-{
-    COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory)
-    {
-        STANDARD_VM_CONTRACT;
-        _ASSERTE(pMD != NULL);
-        _ASSERTE(!pMD->IsNoMetadata());
-        _ASSERTE(pConfig != NULL);
-        _ASSERTE(pDecoderMemory != NULL);
-
-        COR_ILMETHOD_DECODER* pHeader = NULL;
-        COR_ILMETHOD* ilHeader = pConfig->GetILHeader();
-        if (ilHeader == NULL)
-            return NULL;
-
-        COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR;
-        {
-            // Decoder ctor can AV on a malformed method header
-            AVInRuntimeImplOkayHolder AVOkay;
-            pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status);
-        }
-
-        if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR)
-            COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL);
-
-        return pHeader;
-    }
-
-    COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory)
-    {
-        STANDARD_VM_CONTRACT;
-        _ASSERTE(pMD != NULL);
-        if (pMD->IsIL())
-        {
-            return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory);
-        }
-        else if (pMD->IsILStub())
-        {
-            ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver();
-            return pResolver->GetILHeader();
-        }
-
-        _ASSERTE(pMD->IsNoMetadata());
-        return NULL;
-    }
-}
-
-PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry, ULONG* pSizeOfCode)
+PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pEntry, ULONG* pSizeOfCode)
 {
     STANDARD_VM_CONTRACT;
 
     PCODE pCode = NULL;
-
-    // The profiler may have changed the code on the callback.  Need to
-    // pick up the new code.
-    //
-    // (don't want this for OSR, need to see how it works)
-    COR_ILMETHOD_DECODER ilDecoderTemp;
-    COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp);
-
     CORJIT_FLAGS jitFlags;
     PCODE pOtherCode = NULL;
 

From 5513fb86e99add5d262d45044820062c660e6556 Mon Sep 17 00:00:00 2001
From: Aaron R Robinson <arobins@microsoft.com>
Date: Fri, 18 Aug 2023 16:15:09 -0700
Subject: [PATCH 5/6] Remove redundent calls and another spot to check.

---
 src/coreclr/debug/daccess/stack.cpp         | 10 ++++++----
 src/coreclr/vm/versionresilienthashcode.cpp |  8 +++++++-
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/coreclr/debug/daccess/stack.cpp b/src/coreclr/debug/daccess/stack.cpp
index 21dfaffbfd1e06..6b9f1a491c291c 100644
--- a/src/coreclr/debug/daccess/stack.cpp
+++ b/src/coreclr/debug/daccess/stack.cpp
@@ -1253,17 +1253,19 @@ ClrDataFrame::GetLocalSig(MetaSig** sig,
     {
         // It turns out we cannot really get rid of this check.  Dynamic methods
         // (including IL stubs) do not have their local sig's available after JIT time.
-        // IL Methods with dynamically generated IL (for example, UnsafeAccessors) may
+        // IL methods with dynamically generated IL (for example, UnsafeAccessors) may
         // not have an IL header.
-        if (!m_methodDesc->IsIL()
-            || m_methodDesc->GetILHeader() == NULL)
+        COR_ILMETHOD* ilHeader = m_methodDesc->IsIL()
+            ? m_methodDesc->GetILHeader()
+            : NULL;
+        if (ilHeader == NULL)
         {
             *sig = NULL;
             *count = 0;
             return E_FAIL;
         }
 
-        COR_ILMETHOD_DECODER methodDecoder(m_methodDesc->GetILHeader());
+        COR_ILMETHOD_DECODER methodDecoder(ilHeader);
         mdSignature localSig = methodDecoder.GetLocalVarSigTok() ?
             methodDecoder.GetLocalVarSigTok() : mdSignatureNil;
         if (localSig == mdSignatureNil)
diff --git a/src/coreclr/vm/versionresilienthashcode.cpp b/src/coreclr/vm/versionresilienthashcode.cpp
index b3ba764baac595..85bd146d8dc463 100644
--- a/src/coreclr/vm/versionresilienthashcode.cpp
+++ b/src/coreclr/vm/versionresilienthashcode.cpp
@@ -286,7 +286,7 @@ bool AddVersionResilientHashCodeForInstruction(ILInstructionParser *parser, xxHa
             hash->Add(varValue);
             break;
         }
-        
+
         case InlineVar: // 2 byte value which is token change resilient
         {
             uint16_t varValue;
@@ -388,6 +388,12 @@ bool GetVersionResilientILCodeHashCode(MethodDesc *pMD, int* hashCode, unsigned*
 
         initLocals = (options & CORINFO_OPT_INIT_LOCALS) == CORINFO_OPT_INIT_LOCALS;
     }
+    else if (!pMD->HasILHeader())
+    {
+        // Dynamically generated IL methods like UnsafeAccessors may not have
+        // an IL header.
+        return false;
+    }
     else
     {
         COR_ILMETHOD_DECODER header(pMD->GetILHeader(TRUE), pMD->GetMDImport(), NULL);

From fb29886464e65fa54c905c4d2dd039a20b46136f Mon Sep 17 00:00:00 2001
From: Aaron R Robinson <arobins@microsoft.com>
Date: Fri, 18 Aug 2023 19:03:21 -0700
Subject: [PATCH 6/6] Move header include

---
 src/coreclr/utilcode/stresslog.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/coreclr/utilcode/stresslog.cpp b/src/coreclr/utilcode/stresslog.cpp
index c55c5afe9249c8..90ad5900473ed7 100644
--- a/src/coreclr/utilcode/stresslog.cpp
+++ b/src/coreclr/utilcode/stresslog.cpp
@@ -12,9 +12,9 @@
 #include "switches.h"
 #include "stresslog.h"
 #include "clrhost.h"
+#include "ex.h"
 #define DONOT_DEFINE_ETW_CALLBACK
 #include "eventtracebase.h"
-#include "ex.h"
 
  #if !defined(STRESS_LOG_READONLY)
 #ifdef HOST_WINDOWS
