//===-- TraceInstructionDumper.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/TraceInstructionDumper.h"

#include "lldb/Core/Module.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"

using namespace lldb;
using namespace lldb_private;
using namespace llvm;

TraceInstructionDumper::TraceInstructionDumper(lldb::TraceCursorUP &&cursor_up,
                                               int initial_index, bool raw,
                                               bool show_tsc)
    : m_cursor_up(std::move(cursor_up)), m_index(initial_index), m_raw(raw),
      m_show_tsc(show_tsc) {}

/// \return
///     Return \b true if the cursor could move one step.
bool TraceInstructionDumper::TryMoveOneStep() {
  if (!m_cursor_up->Next()) {
    SetNoMoreData();
    return false;
  }
  m_index += m_cursor_up->IsForwards() ? 1 : -1;
  return true;
}

/// \return
///     The number of characters that would be needed to print the given
///     integer.
static int GetNumberOfChars(int num) {
  if (num == 0)
    return 1;
  return (num < 0 ? 1 : 0) + static_cast<int>(log10(abs(num))) + 1;
}

/// Helper struct that holds symbol, disassembly and address information of an
/// instruction.
struct InstructionSymbolInfo {
  SymbolContext sc;
  Address address;
  lldb::addr_t load_address;
  lldb::DisassemblerSP disassembler;
  lldb::InstructionSP instruction;
  lldb_private::ExecutionContext exe_ctx;
};

// This custom LineEntry validator is neded because some line_entries have
// 0 as line, which is meaningless. Notice that LineEntry::IsValid only
// checks that line is not LLDB_INVALID_LINE_NUMBER, i.e. UINT32_MAX.
static bool IsLineEntryValid(const LineEntry &line_entry) {
  return line_entry.IsValid() && line_entry.line > 0;
}

/// \return
///     \b true if the provided line entries match line, column and source file.
///     This function assumes that the line entries are valid.
static bool FileLineAndColumnMatches(const LineEntry &a, const LineEntry &b) {
  if (a.line != b.line)
    return false;
  if (a.column != b.column)
    return false;
  return a.file == b.file;
}

/// Compare the symbol contexts of the provided \a InstructionSymbolInfo
/// objects.
///
/// \return
///     \a true if both instructions belong to the same scope level analized
///     in the following order:
///       - module
///       - symbol
///       - function
///       - line
static bool
IsSameInstructionSymbolContext(const InstructionSymbolInfo &prev_insn,
                               const InstructionSymbolInfo &insn) {
  // module checks
  if (insn.sc.module_sp != prev_insn.sc.module_sp)
    return false;

  // symbol checks
  if (insn.sc.symbol != prev_insn.sc.symbol)
    return false;

  // function checks
  if (!insn.sc.function && !prev_insn.sc.function)
    return true;
  else if (insn.sc.function != prev_insn.sc.function)
    return false;

  // line entry checks
  const bool curr_line_valid = IsLineEntryValid(insn.sc.line_entry);
  const bool prev_line_valid = IsLineEntryValid(prev_insn.sc.line_entry);
  if (curr_line_valid && prev_line_valid)
    return FileLineAndColumnMatches(insn.sc.line_entry,
                                    prev_insn.sc.line_entry);
  return curr_line_valid == prev_line_valid;
}

/// Dump the symbol context of the given instruction address if it's different
/// from the symbol context of the previous instruction in the trace.
///
/// \param[in] prev_sc
///     The symbol context of the previous instruction in the trace.
///
/// \param[in] address
///     The address whose symbol information will be dumped.
///
/// \return
///     The symbol context of the current address, which might differ from the
///     previous one.
static void
DumpInstructionSymbolContext(Stream &s,
                             Optional<InstructionSymbolInfo> prev_insn,
                             InstructionSymbolInfo &insn) {
  if (prev_insn && IsSameInstructionSymbolContext(*prev_insn, insn))
    return;

  s.Printf("  ");

  if (!insn.sc.module_sp)
    s.Printf("(none)");
  else if (!insn.sc.function && !insn.sc.symbol)
    s.Printf("%s`(none)",
             insn.sc.module_sp->GetFileSpec().GetFilename().AsCString());
  else
    insn.sc.DumpStopContext(&s, insn.exe_ctx.GetTargetPtr(), insn.address,
                            /*show_fullpath=*/false,
                            /*show_module=*/true, /*show_inlined_frames=*/false,
                            /*show_function_arguments=*/true,
                            /*show_function_name=*/true);
  s.Printf("\n");
}

static void DumpInstructionDisassembly(Stream &s, InstructionSymbolInfo &insn) {
  if (!insn.instruction)
    return;
  s.Printf("    ");
  insn.instruction->Dump(&s, /*show_address=*/false, /*show_bytes=*/false,
                         /*max_opcode_byte_size=*/0, &insn.exe_ctx, &insn.sc,
                         /*prev_sym_ctx=*/nullptr,
                         /*disassembly_addr_format=*/nullptr,
                         /*max_address_text_size=*/0);
}

void TraceInstructionDumper::SetNoMoreData() { m_no_more_data = true; }

bool TraceInstructionDumper::HasMoreData() { return !m_no_more_data; }

void TraceInstructionDumper::DumpInstructions(Stream &s, size_t count) {
  ThreadSP thread_sp = m_cursor_up->GetExecutionContextRef().GetThreadSP();
  if (!thread_sp) {
    s.Printf("invalid thread");
    return;
  }

  s.Printf("thread #%u: tid = %" PRIu64 "\n", thread_sp->GetIndexID(),
           thread_sp->GetID());

  int digits_count = GetNumberOfChars(
      m_cursor_up->IsForwards() ? m_index + count - 1 : m_index - count + 1);
  bool was_prev_instruction_an_error = false;

  auto printMissingInstructionsMessage = [&]() {
    s.Printf("    ...missing instructions\n");
  };

  auto printInstructionIndex = [&]() {
    s.Printf("    [%*d] ", digits_count, m_index);

    if (m_show_tsc) {
      s.Printf("[tsc=");

      if (Optional<uint64_t> timestamp = m_cursor_up->GetTimestampCounter())
        s.Printf("0x%016" PRIx64, *timestamp);
      else
        s.Printf("unavailable");

      s.Printf("] ");
    }
  };

  InstructionSymbolInfo prev_insn_info;

  Target &target = thread_sp->GetProcess()->GetTarget();
  ExecutionContext exe_ctx;
  target.CalculateExecutionContext(exe_ctx);
  const ArchSpec &arch = target.GetArchitecture();

  // Find the symbol context for the given address reusing the previous
  // instruction's symbol context when possible.
  auto calculateSymbolContext = [&](const Address &address) {
    AddressRange range;
    if (prev_insn_info.sc.GetAddressRange(eSymbolContextEverything, 0,
                                          /*inline_block_range*/ false,
                                          range) &&
        range.Contains(address))
      return prev_insn_info.sc;

    SymbolContext sc;
    address.CalculateSymbolContext(&sc, eSymbolContextEverything);
    return sc;
  };

  // Find the disassembler for the given address reusing the previous
  // instruction's disassembler when possible.
  auto calculateDisass = [&](const Address &address, const SymbolContext &sc) {
    if (prev_insn_info.disassembler) {
      if (InstructionSP instruction =
              prev_insn_info.disassembler->GetInstructionList()
                  .GetInstructionAtAddress(address))
        return std::make_tuple(prev_insn_info.disassembler, instruction);
    }

    if (sc.function) {
      if (DisassemblerSP disassembler =
              sc.function->GetInstructions(exe_ctx, nullptr)) {
        if (InstructionSP instruction =
                disassembler->GetInstructionList().GetInstructionAtAddress(
                    address))
          return std::make_tuple(disassembler, instruction);
      }
    }
    // We fallback to a single instruction disassembler
    AddressRange range(address, arch.GetMaximumOpcodeByteSize());
    DisassemblerSP disassembler =
        Disassembler::DisassembleRange(arch, /*plugin_name*/ nullptr,
                                       /*flavor*/ nullptr, target, range);
    return std::make_tuple(disassembler,
                           disassembler ? disassembler->GetInstructionList()
                                              .GetInstructionAtAddress(address)
                                        : InstructionSP());
  };

  for (size_t i = 0; i < count; i++) {
    if (!HasMoreData()) {
      s.Printf("    no more data\n");
      break;
    }

    if (Error err = m_cursor_up->GetError()) {
      if (!m_cursor_up->IsForwards() && !was_prev_instruction_an_error)
        printMissingInstructionsMessage();

      was_prev_instruction_an_error = true;

      printInstructionIndex();
      s << toString(std::move(err));
    } else {
      if (m_cursor_up->IsForwards() && was_prev_instruction_an_error)
        printMissingInstructionsMessage();

      was_prev_instruction_an_error = false;

      InstructionSymbolInfo insn_info;

      if (!m_raw) {
        insn_info.load_address = m_cursor_up->GetLoadAddress();
        insn_info.exe_ctx = exe_ctx;
        insn_info.address.SetLoadAddress(insn_info.load_address, &target);
        insn_info.sc = calculateSymbolContext(insn_info.address);
        std::tie(insn_info.disassembler, insn_info.instruction) =
            calculateDisass(insn_info.address, insn_info.sc);

        DumpInstructionSymbolContext(s, prev_insn_info, insn_info);
      }

      printInstructionIndex();
      s.Printf("0x%016" PRIx64, m_cursor_up->GetLoadAddress());

      if (!m_raw)
        DumpInstructionDisassembly(s, insn_info);

      prev_insn_info = insn_info;
    }

    s.Printf("\n");
    TryMoveOneStep();
  }
}
