Skip to content

Commit 761e888

Browse files
committed
Auto merge of #93516 - nagisa:branch-protection, r=cjgillot
No branch protection metadata unless enabled Even if we emit metadata disabling branch protection, this metadata may conflict with other modules (e.g. during LTO) that have different branch protection metadata set. This is an unstable flag and feature, so ideally the flag not being specified should act as if the feature wasn't implemented in the first place. Additionally this PR also ensures we emit an error if `-Zbranch-protection` is set on targets other than the supported aarch64. For now the error is being output from codegen, but ideally it should be moved to earlier in the pipeline before stabilization.
2 parents 10cc7a6 + b995dc9 commit 761e888

File tree

8 files changed

+85
-58
lines changed

8 files changed

+85
-58
lines changed

compiler/rustc_codegen_llvm/src/context.rs

+30-30
Original file line numberDiff line numberDiff line change
@@ -269,36 +269,36 @@ pub unsafe fn create_module<'ll>(
269269
}
270270
}
271271

272-
if sess.target.arch == "aarch64" {
273-
let BranchProtection { bti, pac_ret: pac } = sess.opts.debugging_opts.branch_protection;
274-
275-
llvm::LLVMRustAddModuleFlag(
276-
llmod,
277-
llvm::LLVMModFlagBehavior::Error,
278-
"branch-target-enforcement\0".as_ptr().cast(),
279-
bti.into(),
280-
);
281-
282-
llvm::LLVMRustAddModuleFlag(
283-
llmod,
284-
llvm::LLVMModFlagBehavior::Error,
285-
"sign-return-address\0".as_ptr().cast(),
286-
pac.is_some().into(),
287-
);
288-
let pac_opts = pac.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
289-
llvm::LLVMRustAddModuleFlag(
290-
llmod,
291-
llvm::LLVMModFlagBehavior::Error,
292-
"sign-return-address-all\0".as_ptr().cast(),
293-
pac_opts.leaf.into(),
294-
);
295-
let is_bkey: bool = pac_opts.key != PAuthKey::A;
296-
llvm::LLVMRustAddModuleFlag(
297-
llmod,
298-
llvm::LLVMModFlagBehavior::Error,
299-
"sign-return-address-with-bkey\0".as_ptr().cast(),
300-
is_bkey.into(),
301-
);
272+
if let Some(BranchProtection { bti, pac_ret }) = sess.opts.debugging_opts.branch_protection {
273+
if sess.target.arch != "aarch64" {
274+
sess.err("-Zbranch-protection is only supported on aarch64");
275+
} else {
276+
llvm::LLVMRustAddModuleFlag(
277+
llmod,
278+
llvm::LLVMModFlagBehavior::Error,
279+
"branch-target-enforcement\0".as_ptr().cast(),
280+
bti.into(),
281+
);
282+
llvm::LLVMRustAddModuleFlag(
283+
llmod,
284+
llvm::LLVMModFlagBehavior::Error,
285+
"sign-return-address\0".as_ptr().cast(),
286+
pac_ret.is_some().into(),
287+
);
288+
let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
289+
llvm::LLVMRustAddModuleFlag(
290+
llmod,
291+
llvm::LLVMModFlagBehavior::Error,
292+
"sign-return-address-all\0".as_ptr().cast(),
293+
pac_opts.leaf.into(),
294+
);
295+
llvm::LLVMRustAddModuleFlag(
296+
llmod,
297+
llvm::LLVMModFlagBehavior::Error,
298+
"sign-return-address-with-bkey\0".as_ptr().cast(),
299+
u32::from(pac_opts.key == PAuthKey::B),
300+
);
301+
}
302302
}
303303

304304
// Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang).

compiler/rustc_interface/src/tests.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,10 @@ fn test_debugging_options_tracking_hash() {
721721
tracked!(binary_dep_depinfo, true);
722722
tracked!(
723723
branch_protection,
724-
BranchProtection { bti: true, pac_ret: Some(PacRet { leaf: true, key: PAuthKey::B }) }
724+
Some(BranchProtection {
725+
bti: true,
726+
pac_ret: Some(PacRet { leaf: true, key: PAuthKey::B })
727+
})
725728
);
726729
tracked!(chalk, true);
727730
tracked!(codegen_backend, Some("abc".to_string()));

compiler/rustc_session/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![feature(let_else)]
44
#![feature(min_specialization)]
55
#![feature(once_cell)]
6+
#![feature(option_get_or_insert_default)]
67
#![recursion_limit = "256"]
78
#![allow(rustc::potential_query_instability)]
89

compiler/rustc_session/src/options.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -978,9 +978,10 @@ mod parse {
978978
true
979979
}
980980

981-
crate fn parse_branch_protection(slot: &mut BranchProtection, v: Option<&str>) -> bool {
981+
crate fn parse_branch_protection(slot: &mut Option<BranchProtection>, v: Option<&str>) -> bool {
982982
match v {
983983
Some(s) => {
984+
let slot = slot.get_or_insert_default();
984985
for opt in s.split(',') {
985986
match opt {
986987
"bti" => slot.bti = true,
@@ -1155,7 +1156,7 @@ options! {
11551156
(default: no)"),
11561157
borrowck: String = ("migrate".to_string(), parse_string, [UNTRACKED],
11571158
"select which borrowck is used (`mir` or `migrate`) (default: `migrate`)"),
1158-
branch_protection: BranchProtection = (BranchProtection::default(), parse_branch_protection, [TRACKED],
1159+
branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED],
11591160
"set options for branch target identification and pointer authentication on AArch64"),
11601161
cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED],
11611162
"instrument control-flow architecture protection"),

src/test/codegen/branch-protection.rs

+29-24
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Test that the correct module flags are emitted with different branch protection flags.
22

3-
// revisions: bti pac-ret leaf b-key
3+
// revisions: BTI PACRET LEAF BKEY NONE
44
// min-llvm-version: 12.0.0
55
// needs-llvm-components: aarch64
6-
// [bti] compile-flags: -Z branch-protection=bti
7-
// [pac-ret] compile-flags: -Z branch-protection=pac-ret
8-
// [leaf] compile-flags: -Z branch-protection=pac-ret,leaf
9-
// [b-key] compile-flags: -Z branch-protection=pac-ret,b-key
6+
// [BTI] compile-flags: -Z branch-protection=bti
7+
// [PACRET] compile-flags: -Z branch-protection=pac-ret
8+
// [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf
9+
// [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key
1010
// compile-flags: --target aarch64-unknown-linux-gnu
1111

1212
#![crate_type = "lib"]
@@ -20,22 +20,27 @@ trait Sized { }
2020
pub fn test() {
2121
}
2222

23-
// bti: !"branch-target-enforcement", i32 1
24-
// bti: !"sign-return-address", i32 0
25-
// bti: !"sign-return-address-all", i32 0
26-
// bti: !"sign-return-address-with-bkey", i32 0
27-
28-
// pac-ret: !"branch-target-enforcement", i32 0
29-
// pac-ret: !"sign-return-address", i32 1
30-
// pac-ret: !"sign-return-address-all", i32 0
31-
// pac-ret: !"sign-return-address-with-bkey", i32 0
32-
33-
// leaf: !"branch-target-enforcement", i32 0
34-
// leaf: !"sign-return-address", i32 1
35-
// leaf: !"sign-return-address-all", i32 1
36-
// leaf: !"sign-return-address-with-bkey", i32 0
37-
38-
// b-key: !"branch-target-enforcement", i32 0
39-
// b-key: !"sign-return-address", i32 1
40-
// b-key: !"sign-return-address-all", i32 0
41-
// b-key: !"sign-return-address-with-bkey", i32 1
23+
// BTI: !"branch-target-enforcement", i32 1
24+
// BTI: !"sign-return-address", i32 0
25+
// BTI: !"sign-return-address-all", i32 0
26+
// BTI: !"sign-return-address-with-bkey", i32 0
27+
28+
// PACRET: !"branch-target-enforcement", i32 0
29+
// PACRET: !"sign-return-address", i32 1
30+
// PACRET: !"sign-return-address-all", i32 0
31+
// PACRET: !"sign-return-address-with-bkey", i32 0
32+
33+
// LEAF: !"branch-target-enforcement", i32 0
34+
// LEAF: !"sign-return-address", i32 1
35+
// LEAF: !"sign-return-address-all", i32 1
36+
// LEAF: !"sign-return-address-with-bkey", i32 0
37+
38+
// BKEY: !"branch-target-enforcement", i32 0
39+
// BKEY: !"sign-return-address", i32 1
40+
// BKEY: !"sign-return-address-all", i32 0
41+
// BKEY: !"sign-return-address-with-bkey", i32 1
42+
43+
// NONE-NOT: branch-target-enforcement
44+
// NONE-NOT: sign-return-address
45+
// NONE-NOT: sign-return-address-all
46+
// NONE-NOT: sign-return-address-with-bkey
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
error: -Zbranch-protection is only supported on aarch64
2+
3+
error: aborting due to previous error
4+
Original file line numberDiff line numberDiff line change
@@ -1 +1,14 @@
1-
// compile-flags: -Z branch-protection=leaf
1+
// revisions: BADFLAGS BADTARGET
2+
// [BADFLAGS] compile-flags: --target=aarch64-unknown-linux-gnu -Zbranch-protection=leaf
3+
// [BADFLAGS] check-fail
4+
// [BADFLAGS] needs-llvm-components: aarch64
5+
// [BADTARGET] compile-flags: --target=x86_64-unknown-linux-gnu -Zbranch-protection=bti
6+
// [BADTARGET] build-fail
7+
// [BADTARGET] needs-llvm-components: x86
8+
9+
#![crate_type = "lib"]
10+
#![feature(no_core, lang_items)]
11+
#![no_core]
12+
13+
#[lang="sized"]
14+
trait Sized { }

0 commit comments

Comments
 (0)