Skip to content

Commit 9e9fa00

Browse files
[Arm][AArch64][Clang] Respect function's branch protection attributes. (#101978)
Default attributes assigned to all functions according to the command line parameters. Some functions might have their own attributes and we need to set or remove attributes accordingly. Tests are updated to test this scenarios too.
1 parent 7a98071 commit 9e9fa00

File tree

5 files changed

+52
-8
lines changed

5 files changed

+52
-8
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2010,7 +2010,7 @@ static void getTrivialDefaultFunctionAttributes(
20102010
}
20112011

20122012
TargetInfo::BranchProtectionInfo BPI(LangOpts);
2013-
TargetCodeGenInfo::setBranchProtectionFnAttributes(BPI, FuncAttrs);
2013+
TargetCodeGenInfo::initBranchProtectionFnAttributes(BPI, FuncAttrs);
20142014
}
20152015

20162016
/// Merges `target-features` from \TargetOpts and \F, and sets the result in

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,37 @@ llvm::Value *TargetCodeGenInfo::createEnqueuedBlockKernel(
209209

210210
void TargetCodeGenInfo::setBranchProtectionFnAttributes(
211211
const TargetInfo::BranchProtectionInfo &BPI, llvm::Function &F) {
212-
llvm::AttrBuilder FuncAttrs(F.getContext());
213-
setBranchProtectionFnAttributes(BPI, FuncAttrs);
214-
F.addFnAttrs(FuncAttrs);
212+
// Called on already created and initialized function where attributes already
213+
// set from command line attributes but some might need to be removed as the
214+
// actual BPI is different.
215+
if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
216+
F.addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
217+
F.addFnAttr("sign-return-address-key", BPI.getSignKeyStr());
218+
} else {
219+
if (F.hasFnAttribute("sign-return-address"))
220+
F.removeFnAttr("sign-return-address");
221+
if (F.hasFnAttribute("sign-return-address-key"))
222+
F.removeFnAttr("sign-return-address-key");
223+
}
224+
225+
auto AddRemoveAttributeAsSet = [&](bool Set, const StringRef &ModAttr) {
226+
if (Set)
227+
F.addFnAttr(ModAttr);
228+
else if (F.hasFnAttribute(ModAttr))
229+
F.removeFnAttr(ModAttr);
230+
};
231+
232+
AddRemoveAttributeAsSet(BPI.BranchTargetEnforcement,
233+
"branch-target-enforcement");
234+
AddRemoveAttributeAsSet(BPI.BranchProtectionPAuthLR,
235+
"branch-protection-pauth-lr");
236+
AddRemoveAttributeAsSet(BPI.GuardedControlStack, "guarded-control-stack");
215237
}
216238

217-
void TargetCodeGenInfo::setBranchProtectionFnAttributes(
239+
void TargetCodeGenInfo::initBranchProtectionFnAttributes(
218240
const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs) {
241+
// Only used for initializing attributes in the AttrBuilder, which will not
242+
// contain any of these attributes so no need to remove anything.
219243
if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
220244
FuncAttrs.addAttribute("sign-return-address", BPI.getSignReturnAddrStr());
221245
FuncAttrs.addAttribute("sign-return-address-key", BPI.getSignKeyStr());

clang/lib/CodeGen/TargetInfo.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,13 +423,16 @@ class TargetCodeGenInfo {
423423
return nullptr;
424424
}
425425

426+
// Set the Branch Protection Attributes of the Function accordingly to the
427+
// BPI. Remove attributes that contradict with current BPI.
426428
static void
427429
setBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI,
428430
llvm::Function &F);
429431

432+
// Add the Branch Protection Attributes of the FuncAttrs.
430433
static void
431-
setBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI,
432-
llvm::AttrBuilder &FuncAttrs);
434+
initBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI,
435+
llvm::AttrBuilder &FuncAttrs);
433436

434437
protected:
435438
static std::string qualifyWindowsLibrary(StringRef Lib);

clang/test/CodeGen/aarch64-branch-protection-attr.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
// REQUIRES: aarch64-registered-target
22
// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a %s -o - \
33
// RUN: | FileCheck %s --check-prefix=CHECK
4+
// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -mbranch-target-enforce %s -o - \
5+
// RUN: | FileCheck %s --check-prefix=CHECK
6+
// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -mguarded-control-stack %s -o - \
7+
// RUN: | FileCheck %s --check-prefix=CHECK
8+
// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -msign-return-address=non-leaf -msign-return-address-key=a_key %s -o - \
9+
// RUN: | FileCheck %s --check-prefix=CHECK
10+
// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -msign-return-address=all -msign-return-address-key=b_key %s -o - \
11+
// RUN: | FileCheck %s --check-prefix=CHECK
12+
// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -mbranch-protection-pauth-lr -msign-return-address=all -msign-return-address-key=a_key %s -o - \
13+
// RUN: | FileCheck %s --check-prefix=CHECK
14+
// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -mguarded-control-stack -mbranch-target-enforce -mbranch-protection-pauth-lr -msign-return-address=all -msign-return-address-key=a_key %s -o - \
15+
// RUN: | FileCheck %s --check-prefix=CHECK
416

517
__attribute__ ((target("branch-protection=none")))
618
void none() {}
@@ -83,7 +95,6 @@ void gcs() {}
8395

8496
// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}} "branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"
8597

86-
8798
// CHECK-DAG: attributes #[[#PAUTHLR]] = { {{.*}} "branch-protection-pauth-lr" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
8899

89100
// CHECK-DAG: attributes #[[#PAUTHLR_BKEY]] = { {{.*}} "branch-protection-pauth-lr" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="b_key"

clang/test/CodeGen/arm-branch-protection-attr-1.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
// REQUIRES: arm-registered-target
22
// RUN: %clang_cc1 -triple thumbv7m-unknown-unknown-eabi -emit-llvm %s -o - \
33
// RUN: | FileCheck %s --check-prefix=CHECK
4+
// RUN: %clang_cc1 -triple thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -emit-llvm %s -o - \
5+
// RUN: | FileCheck %s --check-prefix=CHECK
6+
// RUN: %clang_cc1 -triple thumbv7m-unknown-unknown-eabi -msign-return-address=all -emit-llvm %s -o - \
7+
// RUN: | FileCheck %s --check-prefix=CHECK
8+
// RUN: %clang_cc1 -triple thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -msign-return-address=all -emit-llvm %s -o - \
9+
// RUN: | FileCheck %s --check-prefix=CHECK
410

511
__attribute__((target("branch-protection=none"))) void none() {}
612
// CHECK: define{{.*}} void @none() #[[#NONE:]]

0 commit comments

Comments
 (0)