r240170 - [CFI] Require -flto instead of implying it.
Alexey Samsonov
vonosmas at gmail.com
Fri Jun 19 12:57:46 PDT 2015
Author: samsonov
Date: Fri Jun 19 14:57:46 2015
New Revision: 240170
URL: http://llvm.org/viewvc/llvm-project?rev=240170&view=rev
Log:
[CFI] Require -flto instead of implying it.
Summary:
This is unfortunate, but would let us land http://reviews.llvm.org/D10467,
that makes ToolChains responsible for computing the set of sanitizers
they support.
Unfortunately, Darwin ToolChains doesn't know about actual OS they
target until ToolChain::TranslateArgs() is called. In particular, it
means we won't be able to construct SanitizerArgs for these ToolChains
before that.
This change removes SanitizerArgs::needsLTO() method, so that now
ToolChain::IsUsingLTO(), which is called very early, doesn't need
SanitizerArgs to implement this method.
Docs and test cases are updated accordingly. See
https://llvm.org/bugs/show_bug.cgi?id=23539, which describes why we
start all these.
Test Plan: regression test suite
Reviewers: pcc
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D10560
Modified:
cfe/trunk/docs/ControlFlowIntegrity.rst
cfe/trunk/docs/UsersManual.rst
cfe/trunk/include/clang/Driver/Driver.h
cfe/trunk/include/clang/Driver/SanitizerArgs.h
cfe/trunk/lib/Driver/Driver.cpp
cfe/trunk/lib/Driver/SanitizerArgs.cpp
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/test/Driver/fsanitize.c
Modified: cfe/trunk/docs/ControlFlowIntegrity.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ControlFlowIntegrity.rst?rev=240170&r1=240169&r2=240170&view=diff
==============================================================================
--- cfe/trunk/docs/ControlFlowIntegrity.rst (original)
+++ cfe/trunk/docs/ControlFlowIntegrity.rst Fri Jun 19 14:57:46 2015
@@ -20,8 +20,8 @@ program's control flow. These schemes ha
allowing developers to enable them in release builds.
To enable Clang's available CFI schemes, use the flag ``-fsanitize=cfi``.
-As currently implemented, CFI relies on link-time optimization (LTO); the CFI
-schemes imply ``-flto``, and the linker used must support LTO, for example
+As currently implemented, CFI relies on link-time optimization (LTO); so it is
+required to specify ``-flto``, and the linker used must support LTO, for example
via the `gold plugin`_. To allow the checks to be implemented efficiently,
the program must be structured such that certain object files are compiled
with CFI enabled, and are statically linked into the program. This may
Modified: cfe/trunk/docs/UsersManual.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=240170&r1=240169&r2=240170&view=diff
==============================================================================
--- cfe/trunk/docs/UsersManual.rst (original)
+++ cfe/trunk/docs/UsersManual.rst Fri Jun 19 14:57:46 2015
@@ -976,7 +976,7 @@ are listed below.
- ``-fsanitize=dataflow``: :doc:`DataFlowSanitizer`, a general data
flow analysis.
- ``-fsanitize=cfi``: :doc:`control flow integrity <ControlFlowIntegrity>`
- checks. Implies ``-flto``.
+ checks. Requires ``-flto``.
- ``-fsanitize=safe-stack``: :doc:`safe stack <SafeStack>`
protection against stack-based memory corruption errors.
@@ -991,13 +991,13 @@ are listed below.
- ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks
<cfi-strictness>`.
- ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong
- dynamic type. Implies ``-flto``.
+ dynamic type. Requires ``-flto``.
- ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another
- unrelated type to the wrong dynamic type. Implies ``-flto``.
+ unrelated type to the wrong dynamic type. Requires ``-flto``.
- ``-fsanitize=cfi-nvcall``: Non-virtual call via an object whose vptr is of
- the wrong dynamic type. Implies ``-flto``.
+ the wrong dynamic type. Requires ``-flto``.
- ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the
- wrong dynamic type. Implies ``-flto``.
+ wrong dynamic type. Requires ``-flto``.
- ``-fsanitize=enum``: Load of a value of an enumerated type which
is not in the range of representable values for that enumerated
type.
Modified: cfe/trunk/include/clang/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=240170&r1=240169&r2=240170&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Driver.h (original)
+++ cfe/trunk/include/clang/Driver/Driver.h Fri Jun 19 14:57:46 2015
@@ -402,7 +402,7 @@ public:
/// handle this action.
bool ShouldUseClangCompiler(const JobAction &JA) const;
- bool IsUsingLTO(const ToolChain &TC, const llvm::opt::ArgList &Args) const;
+ bool IsUsingLTO(const llvm::opt::ArgList &Args) const;
private:
/// \brief Retrieves a ToolChain for a particular target triple.
Modified: cfe/trunk/include/clang/Driver/SanitizerArgs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/SanitizerArgs.h?rev=240170&r1=240169&r2=240170&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/SanitizerArgs.h (original)
+++ cfe/trunk/include/clang/Driver/SanitizerArgs.h Fri Jun 19 14:57:46 2015
@@ -53,7 +53,6 @@ class SanitizerArgs {
bool requiresPIE() const;
bool needsUnwindTables() const;
- bool needsLTO() const;
bool linkCXXRuntimes() const { return LinkCXXRuntimes; }
void addArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=240170&r1=240169&r2=240170&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Fri Jun 19 14:57:46 2015
@@ -1362,7 +1362,7 @@ Driver::ConstructPhaseAction(const ToolC
types::TY_LLVM_BC);
}
case phases::Backend: {
- if (IsUsingLTO(TC, Args)) {
+ if (IsUsingLTO(Args)) {
types::ID Output =
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
return llvm::make_unique<BackendJobAction>(std::move(Input), Output);
@@ -1383,14 +1383,8 @@ Driver::ConstructPhaseAction(const ToolC
llvm_unreachable("invalid phase in ConstructPhaseAction");
}
-bool Driver::IsUsingLTO(const ToolChain &TC, const ArgList &Args) const {
- if (TC.getSanitizerArgs().needsLTO())
- return true;
-
- if (Args.hasFlag(options::OPT_flto, options::OPT_fno_lto, false))
- return true;
-
- return false;
+bool Driver::IsUsingLTO(const ArgList &Args) const {
+ return Args.hasFlag(options::OPT_flto, options::OPT_fno_lto, false);
}
void Driver::BuildJobs(Compilation &C) const {
Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=240170&r1=240169&r2=240170&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original)
+++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Fri Jun 19 14:57:46 2015
@@ -188,10 +188,6 @@ bool SanitizerArgs::needsUnwindTables()
return Sanitizers.Mask & NeedsUnwindTables;
}
-bool SanitizerArgs::needsLTO() const {
- return Sanitizers.Mask & NeedsLTO;
-}
-
void SanitizerArgs::clear() {
Sanitizers.clear();
RecoverableSanitizers.clear();
@@ -301,6 +297,12 @@ SanitizerArgs::SanitizerArgs(const ToolC
Kinds &= ~Vptr;
}
+ // Check that LTO is enabled if we need it.
+ if ((Kinds & NeedsLTO) && !D.IsUsingLTO(Args)) {
+ D.Diag(diag::err_drv_argument_only_allowed_with)
+ << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
+ }
+
// Warn about incompatible groups of sanitizers.
std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
std::make_pair(Address, Thread), std::make_pair(Address, Memory),
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=240170&r1=240169&r2=240170&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Fri Jun 19 14:57:46 2015
@@ -6038,7 +6038,7 @@ void cloudabi::Link::ConstructJob(Compil
Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
Args.AddAllArgs(CmdArgs, options::OPT_r);
- if (D.IsUsingLTO(ToolChain, Args))
+ if (D.IsUsingLTO(Args))
AddGoldPlugin(ToolChain, Args, CmdArgs);
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
@@ -6189,8 +6189,7 @@ void darwin::Link::AddLinkArgs(Compilati
// If we are using LTO, then automatically create a temporary file path for
// the linker to use, so that it's lifetime will extend past a possible
// dsymutil step.
- if (Version[0] >= 116 && D.IsUsingLTO(getToolChain(), Args) &&
- NeedsTempPath(Inputs)) {
+ if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) {
const char *TmpPath = C.getArgs().MakeArgString(
D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
C.addTempFile(TmpPath);
@@ -7226,7 +7225,7 @@ void freebsd::Link::ConstructJob(Compila
Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
Args.AddAllArgs(CmdArgs, options::OPT_r);
- if (D.IsUsingLTO(getToolChain(), Args))
+ if (D.IsUsingLTO(Args))
AddGoldPlugin(ToolChain, Args, CmdArgs);
bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
@@ -8086,7 +8085,7 @@ void gnutools::Link::ConstructJob(Compil
for (const auto &Path : Paths)
CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
- if (D.IsUsingLTO(getToolChain(), Args))
+ if (D.IsUsingLTO(Args))
AddGoldPlugin(ToolChain, Args, CmdArgs);
if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
Modified: cfe/trunk/test/Driver/fsanitize.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize.c?rev=240170&r1=240169&r2=240170&view=diff
==============================================================================
--- cfe/trunk/test/Driver/fsanitize.c (original)
+++ cfe/trunk/test/Driver/fsanitize.c Fri Jun 19 14:57:46 2015
@@ -202,17 +202,20 @@
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-UBSAN-DARWIN
// CHECK-FSAN-UBSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-derived-cast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-DCAST
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-unrelated-cast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-UCAST
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-nvcall -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NVCALL
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-vcall -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-VCALL
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-derived-cast -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-DCAST
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-unrelated-cast -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-UCAST
+// RUN: %clang -target x86_64-linux-gnu -flto -fsanitize=cfi-nvcall -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NVCALL
+// RUN: %clang -target x86_64-linux-gnu -flto -fsanitize=cfi-vcall -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-VCALL
// CHECK-CFI: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall
// CHECK-CFI-DCAST: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast
// CHECK-CFI-UCAST: -emit-llvm-bc{{.*}}-fsanitize=cfi-unrelated-cast
// CHECK-CFI-NVCALL: -emit-llvm-bc{{.*}}-fsanitize=cfi-nvcall
// CHECK-CFI-VCALL: -emit-llvm-bc{{.*}}-fsanitize=cfi-vcall
+// RUN: %clang -target x86_64-linux-gnu -flto -fsanitize=cfi-derived-cast -fno-lto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOLTO
+// CHECK-CFI-NOLTO: '-fsanitize=cfi-derived-cast' only allowed with '-flto'
+
// RUN: %clang -target x86_64-linux-gnu -fsanitize-trap=address -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-TRAP
// CHECK-ASAN-TRAP: error: unsupported argument 'address' to option '-fsanitize-trap'
More information about the cfe-commits
mailing list