summaryrefslogtreecommitdiff
path: root/packaging/0035-PEImageLayout-flush-instruction-cache-only-for-pages.patch
diff options
context:
space:
mode:
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.patch117
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
+