Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 3f67146

Browse files
sdmacleagkhanna79
authored andcommitted
Remove PAL FileAlignment restriction (#10959)
* Remove PAL FileAlignment restriction * Address PR #10959 feedback * Fix amd64 crossgen error * Respond to review feedback * Fix arm32 regression * Prepare to remove VIRTUAL_PAGE_* from map.cpp Also simplify previous section code * Rename function to GetVirtualPageSize()
1 parent 69d43a0 commit 3f67146

File tree

5 files changed

+52
-50
lines changed

5 files changed

+52
-50
lines changed

src/pal/src/map/map.cpp

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ using namespace CorUnix;
4444

4545
SET_DEFAULT_DEBUG_CHANNEL(VIRTUAL);
4646

47+
#include "pal/utils.h"
48+
49+
// This is temporary until #10981 merges.
50+
// There will be an equivalent but opposite temporary fix in #10981 which
51+
// will trigger a merge conflict to be sure both of these workarounds are removed
52+
#define GetVirtualPageSize() VIRTUAL_PAGE_SIZE
53+
4754
//
4855
// The mapping critical section guards access to the list
4956
// of currently mapped views. If a thread needs to access
@@ -2012,14 +2019,14 @@ BOOL MAPGetRegionInfo(LPVOID lpAddress,
20122019
real_map_sz = pView->NumberOfBytesToMap;
20132020
#endif
20142021

2015-
MappedSize = ((real_map_sz-1) & ~VIRTUAL_PAGE_MASK) + VIRTUAL_PAGE_SIZE;
2022+
MappedSize = ALIGN_UP(real_map_sz, GetVirtualPageSize());
20162023
if ( real_map_addr <= lpAddress &&
20172024
(VOID *)((UINT_PTR)real_map_addr+MappedSize) > lpAddress )
20182025
{
20192026
if (lpBuffer)
20202027
{
2021-
SIZE_T regionSize = MappedSize + (UINT_PTR) real_map_addr -
2022-
((UINT_PTR) lpAddress & ~VIRTUAL_PAGE_MASK);
2028+
SIZE_T regionSize = MappedSize + (UINT_PTR) real_map_addr -
2029+
ALIGN_DOWN((UINT_PTR)lpAddress, GetVirtualPageSize());
20232030

20242031
lpBuffer->BaseAddress = lpAddress;
20252032
lpBuffer->AllocationProtect = 0;
@@ -2241,7 +2248,9 @@ MAPmmapAndRecord(
22412248
PAL_ERROR palError = NO_ERROR;
22422249
LPVOID pvBaseAddress = NULL;
22432250

2244-
pvBaseAddress = mmap(addr, len, prot, flags, fd, offset);
2251+
off_t adjust = offset & (GetVirtualPageSize() - 1);
2252+
2253+
pvBaseAddress = mmap(static_cast<char *>(addr) - adjust, len + adjust, prot, flags, fd, offset - adjust);
22452254
if (MAP_FAILED == pvBaseAddress)
22462255
{
22472256
ERROR_(LOADER)( "mmap failed with code %d: %s.\n", errno, strerror( errno ) );
@@ -2368,14 +2377,6 @@ void * MAPMapPEFile(HANDLE hFile)
23682377
goto done;
23692378
}
23702379

2371-
//this code requires that the file alignment be the same as the page alignment
2372-
if (ntHeader.OptionalHeader.FileAlignment < VIRTUAL_PAGE_SIZE)
2373-
{
2374-
ERROR_(LOADER)( "Optional header file alignment is bad\n" );
2375-
palError = ERROR_INVALID_PARAMETER;
2376-
goto done;
2377-
}
2378-
23792380
//This doesn't read the entire NT header (the optional header technically has a variable length. But I
23802381
//don't need more directories.
23812382

@@ -2416,7 +2417,7 @@ void * MAPMapPEFile(HANDLE hFile)
24162417
{
24172418
//if we're forcing relocs, create an anonymous mapping at the preferred base. Only create the
24182419
//mapping if we can create it at the specified address.
2419-
pForceRelocBase = mmap( (void*)preferredBase, VIRTUAL_PAGE_SIZE, PROT_NONE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0 );
2420+
pForceRelocBase = mmap( (void*)preferredBase, GetVirtualPageSize(), PROT_NONE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0 );
24202421
if (pForceRelocBase == MAP_FAILED)
24212422
{
24222423
TRACE_(LOADER)("Attempt to take preferred base of %p to force relocation failed\n", (void*)preferredBase);
@@ -2445,7 +2446,7 @@ void * MAPMapPEFile(HANDLE hFile)
24452446
// First try to reserve virtual memory using ExecutableAllcator. This allows all PE images to be
24462447
// near each other and close to the coreclr library which also allows the runtime to generate
24472448
// more efficient code (by avoiding usage of jump stubs).
2448-
loadedBase = ReserveMemoryFromExecutableAllocator(pThread, virtualSize);
2449+
loadedBase = ReserveMemoryFromExecutableAllocator(pThread, ALIGN_UP(virtualSize, GetVirtualPageSize()));
24492450
if (loadedBase == NULL)
24502451
{
24512452
// MAC64 requires we pass MAP_SHARED (or MAP_PRIVATE) flags - otherwise, the call is failed.
@@ -2468,7 +2469,7 @@ void * MAPMapPEFile(HANDLE hFile)
24682469
if (forceRelocs)
24692470
{
24702471
_ASSERTE(((SIZE_T)loadedBase) != preferredBase);
2471-
munmap(pForceRelocBase, VIRTUAL_PAGE_SIZE); // now that we've forced relocation, let the original address mapping go
2472+
munmap(pForceRelocBase, GetVirtualPageSize()); // now that we've forced relocation, let the original address mapping go
24722473
}
24732474
if (((SIZE_T)loadedBase) != preferredBase)
24742475
{
@@ -2484,7 +2485,7 @@ void * MAPMapPEFile(HANDLE hFile)
24842485
//separately.
24852486

24862487
size_t headerSize;
2487-
headerSize = VIRTUAL_PAGE_SIZE; // if there are lots of sections, this could be wrong
2488+
headerSize = GetVirtualPageSize(); // if there are lots of sections, this could be wrong
24882489

24892490
//first, map the PE header to the first page in the image. Get pointers to the section headers
24902491
palError = MAPmmapAndRecord(pFileObject, loadedBase,
@@ -2519,10 +2520,8 @@ void * MAPMapPEFile(HANDLE hFile)
25192520
goto doneReleaseMappingCriticalSection;
25202521
}
25212522

2522-
void* prevSectionBase;
2523-
prevSectionBase = loadedBase; // the first "section" for our purposes is the header
2524-
size_t prevSectionSizeInMemory;
2525-
prevSectionSizeInMemory = headerSize;
2523+
void* prevSectionEnd;
2524+
prevSectionEnd = (char*)loadedBase + headerSize; // the first "section" for our purposes is the header
25262525
for (unsigned i = 0; i < numSections; ++i)
25272526
{
25282527
//for each section, map the section of the file to the correct virtual offset. Gather the
@@ -2532,12 +2531,13 @@ void * MAPMapPEFile(HANDLE hFile)
25322531
IMAGE_SECTION_HEADER &currentHeader = firstSection[i];
25332532

25342533
void* sectionBase = (char*)loadedBase + currentHeader.VirtualAddress;
2534+
void* sectionBaseAligned = ALIGN_DOWN(sectionBase, GetVirtualPageSize());
25352535

25362536
// Validate the section header
25372537
if ( (sectionBase < loadedBase) // Did computing the section base overflow?
25382538
|| ((char*)sectionBase + currentHeader.SizeOfRawData < (char*)sectionBase) // Does the section overflow?
25392539
|| ((char*)sectionBase + currentHeader.SizeOfRawData > (char*)loadedBase + virtualSize) // Does the section extend past the end of the image as the header stated?
2540-
|| ((char*)prevSectionBase + prevSectionSizeInMemory > sectionBase) // Does this section overlap the previous one?
2540+
|| (prevSectionEnd > sectionBase) // Does this section overlap the previous one?
25412541
)
25422542
{
25432543
ERROR_(LOADER)( "section %d is corrupt\n", i );
@@ -2552,13 +2552,12 @@ void * MAPMapPEFile(HANDLE hFile)
25522552
}
25532553

25542554
// Is there space between the previous section and this one? If so, add a PROT_NONE mapping to cover it.
2555-
if ((char*)prevSectionBase + prevSectionSizeInMemory < sectionBase)
2555+
if (prevSectionEnd < sectionBaseAligned)
25562556
{
2557-
char* gapBase = (char*)prevSectionBase + prevSectionSizeInMemory;
25582557
palError = MAPRecordMapping(pFileObject,
25592558
loadedBase,
2560-
(void*)gapBase,
2561-
(char*)sectionBase - gapBase,
2559+
prevSectionEnd,
2560+
(char*)sectionBaseAligned - (char*)prevSectionEnd,
25622561
PROT_NONE);
25632562
if (NO_ERROR != palError)
25642563
{
@@ -2602,20 +2601,18 @@ void * MAPMapPEFile(HANDLE hFile)
26022601
}
26032602
#endif // _DEBUG
26042603

2605-
prevSectionBase = sectionBase;
2606-
prevSectionSizeInMemory = (currentHeader.SizeOfRawData + VIRTUAL_PAGE_MASK) & ~VIRTUAL_PAGE_MASK; // round up to page boundary
2604+
prevSectionEnd = ALIGN_UP((char*)sectionBase + currentHeader.SizeOfRawData, GetVirtualPageSize()); // round up to page boundary
26072605
}
26082606

26092607
// Is there space after the last section and before the end of the mapped image? If so, add a PROT_NONE mapping to cover it.
26102608
char* imageEnd;
26112609
imageEnd = (char*)loadedBase + virtualSize; // actually, points just after the mapped end
2612-
if ((char*)prevSectionBase + prevSectionSizeInMemory < imageEnd)
2610+
if (prevSectionEnd < imageEnd)
26132611
{
2614-
char* gapBase = (char*)prevSectionBase + prevSectionSizeInMemory;
26152612
palError = MAPRecordMapping(pFileObject,
26162613
loadedBase,
2617-
(void*)gapBase,
2618-
imageEnd - gapBase,
2614+
prevSectionEnd,
2615+
(char*)imageEnd - (char*)prevSectionEnd,
26192616
PROT_NONE);
26202617
if (NO_ERROR != palError)
26212618
{

src/utilcode/pedecoder.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,6 @@ CHECK PEDecoder::CheckNTHeaders() const
263263
CHECK(CheckAligned((UINT)VAL32(pNT->OptionalHeader.FileAlignment), 512));
264264
CHECK(CheckAligned((UINT)VAL32(pNT->OptionalHeader.SectionAlignment), VAL32(pNT->OptionalHeader.FileAlignment)));
265265

266-
// INVESTIGATE: this doesn't seem to be necessary on Win64 - why??
267-
//CHECK(CheckAligned((UINT)VAL32(pNT->OptionalHeader.SectionAlignment), OS_PAGE_SIZE));
268-
CHECK(CheckAligned((UINT)VAL32(pNT->OptionalHeader.SectionAlignment), 0x1000)); // for base relocs logic
269266
CHECK(CheckAligned((UINT)VAL32(pNT->OptionalHeader.SizeOfImage), VAL32(pNT->OptionalHeader.SectionAlignment)));
270267
CHECK(CheckAligned((UINT)VAL32(pNT->OptionalHeader.SizeOfHeaders), VAL32(pNT->OptionalHeader.FileAlignment)));
271268

src/vm/peimagelayout.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,17 @@ void PEImageLayout::ApplyBaseRelocations()
155155
{
156156
PIMAGE_BASE_RELOCATION r = (PIMAGE_BASE_RELOCATION)(dir + dirPos);
157157

158+
COUNT_T fixupsSize = VAL32(r->SizeOfBlock);
159+
160+
USHORT *fixups = (USHORT *) (r + 1);
161+
162+
_ASSERTE(fixupsSize > sizeof(IMAGE_BASE_RELOCATION));
163+
_ASSERTE((fixupsSize - sizeof(IMAGE_BASE_RELOCATION)) % 2 == 0);
164+
165+
COUNT_T fixupsCount = (fixupsSize - sizeof(IMAGE_BASE_RELOCATION)) / 2;
166+
167+
_ASSERTE((BYTE *)(fixups + fixupsCount) <= (BYTE *)(dir + dirSize));
168+
158169
DWORD rva = VAL32(r->VirtualAddress);
159170

160171
BYTE * pageAddress = (BYTE *)GetBase() + rva;
@@ -172,7 +183,9 @@ void PEImageLayout::ApplyBaseRelocations()
172183
dwOldProtection = 0;
173184
}
174185

175-
IMAGE_SECTION_HEADER *pSection = RvaToSection(rva);
186+
USHORT fixup = VAL16(fixups[0]);
187+
188+
IMAGE_SECTION_HEADER *pSection = RvaToSection(rva + (fixup & 0xfff));
176189
PREFIX_ASSUME(pSection != NULL);
177190

178191
pWriteableRegion = (BYTE*)GetRvaData(VAL32(pSection->VirtualAddress));
@@ -199,17 +212,6 @@ void PEImageLayout::ApplyBaseRelocations()
199212
}
200213
}
201214

202-
COUNT_T fixupsSize = VAL32(r->SizeOfBlock);
203-
204-
USHORT *fixups = (USHORT *) (r + 1);
205-
206-
_ASSERTE(fixupsSize > sizeof(IMAGE_BASE_RELOCATION));
207-
_ASSERTE((fixupsSize - sizeof(IMAGE_BASE_RELOCATION)) % 2 == 0);
208-
209-
COUNT_T fixupsCount = (fixupsSize - sizeof(IMAGE_BASE_RELOCATION)) / 2;
210-
211-
_ASSERTE((BYTE *)(fixups + fixupsCount) <= (BYTE *)(dir + dirSize));
212-
213215
for (COUNT_T fixupIndex = 0; fixupIndex < fixupsCount; fixupIndex++)
214216
{
215217
USHORT fixup = VAL16(fixups[fixupIndex]);

src/zap/zapimage.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,8 +1545,8 @@ void ZapImage::OutputTables()
15451545
SetSizeOfStackCommit(m_ModuleDecoder.GetSizeOfStackCommit());
15461546
}
15471547

1548-
#if defined(FEATURE_PAL)
1549-
// PAL library requires native image sections to align to page bounaries.
1548+
#if defined(FEATURE_PAL) && !defined(BIT64)
1549+
// To minimize wasted VA space on 32 bit systems align file to page bounaries (presumed to be 4K).
15501550
SetFileAlignment(0x1000);
15511551
#elif defined(_TARGET_ARM_) && defined(FEATURE_CORESYSTEM)
15521552
if (!IsReadyToRunCompilation())

src/zap/zapwriter.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,13 @@ void ZapWriter::Initialize()
5555
m_FileAlignment = 0x200;
5656
}
5757

58+
#if defined(FEATURE_PAL) && defined(BIT64)
59+
#define SECTION_ALIGNMENT m_FileAlignment
60+
#define PAL_MAX_PAGE_SIZE 0x10000
61+
#else
5862
#define SECTION_ALIGNMENT 0x1000
63+
#define PAL_MAX_PAGE_SIZE 0
64+
#endif
5965

6066
void ZapWriter::Save(IStream * pStream)
6167
{
@@ -119,7 +125,7 @@ void ZapWriter::ComputeRVAs()
119125

120126
pPhysicalSection->m_dwFilePos = dwFilePos;
121127

122-
dwPos = AlignUp(dwPos, SECTION_ALIGNMENT);
128+
dwPos = AlignUp(dwPos, SECTION_ALIGNMENT) + PAL_MAX_PAGE_SIZE;
123129
pPhysicalSection->SetRVA(dwPos);
124130

125131
DWORD dwEndOfRawData = dwPos;
@@ -193,7 +199,7 @@ void ZapWriter::SaveContent()
193199
WritePad(dwAlignedFilePos - dwFilePos);
194200
dwFilePos = dwAlignedFilePos;
195201

196-
dwPos = AlignUp(dwPos, SECTION_ALIGNMENT);
202+
dwPos = AlignUp(dwPos, SECTION_ALIGNMENT) + PAL_MAX_PAGE_SIZE;
197203

198204
if (m_fWritingRelocs)
199205
{

0 commit comments

Comments
 (0)