// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "decoder.h"

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <lib/syslog/cpp/macros.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <string>

#include "garnet/lib/debugger_utils/util.h"
#include "src/lib/files/directory.h"
#include "src/lib/files/path.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace intel_processor_trace {

static void* MmapFile(const char* file, size_t* size) {
  int fd = open(file, O_RDONLY);
  if (fd < 0)
    return nullptr;
  struct stat st;
  void* map = MAP_FAILED;
  if (fstat(fd, &st) >= 0) {
    *size = st.st_size;
    map = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  }
  close(fd);
  return map != MAP_FAILED ? map : nullptr;
}

static void UnmapFile(void* map, size_t size) { munmap(map, size); }

std::unique_ptr<DecoderState> DecoderState::Create(const DecoderConfig& config) {
  auto decoder = std::unique_ptr<DecoderState>(new DecoderState());

  FX_DCHECK(config.pt_file_name != "" || config.pt_list_file_name != "");
  FX_DCHECK(config.ktrace_file_name != "");

  if (!decoder->AllocImage("ipt-dump"))
    return nullptr;

  // Read sideband data before we read anything else.

  if (!decoder->ReadKtraceFile(config.ktrace_file_name))
    return nullptr;

  for (auto& f : config.map_file_names) {
    if (!decoder->ReadMapFile(f))
      return nullptr;
  }

  for (auto& f : config.ids_file_names) {
    if (!decoder->ReadIdsFile(f))
      return nullptr;
  }

  if (config.pt_file_name != "") {
    decoder->AddPtFile(files::GetCurrentDirectory(), PtFile::kIdUnset, config.pt_file_name);
  } else {
    if (!decoder->ReadPtListFile(config.pt_list_file_name))
      return nullptr;
  }

  for (auto& f : config.elf_file_names) {
    // TODO(dje): This isn't useful without base addr, cr3, etc.
    if (!decoder->ReadElf(f, 0, 0, 0, 0))
      return nullptr;
  }

  if (config.kernel_file_name != "") {
    decoder->SetKernelCr3(config.kernel_cr3);
    if (!decoder->ReadKernelElf(config.kernel_file_name, config.kernel_cr3))
      return nullptr;
  }

  return decoder;
}

DecoderState::DecoderState() : image_(nullptr), decoder_(nullptr), kernel_cr3_(pt_asid_no_cr3) {
  pt_config_init(&config_);
}

DecoderState::~DecoderState() {
  if (config_.begin)
    UnmapFile(config_.begin, config_.end - config_.begin);
  if (decoder_)
    pt_insn_free_decoder(decoder_);
  if (image_)
    pt_image_free(image_);
}

Process::Process(zx_koid_t p, uint64_t c, uint64_t start, uint64_t end)
    : pid(p), cr3(c), start_time(start), end_time(end) {
  FX_VLOGS(2) << fxl::StringPrintf("pid %" PRIu64 " cr3 0x%" PRIx64 " start %" PRIu64, pid, cr3,
                                   start_time);
}

PtFile::PtFile(uint64_t i, const std::string& f) : id(i), file(f) {
  FX_VLOGS(2) << fxl::StringPrintf("pt_file %" PRIu64 ", file %s", id, file.c_str());
}

const Process* DecoderState::LookupProcessByPid(zx_koid_t pid) {
  // TODO(dje): Add O(1) lookup when there's a need.
  for (const auto& p : processes_) {
    if (p.pid == pid)
      return &p;
  }

  return nullptr;
}

const Process* DecoderState::LookupProcessByCr3(uint64_t cr3) {
  // TODO(dje): Add O(1) lookup when there's a need.
  for (const auto& p : processes_) {
    if (p.cr3 == cr3)
      return &p;
    // If tracing just threads, cr3 values in the trace may be this.
    // If there's only one process, we're ok.
    // TODO(dje): Tracing threads with multiple processes.
    if (cr3 == pt_asid_no_cr3 && processes_.size() == 1)
      return &p;
  }

  return nullptr;
}

const LoadMap* DecoderState::LookupMapEntry(zx_koid_t pid, uint64_t addr) {
  return load_maps_.LookupLoadMap(pid, addr);
}

const BuildId* DecoderState::LookupBuildId(const std::string& bid) {
  return build_ids_.LookupBuildId(bid);
}

std::string DecoderState::LookupFile(const std::string& file) {
  // TODO(dje): This function is here in case we need to do fancier lookup
  // later.
  return file;
}

// static
int DecoderState::ReadMemCallback(uint8_t* buffer, size_t size, const struct pt_asid* asid,
                                  uint64_t addr, void* context) {
  auto decoder = reinterpret_cast<DecoderState*>(context);
  uint64_t cr3 = asid->cr3;

  auto proc = decoder->LookupProcessByCr3(cr3);
  if (!proc) {
    FX_VLOGS(1) << fxl::StringPrintf(
        "process lookup failed for cr3:"
        " 0x%" PRIx64,
        cr3);
    decoder->unknown_cr3s_.emplace(cr3);
    return -pte_nomap;
  }

  auto map = decoder->LookupMapEntry(proc->pid, addr);
  if (!map) {
    FX_VLOGS(1) << fxl::StringPrintf(
        "map lookup failed for cr3/addr:"
        " 0x%" PRIx64 "/0x%" PRIx64,
        cr3, addr);
    return -pte_nomap;
  }

  auto bid = decoder->LookupBuildId(map->build_id);
  if (!bid) {
    FX_VLOGS(1) << fxl::StringPrintf(
        "build_id not found: %s, for cr3/addr:"
        " 0x%" PRIx64 "/0x%" PRIx64,
        map->build_id.c_str(), cr3, addr);
    return -pte_nomap;
  }

  auto file = decoder->LookupFile(bid->file);
  if (!file.size()) {
    FX_VLOGS(1) << fxl::StringPrintf(
        "file not found: %s, for build_id %s, cr3/addr:"
        " 0x%" PRIx64 "/0x%" PRIx64,
        bid->file.c_str(), map->build_id.c_str(), cr3, addr);
    return -pte_nomap;
  }

  if (!decoder->ReadElf(file.c_str(), map->base_addr, cr3, 0, map->end_addr - map->load_addr)) {
    FX_VLOGS(1) << "Reading ELF file failed: " << file;
    return -pte_nomap;
  }

  return pt_image_read_for_callback(decoder->image_, buffer, size, asid, addr);
}

bool DecoderState::AllocImage(const std::string& name) {
  FX_DCHECK(!image_);

  struct pt_image* image = pt_image_alloc(name.c_str());
  FX_DCHECK(image);

  pt_image_set_callback(image, ReadMemCallback, this);

  image_ = image;

  return true;
}

bool DecoderState::AddProcess(zx_koid_t pid, uint64_t cr3, uint64_t start_time) {
  FX_VLOGS(2) << fxl::StringPrintf("New process: %" PRIu64 ", cr3 0x%" PRIx64 " @%" PRIu64, pid,
                                   cr3, start_time);
  processes_.push_back(Process(pid, cr3, start_time, 0));
  return true;
}

bool DecoderState::MarkProcessExited(zx_koid_t pid, uint64_t end_time) {
  FX_VLOGS(2) << fxl::StringPrintf("Marking process exit: %" PRIu64 " @%" PRIu64, pid, end_time);

  // We don't remove the process as process start/exit records are read in
  // one pass over the ktrace file. Instead just mark when it exited.
  // We assume process ids won't wrap, which is pretty safe for now.
  for (auto i = processes_.begin(); i != processes_.end(); ++i) {
    if (i->pid == pid) {
      i->end_time = end_time;
      break;
    }
  }

  // If we didn't find an entry that's ok. We might have gotten a process-exit
  // notification for a process that we didn't get a start notification for.
  return true;
}

void DecoderState::AddPtFile(const std::string& file_dir, uint64_t id, const std::string& path) {
  std::string abs_path;

  // Convert relative paths to absolute ones.
  if (path[0] != '/') {
    std::string abs_file_dir = files::AbsolutePath(file_dir);
    abs_path = abs_file_dir + "/" + path;
  } else {
    abs_path = path;
  }
  pt_files_.push_back(PtFile(id, abs_path));
}

bool DecoderState::AllocDecoder(const std::string& pt_file_name) {
  unsigned zero = 0;

  FX_DCHECK(decoder_ == nullptr);

  pt_cpu_errata(&config_.errata, &config_.cpu);
  // When no bit is set, set all, as libipt does not keep up with newer
  // CPUs otherwise.
  if (!memcmp(&config_.errata, &zero, 4))
    memset(&config_.errata, 0xff, sizeof(config_.errata));

  size_t len;
  unsigned char* map = reinterpret_cast<unsigned char*>(MmapFile(pt_file_name.c_str(), &len));
  if (!map) {
    fprintf(stderr, "Cannot open PT file %s: %s\n", pt_file_name.c_str(), strerror(errno));
    return false;
  }
  config_.begin = map;
  config_.end = map + len;

  decoder_ = pt_insn_alloc_decoder(&config_);
  if (!decoder_) {
    fprintf(stderr, "Cannot create PT decoder\n");
    UnmapFile(map, len);
    return false;
  }

  pt_insn_set_image(decoder_, image_);

  return true;
}

void DecoderState::FreeDecoder() {
  FX_DCHECK(decoder_);
  pt_insn_free_decoder(decoder_);
  decoder_ = nullptr;
}

const SymbolTable* DecoderState::FindSymbolTable(uint64_t cr3, uint64_t pc) {
  return simple_pt::FindSymbolTable(symtabs_, cr3, pc);
}

const Symbol* DecoderState::FindSymbol(uint64_t cr3, uint64_t pc, const SymbolTable** out_symtab) {
  return simple_pt::FindSymbol(symtabs_, cr3, pc, out_symtab);
}

const char* DecoderState::FindPcFileName(uint64_t cr3, uint64_t pc) {
  return simple_pt::FindPcFileName(symtabs_, cr3, pc);
}

bool DecoderState::SeenCr3(uint64_t cr3) { return simple_pt::SeenCr3(symtabs_, cr3); }

}  // namespace intel_processor_trace
