diff --git a/llvm/include/llvm/CodeGen/AccelTable.h b/llvm/include/llvm/CodeGen/AccelTable.h --- a/llvm/include/llvm/CodeGen/AccelTable.h +++ b/llvm/include/llvm/CodeGen/AccelTable.h @@ -25,6 +25,7 @@ #include "llvm/Support/DJB.h" #include "llvm/Support/Debug.h" #include +#include #include /// \file @@ -310,9 +311,13 @@ const DwarfDebug &DD, ArrayRef> CUs); +/// Emit a DWARFv5 Accelerator Table consisting of entries in the specified +/// AccelTable. The \p CUs contains either symbols keeping offsets to the +/// start of compilation unit, either offsets to the start of compilation +/// unit themselves. void emitDWARF5AccelTable( AsmPrinter *Asm, AccelTable &Contents, - ArrayRef CUs, + ArrayRef> CUs, llvm::function_ref getCUIndexForEntry); diff --git a/llvm/include/llvm/DWARFLinkerParallel/DWARFLinker.h b/llvm/include/llvm/DWARFLinkerParallel/DWARFLinker.h --- a/llvm/include/llvm/DWARFLinkerParallel/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinkerParallel/DWARFLinker.h @@ -100,9 +100,6 @@ /// Emit section named SecName with data SecData. virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0; - /// Emit temporarily symbol named \p SymName inside section \p SecName. - virtual MCSymbol *emitTempSym(StringRef SecName, StringRef SymName) = 0; - /// Emit the swift_ast section stored in \p Buffer. virtual void emitSwiftAST(StringRef Buffer) = 0; diff --git a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp @@ -213,7 +213,7 @@ Header Header; DenseMap> Abbreviations; - ArrayRef CompUnits; + ArrayRef> CompUnits; llvm::function_ref getCUIndexForEntry; MCSymbol *ContributionEnd = nullptr; MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start"); @@ -235,7 +235,7 @@ public: Dwarf5AccelTableWriter( AsmPrinter *Asm, const AccelTableBase &Contents, - ArrayRef CompUnits, + ArrayRef> CompUnits, llvm::function_ref GetCUIndexForEntry); void emit(); @@ -419,7 +419,10 @@ void Dwarf5AccelTableWriter::emitCUList() const { for (const auto &CU : enumerate(CompUnits)) { Asm->OutStreamer->AddComment("Compilation unit " + Twine(CU.index())); - Asm->emitDwarfSymbolReference(CU.value()); + if (std::holds_alternative(CU.value())) + Asm->emitDwarfSymbolReference(std::get(CU.value())); + else + Asm->emitDwarfLengthOrOffset(std::get(CU.value())); } } @@ -508,7 +511,7 @@ template Dwarf5AccelTableWriter::Dwarf5AccelTableWriter( AsmPrinter *Asm, const AccelTableBase &Contents, - ArrayRef CompUnits, + ArrayRef> CompUnits, llvm::function_ref getCUIndexForEntry) : AccelTableWriter(Asm, Contents, false), Header(CompUnits.size(), Contents.getBucketCount(), @@ -545,7 +548,7 @@ void llvm::emitDWARF5AccelTable( AsmPrinter *Asm, AccelTable &Contents, const DwarfDebug &DD, ArrayRef> CUs) { - std::vector CompUnits; + std::vector> CompUnits; SmallVector CUIndex(CUs.size()); int Count = 0; for (const auto &CU : enumerate(CUs)) { @@ -581,7 +584,7 @@ void llvm::emitDWARF5AccelTable( AsmPrinter *Asm, AccelTable &Contents, - ArrayRef CUs, + ArrayRef> CUs, llvm::function_ref getCUIndexForEntry) { Contents.finalize(Asm, "names"); diff --git a/llvm/lib/DWARFLinker/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp --- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp +++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp @@ -297,7 +297,7 @@ return; // Build up data structures needed to emit this section. - std::vector CompUnits; + std::vector> CompUnits; DenseMap UniqueIdToCuMap; unsigned Id = 0; for (auto &CU : EmittedUnits) { diff --git a/llvm/lib/DWARFLinkerParallel/ArrayList.h b/llvm/lib/DWARFLinkerParallel/ArrayList.h --- a/llvm/lib/DWARFLinkerParallel/ArrayList.h +++ b/llvm/lib/DWARFLinkerParallel/ArrayList.h @@ -9,8 +9,8 @@ #ifndef LLVM_LIB_DWARFLINKERPARALLEL_ARRAYLIST_H #define LLVM_LIB_DWARFLINKERPARALLEL_ARRAYLIST_H -#include "DWARFLinkerGlobalData.h" #include "llvm/Support/PerThreadBumpPtrAllocator.h" +#include namespace llvm { namespace dwarflinker_parallel { @@ -18,51 +18,54 @@ /// This class is a simple list of T structures. It keeps elements as /// pre-allocated groups to save memory for each element's next pointer. /// It allocates internal data using specified per-thread BumpPtrAllocator. +/// Method add() can be called asynchronously. template class ArrayList { public: - /// Copy specified \p Item into the list. - T ¬eItem(const T &Item) { - assert(Allocator != nullptr); - - ItemsGroup *CurGroup = LastGroup; - - if (CurGroup == nullptr) { - // Allocate first ItemsGroup. - LastGroup = Allocator->Allocate(); - LastGroup->ItemsCount = 0; - LastGroup->Next = nullptr; - GroupsHead = LastGroup; - CurGroup = LastGroup; + /// Add specified \p Item to the list. + T &add(const T &Item) { + assert(Allocator); + + // Allocate head group if it is not allocated yet. + while (!LastGroup) { + if (allocateNewGroup(GroupsHead)) + LastGroup = GroupsHead.load(); } - if (CurGroup->ItemsCount == ItemsGroupSize) { - // Allocate next ItemsGroup if current one is full. - LastGroup = Allocator->Allocate(); - LastGroup->ItemsCount = 0; - LastGroup->Next = nullptr; - CurGroup->Next = LastGroup; + ItemsGroup *CurGroup; + size_t CurItemsCount; + do { CurGroup = LastGroup; - } + CurItemsCount = CurGroup->ItemsCount.fetch_add(1); + + // Check whether current group is full. + if (CurItemsCount < ItemsGroupSize) + break; + + // Allocate next group if necessary. + if (!CurGroup->Next) + allocateNewGroup(CurGroup->Next); + + LastGroup.compare_exchange_weak(CurGroup, CurGroup->Next); + } while (true); - // Copy item into the next position inside current ItemsGroup. - CurGroup->Items[CurGroup->ItemsCount] = Item; - return CurGroup->Items[CurGroup->ItemsCount++]; + // Store item into the current group. + CurGroup->Items[CurItemsCount] = Item; + return CurGroup->Items[CurItemsCount]; } using ItemHandlerTy = function_ref; /// Enumerate all items and apply specified \p Handler to each. void forEach(ItemHandlerTy Handler) { - for (ItemsGroup *CurGroup = GroupsHead; CurGroup != nullptr; + for (ItemsGroup *CurGroup = GroupsHead; CurGroup; CurGroup = CurGroup->Next) { - for (size_t Idx = 0; Idx < CurGroup->ItemsCount; Idx++) { - Handler(CurGroup->Items[Idx]); - } + for (T &Item : *CurGroup) + Handler(Item); } } /// Check whether list is empty. - bool empty() { return GroupsHead == nullptr; } + bool empty() { return !GroupsHead; } /// Erase list. void erase() { @@ -76,13 +79,61 @@ protected: struct ItemsGroup { - std::array Items; - ItemsGroup *Next = nullptr; - size_t ItemsCount = 0; + using ArrayTy = std::array; + + // Array of items kept by this group. + ArrayTy Items; + + // Pointer to the next items group. + std::atomic Next = nullptr; + + // Number of items in this group. + // NOTE: ItemsCount could be inaccurate as it might be incremented by + // several threads. Use getItemsCount() method to get real number of items + // inside ItemsGroup. + std::atomic ItemsCount = 0; + + size_t getItemsCount() const { + return std::min(ItemsCount.load(), ItemsGroupSize); + } + + typename ArrayTy::iterator begin() { return Items.begin(); } + typename ArrayTy::iterator end() { return Items.begin() + getItemsCount(); } }; - ItemsGroup *GroupsHead = nullptr; - ItemsGroup *LastGroup = nullptr; + // Allocate new group. Put allocated group into the \p AtomicGroup if + // it is empty. If \p AtomicGroup is filled by another thread then + // put allocated group into the end of groups list. + // \returns true if allocated group is put into the \p AtomicGroup. + bool allocateNewGroup(std::atomic &AtomicGroup) { + ItemsGroup *CurGroup = nullptr; + + // Allocate new group. + ItemsGroup *NewGroup = Allocator->Allocate(); + NewGroup->ItemsCount = 0; + NewGroup->Next = nullptr; + + // Try to replace current group with allocated one. + if (AtomicGroup.compare_exchange_weak(CurGroup, NewGroup)) + return true; + + // Put allocated group as last group. + while (CurGroup) { + ItemsGroup *NextGroup = CurGroup->Next; + + if (!NextGroup) { + if (CurGroup->Next.compare_exchange_weak(NextGroup, NewGroup)) + break; + } + + CurGroup = NextGroup; + } + + return false; + } + + std::atomic GroupsHead = nullptr; + std::atomic LastGroup = nullptr; parallel::PerThreadBumpPtrAllocator *Allocator = nullptr; }; diff --git a/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.h b/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.h --- a/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.h +++ b/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.h @@ -17,6 +17,28 @@ namespace llvm { namespace dwarflinker_parallel { +/// Information gathered and exchanged between the various +/// clone*Attr helpers about the attributes of a particular DIE. +struct AttributesInfo { + /// Short Name. + StringEntry *Name = nullptr; + + /// Mangled Name. + StringEntry *MangledName = nullptr; + + /// Does the DIE have an address pointing to live code section? + bool HasLiveAddress = false; + + /// Is this DIE only a declaration? + bool IsDeclaration = false; + + /// Does the DIE have a ranges attribute? + bool HasRanges = false; + + /// Does the DIE have a string offset attribute? + bool HasStringOffsetBaseAttr = false; +}; + /// This class creates clones of input DIE attributes. /// It enumerates attributes of input DIE, creates clone for each /// attribute, adds cloned attribute to the output DIE. @@ -44,29 +66,7 @@ /// Create abbreviations for the output DIE after all attributes are cloned. unsigned finalizeAbbreviations(bool HasChildrenToClone); - /// Information gathered and exchanged between the various - /// clone*Attr helpers about the attributes of a particular DIE. - /// /// Cannot be used concurrently. - struct AttributesInfo { - /// Names. - StringEntry *Name = nullptr; - StringEntry *MangledName = nullptr; - StringEntry *NameWithoutTemplate = nullptr; - - /// Does the DIE have a low_pc attribute? - bool HasLowPc = false; - - /// Is this DIE only a declaration? - bool IsDeclaration = false; - - /// Does the DIE have a ranges attribute? - bool HasRanges = false; - - /// Does the DIE have a string offset attribute? - bool HasStringOffsetBaseAttr = false; - }; - AttributesInfo AttrInfo; protected: diff --git a/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.cpp b/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.cpp --- a/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.cpp +++ b/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.cpp @@ -226,7 +226,7 @@ return 0; std::optional> RefDiePair = - CU.resolveDIEReference(Val); + CU.resolveDIEReference(Val, ResolveInterCUReferencesMode::Resolve); if (!RefDiePair) { // If the referenced DIE is not found, drop the attribute. CU.warn("cann't find referenced DIE.", InputDieEntry); @@ -314,6 +314,11 @@ } uint64_t Value; + if (AttrSpec.Attr == dwarf::DW_AT_const_value && + (InputDieEntry->getTag() == dwarf::DW_TAG_variable || + InputDieEntry->getTag() == dwarf::DW_TAG_constant)) + AttrInfo.HasLiveAddress = true; + if (CU.getGlobalData().getOptions().UpdateIndexTablesOnly) { if (auto OptionalValue = Val.getAsUnsignedConstant()) Value = *OptionalValue; @@ -483,6 +488,11 @@ (AttrOutOffset + (FinalAttributeSize - Bytes.size())); } + if (HasLocationExpressionAddress) + AttrInfo.HasLiveAddress = + VarAddressAdjustment.has_value() || + CU.getGlobalData().getOptions().UpdateIndexTablesOnly; + return FinalAttributeSize; } @@ -490,7 +500,7 @@ const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) { if (AttrSpec.Attr == dwarf::DW_AT_low_pc) - AttrInfo.HasLowPc = true; + AttrInfo.HasLiveAddress = true; if (CU.getGlobalData().getOptions().UpdateIndexTablesOnly) return Generator diff --git a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.h b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.h --- a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.h +++ b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.h @@ -35,10 +35,12 @@ template class AccelTable; class MCCodeEmitter; -class DWARFDebugMacro; namespace dwarflinker_parallel { +using DebugNamesUnitsOffsets = std::vector>; +using CompUnitIDToIdx = DenseMap; + /// This class emits DWARF data to the output stream. It emits already /// generated section data and specific data, which could not be generated /// by CompileUnit. @@ -71,9 +73,6 @@ /// Emit specified section data. void emitSectionContents(StringRef SecData, StringRef SecName) override; - /// Emit temporary symbol. - MCSymbol *emitTempSym(StringRef SecName, StringRef SymName) override; - /// Emit abbreviations. void emitAbbrevs(const SmallVector> &Abbrevs, unsigned DwarfVersion); @@ -87,6 +86,23 @@ /// Returns size of generated .debug_info section. uint64_t getDebugInfoSectionSize() const { return DebugInfoSectionSize; } + /// Emits .debug_names section according to the specified \p Table. + void emitDebugNames(AccelTable &Table, + DebugNamesUnitsOffsets &CUOffsets, + CompUnitIDToIdx &UnitIDToIdxMap); + + /// Emits .apple_names section according to the specified \p Table. + void emitAppleNames(AccelTable &Table); + + /// Emits .apple_namespaces section according to the specified \p Table. + void emitAppleNamespaces(AccelTable &Table); + + /// Emits .apple_objc section according to the specified \p Table. + void emitAppleObjc(AccelTable &Table); + + /// Emits .apple_types section according to the specified \p Table. + void emitAppleTypes(AccelTable &Table); + private: // Enumerate all string patches and write them into the destination section. // Order of patches is the same as in original input file. To avoid emitting diff --git a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp --- a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp +++ b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp @@ -171,18 +171,18 @@ .Case("debug_line_str", MC->getObjectFileInfo()->getDwarfLineStrSection()) .Case("debug_str_offsets", MC->getObjectFileInfo()->getDwarfStrOffSection()) - .Default(nullptr); -} - -MCSymbol *DwarfEmitterImpl::emitTempSym(StringRef SecName, StringRef SymName) { - if (MCSection *Section = switchSection(SecName)) { - MS->switchSection(Section); - MCSymbol *Res = Asm->createTempSymbol(SymName); - Asm->OutStreamer->emitLabel(Res); - return Res; - } + .Case("debug_pubnames", + MC->getObjectFileInfo()->getDwarfPubNamesSection()) + .Case("debug_pubtypes", + MC->getObjectFileInfo()->getDwarfPubTypesSection()) + .Case("debug_names", MC->getObjectFileInfo()->getDwarfDebugNamesSection()) + .Case("apple_names", MC->getObjectFileInfo()->getDwarfAccelNamesSection()) + .Case("apple_namespac", + MC->getObjectFileInfo()->getDwarfAccelNamespaceSection()) + .Case("apple_objc", MC->getObjectFileInfo()->getDwarfAccelObjCSection()) + .Case("apple_types", MC->getObjectFileInfo()->getDwarfAccelTypesSection()) - return nullptr; + .Default(nullptr); } void DwarfEmitterImpl::emitAbbrevs( @@ -200,8 +200,7 @@ // Emit size of content not including length itself. The size has already // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to // account for the length field. - Asm->emitInt32(Unit.getDebugInfoHeaderSize() + - Unit.getOutUnitDIE()->getSize() - 4); + Asm->emitInt32(Unit.getUnitSize() - 4); Asm->emitInt16(Unit.getVersion()); if (Unit.getVersion() >= 5) { @@ -224,5 +223,50 @@ DebugInfoSectionSize += Die.getSize(); } +void DwarfEmitterImpl::emitDebugNames( + AccelTable &Table, + DebugNamesUnitsOffsets &CUOffsets, CompUnitIDToIdx &CUidToIdx) { + if (CUOffsets.empty()) + return; + + Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection()); + emitDWARF5AccelTable(Asm.get(), Table, CUOffsets, + [&CUidToIdx](const DWARF5AccelTableStaticData &Entry) { + return CUidToIdx[Entry.getCUIndex()]; + }); +} + +void DwarfEmitterImpl::emitAppleNamespaces( + AccelTable &Table) { + Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection()); + auto *SectionBegin = Asm->createTempSymbol("namespac_begin"); + Asm->OutStreamer->emitLabel(SectionBegin); + emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin); +} + +void DwarfEmitterImpl::emitAppleNames( + AccelTable &Table) { + Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection()); + auto *SectionBegin = Asm->createTempSymbol("names_begin"); + Asm->OutStreamer->emitLabel(SectionBegin); + emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin); +} + +void DwarfEmitterImpl::emitAppleObjc( + AccelTable &Table) { + Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection()); + auto *SectionBegin = Asm->createTempSymbol("objc_begin"); + Asm->OutStreamer->emitLabel(SectionBegin); + emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin); +} + +void DwarfEmitterImpl::emitAppleTypes( + AccelTable &Table) { + Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection()); + auto *SectionBegin = Asm->createTempSymbol("types_begin"); + Asm->OutStreamer->emitLabel(SectionBegin); + emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin); +} + } // end of namespace dwarflinker_parallel } // namespace llvm diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.h b/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.h --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.h +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.h @@ -19,6 +19,13 @@ using OffsetToUnitTy = function_ref; +struct AttributesInfo; + +enum ResolveInterCUReferencesMode : bool { + Resolve = true, + AvoidResolving = false, +}; + /// Stores all information related to a compile unit, be it in its original /// instance of the object file or its brand new cloned and generated DIE tree. class CompileUnit : public DwarfUnit { @@ -293,7 +300,8 @@ /// \returns referenced die and corresponding compilation unit. /// compilation unit is null if reference could not be resolved. std::optional> - resolveDIEReference(const DWARFFormValue &RefValue); + resolveDIEReference(const DWARFFormValue &RefValue, + ResolveInterCUReferencesMode CanResolveInterCUReferences); /// @} /// Add a function range [\p LowPC, \p HighPC) that is relocated by applying @@ -513,6 +521,14 @@ void emitMacroTableImpl(const DWARFDebugMacro *MacroTable, uint64_t OffsetToMacroTable, bool hasDWARFv5Header); + /// Store accelerator information for the \p InputDieEntry. + void rememberAcceleratorEntries(const DWARFDebugInfoEntry *InputDieEntry, + uint64_t OutOffset, AttributesInfo &AttrInfo); + + /// Store ObjC accelerator information for the \p InputDieEntry. + void rememberObjCAccelerator(const DWARFDebugInfoEntry *InputDieEntry, + uint64_t OutOffset, AttributesInfo &AttrInfo); + /// DWARFFile containing this compile unit. DWARFFile &File; @@ -528,10 +544,6 @@ ResolvedPathsMap ResolvedFullPaths; StringMap ResolvedParentPaths; - /// This field instructs compile unit to store DIE name with stripped - /// template parameters into the accelerator table. - bool CanStripTemplateName = false; - /// Maps an address into the index inside .debug_addr section. IndexedValuesMap DebugAddrIndexMap; diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.cpp --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.cpp +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.cpp @@ -9,7 +9,9 @@ #include "DWARFLinkerCompileUnit.h" #include "DIEAttributeCloner.h" #include "DIEGenerator.h" +#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" +#include "llvm/Support/DJB.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatVariadic.h" @@ -30,8 +32,8 @@ // with marking from "LivenessAnalysisDone" stage partially // done. That marking should be cleared. - for (DIEInfo &DieInfo : DieInfoArray) - DieInfo.unsetFlagsWhichSetDuringLiveAnalysis(); + for (DIEInfo &Info : DieInfoArray) + Info.unsetFlagsWhichSetDuringLiveAnalysis(); LowPc = std::nullopt; HighPc = 0; @@ -43,6 +45,7 @@ return; } + AcceleratorRecords.erase(); AbbreviationsSet.clear(); Abbreviations.clear(); OutUnitDIE = nullptr; @@ -211,10 +214,11 @@ void CompileUnit::updateDieRefPatchesWithClonedOffsets() { if (std::optional DebugInfoSection = - getSectionDescriptor(DebugSectionKind::DebugInfo)) { + tryGetSectionDescriptor(DebugSectionKind::DebugInfo)) { (*DebugInfoSection) ->ListDebugDieRefPatch.forEach([](DebugDieRefPatch &Patch) { + /// Replace stored DIE indexes with DIE output offsets. Patch.RefDieIdxOrClonedOffset = Patch.RefCU.getPointer()->getDieOutOffset( Patch.RefDieIdxOrClonedOffset); @@ -223,6 +227,7 @@ (*DebugInfoSection) ->ListDebugULEB128DieRefPatch.forEach( [](DebugULEB128DieRefPatch &Patch) { + /// Replace stored DIE indexes with DIE output offsets. Patch.RefDieIdxOrClonedOffset = Patch.RefCU.getPointer()->getDieOutOffset( Patch.RefDieIdxOrClonedOffset); @@ -230,10 +235,11 @@ } if (std::optional DebugLocSection = - getSectionDescriptor(DebugSectionKind::DebugLoc)) { + tryGetSectionDescriptor(DebugSectionKind::DebugLoc)) { (*DebugLocSection) ->ListDebugULEB128DieRefPatch.forEach( [](DebugULEB128DieRefPatch &Patch) { + /// Replace stored DIE indexes with DIE output offsets. Patch.RefDieIdxOrClonedOffset = Patch.RefCU.getPointer()->getDieOutOffset( Patch.RefDieIdxOrClonedOffset); @@ -241,10 +247,11 @@ } if (std::optional DebugLocListsSection = - getSectionDescriptor(DebugSectionKind::DebugLocLists)) { + tryGetSectionDescriptor(DebugSectionKind::DebugLocLists)) { (*DebugLocListsSection) ->ListDebugULEB128DieRefPatch.forEach( [](DebugULEB128DieRefPatch &Patch) { + /// Replace stored DIE indexes with DIE output offsets. Patch.RefDieIdxOrClonedOffset = Patch.RefCU.getPointer()->getDieOutOffset( Patch.RefDieIdxOrClonedOffset); @@ -253,7 +260,9 @@ } std::optional> -CompileUnit::resolveDIEReference(const DWARFFormValue &RefValue) { +CompileUnit::resolveDIEReference( + const DWARFFormValue &RefValue, + ResolveInterCUReferencesMode CanResolveInterCUReferences) { if (std::optional Ref = *RefValue.getAsRelativeReference()) { if (Ref->Unit != nullptr) { @@ -262,17 +271,27 @@ if (std::optional RefDieIdx = getDIEIndexForOffset(Ref->Unit->getOffset() + Ref->Offset)) return std::make_pair(this, *RefDieIdx); - } else if (CompileUnit *RefCU = getUnitFromOffset(Ref->Offset)) { - // Referenced DIE is in other compile unit. + } - // Check whether DIEs are loaded for that compile unit. - enum Stage ReferredCUStage = RefCU->getStage(); - if (ReferredCUStage < Stage::Loaded || ReferredCUStage > Stage::Cloned) + if (CompileUnit *RefCU = getUnitFromOffset(Ref->Offset)) { + if (RefCU->getUniqueID() == getUniqueID()) { + // Referenced DIE is in current compile unit. + if (std::optional RefDieIdx = + getDIEIndexForOffset(Ref->Offset)) + return std::make_pair(this, *RefDieIdx); + } else if (CanResolveInterCUReferences) { + // Referenced DIE is in other compile unit. + + // Check whether DIEs are loaded for that compile unit. + enum Stage ReferredCUStage = RefCU->getStage(); + if (ReferredCUStage < Stage::Loaded || ReferredCUStage > Stage::Cloned) + return std::make_pair(RefCU, 0); + + if (std::optional RefDieIdx = + RefCU->getDIEIndexForOffset(Ref->Offset)) + return std::make_pair(RefCU, *RefDieIdx); + } else return std::make_pair(RefCU, 0); - - if (std::optional RefDieIdx = - RefCU->getDIEIndexForOffset(Ref->Offset)) - return std::make_pair(RefCU, *RefDieIdx); } } @@ -1136,10 +1155,6 @@ if (!OrigUnitDIE.isValid()) return Error::success(); - CanStripTemplateName = - llvm::is_contained(getGlobalData().getOptions().AccelTables, - DWARFLinker::AccelTableKind::Apple); - // Clone input DIE entry recursively. DIE *OutCUDie = cloneDIE(OrigUnitDIE.getDebugInfoEntry(), getDebugInfoHeaderSize(), @@ -1172,6 +1187,11 @@ if (Error Err = emitDebugAddrSection()) return Err; + // Generate Pub accelerator tables. + if (llvm::is_contained(GlobalData.getOptions().AccelTables, + DWARFLinker::AccelTableKind::Pub)) + emitPubAccelerators(); + if (Error Err = emitDebugStringOffsetSection()) return Err; @@ -1221,6 +1241,10 @@ VarAddressAdjustment, HasLocationExpressionAddress); AttributesCloner.clone(); + // Remember accelerator info. + rememberAcceleratorEntries(InputDieEntry, OutOffset, + AttributesCloner.AttrInfo); + bool HasChildrenToClone = Info.getKeepChildren(); OutOffset = AttributesCloner.finalizeAbbreviations(HasChildrenToClone); @@ -1400,3 +1424,202 @@ llvm::errs() << "}\n"; } #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + +static uint32_t hashFullyQualifiedName(CompileUnit *InputCU, DWARFDie &InputDIE, + int ChildRecurseDepth = 0) { + const char *Name = nullptr; + CompileUnit *CU = InputCU; + std::optional RefVal; + + // Usually name`s depth does not exceed 3. Set maximal depth + // to 1000 here, to avoid infinite loop in case incorrect input + // DWARF. + size_t MaxNameDepth = 1000; + size_t CurNameDepth = 0; + + while (CurNameDepth++ < MaxNameDepth) { + if (const char *CurrentName = InputDIE.getName(DINameKind::ShortName)) + Name = CurrentName; + + if (!(RefVal = InputDIE.find(dwarf::DW_AT_specification)) && + !(RefVal = InputDIE.find(dwarf::DW_AT_abstract_origin))) + break; + + if (!RefVal->isFormClass(DWARFFormValue::FC_Reference)) + break; + + std::optional> RefDie = + CU->resolveDIEReference(*RefVal, ResolveInterCUReferencesMode::Resolve); + if (!RefDie) + break; + + assert(RefDie->second != 0); + + CU = RefDie->first; + InputDIE = RefDie->first->getDIEAtIndex(RefDie->second); + } + + if (!Name && InputDIE.getTag() == dwarf::DW_TAG_namespace) + Name = "(anonymous namespace)"; + + DWARFDie ParentDie = InputDIE.getParent(); + if (!ParentDie.isValid() || ParentDie.getTag() == dwarf::DW_TAG_compile_unit) + return djbHash(Name ? Name : "", djbHash(ChildRecurseDepth ? "" : "::")); + + return djbHash( + (Name ? Name : ""), + djbHash((Name ? "::" : ""), + hashFullyQualifiedName(CU, ParentDie, ++ChildRecurseDepth))); +} + +void CompileUnit::rememberAcceleratorEntries( + const DWARFDebugInfoEntry *InputDieEntry, uint64_t OutOffset, + AttributesInfo &AttrInfo) { + if (GlobalData.getOptions().AccelTables.empty()) + return; + + DWARFDie InputDIE = getDIE(InputDieEntry); + + // Look for short name recursively if short name is not known yet. + if (AttrInfo.Name == nullptr) + if (const char *ShortName = InputDIE.getShortName()) + AttrInfo.Name = getGlobalData().getStringPool().insert(ShortName).first; + + switch (InputDieEntry->getTag()) { + case dwarf::DW_TAG_array_type: + case dwarf::DW_TAG_class_type: + case dwarf::DW_TAG_enumeration_type: + case dwarf::DW_TAG_pointer_type: + case dwarf::DW_TAG_reference_type: + case dwarf::DW_TAG_string_type: + case dwarf::DW_TAG_structure_type: + case dwarf::DW_TAG_subroutine_type: + case dwarf::DW_TAG_typedef: + case dwarf::DW_TAG_union_type: + case dwarf::DW_TAG_ptr_to_member_type: + case dwarf::DW_TAG_set_type: + case dwarf::DW_TAG_subrange_type: + case dwarf::DW_TAG_base_type: + case dwarf::DW_TAG_const_type: + case dwarf::DW_TAG_constant: + case dwarf::DW_TAG_file_type: + case dwarf::DW_TAG_namelist: + case dwarf::DW_TAG_packed_type: + case dwarf::DW_TAG_volatile_type: + case dwarf::DW_TAG_restrict_type: + case dwarf::DW_TAG_atomic_type: + case dwarf::DW_TAG_interface_type: + case dwarf::DW_TAG_unspecified_type: + case dwarf::DW_TAG_shared_type: + case dwarf::DW_TAG_immutable_type: + case dwarf::DW_TAG_rvalue_reference_type: { + if (!AttrInfo.IsDeclaration && AttrInfo.Name != nullptr && + !AttrInfo.Name->getKey().empty()) { + uint32_t Hash = hashFullyQualifiedName(this, InputDIE); + + uint64_t RuntimeLang = + dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class)) + .value_or(0); + + bool ObjCClassIsImplementation = + (RuntimeLang == dwarf::DW_LANG_ObjC || + RuntimeLang == dwarf::DW_LANG_ObjC_plus_plus) && + dwarf::toUnsigned( + InputDIE.find(dwarf::DW_AT_APPLE_objc_complete_type)) + .value_or(0); + + rememberTypeForAccelerators(AttrInfo.Name, OutOffset, + InputDieEntry->getTag(), Hash, + ObjCClassIsImplementation); + } + } break; + case dwarf::DW_TAG_namespace: { + if (AttrInfo.Name == nullptr) + AttrInfo.Name = + getGlobalData().getStringPool().insert("(anonymous namespace)").first; + + rememberNamespaceForAccelerators(AttrInfo.Name, OutOffset, + InputDieEntry->getTag()); + } break; + case dwarf::DW_TAG_imported_declaration: { + if (AttrInfo.Name != nullptr) + rememberNamespaceForAccelerators(AttrInfo.Name, OutOffset, + InputDieEntry->getTag()); + } break; + case dwarf::DW_TAG_compile_unit: + case dwarf::DW_TAG_lexical_block: { + // Nothing to do. + } break; + default: + if (AttrInfo.HasLiveAddress || AttrInfo.HasRanges) { + if (AttrInfo.Name != nullptr) + rememberNameForAccelerators( + AttrInfo.Name, OutOffset, InputDieEntry->getTag(), + InputDieEntry->getTag() == dwarf::DW_TAG_inlined_subroutine); + + // Look for mangled name recursively if mangled name is not known yet. + if (AttrInfo.MangledName == nullptr) + if (const char *LinkageName = InputDIE.getLinkageName()) + AttrInfo.MangledName = + getGlobalData().getStringPool().insert(LinkageName).first; + + if (AttrInfo.MangledName != nullptr && + AttrInfo.MangledName != AttrInfo.Name) + rememberNameForAccelerators( + AttrInfo.MangledName, OutOffset, InputDieEntry->getTag(), + InputDieEntry->getTag() == dwarf::DW_TAG_inlined_subroutine); + + // Strip template parameters from the short name. + if (AttrInfo.Name != nullptr && AttrInfo.MangledName != AttrInfo.Name && + (InputDieEntry->getTag() != dwarf::DW_TAG_inlined_subroutine)) { + if (std::optional Name = + StripTemplateParameters(AttrInfo.Name->getKey())) { + StringEntry *NameWithoutTemplateParams = + getGlobalData().getStringPool().insert(*Name).first; + + rememberNameForAccelerators(NameWithoutTemplateParams, OutOffset, + InputDieEntry->getTag(), true); + } + } + + if (AttrInfo.Name) + rememberObjCAccelerator(InputDieEntry, OutOffset, AttrInfo); + } + break; + } +} + +void CompileUnit::rememberObjCAccelerator( + const DWARFDebugInfoEntry *InputDieEntry, uint64_t OutOffset, + AttributesInfo &AttrInfo) { + std::optional Names = + getObjCNamesIfSelector(AttrInfo.Name->getKey()); + if (!Names) + return; + + StringEntry *Selector = + getGlobalData().getStringPool().insert(Names->Selector).first; + rememberNameForAccelerators(Selector, OutOffset, InputDieEntry->getTag(), + true); + StringEntry *ClassName = + getGlobalData().getStringPool().insert(Names->ClassName).first; + rememberObjCNameForAccelerators(ClassName, OutOffset, + InputDieEntry->getTag()); + if (Names->ClassNameNoCategory) { + StringEntry *ClassNameNoCategory = getGlobalData() + .getStringPool() + .insert(*Names->ClassNameNoCategory) + .first; + rememberObjCNameForAccelerators(ClassNameNoCategory, OutOffset, + InputDieEntry->getTag()); + } + if (Names->MethodNameNoCategory) { + StringEntry *MethodNameNoCategory = + getGlobalData() + .getStringPool() + .insert(*Names->MethodNameNoCategory) + .first; + rememberNameForAccelerators(MethodNameNoCategory, OutOffset, + InputDieEntry->getTag(), true); + } +} diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.h b/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.h --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.h +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.h @@ -316,37 +316,47 @@ /// Enumerate all compile units and assign offsets to their strings. void assignOffsetsToStrings(); - /// Enumerates specified string patches, assigns offset and index. - template - void assignOffsetsToStringsImpl( - ArrayList &Section, size_t &IndexAccumulator, - uint64_t &OffsetAccumulator, - StringEntryToDwarfStringPoolEntryMap &StringsForEmission); - /// Print statistic for processed Debug Info. void printStatistic(); + enum StringDestinationKind : uint8_t { DebugStr, DebugLineStr }; + + /// Enumerates all strings. + void forEachOutputString( + function_ref + StringHandler); + /// Enumerates sections for modules, invariant for object files, compile /// units. void forEachObjectSectionsSet( function_ref SectionsSetHandler); + /// Enumerates all comple units. + void forEachCompileUnit(function_ref UnitHandler); + /// Enumerates all patches and update them with the correct values. void patchOffsetsAndSizes(); /// Emit debug sections common for all input files. - void emitCommonSections(); + void emitCommonSectionsAndWriteCompileUnitsToTheOutput(); + + /// Emit apple accelerator sections. + void emitAppleAcceleratorSections(const Triple &TargetTriple); + + /// Emit .debug_names section. + void emitDWARFv5DebugNamesSection(const Triple &TargetTriple); + + /// Emit string sections. + void emitStringSections(); /// Cleanup data(string pools) after output sections are generated. - void cleanupDataAfterOutputSectionsAreGenerated(); + void cleanupDataAfterDWARFOutputIsWritten(); /// Enumerate all compile units and put their data into the output stream. - void writeDWARFToTheOutput(); + void writeCompileUnitsToTheOutput(); - template - void emitStringsImpl(ArrayList &StringPatches, - const StringEntryToDwarfStringPoolEntryMap &Strings, - uint64_t &NextOffset, SectionDescriptor &OutSection); + /// Enumerate common sections and put their data into the output stream. + void writeCommonSectionsToTheOutput(); /// \defgroup Data members accessed asinchroniously. /// diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.cpp b/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.cpp --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.cpp +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.cpp @@ -712,17 +712,15 @@ // Patch size/offsets fields according to the assigned CU offsets. patchOffsetsAndSizes(); - // FIXME: Build accelerator tables. + // Emit common sections and write debug tables from all object files/compile + // units into the resulting file. + emitCommonSectionsAndWriteCompileUnitsToTheOutput(); - // Emit common sections. - emitCommonSections(); + // Write common debug sections into the resulting file. + writeCommonSectionsToTheOutput(); // Cleanup data. - cleanupDataAfterOutputSectionsAreGenerated(); - - // Write debug tables from all object files/compile units into the - // resulting file. - writeDWARFToTheOutput(); + cleanupDataAfterDWARFOutputIsWritten(); if (GlobalData.getOptions().Statistics) printStatistic(); @@ -738,7 +736,7 @@ for (std::unique_ptr &CU : Context->CompileUnits) if (std::optional DebugInfo = - CU->getSectionDescriptor(DebugSectionKind::DebugInfo)) + CU->tryGetSectionDescriptor(DebugSectionKind::DebugInfo)) AllDebugInfoSectionsSize += (*DebugInfo)->getContents().size(); SizeByObject[Context->InputDWARFFile.FileName].Input = @@ -806,42 +804,32 @@ size_t CurDebugLineStrIndex = 0; uint64_t CurDebugLineStrOffset = 0; - // To save space we do not create any separate string table. - // We use already allocated string patches and assign offsets - // to them in the natural order. - // ASSUMPTION: strings should be stored into .debug_str/.debug_line_str - // sections in the same order as they were assigned offsets. - - forEachObjectSectionsSet([&](OutputSections &SectionsSet) { - SectionsSet.forEach([&](SectionDescriptor &OutSection) { - assignOffsetsToStringsImpl(OutSection.ListDebugStrPatch, CurDebugStrIndex, - CurDebugStrOffset, DebugStrStrings); - - assignOffsetsToStringsImpl(OutSection.ListDebugLineStrPatch, - CurDebugLineStrIndex, CurDebugLineStrOffset, - DebugLineStrStrings); - }); - }); -} - -template -void DWARFLinkerImpl::assignOffsetsToStringsImpl( - ArrayList &Patches, size_t &IndexAccumulator, - uint64_t &OffsetAccumulator, - StringEntryToDwarfStringPoolEntryMap &StringsForEmission) { - - // Enumerates all patches, adds string into the - // StringEntry->DwarfStringPoolEntry map, assign offset and index to the - // string if it is not indexed yet. - Patches.forEach([&](PatchTy &Patch) { - DwarfStringPoolEntryWithExtString *Entry = - StringsForEmission.add(Patch.String); - assert(Entry != nullptr); - - if (!Entry->isIndexed()) { - Entry->Offset = OffsetAccumulator; - OffsetAccumulator += Entry->String.size() + 1; - Entry->Index = IndexAccumulator++; + // Enumerates all strings, add them into the DwarfStringPoolEntry map, + // assign offset and index to the string if it is not indexed yet. + forEachOutputString([&](StringDestinationKind Kind, + const StringEntry *String) { + switch (Kind) { + case StringDestinationKind::DebugStr: { + DwarfStringPoolEntryWithExtString *Entry = DebugStrStrings.add(String); + assert(Entry != nullptr); + + if (!Entry->isIndexed()) { + Entry->Offset = CurDebugStrOffset; + CurDebugStrOffset += Entry->String.size() + 1; + Entry->Index = CurDebugStrIndex++; + } + } break; + case StringDestinationKind::DebugLineStr: { + DwarfStringPoolEntryWithExtString *Entry = + DebugLineStrStrings.add(String); + assert(Entry != nullptr); + + if (!Entry->isIndexed()) { + Entry->Offset = CurDebugLineStrOffset; + CurDebugLineStrOffset += Entry->String.size() + 1; + Entry->Index = CurDebugLineStrIndex++; + } + } break; } }); } @@ -854,6 +842,31 @@ }); } +void DWARFLinkerImpl::forEachOutputString( + function_ref + StringHandler) { + // To save space we do not create any separate string table. + // We use already allocated string patches and accelerator entries: + // enumerate them in natural order and assign offsets. + // ASSUMPTION: strings should be stored into .debug_str/.debug_line_str + // sections in the same order as they were assigned offsets. + forEachCompileUnit([&](CompileUnit *CU) { + CU->forEach([&](SectionDescriptor &OutSection) { + OutSection.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) { + StringHandler(StringDestinationKind::DebugStr, Patch.String); + }); + + OutSection.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) { + StringHandler(StringDestinationKind::DebugLineStr, Patch.String); + }); + }); + + CU->AcceleratorRecords.forEach([&](DwarfUnit::AccelInfo &Info) { + StringHandler(DebugStr, Info.String); + }); + }); +} + void DWARFLinkerImpl::forEachObjectSectionsSet( function_ref SectionsSetHandler) { // Handle all modules first(before regular compilation units). @@ -871,6 +884,19 @@ } } +void DWARFLinkerImpl::forEachCompileUnit( + function_ref UnitHandler) { + // Enumerate module units. + for (const std::unique_ptr &Context : ObjectContexts) + for (LinkContext::RefModuleUnit &ModuleUnit : Context->ModulesCompileUnits) + UnitHandler(ModuleUnit.Unit.get()); + + // Enumerate compile units. + for (const std::unique_ptr &Context : ObjectContexts) + for (std::unique_ptr &CU : Context->CompileUnits) + UnitHandler(CU.get()); +} + void DWARFLinkerImpl::patchOffsetsAndSizes() { forEachObjectSectionsSet([&](OutputSections &SectionsSet) { SectionsSet.forEach([&](SectionDescriptor &OutSection) { @@ -880,78 +906,292 @@ }); } -template -void DWARFLinkerImpl::emitStringsImpl( - ArrayList &StringPatches, - const StringEntryToDwarfStringPoolEntryMap &Strings, uint64_t &NextOffset, - SectionDescriptor &OutSection) { - // Enumerate all string patches and write strings into the destination - // section. We enumerate patches to have a predictable order of strings(i.e. - // strings are emitted in the order as they appear in the patches). - StringPatches.forEach([&](const PatchTy &Patch) { - DwarfStringPoolEntryWithExtString *StringToEmit = - Strings.getExistingEntry(Patch.String); - assert(StringToEmit->isIndexed()); - - // Patches can refer the same strings. We use accumulated NextOffset - // to understand whether corresponding string is already emitted. - // Skip patch if string is already emitted. - if (StringToEmit->Offset >= NextOffset) { - NextOffset = StringToEmit->Offset + StringToEmit->String.size() + 1; - // Emit the string itself. - OutSection.emitInplaceString(StringToEmit->String); - } - }); -} - -void DWARFLinkerImpl::emitCommonSections() { +void DWARFLinkerImpl::emitCommonSectionsAndWriteCompileUnitsToTheOutput() { parallel::TaskGroup TG; - SectionDescriptor &OutDebugStrSection = - CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugStr); - SectionDescriptor &OutDebugLineStrSection = - CommonSections.getOrCreateSectionDescriptor( - DebugSectionKind::DebugLineStr); - - // Emit .debug_str section. - TG.spawn([&]() { - uint64_t DebugStrNextOffset = 0; - - // Emit zero length string. Accelerator tables does not work correctly - // if the first string is not zero length string. - OutDebugStrSection.emitInplaceString(""); - DebugStrNextOffset++; - - forEachObjectSectionsSet([&](OutputSections &Sections) { - Sections.forEach([&](SectionDescriptor &Section) { - emitStringsImpl(Section.ListDebugStrPatch, DebugStrStrings, - DebugStrNextOffset, OutDebugStrSection); + // Create section descriptors ahead if they are not exist at the moment. + // SectionDescriptors container is not thread safe. Thus we should be sure + // that descriptors would not be created in following parallel tasks. + + CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugStr); + CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugLineStr); + + if (llvm::is_contained(GlobalData.Options.AccelTables, + AccelTableKind::Apple)) { + CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleNames); + CommonSections.getOrCreateSectionDescriptor( + DebugSectionKind::AppleNamespaces); + CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleObjC); + CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleTypes); + } + + if (llvm::is_contained(GlobalData.Options.AccelTables, + AccelTableKind::DebugNames)) + CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugNames); + + const Triple &TargetTriple = TheDwarfEmitter->getTargetTriple(); + + // Emit .debug_str and .debug_line_str sections. + TG.spawn([&]() { emitStringSections(); }); + + if (llvm::is_contained(GlobalData.Options.AccelTables, + AccelTableKind::Apple)) { + // Emit apple accelerator sections. + TG.spawn([&]() { emitAppleAcceleratorSections(TargetTriple); }); + } + + if (llvm::is_contained(GlobalData.Options.AccelTables, + AccelTableKind::DebugNames)) { + // Emit .debug_names section. + TG.spawn([&]() { emitDWARFv5DebugNamesSection(TargetTriple); }); + } + + // Write compile units to the output file. + TG.spawn([&]() { writeCompileUnitsToTheOutput(); }); +} + +void DWARFLinkerImpl::emitStringSections() { + uint64_t DebugStrNextOffset = 0; + uint64_t DebugLineStrNextOffset = 0; + + // Emit zero length string. Accelerator tables does not work correctly + // if the first string is not zero length string. + CommonSections.getSectionDescriptor(DebugSectionKind::DebugStr) + .emitInplaceString(""); + DebugStrNextOffset++; + + forEachOutputString( + [&](StringDestinationKind Kind, const StringEntry *String) { + switch (Kind) { + case StringDestinationKind::DebugStr: { + DwarfStringPoolEntryWithExtString *StringToEmit = + DebugStrStrings.getExistingEntry(String); + assert(StringToEmit->isIndexed()); + + // Strings may be repeated. Use accumulated DebugStrNextOffset + // to understand whether corresponding string is already emitted. + // Skip string if its offset less than accumulated offset. + if (StringToEmit->Offset >= DebugStrNextOffset) { + DebugStrNextOffset = + StringToEmit->Offset + StringToEmit->String.size() + 1; + // Emit the string itself. + CommonSections.getSectionDescriptor(DebugSectionKind::DebugStr) + .emitInplaceString(StringToEmit->String); + } + } break; + case StringDestinationKind::DebugLineStr: { + DwarfStringPoolEntryWithExtString *StringToEmit = + DebugLineStrStrings.getExistingEntry(String); + assert(StringToEmit->isIndexed()); + + // Strings may be repeated. Use accumulated DebugLineStrStrings + // to understand whether corresponding string is already emitted. + // Skip string if its offset less than accumulated offset. + if (StringToEmit->Offset >= DebugLineStrNextOffset) { + DebugLineStrNextOffset = + StringToEmit->Offset + StringToEmit->String.size() + 1; + // Emit the string itself. + CommonSections.getSectionDescriptor(DebugSectionKind::DebugLineStr) + .emitInplaceString(StringToEmit->String); + } + } break; + } }); +} + +void DWARFLinkerImpl::emitAppleAcceleratorSections(const Triple &TargetTriple) { + AccelTable AppleNamespaces; + AccelTable AppleNames; + AccelTable AppleObjC; + AccelTable AppleTypes; + + forEachCompileUnit([&](CompileUnit *CU) { + CU->AcceleratorRecords.forEach([&](const DwarfUnit::AccelInfo &Info) { + switch (Info.Type) { + case DwarfUnit::AccelType::None: { + llvm_unreachable("Unknown accelerator record"); + } break; + case DwarfUnit::AccelType::Namespace: { + AppleNamespaces.addName( + *DebugStrStrings.getExistingEntry(Info.String), + CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset + + Info.OutOffset); + } break; + case DwarfUnit::AccelType::Name: { + AppleNames.addName( + *DebugStrStrings.getExistingEntry(Info.String), + CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset + + Info.OutOffset); + } break; + case DwarfUnit::AccelType::ObjC: { + AppleObjC.addName( + *DebugStrStrings.getExistingEntry(Info.String), + CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset + + Info.OutOffset); + } break; + case DwarfUnit::AccelType::Type: { + AppleTypes.addName( + *DebugStrStrings.getExistingEntry(Info.String), + CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset + + Info.OutOffset, + Info.Tag, + Info.ObjcClassImplementation ? dwarf::DW_FLAG_type_implementation + : 0, + Info.QualifiedNameHash); + } break; + } }); }); - // Emit .debug_line_str section. - TG.spawn([&]() { - uint64_t DebugLineStrNextOffset = 0; + { + // FIXME: we use AsmPrinter to emit accelerator sections. + // It might be beneficial to directly emit accelerator data + // to the raw_svector_ostream. + SectionDescriptor &OutSection = + CommonSections.getSectionDescriptor(DebugSectionKind::AppleNamespaces); + DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, + OutSection.OS); + if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { + consumeError(std::move(Err)); + return; + } - forEachObjectSectionsSet([&](OutputSections &Sections) { - Sections.forEach([&](SectionDescriptor &Section) { - emitStringsImpl(Section.ListDebugLineStrPatch, DebugLineStrStrings, - DebugLineStrNextOffset, OutDebugLineStrSection); - }); + // Emit table. + Emitter.emitAppleNamespaces(AppleNamespaces); + Emitter.finish(); + + // Set start offset and size for output section. + OutSection.setSizesForSectionCreatedByAsmPrinter(); + } + + { + // FIXME: we use AsmPrinter to emit accelerator sections. + // It might be beneficial to directly emit accelerator data + // to the raw_svector_ostream. + SectionDescriptor &OutSection = + CommonSections.getSectionDescriptor(DebugSectionKind::AppleNames); + DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, + OutSection.OS); + if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { + consumeError(std::move(Err)); + return; + } + + // Emit table. + Emitter.emitAppleNames(AppleNames); + Emitter.finish(); + + // Set start offset ans size for output section. + OutSection.setSizesForSectionCreatedByAsmPrinter(); + } + + { + // FIXME: we use AsmPrinter to emit accelerator sections. + // It might be beneficial to directly emit accelerator data + // to the raw_svector_ostream. + SectionDescriptor &OutSection = + CommonSections.getSectionDescriptor(DebugSectionKind::AppleObjC); + DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, + OutSection.OS); + if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { + consumeError(std::move(Err)); + return; + } + + // Emit table. + Emitter.emitAppleObjc(AppleObjC); + Emitter.finish(); + + // Set start offset ans size for output section. + OutSection.setSizesForSectionCreatedByAsmPrinter(); + } + + { + // FIXME: we use AsmPrinter to emit accelerator sections. + // It might be beneficial to directly emit accelerator data + // to the raw_svector_ostream. + SectionDescriptor &OutSection = + CommonSections.getSectionDescriptor(DebugSectionKind::AppleTypes); + DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, + OutSection.OS); + if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { + consumeError(std::move(Err)); + return; + } + + // Emit table. + Emitter.emitAppleTypes(AppleTypes); + Emitter.finish(); + + // Set start offset ans size for output section. + OutSection.setSizesForSectionCreatedByAsmPrinter(); + } +} + +void DWARFLinkerImpl::emitDWARFv5DebugNamesSection(const Triple &TargetTriple) { + std::unique_ptr> DebugNames; + + DebugNamesUnitsOffsets CompUnits; + CompUnitIDToIdx CUidToIdx; + + unsigned Id = 0; + + forEachCompileUnit([&](CompileUnit *CU) { + CompUnits.push_back( + CU->getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo) + .StartOffset); + CUidToIdx[CU->getUniqueID()] = Id++; + + CU->AcceleratorRecords.forEach([&](const DwarfUnit::AccelInfo &Info) { + if (DebugNames.get() == nullptr) + DebugNames = std::make_unique>(); + + switch (Info.Type) { + case DwarfUnit::AccelType::Name: + case DwarfUnit::AccelType::Namespace: + case DwarfUnit::AccelType::Type: { + DebugNames->addName(*DebugStrStrings.getExistingEntry(Info.String), + Info.OutOffset, Info.Tag, CU->getUniqueID()); + } break; + + default: + break; // Nothing to do. + }; }); }); + + if (DebugNames.get() != nullptr) { + // FIXME: we use AsmPrinter to emit accelerator sections. + // It might be beneficial to directly emit accelerator data + // to the raw_svector_ostream. + SectionDescriptor &OutSection = + CommonSections.getSectionDescriptor(DebugSectionKind::DebugNames); + DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, + OutSection.OS); + if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { + consumeError(std::move(Err)); + return; + } + + // Emit table. + Emitter.emitDebugNames(*DebugNames, CompUnits, CUidToIdx); + Emitter.finish(); + + // Set start offset ans size for output section. + OutSection.setSizesForSectionCreatedByAsmPrinter(); + } } -void DWARFLinkerImpl::cleanupDataAfterOutputSectionsAreGenerated() { +void DWARFLinkerImpl::cleanupDataAfterDWARFOutputIsWritten() { GlobalData.getStringPool().clear(); DebugStrStrings.clear(); DebugLineStrStrings.clear(); } -void DWARFLinkerImpl::writeDWARFToTheOutput() { +void DWARFLinkerImpl::writeCompileUnitsToTheOutput() { bool HasAbbreviations = false; + // Enumerate all sections and store them into the final emitter. forEachObjectSectionsSet([&](OutputSections &Sections) { Sections.forEach([&](SectionDescriptor &OutSection) { if (!HasAbbreviations && !OutSection.getContents().empty() && @@ -961,21 +1201,23 @@ // Emit section content. TheDwarfEmitter->emitSectionContents(OutSection.getContents(), OutSection.getName()); - OutSection.erase(); + OutSection.clearSectionContent(); }); }); + if (!HasAbbreviations) { + const SmallVector> Abbreviations; + TheDwarfEmitter->emitAbbrevs(Abbreviations, 3); + } +} + +void DWARFLinkerImpl::writeCommonSectionsToTheOutput() { CommonSections.forEach([&](SectionDescriptor &OutSection) { // Emit section content. TheDwarfEmitter->emitSectionContents(OutSection.getContents(), OutSection.getName()); - OutSection.erase(); + OutSection.clearSectionContent(); }); - - if (!HasAbbreviations) { - const SmallVector> Abbreviations; - TheDwarfEmitter->emitAbbrevs(Abbreviations, 3); - } } } // end of namespace dwarflinker_parallel diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.h b/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.h --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.h +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.h @@ -31,7 +31,9 @@ DwarfUnit(LinkingGlobalData &GlobalData, unsigned ID, StringRef ClangModuleName) : OutputSections(GlobalData), ID(ID), ClangModuleName(ClangModuleName), - OutUnitDIE(nullptr) {} + OutUnitDIE(nullptr) { + AcceleratorRecords.setAllocator(&GlobalData.getAllocator()); + } /// Unique id of the unit. unsigned getUniqueID() const { return ID; } @@ -39,9 +41,6 @@ /// Return language of this unit. uint16_t getLanguage() const { return Language; } - /// Set size of this(newly generated) compile unit. - void setUnitSize(uint64_t UnitSize) { this->UnitSize = UnitSize; } - /// Returns size of this(newly generated) compile unit. uint64_t getUnitSize() const { return UnitSize; } @@ -79,7 +78,12 @@ DIE *getOutUnitDIE() { return OutUnitDIE; } /// Set output unit DIE. - void setOutUnitDIE(DIE *UnitDie) { OutUnitDIE = UnitDie; } + void setOutUnitDIE(DIE *UnitDie) { + OutUnitDIE = UnitDie; + + if (OutUnitDIE != nullptr) + UnitSize = getDebugInfoHeaderSize() + OutUnitDIE->getSize(); + } /// \defgroup Methods used to emit unit's debug info: /// @@ -95,18 +99,30 @@ const DWARFDebugLine::LineTable &OutLineTable); /// @} + /// \defgroup Methods used for reporting warnings and errors: + /// + /// @{ + void warn(const Twine &Warning) { GlobalData.warn(Warning, getUnitName()); } + + void error(const Twine &Err) { GlobalData.warn(Err, getUnitName()); } + /// @} + + /// \defgroup Methods and data members used for building accelerator tables: + /// + /// @{ + + enum class AccelType : uint8_t { None, Name, Namespace, ObjC, Type }; + /// This structure keeps fields which would be used for creating accelerator /// table. struct AccelInfo { - AccelInfo(StringEntry *Name, const DIE *Die, bool SkipPubSection = false); - AccelInfo(StringEntry *Name, const DIE *Die, uint32_t QualifiedNameHash, - bool ObjCClassIsImplementation); + AccelInfo() { + AvoidForPubSections = false; + ObjcClassImplementation = false; + } /// Name of the entry. - StringEntry *Name = nullptr; - - /// Tag of the DIE this entry describes. - dwarf::Tag Tag = dwarf::DW_TAG_null; + StringEntry *String = nullptr; /// Output offset of the DIE this entry describes. uint64_t OutOffset = 0; @@ -114,22 +130,75 @@ /// Hash of the fully qualified name. uint32_t QualifiedNameHash = 0; - /// Emit this entry only in the apple_* sections. - bool SkipPubSection = false; + /// Tag of the DIE this entry describes. + dwarf::Tag Tag = dwarf::DW_TAG_null; + + /// Type of this accelerator record. + AccelType Type = AccelType::None; - /// Is this an ObjC class implementation? - bool ObjcClassImplementation = false; + /// Avoid using this entry for pub sections. + bool AvoidForPubSections : 1; - /// Cloned Die containing acceleration info. - const DIE *Die = nullptr; + /// Is this an ObjC class implementation? + bool ObjcClassImplementation : 1; }; - /// \defgroup Methods used for reporting warnings and errors: - /// - /// @{ - void warn(const Twine &Warning) { GlobalData.warn(Warning, getUnitName()); } + void rememberNameForAccelerators(StringEntry *Name, uint64_t OutOffset, + dwarf::Tag Tag, bool AvoidForPubSections) { + AccelInfo Info; + + Info.Type = AccelType::Name; + Info.String = Name; + Info.OutOffset = OutOffset; + Info.Tag = Tag; + Info.AvoidForPubSections = AvoidForPubSections; + + AcceleratorRecords.add(Info); + } + void rememberNamespaceForAccelerators(StringEntry *Name, uint64_t OutOffset, + dwarf::Tag Tag) { + AccelInfo Info; + + Info.Type = AccelType::Namespace; + Info.String = Name; + Info.OutOffset = OutOffset; + Info.Tag = Tag; + + AcceleratorRecords.add(Info); + } + void rememberObjCNameForAccelerators(StringEntry *Name, uint64_t OutOffset, + dwarf::Tag Tag) { + AccelInfo Info; + + Info.Type = AccelType::ObjC; + Info.String = Name; + Info.OutOffset = OutOffset; + Info.Tag = Tag; + Info.AvoidForPubSections = true; + + AcceleratorRecords.add(Info); + } + void rememberTypeForAccelerators(StringEntry *Name, uint64_t OutOffset, + dwarf::Tag Tag, uint32_t QualifiedNameHash, + bool ObjcClassImplementation) { + AccelInfo Info; + + Info.Type = AccelType::Type; + Info.String = Name; + Info.OutOffset = OutOffset; + Info.Tag = Tag; + Info.QualifiedNameHash = QualifiedNameHash; + Info.ObjcClassImplementation = ObjcClassImplementation; + + AcceleratorRecords.add(Info); + } + + /// Emit .debug_pubnames and .debug_pubtypes for \p Unit. + void emitPubAccelerators(); + + /// Accelerator tables data. + ArrayList AcceleratorRecords; - void error(const Twine &Err) { GlobalData.warn(Err, getUnitName()); } /// @} protected: @@ -137,6 +206,12 @@ void emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev, SectionDescriptor &AbbrevSection); + /// Emit single pubnames/pubtypes accelerator entry. + std::optional + emitPubAcceleratorEntry(SectionDescriptor &OutSection, + DwarfUnit::AccelInfo &Info, + std::optional LengthOffset); + /// Unique ID for the unit. unsigned ID = 0; diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.cpp b/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.cpp --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.cpp +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.cpp @@ -126,5 +126,83 @@ return DebugLineEmitter.emit(OutLineTable); } +/// Emit the pubnames or pubtypes section contribution for \p +/// Unit into \p Sec. The data is provided in \p Info. +std::optional +DwarfUnit::emitPubAcceleratorEntry(SectionDescriptor &OutSection, + DwarfUnit::AccelInfo &Info, + std::optional LengthOffset) { + if (!LengthOffset) { + // Emit the header. + OutSection.emitIntVal(0xBADDEF, + getFormParams().getDwarfOffsetByteSize()); // Length + LengthOffset = OutSection.OS.tell(); + + OutSection.emitIntVal(dwarf::DW_PUBNAMES_VERSION, 2); // Version + + OutSection.notePatch(DebugOffsetPatch{ + OutSection.OS.tell(), + &getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)}); + OutSection.emitOffset(0xBADDEF); // Unit offset + + OutSection.emitIntVal(getUnitSize(), 4); // Size + } + OutSection.emitOffset(Info.OutOffset); + + // Emit the string itself. + OutSection.emitInplaceString(Info.String->first()); + + return LengthOffset; +} + +/// Emit .debug_pubnames and .debug_pubtypes for \p Unit. +void DwarfUnit::emitPubAccelerators() { + std::optional NamesLengthOffset; + std::optional TypesLengthOffset; + + AcceleratorRecords.forEach([&](DwarfUnit::AccelInfo &Info) { + if (Info.AvoidForPubSections) + return; + + switch (Info.Type) { + case DwarfUnit::AccelType::Name: { + NamesLengthOffset = emitPubAcceleratorEntry( + getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames), Info, + NamesLengthOffset); + } break; + case DwarfUnit::AccelType::Type: { + TypesLengthOffset = emitPubAcceleratorEntry( + getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes), Info, + TypesLengthOffset); + } break; + default: { + // Nothing to do. + } break; + } + }); + + if (NamesLengthOffset) { + SectionDescriptor &OutSection = + getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames); + OutSection.emitIntVal(0, 4); // End marker. + + OutSection.apply(*NamesLengthOffset - + OutSection.getFormParams().getDwarfOffsetByteSize(), + dwarf::DW_FORM_sec_offset, + OutSection.OS.tell() - *NamesLengthOffset); + } + + if (TypesLengthOffset) { + SectionDescriptor &OutSection = + getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes); + OutSection.emitIntVal(0, 4); // End marker. + + OutSection.apply(*TypesLengthOffset - + OutSection.getFormParams().getDwarfOffsetByteSize(), + dwarf::DW_FORM_sec_offset, + OutSection.OS.tell() - *TypesLengthOffset); + } +} + } // end of namespace dwarflinker_parallel } // end of namespace llvm diff --git a/llvm/lib/DWARFLinkerParallel/DependencyTracker.cpp b/llvm/lib/DWARFLinkerParallel/DependencyTracker.cpp --- a/llvm/lib/DWARFLinkerParallel/DependencyTracker.cpp +++ b/llvm/lib/DWARFLinkerParallel/DependencyTracker.cpp @@ -221,53 +221,28 @@ // Resolve reference. std::optional> RefDie = - CU.resolveDIEReference(Val); + CU.resolveDIEReference( + Val, Context.InterCUProcessingStarted + ? ResolveInterCUReferencesMode::Resolve + : ResolveInterCUReferencesMode::AvoidResolving); if (!RefDie) { CU.warn("cann't find referenced DIE", Entry); continue; } - if (CU.getUniqueID() == RefDie->first->getUniqueID()) { - // Check if referenced DIE entry is already kept. - if (RefDie->first->getDIEInfo(RefDie->second).getKeep()) - continue; - - // If referenced DIE is inside current compilation unit. - const DWARFDebugInfoEntry *RefEntry = - RefDie->first->getDebugInfoEntry(RefDie->second); - - if (RootItem.RootEntry->getTag() == dwarf::DW_TAG_compile_unit) - addItemToWorklist(*RefDie->first, RefEntry); - else { - uint64_t RootStartOffset = RootItem.RootEntry->getOffset(); - uint64_t RootEndOffset; - if (std::optional SiblingIdx = - RootItem.RootEntry->getSiblingIdx()) { - RootEndOffset = - RootItem.CU.getDebugInfoEntry(*SiblingIdx)->getOffset(); - } else { - RootEndOffset = RootItem.CU.getOrigUnit().getNextUnitOffset(); - } - - // Do not put item in work list if it is an ancestor of RootItem. - // (since we will visit and mark it as kept during normal traversing of - // RootItem children) - if (RootStartOffset > RefEntry->getOffset() || - RefEntry->getOffset() >= RootEndOffset) - addItemToWorklist(*RefDie->first, RefEntry); - } - } else if (Context.InterCUProcessingStarted && RefDie->second != 0) { - // If referenced DIE is in other compilation unit and - // it is safe to navigate other units DIEs. - addItemToWorklist(*RefDie->first, - RefDie->first->getDebugInfoEntry(RefDie->second)); - } else { + if (RefDie->second == 0) { // Delay resolving reference. RefDie->first->setInterconnectedCU(); CU.setInterconnectedCU(); Context.HasNewInterconnectedCUs = true; return false; } + + assert(CU.getUniqueID() == RefDie->first->getUniqueID() || + Context.InterCUProcessingStarted); + + addItemToWorklist(*RefDie->first, + RefDie->first->getDebugInfoEntry(RefDie->second)); } return true; diff --git a/llvm/lib/DWARFLinkerParallel/OutputSections.h b/llvm/lib/DWARFLinkerParallel/OutputSections.h --- a/llvm/lib/DWARFLinkerParallel/OutputSections.h +++ b/llvm/lib/DWARFLinkerParallel/OutputSections.h @@ -21,6 +21,7 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/raw_ostream.h" @@ -47,6 +48,13 @@ DebugStr, DebugLineStr, DebugStrOffsets, + DebugPubNames, + DebugPubTypes, + DebugNames, + AppleNames, + AppleNamespaces, + AppleObjC, + AppleTypes, NumberOfEnumEntries // must be last }; constexpr static size_t SectionKindsNum = @@ -143,8 +151,11 @@ ListDebugOffsetPatch.setAllocator(&GlobalData.getAllocator()); } - /// Erase whole section contents(data bits, list of patches, format). - void erase(); + /// Erase whole section contents(data bits, list of patches). + void clearAllSectionData(); + + /// Erase only section output data bits. + void clearSectionContent(); /// When objects(f.e. compile units) are glued into the single file, /// the debug sections corresponding to the concrete object are assigned @@ -157,7 +168,7 @@ /// Section patches. #define ADD_PATCHES_LIST(T) \ - T ¬ePatch(const T &Patch) { return List##T.noteItem(Patch); } \ + T ¬ePatch(const T &Patch) { return List##T.add(Patch); } \ ArrayList List##T; ADD_PATCHES_LIST(DebugStrPatch) @@ -216,7 +227,7 @@ /// Emit specified inplace string value into the current section contents. void emitInplaceString(StringRef String) { - OS << String; + OS << GlobalData.translateString(String); emitIntVal(0, 1); } @@ -295,10 +306,42 @@ } /// Returns descriptor for the specified section of \p SectionKind. - std::optional + /// The descriptor should already be created. The llvm_unreachable + /// would be raised if it is not. + const SectionDescriptor & getSectionDescriptor(DebugSectionKind SectionKind) const { SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind); + if (It == SectionDescriptors.end()) + llvm_unreachable( + formatv("Section {0} does not exist", getSectionName(SectionKind)) + .str() + .c_str()); + + return It->second; + } + + /// Returns descriptor for the specified section of \p SectionKind. + /// The descriptor should already be created. The llvm_unreachable + /// would be raised if it is not. + SectionDescriptor &getSectionDescriptor(DebugSectionKind SectionKind) { + SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind); + + if (It == SectionDescriptors.end()) + llvm_unreachable( + formatv("Section {0} does not exist", getSectionName(SectionKind)) + .str() + .c_str()); + + return It->second; + } + + /// Returns descriptor for the specified section of \p SectionKind. + /// Returns std::nullopt if section descriptor is not created yet. + std::optional + tryGetSectionDescriptor(DebugSectionKind SectionKind) const { + SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind); + if (It == SectionDescriptors.end()) return std::nullopt; @@ -306,8 +349,9 @@ } /// Returns descriptor for the specified section of \p SectionKind. + /// Returns std::nullopt if section descriptor is not created yet. std::optional - getSectionDescriptor(DebugSectionKind SectionKind) { + tryGetSectionDescriptor(DebugSectionKind SectionKind) { SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind); if (It == SectionDescriptors.end()) @@ -317,7 +361,7 @@ } /// Returns descriptor for the specified section of \p SectionKind. - /// If descriptor does not exist then create it. + /// If descriptor does not exist then creates it. SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind) { return SectionDescriptors @@ -328,7 +372,7 @@ /// Erases data of all sections. void eraseSections() { for (auto &Section : SectionDescriptors) - Section.second.erase(); + Section.second.clearAllSectionData(); } /// Enumerate all sections and call \p Handler for each. diff --git a/llvm/lib/DWARFLinkerParallel/OutputSections.cpp b/llvm/lib/DWARFLinkerParallel/OutputSections.cpp --- a/llvm/lib/DWARFLinkerParallel/OutputSections.cpp +++ b/llvm/lib/DWARFLinkerParallel/OutputSections.cpp @@ -14,10 +14,12 @@ namespace dwarflinker_parallel { static constexpr StringLiteral SectionNames[SectionKindsNum] = { - "debug_info", "debug_line", "debug_frame", "debug_ranges", - "debug_rnglists", "debug_loc", "debug_loclists", "debug_aranges", - "debug_abbrev", "debug_macinfo", "debug_macro", "debug_addr", - "debug_str", "debug_line_str", "debug_str_offsets"}; + "debug_info", "debug_line", "debug_frame", "debug_ranges", + "debug_rnglists", "debug_loc", "debug_loclists", "debug_aranges", + "debug_abbrev", "debug_macinfo", "debug_macro", "debug_addr", + "debug_str", "debug_line_str", "debug_str_offsets", "debug_pubnames", + "debug_pubtypes", "debug_names", "apple_names", "apple_namespac", + "apple_objc", "apple_types"}; const StringLiteral &getSectionName(DebugSectionKind SectionKind) { return SectionNames[static_cast(SectionKind)]; @@ -56,6 +58,20 @@ DebugSectionKind::DebugLineStr) .Case(getSectionName(DebugSectionKind::DebugStrOffsets), DebugSectionKind::DebugStrOffsets) + .Case(getSectionName(DebugSectionKind::DebugPubNames), + DebugSectionKind::DebugPubNames) + .Case(getSectionName(DebugSectionKind::DebugPubTypes), + DebugSectionKind::DebugPubTypes) + .Case(getSectionName(DebugSectionKind::DebugNames), + DebugSectionKind::DebugNames) + .Case(getSectionName(DebugSectionKind::AppleNames), + DebugSectionKind::AppleNames) + .Case(getSectionName(DebugSectionKind::AppleNamespaces), + DebugSectionKind::AppleNamespaces) + .Case(getSectionName(DebugSectionKind::AppleObjC), + DebugSectionKind::AppleObjC) + .Case(getSectionName(DebugSectionKind::AppleTypes), + DebugSectionKind::AppleTypes) .Default(std::nullopt); return std::nullopt; @@ -76,9 +92,9 @@ RefCU(RefCU, SrcCU->getUniqueID() == RefCU->getUniqueID()), RefDieIdxOrClonedOffset(RefIdx) {} -void SectionDescriptor::erase() { +void SectionDescriptor::clearAllSectionData() { StartOffset = 0; - Contents = OutSectionDataTy(); + clearSectionContent(); ListDebugStrPatch.erase(); ListDebugLineStrPatch.erase(); ListDebugRangePatch.erase(); @@ -88,6 +104,8 @@ ListDebugOffsetPatch.erase(); } +void SectionDescriptor::clearSectionContent() { Contents = OutSectionDataTy(); } + void SectionDescriptor::setSizesForSectionCreatedByAsmPrinter() { if (Contents.empty()) return; @@ -107,7 +125,6 @@ consumeError(SectNameOrErr.takeError()); continue; } - if (std::optional SectKind = parseDebugTableName(*SectNameOrErr)) { if (*SectKind == SectionKind) { @@ -160,7 +177,7 @@ switch (StringForm) { case dwarf::DW_FORM_string: { - emitInplaceString(GlobalData.translateString(StringVal)); + emitInplaceString(StringVal); } break; case dwarf::DW_FORM_strp: { notePatch(DebugStrPatch{ @@ -333,9 +350,9 @@ std::optional RangeSection; if (Format.Version >= 5) - RangeSection = getSectionDescriptor(DebugSectionKind::DebugRngLists); + RangeSection = tryGetSectionDescriptor(DebugSectionKind::DebugRngLists); else - RangeSection = getSectionDescriptor(DebugSectionKind::DebugRange); + RangeSection = tryGetSectionDescriptor(DebugSectionKind::DebugRange); if (RangeSection) { Section.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) { @@ -349,9 +366,9 @@ std::optional LocationSection; if (Format.Version >= 5) - LocationSection = getSectionDescriptor(DebugSectionKind::DebugLocLists); + LocationSection = tryGetSectionDescriptor(DebugSectionKind::DebugLocLists); else - LocationSection = getSectionDescriptor(DebugSectionKind::DebugLoc); + LocationSection = tryGetSectionDescriptor(DebugSectionKind::DebugLoc); if (LocationSection) { Section.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) { @@ -367,17 +384,14 @@ uint64_t FinalOffset = Patch.RefDieIdxOrClonedOffset; dwarf::Form FinalForm = dwarf::DW_FORM_ref4; + // Check whether it is local or inter-CU reference. if (!Patch.RefCU.getInt()) { - std::optional ReferencedSectionDescriptor = + SectionDescriptor &ReferencedSectionDescriptor = Patch.RefCU.getPointer()->getSectionDescriptor( DebugSectionKind::DebugInfo); - if (!ReferencedSectionDescriptor) { - // Referenced section should be already created at this point. - llvm_unreachable("Referenced section does not exist"); - } FinalForm = dwarf::DW_FORM_ref_addr; - FinalOffset += (*ReferencedSectionDescriptor)->StartOffset; + FinalOffset += ReferencedSectionDescriptor.StartOffset; } Section.apply(Patch.PatchOffset, FinalForm, FinalOffset); @@ -392,6 +406,8 @@ Section.ListDebugOffsetPatch.forEach([&](DebugOffsetPatch &Patch) { uint64_t FinalValue = Patch.SectionPtr.getPointer()->StartOffset; + + // Check whether we need to read value from the original location. if (Patch.SectionPtr.getInt()) FinalValue += Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize()); diff --git a/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/dwarf5-dwarf4-combination-macho.test b/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/dwarf5-dwarf4-combination-macho.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/dwarf5-dwarf4-combination-macho.test +++ /dev/null @@ -1,200 +0,0 @@ -; This test checks to ensure that if a DWARF v5 and DWARF v4 object file is used to -; generate a dsym, dsymutil correctly outputs the debug information, by keeping -; the DWARF v5 and DWARF v4 debug info distinct, and that all the section headers -; have the correct format. - -; 1.o was produced with the source file: - -; a.cpp -; __attribute__((section("1,__text_foo"))) void foo() {} -; -; int foo2(int a) { -; return a+5; -; } -; int main () { -; return 1; -; } - -; clang -g -c -O1 a.cpp -Xclang -gdwarf-5 -o 1.o - -; 2.o was produced with the following source file: - -; b.cpp -; __attribute__((section("1,__text_foo2"))) void foo2() {} -; -; int bar(int x) { -; int y = x + 2; -; return y; -; } - -; clang -g -c -O1 b.cpp -gdwarf-4 -o 2.o - - -RUN: rm -rf %t.dir && mkdir -p %t.dir -RUN: dsymutil --linker llvm -y %p/../dummy-debug-map-amr64.map \ -RUN: -oso-prepend-path=%p/../../Inputs/DWARF5-DWARF4-combination \ -RUN: -o %t.dir/dwarf5-dwarf4-combination-macho.dSYM -RUN: llvm-dwarfdump %t.dir/dwarf5-dwarf4-combination-macho.dSYM -a --verbose | FileCheck %s - - -CHECK:.debug_abbrev contents: -CHECK-NEXT: Abbrev table for offset: 0x00000000 - -CHECK: .debug_info contents: -CHECK: 0x00000000: Compile Unit: length = 0x0000004a, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 -CHECK: DW_AT_producer [DW_FORM_strx] (indexed (00000000) string = "Apple clang version 14.0.3 (clang-1403.0.22.14.1)") -CHECK: DW_AT_name [DW_FORM_strx] (indexed (00000001) string = "a.cpp") -CHECK: DW_AT_LLVM_sysroot [DW_FORM_strx] (indexed (00000002) string = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk") -CHECK: DW_AT_APPLE_sdk [DW_FORM_strx] (indexed (00000003) string = "MacOSX.sdk") -CHECK: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008) -CHECK: DW_AT_comp_dir [DW_FORM_strx] (indexed (00000004) string = "/Users/shubham/Development/test109275485") -CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x[[RANGELIST_OFFSET:[0-9a-f]+]] -CHECK-NEXT: [0x[[RANGELIST_OFFSET_START:[0-9a-f]+]], 0x[[RANGELIST_OFFSET_END:[0-9a-f]+]])) -CHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) -CHECK: 0x0000002c: DW_TAG_subprogram [2] * (0x0000000c) -CHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x[[#%.16x,LOCLIST_LOWPC:]]) -CHECK: DW_AT_linkage_name [DW_FORM_strx] (indexed (00000005) string = "_Z4foo2i") -CHECK: DW_AT_name [DW_FORM_strx] (indexed (00000006) string = "foo2") -CHECK: 0x0000003c: DW_TAG_formal_parameter [3] (0x0000002c) -CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x[[LOCLIST_OFFSET:[0-9a-f]+]]: -CHECK-NEXT: [0x[[#%.16x,LOCLIST_PAIR_START:]], 0x[[#%.16x,LOCLIST_PAIR_END:]]): [[LOCLIST_EXPR:.*]] -CHECK-NEXT: [0x[[#%.16x,LOCLIST_PAIR_START2:]], 0x[[#%.16x,LOCLIST_PAIR_END2:]]): [[LOCLIST_EXPR2:.*]]) -CHECK: DW_AT_name [DW_FORM_strx] (indexed (00000007) string = "a") - -CHECK: 0x0000004e: Compile Unit: length = 0x00000072, format = DWARF32, version = 0x0004, abbr_offset = 0x005a, addr_size = 0x08 -CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "Apple clang version 14.0.3 (clang-1403.0.22.14.1)") -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x000000e0] = "b.cpp") -CHECK: DW_AT_LLVM_sysroot [DW_FORM_strp] ( .debug_str[0x00000039] = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk") -CHECK: DW_AT_APPLE_sdk [DW_FORM_strp] ( .debug_str[0x00000098] = "MacOSX.sdk") -CHECK-NOT: DW_AT_str_offsets_base -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x000000a3] = "/Users/shubham/Development/test109275485") -CHECK: DW_AT_low_pc [DW_FORM_addr] (0x[[#%.16x,RANGE_LOWPC:]]) -CHECK-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 -CHECK-NEXT: [0x[[#%.16x,RANGE_START:]], 0x[[#%.16x,RANGE_END:]])) -CHECK: 0x00000080: DW_TAG_subprogram {{.*}} * (0x00000059) -CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x[[#%.16x,LOC_LOWPC:]]) -CHECK: DW_AT_linkage_name [DW_FORM_strp] ( .debug_str[0x000000e6] = "_Z3bari") -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x000000ee] = "bar") -CHECK: 0x0000009d: DW_TAG_formal_parameter {{.*}} (0x00000080) -CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x[[LOC_OFFSET:[0-9a-f]+]]: -CHECK-NEXT: [0x[[#%.16x,LOC_PAIR_START:]], 0x[[#%.16x,LOC_PAIR_END:]]): [[LOC_EXPR:.*]] -CHECK-NEXT: [0x[[#%.16x,LOC_PAIR_START2:]], 0x[[#%.16x,LOC_PAIR_END2:]]): [[LOC_EXPR2:.*]]) -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x000000f2] = "x") - -CHECK: .debug_loc contents: -CHECK-NEXT: 0x[[LOC_OFFSET]]: -CHECK-NEXT: (0x[[#sub(LOC_PAIR_START,LOC_LOWPC)]], 0x[[#sub(LOC_PAIR_END,LOC_LOWPC)]]): [[LOC_EXPR:.*]] -CHECK-NEXT: (0x[[#sub(LOC_PAIR_START2,LOC_LOWPC)]], 0x[[#sub(LOC_PAIR_END2,LOC_LOWPC)]]): [[LOC_EXPR2:.*]] - -CHECK: .debug_loclists contents: -CHECK-NEXT: 0x00000000: locations list header: length = 0x00000018, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 -CHECK-NEXT: 0x[[LOCLIST_OFFSET]]: -CHECK-NEXT: DW_LLE_base_addressx (0x0000000000000000) -CHECK-NEXT: DW_LLE_offset_pair (0x[[#sub(LOCLIST_PAIR_START,LOCLIST_LOWPC)]], 0x[[#sub(LOCLIST_PAIR_END,LOCLIST_LOWPC)]]) -CHECK-NEXT: DW_LLE_offset_pair (0x[[#sub(LOCLIST_PAIR_START2,LOCLIST_LOWPC)]], 0x[[#sub(LOCLIST_PAIR_END2,LOCLIST_LOWPC)]]) -CHECK-NEXT: DW_LLE_end_of_list () - -CHECK: .debug_line contents: -CHECK-NEXT: debug_line[0x00000000] -CHECK-NEXT: Line table prologue: -CHECK-NEXT: total_length: 0x00000048 -CHECK-NEXT: format: DWARF32 -CHECK-NEXT: version: 5 -CHECK-NEXT: address_size: 8 -CHECK-NEXT: seg_select_size: 0 -CHECK-NEXT: prologue_length: 0x00000025 -CHECK-NEXT: min_inst_length: 1 -CHECK-NEXT: max_ops_per_inst: 1 -CHECK-NEXT: default_is_stmt: 1 -CHECK-NEXT: line_base: -5 -CHECK-NEXT: line_range: 14 -CHECK-NEXT: opcode_base: 13 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_copy] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_advance_pc] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_advance_line] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_file] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_column] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_negate_stmt] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_basic_block] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_const_add_pc] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_prologue_end] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_isa] = 1 -CHECK-NEXT: include_directories[ 0] = .debug_line_str[0x00000000] = "/Users/shubham/Development/test109275485" -CHECK-NEXT: file_names[ 0]: -CHECK-NEXT: name: .debug_line_str[0x00000029] = "a.cpp" -CHECK-NEXT: dir_index: 0 - -CHECK: debug_line[0x0000004c] -CHECK-NEXT: Line table prologue: -CHECK-NEXT: total_length: 0x0000003b -CHECK-NEXT: format: DWARF32 -CHECK-NEXT: version: 4 -CHECK-NEXT: prologue_length: 0x0000001d -CHECK-NEXT: min_inst_length: 1 -CHECK-NEXT: max_ops_per_inst: 1 -CHECK-NEXT: default_is_stmt: 1 -CHECK-NEXT: line_base: -5 -CHECK-NEXT: line_range: 14 -CHECK-NEXT: opcode_base: 13 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_copy] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_advance_pc] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_advance_line] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_file] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_column] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_negate_stmt] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_basic_block] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_const_add_pc] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_prologue_end] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_isa] = 1 -CHECK-NEXT: file_names[ 1]: -CHECK-NEXT: name: "b.cpp" -CHECK-NEXT: dir_index: 0 -CHECK-NEXT: mod_time: 0x00000000 -CHECK-NEXT: length: 0x00000000 - -CHECK: .debug_str contents: -CHECK-NEXT: 0x00000000: "" -CHECK-NEXT: 0x00000001: "Apple clang version 14.0.3 (clang-1403.0.22.14.1)" -CHECK-NEXT: 0x00000033: "a.cpp" -CHECK-NEXT: 0x00000039: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" -CHECK-NEXT: 0x00000098: "MacOSX.sdk" -CHECK-NEXT: 0x000000a3: "/Users/shubham/Development/test109275485" -CHECK-NEXT: 0x000000cc: "_Z4foo2i" -CHECK-NEXT: 0x000000d5: "foo2" -CHECK-NEXT: 0x000000da: "a" -CHECK-NEXT: 0x000000dc: "int" -CHECK-NEXT: 0x000000e0: "b.cpp" -CHECK-NEXT: 0x000000e6: "_Z3bari" -CHECK-NEXT: 0x000000ee: "bar" -CHECK-NEXT: 0x000000f2: "x" -CHECK-NEXT: 0x000000f4: "y" - -CHECK: .debug_line_str contents: -CHECK-NEXT: 0x00000000: "/Users/shubham/Development/test109275485" -CHECK-NEXT: 0x00000029: "a.cpp" - -CHECK: .debug_ranges contents: -CHECK-NEXT: 00000000 [[#sub(RANGE_START,RANGE_LOWPC)]] [[#sub(RANGE_END,RANGE_LOWPC)]] - -CHECK: .debug_rnglists contents: -CHECK-NEXT: 0x00000000: range list header: length = 0x0000000e, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 -CHECK-NEXT: ranges: -CHECK-NEXT: [[RANGELIST_OFFSET]]: [DW_RLE_base_addressx]: 0x0000000000000000 -CHECK-NEXT: 0x0000000e: [DW_RLE_offset_pair ]: {{.*}}[0x[[RANGELIST_OFFSET_START]], 0x[[RANGELIST_OFFSET_END]]) -CHECK-NEXT: 0x00000011: [DW_RLE_end_of_list ] - -CHECK: .debug_str_offsets contents: -CHECK-NEXT: 0x00000000: Contribution size = 40, Format = DWARF32, Version = 5 -CHECK-NEXT: 0x00000008: 00000001 "Apple clang version 14.0.3 (clang-1403.0.22.14.1)" -CHECK-NEXT: 0x0000000c: 00000033 "a.cpp" -CHECK-NEXT: 0x00000010: 00000039 "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" -CHECK-NEXT: 0x00000014: 00000098 "MacOSX.sdk" -CHECK-NEXT: 0x00000018: 000000a3 "/Users/shubham/Development/test109275485" -CHECK-NEXT: 0x0000001c: 000000cc "_Z4foo2i" -CHECK-NEXT: 0x00000020: 000000d5 "foo2" -CHECK-NEXT: 0x00000024: 000000da "a" -CHECK-NEXT: 0x00000028: 000000dc "int" diff --git a/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/dwarf5-macho.test b/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/dwarf5-macho.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/dwarf5-macho.test +++ /dev/null @@ -1,92 +0,0 @@ -; This test checks to that DWARF v5 debug info can be correctly linked -; into a dSYM bundle by dsymutil, with the correct section names and DWARF v5 -; headers for the different sections. - -; 1.o was produced with the source file: - -; a.cpp -; __attribute__((section("1,__text_foo"))) void foo() {} -; -; int foo2(int a) { -; return a+5; -; } -; int main () { -; return 1; -; } - -; clang -g -c -O1 a.cpp -Xclang -gdwarf-5 -o 1.o - - -RUN: rm -rf %t.dir && mkdir -p %t.dir -RUN: dsymutil --linker llvm -y %p/../dummy-debug-map-amr64.map \ -RUN: -oso-prepend-path=%p/../../Inputs/DWARF5 -o %t.dir/dwarf5-macho.dSYM -RUN: llvm-dwarfdump %t.dir/dwarf5-macho.dSYM -a --verbose | FileCheck %s - -CHECK:.debug_abbrev contents: -CHECK-NEXT: Abbrev table for offset: 0x00000000 - -CHECK: .debug_info contents: -CHECK-NEXT: Compile Unit: length = 0x0000004a, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 -CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x[[RANGELIST_OFFSET:[0-9a-f]+]] -CHECK-NEXT: [0x[[RANGELIST_OFFSET_START:[0-9a-f]+]], 0x[[RANGELIST_OFFSET_END:[0-9a-f]+]])) -CHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) -CHECK: 0x0000002c: DW_TAG_subprogram [2] * (0x0000000c) -CHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x[[#%.16x,LOCLIST_LOWPC:]]) -CHECK: 0x0000003c: DW_TAG_formal_parameter [3] (0x0000002c) -CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x[[LOC_OFFSET:[0-9a-f]+]]: -CHECK-NEXT: [0x[[#%.16x,LOCLIST_PAIR_START:]], 0x[[#%.16x,LOCLIST_PAIR_END:]]): [[LOCLIST_EXPR:.*]] -CHECK-NEXT: [0x[[#%.16x,LOCLIST_PAIR_START2:]], 0x[[#%.16x,LOCLIST_PAIR_END2:]]): [[LOCLIST_EXPR2:.*]]) - -CHECK: .debug_loclists contents: -CHECK-NEXT: 0x00000000: locations list header: length = 0x00000018, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 -CHECK-NEXT: 0x[[LOC_OFFSET]]: -CHECK-NEXT: DW_LLE_base_addressx (0x0000000000000000) -CHECK-NEXT: DW_LLE_offset_pair (0x[[#sub(LOCLIST_PAIR_START,LOCLIST_LOWPC)]], 0x[[#sub(LOCLIST_PAIR_END,LOCLIST_LOWPC)]]) -CHECK-NEXT: DW_LLE_offset_pair (0x[[#sub(LOCLIST_PAIR_START2,LOCLIST_LOWPC)]], 0x[[#sub(LOCLIST_PAIR_END2,LOCLIST_LOWPC)]]) -CHECK-NEXT: DW_LLE_end_of_list () - -CHECK: .debug_line contents: -CHECK-NEXT: debug_line[0x00000000] -CHECK-NEXT: Line table prologue: -CHECK-NEXT: total_length: 0x00000048 -CHECK-NEXT: format: DWARF32 -CHECK-NEXT: version: 5 -CHECK-NEXT: address_size: 8 -CHECK-NEXT: seg_select_size: 0 -CHECK-NEXT: prologue_length: 0x00000025 -CHECK-NEXT: min_inst_length: 1 -CHECK-NEXT: max_ops_per_inst: 1 -CHECK-NEXT: default_is_stmt: 1 -CHECK-NEXT: line_base: -5 -CHECK-NEXT: line_range: 14 -CHECK-NEXT: opcode_base: 13 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_copy] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_advance_pc] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_advance_line] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_file] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_column] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_negate_stmt] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_basic_block] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_const_add_pc] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_prologue_end] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0 -CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_isa] = 1 -CHECK-NEXT: include_directories[ 0] = .debug_line_str[0x00000000] = "/Users/shubham/Development/test109275485" -CHECK-NEXT: file_names[ 0]: -CHECK-NEXT: name: .debug_line_str[0x00000029] = "a.cpp" -CHECK-NEXT: dir_index: 0 - - -CHECK: .debug_str contents: - -CHECK: .debug_line_str contents: -CHECK-NEXT: 0x00000000: "/Users/shubham/Development/test109275485" -CHECK-NEXT: 0x00000029: "a.cpp" - -CHECK: .debug_rnglists contents: -CHECK-NEXT: 0x00000000: range list header: length = 0x0000000e, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 -CHECK-NEXT: ranges: -CHECK-NEXT: [[RANGELIST_OFFSET]]: [DW_RLE_base_addressx]: 0x0000000000000000 -CHECK-NEXT: 0x0000000e: [DW_RLE_offset_pair ]: {{.*}}[0x[[RANGELIST_OFFSET_START]], 0x[[RANGELIST_OFFSET_END]]) -CHECK-NEXT: 0x00000011: [DW_RLE_end_of_list ] diff --git a/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/fat-dylib-update.test b/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/fat-dylib-update.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/fat-dylib-update.test +++ /dev/null @@ -1,110 +0,0 @@ -# REQUIRES: object-emission,system-darwin -# RUN: dsymutil --linker llvm -oso-prepend-path %p/../.. %p/../../Inputs/fat-test.arm.dylib -o %t.dSYM -# RUN: llvm-dwarfdump -a -v %t.dSYM/Contents/Resources/DWARF/fat-test.arm.dylib | FileCheck %s -# RUN: dsymutil --linker llvm -u %t.dSYM -# RUN: llvm-dwarfdump -a -v %t.dSYM/Contents/Resources/DWARF/fat-test.arm.dylib | FileCheck %s -# RUN: dsymutil --linker llvm -u %t.dSYM -o %t1.dSYM -# RUN: llvm-dwarfdump -a -v %t1.dSYM/Contents/Resources/DWARF/fat-test.arm.dylib | FileCheck %s - -CHECK: /Contents/Resources/DWARF/fat-test.arm.dylib(armv7): file format Mach-O arm - -CHECK: .debug_info contents: -CHECK: Compile Unit: length = 0x00000034, format = DWARF32, version = 0x0002, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x00000038) -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "clang version 3.8.0 (trunk 243776)") -CHECK: DW_AT_language [DW_FORM_data2] (DW_LANG_C99) -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000024] = "fat-test.c") -CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x00000000) -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000002f] = "/Inputs") -CHECK: DW_TAG_variable [2] -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000037] = "armv7_var") -CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x0030 => {0x00000030} -CHECK: DW_AT_external [DW_FORM_flag] (0x01) -CHECK: DW_AT_decl_file [DW_FORM_data1] ("/Inputs/fat-test.c") -CHECK: DW_AT_decl_line [DW_FORM_data1] (23) -CHECK: DW_AT_location [DW_FORM_block1] (DW_OP_addr 0x1000) -CHECK: DW_TAG_base_type [3] -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000041] = "int") -CHECK: DW_AT_encoding [DW_FORM_data1] (DW_ATE_signed) -CHECK: DW_AT_byte_size [DW_FORM_data1] (0x04) -CHECK: NULL - - -CHECK: .debug_line contents: -CHECK: Line table prologue: -CHECK: total_length: 0x0000002a -CHECK: version: 2 -CHECK: prologue_length: 0x00000021 -CHECK: min_inst_length: 1 -CHECK: default_is_stmt: 1 -CHECK: line_base: -5 -CHECK: line_range: 14 -CHECK: opcode_base: 13 - -CHECK: /Contents/Resources/DWARF/fat-test.arm.dylib(armv7s): file format Mach-O arm - -CHECK: .debug_info contents: -CHECK: Compile Unit: length = 0x00000034, format = DWARF32, version = 0x0002, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x00000038) -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "clang version 3.8.0 (trunk 243776)") -CHECK: DW_AT_language [DW_FORM_data2] (DW_LANG_C99) -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000024] = "fat-test.c") -CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x00000000) -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000002f] = "/Inputs") -CHECK: DW_TAG_variable [2] -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000037] = "armv7s_var") -CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x0030 => {0x00000030} -CHECK: DW_AT_external [DW_FORM_flag] (0x01) -CHECK: DW_AT_decl_file [DW_FORM_data1] ("/Inputs/fat-test.c") -CHECK: DW_AT_decl_line [DW_FORM_data1] (21) -CHECK: DW_AT_location [DW_FORM_block1] (DW_OP_addr 0x1000) -CHECK: DW_TAG_base_type [3] -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000042] = "int") -CHECK: DW_AT_encoding [DW_FORM_data1] (DW_ATE_signed) -CHECK: DW_AT_byte_size [DW_FORM_data1] (0x04) -CHECK: NULL - -CHECK: .debug_line contents: -CHECK: Line table prologue: -CHECK: total_length: 0x0000002a -CHECK: version: 2 -CHECK: prologue_length: 0x00000021 -CHECK: min_inst_length: 1 -CHECK: default_is_stmt: 1 -CHECK: line_base: -5 -CHECK: line_range: 14 -CHECK: opcode_base: 13 - -CHECK: /Contents/Resources/DWARF/fat-test.arm.dylib(arm64): file format Mach-O arm64 - -CHECK: .debug_info contents: -CHECK: Compile Unit: length = 0x00000038, format = DWARF32, version = 0x0002, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000003c) -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "clang version 3.8.0 (trunk 243776)") -CHECK: DW_AT_language [DW_FORM_data2] (DW_LANG_C99) -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000024] = "fat-test.c") -CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x00000000) -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000002f] = "/Inputs") -CHECK: DW_TAG_variable [2] -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000037] = "arm64_var") -CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x0034 => {0x00000034} -CHECK: DW_AT_external [DW_FORM_flag] (0x01) -CHECK: DW_AT_decl_file [DW_FORM_data1] ("/Inputs/fat-test.c") -CHECK: DW_AT_decl_line [DW_FORM_data1] (25) -CHECK: DW_AT_location [DW_FORM_block1] (DW_OP_addr 0x4000) -CHECK: DW_TAG_base_type [3] -CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000041] = "int") -CHECK: DW_AT_encoding [DW_FORM_data1] (DW_ATE_signed) -CHECK: DW_AT_byte_size [DW_FORM_data1] (0x04) -CHECK: NULL - -CHECK: .debug_line contents: -CHECK: Line table prologue: -CHECK: total_length: 0x0000002a -CHECK: version: 2 -CHECK: prologue_length: 0x00000021 -CHECK: min_inst_length: 1 -CHECK: default_is_stmt: 1 -CHECK: line_base: -5 -CHECK: line_range: 14 -CHECK: opcode_base: 13 diff --git a/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/obfuscated.test b/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/obfuscated.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/obfuscated.test +++ /dev/null @@ -1,119 +0,0 @@ -REQUIRES: system-darwin - -RUN: dsymutil --linker llvm --symbol-map %p/../../Inputs/obfuscated.map %p/../../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck %s - -RUN: dsymutil --linker llvm --symbol-map %p/../../Inputs/obfuscated.map %p/../../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -RUN: dsymutil --linker llvm --symbol-map %p/../../Inputs/obfuscated.2.map %p/../../Inputs/obfuscated.2.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -// Run with plist and make sure dsymutil finds it. -RUN: mkdir -p %t.dSYM/Contents/Resources/DWARF/ -RUN: mkdir -p %t.mapdir -RUN: cp %p/../../Inputs/obfuscated.arm64 %t.dSYM/Contents/Resources/DWARF/ -RUN: cp %p/../../Inputs/E828A486-8433-3A5E-B6DB-A6294D28133D.plist %t.dSYM/Contents/Resources/ -RUN: cp %p/../../Inputs/obfuscated.map %t.mapdir/506AA50A-6B26-3B37-86D2-DC6EBD57B720.bcsymbolmap -RUN: dsymutil --linker llvm --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=OBFUSCATING %s - -// Run without plist and make sure dsymutil doesn't crash. -RUN: rm %t.dSYM/Contents/Resources/E828A486-8433-3A5E-B6DB-A6294D28133D.plist -RUN: dsymutil --linker llvm --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=NOTOBFUSCATING %s - -OBFUSCATING-NOT: not unobfuscating - -NOTOBFUSCATING: not unobfuscating - -NOHIDDEN-NOT: __hidden# - -CHECK: .debug_info contents: - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "main.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "main") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "one.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "one") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "two.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "two") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "three.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "three") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "four.c") -CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x0000011e) -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "four") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "five.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "five") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "six.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "six") - -CHECK: .debug_line contents: -CHECK: file_names[ 1]: -CHECK: name: "main.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "one.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "two.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "three.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "four.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "five.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "six.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 diff --git a/llvm/test/tools/dsymutil/ARM/accel-imported-declarations.test b/llvm/test/tools/dsymutil/ARM/accel-imported-declarations.test --- a/llvm/test/tools/dsymutil/ARM/accel-imported-declarations.test +++ b/llvm/test/tools/dsymutil/ARM/accel-imported-declarations.test @@ -4,6 +4,14 @@ RUN: llvm-dwarfdump -v %t.dwarf.dSYM | FileCheck %s -check-prefixes=DWARF,COMMON RUN: llvm-dwarfdump -v %t.apple.dSYM | FileCheck %s -check-prefixes=APPLE,COMMON +RUN: dsymutil --linker llvm -accelerator=Dwarf -oso-prepend-path=%p/../Inputs \ +RUN: %p/../Inputs/accel-imported-declaration.macho-arm64 -o %t.dwarf.dSYM +RUN: dsymutil --linker llvm -accelerator=Apple -oso-prepend-path=%p/../Inputs \ +RUN: %p/../Inputs/accel-imported-declaration.macho-arm64 -o %t.apple.dSYM + +RUN: llvm-dwarfdump -v %t.dwarf.dSYM | FileCheck %s -check-prefixes=DWARF,COMMON +RUN: llvm-dwarfdump -v %t.apple.dSYM | FileCheck %s -check-prefixes=APPLE,COMMON + COMMON: .debug_info contents COMMON: {{.*}}DW_TAG_namespace COMMON: DW_AT_name{{.*}}"A" diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test b/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test --- a/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test +++ b/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test @@ -29,11 +29,16 @@ ; clang -g -c -O1 b.cpp -gdwarf-4 -o 2.o - RUN: rm -rf %t.dir && mkdir -p %t.dir RUN: dsymutil -y %p/dummy-debug-map-amr64.map -oso-prepend-path=%p/../Inputs/DWARF5-DWARF4-combination -o %t.dir/dwarf5-dwarf4-combination-macho.dSYM RUN: llvm-dwarfdump %t.dir/dwarf5-dwarf4-combination-macho.dSYM -a --verbose | FileCheck %s +RUN: rm -rf %t.dir && mkdir -p %t.dir +RUN: dsymutil --linker llvm -y %p/dummy-debug-map-amr64.map \ +RUN: -oso-prepend-path=%p/../Inputs/DWARF5-DWARF4-combination \ +RUN: -o %t.dir/dwarf5-dwarf4-combination-macho.dSYM +RUN: llvm-dwarfdump %t.dir/dwarf5-dwarf4-combination-macho.dSYM \ +RUN: -a --verbose | FileCheck %s CHECK:.debug_abbrev contents: CHECK-NEXT: Abbrev table for offset: 0x00000000 @@ -59,7 +64,7 @@ CHECK-NEXT: [0x[[#%.16x,LOCLIST_PAIR_START2:]], 0x[[#%.16x,LOCLIST_PAIR_END2:]]): [[LOCLIST_EXPR2:.*]]) CHECK: DW_AT_name [DW_FORM_strx] (indexed (00000007) string = "a") -CHECK: 0x0000004e: Compile Unit: length = 0x00000072, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 +CHECK: 0x0000004e: Compile Unit: length = 0x00000072, format = DWARF32, version = 0x0004, abbr_offset = 0x00{{00|5a}}, addr_size = 0x08 CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "Apple clang version 14.0.3 (clang-1403.0.22.14.1)") CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x000000e0] = "b.cpp") CHECK: DW_AT_LLVM_sysroot [DW_FORM_strp] ( .debug_str[0x00000039] = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk") @@ -69,11 +74,11 @@ CHECK: DW_AT_low_pc [DW_FORM_addr] (0x[[#%.16x,RANGE_LOWPC:]]) CHECK-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 CHECK-NEXT: [0x[[#%.16x,RANGE_START:]], 0x[[#%.16x,RANGE_END:]])) -CHECK: 0x00000080: DW_TAG_subprogram [6] * (0x00000059) +CHECK: 0x00000080: DW_TAG_subprogram {{.*}} * (0x00000059) CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x[[#%.16x,LOC_LOWPC:]]) CHECK: DW_AT_linkage_name [DW_FORM_strp] ( .debug_str[0x000000e6] = "_Z3bari") CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x000000ee] = "bar") -CHECK: 0x0000009d: DW_TAG_formal_parameter [7] (0x00000080) +CHECK: 0x0000009d: DW_TAG_formal_parameter {{.*}} (0x00000080) CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x[[LOC_OFFSET:[0-9a-f]+]]: CHECK-NEXT: [0x[[#%.16x,LOC_PAIR_START:]], 0x[[#%.16x,LOC_PAIR_END:]]): [[LOC_EXPR:.*]] CHECK-NEXT: [0x[[#%.16x,LOC_PAIR_START2:]], 0x[[#%.16x,LOC_PAIR_END2:]]): [[LOC_EXPR2:.*]]) diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test b/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test --- a/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test +++ b/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test @@ -21,6 +21,11 @@ RUN: dsymutil -y %p/dummy-debug-map-amr64.map -oso-prepend-path=%p/../Inputs/DWARF5 -o %t.dir/dwarf5-macho.dSYM RUN: llvm-dwarfdump %t.dir/dwarf5-macho.dSYM -a --verbose | FileCheck %s +RUN: rm -rf %t.dir && mkdir -p %t.dir +RUN: dsymutil --linker llvm -y %p/dummy-debug-map-amr64.map \ +RUN: -oso-prepend-path=%p/../Inputs/DWARF5 -o %t.dir/dwarf5-macho.dSYM +RUN: llvm-dwarfdump %t.dir/dwarf5-macho.dSYM -a --verbose | FileCheck %s + CHECK:.debug_abbrev contents: CHECK-NEXT: Abbrev table for offset: 0x00000000 diff --git a/llvm/test/tools/dsymutil/ARM/fat-dylib-update.test b/llvm/test/tools/dsymutil/ARM/fat-dylib-update.test --- a/llvm/test/tools/dsymutil/ARM/fat-dylib-update.test +++ b/llvm/test/tools/dsymutil/ARM/fat-dylib-update.test @@ -5,6 +5,13 @@ # RUN: llvm-dwarfdump -a -v %t.dSYM/Contents/Resources/DWARF/fat-test.arm.dylib | FileCheck %s # RUN: dsymutil -u %t.dSYM -o %t1.dSYM # RUN: llvm-dwarfdump -a -v %t1.dSYM/Contents/Resources/DWARF/fat-test.arm.dylib | FileCheck %s +# +# RUN: dsymutil --linker llvm -oso-prepend-path %p/.. %p/../Inputs/fat-test.arm.dylib -o %t.dSYM +# RUN: llvm-dwarfdump -a -v %t.dSYM/Contents/Resources/DWARF/fat-test.arm.dylib | FileCheck %s +# RUN: dsymutil --linker llvm -u %t.dSYM +# RUN: llvm-dwarfdump -a -v %t.dSYM/Contents/Resources/DWARF/fat-test.arm.dylib | FileCheck %s +# RUN: dsymutil --linker llvm -u %t.dSYM -o %t1.dSYM +# RUN: llvm-dwarfdump -a -v %t1.dSYM/Contents/Resources/DWARF/fat-test.arm.dylib | FileCheck %s CHECK: /Contents/Resources/DWARF/fat-test.arm.dylib(armv7): file format Mach-O arm diff --git a/llvm/test/tools/dsymutil/ARM/obfuscated.test b/llvm/test/tools/dsymutil/ARM/obfuscated.test --- a/llvm/test/tools/dsymutil/ARM/obfuscated.test +++ b/llvm/test/tools/dsymutil/ARM/obfuscated.test @@ -28,6 +28,36 @@ RUN: rm %t.dSYM/Contents/Resources/E828A486-8433-3A5E-B6DB-A6294D28133D.plist RUN: dsymutil --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=NOTOBFUSCATING %s +// ---------------------------------------- +// Repeat the same steps for --linker llvm. +RUN: dsymutil --linker llvm --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck %s + +RUN: dsymutil --linker llvm --accelerator=Pub --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck --check-prefix=PUB %s + +RUN: dsymutil --linker llvm --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck --check-prefix=NOHIDDEN %s + +RUN: dsymutil --linker llvm --symbol-map %p/../Inputs/obfuscated.2.map %p/../Inputs/obfuscated.2.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck --check-prefix=NOHIDDEN %s + +// Run with plist and make sure dsymutil finds it. +RUN: mkdir -p %t.dSYM/Contents/Resources/DWARF/ +RUN: mkdir -p %t.mapdir +RUN: cp %p/../Inputs/obfuscated.arm64 %t.dSYM/Contents/Resources/DWARF/ +RUN: cp %p/../Inputs/E828A486-8433-3A5E-B6DB-A6294D28133D.plist %t.dSYM/Contents/Resources/ +RUN: cp %p/../Inputs/obfuscated.map %t.mapdir/506AA50A-6B26-3B37-86D2-DC6EBD57B720.bcsymbolmap +RUN: dsymutil --linker llvm --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=OBFUSCATING %s + +// Run without plist and make sure dsymutil doesn't crash. +RUN: rm %t.dSYM/Contents/Resources/E828A486-8433-3A5E-B6DB-A6294D28133D.plist +RUN: dsymutil --linker llvm --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=NOTOBFUSCATING %s + OBFUSCATING-NOT: not unobfuscating NOTOBFUSCATING: not unobfuscating diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-linking-bundle.test b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-linking-bundle.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-linking-bundle.test +++ /dev/null @@ -1,41 +0,0 @@ -RUN: rm -rf %t -RUN: mkdir -p %t/dsymdest -RUN: cat %p/../../Inputs/basic.macho.x86_64 > %t/basic.macho.x86_64 - -RUN: dsymutil --linker llvm -accelerator=Pub -oso-prepend-path=%p/../.. %t/basic.macho.x86_64 - -Check that the object file in the bundle exists and is sane: -RUN: llvm-dwarfdump -a %t/basic.macho.x86_64.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 | FileCheck %S/basic-linking-x86.test - -Check that we don't create an empty Remarks directory if there are no remarks. -RUN: not ls %t/basic.macho.x86_64.dSYM/Contents/Resources/Remarks - -Check that llvm-dwarfdump -a recognizes the bundle as a dSYM: -RUN: llvm-dwarfdump -a %t/basic.macho.x86_64.dSYM | FileCheck %S/basic-linking-x86.test - -RUN: FileCheck %s --input-file %t/basic.macho.x86_64.dSYM/Contents/Info.plist - -RUN: dsymutil --linker llvm -oso-prepend-path=%p/../.. %t/basic.macho.x86_64 -o %t/dsymdest/basic.macho.x86_64.dSYM -RUN: llvm-dwarfdump -a %t/dsymdest/basic.macho.x86_64.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 | FileCheck %S/basic-linking-x86.test -RUN: FileCheck %s --input-file %t/dsymdest/basic.macho.x86_64.dSYM/Contents/Info.plist - -CHECK: -CHECK-NEXT: -CHECK-NEXT: -CHECK-NEXT: -CHECK-NEXT: CFBundleDevelopmentRegion -CHECK-NEXT: English -CHECK-NEXT: CFBundleIdentifier -CHECK-NEXT: com.apple.xcode.dsym.basic.macho.x86_64 -CHECK-NEXT: CFBundleInfoDictionaryVersion -CHECK-NEXT: 6.0 -CHECK-NEXT: CFBundlePackageType -CHECK-NEXT: dSYM -CHECK-NEXT: CFBundleSignature -CHECK-NEXT: ???? -CHECK-NEXT: CFBundleShortVersionString -CHECK-NEXT: 1.0 -CHECK-NEXT: CFBundleVersion -CHECK-NEXT: 1 -CHECK-NEXT: -CHECK-NEXT: diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-linking-x86.test b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-linking-x86.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-linking-x86.test +++ /dev/null @@ -1,190 +0,0 @@ -RUN: cat %p/../../Inputs/basic.macho.x86_64 > %t1 -RUN: dsymutil --linker llvm -accelerator=Pub -f -oso-prepend-path=%p/../.. %t1 -RUN: llvm-dwarfdump -a %t1.dwarf | FileCheck %s -RUN: dsymutil --linker llvm -accelerator=Pub -f -o %t2 -oso-prepend-path=%p/../.. %p/../../Inputs/basic.macho.x86_64 -RUN: llvm-dwarfdump -a %t2 | FileCheck %s -RUN: dsymutil --linker llvm -accelerator=Pub -f -o - -oso-prepend-path=%p/../.. %p/../../Inputs/basic.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,BASIC -RUN: dsymutil --linker llvm -accelerator=Pub -f -o - -oso-prepend-path=%p/../.. %p/../../Inputs/basic-archive.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,ARCHIVE -RUN: dsymutil --linker llvm -accelerator=Pub -dump-debug-map -oso-prepend-path=%p/../.. %p/../../Inputs/basic.macho.x86_64 | dsymutil -accelerator=Pub -f -y -o - - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,BASIC -RUN: dsymutil --linker llvm -accelerator=Pub -dump-debug-map -oso-prepend-path=%p/../.. %p/../../Inputs/basic-archive.macho.x86_64 | dsymutil -accelerator=Pub -f -o - -y - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,ARCHIVE - -CHECK: file format Mach-O 64-bit x86-64 - -CHECK: debug_info contents - -CHECK: Compile Unit: - -CHECK: DW_TAG_compile_unit -CHECK: DW_AT_producer ("Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)") -CHECK: DW_AT_language (DW_LANG_C99) -CHECK: DW_AT_name ("basic1.c") -CHECK: DW_AT_stmt_list (0x00000000) -CHECK: DW_AT_comp_dir ("/Inputs") -CHECK: DW_AT_low_pc (0x0000000100000ea0) -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("main") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic1.c") -CHECK: DW_AT_decl_line (23) -CHECK: DW_AT_prototyped (0x01) -CHECK: DW_AT_type (0x00000063 -CHECK: DW_AT_external (0x01) -CHECK: DW_AT_accessibility (DW_ACCESS_public) -CHECK: DW_AT_low_pc (0x0000000100000ea0) -CHECK: DW_AT_high_pc (0x0000000100000ec4) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_name ("argc") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic1.c") -CHECK: DW_AT_decl_line (23) -CHECK: DW_AT_type (0x00000063 -CHECK: DW_AT_location (DW_OP_fbreg -8) -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_name ("argv") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic1.c") -CHECK: DW_AT_decl_line (23) -CHECK: DW_AT_type (0x0000006a -CHECK: DW_AT_location (DW_OP_fbreg -16) -CHECK: NULL -CHECK: DW_TAG_base_type -CHECK: DW_AT_name ("int") -CHECK: DW_AT_encoding (DW_ATE_signed) -CHECK: DW_AT_byte_size (0x04) -CHECK: DW_TAG_pointer_type -CHECK: DW_AT_type (0x0000006f -CHECK: DW_TAG_pointer_type -CHECK: DW_AT_type (0x00000074 -CHECK: DW_TAG_const_type -CHECK: DW_AT_type (0x00000079 -CHECK: DW_TAG_base_type -CHECK: DW_AT_name ("char") -CHECK: DW_AT_encoding (DW_ATE_signed_char) -CHECK: DW_AT_byte_size (0x01) -CHECK: NULL - -CHECK: Compile Unit: - -CHECK: DW_TAG_compile_unit -CHECK: DW_AT_producer ("Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)") -CHECK: DW_AT_name ("basic2.c") -CHECK: DW_AT_stmt_list (0x0000003f) -CHECK: DW_AT_comp_dir ("/Inputs") -CHECK: DW_AT_low_pc (0x0000000100000ed0) -CHECK: DW_TAG_base_type -CHECK: DW_AT_name ("int") -CHECK: DW_TAG_variable -CHECK: DW_AT_name ("private_int") -CHECK: DW_AT_type (0x000000a7 -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic2.c") -BASIC: DW_AT_location (DW_OP_addr 0x100001008) -ARCHIVE: DW_AT_location (DW_OP_addr 0x100001004) -CHECK: DW_TAG_variable -CHECK: DW_AT_name ("baz") -CHECK: DW_AT_type (0x000000a7 -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic2.c") -CHECK: DW_AT_location (DW_OP_addr 0x100001000) -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("foo") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic2.c") -CHECK: DW_AT_type (0x000000a7 -CHECK: DW_AT_low_pc (0x0000000100000ed0) -CHECK: DW_AT_high_pc (0x0000000100000f19) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_name ("arg") -CHECK: DW_AT_type (0x000000a7 -CHECK: DW_AT_location (DW_OP_fbreg -4) -CHECK: NULL -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("inc") -CHECK: DW_AT_type (0x000000a7 -CHECK: DW_AT_low_pc (0x0000000100000f20) -CHECK: DW_AT_high_pc (0x0000000100000f37) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: NULL - -CHECK: Compile Unit: - -CHECK: DW_TAG_compile_unit -CHECK: DW_AT_producer ("Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)") -CHECK: DW_AT_name ("basic3.c") -CHECK: DW_AT_stmt_list (0x00000093) -CHECK: DW_AT_comp_dir ("/Inputs") -CHECK: DW_AT_low_pc (0x0000000100000f40) -CHECK: DW_TAG_variable -CHECK: DW_AT_name ("val") -CHECK: DW_AT_type (0x00000162 -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic3.c") -BASIC: DW_AT_location (DW_OP_addr 0x100001004) -ARCHIVE: DW_AT_location (DW_OP_addr 0x100001008) -CHECK: DW_TAG_volatile_type -CHECK: DW_AT_type (0x00000167 -CHECK: DW_TAG_base_type -CHECK: DW_AT_name ("int") -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("bar") -CHECK: DW_AT_type (0x00000167 -CHECK: DW_AT_low_pc (0x0000000100000f40) -CHECK: DW_AT_high_pc (0x0000000100000f84) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_name ("arg") -CHECK: DW_AT_type (0x00000167 -CHECK: DW_AT_location (DW_OP_fbreg -8) -CHECK: NULL -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("inc") -CHECK: DW_AT_type (0x00000167 -CHECK: DW_AT_low_pc (0x0000000100000f90) -CHECK: DW_AT_high_pc (0x0000000100000fa9) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) - -CHECK: NULL - -CHECK-NOT: .debug_loc contents - -CHECK:.debug_aranges contents: -CHECK-NEXT:Address Range Header: length = 0x0000002c, format = DWARF32, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x08, seg_size = 0x00 -CHECK-NEXT:[0x0000000100000ea0, 0x0000000100000ec4) -CHECK-NEXT:Address Range Header: length = 0x0000003c, format = DWARF32, version = 0x0002, cu_offset = 0x00000081, addr_size = 0x08, seg_size = 0x00 -CHECK-NEXT:[0x0000000100000ed0, 0x0000000100000f19) -CHECK-NEXT:[0x0000000100000f20, 0x0000000100000f37) -CHECK-NEXT:Address Range Header: length = 0x0000003c, format = DWARF32, version = 0x0002, cu_offset = 0x00000126, addr_size = 0x08, seg_size = 0x00 -CHECK-NEXT:[0x0000000100000f40, 0x0000000100000f84) -CHECK-NEXT:[0x0000000100000f90, 0x0000000100000fa9) - -CHECK: .debug_line contents: -CHECK: file_names[ 1]: -CHECK-NEXT: name: "basic1.c" -CHECK-NEXT: dir_index: 0 -CHECK: Address Line Column File ISA Discriminator OpIndex Flags -CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------- ------------- -CHECK-NEXT: 0x0000000100000ea0 23 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000eb6 24 0 1 0 0 0 is_stmt prologue_end -CHECK-NEXT: 0x0000000100000ec4 24 0 1 0 0 0 is_stmt end_sequence - -CHECK: file_names[ 1]: -CHECK-NEXT: name: "basic2.c" -CHECK-NEXT: dir_index: 0 -CHECK: Address Line Column File ISA Discriminator OpIndex Flags -CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------- ------------- -CHECK-NEXT: 0x0000000100000ed0 19 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000ee2 20 0 1 0 0 0 is_stmt prologue_end -CHECK-NEXT: 0x0000000100000f19 20 0 1 0 0 0 is_stmt end_sequence -CHECK-NEXT: 0x0000000100000f20 14 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f24 15 0 1 0 0 0 is_stmt prologue_end -CHECK-NEXT: 0x0000000100000f37 15 0 1 0 0 0 is_stmt end_sequence - -CHECK: file_names[ 1]: -CHECK-NEXT: name: "basic3.c" -CHECK-NEXT: dir_index: 0 -CHECK: Address Line Column File ISA Discriminator OpIndex Flags -CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------- ------------- -CHECK-NEXT: 0x0000000100000f40 16 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f4b 17 0 1 0 0 0 is_stmt prologue_end -CHECK-NEXT: 0x0000000100000f58 18 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f6c 19 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f7b 20 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f84 20 0 1 0 0 0 is_stmt end_sequence -CHECK-NEXT: 0x0000000100000f90 11 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f9b 12 0 1 0 0 0 is_stmt prologue_end -CHECK-NEXT: 0x0000000100000fa9 12 0 1 0 0 0 is_stmt end_sequence diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-lto-dw4-linking-x86.test b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-lto-dw4-linking-x86.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-lto-dw4-linking-x86.test +++ /dev/null @@ -1,183 +0,0 @@ -RUN: dsymutil --linker llvm -f -o - -oso-prepend-path=%p/../.. %p/../../Inputs/basic-lto-dw4.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s - -CHECK: file format Mach-O 64-bit x86-64 - -CHECK: debug_info contents - -CHECK: Compile Unit: {{.*}} version = 0x0004 -CHECK: DW_TAG_compile_unit -CHECK: DW_AT_producer ("clang version 3.7.0 ") -CHECK: DW_AT_language (DW_LANG_C99) -CHECK: DW_AT_name ("basic1.c") -CHECK: DW_AT_stmt_list (0x00000000) -CHECK: DW_AT_comp_dir ("/Inputs") -CHECK: DW_AT_low_pc (0x0000000100000f40) -CHECK: DW_AT_high_pc (0x0000000100000f4b) -CHECK: DW_TAG_subprogram -CHECK: DW_AT_low_pc (0x0000000100000f40) -CHECK: DW_AT_high_pc (0x0000000100000f4b) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: DW_AT_name ("main") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic1.c") -CHECK: DW_AT_prototyped (true) -CHECK: DW_AT_type (0x00000000000000a1 -CHECK: DW_AT_external (true) -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_location (DW_OP_reg5 RDI, DW_OP_piece 0x4) -CHECK: DW_AT_name ("argc") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic1.c") -CHECK: DW_AT_type (0x00000000000000a1 -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_location (DW_OP_reg4 RSI) -CHECK: DW_AT_name ("argv") -CHECK: DW_AT_type (0x00000060 -CHECK: NULL -CHECK: DW_TAG_pointer_type -CHECK: DW_AT_type (0x00000065 -CHECK: DW_TAG_pointer_type -CHECK: DW_TAG_const_type -CHECK: DW_TAG_base_type -CHECK: DW_AT_name ("char") -CHECK: DW_AT_encoding (DW_ATE_signed_char) -CHECK: DW_AT_byte_size (0x01) -CHECK: NULL - -CHECK: Compile Unit:{{.*}} version = 0x0004 - -CHECK: DW_TAG_compile_unit -CHECK: DW_AT_producer ("clang version 3.7.0 ") -CHECK: DW_AT_language (DW_LANG_C99) -CHECK: DW_AT_name ("basic2.c") -CHECK: DW_AT_stmt_list (0x00000044) -CHECK: DW_AT_low_pc (0x0000000100000f50) -CHECK: DW_AT_high_pc (0x0000000100000f87) -CHECK: DW_TAG_base_type -CHECK: DW_AT_name ("int") -CHECK: DW_TAG_variable -CHECK: DW_AT_name ("baz") -CHECK: DW_AT_location (DW_OP_addr 0x100001000) -CHECK: DW_TAG_variable -CHECK: DW_AT_name ("private_int") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic2.c") -CHECK: DW_AT_location (DW_OP_addr 0x100001008) -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("inc") -CHECK: DW_AT_type (0x000000a1 -CHECK: DW_AT_inline (DW_INL_inlined) -CHECK: DW_TAG_subprogram -CHECK: DW_AT_low_pc (0x0000000100000f50) -CHECK: DW_AT_high_pc (0x0000000100000f87) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: DW_AT_name ("foo") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic2.c") -CHECK: DW_AT_prototyped (true) -CHECK: DW_AT_type (0x000000a1 -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_location (0x00000000 -CHECK: [0x0000000100000f50, 0x0000000100000f5c): DW_OP_reg5 RDI, DW_OP_piece 0x4) -CHECK: DW_AT_name ("arg") -CHECK: DW_AT_type (0x000000a1 -CHECK: DW_TAG_inlined_subroutine -CHECK: DW_AT_abstract_origin (0x000000d2 "inc") -CHECK: DW_AT_low_pc (0x0000000100000f61) -CHECK: DW_AT_high_pc (0x0000000100000f70) -CHECK: NULL -CHECK: NULL - -CHECK: Compile Unit: {{.*}} version = 0x0004 - -CHECK: DW_TAG_compile_unit -CHECK: DW_AT_producer ("clang version 3.7.0 ") -CHECK: DW_AT_name ("basic3.c") -CHECK: DW_AT_stmt_list (0x0000009a) -CHECK: DW_AT_low_pc (0x0000000100000f90) -CHECK: DW_AT_high_pc (0x0000000100000fb4) -CHECK: DW_TAG_variable -CHECK: DW_AT_name ("val") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic3.c") -CHECK: DW_AT_location (DW_OP_addr 0x100001004) -CHECK: DW_TAG_volatile_type -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("inc") -CHECK: DW_AT_inline (DW_INL_inlined) -CHECK: DW_TAG_subprogram -CHECK: DW_AT_low_pc (0x0000000100000f90) -CHECK: DW_AT_high_pc (0x0000000100000fb4) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: DW_AT_name ("bar") -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_location (0x00000025 -CHECK: [0x0000000100000f90, 0x0000000100000f9f): DW_OP_reg5 RDI, DW_OP_piece 0x4 -CHECK: [0x0000000100000fa9, 0x0000000100000fad): DW_OP_reg5 RDI, DW_OP_piece 0x4) -CHECK: DW_AT_name ("arg") -CHECK: DW_TAG_inlined_subroutine -CHECK: DW_AT_abstract_origin (0x0000015f "inc") -CHECK: DW_AT_ranges (0x00000000 -CHECK: [0x0000000100000f94, 0x0000000100000f9a) -CHECK: [0x0000000100000f9f, 0x0000000100000fa7)) - -CHECK: NULL -CHECK: NULL - - -CHECK: .debug_loc contents: -CHECK-NEXT: 0x00000000: -CHECK-NEXT: (0x0000000000000000, 0x000000000000000c): DW_OP_reg5 RDI, DW_OP_piece 0x4 -CHECK-NOT: : -CHECK: 0x00000025: -CHECK-NEXT: (0x0000000000000000, 0x000000000000000f): DW_OP_reg5 RDI, DW_OP_piece 0x4 -CHECK-NEXT: (0x0000000000000019, 0x000000000000001d): DW_OP_reg5 RDI, DW_OP_piece 0x4 - - -CHECK: .debug_aranges contents: -CHECK-NEXT: Address Range Header: length = 0x0000002c, format = DWARF32, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x08, seg_size = 0x00 -CHECK-NEXT: [0x0000000100000f40, 0x0000000100000f4b) -CHECK-NEXT: Address Range Header: length = 0x0000002c, format = DWARF32, version = 0x0002, cu_offset = 0x00000077, addr_size = 0x08, seg_size = 0x00 -CHECK-NEXT: [0x0000000100000f50, 0x0000000100000f87) -CHECK-NEXT: Address Range Header: length = 0x0000002c, format = DWARF32, version = 0x0002, cu_offset = 0x0000011b, addr_size = 0x08, seg_size = 0x00 -CHECK-NEXT: [0x0000000100000f90, 0x0000000100000fb4) - -CHECK: .debug_line contents: -CHECK: file_names[ 1]: -CHECK-NEXT: name: "basic1.c" -CHECK-NEXT: dir_index: 0 -CHECK: Address Line Column File ISA Discriminator OpIndex Flags -CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------- ------------- -CHECK-NEXT: 0x0000000100000f40 26 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f44 27 10 1 0 0 0 is_stmt prologue_end -CHECK-NEXT: 0x0000000100000f49 27 3 1 0 0 0 -CHECK-NEXT: 0x0000000100000f4b 27 3 1 0 0 0 end_sequence - -CHECK: file_names[ 1]: -CHECK-NEXT: name: "basic2.c" -CHECK-NEXT: dir_index: 0 -CHECK: Address Line Column File ISA Discriminator OpIndex Flags -CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------- ------------- -CHECK-NEXT: 0x0000000100000f50 19 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f54 20 18 1 0 0 0 is_stmt prologue_end -CHECK-NEXT: 0x0000000100000f5a 20 17 1 0 0 0 -CHECK-NEXT: 0x0000000100000f5c 20 10 1 0 0 0 -CHECK-NEXT: 0x0000000100000f61 15 10 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f70 20 23 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f74 20 36 1 0 0 0 -CHECK-NEXT: 0x0000000100000f83 20 31 1 0 0 0 -CHECK-NEXT: 0x0000000100000f85 20 3 1 0 0 0 -CHECK-NEXT: 0x0000000100000f87 20 3 1 0 0 0 end_sequence - -CHECK: file_names[ 1]: -CHECK-NEXT: name: "basic3.c" -CHECK-NEXT: dir_index: 0 -CHECK: Address Line Column File ISA Discriminator OpIndex Flags -CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------- ------------- -CHECK-NEXT: 0x0000000100000f90 16 0 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f94 12 10 1 0 0 0 is_stmt prologue_end -CHECK-NEXT: 0x0000000100000f9a 17 7 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000f9f 12 10 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000fa7 20 1 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000fa9 19 18 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000fab 19 10 1 0 0 0 -CHECK-NEXT: 0x0000000100000fb2 20 1 1 0 0 0 is_stmt -CHECK-NEXT: 0x0000000100000fb4 20 1 1 0 0 0 is_stmt end_sequence - -CHECK-NOT: .debug_pubnames contents: -CHECK-NOT: .debug_pubtypes contents: diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-lto-linking-x86.test b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-lto-linking-x86.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-lto-linking-x86.test +++ /dev/null @@ -1,182 +0,0 @@ -RUN: dsymutil --linker llvm -f -o - -oso-prepend-path=%p/../.. %p/../../Inputs/basic-lto.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path=%p/../.. -dump-debug-map %p/../../Inputs/basic-lto.macho.x86_64 | dsymutil -f -o - -y - | llvm-dwarfdump -a - | FileCheck %s - -CHECK: file format Mach-O 64-bit x86-64 - -CHECK: debug_info contents - -CHECK: Compile Unit: - -CHECK: DW_TAG_compile_unit -CHECK: DW_AT_producer ("Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)") -CHECK: DW_AT_language (DW_LANG_C99) -CHECK: DW_AT_name ("basic1.c") -CHECK: DW_AT_stmt_list (0x00000000) -CHECK: DW_AT_comp_dir ("/Inputs") -CHECK: DW_AT_low_pc (0x0000000100000f40) -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("main") -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic1.c") -CHECK: DW_AT_decl_line (23) -CHECK: DW_AT_prototyped (0x01) -CHECK: DW_AT_type (0x00000063 -CHECK: DW_AT_external (0x01) -CHECK: DW_AT_accessibility (DW_ACCESS_public) -CHECK: DW_AT_low_pc (0x0000000100000f40) -CHECK: DW_AT_high_pc (0x0000000100000f4b) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_name ("argc") -CHECK: DW_AT_type (0x00000063 -CHECK: DW_AT_location (DW_OP_reg5 RDI, DW_OP_piece 0x4) -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_name ("argv") -CHECK: DW_AT_type (0x0000006a -CHECK: DW_AT_location (DW_OP_reg4 RSI) -CHECK: NULL -CHECK: DW_TAG_base_type -CHECK: DW_AT_name ("int") -CHECK: DW_AT_encoding (DW_ATE_signed) -CHECK: DW_AT_byte_size (0x04) -CHECK: DW_TAG_pointer_type -CHECK: DW_AT_type (0x0000006f -CHECK: DW_TAG_pointer_type -CHECK: DW_AT_type (0x00000074 -CHECK: DW_TAG_const_type -CHECK: DW_AT_type (0x00000079 -CHECK: DW_TAG_base_type -CHECK: DW_AT_name ("char") -CHECK: DW_AT_encoding (DW_ATE_signed_char) -CHECK: DW_AT_byte_size (0x01) -CHECK: NULL - -CHECK: Compile Unit: - -CHECK: DW_TAG_compile_unit -CHECK: DW_AT_producer ("Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)") -CHECK: DW_AT_name ("basic2.c") -CHECK: DW_AT_stmt_list (0x0000003e) -CHECK: DW_AT_comp_dir ("/Inputs") -CHECK: DW_AT_low_pc (0x0000000100000f50) -CHECK: DW_TAG_variable -CHECK: DW_AT_name ("private_int") -CHECK: DW_AT_type (0x0000000000000063 -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic2.c") -CHECK: DW_AT_location (DW_OP_addr 0x100001008) -CHECK: DW_TAG_variable -CHECK: DW_AT_name ("baz") -CHECK: DW_AT_type (0x0000000000000063 -CHECK: DW_AT_location (DW_OP_addr 0x100001000) -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("foo") -CHECK: DW_AT_type (0x0000000000000063 -CHECK: DW_AT_low_pc (0x0000000100000f50) -CHECK: DW_AT_high_pc (0x0000000100000f89) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_name ("arg") -CHECK: DW_AT_type (0x0000000000000063 -CHECK: DW_AT_location (0x00000000 -CHECK: [0x0000000100000f50, 0x0000000100000f5e): DW_OP_reg5 RDI, DW_OP_piece 0x4) -CHECK:[[INC1:0x[0-9a-f]*]]{{.*}}DW_TAG_inlined_subroutine -CHECK: DW_AT_abstract_origin (0x00000128 "inc") -CHECK: DW_AT_low_pc (0x0000000100000f63) -CHECK: DW_AT_high_pc (0x0000000100000f72) -CHECK: DW_AT_call_line (20) -CHECK: NULL -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("inc") -CHECK: DW_AT_type (0x0000000000000063 -CHECK: DW_AT_inline (DW_INL_inlined) -CHECK: NULL - -CHECK: Compile Unit: - -CHECK: DW_TAG_compile_unit -CHECK: DW_AT_producer ("Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)") -CHECK: DW_AT_name ("basic3.c") -CHECK: DW_AT_stmt_list (0x0000007e) -CHECK: DW_AT_comp_dir ("/Inputs") -CHECK: DW_AT_low_pc (0x0000000100000f90) -CHECK: DW_TAG_variable -CHECK: DW_AT_name ("val") -CHECK: DW_AT_type (0x00000176 -CHECK: DW_AT_decl_file ("/Inputs{{[/\\]}}basic3.c") -CHECK: DW_AT_location (DW_OP_addr 0x100001004) -CHECK: DW_TAG_volatile_type -CHECK: DW_AT_type (0x0000000000000063 -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("bar") -CHECK: DW_AT_type (0x0000000000000063 -CHECK: DW_AT_low_pc (0x0000000100000f90) -CHECK: DW_AT_high_pc (0x0000000100000fb4) -CHECK: DW_AT_frame_base (DW_OP_reg6 RBP) -CHECK: DW_TAG_formal_parameter -CHECK: DW_AT_name ("arg") -CHECK: DW_AT_type (0x0000000000000063 -CHECK: DW_AT_location (0x00000025 -CHECK: [0x0000000100000f90, 0x0000000100000f9f): DW_OP_reg5 RDI, DW_OP_piece 0x4 -CHECK: [0x0000000100000fa9, 0x0000000100000fad): DW_OP_reg5 RDI, DW_OP_piece 0x4) -CHECK: DW_TAG_lexical_block -CHECK: DW_AT_low_pc (0x0000000100000f94) -CHECK: DW_AT_high_pc (0x0000000100000fa7) -CHECK:[[INC2:0x[0-9a-f]*]]{{.*}}DW_TAG_inlined_subroutine -CHECK: DW_AT_abstract_origin (0x000001d4 "inc") -CHECK: DW_AT_ranges (0x00000000 -CHECK: [0x0000000100000f94, 0x0000000100000f9a) -CHECK: [0x0000000100000f9f, 0x0000000100000fa7)) -CHECK: NULL -CHECK: NULL -CHECK: DW_TAG_subprogram -CHECK: DW_AT_name ("inc") -CHECK: DW_AT_type (0x0000000000000063 -CHECK: NULL - -CHECK: .debug_loc contents: -CHECK-NEXT: 0x00000000: -CHECK-NEXT: (0x0000000000000000, 0x000000000000000e): DW_OP_reg5 RDI, DW_OP_piece 0x4 -CHECK-NOT: : -CHECK: 0x00000025: -CHECK-NEXT: (0x0000000000000000, 0x000000000000000f): DW_OP_reg5 RDI, DW_OP_piece 0x4 -CHECK-NEXT: (0x0000000000000019, 0x000000000000001d): DW_OP_reg5 RDI, DW_OP_piece 0x4 - -CHECK: .debug_aranges contents: -CHECK-NEXT: Address Range Header: length = 0x0000002c, format = DWARF32, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x08, seg_size = 0x00 -CHECK-NEXT: [0x0000000100000f40, 0x0000000100000f4b) -CHECK-NEXT: Address Range Header: length = 0x0000002c, format = DWARF32, version = 0x0002, cu_offset = 0x00000081, addr_size = 0x08, seg_size = 0x00 -CHECK-NEXT: [0x0000000100000f50, 0x0000000100000f89) -CHECK-NEXT: Address Range Header: length = 0x0000002c, format = DWARF32, version = 0x0002, cu_offset = 0x0000013a, addr_size = 0x08, seg_size = 0x00 -CHECK-NEXT: [0x0000000100000f90, 0x0000000100000fb4) - - -CHECK: .debug_line contents -CHECK: file_names[ 1]: -CHECK-NEXT: name: "basic1.c" -CHECK-NEXT: dir_index: 0 -CHECK: 0x0000000100000f40 23 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000f44 24 0 1 0 0 0 is_stmt prologue_end -CHECK: 0x0000000100000f4b 24 0 1 0 0 0 is_stmt end_sequence - -CHECK: file_names[ 1]: -CHECK-NEXT: name: "basic2.c" -CHECK-NEXT: dir_index: 0 -CHECK: 0x0000000100000f50 19 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000f54 20 0 1 0 0 0 is_stmt prologue_end -CHECK: 0x0000000100000f63 15 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000f72 20 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000f89 20 0 1 0 0 0 is_stmt end_sequence - -CHECK: file_names[ 1]: -CHECK-NEXT: name: "basic3.c" -CHECK-NEXT: dir_index: 0 -CHECK: 0x0000000100000f90 16 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000f94 12 0 1 0 0 0 is_stmt prologue_end -CHECK: 0x0000000100000f9a 17 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000f9f 12 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000fa7 20 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000fa9 19 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000fb2 20 0 1 0 0 0 is_stmt -CHECK: 0x0000000100000fb4 20 0 1 0 0 0 is_stmt end_sequence - -CHECK-NOT: .debug_pubnames contents: -CHECK-NOT: .debug_pubtypes contents: diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-with-libfat-test.test b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-with-libfat-test.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-with-libfat-test.test +++ /dev/null @@ -1,12 +0,0 @@ -RUN: cat %p/../../Inputs/basic-with-libfat-test.macho.x86_64 > %t1 -RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../.. %t1 -RUN: llvm-dwarfdump %t1.dwarf | FileCheck %s - -The test binary was created by force-linking the libfat-test.a fat archive -with the basic linking test archive, like so: -$ clang -all_load libfat-test.a libbasic.a basic1.macho.x86_64.o -Wl,-dead_strip -u _x86_64_var - -CHECK: DW_AT_name{{.*}}"x86_64_var" -CHECK: DW_AT_name{{.*}}"basic2.c" -CHECK: DW_AT_name{{.*}}"basic3.c" -CHECK: DW_AT_name{{.*}}"basic1.c" diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/multiple-inputs.test b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/multiple-inputs.test deleted file mode 100644 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/multiple-inputs.test +++ /dev/null @@ -1,30 +0,0 @@ -RUN: rm -rf %t -RUN: mkdir -p %t - -RUN: cat %p/../../Inputs/basic.macho.x86_64 > %t/basic.macho.x86_64 -RUN: cat %p/../../Inputs/basic-archive.macho.x86_64 > %t/basic-archive.macho.x86_64 -RUN: cat %p/../../Inputs/basic-lto.macho.x86_64 > %t/basic-lto.macho.x86_64 -RUN: cat %p/../../Inputs/basic-lto-dw4.macho.x86_64 > %t/basic-lto-dw4.macho.x86_64 - -# Multiple inputs in flat mode -RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../.. %t/basic.macho.x86_64 %t/basic-archive.macho.x86_64 %t/basic-lto.macho.x86_64 %t/basic-lto-dw4.macho.x86_64 -RUN: llvm-dwarfdump -a %t/basic.macho.x86_64.dwarf \ -RUN: | FileCheck %S/basic-linking-x86.test --check-prefixes=CHECK,BASIC -RUN: llvm-dwarfdump -a %t/basic-archive.macho.x86_64.dwarf \ -RUN: | FileCheck %S/basic-linking-x86.test --check-prefixes=CHECK,ARCHIVE -RUN: llvm-dwarfdump -a %t/basic-lto.macho.x86_64.dwarf | FileCheck %S/basic-lto-linking-x86.test -RUN: llvm-dwarfdump -a %t/basic-lto-dw4.macho.x86_64.dwarf | FileCheck %S/basic-lto-dw4-linking-x86.test - -# Multiple inputs that end up in the same named bundle -RUN: dsymutil --linker llvm -oso-prepend-path=%p/../.. %t/basic.macho.x86_64 %t/basic-archive.macho.x86_64 %t/basic-lto.macho.x86_64 %t/basic-lto-dw4.macho.x86_64 -o %t.dSYM -RUN: llvm-dwarfdump -a %t.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 \ -RUN: | FileCheck %S/basic-linking-x86.test --check-prefixes=CHECK,BASIC -RUN: llvm-dwarfdump -a %t.dSYM/Contents/Resources/DWARF/basic-archive.macho.x86_64 \ -RUN: | FileCheck %S/basic-linking-x86.test --check-prefixes=CHECK,ARCHIVE -RUN: llvm-dwarfdump -a %t.dSYM/Contents/Resources/DWARF/basic-lto.macho.x86_64 | FileCheck %S/basic-lto-linking-x86.test -RUN: llvm-dwarfdump -a %t.dSYM/Contents/Resources/DWARF/basic-lto-dw4.macho.x86_64 | FileCheck %S/basic-lto-dw4-linking-x86.test - -# Multiple inputs in a named bundle in flat mode... impossible. -RUN: not dsymutil --linker llvm -f -oso-prepend-path=%p/../.. %t/basic.macho.x86_64 %t/basic-archive.macho.x86_64 %t/basic-lto.macho.x86_64 %t/basic-lto-dw4.macho.x86_64 -o %t.dSYM 2>&1 | FileCheck %s - -CHECK: error: cannot use -o with multiple inputs in flat mode diff --git a/llvm/test/tools/dsymutil/X86/basic-linking-bundle.test b/llvm/test/tools/dsymutil/X86/basic-linking-bundle.test --- a/llvm/test/tools/dsymutil/X86/basic-linking-bundle.test +++ b/llvm/test/tools/dsymutil/X86/basic-linking-bundle.test @@ -19,6 +19,31 @@ RUN: llvm-dwarfdump -a %t/dsymdest/basic.macho.x86_64.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 | FileCheck %S/basic-linking-x86.test RUN: FileCheck %s --input-file %t/dsymdest/basic.macho.x86_64.dSYM/Contents/Info.plist +### -------------------------------------------- +### Repeat the steps for --linker llvm + +RUN: rm -rf %t +RUN: mkdir -p %t/dsymdest +RUN: cat %p/../Inputs/basic.macho.x86_64 > %t/basic.macho.x86_64 + +RUN: dsymutil --linker llvm -accelerator=Pub -oso-prepend-path=%p/.. %t/basic.macho.x86_64 + +Check that the object file in the bundle exists and is sane: +RUN: llvm-dwarfdump -a %t/basic.macho.x86_64.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 | FileCheck %S/basic-linking-x86.test + +Check that we don't create an empty Remarks directory if there are no remarks. +RUN: not ls %t/basic.macho.x86_64.dSYM/Contents/Resources/Remarks + +Check that llvm-dwarfdump -a recognizes the bundle as a dSYM: +RUN: llvm-dwarfdump -a %t/basic.macho.x86_64.dSYM | FileCheck %S/basic-linking-x86.test + +RUN: FileCheck %s --input-file %t/basic.macho.x86_64.dSYM/Contents/Info.plist + +RUN: dsymutil --linker llvm -oso-prepend-path=%p/.. %t/basic.macho.x86_64 -o %t/dsymdest/basic.macho.x86_64.dSYM +RUN: llvm-dwarfdump -a %t/dsymdest/basic.macho.x86_64.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 | FileCheck %S/basic-linking-x86.test +RUN: FileCheck %s --input-file %t/dsymdest/basic.macho.x86_64.dSYM/Contents/Info.plist + + CHECK: CHECK-NEXT: CHECK-NEXT: diff --git a/llvm/test/tools/dsymutil/X86/basic-linking-x86.test b/llvm/test/tools/dsymutil/X86/basic-linking-x86.test --- a/llvm/test/tools/dsymutil/X86/basic-linking-x86.test +++ b/llvm/test/tools/dsymutil/X86/basic-linking-x86.test @@ -8,6 +8,19 @@ RUN: dsymutil -accelerator=Pub -dump-debug-map -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 | dsymutil -accelerator=Pub -f -y -o - - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,BASIC,PUB RUN: dsymutil -accelerator=Pub -dump-debug-map -oso-prepend-path=%p/.. %p/../Inputs/basic-archive.macho.x86_64 | dsymutil -accelerator=Pub -f -o - -y - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,ARCHIVE,PUB +### --------------------------------------- +### Repeat the same steps for --linker llvm + +RUN: cat %p/../Inputs/basic.macho.x86_64 > %t1 +RUN: dsymutil --linker llvm -accelerator=Pub -f -oso-prepend-path=%p/.. %t1 +RUN: llvm-dwarfdump -a %t1.dwarf | FileCheck %s +RUN: dsymutil --linker llvm -accelerator=Pub -f -o %t2 -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 +RUN: llvm-dwarfdump -a %t2 | FileCheck %s +RUN: dsymutil --linker llvm -accelerator=Pub -f -o - -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,BASIC,PUB +RUN: dsymutil --linker llvm -accelerator=Pub -f -o - -oso-prepend-path=%p/.. %p/../Inputs/basic-archive.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,ARCHIVE,PUB +RUN: dsymutil --linker llvm -accelerator=Pub -dump-debug-map -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 | dsymutil -accelerator=Pub -f -y -o - - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,BASIC,PUB +RUN: dsymutil --linker llvm -accelerator=Pub -dump-debug-map -oso-prepend-path=%p/.. %p/../Inputs/basic-archive.macho.x86_64 | dsymutil -accelerator=Pub -f -o - -y - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,ARCHIVE,PUB + CHECK: file format Mach-O 64-bit x86-64 CHECK: debug_info contents diff --git a/llvm/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test b/llvm/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test --- a/llvm/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test +++ b/llvm/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test @@ -1,5 +1,9 @@ RUN: dsymutil -f -o - -oso-prepend-path=%p/.. %p/../Inputs/basic-lto-dw4.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s +RUN: dsymutil --linker llvm -f -o - -oso-prepend-path=%p/.. \ +RUN: %p/../Inputs/basic-lto-dw4.macho.x86_64 | llvm-dwarfdump -a - \ +RUN: | FileCheck %s + CHECK: file format Mach-O 64-bit x86-64 CHECK: debug_info contents diff --git a/llvm/test/tools/dsymutil/X86/basic-lto-linking-x86.test b/llvm/test/tools/dsymutil/X86/basic-lto-linking-x86.test --- a/llvm/test/tools/dsymutil/X86/basic-lto-linking-x86.test +++ b/llvm/test/tools/dsymutil/X86/basic-lto-linking-x86.test @@ -1,6 +1,12 @@ RUN: dsymutil -f -o - -oso-prepend-path=%p/.. %p/../Inputs/basic-lto.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s RUN: dsymutil -oso-prepend-path=%p/.. -dump-debug-map %p/../Inputs/basic-lto.macho.x86_64 | dsymutil -f -o - -y - | llvm-dwarfdump -a - | FileCheck %s +RUN: dsymutil --linker llvm -f -o - -oso-prepend-path=%p/.. \ +RUN: %p/../Inputs/basic-lto.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s +RUN: dsymutil --linker llvm -oso-prepend-path=%p/.. -dump-debug-map \ +RUN: %p/../Inputs/basic-lto.macho.x86_64 | dsymutil -f -o - -y - | \ +RUN: llvm-dwarfdump -a - | FileCheck %s + CHECK: file format Mach-O 64-bit x86-64 CHECK: debug_info contents diff --git a/llvm/test/tools/dsymutil/X86/basic-with-libfat-test.test b/llvm/test/tools/dsymutil/X86/basic-with-libfat-test.test --- a/llvm/test/tools/dsymutil/X86/basic-with-libfat-test.test +++ b/llvm/test/tools/dsymutil/X86/basic-with-libfat-test.test @@ -1,4 +1,8 @@ -RUN: dsymutil -f -o - -oso-prepend-path=%p/.. %p/../Inputs/basic-with-libfat-test.macho.x86_64 | llvm-dwarfdump - | FileCheck %s +RUN: dsymutil -f -o - -oso-prepend-path=%p/.. %p/../Inputs/basic-with-libfat-test.macho.x86_64 | llvm-dwarfdump - | FileCheck %s + +RUN: dsymutil --linker llvm -f -o - -oso-prepend-path=%p/.. \ +RUN: %p/../Inputs/basic-with-libfat-test.macho.x86_64 | llvm-dwarfdump - \ +RUN: | FileCheck %s The test binary was created by force-linking the libfat-test.a fat archive with the basic linking test archive, like so: diff --git a/llvm/test/tools/dsymutil/X86/multiple-inputs.test b/llvm/test/tools/dsymutil/X86/multiple-inputs.test --- a/llvm/test/tools/dsymutil/X86/multiple-inputs.test +++ b/llvm/test/tools/dsymutil/X86/multiple-inputs.test @@ -27,4 +27,43 @@ # Multiple inputs in a named bundle in flat mode... impossible. RUN: not dsymutil -f -oso-prepend-path=%p/.. %t/basic.macho.x86_64 %t/basic-archive.macho.x86_64 %t/basic-lto.macho.x86_64 %t/basic-lto-dw4.macho.x86_64 -o %t.dSYM 2>&1 | FileCheck %s +## --------------------------------------- +## Repeat the same steps for --linker llvm + +RUN: rm -rf %t +RUN: mkdir -p %t + +RUN: cat %p/../Inputs/basic.macho.x86_64 > %t/basic.macho.x86_64 +RUN: cat %p/../Inputs/basic-archive.macho.x86_64 > %t/basic-archive.macho.x86_64 +RUN: cat %p/../Inputs/basic-lto.macho.x86_64 > %t/basic-lto.macho.x86_64 +RUN: cat %p/../Inputs/basic-lto-dw4.macho.x86_64 > %t/basic-lto-dw4.macho.x86_64 + +# Multiple inputs in flat mode +RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/.. \ +RUN: %t/basic.macho.x86_64 %t/basic-archive.macho.x86_64 \ +RUN: %t/basic-lto.macho.x86_64 %t/basic-lto-dw4.macho.x86_64 +RUN: llvm-dwarfdump -a %t/basic.macho.x86_64.dwarf \ +RUN: | FileCheck %S/basic-linking-x86.test --check-prefixes=CHECK,BASIC +RUN: llvm-dwarfdump -a %t/basic-archive.macho.x86_64.dwarf \ +RUN: | FileCheck %S/basic-linking-x86.test --check-prefixes=CHECK,ARCHIVE +RUN: llvm-dwarfdump -a %t/basic-lto.macho.x86_64.dwarf | FileCheck %S/basic-lto-linking-x86.test +RUN: llvm-dwarfdump -a %t/basic-lto-dw4.macho.x86_64.dwarf | FileCheck %S/basic-lto-dw4-linking-x86.test + +# Multiple inputs that end up in the same named bundle +RUN: dsymutil --linker llvm -oso-prepend-path=%p/.. %t/basic.macho.x86_64 \ +RUN: %t/basic-archive.macho.x86_64 %t/basic-lto.macho.x86_64 \ +RUN: %t/basic-lto-dw4.macho.x86_64 -o %t.dSYM +RUN: llvm-dwarfdump -a %t.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 \ +RUN: | FileCheck %S/basic-linking-x86.test --check-prefixes=CHECK,BASIC +RUN: llvm-dwarfdump -a %t.dSYM/Contents/Resources/DWARF/basic-archive.macho.x86_64 \ +RUN: | FileCheck %S/basic-linking-x86.test --check-prefixes=CHECK,ARCHIVE +RUN: llvm-dwarfdump -a %t.dSYM/Contents/Resources/DWARF/basic-lto.macho.x86_64 | FileCheck %S/basic-lto-linking-x86.test +RUN: llvm-dwarfdump -a %t.dSYM/Contents/Resources/DWARF/basic-lto-dw4.macho.x86_64 | FileCheck %S/basic-lto-dw4-linking-x86.test + +# Multiple inputs in a named bundle in flat mode... impossible. +RUN: not dsymutil --linker llvm -f -oso-prepend-path=%p/.. \ +RUN: %t/basic.macho.x86_64 %t/basic-archive.macho.x86_64 \ +RUN: %t/basic-lto.macho.x86_64 %t/basic-lto-dw4.macho.x86_64 \ +RUN: -o %t.dSYM 2>&1 | FileCheck %s + CHECK: error: cannot use -o with multiple inputs in flat mode diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf4.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf4.test --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf4.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf4.test @@ -11,6 +11,16 @@ # RUN: llvm-dwarfutil --garbage-collection --build-accelerator=DWARF %t.o %t1 # RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY # RUN: llvm-dwarfdump -a %t1 | FileCheck %s +# +# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection \ +# RUN: --build-accelerator=DWARF %t.o %t1 +# RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY +# RUN: llvm-dwarfdump -a %t1 | FileCheck %s + +# RUN: llvm-dwarfutil --linker llvm --garbage-collection \ +# RUN: --build-accelerator=DWARF %t.o %t1 +# RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY +# RUN: llvm-dwarfdump -a %t1 | FileCheck %s # VERIFY: No errors diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf5.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf5.test --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf5.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf5.test @@ -9,6 +9,16 @@ # RUN: llvm-dwarfutil --garbage-collection --build-accelerator=DWARF %p/Inputs/dwarf5.out %t1 # RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY # RUN: llvm-dwarfdump -a %t1 | FileCheck %s +# +# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection \ +# RUN: --build-accelerator=DWARF %p/Inputs/dwarf5.out %t1 +# RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY +# RUN: llvm-dwarfdump -a %t1 | FileCheck %s + +# RUN: llvm-dwarfutil --linker llvm --garbage-collection \ +# RUN: --build-accelerator=DWARF %p/Inputs/dwarf5.out %t1 +# RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY +# RUN: llvm-dwarfdump -a %t1 | FileCheck %s # VERIFY: No errors