Path: blob/main/contrib/llvm-project/lldb/source/API/SBInstructionList.cpp
39587 views
//===-- SBInstructionList.cpp ---------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/API/SBInstructionList.h"9#include "lldb/API/SBAddress.h"10#include "lldb/API/SBFile.h"11#include "lldb/API/SBInstruction.h"12#include "lldb/API/SBStream.h"13#include "lldb/Core/Disassembler.h"14#include "lldb/Core/Module.h"15#include "lldb/Host/StreamFile.h"16#include "lldb/Symbol/SymbolContext.h"17#include "lldb/Utility/Instrumentation.h"18#include "lldb/Utility/Stream.h"1920using namespace lldb;21using namespace lldb_private;2223SBInstructionList::SBInstructionList() { LLDB_INSTRUMENT_VA(this); }2425SBInstructionList::SBInstructionList(const SBInstructionList &rhs)26: m_opaque_sp(rhs.m_opaque_sp) {27LLDB_INSTRUMENT_VA(this, rhs);28}2930const SBInstructionList &SBInstructionList::31operator=(const SBInstructionList &rhs) {32LLDB_INSTRUMENT_VA(this, rhs);3334if (this != &rhs)35m_opaque_sp = rhs.m_opaque_sp;36return *this;37}3839SBInstructionList::~SBInstructionList() = default;4041bool SBInstructionList::IsValid() const {42LLDB_INSTRUMENT_VA(this);43return this->operator bool();44}45SBInstructionList::operator bool() const {46LLDB_INSTRUMENT_VA(this);4748return m_opaque_sp.get() != nullptr;49}5051size_t SBInstructionList::GetSize() {52LLDB_INSTRUMENT_VA(this);5354if (m_opaque_sp)55return m_opaque_sp->GetInstructionList().GetSize();56return 0;57}5859SBInstruction SBInstructionList::GetInstructionAtIndex(uint32_t idx) {60LLDB_INSTRUMENT_VA(this, idx);6162SBInstruction inst;63if (m_opaque_sp && idx < m_opaque_sp->GetInstructionList().GetSize())64inst.SetOpaque(65m_opaque_sp,66m_opaque_sp->GetInstructionList().GetInstructionAtIndex(idx));67return inst;68}6970size_t SBInstructionList::GetInstructionsCount(const SBAddress &start,71const SBAddress &end,72bool canSetBreakpoint) {73LLDB_INSTRUMENT_VA(this, start, end, canSetBreakpoint);7475size_t num_instructions = GetSize();76size_t i = 0;77SBAddress addr;78size_t lower_index = 0;79size_t upper_index = 0;80size_t instructions_to_skip = 0;81for (i = 0; i < num_instructions; ++i) {82addr = GetInstructionAtIndex(i).GetAddress();83if (start == addr)84lower_index = i;85if (end == addr)86upper_index = i;87}88if (canSetBreakpoint)89for (i = lower_index; i <= upper_index; ++i) {90SBInstruction insn = GetInstructionAtIndex(i);91if (!insn.CanSetBreakpoint())92++instructions_to_skip;93}94return upper_index - lower_index - instructions_to_skip;95}9697void SBInstructionList::Clear() {98LLDB_INSTRUMENT_VA(this);99100m_opaque_sp.reset();101}102103void SBInstructionList::AppendInstruction(SBInstruction insn) {104LLDB_INSTRUMENT_VA(this, insn);105}106107void SBInstructionList::SetDisassembler(const lldb::DisassemblerSP &opaque_sp) {108m_opaque_sp = opaque_sp;109}110111void SBInstructionList::Print(FILE *out) {112LLDB_INSTRUMENT_VA(this, out);113if (out == nullptr)114return;115StreamFile stream(out, false);116GetDescription(stream);117}118119void SBInstructionList::Print(SBFile out) {120LLDB_INSTRUMENT_VA(this, out);121if (!out.IsValid())122return;123StreamFile stream(out.m_opaque_sp);124GetDescription(stream);125}126127void SBInstructionList::Print(FileSP out_sp) {128LLDB_INSTRUMENT_VA(this, out_sp);129if (!out_sp || !out_sp->IsValid())130return;131StreamFile stream(out_sp);132GetDescription(stream);133}134135bool SBInstructionList::GetDescription(lldb::SBStream &stream) {136LLDB_INSTRUMENT_VA(this, stream);137return GetDescription(stream.ref());138}139140bool SBInstructionList::GetDescription(Stream &sref) {141142if (m_opaque_sp) {143size_t num_instructions = GetSize();144if (num_instructions) {145// Call the ref() to make sure a stream is created if one deesn't exist146// already inside description...147const uint32_t max_opcode_byte_size =148m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();149FormatEntity::Entry format;150FormatEntity::Parse("${addr}: ", format);151SymbolContext sc;152SymbolContext prev_sc;153for (size_t i = 0; i < num_instructions; ++i) {154Instruction *inst =155m_opaque_sp->GetInstructionList().GetInstructionAtIndex(i).get();156if (inst == nullptr)157break;158159const Address &addr = inst->GetAddress();160prev_sc = sc;161ModuleSP module_sp(addr.GetModule());162if (module_sp) {163module_sp->ResolveSymbolContextForAddress(164addr, eSymbolContextEverything, sc);165}166167inst->Dump(&sref, max_opcode_byte_size, true, false,168/*show_control_flow_kind=*/false, nullptr, &sc, &prev_sc,169&format, 0);170sref.EOL();171}172return true;173}174}175return false;176}177178bool SBInstructionList::DumpEmulationForAllInstructions(const char *triple) {179LLDB_INSTRUMENT_VA(this, triple);180181if (m_opaque_sp) {182size_t len = GetSize();183for (size_t i = 0; i < len; ++i) {184if (!GetInstructionAtIndex((uint32_t)i).DumpEmulation(triple))185return false;186}187}188return true;189}190191192