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