Use MAP_JIT when doing an mmap for executable pages (needed for macOS Catalina).
Please refer to https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-jit for more details. This is the Dart VM part for https://github.com/flutter/flutter/issues/36714 Change-Id: Ifbc0ce82921d5f05421e01ce2d19423a5f3e32f9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112849 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Siva Annamalai <asiva@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
f87237c4e4
commit
ec2d06d4b9
@@ -7,6 +7,9 @@
|
||||
|
||||
#include "platform/utils.h"
|
||||
|
||||
#include <errno.h> // NOLINT
|
||||
#include <sys/utsname.h> // NOLINT
|
||||
|
||||
namespace dart {
|
||||
|
||||
char* Utils::StrNDup(const char* s, intptr_t n) {
|
||||
@@ -64,6 +67,76 @@ int Utils::VSNPrint(char* str, size_t size, const char* format, va_list args) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Returns the running system's Darwin major version. Don't call this, it's
|
||||
// an implementation detail and its result is meant to be cached by
|
||||
// MacOSXMinorVersion.
|
||||
int32_t DarwinMajorVersionInternal() {
|
||||
// uname is implemented as a simple series of sysctl system calls to
|
||||
// obtain the relevant data from the kernel. The data is
|
||||
// compiled right into the kernel, so no threads or blocking or other
|
||||
// funny business is necessary.
|
||||
|
||||
struct utsname uname_info;
|
||||
if (uname(&uname_info) != 0) {
|
||||
FATAL("Fatal error in DarwinMajorVersionInternal : invalid return uname");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(uname_info.sysname, "Darwin") != 0) {
|
||||
FATAL1(
|
||||
"Fatal error in DarwinMajorVersionInternal : unexpected uname"
|
||||
" sysname '%s'",
|
||||
uname_info.sysname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t darwin_major_version = 0;
|
||||
char* dot = strchr(uname_info.release, '.');
|
||||
if (dot) {
|
||||
errno = 0;
|
||||
char* end_ptr = NULL;
|
||||
darwin_major_version = strtol(uname_info.release, &end_ptr, 10);
|
||||
if (errno != 0 || (end_ptr == uname_info.release)) {
|
||||
dot = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dot) {
|
||||
FATAL1(
|
||||
"Fatal error in DarwinMajorVersionInternal :"
|
||||
" could not parse uname release '%s'",
|
||||
uname_info.release);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return darwin_major_version;
|
||||
}
|
||||
|
||||
// Returns the running system's Mac OS X minor version. This is the |y| value
|
||||
// in 10.y or 10.y.z. Don't call this, it's an implementation detail and the
|
||||
// result is meant to be cached by MacOSXMinorVersion.
|
||||
int32_t MacOSXMinorVersionInternal() {
|
||||
int darwin_major_version = DarwinMajorVersionInternal();
|
||||
|
||||
// The Darwin major version is always 4 greater than the Mac OS X minor
|
||||
// version for Darwin versions beginning with 6, corresponding to Mac OS X
|
||||
// 10.2. Since this correspondence may change in the future, warn when
|
||||
// encountering a version higher than anything seen before. Older Darwin
|
||||
// versions, or versions that can't be determined, result in
|
||||
// immediate death.
|
||||
ASSERT(darwin_major_version >= 6);
|
||||
return (darwin_major_version - 4);
|
||||
}
|
||||
|
||||
int32_t MacOSXMinorVersion() {
|
||||
static int mac_os_x_minor_version = MacOSXMinorVersionInternal();
|
||||
return mac_os_x_minor_version;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace dart
|
||||
|
||||
#endif // defined(HOST_OS_MACOS)
|
||||
|
||||
@@ -5,10 +5,71 @@
|
||||
#ifndef RUNTIME_PLATFORM_UTILS_MACOS_H_
|
||||
#define RUNTIME_PLATFORM_UTILS_MACOS_H_
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <libkern/OSByteOrder.h> // NOLINT
|
||||
|
||||
namespace dart {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Returns the system's Mac OS X minor version. This is the |y| value
|
||||
// in 10.y or 10.y.z.
|
||||
int32_t MacOSXMinorVersion();
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Run-time OS version checks.
|
||||
#define DEFINE_IS_OS_FUNCS(V, TEST_DEPLOYMENT_TARGET) \
|
||||
inline bool IsOS10_##V() { \
|
||||
TEST_DEPLOYMENT_TARGET(>, V, false) \
|
||||
return internal::MacOSXMinorVersion() == V; \
|
||||
} \
|
||||
inline bool IsAtLeastOS10_##V() { \
|
||||
TEST_DEPLOYMENT_TARGET(>=, V, true) \
|
||||
return internal::MacOSXMinorVersion() >= V; \
|
||||
} \
|
||||
inline bool IsAtMostOS10_##V() { \
|
||||
TEST_DEPLOYMENT_TARGET(>, V, false) \
|
||||
return internal::MacOSXMinorVersion() <= V; \
|
||||
}
|
||||
|
||||
#define TEST_DEPLOYMENT_TARGET(OP, V, RET) \
|
||||
if (MAC_OS_X_VERSION_MIN_REQUIRED OP MAC_OS_X_VERSION_10_##V) return RET;
|
||||
#define IGNORE_DEPLOYMENT_TARGET(OP, V, RET)
|
||||
|
||||
DEFINE_IS_OS_FUNCS(9, TEST_DEPLOYMENT_TARGET)
|
||||
DEFINE_IS_OS_FUNCS(10, TEST_DEPLOYMENT_TARGET)
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_11
|
||||
DEFINE_IS_OS_FUNCS(11, TEST_DEPLOYMENT_TARGET)
|
||||
#else
|
||||
DEFINE_IS_OS_FUNCS(11, IGNORE_DEPLOYMENT_TARGET)
|
||||
#endif
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_12
|
||||
DEFINE_IS_OS_FUNCS(12, TEST_DEPLOYMENT_TARGET)
|
||||
#else
|
||||
DEFINE_IS_OS_FUNCS(12, IGNORE_DEPLOYMENT_TARGET)
|
||||
#endif
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_13
|
||||
DEFINE_IS_OS_FUNCS(13, TEST_DEPLOYMENT_TARGET)
|
||||
#else
|
||||
DEFINE_IS_OS_FUNCS(13, IGNORE_DEPLOYMENT_TARGET)
|
||||
#endif
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_14
|
||||
DEFINE_IS_OS_FUNCS(14, TEST_DEPLOYMENT_TARGET)
|
||||
#else
|
||||
DEFINE_IS_OS_FUNCS(14, IGNORE_DEPLOYMENT_TARGET)
|
||||
#endif
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
DEFINE_IS_OS_FUNCS(15, TEST_DEPLOYMENT_TARGET)
|
||||
#else
|
||||
DEFINE_IS_OS_FUNCS(15, IGNORE_DEPLOYMENT_TARGET)
|
||||
#endif
|
||||
|
||||
inline int Utils::CountLeadingZeros(uword x) {
|
||||
#if defined(ARCH_IS_32_BIT)
|
||||
return __builtin_clzl(x);
|
||||
|
||||
@@ -194,6 +194,8 @@ VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
|
||||
// The mapping will be RX and stays that way until it will eventually be
|
||||
// unmapped.
|
||||
MemoryRegion region(region_ptr, size);
|
||||
// DUAL_MAPPING_SUPPORTED is false in TARGET_OS_MACOS and hence support
|
||||
// for MAP_JIT is not required here.
|
||||
const int alias_prot = PROT_READ | PROT_EXEC;
|
||||
void* alias_ptr =
|
||||
MapAligned(fd, alias_prot, size, alignment, allocated_size);
|
||||
@@ -211,8 +213,13 @@ VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
|
||||
const int prot =
|
||||
PROT_READ | PROT_WRITE |
|
||||
((is_executable && !FLAG_write_protect_code) ? PROT_EXEC : 0);
|
||||
void* address =
|
||||
mmap(NULL, allocated_size, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
int map_flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||
#if defined(HOST_OS_MACOS)
|
||||
if (IsAtLeastOS10_14()) {
|
||||
map_flags |= MAP_JIT;
|
||||
}
|
||||
#endif // defined(HOST_OS_MACOS)
|
||||
void* address = mmap(NULL, allocated_size, prot, map_flags, -1, 0);
|
||||
LOG_INFO("mmap(NULL, 0x%" Px ", %u, ...): %p\n", allocated_size, prot,
|
||||
address);
|
||||
if (address == MAP_FAILED) {
|
||||
|
||||
Reference in New Issue
Block a user