Debugger: Correct PC value when read with 'p' instead of 'g' packet

The 'g' packet is handled by _readGPRs which has a special case for
the PC due to the way the CPU reports the PC value.

This was added by added by a967f9aac4.

The 'p' packet is handled by _readRegister which did not have this
special case for PC. This lead to GDB reporting the correct PC value
but LLDB not, as the latter used 'p' instead.

This meant you saw things like this:
    0x80002a4 <+16>: str    r0, [sp, #0x4]
    0x80002a8 <+20>: bl     0x80001f0      <----------expected to be here.
->  0x80002ac <+24>: b      0x80002b0

Where you expected to be about to bl to another function,
but it looked like you had already done it.

And more obviously, when you first attached to the GDB stub,
the PC was reported as 4 not 0.
This commit is contained in:
David Spickett 2023-09-22 16:26:32 +01:00 committed by Vicki Pfau
parent d2205d3475
commit 35cdd5d242
1 changed files with 8 additions and 2 deletions

View File

@ -354,6 +354,10 @@ static void _writeGPRs(struct GDBStub* stub, const char* message) {
_sendMessage(stub);
}
static int32_t _readPC(struct ARMCore* cpu) {
return cpu->gprs[ARM_PC] - (cpu->cpsr.t ? WORD_SIZE_THUMB : WORD_SIZE_ARM);
}
static void _readGPRs(struct GDBStub* stub, const char* message) {
struct ARMCore* cpu = stub->d.core->cpu;
UNUSED(message);
@ -367,7 +371,7 @@ static void _readGPRs(struct GDBStub* stub, const char* message) {
}
// Program counter
_int2hex32(cpu->gprs[ARM_PC] - (cpu->cpsr.t ? WORD_SIZE_THUMB : WORD_SIZE_ARM), &stub->outgoing[i]);
_int2hex32(_readPC(cpu), &stub->outgoing[i]);
i += 8;
// CPU status
@ -417,8 +421,10 @@ static void _readRegister(struct GDBStub* stub, const char* message) {
unsigned i = 0;
uint32_t reg = _readHex(readAddress, &i);
uint32_t value;
if (reg < 0x10) {
if (reg < ARM_PC) {
value = cpu->gprs[reg];
} else if (reg == ARM_PC) {
value = _readPC(cpu);
} else if (reg == 0x19) {
value = cpu->cpsr.packed;
} else {