// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/globals.h"
#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX) ||            \
    defined(DART_HOST_OS_MACOS)

#include "vm/virtual_memory.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>

#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
#include <sys/prctl.h>
#endif

#if defined(DART_HOST_OS_MACOS)
#include <mach/mach_error.h>
#include <mach/mach_init.h>
#include <mach/vm_map.h>
#endif

#if defined(DART_ENABLE_RX_WORKAROUNDS)
#include <dispatch/dispatch.h>
#include <dispatch/source.h>
#include <mach/mach.h>
#include <mach/mach_port.h>
#include <mach/thread_act.h>

#include "platform/syslog.h"
#include "vm/cpu.h"
#endif

#include "platform/assert.h"
#include "platform/thread_sanitizer.h"
#include "platform/utils.h"
#include "vm/heap/pages.h"
#include "vm/isolate.h"
#include "vm/virtual_memory_compressed.h"

// #define VIRTUAL_MEMORY_LOGGING 1
#if defined(VIRTUAL_MEMORY_LOGGING)
#define LOG_INFO(msg, ...) OS::PrintErr(msg, ##__VA_ARGS__)
#else
#define LOG_INFO(msg, ...)
#endif  // defined(VIRTUAL_MEMORY_LOGGING)

namespace dart {

// standard MAP_FAILED causes "error: use of old-style cast" as it
// defines MAP_FAILED as ((void *) -1)
#undef MAP_FAILED
#define MAP_FAILED reinterpret_cast<void*>(-1)

DECLARE_FLAG(bool, write_protect_code);

#if defined(DART_TARGET_OS_LINUX)
DECLARE_FLAG(bool, generate_perf_events_symbols);
DECLARE_FLAG(bool, generate_perf_jitdump);
#endif

uword VirtualMemory::page_size_ = 0;

#if defined(DART_ENABLE_RX_WORKAROUNDS)
bool VirtualMemory::should_dual_map_executable_pages_ = false;
#endif  // defined(DART_ENABLE_RX_WORKAROUNDS)

static void* Map(void* addr,
                 size_t length,
                 int prot,
                 int flags,
                 int fd,
                 off_t offset) {
  void* result = mmap(addr, length, prot, flags, fd, offset);
  int error = errno;
  LOG_INFO("mmap(%p, 0x%" Px ", %u, ...): %p\n", addr, length, prot, result);
  if ((result == MAP_FAILED) && (error != ENOMEM)) {
    const int kBufferSize = 1024;
    char error_buf[kBufferSize];
    FATAL("mmap failed: %d (%s)", error,
          Utils::StrError(error, error_buf, kBufferSize));
  }
  return result;
}

static void Unmap(uword start, uword end) {
  ASSERT(start <= end);
  uword size = end - start;
  if (size == 0) {
    return;
  }

  if (munmap(reinterpret_cast<void*>(start), size) != 0) {
    int error = errno;
    const int kBufferSize = 1024;
    char error_buf[kBufferSize];
    FATAL("munmap failed: %d (%s)", error,
          Utils::StrError(error, error_buf, kBufferSize));
  }
}

static void* GenericMapAligned(void* hint,
                               int prot,
                               intptr_t size,
                               intptr_t alignment,
                               intptr_t allocated_size,
                               int map_flags) {
#if defined(DART_HOST_OS_MACOS) && !defined(USING_THREAD_SANITIZER)
  // Allocate aligned memory in one step when possible.
  // vm_map doesn't support MAP_JIT.
  // tsan is missing an interceptor for mach_vm_map.
  if ((map_flags & MAP_JIT) == 0) {
    vm_address_t address = 0;
    vm_prot_t cur_prot = 0;
    if ((prot & PROT_READ) != 0) cur_prot |= VM_PROT_READ;
    if ((prot & PROT_WRITE) != 0) cur_prot |= VM_PROT_WRITE;
    if ((prot & PROT_EXEC) != 0) cur_prot |= VM_PROT_EXECUTE;
    vm_prot_t max_prot = VM_PROT_ALL;
    const kern_return_t result =
        vm_map(mach_task_self(), &address, size, /*mask=*/alignment - 1,
               VM_FLAGS_ANYWHERE, MEMORY_OBJECT_NULL, /*offset=*/0,
               /*copy=*/FALSE, cur_prot, max_prot, VM_INHERIT_DEFAULT);
    if (result != KERN_SUCCESS) {
      return nullptr;
    }
    return reinterpret_cast<void*>(address);
  }
#endif
  void* address = Map(hint, allocated_size, prot, map_flags, -1, 0);
  if (address == MAP_FAILED) {
    return nullptr;
  }

  const uword base = reinterpret_cast<uword>(address);
  const uword aligned_base = Utils::RoundUp(base, alignment);

  Unmap(base, aligned_base);
  Unmap(aligned_base + size, base + allocated_size);
  return reinterpret_cast<void*>(aligned_base);
}

intptr_t VirtualMemory::CalculatePageSize() {
  const intptr_t page_size = getpagesize();
  ASSERT(page_size != 0);
  ASSERT(Utils::IsPowerOfTwo(page_size));
  return page_size;
}

#if defined(DART_ENABLE_RX_WORKAROUNDS)
// The function NOTIFY_DEBUGGER_ABOUT_RX_PAGES is a hook point for the debugger.
//
// We expect that LLBD is configured to intercept calls to this function and
// takes care of writing into all pages covered by [base, base+size) address
// range.
//
// For example, you can define the following Python helper script:
//
// ```python
// # rx_helper.py
// import lldb
//
// def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
//     """Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
//     base = frame.register["x0"].GetValueAsAddress()
//     page_len = frame.register["x1"].GetValueAsUnsigned()

//     # Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
//     # first page to see if handled it correctly. This makes diagnosing
//     # misconfiguration (e.g. missing breakpoint) easier.
//     data = bytearray(page_len)
//     data[0:8] = b'IHELPED!';

//     error = lldb.SBError()
//     frame.GetThread().GetProcess().WriteMemory(base, data, error)
//     if not error.Success():
//         print(f'Failed to write into {base}[+{page_len}]', error)
//         return
//
// def __lldb_init_module(debugger: lldb.SBDebugger, _):
//     target = debugger.GetDummyTarget()
//     # Caveat: must use BreakpointCreateByRegEx here and not
//     # BreakpointCreateByName. For some reasons callback function does not
//     # get carried over from dummy target for the later.
//     bp = target.bpCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
//     bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
//     bp.SetAutoContinue(True)
//     print("-- LLDB integration loaded --")
// ```
//
// Which is then imported into LLDB via `.lldbinit` script:
//
// ```
// # .lldbinit
// command script import --relative-to-command-file rx_helper.py
// ```
//
// XCode allows configuring custom LLDB Init Files: see Product -> Scheme ->
// Run -> Info -> LLDB Init File, you can use `$(SRCROOT)/...` to place LLDB
// script inside project directory itself.
//
__attribute__((noinline)) __attribute__((visibility("default"))) extern "C" void
NOTIFY_DEBUGGER_ABOUT_RX_PAGES(void* base, size_t size) {
  // Note: need this to prevent LLVM from optimizing it away even with
  // noinline.
  asm volatile("" ::"r"(base), "r"(size) : "memory");
}

namespace {

// Handler for EXC_BAD_ACCESS which resumes the thread at the caller of the
// function (sets PC = LR and R0 = kExceptionalReturnValue). This exception
// handler is used to check if we can successfully create executable code
// dynamically: see |CheckIfRXWorks| below.
//
// Note: the handler is using Mach kernel APIs for exception handling instead
// of POSIX signals because using Mach APIs allows to intercept EXC_BAD_ACCESS
// before it stops the debugger.
class ScopedExcBadAccessHandler {
 public:
  static constexpr int32_t kExceptionalReturnValue = 0xDEADDEAD;

  ScopedExcBadAccessHandler() {
    mach_port_options_t options;
    memset(&options, 0, sizeof(options));
    options.flags = MPO_INSERT_SEND_RIGHT;

    mach_port_t exception_port = MACH_PORT_NULL;
    kern_return_t kr =
        mach_port_construct(mach_task_self(), &options, 0, &exception_port);
    RELEASE_ASSERT(kr == KERN_SUCCESS);

    dispatch_source_t source = source_ =
        dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, exception_port,
                               0, DISPATCH_TARGET_QUEUE_DEFAULT);
    RELEASE_ASSERT(source);

    // Process exceptions: ProcessMachExceptionRaiseStateMessage decodes
    // the message and forwards it to IgnoreExceptionAndReturnToCaller.
    dispatch_source_set_event_handler(source, ^{
      constexpr mach_msg_size_t kMaxMessageSize = 5 * KB;
      mach_msg_server_once(ProcessMachExceptionRaiseStateMessage,
                           kMaxMessageSize, exception_port,
                           MACH_MSG_TIMEOUT_NONE);
    });

    // When this handler is no longer needed destroy the port.
    dispatch_source_set_cancel_handler(source, ^{
      mach_port_deallocate(mach_task_self(), exception_port);
      // Note: don't capture this because it will be invalid by the time
      // cancelation handler is called.
      dispatch_release(source);
    });

    dispatch_resume(source);

    old_mask_count_ = 1;  // We expect at most one old handler.
    kern_return_t result = thread_swap_exception_ports(
        mach_thread_self(), EXC_MASK_BAD_ACCESS, exception_port,
        MACH_EXCEPTION_CODES | EXCEPTION_STATE, MACHINE_THREAD_STATE,
        &old_exception_mask_, &old_mask_count_, &old_handler_, &old_behavior_,
        &old_flavor_);
    RELEASE_ASSERT(result == KERN_SUCCESS);
    RELEASE_ASSERT(old_mask_count_ == 1);
  }

  ~ScopedExcBadAccessHandler() {
    kern_return_t result =
        thread_set_exception_ports(mach_thread_self(), old_exception_mask_,
                                   old_handler_, old_behavior_, old_flavor_);
    RELEASE_ASSERT(result == KERN_SUCCESS);
    dispatch_source_cancel(source_);
  }

 private:
  // This exception handler simply ignores the EXC_BAD_ACCESS and
  // makes the thread continue at the caller frame by setting PC to LR and
  // X0 to a special signal value.
  //
  // The signature of this handler matches |catch_exception_raise_state|.
  //
  // See https://developer.apple.com/documentation/kernel/1537255-catch_exception_raise_state
  static kern_return_t IgnoreExceptionAndReturnToCaller(
      mach_port_t exception_port,
      exception_type_t exception,
      const mach_exception_data_t code,
      mach_msg_type_number_t code_count,
      int* flavor,
      const thread_state_t old_state,
      mach_msg_type_number_t old_state_count,
      thread_state_t new_state,
      mach_msg_type_number_t* new_state_count) {
    // Copy old_state into new_state.
    memmove(new_state, old_state, sizeof(*old_state) * old_state_count);
    *new_state_count = old_state_count;

    // Update X0 and PC so that we can successfully resume execution.
    auto arm_new_state =
        reinterpret_cast<arm_unified_thread_state_t*>(new_state);
    arm_new_state->ts_64.__x[0] = kExceptionalReturnValue;
#if defined(HOST_ARCH_ARM64E)
    __darwin_arm_thread_state64_set_pc_fptr(
        arm_new_state->ts_64,
        __darwin_arm_thread_state64_get_lr_fptr(arm_new_state->ts_64));
#else
    arm_new_state->ts_64.__pc = arm_new_state->ts_64.__lr;
#endif
    return KERN_SUCCESS;
  }

  // The code in |ProcessMachExceptionRaiseStateMessage| and corresponding
  // structure definitions are based on output of the mig
  // (Mach Interface Generator, see |man mig|) applied to mach/mach_exc.defs.
  //
  // Including mig output directly is undesirable because it relies on
  // linking to exception handling routines by name (e.g. it expects
  // special symbols like mach_catch_exception_raise_state,
  // mach_catch_exception_raise_state_identity, to be defined). This might
  // make Dart VM harder to embed - as some other part of the code base might
  // want to use mig generated exception handling code and already define
  // this symbols.
  //
  // Thus we rewrite that code dropping all irrelevant bits and making the
  // code more readable.
  //
  // Request message for mach_exception_raise_state has two variadic arrays
  // inside, so we split it into two chunks each ending with a corresponding
  // variadic array.
#define TRAILING_ARRAY(Type, name, count, max_count)                           \
  Type* name() {                                                               \
    return reinterpret_cast<Type*>(this + 1);                                  \
  }                                                                            \
  bool IsValid() const {                                                       \
    return count <= max_count;                                                 \
  }                                                                            \
  mach_msg_size_t Size() const {                                               \
    return sizeof(*this) + sizeof(Type) * count;                               \
  }

  // A helper method for parsing a message which contains variadic arrays
  // inside. Such message is split into separate chunks each ending with
  // a trailing array.
  template <typename... Ts>
  static std::tuple<bool, Ts*...> ParseMessage(mach_msg_header_t* header) {
    uword current = reinterpret_cast<uword>(header);
    mach_msg_size_t remaining = header->msgh_size;
    const uword message_end = current + remaining;

    std::tuple<bool, Ts*...> result{
        true, [&current, &remaining]() -> Ts* {
          if (remaining >= sizeof(Ts)) {
            Ts* chunk = reinterpret_cast<Ts*>(current);
            const auto chunk_size = chunk->Size();
            if (chunk->IsValid() && chunk_size <= remaining) {
              current += chunk_size;
              remaining -= chunk_size;
              return chunk;
            }
          }

          // Once an error is encountered shortcut the rest of the parsing
          // by setting number of remaining bytes to 0.
          remaining = 0;
          current = 0;
          return nullptr;
        }()...};

    // If we did not fully parse the message - we have either failed or
    // we have unparsed bytes. Either case is an error.
    if (current != message_end) {
      return {false, static_cast<Ts*>(nullptr)...};
    }
    return result;
  }

#pragma pack(push, 4)
  static constexpr natural_t kMaxCodeCount = 2;
  static constexpr natural_t kMaxStateCount = 1296;

  struct RequestChunk0 {
    mach_msg_header_t Head;
    NDR_record_t NDR;
    exception_type_t exception;
    mach_msg_type_number_t code_count;  // <= kMaxCodeCount
    TRAILING_ARRAY(int64_t, code, code_count, kMaxCodeCount);
  };

  struct RequestChunk1 {
    int flavor;
    mach_msg_type_number_t old_state_count;  // <= kMaxStateCount
    TRAILING_ARRAY(natural_t, old_state, old_state_count, kMaxStateCount);
  };

  struct Reply {
    mach_msg_header_t Head;
    NDR_record_t NDR;
    kern_return_t RetCode;
    int flavor;
    mach_msg_type_number_t new_state_count;
    TRAILING_ARRAY(natural_t, new_state, new_state_count, kMaxStateCount);
  };
#pragma pack(pop)

  static boolean_t ReplyWithError(mach_msg_header_t* reply_header,
                                  kern_return_t code) {
    auto reply = reinterpret_cast<mig_reply_error_t*>(reply_header);
    reply->RetCode = code;
    reply->NDR = NDR_record;
    return FALSE;
  }

  static boolean_t ProcessMachExceptionRaiseStateMessage(
      mach_msg_header_t* request_header,
      mach_msg_header_t* reply_header) {
    reply_header->msgh_bits =
        MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(request_header->msgh_bits), 0);
    reply_header->msgh_remote_port = request_header->msgh_remote_port;
    // Minimal size: will update later if success.
    reply_header->msgh_size =
        static_cast<mach_msg_size_t>(sizeof(mig_reply_error_t));
    reply_header->msgh_local_port = MACH_PORT_NULL;
    reply_header->msgh_id = request_header->msgh_id + 100;
    reply_header->msgh_reserved = 0;

    if (request_header->msgh_id != 2406) {
      return ReplyWithError(reply_header, MIG_BAD_ID);
    }

    if (request_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
      return ReplyWithError(reply_header, MIG_BAD_ARGUMENTS);
    }

    auto [ok, req0, req1] =
        ParseMessage<RequestChunk0, RequestChunk1>(request_header);
    if (!ok) {
      return ReplyWithError(reply_header, MIG_BAD_ARGUMENTS);
    }

    auto reply = reinterpret_cast<Reply*>(reply_header);
    reply->new_state_count = kMaxStateCount;
    reply->RetCode = IgnoreExceptionAndReturnToCaller(
        request_header->msgh_local_port, req0->exception, req0->code(),
        req0->code_count, &req1->flavor, req1->old_state(),
        req1->old_state_count, reply->new_state(), &reply->new_state_count);
    if (reply->RetCode != KERN_SUCCESS) {
      return ReplyWithError(reply_header, reply->RetCode);
    }

    reply->NDR = NDR_record;
    reply->flavor = req1->flavor;
    reply->Head.msgh_size = reply->Size();
    return TRUE;
  }

  dispatch_source_t source_ = nullptr;

  // Old exception handler (e.g. one installed by the debugger or some
  // other library).
  natural_t old_mask_count_ = 0;
  exception_mask_t old_exception_mask_ = 0;
  mach_port_t old_handler_ = MACH_PORT_NULL;
  exception_behavior_t old_behavior_ = 0;
  thread_state_flavor_t old_flavor_ = 0;

  DISALLOW_COPY_AND_ASSIGN(ScopedExcBadAccessHandler);
};

// Check if we can generate machine code dynamically by creating a small
// function in memory and then trying to execute it.
//
// Returns true if that was successful.
//
// Note: we use Syslog::PrintErr below instead of OS::PrintErr to send
// output to the same location where FATAL message would be reported to if any.
bool CheckIfRXWorks() {
  // Try creating executable VirtualMemory.
  std::unique_ptr<VirtualMemory> mem{
      VirtualMemory::Allocate(VirtualMemory::PageSize(), /*is_executable=*/true,
                              /*name=*/nullptr)};
  if (mem == nullptr) {
    Syslog::PrintErr("Failed to map a test RX page");
    return false;
  }

  // Freshly created virtual memory should have signs of debugger script
  // working. See the comment above for the example of an LLDB script.
  const bool debugger_script_loaded =
      memcmp(mem->address(), "IHELPED!", 8) == 0;

  // Flip memory to RW write a simple function that computes a 32-bit integer
  // square and then flip protection back to R/RX.
  mem->Protect(VirtualMemory::kReadWrite);
  constexpr uint32_t kSquareFunctionCode[] = {
      0x1b007c00,  // mul w0, w0, w0
      0xd65f03c0   // ret
  };
  memmove(mem->address(), kSquareFunctionCode, sizeof(kSquareFunctionCode));
  VirtualMemory::WriteProtectCode(mem->address(), mem->size());

  // Get executable entry point and check that write have succeeded.
  const uword entry_point = mem->start() + mem->OffsetToExecutableAlias();
  if (memcmp(reinterpret_cast<void*>(entry_point), kSquareFunctionCode,
             sizeof(kSquareFunctionCode)) != 0) {
    Syslog::PrintErr("Failed to write executable code: code mismatch");
    return false;
  }
  CPU::FlushICache(entry_point, sizeof(kSquareFunctionCode));

  constexpr int32_t kInput = 11;
  constexpr int32_t kExpectedOutput = kInput * kInput;

  // Invoke square function and catch any potential EXC_BAD_ACCESS.
  int32_t result = 0;
  {
    ScopedExcBadAccessHandler exception_handler;
    auto square = reinterpret_cast<int32_t (*)(int32_t)>(entry_point);
    result = square(kInput);
  }

  // Validate that the code we have generated produced expected result.
  if (result != kExpectedOutput) {
    Syslog::PrintErr(
        "Failed to execute code (error: %s, debugger assist: %s)\n",
        result == ScopedExcBadAccessHandler::kExceptionalReturnValue
            ? "EXC_BAD_ACCESS"
            : "unknown",
        debugger_script_loaded ? "ok" : "not detected");
    return false;
  }

  return true;
}
}  // namespace
#endif

void VirtualMemory::Init() {
  if (FLAG_old_gen_heap_size < 0 || FLAG_old_gen_heap_size > kMaxAddrSpaceMB) {
    OS::PrintErr(
        "warning: value specified for --old_gen_heap_size %d is larger than"
        " the physically addressable range, using 0(unlimited) instead.`\n",
        FLAG_old_gen_heap_size);
    FLAG_old_gen_heap_size = 0;
  }
  if (FLAG_new_gen_semi_max_size < 0 ||
      FLAG_new_gen_semi_max_size > kMaxAddrSpaceMB) {
    OS::PrintErr(
        "warning: value specified for --new_gen_semi_max_size %d is larger"
        " than the physically addressable range, using %" Pd " instead.`\n",
        FLAG_new_gen_semi_max_size, kDefaultNewGenSemiMaxSize);
    FLAG_new_gen_semi_max_size = kDefaultNewGenSemiMaxSize;
  }
  page_size_ = CalculatePageSize();

#if defined(DART_ENABLE_RX_WORKAROUNDS)
  bool can_jit = true;
  if (IsAtLeastIOS26_0()) {
    should_dual_map_executable_pages_ = true;
    can_jit = CheckIfRXWorks();
  }
#if defined(DART_INCLUDE_SIMULATOR)
  FLAG_use_simulator = !can_jit;
  Syslog::PrintErr("Dart execution mode: %s\n",
                   FLAG_use_simulator ? "simulator" : "JIT");
#else
  if (!can_jit) {
    FATAL(
        "Unable to JIT: failed to create executable machine code dynamically "
        "due to OS restrictions");
  }
#endif
#endif

#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
  FILE* fp = fopen("/proc/sys/vm/max_map_count", "r");
  if (fp != nullptr) {
    size_t max_map_count = 0;
    int count = fscanf(fp, "%zu", &max_map_count);
    fclose(fp);
    if (count == 1) {
      size_t max_heap_pages = FLAG_old_gen_heap_size * MB / Page::kPageSize;
      if (max_map_count < max_heap_pages) {
        OS::PrintErr(
            "warning: vm.max_map_count (%zu) is not large enough to support "
            "--old_gen_heap_size=%d. Consider increasing it with `sysctl -w "
            "vm.max_map_count=%zu`\n",
            max_map_count, FLAG_old_gen_heap_size, max_heap_pages);
      }
    }
  }
#endif
}

void VirtualMemory::Cleanup() {
  page_size_ = 0;
}

VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
                                              intptr_t alignment,
                                              bool is_executable,
                                              const char* name) {
  // When FLAG_write_protect_code is active, code memory (indicated by
  // is_executable = true) is allocated as non-executable and later
  // changed to executable via VirtualMemory::Protect.
  ASSERT(Utils::IsAligned(size, PageSize()));
  ASSERT(Utils::IsPowerOfTwo(alignment));
  ASSERT(Utils::IsAligned(alignment, PageSize()));
  ASSERT(name != nullptr);

  // Ignore executable for gen_snapshot/simulator, but still let the heap
  // track code and data pages separately.
  if (!VirtualMemory::ExecutesGeneratedCode()) {
    is_executable = false;
  }

  const intptr_t allocated_size = size + alignment - PageSize();

#if defined(DART_ENABLE_RX_WORKAROUNDS)
  // We need to map the original page using RX for dual mapping to have
  // effect on iOS.
  const int prot = (is_executable && should_dual_map_executable_pages_)
                       ? PROT_READ | PROT_EXEC
                       : PROT_READ | PROT_WRITE;
#else
  const int prot =
      PROT_READ | PROT_WRITE |
      ((is_executable && !FLAG_write_protect_code) ? PROT_EXEC : 0);
#endif

  int map_flags = MAP_PRIVATE | MAP_ANONYMOUS;
#if defined(DART_HOST_OS_MACOS) && !defined(DART_HOST_OS_IOS)
  if (is_executable && !ShouldDualMapExecutablePages()) {
    map_flags |= MAP_JIT;
  }
#endif  // defined(DART_HOST_OS_MACOS) && !defined(DART_HOST_OS_IOS)

  void* hint = nullptr;
  // Some 64-bit microarchitectures store only the low 32-bits of targets as
  // part of indirect branch prediction, predicting that the target's upper bits
  // will be same as the call instruction's address. This leads to misprediction
  // for indirect calls crossing a 4GB boundary. We ask mmap to place our
  // generated code near the VM binary to avoid this.
  if (is_executable) {
    hint = reinterpret_cast<void*>(&Dart_Initialize);
  }
  void* address =
      GenericMapAligned(hint, prot, size, alignment, allocated_size, map_flags);
#if defined(DART_HOST_OS_LINUX)
  // On WSL 1 trying to allocate memory close to the binary by supplying a hint
  // fails with ENOMEM for unclear reason. Some reports suggest that this might
  // be related to the alignment of the hint but aligning it by 64Kb does not
  // make the issue go away in our experiments. Instead just retry without any
  // hint.
  if (address == nullptr && hint != nullptr &&
      Utils::IsWindowsSubsystemForLinux()) {
    address = GenericMapAligned(nullptr, prot, size, alignment, allocated_size,
                                map_flags);
  }
#endif
  if (address == nullptr) {
    return nullptr;
  }

#if defined(DART_ENABLE_RX_WORKAROUNDS)
  if (is_executable && should_dual_map_executable_pages_) {
    // |address| is mapped RX, create a corresponding RW alias through which
    // we will write into the executable mapping.
    vm_address_t writable_address = 0;
    vm_prot_t cur_protection, max_protection;
    const kern_return_t result =
        vm_remap(mach_task_self(), &writable_address, size,
                 /*mask=*/alignment - 1, VM_FLAGS_ANYWHERE, mach_task_self(),
                 reinterpret_cast<vm_address_t>(address), /*copy=*/FALSE,
                 &cur_protection, &max_protection, VM_INHERIT_NONE);
    if (result != KERN_SUCCESS) {
      munmap(address, size);
      return nullptr;
    }

    NOTIFY_DEBUGGER_ABOUT_RX_PAGES(reinterpret_cast<void*>(address), size);

    Protect(reinterpret_cast<void*>(writable_address), size, kReadWrite);

    MemoryRegion region(address, size);
    MemoryRegion writable_alias(reinterpret_cast<void*>(writable_address),
                                size);
    return new VirtualMemory(writable_alias, region, writable_alias);
  }
#endif  // defined(DART_ENABLE_RX_WORKAROUNDS)

#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
  // PR_SET_VMA was only added to mainline Linux in 5.17, and some versions of
  // the Android NDK have incorrect headers, so we manually define it if absent.
#if !defined(PR_SET_VMA)
#define PR_SET_VMA 0x53564d41
#endif
#if !defined(PR_SET_VMA_ANON_NAME)
#define PR_SET_VMA_ANON_NAME 0
#endif
  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, address, size, name);
#endif

  MemoryRegion region(reinterpret_cast<void*>(address), size);
  return new VirtualMemory(region, region);
}

VirtualMemory* VirtualMemory::Reserve(intptr_t size, intptr_t alignment) {
  ASSERT(Utils::IsAligned(size, PageSize()));
  ASSERT(Utils::IsPowerOfTwo(alignment));
  ASSERT(Utils::IsAligned(alignment, PageSize()));
  intptr_t allocated_size = size + alignment - PageSize();
  void* address =
      GenericMapAligned(nullptr, PROT_NONE, size, alignment, allocated_size,
                        MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE);
  if (address == nullptr) {
    return nullptr;
  }
  MemoryRegion region(address, size);
  return new VirtualMemory(region, region);
}

void VirtualMemory::Commit(void* address, intptr_t size) {
  ASSERT(Utils::IsAligned(address, PageSize()));
  ASSERT(Utils::IsAligned(size, PageSize()));
  void* result = mmap(address, size, PROT_READ | PROT_WRITE,
                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
  if (result == MAP_FAILED) {
    int error = errno;
    const int kBufferSize = 1024;
    char error_buf[kBufferSize];
    FATAL("Failed to commit: %d (%s)", error,
          Utils::StrError(error, error_buf, kBufferSize));
  }
}

void VirtualMemory::Decommit(void* address, intptr_t size) {
  ASSERT(Utils::IsAligned(address, PageSize()));
  ASSERT(Utils::IsAligned(size, PageSize()));
  void* result =
      mmap(address, size, PROT_NONE,
           MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED, -1, 0);
  if (result == MAP_FAILED) {
    int error = errno;
    const int kBufferSize = 1024;
    char error_buf[kBufferSize];
    FATAL("Failed to decommit: %d (%s)", error,
          Utils::StrError(error, error_buf, kBufferSize));
  }
}

VirtualMemory::~VirtualMemory() {
#if defined(DART_COMPRESSED_POINTERS)
  if (cage_ != nullptr) {
    cage_->Free(reserved_.pointer(), reserved_.size());
    return;
  }
#endif  // defined(DART_COMPRESSED_POINTERS)
  if (vm_owns_region()) {
    Unmap(reserved_.start(), reserved_.end());
#if defined(DART_ENABLE_RX_WORKAROUNDS)
    if (reserved_.start() != executable_alias_.start()) {
      Unmap(executable_alias_.start(), executable_alias_.end());
    }
#endif  // defined(DART_ENABLE_RX_WORKAROUNDS)
  }
}

bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) {
  const uword start = reinterpret_cast<uword>(address);
  Unmap(start, start + size);
  return true;
}

void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
#if defined(DEBUG)
  Thread* thread = Thread::Current();
  ASSERT(thread == nullptr || thread->IsDartMutatorThread() ||
         thread->isolate() == nullptr ||
         thread->isolate()->mutator_thread()->IsAtSafepoint());
#endif
  uword start_address = reinterpret_cast<uword>(address);
  uword end_address = start_address + size;
  uword page_address = Utils::RoundDown(start_address, PageSize());
  int prot = 0;
  switch (mode) {
    case kNoAccess:
      prot = PROT_NONE;
      break;
    case kReadOnly:
      prot = PROT_READ;
      break;
    case kReadWrite:
      prot = PROT_READ | PROT_WRITE;
      break;
    case kReadExecute:
      prot = PROT_READ | PROT_EXEC;
      break;
    case kReadWriteExecute:
      prot = PROT_READ | PROT_WRITE | PROT_EXEC;
      break;
  }
  if (mprotect(reinterpret_cast<void*>(page_address),
               end_address - page_address, prot) != 0) {
    int error = errno;
    const int kBufferSize = 1024;
    char error_buf[kBufferSize];
    LOG_INFO("mprotect(0x%" Px ", 0x%" Px ", %u) failed\n", page_address,
             end_address - page_address, prot);
    FATAL("mprotect failed: %d (%s)", error,
          Utils::StrError(error, error_buf, kBufferSize));
  }
  LOG_INFO("mprotect(0x%" Px ", 0x%" Px ", %u) ok\n", page_address,
           end_address - page_address, prot);
}

void VirtualMemory::DontNeed(void* address, intptr_t size) {
  uword start_address = reinterpret_cast<uword>(address);
  uword end_address = start_address + size;
  uword page_address = Utils::RoundDown(start_address, PageSize());
#if defined(DART_HOST_OS_MACOS)
  int advice = MADV_FREE;
#else
  int advice = MADV_DONTNEED;
#endif
  if (madvise(reinterpret_cast<void*>(page_address), end_address - page_address,
              advice) != 0) {
    int error = errno;
    const int kBufferSize = 1024;
    char error_buf[kBufferSize];
    FATAL("madvise failed: %d (%s)", error,
          Utils::StrError(error, error_buf, kBufferSize));
  }
}

#if defined(DART_HOST_OS_MACOS)
bool VirtualMemory::DuplicateRX(VirtualMemory* target) {
  const intptr_t aligned_size = Utils::RoundUp(size(), PageSize());
  ASSERT_LESS_OR_EQUAL(aligned_size, target->size());

  // Mac is special cased because iOS doesn't allow allocating new executable
  // memory, so the default approach would fail. We are allowed to make new
  // mappings of existing executable memory using vm_remap though, which is
  // effectively the same for non-writable memory.
  const mach_port_t task = mach_task_self();
  const vm_address_t source_address = reinterpret_cast<vm_address_t>(address());
  const vm_size_t mem_size = aligned_size;
  const vm_prot_t read_execute = VM_PROT_READ | VM_PROT_EXECUTE;
  vm_prot_t current_protection = read_execute;
  vm_prot_t max_protection = read_execute;
  vm_address_t target_address =
      reinterpret_cast<vm_address_t>(target->address());
  kern_return_t status = vm_remap(
      task, &target_address, mem_size,
      /*mask=*/0,
      /*flags=*/VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, task, source_address,
      /*copy=*/true, &current_protection, &max_protection,
      /*inheritance=*/VM_INHERIT_NONE);
  if (status != KERN_SUCCESS) {
    OS::PrintErr("DuplicateRX failed: %s\n", mach_error_string(status));
    return false;
  }
  ASSERT(reinterpret_cast<void*>(target_address) == target->address());
  ASSERT_EQUAL(current_protection & read_execute, read_execute);
  ASSERT_EQUAL(max_protection & read_execute, read_execute);
  return true;
}
#endif  // defined(DART_HOST_OS_MACOS)

}  // namespace dart

#endif  // defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX) ||     \
        // defined(DART_HOST_OS_MACOS)
