[llvm] [DWARFLinker][NFC] Decrease DWARFLinker dependence on DwarfStreamer. (PR #77932)

Alexey Lapshin via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 19 05:42:10 PST 2024


https://github.com/avl-llvm updated https://github.com/llvm/llvm-project/pull/77932

>From 15144b8f8a5aee07471f4a334164e002ae879455 Mon Sep 17 00:00:00 2001
From: Alexey Lapshin <a.v.lapshin at mail.ru>
Date: Fri, 12 Jan 2024 13:07:33 +0300
Subject: [PATCH 1/2] [DWARFLinker][NFC] Decrease DWARFLinker dependence on
 DwarfStreamer.

This patch is extracted from #74725.

The DwarfStreamer interface looks overcomplicated and has unnecessary dependencies:

1. it contains emitSwiftAST, emitSwiftReflectionSection methods which are not used by
DWARFLinker.

2. its interface uses DWARFLinker classes(CompileUnit) which makes it dependend
on DWARFLinker.

3. it has "AsmPrinter &getAsmPrinter()" method which provides very low level interface.

This patch avoids creation of DwarfStreamer by DWARFLinker and simplifies interface:

1. dwarf_linker::classic.

   Now client of DWARFLinker creates DwarfStreamer and pass it to the DWARFLinker
   through DwarfEmitter interface. It simplifies dependence. Later it would be good
   to remove class DwarfStreamer from dwarf_linker::classic completely.

2. dwarf_linker::parallel.

   Now client of DWARFLinker sets handler of output debug sections to the DWARFLinker.
   It simplifies dependence to following small interface:

   using SectionHandlerTy =
    std::function<void(std::shared_ptr<SectionDescriptorBase> Section)>;

   virtual void setOutputDWARFHandler(const Triple &TargetTriple,
                                     SectionHandlerTy SectionHandler) = 0;
---
 .../llvm/DWARFLinker/Classic/DWARFLinker.h    |  24 +---
 .../llvm/DWARFLinker/Classic/DWARFStreamer.h  |  18 ++-
 .../llvm/DWARFLinker/DWARFLinkerBase.h        |  47 +++++++
 .../llvm/DWARFLinker/Parallel/DWARFLinker.h   |  57 ++++----
 llvm/lib/DWARFLinker/CMakeLists.txt           |   1 +
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp  |  33 ++---
 .../lib/DWARFLinker/Classic/DWARFStreamer.cpp |  90 ++++++++++---
 llvm/lib/DWARFLinker/DWARFLinkerBase.cpp      |  64 +++++++++
 .../DWARFLinker/Parallel/DWARFEmitterImpl.cpp |  66 ----------
 .../DWARFLinker/Parallel/DWARFEmitterImpl.h   |  23 +---
 .../Parallel/DWARFLinkerCompileUnit.cpp       |  14 +-
 .../Parallel/DWARFLinkerCompileUnit.h         |   7 +-
 .../Parallel/DWARFLinkerGlobalData.h          |  29 +++-
 .../DWARFLinker/Parallel/DWARFLinkerImpl.cpp  |  92 +++++--------
 .../DWARFLinker/Parallel/DWARFLinkerImpl.h    |  23 ++--
 .../Parallel/DWARFLinkerTypeUnit.cpp          |  12 +-
 .../Parallel/DWARFLinkerTypeUnit.h            |   2 +-
 .../DWARFLinker/Parallel/OutputSections.cpp   |  53 --------
 .../lib/DWARFLinker/Parallel/OutputSections.h | 124 ++++++------------
 llvm/tools/dsymutil/DwarfLinkerForBinary.cpp  |  36 +++--
 llvm/tools/dsymutil/DwarfLinkerForBinary.h    |   4 +-
 llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp |  25 +++-
 22 files changed, 419 insertions(+), 425 deletions(-)
 create mode 100644 llvm/lib/DWARFLinker/DWARFLinkerBase.cpp

diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
index 46d3f3148818b1..b1d3f03394f5ec 100644
--- a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
@@ -42,7 +42,8 @@ class DwarfEmitter {
   virtual ~DwarfEmitter() = default;
 
   /// Emit section named SecName with data SecData.
-  virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0;
+  virtual void emitSectionContents(StringRef SecData,
+                                   DebugSectionKind SecKind) = 0;
 
   /// Emit the abbreviation table \p Abbrevs to the .debug_abbrev section.
   virtual void
@@ -188,17 +189,6 @@ class DwarfEmitter {
 
   /// Dump the file to the disk.
   virtual void finish() = 0;
-
-  /// Emit the swift_ast section stored in \p Buffer.
-  virtual void emitSwiftAST(StringRef Buffer) = 0;
-
-  /// Emit the swift reflection section stored in \p Buffer.
-  virtual void emitSwiftReflectionSection(
-      llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
-      StringRef Buffer, uint32_t Alignment, uint32_t Size) = 0;
-
-  /// Returns underlying AsmPrinter.
-  virtual AsmPrinter &getAsmPrinter() const = 0;
 };
 
 class DwarfStreamer;
@@ -232,10 +222,10 @@ class DWARFLinker : public DWARFLinkerBase {
                                          StringsTranslator);
   }
 
-  Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
-                      raw_pwrite_stream &OutFile);
-
-  DwarfEmitter *getEmitter();
+  /// Set output DWARF emitter.
+  void setOutputDWARFEmitter(DwarfEmitter *Emitter) {
+    TheDwarfEmitter = Emitter;
+  }
 
   /// Add object file to be linked. Pre-load compile unit die. Call
   /// \p OnCUDieLoaded for each compile unit die. If specified \p File
@@ -762,7 +752,7 @@ class DWARFLinker : public DWARFLinkerBase {
   BumpPtrAllocator DIEAlloc;
   /// @}
 
-  std::unique_ptr<DwarfStreamer> TheDwarfEmitter;
+  DwarfEmitter *TheDwarfEmitter = nullptr;
   std::vector<LinkContext> ObjectContexts;
 
   /// The CIEs that have been emitted in the output section. The actual CIE
diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h
index f010c348f12148..bebdfd5e60257e 100644
--- a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h
+++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h
@@ -45,18 +45,23 @@ class DwarfStreamer : public DwarfEmitter {
 public:
   DwarfStreamer(DWARFLinkerBase::OutputFileType OutFileType,
                 raw_pwrite_stream &OutFile,
-                std::function<StringRef(StringRef Input)> Translator,
+                DWARFLinkerBase::TranslatorFuncTy Translator,
                 DWARFLinkerBase::MessageHandlerTy Warning)
       : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
         WarningHandler(Warning) {}
   virtual ~DwarfStreamer() = default;
 
+  static Expected<std::unique_ptr<DwarfStreamer>> createStreamer(
+      const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType,
+      raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator,
+      DWARFLinkerBase::MessageHandlerTy Warning);
+
   Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);
 
   /// Dump the file to the disk.
   void finish() override;
 
-  AsmPrinter &getAsmPrinter() const override { return *Asm; }
+  AsmPrinter &getAsmPrinter() const { return *Asm; }
 
   /// Set the current output section to debug_info and change
   /// the MC Dwarf version to \p DwarfVersion.
@@ -77,7 +82,8 @@ class DwarfStreamer : public DwarfEmitter {
                    unsigned DwarfVersion) override;
 
   /// Emit contents of section SecName From Obj.
-  void emitSectionContents(StringRef SecData, StringRef SecName) override;
+  void emitSectionContents(StringRef SecData,
+                           DebugSectionKind SecKind) override;
 
   /// Emit the string table described by \p Pool into .debug_str table.
   void emitStrings(const NonRelocatableStringpool &Pool) override;
@@ -91,12 +97,12 @@ class DwarfStreamer : public DwarfEmitter {
   void emitLineStrings(const NonRelocatableStringpool &Pool) override;
 
   /// Emit the swift_ast section stored in \p Buffer.
-  void emitSwiftAST(StringRef Buffer) override;
+  void emitSwiftAST(StringRef Buffer);
 
   /// Emit the swift reflection section stored in \p Buffer.
   void emitSwiftReflectionSection(
       llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
-      StringRef Buffer, uint32_t Alignment, uint32_t Size) override;
+      StringRef Buffer, uint32_t Alignment, uint32_t Size);
 
   /// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
   MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override;
@@ -215,6 +221,8 @@ class DwarfStreamer : public DwarfEmitter {
       WarningHandler(Warning, Context, nullptr);
   }
 
+  MCSection *getMCSection(DebugSectionKind SecKind);
+
   void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
                           const Offset2UnitMap &UnitMacroMap,
                           OffsetsStringPool &StringPool, uint64_t &OutOffset);
diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h
index 626fb53d90f9fa..5c811b668f0a31 100644
--- a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h
@@ -23,6 +23,53 @@ class DWARFUnit;
 
 namespace dwarf_linker {
 
+/// List of tracked debug tables.
+enum class DebugSectionKind : uint8_t {
+  DebugInfo = 0,
+  DebugLine,
+  DebugFrame,
+  DebugRange,
+  DebugRngLists,
+  DebugLoc,
+  DebugLocLists,
+  DebugARanges,
+  DebugAbbrev,
+  DebugMacinfo,
+  DebugMacro,
+  DebugAddr,
+  DebugStr,
+  DebugLineStr,
+  DebugStrOffsets,
+  DebugPubNames,
+  DebugPubTypes,
+  DebugNames,
+  AppleNames,
+  AppleNamespaces,
+  AppleObjC,
+  AppleTypes,
+  NumberOfEnumEntries // must be last
+};
+
+static constexpr size_t SectionKindsNum =
+    static_cast<size_t>(DebugSectionKind::NumberOfEnumEntries);
+
+static constexpr StringLiteral SectionNames[SectionKindsNum] = {
+    "debug_info",     "debug_line",     "debug_frame",       "debug_ranges",
+    "debug_rnglists", "debug_loc",      "debug_loclists",    "debug_aranges",
+    "debug_abbrev",   "debug_macinfo",  "debug_macro",       "debug_addr",
+    "debug_str",      "debug_line_str", "debug_str_offsets", "debug_pubnames",
+    "debug_pubtypes", "debug_names",    "apple_names",       "apple_namespac",
+    "apple_objc",     "apple_types"};
+
+/// Return the name of the section.
+static constexpr const StringLiteral &
+getSectionName(DebugSectionKind SectionKind) {
+  return SectionNames[static_cast<uint8_t>(SectionKind)];
+}
+
+/// Recognise the table name and match it with the DebugSectionKind.
+std::optional<DebugSectionKind> parseDebugTableName(StringRef Name);
+
 /// The base interface for DWARFLinker implementations.
 class DWARFLinkerBase {
 public:
diff --git a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h
index c38a9906940ec5..99506e28a6ae61 100644
--- a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h
@@ -89,30 +89,34 @@ namespace llvm {
 namespace dwarf_linker {
 namespace parallel {
 
-/// ExtraDwarfEmitter allows adding extra data to the DWARFLinker output.
-/// The finish() method should be called after all extra data are emitted.
-class ExtraDwarfEmitter {
-public:
-  virtual ~ExtraDwarfEmitter() = default;
-
-  /// Dump the file to the disk.
-  virtual void finish() = 0;
-
-  /// Emit section named SecName with data SecData.
-  virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0;
-
-  /// Emit the swift_ast section stored in \p Buffer.
-  virtual void emitSwiftAST(StringRef Buffer) = 0;
-
-  /// Emit the swift reflection section stored in \p Buffer.
-  virtual void emitSwiftReflectionSection(
-      llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
-      StringRef Buffer, uint32_t Alignment, uint32_t Size) = 0;
-
-  /// Returns underlying AsmPrinter.
-  virtual AsmPrinter &getAsmPrinter() const = 0;
+/// This structure keeps data of the concrete section.
+struct SectionDescriptorBase {
+  SectionDescriptorBase(DebugSectionKind SectionKind, dwarf::FormParams Format,
+                        llvm::endianness Endianess)
+      : SectionKind(SectionKind), Format(Format), Endianess(Endianess) {}
+  virtual ~SectionDescriptorBase() = default;
+  /// Returns section content.
+  virtual StringRef getContents() = 0;
+  /// Returns section kind.
+  DebugSectionKind getKind() { return SectionKind; }
+  /// Returns section name.
+  const StringLiteral &getName() const { return getSectionName(SectionKind); }
+  /// Returns endianess used by section.
+  llvm::endianness getEndianess() const { return Endianess; }
+  /// Returns FormParams used by section.
+  dwarf::FormParams getFormParams() const { return Format; }
+
+protected:
+  /// The section kind.
+  DebugSectionKind SectionKind = DebugSectionKind::NumberOfEnumEntries;
+  /// Output format.
+  dwarf::FormParams Format = {4, 4, dwarf::DWARF32};
+  llvm::endianness Endianess = llvm::endianness::little;
 };
 
+using SectionHandlerTy =
+    std::function<void(std::shared_ptr<SectionDescriptorBase> Section)>;
+
 class DWARFLinker : public DWARFLinkerBase {
 public:
   virtual ~DWARFLinker() = default;
@@ -122,12 +126,9 @@ class DWARFLinker : public DWARFLinkerBase {
   createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler,
                TranslatorFuncTy StringsTranslator = nullptr);
 
-  /// Creates emitter for output dwarf.
-  virtual Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
-                              raw_pwrite_stream &OutFile) = 0;
-
-  /// Returns previously created dwarf emitter. May be nullptr.
-  virtual ExtraDwarfEmitter *getEmitter() = 0;
+  /// Set output DWARF handler.
+  virtual void setOutputDWARFHandler(const Triple &TargetTriple,
+                                     SectionHandlerTy SectionHandler) = 0;
 };
 
 } // end of namespace parallel
diff --git a/llvm/lib/DWARFLinker/CMakeLists.txt b/llvm/lib/DWARFLinker/CMakeLists.txt
index 66bbf72165d642..f9d523757cd7c8 100644
--- a/llvm/lib/DWARFLinker/CMakeLists.txt
+++ b/llvm/lib/DWARFLinker/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_llvm_component_library(LLVMDWARFLinker
+  DWARFLinkerBase.cpp
   Utils.cpp
 
   ADDITIONAL_HEADER_DIRS
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index db294169ceb9b8..d2b4db3b0c6fb2 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -2644,19 +2644,22 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits(
 
 void DWARFLinker::copyInvariantDebugSection(DWARFContext &Dwarf) {
   TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getLocSection().Data,
-                                       "debug_loc");
+                                       DebugSectionKind::DebugLoc);
   TheDwarfEmitter->emitSectionContents(
-      Dwarf.getDWARFObj().getRangesSection().Data, "debug_ranges");
+      Dwarf.getDWARFObj().getRangesSection().Data,
+      DebugSectionKind::DebugRange);
   TheDwarfEmitter->emitSectionContents(
-      Dwarf.getDWARFObj().getFrameSection().Data, "debug_frame");
+      Dwarf.getDWARFObj().getFrameSection().Data, DebugSectionKind::DebugFrame);
   TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getArangesSection(),
-                                       "debug_aranges");
+                                       DebugSectionKind::DebugARanges);
   TheDwarfEmitter->emitSectionContents(
-      Dwarf.getDWARFObj().getAddrSection().Data, "debug_addr");
+      Dwarf.getDWARFObj().getAddrSection().Data, DebugSectionKind::DebugAddr);
   TheDwarfEmitter->emitSectionContents(
-      Dwarf.getDWARFObj().getRnglistsSection().Data, "debug_rnglists");
+      Dwarf.getDWARFObj().getRnglistsSection().Data,
+      DebugSectionKind::DebugRngLists);
   TheDwarfEmitter->emitSectionContents(
-      Dwarf.getDWARFObj().getLoclistsSection().Data, "debug_loclists");
+      Dwarf.getDWARFObj().getLoclistsSection().Data,
+      DebugSectionKind::DebugLocLists);
 }
 
 void DWARFLinker::addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader,
@@ -2848,7 +2851,7 @@ Error DWARFLinker::link() {
       SizeByObject[OptContext.File.FileName].Input =
           getDebugInfoSize(*OptContext.File.Dwarf);
       SizeByObject[OptContext.File.FileName].Output =
-          DIECloner(*this, TheDwarfEmitter.get(), OptContext.File, DIEAlloc,
+          DIECloner(*this, TheDwarfEmitter, OptContext.File, DIEAlloc,
                     OptContext.CompileUnits, Options.Update, DebugStrPool,
                     DebugLineStrPool, StringOffsetPool)
               .cloneAllCompileUnits(*OptContext.File.Dwarf, OptContext.File,
@@ -3011,7 +3014,7 @@ Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
   UnitListTy CompileUnits;
   CompileUnits.emplace_back(std::move(Unit.Unit));
   assert(TheDwarfEmitter);
-  DIECloner(*this, TheDwarfEmitter.get(), Unit.File, DIEAlloc, CompileUnits,
+  DIECloner(*this, TheDwarfEmitter, Unit.File, DIEAlloc, CompileUnits,
             Options.Update, DebugStrPool, DebugLineStrPool, StringOffsetPool)
       .cloneAllCompileUnits(*Unit.File.Dwarf, Unit.File,
                             Unit.File.Dwarf->isLittleEndian());
@@ -3030,16 +3033,4 @@ void DWARFLinker::verifyInput(const DWARFFile &File) {
   }
 }
 
-Error DWARFLinker::createEmitter(const Triple &TheTriple,
-                                 OutputFileType FileType,
-                                 raw_pwrite_stream &OutFile) {
-
-  TheDwarfEmitter = std::make_unique<DwarfStreamer>(
-      FileType, OutFile, StringsTranslator, WarningHandler);
-
-  return TheDwarfEmitter->init(TheTriple, "__DWARF");
-}
-
-DwarfEmitter *DWARFLinker::getEmitter() { return TheDwarfEmitter.get(); }
-
 } // namespace llvm
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
index 020bbb06449d3a..6d522370e440d1 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
@@ -30,6 +30,18 @@ using namespace llvm;
 using namespace dwarf_linker;
 using namespace dwarf_linker::classic;
 
+Expected<std::unique_ptr<DwarfStreamer>> DwarfStreamer::createStreamer(
+    const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType,
+    raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator,
+    DWARFLinkerBase::MessageHandlerTy Warning) {
+  std::unique_ptr<DwarfStreamer> Streamer =
+      std::make_unique<DwarfStreamer>(FileType, OutFile, Translator, Warning);
+  if (Error Err = Streamer->init(TheTriple, "__DWARF"))
+    return std::move(Err);
+
+  return std::move(Streamer);
+}
+
 Error DwarfStreamer::init(Triple TheTriple,
                           StringRef Swift5ReflectionSegmentName) {
   std::string ErrorStr;
@@ -212,30 +224,72 @@ void DwarfStreamer::emitDIE(DIE &Die) {
 }
 
 /// Emit contents of section SecName From Obj.
-void DwarfStreamer::emitSectionContents(StringRef SecData, StringRef SecName) {
-  MCSection *Section =
-      StringSwitch<MCSection *>(SecName)
-          .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection())
-          .Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection())
-          .Case("debug_ranges",
-                MC->getObjectFileInfo()->getDwarfRangesSection())
-          .Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
-          .Case("debug_aranges",
-                MC->getObjectFileInfo()->getDwarfARangesSection())
-          .Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection())
-          .Case("debug_rnglists",
-                MC->getObjectFileInfo()->getDwarfRnglistsSection())
-          .Case("debug_loclists",
-                MC->getObjectFileInfo()->getDwarfLoclistsSection())
-          .Default(nullptr);
-
-  if (Section) {
+void DwarfStreamer::emitSectionContents(StringRef SecData,
+                                        DebugSectionKind SecKind) {
+  if (SecData.empty())
+    return;
+
+  if (MCSection *Section = getMCSection(SecKind)) {
     MS->switchSection(Section);
 
     MS->emitBytes(SecData);
   }
 }
 
+MCSection *DwarfStreamer::getMCSection(DebugSectionKind SecKind) {
+  switch (SecKind) {
+  case DebugSectionKind::DebugInfo:
+    return MC->getObjectFileInfo()->getDwarfInfoSection();
+  case DebugSectionKind::DebugLine:
+    return MC->getObjectFileInfo()->getDwarfLineSection();
+  case DebugSectionKind::DebugFrame:
+    return MC->getObjectFileInfo()->getDwarfFrameSection();
+  case DebugSectionKind::DebugRange:
+    return MC->getObjectFileInfo()->getDwarfRangesSection();
+  case DebugSectionKind::DebugRngLists:
+    return MC->getObjectFileInfo()->getDwarfRnglistsSection();
+  case DebugSectionKind::DebugLoc:
+    return MC->getObjectFileInfo()->getDwarfLocSection();
+  case DebugSectionKind::DebugLocLists:
+    return MC->getObjectFileInfo()->getDwarfLoclistsSection();
+  case DebugSectionKind::DebugARanges:
+    return MC->getObjectFileInfo()->getDwarfARangesSection();
+  case DebugSectionKind::DebugAbbrev:
+    return MC->getObjectFileInfo()->getDwarfAbbrevSection();
+  case DebugSectionKind::DebugMacinfo:
+    return MC->getObjectFileInfo()->getDwarfMacinfoSection();
+  case DebugSectionKind::DebugMacro:
+    return MC->getObjectFileInfo()->getDwarfMacroSection();
+  case DebugSectionKind::DebugAddr:
+    return MC->getObjectFileInfo()->getDwarfAddrSection();
+  case DebugSectionKind::DebugStr:
+    return MC->getObjectFileInfo()->getDwarfStrSection();
+  case DebugSectionKind::DebugLineStr:
+    return MC->getObjectFileInfo()->getDwarfLineStrSection();
+  case DebugSectionKind::DebugStrOffsets:
+    return MC->getObjectFileInfo()->getDwarfStrOffSection();
+  case DebugSectionKind::DebugPubNames:
+    return MC->getObjectFileInfo()->getDwarfPubNamesSection();
+  case DebugSectionKind::DebugPubTypes:
+    return MC->getObjectFileInfo()->getDwarfPubTypesSection();
+  case DebugSectionKind::DebugNames:
+    return MC->getObjectFileInfo()->getDwarfDebugNamesSection();
+  case DebugSectionKind::AppleNames:
+    return MC->getObjectFileInfo()->getDwarfAccelNamesSection();
+  case DebugSectionKind::AppleNamespaces:
+    return MC->getObjectFileInfo()->getDwarfAccelNamespaceSection();
+  case DebugSectionKind::AppleObjC:
+    return MC->getObjectFileInfo()->getDwarfAccelObjCSection();
+  case DebugSectionKind::AppleTypes:
+    return MC->getObjectFileInfo()->getDwarfAccelTypesSection();
+  case DebugSectionKind::NumberOfEnumEntries:
+    llvm_unreachable("Unknown DebugSectionKind value");
+    break;
+  }
+
+  return nullptr;
+}
+
 /// Emit the debug_str section stored in \p Pool.
 void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) {
   Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection());
diff --git a/llvm/lib/DWARFLinker/DWARFLinkerBase.cpp b/llvm/lib/DWARFLinker/DWARFLinkerBase.cpp
new file mode 100644
index 00000000000000..7ba98d43274fa3
--- /dev/null
+++ b/llvm/lib/DWARFLinker/DWARFLinkerBase.cpp
@@ -0,0 +1,64 @@
+//=== DWARFLinkerBase.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DWARFLinker/DWARFLinkerBase.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace llvm;
+using namespace llvm::dwarf_linker;
+
+std::optional<DebugSectionKind>
+llvm::dwarf_linker::parseDebugTableName(llvm::StringRef SecName) {
+  return llvm::StringSwitch<std::optional<DebugSectionKind>>(
+             SecName.substr(SecName.find_first_not_of("._")))
+      .Case(getSectionName(DebugSectionKind::DebugInfo),
+            DebugSectionKind::DebugInfo)
+      .Case(getSectionName(DebugSectionKind::DebugLine),
+            DebugSectionKind::DebugLine)
+      .Case(getSectionName(DebugSectionKind::DebugFrame),
+            DebugSectionKind::DebugFrame)
+      .Case(getSectionName(DebugSectionKind::DebugRange),
+            DebugSectionKind::DebugRange)
+      .Case(getSectionName(DebugSectionKind::DebugRngLists),
+            DebugSectionKind::DebugRngLists)
+      .Case(getSectionName(DebugSectionKind::DebugLoc),
+            DebugSectionKind::DebugLoc)
+      .Case(getSectionName(DebugSectionKind::DebugLocLists),
+            DebugSectionKind::DebugLocLists)
+      .Case(getSectionName(DebugSectionKind::DebugARanges),
+            DebugSectionKind::DebugARanges)
+      .Case(getSectionName(DebugSectionKind::DebugAbbrev),
+            DebugSectionKind::DebugAbbrev)
+      .Case(getSectionName(DebugSectionKind::DebugMacinfo),
+            DebugSectionKind::DebugMacinfo)
+      .Case(getSectionName(DebugSectionKind::DebugMacro),
+            DebugSectionKind::DebugMacro)
+      .Case(getSectionName(DebugSectionKind::DebugAddr),
+            DebugSectionKind::DebugAddr)
+      .Case(getSectionName(DebugSectionKind::DebugStr),
+            DebugSectionKind::DebugStr)
+      .Case(getSectionName(DebugSectionKind::DebugLineStr),
+            DebugSectionKind::DebugLineStr)
+      .Case(getSectionName(DebugSectionKind::DebugStrOffsets),
+            DebugSectionKind::DebugStrOffsets)
+      .Case(getSectionName(DebugSectionKind::DebugPubNames),
+            DebugSectionKind::DebugPubNames)
+      .Case(getSectionName(DebugSectionKind::DebugPubTypes),
+            DebugSectionKind::DebugPubTypes)
+      .Case(getSectionName(DebugSectionKind::DebugNames),
+            DebugSectionKind::DebugNames)
+      .Case(getSectionName(DebugSectionKind::AppleNames),
+            DebugSectionKind::AppleNames)
+      .Case(getSectionName(DebugSectionKind::AppleNamespaces),
+            DebugSectionKind::AppleNamespaces)
+      .Case(getSectionName(DebugSectionKind::AppleObjC),
+            DebugSectionKind::AppleObjC)
+      .Case(getSectionName(DebugSectionKind::AppleTypes),
+            DebugSectionKind::AppleTypes)
+      .Default(std::nullopt);
+}
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.cpp
index 115167f0c7dc9a..b9edcb63a34015 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.cpp
@@ -120,72 +120,6 @@ Error DwarfEmitterImpl::init(Triple TheTriple,
   return Error::success();
 }
 
-void DwarfEmitterImpl::emitSwiftAST(StringRef Buffer) {
-  MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
-  SwiftASTSection->setAlignment(Align(32));
-  MS->switchSection(SwiftASTSection);
-  MS->emitBytes(Buffer);
-}
-
-/// Emit the swift reflection section stored in \p Buffer.
-void DwarfEmitterImpl::emitSwiftReflectionSection(
-    llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
-    StringRef Buffer, uint32_t Alignment, uint32_t) {
-  MCSection *ReflectionSection =
-      MOFI->getSwift5ReflectionSection(ReflSectionKind);
-  if (ReflectionSection == nullptr)
-    return;
-  ReflectionSection->setAlignment(Align(Alignment));
-  MS->switchSection(ReflectionSection);
-  MS->emitBytes(Buffer);
-}
-
-void DwarfEmitterImpl::emitSectionContents(StringRef SecData,
-                                           StringRef SecName) {
-  if (SecData.empty())
-    return;
-
-  if (MCSection *Section = switchSection(SecName)) {
-    MS->switchSection(Section);
-
-    MS->emitBytes(SecData);
-  }
-}
-
-MCSection *DwarfEmitterImpl::switchSection(StringRef SecName) {
-  return StringSwitch<MCSection *>(SecName)
-      .Case("debug_info", MC->getObjectFileInfo()->getDwarfInfoSection())
-      .Case("debug_abbrev", MC->getObjectFileInfo()->getDwarfAbbrevSection())
-      .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection())
-      .Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection())
-      .Case("debug_ranges", MC->getObjectFileInfo()->getDwarfRangesSection())
-      .Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
-      .Case("debug_aranges", MC->getObjectFileInfo()->getDwarfARangesSection())
-      .Case("debug_rnglists",
-            MC->getObjectFileInfo()->getDwarfRnglistsSection())
-      .Case("debug_loclists",
-            MC->getObjectFileInfo()->getDwarfLoclistsSection())
-      .Case("debug_macro", MC->getObjectFileInfo()->getDwarfMacroSection())
-      .Case("debug_macinfo", MC->getObjectFileInfo()->getDwarfMacinfoSection())
-      .Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection())
-      .Case("debug_str", MC->getObjectFileInfo()->getDwarfStrSection())
-      .Case("debug_line_str", MC->getObjectFileInfo()->getDwarfLineStrSection())
-      .Case("debug_str_offsets",
-            MC->getObjectFileInfo()->getDwarfStrOffSection())
-      .Case("debug_pubnames",
-            MC->getObjectFileInfo()->getDwarfPubNamesSection())
-      .Case("debug_pubtypes",
-            MC->getObjectFileInfo()->getDwarfPubTypesSection())
-      .Case("debug_names", MC->getObjectFileInfo()->getDwarfDebugNamesSection())
-      .Case("apple_names", MC->getObjectFileInfo()->getDwarfAccelNamesSection())
-      .Case("apple_namespac",
-            MC->getObjectFileInfo()->getDwarfAccelNamespaceSection())
-      .Case("apple_objc", MC->getObjectFileInfo()->getDwarfAccelObjCSection())
-      .Case("apple_types", MC->getObjectFileInfo()->getDwarfAccelTypesSection())
-
-      .Default(nullptr);
-}
-
 void DwarfEmitterImpl::emitAbbrevs(
     const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
     unsigned DwarfVersion) {
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.h b/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.h
index 89a33fe9419153..71351f1d8c1cee 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.h
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.h
@@ -45,7 +45,7 @@ using CompUnitIDToIdx = DenseMap<unsigned, unsigned>;
 /// This class emits DWARF data to the output stream. It emits already
 /// generated section data and specific data, which could not be generated
 /// by CompileUnit.
-class DwarfEmitterImpl : public ExtraDwarfEmitter {
+class DwarfEmitterImpl {
 public:
   DwarfEmitterImpl(DWARFLinker::OutputFileType OutFileType,
                    raw_pwrite_stream &OutFile)
@@ -58,21 +58,7 @@ class DwarfEmitterImpl : public ExtraDwarfEmitter {
   const Triple &getTargetTriple() { return MC->getTargetTriple(); }
 
   /// Dump the file to the disk.
-  void finish() override { MS->finish(); }
-
-  /// Returns AsmPrinter.
-  AsmPrinter &getAsmPrinter() const override { return *Asm; }
-
-  /// Emit the swift_ast section stored in \p Buffer.
-  void emitSwiftAST(StringRef Buffer) override;
-
-  /// Emit the swift reflection section stored in \p Buffer.
-  void emitSwiftReflectionSection(
-      llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
-      StringRef Buffer, uint32_t Alignment, uint32_t) override;
-
-  /// Emit specified section data.
-  void emitSectionContents(StringRef SecData, StringRef SecName) override;
+  void finish() { MS->finish(); }
 
   /// Emit abbreviations.
   void emitAbbrevs(const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
@@ -115,8 +101,6 @@ class DwarfEmitterImpl : public ExtraDwarfEmitter {
                        const StringEntryToDwarfStringPoolEntryMap &Strings,
                        uint64_t &NextOffset, MCSection *OutSection);
 
-  MCSection *switchSection(StringRef SecName);
-
   /// \defgroup MCObjects MC layer objects constructed by the streamer
   /// @{
   std::unique_ptr<MCRegisterInfo> MRI;
@@ -135,7 +119,8 @@ class DwarfEmitterImpl : public ExtraDwarfEmitter {
 
   /// The output file we stream the linked Dwarf to.
   raw_pwrite_stream &OutFile;
-  DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object;
+  DWARFLinkerBase::OutputFileType OutFileType =
+      DWARFLinkerBase::OutputFileType::Object;
 
   uint64_t DebugInfoSectionSize = 0;
 };
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
index 6ed284a66a8561..212264714c2a57 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
@@ -1229,8 +1229,9 @@ void CompileUnit::cloneDieAttrExpression(
   }
 }
 
-Error CompileUnit::cloneAndEmit(std::optional<Triple> TargetTriple,
-                                TypeUnit *ArtificialTypeUnit) {
+Error CompileUnit::cloneAndEmit(
+    std::optional<std::reference_wrapper<const Triple>> TargetTriple,
+    TypeUnit *ArtificialTypeUnit) {
   BumpPtrAllocator Allocator;
 
   DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE();
@@ -1247,18 +1248,17 @@ Error CompileUnit::cloneAndEmit(std::optional<Triple> TargetTriple,
       std::nullopt, std::nullopt, Allocator, ArtificialTypeUnit);
   setOutUnitDIE(OutCUDie.first);
 
-  if (getGlobalData().getOptions().NoOutput || (OutCUDie.first == nullptr))
+  if (!TargetTriple.has_value() || (OutCUDie.first == nullptr))
     return Error::success();
 
-  assert(TargetTriple.has_value());
-  if (Error Err = cloneAndEmitLineTable(*TargetTriple))
+  if (Error Err = cloneAndEmitLineTable((*TargetTriple).get()))
     return Err;
 
   if (Error Err = cloneAndEmitDebugMacro())
     return Err;
 
   getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
-  if (Error Err = emitDebugInfo(*TargetTriple))
+  if (Error Err = emitDebugInfo((*TargetTriple).get()))
     return Err;
 
   // ASSUMPTION: .debug_info section should already be emitted at this point.
@@ -1514,7 +1514,7 @@ TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
   return Entry;
 }
 
-Error CompileUnit::cloneAndEmitLineTable(Triple &TargetTriple) {
+Error CompileUnit::cloneAndEmitLineTable(const Triple &TargetTriple) {
   const DWARFDebugLine::LineTable *InputLineTable =
       getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit());
   if (InputLineTable == nullptr) {
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
index abd978e7c0e4bb..20e20222a4ac0a 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
@@ -401,8 +401,9 @@ class alignas(8) CompileUnit : public DwarfUnit {
   const RangesTy &getFunctionRanges() const { return Ranges; }
 
   /// Clone and emit this compilation unit.
-  Error cloneAndEmit(std::optional<Triple> TargetTriple,
-                     TypeUnit *ArtificialTypeUnit);
+  Error
+  cloneAndEmit(std::optional<std::reference_wrapper<const Triple>> TargetTriple,
+               TypeUnit *ArtificialTypeUnit);
 
   /// Clone and emit debug locations(.debug_loc/.debug_loclists).
   Error cloneAndEmitDebugLocations();
@@ -422,7 +423,7 @@ class alignas(8) CompileUnit : public DwarfUnit {
            BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit);
 
   // Clone and emit line table.
-  Error cloneAndEmitLineTable(Triple &TargetTriple);
+  Error cloneAndEmitLineTable(const Triple &TargetTriple);
 
   /// Clone attribute location axpression.
   void cloneDieAttrExpression(const DWARFExpression &InputExpression,
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h
index b641343ac808c7..38c261a8106fcd 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h
@@ -39,9 +39,6 @@ struct DWARFLinkerOptions {
   /// Verify the input DWARF.
   bool VerifyInputDWARF = false;
 
-  /// Do not emit output.
-  bool NoOutput = false;
-
   /// Do not unique types according to ODR
   bool NoODR = false;
 
@@ -59,13 +56,14 @@ struct DWARFLinkerOptions {
   unsigned Threads = 1;
 
   /// The accelerator table kinds
-  SmallVector<DWARFLinker::AccelTableKind, 1> AccelTables;
+  SmallVector<DWARFLinkerBase::AccelTableKind, 1> AccelTables;
 
   /// Prepend path for the clang modules.
   std::string PrependPath;
 
   /// input verification handler(it might be called asynchronously).
-  DWARFLinker::InputVerificationHandlerTy InputVerificationHandler = nullptr;
+  DWARFLinkerBase::InputVerificationHandlerTy InputVerificationHandler =
+      nullptr;
 
   /// A list of all .swiftinterface files referenced by the debug
   /// info, mapping Module name to path on disk. The entries need to
@@ -74,12 +72,12 @@ struct DWARFLinkerOptions {
   /// this is dsymutil specific fag.
   ///
   /// (it might be called asynchronously).
-  DWARFLinker::SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr;
+  DWARFLinkerBase::SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr;
 
   /// A list of remappings to apply to file paths.
   ///
   /// (it might be called asynchronously).
-  DWARFLinker::ObjectPrefixMapTy *ObjectPrefixMap = nullptr;
+  DWARFLinkerBase::ObjectPrefixMapTy *ObjectPrefixMap = nullptr;
 };
 
 class DWARFLinkerImpl;
@@ -147,6 +145,19 @@ class LinkingGlobalData {
     });
   }
 
+  /// Set target triple.
+  void setTargetTriple(const Triple &TargetTriple) {
+    this->TargetTriple = TargetTriple;
+  }
+
+  /// Optionally return target triple.
+  std::optional<std::reference_wrapper<const Triple>> getTargetTriple() {
+    if (TargetTriple)
+      return std::cref(*TargetTriple);
+
+    return std::nullopt;
+  }
+
 protected:
   llvm::parallel::PerThreadBumpPtrAllocator Allocator;
   StringPool Strings;
@@ -154,6 +165,10 @@ class LinkingGlobalData {
   DWARFLinkerOptions Options;
   MessageHandlerTy WarningHandler;
   MessageHandlerTy ErrorHandler;
+
+  /// Triple for output data. May be not set if generation of output
+  /// data is not requested.
+  std::optional<Triple> TargetTriple;
 };
 
 } // end of namespace parallel
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
index b0b819cf977850..f127214927a5d3 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
@@ -32,11 +32,9 @@ DWARFLinkerImpl::DWARFLinkerImpl(MessageHandlerTy ErrorHandler,
 DWARFLinkerImpl::LinkContext::LinkContext(LinkingGlobalData &GlobalData,
                                           DWARFFile &File,
                                           StringMap<uint64_t> &ClangModules,
-                                          std::atomic<size_t> &UniqueUnitID,
-                                          std::optional<Triple> TargetTriple)
+                                          std::atomic<size_t> &UniqueUnitID)
     : OutputSections(GlobalData), InputDWARFFile(File),
-      ClangModules(ClangModules), TargetTriple(TargetTriple),
-      UniqueUnitID(UniqueUnitID) {
+      ClangModules(ClangModules), UniqueUnitID(UniqueUnitID) {
 
   if (File.Dwarf) {
     if (!File.Dwarf->compile_units().empty())
@@ -63,25 +61,10 @@ void DWARFLinkerImpl::LinkContext::addModulesCompileUnit(
   ModulesCompileUnits.emplace_back(std::move(Unit));
 }
 
-Error DWARFLinkerImpl::createEmitter(const Triple &TheTriple,
-                                     OutputFileType FileType,
-                                     raw_pwrite_stream &OutFile) {
-
-  TheDwarfEmitter = std::make_unique<DwarfEmitterImpl>(FileType, OutFile);
-
-  return TheDwarfEmitter->init(TheTriple, "__DWARF");
-}
-
-ExtraDwarfEmitter *DWARFLinkerImpl::getEmitter() {
-  return TheDwarfEmitter.get();
-}
-
 void DWARFLinkerImpl::addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader,
                                     CompileUnitHandlerTy OnCUDieLoaded) {
   ObjectContexts.emplace_back(std::make_unique<LinkContext>(
-      GlobalData, File, ClangModules, UniqueUnitID,
-      (TheDwarfEmitter.get() == nullptr ? std::optional<Triple>(std::nullopt)
-                                        : TheDwarfEmitter->getTargetTriple())));
+      GlobalData, File, ClangModules, UniqueUnitID));
 
   if (ObjectContexts.back()->InputDWARFFile.Dwarf) {
     for (const std::unique_ptr<DWARFUnit> &CU :
@@ -117,8 +100,9 @@ Error DWARFLinkerImpl::link() {
                                     0, dwarf::DwarfFormat::DWARF32};
   llvm::endianness GlobalEndianness = llvm::endianness::native;
 
-  if (TheDwarfEmitter) {
-    GlobalEndianness = TheDwarfEmitter->getTargetTriple().isLittleEndian()
+  if (std::optional<std::reference_wrapper<const Triple>> CurTriple =
+          GlobalData.getTargetTriple()) {
+    GlobalEndianness = (*CurTriple).get().isLittleEndian()
                            ? llvm::endianness::little
                            : llvm::endianness::big;
   }
@@ -147,7 +131,7 @@ Error DWARFLinkerImpl::link() {
     if (GlobalData.getOptions().VerifyInputDWARF)
       verifyInput(Context->InputDWARFFile);
 
-    if (!TheDwarfEmitter)
+    if (!GlobalData.getTargetTriple())
       GlobalEndianness = Context->getEndianness();
     GlobalFormat.AddrSize =
         std::max(GlobalFormat.AddrSize, Context->getFormParams().AddrSize);
@@ -173,9 +157,9 @@ Error DWARFLinkerImpl::link() {
   }
 
   if (GlobalFormat.AddrSize == 0) {
-    if (TheDwarfEmitter)
-      GlobalFormat.AddrSize =
-          TheDwarfEmitter->getTargetTriple().isArch32Bit() ? 4 : 8;
+    if (std::optional<std::reference_wrapper<const Triple>> TargetTriple =
+            GlobalData.getTargetTriple())
+      GlobalFormat.AddrSize = (*TargetTriple).get().isArch32Bit() ? 4 : 8;
     else
       GlobalFormat.AddrSize = 8;
   }
@@ -225,12 +209,10 @@ Error DWARFLinkerImpl::link() {
                                                   ->getValue()
                                                   .load()
                                                   ->Children.empty()) {
-    std::optional<Triple> OutTriple = TheDwarfEmitter.get() == nullptr
-                                          ? std::optional<Triple>(std::nullopt)
-                                          : TheDwarfEmitter->getTargetTriple();
-
-    if (Error Err = ArtificialTypeUnit.get()->finishCloningAndEmit(OutTriple))
-      return Err;
+    if (GlobalData.getTargetTriple().has_value())
+      if (Error Err = ArtificialTypeUnit.get()->finishCloningAndEmit(
+              (*GlobalData.getTargetTriple()).get()))
+        return Err;
   }
 
   // At this stage each compile units are cloned to their own set of debug
@@ -258,8 +240,6 @@ Error DWARFLinkerImpl::validateAndUpdateOptions() {
     return createStringError(std::errc::invalid_argument,
                              "target DWARF version is not set");
 
-  GlobalData.Options.NoOutput = TheDwarfEmitter.get() == nullptr;
-
   if (GlobalData.getOptions().Verbose && GlobalData.getOptions().Threads != 1) {
     GlobalData.Options.Threads = 1;
     GlobalData.warn(
@@ -690,7 +670,8 @@ void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
           if (CU.isClangModule() ||
               GlobalData.getOptions().UpdateIndexTablesOnly ||
               CU.getContaingFile().Addresses->hasValidRelocs()) {
-            if (Error Err = CU.cloneAndEmit(TargetTriple, ArtificialTypeUnit))
+            if (Error Err = CU.cloneAndEmit(GlobalData.getTargetTriple(),
+                                            ArtificialTypeUnit))
               return std::move(Err);
           }
 
@@ -727,7 +708,7 @@ void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
 }
 
 Error DWARFLinkerImpl::LinkContext::emitInvariantSections() {
-  if (GlobalData.getOptions().NoOutput)
+  if (!GlobalData.getTargetTriple().has_value())
     return Error::success();
 
   getOrCreateSectionDescriptor(DebugSectionKind::DebugLoc).OS
@@ -749,7 +730,7 @@ Error DWARFLinkerImpl::LinkContext::emitInvariantSections() {
 }
 
 Error DWARFLinkerImpl::LinkContext::cloneAndEmitDebugFrame() {
-  if (GlobalData.getOptions().NoOutput)
+  if (!GlobalData.getTargetTriple().has_value())
     return Error::success();
 
   if (InputDWARFFile.Dwarf.get() == nullptr)
@@ -870,8 +851,9 @@ void DWARFLinkerImpl::LinkContext::emitFDE(uint32_t CIEOffset,
 }
 
 void DWARFLinkerImpl::glueCompileUnitsAndWriteToTheOutput() {
-  if (GlobalData.getOptions().NoOutput)
+  if (!GlobalData.getTargetTriple().has_value())
     return;
+  assert(SectionHandler);
 
   // Go through all object files, all compile units and assign
   // offsets to them.
@@ -1154,21 +1136,23 @@ void DWARFLinkerImpl::emitCommonSectionsAndWriteCompileUnitsToTheOutput() {
                          AccelTableKind::DebugNames))
     CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugNames);
 
-  const Triple &TargetTriple = TheDwarfEmitter->getTargetTriple();
-
   // Emit .debug_str and .debug_line_str sections.
   TG.spawn([&]() { emitStringSections(); });
 
   if (llvm::is_contained(GlobalData.Options.AccelTables,
                          AccelTableKind::Apple)) {
     // Emit apple accelerator sections.
-    TG.spawn([&]() { emitAppleAcceleratorSections(TargetTriple); });
+    TG.spawn([&]() {
+      emitAppleAcceleratorSections((*GlobalData.getTargetTriple()).get());
+    });
   }
 
   if (llvm::is_contained(GlobalData.Options.AccelTables,
                          AccelTableKind::DebugNames)) {
     // Emit .debug_names section.
-    TG.spawn([&]() { emitDWARFv5DebugNamesSection(TargetTriple); });
+    TG.spawn([&]() {
+      emitDWARFv5DebugNamesSection((*GlobalData.getTargetTriple()).get());
+    });
   }
 
   // Write compile units to the output file.
@@ -1419,33 +1403,17 @@ void DWARFLinkerImpl::cleanupDataAfterDWARFOutputIsWritten() {
 }
 
 void DWARFLinkerImpl::writeCompileUnitsToTheOutput() {
-  bool HasAbbreviations = false;
-
   // Enumerate all sections and store them into the final emitter.
   forEachObjectSectionsSet([&](OutputSections &Sections) {
-    Sections.forEach([&](SectionDescriptor &OutSection) {
-      if (!HasAbbreviations && !OutSection.getContents().empty() &&
-          OutSection.getKind() == DebugSectionKind::DebugAbbrev)
-        HasAbbreviations = true;
-
+    Sections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) {
       // Emit section content.
-      TheDwarfEmitter->emitSectionContents(OutSection.getContents(),
-                                           OutSection.getName());
-      OutSection.clearSectionContent();
+      SectionHandler(OutSection);
     });
   });
-
-  if (!HasAbbreviations) {
-    const SmallVector<std::unique_ptr<DIEAbbrev>> Abbreviations;
-    TheDwarfEmitter->emitAbbrevs(Abbreviations, 3);
-  }
 }
 
 void DWARFLinkerImpl::writeCommonSectionsToTheOutput() {
-  CommonSections.forEach([&](SectionDescriptor &OutSection) {
-    // Emit section content.
-    TheDwarfEmitter->emitSectionContents(OutSection.getContents(),
-                                         OutSection.getName());
-    OutSection.clearSectionContent();
+  CommonSections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) {
+    SectionHandler(OutSection);
   });
 }
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h
index b4331df5e323d7..527c7a0ec3642f 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h
@@ -29,12 +29,6 @@ class DWARFLinkerImpl : public DWARFLinker {
                   MessageHandlerTy WarningHandler,
                   TranslatorFuncTy StringsTranslator);
 
-  /// Create debug info emitter.
-  Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
-                      raw_pwrite_stream &OutFile) override;
-
-  ExtraDwarfEmitter *getEmitter() override;
-
   /// Add object file to be linked. Pre-load compile unit die. Call
   /// \p OnCUDieLoaded for each compile unit die. If specified \p File
   /// has reference to the Clang module then such module would be
@@ -49,6 +43,14 @@ class DWARFLinkerImpl : public DWARFLinker {
   /// Link debug info for added files.
   Error link() override;
 
+  /// Set output DWARF handler. May be not set if output generation is not
+  /// necessary.
+  void setOutputDWARFHandler(const Triple &TargetTriple,
+                             SectionHandlerTy SectionHandler) override {
+    GlobalData.setTargetTriple(TargetTriple);
+    this->SectionHandler = SectionHandler;
+  }
+
   /// \defgroup Methods setting various linking options:
   ///
   /// @{
@@ -190,8 +192,6 @@ class DWARFLinkerImpl : public DWARFLinker {
 
     StringMap<uint64_t> &ClangModules;
 
-    std::optional<Triple> TargetTriple;
-
     /// Flag indicating that new inter-connected compilation units were
     /// discovered. It is used for restarting units processing
     /// if new inter-connected units were found.
@@ -204,8 +204,7 @@ class DWARFLinkerImpl : public DWARFLinker {
 
     LinkContext(LinkingGlobalData &GlobalData, DWARFFile &File,
                 StringMap<uint64_t> &ClangModules,
-                std::atomic<size_t> &UniqueUnitID,
-                std::optional<Triple> TargetTriple);
+                std::atomic<size_t> &UniqueUnitID);
 
     /// Check whether specified \p CUDie is a Clang module reference.
     /// if \p Quiet is false then display error messages.
@@ -364,8 +363,8 @@ class DWARFLinkerImpl : public DWARFLinker {
   /// Common sections.
   OutputSections CommonSections;
 
-  /// The emitter of final dwarf file.
-  std::unique_ptr<DwarfEmitterImpl> TheDwarfEmitter;
+  /// Hanler for output sections.
+  SectionHandlerTy SectionHandler = nullptr;
 
   /// Overall compile units number.
   uint64_t OverallNumberOfCU = 0;
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp
index 397411895a8e3e..3030aa2c39b234 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp
@@ -337,11 +337,11 @@ uint8_t TypeUnit::getSizeByAttrForm(dwarf::Form Form) const {
   llvm_unreachable("Unsupported Attr Form");
 }
 
-Error TypeUnit::finishCloningAndEmit(std::optional<Triple> TargetTriple) {
+Error TypeUnit::finishCloningAndEmit(const Triple &TargetTriple) {
   BumpPtrAllocator Allocator;
   createDIETree(Allocator);
 
-  if (getGlobalData().getOptions().NoOutput || (getOutUnitDIE() == nullptr))
+  if (getOutUnitDIE() == nullptr)
     return Error::success();
 
   // Create sections ahead so that they should not be created asynchronously
@@ -360,14 +360,12 @@ Error TypeUnit::finishCloningAndEmit(std::optional<Triple> TargetTriple) {
 
   // Add task for emitting .debug_line section.
   if (!LineTable.Prologue.FileNames.empty()) {
-    Tasks.push_back([&]() -> Error {
-      assert(TargetTriple.has_value());
-      return emitDebugLine(*TargetTriple, LineTable);
-    });
+    Tasks.push_back(
+        [&]() -> Error { return emitDebugLine(TargetTriple, LineTable); });
   }
 
   // Add task for emitting .debug_info section.
-  Tasks.push_back([&]() -> Error { return emitDebugInfo(*TargetTriple); });
+  Tasks.push_back([&]() -> Error { return emitDebugInfo(TargetTriple); });
 
   // Add task for emitting Pub accelerator sections.
   if (llvm::is_contained(GlobalData.getOptions().AccelTables,
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.h
index 0944de8d1315a9..328da5c0570b16 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.h
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.h
@@ -31,7 +31,7 @@ class TypeUnit : public DwarfUnit {
   void createDIETree(BumpPtrAllocator &Allocator);
 
   /// Emits resulting dwarf based on information from DIE tree.
-  Error finishCloningAndEmit(std::optional<Triple> TargetTriple);
+  Error finishCloningAndEmit(const Triple &TargetTriple);
 
   /// Returns global type pool.
   TypePool &getTypePool() { return Types; }
diff --git a/llvm/lib/DWARFLinker/Parallel/OutputSections.cpp b/llvm/lib/DWARFLinker/Parallel/OutputSections.cpp
index cd1205b60f85ba..d03f9b40d49021 100644
--- a/llvm/lib/DWARFLinker/Parallel/OutputSections.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/OutputSections.cpp
@@ -15,59 +15,6 @@ using namespace llvm;
 using namespace dwarf_linker;
 using namespace dwarf_linker::parallel;
 
-std::optional<DebugSectionKind>
-dwarf_linker::parallel::parseDebugTableName(llvm::StringRef SecName) {
-  return llvm::StringSwitch<std::optional<DebugSectionKind>>(
-             SecName.substr(SecName.find_first_not_of("._")))
-      .Case(getSectionName(DebugSectionKind::DebugInfo),
-            DebugSectionKind::DebugInfo)
-      .Case(getSectionName(DebugSectionKind::DebugLine),
-            DebugSectionKind::DebugLine)
-      .Case(getSectionName(DebugSectionKind::DebugFrame),
-            DebugSectionKind::DebugFrame)
-      .Case(getSectionName(DebugSectionKind::DebugRange),
-            DebugSectionKind::DebugRange)
-      .Case(getSectionName(DebugSectionKind::DebugRngLists),
-            DebugSectionKind::DebugRngLists)
-      .Case(getSectionName(DebugSectionKind::DebugLoc),
-            DebugSectionKind::DebugLoc)
-      .Case(getSectionName(DebugSectionKind::DebugLocLists),
-            DebugSectionKind::DebugLocLists)
-      .Case(getSectionName(DebugSectionKind::DebugARanges),
-            DebugSectionKind::DebugARanges)
-      .Case(getSectionName(DebugSectionKind::DebugAbbrev),
-            DebugSectionKind::DebugAbbrev)
-      .Case(getSectionName(DebugSectionKind::DebugMacinfo),
-            DebugSectionKind::DebugMacinfo)
-      .Case(getSectionName(DebugSectionKind::DebugMacro),
-            DebugSectionKind::DebugMacro)
-      .Case(getSectionName(DebugSectionKind::DebugAddr),
-            DebugSectionKind::DebugAddr)
-      .Case(getSectionName(DebugSectionKind::DebugStr),
-            DebugSectionKind::DebugStr)
-      .Case(getSectionName(DebugSectionKind::DebugLineStr),
-            DebugSectionKind::DebugLineStr)
-      .Case(getSectionName(DebugSectionKind::DebugStrOffsets),
-            DebugSectionKind::DebugStrOffsets)
-      .Case(getSectionName(DebugSectionKind::DebugPubNames),
-            DebugSectionKind::DebugPubNames)
-      .Case(getSectionName(DebugSectionKind::DebugPubTypes),
-            DebugSectionKind::DebugPubTypes)
-      .Case(getSectionName(DebugSectionKind::DebugNames),
-            DebugSectionKind::DebugNames)
-      .Case(getSectionName(DebugSectionKind::AppleNames),
-            DebugSectionKind::AppleNames)
-      .Case(getSectionName(DebugSectionKind::AppleNamespaces),
-            DebugSectionKind::AppleNamespaces)
-      .Case(getSectionName(DebugSectionKind::AppleObjC),
-            DebugSectionKind::AppleObjC)
-      .Case(getSectionName(DebugSectionKind::AppleTypes),
-            DebugSectionKind::AppleTypes)
-      .Default(std::nullopt);
-
-  return std::nullopt;
-}
-
 DebugDieRefPatch::DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU,
                                    CompileUnit *RefCU, uint32_t RefIdx)
     : SectionPatch({PatchOffset}),
diff --git a/llvm/lib/DWARFLinker/Parallel/OutputSections.h b/llvm/lib/DWARFLinker/Parallel/OutputSections.h
index b9df2228920a94..a21e4b2b75a503 100644
--- a/llvm/lib/DWARFLinker/Parallel/OutputSections.h
+++ b/llvm/lib/DWARFLinker/Parallel/OutputSections.h
@@ -34,51 +34,6 @@ namespace parallel {
 
 class TypeUnit;
 
-/// List of tracked debug tables.
-enum class DebugSectionKind : uint8_t {
-  DebugInfo = 0,
-  DebugLine,
-  DebugFrame,
-  DebugRange,
-  DebugRngLists,
-  DebugLoc,
-  DebugLocLists,
-  DebugARanges,
-  DebugAbbrev,
-  DebugMacinfo,
-  DebugMacro,
-  DebugAddr,
-  DebugStr,
-  DebugLineStr,
-  DebugStrOffsets,
-  DebugPubNames,
-  DebugPubTypes,
-  DebugNames,
-  AppleNames,
-  AppleNamespaces,
-  AppleObjC,
-  AppleTypes,
-  NumberOfEnumEntries // must be last
-};
-constexpr static size_t SectionKindsNum =
-    static_cast<size_t>(DebugSectionKind::NumberOfEnumEntries);
-
-static constexpr StringLiteral SectionNames[SectionKindsNum] = {
-    "debug_info",     "debug_line",     "debug_frame",       "debug_ranges",
-    "debug_rnglists", "debug_loc",      "debug_loclists",    "debug_aranges",
-    "debug_abbrev",   "debug_macinfo",  "debug_macro",       "debug_addr",
-    "debug_str",      "debug_line_str", "debug_str_offsets", "debug_pubnames",
-    "debug_pubtypes", "debug_names",    "apple_names",       "apple_namespac",
-    "apple_objc",     "apple_types"};
-
-static constexpr const StringLiteral &
-getSectionName(DebugSectionKind SectionKind) {
-  return SectionNames[static_cast<uint8_t>(SectionKind)];
-}
-
-/// Recognise the table name and match it with the DebugSectionKind.
-std::optional<DebugSectionKind> parseDebugTableName(StringRef Name);
-
 /// There are fields(sizes, offsets) which should be updated after
 /// sections are generated. To remember offsets and related data
 /// the descendants of SectionPatch structure should be used.
@@ -194,12 +149,13 @@ class OutputSections;
 
 /// This structure is used to keep data of the concrete section.
 /// Like data bits, list of patches, format.
-struct SectionDescriptor {
+struct SectionDescriptor : SectionDescriptorBase {
   friend OutputSections;
 
   SectionDescriptor(DebugSectionKind SectionKind, LinkingGlobalData &GlobalData,
                     dwarf::FormParams Format, llvm::endianness Endianess)
-      : OS(Contents), ListDebugStrPatch(&GlobalData.getAllocator()),
+      : SectionDescriptorBase(SectionKind, Format, Endianess), OS(Contents),
+        ListDebugStrPatch(&GlobalData.getAllocator()),
         ListDebugLineStrPatch(&GlobalData.getAllocator()),
         ListDebugRangePatch(&GlobalData.getAllocator()),
         ListDebugLocPatch(&GlobalData.getAllocator()),
@@ -211,10 +167,9 @@ struct SectionDescriptor {
         ListDebugTypeStrPatch(&GlobalData.getAllocator()),
         ListDebugTypeLineStrPatch(&GlobalData.getAllocator()),
         ListDebugTypeDeclFilePatch(&GlobalData.getAllocator()),
-        GlobalData(GlobalData), SectionKind(SectionKind), Format(Format),
-        Endianess(Endianess) {}
+        GlobalData(GlobalData) {}
 
-  /// Erase whole section contents(data bits, list of patches).
+  /// Erase whole section content(data bits, list of patches).
   void clearAllSectionData();
 
   /// Erase only section output data bits.
@@ -263,7 +218,7 @@ struct SectionDescriptor {
   void setSizesForSectionCreatedByAsmPrinter();
 
   /// Returns section content.
-  StringRef getContents() {
+  StringRef getContents() override {
     if (SectionOffsetInsideAsmPrinterOutputStart == 0)
       return StringRef(Contents.data(), Contents.size());
 
@@ -311,18 +266,6 @@ struct SectionDescriptor {
   /// Write specified \p Value of \p AttrForm to the \p PatchOffset.
   void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val);
 
-  /// Returns section kind.
-  DebugSectionKind getKind() { return SectionKind; }
-
-  /// Returns section name.
-  const StringLiteral &getName() const { return getSectionName(SectionKind); }
-
-  /// Returns endianess used by section.
-  llvm::endianness getEndianess() const { return Endianess; }
-
-  /// Returns FormParams used by section.
-  dwarf::FormParams getFormParams() const { return Format; }
-
   /// Returns integer value of \p Size located by specified \p PatchOffset.
   uint64_t getIntVal(uint64_t PatchOffset, unsigned Size);
 
@@ -344,9 +287,6 @@ struct SectionDescriptor {
 
   LinkingGlobalData &GlobalData;
 
-  /// The section kind.
-  DebugSectionKind SectionKind = DebugSectionKind::NumberOfEnumEntries;
-
   /// Section data bits.
   OutSectionDataTy Contents;
 
@@ -355,10 +295,6 @@ struct SectionDescriptor {
   /// real section content inside elf file.
   size_t SectionOffsetInsideAsmPrinterOutputStart = 0;
   size_t SectionOffsetInsideAsmPrinterOutputEnd = 0;
-
-  /// Output format.
-  dwarf::FormParams Format = {4, 4, dwarf::DWARF32};
-  llvm::endianness Endianess = llvm::endianness::little;
 };
 
 /// This class keeps contents and offsets to the debug sections. Any objects
@@ -387,7 +323,7 @@ class OutputSections {
               .str()
               .c_str());
 
-    return It->second;
+    return *It->second;
   }
 
   /// Returns descriptor for the specified section of \p SectionKind.
@@ -402,7 +338,9 @@ class OutputSections {
               .str()
               .c_str());
 
-    return It->second;
+    assert(It->second.get() != nullptr);
+
+    return *It->second;
   }
 
   /// Returns descriptor for the specified section of \p SectionKind.
@@ -414,7 +352,7 @@ class OutputSections {
     if (It == SectionDescriptors.end())
       return std::nullopt;
 
-    return &It->second;
+    return It->second.get();
   }
 
   /// Returns descriptor for the specified section of \p SectionKind.
@@ -426,26 +364,44 @@ class OutputSections {
     if (It == SectionDescriptors.end())
       return std::nullopt;
 
-    return &It->second;
+    return It->second.get();
   }
 
   /// Returns descriptor for the specified section of \p SectionKind.
   /// If descriptor does not exist then creates it.
   SectionDescriptor &
   getOrCreateSectionDescriptor(DebugSectionKind SectionKind) {
-    return SectionDescriptors
-        .try_emplace(SectionKind, SectionKind, GlobalData, Format, Endianness)
-        .first->second;
+    SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind);
+
+    if (It == SectionDescriptors.end()) {
+      SectionDescriptor *Section =
+          new SectionDescriptor(SectionKind, GlobalData, Format, Endianness);
+      auto Result = SectionDescriptors.try_emplace(SectionKind, Section);
+      assert(Result.second);
+
+      It = Result.first;
+    }
+
+    return *It->second;
   }
 
   /// Erases data of all sections.
   void eraseSections() {
     for (auto &Section : SectionDescriptors)
-      Section.second.clearAllSectionData();
+      Section.second->clearAllSectionData();
   }
 
   /// Enumerate all sections and call \p Handler for each.
   void forEach(function_ref<void(SectionDescriptor &)> Handler) {
+    for (auto &Section : SectionDescriptors) {
+      assert(Section.second.get() != nullptr);
+      Handler(*(Section.second));
+    }
+  }
+
+  /// Enumerate all sections and call \p Handler for each.
+  void forEach(
+      function_ref<void(std::shared_ptr<SectionDescriptor> Section)> Handler) {
     for (auto &Section : SectionDescriptors)
       Handler(Section.second);
   }
@@ -456,10 +412,11 @@ class OutputSections {
   void assignSectionsOffsetAndAccumulateSize(
       std::array<uint64_t, SectionKindsNum> &SectionSizesAccumulator) {
     for (auto &Section : SectionDescriptors) {
-      Section.second.StartOffset = SectionSizesAccumulator[static_cast<uint8_t>(
-          Section.second.getKind())];
-      SectionSizesAccumulator[static_cast<uint8_t>(Section.second.getKind())] +=
-          Section.second.getContents().size();
+      Section.second->StartOffset =
+          SectionSizesAccumulator[static_cast<uint8_t>(
+              Section.second->getKind())];
+      SectionSizesAccumulator[static_cast<uint8_t>(
+          Section.second->getKind())] += Section.second->getContents().size();
     }
   }
 
@@ -505,7 +462,8 @@ class OutputSections {
   llvm::endianness Endianness = llvm::endianness::native;
 
   /// All keeping sections.
-  using SectionsSetTy = std::map<DebugSectionKind, SectionDescriptor>;
+  using SectionsSetTy =
+      std::map<DebugSectionKind, std::shared_ptr<SectionDescriptor>>;
   SectionsSetTy SectionDescriptors;
 };
 
diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
index 4ad188b0796f53..d09dcf678e1e99 100644
--- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
+++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
@@ -533,9 +533,8 @@ Error DwarfLinkerForBinary::copySwiftInterfaces(StringRef Architecture) const {
   return Error::success();
 }
 
-template <typename OutStreamer>
 void DwarfLinkerForBinary::copySwiftReflectionMetadata(
-    const llvm::dsymutil::DebugMapObject *Obj, OutStreamer *Streamer,
+    const llvm::dsymutil::DebugMapObject *Obj, classic::DwarfStreamer *Streamer,
     std::vector<uint64_t> &SectionToOffsetInDwarf,
     std::vector<MachOUtils::DwarfRelocationApplicationInfo>
         &RelocationsToApply) {
@@ -649,14 +648,32 @@ bool DwarfLinkerForBinary::linkImpl(
       },
       Options.Translator ? TranslationLambda : nullptr);
 
+  std::unique_ptr<classic::DwarfStreamer> Streamer;
   if (!Options.NoOutput) {
-    if (Error Err = GeneralLinker->createEmitter(Map.getTriple(), ObjectType,
-                                                 OutFile)) {
-      handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
+    if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr =
+            classic::DwarfStreamer::createStreamer(
+                Map.getTriple(), ObjectType, OutFile, Options.Translator,
+                [&](const Twine &Warning, StringRef Context,
+                    const DWARFDie *DIE) {
+                  reportWarning(Warning, Context, DIE);
+                }))
+      Streamer = std::move(*StreamerOrErr);
+    else {
+      handleAllErrors(StreamerOrErr.takeError(), [&](const ErrorInfoBase &EI) {
         reportError(EI.message(), "dwarf streamer init");
       });
       return false;
     }
+
+    if constexpr (std::is_same<Linker, parallel::DWARFLinker>::value) {
+      GeneralLinker->setOutputDWARFHandler(
+          Map.getTriple(),
+          [&](std::shared_ptr<parallel::SectionDescriptorBase> Section) {
+            Streamer->emitSectionContents(Section->getContents(),
+                                          Section->getKind());
+          });
+    } else
+      GeneralLinker->setOutputDWARFEmitter(Streamer.get());
   }
 
   remarks::RemarkLinker RL;
@@ -749,7 +766,7 @@ bool DwarfLinkerForBinary::linkImpl(
     auto SectionToOffsetInDwarf =
         calculateStartOfStrippableReflectionSections(Map);
     for (const auto &Obj : Map.objects())
-      copySwiftReflectionMetadata(Obj.get(), GeneralLinker->getEmitter(),
+      copySwiftReflectionMetadata(Obj.get(), Streamer.get(),
                                   SectionToOffsetInDwarf, RelocationsToApply);
   }
 
@@ -796,7 +813,7 @@ bool DwarfLinkerForBinary::linkImpl(
 
       // Copy the module into the .swift_ast section.
       if (!Options.NoOutput)
-        GeneralLinker->getEmitter()->emitSwiftAST((*ErrorOrMem)->getBuffer());
+        Streamer->emitSwiftAST((*ErrorOrMem)->getBuffer());
 
       continue;
     }
@@ -850,10 +867,9 @@ bool DwarfLinkerForBinary::linkImpl(
       ObjectType == Linker::OutputFileType::Object)
     return MachOUtils::generateDsymCompanion(
         Options.VFS, Map, Options.Translator,
-        *GeneralLinker->getEmitter()->getAsmPrinter().OutStreamer, OutFile,
-        RelocationsToApply);
+        *Streamer->getAsmPrinter().OutStreamer, OutFile, RelocationsToApply);
 
-  GeneralLinker->getEmitter()->finish();
+  Streamer->finish();
   return true;
 }
 
diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.h b/llvm/tools/dsymutil/DwarfLinkerForBinary.h
index 052c6a899fd76a..14b9625117c2d6 100644
--- a/llvm/tools/dsymutil/DwarfLinkerForBinary.h
+++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.h
@@ -253,9 +253,9 @@ class DwarfLinkerForBinary {
 
   Error copySwiftInterfaces(StringRef Architecture) const;
 
-  template <typename OutStreamer>
   void copySwiftReflectionMetadata(
-      const llvm::dsymutil::DebugMapObject *Obj, OutStreamer *Streamer,
+      const llvm::dsymutil::DebugMapObject *Obj,
+      classic::DwarfStreamer *Streamer,
       std::vector<uint64_t> &SectionToOffsetInDwarf,
       std::vector<MachOUtils::DwarfRelocationApplicationInfo>
           &RelocationsToApply);
diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
index d677bb0962669f..19eb1bed7578bb 100644
--- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
+++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
@@ -336,9 +336,26 @@ Error linkDebugInfoImpl(object::ObjectFile &File, const Options &Options,
       Linker::createLinker(ReportErr, ReportWarn);
 
   Triple TargetTriple = File.makeTriple();
-  if (Error Err = DebugInfoLinker->createEmitter(
-          TargetTriple, Linker::OutputFileType::Object, OutStream))
-    return Err;
+  std::unique_ptr<classic::DwarfStreamer> Streamer;
+  if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr =
+          classic::DwarfStreamer::createStreamer(
+              TargetTriple, Linker::OutputFileType::Object, OutStream, nullptr,
+              ReportWarn))
+    Streamer = std::move(*StreamerOrErr);
+  else
+    return StreamerOrErr.takeError();
+
+  if constexpr (std::is_same<Linker,
+                             dwarf_linker::parallel::DWARFLinker>::value) {
+    DebugInfoLinker->setOutputDWARFHandler(
+        TargetTriple,
+        [&](std::shared_ptr<dwarf_linker::parallel::SectionDescriptorBase>
+                Section) {
+          Streamer->emitSectionContents(Section->getContents(),
+                                        Section->getKind());
+        });
+  } else
+    DebugInfoLinker->setOutputDWARFEmitter(Streamer.get());
 
   DebugInfoLinker->setEstimatedObjfilesAmount(1);
   DebugInfoLinker->setNumThreads(Options.NumThreads);
@@ -445,7 +462,7 @@ Error linkDebugInfoImpl(object::ObjectFile &File, const Options &Options,
   if (Error Err = DebugInfoLinker->link())
     return Err;
 
-  DebugInfoLinker->getEmitter()->finish();
+  Streamer->finish();
   return Error::success();
 }
 

>From 83a7d68f90075779cf51ceb4a148104e44b22333 Mon Sep 17 00:00:00 2001
From: Alexey Lapshin <a.v.lapshin at mail.ru>
Date: Fri, 19 Jan 2024 16:39:52 +0300
Subject: [PATCH 2/2] add comment.

---
 llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h
index 99506e28a6ae61..5312712a4a5b81 100644
--- a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h
@@ -126,7 +126,9 @@ class DWARFLinker : public DWARFLinkerBase {
   createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler,
                TranslatorFuncTy StringsTranslator = nullptr);
 
-  /// Set output DWARF handler.
+  /// Set output DWARF handler. Result of linking DWARF is set of sections
+  /// containing final debug info. DWARFLinkerBase::link() pass generated
+  /// sections using specified \p SectionHandler.
   virtual void setOutputDWARFHandler(const Triple &TargetTriple,
                                      SectionHandlerTy SectionHandler) = 0;
 };



More information about the llvm-commits mailing list