//===-- SBInstruction.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/API/SBInstruction.h"
#include "lldb/Utility/Instrumentation.h"

#include "lldb/API/SBAddress.h"
#include "lldb/API/SBFile.h"
#include "lldb/API/SBFrame.h"

#include "lldb/API/SBStream.h"
#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBTarget.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Module.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StreamFile.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StructuredData.h"

#include <memory>

// We recently fixed a leak in one of the Instruction subclasses where the
// instruction will only hold a weak reference to the disassembler to avoid a
// cycle that was keeping both objects alive (leak) and we need the
// InstructionImpl class to make sure our public API behaves as users would
// expect. Calls in our public API allow clients to do things like:
//
// 1  lldb::SBInstruction inst;
// 2  inst = target.ReadInstructions(pc, 1).GetInstructionAtIndex(0)
// 3  if (inst.DoesBranch())
// 4  ...
//
// There was a temporary lldb::DisassemblerSP object created in the
// SBInstructionList that was returned by lldb.target.ReadInstructions() that
// will go away after line 2 but the "inst" object should be able to still
// answer questions about itself. So we make sure that any SBInstruction
// objects that are given out have a strong reference to the disassembler and
// the instruction so that the object can live and successfully respond to all
// queries.
class InstructionImpl {
public:
  InstructionImpl(const lldb::DisassemblerSP &disasm_sp,
                  const lldb::InstructionSP &inst_sp)
      : m_disasm_sp(disasm_sp), m_inst_sp(inst_sp) {}

  lldb::InstructionSP GetSP() const { return m_inst_sp; }

  bool IsValid() const { return (bool)m_inst_sp; }

protected:
  lldb::DisassemblerSP m_disasm_sp; // Can be empty/invalid
  lldb::InstructionSP m_inst_sp;
};

using namespace lldb;
using namespace lldb_private;

SBInstruction::SBInstruction() { LLDB_INSTRUMENT_VA(this); }

SBInstruction::SBInstruction(const lldb::DisassemblerSP &disasm_sp,
                             const lldb::InstructionSP &inst_sp)
    : m_opaque_sp(new InstructionImpl(disasm_sp, inst_sp)) {}

SBInstruction::SBInstruction(const SBInstruction &rhs)
    : m_opaque_sp(rhs.m_opaque_sp) {
  LLDB_INSTRUMENT_VA(this, rhs);
}

const SBInstruction &SBInstruction::operator=(const SBInstruction &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  if (this != &rhs)
    m_opaque_sp = rhs.m_opaque_sp;
  return *this;
}

SBInstruction::~SBInstruction() = default;

bool SBInstruction::IsValid() {
  LLDB_INSTRUMENT_VA(this);
  return this->operator bool();
}
SBInstruction::operator bool() const {
  LLDB_INSTRUMENT_VA(this);

  return m_opaque_sp && m_opaque_sp->IsValid();
}

SBAddress SBInstruction::GetAddress() {
  LLDB_INSTRUMENT_VA(this);

  SBAddress sb_addr;
  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp && inst_sp->GetAddress().IsValid())
    sb_addr.SetAddress(inst_sp->GetAddress());
  return sb_addr;
}

const char *SBInstruction::GetMnemonic(SBTarget target) {
  LLDB_INSTRUMENT_VA(this, target);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (!inst_sp)
    return nullptr;

  ExecutionContext exe_ctx;
  TargetSP target_sp(target.GetSP());
  TargetAPIMutex api_lock;
  std::unique_lock<TargetAPIMutex> guard;
  if (target_sp) {
    api_lock = TargetAPIMutex(target_sp->GetAPIMutex());
    guard = std::unique_lock<TargetAPIMutex>(api_lock);

    target_sp->CalculateExecutionContext(exe_ctx);
    exe_ctx.SetProcessSP(target_sp->GetProcessSP());
  }
  return ConstString(inst_sp->GetMnemonic(&exe_ctx)).GetCString();
}

const char *SBInstruction::GetOperands(SBTarget target) {
  LLDB_INSTRUMENT_VA(this, target);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (!inst_sp)
    return nullptr;

  ExecutionContext exe_ctx;
  TargetSP target_sp(target.GetSP());
  TargetAPIMutex api_lock;
  std::unique_lock<TargetAPIMutex> guard;
  if (target_sp) {
    api_lock = TargetAPIMutex(target_sp->GetAPIMutex());
    guard = std::unique_lock<TargetAPIMutex>(api_lock);

    target_sp->CalculateExecutionContext(exe_ctx);
    exe_ctx.SetProcessSP(target_sp->GetProcessSP());
  }
  return ConstString(inst_sp->GetOperands(&exe_ctx)).GetCString();
}

const char *SBInstruction::GetComment(SBTarget target) {
  LLDB_INSTRUMENT_VA(this, target);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (!inst_sp)
    return nullptr;

  ExecutionContext exe_ctx;
  TargetSP target_sp(target.GetSP());
  TargetAPIMutex api_lock;
  std::unique_lock<TargetAPIMutex> guard;
  if (target_sp) {
    api_lock = TargetAPIMutex(target_sp->GetAPIMutex());
    guard = std::unique_lock<TargetAPIMutex>(api_lock);

    target_sp->CalculateExecutionContext(exe_ctx);
    exe_ctx.SetProcessSP(target_sp->GetProcessSP());
  }
  return ConstString(inst_sp->GetComment(&exe_ctx)).GetCString();
}

lldb::InstructionControlFlowKind
SBInstruction::GetControlFlowKind(lldb::SBTarget target) {
  LLDB_INSTRUMENT_VA(this, target);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    ExecutionContext exe_ctx;
    TargetSP target_sp(target.GetSP());
    TargetAPIMutex api_lock;
    std::unique_lock<TargetAPIMutex> guard;
    if (target_sp) {
      api_lock = TargetAPIMutex(target_sp->GetAPIMutex());
      guard = std::unique_lock<TargetAPIMutex>(api_lock);

      target_sp->CalculateExecutionContext(exe_ctx);
      exe_ctx.SetProcessSP(target_sp->GetProcessSP());
    }
    return inst_sp->GetControlFlowKind(&exe_ctx);
  }
  return lldb::eInstructionControlFlowKindUnknown;
}

size_t SBInstruction::GetByteSize() {
  LLDB_INSTRUMENT_VA(this);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->GetOpcode().GetByteSize();
  return 0;
}

SBData SBInstruction::GetData(SBTarget target) {
  LLDB_INSTRUMENT_VA(this, target);

  lldb::SBData sb_data;
  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    DataExtractorSP data_extractor_sp(new DataExtractor());
    if (inst_sp->GetData(*data_extractor_sp)) {
      sb_data.SetOpaque(data_extractor_sp);
    }
  }
  return sb_data;
}

bool SBInstruction::DoesBranch() {
  LLDB_INSTRUMENT_VA(this);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->DoesBranch();
  return false;
}

bool SBInstruction::HasDelaySlot() {
  LLDB_INSTRUMENT_VA(this);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->HasDelaySlot();
  return false;
}

bool SBInstruction::CanSetBreakpoint() {
  LLDB_INSTRUMENT_VA(this);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->CanSetBreakpoint();
  return false;
}

lldb::InstructionSP SBInstruction::GetOpaque() {
  if (m_opaque_sp)
    return m_opaque_sp->GetSP();
  else
    return lldb::InstructionSP();
}

void SBInstruction::SetOpaque(const lldb::DisassemblerSP &disasm_sp,
                              const lldb::InstructionSP &inst_sp) {
  m_opaque_sp = std::make_shared<InstructionImpl>(disasm_sp, inst_sp);
}

bool SBInstruction::GetDescription(lldb::SBStream &s) {
  LLDB_INSTRUMENT_VA(this, s);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    SymbolContext sc;
    const Address &addr = inst_sp->GetAddress();
    ModuleSP module_sp(addr.GetModule());
    if (module_sp)
      module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything,
                                                sc);
    // Use the "ref()" instead of the "get()" accessor in case the SBStream
    // didn't have a stream already created, one will get created...
    FormatEntity::Entry format;
    FormatEntity::Parse("${addr}: ", format);
    inst_sp->Dump(&s.ref(), 0, true, false, /*show_control_flow_kind=*/false,
                  nullptr, &sc, nullptr, &format, 0);
    return true;
  }
  return false;
}

void SBInstruction::Print(FILE *outp) {
  LLDB_INSTRUMENT_VA(this, outp);
  FileSP out = std::make_shared<NativeFile>(outp, File::eOpenOptionWriteOnly,
                                            /*take_ownership=*/false);
  Print(out);
}

void SBInstruction::Print(SBFile out) {
  LLDB_INSTRUMENT_VA(this, out);
  Print(out.m_opaque_sp);
}

void SBInstruction::Print(FileSP out_sp) {
  LLDB_INSTRUMENT_VA(this, out_sp);

  if (!out_sp || !out_sp->IsValid())
    return;

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    SymbolContext sc;
    const Address &addr = inst_sp->GetAddress();
    ModuleSP module_sp(addr.GetModule());
    if (module_sp)
      module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything,
                                                sc);
    StreamFile out_stream(out_sp);
    FormatEntity::Entry format;
    FormatEntity::Parse("${addr}: ", format);
    inst_sp->Dump(&out_stream, 0, true, false, /*show_control_flow_kind=*/false,
                  nullptr, &sc, nullptr, &format, 0);
  }
}

bool SBInstruction::EmulateWithFrame(lldb::SBFrame &frame,
                                     uint32_t evaluate_options) {
  LLDB_INSTRUMENT_VA(this, frame, evaluate_options);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    lldb::StackFrameSP frame_sp(frame.GetFrameSP());

    if (frame_sp) {
      lldb_private::ExecutionContext exe_ctx;
      frame_sp->CalculateExecutionContext(exe_ctx);
      lldb_private::Target *target = exe_ctx.GetTargetPtr();
      lldb_private::ArchSpec arch = target->GetArchitecture();

      return inst_sp->Emulate(
          arch, evaluate_options, (void *)frame_sp.get(),
          &lldb_private::EmulateInstruction::ReadMemoryFrame,
          &lldb_private::EmulateInstruction::WriteMemoryFrame,
          &lldb_private::EmulateInstruction::ReadRegisterFrame,
          &lldb_private::EmulateInstruction::WriteRegisterFrame);
    }
  }
  return false;
}

bool SBInstruction::DumpEmulation(const char *triple) {
  LLDB_INSTRUMENT_VA(this, triple);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp && triple) {
    return inst_sp->DumpEmulation(HostInfo::GetAugmentedArchSpec(triple));
  }
  return false;
}

bool SBInstruction::TestEmulation(lldb::SBStream &output_stream,
                                  const char *test_file) {
  LLDB_INSTRUMENT_VA(this, output_stream, test_file);

  if (!m_opaque_sp)
    SetOpaque(lldb::DisassemblerSP(),
              lldb::InstructionSP(new PseudoInstruction()));

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->TestEmulation(output_stream.ref(), test_file);
  return false;
}

SBStructuredData SBInstruction::GetVariableAnnotations() {
  LLDB_INSTRUMENT_VA(this);

  SBStructuredData result;

  if (!m_opaque_sp || !m_opaque_sp->IsValid())
    return result;

  lldb::InstructionSP inst_sp = m_opaque_sp->GetSP();
  if (!inst_sp)
    return result;

  StructuredData::ArraySP array_sp = inst_sp->GetVariableAnnotations();
  result.m_impl_up->SetObjectSP(array_sp);

  return result;
}
