diff options
author | Mircea Trofin <mtrofin@google.com> | 2019-03-15 15:00:12 +0000 |
---|---|---|
committer | Mircea Trofin <mtrofin@google.com> | 2019-03-15 15:00:12 +0000 |
commit | 2c3ab665393c725c39470470b719ecac63de23a3 (patch) | |
tree | 1c971b529c5ab6919ebacd085c81f59966b46c9f /llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | |
parent | a06b467ddcfc778e452e8f2db726d4ec1b6c5b4a (diff) | |
download | bcm5719-llvm-2c3ab665393c725c39470470b719ecac63de23a3.tar.gz bcm5719-llvm-2c3ab665393c725c39470470b719ecac63de23a3.zip |
[llvm] Skip over empty line table entries.
Summary:
This is similar to how addr2line handles consecutive entries with the
same address - pick the last one.
Reviewers: dblaikie, friss, JDevlieghere
Reviewed By: dblaikie
Subscribers: eugenis, vitalybuka, echristo, JDevlieghere, probinson, aprantl, hiraditya, rupprecht, jdoerfert, llvm-commits
Tags: #llvm, #debug-info
Differential Revision: https://reviews.llvm.org/D58952
llvm-svn: 356265
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index a2c25248618..53420187773 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -869,17 +869,36 @@ uint32_t DWARFDebugLine::LineTable::findRowInSeq( RowIter LastRow = Rows.begin() + Seq.LastRowIndex; LineTable::RowIter RowPos = std::lower_bound( FirstRow, LastRow, Row, DWARFDebugLine::Row::orderByAddress); - if (RowPos == LastRow) { - return Seq.LastRowIndex - 1; - } + // Since Address is in Seq, FirstRow <= RowPos < LastRow. + assert(FirstRow <= RowPos && RowPos < LastRow); assert(Seq.SectionIndex == RowPos->Address.SectionIndex); - uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow); - if (RowPos->Address.Address > Address.Address) { - if (RowPos == FirstRow) - return UnknownRowIndex; - else - Index--; + if (RowPos->Address.Address != Address.Address) { + // lower_bound either lands on the RowPos with the same Address + // as the queried one, or on the first that's larger. + assert(RowPos->Address.Address > Address.Address); + // We know RowPos can't be FirstRow, in this case, + // because the queried Address is in Seq. So if it were + // FirstRow, then RowPos->Address.Address == Address.Address, + // and we wouldn't be here. + assert(RowPos != FirstRow); + --RowPos; } + // In some cases, e.g. first instruction in a function, the compiler generates + // two entries, both with the same address. We want the last one. + // There are 2 cases wrt. RowPos and the addresses in records before/after it: + // 1) RowPos's address is the one we looked for. In this case, we want to + // skip any potential empty ranges. + // 2) RowPos's address is less than the one we looked for. In that case, we + // arrived here by finding the first range with a greater address, + // then decrementing 1. If the address of this range is part of a sequence of + // empty ones, it is the last one. + // In either case, the loop below lands on the correct RowPos. + while (RowPos->Address.Address == (RowPos + 1)->Address.Address) { + ++RowPos; + } + + assert(RowPos < LastRow); + uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow); return Index; } |