//===-- linux.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 "platform.h"

#if SCUDO_LINUX

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

#include <errno.h>
#include <fcntl.h>
#include <linux/futex.h>
#include <sched.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

#if SCUDO_ANDROID
#include <sys/prctl.h>
// Definitions of prctl arguments to set a vma name in Android kernels.
#define ANDROID_PR_SET_VMA 0x53564d41
#define ANDROID_PR_SET_VMA_ANON_NAME 0
#endif

namespace scudo {

uptr getPageSize() { return static_cast<uptr>(sysconf(_SC_PAGESIZE)); }

void NORETURN die() { abort(); }

void *map(void *Addr, uptr Size, UNUSED const char *Name, uptr Flags,
          UNUSED MapPlatformData *Data) {
  int MmapFlags = MAP_PRIVATE | MAP_ANONYMOUS;
  int MmapProt;
  if (Flags & MAP_NOACCESS) {
    MmapFlags |= MAP_NORESERVE;
    MmapProt = PROT_NONE;
  } else {
    MmapProt = PROT_READ | PROT_WRITE;
  }
#if defined(__aarch64__)
#ifndef PROT_MTE
#define PROT_MTE 0x20
#endif
  if (Flags & MAP_MEMTAG)
    MmapProt |= PROT_MTE;
#endif
  if (Addr) {
    // Currently no scenario for a noaccess mapping with a fixed address.
    DCHECK_EQ(Flags & MAP_NOACCESS, 0);
    MmapFlags |= MAP_FIXED;
  }
  void *P = mmap(Addr, Size, MmapProt, MmapFlags, -1, 0);
  if (P == MAP_FAILED) {
    if (!(Flags & MAP_ALLOWNOMEM) || errno != ENOMEM)
      dieOnMapUnmapError(errno == ENOMEM);
    return nullptr;
  }
#if SCUDO_ANDROID
  if (Name)
    prctl(ANDROID_PR_SET_VMA, ANDROID_PR_SET_VMA_ANON_NAME, P, Size, Name);
#endif
  return P;
}

void unmap(void *Addr, uptr Size, UNUSED uptr Flags,
           UNUSED MapPlatformData *Data) {
  if (munmap(Addr, Size) != 0)
    dieOnMapUnmapError();
}

void setMemoryPermission(uptr Addr, uptr Size, uptr Flags,
                         UNUSED MapPlatformData *Data) {
  int Prot = (Flags & MAP_NOACCESS) ? PROT_NONE : (PROT_READ | PROT_WRITE);
  if (mprotect(reinterpret_cast<void *>(Addr), Size, Prot) != 0)
    dieOnMapUnmapError();
}

static bool madviseNeedsMemset() {
  uptr Size = getPageSizeCached();
  char *P = (char *)mmap(0, Size, PROT_READ | PROT_WRITE,
                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (!P)
    dieOnMapUnmapError(errno == ENOMEM);
  *P = 1;
  while (madvise(P, Size, MADV_DONTNEED) == -1 && errno == EAGAIN) {
  }
  bool R = (*P != 0);
  if (munmap(P, Size) != 0)
    dieOnMapUnmapError();
  return R;
}

static bool madviseNeedsMemsetCached() {
  static atomic_u8 Cache;
  enum State : u8 { Unknown = 0, Yes = 1, No = 2 };
  State NeedsMemset = static_cast<State>(atomic_load_relaxed(&Cache));
  if (NeedsMemset == Unknown) {
    NeedsMemset = madviseNeedsMemset() ? Yes : No;
    atomic_store_relaxed(&Cache, NeedsMemset);
  }
  return NeedsMemset == Yes;
}

void releasePagesToOS(uptr BaseAddress, uptr Offset, uptr Size,
                      UNUSED MapPlatformData *Data) {
  void *Addr = reinterpret_cast<void *>(BaseAddress + Offset);
  if (madviseNeedsMemsetCached()) {
    // Workaround for QEMU-user ignoring MADV_DONTNEED.
    // https://github.com/qemu/qemu/blob/b1cffefa1b163bce9aebc3416f562c1d3886eeaa/linux-user/syscall.c#L11941
    // https://bugs.launchpad.net/qemu/+bug/1926521
    memset(Addr, 0, Size);
  }
  while (madvise(Addr, Size, MADV_DONTNEED) == -1 && errno == EAGAIN) {
  }
}

// Calling getenv should be fine (c)(tm) at any time.
const char *getEnv(const char *Name) { return getenv(Name); }

namespace {
enum State : u32 { Unlocked = 0, Locked = 1, Sleeping = 2 };
}

bool HybridMutex::tryLock() {
  return atomic_compare_exchange(&M, Unlocked, Locked) == Unlocked;
}

// The following is based on https://akkadia.org/drepper/futex.pdf.
void HybridMutex::lockSlow() {
  u32 V = atomic_compare_exchange(&M, Unlocked, Locked);
  if (V == Unlocked)
    return;
  if (V != Sleeping)
    V = atomic_exchange(&M, Sleeping, memory_order_acquire);
  while (V != Unlocked) {
    syscall(SYS_futex, reinterpret_cast<uptr>(&M), FUTEX_WAIT_PRIVATE, Sleeping,
            nullptr, nullptr, 0);
    V = atomic_exchange(&M, Sleeping, memory_order_acquire);
  }
}

void HybridMutex::unlock() {
  if (atomic_fetch_sub(&M, 1U, memory_order_release) != Locked) {
    atomic_store(&M, Unlocked, memory_order_release);
    syscall(SYS_futex, reinterpret_cast<uptr>(&M), FUTEX_WAKE_PRIVATE, 1,
            nullptr, nullptr, 0);
  }
}

u64 getMonotonicTime() {
  timespec TS;
  clock_gettime(CLOCK_MONOTONIC, &TS);
  return static_cast<u64>(TS.tv_sec) * (1000ULL * 1000 * 1000) +
         static_cast<u64>(TS.tv_nsec);
}

u32 getNumberOfCPUs() {
  cpu_set_t CPUs;
  // sched_getaffinity can fail for a variety of legitimate reasons (lack of
  // CAP_SYS_NICE, syscall filtering, etc), in which case we shall return 0.
  if (sched_getaffinity(0, sizeof(cpu_set_t), &CPUs) != 0)
    return 0;
  return static_cast<u32>(CPU_COUNT(&CPUs));
}

u32 getThreadID() {
#if SCUDO_ANDROID
  return static_cast<u32>(gettid());
#else
  return static_cast<u32>(syscall(SYS_gettid));
#endif
}

// Blocking is possibly unused if the getrandom block is not compiled in.
bool getRandom(void *Buffer, uptr Length, UNUSED bool Blocking) {
  if (!Buffer || !Length || Length > MaxRandomLength)
    return false;
  ssize_t ReadBytes;
#if defined(SYS_getrandom)
#if !defined(GRND_NONBLOCK)
#define GRND_NONBLOCK 1
#endif
  // Up to 256 bytes, getrandom will not be interrupted.
  ReadBytes =
      syscall(SYS_getrandom, Buffer, Length, Blocking ? 0 : GRND_NONBLOCK);
  if (ReadBytes == static_cast<ssize_t>(Length))
    return true;
#endif // defined(SYS_getrandom)
  // Up to 256 bytes, a read off /dev/urandom will not be interrupted.
  // Blocking is moot here, O_NONBLOCK has no effect when opening /dev/urandom.
  const int FileDesc = open("/dev/urandom", O_RDONLY);
  if (FileDesc == -1)
    return false;
  ReadBytes = read(FileDesc, Buffer, Length);
  close(FileDesc);
  return (ReadBytes == static_cast<ssize_t>(Length));
}

// Allocation free syslog-like API.
extern "C" WEAK int async_safe_write_log(int pri, const char *tag,
                                         const char *msg);

void outputRaw(const char *Buffer) {
  if (&async_safe_write_log) {
    constexpr s32 AndroidLogInfo = 4;
    constexpr uptr MaxLength = 1024U;
    char LocalBuffer[MaxLength];
    while (strlen(Buffer) > MaxLength) {
      uptr P;
      for (P = MaxLength - 1; P > 0; P--) {
        if (Buffer[P] == '\n') {
          memcpy(LocalBuffer, Buffer, P);
          LocalBuffer[P] = '\0';
          async_safe_write_log(AndroidLogInfo, "scudo", LocalBuffer);
          Buffer = &Buffer[P + 1];
          break;
        }
      }
      // If no newline was found, just log the buffer.
      if (P == 0)
        break;
    }
    async_safe_write_log(AndroidLogInfo, "scudo", Buffer);
  } else {
    (void)write(2, Buffer, strlen(Buffer));
  }
}

extern "C" WEAK void android_set_abort_message(const char *);

void setAbortMessage(const char *Message) {
  if (&android_set_abort_message)
    android_set_abort_message(Message);
}

} // namespace scudo

#endif // SCUDO_LINUX
