9.4 Building a Secure image using a previously generated import library

You can build a new version of a Secure image and use the same addresses for the entry points that were present in the previous version. You specify the import library that is generated for the previous version of the Secure image and generate another import library for the new Secure image.

Prerequisites

The following procedure is not a complete example, and assumes that your code sets up the Security Attribution Unit (SAU) and calls the Non-secure startup code.

The following procedure assumes that you have the import library package that is created in 9.2 Building a Secure image using the ARMv8-M Security Extensions.

Procedure

  1. Create an interface header file, myinterface_v2.h, to specify the C linkage for use by Non-secure code:
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    int entry1(int x);
    int entry2(int x);
    int entry3(int x);
    int entry4(int x);
    
    #ifdef __cplusplus
    }
    #endif
  2. Include the following in the C program for your Secure code, secure.c:
    #include <arm_cmse.h>
    #include "myinterface_v2.h"
    
    int func1(int x) { return x; }
    int __attribute__((cmse_nonsecure_entry)) entry1(int x) { return func1(x);  }
    int __attribute__((cmse_nonsecure_entry)) entry2(int x) { return entry1(x); }
    int __attribute__((cmse_nonsecure_entry)) entry3(int x) { return func1(x) + entry1(x);  }
    int __attribute__((cmse_nonsecure_entry)) entry4(int x) { return entry1(x) * entry2(x); }
    
    int main(void) { return 0; }
    In addition to the implementation of the two entry functions, the code defines the function func1() that is called only by Secure code.

    Note:

    If you are compiling the Secure code as C++, then you must add extern "C" to the functions declared as __attribute__((cmse_nonsecure_entry)).
  3. Create an object file using the armclang -mcmse command-line options:
    $ armclang -c --target arm-arm-none-eabi -march=armv8-m.main -mcmse secure.c -o secure.o
  4. To see the disassembly of the machine code that is generated by armclang, enter:
    $ armclang -c --target arm-arm-none-eabi -march=armv8-m.main -mcmse -S secure.c
    The disassembly is stored in the file secure.s, for example:
        .text
        ...
        .code 16
        .thumb_func
    
        ...
    
    func1:
        .fnstart
        ...
        bx lr
    
        ...
    
    __acle_se_entry1:
    entry1:
        .fnstart
    @ BB#0:
        .save	{r7, lr}
        push	{r7, lr}
        ...
        bl func1
        pop.w {r7, lr}
        ...
        bxns lr
    
        ...
    
    __acle_se_entry4:
    entry4:
        .fnstart
    @ BB#0:
        .save	{r7, lr}
        push	{r7, lr}
        ...
        bl entry1
        ...
        pop.w {r7, lr}
        bxns lr
    
        ...
    
    main:
        .fnstart
    @ BB#0:
        ...
        movs r0, #0
        ...
        bx lr
    
        ...

    An entry function does not start with a Secure Gateway (SG) instruction. The two symbols __acle_se_entry_name and entry_name indicate the start of an entry function to the linker.

  5. Create a scatter file containing the Veneer$$CMSE selector to place the entry function veneers in a Non-Secure Callable (NSC) memory region.
    LOAD_REGION 0x0 0x3000
    {
        EXEC_R 0x0
        {
            *(+RO,+RW,+ZI)
        }
        EXEC_NSCR 0x4000 0x1000
        {
            *(Veneer$$CMSE)
        }
        ARM_LIB_STACK 0x700000 EMPTY -0x10000
        {
        }
        ARM_LIB_HEAP  +0 EMPTY 0x10000
        {
        }
    }
    ...
  6. Link the object file using the armlink --import-cmse-lib-out and --import-cmse-lib-in command-line option, together with the preprocessed scatter file to create the Secure image:
    $ armlink secure.o -o secure.axf --cpu 8-M.Main --import-cmse-lib-out importlib_v2.o --import-cmse-lib-in importlib_v1.o --scatter secure.scf

    In addition to the final image, the link in this example also produces the import library, importlib_v2.o, for use when building a Non-secure image. Assuming that the section with veneers is placed at address 0x4000, the import library consists of a relocatable file containing only a symbol table with the following entries:

    Symbol type Name Address
    STB_GLOBAL, SHN_ABS, STT_FUNC entry1 0x4001
    STB_GLOBAL, SHN_ABS, STT_FUNC entry2 0x4009
    STB_GLOBAL, SHN_ABS, STT_FUNC entry3 0x4021
    STB_GLOBAL, SHN_ABS, STT_FUNC entry4 0x4029

    When you link the relocatable file corresponding to this assembly code into an image, the linker creates veneers in a section containing only entry veneers.

  7. Enter the following command to see the entry veneers that the linker generates:
    $ fromelf --text -s -c secure.axf

    The following entry veneers are generated in the EXEC_NSCR execute-only (XO) region for this example:

    ...
    
    ** Section #3 'EXEC_NSCR' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR + SHF_ARM_NOREAD]
        Size   : 64 bytes (alignment 32)
        Address: 0x00004000
    
        $t
        entry1
            0x00004000:    e97fe97f    ....    SG        ; [0x3e08]
            0x00004004:    f7fcb85e    ..^.    B        __acle_se_entry1 ; 0xc4
        entry2
            0x00004008:    e97fe97f    ....    SG        ; [0x3e10]
            0x0000400c:    f7fcb86c    ..l.    B        __acle_se_entry2 ; 0xe8
    
    ...
    
        entry3
            0x00004020:    e97fe97f    ....    SG        ; [0x3e28]
            0x00004024:    f7fcb872    ..r.    B        __acle_se_entry3 ; 0x10c
        entry4
            0x00004028:    e97fe97f    ....    SG        ; [0x3e30]
            0x0000402c:    f7fcb888    ....    B        __acle_se_entry4 ; 0x140
    
    ...

    The section with the veneers is aligned on a 32-byte boundary and padded to a 32-byte boundary.

    If you do not use a scatter file, the entry veneers are placed in an ER_XO section as the first execution region. The entry veneers for the existing entry points are placed in a CMSE veneer section. For example:

    ...
    
    ** Section #1 'ER_XO' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR + SHF_ARM_NOREAD]
        Size   : 32 bytes (alignment 32)
        Address: 0x00008000
    
        $t
        entry3
            0x00008000:    e97fe97f    ....    SG        ; [0x7e08]
            0x00008004:    f000b87e    ..~.    B.W      __acle_se_entry3 ; 0x8104
        entry4
            0x00008008:    e97fe97f    ....    SG        ; [0x7e10]
            0x0000800c:    f000b894    ....    B.W      __acle_se_entry4 ; 0x8138
    
    ...
    
    ** Section #4 'ER$$Veneer$$CMSE_AT_0x00004000' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR + SHF_ARM_NOREAD]
        Size   : 32 bytes (alignment 32)
        Address: 0x00004000
    
        $t
        entry1
            0x00004000:    e97fe97f    ....    SG        ; [0x3e08]
            0x00004004:    f004b85a    ..Z.    B.W      __acle_se_entry1 ; 0x80bc
        entry2
            0x00004008:    e97fe97f    ....    SG        ; [0x3e10]
            0x0000400c:    f004b868    ..h.    B.W      __acle_se_entry2 ; 0x80e0
    
    ...

Postrequisites

After you have built your updated Secure image:

  1. Pre-load the updated Secure image onto your device.
  2. Deliver your device with the pre-loaded image, together with the new import library package, to a party who develops the Non-secure code for this device. The import library package contains:
    • The interface header file, myinterface_v2.h.
    • The import library, importlib_v2.o.
Non-ConfidentialPDF file icon PDF versionARM 100066_0608_00_en
Copyright © 2014–2017 ARM Limited or its affiliates. All rights reserved.