r174349 - Driver and option support for -gsplit-dwarf. This is a part of

Eric Christopher echristo at gmail.com
Mon Feb 4 23:29:57 PST 2013


Author: echristo
Date: Tue Feb  5 01:29:57 2013
New Revision: 174349

URL: http://llvm.org/viewvc/llvm-project?rev=174349&view=rev
Log:
Driver and option support for -gsplit-dwarf. This is a part of
the DWARF5 split dwarf proposal.

Added:
    cfe/trunk/test/Driver/split-debug.c
Modified:
    cfe/trunk/include/clang/Driver/Action.h
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/lib/Driver/Action.cpp
    cfe/trunk/lib/Driver/Driver.cpp
    cfe/trunk/lib/Driver/ToolChains.cpp
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Driver/Tools.h
    cfe/trunk/lib/Driver/WindowsToolChain.cpp

Modified: cfe/trunk/include/clang/Driver/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Action.h?rev=174349&r1=174348&r2=174349&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Action.h (original)
+++ cfe/trunk/include/clang/Driver/Action.h Tue Feb  5 01:29:57 2013
@@ -46,9 +46,10 @@ public:
     LipoJobClass,
     DsymutilJobClass,
     VerifyJobClass,
+    SplitDebugJobClass,
 
     JobClassFirst=PreprocessJobClass,
-    JobClassLast=VerifyJobClass
+    JobClassLast=SplitDebugJobClass
   };
 
   static const char *getClassName(ActionClass AC);
@@ -233,6 +234,15 @@ public:
   }
 };
 
+class SplitDebugJobAction : public JobAction {
+  virtual void anchor();
+public:
+  SplitDebugJobAction(ActionList &Inputs, types::ID Type);
+  static bool classof(const Action *A) {
+    return A->getKind() == SplitDebugJobClass;
+  }
+};
+
 } // end namespace driver
 } // end namespace clang
 

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=174349&r1=174348&r2=174349&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Tue Feb  5 01:29:57 2013
@@ -134,6 +134,8 @@ def dwarf_debug_flags : Separate<["-"],
   HelpText<"The string to embed in the Dwarf debug flags record.">;
 def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
   HelpText<"Turn on column location information.">;
+def split_dwarf : Flag<["-"], "split-dwarf">,
+  HelpText<"Split out the dwarf .dwo sections">;
 def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">,
   HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
 def no_implicit_float : Flag<["-"], "no-implicit-float">,

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=174349&r1=174348&r2=174349&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Tue Feb  5 01:29:57 2013
@@ -760,6 +760,7 @@ def gno_record_gcc_switches : Flag<["-"]
 def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group<g_flags_Group>;
 def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group<g_flags_Group>;
 def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>;
+def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
 def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
 def help : Flag<["-", "--"], "help">, Flags<[CC1Option]>,
   HelpText<"Display available options">;

Modified: cfe/trunk/lib/Driver/Action.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Action.cpp?rev=174349&r1=174348&r2=174349&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Action.cpp (original)
+++ cfe/trunk/lib/Driver/Action.cpp Tue Feb  5 01:29:57 2013
@@ -33,6 +33,7 @@ const char *Action::getClassName(ActionC
   case LipoJobClass: return "lipo";
   case DsymutilJobClass: return "dsymutil";
   case VerifyJobClass: return "verify";
+  case SplitDebugJobClass: return "split-debug";
   }
 
   llvm_unreachable("invalid class");
@@ -119,3 +120,9 @@ void VerifyJobAction::anchor() {}
 VerifyJobAction::VerifyJobAction(ActionList &Inputs, types::ID Type)
   : JobAction(VerifyJobClass, Inputs, Type) {
 }
+
+void SplitDebugJobAction::anchor() {}
+
+SplitDebugJobAction::SplitDebugJobAction(ActionList &Inputs, types::ID Type)
+  : JobAction(SplitDebugJobClass, Inputs, Type) {
+}

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=174349&r1=174348&r2=174349&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Tue Feb  5 01:29:57 2013
@@ -25,6 +25,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -1036,6 +1037,7 @@ void Driver::BuildActions(const ToolChai
 
   // Construct the actions to perform.
   ActionList LinkerInputs;
+  ActionList SplitInputs;
   unsigned NumSteps = 0;
   for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
     types::ID InputType = Inputs[i].first;
@@ -1105,6 +1107,12 @@ void Driver::BuildActions(const ToolChai
       Current.reset(ConstructPhaseAction(Args, Phase, Current.take()));
       if (Current->getType() == types::TY_Nothing)
         break;
+      else if (Current->getType() == types::TY_Object &&
+               Args.hasArg(options::OPT_gsplit_dwarf)) {
+        ActionList Input;
+        Input.push_back(Current.take());
+        Current.reset(new SplitDebugJobAction(Input, types::TY_Object));
+      }
     }
 
     // If we ended with something, add to the output list.
@@ -1112,6 +1120,16 @@ void Driver::BuildActions(const ToolChai
       Actions.push_back(Current.take());
   }
 
+  if (!SplitInputs.empty()) {
+    for (ActionList::iterator i = SplitInputs.begin(), e = SplitInputs.end();
+         i != e; ++i) {
+      Action *Act = *i;
+      ActionList Inputs;
+      Inputs.push_back(Act);
+      Actions.push_back(new SplitDebugJobAction(Inputs, types::TY_Object));
+    }
+  }
+
   // Add a link action if necessary.
   if (!LinkerInputs.empty())
     Actions.push_back(new LinkJobAction(LinkerInputs, types::TY_Image));
@@ -1396,12 +1414,13 @@ void Driver::BuildJobsForAction(Compilat
     BaseInput = InputInfos[0].getFilename();
 
   // Determine the place to write output to, if any.
-  if (JA->getType() == types::TY_Nothing) {
+  if (JA->getType() == types::TY_Nothing)
     Result = InputInfo(A->getType(), BaseInput);
-  } else {
+  else if (isa<SplitDebugJobAction>(A))
+    Result = InputInfos[0];
+  else
     Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, AtTopLevel),
                        A->getType(), BaseInput);
-  }
 
   if (CCCPrintBindings && !CCGenDiagnostics) {
     llvm::errs() << "# \"" << T.getToolChain().getTripleString() << '"'

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=174349&r1=174348&r2=174349&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Tue Feb  5 01:29:57 2013
@@ -189,6 +189,7 @@ Tool &Darwin::SelectTool(const Compilati
   Tool *&T = Tools[Key];
   if (!T) {
     switch (Key) {
+    case Action::SplitDebugJobClass:
     case Action::InputClass:
     case Action::BindArchClass:
       llvm_unreachable("Invalid tool kind.");
@@ -1388,6 +1389,7 @@ Tool &Generic_GCC::SelectTool(const Comp
   Tool *&T = Tools[Key];
   if (!T) {
     switch (Key) {
+    case Action::SplitDebugJobClass:
     case Action::InputClass:
     case Action::BindArchClass:
       llvm_unreachable("Invalid tool kind.");
@@ -2450,6 +2452,8 @@ Tool &Linux::SelectTool(const Compilatio
       break;
     case Action::LinkJobClass:
       T = new tools::linuxtools::Link(*this); break;
+    case Action::SplitDebugJobClass:
+      T = new tools::linuxtools::SplitDebug(*this); break;
     default:
       T = &Generic_GCC::SelectTool(C, JA, Inputs);
     }

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=174349&r1=174348&r2=174349&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Tue Feb  5 01:29:57 2013
@@ -2250,16 +2250,15 @@ void Clang::ConstructJob(Compilation &C,
                       D.CCLogDiagnosticsFilename : "-");
   }
 
-  // Use the last option from "-g" group. "-gline-tables-only" is
-  // preserved, all other debug options are substituted with "-g".
+  // Use the last option from "-g" group. "-gline-tables-only"
+  // is preserved, all other debug options are substituted with "-g".
   Args.ClaimAllArgs(options::OPT_g_Group);
   if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
-    if (A->getOption().matches(options::OPT_gline_tables_only)) {
+    if (A->getOption().matches(options::OPT_gline_tables_only))
       CmdArgs.push_back("-gline-tables-only");
-    } else if (!A->getOption().matches(options::OPT_g0) &&
-               !A->getOption().matches(options::OPT_ggdb0)) {
+    else if (!A->getOption().matches(options::OPT_g0) &&
+             !A->getOption().matches(options::OPT_ggdb0))
       CmdArgs.push_back("-g");
-    }
   }
 
   // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
@@ -2267,6 +2266,14 @@ void Clang::ConstructJob(Compilation &C,
   if (Args.hasArg(options::OPT_gcolumn_info))
     CmdArgs.push_back("-dwarf-column-info");
 
+  // -gsplit-dwarf should turn on -g and enable the backend dwarf
+  // splitting and extraction.
+  if (Args.hasArg(options::OPT_gsplit_dwarf)) {
+    CmdArgs.push_back("-g");
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-split-dwarf=Enable");
+  }
+
   Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
   Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
 
@@ -5829,6 +5836,42 @@ void linuxtools::Link::ConstructJob(Comp
   C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
 }
 
+void linuxtools::SplitDebug::ConstructJob(Compilation &C, const JobAction &JA,
+                                          const InputInfo &Output,
+                                          const InputInfoList &Inputs,
+                                          const ArgList &Args,
+                                          const char *LinkingOutput) const {
+  // Assert some invariants.
+  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
+  const InputInfo &Input = Inputs[0];
+  assert(Input.isFilename() && "Unexpected verify input");
+
+  ArgStringList ExtractArgs;
+  ExtractArgs.push_back("--extract-dwo");
+
+  ArgStringList StripArgs;
+  StripArgs.push_back("--strip-dwo");
+
+  // Grabbing the output of the earlier compile step.
+  StripArgs.push_back(Input.getFilename());
+  ExtractArgs.push_back(Input.getFilename());
+
+  // Add an output for the extract.
+  SmallString<128> T(Inputs[0].getBaseInput());
+  llvm::sys::path::replace_extension(T, "dwo");
+  const char *OutFile = Args.MakeArgString(T);
+  ExtractArgs.push_back(OutFile);
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath("objcopy"));
+
+  // First extract the dwo sections.
+  C.addCommand(new Command(JA, *this, Exec, ExtractArgs));
+
+  // Then remove them from the original .o file.
+  C.addCommand(new Command(JA, *this, Exec, StripArgs));
+}
+
 void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
                                    const InputInfo &Output,
                                    const InputInfoList &Inputs,

Modified: cfe/trunk/lib/Driver/Tools.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.h?rev=174349&r1=174348&r2=174349&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.h (original)
+++ cfe/trunk/lib/Driver/Tools.h Tue Feb  5 01:29:57 2013
@@ -454,6 +454,20 @@ namespace linuxtools {
                               const ArgList &TCArgs,
                               const char *LinkingOutput) const;
   };
+
+  class LLVM_LIBRARY_VISIBILITY SplitDebug : public Tool  {
+  public:
+    SplitDebug(const ToolChain &TC) : Tool("linuxtools::SplitDebug",
+                                           "objcopy", TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
 }
   /// minix -- Directly call GNU Binutils assembler and linker
 namespace minix {

Modified: cfe/trunk/lib/Driver/WindowsToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/WindowsToolChain.cpp?rev=174349&r1=174348&r2=174349&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/WindowsToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/WindowsToolChain.cpp Tue Feb  5 01:29:57 2013
@@ -54,6 +54,7 @@ Tool &Windows::SelectTool(const Compilat
     case Action::LipoJobClass:
     case Action::DsymutilJobClass:
     case Action::VerifyJobClass:
+    case Action::SplitDebugJobClass:
       llvm_unreachable("Invalid tool kind.");
     case Action::PreprocessJobClass:
     case Action::PrecompileJobClass:

Added: cfe/trunk/test/Driver/split-debug.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/split-debug.c?rev=174349&view=auto
==============================================================================
--- cfe/trunk/test/Driver/split-debug.c (added)
+++ cfe/trunk/test/Driver/split-debug.c Tue Feb  5 01:29:57 2013
@@ -0,0 +1,19 @@
+// Check that we split debug output properly
+//
+// REQUIRES: asserts
+// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases \
+// RUN:   -gsplit-dwarf -arch x86_64 %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-ACTIONS < %t %s
+//
+// CHECK-ACTIONS: 0: input, "{{.*}}split-debug.c", c
+// CHECK-ACTIONS: 4: split-debug, {3}, object
+
+// Check output name derivation.
+//
+// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-bindings \
+// RUN:   -gsplit-dwarf -arch x86_64 -c %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-OUTPUT-NAME < %t %s
+//
+// CHECK-OUTPUT-NAME:# "x86_64-unknown-linux-gnu" - "clang", inputs: ["{{.*}}split-debug.c"], output: "{{.*}}split-debug{{.*}}.o"
+// CHECK-OUTPUT-NAME:# "x86_64-unknown-linux-gnu" - "linuxtools::SplitDebug", inputs: ["{{.*}}split-debug{{.*}}.o"], output: "{{.*}}split-debug{{.*}}.o"
+





More information about the cfe-commits mailing list