summaryrefslogtreecommitdiff
path: root/lib/DebugInfo/DWARF/DWARFUnit.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/DebugInfo/DWARF/DWARFUnit.cpp
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/DebugInfo/DWARF/DWARFUnit.cpp')
-rw-r--r--lib/DebugInfo/DWARF/DWARFUnit.cpp92
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;
+}