//===-- mem_map_fuchsia.cpp -------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mem_map_fuchsia.h"

#include "atomic_helpers.h"
#include "common.h"
#include "string_utils.h"

#if SCUDO_FUCHSIA

#include <zircon/process.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>

namespace scudo {

static void NORETURN dieOnError(zx_status_t Status, const char *FnName,
                                uptr Size) {
  ScopedString Error;
  Error.append("SCUDO ERROR: %s failed with size %zuKB (%s)", FnName,
               Size >> 10, _zx_status_get_string(Status));
  outputRaw(Error.data());
  die();
}

static void setVmoName(zx_handle_t Vmo, const char *Name) {
  size_t Len = strlen(Name);
  DCHECK_LT(Len, ZX_MAX_NAME_LEN);
  zx_status_t Status = _zx_object_set_property(Vmo, ZX_PROP_NAME, Name, Len);
  CHECK_EQ(Status, ZX_OK);
}

// Returns the (cached) base address of the root VMAR.
static uptr getRootVmarBase() {
  static atomic_uptr CachedResult = {0};

  uptr Result = atomic_load(&CachedResult, memory_order_acquire);
  if (UNLIKELY(!Result)) {
    zx_info_vmar_t VmarInfo;
    zx_status_t Status =
        _zx_object_get_info(_zx_vmar_root_self(), ZX_INFO_VMAR, &VmarInfo,
                            sizeof(VmarInfo), nullptr, nullptr);
    CHECK_EQ(Status, ZX_OK);
    CHECK_NE(VmarInfo.base, 0);

    atomic_store(&CachedResult, VmarInfo.base, memory_order_release);
    Result = VmarInfo.base;
  }

  return Result;
}

// Lazily creates and then always returns the same zero-sized VMO.
static zx_handle_t getPlaceholderVmo() {
  static atomic_u32 StoredVmo = {ZX_HANDLE_INVALID};

  zx_handle_t Vmo = atomic_load(&StoredVmo, memory_order_acquire);
  if (UNLIKELY(Vmo == ZX_HANDLE_INVALID)) {
    // Create a zero-sized placeholder VMO.
    zx_status_t Status = _zx_vmo_create(0, 0, &Vmo);
    if (UNLIKELY(Status != ZX_OK))
      dieOnError(Status, "zx_vmo_create", 0);

    setVmoName(Vmo, "scudo:reserved");

    // Atomically store its handle. If some other thread wins the race, use its
    // handle and discard ours.
    zx_handle_t OldValue = atomic_compare_exchange_strong(
        &StoredVmo, ZX_HANDLE_INVALID, Vmo, memory_order_acq_rel);
    if (UNLIKELY(OldValue != ZX_HANDLE_INVALID)) {
      Status = _zx_handle_close(Vmo);
      CHECK_EQ(Status, ZX_OK);

      Vmo = OldValue;
    }
  }

  return Vmo;
}

MemMapFuchsia::MemMapFuchsia(uptr Base, uptr Capacity)
    : MapAddr(Base), WindowBase(Base), WindowSize(Capacity) {
  // Create the VMO.
  zx_status_t Status = _zx_vmo_create(Capacity, 0, &Vmo);
  if (UNLIKELY(Status != ZX_OK))
    dieOnError(Status, "zx_vmo_create", Capacity);
}

bool MemMapFuchsia::mapImpl(UNUSED uptr Addr, uptr Size, const char *Name,
                            uptr Flags) {
  const bool AllowNoMem = !!(Flags & MAP_ALLOWNOMEM);
  const bool PreCommit = !!(Flags & MAP_PRECOMMIT);
  const bool NoAccess = !!(Flags & MAP_NOACCESS);

  // Create the VMO.
  zx_status_t Status = _zx_vmo_create(Size, 0, &Vmo);
  if (UNLIKELY(Status != ZX_OK)) {
    if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem)
      dieOnError(Status, "zx_vmo_create", Size);
    return false;
  }

  if (Name != nullptr)
    setVmoName(Vmo, Name);

  // Map it.
  zx_vm_option_t MapFlags = ZX_VM_ALLOW_FAULTS;
  if (!NoAccess)
    MapFlags |= ZX_VM_PERM_READ | ZX_VM_PERM_WRITE;
  Status =
      _zx_vmar_map(_zx_vmar_root_self(), MapFlags, 0, Vmo, 0, Size, &MapAddr);
  if (UNLIKELY(Status != ZX_OK)) {
    if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem)
      dieOnError(Status, "zx_vmar_map", Size);

    Status = _zx_handle_close(Vmo);
    CHECK_EQ(Status, ZX_OK);

    MapAddr = 0;
    Vmo = ZX_HANDLE_INVALID;
    return false;
  }

  if (PreCommit) {
    Status = _zx_vmar_op_range(_zx_vmar_root_self(), ZX_VMAR_OP_COMMIT, MapAddr,
                               Size, nullptr, 0);
    CHECK_EQ(Status, ZX_OK);
  }

  WindowBase = MapAddr;
  WindowSize = Size;
  return true;
}

void MemMapFuchsia::unmapImpl(uptr Addr, uptr Size) {
  zx_status_t Status;

  if (Size == WindowSize) {
    // NOTE: Closing first and then unmapping seems slightly faster than doing
    // the same operations in the opposite order.
    Status = _zx_handle_close(Vmo);
    CHECK_EQ(Status, ZX_OK);
    Status = _zx_vmar_unmap(_zx_vmar_root_self(), Addr, Size);
    CHECK_EQ(Status, ZX_OK);

    MapAddr = WindowBase = WindowSize = 0;
    Vmo = ZX_HANDLE_INVALID;
  } else {
    // Unmap the subrange.
    Status = _zx_vmar_unmap(_zx_vmar_root_self(), Addr, Size);
    CHECK_EQ(Status, ZX_OK);

    // Decommit the pages that we just unmapped.
    Status = _zx_vmo_op_range(Vmo, ZX_VMO_OP_DECOMMIT, Addr - MapAddr, Size,
                              nullptr, 0);
    CHECK_EQ(Status, ZX_OK);

    if (Addr == WindowBase)
      WindowBase += Size;
    WindowSize -= Size;
  }
}

bool MemMapFuchsia::remapImpl(uptr Addr, uptr Size, const char *Name,
                              uptr Flags) {
  const bool AllowNoMem = !!(Flags & MAP_ALLOWNOMEM);
  const bool PreCommit = !!(Flags & MAP_PRECOMMIT);
  const bool NoAccess = !!(Flags & MAP_NOACCESS);

  // NOTE: This will rename the *whole* VMO, not only the requested portion of
  // it. But we cannot do better than this given the MemMap API. In practice,
  // the upper layers of Scudo always pass the same Name for a given MemMap.
  if (Name != nullptr)
    setVmoName(Vmo, Name);

  uptr MappedAddr;
  zx_vm_option_t MapFlags = ZX_VM_ALLOW_FAULTS | ZX_VM_SPECIFIC_OVERWRITE;
  if (!NoAccess)
    MapFlags |= ZX_VM_PERM_READ | ZX_VM_PERM_WRITE;
  zx_status_t Status =
      _zx_vmar_map(_zx_vmar_root_self(), MapFlags, Addr - getRootVmarBase(),
                   Vmo, Addr - MapAddr, Size, &MappedAddr);
  if (UNLIKELY(Status != ZX_OK)) {
    if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem)
      dieOnError(Status, "zx_vmar_map", Size);
    return false;
  }
  DCHECK_EQ(Addr, MappedAddr);

  if (PreCommit) {
    Status = _zx_vmar_op_range(_zx_vmar_root_self(), ZX_VMAR_OP_COMMIT, MapAddr,
                               Size, nullptr, 0);
    CHECK_EQ(Status, ZX_OK);
  }

  return true;
}

void MemMapFuchsia::releaseAndZeroPagesToOSImpl(uptr From, uptr Size) {
  zx_status_t Status = _zx_vmo_op_range(Vmo, ZX_VMO_OP_DECOMMIT, From - MapAddr,
                                        Size, nullptr, 0);
  CHECK_EQ(Status, ZX_OK);
}

void MemMapFuchsia::setMemoryPermissionImpl(uptr Addr, uptr Size, uptr Flags) {
  const bool NoAccess = !!(Flags & MAP_NOACCESS);

  zx_vm_option_t MapFlags = 0;
  if (!NoAccess)
    MapFlags |= ZX_VM_PERM_READ | ZX_VM_PERM_WRITE;
  zx_status_t Status =
      _zx_vmar_protect(_zx_vmar_root_self(), MapFlags, Addr, Size);
  CHECK_EQ(Status, ZX_OK);
}

bool ReservedMemoryFuchsia::createImpl(UNUSED uptr Addr, uptr Size,
                                       UNUSED const char *Name, uptr Flags) {
  const bool AllowNoMem = !!(Flags & MAP_ALLOWNOMEM);

  // Reserve memory by mapping the placeholder VMO without any permission.
  zx_status_t Status = _zx_vmar_map(_zx_vmar_root_self(), ZX_VM_ALLOW_FAULTS, 0,
                                    getPlaceholderVmo(), 0, Size, &Base);
  if (UNLIKELY(Status != ZX_OK)) {
    if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem)
      dieOnError(Status, "zx_vmar_map", Size);
    return false;
  }

  Capacity = Size;
  return true;
}

void ReservedMemoryFuchsia::releaseImpl() {
  zx_status_t Status = _zx_vmar_unmap(_zx_vmar_root_self(), Base, Capacity);
  CHECK_EQ(Status, ZX_OK);
}

ReservedMemoryFuchsia::MemMapT ReservedMemoryFuchsia::dispatchImpl(uptr Addr,
                                                                   uptr Size) {
  return ReservedMemoryFuchsia::MemMapT(Addr, Size);
}

} // namespace scudo

#endif // SCUDO_FUCHSIA
