Reputation: 1002
I'm trying to construct a call stack on a Cortex-M3 processor (ARMv7-M architecture), no OS (bare metal). However, there is no frame pointer register for this ABI. Therefore I'm struggling to generate the call stack when I have no frame pointer.
Regardless of using -mapcs-frame
, -fno-omit-frame-pointer
and -O0
options with GCC, no frame pointer is kept. I'm wondering if there's a different ABI I can force GCC to use so I have a frame pointer/stack frame? If not, is there some other reliable method of generating a call stack?
Thanks in advance.
Upvotes: 5
Views: 7702
Reputation: 209
BTW wrt the comment above, the ARM calling standard is the same as Thumb, see (AAPCS Arm calling standard) The instruction sets are different BUT the CPU register set is not.
I would prefer to ask questions in the comments, but as yet I do not have enough points. With that in mind....
Do you have a binary successfully built and execution, but you are trying to dump some kind of call trace? My confusion is the 'no frame pointer register' statement - r13 is the stack frame pointer. I think you are referring to storing the frame pointer though.
It has been a while but I think these are the options I used
arm-none-eabi-gcc - -nostdlib -ggdb -mthumb -mcpu=cortex-m3 -mtpcs-frame -mtpcs-leaf-frame myfile.c
This was on gcc-arm-none downloaded from linaro. gdb was able to do a backtrace with those options on an Atmel SAM3X. The Thumb ABI was the same as the ARM EABI, or at least appears to be looking at the assembler via objdump -D .
The previous frame pointer gets stored in r7 when -fno-omit-frame-pointer is specified (or implied)
void test2(int i) {}
void main() { test(0);
Compiled with -fomit-frame-pointer
00008000 <test2>:
8000: b082 sub sp, #8
8002: 9001 str r0, [sp, #4]
8004: b002 add sp, #8
8006: 4770 bx lr
00008008 <main>:
8008: b508 push {r3, lr}
800a: f04f 0000 mov.w r0, #0
800e: f7ff fff7 bl 8000 <test2>
8012: bd08 pop {r3, pc}
Compiled with -fno-omit-frame-pointer
00008000 <test2>:
8000: b480 push {r7}
8002: b083 sub sp, #12
8004: af00 add r7, sp, #0
8006: 6078 str r0, [r7, #4]
8008: f107 070c add.w r7, r7, #12
800c: 46bd mov sp, r7
800e: bc80 pop {r7}
8010: 4770 bx lr
8012: bf00 nop
00008014 <main>:
8014: b580 push {r7, lr}
8016: af00 add r7, sp, #0
8018: f04f 0000 mov.w r0, #0
801c: f7ff fff0 bl 8000 <test2>
8020: bd80 pop {r7, pc}
8022: bf00 nop
So use r7 to get to the previous stack frame, then get the next r7 from that location and so on.
Upvotes: 2