You copied the Doc URL to your clipboard.

Overview of building Secure and Non-secure images

Arm® Compiler 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.


The Armv8‑M Security Extension is 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, TT, instruction.
  • TT instruction intrinsics.
  • Non-secure function pointer intrinsics.
  • The __attribute__((cmse_nonsecure_call)) and __attribute__((cmse_nonsecure_entry)) function attributes.

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_CMSE predefined macro indicates what Armv8‑M Security Extension features are supported.
  • Compile 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 declared as __attribute__((cmse_nonsecure_entry)). Therefore, the functions could potentially leak sensitive data.
  • Structs with undefined bits caused by padding and half-precision floating-point members 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 reference are also unsupported and produce an error.
  • The following cases are not supported when compiling with -mcmse and produce 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, entryname, is identified with:


The calling sequence is as follows:

  1. The Non-secure image uses the branch BL instruction to call the Secure gateway veneer for the required entry function in the Secure image:
    bl    entryname
  2. The Secure gateway veneer consists of the SG instruction and a call to the entry function in the Secure image using the B instruction:
        B.W        __acle_se_entryname
  3. The Secure image returns from the entry function using the BXNS instruction:
    bxns  lr

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.