Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4a3c4da

Browse files
authoredJul 30, 2024
Unrolled build for rust-lang#128141
Rollup merge of rust-lang#128141 - nikic:aarch64-bti, r=DianQK,cuviper Set branch protection function attributes Since LLVM 19, it is necessary to set not only module flags, but also function attributes for branch protection on aarch64. See llvm/llvm-project@e15d67c for the relevant LLVM change. Fixes rust-lang#127829.
2 parents 710ce90 + ea7625f commit 4a3c4da

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed
 

‎compiler/rustc_codegen_llvm/src/attributes.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::*;
55
use rustc_hir::def_id::DefId;
66
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};
77
use rustc_middle::ty::{self, TyCtxt};
8-
use rustc_session::config::{FunctionReturn, OptLevel};
8+
use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet};
99
use rustc_span::symbol::sym;
1010
use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector};
1111
use smallvec::SmallVec;
@@ -405,8 +405,33 @@ pub fn from_fn_attrs<'ll, 'tcx>(
405405
// And it is a module-level attribute, so the alternative is pulling naked functions into new LLVM modules.
406406
// Otherwise LLVM's "naked" functions come with endbr prefixes per https://github.com/rust-lang/rust/issues/98768
407407
to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx));
408-
// Need this for AArch64.
409-
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false"));
408+
if llvm_util::get_version() < (19, 0, 0) {
409+
// Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to
410+
// the string "false". Now it is disabled by absence of the attribute.
411+
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false"));
412+
}
413+
} else if llvm_util::get_version() >= (19, 0, 0) {
414+
// For non-naked functions, set branch protection attributes on aarch64.
415+
if let Some(BranchProtection { bti, pac_ret }) =
416+
cx.sess().opts.unstable_opts.branch_protection
417+
{
418+
assert!(cx.sess().target.arch == "aarch64");
419+
if bti {
420+
to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));
421+
}
422+
if let Some(PacRet { leaf, key }) = pac_ret {
423+
to_add.push(llvm::CreateAttrStringValue(
424+
cx.llcx,
425+
"sign-return-address",
426+
if leaf { "all" } else { "non-leaf" },
427+
));
428+
to_add.push(llvm::CreateAttrStringValue(
429+
cx.llcx,
430+
"sign-return-address-key",
431+
if key == PAuthKey::A { "a_key" } else { "b_key" },
432+
));
433+
}
434+
}
410435
}
411436
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR)
412437
|| codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR_ZEROED)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Test that the correct module flags are emitted with different branch protection flags.
2+
3+
//@ revisions: BTI PACRET LEAF BKEY NONE
4+
//@ needs-llvm-components: aarch64
5+
//@ [BTI] compile-flags: -Z branch-protection=bti
6+
//@ [PACRET] compile-flags: -Z branch-protection=pac-ret
7+
//@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf
8+
//@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key
9+
//@ compile-flags: --target aarch64-unknown-linux-gnu
10+
//@ ignore-llvm-version: 19 - 99
11+
12+
#![crate_type = "lib"]
13+
#![feature(no_core, lang_items)]
14+
#![no_core]
15+
16+
#[lang = "sized"]
17+
trait Sized {}
18+
19+
// A basic test function.
20+
pub fn test() {}
21+
22+
// BTI: !"branch-target-enforcement", i32 1
23+
// BTI: !"sign-return-address", i32 0
24+
// BTI: !"sign-return-address-all", i32 0
25+
// BTI: !"sign-return-address-with-bkey", i32 0
26+
27+
// PACRET: !"branch-target-enforcement", i32 0
28+
// PACRET: !"sign-return-address", i32 1
29+
// PACRET: !"sign-return-address-all", i32 0
30+
// PACRET: !"sign-return-address-with-bkey", i32 0
31+
32+
// LEAF: !"branch-target-enforcement", i32 0
33+
// LEAF: !"sign-return-address", i32 1
34+
// LEAF: !"sign-return-address-all", i32 1
35+
// LEAF: !"sign-return-address-with-bkey", i32 0
36+
37+
// BKEY: !"branch-target-enforcement", i32 0
38+
// BKEY: !"sign-return-address", i32 1
39+
// BKEY: !"sign-return-address-all", i32 0
40+
// BKEY: !"sign-return-address-with-bkey", i32 1
41+
42+
// NONE-NOT: branch-target-enforcement
43+
// NONE-NOT: sign-return-address
44+
// NONE-NOT: sign-return-address-all
45+
// NONE-NOT: sign-return-address-with-bkey

‎tests/codegen/branch-protection.rs

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf
88
//@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key
99
//@ compile-flags: --target aarch64-unknown-linux-gnu
10+
//@ min-llvm-version: 19
1011

1112
#![crate_type = "lib"]
1213
#![feature(no_core, lang_items)]
@@ -16,23 +17,32 @@
1617
trait Sized {}
1718

1819
// A basic test function.
20+
// CHECK: @test(){{.*}} [[ATTR:#[0-9]+]] {
21+
#[no_mangle]
1922
pub fn test() {}
2023

24+
// BTI: attributes [[ATTR]] = {{.*}} "branch-target-enforcement"
2125
// BTI: !"branch-target-enforcement", i32 1
2226
// BTI: !"sign-return-address", i32 0
2327
// BTI: !"sign-return-address-all", i32 0
2428
// BTI: !"sign-return-address-with-bkey", i32 0
2529

30+
// PACRET: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf"
31+
// PACRET-SAME: "sign-return-address-key"="a_key"
2632
// PACRET: !"branch-target-enforcement", i32 0
2733
// PACRET: !"sign-return-address", i32 1
2834
// PACRET: !"sign-return-address-all", i32 0
2935
// PACRET: !"sign-return-address-with-bkey", i32 0
3036

37+
// LEAF: attributes [[ATTR]] = {{.*}} "sign-return-address"="all"
38+
// LEAF-SAME: "sign-return-address-key"="a_key"
3139
// LEAF: !"branch-target-enforcement", i32 0
3240
// LEAF: !"sign-return-address", i32 1
3341
// LEAF: !"sign-return-address-all", i32 1
3442
// LEAF: !"sign-return-address-with-bkey", i32 0
3543

44+
// BKEY: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf"
45+
// BKEY-SAME: "sign-return-address-key"="b_key"
3646
// BKEY: !"branch-target-enforcement", i32 0
3747
// BKEY: !"sign-return-address", i32 1
3848
// BKEY: !"sign-return-address-all", i32 0

0 commit comments

Comments
 (0)
Failed to load comments.