I'm experimenting with the idea of having self-modifying or dynamically loaded code in my ESP-IDF project and have encountered some behavior I can’t explain.
I have a regular ESP-IDF project compiled and running on an ESP32-C3.
After flashing the normal firmware, I modify the firmware image in flash by adding an additional code segment that should be loaded at 0x50001000.
After a reboot, the bootloader indeed detects and loads my new segment:
Code: Select all
I (222) esp_image: segment 6: paddr=002d89a0 vaddr=50001000 size=001e4h ( 484) loadHowever, when I try to execute it by jumping to 0x50001000, I get an Illegal Instruction exception:
Code: Select all
Guru Meditation Error: Core 0 panic'ed (Illegal instruction). Exception was unhandled.
Core 0 register dump:
MEPC : 0x50001000 RA : 0x42088722 SP : 0x3fca2d40 GP : 0x3fc8ca00
TP : 0x3fca3360 T0 : 0x42085e36 T1 : 0x40387f60 T2 : 0xffffffff
S0/FP : 0x00000004 S1 : 0x50001000 A0 : 0x3fca5274 A1 : 0x3fca52b0
A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00000002 A5 : 0x3fcb6b5c
A6 : 0x3fcc5574 A7 : 0x3fca2c24 S2 : 0x3fcabeec S3 : 0x00000000
S4 : 0x00000001 S5 : 0x00000016 S6 : 0x00000d79 S7 : 0x00000001
S8 : 0x00000001 S9 : 0x00000d79 S10 : 0x00000d79 S11 : 0x3c1df000
T3 : 0xffffffff T4 : 0x00000000 T5 : 0x0ccccccc T6 : 0x00000019
MSTATUS : 0x00001881 MTVEC : 0x40380001 MCAUSE : 0x00000002 MTVAL : 0x00000000
MHARTID : 0x00000000
If I connect GDB via OpenOCD (USB/JTAG) and then perform the exact same jump to 0x50001000, the code executes perfectly—no exception, no issue. This happens without any breakpoints or stepping; just having GDB attached makes it work.
This behavior is fully reproducible:
Without GDB → Illegal Instruction
With GDB attached → works flawlessly
Does anyone have an idea why executing from 0x50001000 only works when GDB is connected?
Any insights or pointers would be greatly appreciated.