From d255d70e7a6a84c82cc74f968f529f42dd40b8ce Mon Sep 17 00:00:00 2001 From: Hugues de Valon Date: Tue, 29 Sep 2020 12:20:56 +0100 Subject: [PATCH 1/3] Update LLVM and add Unsupported diagnostic Secure entry functions do not support if arguments are passed on the stack. An "unsupported" diagnostic will be emitted by LLVM if that is the case. This commits adds support in Rust for that diagnostic so that an error will be output if that is the case! Signed-off-by: Hugues de Valon --- compiler/rustc_codegen_llvm/src/back/write.rs | 7 +++++++ compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs | 2 ++ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 3 +++ 4 files changed, 13 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 937821e9d4fb2..f35c1016f86be 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -344,6 +344,13 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void .expect("non-UTF8 diagnostic"); diag_handler.warn(&msg); } + llvm::diagnostic::Unsupported(diagnostic_ref) => { + let msg = llvm::build_string(|s| { + llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s) + }) + .expect("non-UTF8 diagnostic"); + diag_handler.err(&msg); + } llvm::diagnostic::UnknownDiagnostic(..) => {} } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs index 47f5c94e70c53..ccd3e42e458fd 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs @@ -118,6 +118,7 @@ pub enum Diagnostic<'ll> { InlineAsm(InlineAsmDiagnostic<'ll>), PGO(&'ll DiagnosticInfo), Linker(&'ll DiagnosticInfo), + Unsupported(&'ll DiagnosticInfo), /// LLVM has other types that we do not wrap here. UnknownDiagnostic(&'ll DiagnosticInfo), @@ -159,6 +160,7 @@ impl Diagnostic<'ll> { Dk::PGOProfile => PGO(di), Dk::Linker => Linker(di), + Dk::Unsupported => Unsupported(di), _ => UnknownDiagnostic(di), } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 45c5f56f44793..af3f3e7aa03c0 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -483,6 +483,7 @@ pub enum DiagnosticKind { OptimizationFailure, PGOProfile, Linker, + Unsupported, } /// LLVMRustDiagnosticLevel diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index e85a9b7638004..9f8ea7f43d84b 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1171,6 +1171,7 @@ enum class LLVMRustDiagnosticKind { OptimizationFailure, PGOProfile, Linker, + Unsupported, }; static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) { @@ -1197,6 +1198,8 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) { return LLVMRustDiagnosticKind::PGOProfile; case DK_Linker: return LLVMRustDiagnosticKind::Linker; + case DK_Unsupported: + return LLVMRustDiagnosticKind::Unsupported; default: return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark) ? LLVMRustDiagnosticKind::OptimizationRemarkOther From 1aaafac6ffec2556a27a3c34365c685c124ee029 Mon Sep 17 00:00:00 2001 From: Hugues de Valon Date: Mon, 28 Sep 2020 21:10:38 +0100 Subject: [PATCH 2/3] Add support for cmse_nonsecure_entry attribute This patch adds support for the LLVM cmse_nonsecure_entry attribute. This is a target-dependent attribute that only has sense for the thumbv8m Rust targets. You can find more information about this attribute here: https://developer.arm.com/documentation/ecm0359818/latest/ Signed-off-by: Hugues de Valon --- compiler/rustc_codegen_llvm/src/attributes.rs | 3 + compiler/rustc_codegen_llvm/src/llvm/mod.rs | 6 ++ compiler/rustc_error_codes/src/error_codes.rs | 1 + .../src/error_codes/E0775.md | 17 +++++ compiler/rustc_feature/src/active.rs | 3 + compiler/rustc_feature/src/builtin_attrs.rs | 2 + .../src/middle/codegen_fn_attrs.rs | 3 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_typeck/src/collect.rs | 6 ++ .../language-features/cmse-nonsecure-entry.md | 75 +++++++++++++++++++ src/llvm-project | 2 +- .../cmse-nonsecure-entry/params-on-stack.rs | 11 +++ .../params-on-stack.stderr | 5 ++ .../ui/cmse-nonsecure-entry/trustzone-only.rs | 11 +++ .../trustzone-only.stderr | 9 +++ 15 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0775.md create mode 100644 src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md create mode 100644 src/test/ui/cmse-nonsecure-entry/params-on-stack.rs create mode 100644 src/test/ui/cmse-nonsecure-entry/params-on-stack.stderr create mode 100644 src/test/ui/cmse-nonsecure-entry/trustzone-only.rs create mode 100644 src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 227a87ff81994..73c34818446a6 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -294,6 +294,9 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) { Attribute::NoAlias.apply_llfn(llvm::AttributePlace::ReturnValue, llfn); } + if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) { + llvm::AddFunctionAttrString(llfn, Function, const_cstr!("cmse_nonsecure_entry")); + } sanitize(cx, codegen_fn_attrs.no_sanitize, llfn); // Always annotate functions with the target-cpu they are compiled for. diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index c09e3659f80a2..ed9b99188bb90 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -37,6 +37,12 @@ pub fn AddFunctionAttrStringValue(llfn: &'a Value, idx: AttributePlace, attr: &C } } +pub fn AddFunctionAttrString(llfn: &'a Value, idx: AttributePlace, attr: &CStr) { + unsafe { + LLVMRustAddFunctionAttrStringValue(llfn, idx.as_uint(), attr.as_ptr(), std::ptr::null()) + } +} + #[derive(Copy, Clone)] pub enum AttributePlace { ReturnValue, diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index a202736ea6cbe..c97532967323e 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -458,6 +458,7 @@ E0770: include_str!("./error_codes/E0770.md"), E0771: include_str!("./error_codes/E0771.md"), E0773: include_str!("./error_codes/E0773.md"), E0774: include_str!("./error_codes/E0774.md"), +E0775: include_str!("./error_codes/E0775.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/compiler/rustc_error_codes/src/error_codes/E0775.md b/compiler/rustc_error_codes/src/error_codes/E0775.md new file mode 100644 index 0000000000000..f21ee73791cab --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0775.md @@ -0,0 +1,17 @@ +`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M +extension. + +Erroneous code example: + +```compile_fail,E0775 +#![feature(cmse_nonsecure_entry)] + +#[cmse_nonsecure_entry] +fn toto() {} +``` + +To fix this error, compile your code for a Rust target that supports the +TrustZone-M extension. The current possible targets are: +* `thumbv8m.main-none-eabi` +* `thumbv8m.main-none-eabihf` +* `thumbv8m.base-none-eabi` diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 7f5b19134804e..348cff8d2dad2 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -590,6 +590,9 @@ declare_features! ( /// Allows using and casting function pointers in a `const fn`. (active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None), + /// Allows to use the `#[cmse_nonsecure_entry]` attribute. + (active, cmse_nonsecure_entry, "1.48.0", Some(75835), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 22c1ca2f289d3..b7e113e601007 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -349,6 +349,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ experimental!(register_tool), ), + gated!(cmse_nonsecure_entry, AssumedUsed, template!(Word), experimental!(cmse_nonsecure_entry)), + // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 62a6198b9b402..d71cdc4e67de4 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -79,6 +79,9 @@ bitflags! { /// #[ffi_const]: applies clang's `const` attribute to a foreign function /// declaration. const FFI_CONST = 1 << 13; + /// #[cmse_nonsecure_entry]: with a TrustZone-M extension, declare a + /// function as an entry function from Non-Secure code. + const CMSE_NONSECURE_ENTRY = 1 << 14; } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4234aef335906..e3ad31469b237 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -337,6 +337,7 @@ symbols! { closure_to_fn_coercion, cmp, cmpxchg16b_target_feature, + cmse_nonsecure_entry, coerce_unsized, cold, column, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index d6985f3bd4d63..6c0d51ed71771 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2543,6 +2543,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; } else if tcx.sess.check_name(attr, sym::used) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; + } else if tcx.sess.check_name(attr, sym::cmse_nonsecure_entry) { + if !tcx.sess.target.target.llvm_target.contains("thumbv8m") { + struct_span_err!(tcx.sess, attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension") + .emit(); + } + codegen_fn_attrs.flags |= CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY; } else if tcx.sess.check_name(attr, sym::thread_local) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL; } else if tcx.sess.check_name(attr, sym::track_caller) { diff --git a/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md b/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md new file mode 100644 index 0000000000000..9d69be3e69ba7 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md @@ -0,0 +1,75 @@ +# `cmse_nonsecure_entry` + +The tracking issue for this feature is: [#75835] + +[#75835]: https://github.com/rust-lang/rust/issues/75835 + +------------------------ + +The [TrustZone-M +feature](https://developer.arm.com/documentation/100690/latest/) is available +for targets with the Armv8-M architecture profile (`thumbv8m` in their target +name). +LLVM, the Rust compiler and the linker are providing +[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the +TrustZone-M feature. + +One of the things provided, with this unstable feature, is the +`cmse_nonsecure_entry` attribute. This attribute marks a Secure function as an +entry function (see [section +5.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details). +With this attribute, the compiler will do the following: +* add a special symbol on the function which is the `__acle_se_` prefix and the + standard function name +* constrain the number of parameters to avoid using the Non-Secure stack +* before returning from the function, clear registers that might contain Secure + information +* use the `BXNS` instruction to return + +The special symbol `__acle_se_` will be used by the linker to generate a secure +gateway veneer. + + + +``` rust,ignore +#![feature(cmse_nonsecure_entry)] + +#[no_mangle] +#[cmse_nonsecure_entry] +pub extern "C" fn entry_function(input: u32) -> u32 { + input + 6 +} +``` + +``` text +$ rustc --emit obj --crate-type lib --target thumbv8m.main-none-eabi function.rs +$ arm-none-eabi-objdump -D function.o + +00000000 : + 0: b580 push {r7, lr} + 2: 466f mov r7, sp + 4: b082 sub sp, #8 + 6: 9001 str r0, [sp, #4] + 8: 1d81 adds r1, r0, #6 + a: 460a mov r2, r1 + c: 4281 cmp r1, r0 + e: 9200 str r2, [sp, #0] + 10: d30b bcc.n 2a + 12: e7ff b.n 14 + 14: 9800 ldr r0, [sp, #0] + 16: b002 add sp, #8 + 18: e8bd 4080 ldmia.w sp!, {r7, lr} + 1c: 4671 mov r1, lr + 1e: 4672 mov r2, lr + 20: 4673 mov r3, lr + 22: 46f4 mov ip, lr + 24: f38e 8800 msr CPSR_f, lr + 28: 4774 bxns lr + 2a: f240 0000 movw r0, #0 + 2e: f2c0 0000 movt r0, #0 + 32: f240 0200 movw r2, #0 + 36: f2c0 0200 movt r2, #0 + 3a: 211c movs r1, #28 + 3c: f7ff fffe bl 0 <_ZN4core9panicking5panic17h5c028258ca2fb3f5E> + 40: defe udf #254 ; 0xfe +``` diff --git a/src/llvm-project b/src/llvm-project index 7075196da1aa3..2c56ba7db75b5 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 7075196da1aa3527f7c87943607e25f3cf24997a +Subproject commit 2c56ba7db75b536b0432228b4760ed79174eca30 diff --git a/src/test/ui/cmse-nonsecure-entry/params-on-stack.rs b/src/test/ui/cmse-nonsecure-entry/params-on-stack.rs new file mode 100644 index 0000000000000..14c334fd0102e --- /dev/null +++ b/src/test/ui/cmse-nonsecure-entry/params-on-stack.rs @@ -0,0 +1,11 @@ +// gate-test-cmse_nonsecure_entry +// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +// only-thumbv8m.main-none-eabi +#![feature(cmse_nonsecure_entry)] +#![no_std] + +#[no_mangle] +#[cmse_nonsecure_entry] +pub extern "C" fn entry_function(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 { + a + b + c + d + e +} diff --git a/src/test/ui/cmse-nonsecure-entry/params-on-stack.stderr b/src/test/ui/cmse-nonsecure-entry/params-on-stack.stderr new file mode 100644 index 0000000000000..d9956acbe7577 --- /dev/null +++ b/src/test/ui/cmse-nonsecure-entry/params-on-stack.stderr @@ -0,0 +1,5 @@ +error: :0:0: in function entry_function i32 (i32, i32, i32, i32, i32): secure entry function requires arguments on stack + + +error: aborting due to previous error + diff --git a/src/test/ui/cmse-nonsecure-entry/trustzone-only.rs b/src/test/ui/cmse-nonsecure-entry/trustzone-only.rs new file mode 100644 index 0000000000000..efb4eb09b68a8 --- /dev/null +++ b/src/test/ui/cmse-nonsecure-entry/trustzone-only.rs @@ -0,0 +1,11 @@ +// gate-test-cmse_nonsecure_entry +// ignore-thumbv8m.main-none-eabi +#![feature(cmse_nonsecure_entry)] + +#[no_mangle] +#[cmse_nonsecure_entry] //~ ERROR [E0775] +pub extern "C" fn entry_function(input: u32) -> u32 { + input + 6 +} + +fn main() {} diff --git a/src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr b/src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr new file mode 100644 index 0000000000000..d3e0c1e42eb42 --- /dev/null +++ b/src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr @@ -0,0 +1,9 @@ +error[E0775]: `#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension + --> $DIR/trustzone-only.rs:6:1 + | +LL | #[cmse_nonsecure_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0775`. From 2588287deffd92c4ca0b5b39f92b9cca894a3983 Mon Sep 17 00:00:00 2001 From: Hugues de Valon Date: Wed, 30 Sep 2020 18:10:17 +0100 Subject: [PATCH 3/3] Add more tests and check for ABI Signed-off-by: Hugues de Valon --- compiler/rustc_error_codes/src/error_codes.rs | 1 + .../src/error_codes/E0775.md | 2 +- .../src/error_codes/E0776.md | 13 +++++++++++++ compiler/rustc_typeck/src/collect.rs | 9 +++++++++ .../language-features/cmse-nonsecure-entry.md | 6 ++++++ src/test/ui/cmse-nonsecure-entry/gate_test.rs | 11 +++++++++++ .../ui/cmse-nonsecure-entry/gate_test.stderr | 19 +++++++++++++++++++ .../params-on-registers.rs | 11 +++++++++++ .../cmse-nonsecure-entry/params-on-stack.rs | 3 +-- .../ui/cmse-nonsecure-entry/trustzone-only.rs | 1 - .../trustzone-only.stderr | 2 +- src/test/ui/cmse-nonsecure-entry/wrong-abi.rs | 10 ++++++++++ .../ui/cmse-nonsecure-entry/wrong-abi.stderr | 9 +++++++++ 13 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0776.md create mode 100644 src/test/ui/cmse-nonsecure-entry/gate_test.rs create mode 100644 src/test/ui/cmse-nonsecure-entry/gate_test.stderr create mode 100644 src/test/ui/cmse-nonsecure-entry/params-on-registers.rs create mode 100644 src/test/ui/cmse-nonsecure-entry/wrong-abi.rs create mode 100644 src/test/ui/cmse-nonsecure-entry/wrong-abi.stderr diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index c97532967323e..8b21dacf78724 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -459,6 +459,7 @@ E0771: include_str!("./error_codes/E0771.md"), E0773: include_str!("./error_codes/E0773.md"), E0774: include_str!("./error_codes/E0774.md"), E0775: include_str!("./error_codes/E0775.md"), +E0776: include_str!("./error_codes/E0776.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/compiler/rustc_error_codes/src/error_codes/E0775.md b/compiler/rustc_error_codes/src/error_codes/E0775.md index f21ee73791cab..9bafd52f75cf2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0775.md +++ b/compiler/rustc_error_codes/src/error_codes/E0775.md @@ -7,7 +7,7 @@ Erroneous code example: #![feature(cmse_nonsecure_entry)] #[cmse_nonsecure_entry] -fn toto() {} +pub extern "C" fn entry_function() {} ``` To fix this error, compile your code for a Rust target that supports the diff --git a/compiler/rustc_error_codes/src/error_codes/E0776.md b/compiler/rustc_error_codes/src/error_codes/E0776.md new file mode 100644 index 0000000000000..d65beebe07c61 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0776.md @@ -0,0 +1,13 @@ +`#[cmse_nonsecure_entry]` functions require a C ABI + +Erroneous code example: + +```compile_fail,E0776 +#![feature(cmse_nonsecure_entry)] + +#[no_mangle] +#[cmse_nonsecure_entry] +pub fn entry_function(input: Vec) {} +``` + +To fix this error, declare your entry function with a C ABI, using `extern "C"`. diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 6c0d51ed71771..9aca112a9142d 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2544,6 +2544,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { } else if tcx.sess.check_name(attr, sym::used) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; } else if tcx.sess.check_name(attr, sym::cmse_nonsecure_entry) { + if tcx.fn_sig(id).abi() != abi::Abi::C { + struct_span_err!( + tcx.sess, + attr.span, + E0776, + "`#[cmse_nonsecure_entry]` requires C ABI" + ) + .emit(); + } if !tcx.sess.target.target.llvm_target.contains("thumbv8m") { struct_span_err!(tcx.sess, attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension") .emit(); diff --git a/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md b/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md index 9d69be3e69ba7..338fbc4b2bfca 100644 --- a/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md +++ b/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md @@ -26,6 +26,12 @@ With this attribute, the compiler will do the following: information * use the `BXNS` instruction to return +Because the stack can not be used to pass parameters, there will be compilation +errors if: +* the total size of all parameters is too big (for example more than four 32 + bits integers) +* the entry function is not using a C ABI + The special symbol `__acle_se_` will be used by the linker to generate a secure gateway veneer. diff --git a/src/test/ui/cmse-nonsecure-entry/gate_test.rs b/src/test/ui/cmse-nonsecure-entry/gate_test.rs new file mode 100644 index 0000000000000..02d5f20febc4a --- /dev/null +++ b/src/test/ui/cmse-nonsecure-entry/gate_test.rs @@ -0,0 +1,11 @@ +// gate-test-cmse_nonsecure_entry + +#[no_mangle] +#[cmse_nonsecure_entry] +//~^ ERROR [E0775] +//~| ERROR [E0658] +pub extern "C" fn entry_function(input: u32) -> u32 { + input + 6 +} + +fn main() {} diff --git a/src/test/ui/cmse-nonsecure-entry/gate_test.stderr b/src/test/ui/cmse-nonsecure-entry/gate_test.stderr new file mode 100644 index 0000000000000..75a29b317df87 --- /dev/null +++ b/src/test/ui/cmse-nonsecure-entry/gate_test.stderr @@ -0,0 +1,19 @@ +error[E0658]: the `#[cmse_nonsecure_entry]` attribute is an experimental feature + --> $DIR/gate_test.rs:4:1 + | +LL | #[cmse_nonsecure_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #75835 for more information + = help: add `#![feature(cmse_nonsecure_entry)]` to the crate attributes to enable + +error[E0775]: `#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension + --> $DIR/gate_test.rs:4:1 + | +LL | #[cmse_nonsecure_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0658, E0775. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/cmse-nonsecure-entry/params-on-registers.rs b/src/test/ui/cmse-nonsecure-entry/params-on-registers.rs new file mode 100644 index 0000000000000..a723eb734731d --- /dev/null +++ b/src/test/ui/cmse-nonsecure-entry/params-on-registers.rs @@ -0,0 +1,11 @@ +// build-pass +// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +// only-thumbv8m.main-none-eabi +#![feature(cmse_nonsecure_entry)] +#![no_std] + +#[no_mangle] +#[cmse_nonsecure_entry] +pub extern "C" fn entry_function(a: u32, b: u32, c: u32, d: u32) -> u32 { + a + b + c + d +} diff --git a/src/test/ui/cmse-nonsecure-entry/params-on-stack.rs b/src/test/ui/cmse-nonsecure-entry/params-on-stack.rs index 14c334fd0102e..553d3a8cb0be7 100644 --- a/src/test/ui/cmse-nonsecure-entry/params-on-stack.rs +++ b/src/test/ui/cmse-nonsecure-entry/params-on-stack.rs @@ -1,4 +1,3 @@ -// gate-test-cmse_nonsecure_entry // compile-flags: --target thumbv8m.main-none-eabi --crate-type lib // only-thumbv8m.main-none-eabi #![feature(cmse_nonsecure_entry)] @@ -6,6 +5,6 @@ #[no_mangle] #[cmse_nonsecure_entry] -pub extern "C" fn entry_function(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 { +pub extern "C" fn entry_function(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 { //~ ERROR a + b + c + d + e } diff --git a/src/test/ui/cmse-nonsecure-entry/trustzone-only.rs b/src/test/ui/cmse-nonsecure-entry/trustzone-only.rs index efb4eb09b68a8..3783e2794021f 100644 --- a/src/test/ui/cmse-nonsecure-entry/trustzone-only.rs +++ b/src/test/ui/cmse-nonsecure-entry/trustzone-only.rs @@ -1,4 +1,3 @@ -// gate-test-cmse_nonsecure_entry // ignore-thumbv8m.main-none-eabi #![feature(cmse_nonsecure_entry)] diff --git a/src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr b/src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr index d3e0c1e42eb42..7e8862f9ab7f2 100644 --- a/src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr +++ b/src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr @@ -1,5 +1,5 @@ error[E0775]: `#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension - --> $DIR/trustzone-only.rs:6:1 + --> $DIR/trustzone-only.rs:5:1 | LL | #[cmse_nonsecure_entry] | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/cmse-nonsecure-entry/wrong-abi.rs b/src/test/ui/cmse-nonsecure-entry/wrong-abi.rs new file mode 100644 index 0000000000000..611c8643dcb02 --- /dev/null +++ b/src/test/ui/cmse-nonsecure-entry/wrong-abi.rs @@ -0,0 +1,10 @@ +// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +// only-thumbv8m.main-none-eabi +#![feature(cmse_nonsecure_entry)] +#![no_std] + +#[no_mangle] +#[cmse_nonsecure_entry] +pub fn entry_function(a: u32, b: u32, c: u32, d: u32) -> u32 { //~ ERROR [E0776] + a + b + c + d +} diff --git a/src/test/ui/cmse-nonsecure-entry/wrong-abi.stderr b/src/test/ui/cmse-nonsecure-entry/wrong-abi.stderr new file mode 100644 index 0000000000000..d6967a11e6bf7 --- /dev/null +++ b/src/test/ui/cmse-nonsecure-entry/wrong-abi.stderr @@ -0,0 +1,9 @@ +error[E0776]: `#[cmse_nonsecure_entry]` functions require C ABI + --> $DIR/wrong-abi.rs:7:1 + | +LL | #[cmse_nonsecure_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0776`.