Fix breakpoints, implement step
This commit is contained in:
		
							parent
							
								
									062ea1c19a
								
							
						
					
					
						commit
						62722d28f7
					
				| 
						 | 
					@ -6,6 +6,12 @@
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <vb.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 {
 | 
					typedef enum rdb_server_stop_reason_t {
 | 
				
			||||||
    /* not even stopped */
 | 
					    /* not even stopped */
 | 
				
			||||||
    stop_reason_none,
 | 
					    stop_reason_none,
 | 
				
			||||||
| 
						 | 
					@ -22,13 +28,14 @@ typedef enum rdb_server_stop_reason_t {
 | 
				
			||||||
#define RDB_SERVER_MAX_BREAKPOINTS 16
 | 
					#define RDB_SERVER_MAX_BREAKPOINTS 16
 | 
				
			||||||
typedef struct RdbServer {
 | 
					typedef struct RdbServer {
 | 
				
			||||||
    VB *sim;
 | 
					    VB *sim;
 | 
				
			||||||
    bool running;
 | 
					 | 
				
			||||||
    uint32_t brks[RDB_SERVER_MAX_BREAKPOINTS];
 | 
					    uint32_t brks[RDB_SERVER_MAX_BREAKPOINTS];
 | 
				
			||||||
    uint32_t brkslen;
 | 
					    uint32_t brkslen;
 | 
				
			||||||
 | 
					    rdb_server_state_t state;
 | 
				
			||||||
    rdb_server_stop_reason_t stopreason;
 | 
					    rdb_server_stop_reason_t stopreason;
 | 
				
			||||||
} RdbServer;
 | 
					} RdbServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void rdbServerInit(RdbServer *srv, VB *sim);
 | 
					void rdbServerInit(RdbServer *srv, VB *sim);
 | 
				
			||||||
 | 
					bool rdbServerIsRunning(RdbServer *srv);
 | 
				
			||||||
int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res);
 | 
					int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res);
 | 
				
			||||||
int rdbServerSendStopPacket(RdbServer *srv, 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");
 | 
					            printf("client has disconnected\n");
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        } else if (read_result == read_result_pending) {
 | 
					        } else if (read_result == read_result_pending) {
 | 
				
			||||||
            if (srv.running) {
 | 
					            if (rdbServerIsRunning(&srv)) {
 | 
				
			||||||
                cycles = MAX_STEP_CYCLES;
 | 
					                cycles = MAX_STEP_CYCLES;
 | 
				
			||||||
                brk = vbEmulate(sim, &cycles);
 | 
					                brk = vbEmulate(sim, &cycles);
 | 
				
			||||||
                if (brk) {
 | 
					                if (brk) {
 | 
				
			||||||
                    /* We stopped for some reason */ 
 | 
					                    /* We stopped for some reason */ 
 | 
				
			||||||
                    if (brk == -1) {
 | 
					                    if (brk == -1) {
 | 
				
			||||||
                        /* the reason was "opcode not implemented" */
 | 
					                        /* the reason was "opcode not implemented" */
 | 
				
			||||||
                        srv.running = false;
 | 
					                        srv.state = state_stopped;
 | 
				
			||||||
                        srv.stopreason = stop_reason_not_implemented;
 | 
					                        srv.stopreason = stop_reason_not_implemented;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    result = rdbServerSendStopPacket(&srv, &res);
 | 
					                    result = rdbServerSendStopPacket(&srv, &res);
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,7 @@ int server(int connfd, VB *sim) {
 | 
				
			||||||
            if (result != 0) {
 | 
					            if (result != 0) {
 | 
				
			||||||
                return result;
 | 
					                return result;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            rdbRequestSetBlocking(&req, !srv.running);
 | 
					            rdbRequestSetBlocking(&req, !rdbServerIsRunning(&srv));
 | 
				
			||||||
            rdbRequestReset(&req);
 | 
					            rdbRequestReset(&req);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,10 +140,6 @@ int main(int argc, char** argv) {
 | 
				
			||||||
    if (readROM(sim, argv[1])) {
 | 
					    if (readROM(sim, argv[1])) {
 | 
				
			||||||
        return 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) {
 | 
					    if (argc > 2) {
 | 
				
			||||||
        char *end;
 | 
					        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)sim;
 | 
				
			||||||
    (void)code;
 | 
					    (void)code;
 | 
				
			||||||
    (void)length;
 | 
					    (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) {
 | 
					    for (i = 0; i < srv->brkslen; ++i) {
 | 
				
			||||||
        if (srv->brks[i] == address) {
 | 
					        if (srv->brks[i] == address) {
 | 
				
			||||||
 | 
					            srv->state = state_stopped;
 | 
				
			||||||
            srv->stopreason = stop_reason_breakpoint;
 | 
					            srv->stopreason = stop_reason_breakpoint;
 | 
				
			||||||
            return 1;
 | 
					            return 1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -115,8 +129,8 @@ static void removeBreakpoint(RdbServer *srv, uint32_t address) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void rdbServerInit(RdbServer *srv, VB *sim) {
 | 
					void rdbServerInit(RdbServer *srv, VB *sim) {
 | 
				
			||||||
    srv->sim = sim;
 | 
					    srv->sim = sim;
 | 
				
			||||||
    srv->running = false;
 | 
					 | 
				
			||||||
    srv->brkslen = 0;
 | 
					    srv->brkslen = 0;
 | 
				
			||||||
 | 
					    srv->state = state_stopped;
 | 
				
			||||||
    srv->stopreason = stop_reason_none;
 | 
					    srv->stopreason = stop_reason_none;
 | 
				
			||||||
    vbSetUserData(sim, srv);
 | 
					    vbSetUserData(sim, srv);
 | 
				
			||||||
    vbSetExecuteCallback(sim, onExecute);
 | 
					    vbSetExecuteCallback(sim, onExecute);
 | 
				
			||||||
| 
						 | 
					@ -134,7 +148,7 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (cmdMatchStr(cmd, "qSupported")) {
 | 
					    if (cmdMatchStr(cmd, "qSupported")) {
 | 
				
			||||||
        /* The debugger is asking for a list of features we support. */
 | 
					        /* 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);
 | 
					        return rdbResponseSendPacket(res);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (cmdMatchStr(cmd, "QThreadSuffixSupported")) {
 | 
					    if (cmdMatchStr(cmd, "QThreadSuffixSupported")) {
 | 
				
			||||||
| 
						 | 
					@ -187,6 +201,11 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
 | 
				
			||||||
        rdbResponseWriteStr(res, "c;C;s;S");
 | 
					        rdbResponseWriteStr(res, "c;C;s;S");
 | 
				
			||||||
        return rdbResponseSendPacket(res);
 | 
					        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")) {
 | 
					    if (cmdMatchStr(cmd, "qC")) {
 | 
				
			||||||
        /* The debugger is asking for the current thread id. Return "thread 1". */
 | 
					        /* The debugger is asking for the current thread id. Return "thread 1". */
 | 
				
			||||||
        rdbResponseWriteStr(res, "QCp1.t1");
 | 
					        rdbResponseWriteStr(res, "QCp1.t1");
 | 
				
			||||||
| 
						 | 
					@ -246,13 +265,13 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
 | 
				
			||||||
    if (cmdMatchStr(cmd, "c")) {
 | 
					    if (cmdMatchStr(cmd, "c")) {
 | 
				
			||||||
        /* The debugger has told us to run until we are stopped. */
 | 
					        /* 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). */
 | 
					        /* 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;
 | 
					        srv->stopreason = stop_reason_none;
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (cmdMatchStr(cmd, "\x03")) {
 | 
					    if (cmdMatchStr(cmd, "\x03")) {
 | 
				
			||||||
        /* Received an ETX, indicating that the server wants to cancel the "c" command from before. */
 | 
					        /* 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;
 | 
					        srv->stopreason = stop_reason_trap;
 | 
				
			||||||
        /* Send the response to the "c" command from before. */
 | 
					        /* Send the response to the "c" command from before. */
 | 
				
			||||||
        return rdbServerSendStopPacket(srv, res);
 | 
					        return rdbServerSendStopPacket(srv, res);
 | 
				
			||||||
| 
						 | 
					@ -265,7 +284,10 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
 | 
				
			||||||
        /* read memory */
 | 
					        /* read memory */
 | 
				
			||||||
        uint32_t i, address, len;
 | 
					        uint32_t i, address, len;
 | 
				
			||||||
        if (!cmdMatchHexNumber(cmd, &address)) return -1;
 | 
					        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;
 | 
					        if (!cmdMatchHexNumber(cmd, &len)) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i = 0; i < len; ++i) {
 | 
					        for (i = 0; i < len; ++i) {
 | 
				
			||||||
| 
						 | 
					@ -314,6 +336,11 @@ int rdbServerHandleCommand(RdbServer *srv, CommandBuf *cmd, RdbResponse *res) {
 | 
				
			||||||
    return rdbResponseSendPacket(res);
 | 
					    return rdbResponseSendPacket(res);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool rdbServerIsRunning(RdbServer *srv) {
 | 
				
			||||||
 | 
					    /* stepping counts */
 | 
				
			||||||
 | 
					    return srv->state != state_stopped;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rdbServerSendStopPacket(RdbServer *srv, RdbResponse *res) {
 | 
					int rdbServerSendStopPacket(RdbServer *srv, RdbResponse *res) {
 | 
				
			||||||
    rdbResponseBeginPacket(res);
 | 
					    rdbResponseBeginPacket(res);
 | 
				
			||||||
    switch (srv->stopreason) {
 | 
					    switch (srv->stopreason) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue