X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FDebugInfo%2FDWARFDebugLine.cpp;h=d99575d80033327cbf35cd711868643565fb4090;hb=c4dc2490c4ea2c75e451eec5950179f06d2610a2;hp=9db86c33fb5b083c2599de1ebf8f9955f9b36f09;hpb=7393c7f748acb10b143cab296ae98551b4c430f4;p=oota-llvm.git diff --git a/lib/DebugInfo/DWARFDebugLine.cpp b/lib/DebugInfo/DWARFDebugLine.cpp index 9db86c33fb5..d99575d8003 100644 --- a/lib/DebugInfo/DWARFDebugLine.cpp +++ b/lib/DebugInfo/DWARFDebugLine.cpp @@ -41,8 +41,9 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { "----------------\n"; for (uint32_t i = 0; i < FileNames.size(); ++i) { const FileNameEntry& fileEntry = FileNames[i]; - OS << format("file_names[%3u] %4u ", i+1, fileEntry.DirIdx) - << format("0x%8.8x 0x%8.8x ", fileEntry.ModTime, fileEntry.Length) + OS << format("file_names[%3u] %4" PRIu64 " ", i+1, fileEntry.DirIdx) + << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", + fileEntry.ModTime, fileEntry.Length) << fileEntry.Name << '\n'; } } @@ -68,7 +69,7 @@ void DWARFDebugLine::Row::reset(bool default_is_stmt) { } void DWARFDebugLine::Row::dump(raw_ostream &OS) const { - OS << format("0x%16.16llx %6u %6u", Address, Line, Column) + OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column) << format(" %6u %3u ", File, Isa) << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "") @@ -91,52 +92,50 @@ void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { } } +DWARFDebugLine::State::~State() {} + void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) { + if (Sequence::Empty) { + // Record the beginning of instruction sequence. + Sequence::Empty = false; + Sequence::LowPC = Address; + Sequence::FirstRowIndex = row; + } ++row; // Increase the row number. LineTable::appendRow(*this); + if (EndSequence) { + // Record the end of instruction sequence. + Sequence::HighPC = Address; + Sequence::LastRowIndex = row; + if (Sequence::isValid()) + LineTable::appendSequence(*this); + Sequence::reset(); + } Row::postAppend(); } -void DWARFDebugLine::parse(const DataExtractor debug_line_data) { - LineTableMap.clear(); - uint32_t offset = 0; - State state; - while (debug_line_data.isValidOffset(offset)) { - const uint32_t debug_line_offset = offset; - - if (parseStatementTable(debug_line_data, &offset, state)) { - // Make sure we don't don't loop infinitely - if (offset <= debug_line_offset) - break; - - LineTableMap[debug_line_offset] = state; - state.reset(); - } - else - ++offset; // Try next byte in line table +void DWARFDebugLine::State::finalize() { + row = DoneParsingLineTable; + if (!Sequence::Empty) { + fprintf(stderr, "warning: last sequence in debug line table is not" + "terminated!\n"); + } + // Sort all sequences so that address lookup will work faster. + if (!Sequences.empty()) { + std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC); + // Note: actually, instruction address ranges of sequences should not + // overlap (in shared objects and executables). If they do, the address + // lookup would still work, though, but result would be ambiguous. + // We don't report warning in this case. For example, + // sometimes .so compiled from multiple object files contains a few + // rudimentary sequences for address ranges [0x0, 0xsomething). } } -void DWARFDebugLine::DumpingState::finalize(uint32_t offset) { - LineTable::dump(OS); -} - -void DWARFDebugLine::dump(const DataExtractor debug_line_data, raw_ostream &OS){ - uint32_t offset = 0; - DumpingState state(OS); - while (debug_line_data.isValidOffset(offset)) { - const uint32_t debug_line_offset = offset; - - if (parseStatementTable(debug_line_data, &offset, state)) { - // Make sure we don't don't loop infinitely - if (offset <= debug_line_offset) - break; +DWARFDebugLine::DumpingState::~DumpingState() {} - state.reset(); - } - else - ++offset; // Try next byte in line table - } +void DWARFDebugLine::DumpingState::finalize() { + LineTable::dump(OS); } const DWARFDebugLine::LineTable * @@ -147,6 +146,21 @@ DWARFDebugLine::getLineTable(uint32_t offset) const { return 0; } +const DWARFDebugLine::LineTable * +DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data, + uint32_t offset) { + std::pair pos = + LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable())); + if (pos.second) { + // Parse and cache the line table for at this offset. + State state; + if (!parseStatementTable(debug_line_data, &offset, state)) + return 0; + pos.first->second = state; + } + return &pos.first->second; +} + bool DWARFDebugLine::parsePrologue(DataExtractor debug_line_data, uint32_t *offset_ptr, Prologue *prologue) { @@ -196,10 +210,11 @@ DWARFDebugLine::parsePrologue(DataExtractor debug_line_data, if (*offset_ptr != end_prologue_offset) { fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should" - " have ended at 0x%8.8x but it ended ad 0x%8.8x\n", + " have ended at 0x%8.8x but it ended ad 0x%8.8x\n", prologue_offset, end_prologue_offset, *offset_ptr); + return false; } - return end_prologue_offset; + return true; } bool @@ -218,6 +233,8 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, const uint32_t end_offset = debug_line_offset + prologue->TotalLength + sizeof(prologue->TotalLength); + state.reset(); + while (*offset_ptr < end_offset) { uint8_t opcode = debug_line_data.getU8(offset_ptr); @@ -394,7 +411,7 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, // of such opcodes because they are specified in the prologue // as a multiple of LEB128 operands for each opcode. { - assert(opcode - 1 < prologue->StandardOpcodeLengths.size()); + assert(opcode - 1U < prologue->StandardOpcodeLengths.size()); uint8_t opcode_length = prologue->StandardOpcodeLengths[opcode - 1]; for (uint8_t i=0; i::const_iterator iterator; - iterator begin_pos = Rows.begin(); - iterator end_pos = Rows.end(); - iterator pos = std::lower_bound(begin_pos, end_pos, row, - findMatchingAddress); - if (pos == end_pos) { - if (address < cu_high_pc) - return Rows.size()-1; - } else { - // Rely on fact that we are using a std::vector and we can do - // pointer arithmetic to find the row index (which will be one less - // that what we found since it will find the first position after - // the current address) since std::vector iterators are just - // pointers to the container type. - index = pos - begin_pos; - if (pos->Address > address) { - if (index > 0) - --index; - else - index = UINT32_MAX; - } - } +DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { + uint32_t unknown_index = UINT32_MAX; + if (Sequences.empty()) + return unknown_index; + // First, find an instruction sequence containing the given address. + DWARFDebugLine::Sequence sequence; + sequence.LowPC = address; + SequenceIter first_seq = Sequences.begin(); + SequenceIter last_seq = Sequences.end(); + SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence, + DWARFDebugLine::Sequence::orderByLowPC); + DWARFDebugLine::Sequence found_seq; + if (seq_pos == last_seq) { + found_seq = Sequences.back(); + } else if (seq_pos->LowPC == address) { + found_seq = *seq_pos; + } else { + if (seq_pos == first_seq) + return unknown_index; + found_seq = *(seq_pos - 1); + } + if (!found_seq.containsPC(address)) + return unknown_index; + // Search for instruction address in the rows describing the sequence. + // Rows are stored in a vector, so we may use arithmetical operations with + // iterators. + DWARFDebugLine::Row row; + row.Address = address; + RowIter first_row = Rows.begin() + found_seq.FirstRowIndex; + RowIter last_row = Rows.begin() + found_seq.LastRowIndex; + RowIter row_pos = std::lower_bound(first_row, last_row, row, + DWARFDebugLine::Row::orderByAddress); + if (row_pos == last_row) { + return found_seq.LastRowIndex - 1; + } + uint32_t index = found_seq.FirstRowIndex + (row_pos - first_row); + if (row_pos->Address > address) { + if (row_pos == first_row) + return unknown_index; + else + index--; } - return index; // Failed to find address. + return index; }