From 543e02b4381244c28463696f159170004c787628 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Sat, 5 Dec 2015 03:05:45 +0000 Subject: [PATCH] [llvm-dwp] Support debug_tu_index git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254827 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCObjectFileInfo.h | 2 + lib/MC/MCObjectFileInfo.cpp | 10 ++ test/tools/llvm-dwp/Inputs/simple/a.dwo | Bin 1193 -> 1369 bytes test/tools/llvm-dwp/Inputs/simple/b.dwo | Bin 1241 -> 1409 bytes test/tools/llvm-dwp/X86/simple.test | 51 ++++++-- tools/llvm-dwp/llvm-dwp.cpp | 163 ++++++++++++++++-------- 6 files changed, 160 insertions(+), 66 deletions(-) diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 388a208fb4a..cf2c3f12bb6 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -118,6 +118,7 @@ protected: // These are for Fission DWP files. MCSection *DwarfCUIndexSection; + MCSection *DwarfTUIndexSection; /// Section for newer gnu pubnames. MCSection *DwarfGnuPubNamesSection; @@ -266,6 +267,7 @@ public: MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; } MCSection *getDwarfAddrSection() const { return DwarfAddrSection; } MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; } + MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; } MCSection *getCOFFDebugSymbolsSection() const { return COFFDebugSymbolsSection; diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index 41e28698b1c..dbedd73a432 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -262,6 +262,9 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) { DwarfCUIndexSection = Ctx->getMachOSection("__DWARF", "__debug_cu_index", MachO::S_ATTR_DEBUG, SectionKind::getMetadata()); + DwarfTUIndexSection = + Ctx->getMachOSection("__DWARF", "__debug_tu_index", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); StackMapSection = Ctx->getMachOSection("__LLVM_STACKMAPS", "__llvm_stackmaps", 0, SectionKind::getMetadata()); @@ -537,6 +540,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) { // DWP Sections DwarfCUIndexSection = Ctx->getELFSection(".debug_cu_index", ELF::SHT_PROGBITS, 0); + DwarfTUIndexSection = + Ctx->getELFSection(".debug_tu_index", ELF::SHT_PROGBITS, 0); StackMapSection = Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); @@ -725,6 +730,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) { COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getMetadata()); + DwarfTUIndexSection = Ctx->getCOFFSection( + ".debug_tu_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/test/tools/llvm-dwp/Inputs/simple/a.dwo b/test/tools/llvm-dwp/Inputs/simple/a.dwo index 7bdb2a7b9f826e0dfcbafb94b64ef9285b42f4c6..1fc71ca8d17560f4ce433262fedc9bcb4fc14a2f 100644 GIT binary patch delta 328 zcmZ388{}|hxlj$xh!BI4n`n@kt5*BqcHZv%uGzmKv6~} zrr!+Af0A#>JUUQn!JvRp3=@-s39&G+PTa0#W+RyiRK?=RC?GD(%D})X%)s1a$IWfU zZOsi-DF(z$3<5xsk?}VlBSWHIazO!*H}Ovve#j`#SUCA0qd4aih!BG_SgaW=rVjO_)MQ0wb52JnZ}Q|sW^>UQ5HB(u lfa>D{(j1f5GHbI&03FEy)Gs{w1M^M^Ae)(i9jXY40suf}IPw4h delta 204 zcmcb~wUTp!hIj)b0~|PjSq=0@DFV`5}vWMC9zRBf^oW@T=&+vvp3z`!KTU?Z8SF!7_h z0jndUfVePFHJdO4P@0?DirbnSs8tMznHU6sBqQT*K1PNlz2t%dAaAk;VT#m;uP-=C &TypeIndexEntries, + uint32_t OutTypesOffset, StringRef Types, + const UnitIndexEntry &CUEntry) { + uint32_t Offset = 0; + DataExtractor Data(Types, true, 0); + while (Data.isValidOffset(Offset)) { + TypeIndexEntries.push_back(CUEntry); + auto &Entry = TypeIndexEntries.back(); + // Zero out the debug_info contribution + Entry.Contributions[0] = {}; + auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO]; + C.Offset = OutTypesOffset + Offset; + auto PrevOffset = Offset; + // Length of the unit, including the 4 byte length field. + C.Length = Data.getU32(&Offset) + 4; + + Data.getU16(&Offset); // Version + Data.getU32(&Offset); // Abbrev offset + Data.getU8(&Offset); // Address size + Entry.Signature = Data.getU64(&Offset); + Offset = PrevOffset + C.Length; + } +} + +static void +writeIndexTable(MCStreamer &Out, ArrayRef ContributionOffsets, + ArrayRef IndexEntries, + uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field) { + for (const auto &E : IndexEntries) + for (size_t i = 0; i != array_lengthof(E.Contributions); ++i) + if (ContributionOffsets[i]) + Out.EmitIntValue(E.Contributions[i].*Field, 4); +} + +static void writeIndex(MCStreamer &Out, MCSection *Section, + ArrayRef ContributionOffsets, + ArrayRef IndexEntries) { + unsigned Columns = 0; + for (auto &C : ContributionOffsets) + if (C) + ++Columns; + + std::vector Buckets(NextPowerOf2(3 * IndexEntries.size() / 2)); + uint64_t Mask = Buckets.size() - 1; + for (size_t i = 0; i != IndexEntries.size(); ++i) { + auto S = IndexEntries[i].Signature; + auto H = S & Mask; + while (Buckets[H]) + H += ((S >> 32) & Mask) | 1; + Buckets[H] = i + 1; + } + + Out.SwitchSection(Section); + Out.EmitIntValue(2, 4); // Version + Out.EmitIntValue(Columns, 4); // Columns + Out.EmitIntValue(IndexEntries.size(), 4); // Num Units + Out.EmitIntValue(Buckets.size(), 4); // Num Buckets + + // Write the signatures. + for (const auto &I : Buckets) + Out.EmitIntValue(I ? IndexEntries[I - 1].Signature : 0, 8); + + // Write the indexes. + for (const auto &I : Buckets) + Out.EmitIntValue(I, 4); + + // Write the column headers (which sections will appear in the table) + for (size_t i = 0; i != ContributionOffsets.size(); ++i) + if (ContributionOffsets[i]) + Out.EmitIntValue(i + DW_SECT_INFO, 4); + + // Write the offsets. + writeIndexTable(Out, ContributionOffsets, IndexEntries, + &DWARFUnitIndex::Entry::SectionContribution::Offset); + + // Write the lengths. + writeIndexTable(Out, ContributionOffsets, IndexEntries, + &DWARFUnitIndex::Entry::SectionContribution::Length); +} static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { const auto &MCOFI = *Out.getContext().getObjectFileInfo(); MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); @@ -143,12 +227,8 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}}, {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}}; - struct UnitIndexEntry { - uint64_t Signature; - DWARFUnitIndex::Entry::SectionContribution Contributions[8]; - }; - std::vector IndexEntries; + std::vector TypeIndexEntries; StringMap Strings; uint32_t StringOffset = 0; @@ -167,6 +247,9 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { StringRef CurStrOffsetSection; StringRef InfoSection; StringRef AbbrevSection; + StringRef TypesSection; + + auto TypesOffset = ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]; for (const auto &Section : ErrOrObj->getBinary()->sections()) { StringRef Name; @@ -188,12 +271,18 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { ContributionOffsets[Index] += (CurEntry.Contributions[Index].Length = Contents.size()); - if (Kind == DW_SECT_INFO) { - assert(InfoSection.empty()); + switch (Kind) { + case DW_SECT_INFO: InfoSection = Contents; - } else if (Kind == DW_SECT_ABBREV) { - assert(AbbrevSection.empty()); + break; + case DW_SECT_ABBREV: AbbrevSection = Contents; + break; + case DW_SECT_TYPES: + TypesSection = Contents; + break; + default: + break; } } @@ -211,6 +300,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { assert(!AbbrevSection.empty()); assert(!InfoSection.empty()); CurEntry.Signature = getCUSignature(AbbrevSection, InfoSection); + addAllTypes(TypeIndexEntries, TypesOffset, TypesSection, CurEntry); if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset, StrSection, StrOffsetSection, @@ -218,52 +308,19 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { return Err; } - unsigned Columns = 0; - for (auto &C : ContributionOffsets) - if (C) - ++Columns; - - std::vector Buckets(NextPowerOf2(3 * IndexEntries.size() / 2)); - uint64_t Mask = Buckets.size() - 1; - for (size_t i = 0; i != IndexEntries.size(); ++i) { - auto S = IndexEntries[i].Signature; - auto H = S & Mask; - while (Buckets[H]) - H += ((S >> 32) & Mask) | 1; - Buckets[H] = i + 1; - } + // Lie about there being no info contributions so the TU index only includes + // the type unit contribution + ContributionOffsets[0] = 0; + writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets, + TypeIndexEntries); - Out.SwitchSection(MCOFI.getDwarfCUIndexSection()); - Out.EmitIntValue(2, 4); // Version - Out.EmitIntValue(Columns, 4); // Columns - Out.EmitIntValue(IndexEntries.size(), 4); // Num Units - // FIXME: This is not the right number of buckets for a real hash. - Out.EmitIntValue(Buckets.size(), 4); // Num Buckets + // Lie about the type contribution + ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO] = 0; + // Unlie about the info contribution + ContributionOffsets[0] = 1; - // Write the signatures. - for (const auto &I : Buckets) - Out.EmitIntValue(I ? IndexEntries[I - 1].Signature : 0, 8); - - // Write the indexes. - for (const auto &I : Buckets) - Out.EmitIntValue(I, 4); - - // Write the column headers (which sections will appear in the table) - for (size_t i = 0; i != array_lengthof(ContributionOffsets); ++i) - if (ContributionOffsets[i]) - Out.EmitIntValue(i + DW_SECT_INFO, 4); - - // Write the offsets. - for (const auto &E : IndexEntries) - for (size_t i = 0; i != array_lengthof(E.Contributions); ++i) - if (ContributionOffsets[i]) - Out.EmitIntValue(E.Contributions[i].Offset, 4); - - // Write the lengths. - for (const auto &E : IndexEntries) - for (size_t i = 0; i != array_lengthof(E.Contributions); ++i) - if (ContributionOffsets[i]) - Out.EmitIntValue(E.Contributions[i].Length, 4); + writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets, + IndexEntries); return std::error_code(); } -- 2.34.1