Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking Issue for the C-cmse-nonsecure-call ABI #81391

Open
2 tasks
hug-dev opened this issue Jan 25, 2021 · 4 comments
Open
2 tasks

Tracking Issue for the C-cmse-nonsecure-call ABI #81391

hug-dev opened this issue Jan 25, 2021 · 4 comments
Labels
C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-abi_c_cmse_nonsecure_call `#![feature(abi_c_cmse_nonsecure_call)]` O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state WG-embedded Working group: Embedded systems

Comments

@hug-dev
Copy link
Contributor

hug-dev commented Jan 25, 2021

This is a tracking issue for the PR #81346.
The feature gate for the issue is #![feature(abi_c_cmse_nonsecure_call)].

Description

The TrustZone-M feature 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 for the TrustZone-M feature.

One of the things provided, with this unstable feature, is the C-cmse-nonsecure-call function ABI. This ABI is used on function pointers to non-secure code to mark a non-secure function call (see section 5.5 for details).

With this ABI, the compiler will do the following to perform the call:

  • save registers needed after the call to Secure memory
  • clear all registers that might contain confidential information
  • clear the Least Significant Bit of the function address
  • branches using the BLXNS instruction

To avoid using the non-secure stack, the compiler will constrain the number and type of parameters/return value.

The extern "C-cmse-nonsecure-call" ABI is otherwise equivalent to the extern "C" ABI.

Example

#![no_std]
#![feature(abi_c_cmse_nonsecure_call)]

#[no_mangle]
pub fn call_nonsecure_function(addr: usize) -> u32 {
    let non_secure_function =
        unsafe { core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn() -> u32>(addr) };
    non_secure_function()
}
$ rustc --emit asm --crate-type lib --target thumbv8m.main-none-eabi function.rs

call_nonsecure_function:
        .fnstart
        .save   {r7, lr}
        push    {r7, lr}
        .setfp  r7, sp
        mov     r7, sp
        .pad    #16
        sub     sp, #16
        str     r0, [sp, #12]
        ldr     r0, [sp, #12]
        str     r0, [sp, #8]
        b       .LBB0_1
.LBB0_1:
        ldr     r0, [sp, #8]
        push.w  {r4, r5, r6, r7, r8, r9, r10, r11}
        bic     r0, r0, #1
        mov     r1, r0
        mov     r2, r0
        mov     r3, r0
        mov     r4, r0
        mov     r5, r0
        mov     r6, r0
        mov     r7, r0
        mov     r8, r0
        mov     r9, r0
        mov     r10, r0
        mov     r11, r0
        mov     r12, r0
        msr     apsr_nzcvq, r0
        blxns   r0
        pop.w   {r4, r5, r6, r7, r8, r9, r10, r11}
        str     r0, [sp, #4]
        b       .LBB0_2
.LBB0_2:
        ldr     r0, [sp, #4]
        add     sp, #16
        pop     {r7, pc}

Steps

@hug-dev hug-dev added the C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. label Jan 25, 2021
@jonas-schievink jonas-schievink added F-abi_c_cmse_nonsecure_call `#![feature(abi_c_cmse_nonsecure_call)]` O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state WG-embedded Working group: Embedded systems labels Jan 25, 2021
@nagisa
Copy link
Member

nagisa commented Jan 26, 2021

What's the name of the actual underlying calling convention? Is it AAPCS? I think the extern name should contain it too somehow.

@hug-dev
Copy link
Contributor Author

hug-dev commented Jan 26, 2021

What's the name of the actual underlying calling convention?

It will use the C convention ultimately, the current implementation maps it to llvm::CCallConv (I guess similar than AAPCS as this feature is only available on Arm processors?).
Do you mean that because it might be possible to have the cmse_nonsecure_call feature available for other ABIs as well?

I think restricting it to only ever use the C ABI is not a bad thing: this is used to switch to functions that are defined in other executable files that could have been written in any programming language.

@nagisa
Copy link
Member

nagisa commented Jan 26, 2021

Well, what I really want is for the underlying ABI to be explicit in the ABI string, whatever it is, so that it is more obvious that a transmute as given in the example above is… valid. It would also, as you mention, enable us to add non-secure options for other calling conventions if necessary.

So a couple of proposals: C_cmse_nonsecure or cmse_nonsecure_C.

@hug-dev
Copy link
Contributor Author

hug-dev commented Jan 26, 2021

Ok makes sense! Will modify the implementation PR and this with the C in front: extern "C-cmse-nonsecure-call".

@hug-dev hug-dev changed the title Tracking Issue for the cmse-nonsecure-call ABI Tracking Issue for the C-cmse-nonsecure-call ABI Jan 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-abi_c_cmse_nonsecure_call `#![feature(abi_c_cmse_nonsecure_call)]` O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state WG-embedded Working group: Embedded systems
Projects
None yet
Development

No branches or pull requests

3 participants