diff tools/dsymutil/DwarfLinker.cpp @ 147:c2174574ed3a

LLVM 10
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 16:55:33 +0900
parents 3a76565eade5
children
line wrap: on
line diff
--- a/tools/dsymutil/DwarfLinker.cpp	Sat Feb 17 09:57:20 2018 +0900
+++ b/tools/dsymutil/DwarfLinker.cpp	Wed Aug 14 16:55:33 2019 +0900
@@ -1,18 +1,21 @@
 //===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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 "DwarfLinker.h"
 #include "BinaryHolder.h"
 #include "DebugMap.h"
+#include "DeclContext.h"
+#include "DwarfStreamer.h"
 #include "MachOUtils.h"
 #include "NonRelocatableStringpool.h"
 #include "dsymutil.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/DenseSet.h"
@@ -51,12 +54,12 @@
 #include "llvm/MC/MCDwarf.h"
 #include "llvm/MC/MCInstrInfo.h"
 #include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/MCTargetOptions.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.def"
 #include "llvm/Object/MachO.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Object/SymbolicFile.h"
@@ -75,7 +78,9 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/ThreadPool.h"
 #include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
@@ -98,1717 +103,41 @@
 namespace llvm {
 namespace dsymutil {
 
-namespace {
-
-/// Retrieve the section named \a SecName in \a Obj.
-///
-/// To accommodate for platform discrepancies, the name passed should be
-/// (for example) 'debug_info' to match either '__debug_info' or '.debug_info'.
-/// This function will strip the initial platform-specific characters.
-static Optional<object::SectionRef>
-getSectionByName(const object::ObjectFile &Obj, StringRef SecName) {
-  for (const object::SectionRef &Section : Obj.sections()) {
-    StringRef SectionName;
-    Section.getName(SectionName);
-    SectionName = SectionName.substr(SectionName.find_first_not_of("._"));
-    if (SectionName != SecName)
-      continue;
-    return Section;
-  }
-  return None;
-}
-
-template <typename KeyT, typename ValT>
-using HalfOpenIntervalMap =
-    IntervalMap<KeyT, ValT, IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
-                IntervalMapHalfOpenInfo<KeyT>>;
-
-using FunctionIntervals = HalfOpenIntervalMap<uint64_t, int64_t>;
-
-// FIXME: Delete this structure.
-struct PatchLocation {
-  DIE::value_iterator I;
-
-  PatchLocation() = default;
-  PatchLocation(DIE::value_iterator I) : I(I) {}
-
-  void set(uint64_t New) const {
-    assert(I);
-    const auto &Old = *I;
-    assert(Old.getType() == DIEValue::isInteger);
-    *I = DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New));
-  }
-
-  uint64_t get() const {
-    assert(I);
-    return I->getDIEInteger().getValue();
-  }
-};
-
-class CompileUnit;
-struct DeclMapInfo;
-
-/// A DeclContext is a named program scope that is used for ODR
-/// uniquing of types.
-/// The set of DeclContext for the ODR-subject parts of a Dwarf link
-/// is expanded (and uniqued) with each new object file processed. We
-/// need to determine the context of each DIE in an linked object file
-/// to see if the corresponding type has already been emitted.
-///
-/// The contexts are conceptually organised as a tree (eg. a function
-/// scope is contained in a namespace scope that contains other
-/// scopes), but storing/accessing them in an actual tree is too
-/// inefficient: we need to be able to very quickly query a context
-/// for a given child context by name. Storing a StringMap in each
-/// DeclContext would be too space inefficient.
-/// The solution here is to give each DeclContext a link to its parent
-/// (this allows to walk up the tree), but to query the existance of a
-/// specific DeclContext using a separate DenseMap keyed on the hash
-/// of the fully qualified name of the context.
-class DeclContext {
-  friend DeclMapInfo;
-
-  unsigned QualifiedNameHash = 0;
-  uint32_t Line = 0;
-  uint32_t ByteSize = 0;
-  uint16_t Tag = dwarf::DW_TAG_compile_unit;
-  unsigned DefinedInClangModule : 1;
-  StringRef Name;
-  StringRef File;
-  const DeclContext &Parent;
-  DWARFDie LastSeenDIE;
-  uint32_t LastSeenCompileUnitID = 0;
-  uint32_t CanonicalDIEOffset = 0;
-
-public:
-  using Map = DenseSet<DeclContext *, DeclMapInfo>;
-
-  DeclContext() : DefinedInClangModule(0), Parent(*this) {}
-
-  DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag,
-              StringRef Name, StringRef File, const DeclContext &Parent,
-              DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0)
-      : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag),
-        DefinedInClangModule(0), Name(Name), File(File), Parent(Parent),
-        LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId) {}
-
-  uint32_t getQualifiedNameHash() const { return QualifiedNameHash; }
-
-  bool setLastSeenDIE(CompileUnit &U, const DWARFDie &Die);
-
-  uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; }
-  void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; }
-
-  bool isDefinedInClangModule() const { return DefinedInClangModule; }
-  void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; }
-
-  uint16_t getTag() const { return Tag; }
-  StringRef getName() const { return Name; }
-};
-
-/// Info type for the DenseMap storing the DeclContext pointers.
-struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
-  using DenseMapInfo<DeclContext *>::getEmptyKey;
-  using DenseMapInfo<DeclContext *>::getTombstoneKey;
-
-  static unsigned getHashValue(const DeclContext *Ctxt) {
-    return Ctxt->QualifiedNameHash;
-  }
-
-  static bool isEqual(const DeclContext *LHS, const DeclContext *RHS) {
-    if (RHS == getEmptyKey() || RHS == getTombstoneKey())
-      return RHS == LHS;
-    return LHS->QualifiedNameHash == RHS->QualifiedNameHash &&
-           LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize &&
-           LHS->Name.data() == RHS->Name.data() &&
-           LHS->File.data() == RHS->File.data() &&
-           LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash;
-  }
-};
-
-/// This class gives a tree-like API to the DenseMap that stores the
-/// DeclContext objects. It also holds the BumpPtrAllocator where
-/// these objects will be allocated.
-class DeclContextTree {
-  BumpPtrAllocator Allocator;
-  DeclContext Root;
-  DeclContext::Map Contexts;
-
-public:
-  /// Get the child of \a Context described by \a DIE in \a Unit. The
-  /// required strings will be interned in \a StringPool.
-  /// \returns The child DeclContext along with one bit that is set if
-  /// this context is invalid.
-  /// An invalid context means it shouldn't be considered for uniquing, but its
-  /// not returning null, because some children of that context might be
-  /// uniquing candidates.  FIXME: The invalid bit along the return value is to
-  /// emulate some dsymutil-classic functionality.
-  PointerIntPair<DeclContext *, 1>
-  getChildDeclContext(DeclContext &Context,
-                      const DWARFDie &DIE, CompileUnit &Unit,
-                      NonRelocatableStringpool &StringPool, bool InClangModule);
-
-  DeclContext &getRoot() { return Root; }
-};
-
-/// 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.
-class CompileUnit {
-public:
-  /// Information gathered about a DIE in the object file.
-  struct DIEInfo {
-    /// Address offset to apply to the described entity.
-    int64_t AddrAdjust;
-
-    /// ODR Declaration context.
-    DeclContext *Ctxt;
-
-    /// Cloned version of that DIE.
-    DIE *Clone;
-
-    /// The index of this DIE's parent.
-    uint32_t ParentIdx;
-
-    /// Is the DIE part of the linked output?
-    bool Keep : 1;
-
-    /// Was this DIE's entity found in the map?
-    bool InDebugMap : 1;
-
-    /// Is this a pure forward declaration we can strip?
-    bool Prune : 1;
-
-    /// Does DIE transitively refer an incomplete decl?
-    bool Incomplete : 1;
-  };
-
-  CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR,
-              StringRef ClangModuleName)
-      : OrigUnit(OrigUnit), ID(ID), Ranges(RangeAlloc),
-        ClangModuleName(ClangModuleName) {
-    Info.resize(OrigUnit.getNumDIEs());
-
-    auto CUDie = OrigUnit.getUnitDIE(false);
-    if (auto Lang = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_language)))
-      HasODR = CanUseODR && (*Lang == dwarf::DW_LANG_C_plus_plus ||
-                             *Lang == dwarf::DW_LANG_C_plus_plus_03 ||
-                             *Lang == dwarf::DW_LANG_C_plus_plus_11 ||
-                             *Lang == dwarf::DW_LANG_C_plus_plus_14 ||
-                             *Lang == dwarf::DW_LANG_ObjC_plus_plus);
-    else
-      HasODR = false;
-  }
-
-  DWARFUnit &getOrigUnit() const { return OrigUnit; }
-
-  unsigned getUniqueID() const { return ID; }
-
-  void createOutputDIE() {
-    NewUnit.emplace(OrigUnit.getVersion(), OrigUnit.getAddressByteSize(),
-                    OrigUnit.getUnitDIE().getTag());
-  }
-
-  DIE *getOutputUnitDIE() const {
-    if (NewUnit)
-      return &const_cast<BasicDIEUnit &>(*NewUnit).getUnitDie();
-    return nullptr;
-  }
-
-  bool hasODR() const { return HasODR; }
-  bool isClangModule() const { return !ClangModuleName.empty(); }
-  const std::string &getClangModuleName() const { return ClangModuleName; }
-
-  DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
-  const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }
-
-  uint64_t getStartOffset() const { return StartOffset; }
-  uint64_t getNextUnitOffset() const { return NextUnitOffset; }
-  void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; }
-
-  uint64_t getLowPc() const { return LowPc; }
-  uint64_t getHighPc() const { return HighPc; }
-
-  Optional<PatchLocation> getUnitRangesAttribute() const {
-    return UnitRangeAttribute;
-  }
-
-  const FunctionIntervals &getFunctionRanges() const { return Ranges; }
-
-  const std::vector<PatchLocation> &getRangesAttributes() const {
-    return RangeAttributes;
-  }
-
-  const std::vector<std::pair<PatchLocation, int64_t>> &
-  getLocationAttributes() const {
-    return LocationAttributes;
-  }
-
-  void setHasInterestingContent() { HasInterestingContent = true; }
-  bool hasInterestingContent() { return HasInterestingContent; }
-
-  /// Mark every DIE in this unit as kept. This function also
-  /// marks variables as InDebugMap so that they appear in the
-  /// reconstructed accelerator tables.
-  void markEverythingAsKept();
-
-  /// Compute the end offset for this unit. Must be called after the CU's DIEs
-  /// have been cloned.  \returns the next unit offset (which is also the
-  /// current debug_info section size).
-  uint64_t computeNextUnitOffset();
-
-  /// Keep track of a forward reference to DIE \p Die in \p RefUnit by \p
-  /// Attr. The attribute should be fixed up later to point to the absolute
-  /// offset of \p Die in the debug_info section or to the canonical offset of
-  /// \p Ctxt if it is non-null.
-  void noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
-                            DeclContext *Ctxt, PatchLocation Attr);
-
-  /// Apply all fixups recored by noteForwardReference().
-  void fixupForwardReferences();
-
-  /// Add a function range [\p LowPC, \p HighPC) that is relocatad by applying
-  /// offset \p PCOffset.
-  void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);
-
-  /// Keep track of a DW_AT_range attribute that we will need to patch up later.
-  void noteRangeAttribute(const DIE &Die, PatchLocation Attr);
-
-  /// Keep track of a location attribute pointing to a location list in the
-  /// debug_loc section.
-  void noteLocationAttribute(PatchLocation Attr, int64_t PcOffset);
-
-  /// Add a name accelerator entry for \a Die with \a Name.
-  void addNamespaceAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name);
-
-  /// Add a name accelerator entry for \a Die with \a Name.
-  void addNameAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name,
-                          bool SkipPubnamesSection = false);
-
-  /// Add various accelerator entries for \p Die with \p Name which is stored
-  /// in the string table at \p Offset. \p Name must be an Objective-C
-  /// selector.
-  void addObjCAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name,
-                          bool SkipPubnamesSection = false);
-
-  /// Add a type accelerator entry for \p Die with \p Name which is stored in
-  /// the string table at \p Offset.
-  void addTypeAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name,
-                          bool ObjcClassImplementation,
-                          uint32_t QualifiedNameHash);
-
-  struct AccelInfo {
-    /// Name of the entry.
-    DwarfStringPoolEntryRef Name;
-
-    /// DIE this entry describes.
-    const DIE *Die;
-
-    /// Hash of the fully qualified name.
-    uint32_t QualifiedNameHash;
-
-    /// Emit this entry only in the apple_* sections.
-    bool SkipPubSection;
-
-    /// Is this an ObjC class implem?
-    bool ObjcClassImplementation;
-
-    AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die,
-              bool SkipPubSection = false)
-        : Name(Name), Die(Die), SkipPubSection(SkipPubSection) {}
-
-    AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die,
-              uint32_t QualifiedNameHash, bool ObjCClassIsImplementation)
-        : Name(Name), Die(Die), QualifiedNameHash(QualifiedNameHash),
-          SkipPubSection(false),
-          ObjcClassImplementation(ObjCClassIsImplementation) {}
-  };
-
-  const std::vector<AccelInfo> &getPubnames() const { return Pubnames; }
-  const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; }
-  const std::vector<AccelInfo> &getNamespaces() const { return Namespaces; }
-  const std::vector<AccelInfo> &getObjC() const { return ObjC; }
-
-  /// Get the full path for file \a FileNum in the line table
-  StringRef getResolvedPath(unsigned FileNum) {
-    if (FileNum >= ResolvedPaths.size())
-      return StringRef();
-    return ResolvedPaths[FileNum];
-  }
-
-  /// Set the fully resolved path for the line-table's file \a FileNum
-  /// to \a Path.
-  void setResolvedPath(unsigned FileNum, StringRef Path) {
-    if (ResolvedPaths.size() <= FileNum)
-      ResolvedPaths.resize(FileNum + 1);
-    ResolvedPaths[FileNum] = Path;
-  }
-
-private:
-  DWARFUnit &OrigUnit;
-  unsigned ID;
-  std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index.
-  Optional<BasicDIEUnit> NewUnit;
-
-  uint64_t StartOffset;
-  uint64_t NextUnitOffset;
-
-  uint64_t LowPc = std::numeric_limits<uint64_t>::max();
-  uint64_t HighPc = 0;
-
-  /// A list of attributes to fixup with the absolute offset of
-  /// a DIE in the debug_info section.
-  ///
-  /// The offsets for the attributes in this array couldn't be set while
-  /// cloning because for cross-cu forward refences the target DIE's
-  /// offset isn't known you emit the reference attribute.
-  std::vector<std::tuple<DIE *, const CompileUnit *, DeclContext *,
-                         PatchLocation>> ForwardDIEReferences;
-
-  FunctionIntervals::Allocator RangeAlloc;
-
-  /// The ranges in that interval 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.
-  FunctionIntervals Ranges;
-
-  /// DW_AT_ranges attributes to patch after we have gathered
-  /// all the unit's function addresses.
-  /// @{
-  std::vector<PatchLocation> RangeAttributes;
-  Optional<PatchLocation> UnitRangeAttribute;
-  /// @}
-
-  /// Location attributes that need to be transferred from the
-  /// original debug_loc section to the liked one. They are stored
-  /// along with the PC offset that is to be applied to their
-  /// function's address.
-  std::vector<std::pair<PatchLocation, int64_t>> LocationAttributes;
-
-  /// Accelerator entries for the unit, both for the pub*
-  /// sections and the apple* ones.
-  /// @{
-  std::vector<AccelInfo> Pubnames;
-  std::vector<AccelInfo> Pubtypes;
-  std::vector<AccelInfo> Namespaces;
-  std::vector<AccelInfo> ObjC;
-  /// @}
-
-  /// Cached resolved paths from the line table.
-  /// Note, the StringRefs here point in to the intern (uniquing) string pool.
-  /// This means that a StringRef returned here doesn't need to then be uniqued
-  /// for the purposes of getting a unique address for each string.
-  std::vector<StringRef> ResolvedPaths;
-
-  /// Is this unit subject to the ODR rule?
-  bool HasODR;
-
-  /// Did a DIE actually contain a valid reloc?
-  bool HasInterestingContent;
-
-  /// If this is a Clang module, this holds the module's name.
-  std::string ClangModuleName;
-};
-
-/// Check if the DIE at \p Idx is in the scope of a function.
-static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
-  while (Idx) {
-    if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram)
-      return true;
-    Idx = U.getInfo(Idx).ParentIdx;
-  }
-  return false;
-}
-
-} // end anonymous namespace
-
-void CompileUnit::markEverythingAsKept() {
-  unsigned Idx = 0;
-
-  setHasInterestingContent();
-
-  for (auto &I : Info) {
-    // Mark everything that wasn't explicit marked for pruning.
-    I.Keep = !I.Prune;
-    auto DIE = OrigUnit.getDIEAtIndex(Idx++);
-
-    // Try to guess which DIEs must go to the accelerator tables. We do that
-    // just for variables, because functions will be handled depending on
-    // whether they carry a DW_AT_low_pc attribute or not.
-    if (DIE.getTag() != dwarf::DW_TAG_variable &&
-        DIE.getTag() != dwarf::DW_TAG_constant)
-      continue;
-
-    Optional<DWARFFormValue> Value;
-    if (!(Value = DIE.find(dwarf::DW_AT_location))) {
-      if ((Value = DIE.find(dwarf::DW_AT_const_value)) &&
-          !inFunctionScope(*this, I.ParentIdx))
-        I.InDebugMap = true;
-      continue;
-    }
-    if (auto Block = Value->getAsBlock()) {
-      if (Block->size() > OrigUnit.getAddressByteSize() &&
-          (*Block)[0] == dwarf::DW_OP_addr)
-        I.InDebugMap = true;
-    }
-  }
-}
-
-uint64_t CompileUnit::computeNextUnitOffset() {
-  NextUnitOffset = StartOffset + 11 /* Header size */;
-  // The root DIE might be null, meaning that the Unit had nothing to
-  // contribute to the linked output. In that case, we will emit the
-  // unit header without any actual DIE.
-  if (NewUnit)
-    NextUnitOffset += NewUnit->getUnitDie().getSize();
-  return NextUnitOffset;
-}
-
-/// Keep track of a forward cross-cu reference from this unit
-/// to \p Die that lives in \p RefUnit.
-void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
-                                       DeclContext *Ctxt, PatchLocation Attr) {
-  ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr);
-}
-
-/// Apply all fixups recorded by noteForwardReference().
-void CompileUnit::fixupForwardReferences() {
-  for (const auto &Ref : ForwardDIEReferences) {
-    DIE *RefDie;
-    const CompileUnit *RefUnit;
-    PatchLocation Attr;
-    DeclContext *Ctxt;
-    std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref;
-    if (Ctxt && Ctxt->getCanonicalDIEOffset())
-      Attr.set(Ctxt->getCanonicalDIEOffset());
-    else
-      Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
-  }
-}
-
-void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
-                                   int64_t PcOffset) {
-  Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
-  this->LowPc = std::min(LowPc, FuncLowPc + PcOffset);
-  this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
-}
-
-void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) {
-  if (Die.getTag() != dwarf::DW_TAG_compile_unit)
-    RangeAttributes.push_back(Attr);
-  else
-    UnitRangeAttribute = Attr;
-}
-
-void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) {
-  LocationAttributes.emplace_back(Attr, PcOffset);
-}
-
-void CompileUnit::addNamespaceAccelerator(const DIE *Die,
-                                          DwarfStringPoolEntryRef Name) {
-  Namespaces.emplace_back(Name, Die);
-}
-
-void CompileUnit::addObjCAccelerator(const DIE *Die,
-                                     DwarfStringPoolEntryRef Name,
-                                     bool SkipPubSection) {
-  ObjC.emplace_back(Name, Die, SkipPubSection);
-}
-
-void CompileUnit::addNameAccelerator(const DIE *Die,
-                                     DwarfStringPoolEntryRef Name,
-                                     bool SkipPubSection) {
-  Pubnames.emplace_back(Name, Die, SkipPubSection);
-}
-
-void CompileUnit::addTypeAccelerator(const DIE *Die,
-                                     DwarfStringPoolEntryRef Name,
-                                     bool ObjcClassImplementation,
-                                     uint32_t QualifiedNameHash) {
-  Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
-}
-
-namespace {
-
-/// The Dwarf streaming logic
-///
-/// All interactions with the MC layer that is used to build the debug
-/// information binary representation are handled in this class.
-class DwarfStreamer {
-  /// \defgroup MCObjects MC layer objects constructed by the streamer
-  /// @{
-  std::unique_ptr<MCRegisterInfo> MRI;
-  std::unique_ptr<MCAsmInfo> MAI;
-  std::unique_ptr<MCObjectFileInfo> MOFI;
-  std::unique_ptr<MCContext> MC;
-  MCAsmBackend *MAB; // Owned by MCStreamer
-  std::unique_ptr<MCInstrInfo> MII;
-  std::unique_ptr<MCSubtargetInfo> MSTI;
-  MCCodeEmitter *MCE; // Owned by MCStreamer
-  MCStreamer *MS;     // Owned by AsmPrinter
-  std::unique_ptr<TargetMachine> TM;
-  std::unique_ptr<AsmPrinter> Asm;
-  /// @}
-
-  /// The file we stream the linked Dwarf to.
-  raw_fd_ostream &OutFile;
-
-  uint32_t RangesSectionSize;
-  uint32_t LocSectionSize;
-  uint32_t LineSectionSize;
-  uint32_t FrameSectionSize;
-
-  /// 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<CompileUnit::AccelInfo> &Names);
-
-public:
-  DwarfStreamer(raw_fd_ostream &OutFile) : OutFile(OutFile) {}
-  bool init(Triple TheTriple);
-
-  /// Dump the file to the disk.
-  bool finish(const DebugMap &);
-
-  AsmPrinter &getAsmPrinter() const { 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 compilation unit header for \p Unit in the
-  /// debug_info section.
-  ///
-  /// As a side effect, this also switches the current Dwarf version
-  /// of the MC layer to the one of U.getOrigUnit().
-  void emitCompileUnitHeader(CompileUnit &Unit);
-
-  /// Recursively emit the DIE tree rooted at \p Die.
-  void emitDIE(DIE &Die);
-
-  /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
-  void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
-                   unsigned DwarfVersion);
-
-  /// Emit the string table described by \p Pool.
-  void emitStrings(const NonRelocatableStringpool &Pool);
-
-  /// Emit the swift_ast section stored in \p Buffer.
-  void emitSwiftAST(StringRef Buffer);
-
-  /// Emit debug_ranges for \p FuncRange by translating the
-  /// original \p Entries.
-  void emitRangesEntries(
-      int64_t UnitPcOffset, uint64_t OrigLowPc,
-      const FunctionIntervals::const_iterator &FuncRange,
-      const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
-      unsigned AddressSize);
-
-  /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,
-  /// also emit the debug_ranges entries for the DW_TAG_compile_unit's
-  /// DW_AT_ranges attribute.
-  void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection);
-
-  uint32_t getRangesSectionSize() const { return RangesSectionSize; }
-
-  /// Emit the debug_loc contribution for \p Unit by copying the entries from \p
-  /// Dwarf and offseting them. Update the location attributes to point to the
-  /// new entries.
-  void emitLocationsForUnit(const CompileUnit &Unit, DWARFContext &Dwarf);
-
-  /// Emit the line table described in \p Rows into the debug_line section.
-  void emitLineTableForUnit(MCDwarfLineTableParams Params,
-                            StringRef PrologueBytes, unsigned MinInstLength,
-                            std::vector<DWARFDebugLine::Row> &Rows,
-                            unsigned AdddressSize);
-
-  /// Copy over the debug sections that are not modified when updating.
-  void copyInvariantDebugSection(const object::ObjectFile &Obj, LinkOptions &);
-
-  uint32_t getLineSectionSize() const { return LineSectionSize; }
-
-  /// Emit the .debug_pubnames contribution for \p Unit.
-  void emitPubNamesForUnit(const CompileUnit &Unit);
-
-  /// Emit the .debug_pubtypes contribution for \p Unit.
-  void emitPubTypesForUnit(const CompileUnit &Unit);
-
-  /// Emit a CIE.
-  void emitCIE(StringRef CIEBytes);
-
-  /// Emit an FDE with data \p Bytes.
-  void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address,
-               StringRef Bytes);
-
-  /// Emit Apple namespaces accelerator table.
-  void
-  emitAppleNamespaces(AppleAccelTable<AppleAccelTableStaticOffsetData> &Table);
-
-  /// Emit Apple names accelerator table.
-  void emitAppleNames(AppleAccelTable<AppleAccelTableStaticOffsetData> &Table);
-
-  /// Emit Apple Objective-C accelerator table.
-  void emitAppleObjc(AppleAccelTable<AppleAccelTableStaticOffsetData> &Table);
-
-  /// Emit Apple type accelerator table.
-  void emitAppleTypes(AppleAccelTable<AppleAccelTableStaticTypeData> &Table);
-
-  uint32_t getFrameSectionSize() const { return FrameSectionSize; }
-};
-
-} // end anonymous namespace
-
-bool DwarfStreamer::init(Triple TheTriple) {
-  std::string ErrorStr;
-  std::string TripleName;
-  StringRef Context = "dwarf streamer init";
-
-  // Get the target.
-  const Target *TheTarget =
-      TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
-  if (!TheTarget)
-    return error(ErrorStr, Context);
-  TripleName = TheTriple.getTriple();
-
-  // Create all the MC Objects.
-  MRI.reset(TheTarget->createMCRegInfo(TripleName));
-  if (!MRI)
-    return error(Twine("no register info for target ") + TripleName, Context);
-
-  MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName));
-  if (!MAI)
-    return error("no asm info for target " + TripleName, Context);
-
-  MOFI.reset(new MCObjectFileInfo);
-  MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get()));
-  MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, *MC);
-
-  MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
-  if (!MSTI)
-    return error("no subtarget info for target " + TripleName, Context);
-
-  MCTargetOptions Options;
-  MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, Options);
-  if (!MAB)
-    return error("no asm backend for target " + TripleName, Context);
-
-  MII.reset(TheTarget->createMCInstrInfo());
-  if (!MII)
-    return error("no instr info info for target " + TripleName, Context);
-
-  MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC);
-  if (!MCE)
-    return error("no code emitter for target " + TripleName, Context);
-
-  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
-  MS = TheTarget->createMCObjectStreamer(
-      TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB), OutFile,
-      std::unique_ptr<MCCodeEmitter>(MCE), *MSTI, MCOptions.MCRelaxAll,
-      MCOptions.MCIncrementalLinkerCompatible,
-      /*DWARFMustBeAtTheEnd*/ false);
-  if (!MS)
-    return error("no object streamer for target " + TripleName, Context);
-
-  // Finally create the AsmPrinter we'll use to emit the DIEs.
-  TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
-                                          None));
-  if (!TM)
-    return error("no target machine for target " + TripleName, Context);
-
-  Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
-  if (!Asm)
-    return error("no asm printer for target " + TripleName, Context);
-
-  RangesSectionSize = 0;
-  LocSectionSize = 0;
-  LineSectionSize = 0;
-  FrameSectionSize = 0;
-
-  return true;
-}
-
-bool DwarfStreamer::finish(const DebugMap &DM) {
-  bool Result = true;
-  if (DM.getTriple().isOSDarwin() && !DM.getBinaryPath().empty())
-    Result = MachOUtils::generateDsymCompanion(DM, *MS, OutFile);
-  else
-    MS->Finish();
-  return Result;
-}
-
-/// Set the current output section to debug_info and change
-/// the MC Dwarf version to \p DwarfVersion.
-void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) {
-  MS->SwitchSection(MOFI->getDwarfInfoSection());
-  MC->setDwarfVersion(DwarfVersion);
-}
-
-/// Emit the compilation unit header for \p Unit in the debug_info section.
-///
-/// A Dwarf scetion header is encoded as:
-///  uint32_t   Unit length (omiting this field)
-///  uint16_t   Version
-///  uint32_t   Abbreviation table offset
-///  uint8_t    Address size
-///
-/// Leading to a total of 11 bytes.
-void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit) {
-  unsigned Version = Unit.getOrigUnit().getVersion();
-  switchToDebugInfoSection(Version);
-
-  // Emit size of content not including length itself. The size has
-  // already been computed in CompileUnit::computeOffsets(). Substract
-  // 4 to that size to account for the length field.
-  Asm->EmitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4);
-  Asm->EmitInt16(Version);
-  // We share one abbreviations table across all units so it's always at the
-  // start of the section.
-  Asm->EmitInt32(0);
-  Asm->EmitInt8(Unit.getOrigUnit().getAddressByteSize());
-}
-
-/// Emit the \p Abbrevs array as the shared abbreviation table
-/// for the linked Dwarf file.
-void DwarfStreamer::emitAbbrevs(
-    const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
-    unsigned DwarfVersion) {
-  MS->SwitchSection(MOFI->getDwarfAbbrevSection());
-  MC->setDwarfVersion(DwarfVersion);
-  Asm->emitDwarfAbbrevs(Abbrevs);
-}
-
-/// Recursively emit the DIE tree rooted at \p Die.
-void DwarfStreamer::emitDIE(DIE &Die) {
-  MS->SwitchSection(MOFI->getDwarfInfoSection());
-  Asm->emitDwarfDIE(Die);
-}
-
-/// Emit the debug_str section stored in \p Pool.
-void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) {
-  Asm->OutStreamer->SwitchSection(MOFI->getDwarfStrSection());
-  std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntries();
-  for (auto Entry : Entries) {
-    if (Entry.getIndex() == -1U)
-      break;
-    // Emit the string itself.
-    Asm->OutStreamer->EmitBytes(Entry.getString());
-    // Emit a null terminator.
-    Asm->EmitInt8(0);
-  }
-}
-
-void DwarfStreamer::emitAppleNamespaces(
-    AppleAccelTable<AppleAccelTableStaticOffsetData> &Table) {
-  Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelNamespaceSection());
-  Table.finalizeTable(Asm.get(), "namespac");
-  auto *SectionBegin = Asm->createTempSymbol("namespac_begin");
-  Asm->OutStreamer->EmitLabel(SectionBegin);
-  Table.emit(Asm.get(), SectionBegin);
-}
-
-void DwarfStreamer::emitAppleNames(
-    AppleAccelTable<AppleAccelTableStaticOffsetData> &Table) {
-  Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelNamesSection());
-  Table.finalizeTable(Asm.get(), "names");
-  auto *SectionBegin = Asm->createTempSymbol("names_begin");
-  Asm->OutStreamer->EmitLabel(SectionBegin);
-  Table.emit(Asm.get(), SectionBegin);
-}
-
-void DwarfStreamer::emitAppleObjc(
-    AppleAccelTable<AppleAccelTableStaticOffsetData> &Table) {
-  Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelObjCSection());
-  Table.finalizeTable(Asm.get(), "objc");
-  auto *SectionBegin = Asm->createTempSymbol("objc_begin");
-  Asm->OutStreamer->EmitLabel(SectionBegin);
-  Table.emit(Asm.get(), SectionBegin);
-}
-
-void DwarfStreamer::emitAppleTypes(
-    AppleAccelTable<AppleAccelTableStaticTypeData> &Table) {
-  Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelTypesSection());
-  Table.finalizeTable(Asm.get(), "types");
-  auto *SectionBegin = Asm->createTempSymbol("types_begin");
-  Asm->OutStreamer->EmitLabel(SectionBegin);
-  Table.emit(Asm.get(), SectionBegin);
-}
-
-/// Emit the swift_ast section stored in \p Buffers.
-void DwarfStreamer::emitSwiftAST(StringRef Buffer) {
-  MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
-  SwiftASTSection->setAlignment(1 << 5);
-  MS->SwitchSection(SwiftASTSection);
-  MS->EmitBytes(Buffer);
-}
-
-/// Emit the debug_range section contents for \p FuncRange by
-/// translating the original \p Entries. The debug_range section
-/// format is totally trivial, consisting just of pairs of address
-/// sized addresses describing the ranges.
-void DwarfStreamer::emitRangesEntries(
-    int64_t UnitPcOffset, uint64_t OrigLowPc,
-    const FunctionIntervals::const_iterator &FuncRange,
-    const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
-    unsigned AddressSize) {
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
-
-  // Offset each range by the right amount.
-  int64_t PcOffset = Entries.empty() ? 0 : FuncRange.value() + UnitPcOffset;
-  for (const auto &Range : Entries) {
-    if (Range.isBaseAddressSelectionEntry(AddressSize)) {
-      warn("unsupported base address selection operation",
-           "emitting debug_ranges");
-      break;
-    }
-    // Do not emit empty ranges.
-    if (Range.StartAddress == Range.EndAddress)
-      continue;
-
-    // All range entries should lie in the function range.
-    if (!(Range.StartAddress + OrigLowPc >= FuncRange.start() &&
-          Range.EndAddress + OrigLowPc <= FuncRange.stop()))
-      warn("inconsistent range data.", "emitting debug_ranges");
-    MS->EmitIntValue(Range.StartAddress + PcOffset, AddressSize);
-    MS->EmitIntValue(Range.EndAddress + PcOffset, AddressSize);
-    RangesSectionSize += 2 * AddressSize;
-  }
-
-  // Add the terminator entry.
-  MS->EmitIntValue(0, AddressSize);
-  MS->EmitIntValue(0, AddressSize);
-  RangesSectionSize += 2 * AddressSize;
-}
-
-/// Emit the debug_aranges contribution of a unit and
-/// if \p DoDebugRanges is true the debug_range contents for a
-/// compile_unit level DW_AT_ranges attribute (Which are basically the
-/// same thing with a different base address).
-/// Just aggregate all the ranges gathered inside that unit.
-void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit,
-                                          bool DoDebugRanges) {
-  unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
-  // Gather the ranges in a vector, so that we can simplify them. The
-  // IntervalMap will have coalesced the non-linked ranges, but here
-  // we want to coalesce the linked addresses.
-  std::vector<std::pair<uint64_t, uint64_t>> Ranges;
-  const auto &FunctionRanges = Unit.getFunctionRanges();
-  for (auto Range = FunctionRanges.begin(), End = FunctionRanges.end();
-       Range != End; ++Range)
-    Ranges.push_back(std::make_pair(Range.start() + Range.value(),
-                                    Range.stop() + Range.value()));
-
-  // The object addresses where sorted, but again, the linked
-  // addresses might end up in a different order.
-  std::sort(Ranges.begin(), Ranges.end());
-
-  if (!Ranges.empty()) {
-    MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
-
-    MCSymbol *BeginLabel = Asm->createTempSymbol("Barange");
-    MCSymbol *EndLabel = Asm->createTempSymbol("Earange");
-
-    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 = AddressSize * 2;
-    unsigned Padding = OffsetToAlignment(HeaderSize, TupleSize);
-
-    Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Arange length
-    Asm->OutStreamer->EmitLabel(BeginLabel);
-    Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); // Version number
-    Asm->EmitInt32(Unit.getStartOffset());     // Corresponding unit's offset
-    Asm->EmitInt8(AddressSize);                // Address size
-    Asm->EmitInt8(0);                          // Segment size
-
-    Asm->OutStreamer->emitFill(Padding, 0x0);
-
-    for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End;
-         ++Range) {
-      uint64_t RangeStart = Range->first;
-      MS->EmitIntValue(RangeStart, AddressSize);
-      while ((Range + 1) != End && Range->second == (Range + 1)->first)
-        ++Range;
-      MS->EmitIntValue(Range->second - RangeStart, AddressSize);
-    }
-
-    // Emit terminator
-    Asm->OutStreamer->EmitIntValue(0, AddressSize);
-    Asm->OutStreamer->EmitIntValue(0, AddressSize);
-    Asm->OutStreamer->EmitLabel(EndLabel);
-  }
-
-  if (!DoDebugRanges)
-    return;
-
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
-  // Offset each range by the right amount.
-  int64_t PcOffset = -Unit.getLowPc();
-  // Emit coalesced ranges.
-  for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; ++Range) {
-    MS->EmitIntValue(Range->first + PcOffset, AddressSize);
-    while (Range + 1 != End && Range->second == (Range + 1)->first)
-      ++Range;
-    MS->EmitIntValue(Range->second + PcOffset, AddressSize);
-    RangesSectionSize += 2 * AddressSize;
-  }
-
-  // Add the terminator entry.
-  MS->EmitIntValue(0, AddressSize);
-  MS->EmitIntValue(0, AddressSize);
-  RangesSectionSize += 2 * AddressSize;
-}
-
-/// Emit location lists for \p Unit and update attribtues to
-/// point to the new entries.
-void DwarfStreamer::emitLocationsForUnit(const CompileUnit &Unit,
-                                         DWARFContext &Dwarf) {
-  const auto &Attributes = Unit.getLocationAttributes();
-
-  if (Attributes.empty())
-    return;
-
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
-
-  unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
-  const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection();
-  DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
-  DWARFUnit &OrigUnit = Unit.getOrigUnit();
-  auto OrigUnitDie = OrigUnit.getUnitDIE(false);
-  int64_t UnitPcOffset = 0;
-  if (auto OrigLowPc = dwarf::toAddress(OrigUnitDie.find(dwarf::DW_AT_low_pc)))
-    UnitPcOffset = int64_t(*OrigLowPc) - Unit.getLowPc();
-
-  for (const auto &Attr : Attributes) {
-    uint32_t Offset = Attr.first.get();
-    Attr.first.set(LocSectionSize);
-    // This is the quantity to add to the old location address to get
-    // the correct address for the new one.
-    int64_t LocPcOffset = Attr.second + UnitPcOffset;
-    while (Data.isValidOffset(Offset)) {
-      uint64_t Low = Data.getUnsigned(&Offset, AddressSize);
-      uint64_t High = Data.getUnsigned(&Offset, AddressSize);
-      LocSectionSize += 2 * AddressSize;
-      if (Low == 0 && High == 0) {
-        Asm->OutStreamer->EmitIntValue(0, AddressSize);
-        Asm->OutStreamer->EmitIntValue(0, AddressSize);
-        break;
-      }
-      Asm->OutStreamer->EmitIntValue(Low + LocPcOffset, AddressSize);
-      Asm->OutStreamer->EmitIntValue(High + LocPcOffset, AddressSize);
-      uint64_t Length = Data.getU16(&Offset);
-      Asm->OutStreamer->EmitIntValue(Length, 2);
-      // Just copy the bytes over.
-      Asm->OutStreamer->EmitBytes(
-          StringRef(InputSec.Data.substr(Offset, Length)));
-      Offset += Length;
-      LocSectionSize += Length + 2;
-    }
-  }
-}
-
-void DwarfStreamer::emitLineTableForUnit(MCDwarfLineTableParams Params,
-                                         StringRef PrologueBytes,
-                                         unsigned MinInstLength,
-                                         std::vector<DWARFDebugLine::Row> &Rows,
-                                         unsigned PointerSize) {
-  // Switch to the section where the table will be emitted into.
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection());
-  MCSymbol *LineStartSym = MC->createTempSymbol();
-  MCSymbol *LineEndSym = MC->createTempSymbol();
-
-  // The first 4 bytes is the total length of the information for this
-  // compilation unit (not including these 4 bytes for the length).
-  Asm->EmitLabelDifference(LineEndSym, LineStartSym, 4);
-  Asm->OutStreamer->EmitLabel(LineStartSym);
-  // Copy Prologue.
-  MS->EmitBytes(PrologueBytes);
-  LineSectionSize += PrologueBytes.size() + 4;
-
-  SmallString<128> EncodingBuffer;
-  raw_svector_ostream EncodingOS(EncodingBuffer);
-
-  if (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<int64_t>::max(), 0,
-                            EncodingOS);
-    MS->EmitBytes(EncodingOS.str());
-    LineSectionSize += EncodingBuffer.size();
-    MS->EmitLabel(LineEndSym);
-    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 (unsigned Idx = 0; Idx < Rows.size(); ++Idx) {
-    auto &Row = Rows[Idx];
-
-    int64_t AddressDelta;
-    if (Address == -1ULL) {
-      MS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);
-      MS->EmitULEB128IntValue(PointerSize + 1);
-      MS->EmitIntValue(dwarf::DW_LNE_set_address, 1);
-      MS->EmitIntValue(Row.Address, PointerSize);
-      LineSectionSize += 2 + PointerSize + getULEB128Size(PointerSize + 1);
-      AddressDelta = 0;
-    } else {
-      AddressDelta = (Row.Address - Address) / MinInstLength;
-    }
-
-    // FIXME: code copied and transfromed 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;
-      MS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
-      MS->EmitULEB128IntValue(FileNum);
-      LineSectionSize += 1 + getULEB128Size(FileNum);
-    }
-    if (Column != Row.Column) {
-      Column = Row.Column;
-      MS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
-      MS->EmitULEB128IntValue(Column);
-      LineSectionSize += 1 + getULEB128Size(Column);
-    }
-
-    // FIXME: We should handle the discriminator here, but dsymutil
-    // doesn' consider it, thus ignore it for now.
-
-    if (Isa != Row.Isa) {
-      Isa = Row.Isa;
-      MS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
-      MS->EmitULEB128IntValue(Isa);
-      LineSectionSize += 1 + getULEB128Size(Isa);
-    }
-    if (IsStatement != Row.IsStmt) {
-      IsStatement = Row.IsStmt;
-      MS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1);
-      LineSectionSize += 1;
-    }
-    if (Row.BasicBlock) {
-      MS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1);
-      LineSectionSize += 1;
-    }
-
-    if (Row.PrologueEnd) {
-      MS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
-      LineSectionSize += 1;
-    }
-
-    if (Row.EpilogueBegin) {
-      MS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
-      LineSectionSize += 1;
-    }
-
-    int64_t LineDelta = int64_t(Row.Line) - LastLine;
-    if (!Row.EndSequence) {
-      MCDwarfLineAddr::Encode(*MC, Params, LineDelta, AddressDelta, EncodingOS);
-      MS->EmitBytes(EncodingOS.str());
-      LineSectionSize += EncodingBuffer.size();
-      EncodingBuffer.resize(0);
-      Address = Row.Address;
-      LastLine = Row.Line;
-      RowsSinceLastSequence++;
-    } else {
-      if (LineDelta) {
-        MS->EmitIntValue(dwarf::DW_LNS_advance_line, 1);
-        MS->EmitSLEB128IntValue(LineDelta);
-        LineSectionSize += 1 + getSLEB128Size(LineDelta);
-      }
-      if (AddressDelta) {
-        MS->EmitIntValue(dwarf::DW_LNS_advance_pc, 1);
-        MS->EmitULEB128IntValue(AddressDelta);
-        LineSectionSize += 1 + getULEB128Size(AddressDelta);
-      }
-      MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(),
-                              0, EncodingOS);
-      MS->EmitBytes(EncodingOS.str());
-      LineSectionSize += EncodingBuffer.size();
-      EncodingBuffer.resize(0);
-      Address = -1ULL;
-      LastLine = FileNum = IsStatement = 1;
-      RowsSinceLastSequence = Column = Isa = 0;
-    }
-  }
-
-  if (RowsSinceLastSequence) {
-    MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
-                            EncodingOS);
-    MS->EmitBytes(EncodingOS.str());
-    LineSectionSize += EncodingBuffer.size();
-    EncodingBuffer.resize(0);
-  }
-
-  MS->EmitLabel(LineEndSym);
-}
-
-static void emitSectionContents(const object::ObjectFile &Obj,
-                                StringRef SecName, MCStreamer *MS) {
-  StringRef Contents;
-  if (auto Sec = getSectionByName(Obj, SecName))
-    if (!Sec->getContents(Contents))
-      MS->EmitBytes(Contents);
-}
-
-void DwarfStreamer::copyInvariantDebugSection(const object::ObjectFile &Obj,
-                                              LinkOptions &Options) {
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection());
-  emitSectionContents(Obj, "debug_line", MS);
-
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
-  emitSectionContents(Obj, "debug_loc", MS);
-
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
-  emitSectionContents(Obj, "debug_ranges", MS);
-
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
-  emitSectionContents(Obj, "debug_frame", MS);
-
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
-  emitSectionContents(Obj, "debug_aranges", MS);
-}
-
-/// Emit the pubnames or pubtypes section contribution for \p
-/// Unit into \p Sec. The data is provided in \p Names.
-void DwarfStreamer::emitPubSectionForUnit(
-    MCSection *Sec, StringRef SecName, const CompileUnit &Unit,
-    const std::vector<CompileUnit::AccelInfo> &Names) {
-  if (Names.empty())
-    return;
-
-  // Start the dwarf pubnames section.
-  Asm->OutStreamer->SwitchSection(Sec);
-  MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin");
-  MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end");
-
-  bool HeaderEmitted = false;
-  // Emit the pubnames for this compilation unit.
-  for (const auto &Name : Names) {
-    if (Name.SkipPubSection)
-      continue;
-
-    if (!HeaderEmitted) {
-      // Emit the header.
-      Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Length
-      Asm->OutStreamer->EmitLabel(BeginLabel);
-      Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); // Version
-      Asm->EmitInt32(Unit.getStartOffset());      // Unit offset
-      Asm->EmitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size
-      HeaderEmitted = true;
-    }
-    Asm->EmitInt32(Name.Die->getOffset());
-
-    // Emit the string itself.
-    Asm->OutStreamer->EmitBytes(Name.Name.getString());
-    // Emit a null terminator.
-    Asm->EmitInt8(0);
-  }
-
-  if (!HeaderEmitted)
-    return;
-  Asm->EmitInt32(0); // End marker.
-  Asm->OutStreamer->EmitLabel(EndLabel);
-}
-
-/// Emit .debug_pubnames for \p Unit.
-void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) {
-  emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
-                        "names", Unit, Unit.getPubnames());
-}
-
-/// Emit .debug_pubtypes for \p Unit.
-void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) {
-  emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
-                        "types", Unit, Unit.getPubtypes());
-}
-
-/// Emit a CIE into the debug_frame section.
-void DwarfStreamer::emitCIE(StringRef CIEBytes) {
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
-
-  MS->EmitBytes(CIEBytes);
-  FrameSectionSize += CIEBytes.size();
-}
-
-/// 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 DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize,
-                            uint32_t Address, StringRef FDEBytes) {
-  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
-
-  MS->EmitIntValue(FDEBytes.size() + 4 + AddrSize, 4);
-  MS->EmitIntValue(CIEOffset, 4);
-  MS->EmitIntValue(Address, AddrSize);
-  MS->EmitBytes(FDEBytes);
-  FrameSectionSize += FDEBytes.size() + 8 + AddrSize;
-}
-
-namespace {
-
-/// The core of the Dwarf linking logic.
-///
-/// The link of the dwarf information from the object files will be
-/// driven by the selection of 'root DIEs', which are DIEs that
-/// describe variables or functions that are present in the linked
-/// binary (and thus have entries in the debug map). All the debug
-/// information that will be linked (the DIEs, but also the line
-/// tables, ranges, ...) is derived from that set of root DIEs.
-///
-/// The root DIEs are identified because they contain relocations that
-/// correspond to a debug map entry at specific places (the low_pc for
-/// 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 {
-public:
-  DwarfLinker(raw_fd_ostream &OutFile, const LinkOptions &Options)
-      : OutFile(OutFile), Options(Options), BinHolder(Options.Verbose) {}
-
-  /// Link the contents of the DebugMap.
-  bool link(const DebugMap &);
-
-  void reportWarning(const Twine &Warning,
-                     const DWARFDie *DIE = nullptr) const;
-
-private:
-  /// Called at the start of a debug object link.
-  void startDebugObject(DWARFContext &, DebugMapObject &);
-
-  /// Called at the end of a debug object link.
-  void endDebugObject();
-
-  /// Remembers the newest DWARF version we've seen in a unit.
-  void maybeUpdateMaxDwarfVersion(unsigned Version) {
-    if (MaxDwarfVersion < Version)
-      MaxDwarfVersion = Version;
-  }
-
-  /// Keeps track of relocations.
-  class RelocationManager {
-    struct ValidReloc {
-      uint32_t Offset;
-      uint32_t Size;
-      uint64_t Addend;
-      const DebugMapObject::DebugMapEntry *Mapping;
-
-      ValidReloc(uint32_t Offset, uint32_t Size, uint64_t Addend,
-                 const DebugMapObject::DebugMapEntry *Mapping)
-          : Offset(Offset), Size(Size), Addend(Addend), Mapping(Mapping) {}
-
-      bool operator<(const ValidReloc &RHS) const {
-        return Offset < RHS.Offset;
-      }
-    };
-
-    DwarfLinker &Linker;
-
-    /// The valid relocations for the current DebugMapObject.
-    /// This vector is sorted by relocation offset.
-    std::vector<ValidReloc> ValidRelocs;
-
-    /// Index into ValidRelocs of the next relocation to
-    /// consider. As we walk the DIEs in acsending file offset and as
-    /// ValidRelocs is sorted by file offset, keeping this index
-    /// uptodate is all we have to do to have a cheap lookup during the
-    /// root DIE selection and during DIE cloning.
-    unsigned NextValidReloc = 0;
-
-  public:
-    RelocationManager(DwarfLinker &Linker) : Linker(Linker) {}
-
-    bool hasValidRelocs() const { return !ValidRelocs.empty(); }
-
-    /// Reset the NextValidReloc counter.
-    void resetValidRelocs() { NextValidReloc = 0; }
-
-    /// \defgroup FindValidRelocations Translate debug map into a list
-    /// of relevant relocations
-    ///
-    /// @{
-    bool findValidRelocsInDebugInfo(const object::ObjectFile &Obj,
-                                    const DebugMapObject &DMO);
-
-    bool findValidRelocs(const object::SectionRef &Section,
-                         const object::ObjectFile &Obj,
-                         const DebugMapObject &DMO);
-
-    void findValidRelocsMachO(const object::SectionRef &Section,
-                              const object::MachOObjectFile &Obj,
-                              const DebugMapObject &DMO);
-    /// @}
-
-    bool hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset,
-                            CompileUnit::DIEInfo &Info);
-
-    bool applyValidRelocs(MutableArrayRef<char> Data, uint32_t BaseOffset,
-                          bool isLittleEndian);
-  };
-
-  /// \defgroup FindRootDIEs Find DIEs corresponding to debug map entries.
-  ///
-  /// @{
-  /// Recursively walk the \p DIE tree and look for DIEs to
-  /// keep. Store that information in \p CU's DIEInfo.
-  ///
-  /// The return value indicates whether the DIE is incomplete.
-  bool lookForDIEsToKeep(RelocationManager &RelocMgr, const DWARFDie &DIE,
-                         const DebugMapObject &DMO, CompileUnit &CU,
-                         unsigned Flags);
-
-  /// 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,
-                               const DWARFUnit &Unit, DebugMap &ModuleMap,
-                               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 Units.
-  Error loadClangModule(StringRef Filename, StringRef ModulePath,
-                        StringRef ModuleName, uint64_t DwoId,
-                        DebugMap &ModuleMap, unsigned Indent = 0);
-
-  /// Flags passed to DwarfLinker::lookForDIEsToKeep
-  enum TravesalFlags {
-    TF_Keep = 1 << 0,            ///< Mark the traversed DIEs as kept.
-    TF_InFunctionScope = 1 << 1, ///< Current scope is a fucntion scope.
-    TF_DependencyWalk = 1 << 2,  ///< Walking the dependencies of a kept DIE.
-    TF_ParentWalk = 1 << 3,      ///< Walking up the parents of a kept DIE.
-    TF_ODR = 1 << 4,             ///< Use the ODR whhile keeping dependants.
-    TF_SkipPC = 1 << 5,          ///< Skip all location attributes.
-  };
-
-  /// Mark the passed DIE as well as all the ones it depends on as kept.
-  void keepDIEAndDependencies(RelocationManager &RelocMgr,
-                               const DWARFDie &DIE,
-                               CompileUnit::DIEInfo &MyInfo,
-                               const DebugMapObject &DMO, CompileUnit &CU,
-                               bool UseODR);
-
-  unsigned shouldKeepDIE(RelocationManager &RelocMgr,
-                         const DWARFDie &DIE,
-                         CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
-                         unsigned Flags);
-
-  unsigned shouldKeepVariableDIE(RelocationManager &RelocMgr,
-                                 const DWARFDie &DIE,
-                                 CompileUnit &Unit,
-                                 CompileUnit::DIEInfo &MyInfo, unsigned Flags);
-
-  unsigned shouldKeepSubprogramDIE(RelocationManager &RelocMgr,
-                                   const DWARFDie &DIE,
-                                   CompileUnit &Unit,
-                                   CompileUnit::DIEInfo &MyInfo,
-                                   unsigned Flags);
-
-  bool hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset,
-                          CompileUnit::DIEInfo &Info);
-  /// @}
-
-  /// \defgroup Linking Methods used to link the debug information
-  ///
-  /// @{
-
-  class DIECloner {
-    DwarfLinker &Linker;
-    RelocationManager &RelocMgr;
-
-    /// Allocator used for all the DIEValue objects.
-    BumpPtrAllocator &DIEAlloc;
-
-    std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
-    LinkOptions Options;
-
-  public:
-    DIECloner(DwarfLinker &Linker, RelocationManager &RelocMgr,
-              BumpPtrAllocator &DIEAlloc,
-              std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
-              LinkOptions &Options)
-        : Linker(Linker), RelocMgr(RelocMgr), DIEAlloc(DIEAlloc),
-          CompileUnits(CompileUnits), Options(Options) {}
-
-    /// Recursively clone \p InputDIE into an tree of DIE objects
-    /// where useless (as decided by lookForDIEsToKeep()) bits have been
-    /// stripped out and addresses have been rewritten according to the
-    /// debug map.
-    ///
-    /// \param OutOffset is the offset the cloned DIE in the output
-    /// compile unit.
-    /// \param PCOffset (while cloning a function scope) is the offset
-    /// applied to the entry point of the function to get the linked address.
-    /// \param Die the output DIE to use, pass NULL to create one.
-    /// \returns the root of the cloned tree or null if nothing was selected.
-    DIE *cloneDIE(const DWARFDie &InputDIE, CompileUnit &U,
-                  int64_t PCOffset, uint32_t OutOffset, unsigned Flags,
-                  DIE *Die = nullptr);
-
-    /// Construct the output DIE tree by cloning the DIEs we
-    /// chose to keep above. If there are no valid relocs, then there's
-    /// nothing to clone/emit.
-    void cloneAllCompileUnits(DWARFContext &DwarfContext);
-
-  private:
-    using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
-
-    /// Information gathered and exchanged between the various
-    /// clone*Attributes helpers about the attributes of a particular DIE.
-    struct AttributesInfo {
-      /// Names.
-      DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
-
-      /// Offsets in the string pool.
-      uint32_t NameOffset = 0;
-      uint32_t MangledNameOffset = 0;
-
-      /// Value of AT_low_pc in the input DIE
-      uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max();
-
-      /// Value of AT_high_pc in the input DIE
-      uint64_t OrigHighPc = 0;
-
-      /// Offset to apply to PC addresses inside a function.
-      int64_t PCOffset = 0;
-
-      /// Does the DIE have a low_pc attribute?
-      bool HasLowPc = false;
-
-      /// Does the DIE have a ranges attribute?
-      bool HasRanges = false;
-
-      /// Is this DIE only a declaration?
-      bool IsDeclaration = false;
-
-      AttributesInfo() = default;
-    };
-
-    /// Helper for cloneDIE.
-    unsigned cloneAttribute(DIE &Die,
-                            const DWARFDie &InputDIE,
-                            CompileUnit &U, const DWARFFormValue &Val,
-                            const AttributeSpec AttrSpec, unsigned AttrSize,
-                            AttributesInfo &AttrInfo);
-
-    /// Clone a string attribute described by \p AttrSpec and add
-    /// it to \p Die.
-    /// \returns the size of the new attribute.
-    unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
-                                  const DWARFFormValue &Val, const DWARFUnit &U,
-                                  AttributesInfo &Info);
-
-    /// Clone an attribute referencing another DIE and add
-    /// it to \p Die.
-    /// \returns the size of the new attribute.
-    unsigned
-    cloneDieReferenceAttribute(DIE &Die,
-                               const DWARFDie &InputDIE,
-                               AttributeSpec AttrSpec, unsigned AttrSize,
-                               const DWARFFormValue &Val, CompileUnit &Unit);
-
-    /// Clone an attribute referencing another DIE and add
-    /// it to \p Die.
-    /// \returns the size of the new attribute.
-    unsigned cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec,
-                                 const DWARFFormValue &Val, unsigned AttrSize);
-
-    /// Clone an attribute referencing another DIE and add
-    /// it to \p Die.
-    /// \returns the size of the new attribute.
-    unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
-                                   const DWARFFormValue &Val,
-                                   const CompileUnit &Unit,
-                                   AttributesInfo &Info);
-
-    /// Clone a scalar attribute  and add it to \p Die.
-    /// \returns the size of the new attribute.
-    unsigned cloneScalarAttribute(DIE &Die,
-                                  const DWARFDie &InputDIE,
-                                  CompileUnit &U, AttributeSpec AttrSpec,
-                                  const DWARFFormValue &Val, unsigned AttrSize,
-                                  AttributesInfo &Info);
-
-    /// Get the potential name and mangled name for the entity
-    /// described by \p Die and store them in \Info if they are not
-    /// already there.
-    /// \returns is a name was found.
-    bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
-                     bool StripTemplate = false);
-
-    /// Create a copy of abbreviation Abbrev.
-    void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR);
-
-    uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
-                                    int RecurseDepth = 0);
-
-    /// Helper for cloneDIE.
-    void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
-                            DwarfStringPoolEntryRef Name, bool SkipPubSection);
-  };
-
-  /// Assign an abbreviation number to \p Abbrev
-  void AssignAbbrev(DIEAbbrev &Abbrev);
-
-  /// Compute and emit debug_ranges section for \p Unit, and
-  /// patch the attributes referencing it.
-  void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf) const;
-
-  /// Generate and emit the DW_AT_ranges attribute for a
-  /// compile_unit if it had one.
-  void generateUnitRanges(CompileUnit &Unit) const;
-
-  /// Extract the line tables fromt he original dwarf, extract
-  /// the relevant parts according to the linked function ranges and
-  /// emit the result in the debug_line section.
-  void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf);
-
-  /// Emit the accelerator entries for \p Unit.
-  void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
-
-  /// Patch the frame info for an object file and emit it.
-  void patchFrameInfoForObject(const DebugMapObject &, DWARFContext &,
-                               unsigned AddressSize);
-
-  /// FoldingSet that uniques the abbreviations.
-  FoldingSet<DIEAbbrev> AbbreviationsSet;
-
-  /// Storage for the unique Abbreviations.
-  /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot
-  /// be changed to a vecot of unique_ptrs.
-  std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
-
-  /// DIELoc objects that need to be destructed (but not freed!).
-  std::vector<DIELoc *> DIELocs;
-
-  /// DIEBlock objects that need to be destructed (but not freed!).
-  std::vector<DIEBlock *> DIEBlocks;
-
-  /// Allocator used for all the DIEValue objects.
-  BumpPtrAllocator DIEAlloc;
-  /// @}
-
-  /// ODR Contexts for that link.
-  DeclContextTree ODRContexts;
-
-  /// \defgroup Helpers Various helper methods.
-  ///
-  /// @{
-  bool createStreamer(const Triple &TheTriple, raw_fd_ostream &OutFile);
-
-  /// Attempt to load a debug object from disk.
-  ErrorOr<const object::ObjectFile &> loadObject(BinaryHolder &BinaryHolder,
-                                                 DebugMapObject &Obj,
-                                                 const DebugMap &Map);
-  /// @}
-
-  raw_fd_ostream &OutFile;
-  LinkOptions Options;
-  BinaryHolder BinHolder;
-  std::unique_ptr<DwarfStreamer> Streamer;
-  uint64_t OutputDebugInfoSize;
-
-  /// A unique ID that identifies each compile unit.
-  unsigned UnitID;
-
-  unsigned MaxDwarfVersion = 0;
-
-  /// The units of the current debug map object.
-  std::vector<std::unique_ptr<CompileUnit>> Units;
-
-  /// The debug map object currently under consideration.
-  DebugMapObject *CurrentDebugObject;
-
-  /// The Dwarf string pool.
-  NonRelocatableStringpool StringPool;
-
-  /// This map is keyed by the entry PC of functions in that
-  /// debug object and the associated value is a pair storing the
-  /// corresponding end PC and the offset to apply to get the linked
-  /// address.
-  ///
-  /// See startDebugObject() for a more complete description of its use.
-  std::map<uint64_t, std::pair<uint64_t, int64_t>> Ranges;
-
-  /// The CIEs that have been emitted in the output
-  /// section. The actual CIE data serves a the key to this StringMap,
-  /// this takes care of comparing the semantics of CIEs defined in
-  /// different object files.
-  StringMap<uint32_t> EmittedCIEs;
-
-  /// Offset of the last CIE that has been emitted in the output
-  /// debug_frame section.
-  uint32_t LastCIEOffset = 0;
-
-  /// Apple accelerator tables.
-  AppleAccelTable<AppleAccelTableStaticOffsetData> AppleNames;
-  AppleAccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
-  AppleAccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
-  AppleAccelTable<AppleAccelTableStaticTypeData> AppleTypes;
-
-  /// Mapping the PCM filename to the DwoId.
-  StringMap<uint64_t> ClangModules;
-
-  bool ModuleCacheHintDisplayed = false;
-  bool ArchiveHintDisplayed = false;
-};
-
-} // end anonymous namespace
-
 /// Similar to DWARFUnitSection::getUnitForOffset(), but returning our
 /// CompileUnit object instead.
-static CompileUnit *getUnitForOffset(
-    std::vector<std::unique_ptr<CompileUnit>> &Units, unsigned Offset) {
-  auto CU =
-      std::upper_bound(Units.begin(), Units.end(), Offset,
-                       [](uint32_t LHS, const std::unique_ptr<CompileUnit> &RHS) {
-                         return LHS < RHS->getOrigUnit().getNextUnitOffset();
-                       });
+static CompileUnit *getUnitForOffset(const UnitListTy &Units, uint64_t Offset) {
+  auto CU = std::upper_bound(
+      Units.begin(), Units.end(), Offset,
+      [](uint64_t LHS, const std::unique_ptr<CompileUnit> &RHS) {
+        return LHS < RHS->getOrigUnit().getNextUnitOffset();
+      });
   return CU != Units.end() ? CU->get() : nullptr;
 }
 
-/// Resolve the DIE attribute reference that has been
-/// extracted in \p RefValue. The resulting DIE migh be in another
-/// CompileUnit which is stored into \p ReferencedCU.
-/// \returns null if resolving fails for any reason.
-static DWARFDie resolveDIEReference(
-    const DwarfLinker &Linker, std::vector<std::unique_ptr<CompileUnit>> &Units,
-    const DWARFFormValue &RefValue, const DWARFUnit &Unit,
-    const DWARFDie &DIE, CompileUnit *&RefCU) {
+/// 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,
+                                    const DebugMapObject &DMO,
+                                    const UnitListTy &Units,
+                                    const DWARFFormValue &RefValue,
+                                    const DWARFDie &DIE, CompileUnit *&RefCU) {
   assert(RefValue.isFormClass(DWARFFormValue::FC_Reference));
   uint64_t RefOffset = *RefValue.getAsReference();
-
   if ((RefCU = getUnitForOffset(Units, RefOffset)))
     if (const auto RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset)) {
       // In a file with broken references, an attribute might point to a NULL
       // DIE.
-      if(!RefDie.isNULL())
+      if (!RefDie.isNULL())
         return RefDie;
     }
 
-  Linker.reportWarning("could not find referenced DIE", &DIE);
+  Linker.reportWarning("could not find referenced DIE", DMO, &DIE);
   return DWARFDie();
 }
 
-/// \returns whether the passed \a Attr type might contain a DIE
-/// reference suitable for ODR uniquing.
+/// \returns whether the passed \a Attr type might contain a DIE reference
+/// suitable for ODR uniquing.
 static bool isODRAttribute(uint16_t Attr) {
   switch (Attr) {
   default:
@@ -1823,207 +152,43 @@
   llvm_unreachable("Improper attribute.");
 }
 
-/// Set the last DIE/CU a context was seen in and, possibly invalidate
-/// the context if it is ambiguous.
-///
-/// In the current implementation, we don't handle overloaded
-/// functions well, because the argument types are not taken into
-/// account when computing the DeclContext tree.
-///
-/// Some of this is mitigated byt using mangled names that do contain
-/// the arguments types, but sometimes (eg. with function templates)
-/// we don't have that. In that case, just do not unique anything that
-/// refers to the contexts we are not able to distinguish.
-///
-/// If a context that is not a namespace appears twice in the same CU,
-/// we know it is ambiguous. Make it invalid.
-bool DeclContext::setLastSeenDIE(CompileUnit &U,
-                                 const  DWARFDie &Die) {
-  if (LastSeenCompileUnitID == U.getUniqueID()) {
-    DWARFUnit &OrigUnit = U.getOrigUnit();
-    uint32_t FirstIdx = OrigUnit.getDIEIndex(LastSeenDIE);
-    U.getInfo(FirstIdx).Ctxt = nullptr;
-    return false;
-  }
-
-  LastSeenCompileUnitID = U.getUniqueID();
-  LastSeenDIE = Die;
-  return true;
-}
-
-PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext(
-    DeclContext &Context, const DWARFDie &DIE, CompileUnit &U,
-    NonRelocatableStringpool &StringPool, bool InClangModule) {
-  unsigned Tag = DIE.getTag();
-
-  // FIXME: dsymutil-classic compat: We should bail out here if we
-  // have a specification or an abstract_origin. We will get the
-  // parent context wrong here.
-
+static bool isTypeTag(uint16_t Tag) {
   switch (Tag) {
+  case dwarf::DW_TAG_array_type:
+  case dwarf::DW_TAG_class_type:
+  case dwarf::DW_TAG_enumeration_type:
+  case dwarf::DW_TAG_pointer_type:
+  case dwarf::DW_TAG_reference_type:
+  case dwarf::DW_TAG_string_type:
+  case dwarf::DW_TAG_structure_type:
+  case dwarf::DW_TAG_subroutine_type:
+  case dwarf::DW_TAG_typedef:
+  case dwarf::DW_TAG_union_type:
+  case dwarf::DW_TAG_ptr_to_member_type:
+  case dwarf::DW_TAG_set_type:
+  case dwarf::DW_TAG_subrange_type:
+  case dwarf::DW_TAG_base_type:
+  case dwarf::DW_TAG_const_type:
+  case dwarf::DW_TAG_constant:
+  case dwarf::DW_TAG_file_type:
+  case dwarf::DW_TAG_namelist:
+  case dwarf::DW_TAG_packed_type:
+  case dwarf::DW_TAG_volatile_type:
+  case dwarf::DW_TAG_restrict_type:
+  case dwarf::DW_TAG_atomic_type:
+  case dwarf::DW_TAG_interface_type:
+  case dwarf::DW_TAG_unspecified_type:
+  case dwarf::DW_TAG_shared_type:
+    return true;
   default:
-    // By default stop gathering child contexts.
-    return PointerIntPair<DeclContext *, 1>(nullptr);
-  case dwarf::DW_TAG_module:
-    break;
-  case dwarf::DW_TAG_compile_unit:
-    return PointerIntPair<DeclContext *, 1>(&Context);
-  case dwarf::DW_TAG_subprogram:
-    // Do not unique anything inside CU local functions.
-    if ((Context.getTag() == dwarf::DW_TAG_namespace ||
-         Context.getTag() == dwarf::DW_TAG_compile_unit) &&
-        !dwarf::toUnsigned(DIE.find(dwarf::DW_AT_external), 0))
-      return PointerIntPair<DeclContext *, 1>(nullptr);
-    LLVM_FALLTHROUGH;
-  case dwarf::DW_TAG_member:
-  case dwarf::DW_TAG_namespace:
-  case dwarf::DW_TAG_structure_type:
-  case dwarf::DW_TAG_class_type:
-  case dwarf::DW_TAG_union_type:
-  case dwarf::DW_TAG_enumeration_type:
-  case dwarf::DW_TAG_typedef:
-    // Artificial things might be ambiguous, because they might be
-    // created on demand. For example implicitely defined constructors
-    // are ambiguous because of the way we identify contexts, and they
-    // won't be generated everytime everywhere.
-    if (dwarf::toUnsigned(DIE.find(dwarf::DW_AT_artificial), 0))
-      return PointerIntPair<DeclContext *, 1>(nullptr);
     break;
   }
-
-  const char *Name = DIE.getName(DINameKind::LinkageName);
-  const char *ShortName = DIE.getName(DINameKind::ShortName);
-  StringRef NameRef;
-  StringRef ShortNameRef;
-  StringRef FileRef;
-
-  if (Name)
-    NameRef = StringPool.internString(Name);
-  else if (Tag == dwarf::DW_TAG_namespace)
-    // FIXME: For dsymutil-classic compatibility. I think uniquing
-    // within anonymous namespaces is wrong. There is no ODR guarantee
-    // there.
-    NameRef = StringPool.internString("(anonymous namespace)");
-
-  if (ShortName && ShortName != Name)
-    ShortNameRef = StringPool.internString(ShortName);
-  else
-    ShortNameRef = NameRef;
-
-  if (Tag != dwarf::DW_TAG_class_type && Tag != dwarf::DW_TAG_structure_type &&
-      Tag != dwarf::DW_TAG_union_type &&
-      Tag != dwarf::DW_TAG_enumeration_type && NameRef.empty())
-    return PointerIntPair<DeclContext *, 1>(nullptr);
-
-  unsigned Line = 0;
-  unsigned ByteSize = std::numeric_limits<uint32_t>::max();
-
-  if (!InClangModule) {
-    // Gather some discriminating data about the DeclContext we will be
-    // creating: File, line number and byte size. This shouldn't be
-    // necessary, because the ODR is just about names, but given that we
-    // do some approximations with overloaded functions and anonymous
-    // namespaces, use these additional data points to make the process
-    // safer.  This is disabled for clang modules, because forward
-    // declarations of module-defined types do not have a file and line.
-    ByteSize = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_byte_size),
-                                 std::numeric_limits<uint64_t>::max());
-    if (Tag != dwarf::DW_TAG_namespace || !Name) {
-      if (unsigned FileNum = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_decl_file), 0)) {
-        if (const auto *LT = U.getOrigUnit().getContext().getLineTableForUnit(
-                &U.getOrigUnit())) {
-          // FIXME: dsymutil-classic compatibility. I'd rather not
-          // unique anything in anonymous namespaces, but if we do, then
-          // verify that the file and line correspond.
-          if (!Name && Tag == dwarf::DW_TAG_namespace)
-            FileNum = 1;
-
-          // FIXME: Passing U.getOrigUnit().getCompilationDir()
-          // instead of "" would allow more uniquing, but for now, do
-          // it this way to match dsymutil-classic.
-          if (LT->hasFileAtIndex(FileNum)) {
-            Line = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_decl_line), 0);
-            // Cache the resolved paths, because calling realpath is expansive.
-            StringRef ResolvedPath = U.getResolvedPath(FileNum);
-            if (!ResolvedPath.empty()) {
-              FileRef = ResolvedPath;
-            } else {
-              std::string File;
-              bool gotFileName =
-                LT->getFileNameByIndex(FileNum, "",
-                        DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
-                        File);
-              (void)gotFileName;
-              assert(gotFileName && "Must get file name from line table");
-#ifdef HAVE_REALPATH
-              char RealPath[PATH_MAX + 1];
-              RealPath[PATH_MAX] = 0;
-              if (::realpath(File.c_str(), RealPath))
-                File = RealPath;
-#endif
-              FileRef = StringPool.internString(File);
-              U.setResolvedPath(FileNum, FileRef);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  if (!Line && NameRef.empty())
-    return PointerIntPair<DeclContext *, 1>(nullptr);
-
-  // We hash NameRef, which is the mangled name, in order to get most
-  // overloaded functions resolve correctly.
-  //
-  // Strictly speaking, hashing the Tag is only necessary for a
-  // DW_TAG_module, to prevent uniquing of a module and a namespace
-  // with the same name.
-  //
-  // FIXME: dsymutil-classic won't unique the same type presented
-  // once as a struct and once as a class. Using the Tag in the fully
-  // qualified name hash to get the same effect.
-  unsigned Hash = hash_combine(Context.getQualifiedNameHash(), Tag, NameRef);
-
-  // FIXME: dsymutil-classic compatibility: when we don't have a name,
-  // use the filename.
-  if (Tag == dwarf::DW_TAG_namespace && NameRef == "(anonymous namespace)")
-    Hash = hash_combine(Hash, FileRef);
-
-  // Now look if this context already exists.
-  DeclContext Key(Hash, Line, ByteSize, Tag, NameRef, FileRef, Context);
-  auto ContextIter = Contexts.find(&Key);
-
-  if (ContextIter == Contexts.end()) {
-    // The context wasn't found.
-    bool Inserted;
-    DeclContext *NewContext =
-        new (Allocator) DeclContext(Hash, Line, ByteSize, Tag, NameRef, FileRef,
-                                    Context, DIE, U.getUniqueID());
-    std::tie(ContextIter, Inserted) = Contexts.insert(NewContext);
-    assert(Inserted && "Failed to insert DeclContext");
-    (void)Inserted;
-  } else if (Tag != dwarf::DW_TAG_namespace &&
-             !(*ContextIter)->setLastSeenDIE(U, DIE)) {
-    // The context was found, but it is ambiguous with another context
-    // in the same file. Mark it invalid.
-    return PointerIntPair<DeclContext *, 1>(*ContextIter, /* Invalid= */ 1);
-  }
-
-  assert(ContextIter != Contexts.end());
-  // FIXME: dsymutil-classic compatibility. Union types aren't
-  // uniques, but their children might be.
-  if ((Tag == dwarf::DW_TAG_subprogram &&
-       Context.getTag() != dwarf::DW_TAG_structure_type &&
-       Context.getTag() != dwarf::DW_TAG_class_type) ||
-      (Tag == dwarf::DW_TAG_union_type))
-    return PointerIntPair<DeclContext *, 1>(*ContextIter, /* Invalid= */ 1);
-
-  return PointerIntPair<DeclContext *, 1>(*ContextIter);
+  return false;
 }
 
 bool DwarfLinker::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
@@ -2035,39 +200,37 @@
   // short name.
   if (!Info.MangledName)
     if (const char *MangledName = Die.getName(DINameKind::LinkageName))
-      Info.MangledName = Linker.StringPool.getEntry(MangledName);
+      Info.MangledName = StringPool.getEntry(MangledName);
 
   if (!Info.Name)
     if (const char *Name = Die.getName(DINameKind::ShortName))
-      Info.Name = Linker.StringPool.getEntry(Name);
+      Info.Name = StringPool.getEntry(Name);
 
   if (StripTemplate && Info.Name && Info.MangledName != Info.Name) {
     // FIXME: dsymutil compatibility. This is wrong for operator<
     auto Split = Info.Name.getString().split('<');
     if (!Split.second.empty())
-      Info.NameWithoutTemplate = Linker.StringPool.getEntry(Split.first);
+      Info.NameWithoutTemplate = StringPool.getEntry(Split.first);
   }
 
   return Info.Name || Info.MangledName;
 }
 
-/// Report a warning to the user, optionaly including
-/// information about a specific \p DIE related to the warning.
-void DwarfLinker::reportWarning(const Twine &Warning,
+/// 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 {
-  StringRef Context = "<debug map>";
-  if (CurrentDebugObject)
-    Context = CurrentDebugObject->getObjectFilename();
+  StringRef Context = DMO.getObjectFilename();
   warn(Warning, Context);
 
   if (!Options.Verbose || !DIE)
     return;
 
   DIDumpOptions DumpOpts;
-  DumpOpts.RecurseDepth = 0;
+  DumpOpts.ChildRecurseDepth = 0;
   DumpOpts.Verbose = Options.Verbose;
 
-  errs() << "    in DIE:\n";
+  WithColor::note() << "    in DIE:\n";
   DIE->dump(errs(), 6 /* Indent */, DumpOpts);
 }
 
@@ -2076,22 +239,59 @@
   if (Options.NoOutput)
     return true;
 
-  Streamer = llvm::make_unique<DwarfStreamer>(OutFile);
+  Streamer = llvm::make_unique<DwarfStreamer>(OutFile, Options);
   return Streamer->init(TheTriple);
 }
 
+/// Resolve the relative path to a build artifact referenced by DWARF by
+/// applying DW_AT_comp_dir.
+static void resolveRelativeObjectPath(SmallVectorImpl<char> &Buf, DWARFDie CU) {
+  sys::path::append(Buf, dwarf::toString(CU.find(dwarf::DW_AT_comp_dir), ""));
+}
+
+/// Collect references to parseable Swift interfaces in imported
+/// DW_TAG_module blocks.
+static void analyzeImportedModule(
+    const DWARFDie &DIE, CompileUnit &CU,
+    std::map<std::string, std::string> &ParseableSwiftInterfaces,
+    std::function<void(const Twine &, const DWARFDie &)> ReportWarning) {
+  if (CU.getLanguage() != dwarf::DW_LANG_Swift)
+    return;
+
+  StringRef Path = dwarf::toStringRef(DIE.find(dwarf::DW_AT_LLVM_include_path));
+  if (!Path.endswith(".swiftinterface"))
+    return;
+  if (Optional<DWARFFormValue> Val = DIE.find(dwarf::DW_AT_name))
+    if (Optional<const char *> Name = Val->getAsCString()) {
+      auto &Entry = ParseableSwiftInterfaces[*Name];
+      // The prepend path is applied later when copying.
+      DWARFDie CUDie = CU.getOrigUnit().getUnitDIE();
+      SmallString<128> ResolvedPath;
+      if (sys::path::is_relative(Path))
+        resolveRelativeObjectPath(ResolvedPath, CUDie);
+      sys::path::append(ResolvedPath, Path);
+      if (!Entry.empty() && Entry != ResolvedPath)
+        ReportWarning(
+            Twine("Conflicting parseable interfaces for Swift Module ") +
+                *Name + ": " + Entry + " and " + Path,
+            DIE);
+      Entry = ResolvedPath.str();
+    }
+}
+
 /// Recursive helper to build the global DeclContext information and
 /// gather the child->parent relationships in the original compile unit.
 ///
 /// \return true when this DIE and all of its children are only
 /// forward declarations to types defined in external clang modules
 /// (i.e., forward declarations that are children of a DW_TAG_module).
-static bool analyzeContextInfo(const DWARFDie &DIE,
-                               unsigned ParentIdx, CompileUnit &CU,
-                               DeclContext *CurrentDeclContext,
-                               NonRelocatableStringpool &StringPool,
-                               DeclContextTree &Contexts,
-                               bool InImportedModule = false) {
+static bool analyzeContextInfo(
+    const DWARFDie &DIE, unsigned ParentIdx, CompileUnit &CU,
+    DeclContext *CurrentDeclContext, UniquingStringPool &StringPool,
+    DeclContextTree &Contexts, uint64_t ModulesEndOffset,
+    std::map<std::string, std::string> &ParseableSwiftInterfaces,
+    std::function<void(const Twine &, const DWARFDie &)> ReportWarning,
+    bool InImportedModule = false) {
   unsigned MyIdx = CU.getOrigUnit().getDIEIndex(DIE);
   CompileUnit::DIEInfo &Info = CU.getInfo(MyIdx);
 
@@ -2111,6 +311,7 @@
       dwarf::toString(DIE.find(dwarf::DW_AT_name), "") !=
           CU.getClangModuleName()) {
     InImportedModule = true;
+    analyzeImportedModule(DIE, CU, ParseableSwiftInterfaces, ReportWarning);
   }
 
   Info.ParentIdx = ParentIdx;
@@ -2130,22 +331,29 @@
 
   Info.Prune = InImportedModule;
   if (DIE.hasChildren())
-    for (auto Child: DIE.children())
+    for (auto Child : DIE.children())
       Info.Prune &= analyzeContextInfo(Child, MyIdx, CU, CurrentDeclContext,
-                                       StringPool, Contexts, InImportedModule);
+                                       StringPool, Contexts, ModulesEndOffset,
+                                       ParseableSwiftInterfaces, ReportWarning,
+                                       InImportedModule);
 
   // Prune this DIE if it is either a forward declaration inside a
   // DW_TAG_module or a DW_TAG_module that contains nothing but
   // forward declarations.
-  Info.Prune &=
-      (DIE.getTag() == dwarf::DW_TAG_module) ||
-      dwarf::toUnsigned(DIE.find(dwarf::DW_AT_declaration), 0);
+  Info.Prune &= (DIE.getTag() == dwarf::DW_TAG_module) ||
+                (isTypeTag(DIE.getTag()) &&
+                 dwarf::toUnsigned(DIE.find(dwarf::DW_AT_declaration), 0));
 
-  // Don't prune it if there is no definition for the DIE.
-  Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset();
+  // Only prune forward declarations inside a DW_TAG_module for which a
+  // definition exists elsewhere.
+  if (ModulesEndOffset == 0)
+    Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset();
+  else
+    Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset() > 0 &&
+                  Info.Ctxt->getCanonicalDIEOffset() <= ModulesEndOffset;
 
   return Info.Prune;
-}
+} // namespace dsymutil
 
 static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) {
   switch (Tag) {
@@ -2162,33 +370,35 @@
   llvm_unreachable("Invalid Tag");
 }
 
-void DwarfLinker::startDebugObject(DWARFContext &Dwarf, DebugMapObject &Obj) {
+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:
-  //  - obviously this one is global, while the other ones are per-unit.
-  //  - 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.
+  // 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 : Obj.symbols()) {
+  for (const auto &Entry : Context.DMO.symbols()) {
     const auto &Mapping = Entry.getValue();
     if (Mapping.Size && Mapping.ObjectAddress)
-      Ranges[*Mapping.ObjectAddress] = std::make_pair(
+      Context.Ranges[*Mapping.ObjectAddress] = DebugMapObjectRange(
           *Mapping.ObjectAddress + Mapping.Size,
           int64_t(Mapping.BinaryAddress) - *Mapping.ObjectAddress);
   }
 }
 
-void DwarfLinker::endDebugObject() {
-  Units.clear();
-  Ranges.clear();
+void DwarfLinker::endDebugObject(LinkContext &Context) {
+  Context.Clear();
 
   for (auto I = DIEBlocks.begin(), E = DIEBlocks.end(); I != E; ++I)
     (*I)->~DIEBlock();
@@ -2223,13 +433,16 @@
 /// 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(const object::SectionRef &Section,
-                     const object::MachOObjectFile &Obj,
-                     const DebugMapObject &DMO) {
-  StringRef Contents;
-  Section.getContents(Contents);
-  DataExtractor Data(Contents, Obj.isLittleEndian(), 0);
+void DwarfLinker::RelocationManager::findValidRelocsMachO(
+    const object::SectionRef &Section, const object::MachOObjectFile &Obj,
+    const DebugMapObject &DMO) {
+  Expected<StringRef> ContentsOrErr = Section.getContents();
+  if (!ContentsOrErr) {
+    consumeError(ContentsOrErr.takeError());
+    Linker.reportWarning("error reading section", DMO);
+    return;
+  }
+  DataExtractor Data(*ContentsOrErr, Obj.isLittleEndian(), 0);
   bool SkipNext = false;
 
   for (const object::RelocationRef &Reloc : Section.relocations()) {
@@ -2244,19 +457,21 @@
     if (isMachOPairedReloc(Obj.getAnyRelocationType(MachOReloc),
                            Obj.getArch())) {
       SkipNext = true;
-      Linker.reportWarning(" unsupported relocation in debug_info section.");
+      Linker.reportWarning("unsupported relocation in debug_info section.",
+                           DMO);
       continue;
     }
 
     unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc);
     uint64_t Offset64 = Reloc.getOffset();
     if ((RelocSize != 4 && RelocSize != 8)) {
-      Linker.reportWarning(" unsupported relocation in debug_info section.");
+      Linker.reportWarning("unsupported relocation in debug_info section.",
+                           DMO);
       continue;
     }
-    uint32_t Offset = Offset64;
+    uint64_t OffsetCopy = Offset64;
     // Mach-o uses REL relocations, the addend is at the relocation offset.
-    uint64_t Addend = Data.getUnsigned(&Offset, RelocSize);
+    uint64_t Addend = Data.getUnsigned(&OffsetCopy, RelocSize);
     uint64_t SymAddress;
     int64_t SymOffset;
 
@@ -2276,15 +491,15 @@
       Expected<StringRef> SymbolName = Sym->getName();
       if (!SymbolName) {
         consumeError(SymbolName.takeError());
-        Linker.reportWarning("error getting relocation symbol name.");
+        Linker.reportWarning("error getting relocation symbol name.", DMO);
         continue;
       }
       if (const auto *Mapping = DMO.lookupSymbol(*SymbolName))
         ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping);
     } else if (const auto *Mapping = DMO.lookupObjectAddress(SymAddress)) {
-      // Do not store the addend. The addend was the address of the
-      // symbol in the object file, the address in the binary that is
-      // stored in the debug map doesn't need to be offseted.
+      // Do not store the addend. The addend was the address of the symbol in
+      // the object file, the address in the binary that is stored in the debug
+      // map doesn't need to be offset.
       ValidRelocs.emplace_back(Offset64, RelocSize, SymOffset, Mapping);
     }
   }
@@ -2299,8 +514,8 @@
   if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj))
     findValidRelocsMachO(Section, *MachOObj, DMO);
   else
-    Linker.reportWarning(Twine("unsupported object file type: ") +
-                         Obj.getFileName());
+    Linker.reportWarning(
+        Twine("unsupported object file type: ") + Obj.getFileName(), DMO);
 
   if (ValidRelocs.empty())
     return false;
@@ -2309,7 +524,7 @@
   // the file, this allows us to just keep an index in the relocation
   // array that we advance during our walk, rather than resorting to
   // some associative container. See DwarfLinker::NextValidReloc.
-  std::sort(ValidRelocs.begin(), ValidRelocs.end());
+  llvm::sort(ValidRelocs);
   return true;
 }
 
@@ -2317,10 +532,9 @@
 /// entries in the debug map. These relocations will drive the Dwarf
 /// link by indicating which DIEs refer to symbols present in the
 /// linked binary.
-/// \returns wether there are any valid relocations in the debug info.
-bool DwarfLinker::RelocationManager::
-findValidRelocsInDebugInfo(const object::ObjectFile &Obj,
-                           const DebugMapObject &DMO) {
+/// \returns whether there are any valid relocations in the debug info.
+bool DwarfLinker::RelocationManager::findValidRelocsInDebugInfo(
+    const object::ObjectFile &Obj, const DebugMapObject &DMO) {
   // Find the debug_info section.
   for (const object::SectionRef &Section : Obj.sections()) {
     StringRef SectionName;
@@ -2339,9 +553,8 @@
 /// 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(uint32_t StartOffset, uint32_t EndOffset,
-                   CompileUnit::DIEInfo &Info) {
+bool DwarfLinker::RelocationManager::hasValidRelocation(
+    uint64_t StartOffset, uint64_t EndOffset, CompileUnit::DIEInfo &Info) {
   assert(NextValidReloc == 0 ||
          StartOffset > ValidRelocs[NextValidReloc - 1].Offset);
   if (NextValidReloc >= ValidRelocs.size())
@@ -2366,8 +579,9 @@
                                : std::numeric_limits<uint64_t>::max();
   if (Linker.Options.Verbose)
     outs() << "Found valid debug map entry: " << ValidReloc.Mapping->getKey()
-           << " " << format("\t%016" PRIx64 " => %016" PRIx64, ObjectAddress,
-                            uint64_t(Mapping.BinaryAddress));
+           << " "
+           << format("\t%016" PRIx64 " => %016" PRIx64, ObjectAddress,
+                     uint64_t(Mapping.BinaryAddress));
 
   Info.AddrAdjust = int64_t(Mapping.BinaryAddress) + ValidReloc.Addend;
   if (Mapping.ObjectAddress)
@@ -2381,16 +595,16 @@
 /// supposed to point to the position of the first attribute described
 /// by \p Abbrev.
 /// \return [StartOffset, EndOffset) as a pair.
-static std::pair<uint32_t, uint32_t>
+static std::pair<uint64_t, uint64_t>
 getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx,
-                    unsigned Offset, const DWARFUnit &Unit) {
+                    uint64_t Offset, const DWARFUnit &Unit) {
   DataExtractor Data = Unit.getDebugInfoExtractor();
 
   for (unsigned i = 0; i < Idx; ++i)
     DWARFFormValue::skipValue(Abbrev->getFormByIndex(i), Data, &Offset,
                               Unit.getFormParams());
 
-  uint32_t End = Offset;
+  uint64_t End = Offset;
   DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End,
                             Unit.getFormParams());
 
@@ -2418,9 +632,9 @@
   if (!LocationIdx)
     return Flags;
 
-  uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
+  uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
   const DWARFUnit &OrigUnit = Unit.getOrigUnit();
-  uint32_t LocationOffset, LocationEndOffset;
+  uint64_t LocationOffset, LocationEndOffset;
   std::tie(LocationOffset, LocationEndOffset) =
       getAttributeOffsets(Abbrev, *LocationIdx, Offset, OrigUnit);
 
@@ -2435,7 +649,7 @@
 
   if (Options.Verbose) {
     DIDumpOptions DumpOpts;
-    DumpOpts.RecurseDepth = 0;
+    DumpOpts.ChildRecurseDepth = 0;
     DumpOpts.Verbose = Options.Verbose;
     DIE.dump(outs(), 8 /* Indent */, DumpOpts);
   }
@@ -2446,9 +660,9 @@
 /// Check if a function describing DIE should be kept.
 /// \returns updated TraversalFlags.
 unsigned DwarfLinker::shouldKeepSubprogramDIE(
-    RelocationManager &RelocMgr,
-    const DWARFDie &DIE, CompileUnit &Unit,
-    CompileUnit::DIEInfo &MyInfo, unsigned Flags) {
+    RelocationManager &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE,
+    const DebugMapObject &DMO, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
+    unsigned Flags) {
   const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
 
   Flags |= TF_InFunctionScope;
@@ -2457,9 +671,9 @@
   if (!LowPcIdx)
     return Flags;
 
-  uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
-  const DWARFUnit &OrigUnit = Unit.getOrigUnit();
-  uint32_t LowPcOffset, LowPcEndOffset;
+  uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
+  DWARFUnit &OrigUnit = Unit.getOrigUnit();
+  uint64_t LowPcOffset, LowPcEndOffset;
   std::tie(LowPcOffset, LowPcEndOffset) =
       getAttributeOffsets(Abbrev, *LowPcIdx, Offset, OrigUnit);
 
@@ -2471,22 +685,36 @@
 
   if (Options.Verbose) {
     DIDumpOptions DumpOpts;
-    DumpOpts.RecurseDepth = 0;
+    DumpOpts.ChildRecurseDepth = 0;
     DumpOpts.Verbose = Options.Verbose;
     DIE.dump(outs(), 8 /* Indent */, DumpOpts);
   }
 
+  if (DIE.getTag() == dwarf::DW_TAG_label) {
+    if (Unit.hasLabelAt(*LowPc))
+      return Flags;
+    // 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(OrigUnit.getUnitDIE().find(dwarf::DW_AT_high_pc))
+            .getValueOr(UINT64_MAX) <= LowPc)
+      return Flags;
+    Unit.addLabelLowPc(*LowPc, MyInfo.AddrAdjust);
+    return Flags | TF_Keep;
+  }
+
   Flags |= TF_Keep;
 
   Optional<uint64_t> HighPc = DIE.getHighPC(*LowPc);
   if (!HighPc) {
-    reportWarning("Function without high_pc. Range will be discarded.\n",
+    reportWarning("Function without high_pc. Range will be discarded.\n", DMO,
                   &DIE);
     return Flags;
   }
 
   // Replace the debug map range with a more accurate one.
-  Ranges[*LowPc] = std::make_pair(*HighPc, MyInfo.AddrAdjust);
+  Ranges[*LowPc] = DebugMapObjectRange(*HighPc, MyInfo.AddrAdjust);
   Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust);
   return Flags;
 }
@@ -2494,7 +722,8 @@
 /// Check if a DIE should be kept.
 /// \returns updated TraversalFlags.
 unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr,
-                                    const DWARFDie &DIE,
+                                    RangesTy &Ranges, const DWARFDie &DIE,
+                                    const DebugMapObject &DMO,
                                     CompileUnit &Unit,
                                     CompileUnit::DIEInfo &MyInfo,
                                     unsigned Flags) {
@@ -2503,7 +732,12 @@
   case dwarf::DW_TAG_variable:
     return shouldKeepVariableDIE(RelocMgr, DIE, Unit, MyInfo, Flags);
   case dwarf::DW_TAG_subprogram:
-    return shouldKeepSubprogramDIE(RelocMgr, DIE, Unit, MyInfo, Flags);
+  case dwarf::DW_TAG_label:
+    return shouldKeepSubprogramDIE(RelocMgr, Ranges, DIE, DMO, Unit, MyInfo,
+                                   Flags);
+  case dwarf::DW_TAG_base_type:
+    // DWARF Expressions may reference basic types, but scanning them
+    // is expensive. Basic types are tiny, so just keep all of them.
   case dwarf::DW_TAG_imported_module:
   case dwarf::DW_TAG_imported_declaration:
   case dwarf::DW_TAG_imported_unit:
@@ -2524,11 +758,10 @@
 /// back to lookForDIEsToKeep while adding TF_DependencyWalk to the
 /// TraversalFlags to inform it that it's not doing the primary DIE
 /// tree walk.
-void DwarfLinker::keepDIEAndDependencies(RelocationManager &RelocMgr,
-                                          const DWARFDie &Die,
-                                          CompileUnit::DIEInfo &MyInfo,
-                                          const DebugMapObject &DMO,
-                                          CompileUnit &CU, bool UseODR) {
+void DwarfLinker::keepDIEAndDependencies(
+    RelocationManager &RelocMgr, RangesTy &Ranges, const UnitListTy &Units,
+    const DWARFDie &Die, CompileUnit::DIEInfo &MyInfo,
+    const DebugMapObject &DMO, CompileUnit &CU, bool UseODR) {
   DWARFUnit &Unit = CU.getOrigUnit();
   MyInfo.Keep = true;
 
@@ -2541,7 +774,8 @@
   unsigned AncestorIdx = MyInfo.ParentIdx;
   while (!CU.getInfo(AncestorIdx).Keep) {
     unsigned ODRFlag = UseODR ? TF_ODR : 0;
-    lookForDIEsToKeep(RelocMgr, Unit.getDIEAtIndex(AncestorIdx), DMO, CU,
+    lookForDIEsToKeep(RelocMgr, Ranges, Units, Unit.getDIEAtIndex(AncestorIdx),
+                      DMO, CU,
                       TF_ParentWalk | TF_Keep | TF_DependencyWalk | ODRFlag);
     AncestorIdx = CU.getInfo(AncestorIdx).ParentIdx;
   }
@@ -2550,13 +784,13 @@
   // attributes as kept.
   DWARFDataExtractor Data = Unit.getDebugInfoExtractor();
   const auto *Abbrev = Die.getAbbreviationDeclarationPtr();
-  uint32_t Offset = Die.getOffset() + getULEB128Size(Abbrev->getCode());
+  uint64_t Offset = Die.getOffset() + getULEB128Size(Abbrev->getCode());
 
   // Mark all DIEs referenced through attributes as kept.
   for (const auto &AttrSpec : Abbrev->attributes()) {
     DWARFFormValue Val(AttrSpec.Form);
-
-    if (!Val.isFormClass(DWARFFormValue::FC_Reference)) {
+    if (!Val.isFormClass(DWARFFormValue::FC_Reference) ||
+        AttrSpec.Attr == dwarf::DW_AT_sibling) {
       DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
                                 Unit.getFormParams());
       continue;
@@ -2565,7 +799,7 @@
     Val.extractValue(Data, &Offset, Unit.getFormParams(), &Unit);
     CompileUnit *ReferencedCU;
     if (auto RefDie =
-            resolveDIEReference(*this, Units, Val, Unit, Die, ReferencedCU)) {
+            resolveDIEReference(*this, DMO, Units, Val, Die, ReferencedCU)) {
       uint32_t RefIdx = ReferencedCU->getOrigUnit().getDIEIndex(RefDie);
       CompileUnit::DIEInfo &Info = ReferencedCU->getInfo(RefIdx);
       bool IsModuleRef = Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset() &&
@@ -2590,7 +824,7 @@
         Info.Prune = false;
 
       unsigned ODRFlag = UseODR ? TF_ODR : 0;
-      lookForDIEsToKeep(RelocMgr, RefDie, DMO, *ReferencedCU,
+      lookForDIEsToKeep(RelocMgr, Ranges, Units, RefDie, DMO, *ReferencedCU,
                         TF_Keep | TF_DependencyWalk | ODRFlag);
 
       // The incomplete property is propagated if the current DIE is complete
@@ -2606,6 +840,50 @@
   }
 }
 
+namespace {
+/// This class represents an item in the work list. In addition to it's obvious
+/// purpose of representing the state associated with a particular run of the
+/// work loop, it also serves as a marker to indicate that we should run the
+/// "continuation" code.
+///
+/// Originally, the latter was lambda which allowed arbitrary code to be run.
+/// Because we always need to run the exact same code, it made more sense to
+/// use a boolean and repurpose the already existing DIE field.
+struct WorklistItem {
+  DWARFDie Die;
+  unsigned Flags;
+  bool IsContinuation;
+  CompileUnit::DIEInfo *ChildInfo = nullptr;
+
+  /// Construct a classic worklist item.
+  WorklistItem(DWARFDie Die, unsigned Flags)
+      : Die(Die), Flags(Flags), IsContinuation(false){};
+
+  /// Creates a continuation marker.
+  WorklistItem(DWARFDie Die) : Die(Die), IsContinuation(true){};
+};
+} // namespace
+
+// Helper that updates the completeness of the current DIE. It depends on the
+// fact that the incompletness of its children is already computed.
+static void updateIncompleteness(const DWARFDie &Die,
+                                 CompileUnit::DIEInfo &ChildInfo,
+                                 CompileUnit &CU) {
+  // Only propagate incomplete members.
+  if (Die.getTag() != dwarf::DW_TAG_structure_type &&
+      Die.getTag() != dwarf::DW_TAG_class_type)
+    return;
+
+  unsigned Idx = CU.getOrigUnit().getDIEIndex(Die);
+  CompileUnit::DIEInfo &MyInfo = CU.getInfo(Idx);
+
+  if (MyInfo.Incomplete)
+    return;
+
+  if (ChildInfo.Incomplete || ChildInfo.Prune)
+    MyInfo.Incomplete = true;
+}
+
 /// Recursively walk the \p DIE tree and look for DIEs to
 /// keep. Store that information in \p CU's DIEInfo.
 ///
@@ -2620,58 +898,83 @@
 /// traversal we are currently doing.
 ///
 /// The return value indicates whether the DIE is incomplete.
-bool DwarfLinker::lookForDIEsToKeep(RelocationManager &RelocMgr,
+void DwarfLinker::lookForDIEsToKeep(RelocationManager &RelocMgr,
+                                    RangesTy &Ranges, const UnitListTy &Units,
                                     const DWARFDie &Die,
                                     const DebugMapObject &DMO, CompileUnit &CU,
                                     unsigned Flags) {
-  unsigned Idx = CU.getOrigUnit().getDIEIndex(Die);
-  CompileUnit::DIEInfo &MyInfo = CU.getInfo(Idx);
-  bool AlreadyKept = MyInfo.Keep;
-  if (MyInfo.Prune)
-    return true;
+  // LIFO work list.
+  SmallVector<WorklistItem, 4> Worklist;
+  Worklist.emplace_back(Die, Flags);
+
+  while (!Worklist.empty()) {
+    WorklistItem Current = Worklist.back();
+    Worklist.pop_back();
+
+    if (Current.IsContinuation) {
+      updateIncompleteness(Current.Die, *Current.ChildInfo, CU);
+      continue;
+    }
+
+    unsigned Idx = CU.getOrigUnit().getDIEIndex(Current.Die);
+    CompileUnit::DIEInfo &MyInfo = CU.getInfo(Idx);
+
+    // At this point we are guaranteed to have a continuation marker before us
+    // in the worklist, except for the last DIE.
+    if (!Worklist.empty())
+      Worklist.back().ChildInfo = &MyInfo;
+
+    if (MyInfo.Prune)
+      continue;
+
+    // If the Keep flag is set, we are marking a required DIE's dependencies.
+    // If our target is already marked as kept, we're all set.
+    bool AlreadyKept = MyInfo.Keep;
+    if ((Current.Flags & TF_DependencyWalk) && AlreadyKept)
+      continue;
 
-  // If the Keep flag is set, we are marking a required DIE's
-  // dependencies. If our target is already marked as kept, we're all
-  // set.
-  if ((Flags & TF_DependencyWalk) && AlreadyKept)
-    return MyInfo.Incomplete;
+    // We must not call shouldKeepDIE while called from keepDIEAndDependencies,
+    // because it would screw up the relocation finding logic.
+    if (!(Current.Flags & TF_DependencyWalk))
+      Current.Flags = shouldKeepDIE(RelocMgr, Ranges, Current.Die, DMO, CU,
+                                    MyInfo, Current.Flags);
+
+    // If it is a newly kept DIE mark it as well as all its dependencies as
+    // kept.
+    if (!AlreadyKept && (Current.Flags & TF_Keep)) {
+      bool UseOdr = (Current.Flags & TF_DependencyWalk)
+                        ? (Current.Flags & TF_ODR)
+                        : CU.hasODR();
+      keepDIEAndDependencies(RelocMgr, Ranges, Units, Current.Die, MyInfo, DMO,
+                             CU, UseOdr);
+    }
 
-  // We must not call shouldKeepDIE while called from keepDIEAndDependencies,
-  // because it would screw up the relocation finding logic.
-  if (!(Flags & TF_DependencyWalk))
-    Flags = shouldKeepDIE(RelocMgr, Die, CU, MyInfo, Flags);
+    // The TF_ParentWalk flag tells us that we are currently walking up
+    // the parent chain of a required DIE, and we don't want to mark all
+    // the children of the parents as kept (consider for example a
+    // DW_TAG_namespace node in 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(Current.Die.getTag()))
+      Current.Flags &= ~TF_ParentWalk;
 
-  // If it is a newly kept DIE mark it as well as all its dependencies as kept.
-  if (!AlreadyKept && (Flags & TF_Keep)) {
-    bool UseOdr = (Flags & TF_DependencyWalk) ? (Flags & TF_ODR) : CU.hasODR();
-    keepDIEAndDependencies(RelocMgr, Die, MyInfo, DMO, CU, UseOdr);
+    if (!Current.Die.hasChildren() || (Current.Flags & TF_ParentWalk))
+      continue;
+
+    // Add children in reverse order to the worklist to effectively process
+    // them in order.
+    for (auto Child : reverse(Current.Die.children())) {
+      // Add continuation marker before every child to calculate incompleteness
+      // after the last child is processed. We can't store this information in
+      // the same item because we might have to process other continuations
+      // first.
+      Worklist.emplace_back(Current.Die);
+      Worklist.emplace_back(Child, Current.Flags);
+    }
   }
-  // The TF_ParentWalk flag tells us that we are currently walking up
-  // the parent chain of a required DIE, and we don't want to mark all
-  // the children of the parents as kept (consider for example a
-  // DW_TAG_namespace node in 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 &= ~TF_ParentWalk;
-
-  if (!Die.hasChildren() || (Flags & TF_ParentWalk))
-    return MyInfo.Incomplete;
-
-  bool Incomplete = false;
-  for (auto Child : Die.children()) {
-    Incomplete |= lookForDIEsToKeep(RelocMgr, Child, DMO, CU, Flags);
-
-    // If any of the members are incomplete we propagate the incompleteness.
-    if (!MyInfo.Incomplete && Incomplete &&
-        (Die.getTag() == dwarf::DW_TAG_structure_type ||
-         Die.getTag() == dwarf::DW_TAG_class_type))
-      MyInfo.Incomplete = true;
-  }
-  return MyInfo.Incomplete;
 }
 
-/// Assign an abbreviation numer to \p Abbrev.
+/// Assign an abbreviation number to \p Abbrev.
 ///
 /// Our DIEs get freed after every DebugMapObject has been processed,
 /// thus the FoldingSet we use to unique DIEAbbrevs cannot refer to
@@ -2701,39 +1004,41 @@
   }
 }
 
-unsigned DwarfLinker::DIECloner::cloneStringAttribute(DIE &Die,
-                                                      AttributeSpec AttrSpec,
-                                                      const DWARFFormValue &Val,
-                                                      const DWARFUnit &U,
-                                                      AttributesInfo &Info) {
+unsigned DwarfLinker::DIECloner::cloneStringAttribute(
+    DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
+    const DWARFUnit &U, OffsetsStringPool &StringPool, AttributesInfo &Info) {
   // Switch everything to out of line strings.
   const char *String = *Val.getAsCString();
-  auto StringEntry = Linker.StringPool.getEntry(String);
+  auto StringEntry = StringPool.getEntry(String);
+
+  // Update attributes info.
   if (AttrSpec.Attr == dwarf::DW_AT_name)
     Info.Name = StringEntry;
   else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name ||
            AttrSpec.Attr == dwarf::DW_AT_linkage_name)
     Info.MangledName = StringEntry;
+
   Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_strp,
                DIEInteger(StringEntry.getOffset()));
+
   return 4;
 }
 
 unsigned DwarfLinker::DIECloner::cloneDieReferenceAttribute(
-    DIE &Die, const DWARFDie &InputDIE,
-    AttributeSpec AttrSpec, unsigned AttrSize, const DWARFFormValue &Val,
+    DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec,
+    unsigned AttrSize, const DWARFFormValue &Val, const DebugMapObject &DMO,
     CompileUnit &Unit) {
   const DWARFUnit &U = Unit.getOrigUnit();
-  uint32_t Ref = *Val.getAsReference();
+  uint64_t Ref = *Val.getAsReference();
   DIE *NewRefDie = nullptr;
   CompileUnit *RefUnit = nullptr;
   DeclContext *Ctxt = nullptr;
 
-  DWARFDie RefDie = resolveDIEReference(Linker, CompileUnits, Val, U, InputDIE,
-                                        RefUnit);
+  DWARFDie RefDie =
+      resolveDIEReference(Linker, DMO, CompileUnits, Val, InputDIE, RefUnit);
 
   // If the referenced DIE is not found,  drop the attribute.
-  if (!RefDie)
+  if (!RefDie || AttrSpec.Attr == dwarf::DW_AT_sibling)
     return 0;
 
   unsigned Idx = RefUnit->getOrigUnit().getDIEIndex(RefDie);
@@ -2790,15 +1095,74 @@
   return AttrSize;
 }
 
-unsigned DwarfLinker::DIECloner::cloneBlockAttribute(DIE &Die,
-                                                     AttributeSpec AttrSpec,
-                                                     const DWARFFormValue &Val,
-                                                     unsigned AttrSize) {
+void DwarfLinker::DIECloner::cloneExpression(
+    DataExtractor &Data, DWARFExpression Expression, const DebugMapObject &DMO,
+    CompileUnit &Unit, SmallVectorImpl<uint8_t> &OutputBuffer) {
+  using Encoding = DWARFExpression::Operation::Encoding;
+
+  uint64_t OpOffset = 0;
+  for (auto &Op : Expression) {
+    auto Description = Op.getDescription();
+    // DW_OP_const_type is variable-length and has 3
+    // operands. DWARFExpression thus far only supports 2.
+    auto Op0 = Description.Op[0];
+    auto Op1 = Description.Op[1];
+    if ((Op0 == Encoding::BaseTypeRef && Op1 != Encoding::SizeNA) ||
+        (Op1 == Encoding::BaseTypeRef && Op0 != Encoding::Size1))
+      Linker.reportWarning("Unsupported DW_OP encoding.", DMO);
+
+    if ((Op0 == Encoding::BaseTypeRef && Op1 == Encoding::SizeNA) ||
+        (Op1 == Encoding::BaseTypeRef && Op0 == 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.
+      OutputBuffer.push_back(Op.getCode());
+      uint64_t RefOffset;
+      if (Op1 == Encoding::SizeNA) {
+        RefOffset = Op.getRawOperand(0);
+      } else {
+        OutputBuffer.push_back(Op.getRawOperand(0));
+        RefOffset = Op.getRawOperand(1);
+      }
+      auto RefDie = Unit.getOrigUnit().getDIEForOffset(RefOffset);
+      uint32_t RefIdx = Unit.getOrigUnit().getDIEIndex(RefDie);
+      CompileUnit::DIEInfo &Info = Unit.getInfo(RefIdx);
+      uint32_t Offset = 0;
+      if (DIE *Clone = Info.Clone)
+        Offset = Clone->getOffset();
+      else
+        Linker.reportWarning("base type ref doesn't point to DW_TAG_base_type.",
+                             DMO);
+      uint8_t ULEB[16];
+      unsigned RealSize = encodeULEB128(Offset, ULEB, ULEBsize);
+      if (RealSize > ULEBsize) {
+        // Emit the generic type as a fallback.
+        RealSize = encodeULEB128(0, ULEB, ULEBsize);
+        Linker.reportWarning("base type ref doesn't fit.", DMO);
+      }
+      assert(RealSize == ULEBsize && "padding failed");
+      ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
+      OutputBuffer.append(ULEBbytes.begin(), ULEBbytes.end());
+    } else {
+      // Copy over everything else unmodified.
+      StringRef Bytes = Data.getData().slice(OpOffset, Op.getEndOffset());
+      OutputBuffer.append(Bytes.begin(), Bytes.end());
+    }
+    OpOffset = Op.getEndOffset();
+  }
+}
+
+unsigned DwarfLinker::DIECloner::cloneBlockAttribute(
+    DIE &Die, const DebugMapObject &DMO, CompileUnit &Unit,
+    AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize,
+    bool IsLittleEndian) {
   DIEValueList *Attr;
   DIEValue Value;
   DIELoc *Loc = nullptr;
   DIEBlock *Block = nullptr;
-  // Just copy the block data over.
   if (AttrSpec.Form == dwarf::DW_FORM_exprloc) {
     Loc = new (DIEAlloc) DIELoc;
     Linker.DIELocs.push_back(Loc);
@@ -2815,10 +1179,26 @@
   else
     Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
                      dwarf::Form(AttrSpec.Form), Block);
+
+  // If the block is a DWARF Expression, clone it into the temporary
+  // buffer using cloneExpression(), otherwise copy the data directly.
+  SmallVector<uint8_t, 32> Buffer;
   ArrayRef<uint8_t> Bytes = *Val.getAsBlock();
+  if (DWARFAttribute::mayHaveLocationDescription(AttrSpec.Attr) &&
+      (Val.isFormClass(DWARFFormValue::FC_Block) ||
+       Val.isFormClass(DWARFFormValue::FC_Exprloc))) {
+    DWARFUnit &OrigUnit = Unit.getOrigUnit();
+    DataExtractor Data(StringRef((const char *)Bytes.data(), Bytes.size()),
+                       IsLittleEndian, OrigUnit.getAddressByteSize());
+    DWARFExpression Expr(Data, OrigUnit.getVersion(),
+                         OrigUnit.getAddressByteSize());
+    cloneExpression(Data, Expr, DMO, Unit, Buffer);
+    Bytes = Buffer;
+  }
   for (auto Byte : Bytes)
     Attr->addValue(DIEAlloc, static_cast<dwarf::Attribute>(0),
                    dwarf::DW_FORM_data1, DIEInteger(Byte));
+
   // FIXME: If DIEBlock and DIELoc just reuses the Size field of
   // the DIE class, this if could be replaced by
   // Attr->setSize(Bytes.size()).
@@ -2882,9 +1262,9 @@
 }
 
 unsigned DwarfLinker::DIECloner::cloneScalarAttribute(
-    DIE &Die, const DWARFDie &InputDIE, CompileUnit &Unit,
-    AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize,
-    AttributesInfo &Info) {
+    DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO,
+    CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val,
+    unsigned AttrSize, AttributesInfo &Info) {
   uint64_t Value;
 
   if (LLVM_UNLIKELY(Linker.Options.Update)) {
@@ -2896,7 +1276,8 @@
       Value = *OptionalValue;
     else {
       Linker.reportWarning(
-          "Unsupported scalar attribute form. Dropping attribute.", &InputDIE);
+          "Unsupported scalar attribute form. Dropping attribute.", DMO,
+          &InputDIE);
       return 0;
     }
     if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
@@ -2920,7 +1301,7 @@
     Value = *OptionalValue;
   else {
     Linker.reportWarning(
-        "Unsupported scalar attribute form. Dropping attribute.",
+        "Unsupported scalar attribute form. Dropping attribute.", DMO,
         &InputDIE);
     return 0;
   }
@@ -2935,8 +1316,9 @@
   // A more generic way to check for location attributes would be
   // nice, but it's very unlikely that any other attribute needs a
   // 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;
@@ -2948,28 +1330,30 @@
 /// value \p Val, and add it to \p Die.
 /// \returns the size of the cloned attribute.
 unsigned DwarfLinker::DIECloner::cloneAttribute(
-    DIE &Die, const DWARFDie &InputDIE, CompileUnit &Unit,
-    const DWARFFormValue &Val, const AttributeSpec AttrSpec, unsigned AttrSize,
-    AttributesInfo &Info) {
+    DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO,
+    CompileUnit &Unit, OffsetsStringPool &StringPool, const DWARFFormValue &Val,
+    const AttributeSpec AttrSpec, unsigned AttrSize, AttributesInfo &Info,
+    bool IsLittleEndian) {
   const DWARFUnit &U = Unit.getOrigUnit();
 
   switch (AttrSpec.Form) {
   case dwarf::DW_FORM_strp:
   case dwarf::DW_FORM_string:
-    return cloneStringAttribute(Die, AttrSpec, Val, U, Info);
+    return cloneStringAttribute(Die, AttrSpec, Val, U, StringPool, Info);
   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:
     return cloneDieReferenceAttribute(Die, InputDIE, AttrSpec, AttrSize, Val,
-                                      Unit);
+                                      DMO, Unit);
   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:
-    return cloneBlockAttribute(Die, AttrSpec, Val, AttrSize);
+    return cloneBlockAttribute(Die, DMO, Unit, AttrSpec, Val, AttrSize,
+                               IsLittleEndian);
   case dwarf::DW_FORM_addr:
     return cloneAddressAttribute(Die, AttrSpec, Val, Unit, Info);
   case dwarf::DW_FORM_data1:
@@ -2981,11 +1365,12 @@
   case dwarf::DW_FORM_sec_offset:
   case dwarf::DW_FORM_flag:
   case dwarf::DW_FORM_flag_present:
-    return cloneScalarAttribute(Die, InputDIE, Unit, AttrSpec, Val, AttrSize,
-                                Info);
+    return cloneScalarAttribute(Die, InputDIE, DMO, Unit, AttrSpec, Val,
+                                AttrSize, Info);
   default:
     Linker.reportWarning(
-        "Unsupported attribute form in cloneAttribute. Dropping.", &InputDIE);
+        "Unsupported attribute form in cloneAttribute. Dropping.", DMO,
+        &InputDIE);
   }
 
   return 0;
@@ -2998,10 +1383,9 @@
 /// Like for findValidRelocs(), this function must be called with
 /// monotonic \p BaseOffset values.
 ///
-/// \returns wether any reloc has been applied.
-bool DwarfLinker::RelocationManager::
-applyValidRelocs(MutableArrayRef<char> Data, uint32_t BaseOffset,
-                 bool isLittleEndian) {
+/// \returns whether any reloc has been applied.
+bool DwarfLinker::RelocationManager::applyValidRelocs(
+    MutableArrayRef<char> Data, uint64_t BaseOffset, bool IsLittleEndian) {
   assert((NextValidReloc == 0 ||
           BaseOffset > ValidRelocs[NextValidReloc - 1].Offset) &&
          "BaseOffset should only be increasing.");
@@ -3025,7 +1409,7 @@
     uint64_t Value = ValidReloc.Mapping->getValue().BinaryAddress;
     Value += ValidReloc.Addend;
     for (unsigned i = 0; i != ValidReloc.Size; ++i) {
-      unsigned Index = isLittleEndian ? i : (ValidReloc.Size - i - 1);
+      unsigned Index = IsLittleEndian ? i : (ValidReloc.Size - i - 1);
       Buf[i] = uint8_t(Value >> (Index * 8));
     }
     assert(ValidReloc.Size <= sizeof(Buf));
@@ -3036,40 +1420,6 @@
   return Applied;
 }
 
-static bool isTypeTag(uint16_t Tag) {
-  switch (Tag) {
-  case dwarf::DW_TAG_array_type:
-  case dwarf::DW_TAG_class_type:
-  case dwarf::DW_TAG_enumeration_type:
-  case dwarf::DW_TAG_pointer_type:
-  case dwarf::DW_TAG_reference_type:
-  case dwarf::DW_TAG_string_type:
-  case dwarf::DW_TAG_structure_type:
-  case dwarf::DW_TAG_subroutine_type:
-  case dwarf::DW_TAG_typedef:
-  case dwarf::DW_TAG_union_type:
-  case dwarf::DW_TAG_ptr_to_member_type:
-  case dwarf::DW_TAG_set_type:
-  case dwarf::DW_TAG_subrange_type:
-  case dwarf::DW_TAG_base_type:
-  case dwarf::DW_TAG_const_type:
-  case dwarf::DW_TAG_constant:
-  case dwarf::DW_TAG_file_type:
-  case dwarf::DW_TAG_namelist:
-  case dwarf::DW_TAG_packed_type:
-  case dwarf::DW_TAG_volatile_type:
-  case dwarf::DW_TAG_restrict_type:
-  case dwarf::DW_TAG_atomic_type:
-  case dwarf::DW_TAG_interface_type:
-  case dwarf::DW_TAG_unspecified_type:
-  case dwarf::DW_TAG_shared_type:
-    return true;
-  default:
-    break;
-  }
-  return false;
-}
-
 static bool isObjCSelector(StringRef Name) {
   return Name.size() > 2 && (Name[0] == '-' || Name[0] == '+') &&
          (Name[1] == '[');
@@ -3078,6 +1428,7 @@
 void DwarfLinker::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.
@@ -3092,28 +1443,25 @@
     return;
 
   StringRef Selector(SelectorStart.data(), SelectorStart.size() - 1);
-  Unit.addNameAccelerator(Die, Linker.StringPool.getEntry(Selector),
-                          SkipPubSection);
+  Unit.addNameAccelerator(Die, StringPool.getEntry(Selector), SkipPubSection);
 
   // Add an entry for the class name that points to this
   // method/class function.
   StringRef ClassName(ClassNameStart.data(), FirstSpace);
-  Unit.addObjCAccelerator(Die, Linker.StringPool.getEntry(ClassName),
-                          SkipPubSection);
+  Unit.addObjCAccelerator(Die, StringPool.getEntry(ClassName), SkipPubSection);
 
   if (ClassName[ClassName.size() - 1] == ')') {
     size_t OpenParens = ClassName.find('(');
     if (OpenParens != StringRef::npos) {
       StringRef ClassNameNoCategory(ClassName.data(), OpenParens);
-      Unit.addObjCAccelerator(
-          Die, Linker.StringPool.getEntry(ClassNameNoCategory), SkipPubSection);
+      Unit.addObjCAccelerator(Die, StringPool.getEntry(ClassNameNoCategory),
+                              SkipPubSection);
 
       std::string MethodNameNoCategory(Name.getString().data(), OpenParens + 2);
       // FIXME: The missing space here may be a bug, but
       //        dsymutil-classic also does it this way.
       MethodNameNoCategory.append(SelectorStart);
-      Unit.addNameAccelerator(Die,
-                              Linker.StringPool.getEntry(MethodNameNoCategory),
+      Unit.addNameAccelerator(Die, StringPool.getEntry(MethodNameNoCategory),
                               SkipPubSection);
     }
   }
@@ -3132,11 +1480,11 @@
     return SkipPC;
   case dwarf::DW_AT_location:
   case dwarf::DW_AT_frame_base:
-    // FIXME: for some reason dsymutil-classic keeps the location
-    // attributes when they are of block type (ie. not location
-    // lists). This is totally wrong for globals where we will keep a
-    // wrong address. It is mostly harmless for locals, but there is
-    // no point in keeping these anyway when the function wasn't linked.
+    // FIXME: for some reason dsymutil-classic keeps the location attributes
+    // when they are of block type (i.e. not location lists). This is totally
+    // wrong for globals where we will keep a wrong address. It is mostly
+    // harmless for locals, but there is no point in keeping these anyway when
+    // the function wasn't linked.
     return (SkipPC || (!InFunctionScope && Tag == dwarf::DW_TAG_variable &&
                        !InDebugMap)) &&
            !DWARFFormValue(AttrSpec.Form).isFormClass(DWARFFormValue::FC_Block);
@@ -3144,8 +1492,9 @@
 }
 
 DIE *DwarfLinker::DIECloner::cloneDIE(
-    const DWARFDie &InputDIE, CompileUnit &Unit,
-    int64_t PCOffset, uint32_t OutOffset, unsigned Flags, DIE *Die) {
+    const DWARFDie &InputDIE, const DebugMapObject &DMO, CompileUnit &Unit,
+    OffsetsStringPool &StringPool, int64_t PCOffset, uint32_t OutOffset,
+    unsigned Flags, bool IsLittleEndian, DIE *Die) {
   DWARFUnit &U = Unit.getOrigUnit();
   unsigned Idx = U.getDIEIndex(InputDIE);
   CompileUnit::DIEInfo &Info = Unit.getInfo(Idx);
@@ -3154,7 +1503,7 @@
   if (!Unit.getInfo(Idx).Keep)
     return nullptr;
 
-  uint32_t Offset = InputDIE.getOffset();
+  uint64_t Offset = InputDIE.getOffset();
   assert(!(Die && Info.Clone) && "Can't supply a DIE and a cloned DIE");
   if (!Die) {
     // The DIE might have been already created by a forward reference
@@ -3181,15 +1530,14 @@
   // 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.
-  uint32_t NextOffset =
-    (Idx + 1 < U.getNumDIEs())
-    ? U.getDIEAtIndex(Idx + 1).getOffset()
-    : U.getNextUnitOffset();
+  uint64_t NextOffset = (Idx + 1 < U.getNumDIEs())
+                            ? U.getDIEAtIndex(Idx + 1).getOffset()
+                            : U.getNextUnitOffset();
   AttributesInfo AttrInfo;
 
-  // We could copy the data only if we need to aply a relocation to
-  // it. After testing, it seems there is no performance downside to
-  // doing the copy unconditionally, and it makes the code simpler.
+  // 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());
@@ -3200,7 +1548,7 @@
     // (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
-    // independantly by the linker). The computation of the actual
+    // independently by the linker). The computation of the actual
     // high_pc value is done in cloneAddressAttribute().
     AttrInfo.OrigHighPc =
         dwarf::toAddress(InputDIE.find(dwarf::DW_AT_high_pc), 0);
@@ -3247,12 +1595,12 @@
     }
 
     DWARFFormValue Val(AttrSpec.Form);
-    uint32_t AttrSize = Offset;
+    uint64_t AttrSize = Offset;
     Val.extractValue(Data, &Offset, U.getFormParams(), &U);
     AttrSize = Offset - AttrSize;
 
-    OutOffset +=
-        cloneAttribute(*Die, InputDIE, Unit, Val, AttrSpec, AttrSize, AttrInfo);
+    OutOffset += cloneAttribute(*Die, InputDIE, DMO, Unit, StringPool, Val,
+                                AttrSpec, AttrSize, AttrInfo, IsLittleEndian);
   }
 
   // Look for accelerator entries.
@@ -3262,7 +1610,7 @@
   // accelerator tables too. For now stick with dsymutil's behavior.
   if ((Info.InDebugMap || AttrInfo.HasLowPc || AttrInfo.HasRanges) &&
       Tag != dwarf::DW_TAG_compile_unit &&
-      getDIENames(InputDIE, AttrInfo,
+      getDIENames(InputDIE, AttrInfo, StringPool,
                   Tag != dwarf::DW_TAG_inlined_subroutine)) {
     if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name)
       Unit.addNameAccelerator(Die, AttrInfo.MangledName,
@@ -3275,16 +1623,17 @@
                               Tag == dwarf::DW_TAG_inlined_subroutine);
     }
     if (AttrInfo.Name && isObjCSelector(AttrInfo.Name.getString()))
-      addObjCAccelerator(Unit, Die, AttrInfo.Name, /* SkipPubSection =*/true);
+      addObjCAccelerator(Unit, Die, AttrInfo.Name, StringPool,
+                         /* SkipPubSection =*/true);
 
   } else if (Tag == dwarf::DW_TAG_namespace) {
     if (!AttrInfo.Name)
-      AttrInfo.Name = Linker.StringPool.getEntry("(anonymous namespace)");
+      AttrInfo.Name = StringPool.getEntry("(anonymous namespace)");
     Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
   } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration &&
-             getDIENames(InputDIE, AttrInfo) && AttrInfo.Name &&
+             getDIENames(InputDIE, AttrInfo, StringPool) && AttrInfo.Name &&
              AttrInfo.Name.getString()[0]) {
-    uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit);
+    uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, DMO);
     uint64_t RuntimeLang =
         dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
             .getValueOr(0);
@@ -3324,8 +1673,9 @@
   }
 
   // Recursively clone children.
-  for (auto Child: InputDIE.children()) {
-    if (DIE *Clone = cloneDIE(Child, Unit, PCOffset, OutOffset, Flags)) {
+  for (auto Child : InputDIE.children()) {
+    if (DIE *Clone = cloneDIE(Child, DMO, Unit, StringPool, PCOffset, OutOffset,
+                              Flags, IsLittleEndian)) {
       Die->addChild(Clone);
       OutOffset = Clone->getOffset() + Clone->getSize();
     }
@@ -3342,12 +1692,13 @@
 /// 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 {
+                                     DWARFContext &OrigDwarf,
+                                     const DebugMapObject &DMO) const {
   DWARFDebugRangeList RangeList;
   const auto &FunctionRanges = Unit.getFunctionRanges();
   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
   DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(),
-                                    OrigDwarf.getDWARFObj().getRangeSection(),
+                                    OrigDwarf.getDWARFObj().getRangesSection(),
                                     OrigDwarf.isLittleEndian(), AddressSize);
   auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
   DWARFUnit &OrigUnit = Unit.getOrigUnit();
@@ -3361,9 +1712,13 @@
     UnitPcOffset = int64_t(OrigLowPc) - Unit.getLowPc();
 
   for (const auto &RangeAttribute : Unit.getRangesAttributes()) {
-    uint32_t Offset = RangeAttribute.get();
+    uint64_t Offset = RangeAttribute.get();
     RangeAttribute.set(Streamer->getRangesSectionSize());
-    RangeList.extract(RangeExtractor, &Offset);
+    if (Error E = RangeList.extract(RangeExtractor, &Offset)) {
+      llvm::consumeError(std::move(E));
+      reportWarning("invalid range list ignored.", DMO);
+      RangeList.clear();
+    }
     const auto &Entries = RangeList.getEntries();
     if (!Entries.empty()) {
       const DWARFDebugRangeList::RangeListEntry &First = Entries.front();
@@ -3374,7 +1729,7 @@
         CurrRange = FunctionRanges.find(First.StartAddress + OrigLowPc);
         if (CurrRange == InvalidRange ||
             CurrRange.start() > First.StartAddress + OrigLowPc) {
-          reportWarning("no mapping for range.");
+          reportWarning("no mapping for range.", DMO);
           continue;
         }
       }
@@ -3411,18 +1766,16 @@
     return;
   }
 
-  auto InsertPoint = std::lower_bound(
-      Rows.begin(), Rows.end(), Seq.front(),
-      [](const DWARFDebugLine::Row &LHS, const DWARFDebugLine::Row &RHS) {
-        return LHS.Address < RHS.Address;
-      });
+  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
+  // sequences have been inserted in order. Using a global sort like
   // described in patchLineTableForUnit() and delaying the end_sequene
   // elimination to emitLineTableForUnit() we can get rid of all of them.
-  if (InsertPoint != Rows.end() &&
-      InsertPoint->Address == Seq.front().Address && InsertPoint->EndSequence) {
+  if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
+      InsertPoint->EndSequence) {
     *InsertPoint = Seq.front();
     Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
   } else {
@@ -3446,7 +1799,9 @@
 /// recreate a relocated version of these for the address ranges that
 /// are present in the binary.
 void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
-                                        DWARFContext &OrigDwarf) {
+                                        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)
@@ -3458,11 +1813,16 @@
 
   // Parse the original line info for the unit.
   DWARFDebugLine::LineTable LineTable;
-  uint32_t StmtOffset = *StmtList;
+  uint64_t StmtOffset = *StmtList;
   DWARFDataExtractor LineExtractor(
       OrigDwarf.getDWARFObj(), OrigDwarf.getDWARFObj().getLineSection(),
       OrigDwarf.isLittleEndian(), Unit.getOrigUnit().getAddressByteSize());
-  LineTable.parse(LineExtractor, &StmtOffset, OrigDwarf, &Unit.getOrigUnit());
+  if (Options.Translator)
+    return Streamer->translateLineTable(LineExtractor, StmtOffset);
+
+  Error Err = LineTable.parse(LineExtractor, &StmtOffset, OrigDwarf,
+                              &Unit.getOrigUnit(), DWARFContext::dumpWarning);
+  DWARFContext::dumpWarning(std::move(Err));
 
   // This vector is the output line table.
   std::vector<DWARFDebugLine::Row> NewRows;
@@ -3475,7 +1835,7 @@
   auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
 
   // FIXME: This logic is meant to generate exactly the same output as
-  // Darwin's classic dsynutil. There is a nicer way to implement this
+  // 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
@@ -3486,22 +1846,22 @@
   // Iterate over the object file line info and extract the sequences
   // that correspond to linked functions.
   for (auto &Row : LineTable.Rows) {
-    // Check wether we stepped out of the range. The range is
+    // 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 == InvalidRange || Row.Address < CurrRange.start() ||
-        Row.Address > CurrRange.stop() ||
-        (Row.Address == CurrRange.stop() && !Row.EndSequence)) {
+    if (CurrRange == InvalidRange || Row.Address.Address < CurrRange.start() ||
+        Row.Address.Address > CurrRange.stop() ||
+        (Row.Address.Address == CurrRange.stop() && !Row.EndSequence)) {
       // We just stepped out of a known range. Insert a end_sequence
       // corresponding to the end of the range.
       uint64_t StopAddress = CurrRange != InvalidRange
                                  ? CurrRange.stop() + CurrRange.value()
                                  : -1ULL;
-      CurrRange = FunctionRanges.find(Row.Address);
+      CurrRange = FunctionRanges.find(Row.Address.Address);
       bool CurrRangeValid =
-          CurrRange != InvalidRange && CurrRange.start() <= Row.Address;
+          CurrRange != InvalidRange && CurrRange.start() <= Row.Address.Address;
       if (!CurrRangeValid) {
         CurrRange = InvalidRange;
         if (StopAddress != -1ULL) {
@@ -3511,13 +1871,13 @@
           // for now do as dsymutil.
           // FIXME: Understand exactly what cases this addresses and
           // potentially remove it along with the Ranges map.
-          auto Range = Ranges.lower_bound(Row.Address);
+          auto Range = Ranges.lower_bound(Row.Address.Address);
           if (Range != Ranges.begin() && Range != Ranges.end())
             --Range;
 
-          if (Range != Ranges.end() && Range->first <= Row.Address &&
-              Range->second.first >= Row.Address) {
-            StopAddress = Row.Address + Range->second.second;
+          if (Range != Ranges.end() && Range->first <= Row.Address.Address &&
+              Range->second.HighPC >= Row.Address.Address) {
+            StopAddress = Row.Address.Address + Range->second.Offset;
           }
         }
       }
@@ -3525,7 +1885,7 @@
         // Insert end sequence row with the computed end address, but
         // the same line as the previous one.
         auto NextLine = Seq.back();
-        NextLine.Address = StopAddress;
+        NextLine.Address.Address = StopAddress;
         NextLine.EndSequence = 1;
         NextLine.PrologueEnd = 0;
         NextLine.BasicBlock = 0;
@@ -3543,7 +1903,7 @@
       continue;
 
     // Relocate row address and add it to the current sequence.
-    Row.Address += CurrRange.value();
+    Row.Address.Address += CurrRange.value();
     Seq.emplace_back(Row);
 
     if (Row.EndSequence)
@@ -3551,7 +1911,7 @@
   }
 
   // Finished extracting, now emit the line tables.
-  // FIXME: LLVM hardcodes its prologue values. We just copy the
+  // FIXME: LLVM hard-codes its prologue values. We just copy the
   // prologue over and that works because we act as both producer and
   // consumer. It would be nicer to have a real configurable line
   // table emitter.
@@ -3559,7 +1919,7 @@
       LineTable.Prologue.getVersion() > 5 ||
       LineTable.Prologue.DefaultIsStmt != DWARF2_LINE_DEFAULT_IS_STMT ||
       LineTable.Prologue.OpcodeBase > 13)
-    reportWarning("line table parameters mismatch. Cannot emit.");
+    reportWarning("line table parameters mismatch. Cannot emit.", DMO);
   else {
     uint32_t PrologueEnd = *StmtList + 10 + LineTable.Prologue.PrologueLength;
     // DWARF v5 has an extra 2 bytes of information before the header_length
@@ -3579,6 +1939,20 @@
 }
 
 void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
+  switch (Options.TheAccelTableKind) {
+  case AccelTableKind::Apple:
+    emitAppleAcceleratorEntriesForUnit(Unit);
+    break;
+  case AccelTableKind::Dwarf:
+    emitDwarfAcceleratorEntriesForUnit(Unit);
+    break;
+  case AccelTableKind::Default:
+    llvm_unreachable("The default must be updated to a concrete value.");
+    break;
+  }
+}
+
+void DwarfLinker::emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit) {
   // Add namespaces.
   for (const auto &Namespace : Unit.getNamespaces())
     AppleNamespaces.addName(Namespace.Name,
@@ -3607,6 +1981,18 @@
     AppleObjc.addName(ObjC.Name, ObjC.Die->getOffset() + Unit.getStartOffset());
 }
 
+void DwarfLinker::emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit) {
+  for (const auto &Namespace : Unit.getNamespaces())
+    DebugNames.addName(Namespace.Name, Namespace.Die->getOffset(),
+                       Namespace.Die->getTag(), Unit.getUniqueID());
+  for (const auto &Pubname : Unit.getPubnames())
+    DebugNames.addName(Pubname.Name, Pubname.Die->getOffset(),
+                       Pubname.Die->getTag(), Unit.getUniqueID());
+  for (const auto &Pubtype : Unit.getPubtypes())
+    DebugNames.addName(Pubtype.Name, Pubtype.Die->getOffset(),
+                       Pubtype.Die->getTag(), Unit.getUniqueID());
+}
+
 /// Read the frame info stored in the object, and emit the
 /// patched frame descriptions for the linked binary.
 ///
@@ -3614,24 +2000,25 @@
 /// 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) {
-  StringRef FrameData = OrigDwarf.getDWARFObj().getDebugFrameSection();
+  StringRef FrameData = OrigDwarf.getDWARFObj().getFrameSection().Data;
   if (FrameData.empty())
     return;
 
   DataExtractor Data(FrameData, OrigDwarf.isLittleEndian(), 0);
-  uint32_t InputOffset = 0;
+  uint64_t InputOffset = 0;
 
   // Store the data of the CIEs defined in this object, keyed by their
   // offsets.
-  DenseMap<uint32_t, StringRef> LocalCIES;
+  DenseMap<uint64_t, StringRef> LocalCIES;
 
   while (Data.isValidOffset(InputOffset)) {
-    uint32_t EntryOffset = InputOffset;
+    uint64_t EntryOffset = InputOffset;
     uint32_t InitialLength = Data.getU32(&InputOffset);
     if (InitialLength == 0xFFFFFFFF)
-      return reportWarning("Dwarf64 bits no supported");
+      return reportWarning("Dwarf64 bits no supported", DMO);
 
     uint32_t CIEId = Data.getU32(&InputOffset);
     if (CIEId == 0xFFFFFFFF) {
@@ -3653,7 +2040,7 @@
     if (Range != Ranges.begin())
       --Range;
     if (Range == Ranges.end() || Range->first > Loc ||
-        Range->second.first <= Loc) {
+        Range->second.HighPC <= Loc) {
       // The +4 is to account for the size of the InitialLength field itself.
       InputOffset = EntryOffset + InitialLength + 4;
       continue;
@@ -3663,7 +2050,7 @@
     // Have we already emitted a corresponding CIE?
     StringRef CIEData = LocalCIES[CIEId];
     if (CIEData.empty())
-      return reportWarning("Inconsistent debug_frame content. Dropping.");
+      return reportWarning("Inconsistent debug_frame content. Dropping.", DMO);
 
     // Look if we already emitted a CIE that corresponds to the
     // referenced one (the CIE data is the key of that lookup).
@@ -3686,7 +2073,7 @@
     // fields that will get reconstructed by emitFDE().
     unsigned FDERemainingBytes = InitialLength - (4 + AddrSize);
     Streamer->emitFDE(IteratorInserted.first->getValue(), AddrSize,
-                      Loc + Range->second.second,
+                      Loc + Range->second.Offset,
                       FrameData.substr(InputOffset, FDERemainingBytes));
     InputOffset += FDERemainingBytes;
   }
@@ -3707,9 +2094,10 @@
   Linker.AssignAbbrev(Copy);
 }
 
-uint32_t DwarfLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE,
-                                                        CompileUnit &U,
-                                                        int RecurseDepth) {
+uint32_t
+DwarfLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
+                                               const DebugMapObject &DMO,
+                                               int ChildRecurseDepth) {
   const char *Name = nullptr;
   DWARFUnit *OrigUnit = &U.getOrigUnit();
   CompileUnit *CU = &U;
@@ -3727,8 +2115,8 @@
       break;
 
     CompileUnit *RefCU;
-    if (auto RefDIE = resolveDIEReference(Linker, CompileUnits, *Ref,
-                                          U.getOrigUnit(), DIE, RefCU)) {
+    if (auto RefDIE =
+            resolveDIEReference(Linker, DMO, CompileUnits, *Ref, DIE, RefCU)) {
       CU = RefCU;
       OrigUnit = &RefCU->getOrigUnit();
       DIE = RefDIE;
@@ -3743,43 +2131,45 @@
       // FIXME: dsymutil-classic compatibility. Ignore modules.
       CU->getOrigUnit().getDIEAtIndex(CU->getInfo(Idx).ParentIdx).getTag() ==
           dwarf::DW_TAG_module)
-    return djbHash(Name ? Name : "", djbHash(RecurseDepth ? "" : "::"));
+    return djbHash(Name ? Name : "", djbHash(ChildRecurseDepth ? "" : "::"));
 
   DWARFDie Die = OrigUnit->getDIEAtIndex(CU->getInfo(Idx).ParentIdx);
-  return djbHash((Name ? Name : ""),
-                 djbHash((Name ? "::" : ""),
-                         hashFullyQualifiedName(Die, *CU, ++RecurseDepth)));
+  return djbHash(
+      (Name ? Name : ""),
+      djbHash((Name ? "::" : ""),
+              hashFullyQualifiedName(Die, *CU, DMO, ++ChildRecurseDepth)));
 }
 
-static uint64_t getDwoId(const DWARFDie &CUDie,
-                         const DWARFUnit &Unit) {
-  auto DwoId = dwarf::toUnsigned(CUDie.find({dwarf::DW_AT_dwo_id,
-                                             dwarf::DW_AT_GNU_dwo_id}));
+static uint64_t getDwoId(const DWARFDie &CUDie, const DWARFUnit &Unit) {
+  auto DwoId = dwarf::toUnsigned(
+      CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id}));
   if (DwoId)
     return *DwoId;
   return 0;
 }
 
 bool DwarfLinker::registerModuleReference(
-    const DWARFDie &CUDie, const DWARFUnit &Unit,
-    DebugMap &ModuleMap, unsigned Indent) {
-  std::string PCMfile =
-      dwarf::toString(CUDie.find({dwarf::DW_AT_dwo_name,
-                                  dwarf::DW_AT_GNU_dwo_name}), "");
+    DWARFDie CUDie, const DWARFUnit &Unit, DebugMap &ModuleMap,
+    const DebugMapObject &DMO, RangesTy &Ranges, OffsetsStringPool &StringPool,
+    UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts,
+    uint64_t ModulesEndOffset, unsigned &UnitID, bool IsLittleEndian,
+    unsigned Indent, bool Quiet) {
+  std::string PCMfile = dwarf::toString(
+      CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), "");
   if (PCMfile.empty())
     return false;
 
   // Clang module DWARF skeleton CUs abuse this for the path to the module.
-  std::string PCMpath = dwarf::toString(CUDie.find(dwarf::DW_AT_comp_dir), "");
   uint64_t DwoId = getDwoId(CUDie, Unit);
 
   std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
   if (Name.empty()) {
-    reportWarning("Anonymous module skeleton CU for " + PCMfile);
+    if (!Quiet)
+      reportWarning("Anonymous module skeleton CU for " + PCMfile, DMO);
     return true;
   }
 
-  if (Options.Verbose) {
+  if (!Quiet && Options.Verbose) {
     outs().indent(Indent);
     outs() << "Found clang module reference " << PCMfile;
   }
@@ -3789,21 +2179,26 @@
     // 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 (Options.Verbose && (Cached->second != DwoId))
+    if (!Quiet && Options.Verbose && (Cached->second != DwoId))
       reportWarning(Twine("hash mismatch: this object file was built against a "
-                          "different version of the module ") + PCMfile);
-    if (Options.Verbose)
+                          "different version of the module ") +
+                        PCMfile,
+                    DMO);
+    if (!Quiet && Options.Verbose)
       outs() << " [cached].\n";
     return true;
   }
-  if (Options.Verbose)
+  if (!Quiet && Options.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, DwoId});
-  if (Error E = loadClangModule(PCMfile, PCMpath, Name, DwoId, ModuleMap,
-                                Indent + 2)) {
+
+  if (Error E = loadClangModule(CUDie, PCMfile, Name, DwoId, ModuleMap, DMO,
+                                Ranges, StringPool, UniquingStringPool,
+                                ODRContexts, ModulesEndOffset, UnitID,
+                                IsLittleEndian, Indent + 2, Quiet)) {
     consumeError(std::move(E));
     return false;
   }
@@ -3811,35 +2206,46 @@
 }
 
 ErrorOr<const object::ObjectFile &>
-DwarfLinker::loadObject(BinaryHolder &BinaryHolder, DebugMapObject &Obj,
-                        const DebugMap &Map) {
-  auto ErrOrObjs =
-      BinaryHolder.GetObjectFiles(Obj.getObjectFilename(), Obj.getTimestamp());
-  if (std::error_code EC = ErrOrObjs.getError()) {
-    reportWarning(Twine(Obj.getObjectFilename()) + ": " + EC.message());
-    return EC;
+DwarfLinker::loadObject(const DebugMapObject &Obj, const DebugMap &Map) {
+  auto ObjectEntry =
+      BinHolder.getObjectEntry(Obj.getObjectFilename(), Obj.getTimestamp());
+  if (!ObjectEntry) {
+    auto Err = ObjectEntry.takeError();
+    reportWarning(
+        Twine(Obj.getObjectFilename()) + ": " + toString(std::move(Err)), Obj);
+    return errorToErrorCode(std::move(Err));
   }
-  auto ErrOrObj = BinaryHolder.Get(Map.getTriple());
-  if (std::error_code EC = ErrOrObj.getError())
-    reportWarning(Twine(Obj.getObjectFilename()) + ": " + EC.message());
-  return ErrOrObj;
+
+  auto Object = ObjectEntry->getObject(Map.getTriple());
+  if (!Object) {
+    auto Err = Object.takeError();
+    reportWarning(
+        Twine(Obj.getObjectFilename()) + ": " + toString(std::move(Err)), Obj);
+    return errorToErrorCode(std::move(Err));
+  }
+
+  return *Object;
 }
 
-Error DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
-                                   StringRef ModuleName, uint64_t DwoId,
-                                   DebugMap &ModuleMap, unsigned Indent) {
-  SmallString<80> Path(Options.PrependPath);
+Error DwarfLinker::loadClangModule(
+    DWARFDie CUDie, StringRef Filename, StringRef ModuleName, uint64_t DwoId,
+    DebugMap &ModuleMap, const DebugMapObject &DMO, RangesTy &Ranges,
+    OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool,
+    DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, unsigned &UnitID,
+    bool IsLittleEndian, unsigned Indent, bool Quiet) {
+  /// Using a SmallString<0> because loadClangModule() is recursive.
+  SmallString<0> Path(Options.PrependPath);
   if (sys::path::is_relative(Filename))
-    sys::path::append(Path, ModulePath, Filename);
-  else
-    sys::path::append(Path, Filename);
-  BinaryHolder ObjHolder(Options.Verbose);
+    resolveRelativeObjectPath(Path, CUDie);
+  sys::path::append(Path, Filename);
+  // Don't use the cached binary holder because we have no thread-safety
+  // guarantee and the lifetime is limited.
   auto &Obj = ModuleMap.addDebugMapObject(
       Path, sys::TimePoint<std::chrono::seconds>(), MachO::N_OSO);
-  auto ErrOrObj = loadObject(ObjHolder, Obj, ModuleMap);
+  auto ErrOrObj = loadObject(Obj, ModuleMap);
   if (!ErrOrObj) {
     // Try and emit more helpful warnings by applying some heuristics.
-    StringRef ObjFile = CurrentDebugObject->getObjectFilename();
+    StringRef ObjFile = DMO.getObjectFilename();
     bool isClangModule = sys::path::extension(Filename).equals(".pcm");
     bool isArchive = ObjFile.endswith(")");
     if (isClangModule) {
@@ -3849,9 +2255,9 @@
         // cache has expired and was pruned by clang.  A more adventurous
         // dsymutil would invoke clang to rebuild the module now.
         if (!ModuleCacheHintDisplayed) {
-          errs() << "note: The clang module cache may have expired since this "
-                    "object file was built. Rebuilding the object file will "
-                    "rebuild the module cache.\n";
+          WithColor::note() << "The clang module cache may have expired since "
+                               "this object file was built. Rebuilding the "
+                               "object file will rebuild the module cache.\n";
           ModuleCacheHintDisplayed = true;
         }
       } else if (isArchive) {
@@ -3860,11 +2266,13 @@
         // was built on a different machine. We don't want to discourage module
         // debugging for convenience libraries within a project though.
         if (!ArchiveHintDisplayed) {
-          errs() << "note: Linking a static library that was built with "
-                    "-gmodules, but the module cache was not found.  "
-                    "Redistributable static libraries should never be built "
-                    "with module debugging enabled.  The debug experience will "
-                    "be degraded due to incomplete debug information.\n";
+          WithColor::note()
+              << "Linking a static library that was built with "
+                 "-gmodules, but the module cache was not found.  "
+                 "Redistributable static libraries should never be "
+                 "built with module debugging enabled.  The debug "
+                 "experience will be degraded due to incomplete "
+                 "debug information.\n";
           ArchiveHintDisplayed = true;
         }
       }
@@ -3877,18 +2285,23 @@
   // Setup access to the debug info.
   auto DwarfContext = DWARFContext::create(*ErrOrObj);
   RelocationManager RelocMgr(*this);
+
   for (const auto &CU : DwarfContext->compile_units()) {
-    maybeUpdateMaxDwarfVersion(CU->getVersion());
-
+    updateDwarfVersion(CU->getVersion());
     // Recursively get all modules imported by this one.
     auto CUDie = CU->getUnitDIE(false);
-    if (!registerModuleReference(CUDie, *CU, ModuleMap, Indent)) {
+    if (!CUDie)
+      continue;
+    if (!registerModuleReference(CUDie, *CU, ModuleMap, DMO, Ranges, StringPool,
+                                 UniquingStringPool, ODRContexts,
+                                 ModulesEndOffset, UnitID, IsLittleEndian,
+                                 Indent, Quiet)) {
       if (Unit) {
         std::string Err =
             (Filename +
              ": Clang modules are expected to have exactly 1 compile unit.\n")
                 .str();
-        errs() << Err;
+        error(Err);
         return make_error<StringError>(Err, inconvertibleErrorCode());
       }
       // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
@@ -3896,10 +2309,12 @@
       // ASTFileSignatures will change randomly when a module is rebuilt.
       uint64_t PCMDwoId = getDwoId(CUDie, *CU);
       if (PCMDwoId != DwoId) {
-        if (Options.Verbose)
+        if (!Quiet && Options.Verbose)
           reportWarning(
               Twine("hash mismatch: this object file was built against a "
-                    "different version of the module ") + Filename);
+                    "different version of the module ") +
+                  Filename,
+              DMO);
         // Update the cache entry with the DwoId of the module loaded from disk.
         ClangModules[Filename] = PCMDwoId;
       }
@@ -3908,55 +2323,80 @@
       Unit = llvm::make_unique<CompileUnit>(*CU, UnitID++, !Options.NoODR,
                                             ModuleName);
       Unit->setHasInterestingContent();
-      analyzeContextInfo(CUDie, 0, *Unit, &ODRContexts.getRoot(), StringPool,
-                         ODRContexts);
+      analyzeContextInfo(CUDie, 0, *Unit, &ODRContexts.getRoot(),
+                         UniquingStringPool, ODRContexts, ModulesEndOffset,
+                         ParseableSwiftInterfaces,
+                         [&](const Twine &Warning, const DWARFDie &DIE) {
+                           reportWarning(Warning, DMO, &DIE);
+                         });
       // Keep everything.
       Unit->markEverythingAsKept();
     }
   }
   if (!Unit->getOrigUnit().getUnitDIE().hasChildren())
     return Error::success();
-  if (Options.Verbose) {
+  if (!Quiet && Options.Verbose) {
     outs().indent(Indent);
     outs() << "cloning .debug_info from " << Filename << "\n";
   }
 
-  std::vector<std::unique_ptr<CompileUnit>> CompileUnits;
+  UnitListTy CompileUnits;
   CompileUnits.push_back(std::move(Unit));
   DIECloner(*this, RelocMgr, DIEAlloc, CompileUnits, Options)
-      .cloneAllCompileUnits(*DwarfContext);
+      .cloneAllCompileUnits(*DwarfContext, DMO, Ranges, StringPool,
+                            IsLittleEndian);
   return Error::success();
 }
 
-void DwarfLinker::DIECloner::cloneAllCompileUnits(DWARFContext &DwarfContext) {
+void DwarfLinker::DIECloner::cloneAllCompileUnits(
+    DWARFContext &DwarfContext, const DebugMapObject &DMO, RangesTy &Ranges,
+    OffsetsStringPool &StringPool, bool IsLittleEndian) {
   if (!Linker.Streamer)
     return;
 
   for (auto &CurrentUnit : CompileUnits) {
     auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE();
     CurrentUnit->setStartOffset(Linker.OutputDebugInfoSize);
+    if (!InputDIE) {
+      Linker.OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset();
+      continue;
+    }
     if (CurrentUnit->getInfo(0).Keep) {
       // Clone the InputDIE into your Unit DIE in our compile unit since it
       // already has a DIE inside of it.
       CurrentUnit->createOutputDIE();
-      cloneDIE(InputDIE, *CurrentUnit, 0 /* PC offset */,
-               11 /* Unit Header size */, 0, CurrentUnit->getOutputUnitDIE());
+      cloneDIE(InputDIE, DMO, *CurrentUnit, StringPool, 0 /* PC offset */,
+               11 /* Unit Header size */, 0, IsLittleEndian,
+               CurrentUnit->getOutputUnitDIE());
     }
+
     Linker.OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset();
+
     if (Linker.Options.NoOutput)
       continue;
 
-    if (LLVM_LIKELY(!Linker.Options.Update)) {
-      // FIXME: for compatibility with the classic dsymutil, we emit an empty
-      // line table for the unit, even if the unit doesn't actually exist in
-      // the DIE tree.
-      Linker.patchLineTableForUnit(*CurrentUnit, DwarfContext);
-      Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
-      Linker.patchRangesForUnit(*CurrentUnit, DwarfContext);
-      Linker.Streamer->emitLocationsForUnit(*CurrentUnit, DwarfContext);
-    } else {
-      Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
-    }
+    // FIXME: for compatibility with the classic dsymutil, we emit
+    // an empty line table for the unit, even if the unit doesn't
+    // actually exist in the DIE tree.
+    if (LLVM_LIKELY(!Linker.Options.Update) || Linker.Options.Translator)
+      Linker.patchLineTableForUnit(*CurrentUnit, DwarfContext, Ranges, DMO);
+
+    Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
+
+    if (LLVM_UNLIKELY(Linker.Options.Update))
+      continue;
+
+    Linker.patchRangesForUnit(*CurrentUnit, DwarfContext, DMO);
+    auto ProcessExpr = [&](StringRef Bytes, SmallVectorImpl<uint8_t> &Buffer) {
+      DWARFUnit &OrigUnit = CurrentUnit->getOrigUnit();
+      DataExtractor Data(Bytes, IsLittleEndian, OrigUnit.getAddressByteSize());
+      cloneExpression(Data,
+                      DWARFExpression(Data, OrigUnit.getVersion(),
+                                      OrigUnit.getAddressByteSize()),
+                      DMO, *CurrentUnit, Buffer);
+    };
+    Linker.Streamer->emitLocationsForUnit(*CurrentUnit, DwarfContext,
+                                          ProcessExpr);
   }
 
   if (Linker.Options.NoOutput)
@@ -3966,14 +2406,132 @@
   for (auto &CurrentUnit : CompileUnits) {
     if (LLVM_LIKELY(!Linker.Options.Update))
       Linker.generateUnitRanges(*CurrentUnit);
+
     CurrentUnit->fixupForwardReferences();
-    Linker.Streamer->emitCompileUnitHeader(*CurrentUnit);
+
     if (!CurrentUnit->getOutputUnitDIE())
       continue;
+
+    Linker.Streamer->emitCompileUnitHeader(*CurrentUnit);
     Linker.Streamer->emitDIE(*CurrentUnit->getOutputUnitDIE());
   }
 }
 
+void DwarfLinker::updateAccelKind(DWARFContext &Dwarf) {
+  if (Options.TheAccelTableKind != AccelTableKind::Default)
+    return;
+
+  auto &DwarfObj = Dwarf.getDWARFObj();
+
+  if (!AtLeastOneDwarfAccelTable &&
+      (!DwarfObj.getAppleNamesSection().Data.empty() ||
+       !DwarfObj.getAppleTypesSection().Data.empty() ||
+       !DwarfObj.getAppleNamespacesSection().Data.empty() ||
+       !DwarfObj.getAppleObjCSection().Data.empty())) {
+    AtLeastOneAppleAccelTable = true;
+  }
+
+  if (!AtLeastOneDwarfAccelTable &&
+      !DwarfObj.getNamesSection().Data.empty()) {
+    AtLeastOneDwarfAccelTable = true;
+  }
+}
+
+bool DwarfLinker::emitPaperTrailWarnings(const DebugMapObject &DMO,
+                                         const DebugMap &Map,
+                                         OffsetsStringPool &StringPool) {
+  if (DMO.getWarnings().empty() || !DMO.empty())
+    return false;
+
+  Streamer->switchToDebugInfoSection(/* Version */ 2);
+  DIE *CUDie = DIE::get(DIEAlloc, dwarf::DW_TAG_compile_unit);
+  CUDie->setOffset(11);
+  StringRef Producer = StringPool.internString("dsymutil");
+  StringRef File = StringPool.internString(DMO.getObjectFilename());
+  CUDie->addValue(DIEAlloc, dwarf::DW_AT_producer, dwarf::DW_FORM_strp,
+                  DIEInteger(StringPool.getStringOffset(Producer)));
+  DIEBlock *String = new (DIEAlloc) DIEBlock();
+  DIEBlocks.push_back(String);
+  for (auto &C : File)
+    String->addValue(DIEAlloc, dwarf::Attribute(0), dwarf::DW_FORM_data1,
+                     DIEInteger(C));
+  String->addValue(DIEAlloc, dwarf::Attribute(0), dwarf::DW_FORM_data1,
+                   DIEInteger(0));
+
+  CUDie->addValue(DIEAlloc, dwarf::DW_AT_name, dwarf::DW_FORM_string, String);
+  for (const auto &Warning : DMO.getWarnings()) {
+    DIE &ConstDie = CUDie->addChild(DIE::get(DIEAlloc, dwarf::DW_TAG_constant));
+    ConstDie.addValue(
+        DIEAlloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp,
+        DIEInteger(StringPool.getStringOffset("dsymutil_warning")));
+    ConstDie.addValue(DIEAlloc, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag,
+                      DIEInteger(1));
+    ConstDie.addValue(DIEAlloc, dwarf::DW_AT_const_value, dwarf::DW_FORM_strp,
+                      DIEInteger(StringPool.getStringOffset(Warning)));
+  }
+  unsigned Size = 4 /* FORM_strp */ + File.size() + 1 +
+                  DMO.getWarnings().size() * (4 + 1 + 4) +
+                  1 /* End of children */;
+  DIEAbbrev Abbrev = CUDie->generateAbbrev();
+  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);
+    Child.setAbbrevNumber(Abbrev.getNumber());
+    Size += getULEB128Size(Abbrev.getNumber());
+  }
+  CUDie->setSize(Size);
+  auto &Asm = Streamer->getAsmPrinter();
+  Asm.emitInt32(11 + CUDie->getSize() - 4);
+  Asm.emitInt16(2);
+  Asm.emitInt32(0);
+  Asm.emitInt8(Map.getTriple().isArch64Bit() ? 8 : 4);
+  Streamer->emitDIE(*CUDie);
+  OutputDebugInfoSize += 11 /* Header */ + Size;
+
+  return true;
+}
+
+static Error copySwiftInterfaces(
+    const std::map<std::string, std::string> &ParseableSwiftInterfaces,
+    StringRef Architecture, const LinkOptions &Options) {
+  std::error_code EC;
+  SmallString<128> InputPath;
+  SmallString<128> Path;
+  sys::path::append(Path, *Options.ResourceDir, "Swift", Architecture);
+  if ((EC = sys::fs::create_directories(Path.str(), true,
+                                        sys::fs::perms::all_all)))
+    return make_error<StringError>(
+        "cannot create directory: " + toString(errorCodeToError(EC)), EC);
+  unsigned BaseLength = Path.size();
+
+  for (auto &I : ParseableSwiftInterfaces) {
+    StringRef ModuleName = I.first;
+    StringRef InterfaceFile = I.second;
+    if (!Options.PrependPath.empty()) {
+      InputPath.clear();
+      sys::path::append(InputPath, Options.PrependPath, InterfaceFile);
+      InterfaceFile = InputPath;
+    }
+    sys::path::append(Path, ModuleName);
+    Path.append(".swiftinterface");
+    if (Options.Verbose)
+      outs() << "copy parseable Swift interface " << InterfaceFile << " -> "
+             << Path.str() << '\n';
+
+    // 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)));
+    Path.resize(BaseLength);
+  }
+  return Error::success();
+}
+
 bool DwarfLinker::link(const DebugMap &Map) {
   if (!createStreamer(Map.getTriple(), OutFile))
     return false;
@@ -3981,35 +2539,79 @@
   // Size of the DIEs (and headers) generated for the linked output.
   OutputDebugInfoSize = 0;
   // A unique ID that identifies each compile unit.
-  UnitID = 0;
+  unsigned UnitID = 0;
   DebugMap ModuleMap(Map.getTriple(), Map.getBinaryPath());
 
+  // First populate the data structure we need for each iteration of the
+  // parallel loop.
+  unsigned NumObjects = Map.getNumberOfObjects();
+  std::vector<LinkContext> ObjectContexts;
+  ObjectContexts.reserve(NumObjects);
   for (const auto &Obj : Map.objects()) {
-    CurrentDebugObject = Obj.get();
+    ObjectContexts.emplace_back(Map, *this, *Obj.get());
+    LinkContext &LC = ObjectContexts.back();
+    if (LC.ObjectFile)
+      updateAccelKind(*LC.DwarfContext);
+  }
+
+  // This Dwarf string pool which is only used for uniquing. This one should
+  // never be used for offsets as its not thread-safe or predictable.
+  UniquingStringPool UniquingStringPool;
+
+  // This Dwarf string pool which is used for emission. It must be used
+  // serially as the order of calling getStringOffset matters for
+  // reproducibility.
+  OffsetsStringPool OffsetsStringPool(Options.Translator);
 
+  // ODR Contexts for the link.
+  DeclContextTree ODRContexts;
+
+  // If we haven't decided on an accelerator table kind yet, we base ourselves
+  // on the DWARF we have seen so far. At this point we haven't pulled in debug
+  // information from modules yet, so it is technically possible that they
+  // would affect the decision. However, as they're built with the same
+  // compiler and flags, it is safe to assume that they will follow the
+  // decision made here.
+  if (Options.TheAccelTableKind == AccelTableKind::Default) {
+    if (AtLeastOneDwarfAccelTable && !AtLeastOneAppleAccelTable)
+      Options.TheAccelTableKind = AccelTableKind::Dwarf;
+    else
+      Options.TheAccelTableKind = AccelTableKind::Apple;
+  }
+
+  for (LinkContext &LinkContext : ObjectContexts) {
     if (Options.Verbose)
-      outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n";
+      outs() << "DEBUG MAP OBJECT: " << LinkContext.DMO.getObjectFilename()
+             << "\n";
 
     // N_AST objects (swiftmodule files) should get dumped directly into the
     // appropriate DWARF section.
-    if (Obj->getType() == MachO::N_AST) {
-      StringRef File = Obj->getObjectFilename();
+    if (LinkContext.DMO.getType() == MachO::N_AST) {
+      StringRef File = LinkContext.DMO.getObjectFilename();
       auto ErrorOrMem = MemoryBuffer::getFile(File);
       if (!ErrorOrMem) {
-        errs() << "Warning: Could not open " << File << "\n";
+        warn("Could not open '" + File + "'\n");
         continue;
       }
       sys::fs::file_status Stat;
-      if (auto errc = sys::fs::status(File, Stat)) {
-        errs() << "Warning: " << errc.message() << "\n";
+      if (auto Err = sys::fs::status(File, Stat)) {
+        warn(Err.message());
         continue;
       }
-      if (!Options.NoTimestamp && Stat.getLastModificationTime() !=
-                                      sys::TimePoint<>(Obj->getTimestamp())) {
-        errs() << "Warning: Timestamp mismatch for " << File << ": "
-               << Stat.getLastModificationTime() << " and "
-               << sys::TimePoint<>(Obj->getTimestamp()) << "\n";
-        continue;
+      if (!Options.NoTimestamp) {
+        // The modification can have sub-second precision so we need to cast
+        // away the extra precision that's not present in the debug map.
+        auto ModificationTime =
+            std::chrono::time_point_cast<std::chrono::seconds>(
+                Stat.getLastModificationTime());
+        if (ModificationTime != LinkContext.DMO.getTimestamp()) {
+          // Not using the helper here as we can easily stream TimePoint<>.
+          WithColor::warning()
+              << "Timestamp mismatch for " << File << ": "
+              << Stat.getLastModificationTime() << " and "
+              << sys::TimePoint<>(LinkContext.DMO.getTimestamp()) << "\n";
+          continue;
+        }
       }
 
       // Copy the module into the .swift_ast section.
@@ -4018,149 +2620,240 @@
       continue;
     }
 
-    auto ErrOrObj = loadObject(BinHolder, *Obj, Map);
-    if (!ErrOrObj)
+    if (emitPaperTrailWarnings(LinkContext.DMO, Map, OffsetsStringPool))
+      continue;
+
+    if (!LinkContext.ObjectFile)
       continue;
 
     // Look for relocations that correspond to debug map entries.
-    RelocationManager RelocMgr(*this);
+
     if (LLVM_LIKELY(!Options.Update) &&
-        !RelocMgr.findValidRelocsInDebugInfo(*ErrOrObj, *Obj)) {
+        !LinkContext.RelocMgr.findValidRelocsInDebugInfo(
+            *LinkContext.ObjectFile, LinkContext.DMO)) {
       if (Options.Verbose)
         outs() << "No valid relocations found. Skipping.\n";
+
+      // Clear this ObjFile entry as a signal to other loops that we should not
+      // process this iteration.
+      LinkContext.ObjectFile = nullptr;
       continue;
     }
 
     // Setup access to the debug info.
-    auto DwarfContext = DWARFContext::create(*ErrOrObj);
-    startDebugObject(*DwarfContext, *Obj);
+    if (!LinkContext.DwarfContext)
+      continue;
+
+    startDebugObject(LinkContext);
 
     // In a first phase, just read in the debug info and load all clang modules.
-    for (const auto &CU : DwarfContext->compile_units()) {
+    LinkContext.CompileUnits.reserve(
+        LinkContext.DwarfContext->getNumCompileUnits());
+
+    for (const auto &CU : LinkContext.DwarfContext->compile_units()) {
+      updateDwarfVersion(CU->getVersion());
       auto CUDie = CU->getUnitDIE(false);
       if (Options.Verbose) {
         outs() << "Input compilation unit:";
         DIDumpOptions DumpOpts;
-        DumpOpts.RecurseDepth = 0;
+        DumpOpts.ChildRecurseDepth = 0;
         DumpOpts.Verbose = Options.Verbose;
         CUDie.dump(outs(), 0, DumpOpts);
       }
+      if (CUDie && !LLVM_UNLIKELY(Options.Update))
+        registerModuleReference(CUDie, *CU, ModuleMap, LinkContext.DMO,
+                                LinkContext.Ranges, OffsetsStringPool,
+                                UniquingStringPool, ODRContexts, 0, UnitID,
+                                LinkContext.DwarfContext->isLittleEndian());
+    }
+  }
 
+  // If we haven't seen any CUs, pick an arbitrary valid Dwarf version anyway.
+  if (MaxDwarfVersion == 0)
+    MaxDwarfVersion = 3;
+
+  // At this point we know how much data we have emitted. We use this value to
+  // compare canonical DIE offsets in analyzeContextInfo to see if a definition
+  // is already emitted, without being affected by canonical die offsets set
+  // later. This prevents undeterminism when analyze and clone execute
+  // concurrently, as clone set the canonical DIE offset and analyze reads it.
+  const uint64_t ModulesEndOffset = OutputDebugInfoSize;
+
+  // These variables manage the list of processed object files.
+  // The mutex and condition variable are to ensure that this is thread safe.
+  std::mutex ProcessedFilesMutex;
+  std::condition_variable ProcessedFilesConditionVariable;
+  BitVector ProcessedFiles(NumObjects, false);
+
+  //  Analyzing the context info is particularly expensive so it is executed in
+  //  parallel with emitting the previous compile unit.
+  auto AnalyzeLambda = [&](size_t i) {
+    auto &LinkContext = ObjectContexts[i];
+
+    if (!LinkContext.ObjectFile || !LinkContext.DwarfContext)
+      return;
+
+    for (const auto &CU : LinkContext.DwarfContext->compile_units()) {
+      updateDwarfVersion(CU->getVersion());
+      // 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.
+      bool Quiet = true;
+      auto CUDie = CU->getUnitDIE(false);
       if (!CUDie || LLVM_UNLIKELY(Options.Update) ||
-          !registerModuleReference(CUDie, *CU, ModuleMap)) {
-        Units.push_back(llvm::make_unique<CompileUnit>(
+          !registerModuleReference(CUDie, *CU, ModuleMap, LinkContext.DMO,
+                                   LinkContext.Ranges, OffsetsStringPool,
+                                   UniquingStringPool, ODRContexts,
+                                   ModulesEndOffset, UnitID, Quiet)) {
+        LinkContext.CompileUnits.push_back(llvm::make_unique<CompileUnit>(
             *CU, UnitID++, !Options.NoODR && !Options.Update, ""));
-        maybeUpdateMaxDwarfVersion(CU->getVersion());
       }
     }
 
     // Now build the DIE parent links that we will use during the next phase.
-    for (auto &CurrentUnit : Units)
-      analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0, *CurrentUnit,
-                         &ODRContexts.getRoot(), StringPool, ODRContexts);
+    for (auto &CurrentUnit : LinkContext.CompileUnits) {
+      auto CUDie = CurrentUnit->getOrigUnit().getUnitDIE();
+      if (!CUDie)
+        continue;
+      analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0,
+                         *CurrentUnit, &ODRContexts.getRoot(),
+                         UniquingStringPool, ODRContexts, ModulesEndOffset,
+                         ParseableSwiftInterfaces,
+                         [&](const Twine &Warning, const DWARFDie &DIE) {
+                           reportWarning(Warning, LinkContext.DMO, &DIE);
+                         });
+    }
+  };
 
-    // Then mark all the DIEs that need to be present in the linked
-    // output and collect some information about them. Note that this
-    // loop can not be merged with the previous one because cross-CU
-    // references require the ParentIdx to be setup for every CU in
+  // And then the remaining work in serial again.
+  // Note, although this loop runs in serial, it can run in parallel with
+  // the analyzeContextInfo loop so long as we process files with indices >=
+  // than those processed by analyzeContextInfo.
+  auto CloneLambda = [&](size_t i) {
+    auto &LinkContext = ObjectContexts[i];
+    if (!LinkContext.ObjectFile)
+      return;
+
+    // Then mark all the DIEs that need to be present in the linked output
+    // and collect some information about them.
+    // Note that this loop can not be merged with the previous one because
+    // cross-cu references require the ParentIdx to be setup for every CU in
     // the object file before calling this.
     if (LLVM_UNLIKELY(Options.Update)) {
-      for (auto &CurrentUnit : Units)
+      for (auto &CurrentUnit : LinkContext.CompileUnits)
         CurrentUnit->markEverythingAsKept();
-      Streamer->copyInvariantDebugSection(*ErrOrObj, Options);
+      Streamer->copyInvariantDebugSection(*LinkContext.ObjectFile);
     } else {
-      for (auto &CurrentUnit : Units)
-        lookForDIEsToKeep(RelocMgr, CurrentUnit->getOrigUnit().getUnitDIE(),
-                          *Obj, *CurrentUnit, 0);
+      for (auto &CurrentUnit : LinkContext.CompileUnits)
+        lookForDIEsToKeep(LinkContext.RelocMgr, LinkContext.Ranges,
+                          LinkContext.CompileUnits,
+                          CurrentUnit->getOrigUnit().getUnitDIE(),
+                          LinkContext.DMO, *CurrentUnit, 0);
     }
 
-    // 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.
-    RelocMgr.resetValidRelocs();
-    if (RelocMgr.hasValidRelocs() || LLVM_UNLIKELY(Options.Update))
-      DIECloner(*this, RelocMgr, DIEAlloc, Units, Options)
-          .cloneAllCompileUnits(*DwarfContext);
-    if (!Options.NoOutput && !Units.empty() && LLVM_LIKELY(!Options.Update))
-      patchFrameInfoForObject(*Obj, *DwarfContext,
-                              Units[0]->getOrigUnit().getAddressByteSize());
+    // 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)
+          .cloneAllCompileUnits(*LinkContext.DwarfContext, LinkContext.DMO,
+                                LinkContext.Ranges, OffsetsStringPool,
+                                LinkContext.DwarfContext->isLittleEndian());
+    if (!Options.NoOutput && !LinkContext.CompileUnits.empty() &&
+        LLVM_LIKELY(!Options.Update))
+      patchFrameInfoForObject(
+          LinkContext.DMO, LinkContext.Ranges, *LinkContext.DwarfContext,
+          LinkContext.CompileUnits[0]->getOrigUnit().getAddressByteSize());
 
     // Clean-up before starting working on the next object.
-    endDebugObject();
-  }
+    endDebugObject(LinkContext);
+  };
+
+  auto EmitLambda = [&]() {
+    // Emit everything that's global.
+    if (!Options.NoOutput) {
+      Streamer->emitAbbrevs(Abbreviations, MaxDwarfVersion);
+      Streamer->emitStrings(OffsetsStringPool);
+      switch (Options.TheAccelTableKind) {
+      case AccelTableKind::Apple:
+        Streamer->emitAppleNames(AppleNames);
+        Streamer->emitAppleNamespaces(AppleNamespaces);
+        Streamer->emitAppleTypes(AppleTypes);
+        Streamer->emitAppleObjc(AppleObjc);
+        break;
+      case AccelTableKind::Dwarf:
+        Streamer->emitDebugNames(DebugNames);
+        break;
+      case AccelTableKind::Default:
+        llvm_unreachable("Default should have already been resolved.");
+        break;
+      }
+    }
+  };
+
+  auto AnalyzeAll = [&]() {
+    for (unsigned i = 0, e = NumObjects; i != e; ++i) {
+      AnalyzeLambda(i);
 
-  // Emit everything that's global.
-  if (!Options.NoOutput) {
-    Streamer->emitAbbrevs(Abbreviations, MaxDwarfVersion);
-    Streamer->emitStrings(StringPool);
-    Streamer->emitAppleNames(AppleNames);
-    Streamer->emitAppleNamespaces(AppleNamespaces);
-    Streamer->emitAppleTypes(AppleTypes);
-    Streamer->emitAppleObjc(AppleObjc);
+      std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
+      ProcessedFiles.set(i);
+      ProcessedFilesConditionVariable.notify_one();
+    }
+  };
+
+  auto CloneAll = [&]() {
+    for (unsigned i = 0, e = NumObjects; i != e; ++i) {
+      {
+        std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
+        if (!ProcessedFiles[i]) {
+          ProcessedFilesConditionVariable.wait(
+              LockGuard, [&]() { return ProcessedFiles[i]; });
+        }
+      }
+
+      CloneLambda(i);
+    }
+    EmitLambda();
+  };
+
+  // To limit memory usage in the single threaded case, analyze and clone are
+  // run sequentially so the LinkContext is freed after processing each object
+  // in endDebugObject.
+  if (Options.Threads == 1) {
+    for (unsigned i = 0, e = NumObjects; i != e; ++i) {
+      AnalyzeLambda(i);
+      CloneLambda(i);
+    }
+    EmitLambda();
+  } else {
+    ThreadPool pool(2);
+    pool.async(AnalyzeAll);
+    pool.async(CloneAll);
+    pool.wait();
   }
 
-  return Options.NoOutput ? true : Streamer->finish(Map);
-}
-
-DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) {
-  if (S.empty() && !Strings.empty())
-    return EmptyString;
-
-  auto I = Strings.insert(std::make_pair(S, DwarfStringPoolEntry()));
-  auto &Entry = I.first->second;
-  if (I.second || Entry.Index == -1U) {
-    Entry.Index = NumEntries++;
-    Entry.Offset = CurrentEndOffset;
-    Entry.Symbol = nullptr;
-    CurrentEndOffset += S.size() + 1;
-  }
-  return DwarfStringPoolEntryRef(*I.first);
-}
-
-uint32_t NonRelocatableStringpool::getStringOffset(StringRef S) {
-  return getEntry(S).getOffset();
-}
+  if (Options.NoOutput)
+    return true;
 
-/// Put \p S into the StringMap so that it gets permanent
-/// storage, but do not actually link it in the chain of elements
-/// that go into the output section. A latter call to
-/// getStringOffset() with the same string will chain it though.
-StringRef NonRelocatableStringpool::internString(StringRef S) {
-  DwarfStringPoolEntry Entry{nullptr, 0, -1U};
-  auto InsertResult = Strings.insert(std::make_pair(S, Entry));
-  return InsertResult.first->getKey();
-}
+  if (Options.ResourceDir && !ParseableSwiftInterfaces.empty()) {
+    StringRef ArchName = Triple::getArchTypeName(Map.getTriple().getArch());
+    if (auto E =
+            copySwiftInterfaces(ParseableSwiftInterfaces, ArchName, Options))
+      return error(toString(std::move(E)));
+  }
 
-std::vector<DwarfStringPoolEntryRef>
-NonRelocatableStringpool::getEntries() const {
-  std::vector<DwarfStringPoolEntryRef> Result;
-  Result.reserve(Strings.size());
-  for (const auto &E : Strings)
-    Result.emplace_back(E);
-  std::sort(
-      Result.begin(), Result.end(),
-      [](const DwarfStringPoolEntryRef A, const DwarfStringPoolEntryRef B) {
-        return A.getIndex() < B.getIndex();
-      });
-  return Result;
-}
+  return Streamer->finish(Map, Options.Translator);
+} // namespace dsymutil
 
-void warn(const Twine &Warning, const Twine &Context) {
-  errs() << Twine("while processing ") + Context + ":\n";
-  errs() << Twine("warning: ") + Warning + "\n";
-}
-
-bool error(const Twine &Error, const Twine &Context) {
-  errs() << Twine("while processing ") + Context + ":\n";
-  errs() << Twine("error: ") + Error + "\n";
-  return false;
-}
-
-bool linkDwarf(raw_fd_ostream &OutFile, const DebugMap &DM,
-               const LinkOptions &Options) {
-  DwarfLinker Linker(OutFile, Options);
+bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
+               const DebugMap &DM, LinkOptions Options) {
+  DwarfLinker Linker(OutFile, BinHolder, std::move(Options));
   return Linker.link(DM);
 }
 
-} // end namespace dsymutil
-} // end namespace llvm
+} // namespace dsymutil
+} // namespace llvm