| //===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef SymbolFileDWARF_DWARFDebugLine_h_ |
| #define SymbolFileDWARF_DWARFDebugLine_h_ |
| |
| #include <map> |
| #include <string> |
| #include <vector> |
| |
| #include "lldb/lldb-private.h" |
| |
| #include "DWARFDataExtractor.h" |
| #include "DWARFDefines.h" |
| |
| class SymbolFileDWARF; |
| |
| //---------------------------------------------------------------------- |
| // DWARFDebugLine |
| //---------------------------------------------------------------------- |
| class DWARFDebugLine { |
| public: |
| //------------------------------------------------------------------ |
| // FileNameEntry |
| //------------------------------------------------------------------ |
| struct FileNameEntry { |
| FileNameEntry() : name(nullptr), dir_idx(0), mod_time(0), length(0) {} |
| |
| const char *name; |
| dw_sleb128_t dir_idx; |
| dw_sleb128_t mod_time; |
| dw_sleb128_t length; |
| }; |
| |
| //------------------------------------------------------------------ |
| // Prologue |
| //------------------------------------------------------------------ |
| struct Prologue { |
| |
| Prologue() |
| : total_length(0), version(0), prologue_length(0), min_inst_length(0), |
| default_is_stmt(0), line_base(0), line_range(0), opcode_base(0), |
| standard_opcode_lengths(), include_directories(), file_names() {} |
| |
| typedef std::shared_ptr<Prologue> shared_ptr; |
| |
| uint32_t total_length; // The size in bytes of the statement information for |
| // this compilation unit (not including the |
| // total_length field itself). |
| uint16_t |
| version; // Version identifier for the statement information format. |
| uint32_t prologue_length; // The number of bytes following the |
| // prologue_length field to the beginning of the |
| // first byte of the statement program itself. |
| uint8_t min_inst_length; // The size in bytes of the smallest target machine |
| // instruction. Statement program opcodes that |
| // alter the address register first multiply their |
| // operands by this value. |
| uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum |
| // number of individual |
| // operations that may be |
| // encoded in an instruction. |
| uint8_t default_is_stmt; // The initial value of theis_stmtregister. |
| int8_t line_base; // This parameter affects the meaning of the special |
| // opcodes. See below. |
| uint8_t line_range; // This parameter affects the meaning of the special |
| // opcodes. See below. |
| uint8_t opcode_base; // The number assigned to the first special opcode. |
| std::vector<uint8_t> standard_opcode_lengths; |
| std::vector<const char *> include_directories; |
| std::vector<FileNameEntry> file_names; |
| |
| int32_t MaxLineIncrementForSpecialOpcode() const { |
| return line_base + (int8_t)line_range - 1; |
| } |
| bool IsValid() const; |
| // void Append(BinaryStreamBuf& buff) const; |
| void Dump(lldb_private::Log *log); |
| void Clear() { |
| total_length = version = prologue_length = min_inst_length = line_base = |
| line_range = opcode_base = 0; |
| line_base = 0; |
| standard_opcode_lengths.clear(); |
| include_directories.clear(); |
| file_names.clear(); |
| } |
| bool GetFile(uint32_t file_idx, const lldb_private::FileSpec &cu_comp_dir, |
| lldb_private::FileSpec &file) const; |
| }; |
| |
| // Standard .debug_line state machine structure |
| struct Row { |
| typedef std::vector<Row> collection; |
| typedef collection::iterator iterator; |
| typedef collection::const_iterator const_iterator; |
| |
| Row(bool default_is_stmt = false); |
| virtual ~Row() {} |
| void PostAppend(); |
| void Reset(bool default_is_stmt); |
| void Dump(lldb_private::Log *log) const; |
| static void Insert(Row::collection &state_coll, const Row &state); |
| static void Dump(lldb_private::Log *log, const Row::collection &state_coll); |
| |
| dw_addr_t address; // The program-counter value corresponding to a machine |
| // instruction generated by the compiler. |
| uint32_t line; // An unsigned integer indicating a source line number. Lines |
| // are numbered beginning at 1. The compiler may emit the |
| // value 0 in cases where an instruction cannot be attributed |
| // to any source line. |
| uint16_t column; // An unsigned integer indicating a column number within a |
| // source line. Columns are numbered beginning at 1. The |
| // value 0 is reserved to indicate that a statement begins |
| // at the 'left edge' of the line. |
| uint16_t file; // An unsigned integer indicating the identity of the source |
| // file corresponding to a machine instruction. |
| uint8_t is_stmt : 1, // A boolean indicating that the current instruction is |
| // the beginning of a statement. |
| basic_block : 1, // A boolean indicating that the current instruction is |
| // the beginning of a basic block. |
| end_sequence : 1, // A boolean indicating that the current address is |
| // that of the first byte after the end of a sequence |
| // of target machine instructions. |
| prologue_end : 1, // A boolean indicating that the current address is |
| // one (of possibly many) where execution should be |
| // suspended for an entry breakpoint of a function. |
| epilogue_begin : 1; // A boolean indicating that the current address is |
| // one (of possibly many) where execution should be |
| // suspended for an exit breakpoint of a function. |
| uint32_t isa; // An unsigned integer whose value encodes the applicable |
| // instruction set architecture for the current instruction. |
| }; |
| |
| //------------------------------------------------------------------ |
| // LineTable |
| //------------------------------------------------------------------ |
| struct LineTable { |
| typedef std::shared_ptr<LineTable> shared_ptr; |
| |
| LineTable() : prologue(), rows() {} |
| |
| void AppendRow(const DWARFDebugLine::Row &state); |
| void Clear() { |
| prologue.reset(); |
| rows.clear(); |
| } |
| |
| uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const; |
| void Dump(lldb_private::Log *log) const; |
| |
| Prologue::shared_ptr prologue; |
| Row::collection rows; |
| }; |
| |
| //------------------------------------------------------------------ |
| // State |
| //------------------------------------------------------------------ |
| struct State : public Row { |
| typedef void (*Callback)(dw_offset_t offset, const State &state, |
| void *userData); |
| |
| // Special row codes used when calling the callback |
| enum { StartParsingLineTable = 0, DoneParsingLineTable = -1 }; |
| |
| State(Prologue::shared_ptr &prologue_sp, lldb_private::Log *log, |
| Callback callback, void *userData); |
| |
| void AppendRowToMatrix(dw_offset_t offset); |
| |
| void Finalize(dw_offset_t offset); |
| |
| void Reset(); |
| |
| Prologue::shared_ptr prologue; |
| lldb_private::Log *log; |
| Callback callback; // Callback function that gets called each time an entry |
| // is to be added to the matrix |
| void *callbackUserData; |
| int row; // The row number that starts at zero for the prologue, and |
| // increases for each row added to the matrix |
| private: |
| DISALLOW_COPY_AND_ASSIGN(State); |
| }; |
| |
| static bool DumpOpcodes( |
| lldb_private::Log *log, SymbolFileDWARF *dwarf2Data, |
| dw_offset_t line_offset = DW_INVALID_OFFSET, |
| uint32_t dump_flags = 0); // If line_offset is invalid, dump everything |
| static bool DumpLineTableRows( |
| lldb_private::Log *log, SymbolFileDWARF *dwarf2Data, |
| dw_offset_t line_offset = |
| DW_INVALID_OFFSET); // If line_offset is invalid, dump everything |
| static bool |
| ParseSupportFiles(const lldb::ModuleSP &module_sp, |
| const lldb_private::DWARFDataExtractor &debug_line_data, |
| const lldb_private::FileSpec &cu_comp_dir, |
| dw_offset_t stmt_list, |
| lldb_private::FileSpecList &support_files); |
| static bool |
| ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data, |
| lldb::offset_t *offset_ptr, Prologue *prologue); |
| static bool |
| ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data, |
| lldb::offset_t *offset_ptr, State::Callback callback, |
| void *userData); |
| static dw_offset_t |
| DumpStatementTable(lldb_private::Log *log, |
| const lldb_private::DWARFDataExtractor &debug_line_data, |
| const dw_offset_t line_offset); |
| static dw_offset_t |
| DumpStatementOpcodes(lldb_private::Log *log, |
| const lldb_private::DWARFDataExtractor &debug_line_data, |
| const dw_offset_t line_offset, uint32_t flags); |
| static bool |
| ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data, |
| lldb::offset_t *offset_ptr, LineTable *line_table); |
| static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data, |
| DWARFDebugLine::State::Callback callback, void *userData); |
| // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, |
| // const DWARFDebugLine::Row::collection& state_coll, const uint32_t |
| // addr_size, BinaryStreamBuf &debug_line_data); |
| |
| DWARFDebugLine() : m_lineTableMap() {} |
| |
| void Parse(const lldb_private::DWARFDataExtractor &debug_line_data); |
| void ParseIfNeeded(const lldb_private::DWARFDataExtractor &debug_line_data); |
| LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const; |
| |
| protected: |
| typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap; |
| typedef LineTableMap::iterator LineTableIter; |
| typedef LineTableMap::const_iterator LineTableConstIter; |
| |
| LineTableMap m_lineTableMap; |
| }; |
| |
| #endif // SymbolFileDWARF_DWARFDebugLine_h_ |