diff options
-rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h | 11 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCObjectFileInfo.h | 4 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectFileInfo.cpp | 12 | ||||
-rw-r--r-- | llvm/test/tools/llvm-dwp/X86/simple.test | 13 | ||||
-rw-r--r-- | llvm/tools/llvm-dwp/llvm-dwp.cpp | 103 |
7 files changed, 128 insertions, 43 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h index 83da6fef441..a85c2f9f0a2 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h @@ -41,12 +41,15 @@ class DWARFUnitIndex { public: class Entry { - const DWARFUnitIndex *Index; - uint64_t Signature; + public: struct SectionContribution { uint32_t Offset; uint32_t Length; }; + + private: + const DWARFUnitIndex *Index; + uint64_t Signature; std::unique_ptr<SectionContribution[]> Contributions; friend class DWARFUnitIndex; @@ -58,14 +61,18 @@ public: private: struct Header Header; + DWARFSectionKind InfoColumnKind; int InfoColumn = -1; std::unique_ptr<DWARFSectionKind[]> ColumnKinds; std::unique_ptr<Entry[]> Rows; static StringRef getColumnHeader(DWARFSectionKind DS); + bool parseImpl(DataExtractor IndexData); public: bool parse(DataExtractor IndexData); + DWARFUnitIndex(DWARFSectionKind InfoColumnKind) + : InfoColumnKind(InfoColumnKind) {} void dump(raw_ostream &OS) const; const Entry *getFromOffset(uint32_t Offset) const; }; diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h index eaca3833dc8..388a208fb4a 100644 --- a/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -116,6 +116,9 @@ protected: MCSection *DwarfStrOffDWOSection; MCSection *DwarfAddrSection; + // These are for Fission DWP files. + MCSection *DwarfCUIndexSection; + /// Section for newer gnu pubnames. MCSection *DwarfGnuPubNamesSection; /// Section for newer gnu pubtypes. @@ -262,6 +265,7 @@ public: MCSection *getDwarfLocDWOSection() const { return DwarfLocDWOSection; } MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; } MCSection *getDwarfAddrSection() const { return DwarfAddrSection; } + MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; } MCSection *getCOFFDebugSymbolsSection() const { return COFFDebugSymbolsSection; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 2165d353ba0..a4195b75c47 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -163,20 +163,12 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) { OS << "\n.debug_cu_index contents:\n"; - DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), - savedAddressByteSize); - DWARFUnitIndex CUIndex; - if (CUIndex.parse(CUIndexData)) - CUIndex.dump(OS); + getCUIndex().dump(OS); } if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) { OS << "\n.debug_tu_index contents:\n"; - DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), - savedAddressByteSize); - DWARFUnitIndex TUIndex; - if (TUIndex.parse(TUIndexData)) - TUIndex.dump(OS); + getTUIndex().dump(OS); } if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) { @@ -280,7 +272,7 @@ const DWARFUnitIndex &DWARFContext::getCUIndex() { DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0); - CUIndex = llvm::make_unique<DWARFUnitIndex>(); + CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO); CUIndex->parse(CUIndexData); return *CUIndex; } @@ -291,7 +283,7 @@ const DWARFUnitIndex &DWARFContext::getTUIndex() { DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0); - TUIndex = llvm::make_unique<DWARFUnitIndex>(); + TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES); TUIndex->parse(TUIndexData); return *TUIndex; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp index baefed30f36..e8e7441d976 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp @@ -30,6 +30,13 @@ void DWARFUnitIndex::Header::dump(raw_ostream &OS) const { } bool DWARFUnitIndex::parse(DataExtractor IndexData) { + bool b = parseImpl(IndexData); + if (!b) + *this = DWARFUnitIndex(InfoColumnKind); + return b; +} + +bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) { uint32_t Offset = 0; if (!Header.parse(IndexData, &Offset)) return false; @@ -62,7 +69,7 @@ bool DWARFUnitIndex::parse(DataExtractor IndexData) { // Read the Column Headers for (unsigned i = 0; i != Header.NumColumns; ++i) { ColumnKinds[i] = static_cast<DWARFSectionKind>(IndexData.getU32(&Offset)); - if (ColumnKinds[i] == DW_SECT_INFO || ColumnKinds[i] == DW_SECT_TYPES) { + if (ColumnKinds[i] == InfoColumnKind) { if (InfoColumn != -1) return false; InfoColumn = i; @@ -107,6 +114,9 @@ StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) { } void DWARFUnitIndex::dump(raw_ostream &OS) const { + if (!Header.NumBuckets) + return; + Header.dump(OS); OS << "Index Signature "; for (unsigned i = 0; i != Header.NumColumns; ++i) diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index 8b75457a246..41e28698b1c 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -259,6 +259,9 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) { DwarfDebugInlineSection = Ctx->getMachOSection("__DWARF", "__debug_inlined", MachO::S_ATTR_DEBUG, SectionKind::getMetadata()); + DwarfCUIndexSection = + Ctx->getMachOSection("__DWARF", "__debug_cu_index", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); StackMapSection = Ctx->getMachOSection("__LLVM_STACKMAPS", "__llvm_stackmaps", 0, SectionKind::getMetadata()); @@ -531,6 +534,10 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) { DwarfAddrSection = Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, "addr_sec"); + // DWP Sections + DwarfCUIndexSection = + Ctx->getELFSection(".debug_cu_index", ELF::SHT_PROGBITS, 0); + StackMapSection = Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); @@ -713,6 +720,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) { COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getMetadata(), "addr_sec"); + DwarfCUIndexSection = Ctx->getCOFFSection( + ".debug_cu_index", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); DwarfAccelNamesSection = Ctx->getCOFFSection( ".apple_names", COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | diff --git a/llvm/test/tools/llvm-dwp/X86/simple.test b/llvm/test/tools/llvm-dwp/X86/simple.test index 754450f13f3..aa5ae40dc2b 100644 --- a/llvm/test/tools/llvm-dwp/X86/simple.test +++ b/llvm/test/tools/llvm-dwp/X86/simple.test @@ -33,12 +33,13 @@ CHECK: DW_AT_name {{.*}} "a" CHECK: DW_TAG_structure_type CHECK: DW_AT_name {{.*}} "foo" -FIXME: Using cu_index, identify that abbr_offset is 0x0031, not 0x0000 -CHECK: 0x00000029: Compile Unit: length = 0x00000031 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x0000005e) -FIXME: Using cu_index, use strings based on the right str index offset -CHECK: DW_AT_name {{.*}} "a.cpp" -FIXME: Using cu_index to find the right abbrevs at abbr_offset, this abbrevation should actually be structure_type -CHECK: DW_TAG_variable +CHECK: 0x00000029: Compile Unit: length = 0x00000031 version = 0x0004 abbr_offset = 0x0031 addr_size = 0x08 (next unit at 0x0000005e) +CHECK: DW_AT_name {{.*}} "b.cpp" +CHECK: DW_TAG_structure_type +CHECK: DW_AT_name {{.*}} "bar" +CHECK: DW_TAG_subprogram +CHECK: DW_AT_name {{.*}} "b" +CHECK: DW_TAG_formal_parameter CHECK: .debug_cu_index contents: FIXME: Emit and verify the cu_index contents diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp index 9ce37ec2cee..6617b0b23ae 100644 --- a/llvm/tools/llvm-dwp/llvm-dwp.cpp +++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp @@ -17,6 +17,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include <memory> #include <list> #include <unordered_set> @@ -85,48 +86,106 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) { const auto &MCOFI = *Out.getContext().getObjectFileInfo(); MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection(); - const StringMap<MCSection *> KnownSections = { - {"debug_info.dwo", MCOFI.getDwarfInfoDWOSection()}, - {"debug_types.dwo", MCOFI.getDwarfTypesDWOSection()}, - {"debug_str_offsets.dwo", StrOffsetSection}, - {"debug_str.dwo", StrSection}, - {"debug_loc.dwo", MCOFI.getDwarfLocDWOSection()}, - {"debug_abbrev.dwo", MCOFI.getDwarfAbbrevDWOSection()}}; + const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = { + {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}}, + {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}}, + {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}}, + {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}}, + {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}}, + {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}}; + + struct UnitIndexEntry { + uint64_t Signature; + DWARFUnitIndex::Entry::SectionContribution Contributions[8]; + }; + + std::vector<UnitIndexEntry> IndexEntries; StringMap<uint32_t> Strings; uint32_t StringOffset = 0; + uint64_t UnitIndex = 0; + uint32_t ContributionOffsets[8] = {}; + for (const auto &Input : Inputs) { auto ErrOrObj = object::ObjectFile::createObjectFile(Input); if (!ErrOrObj) return ErrOrObj.getError(); - const auto *Obj = ErrOrObj->getBinary(); + + IndexEntries.emplace_back(); + UnitIndexEntry &CurEntry = IndexEntries.back(); + CurEntry.Signature = UnitIndex++; + StringRef CurStrSection; StringRef CurStrOffsetSection; - for (const auto &Section : Obj->sections()) { + + for (const auto &Section : ErrOrObj->getBinary()->sections()) { StringRef Name; if (std::error_code Err = Section.getName(Name)) return Err; - if (MCSection *OutSection = - KnownSections.lookup(Name.substr(Name.find_first_not_of("._")))) { - StringRef Contents; - if (auto Err = Section.getContents(Contents)) - return Err; - if (OutSection == StrOffsetSection) - CurStrOffsetSection = Contents; - else if (OutSection == StrSection) - CurStrSection = Contents; - else { - Out.SwitchSection(OutSection); - Out.EmitBytes(Contents); - } + + auto SectionPair = + KnownSections.find(Name.substr(Name.find_first_not_of("._"))); + if (SectionPair == KnownSections.end()) + continue; + + StringRef Contents; + if (auto Err = Section.getContents(Contents)) + return Err; + + if (DWARFSectionKind Kind = SectionPair->second.second) { + auto Index = Kind - DW_SECT_INFO; + CurEntry.Contributions[Index].Offset = ContributionOffsets[Index]; + ContributionOffsets[Index] += + (CurEntry.Contributions[Index].Length = Contents.size()); + } + + MCSection *OutSection = SectionPair->second.first; + if (OutSection == StrOffsetSection) + CurStrOffsetSection = Contents; + else if (OutSection == StrSection) + CurStrSection = Contents; + else { + Out.SwitchSection(OutSection); + Out.EmitBytes(Contents); } } + if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset, StrSection, StrOffsetSection, CurStrSection, CurStrOffsetSection)) return Err; } + + Out.SwitchSection(MCOFI.getDwarfCUIndexSection()); + Out.EmitIntValue(2, 4); // Version + Out.EmitIntValue(8, 4); // Columns + Out.EmitIntValue(IndexEntries.size(), 4); // Num Units + // FIXME: This is not the right number of buckets for a real hash. + Out.EmitIntValue(IndexEntries.size(), 4); // Num Buckets + + // Write the signatures. + for (const auto &E : IndexEntries) + Out.EmitIntValue(E.Signature, 8); + + // Write the indexes. + for (size_t i = 0; i != IndexEntries.size(); ++i) + Out.EmitIntValue(i + 1, 4); + + // Write the column headers (which sections will appear in the table) + for (size_t i = 1; i != 9; ++i) + Out.EmitIntValue(i, 4); + + // Write the offsets. + for (const auto &E : IndexEntries) + for (const auto &C : E.Contributions) + Out.EmitIntValue(C.Offset, 4); + + // Write the lengths. + for (const auto &E : IndexEntries) + for (const auto &C : E.Contributions) + Out.EmitIntValue(C.Length, 4); + return std::error_code(); } |