//===-- sanitizer_fuchsia.cc ---------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and other sanitizer
// run-time libraries and implements Fuchsia-specific functions from
// sanitizer_common.h.
//===---------------------------------------------------------------------===//

#include "sanitizer_fuchsia.h"
#if SANITIZER_FUCHSIA

#include "sanitizer_common.h"
#include "sanitizer_libc.h"
#include "sanitizer_mutex.h"
#include "sanitizer_stacktrace.h"

#include <limits.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <unwind.h>
#include <zircon/errors.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>

namespace __sanitizer {

void NORETURN internal__exit(int exitcode) { _zx_process_exit(exitcode); }

uptr internal_sched_yield() {
  zx_status_t status = _zx_nanosleep(0);
  CHECK_EQ(status, ZX_OK);
  return 0;  // Why doesn't this return void?
}

static void internal_nanosleep(zx_time_t ns) {
  zx_status_t status = _zx_nanosleep(_zx_deadline_after(ns));
  CHECK_EQ(status, ZX_OK);
}

unsigned int internal_sleep(unsigned int seconds) {
  internal_nanosleep(ZX_SEC(seconds));
  return 0;
}

u64 NanoTime() { return _zx_time_get(ZX_CLOCK_UTC); }

uptr internal_getpid() {
  zx_info_handle_basic_t info;
  zx_status_t status =
      _zx_object_get_info(_zx_process_self(), ZX_INFO_HANDLE_BASIC, &info,
                          sizeof(info), NULL, NULL);
  CHECK_EQ(status, ZX_OK);
  uptr pid = static_cast<uptr>(info.koid);
  CHECK_EQ(pid, info.koid);
  return pid;
}

uptr GetThreadSelf() { return reinterpret_cast<uptr>(thrd_current()); }

uptr GetTid() { return GetThreadSelf(); }

void Abort() { abort(); }

int Atexit(void (*function)(void)) { return atexit(function); }

void SleepForSeconds(int seconds) { internal_sleep(seconds); }

void SleepForMillis(int millis) { internal_nanosleep(ZX_MSEC(millis)); }

void GetThreadStackTopAndBottom(bool, uptr *stack_top, uptr *stack_bottom) {
  pthread_attr_t attr;
  CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
  void *base;
  size_t size;
  CHECK_EQ(pthread_attr_getstack(&attr, &base, &size), 0);
  CHECK_EQ(pthread_attr_destroy(&attr), 0);

  *stack_bottom = reinterpret_cast<uptr>(base);
  *stack_top = *stack_bottom + size;
}

void MaybeReexec() {}
void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {}
void DisableCoreDumperIfNecessary() {}
void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
void StartReportDeadlySignal() {}
void ReportDeadlySignal(const SignalContext &sig, u32 tid,
                        UnwindSignalStackCallbackType unwind,
                        const void *unwind_context) {}
void SetAlternateSignalStack() {}
void UnsetAlternateSignalStack() {}
void InitTlsSize() {}

void PrintModuleMap() {}

bool SignalContext::IsStackOverflow() const { return false; }
void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); }
const char *SignalContext::Describe() const { UNIMPLEMENTED(); }

struct UnwindTraceArg {
  BufferedStackTrace *stack;
  u32 max_depth;
};

_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
  UnwindTraceArg *arg = static_cast<UnwindTraceArg *>(param);
  CHECK_LT(arg->stack->size, arg->max_depth);
  uptr pc = _Unwind_GetIP(ctx);
  if (pc < PAGE_SIZE) return _URC_NORMAL_STOP;
  arg->stack->trace_buffer[arg->stack->size++] = pc;
  return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP
                                             : _URC_NO_REASON);
}

void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
  CHECK_GE(max_depth, 2);
  size = 0;
  UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};
  _Unwind_Backtrace(Unwind_Trace, &arg);
  CHECK_GT(size, 0);
  // We need to pop a few frames so that pc is on top.
  uptr to_pop = LocatePcInTrace(pc);
  // trace_buffer[0] belongs to the current function so we always pop it,
  // unless there is only 1 frame in the stack trace (1 frame is always better
  // than 0!).
  PopStackFrames(Min(to_pop, static_cast<uptr>(1)));
  trace_buffer[0] = pc;
}

void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
                                                    u32 max_depth) {
  CHECK_NE(context, nullptr);
  UNREACHABLE("signal context doesn't exist");
}

enum MutexState : int { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 };

BlockingMutex::BlockingMutex() {
  // NOTE!  It's important that this use internal_memset, because plain
  // memset might be intercepted (e.g., actually be __asan_memset).
  // Defining this so the compiler initializes each field, e.g.:
  //   BlockingMutex::BlockingMutex() : BlockingMutex(LINKER_INITIALIZED) {}
  // might result in the compiler generating a call to memset, which would
  // have the same problem.
  internal_memset(this, 0, sizeof(*this));
}

void BlockingMutex::Lock() {
  CHECK_EQ(owner_, 0);
  atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
  if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked)
    return;
  while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) {
    zx_status_t status = _zx_futex_wait(reinterpret_cast<zx_futex_t *>(m),
                                        MtxSleeping, ZX_TIME_INFINITE);
    if (status != ZX_ERR_BAD_STATE)  // Normal race.
      CHECK_EQ(status, ZX_OK);
  }
}

void BlockingMutex::Unlock() {
  atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
  u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release);
  CHECK_NE(v, MtxUnlocked);
  if (v == MtxSleeping) {
    zx_status_t status = _zx_futex_wake(reinterpret_cast<zx_futex_t *>(m), 1);
    CHECK_EQ(status, ZX_OK);
  }
}

void BlockingMutex::CheckLocked() {
  atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
  CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed));
}

uptr GetPageSize() { return PAGE_SIZE; }

uptr GetMmapGranularity() { return PAGE_SIZE; }

sanitizer_shadow_bounds_t ShadowBounds;

uptr GetMaxVirtualAddress() {
  ShadowBounds = __sanitizer_shadow_bounds();
  return ShadowBounds.memory_limit - 1;
}

static void *DoAnonymousMmapOrDie(uptr size, const char *mem_type,
                                  bool raw_report, bool die_for_nomem) {
  size = RoundUpTo(size, PAGE_SIZE);

  zx_handle_t vmo;
  zx_status_t status = _zx_vmo_create(size, 0, &vmo);
  if (status != ZX_OK) {
    if (status != ZX_ERR_NO_MEMORY || die_for_nomem)
      ReportMmapFailureAndDie(size, mem_type, "zx_vmo_create", status,
                              raw_report);
    return nullptr;
  }
  _zx_object_set_property(vmo, ZX_PROP_NAME, mem_type,
                          internal_strlen(mem_type));

  // TODO(mcgrathr): Maybe allocate a VMAR for all sanitizer heap and use that?
  uintptr_t addr;
  status = _zx_vmar_map(_zx_vmar_root_self(), 0, vmo, 0, size,
                        ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE, &addr);
  _zx_handle_close(vmo);

  if (status != ZX_OK) {
    if (status != ZX_ERR_NO_MEMORY || die_for_nomem)
      ReportMmapFailureAndDie(size, mem_type, "zx_vmar_map", status,
                              raw_report);
    return nullptr;
  }

  IncreaseTotalMmap(size);

  return reinterpret_cast<void *>(addr);
}

void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {
  return DoAnonymousMmapOrDie(size, mem_type, raw_report, true);
}

void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
  return MmapOrDie(size, mem_type);
}

void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
  return DoAnonymousMmapOrDie(size, mem_type, false, false);
}

uptr ReservedAddressRange::Init(uptr init_size, const char* name,
                                uptr fixed_addr) {
  base_ = MmapNoAccess(init_size);
  size_ = init_size;
  name_ = name;
  return reinterpret_cast<uptr>(base_);
}

// Uses fixed_addr for now.
// Will use offset instead once we've implemented this function for real.
uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size,
                               bool tolerate_enomem) {
  return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, map_size));
}

void ReservedAddressRange::Unmap(uptr addr, uptr size) {
  void* addr_as_void = reinterpret_cast<void*>(addr);
  uptr base_as_uptr = reinterpret_cast<uptr>(base_);
  // Only unmap at the beginning or end of the range.
  CHECK((addr_as_void == base_) || (addr + size == base_as_uptr + size_));
  CHECK_LE(size, size_);
  UnmapOrDie(reinterpret_cast<void*>(addr), size);
}

// MmapNoAccess and MmapFixedOrDie are used only by sanitizer_allocator.
// Instead of doing exactly what they say, we make MmapNoAccess actually
// just allocate a VMAR to reserve the address space.  Then MmapFixedOrDie
// uses that VMAR instead of the root.

zx_handle_t allocator_vmar = ZX_HANDLE_INVALID;
uintptr_t allocator_vmar_base;
size_t allocator_vmar_size;

void *MmapNoAccess(uptr size) {
  size = RoundUpTo(size, PAGE_SIZE);
  CHECK_EQ(allocator_vmar, ZX_HANDLE_INVALID);
  uintptr_t base;
  zx_status_t status =
      _zx_vmar_allocate(_zx_vmar_root_self(), 0, size,
                        ZX_VM_FLAG_CAN_MAP_READ | ZX_VM_FLAG_CAN_MAP_WRITE |
                            ZX_VM_FLAG_CAN_MAP_SPECIFIC,
                        &allocator_vmar, &base);
  if (status != ZX_OK)
    ReportMmapFailureAndDie(size, "sanitizer allocator address space",
                            "zx_vmar_allocate", status);

  allocator_vmar_base = base;
  allocator_vmar_size = size;
  return reinterpret_cast<void *>(base);
}

constexpr const char kAllocatorVmoName[] = "sanitizer_allocator";

static void *DoMmapFixedOrDie(uptr fixed_addr, uptr size, bool die_for_nomem) {
  size = RoundUpTo(size, PAGE_SIZE);

  zx_handle_t vmo;
  zx_status_t status = _zx_vmo_create(size, 0, &vmo);
  if (status != ZX_OK) {
    if (status != ZX_ERR_NO_MEMORY || die_for_nomem)
      ReportMmapFailureAndDie(size, kAllocatorVmoName, "zx_vmo_create", status);
    return nullptr;
  }
  _zx_object_set_property(vmo, ZX_PROP_NAME, kAllocatorVmoName,
                          sizeof(kAllocatorVmoName) - 1);

  DCHECK_GE(fixed_addr, allocator_vmar_base);
  uintptr_t offset = fixed_addr - allocator_vmar_base;
  DCHECK_LE(size, allocator_vmar_size);
  DCHECK_GE(allocator_vmar_size - offset, size);

  uintptr_t addr;
  status = _zx_vmar_map(
      allocator_vmar, offset, vmo, 0, size,
      ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE | ZX_VM_FLAG_SPECIFIC,
      &addr);
  _zx_handle_close(vmo);
  if (status != ZX_OK) {
    if (status != ZX_ERR_NO_MEMORY || die_for_nomem)
      ReportMmapFailureAndDie(size, kAllocatorVmoName, "zx_vmar_map", status);
    return nullptr;
  }

  IncreaseTotalMmap(size);

  return reinterpret_cast<void *>(addr);
}

void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
  return DoMmapFixedOrDie(fixed_addr, size, true);
}

void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) {
  return DoMmapFixedOrDie(fixed_addr, size, false);
}

// This should never be called.
void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) {
  UNIMPLEMENTED();
}

void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
                                   const char *mem_type) {
  CHECK_GE(size, PAGE_SIZE);
  CHECK(IsPowerOfTwo(size));
  CHECK(IsPowerOfTwo(alignment));

  zx_handle_t vmo;
  zx_status_t status = _zx_vmo_create(size, 0, &vmo);
  if (status != ZX_OK) {
    if (status != ZX_ERR_NO_MEMORY)
      ReportMmapFailureAndDie(size, mem_type, "zx_vmo_create", status, false);
    return nullptr;
  }
  _zx_object_set_property(vmo, ZX_PROP_NAME, mem_type,
                          internal_strlen(mem_type));

  // TODO(mcgrathr): Maybe allocate a VMAR for all sanitizer heap and use that?

  // Map a larger size to get a chunk of address space big enough that
  // it surely contains an aligned region of the requested size.  Then
  // overwrite the aligned middle portion with a mapping from the
  // beginning of the VMO, and unmap the excess before and after.
  size_t map_size = size + alignment;
  uintptr_t addr;
  status = _zx_vmar_map(_zx_vmar_root_self(), 0, vmo, 0, map_size,
                        ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE, &addr);
  if (status == ZX_OK) {
    uintptr_t map_addr = addr;
    uintptr_t map_end = map_addr + map_size;
    addr = RoundUpTo(map_addr, alignment);
    uintptr_t end = addr + size;
    if (addr != map_addr) {
      zx_info_vmar_t info;
      status = _zx_object_get_info(_zx_vmar_root_self(), ZX_INFO_VMAR, &info,
                                   sizeof(info), NULL, NULL);
      if (status == ZX_OK) {
        uintptr_t new_addr;
        status =
            _zx_vmar_map(_zx_vmar_root_self(), addr - info.base, vmo, 0, size,
                         ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE |
                             ZX_VM_FLAG_SPECIFIC_OVERWRITE,
                         &new_addr);
        if (status == ZX_OK) CHECK_EQ(new_addr, addr);
      }
    }
    if (status == ZX_OK && addr != map_addr)
      status = _zx_vmar_unmap(_zx_vmar_root_self(), map_addr, addr - map_addr);
    if (status == ZX_OK && end != map_end)
      status = _zx_vmar_unmap(_zx_vmar_root_self(), end, map_end - end);
  }
  _zx_handle_close(vmo);

  if (status != ZX_OK) {
    if (status != ZX_ERR_NO_MEMORY)
      ReportMmapFailureAndDie(size, mem_type, "zx_vmar_map", status, false);
    return nullptr;
  }

  IncreaseTotalMmap(size);

  return reinterpret_cast<void *>(addr);
}

void UnmapOrDie(void *addr, uptr size) {
  if (!addr || !size) return;
  size = RoundUpTo(size, PAGE_SIZE);

  zx_status_t status = _zx_vmar_unmap(_zx_vmar_root_self(),
                                      reinterpret_cast<uintptr_t>(addr), size);
  if (status != ZX_OK) {
    Report("ERROR: %s failed to deallocate 0x%zx (%zd) bytes at address %p\n",
           SanitizerToolName, size, size, addr);
    CHECK("unable to unmap" && 0);
  }

  DecreaseTotalMmap(size);
}

// This is used on the shadow mapping, which cannot be changed.
// Zircon doesn't have anything like MADV_DONTNEED.
void ReleaseMemoryPagesToOS(uptr beg, uptr end) {}

void DumpProcessMap() {
  UNIMPLEMENTED();  // TODO(mcgrathr): write it
}

bool IsAccessibleMemoryRange(uptr beg, uptr size) {
  // TODO(mcgrathr): Figure out a better way.
  zx_handle_t vmo;
  zx_status_t status = _zx_vmo_create(size, 0, &vmo);
  if (status == ZX_OK) {
    while (size > 0) {
      size_t wrote;
      status = _zx_vmo_write(vmo, reinterpret_cast<const void *>(beg), 0, size,
                             &wrote);
      if (status != ZX_OK) break;
      CHECK_GT(wrote, 0);
      CHECK_LE(wrote, size);
      beg += wrote;
      size -= wrote;
    }
    _zx_handle_close(vmo);
  }
  return status == ZX_OK;
}

// FIXME implement on this platform.
void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) {}

bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
                      uptr *read_len, uptr max_len, error_t *errno_p) {
  zx_handle_t vmo;
  zx_status_t status = __sanitizer_get_configuration(file_name, &vmo);
  if (status == ZX_OK) {
    uint64_t vmo_size;
    status = _zx_vmo_get_size(vmo, &vmo_size);
    if (status == ZX_OK) {
      if (vmo_size < max_len) max_len = vmo_size;
      size_t map_size = RoundUpTo(max_len, PAGE_SIZE);
      uintptr_t addr;
      status = _zx_vmar_map(_zx_vmar_root_self(), 0, vmo, 0, map_size,
                            ZX_VM_FLAG_PERM_READ, &addr);
      if (status == ZX_OK) {
        *buff = reinterpret_cast<char *>(addr);
        *buff_size = map_size;
        *read_len = max_len;
      }
    }
    _zx_handle_close(vmo);
  }
  if (status != ZX_OK && errno_p) *errno_p = status;
  return status == ZX_OK;
}

void RawWrite(const char *buffer) {
  __sanitizer_log_write(buffer, internal_strlen(buffer));
}

void CatastrophicErrorWrite(const char *buffer, uptr length) {
  __sanitizer_log_write(buffer, length);
}

char **StoredArgv;
char **StoredEnviron;

char **GetArgv() { return StoredArgv; }

const char *GetEnv(const char *name) {
  if (StoredEnviron) {
    uptr NameLen = internal_strlen(name);
    for (char **Env = StoredEnviron; *Env != 0; Env++) {
      if (internal_strncmp(*Env, name, NameLen) == 0 && (*Env)[NameLen] == '=')
        return (*Env) + NameLen + 1;
    }
  }
  return nullptr;
}

uptr ReadBinaryName(/*out*/ char *buf, uptr buf_len) {
  const char *argv0 = StoredArgv[0];
  if (!argv0) argv0 = "<UNKNOWN>";
  internal_strncpy(buf, argv0, buf_len);
  return internal_strlen(buf);
}

uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
  return ReadBinaryName(buf, buf_len);
}

uptr MainThreadStackBase, MainThreadStackSize;

bool GetRandom(void *buffer, uptr length, bool blocking) {
  CHECK_LE(length, ZX_CPRNG_DRAW_MAX_LEN);
  size_t size;
  CHECK_EQ(_zx_cprng_draw(buffer, length, &size), ZX_OK);
  CHECK_EQ(size, length);
  return true;
}

}  // namespace __sanitizer

using namespace __sanitizer;  // NOLINT

extern "C" {
void __sanitizer_startup_hook(int argc, char **argv, char **envp,
                              void *stack_base, size_t stack_size) {
  __sanitizer::StoredArgv = argv;
  __sanitizer::StoredEnviron = envp;
  __sanitizer::MainThreadStackBase = reinterpret_cast<uintptr_t>(stack_base);
  __sanitizer::MainThreadStackSize = stack_size;
}

void __sanitizer_set_report_path(const char *path) {
  // Handle the initialization code in each sanitizer, but no other calls.
  // This setting is never consulted on Fuchsia.
  DCHECK_EQ(path, common_flags()->log_path);
}

void __sanitizer_set_report_fd(void *fd) {
  UNREACHABLE("not available on Fuchsia");
}
}  // extern "C"

#endif  // SANITIZER_FUCHSIA
