[DWARF] Factor out a DWARFUnitHeader class. NFC
Extract information related to a "unit header" from DWARFUnit into a
new DWARFUnitHeader class, and add a DWARFUnit member for the header.
This is one step in the direction of allowing type units in the
.debug_info section for DWARF v5.
Differential Revision: https://reviews.llvm.org/D46707
llvm-svn: 332289
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index a0c5c19..00be75e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -18,26 +18,13 @@
using namespace llvm;
-bool DWARFTypeUnit::extractImpl(const DWARFDataExtractor &debug_info,
- uint32_t *offset_ptr) {
- if (!DWARFUnit::extractImpl(debug_info, offset_ptr))
- return false;
- TypeHash = debug_info.getU64(offset_ptr);
- TypeOffset = debug_info.getU32(offset_ptr);
- // TypeOffset is relative to the beginning of the header,
- // so we have to account for the leading length field.
- // FIXME: The size of the length field is 12 in DWARF64.
- unsigned SizeOfLength = 4;
- return TypeOffset < getLength() + SizeOfLength;
-}
-
void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
- DWARFDie TD = getDIEForOffset(TypeOffset + getOffset());
+ DWARFDie TD = getDIEForOffset(getTypeOffset() + getOffset());
const char *Name = TD.getName(DINameKind::ShortName);
if (DumpOpts.SummarizeTypes) {
OS << "name = '" << Name << "'"
- << " type_signature = " << format("0x%016" PRIx64, TypeHash)
+ << " type_signature = " << format("0x%016" PRIx64, getTypeHash())
<< " length = " << format("0x%08x", getLength()) << '\n';
return;
}
@@ -50,8 +37,8 @@
OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())
<< " addr_size = " << format("0x%02x", getAddressByteSize())
<< " name = '" << Name << "'"
- << " type_signature = " << format("0x%016" PRIx64, TypeHash)
- << " type_offset = " << format("0x%04x", TypeOffset)
+ << " type_signature = " << format("0x%016" PRIx64, getTypeHash())
+ << " type_offset = " << format("0x%04x", getTypeOffset())
<< " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";
if (DWARFDie TU = getUnitDIE(false))
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 2d456b4..6fa604c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -48,15 +48,15 @@
}
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
+ const DWARFUnitHeader &Header,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE,
- bool IsDWO, const DWARFUnitSectionBase &UnitSection,
- const DWARFUnitIndex::Entry *IndexEntry)
- : Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
- LineSection(LS), StringSection(SS), StringOffsetSection(SOS),
- AddrOffsetSection(AOS), isLittleEndian(LE), isDWO(IsDWO),
- UnitSection(UnitSection), IndexEntry(IndexEntry) {
+ bool IsDWO, const DWARFUnitSectionBase &UnitSection)
+ : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
+ RangeSection(RS), LineSection(LS), StringSection(SS),
+ StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
+ isDWO(IsDWO), UnitSection(UnitSection) {
clear();
}
@@ -92,10 +92,16 @@
return true;
}
-bool DWARFUnit::extractImpl(const DWARFDataExtractor &debug_info,
- uint32_t *offset_ptr) {
+bool DWARFUnitHeader::extract(DWARFContext &Context,
+ const DWARFDataExtractor &debug_info,
+ uint32_t *offset_ptr,
+ DWARFSectionKind SectionKind,
+ const DWARFUnitIndex *Index) {
+ Offset = *offset_ptr;
+ IndexEntry = Index ? Index->getFromOffset(*offset_ptr) : nullptr;
Length = debug_info.getU32(offset_ptr);
// FIXME: Support DWARF64.
+ unsigned SizeOfLength = 4;
FormParams.Format = DWARF32;
FormParams.Version = debug_info.getU16(offset_ptr);
if (FormParams.Version >= 5) {
@@ -105,6 +111,12 @@
} else {
AbbrOffset = debug_info.getRelocatedValue(4, offset_ptr);
FormParams.AddrSize = debug_info.getU8(offset_ptr);
+ // Fake a unit type based on the section type. This isn't perfect,
+ // but distinguishing compile and type units is generally enough.
+ if (SectionKind == DW_SECT_TYPES)
+ UnitType = DW_UT_type;
+ else
+ UnitType = DW_UT_compile;
}
if (IndexEntry) {
if (AbbrOffset)
@@ -117,12 +129,20 @@
return false;
AbbrOffset = AbbrEntry->Offset;
}
-
+ bool TypeOffsetOK = true;
+ if (isTypeUnit()) {
+ TypeHash = debug_info.getU64(offset_ptr);
+ TypeOffset = debug_info.getU32(offset_ptr);
+ // Type offset is unit-relative; should be after the header and before
+ // the end of the current unit.
+ TypeOffsetOK = TypeOffset >= *offset_ptr - Offset &&
+ TypeOffset < getLength() + SizeOfLength;
+ }
bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8;
- if (!LengthOK || !VersionOK || !AddrSizeOK)
+ if (!LengthOK || !VersionOK || !AddrSizeOK || !TypeOffsetOK)
return false;
// Keep track of the highest DWARF version we encounter across all units.
@@ -130,23 +150,6 @@
return true;
}
-bool DWARFUnit::extract(const DWARFDataExtractor &debug_info,
- uint32_t *offset_ptr) {
- clear();
-
- Offset = *offset_ptr;
-
- if (debug_info.isValidOffset(*offset_ptr)) {
- if (extractImpl(debug_info, offset_ptr))
- return true;
-
- // reset the offset to where we tried to parse from if anything went wrong
- *offset_ptr = Offset;
- }
-
- return false;
-}
-
bool DWARFUnit::extractRangeList(uint32_t RangeListOffset,
DWARFDebugRangeList &RangeList) const {
// Require that compile unit is extracted.
@@ -158,10 +161,7 @@
}
void DWARFUnit::clear() {
- Offset = 0;
- Length = 0;
Abbrevs = nullptr;
- FormParams = dwarf::FormParams({0, 0, DWARF32});
BaseAddr.reset();
RangeSectionBase = 0;
AddrOffsetSectionBase = 0;
@@ -185,7 +185,7 @@
// Set the offset to that of the first DIE and calculate the start of the
// next compilation unit header.
- uint32_t DIEOffset = Offset + getHeaderSize();
+ uint32_t DIEOffset = getOffset() + getHeaderSize();
uint32_t NextCUOffset = getNextUnitOffset();
DWARFDebugInfoEntry DIE;
DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
@@ -266,6 +266,7 @@
// which may differ from the unit's format.
uint64_t StringOffsetsContributionBase =
isDWO ? 0 : toSectionOffset(UnitDie.find(DW_AT_str_offsets_base), 0);
+ auto IndexEntry = Header.getIndexEntry();
if (IndexEntry)
if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
StringOffsetsContributionBase += C->Offset;
@@ -486,7 +487,7 @@
const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
if (!Abbrevs)
- Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset);
+ Abbrevs = Abbrev->getAbbreviationDeclarationSet(Header.getAbbrOffset());
return Abbrevs;
}
@@ -570,6 +571,7 @@
// index table (in a package file). In a .dwo file it is simply
// the length of the string offsets section.
uint64_t Size = 0;
+ auto IndexEntry = Header.getIndexEntry();
if (!IndexEntry)
Size = StringOffsetSection.Data.size();
else if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index b3b8d7d..99eab98 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -274,16 +274,17 @@
if (isUnitDWARF64)
break;
} else {
+ DWARFUnitHeader Header;
+ Header.extract(DCtx, DebugInfoData, &OffsetStart);
std::unique_ptr<DWARFUnit> Unit;
switch (UnitType) {
case dwarf::DW_UT_type:
case dwarf::DW_UT_split_type: {
Unit.reset(new DWARFTypeUnit(
- DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
+ DCtx, DObj.getInfoSection(), Header, DCtx.getDebugAbbrev(),
&DObj.getRangeSection(), DObj.getStringSection(),
DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
- DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection,
- nullptr));
+ DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection));
break;
}
case dwarf::DW_UT_skeleton:
@@ -294,16 +295,14 @@
// verifying a compile unit in DWARF v4.
case 0: {
Unit.reset(new DWARFCompileUnit(
- DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
+ DCtx, DObj.getInfoSection(), Header, DCtx.getDebugAbbrev(),
&DObj.getRangeSection(), DObj.getStringSection(),
DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
- DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection,
- nullptr));
+ DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection));
break;
}
default: { llvm_unreachable("Invalid UnitType."); }
}
- Unit->extract(DebugInfoData, &OffsetStart);
if (!verifyUnitContents(*Unit, UnitType))
++NumDebugInfoErrors;
}