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