summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp56
1 files changed, 37 insertions, 19 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index c5add6a478b..eb138e28307 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -33,8 +33,9 @@ using namespace dwarf;
void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(),
- C.getStringSection(), StringRef(), &C.getAddrSection(),
- C.getLineSection().Data, C.isLittleEndian(), false);
+ C.getStringSection(), C.getStringOffsetSection(),
+ &C.getAddrSection(), C.getLineSection().Data, C.isLittleEndian(),
+ false);
}
void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
@@ -48,19 +49,14 @@ void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
- StringRef SS, StringRef SOS, const DWARFSection *AOS,
- StringRef LS, bool LE, bool IsDWO,
+ StringRef SS, const DWARFSection &SOS,
+ const DWARFSection *AOS, StringRef 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([&]() {
- if (IndexEntry)
- if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
- return SOS.slice(C->Offset, C->Offset + C->Length);
- return SOS;
- }()),
- AddrOffsetSection(AOS), isLittleEndian(LE), isDWO(IsDWO),
- UnitSection(UnitSection), IndexEntry(IndexEntry) {
+ LineSection(LS), StringSection(SS), StringOffsetSection(SOS),
+ StringOffsetSectionBase(0), AddrOffsetSection(AOS), isLittleEndian(LE),
+ isDWO(IsDWO), UnitSection(UnitSection), IndexEntry(IndexEntry) {
clear();
}
@@ -77,17 +73,25 @@ bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
}
bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
- uint32_t &Result) const {
- // FIXME: string offset section entries are 8-byte for DWARF64.
- const uint32_t ItemSize = 4;
- uint32_t Offset = Index * ItemSize;
- if (StringOffsetSection.size() < Offset + ItemSize)
+ uint64_t &Result) const {
+ unsigned ItemSize = getFormat() == DWARF64 ? 8 : 4;
+ uint32_t Offset = StringOffsetSectionBase + Index * ItemSize;
+ if (StringOffsetSection.Data.size() < Offset + ItemSize)
return false;
- DataExtractor DA(StringOffsetSection, isLittleEndian, 0);
- Result = DA.getU32(&Offset);
+ DataExtractor DA(StringOffsetSection.Data, isLittleEndian, 0);
+ Result = ItemSize == 4 ? DA.getU32(&Offset) : DA.getU64(&Offset);
return true;
}
+uint64_t DWARFUnit::getStringOffsetSectionRelocation(uint32_t Index) const {
+ unsigned ItemSize = getFormat() == DWARF64 ? 8 : 4;
+ uint64_t ByteOffset = StringOffsetSectionBase + Index * ItemSize;
+ RelocAddrMap::const_iterator AI = getStringOffsetsRelocMap().find(ByteOffset);
+ if (AI != getStringOffsetsRelocMap().end())
+ return AI->second.Value;
+ return 0;
+}
+
bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
Length = debug_info.getU32(offset_ptr);
Version = debug_info.getU16(offset_ptr);
@@ -119,6 +123,9 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
if (!LengthOK || !VersionOK || !AddrSizeOK)
return false;
+ // Keep track of the highest DWARF version we encounter across all units.
+ Context.setMaxVersionIfGreater(Version);
+
Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset);
return Abbrevs != nullptr;
}
@@ -242,6 +249,17 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
setBaseAddress(*BaseAddr);
AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
+
+ // In general, we derive the offset of the unit's contibution to the
+ // debug_str_offsets{.dwo} section from the unit DIE's
+ // DW_AT_str_offsets_base attribute. In dwp files we add to it the offset
+ // we get from the index table.
+ StringOffsetSectionBase =
+ toSectionOffset(UnitDie.find(DW_AT_str_offsets_base), 0);
+ if (IndexEntry)
+ if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
+ StringOffsetSectionBase += C->Offset;
+
// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
// skeleton CU DIE, so that DWARF users not aware of it are not broken.
}
OpenPOWER on IntegriCloud