Compile against C90
This commit is contained in:
parent
8de384fa91
commit
02a7c9811c
3
cmdbuf.c
3
cmdbuf.c
|
@ -32,8 +32,9 @@ bool cmd_match_hex_number(CommandBuf *cmd, uint32_t *value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmd_match_hex_bytes(CommandBuf *cmd, const uint32_t count, uint8_t *value) {
|
bool cmd_match_hex_bytes(CommandBuf *cmd, const uint32_t count, uint8_t *value) {
|
||||||
|
size_t i;
|
||||||
if (cmd->len < (count * 2)) return false;
|
if (cmd->len < (count * 2)) return false;
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
char hi, lo;
|
char hi, lo;
|
||||||
if (!parse_hex_digit(cmd->buf[i * 2], &hi)) return false;
|
if (!parse_hex_digit(cmd->buf[i * 2], &hi)) return false;
|
||||||
if (!parse_hex_digit(cmd->buf[(i * 2) + 1], &lo)) return false;
|
if (!parse_hex_digit(cmd->buf[(i * 2) + 1], &lo)) return false;
|
||||||
|
|
|
@ -10,7 +10,7 @@ typedef enum rdb_read_result_t {
|
||||||
read_result_success,
|
read_result_success,
|
||||||
read_result_error,
|
read_result_error,
|
||||||
read_result_pending,
|
read_result_pending,
|
||||||
read_result_disconnected,
|
read_result_disconnected
|
||||||
} rdb_read_result_t;
|
} rdb_read_result_t;
|
||||||
|
|
||||||
typedef enum rdb_read_state_t {
|
typedef enum rdb_read_state_t {
|
||||||
|
@ -18,7 +18,7 @@ typedef enum rdb_read_state_t {
|
||||||
read_state_body,
|
read_state_body,
|
||||||
read_state_body_escape,
|
read_state_body_escape,
|
||||||
read_state_checksum_1,
|
read_state_checksum_1,
|
||||||
read_state_checksum_2,
|
read_state_checksum_2
|
||||||
} rdb_read_state_t;
|
} rdb_read_state_t;
|
||||||
|
|
||||||
typedef struct RdbRequest {
|
typedef struct RdbRequest {
|
||||||
|
|
39
main.c
39
main.c
|
@ -8,28 +8,31 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <vb.h>
|
#include <vb.h>
|
||||||
|
|
||||||
const size_t BUFLEN = 8096;
|
#define BUFLEN 8096
|
||||||
|
|
||||||
int server(int connfd, VB *sim) {
|
int server(int connfd, VB *sim) {
|
||||||
RdbRequest req;
|
RdbRequest req;
|
||||||
RdbResponse res;
|
RdbResponse res;
|
||||||
char reqbuf[BUFLEN];
|
char reqbuf[BUFLEN];
|
||||||
char resbuf[BUFLEN];
|
char resbuf[BUFLEN];
|
||||||
|
bool running;
|
||||||
|
rdb_read_result_t read_result;
|
||||||
|
int result;
|
||||||
|
|
||||||
rdb_request_init(&req, connfd, reqbuf, BUFLEN);
|
rdb_request_init(&req, connfd, reqbuf, BUFLEN);
|
||||||
rdb_response_init(&res, connfd, resbuf, BUFLEN);
|
rdb_response_init(&res, connfd, resbuf, BUFLEN);
|
||||||
|
|
||||||
bool running = false;
|
running = false;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
CommandBuf cmd;
|
CommandBuf cmd;
|
||||||
rdb_read_result_t result = rdb_request_read(&req, &cmd);
|
read_result = rdb_request_read(&req, &cmd);
|
||||||
if (result == read_result_error) {
|
if (read_result == read_result_error) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (result == read_result_disconnected) {
|
} else if (read_result == read_result_disconnected) {
|
||||||
printf("client has disconnected\n");
|
printf("client has disconnected\n");
|
||||||
return 0;
|
return 0;
|
||||||
} else if (result == read_result_pending) {
|
} else if (read_result == read_result_pending) {
|
||||||
if (running) {
|
if (running) {
|
||||||
printf("pretend the emulator is running now\n");
|
printf("pretend the emulator is running now\n");
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
@ -38,7 +41,7 @@ int server(int connfd, VB *sim) {
|
||||||
} else {
|
} else {
|
||||||
printf("received command \"%.*s\"\n", (int) cmd.len, cmd.buf);
|
printf("received command \"%.*s\"\n", (int) cmd.len, cmd.buf);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
int result = handle_command(&res, &cmd, sim, &running);
|
result = handle_command(&res, &cmd, sim, &running);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +54,7 @@ int server(int connfd, VB *sim) {
|
||||||
|
|
||||||
int readROM(VB *sim, char *filename) {
|
int readROM(VB *sim, char *filename) {
|
||||||
FILE *file = fopen(filename, "rb");
|
FILE *file = fopen(filename, "rb");
|
||||||
|
uint8_t *rom;
|
||||||
long size;
|
long size;
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
@ -72,7 +76,7 @@ int readROM(VB *sim, char *filename) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *rom = malloc(size);
|
rom = malloc(size);
|
||||||
if (!rom) {
|
if (!rom) {
|
||||||
perror("could not allocate ROM");
|
perror("could not allocate ROM");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -92,11 +96,18 @@ int readROM(VB *sim, char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
VB *sim;
|
||||||
|
short port;
|
||||||
|
int fd, connfd;
|
||||||
|
struct sockaddr_in addr, cliaddr;
|
||||||
|
socklen_t cliaddrlen;
|
||||||
|
int response;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "Please pass a ROM file\n");
|
fprintf(stderr, "Please pass a ROM file\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
VB *sim = malloc(vbSizeOf());
|
sim = malloc(vbSizeOf());
|
||||||
if (!sim) {
|
if (!sim) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +117,6 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
vbSetProgramCounter(sim, 0x07000000);
|
vbSetProgramCounter(sim, 0x07000000);
|
||||||
|
|
||||||
short port;
|
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
char *end;
|
char *end;
|
||||||
port = (short) strtol(argv[2], &end, 10);
|
port = (short) strtol(argv[2], &end, 10);
|
||||||
|
@ -118,13 +128,12 @@ int main(int argc, char** argv) {
|
||||||
port = 8080;
|
port = 8080;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("could not open socket");
|
perror("could not open socket");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addr.sin_addr.s_addr = INADDR_ANY;
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
|
@ -139,9 +148,7 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("connecting\n");
|
printf("connecting\n");
|
||||||
int connfd;
|
cliaddrlen = sizeof(cliaddr);
|
||||||
struct sockaddr_in cliaddr;
|
|
||||||
socklen_t cliaddrlen = sizeof(cliaddr);
|
|
||||||
connfd = accept(fd, (struct sockaddr *) &cliaddr, &cliaddrlen);
|
connfd = accept(fd, (struct sockaddr *) &cliaddr, &cliaddrlen);
|
||||||
if (connfd == -1) {
|
if (connfd == -1) {
|
||||||
perror("could not accept connection");
|
perror("could not accept connection");
|
||||||
|
@ -149,7 +156,7 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
printf("connected\n");
|
printf("connected\n");
|
||||||
|
|
||||||
int response = server(connfd, sim);
|
response = server(connfd, sim);
|
||||||
return close(connfd)
|
return close(connfd)
|
||||||
|| close(fd)
|
|| close(fd)
|
||||||
|| response;
|
|| response;
|
||||||
|
|
2
makefile
2
makefile
|
@ -2,7 +2,7 @@ build:
|
||||||
@mkdir -p build
|
@mkdir -p build
|
||||||
@gcc main.c cmdbuf.c hex.c request.c response.c server.c ../vbtest/vb.c \
|
@gcc main.c cmdbuf.c hex.c request.c response.c server.c ../vbtest/vb.c \
|
||||||
-I include -I ../vbtest \
|
-I include -I ../vbtest \
|
||||||
-Werror -Wall -Wextra -Wpedantic \
|
-Werror -std=c90 -Wall -Wextra -Wpedantic \
|
||||||
-Wno-unused-parameter -Wno-unused-function \
|
-Wno-unused-parameter -Wno-unused-function \
|
||||||
-o ./build/rdb
|
-o ./build/rdb
|
||||||
clean:
|
clean:
|
||||||
|
|
20
request.c
20
request.c
|
@ -47,14 +47,14 @@ static rdb_read_result_t read_char(RdbRequest *req, char *in) {
|
||||||
|
|
||||||
rdb_read_result_t rdb_request_read(RdbRequest *req, CommandBuf *cmd) {
|
rdb_read_result_t rdb_request_read(RdbRequest *req, CommandBuf *cmd) {
|
||||||
rdb_read_result_t res;
|
rdb_read_result_t res;
|
||||||
char in;
|
char in, hi, lo;
|
||||||
|
|
||||||
switch (req->state) {
|
switch (req->state) {
|
||||||
case read_state_header:
|
case read_state_header:
|
||||||
cmd->buf = req->outbuf;
|
cmd->buf = req->outbuf;
|
||||||
cmd->len = 0;
|
cmd->len = 0;
|
||||||
|
|
||||||
// read any acknowledgements and continue
|
/* read any acknowledgements and continue */
|
||||||
do {
|
do {
|
||||||
res = read_char(req, &in);
|
res = read_char(req, &in);
|
||||||
if (res != read_result_success) return res;
|
if (res != read_result_success) return res;
|
||||||
|
@ -66,13 +66,13 @@ rdb_read_result_t rdb_request_read(RdbRequest *req, CommandBuf *cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in == '\x03') {
|
if (in == '\x03') {
|
||||||
// interrupt from the server
|
/* interrupt from the server */
|
||||||
cmd->buf[0] = in;
|
cmd->buf[0] = in;
|
||||||
cmd->len = 1;
|
cmd->len = 1;
|
||||||
return read_result_success;
|
return read_result_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// now, we should be at the start of a packet
|
/* now, we should be at the start of a packet */
|
||||||
if (in != '$') {
|
if (in != '$') {
|
||||||
fprintf(stderr, "unexpected packet start \"%c\"\n", in);
|
fprintf(stderr, "unexpected packet start \"%c\"\n", in);
|
||||||
return read_result_error;
|
return read_result_error;
|
||||||
|
@ -87,20 +87,20 @@ rdb_read_result_t rdb_request_read(RdbRequest *req, CommandBuf *cmd) {
|
||||||
if (res != read_result_success) return res;
|
if (res != read_result_success) return res;
|
||||||
|
|
||||||
if (req->state == read_state_body && in == '#') {
|
if (req->state == read_state_body && in == '#') {
|
||||||
// end of packet body
|
/* end of packet body */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
req->chk += in;
|
req->chk += in;
|
||||||
|
|
||||||
if (req->state == read_state_body && in == '}') {
|
if (req->state == read_state_body && in == '}') {
|
||||||
// escape sequence
|
/* escape sequence */
|
||||||
req->state = read_state_body_escape;
|
req->state = read_state_body_escape;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->len >= req->outbuflen) {
|
if (cmd->len >= req->outbuflen) {
|
||||||
// ran out of room in the buffer
|
/* ran out of room in the buffer */
|
||||||
fprintf(stderr, "packet too big for buffer\n");
|
fprintf(stderr, "packet too big for buffer\n");
|
||||||
return read_result_error;
|
return read_result_error;
|
||||||
}
|
}
|
||||||
|
@ -118,8 +118,7 @@ rdb_read_result_t rdb_request_read(RdbRequest *req, CommandBuf *cmd) {
|
||||||
res = read_char(req, &in);
|
res = read_char(req, &in);
|
||||||
if (res != read_result_success) return res;
|
if (res != read_result_success) return res;
|
||||||
|
|
||||||
// check the high digit of the checksum
|
/* check the high digit of the checksum */
|
||||||
char hi;
|
|
||||||
if (!parse_hex_digit(in, &hi)) {
|
if (!parse_hex_digit(in, &hi)) {
|
||||||
fprintf(stderr, "invalid checksum1\n");
|
fprintf(stderr, "invalid checksum1\n");
|
||||||
return read_result_error;
|
return read_result_error;
|
||||||
|
@ -134,8 +133,7 @@ rdb_read_result_t rdb_request_read(RdbRequest *req, CommandBuf *cmd) {
|
||||||
res = read_char(req, &in);
|
res = read_char(req, &in);
|
||||||
if (res != read_result_success) return res;
|
if (res != read_result_success) return res;
|
||||||
|
|
||||||
// check the high digit of the checksum
|
/* check the high digit of the checksum */
|
||||||
char lo;
|
|
||||||
if (!parse_hex_digit(in, &lo)) {
|
if (!parse_hex_digit(in, &lo)) {
|
||||||
fprintf(stderr, "invalid checksum3 %c\n", in);
|
fprintf(stderr, "invalid checksum3 %c\n", in);
|
||||||
return read_result_error;
|
return read_result_error;
|
||||||
|
|
14
response.c
14
response.c
|
@ -58,8 +58,8 @@ void rdb_response_begin_packet(RdbResponse *res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rdb_response_write_str(RdbResponse *res, const char *str) {
|
bool rdb_response_write_str(RdbResponse *res, const char *str) {
|
||||||
size_t len = strlen(str);
|
size_t i, len = strlen(str);
|
||||||
for (size_t i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
if (!write_char(res, str[i])) {
|
if (!write_char(res, str[i])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,8 @@ bool rdb_response_write_str(RdbResponse *res, const char *str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rdb_response_write_str_hex(RdbResponse *res, const char *str) {
|
bool rdb_response_write_str_hex(RdbResponse *res, const char *str) {
|
||||||
size_t len = strlen(str);
|
size_t i, len = strlen(str);
|
||||||
for (size_t i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
char hi, lo;
|
char hi, lo;
|
||||||
if (!char_to_hex_digits(str[i], &hi, &lo)
|
if (!char_to_hex_digits(str[i], &hi, &lo)
|
||||||
|| !write_char(res, hi)
|
|| !write_char(res, hi)
|
||||||
|
@ -95,11 +95,13 @@ bool rdb_response_write_i32_hex(RdbResponse *res, uint32_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int rdb_response_send_packet(RdbResponse *res) {
|
int rdb_response_send_packet(RdbResponse *res) {
|
||||||
|
char hi, lo;
|
||||||
|
ssize_t rwrite;
|
||||||
|
|
||||||
if (res->len + 3 > res->buflen) {
|
if (res->len + 3 > res->buflen) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
res->buf[res->len++] = '#';
|
res->buf[res->len++] = '#';
|
||||||
char hi, lo;
|
|
||||||
if (!char_to_hex_digits(res->chk, &hi, &lo)) {
|
if (!char_to_hex_digits(res->chk, &hi, &lo)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +109,7 @@ int rdb_response_send_packet(RdbResponse *res) {
|
||||||
res->buf[res->len++] = lo;
|
res->buf[res->len++] = lo;
|
||||||
printf("sending command \"%.*s\" %d\n", (int) res->len, res->buf, (int)res->len);
|
printf("sending command \"%.*s\" %d\n", (int) res->len, res->buf, (int)res->len);
|
||||||
|
|
||||||
ssize_t rwrite = write(res->connfd, res->buf, res->len);
|
rwrite = write(res->connfd, res->buf, res->len);
|
||||||
if (rwrite == -1) {
|
if (rwrite == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
59
server.c
59
server.c
|
@ -73,45 +73,46 @@ int handle_command(RdbResponse *res, CommandBuf *cmd, VB *sim, bool *running) {
|
||||||
rdb_response_begin_packet(res);
|
rdb_response_begin_packet(res);
|
||||||
|
|
||||||
if (cmd_match_str(cmd, "QStartNoAckMode")) {
|
if (cmd_match_str(cmd, "QStartNoAckMode")) {
|
||||||
// The debugger is asking us to no longer ACK messages.
|
/* The debugger is asking us to no longer ACK messages. */
|
||||||
// Note that we ack THIS response, because we already called rdb_response_begin_packet.
|
/* Note that we ack THIS response, because we already called rdb_response_begin_packet. */
|
||||||
res->should_ack = false;
|
res->should_ack = false;
|
||||||
rdb_response_write_str(res, "OK");
|
rdb_response_write_str(res, "OK");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "qSupported")) {
|
if (cmd_match_str(cmd, "qSupported")) {
|
||||||
// The debugger is asking for a list of features we support.
|
/* The debugger is asking for a list of features we support. */
|
||||||
rdb_response_write_str(res, "no-resumed+;multiprocess;vContSupported;QNonStop+");
|
rdb_response_write_str(res, "no-resumed+;multiprocess;vContSupported;QNonStop+");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "QThreadSuffixSupported")) {
|
if (cmd_match_str(cmd, "QThreadSuffixSupported")) {
|
||||||
// The debugger is asking us to include the current thread as a suffix to some responses.
|
/* The debugger is asking us to include the current thread as a suffix to some responses. */
|
||||||
rdb_response_write_str(res, "OK");
|
rdb_response_write_str(res, "OK");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "QListThreadsInStopReply")) {
|
if (cmd_match_str(cmd, "QListThreadsInStopReply")) {
|
||||||
// The debugger is asking us to list all threads whenever we stop running.
|
/* The debugger is asking us to list all threads whenever we stop running. */
|
||||||
rdb_response_write_str(res, "OK");
|
rdb_response_write_str(res, "OK");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "qHostInfo")) {
|
if (cmd_match_str(cmd, "qHostInfo")) {
|
||||||
// The debugger is asking us to describe the "host machine" getting debugged.
|
/* The debugger is asking us to describe the "host machine" getting debugged. */
|
||||||
rdb_response_write_str(res, "triple:");
|
rdb_response_write_str(res, "triple:");
|
||||||
rdb_response_write_str_hex(res, "v810-unknown-vb");
|
rdb_response_write_str_hex(res, "v810-unknown-vb");
|
||||||
rdb_response_write_str(res, ";endian:little;ptrsize:4;");
|
rdb_response_write_str(res, ";endian:little;ptrsize:4;");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "qProcessInfo")) {
|
if (cmd_match_str(cmd, "qProcessInfo")) {
|
||||||
// The debugger is asking us to describe the "process" getting debugged.
|
/* The debugger is asking us to describe the "process" getting debugged. */
|
||||||
// We make up a process with id 1.
|
/* We make up a process with id 1. */
|
||||||
rdb_response_write_str(res, "pid:1;triple:");
|
rdb_response_write_str(res, "pid:1;triple:");
|
||||||
rdb_response_write_str_hex(res, "v810-unknown-vb");
|
rdb_response_write_str_hex(res, "v810-unknown-vb");
|
||||||
rdb_response_write_str(res, "endian:little;ptrsize:4;");
|
rdb_response_write_str(res, "endian:little;ptrsize:4;");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "qRegisterInfo")) {
|
if (cmd_match_str(cmd, "qRegisterInfo")) {
|
||||||
// The debugger is asking for information about a specific register.
|
|
||||||
uint32_t reg_no;
|
uint32_t reg_no;
|
||||||
|
|
||||||
|
/* The debugger is asking for information about a specific register. */
|
||||||
if (!cmd_match_hex_number(cmd, ®_no)) return 1;
|
if (!cmd_match_hex_number(cmd, ®_no)) return 1;
|
||||||
if (reg_no <= PC_INDEX) {
|
if (reg_no <= PC_INDEX) {
|
||||||
rdb_response_write_str(res, REGISTERS[reg_no]);
|
rdb_response_write_str(res, REGISTERS[reg_no]);
|
||||||
|
@ -119,34 +120,34 @@ int handle_command(RdbResponse *res, CommandBuf *cmd, VB *sim, bool *running) {
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "qfThreadInfo")) {
|
if (cmd_match_str(cmd, "qfThreadInfo")) {
|
||||||
// The debugger is asking us to list all threads. Return a list with "thread 1".
|
/* The debugger is asking us to list all threads. Return a list with "thread 1". */
|
||||||
rdb_response_write_str(res, "mp1.t1");
|
rdb_response_write_str(res, "mp1.t1");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "qsThreadInfo")) {
|
if (cmd_match_str(cmd, "qsThreadInfo")) {
|
||||||
// The debugger is asking us to list all threads.
|
/* The debugger is asking us to list all threads. */
|
||||||
rdb_response_write_str(res, "l");
|
rdb_response_write_str(res, "l");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "vCont?")) {
|
if (cmd_match_str(cmd, "vCont?")) {
|
||||||
// The debugger is asking which vCont commands we support.
|
/* The debugger is asking which vCont commands we support. */
|
||||||
rdb_response_write_str(res, "c;C;s;S");
|
rdb_response_write_str(res, "c;C;s;S");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "qC")) {
|
if (cmd_match_str(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". */
|
||||||
rdb_response_write_str(res, "QCp1.t1");
|
rdb_response_write_str(res, "QCp1.t1");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "p")) {
|
if (cmd_match_str(cmd, "p")) {
|
||||||
// read a register.
|
uint32_t reg_no, reg_value;
|
||||||
uint32_t reg_no;
|
|
||||||
|
/* read a register. */
|
||||||
if (!cmd_match_hex_number(cmd, ®_no)) return 1;
|
if (!cmd_match_hex_number(cmd, ®_no)) return 1;
|
||||||
if (reg_no > PC_INDEX) {
|
if (reg_no > PC_INDEX) {
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t reg_value;
|
|
||||||
if (reg_no == PC_INDEX) {
|
if (reg_no == PC_INDEX) {
|
||||||
reg_value = vbGetProgramCounter(sim);
|
reg_value = vbGetProgramCounter(sim);
|
||||||
} else if (reg_no > 31) {
|
} else if (reg_no > 31) {
|
||||||
|
@ -158,14 +159,15 @@ int handle_command(RdbResponse *res, CommandBuf *cmd, VB *sim, bool *running) {
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "P")) {
|
if (cmd_match_str(cmd, "P")) {
|
||||||
// write a register.
|
uint32_t reg_no, reg_value;
|
||||||
uint32_t reg_no;
|
|
||||||
uint8_t reg_bytes[4];
|
uint8_t reg_bytes[4];
|
||||||
|
|
||||||
|
/* write a register. */
|
||||||
if (!cmd_match_hex_number(cmd, ®_no)) return -1;
|
if (!cmd_match_hex_number(cmd, ®_no)) return -1;
|
||||||
if (!cmd_match_str(cmd, "=")) return -1;
|
if (!cmd_match_str(cmd, "=")) return -1;
|
||||||
if (!cmd_match_hex_bytes(cmd, 4, reg_bytes)) return -1;
|
if (!cmd_match_hex_bytes(cmd, 4, reg_bytes)) return -1;
|
||||||
|
|
||||||
int32_t reg_value = ((uint32_t) (reg_bytes[3]) << 24) |
|
reg_value = ((uint32_t) (reg_bytes[3]) << 24) |
|
||||||
((uint32_t) (reg_bytes[2]) << 16) |
|
((uint32_t) (reg_bytes[2]) << 16) |
|
||||||
((uint32_t) (reg_bytes[1]) << 8) |
|
((uint32_t) (reg_bytes[1]) << 8) |
|
||||||
((uint32_t) reg_bytes[0]);
|
((uint32_t) reg_bytes[0]);
|
||||||
|
@ -184,39 +186,38 @@ int handle_command(RdbResponse *res, CommandBuf *cmd, VB *sim, bool *running) {
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "Hc-1")) {
|
if (cmd_match_str(cmd, "Hc-1")) {
|
||||||
// Set the "current thread" for future commands to all threads (thread -1).
|
/* Set the "current thread" for future commands to all threads (thread -1). */
|
||||||
rdb_response_write_str(res, "OK");
|
rdb_response_write_str(res, "OK");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "c")) {
|
if (cmd_match_str(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). */
|
||||||
*running = true;
|
*running = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "\x03")) {
|
if (cmd_match_str(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. */
|
||||||
*running = false;
|
*running = false;
|
||||||
// Send the response to the "c" command from before.
|
/* Send the response to the "c" command from before. */
|
||||||
rdb_response_write_str(res, "T05thread:p1.t1;threads:p1.t1");
|
rdb_response_write_str(res, "T05thread:p1.t1;threads:p1.t1");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "?")) {
|
if (cmd_match_str(cmd, "?")) {
|
||||||
// The debugger has asked us why we stopped
|
/* The debugger has asked us why we stopped */
|
||||||
rdb_response_write_str(res, "T");
|
rdb_response_write_str(res, "T");
|
||||||
rdb_response_write_str(res, *running ? "00" : "05");
|
rdb_response_write_str(res, *running ? "00" : "05");
|
||||||
rdb_response_write_str(res, "thread:p1.t1;threads:p1.t1;");
|
rdb_response_write_str(res, "thread:p1.t1;threads:p1.t1;");
|
||||||
return rdb_response_send_packet(res);
|
return rdb_response_send_packet(res);
|
||||||
}
|
}
|
||||||
if (cmd_match_str(cmd, "m")) {
|
if (cmd_match_str(cmd, "m")) {
|
||||||
// read memory
|
/* read memory */
|
||||||
uint32_t address;
|
uint32_t i, address, len;
|
||||||
uint32_t len;
|
|
||||||
if (!cmd_match_hex_number(cmd, &address)) return -1;
|
if (!cmd_match_hex_number(cmd, &address)) return -1;
|
||||||
if (!cmd_match_str(cmd, ",")) return -1;
|
if (!cmd_match_str(cmd, ",")) return -1;
|
||||||
if (!cmd_match_hex_number(cmd, &len)) return -1;
|
if (!cmd_match_hex_number(cmd, &len)) return -1;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
uint8_t byte = vbRead(sim, address + i, VB_U8);
|
uint8_t byte = vbRead(sim, address + i, VB_U8);
|
||||||
rdb_response_write_i8_hex(res, byte);
|
rdb_response_write_i8_hex(res, byte);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue