зеркало из https://github.com/microsoft/clang-1.git
Driver and option support for -gsplit-dwarf. This is a part of
the DWARF5 split dwarf proposal. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174349 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
4f4e2af264
Коммит
c706c8e440
|
@ -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
|
||||
|
||||
|
|
|
@ -134,6 +134,8 @@ def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
|
|||
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">,
|
||||
|
|
|
@ -760,6 +760,7 @@ def gno_record_gcc_switches : Flag<["-"], "gno-record-gcc-switches">,
|
|||
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">;
|
||||
|
|
|
@ -33,6 +33,7 @@ const char *Action::getClassName(ActionClass AC) {
|
|||
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) {
|
||||
}
|
||||
|
|
|
@ -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 ToolChain &TC, const DerivedArgList &Args,
|
|||
|
||||
// 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 ToolChain &TC, const DerivedArgList &Args,
|
|||
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 ToolChain &TC, const DerivedArgList &Args,
|
|||
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(Compilation &C,
|
|||
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() << '"'
|
||||
|
|
|
@ -189,6 +189,7 @@ Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,
|
|||
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 Compilation &C,
|
|||
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 Compilation &C, const JobAction &JA,
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -2250,23 +2250,30 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
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.
|
||||
Args.ClaimAllArgs(options::OPT_g_flags_Group);
|
||||
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(Compilation &C, const JobAction &JA,
|
|||
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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -54,6 +54,7 @@ Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA,
|
|||
case Action::LipoJobClass:
|
||||
case Action::DsymutilJobClass:
|
||||
case Action::VerifyJobClass:
|
||||
case Action::SplitDebugJobClass:
|
||||
llvm_unreachable("Invalid tool kind.");
|
||||
case Action::PreprocessJobClass:
|
||||
case Action::PrecompileJobClass:
|
||||
|
|
|
@ -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"
|
||||
|
Загрузка…
Ссылка в новой задаче