Index: llvm/include/llvm/CodeGen/DWARFOptCompileUnit.h =================================================================== --- llvm/include/llvm/CodeGen/DWARFOptCompileUnit.h +++ llvm/include/llvm/CodeGen/DWARFOptCompileUnit.h @@ -1,4 +1,4 @@ -//===- tools/dsymutil/CompileUnit.h - Dwarf debug info linker ---*- C++ -*-===// +//===- DWARFOptCompileUnit.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. @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H -#define LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H +#ifndef LLVM_CODEGEN_DWARFOPTIMIZER_COMPILEUNIT_H +#define LLVM_CODEGEN_DWARFOPTIMIZER_COMPILEUNIT_H #include "llvm/ADT/IntervalMap.h" #include "llvm/CodeGen/DIE.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include "llvm/Support/DataExtractor.h" namespace llvm { -namespace dsymutil { class DeclContext; @@ -46,7 +46,7 @@ }; /// Stores all information relating to a compile unit, be it in its original -/// instance in the object file to its brand new cloned and linked DIE tree. +/// instance in the object file to its brand new cloned and generated DIE tree. class CompileUnit { public: /// Information gathered about a DIE in the object file. @@ -325,7 +325,6 @@ std::string ClangModuleName; }; -} // end namespace dsymutil } // end namespace llvm -#endif // LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H +#endif // LLVM_CODEGEN_DWARFOPTIMIZER_COMPILEUNIT_H Index: llvm/include/llvm/CodeGen/DWARFOptDeclContext.h =================================================================== --- llvm/include/llvm/CodeGen/DWARFOptDeclContext.h +++ llvm/include/llvm/CodeGen/DWARFOptDeclContext.h @@ -1,4 +1,4 @@ -//===- tools/dsymutil/DeclContext.h - Dwarf debug info linker ---*- C++ -*-===// +//===- DWARFOptDeclContext.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. @@ -6,20 +6,19 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H -#define LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H +#ifndef LLVM_CODEGEN_DWARFOPTIMIZER_DECLCONTEXT_H +#define LLVM_CODEGEN_DWARFOPTIMIZER_DECLCONTEXT_H -#include "CompileUnit.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/NonRelocatableStringpool.h" +#include "llvm/CodeGen/DWARFOptCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" #include "llvm/Support/Path.h" namespace llvm { -namespace dsymutil { struct DeclMapInfo; @@ -165,7 +164,6 @@ } }; -} // end namespace dsymutil } // end namespace llvm -#endif // LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H +#endif // LLVM_CODEGEN_DWARFOPTIMIZER_DECLCONTEXT_H Index: llvm/include/llvm/CodeGen/DWARFOptimizer.h =================================================================== --- /dev/null +++ llvm/include/llvm/CodeGen/DWARFOptimizer.h @@ -0,0 +1,86 @@ +//===- DWARFOptimizer.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_CODEGEN_DWARFOPTIMIZER_H +#define LLVM_CODEGEN_DWARFOPTIMIZER_H + +#include "llvm/CodeGen/NonRelocatableStringpool.h" +#include "llvm/CodeGen/DWARFOptDeclContext.h" +#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include + +namespace llvm { + +enum class DwarfOptimizerClient { Dsymutil, LLD, General }; + +/// Partial address range. Besides an offset, only the +/// HighPC is stored. The structure is stored in a map where the LowPC is the +/// key. +struct ObjFileAddressRange { + /// Function HighPC. + uint64_t HighPC; + /// Offset to apply to the linked address. + /// should be 0 for not-linked object file. + int64_t Offset; + + ObjFileAddressRange(uint64_t EndPC, int64_t Offset) + : HighPC(EndPC), Offset(Offset) {} + + ObjFileAddressRange() : HighPC(0), Offset(0) {} +}; + +/// Map LowPC to ObjFileAddressRange. +using RangesTy = std::map; + +/// AddressesMap represents information about valid addresses used +/// by debug information. Valid addresses are those which points to +/// live code sections. i.e. relocations for these addresses point +/// into sections which would be/are placed into resulting binary. +class AddressesMap { +public: + virtual ~AddressesMap(); + + /// Returns true if represented addresses are from linked file. + /// Returns false if represented addresses are from not-linked + /// object file. + virtual bool areRelocationsResolved() const = 0; + + /// Checks that there are valid relocations against a .debug_info + /// section. Reset current relocation pointer if neccessary. + virtual bool hasValidRelocs(bool resetRelocsPtr = true) = 0; + + /// Checks that there is a relocation against .debug_info + /// table between \p StartOffset and \p NextOffset. + /// + /// This function must be called with offsets in strictly ascending + /// order because it never looks back at relocations it already 'went past'. + /// \returns true and sets Info.InDebugMap if it is the case. + virtual bool hasValidRelocationAt(uint64_t StartOffset, uint64_t EndOffset, + CompileUnit::DIEInfo &Info) = 0; + + /// Apply the valid relocations to the buffer \p Data, taking into + /// account that Data is at \p BaseOffset in the debug_info section. + /// + /// This function must be called with monotonic \p BaseOffset values. + /// + /// \returns true whether any reloc has been applied. + virtual bool applyValidRelocs(MutableArrayRef Data, uint64_t BaseOffset, + bool IsLittleEndian) = 0; + + /// Returns all valid functions address ranges(i.e., those ranges + /// which points to sections with code). + virtual RangesTy &getValidAddressRanges() = 0; + + /// Erases all data. + virtual void clear() = 0; +}; + +} // end namespace llvm + +#endif // LLVM_CODEGEN_DWARFOPTIMIZER_H Index: llvm/include/llvm/CodeGen/NonRelocatableStringpool.h =================================================================== --- llvm/include/llvm/CodeGen/NonRelocatableStringpool.h +++ llvm/include/llvm/CodeGen/NonRelocatableStringpool.h @@ -1,4 +1,4 @@ -//===- llvm/CodeGen/NonRelocatableStringpool.h - A simple stringpool -----===// +//===- NonRelocatableStringpool.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. Index: llvm/lib/CodeGen/CMakeLists.txt =================================================================== --- llvm/lib/CodeGen/CMakeLists.txt +++ llvm/lib/CodeGen/CMakeLists.txt @@ -187,3 +187,4 @@ add_subdirectory(AsmPrinter) add_subdirectory(MIRParser) add_subdirectory(GlobalISel) +add_subdirectory(DWARFOptimizer) Index: llvm/lib/CodeGen/DWARFOptimizer/CMakeLists.txt =================================================================== --- /dev/null +++ llvm/lib/CodeGen/DWARFOptimizer/CMakeLists.txt @@ -0,0 +1,11 @@ +add_llvm_component_library(LLVMDWARFOptimizer + DWARFOptCompileUnit.cpp + DWARFOptDeclContext.cpp + DWARFOptimizer.cpp + + ADDITIONAL_HEADER_DIRS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/CodeGen + + DEPENDS + intrinsics_gen + ) Index: llvm/lib/CodeGen/DWARFOptimizer/DWARFOptCompileUnit.cpp =================================================================== --- llvm/lib/CodeGen/DWARFOptimizer/DWARFOptCompileUnit.cpp +++ llvm/lib/CodeGen/DWARFOptimizer/DWARFOptCompileUnit.cpp @@ -1,4 +1,4 @@ -//===- tools/dsymutil/CompileUnit.h - Dwarf compile unit ------------------===// +//===- DWARFOptCompileUnit.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,11 +6,10 @@ // //===----------------------------------------------------------------------===// -#include "CompileUnit.h" -#include "DeclContext.h" +#include "llvm/CodeGen/DWARFOptCompileUnit.h" +#include "llvm/CodeGen/DWARFOptDeclContext.h" namespace llvm { -namespace dsymutil { /// Check if the DIE at \p Idx is in the scope of a function. static bool inFunctionScope(CompileUnit &U, unsigned Idx) { @@ -142,5 +141,4 @@ Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation); } -} // namespace dsymutil } // namespace llvm Index: llvm/lib/CodeGen/DWARFOptimizer/DWARFOptDeclContext.cpp =================================================================== --- llvm/lib/CodeGen/DWARFOptimizer/DWARFOptDeclContext.cpp +++ llvm/lib/CodeGen/DWARFOptimizer/DWARFOptDeclContext.cpp @@ -1,4 +1,4 @@ -//===- tools/dsymutil/DeclContext.cpp - Declaration context ---------------===// +//===- DWARFOptDeclContext.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,13 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "DeclContext.h" +#include "llvm/CodeGen/DWARFOptDeclContext.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" namespace llvm { -namespace dsymutil { /// Set the last DIE/CU a context was seen in and, possibly invalidate the /// context if it is ambiguous. @@ -206,5 +205,5 @@ return PointerIntPair(*ContextIter); } -} // namespace dsymutil + } // namespace llvm Index: llvm/lib/CodeGen/DWARFOptimizer/DWARFOptimizer.cpp =================================================================== --- /dev/null +++ llvm/lib/CodeGen/DWARFOptimizer/DWARFOptimizer.cpp @@ -0,0 +1,15 @@ +//=== DWARFOptimizer.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/CodeGen/DWARFOptimizer.h" + +namespace llvm { + +AddressesMap::~AddressesMap() {} + +} // namespace llvm Index: llvm/lib/CodeGen/DWARFOptimizer/LLVMBuild.txt =================================================================== --- /dev/null +++ llvm/lib/CodeGen/DWARFOptimizer/LLVMBuild.txt @@ -0,0 +1,21 @@ +;===- ./lib/CodeGen/DWARFOptimizer/LLVMBuild.txt ---------------*- Conf -*--===; +; +; 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 +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = DWARFOptimizer +parent = CodeGen +required_libraries = DebugInfoDWARF AsmPrinter CodeGen MC Object Support Index: llvm/lib/CodeGen/LLVMBuild.txt =================================================================== --- llvm/lib/CodeGen/LLVMBuild.txt +++ llvm/lib/CodeGen/LLVMBuild.txt @@ -15,7 +15,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = AsmPrinter SelectionDAG MIRParser GlobalISel +subdirectories = AsmPrinter SelectionDAG MIRParser GlobalISel DWARFOptimizer [component_0] type = Library Index: llvm/lib/CodeGen/NonRelocatableStringpool.cpp =================================================================== --- llvm/lib/CodeGen/NonRelocatableStringpool.cpp +++ llvm/lib/CodeGen/NonRelocatableStringpool.cpp @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/NonRelocatableStringpool.cpp - A simple stringpool --===// +//===-- NonRelocatableStringpool.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. Index: llvm/tools/dsymutil/CMakeLists.txt =================================================================== --- llvm/tools/dsymutil/CMakeLists.txt +++ llvm/tools/dsymutil/CMakeLists.txt @@ -9,6 +9,7 @@ AllTargetsInfos AsmPrinter DebugInfoDWARF + DWARFOptimizer MC Object CodeGen @@ -22,9 +23,7 @@ dsymutil.cpp BinaryHolder.cpp CFBundle.cpp - CompileUnit.cpp DebugMap.cpp - DeclContext.cpp DwarfLinker.cpp DwarfStreamer.cpp MachODebugMapParser.cpp Index: llvm/tools/dsymutil/DwarfLinker.h =================================================================== --- llvm/tools/dsymutil/DwarfLinker.h +++ llvm/tools/dsymutil/DwarfLinker.h @@ -10,33 +10,17 @@ #define LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H #include "BinaryHolder.h" -#include "CompileUnit.h" #include "DebugMap.h" -#include "DeclContext.h" #include "DwarfStreamer.h" #include "LinkUtils.h" +#include "llvm/CodeGen/DWARFOptCompileUnit.h" +#include "llvm/CodeGen/DWARFOptDeclContext.h" +#include "llvm/CodeGen/DWARFOptimizer.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" namespace llvm { namespace dsymutil { -/// Partial address range for debug map objects. Besides an offset, only the -/// HighPC is stored. The structure is stored in a map where the LowPC is the -/// key. -struct DebugMapObjectRange { - /// Function HighPC. - uint64_t HighPC; - /// Offset to apply to the linked address. - int64_t Offset; - - DebugMapObjectRange(uint64_t EndPC, int64_t Offset) - : HighPC(EndPC), Offset(Offset) {} - - DebugMapObjectRange() : HighPC(0), Offset(0) {} -}; - -/// Map LowPC to DebugMapObjectRange. -using RangesTy = std::map; using UnitListTy = std::vector>; /// The core of the Dwarf linking logic. @@ -89,7 +73,7 @@ OffsetsStringPool &StringPool); /// Keeps track of relocations. - class RelocationManager { + class RelocationManager : public AddressesMap { struct ValidReloc { uint64_t Offset; uint32_t Size; @@ -117,13 +101,50 @@ /// cheap lookup during the root DIE selection and during DIE cloning. unsigned NextValidReloc = 0; + RangesTy AddressRanges; + public: - RelocationManager(DwarfLinker &Linker) : Linker(Linker) {} + RelocationManager(DwarfLinker &Linker, const object::ObjectFile &Obj, + const DebugMapObject &DMO) + : Linker(Linker) { + findValidRelocsInDebugInfo(Obj, DMO); + + // Iterate over the debug map entries and put all the ones that are + // functions (because they have a size) into the Ranges map. This map is + // very similar to the FunctionRanges that are stored in each unit, with 2 + // notable differences: + // + // 1. Obviously this one is global, while the other ones are per-unit. + // + // 2. This one contains not only the functions described in the DIE + // tree, but also the ones that are only in the debug map. + // + // The latter information is required to reproduce dsymutil's logic while + // linking line tables. The cases where this information matters look like + // bugs that need to be investigated, but for now we need to reproduce + // dsymutil's behavior. + // FIXME: Once we understood exactly if that information is needed, + // maybe totally remove this (or try to use it to do a real + // -gline-tables-only on Darwin. + for (const auto &Entry : DMO.symbols()) { + const auto &Mapping = Entry.getValue(); + if (Mapping.Size && Mapping.ObjectAddress) + AddressRanges[*Mapping.ObjectAddress] = ObjFileAddressRange( + *Mapping.ObjectAddress + Mapping.Size, + int64_t(Mapping.BinaryAddress) - *Mapping.ObjectAddress); + } + } + virtual ~RelocationManager () override { + clear(); + } - bool hasValidRelocs() const { return !ValidRelocs.empty(); } + virtual bool areRelocationsResolved() const override { return true; } - /// Reset the NextValidReloc counter. - void resetValidRelocs() { NextValidReloc = 0; } + bool hasValidRelocs(bool resetRelocsPtr = true) override { + if (resetRelocsPtr) + NextValidReloc = 0; + return !ValidRelocs.empty(); + } /// \defgroup FindValidRelocations Translate debug map into a list /// of relevant relocations @@ -141,32 +162,43 @@ const DebugMapObject &DMO); /// @} - bool hasValidRelocation(uint64_t StartOffset, uint64_t EndOffset, - CompileUnit::DIEInfo &Info); + bool hasValidRelocationAt(uint64_t StartOffset, uint64_t EndOffset, + CompileUnit::DIEInfo &Info) override; bool applyValidRelocs(MutableArrayRef Data, uint64_t BaseOffset, - bool IsLittleEndian); + bool IsLittleEndian) override; + + RangesTy &getValidAddressRanges() override { return AddressRanges; } + + void clear() override { + AddressRanges.clear(); + ValidRelocs.clear(); + NextValidReloc = 0; + } }; /// Keeps track of data associated with one object during linking. struct LinkContext { + DwarfLinker &Linker; DebugMapObject &DMO; - const object::ObjectFile *ObjectFile; - RelocationManager RelocMgr; + const object::ObjectFile *ObjectFile = nullptr; + std::unique_ptr RelocMgr; std::unique_ptr DwarfContext; RangesTy Ranges; UnitListTy CompileUnits; LinkContext(const DebugMap &Map, DwarfLinker &Linker, DebugMapObject &DMO) - : DMO(DMO), RelocMgr(Linker) { + : Linker(Linker), DMO(DMO) { // Swift ASTs are not object files. if (DMO.getType() == MachO::N_AST) { ObjectFile = nullptr; return; } - auto ErrOrObj = Linker.loadObject(DMO, Map); - ObjectFile = ErrOrObj ? &*ErrOrObj : nullptr; - DwarfContext = ObjectFile ? DWARFContext::create(*ObjectFile) : nullptr; + if (auto ErrOrObj = Linker.loadObject(DMO, Map)) { + ObjectFile = &*ErrOrObj; + DwarfContext = DWARFContext::create(*ObjectFile); + RelocMgr.reset(new RelocationManager(Linker, *ObjectFile, DMO)); + } } /// Clear part of the context that's no longer needed when we're done with @@ -175,6 +207,7 @@ DwarfContext.reset(nullptr); CompileUnits.clear(); Ranges.clear(); + RelocMgr->clear(); } }; Index: llvm/tools/dsymutil/DwarfLinker.cpp =================================================================== --- llvm/tools/dsymutil/DwarfLinker.cpp +++ llvm/tools/dsymutil/DwarfLinker.cpp @@ -9,7 +9,6 @@ #include "DwarfLinker.h" #include "BinaryHolder.h" #include "DebugMap.h" -#include "DeclContext.h" #include "DwarfStreamer.h" #include "MachOUtils.h" #include "dsymutil.h" @@ -36,6 +35,7 @@ #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DIE.h" #include "llvm/CodeGen/NonRelocatableStringpool.h" +#include "llvm/CodeGen/DWARFOptDeclContext.h" #include "llvm/Config/config.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" @@ -374,30 +374,6 @@ } void DwarfLinker::startDebugObject(LinkContext &Context) { - // Iterate over the debug map entries and put all the ones that are - // functions (because they have a size) into the Ranges map. This map is - // very similar to the FunctionRanges that are stored in each unit, with 2 - // notable differences: - // - // 1. Obviously this one is global, while the other ones are per-unit. - // - // 2. This one contains not only the functions described in the DIE - // tree, but also the ones that are only in the debug map. - // - // The latter information is required to reproduce dsymutil's logic while - // linking line tables. The cases where this information matters look like - // bugs that need to be investigated, but for now we need to reproduce - // dsymutil's behavior. - // FIXME: Once we understood exactly if that information is needed, - // maybe totally remove this (or try to use it to do a real - // -gline-tables-only on Darwin. - for (const auto &Entry : Context.DMO.symbols()) { - const auto &Mapping = Entry.getValue(); - if (Mapping.Size && Mapping.ObjectAddress) - Context.Ranges[*Mapping.ObjectAddress] = DebugMapObjectRange( - *Mapping.ObjectAddress + Mapping.Size, - int64_t(Mapping.BinaryAddress) - *Mapping.ObjectAddress); - } } void DwarfLinker::endDebugObject(LinkContext &Context) { @@ -560,7 +536,7 @@ /// This function must be called with offsets in strictly ascending /// order because it never looks back at relocations it already 'went past'. /// \returns true and sets Info.InDebugMap if it is the case. -bool DwarfLinker::RelocationManager::hasValidRelocation( +bool DwarfLinker::RelocationManager::hasValidRelocationAt( uint64_t StartOffset, uint64_t EndOffset, CompileUnit::DIEInfo &Info) { assert(NextValidReloc == 0 || StartOffset > ValidRelocs[NextValidReloc - 1].Offset); @@ -651,7 +627,8 @@ // always check if the variable has a valid relocation, so that the // DIEInfo is filled. However, we don't want a static variable in a // function to force us to keep the enclosing function. - if (!RelocMgr.hasValidRelocation(LocationOffset, LocationEndOffset, MyInfo) || + if (!RelocMgr.hasValidRelocationAt(LocationOffset, LocationEndOffset, + MyInfo) || (Flags & TF_InFunctionScope)) return Flags; @@ -689,7 +666,7 @@ auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc)); assert(LowPc.hasValue() && "low_pc attribute is not an address."); if (!LowPc || - !RelocMgr.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo)) + !RelocMgr.hasValidRelocationAt(LowPcOffset, LowPcEndOffset, MyInfo)) return Flags; if (Options.Verbose) { @@ -724,7 +701,7 @@ } // Replace the debug map range with a more accurate one. - Ranges[*LowPc] = DebugMapObjectRange(*HighPc, MyInfo.AddrAdjust); + Ranges[*LowPc] = ObjFileAddressRange(*HighPc, MyInfo.AddrAdjust); Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust); return Flags; } @@ -1651,7 +1628,8 @@ Data = DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize()); // Modify the copy with relocated addresses. - if (RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) { + if (RelocMgr.areRelocationsResolved() && + RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) { // If we applied relocations, we store the value of high_pc that was // potentially stored in the input DIE. If high_pc is an address // (Dwarf version == 2), then it might have been relocated to a @@ -2393,7 +2371,7 @@ // Setup access to the debug info. auto DwarfContext = DWARFContext::create(*ErrOrObj); - RelocationManager RelocMgr(*this); + RelocationManager RelocMgr(*this, *ErrOrObj, DMO); for (const auto &CU : DwarfContext->compile_units()) { updateDwarfVersion(CU->getVersion()); @@ -2774,8 +2752,7 @@ // Look for relocations that correspond to debug map entries. if (LLVM_LIKELY(!Options.Update) && - !LinkContext.RelocMgr.findValidRelocsInDebugInfo( - *LinkContext.ObjectFile, LinkContext.DMO)) { + !LinkContext.RelocMgr->hasValidRelocs()) { if (Options.Verbose) outs() << "No valid relocations found. Skipping.\n"; @@ -2892,7 +2869,7 @@ Streamer->copyInvariantDebugSection(*LinkContext.ObjectFile); } else { for (auto &CurrentUnit : LinkContext.CompileUnits) - lookForDIEsToKeep(LinkContext.RelocMgr, LinkContext.Ranges, + lookForDIEsToKeep(*LinkContext.RelocMgr, LinkContext.Ranges, LinkContext.CompileUnits, CurrentUnit->getOrigUnit().getUnitDIE(), LinkContext.DMO, *CurrentUnit, 0); @@ -2901,10 +2878,9 @@ // The calls to applyValidRelocs inside cloneDIE will walk the reloc // array again (in the same way findValidRelocsInDebugInfo() did). We // need to reset the NextValidReloc index to the beginning. - LinkContext.RelocMgr.resetValidRelocs(); - if (LinkContext.RelocMgr.hasValidRelocs() || LLVM_UNLIKELY(Options.Update)) - DIECloner(*this, LinkContext.RelocMgr, DIEAlloc, LinkContext.CompileUnits, - Options) + if (LinkContext.RelocMgr->hasValidRelocs() || LLVM_UNLIKELY(Options.Update)) + DIECloner(*this, *LinkContext.RelocMgr, DIEAlloc, + LinkContext.CompileUnits, Options) .cloneAllCompileUnits(*LinkContext.DwarfContext, LinkContext.DMO, LinkContext.Ranges, OffsetsStringPool, LinkContext.DwarfContext->isLittleEndian()); Index: llvm/tools/dsymutil/DwarfStreamer.h =================================================================== --- llvm/tools/dsymutil/DwarfStreamer.h +++ llvm/tools/dsymutil/DwarfStreamer.h @@ -9,11 +9,11 @@ #ifndef LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H #define LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H -#include "CompileUnit.h" #include "DebugMap.h" #include "LinkUtils.h" #include "llvm/CodeGen/AccelTable.h" #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/DWARFOptCompileUnit.h" #include "llvm/CodeGen/NonRelocatableStringpool.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" Index: llvm/tools/dsymutil/DwarfStreamer.cpp =================================================================== --- llvm/tools/dsymutil/DwarfStreamer.cpp +++ llvm/tools/dsymutil/DwarfStreamer.cpp @@ -7,10 +7,10 @@ //===----------------------------------------------------------------------===// #include "DwarfStreamer.h" -#include "CompileUnit.h" #include "LinkUtils.h" #include "MachOUtils.h" #include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/DWARFOptCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MCTargetOptionsCommandFlags.inc" Index: llvm/tools/dsymutil/LLVMBuild.txt =================================================================== --- llvm/tools/dsymutil/LLVMBuild.txt +++ llvm/tools/dsymutil/LLVMBuild.txt @@ -18,4 +18,4 @@ type = Tool name = dsymutil parent = Tools -required_libraries = AsmPrinter DebugInfoDWARF MC Object CodeGen Support all-targets +required_libraries = AsmPrinter DebugInfoDWARF DWARFOptimizer MC Object CodeGen Support all-targets