[DWARFLinker][dsymutil][NFC] Move DwarfStreamer into DWARFLinker.
authorAlexey Lapshin <a.v.lapshin@mail.ru>
Mon, 6 Apr 2020 21:42:40 +0000 (00:42 +0300)
committerAlexey Lapshin <a.v.lapshin@mail.ru>
Tue, 7 Apr 2020 18:21:54 +0000 (21:21 +0300)
For implementing "remove obsolete debug info in lld", it is neccesary
to have DWARF generation code implementation. dsymutil uses DwarfStreamer
for that purpose. DwarfStreamer uses AsmPrinter. It is considered OK
to use AsmPrinter based code in lld(D74169). This patch moves
DwarfStreamer implementation into DWARFLinker, so that it could be reused
from lld.

Generally, a better place for such a common DWARF generation code would be
not DWARFLinker but an additional separate library. Such a library could
contain a single version of DWARF generation routines and could also
be independent of AsmPrinter. At the current moment, DwarfStreamer
does not pretend to be such a general implementation of DWARF generation.
So I decided to put it into DWARFLinker since it is the only user
of DwarfStreamer.

Testing: it passes "check-all" lit testing. MD5 checksum for clang .dSYM
bundle matches for the dsymutil with/without that patch.

Reviewed By: JDevlieghere

Differential revision: https://reviews.llvm.org/D77169

llvm/include/llvm/DWARFLinker/DWARFStreamer.h [moved from llvm/tools/dsymutil/DwarfStreamer.h with 81% similarity]
llvm/lib/DWARFLinker/CMakeLists.txt
llvm/lib/DWARFLinker/DWARFStreamer.cpp [moved from llvm/tools/dsymutil/DwarfStreamer.cpp with 97% similarity]
llvm/tools/dsymutil/CMakeLists.txt
llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
llvm/tools/dsymutil/DwarfLinkerForBinary.h
llvm/tools/dsymutil/LinkUtils.h

similarity index 81%
rename from llvm/tools/dsymutil/DwarfStreamer.h
rename to llvm/include/llvm/DWARFLinker/DWARFStreamer.h
index 1084a28..de58f5d 100644 (file)
@@ -1,4 +1,4 @@
-//===- tools/dsymutil/DwarfStreamer.h - Dwarf Streamer ----------*- C++ -*-===//
+//===- DwarfStreamer.h ------------------------------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,37 +6,35 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H
-#define LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H
+#ifndef LLVM_DWARFLINKER_DWARFSTREAMER_H
+#define LLVM_DWARFLINKER_DWARFSTREAMER_H
 
-#include "DebugMap.h"
-#include "LinkUtils.h"
 #include "llvm/CodeGen/AccelTable.h"
 #include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/NonRelocatableStringpool.h"
 #include "llvm/DWARFLinker/DWARFLinker.h"
-#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
-#include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCContext.h"
-#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/MCSymbol.h"
-#include "llvm/MC/MCTargetOptions.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
 
 namespace llvm {
-namespace dsymutil {
+
+enum class OutputFileType {
+  Object,
+  Assembly,
+};
+
+///   User of DwarfStreamer should call initialization code
+///   for AsmPrinter:
+///
+///   InitializeAllTargetInfos();
+///   InitializeAllTargetMCs();
+///   InitializeAllTargets();
+///   InitializeAllAsmPrinters();
+
+class MCCodeEmitter;
 
 /// The Dwarf streaming logic.
 ///
@@ -44,13 +42,16 @@ namespace dsymutil {
 /// information binary representation are handled in this class.
 class DwarfStreamer : public DwarfEmitter {
 public:
-  DwarfStreamer(raw_fd_ostream &OutFile, LinkOptions Options)
-      : OutFile(OutFile), Options(std::move(Options)) {}
+  DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile,
+                std::function<StringRef(StringRef Input)> Translator,
+                bool Minimize, messageHandler Error, messageHandler Warning)
+      : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
+        Minimize(Minimize), ErrorHandler(Error), WarningHandler(Warning) {}
 
   bool init(Triple TheTriple);
 
   /// Dump the file to the disk.
-  bool finish(const DebugMap &, SymbolMapTranslator &T);
+  void finish();
 
   AsmPrinter &getAsmPrinter() const { return *Asm; }
 
@@ -158,6 +159,16 @@ public:
   }
 
 private:
+  inline void error(const Twine &Error, StringRef Context = "") {
+    if (ErrorHandler)
+      ErrorHandler(Error, Context, nullptr);
+  }
+
+  inline void warn(const Twine &Warning, StringRef Context = "") {
+    if (WarningHandler)
+      WarningHandler(Warning, Context, nullptr);
+  }
+
   /// \defgroup MCObjects MC layer objects constructed by the streamer
   /// @{
   std::unique_ptr<MCRegisterInfo> MRI;
@@ -174,10 +185,11 @@ private:
   std::unique_ptr<AsmPrinter> Asm;
   /// @}
 
-  /// The file we stream the linked Dwarf to.
-  raw_fd_ostream &OutFile;
-
-  LinkOptions Options;
+  /// The output file we stream the linked Dwarf to.
+  raw_pwrite_stream &OutFile;
+  OutputFileType OutFileType = OutputFileType::Object;
+  std::function<StringRef(StringRef Input)> Translator;
+  bool Minimize = true;
 
   uint64_t RangesSectionSize = 0;
   uint64_t LocSectionSize = 0;
@@ -197,9 +209,11 @@ private:
   void emitPubSectionForUnit(MCSection *Sec, StringRef Name,
                              const CompileUnit &Unit,
                              const std::vector<CompileUnit::AccelInfo> &Names);
+
+  messageHandler ErrorHandler = nullptr;
+  messageHandler WarningHandler = nullptr;
 };
 
-} // end namespace dsymutil
 } // end namespace llvm
 
-#endif // LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H
+#endif // LLVM_DWARFLINKER_DWARFSTREAMER_H
index f8c6133..724ed76 100644 (file)
@@ -2,6 +2,7 @@ add_llvm_component_library(LLVMDWARFLinker
   DWARFLinkerCompileUnit.cpp
   DWARFLinkerDeclContext.cpp
   DWARFLinker.cpp
+  DWARFStreamer.cpp
 
   DEPENDS
   intrinsics_gen
similarity index 97%
rename from llvm/tools/dsymutil/DwarfStreamer.cpp
rename to llvm/lib/DWARFLinker/DWARFStreamer.cpp
index c53d5d5..5b38b58 100644 (file)
@@ -1,4 +1,4 @@
-//===- tools/dsymutil/DwarfStreamer.cpp - Dwarf Streamer ------------------===//
+//===- DwarfStreamer.cpp --------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,25 +6,29 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "DwarfStreamer.h"
-#include "LinkUtils.h"
-#include "MachOUtils.h"
+#include "llvm/DWARFLinker/DWARFStreamer.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/CodeGen/NonRelocatableStringpool.h"
 #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCTargetOptions.h"
 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/TargetRegistry.h"
-#include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
 
 namespace llvm {
 
 static mc::RegisterMCTargetOptionsFlags MOF;
 
-namespace dsymutil {
-
 bool DwarfStreamer::init(Triple TheTriple) {
   std::string ErrorStr;
   std::string TripleName;
@@ -34,18 +38,19 @@ bool DwarfStreamer::init(Triple TheTriple) {
   const Target *TheTarget =
       TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
   if (!TheTarget)
-    return error(ErrorStr, Context);
+    return error(ErrorStr, Context), false;
   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);
+    return error(Twine("no register info for target ") + TripleName, Context),
+           false;
 
   MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
   MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
   if (!MAI)
-    return error("no asm info for target " + TripleName, Context);
+    return error("no asm info for target " + TripleName, Context), false;
 
   MOFI.reset(new MCObjectFileInfo);
   MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get()));
@@ -53,21 +58,21 @@ bool DwarfStreamer::init(Triple TheTriple) {
 
   MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
   if (!MSTI)
-    return error("no subtarget info for target " + TripleName, Context);
+    return error("no subtarget info for target " + TripleName, Context), false;
 
   MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);
   if (!MAB)
-    return error("no asm backend for target " + TripleName, Context);
+    return error("no asm backend for target " + TripleName, Context), false;
 
   MII.reset(TheTarget->createMCInstrInfo());
   if (!MII)
-    return error("no instr info info for target " + TripleName, Context);
+    return error("no instr info info for target " + TripleName, Context), false;
 
   MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC);
   if (!MCE)
-    return error("no code emitter for target " + TripleName, Context);
+    return error("no code emitter for target " + TripleName, Context), false;
 
-  switch (Options.FileType) {
+  switch (OutFileType) {
   case OutputFileType::Assembly: {
     MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(),
                                          *MAI, *MII, *MRI);
@@ -88,17 +93,17 @@ bool DwarfStreamer::init(Triple TheTriple) {
   }
 
   if (!MS)
-    return error("no object streamer for target " + TripleName, Context);
+    return error("no object streamer for target " + TripleName, Context), false;
 
   // 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);
+    return error("no target machine for target " + TripleName, Context), false;
 
   Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
   if (!Asm)
-    return error("no asm printer for target " + TripleName, Context);
+    return error("no asm printer for target " + TripleName, Context), false;
 
   RangesSectionSize = 0;
   LocSectionSize = 0;
@@ -109,15 +114,7 @@ bool DwarfStreamer::init(Triple TheTriple) {
   return true;
 }
 
-bool DwarfStreamer::finish(const DebugMap &DM, SymbolMapTranslator &T) {
-  bool Result = true;
-  if (DM.getTriple().isOSDarwin() && !DM.getBinaryPath().empty() &&
-      Options.FileType == OutputFileType::Object)
-    Result = MachOUtils::generateDsymCompanion(DM, T, *MS, OutFile);
-  else
-    MS->Finish();
-  return Result;
-}
+void DwarfStreamer::finish() { MS->Finish(); }
 
 void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) {
   MS->SwitchSection(MOFI->getDwarfInfoSection());
@@ -660,7 +657,7 @@ void DwarfStreamer::translateLineTable(DataExtractor Data, uint64_t Offset) {
     if (Dir[0] == 0)
       break;
 
-    StringRef Translated = Options.Translator(Dir);
+    StringRef Translated = Translator(Dir);
     Asm->OutStreamer->emitBytes(Translated);
     Asm->emitInt8(0);
     LineSectionSize += Translated.size() + 1;
@@ -672,7 +669,7 @@ void DwarfStreamer::translateLineTable(DataExtractor Data, uint64_t Offset) {
     if (File[0] == 0)
       break;
 
-    StringRef Translated = Options.Translator(File);
+    StringRef Translated = Translator(File);
     Asm->OutStreamer->emitBytes(Translated);
     Asm->emitInt8(0);
     LineSectionSize += Translated.size() + 1;
@@ -740,7 +737,7 @@ void DwarfStreamer::emitPubSectionForUnit(
 
 /// Emit .debug_pubnames for \p Unit.
 void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) {
-  if (Options.Minimize)
+  if (Minimize)
     return;
   emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
                         "names", Unit, Unit.getPubnames());
@@ -748,7 +745,7 @@ void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) {
 
 /// Emit .debug_pubtypes for \p Unit.
 void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) {
-  if (Options.Minimize)
+  if (Minimize)
     return;
   emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
                         "types", Unit, Unit.getPubtypes());
@@ -776,5 +773,4 @@ void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize,
   FrameSectionSize += FDEBytes.size() + 8 + AddrSize;
 }
 
-} // namespace dsymutil
 } // namespace llvm
index dc31b86..a42e1a9 100644 (file)
@@ -24,7 +24,6 @@ add_llvm_tool(dsymutil
   CFBundle.cpp
   DebugMap.cpp
   DwarfLinkerForBinary.cpp
-  DwarfStreamer.cpp
   MachODebugMapParser.cpp
   MachOUtils.cpp
   SymbolMap.cpp
index c1c247d..4e99e5f 100644 (file)
@@ -9,7 +9,6 @@
 #include "DwarfLinkerForBinary.h"
 #include "BinaryHolder.h"
 #include "DebugMap.h"
-#include "DwarfStreamer.h"
 #include "MachOUtils.h"
 #include "dsymutil.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -163,7 +162,14 @@ bool DwarfLinkerForBinary::createStreamer(const Triple &TheTriple,
   if (Options.NoOutput)
     return true;
 
-  Streamer = std::make_unique<DwarfStreamer>(OutFile, Options);
+  Streamer = std::make_unique<DwarfStreamer>(
+      Options.FileType, OutFile, Options.Translator, Options.Minimize,
+      [&](const Twine &Error, StringRef Context, const DWARFDie *) {
+        error(Error, Context);
+      },
+      [&](const Twine &Warning, StringRef Context, const DWARFDie *) {
+        warn(Warning, Context);
+      });
   return Streamer->init(TheTriple);
 }
 
@@ -318,7 +324,7 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) {
         reportWarning(Warning, Context, DIE);
       });
   GeneralLinker.setErrorHandler(
-      [&](const Twine &Error, StringRef Context, const DWARFDie *DIE) {
+      [&](const Twine &Error, StringRef Context, const DWARFDie *) {
         error(Error, Context);
       });
   GeneralLinker.setObjFileLoader(
@@ -442,7 +448,14 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) {
       return error(toString(std::move(E)));
   }
 
-  return Streamer->finish(Map, Options.Translator);
+  if (Map.getTriple().isOSDarwin() && !Map.getBinaryPath().empty() &&
+      Options.FileType == OutputFileType::Object)
+    return MachOUtils::generateDsymCompanion(
+        Map, Options.Translator, *Streamer->getAsmPrinter().OutStreamer,
+        OutFile);
+
+  Streamer->finish();
+  return true;
 }
 
 static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) {
index 9b7d9c5..7cabacb 100644 (file)
 
 #include "BinaryHolder.h"
 #include "DebugMap.h"
-#include "DwarfStreamer.h"
 #include "LinkUtils.h"
 #include "llvm/DWARFLinker/DWARFLinker.h"
 #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
 #include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
+#include "llvm/DWARFLinker/DWARFStreamer.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/Remarks/RemarkFormat.h"
 #include "llvm/Remarks/RemarkLinker.h"
index 0339f44..c630be3 100644 (file)
 #include "llvm/Support/WithColor.h"
 
 #include "llvm/DWARFLinker/DWARFLinker.h"
+#include "llvm/DWARFLinker/DWARFStreamer.h"
 #include <string>
 
 namespace llvm {
 namespace dsymutil {
 
-enum class OutputFileType {
-  Object,
-  Assembly,
-};
-
 struct LinkOptions {
   /// Verbosity
   bool Verbose = false;