未验证 提交 64096424 编写于 作者: J Jonathan Giannuzzi 提交者: GitHub

Load R2R images on osx-arm64 according to Apple's guidelines (#67118)

* Load R2R images on osx-arm64 according to Apple's guidelines

* Address review comments

* use MAP_PRIVATE for the mapped file
* correct the condition

* Use PAL_JitWriteProtect once per relocation

* Flush instruction cache during relocation on Apple Silicon

* Fix typo in comment

* Use PAL_JitWriteProtect in the same spots where protection is toggled

This allows to keep the instruction cache flush logic identical between platforms.

* Revert the change for Intel to avoid any regression

* Always unmap the file to avoid leaks + log errors
上级 09d83464
......@@ -2041,14 +2041,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_WRITE) == -1) ||
(pread(fd, pvBaseAddress, len + adjust, offset - adjust) == -1) ||
(mprotect(pvBaseAddress, len + adjust, prot) == -1))
{
palError = FILEGetLastErrorFromErrno();
}
#endif
}
else
#endif
......
......@@ -229,10 +229,18 @@ void PEImageLayout::ApplyBaseRelocations(bool relocationMustWriteCopy)
// 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;
}
......@@ -251,8 +259,9 @@ void PEImageLayout::ApplyBaseRelocations(bool relocationMustWriteCopy)
#if defined(TARGET_UNIX)
if (((pSection->Characteristics & VAL32(IMAGE_SCN_MEM_EXECUTE)) != 0))
{
#ifdef __APPLE__
dwNewProtection = PAGE_READWRITE;
#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
......@@ -260,9 +269,11 @@ void PEImageLayout::ApplyBaseRelocations(bool relocationMustWriteCopy)
#endif
}
#endif // TARGET_UNIX
#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
......@@ -323,13 +334,19 @@ void PEImageLayout::ApplyBaseRelocations(bool relocationMustWriteCopy)
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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册