From 0d928aeb87aadba32c097488103633edf3479c91 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Tue, 3 May 2022 13:56:57 -0700 Subject: [PATCH 1/4] Same alignment in the bundle on OSX as on Linux --- .../Microsoft.NET.HostModel/Bundle/TargetInfo.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs b/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs index 49313415c8e36..b29a102bf6e59 100644 --- a/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs +++ b/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs @@ -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 From 14aae0c5cf5ac5d18b7d87d48593256df6971cdc Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Tue, 3 May 2022 16:41:28 -0700 Subject: [PATCH 2/4] Extra VA gap between section in casse we run from sf bundle --- .../ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs index 608e159f7f6e3..5d8cdc4c3cb58 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs @@ -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); From 1426d16daf87f87323b111f1a382dece87400392 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Tue, 3 May 2022 16:42:33 -0700 Subject: [PATCH 3/4] Rename prevSectionEnd -> prevSectionEndAligned and make it aligned. --- src/coreclr/pal/src/map/map.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/coreclr/pal/src/map/map.cpp b/src/coreclr/pal/src/map/map.cpp index 891c978ddeed1..55b6aa3fecf0e 100644 --- a/src/coreclr/pal/src/map/map.cpp +++ b/src/coreclr/pal/src/map/map.cpp @@ -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) { @@ -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 ); @@ -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) { @@ -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) { From b8e8cae1885f415771430a707fc4b1aaa48f67b1 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Tue, 3 May 2022 16:55:24 -0700 Subject: [PATCH 4/4] Suppress assert for now on OSX --- src/coreclr/vm/peimagelayout.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/peimagelayout.cpp b/src/coreclr/vm/peimagelayout.cpp index a4b034da2faf8..d2e2482d002e2 100644 --- a/src/coreclr/vm/peimagelayout.cpp +++ b/src/coreclr/vm/peimagelayout.cpp @@ -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.