diff options
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r-- | lib/DebugInfo/DWARFAbbreviationDeclaration.cpp | 18 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFAbbreviationDeclaration.h | 15 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFCompileUnit.h | 2 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFContext.cpp | 308 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFContext.h | 182 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugAbbrev.cpp | 19 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugArangeSet.cpp | 12 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugArangeSet.h | 13 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugAranges.cpp | 25 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugFrame.cpp | 22 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugFrame.h | 3 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugInfoEntry.cpp | 11 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugInfoEntry.h | 3 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugLine.cpp | 46 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugLine.h | 13 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugLoc.cpp | 74 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugLoc.h | 21 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFDebugRangeList.cpp | 13 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFTypeUnit.h | 4 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFUnit.cpp | 13 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFUnit.h | 7 |
21 files changed, 496 insertions, 328 deletions
diff --git a/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp b/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp index f46fd58a63..c3e570e14c 100644 --- a/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp +++ b/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp @@ -18,7 +18,7 @@ void DWARFAbbreviationDeclaration::clear() { Code = 0; Tag = 0; HasChildren = false; - Attributes.clear(); + AttributeSpecs.clear(); } DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() { @@ -51,7 +51,7 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data, uint32_t* OffsetPtr) { } if (Attr == 0 && Form == 0) break; - Attributes.push_back(AttributeSpec(Attr, Form)); + AttributeSpecs.push_back(AttributeSpec(Attr, Form)); } if (Tag == 0) { @@ -69,19 +69,19 @@ void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const { else OS << format("DW_TAG_Unknown_%x", getTag()); OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n'; - for (unsigned i = 0, e = Attributes.size(); i != e; ++i) { + for (const AttributeSpec &Spec : AttributeSpecs) { OS << '\t'; - const char *attrString = AttributeString(Attributes[i].Attr); + const char *attrString = AttributeString(Spec.Attr); if (attrString) OS << attrString; else - OS << format("DW_AT_Unknown_%x", Attributes[i].Attr); + OS << format("DW_AT_Unknown_%x", Spec.Attr); OS << '\t'; - const char *formString = FormEncodingString(Attributes[i].Form); + const char *formString = FormEncodingString(Spec.Form); if (formString) OS << formString; else - OS << format("DW_FORM_Unknown_%x", Attributes[i].Form); + OS << format("DW_FORM_Unknown_%x", Spec.Form); OS << '\n'; } OS << '\n'; @@ -89,8 +89,8 @@ void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const { uint32_t DWARFAbbreviationDeclaration::findAttributeIndex(uint16_t attr) const { - for (uint32_t i = 0, e = Attributes.size(); i != e; ++i) { - if (Attributes[i].Attr == attr) + for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) { + if (AttributeSpecs[i].Attr == attr) return i; } return -1U; diff --git a/lib/DebugInfo/DWARFAbbreviationDeclaration.h b/lib/DebugInfo/DWARFAbbreviationDeclaration.h index e9b072eb86..b86b9ecbe4 100644 --- a/lib/DebugInfo/DWARFAbbreviationDeclaration.h +++ b/lib/DebugInfo/DWARFAbbreviationDeclaration.h @@ -27,19 +27,24 @@ class DWARFAbbreviationDeclaration { uint16_t Attr; uint16_t Form; }; - SmallVector<AttributeSpec, 8> Attributes; + typedef SmallVector<AttributeSpec, 8> AttributeSpecVector; + AttributeSpecVector AttributeSpecs; public: DWARFAbbreviationDeclaration(); uint32_t getCode() const { return Code; } uint32_t getTag() const { return Tag; } bool hasChildren() const { return HasChildren; } - uint32_t getNumAttributes() const { return Attributes.size(); } - uint16_t getAttrByIndex(uint32_t idx) const { - return idx < Attributes.size() ? Attributes[idx].Attr : 0; + + typedef iterator_range<AttributeSpecVector::const_iterator> + attr_iterator_range; + + attr_iterator_range attributes() const { + return attr_iterator_range(AttributeSpecs.begin(), AttributeSpecs.end()); } + uint16_t getFormByIndex(uint32_t idx) const { - return idx < Attributes.size() ? Attributes[idx].Form : 0; + return idx < AttributeSpecs.size() ? AttributeSpecs[idx].Form : 0; } uint32_t findAttributeIndex(uint16_t attr) const; diff --git a/lib/DebugInfo/DWARFCompileUnit.h b/lib/DebugInfo/DWARFCompileUnit.h index 1c9573b0b4..d1853d80a3 100644 --- a/lib/DebugInfo/DWARFCompileUnit.h +++ b/lib/DebugInfo/DWARFCompileUnit.h @@ -22,7 +22,7 @@ public: : DWARFUnit(DA, IS, AS, RS, SS, SOS, AOS, M, LE) {} void dump(raw_ostream &OS); // VTable anchor. - ~DWARFCompileUnit() LLVM_OVERRIDE; + ~DWARFCompileUnit() override; }; } diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index e47719025c..60c5f6ab56 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -10,7 +10,6 @@ #include "DWARFContext.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" @@ -23,38 +22,34 @@ using namespace object; typedef DWARFDebugLine::LineTable DWARFLineTable; -DWARFContext::~DWARFContext() { - DeleteContainerPointers(CUs); - DeleteContainerPointers(TUs); - DeleteContainerPointers(DWOCUs); -} - static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data, bool LittleEndian, bool GnuStyle) { OS << "\n." << Name << " contents:\n"; DataExtractor pubNames(Data, LittleEndian, 0); uint32_t offset = 0; - OS << "length = " << format("0x%08x", pubNames.getU32(&offset)); - OS << " version = " << format("0x%04x", pubNames.getU16(&offset)); - OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset)); - OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n'; - if (GnuStyle) - OS << "Offset Linkage Kind Name\n"; - else - OS << "Offset Name\n"; - - while (offset < Data.size()) { - uint32_t dieRef = pubNames.getU32(&offset); - if (dieRef == 0) - break; - OS << format("0x%8.8x ", dieRef); - if (GnuStyle) { - PubIndexEntryDescriptor desc(pubNames.getU8(&offset)); - OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage)) - << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind)) - << ' '; + while (pubNames.isValidOffset(offset)) { + OS << "length = " << format("0x%08x", pubNames.getU32(&offset)); + OS << " version = " << format("0x%04x", pubNames.getU16(&offset)); + OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset)); + OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n'; + if (GnuStyle) + OS << "Offset Linkage Kind Name\n"; + else + OS << "Offset Name\n"; + + while (offset < Data.size()) { + uint32_t dieRef = pubNames.getU32(&offset); + if (dieRef == 0) + break; + OS << format("0x%8.8x ", dieRef); + if (GnuStyle) { + PubIndexEntryDescriptor desc(pubNames.getU8(&offset)); + OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage)) + << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind)) + << ' '; + } + OS << '\"' << pubNames.getCStr(&offset) << "\"\n"; } - OS << '\"' << pubNames.getCStr(&offset) << "\"\n"; } } @@ -64,16 +59,36 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { getDebugAbbrev()->dump(OS); } + if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) + if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) { + OS << "\n.debug_abbrev.dwo contents:\n"; + D->dump(OS); + } + if (DumpType == DIDT_All || DumpType == DIDT_Info) { OS << "\n.debug_info contents:\n"; - for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) - getCompileUnitAtIndex(i)->dump(OS); + for (const auto &CU : compile_units()) + CU->dump(OS); + } + + if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) && + getNumDWOCompileUnits()) { + OS << "\n.debug_info.dwo contents:\n"; + for (const auto &DWOCU : dwo_compile_units()) + DWOCU->dump(OS); } - if (DumpType == DIDT_All || DumpType == DIDT_Types) { + if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) { OS << "\n.debug_types contents:\n"; - for (unsigned i = 0, e = getNumTypeUnits(); i != e; ++i) - getTypeUnitAtIndex(i)->dump(OS); + for (const auto &TU : type_units()) + TU->dump(OS); + } + + if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) && + getNumDWOTypeUnits()) { + OS << "\n.debug_types.dwo contents:\n"; + for (const auto &DWOTU : dwo_type_units()) + DWOTU->dump(OS); } if (DumpType == DIDT_All || DumpType == DIDT_Loc) { @@ -81,6 +96,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { getDebugLoc()->dump(OS); } + if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) { + OS << "\n.debug_loc.dwo contents:\n"; + getDebugLocDWO()->dump(OS); + } + if (DumpType == DIDT_All || DumpType == DIDT_Frames) { OS << "\n.debug_frame contents:\n"; getDebugFrame()->dump(OS); @@ -98,12 +118,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { uint8_t savedAddressByteSize = 0; if (DumpType == DIDT_All || DumpType == DIDT_Line) { OS << "\n.debug_line contents:\n"; - for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) { - DWARFCompileUnit *cu = getCompileUnitAtIndex(i); - savedAddressByteSize = cu->getAddressByteSize(); + for (const auto &CU : compile_units()) { + savedAddressByteSize = CU->getAddressByteSize(); unsigned stmtOffset = - cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset( - cu, DW_AT_stmt_list, -1U); + CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset( + CU.get(), DW_AT_stmt_list, -1U); if (stmtOffset != -1U) { DataExtractor lineData(getLineSection().Data, isLittleEndian(), savedAddressByteSize); @@ -113,6 +132,16 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { } } + if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) { + OS << "\n.debug_line.dwo contents:\n"; + unsigned stmtOffset = 0; + DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(), + savedAddressByteSize); + DWARFDebugLine::DumpingState state(OS); + while (DWARFDebugLine::parsePrologue(lineData, &stmtOffset, &state.Prologue)) + state.finalize(); + } + if (DumpType == DIDT_All || DumpType == DIDT_Str) { OS << "\n.debug_str contents:\n"; DataExtractor strData(getStringSection(), isLittleEndian(), 0); @@ -124,6 +153,18 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { } } + if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) && + !getStringDWOSection().empty()) { + OS << "\n.debug_str.dwo contents:\n"; + DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0); + offset = 0; + uint32_t strDWOOffset = 0; + while (const char *s = strDWOData.getCStr(&offset)) { + OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s); + strDWOOffset = offset; + } + } + if (DumpType == DIDT_All || DumpType == DIDT_Ranges) { OS << "\n.debug_ranges contents:\n"; // In fact, different compile units may have different address byte @@ -154,44 +195,18 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(), isLittleEndian(), true /* GnuStyle */); - if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) { - const DWARFDebugAbbrev *D = getDebugAbbrevDWO(); - if (D) { - OS << "\n.debug_abbrev.dwo contents:\n"; - getDebugAbbrevDWO()->dump(OS); + if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) && + !getStringOffsetDWOSection().empty()) { + OS << "\n.debug_str_offsets.dwo contents:\n"; + DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), + 0); + offset = 0; + uint64_t size = getStringOffsetDWOSection().size(); + while (offset < size) { + OS << format("0x%8.8x: ", offset); + OS << format("%8.8x\n", strOffsetExt.getU32(&offset)); } } - - if (DumpType == DIDT_All || DumpType == DIDT_InfoDwo) - if (getNumDWOCompileUnits()) { - OS << "\n.debug_info.dwo contents:\n"; - for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i) - getDWOCompileUnitAtIndex(i)->dump(OS); - } - - if (DumpType == DIDT_All || DumpType == DIDT_StrDwo) - if (!getStringDWOSection().empty()) { - OS << "\n.debug_str.dwo contents:\n"; - DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0); - offset = 0; - uint32_t strDWOOffset = 0; - while (const char *s = strDWOData.getCStr(&offset)) { - OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s); - strDWOOffset = offset; - } - } - - if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) - if (!getStringOffsetDWOSection().empty()) { - OS << "\n.debug_str_offsets.dwo contents:\n"; - DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0); - offset = 0; - uint64_t size = getStringOffsetDWOSection().size(); - while (offset < size) { - OS << format("0x%8.8x: ", offset); - OS << format("%8.8x\n", strOffsetExt.getU32(&offset)); - } - } } const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { @@ -227,6 +242,16 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() { return Loc.get(); } +const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() { + if (LocDWO) + return LocDWO.get(); + + DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0); + LocDWO.reset(new DWARFDebugLocDWO()); + LocDWO->parse(LocData); + return LocDWO.get(); +} + const DWARFDebugAranges *DWARFContext::getDebugAranges() { if (Aranges) return Aranges.get(); @@ -278,50 +303,52 @@ DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) { } void DWARFContext::parseCompileUnits() { + if (!CUs.empty()) + return; uint32_t offset = 0; const DataExtractor &DIData = DataExtractor(getInfoSection().Data, isLittleEndian(), 0); while (DIData.isValidOffset(offset)) { - OwningPtr<DWARFCompileUnit> CU(new DWARFCompileUnit( + std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit( getDebugAbbrev(), getInfoSection().Data, getAbbrevSection(), getRangeSection(), getStringSection(), StringRef(), getAddrSection(), &getInfoSection().Relocs, isLittleEndian())); if (!CU->extract(DIData, &offset)) { break; } - CUs.push_back(CU.take()); + CUs.push_back(std::move(CU)); offset = CUs.back()->getNextUnitOffset(); } } void DWARFContext::parseTypeUnits() { - const std::map<object::SectionRef, Section> &Sections = getTypesSections(); - for (std::map<object::SectionRef, Section>::const_iterator - I = Sections.begin(), - E = Sections.end(); - I != E; ++I) { + if (!TUs.empty()) + return; + for (const auto &I : getTypesSections()) { uint32_t offset = 0; const DataExtractor &DIData = - DataExtractor(I->second.Data, isLittleEndian(), 0); + DataExtractor(I.second.Data, isLittleEndian(), 0); while (DIData.isValidOffset(offset)) { - OwningPtr<DWARFTypeUnit> TU(new DWARFTypeUnit( - getDebugAbbrev(), I->second.Data, getAbbrevSection(), + std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit( + getDebugAbbrev(), I.second.Data, getAbbrevSection(), getRangeSection(), getStringSection(), StringRef(), getAddrSection(), - &I->second.Relocs, isLittleEndian())); + &I.second.Relocs, isLittleEndian())); if (!TU->extract(DIData, &offset)) break; - TUs.push_back(TU.take()); + TUs.push_back(std::move(TU)); offset = TUs.back()->getNextUnitOffset(); } } } void DWARFContext::parseDWOCompileUnits() { + if (!DWOCUs.empty()) + return; uint32_t offset = 0; const DataExtractor &DIData = DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0); while (DIData.isValidOffset(offset)) { - OwningPtr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit( + std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit( getDebugAbbrevDWO(), getInfoDWOSection().Data, getAbbrevDWOSection(), getRangeDWOSection(), getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), @@ -329,34 +356,57 @@ void DWARFContext::parseDWOCompileUnits() { if (!DWOCU->extract(DIData, &offset)) { break; } - DWOCUs.push_back(DWOCU.take()); + DWOCUs.push_back(std::move(DWOCU)); offset = DWOCUs.back()->getNextUnitOffset(); } } +void DWARFContext::parseDWOTypeUnits() { + if (!DWOTUs.empty()) + return; + for (const auto &I : getTypesDWOSections()) { + uint32_t offset = 0; + const DataExtractor &DIData = + DataExtractor(I.second.Data, isLittleEndian(), 0); + while (DIData.isValidOffset(offset)) { + std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit( + getDebugAbbrevDWO(), I.second.Data, getAbbrevDWOSection(), + getRangeDWOSection(), getStringDWOSection(), + getStringOffsetDWOSection(), getAddrSection(), &I.second.Relocs, + isLittleEndian())); + if (!TU->extract(DIData, &offset)) + break; + DWOTUs.push_back(std::move(TU)); + offset = DWOTUs.back()->getNextUnitOffset(); + } + } +} + namespace { struct OffsetComparator { - bool operator()(const DWARFCompileUnit *LHS, - const DWARFCompileUnit *RHS) const { + + bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS, + const std::unique_ptr<DWARFCompileUnit> &RHS) const { return LHS->getOffset() < RHS->getOffset(); } - bool operator()(const DWARFCompileUnit *LHS, uint32_t RHS) const { + bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS, + uint32_t RHS) const { return LHS->getOffset() < RHS; } - bool operator()(uint32_t LHS, const DWARFCompileUnit *RHS) const { + bool operator()(uint32_t LHS, + const std::unique_ptr<DWARFCompileUnit> &RHS) const { return LHS < RHS->getOffset(); } }; } DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) { - if (CUs.empty()) - parseCompileUnits(); + parseCompileUnits(); - DWARFCompileUnit **CU = + std::unique_ptr<DWARFCompileUnit> *CU = std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator()); if (CU != CUs.end()) { - return *CU; + return CU->get(); } return 0; } @@ -484,9 +534,7 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, if (!LineTable->lookupAddressRange(Address, Size, RowVector)) return Lines; - uint32_t NumRows = RowVector.size(); - for (uint32_t i = 0; i < NumRows; ++i) { - uint32_t RowIndex = RowVector[i]; + for (uint32_t RowIndex : RowVector) { // Take file number and line/column from the row. const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; std::string FileName = "<invalid>"; @@ -572,17 +620,14 @@ static bool consumeCompressedDebugSectionHeader(StringRef &data, return true; } -DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : - IsLittleEndian(Obj->isLittleEndian()), - AddressSize(Obj->getBytesInAddress()) { - error_code ec; - for (object::section_iterator i = Obj->begin_sections(), - e = Obj->end_sections(); - i != e; i.increment(ec)) { +DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) + : IsLittleEndian(Obj->isLittleEndian()), + AddressSize(Obj->getBytesInAddress()) { + for (const SectionRef &Section : Obj->sections()) { StringRef name; - i->getName(name); + Section.getName(name); StringRef data; - i->getContents(data); + Section.getContents(data); name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes. @@ -592,17 +637,17 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : if (!zlib::isAvailable() || !consumeCompressedDebugSectionHeader(data, OriginalSize)) continue; - OwningPtr<MemoryBuffer> UncompressedSection; + std::unique_ptr<MemoryBuffer> UncompressedSection; if (zlib::uncompress(data, UncompressedSection, OriginalSize) != zlib::StatusOK) continue; // Make data point to uncompressed section contents and save its contents. name = name.substr(1); data = UncompressedSection->getBuffer(); - UncompressedSections.push_back(UncompressedSection.take()); + UncompressedSections.push_back(std::move(UncompressedSection)); } - StringRef *Section = + StringRef *SectionData = StringSwitch<StringRef *>(name) .Case("debug_info", &InfoSection.Data) .Case("debug_abbrev", &AbbrevSection) @@ -618,13 +663,15 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : .Case("debug_gnu_pubtypes", &GnuPubTypesSection) .Case("debug_info.dwo", &InfoDWOSection.Data) .Case("debug_abbrev.dwo", &AbbrevDWOSection) + .Case("debug_loc.dwo", &LocDWOSection.Data) + .Case("debug_line.dwo", &LineDWOSection.Data) .Case("debug_str.dwo", &StringDWOSection) .Case("debug_str_offsets.dwo", &StringOffsetDWOSection) .Case("debug_addr", &AddrSection) // Any more debug info sections go here. .Default(0); - if (Section) { - *Section = data; + if (SectionData) { + *SectionData = data; if (name == "debug_ranges") { // FIXME: Use the other dwo range section when we emit it. RangeDWOSection = data; @@ -632,11 +679,13 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : } else if (name == "debug_types") { // Find debug_types data by section rather than name as there are // multiple, comdat grouped, debug_types sections. - TypesSections[*i].Data = data; + TypesSections[Section].Data = data; + } else if (name == "debug_types.dwo") { + TypesDWOSections[Section].Data = data; } - section_iterator RelocatedSection = i->getRelocatedSection(); - if (RelocatedSection == Obj->end_sections()) + section_iterator RelocatedSection = Section.getRelocatedSection(); + if (RelocatedSection == Obj->section_end()) continue; StringRef RelSecName; @@ -653,36 +702,37 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : .Case("debug_line", &LineSection.Relocs) .Default(0); if (!Map) { - if (RelSecName != "debug_types") - continue; // Find debug_types relocs by section rather than name as there are // multiple, comdat grouped, debug_types sections. - Map = &TypesSections[*RelocatedSection].Relocs; + if (RelSecName == "debug_types") + Map = &TypesSections[*RelocatedSection].Relocs; + else if (RelSecName == "debug_types.dwo") + Map = &TypesDWOSections[*RelocatedSection].Relocs; + else + continue; } - if (i->begin_relocations() != i->end_relocations()) { + if (Section.relocation_begin() != Section.relocation_end()) { uint64_t SectionSize; RelocatedSection->getSize(SectionSize); - for (object::relocation_iterator reloc_i = i->begin_relocations(), - reloc_e = i->end_relocations(); - reloc_i != reloc_e; reloc_i.increment(ec)) { + for (const RelocationRef &Reloc : Section.relocations()) { uint64_t Address; - reloc_i->getOffset(Address); + Reloc.getOffset(Address); uint64_t Type; - reloc_i->getType(Type); + Reloc.getType(Type); uint64_t SymAddr = 0; // ELF relocations may need the symbol address if (Obj->isELF()) { - object::symbol_iterator Sym = reloc_i->getSymbol(); + object::symbol_iterator Sym = Reloc.getSymbol(); Sym->getAddress(SymAddr); } object::RelocVisitor V(Obj->getFileFormatName()); // The section address is always 0 for debug sections. - object::RelocToApply R(V.visit(Type, *reloc_i, 0, SymAddr)); + object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr)); if (V.error()) { SmallString<32> Name; - error_code ec(reloc_i->getTypeName(Name)); + error_code ec(Reloc.getTypeName(Name)); if (ec) { errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n"; } @@ -712,8 +762,4 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : } } -DWARFContextInMemory::~DWARFContextInMemory() { - DeleteContainerPointers(UncompressedSections); -} - void DWARFContextInMemory::anchor() { } diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h index 03863ab8b1..ad6841ae9e 100644 --- a/lib/DebugInfo/DWARFContext.h +++ b/lib/DebugInfo/DWARFContext.h @@ -17,7 +17,7 @@ #include "DWARFDebugLoc.h" #include "DWARFDebugRangeList.h" #include "DWARFTypeUnit.h" -#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/DIContext.h" @@ -28,30 +28,41 @@ namespace llvm { /// information parsing. The actual data is supplied through pure virtual /// methods that a concrete implementation provides. class DWARFContext : public DIContext { - SmallVector<DWARFCompileUnit *, 1> CUs; - SmallVector<DWARFTypeUnit *, 1> TUs; - OwningPtr<DWARFDebugAbbrev> Abbrev; - OwningPtr<DWARFDebugLoc> Loc; - OwningPtr<DWARFDebugAranges> Aranges; - OwningPtr<DWARFDebugLine> Line; - OwningPtr<DWARFDebugFrame> DebugFrame; - - SmallVector<DWARFCompileUnit *, 1> DWOCUs; - OwningPtr<DWARFDebugAbbrev> AbbrevDWO; + typedef SmallVector<std::unique_ptr<DWARFCompileUnit>, 1> CUVector; + typedef SmallVector<std::unique_ptr<DWARFTypeUnit>, 1> TUVector; + + CUVector CUs; + TUVector TUs; + std::unique_ptr<DWARFDebugAbbrev> Abbrev; + std::unique_ptr<DWARFDebugLoc> Loc; + std::unique_ptr<DWARFDebugAranges> Aranges; + std::unique_ptr<DWARFDebugLine> Line; + std::unique_ptr<DWARFDebugFrame> DebugFrame; + + CUVector DWOCUs; + TUVector DWOTUs; + std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO; + std::unique_ptr<DWARFDebugLocDWO> LocDWO; DWARFContext(DWARFContext &) LLVM_DELETED_FUNCTION; DWARFContext &operator=(DWARFContext &) LLVM_DELETED_FUNCTION; - /// Read compile units from the debug_info section and store them in CUs. + /// Read compile units from the debug_info section (if necessary) + /// and store them in CUs. void parseCompileUnits(); - /// Read type units from the debug_types sections and store them in CUs. + /// Read type units from the debug_types sections (if necessary) + /// and store them in TUs. void parseTypeUnits(); - /// Read compile units from the debug_info.dwo section and store them in - /// DWOCUs. + /// Read compile units from the debug_info.dwo section (if necessary) + /// and store them in DWOCUs. void parseDWOCompileUnits(); + /// Read type units from the debug_types.dwo section (if necessary) + /// and store them in DWOTUs. + void parseDWOTypeUnits(); + public: struct Section { StringRef Data; @@ -59,54 +70,74 @@ public: }; DWARFContext() : DIContext(CK_DWARF) {} - virtual ~DWARFContext(); static bool classof(const DIContext *DICtx) { return DICtx->getKind() == CK_DWARF; } - virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All); + void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override; + + typedef iterator_range<CUVector::iterator> cu_iterator_range; + typedef iterator_range<TUVector::iterator> tu_iterator_range; + + /// Get compile units in this context. + cu_iterator_range compile_units() { + parseCompileUnits(); + return cu_iterator_range(CUs.begin(), CUs.end()); + } + + /// Get type units in this context. + tu_iterator_range type_units() { + parseTypeUnits(); + return tu_iterator_range(TUs.begin(), TUs.end()); + } + + /// Get compile units in the DWO context. + cu_iterator_range dwo_compile_units() { + parseDWOCompileUnits(); + return cu_iterator_range(DWOCUs.begin(), DWOCUs.end()); + } + + /// Get type units in the DWO context. + tu_iterator_range dwo_type_units() { + parseDWOTypeUnits(); + return tu_iterator_range(DWOTUs.begin(), DWOTUs.end()); + } /// Get the number of compile units in this context. unsigned getNumCompileUnits() { - if (CUs.empty()) - parseCompileUnits(); + parseCompileUnits(); return CUs.size(); } /// Get the number of compile units in this context. unsigned getNumTypeUnits() { - if (TUs.empty()) - parseTypeUnits(); + parseTypeUnits(); return TUs.size(); } /// Get the number of compile units in the DWO context. unsigned getNumDWOCompileUnits() { - if (DWOCUs.empty()) - parseDWOCompileUnits(); + parseDWOCompileUnits(); return DWOCUs.size(); } - /// Get the compile unit at the specified index for this compile unit. - DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { - if (CUs.empty()) - parseCompileUnits(); - return CUs[index]; + /// Get the number of compile units in the DWO context. + unsigned getNumDWOTypeUnits() { + parseDWOTypeUnits(); + return DWOTUs.size(); } - /// Get the type unit at the specified index for this compile unit. - DWARFTypeUnit *getTypeUnitAtIndex(unsigned index) { - if (TUs.empty()) - parseTypeUnits(); - return TUs[index]; + /// Get the compile unit at the specified index for this compile unit. + DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { + parseCompileUnits(); + return CUs[index].get(); } /// Get the compile unit at the specified index for the DWO compile units. DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) { - if (DWOCUs.empty()) - parseDWOCompileUnits(); - return DWOCUs[index]; + parseDWOCompileUnits(); + return DWOCUs[index].get(); } /// Get a pointer to the parsed DebugAbbrev object. @@ -118,6 +149,9 @@ public: /// Get a pointer to the parsed dwo abbreviations object. const DWARFDebugAbbrev *getDebugAbbrevDWO(); + /// Get a pointer to the parsed DebugLoc object. + const DWARFDebugLocDWO *getDebugLocDWO(); + /// Get a pointer to the parsed DebugAranges object. const DWARFDebugAranges *getDebugAranges(); @@ -128,22 +162,26 @@ public: const DWARFDebugLine::LineTable * getLineTableForCompileUnit(DWARFCompileUnit *cu); - virtual DILineInfo getLineInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier = DILineInfoSpecifier()); - virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address, - uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()); - virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier = DILineInfoSpecifier()); + DILineInfo getLineInfoForAddress(uint64_t Address, + DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; + DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, + DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; + DIInliningInfo getInliningInfoForAddress(uint64_t Address, + DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; virtual bool isLittleEndian() const = 0; virtual uint8_t getAddressSize() const = 0; virtual const Section &getInfoSection() = 0; - virtual const std::map<object::SectionRef, Section> &getTypesSections() = 0; + typedef MapVector<object::SectionRef, Section, + std::map<object::SectionRef, unsigned> > TypeSectionMap; + virtual const TypeSectionMap &getTypesSections() = 0; virtual StringRef getAbbrevSection() = 0; virtual const Section &getLocSection() = 0; + virtual const Section &getLocDWOSection() = 0; virtual StringRef getARangeSection() = 0; virtual StringRef getDebugFrameSection() = 0; virtual const Section &getLineSection() = 0; + virtual const Section &getLineDWOSection() = 0; virtual StringRef getStringSection() = 0; virtual StringRef getRangeSection() = 0; virtual StringRef getPubNamesSection() = 0; @@ -153,6 +191,7 @@ public: // Sections for DWARF5 split dwarf proposal. virtual const Section &getInfoDWOSection() = 0; + virtual const TypeSectionMap &getTypesDWOSections() = 0; virtual StringRef getAbbrevDWOSection() = 0; virtual StringRef getStringDWOSection() = 0; virtual StringRef getStringOffsetDWOSection() = 0; @@ -179,12 +218,14 @@ class DWARFContextInMemory : public DWARFContext { bool IsLittleEndian; uint8_t AddressSize; Section InfoSection; - std::map<object::SectionRef, Section> TypesSections; + TypeSectionMap TypesSections; StringRef AbbrevSection; Section LocSection; + Section LocDWOSection; StringRef ARangeSection; StringRef DebugFrameSection; Section LineSection; + Section LineDWOSection; StringRef StringSection; StringRef RangeSection; StringRef PubNamesSection; @@ -194,44 +235,47 @@ class DWARFContextInMemory : public DWARFContext { // Sections for DWARF5 split dwarf proposal. Section InfoDWOSection; + TypeSectionMap TypesDWOSections; StringRef AbbrevDWOSection; StringRef StringDWOSection; StringRef StringOffsetDWOSection; StringRef RangeDWOSection; StringRef AddrSection; - SmallVector<MemoryBuffer*, 4> UncompressedSections; + SmallVector<std::unique_ptr<MemoryBuffer>, 4> UncompressedSections; public: DWARFContextInMemory(object::ObjectFile *); - ~DWARFContextInMemory(); - virtual bool isLittleEndian() const { return IsLittleEndian; } - virtual uint8_t getAddressSize() const { return AddressSize; } - virtual const Section &getInfoSection() { return InfoSection; } - virtual const std::map<object::SectionRef, Section> &getTypesSections() { - return TypesSections; - } - virtual StringRef getAbbrevSection() { return AbbrevSection; } - virtual const Section &getLocSection() { return LocSection; } - virtual StringRef getARangeSection() { return ARangeSection; } - virtual StringRef getDebugFrameSection() { return DebugFrameSection; } - virtual const Section &getLineSection() { return LineSection; } - virtual StringRef getStringSection() { return StringSection; } - virtual StringRef getRangeSection() { return RangeSection; } - virtual StringRef getPubNamesSection() { return PubNamesSection; } - virtual StringRef getPubTypesSection() { return PubTypesSection; } - virtual StringRef getGnuPubNamesSection() { return GnuPubNamesSection; } - virtual StringRef getGnuPubTypesSection() { return GnuPubTypesSection; } + bool isLittleEndian() const override { return IsLittleEndian; } + uint8_t getAddressSize() const override { return AddressSize; } + const Section &getInfoSection() override { return InfoSection; } + const TypeSectionMap &getTypesSections() override { return TypesSections; } + StringRef getAbbrevSection() override { return AbbrevSection; } + const Section &getLocSection() override { return LocSection; } + const Section &getLocDWOSection() override { return LocDWOSection; } + StringRef getARangeSection() override { return ARangeSection; } + StringRef getDebugFrameSection() override { return DebugFrameSection; } + const Section &getLineSection() override { return LineSection; } + const Section &getLineDWOSection() override { return LineDWOSection; } + StringRef getStringSection() override { return StringSection; } + StringRef getRangeSection() override { return RangeSection; } + StringRef getPubNamesSection() override { return PubNamesSection; } + StringRef getPubTypesSection() override { return PubTypesSection; } + StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; } + StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; } // Sections for DWARF5 split dwarf proposal. - virtual const Section &getInfoDWOSection() { return InfoDWOSection; } - virtual StringRef getAbbrevDWOSection() { return AbbrevDWOSection; } - virtual StringRef getStringDWOSection() { return StringDWOSection; } - virtual StringRef getStringOffsetDWOSection() { + const Section &getInfoDWOSection() override { return InfoDWOSection; } + const TypeSectionMap &getTypesDWOSections() override { + return TypesDWOSections; + } + StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; } + StringRef getStringDWOSection() override { return StringDWOSection; } + StringRef getStringOffsetDWOSection() override { return StringOffsetDWOSection; } - virtual StringRef getRangeDWOSection() { return RangeDWOSection; } - virtual StringRef getAddrSection() { + StringRef getRangeDWOSection() override { return RangeDWOSection; } + StringRef getAddrSection() override { return AddrSection; } }; diff --git a/lib/DebugInfo/DWARFDebugAbbrev.cpp b/lib/DebugInfo/DWARFDebugAbbrev.cpp index 6e6c37e309..fd5f5e95fc 100644 --- a/lib/DebugInfo/DWARFDebugAbbrev.cpp +++ b/lib/DebugInfo/DWARFDebugAbbrev.cpp @@ -33,19 +33,17 @@ bool DWARFAbbreviationDeclarationSet::extract(DataExtractor data, } void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const { - for (unsigned i = 0, e = Decls.size(); i != e; ++i) - Decls[i].dump(OS); + for (const auto &Decl : Decls) + Decl.dump(OS); } const DWARFAbbreviationDeclaration* DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(uint32_t abbrCode) const { if (IdxOffset == UINT32_MAX) { - DWARFAbbreviationDeclarationCollConstIter pos; - DWARFAbbreviationDeclarationCollConstIter end = Decls.end(); - for (pos = Decls.begin(); pos != end; ++pos) { - if (pos->getCode() == abbrCode) - return &(*pos); + for (const auto &Decl : Decls) { + if (Decl.getCode() == abbrCode) + return &Decl; } } else { uint32_t idx = abbrCode - IdxOffset; @@ -81,10 +79,9 @@ void DWARFDebugAbbrev::dump(raw_ostream &OS) const { return; } - DWARFAbbreviationDeclarationCollMapConstIter pos; - for (pos = AbbrevCollMap.begin(); pos != AbbrevCollMap.end(); ++pos) { - OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", pos->first); - pos->second.dump(OS); + for (const auto &I : AbbrevCollMap) { + OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first); + I.second.dump(OS); } } diff --git a/lib/DebugInfo/DWARFDebugArangeSet.cpp b/lib/DebugInfo/DWARFDebugArangeSet.cpp index 229376e4a1..c0a33ceaf2 100644 --- a/lib/DebugInfo/DWARFDebugArangeSet.cpp +++ b/lib/DebugInfo/DWARFDebugArangeSet.cpp @@ -67,7 +67,9 @@ DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) { Descriptor arangeDescriptor; - assert(sizeof(arangeDescriptor.Address) == sizeof(arangeDescriptor.Length)); + static_assert(sizeof(arangeDescriptor.Address) == + sizeof(arangeDescriptor.Length), + "Different datatypes for addresses and sizes!"); assert(sizeof(arangeDescriptor.Address) >= HeaderData.AddrSize); while (data.isValidOffset(*offset_ptr)) { @@ -94,9 +96,9 @@ void DWARFDebugArangeSet::dump(raw_ostream &OS) const { HeaderData.CuOffset, HeaderData.AddrSize, HeaderData.SegSize); const uint32_t hex_width = HeaderData.AddrSize * 2; - for (DescriptorConstIter pos = ArangeDescriptors.begin(), - end = ArangeDescriptors.end(); pos != end; ++pos) - OS << format("[0x%*.*" PRIx64 " -", hex_width, hex_width, pos->Address) + for (const auto &Desc : ArangeDescriptors) { + OS << format("[0x%*.*" PRIx64 " -", hex_width, hex_width, Desc.Address) << format(" 0x%*.*" PRIx64 ")\n", - hex_width, hex_width, pos->getEndAddress()); + hex_width, hex_width, Desc.getEndAddress()); + } } diff --git a/lib/DebugInfo/DWARFDebugArangeSet.h b/lib/DebugInfo/DWARFDebugArangeSet.h index 49a713201d..c18b3c5e50 100644 --- a/lib/DebugInfo/DWARFDebugArangeSet.h +++ b/lib/DebugInfo/DWARFDebugArangeSet.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H #define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/DataExtractor.h" #include <vector> @@ -44,7 +45,7 @@ public: private: typedef std::vector<Descriptor> DescriptorColl; - typedef DescriptorColl::const_iterator DescriptorConstIter; + typedef iterator_range<DescriptorColl::const_iterator> desc_iterator_range; uint32_t Offset; Header HeaderData; @@ -57,12 +58,12 @@ public: void dump(raw_ostream &OS) const; uint32_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; } - uint32_t getNumDescriptors() const { return ArangeDescriptors.size(); } - const Descriptor *getDescriptor(uint32_t i) const { - if (i < ArangeDescriptors.size()) - return &ArangeDescriptors[i]; - return NULL; + + desc_iterator_range descriptors() const { + return desc_iterator_range(ArangeDescriptors.begin(), + ArangeDescriptors.end()); } + uint32_t getNumDescriptors() const { return ArangeDescriptors.size(); } }; } diff --git a/lib/DebugInfo/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARFDebugAranges.cpp index 591d4bde71..dfab7886b5 100644 --- a/lib/DebugInfo/DWARFDebugAranges.cpp +++ b/lib/DebugInfo/DWARFDebugAranges.cpp @@ -33,15 +33,12 @@ void DWARFDebugAranges::extract(DataExtractor DebugArangesData) { return; Aranges.reserve(TotalRanges); - for (RangeSetColl::const_iterator I = Sets.begin(), E = Sets.end(); I != E; - ++I) { - uint32_t CUOffset = I->getCompileUnitDIEOffset(); - - for (uint32_t i = 0, n = I->getNumDescriptors(); i < n; ++i) { - const DWARFDebugArangeSet::Descriptor *ArangeDescPtr = - I->getDescriptor(i); - uint64_t LowPC = ArangeDescPtr->Address; - uint64_t HighPC = LowPC + ArangeDescPtr->Length; + for (const auto &I : Sets) { + uint32_t CUOffset = I.getCompileUnitDIEOffset(); + + for (const auto &Desc : I.descriptors()) { + uint64_t LowPC = Desc.Address; + uint64_t HighPC = Desc.getEndAddress(); appendRange(CUOffset, LowPC, HighPC); } } @@ -59,12 +56,10 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) { // Generate aranges from DIEs: even if .debug_aranges section is present, // it may describe only a small subset of compilation units, so we need to // manually build aranges for the rest of them. - for (uint32_t i = 0, n = CTX->getNumCompileUnits(); i < n; ++i) { - if (DWARFCompileUnit *CU = CTX->getCompileUnitAtIndex(i)) { - uint32_t CUOffset = CU->getOffset(); - if (ParsedCUOffsets.insert(CUOffset).second) - CU->buildAddressRangeTable(this, true, CUOffset); - } + for (const auto &CU : CTX->compile_units()) { + uint32_t CUOffset = CU->getOffset(); + if (ParsedCUOffsets.insert(CUOffset).second) + CU->buildAddressRangeTable(this, true, CUOffset); } sortAndMinimize(); diff --git a/lib/DebugInfo/DWARFDebugFrame.cpp b/lib/DebugInfo/DWARFDebugFrame.cpp index 3efe6a1ebd..5bf7b070b8 100644 --- a/lib/DebugInfo/DWARFDebugFrame.cpp +++ b/lib/DebugInfo/DWARFDebugFrame.cpp @@ -10,8 +10,8 @@ #include "DWARFDebugFrame.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/DataTypes.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <string> @@ -125,6 +125,7 @@ void FrameEntry::parseInstructions(uint32_t *Offset, uint32_t EndOffset) { case DW_CFA_nop: case DW_CFA_remember_state: case DW_CFA_restore_state: + case DW_CFA_GNU_window_save: // No operands addInstruction(Opcode); break; @@ -185,10 +186,8 @@ void FrameEntry::parseInstructions(uint32_t *Offset, uint32_t EndOffset) { void FrameEntry::dumpInstructions(raw_ostream &OS) const { // TODO: at the moment only instruction names are dumped. Expand this to // dump operands as well. - for (std::vector<Instruction>::const_iterator I = Instructions.begin(), - E = Instructions.end(); - I != E; ++I) { - uint8_t Opcode = I->Opcode; + for (const auto &Instr : Instructions) { + uint8_t Opcode = Instr.Opcode; if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK; OS << " " << CallFrameString(Opcode) << ":\n"; @@ -213,7 +212,7 @@ public: ~CIE() { } - void dumpHeader(raw_ostream &OS) const { + void dumpHeader(raw_ostream &OS) const override { OS << format("%08x %08x %08x CIE", (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID) << "\n"; @@ -257,7 +256,7 @@ public: ~FDE() { } - void dumpHeader(raw_ostream &OS) const { + void dumpHeader(raw_ostream &OS) const override { OS << format("%08x %08x %08x FDE ", (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset); OS << format("cie=%08x pc=%08x...%08x\n", @@ -288,9 +287,8 @@ DWARFDebugFrame::DWARFDebugFrame() { DWARFDebugFrame::~DWARFDebugFrame() { - for (EntryVector::iterator I = Entries.begin(), E = Entries.end(); - I != E; ++I) { - delete *I; + for (const auto &Entry : Entries) { + delete Entry; } } @@ -380,9 +378,7 @@ void DWARFDebugFrame::parse(DataExtractor Data) { void DWARFDebugFrame::dump(raw_ostream &OS) const { OS << "\n"; - for (EntryVector::const_iterator I = Entries.begin(), E = Entries.end(); - I != E; ++I) { - FrameEntry *Entry = *I; + for (const auto &Entry : Entries) { Entry->dumpHeader(OS); Entry->dumpInstructions(OS); OS << "\n"; diff --git a/lib/DebugInfo/DWARFDebugFrame.h b/lib/DebugInfo/DWARFDebugFrame.h index 48b8d63a5a..7683849b4a 100644 --- a/lib/DebugInfo/DWARFDebugFrame.h +++ b/lib/DebugInfo/DWARFDebugFrame.h @@ -42,5 +42,4 @@ private: } // namespace llvm -#endif - +#endif diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp index babfd2ece0..bde25ec82d 100644 --- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -40,11 +40,8 @@ void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, AbbrevDecl->hasChildren() ? '*' : ' '); // Dump all data in the DIE for the attributes. - const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); - for (uint32_t i = 0; i != numAttributes; ++i) { - uint16_t attr = AbbrevDecl->getAttrByIndex(i); - uint16_t form = AbbrevDecl->getFormByIndex(i); - dumpAttribute(OS, u, &offset, attr, form, indent); + for (const auto &AttrSpec : AbbrevDecl->attributes()) { + dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent); } const DWARFDebugInfoEntryMinimal *child = getFirstChild(); @@ -116,8 +113,8 @@ bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U, assert(FixedFormSizes.size() > 0); // Skip all data in the .debug_info for the attributes - for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) { - uint16_t Form = AbbrevDecl->getFormByIndex(i); + for (const auto &AttrSpec : AbbrevDecl->attributes()) { + uint16_t Form = AttrSpec.Form; uint8_t FixedFormSize = (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0; diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.h b/lib/DebugInfo/DWARFDebugInfoEntry.h index aa61056332..f30e531045 100644 --- a/lib/DebugInfo/DWARFDebugInfoEntry.h +++ b/lib/DebugInfo/DWARFDebugInfoEntry.h @@ -60,9 +60,6 @@ public: bool isSubroutineDIE() const; uint32_t getOffset() const { return Offset; } - uint32_t getNumAttributes() const { - return !isNULL() ? AbbrevDecl->getNumAttributes() : 0; - } bool hasChildren() const { return !isNULL() && AbbrevDecl->hasChildren(); } // We know we are kept in a vector of contiguous entries, so we know diff --git a/lib/DebugInfo/DWARFDebugLine.cpp b/lib/DebugInfo/DWARFDebugLine.cpp index 13d09dd298..43d976480c 100644 --- a/lib/DebugInfo/DWARFDebugLine.cpp +++ b/lib/DebugInfo/DWARFDebugLine.cpp @@ -18,14 +18,15 @@ using namespace dwarf; void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { OS << "Line table prologue:\n" - << format(" total_length: 0x%8.8x\n", TotalLength) - << format(" version: %u\n", Version) - << format("prologue_length: 0x%8.8x\n", PrologueLength) - << format("min_inst_length: %u\n", MinInstLength) - << format("default_is_stmt: %u\n", DefaultIsStmt) - << format(" line_base: %i\n", LineBase) - << format(" line_range: %u\n", LineRange) - << format(" opcode_base: %u\n", OpcodeBase); + << format(" total_length: 0x%8.8x\n", TotalLength) + << format(" version: %u\n", Version) + << format(" prologue_length: 0x%8.8x\n", PrologueLength) + << format(" min_inst_length: %u\n", MinInstLength) + << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst) + << format(" default_is_stmt: %u\n", DefaultIsStmt) + << format(" line_base: %i\n", LineBase) + << format(" line_range: %u\n", LineRange) + << format(" opcode_base: %u\n", OpcodeBase); for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i) OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i+1), @@ -62,6 +63,7 @@ void DWARFDebugLine::Row::reset(bool default_is_stmt) { Column = 0; File = 1; Isa = 0; + Discriminator = 0; IsStmt = default_is_stmt; BasicBlock = false; EndSequence = false; @@ -71,7 +73,7 @@ void DWARFDebugLine::Row::reset(bool default_is_stmt) { void DWARFDebugLine::Row::dump(raw_ostream &OS) const { OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column) - << format(" %6u %3u ", File, Isa) + << format(" %6u %3u %13u ", File, Isa, Discriminator) << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "") << (PrologueEnd ? " prologue_end" : "") @@ -85,11 +87,12 @@ void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { OS << '\n'; if (!Rows.empty()) { - OS << "Address Line Column File ISA Flags\n" - << "------------------ ------ ------ ------ --- -------------\n"; - for (std::vector<Row>::const_iterator pos = Rows.begin(), - end = Rows.end(); pos != end; ++pos) - pos->dump(OS); + OS << "Address Line Column File ISA Discriminator Flags\n" + << "------------------ ------ ------ ------ --- ------------- " + "-------------\n"; + for (const Row &R : Rows) { + R.dump(OS); + } } } @@ -170,12 +173,14 @@ DWARFDebugLine::parsePrologue(DataExtractor debug_line_data, prologue->clear(); prologue->TotalLength = debug_line_data.getU32(offset_ptr); prologue->Version = debug_line_data.getU16(offset_ptr); - if (prologue->Version != 2) + if (prologue->Version < 2) return false; prologue->PrologueLength = debug_line_data.getU32(offset_ptr); const uint32_t end_prologue_offset = prologue->PrologueLength + *offset_ptr; prologue->MinInstLength = debug_line_data.getU8(offset_ptr); + if (prologue->Version >= 4) + prologue->MaxOpsPerInst = debug_line_data.getU8(offset_ptr); prologue->DefaultIsStmt = debug_line_data.getU8(offset_ptr); prologue->LineBase = debug_line_data.getU8(offset_ptr); prologue->LineRange = debug_line_data.getU8(offset_ptr); @@ -218,10 +223,9 @@ DWARFDebugLine::parsePrologue(DataExtractor debug_line_data, return true; } -bool -DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, - const RelocAddrMap *RMap, - uint32_t *offset_ptr, State &state) { +bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, + const RelocAddrMap *RMap, + uint32_t *offset_ptr, State &state) { const uint32_t debug_line_offset = *offset_ptr; Prologue *prologue = &state.Prologue; @@ -311,6 +315,10 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, } break; + case DW_LNE_set_discriminator: + state.Discriminator = debug_line_data.getULEB128(offset_ptr); + break; + default: // Length doesn't include the zero opcode byte or the length itself, but // it does include the sub_opcode, so we have to adjust for that below diff --git a/lib/DebugInfo/DWARFDebugLine.h b/lib/DebugInfo/DWARFDebugLine.h index 2990756bd7..a336f49b29 100644 --- a/lib/DebugInfo/DWARFDebugLine.h +++ b/lib/DebugInfo/DWARFDebugLine.h @@ -34,8 +34,9 @@ public: struct Prologue { Prologue() - : TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0), - DefaultIsStmt(0), LineBase(0), LineRange(0), OpcodeBase(0) {} + : TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0), + MaxOpsPerInst(0), DefaultIsStmt(0), LineBase(0), LineRange(0), + OpcodeBase(0) {} // The size in bytes of the statement information for this compilation unit // (not including the total_length field itself). @@ -49,6 +50,9 @@ public: // program opcodes that alter the address register first multiply their // operands by this value. uint8_t MinInstLength; + // The maximum number of individual operations that may be encoded in an + // instruction. + uint8_t MaxOpsPerInst; // The initial value of theis_stmtregister. uint8_t DefaultIsStmt; // This parameter affects the meaning of the special opcodes. See below. @@ -112,6 +116,9 @@ public: // An unsigned integer whose value encodes the applicable instruction set // architecture for the current instruction. uint8_t Isa; + // An unsigned integer representing the DWARF path discriminator value + // for this location. + uint32_t Discriminator; // A boolean indicating that the current instruction is the beginning of a // statement. uint8_t IsStmt:1, @@ -224,7 +231,7 @@ public: struct DumpingState : public State { DumpingState(raw_ostream &OS) : OS(OS) {} virtual ~DumpingState(); - virtual void finalize(); + void finalize() override; private: raw_ostream &OS; }; diff --git a/lib/DebugInfo/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARFDebugLoc.cpp index 3895ffa8d7..e4aa5dcce2 100644 --- a/lib/DebugInfo/DWARFDebugLoc.cpp +++ b/lib/DebugInfo/DWARFDebugLoc.cpp @@ -11,23 +11,24 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Dwarf.h" using namespace llvm; void DWARFDebugLoc::dump(raw_ostream &OS) const { - for (LocationLists::const_iterator I = Locations.begin(), E = Locations.end(); I != E; ++I) { - OS << format("0x%8.8x: ", I->Offset); + for (const LocationList &L : Locations) { + OS << format("0x%8.8x: ", L.Offset); const unsigned Indent = 12; - for (SmallVectorImpl<Entry>::const_iterator I2 = I->Entries.begin(), E2 = I->Entries.end(); I2 != E2; ++I2) { - if (I2 != I->Entries.begin()) + for (const Entry &E : L.Entries) { + if (&E != L.Entries.begin()) OS.indent(Indent); - OS << "Beginning address offset: " << format("0x%016" PRIx64, I2->Begin) + OS << "Beginning address offset: " << format("0x%016" PRIx64, E.Begin) << '\n'; OS.indent(Indent) << " Ending address offset: " - << format("0x%016" PRIx64, I2->End) << '\n'; + << format("0x%016" PRIx64, E.End) << '\n'; OS.indent(Indent) << " Location description: "; - for (SmallVectorImpl<unsigned char>::const_iterator I3 = I2->Loc.begin(), E3 = I2->Loc.end(); I3 != E3; ++I3) { - OS << format("%2.2x ", *I3); + for (unsigned char Loc : E.Loc) { + OS << format("%2.2x ", Loc); } OS << "\n\n"; } @@ -36,7 +37,7 @@ void DWARFDebugLoc::dump(raw_ostream &OS) const { void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) { uint32_t Offset = 0; - while (data.isValidOffset(Offset)) { + while (data.isValidOffset(Offset+AddressSize-1)) { Locations.resize(Locations.size() + 1); LocationList &Loc = Locations.back(); Loc.Offset = Offset; @@ -68,7 +69,60 @@ void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) { Offset += Bytes; E.Loc.reserve(str.size()); std::copy(str.begin(), str.end(), std::back_inserter(E.Loc)); - Loc.Entries.push_back(llvm_move(E)); + Loc.Entries.push_back(std::move(E)); } } + if (data.isValidOffset(Offset)) + llvm::errs() << "error: failed to consume entire .debug_loc section\n"; } + +void DWARFDebugLocDWO::parse(DataExtractor data) { + uint32_t Offset = 0; + while (data.isValidOffset(Offset)) { + Locations.resize(Locations.size() + 1); + LocationList &Loc = Locations.back(); + Loc.Offset = Offset; + dwarf::LocationListEntry Kind; + while ((Kind = static_cast<dwarf::LocationListEntry>( + data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list_entry) { + + if (Kind != dwarf::DW_LLE_start_length_entry) { + llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind + << " not implemented\n"; + return; + } + + Entry E; + + E.Start = data.getULEB128(&Offset); + E.Length = data.getU32(&Offset); + + unsigned Bytes = data.getU16(&Offset); + // A single location description describing the location of the object... + StringRef str = data.getData().substr(Offset, Bytes); + Offset += Bytes; + E.Loc.resize(str.size()); + std::copy(str.begin(), str.end(), E.Loc.begin()); + + Loc.Entries.push_back(std::move(E)); + } + } +} + +void DWARFDebugLocDWO::dump(raw_ostream &OS) const { + for (const LocationList &L : Locations) { + OS << format("0x%8.8x: ", L.Offset); + const unsigned Indent = 12; + for (const Entry &E : L.Entries) { + if (&E != L.Entries.begin()) + OS.indent(Indent); + OS << "Beginning address index: " << E.Start << '\n'; + OS.indent(Indent) << " Length: " << E.Length << '\n'; + OS.indent(Indent) << " Location description: "; + for (unsigned char Loc : E.Loc) + OS << format("%2.2x ", Loc); + OS << "\n\n"; + } + } +} + diff --git a/lib/DebugInfo/DWARFDebugLoc.h b/lib/DebugInfo/DWARFDebugLoc.h index d31aaaa127..663acbb42f 100644 --- a/lib/DebugInfo/DWARFDebugLoc.h +++ b/lib/DebugInfo/DWARFDebugLoc.h @@ -55,6 +55,27 @@ public: /// specified address size to interpret the address ranges. void parse(DataExtractor data, unsigned AddressSize); }; + +class DWARFDebugLocDWO { + struct Entry { + uint64_t Start; + uint32_t Length; + SmallVector<unsigned char, 4> Loc; + }; + + struct LocationList { + unsigned Offset; + SmallVector<Entry, 2> Entries; + }; + + typedef SmallVector<LocationList, 4> LocationLists; + + LocationLists Locations; + +public: + void parse(DataExtractor data); + void dump(raw_ostream &OS) const; +}; } #endif diff --git a/lib/DebugInfo/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARFDebugRangeList.cpp index 1806beee72..aa2a2be599 100644 --- a/lib/DebugInfo/DWARFDebugRangeList.cpp +++ b/lib/DebugInfo/DWARFDebugRangeList.cpp @@ -45,22 +45,21 @@ bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) { } void DWARFDebugRangeList::dump(raw_ostream &OS) const { - for (int i = 0, n = Entries.size(); i != n; ++i) { + for (const RangeListEntry &RLE : Entries) { const char *format_str = (AddressSize == 4 ? "%08x %08" PRIx64 " %08" PRIx64 "\n" : "%08x %016" PRIx64 " %016" PRIx64 "\n"); - OS << format(format_str, Offset, Entries[i].StartAddress, - Entries[i].EndAddress); + OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress); } OS << format("%08x <End of list>\n", Offset); } bool DWARFDebugRangeList::containsAddress(uint64_t BaseAddress, uint64_t Address) const { - for (int i = 0, n = Entries.size(); i != n; ++i) { - if (Entries[i].isBaseAddressSelectionEntry(AddressSize)) - BaseAddress = Entries[i].EndAddress; - else if (Entries[i].containsAddress(BaseAddress, Address)) + for (const RangeListEntry &RLE : Entries) { + if (RLE.isBaseAddressSelectionEntry(AddressSize)) + BaseAddress = RLE.EndAddress; + else if (RLE.containsAddress(BaseAddress, Address)) return true; } return false; diff --git a/lib/DebugInfo/DWARFTypeUnit.h b/lib/DebugInfo/DWARFTypeUnit.h index 7a0dab204d..05e13ff104 100644 --- a/lib/DebugInfo/DWARFTypeUnit.h +++ b/lib/DebugInfo/DWARFTypeUnit.h @@ -23,10 +23,10 @@ public: StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, const RelocAddrMap *M, bool LE) : DWARFUnit(DA, IS, AS, RS, SS, SOS, AOS, M, LE) {} - uint32_t getSize() const LLVM_OVERRIDE { return DWARFUnit::getSize() + 12; } + uint32_t getSize() const override { return DWARFUnit::getSize() + 12; } void dump(raw_ostream &OS); protected: - bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) LLVM_OVERRIDE; + bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) override; }; } diff --git a/lib/DebugInfo/DWARFUnit.cpp b/lib/DebugInfo/DWARFUnit.cpp index 5167eb947c..316c208479 100644 --- a/lib/DebugInfo/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARFUnit.cpp @@ -263,12 +263,12 @@ bool DWARFUnit::parseDWO() { sys::path::append(AbsolutePath, CompilationDir); } sys::path::append(AbsolutePath, DWOFileName); - object::ObjectFile *DWOFile = + ErrorOr<object::ObjectFile *> DWOFile = object::ObjectFile::createObjectFile(AbsolutePath); if (!DWOFile) return false; // Reset DWOHolder. - DWO.reset(new DWOHolder(DWOFile)); + DWO.reset(new DWOHolder(DWOFile.get())); DWARFUnit *DWOCU = DWO->getUnit(); // Verify that compile unit in .dwo file is valid. if (DWOCU == 0 || DWOCU->getDWOId() != getDWOId()) { @@ -331,11 +331,12 @@ DWARFUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges, const DWARFDebugInfoEntryMinimal * DWARFUnit::getSubprogramForAddress(uint64_t Address) { extractDIEsIfNeeded(false); - for (size_t i = 0, n = DieArray.size(); i != n; i++) - if (DieArray[i].isSubprogramDIE() && - DieArray[i].addressRangeContainsAddress(this, Address)) { - return &DieArray[i]; + for (const DWARFDebugInfoEntryMinimal &DIE : DieArray) { + if (DIE.isSubprogramDIE() && + DIE.addressRangeContainsAddress(this, Address)) { + return &DIE; } + } return 0; } diff --git a/lib/DebugInfo/DWARFUnit.h b/lib/DebugInfo/DWARFUnit.h index bd768a6bce..5b4cf0905b 100644 --- a/lib/DebugInfo/DWARFUnit.h +++ b/lib/DebugInfo/DWARFUnit.h @@ -10,7 +10,6 @@ #ifndef LLVM_DEBUGINFO_DWARFUNIT_H #define LLVM_DEBUGINFO_DWARFUNIT_H -#include "llvm/ADT/OwningPtr.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugInfoEntry.h" #include "DWARFDebugRangeList.h" @@ -50,14 +49,14 @@ class DWARFUnit { std::vector<DWARFDebugInfoEntryMinimal> DieArray; class DWOHolder { - OwningPtr<object::ObjectFile> DWOFile; - OwningPtr<DWARFContext> DWOContext; + std::unique_ptr<object::ObjectFile> DWOFile; + std::unique_ptr<DWARFContext> DWOContext; DWARFUnit *DWOU; public: DWOHolder(object::ObjectFile *DWOFile); DWARFUnit *getUnit() const { return DWOU; } }; - OwningPtr<DWOHolder> DWO; + std::unique_ptr<DWOHolder> DWO; protected: virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr); |