1 //===-- SBInstructionList.cpp -----------------------------------*- C++ -*-===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBInstructionList.h"
10 #include "SBReproducerPrivate.h"
11 #include "lldb/API/SBAddress.h"
12 #include "lldb/API/SBInstruction.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBFile.h"
15 #include "lldb/Core/Disassembler.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/StreamFile.h"
18 #include "lldb/Symbol/SymbolContext.h"
19 #include "lldb/Utility/Stream.h"
22 using namespace lldb_private
;
24 SBInstructionList::SBInstructionList() : m_opaque_sp() {
25 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBInstructionList
);
28 SBInstructionList::SBInstructionList(const SBInstructionList
&rhs
)
29 : m_opaque_sp(rhs
.m_opaque_sp
) {
30 LLDB_RECORD_CONSTRUCTOR(SBInstructionList
, (const lldb::SBInstructionList
&),
34 const SBInstructionList
&SBInstructionList::
35 operator=(const SBInstructionList
&rhs
) {
37 const lldb::SBInstructionList
&,
38 SBInstructionList
, operator=,(const lldb::SBInstructionList
&), rhs
);
41 m_opaque_sp
= rhs
.m_opaque_sp
;
42 return LLDB_RECORD_RESULT(*this);
45 SBInstructionList::~SBInstructionList() {}
47 bool SBInstructionList::IsValid() const {
48 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBInstructionList
, IsValid
);
49 return this->operator bool();
51 SBInstructionList::operator bool() const {
52 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBInstructionList
, operator bool);
54 return m_opaque_sp
.get() != nullptr;
57 size_t SBInstructionList::GetSize() {
58 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBInstructionList
, GetSize
);
61 return m_opaque_sp
->GetInstructionList().GetSize();
65 SBInstruction
SBInstructionList::GetInstructionAtIndex(uint32_t idx
) {
66 LLDB_RECORD_METHOD(lldb::SBInstruction
, SBInstructionList
,
67 GetInstructionAtIndex
, (uint32_t), idx
);
70 if (m_opaque_sp
&& idx
< m_opaque_sp
->GetInstructionList().GetSize())
73 m_opaque_sp
->GetInstructionList().GetInstructionAtIndex(idx
));
74 return LLDB_RECORD_RESULT(inst
);
77 size_t SBInstructionList::GetInstructionsCount(const SBAddress
&start
,
79 bool canSetBreakpoint
) {
80 LLDB_RECORD_METHOD(size_t, SBInstructionList
, GetInstructionsCount
,
81 (const lldb::SBAddress
&, const lldb::SBAddress
&, bool),
82 start
, end
, canSetBreakpoint
);
84 size_t num_instructions
= GetSize();
87 size_t lower_index
= 0;
88 size_t upper_index
= 0;
89 size_t instructions_to_skip
= 0;
90 for (i
= 0; i
< num_instructions
; ++i
) {
91 addr
= GetInstructionAtIndex(i
).GetAddress();
98 for (i
= lower_index
; i
<= upper_index
; ++i
) {
99 SBInstruction insn
= GetInstructionAtIndex(i
);
100 if (!insn
.CanSetBreakpoint())
101 ++instructions_to_skip
;
103 return upper_index
- lower_index
- instructions_to_skip
;
106 void SBInstructionList::Clear() {
107 LLDB_RECORD_METHOD_NO_ARGS(void, SBInstructionList
, Clear
);
112 void SBInstructionList::AppendInstruction(SBInstruction insn
) {
113 LLDB_RECORD_METHOD(void, SBInstructionList
, AppendInstruction
,
114 (lldb::SBInstruction
), insn
);
117 void SBInstructionList::SetDisassembler(const lldb::DisassemblerSP
&opaque_sp
) {
118 m_opaque_sp
= opaque_sp
;
121 void SBInstructionList::Print(FILE *out
) {
122 LLDB_RECORD_METHOD(void, SBInstructionList
, Print
, (FILE *), out
);
125 StreamFile
stream(out
, false);
126 GetDescription(stream
);
129 void SBInstructionList::Print(SBFile out
) {
130 LLDB_RECORD_METHOD(void, SBInstructionList
, Print
, (SBFile
), out
);
133 StreamFile
stream(out
.m_opaque_sp
);
134 GetDescription(stream
);
137 void SBInstructionList::Print(FileSP out_sp
) {
138 LLDB_RECORD_METHOD(void, SBInstructionList
, Print
, (FileSP
), out_sp
);
139 if (!out_sp
|| !out_sp
->IsValid())
141 StreamFile
stream(out_sp
);
142 GetDescription(stream
);
145 bool SBInstructionList::GetDescription(lldb::SBStream
&stream
) {
146 LLDB_RECORD_METHOD(bool, SBInstructionList
, GetDescription
,
147 (lldb::SBStream
&), stream
);
148 return GetDescription(stream
.ref());
151 bool SBInstructionList::GetDescription(Stream
&sref
) {
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 exist
157 // 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}: ", format
);
163 SymbolContext prev_sc
;
164 for (size_t i
= 0; i
< num_instructions
; ++i
) {
166 m_opaque_sp
->GetInstructionList().GetInstructionAtIndex(i
).get();
170 const Address
&addr
= inst
->GetAddress();
172 ModuleSP
module_sp(addr
.GetModule());
174 module_sp
->ResolveSymbolContextForAddress(
175 addr
, eSymbolContextEverything
, sc
);
178 inst
->Dump(&sref
, max_opcode_byte_size
, true, false, nullptr, &sc
,
179 &prev_sc
, &format
, 0);
188 bool SBInstructionList::DumpEmulationForAllInstructions(const char *triple
) {
189 LLDB_RECORD_METHOD(bool, SBInstructionList
, DumpEmulationForAllInstructions
,
190 (const char *), triple
);
193 size_t len
= GetSize();
194 for (size_t i
= 0; i
< len
; ++i
) {
195 if (!GetInstructionAtIndex((uint32_t)i
).DumpEmulation(triple
))
202 namespace lldb_private
{
206 void RegisterMethods
<SBInstructionList
>(Registry
&R
) {
207 LLDB_REGISTER_CONSTRUCTOR(SBInstructionList
, ());
208 LLDB_REGISTER_CONSTRUCTOR(SBInstructionList
,
209 (const lldb::SBInstructionList
&));
210 LLDB_REGISTER_METHOD(
211 const lldb::SBInstructionList
&,
212 SBInstructionList
, operator=,(const lldb::SBInstructionList
&));
213 LLDB_REGISTER_METHOD_CONST(bool, SBInstructionList
, IsValid
, ());
214 LLDB_REGISTER_METHOD_CONST(bool, SBInstructionList
, operator bool, ());
215 LLDB_REGISTER_METHOD(size_t, SBInstructionList
, GetSize
, ());
216 LLDB_REGISTER_METHOD(lldb::SBInstruction
, SBInstructionList
,
217 GetInstructionAtIndex
, (uint32_t));
218 LLDB_REGISTER_METHOD(
219 size_t, SBInstructionList
, GetInstructionsCount
,
220 (const lldb::SBAddress
&, const lldb::SBAddress
&, bool));
221 LLDB_REGISTER_METHOD(void, SBInstructionList
, Clear
, ());
222 LLDB_REGISTER_METHOD(void, SBInstructionList
, AppendInstruction
,
223 (lldb::SBInstruction
));
224 LLDB_REGISTER_METHOD(void, SBInstructionList
, Print
, (FILE *));
225 LLDB_REGISTER_METHOD(void, SBInstructionList
, Print
, (SBFile
));
226 LLDB_REGISTER_METHOD(void, SBInstructionList
, Print
, (FileSP
));
227 LLDB_REGISTER_METHOD(bool, SBInstructionList
, GetDescription
,
229 LLDB_REGISTER_METHOD(bool, SBInstructionList
,
230 DumpEmulationForAllInstructions
, (const char *));