[DebugInfo] add SectionedAddress to DebugInfo interfaces.
That patch is the fix for https://bugs.llvm.org/show_bug.cgi?id=40703
"wrong line number info for obj file compiled with -ffunction-sections"
bug. The problem happened with only .o files. If object file contains
several .text sections then line number information showed incorrectly.
The reason for this is that DwarfLineTable could not detect section which
corresponds to specified address(because address is the local to the
section). And as the result it could not select proper sequence in the
line table. The fix is to pass SectionIndex with the address. So that it
would be possible to differentiate addresses from various sections. With
this fix llvm-objdump shows correct line numbers for disassembled code.
Differential review: https://reviews.llvm.org/D58194
llvm-svn: 354972
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 406c342..a2c2524 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -353,7 +353,8 @@
}
void DWARFDebugLine::Row::reset(bool DefaultIsStmt) {
- Address = 0;
+ Address.Address = 0;
+ Address.SectionIndex = object::SectionedAddress::UndefSection;
Line = 1;
Column = 0;
File = 1;
@@ -373,7 +374,7 @@
}
void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
- OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
+ OS << format("0x%16.16" PRIx64 " %6u %6u", Address.Address, Line, Column)
<< format(" %6u %3u %13u ", File, Isa, Discriminator)
<< (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
<< (PrologueEnd ? " prologue_end" : "")
@@ -386,6 +387,7 @@
void DWARFDebugLine::Sequence::reset() {
LowPC = 0;
HighPC = 0;
+ SectionIndex = object::SectionedAddress::UndefSection;
FirstRowIndex = 0;
LastRowIndex = 0;
Empty = true;
@@ -426,15 +428,16 @@
if (Sequence.Empty) {
// Record the beginning of instruction sequence.
Sequence.Empty = false;
- Sequence.LowPC = Row.Address;
+ Sequence.LowPC = Row.Address.Address;
Sequence.FirstRowIndex = RowNumber;
}
++RowNumber;
LineTable->appendRow(Row);
if (Row.EndSequence) {
// Record the end of instruction sequence.
- Sequence.HighPC = Row.Address;
+ Sequence.HighPC = Row.Address.Address;
Sequence.LastRowIndex = RowNumber;
+ Sequence.SectionIndex = Row.Address.SectionIndex;
if (Sequence.isValid())
LineTable->appendSequence(Sequence);
Sequence.reset();
@@ -565,9 +568,10 @@
ExtOffset, DebugLineData.getAddressSize(),
Len - 1);
}
- State.Row.Address = DebugLineData.getRelocatedAddress(OffsetPtr);
+ State.Row.Address.Address = DebugLineData.getRelocatedAddress(
+ OffsetPtr, &State.Row.Address.SectionIndex);
if (OS)
- *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address);
+ *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
break;
case DW_LNE_define_file:
@@ -654,7 +658,7 @@
{
uint64_t AddrOffset =
DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength;
- State.Row.Address += AddrOffset;
+ State.Row.Address.Address += AddrOffset;
if (OS)
*OS << " (" << AddrOffset << ")";
}
@@ -712,7 +716,7 @@
uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase;
uint64_t AddrOffset =
(AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
- State.Row.Address += AddrOffset;
+ State.Row.Address.Address += AddrOffset;
if (OS)
*OS
<< format(" (0x%16.16" PRIx64 ")", AddrOffset);
@@ -731,7 +735,7 @@
// can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
{
uint16_t PCOffset = DebugLineData.getU16(OffsetPtr);
- State.Row.Address += PCOffset;
+ State.Row.Address.Address += PCOffset;
if (OS)
*OS
<< format(" (0x%16.16" PRIx64 ")", PCOffset);
@@ -814,7 +818,7 @@
int32_t LineOffset =
Prologue.LineBase + (AdjustOpcode % Prologue.LineRange);
State.Row.Line += LineOffset;
- State.Row.Address += AddrOffset;
+ State.Row.Address.Address += AddrOffset;
if (OS) {
*OS << "address += " << AddrOffset << ", line += " << LineOffset
@@ -850,11 +854,12 @@
return Error::success();
}
-uint32_t
-DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq,
- uint64_t Address) const {
+uint32_t DWARFDebugLine::LineTable::findRowInSeq(
+ const DWARFDebugLine::Sequence &Seq,
+ object::SectionedAddress Address) const {
if (!Seq.containsPC(Address))
return UnknownRowIndex;
+ assert(Seq.SectionIndex == Address.SectionIndex);
// Search for instruction address in the rows describing the sequence.
// Rows are stored in a vector, so we may use arithmetical operations with
// iterators.
@@ -867,8 +872,9 @@
if (RowPos == LastRow) {
return Seq.LastRowIndex - 1;
}
+ assert(Seq.SectionIndex == RowPos->Address.SectionIndex);
uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow);
- if (RowPos->Address > Address) {
+ if (RowPos->Address.Address > Address.Address) {
if (RowPos == FirstRow)
return UnknownRowIndex;
else
@@ -877,42 +883,81 @@
return Index;
}
-uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const {
+uint32_t DWARFDebugLine::LineTable::lookupAddress(
+ object::SectionedAddress Address) const {
+
+ // Search for relocatable addresses
+ uint32_t Result = lookupAddressImpl(Address);
+
+ if (Result != UnknownRowIndex ||
+ Address.SectionIndex == object::SectionedAddress::UndefSection)
+ return Result;
+
+ // Search for absolute addresses
+ Address.SectionIndex = object::SectionedAddress::UndefSection;
+ return lookupAddressImpl(Address);
+}
+
+uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
+ object::SectionedAddress Address) const {
if (Sequences.empty())
return UnknownRowIndex;
// First, find an instruction sequence containing the given address.
DWARFDebugLine::Sequence Sequence;
- Sequence.LowPC = Address;
+ Sequence.SectionIndex = Address.SectionIndex;
+ Sequence.LowPC = Address.Address;
SequenceIter FirstSeq = Sequences.begin();
SequenceIter LastSeq = Sequences.end();
SequenceIter SeqPos = std::lower_bound(
FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
DWARFDebugLine::Sequence FoundSeq;
+
if (SeqPos == LastSeq) {
FoundSeq = Sequences.back();
- } else if (SeqPos->LowPC == Address) {
+ } else if (SeqPos->LowPC == Address.Address &&
+ SeqPos->SectionIndex == Address.SectionIndex) {
FoundSeq = *SeqPos;
} else {
if (SeqPos == FirstSeq)
return UnknownRowIndex;
FoundSeq = *(SeqPos - 1);
}
+ if (FoundSeq.SectionIndex != Address.SectionIndex)
+ return UnknownRowIndex;
return findRowInSeq(FoundSeq, Address);
}
bool DWARFDebugLine::LineTable::lookupAddressRange(
- uint64_t Address, uint64_t Size, std::vector<uint32_t> &Result) const {
+ object::SectionedAddress Address, uint64_t Size,
+ std::vector<uint32_t> &Result) const {
+
+ // Search for relocatable addresses
+ if (lookupAddressRangeImpl(Address, Size, Result))
+ return true;
+
+ if (Address.SectionIndex == object::SectionedAddress::UndefSection)
+ return false;
+
+ // Search for absolute addresses
+ Address.SectionIndex = object::SectionedAddress::UndefSection;
+ return lookupAddressRangeImpl(Address, Size, Result);
+}
+
+bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
+ object::SectionedAddress Address, uint64_t Size,
+ std::vector<uint32_t> &Result) const {
if (Sequences.empty())
return false;
- uint64_t EndAddr = Address + Size;
+ uint64_t EndAddr = Address.Address + Size;
// First, find an instruction sequence containing the given address.
DWARFDebugLine::Sequence Sequence;
- Sequence.LowPC = Address;
+ Sequence.SectionIndex = Address.SectionIndex;
+ Sequence.LowPC = Address.Address;
SequenceIter FirstSeq = Sequences.begin();
SequenceIter LastSeq = Sequences.end();
SequenceIter SeqPos = std::lower_bound(
FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
- if (SeqPos == LastSeq || SeqPos->LowPC != Address) {
+ if (SeqPos == LastSeq || !SeqPos->containsPC(Address)) {
if (SeqPos == FirstSeq)
return false;
SeqPos--;
@@ -934,7 +979,8 @@
FirstRowIndex = findRowInSeq(CurSeq, Address);
// Figure out the last row in the range.
- uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1);
+ uint32_t LastRowIndex =
+ findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex});
if (LastRowIndex == UnknownRowIndex)
LastRowIndex = CurSeq.LastRowIndex - 1;
@@ -1011,8 +1057,8 @@
}
bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
- uint64_t Address, const char *CompDir, FileLineInfoKind Kind,
- DILineInfo &Result) const {
+ object::SectionedAddress Address, const char *CompDir,
+ FileLineInfoKind Kind, DILineInfo &Result) const {
// Get the index of row we're looking for in the line table.
uint32_t RowIndex = lookupAddress(Address);
if (RowIndex == -1U)