// 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(TARGET_OS_LINUX)

#include "vm/os.h"

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

#include "platform/utils.h"
#include "vm/code_observers.h"
#include "vm/dart.h"
#include "vm/debuginfo.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/os_thread.h"
#include "vm/vtune.h"
#include "vm/zone.h"


namespace dart {

// Linux CodeObservers.

DEFINE_FLAG(bool, generate_gdb_symbols, false,
    "Generate symbols of generated dart functions for debugging with GDB");
DEFINE_FLAG(bool, generate_perf_events_symbols, false,
    "Generate events symbols for profiling with perf");
DEFINE_FLAG(bool, generate_perf_jitdump, false,
    "Writes jitdump data for profiling with perf annotate");


class PerfCodeObserver : public CodeObserver {
 public:
  PerfCodeObserver() : out_file_(NULL) {
    Dart_FileOpenCallback file_open = Isolate::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 = Isolate::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 = Isolate::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);
};


class GdbCodeObserver : public CodeObserver {
 public:
  GdbCodeObserver() { }

  virtual bool IsActive() const {
    return FLAG_generate_gdb_symbols;
  }

  virtual void Notify(const char* name,
                      uword base,
                      uword prologue_offset,
                      uword size,
                      bool optimized) {
    if (prologue_offset > 0) {
      // In order to ensure that gdb sees the first instruction of a function
      // as the prologue sequence we register two symbols for the cases when
      // the prologue sequence is not the first instruction:
      // <name>_entry is used for code preceding the prologue sequence.
      // <name> for rest of the code (first instruction is prologue sequence).
      char* pname = OS::SCreate(Thread::Current()->zone(),
          "%s_%s", name, "entry");
      DebugInfo::RegisterSection(pname, base, size);
      DebugInfo::RegisterSection(name,
                                 (base + prologue_offset),
                                 (size - prologue_offset));
    } else {
      DebugInfo::RegisterSection(name, base, size);
    }
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(GdbCodeObserver);
};


#define CLOCKFD 3
#define FD_TO_CLOCKID(fd)       ((~(clockid_t) (fd) << 3) | CLOCKFD)  // NOLINT

class JitdumpCodeObserver : public CodeObserver {
 public:
  JitdumpCodeObserver() {
    ASSERT(FLAG_generate_perf_jitdump);
    out_file_ = NULL;
    clock_fd_ = -1;
    clock_id_ = kInvalidClockId;
    code_sequence_ = 0;
    Dart_FileOpenCallback file_open = Isolate::file_open_callback();
    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
    Dart_FileCloseCallback file_close = Isolate::file_close_callback();
    if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
      return;
    }
    // The Jitdump code observer writes all jitted code into the file
    // 'perf.jitdump' in the current working directory. We open the file once
    // on initialization and close it when the VM is going down.
    {
      // Open the file.
      const char* filename = "perf.jitdump";
      out_file_ = (*file_open)(filename, true);
      ASSERT(out_file_ != NULL);
      // Write the jit dump header.
      WriteHeader();
    }
    // perf uses an internal clock and because our output is merged with data
    // collected by perf our timestamps must be consistent. Using
    // the posix-clock-module (/dev/trace_clock) as our time source ensures
    // we are consistent with the perf timestamps.
    clock_id_ = kInvalidClockId;
    clock_fd_ = open("/dev/trace_clock", O_RDONLY);
    if (clock_fd_ >= 0) {
      clock_id_ = FD_TO_CLOCKID(clock_fd_);
    }
  }

  ~JitdumpCodeObserver() {
    Dart_FileCloseCallback file_close = Isolate::file_close_callback();
    if (file_close == NULL) {
      return;
    }
    ASSERT(out_file_ != NULL);
    (*file_close)(out_file_);
    if (clock_fd_ >= 0) {
      close(clock_fd_);
    }
  }

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

  virtual void Notify(const char* name,
                      uword base,
                      uword prologue_offset,
                      uword size,
                      bool optimized) {
    WriteCodeLoad(name, base, prologue_offset, size, optimized);
  }

 private:
  static const uint32_t kJitHeaderMagic = 0x4A695444;
  static const uint32_t kJitHeaderMagicSw = 0x4454694A;
  static const uint32_t kJitHeaderVersion = 0x1;
  static const uint32_t kElfMachIA32 = 3;
  static const uint32_t kElfMachX64 = 62;
  static const uint32_t kElfMachARM = 40;
  // TODO(zra): Find the right ARM64 constant.
  static const uint32_t kElfMachARM64 = 40;
  static const uint32_t kElfMachMIPS = 10;
  static const int kInvalidClockId = -1;

  struct jitheader {
    uint32_t magic;   /* characters "jItD" */
    uint32_t version; /* header version */
    uint32_t total_size;  /* total size of header */
    uint32_t elf_mach;  /* elf mach target */
    uint32_t pad1;    /* reserved */
    uint32_t pid;   /* JIT process id */
    uint64_t timestamp; /* timestamp */
  };

  /* record prefix (mandatory in each record) */
  struct jr_prefix {
    uint32_t id;
    uint32_t total_size;
    uint64_t timestamp;
  };

  enum jit_record_type {
    JIT_CODE_LOAD = 0,
    /* JIT_CODE_MOVE = 1, */
    /* JIT_CODE_DEBUG_INFO = 2, */
    /* JIT_CODE_CLOSE = 3, */
    JIT_CODE_MAX = 4,
  };

  struct jr_code_load {
    struct jr_prefix prefix;
    uint32_t pid;
    uint32_t tid;
    uint64_t vma;
    uint64_t code_addr;
    uint64_t code_size;
    uint64_t code_index;
  };

  const char* GenerateCodeName(const char* name, bool optimized) {
    const char* marker = optimized ? "*" : "";
    return OS::SCreate(Thread::Current()->zone(), "%s%s", marker, name);
  }

  uint32_t GetElfMach() {
#if defined(TARGET_ARCH_IA32)
    return kElfMachIA32;
#elif defined(TARGET_ARCH_X64)
    return kElfMachX64;
#elif defined(TARGET_ARCH_ARM)
    return kElfMachARM;
#elif defined(TARGET_ARCH_ARM64)
    return kElfMachARM64;
#elif defined(TARGET_ARCH_MIPS)
    return kElfMachMIPS;
#else
#error Unknown architecture.
#endif
  }

  pid_t gettid() {
    // libc doesn't wrap the Linux-specific gettid system call.
    // Note that this thread id is not the same as the posix thread id.
    return syscall(SYS_gettid);
  }

  uint64_t GetKernelTimeNanos() {
    if (clock_id_ != kInvalidClockId) {
      struct timespec ts;
      int r = clock_gettime(clock_id_, &ts);
      ASSERT(r == 0);
      uint64_t nanos = static_cast<uint64_t>(ts.tv_sec) *
                       static_cast<uint64_t>(kNanosecondsPerSecond);
      nanos += static_cast<uint64_t>(ts.tv_nsec);
      return nanos;
    } else {
      return OS::GetCurrentTimeMicros() * kNanosecondsPerMicrosecond;
    }
  }

  void WriteHeader() {
    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
    ASSERT(file_write != NULL);
    ASSERT(out_file_ != NULL);
    jitheader header;
    header.magic = kJitHeaderMagic;
    header.version = kJitHeaderVersion;
    header.total_size = sizeof(jitheader);
    header.pad1 = 0x0;
    header.elf_mach = GetElfMach();
    header.pid = getpid();
    header.timestamp = GetKernelTimeNanos();
    {
      MutexLocker ml(CodeObservers::mutex());
      (*file_write)(&header, sizeof(header), out_file_);
    }
  }

  void WriteCodeLoad(const char* name, uword base, uword prologue_offset,
                     uword code_size, bool optimized) {
    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
    ASSERT(file_write != NULL);
    ASSERT(out_file_ != NULL);

    const char* code_name = GenerateCodeName(name, optimized);
    const intptr_t code_name_size = strlen(code_name) + 1;
    uint8_t* code_pointer = reinterpret_cast<uint8_t*>(base);

    jr_code_load code_load;
    code_load.prefix.id = JIT_CODE_LOAD;
    code_load.prefix.total_size =
        sizeof(code_load) + code_name_size + code_size;
    code_load.prefix.timestamp = GetKernelTimeNanos();
    code_load.pid = getpid();
    code_load.tid = gettid();
    code_load.vma = 0x0;  //  Our addresses are absolute.
    code_load.code_addr = base;
    code_load.code_size = code_size;

    {
      MutexLocker ml(CodeObservers::mutex());
      // Set this field under the index.
      code_load.code_index = code_sequence_++;
      // Write structures.
      (*file_write)(&code_load, sizeof(code_load), out_file_);
      (*file_write)(code_name, code_name_size, out_file_);
      (*file_write)(code_pointer, code_size, out_file_);
    }
  }

  void* out_file_;
  int clock_fd_;
  int clock_id_;
  uint64_t code_sequence_;
  DISALLOW_COPY_AND_ASSIGN(JitdumpCodeObserver);
};


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


void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
  const int kMinimumAlignment = 16;
  ASSERT(Utils::IsPowerOfTwo(alignment));
  ASSERT(alignment >= kMinimumAlignment);
  void* p = memalign(alignment, size);
  if (p == NULL) {
    UNREACHABLE();
  }
  return p;
}


void OS::AlignedFree(void* ptr) {
  free(ptr);
}


// 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)
  const int kMinimumAlignment = 16;
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
  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)
  const int kMinimumAlignment = 32;
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
  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;
}


bool OS::AllowStackFrameIteratorFromAnotherThread() {
  return false;
}


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


char* OS::StrNDup(const char* s, intptr_t n) {
  return strndup(s, n);
}


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


int OS::SNPrint(char* str, size_t size, const char* format, ...) {
  va_list args;
  va_start(args, format);
  int retval = VSNPrint(str, size, format, args);
  va_end(args);
  return retval;
}


int OS::VSNPrint(char* str, size_t size, const char* format, va_list args) {
  int retval = vsnprintf(str, size, format, args);
  if (retval < 0) {
    FATAL1("Fatal error in OS::VSNPrint with format '%s'", format);
  }
  return retval;
}


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 = 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);
  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;
  *value = strtoll(str, &endptr, base);
  return ((errno == 0) && (endptr != str) && (*endptr == 0));
}


void OS::RegisterCodeObservers() {
  if (FLAG_generate_perf_events_symbols) {
    CodeObservers::Register(new PerfCodeObserver);
  }
  if (FLAG_generate_gdb_symbols) {
    CodeObservers::Register(new GdbCodeObserver);
  }
  if (FLAG_generate_perf_jitdump) {
    CodeObservers::Register(new JitdumpCodeObserver);
  }
#if defined(DART_VTUNE_SUPPORT)
  CodeObservers::Register(new VTuneCodeObserver);
#endif
}


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(TARGET_OS_LINUX)
