1 //===-- SBInstructionList.cpp -----------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/API/SBInstructionList.h"
11 #include "lldb/API/SBInstruction.h"
12 #include "lldb/API/SBAddress.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/Core/Disassembler.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Symbol/SymbolContext.h"
17 #include "lldb/Utility/Stream.h"
18
19 using namespace lldb;
20 using namespace lldb_private;
21
SBInstructionList()22 SBInstructionList::SBInstructionList() : m_opaque_sp() {}
23
SBInstructionList(const SBInstructionList & rhs)24 SBInstructionList::SBInstructionList(const SBInstructionList &rhs)
25 : m_opaque_sp(rhs.m_opaque_sp) {}
26
27 const SBInstructionList &SBInstructionList::
operator =(const SBInstructionList & rhs)28 operator=(const SBInstructionList &rhs) {
29 if (this != &rhs)
30 m_opaque_sp = rhs.m_opaque_sp;
31 return *this;
32 }
33
~SBInstructionList()34 SBInstructionList::~SBInstructionList() {}
35
IsValid() const36 bool SBInstructionList::IsValid() const { return m_opaque_sp.get() != NULL; }
37
GetSize()38 size_t SBInstructionList::GetSize() {
39 if (m_opaque_sp)
40 return m_opaque_sp->GetInstructionList().GetSize();
41 return 0;
42 }
43
GetInstructionAtIndex(uint32_t idx)44 SBInstruction SBInstructionList::GetInstructionAtIndex(uint32_t idx) {
45 SBInstruction inst;
46 if (m_opaque_sp && idx < m_opaque_sp->GetInstructionList().GetSize())
47 inst.SetOpaque(
48 m_opaque_sp,
49 m_opaque_sp->GetInstructionList().GetInstructionAtIndex(idx));
50 return inst;
51 }
52
GetInstructionsCount(const SBAddress & start,const SBAddress & end,bool canSetBreakpoint)53 size_t SBInstructionList::GetInstructionsCount(const SBAddress &start,
54 const SBAddress &end,
55 bool canSetBreakpoint) {
56 size_t num_instructions = GetSize();
57 size_t i = 0;
58 SBAddress addr;
59 size_t lower_index = 0;
60 size_t upper_index = 0;
61 size_t instructions_to_skip = 0;
62 for (i = 0; i < num_instructions; ++i) {
63 addr = GetInstructionAtIndex(i).GetAddress();
64 if (start == addr)
65 lower_index = i;
66 if (end == addr)
67 upper_index = i;
68 }
69 if (canSetBreakpoint)
70 for (i = lower_index; i <= upper_index; ++i) {
71 SBInstruction insn = GetInstructionAtIndex(i);
72 if (!insn.CanSetBreakpoint())
73 ++instructions_to_skip;
74 }
75 return upper_index - lower_index - instructions_to_skip;
76 }
77
Clear()78 void SBInstructionList::Clear() { m_opaque_sp.reset(); }
79
AppendInstruction(SBInstruction insn)80 void SBInstructionList::AppendInstruction(SBInstruction insn) {}
81
SetDisassembler(const lldb::DisassemblerSP & opaque_sp)82 void SBInstructionList::SetDisassembler(const lldb::DisassemblerSP &opaque_sp) {
83 m_opaque_sp = opaque_sp;
84 }
85
Print(FILE * out)86 void SBInstructionList::Print(FILE *out) {
87 if (out == NULL)
88 return;
89 }
90
GetDescription(lldb::SBStream & description)91 bool SBInstructionList::GetDescription(lldb::SBStream &description) {
92 if (m_opaque_sp) {
93 size_t num_instructions = GetSize();
94 if (num_instructions) {
95 // Call the ref() to make sure a stream is created if one deesn't exist
96 // already inside description...
97 Stream &sref = description.ref();
98 const uint32_t max_opcode_byte_size =
99 m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();
100 FormatEntity::Entry format;
101 FormatEntity::Parse("${addr}: ", format);
102 SymbolContext sc;
103 SymbolContext prev_sc;
104 for (size_t i = 0; i < num_instructions; ++i) {
105 Instruction *inst =
106 m_opaque_sp->GetInstructionList().GetInstructionAtIndex(i).get();
107 if (inst == NULL)
108 break;
109
110 const Address &addr = inst->GetAddress();
111 prev_sc = sc;
112 ModuleSP module_sp(addr.GetModule());
113 if (module_sp) {
114 module_sp->ResolveSymbolContextForAddress(
115 addr, eSymbolContextEverything, sc);
116 }
117
118 inst->Dump(&sref, max_opcode_byte_size, true, false, NULL, &sc,
119 &prev_sc, &format, 0);
120 sref.EOL();
121 }
122 return true;
123 }
124 }
125 return false;
126 }
127
DumpEmulationForAllInstructions(const char * triple)128 bool SBInstructionList::DumpEmulationForAllInstructions(const char *triple) {
129 if (m_opaque_sp) {
130 size_t len = GetSize();
131 for (size_t i = 0; i < len; ++i) {
132 if (!GetInstructionAtIndex((uint32_t)i).DumpEmulation(triple))
133 return false;
134 }
135 }
136 return true;
137 }
138