mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #146338 - CrooseGit:dev/reucru01/AArch64-enable-GCS, r=Urgau,davidtwco
Extends AArch64 branch protection support to include GCS Extends existing support for AArch64 branch protection to include support for [Guarded Control Stacks](https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/arm-a-profile-architecture-2022#guarded-control-stack-gcs:~:text=Extraction%20or%20tracking.-,Guarded%20Control%20Stack%20(GCS),-With%20the%202022).
This commit is contained in:
@@ -407,13 +407,16 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
|
||||
to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
|
||||
|
||||
// For non-naked functions, set branch protection attributes on aarch64.
|
||||
if let Some(BranchProtection { bti, pac_ret }) =
|
||||
if let Some(BranchProtection { bti, pac_ret, gcs }) =
|
||||
cx.sess().opts.unstable_opts.branch_protection
|
||||
{
|
||||
assert!(cx.sess().target.arch == "aarch64");
|
||||
if bti {
|
||||
to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));
|
||||
}
|
||||
if gcs {
|
||||
to_add.push(llvm::CreateAttrString(cx.llcx, "guarded-control-stack"));
|
||||
}
|
||||
if let Some(PacRet { leaf, pc, key }) = pac_ret {
|
||||
if pc {
|
||||
to_add.push(llvm::CreateAttrString(cx.llcx, "branch-protection-pauth-lr"));
|
||||
|
||||
@@ -370,7 +370,8 @@ pub(crate) unsafe fn create_module<'ll>(
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
|
||||
if let Some(BranchProtection { bti, pac_ret, gcs }) = sess.opts.unstable_opts.branch_protection
|
||||
{
|
||||
if sess.target.arch == "aarch64" {
|
||||
llvm::add_module_flag_u32(
|
||||
llmod,
|
||||
@@ -403,6 +404,12 @@ pub(crate) unsafe fn create_module<'ll>(
|
||||
"sign-return-address-with-bkey",
|
||||
u32::from(pac_opts.key == PAuthKey::B),
|
||||
);
|
||||
llvm::add_module_flag_u32(
|
||||
llmod,
|
||||
llvm::ModuleFlagMergeBehavior::Min,
|
||||
"guarded-control-stack",
|
||||
gcs.into(),
|
||||
);
|
||||
} else {
|
||||
bug!(
|
||||
"branch-protection used on non-AArch64 target; \
|
||||
|
||||
@@ -772,7 +772,8 @@ macro_rules! tracked {
|
||||
branch_protection,
|
||||
Some(BranchProtection {
|
||||
bti: true,
|
||||
pac_ret: Some(PacRet { leaf: true, pc: true, key: PAuthKey::B })
|
||||
pac_ret: Some(PacRet { leaf: true, pc: true, key: PAuthKey::B }),
|
||||
gcs: true,
|
||||
})
|
||||
);
|
||||
tracked!(codegen_backend, Some("abc".to_string()));
|
||||
|
||||
@@ -1621,6 +1621,7 @@ pub struct PacRet {
|
||||
pub struct BranchProtection {
|
||||
pub bti: bool,
|
||||
pub pac_ret: Option<PacRet>,
|
||||
pub gcs: bool,
|
||||
}
|
||||
|
||||
pub(crate) const fn default_lib_output() -> CrateType {
|
||||
|
||||
@@ -866,7 +866,7 @@ mod desc {
|
||||
pub(crate) const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
|
||||
pub(crate) const parse_stack_protector: &str =
|
||||
"one of (`none` (default), `basic`, `strong`, or `all`)";
|
||||
pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `pac-ret`, followed by a combination of `pc`, `b-key`, or `leaf`";
|
||||
pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)";
|
||||
pub(crate) const parse_proc_macro_execution_strategy: &str =
|
||||
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
|
||||
pub(crate) const parse_remap_path_scope: &str =
|
||||
@@ -1905,6 +1905,7 @@ pub(crate) fn parse_branch_protection(
|
||||
Some(pac) => pac.pc = true,
|
||||
_ => return false,
|
||||
},
|
||||
"gcs" => slot.gcs = true,
|
||||
_ => return false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:22.04
|
||||
FROM ubuntu:25.10
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:25.04
|
||||
FROM ubuntu:25.10
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:22.04
|
||||
FROM ubuntu:25.10
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
|
||||
@@ -13,6 +13,7 @@ It takes some combination of the following values, separated by a `,`.
|
||||
- `leaf` - Enable pointer authentication for all functions, including leaf functions.
|
||||
- `b-key` - Sign return addresses with key B, instead of the default key A.
|
||||
- `bti` - Enable branch target identification.
|
||||
- `gcs` - Enable guarded control stack support.
|
||||
|
||||
`leaf`, `b-key` and `pc` are only valid if `pac-ret` was previously specified.
|
||||
For example, `-Z branch-protection=bti,pac-ret,leaf` is valid, but
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
// Test that PAC instructions are emitted when branch-protection is specified.
|
||||
|
||||
//@ add-core-stubs
|
||||
//@ revisions: PACRET PAUTHLR_NOP PAUTHLR
|
||||
//@ revisions: GCS PACRET PAUTHLR_NOP PAUTHLR
|
||||
//@ assembly-output: emit-asm
|
||||
//@ needs-llvm-components: aarch64
|
||||
//@ compile-flags: --target aarch64-unknown-linux-gnu
|
||||
//@ [GCS] min-llvm-version: 21
|
||||
//@ [GCS] ignore-apple (XCode version needs updating)
|
||||
//@ [GCS] compile-flags: -Z branch-protection=gcs
|
||||
//@ [PACRET] compile-flags: -Z branch-protection=pac-ret,leaf
|
||||
//@ [PAUTHLR_NOP] compile-flags: -Z branch-protection=pac-ret,pc,leaf
|
||||
//@ [PAUTHLR] compile-flags: -C target-feature=+pauth-lr -Z branch-protection=pac-ret,pc,leaf
|
||||
@@ -17,6 +20,7 @@
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
// GCS: .aeabi_attribute 2, 1 // Tag_Feature_GCS
|
||||
// PACRET: hint #25
|
||||
// PACRET: hint #29
|
||||
// PAUTHLR_NOP: hint #25
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// Test that the correct module flags are emitted with different branch protection flags.
|
||||
|
||||
//@ add-core-stubs
|
||||
//@ revisions: BTI PACRET LEAF BKEY PAUTHLR PAUTHLR_BKEY PAUTHLR_LEAF PAUTHLR_BTI NONE
|
||||
//@ revisions: BTI GCS PACRET LEAF BKEY PAUTHLR PAUTHLR_BKEY PAUTHLR_LEAF PAUTHLR_BTI NONE
|
||||
//@ needs-llvm-components: aarch64
|
||||
//@ [BTI] compile-flags: -Z branch-protection=bti
|
||||
//@ [GCS] compile-flags: -Z branch-protection=gcs
|
||||
//@ [PACRET] compile-flags: -Z branch-protection=pac-ret
|
||||
//@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf
|
||||
//@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key
|
||||
@@ -32,6 +33,9 @@ pub fn test() {}
|
||||
// BTI: !"sign-return-address-all", i32 0
|
||||
// BTI: !"sign-return-address-with-bkey", i32 0
|
||||
|
||||
// GCS: attributes [[ATTR]] = {{.*}} "guarded-control-stack"
|
||||
// GCS: !"guarded-control-stack", i32 1
|
||||
|
||||
// PACRET: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf"
|
||||
// PACRET-SAME: "sign-return-address-key"="a_key"
|
||||
// PACRET: !"branch-target-enforcement", i32 0
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
// `-Z branch protection` is an unstable compiler feature which adds pointer-authentication
|
||||
// code (PAC), a useful hashing measure for verifying that pointers have not been modified.
|
||||
// This test checks that compilation and execution is successful when this feature is activated,
|
||||
// with some of its possible extra arguments (bti, pac-ret, leaf) when doing LTO.
|
||||
// with some of its possible extra arguments (bti, gcs, pac-ret, leaf) when doing LTO.
|
||||
// See https://github.com/rust-lang/rust/pull/88354
|
||||
|
||||
//@ needs-force-clang-based-tests
|
||||
//@ only-aarch64
|
||||
// Reason: branch protection is not supported on other architectures
|
||||
//@ ignore-apple
|
||||
// Reason: XCode needs updating to support gcs
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed
|
||||
|
||||
@@ -19,7 +21,7 @@ fn main() {
|
||||
clang()
|
||||
.arg("-v")
|
||||
.lto("thin")
|
||||
.arg("-mbranch-protection=bti+pac-ret+b-key+leaf")
|
||||
.arg("-mbranch-protection=bti+gcs+pac-ret+b-key+leaf")
|
||||
.arg("-c")
|
||||
.out_exe("test.o")
|
||||
.input("test.c")
|
||||
@@ -30,7 +32,7 @@ fn main() {
|
||||
.opt_level("2")
|
||||
.linker(&env_var("CLANG"))
|
||||
.link_arg("-fuse-ld=lld")
|
||||
.arg("-Zbranch-protection=bti,pac-ret,leaf")
|
||||
.arg("-Zbranch-protection=bti,gcs,pac-ret,leaf")
|
||||
.input("test.rs")
|
||||
.output("test.bin")
|
||||
.run();
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// `-Z branch protection` is an unstable compiler feature which adds pointer-authentication
|
||||
// code (PAC), a useful hashing measure for verifying that pointers have not been modified.
|
||||
// This test checks that compilation and execution is successful when this feature is activated,
|
||||
// with some of its possible extra arguments (bti, pac-ret, pc, leaf, b-key).
|
||||
// with some of its possible extra arguments (bti, gcs, pac-ret, pc, leaf, b-key).
|
||||
// See https://github.com/rust-lang/rust/pull/88354
|
||||
|
||||
//@ only-aarch64
|
||||
// Reason: branch protection is not supported on other architectures
|
||||
//@ ignore-apple
|
||||
// Reason: XCode needs updating to support gcs
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed
|
||||
|
||||
@@ -13,17 +15,17 @@
|
||||
|
||||
fn main() {
|
||||
build_native_static_lib("test");
|
||||
rustc().arg("-Zbranch-protection=bti,pac-ret,leaf").input("test.rs").run();
|
||||
rustc().arg("-Zbranch-protection=bti,gcs,pac-ret,leaf").input("test.rs").run();
|
||||
run("test");
|
||||
cc().arg("-v")
|
||||
.arg("-c")
|
||||
.out_exe("test")
|
||||
.input("test.c")
|
||||
.arg("-mbranch-protection=bti+pac-ret+leaf")
|
||||
.arg("-mbranch-protection=bti+gcs+pac-ret+leaf")
|
||||
.run();
|
||||
let obj_file = if is_windows_msvc() { "test.obj" } else { "test" };
|
||||
llvm_ar().obj_to_ar().output_input("libtest.a", &obj_file).run();
|
||||
rustc().arg("-Zbranch-protection=bti,pac-ret,leaf").input("test.rs").run();
|
||||
rustc().arg("-Zbranch-protection=bti,gcs,pac-ret,leaf").input("test.rs").run();
|
||||
run("test");
|
||||
|
||||
// FIXME: +pc was only recently added to LLVM
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
error: incorrect value `leaf` for unstable option `branch-protection` - a `,` separated combination of `bti`, `pac-ret`, followed by a combination of `pc`, `b-key`, or `leaf` was expected
|
||||
error: incorrect value `leaf` for unstable option `branch-protection` - a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set) was expected
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
error: incorrect value `pc` for unstable option `branch-protection` - a `,` separated combination of `bti`, `pac-ret`, followed by a combination of `pc`, `b-key`, or `leaf` was expected
|
||||
error: incorrect value `pc` for unstable option `branch-protection` - a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set) was expected
|
||||
|
||||
|
||||
Reference in New Issue
Block a user