I am using a Segger J-Link Base with gdb on Linux to debug an Atmel SAM4S8C MCU. I have the following in a gdb command file that I specify with the --command
argument when starting gdb:
target remote localhost:2331
monitor flash device SAM4S8C
I also specify my ELF file and load
the program in the command file.
I have noticed that when I load my program (using load
) the stack pointer is not getting set correctly. monitor reset
also does not modify the stack pointer.
The J-Link User Guide says (for Cortex-M3 devices):
Moreover, the user have to correct the Stack pointer (R13) and the PC (R15) manually, after reset in order to debug the application.
What is the command to do this from gdb?
It's strange that I should have to do this manually. The stack pointer is the first entry of the reset vector. As I develop my code, the initial stack pointer changes (particularly switching between applications that have very different initial stack pointers, which is how I first noticed this).
Is there a way to get gdb to read this from the ELF file during load
and automatically set it?
Cortex-M were designed so that no assembly startup code would be required:
At startup, Cortex-M will automaticaly load sp and pc registers from the two first 32-bits words of flash.
In the case of my LPC1788, that means I need to load r13/sp with the content of 0x00000000, and r15/pc with the content of 0x00000004:
target remote localhost:2331
monitor interface SWD
monitor endian little
monitor speed auto
monitor reset
monitor halt
monitor flash device = LPC1788
monitor flash download = 1
monitor flash breakpoints = 1
file program.elf
load program.elf
break main
monitor reg r13 = (0x00000000)
monitor reg r15 = (0x00000004)
continue
I had this issue as my product used a bootloader located at the start of flash which I wanted to skip while debugging. Since the stack pointer value should be stored as the first word in your executable and the reset vector as the next, you need something like:
$sp = {int} program_start_address
$pc = {int} program_start_address + 4
e.g. for a binary that starts at 0x08001000
$sp = {int} 0x08001000
$pc = {int} 0x08001004
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With