From fab91e950966dbc5d3b59208e4dab274ac54e891 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 21 Aug 2023 10:35:18 +0200 Subject: [PATCH] Revert "[Reland][DWARFLinkerParallel] Add limited functionality to DWARFLinkerParallel." This reverts commit 0229dd0626b2538c78ebbd2b1bd44c31fbf1cdec. This introduces two test failures on s390x. tools/dsymutil/X86/location-expression.test: warning: cann't load line table. note: while processing CU1 /builddir/build/BUILD/llvm-18.0.0.src/test/tools/dsymutil/X86/location-expression.test:20:10: error: CHECK: expected string not found in input # CHECK: DW_AT_name{{.*}}"CU1" ^ :34:32: note: scanning from here 0x0000000b: DW_TAG_compile_unit [1] * ^ :37:2: note: possible intended match here DW_AT_name [DW_FORM_strp] ( .debug_str[0x09000000] = ) ^ tools/dsymutil/X86/tls-variable.test: warning: cann't load line table. note: while processing CU1 /builddir/build/BUILD/llvm-18.0.0.src/test/tools/dsymutil/X86/tls-variable.test:19:10: error: CHECK: expected string not found in input # CHECK: DW_AT_name{{.*}}"CU1" ^ :26:32: note: scanning from here 0x0000000b: DW_TAG_compile_unit ^ :29:2: note: possible intended match here DW_AT_name () ^ --- .../llvm/CodeGen/DwarfStringPoolEntry.h | 35 +- llvm/include/llvm/DWARFLinker/DWARFLinker.h | 4 +- .../llvm/DWARFLinkerParallel/AddressesMap.h | 104 -- .../llvm/DWARFLinkerParallel/DWARFFile.h | 12 +- .../llvm/DWARFLinkerParallel/StringPool.h | 4 +- .../llvm/DWARFLinkerParallel/StringTable.h | 88 ++ .../llvm/DebugInfo/DWARF/DWARFDebugMacro.h | 1 - llvm/lib/DWARFLinker/DWARFLinker.cpp | 2 - .../DWARFLinker/DWARFLinkerCompileUnit.cpp | 2 - llvm/lib/DWARFLinkerParallel/ArrayList.h | 92 -- llvm/lib/DWARFLinkerParallel/CMakeLists.txt | 5 - .../DIEAttributeCloner.cpp | 568 ------- .../DWARFLinkerParallel/DIEAttributeCloner.h | 147 -- llvm/lib/DWARFLinkerParallel/DIEGenerator.h | 165 -- .../DWARFLinkerParallel/DWARFEmitterImpl.cpp | 113 +- .../DWARFLinkerParallel/DWARFEmitterImpl.h | 211 ++- llvm/lib/DWARFLinkerParallel/DWARFFile.cpp | 18 - .../DWARFLinkerCompileUnit.cpp | 1402 ----------------- .../DWARFLinkerCompileUnit.h | 468 +----- .../DWARFLinkerGlobalData.h | 159 -- .../DWARFLinkerParallel/DWARFLinkerImpl.cpp | 1079 +------------ .../lib/DWARFLinkerParallel/DWARFLinkerImpl.h | 298 ++-- .../DWARFLinkerParallel/DWARFLinkerUnit.cpp | 130 -- .../lib/DWARFLinkerParallel/DWARFLinkerUnit.h | 131 +- .../DebugLineSectionEmitter.h | 384 ----- .../DWARFLinkerParallel/DependencyTracker.cpp | 428 ----- .../DWARFLinkerParallel/DependencyTracker.h | 102 -- .../DWARFLinkerParallel/IndexedValuesMap.h | 49 - .../DWARFLinkerParallel/OutputSections.cpp | 400 +---- llvm/lib/DWARFLinkerParallel/OutputSections.h | 411 +---- .../StringEntryToDwarfStringPoolEntryMap.h | 72 - .../dwarf5-dwarf4-combination-macho.test | 200 --- .../ARM/DWARFLinkerParallel/dwarf5-macho.test | 92 -- .../DWARFLinkerParallel/fat-dylib-update.test | 110 -- .../ARM/DWARFLinkerParallel/obfuscated.test | 119 -- .../tools/dsymutil/ARM/call-pc-reloc.test | 3 - .../tools/dsymutil/ARM/dwarf5-addr-base.test | 28 +- .../dsymutil/ARM/dwarf5-addrx-0x0-last.test | 8 - .../ARM/dwarf5-str-offsets-base-strx.test | 253 +-- llvm/test/tools/dsymutil/ARM/empty-map.test | 2 - .../test/tools/dsymutil/ARM/extern-alias.test | 4 - .../tools/dsymutil/ARM/fat-arch-name.test | 2 - .../dsymutil/ARM/fat-arch-not-found.test | 2 - llvm/test/tools/dsymutil/ARM/inlined-low_pc.c | 4 - llvm/test/tools/dsymutil/ARM/preload.test | 5 - llvm/test/tools/dsymutil/ARM/scattered.c | 8 +- llvm/test/tools/dsymutil/ARM/thumb.c | 5 - .../basic-linking-bundle.test | 41 - .../basic-linking-x86.test | 190 +-- .../basic-lto-dw4-linking-x86.test | 183 --- .../basic-lto-linking-x86.test | 182 --- .../basic-with-libfat-test.test | 12 - .../X86/DWARFLinkerParallel/empty_range.s | 53 - .../X86/DWARFLinkerParallel/frame-1.test | 36 - .../X86/DWARFLinkerParallel/frame-2.test | 46 - .../DWARFLinkerParallel/multiple-inputs.test | 30 - llvm/test/tools/dsymutil/X86/alias.test | 4 - .../dsymutil/X86/call-site-entry-linking.test | 3 - .../dsymutil/X86/call-site-entry-reloc.test | 3 - .../tools/dsymutil/X86/common-sym-multi.test | 3 - llvm/test/tools/dsymutil/X86/common-sym.test | 2 - .../tools/dsymutil/X86/custom-line-table.test | 2 - .../tools/dsymutil/X86/darwin-bundle.test | 7 - .../test/tools/dsymutil/X86/dead-stripped.cpp | 5 - .../dsymutil/X86/debug-loc-base-addr.test | 2 - .../tools/dsymutil/X86/dwarf4-linetable.test | 2 - .../test/tools/dsymutil/X86/dwarf5-addrx.test | 11 - .../X86/dwarf5-call-site-entry-reloc.test | 3 - .../dsymutil/X86/dwarf5-dw-op-addrx.test | 8 - .../tools/dsymutil/X86/dwarf5-linetable.test | 2 - .../tools/dsymutil/X86/dwarf5-loclists.test | 8 - .../tools/dsymutil/X86/dwarf5-rnglists.test | 10 +- llvm/test/tools/dsymutil/X86/eh_frame.test | 5 - llvm/test/tools/dsymutil/X86/empty-CU.test | 2 - .../dsymutil/X86/fat-archive-input-i386.test | 2 - .../dsymutil/X86/fat-object-input-x86_64.test | 2 - .../X86/fat-object-input-x86_64h.test | 2 - .../tools/dsymutil/X86/generate-empty-CU.test | 10 +- .../X86/global_downgraded_to_static.c | 6 +- .../dsymutil/X86/inlined-static-variable.cpp | 5 - llvm/test/tools/dsymutil/X86/keep-func.test | 5 - llvm/test/tools/dsymutil/X86/label.test | 2 - llvm/test/tools/dsymutil/X86/label2.test | 3 - .../tools/dsymutil/X86/lc_build_version.test | 3 - .../dsymutil/X86/location-expression.test | 17 +- llvm/test/tools/dsymutil/X86/mismatch.m | 2 - .../dsymutil/X86/modules-dwarf-version.m | 3 - llvm/test/tools/dsymutil/X86/modules-empty.m | 7 +- .../tools/dsymutil/X86/multiple-inputs.test | 1 + .../dsymutil/X86/object-prefix-path.test | 5 - .../tools/dsymutil/X86/op-convert-offset.test | 10 +- llvm/test/tools/dsymutil/X86/op-convert.test | 3 - .../dsymutil/X86/papertrail-warnings.test | 2 - .../tools/dsymutil/X86/reflection-dump.test | 3 - .../dsymutil/X86/remarks-linking-archive.text | 7 - .../X86/remarks-linking-bundle-empty.test | 5 - .../dsymutil/X86/remarks-linking-bundle.test | 8 - .../X86/remarks-linking-fat-bundle.test | 7 - llvm/test/tools/dsymutil/X86/reproducer.test | 6 - llvm/test/tools/dsymutil/X86/statistics.test | 1 - .../tools/dsymutil/X86/swift-ast-x86_64.test | 6 - .../tools/dsymutil/X86/swift-dwarf-loc.test | 2 - .../tools/dsymutil/X86/tail-call-linking.test | 3 - llvm/test/tools/dsymutil/X86/thinlto.test | 3 - .../dsymutil/X86/timestamp-mismatch.test | 2 - .../test/tools/dsymutil/X86/tls-variable.test | 1 - .../tools/dsymutil/X86/union-fwd-decl.test | 3 - llvm/test/tools/dsymutil/X86/verify.test | 19 - .../X86/DWARFLinkerParallel/gc-default.test | 134 ++ .../ELF/X86/dwarf4-macro-short.test | 4 - .../llvm-dwarfutil/ELF/X86/dwarf4-macro.test | 17 +- .../ELF/X86/dwarf5-addresses.test | 16 +- .../ELF/X86/dwarf5-attributes.test | 16 +- .../ELF/X86/dwarf5-line-str.test | 16 +- .../ELF/X86/dwarf5-loclists.test | 12 - .../ELF/X86/dwarf5-macro-opcodeop.test | 4 - .../ELF/X86/dwarf5-macro-short.test | 4 - .../llvm-dwarfutil/ELF/X86/dwarf5-macro.test | 17 +- .../ELF/X86/dwarf5-rnglists.test | 12 - .../llvm-dwarfutil/ELF/X86/gc-default.test | 6 - .../gc-func-overlapping-address-ranges.test | 3 - .../llvm-dwarfutil/ELF/X86/gc-maxpc.test | 3 - .../llvm-dwarfutil/ELF/X86/gc-no-garbage.test | 2 - .../gc-unit-overlapping-address-ranges.test | 3 - .../tools/llvm-dwarfutil/ELF/X86/verify.test | 5 - llvm/tools/dsymutil/BinaryHolder.cpp | 21 - llvm/tools/dsymutil/BinaryHolder.h | 3 - llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 38 +- llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp | 48 +- .../CodeGen/DwarfStringPoolEntryRefTest.cpp | 34 +- .../DWARFLinkerParallel/CMakeLists.txt | 1 + .../DWARFLinkerParallel/StringPoolTest.cpp | 5 + .../DWARFLinkerParallel/StringTableTest.cpp | 118 ++ 133 files changed, 1007 insertions(+), 8485 deletions(-) create mode 100644 llvm/include/llvm/DWARFLinkerParallel/StringTable.h delete mode 100644 llvm/lib/DWARFLinkerParallel/ArrayList.h delete mode 100644 llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.cpp delete mode 100644 llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.h delete mode 100644 llvm/lib/DWARFLinkerParallel/DIEGenerator.h delete mode 100644 llvm/lib/DWARFLinkerParallel/DWARFFile.cpp delete mode 100644 llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.cpp delete mode 100644 llvm/lib/DWARFLinkerParallel/DWARFLinkerGlobalData.h delete mode 100644 llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.cpp delete mode 100644 llvm/lib/DWARFLinkerParallel/DebugLineSectionEmitter.h delete mode 100644 llvm/lib/DWARFLinkerParallel/DependencyTracker.cpp delete mode 100644 llvm/lib/DWARFLinkerParallel/DependencyTracker.h delete mode 100644 llvm/lib/DWARFLinkerParallel/IndexedValuesMap.h delete mode 100644 llvm/lib/DWARFLinkerParallel/StringEntryToDwarfStringPoolEntryMap.h delete mode 100644 llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/dwarf5-dwarf4-combination-macho.test delete mode 100644 llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/dwarf5-macho.test delete mode 100644 llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/fat-dylib-update.test delete mode 100644 llvm/test/tools/dsymutil/ARM/DWARFLinkerParallel/obfuscated.test delete mode 100644 llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-linking-bundle.test delete mode 100644 llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-lto-dw4-linking-x86.test delete mode 100644 llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-lto-linking-x86.test delete mode 100644 llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-with-libfat-test.test delete mode 100644 llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/empty_range.s delete mode 100644 llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/frame-1.test delete mode 100644 llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/frame-2.test delete mode 100644 llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/multiple-inputs.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/DWARFLinkerParallel/gc-default.test create mode 100644 llvm/unittests/DWARFLinkerParallel/StringTableTest.cpp diff --git a/llvm/include/llvm/CodeGen/DwarfStringPoolEntry.h b/llvm/include/llvm/CodeGen/DwarfStringPoolEntry.h index 188dfbe790e2c..7822ebf2eb099 100644 --- a/llvm/include/llvm/CodeGen/DwarfStringPoolEntry.h +++ b/llvm/include/llvm/CodeGen/DwarfStringPoolEntry.h @@ -27,34 +27,29 @@ struct DwarfStringPoolEntry { bool isIndexed() const { return Index != NotIndexed; } }; -/// DwarfStringPoolEntry with string keeping externally. -struct DwarfStringPoolEntryWithExtString : public DwarfStringPoolEntry { - StringRef String; -}; - /// DwarfStringPoolEntryRef: Dwarf string pool entry reference. /// /// Dwarf string pool entry keeps string value and its data. /// There are two variants how data are represented: /// -/// 1. String data in pool - StringMapEntry. -/// 2. External string data - DwarfStringPoolEntryWithExtString. +/// 1. By value - StringMapEntry. +/// 2. By pointer - StringMapEntry. /// -/// The external data variant allows reducing memory usage for the case -/// when string pool entry does not have data: string entry does not -/// keep any data and so no need to waste space for the full -/// DwarfStringPoolEntry. It is recommended to use external variant if not all -/// entries of dwarf string pool have corresponding DwarfStringPoolEntry. +/// The "By pointer" variant allows for reducing memory usage for the case +/// when string pool entry does not have data: it keeps the null pointer +/// and so no need to waste space for the full DwarfStringPoolEntry. +/// It is recommended to use "By pointer" variant if not all entries +/// of dwarf string pool have corresponding DwarfStringPoolEntry. class DwarfStringPoolEntryRef { /// Pointer type for "By value" string entry. using ByValStringEntryPtr = const StringMapEntry *; - /// Pointer type for external string entry. - using ExtStringEntryPtr = const DwarfStringPoolEntryWithExtString *; + /// Pointer type for "By pointer" string entry. + using ByPtrStringEntryPtr = const StringMapEntry *; /// Pointer to the dwarf string pool Entry. - PointerUnion MapEntry = nullptr; + PointerUnion MapEntry = nullptr; public: DwarfStringPoolEntryRef() = default; @@ -66,8 +61,10 @@ class DwarfStringPoolEntryRef { /// ASSUMPTION: DwarfStringPoolEntryRef keeps pointer to \p Entry, /// thus specified entry mustn`t be reallocated. - DwarfStringPoolEntryRef(const DwarfStringPoolEntryWithExtString &Entry) - : MapEntry(&Entry) {} + DwarfStringPoolEntryRef(const StringMapEntry &Entry) + : MapEntry(&Entry) { + assert(cast(MapEntry)->second != nullptr); + } explicit operator bool() const { return !MapEntry.isNull(); } @@ -91,7 +88,7 @@ class DwarfStringPoolEntryRef { if (isa(MapEntry)) return cast(MapEntry)->first(); - return cast(MapEntry)->String; + return cast(MapEntry)->first(); } /// \returns the entire string pool entry for convenience. @@ -99,7 +96,7 @@ class DwarfStringPoolEntryRef { if (isa(MapEntry)) return cast(MapEntry)->second; - return *cast(MapEntry); + return *cast(MapEntry)->second; } bool operator==(const DwarfStringPoolEntryRef &X) const { diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h index 5ca6f2e4e4e06..b11e8e14aee4e 100644 --- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -270,11 +270,9 @@ using UnitListTy = std::vector>; /// and its address map. class DWARFFile { public: - using UnloadCallbackTy = std::function; DWARFFile(StringRef Name, std::unique_ptr Dwarf, std::unique_ptr Addresses, - const std::vector &Warnings, - UnloadCallbackTy = nullptr) + const std::vector &Warnings) : FileName(Name), Dwarf(std::move(Dwarf)), Addresses(std::move(Addresses)), Warnings(Warnings) {} diff --git a/llvm/include/llvm/DWARFLinkerParallel/AddressesMap.h b/llvm/include/llvm/DWARFLinkerParallel/AddressesMap.h index 22fbec20d7d37..5d735abab419e 100644 --- a/llvm/include/llvm/DWARFLinkerParallel/AddressesMap.h +++ b/llvm/include/llvm/DWARFLinkerParallel/AddressesMap.h @@ -10,10 +10,8 @@ #define LLVM_DWARFLINKERPARALLEL_ADDRESSESMAP_H #include "llvm/ADT/AddressRanges.h" -#include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" #include "llvm/DebugInfo/DWARF/DWARFExpression.h" -#include "llvm/DebugInfo/DWARF/DWARFUnit.h" #include namespace llvm { @@ -64,108 +62,6 @@ class AddressesMap { /// Erases all data. virtual void clear() = 0; - - /// This function checks whether variable has DWARF expression containing - /// operation referencing live address(f.e. DW_OP_addr, DW_OP_addrx...). - /// \returns first is true if the expression has an operation referencing an - /// address. - /// second is the relocation adjustment value if the live address is - /// referenced. - std::pair> - getVariableRelocAdjustment(const DWARFDie &DIE) { - assert((DIE.getTag() == dwarf::DW_TAG_variable || - DIE.getTag() == dwarf::DW_TAG_constant) && - "Wrong type of input die"); - - const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); - - // Check if DIE has DW_AT_location attribute. - DWARFUnit *U = DIE.getDwarfUnit(); - std::optional LocationIdx = - Abbrev->findAttributeIndex(dwarf::DW_AT_location); - if (!LocationIdx) - return std::make_pair(false, std::nullopt); - - // Get offset to the DW_AT_location attribute. - uint64_t AttrOffset = - Abbrev->getAttributeOffsetFromIndex(*LocationIdx, DIE.getOffset(), *U); - - // Get value of the DW_AT_location attribute. - std::optional LocationValue = - Abbrev->getAttributeValueFromOffset(*LocationIdx, AttrOffset, *U); - if (!LocationValue) - return std::make_pair(false, std::nullopt); - - // Check that DW_AT_location attribute is of 'exprloc' class. - // Handling value of location expressions for attributes of 'loclist' - // class is not implemented yet. - std::optional> Expr = LocationValue->getAsBlock(); - if (!Expr) - return std::make_pair(false, std::nullopt); - - // Parse 'exprloc' expression. - DataExtractor Data(toStringRef(*Expr), U->getContext().isLittleEndian(), - U->getAddressByteSize()); - DWARFExpression Expression(Data, U->getAddressByteSize(), - U->getFormParams().Format); - - bool HasLocationAddress = false; - uint64_t CurExprOffset = 0; - for (DWARFExpression::iterator It = Expression.begin(); - It != Expression.end(); ++It) { - DWARFExpression::iterator NextIt = It; - ++NextIt; - - const DWARFExpression::Operation &Op = *It; - switch (Op.getCode()) { - case dwarf::DW_OP_const2u: - case dwarf::DW_OP_const4u: - case dwarf::DW_OP_const8u: - case dwarf::DW_OP_const2s: - case dwarf::DW_OP_const4s: - case dwarf::DW_OP_const8s: - if (NextIt == Expression.end() || !isTlsAddressCode(NextIt->getCode())) - break; - [[fallthrough]]; - case dwarf::DW_OP_addr: { - HasLocationAddress = true; - // Check relocation for the address. - if (std::optional RelocAdjustment = - getExprOpAddressRelocAdjustment(*U, Op, - AttrOffset + CurExprOffset, - AttrOffset + Op.getEndOffset())) - return std::make_pair(HasLocationAddress, *RelocAdjustment); - } break; - case dwarf::DW_OP_constx: - case dwarf::DW_OP_addrx: { - HasLocationAddress = true; - if (std::optional AddressOffset = - DIE.getDwarfUnit()->getIndexedAddressOffset( - Op.getRawOperand(0))) { - // Check relocation for the address. - if (std::optional RelocAdjustment = - getExprOpAddressRelocAdjustment( - *U, Op, *AddressOffset, - *AddressOffset + - DIE.getDwarfUnit()->getAddressByteSize())) - return std::make_pair(HasLocationAddress, *RelocAdjustment); - } - } break; - default: { - // Nothing to do. - } break; - } - CurExprOffset = Op.getEndOffset(); - } - - return std::make_pair(HasLocationAddress, std::nullopt); - } - -protected: - inline bool isTlsAddressCode(uint8_t DW_OP_Code) { - return DW_OP_Code == dwarf::DW_OP_form_tls_address || - DW_OP_Code == dwarf::DW_OP_GNU_push_tls_address; - } }; } // end of namespace dwarflinker_parallel diff --git a/llvm/include/llvm/DWARFLinkerParallel/DWARFFile.h b/llvm/include/llvm/DWARFLinkerParallel/DWARFFile.h index e48150ef2339e..c20d59f9771d9 100644 --- a/llvm/include/llvm/DWARFLinkerParallel/DWARFFile.h +++ b/llvm/include/llvm/DWARFLinkerParallel/DWARFFile.h @@ -30,7 +30,14 @@ class DWARFFile { DWARFFile(StringRef Name, std::unique_ptr Dwarf, std::unique_ptr Addresses, const std::vector &Warnings, - UnloadCallbackTy UnloadFunc = nullptr); + UnloadCallbackTy UnloadFunc = nullptr) + : FileName(Name), Dwarf(std::move(Dwarf)), + Addresses(std::move(Addresses)), Warnings(Warnings), + UnloadFunc(UnloadFunc) { + if (this->Dwarf) + Endianess = this->Dwarf->isLittleEndian() ? support::endianness::little + : support::endianness::big; + } /// Object file name. StringRef FileName; @@ -44,6 +51,9 @@ class DWARFFile { /// Warnings for object file. const std::vector &Warnings; + /// Endiannes of source DWARF information. + support::endianness Endianess = support::endianness::little; + /// Callback to the module keeping object file to unload. UnloadCallbackTy UnloadFunc; diff --git a/llvm/include/llvm/DWARFLinkerParallel/StringPool.h b/llvm/include/llvm/DWARFLinkerParallel/StringPool.h index 8608476a8dc79..44383ed6c7ddc 100644 --- a/llvm/include/llvm/DWARFLinkerParallel/StringPool.h +++ b/llvm/include/llvm/DWARFLinkerParallel/StringPool.h @@ -21,7 +21,7 @@ namespace dwarflinker_parallel { /// StringEntry keeps data of the string: the length, external offset /// and a string body which is placed right after StringEntry. -using StringEntry = StringMapEntry; +using StringEntry = StringMapEntry; class StringPoolEntryInfo { public: @@ -64,8 +64,6 @@ class StringPool parallel::PerThreadBumpPtrAllocator &getAllocatorRef() { return Allocator; } - void clear() { Allocator.Reset(); } - private: parallel::PerThreadBumpPtrAllocator Allocator; }; diff --git a/llvm/include/llvm/DWARFLinkerParallel/StringTable.h b/llvm/include/llvm/DWARFLinkerParallel/StringTable.h new file mode 100644 index 0000000000000..4f8aece521d85 --- /dev/null +++ b/llvm/include/llvm/DWARFLinkerParallel/StringTable.h @@ -0,0 +1,88 @@ +//===- StringTable.h --------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DWARFLINKERPARALLEL_STRINGTABLE_H +#define LLVM_DWARFLINKERPARALLEL_STRINGTABLE_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/DWARFLinkerParallel/StringPool.h" + +namespace llvm { +namespace dwarflinker_parallel { + +using StringsVector = SmallVector; + +/// This class prepares strings for emission into .debug_str table: +/// translates string if necessary, assigns index and offset, keeps in order. +class StringTable { +public: + StringTable(StringPool &Strings, + std::function StringsTranslator) + : Strings(Strings), StringsTranslator(StringsTranslator) {} + ~StringTable() {} + + /// Add string to the vector of strings which should be emitted. + /// Translate input string if neccessary, assign index and offset. + /// \returns updated string entry. + StringEntry *add(StringEntry *String) { + // Translate string if necessary. + if (StringsTranslator) + String = Strings.insert(StringsTranslator(String->first())).first; + + // Store String for emission and assign index and offset. + if (String->getValue() == nullptr) { + DwarfStringPoolEntry *NewEntry = + Strings.getAllocatorRef().Allocate(); + + NewEntry->Symbol = nullptr; + NewEntry->Index = StringEntriesForEmission.size(); + + if (StringEntriesForEmission.empty()) + NewEntry->Offset = 0; + else { + StringEntry *PrevString = StringEntriesForEmission.back(); + NewEntry->Offset = + PrevString->getValue()->Offset + PrevString->getKeyLength() + 1; + } + + String->getValue() = NewEntry; + StringEntriesForEmission.push_back(String); + } + + return String; + } + + /// Erase contents of StringsForEmission. + void clear() { StringEntriesForEmission.clear(); } + + /// Enumerate all strings in sequential order and call \p Handler for each + /// string. + void forEach(function_ref Handler) const { + for (const StringEntry *Entry : StringEntriesForEmission) + Handler(*Entry); + } + + std::function getTranslator() { + return StringsTranslator; + } + +protected: + /// List of strings for emission. + StringsVector StringEntriesForEmission; + + /// String pool for the translated strings. + StringPool &Strings; + + /// Translator for the strings. + std::function StringsTranslator; +}; + +} // end of namespace dwarflinker_parallel +} // end namespace llvm + +#endif // LLVM_DWARFLINKERPARALLEL_STRINGTABLE_H diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h index 6b1b2ae6d7e04..10d4eb25a921b 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h @@ -22,7 +22,6 @@ class DwarfStreamer; class DWARFDebugMacro { friend DwarfStreamer; - friend dwarflinker_parallel::CompileUnit; /// DWARFv5 section 6.3.1 Macro Information Header. enum HeaderFlagMask { diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp index ae95a30873d9f..dbbd1b434c7c8 100644 --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -444,10 +444,8 @@ DWARFLinker::getVariableRelocAdjustment(AddressesMap &RelocMgr, const DWARFExpression::Operation &Op = *It; switch (Op.getCode()) { - case dwarf::DW_OP_const2u: case dwarf::DW_OP_const4u: case dwarf::DW_OP_const8u: - case dwarf::DW_OP_const2s: case dwarf::DW_OP_const4s: case dwarf::DW_OP_const8s: if (NextIt == Expression.end() || !isTlsAddressCode(NextIt->getCode())) diff --git a/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp index 06559bc38c86c..add0d94da73fc 100644 --- a/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp @@ -97,10 +97,8 @@ void CompileUnit::markEverythingAsKept() { ++NextIt; switch (It->getCode()) { - case dwarf::DW_OP_const2u: case dwarf::DW_OP_const4u: case dwarf::DW_OP_const8u: - case dwarf::DW_OP_const2s: case dwarf::DW_OP_const4s: case dwarf::DW_OP_const8s: if (NextIt == Expression.end() || diff --git a/llvm/lib/DWARFLinkerParallel/ArrayList.h b/llvm/lib/DWARFLinkerParallel/ArrayList.h deleted file mode 100644 index 67aea161f510e..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/ArrayList.h +++ /dev/null @@ -1,92 +0,0 @@ -//===- ArrayList.h ----------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_DWARFLINKERPARALLEL_ARRAYLIST_H -#define LLVM_LIB_DWARFLINKERPARALLEL_ARRAYLIST_H - -#include "DWARFLinkerGlobalData.h" -#include "llvm/Support/PerThreadBumpPtrAllocator.h" - -namespace llvm { -namespace dwarflinker_parallel { - -/// 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. -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; - } - - if (CurGroup->ItemsCount == ItemsGroupSize) { - // Allocate next ItemsGroup if current one is full. - LastGroup = Allocator->Allocate(); - LastGroup->ItemsCount = 0; - LastGroup->Next = nullptr; - CurGroup->Next = LastGroup; - CurGroup = LastGroup; - } - - // Copy item into the next position inside current ItemsGroup. - CurGroup->Items[CurGroup->ItemsCount] = Item; - return CurGroup->Items[CurGroup->ItemsCount++]; - } - - using ItemHandlerTy = function_ref; - - /// Enumerate all items and apply specified \p Handler to each. - void forEach(ItemHandlerTy Handler) { - for (ItemsGroup *CurGroup = GroupsHead; CurGroup != nullptr; - CurGroup = CurGroup->Next) { - for (size_t Idx = 0; Idx < CurGroup->ItemsCount; Idx++) { - Handler(CurGroup->Items[Idx]); - } - } - } - - /// Check whether list is empty. - bool empty() { return GroupsHead == nullptr; } - - /// Erase list. - void erase() { - GroupsHead = nullptr; - LastGroup = nullptr; - } - - void setAllocator(parallel::PerThreadBumpPtrAllocator *Allocator) { - this->Allocator = Allocator; - } - -protected: - struct ItemsGroup { - std::array Items; - ItemsGroup *Next = nullptr; - size_t ItemsCount = 0; - }; - - ItemsGroup *GroupsHead = nullptr; - ItemsGroup *LastGroup = nullptr; - parallel::PerThreadBumpPtrAllocator *Allocator = nullptr; -}; - -} // end of namespace dwarflinker_parallel -} // end namespace llvm - -#endif // LLVM_LIB_DWARFLINKERPARALLEL_ARRAYLIST_H diff --git a/llvm/lib/DWARFLinkerParallel/CMakeLists.txt b/llvm/lib/DWARFLinkerParallel/CMakeLists.txt index d321ecf8d5ce8..8a1481c9df3e4 100644 --- a/llvm/lib/DWARFLinkerParallel/CMakeLists.txt +++ b/llvm/lib/DWARFLinkerParallel/CMakeLists.txt @@ -1,12 +1,7 @@ add_llvm_component_library(LLVMDWARFLinkerParallel - DependencyTracker.cpp - DIEAttributeCloner.cpp DWARFEmitterImpl.cpp - DWARFFile.cpp DWARFLinker.cpp - DWARFLinkerCompileUnit.cpp DWARFLinkerImpl.cpp - DWARFLinkerUnit.cpp OutputSections.cpp StringPool.cpp diff --git a/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.cpp b/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.cpp deleted file mode 100644 index 25a55026dd675..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.cpp +++ /dev/null @@ -1,568 +0,0 @@ -//=== DIEAttributeCloner.cpp ----------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "DIEAttributeCloner.h" -#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" - -namespace llvm { -namespace dwarflinker_parallel { - -void DIEAttributeCloner::clone() { - DWARFUnit &U = CU.getOrigUnit(); - - // Extract and clone every attribute. - DWARFDataExtractor Data = U.getDebugInfoExtractor(); - - uint64_t Offset = InputDieEntry->getOffset(); - // Point to the next DIE (generally there is always at least a NULL - // entry after the current one). If this is a lone - // DW_TAG_compile_unit without any children, point to the next unit. - uint64_t NextOffset = (InputDIEIdx + 1 < U.getNumDIEs()) - ? U.getDIEAtIndex(InputDIEIdx + 1).getOffset() - : U.getNextUnitOffset(); - - // We could copy the data only if we need to apply a relocation to it. After - // testing, it seems there is no performance downside to doing the copy - // unconditionally, and it makes the code simpler. - SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset)); - Data = - DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize()); - - // Modify the copy with relocated addresses. - CU.getContaingFile().Addresses->applyValidRelocs(DIECopy, Offset, - Data.isLittleEndian()); - - // Reset the Offset to 0 as we will be working on the local copy of - // the data. - Offset = 0; - - const auto *Abbrev = InputDieEntry->getAbbreviationDeclarationPtr(); - Offset += getULEB128Size(Abbrev->getCode()); - - // Set current output offset. - AttrOutOffset = OutDIE->getOffset(); - for (const auto &AttrSpec : Abbrev->attributes()) { - // Check whether current attribute should be skipped. - if (shouldSkipAttribute(AttrSpec)) { - DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, - U.getFormParams()); - continue; - } - - DWARFFormValue Val = AttrSpec.getFormValue(); - Val.extractValue(Data, &Offset, U.getFormParams(), &U); - - // Clone current attribute. - switch (AttrSpec.Form) { - case dwarf::DW_FORM_strp: - case dwarf::DW_FORM_line_strp: - case dwarf::DW_FORM_string: - case dwarf::DW_FORM_strx: - case dwarf::DW_FORM_strx1: - case dwarf::DW_FORM_strx2: - case dwarf::DW_FORM_strx3: - case dwarf::DW_FORM_strx4: - AttrOutOffset += cloneStringAttr(Val, AttrSpec); - break; - case dwarf::DW_FORM_ref_addr: - case dwarf::DW_FORM_ref1: - case dwarf::DW_FORM_ref2: - case dwarf::DW_FORM_ref4: - case dwarf::DW_FORM_ref8: - case dwarf::DW_FORM_ref_udata: - AttrOutOffset += cloneDieRefAttr(Val, AttrSpec); - break; - case dwarf::DW_FORM_data1: - case dwarf::DW_FORM_data2: - case dwarf::DW_FORM_data4: - case dwarf::DW_FORM_data8: - case dwarf::DW_FORM_udata: - case dwarf::DW_FORM_sdata: - case dwarf::DW_FORM_sec_offset: - case dwarf::DW_FORM_flag: - case dwarf::DW_FORM_flag_present: - case dwarf::DW_FORM_rnglistx: - case dwarf::DW_FORM_loclistx: - case dwarf::DW_FORM_implicit_const: - AttrOutOffset += cloneScalarAttr(Val, AttrSpec); - break; - case dwarf::DW_FORM_block: - case dwarf::DW_FORM_block1: - case dwarf::DW_FORM_block2: - case dwarf::DW_FORM_block4: - case dwarf::DW_FORM_exprloc: - AttrOutOffset += cloneBlockAttr(Val, AttrSpec); - break; - case dwarf::DW_FORM_addr: - case dwarf::DW_FORM_addrx: - case dwarf::DW_FORM_addrx1: - case dwarf::DW_FORM_addrx2: - case dwarf::DW_FORM_addrx3: - case dwarf::DW_FORM_addrx4: - AttrOutOffset += cloneAddressAttr(Val, AttrSpec); - break; - default: - CU.warn("unsupported attribute form " + - dwarf::FormEncodingString(AttrSpec.Form) + - " in DieAttributeCloner::clone(). Dropping.", - InputDieEntry); - } - } - - // We convert source strings into the indexed form for DWARFv5. - // Check if original compile unit already has DW_AT_str_offsets_base - // attribute. - if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit && - CU.getVersion() >= 5 && !AttrInfo.HasStringOffsetBaseAttr) { - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugOffsetPatch{ - AttrOutOffset, - &CU.getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets), - true}, - PatchesOffsets); - - AttrOutOffset += Generator - .addScalarAttribute(dwarf::DW_AT_str_offsets_base, - dwarf::DW_FORM_sec_offset, - CU.getDebugStrOffsetsHeaderSize()) - .second; - } -} - -bool DIEAttributeCloner::shouldSkipAttribute( - DWARFAbbreviationDeclaration::AttributeSpec AttrSpec) { - switch (AttrSpec.Attr) { - default: - return false; - case dwarf::DW_AT_low_pc: - case dwarf::DW_AT_high_pc: - case dwarf::DW_AT_ranges: - if (CU.getGlobalData().getOptions().UpdateIndexTablesOnly) - return false; - - // Skip address attribute if we are in function scope and function does not - // reference live address. - return CU.getDIEInfo(InputDIEIdx).getIsInFunctionScope() && - !FuncAddressAdjustment.has_value(); - case dwarf::DW_AT_rnglists_base: - // In case !Update the .debug_addr table is not generated/preserved. - // Thus instead of DW_FORM_rnglistx the DW_FORM_sec_offset is used. - // Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the - // DW_AT_rnglists_base is removed. - return !CU.getGlobalData().getOptions().UpdateIndexTablesOnly; - case dwarf::DW_AT_loclists_base: - // In case !Update the .debug_addr table is not generated/preserved. - // Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used. - // Since DW_AT_loclists_base is used for only DW_FORM_loclistx the - // DW_AT_loclists_base is removed. - return !CU.getGlobalData().getOptions().UpdateIndexTablesOnly; - case dwarf::DW_AT_location: - case dwarf::DW_AT_frame_base: - if (CU.getGlobalData().getOptions().UpdateIndexTablesOnly) - return false; - - // When location expression contains an address: skip this attribute - // if it does not reference live address. - if (HasLocationExpressionAddress) - return !VarAddressAdjustment.has_value(); - - // Skip location attribute if we are in function scope and function does not - // reference live address. - return CU.getDIEInfo(InputDIEIdx).getIsInFunctionScope() && - !FuncAddressAdjustment.has_value(); - } -} - -size_t DIEAttributeCloner::cloneStringAttr( - const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) { - std::optional String = dwarf::toString(Val); - if (!String) { - CU.warn("cann't read string attribute."); - return 0; - } - - StringEntry *StringInPool = - CU.getGlobalData().getStringPool().insert(*String).first; - if (AttrSpec.Form == dwarf::DW_FORM_line_strp) { - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugLineStrPatch{{AttrOutOffset}, StringInPool}, PatchesOffsets); - return Generator - .addStringPlaceholderAttribute(AttrSpec.Attr, dwarf::DW_FORM_line_strp) - .second; - } - - // Update attributes info. - if (AttrSpec.Attr == dwarf::DW_AT_name) - AttrInfo.Name = StringInPool; - else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name || - AttrSpec.Attr == dwarf::DW_AT_linkage_name) - AttrInfo.MangledName = StringInPool; - - if (CU.getVersion() < 5) { - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugStrPatch{{AttrOutOffset}, StringInPool}, PatchesOffsets); - - return Generator - .addStringPlaceholderAttribute(AttrSpec.Attr, dwarf::DW_FORM_strp) - .second; - } - - return Generator - .addIndexedStringAttribute(AttrSpec.Attr, dwarf::DW_FORM_strx, - CU.getDebugStrIndex(StringInPool)) - .second; -} - -size_t DIEAttributeCloner::cloneDieRefAttr( - const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) { - if (AttrSpec.Attr == dwarf::DW_AT_sibling) - return 0; - - std::optional> RefDiePair = - CU.resolveDIEReference(Val); - if (!RefDiePair) { - // If the referenced DIE is not found, drop the attribute. - CU.warn("cann't find referenced DIE.", InputDieEntry); - return 0; - } - assert(RefDiePair->first->getStage() >= CompileUnit::Stage::Loaded); - assert(RefDiePair->second != 0); - - // Get output offset for referenced DIE. - uint64_t OutDieOffset = - RefDiePair->first->getDieOutOffset(RefDiePair->second); - - // Examine whether referenced DIE is in current compile unit. - bool IsLocal = CU.getUniqueID() == RefDiePair->first->getUniqueID(); - - // Set attribute form basing on the kind of referenced DIE(local or not?). - dwarf::Form NewForm = IsLocal ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr; - - // Check whether current attribute references already cloned DIE inside - // the same compilation unit. If true - write the already known offset value. - if (IsLocal && (OutDieOffset != 0)) - return Generator.addScalarAttribute(AttrSpec.Attr, NewForm, OutDieOffset) - .second; - - // If offset value is not known at this point then create patch for the - // reference value and write dummy value into the attribute. - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugDieRefPatch{AttrOutOffset, &CU, RefDiePair->first, - RefDiePair->second}, - PatchesOffsets); - return Generator.addScalarAttribute(AttrSpec.Attr, NewForm, 0xBADDEF).second; -} - -size_t DIEAttributeCloner::cloneScalarAttr( - const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) { - - // Create patches for attribute referencing other non invariant section. - // Invariant section could not be updated here as this section and - // reference to it do not change value in case --update. - if (AttrSpec.Attr == dwarf::DW_AT_macro_info) { - if (std::optional Offset = Val.getAsSectionOffset()) { - const DWARFDebugMacro *Macro = - CU.getContaingFile().Dwarf->getDebugMacinfo(); - if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset)) - return 0; - - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugOffsetPatch{AttrOutOffset, &CU.getOrCreateSectionDescriptor( - DebugSectionKind::DebugMacinfo)}, - PatchesOffsets); - } - } else if (AttrSpec.Attr == dwarf::DW_AT_macros) { - if (std::optional Offset = Val.getAsSectionOffset()) { - const DWARFDebugMacro *Macro = - CU.getContaingFile().Dwarf->getDebugMacro(); - if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset)) - return 0; - - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugOffsetPatch{AttrOutOffset, &CU.getOrCreateSectionDescriptor( - DebugSectionKind::DebugMacro)}, - PatchesOffsets); - } - } else if (AttrSpec.Attr == dwarf::DW_AT_stmt_list) { - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugOffsetPatch{AttrOutOffset, &CU.getOrCreateSectionDescriptor( - DebugSectionKind::DebugLine)}, - PatchesOffsets); - } else if (AttrSpec.Attr == dwarf::DW_AT_str_offsets_base) { - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugOffsetPatch{ - AttrOutOffset, - &CU.getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets), - true}, - PatchesOffsets); - - // Use size of .debug_str_offsets header as attribute value. The offset - // to .debug_str_offsets would be added later while patching. - AttrInfo.HasStringOffsetBaseAttr = true; - return Generator - .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, - CU.getDebugStrOffsetsHeaderSize()) - .second; - } - - uint64_t Value; - if (CU.getGlobalData().getOptions().UpdateIndexTablesOnly) { - if (auto OptionalValue = Val.getAsUnsignedConstant()) - Value = *OptionalValue; - else if (auto OptionalValue = Val.getAsSignedConstant()) - Value = *OptionalValue; - else if (auto OptionalValue = Val.getAsSectionOffset()) - Value = *OptionalValue; - else { - CU.warn("unsupported scalar attribute form. Dropping attribute.", - InputDieEntry); - return 0; - } - - if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value) - AttrInfo.IsDeclaration = true; - - if (AttrSpec.Form == dwarf::DW_FORM_loclistx) - return Generator.addLocListAttribute(AttrSpec.Attr, AttrSpec.Form, Value) - .second; - - return Generator.addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, Value) - .second; - } - - dwarf::Form ResultingForm = AttrSpec.Form; - if (AttrSpec.Form == dwarf::DW_FORM_rnglistx) { - // DWARFLinker does not generate .debug_addr table. Thus we need to change - // all "addrx" related forms to "addr" version. Change DW_FORM_rnglistx - // to DW_FORM_sec_offset here. - std::optional Index = Val.getAsSectionOffset(); - if (!Index) { - CU.warn("cann't read the attribute. Dropping.", InputDieEntry); - return 0; - } - std::optional Offset = CU.getOrigUnit().getRnglistOffset(*Index); - if (!Offset) { - CU.warn("cann't read the attribute. Dropping.", InputDieEntry); - return 0; - } - - Value = *Offset; - ResultingForm = dwarf::DW_FORM_sec_offset; - } else if (AttrSpec.Form == dwarf::DW_FORM_loclistx) { - // DWARFLinker does not generate .debug_addr table. Thus we need to change - // all "addrx" related forms to "addr" version. Change DW_FORM_loclistx - // to DW_FORM_sec_offset here. - std::optional Index = Val.getAsSectionOffset(); - if (!Index) { - CU.warn("cann't read the attribute. Dropping.", InputDieEntry); - return 0; - } - std::optional Offset = CU.getOrigUnit().getLoclistOffset(*Index); - if (!Offset) { - CU.warn("cann't read the attribute. Dropping.", InputDieEntry); - return 0; - } - - Value = *Offset; - ResultingForm = dwarf::DW_FORM_sec_offset; - } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc && - InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) { - std::optional LowPC = CU.getLowPc(); - if (!LowPC) - return 0; - // Dwarf >= 4 high_pc is an size, not an address. - Value = CU.getHighPc() - *LowPC; - } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset) - Value = *Val.getAsSectionOffset(); - else if (AttrSpec.Form == dwarf::DW_FORM_sdata) - Value = *Val.getAsSignedConstant(); - else if (auto OptionalValue = Val.getAsUnsignedConstant()) - Value = *OptionalValue; - else { - CU.warn("unsupported scalar attribute form. Dropping attribute.", - InputDieEntry); - return 0; - } - - if (AttrSpec.Attr == dwarf::DW_AT_ranges || - AttrSpec.Attr == dwarf::DW_AT_start_scope) { - // Create patch for the range offset value. - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugRangePatch{{AttrOutOffset}, - InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit}, - PatchesOffsets); - AttrInfo.HasRanges = true; - } else if (DWARFAttribute::mayHaveLocationList(AttrSpec.Attr) && - dwarf::doesFormBelongToClass(AttrSpec.Form, - DWARFFormValue::FC_SectionOffset, - CU.getOrigUnit().getVersion())) { - int64_t AddrAdjustmentValue = 0; - if (VarAddressAdjustment) - AddrAdjustmentValue = *VarAddressAdjustment; - else if (FuncAddressAdjustment) - AddrAdjustmentValue = *FuncAddressAdjustment; - - // Create patch for the location offset value. - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugLocPatch{{AttrOutOffset}, AddrAdjustmentValue}, PatchesOffsets); - } else if (AttrSpec.Attr == dwarf::DW_AT_addr_base) { - DebugInfoOutputSection.notePatchWithOffsetUpdate( - DebugOffsetPatch{ - AttrOutOffset, - &CU.getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr), - true}, - PatchesOffsets); - - // Use size of .debug_addr header as attribute value. The offset to - // .debug_addr would be added later while patching. - return Generator - .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, - CU.getDebugAddrHeaderSize()) - .second; - } else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value) - AttrInfo.IsDeclaration = true; - - return Generator.addScalarAttribute(AttrSpec.Attr, ResultingForm, Value) - .second; -} - -size_t DIEAttributeCloner::cloneBlockAttr( - const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) { - - size_t NumberOfPatchesAtStart = PatchesOffsets.size(); - - // If the block is a DWARF Expression, clone it into the temporary - // buffer using cloneExpression(), otherwise copy the data directly. - SmallVector Buffer; - ArrayRef Bytes = *Val.getAsBlock(); - if (DWARFAttribute::mayHaveLocationExpr(AttrSpec.Attr) && - (Val.isFormClass(DWARFFormValue::FC_Block) || - Val.isFormClass(DWARFFormValue::FC_Exprloc))) { - DWARFUnit &OrigUnit = CU.getOrigUnit(); - DataExtractor Data(StringRef((const char *)Bytes.data(), Bytes.size()), - OrigUnit.isLittleEndian(), - OrigUnit.getAddressByteSize()); - DWARFExpression Expr(Data, OrigUnit.getAddressByteSize(), - OrigUnit.getFormParams().Format); - - CU.cloneDieAttrExpression(Expr, Buffer, DebugInfoOutputSection, - VarAddressAdjustment, PatchesOffsets); - Bytes = Buffer; - } - - // The expression location data might be updated and exceed the original size. - // Check whether the new data fits into the original form. - dwarf::Form ResultForm = AttrSpec.Form; - if ((ResultForm == dwarf::DW_FORM_block1 && Bytes.size() > UINT8_MAX) || - (ResultForm == dwarf::DW_FORM_block2 && Bytes.size() > UINT16_MAX) || - (ResultForm == dwarf::DW_FORM_block4 && Bytes.size() > UINT32_MAX)) - ResultForm = dwarf::DW_FORM_block; - - size_t FinalAttributeSize; - if (AttrSpec.Form == dwarf::DW_FORM_exprloc) - FinalAttributeSize = - Generator.addLocationAttribute(AttrSpec.Attr, ResultForm, Bytes).second; - else - FinalAttributeSize = - Generator.addBlockAttribute(AttrSpec.Attr, ResultForm, Bytes).second; - - // Update patches offsets with the size of length field for Bytes. - for (size_t Idx = NumberOfPatchesAtStart; Idx < PatchesOffsets.size(); - Idx++) { - assert(FinalAttributeSize > Bytes.size()); - *PatchesOffsets[Idx] += - (AttrOutOffset + (FinalAttributeSize - Bytes.size())); - } - - return FinalAttributeSize; -} - -size_t DIEAttributeCloner::cloneAddressAttr( - const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) { - if (AttrSpec.Attr == dwarf::DW_AT_low_pc) - AttrInfo.HasLowPc = true; - - if (CU.getGlobalData().getOptions().UpdateIndexTablesOnly) - return Generator - .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, Val.getRawUValue()) - .second; - - // Cloned Die may have address attributes relocated to a - // totally unrelated value. This can happen: - // - If high_pc is an address (Dwarf version == 2), then it might have been - // relocated to a totally unrelated value (because the end address in the - // object file might be start address of another function which got moved - // independently by the linker). - // - If address relocated in an inline_subprogram that happens at the - // beginning of its inlining function. - // To avoid above cases and to not apply relocation twice (in - // applyValidRelocs and here), read address attribute from InputDIE and apply - // Info.PCOffset here. - - std::optional AddrAttribute = - CU.find(InputDieEntry, AttrSpec.Attr); - if (!AddrAttribute) - llvm_unreachable("Cann't find attribute"); - - std::optional Addr = AddrAttribute->getAsAddress(); - if (!Addr) { - CU.warn("cann't read address attribute value."); - return 0; - } - - if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit && - AttrSpec.Attr == dwarf::DW_AT_low_pc) { - if (std::optional LowPC = CU.getLowPc()) - Addr = *LowPC; - else - return 0; - } else if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit && - AttrSpec.Attr == dwarf::DW_AT_high_pc) { - if (uint64_t HighPc = CU.getHighPc()) - Addr = HighPc; - else - return 0; - } else { - if (VarAddressAdjustment) - *Addr += *VarAddressAdjustment; - else if (FuncAddressAdjustment) - *Addr += *FuncAddressAdjustment; - } - - if (AttrSpec.Form == dwarf::DW_FORM_addr) { - return Generator.addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, *Addr) - .second; - } - - return Generator - .addScalarAttribute(AttrSpec.Attr, dwarf::Form::DW_FORM_addrx, - CU.getDebugAddrIndex(*Addr)) - .second; -} - -unsigned DIEAttributeCloner::finalizeAbbreviations(bool HasChildrenToClone) { - size_t SizeOfAbbreviationNumber = - Generator.finalizeAbbreviations(HasChildrenToClone); - - // We need to update patches offsets after we know the size of the - // abbreviation number. - updatePatchesWithSizeOfAbbreviationNumber(SizeOfAbbreviationNumber); - - // Add the size of the abbreviation number to the output offset. - AttrOutOffset += SizeOfAbbreviationNumber; - - return AttrOutOffset; -} - -} // end of namespace dwarflinker_parallel -} // namespace llvm diff --git a/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.h b/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.h deleted file mode 100644 index d590b1805e8ef..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DIEAttributeCloner.h +++ /dev/null @@ -1,147 +0,0 @@ -//===- DIEAttributeCloner.h -------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_DWARFLINKERPARALLEL_DIEATTRIBUTECLONER_H -#define LLVM_LIB_DWARFLINKERPARALLEL_DIEATTRIBUTECLONER_H - -#include "ArrayList.h" -#include "DIEGenerator.h" -#include "DWARFLinkerCompileUnit.h" -#include "DWARFLinkerGlobalData.h" - -namespace llvm { -namespace dwarflinker_parallel { - -/// 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. -class DIEAttributeCloner { -public: - DIEAttributeCloner(DIE *OutDIE, CompileUnit &CU, - const DWARFDebugInfoEntry *InputDieEntry, - DIEGenerator &Generator, - std::optional FuncAddressAdjustment, - std::optional VarAddressAdjustment, - bool HasLocationExpressionAddress) - : OutDIE(OutDIE), CU(CU), - DebugInfoOutputSection( - CU.getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)), - InputDieEntry(InputDieEntry), Generator(Generator), - FuncAddressAdjustment(FuncAddressAdjustment), - VarAddressAdjustment(VarAddressAdjustment), - HasLocationExpressionAddress(HasLocationExpressionAddress) { - InputDIEIdx = CU.getDIEIndex(InputDieEntry); - } - - /// Clone attributes of input DIE. - void clone(); - - /// 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: - /// Clone string attribute. - size_t - cloneStringAttr(const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); - - /// Clone attribute referencing another DIE. - size_t - cloneDieRefAttr(const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); - - /// Clone scalar attribute. - size_t - cloneScalarAttr(const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); - - /// Clone block or exprloc attribute. - size_t - cloneBlockAttr(const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); - - /// Clone address attribute. - size_t - cloneAddressAttr(const DWARFFormValue &Val, - const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); - - /// Returns true if attribute should be skipped. - bool - shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec); - - /// Update patches offsets with the size of abbreviation number. - void - updatePatchesWithSizeOfAbbreviationNumber(unsigned SizeOfAbbreviationNumber) { - for (uint64_t *OffsetPtr : PatchesOffsets) - *OffsetPtr += SizeOfAbbreviationNumber; - } - - /// Output DIE. - DIE *OutDIE = nullptr; - - /// Compile unit for the output DIE. - CompileUnit &CU; - - /// .debug_info section descriptor. - SectionDescriptor &DebugInfoOutputSection; - - /// Input DIE entry. - const DWARFDebugInfoEntry *InputDieEntry = nullptr; - - /// Input DIE index. - uint32_t InputDIEIdx = 0; - - /// Output DIE generator. - DIEGenerator &Generator; - - /// Relocation adjustment for the function address ranges. - std::optional FuncAddressAdjustment; - - /// Relocation adjustment for the variable locations. - std::optional VarAddressAdjustment; - - /// Indicates whether InputDieEntry has an location attribute - /// containg address expression. - bool HasLocationExpressionAddress = false; - - /// Output offset after all attributes. - unsigned AttrOutOffset = 0; - - /// Patches for the cloned attributes. - OffsetsPtrVector PatchesOffsets; -}; - -} // end of namespace dwarflinker_parallel -} // end namespace llvm - -#endif // LLVM_LIB_DWARFLINKERPARALLEL_DIEATTRIBUTECLONER_H diff --git a/llvm/lib/DWARFLinkerParallel/DIEGenerator.h b/llvm/lib/DWARFLinkerParallel/DIEGenerator.h deleted file mode 100644 index c0bbce0f52014..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DIEGenerator.h +++ /dev/null @@ -1,165 +0,0 @@ -//===- DIEGenerator.h -------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_DWARFLINKERPARALLEL_DIEGENERATOR_H -#define LLVM_LIB_DWARFLINKERPARALLEL_DIEGENERATOR_H - -#include "DWARFLinkerGlobalData.h" -#include "DWARFLinkerUnit.h" -#include "llvm/CodeGen/DIE.h" -#include "llvm/Support/LEB128.h" - -namespace llvm { -namespace dwarflinker_parallel { - -/// This class is a helper to create output DIE tree. -class DIEGenerator { -public: - DIEGenerator(BumpPtrAllocator &Allocator, DwarfUnit &CU) - : Allocator(Allocator), CU(CU) {} - - /// Creates a DIE of specified tag \p DieTag and \p OutOffset. - DIE *createDIE(dwarf::Tag DieTag, uint32_t OutOffset) { - OutputDIE = DIE::get(Allocator, DieTag); - - OutputDIE->setOffset(OutOffset); - - return OutputDIE; - } - - /// Adds a specified \p Child to the current DIE. - void addChild(DIE *Child) { - assert(Child != nullptr); - assert(OutputDIE != nullptr); - - OutputDIE->addChild(Child); - } - - /// Adds specified scalar attribute to the current DIE. - std::pair addScalarAttribute(dwarf::Attribute Attr, - dwarf::Form AttrForm, - uint64_t Value) { - return addAttribute(Attr, AttrForm, DIEInteger(Value)); - } - - /// Adds specified location attribute to the current DIE. - std::pair addLocationAttribute(dwarf::Attribute Attr, - dwarf::Form AttrForm, - ArrayRef Bytes) { - DIELoc *Loc = new (Allocator) DIELoc; - for (auto Byte : Bytes) - static_cast(Loc)->addValue( - Allocator, static_cast(0), dwarf::DW_FORM_data1, - DIEInteger(Byte)); - Loc->setSize(Bytes.size()); - - return addAttribute(Attr, AttrForm, Loc); - } - - /// Adds specified block or exprloc attribute to the current DIE. - std::pair addBlockAttribute(dwarf::Attribute Attr, - dwarf::Form AttrForm, - ArrayRef Bytes) { - // The expression location data might be updated and exceed the original - // size. Check whether the new data fits into the original form. - assert((AttrForm == dwarf::DW_FORM_block) || - (AttrForm == dwarf::DW_FORM_exprloc) || - (AttrForm == dwarf::DW_FORM_block1 && Bytes.size() <= UINT8_MAX) || - (AttrForm == dwarf::DW_FORM_block2 && Bytes.size() <= UINT16_MAX) || - (AttrForm == dwarf::DW_FORM_block4 && Bytes.size() <= UINT32_MAX)); - - DIEBlock *Block = new (Allocator) DIEBlock; - for (auto Byte : Bytes) - static_cast(Block)->addValue( - Allocator, static_cast(0), dwarf::DW_FORM_data1, - DIEInteger(Byte)); - Block->setSize(Bytes.size()); - - return addAttribute(Attr, AttrForm, Block); - } - - /// Adds specified location list attribute to the current DIE. - std::pair addLocListAttribute(dwarf::Attribute Attr, - dwarf::Form AttrForm, - uint64_t Value) { - return addAttribute(Attr, AttrForm, DIELocList(Value)); - } - - /// Adds indexed string attribute. - std::pair addIndexedStringAttribute(dwarf::Attribute Attr, - dwarf::Form AttrForm, - uint64_t Idx) { - assert(AttrForm == dwarf::DW_FORM_strx); - return addAttribute(Attr, AttrForm, DIEInteger(Idx)); - } - - /// Adds string attribute with dummy offset to the current DIE. - std::pair - addStringPlaceholderAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm) { - assert(AttrForm == dwarf::DW_FORM_strp || - AttrForm == dwarf::DW_FORM_line_strp); - return addAttribute(Attr, AttrForm, DIEInteger(0xBADDEF)); - } - - /// Adds inplace string attribute to the current DIE. - std::pair addInplaceString(dwarf::Attribute Attr, - StringRef String) { - DIEBlock *Block = new (Allocator) DIEBlock; - for (auto Byte : String.bytes()) - static_cast(Block)->addValue( - Allocator, static_cast(0), dwarf::DW_FORM_data1, - DIEInteger(Byte)); - - static_cast(Block)->addValue( - Allocator, static_cast(0), dwarf::DW_FORM_data1, - DIEInteger(0)); - Block->setSize(String.size() + 1); - - DIEValue &ValueRef = - *OutputDIE->addValue(Allocator, Attr, dwarf::DW_FORM_string, Block); - return std::pair(ValueRef, String.size() + 1); - } - - /// Creates appreviations for the current DIE. Returns value of - /// abbreviation number. - size_t finalizeAbbreviations(bool CHILDREN_yes) { - // Create abbreviations for output DIE. - DIEAbbrev NewAbbrev = OutputDIE->generateAbbrev(); - if (CHILDREN_yes) - NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); - - CU.assignAbbrev(NewAbbrev); - OutputDIE->setAbbrevNumber(NewAbbrev.getNumber()); - - return getULEB128Size(OutputDIE->getAbbrevNumber()); - } - -protected: - template - std::pair addAttribute(dwarf::Attribute Attr, - dwarf::Form AttrForm, T &&Value) { - DIEValue &ValueRef = - *OutputDIE->addValue(Allocator, Attr, AttrForm, std::forward(Value)); - unsigned ValueSize = ValueRef.sizeOf(CU.getFormParams()); - return std::pair(ValueRef, ValueSize); - } - - // Allocator for output DIEs and values. - BumpPtrAllocator &Allocator; - - // Unit for the output DIE. - DwarfUnit &CU; - - // OutputDIE. - DIE *OutputDIE = nullptr; -}; - -} // end of namespace dwarflinker_parallel -} // end namespace llvm - -#endif // LLVM_LIB_DWARFLINKERPARALLEL_DIEGENERATOR_H diff --git a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp index 38898ac6f2fa2..50909c0ba6693 100644 --- a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp +++ b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp @@ -114,115 +114,18 @@ Error DwarfEmitterImpl::init(Triple TheTriple, TripleName.c_str()); Asm->setDwarfUsesRelocationsAcrossSections(false); + RangesSectionSize = 0; + RngListsSectionSize = 0; + LocSectionSize = 0; + LocListsSectionSize = 0; + LineSectionSize = 0; + FrameSectionSize = 0; DebugInfoSectionSize = 0; + MacInfoSectionSize = 0; + MacroSectionSize = 0; return Error::success(); } -void DwarfEmitterImpl::emitSwiftAST(StringRef Buffer) { - MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection(); - SwiftASTSection->setAlignment(Align(32)); - MS->switchSection(SwiftASTSection); - MS->emitBytes(Buffer); -} - -/// Emit the swift reflection section stored in \p Buffer. -void DwarfEmitterImpl::emitSwiftReflectionSection( - llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind, - StringRef Buffer, uint32_t Alignment, uint32_t) { - MCSection *ReflectionSection = - MOFI->getSwift5ReflectionSection(ReflSectionKind); - if (ReflectionSection == nullptr) - return; - ReflectionSection->setAlignment(Align(Alignment)); - MS->switchSection(ReflectionSection); - MS->emitBytes(Buffer); -} - -void DwarfEmitterImpl::emitSectionContents(StringRef SecData, - StringRef SecName) { - if (SecData.empty()) - return; - - if (MCSection *Section = switchSection(SecName)) { - MS->switchSection(Section); - - MS->emitBytes(SecData); - } -} - -MCSection *DwarfEmitterImpl::switchSection(StringRef SecName) { - return StringSwitch(SecName) - .Case("debug_info", MC->getObjectFileInfo()->getDwarfInfoSection()) - .Case("debug_abbrev", MC->getObjectFileInfo()->getDwarfAbbrevSection()) - .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection()) - .Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection()) - .Case("debug_ranges", MC->getObjectFileInfo()->getDwarfRangesSection()) - .Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection()) - .Case("debug_aranges", MC->getObjectFileInfo()->getDwarfARangesSection()) - .Case("debug_rnglists", - MC->getObjectFileInfo()->getDwarfRnglistsSection()) - .Case("debug_loclists", - MC->getObjectFileInfo()->getDwarfLoclistsSection()) - .Case("debug_macro", MC->getObjectFileInfo()->getDwarfMacroSection()) - .Case("debug_macinfo", MC->getObjectFileInfo()->getDwarfMacinfoSection()) - .Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection()) - .Case("debug_str", MC->getObjectFileInfo()->getDwarfStrSection()) - .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; - } - - return nullptr; -} - -void DwarfEmitterImpl::emitAbbrevs( - const SmallVector> &Abbrevs, - unsigned DwarfVersion) { - MS->switchSection(MOFI->getDwarfAbbrevSection()); - MC->setDwarfVersion(DwarfVersion); - Asm->emitDwarfAbbrevs(Abbrevs); -} - -void DwarfEmitterImpl::emitCompileUnitHeader(DwarfUnit &Unit) { - MS->switchSection(MOFI->getDwarfInfoSection()); - MC->setDwarfVersion(Unit.getVersion()); - - // 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->emitInt16(Unit.getVersion()); - - if (Unit.getVersion() >= 5) { - Asm->emitInt8(dwarf::DW_UT_compile); - Asm->emitInt8(Unit.getFormParams().AddrSize); - // Proper offset to the abbreviations table will be set later. - Asm->emitInt32(0); - DebugInfoSectionSize += 12; - } else { - // Proper offset to the abbreviations table will be set later. - Asm->emitInt32(0); - Asm->emitInt8(Unit.getFormParams().AddrSize); - DebugInfoSectionSize += 11; - } -} - -void DwarfEmitterImpl::emitDIE(DIE &Die) { - MS->switchSection(MOFI->getDwarfInfoSection()); - Asm->emitDwarfDIE(Die); - DebugInfoSectionSize += Die.getSize(); -} - } // end of namespace dwarflinker_parallel } // namespace llvm diff --git a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.h b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.h index 3a8aab1ca83dc..d07397a304196 100644 --- a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.h +++ b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.h @@ -14,6 +14,7 @@ #include "llvm/CodeGen/AccelTable.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/DWARFLinkerParallel/DWARFLinker.h" +#include "llvm/DWARFLinkerParallel/StringTable.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstrInfo.h" @@ -39,66 +40,186 @@ class DWARFDebugMacro; namespace dwarflinker_parallel { -/// 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. +struct UnitStartSymbol { + unsigned UnitID = 0; + MCSymbol *Symbol = 0; +}; +using UnitStartSymbolsTy = SmallVector; +using Offset2UnitMapTy = DenseMap; + +struct RangeAttrPatch; +struct LocAttrPatch; + +/// The Dwarf emission logic. +/// +/// All interactions with the MC layer that is used to build the debug +/// information binary representation are handled in this class. class DwarfEmitterImpl : public ExtraDwarfEmitter { public: DwarfEmitterImpl(DWARFLinker::OutputFileType OutFileType, - raw_pwrite_stream &OutFile) - : OutFile(OutFile), OutFileType(OutFileType) {} + raw_pwrite_stream &OutFile, + std::function Translator, + DWARFLinker::MessageHandlerTy Warning) + : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator), + WarningHandler(Warning) {} - /// Initialize AsmPrinter data. Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName); - /// Returns triple of output stream. - const Triple &getTargetTriple() { return MC->getTargetTriple(); } - /// Dump the file to the disk. void finish() override { MS->finish(); } - /// Returns AsmPrinter. AsmPrinter &getAsmPrinter() const override { return *Asm; } + /// Set the current output section to debug_info and change + /// the MC Dwarf version to \p DwarfVersion. + void switchToDebugInfoSection(unsigned DwarfVersion) {} + /// Emit the swift_ast section stored in \p Buffer. - void emitSwiftAST(StringRef Buffer) override; + void emitSwiftAST(StringRef Buffer) override {} /// Emit the swift reflection section stored in \p Buffer. void emitSwiftReflectionSection( llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind, - StringRef Buffer, uint32_t Alignment, uint32_t) override; + StringRef Buffer, uint32_t Alignment, uint32_t Size) override {} - /// Emit specified section data. - void emitSectionContents(StringRef SecData, StringRef SecName) override; + void emitPaperTrailWarningsDie(DIE &Die) {} - /// Emit temporary symbol. - MCSymbol *emitTempSym(StringRef SecName, StringRef SymName) override; + void emitSectionContents(StringRef SecData, StringRef SecName) override {} + + MCSymbol *emitTempSym(StringRef SecName, StringRef SymName) override { + return nullptr; + } - /// Emit abbreviations. void emitAbbrevs(const SmallVector> &Abbrevs, - unsigned DwarfVersion); + unsigned DwarfVersion) {} + + void emitStrings(const StringTable &Strings) {} + + void emitLineStrings(const StringTable &Strings) {} + + void emitDebugNames(AccelTable &, + UnitStartSymbolsTy &UnitOffsets) {} + + void emitAppleNamespaces(AccelTable &) {} + + void emitAppleNames(AccelTable &) {} + + void emitAppleObjc(AccelTable &) {} + + void emitAppleTypes(AccelTable &) {} + + MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) { + return nullptr; + } + + void emitDwarfDebugRangeListFragment(const CompileUnit &Unit, + const AddressRanges &LinkedRanges, + RangeAttrPatch &Patch) {} + + void emitDwarfDebugRangeListFooter(const CompileUnit &Unit, + MCSymbol *EndLabel) {} + + MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) { + return nullptr; + } + + void emitDwarfDebugLocListFragment( + const CompileUnit &Unit, + const DWARFLocationExpressionsVector &LinkedLocationExpression, + LocAttrPatch &Patch) {} + + void emitDwarfDebugLocListFooter(const CompileUnit &Unit, + MCSymbol *EndLabel) {} + + void emitDwarfDebugArangesTable(const CompileUnit &Unit, + const AddressRanges &LinkedRanges) {} + + void translateLineTable(DataExtractor LineData, uint64_t Offset) {} + + void emitLineTableForUnit(MCDwarfLineTableParams Params, + StringRef PrologueBytes, unsigned MinInstLength, + std::vector &Rows, + unsigned AdddressSize) {} - /// Emit compile unit header. - void emitCompileUnitHeader(DwarfUnit &Unit); + void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable, + const CompileUnit &Unit, const StringTable &Strings, + const StringTable &LineTableStrings) {} - /// Emit DIE recursively. - void emitDIE(DIE &Die); + void emitPubNamesForUnit(const CompileUnit &Unit) {} + + void emitPubTypesForUnit(const CompileUnit &Unit) {} + + void emitCIE(StringRef CIEBytes) {} + + void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address, + StringRef Bytes) {} + + void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) {} + + void emitDIE(DIE &Die) {} + + void emitMacroTables(DWARFContext *Context, + const Offset2UnitMapTy &UnitMacroMap, + StringTable &Strings) {} + + /// Returns size of generated .debug_line section. + uint64_t getDebugLineSectionSize() const { return LineSectionSize; } + + /// Returns size of generated .debug_frame section. + uint64_t getDebugFrameSectionSize() const { return FrameSectionSize; } + + /// Returns size of generated .debug_ranges section. + uint64_t getDebugRangesSectionSize() const { return RangesSectionSize; } + + /// Returns size of generated .debug_rnglists section. + uint64_t getDebugRngListsSectionSize() const { return RngListsSectionSize; } /// Returns size of generated .debug_info section. uint64_t getDebugInfoSectionSize() const { return DebugInfoSectionSize; } + /// Returns size of generated .debug_macinfo section. + uint64_t getDebugMacInfoSectionSize() const { return MacInfoSectionSize; } + + /// Returns size of generated .debug_macro section. + uint64_t getDebugMacroSectionSize() const { return MacroSectionSize; } + + /// Returns size of generated .debug_loc section. + uint64_t getDebugLocSectionSize() const { return LocSectionSize; } + + /// Returns size of generated .debug_loclists section. + uint64_t getDebugLocListsSectionSize() const { return LocListsSectionSize; } + 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 - // the same string twice we accumulate NextOffset value. Thus if string - // offset smaller than NextOffset value then the patch is skipped (as that - // string was emitted earlier). - template - void emitStringsImpl(ArrayList &StringPatches, - const StringEntryToDwarfStringPoolEntryMap &Strings, - uint64_t &NextOffset, MCSection *OutSection); - - MCSection *switchSection(StringRef SecName); + inline void warn(const Twine &Warning, StringRef Context = "") { + if (WarningHandler) + WarningHandler(Warning, Context, nullptr); + } + + void emitMacroTableImpl(const DWARFDebugMacro *MacroTable, + const Offset2UnitMapTy &UnitMacroMap, + StringPool &StringPool, uint64_t &OutOffset) {} + + /// Emit piece of .debug_ranges for \p LinkedRanges. + void emitDwarfDebugRangesTableFragment(const CompileUnit &Unit, + const AddressRanges &LinkedRanges, + RangeAttrPatch &Patch) {} + + /// Emit piece of .debug_rnglists for \p LinkedRanges. + void emitDwarfDebugRngListsTableFragment(const CompileUnit &Unit, + const AddressRanges &LinkedRanges, + RangeAttrPatch &Patch) {} + + /// Emit piece of .debug_loc for \p LinkedRanges. + void emitDwarfDebugLocTableFragment( + const CompileUnit &Unit, + const DWARFLocationExpressionsVector &LinkedLocationExpression, + LocAttrPatch &Patch) {} + + /// Emit piece of .debug_loclists for \p LinkedRanges. + void emitDwarfDebugLocListsTableFragment( + const CompileUnit &Unit, + const DWARFLocationExpressionsVector &LinkedLocationExpression, + LocAttrPatch &Patch) {} /// \defgroup MCObjects MC layer objects constructed by the streamer /// @{ @@ -119,8 +240,32 @@ class DwarfEmitterImpl : public ExtraDwarfEmitter { /// The output file we stream the linked Dwarf to. raw_pwrite_stream &OutFile; DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object; + std::function Translator; + uint64_t RangesSectionSize = 0; + uint64_t RngListsSectionSize = 0; + uint64_t LocSectionSize = 0; + uint64_t LocListsSectionSize = 0; + uint64_t LineSectionSize = 0; + uint64_t FrameSectionSize = 0; uint64_t DebugInfoSectionSize = 0; + uint64_t MacInfoSectionSize = 0; + uint64_t MacroSectionSize = 0; + + /// Keep track of emitted CUs and their Unique ID. + struct EmittedUnit { + unsigned ID; + MCSymbol *LabelBegin; + }; + std::vector EmittedUnitsTy; + + /// Emit the pubnames or pubtypes section contribution for \p + /// Unit into \p Sec. The data is provided in \p Names. + void emitPubSectionForUnit(MCSection *Sec, StringRef Name, + const CompileUnit &Unit, + const std::vector &Names); + + DWARFLinker::MessageHandlerTy WarningHandler = nullptr; }; } // end namespace dwarflinker_parallel diff --git a/llvm/lib/DWARFLinkerParallel/DWARFFile.cpp b/llvm/lib/DWARFLinkerParallel/DWARFFile.cpp deleted file mode 100644 index 86c7e816ead8f..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DWARFFile.cpp +++ /dev/null @@ -1,18 +0,0 @@ -//=== DWARFFile.cpp -------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/DWARFLinkerParallel/DWARFFile.h" -#include "DWARFLinkerGlobalData.h" - -llvm::dwarflinker_parallel::DWARFFile::DWARFFile( - StringRef Name, std::unique_ptr Dwarf, - std::unique_ptr Addresses, - const std::vector &Warnings, - DWARFFile::UnloadCallbackTy UnloadFunc) - : FileName(Name), Dwarf(std::move(Dwarf)), Addresses(std::move(Addresses)), - Warnings(Warnings), UnloadFunc(UnloadFunc) {} diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.cpp deleted file mode 100644 index 81751601293cb..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.cpp +++ /dev/null @@ -1,1402 +0,0 @@ -//=== DWARFLinkerCompileUnit.cpp ------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "DWARFLinkerCompileUnit.h" -#include "DIEAttributeCloner.h" -#include "DIEGenerator.h" -#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/FormatVariadic.h" - -using namespace llvm; -using namespace llvm::dwarflinker_parallel; - -void CompileUnit::loadLineTable() { - LineTablePtr = File.Dwarf->getLineTableForUnit(&getOrigUnit()); -} - -void CompileUnit::maybeResetToLoadedStage() { - // Nothing to reset if stage is less than "Loaded". - if (getStage() < Stage::Loaded) - return; - - // Note: We need to do erasing for "Loaded" stage because - // if live analysys failed then we will have "Loaded" stage - // with marking from "LivenessAnalysisDone" stage partially - // done. That marking should be cleared. - - for (DIEInfo &DieInfo : DieInfoArray) - DieInfo.unsetFlagsWhichSetDuringLiveAnalysis(); - - LowPc = std::nullopt; - HighPc = 0; - Labels.clear(); - Ranges.clear(); - - if (getStage() < Stage::Cloned) { - setStage(Stage::Loaded); - return; - } - - AbbreviationsSet.clear(); - Abbreviations.clear(); - OutUnitDIE = nullptr; - DebugAddrIndexMap.clear(); - - for (uint64_t &Offset : OutDieOffsetArray) - Offset = 0; - eraseSections(); - - setStage(Stage::CreatedNotLoaded); -} - -bool CompileUnit::loadInputDIEs() { - DWARFDie InputUnitDIE = getUnitDIE(false); - if (!InputUnitDIE) - return false; - - // load input dies, resize Info structures array. - DieInfoArray.resize(getOrigUnit().getNumDIEs()); - OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0); - return true; -} - -void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry, - bool IsInModule, bool IsInFunction) { - for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry); - CurChild && CurChild->getAbbreviationDeclarationPtr(); - CurChild = getSiblingEntry(CurChild)) { - CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild); - - if (IsInModule) - ChildInfo.setIsInMouduleScope(); - if (IsInFunction) - ChildInfo.setIsInFunctionScope(); - - switch (CurChild->getTag()) { - case dwarf::DW_TAG_module: - ChildInfo.setIsInMouduleScope(); - if (DieEntry->getTag() == dwarf::DW_TAG_compile_unit && - dwarf::toString(find(CurChild, dwarf::DW_AT_name), "") != - getClangModuleName()) - analyzeImportedModule(CurChild); - break; - case dwarf::DW_TAG_subprogram: - ChildInfo.setIsInFunctionScope(); - break; - default: - break; - } - - if (IsInModule) - ChildInfo.setIsInMouduleScope(); - if (IsInFunction) - ChildInfo.setIsInFunctionScope(); - - if (CurChild->hasChildren()) - analyzeDWARFStructureRec(CurChild, ChildInfo.getIsInMouduleScope(), - ChildInfo.getIsInFunctionScope()); - } -} - -StringEntry *CompileUnit::getFileName(unsigned FileIdx, - StringPool &GlobalStrings) { - if (LineTablePtr) { - if (LineTablePtr->hasFileAtIndex(FileIdx)) { - // Cache the resolved paths based on the index in the line table, - // because calling realpath is expensive. - ResolvedPathsMap::const_iterator It = ResolvedFullPaths.find(FileIdx); - if (It == ResolvedFullPaths.end()) { - std::string OrigFileName; - bool FoundFileName = LineTablePtr->getFileNameByIndex( - FileIdx, getOrigUnit().getCompilationDir(), - DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, - OrigFileName); - (void)FoundFileName; - assert(FoundFileName && "Must get file name from line table"); - - // Second level of caching, this time based on the file's parent - // path. - StringRef FileName = sys::path::filename(OrigFileName); - StringRef ParentPath = sys::path::parent_path(OrigFileName); - - // If the ParentPath has not yet been resolved, resolve and cache it for - // future look-ups. - StringMap::iterator ParentIt = - ResolvedParentPaths.find(ParentPath); - if (ParentIt == ResolvedParentPaths.end()) { - SmallString<256> RealPath; - sys::fs::real_path(ParentPath, RealPath); - ParentIt = - ResolvedParentPaths - .insert({ParentPath, GlobalStrings.insert(RealPath).first}) - .first; - } - - // Join the file name again with the resolved path. - SmallString<256> ResolvedPath(ParentIt->second->first()); - sys::path::append(ResolvedPath, FileName); - - It = ResolvedFullPaths - .insert(std::make_pair( - FileIdx, GlobalStrings.insert(ResolvedPath).first)) - .first; - } - - return It->second; - } - } - - return nullptr; -} - -void CompileUnit::cleanupDataAfterClonning() { - AbbreviationsSet.clear(); - ResolvedFullPaths.shrink_and_clear(); - ResolvedParentPaths.clear(); - DieInfoArray = SmallVector(); - OutDieOffsetArray = SmallVector(); - getOrigUnit().clear(); -} - -/// Collect references to parseable Swift interfaces in imported -/// DW_TAG_module blocks. -void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) { - if (getLanguage() != dwarf::DW_LANG_Swift) - return; - - if (!GlobalData.getOptions().ParseableSwiftInterfaces) - return; - - StringRef Path = - dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_include_path)); - if (!Path.endswith(".swiftinterface")) - return; - // Don't track interfaces that are part of the SDK. - StringRef SysRoot = - dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_sysroot)); - if (SysRoot.empty()) - SysRoot = getSysRoot(); - if (!SysRoot.empty() && Path.startswith(SysRoot)) - return; - if (std::optional Val = find(DieEntry, dwarf::DW_AT_name)) { - Expected Name = Val->getAsCString(); - if (!Name) { - warn(Name.takeError()); - return; - } - - auto &Entry = (*GlobalData.getOptions().ParseableSwiftInterfaces)[*Name]; - // The prepend path is applied later when copying. - SmallString<128> ResolvedPath; - if (sys::path::is_relative(Path)) - sys::path::append( - ResolvedPath, - dwarf::toString(getUnitDIE().find(dwarf::DW_AT_comp_dir), "")); - sys::path::append(ResolvedPath, Path); - if (!Entry.empty() && Entry != ResolvedPath) { - DWARFDie Die = getDIE(DieEntry); - warn(Twine("conflicting parseable interfaces for Swift Module ") + *Name + - ": " + Entry + " and " + Path + ".", - &Die); - } - Entry = std::string(ResolvedPath.str()); - } -} - -void CompileUnit::updateDieRefPatchesWithClonedOffsets() { - if (std::optional DebugInfoSection = - getSectionDescriptor(DebugSectionKind::DebugInfo)) { - - (*DebugInfoSection) - ->ListDebugDieRefPatch.forEach([](DebugDieRefPatch &Patch) { - Patch.RefDieIdxOrClonedOffset = - Patch.RefCU.getPointer()->getDieOutOffset( - Patch.RefDieIdxOrClonedOffset); - }); - - (*DebugInfoSection) - ->ListDebugULEB128DieRefPatch.forEach( - [](DebugULEB128DieRefPatch &Patch) { - Patch.RefDieIdxOrClonedOffset = - Patch.RefCU.getPointer()->getDieOutOffset( - Patch.RefDieIdxOrClonedOffset); - }); - } - - if (std::optional DebugLocSection = - getSectionDescriptor(DebugSectionKind::DebugLoc)) { - (*DebugLocSection) - ->ListDebugULEB128DieRefPatch.forEach( - [](DebugULEB128DieRefPatch &Patch) { - Patch.RefDieIdxOrClonedOffset = - Patch.RefCU.getPointer()->getDieOutOffset( - Patch.RefDieIdxOrClonedOffset); - }); - } - - if (std::optional DebugLocListsSection = - getSectionDescriptor(DebugSectionKind::DebugLocLists)) { - (*DebugLocListsSection) - ->ListDebugULEB128DieRefPatch.forEach( - [](DebugULEB128DieRefPatch &Patch) { - Patch.RefDieIdxOrClonedOffset = - Patch.RefCU.getPointer()->getDieOutOffset( - Patch.RefDieIdxOrClonedOffset); - }); - } -} - -std::optional> -CompileUnit::resolveDIEReference(const DWARFFormValue &RefValue) { - if (std::optional Ref = - *RefValue.getAsRelativeReference()) { - if (Ref->Unit != nullptr) { - // Referenced DIE is in current compile unit. - - 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) - return std::make_pair(RefCU, 0); - - if (std::optional RefDieIdx = - RefCU->getDIEIndexForOffset(Ref->Offset)) - return std::make_pair(RefCU, *RefDieIdx); - } - } - - return std::nullopt; -} - -void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc, - int64_t PcOffset) { - std::lock_guard Guard(RangesMutex); - - Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset); - if (LowPc) - LowPc = std::min(*LowPc, FuncLowPc + PcOffset); - else - LowPc = FuncLowPc + PcOffset; - this->HighPc = std::max(HighPc, FuncHighPc + PcOffset); -} - -void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) { - std::lock_guard Guard(LabelsMutex); - Labels.insert({LabelLowPc, PcOffset}); -} - -Error CompileUnit::cloneAndEmitDebugLocations() { - if (getGlobalData().getOptions().UpdateIndexTablesOnly) - return Error::success(); - - if (getOrigUnit().getVersion() < 5) { - emitLocations(DebugSectionKind::DebugLoc); - return Error::success(); - } - - emitLocations(DebugSectionKind::DebugLocLists); - return Error::success(); -} - -void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) { - SectionDescriptor &DebugInfoSection = - getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); - - if (!DebugInfoSection.ListDebugLocPatch.empty()) { - SectionDescriptor &OutLocationSection = - getOrCreateSectionDescriptor(LocationSectionKind); - DWARFUnit &OrigUnit = getOrigUnit(); - - uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection); - - DebugInfoSection.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) { - // Get location expressions vector corresponding to the current - // attribute from the source DWARF. - uint64_t InputDebugLocSectionOffset = DebugInfoSection.getIntVal( - Patch.PatchOffset, - DebugInfoSection.getFormParams().getDwarfOffsetByteSize()); - Expected OriginalLocations = - OrigUnit.findLoclistFromOffset(InputDebugLocSectionOffset); - - if (!OriginalLocations) { - warn(OriginalLocations.takeError()); - return; - } - - LinkedLocationExpressionsVector LinkedLocationExpressions; - for (DWARFLocationExpression &CurExpression : *OriginalLocations) { - LinkedLocationExpressionsWithOffsetPatches LinkedExpression; - - if (CurExpression.Range) { - // Relocate address range. - LinkedExpression.Expression.Range = { - CurExpression.Range->LowPC + Patch.AddrAdjustmentValue, - CurExpression.Range->HighPC + Patch.AddrAdjustmentValue}; - } - - DataExtractor Data(CurExpression.Expr, OrigUnit.isLittleEndian(), - OrigUnit.getAddressByteSize()); - - DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(), - OrigUnit.getFormParams().Format); - cloneDieAttrExpression(InputExpression, - LinkedExpression.Expression.Expr, - OutLocationSection, Patch.AddrAdjustmentValue, - LinkedExpression.Patches); - - LinkedLocationExpressions.push_back({LinkedExpression}); - } - - // Emit locations list table fragment corresponding to the CurLocAttr. - DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, - OutLocationSection.OS.tell()); - emitLocListFragment(LinkedLocationExpressions, OutLocationSection); - }); - - if (OffsetAfterUnitLength > 0) { - assert(OffsetAfterUnitLength - - OutLocationSection.getFormParams().getDwarfOffsetByteSize() < - OffsetAfterUnitLength); - OutLocationSection.apply( - OffsetAfterUnitLength - - OutLocationSection.getFormParams().getDwarfOffsetByteSize(), - dwarf::DW_FORM_sec_offset, - OutLocationSection.OS.tell() - OffsetAfterUnitLength); - } - } -} - -/// Emit debug locations(.debug_loc, .debug_loclists) header. -uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) { - if (getOrigUnit().getVersion() < 5) - return 0; - - // unit_length. - OutLocationSection.emitUnitLength(0xBADDEF); - uint64_t OffsetAfterUnitLength = OutLocationSection.OS.tell(); - - // Version. - OutLocationSection.emitIntVal(5, 2); - - // Address size. - OutLocationSection.emitIntVal(OutLocationSection.getFormParams().AddrSize, 1); - - // Seg_size - OutLocationSection.emitIntVal(0, 1); - - // Offset entry count - OutLocationSection.emitIntVal(0, 4); - - return OffsetAfterUnitLength; -} - -/// Emit debug locations(.debug_loc, .debug_loclists) fragment. -uint64_t CompileUnit::emitLocListFragment( - const LinkedLocationExpressionsVector &LinkedLocationExpression, - SectionDescriptor &OutLocationSection) { - uint64_t OffsetBeforeLocationExpression = 0; - - if (getOrigUnit().getVersion() < 5) { - uint64_t BaseAddress = 0; - if (std::optional LowPC = getLowPc()) - BaseAddress = *LowPC; - - for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression : - LinkedLocationExpression) { - if (LocExpression.Expression.Range) { - OutLocationSection.emitIntVal( - LocExpression.Expression.Range->LowPC - BaseAddress, - OutLocationSection.getFormParams().AddrSize); - OutLocationSection.emitIntVal( - LocExpression.Expression.Range->HighPC - BaseAddress, - OutLocationSection.getFormParams().AddrSize); - } - - OutLocationSection.emitIntVal(LocExpression.Expression.Expr.size(), 2); - OffsetBeforeLocationExpression = OutLocationSection.OS.tell(); - for (uint64_t *OffsetPtr : LocExpression.Patches) - *OffsetPtr += OffsetBeforeLocationExpression; - - OutLocationSection.OS - << StringRef((const char *)LocExpression.Expression.Expr.data(), - LocExpression.Expression.Expr.size()); - } - - // Emit the terminator entry. - OutLocationSection.emitIntVal(0, - OutLocationSection.getFormParams().AddrSize); - OutLocationSection.emitIntVal(0, - OutLocationSection.getFormParams().AddrSize); - return OffsetBeforeLocationExpression; - } - - std::optional BaseAddress; - for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression : - LinkedLocationExpression) { - if (LocExpression.Expression.Range) { - // Check whether base address is set. If it is not set yet - // then set current base address and emit base address selection entry. - if (!BaseAddress) { - BaseAddress = LocExpression.Expression.Range->LowPC; - - // Emit base address. - OutLocationSection.emitIntVal(dwarf::DW_LLE_base_addressx, 1); - encodeULEB128(DebugAddrIndexMap.getValueIndex(*BaseAddress), - OutLocationSection.OS); - } - - // Emit type of entry. - OutLocationSection.emitIntVal(dwarf::DW_LLE_offset_pair, 1); - - // Emit start offset relative to base address. - encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress, - OutLocationSection.OS); - - // Emit end offset relative to base address. - encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress, - OutLocationSection.OS); - } else - // Emit type of entry. - OutLocationSection.emitIntVal(dwarf::DW_LLE_default_location, 1); - - encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.OS); - OffsetBeforeLocationExpression = OutLocationSection.OS.tell(); - for (uint64_t *OffsetPtr : LocExpression.Patches) - *OffsetPtr += OffsetBeforeLocationExpression; - - OutLocationSection.OS << StringRef( - (const char *)LocExpression.Expression.Expr.data(), - LocExpression.Expression.Expr.size()); - } - - // Emit the terminator entry. - OutLocationSection.emitIntVal(dwarf::DW_LLE_end_of_list, 1); - return OffsetBeforeLocationExpression; -} - -Error CompileUnit::emitDebugAddrSection() { - if (GlobalData.getOptions().UpdateIndexTablesOnly) - return Error::success(); - - if (getVersion() < 5) - return Error::success(); - - if (DebugAddrIndexMap.empty()) - return Error::success(); - - SectionDescriptor &OutAddrSection = - getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr); - - // Emit section header. - - // Emit length. - OutAddrSection.emitUnitLength(0xBADDEF); - uint64_t OffsetAfterSectionLength = OutAddrSection.OS.tell(); - - // Emit version. - OutAddrSection.emitIntVal(5, 2); - - // Emit address size. - OutAddrSection.emitIntVal(getFormParams().AddrSize, 1); - - // Emit segment size. - OutAddrSection.emitIntVal(0, 1); - - // Emit addresses. - for (uint64_t AddrValue : DebugAddrIndexMap.getValues()) - OutAddrSection.emitIntVal(AddrValue, getFormParams().AddrSize); - - // Patch section length. - OutAddrSection.apply( - OffsetAfterSectionLength - - OutAddrSection.getFormParams().getDwarfOffsetByteSize(), - dwarf::DW_FORM_sec_offset, - OutAddrSection.OS.tell() - OffsetAfterSectionLength); - - return Error::success(); -} - -Error CompileUnit::emitDebugStringOffsetSection() { - if (getVersion() < 5) - return Error::success(); - - if (DebugStringIndexMap.empty()) - return Error::success(); - - SectionDescriptor &OutDebugStrOffsetsSection = - getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets); - - // Emit section header. - - // Emit length. - OutDebugStrOffsetsSection.emitUnitLength(0xBADDEF); - uint64_t OffsetAfterSectionLength = OutDebugStrOffsetsSection.OS.tell(); - - // Emit version. - OutDebugStrOffsetsSection.emitIntVal(5, 2); - - // Emit padding. - OutDebugStrOffsetsSection.emitIntVal(0, 2); - - // Emit index to offset map. - for (const StringEntry *String : DebugStringIndexMap.getValues()) { - // Note patch for string offset value. - OutDebugStrOffsetsSection.notePatch( - DebugStrPatch{{OutDebugStrOffsetsSection.OS.tell()}, String}); - - // Emit placeholder for offset value. - OutDebugStrOffsetsSection.emitOffset(0xBADDEF); - } - - // Patch section length. - OutDebugStrOffsetsSection.apply( - OffsetAfterSectionLength - - OutDebugStrOffsetsSection.getFormParams().getDwarfOffsetByteSize(), - dwarf::DW_FORM_sec_offset, - OutDebugStrOffsetsSection.OS.tell() - OffsetAfterSectionLength); - - return Error::success(); -} - -Error CompileUnit::cloneAndEmitRanges() { - if (getGlobalData().getOptions().UpdateIndexTablesOnly) - return Error::success(); - - // Build set of linked address ranges for unit function ranges. - AddressRanges LinkedFunctionRanges; - for (const AddressRangeValuePair &Range : getFunctionRanges()) - LinkedFunctionRanges.insert( - {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value}); - - emitAranges(LinkedFunctionRanges); - - if (getOrigUnit().getVersion() < 5) { - cloneAndEmitRangeList(DebugSectionKind::DebugRange, LinkedFunctionRanges); - return Error::success(); - } - - cloneAndEmitRangeList(DebugSectionKind::DebugRngLists, LinkedFunctionRanges); - return Error::success(); -} - -void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind, - AddressRanges &LinkedFunctionRanges) { - SectionDescriptor &DebugInfoSection = - getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); - SectionDescriptor &OutRangeSection = - getOrCreateSectionDescriptor(RngSectionKind); - - if (!DebugInfoSection.ListDebugRangePatch.empty()) { - std::optional CachedRange; - uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection); - - DebugRangePatch *CompileUnitRangePtr = nullptr; - DebugInfoSection.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) { - if (Patch.IsCompileUnitRanges) { - CompileUnitRangePtr = &Patch; - } else { - // Get ranges from the source DWARF corresponding to the current - // attribute. - AddressRanges LinkedRanges; - uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal( - Patch.PatchOffset, - DebugInfoSection.getFormParams().getDwarfOffsetByteSize()); - if (Expected InputRanges = - getOrigUnit().findRnglistFromOffset( - InputDebugRangesSectionOffset)) { - // Apply relocation adjustment. - for (const auto &Range : *InputRanges) { - if (!CachedRange || !CachedRange->Range.contains(Range.LowPC)) - CachedRange = - getFunctionRanges().getRangeThatContains(Range.LowPC); - - // All range entries should lie in the function range. - if (!CachedRange) { - warn("inconsistent range data."); - continue; - } - - // Store range for emiting. - LinkedRanges.insert({Range.LowPC + CachedRange->Value, - Range.HighPC + CachedRange->Value}); - } - } else { - llvm::consumeError(InputRanges.takeError()); - warn("invalid range list ignored."); - } - - // Emit linked ranges. - DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, - OutRangeSection.OS.tell()); - emitRangeListFragment(LinkedRanges, OutRangeSection); - } - }); - - if (CompileUnitRangePtr != nullptr) { - // Emit compile unit ranges last to be binary compatible with classic - // dsymutil. - DebugInfoSection.apply(CompileUnitRangePtr->PatchOffset, - dwarf::DW_FORM_sec_offset, - OutRangeSection.OS.tell()); - emitRangeListFragment(LinkedFunctionRanges, OutRangeSection); - } - - if (OffsetAfterUnitLength > 0) { - assert(OffsetAfterUnitLength - - OutRangeSection.getFormParams().getDwarfOffsetByteSize() < - OffsetAfterUnitLength); - OutRangeSection.apply( - OffsetAfterUnitLength - - OutRangeSection.getFormParams().getDwarfOffsetByteSize(), - dwarf::DW_FORM_sec_offset, - OutRangeSection.OS.tell() - OffsetAfterUnitLength); - } - } -} - -uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) { - if (OutRangeSection.getFormParams().Version < 5) - return 0; - - // unit_length. - OutRangeSection.emitUnitLength(0xBADDEF); - uint64_t OffsetAfterUnitLength = OutRangeSection.OS.tell(); - - // Version. - OutRangeSection.emitIntVal(5, 2); - - // Address size. - OutRangeSection.emitIntVal(OutRangeSection.getFormParams().AddrSize, 1); - - // Seg_size - OutRangeSection.emitIntVal(0, 1); - - // Offset entry count - OutRangeSection.emitIntVal(0, 4); - - return OffsetAfterUnitLength; -} - -void CompileUnit::emitRangeListFragment(const AddressRanges &LinkedRanges, - SectionDescriptor &OutRangeSection) { - if (OutRangeSection.getFormParams().Version < 5) { - // Emit ranges. - uint64_t BaseAddress = 0; - if (std::optional LowPC = getLowPc()) - BaseAddress = *LowPC; - - for (const AddressRange &Range : LinkedRanges) { - OutRangeSection.emitIntVal(Range.start() - BaseAddress, - OutRangeSection.getFormParams().AddrSize); - OutRangeSection.emitIntVal(Range.end() - BaseAddress, - OutRangeSection.getFormParams().AddrSize); - } - - // Add the terminator entry. - OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize); - OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize); - return; - } - - std::optional BaseAddress; - for (const AddressRange &Range : LinkedRanges) { - if (!BaseAddress) { - BaseAddress = Range.start(); - - // Emit base address. - OutRangeSection.emitIntVal(dwarf::DW_RLE_base_addressx, 1); - encodeULEB128(getDebugAddrIndex(*BaseAddress), OutRangeSection.OS); - } - - // Emit type of entry. - OutRangeSection.emitIntVal(dwarf::DW_RLE_offset_pair, 1); - - // Emit start offset relative to base address. - encodeULEB128(Range.start() - *BaseAddress, OutRangeSection.OS); - - // Emit end offset relative to base address. - encodeULEB128(Range.end() - *BaseAddress, OutRangeSection.OS); - } - - // Emit the terminator entry. - OutRangeSection.emitIntVal(dwarf::DW_RLE_end_of_list, 1); -} - -void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) { - if (LinkedFunctionRanges.empty()) - return; - - SectionDescriptor &DebugInfoSection = - getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); - SectionDescriptor &OutArangesSection = - getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges); - - // Emit Header. - unsigned HeaderSize = - sizeof(int32_t) + // Size of contents (w/o this field - sizeof(int16_t) + // DWARF ARange version number - sizeof(int32_t) + // Offset of CU in the .debug_info section - sizeof(int8_t) + // Pointer Size (in bytes) - sizeof(int8_t); // Segment Size (in bytes) - - unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2; - unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize)); - - OutArangesSection.emitOffset(0xBADDEF); // Aranges length - uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell(); - - OutArangesSection.emitIntVal(dwarf::DW_ARANGES_VERSION, 2); // Version number - OutArangesSection.notePatch( - DebugOffsetPatch{OutArangesSection.OS.tell(), &DebugInfoSection}); - OutArangesSection.emitOffset(0xBADDEF); // Corresponding unit's offset - OutArangesSection.emitIntVal(OutArangesSection.getFormParams().AddrSize, - 1); // Address size - OutArangesSection.emitIntVal(0, 1); // Segment size - - for (size_t Idx = 0; Idx < Padding; Idx++) - OutArangesSection.emitIntVal(0, 1); // Padding - - // Emit linked ranges. - for (const AddressRange &Range : LinkedFunctionRanges) { - OutArangesSection.emitIntVal(Range.start(), - OutArangesSection.getFormParams().AddrSize); - OutArangesSection.emitIntVal(Range.end() - Range.start(), - OutArangesSection.getFormParams().AddrSize); - } - - // Emit terminator. - OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize); - OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize); - - uint64_t OffsetAfterArangesEnd = OutArangesSection.OS.tell(); - - // Update Aranges lentgh. - OutArangesSection.apply( - OffsetAfterArangesLengthField - - OutArangesSection.getFormParams().getDwarfOffsetByteSize(), - dwarf::DW_FORM_sec_offset, - OffsetAfterArangesEnd - OffsetAfterArangesLengthField); -} - -Error CompileUnit::cloneAndEmitDebugMacro() { - if (getOutUnitDIE() == nullptr) - return Error::success(); - - DWARFUnit &OrigUnit = getOrigUnit(); - DWARFDie OrigUnitDie = OrigUnit.getUnitDIE(); - - // Check for .debug_macro table. - if (std::optional MacroAttr = - dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) { - if (const DWARFDebugMacro *Table = - getContaingFile().Dwarf->getDebugMacro()) { - emitMacroTableImpl(Table, *MacroAttr, true); - } - } - - // Check for .debug_macinfo table. - if (std::optional MacroAttr = - dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) { - if (const DWARFDebugMacro *Table = - getContaingFile().Dwarf->getDebugMacinfo()) { - emitMacroTableImpl(Table, *MacroAttr, false); - } - } - - return Error::success(); -} - -void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro *MacroTable, - uint64_t OffsetToMacroTable, - bool hasDWARFv5Header) { - SectionDescriptor &OutSection = - hasDWARFv5Header - ? getOrCreateSectionDescriptor(DebugSectionKind::DebugMacro) - : getOrCreateSectionDescriptor(DebugSectionKind::DebugMacinfo); - - bool DefAttributeIsReported = false; - bool UndefAttributeIsReported = false; - bool ImportAttributeIsReported = false; - - for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) { - if (OffsetToMacroTable == List.Offset) { - // Write DWARFv5 header. - if (hasDWARFv5Header) { - // Write header version. - OutSection.emitIntVal(List.Header.Version, sizeof(List.Header.Version)); - - uint8_t Flags = List.Header.Flags; - - // Check for OPCODE_OPERANDS_TABLE. - if (Flags & - DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) { - Flags &= - ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE; - warn("opcode_operands_table is not supported yet."); - } - - // Check for DEBUG_LINE_OFFSET. - std::optional StmtListOffset; - if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) { - // Get offset to the line table from the cloned compile unit. - for (auto &V : getOutUnitDIE()->values()) { - if (V.getAttribute() == dwarf::DW_AT_stmt_list) { - StmtListOffset = V.getDIEInteger().getValue(); - break; - } - } - - if (!StmtListOffset) { - Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET; - warn("couldn`t find line table for macro table."); - } - } - - // Write flags. - OutSection.emitIntVal(Flags, sizeof(Flags)); - - // Write offset to line table. - if (StmtListOffset) { - OutSection.notePatch(DebugOffsetPatch{ - OutSection.OS.tell(), - &getOrCreateSectionDescriptor(DebugSectionKind::DebugLine)}); - // TODO: check that List.Header.getOffsetByteSize() and - // DebugOffsetPatch agree on size. - OutSection.emitIntVal(0xBADDEF, List.Header.getOffsetByteSize()); - } - } - - // Write macro entries. - for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) { - if (MacroEntry.Type == 0) { - encodeULEB128(MacroEntry.Type, OutSection.OS); - continue; - } - - uint8_t MacroType = MacroEntry.Type; - switch (MacroType) { - default: { - bool HasVendorSpecificExtension = - (!hasDWARFv5Header && - MacroType == dwarf::DW_MACINFO_vendor_ext) || - (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user && - MacroType <= dwarf::DW_MACRO_hi_user)); - - if (HasVendorSpecificExtension) { - // Write macinfo type. - OutSection.emitIntVal(MacroType, 1); - - // Write vendor extension constant. - encodeULEB128(MacroEntry.ExtConstant, OutSection.OS); - - // Write vendor extension string. - OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr); - } else - warn("unknown macro type. skip."); - } break; - // debug_macro and debug_macinfo share some common encodings. - // DW_MACRO_define == DW_MACINFO_define - // DW_MACRO_undef == DW_MACINFO_undef - // DW_MACRO_start_file == DW_MACINFO_start_file - // DW_MACRO_end_file == DW_MACINFO_end_file - // For readibility/uniformity we are using DW_MACRO_*. - case dwarf::DW_MACRO_define: - case dwarf::DW_MACRO_undef: { - // Write macinfo type. - OutSection.emitIntVal(MacroType, 1); - - // Write source line. - encodeULEB128(MacroEntry.Line, OutSection.OS); - - // Write macro string. - OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr); - } break; - case dwarf::DW_MACRO_define_strp: - case dwarf::DW_MACRO_undef_strp: - case dwarf::DW_MACRO_define_strx: - case dwarf::DW_MACRO_undef_strx: { - // DW_MACRO_*_strx forms are not supported currently. - // Convert to *_strp. - switch (MacroType) { - case dwarf::DW_MACRO_define_strx: { - MacroType = dwarf::DW_MACRO_define_strp; - if (!DefAttributeIsReported) { - warn("DW_MACRO_define_strx unsupported yet. Convert to " - "DW_MACRO_define_strp."); - DefAttributeIsReported = true; - } - } break; - case dwarf::DW_MACRO_undef_strx: { - MacroType = dwarf::DW_MACRO_undef_strp; - if (!UndefAttributeIsReported) { - warn("DW_MACRO_undef_strx unsupported yet. Convert to " - "DW_MACRO_undef_strp."); - UndefAttributeIsReported = true; - } - } break; - default: - // Nothing to do. - break; - } - - // Write macinfo type. - OutSection.emitIntVal(MacroType, 1); - - // Write source line. - encodeULEB128(MacroEntry.Line, OutSection.OS); - - // Write macro string. - OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr); - break; - } - case dwarf::DW_MACRO_start_file: { - // Write macinfo type. - OutSection.emitIntVal(MacroType, 1); - // Write source line. - encodeULEB128(MacroEntry.Line, OutSection.OS); - // Write source file id. - encodeULEB128(MacroEntry.File, OutSection.OS); - } break; - case dwarf::DW_MACRO_end_file: { - // Write macinfo type. - OutSection.emitIntVal(MacroType, 1); - } break; - case dwarf::DW_MACRO_import: - case dwarf::DW_MACRO_import_sup: { - if (!ImportAttributeIsReported) { - warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported " - "yet. remove."); - ImportAttributeIsReported = true; - } - } break; - } - } - - return; - } - } -} - -void CompileUnit::cloneDieAttrExpression( - const DWARFExpression &InputExpression, - SmallVectorImpl &OutputExpression, SectionDescriptor &Section, - std::optional VarAddressAdjustment, - OffsetsPtrVector &PatchesOffsets) { - using Encoding = DWARFExpression::Operation::Encoding; - - DWARFUnit &OrigUnit = getOrigUnit(); - uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize(); - - uint64_t OpOffset = 0; - for (auto &Op : InputExpression) { - auto Desc = Op.getDescription(); - // DW_OP_const_type is variable-length and has 3 - // operands. Thus far we only support 2. - if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) || - (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef && - Desc.Op[0] != Encoding::Size1)) - warn("unsupported DW_OP encoding."); - - if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) || - (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef && - Desc.Op[0] == Encoding::Size1)) { - // This code assumes that the other non-typeref operand fits into 1 byte. - assert(OpOffset < Op.getEndOffset()); - uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1; - assert(ULEBsize <= 16); - - // Copy over the operation. - assert(!Op.getSubCode() && "SubOps not yet supported"); - OutputExpression.push_back(Op.getCode()); - uint64_t RefOffset; - if (Desc.Op.size() == 1) { - RefOffset = Op.getRawOperand(0); - } else { - OutputExpression.push_back(Op.getRawOperand(0)); - RefOffset = Op.getRawOperand(1); - } - uint8_t ULEB[16]; - uint32_t Offset = 0; - unsigned RealSize = 0; - // Look up the base type. For DW_OP_convert, the operand may be 0 to - // instead indicate the generic type. The same holds for - // DW_OP_reinterpret, which is currently not supported. - if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) { - RefOffset += OrigUnit.getOffset(); - uint32_t RefDieIdx = 0; - if (std::optional Idx = - OrigUnit.getDIEIndexForOffset(RefOffset)) - RefDieIdx = *Idx; - - // Use fixed size for ULEB128 data, since we need to update that size - // later with the proper offsets. Use 5 for DWARF32, 9 for DWARF64. - ULEBsize = getFormParams().getDwarfOffsetByteSize() + 1; - - RealSize = encodeULEB128(0xBADDEF, ULEB, ULEBsize); - - Section.notePatchWithOffsetUpdate( - DebugULEB128DieRefPatch(OutputExpression.size(), this, this, - RefDieIdx), - PatchesOffsets); - } else - RealSize = encodeULEB128(Offset, ULEB, ULEBsize); - - if (RealSize > ULEBsize) { - // Emit the generic type as a fallback. - RealSize = encodeULEB128(0, ULEB, ULEBsize); - warn("base type ref doesn't fit."); - } - assert(RealSize == ULEBsize && "padding failed"); - ArrayRef ULEBbytes(ULEB, ULEBsize); - OutputExpression.append(ULEBbytes.begin(), ULEBbytes.end()); - } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly && - Op.getCode() == dwarf::DW_OP_addrx) { - if (std::optional SA = - OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) { - // DWARFLinker does not use addrx forms since it generates relocated - // addresses. Replace DW_OP_addrx with DW_OP_addr here. - // Argument of DW_OP_addrx should be relocated here as it is not - // processed by applyValidRelocs. - OutputExpression.push_back(dwarf::DW_OP_addr); - uint64_t LinkedAddress = - SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0); - if ((getEndianness() == support::endianness::little) != - sys::IsLittleEndianHost) - sys::swapByteOrder(LinkedAddress); - ArrayRef AddressBytes( - reinterpret_cast(&LinkedAddress), - OrigAddressByteSize); - OutputExpression.append(AddressBytes.begin(), AddressBytes.end()); - } else - warn("cann't read DW_OP_addrx operand."); - } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly && - Op.getCode() == dwarf::DW_OP_constx) { - if (std::optional SA = - OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) { - // DWARFLinker does not use constx forms since it generates relocated - // addresses. Replace DW_OP_constx with DW_OP_const[*]u here. - // Argument of DW_OP_constx should be relocated here as it is not - // processed by applyValidRelocs. - std::optional OutOperandKind; - switch (OrigAddressByteSize) { - case 2: - OutOperandKind = dwarf::DW_OP_const2u; - break; - case 4: - OutOperandKind = dwarf::DW_OP_const4u; - break; - case 8: - OutOperandKind = dwarf::DW_OP_const8u; - break; - default: - warn( - formatv(("unsupported address size: {0}."), OrigAddressByteSize)); - break; - } - - if (OutOperandKind) { - OutputExpression.push_back(*OutOperandKind); - uint64_t LinkedAddress = - SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0); - if ((getEndianness() == support::endianness::little) != - sys::IsLittleEndianHost) - sys::swapByteOrder(LinkedAddress); - ArrayRef AddressBytes( - reinterpret_cast(&LinkedAddress), - OrigAddressByteSize); - OutputExpression.append(AddressBytes.begin(), AddressBytes.end()); - } - } else - warn("cann't read DW_OP_constx operand."); - } else { - // Copy over everything else unmodified. - StringRef Bytes = - InputExpression.getData().slice(OpOffset, Op.getEndOffset()); - OutputExpression.append(Bytes.begin(), Bytes.end()); - } - OpOffset = Op.getEndOffset(); - } -} - -Error CompileUnit::cloneAndEmit(std::optional TargetTriple) { - BumpPtrAllocator Allocator; - - DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE(); - 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(), - std::nullopt, std::nullopt, Allocator); - setOutUnitDIE(OutCUDie); - - if (getGlobalData().getOptions().NoOutput || (OutCUDie == nullptr)) - return Error::success(); - - assert(TargetTriple.has_value()); - if (Error Err = cloneAndEmitLineTable(*TargetTriple)) - return Err; - - if (Error Err = cloneAndEmitDebugMacro()) - return Err; - - if (Error Err = emitDebugInfo(*TargetTriple)) - return Err; - - // ASSUMPTION: .debug_info section should already be emitted at this point. - // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section - // data. - - if (Error Err = cloneAndEmitRanges()) - return Err; - - if (Error Err = cloneAndEmitDebugLocations()) - return Err; - - if (Error Err = emitDebugAddrSection()) - return Err; - - if (Error Err = emitDebugStringOffsetSection()) - return Err; - - return emitAbbreviations(); -} - -bool needToClone(CompileUnit::DIEInfo &Info) { - return Info.getKeep() || Info.getKeepChildren(); -} - -DIE *CompileUnit::cloneDIE(const DWARFDebugInfoEntry *InputDieEntry, - uint64_t OutOffset, - std::optional FuncAddressAdjustment, - std::optional VarAddressAdjustment, - BumpPtrAllocator &Allocator) { - uint32_t InputDieIdx = getDIEIndex(InputDieEntry); - CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx); - - if (!needToClone(Info)) - return nullptr; - - bool HasLocationExpressionAddress = false; - if (InputDieEntry->getTag() == dwarf::DW_TAG_subprogram) { - // Get relocation adjustment value for the current function. - FuncAddressAdjustment = - getContaingFile().Addresses->getSubprogramRelocAdjustment( - getDIE(InputDieEntry)); - } else if (InputDieEntry->getTag() == dwarf::DW_TAG_variable) { - // Get relocation adjustment value for the current variable. - std::pair> LocExprAddrAndRelocAdjustment = - getContaingFile().Addresses->getVariableRelocAdjustment( - getDIE(InputDieEntry)); - - HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first; - if (LocExprAddrAndRelocAdjustment.first && - LocExprAddrAndRelocAdjustment.second) - VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second; - } - - DIEGenerator DIEGenerator(Allocator, *this); - DIE *ClonedDIE = DIEGenerator.createDIE(InputDieEntry->getTag(), OutOffset); - rememberDieOutOffset(InputDieIdx, OutOffset); - - // Clone Attributes. - DIEAttributeCloner AttributesCloner( - ClonedDIE, *this, InputDieEntry, DIEGenerator, FuncAddressAdjustment, - VarAddressAdjustment, HasLocationExpressionAddress); - AttributesCloner.clone(); - - bool HasChildrenToClone = Info.getKeepChildren(); - OutOffset = AttributesCloner.finalizeAbbreviations(HasChildrenToClone); - - if (HasChildrenToClone) { - // Recursively clone children. - for (const DWARFDebugInfoEntry *CurChild = - getFirstChildEntry(InputDieEntry); - CurChild && CurChild->getAbbreviationDeclarationPtr(); - CurChild = getSiblingEntry(CurChild)) { - if (DIE *ClonedChild = - cloneDIE(CurChild, OutOffset, FuncAddressAdjustment, - VarAddressAdjustment, Allocator)) { - OutOffset = ClonedChild->getOffset() + ClonedChild->getSize(); - DIEGenerator.addChild(ClonedChild); - } - } - - // Account for the end of children marker. - OutOffset += sizeof(int8_t); - } - - // Update our size. - ClonedDIE->setSize(OutOffset - ClonedDIE->getOffset()); - return ClonedDIE; -} - -Error CompileUnit::cloneAndEmitLineTable(Triple &TargetTriple) { - const DWARFDebugLine::LineTable *InputLineTable = - getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit()); - if (InputLineTable == nullptr) { - warn("cann't load line table."); - return Error::success(); - } - - DWARFDebugLine::LineTable OutLineTable; - - // Set Line Table header. - OutLineTable.Prologue = InputLineTable->Prologue; - OutLineTable.Prologue.FormParams.AddrSize = getFormParams().AddrSize; - - // Set Line Table Rows. - if (getGlobalData().getOptions().UpdateIndexTablesOnly) { - OutLineTable.Rows = InputLineTable->Rows; - // If all the line table contains is a DW_LNE_end_sequence, clear the line - // table rows, it will be inserted again in the DWARFStreamer. - if (OutLineTable.Rows.size() == 1 && OutLineTable.Rows[0].EndSequence) - OutLineTable.Rows.clear(); - - OutLineTable.Sequences = InputLineTable->Sequences; - } else { - // This vector is the output line table. - std::vector NewRows; - NewRows.reserve(InputLineTable->Rows.size()); - - // Current sequence of rows being extracted, before being inserted - // in NewRows. - std::vector Seq; - - const auto &FunctionRanges = getFunctionRanges(); - std::optional CurrRange; - - // FIXME: This logic is meant to generate exactly the same output as - // Darwin's classic dsymutil. There is a nicer way to implement this - // by simply putting all the relocated line info in NewRows and simply - // sorting NewRows before passing it to emitLineTableForUnit. This - // should be correct as sequences for a function should stay - // together in the sorted output. There are a few corner cases that - // look suspicious though, and that required to implement the logic - // this way. Revisit that once initial validation is finished. - - // Iterate over the object file line info and extract the sequences - // that correspond to linked functions. - for (DWARFDebugLine::Row Row : InputLineTable->Rows) { - // Check whether we stepped out of the range. The range is - // half-open, but consider accept the end address of the range if - // it is marked as end_sequence in the input (because in that - // case, the relocation offset is accurate and that entry won't - // serve as the start of another function). - if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) { - // We just stepped out of a known range. Insert a end_sequence - // corresponding to the end of the range. - uint64_t StopAddress = - CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL; - CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address); - if (StopAddress != -1ULL && !Seq.empty()) { - // Insert end sequence row with the computed end address, but - // the same line as the previous one. - auto NextLine = Seq.back(); - NextLine.Address.Address = StopAddress; - NextLine.EndSequence = 1; - NextLine.PrologueEnd = 0; - NextLine.BasicBlock = 0; - NextLine.EpilogueBegin = 0; - Seq.push_back(NextLine); - insertLineSequence(Seq, NewRows); - } - - if (!CurrRange) - continue; - } - - // Ignore empty sequences. - if (Row.EndSequence && Seq.empty()) - continue; - - // Relocate row address and add it to the current sequence. - Row.Address.Address += CurrRange->Value; - Seq.emplace_back(Row); - - if (Row.EndSequence) - insertLineSequence(Seq, NewRows); - } - - OutLineTable.Rows = std::move(NewRows); - } - - return emitDebugLine(TargetTriple, OutLineTable); -} - -void CompileUnit::insertLineSequence(std::vector &Seq, - std::vector &Rows) { - if (Seq.empty()) - return; - - if (!Rows.empty() && Rows.back().Address < Seq.front().Address) { - llvm::append_range(Rows, Seq); - Seq.clear(); - return; - } - - object::SectionedAddress Front = Seq.front().Address; - auto InsertPoint = partition_point( - Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; }); - - // FIXME: this only removes the unneeded end_sequence if the - // sequences have been inserted in order. Using a global sort like - // described in cloneAndEmitLineTable() and delaying the end_sequene - // elimination to DebugLineEmitter::emit() we can get rid of all of them. - if (InsertPoint != Rows.end() && InsertPoint->Address == Front && - InsertPoint->EndSequence) { - *InsertPoint = Seq.front(); - Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end()); - } else { - Rows.insert(InsertPoint, Seq.begin(), Seq.end()); - } - - Seq.clear(); -} - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void CompileUnit::DIEInfo::dump() { - llvm::errs() << "{\n"; - llvm::errs() << " Placement: "; - switch (getPlacement()) { - case NotSet: - llvm::errs() << "NotSet\n"; - break; - case TypeTable: - llvm::errs() << "TypeTable\n"; - break; - case PlainDwarf: - llvm::errs() << "PlainDwarf\n"; - break; - case Both: - llvm::errs() << "Both\n"; - break; - case Parent: - llvm::errs() << "Parent\n"; - break; - } - - llvm::errs() << " Keep: " << getKeep(); - llvm::errs() << " KeepChildren: " << getKeepChildren(); - llvm::errs() << " ReferrencedBy: " << getReferrencedBy(); - llvm::errs() << " IsInMouduleScope: " << getIsInMouduleScope(); - llvm::errs() << " IsInFunctionScope: " << getIsInFunctionScope(); - llvm::errs() << "}\n"; -} -#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.h b/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.h index 24cbcf4d6f1e2..1617a848512d5 100644 --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.h +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.h @@ -10,332 +10,52 @@ #define LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERCOMPILEUNIT_H #include "DWARFLinkerUnit.h" -#include "IndexedValuesMap.h" #include "llvm/DWARFLinkerParallel/DWARFFile.h" +#include "llvm/DWARFLinkerParallel/DWARFLinker.h" #include namespace llvm { namespace dwarflinker_parallel { -using OffsetToUnitTy = function_ref; +struct LinkContext; +class DWARFFile; /// 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 { public: - /// The stages of new compile unit processing. - enum class Stage : uint8_t { - /// Created, linked with input DWARF file. - CreatedNotLoaded = 0, - - /// Input DWARF is loaded. - Loaded, - - /// Input DWARF is analysed(DIEs pointing to the real code section are - /// discovered, type names are assigned if ODR is requested). - LivenessAnalysisDone, - - /// Output DWARF is generated. - Cloned, - - /// Offsets inside patch records are updated. - PatchesUpdated, - - /// Resources(Input DWARF, Output DWARF tree) are released. - Cleaned, - }; - - CompileUnit(LinkingGlobalData &GlobalData, unsigned ID, - StringRef ClangModuleName, DWARFFile &File, - OffsetToUnitTy UnitFromOffset) - : DwarfUnit(GlobalData, ID, ClangModuleName), File(File), - getUnitFromOffset(UnitFromOffset), Stage(Stage::CreatedNotLoaded) { - UnitName = File.FileName; - } - - CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit, unsigned ID, + CompileUnit(LinkContext &, unsigned ID, StringRef ClangModuleName, + DWARFFile &File, + DWARFLinker::SwiftInterfacesMapTy *, + UnitMessageHandlerTy WarningHandler) + : DwarfUnit(ID, ClangModuleName, WarningHandler), ContaingFile(File) { + FormParams.Version = 4; + FormParams.Format = dwarf::DWARF32; + FormParams.AddrSize = 4; + UnitName = ContaingFile.FileName; + } + + CompileUnit(LinkContext &, DWARFUnit &OrigUnit, unsigned ID, StringRef ClangModuleName, DWARFFile &File, - OffsetToUnitTy UnitFromOffset) - : DwarfUnit(GlobalData, ID, ClangModuleName), File(File), - OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset), - Stage(Stage::CreatedNotLoaded) { + UnitMessageHandlerTy WarningHandler) + : DwarfUnit(ID, ClangModuleName, WarningHandler), + ContaingFile(File), OrigUnit(&OrigUnit) { DWARFDie CUDie = OrigUnit.getUnitDIE(); if (!CUDie) return; - setOutputFormat(OrigUnit); - - Language = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_language), 0); - if (const char *CUName = CUDie.getName(DINameKind::ShortName)) - UnitName = CUName; - else - UnitName = File.FileName; - SysRoot = dwarf::toStringRef(CUDie.find(dwarf::DW_AT_LLVM_sysroot)).str(); - } - - /// Returns stage of overall processing. - Stage getStage() const { return Stage; } - - /// Set stage of overall processing. - void setStage(Stage Stage) { this->Stage = Stage; } - - /// Loads unit line table. - void loadLineTable(); - - /// Returns name of the file for the \p FileIdx - /// from the unit`s line table. - StringEntry *getFileName(unsigned FileIdx, StringPool &GlobalStrings); - - /// Returns DWARFFile containing this compile unit. - const DWARFFile &getContaingFile() const { return File; } + if (File.Dwarf) + Endianess = File.Dwarf->isLittleEndian() ? support::endianness::little + : support::endianness::big; - /// Load DIEs of input compilation unit. \returns true if input DIEs - /// successfully loaded. - bool loadInputDIEs(); + FormParams.Version = OrigUnit.getVersion(); + FormParams.Format = dwarf::DWARF32; + FormParams.AddrSize = OrigUnit.getAddressByteSize(); - /// Reset compile units data(results of liveness analysis, clonning) - /// if current stage greater than Stage::Loaded. We need to reset data - /// as we are going to repeat stages. - void maybeResetToLoadedStage(); - - /// Collect references to parseable Swift interfaces in imported - /// DW_TAG_module blocks. - void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry); - - /// Navigate DWARF tree and set die properties. - void analyzeDWARFStructure() { - analyzeDWARFStructureRec(getUnitDIE().getDebugInfoEntry(), false, false); - } - - /// Cleanup unneeded resources after compile unit is cloned. - void cleanupDataAfterClonning(); - - /// After cloning stage the output DIEs offsets are deallocated. - /// This method copies output offsets for referenced DIEs into DIEs patches. - void updateDieRefPatchesWithClonedOffsets(); - - /// Kinds of placement for the output die. - enum DieOutputPlacement : uint8_t { - NotSet = 0, - - /// Corresponding DIE goes to the type table only. - /// NOTE: Not used yet. - TypeTable = 1, - - /// Corresponding DIE goes to the plain dwarf only. - PlainDwarf = 2, - - /// Corresponding DIE goes to type table and to plain dwarf. - /// NOTE: Not used yet. - Both = 3, - - /// Corresponding DIE needs to examine parent to determine - /// the point of placement. - /// NOTE: Not used yet. - Parent = 4 - }; - - /// Information gathered about source DIEs. - struct DIEInfo { - DIEInfo() = default; - DIEInfo(const DIEInfo &Other) { Flags = Other.Flags.load(); } - DIEInfo &operator=(const DIEInfo &Other) { - Flags = Other.Flags.load(); - return *this; - } - - /// Data member keeping various flags. - std::atomic Flags = {0}; - - /// \returns Placement kind for the corresponding die. - DieOutputPlacement getPlacement() const { - return DieOutputPlacement(Flags & 0x7); - } - - /// Sets Placement kind for the corresponding die. - void setPlacement(DieOutputPlacement Placement) { - auto InputData = Flags.load(); - while (!Flags.compare_exchange_weak(InputData, - ((InputData & ~0x7) | Placement))) { - } - } - - /// Unsets Placement kind for the corresponding die. - void unsetPlacement() { - auto InputData = Flags.load(); - while (!Flags.compare_exchange_weak(InputData, (InputData & ~0x7))) { - } - } - - /// Sets Placement kind for the corresponding die. - bool setPlacementIfUnset(DieOutputPlacement Placement) { - auto InputData = Flags.load(); - if ((InputData & 0x7) == NotSet) - if (Flags.compare_exchange_weak(InputData, (InputData | Placement))) - return true; - - return false; - } - -#define SINGLE_FLAG_METHODS_SET(Name, Value) \ - bool get##Name() const { return Flags & Value; } \ - void set##Name() { \ - auto InputData = Flags.load(); \ - while (!Flags.compare_exchange_weak(InputData, InputData | Value)) { \ - } \ - } \ - void unset##Name() { \ - auto InputData = Flags.load(); \ - while (!Flags.compare_exchange_weak(InputData, InputData & ~Value)) { \ - } \ - } - - /// DIE is a part of the linked output. - SINGLE_FLAG_METHODS_SET(Keep, 0x08) - - /// DIE has children which are part of the linked output. - SINGLE_FLAG_METHODS_SET(KeepChildren, 0x10) - - /// DIE is referenced by other DIE. - SINGLE_FLAG_METHODS_SET(ReferrencedBy, 0x20) - - /// DIE is in module scope. - SINGLE_FLAG_METHODS_SET(IsInMouduleScope, 0x40) - - /// DIE is in function scope. - SINGLE_FLAG_METHODS_SET(IsInFunctionScope, 0x80) - - void unsetFlagsWhichSetDuringLiveAnalysis() { - auto InputData = Flags.load(); - while (!Flags.compare_exchange_weak( - InputData, InputData & ~(0x7 | 0x8 | 0x10 | 0x20))) { - } - } - - /// Erase all flags. - void eraseData() { Flags = 0; } - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - LLVM_DUMP_METHOD void dump(); -#endif - }; - - /// \defgroup Group of functions returning DIE info. - /// - /// @{ - - /// \p Idx index of the DIE. - /// \returns DieInfo descriptor. - DIEInfo &getDIEInfo(unsigned Idx) { return DieInfoArray[Idx]; } - - /// \p Idx index of the DIE. - /// \returns DieInfo descriptor. - const DIEInfo &getDIEInfo(unsigned Idx) const { return DieInfoArray[Idx]; } - - /// \p Idx index of the DIE. - /// \returns DieInfo descriptor. - DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) { - return DieInfoArray[getOrigUnit().getDIEIndex(Entry)]; - } - - /// \p Idx index of the DIE. - /// \returns DieInfo descriptor. - const DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) const { - return DieInfoArray[getOrigUnit().getDIEIndex(Entry)]; - } - - /// \p Die - /// \returns PlainDieInfo descriptor. - DIEInfo &getDIEInfo(const DWARFDie &Die) { - return DieInfoArray[getOrigUnit().getDIEIndex(Die)]; - } - - /// \p Die - /// \returns PlainDieInfo descriptor. - const DIEInfo &getDIEInfo(const DWARFDie &Die) const { - return DieInfoArray[getOrigUnit().getDIEIndex(Die)]; - } - - /// \p Idx index of the DIE. - /// \returns DieInfo descriptor. - uint64_t getDieOutOffset(uint32_t Idx) { - return reinterpret_cast *>(&OutDieOffsetArray[Idx]) - ->load(); - } - - /// \p Idx index of the DIE. - /// \returns DieInfo descriptor. - void rememberDieOutOffset(uint32_t Idx, uint64_t Offset) { - reinterpret_cast *>(&OutDieOffsetArray[Idx]) - ->store(Offset); - } - - /// @} - - /// Returns value of DW_AT_low_pc attribute. - std::optional getLowPc() const { return LowPc; } - - /// Returns value of DW_AT_high_pc attribute. - uint64_t getHighPc() const { return HighPc; } - - /// Returns true if there is a label corresponding to the specified \p Addr. - bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); } - - /// Add the low_pc of a label that is relocated by applying - /// offset \p PCOffset. - void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset); - - /// Resolve the DIE attribute reference that has been extracted in \p - /// RefValue. The resulting DIE might be in another CompileUnit. - /// \returns referenced die and corresponding compilation unit. - /// compilation unit is null if reference could not be resolved. - std::optional> - resolveDIEReference(const DWARFFormValue &RefValue); - /// @} - - /// Add a function range [\p LowPC, \p HighPC) that is relocated by applying - /// offset \p PCOffset. - void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset); - - /// Returns function ranges of this unit. - const RangesTy &getFunctionRanges() const { return Ranges; } - - /// Clone and emit this compilation unit. - Error cloneAndEmit(std::optional TargetTriple); - - /// Clone and emit debug locations(.debug_loc/.debug_loclists). - Error cloneAndEmitDebugLocations(); - - /// Clone and emit ranges. - Error cloneAndEmitRanges(); - - /// Clone and emit debug macros(.debug_macinfo/.debug_macro). - Error cloneAndEmitDebugMacro(); - - // Clone input DIE entry. - DIE *cloneDIE(const DWARFDebugInfoEntry *InputDieEntry, uint64_t OutOffset, - std::optional FuncAddressAdjustment, - std::optional VarAddressAdjustment, - BumpPtrAllocator &Allocator); - - // Clone and emit line table. - Error cloneAndEmitLineTable(Triple &TargetTriple); - - /// Clone attribute location axpression. - void cloneDieAttrExpression(const DWARFExpression &InputExpression, - SmallVectorImpl &OutputExpression, - SectionDescriptor &Section, - std::optional VarAddressAdjustment, - OffsetsPtrVector &PatchesOffsets); - - /// Returns index(inside .debug_addr) of an address. - uint64_t getDebugAddrIndex(uint64_t Addr) { - return DebugAddrIndexMap.getValueIndex(Addr); - } + Language = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_language), 0); - /// Returns index(inside .debug_str_offsets) of specified string. - uint64_t getDebugStrIndex(const StringEntry *String) { - return DebugStringIndexMap.getValueIndex(String); + UnitName = ContaingFile.FileName; + SysRoot = dwarf::toStringRef(CUDie.find(dwarf::DW_AT_LLVM_sysroot)).str(); } /// \defgroup Helper methods to access OrigUnit. @@ -422,144 +142,12 @@ class CompileUnit : public DwarfUnit { /// @} - /// \defgroup Methods used for reporting warnings and errors: - /// - /// @{ - - void warn(const Twine &Warning, const DWARFDie *DIE = nullptr) { - GlobalData.warn(Warning, getUnitName(), DIE); - } - - void warn(Error Warning, const DWARFDie *DIE = nullptr) { - handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) { - GlobalData.warn(Info.message(), getUnitName(), DIE); - }); - } - - void warn(const Twine &Warning, const DWARFDebugInfoEntry *DieEntry) { - if (DieEntry != nullptr) { - DWARFDie DIE(&getOrigUnit(), DieEntry); - GlobalData.warn(Warning, getUnitName(), &DIE); - return; - } - - GlobalData.warn(Warning, getUnitName()); - } - - void error(const Twine &Err, const DWARFDie *DIE = nullptr) { - GlobalData.warn(Err, getUnitName(), DIE); - } - - void error(Error Err, const DWARFDie *DIE = nullptr) { - handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) { - GlobalData.error(Info.message(), getUnitName(), DIE); - }); - } - - /// @} - private: - /// Navigate DWARF tree recursively and set die properties. - void analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry, - bool IsInModule, bool IsInFunction); - - struct LinkedLocationExpressionsWithOffsetPatches { - DWARFLocationExpression Expression; - OffsetsPtrVector Patches; - }; - using LinkedLocationExpressionsVector = - SmallVector; - - /// Emit debug locations. - void emitLocations(DebugSectionKind LocationSectionKind); - - /// Emit location list header. - uint64_t emitLocListHeader(SectionDescriptor &OutLocationSection); - - /// Emit location list fragment. - uint64_t emitLocListFragment( - const LinkedLocationExpressionsVector &LinkedLocationExpression, - SectionDescriptor &OutLocationSection); - - /// Emit the .debug_addr section fragment for current unit. - Error emitDebugAddrSection(); - - /// Emit the .debug_str_offsets section for current unit. - Error emitDebugStringOffsetSection(); - - /// Emit .debug_aranges. - void emitAranges(AddressRanges &LinkedFunctionRanges); - - /// Clone and emit .debug_ranges/.debug_rnglists. - void cloneAndEmitRangeList(DebugSectionKind RngSectionKind, - AddressRanges &LinkedFunctionRanges); - - /// Emit range list header. - uint64_t emitRangeListHeader(SectionDescriptor &OutRangeSection); - - /// Emit range list fragment. - void emitRangeListFragment(const AddressRanges &LinkedRanges, - SectionDescriptor &OutRangeSection); - - /// Insert the new line info sequence \p Seq into the current - /// set of already linked line info \p Rows. - void insertLineSequence(std::vector &Seq, - std::vector &Rows); - - /// Emits body for both macro sections. - void emitMacroTableImpl(const DWARFDebugMacro *MacroTable, - uint64_t OffsetToMacroTable, bool hasDWARFv5Header); - /// DWARFFile containing this compile unit. - DWARFFile &File; + DWARFFile &ContaingFile; /// Pointer to the paired compile unit from the input DWARF. DWARFUnit *OrigUnit = nullptr; - - /// Line table for this unit. - const DWARFDebugLine::LineTable *LineTablePtr = nullptr; - - /// Cached resolved paths from the line table. - /// The key is . - using ResolvedPathsMap = DenseMap; - 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; - - /// Maps a string into the index inside .debug_str_offsets section. - IndexedValuesMap DebugStringIndexMap; - - /// \defgroup Data Members accessed asinchroniously. - /// - /// @{ - OffsetToUnitTy getUnitFromOffset; - - std::optional LowPc; - uint64_t HighPc = 0; - - /// The ranges in that map are the PC ranges for functions in this unit, - /// associated with the PC offset to apply to the addresses to get - /// the linked address. - RangesTy Ranges; - std::mutex RangesMutex; - - /// The DW_AT_low_pc of each DW_TAG_label. - SmallDenseMap Labels; - std::mutex LabelsMutex; - - /// This field keeps current stage of overall compile unit processing. - std::atomic Stage; - - /// DIE info indexed by DIE index. - SmallVector DieInfoArray; - SmallVector OutDieOffsetArray; - /// @} }; } // end of namespace dwarflinker_parallel diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerGlobalData.h b/llvm/lib/DWARFLinkerParallel/DWARFLinkerGlobalData.h deleted file mode 100644 index 78d0b5468d049..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerGlobalData.h +++ /dev/null @@ -1,159 +0,0 @@ -//===- DWARFLinkerGlobalData.h ----------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERGLOBALDATA_H -#define LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERGLOBALDATA_H - -#include "llvm/DWARFLinkerParallel/DWARFLinker.h" -#include "llvm/DWARFLinkerParallel/StringPool.h" -#include "llvm/Support/PerThreadBumpPtrAllocator.h" -#include - -namespace llvm { - -class DWARFDie; - -namespace dwarflinker_parallel { - -using TranslatorFuncTy = std::function; -using MessageHandlerTy = std::function; - -/// linking options -struct DWARFLinkerOptions { - /// DWARF version for the output. - uint16_t TargetDWARFVersion = 0; - - /// Generate processing log to the standard output. - bool Verbose = false; - - /// Print statistics. - bool Statistics = false; - - /// Verify the input DWARF. - bool VerifyInputDWARF = false; - - /// Do not emit output. - bool NoOutput = false; - - /// Do not unique types according to ODR - bool NoODR = false; - - /// Update index tables. - bool UpdateIndexTablesOnly = false; - - /// Whether we want a static variable to force us to keep its enclosing - /// function. - bool KeepFunctionForStatic = false; - - /// Allow to generate valid, but non deterministic output. - bool AllowNonDeterministicOutput = false; - - /// Number of threads. - unsigned Threads = 1; - - /// The accelerator table kinds - SmallVector AccelTables; - - /// Prepend path for the clang modules. - std::string PrependPath; - - /// input verification handler(it might be called asynchronously). - DWARFLinker::InputVerificationHandlerTy InputVerificationHandler = nullptr; - - /// A list of all .swiftinterface files referenced by the debug - /// info, mapping Module name to path on disk. The entries need to - /// be uniqued and sorted and there are only few entries expected - /// per compile unit, which is why this is a std::map. - /// this is dsymutil specific fag. - /// - /// (it might be called asynchronously). - DWARFLinker::SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr; - - /// A list of remappings to apply to file paths. - /// - /// (it might be called asynchronously). - DWARFLinker::ObjectPrefixMapTy *ObjectPrefixMap = nullptr; -}; - -class DWARFLinkerImpl; - -/// This class keeps data and services common for the whole linking process. -class LinkingGlobalData { - friend DWARFLinkerImpl; - -public: - /// Returns global per-thread allocator. - parallel::PerThreadBumpPtrAllocator &getAllocator() { return Allocator; } - - /// Returns global string pool. - StringPool &getStringPool() { return Strings; } - - /// Set translation function. - void setTranslator(TranslatorFuncTy Translator) { - this->Translator = Translator; - } - - /// Translate specified string. - StringRef translateString(StringRef String) { - if (Translator) - return Translator(String); - - return String; - } - - /// Returns linking options. - const DWARFLinkerOptions &getOptions() const { return Options; } - - /// Set warning handler. - void setWarningHandler(MessageHandlerTy Handler) { WarningHandler = Handler; } - - /// Set error handler. - void setErrorHandler(MessageHandlerTy Handler) { ErrorHandler = Handler; } - - /// Report warning. - void warn(const Twine &Warning, StringRef Context, - const DWARFDie *DIE = nullptr) { - if (WarningHandler) - (WarningHandler)(Warning, Context, DIE); - } - - /// Report warning. - void warn(Error Warning, StringRef Context, const DWARFDie *DIE = nullptr) { - handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) { - warn(Info.message(), Context, DIE); - }); - } - - /// Report error. - void error(const Twine &Err, StringRef Context, - const DWARFDie *DIE = nullptr) { - if (ErrorHandler) - (ErrorHandler)(Err, Context, DIE); - } - - /// Report error. - void error(Error Err, StringRef Context, const DWARFDie *DIE = nullptr) { - handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) { - error(Info.message(), Context, DIE); - }); - } - -protected: - parallel::PerThreadBumpPtrAllocator Allocator; - StringPool Strings; - TranslatorFuncTy Translator; - DWARFLinkerOptions Options; - MessageHandlerTy WarningHandler; - MessageHandlerTy ErrorHandler; -}; - -} // end of namespace dwarflinker_parallel -} // end namespace llvm - -#endif // LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERGLOBALDATA_H diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.cpp b/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.cpp index 9e1a4671feac6..dfd77af92f272 100644 --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.cpp +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.cpp @@ -7,20 +7,33 @@ //===----------------------------------------------------------------------===// #include "DWARFLinkerImpl.h" -#include "DIEGenerator.h" -#include "DependencyTracker.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/Parallel.h" -#include "llvm/Support/ThreadPool.h" namespace llvm { namespace dwarflinker_parallel { +/// Similar to DWARFUnitSection::getUnitForOffset(), but returning our +/// CompileUnit object instead. +CompileUnit * +DWARFLinkerImpl::LinkContext::getUnitForOffset(CompileUnit &CurrentCU, + uint64_t Offset) const { + if (CurrentCU.isClangModule()) + return &CurrentCU; + + auto CU = llvm::upper_bound( + CompileUnits, Offset, + [](uint64_t LHS, const std::unique_ptr &RHS) { + return LHS < RHS->getOrigUnit().getNextUnitOffset(); + }); + + return CU != CompileUnits.end() ? CU->get() : nullptr; +} + Error DWARFLinkerImpl::createEmitter(const Triple &TheTriple, OutputFileType FileType, raw_pwrite_stream &OutFile) { - TheDwarfEmitter = std::make_unique(FileType, OutFile); + TheDwarfEmitter = std::make_unique( + FileType, OutFile, OutputStrings.getTranslator(), WarningHandler); return TheDwarfEmitter->init(TheTriple, "__DWARF"); } @@ -29,1059 +42,5 @@ ExtraDwarfEmitter *DWARFLinkerImpl::getEmitter() { return TheDwarfEmitter.get(); } -void DWARFLinkerImpl::addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader, - CompileUnitHandlerTy OnCUDieLoaded) { - ObjectContexts.emplace_back(std::make_unique( - GlobalData, File, ClangModules, UniqueUnitID, - (TheDwarfEmitter.get() == nullptr ? std::optional(std::nullopt) - : TheDwarfEmitter->getTargetTriple()))); - - if (ObjectContexts.back()->InputDWARFFile.Dwarf) { - for (const std::unique_ptr &CU : - ObjectContexts.back()->InputDWARFFile.Dwarf->compile_units()) { - DWARFDie CUDie = CU->getUnitDIE(); - OverallNumberOfCU++; - - if (!CUDie) - continue; - - OnCUDieLoaded(*CU); - - // Register mofule reference. - if (!GlobalData.getOptions().UpdateIndexTablesOnly) - ObjectContexts.back()->registerModuleReference(CUDie, Loader, - OnCUDieLoaded); - } - } -} - -Error DWARFLinkerImpl::link() { - // reset compile unit unique ID counter. - UniqueUnitID = 0; - - if (Error Err = validateAndUpdateOptions()) - return Err; - - std::optional Format; - std::optional Endianess; - - for (std::unique_ptr &Context : ObjectContexts) { - if (Context->InputDWARFFile.Dwarf.get() == nullptr) - continue; - - if (GlobalData.getOptions().Verbose) { - outs() << "OBJECT: " << Context->InputDWARFFile.FileName << "\n"; - - for (const std::unique_ptr &OrigCU : - Context->InputDWARFFile.Dwarf->compile_units()) { - outs() << "Input compilation unit:"; - DIDumpOptions DumpOpts; - DumpOpts.ChildRecurseDepth = 0; - DumpOpts.Verbose = GlobalData.getOptions().Verbose; - OrigCU->getUnitDIE().dump(outs(), 0, DumpOpts); - } - } - - // Verify input DWARF if requested. - if (GlobalData.getOptions().VerifyInputDWARF) - verifyInput(Context->InputDWARFFile); - - for (const std::unique_ptr &OrigCU : - Context->InputDWARFFile.Dwarf->compile_units()) { - if (!Format) - Format = OrigCU.get()->getFormParams(); - } - - if (!Endianess) - Endianess = Context->InputDWARFFile.Dwarf->isLittleEndian() - ? support::endianness::little - : support::endianness::big; - } - - if (!Format) - Format = {GlobalData.getOptions().TargetDWARFVersion, 8, - dwarf::DwarfFormat::DWARF32}; - Format->Version = GlobalData.getOptions().TargetDWARFVersion; - if (!Endianess) - Endianess = support::endianness::little; - - CommonSections.setOutputFormat(*Format, *Endianess); - - // Set parallel options. - if (GlobalData.getOptions().Threads == 0) - parallel::strategy = optimal_concurrency(OverallNumberOfCU); - else - parallel::strategy = hardware_concurrency(GlobalData.getOptions().Threads); - - // Link object files. - if (GlobalData.getOptions().Threads == 1) { - for (std::unique_ptr &Context : ObjectContexts) { - // Link object file. - if (Error Err = Context->link()) - GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName); - - Context->InputDWARFFile.unload(); - } - } else { - ThreadPool Pool(parallel::strategy); - for (std::unique_ptr &Context : ObjectContexts) - Pool.async([&]() { - // Link object file. - if (Error Err = Context->link()) - GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName); - - Context->InputDWARFFile.unload(); - }); - - Pool.wait(); - } - - // At this stage each compile units are cloned to their own set of debug - // sections. Now, update patches, assign offsets and assemble final file - // glueing debug tables from each compile unit. - glueCompileUnitsAndWriteToTheOutput(); - - return Error::success(); -} - -void DWARFLinkerImpl::verifyInput(const DWARFFile &File) { - assert(File.Dwarf); - - std::string Buffer; - raw_string_ostream OS(Buffer); - DIDumpOptions DumpOpts; - if (!File.Dwarf->verify(OS, DumpOpts.noImplicitRecursion())) { - if (GlobalData.getOptions().InputVerificationHandler) - GlobalData.getOptions().InputVerificationHandler(File, OS.str()); - } -} - -Error DWARFLinkerImpl::validateAndUpdateOptions() { - if (GlobalData.getOptions().TargetDWARFVersion == 0) - return createStringError(std::errc::invalid_argument, - "target DWARF version is not set"); - - GlobalData.Options.NoOutput = TheDwarfEmitter.get() == nullptr; - - if (GlobalData.getOptions().Verbose && GlobalData.getOptions().Threads != 1) { - GlobalData.Options.Threads = 1; - GlobalData.warn( - "set number of threads to 1 to make --verbose to work properly.", ""); - } - - return Error::success(); -} - -/// Resolve the relative path to a build artifact referenced by DWARF by -/// applying DW_AT_comp_dir. -static void resolveRelativeObjectPath(SmallVectorImpl &Buf, DWARFDie CU) { - sys::path::append(Buf, dwarf::toString(CU.find(dwarf::DW_AT_comp_dir), "")); -} - -static uint64_t getDwoId(const DWARFDie &CUDie) { - auto DwoId = dwarf::toUnsigned( - CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id})); - if (DwoId) - return *DwoId; - return 0; -} - -static std::string -remapPath(StringRef Path, - const DWARFLinker::ObjectPrefixMapTy &ObjectPrefixMap) { - if (ObjectPrefixMap.empty()) - return Path.str(); - - SmallString<256> p = Path; - for (const auto &Entry : ObjectPrefixMap) - if (llvm::sys::path::replace_path_prefix(p, Entry.first, Entry.second)) - break; - return p.str().str(); -} - -static std::string getPCMFile(const DWARFDie &CUDie, - DWARFLinker::ObjectPrefixMapTy *ObjectPrefixMap) { - std::string PCMFile = dwarf::toString( - CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), ""); - - if (PCMFile.empty()) - return PCMFile; - - if (ObjectPrefixMap) - PCMFile = remapPath(PCMFile, *ObjectPrefixMap); - - return PCMFile; -} - -std::pair DWARFLinkerImpl::LinkContext::isClangModuleRef( - const DWARFDie &CUDie, std::string &PCMFile, unsigned Indent, bool Quiet) { - if (PCMFile.empty()) - return std::make_pair(false, false); - - // Clang module DWARF skeleton CUs abuse this for the path to the module. - uint64_t DwoId = getDwoId(CUDie); - - std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), ""); - if (Name.empty()) { - if (!Quiet) - GlobalData.warn("anonymous module skeleton CU for " + PCMFile + ".", - InputDWARFFile.FileName); - return std::make_pair(true, true); - } - - if (!Quiet && GlobalData.getOptions().Verbose) { - outs().indent(Indent); - outs() << "Found clang module reference " << PCMFile; - } - - auto Cached = ClangModules.find(PCMFile); - if (Cached != ClangModules.end()) { - // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is - // fixed in clang, only warn about DWO_id mismatches in verbose mode. - // ASTFileSignatures will change randomly when a module is rebuilt. - if (!Quiet && GlobalData.getOptions().Verbose && (Cached->second != DwoId)) - GlobalData.warn( - Twine("hash mismatch: this object file was built against a " - "different version of the module ") + - PCMFile + ".", - InputDWARFFile.FileName); - if (!Quiet && GlobalData.getOptions().Verbose) - outs() << " [cached].\n"; - return std::make_pair(true, true); - } - - return std::make_pair(true, false); -} - -/// If this compile unit is really a skeleton CU that points to a -/// clang module, register it in ClangModules and return true. -/// -/// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name -/// pointing to the module, and a DW_AT_gnu_dwo_id with the module -/// hash. -bool DWARFLinkerImpl::LinkContext::registerModuleReference( - const DWARFDie &CUDie, ObjFileLoaderTy Loader, - CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) { - std::string PCMFile = - getPCMFile(CUDie, GlobalData.getOptions().ObjectPrefixMap); - std::pair IsClangModuleRef = - isClangModuleRef(CUDie, PCMFile, Indent, false); - - if (!IsClangModuleRef.first) - return false; - - if (IsClangModuleRef.second) - return true; - - if (GlobalData.getOptions().Verbose) - outs() << " ...\n"; - - // Cyclic dependencies are disallowed by Clang, but we still - // shouldn't run into an infinite loop, so mark it as processed now. - ClangModules.insert({PCMFile, getDwoId(CUDie)}); - - if (Error E = - loadClangModule(Loader, CUDie, PCMFile, OnCUDieLoaded, Indent + 2)) { - consumeError(std::move(E)); - return false; - } - return true; -} - -Error DWARFLinkerImpl::LinkContext::loadClangModule( - ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile, - CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) { - - uint64_t DwoId = getDwoId(CUDie); - std::string ModuleName = dwarf::toString(CUDie.find(dwarf::DW_AT_name), ""); - - /// Using a SmallString<0> because loadClangModule() is recursive. - SmallString<0> Path(GlobalData.getOptions().PrependPath); - if (sys::path::is_relative(PCMFile)) - resolveRelativeObjectPath(Path, CUDie); - sys::path::append(Path, PCMFile); - // Don't use the cached binary holder because we have no thread-safety - // guarantee and the lifetime is limited. - - if (Loader == nullptr) { - GlobalData.error("cann't load clang module: loader is not specified.", - InputDWARFFile.FileName); - return Error::success(); - } - - auto ErrOrObj = Loader(InputDWARFFile.FileName, Path); - if (!ErrOrObj) - return Error::success(); - - std::unique_ptr Unit; - for (const auto &CU : ErrOrObj->Dwarf->compile_units()) { - OnCUDieLoaded(*CU); - // Recursively get all modules imported by this one. - auto ChildCUDie = CU->getUnitDIE(); - if (!ChildCUDie) - continue; - if (!registerModuleReference(ChildCUDie, Loader, OnCUDieLoaded, Indent)) { - if (Unit) { - std::string Err = - (PCMFile + - ": Clang modules are expected to have exactly 1 compile unit.\n"); - GlobalData.error(Err, InputDWARFFile.FileName); - return make_error(Err, inconvertibleErrorCode()); - } - // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is - // fixed in clang, only warn about DWO_id mismatches in verbose mode. - // ASTFileSignatures will change randomly when a module is rebuilt. - uint64_t PCMDwoId = getDwoId(ChildCUDie); - if (PCMDwoId != DwoId) { - if (GlobalData.getOptions().Verbose) - GlobalData.warn( - Twine("hash mismatch: this object file was built against a " - "different version of the module ") + - PCMFile + ".", - InputDWARFFile.FileName); - // Update the cache entry with the DwoId of the module loaded from disk. - ClangModules[PCMFile] = PCMDwoId; - } - - // Empty modules units should not be cloned. - if (!ChildCUDie.hasChildren()) - continue; - - // Add this module. - Unit = std::make_unique( - GlobalData, *CU, UniqueUnitID.fetch_add(1), ModuleName, *ErrOrObj, - getUnitForOffset); - } - } - - if (Unit) { - ModulesCompileUnits.emplace_back(RefModuleUnit{*ErrOrObj, std::move(Unit)}); - // Preload line table, as it can't be loaded asynchronously. - ModulesCompileUnits.back().Unit->loadLineTable(); - } - - return Error::success(); -} - -Error DWARFLinkerImpl::LinkContext::link() { - InterCUProcessingStarted = false; - if (InputDWARFFile.Warnings.empty()) { - if (!InputDWARFFile.Dwarf) - return Error::success(); - - // Preload macro tables, as they can't be loaded asynchronously. - InputDWARFFile.Dwarf->getDebugMacinfo(); - InputDWARFFile.Dwarf->getDebugMacro(); - - // Link modules compile units first. - parallelForEach(ModulesCompileUnits, [&](RefModuleUnit &RefModule) { - linkSingleCompileUnit(*RefModule.Unit); - }); - - // Check for live relocations. If there is no any live relocation then we - // can skip entire object file. - if (!GlobalData.getOptions().UpdateIndexTablesOnly && - !InputDWARFFile.Addresses->hasValidRelocs()) { - if (GlobalData.getOptions().Verbose) - outs() << "No valid relocations found. Skipping.\n"; - return Error::success(); - } - - OriginalDebugInfoSize = getInputDebugInfoSize(); - - // Create CompileUnit structures to keep information about source - // DWARFUnit`s, load line tables. - for (const auto &OrigCU : InputDWARFFile.Dwarf->compile_units()) { - // Load only unit DIE at this stage. - auto CUDie = OrigCU->getUnitDIE(); - std::string PCMFile = - getPCMFile(CUDie, GlobalData.getOptions().ObjectPrefixMap); - - // The !isClangModuleRef condition effectively skips over fully resolved - // skeleton units. - if (!CUDie || GlobalData.getOptions().UpdateIndexTablesOnly || - !isClangModuleRef(CUDie, PCMFile, 0, true).first) { - CompileUnits.emplace_back(std::make_unique( - GlobalData, *OrigCU, UniqueUnitID.fetch_add(1), "", InputDWARFFile, - getUnitForOffset)); - - // Preload line table, as it can't be loaded asynchronously. - CompileUnits.back()->loadLineTable(); - } - }; - - HasNewInterconnectedCUs = false; - - // Link self-sufficient compile units and discover inter-connected compile - // units. - parallelForEach(CompileUnits, [&](std::unique_ptr &CU) { - linkSingleCompileUnit(*CU); - }); - - // Link all inter-connected units. - if (HasNewInterconnectedCUs) { - InterCUProcessingStarted = true; - - do { - HasNewInterconnectedCUs = false; - - // Load inter-connected units. - parallelForEach(CompileUnits, [&](std::unique_ptr &CU) { - if (CU->isInterconnectedCU()) { - CU->maybeResetToLoadedStage(); - linkSingleCompileUnit(*CU, CompileUnit::Stage::Loaded); - } - }); - - // Do liveness analysis for inter-connected units. - parallelForEach(CompileUnits, [&](std::unique_ptr &CU) { - linkSingleCompileUnit(*CU, CompileUnit::Stage::LivenessAnalysisDone); - }); - } while (HasNewInterconnectedCUs); - - // Clone inter-connected units. - parallelForEach(CompileUnits, [&](std::unique_ptr &CU) { - linkSingleCompileUnit(*CU, CompileUnit::Stage::Cloned); - }); - - // Update patches for inter-connected units. - parallelForEach(CompileUnits, [&](std::unique_ptr &CU) { - linkSingleCompileUnit(*CU, CompileUnit::Stage::PatchesUpdated); - }); - - // Release data. - parallelForEach(CompileUnits, [&](std::unique_ptr &CU) { - linkSingleCompileUnit(*CU, CompileUnit::Stage::Cleaned); - }); - } - } - - if (!InputDWARFFile.Warnings.empty()) { - // Create compile unit with paper trail warnings. - - Error ResultErr = Error::success(); - // We use task group here as PerThreadBumpPtrAllocator should be called from - // the threads created by ThreadPoolExecutor. - parallel::TaskGroup TGroup; - TGroup.spawn([&]() { - if (Error Err = cloneAndEmitPaperTrails()) - ResultErr = std::move(Err); - }); - return ResultErr; - } else if (GlobalData.getOptions().UpdateIndexTablesOnly) { - // Emit Invariant sections. - - if (Error Err = emitInvariantSections()) - return Err; - } else if (!CompileUnits.empty()) { - // Emit .debug_frame section. - - Error ResultErr = Error::success(); - parallel::TaskGroup TGroup; - // We use task group here as PerThreadBumpPtrAllocator should be called from - // the threads created by ThreadPoolExecutor. - TGroup.spawn([&]() { - if (Error Err = cloneAndEmitDebugFrame()) - ResultErr = std::move(Err); - }); - return ResultErr; - } - - return Error::success(); -} - -void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit( - CompileUnit &CU, enum CompileUnit::Stage DoUntilStage) { - while (CU.getStage() < DoUntilStage) { - if (InterCUProcessingStarted != CU.isInterconnectedCU()) - return; - - switch (CU.getStage()) { - case CompileUnit::Stage::CreatedNotLoaded: { - // Load input compilation unit DIEs. - // Analyze properties of DIEs. - if (!CU.loadInputDIEs()) { - // We do not need to do liveness analysis for invalud compilation unit. - CU.setStage(CompileUnit::Stage::LivenessAnalysisDone); - } else { - CU.analyzeDWARFStructure(); - - // The registerModuleReference() condition effectively skips - // over fully resolved skeleton units. This second pass of - // registerModuleReferences doesn't do any new work, but it - // will collect top-level errors, which are suppressed. Module - // warnings were already displayed in the first iteration. - if (registerModuleReference( - CU.getOrigUnit().getUnitDIE(), nullptr, - [](const DWARFUnit &) {}, 0)) - CU.setStage(CompileUnit::Stage::PatchesUpdated); - else - CU.setStage(CompileUnit::Stage::Loaded); - } - } break; - - case CompileUnit::Stage::Loaded: { - // Mark all the DIEs that need to be present in the generated output. - // If ODR requested, build type names. - if (!DependencyTracker(*this).resolveDependenciesAndMarkLiveness(CU)) { - assert(HasNewInterconnectedCUs); - return; - } - - CU.setStage(CompileUnit::Stage::LivenessAnalysisDone); - } break; - - case CompileUnit::Stage::LivenessAnalysisDone: - -#ifndef NDEBUG - DependencyTracker::verifyKeepChain(CU); -#endif - - // Clone input compile unit. - if (CU.isClangModule() || GlobalData.getOptions().UpdateIndexTablesOnly || - CU.getContaingFile().Addresses->hasValidRelocs()) { - if (Error Err = CU.cloneAndEmit(TargetTriple)) - CU.error(std::move(Err)); - } - - CU.setStage(CompileUnit::Stage::Cloned); - break; - - case CompileUnit::Stage::Cloned: - // Update DIEs referencies. - CU.updateDieRefPatchesWithClonedOffsets(); - CU.setStage(CompileUnit::Stage::PatchesUpdated); - break; - - case CompileUnit::Stage::PatchesUpdated: - // Cleanup resources. - CU.cleanupDataAfterClonning(); - CU.setStage(CompileUnit::Stage::Cleaned); - break; - - case CompileUnit::Stage::Cleaned: - assert(false); - break; - } - } -} - -Error DWARFLinkerImpl::LinkContext::emitInvariantSections() { - if (GlobalData.getOptions().NoOutput) - return Error::success(); - - getOrCreateSectionDescriptor(DebugSectionKind::DebugLoc).OS - << InputDWARFFile.Dwarf->getDWARFObj().getLocSection().Data; - getOrCreateSectionDescriptor(DebugSectionKind::DebugLocLists).OS - << InputDWARFFile.Dwarf->getDWARFObj().getLoclistsSection().Data; - getOrCreateSectionDescriptor(DebugSectionKind::DebugRange).OS - << InputDWARFFile.Dwarf->getDWARFObj().getRangesSection().Data; - getOrCreateSectionDescriptor(DebugSectionKind::DebugRngLists).OS - << InputDWARFFile.Dwarf->getDWARFObj().getRnglistsSection().Data; - getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges).OS - << InputDWARFFile.Dwarf->getDWARFObj().getArangesSection(); - getOrCreateSectionDescriptor(DebugSectionKind::DebugFrame).OS - << InputDWARFFile.Dwarf->getDWARFObj().getFrameSection().Data; - getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr).OS - << InputDWARFFile.Dwarf->getDWARFObj().getAddrSection().Data; - - return Error::success(); -} - -Error DWARFLinkerImpl::LinkContext::cloneAndEmitDebugFrame() { - if (GlobalData.getOptions().NoOutput) - return Error::success(); - - if (InputDWARFFile.Dwarf.get() == nullptr) - return Error::success(); - - const DWARFObject &InputDWARFObj = InputDWARFFile.Dwarf->getDWARFObj(); - - StringRef OrigFrameData = InputDWARFObj.getFrameSection().Data; - if (OrigFrameData.empty()) - return Error::success(); - - RangesTy AllUnitsRanges; - for (std::unique_ptr &Unit : CompileUnits) { - for (auto CurRange : Unit->getFunctionRanges()) - AllUnitsRanges.insert(CurRange.Range, CurRange.Value); - } - - unsigned SrcAddrSize = InputDWARFObj.getAddressSize(); - - SectionDescriptor &OutSection = - getOrCreateSectionDescriptor(DebugSectionKind::DebugFrame); - - DataExtractor Data(OrigFrameData, InputDWARFObj.isLittleEndian(), 0); - uint64_t InputOffset = 0; - - // Store the data of the CIEs defined in this object, keyed by their - // offsets. - DenseMap LocalCIES; - - /// The CIEs that have been emitted in the output section. The actual CIE - /// data serves a the key to this StringMap. - StringMap EmittedCIEs; - - while (Data.isValidOffset(InputOffset)) { - uint64_t EntryOffset = InputOffset; - uint32_t InitialLength = Data.getU32(&InputOffset); - if (InitialLength == 0xFFFFFFFF) - return createFileError(InputDWARFObj.getFileName(), - createStringError(std::errc::invalid_argument, - "Dwarf64 bits no supported")); - - uint32_t CIEId = Data.getU32(&InputOffset); - if (CIEId == 0xFFFFFFFF) { - // This is a CIE, store it. - StringRef CIEData = OrigFrameData.substr(EntryOffset, InitialLength + 4); - LocalCIES[EntryOffset] = CIEData; - // The -4 is to account for the CIEId we just read. - InputOffset += InitialLength - 4; - continue; - } - - uint64_t Loc = Data.getUnsigned(&InputOffset, SrcAddrSize); - - // Some compilers seem to emit frame info that doesn't start at - // the function entry point, thus we can't just lookup the address - // in the debug map. Use the AddressInfo's range map to see if the FDE - // describes something that we can relocate. - std::optional Range = - AllUnitsRanges.getRangeThatContains(Loc); - if (!Range) { - // The +4 is to account for the size of the InitialLength field itself. - InputOffset = EntryOffset + InitialLength + 4; - continue; - } - - // This is an FDE, and we have a mapping. - // Have we already emitted a corresponding CIE? - StringRef CIEData = LocalCIES[CIEId]; - if (CIEData.empty()) - return createFileError( - InputDWARFObj.getFileName(), - createStringError(std::errc::invalid_argument, - "Inconsistent debug_frame content. Dropping.")); - - uint64_t OffsetToCIERecord = OutSection.OS.tell(); - - // Look if we already emitted a CIE that corresponds to the - // referenced one (the CIE data is the key of that lookup). - auto IteratorInserted = - EmittedCIEs.insert(std::make_pair(CIEData, OffsetToCIERecord)); - OffsetToCIERecord = IteratorInserted.first->getValue(); - - // Emit CIE for this ID if it is not emitted yet. - if (IteratorInserted.second) - OutSection.OS << CIEData; - - // Remember offset to the FDE record, so that we might update - // field referencing CIE record(containing OffsetToCIERecord), - // when final offsets are known. OffsetToCIERecord(which is written later) - // is local to the current .debug_frame section, it should be updated - // with final offset of the .debug_frame section. - OutSection.notePatch( - DebugOffsetPatch{OutSection.OS.tell() + 4, &OutSection, true}); - - // Emit the FDE with updated address and CIE pointer. - // (4 + AddrSize) is the size of the CIEId + initial_location - // fields that will get reconstructed by emitFDE(). - unsigned FDERemainingBytes = InitialLength - (4 + SrcAddrSize); - emitFDE(OffsetToCIERecord, SrcAddrSize, Loc + Range->Value, - OrigFrameData.substr(InputOffset, FDERemainingBytes), OutSection); - InputOffset += FDERemainingBytes; - } - - return Error::success(); -} - -/// Emit a FDE into the debug_frame section. \p FDEBytes -/// contains the FDE data without the length, CIE offset and address -/// which will be replaced with the parameter values. -void DWARFLinkerImpl::LinkContext::emitFDE(uint32_t CIEOffset, - uint32_t AddrSize, uint64_t Address, - StringRef FDEBytes, - SectionDescriptor &Section) { - Section.emitIntVal(FDEBytes.size() + 4 + AddrSize, 4); - Section.emitIntVal(CIEOffset, 4); - Section.emitIntVal(Address, AddrSize); - Section.OS.write(FDEBytes.data(), FDEBytes.size()); -} - -Error DWARFLinkerImpl::LinkContext::cloneAndEmitPaperTrails() { - - CompileUnits.emplace_back( - std::make_unique(GlobalData, UniqueUnitID.fetch_add(1), "", - InputDWARFFile, getUnitForOffset)); - - CompileUnit &CU = *CompileUnits.back(); - - BumpPtrAllocator Allocator; - - DIEGenerator ParentGenerator(Allocator, CU); - - SectionDescriptor &DebugInfoSection = - CU.getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); - OffsetsPtrVector PatchesOffsets; - - uint64_t CurrentOffset = CU.getDebugInfoHeaderSize(); - DIE *CUDie = - ParentGenerator.createDIE(dwarf::DW_TAG_compile_unit, CurrentOffset); - CU.setOutUnitDIE(CUDie); - - DebugInfoSection.notePatchWithOffsetUpdate( - DebugStrPatch{{CurrentOffset}, - GlobalData.getStringPool().insert("dsymutil").first}, - PatchesOffsets); - CurrentOffset += ParentGenerator - .addStringPlaceholderAttribute(dwarf::DW_AT_producer, - dwarf::DW_FORM_strp) - .second; - - CurrentOffset += - ParentGenerator - .addInplaceString(dwarf::DW_AT_name, InputDWARFFile.FileName) - .second; - - size_t SizeAbbrevNumber = ParentGenerator.finalizeAbbreviations(true); - CurrentOffset += SizeAbbrevNumber; - for (uint64_t *OffsetPtr : PatchesOffsets) - *OffsetPtr += SizeAbbrevNumber; - for (const auto &Warning : CU.getContaingFile().Warnings) { - PatchesOffsets.clear(); - DIEGenerator ChildGenerator(Allocator, CU); - - DIE *ChildDie = - ChildGenerator.createDIE(dwarf::DW_TAG_constant, CurrentOffset); - ParentGenerator.addChild(ChildDie); - - DebugInfoSection.notePatchWithOffsetUpdate( - DebugStrPatch{ - {CurrentOffset}, - GlobalData.getStringPool().insert("dsymutil_warning").first}, - PatchesOffsets); - CurrentOffset += ChildGenerator - .addStringPlaceholderAttribute(dwarf::DW_AT_name, - dwarf::DW_FORM_strp) - .second; - - CurrentOffset += - ChildGenerator - .addScalarAttribute(dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1) - .second; - - DebugInfoSection.notePatchWithOffsetUpdate( - DebugStrPatch{{CurrentOffset}, - GlobalData.getStringPool().insert(Warning).first}, - PatchesOffsets); - CurrentOffset += ChildGenerator - .addStringPlaceholderAttribute( - dwarf::DW_AT_const_value, dwarf::DW_FORM_strp) - .second; - - SizeAbbrevNumber = ChildGenerator.finalizeAbbreviations(false); - - CurrentOffset += SizeAbbrevNumber; - for (uint64_t *OffsetPtr : PatchesOffsets) - *OffsetPtr += SizeAbbrevNumber; - - ChildDie->setSize(CurrentOffset - ChildDie->getOffset()); - } - - CurrentOffset += 1; // End of children - CUDie->setSize(CurrentOffset - CUDie->getOffset()); - - uint64_t UnitSize = 0; - UnitSize += CU.getDebugInfoHeaderSize(); - UnitSize += CUDie->getSize(); - CU.setUnitSize(UnitSize); - - if (GlobalData.getOptions().NoOutput) - return Error::success(); - - if (Error Err = CU.emitDebugInfo(*TargetTriple)) - return Err; - - return CU.emitAbbreviations(); -} - -void DWARFLinkerImpl::glueCompileUnitsAndWriteToTheOutput() { - if (GlobalData.getOptions().NoOutput) - return; - - // Go through all object files, all compile units and assign - // offsets to them. - assignOffsets(); - - // Patch size/offsets fields according to the assigned CU offsets. - patchOffsetsAndSizes(); - - // FIXME: Build accelerator tables. - - // Emit common sections. - emitCommonSections(); - - // Cleanup data. - cleanupDataAfterOutputSectionsAreGenerated(); - - // Write debug tables from all object files/compile units into the - // resulting file. - writeDWARFToTheOutput(); - - if (GlobalData.getOptions().Statistics) - printStatistic(); -} - -void DWARFLinkerImpl::printStatistic() { - - // For each object file map how many bytes were emitted. - StringMap SizeByObject; - - for (const std::unique_ptr &Context : ObjectContexts) { - uint64_t AllDebugInfoSectionsSize = 0; - - for (std::unique_ptr &CU : Context->CompileUnits) - if (std::optional DebugInfo = - CU->getSectionDescriptor(DebugSectionKind::DebugInfo)) - AllDebugInfoSectionsSize += (*DebugInfo)->getContents().size(); - - SizeByObject[Context->InputDWARFFile.FileName].Input = - Context->OriginalDebugInfoSize; - SizeByObject[Context->InputDWARFFile.FileName].Output = - AllDebugInfoSectionsSize; - } - - // Create a vector sorted in descending order by output size. - std::vector> Sorted; - for (auto &E : SizeByObject) - Sorted.emplace_back(E.first(), E.second); - llvm::sort(Sorted, [](auto &LHS, auto &RHS) { - return LHS.second.Output > RHS.second.Output; - }); - - auto ComputePercentange = [](int64_t Input, int64_t Output) -> float { - const float Difference = Output - Input; - const float Sum = Input + Output; - if (Sum == 0) - return 0; - return (Difference / (Sum / 2)); - }; - - int64_t InputTotal = 0; - int64_t OutputTotal = 0; - const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n"; - - // Print header. - outs() << ".debug_info section size (in bytes)\n"; - outs() << "----------------------------------------------------------------" - "---------------\n"; - outs() << "Filename Object " - " dSYM Change\n"; - outs() << "----------------------------------------------------------------" - "---------------\n"; - - // Print body. - for (auto &E : Sorted) { - InputTotal += E.second.Input; - OutputTotal += E.second.Output; - llvm::outs() << formatv( - FormatStr, sys::path::filename(E.first).take_back(45), E.second.Input, - E.second.Output, ComputePercentange(E.second.Input, E.second.Output)); - } - // Print total and footer. - outs() << "----------------------------------------------------------------" - "---------------\n"; - llvm::outs() << formatv(FormatStr, "Total", InputTotal, OutputTotal, - ComputePercentange(InputTotal, OutputTotal)); - outs() << "----------------------------------------------------------------" - "---------------\n\n"; -} - -void DWARFLinkerImpl::assignOffsets() { - parallel::TaskGroup TGroup; - TGroup.spawn([&]() { assignOffsetsToStrings(); }); - TGroup.spawn([&]() { assignOffsetsToSections(); }); -} - -void DWARFLinkerImpl::assignOffsetsToStrings() { - size_t CurDebugStrIndex = 1; // start from 1 to take into account zero entry. - uint64_t CurDebugStrOffset = - 1; // start from 1 to take into account zero entry. - 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++; - } - }); -} - -void DWARFLinkerImpl::assignOffsetsToSections() { - std::array SectionSizesAccumulator = {0}; - - forEachObjectSectionsSet([&](OutputSections &UnitSections) { - UnitSections.assignSectionsOffsetAndAccumulateSize(SectionSizesAccumulator); - }); -} - -void DWARFLinkerImpl::forEachObjectSectionsSet( - function_ref SectionsSetHandler) { - // Handle all modules first(before regular compilation units). - for (const std::unique_ptr &Context : ObjectContexts) - for (LinkContext::RefModuleUnit &ModuleUnit : Context->ModulesCompileUnits) - SectionsSetHandler(*ModuleUnit.Unit); - - for (const std::unique_ptr &Context : ObjectContexts) { - // Handle object file common sections. - SectionsSetHandler(*Context); - - // Handle compilation units. - for (std::unique_ptr &CU : Context->CompileUnits) - SectionsSetHandler(*CU); - } -} - -void DWARFLinkerImpl::patchOffsetsAndSizes() { - forEachObjectSectionsSet([&](OutputSections &SectionsSet) { - SectionsSet.forEach([&](SectionDescriptor &OutSection) { - SectionsSet.applyPatches(OutSection, DebugStrStrings, - DebugLineStrStrings); - }); - }); -} - -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() { - 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); - }); - }); - }); - - // Emit .debug_line_str section. - TG.spawn([&]() { - uint64_t DebugLineStrNextOffset = 0; - - forEachObjectSectionsSet([&](OutputSections &Sections) { - Sections.forEach([&](SectionDescriptor &Section) { - emitStringsImpl(Section.ListDebugLineStrPatch, DebugLineStrStrings, - DebugLineStrNextOffset, OutDebugLineStrSection); - }); - }); - }); -} - -void DWARFLinkerImpl::cleanupDataAfterOutputSectionsAreGenerated() { - GlobalData.getStringPool().clear(); - DebugStrStrings.clear(); - DebugLineStrStrings.clear(); -} - -void DWARFLinkerImpl::writeDWARFToTheOutput() { - bool HasAbbreviations = false; - - forEachObjectSectionsSet([&](OutputSections &Sections) { - Sections.forEach([&](SectionDescriptor &OutSection) { - if (!HasAbbreviations && !OutSection.getContents().empty() && - OutSection.getKind() == DebugSectionKind::DebugAbbrev) - HasAbbreviations = true; - - // Emit section content. - TheDwarfEmitter->emitSectionContents(OutSection.getContents(), - OutSection.getName()); - OutSection.erase(); - }); - }); - - CommonSections.forEach([&](SectionDescriptor &OutSection) { - // Emit section content. - TheDwarfEmitter->emitSectionContents(OutSection.getContents(), - OutSection.getName()); - OutSection.erase(); - }); - - if (!HasAbbreviations) { - const SmallVector> Abbreviations; - TheDwarfEmitter->emitAbbrevs(Abbreviations, 3); - } -} - } // end of namespace dwarflinker_parallel } // namespace llvm diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.h b/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.h index 7e41eb11f239e..a8fa9b4b46d8a 100644 --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.h +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.h @@ -11,29 +11,29 @@ #include "DWARFEmitterImpl.h" #include "DWARFLinkerCompileUnit.h" -#include "StringEntryToDwarfStringPoolEntryMap.h" #include "llvm/ADT/AddressRanges.h" #include "llvm/CodeGen/AccelTable.h" #include "llvm/DWARFLinkerParallel/DWARFLinker.h" #include "llvm/DWARFLinkerParallel/StringPool.h" +#include "llvm/DWARFLinkerParallel/StringTable.h" namespace llvm { namespace dwarflinker_parallel { -/// This class links debug info. +using Offset2UnitMapTy = DenseMap; + +struct RangeAttrPatch; +struct LocAttrPatch; + class DWARFLinkerImpl : public DWARFLinker { public: DWARFLinkerImpl(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler, TranslatorFuncTy StringsTranslator) - : UniqueUnitID(0), DebugStrStrings(GlobalData), - DebugLineStrStrings(GlobalData), CommonSections(GlobalData) { - GlobalData.setTranslator(StringsTranslator); - GlobalData.setErrorHandler(ErrorHandler); - GlobalData.setWarningHandler(WarningHandler); - } + : UniqueUnitID(0), ErrorHandler(ErrorHandler), + WarningHandler(WarningHandler), + OutputStrings(Strings, StringsTranslator) {} - /// Create debug info emitter. Error createEmitter(const Triple &TheTriple, OutputFileType FileType, raw_pwrite_stream &OutFile) override; @@ -47,11 +47,13 @@ class DWARFLinkerImpl : public DWARFLinker { /// \pre NoODR, Update options should be set before call to addObjectFile. void addObjectFile( DWARFFile &File, ObjFileLoaderTy Loader = nullptr, - - CompileUnitHandlerTy OnCUDieLoaded = [](const DWARFUnit &) {}) override; + CompileUnitHandlerTy OnCUDieLoaded = [](const DWARFUnit &) {}) override {} /// Link debug info for added files. - Error link() override; + Error link() override { + reportWarning("LLVM parallel dwarflinker is not implemented yet.", ""); + return Error::success(); + } /// \defgroup Methods setting various linking options: /// @@ -59,58 +61,51 @@ class DWARFLinkerImpl : public DWARFLinker { /// /// Allows to generate log of linking process to the standard output. - void setVerbosity(bool Verbose) override { - GlobalData.Options.Verbose = Verbose; - } + void setVerbosity(bool Verbose) override { Options.Verbose = Verbose; } /// Print statistics to standard output. void setStatistics(bool Statistics) override { - GlobalData.Options.Statistics = Statistics; + Options.Statistics = Statistics; } /// Verify the input DWARF. void setVerifyInputDWARF(bool Verify) override { - GlobalData.Options.VerifyInputDWARF = Verify; + Options.VerifyInputDWARF = Verify; } /// Do not unique types according to ODR. - void setNoODR(bool) override { - // FIXME: set option when ODR mode will be supported. - // getOptions().NoODR = NoODR; - GlobalData.Options.NoODR = true; - } + void setNoODR(bool NoODR) override { Options.NoODR = NoODR; } /// Update index tables only(do not modify rest of DWARF). void setUpdateIndexTablesOnly(bool UpdateIndexTablesOnly) override { - GlobalData.Options.UpdateIndexTablesOnly = UpdateIndexTablesOnly; + Options.UpdateIndexTablesOnly = UpdateIndexTablesOnly; } /// Allow generating valid, but non-deterministic output. void setAllowNonDeterministicOutput(bool AllowNonDeterministicOutput) override { - GlobalData.Options.AllowNonDeterministicOutput = - AllowNonDeterministicOutput; + Options.AllowNonDeterministicOutput = AllowNonDeterministicOutput; } /// Set to keep the enclosing function for a static variable. void setKeepFunctionForStatic(bool KeepFunctionForStatic) override { - GlobalData.Options.KeepFunctionForStatic = KeepFunctionForStatic; + Options.KeepFunctionForStatic = KeepFunctionForStatic; } /// Use specified number of threads for parallel files linking. void setNumThreads(unsigned NumThreads) override { - GlobalData.Options.Threads = NumThreads; + Options.Threads = NumThreads; } /// Add kind of accelerator tables to be generated. void addAccelTableKind(AccelTableKind Kind) override { - assert(!llvm::is_contained(GlobalData.getOptions().AccelTables, Kind)); - GlobalData.Options.AccelTables.emplace_back(Kind); + assert(!llvm::is_contained(Options.AccelTables, Kind)); + Options.AccelTables.emplace_back(Kind); } /// Set prepend path for clang modules. void setPrependPath(const std::string &Ppath) override { - GlobalData.Options.PrependPath = Ppath; + Options.PrependPath = Ppath; } /// Set estimated objects files amount, for preliminary data allocation. @@ -122,17 +117,17 @@ class DWARFLinkerImpl : public DWARFLinker { /// errors. void setInputVerificationHandler(InputVerificationHandlerTy Handler) override { - GlobalData.Options.InputVerificationHandler = Handler; + Options.InputVerificationHandler = Handler; } /// Set map for Swift interfaces. void setSwiftInterfacesMap(SwiftInterfacesMapTy *Map) override { - GlobalData.Options.ParseableSwiftInterfaces = Map; + Options.ParseableSwiftInterfaces = Map; } /// Set prefix map for objects. void setObjectPrefixMap(ObjectPrefixMapTy *Map) override { - GlobalData.Options.ObjectPrefixMap = Map; + Options.ObjectPrefixMap = Map; } /// Set target DWARF version. @@ -142,28 +137,36 @@ class DWARFLinkerImpl : public DWARFLinker { "unsupported DWARF version: %d", TargetDWARFVersion); - GlobalData.Options.TargetDWARFVersion = TargetDWARFVersion; + Options.TargetDWARFVersion = TargetDWARFVersion; return Error::success(); } /// @} protected: - /// Verify input DWARF file. - void verifyInput(const DWARFFile &File); + /// Reports Warning. + void reportWarning(const Twine &Warning, const DWARFFile &File, + const DWARFDie *DIE = nullptr) const { + if (WarningHandler != nullptr) + WarningHandler(Warning, File.FileName, DIE); + } - /// Validate specified options. - Error validateAndUpdateOptions(); + /// Reports Warning. + void reportWarning(const Twine &Warning, StringRef FileName, + const DWARFDie *DIE = nullptr) const { + if (WarningHandler != nullptr) + WarningHandler(Warning, FileName, DIE); + } - /// Take already linked compile units and glue them into single file. - void glueCompileUnitsAndWriteToTheOutput(); + /// Reports Error. + void reportError(const Twine &Warning, StringRef FileName, + const DWARFDie *DIE = nullptr) const { + if (ErrorHandler != nullptr) + ErrorHandler(Warning, FileName, DIE); + } - /// Hold the input and output of the debug info size in bytes. - struct DebugInfoSize { - uint64_t Input; - uint64_t Output; - }; + /// Returns next available unique Compile Unit ID. + unsigned getNextUniqueUnitID() { return UniqueUnitID.fetch_add(1); } - friend class DependencyTracker; /// Keeps track of data associated with one object during linking. /// i.e. source file descriptor, compilation units, output data /// for compilation units common tables. @@ -185,7 +188,7 @@ class DWARFLinkerImpl : public DWARFLinker { using ModuleUnitListTy = SmallVector; /// Object file descriptor. - DWARFFile &InputDWARFFile; + DWARFFile &File; /// Set of Compilation Units(may be accessed asynchroniously for reading). UnitListTy CompileUnits; @@ -196,190 +199,117 @@ class DWARFLinkerImpl : public DWARFLinker { /// Size of Debug info before optimizing. uint64_t OriginalDebugInfoSize = 0; - /// Flag indicating that all inter-connected units are loaded - /// and the dwarf linking process for these units is started. - bool InterCUProcessingStarted = false; - - StringMap &ClangModules; - - std::optional TargetTriple; - - /// Flag indicating that new inter-connected compilation units were - /// discovered. It is used for restarting units processing - /// if new inter-connected units were found. - std::atomic HasNewInterconnectedCUs = {false}; + /// Output sections, common for all compilation units. + OutTablesFileTy OutDebugInfoBytes; - /// Counter for compile units ID. - std::atomic &UniqueUnitID; - - LinkContext(LinkingGlobalData &GlobalData, DWARFFile &File, - StringMap &ClangModules, - std::atomic &UniqueUnitID, - std::optional TargetTriple) - : OutputSections(GlobalData), InputDWARFFile(File), - ClangModules(ClangModules), TargetTriple(TargetTriple), - UniqueUnitID(UniqueUnitID) { + /// Endianness for the final file. + support::endianness Endianess = support::endianness::little; + LinkContext(DWARFFile &File) : File(File) { if (File.Dwarf) { if (!File.Dwarf->compile_units().empty()) CompileUnits.reserve(File.Dwarf->getNumCompileUnits()); + + Endianess = File.Dwarf->isLittleEndian() ? support::endianness::little + : support::endianness::big; } } - /// Check whether specified \p CUDie is a Clang module reference. - /// if \p Quiet is false then display error messages. - /// \return first == true if CUDie is a Clang module reference. - /// second == true if module is already loaded. - std::pair isClangModuleRef(const DWARFDie &CUDie, - std::string &PCMFile, - unsigned Indent, bool Quiet); - - /// If this compile unit is really a skeleton CU that points to a - /// clang module, register it in ClangModules and return true. - /// - /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name - /// pointing to the module, and a DW_AT_gnu_dwo_id with the module - /// hash. - bool registerModuleReference(const DWARFDie &CUDie, ObjFileLoaderTy Loader, - CompileUnitHandlerTy OnCUDieLoaded, - unsigned Indent = 0); - - /// Recursively add the debug info in this clang module .pcm - /// file (and all the modules imported by it in a bottom-up fashion) - /// to ModuleUnits. - Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie, - const std::string &PCMFile, - CompileUnitHandlerTy OnCUDieLoaded, - unsigned Indent = 0); - /// Add Compile Unit corresponding to the module. void addModulesCompileUnit(RefModuleUnit &&Unit) { ModulesCompileUnits.emplace_back(std::move(Unit)); } - /// Computes the total size of the debug info. - uint64_t getInputDebugInfoSize() const { - uint64_t Size = 0; - - if (InputDWARFFile.Dwarf == nullptr) - return Size; - - for (auto &Unit : InputDWARFFile.Dwarf->compile_units()) - Size += Unit->getLength(); - - return Size; - } - - /// Link compile units for this context. - Error link(); - - /// Link specified compile unit until specified stage. - void linkSingleCompileUnit( - CompileUnit &CU, - enum CompileUnit::Stage DoUntilStage = CompileUnit::Stage::Cleaned); + /// Return Endiannes of the source DWARF information. + support::endianness getEndianness() { return Endianess; } - /// Emit invariant sections. - Error emitInvariantSections(); + /// \returns pointer to compilation unit which corresponds \p Offset. + CompileUnit *getUnitForOffset(CompileUnit &CU, uint64_t Offset) const; + }; - /// Clone and emit .debug_frame. - Error cloneAndEmitDebugFrame(); + /// linking options + struct DWARFLinkerOptions { + /// DWARF version for the output. + uint16_t TargetDWARFVersion = 0; - /// Emit FDE record. - void emitFDE(uint32_t CIEOffset, uint32_t AddrSize, uint64_t Address, - StringRef FDEBytes, SectionDescriptor &Section); + /// Generate processing log to the standard output. + bool Verbose = false; - /// Clone and emit paper trails. - Error cloneAndEmitPaperTrails(); + /// Print statistics. + bool Statistics = false; - std::function getUnitForOffset = - [&](uint64_t Offset) -> CompileUnit * { - auto CU = llvm::upper_bound( - CompileUnits, Offset, - [](uint64_t LHS, const std::unique_ptr &RHS) { - return LHS < RHS->getOrigUnit().getNextUnitOffset(); - }); + /// Verify the input DWARF. + bool VerifyInputDWARF = false; - return CU != CompileUnits.end() ? CU->get() : nullptr; - }; - }; + /// Do not unique types according to ODR + bool NoODR = false; - /// Enumerate all compile units and assign offsets to their sections and - /// strings. - void assignOffsets(); + /// Update index tables. + bool UpdateIndexTablesOnly = false; - /// Enumerate all compile units and assign offsets to their sections. - void assignOffsetsToSections(); + /// Whether we want a static variable to force us to keep its enclosing + /// function. + bool KeepFunctionForStatic = false; - /// Enumerate all compile units and assign offsets to their strings. - void assignOffsetsToStrings(); + /// Allow to generate valid, but non deterministic output. + bool AllowNonDeterministicOutput = false; - /// Enumerates specified string patches, assigns offset and index. - template - void assignOffsetsToStringsImpl( - ArrayList &Section, size_t &IndexAccumulator, - uint64_t &OffsetAccumulator, - StringEntryToDwarfStringPoolEntryMap &StringsForEmission); + /// Number of threads. + unsigned Threads = 1; - /// Print statistic for processed Debug Info. - void printStatistic(); + /// The accelerator table kinds + SmallVector AccelTables; - /// Enumerates sections for modules, invariant for object files, compile - /// units. - void forEachObjectSectionsSet( - function_ref SectionsSetHandler); + /// Prepend path for the clang modules. + std::string PrependPath; - /// Enumerates all patches and update them with the correct values. - void patchOffsetsAndSizes(); + /// input verification handler(it might be called asynchronously). + InputVerificationHandlerTy InputVerificationHandler = nullptr; - /// Emit debug sections common for all input files. - void emitCommonSections(); - - /// Cleanup data(string pools) after output sections are generated. - void cleanupDataAfterOutputSectionsAreGenerated(); - - /// Enumerate all compile units and put their data into the output stream. - void writeDWARFToTheOutput(); + /// A list of all .swiftinterface files referenced by the debug + /// info, mapping Module name to path on disk. The entries need to + /// be uniqued and sorted and there are only few entries expected + /// per compile unit, which is why this is a std::map. + /// this is dsymutil specific fag. + /// + /// (it might be called asynchronously). + SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr; - template - void emitStringsImpl(ArrayList &StringPatches, - const StringEntryToDwarfStringPoolEntryMap &Strings, - uint64_t &NextOffset, SectionDescriptor &OutSection); + /// A list of remappings to apply to file paths. + /// + /// (it might be called asynchronously). + ObjectPrefixMapTy *ObjectPrefixMap = nullptr; + } Options; /// \defgroup Data members accessed asinchroniously. /// /// @{ /// Unique ID for compile unit. - std::atomic UniqueUnitID; + std::atomic UniqueUnitID; + + /// Strings pool. Keeps all strings. + StringPool Strings; - /// Mapping the PCM filename to the DwoId. - StringMap ClangModules; - std::mutex ClangModulesMutex; + /// error handler(it might be called asynchronously). + MessageHandlerTy ErrorHandler = nullptr; + + /// warning handler(it might be called asynchronously). + MessageHandlerTy WarningHandler = nullptr; /// @} /// \defgroup Data members accessed sequentially. /// /// @{ - /// DwarfStringPoolEntries for .debug_str section. - StringEntryToDwarfStringPoolEntryMap DebugStrStrings; - /// DwarfStringPoolEntries for .debug_line_str section. - StringEntryToDwarfStringPoolEntryMap DebugLineStrStrings; + /// Set of strings which should be emitted. + StringTable OutputStrings; /// Keeps all linking contexts. SmallVector> ObjectContexts; - /// Common sections. - OutputSections CommonSections; - /// The emitter of final dwarf file. std::unique_ptr TheDwarfEmitter; - - /// Overall compile units number. - uint64_t OverallNumberOfCU = 0; - - /// Data global for the whole linking process. - LinkingGlobalData GlobalData; /// @} }; diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.cpp b/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.cpp deleted file mode 100644 index e16c237d1a43f..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.cpp +++ /dev/null @@ -1,130 +0,0 @@ -//===- DWARFLinkerUnit.cpp ------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "DWARFLinkerUnit.h" -#include "DWARFEmitterImpl.h" -#include "DebugLineSectionEmitter.h" - -namespace llvm { -namespace dwarflinker_parallel { - -void DwarfUnit::assignAbbrev(DIEAbbrev &Abbrev) { - // Check the set for priors. - FoldingSetNodeID ID; - Abbrev.Profile(ID); - void *InsertToken; - - DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken); - // If it's newly added. - if (InSet) { - // Assign existing abbreviation number. - Abbrev.setNumber(InSet->getNumber()); - } else { - // Add to abbreviation list. - Abbreviations.push_back( - std::make_unique(Abbrev.getTag(), Abbrev.hasChildren())); - for (const auto &Attr : Abbrev.getData()) - Abbreviations.back()->AddAttribute(Attr); - AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken); - // Assign the unique abbreviation number. - Abbrev.setNumber(Abbreviations.size()); - Abbreviations.back()->setNumber(Abbreviations.size()); - } -} - -Error DwarfUnit::emitAbbreviations() { - const std::vector> &Abbrevs = getAbbreviations(); - if (Abbrevs.empty()) - return Error::success(); - - SectionDescriptor &AbbrevSection = - getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev); - - // For each abbreviation. - for (const auto &Abbrev : Abbrevs) - emitDwarfAbbrevEntry(*Abbrev, AbbrevSection); - - // Mark end of abbreviations. - encodeULEB128(0, AbbrevSection.OS); - - return Error::success(); -} - -void DwarfUnit::emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev, - SectionDescriptor &AbbrevSection) { - // Emit the abbreviations code (base 1 index.) - encodeULEB128(Abbrev.getNumber(), AbbrevSection.OS); - - // Emit the abbreviations data. - // Emit its Dwarf tag type. - encodeULEB128(Abbrev.getTag(), AbbrevSection.OS); - - // Emit whether it has children DIEs. - encodeULEB128((unsigned)Abbrev.hasChildren(), AbbrevSection.OS); - - // For each attribute description. - const SmallVectorImpl &Data = Abbrev.getData(); - for (unsigned i = 0, N = Data.size(); i < N; ++i) { - const DIEAbbrevData &AttrData = Data[i]; - - // Emit attribute type. - encodeULEB128(AttrData.getAttribute(), AbbrevSection.OS); - - // Emit form type. - encodeULEB128(AttrData.getForm(), AbbrevSection.OS); - - // Emit value for DW_FORM_implicit_const. - if (AttrData.getForm() == dwarf::DW_FORM_implicit_const) - encodeSLEB128(AttrData.getValue(), AbbrevSection.OS); - } - - // Mark end of abbreviation. - encodeULEB128(0, AbbrevSection.OS); - encodeULEB128(0, AbbrevSection.OS); -} - -Error DwarfUnit::emitDebugInfo(Triple &TargetTriple) { - DIE *OutUnitDIE = getOutUnitDIE(); - if (OutUnitDIE == nullptr) - return Error::success(); - - // FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs - // directly. - - SectionDescriptor &OutSection = - getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); - DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, OutSection.OS); - if (Error Err = Emitter.init(TargetTriple, "__DWARF")) - return Err; - - // Emit compile unit header. - Emitter.emitCompileUnitHeader(*this); - size_t OffsetToAbbreviationTableOffset = - (getFormParams().Version >= 5) ? 8 : 6; - OutSection.notePatch(DebugOffsetPatch{ - OffsetToAbbreviationTableOffset, - &getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev)}); - - // Emit DIEs. - Emitter.emitDIE(*OutUnitDIE); - Emitter.finish(); - - // Set start offset ans size for .debug_info section. - OutSection.setSizesForSectionCreatedByAsmPrinter(); - return Error::success(); -} - -Error DwarfUnit::emitDebugLine(Triple &TargetTriple, - const DWARFDebugLine::LineTable &OutLineTable) { - DebugLineSectionEmitter DebugLineEmitter(TargetTriple, *this); - - return DebugLineEmitter.emit(OutLineTable); -} - -} // end of namespace dwarflinker_parallel -} // end of namespace llvm diff --git a/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.h b/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.h index 50aa6957b3dc2..78e8d82ea0615 100644 --- a/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.h +++ b/llvm/lib/DWARFLinkerParallel/DWARFLinkerUnit.h @@ -9,11 +9,9 @@ #ifndef LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERUNIT_H #define LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERUNIT_H -#include "DWARFLinkerGlobalData.h" #include "OutputSections.h" #include "llvm/ADT/SmallString.h" #include "llvm/CodeGen/DIE.h" -#include "llvm/DWARFLinkerParallel/DWARFLinker.h" #include "llvm/DWARFLinkerParallel/StringPool.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" #include "llvm/Support/LEB128.h" @@ -21,17 +19,44 @@ namespace llvm { namespace dwarflinker_parallel { -class DwarfUnit; -using MacroOffset2UnitMapTy = DenseMap; +using UnitMessageHandlerTy = function_ref; + +/// Each unit keeps output data as a file with debug tables +/// corresponding to the concrete unit. +using OutTablesFileTy = SmallString<0>; /// Base class for all Dwarf units(Compile unit/Type table unit). class DwarfUnit : public OutputSections { public: virtual ~DwarfUnit() {} - DwarfUnit(LinkingGlobalData &GlobalData, unsigned ID, - StringRef ClangModuleName) - : OutputSections(GlobalData), ID(ID), ClangModuleName(ClangModuleName), - OutUnitDIE(nullptr) {} + DwarfUnit(unsigned ID, StringRef ClangModuleName, + UnitMessageHandlerTy WarningHandler) + : ID(ID), ClangModuleName(ClangModuleName), + WarningHandler(WarningHandler) { + FormParams.Version = 4; + FormParams.Format = dwarf::DWARF32; + FormParams.AddrSize = 4; + } + + /// Endiannes for the compile unit. + support::endianness getEndianness() const { return Endianess; } + + /// Return DWARF version. + uint16_t getVersion() const { return FormParams.Version; } + + /// Return size of header of debug_info table. + uint16_t getHeaderSize() const { return FormParams.Version >= 5 ? 12 : 11; } + + /// Return size of address. + uint8_t getAddressByteSize() const { return FormParams.AddrSize; } + + /// Return size of reference. + uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); } + + /// Return format of the Dwarf(DWARF32 or DWARF64). + /// TODO: DWARF64 is not currently supported. + dwarf::DwarfFormat getDwarfFormat() const { return FormParams.Format; } /// Unique id of the unit. unsigned getUniqueID() const { return ID; } @@ -51,48 +76,41 @@ class DwarfUnit : public OutputSections { /// Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef. StringRef getSysRoot() { return SysRoot; } + /// Create a Die for this unit. + void setOutputDIE(DIE *UnitDie) { NewUnit = UnitDie; } + + /// Return Die for this compile unit. + DIE *getOutputUnitDIE() const { return NewUnit; } + /// Return true if this compile unit is from Clang module. bool isClangModule() const { return !ClangModuleName.empty(); } /// Return Clang module name; const std::string &getClangModuleName() const { return ClangModuleName; } - /// Return global data. - LinkingGlobalData &getGlobalData() { return GlobalData; } - - /// Returns true if unit is inter-connected(it references/referenced by other - /// unit). - bool isInterconnectedCU() const { return IsInterconnectedCU; } - - /// Mark this unit as inter-connected(it references/referenced by other unit). - void setInterconnectedCU() { IsInterconnectedCU = true; } - - /// Adds \p Abbrev into unit`s abbreviation table. - void assignAbbrev(DIEAbbrev &Abbrev); - - /// Returns abbreviations for this compile unit. - const std::vector> &getAbbreviations() const { - return Abbreviations; - } + /// Returns generated file keeping debug tables for this compile unit. + OutTablesFileTy &getOutDwarfBits() { return OutDebugInfoBits; } - /// Returns output unit DIE. - DIE *getOutUnitDIE() { return OutUnitDIE; } + /// Erases generated file keeping debug tables for this compile unit. + void eraseDwarfBits() { OutDebugInfoBits = OutTablesFileTy(); } - /// Set output unit DIE. - void setOutUnitDIE(DIE *UnitDie) { OutUnitDIE = UnitDie; } + MCSymbol *getLabelBegin() { return LabelBegin; } + void setLabelBegin(MCSymbol *S) { LabelBegin = S; } - /// \defgroup Methods used to emit unit's debug info: - /// + /// Error reporting methods. /// @{ - /// Emit unit's abbreviations. - Error emitAbbreviations(); - /// Emit .debug_info section for unit DIEs. - Error emitDebugInfo(Triple &TargetTriple); - - /// Emit .debug_line section. - Error emitDebugLine(Triple &TargetTriple, - const DWARFDebugLine::LineTable &OutLineTable); + void reportWarning(const Twine &Warning, + const DWARFDie *Die = nullptr) const { + if (WarningHandler) + WarningHandler(Warning, getUnitName(), Die); + } + void reportWarning(Error Warning) const { + handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) { + if (WarningHandler) + WarningHandler(Info.message(), getUnitName(), nullptr); + }); + } /// @} /// This structure keeps fields which would be used for creating accelerator @@ -124,22 +142,16 @@ class DwarfUnit : public OutputSections { const DIE *Die = nullptr; }; - /// \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()); } - /// @} - protected: - /// Emit single abbreviation entry. - void emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev, - SectionDescriptor &AbbrevSection); - /// Unique ID for the unit. unsigned ID = 0; + /// Properties of the unit. + dwarf::FormParams FormParams; + + /// DIE for newly generated compile unit. + DIE *NewUnit = nullptr; + /// The DW_AT_language of this unit. uint16_t Language = 0; @@ -154,17 +166,18 @@ class DwarfUnit : public OutputSections { uint64_t UnitSize = 0; - /// true if current unit references_to/is_referenced by other unit. - std::atomic IsInterconnectedCU = {false}; + /// Elf file containg generated debug tables for this compile unit. + OutTablesFileTy OutDebugInfoBits; - /// FoldingSet that uniques the abbreviations. - FoldingSet AbbreviationsSet; + /// Endiannes for this compile unit. + support::endianness Endianess = support::endianness::little; - /// Storage for the unique Abbreviations. - std::vector> Abbreviations; + MCSymbol *LabelBegin = nullptr; + + /// true if current unit references_to/is_referenced by other unit. + std::atomic IsInterconnectedCU = {false}; - /// Output unit DIE. - DIE *OutUnitDIE = nullptr; + UnitMessageHandlerTy WarningHandler; }; } // end of namespace dwarflinker_parallel diff --git a/llvm/lib/DWARFLinkerParallel/DebugLineSectionEmitter.h b/llvm/lib/DWARFLinkerParallel/DebugLineSectionEmitter.h deleted file mode 100644 index f1fcd91753900..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DebugLineSectionEmitter.h +++ /dev/null @@ -1,384 +0,0 @@ -//===- DebugLineSectionEmitter.h --------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_DWARFLINKERPARALLEL_DEBUGLINESECTIONEMITTER_H -#define LLVM_LIB_DWARFLINKERPARALLEL_DEBUGLINESECTIONEMITTER_H - -#include "DWARFEmitterImpl.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/DWARFLinkerParallel/AddressesMap.h" -#include "llvm/DWARFLinkerParallel/DWARFLinker.h" -#include "llvm/DebugInfo/DWARF/DWARFObject.h" -#include "llvm/MC/MCTargetOptionsCommandFlags.h" -#include "llvm/MC/TargetRegistry.h" - -namespace llvm { -namespace dwarflinker_parallel { - -/// This class emits specified line table into the .debug_line section. -class DebugLineSectionEmitter { -public: - DebugLineSectionEmitter(const Triple &TheTriple, DwarfUnit &U) - : TheTriple(TheTriple), U(U) {} - - Error emit(const DWARFDebugLine::LineTable &LineTable) { - // FIXME: remove dependence on MCDwarfLineAddr::encode. - // As we reuse MCDwarfLineAddr::encode, we need to create/initialize - // some MC* classes. - if (Error Err = init(TheTriple)) - return Err; - - // Get descriptor for output .debug_line section. - SectionDescriptor &OutSection = - U.getOrCreateSectionDescriptor(DebugSectionKind::DebugLine); - - // unit_length. - OutSection.emitUnitLength(0xBADDEF); - uint64_t OffsetAfterUnitLength = OutSection.OS.tell(); - - // Emit prologue. - emitLineTablePrologue(LineTable.Prologue, OutSection); - - // Emit rows. - emitLineTableRows(LineTable, OutSection); - uint64_t OffsetAfterEnd = OutSection.OS.tell(); - - // Update unit length field with actual length value. - assert(OffsetAfterUnitLength - - OutSection.getFormParams().getDwarfOffsetByteSize() < - OffsetAfterUnitLength); - OutSection.apply(OffsetAfterUnitLength - - OutSection.getFormParams().getDwarfOffsetByteSize(), - dwarf::DW_FORM_sec_offset, - OffsetAfterEnd - OffsetAfterUnitLength); - - return Error::success(); - } - -private: - Error init(Triple TheTriple) { - std::string ErrorStr; - std::string TripleName; - - // Get the target. - const Target *TheTarget = - TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); - if (!TheTarget) - return createStringError(std::errc::invalid_argument, ErrorStr.c_str()); - TripleName = TheTriple.getTriple(); - - // Create all the MC Objects. - MRI.reset(TheTarget->createMCRegInfo(TripleName)); - if (!MRI) - return createStringError(std::errc::invalid_argument, - "no register info for target %s", - TripleName.c_str()); - - MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags(); - MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); - if (!MAI) - return createStringError(std::errc::invalid_argument, - "no asm info for target %s", TripleName.c_str()); - - MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); - if (!MSTI) - return createStringError(std::errc::invalid_argument, - "no subtarget info for target %s", - TripleName.c_str()); - - MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr, - nullptr, true, "__DWARF")); - - return Error::success(); - } - - void emitLineTablePrologue(const DWARFDebugLine::Prologue &P, - SectionDescriptor &Section) { - // version (uhalf). - Section.emitIntVal(P.getVersion(), 2); - if (P.getVersion() == 5) { - // address_size (ubyte). - Section.emitIntVal(P.getAddressSize(), 1); - - // segment_selector_size (ubyte). - Section.emitIntVal(P.SegSelectorSize, 1); - } - - // header_length. - Section.emitOffset(0xBADDEF); - - uint64_t OffsetAfterPrologueLength = Section.OS.tell(); - emitLineTableProloguePayload(P, Section); - uint64_t OffsetAfterPrologueEnd = Section.OS.tell(); - - // Update prologue length field with actual length value. - Section.apply(OffsetAfterPrologueLength - - Section.getFormParams().getDwarfOffsetByteSize(), - dwarf::DW_FORM_sec_offset, - OffsetAfterPrologueEnd - OffsetAfterPrologueLength); - } - - void - emitLineTablePrologueV2IncludeAndFileTable(const DWARFDebugLine::Prologue &P, - SectionDescriptor &Section) { - // include_directories (sequence of path names). - for (const DWARFFormValue &Include : P.IncludeDirectories) { - std::optional IncludeStr = dwarf::toString(Include); - if (!IncludeStr) { - U.warn("cann't read string from line table."); - return; - } - - Section.emitString(Include.getForm(), *IncludeStr); - } - // The last entry is followed by a single null byte. - Section.emitIntVal(0, 1); - - // file_names (sequence of file entries). - for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) { - std::optional FileNameStr = dwarf::toString(File.Name); - if (!FileNameStr) { - U.warn("cann't read string from line table."); - return; - } - - // A null-terminated string containing the full or relative path name of a - // source file. - Section.emitString(File.Name.getForm(), *FileNameStr); - // An unsigned LEB128 number representing the directory index of a - // directory in the include_directories section. - encodeULEB128(File.DirIdx, Section.OS); - // An unsigned LEB128 number representing the (implementation-defined) - // time of last modification for the file, or 0 if not available. - encodeULEB128(File.ModTime, Section.OS); - // An unsigned LEB128 number representing the length in bytes of the file, - // or 0 if not available. - encodeULEB128(File.Length, Section.OS); - } - // The last entry is followed by a single null byte. - Section.emitIntVal(0, 1); - } - - void - emitLineTablePrologueV5IncludeAndFileTable(const DWARFDebugLine::Prologue &P, - SectionDescriptor &Section) { - if (P.IncludeDirectories.empty()) { - // directory_entry_format_count(ubyte). - Section.emitIntVal(0, 1); - } else { - // directory_entry_format_count(ubyte). - Section.emitIntVal(1, 1); - - // directory_entry_format (sequence of ULEB128 pairs). - encodeULEB128(dwarf::DW_LNCT_path, Section.OS); - encodeULEB128(P.IncludeDirectories[0].getForm(), Section.OS); - } - - // directories_count (ULEB128). - encodeULEB128(P.IncludeDirectories.size(), Section.OS); - // directories (sequence of directory names). - for (auto Include : P.IncludeDirectories) { - std::optional IncludeStr = dwarf::toString(Include); - if (!IncludeStr) { - U.warn("cann't read string from line table."); - return; - } - - Section.emitString(Include.getForm(), *IncludeStr); - } - - if (P.FileNames.empty()) { - // file_name_entry_format_count (ubyte). - Section.emitIntVal(0, 1); - } else { - // file_name_entry_format_count (ubyte). - Section.emitIntVal(2, 1); - - // file_name_entry_format (sequence of ULEB128 pairs). - encodeULEB128(dwarf::DW_LNCT_path, Section.OS); - encodeULEB128(P.FileNames[0].Name.getForm(), Section.OS); - - encodeULEB128(dwarf::DW_LNCT_directory_index, Section.OS); - encodeULEB128(dwarf::DW_FORM_data1, Section.OS); - } - - // file_names_count (ULEB128). - encodeULEB128(P.FileNames.size(), Section.OS); - - // file_names (sequence of file name entries). - for (auto File : P.FileNames) { - std::optional FileNameStr = dwarf::toString(File.Name); - if (!FileNameStr) { - U.warn("cann't read string from line table."); - return; - } - - // A null-terminated string containing the full or relative path name of a - // source file. - Section.emitString(File.Name.getForm(), *FileNameStr); - Section.emitIntVal(File.DirIdx, 1); - } - } - - void emitLineTableProloguePayload(const DWARFDebugLine::Prologue &P, - SectionDescriptor &Section) { - // minimum_instruction_length (ubyte). - Section.emitIntVal(P.MinInstLength, 1); - if (P.FormParams.Version >= 4) { - // maximum_operations_per_instruction (ubyte). - Section.emitIntVal(P.MaxOpsPerInst, 1); - } - // default_is_stmt (ubyte). - Section.emitIntVal(P.DefaultIsStmt, 1); - // line_base (sbyte). - Section.emitIntVal(P.LineBase, 1); - // line_range (ubyte). - Section.emitIntVal(P.LineRange, 1); - // opcode_base (ubyte). - Section.emitIntVal(P.OpcodeBase, 1); - - // standard_opcode_lengths (array of ubyte). - for (auto Length : P.StandardOpcodeLengths) - Section.emitIntVal(Length, 1); - - if (P.FormParams.Version < 5) - emitLineTablePrologueV2IncludeAndFileTable(P, Section); - else - emitLineTablePrologueV5IncludeAndFileTable(P, Section); - } - - void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable, - SectionDescriptor &Section) { - - MCDwarfLineTableParams Params; - Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase; - Params.DWARF2LineBase = LineTable.Prologue.LineBase; - Params.DWARF2LineRange = LineTable.Prologue.LineRange; - - SmallString<128> EncodingBuffer; - - if (LineTable.Rows.empty()) { - // We only have the dummy entry, dsymutil emits an entry with a 0 - // address in that case. - MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits::max(), - 0, EncodingBuffer); - Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size()); - return; - } - - // Line table state machine fields - unsigned FileNum = 1; - unsigned LastLine = 1; - unsigned Column = 0; - unsigned IsStatement = 1; - unsigned Isa = 0; - uint64_t Address = -1ULL; - - unsigned RowsSinceLastSequence = 0; - - for (const DWARFDebugLine::Row &Row : LineTable.Rows) { - int64_t AddressDelta; - if (Address == -1ULL) { - Section.emitIntVal(dwarf::DW_LNS_extended_op, 1); - encodeULEB128(Section.getFormParams().AddrSize + 1, Section.OS); - Section.emitIntVal(dwarf::DW_LNE_set_address, 1); - Section.emitIntVal(Row.Address.Address, - Section.getFormParams().AddrSize); - AddressDelta = 0; - } else { - AddressDelta = - (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength; - } - - // FIXME: code copied and transformed from - // MCDwarf.cpp::EmitDwarfLineTable. We should find a way to share this - // code, but the current compatibility requirement with classic dsymutil - // makes it hard. Revisit that once this requirement is dropped. - - if (FileNum != Row.File) { - FileNum = Row.File; - Section.emitIntVal(dwarf::DW_LNS_set_file, 1); - encodeULEB128(FileNum, Section.OS); - } - if (Column != Row.Column) { - Column = Row.Column; - Section.emitIntVal(dwarf::DW_LNS_set_column, 1); - encodeULEB128(Column, Section.OS); - } - - // FIXME: We should handle the discriminator here, but dsymutil doesn't - // consider it, thus ignore it for now. - - if (Isa != Row.Isa) { - Isa = Row.Isa; - Section.emitIntVal(dwarf::DW_LNS_set_isa, 1); - encodeULEB128(Isa, Section.OS); - } - if (IsStatement != Row.IsStmt) { - IsStatement = Row.IsStmt; - Section.emitIntVal(dwarf::DW_LNS_negate_stmt, 1); - } - if (Row.BasicBlock) - Section.emitIntVal(dwarf::DW_LNS_set_basic_block, 1); - - if (Row.PrologueEnd) - Section.emitIntVal(dwarf::DW_LNS_set_prologue_end, 1); - - if (Row.EpilogueBegin) - Section.emitIntVal(dwarf::DW_LNS_set_epilogue_begin, 1); - - int64_t LineDelta = int64_t(Row.Line) - LastLine; - if (!Row.EndSequence) { - MCDwarfLineAddr::encode(*MC, Params, LineDelta, AddressDelta, - EncodingBuffer); - Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size()); - EncodingBuffer.resize(0); - Address = Row.Address.Address; - LastLine = Row.Line; - RowsSinceLastSequence++; - } else { - if (LineDelta) { - Section.emitIntVal(dwarf::DW_LNS_advance_line, 1); - encodeSLEB128(LineDelta, Section.OS); - } - if (AddressDelta) { - Section.emitIntVal(dwarf::DW_LNS_advance_pc, 1); - encodeULEB128(AddressDelta, Section.OS); - } - MCDwarfLineAddr::encode(*MC, Params, - std::numeric_limits::max(), 0, - EncodingBuffer); - Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size()); - EncodingBuffer.resize(0); - Address = -1ULL; - LastLine = FileNum = IsStatement = 1; - RowsSinceLastSequence = Column = Isa = 0; - } - } - - if (RowsSinceLastSequence) { - MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits::max(), - 0, EncodingBuffer); - Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size()); - EncodingBuffer.resize(0); - } - } - - Triple TheTriple; - DwarfUnit &U; - - std::unique_ptr MRI; - std::unique_ptr MAI; - std::unique_ptr MC; - std::unique_ptr MSTI; -}; - -} // end of namespace dwarflinker_parallel -} // end namespace llvm - -#endif // LLVM_LIB_DWARFLINKERPARALLEL_DEBUGLINESECTIONEMITTER_H diff --git a/llvm/lib/DWARFLinkerParallel/DependencyTracker.cpp b/llvm/lib/DWARFLinkerParallel/DependencyTracker.cpp deleted file mode 100644 index 4bf353afbe42b..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DependencyTracker.cpp +++ /dev/null @@ -1,428 +0,0 @@ -//=== DependencyTracker.cpp -----------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "DependencyTracker.h" -#include "llvm/Support/FormatVariadic.h" - -namespace llvm { -namespace dwarflinker_parallel { - -#ifndef NDEBUG -/// A broken link in the keep chain. By recording both the parent and the child -/// we can show only broken links for DIEs with multiple children. -struct BrokenLink { - BrokenLink(DWARFDie Parent, DWARFDie Child) : Parent(Parent), Child(Child) {} - DWARFDie Parent; - DWARFDie Child; -}; - -/// Verify the keep chain by looking for DIEs that are kept but who's parent -/// isn't. -void DependencyTracker::verifyKeepChain(CompileUnit &CU) { - SmallVector Worklist; - Worklist.push_back(CU.getOrigUnit().getUnitDIE()); - - // List of broken links. - SmallVector BrokenLinks; - - while (!Worklist.empty()) { - const DWARFDie Current = Worklist.back(); - Worklist.pop_back(); - - if (!Current.isValid()) - continue; - - const bool CurrentDieIsKept = CU.getDIEInfo(Current).getKeep() || - CU.getDIEInfo(Current).getKeepChildren(); - - for (DWARFDie Child : reverse(Current.children())) { - Worklist.push_back(Child); - - const bool ChildDieIsKept = CU.getDIEInfo(Child).getKeep() || - CU.getDIEInfo(Child).getKeepChildren(); - if (!CurrentDieIsKept && ChildDieIsKept) - BrokenLinks.emplace_back(Current, Child); - } - } - - if (!BrokenLinks.empty()) { - for (BrokenLink Link : BrokenLinks) { - WithColor::error() << formatv( - "Found invalid link in keep chain between {0:x} and {1:x}\n", - Link.Parent.getOffset(), Link.Child.getOffset()); - - errs() << "Parent:"; - Link.Parent.dump(errs(), 0, {}); - CU.getDIEInfo(Link.Parent).dump(); - - errs() << "Child:"; - Link.Child.dump(errs(), 2, {}); - CU.getDIEInfo(Link.Child).dump(); - } - report_fatal_error("invalid keep chain"); - } -} -#endif - -bool DependencyTracker::resolveDependenciesAndMarkLiveness(CompileUnit &CU) { - // We do not track liveness inside Clang modules. We also do not track - // liveness if UpdateIndexTablesOnly is requested. - TrackLiveness = !(CU.isClangModule() || - CU.getGlobalData().getOptions().UpdateIndexTablesOnly); - RootEntriesWorkList.clear(); - - // Search for live root DIEs. - collectRootsToKeep(CU, CU.getDebugInfoEntry(0)); - - // Mark live DIEs as kept. - return markLiveRootsAsKept(); -} - -void DependencyTracker::collectRootsToKeep(CompileUnit &CU, - const DWARFDebugInfoEntry *Entry) { - if (!TrackLiveness) { - addItemToWorklist(CU, Entry); - return; - } - - switch (Entry->getTag()) { - case dwarf::DW_TAG_subprogram: - case dwarf::DW_TAG_label: - if (isLiveSubprogramEntry(CU, Entry)) { - addItemToWorklist(CU, Entry); - break; - } - [[fallthrough]]; - case dwarf::DW_TAG_compile_unit: - case dwarf::DW_TAG_namespace: - case dwarf::DW_TAG_module: - case dwarf::DW_TAG_lexical_block: { - for (const DWARFDebugInfoEntry *CurChild = CU.getFirstChildEntry(Entry); - CurChild && CurChild->getAbbreviationDeclarationPtr(); - CurChild = CU.getSiblingEntry(CurChild)) - collectRootsToKeep(CU, CurChild); - } break; - case dwarf::DW_TAG_constant: - case dwarf::DW_TAG_variable: { - if (isLiveVariableEntry(CU, Entry)) - addItemToWorklist(CU, Entry); - } break; - case dwarf::DW_TAG_base_type: { - addItemToWorklist(CU, Entry); - } break; - case dwarf::DW_TAG_imported_module: - case dwarf::DW_TAG_imported_declaration: - case dwarf::DW_TAG_imported_unit: { - addItemToWorklist(CU, Entry); - } break; - default: - // Nothing to do. - break; - } -} - -bool DependencyTracker::markLiveRootsAsKept() { - bool Res = true; - - while (!RootEntriesWorkList.empty()) { - RootEntryTy CurrentItem = RootEntriesWorkList.pop_back_val(); - - if (!markDIEEntryAsKeptRec(CurrentItem, CurrentItem.CU, - CurrentItem.RootEntry)) - Res = false; - } - - return Res; -} - -bool DependencyTracker::markDIEEntryAsKeptRec( - const RootEntryTy &RootItem, CompileUnit &CU, - const DWARFDebugInfoEntry *Entry) { - if (Entry->getAbbreviationDeclarationPtr() == nullptr) - return true; - - CompileUnit::DIEInfo &Info = CU.getDIEInfo(Entry); - - if (Info.getKeep()) - return true; - - // Mark parents as 'KeepChildren'. - std::optional ParentIdx = Entry->getParentIdx(); - while (ParentIdx) { - const DWARFDebugInfoEntry *ParentEntry = CU.getDebugInfoEntry(*ParentIdx); - CompileUnit::DIEInfo &ParentInfo = CU.getDIEInfo(*ParentIdx); - if (ParentInfo.getKeepChildren()) - break; - ParentInfo.setKeepChildren(); - ParentIdx = ParentEntry->getParentIdx(); - } - - // Mark current DIE as kept. - Info.setKeep(); - setDIEPlacementAndTypename(Info); - - // Set liveness information. - switch (Entry->getTag()) { - case dwarf::DW_TAG_constant: - case dwarf::DW_TAG_variable: { - isLiveVariableEntry(CU, Entry); - } break; - case dwarf::DW_TAG_subprogram: - case dwarf::DW_TAG_label: { - isLiveSubprogramEntry(CU, Entry); - } break; - default: - // Nothing to do. - break; - } - - // Analyse referenced DIEs. - bool Res = true; - if (!maybeAddReferencedRoots(RootItem, CU, Entry)) - Res = false; - - // Navigate children. - for (const DWARFDebugInfoEntry *CurChild = CU.getFirstChildEntry(Entry); - CurChild && CurChild->getAbbreviationDeclarationPtr(); - CurChild = CU.getSiblingEntry(CurChild)) { - if (!markDIEEntryAsKeptRec(RootItem, CU, CurChild)) - Res = false; - } - - return Res; -} - -bool DependencyTracker::maybeAddReferencedRoots( - const RootEntryTy &RootItem, CompileUnit &CU, - const DWARFDebugInfoEntry *Entry) { - const auto *Abbrev = Entry->getAbbreviationDeclarationPtr(); - if (Abbrev == nullptr) - return true; - - DWARFUnit &Unit = CU.getOrigUnit(); - DWARFDataExtractor Data = Unit.getDebugInfoExtractor(); - uint64_t Offset = Entry->getOffset() + getULEB128Size(Abbrev->getCode()); - - // For each DIE attribute... - for (const auto &AttrSpec : Abbrev->attributes()) { - DWARFFormValue Val(AttrSpec.Form); - if (!Val.isFormClass(DWARFFormValue::FC_Reference) || - AttrSpec.Attr == dwarf::DW_AT_sibling) { - DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, - Unit.getFormParams()); - continue; - } - Val.extractValue(Data, &Offset, Unit.getFormParams(), &Unit); - - // Resolve reference. - std::optional> RefDie = - CU.resolveDIEReference(Val); - 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 { - // Delay resolving reference. - RefDie->first->setInterconnectedCU(); - CU.setInterconnectedCU(); - Context.HasNewInterconnectedCUs = true; - return false; - } - } - - return true; -} - -// Returns true if the specified DIE type allows removing children. -static bool childrenCanBeRemoved(uint32_t Tag) { - switch (Tag) { - default: - return true; - case dwarf::DW_TAG_class_type: - case dwarf::DW_TAG_common_block: - case dwarf::DW_TAG_lexical_block: - case dwarf::DW_TAG_structure_type: - case dwarf::DW_TAG_subprogram: - case dwarf::DW_TAG_subroutine_type: - case dwarf::DW_TAG_union_type: - case dwarf::DW_TAG_array_type: - return false; - } - llvm_unreachable("Invalid Tag"); -} - -void DependencyTracker::addItemToWorklist(CompileUnit &CU, - const DWARFDebugInfoEntry *Entry) { - if (Entry->getAbbreviationDeclarationPtr() == nullptr) - return; - - const DWARFDebugInfoEntry *EntryToAdd = Entry; - - // If parent does not allow children removing then use that parent as a root - // DIE. - std::optional ParentIdx = Entry->getParentIdx(); - while (ParentIdx) { - const DWARFDebugInfoEntry *ParentEntry = CU.getDebugInfoEntry(*ParentIdx); - if (childrenCanBeRemoved(ParentEntry->getTag())) - break; - EntryToAdd = ParentEntry; - ParentIdx = ParentEntry->getParentIdx(); - } - - // Check if the DIE entry is already kept. - if (CU.getDIEInfo(EntryToAdd).getKeep()) - return; - - RootEntriesWorkList.emplace_back(CU, EntryToAdd); -} - -bool DependencyTracker::isLiveVariableEntry(CompileUnit &CU, - const DWARFDebugInfoEntry *Entry) { - DWARFDie DIE = CU.getDIE(Entry); - CompileUnit::DIEInfo &Info = CU.getDIEInfo(DIE); - - if (TrackLiveness) { - const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); - - // Global variables with constant value can always be kept. - if (!Info.getIsInFunctionScope() && - Abbrev->findAttributeIndex(dwarf::DW_AT_const_value)) - return true; - - // See if there is a relocation to a valid debug map entry inside this - // variable's location. The order is important here. We want to always check - // if the variable has a location expression address. - // However, we don't want a static variable in a function to force us to - // keep the enclosing function, unless requested explicitly. - std::pair> LocExprAddrAndRelocAdjustment = - CU.getContaingFile().Addresses->getVariableRelocAdjustment(DIE); - - if (!LocExprAddrAndRelocAdjustment.second) - return false; - - if ((Info.getIsInFunctionScope()) && - !LLVM_UNLIKELY(CU.getGlobalData().getOptions().KeepFunctionForStatic)) - return false; - } - - if (CU.getGlobalData().getOptions().Verbose) { - outs() << "Keeping variable DIE:"; - DIDumpOptions DumpOpts; - DumpOpts.ChildRecurseDepth = 0; - DumpOpts.Verbose = CU.getGlobalData().getOptions().Verbose; - DIE.dump(outs(), 8 /* Indent */, DumpOpts); - } - - return true; -} - -bool DependencyTracker::isLiveSubprogramEntry( - CompileUnit &CU, const DWARFDebugInfoEntry *Entry) { - DWARFDie DIE = CU.getDIE(Entry); - - std::optional LowPc; - std::optional HighPc; - std::optional RelocAdjustment; - - if (TrackLiveness) { - LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc)); - if (!LowPc) - return false; - - RelocAdjustment = - CU.getContaingFile().Addresses->getSubprogramRelocAdjustment(DIE); - if (!RelocAdjustment) - return false; - - if (DIE.getTag() == dwarf::DW_TAG_subprogram) { - // Validate subprogram address range. - - HighPc = DIE.getHighPC(*LowPc); - if (!HighPc) { - CU.warn("function without high_pc. Range will be discarded.", &DIE); - return false; - } - - if (*LowPc > *HighPc) { - CU.warn("low_pc greater than high_pc. Range will be discarded.", &DIE); - return false; - } - } else if (DIE.getTag() == dwarf::DW_TAG_variable) { - if (CU.hasLabelAt(*LowPc)) - return false; - - // FIXME: dsymutil-classic compat. dsymutil-classic doesn't consider - // labels that don't fall into the CU's aranges. This is wrong IMO. Debug - // info generation bugs aside, this is really wrong in the case of labels, - // where a label marking the end of a function will have a PC == CU's - // high_pc. - if (dwarf::toAddress( - CU.getOrigUnit().getUnitDIE().find(dwarf::DW_AT_high_pc)) - .value_or(UINT64_MAX) <= LowPc) - return false; - - CU.addLabelLowPc(*LowPc, *RelocAdjustment); - } - } - - if (CU.getGlobalData().getOptions().Verbose) { - outs() << "Keeping subprogram DIE:"; - DIDumpOptions DumpOpts; - DumpOpts.ChildRecurseDepth = 0; - DumpOpts.Verbose = CU.getGlobalData().getOptions().Verbose; - DIE.dump(outs(), 8 /* Indent */, DumpOpts); - } - - if (!TrackLiveness || DIE.getTag() == dwarf::DW_TAG_label) - return true; - - CU.addFunctionRange(*LowPc, *HighPc, *RelocAdjustment); - return true; -} - -void DependencyTracker::setDIEPlacementAndTypename(CompileUnit::DIEInfo &Info) { - Info.setPlacement(CompileUnit::PlainDwarf); -} - -} // end of namespace dwarflinker_parallel -} // namespace llvm diff --git a/llvm/lib/DWARFLinkerParallel/DependencyTracker.h b/llvm/lib/DWARFLinkerParallel/DependencyTracker.h deleted file mode 100644 index 69e57bc3ea4d2..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/DependencyTracker.h +++ /dev/null @@ -1,102 +0,0 @@ -//===- "DependencyTracker.h" ------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_DWARFLINKERPARALLEL_DEPENDENCYTRACKER_H -#define LLVM_LIB_DWARFLINKERPARALLEL_DEPENDENCYTRACKER_H - -#include "DWARFLinkerCompileUnit.h" -#include "DWARFLinkerImpl.h" -#include "llvm/ADT/SmallVector.h" - -namespace llvm { -class DWARFDebugInfoEntry; -class DWARFDie; - -namespace dwarflinker_parallel { - -/// This class discovers DIEs dependencies and marks "live" DIEs. -class DependencyTracker { -public: - DependencyTracker(DWARFLinkerImpl::LinkContext &Context) : Context(Context) {} - - /// Recursively walk the \p DIE tree and look for DIEs to keep. Store that - /// information in \p CU's DIEInfo. - /// - /// This function is the entry point of the DIE selection algorithm. It is - /// expected to walk the DIE tree and(through the mediation of - /// Context.File.Addresses) ask for relocation adjustment value on each - /// DIE that might be a 'root DIE'. - /// - /// Returns true if all dependencies are correctly discovered. Inter-CU - /// dependencies cannot be discovered if referenced CU is not analyzed yet. - /// If that is the case this method returns false. - bool resolveDependenciesAndMarkLiveness(CompileUnit &CU); - - /// Recursively walk the \p DIE tree and check "keepness" information. - /// It is an error if parent node does not have "keep" flag, while - /// child have one. This function dump error at stderr in that case. -#ifndef NDEBUG - static void verifyKeepChain(CompileUnit &CU); -#endif - -protected: - struct RootEntryTy { - RootEntryTy(CompileUnit &CU, const DWARFDebugInfoEntry *RootEntry) - : CU(CU), RootEntry(RootEntry) {} - - // Compile unit keeping root entry. - CompileUnit &CU; - - // Root entry. - const DWARFDebugInfoEntry *RootEntry; - }; - - using RootEntriesListTy = SmallVector; - - /// This function navigates DIEs tree starting from specified \p Entry. - /// It puts 'root DIE' into the worklist. - void collectRootsToKeep(CompileUnit &CU, const DWARFDebugInfoEntry *Entry); - - /// Returns true if specified variable references live code section. - bool isLiveVariableEntry(CompileUnit &CU, const DWARFDebugInfoEntry *Entry); - - /// Returns true if specified subprogram references live code section. - bool isLiveSubprogramEntry(CompileUnit &CU, const DWARFDebugInfoEntry *Entry); - - /// Examine worklist and mark all 'root DIE's as kept. - bool markLiveRootsAsKept(); - - /// Mark whole DIE tree as kept recursively. - bool markDIEEntryAsKeptRec(const RootEntryTy &RootItem, CompileUnit &CU, - const DWARFDebugInfoEntry *Entry); - - /// Check referenced DIEs and add them into the worklist if neccessary. - bool maybeAddReferencedRoots(const RootEntryTy &RootItem, CompileUnit &CU, - const DWARFDebugInfoEntry *Entry); - - /// Add 'root DIE' into the worklist. - void addItemToWorklist(CompileUnit &CU, const DWARFDebugInfoEntry *Entry); - - /// Set kind of placement(whether it goes into type table, plain dwarf or - /// both) for the specified die \p DieIdx. - void setDIEPlacementAndTypename(CompileUnit::DIEInfo &Info); - - /// Flag indicating whether liveness information should be examined. - bool TrackLiveness = false; - - /// List of CU, Entry pairs which are 'root DIE's. - RootEntriesListTy RootEntriesWorkList; - - /// Link context for the analyzed CU. - DWARFLinkerImpl::LinkContext &Context; -}; - -} // end namespace dwarflinker_parallel -} // end namespace llvm - -#endif // LLVM_LIB_DWARFLINKERPARALLEL_DEPENDENCYTRACKER_H diff --git a/llvm/lib/DWARFLinkerParallel/IndexedValuesMap.h b/llvm/lib/DWARFLinkerParallel/IndexedValuesMap.h deleted file mode 100644 index 0dc8de860a42e..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/IndexedValuesMap.h +++ /dev/null @@ -1,49 +0,0 @@ -//===- IndexedValuesMap.h ---------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_DWARFLINKERPARALLEL_INDEXEDVALUESMAP_H -#define LLVM_LIB_DWARFLINKERPARALLEL_INDEXEDVALUESMAP_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" -#include -#include - -namespace llvm { -namespace dwarflinker_parallel { - -template class IndexedValuesMap { -public: - uint64_t getValueIndex(T Value) { - typename ValueToIndexMapTy::iterator It = ValueToIndexMap.find(Value); - if (It == ValueToIndexMap.end()) { - It = ValueToIndexMap.insert(std::make_pair(Value, Values.size())).first; - Values.push_back(Value); - } - return It->second; - } - - const SmallVector &getValues() { return Values; } - - void clear() { - ValueToIndexMap.clear(); - Values.clear(); - } - - bool empty() { return Values.empty(); } - -protected: - using ValueToIndexMapTy = DenseMap; - ValueToIndexMapTy ValueToIndexMap; - SmallVector Values; -}; - -} // end of namespace dwarflinker_parallel -} // end namespace llvm - -#endif // LLVM_LIB_DWARFLINKERPARALLEL_INDEXEDVALUESMAP_H diff --git a/llvm/lib/DWARFLinkerParallel/OutputSections.cpp b/llvm/lib/DWARFLinkerParallel/OutputSections.cpp index c7518153cffe7..69c5bfaa7bdf8 100644 --- a/llvm/lib/DWARFLinkerParallel/OutputSections.cpp +++ b/llvm/lib/DWARFLinkerParallel/OutputSections.cpp @@ -7,400 +7,30 @@ //===----------------------------------------------------------------------===// #include "OutputSections.h" -#include "DWARFLinkerCompileUnit.h" #include "llvm/ADT/StringSwitch.h" namespace llvm { 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"}; - -const StringLiteral &getSectionName(DebugSectionKind SectionKind) { - return SectionNames[static_cast(SectionKind)]; -} - -std::optional parseDebugTableName(llvm::StringRef SecName) { - return llvm::StringSwitch>( - SecName.substr(SecName.find_first_not_of("._"))) - .Case(getSectionName(DebugSectionKind::DebugInfo), - DebugSectionKind::DebugInfo) - .Case(getSectionName(DebugSectionKind::DebugLine), - DebugSectionKind::DebugLine) - .Case(getSectionName(DebugSectionKind::DebugFrame), - DebugSectionKind::DebugFrame) - .Case(getSectionName(DebugSectionKind::DebugRange), - DebugSectionKind::DebugRange) - .Case(getSectionName(DebugSectionKind::DebugRngLists), - DebugSectionKind::DebugRngLists) - .Case(getSectionName(DebugSectionKind::DebugLoc), - DebugSectionKind::DebugLoc) - .Case(getSectionName(DebugSectionKind::DebugLocLists), - DebugSectionKind::DebugLocLists) - .Case(getSectionName(DebugSectionKind::DebugARanges), - DebugSectionKind::DebugARanges) - .Case(getSectionName(DebugSectionKind::DebugAbbrev), - DebugSectionKind::DebugAbbrev) - .Case(getSectionName(DebugSectionKind::DebugMacinfo), - DebugSectionKind::DebugMacinfo) - .Case(getSectionName(DebugSectionKind::DebugMacro), - DebugSectionKind::DebugMacro) - .Case(getSectionName(DebugSectionKind::DebugAddr), - DebugSectionKind::DebugAddr) - .Case(getSectionName(DebugSectionKind::DebugStr), - DebugSectionKind::DebugStr) - .Case(getSectionName(DebugSectionKind::DebugLineStr), - DebugSectionKind::DebugLineStr) - .Case(getSectionName(DebugSectionKind::DebugStrOffsets), - DebugSectionKind::DebugStrOffsets) +std::optional +OutputSections::parseDebugSectionName(llvm::StringRef SecName) { + return llvm::StringSwitch>( + SecName) + .Case("debug_info", DebugSectionKind::DebugInfo) + .Case("debug_line", DebugSectionKind::DebugLine) + .Case("debug_frame", DebugSectionKind::DebugFrame) + .Case("debug_ranges", DebugSectionKind::DebugRange) + .Case("debug_rnglists", DebugSectionKind::DebugRngLists) + .Case("debug_loc", DebugSectionKind::DebugLoc) + .Case("debug_loclists", DebugSectionKind::DebugLocLists) + .Case("debug_aranges", DebugSectionKind::DebugARanges) + .Case("debug_abbrev", DebugSectionKind::DebugAbbrev) + .Case("debug_macinfo", DebugSectionKind::DebugMacinfo) + .Case("debug_macro", DebugSectionKind::DebugMacro) .Default(std::nullopt); return std::nullopt; } -DebugDieRefPatch::DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, - CompileUnit *RefCU, uint32_t RefIdx) - : SectionPatch({PatchOffset}), - RefCU(RefCU, (SrcCU != nullptr) && - (SrcCU->getUniqueID() == RefCU->getUniqueID())), - RefDieIdxOrClonedOffset(RefIdx) {} - -DebugULEB128DieRefPatch::DebugULEB128DieRefPatch(uint64_t PatchOffset, - CompileUnit *SrcCU, - CompileUnit *RefCU, - uint32_t RefIdx) - : SectionPatch({PatchOffset}), - RefCU(RefCU, SrcCU->getUniqueID() == RefCU->getUniqueID()), - RefDieIdxOrClonedOffset(RefIdx) {} - -void SectionDescriptor::erase() { - StartOffset = 0; - Contents = OutSectionDataTy(); - ListDebugStrPatch.erase(); - ListDebugLineStrPatch.erase(); - ListDebugRangePatch.erase(); - ListDebugLocPatch.erase(); - ListDebugDieRefPatch.erase(); - ListDebugULEB128DieRefPatch.erase(); - ListDebugOffsetPatch.erase(); -} - -void SectionDescriptor::setSizesForSectionCreatedByAsmPrinter() { - if (Contents.empty()) - return; - - MemoryBufferRef Mem(Contents, "obj"); - Expected> Obj = - object::ObjectFile::createObjectFile(Mem); - if (!Obj) { - consumeError(Obj.takeError()); - Contents.clear(); - return; - } - - for (const object::SectionRef &Sect : (*Obj).get()->sections()) { - Expected SectNameOrErr = Sect.getName(); - if (!SectNameOrErr) { - consumeError(SectNameOrErr.takeError()); - continue; - } - - if (std::optional SectKind = - parseDebugTableName(*SectNameOrErr)) { - if (*SectKind == SectionKind) { - Expected Data = Sect.getContents(); - if (!Data) { - consumeError(SectNameOrErr.takeError()); - Contents.clear(); - return; - } - - SectionOffsetInsideAsmPrinterOutputStart = - Data->data() - Contents.data(); - SectionOffsetInsideAsmPrinterOutputEnd = - SectionOffsetInsideAsmPrinterOutputStart + Data->size(); - } - } - } - - return; -} - -void SectionDescriptor::emitIntVal(uint64_t Val, unsigned Size) { - switch (Size) { - case 1: { - OS.write(static_cast(Val)); - } break; - case 2: { - uint16_t ShortVal = static_cast(Val); - if ((Endianess == support::endianness::little) != sys::IsLittleEndianHost) - sys::swapByteOrder(ShortVal); - OS.write(reinterpret_cast(&ShortVal), Size); - } break; - case 4: { - uint32_t ShortVal = static_cast(Val); - if ((Endianess == support::endianness::little) != sys::IsLittleEndianHost) - sys::swapByteOrder(ShortVal); - OS.write(reinterpret_cast(&ShortVal), Size); - } break; - case 8: { - if ((Endianess == support::endianness::little) != sys::IsLittleEndianHost) - sys::swapByteOrder(Val); - OS.write(reinterpret_cast(&Val), Size); - } break; - default: - llvm_unreachable("Unsupported integer type size"); - } -} - -void SectionDescriptor::emitString(dwarf::Form StringForm, - const char *StringVal) { - assert(StringVal != nullptr); - - switch (StringForm) { - case dwarf::DW_FORM_string: { - emitInplaceString(GlobalData.translateString(StringVal)); - } break; - case dwarf::DW_FORM_strp: { - notePatch(DebugStrPatch{ - {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first}); - emitStringPlaceholder(); - } break; - case dwarf::DW_FORM_line_strp: { - notePatch(DebugLineStrPatch{ - {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first}); - emitStringPlaceholder(); - } break; - default: - llvm_unreachable("Unsupported string form"); - break; - }; -} - -void SectionDescriptor::apply(uint64_t PatchOffset, dwarf::Form AttrForm, - uint64_t Val) { - switch (AttrForm) { - case dwarf::DW_FORM_strp: - case dwarf::DW_FORM_line_strp: { - applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize()); - } break; - - case dwarf::DW_FORM_ref_addr: { - applyIntVal(PatchOffset, Val, Format.getRefAddrByteSize()); - } break; - case dwarf::DW_FORM_ref1: { - applyIntVal(PatchOffset, Val, 1); - } break; - case dwarf::DW_FORM_ref2: { - applyIntVal(PatchOffset, Val, 2); - } break; - case dwarf::DW_FORM_ref4: { - applyIntVal(PatchOffset, Val, 4); - } break; - case dwarf::DW_FORM_ref8: { - applyIntVal(PatchOffset, Val, 8); - } break; - - case dwarf::DW_FORM_data1: { - applyIntVal(PatchOffset, Val, 1); - } break; - case dwarf::DW_FORM_data2: { - applyIntVal(PatchOffset, Val, 2); - } break; - case dwarf::DW_FORM_data4: { - applyIntVal(PatchOffset, Val, 4); - } break; - case dwarf::DW_FORM_data8: { - applyIntVal(PatchOffset, Val, 8); - } break; - case dwarf::DW_FORM_udata: { - applyULEB128(PatchOffset, Val); - } break; - case dwarf::DW_FORM_sdata: { - applySLEB128(PatchOffset, Val); - } break; - case dwarf::DW_FORM_sec_offset: { - applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize()); - } break; - case dwarf::DW_FORM_flag: { - applyIntVal(PatchOffset, Val, 1); - } break; - - default: - llvm_unreachable("Unsupported attribute form"); - break; - } -} - -uint64_t SectionDescriptor::getIntVal(uint64_t PatchOffset, unsigned Size) { - assert(PatchOffset < getContents().size()); - switch (Size) { - case 1: { - return *reinterpret_cast( - (getContents().data() + PatchOffset)); - } - case 2: { - return support::endian::read16(getContents().data() + PatchOffset, - Endianess); - } - case 4: { - return support::endian::read32(getContents().data() + PatchOffset, - Endianess); - } - case 8: { - return support::endian::read64(getContents().data() + PatchOffset, - Endianess); - } - } - llvm_unreachable("Unsupported integer type size"); - return 0; -} - -void SectionDescriptor::applyIntVal(uint64_t PatchOffset, uint64_t Val, - unsigned Size) { - assert(PatchOffset < getContents().size()); - - switch (Size) { - case 1: { - support::endian::write( - const_cast(getContents().data() + PatchOffset), - static_cast(Val), Endianess); - } break; - case 2: { - support::endian::write( - const_cast(getContents().data() + PatchOffset), - static_cast(Val), Endianess); - } break; - case 4: { - support::endian::write( - const_cast(getContents().data() + PatchOffset), - static_cast(Val), Endianess); - } break; - case 8: { - support::endian::write( - const_cast(getContents().data() + PatchOffset), - static_cast(Val), Endianess); - } break; - default: - llvm_unreachable("Unsupported integer type size"); - } -} - -void SectionDescriptor::applyULEB128(uint64_t PatchOffset, uint64_t Val) { - assert(PatchOffset < getContents().size()); - - uint8_t ULEB[16]; - uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1; - uint8_t RealSize = encodeULEB128(Val, ULEB, DestSize); - - memcpy(const_cast(getContents().data() + PatchOffset), ULEB, - RealSize); -} - -/// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset. -void SectionDescriptor::applySLEB128(uint64_t PatchOffset, uint64_t Val) { - assert(PatchOffset < getContents().size()); - - uint8_t SLEB[16]; - uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1; - uint8_t RealSize = encodeSLEB128(Val, SLEB, DestSize); - - memcpy(const_cast(getContents().data() + PatchOffset), SLEB, - RealSize); -} - -void OutputSections::applyPatches( - SectionDescriptor &Section, - StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, - StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings) { - - Section.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) { - DwarfStringPoolEntryWithExtString *Entry = - DebugStrStrings.getExistingEntry(Patch.String); - assert(Entry != nullptr); - - Section.apply(Patch.PatchOffset, dwarf::DW_FORM_strp, Entry->Offset); - }); - - Section.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) { - DwarfStringPoolEntryWithExtString *Entry = - DebugLineStrStrings.getExistingEntry(Patch.String); - assert(Entry != nullptr); - - Section.apply(Patch.PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset); - }); - - std::optional RangeSection; - if (Format.Version >= 5) - RangeSection = getSectionDescriptor(DebugSectionKind::DebugRngLists); - else - RangeSection = getSectionDescriptor(DebugSectionKind::DebugRange); - - if (RangeSection) { - Section.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) { - uint64_t FinalValue = - Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize()); - FinalValue += (*RangeSection)->StartOffset; - - Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue); - }); - } - - std::optional LocationSection; - if (Format.Version >= 5) - LocationSection = getSectionDescriptor(DebugSectionKind::DebugLocLists); - else - LocationSection = getSectionDescriptor(DebugSectionKind::DebugLoc); - - if (LocationSection) { - Section.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) { - uint64_t FinalValue = - Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize()); - FinalValue += (*LocationSection)->StartOffset; - - Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue); - }); - } - - Section.ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) { - uint64_t FinalOffset = Patch.RefDieIdxOrClonedOffset; - dwarf::Form FinalForm = dwarf::DW_FORM_ref4; - - if (!Patch.RefCU.getInt()) { - std::optional 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; - } - - Section.apply(Patch.PatchOffset, FinalForm, FinalOffset); - }); - - Section.ListDebugULEB128DieRefPatch.forEach( - [&](DebugULEB128DieRefPatch &Patch) { - assert(Patch.RefCU.getInt()); - Section.apply(Patch.PatchOffset, dwarf::DW_FORM_udata, - Patch.RefDieIdxOrClonedOffset); - }); - - Section.ListDebugOffsetPatch.forEach([&](DebugOffsetPatch &Patch) { - uint64_t FinalValue = Patch.SectionPtr.getPointer()->StartOffset; - if (Patch.SectionPtr.getInt()) - FinalValue += - Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize()); - - Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue); - }); -} - } // end of namespace dwarflinker_parallel } // end of namespace llvm diff --git a/llvm/lib/DWARFLinkerParallel/OutputSections.h b/llvm/lib/DWARFLinkerParallel/OutputSections.h index 29148277596dc..15ab4cc1167a3 100644 --- a/llvm/lib/DWARFLinkerParallel/OutputSections.h +++ b/llvm/lib/DWARFLinkerParallel/OutputSections.h @@ -9,397 +9,56 @@ #ifndef LLVM_LIB_DWARFLINKERPARALLEL_OUTPUTSECTIONS_H #define LLVM_LIB_DWARFLINKERPARALLEL_OUTPUTSECTIONS_H -#include "ArrayList.h" -#include "StringEntryToDwarfStringPoolEntryMap.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" -#include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/CodeGen/DwarfStringPoolEntry.h" -#include "llvm/DWARFLinkerParallel/StringPool.h" -#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" -#include "llvm/DebugInfo/DWARF/DWARFObject.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/LEB128.h" -#include "llvm/Support/MemoryBufferRef.h" -#include "llvm/Support/raw_ostream.h" #include #include namespace llvm { namespace dwarflinker_parallel { -/// List of tracked debug tables. -enum class DebugSectionKind : uint8_t { - DebugInfo = 0, - DebugLine, - DebugFrame, - DebugRange, - DebugRngLists, - DebugLoc, - DebugLocLists, - DebugARanges, - DebugAbbrev, - DebugMacinfo, - DebugMacro, - DebugAddr, - DebugStr, - DebugLineStr, - DebugStrOffsets, - NumberOfEnumEntries // must be last -}; -constexpr static size_t SectionKindsNum = - static_cast(DebugSectionKind::NumberOfEnumEntries); - -/// Recognise the table name and match it with the DebugSectionKind. -std::optional parseDebugTableName(StringRef Name); - -/// Return the name of the section. -const StringLiteral &getSectionName(DebugSectionKind SectionKind); - -/// There are fields(sizes, offsets) which should be updated after -/// sections are generated. To remember offsets and related data -/// the descendants of SectionPatch structure should be used. - -struct SectionPatch { - uint64_t PatchOffset = 0; -}; - -/// This structure is used to update strings offsets into .debug_str. -struct DebugStrPatch : SectionPatch { - const StringEntry *String = nullptr; -}; - -/// This structure is used to update strings offsets into .debug_line_str. -struct DebugLineStrPatch : SectionPatch { - const StringEntry *String = nullptr; -}; - -/// This structure is used to update range list offset into -/// .debug_ranges/.debug_rnglists. -struct DebugRangePatch : SectionPatch { - /// Indicates patch which points to immediate compile unit's attribute. - bool IsCompileUnitRanges = false; -}; - -/// This structure is used to update location list offset into -/// .debug_loc/.debug_loclists. -struct DebugLocPatch : SectionPatch { - int64_t AddrAdjustmentValue = 0; -}; - -/// This structure is used to update offset with start of another section. -struct SectionDescriptor; -struct DebugOffsetPatch : SectionPatch { - DebugOffsetPatch(uint64_t PatchOffset, SectionDescriptor *SectionPtr, - bool AddLocalValue = false) - : SectionPatch({PatchOffset}), SectionPtr(SectionPtr, AddLocalValue) {} - - PointerIntPair SectionPtr; -}; - -/// This structure is used to update reference to the DIE. -struct DebugDieRefPatch : SectionPatch { - DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, CompileUnit *RefCU, - uint32_t RefIdx); - - PointerIntPair RefCU; - uint64_t RefDieIdxOrClonedOffset; -}; - -/// This structure is used to update reference to the DIE of ULEB128 form. -struct DebugULEB128DieRefPatch : SectionPatch { - DebugULEB128DieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, - CompileUnit *RefCU, uint32_t RefIdx); - - PointerIntPair RefCU; - uint64_t RefDieIdxOrClonedOffset; -}; - -/// Type for section data. -using OutSectionDataTy = SmallString<0>; - -/// Type for list of pointers to patches offsets. -using OffsetsPtrVector = SmallVector; - -class OutputSections; - -/// This structure is used to keep data of the concrete section. -/// Like data bits, list of patches, format. -struct SectionDescriptor { - friend OutputSections; - - SectionDescriptor(DebugSectionKind SectionKind, LinkingGlobalData &GlobalData, - dwarf::FormParams Format, support::endianness Endianess) - : OS(Contents), GlobalData(GlobalData), SectionKind(SectionKind), - Format(Format), Endianess(Endianess) { - ListDebugStrPatch.setAllocator(&GlobalData.getAllocator()); - ListDebugLineStrPatch.setAllocator(&GlobalData.getAllocator()); - ListDebugRangePatch.setAllocator(&GlobalData.getAllocator()); - ListDebugLocPatch.setAllocator(&GlobalData.getAllocator()); - ListDebugDieRefPatch.setAllocator(&GlobalData.getAllocator()); - ListDebugULEB128DieRefPatch.setAllocator(&GlobalData.getAllocator()); - ListDebugOffsetPatch.setAllocator(&GlobalData.getAllocator()); - } - - /// Erase whole section contents(data bits, list of patches, format). - void erase(); - - /// When objects(f.e. compile units) are glued into the single file, - /// the debug sections corresponding to the concrete object are assigned - /// with offsets inside the whole file. This field keeps offset - /// to the debug section, corresponding to this object. - uint64_t StartOffset = 0; - - /// Stream which stores data to the Contents. - raw_svector_ostream OS; - - /// Section patches. -#define ADD_PATCHES_LIST(T) \ - T ¬ePatch(const T &Patch) { return List##T.noteItem(Patch); } \ - ArrayList List##T; - - ADD_PATCHES_LIST(DebugStrPatch) - ADD_PATCHES_LIST(DebugLineStrPatch) - ADD_PATCHES_LIST(DebugRangePatch) - ADD_PATCHES_LIST(DebugLocPatch) - ADD_PATCHES_LIST(DebugDieRefPatch) - ADD_PATCHES_LIST(DebugULEB128DieRefPatch) - ADD_PATCHES_LIST(DebugOffsetPatch) - - /// Offsets to some fields are not known at the moment of noting patch. - /// In that case we remember pointers to patch offset to update them later. - template - void notePatchWithOffsetUpdate(const T &Patch, - OffsetsPtrVector &PatchesOffsetsList) { - PatchesOffsetsList.emplace_back(¬ePatch(Patch).PatchOffset); - } - - /// Some sections are emitted using AsmPrinter. In that case "Contents" - /// member of SectionDescriptor contains elf file. This method searches - /// for section data inside elf file and remember offset to it. - void setSizesForSectionCreatedByAsmPrinter(); - - /// Returns section content. - StringRef getContents() { - if (SectionOffsetInsideAsmPrinterOutputStart == 0) - return StringRef(Contents.data(), Contents.size()); - - return Contents.slice(SectionOffsetInsideAsmPrinterOutputStart, - SectionOffsetInsideAsmPrinterOutputEnd); - } - - /// Emit unit length into the current section contents. - void emitUnitLength(uint64_t Length) { - maybeEmitDwarf64Mark(); - emitIntVal(Length, getFormParams().getDwarfOffsetByteSize()); - } - - /// Emit DWARF64 mark into the current section contents. - void maybeEmitDwarf64Mark() { - if (getFormParams().Format != dwarf::DWARF64) - return; - emitIntVal(dwarf::DW_LENGTH_DWARF64, 4); - } - - /// Emit specified offset value into the current section contents. - void emitOffset(uint64_t Val) { - emitIntVal(Val, getFormParams().getDwarfOffsetByteSize()); - } - - /// Emit specified integer value into the current section contents. - void emitIntVal(uint64_t Val, unsigned Size); - - /// Emit specified string value into the current section contents. - void emitString(dwarf::Form StringForm, const char *StringVal); - - /// Emit specified inplace string value into the current section contents. - void emitInplaceString(StringRef String) { - OS << String; - emitIntVal(0, 1); - } - - /// Emit string placeholder into the current section contents. - void emitStringPlaceholder() { - // emit bad offset which should be updated later. - emitOffset(0xBADDEF); - } - - /// Write specified \p Value of \p AttrForm to the \p PatchOffset. - void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val); - - /// Returns section kind. - DebugSectionKind getKind() { return SectionKind; } - - /// Returns section name. - const StringLiteral &getName() const { return getSectionName(SectionKind); } - - /// Returns endianess used by section. - support::endianness getEndianess() const { return Endianess; } - - /// Returns FormParams used by section. - dwarf::FormParams getFormParams() const { return Format; } - - /// Returns integer value of \p Size located by specified \p PatchOffset. - uint64_t getIntVal(uint64_t PatchOffset, unsigned Size); - -protected: - /// Writes integer value \p Val of \p Size by specified \p PatchOffset. - void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size); - - /// Writes integer value \p Val of ULEB128 format by specified \p PatchOffset. - void applyULEB128(uint64_t PatchOffset, uint64_t Val); - - /// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset. - void applySLEB128(uint64_t PatchOffset, uint64_t Val); - - /// Sets output format. - void setOutputFormat(dwarf::FormParams Format, - support::endianness Endianess) { - this->Format = Format; - this->Endianess = Endianess; - } - - LinkingGlobalData &GlobalData; - - /// The section kind. - DebugSectionKind SectionKind = DebugSectionKind::NumberOfEnumEntries; - - /// Section data bits. - OutSectionDataTy Contents; - - /// Some sections are generated using AsmPrinter. The real section data - /// located inside elf file in that case. Following fields points to the - /// real section content inside elf file. - size_t SectionOffsetInsideAsmPrinterOutputStart = 0; - size_t SectionOffsetInsideAsmPrinterOutputEnd = 0; - - /// Output format. - dwarf::FormParams Format = {4, 4, dwarf::DWARF32}; - support::endianness Endianess = support::endianness::little; -}; - -/// This class keeps contents and offsets to the debug sections. Any objects -/// which is supposed to be emitted into the debug sections should use this -/// class to track debug sections offsets and keep sections data. +/// This class keeps offsets to the debug sections. Any object which is +/// supposed to be emitted into the debug section should use this class to +/// track debug sections offsets. class OutputSections { public: - OutputSections(LinkingGlobalData &GlobalData) : GlobalData(GlobalData) {} - - /// Sets output format for all keeping sections. - void setOutputFormat(DWARFUnit &OriginalUnit) { - setOutputFormat(OriginalUnit.getFormParams(), - OriginalUnit.isLittleEndian() ? support::endianness::little - : support::endianness::big); - } - - /// Sets output format for all keeping sections. - void setOutputFormat(dwarf::FormParams Format, - support::endianness Endianess) { - this->Format = Format; - this->Endianess = Endianess; - } - - /// Returns descriptor for the specified section of \p SectionKind. - std::optional - getSectionDescriptor(DebugSectionKind SectionKind) const { - SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind); + /// List of tracked debug sections. + enum class DebugSectionKind : uint8_t { + DebugInfo = 0, + DebugLine, + DebugFrame, + DebugRange, + DebugRngLists, + DebugLoc, + DebugLocLists, + DebugARanges, + DebugAbbrev, + DebugMacinfo, + DebugMacro, + }; + constexpr static size_t SectionKindsNum = 11; + + /// Recognise the section name and match it with the DebugSectionKind. + static std::optional parseDebugSectionName(StringRef Name); - if (It == SectionDescriptors.end()) - return std::nullopt; - - return &It->second; - } - - /// Returns descriptor for the specified section of \p SectionKind. - std::optional - getSectionDescriptor(DebugSectionKind SectionKind) { - SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind); - - if (It == SectionDescriptors.end()) - return std::nullopt; - - return &It->second; - } - - /// Returns descriptor for the specified section of \p SectionKind. - /// If descriptor does not exist then create it. - SectionDescriptor & - getOrCreateSectionDescriptor(DebugSectionKind SectionKind) { - return SectionDescriptors - .try_emplace(SectionKind, SectionKind, GlobalData, Format, Endianess) - .first->second; - } - - /// Erases data of all sections. - void eraseSections() { - for (auto &Section : SectionDescriptors) - Section.second.erase(); - } - - /// Enumerate all sections and call \p Handler for each. - void forEach(function_ref Handler) { - for (auto &Section : SectionDescriptors) - Handler(Section.second); - } - - /// Enumerate all sections, for each section set current offset - /// (kept by \p SectionSizesAccumulator), update current offset with section - /// length. - void assignSectionsOffsetAndAccumulateSize( - std::array &SectionSizesAccumulator) { - for (auto &Section : SectionDescriptors) { - Section.second.StartOffset = SectionSizesAccumulator[static_cast( - Section.second.getKind())]; - SectionSizesAccumulator[static_cast(Section.second.getKind())] += - Section.second.getContents().size(); - } - } - - /// Enumerate all sections, for each section apply all section patches. - void applyPatches(SectionDescriptor &Section, - StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, - StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings); - - /// Endiannes for the sections. - support::endianness getEndianness() const { return Endianess; } - - /// Return DWARF version. - uint16_t getVersion() const { return Format.Version; } - - /// Return size of header of debug_info table. - uint16_t getDebugInfoHeaderSize() const { - return Format.Version >= 5 ? 12 : 11; - } - - /// Return size of header of debug_ table. - uint16_t getDebugAddrHeaderSize() const { - assert(Format.Version >= 5); - return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16; + /// When objects(f.e. compile units) are glued into the single file, + /// the debug sections corresponding to the concrete object are assigned + /// with offsets inside the whole file. This method returns offset + /// to the \p SectionKind debug section, corresponding to this object. + uint64_t getStartOffset(DebugSectionKind SectionKind) const { + return Offsets[static_cast< + typename std::underlying_type::type>(SectionKind)]; } - /// Return size of header of debug_str_offsets table. - uint16_t getDebugStrOffsetsHeaderSize() const { - assert(Format.Version >= 5); - return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16; + /// Set offset to the start of specified \p SectionKind debug section, + /// corresponding to this object. + void setStartOffset(DebugSectionKind SectionKind, uint64_t Offset) { + Offsets[static_cast::type>( + SectionKind)] = Offset; } - /// Return size of address. - const dwarf::FormParams &getFormParams() const { return Format; } - protected: - LinkingGlobalData &GlobalData; - - /// Format for sections. - dwarf::FormParams Format = {4, 4, dwarf::DWARF32}; - - /// Endiannes for sections. - support::endianness Endianess = support::endianness::little; - - /// All keeping sections. - using SectionsSetTy = std::map; - SectionsSetTy SectionDescriptors; + /// Offsets to the debug sections composing this object. + std::array Offsets = {0}; }; } // end of namespace dwarflinker_parallel diff --git a/llvm/lib/DWARFLinkerParallel/StringEntryToDwarfStringPoolEntryMap.h b/llvm/lib/DWARFLinkerParallel/StringEntryToDwarfStringPoolEntryMap.h deleted file mode 100644 index b4c74d0adba97..0000000000000 --- a/llvm/lib/DWARFLinkerParallel/StringEntryToDwarfStringPoolEntryMap.h +++ /dev/null @@ -1,72 +0,0 @@ -//===- StringEntryToDwarfStringPoolEntryMap.h -------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_DWARFLINKERPARALLEL_STRINGENTRYTODWARFSTRINGPOOLENTRYMAP_H -#define LLVM_LIB_DWARFLINKERPARALLEL_STRINGENTRYTODWARFSTRINGPOOLENTRYMAP_H - -#include "DWARFLinkerGlobalData.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/DWARFLinkerParallel/StringPool.h" - -namespace llvm { -namespace dwarflinker_parallel { - -/// This class creates a DwarfStringPoolEntry for the corresponding StringEntry. -class StringEntryToDwarfStringPoolEntryMap { -public: - StringEntryToDwarfStringPoolEntryMap(LinkingGlobalData &GlobalData) - : GlobalData(GlobalData) {} - ~StringEntryToDwarfStringPoolEntryMap() {} - - /// Create DwarfStringPoolEntry for specified StringEntry if necessary. - /// Initialize DwarfStringPoolEntry with initial values. - DwarfStringPoolEntryWithExtString *add(const StringEntry *String) { - DwarfStringPoolEntriesTy::iterator it = DwarfStringPoolEntries.find(String); - - if (it == DwarfStringPoolEntries.end()) { - DwarfStringPoolEntryWithExtString *DataPtr = - GlobalData.getAllocator() - .Allocate(); - DataPtr->String = GlobalData.translateString(String->getKey()); - DataPtr->Index = DwarfStringPoolEntry::NotIndexed; - DataPtr->Offset = 0; - DataPtr->Symbol = nullptr; - it = DwarfStringPoolEntries.insert(std::make_pair(String, DataPtr)).first; - } - - assert(it->second != nullptr); - return it->second; - } - - /// Returns already existed DwarfStringPoolEntry for the specified - /// StringEntry. - DwarfStringPoolEntryWithExtString * - getExistingEntry(const StringEntry *String) const { - DwarfStringPoolEntriesTy::const_iterator it = - DwarfStringPoolEntries.find(String); - - assert(it != DwarfStringPoolEntries.end()); - assert(it->second != nullptr); - return it->second; - } - - /// Erase contents of StringsForEmission. - void clear() { DwarfStringPoolEntries.clear(); } - -protected: - using DwarfStringPoolEntriesTy = - DenseMap; - DwarfStringPoolEntriesTy DwarfStringPoolEntries; - - LinkingGlobalData &GlobalData; -}; - -} // end of namespace dwarflinker_parallel -} // end namespace llvm - -#endif // LLVM_LIB_DWARFLINKERPARALLEL_STRINGENTRYTODWARFSTRINGPOOLENTRYMAP_H 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 index 96febc4fb1b87..0000000000000 --- 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 index 0e1e427be67c2..0000000000000 --- 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 index 4947f6005d3fe..0000000000000 --- 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 index 640b5484b2c4e..0000000000000 --- 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/call-pc-reloc.test b/llvm/test/tools/dsymutil/ARM/call-pc-reloc.test index 8c2b2622a3658..f34e682697b01 100644 --- a/llvm/test/tools/dsymutil/ARM/call-pc-reloc.test +++ b/llvm/test/tools/dsymutil/ARM/call-pc-reloc.test @@ -17,7 +17,4 @@ $ clang -arch arm64 main.arm64.o -o main.arm64 -g RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/call_pc/main.arm64 -o %t.dSYM RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_pc -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/call_pc/main.arm64 -o %t.dSYM -RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_pc - CHECK: DW_AT_call_pc (0x0000000100007f94) diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-addr-base.test b/llvm/test/tools/dsymutil/ARM/dwarf5-addr-base.test index 00dcde718e362..96973fe122c8c 100644 --- a/llvm/test/tools/dsymutil/ARM/dwarf5-addr-base.test +++ b/llvm/test/tools/dsymutil/ARM/dwarf5-addr-base.test @@ -49,23 +49,9 @@ RUN: rm -rf %t.dir && mkdir -p %t.dir RUN: dsymutil -y %p/dummy-debug-map-amr64.map -oso-prepend-path=%p/../Inputs/DWARF5-addr-base-str-off-base -o %t.dir/dwarf5-addr-base.dSYM RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.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-addr-base-str-off-base \ -RUN: -o %t.dir/dwarf5-addr-base.dSYM -RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.dSYM -a --verbose | FileCheck %s - -RUN: rm -rf %t.dir && mkdir -p %t.dir RUN: dsymutil --update -y %p/dummy-debug-map-amr64.map -oso-prepend-path=%p/../Inputs/DWARF5-addr-base-str-off-base -o %t.dir/dwarf5-addr-base.dSYM RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.dSYM -a --verbose | FileCheck %s --check-prefix=UPD -RUN: rm -rf %t.dir && mkdir -p %t.dir -RUN: dsymutil --linker llvm --update -y %p/dummy-debug-map-amr64.map \ -RUN: -oso-prepend-path=%p/../Inputs/DWARF5-addr-base-str-off-base \ -RUN: -o %t.dir/dwarf5-addr-base.dSYM -RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.dSYM -a --verbose | \ -RUN: FileCheck %s --check-prefix=UPD - CHECK: .debug_info contents: CHECK-NEXT: 0x00000000: Compile Unit: length = 0x0000004a, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 @@ -76,7 +62,7 @@ CHECK: 0x0000002c: DW_TAG_subprogram [2] * (0x0000000c) CHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x[[ADDR1:[0-9a-f]+]]) -CHECK: 0x0000004e: Compile Unit: length = 0x0000004a, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x00{{00|5a}}, addr_size = 0x08 +CHECK: 0x0000004e: Compile Unit: length = 0x0000004a, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 CHECK: 0x0000005a: DW_TAG_compile_unit [1] * CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000018) @@ -84,9 +70,9 @@ CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000018) CHECK: 0x0000007a: DW_TAG_subprogram [2] * (0x0000005a) CHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x[[ADDR2:[0-9a-f]+]]) -CHECK: 0x0000009c: Compile Unit: length = 0x00000043, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x00{{00|b4}}, addr_size = 0x08 +CHECK: 0x0000009c: Compile Unit: length = 0x00000043, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 -CHECK: 0x000000a8: DW_TAG_compile_unit {{.*}} * +CHECK: 0x000000a8: DW_TAG_compile_unit [5] * CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000028) CHECK: 0x000000c1: DW_TAG_subprogram [2] * (0x000000a8) @@ -125,7 +111,7 @@ UPD: 0x00000071: DW_TAG_subprogram [5] (0x0000000c) UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000003) address = 0x0000000000000010) -UPD: 0x00000085: Compile Unit: length = 0x00000072, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x00{{00|99}}, addr_size = 0x08 +UPD: 0x00000085: Compile Unit: length = 0x00000072, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 UPD: 0x00000091: DW_TAG_compile_unit [1] * UPD: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) @@ -139,12 +125,12 @@ UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000001) ad UPD: 0x000000dc: DW_TAG_subprogram [3] * (0x00000091) UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000002) address = 0x0000000000000008) -UPD: 0x000000fb: Compile Unit: length = 0x00000044, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0{{000|115}}, addr_size = 0x08 +UPD: 0x000000fb: Compile Unit: length = 0x00000044, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 -UPD: 0x00000107: DW_TAG_compile_unit {{.*}} * +UPD: 0x00000107: DW_TAG_compile_unit [7] * UPD: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) -UPD: 0x00000124: DW_TAG_subprogram {{.*}} * (0x00000107) +UPD: 0x00000124: DW_TAG_subprogram [3] * (0x00000107) UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000000018) UPD: .debug_addr contents: diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-addrx-0x0-last.test b/llvm/test/tools/dsymutil/ARM/dwarf5-addrx-0x0-last.test index e54d05f941162..f74c514ab5169 100644 --- a/llvm/test/tools/dsymutil/ARM/dwarf5-addrx-0x0-last.test +++ b/llvm/test/tools/dsymutil/ARM/dwarf5-addrx-0x0-last.test @@ -28,14 +28,6 @@ RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s RUN: llvm-dwarfdump --verbose -debug-info %t.dSYM | FileCheck %s --check-prefix DEBUGINFO RUN: llvm-dwarfdump --verbose -debug-line %t.dSYM | FileCheck %s --check-prefix DEBUGLINE -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs \ -RUN: %p/../Inputs/private/tmp/dwarf5/dwarf5-addrx-0x0-last.out \ -RUN: -o %t.dSYM 2>&1 | FileCheck %s --allow-empty -RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s -RUN: llvm-dwarfdump --verbose -debug-info %t.dSYM | FileCheck %s --check-prefix DEBUGINFO -RUN: llvm-dwarfdump --verbose -debug-line %t.dSYM | FileCheck %s --check-prefix DEBUGLINE - - CHECK-NOT: error: DEBUGINFO: DW_TAG_subprogram diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-str-offsets-base-strx.test b/llvm/test/tools/dsymutil/ARM/dwarf5-str-offsets-base-strx.test index ac813fc620370..4765d02a13f1a 100644 --- a/llvm/test/tools/dsymutil/ARM/dwarf5-str-offsets-base-strx.test +++ b/llvm/test/tools/dsymutil/ARM/dwarf5-str-offsets-base-strx.test @@ -1,8 +1,4 @@ ; This test checks to ensure that if three DWARFv5 object files have correct values for the DW_AT_str_offsets_base and DW_FORM_strx for strings in their compile units. -; DWARFLinkerParallel specific : DWARFLinkerParallel uses .debug_str_offsets -; table local to the compile unit. That leads to different string indexes. -; In such cases test contains both variants for indexes value: -; (indexed (0000000{{9|1}}) string = "b.cpp". ; 1.o was produced with the source file: @@ -51,21 +47,10 @@ RUN: rm -rf %t.dir && mkdir -p %t.dir RUN: dsymutil -y %p/dummy-debug-map-amr64.map -oso-prepend-path=%p/../Inputs/DWARF5-addr-base-str-off-base -o %t.dir/dwarf5-addr-base.dSYM -RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.dSYM -a --verbose | FileCheck %s --check-prefixes=CHECK,GLOBAL +RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.dSYM -a --verbose | FileCheck %s RUN: dsymutil --update -y %p/dummy-debug-map-amr64.map -oso-prepend-path=%p/../Inputs/DWARF5-addr-base-str-off-base -o %t.dir/dwarf5-addr-base.dSYM -RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.dSYM -a --verbose | FileCheck %s --check-prefixes=UPD,GLOBALUPD - -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-addr-base-str-off-base \ -RUN: -o %t.dir/dwarf5-addr-base.dSYM -RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.dSYM -a --verbose | FileCheck %s --check-prefixes=CHECK,LOCAL - -RUN: dsymutil --linker llvm --update -y %p/dummy-debug-map-amr64.map \ -RUN: -oso-prepend-path=%p/../Inputs/DWARF5-addr-base-str-off-base \ -RUN: -o %t.dir/dwarf5-addr-base.dSYM -RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.dSYM -a --verbose | FileCheck %s --check-prefixes=UPD,LOCALUPD +RUN: llvm-dwarfdump %t.dir/dwarf5-addr-base.dSYM -a --verbose | FileCheck %s --check-prefix=UPD 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 (next unit at 0x0000004e) @@ -93,19 +78,19 @@ CHECK: DW_AT_name [DW_FORM_strx] (indexed (00000008) strin CHECK: 0x0000004d: NULL -CHECK: 0x0000004e: Compile Unit: length = 0x0000004a, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x00{{00|5a}}, addr_size = 0x08 (next unit at 0x0000009c) +CHECK: 0x0000004e: Compile Unit: length = 0x0000004a, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000009c) CHECK: 0x0000005a: DW_TAG_compile_unit [1] * CHECK: DW_AT_producer [DW_FORM_strx] (indexed (00000000) string = "Apple clang version 15.0.0 (clang-1500.0.31.1)") -CHECK: DW_AT_name [DW_FORM_strx] (indexed (0000000{{9|1}}) string = "b.cpp") +CHECK: DW_AT_name [DW_FORM_strx] (indexed (00000009) string = "b.cpp") CHECK: DW_AT_LLVM_sysroot [DW_FORM_strx] (indexed (00000002) string = "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk") CHECK: DW_AT_APPLE_sdk [DW_FORM_strx] (indexed (00000003) string = "MacOSX14.0.sdk") -CHECK: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x000000{{08|34}}) +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: 0x0000007a: DW_TAG_subprogram [2] * (0x0000005a) -CHECK: DW_AT_linkage_name [DW_FORM_strx] (indexed (0000000{{a|5}}) string = "_Z4bar2i") -CHECK: DW_AT_name [DW_FORM_strx] (indexed (0000000{{b|6}}) string = "bar2") +CHECK: DW_AT_linkage_name [DW_FORM_strx] (indexed (0000000a) string = "_Z4bar2i") +CHECK: DW_AT_name [DW_FORM_strx] (indexed (0000000b) string = "bar2") CHECK: 0x0000008a: DW_TAG_formal_parameter [3] (0x0000007a) CHECK: DW_AT_name [DW_FORM_strx] (indexed (00000007) string = "a") @@ -117,22 +102,22 @@ CHECK: DW_AT_name [DW_FORM_strx] (indexed (00000008) strin CHECK: 0x0000009b: NULL -CHECK: 0x0000009c: Compile Unit: length = 0x00000043, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x00{{00|b4}}, addr_size = 0x08 (next unit at 0x000000e3) +CHECK: 0x0000009c: Compile Unit: length = 0x00000043, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x000000e3) -CHECK: 0x000000a8: DW_TAG_compile_unit {{.*}} * +CHECK: 0x000000a8: DW_TAG_compile_unit [5] * CHECK: DW_AT_producer [DW_FORM_strx] (indexed (00000000) string = "Apple clang version 15.0.0 (clang-1500.0.31.1)") -CHECK: DW_AT_name [DW_FORM_strx] (indexed (0000000{{c|1}}) string = "c.cpp") +CHECK: DW_AT_name [DW_FORM_strx] (indexed (0000000c) string = "c.cpp") CHECK: DW_AT_LLVM_sysroot [DW_FORM_strx] (indexed (00000002) string = "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk") CHECK: DW_AT_APPLE_sdk [DW_FORM_strx] (indexed (00000003) string = "MacOSX14.0.sdk") -CHECK: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x000000{{08|60}}) +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: 0x000000c1: DW_TAG_subprogram [2] * (0x000000a8) -CHECK: DW_AT_linkage_name [DW_FORM_strx] (indexed (0000000{{d|5}}) string = "_Z3bazi") -CHECK: DW_AT_name [DW_FORM_strx] (indexed (0000000{{e|6}}) string = "baz") +CHECK: DW_AT_linkage_name [DW_FORM_strx] (indexed (0000000d) string = "_Z3bazi") +CHECK: DW_AT_name [DW_FORM_strx] (indexed (0000000e) string = "baz") CHECK: 0x000000d1: DW_TAG_formal_parameter [3] (0x000000c1) -CHECK: DW_AT_name [DW_FORM_strx] (indexed (0000000{{f|7}}) string = "x") +CHECK: DW_AT_name [DW_FORM_strx] (indexed (0000000f) string = "x") CHECK: 0x000000dd: NULL @@ -160,57 +145,24 @@ CHECK-NEXT: 0x0000011d: "_Z3bazi" CHECK-NEXT: 0x00000125: "baz" CHECK-NEXT: 0x00000129: "x" -GLOBAL: .debug_str_offsets contents: -GLOBAL-NEXT: 0x00000000: Contribution size = 68, Format = DWARF32, Version = 5 -GLOBAL-NEXT: 0x00000008: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" -GLOBAL-NEXT: 0x0000000c: 00000030 "a.cpp" -GLOBAL-NEXT: 0x00000010: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" -GLOBAL-NEXT: 0x00000014: 000000b7 "MacOSX14.0.sdk" -GLOBAL-NEXT: 0x00000018: 000000c6 "/Users/shubham/Development/test109275485" -GLOBAL-NEXT: 0x0000001c: 000000ef "_Z4foo2i" -GLOBAL-NEXT: 0x00000020: 000000f8 "foo2" -GLOBAL-NEXT: 0x00000024: 000000fd "a" -GLOBAL-NEXT: 0x00000028: 000000ff "int" -GLOBAL-NEXT: 0x0000002c: 00000103 "b.cpp" -GLOBAL-NEXT: 0x00000030: 00000109 "_Z4bar2i" -GLOBAL-NEXT: 0x00000034: 00000112 "bar2" -GLOBAL-NEXT: 0x00000038: 00000117 "c.cpp" -GLOBAL-NEXT: 0x0000003c: 0000011d "_Z3bazi" -GLOBAL-NEXT: 0x00000040: 00000125 "baz" -GLOBAL-NEXT: 0x00000044: 00000129 "x" - -LOCAL: .debug_str_offsets contents: -LOCAL-NEXT: 0x00000000: Contribution size = 40, Format = DWARF32, Version = 5 -LOCAL-NEXT: 0x00000008: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" -LOCAL-NEXT: 0x0000000c: 00000030 "a.cpp" -LOCAL-NEXT: 0x00000010: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" -LOCAL-NEXT: 0x00000014: 000000b7 "MacOSX14.0.sdk" -LOCAL-NEXT: 0x00000018: 000000c6 "/Users/shubham/Development/test109275485" -LOCAL-NEXT: 0x0000001c: 000000ef "_Z4foo2i" -LOCAL-NEXT: 0x00000020: 000000f8 "foo2" -LOCAL-NEXT: 0x00000024: 000000fd "a" -LOCAL-NEXT: 0x00000028: 000000ff "int" -LOCAL-NEXT: 0x0000002c: Contribution size = 40, Format = DWARF32, Version = 5 -LOCAL-NEXT: 0x00000034: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" -LOCAL-NEXT: 0x00000038: 00000103 "b.cpp" -LOCAL-NEXT: 0x0000003c: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" -LOCAL-NEXT: 0x00000040: 000000b7 "MacOSX14.0.sdk" -LOCAL-NEXT: 0x00000044: 000000c6 "/Users/shubham/Development/test109275485" -LOCAL-NEXT: 0x00000048: 00000109 "_Z4bar2i" -LOCAL-NEXT: 0x0000004c: 00000112 "bar2" -LOCAL-NEXT: 0x00000050: 000000fd "a" -LOCAL-NEXT: 0x00000054: 000000ff "int" -LOCAL-NEXT: 0x00000058: Contribution size = 40, Format = DWARF32, Version = 5 -LOCAL-NEXT: 0x00000060: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" -LOCAL-NEXT: 0x00000064: 00000117 "c.cpp" -LOCAL-NEXT: 0x00000068: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" -LOCAL-NEXT: 0x0000006c: 000000b7 "MacOSX14.0.sdk" -LOCAL-NEXT: 0x00000070: 000000c6 "/Users/shubham/Development/test109275485" -LOCAL-NEXT: 0x00000074: 0000011d "_Z3bazi" -LOCAL-NEXT: 0x00000078: 00000125 "baz" -LOCAL-NEXT: 0x0000007c: 00000129 "x" -LOCAL-NEXT: 0x00000080: 000000ff "int" - +CHECK: .debug_str_offsets contents: +CHECK-NEXT: 0x00000000: Contribution size = 68, Format = DWARF32, Version = 5 +CHECK-NEXT: 0x00000008: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" +CHECK-NEXT: 0x0000000c: 00000030 "a.cpp" +CHECK-NEXT: 0x00000010: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" +CHECK-NEXT: 0x00000014: 000000b7 "MacOSX14.0.sdk" +CHECK-NEXT: 0x00000018: 000000c6 "/Users/shubham/Development/test109275485" +CHECK-NEXT: 0x0000001c: 000000ef "_Z4foo2i" +CHECK-NEXT: 0x00000020: 000000f8 "foo2" +CHECK-NEXT: 0x00000024: 000000fd "a" +CHECK-NEXT: 0x00000028: 000000ff "int" +CHECK-NEXT: 0x0000002c: 00000103 "b.cpp" +CHECK-NEXT: 0x00000030: 00000109 "_Z4bar2i" +CHECK-NEXT: 0x00000034: 00000112 "bar2" +CHECK-NEXT: 0x00000038: 00000117 "c.cpp" +CHECK-NEXT: 0x0000003c: 0000011d "_Z3bazi" +CHECK-NEXT: 0x00000040: 00000125 "baz" +CHECK-NEXT: 0x00000044: 00000129 "x" UPD: .debug_info contents: UPD: 0x00000000: Compile Unit: length = 0x00000081, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000085) @@ -253,23 +205,23 @@ UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000e) string UPD: 0x00000084: NULL -UPD: 0x00000085: Compile Unit: length = 0x00000072, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x00{{00|99}}, addr_size = 0x08 (next unit at 0x000000fb) +UPD: 0x00000085: Compile Unit: length = 0x00000072, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x000000fb) UPD: 0x00000091: DW_TAG_compile_unit [1] * UPD: DW_AT_producer [DW_FORM_strx] (indexed (00000000) string = "Apple clang version 15.0.0 (clang-1500.0.31.1)") -UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000{{f|1}}) string = "b.cpp") +UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000f) string = "b.cpp") UPD: DW_AT_LLVM_sysroot [DW_FORM_strx] (indexed (00000002) string = "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk") UPD: DW_AT_APPLE_sdk [DW_FORM_strx] (indexed (00000003) string = "MacOSX14.0.sdk") -UPD: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x000000{{08|4c}}) +UPD: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008) UPD: DW_AT_comp_dir [DW_FORM_strx] (indexed (00000004) string = "/Users/shubham/Development/test109275485") UPD: 0x000000b6: DW_TAG_subprogram [2] (0x00000091) -UPD: DW_AT_linkage_name [DW_FORM_strx] (indexed (000000{{10|05}}) string = "_Z3barv") -UPD: DW_AT_name [DW_FORM_strx] (indexed (000000{{11|06}}) string = "bar") +UPD: DW_AT_linkage_name [DW_FORM_strx] (indexed (00000010) string = "_Z3barv") +UPD: DW_AT_name [DW_FORM_strx] (indexed (00000011) string = "bar") UPD: 0x000000c2: DW_TAG_subprogram [3] * (0x00000091) -UPD: DW_AT_linkage_name [DW_FORM_strx] (indexed (000000{{12|07}}) string = "_Z4bar2i") -UPD: DW_AT_name [DW_FORM_strx] (indexed (000000{{13|08}}) string = "bar2") +UPD: DW_AT_linkage_name [DW_FORM_strx] (indexed (00000012) string = "_Z4bar2i") +UPD: DW_AT_name [DW_FORM_strx] (indexed (00000013) string = "bar2") UPD: 0x000000d2: DW_TAG_formal_parameter [4] (0x000000c2) UPD: DW_AT_name [DW_FORM_strx] (indexed (00000009) string = "a") @@ -277,40 +229,40 @@ UPD: DW_AT_name [DW_FORM_strx] (indexed (00000009) string UPD: 0x000000db: NULL UPD: 0x000000dc: DW_TAG_subprogram [3] * (0x00000091) -UPD: DW_AT_linkage_name [DW_FORM_strx] (indexed (000000{{14|0a}}) string = "_Z4bar3i") -UPD: DW_AT_name [DW_FORM_strx] (indexed (000000{{15|0b}}) string = "bar3") +UPD: DW_AT_linkage_name [DW_FORM_strx] (indexed (00000014) string = "_Z4bar3i") +UPD: DW_AT_name [DW_FORM_strx] (indexed (00000015) string = "bar3") UPD: 0x000000ec: DW_TAG_formal_parameter [4] (0x000000dc) UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000c) string = "x") UPD: 0x000000f5: NULL -UPD: 0x000000f6: DW_TAG_base_type {{.*}} (0x00000091) -UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000{{e|d}}) string = "int") +UPD: 0x000000f6: DW_TAG_base_type [6] (0x00000091) +UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000e) string = "int") UPD: 0x000000fa: NULL -UPD: 0x000000fb: Compile Unit: length = 0x00000044, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0{{000|115}}, addr_size = 0x08 (next unit at 0x00000143) +UPD: 0x000000fb: Compile Unit: length = 0x00000044, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000143) -UPD: 0x00000107: DW_TAG_compile_unit {{.*}} * +UPD: 0x00000107: DW_TAG_compile_unit [7] * UPD: DW_AT_producer [DW_FORM_strx] (indexed (00000000) string = "Apple clang version 15.0.0 (clang-1500.0.31.1)") -UPD: DW_AT_name [DW_FORM_strx] (indexed (000000{{16|01}}) string = "c.cpp") +UPD: DW_AT_name [DW_FORM_strx] (indexed (00000016) string = "c.cpp") UPD: DW_AT_LLVM_sysroot [DW_FORM_strx] (indexed (00000002) string = "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk") UPD: DW_AT_APPLE_sdk [DW_FORM_strx] (indexed (00000003) string = "MacOSX14.0.sdk") -UPD: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x000000{{08|8c}}) +UPD: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008) UPD: DW_AT_comp_dir [DW_FORM_strx] (indexed (00000004) string = "/Users/shubham/Development/test109275485") -UPD: 0x00000124: DW_TAG_subprogram {{.*}} * (0x00000107) -UPD: DW_AT_linkage_name [DW_FORM_strx] (indexed (000000{{17|05}}) string = "_Z3bazi") -UPD: DW_AT_name [DW_FORM_strx] (indexed (000000{{18|06}}) string = "baz") +UPD: 0x00000124: DW_TAG_subprogram [3] * (0x00000107) +UPD: DW_AT_linkage_name [DW_FORM_strx] (indexed (00000017) string = "_Z3bazi") +UPD: DW_AT_name [DW_FORM_strx] (indexed (00000018) string = "baz") -UPD: 0x00000134: DW_TAG_formal_parameter {{.*}} (0x00000124) -UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000{{c|7}}) string = "x") +UPD: 0x00000134: DW_TAG_formal_parameter [4] (0x00000124) +UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000c) string = "x") UPD: 0x0000013d: NULL -UPD: 0x0000013e: DW_TAG_base_type {{.*}} (0x00000107) -UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000{{e|8}}) string = "int") +UPD: 0x0000013e: DW_TAG_base_type [6] (0x00000107) +UPD: DW_AT_name [DW_FORM_strx] (indexed (0000000e) string = "int") UPD: 0x00000142: NULL @@ -342,73 +294,30 @@ UPD-NEXT: 0x00000152: "c.cpp" UPD-NEXT: 0x00000158: "_Z3bazi" UPD-NEXT: 0x00000160: "baz" -GLOBALUPD: .debug_str_offsets contents: -GLOBALUPD-NEXT: 0x00000000: Contribution size = 104, Format = DWARF32, Version = 5 -GLOBALUPD-NEXT: 0x00000008: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" -GLOBALUPD-NEXT: 0x0000000c: 00000030 "a.cpp" -GLOBALUPD-NEXT: 0x00000010: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" -GLOBALUPD-NEXT: 0x00000014: 000000b7 "MacOSX14.0.sdk" -GLOBALUPD-NEXT: 0x00000018: 000000c6 "/Users/shubham/Development/test109275485" -GLOBALUPD-NEXT: 0x0000001c: 000000ef "_Z3foov" -GLOBALUPD-NEXT: 0x00000020: 000000f7 "foo" -GLOBALUPD-NEXT: 0x00000024: 000000fb "_Z4foo2i" -GLOBALUPD-NEXT: 0x00000028: 00000104 "foo2" -GLOBALUPD-NEXT: 0x0000002c: 00000109 "a" -GLOBALUPD-NEXT: 0x00000030: 0000010b "_Z4foo3i" -GLOBALUPD-NEXT: 0x00000034: 00000114 "foo3" -GLOBALUPD-NEXT: 0x00000038: 00000119 "x" -GLOBALUPD-NEXT: 0x0000003c: 0000011b "main" -GLOBALUPD-NEXT: 0x00000040: 00000120 "int" -GLOBALUPD-NEXT: 0x00000044: 00000124 "b.cpp" -GLOBALUPD-NEXT: 0x00000048: 0000012a "_Z3barv" -GLOBALUPD-NEXT: 0x0000004c: 00000132 "bar" -GLOBALUPD-NEXT: 0x00000050: 00000136 "_Z4bar2i" -GLOBALUPD-NEXT: 0x00000054: 0000013f "bar2" -GLOBALUPD-NEXT: 0x00000058: 00000144 "_Z4bar3i" -GLOBALUPD-NEXT: 0x0000005c: 0000014d "bar3" -GLOBALUPD-NEXT: 0x00000060: 00000152 "c.cpp" -GLOBALUPD-NEXT: 0x00000064: 00000158 "_Z3bazi" -GLOBALUPD-NEXT: 0x00000068: 00000160 "baz" - -LOCALUPD: .debug_str_offsets contents: -LOCALUPD-NEXT: 0x00000000: Contribution size = 64, Format = DWARF32, Version = 5 -LOCALUPD-NEXT: 0x00000008: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" -LOCALUPD-NEXT: 0x0000000c: 00000030 "a.cpp" -LOCALUPD-NEXT: 0x00000010: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" -LOCALUPD-NEXT: 0x00000014: 000000b7 "MacOSX14.0.sdk" -LOCALUPD-NEXT: 0x00000018: 000000c6 "/Users/shubham/Development/test109275485" -LOCALUPD-NEXT: 0x0000001c: 000000ef "_Z3foov" -LOCALUPD-NEXT: 0x00000020: 000000f7 "foo" -LOCALUPD-NEXT: 0x00000024: 000000fb "_Z4foo2i" -LOCALUPD-NEXT: 0x00000028: 00000104 "foo2" -LOCALUPD-NEXT: 0x0000002c: 00000109 "a" -LOCALUPD-NEXT: 0x00000030: 0000010b "_Z4foo3i" -LOCALUPD-NEXT: 0x00000034: 00000114 "foo3" -LOCALUPD-NEXT: 0x00000038: 00000119 "x" -LOCALUPD-NEXT: 0x0000003c: 0000011b "main" -LOCALUPD-NEXT: 0x00000040: 00000120 "int" -LOCALUPD-NEXT: 0x00000044: Contribution size = 60, Format = DWARF32, Version = 5 -LOCALUPD-NEXT: 0x0000004c: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" -LOCALUPD-NEXT: 0x00000050: 00000124 "b.cpp" -LOCALUPD-NEXT: 0x00000054: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" -LOCALUPD-NEXT: 0x00000058: 000000b7 "MacOSX14.0.sdk" -LOCALUPD-NEXT: 0x0000005c: 000000c6 "/Users/shubham/Development/test109275485" -LOCALUPD-NEXT: 0x00000060: 0000012a "_Z3barv" -LOCALUPD-NEXT: 0x00000064: 00000132 "bar" -LOCALUPD-NEXT: 0x00000068: 00000136 "_Z4bar2i" -LOCALUPD-NEXT: 0x0000006c: 0000013f "bar2" -LOCALUPD-NEXT: 0x00000070: 00000109 "a" -LOCALUPD-NEXT: 0x00000074: 00000144 "_Z4bar3i" -LOCALUPD-NEXT: 0x00000078: 0000014d "bar3" -LOCALUPD-NEXT: 0x0000007c: 00000119 "x" -LOCALUPD-NEXT: 0x00000080: 00000120 "int" -LOCALUPD-NEXT: 0x00000084: Contribution size = 40, Format = DWARF32, Version = 5 -LOCALUPD-NEXT: 0x0000008c: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" -LOCALUPD-NEXT: 0x00000090: 00000152 "c.cpp" -LOCALUPD-NEXT: 0x00000094: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" -LOCALUPD-NEXT: 0x00000098: 000000b7 "MacOSX14.0.sdk" -LOCALUPD-NEXT: 0x0000009c: 000000c6 "/Users/shubham/Development/test109275485" -LOCALUPD-NEXT: 0x000000a0: 00000158 "_Z3bazi" -LOCALUPD-NEXT: 0x000000a4: 00000160 "baz" -LOCALUPD-NEXT: 0x000000a8: 00000119 "x" -LOCALUPD-NEXT: 0x000000ac: 00000120 "int" +UPD: .debug_str_offsets contents: +UPD-NEXT: 0x00000000: Contribution size = 104, Format = DWARF32, Version = 5 +UPD-NEXT: 0x00000008: 00000001 "Apple clang version 15.0.0 (clang-1500.0.31.1)" +UPD-NEXT: 0x0000000c: 00000030 "a.cpp" +UPD-NEXT: 0x00000010: 00000036 "/Users/shubham/apple-internal/Xcode-Rainbow/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" +UPD-NEXT: 0x00000014: 000000b7 "MacOSX14.0.sdk" +UPD-NEXT: 0x00000018: 000000c6 "/Users/shubham/Development/test109275485" +UPD-NEXT: 0x0000001c: 000000ef "_Z3foov" +UPD-NEXT: 0x00000020: 000000f7 "foo" +UPD-NEXT: 0x00000024: 000000fb "_Z4foo2i" +UPD-NEXT: 0x00000028: 00000104 "foo2" +UPD-NEXT: 0x0000002c: 00000109 "a" +UPD-NEXT: 0x00000030: 0000010b "_Z4foo3i" +UPD-NEXT: 0x00000034: 00000114 "foo3" +UPD-NEXT: 0x00000038: 00000119 "x" +UPD-NEXT: 0x0000003c: 0000011b "main" +UPD-NEXT: 0x00000040: 00000120 "int" +UPD-NEXT: 0x00000044: 00000124 "b.cpp" +UPD-NEXT: 0x00000048: 0000012a "_Z3barv" +UPD-NEXT: 0x0000004c: 00000132 "bar" +UPD-NEXT: 0x00000050: 00000136 "_Z4bar2i" +UPD-NEXT: 0x00000054: 0000013f "bar2" +UPD-NEXT: 0x00000058: 00000144 "_Z4bar3i" +UPD-NEXT: 0x0000005c: 0000014d "bar3" +UPD-NEXT: 0x00000060: 00000152 "c.cpp" +UPD-NEXT: 0x00000064: 00000158 "_Z3bazi" +UPD-NEXT: 0x00000068: 00000160 "baz" diff --git a/llvm/test/tools/dsymutil/ARM/empty-map.test b/llvm/test/tools/dsymutil/ARM/empty-map.test index 2668d46ed6d7d..d80311e5f5c31 100644 --- a/llvm/test/tools/dsymutil/ARM/empty-map.test +++ b/llvm/test/tools/dsymutil/ARM/empty-map.test @@ -1,7 +1,5 @@ # RUN: dsymutil -f -oso-prepend-path=%p/../Inputs -y %s -o - 2>&1 | FileCheck %s -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../Inputs -y %s -o - 2>&1 | FileCheck %s - --- triple: 'thumbv7-apple-darwin' ... diff --git a/llvm/test/tools/dsymutil/ARM/extern-alias.test b/llvm/test/tools/dsymutil/ARM/extern-alias.test index f8b59584d2b46..cb459fbd66289 100644 --- a/llvm/test/tools/dsymutil/ARM/extern-alias.test +++ b/llvm/test/tools/dsymutil/ARM/extern-alias.test @@ -37,10 +37,6 @@ $ xcrun --sdk iphoneos clang private_extern.o main.o -target arm64-apple-ios14.0 RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/private_extern/private_extern.out -o %t.dSYM --verbose | FileCheck %s RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/extern/extern.out -o %t.dSYM --verbose | FileCheck %s - -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/private_extern/private_extern.out -o %t.dSYM --verbose | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/extern/extern.out -o %t.dSYM --verbose | FileCheck %s - CHECK-NOT: could not find object file symbol for symbol _baz CHECK: { sym: _baz, objAddr: 0x0, binAddr: 0x100007F58, size: 0x0 } CHECK: { sym: _foo, objAddr: 0x0, binAddr: 0x100007F58, size: 0x20 } diff --git a/llvm/test/tools/dsymutil/ARM/fat-arch-name.test b/llvm/test/tools/dsymutil/ARM/fat-arch-name.test index 4840de13af582..4f7866d4d22de 100644 --- a/llvm/test/tools/dsymutil/ARM/fat-arch-name.test +++ b/llvm/test/tools/dsymutil/ARM/fat-arch-name.test @@ -1,7 +1,5 @@ # RUN: dsymutil -no-output %p/../Inputs/fat-test.arm.dylib -o /dev/null -verbose 2>&1 | FileCheck %s -# RUN: dsymutil --linker llvm -no-output %p/../Inputs/fat-test.arm.dylib -o /dev/null -verbose 2>&1 | FileCheck %s - # We detect thumb triples from the binaries, because those are the only ones # that are guaranteed to be able to generate a Target instance (for example # we would detect armv7m-apple-darwin as non-thumb triple, but you can't diff --git a/llvm/test/tools/dsymutil/ARM/fat-arch-not-found.test b/llvm/test/tools/dsymutil/ARM/fat-arch-not-found.test index 59d2ccc783840..b223299204aab 100644 --- a/llvm/test/tools/dsymutil/ARM/fat-arch-not-found.test +++ b/llvm/test/tools/dsymutil/ARM/fat-arch-not-found.test @@ -1,6 +1,4 @@ # RUN: dsymutil -f -oso-prepend-path=%p/../Inputs -y %s -o - 2>&1 | FileCheck %s -# -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../Inputs -y %s -o - 2>&1 | FileCheck %s --- triple: 'armv7-apple-darwin' diff --git a/llvm/test/tools/dsymutil/ARM/inlined-low_pc.c b/llvm/test/tools/dsymutil/ARM/inlined-low_pc.c index 9cd10be1ec3cf..99fe0450dc834 100644 --- a/llvm/test/tools/dsymutil/ARM/inlined-low_pc.c +++ b/llvm/test/tools/dsymutil/ARM/inlined-low_pc.c @@ -5,10 +5,6 @@ int bar(int a) { return foo(a); } // RUN: dsymutil -f -y %p/dummy-debug-map-amr64.map -oso-prepend-path %p/../Inputs/inlined-low_pc -o - | llvm-dwarfdump - | FileCheck %s -// RUN: dsymutil --linker llvm -f -y %p/dummy-debug-map-amr64.map \ -// RUN: -oso-prepend-path %p/../Inputs/inlined-low_pc -o - | \ -// RUN: llvm-dwarfdump - | FileCheck %s - // CHECK: DW_TAG_subprogram // CHECK: DW_AT_low_pc{{.*}}0x0000000000010000 // CHECK: DW_AT_name{{.*}}"bar" diff --git a/llvm/test/tools/dsymutil/ARM/preload.test b/llvm/test/tools/dsymutil/ARM/preload.test index 2d1ac9b455d1b..3caa4a22c4a03 100644 --- a/llvm/test/tools/dsymutil/ARM/preload.test +++ b/llvm/test/tools/dsymutil/ARM/preload.test @@ -7,9 +7,4 @@ $ xcrun clang -o foo foo.o -g3 -Wl,-preload -nodefaultlibs RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/preload/foo -o %t.dSYM RUN: llvm-nm %p/../Inputs/private/tmp/preload/foo | FileCheck %s RUN: llvm-nm %t.dSYM/Contents/Resources/DWARF/foo | FileCheck %s - -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/preload/foo -o %t.dSYM -RUN: llvm-nm %p/../Inputs/private/tmp/preload/foo | FileCheck %s -RUN: llvm-nm %t.dSYM/Contents/Resources/DWARF/foo | FileCheck %s - CHECK: start diff --git a/llvm/test/tools/dsymutil/ARM/scattered.c b/llvm/test/tools/dsymutil/ARM/scattered.c index 75076f96cadd8..81082bcd736bf 100644 --- a/llvm/test/tools/dsymutil/ARM/scattered.c +++ b/llvm/test/tools/dsymutil/ARM/scattered.c @@ -1,10 +1,4 @@ -RUN: dsymutil -y %p/dummy-debug-map.map -oso-prepend-path \ -RUN: %p/../Inputs/scattered-reloc/ -f -o - | \ -RUN: llvm-dwarfdump -debug-info - | FileCheck %s - -RUN: dsymutil --linker llvm -y %p/dummy-debug-map.map \ -RUN: -oso-prepend-path %p/../Inputs/scattered-reloc/ -f -o - \ -RUN: | llvm-dwarfdump -debug-info - | FileCheck %s +RUN: dsymutil -y %p/dummy-debug-map.map -oso-prepend-path %p/../Inputs/scattered-reloc/ -f -o - | llvm-dwarfdump -debug-info - | FileCheck %s // See Inputs/scattered-reloc/scattered.s to see how this test // actually works. diff --git a/llvm/test/tools/dsymutil/ARM/thumb.c b/llvm/test/tools/dsymutil/ARM/thumb.c index 205ddd0710684..81602d17e8776 100644 --- a/llvm/test/tools/dsymutil/ARM/thumb.c +++ b/llvm/test/tools/dsymutil/ARM/thumb.c @@ -1,11 +1,6 @@ // RUN: dsymutil -f -oso-prepend-path=%p/.. %p/../Inputs/thumb.armv7m -o - | llvm-dwarfdump - | FileCheck %s // RUN: dsymutil -arch armv7m -f -oso-prepend-path=%p/.. %p/../Inputs/thumb.armv7m -o - | llvm-dwarfdump - | FileCheck %s -// RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/.. \ -// RUN: %p/../Inputs/thumb.armv7m -o - | llvm-dwarfdump - | FileCheck %s -// RUN: dsymutil --linker llvm -arch armv7m -f -oso-prepend-path=%p/.. \ -// RUN: %p/../Inputs/thumb.armv7m -o - | llvm-dwarfdump - | FileCheck %s - /* Compile with: clang -c thumb.c -arch armv7m -g clang thumb.o -o thumb.armv7m -arch armv7m -nostdlib -static -Wl,-e,_start 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 index ae92280840e79..0000000000000 --- 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 index b65529e487237..ba5bc6f4a3e50 100644 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-linking-x86.test +++ b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/basic-linking-x86.test @@ -1,190 +1,4 @@ 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 +RUN: dsymutil --linker llvm --no-output -accelerator=Pub -f -oso-prepend-path=%p/../.. %t1 2>&1 | FileCheck %s --allow-empty -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 +#CHECK: LLVM parallel dwarflinker is not implemented yet. 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 index 75a85d82b4ef2..0000000000000 --- 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 index 2c936530a85a1..0000000000000 --- 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 index 21ddd3b5d2951..0000000000000 --- 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/empty_range.s b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/empty_range.s deleted file mode 100644 index 603867250d3b7..0000000000000 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/empty_range.s +++ /dev/null @@ -1,53 +0,0 @@ -# This test verifies that an empty range list in the .debug_ranges section -# doesn't crash dsymutil. As clang does not produce this kind of debug -# info anymore, we used this hand-crafted assembly file to produce a testcase -# Compile with: -# llvm-mc -triple x86_64-apple-darwin -filetype=obj -o 1.o empty_range.o - -# RUN: dsymutil --linker llvm -f -y %p/../dummy-debug-map.map -oso-prepend-path %p/../../Inputs/empty_range -o - | llvm-dwarfdump -debug-info - | FileCheck %s - - .section __TEXT,__text,regular,pure_instructions - .macosx_version_min 10, 11 - .globl __Z3foov - .align 4, 0x90 -__Z3foov: ## @_Z3foov -Lfunc_begin0: - pushq %rbp - movq %rsp, %rbp - popq %rbp - retq -Lfunc_end0: - .section __DWARF,__debug_abbrev,regular,debug -Lsection_abbrev: - .byte 1 ## Abbreviation Code - .byte 17 ## DW_TAG_compile_unit - .byte 1 ## DW_CHILDREN_yes - .byte 0 ## EOM(1) - .byte 0 ## EOM(2) - .byte 2 ## Abbreviation Code - .byte 46 ## DW_TAG_subprogram - .byte 0 ## DW_CHILDREN_no - .byte 17 ## DW_AT_low_pc - .byte 1 ## DW_FORM_addr - .byte 0x55 ## DW_AT_ranges - .byte 6 ## DW_FORM_data4 - .byte 0 ## EOM(1) - .byte 0 ## EOM(2) - .byte 0 ## EOM(3) - .section __DWARF,__debug_info,regular,debug -Lsection_info: - .long 22 ## Length of Unit - .short 2 ## DWARF version number - .long 0 ## Offset Into Abbrev. Section - .byte 8 ## Address Size (in bytes) - .byte 1 ## Abbrev [1] DW_TAG_compile_unit - .byte 2 ## Abbrev [2] DW_TAG_subprogram - .quad Lfunc_begin0 ## DW_AT_low_pc - .long 0 ## DW_AT_ranges (pointing at an empty entry) - .byte 0 ## End Of Children Mark - .section __DWARF,__debug_ranges,regular,debug -Ldebug_range: - .long 0 - .long 0 - -# CHECK-NOT: DW_TAG_compile_unit diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/frame-1.test b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/frame-1.test deleted file mode 100644 index dbdbb455eab16..0000000000000 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/frame-1.test +++ /dev/null @@ -1,36 +0,0 @@ -# RUN: rm -rf %t -# RUN: mkdir -p %t -# RUN: llc -filetype=obj %p/../../Inputs/frame-dw2.ll -o %t/frame-dw2.o -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%t -y %s -o - | \ -# RUN: llvm-dwarfdump -debug-frame - | FileCheck %s - -# This test is meant to verify that identical CIEs will get reused -# in the same file but not inbetween files. For this to happen, we -# link twice the same file using this made-up debug map: - ---- -triple: 'i386-apple-darwin' -objects: - - filename: frame-dw2.o - symbols: - - { sym: _bar, objAddr: 0x0, binAddr: 0x1000, size: 0x12 } - - { sym: _baz, objAddr: 0x0, binAddr: 0x2000, size: 0x12 } - - filename: frame-dw2.o - symbols: - - { sym: _bar, objAddr: 0x0, binAddr: 0x3000, size: 0x12 } - - { sym: _baz, objAddr: 0x0, binAddr: 0x4000, size: 0x12 } -... - -# CHECK: .debug_frame contents: -# CHECK: 00000000 {{[0-9a-f]*}} ffffffff CIE -# CHECK-NOT: FDE -# CHECK: FDE cie=00000000 pc=00001000...00001 -# CHECK-NOT: FDE -# CHECK: FDE cie=00000000 pc=00002000...00002 -# CHECK: [[CIECU2:[0-9a-f]*]] {{[0-9a-f]*}} ffffffff CIE -# CHECK-NOT: FDE -# CHECK: FDE cie=[[CIECU2]] pc=00003000...00003 -# CHECK-NOT: FDE -# CHECK: FDE cie=[[CIECU2]] pc=00004000...00004 -# CHECK-NOT: FDE -# CHECK: .eh_frame contents: diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/frame-2.test b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/frame-2.test deleted file mode 100644 index ffb559050dabb..0000000000000 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/frame-2.test +++ /dev/null @@ -1,46 +0,0 @@ -# RUN: rm -rf %t -# RUN: mkdir -p %t -# RUN: llc -filetype=obj %p/../../Inputs/frame-dw2.ll -o %t/frame-dw2.o -# RUN: llc -filetype=obj %p/../../Inputs/frame-dw4.ll -o %t/frame-dw4.o -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%t -y %s -o - | \ -# RUN: llvm-dwarfdump -debug-frame - | FileCheck %s - -# Check the handling of multiple different CIEs. To have CIEs that -# appear to be different, use a dwarf2 version of the file along with -# a dwarf 4 version. The CIE header version (and layout) will be different. ---- -triple: 'i386-apple-darwin' -objects: - - filename: frame-dw2.o - symbols: - - { sym: _bar, objAddr: 0x0, binAddr: 0x1000, size: 0x12 } - - { sym: _baz, objAddr: 0x0, binAddr: 0x2000, size: 0x12 } - - filename: frame-dw4.o - symbols: - - { sym: _baz, objAddr: 0x0, binAddr: 0x3000, size: 0x12 } - - filename: frame-dw2.o - symbols: - - { sym: _bar, objAddr: 0x0, binAddr: 0x4000, size: 0x12 } -... - -# CHECK: .debug_frame contents: -# CHECK: 00000000 {{[0-9a-f]*}} ffffffff CIE -# CHECK-NEXT: Format: DWARF32 -# CHECK-NEXT: Version:{{.*}}1 -# CHECK-NOT: FDE -# CHECK: FDE cie=00000000 pc=00001000...00001 -# CHECK-NOT: FDE -# CHECK: FDE cie=00000000 pc=00002000...00002 -# CHECK-NOT: FDE -# CHECK: [[CIEDW4:[0-9a-f]*]] 00000010 ffffffff CIE -# CHECK-NEXT: Format: DWARF32 -# CHECK-NEXT: Version:{{.*}}4 -# CHECK-NOT: FDE -# CHECK: FDE cie=[[CIEDW4]] pc=00003000...00003 -# CHECK: [[CIEDW1_2:[0-9a-f]*]] 00000010 ffffffff CIE -# CHECK-NEXT: Format: DWARF32 -# CHECK-NEXT: Version:{{.*}}1 -# CHECK-NOT: FDE -# CHECK: FDE cie=[[CIEDW1_2]] pc=00004000...00004 -# CHECK-NOT: FDE -# CHECK: .eh_frame contents: 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 index 9adcdcbc4ba71..0000000000000 --- 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/alias.test b/llvm/test/tools/dsymutil/X86/alias.test index 4c1e816870609..2e56ba5719b15 100644 --- a/llvm/test/tools/dsymutil/X86/alias.test +++ b/llvm/test/tools/dsymutil/X86/alias.test @@ -1,9 +1,5 @@ # RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/alias \ # RUN: %p/../Inputs/alias/foobar -o - | llvm-dwarfdump - 2>&1 | FileCheck %s - -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../Inputs/alias \ -# RUN: %p/../Inputs/alias/foobar -o - | llvm-dwarfdump - 2>&1 | FileCheck %s - # CHECK-NOT: could not find object file symbol for symbol # CHECK: DW_AT_name ("foo.c") # CHECK: DW_AT_name ("bar.c") diff --git a/llvm/test/tools/dsymutil/X86/call-site-entry-linking.test b/llvm/test/tools/dsymutil/X86/call-site-entry-linking.test index 2ef400f5d7120..7eef7af41f525 100644 --- a/llvm/test/tools/dsymutil/X86/call-site-entry-linking.test +++ b/llvm/test/tools/dsymutil/X86/call-site-entry-linking.test @@ -1,7 +1,4 @@ RUN: dsymutil -oso-prepend-path=%p %p/Inputs/call-site-entry.macho.x86_64 -o %t.dSYM RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_return_pc -RUN: dsymutil --linker llvm -oso-prepend-path=%p %p/Inputs/call-site-entry.macho.x86_64 -o %t.dSYM -RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_return_pc - CHECK: DW_AT_call_return_pc (0x0000000100000fa4) diff --git a/llvm/test/tools/dsymutil/X86/call-site-entry-reloc.test b/llvm/test/tools/dsymutil/X86/call-site-entry-reloc.test index a03ce06d6545b..46e947044ffca 100644 --- a/llvm/test/tools/dsymutil/X86/call-site-entry-reloc.test +++ b/llvm/test/tools/dsymutil/X86/call-site-entry-reloc.test @@ -22,8 +22,5 @@ twice. RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/call_return_pc/call -o %t.dSYM RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_return_pc -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/call_return_pc/call -o %t.dSYM -RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_return_pc - CHECK: DW_AT_call_return_pc (0x0000000100000f72) CHECK: DW_AT_call_return_pc (0x0000000100000f78) diff --git a/llvm/test/tools/dsymutil/X86/common-sym-multi.test b/llvm/test/tools/dsymutil/X86/common-sym-multi.test index 9ce14bb541c2e..ff970a53bfecf 100644 --- a/llvm/test/tools/dsymutil/X86/common-sym-multi.test +++ b/llvm/test/tools/dsymutil/X86/common-sym-multi.test @@ -1,9 +1,6 @@ RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -f -o - | llvm-dwarfdump -debug-info - | FileCheck %s RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -dump-debug-map | FileCheck %s --check-prefix DEBUGMAP -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -f -o - | llvm-dwarfdump -debug-info - | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -dump-debug-map | FileCheck %s --check-prefix DEBUGMAP - The test was compiled from two source files: $ cd /private/tmp/common $ cat common1.c diff --git a/llvm/test/tools/dsymutil/X86/common-sym.test b/llvm/test/tools/dsymutil/X86/common-sym.test index 796866c4743ca..0f07c8f39b81a 100644 --- a/llvm/test/tools/dsymutil/X86/common-sym.test +++ b/llvm/test/tools/dsymutil/X86/common-sym.test @@ -1,7 +1,5 @@ RUN: dsymutil -oso-prepend-path %p/.. %p/../Inputs/common.macho.x86_64 -f -o - | llvm-dwarfdump -v -debug-info - | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path %p/.. %p/../Inputs/common.macho.x86_64 -f -o - | llvm-dwarfdump -v -debug-info - | FileCheck %s - The test was compiled from a single source: $ cat common.c char common[16]; diff --git a/llvm/test/tools/dsymutil/X86/custom-line-table.test b/llvm/test/tools/dsymutil/X86/custom-line-table.test index 8a164655ec21a..f75e01a12fba9 100644 --- a/llvm/test/tools/dsymutil/X86/custom-line-table.test +++ b/llvm/test/tools/dsymutil/X86/custom-line-table.test @@ -1,6 +1,4 @@ # RUN: dsymutil -oso-prepend-path %p/../Inputs -y %s -f -o - | llvm-dwarfdump - --debug-line | FileCheck %s -# -# RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs -y %s -f -o - | llvm-dwarfdump - --debug-line | FileCheck %s # This test runs dsymutil on an object file with non-standard (as far # as llvm is concerned) line table settings. diff --git a/llvm/test/tools/dsymutil/X86/darwin-bundle.test b/llvm/test/tools/dsymutil/X86/darwin-bundle.test index 80a42217edff1..d44b25e487054 100644 --- a/llvm/test/tools/dsymutil/X86/darwin-bundle.test +++ b/llvm/test/tools/dsymutil/X86/darwin-bundle.test @@ -11,13 +11,6 @@ RUN: FileCheck %s --input-file %t/dsymdest/basic.macho.x86_64.dSYM/Contents/Info RUN: dsymutil -oso-prepend-path=%p/.. %t/basic.macho.x86_64 -toolchain "toolchain&and'some CHECK-NEXT: CHECK-NEXT: diff --git a/llvm/test/tools/dsymutil/X86/dead-stripped.cpp b/llvm/test/tools/dsymutil/X86/dead-stripped.cpp index 8a72aee6fb38f..6ea5ef22a65ac 100644 --- a/llvm/test/tools/dsymutil/X86/dead-stripped.cpp +++ b/llvm/test/tools/dsymutil/X86/dead-stripped.cpp @@ -1,10 +1,5 @@ // RUN: dsymutil -f -y %p/dummy-debug-map.map -oso-prepend-path %p/../Inputs/dead-stripped -o - | llvm-dwarfdump - --debug-info | FileCheck %s --implicit-check-not "{{DW_AT_low_pc|DW_AT_high_pc|DW_AT_location|DW_TAG|NULL}}" -// RUN: dsymutil --linker llvm -f -y %p/dummy-debug-map.map -oso-prepend-path \ -// RUN: %p/../Inputs/dead-stripped -o - | llvm-dwarfdump - --debug-info | \ -// RUN: FileCheck %s --implicit-check-not \ -// RUN: "{{DW_AT_low_pc|DW_AT_high_pc|DW_AT_location|DW_TAG|NULL}}" - // The test was compiled with: // clang++ -O2 -g -c dead-strip.cpp -o 1.o diff --git a/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test b/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test index 341f64dec4090..a36e9139bcf0b 100644 --- a/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test +++ b/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test @@ -1,7 +1,5 @@ RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/baseaddr/loc1.x86_64 -f -o - | llvm-dwarfdump --debug-info - | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/baseaddr/loc1.x86_64 -f -o - | llvm-dwarfdump --debug-info - | FileCheck %s - The test was compiled from a single source: $ cat loc1.cpp int f1(int i, int j) { diff --git a/llvm/test/tools/dsymutil/X86/dwarf4-linetable.test b/llvm/test/tools/dsymutil/X86/dwarf4-linetable.test index eb3e8fb2a714b..4de68abbf062e 100644 --- a/llvm/test/tools/dsymutil/X86/dwarf4-linetable.test +++ b/llvm/test/tools/dsymutil/X86/dwarf4-linetable.test @@ -1,7 +1,5 @@ # RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/ -y %s -o - | llvm-dwarfdump -debug-line - | FileCheck %s -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../Inputs/ -y %s -o - | llvm-dwarfdump -debug-line - | FileCheck %s - # Source: # int main() { # return 0; diff --git a/llvm/test/tools/dsymutil/X86/dwarf5-addrx.test b/llvm/test/tools/dsymutil/X86/dwarf5-addrx.test index fd6197bdc5fb4..463c51a1b068e 100644 --- a/llvm/test/tools/dsymutil/X86/dwarf5-addrx.test +++ b/llvm/test/tools/dsymutil/X86/dwarf5-addrx.test @@ -52,17 +52,6 @@ RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s RUN: llvm-dwarfdump --verbose %t.dSYM | FileCheck %s --check-prefix UPDATE-DWARF -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/dwarf5/dwarf5-addrx.out -o %t.dSYM 2>&1 | FileCheck %s --allow-empty -RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s - -RUN: llvm-dwarfdump --verbose %t.dSYM | FileCheck %s --check-prefix DWARF - -RUN: dsymutil --linker llvm --update -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/dwarf5/dwarf5-addrx.out -o %t.dSYM 2>&1 | FileCheck %s --allow-empty -RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s - -RUN: llvm-dwarfdump --verbose %t.dSYM | FileCheck %s --check-prefix UPDATE-DWARF - - CHECK-NOT: error: DWARF: DW_TAG_compile_unit diff --git a/llvm/test/tools/dsymutil/X86/dwarf5-call-site-entry-reloc.test b/llvm/test/tools/dsymutil/X86/dwarf5-call-site-entry-reloc.test index bc17a456b2b4c..b960d4496ce7d 100644 --- a/llvm/test/tools/dsymutil/X86/dwarf5-call-site-entry-reloc.test +++ b/llvm/test/tools/dsymutil/X86/dwarf5-call-site-entry-reloc.test @@ -22,9 +22,6 @@ #RUN: dsymutil -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM #RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_return_pc -#RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM -#RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_return_pc - #CHECK: DW_AT_call_return_pc (0x0000000100000f72) #CHECK: DW_AT_call_return_pc (0x0000000100000f78) diff --git a/llvm/test/tools/dsymutil/X86/dwarf5-dw-op-addrx.test b/llvm/test/tools/dsymutil/X86/dwarf5-dw-op-addrx.test index f78a3102e18a5..34100145b17de 100644 --- a/llvm/test/tools/dsymutil/X86/dwarf5-dw-op-addrx.test +++ b/llvm/test/tools/dsymutil/X86/dwarf5-dw-op-addrx.test @@ -25,14 +25,6 @@ #RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s #RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix UPD-DWARF-CHECK -#RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM -#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s -#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix DWARF-CHECK - -#RUN: dsymutil --linker llvm --update -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM -#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s -#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix UPD-DWARF-CHECK - #CHECK: No errors. #DWARF-CHECK: DW_TAG_compile_unit diff --git a/llvm/test/tools/dsymutil/X86/dwarf5-linetable.test b/llvm/test/tools/dsymutil/X86/dwarf5-linetable.test index a07e13038e94b..008e133ec6301 100644 --- a/llvm/test/tools/dsymutil/X86/dwarf5-linetable.test +++ b/llvm/test/tools/dsymutil/X86/dwarf5-linetable.test @@ -1,7 +1,5 @@ # RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/ -y %s -o - | llvm-dwarfdump -debug-line -debug-line-str --verbose - | FileCheck %s -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../Inputs/ -y %s -o - | llvm-dwarfdump -debug-line -debug-line-str --verbose - | FileCheck %s - # Source: # int main() { # return 0; diff --git a/llvm/test/tools/dsymutil/X86/dwarf5-loclists.test b/llvm/test/tools/dsymutil/X86/dwarf5-loclists.test index f7133d638d32b..ccb458c35c41a 100644 --- a/llvm/test/tools/dsymutil/X86/dwarf5-loclists.test +++ b/llvm/test/tools/dsymutil/X86/dwarf5-loclists.test @@ -24,14 +24,6 @@ #RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s #RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix UPD-DWARF-CHECK -#RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM -#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s -#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix DWARF-CHECK - -#RUN: dsymutil --linker llvm --update -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM -#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s -#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix UPD-DWARF-CHECK - #CHECK: No errors. #DWARF-CHECK: DW_TAG_formal_parameter diff --git a/llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test b/llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test index b6d2f4391c70e..7603ae738f8e8 100644 --- a/llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test +++ b/llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test @@ -32,19 +32,11 @@ #RUN: dsymutil -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM #RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s #RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix DWARF-CHECK - +# #RUN: dsymutil --update -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM #RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s #RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix UPD-DWARF-CHECK -#RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM -#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s -#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix DWARF-CHECK - -#RUN: dsymutil --linker llvm --update -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM -#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s -#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix UPD-DWARF-CHECK - #CHECK: No errors. #DWARF-CHECK: DW_TAG_compile_unit diff --git a/llvm/test/tools/dsymutil/X86/eh_frame.test b/llvm/test/tools/dsymutil/X86/eh_frame.test index 08e403eedfb41..c4be843fff597 100644 --- a/llvm/test/tools/dsymutil/X86/eh_frame.test +++ b/llvm/test/tools/dsymutil/X86/eh_frame.test @@ -18,10 +18,5 @@ RUN: llvm-dwarfdump --verify %t.dSYM RUN: llvm-otool -s __TEXT __eh_frame %p/../Inputs/private/tmp/eh_frame/eh_frame.out | FileCheck %s RUN: llvm-otool -s __TEXT __eh_frame %t.dSYM/Contents/Resources/DWARF/eh_frame.out | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/eh_frame/eh_frame.out -o %t.dSYM -RUN: llvm-dwarfdump --verify %t.dSYM -RUN: llvm-otool -s __TEXT __eh_frame %p/../Inputs/private/tmp/eh_frame/eh_frame.out | FileCheck %s -RUN: llvm-otool -s __TEXT __eh_frame %t.dSYM/Contents/Resources/DWARF/eh_frame.out | FileCheck %s - CHECK: 14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01 CHECK: 10 0c 07 08 90 01 00 00 diff --git a/llvm/test/tools/dsymutil/X86/empty-CU.test b/llvm/test/tools/dsymutil/X86/empty-CU.test index db9f70874971b..7b06607a74cbc 100644 --- a/llvm/test/tools/dsymutil/X86/empty-CU.test +++ b/llvm/test/tools/dsymutil/X86/empty-CU.test @@ -1,8 +1,6 @@ RUN: llvm-mc %p/../Inputs/empty-CU.s -filetype obj -triple x86_64-apple-darwin -o %t.o RUN: dsymutil --update -f %t.o -o - | llvm-dwarfdump -v - -debug-info | FileCheck %s -RUN: dsymutil --linker llvm --update -f %t.o -o - | llvm-dwarfdump -v - -debug-info | FileCheck %s - CHECK: .debug_info contents: CHECK: 0x00000000: Compile Unit: length = 0x00000008, format = DWARF32, version = 0x0003, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x0000000c) diff --git a/llvm/test/tools/dsymutil/X86/fat-archive-input-i386.test b/llvm/test/tools/dsymutil/X86/fat-archive-input-i386.test index a2d165500b9fe..5c71f130a7f70 100644 --- a/llvm/test/tools/dsymutil/X86/fat-archive-input-i386.test +++ b/llvm/test/tools/dsymutil/X86/fat-archive-input-i386.test @@ -1,7 +1,5 @@ # RUN: dsymutil -f -oso-prepend-path=%p/../Inputs -y %s -o - | llvm-dwarfdump -debug-info - | FileCheck %s -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../Inputs -y %s -o - | llvm-dwarfdump -debug-info - | FileCheck %s - --- triple: 'i386-apple-darwin' objects: diff --git a/llvm/test/tools/dsymutil/X86/fat-object-input-x86_64.test b/llvm/test/tools/dsymutil/X86/fat-object-input-x86_64.test index 6259d11a3358f..d6cb6714be6e5 100644 --- a/llvm/test/tools/dsymutil/X86/fat-object-input-x86_64.test +++ b/llvm/test/tools/dsymutil/X86/fat-object-input-x86_64.test @@ -1,7 +1,5 @@ # RUN: dsymutil -f -oso-prepend-path=%p/../Inputs -y %s -o - | llvm-dwarfdump -debug-info - | FileCheck %s -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../Inputs -y %s -o - | llvm-dwarfdump -debug-info - | FileCheck %s - --- triple: 'x86_64-apple-darwin' objects: diff --git a/llvm/test/tools/dsymutil/X86/fat-object-input-x86_64h.test b/llvm/test/tools/dsymutil/X86/fat-object-input-x86_64h.test index 588fee9bb1092..d7200c8647cf0 100644 --- a/llvm/test/tools/dsymutil/X86/fat-object-input-x86_64h.test +++ b/llvm/test/tools/dsymutil/X86/fat-object-input-x86_64h.test @@ -1,7 +1,5 @@ # RUN: dsymutil -f -oso-prepend-path=%p/../Inputs -y %s -o - | llvm-dwarfdump -debug-info - | FileCheck %s -# RUN: dsymutil --linker llvm -f -oso-prepend-path=%p/../Inputs -y %s -o - | llvm-dwarfdump -debug-info - | FileCheck %s - --- triple: 'x86_64h-apple-darwin' objects: diff --git a/llvm/test/tools/dsymutil/X86/generate-empty-CU.test b/llvm/test/tools/dsymutil/X86/generate-empty-CU.test index aa70ca7de98b7..58afea183a2f0 100644 --- a/llvm/test/tools/dsymutil/X86/generate-empty-CU.test +++ b/llvm/test/tools/dsymutil/X86/generate-empty-CU.test @@ -1,9 +1,7 @@ # RUN: dsymutil -f -o - -oso-prepend-path=%p/.. -y %s | llvm-dwarfdump -v - | FileCheck %s -# RUN: dsymutil --linker llvm -f -o - -oso-prepend-path=%p/.. -y %s | llvm-dwarfdump -v - | FileCheck %s - # This test on links the Dwarf for an LTO binary and on purpose doesn't retain -# any symbol in the second CU out of 3. To be valid DWARF dsymutil must not +# any symbol in the second CU out of 3. To be valid DWARF ssymutil must not # generate an empty CU but omit it. --- @@ -24,12 +22,10 @@ CHECK: DW_AT_name {{.*}} "basic1.c" CHECK: DW_TAG_subprogram DW_AT_name {{.*}} "main" -CHECK: 0x00000081: Compile Unit: length = 0x00000089, format = DWARF32, version = 0x0002, abbr_offset = 0x00{{00|53}}, addr_size = 0x08 (next unit at 0x0000010e) +CHECK: 0x00000081: Compile Unit: length = 0x00000089, format = DWARF32, version = 0x0002, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000010e) CHECK: DW_TAG_compile_unit CHECK: DW_AT_name {{.*}} "basic3.c" -CHECK: DW_TAG_subprogram +CHECK: DW_TAG_subprogram [7] * CHECK: DW_AT_name {{.*}} = "bar" - -CHECK-NOT: DW_TAG_compile_unit diff --git a/llvm/test/tools/dsymutil/X86/global_downgraded_to_static.c b/llvm/test/tools/dsymutil/X86/global_downgraded_to_static.c index 28910cb0d3414..0c808a208fe9c 100644 --- a/llvm/test/tools/dsymutil/X86/global_downgraded_to_static.c +++ b/llvm/test/tools/dsymutil/X86/global_downgraded_to_static.c @@ -1,9 +1,5 @@ // REQUIRES : system-darwin -// RUN: dsymutil -oso-prepend-path %p/.. -dump-debug-map \ -// RUN: %p/../Inputs/global_downgraded_to_static.x86_64 2>&1 | FileCheck %s -// -// RUN: dsymutil --linker llvm -oso-prepend-path %p/.. -dump-debug-map \ -// RUN: %p/../Inputs/global_downgraded_to_static.x86_64 2>&1 | FileCheck %s +// RUN: dsymutil -oso-prepend-path %p/.. -dump-debug-map %p/../Inputs/global_downgraded_to_static.x86_64 2>&1 | FileCheck %s // // To build: // clang -g -c -DFILE1 global_downgraded_to_static.c -o 1.o diff --git a/llvm/test/tools/dsymutil/X86/inlined-static-variable.cpp b/llvm/test/tools/dsymutil/X86/inlined-static-variable.cpp index e933be8fd9bdb..5593b2638147e 100644 --- a/llvm/test/tools/dsymutil/X86/inlined-static-variable.cpp +++ b/llvm/test/tools/dsymutil/X86/inlined-static-variable.cpp @@ -1,10 +1,5 @@ // RUN: dsymutil -f -y %p/dummy-debug-map.map -oso-prepend-path %p/../Inputs/inlined-static-variable -o - | llvm-dwarfdump - | FileCheck %s --implicit-check-not "{{DW_AT_low_pc|DW_AT_high_pc|DW_AT_location|DW_TAG|NULL}}" -// RUN: dsymutil --linker llvm -f -y %p/dummy-debug-map.map -oso-prepend-path \ -// RUN: %p/../Inputs/inlined-static-variable -o - | llvm-dwarfdump - | \ -// RUN: FileCheck %s --implicit-check-not \ -// RUN: "{{DW_AT_low_pc|DW_AT_high_pc|DW_AT_location|DW_TAG|NULL}}" - // clang -g -c inlined-static-variable.cpp -o 4.o // The functions removed and not_removed are not in the debug map and are diff --git a/llvm/test/tools/dsymutil/X86/keep-func.test b/llvm/test/tools/dsymutil/X86/keep-func.test index f307f5ad89900..021c7212bd831 100644 --- a/llvm/test/tools/dsymutil/X86/keep-func.test +++ b/llvm/test/tools/dsymutil/X86/keep-func.test @@ -25,11 +25,6 @@ RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/keep_func/ RUN: llvm-dwarfdump %t.omit.dSYM | FileCheck %s --check-prefix OMIT RUN: llvm-dwarfdump %t.keep.dSYM | FileCheck %s --check-prefix KEEP -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/keep_func/main.out -o %t.omit.dSYM -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/keep_func/main.out -o %t.keep.dSYM -keep-function-for-static -RUN: llvm-dwarfdump %t.omit.dSYM | FileCheck %s --check-prefix OMIT -RUN: llvm-dwarfdump %t.keep.dSYM | FileCheck %s --check-prefix KEEP - KEEP: DW_AT_name ("MyDummyVar") KEEP: DW_AT_name ("FOO_VAR_TYPE") KEEP: DW_AT_name ("x1") diff --git a/llvm/test/tools/dsymutil/X86/label.test b/llvm/test/tools/dsymutil/X86/label.test index 129f603781e51..62c9d62b76b17 100644 --- a/llvm/test/tools/dsymutil/X86/label.test +++ b/llvm/test/tools/dsymutil/X86/label.test @@ -1,7 +1,5 @@ # RUN: dsymutil -oso-prepend-path %p/../Inputs -y %s -f -o - | llvm-dwarfdump - --debug-info | FileCheck %s -# RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs -y %s -f -o - | llvm-dwarfdump - --debug-info | FileCheck %s - # Compile with: # echo -e ".global _foo;\nfoo:\nnop" | clang -x assembler -g - -c -o /tmp/label.o diff --git a/llvm/test/tools/dsymutil/X86/label2.test b/llvm/test/tools/dsymutil/X86/label2.test index 9e0f39e5f337b..0517d1e7135b5 100644 --- a/llvm/test/tools/dsymutil/X86/label2.test +++ b/llvm/test/tools/dsymutil/X86/label2.test @@ -14,9 +14,6 @@ $ clang label.o -o label.out RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/label/label.out -o %t.dSYM RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/label/label.out -o %t.dSYM -RUN: llvm-dwarfdump %t.dSYM | FileCheck %s - CHECK: DW_TAG_label CHECK-NEXT: DW_AT_name ("foobar") CHECK-NEXT: DW_AT_decl_file ("/tmp/label{{[/\\]}}label.c") diff --git a/llvm/test/tools/dsymutil/X86/lc_build_version.test b/llvm/test/tools/dsymutil/X86/lc_build_version.test index f0d0e803b7a3b..2c91cbb0aa0e5 100644 --- a/llvm/test/tools/dsymutil/X86/lc_build_version.test +++ b/llvm/test/tools/dsymutil/X86/lc_build_version.test @@ -1,9 +1,6 @@ # RUN: dsymutil -f %p/../Inputs/lc_build_version.x86_64 -o - \ # RUN: -oso-prepend-path=%p/.. | obj2yaml | FileCheck %s -# RUN: dsymutil --linker llvm -f %p/../Inputs/lc_build_version.x86_64 -o - \ -# RUN: -oso-prepend-path=%p/.. | obj2yaml | FileCheck %s - CHECK: LoadCommands: CHECK: - cmd: LC_BUILD_VERSION CHECK-NEXT: cmdsize: 24 diff --git a/llvm/test/tools/dsymutil/X86/location-expression.test b/llvm/test/tools/dsymutil/X86/location-expression.test index 5414dff3745b2..a991edb6b75f7 100644 --- a/llvm/test/tools/dsymutil/X86/location-expression.test +++ b/llvm/test/tools/dsymutil/X86/location-expression.test @@ -11,7 +11,6 @@ # RUN: echo ' - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x10000, size: 0x10 }' >> %t2.map # RUN: echo '...' >> %t2.map # RUN: dsymutil -y %t2.map -f -o - | llvm-dwarfdump -a --verbose - | FileCheck %s -# RUN: dsymutil --linker llvm -y %t2.map -f -o - | llvm-dwarfdump -a --verbose - | FileCheck %s # CHECK: file format Mach-O 64-bit x86-64 # CHECK: .debug_info contents: @@ -21,11 +20,11 @@ # CHECK: 0x0000001b: DW_TAG_variable # CHECK: DW_AT_name {{.*}}"var1" # CHECK: DW_AT_type {{.*}}"class1" -# CHECK: DW_AT_location [DW_FORM_block1] (DW_OP_const8u 0x{{.*}}, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address) +# CHECK: DW_AT_location [DW_FORM_block1] (DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address) # CHECK: 0x000000ab: DW_TAG_variable # CHECK: DW_AT_name {{.*}}"var2" # CHECK: DW_AT_type {{.*}}"class1" -# CHECK: DW_AT_location [DW_FORM_block] (DW_OP_const8u 0x{{.*}}, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address) +# CHECK: DW_AT_location [DW_FORM_block] (DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address) # CHECK: 0x00000146: DW_TAG_variable # CHECK: DW_AT_name {{.*}}"var3" # CHECK: DW_AT_type {{.*}}"class1" @@ -73,21 +72,13 @@ LoadCommands: offset: 0x00000410 align: 0 reloff: 0x00000600 - nreloc: 2 + nreloc: 1 flags: 0x02000000 reserved1: 0x00000000 reserved2: 0x00000000 reserved3: 0x00000000 relocations: - - address: 0x30 - symbolnum: 1 - pcrel: true - length: 3 - extern: true - type: 0 - scattered: false - value: 0 - - address: 0xc2 + - address: 0x1FC symbolnum: 1 pcrel: true length: 3 diff --git a/llvm/test/tools/dsymutil/X86/mismatch.m b/llvm/test/tools/dsymutil/X86/mismatch.m index d2d257a54c777..2e907530c5b1c 100644 --- a/llvm/test/tools/dsymutil/X86/mismatch.m +++ b/llvm/test/tools/dsymutil/X86/mismatch.m @@ -19,8 +19,6 @@ // RUN: cp %p/../Inputs/mismatch/1.o %t.dir/2.o // RUN: dsymutil --verbose -f -oso-prepend-path=%t.dir \ // RUN: -y %p/dummy-debug-map.map -o %t.bin 2>&1 | FileCheck %s -// RUN: dsymutil --linker llvm --verbose -f -oso-prepend-path=%t.dir \ -// RUN: -y %p/dummy-debug-map.map -o %t.bin 2>&1 | FileCheck %s @import mismatch; diff --git a/llvm/test/tools/dsymutil/X86/modules-dwarf-version.m b/llvm/test/tools/dsymutil/X86/modules-dwarf-version.m index b57e91adb8b86..7c395f22e5168 100644 --- a/llvm/test/tools/dsymutil/X86/modules-dwarf-version.m +++ b/llvm/test/tools/dsymutil/X86/modules-dwarf-version.m @@ -11,9 +11,6 @@ // RUN: dsymutil -verify -f -oso-prepend-path=%t.dir \ // RUN: -y %p/dummy-debug-map.map -o - \ // RUN: | llvm-dwarfdump --debug-info - | FileCheck %s -// RUN: dsymutil --linker llvm -verify -f -oso-prepend-path=%t.dir \ -// RUN: -y %p/dummy-debug-map.map -o - \ -// RUN: | llvm-dwarfdump --debug-info - | FileCheck %s @import Bar; int main(int argc, char **argv) { diff --git a/llvm/test/tools/dsymutil/X86/modules-empty.m b/llvm/test/tools/dsymutil/X86/modules-empty.m index fc415acc59f6d..ce5ab427af57d 100644 --- a/llvm/test/tools/dsymutil/X86/modules-empty.m +++ b/llvm/test/tools/dsymutil/X86/modules-empty.m @@ -12,16 +12,11 @@ // RUN: rm -rf %t.dir // RUN: mkdir %t.dir -// RUN: cp %p/../Inputs/modules-empty/1.o %p/../Inputs/modules-empty/Empty.pcm \ -// RUN: %t.dir +// RUN: cp %p/../Inputs/modules-empty/1.o %p/../Inputs/modules-empty/Empty.pcm %t.dir // RUN: dsymutil -f -oso-prepend-path=%t.dir \ // RUN: -verify \ // RUN: -y %p/dummy-debug-map.map -o - \ // RUN: | llvm-dwarfdump --debug-info - | FileCheck %s -// RUN: dsymutil --linker llvm -f -oso-prepend-path=%t.dir \ -// RUN: -verify \ -// RUN: -y %p/dummy-debug-map.map -o - \ -// RUN: | llvm-dwarfdump --debug-info - | FileCheck %s #include "Empty.h" int main() { diff --git a/llvm/test/tools/dsymutil/X86/multiple-inputs.test b/llvm/test/tools/dsymutil/X86/multiple-inputs.test index 6e1ed2e48c6d7..ea541426eb17e 100644 --- a/llvm/test/tools/dsymutil/X86/multiple-inputs.test +++ b/llvm/test/tools/dsymutil/X86/multiple-inputs.test @@ -28,3 +28,4 @@ RUN: llvm-dwarfdump -a %t.dSYM/Contents/Resources/DWARF/basic-lto-dw4.macho.x86_ 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 CHECK: error: cannot use -o with multiple inputs in flat mode + diff --git a/llvm/test/tools/dsymutil/X86/object-prefix-path.test b/llvm/test/tools/dsymutil/X86/object-prefix-path.test index 9ac5ad755ec13..16956e0f94521 100644 --- a/llvm/test/tools/dsymutil/X86/object-prefix-path.test +++ b/llvm/test/tools/dsymutil/X86/object-prefix-path.test @@ -7,10 +7,5 @@ RUN: %p/dummy-debug-map.map -o %t \ RUN: -object-prefix-map=/ModuleCache=/ModuleCacheRenamed \ RUN: 2>&1 | FileCheck %s -RUN: dsymutil --linker llvm -verify -f -oso-prepend-path=%t.dir -y \ -RUN: %p/dummy-debug-map.map -o %t \ -RUN: -object-prefix-map=/ModuleCache=/ModuleCacheRenamed \ -RUN: 2>&1 | FileCheck %s - CHECK: warning: {{.*}}Bar.pcm: CHECK-NOT: warning: {{.*}}Foo.pcm: diff --git a/llvm/test/tools/dsymutil/X86/op-convert-offset.test b/llvm/test/tools/dsymutil/X86/op-convert-offset.test index fa780993bd0d6..80cfc867b1d92 100644 --- a/llvm/test/tools/dsymutil/X86/op-convert-offset.test +++ b/llvm/test/tools/dsymutil/X86/op-convert-offset.test @@ -24,14 +24,6 @@ RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/op-convert RUN: llvm-dwarfdump %p/../Inputs/private/tmp/op-convert-offset/op-convert-offset.o 2>&1 | FileCheck %s --check-prefix OBJ RUN: llvm-dwarfdump %t.dSYM 2>&1 | FileCheck %s --check-prefix DSYM -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs \ -RUN: %p/../Inputs/private/tmp/op-convert-offset/op-convert-offset \ -RUN: -o %t.dSYM 2>&1 -RUN: llvm-dwarfdump \ -RUN: %p/../Inputs/private/tmp/op-convert-offset/op-convert-offset.o 2>&1 \ -RUN: | FileCheck %s --check-prefix OBJ -RUN: llvm-dwarfdump %t.dSYM 2>&1 | FileCheck %s --check-prefix DSYM - OBJ: 0x0000007d: DW_TAG_base_type OBJ: DW_AT_name ("DW_ATE_unsigned_1") OBJ: DW_AT_encoding (DW_ATE_unsigned) @@ -50,4 +42,4 @@ DSYM: DW_AT_byte_size (0x01) DSYM: 0x0000009b: DW_TAG_formal_parameter DSYM: DW_AT_location (DW_OP_breg2 RCX+0, DW_OP_constu 0xff, DW_OP_and, DW_OP_convert (0x00000084) "DW_ATE_unsigned_1", DW_OP_convert (0x00000088) "DW_ATE_unsigned_8", DW_OP_stack_value) DSYM: DW_AT_name ("b") -DSYM: DW_AT_type ({{.*}} "_Bool") +DSYM: DW_AT_type (0x000000b6 "_Bool") diff --git a/llvm/test/tools/dsymutil/X86/op-convert.test b/llvm/test/tools/dsymutil/X86/op-convert.test index 15725a0435d48..a03869865599d 100644 --- a/llvm/test/tools/dsymutil/X86/op-convert.test +++ b/llvm/test/tools/dsymutil/X86/op-convert.test @@ -1,9 +1,6 @@ # RUN: dsymutil -f -o %t --verify -oso-prepend-path=%p/../Inputs -y %s # RUN: llvm-dwarfdump %t | FileCheck %s -# RUN: dsymutil --linker llvm -f -o %t --verify -oso-prepend-path=%p/../Inputs -y %s -# RUN: llvm-dwarfdump %t | FileCheck %s - --- triple: 'x86_64-apple-darwin' objects: diff --git a/llvm/test/tools/dsymutil/X86/papertrail-warnings.test b/llvm/test/tools/dsymutil/X86/papertrail-warnings.test index 69c851a335ad6..1678adb8ae7b7 100644 --- a/llvm/test/tools/dsymutil/X86/papertrail-warnings.test +++ b/llvm/test/tools/dsymutil/X86/papertrail-warnings.test @@ -1,7 +1,5 @@ RUN: env RC_DEBUG_OPTIONS=1 dsymutil -f %p/../Inputs/basic.macho.x86_64 -o - | llvm-dwarfdump -v - | FileCheck -DMSG=%errc_ENOENT %s -RUN: env RC_DEBUG_OPTIONS=1 dsymutil --linker llvm -f %p/../Inputs/basic.macho.x86_64 -o - | llvm-dwarfdump -v - | FileCheck -DMSG=%errc_ENOENT %s - CHECK: .debug_info contents: CHECK: Compile Unit: CHECK: DW_TAG_compile_unit [1] * diff --git a/llvm/test/tools/dsymutil/X86/reflection-dump.test b/llvm/test/tools/dsymutil/X86/reflection-dump.test index 77694773ab0f9..bcee07d5929eb 100644 --- a/llvm/test/tools/dsymutil/X86/reflection-dump.test +++ b/llvm/test/tools/dsymutil/X86/reflection-dump.test @@ -9,9 +9,6 @@ RUN: yaml2obj %p/../Inputs/reflection_metadata.yaml -o %t.dir/tmp/reflection_met RUN: dsymutil -oso-prepend-path=%t.dir %t.dir/main -o %t.dir/main.dSYM RUN: llvm-objdump -s %t.dir/main.dSYM/Contents/Resources/DWARF/main | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path=%t.dir %t.dir/main -o %t.dir/main.dSYM -RUN: llvm-objdump -s %t.dir/main.dSYM/Contents/Resources/DWARF/main | FileCheck %s - REQUIRES: host-byteorder-little-endian diff --git a/llvm/test/tools/dsymutil/X86/remarks-linking-archive.text b/llvm/test/tools/dsymutil/X86/remarks-linking-archive.text index 5578fd28b89a8..117349c78396d 100644 --- a/llvm/test/tools/dsymutil/X86/remarks-linking-archive.text +++ b/llvm/test/tools/dsymutil/X86/remarks-linking-archive.text @@ -7,17 +7,10 @@ RUN: dsymutil -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs Check that the remark file in the bundle exists and is sane: RUN: llvm-bcanalyzer -dump %t/basic.macho.remarks.archive.x86_64.dSYM/Contents/Resources/Remarks/basic.macho.remarks.archive.x86_64 | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs %t/basic.macho.remarks.archive.x86_64 - -Check that the remark file in the bundle exists and is sane: -RUN: llvm-bcanalyzer -dump %t/basic.macho.remarks.archive.x86_64.dSYM/Contents/Resources/Remarks/basic.macho.remarks.archive.x86_64 | FileCheck %s - Check that we don't error if we're missing remark files from an archive, but we warn instead. Instead of creating a new binary, just remove the remarks prepend path. RUN: dsymutil -oso-prepend-path=%p/../Inputs %t/basic.macho.remarks.archive.x86_64 2>&1 | FileCheck %s --check-prefix=CHECK-MISSING -RUN: dsymutil --linker llvm -oso-prepend-path=%p/../Inputs %t/basic.macho.remarks.archive.x86_64 2>&1 | FileCheck %s --check-prefix=CHECK-MISSING - CHECK: &1 - -RUN: dsymutil --linker llvm -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs %t/basic.macho.remarks.empty.x86_64 - -Check that the remark file in the bundle does not exist: -RUN: not cat %t/basic.macho.remarks.empty.x86_64.dSYM/Contents/Resources/Remarks/basic.macho.remarks.empty.x86_64 2>&1 diff --git a/llvm/test/tools/dsymutil/X86/remarks-linking-bundle.test b/llvm/test/tools/dsymutil/X86/remarks-linking-bundle.test index 3fb7fd59d44bc..11b9a6f9d5eab 100644 --- a/llvm/test/tools/dsymutil/X86/remarks-linking-bundle.test +++ b/llvm/test/tools/dsymutil/X86/remarks-linking-bundle.test @@ -7,18 +7,10 @@ RUN: dsymutil -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs Check that the remark file in the bundle exists and is sane: RUN: llvm-bcanalyzer -dump %t/basic.macho.remarks.x86_64.dSYM/Contents/Resources/Remarks/basic.macho.remarks.x86_64 | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs %t/basic.macho.remarks.x86_64 - -Check that the remark file in the bundle exists and is sane: -RUN: llvm-bcanalyzer -dump %t/basic.macho.remarks.x86_64.dSYM/Contents/Resources/Remarks/basic.macho.remarks.x86_64 | FileCheck %s - Now emit it in a different format: YAML. RUN: dsymutil -remarks-output-format=yaml -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs %t/basic.macho.remarks.x86_64 RUN: cat %t/basic.macho.remarks.x86_64.dSYM/Contents/Resources/Remarks/basic.macho.remarks.x86_64 | FileCheck %s --check-prefix=CHECK-YAML -RUN: dsymutil --linker llvm -remarks-output-format=yaml -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs %t/basic.macho.remarks.x86_64 -RUN: cat %t/basic.macho.remarks.x86_64.dSYM/Contents/Resources/Remarks/basic.macho.remarks.x86_64 | FileCheck %s --check-prefix=CHECK-YAML - CHECK: &1 | FileCheck %s --check-prefix=ERROR -RUN: not dsymutil --linker llvm -f -o %t.error -oso-prepend-path=%t %t/Inputs/basic.macho.x86_64 2>&1 | FileCheck %s --check-prefix=ERROR - # Use the reproducer. RUN: dsymutil -use-reproducer %t.repro -f -o - -oso-prepend-path=%t %t/Inputs/basic.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s -RUN: dsymutil --linker llvm -use-reproducer %t.repro -f -o - -oso-prepend-path=%t %t/Inputs/basic.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s - # Using a reproducer takes precedence. RUN: dsymutil -gen-reproducer -use-reproducer %t.repro -f -o - -oso-prepend-path=%t %t/Inputs/basic.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s -RUN: dsymutil --linker llvm -gen-reproducer -use-reproducer %t.repro -f -o - -oso-prepend-path=%t %t/Inputs/basic.macho.x86_64 | llvm-dwarfdump -a - | FileCheck %s - CHECK: .debug_info CHECK: DW_TAG_compile_unit CHECK-NEXT: DW_AT_producer ("Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)") diff --git a/llvm/test/tools/dsymutil/X86/statistics.test b/llvm/test/tools/dsymutil/X86/statistics.test index 082d20b1c5371..0237aede28001 100644 --- a/llvm/test/tools/dsymutil/X86/statistics.test +++ b/llvm/test/tools/dsymutil/X86/statistics.test @@ -1,5 +1,4 @@ # RUN: dsymutil -statistics -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s -# RUN: dsymutil --linker llvm -statistics -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s # # CHECK: ------------------------------------------------------------------------------- # CHECK-NEXT: Filename Object dSYM Change diff --git a/llvm/test/tools/dsymutil/X86/swift-ast-x86_64.test b/llvm/test/tools/dsymutil/X86/swift-ast-x86_64.test index 9d959e06fb958..a16330d8c1b05 100644 --- a/llvm/test/tools/dsymutil/X86/swift-ast-x86_64.test +++ b/llvm/test/tools/dsymutil/X86/swift-ast-x86_64.test @@ -3,12 +3,6 @@ RUN: dsymutil -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.x86_64 -o %T/ RUN: llvm-readobj --sections --section-data %T/swift-ast.dSYM/Contents/Resources/DWARF/swift-ast.macho.x86_64 | FileCheck %s --check-prefix=READOBJ RUN: llvm-dwarfdump --show-section-sizes %T/swift-ast.dSYM/Contents/Resources/DWARF/swift-ast.macho.x86_64 | FileCheck %s --check-prefix=DWARFDUMP -RUN: dsymutil --linker llvm -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.x86_64 -o %T/swift-ast.dSYM -verbose -no-swiftmodule-timestamp | FileCheck %s --check-prefix=DSYMUTIL -RUN: dsymutil --linker llvm -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.x86_64 -o %T/swift-ast.dSYM -verbose | FileCheck %s --check-prefix=DSYMUTIL -RUN: llvm-readobj --sections --section-data %T/swift-ast.dSYM/Contents/Resources/DWARF/swift-ast.macho.x86_64 | FileCheck %s --check-prefix=READOBJ -RUN: llvm-dwarfdump --show-section-sizes %T/swift-ast.dSYM/Contents/Resources/DWARF/swift-ast.macho.x86_64 | FileCheck %s --check-prefix=DWARFDUMP - - The tested object file has been created by the dummy Swift code: let x = 1 diff --git a/llvm/test/tools/dsymutil/X86/swift-dwarf-loc.test b/llvm/test/tools/dsymutil/X86/swift-dwarf-loc.test index d12e2e137d7e4..65282223a3033 100644 --- a/llvm/test/tools/dsymutil/X86/swift-dwarf-loc.test +++ b/llvm/test/tools/dsymutil/X86/swift-dwarf-loc.test @@ -1,7 +1,5 @@ RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/swift-dwarf-loc.macho.x86_64 -no-output -verbose | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/swift-dwarf-loc.macho.x86_64 -no-output -verbose | FileCheck %s - This test checks that dsymutil generates a valid dwarf location for a symbol with no flags set. The following IR was compiled for x86_64-apple: diff --git a/llvm/test/tools/dsymutil/X86/tail-call-linking.test b/llvm/test/tools/dsymutil/X86/tail-call-linking.test index f4e2afe808a09..29ae2cc544cf6 100644 --- a/llvm/test/tools/dsymutil/X86/tail-call-linking.test +++ b/llvm/test/tools/dsymutil/X86/tail-call-linking.test @@ -1,7 +1,4 @@ RUN: dsymutil -oso-prepend-path=%p %p/Inputs/tail-call.macho.x86_64 -o %t.dSYM RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_pc -RUN: dsymutil --linker llvm -oso-prepend-path=%p %p/Inputs/tail-call.macho.x86_64 -o %t.dSYM -RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -implicit-check-not=DW_AT_call_pc - CHECK: DW_AT_call_pc (0x0000000100000f95) diff --git a/llvm/test/tools/dsymutil/X86/thinlto.test b/llvm/test/tools/dsymutil/X86/thinlto.test index 2d2195805f3aa..ebd4068a5c127 100644 --- a/llvm/test/tools/dsymutil/X86/thinlto.test +++ b/llvm/test/tools/dsymutil/X86/thinlto.test @@ -20,8 +20,5 @@ $ xcrun clang++ -g -flto=thin -O2 foo.cpp bar.cpp -c $ xcrun clang++ -flto=thin foo.o bar.o -Xlinker -object_path_lto -Xlinker lto -shared -o foobar.dylib RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/thinlto/foobar.dylib -o %t.dSYM 2>&1 | FileCheck %s --allow-empty - -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/thinlto/foobar.dylib -o %t.dSYM 2>&1 | FileCheck %s --allow-empty - CHECK-NOT: could not find object file symbol for symbol __ZZ9function2vE12magic_static CHECK-NOT: could not find object file symbol for symbol __ZGVZ9function2vE12magic_static diff --git a/llvm/test/tools/dsymutil/X86/timestamp-mismatch.test b/llvm/test/tools/dsymutil/X86/timestamp-mismatch.test index f41fe31f5549b..7d41905e79514 100644 --- a/llvm/test/tools/dsymutil/X86/timestamp-mismatch.test +++ b/llvm/test/tools/dsymutil/X86/timestamp-mismatch.test @@ -5,8 +5,6 @@ RUN: cp %p/../Inputs/basic2.macho.x86_64.o %t/Inputs RUN: cp %p/../Inputs/basic3.macho.x86_64.o %t/Inputs RUN: dsymutil -oso-prepend-path=%t %t/Inputs/basic.macho.x86_64 -o %t.dSYM 2>&1 | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path=%t %t/Inputs/basic.macho.x86_64 -o %t.dSYM 2>&1 | FileCheck %s - CHECK: warning: {{.*}}/Inputs/basic1.macho.x86_64.o: timestamp mismatch between object file ({{.*}}) and debug map ({{.*}}) CHECK: warning: {{.*}}/Inputs/basic2.macho.x86_64.o: timestamp mismatch between object file ({{.*}}) and debug map ({{.*}}) CHECK: warning: {{.*}}/Inputs/basic3.macho.x86_64.o: timestamp mismatch between object file ({{.*}}) and debug map ({{.*}}) diff --git a/llvm/test/tools/dsymutil/X86/tls-variable.test b/llvm/test/tools/dsymutil/X86/tls-variable.test index 48027e4f98714..19f9e380f22be 100644 --- a/llvm/test/tools/dsymutil/X86/tls-variable.test +++ b/llvm/test/tools/dsymutil/X86/tls-variable.test @@ -10,7 +10,6 @@ # RUN: echo ' - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x10000, size: 0x10 }' >> %t2.map # RUN: echo '...' >> %t2.map # RUN: dsymutil -y %t2.map --keep-function-for-static -f -o - | llvm-dwarfdump -a - | FileCheck %s -# RUN: dsymutil --linker llvm -y %t2.map --keep-function-for-static -f -o - | 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/union-fwd-decl.test b/llvm/test/tools/dsymutil/X86/union-fwd-decl.test index c5c8c9e93e0a0..c73db0e3f5532 100644 --- a/llvm/test/tools/dsymutil/X86/union-fwd-decl.test +++ b/llvm/test/tools/dsymutil/X86/union-fwd-decl.test @@ -48,9 +48,6 @@ Note that the link order in the last command matters for this test. RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/union/a.out -o %t.dSYM RUN: llvm-dwarfdump %t.dSYM | FileCheck %s -RUN: dsymutil --linker llvm -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/union/a.out -o %t.dSYM -RUN: llvm-dwarfdump %t.dSYM | FileCheck %s - CHECK: DW_TAG_compile_unit CHECK: DW_AT_name ("Container_ivars") diff --git a/llvm/test/tools/dsymutil/X86/verify.test b/llvm/test/tools/dsymutil/X86/verify.test index b48af48473b63..2a7b1938e843f 100644 --- a/llvm/test/tools/dsymutil/X86/verify.test +++ b/llvm/test/tools/dsymutil/X86/verify.test @@ -25,25 +25,6 @@ # QUIET-SUCCESS-NOT: input verification failed # QUIET-SUCCESS-NOT: output verification failed # BOGUS: error: invalid verify type specified: 'bogus' -# -# Positive tests in regular and verbose mode. -# RUN: dsymutil --linker llvm -verify -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s --allow-empty --check-prefix=QUIET-SUCCESS -# RUN: dsymutil --linker llvm -verify -verbose -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s --check-prefixes=QUIET-SUCCESS,VERBOSE -# -# # Negative output tests in regular and verbose mode. -# (Invalid object generated from ../Inputs/invalid.s by modified the low PC.) -# RUN: not dsymutil --linker llvm -verify -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefix=QUIET-OUTPUT-FAIL -# RUN: not dsymutil --linker llvm -verify-dwarf=output -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefix=QUIET-OUTPUT-FAIL -# RUN: not dsymutil --linker llvm -verify -verbose -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefixes=QUIET-OUTPUT-FAIL,VERBOSE -# -# # Negative input & output tests in regular and verbose mode. Only output failures result in a non-zero exit code. -# RUN: dsymutil --linker llvm -verify-dwarf=input -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefix=QUIET-INPUT-FAIL -# RUN: dsymutil --linker llvm -verify-dwarf=input -verbose -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefix=QUIET-INPUT-FAIL -# RUN: dsymutil --linker llvm -verify-dwarf=none -verbose -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefixes=QUIET-SUCCESS -# RUN: not dsymutil --linker llvm -verify-dwarf=bogus -verbose -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefixes=BOGUS -# RUN: not dsymutil --linker llvm -verify-dwarf=all -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefixes=QUIET-OUTPUT-FAIL,QUIET-INPUT-FAIL -# RUN: not dsymutil --linker llvm -verify-dwarf=all -verbose -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefixes=VERBOSE-INPUT-FAIL - --- triple: 'x86_64-apple-darwin' diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/DWARFLinkerParallel/gc-default.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/DWARFLinkerParallel/gc-default.test new file mode 100644 index 0000000000000..5083fd54c136e --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/DWARFLinkerParallel/gc-default.test @@ -0,0 +1,134 @@ +## This test checks that debug info related to deleted code (marked with +## default tombstone value) is removed. + +# RUN: yaml2obj %s -o %t.o +# RUN: llvm-dwarfutil --linker llvm %t.o %t1.out 2>&1 | FileCheck %s --allow-empty + +#CHECK: LLVM parallel dwarflinker is not implemented yet. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + Size: 0x1b +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Tag: DW_TAG_subprogram + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Tag: DW_TAG_class_type + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Tag: DW_TAG_member + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Tag: DW_TAG_class_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_declaration + Form: DW_FORM_flag_present + - Tag: DW_TAG_class_type + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_declaration + Form: DW_FORM_flag_present + - Tag: DW_TAG_template_type_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x1b + - AbbrCode: 3 + Values: + - CStr: class1 + - AbbrCode: 4 + Values: + - Value: 0x0000006c + - CStr: member1 + - AbbrCode: 0 + - AbbrCode: 3 + Values: + - CStr: class2 + - AbbrCode: 4 + Values: + - Value: 0x0000006c + - CStr: member1 + - AbbrCode: 0 + - AbbrCode: 3 + Values: + - CStr: class3 + - AbbrCode: 4 + Values: + - Value: 0x0000006c + - CStr: member1 + - AbbrCode: 0 + - AbbrCode: 8 + Values: + - CStr: int + - AbbrCode: 2 + Values: + - CStr: foo1 + - Value: 0x1000 + - Value: 0x10 + - Value: 0x0000002a + - AbbrCode: 2 + Values: + - CStr: foo2 + - Value: 0x0 + - Value: 0x100 + - Value: 0x00000040 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro-short.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro-short.test index 95def093e66a2..f500ad1d1232d 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro-short.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro-short.test @@ -7,10 +7,6 @@ # RUN: llvm-dwarfdump --verify %t1 | FileCheck --check-prefix=VERIFY %s # RUN: llvm-dwarfdump -a %t1 | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm %t.o %t1 -# RUN: llvm-dwarfdump --verify %t1 | FileCheck --check-prefix=VERIFY %s -# RUN: llvm-dwarfdump -a %t1 | FileCheck %s - # VERIFY: No errors. ## Content: "03000201064400020744000400": diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro.test index 6797af9d578cf..a84653c612cb7 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro.test @@ -39,28 +39,16 @@ #RUN: llvm-dwarfdump -verify %t1 | FileCheck %s #RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACINFO -#RUN: llvm-dwarfutil --linker llvm --garbage-collection %p/Inputs/dwarf4-macro.out %t1 -#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACINFO - ## Check that macro table preserved during simple copying. # #RUN: llvm-dwarfutil --no-garbage-collection %p/Inputs/dwarf4-macro.out %t1 #RUN: llvm-dwarfdump -verify %t1 | FileCheck %s #RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACINFO -#RUN: llvm-dwarfutil --linker llvm --no-garbage-collection %p/Inputs/dwarf4-macro.out %t1 -#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACINFO - ## Check that macro table preserved during updating accelerator tables. #RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %p/Inputs/dwarf4-macro.out %t1 #RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefixes=MACINFO - -#RUN: llvm-dwarfutil --linker llvm --no-garbage-collection --build-accelerator=DWARF %p/Inputs/dwarf4-macro.out %t1 -#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefixes=MACINFO +#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefixes=MACINFO,NAMES #CHECK: No errors. @@ -2240,3 +2228,6 @@ #MACINFO-NEXT: DW_MACINFO_define - lineno: 0 macro: __STDC_UTF_32__ 1 #MACINFO-NEXT: DW_MACINFO_define - lineno: 0 macro: __GCC_HAVE_DWARF2_CFI_ASM 1 + +#NAMES: .debug_names contents +#NAMES: Name Index diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addresses.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addresses.test index 90c40fd1e4ab6..50dd070633bc7 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addresses.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addresses.test @@ -12,27 +12,15 @@ # RUN: llvm-dwarfutil %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK - -# RUN: llvm-dwarfutil --linker llvm %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK - +# # RUN: llvm-dwarfutil --no-garbage-collection %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK - -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK - +# # RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection --build-accelerator=DWARF %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK - #CHECK: No errors. #DWARF-CHECK: DW_TAG_compile_unit diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-attributes.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-attributes.test index bf880c643a4dc..779e165ab72b8 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-attributes.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-attributes.test @@ -6,27 +6,15 @@ # RUN: llvm-dwarfutil %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - -# RUN: llvm-dwarfutil --linker llvm %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - +# # RUN: llvm-dwarfutil --no-garbage-collection %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - +# # RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection --build-accelerator=DWARF %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - #VERIFY-CHECK: No errors. #CHECK: .debug_abbrev diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-line-str.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-line-str.test index 52bf01c3a7130..8f2957350484e 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-line-str.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-line-str.test @@ -6,27 +6,15 @@ # RUN: llvm-dwarfutil %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - +# # RUN: llvm-dwarfutil --no-garbage-collection %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - +# # RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection --build-accelerator=DWARF %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s --check-prefix VERIFY-CHECK -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s - #VERIFY-CHECK: No errors. #CHECK: .debug_info diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-loclists.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-loclists.test index 719944b3d224e..b02c76e3367ec 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-loclists.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-loclists.test @@ -16,18 +16,6 @@ # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK -# RUN: llvm-dwarfutil --linker llvm %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK - -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK - -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection --build-accelerator=DWARF %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK - #CHECK: No errors. #DWARF-CHECK: DW_TAG_compile_unit diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro-opcodeop.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro-opcodeop.test index c9e89b2d1d125..c19462c309e06 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro-opcodeop.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro-opcodeop.test @@ -6,10 +6,6 @@ # RUN: llvm-dwarfdump --verify %t1 | FileCheck --check-prefix=VERIFY %s # RUN: llvm-dwarfdump -a %t1 | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm %t.o %t1 2>&1 | FileCheck --check-prefix=ERR %s -# RUN: llvm-dwarfdump --verify %t1 | FileCheck --check-prefix=VERIFY %s -# RUN: llvm-dwarfdump -a %t1 | FileCheck %s - # ERR: error: opcode_operands_table is not supported # VERIFY: No errors. diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro-short.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro-short.test index b38aae6f816d9..ecafd814baf3c 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro-short.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro-short.test @@ -8,10 +8,6 @@ # RUN: llvm-dwarfdump --verify %t1 | FileCheck --check-prefix=VERIFY %s # RUN: llvm-dwarfdump -a %t1 | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm %t.o %t1 2>&1 | FileCheck --check-prefix=WARN %s -# RUN: llvm-dwarfdump --verify %t1 | FileCheck --check-prefix=VERIFY %s -# RUN: llvm-dwarfdump -a %t1 | FileCheck %s - # WARN: warning: DW_MACRO_define_strx unsupported yet. Convert to DW_MACRO_define_strp. # WARN: warning: DW_MACRO_undef_strx unsupported yet. Convert to DW_MACRO_undef_strp. # WARN: warning: DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. remove. diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro.test index 053d55871d455..57487be9d4270 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro.test @@ -39,28 +39,16 @@ #RUN: llvm-dwarfdump -verify %t1 | FileCheck %s #RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACRO -#RUN: llvm-dwarfutil --linker llvm --garbage-collection %p/Inputs/dwarf5-macro.out %t1 -#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACRO - ## Check that macro table preserved during simple copying. # #RUN: llvm-dwarfutil --no-garbage-collection %p/Inputs/dwarf5-macro.out %t1 #RUN: llvm-dwarfdump -verify %t1 | FileCheck %s #RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACRO -#RUN: llvm-dwarfutil --linker llvm --no-garbage-collection %p/Inputs/dwarf5-macro.out %t1 -#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACRO - ## Check that macro table preserved during updating accelerator tables. #RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %p/Inputs/dwarf5-macro.out %t1 #RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefixes=MACRO - -#RUN: llvm-dwarfutil --linker llvm --no-garbage-collection --build-accelerator=DWARF %p/Inputs/dwarf5-macro.out %t1 -#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefixes=MACRO +#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefixes=MACRO,NAMES #CHECK: No errors. @@ -2245,3 +2233,6 @@ #MACRO-NEXT: DW_MACRO_define_str{{[px]}} - lineno: 0 macro: __STDC_UTF_16__ 1 #MACRO-NEXT: DW_MACRO_define_str{{[px]}} - lineno: 0 macro: __STDC_UTF_32__ 1 #MACRO-NEXT: DW_MACRO_define_str{{[px]}} - lineno: 0 macro: __GCC_HAVE_DWARF2_CFI_ASM 1 + +#NAMES: .debug_names contents +#NAMES: Name Index diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-rnglists.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-rnglists.test index 78b53897346c4..d9458e901944f 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-rnglists.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-rnglists.test @@ -8,26 +8,14 @@ # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK -# RUN: llvm-dwarfutil --linker llvm %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK - # RUN: llvm-dwarfutil --no-garbage-collection %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK - # RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %t.o %t1 # RUN: llvm-dwarfdump -verify %t1 | FileCheck %s # RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK -# RUN: llvm-dwarfutil --linker llvm --no-garbage-collection --build-accelerator=DWARF %t.o %t1 -# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s -# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK - #CHECK: No errors. #DWARF-CHECK: DW_TAG_compile_unit diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-default.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-default.test index 90cb99858c9ef..b364a751a7c7c 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-default.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-default.test @@ -7,20 +7,14 @@ # RUN: llvm-dwarfutil --linker apple %t.o - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,CHECK-GC -# RUN: llvm-dwarfutil --linker llvm %t.o - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,CHECK-GC - # RUN: llvm-dwarfutil --garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,CHECK-GC # RUN: llvm-dwarfutil --no-garbage-collection --garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,CHECK-GC # RUN: llvm-dwarfutil --garbage-collection --no-garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,CHECK-NOGC -# RUN: llvm-dwarfutil --linker llvm --garbage-collection --no-garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,CHECK-NOGC - # RUN: llvm-dwarfutil %t.o --tombstone=universal - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,CHECK-GC -# RUN: llvm-dwarfutil --linker llvm %t.o --tombstone=universal - | llvm-dwarfdump -a - | FileCheck %s --check-prefixes=CHECK,CHECK-GC - # CHECK: DW_TAG_compile_unit # CHECK: DW_AT_name{{.*}}"CU1" # CHECK: DW_TAG_class_type diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-func-overlapping-address-ranges.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-func-overlapping-address-ranges.test index 232f6a5553e57..cfbb7cb105586 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-func-overlapping-address-ranges.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-func-overlapping-address-ranges.test @@ -5,9 +5,6 @@ # RUN: llvm-dwarfutil --garbage-collection %t.o %t1 # RUN: llvm-dwarfdump -a %t1 | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm --garbage-collection %t.o %t1 -# RUN: llvm-dwarfdump -a %t1 | FileCheck %s - # CHECK: DW_TAG_compile_unit # CHECK: DW_AT_name{{.*}}"CU1" # CHECK: DW_AT_low_pc{{.*}}0000000000001000 diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-maxpc.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-maxpc.test index cb3b435ea9aa4..6184f72496129 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-maxpc.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-maxpc.test @@ -6,9 +6,6 @@ # RUN: llvm-dwarfutil --tombstone=maxpc --garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s # RUN: llvm-dwarfutil --tombstone=universal --garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm --tombstone=maxpc --garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm --tombstone=universal --garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s - # CHECK: DW_TAG_compile_unit # CHECK: DW_AT_name{{.*}}"CU1" # CHECK: DW_TAG_class_type diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-no-garbage.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-no-garbage.test index 1f5ddd78adaa2..11252295617d7 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-no-garbage.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-no-garbage.test @@ -4,8 +4,6 @@ # RUN: yaml2obj %s -o %t.o # RUN: llvm-dwarfutil --tombstone=maxpc --garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm --tombstone=maxpc --garbage-collection %t.o - | llvm-dwarfdump -a - | FileCheck %s - # CHECK: DW_TAG_compile_unit # CHECK: DW_AT_name{{.*}}"CU1" # CHECK: DW_TAG_class_type diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-unit-overlapping-address-ranges.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-unit-overlapping-address-ranges.test index 2ee1d73b6f92f..f9d42c28d4209 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-unit-overlapping-address-ranges.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/gc-unit-overlapping-address-ranges.test @@ -6,9 +6,6 @@ # RUN: llvm-dwarfutil --garbage-collection %t.o %t1 # RUN: llvm-dwarfdump -a %t1 | FileCheck %s -# RUN: llvm-dwarfutil --linker llvm --garbage-collection %t.o %t1 -# RUN: llvm-dwarfdump -a %t1 | FileCheck %s - # CHECK: DW_TAG_compile_unit # CHECK: DW_AT_name{{.*}}"CU1" # CHECK: DW_TAG_class_type diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/verify.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/verify.test index e9557edddde42..844e8fb671af3 100644 --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/verify.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/verify.test @@ -7,23 +7,18 @@ ## Verify resulting debug info after --garbage-collection optimisation. # RUN: llvm-dwarfutil %t.o %t1 --verify -# RUN: llvm-dwarfutil --linker llvm %t.o %t1 --verify ## Verify separate debug file after --garbage-collection optimisation. # RUN: llvm-dwarfutil %t.o --separate-debug-file %t1 --verify -# RUN: llvm-dwarfutil --linker llvm %t.o --separate-debug-file %t1 --verify ## Verify not optimised resulting debug info. # RUN: not llvm-dwarfutil --no-garbage-collection %t.o %t1 --verify 2>&1 | FileCheck %s -DFILE=%t1 -# RUN: not llvm-dwarfutil --linker llvm --no-garbage-collection %t.o %t1 --verify 2>&1 | FileCheck %s -DFILE=%t1 ## Verify not optimised resulting separate debug file. # RUN: not llvm-dwarfutil --no-garbage-collection %t.o --separate-debug-file %t1 --verify 2>&1 | FileCheck %s -DFILE=%t1.debug -# RUN: not llvm-dwarfutil --linker llvm --no-garbage-collection %t.o --separate-debug-file %t1 --verify 2>&1 | FileCheck %s -DFILE=%t1.debug ## Check that verification is disabled when destination is stdout. # RUN: llvm-dwarfutil %t.o - --verify 2>&1 | FileCheck %s --check-prefix=CHECK-STDOUT -# RUN: llvm-dwarfutil --linker llvm %t.o - --verify 2>&1 | FileCheck %s --check-prefix=CHECK-STDOUT # CHECK: error: '[[FILE]]': output verification failed # CHECK-STDOUT: warning: verification skipped because writing to stdout diff --git a/llvm/tools/dsymutil/BinaryHolder.cpp b/llvm/tools/dsymutil/BinaryHolder.cpp index c6661f4058f10..d8293f7f354f2 100644 --- a/llvm/tools/dsymutil/BinaryHolder.cpp +++ b/llvm/tools/dsymutil/BinaryHolder.cpp @@ -238,7 +238,6 @@ BinaryHolder::getObjectEntry(StringRef Filename, TimestampTy Timestamp) { if (isArchive(Filename)) { StringRef ArchiveFilename = getArchiveAndObjectName(Filename).first; std::lock_guard Lock(ArchiveCacheMutex); - ArchiveRefCounter[ArchiveFilename]++; if (ArchiveCache.count(ArchiveFilename)) { return ArchiveCache[ArchiveFilename]->getObjectEntry(Filename, Timestamp, Verbose); @@ -259,7 +258,6 @@ BinaryHolder::getObjectEntry(StringRef Filename, TimestampTy Timestamp) { // If this is an object, we might have it cached. If not we'll have to load // it from the file system and cache it now. std::lock_guard Lock(ObjectCacheMutex); - ObjectRefCounter[Filename]++; if (!ObjectCache.count(Filename)) { auto OE = std::make_unique(); auto Err = OE->load(VFS, Filename, Timestamp, Verbose); @@ -278,24 +276,5 @@ void BinaryHolder::clear() { ObjectCache.clear(); } -void BinaryHolder::eraseObjectEntry(StringRef Filename) { - if (Verbose) - WithColor::note() << "erasing '" << Filename << "' from cache\n"; - - if (isArchive(Filename)) { - StringRef ArchiveFilename = getArchiveAndObjectName(Filename).first; - std::lock_guard Lock(ArchiveCacheMutex); - ArchiveRefCounter[ArchiveFilename]--; - if (ArchiveRefCounter[ArchiveFilename] == 0) - ArchiveCache.erase(ArchiveFilename); - return; - } - - std::lock_guard Lock(ObjectCacheMutex); - ObjectRefCounter[Filename]--; - if (ObjectRefCounter[Filename] == 0) - ObjectCache.erase(Filename); -} - } // namespace dsymutil } // namespace llvm diff --git a/llvm/tools/dsymutil/BinaryHolder.h b/llvm/tools/dsymutil/BinaryHolder.h index c4fc5a6110e77..84084c568cbea 100644 --- a/llvm/tools/dsymutil/BinaryHolder.h +++ b/llvm/tools/dsymutil/BinaryHolder.h @@ -126,18 +126,15 @@ class BinaryHolder { getObjectEntry(StringRef Filename, TimestampTy Timestamp = TimestampTy()); void clear(); - void eraseObjectEntry(StringRef Filename); private: /// Cache of static archives. Objects that are part of a static archive are /// stored under this object, rather than in the map below. StringMap> ArchiveCache; - StringMap ArchiveRefCounter; std::mutex ArchiveCacheMutex; /// Object entries for objects that are not in a static archive. StringMap> ObjectCache; - StringMap ObjectRefCounter; std::mutex ObjectCacheMutex; /// Virtual File System instance. diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp index d1c239e994f61..63dc699324710 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -123,22 +123,16 @@ static void dumpDIE(const DWARFDie *DIE, bool Verbose) { /// specific \p DIE related to the warning. void DwarfLinkerForBinary::reportWarning(Twine Warning, Twine Context, const DWARFDie *DIE) const { - // FIXME: implement warning logging which does not block other threads. - if (ErrorHandlerMutex.try_lock()) { - warn(Warning, Context); - dumpDIE(DIE, Options.Verbose); - ErrorHandlerMutex.unlock(); - } + std::lock_guard Guard(ErrorHandlerMutex); + warn(Warning, Context); + dumpDIE(DIE, Options.Verbose); } void DwarfLinkerForBinary::reportError(Twine Error, Twine Context, const DWARFDie *DIE) const { - // FIXME: implement error logging which does not block other threads. - if (ErrorHandlerMutex.try_lock()) { - error(Error, Context); - dumpDIE(DIE, Options.Verbose); - ErrorHandlerMutex.unlock(); - } + std::lock_guard Guard(ErrorHandlerMutex); + error(Error, Context); + dumpDIE(DIE, Options.Verbose); } ErrorOr @@ -239,23 +233,9 @@ DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj, if (ErrorOrObj) { Res = std::make_unique( - Obj.getObjectFilename(), - DWARFContext::create( - *ErrorOrObj, DWARFContext::ProcessDebugRelocations::Process, - nullptr, "", - [&](Error Err) { - handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) { - reportError(Info.message()); - }); - }, - [&](Error Warning) { - handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) { - reportWarning(Info.message()); - }); - }), + Obj.getObjectFilename(), DWARFContext::create(*ErrorOrObj), std::make_unique(*this, *ErrorOrObj, Obj), - Obj.empty() ? Obj.getWarnings() : EmptyWarnings, - [&](StringRef FileName) { BinHolder.eraseObjectEntry(FileName); }); + Obj.empty() ? Obj.getWarnings() : EmptyWarnings); Error E = RL.link(*ErrorOrObj); if (Error NewE = handleErrors( @@ -1059,10 +1039,8 @@ std::optional DwarfLinkerForBinary::AddressManager:: default: { assert(false && "Specified operation does not have address operand"); } break; - case dwarf::DW_OP_const2u: case dwarf::DW_OP_const4u: case dwarf::DW_OP_const8u: - case dwarf::DW_OP_const2s: case dwarf::DW_OP_const4s: case dwarf::DW_OP_const8s: case dwarf::DW_OP_addr: { diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp index fbbead16a0370..47a23e8448cc4 100644 --- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp +++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp @@ -98,18 +98,15 @@ class ObjFileAddressMap : public AddressMapBase { return std::nullopt; } - std::optional - getExprOpAddressRelocAdjustment(DWARFUnit &U, - const DWARFExpression::Operation &Op, - uint64_t, uint64_t) override { + std::optional getExprOpAddressRelocAdjustment( + DWARFUnit &U, const DWARFExpression::Operation &Op, uint64_t StartOffset, + uint64_t EndOffset) override { switch (Op.getCode()) { default: { assert(false && "Specified operation does not have address operand"); } break; - case dwarf::DW_OP_const2u: case dwarf::DW_OP_const4u: case dwarf::DW_OP_const8u: - case dwarf::DW_OP_const2s: case dwarf::DW_OP_const4s: case dwarf::DW_OP_const8s: case dwarf::DW_OP_addr: { @@ -290,33 +287,23 @@ static std::string getMessageForDeletedAcceleratorTables( template Error linkDebugInfoImpl(object::ObjectFile &File, const Options &Options, raw_pwrite_stream &OutStream) { - std::mutex ErrorHandlerMutex; - auto ReportWarn = [&](const Twine &Message, StringRef Context, const DWARFDie *Die) { - // FIXME: implement warning logging which does not block other threads. - if (!ErrorHandlerMutex.try_lock()) + warning(Message, Context); + + if (!Options.Verbose || !Die) return; - warning(Message, Context); - if (Options.Verbose && Die) { - DIDumpOptions DumpOpts; - DumpOpts.ChildRecurseDepth = 0; - DumpOpts.Verbose = Options.Verbose; + DIDumpOptions DumpOpts; + DumpOpts.ChildRecurseDepth = 0; + DumpOpts.Verbose = Options.Verbose; - WithColor::note() << " in DIE:\n"; - Die->dump(errs(), /*Indent=*/6, DumpOpts); - } - ErrorHandlerMutex.unlock(); + WithColor::note() << " in DIE:\n"; + Die->dump(errs(), /*Indent=*/6, DumpOpts); }; auto ReportErr = [&](const Twine &Message, StringRef Context, const DWARFDie *) { - // FIXME: implement error logging which does not block other threads. - if (!ErrorHandlerMutex.try_lock()) - return; - WithColor::error(errs(), Context) << Message << '\n'; - ErrorHandlerMutex.unlock(); }; // Create DWARF linker. @@ -338,18 +325,7 @@ Error linkDebugInfoImpl(object::ObjectFile &File, const Options &Options, std::vector EmptyWarnings; // Add object files to the DWARFLinker. - std::unique_ptr Context = DWARFContext::create( - File, DWARFContext::ProcessDebugRelocations::Process, nullptr, "", - [&](Error Err) { - handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) { - ReportErr(Info.message(), "", nullptr); - }); - }, - [&](Error Warning) { - handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) { - ReportWarn(Info.message(), "", nullptr); - }); - }); + std::unique_ptr Context = DWARFContext::create(File); std::unique_ptr> AddressesMap( std::make_unique>(*Context, Options, File)); diff --git a/llvm/unittests/CodeGen/DwarfStringPoolEntryRefTest.cpp b/llvm/unittests/CodeGen/DwarfStringPoolEntryRefTest.cpp index 25db003ea81de..6e901f7a18f27 100644 --- a/llvm/unittests/CodeGen/DwarfStringPoolEntryRefTest.cpp +++ b/llvm/unittests/CodeGen/DwarfStringPoolEntryRefTest.cpp @@ -61,25 +61,40 @@ bool isEntryEqual(const DwarfStringPoolEntry &LHS, } TEST(DwarfStringPoolEntryRefTest, TestShortEntry) { - DwarfStringPoolEntryWithExtString DwarfEntry1 = {{nullptr, 0, 0}, "Key1"}; + BumpPtrAllocator Allocator; + DwarfStringPoolEntry DwarfEntry1 = {nullptr, 0, 0}; + StringMapEntry *StringEntry1 = + StringMapEntry::create("Key1", Allocator, + &DwarfEntry1); + + EXPECT_TRUE(StringEntry1->getKey() == "Key1"); + EXPECT_TRUE(StringEntry1->second->Symbol == nullptr); + EXPECT_TRUE(StringEntry1->second->Offset == 0); + EXPECT_TRUE(StringEntry1->second->Index == 0); - DwarfStringPoolEntryRef Ref1(DwarfEntry1); + DwarfStringPoolEntryRef Ref1(*StringEntry1); EXPECT_TRUE(Ref1.getString() == "Key1"); EXPECT_TRUE(Ref1.getOffset() == 0); EXPECT_TRUE(Ref1.getIndex() == 0); EXPECT_TRUE(isEntryEqual(Ref1.getEntry(), DwarfEntry1)); - DwarfStringPoolEntryRef Ref2(DwarfEntry1); + DwarfStringPoolEntryRef Ref2(*StringEntry1); EXPECT_TRUE(Ref2.getString() == "Key1"); EXPECT_TRUE(Ref2.getOffset() == 0); EXPECT_TRUE(isEntryEqual(Ref2.getEntry(), DwarfEntry1)); EXPECT_TRUE(Ref1 == Ref2); EXPECT_FALSE(Ref1 != Ref2); - DwarfStringPoolEntryWithExtString DwarfEntry2 = {{nullptr, 0x1000, 1}, - "Key2"}; + DwarfStringPoolEntry DwarfEntry2 = {nullptr, 0x1000, 1}; + StringMapEntry *StringEntry2 = + StringMapEntry::create("Key2", Allocator, + &DwarfEntry2); + EXPECT_TRUE(StringEntry2->getKey() == "Key2"); + EXPECT_TRUE(StringEntry2->second->Symbol == nullptr); + EXPECT_TRUE(StringEntry2->second->Offset == 0x1000); + EXPECT_TRUE(StringEntry2->second->Index == 1); - DwarfStringPoolEntryRef Ref3(DwarfEntry2); + DwarfStringPoolEntryRef Ref3(*StringEntry2); EXPECT_TRUE(Ref3.getString() == "Key2"); EXPECT_TRUE(Ref3.getOffset() == 0x1000); EXPECT_TRUE(Ref3.getIndex() == 1); @@ -90,8 +105,11 @@ TEST(DwarfStringPoolEntryRefTest, TestShortEntry) { TEST(DwarfStringPoolEntryRefTest, CompareFullAndShort) { BumpPtrAllocator Allocator; - DwarfStringPoolEntryWithExtString DwarfEntry1 = {{nullptr, 0, 0}, "Key1"}; - DwarfStringPoolEntryRef Ref1(DwarfEntry1); + DwarfStringPoolEntry DwarfEntry1 = {nullptr, 0, 0}; + StringMapEntry *StringEntry1 = + StringMapEntry::create("Key1", Allocator, + &DwarfEntry1); + DwarfStringPoolEntryRef Ref1(*StringEntry1); StringMapEntry *StringEntry2 = StringMapEntry::create( diff --git a/llvm/unittests/DWARFLinkerParallel/CMakeLists.txt b/llvm/unittests/DWARFLinkerParallel/CMakeLists.txt index 5eeec23df4edb..e06806103b313 100644 --- a/llvm/unittests/DWARFLinkerParallel/CMakeLists.txt +++ b/llvm/unittests/DWARFLinkerParallel/CMakeLists.txt @@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS add_llvm_unittest(DWARFLinkerParallelTests DWARFLinkerTest.cpp StringPoolTest.cpp + StringTableTest.cpp ) target_link_libraries(DWARFLinkerParallelTests PRIVATE LLVMTestingSupport) diff --git a/llvm/unittests/DWARFLinkerParallel/StringPoolTest.cpp b/llvm/unittests/DWARFLinkerParallel/StringPoolTest.cpp index 84199f696a59d..11ae18c9e8621 100644 --- a/llvm/unittests/DWARFLinkerParallel/StringPoolTest.cpp +++ b/llvm/unittests/DWARFLinkerParallel/StringPoolTest.cpp @@ -28,17 +28,20 @@ TEST(StringPoolTest, TestStringPool) { std::pair Entry = Strings.insert("test"); EXPECT_TRUE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == "test"); + EXPECT_TRUE(Entry.first->second == nullptr); StringEntry *EntryPtr = Entry.first; Entry = Strings.insert("test"); EXPECT_FALSE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == "test"); + EXPECT_TRUE(Entry.first->second == nullptr); EXPECT_TRUE(EntryPtr == Entry.first); Entry = Strings.insert("test2"); EXPECT_TRUE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == "test2"); + EXPECT_TRUE(Entry.first->second == nullptr); EXPECT_TRUE(EntryPtr != Entry.first); }); } @@ -51,6 +54,7 @@ TEST(StringPoolTest, TestStringPoolParallel) { std::pair Entry = Strings.insert(std::to_string(Idx)); EXPECT_TRUE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == std::to_string(Idx)); + EXPECT_TRUE(Entry.first->second == nullptr); }); // Check data. @@ -58,6 +62,7 @@ TEST(StringPoolTest, TestStringPoolParallel) { std::pair Entry = Strings.insert(std::to_string(Idx)); EXPECT_FALSE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == std::to_string(Idx)); + EXPECT_TRUE(Entry.first->second == nullptr); }); } diff --git a/llvm/unittests/DWARFLinkerParallel/StringTableTest.cpp b/llvm/unittests/DWARFLinkerParallel/StringTableTest.cpp new file mode 100644 index 0000000000000..02bb95001acd4 --- /dev/null +++ b/llvm/unittests/DWARFLinkerParallel/StringTableTest.cpp @@ -0,0 +1,118 @@ +//===- llvm/unittest/DWARFLinkerParallel/StringTableTest.cpp --------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DWARFLinkerParallel/StringTable.h" +#include "llvm/Support/Parallel.h" +#include "gtest/gtest.h" +#include + +using namespace llvm; +using namespace dwarflinker_parallel; + +namespace { + +TEST(StringPoolTest, TestStringTable) { + struct StringDescription { + const char *Str = nullptr; + uint64_t Idx = 0; + uint64_t Offset = 0; + }; + + SmallVector InputStrings = { + {"first", 0, 0}, {"second", 1, 6}, {"third", 2, 13}}; + + StringPool Strings; + StringTable OutStrings(Strings, nullptr); + + // StringPool uses PerThreadBumpPtrAllocator which should be accessed from + // threads created by ThreadPoolExecutor. Use TaskGroup to run on + // ThreadPoolExecutor threads. + parallel::TaskGroup tg; + + tg.spawn([&]() { + // Check string insertion. + StringEntry *FirstPtr = Strings.insert(InputStrings[0].Str).first; + StringEntry *SecondPtr = Strings.insert(InputStrings[1].Str).first; + StringEntry *ThirdPtr = Strings.insert(InputStrings[2].Str).first; + + FirstPtr = OutStrings.add(FirstPtr); + SecondPtr = OutStrings.add(SecondPtr); + ThirdPtr = OutStrings.add(ThirdPtr); + + // Check fields of inserted strings. + EXPECT_TRUE(FirstPtr->getKey() == InputStrings[0].Str); + EXPECT_TRUE(FirstPtr->getValue()->Offset == InputStrings[0].Offset); + EXPECT_TRUE(FirstPtr->getValue()->Index == InputStrings[0].Idx); + + EXPECT_TRUE(SecondPtr->getKey() == InputStrings[1].Str); + EXPECT_TRUE(SecondPtr->getValue()->Offset == InputStrings[1].Offset); + EXPECT_TRUE(SecondPtr->getValue()->Index == InputStrings[1].Idx); + + EXPECT_TRUE(ThirdPtr->getKey() == InputStrings[2].Str); + EXPECT_TRUE(ThirdPtr->getValue()->Offset == InputStrings[2].Offset); + EXPECT_TRUE(ThirdPtr->getValue()->Index == InputStrings[2].Idx); + + // Check order enumerated strings. + uint64_t CurIdx = 0; + std::function checkStr = + [&](DwarfStringPoolEntryRef Entry) { + EXPECT_TRUE(Entry.getEntry().isIndexed()); + EXPECT_TRUE(Entry.getIndex() == CurIdx); + EXPECT_TRUE(Entry.getOffset() == InputStrings[CurIdx].Offset); + EXPECT_TRUE(Entry.getString() == InputStrings[CurIdx].Str); + + CurIdx++; + }; + + OutStrings.forEach(checkStr); + }); +} + +TEST(StringPoolTest, TestStringTableWithTranslator) { + std::string Word; + std::function TranslatorFunc = + [&](StringRef InputString) -> StringRef { + Word.clear(); + for (auto Sym : InputString) + Word.insert(Word.begin(), Sym); + Word += '0'; + return Word; + }; + + StringPool Strings; + StringTable OutStrings(Strings, TranslatorFunc); + + // StringPool uses PerThreadBumpPtrAllocator which should be accessed from + // threads created by ThreadPoolExecutor. Use TaskGroup to run on + // ThreadPoolExecutor threads. + parallel::TaskGroup tg; + + tg.spawn([&]() { + StringEntry *FirstPtr = Strings.insert("first").first; + StringEntry *SecondPtr = Strings.insert("second").first; + StringEntry *ThirdPtr = Strings.insert("third").first; + + FirstPtr = OutStrings.add(FirstPtr); + SecondPtr = OutStrings.add(SecondPtr); + ThirdPtr = OutStrings.add(ThirdPtr); + + EXPECT_TRUE(FirstPtr->getKey() == "tsrif0"); + EXPECT_TRUE(FirstPtr->getValue()->Offset == 0); + EXPECT_TRUE(FirstPtr->getValue()->Index == 0); + + EXPECT_TRUE(SecondPtr->getKey() == "dnoces0"); + EXPECT_TRUE(SecondPtr->getValue()->Offset == 7); + EXPECT_TRUE(SecondPtr->getValue()->Index == 1); + + EXPECT_TRUE(ThirdPtr->getKey() == "driht0"); + EXPECT_TRUE(ThirdPtr->getValue()->Offset == 15); + EXPECT_TRUE(ThirdPtr->getValue()->Index == 2); + }); +} + +} // anonymous namespace