From: Konstantin Baladurin Date: Fri, 30 Mar 2018 07:18:04 +0000 (+0300) Subject: PEImageLayout: clear instruction cache after relocations X-Git-Tag: submit/tizen/20210909.063632~11030^2~5118 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=92b49fe1e62aba349284439ba1f75ab5f8deb129;p=platform%2Fupstream%2Fdotnet%2Fruntime.git PEImageLayout: clear instruction cache after relocations It fixes crashes on arm when using AOT images. Commit migrated from https://github.com/dotnet/coreclr/commit/4a2a446bce2035ea477de234fb24c37e7f134616 --- diff --git a/src/coreclr/src/vm/peimagelayout.cpp b/src/coreclr/src/vm/peimagelayout.cpp index 0a84892..a3514e5 100644 --- a/src/coreclr/src/vm/peimagelayout.cpp +++ b/src/coreclr/src/vm/peimagelayout.cpp @@ -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 }