Domanda

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]
È stato utile?

Soluzione

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.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top