diff options
| -rw-r--r-- | include/clang/Driver/Options.td | 4 | ||||
| -rw-r--r-- | include/clang/Frontend/CodeGenOptions.def | 1 | ||||
| -rw-r--r-- | lib/CodeGen/CGCall.cpp | 3 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Arch/X86.cpp | 18 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Clang.cpp | 3 | ||||
| -rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 2 | ||||
| -rw-r--r-- | test/CodeGen/attr-speculative-load-hardening.c | 10 | ||||
| -rw-r--r-- | test/Driver/x86-target-features.c | 9 |
8 files changed, 45 insertions, 5 deletions
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index e4539ab080..32038dc733 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -2009,6 +2009,10 @@ def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group<m_Group>; def mretpoline : Flag<["-"], "mretpoline">, Group<m_Group>, Flags<[CoreOption,DriverOption]>; def mno_retpoline : Flag<["-"], "mno-retpoline">, Group<m_Group>, Flags<[CoreOption,DriverOption]>; +def mspeculative_load_hardening : Flag<["-"], "mspeculative-load-hardening">, + Group<m_Group>, Flags<[CoreOption,CC1Option]>; +def mno_speculative_load_hardening : Flag<["-"], "mno-speculative-load-hardening">, + Group<m_Group>, Flags<[CoreOption]>; def mrelax : Flag<["-"], "mrelax">, Group<m_riscv_Features_Group>, HelpText<"Enable linker relaxation">; diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 4968e7b2bf..f94979c3e6 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -211,6 +211,7 @@ CODEGENOPT(SanitizeCoverageStackDepth, 1, 0) ///< Enable max stack depth tracing CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers. CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled. CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float. +CODEGENOPT(SpeculativeLoadHardening, 1, 0) ///< Enable speculative load hardening. CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield accesses. CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition. CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index c2b4c95ae9..8857ffdde4 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1784,6 +1784,9 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone, FuncAttrs.addAttribute("stackrealign"); if (CodeGenOpts.Backchain) FuncAttrs.addAttribute("backchain"); + + if (CodeGenOpts.SpeculativeLoadHardening) + FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening); } if (getLangOpts().assumeFunctionsAreConvergent()) { diff --git a/lib/Driver/ToolChains/Arch/X86.cpp b/lib/Driver/ToolChains/Arch/X86.cpp index ff2023c2cb..bc707857d8 100644 --- a/lib/Driver/ToolChains/Arch/X86.cpp +++ b/lib/Driver/ToolChains/Arch/X86.cpp @@ -146,15 +146,23 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, // Translate the high level `-mretpoline` flag to the specific target feature // flags. We also detect if the user asked for retpoline external thunks but - // failed to ask for retpolines themselves. This is a bit hacky but keeps - // existing usages working. We should consider deprecated this and instead - // warning if the user requests external retpoline thunks and *doesn't* - // request some form of retpolines. - if (Args.hasArgNoClaim(options::OPT_mretpoline, options::OPT_mno_retpoline)) { + // failed to ask for retpolines themselves (through any of the different + // flags). This is a bit hacky but keeps existing usages working. We should + // consider deprecating this and instead warn if the user requests external + // retpoline thunks and *doesn't* request some form of retpolines. + if (Args.hasArgNoClaim(options::OPT_mretpoline, options::OPT_mno_retpoline, + options::OPT_mspeculative_load_hardening, + options::OPT_mno_speculative_load_hardening)) { if (Args.hasFlag(options::OPT_mretpoline, options::OPT_mno_retpoline, false)) { Features.push_back("+retpoline-indirect-calls"); Features.push_back("+retpoline-indirect-branches"); + } else if (Args.hasFlag(options::OPT_mspeculative_load_hardening, + options::OPT_mno_speculative_load_hardening, + false)) { + // On x86, speculative load hardening relies on at least using retpolines + // for indirect calls. + Features.push_back("+retpoline-indirect-calls"); } } else if (Args.hasFlag(options::OPT_mretpoline_external_thunk, options::OPT_mno_retpoline_external_thunk, false)) { diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index ff083c79f1..79129a7a7c 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -4132,6 +4132,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_pthread); + Args.AddLastArg(CmdArgs, options::OPT_mspeculative_load_hardening, + options::OPT_mno_speculative_load_hardening); + RenderSSPOptions(getToolChain(), Args, CmdArgs, KernelOrKext); // Translate -mstackrealign diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 4ac7929328..5210314493 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1147,6 +1147,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.KeepStaticConsts = Args.hasArg(OPT_fkeep_static_consts); + Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening); + return Success; } diff --git a/test/CodeGen/attr-speculative-load-hardening.c b/test/CodeGen/attr-speculative-load-hardening.c new file mode 100644 index 0000000000..ccbded44bb --- /dev/null +++ b/test/CodeGen/attr-speculative-load-hardening.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -mspeculative-load-hardening -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefix=SLH +// +// Check that we set the attribute on each function. + +int test1() { + return 42; +} +// SLH: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]] + +// SLH: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} } diff --git a/test/Driver/x86-target-features.c b/test/Driver/x86-target-features.c index 527a9a2cff..ee2e6afd61 100644 --- a/test/Driver/x86-target-features.c +++ b/test/Driver/x86-target-features.c @@ -140,6 +140,15 @@ // RETPOLINE-EXTERNAL-THUNK: "-target-feature" "+retpoline-external-thunk" // NO-RETPOLINE-EXTERNAL-THUNK: "-target-feature" "-retpoline-external-thunk" +// RUN: %clang -target i386-linux-gnu -mspeculative-load-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SLH %s +// RUN: %clang -target i386-linux-gnu -mretpoline -mspeculative-load-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=RETPOLINE %s +// RUN: %clang -target i386-linux-gnu -mno-speculative-load-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-SLH %s +// SLH-NOT: retpoline +// SLH: "-target-feature" "+retpoline-indirect-calls" +// SLH-NOT: retpoline +// SLH: "-mspeculative-load-hardening" +// NO-SLH-NOT: retpoline + // RUN: %clang -target i386-linux-gnu -mwaitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=WAITPKG %s // RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s // WAITPKG: "-target-feature" "+waitpkg" |
