diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
commit | 044eb2f6afba375a914ac9d8024f8f5142bb912e (patch) | |
tree | 1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/DebugInfo/DWARF/DWARFUnit.cpp | |
parent | eb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff) |
Notes
Diffstat (limited to 'lib/DebugInfo/DWARF/DWARFUnit.cpp')
-rw-r--r-- | lib/DebugInfo/DWARF/DWARFUnit.cpp | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp index 043bdb874f43..c3d8ff2cbc29 100644 --- a/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -30,18 +30,20 @@ using namespace llvm; using namespace dwarf; void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) { - parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(), - C.getStringSection(), C.getStringOffsetSection(), - &C.getAddrSection(), C.getLineSection(), C.isLittleEndian(), false); + const DWARFObject &D = C.getDWARFObj(); + parseImpl(C, Section, C.getDebugAbbrev(), &D.getRangeSection(), + D.getStringSection(), D.getStringOffsetSection(), + &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false, + false); } void DWARFUnitSectionBase::parseDWO(DWARFContext &C, - const DWARFSection &DWOSection, - DWARFUnitIndex *Index) { - parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &C.getRangeDWOSection(), - C.getStringDWOSection(), C.getStringOffsetDWOSection(), - &C.getAddrSection(), C.getLineDWOSection(), C.isLittleEndian(), - true); + const DWARFSection &DWOSection, bool Lazy) { + const DWARFObject &D = C.getDWARFObj(); + parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(), + D.getStringDWOSection(), D.getStringOffsetDWOSection(), + &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(), + true, Lazy); } DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, @@ -59,13 +61,18 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, DWARFUnit::~DWARFUnit() = default; +DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const { + return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian, + getAddressByteSize()); +} + bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const { uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize(); if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize()) return false; - DWARFDataExtractor DA(*AddrOffsetSection, isLittleEndian, - getAddressByteSize()); + DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection, + isLittleEndian, getAddressByteSize()); Result = DA.getRelocatedAddress(&Offset); return true; } @@ -76,7 +83,8 @@ bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index, uint32_t Offset = StringOffsetSectionBase + Index * ItemSize; if (StringOffsetSection.Data.size() < Offset + ItemSize) return false; - DWARFDataExtractor DA(StringOffsetSection, isLittleEndian, 0); + DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection, + isLittleEndian, 0); Result = DA.getRelocatedValue(ItemSize, &Offset); return true; } @@ -86,7 +94,6 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) { // FIXME: Support DWARF64. FormParams.Format = DWARF32; FormParams.Version = debug_info.getU16(offset_ptr); - uint64_t AbbrOffset; if (FormParams.Version >= 5) { UnitType = debug_info.getU8(offset_ptr); FormParams.AddrSize = debug_info.getU8(offset_ptr); @@ -116,9 +123,7 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) { // Keep track of the highest DWARF version we encounter across all units. Context.setMaxVersionIfGreater(getVersion()); - - Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset); - return Abbrevs != nullptr; + return true; } bool DWARFUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) { @@ -141,8 +146,8 @@ bool DWARFUnit::extractRangeList(uint32_t RangeListOffset, DWARFDebugRangeList &RangeList) const { // Require that compile unit is extracted. assert(!DieArray.empty()); - DWARFDataExtractor RangesData(*RangeSection, isLittleEndian, - getAddressByteSize()); + DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection, + isLittleEndian, getAddressByteSize()); uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset; return RangeList.extract(RangesData, &ActualRangeListOffset); } @@ -152,7 +157,7 @@ void DWARFUnit::clear() { Length = 0; Abbrevs = nullptr; FormParams = DWARFFormParams({0, 0, DWARF32}); - BaseAddr = 0; + BaseAddr.reset(); RangeSectionBase = 0; AddrOffsetSectionBase = 0; clearDIEs(false); @@ -234,11 +239,17 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { // If CU DIE was just parsed, copy several attribute values from it. if (!HasCUDie) { DWARFDie UnitDie = getUnitDIE(); - auto BaseAddr = toAddress(UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc})); - if (BaseAddr) - setBaseAddress(*BaseAddr); - AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0); - RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0); + Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc}); + if (Optional<uint64_t> Addr = toAddress(PC)) + setBaseAddress({*Addr, PC->getSectionIndex()}); + + if (!isDWO) { + assert(AddrOffsetSectionBase == 0); + assert(RangeSectionBase == 0); + 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 @@ -295,18 +306,8 @@ bool DWARFUnit::parseDWO() { void DWARFUnit::clearDIEs(bool KeepCUDie) { if (DieArray.size() > (unsigned)KeepCUDie) { - // std::vectors never get any smaller when resized to a smaller size, - // or when clear() or erase() are called, the size will report that it - // is smaller, but the memory allocated remains intact (call capacity() - // to see this). So we need to create a temporary vector and swap the - // contents which will cause just the internal pointers to be swapped - // so that when temporary vector goes out of scope, it will destroy the - // contents. - std::vector<DWARFDebugInfoEntry> TmpArray; - DieArray.swap(TmpArray); - // Save at least the compile unit DIE - if (KeepCUDie) - DieArray.push_back(TmpArray.front()); + DieArray.resize((unsigned)KeepCUDie); + DieArray.shrink_to_fit(); } } @@ -439,7 +440,7 @@ DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) { // NULL DIEs don't have siblings. if (Die->getAbbreviationDeclarationPtr() == nullptr) return DWARFDie(); - + // Find the next DIE whose depth is the same as the Die's depth. for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx; ++I) { @@ -448,3 +449,20 @@ DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) { } return DWARFDie(); } + +DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) { + if (!Die->hasChildren()) + return DWARFDie(); + + // We do not want access out of bounds when parsing corrupted debug data. + size_t I = getDIEIndex(Die) + 1; + if (I >= DieArray.size()) + return DWARFDie(); + return DWARFDie(this, &DieArray[I]); +} + +const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const { + if (!Abbrevs) + Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset); + return Abbrevs; +} |