简体   繁体   中英

Program counter changes oddly without any instruction modifying it (qemu-arm, bare metal)

I'm currently trying to make a program i wrote run on a bare metal arm device. Since i'm not having the device (yet), i try to run the code on an arm emulation using qemu.

i run my code with this command: qemu-system-arm -M realview-pb-a8 -m 128M -nographic -s -S -kernel myprog .

The execution gets stuck at always the same point, even if i use other board setups. This is the place it gets stuck (some piece of openSSL code):

   0x398b4 <EVP_CipherInit_ex+884>         ldr    r3, [r11, #-24]
   0x398b8 <EVP_CipherInit_ex+888>         ldr    r3, [r3]
   0x398bc <EVP_CipherInit_ex+892>         ldr    r12, [r3, #20]
   0x398c0 <EVP_CipherInit_ex+896>         ldr    r0, [r11, #-24]
   0x398c4 <EVP_CipherInit_ex+900>         ldr    r1, [r11, #-36] ; 0x24  
   0x398c8 <EVP_CipherInit_ex+904>         ldr    r2, [r11, #4] 
   0x398cc <EVP_CipherInit_ex+908>         ldr    r3, [r11, #8]
   0x398d0 <EVP_CipherInit_ex+912>         mov    lr, pc
   0x398d4 <EVP_CipherInit_ex+916>         bx     r12
[..]
-> 0x391e4 <aes_init_key>          push   {r11, lr}  <- Strange thing happens at this instruction.
   0x391e8 <aes_init_key+4>        add    r11, sp, #4
   0x391ec <aes_init_key+8>        sub    sp, sp, #40     ; 0x28
   0x391f0 <aes_init_key+12>       str    r0, [r11, #-24]
   0x391f4 <aes_init_key+16>       str    r1, [r11, #-28]

Right after the instruction at 0x391e4 the $pc changes to 0x391e6 instead of 0x391e8. This is not a valid address, so it jumps right to the beginning of the file at execution. If i change the $pc to the correct value in debugger i reach 0x391e8 but the $pc is again set to a wrong value (0x391ea). I was not able to reproduce this behaviour with other code than mine.

Here is a dump of the main registers right before shit happens.

r0   0xe28db004 -494030844    r1   0x7aeb8  503480
r2      0x7aea8     503464    r3       0x1       1
r4      0x7df98     515992    r5   0x7dfa8  516008
r6          0x0          0    r7       0x0       0
r8          0x0          0    r9       0x0      0
r10     0x60000     393216    r11  0x7ae34  503348
r12     0x391e5     233957    sp   0x7ae08  0x7ae08 <__malloc_av_+252>
lr      0x398d8     235736    pc   0x391e6  0x391e6 <aes_init_key+2>
cpsr 0x200001f3  536871411

And here one right after:

r0   0xe28db004  -494030844   r1     0x7aeb8    503480
r2      0x7aea8      503464   r3         0x1         1
r4      0x7df98      515992   r5     0x7dfa8    516008
r6          0x0           0   r7         0x0         0
r8          0x0           0   r9         0x0         0 
r10     0x60000      393216   r11    0x7ae34    503348
r12     0x391e5      233957   sp     0x7e000   0x7e000
lr      0x391e8      233960   pc         0x8       0x8
cpsr 0x200001db   536871387

How can i resolve this issue? Could this be a compiler error?

I tried these compiler flags: -marm -mthumb-interwork

The 2 byte change sounds suspiciously like thumb mode and indeed your cpsr bit #5 is set. Either this is indeed thumb code, in which case you are disassembling it wrong, or it is arm code in which case it is called wrongfully in thumb mode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM