Commit d157a9bc authored by Andrew Paverd's avatar Andrew Paverd Committed by David Chisnall
Browse files

Add Windows Control Flow Guard checks (/guard:cf).

Summary:
A new function pass (Transforms/CFGuard/CFGuard.cpp) inserts CFGuard checks on
indirect function calls, using either the check mechanism (X86, ARM, AArch64) or
or the dispatch mechanism (X86-64). The check mechanism requires a new calling
convention for the supported targets. The dispatch mechanism adds the target as
an operand bundle, which is processed by SelectionDAG. Another pass
(CodeGen/CFGuardLongjmp.cpp) identifies and emits valid longjmp targets, as
required by /guard:cf. This feature is enabled using the `cfguard` CC1 option.

Reviewers: thakis, rnk, theraven, pcc

Subscribers: ychen, hans, metalcanine, dmajor, tomrittervg, alex, mehdi_amini, mgorny, javed.absar, kristof.beyls, hiraditya, steven_wu, dexonsmith, cfe-commits, llvm-commits

Tags: #clang, #llvm

Differential Revision: https://reviews.llvm.org/D65761
parent a233e7d7
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -124,7 +124,11 @@ Output path for the plist report

.. option:: -cfguard

Emit tables required for Windows Control Flow Guard.
Emit tables and checks for Windows Control Flow Guard.

.. option:: -cfguard-no-checks

Emit tables required for Windows Control Flow Guard without checks.

.. option:: -client\_name<arg>

+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) o
CODEGENOPT(Autolink          , 1, 1) ///< -fno-autolink
CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
CODEGENOPT(Backchain         , 1, 0) ///< -mbackchain
CODEGENOPT(ControlFlowGuardNoChecks  , 1, 0) ///< -cfguard-no-checks
CODEGENOPT(ControlFlowGuard  , 1, 0) ///< -cfguard
CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files.
CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files.
+4 −0
Original line number Diff line number Diff line
@@ -400,6 +400,10 @@ def msign_return_address_key_EQ : Joined<["-"], "msign-return-address-key=">,
    Values<"a_key,b_key">;
def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">;
def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">;
def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">,
    HelpText<"Emit Windows Control Flow Guard tables only (no checks)">;
def cfguard : Flag<["-"], "cfguard">,
    HelpText<"Emit Windows Control Flow Guard tables and checks">;

//===----------------------------------------------------------------------===//
// Dependency Output Options
+0 −2
Original line number Diff line number Diff line
@@ -503,8 +503,6 @@ def bind__at__load : Flag<["-"], "bind_at_load">;
def bundle__loader : Separate<["-"], "bundle_loader">;
def bundle : Flag<["-"], "bundle">;
def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>;
def cfguard : Flag<["-"], "cfguard">, Flags<[CC1Option]>,
  HelpText<"Emit tables required for Windows Control Flow Guard.">;
def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, Flags<[CC1Option]>,
  HelpText<"OpenCL only. This option disables all optimizations. By default optimizations are enabled.">;
def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, Group<opencl_Group>, Flags<[CC1Option]>,
+5 −2
Original line number Diff line number Diff line
@@ -482,8 +482,11 @@ void CodeGenModule::Release() {
    getModule().addModuleFlag(llvm::Module::Warning, "CodeViewGHash", 1);
  }
  if (CodeGenOpts.ControlFlowGuard) {
    // We want function ID tables for Control Flow Guard.
    getModule().addModuleFlag(llvm::Module::Warning, "cfguardtable", 1);
    // Function ID tables and checks for Control Flow Guard (cfguard=2).
    getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 2);
  } else if (CodeGenOpts.ControlFlowGuardNoChecks) {
    // Function ID tables for Control Flow Guard (cfguard=1).
    getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1);
  }
  if (CodeGenOpts.OptimizationLevel > 0 && CodeGenOpts.StrictVTablePointers) {
    // We don't support LTO with 2 with different StrictVTablePointers
Loading