Skip to content

Commit acd2093

Browse files
committed
[clang][RISCV] Introduce command line options for Zicfilp-backed forward-edge CFI
This patch enables the following command line flags for RISC-V targets: + `-fcf-protection=branch` turns on forward-edge control-flow integrity conditioning on RISC-V targets with Zicfilp extension + `-mcf-branch-label-scheme=unlabeled|func-sig` selects the label scheme used in the forward-edge CFI conditioning
1 parent ea902d1 commit acd2093

File tree

12 files changed

+151
-0
lines changed

12 files changed

+151
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===--- CFProtectionOptions.h ----------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines constants for -fcf-protection and other related flags.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_BASIC_CFPROTECTIONOPTIONS_H
14+
#define LLVM_CLANG_BASIC_CFPROTECTIONOPTIONS_H
15+
16+
namespace clang {
17+
18+
enum class CFBranchLabelSchemeKind { Default, Unlabeled, FuncSig };
19+
20+
} // namespace clang
21+
22+
#endif // #ifndef LLVM_CLANG_BASIC_CFPROTECTIONOPTIONS_H

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ CODEGENOPT(CFProtectionReturn , 1, 0) ///< if -fcf-protection is
110110
///< set to full or return.
111111
CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is
112112
///< set to full or branch.
113+
ENUM_CODEGENOPT(CFBranchLabelScheme, CFBranchLabelSchemeKind, 2,
114+
CFBranchLabelSchemeKind::Default) ///< if -mcf-branch-label-scheme is set.
113115
CODEGENOPT(FunctionReturnThunks, 1, 0) ///< -mfunction-return={keep|thunk-extern}
114116
CODEGENOPT(IndirectBranchCSPrefix, 1, 0) ///< if -mindirect-branch-cs-prefix
115117
///< is set.

clang/include/clang/Basic/CodeGenOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H
1414
#define LLVM_CLANG_BASIC_CODEGENOPTIONS_H
1515

16+
#include "clang/Basic/CFProtectionOptions.h"
1617
#include "clang/Basic/PointerAuthOptions.h"
1718
#include "clang/Basic/Sanitizers.h"
1819
#include "clang/Basic/XRayInstr.h"

clang/include/clang/Basic/LangOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ BENIGN_LANGOPT(CompatibilityQualifiedIdBlockParamTypeChecking, 1, 0,
364364
LANGOPT(ObjCDisableDirectMethodsForTesting, 1, 0,
365365
"Disable recognition of objc_direct methods")
366366
LANGOPT(CFProtectionBranch , 1, 0, "Control-Flow Branch Protection enabled")
367+
ENUM_LANGOPT(CFBranchLabelScheme, CFBranchLabelSchemeKind, 2, CFBranchLabelSchemeKind::Default,
368+
"Control-Flow Branch Protection Label Scheme")
367369
LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map")
368370
ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode")
369371
LANGOPT(IncludeDefaultHeader, 1, 0, "Include default header file for OpenCL")

clang/include/clang/Basic/LangOptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H
1515
#define LLVM_CLANG_BASIC_LANGOPTIONS_H
1616

17+
#include "clang/Basic/CFProtectionOptions.h"
1718
#include "clang/Basic/CommentOptions.h"
1819
#include "clang/Basic/LLVM.h"
1920
#include "clang/Basic/LangStandard.h"
@@ -73,6 +74,7 @@ class LangOptionsBase {
7374
public:
7475
using Visibility = clang::Visibility;
7576
using RoundingMode = llvm::RoundingMode;
77+
using CFBranchLabelSchemeKind = clang::CFBranchLabelSchemeKind;
7678

7779
enum GCMode { NonGC, GCOnly, HybridGC };
7880
enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };

clang/include/clang/Basic/TargetInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "clang/Basic/AddressSpaces.h"
1818
#include "clang/Basic/BitmaskEnum.h"
19+
#include "clang/Basic/CFProtectionOptions.h"
1920
#include "clang/Basic/CodeGenOptions.h"
2021
#include "clang/Basic/LLVM.h"
2122
#include "clang/Basic/LangOptions.h"
@@ -1727,6 +1728,9 @@ class TargetInfo : public TransferrableTargetInfo,
17271728
virtual bool
17281729
checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const;
17291730

1731+
/// Get the target default CFBranchLabelScheme scheme
1732+
virtual CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const;
1733+
17301734
/// Check if the target supports CFProtection return.
17311735
virtual bool
17321736
checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const;

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,10 @@ def fcf_protection : Flag<["-"], "fcf-protection">, Group<f_Group>,
28412841
Visibility<[ClangOption, CLOption, CC1Option]>,
28422842
Alias<fcf_protection_EQ>, AliasArgs<["full"]>,
28432843
HelpText<"Enable cf-protection in 'full' mode">;
2844+
def mcf_branch_label_scheme_EQ : Joined<["-"], "mcf-branch-label-scheme=">,
2845+
Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
2846+
HelpText<"Select label scheme for branch control-flow architecture protection">,
2847+
Values<"unlabeled,func-sig">;
28442848
def mfunction_return_EQ : Joined<["-"], "mfunction-return=">,
28452849
Group<m_Group>, Visibility<[ClangOption, CLOption, CC1Option]>,
28462850
HelpText<"Replace returns with jumps to ``__x86_return_thunk`` (x86 only, error otherwise)">,

clang/lib/Basic/TargetInfo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) {
192192
UserLabelPrefix = ULP;
193193
}
194194

195+
CFBranchLabelSchemeKind TargetInfo::getDefaultCFBranchLabelScheme() const {
196+
// if this hook is called, the target should override it
197+
llvm::report_fatal_error("not implemented");
198+
}
199+
195200
bool
196201
TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {
197202
Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";

clang/lib/Basic/Targets/RISCV.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,17 @@ class RISCVTargetInfo : public TargetInfo {
134134

135135
bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
136136
bool &HasSizeMismatch) const override;
137+
138+
bool
139+
checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
140+
if (ISAInfo->hasExtension("zicfilp"))
141+
return true;
142+
return TargetInfo::checkCFProtectionBranchSupported(Diags);
143+
}
144+
145+
CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const override {
146+
return CFBranchLabelSchemeKind::FuncSig;
147+
}
137148
};
138149
class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
139150
public:

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7012,6 +7012,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
70127012
if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
70137013
CmdArgs.push_back(
70147014
Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
7015+
7016+
if (Arg *SA = Args.getLastArg(options::OPT_mcf_branch_label_scheme_EQ))
7017+
CmdArgs.push_back(Args.MakeArgString(Twine("-mcf-branch-label-scheme=") +
7018+
SA->getValue()));
70157019
}
70167020

70177021
if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ))

0 commit comments

Comments
 (0)