|
| 1 | +# `cmse_nonsecure_entry` |
| 2 | + |
| 3 | +The tracking issue for this feature is: [#75835] |
| 4 | + |
| 5 | +[#75835]: https://github.com/rust-lang/rust/issues/75835 |
| 6 | + |
| 7 | +------------------------ |
| 8 | + |
| 9 | +The [TrustZone-M |
| 10 | +feature](https://developer.arm.com/documentation/100690/latest/) is available |
| 11 | +for targets with the Armv8-M architecture profile (`thumbv8m` in their target |
| 12 | +name). |
| 13 | +LLVM, the Rust compiler and the linker are providing |
| 14 | +[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the |
| 15 | +TrustZone-M feature. |
| 16 | + |
| 17 | +One of the things provided, with this unstable feature, is the |
| 18 | +`cmse_nonsecure_entry` attribute. This attribute marks a Secure function as an |
| 19 | +entry function (see [section |
| 20 | +5.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details). |
| 21 | +With this attribute, the compiler will do the following: |
| 22 | +* add a special symbol on the function which is the `__acle_se_` prefix and the |
| 23 | + standard function name |
| 24 | +* constrain the number of parameters to avoid using the Non-Secure stack |
| 25 | +* before returning from the function, clear registers that might contain Secure |
| 26 | + information |
| 27 | +* use the `BXNS` instruction to return |
| 28 | + |
| 29 | +Because the stack can not be used to pass parameters, there will be compilation |
| 30 | +errors if: |
| 31 | +* the total size of all parameters is too big (for example more than four 32 |
| 32 | + bits integers) |
| 33 | +* the entry function is not using a C ABI |
| 34 | + |
| 35 | +The special symbol `__acle_se_` will be used by the linker to generate a secure |
| 36 | +gateway veneer. |
| 37 | + |
| 38 | +<!-- NOTE(ignore) this example is specific to thumbv8m targets --> |
| 39 | + |
| 40 | +``` rust,ignore |
| 41 | +#![feature(cmse_nonsecure_entry)] |
| 42 | +
|
| 43 | +#[no_mangle] |
| 44 | +#[cmse_nonsecure_entry] |
| 45 | +pub extern "C" fn entry_function(input: u32) -> u32 { |
| 46 | + input + 6 |
| 47 | +} |
| 48 | +``` |
| 49 | + |
| 50 | +``` text |
| 51 | +$ rustc --emit obj --crate-type lib --target thumbv8m.main-none-eabi function.rs |
| 52 | +$ arm-none-eabi-objdump -D function.o |
| 53 | +
|
| 54 | +00000000 <entry_function>: |
| 55 | + 0: b580 push {r7, lr} |
| 56 | + 2: 466f mov r7, sp |
| 57 | + 4: b082 sub sp, #8 |
| 58 | + 6: 9001 str r0, [sp, #4] |
| 59 | + 8: 1d81 adds r1, r0, #6 |
| 60 | + a: 460a mov r2, r1 |
| 61 | + c: 4281 cmp r1, r0 |
| 62 | + e: 9200 str r2, [sp, #0] |
| 63 | + 10: d30b bcc.n 2a <entry_function+0x2a> |
| 64 | + 12: e7ff b.n 14 <entry_function+0x14> |
| 65 | + 14: 9800 ldr r0, [sp, #0] |
| 66 | + 16: b002 add sp, #8 |
| 67 | + 18: e8bd 4080 ldmia.w sp!, {r7, lr} |
| 68 | + 1c: 4671 mov r1, lr |
| 69 | + 1e: 4672 mov r2, lr |
| 70 | + 20: 4673 mov r3, lr |
| 71 | + 22: 46f4 mov ip, lr |
| 72 | + 24: f38e 8800 msr CPSR_f, lr |
| 73 | + 28: 4774 bxns lr |
| 74 | + 2a: f240 0000 movw r0, #0 |
| 75 | + 2e: f2c0 0000 movt r0, #0 |
| 76 | + 32: f240 0200 movw r2, #0 |
| 77 | + 36: f2c0 0200 movt r2, #0 |
| 78 | + 3a: 211c movs r1, #28 |
| 79 | + 3c: f7ff fffe bl 0 <_ZN4core9panicking5panic17h5c028258ca2fb3f5E> |
| 80 | + 40: defe udf #254 ; 0xfe |
| 81 | +``` |
0 commit comments