forked from OSchip/llvm-project
llvm-dwarfdump: Don't try to parse rnglist tables when dumping CUs
It's not possible to do this in complete generality - a CU using a sec_offset DW_AT_ranges has no way of knowing where its rnglists contribution starts, so should not attempt to parse any full rnglist table/header to do so. And even using FORM_rnglistx there's no need to parse the header - the offset can be computed using the CU's DWARF format (32 or 64) to compute offset entry sizes, and then the list parsed at that offset without ever trying to find a rnglist contribution header immediately prior to the rnglists_base.
This commit is contained in:
parent
e372c1d762
commit
6d0be74af5
|
@ -116,9 +116,15 @@ public:
|
|||
if (Index > HeaderData.OffsetEntryCount)
|
||||
return None;
|
||||
|
||||
return getOffsetEntry(Data, getHeaderOffset() + getHeaderSize(Format), Format, Index);
|
||||
}
|
||||
|
||||
static Optional<uint64_t> getOffsetEntry(DataExtractor Data,
|
||||
uint64_t OffsetTableOffset,
|
||||
dwarf::DwarfFormat Format,
|
||||
uint32_t Index) {
|
||||
uint8_t OffsetByteSize = Format == dwarf::DWARF64 ? 8 : 4;
|
||||
uint64_t Offset =
|
||||
getHeaderOffset() + getHeaderSize(Format) + OffsetByteSize * Index;
|
||||
uint64_t Offset = OffsetTableOffset + OffsetByteSize * Index;
|
||||
auto R = Data.getUnsigned(&Offset, OffsetByteSize);
|
||||
return R;
|
||||
}
|
||||
|
@ -272,9 +278,10 @@ DWARFListTableBase<DWARFListType>::findList(DWARFDataExtractor Data,
|
|||
uint64_t Offset) {
|
||||
// Extract the list from the section and enter it into the list map.
|
||||
DWARFListType List;
|
||||
Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
|
||||
if (Header.length())
|
||||
Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
|
||||
if (Error E =
|
||||
List.extract(Data, getHeaderOffset(), &Offset,
|
||||
List.extract(Data, Header.length() ? getHeaderOffset() : 0, &Offset,
|
||||
Header.getSectionName(), Header.getListTypeString()))
|
||||
return std::move(E);
|
||||
return List;
|
||||
|
|
|
@ -229,7 +229,6 @@ class DWARFUnit {
|
|||
Optional<StrOffsetsContributionDescriptor> StringOffsetsTableContribution;
|
||||
|
||||
/// A table of range lists (DWARF v5 and later).
|
||||
Optional<DWARFDebugRnglistTable> RngListTable;
|
||||
Optional<DWARFListTableHeader> LoclistTableHeader;
|
||||
|
||||
mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
|
||||
|
|
|
@ -503,27 +503,9 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
|
|||
DWARFListTableHeader::getHeaderSize(Header.getFormat()));
|
||||
} else
|
||||
setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
|
||||
toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
|
||||
if (RangeSection->Data.size()) {
|
||||
// Parse the range list table header. Individual range lists are
|
||||
// extracted lazily.
|
||||
DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
|
||||
isLittleEndian, 0);
|
||||
auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>(
|
||||
RangesDA, RangeSectionBase, Header.getFormat());
|
||||
if (!TableOrError)
|
||||
return createStringError(errc::invalid_argument,
|
||||
"parsing a range list table: " +
|
||||
toString(TableOrError.takeError()));
|
||||
|
||||
RngListTable = TableOrError.get();
|
||||
|
||||
// In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
|
||||
// Adjust RangeSectionBase to point past the table header.
|
||||
if (IsDWO && RngListTable)
|
||||
RangeSectionBase =
|
||||
ContributionBaseOffset + RngListTable->getHeaderSize();
|
||||
}
|
||||
toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
|
||||
DWARFListTableHeader::getHeaderSize(
|
||||
Header.getFormat())));
|
||||
|
||||
// In a split dwarf unit, there is no DW_AT_loclists_base attribute.
|
||||
// Setting LocSectionBase to point past the table header.
|
||||
|
@ -602,19 +584,8 @@ bool DWARFUnit::parseDWO() {
|
|||
if (AddrOffsetSectionBase)
|
||||
DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
|
||||
if (getVersion() >= 5) {
|
||||
DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
|
||||
DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
|
||||
isLittleEndian, 0);
|
||||
if (auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>(
|
||||
RangesDA, RangeSectionBase, Header.getFormat()))
|
||||
DWO->RngListTable = TableOrError.get();
|
||||
else
|
||||
Context.getRecoverableErrorHandler()(createStringError(
|
||||
errc::invalid_argument, "parsing a range list table: %s",
|
||||
toString(TableOrError.takeError()).c_str()));
|
||||
|
||||
if (DWO->RngListTable)
|
||||
DWO->RangeSectionBase = DWO->RngListTable->getHeaderSize();
|
||||
DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(),
|
||||
DWARFListTableHeader::getHeaderSize(getFormat()));
|
||||
} else {
|
||||
auto DWORangesBase = UnitDie.getRangesBaseAttribute();
|
||||
DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
|
||||
|
@ -638,17 +609,13 @@ DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
|
|||
return std::move(E);
|
||||
return RangeList.getAbsoluteRanges(getBaseAddress());
|
||||
}
|
||||
if (RngListTable) {
|
||||
DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
|
||||
isLittleEndian, RngListTable->getAddrSize());
|
||||
auto RangeListOrError = RngListTable->findList(RangesData, Offset);
|
||||
if (RangeListOrError)
|
||||
return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
|
||||
return RangeListOrError.takeError();
|
||||
}
|
||||
|
||||
return createStringError(errc::invalid_argument,
|
||||
"missing or invalid range list table");
|
||||
DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
|
||||
isLittleEndian, Header.getAddressByteSize());
|
||||
DWARFDebugRnglistTable RnglistTable;
|
||||
auto RangeListOrError = RnglistTable.findList(RangesData, Offset);
|
||||
if (RangeListOrError)
|
||||
return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
|
||||
return RangeListOrError.takeError();
|
||||
}
|
||||
|
||||
Expected<DWARFAddressRangesVector>
|
||||
|
@ -656,12 +623,10 @@ DWARFUnit::findRnglistFromIndex(uint32_t Index) {
|
|||
if (auto Offset = getRnglistOffset(Index))
|
||||
return findRnglistFromOffset(*Offset);
|
||||
|
||||
if (RngListTable)
|
||||
return createStringError(errc::invalid_argument,
|
||||
"invalid range list table index %d", Index);
|
||||
|
||||
return createStringError(errc::invalid_argument,
|
||||
"missing or invalid range list table");
|
||||
"invalid range list table index %d (possibly "
|
||||
"missing the entire range list table)",
|
||||
Index);
|
||||
}
|
||||
|
||||
Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
|
||||
|
@ -1007,11 +972,12 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
|
|||
}
|
||||
|
||||
Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) {
|
||||
if (!RngListTable)
|
||||
return None;
|
||||
DataExtractor RangesData(RangeSection->Data, isLittleEndian,
|
||||
getAddressByteSize());
|
||||
if (Optional<uint64_t> Off = RngListTable->getOffsetEntry(RangesData, Index))
|
||||
DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
|
||||
isLittleEndian, 0);
|
||||
if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
|
||||
RangesData, RangeSectionBase, getFormat(), Index))
|
||||
return *Off + RangeSectionBase;
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
|
||||
# RUN: not llvm-dwarfdump -v -debug-info %t.o 2> %t.err | FileCheck %s
|
||||
# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR
|
||||
# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR --implicit-check-not=error
|
||||
# RUN: not llvm-dwarfdump -lookup 10 %t.o 2> %t2.err
|
||||
# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR
|
||||
# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR --implicit-check-not=error
|
||||
# RUN: llvm-dwarfdump -debug-rnglists %t.o | \
|
||||
# RUN: FileCheck %s --check-prefix=RNGLISTS
|
||||
|
||||
|
@ -209,8 +209,7 @@ Range1_end:
|
|||
# CHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x1) rangelist = 0x00000025
|
||||
# CHECK-NEXT: [0x0000002a, 0x00000034))
|
||||
|
||||
#ERR: error: parsing a range list table: did not detect a valid list table with base = 0x8
|
||||
#ERR: error: decoding address ranges: missing or invalid range list table
|
||||
#ERR: error: decoding address ranges: invalid range list offset 0x4000500000008
|
||||
#ERR: error: decoding address ranges: invalid range list offset 0xfa0
|
||||
|
||||
# RNGLISTS: .debug_rnglists contents:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
|
||||
# RUN: not llvm-dwarfdump -v -debug-info %t.o 2> %t.err | FileCheck %s
|
||||
# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR
|
||||
# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR --implicit-check-not=error
|
||||
# RUN: not llvm-dwarfdump -lookup 10 %t.o 2> %t2.err
|
||||
# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR
|
||||
# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR --implicit-check-not=error
|
||||
|
||||
# Test object to verify dwarfdump handles v5 range lists.
|
||||
# We use very simplified compile unit dies.
|
||||
|
@ -203,6 +203,4 @@ Range1_end:
|
|||
# CHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x1) rangelist = 0x00000015
|
||||
# CHECK-NEXT: [0x0000002a, 0x00000034))
|
||||
|
||||
#ERR: error: parsing a range list table: did not detect a valid list table with base = 0x8
|
||||
#ERR: error: decoding address ranges: missing or invalid range list table
|
||||
#ERR: error: decoding address ranges: invalid range list offset 0xfa0
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
# RUN: llvm-mc %s -filetype obj -triple i386-pc-linux -o %t.o
|
||||
# RUN: not llvm-dwarfdump -v -debug-info -debug-line -debug-addr -debug-rnglists -debug-ranges %t.o | FileCheck --implicit-check-not=DW_TAG --implicit-check-not=DW_AT %s
|
||||
|
||||
# FIXME: Remove the 'not' once the rnglist are lazily/correctly parsed (see comment below)
|
||||
# RUN: llvm-dwarfdump -v -debug-info -debug-line -debug-addr -debug-rnglists -debug-ranges %t.o | FileCheck --implicit-check-not=DW_TAG --implicit-check-not=DW_AT %s
|
||||
|
||||
# Test that llvm - dwarfdump strips addresses relating to dead code(using the
|
||||
# DWARFv6 - proposed tombstone constant & nearest equivalent for debug_ranges)
|
||||
|
@ -45,17 +43,14 @@
|
|||
# CHECK: DW_TAG_compile_unit
|
||||
# CHECK: DW_AT_addr_base
|
||||
|
||||
# FIXME: Lazily parse rnglists rather than expecting to be able to parse an
|
||||
# entire rnglists contribution (since there's no way to know where such a
|
||||
# contribution starts) - rather than assuming one starts at 0.
|
||||
|
||||
# CHECK: DW_AT_ranges
|
||||
# [0x0000000000000042, 0x0000000000000048)
|
||||
# [0x0000000000000042, 0x0000000000000048)
|
||||
# [0x0000000000000042, 0x0000000000000048)
|
||||
# [0x0000000000000042, 0x0000000000000042)
|
||||
# [0x0000000000000042, 0x0000000000000048)
|
||||
# [0x0000000000000042, 0x0000000000000048))
|
||||
# CHECK-NEXT: [0x0000000000000042, 0x0000000000000048)
|
||||
# CHECK-NEXT: [0x0000000000000042, 0x0000000000000048)
|
||||
# CHECK-NEXT: [0x0000000000000042, 0x0000000000000048)
|
||||
# CHECK-NEXT: [0x0000000000000042, 0x0000000000000042)
|
||||
# CHECK-NEXT: [0x0000000000000042, 0x0000000000000048)
|
||||
# CHECK-NEXT: [0x0000000000000042, 0x0000000000000048))
|
||||
# CHECK: DW_TAG_subprogram
|
||||
# CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0xffffffffffffffff (dead code))
|
||||
# CHECK: DW_AT_high_pc [DW_FORM_data4] (0x00000006)
|
||||
|
|
Loading…
Reference in New Issue