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

#ifndef SRC_LIB_INTEL_PT_DECODE_DECODER_H_
#define SRC_LIB_INTEL_PT_DECODE_DECODER_H_

#include <string>
#include <unordered_set>
#include <vector>

#include "src/lib/debugger_utils/build_ids.h"
#include "src/lib/debugger_utils/elf_reader.h"
#include "src/lib/debugger_utils/elf_symtab.h"
#include "src/lib/debugger_utils/ktrace_reader.h"
#include "src/lib/debugger_utils/load_maps.h"
#include "third_party/processor-trace/libipt/include/intel-pt.h"
#include "third_party/simple-pt/symtab.h"

namespace intel_processor_trace {

// Parameters needed to drive the decoder.

struct DecoderConfig {
  // Path to the kernel ELF file.
  std::string kernel_file_name;

  // Ideally this should come from sideband data, but it can be manually
  // specified.
  uint64_t kernel_cr3 = pt_asid_no_cr3;

  // Path to the raw processor trace dump.
  // This file is produced by the "ipt" program.
  std::string pt_file_name;

  // Path to a text file containing a mapping of "id" values and their
  // corresponding PT dump files.
  // The format of each line is "id /path/to/pt-file".
  // "id" is either a cpu number for cpu-based tracing, or thread id for
  // thread-based tracing; in decimal.
  std::string pt_list_file_name;

  // Path to needed ktrace data.
  // This file is produced by the "ipt" program.
  std::string ktrace_file_name;

  // Optional additional files passed on the command line.
  std::vector<std::string> elf_file_names;

  // Path to the "ids.txt" files from the build.
  std::vector<std::string> ids_file_names;

  // Path to file containing linker map output.
  std::vector<std::string> map_file_names;
};

struct Process {
  Process(zx_koid_t p, uint64_t c, uint64_t start, uint64_t end);
  zx_koid_t pid;
  uint64_t cr3;
  // The time, in units ktrace uses, when the process was live.
  // An end time of zero means "unknown".
  uint64_t start_time, end_time;
};

struct PtFile {
  PtFile(uint64_t i, const std::string& f);

  // The id of the cpu we are processing. Cpus are numbered 0...N.
  static constexpr uint64_t kIdUnset = ~(uint64_t)0;

  uint64_t id;
  std::string file;
};

using SymbolTable = simple_pt::SymbolTable;
using Symbol = simple_pt::Symbol;
using LoadMap = debugger_utils::LoadMap;
using BuildId = debugger_utils::BuildId;

class DecoderState {
 public:
  static std::unique_ptr<DecoderState> Create(const DecoderConfig& config);

  ~DecoderState();

  const Process* LookupProcessByPid(zx_koid_t pid);
  const Process* LookupProcessByCr3(uint64_t cr3);

  const LoadMap* LookupMapEntry(zx_koid_t pid, uint64_t addr);

  const BuildId* LookupBuildId(const std::string& bid);

  std::string LookupFile(const std::string& file);

  const SymbolTable* FindSymbolTable(uint64_t cr3, uint64_t pc);
  const Symbol* FindSymbol(uint64_t cr3, uint64_t pc, const SymbolTable** out_symtab);
  const char* FindPcFileName(uint64_t cr3, uint64_t pc);

  bool SeenCr3(uint64_t cr3);

  uint64_t kernel_cr3() const { return kernel_cr3_; }
  void set_kernel_cr3(uint64_t cr3) { kernel_cr3_ = cr3; }

  const pt_config& config() const { return config_; }
  void set_nom_freq(uint8_t nom_freq) { config_.nom_freq = nom_freq; }
  void set_family(uint32_t family) { config_.cpu.family = family; }
  void set_model(uint32_t model) { config_.cpu.model = model; }
  void set_stepping(uint32_t stepping) { config_.cpu.stepping = stepping; }

  bool AllocDecoder(const std::string& pt_file);
  void FreeDecoder();
  pt_insn_decoder* decoder() const { return decoder_; }

  const std::vector<Process>& processes() const { return processes_; }

  const std::vector<PtFile>& pt_files() const { return pt_files_; }

  const std::unordered_set<uint64_t>& unknown_cr3s() const { return unknown_cr3s_; }

 private:
  DecoderState();

  bool AllocImage(const std::string& name);

  bool ReadKtraceFile(const std::string& file);
  bool ReadMapFile(const std::string& file);
  bool ReadIdsFile(const std::string& file);
  bool ReadPtListFile(const std::string& file);

  void AddSymtab(std::unique_ptr<SymbolTable> symtab);
  bool ReadElf(const std::string& file, uint64_t base, uint64_t cr3, uint64_t file_off,
               uint64_t map_len);
  bool ReadKernelElf(const std::string& file, uint64_t cr3);

  void SetKernelCr3(uint64_t cr3) { kernel_cr3_ = cr3; }

  static int ReadMemCallback(uint8_t* buffer, size_t size, const struct pt_asid* asid,
                             uint64_t addr, void* context);

  static int ProcessKtraceRecord(debugger_utils::KtraceRecord* rec, void* arg);

  bool AddProcess(zx_koid_t pid, uint64_t cr3, uint64_t start_time);
  bool MarkProcessExited(zx_koid_t pid, uint64_t end_time);

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

  pt_config config_;
  pt_image* image_;
  pt_insn_decoder* decoder_;

  uint64_t kernel_cr3_;

  std::vector<Process> processes_;
  debugger_utils::LoadMapTable load_maps_;
  debugger_utils::BuildIdTable build_ids_;
  std::vector<PtFile> pt_files_;

  // List of cr3 values seen that we don't have processes for.
  // This helps printers explain the results to human readers.
  std::unordered_set<uint64_t> unknown_cr3s_;

  std::vector<std::unique_ptr<SymbolTable>> symtabs_;
};

}  // namespace intel_processor_trace

#endif  // SRC_LIB_INTEL_PT_DECODE_DECODER_H_
