Open hug-dev opened 4 years ago
Note: the error produced when an entry function require arguments being passed on the stack is currently a LLVM error. It would be better to have this error being thrown out in Rust ABI, for better user experience.
noticed the current implementation only allows FFI functions (or extern "C" functions) to be decorated with the attribute. I'm assuming this is only required because the implementation needs the function to use a C ABI and the function by itself is actually safe (i.e. no unsafe code
here). Is my understanding correct?
The reason the C ABI is forced for entry function is because parameters must only be passed using registers and not using memory. See this comment for reference:
Ah, I think we should definitely forbid using this attribute with non-"C" ABI functions then. Since the Rust ABI is unstable, it can pass arguments either directly in registers, or in memory, and that would be a problem here.
This is because depending where the parameters would be in memory, there would be more work needed in LLVM to access them from Secure. For example if they were pushed on to the Non-Secure stack when NS calls the entry functions, LLVM would have to put them onto the Secure stack as a prelude before the actual function executes so that the parameters are where expected 👌
I am thinking now that this could also be implemented as an ABI, similarly than cmse-nonsecure-call
. It could even be the same extern symbol let's say extern "C-cmse-nonsecure"
that:
cmse_nonsecure_entry
LLVM attribute on itcmse_nonsecure_call
callsite attributeWe already restrict the C ABI for entry functions anyway!
We discussed this in today's @rust-lang/lang meeting. We felt like an extern "ABI"
does make sense for most of the functionality of this. What's left sounds like the generation of a special symbol, and it's not clear if we should have that as a built-in attribute, a library attribute, or something in a crate.
What is the recommended work around to deal with entry functions that require many arguments, e.g., 5x i32
? Currently, this is causes an error:
error: <unknown>:0:0: in function fkt i32 (i32, i32, i32, i32, i32): secure entry function requires arguments on stack
What is the recommended work around to deal with entry functions that require many arguments, e.g., 5x
i32
? Currently, this is causes an error:error: <unknown>:0:0: in function fkt i32 (i32, i32, i32, i32, i32): secure entry function requires arguments on stack
Hey!
It is possible for you to pass pointers to structures containing more data. The only drawback is that you must check in the Secure function that the address is accessible by the Non-Secure code. You can do that with the TestTarget
functions.
One caveat with these functions is that they should not be callable from the current binary as that is in the secure context. So calling a function marked extern "C-cmse-nonsecure-entry"
or #[cmse_nonsecure_entry]
would end with a BXNS
instruction and return to wherever the non-secure sides stack indicates, instead of the function that actually called it.
I tried it out on godbolt and LLVM seems to just permit it. I still think rustc should give an error.
Edit: Reading the docs again, BXNS
determines whether to switch to non-secure state based on the least significant bit of the address it will jump to. So maybe this would be ok?
Edit: I asked a developer who is using Trustzone from C and there it is not uncommon to call these entry functions even in your secure zone. So this should just work thanks to LLVM.
I think that some random target feature putting something in the global attribute namespace is a bad precedent.
To me, this should be namespaced in some way -- I don't know if that means #[arch::something_or_other]
or what.
This is a tracking issue for the PR #75810. It was deemed in that PR that a RFC was not necessary because the changes were small. The feature gate for the issue is
#![feature(cmse_nonsecure_entry)]
.Description
The
cmse_nonsecure_entry
attribute is a target-dependent attribute available forthumbv8m
targets. It directly maps to the attribute of the same name in LLVM.It is to be used under the TrustZone-M technology for Armv8-M architecture.
It will modify code generation of Secure entry functions:
__acle_se_
prefix and the standard function nameBXNS
instruction to returnSee section 5.4 of ARMv8-M Security Extensions: Requirements on Development Tools - Engineering Specification for more details.
Example
Having a Secure entry function named
entry_function
:With those commands:
it will emit the following assembly:
You can see from
1c
to24
the clearing of the registers and theBXNS
instruction used on28
.Steps