[PATCH] D65761: Add Windows Control Flow Guard checks (/guard:cf).

Hans Wennborg via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 6 05:12:07 PDT 2019


hans added a comment.
Herald added a subscriber: ychen.

This is very exciting! I didn't look closely at the actual instrumentation code, as rnk knows that better and had some good comments.



================
Comment at: clang/include/clang/Driver/Options.td:500
 def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>;
+def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">, Flags<[CC1Option]>,
+  HelpText<"Emit Windows Control Flow Guard tables only (no checks).">;
----------------
rnk wrote:
> @hans, WDYT about the -cc1 interface? I think this is fine.
The -cc1 interface looks good to me, but since these are cc1 options only, I think they should be in CC1Options.td, not Options.td (I realize this is a pre-existing issue with -cfguard).


================
Comment at: clang/lib/CodeGen/CodeGenModule.cpp:493
+  }
   if (CodeGenOpts.ControlFlowGuard) {
+    // Function ID tables and checks for Control Flow Guard (cfguard=2).
----------------
Maybe check for this first, and then the ControlFlowGuardNoChecks one in an else-if, to make this one take precedence?


================
Comment at: clang/lib/Driver/ToolChains/Clang.cpp:5971
+
+    if (Instrument && !NoChecks)
+      //Emit CFG instrumentation and the table of address-taken functions.
----------------
It seems unfortunate that the Instrument and NoChecks variables allow four different states. whereas I think the logic should really only allow for three: 1) do nothing, 2) tables only, 3) tables and checks. Maybe we could have an enum instead?


================
Comment at: clang/lib/Driver/ToolChains/Clang.cpp:5972
+    if (Instrument && !NoChecks)
+      //Emit CFG instrumentation and the table of address-taken functions.
       CmdArgs.push_back("-cfguard");
----------------
rnk wrote:
> Comment formatting needs to be fixed, you can use clang-format for this.
Also I'd suggest braces since even though there's just one statement, there are multiple lines here and in the else block.


================
Comment at: clang/lib/Driver/ToolChains/MSVC.cpp:420
+  // Flags that can simply be passed through.
+  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_guard);
 
----------------
Thanks for remembering /fallback. Please add a /guard:cf option to the first test in clang/test/Driver/cl-fallback.c


================
Comment at: llvm/docs/LangRef.rst:441
+    This calling convention is used for the Control Flow Guard check function,
+	which can be inserted before indirect calls to check that the call target 
+	is a valid function address. The check function has no return value, but
----------------
Indentation looks a little off here.

"function, which can be inserted before indirect calls" -- maybe instead "function, calls to which can be inserted ..."


================
Comment at: llvm/docs/LangRef.rst:447
+
+    - On X86_32 the target address is passed in ECX.
+    - On ARM the target address is passed in R0.
----------------
I don't think X86_32 is common nomenclature.. maybe just X86 is enough.


================
Comment at: llvm/docs/LangRef.rst:456
+    (architecture-specific) register. All other function arguments are 
+	passed as usual.
+
----------------
Indentation off here too.


================
Comment at: llvm/docs/LangRef.rst:458
+
+    - On X86-64 the target address is passed in RAX.
 "``cc <n>``" - Numbered convention
----------------
Maybe explicitly call out in the text that this calling convention is only used on x86_64, and is used instead of cfguard_checkcc (iiuc)?


================
Comment at: llvm/include/llvm/IR/CallingConv.h:79
+    /// Special calling convention on Windows for calling the Control
+    /// Guard Check ICall funtion. The function take exactly one argument
+    /// (address of the target function) passed in the first argument register,
----------------
nit: s/take/takes/


================
Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:381
 
+  // Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2)
   if (mdconst::extract_or_null<ConstantInt>(
----------------
ultra nit: period at the end, here and for other comments


================
Comment at: llvm/lib/Target/X86/X86FixupCFGuard.cpp:13
+/// for such cases and replaces the pair of instructions with a single
+/// call/invoke. For example:
+///
----------------
Naive question: Why do we generate code as in the examples in the first place, and can't some general optimization pass do this folding? From the examples it looks like straight-forward constant propagation.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65761/new/

https://reviews.llvm.org/D65761





More information about the cfe-commits mailing list