aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/TargetInfo.cpp16
-rw-r--r--clang/lib/Basic/Targets/RISCV.h22
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp4
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp40
5 files changed, 92 insertions, 0 deletions
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 29f5cd1..9219533 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -198,6 +198,22 @@ TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {
return false;
}
+CFBranchLabelSchemeKind TargetInfo::getDefaultCFBranchLabelScheme() const {
+ // if this hook is called, the target should override it to return a
+ // non-default scheme
+ llvm::report_fatal_error("not implemented");
+}
+
+bool TargetInfo::checkCFBranchLabelSchemeSupported(
+ const CFBranchLabelSchemeKind Scheme, DiagnosticsEngine &Diags) const {
+ if (Scheme != CFBranchLabelSchemeKind::Default)
+ Diags.Report(diag::err_opt_not_valid_on_target)
+ << (Twine("mcf-branch-label-scheme=") +
+ getCFBranchLabelSchemeFlagVal(Scheme))
+ .str();
+ return false;
+}
+
bool
TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const {
Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return";
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 351ef21..bf40edb 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -134,6 +134,28 @@ public:
bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
bool &HasSizeMismatch) const override;
+
+ bool checkCFProtectionBranchSupported(DiagnosticsEngine &) const override {
+ // Always generate Zicfilp lpad insns
+ // Non-zicfilp CPUs would read them as NOP
+ return true;
+ }
+
+ CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const override {
+ return CFBranchLabelSchemeKind::FuncSig;
+ }
+
+ bool
+ checkCFBranchLabelSchemeSupported(const CFBranchLabelSchemeKind Scheme,
+ DiagnosticsEngine &Diags) const override {
+ switch (Scheme) {
+ case CFBranchLabelSchemeKind::Default:
+ case CFBranchLabelSchemeKind::Unlabeled:
+ case CFBranchLabelSchemeKind::FuncSig:
+ return true;
+ }
+ return TargetInfo::checkCFBranchLabelSchemeSupported(Scheme, Diags);
+ }
};
class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
public:
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index d53d479..2381fa9 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1164,6 +1164,16 @@ void CodeGenModule::Release() {
// Indicate that we want to instrument branch control flow protection.
getModule().addModuleFlag(llvm::Module::Min, "cf-protection-branch",
1);
+
+ auto Scheme = CodeGenOpts.getCFBranchLabelScheme();
+ if (Target.checkCFBranchLabelSchemeSupported(Scheme, getDiags())) {
+ if (Scheme == CFBranchLabelSchemeKind::Default)
+ Scheme = Target.getDefaultCFBranchLabelScheme();
+ getModule().addModuleFlag(
+ llvm::Module::Error, "cf-branch-label-scheme",
+ llvm::MDString::get(getLLVMContext(),
+ getCFBranchLabelSchemeFlagVal(Scheme)));
+ }
}
if (CodeGenOpts.FunctionReturnThunks)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index a2e403e..cbcc3b8 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7016,6 +7016,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
CmdArgs.push_back(
Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
+
+ if (Arg *SA = Args.getLastArg(options::OPT_mcf_branch_label_scheme_EQ))
+ CmdArgs.push_back(Args.MakeArgString(Twine("-mcf-branch-label-scheme=") +
+ SA->getValue()));
}
if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ))
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index efd8525..6c09843 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1688,6 +1688,18 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
else if (Opts.CFProtectionBranch)
GenerateArg(Consumer, OPT_fcf_protection_EQ, "branch");
+ if (Opts.CFProtectionBranch) {
+ switch (Opts.getCFBranchLabelScheme()) {
+ case CFBranchLabelSchemeKind::Default:
+ break;
+#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
+ case CFBranchLabelSchemeKind::Kind: \
+ GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, #FlagVal); \
+ break;
+#include "clang/Basic/CFProtectionOptions.def"
+ }
+ }
+
if (Opts.FunctionReturnThunks)
GenerateArg(Consumer, OPT_mfunction_return_EQ, "thunk-extern");
@@ -2022,6 +2034,22 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
}
+ if (Opts.CFProtectionBranch && T.isRISCV()) {
+ if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
+ const auto Scheme =
+ llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
+#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
+ .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
+#include "clang/Basic/CFProtectionOptions.def"
+ .Default(CFBranchLabelSchemeKind::Default);
+ if (Scheme != CFBranchLabelSchemeKind::Default)
+ Opts.setCFBranchLabelScheme(Scheme);
+ else
+ Diags.Report(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << A->getValue();
+ }
+ }
+
if (const Arg *A = Args.getLastArg(OPT_mfunction_return_EQ)) {
auto Val = llvm::StringSwitch<llvm::FunctionReturnThunksKind>(A->getValue())
.Case("keep", llvm::FunctionReturnThunksKind::Keep)
@@ -3952,6 +3980,18 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
}
}
+ if (Opts.CFProtectionBranch) {
+ if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
+ const auto Scheme =
+ llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
+#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
+ .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
+#include "clang/Basic/CFProtectionOptions.def"
+ .Default(CFBranchLabelSchemeKind::Default);
+ Opts.setCFBranchLabelScheme(Scheme);
+ }
+ }
+
if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&
!Args.hasArg(OPT_sycl_std_EQ)) {
// If the user supplied -fsycl-is-device or -fsycl-is-host, but failed to