1//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef SymbolFileDWARF_DWARFDebugLine_h_ 11#define SymbolFileDWARF_DWARFDebugLine_h_ 12 13#include <map> 14#include <vector> 15#include <string> 16 17#include "lldb/lldb-private.h" 18 19#include "DWARFDataExtractor.h" 20#include "DWARFDefines.h" 21 22class SymbolFileDWARF; 23class DWARFDebugInfoEntry; 24 25//---------------------------------------------------------------------- 26// DWARFDebugLine 27//---------------------------------------------------------------------- 28class DWARFDebugLine 29{ 30public: 31 //------------------------------------------------------------------ 32 // FileNameEntry 33 //------------------------------------------------------------------ 34 struct FileNameEntry 35 { 36 FileNameEntry() : 37 name(), 38 dir_idx(0), 39 mod_time(0), 40 length(0) 41 { 42 } 43 44 std::string name; 45 dw_sleb128_t dir_idx; 46 dw_sleb128_t mod_time; 47 dw_sleb128_t length; 48 49 }; 50 51 //------------------------------------------------------------------ 52 // Prologue 53 //------------------------------------------------------------------ 54 struct Prologue 55 { 56 57 Prologue() : 58 total_length(0), 59 version(0), 60 prologue_length(0), 61 min_inst_length(0), 62 default_is_stmt(0), 63 line_base(0), 64 line_range(0), 65 opcode_base(0), 66 standard_opcode_lengths(), 67 include_directories(), 68 file_names() 69 { 70 } 71 72 typedef std::shared_ptr<Prologue> shared_ptr; 73 74 uint32_t total_length; // The size in bytes of the statement information for this compilation unit (not including the total_length field itself). 75 uint16_t version; // Version identifier for the statement information format. 76 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. 77 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. 78 uint8_t default_is_stmt;// The initial value of theis_stmtregister. 79 int8_t line_base; // This parameter affects the meaning of the special opcodes. See below. 80 uint8_t line_range; // This parameter affects the meaning of the special opcodes. See below. 81 uint8_t opcode_base; // The number assigned to the first special opcode. 82 std::vector<uint8_t> standard_opcode_lengths; 83 std::vector<std::string> include_directories; 84 std::vector<FileNameEntry> file_names; 85 86 int32_t MaxLineIncrementForSpecialOpcode() const { return line_base + (int8_t)line_range - 1; } 87 bool IsValid() const; 88// void Append(BinaryStreamBuf& buff) const; 89 void Dump (lldb_private::Log *log); 90 void Clear() 91 { 92 total_length = version = prologue_length = min_inst_length = line_base = line_range = opcode_base = 0; 93 line_base = 0; 94 standard_opcode_lengths.clear(); 95 include_directories.clear(); 96 file_names.clear(); 97 } 98 bool GetFile(uint32_t file_idx, std::string& file, std::string& dir) const; 99 100 }; 101 102 // Standard .debug_line state machine structure 103 struct Row 104 { 105 typedef std::vector<Row> collection; 106 typedef collection::iterator iterator; 107 typedef collection::const_iterator const_iterator; 108 109 Row(bool default_is_stmt = false); 110 virtual ~Row() {} 111 void PostAppend (); 112 void Reset(bool default_is_stmt); 113 void Dump(lldb_private::Log *log) const; 114 static void Insert(Row::collection& state_coll, const Row& state); 115 static void Dump(lldb_private::Log *log, const Row::collection& state_coll); 116 117 dw_addr_t address; // The program-counter value corresponding to a machine instruction generated by the compiler. 118 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. 119 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. 120 uint16_t file; // An unsigned integer indicating the identity of the source file corresponding to a machine instruction. 121 uint8_t is_stmt:1, // A boolean indicating that the current instruction is the beginning of a statement. 122 basic_block:1, // A boolean indicating that the current instruction is the beginning of a basic block. 123 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. 124 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. 125 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. 126 uint32_t isa; // An unsigned integer whose value encodes the applicable instruction set architecture for the current instruction. 127 }; 128 129 130 //------------------------------------------------------------------ 131 // LineTable 132 //------------------------------------------------------------------ 133 struct LineTable 134 { 135 typedef std::shared_ptr<LineTable> shared_ptr; 136 137 LineTable() : 138 prologue(), 139 rows() 140 { 141 } 142 143 void AppendRow(const DWARFDebugLine::Row& state); 144 void Clear() 145 { 146 prologue.reset(); 147 rows.clear(); 148 } 149 150 uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const; 151 void Dump(lldb_private::Log *log) const; 152 153 Prologue::shared_ptr prologue; 154 Row::collection rows; 155 }; 156 157 //------------------------------------------------------------------ 158 // State 159 //------------------------------------------------------------------ 160 struct State : public Row 161 { 162 typedef void (*Callback)(dw_offset_t offset, const State& state, void* userData); 163 164 // Special row codes used when calling the callback 165 enum 166 { 167 StartParsingLineTable = 0, 168 DoneParsingLineTable = -1 169 }; 170 171 State (Prologue::shared_ptr& prologue_sp, 172 lldb_private::Log *log, 173 Callback callback, 174 void* userData); 175 176 void 177 AppendRowToMatrix (dw_offset_t offset); 178 179 void 180 Finalize (dw_offset_t offset); 181 182 void 183 Reset (); 184 185 Prologue::shared_ptr prologue; 186 lldb_private::Log *log; 187 Callback callback; // Callback function that gets called each time an entry is to be added to the matrix 188 void* callbackUserData; 189 int row; // The row number that starts at zero for the prologue, and increases for each row added to the matrix 190 private: 191 DISALLOW_COPY_AND_ASSIGN (State); 192 }; 193 194 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 195 static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET); // If line_offset is invalid, dump everything 196 static bool ParseSupportFiles(const lldb::ModuleSP &module_sp, const lldb_private::DWARFDataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, lldb_private::FileSpecList &support_files); 197 static bool ParsePrologue(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue); 198 static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, State::Callback callback, void* userData); 199 static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DWARFDataExtractor& debug_line_data, const dw_offset_t line_offset); 200 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); 201 static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table); 202 static void Parse(const lldb_private::DWARFDataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData); 203// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, const DWARFDebugLine::Row::collection& state_coll, const uint32_t addr_size, BinaryStreamBuf &debug_line_data); 204 205 DWARFDebugLine() : 206 m_lineTableMap() 207 { 208 } 209 210 void Parse(const lldb_private::DWARFDataExtractor& debug_line_data); 211 void ParseIfNeeded(const lldb_private::DWARFDataExtractor& debug_line_data); 212 LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const; 213 214protected: 215 typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap; 216 typedef LineTableMap::iterator LineTableIter; 217 typedef LineTableMap::const_iterator LineTableConstIter; 218 219 LineTableMap m_lineTableMap; 220}; 221 222#endif // SymbolFileDWARF_DWARFDebugLine_h_ 223