X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FDebugInfo%2FDWARFContext.cpp;h=b725619d8e2528f16def360a984676717979a480;hb=27276437ae2169640633f9961620a8d0b19deb39;hp=76eec3da5f07c675bf6b2b30500e4e40a09db3cf;hpb=d374c7b3bf49a62a722b52367f122ca7fd53ab08;p=oota-llvm.git diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 76eec3da5f0..b725619d8e2 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// #include "DWARFContext.h" +#include "llvm/ADT/STLExtras.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" @@ -25,28 +25,38 @@ 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 LittleEndian, bool GnuStyle) { OS << "\n." << Name << " contents:\n"; DataExtractor pubNames(Data, LittleEndian, 0); uint32_t offset = 0; - OS << "Length: " << pubNames.getU32(&offset) << "\n"; - OS << "Version: " << pubNames.getU16(&offset) << "\n"; - OS << "Offset in .debug_info: " << pubNames.getU32(&offset) << "\n"; - OS << "Size: " << pubNames.getU32(&offset) << "\n"; - OS << "Offset Linkage Kind Name\n"; - while (offset < Data.size()) { - uint32_t dieRef = pubNames.getU32(&offset); - if (dieRef == 0) - break; - PubIndexEntryDescriptor desc(pubNames.getU8(&offset)); - OS << format("0x%8.8x ", dieRef) - << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage)) << ' ' - << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind)) - << pubNames.getCStr(&offset) << "\"\n"; + 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"; + } } } @@ -56,18 +66,38 @@ 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); } - if (DumpType == DIDT_All || DumpType == DIDT_Types) { + if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) && + 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_Types) && getNumTypeUnits()) { OS << "\n.debug_types contents:\n"; for (unsigned i = 0, e = getNumTypeUnits(); i != e; ++i) getTypeUnitAtIndex(i)->dump(OS); } + if (DumpType == DIDT_All || DumpType == DIDT_TypesDwo) + if (getNumDWOTypeUnits()) { + OS << "\n.debug_types.dwo contents:\n"; + for (unsigned i = 0, e = getNumDWOTypeUnits(); i != e; ++i) + getDWOTypeUnitAtIndex(i)->dump(OS); + } + if (DumpType == DIDT_All || DumpType == DIDT_Loc) { OS << "\n.debug_loc contents:\n"; getDebugLoc()->dump(OS); @@ -94,8 +124,8 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { DWARFCompileUnit *cu = getCompileUnitAtIndex(i); savedAddressByteSize = cu->getAddressByteSize(); unsigned stmtOffset = - cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list, - -1U); + cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset( + cu, DW_AT_stmt_list, -1U); if (stmtOffset != -1U) { DataExtractor lineData(getLineSection().Data, isLittleEndian(), savedAddressByteSize); @@ -116,6 +146,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 @@ -130,70 +172,34 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { rangeList.dump(OS); } - if (DumpType == DIDT_All || DumpType == DIDT_Pubnames) { - OS << "\n.debug_pubnames contents:\n"; - DataExtractor pubNames(getPubNamesSection(), isLittleEndian(), 0); - offset = 0; - OS << "Length: " << pubNames.getU32(&offset) << "\n"; - OS << "Version: " << pubNames.getU16(&offset) << "\n"; - OS << "Offset in .debug_info: " << pubNames.getU32(&offset) << "\n"; - OS << "Size: " << pubNames.getU32(&offset) << "\n"; - OS << "\n Offset Name\n"; - while (offset < getPubNamesSection().size()) { - uint32_t n = pubNames.getU32(&offset); - if (n == 0) - break; - OS << format("%8x ", n); - OS << pubNames.getCStr(&offset) << "\n"; - } - } + if (DumpType == DIDT_All || DumpType == DIDT_Pubnames) + dumpPubSection(OS, "debug_pubnames", getPubNamesSection(), + isLittleEndian(), false); + + if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes) + dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(), + isLittleEndian(), false); if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames) dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(), - isLittleEndian()); + isLittleEndian(), true /* GnuStyle */); if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes) dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(), - isLittleEndian()); + 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() { @@ -233,13 +239,7 @@ const DWARFDebugAranges *DWARFContext::getDebugAranges() { if (Aranges) return Aranges.get(); - DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0); - Aranges.reset(new DWARFDebugAranges()); - Aranges->extract(arangesData); - // 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. Aranges->generate(this); return Aranges.get(); } @@ -270,8 +270,8 @@ DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) { Line.reset(new DWARFDebugLine(&getLineSection().Relocs)); unsigned stmtOffset = - cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list, - -1U); + cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset( + cu, DW_AT_stmt_list, -1U); if (stmtOffset == -1U) return 0; // No line table for this compile unit. @@ -303,10 +303,8 @@ void DWARFContext::parseCompileUnits() { } void DWARFContext::parseTypeUnits() { - const std::map &Sections = getTypesSections(); - for (std::map::const_iterator - I = Sections.begin(), - E = Sections.end(); + const TypeSectionMap &Sections = getTypesSections(); + for (TypeSectionMap::const_iterator I = Sections.begin(), E = Sections.end(); I != E; ++I) { uint32_t offset = 0; const DataExtractor &DIData = @@ -342,6 +340,27 @@ void DWARFContext::parseDWOCompileUnits() { } } +void DWARFContext::parseDWOTypeUnits() { + const TypeSectionMap &Sections = getTypesDWOSections(); + for (TypeSectionMap::const_iterator I = Sections.begin(), E = Sections.end(); + I != E; ++I) { + uint32_t offset = 0; + const DataExtractor &DIData = + DataExtractor(I->second.Data, isLittleEndian(), 0); + while (DIData.isValidOffset(offset)) { + OwningPtr 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(TU.take()); + offset = DWOTUs.back()->getNextUnitOffset(); + } + } +} + namespace { struct OffsetComparator { bool operator()(const DWARFCompileUnit *LHS, @@ -610,25 +629,27 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : UncompressedSections.push_back(UncompressedSection.take()); } - StringRef *Section = StringSwitch(name) - .Case("debug_info", &InfoSection.Data) - .Case("debug_abbrev", &AbbrevSection) - .Case("debug_loc", &LocSection.Data) - .Case("debug_line", &LineSection.Data) - .Case("debug_aranges", &ARangeSection) - .Case("debug_frame", &DebugFrameSection) - .Case("debug_str", &StringSection) - .Case("debug_ranges", &RangeSection) - .Case("debug_pubnames", &PubNamesSection) - .Case("debug_gnu_pubnames", &GnuPubNamesSection) - .Case("debug_gnu_pubtypes", &GnuPubTypesSection) - .Case("debug_info.dwo", &InfoDWOSection.Data) - .Case("debug_abbrev.dwo", &AbbrevDWOSection) - .Case("debug_str.dwo", &StringDWOSection) - .Case("debug_str_offsets.dwo", &StringOffsetDWOSection) - .Case("debug_addr", &AddrSection) - // Any more debug info sections go here. - .Default(0); + StringRef *Section = + StringSwitch(name) + .Case("debug_info", &InfoSection.Data) + .Case("debug_abbrev", &AbbrevSection) + .Case("debug_loc", &LocSection.Data) + .Case("debug_line", &LineSection.Data) + .Case("debug_aranges", &ARangeSection) + .Case("debug_frame", &DebugFrameSection) + .Case("debug_str", &StringSection) + .Case("debug_ranges", &RangeSection) + .Case("debug_pubnames", &PubNamesSection) + .Case("debug_pubtypes", &PubTypesSection) + .Case("debug_gnu_pubnames", &GnuPubNamesSection) + .Case("debug_gnu_pubtypes", &GnuPubTypesSection) + .Case("debug_info.dwo", &InfoDWOSection.Data) + .Case("debug_abbrev.dwo", &AbbrevDWOSection) + .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 (name == "debug_ranges") { @@ -639,6 +660,8 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : // Find debug_types data by section rather than name as there are // multiple, comdat grouped, debug_types sections. TypesSections[*i].Data = data; + } else if (name == "debug_types.dwo") { + TypesDWOSections[*i].Data = data; } section_iterator RelocatedSection = i->getRelocatedSection(); @@ -659,11 +682,14 @@ 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()) {