From ea7625f4266e69498ea5b9287a72e543a514a837 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 24 Jul 2024 16:47:56 +0200 Subject: [PATCH 1/5] 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 https://github.com/llvm/llvm-project/commit/e15d67cfc2e5775cc79281aa860f3ad3be628f39 for the relevant LLVM change. --- compiler/rustc_codegen_llvm/src/attributes.rs | 31 +++++++++++-- tests/codegen/branch-protection-old-llvm.rs | 45 +++++++++++++++++++ tests/codegen/branch-protection.rs | 10 +++++ 3 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 tests/codegen/branch-protection-old-llvm.rs diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 3877460fcdb0d..ff01a2088812d 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -4,7 +4,7 @@ use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::config::{FunctionReturn, OptLevel}; +use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet}; use rustc_span::symbol::sym; use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector}; use smallvec::SmallVec; @@ -407,8 +407,33 @@ pub fn from_fn_attrs<'ll, 'tcx>( // And it is a module-level attribute, so the alternative is pulling naked functions into new LLVM modules. // Otherwise LLVM's "naked" functions come with endbr prefixes per https://github.com/rust-lang/rust/issues/98768 to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx)); - // Need this for AArch64. - to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false")); + if llvm_util::get_version() < (19, 0, 0) { + // Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to + // the string "false". Now it is disabled by absence of the attribute. + to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false")); + } + } else if llvm_util::get_version() >= (19, 0, 0) { + // For non-naked functions, set branch protection attributes on aarch64. + if let Some(BranchProtection { bti, pac_ret }) = + 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 let Some(PacRet { leaf, key }) = pac_ret { + to_add.push(llvm::CreateAttrStringValue( + cx.llcx, + "sign-return-address", + if leaf { "all" } else { "non-leaf" }, + )); + to_add.push(llvm::CreateAttrStringValue( + cx.llcx, + "sign-return-address-key", + if key == PAuthKey::A { "a_key" } else { "b_key" }, + )); + } + } } if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR_ZEROED) diff --git a/tests/codegen/branch-protection-old-llvm.rs b/tests/codegen/branch-protection-old-llvm.rs new file mode 100644 index 0000000000000..bb3c7a4b70c3c --- /dev/null +++ b/tests/codegen/branch-protection-old-llvm.rs @@ -0,0 +1,45 @@ +// Test that the correct module flags are emitted with different branch protection flags. + +//@ revisions: BTI PACRET LEAF BKEY NONE +//@ needs-llvm-components: aarch64 +//@ [BTI] compile-flags: -Z branch-protection=bti +//@ [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 +//@ compile-flags: --target aarch64-unknown-linux-gnu +//@ ignore-llvm-version: 19 - 99 + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +// A basic test function. +pub fn test() {} + +// BTI: !"branch-target-enforcement", i32 1 +// BTI: !"sign-return-address", i32 0 +// BTI: !"sign-return-address-all", i32 0 +// BTI: !"sign-return-address-with-bkey", i32 0 + +// PACRET: !"branch-target-enforcement", i32 0 +// PACRET: !"sign-return-address", i32 1 +// PACRET: !"sign-return-address-all", i32 0 +// PACRET: !"sign-return-address-with-bkey", i32 0 + +// LEAF: !"branch-target-enforcement", i32 0 +// LEAF: !"sign-return-address", i32 1 +// LEAF: !"sign-return-address-all", i32 1 +// LEAF: !"sign-return-address-with-bkey", i32 0 + +// BKEY: !"branch-target-enforcement", i32 0 +// BKEY: !"sign-return-address", i32 1 +// BKEY: !"sign-return-address-all", i32 0 +// BKEY: !"sign-return-address-with-bkey", i32 1 + +// NONE-NOT: branch-target-enforcement +// NONE-NOT: sign-return-address +// NONE-NOT: sign-return-address-all +// NONE-NOT: sign-return-address-with-bkey diff --git a/tests/codegen/branch-protection.rs b/tests/codegen/branch-protection.rs index a29ec67d578b8..2f5ff9e98c22d 100644 --- a/tests/codegen/branch-protection.rs +++ b/tests/codegen/branch-protection.rs @@ -7,6 +7,7 @@ //@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf //@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key //@ compile-flags: --target aarch64-unknown-linux-gnu +//@ min-llvm-version: 19 #![crate_type = "lib"] #![feature(no_core, lang_items)] @@ -16,23 +17,32 @@ trait Sized {} // A basic test function. +// CHECK: @test(){{.*}} [[ATTR:#[0-9]+]] { +#[no_mangle] pub fn test() {} +// BTI: attributes [[ATTR]] = {{.*}} "branch-target-enforcement" // BTI: !"branch-target-enforcement", i32 1 // BTI: !"sign-return-address", i32 0 // BTI: !"sign-return-address-all", i32 0 // BTI: !"sign-return-address-with-bkey", i32 0 +// PACRET: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf" +// PACRET-SAME: "sign-return-address-key"="a_key" // PACRET: !"branch-target-enforcement", i32 0 // PACRET: !"sign-return-address", i32 1 // PACRET: !"sign-return-address-all", i32 0 // PACRET: !"sign-return-address-with-bkey", i32 0 +// LEAF: attributes [[ATTR]] = {{.*}} "sign-return-address"="all" +// LEAF-SAME: "sign-return-address-key"="a_key" // LEAF: !"branch-target-enforcement", i32 0 // LEAF: !"sign-return-address", i32 1 // LEAF: !"sign-return-address-all", i32 1 // LEAF: !"sign-return-address-with-bkey", i32 0 +// BKEY: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf" +// BKEY-SAME: "sign-return-address-key"="b_key" // BKEY: !"branch-target-enforcement", i32 0 // BKEY: !"sign-return-address", i32 1 // BKEY: !"sign-return-address-all", i32 0 From 39f9c479d9635e7181dc3b05939e56951e059add Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 9 Jul 2024 09:34:59 +0200 Subject: [PATCH 2/5] Update to LLVM 19 --- .gitmodules | 4 ++-- src/llvm-project | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 9ad207a0d5226..dea2f144bede6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -32,8 +32,8 @@ shallow = true [submodule "src/llvm-project"] path = src/llvm-project - url = https://github.com/rust-lang/llvm-project.git - branch = rustc/18.1-2024-05-19 + url = https://github.com/nikic/llvm-project.git + branch = rust-llvm-19 shallow = true [submodule "src/doc/embedded-book"] path = src/doc/embedded-book diff --git a/src/llvm-project b/src/llvm-project index c54cff0e6e4d1..80205eca33a34 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit c54cff0e6e4d1a0d0a2df7c1ce3d96cdd554763e +Subproject commit 80205eca33a344f52d5a8a78bcb9580a55a10c3a From 2508d8eccc69fbc356d0fe38ff8fbe63219048d5 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Mon, 17 Jun 2024 09:35:38 +0000 Subject: [PATCH 3/5] llvm-wrapper: adapt for LLVM 19 API change No functional changes intended. The instrprof_mcdc_condbitmap_update intrinsic was dropped in LLVM 19: * https://github.com/llvm/llvm-project/commit/85a7bba7d28365ff98dae74f20ebf9f53d42023a --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 14757b27a3758..f28372053ea3e 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1557,11 +1557,12 @@ LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(LLVMModuleRef M) { extern "C" LLVMValueRef LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(LLVMModuleRef M) { -#if LLVM_VERSION_GE(18, 0) +#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0) return wrap(llvm::Intrinsic::getDeclaration( unwrap(M), llvm::Intrinsic::instrprof_mcdc_condbitmap_update)); #else - report_fatal_error("LLVM 18.0 is required for mcdc intrinsic functions"); + report_fatal_error( + "The instrprof_mcdc_condbitmap_update only exists in LLVM 18"); #endif } From 69fb4f88f8eb53af9a92a58b288a12f774ef11aa Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 9 Jul 2024 10:56:46 +0200 Subject: [PATCH 4/5] Disable mcdc tests --- tests/coverage/mcdc/condition-limit.rs | 1 + tests/coverage/mcdc/if.rs | 1 + tests/coverage/mcdc/inlined_expressions.rs | 1 + tests/coverage/mcdc/nested_if.rs | 1 + tests/coverage/mcdc/non_control_flow.rs | 1 + 5 files changed, 5 insertions(+) diff --git a/tests/coverage/mcdc/condition-limit.rs b/tests/coverage/mcdc/condition-limit.rs index 571c600ebd096..2ff46b11a1681 100644 --- a/tests/coverage/mcdc/condition-limit.rs +++ b/tests/coverage/mcdc/condition-limit.rs @@ -1,6 +1,7 @@ #![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 18 +//@ ignore-llvm-version: 19 - 99 //@ compile-flags: -Zcoverage-options=mcdc //@ llvm-cov-flags: --show-branches=count --show-mcdc diff --git a/tests/coverage/mcdc/if.rs b/tests/coverage/mcdc/if.rs index d8e6b61a9d59d..6f589659a3d7b 100644 --- a/tests/coverage/mcdc/if.rs +++ b/tests/coverage/mcdc/if.rs @@ -1,6 +1,7 @@ #![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 18 +//@ ignore-llvm-version: 19 - 99 //@ compile-flags: -Zcoverage-options=mcdc //@ llvm-cov-flags: --show-branches=count --show-mcdc diff --git a/tests/coverage/mcdc/inlined_expressions.rs b/tests/coverage/mcdc/inlined_expressions.rs index 65f7ee66f3994..fc1e4dae37c7b 100644 --- a/tests/coverage/mcdc/inlined_expressions.rs +++ b/tests/coverage/mcdc/inlined_expressions.rs @@ -1,6 +1,7 @@ #![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 18 +//@ ignore-llvm-version: 19 - 99 //@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0 //@ llvm-cov-flags: --show-branches=count --show-mcdc diff --git a/tests/coverage/mcdc/nested_if.rs b/tests/coverage/mcdc/nested_if.rs index f5068b5dcc23f..f9ce7a0bc254f 100644 --- a/tests/coverage/mcdc/nested_if.rs +++ b/tests/coverage/mcdc/nested_if.rs @@ -1,6 +1,7 @@ #![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 18 +//@ ignore-llvm-version: 19 - 99 //@ compile-flags: -Zcoverage-options=mcdc //@ llvm-cov-flags: --show-branches=count --show-mcdc diff --git a/tests/coverage/mcdc/non_control_flow.rs b/tests/coverage/mcdc/non_control_flow.rs index 77e64e6625b2c..633d381a1aafc 100644 --- a/tests/coverage/mcdc/non_control_flow.rs +++ b/tests/coverage/mcdc/non_control_flow.rs @@ -1,6 +1,7 @@ #![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 18 +//@ ignore-llvm-version: 19 - 99 //@ compile-flags: -Zcoverage-options=mcdc //@ llvm-cov-flags: --show-branches=count --show-mcdc From fe8592d61e78fffa21082a8cc54dcbee0351668b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 24 Jul 2024 16:03:36 +0200 Subject: [PATCH 5/5] Crash test for issue 121444 has been fixed --- tests/{crashes/121444.rs => ui/abi/large-byval-align.rs} | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename tests/{crashes/121444.rs => ui/abi/large-byval-align.rs} (68%) diff --git a/tests/crashes/121444.rs b/tests/ui/abi/large-byval-align.rs similarity index 68% rename from tests/crashes/121444.rs rename to tests/ui/abi/large-byval-align.rs index a6373a58c426e..e39170df72b49 100644 --- a/tests/crashes/121444.rs +++ b/tests/ui/abi/large-byval-align.rs @@ -1,11 +1,13 @@ -//@ known-bug: #121444 //@ compile-flags: -Copt-level=0 -//@ edition:2021 //@ only-x86_64 //@ ignore-windows +//@ min-llvm-version: 19 +//@ build-pass + #[repr(align(536870912))] pub struct A(i64); +#[allow(improper_ctypes_definitions)] pub extern "C" fn foo(x: A) {} fn main() {