Compile against C90

This commit is contained in:
Simon Gellis 2024-10-07 22:42:28 -04:00
parent 8de384fa91
commit 02a7c9811c
7 changed files with 75 additions and 66 deletions

View File

@ -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;

View File

@ -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
View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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;
} }

View File

@ -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, &reg_no)) return 1; if (!cmd_match_hex_number(cmd, &reg_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, &reg_no)) return 1; if (!cmd_match_hex_number(cmd, &reg_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, &reg_no)) return -1; if (!cmd_match_hex_number(cmd, &reg_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);
} }