[llvm] 1cf11a4 - [Dsymutil][Debuginfo][NFC] Reland: Refactor dsymutil to separate DWARF optimizing part. #2.

Alexey Lapshin via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 8 03:15:37 PST 2020


Author: Alexey Lapshin
Date: 2020-01-08T14:15:31+03:00
New Revision: 1cf11a4c67a15ab5493ef424c898accf49012caa

URL: https://github.com/llvm/llvm-project/commit/1cf11a4c67a15ab5493ef424c898accf49012caa
DIFF: https://github.com/llvm/llvm-project/commit/1cf11a4c67a15ab5493ef424c898accf49012caa.diff

LOG: [Dsymutil][Debuginfo][NFC] Reland: Refactor dsymutil to separate DWARF optimizing part. #2.

Summary:
This patch relands D71271. The problem with D71271 is that it has cyclic dependency:
CodeGen->AsmPrinter->DebugInfoDWARF->CodeGen. To avoid cyclic dependency this patch
puts implementation for DWARFOptimizer into separate library: lib/DWARFLinker.

Thus the difference between this patch and D71271 is in that DWARFOptimizer renamed into
DWARFLinker and it`s files are put into lib/DWARFLinker.

Reviewers: JDevlieghere, friss, dblaikie, aprantl

Reviewed By: JDevlieghere

Subscribers: thegameg, merge_guards_bot, probinson, mgorny, hiraditya, llvm-commits

Tags: #llvm, #debug-info

Differential Revision: https://reviews.llvm.org/D71839

Added: 
    llvm/include/llvm/DWARFLinker/DWARFLinker.h
    llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
    llvm/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
    llvm/lib/DWARFLinker/CMakeLists.txt
    llvm/lib/DWARFLinker/DWARFLinker.cpp
    llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
    llvm/lib/DWARFLinker/DWARFLinkerDeclContext.cpp
    llvm/lib/DWARFLinker/LLVMBuild.txt
    llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
    llvm/tools/dsymutil/DwarfLinkerForBinary.h

Modified: 
    llvm/include/llvm/CodeGen/NonRelocatableStringpool.h
    llvm/lib/CMakeLists.txt
    llvm/lib/CodeGen/NonRelocatableStringpool.cpp
    llvm/lib/LLVMBuild.txt
    llvm/tools/dsymutil/CMakeLists.txt
    llvm/tools/dsymutil/DwarfStreamer.cpp
    llvm/tools/dsymutil/DwarfStreamer.h
    llvm/tools/dsymutil/LLVMBuild.txt

Removed: 
    llvm/tools/dsymutil/CompileUnit.cpp
    llvm/tools/dsymutil/CompileUnit.h
    llvm/tools/dsymutil/DeclContext.cpp
    llvm/tools/dsymutil/DeclContext.h
    llvm/tools/dsymutil/DwarfLinker.cpp
    llvm/tools/dsymutil/DwarfLinker.h


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h b/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h
index f7d082e2a2ba..56db30ff7d6d 100644
--- a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h
+++ b/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.

diff  --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h
new file mode 100644
index 000000000000..218c9641bfb1
--- /dev/null
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h
@@ -0,0 +1,86 @@
+//===- DWARFLinker.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_DWARFLINKER_DWARFLINKER_H
+#define LLVM_DWARFLINKER_DWARFLINKER_H
+
+#include "llvm/CodeGen/NonRelocatableStringpool.h"
+#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include <map>
+
+namespace llvm {
+
+enum class DwarfLinkerClient { 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<uint64_t, ObjFileAddressRange>;
+
+/// 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<char> 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_DWARFLINKER_DWARFLINKER_H

diff  --git a/llvm/tools/dsymutil/CompileUnit.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
similarity index 97%
rename from llvm/tools/dsymutil/CompileUnit.h
rename to llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
index e0f5d3bc65b2..7873a16fea52 100644
--- a/llvm/tools/dsymutil/CompileUnit.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
@@ -1,4 +1,4 @@
-//===- tools/dsymutil/CompileUnit.h - Dwarf debug info linker ---*- C++ -*-===//
+//===- DWARFLinkerCompileUnit.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_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H
+#define LLVM_DWARFLINKER_DWARFLINKERCOMPILEUNIT_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 @@ struct PatchLocation {
 };
 
 /// 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 @@ class CompileUnit {
   std::string ClangModuleName;
 };
 
-} // end namespace dsymutil
 } // end namespace llvm
 
-#endif // LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
+#endif // LLVM_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H

diff  --git a/llvm/tools/dsymutil/DeclContext.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
similarity index 95%
rename from llvm/tools/dsymutil/DeclContext.h
rename to llvm/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
index 36ef50944083..db40254bf600 100644
--- a/llvm/tools/dsymutil/DeclContext.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
@@ -1,4 +1,4 @@
-//===- tools/dsymutil/DeclContext.h - Dwarf debug info linker ---*- C++ -*-===//
+//===- DWARFLinkerDeclContext.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_DWARFLINKER_DWARFLINKERDECLCONTEXT_H
+#define LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_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/DWARFLinker/DWARFLinkerCompileUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
 #include "llvm/Support/Path.h"
 
 namespace llvm {
-namespace dsymutil {
 
 struct DeclMapInfo;
 
@@ -165,7 +164,6 @@ struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
   }
 };
 
-} // end namespace dsymutil
 } // end namespace llvm
 
-#endif // LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
+#endif // LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H

diff  --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt
index f7e08a68e673..8f8d417124c8 100644
--- a/llvm/lib/CMakeLists.txt
+++ b/llvm/lib/CMakeLists.txt
@@ -8,6 +8,7 @@ add_subdirectory(CodeGen)
 add_subdirectory(BinaryFormat)
 add_subdirectory(Bitcode)
 add_subdirectory(Bitstream)
+add_subdirectory(DWARFLinker)
 add_subdirectory(Frontend)
 add_subdirectory(Transforms)
 add_subdirectory(Linker)

diff  --git a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp
index d28399f239ce..9ed3471c0fc9 100644
--- a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp
+++ b/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.

diff  --git a/llvm/lib/DWARFLinker/CMakeLists.txt b/llvm/lib/DWARFLinker/CMakeLists.txt
new file mode 100644
index 000000000000..09610f006fdb
--- /dev/null
+++ b/llvm/lib/DWARFLinker/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_llvm_component_library(LLVMDWARFLinker
+  DWARFLinkerCompileUnit.cpp
+  DWARFLinkerDeclContext.cpp
+  DWARFLinker.cpp
+
+  )

diff  --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp
new file mode 100644
index 000000000000..e26148a1096b
--- /dev/null
+++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp
@@ -0,0 +1,15 @@
+//=== DWARFLinker.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/DWARFLinker/DWARFLinker.h"
+
+namespace llvm {
+
+AddressesMap::~AddressesMap() {}
+
+} // namespace llvm

diff  --git a/llvm/tools/dsymutil/CompileUnit.cpp b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
similarity index 96%
rename from llvm/tools/dsymutil/CompileUnit.cpp
rename to llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
index 036c61a6b926..e4de01676dca 100644
--- a/llvm/tools/dsymutil/CompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
@@ -1,4 +1,4 @@
-//===- tools/dsymutil/CompileUnit.h - Dwarf compile unit ------------------===//
+//===- 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.
@@ -6,11 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "CompileUnit.h"
-#include "DeclContext.h"
+#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
+#include "llvm/DWARFLinker/DWARFLinkerDeclContext.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 @@ void CompileUnit::addTypeAccelerator(const DIE *Die,
   Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
 }
 
-} // namespace dsymutil
 } // namespace llvm

diff  --git a/llvm/tools/dsymutil/DeclContext.cpp b/llvm/lib/DWARFLinker/DWARFLinkerDeclContext.cpp
similarity index 98%
rename from llvm/tools/dsymutil/DeclContext.cpp
rename to llvm/lib/DWARFLinker/DWARFLinkerDeclContext.cpp
index 1c33b672c26b..077fd4494241 100644
--- a/llvm/tools/dsymutil/DeclContext.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinkerDeclContext.cpp
@@ -1,4 +1,4 @@
-//===- tools/dsymutil/DeclContext.cpp - Declaration context ---------------===//
+//===- DWARFLinkerDeclContext.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/DWARFLinker/DWARFLinkerDeclContext.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 @@ PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext(
 
   return PointerIntPair<DeclContext *, 1>(*ContextIter);
 }
-} // namespace dsymutil
+
 } // namespace llvm

diff  --git a/llvm/lib/DWARFLinker/LLVMBuild.txt b/llvm/lib/DWARFLinker/LLVMBuild.txt
new file mode 100644
index 000000000000..b32ea3d9e741
--- /dev/null
+++ b/llvm/lib/DWARFLinker/LLVMBuild.txt
@@ -0,0 +1,21 @@
+;===- ./lib/DWARFLinker/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 = DWARFLinker
+parent = Libraries
+required_libraries = DebugInfoDWARF AsmPrinter CodeGen MC Object Support

diff  --git a/llvm/lib/LLVMBuild.txt b/llvm/lib/LLVMBuild.txt
index 3f5383d9b1f1..1ae59791cd6c 100644
--- a/llvm/lib/LLVMBuild.txt
+++ b/llvm/lib/LLVMBuild.txt
@@ -23,6 +23,7 @@ subdirectories =
  CodeGen
  DebugInfo
  Demangle
+ DWARFLinker
  ExecutionEngine
  Frontend
  FuzzMutate

diff  --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt
index b8466baa6346..fecd8a61ad00 100644
--- a/llvm/tools/dsymutil/CMakeLists.txt
+++ b/llvm/tools/dsymutil/CMakeLists.txt
@@ -9,6 +9,7 @@ set(LLVM_LINK_COMPONENTS
   AllTargetsInfos
   AsmPrinter
   DebugInfoDWARF
+  DWARFLinker
   MC
   Object
   CodeGen
@@ -22,10 +23,8 @@ add_llvm_tool(dsymutil
   dsymutil.cpp
   BinaryHolder.cpp
   CFBundle.cpp
-  CompileUnit.cpp
   DebugMap.cpp
-  DeclContext.cpp
-  DwarfLinker.cpp
+  DwarfLinkerForBinary.cpp
   DwarfStreamer.cpp
   MachODebugMapParser.cpp
   MachOUtils.cpp

diff  --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
similarity index 93%
rename from llvm/tools/dsymutil/DwarfLinker.cpp
rename to llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
index 53f6b2899b00..b42fc1a1d506 100644
--- a/llvm/tools/dsymutil/DwarfLinker.cpp
+++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
@@ -1,4 +1,4 @@
-//===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===//
+//===- tools/dsymutil/DwarfLinkerForBinary.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,10 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "DwarfLinker.h"
+#include "DwarfLinkerForBinary.h"
 #include "BinaryHolder.h"
 #include "DebugMap.h"
-#include "DeclContext.h"
 #include "DwarfStreamer.h"
 #include "MachOUtils.h"
 #include "dsymutil.h"
@@ -37,6 +36,7 @@
 #include "llvm/CodeGen/DIE.h"
 #include "llvm/CodeGen/NonRelocatableStringpool.h"
 #include "llvm/Config/config.h"
+#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
@@ -119,7 +119,7 @@ static CompileUnit *getUnitForOffset(const UnitListTy &Units, uint64_t Offset) {
 /// Resolve the DIE attribute reference that has been extracted in \p RefValue.
 /// The resulting DIE might be in another CompileUnit which is stored into \p
 /// ReferencedCU. \returns null if resolving fails for any reason.
-static DWARFDie resolveDIEReference(const DwarfLinker &Linker,
+static DWARFDie resolveDIEReference(const DwarfLinkerForBinary &Linker,
                                     const DebugMapObject &DMO,
                                     const UnitListTy &Units,
                                     const DWARFFormValue &RefValue,
@@ -188,7 +188,8 @@ static bool isTypeTag(uint16_t Tag) {
   return false;
 }
 
-static Error remarksErrorHandler(const DebugMapObject &DMO, DwarfLinker &Linker,
+static Error remarksErrorHandler(const DebugMapObject &DMO,
+                                 DwarfLinkerForBinary &Linker,
                                  std::unique_ptr<FileError> FE) {
   bool IsArchive = DMO.getObjectFilename().endswith(")");
   // Don't report errors for missing remark files from static
@@ -212,10 +213,10 @@ static Error remarksErrorHandler(const DebugMapObject &DMO, DwarfLinker &Linker,
   return createFileError(FE->getFileName(), std::move(NewE));
 }
 
-bool DwarfLinker::DIECloner::getDIENames(const DWARFDie &Die,
-                                         AttributesInfo &Info,
-                                         OffsetsStringPool &StringPool,
-                                         bool StripTemplate) {
+bool DwarfLinkerForBinary::DIECloner::getDIENames(const DWARFDie &Die,
+                                                  AttributesInfo &Info,
+                                                  OffsetsStringPool &StringPool,
+                                                  bool StripTemplate) {
   // This function will be called on DIEs having low_pcs and
   // ranges. As getting the name might be more expansive, filter out
   // blocks directly.
@@ -244,8 +245,9 @@ bool DwarfLinker::DIECloner::getDIENames(const DWARFDie &Die,
 
 /// Report a warning to the user, optionally including information about a
 /// specific \p DIE related to the warning.
-void DwarfLinker::reportWarning(const Twine &Warning, const DebugMapObject &DMO,
-                                const DWARFDie *DIE) const {
+void DwarfLinkerForBinary::reportWarning(const Twine &Warning,
+                                         const DebugMapObject &DMO,
+                                         const DWARFDie *DIE) const {
   StringRef Context = DMO.getObjectFilename();
   warn(Warning, Context);
 
@@ -260,8 +262,8 @@ void DwarfLinker::reportWarning(const Twine &Warning, const DebugMapObject &DMO,
   DIE->dump(errs(), 6 /* Indent */, DumpOpts);
 }
 
-bool DwarfLinker::createStreamer(const Triple &TheTriple,
-                                 raw_fd_ostream &OutFile) {
+bool DwarfLinkerForBinary::createStreamer(const Triple &TheTriple,
+                                          raw_fd_ostream &OutFile) {
   if (Options.NoOutput)
     return true;
 
@@ -397,34 +399,9 @@ static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) {
   llvm_unreachable("Invalid Tag");
 }
 
-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 
diff erences:
-  //
-  //  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 DwarfLinkerForBinary::startDebugObject(LinkContext &Context) {}
 
-void DwarfLinker::endDebugObject(LinkContext &Context) {
+void DwarfLinkerForBinary::endDebugObject(LinkContext &Context) {
   Context.Clear();
 
   for (auto I = DIEBlocks.begin(), E = DIEBlocks.end(); I != E; ++I)
@@ -460,7 +437,7 @@ static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) {
 /// Iterate over the relocations of the given \p Section and
 /// store the ones that correspond to debug map entries into the
 /// ValidRelocs array.
-void DwarfLinker::RelocationManager::findValidRelocsMachO(
+void DwarfLinkerForBinary::RelocationManager::findValidRelocsMachO(
     const object::SectionRef &Section, const object::MachOObjectFile &Obj,
     const DebugMapObject &DMO) {
   Expected<StringRef> ContentsOrErr = Section.getContents();
@@ -534,7 +511,7 @@ void DwarfLinker::RelocationManager::findValidRelocsMachO(
 
 /// Dispatch the valid relocation finding logic to the
 /// appropriate handler depending on the object file format.
-bool DwarfLinker::RelocationManager::findValidRelocs(
+bool DwarfLinkerForBinary::RelocationManager::findValidRelocs(
     const object::SectionRef &Section, const object::ObjectFile &Obj,
     const DebugMapObject &DMO) {
   // Dispatch to the right handler depending on the file type.
@@ -560,7 +537,7 @@ bool DwarfLinker::RelocationManager::findValidRelocs(
 /// link by indicating which DIEs refer to symbols present in the
 /// linked binary.
 /// \returns whether there are any valid relocations in the debug info.
-bool DwarfLinker::RelocationManager::findValidRelocsInDebugInfo(
+bool DwarfLinkerForBinary::RelocationManager::findValidRelocsInDebugInfo(
     const object::ObjectFile &Obj, const DebugMapObject &DMO) {
   // Find the debug_info section.
   for (const object::SectionRef &Section : Obj.sections()) {
@@ -584,7 +561,7 @@ bool DwarfLinker::RelocationManager::findValidRelocsInDebugInfo(
 /// 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 DwarfLinkerForBinary::RelocationManager::hasValidRelocationAt(
     uint64_t StartOffset, uint64_t EndOffset, CompileUnit::DIEInfo &Info) {
   assert(NextValidReloc == 0 ||
          StartOffset > ValidRelocs[NextValidReloc - 1].Offset);
@@ -645,11 +622,9 @@ getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx,
 
 /// Check if a variable describing DIE should be kept.
 /// \returns updated TraversalFlags.
-unsigned DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr,
-                                            const DWARFDie &DIE,
-                                            CompileUnit &Unit,
-                                            CompileUnit::DIEInfo &MyInfo,
-                                            unsigned Flags) {
+unsigned DwarfLinkerForBinary::shouldKeepVariableDIE(
+    RelocationManager &RelocMgr, const DWARFDie &DIE, CompileUnit &Unit,
+    CompileUnit::DIEInfo &MyInfo, unsigned Flags) {
   const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
 
   // Global variables with constant value can always be kept.
@@ -675,7 +650,8 @@ unsigned DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr,
   // 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;
 
@@ -692,7 +668,7 @@ unsigned DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr,
 
 /// Check if a function describing DIE should be kept.
 /// \returns updated TraversalFlags.
-unsigned DwarfLinker::shouldKeepSubprogramDIE(
+unsigned DwarfLinkerForBinary::shouldKeepSubprogramDIE(
     RelocationManager &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE,
     const DebugMapObject &DMO, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
     unsigned Flags) {
@@ -713,7 +689,7 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
   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) {
@@ -748,19 +724,17 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
   }
 
   // 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;
 }
 
 /// Check if a DIE should be kept.
 /// \returns updated TraversalFlags.
-unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr,
-                                    RangesTy &Ranges, const DWARFDie &DIE,
-                                    const DebugMapObject &DMO,
-                                    CompileUnit &Unit,
-                                    CompileUnit::DIEInfo &MyInfo,
-                                    unsigned Flags) {
+unsigned DwarfLinkerForBinary::shouldKeepDIE(
+    RelocationManager &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE,
+    const DebugMapObject &DMO, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
+    unsigned Flags) {
   switch (DIE.getTag()) {
   case dwarf::DW_TAG_constant:
   case dwarf::DW_TAG_variable:
@@ -885,11 +859,11 @@ static void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
   // the parent chain). There are however a set of DIE types for which we want
   // to ignore that directive and still walk their children.
   if (dieNeedsChildrenToBeMeaningful(Die.getTag()))
-    Flags &= ~DwarfLinker::TF_ParentWalk;
+    Flags &= ~DwarfLinkerForBinary::TF_ParentWalk;
 
   // We're finished if this DIE has no children or we're walking the parent
   // chain.
-  if (!Die.hasChildren() || (Flags & DwarfLinker::TF_ParentWalk))
+  if (!Die.hasChildren() || (Flags & DwarfLinkerForBinary::TF_ParentWalk))
     return;
 
   // Add children in reverse order to the worklist to effectively process them
@@ -908,12 +882,12 @@ static void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
 /// Look at DIEs referenced by the given DIE and decide whether they should be
 /// kept. All DIEs referenced though attributes should be kept.
 static void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
-                                 unsigned Flags, DwarfLinker &Linker,
+                                 unsigned Flags, DwarfLinkerForBinary &Linker,
                                  const UnitListTy &Units,
                                  const DebugMapObject &DMO,
                                  SmallVectorImpl<WorklistItem> &Worklist) {
-  bool UseOdr = (Flags & DwarfLinker::TF_DependencyWalk)
-                    ? (Flags & DwarfLinker::TF_ODR)
+  bool UseOdr = (Flags & DwarfLinkerForBinary::TF_DependencyWalk)
+                    ? (Flags & DwarfLinkerForBinary::TF_ODR)
                     : CU.hasODR();
   DWARFUnit &Unit = CU.getOrigUnit();
   DWARFDataExtractor Data = Unit.getDebugInfoExtractor();
@@ -962,7 +936,7 @@ static void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
     }
   }
 
-  unsigned ODRFlag = UseOdr ? DwarfLinker::TF_ODR : 0;
+  unsigned ODRFlag = UseOdr ? DwarfLinkerForBinary::TF_ODR : 0;
 
   // Add referenced DIEs in reverse order to the worklist to effectively
   // process them in order.
@@ -974,8 +948,9 @@ static void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
     Worklist.emplace_back(Die, CU, WorklistItemType::UpdateRefIncompleteness,
                           &Info);
     Worklist.emplace_back(P.first, P.second,
-                          DwarfLinker::TF_Keep |
-                              DwarfLinker::TF_DependencyWalk | ODRFlag);
+                          DwarfLinkerForBinary::TF_Keep |
+                              DwarfLinkerForBinary::TF_DependencyWalk |
+                              ODRFlag);
   }
 }
 
@@ -1018,11 +993,12 @@ static void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
 /// UpdateRefIncompleteness).
 ///
 /// The return value indicates whether the DIE is incomplete.
-void DwarfLinker::lookForDIEsToKeep(RelocationManager &RelocMgr,
-                                    RangesTy &Ranges, const UnitListTy &Units,
-                                    const DWARFDie &Die,
-                                    const DebugMapObject &DMO, CompileUnit &Cu,
-                                    unsigned Flags) {
+void DwarfLinkerForBinary::lookForDIEsToKeep(RelocationManager &RelocMgr,
+                                             RangesTy &Ranges,
+                                             const UnitListTy &Units,
+                                             const DWARFDie &Die,
+                                             const DebugMapObject &DMO,
+                                             CompileUnit &Cu, unsigned Flags) {
   // LIFO work list.
   SmallVector<WorklistItem, 4> Worklist;
   Worklist.emplace_back(Die, Cu, Flags);
@@ -1113,7 +1089,7 @@ void DwarfLinker::lookForDIEsToKeep(RelocationManager &RelocMgr,
 /// thus the FoldingSet we use to unique DIEAbbrevs cannot refer to
 /// the instances hold by the DIEs. When we encounter an abbreviation
 /// that we don't know, we create a permanent copy of it.
-void DwarfLinker::AssignAbbrev(DIEAbbrev &Abbrev) {
+void DwarfLinkerForBinary::assignAbbrev(DIEAbbrev &Abbrev) {
   // Check the set for priors.
   FoldingSetNodeID ID;
   Abbrev.Profile(ID);
@@ -1137,7 +1113,7 @@ void DwarfLinker::AssignAbbrev(DIEAbbrev &Abbrev) {
   }
 }
 
-unsigned DwarfLinker::DIECloner::cloneStringAttribute(
+unsigned DwarfLinkerForBinary::DIECloner::cloneStringAttribute(
     DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
     const DWARFUnit &U, OffsetsStringPool &StringPool, AttributesInfo &Info) {
   // Switch everything to out of line strings.
@@ -1157,7 +1133,7 @@ unsigned DwarfLinker::DIECloner::cloneStringAttribute(
   return 4;
 }
 
-unsigned DwarfLinker::DIECloner::cloneDieReferenceAttribute(
+unsigned DwarfLinkerForBinary::DIECloner::cloneDieReferenceAttribute(
     DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec,
     unsigned AttrSize, const DWARFFormValue &Val, const DebugMapObject &DMO,
     CompileUnit &Unit) {
@@ -1228,7 +1204,7 @@ unsigned DwarfLinker::DIECloner::cloneDieReferenceAttribute(
   return AttrSize;
 }
 
-void DwarfLinker::DIECloner::cloneExpression(
+void DwarfLinkerForBinary::DIECloner::cloneExpression(
     DataExtractor &Data, DWARFExpression Expression, const DebugMapObject &DMO,
     CompileUnit &Unit, SmallVectorImpl<uint8_t> &OutputBuffer) {
   using Encoding = DWARFExpression::Operation::Encoding;
@@ -1288,7 +1264,7 @@ void DwarfLinker::DIECloner::cloneExpression(
   }
 }
 
-unsigned DwarfLinker::DIECloner::cloneBlockAttribute(
+unsigned DwarfLinkerForBinary::DIECloner::cloneBlockAttribute(
     DIE &Die, const DebugMapObject &DMO, CompileUnit &Unit,
     AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize,
     bool IsLittleEndian) {
@@ -1346,7 +1322,7 @@ unsigned DwarfLinker::DIECloner::cloneBlockAttribute(
   return AttrSize;
 }
 
-unsigned DwarfLinker::DIECloner::cloneAddressAttribute(
+unsigned DwarfLinkerForBinary::DIECloner::cloneAddressAttribute(
     DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
     const CompileUnit &Unit, AttributesInfo &Info) {
   uint64_t Addr = *Val.getAsAddress();
@@ -1394,7 +1370,7 @@ unsigned DwarfLinker::DIECloner::cloneAddressAttribute(
   return Unit.getOrigUnit().getAddressByteSize();
 }
 
-unsigned DwarfLinker::DIECloner::cloneScalarAttribute(
+unsigned DwarfLinkerForBinary::DIECloner::cloneScalarAttribute(
     DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO,
     CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val,
     unsigned AttrSize, AttributesInfo &Info) {
@@ -1451,7 +1427,7 @@ unsigned DwarfLinker::DIECloner::cloneScalarAttribute(
   // location list.
   // FIXME: use DWARFAttribute::mayHaveLocationDescription().
   else if (AttrSpec.Attr == dwarf::DW_AT_location ||
-         AttrSpec.Attr == dwarf::DW_AT_frame_base)
+           AttrSpec.Attr == dwarf::DW_AT_frame_base)
     Unit.noteLocationAttribute(Patch, Info.PCOffset);
   else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
     Info.IsDeclaration = true;
@@ -1462,7 +1438,7 @@ unsigned DwarfLinker::DIECloner::cloneScalarAttribute(
 /// Clone \p InputDIE's attribute described by \p AttrSpec with
 /// value \p Val, and add it to \p Die.
 /// \returns the size of the cloned attribute.
-unsigned DwarfLinker::DIECloner::cloneAttribute(
+unsigned DwarfLinkerForBinary::DIECloner::cloneAttribute(
     DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO,
     CompileUnit &Unit, OffsetsStringPool &StringPool, const DWARFFormValue &Val,
     const AttributeSpec AttrSpec, unsigned AttrSize, AttributesInfo &Info,
@@ -1517,7 +1493,7 @@ unsigned DwarfLinker::DIECloner::cloneAttribute(
 /// monotonic \p BaseOffset values.
 ///
 /// \returns whether any reloc has been applied.
-bool DwarfLinker::RelocationManager::applyValidRelocs(
+bool DwarfLinkerForBinary::RelocationManager::applyValidRelocs(
     MutableArrayRef<char> Data, uint64_t BaseOffset, bool IsLittleEndian) {
   assert((NextValidReloc == 0 ||
           BaseOffset > ValidRelocs[NextValidReloc - 1].Offset) &&
@@ -1558,11 +1534,9 @@ static bool isObjCSelector(StringRef Name) {
          (Name[1] == '[');
 }
 
-void DwarfLinker::DIECloner::addObjCAccelerator(CompileUnit &Unit,
-                                                const DIE *Die,
-                                                DwarfStringPoolEntryRef Name,
-                                                OffsetsStringPool &StringPool,
-                                                bool SkipPubSection) {
+void DwarfLinkerForBinary::DIECloner::addObjCAccelerator(
+    CompileUnit &Unit, const DIE *Die, DwarfStringPoolEntryRef Name,
+    OffsetsStringPool &StringPool, bool SkipPubSection) {
   assert(isObjCSelector(Name.getString()) && "not an objc selector");
   // Objective C method or class function.
   // "- [Class(Category) selector :withArg ...]"
@@ -1624,7 +1598,7 @@ shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
   }
 }
 
-DIE *DwarfLinker::DIECloner::cloneDIE(
+DIE *DwarfLinkerForBinary::DIECloner::cloneDIE(
     const DWARFDie &InputDIE, const DebugMapObject &DMO, CompileUnit &Unit,
     OffsetsStringPool &StringPool, int64_t PCOffset, uint32_t OutOffset,
     unsigned Flags, bool IsLittleEndian, DIE *Die) {
@@ -1675,7 +1649,8 @@ DIE *DwarfLinker::DIECloner::cloneDIE(
   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
@@ -1793,7 +1768,7 @@ DIE *DwarfLinker::DIECloner::cloneDIE(
   if (HasChildren)
     NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
   // Assign a permanent abbrev number
-  Linker.AssignAbbrev(NewAbbrev);
+  Linker.assignAbbrev(NewAbbrev);
   Die->setAbbrevNumber(NewAbbrev.getNumber());
 
   // Add the size of the abbreviation number to the output offset.
@@ -1824,9 +1799,9 @@ DIE *DwarfLinker::DIECloner::cloneDIE(
 /// Patch the input object file relevant debug_ranges entries
 /// and emit them in the output file. Update the relevant attributes
 /// to point at the new entries.
-void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit,
-                                     DWARFContext &OrigDwarf,
-                                     const DebugMapObject &DMO) const {
+void DwarfLinkerForBinary::patchRangesForUnit(const CompileUnit &Unit,
+                                              DWARFContext &OrigDwarf,
+                                              const DebugMapObject &DMO) const {
   DWARFDebugRangeList RangeList;
   const auto &FunctionRanges = Unit.getFunctionRanges();
   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
@@ -1879,7 +1854,7 @@ void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit,
 /// FIXME: this could actually be done right in patchRangesForUnit,
 /// but for the sake of initial bit-for-bit compatibility with legacy
 /// dsymutil, we have to do it in a delayed pass.
-void DwarfLinker::generateUnitRanges(CompileUnit &Unit) const {
+void DwarfLinkerForBinary::generateUnitRanges(CompileUnit &Unit) const {
   auto Attr = Unit.getUnitRangesAttribute();
   if (Attr)
     Attr->set(Streamer->getRangesSectionSize());
@@ -1931,10 +1906,10 @@ static void patchStmtList(DIE &Die, DIEInteger Offset) {
 /// Extract the line table for \p Unit from \p OrigDwarf, and
 /// recreate a relocated version of these for the address ranges that
 /// are present in the binary.
-void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
-                                        DWARFContext &OrigDwarf,
-                                        RangesTy &Ranges,
-                                        const DebugMapObject &DMO) {
+void DwarfLinkerForBinary::patchLineTableForUnit(CompileUnit &Unit,
+                                                 DWARFContext &OrigDwarf,
+                                                 RangesTy &Ranges,
+                                                 const DebugMapObject &DMO) {
   DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE();
   auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list));
   if (!StmtList)
@@ -2071,7 +2046,7 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
   }
 }
 
-void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
+void DwarfLinkerForBinary::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
   switch (Options.TheAccelTableKind) {
   case AccelTableKind::Apple:
     emitAppleAcceleratorEntriesForUnit(Unit);
@@ -2085,7 +2060,8 @@ void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
   }
 }
 
-void DwarfLinker::emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit) {
+void DwarfLinkerForBinary::emitAppleAcceleratorEntriesForUnit(
+    CompileUnit &Unit) {
   // Add namespaces.
   for (const auto &Namespace : Unit.getNamespaces())
     AppleNamespaces.addName(Namespace.Name,
@@ -2114,7 +2090,8 @@ void DwarfLinker::emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit) {
     AppleObjc.addName(ObjC.Name, ObjC.Die->getOffset() + Unit.getStartOffset());
 }
 
-void DwarfLinker::emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit) {
+void DwarfLinkerForBinary::emitDwarfAcceleratorEntriesForUnit(
+    CompileUnit &Unit) {
   for (const auto &Namespace : Unit.getNamespaces())
     DebugNames.addName(Namespace.Name, Namespace.Die->getOffset(),
                        Namespace.Die->getTag(), Unit.getUniqueID());
@@ -2132,10 +2109,10 @@ void DwarfLinker::emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit) {
 /// This is actually pretty easy as the data of the CIEs and FDEs can
 /// be considered as black boxes and moved as is. The only thing to do
 /// is to patch the addresses in the headers.
-void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO,
-                                          RangesTy &Ranges,
-                                          DWARFContext &OrigDwarf,
-                                          unsigned AddrSize) {
+void DwarfLinkerForBinary::patchFrameInfoForObject(const DebugMapObject &DMO,
+                                                   RangesTy &Ranges,
+                                                   DWARFContext &OrigDwarf,
+                                                   unsigned AddrSize) {
   StringRef FrameData = OrigDwarf.getDWARFObj().getFrameSection().Data;
   if (FrameData.empty())
     return;
@@ -2212,25 +2189,24 @@ void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO,
   }
 }
 
-void DwarfLinker::DIECloner::copyAbbrev(
-    const DWARFAbbreviationDeclaration &Abbrev, bool hasODR) {
+void DwarfLinkerForBinary::DIECloner::copyAbbrev(
+    const DWARFAbbreviationDeclaration &Abbrev, bool HasODR) {
   DIEAbbrev Copy(dwarf::Tag(Abbrev.getTag()),
                  dwarf::Form(Abbrev.hasChildren()));
 
   for (const auto &Attr : Abbrev.attributes()) {
     uint16_t Form = Attr.Form;
-    if (hasODR && isODRAttribute(Attr.Attr))
+    if (HasODR && isODRAttribute(Attr.Attr))
       Form = dwarf::DW_FORM_ref_addr;
     Copy.AddAttribute(dwarf::Attribute(Attr.Attr), dwarf::Form(Form));
   }
 
-  Linker.AssignAbbrev(Copy);
+  Linker.assignAbbrev(Copy);
 }
 
-uint32_t
-DwarfLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
-                                               const DebugMapObject &DMO,
-                                               int ChildRecurseDepth) {
+uint32_t DwarfLinkerForBinary::DIECloner::hashFullyQualifiedName(
+    DWARFDie DIE, CompileUnit &U, const DebugMapObject &DMO,
+    int ChildRecurseDepth) {
   const char *Name = nullptr;
   DWARFUnit *OrigUnit = &U.getOrigUnit();
   CompileUnit *CU = &U;
@@ -2281,7 +2257,7 @@ static uint64_t getDwoId(const DWARFDie &CUDie, const DWARFUnit &Unit) {
   return 0;
 }
 
-bool DwarfLinker::registerModuleReference(
+bool DwarfLinkerForBinary::registerModuleReference(
     DWARFDie CUDie, const DWARFUnit &Unit, DebugMap &ModuleMap,
     const DebugMapObject &DMO, RangesTy &Ranges, OffsetsStringPool &StringPool,
     UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts,
@@ -2339,7 +2315,8 @@ bool DwarfLinker::registerModuleReference(
 }
 
 ErrorOr<const object::ObjectFile &>
-DwarfLinker::loadObject(const DebugMapObject &Obj, const DebugMap &Map) {
+DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj,
+                                 const DebugMap &Map) {
   auto ObjectEntry =
       BinHolder.getObjectEntry(Obj.getObjectFilename(), Obj.getTimestamp());
   if (!ObjectEntry) {
@@ -2360,7 +2337,7 @@ DwarfLinker::loadObject(const DebugMapObject &Obj, const DebugMap &Map) {
   return *Object;
 }
 
-Error DwarfLinker::loadClangModule(
+Error DwarfLinkerForBinary::loadClangModule(
     DWARFDie CUDie, StringRef Filename, StringRef ModuleName, uint64_t DwoId,
     DebugMap &ModuleMap, const DebugMapObject &DMO, RangesTy &Ranges,
     OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool,
@@ -2417,7 +2394,7 @@ Error DwarfLinker::loadClangModule(
 
   // 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());
@@ -2454,7 +2431,7 @@ Error DwarfLinker::loadClangModule(
 
       // Add this module.
       Unit = std::make_unique<CompileUnit>(*CU, UnitID++, !Options.NoODR,
-                                            ModuleName);
+                                           ModuleName);
       Unit->setHasInterestingContent();
       analyzeContextInfo(CUDie, 0, *Unit, &ODRContexts.getRoot(),
                          UniquingStringPool, ODRContexts, ModulesEndOffset,
@@ -2481,7 +2458,7 @@ Error DwarfLinker::loadClangModule(
   return Error::success();
 }
 
-void DwarfLinker::DIECloner::cloneAllCompileUnits(
+void DwarfLinkerForBinary::DIECloner::cloneAllCompileUnits(
     DWARFContext &DwarfContext, const DebugMapObject &DMO, RangesTy &Ranges,
     OffsetsStringPool &StringPool, bool IsLittleEndian) {
   if (!Linker.Streamer)
@@ -2550,7 +2527,7 @@ void DwarfLinker::DIECloner::cloneAllCompileUnits(
   }
 }
 
-void DwarfLinker::updateAccelKind(DWARFContext &Dwarf) {
+void DwarfLinkerForBinary::updateAccelKind(DWARFContext &Dwarf) {
   if (Options.TheAccelTableKind != AccelTableKind::Default)
     return;
 
@@ -2564,15 +2541,14 @@ void DwarfLinker::updateAccelKind(DWARFContext &Dwarf) {
     AtLeastOneAppleAccelTable = true;
   }
 
-  if (!AtLeastOneDwarfAccelTable &&
-      !DwarfObj.getNamesSection().Data.empty()) {
+  if (!AtLeastOneDwarfAccelTable && !DwarfObj.getNamesSection().Data.empty()) {
     AtLeastOneDwarfAccelTable = true;
   }
 }
 
-bool DwarfLinker::emitPaperTrailWarnings(const DebugMapObject &DMO,
-                                         const DebugMap &Map,
-                                         OffsetsStringPool &StringPool) {
+bool DwarfLinkerForBinary::emitPaperTrailWarnings(
+    const DebugMapObject &DMO, const DebugMap &Map,
+    OffsetsStringPool &StringPool) {
   if (DMO.getWarnings().empty() || !DMO.empty())
     return false;
 
@@ -2606,13 +2582,13 @@ bool DwarfLinker::emitPaperTrailWarnings(const DebugMapObject &DMO,
                   DMO.getWarnings().size() * (4 + 1 + 4) +
                   1 /* End of children */;
   DIEAbbrev Abbrev = CUDie->generateAbbrev();
-  AssignAbbrev(Abbrev);
+  assignAbbrev(Abbrev);
   CUDie->setAbbrevNumber(Abbrev.getNumber());
   Size += getULEB128Size(Abbrev.getNumber());
   // Abbreviation ordering needed for classic compatibility.
   for (auto &Child : CUDie->children()) {
     Abbrev = Child.generateAbbrev();
-    AssignAbbrev(Abbrev);
+    assignAbbrev(Abbrev);
     Child.setAbbrevNumber(Abbrev.getNumber());
     Size += getULEB128Size(Abbrev.getNumber());
   }
@@ -2657,17 +2633,15 @@ static Error copySwiftInterfaces(
 
     // copy_file attempts an APFS clone first, so this should be cheap.
     if ((EC = sys::fs::copy_file(InterfaceFile, Path.str())))
-      warn(Twine("cannot copy parseable Swift interface ") +
-           InterfaceFile + ": " +
-           toString(errorCodeToError(EC)));
+      warn(Twine("cannot copy parseable Swift interface ") + InterfaceFile +
+           ": " + toString(errorCodeToError(EC)));
     Path.resize(BaseLength);
   }
   return Error::success();
 }
 
 static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
-                         StringRef ArchName,
-                         const remarks::RemarkLinker &RL) {
+                         StringRef ArchName, const remarks::RemarkLinker &RL) {
   // Make sure we don't create the directories and the file if there is nothing
   // to serialize.
   if (RL.empty())
@@ -2701,7 +2675,7 @@ static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
   return Error::success();
 }
 
-bool DwarfLinker::link(const DebugMap &Map) {
+bool DwarfLinkerForBinary::link(const DebugMap &Map) {
   if (!createStreamer(Map.getTriple(), OutFile))
     return false;
 
@@ -2798,8 +2772,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
     // 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";
 
@@ -2916,7 +2889,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
       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);
@@ -2925,10 +2898,9 @@ bool DwarfLinker::link(const DebugMap &Map) {
     // 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());
@@ -3074,7 +3046,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
 
 bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
                const DebugMap &DM, LinkOptions Options) {
-  DwarfLinker Linker(OutFile, BinHolder, std::move(Options));
+  DwarfLinkerForBinary Linker(OutFile, BinHolder, std::move(Options));
   return Linker.link(DM);
 }
 

diff  --git a/llvm/tools/dsymutil/DwarfLinker.h b/llvm/tools/dsymutil/DwarfLinkerForBinary.h
similarity index 85%
rename from llvm/tools/dsymutil/DwarfLinker.h
rename to llvm/tools/dsymutil/DwarfLinkerForBinary.h
index b8d8e9d02e32..133e28e7feaf 100644
--- a/llvm/tools/dsymutil/DwarfLinker.h
+++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.h
@@ -1,4 +1,4 @@
-//===- tools/dsymutil/DwarfLinker.h - Dwarf debug info linker ---*- C++ -*-===//
+//===- tools/dsymutil/DwarfLinkerForBinary.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.
@@ -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/DWARFLinker/DWARFLinker.h"
+#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
+#include "llvm/DWARFLinker/DWARFLinkerDeclContext.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<uint64_t, DebugMapObjectRange>;
 using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
 
 /// The core of the Dwarf linking logic.
@@ -53,10 +37,10 @@ using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
 /// a function, the location for a variable). These relocations are
 /// called ValidRelocs in the DwarfLinker and are gathered as a very
 /// first step when we start processing a DebugMapObject.
-class DwarfLinker {
+class DwarfLinkerForBinary {
 public:
-  DwarfLinker(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
-              LinkOptions Options)
+  DwarfLinkerForBinary(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
+                       LinkOptions Options)
       : OutFile(OutFile), BinHolder(BinHolder), Options(std::move(Options)) {}
 
   /// Link the contents of the DebugMap.
@@ -74,6 +58,7 @@ class DwarfLinker {
     TF_ODR = 1 << 4,             ///< Use the ODR while keeping dependents.
     TF_SkipPC = 1 << 5,          ///< Skip all location attributes.
   };
+
 private:
   /// Remembers the oldest and newest DWARF version we've seen in a unit.
   void updateDwarfVersion(unsigned Version) {
@@ -89,7 +74,7 @@ class DwarfLinker {
                               OffsetsStringPool &StringPool);
 
   /// Keeps track of relocations.
-  class RelocationManager {
+  class RelocationManager : public AddressesMap {
     struct ValidReloc {
       uint64_t Offset;
       uint32_t Size;
@@ -105,7 +90,7 @@ class DwarfLinker {
       }
     };
 
-    const DwarfLinker &Linker;
+    const DwarfLinkerForBinary &Linker;
 
     /// The valid relocations for the current DebugMapObject.
     /// This vector is sorted by relocation offset.
@@ -117,13 +102,48 @@ class DwarfLinker {
     /// cheap lookup during the root DIE selection and during DIE cloning.
     unsigned NextValidReloc = 0;
 
+    RangesTy AddressRanges;
+
   public:
-    RelocationManager(DwarfLinker &Linker) : Linker(Linker) {}
+    RelocationManager(DwarfLinkerForBinary &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 
diff erences:
+      //
+      //  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 +161,44 @@ class DwarfLinker {
                               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<char> 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 {
+    DwarfLinkerForBinary &Linker;
     DebugMapObject &DMO;
-    const object::ObjectFile *ObjectFile;
-    RelocationManager RelocMgr;
+    const object::ObjectFile *ObjectFile = nullptr;
+    std::unique_ptr<RelocationManager> RelocMgr;
     std::unique_ptr<DWARFContext> DwarfContext;
     RangesTy Ranges;
     UnitListTy CompileUnits;
 
-    LinkContext(const DebugMap &Map, DwarfLinker &Linker, DebugMapObject &DMO)
-        : DMO(DMO), RelocMgr(Linker) {
+    LinkContext(const DebugMap &Map, DwarfLinkerForBinary &Linker,
+                DebugMapObject &DMO)
+        : 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 @@ class DwarfLinker {
       DwarfContext.reset(nullptr);
       CompileUnits.clear();
       Ranges.clear();
+      RelocMgr->clear();
     }
   };
 
@@ -224,7 +257,6 @@ class DwarfLinker {
                         unsigned &UnitID, bool IsLittleEndian,
                         unsigned Indent = 0, bool Quiet = false);
 
-
   /// Mark the passed DIE as well as all the ones it depends on as kept.
   void keepDIEAndDependencies(RelocationManager &RelocMgr, RangesTy &Ranges,
                               const UnitListTy &Units, const DWARFDie &DIE,
@@ -258,7 +290,7 @@ class DwarfLinker {
   /// @{
 
   class DIECloner {
-    DwarfLinker &Linker;
+    DwarfLinkerForBinary &Linker;
     RelocationManager &RelocMgr;
 
     /// Allocator used for all the DIEValue objects.
@@ -268,7 +300,7 @@ class DwarfLinker {
     LinkOptions Options;
 
   public:
-    DIECloner(DwarfLinker &Linker, RelocationManager &RelocMgr,
+    DIECloner(DwarfLinkerForBinary &Linker, RelocationManager &RelocMgr,
               BumpPtrAllocator &DIEAlloc,
               std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
               LinkOptions &Options)
@@ -409,7 +441,7 @@ class DwarfLinker {
   };
 
   /// Assign an abbreviation number to \p Abbrev
-  void AssignAbbrev(DIEAbbrev &Abbrev);
+  void assignAbbrev(DIEAbbrev &Abbrev);
 
   /// Compute and emit debug_ranges section for \p Unit, and
   /// patch the attributes referencing it.

diff  --git a/llvm/tools/dsymutil/DwarfStreamer.cpp b/llvm/tools/dsymutil/DwarfStreamer.cpp
index 8747aee458fd..54cec3c4f683 100644
--- a/llvm/tools/dsymutil/DwarfStreamer.cpp
+++ b/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/DWARFLinker/DWARFLinkerCompileUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/MC/MCTargetOptions.h"
 #include "llvm/MC/MCTargetOptionsCommandFlags.inc"

diff  --git a/llvm/tools/dsymutil/DwarfStreamer.h b/llvm/tools/dsymutil/DwarfStreamer.h
index baf215ac1315..8479970a4f74 100644
--- a/llvm/tools/dsymutil/DwarfStreamer.h
+++ b/llvm/tools/dsymutil/DwarfStreamer.h
@@ -9,12 +9,12 @@
 #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/NonRelocatableStringpool.h"
+#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/MC/MCAsmBackend.h"

diff  --git a/llvm/tools/dsymutil/LLVMBuild.txt b/llvm/tools/dsymutil/LLVMBuild.txt
index 61bc07b81d35..819d3c4b30d9 100644
--- a/llvm/tools/dsymutil/LLVMBuild.txt
+++ b/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 DWARFLinker MC Object CodeGen Support all-targets


        


More information about the llvm-commits mailing list