1 //===-- SBInstructionList.cpp ---------------------------------------------===//
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 "lldb/API/SBAddress.h"
11 #include "lldb/API/SBFile.h"
12 #include "lldb/API/SBInstruction.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/Core/Disassembler.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Host/StreamFile.h"
17 #include "lldb/Symbol/SymbolContext.h"
18 #include "lldb/Utility/Instrumentation.h"
19 #include "lldb/Utility/Stream.h"
22 using namespace lldb_private
;
24 SBInstructionList::SBInstructionList() { LLDB_INSTRUMENT_VA(this); }
26 SBInstructionList::SBInstructionList(const SBInstructionList
&rhs
)
27 : m_opaque_sp(rhs
.m_opaque_sp
) {
28 LLDB_INSTRUMENT_VA(this, rhs
);
31 const SBInstructionList
&SBInstructionList::
32 operator=(const SBInstructionList
&rhs
) {
33 LLDB_INSTRUMENT_VA(this, rhs
);
36 m_opaque_sp
= rhs
.m_opaque_sp
;
40 SBInstructionList::~SBInstructionList() = default;
42 bool SBInstructionList::IsValid() const {
43 LLDB_INSTRUMENT_VA(this);
44 return this->operator bool();
46 SBInstructionList::operator bool() const {
47 LLDB_INSTRUMENT_VA(this);
49 return m_opaque_sp
.get() != nullptr;
52 size_t SBInstructionList::GetSize() {
53 LLDB_INSTRUMENT_VA(this);
56 return m_opaque_sp
->GetInstructionList().GetSize();
60 SBInstruction
SBInstructionList::GetInstructionAtIndex(uint32_t idx
) {
61 LLDB_INSTRUMENT_VA(this, idx
);
64 if (m_opaque_sp
&& idx
< m_opaque_sp
->GetInstructionList().GetSize())
67 m_opaque_sp
->GetInstructionList().GetInstructionAtIndex(idx
));
71 size_t SBInstructionList::GetInstructionsCount(const SBAddress
&start
,
73 bool canSetBreakpoint
) {
74 LLDB_INSTRUMENT_VA(this, start
, end
, canSetBreakpoint
);
76 size_t num_instructions
= GetSize();
79 size_t lower_index
= 0;
80 size_t upper_index
= 0;
81 size_t instructions_to_skip
= 0;
82 for (i
= 0; i
< num_instructions
; ++i
) {
83 addr
= GetInstructionAtIndex(i
).GetAddress();
90 for (i
= lower_index
; i
<= upper_index
; ++i
) {
91 SBInstruction insn
= GetInstructionAtIndex(i
);
92 if (!insn
.CanSetBreakpoint())
93 ++instructions_to_skip
;
95 return upper_index
- lower_index
- instructions_to_skip
;
98 void SBInstructionList::Clear() {
99 LLDB_INSTRUMENT_VA(this);
104 void SBInstructionList::AppendInstruction(SBInstruction insn
) {
105 LLDB_INSTRUMENT_VA(this, insn
);
108 void SBInstructionList::SetDisassembler(const lldb::DisassemblerSP
&opaque_sp
) {
109 m_opaque_sp
= opaque_sp
;
112 void SBInstructionList::Print(FILE *out
) {
113 LLDB_INSTRUMENT_VA(this, out
);
116 StreamFile
stream(out
, false);
117 GetDescription(stream
);
120 void SBInstructionList::Print(SBFile out
) {
121 LLDB_INSTRUMENT_VA(this, out
);
124 StreamFile
stream(out
.m_opaque_sp
);
125 GetDescription(stream
);
128 void SBInstructionList::Print(FileSP out_sp
) {
129 LLDB_INSTRUMENT_VA(this, out_sp
);
130 if (!out_sp
|| !out_sp
->IsValid())
132 StreamFile
stream(out_sp
);
133 GetDescription(stream
);
136 bool SBInstructionList::GetDescription(lldb::SBStream
&stream
) {
137 LLDB_INSTRUMENT_VA(this, stream
);
138 return GetDescription(stream
.ref());
141 bool SBInstructionList::GetDescription(Stream
&sref
) {
144 size_t num_instructions
= GetSize();
145 if (num_instructions
) {
146 // Call the ref() to make sure a stream is created if one deesn't exist
147 // already inside description...
148 const uint32_t max_opcode_byte_size
=
149 m_opaque_sp
->GetInstructionList().GetMaxOpcocdeByteSize();
150 FormatEntity::Entry format
;
151 FormatEntity::Parse("${addr}: ", format
);
153 SymbolContext prev_sc
;
154 for (size_t i
= 0; i
< num_instructions
; ++i
) {
156 m_opaque_sp
->GetInstructionList().GetInstructionAtIndex(i
).get();
160 const Address
&addr
= inst
->GetAddress();
162 ModuleSP
module_sp(addr
.GetModule());
164 module_sp
->ResolveSymbolContextForAddress(
165 addr
, eSymbolContextEverything
, sc
);
168 inst
->Dump(&sref
, max_opcode_byte_size
, true, false,
169 /*show_control_flow_kind=*/false, nullptr, &sc
, &prev_sc
,
179 bool SBInstructionList::DumpEmulationForAllInstructions(const char *triple
) {
180 LLDB_INSTRUMENT_VA(this, triple
);
183 size_t len
= GetSize();
184 for (size_t i
= 0; i
< len
; ++i
) {
185 if (!GetInstructionAtIndex((uint32_t)i
).DumpEmulation(triple
))