// 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.

#ifndef RUNTIME_VM_VIRTUAL_MEMORY_H_
#define RUNTIME_VM_VIRTUAL_MEMORY_H_

#include "platform/utils.h"
#include "vm/flags.h"
#include "vm/globals.h"
#include "vm/memory_region.h"

#if defined(DART_HOST_OS_FUCHSIA)
#include <zircon/types.h>
#endif

namespace dart {

#if defined(DART_HOST_OS_IOS) && !defined(DART_PRECOMPILED_RUNTIME) &&         \
    !defined(DART_HOST_OS_SIMULATOR)
// We might need RX workarounds to enable JIT on physical iOS devices.
//
// Older iOS versions allow mprotect to flip between RW <-> RX on code
// pages as long as debugger is connected to the process.
//
// Newever iOS versions do not allow that, but we have discovered that
// dual mapping RX mapping as RW mapping via |vm_remap| and touching original RX
// mapping from the debugger allows us to write code via RW page and then
// execute it via original RX page.
//
// Thus our RX workarounds consist of two parts:
//
// * Dual mapping of executable pages (see ShouldDualMapExecutablePages and
//   OffsetToExecutableAlias).
// * Debugger integration point (see NOTIFY_DEBUGGER_ABOUT_RX_PAGES).
//
// Note: we only use this on newer iOS versions because dual mapping causes
// kernel crashes on M4 Mac OS X devices.
#define DART_ENABLE_RX_WORKAROUNDS
#endif

class Cage;

class VirtualMemory {
 public:
  enum Protection {
    kNoAccess,
    kReadOnly,
    kReadWrite,
    kReadExecute,
    kReadWriteExecute
  };

  // The reserved memory is unmapped on destruction.
  ~VirtualMemory();

  uword start() const { return region_.start(); }
  uword end() const { return region_.end(); }
  void* address() const { return region_.pointer(); }
  intptr_t size() const { return region_.size(); }

  DART_FORCE_INLINE intptr_t OffsetToExecutableAlias() const {
#if defined(DART_ENABLE_RX_WORKAROUNDS)
    return executable_alias_.start() - region_.start();
#else
    return 0;
#endif
  }

  static void Init();
  static void Cleanup();

  DART_FORCE_INLINE static bool ShouldDualMapExecutablePages() {
#if defined(DART_ENABLE_RX_WORKAROUNDS)
    return should_dual_map_executable_pages_;
#else
    return false;
#endif
  }

  DART_FORCE_INLINE static bool ExecutesGeneratedCode() {
#if defined(DART_PRECOMPILER) && !defined(TESTING)
    return false;  // I.e., gen_snapshot.
#else
    return true;
#endif
  }

  // Write protect a chunk of machine code which is currently writable.
  DART_FORCE_INLINE static void WriteProtectCode(void* address, intptr_t size) {
    Protect(address, size,
            ShouldDualMapExecutablePages() || !ExecutesGeneratedCode()
                ? kReadOnly
                : kReadExecute);
  }
  DART_FORCE_INLINE void WriteProtectCode() const {
    WriteProtectCode(address(), size());
  }

  bool Contains(uword addr) const { return region_.Contains(addr); }

  // Changes the protection of the virtual memory area.
  static void Protect(void* address, intptr_t size, Protection mode);
  void Protect(Protection mode) { return Protect(address(), size(), mode); }

  static void DontNeed(void* address, intptr_t size);

  // Reserves and commits a virtual memory segment with size. If a segment of
  // the requested size cannot be allocated, nullptr is returned.
  static VirtualMemory* Allocate(intptr_t size,
                                 bool is_executable,
                                 const char* name) {
    return AllocateAligned(size, PageSize(), is_executable, name);
  }
  static VirtualMemory* AllocateAligned(intptr_t size,
                                        intptr_t alignment,
                                        bool is_executable,
                                        const char* name);

  // Duplicates `this` memory into the `target` memory using Mach specific
  // vm_remap call.
  //
  // This exists specifically to clone executable pages originating from
  // codesigned binaries on iOS and Mac OS X.
  //
  // IMPORTANT: using this to remap unsigned RX pages results in kernel
  // crashes in certain combinations of hardware and kernel version and thus
  // should be avoided.
  //
  // Assumes
  //   * `this` has RX protection and is codesigned.
  //   * `target` has RW protection, and is at least as large as `this`.
#if defined(DART_HOST_OS_MACOS)
  bool DuplicateRX(VirtualMemory* target);
#endif  // defined(DART_HOST_OS_MACOS)

  // Returns the cached page size. Use only if Init() has been called.
  static intptr_t PageSize() {
    ASSERT(page_size_ != 0);
    return page_size_;
  }

  static bool InSamePage(uword address0, uword address1);

  // Truncate this virtual memory segment.
  void Truncate(intptr_t new_size);

  // False for a part of a snapshot added directly to the Dart heap, which
  // belongs to the embedder and must not be deallocated or have its
  // protection status changed by the VM.
  bool vm_owns_region() const { return reserved_.pointer() != nullptr; }

#if defined(DART_COMPRESSED_POINTERS)
  bool InCage() const { return cage_ != nullptr; }
#else
  bool InCage() const { return false; }
#endif

  static VirtualMemory* ForImagePage(void* pointer, uword size);
  static VirtualMemory* Adopt(void* pointer, uword size);

 private:
  static intptr_t CalculatePageSize();

  // Free a sub segment. On operating systems that support it this
  // can give back the virtual memory to the system. Returns true on success.
  static bool FreeSubSegment(void* address, intptr_t size);

  static VirtualMemory* Reserve(intptr_t size, intptr_t alignment);
  static void Commit(void* address, intptr_t size);
  static void Decommit(void* address, intptr_t size);

#if defined(DART_ENABLE_RX_WORKAROUNDS)
  // These constructors are only used internally when reserving new virtual
  // spaces. They do not reserve any virtual address space on their own.
  VirtualMemory(const MemoryRegion& region,
                const MemoryRegion& executable_alias,
                const MemoryRegion& reserved)
      : region_(region),
        executable_alias_(executable_alias),
        reserved_(reserved) {}
#endif

  VirtualMemory(const MemoryRegion& region, const MemoryRegion& reserved)
      : region_(region),
#if defined(DART_ENABLE_RX_WORKAROUNDS)
        executable_alias_(region),
#endif
        reserved_(reserved) {
  }

#if defined(DART_COMPRESSED_POINTERS)
  VirtualMemory(const MemoryRegion& region,
                const MemoryRegion& reserved,
                Cage* cage)
      : region_(region),
#if defined(DART_ENABLE_RX_WORKAROUNDS)
        executable_alias_(region),
#endif
        reserved_(reserved),
        cage_(cage) {
  }
#endif

  MemoryRegion region_;

#if defined(DART_ENABLE_RX_WORKAROUNDS)
  // For dual mapped RW+RX pages this will contain address of the executable
  // alias. Objects will be allocated in the writable mapping but entry points
  // will point into executable (RX) alias.
  MemoryRegion executable_alias_;
#endif

  // The underlying reservation not yet given back to the OS.
  // Its address might disagree with region_ due to aligned allocations.
  // Its size might disagree with region_ due to Truncate.
  MemoryRegion reserved_;

#if defined(DART_COMPRESSED_POINTERS)
  Cage* cage_ = nullptr;
#endif

  static uword page_size_;

#if defined(DART_ENABLE_RX_WORKAROUNDS)
  static bool should_dual_map_executable_pages_;
#endif

  friend class Cage;
  DISALLOW_IMPLICIT_CONSTRUCTORS(VirtualMemory);
};

}  // namespace dart

#endif  // RUNTIME_VM_VIRTUAL_MEMORY_H_
