Index: llvm/test/tools/dsymutil/X86/accelerator.test =================================================================== --- /dev/null +++ llvm/test/tools/dsymutil/X86/accelerator.test @@ -0,0 +1,38 @@ +RUN: dsymutil -accelerator=Dwarf -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 -o %t.dwarf.dSYM +RUN: dsymutil -accelerator=Apple -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 -o %t.apple.dSYM + +RUN: llvm-dwarfdump -verify %t.dwarf.dSYM +RUN: llvm-dwarfdump -verify %t.apple.dSYM + +RUN: llvm-dwarfdump -debug-names %t.dwarf.dSYM | FileCheck %s -check-prefix=NAMES -check-prefix=DWARF +RUN: llvm-dwarfdump -apple-names -apple-namespaces -apple-types %t.apple.dSYM | FileCheck %s -check-prefix=NAMES -check-prefix=APPLE + +RUN: dsymutil -update -accelerator=Dwarf %t.apple.dSYM -o %t.dwarf.updated.dSYM +RUN: dsymutil -update -accelerator=Apple %t.dwarf.dSYM -o %t.apple.updated.dSYM + +RUN: llvm-dwarfdump -verify %t.dwarf.updated.dSYM +RUN: llvm-dwarfdump -verify %t.apple.updated.dSYM + +RUN: llvm-dwarfdump -debug-names %t.dwarf.updated.dSYM | FileCheck %s -check-prefix=NAMES -check-prefix=DWARF +RUN: llvm-dwarfdump -apple-names -apple-namespaces -apple-types %t.apple.updated.dSYM | FileCheck %s -check-prefix=NAMES -check-prefix=APPLE + +DWARF: .debug_names contents: +DWARF: Compilation Unit offsets [ +DWARF: CU[0] +DWARF: CU[1] +DWARF: CU[2] +DWARF: ] + +APPLE-DAG: .apple_names contents: +APPLE-DAG: .apple_types contents: +APPLE-DAG: .apple_namespaces contents: + +NAMES-DAG: "private_int" +NAMES-DAG: "baz" +NAMES-DAG: "int" +NAMES-DAG: "bar" +NAMES-DAG: "foo" +NAMES-DAG: "inc" +NAMES-DAG: "val" +NAMES-DAG: "main" +NAMES-DAG: "char" Index: llvm/test/tools/dsymutil/cmdline.test =================================================================== --- llvm/test/tools/dsymutil/cmdline.test +++ llvm/test/tools/dsymutil/cmdline.test @@ -5,6 +5,7 @@ HELP: Color Options HELP: -color HELP: Specific Options: +HELP: -accelerator HELP: -arch= HELP: -dump-debug-map HELP: -flat Index: llvm/tools/dsymutil/DwarfLinker.h =================================================================== --- llvm/tools/dsymutil/DwarfLinker.h +++ llvm/tools/dsymutil/DwarfLinker.h @@ -411,6 +411,8 @@ /// Emit the accelerator entries for \p Unit. void emitAcceleratorEntriesForUnit(CompileUnit &Unit); + void emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit); + void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit); /// Patch the frame info for an object file and emit it. void patchFrameInfoForObject(const DebugMapObject &, RangesTy &Ranges, @@ -461,6 +463,7 @@ uint32_t LastCIEOffset = 0; /// Apple accelerator tables. + AccelTable DebugNames; AccelTable AppleNames; AccelTable AppleNamespaces; AccelTable AppleObjc; Index: llvm/tools/dsymutil/DwarfLinker.cpp =================================================================== --- llvm/tools/dsymutil/DwarfLinker.cpp +++ llvm/tools/dsymutil/DwarfLinker.cpp @@ -1746,6 +1746,17 @@ } void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) { + switch (Options.TheAccelTableKind) { + case AccelTableKind::Apple: + emitAppleAcceleratorEntriesForUnit(Unit); + break; + case AccelTableKind::Dwarf: + emitDwarfAcceleratorEntriesForUnit(Unit); + break; + } +} + +void DwarfLinker::emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit) { // Add namespaces. for (const auto &Namespace : Unit.getNamespaces()) AppleNamespaces.addName(Namespace.Name, @@ -1774,6 +1785,18 @@ AppleObjc.addName(ObjC.Name, ObjC.Die->getOffset() + Unit.getStartOffset()); } +void DwarfLinker::emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit) { + for (const auto &Namespace : Unit.getNamespaces()) + DebugNames.addName(Namespace.Name, Namespace.Die->getOffset(), + Namespace.Die->getTag(), Unit.getUniqueID()); + for (const auto &Pubname : Unit.getPubnames()) + DebugNames.addName(Pubname.Name, Pubname.Die->getOffset(), + Pubname.Die->getTag(), Unit.getUniqueID()); + for (const auto &Pubtype : Unit.getPubtypes()) + DebugNames.addName(Pubtype.Name, Pubtype.Die->getOffset(), + Pubtype.Die->getTag(), Unit.getUniqueID()); +} + /// Read the frame info stored in the object, and emit the /// patched frame descriptions for the linked binary. /// @@ -2444,10 +2467,17 @@ if (!Options.NoOutput) { Streamer->emitAbbrevs(Abbreviations, MaxDwarfVersion); Streamer->emitStrings(OffsetsStringPool); - Streamer->emitAppleNames(AppleNames); - Streamer->emitAppleNamespaces(AppleNamespaces); - Streamer->emitAppleTypes(AppleTypes); - Streamer->emitAppleObjc(AppleObjc); + switch (Options.TheAccelTableKind) { + case AccelTableKind::Apple: + Streamer->emitAppleNames(AppleNames); + Streamer->emitAppleNamespaces(AppleNamespaces); + Streamer->emitAppleTypes(AppleTypes); + Streamer->emitAppleObjc(AppleObjc); + break; + case AccelTableKind::Dwarf: + Streamer->emitDebugNames(DebugNames); + break; + } } }; Index: llvm/tools/dsymutil/DwarfStreamer.h =================================================================== --- llvm/tools/dsymutil/DwarfStreamer.h +++ llvm/tools/dsymutil/DwarfStreamer.h @@ -27,6 +27,7 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -121,6 +122,9 @@ void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address, StringRef Bytes); + /// Emit DWARF debug names. + void emitDebugNames(AccelTable &Table); + /// Emit Apple namespaces accelerator table. void emitAppleNamespaces(AccelTable &Table); @@ -162,6 +166,9 @@ uint32_t LineSectionSize; uint32_t FrameSectionSize; + /// Keep track of emitted CUs and their Unique ID. + std::vector EmittedUnits; + /// Emit the pubnames or pubtypes section contribution for \p /// Unit into \p Sec. The data is provided in \p Names. void emitPubSectionForUnit(MCSection *Sec, StringRef Name, Index: llvm/tools/dsymutil/DwarfStreamer.cpp =================================================================== --- llvm/tools/dsymutil/DwarfStreamer.cpp +++ llvm/tools/dsymutil/DwarfStreamer.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "DwarfStreamer.h" +#include "CompileUnit.h" #include "LinkUtils.h" #include "MachOUtils.h" #include "llvm/ADT/Triple.h" @@ -165,6 +166,9 @@ // start of the section. Asm->emitInt32(0); Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize()); + + // Remember this CU. + EmittedUnits.push_back(&Unit); } /// Emit the \p Abbrevs array as the shared abbreviation table @@ -197,6 +201,30 @@ } } +void DwarfStreamer::emitDebugNames( + AccelTable &Table) { + if (EmittedUnits.empty()) + return; + + // Build up datastructures needed to emit this section. + std::vector CompUnits; + DenseMap UniqueIdToCuMap; + unsigned Id = 0; + for (auto *CU : EmittedUnits) { + CompUnits.push_back(CU->getLabelBegin()); + UniqueIdToCuMap[CU->getUniqueID()] = Id; + assert(CU->getUniqueID() == Id); + Id++; + } + + Asm->OutStreamer->SwitchSection(MOFI->getDwarfDebugNamesSection()); + emitDWARF5AccelTable( + Asm.get(), Table, CompUnits, + [&UniqueIdToCuMap](const DWARF5AccelTableStaticData &Entry) { + return UniqueIdToCuMap[Entry.getCUIndex()]; + }); +} + void DwarfStreamer::emitAppleNamespaces( AccelTable &Table) { Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelNamespaceSection()); Index: llvm/tools/dsymutil/LinkUtils.h =================================================================== --- llvm/tools/dsymutil/LinkUtils.h +++ llvm/tools/dsymutil/LinkUtils.h @@ -22,6 +22,12 @@ Assembly, }; +/// The kind of accelerator tables we should emit. +enum class AccelTableKind { + Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc. + Dwarf, ///< DWARF v5 .debug_names. +}; + struct LinkOptions { /// Verbosity bool Verbose = false; @@ -47,6 +53,9 @@ // Output file type. OutputFileType FileType = OutputFileType::Object; + /// The accelerator table kind + AccelTableKind TheAccelTableKind; + /// -oso-prepend-path std::string PrependPath; Index: llvm/tools/dsymutil/dsymutil.cpp =================================================================== --- llvm/tools/dsymutil/dsymutil.cpp +++ llvm/tools/dsymutil/dsymutil.cpp @@ -103,6 +103,12 @@ init(false), cat(DsymCategory)); static alias UpdateA("u", desc("Alias for --update"), aliasopt(Update)); +static cl::opt AcceleratorTable( + "accelerator", cl::desc("Output accelerator tables."), + cl::values(clEnumValN(AccelTableKind::Apple, "Apple", "Apple"), + clEnumValN(AccelTableKind::Dwarf, "Dwarf", "DWARF")), + cl::init(AccelTableKind::Apple), cat(DsymCategory)); + static opt NumThreads( "num-threads", desc("Specifies the maximum number (n) of simultaneous threads to use\n" @@ -326,6 +332,7 @@ Options.Update = Update; Options.NoTimestamp = NoTimestamp; Options.PrependPath = OsoPrependPath; + Options.TheAccelTableKind = AcceleratorTable; if (Assembly) Options.FileType = OutputFileType::Assembly;