From 35cdd5d2429a267e72d92e623a3aaa97da941207 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Fri, 22 Sep 2023 16:26:32 +0100 Subject: [PATCH] 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 a967f9aac433c817fbca981c5e254e5107457f47. 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. --- src/debugger/gdb-stub.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c index 1e303d4a3..58d46b633 100644 --- a/src/debugger/gdb-stub.c +++ b/src/debugger/gdb-stub.c @@ -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 {