X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FDebugInfo%2FDWARFContext.cpp;h=9dc8f149933d4db53be5439f1dac5e884364c97e;hb=66589dcc8fb5dcf0894a9a80a8dee890a4f3a379;hp=075d8cddc0d26c77ab7d04990691b81416fa76c0;hpb=9528b0e466ace36268abe9d011fffc67d831088c;p=oota-llvm.git diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 075d8cddc0d..9dc8f149933 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -25,9 +25,39 @@ 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: " << 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"; + 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"; + } +} + void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) { OS << ".debug_abbrev contents:\n"; @@ -40,8 +70,14 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { getCompileUnitAtIndex(i)->dump(OS); } + if (DumpType == DIDT_All || DumpType == DIDT_Types) { + 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_Loc) { - OS << ".debug_loc contents:\n"; + OS << "\n.debug_loc contents:\n"; getDebugLoc()->dump(OS); } @@ -102,44 +138,21 @@ 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_GnuPubnames) { - OS << "\n.debug_gnu_pubnames contents:\n"; - DataExtractor pubNames(getGnuPubNamesSection(), 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 << "Offset Linkage Kind Name\n"; - while (offset < getGnuPubNamesSection().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)) - << ' ' << dwarf::GDBIndexEntryKindString(desc.Kind) << " \"" - << pubNames.getCStr(&offset) << "\"\n"; - } - } + 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(), true /* GnuStyle */); + + if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes) + dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(), + isLittleEndian(), true /* GnuStyle */); if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) { const DWARFDebugAbbrev *D = getDebugAbbrevDWO(); @@ -218,13 +231,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(); } @@ -283,7 +290,29 @@ void DWARFContext::parseCompileUnits() { break; } CUs.push_back(CU.take()); - offset = CUs.back()->getNextCompileUnitOffset(); + offset = CUs.back()->getNextUnitOffset(); + } +} + +void DWARFContext::parseTypeUnits() { + const std::map &Sections = getTypesSections(); + for (std::map::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( + getDebugAbbrev(), I->second.Data, getAbbrevSection(), + getRangeSection(), getStringSection(), StringRef(), getAddrSection(), + &I->second.Relocs, isLittleEndian())); + if (!TU->extract(DIData, &offset)) + break; + TUs.push_back(TU.take()); + offset = TUs.back()->getNextUnitOffset(); + } } } @@ -301,7 +330,7 @@ void DWARFContext::parseDWOCompileUnits() { break; } DWOCUs.push_back(DWOCU.take()); - offset = DWOCUs.back()->getNextCompileUnitOffset(); + offset = DWOCUs.back()->getNextUnitOffset(); } } @@ -400,7 +429,7 @@ DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, CU->getInlinedChainForAddress(Address); if (InlinedChain.DIEs.size() > 0) { const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; - if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.CU)) + if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) FunctionName = Name; } } @@ -433,7 +462,7 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, CU->getInlinedChainForAddress(Address); if (InlinedChain.DIEs.size() > 0) { const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; - if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.CU)) + if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) FunctionName = Name; } } @@ -492,7 +521,7 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, uint32_t Column = 0; // Get function name if necessary. if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.CU)) + if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U)) FunctionName = Name; } if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { @@ -516,7 +545,7 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, } // Get call file/line/column of a current DIE. if (i + 1 < n) { - FunctionDIE.getCallerFrame(InlinedChain.CU, CallFile, CallLine, + FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine, CallColumn); } } @@ -573,30 +602,37 @@ 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_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") { // FIXME: Use the other dwo range section when we emit it. RangeDWOSection = data; } + } 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; } section_iterator RelocatedSection = i->getRelocatedSection(); @@ -616,8 +652,13 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : .Case("debug_info.dwo", &InfoDWOSection.Relocs) .Case("debug_line", &LineSection.Relocs) .Default(0); - if (!Map) - continue; + 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 (i->begin_relocations() != i->end_relocations()) { uint64_t SectionSize;