Fix breakpoints, implement step

This commit is contained in:
Simon Gellis 2024-10-12 01:06:10 -04:00
parent 062ea1c19a
commit 62722d28f7
3 changed files with 43 additions and 13 deletions

View File

@ -6,6 +6,12 @@
#include <stdbool.h>
#include <vb.h>
typedef enum rdb_server_state_t {
state_stopped,
state_running,
state_stepping
} rdb_server_state_t;
typedef enum rdb_server_stop_reason_t {
/* not even stopped */
stop_reason_none,
@ -22,13 +28,14 @@ typedef enum rdb_server_stop_reason_t {
#define RDB_SERVER_MAX_BREAKPOINTS 16
typedef struct RdbServer {
VB *sim;
bool running;
uint32_t brks[RDB_SERVER_MAX_BREAKPOINTS];
uint32_t brkslen;
rdb_server_state_t state;
rdb_server_stop_reason_t stopreason;
} RdbServer;
void rdbServerInit(RdbServer *srv, VB *sim);
bool rdbServerIsRunning(RdbServer *srv);
int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res);
int rdbServerSendStopPacket(RdbServer *srv, RdbResponse *res);

10
main.c
View File

@ -44,14 +44,14 @@ int server(int connfd, VB *sim) {
printf("client has disconnected\n");
return 0;
} else if (read_result == read_result_pending) {
if (srv.running) {
if (rdbServerIsRunning(&srv)) {
cycles = MAX_STEP_CYCLES;
brk = vbEmulate(sim, &cycles);
if (brk) {
/* We stopped for some reason */
if (brk == -1) {
/* the reason was "opcode not implemented" */
srv.running = false;
srv.state = state_stopped;
srv.stopreason = stop_reason_not_implemented;
}
result = rdbServerSendStopPacket(&srv, &res);
@ -70,7 +70,7 @@ int server(int connfd, VB *sim) {
if (result != 0) {
return result;
}
rdbRequestSetBlocking(&req, !srv.running);
rdbRequestSetBlocking(&req, !rdbServerIsRunning(&srv));
rdbRequestReset(&req);
}
@ -140,10 +140,6 @@ int main(int argc, char** argv) {
if (readROM(sim, argv[1])) {
return 1;
}
/* relevant state at the start of the physics sim's main */
vbSetProgramCounter(sim, 0x070002ba);
vbSetProgramRegister(sim, 3, 0x0500ffc0);
vbSetProgramRegister(sim, 4, 0x05008000);
if (argc > 2) {
char *end;

View File

@ -76,8 +76,22 @@ static int onExecute(VB *sim, uint32_t address, const uint16_t *code, int length
(void)sim;
(void)code;
(void)length;
/* if we're stopped, just stop */
if (srv->state == state_stopped) {
return 1;
}
/* if we're stepping, we'll run this one instruction but no others */
if (srv->state == state_stepping) {
srv->state = state_stopped;
srv->stopreason = stop_reason_trace;
return 0;
}
for (i = 0; i < srv->brkslen; ++i) {
if (srv->brks[i] == address) {
srv->state = state_stopped;
srv->stopreason = stop_reason_breakpoint;
return 1;
}
@ -115,8 +129,8 @@ static void removeBreakpoint(RdbServer *srv, uint32_t address) {
void rdbServerInit(RdbServer *srv, VB *sim) {
srv->sim = sim;
srv->running = false;
srv->brkslen = 0;
srv->state = state_stopped;
srv->stopreason = stop_reason_none;
vbSetUserData(sim, srv);
vbSetExecuteCallback(sim, onExecute);
@ -134,7 +148,7 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
}
if (cmdMatchStr(cmd, "qSupported")) {
/* The debugger is asking for a list of features we support. */
rdbResponseWriteStr(res, "no-resumed+;multiprocess;vContSupported;QNonStop+");
rdbResponseWriteStr(res, "no-resumed+;multiprocess;vContSupported");
return rdbResponseSendPacket(res);
}
if (cmdMatchStr(cmd, "QThreadSuffixSupported")) {
@ -187,6 +201,11 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
rdbResponseWriteStr(res, "c;C;s;S");
return rdbResponseSendPacket(res);
}
if (cmdMatchStr(cmd, "vCont;s:1")) {
/* The debugger wants us to step */
srv->state = state_stepping;
return 0;
}
if (cmdMatchStr(cmd, "qC")) {
/* The debugger is asking for the current thread id. Return "thread 1". */
rdbResponseWriteStr(res, "QCp1.t1");
@ -246,13 +265,13 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
if (cmdMatchStr(cmd, "c")) {
/* The debugger has told us to run until we are stopped. */
/* Don't send a response to this until we receive an ETX (when the debugger pauses us). */
srv->running = true;
srv->state = state_running;
srv->stopreason = stop_reason_none;
return 0;
}
if (cmdMatchStr(cmd, "\x03")) {
/* Received an ETX, indicating that the server wants to cancel the "c" command from before. */
srv->running = false;
srv->state = state_stopped;
srv->stopreason = stop_reason_trap;
/* Send the response to the "c" command from before. */
return rdbServerSendStopPacket(srv, res);
@ -265,7 +284,10 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
/* read memory */
uint32_t i, address, len;
if (!cmdMatchHexNumber(cmd, &address)) return -1;
if (!cmdMatchStr(cmd, ",")) return -1;
if (!cmdMatchStr(cmd, ",")) {
/* if the server asks for too much memory, just error */
return rdbResponseSendPacket(res);
};
if (!cmdMatchHexNumber(cmd, &len)) return -1;
for (i = 0; i < len; ++i) {
@ -314,6 +336,11 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
return rdbResponseSendPacket(res);
}
bool rdbServerIsRunning(RdbServer *srv) {
/* stepping counts */
return srv->state != state_stopped;
}
int rdbServerSendStopPacket(RdbServer *srv, RdbResponse *res) {
rdbResponseBeginPacket(res);
switch (srv->stopreason) {