Bug 87400 - GCC doesn't produce valid frames for stack traces with Thumb-2 (Cortex-M3+)
Summary: GCC doesn't produce valid frames for stack traces with Thumb-2 (Cortex-M3+)
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 7.3.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-09-24 08:05 UTC by Alex Kalmuk
Modified: 2018-09-24 10:19 UTC (History)
0 users

See Also:
Host:
Target: arm-none-eabi
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Kalmuk 2018-09-24 08:05:04 UTC
GCC generates special frames for doing stack traces on ARM. These frames can be generated for ARM instruction set using `-mapcs-frame`:

Example of the produced frame:
$ arm-none-eabi-gcc -marm -mcpu=arm926ej-s -march=armv5te -mapcs-frame --specs=nosys.specs -o test test.c

000081f8 <my_func>:
    81f8:   e1a0c00d    mov ip, sp
    81fc:   e92dd800    push    {fp, ip, lr, pc}

This type of prologue can be also generated for Cortex-M (thumb instruction set) using `-mthumb -mcpu=cortex-m1 -mtpcs-frame -mtpcs-leaf-frame`:

$ arm-none-eabi-gcc -mthumb -mcpu=cortex-m1 -mtpcs-frame -mtpcs-leaf-frame --specs=nosys.specs -o test test.c

In that case function prologue will look like:
00008104 <my_func>:
    8104:   b084        sub sp, #16
    8106:   b580        push    {r7, lr}
    8108:   aa06        add r2, sp, #24
    810a:   9203        str r2, [sp, #12]
    810c:   467a        mov r2, pc
    810e:   9205        str r2, [sp, #20]
    8110:   465a        mov r2, fp
    8112:   9202        str r2, [sp, #8]

It's the same thing like for ARM instruction set, but since Thumb doesn't allow to push high registers, GCC produces it through mov/str instructions.

But in case of `-mcpu=cortex-m3` (instead of `-mcpu=cortex-m1`), we do not get such prologue. After investigating gcc/config/arm/arm.c, I figured out that these prologues are generated only for Thumb-1 (Cortex-M0/M1) and ARM instruction sets, but ingnored for Thumb-2 (Cortex-M3+). It is a bug, or there is some reason do not generate these prologues for Thumb-2?
Comment 1 Richard Earnshaw 2018-09-24 09:13:54 UTC
-mapcs-frame predates the Thumb ISA.  It does not and cannot support it.  Furthermore, -mapcs-frame is deprecated even for Arm state.
Comment 2 Alex Kalmuk 2018-09-24 09:23:38 UTC
I write about mtpcs-frame for thumb, not mapcs-frame, I know the last one for arm instruction set.
Comment 3 Richard Earnshaw 2018-09-24 09:38:26 UTC
(In reply to Alex Kalmuk from comment #2)
> I write about mtpcs-frame for thumb, not mapcs-frame, I know the last one
> for arm instruction set.

The tpcs is also obsolete (the tpcs was replaced by the atpcs more than 20 years ago); the atpcs was superseded by the aapcs about 15 years ago now.

I'm not sure why the tpcs-frame and tpcs-leaf-frame flags weren't removed from the compiler; they certainly doesn't do anything useful now.

Unfortunately, the aapcs does not define a frame pointer or mandate a frame layout, which makes backtracing through a frame impossible.  Any frame pointer used by the compiler can only be used within that frame.
Comment 4 Alex Kalmuk 2018-09-24 10:19:52 UTC
Thank you for pointing it out.

So now the alternative is to use .ARM.exidx linker section even for Cortex-M (or, probably, to use dwarf debugging information on gdb side)?