From 6ea396a974bf06360aa024ffce57b6febfd039e7 Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Mon, 7 Oct 2024 22:18:42 -0400 Subject: [PATCH] Rename RdbClient to RdbResponse --- client.c | 113 -------------------------------------------- include/client.h | 27 ----------- include/request.h | 2 +- include/response.h | 26 ++++++++++ include/server.h | 4 +- main.c | 17 +++---- makefile | 2 +- response.c | 115 +++++++++++++++++++++++++++++++++++++++++++++ server.c | 94 ++++++++++++++++++------------------ 9 files changed, 201 insertions(+), 199 deletions(-) delete mode 100644 client.c delete mode 100644 include/client.h create mode 100644 include/response.h create mode 100644 response.c diff --git a/client.c b/client.c deleted file mode 100644 index 2cbe418..0000000 --- a/client.c +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include -#include -#include -#include - -static bool write_char(RdbClient *self, char out) { - if (self->len >= RDB_CLIENT_BUFLEN) { - return false; - } - if (out == '#' || out == '$' || out == '}' || out == '*') { - self->full_buf[self->len++] = '}'; - self->chk += '}'; - if (self->len >= RDB_CLIENT_BUFLEN) { - return false; - } - out ^= 0x20; - } - self->full_buf[self->len++] = out; - self->chk += out; - return true; -} - -bool char_to_hex_digit(char in, char *out) { - if (in & 0xf0) { - return false; - } - in &= 0x0f; - if (in > 9) { - *out = 'a' + in - 10; - } else { - *out = '0' + in; - } - return true; -} - -bool char_to_hex_digits(char in, char *hi, char *lo) { - return char_to_hex_digit((in & 0xf0) >> 4, hi) - && char_to_hex_digit(in & 0x0f, lo); -} - -void rdb_client_init(RdbClient *self, int connfd) { - self->connfd = connfd; - self->len = 0; - self->chk = 0; - self->should_ack = true; -} - -void rdb_client_begin_packet(RdbClient *self) { - self->len = 0; - self->chk = 0; - if (self->should_ack) { - self->full_buf[self->len++] = '+'; - } - self->full_buf[self->len++] = '$'; -} - -bool rdb_client_write_str(RdbClient *self, const char *str) { - size_t len = strlen(str); - for (size_t i = 0; i < len; ++i) { - if (!write_char(self, str[i])) { - return false; - } - } - return true; -} - -bool rdb_client_write_str_hex(RdbClient *self, const char *str) { - size_t len = strlen(str); - for (size_t i = 0; i < len; ++i) { - char hi, lo; - if (!char_to_hex_digits(str[i], &hi, &lo) - || !write_char(self, hi) - || !write_char(self, lo)) { - return false; - } - } - return true; -} - -bool rdb_client_write_i8_hex(RdbClient *self, uint8_t value) { - char hi, lo; - return char_to_hex_digits(value, &hi, &lo) - && write_char(self, hi) - && write_char(self, lo); -} - -bool rdb_client_write_i32_hex(RdbClient *self, uint32_t value) { - return rdb_client_write_i8_hex(self, (uint8_t) value) - && rdb_client_write_i8_hex(self, (uint8_t) (value >> 8)) - && rdb_client_write_i8_hex(self, (uint8_t) (value >> 16)) - && rdb_client_write_i8_hex(self, (uint8_t) (value >> 24)); -} - -int rdb_client_send_packet(RdbClient *self) { - if (self->len + 3 > RDB_CLIENT_BUFLEN) { - return -1; - } - self->full_buf[self->len++] = '#'; - char hi, lo; - if (!char_to_hex_digits(self->chk, &hi, &lo)) { - return -1; - } - self->full_buf[self->len++] = hi; - self->full_buf[self->len++] = lo; - printf("sending command \"%.*s\" %d\n", (int) self->len, self->full_buf, (int)self->len); - - ssize_t rwrite = write(self->connfd, self->full_buf, self->len); - if (rwrite == -1) { - return -1; - } - return 0; -} \ No newline at end of file diff --git a/include/client.h b/include/client.h deleted file mode 100644 index 954697c..0000000 --- a/include/client.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef RDBSERVER_CLIENT_H_ -#define RDBSERVER_CLIENT_H_ - -#include -#include -#include -#include - -#define RDB_CLIENT_BUFLEN 8096 - -typedef struct RdbClient { - int connfd; - char full_buf[RDB_CLIENT_BUFLEN]; - size_t len; - char chk; - bool should_ack; -} RdbClient; - -void rdb_client_init(RdbClient *self, int connfd); -void rdb_client_begin_packet(RdbClient *self); -bool rdb_client_write_str(RdbClient *self, const char *str); -bool rdb_client_write_str_hex(RdbClient *self, const char *str); -bool rdb_client_write_i8_hex(RdbClient *self, uint8_t value); -bool rdb_client_write_i32_hex(RdbClient *self, uint32_t value); -int rdb_client_send_packet(RdbClient *self); - -#endif \ No newline at end of file diff --git a/include/request.h b/include/request.h index 9a1cb10..dee506e 100644 --- a/include/request.h +++ b/include/request.h @@ -35,7 +35,7 @@ typedef struct RdbRequest { char chk; } RdbRequest; -void rdb_request_init(RdbRequest *req, int connfd, char *cmd, size_t cmdlen); +void rdb_request_init(RdbRequest *req, int connfd, char *buf, size_t buflen); void rdb_request_reset(RdbRequest *req); void rdb_request_set_blocking(RdbRequest *req, bool blocking); rdb_read_result_t rdb_request_read(RdbRequest *req, CommandBuf *cmd); diff --git a/include/response.h b/include/response.h new file mode 100644 index 0000000..b2dd0bf --- /dev/null +++ b/include/response.h @@ -0,0 +1,26 @@ +#ifndef RDBSERVER_RESPONSE_H_ +#define RDBSERVER_RESPONSE_H_ + +#include +#include +#include +#include + +typedef struct RdbResponse { + int connfd; + char *buf; + size_t buflen; + size_t len; + char chk; + bool should_ack; +} RdbResponse; + +void rdb_response_init(RdbResponse *self, int connfd, char *buf, size_t buflen); +void rdb_response_begin_packet(RdbResponse *self); +bool rdb_response_write_str(RdbResponse *self, const char *str); +bool rdb_response_write_str_hex(RdbResponse *self, const char *str); +bool rdb_response_write_i8_hex(RdbResponse *self, uint8_t value); +bool rdb_response_write_i32_hex(RdbResponse *self, uint32_t value); +int rdb_response_send_packet(RdbResponse *self); + +#endif \ No newline at end of file diff --git a/include/server.h b/include/server.h index 3131054..a8d35a0 100644 --- a/include/server.h +++ b/include/server.h @@ -1,11 +1,11 @@ #ifndef RDBSERVER_SERVER_H_ #define RDBSERVER_SERVER_H_ -#include #include +#include #include #include -int handle_command(RdbClient *client, CommandBuf *cmd, VB *sim, bool *running); +int handle_command(RdbResponse *res, CommandBuf *cmd, VB *sim, bool *running); #endif \ No newline at end of file diff --git a/main.c b/main.c index e1dea5d..fba492d 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,6 @@ -#include #include #include +#include #include #include #include @@ -12,11 +12,12 @@ const size_t BUFLEN = 8096; int server(int connfd, VB *sim) { RdbRequest req; - RdbClient client; - char buf[BUFLEN]; + RdbResponse res; + char reqbuf[BUFLEN]; + char resbuf[BUFLEN]; - rdb_request_init(&req, connfd, buf, BUFLEN); - rdb_client_init(&client, connfd); + rdb_request_init(&req, connfd, reqbuf, BUFLEN); + rdb_response_init(&res, connfd, resbuf, BUFLEN); bool running = false; @@ -37,9 +38,9 @@ int server(int connfd, VB *sim) { } else { printf("received command \"%.*s\"\n", (int) cmd.len, cmd.buf); fflush(stdout); - int res = handle_command(&client, &cmd, sim, &running); - if (res != 0) { - return res; + int result = handle_command(&res, &cmd, sim, &running); + if (result != 0) { + return result; } rdb_request_set_blocking(&req, !running); rdb_request_reset(&req); diff --git a/makefile b/makefile index 2207a39..13cb723 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ build: @mkdir -p build - @gcc main.c client.c cmdbuf.c hex.c request.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 \ -Werror -Wall -Wextra -Wpedantic \ -Wno-unused-parameter -Wno-unused-function \ diff --git a/response.c b/response.c new file mode 100644 index 0000000..402c396 --- /dev/null +++ b/response.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include + +static bool write_char(RdbResponse *res, char out) { + if (res->len >= res->buflen) { + return false; + } + if (out == '#' || out == '$' || out == '}' || out == '*') { + res->buf[res->len++] = '}'; + res->chk += '}'; + if (res->len >= res->buflen) { + return false; + } + out ^= 0x20; + } + res->buf[res->len++] = out; + res->chk += out; + return true; +} + +bool char_to_hex_digit(char in, char *out) { + if (in & 0xf0) { + return false; + } + in &= 0x0f; + if (in > 9) { + *out = 'a' + in - 10; + } else { + *out = '0' + in; + } + return true; +} + +bool char_to_hex_digits(char in, char *hi, char *lo) { + return char_to_hex_digit((in & 0xf0) >> 4, hi) + && char_to_hex_digit(in & 0x0f, lo); +} + +void rdb_response_init(RdbResponse *res, int connfd, char *buf, size_t buflen) { + res->connfd = connfd; + res->buf = buf; + res->buflen = buflen; + res->len = 0; + res->chk = 0; + res->should_ack = true; +} + +void rdb_response_begin_packet(RdbResponse *res) { + res->len = 0; + res->chk = 0; + if (res->should_ack) { + res->buf[res->len++] = '+'; + } + res->buf[res->len++] = '$'; +} + +bool rdb_response_write_str(RdbResponse *res, const char *str) { + size_t len = strlen(str); + for (size_t i = 0; i < len; ++i) { + if (!write_char(res, str[i])) { + return false; + } + } + return true; +} + +bool rdb_response_write_str_hex(RdbResponse *res, const char *str) { + size_t len = strlen(str); + for (size_t i = 0; i < len; ++i) { + char hi, lo; + if (!char_to_hex_digits(str[i], &hi, &lo) + || !write_char(res, hi) + || !write_char(res, lo)) { + return false; + } + } + return true; +} + +bool rdb_response_write_i8_hex(RdbResponse *res, uint8_t value) { + char hi, lo; + return char_to_hex_digits(value, &hi, &lo) + && write_char(res, hi) + && write_char(res, lo); +} + +bool rdb_response_write_i32_hex(RdbResponse *res, uint32_t value) { + return rdb_response_write_i8_hex(res, (uint8_t) value) + && rdb_response_write_i8_hex(res, (uint8_t) (value >> 8)) + && rdb_response_write_i8_hex(res, (uint8_t) (value >> 16)) + && rdb_response_write_i8_hex(res, (uint8_t) (value >> 24)); +} + +int rdb_response_send_packet(RdbResponse *res) { + if (res->len + 3 > res->buflen) { + return -1; + } + res->buf[res->len++] = '#'; + char hi, lo; + if (!char_to_hex_digits(res->chk, &hi, &lo)) { + return -1; + } + res->buf[res->len++] = hi; + res->buf[res->len++] = lo; + printf("sending command \"%.*s\" %d\n", (int) res->len, res->buf, (int)res->len); + + ssize_t rwrite = write(res->connfd, res->buf, res->len); + if (rwrite == -1) { + return -1; + } + return 0; +} \ No newline at end of file diff --git a/server.c b/server.c index 3638e10..a3db239 100644 --- a/server.c +++ b/server.c @@ -69,81 +69,81 @@ const uint32_t SYSTEM_REGISTERS[] = { const uint32_t PC_INDEX = 32 + 13; -int handle_command(RdbClient *client, CommandBuf *cmd, VB *sim, bool *running) { - rdb_client_begin_packet(client); +int handle_command(RdbResponse *res, CommandBuf *cmd, VB *sim, bool *running) { + rdb_response_begin_packet(res); if (cmd_match_only_str(cmd, "QStartNoAckMode")) { // The debugger is asking us to no longer ACK messages. - // Note that we ack THIS response, because we already called rdb_client_begin_packet. - client->should_ack = false; - rdb_client_write_str(client, "OK"); - return rdb_client_send_packet(client); + // Note that we ack THIS response, because we already called rdb_response_begin_packet. + res->should_ack = false; + rdb_response_write_str(res, "OK"); + return rdb_response_send_packet(res); } if (cmd_match_str(cmd, "qSupported")) { // The debugger is asking for a list of features we support. - rdb_client_write_str(client, "no-resumed+;multiprocess;vContSupported;QNonStop+"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "no-resumed+;multiprocess;vContSupported;QNonStop+"); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "QThreadSuffixSupported")) { // The debugger is asking us to include the current thread as a suffix to some responses. - rdb_client_write_str(client, "OK"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "OK"); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "QListThreadsInStopReply")) { // The debugger is asking us to list all threads whenever we stop running. - rdb_client_write_str(client, "OK"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "OK"); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "qHostInfo")) { // The debugger is asking us to describe the "host machine" getting debugged. - rdb_client_write_str(client, "triple:"); - rdb_client_write_str_hex(client, "v810-unknown-vb"); - rdb_client_write_str(client, ";endian:little;ptrsize:4;"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "triple:"); + rdb_response_write_str_hex(res, "v810-unknown-vb"); + rdb_response_write_str(res, ";endian:little;ptrsize:4;"); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "qProcessInfo")) { // The debugger is asking us to describe the "process" getting debugged. // We make up a process with id 1. - rdb_client_write_str(client, "pid:1;triple:"); - rdb_client_write_str_hex(client, "v810-unknown-vb"); - rdb_client_write_str(client, "endian:little;ptrsize:4;"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "pid:1;triple:"); + rdb_response_write_str_hex(res, "v810-unknown-vb"); + rdb_response_write_str(res, "endian:little;ptrsize:4;"); + return rdb_response_send_packet(res); } if (cmd_match_str(cmd, "qRegisterInfo")) { // The debugger is asking for information about a specific register. uint32_t reg_no; if (!cmd_match_hex_number(cmd, ®_no)) return 1; if (reg_no <= PC_INDEX) { - rdb_client_write_str(client, REGISTERS[reg_no]); + rdb_response_write_str(res, REGISTERS[reg_no]); } - return rdb_client_send_packet(client); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "qfThreadInfo")) { // The debugger is asking us to list all threads. Return a list with "thread 1". - rdb_client_write_str(client, "mp1.t1"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "mp1.t1"); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "qsThreadInfo")) { // The debugger is asking us to list all threads. - rdb_client_write_str(client, "l"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "l"); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "vCont?")) { // The debugger is asking which vCont commands we support. - rdb_client_write_str(client, "c;C;s;S"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "c;C;s;S"); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "qC")) { // The debugger is asking for the current thread id. Return "thread 1". - rdb_client_write_str(client, "QCp1.t1"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "QCp1.t1"); + return rdb_response_send_packet(res); } if (cmd_match_str(cmd, "p")) { // read a register. uint32_t reg_no; if (!cmd_match_hex_number(cmd, ®_no)) return 1; if (reg_no > PC_INDEX) { - return rdb_client_send_packet(client); + return rdb_response_send_packet(res); } int32_t reg_value; @@ -154,8 +154,8 @@ int handle_command(RdbClient *client, CommandBuf *cmd, VB *sim, bool *running) { } else { reg_value = vbGetProgramRegister(sim, reg_no); } - rdb_client_write_i32_hex(client, reg_value); - return rdb_client_send_packet(client); + rdb_response_write_i32_hex(res, reg_value); + return rdb_response_send_packet(res); } if (cmd_match_str(cmd, "P")) { // write a register. @@ -171,7 +171,7 @@ int handle_command(RdbClient *client, CommandBuf *cmd, VB *sim, bool *running) { ((uint32_t) reg_bytes[0]); if (reg_no > PC_INDEX) { - return rdb_client_send_packet(client); + return rdb_response_send_packet(res); } if (reg_no == PC_INDEX) { vbSetProgramCounter(sim, reg_value); @@ -180,13 +180,13 @@ int handle_command(RdbClient *client, CommandBuf *cmd, VB *sim, bool *running) { } else { vbSetProgramRegister(sim, reg_no, reg_value); } - rdb_client_write_str(client, "OK"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "OK"); + return rdb_response_send_packet(res); } if (cmd_match_str(cmd, "Hc-1")) { // Set the "current thread" for future commands to all threads (thread -1). - rdb_client_write_str(client, "OK"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "OK"); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "c")) { // The debugger has told us to run until we are stopped. @@ -198,15 +198,15 @@ int handle_command(RdbClient *client, CommandBuf *cmd, VB *sim, bool *running) { // Received an ETX, indicating that the server wants to cancel the "c" command from before. *running = false; // Send the response to the "c" command from before. - rdb_client_write_str(client, "T05thread:p1.t1;threads:p1.t1"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "T05thread:p1.t1;threads:p1.t1"); + return rdb_response_send_packet(res); } if (cmd_match_only_str(cmd, "?")) { // The debugger has asked us why we stopped - rdb_client_write_str(client, "T"); - rdb_client_write_str(client, *running ? "00" : "05"); - rdb_client_write_str(client, "thread:p1.t1;threads:p1.t1;"); - return rdb_client_send_packet(client); + rdb_response_write_str(res, "T"); + rdb_response_write_str(res, *running ? "00" : "05"); + rdb_response_write_str(res, "thread:p1.t1;threads:p1.t1;"); + return rdb_response_send_packet(res); } if (cmd_match_str(cmd, "m")) { // read memory @@ -218,11 +218,11 @@ int handle_command(RdbClient *client, CommandBuf *cmd, VB *sim, bool *running) { for (uint32_t i = 0; i < len; ++i) { uint8_t byte = vbRead(sim, address + i, VB_U8); - rdb_client_write_i8_hex(client, byte); + rdb_response_write_i8_hex(res, byte); } - return rdb_client_send_packet(client); + return rdb_response_send_packet(res); } fprintf(stderr, "Unrecognized command.\n"); - return rdb_client_send_packet(client); + return rdb_response_send_packet(res); }