[llvm] r230824 - [dsymutil] Add the DwarfStreamer class.

Frederic Riss friss at apple.com
Fri Feb 27 16:29:11 PST 2015


Author: friss
Date: Fri Feb 27 18:29:11 2015
New Revision: 230824

URL: http://llvm.org/viewvc/llvm-project?rev=230824&view=rev
Log:
[dsymutil] Add the DwarfStreamer class.

This class is responsible for getting the linked data to the
disk in the appropriate form. Today it it an empty shell that
just instantiates an MC layer.

As we do not put anything in the resulting file yet, we just
check it has the right architecture (and check that -o does
the right thing).

To be able to create all the components, this commit adds a
few dependencies to llvm-dsymutil, namely all-targets, MC and
AsmPrinter.

Also add a -no-output option, so that tests that do not need
the binary result can continue to run even if they do not have
the required target linked in.

Added:
    llvm/trunk/test/tools/dsymutil/X86/
    llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test
    llvm/trunk/test/tools/dsymutil/X86/lit.local.cfg
Modified:
    llvm/trunk/test/tools/dsymutil/basic-linking.test
    llvm/trunk/tools/dsymutil/CMakeLists.txt
    llvm/trunk/tools/dsymutil/DwarfLinker.cpp
    llvm/trunk/tools/dsymutil/LLVMBuild.txt
    llvm/trunk/tools/dsymutil/Makefile
    llvm/trunk/tools/dsymutil/dsymutil.cpp
    llvm/trunk/tools/dsymutil/dsymutil.h

Added: llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test?rev=230824&view=auto
==============================================================================
--- llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test (added)
+++ llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test Fri Feb 27 18:29:11 2015
@@ -0,0 +1,8 @@
+RUN: cat %p/../Inputs/basic.macho.x86_64 > %t1
+RUN: llvm-dsymutil -oso-prepend-path=%p/.. %t1
+RUN: llvm-dwarfdump %t1.dwarf | FileCheck %s
+RUN: llvm-dsymutil -o %t2 -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64
+RUN: llvm-dwarfdump %t2 | FileCheck %s
+RUN: llvm-dsymutil -o - -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 | llvm-dwarfdump - | FileCheck %s
+
+CHECK: file format Mach-O 64-bit x86-64

Added: llvm/trunk/test/tools/dsymutil/X86/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/lit.local.cfg?rev=230824&view=auto
==============================================================================
--- llvm/trunk/test/tools/dsymutil/X86/lit.local.cfg (added)
+++ llvm/trunk/test/tools/dsymutil/X86/lit.local.cfg Fri Feb 27 18:29:11 2015
@@ -0,0 +1,2 @@
+if not 'X86' in config.root.targets:
+    config.unsupported = True

Modified: llvm/trunk/test/tools/dsymutil/basic-linking.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/basic-linking.test?rev=230824&r1=230823&r2=230824&view=diff
==============================================================================
--- llvm/trunk/test/tools/dsymutil/basic-linking.test (original)
+++ llvm/trunk/test/tools/dsymutil/basic-linking.test Fri Feb 27 18:29:11 2015
@@ -1,6 +1,6 @@
-RUN: llvm-dsymutil -v -oso-prepend-path=%p %p/Inputs/basic.macho.x86_64 | FileCheck %s
-RUN: llvm-dsymutil -v -oso-prepend-path=%p %p/Inputs/basic-lto.macho.x86_64 | FileCheck %s --check-prefix=CHECK-LTO
-RUN: llvm-dsymutil -v -oso-prepend-path=%p %p/Inputs/basic-archive.macho.x86_64 | FileCheck %s --check-prefix=CHECK-ARCHIVE
+RUN: llvm-dsymutil -no-output -v -oso-prepend-path=%p %p/Inputs/basic.macho.x86_64 | FileCheck %s
+RUN: llvm-dsymutil -no-output -v -oso-prepend-path=%p %p/Inputs/basic-lto.macho.x86_64 | FileCheck %s --check-prefix=CHECK-LTO
+RUN: llvm-dsymutil -no-output -v -oso-prepend-path=%p %p/Inputs/basic-archive.macho.x86_64 | FileCheck %s --check-prefix=CHECK-ARCHIVE
 
 This test check the basic Dwarf linking process through the debug dumps.
 

Modified: llvm/trunk/tools/dsymutil/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/CMakeLists.txt?rev=230824&r1=230823&r2=230824&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/CMakeLists.txt (original)
+++ llvm/trunk/tools/dsymutil/CMakeLists.txt Fri Feb 27 18:29:11 2015
@@ -1,5 +1,8 @@
 set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  AsmPrinter
   DebugInfoDWARF
+  MC
   Object
   Support
   )

Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=230824&r1=230823&r2=230824&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Fri Feb 27 18:29:11 2015
@@ -10,12 +10,24 @@
 #include "BinaryHolder.h"
 #include "DebugMap.h"
 #include "dsymutil.h"
+#include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCStreamer.h"
 #include "llvm/Object/MachO.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/LEB128.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
 #include <string>
 
 namespace llvm {
@@ -28,6 +40,12 @@ void warn(const Twine &Warning, const Tw
   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;
+}
+
 /// \brief 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.
@@ -55,6 +73,110 @@ private:
   std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index.
 };
 
+/// \brief 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;
+  /// @}
+
+  /// \brief the file we stream the linked Dwarf to.
+  std::unique_ptr<raw_fd_ostream> OutFile;
+
+public:
+  /// \brief Actually create the streamer and the ouptut file.
+  ///
+  /// This could be done directly in the constructor, but it feels
+  /// more natural to handle errors through return value.
+  bool init(Triple TheTriple, StringRef OutputFilename);
+
+  ///\brief Dump the file to the disk.
+  bool finish();
+};
+
+bool DwarfStreamer::init(Triple TheTriple, StringRef OutputFilename) {
+  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(TripleName, Reloc::Default, CodeModel::Default,
+                             *MC);
+
+  MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, "");
+  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);
+
+  MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
+  if (!MSTI)
+    return error("no subtarget info for target " + TripleName, Context);
+
+  MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MSTI, *MC);
+  if (!MCE)
+    return error("no code emitter for target " + TripleName, Context);
+
+  // Create the output file.
+  std::error_code EC;
+  OutFile = make_unique<raw_fd_ostream>(OutputFilename, EC, sys::fs::F_None);
+  if (EC)
+    return error(Twine(OutputFilename) + ": " + EC.message(), Context);
+
+  MS = TheTarget->createMCObjectStreamer(TripleName, *MC, *MAB, *OutFile, MCE,
+                                         *MSTI, 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()));
+  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);
+
+  return true;
+}
+
+bool DwarfStreamer::finish() {
+  MS->Finish();
+  return true;
+}
+
 /// \brief The core of the Dwarf linking logic.
 ///
 /// The link of the dwarf information from the object files will be
@@ -178,12 +300,15 @@ private:
 
   void reportWarning(const Twine &Warning, const DWARFUnit *Unit = nullptr,
                      const DWARFDebugInfoEntryMinimal *DIE = nullptr);
+
+  bool createStreamer(Triple TheTriple, StringRef OutputFilename);
   /// @}
 
 private:
   std::string OutputFilename;
   LinkOptions Options;
   BinaryHolder BinHolder;
+  std::unique_ptr<DwarfStreamer> Streamer;
 
   /// The units of the current debug map object.
   std::vector<CompileUnit> Units;
@@ -238,6 +363,14 @@ void DwarfLinker::reportWarning(const Tw
             6 /* Indent */);
 }
 
+bool DwarfLinker::createStreamer(Triple TheTriple, StringRef OutputFilename) {
+  if (Options.NoOutput)
+    return true;
+
+  Streamer = make_unique<DwarfStreamer>();
+  return Streamer->init(TheTriple, OutputFilename);
+}
+
 /// \brief Recursive helper to gather the child->parent relationships in the
 /// original compile unit.
 static void gatherDIEParents(const DWARFDebugInfoEntryMinimal *DIE,
@@ -509,7 +642,6 @@ unsigned DwarfLinker::shouldKeepDIE(cons
   return Flags;
 }
 
-
 /// \brief Mark the passed DIE as well as all the ones it depends on
 /// as kept.
 ///
@@ -614,6 +746,9 @@ bool DwarfLinker::link(const DebugMap &M
     return false;
   }
 
+  if (!createStreamer(Map.getTriple(), OutputFilename))
+    return false;
+
   for (const auto &Obj : Map.objects()) {
     CurrentDebugObject = Obj.get();
 
@@ -661,7 +796,7 @@ bool DwarfLinker::link(const DebugMap &M
     endDebugObject();
   }
 
-  return true;
+  return Options.NoOutput ? true : Streamer->finish();
 }
 }
 

Modified: llvm/trunk/tools/dsymutil/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/LLVMBuild.txt?rev=230824&r1=230823&r2=230824&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/LLVMBuild.txt (original)
+++ llvm/trunk/tools/dsymutil/LLVMBuild.txt Fri Feb 27 18:29:11 2015
@@ -19,4 +19,4 @@
 type = Tool
 name = llvm-dsymutil
 parent = Tools
-required_libraries = DebugInfoDWARF Object Support
+required_libraries = AsmPrinter DebugInfoDWARF MC Object Support all-targets

Modified: llvm/trunk/tools/dsymutil/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/Makefile?rev=230824&r1=230823&r2=230824&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/Makefile (original)
+++ llvm/trunk/tools/dsymutil/Makefile Fri Feb 27 18:29:11 2015
@@ -9,7 +9,7 @@
 
 LEVEL := ../..
 TOOLNAME := llvm-dsymutil
-LINK_COMPONENTS := DebugInfoDWARF Object Support
+LINK_COMPONENTS := all-targets AsmPrinter DebugInfoDWARF MC Object Support
 
 # This tool has no plugins, optimize startup time.
 TOOL_NO_EXPORTS := 1

Modified: llvm/trunk/tools/dsymutil/dsymutil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/dsymutil.cpp?rev=230824&r1=230823&r2=230824&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/dsymutil.cpp (original)
+++ llvm/trunk/tools/dsymutil/dsymutil.cpp Fri Feb 27 18:29:11 2015
@@ -19,6 +19,7 @@
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/TargetSelect.h"
 #include <string>
 
 using namespace llvm::dsymutil;
@@ -40,6 +41,10 @@ static opt<std::string> OsoPrependPath("
 
 static opt<bool> Verbose("v", desc("Verbosity level"), init(false));
 
+static opt<bool> NoOutput("no-output", desc("Do the link in memory, but do "
+                                            "not emit the result file."),
+                          init(false));
+
 static opt<bool>
     ParseOnly("parse-only",
               desc("Only parse the debug map, do not actaully link "
@@ -57,6 +62,12 @@ int main(int argc, char **argv) {
   auto DebugMapPtrOrErr = parseDebugMap(InputFile, OsoPrependPath, Verbose);
 
   Options.Verbose = Verbose;
+  Options.NoOutput = NoOutput;
+
+  llvm::InitializeAllTargetInfos();
+  llvm::InitializeAllTargetMCs();
+  llvm::InitializeAllTargets();
+  llvm::InitializeAllAsmPrinters();
 
   if (auto EC = DebugMapPtrOrErr.getError()) {
     llvm::errs() << "error: cannot parse the debug map for \"" << InputFile

Modified: llvm/trunk/tools/dsymutil/dsymutil.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/dsymutil.h?rev=230824&r1=230823&r2=230824&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/dsymutil.h (original)
+++ llvm/trunk/tools/dsymutil/dsymutil.h Fri Feb 27 18:29:11 2015
@@ -25,9 +25,10 @@ namespace llvm {
 namespace dsymutil {
 
 struct LinkOptions {
-  bool Verbose;
+  bool Verbose;  ///< Verbosity
+  bool NoOutput; ///< Skip emitting output
 
-  LinkOptions() : Verbose(false) {}
+  LinkOptions() : Verbose(false), NoOutput(false) {}
 };
 
 /// \brief Extract the DebugMap from the given file.





More information about the llvm-commits mailing list