LLDB  mainline
SBInstructionList.cpp
Go to the documentation of this file.
1 //===-- SBInstructionList.cpp ---------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
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"
19 #include "lldb/Utility/Stream.h"
20 
21 using namespace lldb;
22 using namespace lldb_private;
23 
26 }
27 
29  : m_opaque_sp(rhs.m_opaque_sp) {
31  rhs);
32 }
33 
38  SBInstructionList, operator=,(const lldb::SBInstructionList &), rhs);
39 
40  if (this != &rhs)
42  return LLDB_RECORD_RESULT(*this);
43 }
44 
46 
49  return this->operator bool();
50 }
51 SBInstructionList::operator bool() const {
53 
54  return m_opaque_sp.get() != nullptr;
55 }
56 
59 
60  if (m_opaque_sp)
61  return m_opaque_sp->GetInstructionList().GetSize();
62  return 0;
63 }
64 
68 
69  SBInstruction inst;
70  if (m_opaque_sp && idx < m_opaque_sp->GetInstructionList().GetSize())
71  inst.SetOpaque(
73  m_opaque_sp->GetInstructionList().GetInstructionAtIndex(idx));
74  return LLDB_RECORD_RESULT(inst);
75 }
76 
78  const SBAddress &end,
79  bool canSetBreakpoint) {
81  (const lldb::SBAddress &, const lldb::SBAddress &, bool),
82  start, end, canSetBreakpoint);
83 
84  size_t num_instructions = GetSize();
85  size_t i = 0;
86  SBAddress addr;
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) {
92  if (start == addr)
93  lower_index = i;
94  if (end == addr)
95  upper_index = i;
96  }
97  if (canSetBreakpoint)
98  for (i = lower_index; i <= upper_index; ++i) {
100  if (!insn.CanSetBreakpoint())
101  ++instructions_to_skip;
102  }
103  return upper_index - lower_index - instructions_to_skip;
104 }
105 
108 
109  m_opaque_sp.reset();
110 }
111 
114  (lldb::SBInstruction), insn);
115 }
116 
117 void SBInstructionList::SetDisassembler(const lldb::DisassemblerSP &opaque_sp) {
118  m_opaque_sp = opaque_sp;
119 }
120 
121 void SBInstructionList::Print(FILE *out) {
122  LLDB_RECORD_METHOD(void, SBInstructionList, Print, (FILE *), out);
123  if (out == nullptr)
124  return;
125  StreamFile stream(out, false);
126  GetDescription(stream);
127 }
128 
131  if (!out.IsValid())
132  return;
133  StreamFile stream(out.m_opaque_sp);
134  GetDescription(stream);
135 }
136 
137 void SBInstructionList::Print(FileSP out_sp) {
138  LLDB_RECORD_METHOD(void, SBInstructionList, Print, (FileSP), out_sp);
139  if (!out_sp || !out_sp->IsValid())
140  return;
141  StreamFile stream(out_sp);
142  GetDescription(stream);
143 }
144 
147  (lldb::SBStream &), stream);
148  return GetDescription(stream.ref());
149 }
150 
152 
153  if (m_opaque_sp) {
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);
162  SymbolContext sc;
163  SymbolContext prev_sc;
164  for (size_t i = 0; i < num_instructions; ++i) {
165  Instruction *inst =
166  m_opaque_sp->GetInstructionList().GetInstructionAtIndex(i).get();
167  if (inst == nullptr)
168  break;
169 
170  const Address &addr = inst->GetAddress();
171  prev_sc = sc;
172  ModuleSP module_sp(addr.GetModule());
173  if (module_sp) {
174  module_sp->ResolveSymbolContextForAddress(
175  addr, eSymbolContextEverything, sc);
176  }
177 
178  inst->Dump(&sref, max_opcode_byte_size, true, false, nullptr, &sc,
179  &prev_sc, &format, 0);
180  sref.EOL();
181  }
182  return true;
183  }
184  }
185  return false;
186 }
187 
190  (const char *), triple);
191 
192  if (m_opaque_sp) {
193  size_t len = GetSize();
194  for (size_t i = 0; i < len; ++i) {
195  if (!GetInstructionAtIndex((uint32_t)i).DumpEmulation(triple))
196  return false;
197  }
198  }
199  return true;
200 }
201 
202 namespace lldb_private {
203 namespace repro {
204 
205 template <>
209  (const lldb::SBInstructionList &));
211  const lldb::SBInstructionList &,
212  SBInstructionList, operator=,(const lldb::SBInstructionList &));
214  LLDB_REGISTER_METHOD_CONST(bool, SBInstructionList, operator bool, ());
220  (const lldb::SBAddress &, const lldb::SBAddress &, bool));
224  LLDB_REGISTER_METHOD(void, SBInstructionList, Print, (FILE *));
226  LLDB_REGISTER_METHOD(void, SBInstructionList, Print, (FileSP));
228  (lldb::SBStream &));
230  DumpEmulationForAllInstructions, (const char *));
231 }
232 
233 }
234 }
The registry contains a unique mapping between functions and their ID.
lldb::SBInstruction GetInstructionAtIndex(uint32_t idx)
A class that represents a running process on the host machine.
#define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class)
void SetOpaque(const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP &inst_sp)
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
bool DumpEmulationForAllInstructions(const char *triple)
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
virtual void Dump(Stream *s, uint32_t max_opcode_byte_size, bool show_address, bool show_bytes, const ExecutionContext *exe_ctx, const SymbolContext *sym_ctx, const SymbolContext *prev_sym_ctx, const FormatEntity::Entry *disassembly_addr_format, size_t max_address_text_size)
Dump the text representation of this Instruction to a Stream.
size_t GetInstructionsCount(const SBAddress &start, const SBAddress &end, bool canSetBreakpoint=false)
bool GetDescription(lldb::SBStream &description)
#define LLDB_REGISTER_CONSTRUCTOR(Class, Signature)
#define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method)
bool IsValid() const
Definition: SBFile.cpp:106
#define LLDB_RECORD_CONSTRUCTOR(Class, Signature,...)
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:128
#define LLDB_RECORD_METHOD(Result, Class, Method, Signature,...)
void SetDisassembler(const lldb::DisassemblerSP &opaque_sp)
void AppendInstruction(lldb::SBInstruction inst)
A section + offset based address class.
Definition: Address.h:59
lldb_private::Stream & ref()
Definition: SBStream.cpp:178
const SBInstructionList & operator=(const SBInstructionList &rhs)
FileSP m_opaque_sp
Definition: SBFile.h:45
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition: Address.cpp:282
void RegisterMethods< SBInstructionList >(Registry &R)
Definition: SBAddress.h:15
#define LLDB_REGISTER_METHOD(Result, Class, Method, Signature)
#define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method)
#define LLDB_RECORD_RESULT(Result)
const Address & GetAddress() const
Definition: Disassembler.h:64
#define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature)
lldb::DisassemblerSP m_opaque_sp