diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 31 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/MSVC.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 1 |
4 files changed, 40 insertions, 21 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 75708d6e496..480a33f2728 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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 diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index ae12465d3f8..c60dc76ae1b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5975,26 +5975,19 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, } if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) { - SmallVector<StringRef, 1> SplitArgs; - StringRef(A->getValue()).split(SplitArgs, ","); - bool Instrument = false; - bool NoChecks = false; - for (StringRef Arg : SplitArgs) { - if (Arg.equals_lower("cf")) - Instrument = true; - else if (Arg.equals_lower("cf-")) - Instrument = false; - else if (Arg.equals_lower("nochecks")) - NoChecks = true; - else if (Arg.equals_lower("nochecks-")) - NoChecks = false; - else - D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << Arg; - } - // Currently there's no support emitting CFG instrumentation; the flag only - // emits the table of address-taken functions. - if (Instrument || NoChecks) + StringRef GuardArgs = A->getValue(); + // The only valid options are "cf", "cf,nochecks", and "cf-". + if (GuardArgs.equals_lower("cf")) { + // Emit CFG instrumentation and the table of address-taken functions. CmdArgs.push_back("-cfguard"); + } else if (GuardArgs.equals_lower("cf,nochecks")) { + // Emit only the table of address-taken functions. + CmdArgs.push_back("-cfguard-no-checks"); + } else if (GuardArgs.equals_lower("cf-")) { + // Do nothing, but we might want to emit a security warning in future. + } else { + D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << GuardArgs; + } } } diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 1d31844bfcc..4e143f6a5d3 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -422,6 +422,17 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link); + // Control Flow Guard checks + if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) { + StringRef GuardArgs = A->getValue(); + if (GuardArgs.equals_lower("cf") || GuardArgs.equals_lower("cf,nochecks")) { + // MSVC doesn't yet support the "nochecks" modifier. + CmdArgs.push_back("-guard:cf"); + } else if (GuardArgs.equals_lower("cf-")) { + CmdArgs.push_back("-guard:cf-"); + } + } + if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, options::OPT_fno_openmp, false)) { CmdArgs.push_back("-nodefaultlib:vcomp.lib"); @@ -679,6 +690,17 @@ std::unique_ptr<Command> visualstudio::Compiler::GetCommand( : "/Zc:threadSafeInit-"); } + // Control Flow Guard checks + if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) { + StringRef GuardArgs = A->getValue(); + if (GuardArgs.equals_lower("cf") || GuardArgs.equals_lower("cf,nochecks")) { + // MSVC doesn't yet support the "nochecks" modifier. + CmdArgs.push_back("/guard:cf"); + } else if (GuardArgs.equals_lower("cf-")) { + CmdArgs.push_back("/guard:cf-"); + } + } + // Pass through all unknown arguments so that the fallback command can see // them too. Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index f6e6f71b280..f197a67e7a3 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1003,6 +1003,7 @@ 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.ControlFlowGuardNoChecks = Args.hasArg(OPT_cfguard_no_checks); Opts.ControlFlowGuard = Args.hasArg(OPT_cfguard); Opts.DisableGCov = Args.hasArg(OPT_test_coverage); |