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

#include "vm/globals.h"
#if defined(HOST_OS_LINUX)

#include "vm/os.h"

#include <errno.h>         // NOLINT
#include <fcntl.h>         // NOLINT
#include <limits.h>        // NOLINT
#include <malloc.h>        // NOLINT
#include <sys/mman.h>      // NOLINT
#include <sys/resource.h>  // NOLINT
#include <sys/stat.h>      // NOLINT
#include <sys/syscall.h>   // NOLINT
#include <sys/time.h>      // NOLINT
#include <sys/types.h>     // NOLINT
#include <time.h>          // NOLINT
#include <unistd.h>        // NOLINT

#include "platform/memory_sanitizer.h"
#include "platform/utils.h"
#include "vm/code_observers.h"
#include "vm/dart.h"
#include "vm/flags.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/os_thread.h"
#include "vm/zone.h"

namespace dart {

#ifndef PRODUCT

DEFINE_FLAG(bool,
            generate_perf_events_symbols,
            false,
            "Generate events symbols for profiling with perf");

DEFINE_FLAG(bool,
            generate_perf_jitdump,
            false,
            "Generate jitdump file to use with perf-inject");

DECLARE_FLAG(bool, write_protect_code);
DECLARE_FLAG(bool, write_protect_vm_isolate);

// Linux CodeObservers.

// Simple perf support: generate /tmp/perf-<pid>.map file that maps
// memory ranges to symbol names for JIT generated code. This allows
// perf-report to resolve addresses falling into JIT generated code.
// However perf-annotate does not work in this mode because JIT code
// is transient and does not exist anymore at the moment when you
// invoke perf-report.
class PerfCodeObserver : public CodeObserver {
 public:
  PerfCodeObserver() : out_file_(NULL) {
    Dart_FileOpenCallback file_open = Dart::file_open_callback();
    if (file_open == NULL) {
      return;
    }
    intptr_t pid = getpid();
    char* filename = OS::SCreate(NULL, "/tmp/perf-%" Pd ".map", pid);
    out_file_ = (*file_open)(filename, true);
    free(filename);
  }

  ~PerfCodeObserver() {
    Dart_FileCloseCallback file_close = Dart::file_close_callback();
    if ((file_close == NULL) || (out_file_ == NULL)) {
      return;
    }
    (*file_close)(out_file_);
  }

  virtual bool IsActive() const {
    return FLAG_generate_perf_events_symbols && (out_file_ != NULL);
  }

  virtual void Notify(const char* name,
                      uword base,
                      uword prologue_offset,
                      uword size,
                      bool optimized) {
    Dart_FileWriteCallback file_write = Dart::file_write_callback();
    if ((file_write == NULL) || (out_file_ == NULL)) {
      return;
    }
    const char* marker = optimized ? "*" : "";
    char* buffer =
        OS::SCreate(Thread::Current()->zone(), "%" Px " %" Px " %s%s\n", base,
                    size, marker, name);
    {
      MutexLocker ml(CodeObservers::mutex());
      (*file_write)(buffer, strlen(buffer), out_file_);
    }
  }

 private:
  void* out_file_;

  DISALLOW_COPY_AND_ASSIGN(PerfCodeObserver);
};

// Code observer that generates a JITDUMP[1] file that can be interpreted by
// perf-inject to generate ELF images for JIT generated code objects, which
// allows both perf-report and perf-annotate to recognize them.
//
// Usage:
//
//   $ perf record -k mono dart --generate-perf-jitdump benchmark.dart
//   $ perf inject -j -i perf.data -o perf.data.jitted
//   $ perf report -i perf.data.jitted
//
// [1] see linux/tools/perf/Documentation/jitdump-specification.txt for
//     JITDUMP binary format.
class JitDumpCodeObserver : public CodeObserver {
 public:
  JitDumpCodeObserver()
      : out_file_(nullptr), mapped_(nullptr), mapped_size_(0), code_id_(0) {
    const intptr_t pid = getpid();
    char* const filename = OS::SCreate(nullptr, "/tmp/jit-%" Pd ".dump", pid);
    const int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0666);
    free(filename);

    if (fd == -1) {
      return;
    }

    // Map JITDUMP file, this mapping will be recorded by perf. This allows
    // perf-inject to find this file later.
    const long page_size = sysconf(_SC_PAGESIZE);  // NOLINT(runtime/int)
    if (page_size == -1) {
      close(fd);
      return;
    }

    mapped_ =
        mmap(nullptr, page_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
    if (mapped_ == nullptr) {
      close(fd);
      return;
    }
    mapped_size_ = page_size;

    out_file_ = fdopen(fd, "w+");
    if (out_file_ == nullptr) {
      close(fd);
      return;
    }

    // Buffer the output to avoid high IO overheads - we are going to be
    // writing all JIT generated code out.
    setvbuf(out_file_, nullptr, _IOFBF, 2 * MB);

    // Disable code write protection and vm isolate write protection, because
    // calling mprotect on the pages filled with JIT generated code objects
    // confuses perf.
    FLAG_write_protect_code = false;
    FLAG_write_protect_vm_isolate = false;

    // Write JITDUMP header.
    WriteHeader();
  }

  ~JitDumpCodeObserver() {
    if (mapped_ != nullptr) {
      munmap(mapped_, mapped_size_);
      mapped_ = nullptr;
    }

    if (out_file_ != nullptr) {
      fclose(out_file_);
      out_file_ = nullptr;
    }
  }

  virtual bool IsActive() const {
    return FLAG_generate_perf_jitdump && (out_file_ != nullptr);
  }

  virtual void Notify(const char* name,
                      uword base,
                      uword prologue_offset,
                      uword size,
                      bool optimized) {
    const char* marker = optimized ? "*" : "";
    char* buffer = OS::SCreate(Thread::Current()->zone(), "%s%s", marker, name);
    const size_t name_length = strlen(buffer);

    CodeLoadEvent ev;
    ev.event = BaseEvent::kLoad;
    ev.size = sizeof(ev) + (name_length + 1) + size;
    ev.time_stamp = OS::GetCurrentMonotonicTicks();
    ev.process_id = getpid();
    ev.thread_id = syscall(SYS_gettid);
    ev.vma = base;
    ev.code_address = base;
    ev.code_size = size;

    {
      MutexLocker ml(CodeObservers::mutex());
      ev.code_id = code_id_++;

      WriteFully(&ev, sizeof(ev));
      WriteFully(buffer, name_length + 1);
      WriteFully(reinterpret_cast<void*>(base), size);
    }
  }

 private:
  struct Header {
    const uint32_t magic = 0x4A695444;
    const uint32_t version = 1;
    const uint32_t size = sizeof(Header);
    uint32_t elf_mach_target;
    const uint32_t reserved = 0xDEADBEEF;
    uint32_t process_id;
    uint64_t time_stamp;
    const uint64_t flags = 0;
  };

  struct BaseEvent {
    enum Event {
      kLoad = 0,
      kMove = 1,
      kDebugInfo = 2,
      kClose = 3,
      kUnwindingInfo = 4
    };

    uint32_t event;
    uint32_t size;
    uint64_t time_stamp;
  };

  struct CodeLoadEvent : BaseEvent {
    uint32_t process_id;
    uint32_t thread_id;
    uint64_t vma;
    uint64_t code_address;
    uint64_t code_size;
    uint64_t code_id;
  };

  // ELF machine architectures
  // From linux/include/uapi/linux/elf-em.h
  static const uint32_t EM_386 = 3;
  static const uint32_t EM_X86_64 = 62;
  static const uint32_t EM_ARM = 40;
  static const uint32_t EM_AARCH64 = 183;

  static uint32_t GetElfMachineArchitecture() {
#if TARGET_ARCH_IA32
    return EM_386;
#elif TARGET_ARCH_X64
    return EM_X86_64;
#elif TARGET_ARCH_ARM
    return EM_ARM;
#elif TARGET_ARCH_ARM64
    return EM_AARCH64;
#else
    UNREACHABLE();
    return 0;
#endif
  }

  void WriteHeader() {
    Header header;
    header.elf_mach_target = GetElfMachineArchitecture();
    header.process_id = getpid();
    header.time_stamp = OS::GetCurrentTimeMicros();
    WriteFully(&header, sizeof(header));
  }

  void WriteFully(void* buffer, size_t size) {
    const char* ptr = static_cast<char*>(buffer);
    while (size > 0) {
      const size_t written = fwrite(ptr, 1, size, out_file_);
      if (written == 0) {
        UNREACHABLE();
        break;
      }
      size -= written;
      ptr += written;
    }
  }

  FILE* out_file_;
  void* mapped_;
  long mapped_size_;  // NOLINT(runtime/int)

  intptr_t code_id_;

  DISALLOW_COPY_AND_ASSIGN(JitDumpCodeObserver);
};

#endif  // !PRODUCT

const char* OS::Name() {
  return "linux";
}

intptr_t OS::ProcessId() {
  return static_cast<intptr_t>(getpid());
}

static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
  time_t seconds = static_cast<time_t>(seconds_since_epoch);
  if (seconds != seconds_since_epoch) return false;
  struct tm* error_code = localtime_r(&seconds, tm_result);
  return error_code != NULL;
}

const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
  tm decomposed;
  bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
  // If unsuccessful, return an empty string like V8 does.
  return (succeeded && (decomposed.tm_zone != NULL)) ? decomposed.tm_zone : "";
}

int OS::GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch) {
  tm decomposed;
  bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
  // Even if the offset was 24 hours it would still easily fit into 32 bits.
  // If unsuccessful, return zero like V8 does.
  return succeeded ? static_cast<int>(decomposed.tm_gmtoff) : 0;
}

int OS::GetLocalTimeZoneAdjustmentInSeconds() {
  // TODO(floitsch): avoid excessive calls to tzset?
  tzset();
  // Even if the offset was 24 hours it would still easily fit into 32 bits.
  // Note that Unix and Dart disagree on the sign.
  return static_cast<int>(-timezone);
}

int64_t OS::GetCurrentTimeMillis() {
  return GetCurrentTimeMicros() / 1000;
}

int64_t OS::GetCurrentTimeMicros() {
  // gettimeofday has microsecond resolution.
  struct timeval tv;
  if (gettimeofday(&tv, NULL) < 0) {
    UNREACHABLE();
    return 0;
  }
  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
}

int64_t OS::GetCurrentMonotonicTicks() {
  struct timespec ts;
  if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
    UNREACHABLE();
    return 0;
  }
  // Convert to nanoseconds.
  int64_t result = ts.tv_sec;
  result *= kNanosecondsPerSecond;
  result += ts.tv_nsec;
  return result;
}

int64_t OS::GetCurrentMonotonicFrequency() {
  return kNanosecondsPerSecond;
}

int64_t OS::GetCurrentMonotonicMicros() {
  int64_t ticks = GetCurrentMonotonicTicks();
  ASSERT(GetCurrentMonotonicFrequency() == kNanosecondsPerSecond);
  return ticks / kNanosecondsPerMicrosecond;
}

int64_t OS::GetCurrentThreadCPUMicros() {
  struct timespec ts;
  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != 0) {
    UNREACHABLE();
    return -1;
  }
  int64_t result = ts.tv_sec;
  result *= kMicrosecondsPerSecond;
  result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
  return result;
}

// TODO(5411554):  May need to hoist these architecture dependent code
// into a architecture specific file e.g: os_ia32_linux.cc
intptr_t OS::ActivationFrameAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) ||                   \
    defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
  const int kMinimumAlignment = 16;
#elif defined(TARGET_ARCH_ARM)
  const int kMinimumAlignment = 8;
#else
#error Unsupported architecture.
#endif
  intptr_t alignment = kMinimumAlignment;
  // TODO(5411554): Allow overriding default stack alignment for
  // testing purposes.
  // Flags::DebugIsInt("stackalign", &alignment);
  ASSERT(Utils::IsPowerOfTwo(alignment));
  ASSERT(alignment >= kMinimumAlignment);
  return alignment;
}

intptr_t OS::PreferredCodeAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) ||                   \
    defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
  const int kMinimumAlignment = 32;
#elif defined(TARGET_ARCH_ARM)
  const int kMinimumAlignment = 16;
#else
#error Unsupported architecture.
#endif
  intptr_t alignment = kMinimumAlignment;
  // TODO(5411554): Allow overriding default code alignment for
  // testing purposes.
  // Flags::DebugIsInt("codealign", &alignment);
  ASSERT(Utils::IsPowerOfTwo(alignment));
  ASSERT(alignment >= kMinimumAlignment);
  ASSERT(alignment <= OS::kMaxPreferredCodeAlignment);
  return alignment;
}

int OS::NumberOfAvailableProcessors() {
  return sysconf(_SC_NPROCESSORS_ONLN);
}

void OS::Sleep(int64_t millis) {
  int64_t micros = millis * kMicrosecondsPerMillisecond;
  SleepMicros(micros);
}

void OS::SleepMicros(int64_t micros) {
  struct timespec req;  // requested.
  struct timespec rem;  // remainder.
  int64_t seconds = micros / kMicrosecondsPerSecond;
  micros = micros - seconds * kMicrosecondsPerSecond;
  int64_t nanos = micros * kNanosecondsPerMicrosecond;
  req.tv_sec = seconds;
  req.tv_nsec = nanos;
  while (true) {
    int r = nanosleep(&req, &rem);
    if (r == 0) {
      break;
    }
    // We should only ever see an interrupt error.
    ASSERT(errno == EINTR);
    // Copy remainder into requested and repeat.
    req = rem;
  }
}

// TODO(regis, iposva): When this function is no longer called from the
// CodeImmutability test in object_test.cc, it will be called only from the
// simulator, which means that only the Intel implementation is needed.
void OS::DebugBreak() {
  __builtin_trap();
}

DART_NOINLINE uintptr_t OS::GetProgramCounter() {
  return reinterpret_cast<uintptr_t>(
      __builtin_extract_return_addr(__builtin_return_address(0)));
}

void OS::Print(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VFPrint(stdout, format, args);
  va_end(args);
}

void OS::VFPrint(FILE* stream, const char* format, va_list args) {
  vfprintf(stream, format, args);
  fflush(stream);
}

char* OS::SCreate(Zone* zone, const char* format, ...) {
  va_list args;
  va_start(args, format);
  char* buffer = VSCreate(zone, format, args);
  va_end(args);
  return buffer;
}

char* OS::VSCreate(Zone* zone, const char* format, va_list args) {
  // Measure.
  va_list measure_args;
  va_copy(measure_args, args);
  intptr_t len = Utils::VSNPrint(NULL, 0, format, measure_args);
  va_end(measure_args);

  char* buffer;
  if (zone) {
    buffer = zone->Alloc<char>(len + 1);
  } else {
    buffer = reinterpret_cast<char*>(malloc(len + 1));
  }
  ASSERT(buffer != NULL);

  // Print.
  va_list print_args;
  va_copy(print_args, args);
  Utils::VSNPrint(buffer, len + 1, format, print_args);
  va_end(print_args);
  return buffer;
}

bool OS::StringToInt64(const char* str, int64_t* value) {
  ASSERT(str != NULL && strlen(str) > 0 && value != NULL);
  int32_t base = 10;
  char* endptr;
  int i = 0;
  if (str[0] == '-') {
    i = 1;
  }
  if ((str[i] == '0') && (str[i + 1] == 'x' || str[i + 1] == 'X') &&
      (str[i + 2] != '\0')) {
    base = 16;
  }
  errno = 0;
  if (base == 16) {
    // Unsigned 64-bit hexadecimal integer literals are allowed but
    // immediately interpreted as signed 64-bit integers.
    *value = static_cast<int64_t>(strtoull(str, &endptr, base));
  } else {
    *value = strtoll(str, &endptr, base);
  }
  return ((errno == 0) && (endptr != str) && (*endptr == 0));
}

void OS::RegisterCodeObservers() {
#ifndef PRODUCT
  if (FLAG_generate_perf_events_symbols) {
    CodeObservers::Register(new PerfCodeObserver);
  }

  if (FLAG_generate_perf_jitdump) {
    CodeObservers::Register(new JitDumpCodeObserver);
  }
#endif  // !PRODUCT
}

void OS::PrintErr(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VFPrint(stderr, format, args);
  va_end(args);
}

void OS::InitOnce() {
  // TODO(5411554): For now we check that initonce is called only once,
  // Once there is more formal mechanism to call InitOnce we can move
  // this check there.
  static bool init_once_called = false;
  ASSERT(init_once_called == false);
  init_once_called = true;
}

void OS::Shutdown() {}

void OS::Abort() {
  abort();
}

void OS::Exit(int code) {
  exit(code);
}

}  // namespace dart

#endif  // defined(HOST_OS_LINUX)
