Overview of building Secure and Non-secure images
ARM® Compiler 6 tools allow you to build images that run in the Secure state of the ARMv8-M Security Extensions. You can also create an import library package that developers of Non-secure images must have for those images to call the Secure image.
NoteARMv8-M Security Extensions are not supported when building Read-Only Position-Independent (ROPI) and Read-Write Position-Independent (RWPI) images.
To build an image that runs in the Secure state you must include the
<arm_cmse.h> header in your code, and
compile using the armclang
-mcmse command-line option. Compiling in this way
makes the following features available:
- The Test Target,
- Non-secure function pointer intrinsics.
On startup, your Secure code must set up the Security Attribution Unit (SAU) and call the Non-secure startup code.
Important considerations when compiling Secure and Non-secure code
Be aware of the following when compiling Secure and Non-secure code:
- You can compile your Secure and Non-secure code in C or C++, but the boundary between the two must have C function call linkage.
- You cannot pass C++ objects, such as classes and references, across the security boundary.
- You must not throw C++ exceptions across the security boundary.
- The value of the
__ARM_FEATURE_CMSEpredefined macro indicates what ARMv8-M Security Extension features are supported.
Secure code with the maximum capabilities for the target. For
example, if you compile with no FPU then the Secure functions do not
clear floating-point registers when returning from functions
__attribute__((cmse_nonsecure_entry)). Therefore, the functions could potentially leak sensitive data.
- Structs with undefined bits caused by padding and half float are currently unsupported as arguments and return values for Secure functions. Using such structs might leak sensitive information. Structs that are large enough to be passed by pointer are also unsupported and produce an error.
The following cases are not supported when compiling with
-mcmseand give an error:
- Variadic entry functions.
- Entry functions with arguments that do not fit in registers, because there are either many arguments or the arguments have large values.
- Non-secure function calls with arguments that do not fit in registers, because there are either many arguments or the arguments have large values.
How a Non-secure image calls a Secure image using veneers
Calling a Secure image from a Non-secure image requires a transition from Non-secure to Secure state. A transition is initiated through Secure gateway veneers. Secure gateway veneers decouple the addresses from the rest of the Secure code.
An entry point in the Secure image,
, is identified
The calling sequence is as follows:
- The Non-secure image uses the branch
BLinstruction to call the Secure gateway veneer for the required entry function in the Secure image:
- The Secure gateway veneer consists of the
SGinstruction and a call to the entry function in the Secure image using the
entrynameSG B.W __acle_se_
- The Secure image returns from the entry function using the
The following figure is a graphical representation of the calling sequence, but for clarity, the return from the entry function is not shown:
Import library package
An import library package identifies the entry functions available in a Secure image. The import library package contains:
- An interface header file, for example myinterface.h. You manually create this file using any text editor.
- An import library, for example importlib.o. armlink
generates this library during the link stage for a Secure image.
You must do separate compile and link stages:
- To create an import library when building a Secure image.
- To use an import library when building a Non-secure image.