Software interrupt exception or undefined instruction exception?

arm, bare-metal, gdb, jtag

Solution

This is a community wiki answer.

The issue was caused by two different problems:

- The wrong vector table was being initialized. The ARM has selectable high and low vectors and high `0xffff0000` was the default, whereas the code was initialized as if the vector table was at `0x00000000`. The high vector table contained the following instructions (infinite loops on exceptions):

0xffff0000: b 0xffff0020 
0xffff0004: b 0xffff0004 
0xffff0008: b 0xffff0008 
0xffff000c: b 0xffff000c 
0xffff0010: b 0xffff0010 
0xffff0014: b 0xffff0014 
0xffff0018: b 0xffff0018 
0xffff001c: b 0xffff001c

- The SDRAM issues on the board caused the program content in RAM to be corrupted and to generate undefined exceptions. Following that the program stopped responding as it was in an infinite loop and the OP stopped gdb. The JTAG debugger used (peedi) actually jumps to the next instruction when gdb is stopped with `ctrl+C`, that's why the `pc` was `0xffff0008` even though the `cpsr` indicated an undefined exception situated at `0xffff0004`.

Problem

I am running a program on a bare-metal ARM (v5TE-compliant) with a JTAG connector and gdb. The program runs from some SDRAM in supervisor mode, and uses only arm instructions. At some point an exception occurs. Stopping gdb with ctrl+C I can see that the CPSR indicates an undefined exception mode, however the program counter indicates a software interrupt exception (`0xffff0008`). According to the ARM ARM, when an undefined instruction exception occurs, the `PC_und` should be `0xffff0004` or `0x00000004`. What's happening to my program, did a SWI happen or an undefined instruction exception? edit to make my question clearer: My program purpose is to test the hardware of the custom board. When there is a hardware problem, there can be a corruption from the program in RAM (as can be seen below) which is the cause of the exception generated. When the hardware is normal the test software runs without problem. My RAM addresses range from 0 to 0x40000000, the program is loaded between 0x1000 and 0x2000. The supervisor mode stack pointer is set to 0xff0. The interruption vector consists only of breakpoints. ``` (gdb) c Continuing. ^C^C Program received signal SIGTRAP, Trace/breakpoint trap. 0xffff0008 in ?? () ``` Registers from the undefined exception mode: ``` (gdb) i r r0 0x52878 338040 r1 0x2020000 33685504 r2 0x2020000 33685504 r3 0x2020000 33685504 r4 0x2020000 33685504 r5 0x2020000 33685504 r6 0x2020000 33685504 r7 0x2020000 33685504 r8 0x2020000 33685504 r9 0x2020000 33685504 r10 0x2020000 33685504 r11 0x2020000 33685504 r12 0x2020000 33685504 sp 0x2020000 0x2020000 lr 0xffff0008 4294901768 pc 0xffff0008 0xffff0008 fps 0x0 0 cpsr 0x800000db 2147483867 ``` Registers from the supervisor mode: ``` (gdb) set $cpsr=0xd3 (gdb) i r r0 0x52878 338040 r1 0x2020000 33685504 r2 0x2020000 33685504 r3 0x2020000 33685504 r4 0x2020000 33685504 r5 0x2020000 33685504 r6 0x2020000 33685504 r7 0x2020000 33685504 r8 0x2020000 33685504 r9 0x2020000 33685504 r10 0x2020000 33685504 r11 0x2020000 33685504 r12 0x2020000 33685504 sp 0xff3ffffe 0xff3ffffe lr 0x1020 4128 pc 0xffff0008 0xffff0008 fps 0x0 0 cpsr 0xd3 211 ``` Here is the (corrupted)program in RAM around the address pointed by the supervisor link register: ``` (gdb) x/5i 0x1020-8 0x1018 <_start+24>: bic r0, r0, #135168 ; 0x21000 0x101c <_start+28>: strbcs r0, [r0], #1025 0x1020 <_start+32>: mcr 15, 0, r0, cr1, cr0, {0} 0x1024 <_start+36>: ldr r1, [pc, #120] ; 0x10a4 <skip_intreg_reset+100> 0x1028 <_start+40>: ldr r2, [r1, #8] (gdb) x/4w 0x1018 0x1018 <_start+24>: 0xe3c00a01 0x101C <_start+28>: 0xfec00401 0x1020 <_start+32>: 0xee010f10 0x1024 <_start+36>: 0xe59f1078 ``` dump from the program object file: ``` 18: e3c00a01 bic r0, r0, #4096 ; 0x1000 1c: e3c00001 bic r0, r0, #1 ; 0x1 20: ee010f10 mcr 15, 0, r0, cr1, cr0, {0} 24: e59f1078 ldr r1, [pc, #120] ; a4 <skip_intreg_reset+0x64> 28: e5912000 ldr r2, [r1] ```

Original source