Created attachment 14091 [details]
Track msp and psp for targets with security ext
For Arm Cortex-M33 with trustzone enabled, the stack unwinding does not work as expected when a interrupt happens where the ISR is in secure context and the CPU is currently executing in non-secure context.
Using the STM32 example NUCLEO-L552ZE-Q/Examples/GTZC/GTZC_TZSC_MPCBB_TrustZone with the small modification to enable TIM2 and put the ISR in secure context.
Put a break point in the main() in non-secure context and run to this point.
#0 HAL_TIM_IRQHandler (htim=0x3000002c <htim2>) at C:/Users/foo/STM32Cube/Repository/STM32Cube_FW_L5_V1.3.1/Drivers/STM32L5xx_HAL_Driver/Src/stm32l5xx_hal_tim.c:3756
#1 0x0c00079a in TIM2_IRQHandler () at C:/Users/foo/STM32Cube/Repository/STM32Cube_FW_L5_V1.3.1/Projects/NUCLEO-L552ZE-Q/Examples/GTZC/GTZC_TZSC_MPCBB_TrustZone/Secure/Src/stm32l5xx_it.c:270
#2 <signal handler called>
#3 Reset_Handler () at ../Application/Startup/startup_stm32l552zetxq.s:102
#4 0x0804026e in Reset_Handler () at ../Application/Startup/startup_stm32l552zetxq.s:99
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Running "info r" makes GDB assert on frame 3 and 4 in the list above. With the attached patch, the assert is not triggered, but I'm not sure if it's the correct fix for the issue.
In addition to the assert, I also see that there is a mismatch between the stack pointers.
For Cortex-M33 with trustzone, sp is an "alias" for one of msp or psp. msp is an "alias" for msp_s or msp_ns and psp is an "alias" for psp_s or psp_ns.
#2 <signal handler called>
r0 0x3000002c 805306412
r1 0x70 112
r2 0x200180a8 536969384
r3 0x0 0
r4 0x8040238 134480440
r5 0x8040238 134480440
r6 0x8040238 134480440
r7 0x2002fff8 537067512
r8 0x8040238 134480440
r9 0x8040238 134480440
r10 0x8040238 134480440
r11 0x8040238 134480440
r12 0x8040238 134480440
sp 0x30017f30 0x30017f30
lr 0xffffffb9 -71
pc 0xffffffb9 0xffffffb9
xpsr 0x8900003d -1996488643
fpscr 0x0 0
msp 0x30017f18 0x30017f18
psp 0x0 0x0
msp_ns 0x2002ffd8 0x2002ffd8
psp_ns 0xfffffffc 0xfffffffc
msp_s 0x30017f18 0x30017f18
psp_s 0x0 0x0
primask 0x0 0
basepri 0x0 0
faultmask 0x0 0
control 0x0 0
msplim_s 0x0 0x0
psplim_s 0x0 0x0
msplim_ns 0x0 0x0
psplim_ns 0x0 0x0
primask_s 0x0 0
basepri_s 0x0 0
faultmask_s 0x0 0
control_s 0x0 0
primask_ns 0x0 0
basepri_ns 0x0 0
faultmask_ns 0x0 0
control_ns 0x0 0
As can be seen here, something has "updated" the sp to 0x30017f30, but that update should also be applied to msp and msp_s as they should be in sync in this case.
In addition, not sure if it's related or not, the main() frame for the non-secure context is missing from the bt above.
Could you please post this to the gdb-patches@ mailing list? Have you done some testing on it?
On hold waiting for reproduction on a STM32.
Hi Torbjörn. Have we addressed this with one of the recent patches?
(In reply to Luis Machado from comment #3)
> Hi Torbjörn. Have we addressed this with one of the recent patches?
Yes, that's one of the tickets. There are a few more and I will try to collect them all in a list to you within the next few days.
If this particular one is fixed, then it should be OK to close it as so.
Should this be closed?
I think it should be working now.
There are still situations where GDB may have too little info to do proper unwinding. Unfortunately, I have not had time over the past few months to try to figure out if something can be done to improve these situations.
Thanks. I'll close this one for now. We can always open a new one to address whatever shortcomings we run into.