Fix breakpoints, implement step
This commit is contained in:
parent
062ea1c19a
commit
62722d28f7
|
@ -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
10
main.c
|
@ -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;
|
||||
|
|
37
server.c
37
server.c
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue