17 using namespace dwarf;
20 OS <<
"Line table prologue:\n"
21 <<
format(
" total_length: 0x%8.8x\n", TotalLength)
22 <<
format(
" version: %u\n", Version)
23 <<
format(
"prologue_length: 0x%8.8x\n", PrologueLength)
24 <<
format(
"min_inst_length: %u\n", MinInstLength)
25 <<
format(
"default_is_stmt: %u\n", DefaultIsStmt)
26 <<
format(
" line_base: %i\n", LineBase)
27 <<
format(
" line_range: %u\n", LineRange)
28 <<
format(
" opcode_base: %u\n", OpcodeBase);
30 for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i)
32 StandardOpcodeLengths[i]);
34 if (!IncludeDirectories.empty())
35 for (uint32_t i = 0; i < IncludeDirectories.size(); ++i)
36 OS <<
format(
"include_directories[%3u] = '", i+1)
37 << IncludeDirectories[i] <<
"'\n";
39 if (!FileNames.empty()) {
40 OS <<
" Dir Mod Time File Len File Name\n"
41 <<
" ---- ---------- ---------- -----------"
43 for (uint32_t i = 0; i < FileNames.size(); ++i) {
45 OS <<
format(
"file_names[%3u] %4" PRIu64
" ", i+1, fileEntry.
DirIdx)
46 <<
format(
"0x%8.8" PRIx64
" 0x%8.8" PRIx64
" ",
48 << fileEntry.
Name <<
'\n';
56 EpilogueBegin =
false;
65 IsStmt = default_is_stmt;
69 EpilogueBegin =
false;
73 OS <<
format(
"0x%16.16" PRIx64
" %6u %6u", Address, Line, Column)
75 << (IsStmt ?
" is_stmt" :
"")
77 << (PrologueEnd ?
" prologue_end" :
"")
78 << (EpilogueBegin ?
" epilogue_begin" :
"")
79 << (EndSequence ?
" end_sequence" :
"")
88 OS <<
"Address Line Column File ISA Flags\n"
89 <<
"------------------ ------ ------ ------ --- -------------\n";
90 for (std::vector<Row>::const_iterator pos = Rows.begin(),
99 if (Sequence::Empty) {
101 Sequence::Empty =
false;
102 Sequence::LowPC = Address;
103 Sequence::FirstRowIndex = row;
106 LineTable::appendRow(*
this);
109 Sequence::HighPC = Address;
110 Sequence::LastRowIndex = row;
111 if (Sequence::isValid())
112 LineTable::appendSequence(*
this);
119 row = DoneParsingLineTable;
120 if (!Sequence::Empty) {
121 fprintf(stderr,
"warning: last sequence in debug line table is not"
125 if (!Sequences.empty()) {
126 std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
144 LineTableConstIter pos = LineTableMap.find(offset);
145 if (pos != LineTableMap.end())
153 std::pair<LineTableIter, bool> pos =
154 LineTableMap.insert(LineTableMapTy::value_type(offset,
LineTable()));
158 if (!parseStatementTable(debug_line_data, RelocMap, &offset, state))
160 pos.first->second = state;
162 return &pos.first->second;
167 uint32_t *offset_ptr,
Prologue *prologue) {
168 const uint32_t prologue_offset = *offset_ptr;
177 const uint32_t end_prologue_offset = prologue->
PrologueLength + *offset_ptr;
185 for (uint32_t i = 1; i < prologue->
OpcodeBase; ++i) {
186 uint8_t op_len = debug_line_data.
getU8(offset_ptr);
190 while (*offset_ptr < end_prologue_offset) {
191 const char *s = debug_line_data.
getCStr(offset_ptr);
198 while (*offset_ptr < end_prologue_offset) {
199 const char *name = debug_line_data.
getCStr(offset_ptr);
200 if (name && name[0]) {
202 fileEntry.
Name = name;
206 prologue->
FileNames.push_back(fileEntry);
212 if (*offset_ptr != end_prologue_offset) {
213 fprintf(stderr,
"warning: parsing line table prologue at 0x%8.8x should"
214 " have ended at 0x%8.8x but it ended at 0x%8.8x\n",
215 prologue_offset, end_prologue_offset, *offset_ptr);
224 uint32_t *offset_ptr,
State &state) {
225 const uint32_t debug_line_offset = *offset_ptr;
229 if (!parsePrologue(debug_line_data, offset_ptr, prologue)) {
231 *offset_ptr = debug_line_offset;
235 const uint32_t end_offset = debug_line_offset + prologue->
TotalLength +
240 while (*offset_ptr < end_offset) {
241 uint8_t opcode = debug_line_data.
getU8(offset_ptr);
246 uint32_t ext_offset = *offset_ptr;
247 uint64_t len = debug_line_data.
getULEB128(offset_ptr);
248 uint32_t arg_size = len - (*offset_ptr - ext_offset);
250 uint8_t sub_opcode = debug_line_data.
getU8(offset_ptr);
251 switch (sub_opcode) {
275 if (AI != RMap->
end()) {
276 const std::pair<uint8_t, int64_t> &R = AI->second;
306 fileEntry.
Name = debug_line_data.
getCStr(offset_ptr);
310 prologue->
FileNames.push_back(fileEntry);
317 (*offset_ptr) += arg_size;
320 }
else if (opcode < prologue->OpcodeBase) {
381 uint8_t adjust_opcode = 255 - prologue->
OpcodeBase;
382 uint64_t addr_offset = (adjust_opcode / prologue->
LineRange) *
424 assert(opcode - 1U < prologue->StandardOpcodeLengths.size());
426 for (uint8_t i=0; i<opcode_length; ++i)
465 uint8_t adjust_opcode = opcode - prologue->
OpcodeBase;
466 uint64_t addr_offset = (adjust_opcode / prologue->
LineRange) *
468 int32_t line_offset = prologue->
LineBase +
470 state.
Line += line_offset;
483 uint32_t unknown_index = UINT32_MAX;
484 if (Sequences.empty())
485 return unknown_index;
488 sequence.
LowPC = address;
491 SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence,
494 if (seq_pos == last_seq) {
495 found_seq = Sequences.back();
496 }
else if (seq_pos->LowPC == address) {
497 found_seq = *seq_pos;
499 if (seq_pos == first_seq)
500 return unknown_index;
501 found_seq = *(seq_pos - 1);
504 return unknown_index;
512 RowIter row_pos = std::lower_bound(first_row, last_row, row,
514 if (row_pos == last_row) {
517 uint32_t index = found_seq.
FirstRowIndex + (row_pos - first_row);
518 if (row_pos->Address > address) {
519 if (row_pos == first_row)
520 return unknown_index;
530 std::vector<uint32_t>& result)
const {
531 if (Sequences.empty())
533 uint64_t end_addr = address + size;
536 sequence.
LowPC = address;
539 SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence,
541 if (seq_pos == last_seq || seq_pos->LowPC != address) {
542 if (seq_pos == first_seq)
546 if (!seq_pos->containsPC(address))
554 while (seq_pos != last_seq && seq_pos->LowPC < end_addr) {
556 uint32_t first_row_index;
557 uint32_t last_row_index;
558 if (seq_pos == start_pos) {
566 RowIter row_pos = std::upper_bound(first_row, last_row, row,
571 first_row_index = cur_seq.
FirstRowIndex + (row_pos - first_row);
572 if (row_pos != first_row)
579 if (cur_seq.
HighPC > end_addr) {
584 RowIter row_pos = std::upper_bound(first_row, last_row, row,
588 last_row_index = cur_seq.
FirstRowIndex + (row_pos - first_row) - 1;
594 for (uint32_t i = first_row_index; i <= last_row_index; ++i) {
606 bool NeedsAbsoluteFilePath,
607 std::string &Result)
const {
611 const char *FileName = Entry.
Name;
612 if (!NeedsAbsoluteFilePath ||
618 uint64_t IncludeDirIndex = Entry.
DirIdx;
620 if (IncludeDirIndex > 0 &&
626 Result = FilePath.
str();
const_iterator end(StringRef path)
Get end iterator over path.
RowVector::const_iterator RowIter
static bool orderByAddress(const Row &LHS, const Row &RHS)
SequenceVector::const_iterator SequenceIter
const LineTable * getLineTable(uint32_t offset) const
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
void postAppend()
Called after a row is appended to the matrix.
bool is_absolute(const Twine &path)
Is path absolute?
const char * LNStandardString(unsigned Standard)
bool getFileNameByIndex(uint64_t FileIndex, bool NeedsAbsoluteFilePath, std::string &Result) const
format_object1< T > format(const char *Fmt, const T &Val)
friend const_iterator end(StringRef path)
Get end iterator over path.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
LLVM Basic Block Representation.
void dump(raw_ostream &OS) const
void dump(raw_ostream &OS) const
void dump(raw_ostream &OS) const
const LineTable * getOrParseLineTable(DataExtractor debug_line_data, uint32_t offset)
bool lookupAddressRange(uint64_t address, uint64_t size, std::vector< uint32_t > &result) const
uint32_t lookupAddress(uint64_t address) const
std::vector< const char * > IncludeDirectories
virtual void appendRowToMatrix(uint32_t offset)
int fprintf(FILE *stream, const char *format, ...);
std::vector< uint8_t > StandardOpcodeLengths
void reset(bool default_is_stmt)
StringRef str() const
Explicit conversion to StringRef.
bool containsPC(uint64_t pc) const
std::vector< FileNameEntry > FileNames
static bool orderByLowPC(const Sequence &LHS, const Sequence &RHS)
static bool parsePrologue(DataExtractor debug_line_data, uint32_t *offset_ptr, Prologue *prologue)
iterator find(const KeyT &Val)
static bool parseStatementTable(DataExtractor debug_line_data, const RelocAddrMap *RMap, uint32_t *offset_ptr, State &state)
Parse a single line table (prologue and all rows).