Fix BackoutJitData (#54711)
authorJan Vorlicek <jan.vorlicek@volny.cz>
Fri, 25 Jun 2021 17:06:37 +0000 (19:06 +0200)
committerGitHub <noreply@github.com>
Fri, 25 Jun 2021 17:06:37 +0000 (19:06 +0200)
* Fix BackoutJitData

The RemoveJitData that the BackoutJitData calls requires the code
header to be copied to the final location. This change fixes it.

I've also found that in one of my previous changes, I've accidentally
enabled jitting into a scratch buffer by default by adding the
FEATURE_WXORX define unconditionally. So I am removing it in this change
for non Apple Silicon, it will be replaced by a dynamic check whether W^X
is enabled in the final W^X change.

src/coreclr/vm/codeman.cpp
src/coreclr/vm/jitinterface.cpp
src/coreclr/vm/jitinterface.h

index 349a760..3722078 100644 (file)
@@ -2685,7 +2685,11 @@ void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveFo
         pCodeHdr = ((CodeHeader *)pCode) - 1;
 
         *pAllocatedSize = sizeof(CodeHeader) + totalSize;
-#define FEATURE_WXORX        
+
+#if defined(HOST_OSX) && defined(HOST_ARM64)
+#define FEATURE_WXORX
+#endif
+
 #ifdef FEATURE_WXORX
         pCodeHdrRW = (CodeHeader *)new BYTE[*pAllocatedSize];
 #else
index f4b155a..8483c1f 100644 (file)
@@ -11212,6 +11212,27 @@ void CEEJitInfo::GetProfilingHandle(bool                      *pbHookFunction,
 }
 
 /*********************************************************************/
+void CEEJitInfo::WriteCodeBytes()
+{
+    LIMITED_METHOD_CONTRACT;
+
+#ifdef USE_INDIRECT_CODEHEADER
+    if (m_pRealCodeHeader != NULL)
+    {
+        // Restore the read only version of the real code header
+        m_CodeHeaderRW->SetRealCodeHeader(m_pRealCodeHeader);
+        m_pRealCodeHeader = NULL;
+    }
+#endif // USE_INDIRECT_CODEHEADER
+
+    if (m_CodeHeaderRW != m_CodeHeader)
+    {
+        ExecutableWriterHolder<void> codeWriterHolder((void *)m_CodeHeader, m_codeWriteBufferSize);
+        memcpy(codeWriterHolder.GetRW(), m_CodeHeaderRW, m_codeWriteBufferSize);
+    }
+}
+
+/*********************************************************************/
 void CEEJitInfo::BackoutJitData(EEJitManager * jitMgr)
 {
     CONTRACTL {
@@ -11219,6 +11240,10 @@ void CEEJitInfo::BackoutJitData(EEJitManager * jitMgr)
         GC_TRIGGERS;
     } CONTRACTL_END;
 
+    // The RemoveJitData call below requires the m_CodeHeader to be valid, so we need to write
+    // the code bytes to the target memory location.
+    WriteCodeBytes();
+
     CodeHeader* pCodeHeader = m_CodeHeader;
     if (pCodeHeader)
         jitMgr->RemoveJitData(pCodeHeader, m_GCinfo_len, m_EHinfo_len);
@@ -11232,20 +11257,7 @@ void CEEJitInfo::WriteCode(EEJitManager * jitMgr)
         GC_TRIGGERS;
     } CONTRACTL_END;
 
-#ifdef USE_INDIRECT_CODEHEADER
-    if (m_pRealCodeHeader != NULL)
-    {
-        // Restore the read only version of the real code header
-        m_CodeHeaderRW->SetRealCodeHeader(m_pRealCodeHeader);
-        m_pRealCodeHeader = NULL;
-    }
-#endif // USE_INDIRECT_CODEHEADER
-
-    if (m_CodeHeaderRW != m_CodeHeader)
-    {
-        ExecutableWriterHolder<void> codeWriterHolder((void *)m_CodeHeader, m_codeWriteBufferSize);
-        memcpy(codeWriterHolder.GetRW(), m_CodeHeaderRW, m_codeWriteBufferSize);
-    }
+    WriteCodeBytes();
 
     // Now that the code header was written to the final location, publish the code via the nibble map
     jitMgr->NibbleMapSet(m_pCodeHeap, m_CodeHeader->GetCodeStartAddress(), TRUE);
index 29e566a..ca9d03c 100644 (file)
@@ -941,6 +941,8 @@ public:
 
 protected :
 
+    void WriteCodeBytes();
+
 #ifdef FEATURE_PGO
     // PGO data
     struct ComputedPgoData