diff options
Diffstat (limited to 'packaging/0035-PEImageLayout-flush-instruction-cache-only-for-pages.patch')
-rw-r--r-- | packaging/0035-PEImageLayout-flush-instruction-cache-only-for-pages.patch | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/packaging/0035-PEImageLayout-flush-instruction-cache-only-for-pages.patch b/packaging/0035-PEImageLayout-flush-instruction-cache-only-for-pages.patch new file mode 100644 index 0000000000..e986952668 --- /dev/null +++ b/packaging/0035-PEImageLayout-flush-instruction-cache-only-for-pages.patch @@ -0,0 +1,117 @@ +From c5539d864c61476446542bee351af3a125118ef3 Mon Sep 17 00:00:00 2001 +From: Konstantin Baladurin <k.baladurin@partner.samsung.com> +Date: Mon, 14 May 2018 12:35:09 +0300 +Subject: [PATCH 35/47] PEImageLayout: flush instruction cache only for pages + with relocs. + +We need to flush instruction cache only for pages that have relocations +instead of full sections because otherwise application's shared clean +memory is increased in some cases on Linux. +--- + src/vm/peimagelayout.cpp | 46 +++++++++++++++++++++++++++++----------------- + 1 file changed, 29 insertions(+), 17 deletions(-) + +diff --git a/src/vm/peimagelayout.cpp b/src/vm/peimagelayout.cpp +index 4bfbe40..5e0243b 100644 +--- a/src/vm/peimagelayout.cpp ++++ b/src/vm/peimagelayout.cpp +@@ -150,7 +150,10 @@ void PEImageLayout::ApplyBaseRelocations() + SIZE_T cbWriteableRegion = 0; + DWORD dwOldProtection = 0; + +- BOOL bRelocDone = FALSE; ++ BYTE * pFlushRegion = NULL; ++ SIZE_T cbFlushRegion = 0; ++ // The page size of PE file relocs is always 4096 bytes ++ const SIZE_T cbPageSize = 4096; + + COUNT_T dirPos = 0; + while (dirPos < dirSize) +@@ -185,13 +188,6 @@ void PEImageLayout::ApplyBaseRelocations() + dwOldProtection, &dwOldProtection)) + ThrowLastError(); + +- if (bRelocDone && bExecRegion) +- { +- ClrFlushInstructionCache(pWriteableRegion, cbWriteableRegion); +- } +- +- bRelocDone = FALSE; +- + dwOldProtection = 0; + } + +@@ -224,6 +220,7 @@ void PEImageLayout::ApplyBaseRelocations() + } + } + ++ BYTE* pEndAddressToFlush = NULL; + for (COUNT_T fixupIndex = 0; fixupIndex < fixupsCount; fixupIndex++) + { + USHORT fixup = VAL16(fixups[fixupIndex]); +@@ -234,13 +231,13 @@ void PEImageLayout::ApplyBaseRelocations() + { + case IMAGE_REL_BASED_PTR: + *(TADDR *)address += delta; +- bRelocDone = TRUE; ++ pEndAddressToFlush = max(pEndAddressToFlush, address + sizeof(TADDR)); + break; + + #ifdef _TARGET_ARM_ + case IMAGE_REL_BASED_THUMB_MOV32: + PutThumb2Mov32((UINT16 *)address, GetThumb2Mov32((UINT16 *)address) + delta); +- bRelocDone = TRUE; ++ pEndAddressToFlush = max(pEndAddressToFlush, address + 8); + break; + #endif + +@@ -253,24 +250,39 @@ void PEImageLayout::ApplyBaseRelocations() + } + } + ++ BOOL bExecRegion = (dwOldProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ | ++ PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0; ++ ++ if (bExecRegion && pEndAddressToFlush != NULL) ++ { ++ // If the current page is not next to the pending region to flush, flush the current pending region and start a new one ++ if (pageAddress >= pFlushRegion + cbFlushRegion + cbPageSize || pageAddress < pFlushRegion) ++ { ++ if (pFlushRegion != NULL) ++ { ++ ClrFlushInstructionCache(pFlushRegion, cbFlushRegion); ++ } ++ pFlushRegion = pageAddress; ++ } ++ ++ cbFlushRegion = pEndAddressToFlush - pFlushRegion; ++ } ++ + dirPos += fixupsSize; + } + _ASSERTE(dirSize == dirPos); + + 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); +- } ++ if (pFlushRegion != NULL) ++ { ++ ClrFlushInstructionCache(pFlushRegion, cbFlushRegion); + } + } + #endif // FEATURE_PREJIT +-- +2.7.4 + |