about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/mod.rs6
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0775.md17
-rw-r--r--compiler/rustc_feature/src/active.rs3
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs3
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_typeck/src/collect.rs6
-rw-r--r--src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md75
m---------src/llvm-project0
-rw-r--r--src/test/ui/cmse-nonsecure-entry/params-on-stack.rs11
-rw-r--r--src/test/ui/cmse-nonsecure-entry/params-on-stack.stderr5
-rw-r--r--src/test/ui/cmse-nonsecure-entry/trustzone-only.rs11
-rw-r--r--src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr9
15 files changed, 153 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 227a87ff819..73c34818446 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 c09e3659f80..ed9b99188bb 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 a202736ea6c..c9753296732 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 00000000000..f21ee73791c
--- /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 7f5b1913480..348cff8d2da 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 22c1ca2f289..b7e113e6010 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 62a6198b9b4..d71cdc4e67d 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 4234aef3359..e3ad31469b2 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 d6985f3bd4d..6c0d51ed717 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 00000000000..9d69be3e69b
--- /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.
+
+<!-- NOTE(ignore) this example is specific to thumbv8m targets -->
+
+``` 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 <entry_function>:
+   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 <entry_function+0x2a>
+  12:   e7ff            b.n     14 <entry_function+0x14>
+  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
-Subproject 7075196da1aa3527f7c87943607e25f3cf24997
+Subproject 2c56ba7db75b536b0432228b4760ed79174eca3
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 00000000000..14c334fd010
--- /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 00000000000..d9956acbe75
--- /dev/null
+++ b/src/test/ui/cmse-nonsecure-entry/params-on-stack.stderr
@@ -0,0 +1,5 @@
+error: <unknown>: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 00000000000..efb4eb09b68
--- /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 00000000000..d3e0c1e42eb
--- /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`.