-
-
Notifications
You must be signed in to change notification settings - Fork 883
Description
When debugging a LDR
/STR
instructions relative to pc
while the pc
is misaligned (found with a +2 misalignment), mGBA does the same thing as a real console. However, the debugger disassembly can lead to a misunderstanding of what's going to happen.
Build Information
- Tested on Windows and Linux
mGBA-0.10.4-7982-6c2da7b
(tag 0.10.4, Qt version) - Tested building master branch on Linux (
mGBA-0.11-8854-cef7dde50
, Qt version) - I don't want to be too specific about my specs and I think this should be enough for this issue.
Note
I usually run version 0.10.4 of mGBA at the moment, but I've checked that neither branch master nor tag 0.10.5 (latest release at the moment if I'm not wrong) haven't changed the code that I think it's involved in this issue.
Reproduction Steps
Note
This issue has been found executing code with a misaligned pc, but I don't know how to make this state easy to reproduce.
- Find or write a code that executes
LDR <Rd>, [pc, #<offset>]
(ARM mode) where<offset> % 4 = 2
(0x02
,0x06
,0x0A
...), - Find or write recognizable data in the target word (let's call it word1) of that
LDR
(for offset0x02
, 2 words after theLDR
; for offset0x06
, 3 words...) and one word after it (let's call this one word2). word2 is important because, when theLDR
is executed with a pc misaligned by 2, it should read this word. - Open the debugger.
- Set a breakpoint at the
LDR
address + 2. - Get to a point where that instruction is executed with a pc that's misaligned by 2 (ARM mode). The debugger should say that the execution has hit the breakpoint.
- In the current state of mGBA, the debugger shows that it would load data from the address of word1 + 2. Also, the data that it displays is a 16 bit rotation of word1.
- Advance to the next instruction. In fact, it loads word2. This is what I've seen happening on console and it is what mGBA does, so the problem should be in the debugger.
Example
I found this issue testing codes for ACE in Pokémon Emerald (where we execute code with a misaligned pc), so I wrote a code that I could use to test the real behavior on console. With this code, I was able to confirm that mGBA has the same behavior as a real console, but the debugger is displaying incoherent information about it.
Source code
.arm
LDR r12, [pc, #0x02] // Opcode 0xE59FC002
STR r12, [pc, #0x02] // Opcode 0xE58FC002
.4byte 0x000000FF
.4byte 0xBEBDBCBB
.4byte 0x0000FF00
.4byte 0xB0000000
.4byte 0x00FF0000
Debugger Output
Hit breakpoint 1 at 0x02071B66
r0: 0202080C r1: 0206FEFE r2: 00000000 r3: 00000002
r4: 0202080C r5: 0202084A r6: 00000007 r7: 00000001
r8: 00000000 r9: 00000000 r10: 00000000 r11: 00000000
r12: 00010100 r13: 03007E04 r14: 080069E7 r15: 02071B6A
cpsr: 0000001F [-------]
Cycle: 5558073930
02071B66: E59FC002 ldr r12, =0x00FF0000 @ 0x02071B6E
> n
r0: 0202080C r1: 0206FEFE r2: 00000000 r3: 00000002
r4: 0202080C r5: 0202084A r6: 00000007 r7: 00000001
r8: 00000000 r9: 00000000 r10: 00000000 r11: 00000000
r12: BEBDBCBB r13: 03007E04 r14: 080069E7 r15: 02071B6E
cpsr: 0000001F [-------]
Cycle: 5558073943
02071B6A: E58FC002 str r12, [0x02071B72]
r0: 0202080C r1: 0206FEFE r2: 00000000 r3: 00000002
r4: 0202080C r5: 0202084A r6: 00000007 r7: 00000001
r8: 00000000 r9: 00000000 r10: 00000000 r11: 00000000
r12: BEBDBCBB r13: 03007E04 r14: 080069E7 r15: 02071B72
cpsr: 0000001F [-------]
Cycle: 5558073955
02071B6E: 000000FF illeq
r0: 0202080C r1: 0206FEFE r2: 00000000 r3: 00000002
r4: 0202080C r5: 0202084A r6: 00000007 r7: 00000001
r8: 00000000 r9: 00000000 r10: 00000000 r11: 00000000
r12: BEBDBCBB r13: 03007E04 r14: 080069E7 r15: 02071B76
cpsr: 0000001F [-------]
Cycle: 5558073961
02071B72: BEBDBCBB illlt
r0: 0202080C r1: 0206FEFE r2: 00000000 r3: 00000002
r4: 0202080C r5: 0202084A r6: 00000007 r7: 00000001
r8: 00000000 r9: 00000000 r10: 00000000 r11: 00000000
r12: BEBDBCBB r13: 03007E04 r14: 080069E7 r15: 02071B7A
cpsr: 0000001F [-------]
Cycle: 5558073967
02071B76: BEBDBCBB illlt
Memory
Memory from 0x02071B60
to 0x02071B7F
before execution:
00 00 00 00 02 C0 9F E5 02 C0 8F E5 FF 00 00 00
BB BC BD BE 00 FF 00 00 00 00 00 B0 00 00 FF 00
Memory from 0x02071B60
to 0x02071B7F
after execution:
00 00 00 00 02 C0 9F E5 02 C0 8F E5 FF 00 00 00
BB BC BD BE BB BC BD BE 00 00 00 B0 00 00 FF 00
Again, this has the same result on a real console
Suggested Fix
Warning
This change is really focused on this issue. I don't think it's going to cause any problems, but I'm not familiar with this codebase, so there should be some testing behind it to make sure it's not breaking anything.
It could try to adjust addrBase
with the pc misalignment. I think addrBase
is only used for the disassembly of LDR
/STR
instructions relative to pc inside the debugger, so the general mGBA behavior shouldn't be affected.