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