1254721Semaste//===-- Disassembler.h ------------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#ifndef liblldb_Disassembler_h_ 10254721Semaste#define liblldb_Disassembler_h_ 11254721Semaste 12254721Semaste#include "lldb/Core/Address.h" 13254721Semaste#include "lldb/Core/EmulateInstruction.h" 14344779Sdim#include "lldb/Core/FormatEntity.h" 15254721Semaste#include "lldb/Core/Opcode.h" 16254721Semaste#include "lldb/Core/PluginInterface.h" 17254721Semaste#include "lldb/Interpreter/OptionValue.h" 18314564Sdim#include "lldb/Symbol/LineEntry.h" 19344779Sdim#include "lldb/Target/ExecutionContext.h" 20327952Sdim#include "lldb/Utility/ArchSpec.h" 21344779Sdim#include "lldb/Utility/ConstString.h" 22321369Sdim#include "lldb/Utility/FileSpec.h" 23344779Sdim#include "lldb/lldb-defines.h" 24344779Sdim#include "lldb/lldb-forward.h" 25344779Sdim#include "lldb/lldb-private-enumerations.h" 26344779Sdim#include "lldb/lldb-types.h" 27254721Semaste 28344779Sdim#include "llvm/ADT/StringRef.h" 29321369Sdim 30344779Sdim#include <functional> 31321369Sdim#include <map> 32344779Sdim#include <memory> 33321369Sdim#include <set> 34321369Sdim#include <string> 35321369Sdim#include <vector> 36321369Sdim 37344779Sdim#include <stddef.h> 38344779Sdim#include <stdint.h> 39344779Sdim#include <stdio.h> 40321369Sdim 41353358Sdimnamespace llvm { 42353358Sdimtemplate <typename T> class SmallVectorImpl; 43353358Sdim} 44353358Sdim 45254721Semastenamespace lldb_private { 46321369Sdimclass AddressRange; 47321369Sdimclass DataExtractor; 48321369Sdimclass Debugger; 49321369Sdimclass Disassembler; 50321369Sdimclass Module; 51321369Sdimclass Stream; 52321369Sdimclass SymbolContext; 53321369Sdimclass SymbolContextList; 54321369Sdimclass Target; 55321369Sdimstruct RegisterInfo; 56254721Semaste 57314564Sdimclass Instruction { 58254721Semastepublic: 59314564Sdim Instruction(const Address &address, 60341825Sdim AddressClass addr_class = AddressClass::eInvalid); 61254721Semaste 62314564Sdim virtual ~Instruction(); 63254721Semaste 64314564Sdim const Address &GetAddress() const { return m_address; } 65296417Sdim 66314564Sdim const char *GetMnemonic(const ExecutionContext *exe_ctx) { 67314564Sdim CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx); 68314564Sdim return m_opcode_name.c_str(); 69314564Sdim } 70254721Semaste 71314564Sdim const char *GetOperands(const ExecutionContext *exe_ctx) { 72314564Sdim CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx); 73314564Sdim return m_mnemonics.c_str(); 74314564Sdim } 75254721Semaste 76314564Sdim const char *GetComment(const ExecutionContext *exe_ctx) { 77314564Sdim CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx); 78314564Sdim return m_comment.c_str(); 79314564Sdim } 80254721Semaste 81314564Sdim virtual void 82314564Sdim CalculateMnemonicOperandsAndComment(const ExecutionContext *exe_ctx) = 0; 83254721Semaste 84341825Sdim AddressClass GetAddressClass(); 85296417Sdim 86314564Sdim void SetAddress(const Address &addr) { 87341825Sdim // Invalidate the address class to lazily discover it if we need to. 88341825Sdim m_address_class = AddressClass::eInvalid; 89314564Sdim m_address = addr; 90314564Sdim } 91254721Semaste 92314564Sdim /// Dump the text representation of this Instruction to a Stream 93314564Sdim /// 94314564Sdim /// Print the (optional) address, (optional) bytes, opcode, 95314564Sdim /// operands, and instruction comments to a stream. 96314564Sdim /// 97353358Sdim /// \param[in] s 98314564Sdim /// The Stream to add the text to. 99314564Sdim /// 100353358Sdim /// \param[in] show_address 101314564Sdim /// Whether the address (using disassembly_addr_format_spec formatting) 102314564Sdim /// should be printed. 103314564Sdim /// 104353358Sdim /// \param[in] show_bytes 105314564Sdim /// Whether the bytes of the assembly instruction should be printed. 106314564Sdim /// 107353358Sdim /// \param[in] max_opcode_byte_size 108314564Sdim /// The size (in bytes) of the largest instruction in the list that 109314564Sdim /// we are printing (for text justification/alignment purposes) 110314564Sdim /// Only needed if show_bytes is true. 111314564Sdim /// 112353358Sdim /// \param[in] exe_ctx 113314564Sdim /// The current execution context, if available. May be used in 114314564Sdim /// the assembling of the operands+comments for this instruction. 115314564Sdim /// Pass NULL if not applicable. 116314564Sdim /// 117353358Sdim /// \param[in] sym_ctx 118314564Sdim /// The SymbolContext for this instruction. 119314564Sdim /// Pass NULL if not available/computed. 120314564Sdim /// Only needed if show_address is true. 121314564Sdim /// 122353358Sdim /// \param[in] prev_sym_ctx 123314564Sdim /// The SymbolContext for the previous instruction. Depending on 124314564Sdim /// the disassembly address format specification, a change in 125314564Sdim /// Symbol / Function may mean that a line is printed with the new 126314564Sdim /// symbol/function name. 127314564Sdim /// Pass NULL if unavailable, or if this is the first instruction of 128314564Sdim /// the InstructionList. 129314564Sdim /// Only needed if show_address is true. 130314564Sdim /// 131353358Sdim /// \param[in] disassembly_addr_format 132314564Sdim /// The format specification for how addresses are printed. 133314564Sdim /// Only needed if show_address is true. 134314564Sdim /// 135353358Sdim /// \param[in] max_address_text_size 136314564Sdim /// The length of the longest address string at the start of the 137314564Sdim /// disassembly line that will be printed (the 138314564Sdim /// Debugger::FormatDisassemblerAddress() string) 139314564Sdim /// so this method can properly align the instruction opcodes. 140314564Sdim /// May be 0 to indicate no indentation/alignment of the opcodes. 141314564Sdim virtual void Dump(Stream *s, uint32_t max_opcode_byte_size, bool show_address, 142314564Sdim bool show_bytes, const ExecutionContext *exe_ctx, 143314564Sdim const SymbolContext *sym_ctx, 144314564Sdim const SymbolContext *prev_sym_ctx, 145314564Sdim const FormatEntity::Entry *disassembly_addr_format, 146314564Sdim size_t max_address_text_size); 147254721Semaste 148314564Sdim virtual bool DoesBranch() = 0; 149254721Semaste 150314564Sdim virtual bool HasDelaySlot(); 151314564Sdim 152321369Sdim bool CanSetBreakpoint (); 153321369Sdim 154314564Sdim virtual size_t Decode(const Disassembler &disassembler, 155314564Sdim const DataExtractor &data, 156314564Sdim lldb::offset_t data_offset) = 0; 157314564Sdim 158314564Sdim virtual void SetDescription(llvm::StringRef) { 159314564Sdim } // May be overridden in sub-classes that have descriptions. 160314564Sdim 161314564Sdim lldb::OptionValueSP ReadArray(FILE *in_file, Stream *out_stream, 162314564Sdim OptionValue::Type data_type); 163314564Sdim 164314564Sdim lldb::OptionValueSP ReadDictionary(FILE *in_file, Stream *out_stream); 165314564Sdim 166314564Sdim bool DumpEmulation(const ArchSpec &arch); 167314564Sdim 168314564Sdim virtual bool TestEmulation(Stream *stream, const char *test_file_name); 169314564Sdim 170314564Sdim bool Emulate(const ArchSpec &arch, uint32_t evaluate_options, void *baton, 171314564Sdim EmulateInstruction::ReadMemoryCallback read_mem_callback, 172314564Sdim EmulateInstruction::WriteMemoryCallback write_mem_calback, 173314564Sdim EmulateInstruction::ReadRegisterCallback read_reg_callback, 174314564Sdim EmulateInstruction::WriteRegisterCallback write_reg_callback); 175314564Sdim 176314564Sdim const Opcode &GetOpcode() const { return m_opcode; } 177314564Sdim 178314564Sdim uint32_t GetData(DataExtractor &data); 179314564Sdim 180314564Sdim struct Operand { 181314564Sdim enum class Type { 182314564Sdim Invalid = 0, 183314564Sdim Register, 184314564Sdim Immediate, 185314564Sdim Dereference, 186314564Sdim Sum, 187314564Sdim Product 188314564Sdim } m_type = Type::Invalid; 189314564Sdim std::vector<Operand> m_children; 190314564Sdim lldb::addr_t m_immediate = 0; 191314564Sdim ConstString m_register; 192314564Sdim bool m_negative = false; 193314564Sdim bool m_clobbered = false; 194314564Sdim 195314564Sdim bool IsValid() { return m_type != Type::Invalid; } 196314564Sdim 197314564Sdim static Operand BuildRegister(ConstString &r); 198314564Sdim static Operand BuildImmediate(lldb::addr_t imm, bool neg); 199314564Sdim static Operand BuildImmediate(int64_t imm); 200314564Sdim static Operand BuildDereference(const Operand &ref); 201314564Sdim static Operand BuildSum(const Operand &lhs, const Operand &rhs); 202314564Sdim static Operand BuildProduct(const Operand &lhs, const Operand &rhs); 203314564Sdim }; 204314564Sdim 205314564Sdim virtual bool ParseOperands(llvm::SmallVectorImpl<Operand> &operands) { 206314564Sdim return false; 207314564Sdim } 208314564Sdim 209314564Sdim virtual bool IsCall() { return false; } 210314564Sdim 211254721Semasteprotected: 212314564Sdim Address m_address; // The section offset address of this instruction 213314564Sdim // We include an address class in the Instruction class to 214341825Sdim // allow the instruction specify the 215341825Sdim // AddressClass::eCodeAlternateISA (currently used for 216341825Sdim // thumb), and also to specify data (AddressClass::eData). 217341825Sdim // The usual value will be AddressClass::eCode, but often 218341825Sdim // when disassembling memory, you might run into data. 219341825Sdim // This can help us to disassemble appropriately. 220254721Semasteprivate: 221341825Sdim AddressClass m_address_class; // Use GetAddressClass () accessor function! 222341825Sdim 223254721Semasteprotected: 224314564Sdim Opcode m_opcode; // The opcode for this instruction 225314564Sdim std::string m_opcode_name; 226314564Sdim std::string m_mnemonics; 227314564Sdim std::string m_comment; 228314564Sdim bool m_calculated_strings; 229254721Semaste 230314564Sdim void 231314564Sdim CalculateMnemonicOperandsAndCommentIfNeeded(const ExecutionContext *exe_ctx) { 232314564Sdim if (!m_calculated_strings) { 233314564Sdim m_calculated_strings = true; 234314564Sdim CalculateMnemonicOperandsAndComment(exe_ctx); 235254721Semaste } 236314564Sdim } 237254721Semaste}; 238254721Semaste 239314564Sdimnamespace OperandMatchers { 240314564Sdimstd::function<bool(const Instruction::Operand &)> 241314564SdimMatchBinaryOp(std::function<bool(const Instruction::Operand &)> base, 242314564Sdim std::function<bool(const Instruction::Operand &)> left, 243314564Sdim std::function<bool(const Instruction::Operand &)> right); 244314564Sdim 245314564Sdimstd::function<bool(const Instruction::Operand &)> 246314564SdimMatchUnaryOp(std::function<bool(const Instruction::Operand &)> base, 247314564Sdim std::function<bool(const Instruction::Operand &)> child); 248314564Sdim 249314564Sdimstd::function<bool(const Instruction::Operand &)> 250314564SdimMatchRegOp(const RegisterInfo &info); 251314564Sdim 252314564Sdimstd::function<bool(const Instruction::Operand &)> FetchRegOp(ConstString ®); 253314564Sdim 254314564Sdimstd::function<bool(const Instruction::Operand &)> MatchImmOp(int64_t imm); 255314564Sdim 256314564Sdimstd::function<bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm); 257314564Sdim 258314564Sdimstd::function<bool(const Instruction::Operand &)> 259314564SdimMatchOpType(Instruction::Operand::Type type); 260314564Sdim} 261314564Sdim 262314564Sdimclass InstructionList { 263254721Semastepublic: 264314564Sdim InstructionList(); 265314564Sdim ~InstructionList(); 266254721Semaste 267314564Sdim size_t GetSize() const; 268254721Semaste 269314564Sdim uint32_t GetMaxOpcocdeByteSize() const; 270254721Semaste 271314564Sdim lldb::InstructionSP GetInstructionAtIndex(size_t idx) const; 272262528Semaste 273353358Sdim //------------------------------------------------------------------ 274353358Sdim /// Get the index of the next branch instruction. 275353358Sdim /// 276353358Sdim /// Given a list of instructions, find the next branch instruction 277353358Sdim /// in the list by returning an index. 278353358Sdim /// 279353358Sdim /// @param[in] start 280353358Sdim /// The instruction index of the first instruction to check. 281353358Sdim /// 282353358Sdim /// @param[in] target 283353358Sdim /// A LLDB target object that is used to resolve addresses. 284353358Sdim /// 285353358Sdim /// @param[in] ignore_calls 286353358Sdim /// It true, then fine the first branch instruction that isn't 287353358Sdim /// a function call (a branch that calls and returns to the next 288353358Sdim /// instruction). If false, find the instruction index of any 289353358Sdim /// branch in the list. 290360784Sdim /// 291360784Sdim /// @param[out] found_calls 292360784Sdim /// If non-null, this will be set to true if any calls were found in 293360784Sdim /// extending the range. 294353358Sdim /// 295353358Sdim /// @return 296353358Sdim /// The instruction index of the first branch that is at or past 297353358Sdim /// \a start. Returns UINT32_MAX if no matching branches are 298353358Sdim /// found. 299353358Sdim //------------------------------------------------------------------ 300314564Sdim uint32_t GetIndexOfNextBranchInstruction(uint32_t start, 301353358Sdim Target &target, 302360784Sdim bool ignore_calls, 303360784Sdim bool *found_calls) const; 304254721Semaste 305314564Sdim uint32_t GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr, 306314564Sdim Target &target); 307254721Semaste 308314564Sdim uint32_t GetIndexOfInstructionAtAddress(const Address &addr); 309254721Semaste 310314564Sdim void Clear(); 311314564Sdim 312314564Sdim void Append(lldb::InstructionSP &inst_sp); 313314564Sdim 314314564Sdim void Dump(Stream *s, bool show_address, bool show_bytes, 315314564Sdim const ExecutionContext *exe_ctx); 316314564Sdim 317254721Semasteprivate: 318314564Sdim typedef std::vector<lldb::InstructionSP> collection; 319314564Sdim typedef collection::iterator iterator; 320314564Sdim typedef collection::const_iterator const_iterator; 321254721Semaste 322314564Sdim collection m_instructions; 323254721Semaste}; 324254721Semaste 325314564Sdimclass PseudoInstruction : public Instruction { 326254721Semastepublic: 327314564Sdim PseudoInstruction(); 328254721Semaste 329314564Sdim ~PseudoInstruction() override; 330254721Semaste 331314564Sdim bool DoesBranch() override; 332296417Sdim 333314564Sdim bool HasDelaySlot() override; 334314564Sdim 335314564Sdim void CalculateMnemonicOperandsAndComment( 336314564Sdim const ExecutionContext *exe_ctx) override { 337314564Sdim // TODO: fill this in and put opcode name into Instruction::m_opcode_name, 338314564Sdim // mnemonic into Instruction::m_mnemonics, and any comment into 339314564Sdim // Instruction::m_comment 340314564Sdim } 341314564Sdim 342314564Sdim size_t Decode(const Disassembler &disassembler, const DataExtractor &data, 343314564Sdim lldb::offset_t data_offset) override; 344314564Sdim 345314564Sdim void SetOpcode(size_t opcode_size, void *opcode_data); 346314564Sdim 347314564Sdim void SetDescription(llvm::StringRef description) override; 348314564Sdim 349254721Semasteprotected: 350314564Sdim std::string m_description; 351314564Sdim 352314564Sdim DISALLOW_COPY_AND_ASSIGN(PseudoInstruction); 353254721Semaste}; 354254721Semaste 355314564Sdimclass Disassembler : public std::enable_shared_from_this<Disassembler>, 356314564Sdim public PluginInterface { 357254721Semastepublic: 358314564Sdim enum { 359314564Sdim eOptionNone = 0u, 360314564Sdim eOptionShowBytes = (1u << 0), 361314564Sdim eOptionRawOuput = (1u << 1), 362314564Sdim eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains 363314564Sdim // the current PC (mixed mode only) 364314564Sdim eOptionMarkPCAddress = 365314564Sdim (1u << 3) // Mark the disassembly line the contains the PC 366314564Sdim }; 367254721Semaste 368314564Sdim enum HexImmediateStyle { 369314564Sdim eHexStyleC, 370314564Sdim eHexStyleAsm, 371314564Sdim }; 372254721Semaste 373314564Sdim // FindPlugin should be lax about the flavor string (it is too annoying to 374341825Sdim // have various internal uses of the disassembler fail because the global 375341825Sdim // flavor string gets set wrong. Instead, if you get a flavor string you 376314564Sdim // don't understand, use the default. Folks who care to check can use the 377341825Sdim // FlavorValidForArchSpec method on the disassembler they got back. 378314564Sdim static lldb::DisassemblerSP 379314564Sdim FindPlugin(const ArchSpec &arch, const char *flavor, const char *plugin_name); 380254721Semaste 381314564Sdim // This version will use the value in the Target settings if flavor is NULL; 382314564Sdim static lldb::DisassemblerSP 383314564Sdim FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch, 384314564Sdim const char *flavor, const char *plugin_name); 385254721Semaste 386314564Sdim static lldb::DisassemblerSP 387314564Sdim DisassembleRange(const ArchSpec &arch, const char *plugin_name, 388314564Sdim const char *flavor, const ExecutionContext &exe_ctx, 389314564Sdim const AddressRange &disasm_range, bool prefer_file_cache); 390254721Semaste 391314564Sdim static lldb::DisassemblerSP 392314564Sdim DisassembleBytes(const ArchSpec &arch, const char *plugin_name, 393314564Sdim const char *flavor, const Address &start, const void *bytes, 394314564Sdim size_t length, uint32_t max_num_instructions, 395314564Sdim bool data_from_file); 396254721Semaste 397314564Sdim static bool Disassemble(Debugger &debugger, const ArchSpec &arch, 398314564Sdim const char *plugin_name, const char *flavor, 399314564Sdim const ExecutionContext &exe_ctx, 400314564Sdim const AddressRange &range, uint32_t num_instructions, 401314564Sdim bool mixed_source_and_assembly, 402314564Sdim uint32_t num_mixed_context_lines, uint32_t options, 403314564Sdim Stream &strm); 404254721Semaste 405314564Sdim static bool Disassemble(Debugger &debugger, const ArchSpec &arch, 406314564Sdim const char *plugin_name, const char *flavor, 407314564Sdim const ExecutionContext &exe_ctx, const Address &start, 408314564Sdim uint32_t num_instructions, 409314564Sdim bool mixed_source_and_assembly, 410314564Sdim uint32_t num_mixed_context_lines, uint32_t options, 411314564Sdim Stream &strm); 412254721Semaste 413314564Sdim static size_t 414314564Sdim Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, 415314564Sdim const char *flavor, const ExecutionContext &exe_ctx, 416314564Sdim SymbolContextList &sc_list, uint32_t num_instructions, 417314564Sdim bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, 418314564Sdim uint32_t options, Stream &strm); 419254721Semaste 420314564Sdim static bool 421314564Sdim Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, 422314564Sdim const char *flavor, const ExecutionContext &exe_ctx, 423353358Sdim ConstString name, Module *module, 424314564Sdim uint32_t num_instructions, bool mixed_source_and_assembly, 425314564Sdim uint32_t num_mixed_context_lines, uint32_t options, Stream &strm); 426254721Semaste 427314564Sdim static bool 428314564Sdim Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, 429314564Sdim const char *flavor, const ExecutionContext &exe_ctx, 430314564Sdim uint32_t num_instructions, bool mixed_source_and_assembly, 431314564Sdim uint32_t num_mixed_context_lines, uint32_t options, Stream &strm); 432254721Semaste 433314564Sdim // Constructors and Destructors 434314564Sdim Disassembler(const ArchSpec &arch, const char *flavor); 435314564Sdim ~Disassembler() override; 436254721Semaste 437314564Sdim typedef const char *(*SummaryCallback)(const Instruction &inst, 438314564Sdim ExecutionContext *exe_context, 439314564Sdim void *user_data); 440254721Semaste 441314564Sdim static bool PrintInstructions(Disassembler *disasm_ptr, Debugger &debugger, 442314564Sdim const ArchSpec &arch, 443314564Sdim const ExecutionContext &exe_ctx, 444314564Sdim uint32_t num_instructions, 445314564Sdim bool mixed_source_and_assembly, 446314564Sdim uint32_t num_mixed_context_lines, 447314564Sdim uint32_t options, Stream &strm); 448254721Semaste 449314564Sdim size_t ParseInstructions(const ExecutionContext *exe_ctx, 450314564Sdim const AddressRange &range, Stream *error_strm_ptr, 451314564Sdim bool prefer_file_cache); 452314564Sdim 453314564Sdim size_t ParseInstructions(const ExecutionContext *exe_ctx, 454314564Sdim const Address &range, uint32_t num_instructions, 455314564Sdim bool prefer_file_cache); 456314564Sdim 457314564Sdim virtual size_t DecodeInstructions(const Address &base_addr, 458314564Sdim const DataExtractor &data, 459314564Sdim lldb::offset_t data_offset, 460314564Sdim size_t num_instructions, bool append, 461314564Sdim bool data_from_file) = 0; 462314564Sdim 463314564Sdim InstructionList &GetInstructionList(); 464314564Sdim 465314564Sdim const InstructionList &GetInstructionList() const; 466314564Sdim 467314564Sdim const ArchSpec &GetArchitecture() const { return m_arch; } 468314564Sdim 469314564Sdim const char *GetFlavor() const { return m_flavor.c_str(); } 470314564Sdim 471314564Sdim virtual bool FlavorValidForArchSpec(const lldb_private::ArchSpec &arch, 472314564Sdim const char *flavor) = 0; 473314564Sdim 474314564Sdimprotected: 475341825Sdim // SourceLine and SourceLinesToDisplay structures are only used in the mixed 476341825Sdim // source and assembly display methods internal to this class. 477314564Sdim 478314564Sdim struct SourceLine { 479314564Sdim FileSpec file; 480314564Sdim uint32_t line; 481314564Sdim uint32_t column; 482314564Sdim 483314564Sdim SourceLine() : file(), line(LLDB_INVALID_LINE_NUMBER), column(0) {} 484314564Sdim 485314564Sdim bool operator==(const SourceLine &rhs) const { 486314564Sdim return file == rhs.file && line == rhs.line && rhs.column == column; 487254721Semaste } 488314564Sdim 489314564Sdim bool operator!=(const SourceLine &rhs) const { 490314564Sdim return file != rhs.file || line != rhs.line || column != rhs.column; 491254721Semaste } 492254721Semaste 493314564Sdim bool IsValid() const { return line != LLDB_INVALID_LINE_NUMBER; } 494314564Sdim }; 495254721Semaste 496314564Sdim struct SourceLinesToDisplay { 497314564Sdim std::vector<SourceLine> lines; 498314564Sdim 499341825Sdim // index of the "current" source line, if we want to highlight that when 500341825Sdim // displaying the source lines. (as opposed to the surrounding source 501341825Sdim // lines provided to give context) 502314564Sdim size_t current_source_line; 503314564Sdim 504314564Sdim // Whether to print a blank line at the end of the source lines. 505314564Sdim bool print_source_context_end_eol; 506314564Sdim 507314564Sdim SourceLinesToDisplay() 508314564Sdim : lines(), current_source_line(-1), print_source_context_end_eol(true) { 509314564Sdim } 510314564Sdim }; 511314564Sdim 512341825Sdim // Get the function's declaration line number, hopefully a line number 513341825Sdim // earlier than the opening curly brace at the start of the function body. 514314564Sdim static SourceLine GetFunctionDeclLineEntry(const SymbolContext &sc); 515314564Sdim 516314564Sdim // Add the provided SourceLine to the map of filenames-to-source-lines-seen. 517314564Sdim static void AddLineToSourceLineTables( 518314564Sdim SourceLine &line, 519314564Sdim std::map<FileSpec, std::set<uint32_t>> &source_lines_seen); 520314564Sdim 521314564Sdim // Given a source line, determine if we should print it when we're doing 522341825Sdim // mixed source & assembly output. We're currently using the 523341825Sdim // target.process.thread.step-avoid-regexp setting (which is used for 524341825Sdim // stepping over inlined STL functions by default) to determine what source 525341825Sdim // lines to avoid showing. 526314564Sdim // 527314564Sdim // Returns true if this source line should be elided (if the source line 528341825Sdim // should not be displayed). 529314564Sdim static bool 530314564Sdim ElideMixedSourceAndDisassemblyLine(const ExecutionContext &exe_ctx, 531314564Sdim const SymbolContext &sc, SourceLine &line); 532314564Sdim 533314564Sdim static bool 534314564Sdim ElideMixedSourceAndDisassemblyLine(const ExecutionContext &exe_ctx, 535314564Sdim const SymbolContext &sc, LineEntry &line) { 536314564Sdim SourceLine sl; 537314564Sdim sl.file = line.file; 538314564Sdim sl.line = line.line; 539314564Sdim sl.column = line.column; 540314564Sdim return ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, sl); 541314564Sdim }; 542314564Sdim 543314564Sdim // Classes that inherit from Disassembler can see and modify these 544314564Sdim ArchSpec m_arch; 545314564Sdim InstructionList m_instruction_list; 546314564Sdim lldb::addr_t m_base_addr; 547314564Sdim std::string m_flavor; 548314564Sdim 549254721Semasteprivate: 550314564Sdim // For Disassembler only 551314564Sdim DISALLOW_COPY_AND_ASSIGN(Disassembler); 552254721Semaste}; 553254721Semaste 554254721Semaste} // namespace lldb_private 555254721Semaste 556296417Sdim#endif // liblldb_Disassembler_h_ 557