diff --git a/include/mgba/debugger/debugger.h b/include/mgba/debugger/debugger.h index 230a95564..d295f71e9 100644 --- a/include/mgba/debugger/debugger.h +++ b/include/mgba/debugger/debugger.h @@ -133,6 +133,7 @@ struct mBreakpoint { int segment; enum mBreakpointType type; struct ParseTree* condition; + bool isTemporary; }; struct mWatchpoint { diff --git a/src/arm/debugger/debugger.c b/src/arm/debugger/debugger.c index c9631e56b..7584d4082 100644 --- a/src/arm/debugger/debugger.c +++ b/src/arm/debugger/debugger.c @@ -218,6 +218,11 @@ static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform* d) { .target = TableLookup(&d->p->pointOwner, breakpoint->d.id) }; mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info); + if (breakpoint->d.isTemporary) { + _destroyBreakpoint(debugger->d.p, breakpoint); + ARMDebugBreakpointListShift(&debugger->breakpoints, i, 1); + --i; + } } } @@ -323,7 +328,10 @@ static void ARMDebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerE ARMRunFake(cpu, breakpoint->sw.opcode); - if (debugger->setSoftwareBreakpoint) { + if (breakpoint->d.isTemporary) { + _destroyBreakpoint(debugger->d.p, breakpoint); + ARMDebugBreakpointListShift(&debugger->swBreakpoints, i, 1); + } else if (debugger->setSoftwareBreakpoint) { debugger->setSoftwareBreakpoint(debugger, breakpoint->d.address, breakpoint->sw.mode, &breakpoint->sw.opcode); } break; diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c index 6d419ac95..1e1fd35a5 100644 --- a/src/debugger/gdb-stub.c +++ b/src/debugger/gdb-stub.c @@ -255,7 +255,25 @@ static void _continue(struct GDBStub* stub, const char* message) { } static void _step(struct GDBStub* stub, const char* message) { + const struct ARMCore* cpu = stub->d.p->core->cpu; + const int32_t pc = cpu->gprs[ARM_PC]; + stub->d.p->core->step(stub->d.p->core); + + if (pc >= GBA_SIZE_BIOS && cpu->gprs[ARM_PC] < GBA_SIZE_BIOS) { + // GDB cannot cope with jumps into BIOS + // skip over them by placing a temporary breakpoint at PC (instruction after the jump) + // and then continue without sending a GDB SIGTRAP + const struct mBreakpoint breakpoint = { + .address = pc, + .type = BREAKPOINT_HARDWARE, + .isTemporary = true + }; + stub->d.p->platform->setBreakpoint(stub->d.p->platform, &stub->d, &breakpoint); + _continue(stub, message); + return; + } + snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02x", SIGTRAP); _sendMessage(stub); // TODO: parse message diff --git a/src/platform/qt/ts/mgba-it.ts b/src/platform/qt/ts/mgba-it.ts index a2b83e6e4..28167d649 100644 --- a/src/platform/qt/ts/mgba-it.ts +++ b/src/platform/qt/ts/mgba-it.ts @@ -5417,7 +5417,7 @@ If it is set to OpenGL and you still see this, your graphics card or drivers may GBC compatible: - Compatibile BGC: + Compatibile GBC: diff --git a/src/sm83/debugger/debugger.c b/src/sm83/debugger/debugger.c index 4f90a5691..1d0265d50 100644 --- a/src/sm83/debugger/debugger.c +++ b/src/sm83/debugger/debugger.c @@ -53,6 +53,11 @@ static void SM83DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) { .target = TableLookup(&d->p->pointOwner, breakpoint->id) }; mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info); + if (breakpoint->isTemporary) { + _destroyBreakpoint(debugger->d.p, breakpoint); + mBreakpointListShift(&debugger->breakpoints, i, 1); + --i; + } } }