brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · 0d958c6 Raw
209 lines · cpp
1//===-- SBInstructionList.cpp ---------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/API/SBInstructionList.h"10#include "lldb/API/SBAddress.h"11#include "lldb/API/SBExecutionContext.h"12#include "lldb/API/SBFile.h"13#include "lldb/API/SBInstruction.h"14#include "lldb/API/SBStream.h"15#include "lldb/Core/Disassembler.h"16#include "lldb/Core/Module.h"17#include "lldb/Host/StreamFile.h"18#include "lldb/Symbol/SymbolContext.h"19#include "lldb/Target/ExecutionContext.h"20#include "lldb/Utility/Instrumentation.h"21#include "lldb/Utility/Stream.h"22 23using namespace lldb;24using namespace lldb_private;25 26SBInstructionList::SBInstructionList() { LLDB_INSTRUMENT_VA(this); }27 28SBInstructionList::SBInstructionList(const SBInstructionList &rhs)29    : m_opaque_sp(rhs.m_opaque_sp) {30  LLDB_INSTRUMENT_VA(this, rhs);31}32 33const SBInstructionList &SBInstructionList::34operator=(const SBInstructionList &rhs) {35  LLDB_INSTRUMENT_VA(this, rhs);36 37  if (this != &rhs)38    m_opaque_sp = rhs.m_opaque_sp;39  return *this;40}41 42SBInstructionList::~SBInstructionList() = default;43 44bool SBInstructionList::IsValid() const {45  LLDB_INSTRUMENT_VA(this);46  return this->operator bool();47}48SBInstructionList::operator bool() const {49  LLDB_INSTRUMENT_VA(this);50 51  return m_opaque_sp.get() != nullptr;52}53 54size_t SBInstructionList::GetSize() {55  LLDB_INSTRUMENT_VA(this);56 57  if (m_opaque_sp)58    return m_opaque_sp->GetInstructionList().GetSize();59  return 0;60}61 62SBInstruction SBInstructionList::GetInstructionAtIndex(uint32_t idx) {63  LLDB_INSTRUMENT_VA(this, idx);64 65  SBInstruction inst;66  if (m_opaque_sp && idx < m_opaque_sp->GetInstructionList().GetSize())67    inst.SetOpaque(68        m_opaque_sp,69        m_opaque_sp->GetInstructionList().GetInstructionAtIndex(idx));70  return inst;71}72 73size_t SBInstructionList::GetInstructionsCount(const SBAddress &start,74                                               const SBAddress &end,75                                               bool canSetBreakpoint) {76  LLDB_INSTRUMENT_VA(this, start, end, canSetBreakpoint);77 78  size_t num_instructions = GetSize();79  size_t i = 0;80  SBAddress addr;81  size_t lower_index = 0;82  size_t upper_index = 0;83  size_t instructions_to_skip = 0;84  for (i = 0; i < num_instructions; ++i) {85    addr = GetInstructionAtIndex(i).GetAddress();86    if (start == addr)87      lower_index = i;88    if (end == addr)89      upper_index = i;90  }91  if (canSetBreakpoint)92    for (i = lower_index; i <= upper_index; ++i) {93      SBInstruction insn = GetInstructionAtIndex(i);94      if (!insn.CanSetBreakpoint())95        ++instructions_to_skip;96    }97  return upper_index - lower_index - instructions_to_skip;98}99 100void SBInstructionList::Clear() {101  LLDB_INSTRUMENT_VA(this);102 103  m_opaque_sp.reset();104}105 106void SBInstructionList::AppendInstruction(SBInstruction insn) {107  LLDB_INSTRUMENT_VA(this, insn);108}109 110void SBInstructionList::SetDisassembler(const lldb::DisassemblerSP &opaque_sp) {111  m_opaque_sp = opaque_sp;112}113 114void SBInstructionList::Print(FILE *out) {115  LLDB_INSTRUMENT_VA(this, out);116  if (out == nullptr)117    return;118  StreamFile stream(out, false);119  GetDescription(stream);120}121 122void SBInstructionList::Print(SBFile out) {123  LLDB_INSTRUMENT_VA(this, out);124  if (!out.IsValid())125    return;126  StreamFile stream(out.m_opaque_sp);127  GetDescription(stream);128}129 130void SBInstructionList::Print(FileSP out_sp) {131  LLDB_INSTRUMENT_VA(this, out_sp);132  if (!out_sp || !out_sp->IsValid())133    return;134  StreamFile stream(out_sp);135  GetDescription(stream);136}137 138bool SBInstructionList::GetDescription(lldb::SBStream &stream) {139  LLDB_INSTRUMENT_VA(this, stream);140  return GetDescription(stream.ref());141}142 143bool SBInstructionList::GetDescription(lldb::SBStream &stream,144                                       lldb::SBExecutionContext &exe_ctx) {145  LLDB_INSTRUMENT_VA(this, stream);146  ExecutionContext exe_ctx_wrapper(exe_ctx.get());147  return GetDescription(stream.ref(), &exe_ctx_wrapper);148}149 150bool SBInstructionList::GetDescription(151    Stream &sref, lldb_private::ExecutionContext *exe_ctx) {152 153  if (m_opaque_sp) {154    size_t num_instructions = GetSize();155    if (num_instructions) {156      // Call the ref() to make sure a stream is created if one deesn't exist157      // already inside description...158      const uint32_t max_opcode_byte_size =159          m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();160      FormatEntity::Entry format;161      FormatEntity::Parse("${addr-file-or-load}: ", format);162      SymbolContext sc;163      SymbolContext prev_sc;164 165      // Expected address of the next instruction. Used to print an empty line166      // for non-contiguous blocks of insns.167      std::optional<Address> next_addr;168      for (size_t i = 0; i < num_instructions; ++i) {169        Instruction *inst =170            m_opaque_sp->GetInstructionList().GetInstructionAtIndex(i).get();171        if (inst == nullptr)172          break;173 174        const Address &addr = inst->GetAddress();175        prev_sc = sc;176        ModuleSP module_sp(addr.GetModule());177        if (module_sp) {178          module_sp->ResolveSymbolContextForAddress(179              addr, eSymbolContextEverything, sc);180        }181 182        if (next_addr && *next_addr != addr)183          sref.EOL();184        inst->Dump(&sref, max_opcode_byte_size, true, false,185                   /*show_control_flow_kind=*/false, exe_ctx, &sc, &prev_sc,186                   &format, 0);187        sref.EOL();188        next_addr = addr;189        next_addr->Slide(inst->GetOpcode().GetByteSize());190      }191      return true;192    }193  }194  return false;195}196 197bool SBInstructionList::DumpEmulationForAllInstructions(const char *triple) {198  LLDB_INSTRUMENT_VA(this, triple);199 200  if (m_opaque_sp) {201    size_t len = GetSize();202    for (size_t i = 0; i < len; ++i) {203      if (!GetInstructionAtIndex((uint32_t)i).DumpEmulation(triple))204        return false;205    }206  }207  return true;208}209