Skip to content

Commit 8036cf7

Browse files
committed
llvm-dwarfdump: Skip tombstoned address ranges
Make the dumper & API a bit more informative by using the new tombstone addresses to filter out or otherwise render more explicitly dead code ranges.
1 parent 8aaa731 commit 8036cf7

File tree

8 files changed

+615
-32
lines changed

8 files changed

+615
-32
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
946946
llvm::Expected<llvm::DWARFAddressRangesVector> llvm_ranges =
947947
range_list_or_error->getAbsoluteRanges(
948948
llvm::object::SectionedAddress{GetBaseAddress()},
949-
[&](uint32_t index) {
949+
GetAddressByteSize(), [&](uint32_t index) {
950950
uint32_t index_size = GetAddressByteSize();
951951
dw_offset_t addr_base = GetAddrBase();
952952
lldb::offset_t offset = addr_base + index * index_size;

llvm/include/llvm/BinaryFormat/Dwarf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "llvm/Support/FormatVariadicDetails.h"
2828
#include "llvm/ADT/Triple.h"
2929

30+
#include <limits>
31+
3032
namespace llvm {
3133
class StringRef;
3234

@@ -745,6 +747,11 @@ template <> struct EnumTraits<LocationAtom> : public std::true_type {
745747
static constexpr char Type[3] = "OP";
746748
static constexpr StringRef (*StringFn)(unsigned) = &OperationEncodingString;
747749
};
750+
751+
inline uint64_t computeTombstoneAddress(uint8_t AddressByteSize) {
752+
return std::numeric_limits<uint64_t>::max() >> (8 - AddressByteSize) * 8;
753+
}
754+
748755
} // End of namespace dwarf
749756

750757
/// Dwarf constants format_provider

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class DWARFDebugRnglist : public DWARFListType<RangeListEntry> {
4848
/// Build a DWARFAddressRangesVector from a rangelist.
4949
DWARFAddressRangesVector
5050
getAbsoluteRanges(Optional<object::SectionedAddress> BaseAddr,
51+
uint8_t AddressByteSize,
5152
function_ref<Optional<object::SectionedAddress>(uint32_t)>
5253
LookupPooledAddress) const;
5354

llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,18 @@ Error DWARFDebugLine::LineTable::parse(
783783
*OS << '\n';
784784
Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0);
785785
}
786+
bool TombstonedAddress = false;
787+
auto EmitRow = [&] {
788+
if (!TombstonedAddress) {
789+
if (Verbose) {
790+
*OS << "\n";
791+
OS->indent(12);
792+
}
793+
if (OS)
794+
State.Row.dump(*OS);
795+
State.appendRowToMatrix();
796+
}
797+
};
786798
while (*OffsetPtr < EndOffset) {
787799
DataExtractor::Cursor Cursor(*OffsetPtr);
788800

@@ -834,13 +846,7 @@ Error DWARFDebugLine::LineTable::parse(
834846
// No need to test the Cursor is valid here, since it must be to get
835847
// into this code path - if it were invalid, the default case would be
836848
// followed.
837-
if (Verbose) {
838-
*OS << "\n";
839-
OS->indent(12);
840-
}
841-
if (OS)
842-
State.Row.dump(*OS);
843-
State.appendRowToMatrix();
849+
EmitRow();
844850
State.resetRowAndSequence();
845851
break;
846852

@@ -882,6 +888,10 @@ Error DWARFDebugLine::LineTable::parse(
882888
State.Row.Address.Address = TableData.getRelocatedAddress(
883889
Cursor, &State.Row.Address.SectionIndex);
884890

891+
uint64_t Tombstone =
892+
dwarf::computeTombstoneAddress(OpcodeAddressSize);
893+
TombstonedAddress = State.Row.Address.Address == Tombstone;
894+
885895
// Restore the address size if the extractor already had it.
886896
if (ExtractorAddressSize != 0)
887897
TableData.setAddressSize(ExtractorAddressSize);
@@ -981,13 +991,7 @@ Error DWARFDebugLine::LineTable::parse(
981991
case DW_LNS_copy:
982992
// Takes no arguments. Append a row to the matrix using the
983993
// current values of the state-machine registers.
984-
if (Verbose) {
985-
*OS << "\n";
986-
OS->indent(12);
987-
}
988-
if (OS)
989-
State.Row.dump(*OS);
990-
State.appendRowToMatrix();
994+
EmitRow();
991995
break;
992996

993997
case DW_LNS_advance_pc:
@@ -1152,15 +1156,9 @@ Error DWARFDebugLine::LineTable::parse(
11521156
ParsingState::AddrAndLineDelta Delta =
11531157
State.handleSpecialOpcode(Opcode, OpcodeOffset);
11541158

1155-
if (Verbose) {
1156-
*OS << "address += " << Delta.Address << ", line += " << Delta.Line
1157-
<< "\n";
1158-
OS->indent(12);
1159-
}
1160-
if (OS)
1161-
State.Row.dump(*OS);
1162-
1163-
State.appendRowToMatrix();
1159+
if (Verbose)
1160+
*OS << "address += " << Delta.Address << ", line += " << Delta.Line;
1161+
EmitRow();
11641162
*OffsetPtr = Cursor.tell();
11651163
}
11661164

llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const {
7070
DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
7171
llvm::Optional<object::SectionedAddress> BaseAddr) const {
7272
DWARFAddressRangesVector Res;
73+
// debug_addr can't use the max integer tombstone because that's used for the
74+
// base address specifier entry - so use max-1.
75+
uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressSize) - 1;
7376
for (const RangeListEntry &RLE : Entries) {
7477
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
7578
BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
@@ -78,12 +81,16 @@ DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
7881

7982
DWARFAddressRange E;
8083
E.LowPC = RLE.StartAddress;
84+
if (E.LowPC == Tombstone)
85+
continue;
8186
E.HighPC = RLE.EndAddress;
8287
E.SectionIndex = RLE.SectionIndex;
8388
// Base address of a range list entry is determined by the closest preceding
8489
// base address selection entry in the same range list. It defaults to the
8590
// base address of the compilation unit if there is no such entry.
8691
if (BaseAddr) {
92+
if (BaseAddr->Address == Tombstone)
93+
continue;
8794
E.LowPC += BaseAddr->Address;
8895
E.HighPC += BaseAddr->Address;
8996
if (E.SectionIndex == -1ULL)

llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,17 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) {
8989

9090
DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
9191
llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const {
92-
return getAbsoluteRanges(BaseAddr, [&](uint32_t Index) {
93-
return U.getAddrOffsetSectionItem(Index);
94-
});
92+
return getAbsoluteRanges(
93+
BaseAddr, U.getAddressByteSize(),
94+
[&](uint32_t Index) { return U.getAddrOffsetSectionItem(Index); });
9595
}
9696

9797
DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
98-
Optional<object::SectionedAddress> BaseAddr,
98+
Optional<object::SectionedAddress> BaseAddr, uint8_t AddressByteSize,
9999
function_ref<Optional<object::SectionedAddress>(uint32_t)>
100100
LookupPooledAddress) const {
101101
DWARFAddressRangesVector Res;
102+
uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressByteSize);
102103
for (const RangeListEntry &RLE : Entries) {
103104
if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
104105
break;
@@ -121,8 +122,12 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
121122
switch (RLE.EntryKind) {
122123
case dwarf::DW_RLE_offset_pair:
123124
E.LowPC = RLE.Value0;
125+
if (E.LowPC == Tombstone)
126+
continue;
124127
E.HighPC = RLE.Value1;
125128
if (BaseAddr) {
129+
if (BaseAddr->Address == Tombstone)
130+
continue;
126131
E.LowPC += BaseAddr->Address;
127132
E.HighPC += BaseAddr->Address;
128133
}
@@ -149,6 +154,8 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
149154
// so we should not run into any here.
150155
llvm_unreachable("Unsupported range list encoding");
151156
}
157+
if (E.LowPC == Tombstone)
158+
continue;
152159
Res.push_back(E);
153160
}
154161
return Res;
@@ -181,6 +188,8 @@ void RangeListEntry::dump(
181188
OS << ": ";
182189
}
183190

191+
uint64_t Tombstone = dwarf::computeTombstoneAddress(AddrSize);
192+
184193
switch (EntryKind) {
185194
case dwarf::DW_RLE_end_of_list:
186195
OS << (DumpOpts.Verbose ? "" : "<End of list>");
@@ -208,8 +217,11 @@ void RangeListEntry::dump(
208217
break;
209218
case dwarf::DW_RLE_offset_pair:
210219
PrintRawEntry(OS, *this, AddrSize, DumpOpts);
211-
DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)
212-
.dump(OS, AddrSize, DumpOpts);
220+
if (CurrentBase != Tombstone)
221+
DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)
222+
.dump(OS, AddrSize, DumpOpts);
223+
else
224+
OS << "dead code";
213225
break;
214226
case dwarf::DW_RLE_start_end:
215227
DWARFAddressRange(Value0, Value1).dump(OS, AddrSize, DumpOpts);

llvm/lib/DebugInfo/DWARF/DWARFDie.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,18 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
268268
WithColor(OS, Color) << Name;
269269
else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
270270
OS << *FormValue.getAsUnsignedConstant();
271-
else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
272-
FormValue.getAsUnsignedConstant()) {
271+
else if (Attr == DW_AT_low_pc &&
272+
(FormValue.getAsAddress() ==
273+
dwarf::computeTombstoneAddress(U->getAddressByteSize()))) {
274+
if (DumpOpts.Verbose) {
275+
FormValue.dump(OS, DumpOpts);
276+
OS << " (";
277+
}
278+
OS << "dead code";
279+
if (DumpOpts.Verbose)
280+
OS << ')';
281+
} else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
282+
FormValue.getAsUnsignedConstant()) {
273283
if (DumpOpts.ShowAddresses) {
274284
// Print the actual address rather than the offset.
275285
uint64_t LowPC, HighPC, Index;
@@ -415,6 +425,9 @@ Optional<uint64_t> DWARFDie::getLocBaseAttribute() const {
415425
}
416426

417427
Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
428+
uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize());
429+
if (LowPC == Tombstone)
430+
return None;
418431
if (auto FormValue = find(DW_AT_high_pc)) {
419432
if (auto Address = FormValue->getAsAddress()) {
420433
// High PC is an address.

0 commit comments

Comments
 (0)