Skip to content

[release/6.0] Load R2R images on osx-arm64 according to Apple's guidelines #67438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6960,7 +6960,9 @@ void Compiler::impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI
//
CLANG_FORMAT_COMMENT_ANCHOR;

#ifndef OSX_ARM64_ABI
if (!opts.IsReadyToRun() || IsTargetAbi(CORINFO_CORERT_ABI))
#endif // !OSX_ARM64_ABI
{

// Reuse the temp used to pass the array dimensions to avoid bloating
Expand Down Expand Up @@ -7017,6 +7019,7 @@ void Compiler::impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI

node = gtNewHelperCallNode(CORINFO_HELP_NEW_MDARR_NONVARARG, TYP_REF, args);
}
#ifndef OSX_ARM64_ABI
else
{
//
Expand Down Expand Up @@ -7046,6 +7049,7 @@ void Compiler::impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI
}
#endif
}
#endif // !OSX_ARM64_ABI

for (GenTreeCall::Use& use : node->AsCall()->Args())
{
Expand Down
36 changes: 35 additions & 1 deletion src/coreclr/pal/src/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2045,14 +2045,48 @@ MAPmmapAndRecord(
// Mojave hardened runtime doesn't allow executable mappings of a file. So we have to create an
// anonymous mapping and read the file contents into it instead.

#if defined(HOST_ARM64)
// Set the requested mapping with forced PROT_WRITE, mmap the file, and copy its contents there.
// Once PROT_WRITE and PROT_EXEC are set together, Apple Silicon will require the use of
// PAL_JitWriteProtect to switch between executable and writable.
LPVOID pvMappedFile = mmap(NULL, len + adjust, PROT_READ, MAP_PRIVATE, fd, offset - adjust);
if (MAP_FAILED == pvMappedFile)
{
ERROR_(LOADER)("mmap failed with code %d: %s.\n", errno, strerror(errno));
palError = FILEGetLastErrorFromErrno();
}
else
{
if (-1 == mprotect(pvBaseAddress, len + adjust, prot | PROT_WRITE))
{
ERROR_(LOADER)("mprotect failed with code %d: %s.\n", errno, strerror(errno));
palError = FILEGetLastErrorFromErrno();
}
else
{
PAL_JitWriteProtect(true);
memcpy(pvBaseAddress, pvMappedFile, len + adjust);
PAL_JitWriteProtect(false);
}
if (-1 == munmap(pvMappedFile, len + adjust))
{
ERROR_(LOADER)("Unable to unmap the file. Expect trouble.\n");
if (NO_ERROR == palError)
palError = FILEGetLastErrorFromErrno();
}
}
#else
// Set the requested mapping with forced PROT_WRITE to ensure data from the file can be read there,
// read the data in and finally remove the forced PROT_WRITE
// read the data in and finally remove the forced PROT_WRITE. On Intel we can still switch the
// protection later with mprotect.
if ((mprotect(pvBaseAddress, len + adjust, prot | PROT_WRITE) == -1) ||
(pread(fd, pvBaseAddress, len + adjust, offset - adjust) == -1) ||
(((prot & PROT_WRITE) == 0) && mprotect(pvBaseAddress, len + adjust, prot) == -1))
{
palError = FILEGetLastErrorFromErrno();
}
#endif

}
else
#endif
Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14200,6 +14200,13 @@ BOOL LoadDynamicInfoEntry(Module *currentModule,
CorInfoHelpFunc corInfoHelpFunc = MapReadyToRunHelper((ReadyToRunHelper)helperNum);
if (corInfoHelpFunc != CORINFO_HELP_UNDEF)
{
#ifdef OSX_ARM64_ABI
if (corInfoHelpFunc == CORINFO_HELP_NEW_MDARR)
{
STRESS_LOG(LF_ZAP, LL_WARNING, "CORINFO_HELP_NEW_MDARR is not supported on osx-arm64\n");
return FALSE;
}
#endif // OSX_ARM64_ABI
result = (size_t)CEEJitInfo::getHelperFtnStatic(corInfoHelpFunc);
}
else
Expand Down
20 changes: 19 additions & 1 deletion src/coreclr/vm/peimagelayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,18 @@ void PEImageLayout::ApplyBaseRelocations()
// Restore the protection
if (dwOldProtection != 0)
{
#if defined(__APPLE__) && defined(HOST_ARM64)
BOOL bExecRegion = (dwOldProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0;

// Disable writing on Apple Silicon
if (bExecRegion)
PAL_JitWriteProtect(false);
#else
if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion,
dwOldProtection, &dwOldProtection))
ThrowLastError();

#endif // __APPLE__ && HOST_ARM64
dwOldProtection = 0;
}

Expand All @@ -238,14 +243,21 @@ void PEImageLayout::ApplyBaseRelocations()
#if defined(TARGET_UNIX) && !defined(CROSSGEN_COMPILE)
if (((pSection->Characteristics & VAL32(IMAGE_SCN_MEM_EXECUTE)) != 0))
{
#if defined(__APPLE__) && defined(HOST_ARM64)
// Enable writing on Apple Silicon
PAL_JitWriteProtect(true);
#else
// On SELinux, we cannot change protection that doesn't have execute access rights
// to one that has it, so we need to set the protection to RWX instead of RW
dwNewProtection = PAGE_EXECUTE_READWRITE;
#endif // __APPLE__ && HOST_ARM64
}
#endif // TARGET_UNIX && !CROSSGEN_COMPILE
#if !(defined(__APPLE__) && defined(HOST_ARM64))
if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion,
dwNewProtection, &dwOldProtection))
ThrowLastError();
#endif // !(__APPLE__ && HOST_ARM64)
#ifdef TARGET_UNIX
dwOldProtection = SectionCharacteristicsToPageProtection(pSection->Characteristics);
#endif // TARGET_UNIX
Expand Down Expand Up @@ -307,13 +319,19 @@ void PEImageLayout::ApplyBaseRelocations()
#ifndef CROSSGEN_COMPILE
if (dwOldProtection != 0)
{
#if defined(__APPLE__) && defined(HOST_ARM64)
BOOL bExecRegion = (dwOldProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0;

// Disable writing on Apple Silicon
if (bExecRegion)
PAL_JitWriteProtect(false);
#else
// Restore the protection
if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion,
dwOldProtection, &dwOldProtection))
ThrowLastError();
#endif // __APPLE__ && HOST_ARM64
}
#ifdef TARGET_UNIX
PAL_LOADMarkSectionAsNotNeeded((void*)dir);
Expand Down