gcc10 generates wrong code for cmse_nonsecure_call API for cortex-m33

Bug #1935681 reported by News
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
Fix Released
Undecided
Unassigned

Bug Description

Release version: arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release)
Host machine: Win10 WSL-1 with Ubuntu 20.04
Symptom: Generate wrong code for cmse_nonsecure_call API
The cmse_nonsecure_call API code should use register r4 to carry the nonsecure function ptr before jumping to __gnu_cmse_nonsecure_call. However, gcc10 sometimes uses other registers, which leads to crash.
gcc9 works well on the same source code with the same building options.

Sample C source code:
--------------------

$ cat test.c
#include <arm_cmse.h>

typedef void (*funcptr_void) (void) __attribute__((cmse_nonsecure_call));

void ttt(void)
{
    funcptr_void nsfunc;
    nsfunc = (funcptr_void)0x10000004;
    nsfunc = (funcptr_void)cmse_check_address_range((void *)nsfunc, 4, CMSE_NONSECURE);
    if (nsfunc) {
        nsfunc();
    }
}

Build cmd line options:
----------------------
$ arm-none-eabi-gcc -mthumb -mcpu=cortex-m33 -mcmse -g -O2 -c -o test.o test.c

The disassembly code for gcc10 build (the wrong one)
----------------------------------------------------

00000000 <ttt>:
ttt():
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:6
#include <arm_cmse.h>

typedef void (*funcptr_void) (void) __attribute__((cmse_nonsecure_call));

void ttt(void)
{
   0: b508 push {r3, lr}
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:9
    funcptr_void nsfunc;
    nsfunc = (funcptr_void)0x10000004;
    nsfunc = (funcptr_void)cmse_check_address_range((void *)nsfunc, 4, CMSE_NONSECURE);
   2: 2212 movs r2, #18
   4: 2104 movs r1, #4
   6: 4806 ldr r0, [pc, #24] ; (20 <ttt+0x20>)
   8: f7ff fffe bl 0 <cmse_check_address_range>
                        8: R_ARM_THM_CALL cmse_check_address_range
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:10
    if (nsfunc) {
   c: b130 cbz r0, 1c <ttt+0x1c>
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:11
        nsfunc();
   e: 0840 lsrs r0, r0, #1
  10: 0040 lsls r0, r0, #1
  12: 4601 mov r1, r0
  14: 4602 mov r2, r0
  16: 4603 mov r3, r0
  18: f7ff fffe bl 0 <__gnu_cmse_nonsecure_call>
                        18: R_ARM_THM_CALL __gnu_cmse_nonsecure_call
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:13
    }
}
  1c: bd08 pop {r3, pc}
  1e: bf00 nop
  20: 10000004 .word 0x10000004

The disassembly code for gcc9 build (the good one)
--------------------------------------------------

00000000 <ttt>:
ttt():
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:6
#include <arm_cmse.h>

typedef void (*funcptr_void) (void) __attribute__((cmse_nonsecure_call));

void ttt(void)
{
   0: b510 push {r4, lr}
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:9
    funcptr_void nsfunc;
    nsfunc = (funcptr_void)0x10000004;
    nsfunc = (funcptr_void)cmse_check_address_range((void *)nsfunc, 4, CMSE_NONSECURE);
   2: 2212 movs r2, #18
   4: 2104 movs r1, #4
   6: 4807 ldr r0, [pc, #28] ; (24 <ttt+0x24>)
   8: f7ff fffe bl 0 <cmse_check_address_range>
                        8: R_ARM_THM_CALL cmse_check_address_range
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:10
    if (nsfunc) {
   c: b140 cbz r0, 20 <ttt+0x20>
   e: 4604 mov r4, r0
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:11
        nsfunc();
  10: 0864 lsrs r4, r4, #1
  12: 0064 lsls r4, r4, #1
  14: 4620 mov r0, r4
  16: 4621 mov r1, r4
  18: 4622 mov r2, r4
  1a: 4623 mov r3, r4
  1c: f7ff fffe bl 0 <__gnu_cmse_nonsecure_call>
                        1c: R_ARM_THM_CALL __gnu_cmse_nonsecure_call
/mnt/d/source/mcu-sw_2/out/cm33_se/test.c:13
    }
}
  20: bd10 pop {r4, pc}
  22: bf00 nop
  24: 10000004 .word 0x10000004

Tags: trustzone
Revision history for this message
News (nnnhhhw) wrote :

Any update on this issue?

Revision history for this message
News (nnnhhhw) wrote :

This is a duplicate with https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99271
In GNU Arm Embedded Toolchain 10.3-2021.07, this issue has been fixed.
The above code is also used to verified on gcc 10.3, and the result is correct.

Changed in gcc-arm-embedded:
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.