From: Adrian McCarthy Date: Tue, 9 Jan 2018 23:49:30 +0000 (+0000) Subject: Reland "Emit Function IDs table for Control Flow Guard" X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5855293e6fbb63b4f7a0fb800e8ab69696b9882f;p=clang Reland "Emit Function IDs table for Control Flow Guard" Adds option /guard:cf to clang-cl and -cfguard to cc1 to emit function IDs of functions that have their address taken into a section named .gfids$y for compatibility with Microsoft's Control Flow Guard feature. The original patch didn't have the lit.local.cfg file that restricts the new test to x86, thus the new test was failing on the non-x86 bots. Differential Revision: https://reviews.llvm.org/D40531 The reverts r322008, which was a revert of r322005. This reverts commit a05b89f9aca70597dc79fe97bc49b50b51f525ba. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@322136 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td index c1f0a89b5d..c1bc7eea3c 100644 --- a/include/clang/Driver/CLCompatOptions.td +++ b/include/clang/Driver/CLCompatOptions.td @@ -235,6 +235,8 @@ def _SLASH_Fi : CLCompileJoined<"Fi">, def _SLASH_Fo : CLCompileJoined<"Fo">, HelpText<"Set output object file, or directory (ends in / or \\) (with /c)">, MetaVarName<"">; +def _SLASH_Guard : CLJoined<"guard:">, + HelpText<"Enable Control Flow Guard with /guard:cf">; def _SLASH_GX : CLFlag<"GX">, HelpText<"Enable exception handling">; def _SLASH_GX_ : CLFlag<"GX-">, @@ -364,7 +366,6 @@ def _SLASH_GL_ : CLFlag<"GL-">; def _SLASH_Gm : CLFlag<"Gm">; def _SLASH_Gm_ : CLFlag<"Gm-">; def _SLASH_GT : CLFlag<"GT">; -def _SLASH_Guard : CLJoined<"guard:">; def _SLASH_GZ : CLFlag<"GZ">; def _SLASH_H : CLFlag<"H">; def _SLASH_homeparams : CLFlag<"homeparams">; diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index af4ea3e3e6..821837d5e6 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -492,6 +492,8 @@ 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, Flags<[CC1Option]>, HelpText<"OpenCL only. This option disables all optimizations. By default optimizations are enabled.">; def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, Group, Flags<[CC1Option]>, diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 7948459934..7db368ccf4 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -38,6 +38,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(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. CODEGENOPT(CoverageExitBlockBeforeBody, 1, 0) ///< Whether to emit the exit block before the body blocks in GCNO files. diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index b08ead80c1..acf6e4d63c 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -457,6 +457,10 @@ void CodeGenModule::Release() { // Indicate that we want CodeView in the metadata. getModule().addModuleFlag(llvm::Module::Warning, "CodeView", 1); } + if (CodeGenOpts.ControlFlowGuard) { + // We want function ID tables for Control Flow Guard. + getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1); + } if (CodeGenOpts.OptimizationLevel > 0 && CodeGenOpts.StrictVTablePointers) { // We don't support LTO with 2 with different StrictVTablePointers // FIXME: we could support it by stripping all the information introduced diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 2db660dc2b..5c536575da 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -5079,6 +5079,10 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, else CmdArgs.push_back("msvc"); } + + if (Args.hasArg(options::OPT__SLASH_Guard) && + Args.getLastArgValue(options::OPT__SLASH_Guard).equals_lower("cf")) + CmdArgs.push_back("-cfguard"); } visualstudio::Compiler *Clang::getCLFallback() const { diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index cd4df03dc9..07b1668fc0 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -721,6 +721,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name); Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier); + Opts.ControlFlowGuard = Args.hasArg(OPT_cfguard); + Opts.DisableGCov = Args.hasArg(OPT_test_coverage); Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes);