From: David Blaikie Date: Sat, 5 Dec 2015 03:05:45 +0000 (+0000) Subject: [llvm-dwp] Support debug_tu_index X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=543e02b4381244c28463696f159170004c787628;p=oota-llvm.git [llvm-dwp] Support debug_tu_index git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254827 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 7bdb2a7b9f8..1fc71ca8d17 100644 Binary files a/test/tools/llvm-dwp/Inputs/simple/a.dwo and b/test/tools/llvm-dwp/Inputs/simple/a.dwo differ diff --git a/test/tools/llvm-dwp/Inputs/simple/b.dwo b/test/tools/llvm-dwp/Inputs/simple/b.dwo index f41243dc722..a69cd69eb99 100644 Binary files a/test/tools/llvm-dwp/Inputs/simple/b.dwo and b/test/tools/llvm-dwp/Inputs/simple/b.dwo differ diff --git a/test/tools/llvm-dwp/X86/simple.test b/test/tools/llvm-dwp/X86/simple.test index 5cc62633468..5502ef23d29 100644 --- a/test/tools/llvm-dwp/X86/simple.test +++ b/test/tools/llvm-dwp/X86/simple.test @@ -13,48 +13,73 @@ b.cpp: void b(bar) { } -CHECK: .debug_abbrev.dwo contents: -CHECK: Abbrev table for offset: 0x00000000 +CHECK-LABEL: .debug_abbrev.dwo contents: +CHECK-LABEL: Abbrev table for offset: +CHECK: 0x0000[[AAOFF:.*]] CHECK: DW_TAG_compile_unit CHECK: DW_TAG_variable CHECK: DW_TAG_structure_type -CHECK: Abbrev table for offset: 0x00000031 +CHECK-LABEL: Abbrev table for offset: +CHECK: 0x0000[[BAOFF:.*]] CHECK: DW_TAG_compile_unit CHECK: DW_TAG_structure_type CHECK: DW_TAG_subprogram CHECK: DW_TAG_formal_parameter CHECK: .debug_info.dwo contents: -CHECK: 0x00000000: Compile Unit: length = 0x00000025 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000029) +CHECK: [[AOFF:0x[0-9a-f]*]]: +CHECK-LABEL: Compile Unit: length = 0x00000029 version = 0x0004 abbr_offset = +CHECK: 0x[[AAOFF]] addr_size = 0x08 (next unit at [[BOFF:.*]]) CHECK: DW_TAG_compile_unit CHECK: DW_AT_name {{.*}} "a.cpp" CHECK: DW_AT_GNU_dwo_id {{.*}} ([[DWOA:.*]]) CHECK: DW_TAG_variable CHECK: DW_AT_name {{.*}} "a" CHECK: DW_TAG_structure_type -CHECK: DW_AT_name {{.*}} "foo" +CHECK: DW_AT_signature {{.*}} ([[FOOSIG:.*]]) -CHECK: 0x00000029: Compile Unit: length = 0x00000031 version = 0x0004 abbr_offset = 0x0031 addr_size = 0x08 (next unit at 0x0000005e) +CHECK: [[BOFF]]: +CHECK-LABEL: Compile Unit: length = 0x00000035 version = 0x0004 abbr_offset = +CHECK: 0x[[BAOFF]] addr_size = 0x08 (next unit at [[XOFF:.*]]) CHECK: DW_AT_name {{.*}} "b.cpp" CHECK: DW_AT_GNU_dwo_id {{.*}} ([[DWOB:.*]]) CHECK: DW_TAG_structure_type -CHECK: DW_AT_name {{.*}} "bar" +CHECK: DW_AT_signature {{.*}} ([[BARSIG:.*]]) CHECK: DW_TAG_subprogram CHECK: DW_AT_name {{.*}} "b" CHECK: DW_TAG_formal_parameter -CHECK: .debug_cu_index contents: -CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS -CHECK: 3 [[DWOA]] [0x00000000, 0x00000029) [0x00000000, 0x00000031) [0x00000000, 0x00000011) [0x00000000, 0x00000010) -CHECK: 4 [[DWOB]] [0x00000029, 0x0000005e) [0x00000031, 0x00000075) [0x00000011, 0x00000022) [0x00000010, 0x00000024) +CHECK-LABEL: .debug_types.dwo contents: +CHECK: [[FOOUOFF:0x[0-9a-f]*]]: +CHECK-LABEL: Type Unit: length = 0x00000020 version = 0x0004 abbr_offset = +CHECK: 0x[[AAOFF]] addr_size = 0x08 type_signature = [[FOOSIG]] type_offset = 0x[[FOOOFF:.*]] (next unit at [[BARUOFF:.*]]) +CHECK: DW_TAG_type_unit +CHECK: [[FOOOFF]]: DW_TAG_structure_type +CHECK: DW_AT_name {{.*}} "foo" +CHECK: [[BARUOFF]]: +CHECK-LABEL: Type Unit: length = 0x00000020 version = 0x0004 abbr_offset = +CHECK: 0x[[BAOFF]] addr_size = 0x08 type_signature = [[BARSIG]] type_offset = 0x001e (next unit at [[XUOFF:.*]]) +CHECK: DW_TAG_type_unit +CHECK: 0x00000042: DW_TAG_structure_type +CHECK: DW_AT_name {{.*}} "bar" -CHECK: .debug_str.dwo contents: +CHECK-LABEL: .debug_cu_index contents: +CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS +CHECK: 1 [[DWOA]] {{\[}}[[AOFF]], [[BOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x0000001a) [0x00000000, 0x00000010) +CHECK: 3 [[DWOB]] {{\[}}[[BOFF]], [[XOFF]]) [0x0000[[BAOFF]], 0x00000099) [0x0000001a, 0x00000034) [0x00000010, 0x00000024) + +CHECK-LABEL: .debug_tu_index contents: +CHECK: Index Signature TYPES ABBREV LINE STR_OFFSETS +CHECK: 1 [[FOOSIG]] {{\[}}[[FOOUOFF]], [[BARUOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x0000001a) [0x00000000, 0x00000010) +CHECK: 4 [[BARSIG]] {{\[}}[[BARUOFF]], [[XUOFF]]) [0x0000[[BAOFF]], 0x00000099) [0x0000001a, 0x00000034) [0x00000010, 0x00000024) + +CHECK-LABEL: .debug_str.dwo contents: CHECK: "clang version CHECK: 0x[[ACPP:.*]]: "a.cpp" CHECK-NOT: "clang version CHECK: 0x[[BCPP:.*]]: "b.cpp" -CHECK: .debug_str_offsets.dwo contents: +CHECK-LABEL: .debug_str_offsets.dwo contents: CHECK: : 00000000 CHECK: : [[ACPP]] CHECK: : 00000000 diff --git a/tools/llvm-dwp/llvm-dwp.cpp b/tools/llvm-dwp/llvm-dwp.cpp index b4aaea3b238..608eca152d9 100644 --- a/tools/llvm-dwp/llvm-dwp.cpp +++ b/tools/llvm-dwp/llvm-dwp.cpp @@ -130,6 +130,90 @@ static uint64_t getCUSignature(StringRef Abbrev, StringRef Info) { return InfoData.getU64(&Offset); } +struct UnitIndexEntry { + uint64_t Signature; + DWARFUnitIndex::Entry::SectionContribution Contributions[8]; +}; + +static void addAllTypes(std::vector &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(); }