mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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 <hugues.devalon@arm.com>
This commit is contained in:
parent
d255d70e7a
commit
1aaafac6ff
@ -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) {
|
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) {
|
||||||
Attribute::NoAlias.apply_llfn(llvm::AttributePlace::ReturnValue, llfn);
|
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);
|
sanitize(cx, codegen_fn_attrs.no_sanitize, llfn);
|
||||||
|
|
||||||
// Always annotate functions with the target-cpu they are compiled for.
|
// Always annotate functions with the target-cpu they are compiled for.
|
||||||
|
@ -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)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum AttributePlace {
|
pub enum AttributePlace {
|
||||||
ReturnValue,
|
ReturnValue,
|
||||||
|
@ -458,6 +458,7 @@ E0770: include_str!("./error_codes/E0770.md"),
|
|||||||
E0771: include_str!("./error_codes/E0771.md"),
|
E0771: include_str!("./error_codes/E0771.md"),
|
||||||
E0773: include_str!("./error_codes/E0773.md"),
|
E0773: include_str!("./error_codes/E0773.md"),
|
||||||
E0774: include_str!("./error_codes/E0774.md"),
|
E0774: include_str!("./error_codes/E0774.md"),
|
||||||
|
E0775: include_str!("./error_codes/E0775.md"),
|
||||||
;
|
;
|
||||||
// E0006, // merged with E0005
|
// E0006, // merged with E0005
|
||||||
// E0008, // cannot bind by-move into a pattern guard
|
// E0008, // cannot bind by-move into a pattern guard
|
||||||
|
17
compiler/rustc_error_codes/src/error_codes/E0775.md
Normal file
17
compiler/rustc_error_codes/src/error_codes/E0775.md
Normal file
@ -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`
|
@ -590,6 +590,9 @@ declare_features! (
|
|||||||
/// Allows using and casting function pointers in a `const fn`.
|
/// Allows using and casting function pointers in a `const fn`.
|
||||||
(active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None),
|
(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
|
// feature-group-end: actual feature gates
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
@ -349,6 +349,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
experimental!(register_tool),
|
experimental!(register_tool),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
gated!(cmse_nonsecure_entry, AssumedUsed, template!(Word), experimental!(cmse_nonsecure_entry)),
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Internal attributes: Stability, deprecation, and unsafe:
|
// Internal attributes: Stability, deprecation, and unsafe:
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -79,6 +79,9 @@ bitflags! {
|
|||||||
/// #[ffi_const]: applies clang's `const` attribute to a foreign function
|
/// #[ffi_const]: applies clang's `const` attribute to a foreign function
|
||||||
/// declaration.
|
/// declaration.
|
||||||
const FFI_CONST = 1 << 13;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +337,7 @@ symbols! {
|
|||||||
closure_to_fn_coercion,
|
closure_to_fn_coercion,
|
||||||
cmp,
|
cmp,
|
||||||
cmpxchg16b_target_feature,
|
cmpxchg16b_target_feature,
|
||||||
|
cmse_nonsecure_entry,
|
||||||
coerce_unsized,
|
coerce_unsized,
|
||||||
cold,
|
cold,
|
||||||
column,
|
column,
|
||||||
|
@ -2543,6 +2543,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
|
|||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
|
||||||
} else if tcx.sess.check_name(attr, sym::used) {
|
} else if tcx.sess.check_name(attr, sym::used) {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::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) {
|
} else if tcx.sess.check_name(attr, sym::thread_local) {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
|
||||||
} else if tcx.sess.check_name(attr, sym::track_caller) {
|
} else if tcx.sess.check_name(attr, sym::track_caller) {
|
||||||
|
@ -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
|
||||||
|
```
|
@ -1 +1 @@
|
|||||||
Subproject commit 7075196da1aa3527f7c87943607e25f3cf24997a
|
Subproject commit 2c56ba7db75b536b0432228b4760ed79174eca30
|
11
src/test/ui/cmse-nonsecure-entry/params-on-stack.rs
Normal file
11
src/test/ui/cmse-nonsecure-entry/params-on-stack.rs
Normal file
@ -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
|
||||||
|
}
|
5
src/test/ui/cmse-nonsecure-entry/params-on-stack.stderr
Normal file
5
src/test/ui/cmse-nonsecure-entry/params-on-stack.stderr
Normal file
@ -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
|
||||||
|
|
11
src/test/ui/cmse-nonsecure-entry/trustzone-only.rs
Normal file
11
src/test/ui/cmse-nonsecure-entry/trustzone-only.rs
Normal file
@ -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() {}
|
9
src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr
Normal file
9
src/test/ui/cmse-nonsecure-entry/trustzone-only.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user