summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKonstantin Baladurin <k.baladurin@partner.samsung.com>2018-05-14 12:35:09 +0300
committerGleb Balykov <g.balykov@samsung.com>2018-09-18 15:49:14 +0300
commit5cc47cbdb69f44772abe0b3f3149468a6706d221 (patch)
tree8d55e57c70f9690b71dd39f669f33171216469aa /src
parenteaae668fc97b56946e4a01a3ad0c89c11f8259d7 (diff)
downloadcoreclr-5cc47cbdb69f44772abe0b3f3149468a6706d221.tar.gz
coreclr-5cc47cbdb69f44772abe0b3f3149468a6706d221.tar.bz2
coreclr-5cc47cbdb69f44772abe0b3f3149468a6706d221.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/vm/peimagelayout.cpp46
1 files changed, 29 insertions, 17 deletions
diff --git a/src/vm/peimagelayout.cpp b/src/vm/peimagelayout.cpp
index a3514e5a06..5f70363f7c 100644
--- a/src/vm/peimagelayout.cpp
+++ b/src/vm/peimagelayout.cpp
@@ -149,7 +149,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)
@@ -184,13 +187,6 @@ void PEImageLayout::ApplyBaseRelocations()
dwOldProtection, &dwOldProtection))
ThrowLastError();
- if (bRelocDone && bExecRegion)
- {
- ClrFlushInstructionCache(pWriteableRegion, cbWriteableRegion);
- }
-
- bRelocDone = FALSE;
-
dwOldProtection = 0;
}
@@ -223,6 +219,7 @@ void PEImageLayout::ApplyBaseRelocations()
}
}
+ BYTE* pEndAddressToFlush = NULL;
for (COUNT_T fixupIndex = 0; fixupIndex < fixupsCount; fixupIndex++)
{
USHORT fixup = VAL16(fixups[fixupIndex]);
@@ -233,13 +230,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
@@ -252,6 +249,24 @@ 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);
@@ -259,18 +274,15 @@ 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);
- }
+ if (pFlushRegion != NULL)
+ {
+ ClrFlushInstructionCache(pFlushRegion, cbFlushRegion);
}
#endif // CROSSGEN_COMPILE
}