Skip to content

Commit b995dc9

Browse files
committed
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.
1 parent cb4ee81 commit b995dc9

File tree

8 files changed

+85
-58
lines changed

8 files changed

+85
-58
lines changed

Diff for: 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).

Diff for: 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()));

Diff for: compiler/rustc_session/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![feature(derive_default_enum)]
33
#![feature(min_specialization)]
44
#![feature(once_cell)]
5+
#![feature(option_get_or_insert_default)]
56
#![recursion_limit = "256"]
67
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]
78

Diff for: compiler/rustc_session/src/options.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -984,9 +984,10 @@ mod parse {
984984
true
985985
}
986986

987-
crate fn parse_branch_protection(slot: &mut BranchProtection, v: Option<&str>) -> bool {
987+
crate fn parse_branch_protection(slot: &mut Option<BranchProtection>, v: Option<&str>) -> bool {
988988
match v {
989989
Some(s) => {
990+
let slot = slot.get_or_insert_default();
990991
for opt in s.split(',') {
991992
match opt {
992993
"bti" => slot.bti = true,
@@ -1161,7 +1162,7 @@ options! {
11611162
(default: no)"),
11621163
borrowck: String = ("migrate".to_string(), parse_string, [UNTRACKED],
11631164
"select which borrowck is used (`mir` or `migrate`) (default: `migrate`)"),
1164-
branch_protection: BranchProtection = (BranchProtection::default(), parse_branch_protection, [TRACKED],
1165+
branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED],
11651166
"set options for branch target identification and pointer authentication on AArch64"),
11661167
cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED],
11671168
"instrument control-flow architecture protection"),

Diff for: 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)