//===-- 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 "common.h"
#include "internal_defs.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 <stdio.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)
    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 ? Size : 0);
    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();
}

void releasePagesToOS(uptr BaseAddress, uptr Offset, uptr Size,
                      UNUSED MapPlatformData *Data) {
  void *Addr = reinterpret_cast<void *>(BaseAddress + Offset);

  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);
  }
}

void HybridMutex::assertHeldImpl() {
  CHECK(atomic_load(&M, memory_order_acquire) != Unlocked);
}

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);
}

u64 getMonotonicTimeFast() {
#if defined(CLOCK_MONOTONIC_COARSE)
  timespec TS;
  clock_gettime(CLOCK_MONOTONIC_COARSE, &TS);
  return static_cast<u64>(TS.tv_sec) * (1000ULL * 1000 * 1000) +
         static_cast<u64>(TS.tv_nsec);
#else
  return getMonotonicTime();
#endif
}

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);

static uptr GetRSSFromBuffer(const char *Buf) {
  // The format of the file is:
  // 1084 89 69 11 0 79 0
  // We need the second number which is RSS in pages.
  const char *Pos = Buf;
  // Skip the first number.
  while (*Pos >= '0' && *Pos <= '9')
    Pos++;
  // Skip whitespaces.
  while (!(*Pos >= '0' && *Pos <= '9') && *Pos != 0)
    Pos++;
  // Read the number.
  u64 Rss = 0;
  for (; *Pos >= '0' && *Pos <= '9'; Pos++)
    Rss = Rss * 10 + static_cast<u64>(*Pos) - '0';
  return static_cast<uptr>(Rss * getPageSizeCached());
}

uptr GetRSS() {
  // TODO: We currently use sanitizer_common's GetRSS which reads the
  // RSS from /proc/self/statm by default. We might want to
  // call getrusage directly, even if it's less accurate.
  auto Fd = open("/proc/self/statm", O_RDONLY);
  char Buf[64];
  s64 Len = read(Fd, Buf, sizeof(Buf) - 1);
  close(Fd);
  if (Len <= 0)
    return 0;
  Buf[Len] = 0;

  return GetRSSFromBuffer(Buf);
}

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
