180814287SRaphael Isemann //===-- SBInstructionList.cpp ---------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/API/SBInstructionList.h"
10dd125943SNitesh Jain #include "lldb/API/SBAddress.h"
111755f5b1SJonas Devlieghere #include "lldb/API/SBFile.h"
12baf5664fSJonas Devlieghere #include "lldb/API/SBInstruction.h"
131d273166SGreg Clayton #include "lldb/API/SBStream.h"
141d273166SGreg Clayton #include "lldb/Core/Disassembler.h"
15aff1b357SJason Molenda #include "lldb/Core/Module.h"
16e7a91156SLawrence D'Anna #include "lldb/Core/StreamFile.h"
17aff1b357SJason Molenda #include "lldb/Symbol/SymbolContext.h"
181755f5b1SJonas Devlieghere #include "lldb/Utility/Instrumentation.h"
19bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
2030fdc8d8SChris Lattner
2130fdc8d8SChris Lattner using namespace lldb;
221d273166SGreg Clayton using namespace lldb_private;
2330fdc8d8SChris Lattner
SBInstructionList()241755f5b1SJonas Devlieghere SBInstructionList::SBInstructionList() { LLDB_INSTRUMENT_VA(this); }
2530fdc8d8SChris Lattner
SBInstructionList(const SBInstructionList & rhs)26b9c1b51eSKate Stone SBInstructionList::SBInstructionList(const SBInstructionList &rhs)
27baf5664fSJonas Devlieghere : m_opaque_sp(rhs.m_opaque_sp) {
281755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, rhs);
29baf5664fSJonas Devlieghere }
3030fdc8d8SChris Lattner
31b9c1b51eSKate Stone const SBInstructionList &SBInstructionList::
operator =(const SBInstructionList & rhs)32b9c1b51eSKate Stone operator=(const SBInstructionList &rhs) {
331755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, rhs);
34baf5664fSJonas Devlieghere
35efabb123SGreg Clayton if (this != &rhs)
36efabb123SGreg Clayton m_opaque_sp = rhs.m_opaque_sp;
37d232abc3SJonas Devlieghere return *this;
38efabb123SGreg Clayton }
39efabb123SGreg Clayton
40866b7a65SJonas Devlieghere SBInstructionList::~SBInstructionList() = default;
41efabb123SGreg Clayton
IsValid() const42baf5664fSJonas Devlieghere bool SBInstructionList::IsValid() const {
431755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
447f5237bcSPavel Labath return this->operator bool();
457f5237bcSPavel Labath }
operator bool() const467f5237bcSPavel Labath SBInstructionList::operator bool() const {
471755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
48baf5664fSJonas Devlieghere
49248a1305SKonrad Kleine return m_opaque_sp.get() != nullptr;
50baf5664fSJonas Devlieghere }
5130fdc8d8SChris Lattner
GetSize()52b9c1b51eSKate Stone size_t SBInstructionList::GetSize() {
531755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
54baf5664fSJonas Devlieghere
551d273166SGreg Clayton if (m_opaque_sp)
561d273166SGreg Clayton return m_opaque_sp->GetInstructionList().GetSize();
5730fdc8d8SChris Lattner return 0;
5830fdc8d8SChris Lattner }
5930fdc8d8SChris Lattner
GetInstructionAtIndex(uint32_t idx)60b9c1b51eSKate Stone SBInstruction SBInstructionList::GetInstructionAtIndex(uint32_t idx) {
611755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, idx);
62baf5664fSJonas Devlieghere
6330fdc8d8SChris Lattner SBInstruction inst;
641d273166SGreg Clayton if (m_opaque_sp && idx < m_opaque_sp->GetInstructionList().GetSize())
65b9c1b51eSKate Stone inst.SetOpaque(
66b9c1b51eSKate Stone m_opaque_sp,
67b9c1b51eSKate Stone m_opaque_sp->GetInstructionList().GetInstructionAtIndex(idx));
68d232abc3SJonas Devlieghere return inst;
6930fdc8d8SChris Lattner }
7030fdc8d8SChris Lattner
GetInstructionsCount(const SBAddress & start,const SBAddress & end,bool canSetBreakpoint)71dd125943SNitesh Jain size_t SBInstructionList::GetInstructionsCount(const SBAddress &start,
72dd125943SNitesh Jain const SBAddress &end,
73dd125943SNitesh Jain bool canSetBreakpoint) {
741755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, start, end, canSetBreakpoint);
75baf5664fSJonas Devlieghere
76dd125943SNitesh Jain size_t num_instructions = GetSize();
77dd125943SNitesh Jain size_t i = 0;
78dd125943SNitesh Jain SBAddress addr;
79dd125943SNitesh Jain size_t lower_index = 0;
80dd125943SNitesh Jain size_t upper_index = 0;
81dd125943SNitesh Jain size_t instructions_to_skip = 0;
82dd125943SNitesh Jain for (i = 0; i < num_instructions; ++i) {
83dd125943SNitesh Jain addr = GetInstructionAtIndex(i).GetAddress();
84dd125943SNitesh Jain if (start == addr)
85dd125943SNitesh Jain lower_index = i;
86dd125943SNitesh Jain if (end == addr)
87dd125943SNitesh Jain upper_index = i;
88dd125943SNitesh Jain }
89dd125943SNitesh Jain if (canSetBreakpoint)
90dd125943SNitesh Jain for (i = lower_index; i <= upper_index; ++i) {
91dd125943SNitesh Jain SBInstruction insn = GetInstructionAtIndex(i);
92dd125943SNitesh Jain if (!insn.CanSetBreakpoint())
93dd125943SNitesh Jain ++instructions_to_skip;
94dd125943SNitesh Jain }
95dd125943SNitesh Jain return upper_index - lower_index - instructions_to_skip;
96dd125943SNitesh Jain }
97dd125943SNitesh Jain
Clear()98baf5664fSJonas Devlieghere void SBInstructionList::Clear() {
991755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
10030fdc8d8SChris Lattner
101baf5664fSJonas Devlieghere m_opaque_sp.reset();
102baf5664fSJonas Devlieghere }
103baf5664fSJonas Devlieghere
AppendInstruction(SBInstruction insn)104baf5664fSJonas Devlieghere void SBInstructionList::AppendInstruction(SBInstruction insn) {
1051755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, insn);
106baf5664fSJonas Devlieghere }
10730fdc8d8SChris Lattner
SetDisassembler(const lldb::DisassemblerSP & opaque_sp)108b9c1b51eSKate Stone void SBInstructionList::SetDisassembler(const lldb::DisassemblerSP &opaque_sp) {
1091d273166SGreg Clayton m_opaque_sp = opaque_sp;
1101d273166SGreg Clayton }
1111d273166SGreg Clayton
Print(FILE * out)112b9c1b51eSKate Stone void SBInstructionList::Print(FILE *out) {
1131755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, out);
114248a1305SKonrad Kleine if (out == nullptr)
11530fdc8d8SChris Lattner return;
116e7a91156SLawrence D'Anna StreamFile stream(out, false);
117e7a91156SLawrence D'Anna GetDescription(stream);
11830fdc8d8SChris Lattner }
11930fdc8d8SChris Lattner
Print(SBFile out)120e7a91156SLawrence D'Anna void SBInstructionList::Print(SBFile out) {
1211755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, out);
122e7a91156SLawrence D'Anna if (!out.IsValid())
123e7a91156SLawrence D'Anna return;
1249efbc564SLawrence D'Anna StreamFile stream(out.m_opaque_sp);
125e7a91156SLawrence D'Anna GetDescription(stream);
126e7a91156SLawrence D'Anna }
127e7a91156SLawrence D'Anna
Print(FileSP out_sp)128e7a91156SLawrence D'Anna void SBInstructionList::Print(FileSP out_sp) {
1291755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, out_sp);
130e7a91156SLawrence D'Anna if (!out_sp || !out_sp->IsValid())
131e7a91156SLawrence D'Anna return;
132e7a91156SLawrence D'Anna StreamFile stream(out_sp);
133e7a91156SLawrence D'Anna GetDescription(stream);
134e7a91156SLawrence D'Anna }
135e7a91156SLawrence D'Anna
GetDescription(lldb::SBStream & stream)136e7a91156SLawrence D'Anna bool SBInstructionList::GetDescription(lldb::SBStream &stream) {
1371755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, stream);
138e7a91156SLawrence D'Anna return GetDescription(stream.ref());
139e7a91156SLawrence D'Anna }
140e7a91156SLawrence D'Anna
GetDescription(Stream & sref)141e7a91156SLawrence D'Anna bool SBInstructionList::GetDescription(Stream &sref) {
142baf5664fSJonas Devlieghere
143b9c1b51eSKate Stone if (m_opaque_sp) {
1441d273166SGreg Clayton size_t num_instructions = GetSize();
145b9c1b51eSKate Stone if (num_instructions) {
14605097246SAdrian Prantl // Call the ref() to make sure a stream is created if one deesn't exist
14705097246SAdrian Prantl // already inside description...
148b9c1b51eSKate Stone const uint32_t max_opcode_byte_size =
149b9c1b51eSKate Stone m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();
150554f68d3SGreg Clayton FormatEntity::Entry format;
151554f68d3SGreg Clayton FormatEntity::Parse("${addr}: ", format);
152aff1b357SJason Molenda SymbolContext sc;
153aff1b357SJason Molenda SymbolContext prev_sc;
154b9c1b51eSKate Stone for (size_t i = 0; i < num_instructions; ++i) {
155b9c1b51eSKate Stone Instruction *inst =
156b9c1b51eSKate Stone m_opaque_sp->GetInstructionList().GetInstructionAtIndex(i).get();
157248a1305SKonrad Kleine if (inst == nullptr)
1581d273166SGreg Clayton break;
159aff1b357SJason Molenda
160aff1b357SJason Molenda const Address &addr = inst->GetAddress();
161aff1b357SJason Molenda prev_sc = sc;
162aff1b357SJason Molenda ModuleSP module_sp(addr.GetModule());
163b9c1b51eSKate Stone if (module_sp) {
164b9c1b51eSKate Stone module_sp->ResolveSymbolContextForAddress(
165b9c1b51eSKate Stone addr, eSymbolContextEverything, sc);
166aff1b357SJason Molenda }
167aff1b357SJason Molenda
168*ad7bcda9SWalter Erquinigo inst->Dump(&sref, max_opcode_byte_size, true, false,
169*ad7bcda9SWalter Erquinigo /*show_control_flow_kind=*/false, nullptr, &sc, &prev_sc,
170*ad7bcda9SWalter Erquinigo &format, 0);
1711d273166SGreg Clayton sref.EOL();
1721d273166SGreg Clayton }
1731d273166SGreg Clayton return true;
1741d273166SGreg Clayton }
1751d273166SGreg Clayton }
1761d273166SGreg Clayton return false;
1771d273166SGreg Clayton }
1781d273166SGreg Clayton
DumpEmulationForAllInstructions(const char * triple)179b9c1b51eSKate Stone bool SBInstructionList::DumpEmulationForAllInstructions(const char *triple) {
1801755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, triple);
181baf5664fSJonas Devlieghere
182b9c1b51eSKate Stone if (m_opaque_sp) {
1837c9dd3ceSCaroline Tice size_t len = GetSize();
184b9c1b51eSKate Stone for (size_t i = 0; i < len; ++i) {
1857c9dd3ceSCaroline Tice if (!GetInstructionAtIndex((uint32_t)i).DumpEmulation(triple))
1867c9dd3ceSCaroline Tice return false;
1877c9dd3ceSCaroline Tice }
1887c9dd3ceSCaroline Tice }
1897c9dd3ceSCaroline Tice return true;
1907c9dd3ceSCaroline Tice }
191