Skip to content

Commit

Permalink
Fix singlefile on OSX ARM64 (#68845)
Browse files Browse the repository at this point in the history
* Same alignment in the bundle on OSX as on Linux

* Extra VA gap between section in casse we run from sf bundle

* Rename prevSectionEnd -> prevSectionEndAligned and make it aligned.

* Suppress assert for now on OSX
  • Loading branch information
VSadov authored May 4, 2022
1 parent 6a9245f commit d44343b
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 17 deletions.
21 changes: 11 additions & 10 deletions src/coreclr/pal/src/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2394,8 +2394,9 @@ void * MAPMapPEFile(HANDLE hFile, off_t offset)
goto doneReleaseMappingCriticalSection;
}

void* prevSectionEnd;
prevSectionEnd = (char*)loadedHeader + headerSize; // the first "section" for our purposes is the header
void* prevSectionEndAligned;
// the first "section" for our purposes is the header
prevSectionEndAligned = ALIGN_UP((char*)loadedHeader + headerSize, GetVirtualPageSize());

for (unsigned i = 0; i < numSections; ++i)
{
Expand All @@ -2412,7 +2413,7 @@ void * MAPMapPEFile(HANDLE hFile, off_t offset)
if ( (sectionBase < loadedHeader) // Did computing the section base overflow?
|| ((char*)sectionBase + currentHeader.SizeOfRawData < (char*)sectionBase) // Does the section overflow?
|| ((char*)sectionBase + currentHeader.SizeOfRawData > (char*)loadedHeader + virtualSize) // Does the section extend past the end of the image as the header stated?
|| (prevSectionEnd > sectionBase) // Does this section overlap the previous one?
|| (prevSectionEndAligned > sectionBase) // Does this section overlap the previous one?
)
{
ERROR_(LOADER)( "section %d is corrupt\n", i );
Expand All @@ -2435,12 +2436,12 @@ void * MAPMapPEFile(HANDLE hFile, off_t offset)
}

// Is there space between the previous section and this one? If so, add a PROT_NONE mapping to cover it.
if (prevSectionEnd < sectionBaseAligned)
if (prevSectionEndAligned < sectionBaseAligned)
{
palError = MAPRecordMapping(pFileObject,
loadedBase,
prevSectionEnd,
(char*)sectionBaseAligned - (char*)prevSectionEnd,
prevSectionEndAligned,
(char*)sectionBaseAligned - (char*)prevSectionEndAligned,
PROT_NONE);
if (NO_ERROR != palError)
{
Expand Down Expand Up @@ -2488,18 +2489,18 @@ void * MAPMapPEFile(HANDLE hFile, off_t offset)
}
#endif // _DEBUG

prevSectionEnd = ALIGN_UP((char*)sectionBase + currentHeader.SizeOfRawData, GetVirtualPageSize()); // round up to page boundary
prevSectionEndAligned = ALIGN_UP((char*)sectionBase + currentHeader.SizeOfRawData, GetVirtualPageSize()); // round up to page boundary
}

// 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.
char* imageEnd;
imageEnd = (char*)loadedBase + virtualSize; // actually, points just after the mapped end
if (prevSectionEnd < imageEnd)
if (prevSectionEndAligned < imageEnd)
{
palError = MAPRecordMapping(pFileObject,
loadedBase,
prevSectionEnd,
offset + (char*)imageEnd - (char*)prevSectionEnd,
prevSectionEndAligned,
offset + (char*)imageEnd - (char*)prevSectionEndAligned,
PROT_NONE);
if (NO_ERROR != palError)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -599,12 +599,19 @@ protected override BlobBuilder SerializeSection(string name, SectionLocation loc

if (!_target.IsWindows)
{
const int RVAAlign = 1 << RVABitsToMatchFilePos;
if (outputSectionIndex > 0)
{
sectionStartRva = Math.Max(sectionStartRva, _sectionRVAs[outputSectionIndex - 1] + _sectionRawSizes[outputSectionIndex - 1]);

// when assembly is stored in a singlefile bundle, an additional skew is introduced
// as the streams inside the bundle are not necessarily page aligned as we do not
// know the actual page size on the target system.
// We may need one page gap of unused VA space before the next section starts.
// We will assume the page size is <= RVAAlign
sectionStartRva += RVAAlign;
}

const int RVAAlign = 1 << RVABitsToMatchFilePos;
sectionStartRva = AlignmentHelper.AlignUp(sectionStartRva, RVAAlign);

int rvaAdjust = (location.PointerToRawData - sectionStartRva) & (RVAAlign - 1);
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/vm/peimagelayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ PEImageLayout* PEImageLayout::LoadConverted(PEImage* pOwner)
if (pFlat == NULL || !pFlat->CheckILOnlyFormat())
EEFileLoadException::Throw(pOwner->GetPathForErrorMessages(), COR_E_BADIMAGEFORMAT);

#ifdef TARGET_UNIX
// TODO: enable on OSX eventually
// right now we have binaries that will trigger this in a singlefile bundle.
#ifdef TARGET_LINUX
// we should not see R2R files here on Unix.
// ConvertedImageLayout may be able to handle them, but the fact that we were unable to
// load directly implies that MAPMapPEFile could not consume what crossgen produced.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,17 @@ public TargetInfo(OSPlatform? os, Architecture? arch, Version targetFrameworkVer
throw new ArgumentException($"Invalid input: Unsupported Target Framework Version {targetFrameworkVersion}");
}

if (IsLinux && Arch == Architecture.Arm64)
if (IsWindows)
{
// We align assemblies in the bundle at 4K so that we can use mmap on Linux without changing the page alignment of ARM64 R2R code.
// We align assemblies in the bundle at 4K - per requirements of memory mapping API (MapViewOfFile3, et al).
// This is only necessary for R2R assemblies, but we do it for all assemblies for simplicity.
// See https://github.com/dotnet/runtime/issues/41832.
AssemblyAlignment = 4096;
}
else if (IsWindows)
else if (Arch == Architecture.Arm64)
{
// We align assemblies in the bundle at 4K - per requirements of memory mapping API (MapViewOfFile3, et al).
// We align assemblies in the bundle at 4K so that we can use mmap on Unix without changing the page alignment of ARM64 R2R code.
// This is only necessary for R2R assemblies, but we do it for all assemblies for simplicity.
// See https://github.com/dotnet/runtime/issues/41832.
AssemblyAlignment = 4096;
}
else
Expand Down

0 comments on commit d44343b

Please sign in to comment.