Skip to content

Commit 9c81d35

Browse files
authored
[release/6.0] Load R2R images on osx-arm64 according to Apple's guidelines (#67438)
* Fix Compiler::impImportNewObjArray on osx-arm64 * Reject R2R images containing calls to CORINFO_HELP_NEW_MDARR * Load R2R images on osx-arm64 according to Apple's guidelines
1 parent 7e2e3c9 commit 9c81d35

File tree

4 files changed

+65
-2
lines changed

4 files changed

+65
-2
lines changed

src/coreclr/jit/importer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6960,7 +6960,9 @@ void Compiler::impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI
69606960
//
69616961
CLANG_FORMAT_COMMENT_ANCHOR;
69626962

6963+
#ifndef OSX_ARM64_ABI
69636964
if (!opts.IsReadyToRun() || IsTargetAbi(CORINFO_CORERT_ABI))
6965+
#endif // !OSX_ARM64_ABI
69646966
{
69656967

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

70187020
node = gtNewHelperCallNode(CORINFO_HELP_NEW_MDARR_NONVARARG, TYP_REF, args);
70197021
}
7022+
#ifndef OSX_ARM64_ABI
70207023
else
70217024
{
70227025
//
@@ -7046,6 +7049,7 @@ void Compiler::impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI
70467049
}
70477050
#endif
70487051
}
7052+
#endif // !OSX_ARM64_ABI
70497053

70507054
for (GenTreeCall::Use& use : node->AsCall()->Args())
70517055
{

src/coreclr/pal/src/map/map.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2045,14 +2045,48 @@ MAPmmapAndRecord(
20452045
// Mojave hardened runtime doesn't allow executable mappings of a file. So we have to create an
20462046
// anonymous mapping and read the file contents into it instead.
20472047

2048+
#if defined(HOST_ARM64)
2049+
// Set the requested mapping with forced PROT_WRITE, mmap the file, and copy its contents there.
2050+
// Once PROT_WRITE and PROT_EXEC are set together, Apple Silicon will require the use of
2051+
// PAL_JitWriteProtect to switch between executable and writable.
2052+
LPVOID pvMappedFile = mmap(NULL, len + adjust, PROT_READ, MAP_PRIVATE, fd, offset - adjust);
2053+
if (MAP_FAILED == pvMappedFile)
2054+
{
2055+
ERROR_(LOADER)("mmap failed with code %d: %s.\n", errno, strerror(errno));
2056+
palError = FILEGetLastErrorFromErrno();
2057+
}
2058+
else
2059+
{
2060+
if (-1 == mprotect(pvBaseAddress, len + adjust, prot | PROT_WRITE))
2061+
{
2062+
ERROR_(LOADER)("mprotect failed with code %d: %s.\n", errno, strerror(errno));
2063+
palError = FILEGetLastErrorFromErrno();
2064+
}
2065+
else
2066+
{
2067+
PAL_JitWriteProtect(true);
2068+
memcpy(pvBaseAddress, pvMappedFile, len + adjust);
2069+
PAL_JitWriteProtect(false);
2070+
}
2071+
if (-1 == munmap(pvMappedFile, len + adjust))
2072+
{
2073+
ERROR_(LOADER)("Unable to unmap the file. Expect trouble.\n");
2074+
if (NO_ERROR == palError)
2075+
palError = FILEGetLastErrorFromErrno();
2076+
}
2077+
}
2078+
#else
20482079
// Set the requested mapping with forced PROT_WRITE to ensure data from the file can be read there,
2049-
// read the data in and finally remove the forced PROT_WRITE
2080+
// read the data in and finally remove the forced PROT_WRITE. On Intel we can still switch the
2081+
// protection later with mprotect.
20502082
if ((mprotect(pvBaseAddress, len + adjust, prot | PROT_WRITE) == -1) ||
20512083
(pread(fd, pvBaseAddress, len + adjust, offset - adjust) == -1) ||
20522084
(((prot & PROT_WRITE) == 0) && mprotect(pvBaseAddress, len + adjust, prot) == -1))
20532085
{
20542086
palError = FILEGetLastErrorFromErrno();
20552087
}
2088+
#endif
2089+
20562090
}
20572091
else
20582092
#endif

src/coreclr/vm/jitinterface.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14200,6 +14200,13 @@ BOOL LoadDynamicInfoEntry(Module *currentModule,
1420014200
CorInfoHelpFunc corInfoHelpFunc = MapReadyToRunHelper((ReadyToRunHelper)helperNum);
1420114201
if (corInfoHelpFunc != CORINFO_HELP_UNDEF)
1420214202
{
14203+
#ifdef OSX_ARM64_ABI
14204+
if (corInfoHelpFunc == CORINFO_HELP_NEW_MDARR)
14205+
{
14206+
STRESS_LOG(LF_ZAP, LL_WARNING, "CORINFO_HELP_NEW_MDARR is not supported on osx-arm64\n");
14207+
return FALSE;
14208+
}
14209+
#endif // OSX_ARM64_ABI
1420314210
result = (size_t)CEEJitInfo::getHelperFtnStatic(corInfoHelpFunc);
1420414211
}
1420514212
else

src/coreclr/vm/peimagelayout.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,18 @@ void PEImageLayout::ApplyBaseRelocations()
213213
// Restore the protection
214214
if (dwOldProtection != 0)
215215
{
216+
#if defined(__APPLE__) && defined(HOST_ARM64)
216217
BOOL bExecRegion = (dwOldProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
217218
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0;
218219

220+
// Disable writing on Apple Silicon
221+
if (bExecRegion)
222+
PAL_JitWriteProtect(false);
223+
#else
219224
if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion,
220225
dwOldProtection, &dwOldProtection))
221226
ThrowLastError();
222-
227+
#endif // __APPLE__ && HOST_ARM64
223228
dwOldProtection = 0;
224229
}
225230

@@ -238,14 +243,21 @@ void PEImageLayout::ApplyBaseRelocations()
238243
#if defined(TARGET_UNIX) && !defined(CROSSGEN_COMPILE)
239244
if (((pSection->Characteristics & VAL32(IMAGE_SCN_MEM_EXECUTE)) != 0))
240245
{
246+
#if defined(__APPLE__) && defined(HOST_ARM64)
247+
// Enable writing on Apple Silicon
248+
PAL_JitWriteProtect(true);
249+
#else
241250
// On SELinux, we cannot change protection that doesn't have execute access rights
242251
// to one that has it, so we need to set the protection to RWX instead of RW
243252
dwNewProtection = PAGE_EXECUTE_READWRITE;
253+
#endif // __APPLE__ && HOST_ARM64
244254
}
245255
#endif // TARGET_UNIX && !CROSSGEN_COMPILE
256+
#if !(defined(__APPLE__) && defined(HOST_ARM64))
246257
if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion,
247258
dwNewProtection, &dwOldProtection))
248259
ThrowLastError();
260+
#endif // !(__APPLE__ && HOST_ARM64)
249261
#ifdef TARGET_UNIX
250262
dwOldProtection = SectionCharacteristicsToPageProtection(pSection->Characteristics);
251263
#endif // TARGET_UNIX
@@ -307,13 +319,19 @@ void PEImageLayout::ApplyBaseRelocations()
307319
#ifndef CROSSGEN_COMPILE
308320
if (dwOldProtection != 0)
309321
{
322+
#if defined(__APPLE__) && defined(HOST_ARM64)
310323
BOOL bExecRegion = (dwOldProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
311324
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0;
312325

326+
// Disable writing on Apple Silicon
327+
if (bExecRegion)
328+
PAL_JitWriteProtect(false);
329+
#else
313330
// Restore the protection
314331
if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion,
315332
dwOldProtection, &dwOldProtection))
316333
ThrowLastError();
334+
#endif // __APPLE__ && HOST_ARM64
317335
}
318336
#ifdef TARGET_UNIX
319337
PAL_LOADMarkSectionAsNotNeeded((void*)dir);

0 commit comments

Comments
 (0)