1 //===-- Disassembler.h ------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_Disassembler_h_
11 #define liblldb_Disassembler_h_
13 #include "lldb/Core/Address.h"
14 #include "lldb/Core/ArchSpec.h"
15 #include "lldb/Core/EmulateInstruction.h"
16 #include "lldb/Core/FormatEntity.h" // for FormatEntity
17 #include "lldb/Core/Opcode.h"
18 #include "lldb/Core/PluginInterface.h"
19 #include "lldb/Interpreter/OptionValue.h"
20 #include "lldb/Symbol/LineEntry.h"
21 #include "lldb/Target/ExecutionContext.h" // for ExecutionContext
22 #include "lldb/Utility/ConstString.h" // for ConstString
23 #include "lldb/Utility/FileSpec.h"
24 #include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN
25 #include "lldb/lldb-enumerations.h" // for AddressClass, AddressClass...
26 #include "lldb/lldb-forward.h" // for InstructionSP, DisassemblerSP
27 #include "lldb/lldb-types.h" // for addr_t, offset_t
29 #include "llvm/ADT/StringRef.h" // for StringRef
31 #include <functional> // for function
33 #include <memory> // for enable_shared_from_this
38 #include <stddef.h> // for size_t
39 #include <stdint.h> // for uint32_t, int64_t
40 #include <stdio.h> // for FILE
42 namespace lldb_private {
45 namespace lldb_private {
48 namespace lldb_private {
51 namespace lldb_private {
54 namespace lldb_private {
57 namespace lldb_private {
60 namespace lldb_private {
63 namespace lldb_private {
64 class SymbolContextList;
66 namespace lldb_private {
69 namespace lldb_private {
73 template <typename T> class SmallVectorImpl;
76 namespace lldb_private {
80 Instruction(const Address &address,
81 lldb::AddressClass addr_class = lldb::eAddressClassInvalid);
83 virtual ~Instruction();
85 const Address &GetAddress() const { return m_address; }
87 const char *GetMnemonic(const ExecutionContext *exe_ctx) {
88 CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx);
89 return m_opcode_name.c_str();
92 const char *GetOperands(const ExecutionContext *exe_ctx) {
93 CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx);
94 return m_mnemonics.c_str();
97 const char *GetComment(const ExecutionContext *exe_ctx) {
98 CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx);
99 return m_comment.c_str();
103 CalculateMnemonicOperandsAndComment(const ExecutionContext *exe_ctx) = 0;
105 lldb::AddressClass GetAddressClass();
107 void SetAddress(const Address &addr) {
108 // Invalidate the address class to lazily discover
110 m_address_class = lldb::eAddressClassInvalid;
114 //------------------------------------------------------------------
115 /// Dump the text representation of this Instruction to a Stream
117 /// Print the (optional) address, (optional) bytes, opcode,
118 /// operands, and instruction comments to a stream.
121 /// The Stream to add the text to.
123 /// @param[in] show_address
124 /// Whether the address (using disassembly_addr_format_spec formatting)
125 /// should be printed.
127 /// @param[in] show_bytes
128 /// Whether the bytes of the assembly instruction should be printed.
130 /// @param[in] max_opcode_byte_size
131 /// The size (in bytes) of the largest instruction in the list that
132 /// we are printing (for text justification/alignment purposes)
133 /// Only needed if show_bytes is true.
135 /// @param[in] exe_ctx
136 /// The current execution context, if available. May be used in
137 /// the assembling of the operands+comments for this instruction.
138 /// Pass NULL if not applicable.
140 /// @param[in] sym_ctx
141 /// The SymbolContext for this instruction.
142 /// Pass NULL if not available/computed.
143 /// Only needed if show_address is true.
145 /// @param[in] prev_sym_ctx
146 /// The SymbolContext for the previous instruction. Depending on
147 /// the disassembly address format specification, a change in
148 /// Symbol / Function may mean that a line is printed with the new
149 /// symbol/function name.
150 /// Pass NULL if unavailable, or if this is the first instruction of
151 /// the InstructionList.
152 /// Only needed if show_address is true.
154 /// @param[in] disassembly_addr_format
155 /// The format specification for how addresses are printed.
156 /// Only needed if show_address is true.
158 /// @param[in] max_address_text_size
159 /// The length of the longest address string at the start of the
160 /// disassembly line that will be printed (the
161 /// Debugger::FormatDisassemblerAddress() string)
162 /// so this method can properly align the instruction opcodes.
163 /// May be 0 to indicate no indentation/alignment of the opcodes.
164 //------------------------------------------------------------------
165 virtual void Dump(Stream *s, uint32_t max_opcode_byte_size, bool show_address,
166 bool show_bytes, const ExecutionContext *exe_ctx,
167 const SymbolContext *sym_ctx,
168 const SymbolContext *prev_sym_ctx,
169 const FormatEntity::Entry *disassembly_addr_format,
170 size_t max_address_text_size);
172 virtual bool DoesBranch() = 0;
174 virtual bool HasDelaySlot();
176 bool CanSetBreakpoint ();
178 virtual size_t Decode(const Disassembler &disassembler,
179 const DataExtractor &data,
180 lldb::offset_t data_offset) = 0;
182 virtual void SetDescription(llvm::StringRef) {
183 } // May be overridden in sub-classes that have descriptions.
185 lldb::OptionValueSP ReadArray(FILE *in_file, Stream *out_stream,
186 OptionValue::Type data_type);
188 lldb::OptionValueSP ReadDictionary(FILE *in_file, Stream *out_stream);
190 bool DumpEmulation(const ArchSpec &arch);
192 virtual bool TestEmulation(Stream *stream, const char *test_file_name);
194 bool Emulate(const ArchSpec &arch, uint32_t evaluate_options, void *baton,
195 EmulateInstruction::ReadMemoryCallback read_mem_callback,
196 EmulateInstruction::WriteMemoryCallback write_mem_calback,
197 EmulateInstruction::ReadRegisterCallback read_reg_callback,
198 EmulateInstruction::WriteRegisterCallback write_reg_callback);
200 const Opcode &GetOpcode() const { return m_opcode; }
202 uint32_t GetData(DataExtractor &data);
212 } m_type = Type::Invalid;
213 std::vector<Operand> m_children;
214 lldb::addr_t m_immediate = 0;
215 ConstString m_register;
216 bool m_negative = false;
217 bool m_clobbered = false;
219 bool IsValid() { return m_type != Type::Invalid; }
221 static Operand BuildRegister(ConstString &r);
222 static Operand BuildImmediate(lldb::addr_t imm, bool neg);
223 static Operand BuildImmediate(int64_t imm);
224 static Operand BuildDereference(const Operand &ref);
225 static Operand BuildSum(const Operand &lhs, const Operand &rhs);
226 static Operand BuildProduct(const Operand &lhs, const Operand &rhs);
229 virtual bool ParseOperands(llvm::SmallVectorImpl<Operand> &operands) {
233 virtual bool IsCall() { return false; }
236 Address m_address; // The section offset address of this instruction
237 // We include an address class in the Instruction class to
238 // allow the instruction specify the eAddressClassCodeAlternateISA
239 // (currently used for thumb), and also to specify data (eAddressClassData).
240 // The usual value will be eAddressClassCode, but often when
241 // disassembling memory, you might run into data. This can
242 // help us to disassemble appropriately.
245 m_address_class; // Use GetAddressClass () accessor function!
247 Opcode m_opcode; // The opcode for this instruction
248 std::string m_opcode_name;
249 std::string m_mnemonics;
250 std::string m_comment;
251 bool m_calculated_strings;
254 CalculateMnemonicOperandsAndCommentIfNeeded(const ExecutionContext *exe_ctx) {
255 if (!m_calculated_strings) {
256 m_calculated_strings = true;
257 CalculateMnemonicOperandsAndComment(exe_ctx);
262 namespace OperandMatchers {
263 std::function<bool(const Instruction::Operand &)>
264 MatchBinaryOp(std::function<bool(const Instruction::Operand &)> base,
265 std::function<bool(const Instruction::Operand &)> left,
266 std::function<bool(const Instruction::Operand &)> right);
268 std::function<bool(const Instruction::Operand &)>
269 MatchUnaryOp(std::function<bool(const Instruction::Operand &)> base,
270 std::function<bool(const Instruction::Operand &)> child);
272 std::function<bool(const Instruction::Operand &)>
273 MatchRegOp(const RegisterInfo &info);
275 std::function<bool(const Instruction::Operand &)> FetchRegOp(ConstString ®);
277 std::function<bool(const Instruction::Operand &)> MatchImmOp(int64_t imm);
279 std::function<bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm);
281 std::function<bool(const Instruction::Operand &)>
282 MatchOpType(Instruction::Operand::Type type);
285 class InstructionList {
290 size_t GetSize() const;
292 uint32_t GetMaxOpcocdeByteSize() const;
294 lldb::InstructionSP GetInstructionAtIndex(size_t idx) const;
296 uint32_t GetIndexOfNextBranchInstruction(uint32_t start,
297 Target &target) const;
299 uint32_t GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr,
302 uint32_t GetIndexOfInstructionAtAddress(const Address &addr);
306 void Append(lldb::InstructionSP &inst_sp);
308 void Dump(Stream *s, bool show_address, bool show_bytes,
309 const ExecutionContext *exe_ctx);
312 typedef std::vector<lldb::InstructionSP> collection;
313 typedef collection::iterator iterator;
314 typedef collection::const_iterator const_iterator;
316 collection m_instructions;
319 class PseudoInstruction : public Instruction {
323 ~PseudoInstruction() override;
325 bool DoesBranch() override;
327 bool HasDelaySlot() override;
329 void CalculateMnemonicOperandsAndComment(
330 const ExecutionContext *exe_ctx) override {
331 // TODO: fill this in and put opcode name into Instruction::m_opcode_name,
332 // mnemonic into Instruction::m_mnemonics, and any comment into
333 // Instruction::m_comment
336 size_t Decode(const Disassembler &disassembler, const DataExtractor &data,
337 lldb::offset_t data_offset) override;
339 void SetOpcode(size_t opcode_size, void *opcode_data);
341 void SetDescription(llvm::StringRef description) override;
344 std::string m_description;
346 DISALLOW_COPY_AND_ASSIGN(PseudoInstruction);
349 class Disassembler : public std::enable_shared_from_this<Disassembler>,
350 public PluginInterface {
354 eOptionShowBytes = (1u << 0),
355 eOptionRawOuput = (1u << 1),
356 eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains
357 // the current PC (mixed mode only)
358 eOptionMarkPCAddress =
359 (1u << 3) // Mark the disassembly line the contains the PC
362 enum HexImmediateStyle {
367 // FindPlugin should be lax about the flavor string (it is too annoying to
368 // have various internal uses of the
369 // disassembler fail because the global flavor string gets set wrong.
370 // Instead, if you get a flavor string you
371 // don't understand, use the default. Folks who care to check can use the
372 // FlavorValidForArchSpec method on the
373 // disassembler they got back.
374 static lldb::DisassemblerSP
375 FindPlugin(const ArchSpec &arch, const char *flavor, const char *plugin_name);
377 // This version will use the value in the Target settings if flavor is NULL;
378 static lldb::DisassemblerSP
379 FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch,
380 const char *flavor, const char *plugin_name);
382 static lldb::DisassemblerSP
383 DisassembleRange(const ArchSpec &arch, const char *plugin_name,
384 const char *flavor, const ExecutionContext &exe_ctx,
385 const AddressRange &disasm_range, bool prefer_file_cache);
387 static lldb::DisassemblerSP
388 DisassembleBytes(const ArchSpec &arch, const char *plugin_name,
389 const char *flavor, const Address &start, const void *bytes,
390 size_t length, uint32_t max_num_instructions,
391 bool data_from_file);
393 static bool Disassemble(Debugger &debugger, const ArchSpec &arch,
394 const char *plugin_name, const char *flavor,
395 const ExecutionContext &exe_ctx,
396 const AddressRange &range, uint32_t num_instructions,
397 bool mixed_source_and_assembly,
398 uint32_t num_mixed_context_lines, uint32_t options,
401 static bool Disassemble(Debugger &debugger, const ArchSpec &arch,
402 const char *plugin_name, const char *flavor,
403 const ExecutionContext &exe_ctx, const Address &start,
404 uint32_t num_instructions,
405 bool mixed_source_and_assembly,
406 uint32_t num_mixed_context_lines, uint32_t options,
410 Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name,
411 const char *flavor, const ExecutionContext &exe_ctx,
412 SymbolContextList &sc_list, uint32_t num_instructions,
413 bool mixed_source_and_assembly, uint32_t num_mixed_context_lines,
414 uint32_t options, Stream &strm);
417 Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name,
418 const char *flavor, const ExecutionContext &exe_ctx,
419 const ConstString &name, Module *module,
420 uint32_t num_instructions, bool mixed_source_and_assembly,
421 uint32_t num_mixed_context_lines, uint32_t options, Stream &strm);
424 Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name,
425 const char *flavor, const ExecutionContext &exe_ctx,
426 uint32_t num_instructions, bool mixed_source_and_assembly,
427 uint32_t num_mixed_context_lines, uint32_t options, Stream &strm);
429 //------------------------------------------------------------------
430 // Constructors and Destructors
431 //------------------------------------------------------------------
432 Disassembler(const ArchSpec &arch, const char *flavor);
433 ~Disassembler() override;
435 typedef const char *(*SummaryCallback)(const Instruction &inst,
436 ExecutionContext *exe_context,
439 static bool PrintInstructions(Disassembler *disasm_ptr, Debugger &debugger,
440 const ArchSpec &arch,
441 const ExecutionContext &exe_ctx,
442 uint32_t num_instructions,
443 bool mixed_source_and_assembly,
444 uint32_t num_mixed_context_lines,
445 uint32_t options, Stream &strm);
447 size_t ParseInstructions(const ExecutionContext *exe_ctx,
448 const AddressRange &range, Stream *error_strm_ptr,
449 bool prefer_file_cache);
451 size_t ParseInstructions(const ExecutionContext *exe_ctx,
452 const Address &range, uint32_t num_instructions,
453 bool prefer_file_cache);
455 virtual size_t DecodeInstructions(const Address &base_addr,
456 const DataExtractor &data,
457 lldb::offset_t data_offset,
458 size_t num_instructions, bool append,
459 bool data_from_file) = 0;
461 InstructionList &GetInstructionList();
463 const InstructionList &GetInstructionList() const;
465 const ArchSpec &GetArchitecture() const { return m_arch; }
467 const char *GetFlavor() const { return m_flavor.c_str(); }
469 virtual bool FlavorValidForArchSpec(const lldb_private::ArchSpec &arch,
470 const char *flavor) = 0;
473 // SourceLine and SourceLinesToDisplay structures are only used in
474 // the mixed source and assembly display methods internal to this class.
481 SourceLine() : file(), line(LLDB_INVALID_LINE_NUMBER), column(0) {}
483 bool operator==(const SourceLine &rhs) const {
484 return file == rhs.file && line == rhs.line && rhs.column == column;
487 bool operator!=(const SourceLine &rhs) const {
488 return file != rhs.file || line != rhs.line || column != rhs.column;
491 bool IsValid() const { return line != LLDB_INVALID_LINE_NUMBER; }
494 struct SourceLinesToDisplay {
495 std::vector<SourceLine> lines;
497 // index of the "current" source line, if we want to highlight that
498 // when displaying the source lines. (as opposed to the surrounding
499 // source lines provided to give context)
500 size_t current_source_line;
502 // Whether to print a blank line at the end of the source lines.
503 bool print_source_context_end_eol;
505 SourceLinesToDisplay()
506 : lines(), current_source_line(-1), print_source_context_end_eol(true) {
510 // Get the function's declaration line number, hopefully a line number earlier
511 // than the opening curly brace at the start of the function body.
512 static SourceLine GetFunctionDeclLineEntry(const SymbolContext &sc);
514 // Add the provided SourceLine to the map of filenames-to-source-lines-seen.
515 static void AddLineToSourceLineTables(
517 std::map<FileSpec, std::set<uint32_t>> &source_lines_seen);
519 // Given a source line, determine if we should print it when we're doing
520 // mixed source & assembly output.
521 // We're currently using the target.process.thread.step-avoid-regexp setting
522 // (which is used for stepping over inlined STL functions by default) to
523 // determine what source lines to avoid showing.
525 // Returns true if this source line should be elided (if the source line
527 // not be displayed).
529 ElideMixedSourceAndDisassemblyLine(const ExecutionContext &exe_ctx,
530 const SymbolContext &sc, SourceLine &line);
533 ElideMixedSourceAndDisassemblyLine(const ExecutionContext &exe_ctx,
534 const SymbolContext &sc, LineEntry &line) {
538 sl.column = line.column;
539 return ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, sl);
542 //------------------------------------------------------------------
543 // Classes that inherit from Disassembler can see and modify these
544 //------------------------------------------------------------------
546 InstructionList m_instruction_list;
547 lldb::addr_t m_base_addr;
548 std::string m_flavor;
551 //------------------------------------------------------------------
552 // For Disassembler only
553 //------------------------------------------------------------------
554 DISALLOW_COPY_AND_ASSIGN(Disassembler);
557 } // namespace lldb_private
559 #endif // liblldb_Disassembler_h_