https://github.com/mylai-mtk updated https://github.com/llvm/llvm-project/pull/109600
>From 3cae49e7cbff687c1303f8204f70c9c1105a9560 Mon Sep 17 00:00:00 2001 From: Ming-Yi Lai <ming-yi....@mediatek.com> Date: Wed, 4 Sep 2024 18:40:48 +0800 Subject: [PATCH 1/3] [clang][RISCV] Accept -fcf-protection=branch when Zicfilp extension is on -fcf-protection=branch turns on indirect branching protection on RISC-V targets with Zicfilp extension. --- clang/lib/Basic/Targets/RISCV.h | 7 +++++++ clang/test/CodeGen/RISCV/riscv-cf-protection.c | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 clang/test/CodeGen/RISCV/riscv-cf-protection.c diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index b808ccc8e9cfe9..13d4b4c04ce8e0 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -131,6 +131,13 @@ class RISCVTargetInfo : public TargetInfo { bool supportsCpuInit() const override { return getTriple().isOSLinux(); } bool validateCpuSupports(StringRef Feature) const override; bool isValidFeatureName(StringRef Name) const override; + + bool + checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override { + if (ISAInfo->hasExtension("zicfilp")) + return true; + return TargetInfo::checkCFProtectionBranchSupported(Diags); + } }; class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { public: diff --git a/clang/test/CodeGen/RISCV/riscv-cf-protection.c b/clang/test/CodeGen/RISCV/riscv-cf-protection.c new file mode 100644 index 00000000000000..56a3c48cde53a1 --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-cf-protection.c @@ -0,0 +1,18 @@ +// RUN: not %clang --target=riscv32 -fcf-protection=branch -c %s \ +// RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s + +// RUN: not %clang --target=riscv32 -fcf-protection=branch -c %s \ +// RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s + +// RUN: not %clang --target=riscv64 -fcf-protection=branch -c %s \ +// RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s + +// RUN: not %clang --target=riscv64 -fcf-protection=branch -c %s \ +// RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s + +// CHECK-BRANCH-PROT-INVALID: error: option 'cf-protection=branch' cannot be +// CHECK-BRANCH-PROT-INVALID-SAME: specified on this target >From 3ac3d29294232f6688d8e570aac8f57a5262df05 Mon Sep 17 00:00:00 2001 From: Ming-Yi Lai <ming-yi....@mediatek.com> Date: Fri, 6 Sep 2024 19:00:10 +0800 Subject: [PATCH 2/3] [Clang] Introduce -fcf-branch-label-scheme=unlabeled|func-sig This flag controls the scheme of the labels of landing pad insns. Landing pad insns are special insns that mark the targets of indirect jumps. In RISC-V Zicfilp extension, its landing pad insn further encodes a field of `label', which can be used to limit the sources of indirect jumps to those that set up a matching label according to a `scheme' selected at compile time. This flag controls the selection of that `scheme'. It's named `-fcf-branch-label-scheme` since the generation of landing pad insns is turned on by `-fcf-protection=branch`. --- .../include/clang/Basic/CFProtectionOptions.h | 22 ++++++++ clang/include/clang/Basic/CodeGenOptions.def | 2 + clang/include/clang/Basic/CodeGenOptions.h | 1 + clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/LangOptions.h | 2 + clang/include/clang/Basic/TargetInfo.h | 4 ++ clang/include/clang/Driver/Options.td | 4 ++ clang/lib/Basic/TargetInfo.cpp | 5 ++ clang/lib/Basic/Targets/RISCV.h | 4 ++ clang/lib/Basic/Targets/X86.h | 4 ++ clang/lib/Driver/ToolChains/Clang.cpp | 4 ++ clang/lib/Frontend/CompilerInvocation.cpp | 37 +++++++++++++ .../test/CodeGen/RISCV/riscv-cf-protection.c | 52 ++++++++++++++++--- 13 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 clang/include/clang/Basic/CFProtectionOptions.h diff --git a/clang/include/clang/Basic/CFProtectionOptions.h b/clang/include/clang/Basic/CFProtectionOptions.h new file mode 100644 index 00000000000000..d97f8489c4631f --- /dev/null +++ b/clang/include/clang/Basic/CFProtectionOptions.h @@ -0,0 +1,22 @@ +//===--- CFProtectionOptions.h ----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines constants for -fcf-protection and other related flags. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_CFPROTECTIONOPTIONS_H +#define LLVM_CLANG_BASIC_CFPROTECTIONOPTIONS_H + +namespace clang { + +enum class CFBranchLabelSchemeKind { Default, Unlabeled, FuncSig }; + +} // namespace clang + +#endif // #ifndef LLVM_CLANG_BASIC_CFPROTECTIONOPTIONS_H diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index b600198998d85b..de7ae73f8a603b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -110,6 +110,8 @@ CODEGENOPT(CFProtectionReturn , 1, 0) ///< if -fcf-protection is ///< set to full or return. CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is ///< set to full or branch. +ENUM_CODEGENOPT(CFBranchLabelScheme, CFBranchLabelSchemeKind, 2, + CFBranchLabelSchemeKind::Default) ///< if -mcf-branch-label-scheme is set. CODEGENOPT(FunctionReturnThunks, 1, 0) ///< -mfunction-return={keep|thunk-extern} CODEGENOPT(IndirectBranchCSPrefix, 1, 0) ///< if -mindirect-branch-cs-prefix ///< is set. diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index f2a707a8ba8d76..a6953c17a447ef 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H #define LLVM_CLANG_BASIC_CODEGENOPTIONS_H +#include "clang/Basic/CFProtectionOptions.h" #include "clang/Basic/PointerAuthOptions.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/XRayInstr.h" diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index fd3346d29f26a3..68db400c22e6c1 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -364,6 +364,8 @@ BENIGN_LANGOPT(CompatibilityQualifiedIdBlockParamTypeChecking, 1, 0, LANGOPT(ObjCDisableDirectMethodsForTesting, 1, 0, "Disable recognition of objc_direct methods") LANGOPT(CFProtectionBranch , 1, 0, "Control-Flow Branch Protection enabled") +ENUM_LANGOPT(CFBranchLabelScheme, CFBranchLabelSchemeKind, 2, CFBranchLabelSchemeKind::Default, + "Control-Flow Branch Protection Label Scheme") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode") LANGOPT(IncludeDefaultHeader, 1, 0, "Include default header file for OpenCL") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 6c186c410e158d..c3d53ca92d450c 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H #define LLVM_CLANG_BASIC_LANGOPTIONS_H +#include "clang/Basic/CFProtectionOptions.h" #include "clang/Basic/CommentOptions.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangStandard.h" @@ -73,6 +74,7 @@ class LangOptionsBase { public: using Visibility = clang::Visibility; using RoundingMode = llvm::RoundingMode; + using CFBranchLabelSchemeKind = clang::CFBranchLabelSchemeKind; enum GCMode { NonGC, GCOnly, HybridGC }; enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index f31d88a354ea28..d96a4fcca56840 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -16,6 +16,7 @@ #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/BitmaskEnum.h" +#include "clang/Basic/CFProtectionOptions.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" @@ -1727,6 +1728,9 @@ class TargetInfo : public TransferrableTargetInfo, virtual bool checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const; + /// Get the target default CFBranchLabelScheme scheme + virtual CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const; + /// Check if the target supports CFProtection return. virtual bool checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 376d7d4290c0bf..e6a46b9fb909e0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2841,6 +2841,10 @@ def fcf_protection : Flag<["-"], "fcf-protection">, Group<f_Group>, Visibility<[ClangOption, CLOption, CC1Option]>, Alias<fcf_protection_EQ>, AliasArgs<["full"]>, HelpText<"Enable cf-protection in 'full' mode">; +def mcf_branch_label_scheme_EQ : Joined<["-"], "mcf-branch-label-scheme=">, + Visibility<[ClangOption, CC1Option]>, Group<m_Group>, + HelpText<"Select label scheme for branch control-flow architecture protection">, + Values<"unlabeled,func-sig">; def mfunction_return_EQ : Joined<["-"], "mfunction-return=">, Group<m_Group>, Visibility<[ClangOption, CLOption, CC1Option]>, HelpText<"Replace returns with jumps to ``__x86_return_thunk`` (x86 only, error otherwise)">, diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 29f5cd14e46e11..8dfd10984ce685 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -192,6 +192,11 @@ void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) { UserLabelPrefix = ULP; } +CFBranchLabelSchemeKind TargetInfo::getDefaultCFBranchLabelScheme() const { + // if this hook is called, the target should override it + llvm::report_fatal_error("not implemented"); +} + bool TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const { Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch"; diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index 13d4b4c04ce8e0..e375ea78cdf62f 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -138,6 +138,10 @@ class RISCVTargetInfo : public TargetInfo { return true; return TargetInfo::checkCFProtectionBranchSupported(Diags); } + + CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const override { + return CFBranchLabelSchemeKind::FuncSig; + }; }; class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { public: diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index a99ae62984c7d5..77d55257f8c52a 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -273,6 +273,10 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { return TargetInfo::checkCFProtectionBranchSupported(Diags); }; + CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const override { + return CFBranchLabelSchemeKind::Unlabeled; + }; + virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap, StringRef Constraint, unsigned Size) const; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0bab48caf1a5e2..d3c5c3d9872ee4 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -7012,6 +7012,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 efd852593468aa..1268eaa466e654 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1688,6 +1688,19 @@ 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; + case CFBranchLabelSchemeKind::Unlabeled: + GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, "unlabeled"); + break; + case CFBranchLabelSchemeKind::FuncSig: + GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, "func-sig"); + break; + } + } + if (Opts.FunctionReturnThunks) GenerateArg(Consumer, OPT_mfunction_return_EQ, "thunk-extern"); @@ -2022,6 +2035,20 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name; } + if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) { + if (Opts.CFProtectionBranch) { + const StringRef Scheme = A->getValue(); + if (Scheme == "unlabeled") + Opts.setCFBranchLabelScheme(CFBranchLabelSchemeKind::Unlabeled); + else if (Scheme == "func-sig") + Opts.setCFBranchLabelScheme(CFBranchLabelSchemeKind::FuncSig); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << Scheme; + } else + Diags.Report(diag::warn_drv_unused_argument) << A->getAsString(Args); + } + 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 +3979,16 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, } } + if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) { + if (Opts.CFProtectionBranch) { + const StringRef Scheme = A->getValue(); + if (Scheme == "unlabeled") + Opts.setCFBranchLabelScheme(CFBranchLabelSchemeKind::Unlabeled); + else if (Scheme == "func-sig") + Opts.setCFBranchLabelScheme(CFBranchLabelSchemeKind::FuncSig); + } + } + 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 diff --git a/clang/test/CodeGen/RISCV/riscv-cf-protection.c b/clang/test/CodeGen/RISCV/riscv-cf-protection.c index 56a3c48cde53a1..02a22006b1638f 100644 --- a/clang/test/CodeGen/RISCV/riscv-cf-protection.c +++ b/clang/test/CodeGen/RISCV/riscv-cf-protection.c @@ -1,18 +1,58 @@ -// RUN: not %clang --target=riscv32 -fcf-protection=branch -c %s \ +// RUN: %clang --target=riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -c %s \ // RUN: -o /dev/null 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s +// RUN: | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s -// RUN: not %clang --target=riscv32 -fcf-protection=branch -c %s \ +// RUN: %clang --target=riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32i_zicfilp1p0 -mcf-branch-label-scheme=func-sig -c %s \ // RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s + +// RUN: not %clang --target=riscv32 -fcf-protection=branch \ +// RUN: -mcf-branch-label-scheme=unlabeled -c %s -o /dev/null 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s -// RUN: not %clang --target=riscv64 -fcf-protection=branch -c %s \ -// RUN: -o /dev/null 2>&1 \ +// RUN: not %clang --target=riscv32 -fcf-protection=branch \ +// RUN: -mcf-branch-label-scheme=func-sig -c %s -o /dev/null 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s -// RUN: not %clang --target=riscv64 -fcf-protection=branch -c %s \ +// RUN: %clang --target=riscv32 -mcf-branch-label-scheme=unlabeled -c %s \ +// RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s + +// RUN: %clang --target=riscv32 -mcf-branch-label-scheme=func-sig -c %s \ +// RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s + +// RUN: %clang --target=riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -c %s \ +// RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s + +// RUN: %clang --target=riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64i_zicfilp1p0 -mcf-branch-label-scheme=func-sig -c %s \ // RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s + +// RUN: not %clang --target=riscv64 -fcf-protection=branch \ +// RUN: -mcf-branch-label-scheme=unlabeled -c %s -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s + +// RUN: not %clang --target=riscv64 -fcf-protection=branch \ +// RUN: -mcf-branch-label-scheme=func-sig -c %s -o /dev/null 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s +// RUN: %clang --target=riscv64 -mcf-branch-label-scheme=unlabeled -c %s \ +// RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s + +// RUN: %clang --target=riscv64 -mcf-branch-label-scheme=func-sig -c %s \ +// RUN: -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s + // CHECK-BRANCH-PROT-INVALID: error: option 'cf-protection=branch' cannot be // CHECK-BRANCH-PROT-INVALID-SAME: specified on this target +// CHECK-UNLABELED-SCHEME-UNUSED: warning: argument unused during compilation: +// CHECK-UNLABELED-SCHEME-UNUSED-SAME: '-mcf-branch-label-scheme=unlabeled' +// CHECK-FUNC-SIG-SCHEME-UNUSED: warning: argument unused during compilation: +// CHECK-FUNC-SIG-SCHEME-UNUSED-SAME: '-mcf-branch-label-scheme=func-sig' >From ce2a105e424ddd039cb56b06fe95c33ff17406a3 Mon Sep 17 00:00:00 2001 From: Ming-Yi Lai <ming-yi....@mediatek.com> Date: Fri, 10 May 2024 14:16:59 +0800 Subject: [PATCH 3/3] [clang][RISCV] Add Zicfilp CFI scheme preprocessor macros These macros allow assembly files to know which CFI label to use when the target has Zicfilp enabled. --- clang/lib/Basic/Targets/RISCV.cpp | 20 ++++++++++++ .../test/CodeGen/RISCV/riscv-cf-protection.c | 32 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index a4925e84784af9..9382645d2c7110 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -224,6 +224,26 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, else Builder.defineMacro("__riscv_32e"); } + + if (ISAInfo->hasExtension("zicfilp") && Opts.CFProtectionBranch) { + auto Scheme = Opts.getCFBranchLabelScheme(); + if (Scheme == CFBranchLabelSchemeKind::Default) + Scheme = getDefaultCFBranchLabelScheme(); + + switch (Scheme) { + case CFBranchLabelSchemeKind::Unlabeled: + Builder.defineMacro("__riscv_landing_pad", "1"); + Builder.defineMacro("__riscv_landing_pad_unlabeled", "1"); + break; + case CFBranchLabelSchemeKind::Default: + llvm_unreachable("default cf-branch-label scheme should already be " + "transformed to other scheme"); + case CFBranchLabelSchemeKind::FuncSig: + Builder.defineMacro("__riscv_landing_pad", "1"); + Builder.defineMacro("__riscv_landing_pad_func_sig", "1"); + break; + } + } } static constexpr Builtin::Info BuiltinInfo[] = { diff --git a/clang/test/CodeGen/RISCV/riscv-cf-protection.c b/clang/test/CodeGen/RISCV/riscv-cf-protection.c index 02a22006b1638f..a2b41dbd8b7c10 100644 --- a/clang/test/CodeGen/RISCV/riscv-cf-protection.c +++ b/clang/test/CodeGen/RISCV/riscv-cf-protection.c @@ -1,3 +1,21 @@ +// Default cf-branch-label-scheme is func-sig +// RUN: %clang --target=riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32i_zicfilp1p0 -fcf-protection=branch -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-ZICFILP-FUNC-SIG %s +// RUN: %clang --target=riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64i_zicfilp1p0 -fcf-protection=branch -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-ZICFILP-FUNC-SIG %s + +// RUN: %clang --target=riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32i_zicfilp1p0 -fcf-protection=branch \ +// RUN: -mcf-branch-label-scheme=unlabeled -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-ZICFILP-UNLABELED %s + +// RUN: %clang --target=riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32i_zicfilp1p0 -fcf-protection=branch \ +// RUN: -mcf-branch-label-scheme=func-sig -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-ZICFILP-FUNC-SIG %s + // RUN: %clang --target=riscv32 -menable-experimental-extensions \ // RUN: -march=rv32i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -c %s \ // RUN: -o /dev/null 2>&1 \ @@ -24,6 +42,16 @@ // RUN: -o /dev/null 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s +// RUN: %clang --target=riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64i_zicfilp1p0 -fcf-protection=branch \ +// RUN: -mcf-branch-label-scheme=unlabeled -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-ZICFILP-UNLABELED %s + +// RUN: %clang --target=riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64i_zicfilp1p0 -fcf-protection=branch \ +// RUN: -mcf-branch-label-scheme=func-sig -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-ZICFILP-FUNC-SIG %s + // RUN: %clang --target=riscv64 -menable-experimental-extensions \ // RUN: -march=rv64i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -c %s \ // RUN: -o /dev/null 2>&1 \ @@ -50,6 +78,10 @@ // RUN: -o /dev/null 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s +// CHECK-ZICFILP-UNLABELED-DAG: __riscv_landing_pad 1{{$}} +// CHECK-ZICFILP-UNLABELED-DAG: __riscv_landing_pad_unlabeled 1{{$}} +// CHECK-ZICFILP-FUNC-SIG-DAG: __riscv_landing_pad 1{{$}} +// CHECK-ZICFILP-FUNC-SIG-DAG: __riscv_landing_pad_func_sig 1{{$}} // CHECK-BRANCH-PROT-INVALID: error: option 'cf-protection=branch' cannot be // CHECK-BRANCH-PROT-INVALID-SAME: specified on this target // CHECK-UNLABELED-SCHEME-UNUSED: warning: argument unused during compilation: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits