PEImageLayout: clear instruction cache after relocations
authorKonstantin Baladurin <k.baladurin@partner.samsung.com>
Fri, 30 Mar 2018 07:18:04 +0000 (10:18 +0300)
committerRuss Keldorph <russ.keldorph@microsoft.com>
Sat, 31 Mar 2018 03:07:26 +0000 (20:07 -0700)
It fixes crashes on arm when using AOT images.

Commit migrated from https://github.com/dotnet/coreclr/commit/4a2a446bce2035ea477de234fb24c37e7f134616

src/coreclr/src/vm/peimagelayout.cpp

index 0a84892..a3514e5 100644 (file)
@@ -149,6 +149,8 @@ void PEImageLayout::ApplyBaseRelocations()
     SIZE_T cbWriteableRegion = 0;
     DWORD dwOldProtection = 0;
 
+    BOOL bRelocDone = FALSE;
+
     COUNT_T dirPos = 0;
     while (dirPos < dirSize)
     {
@@ -175,10 +177,20 @@ void PEImageLayout::ApplyBaseRelocations()
             // Restore the protection
             if (dwOldProtection != 0)
             {
+                BOOL bExecRegion = (dwOldProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
+                    PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0;
+
                 if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion,
                                        dwOldProtection, &dwOldProtection))
                     ThrowLastError();
 
+                if (bRelocDone && bExecRegion)
+                {
+                    ClrFlushInstructionCache(pWriteableRegion, cbWriteableRegion);
+                }
+
+                bRelocDone = FALSE;
+
                 dwOldProtection = 0;
             }
 
@@ -221,11 +233,13 @@ void PEImageLayout::ApplyBaseRelocations()
             {
             case IMAGE_REL_BASED_PTR:
                 *(TADDR *)address += delta;
+                bRelocDone = TRUE;
                 break;
 
 #ifdef _TARGET_ARM_
             case IMAGE_REL_BASED_THUMB_MOV32:
                 PutThumb2Mov32((UINT16 *)address, GetThumb2Mov32((UINT16 *)address) + delta);
+                bRelocDone = TRUE;
                 break;
 #endif
 
@@ -245,10 +259,18 @@ void PEImageLayout::ApplyBaseRelocations()
 #ifndef CROSSGEN_COMPILE
     if (dwOldProtection != 0)
     {
+        BOOL bExecRegion = (dwOldProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
+            PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0;
+
         // Restore the protection
         if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion,
                                dwOldProtection, &dwOldProtection))
             ThrowLastError();
+
+        if (bRelocDone && bExecRegion)
+        {
+            ClrFlushInstructionCache(pWriteableRegion, cbWriteableRegion);
+        }
     }
 #endif // CROSSGEN_COMPILE
 }