Rename RdbClient to RdbResponse
This commit is contained in:
		
							parent
							
								
									1b273171ad
								
							
						
					
					
						commit
						6ea396a974
					
				
							
								
								
									
										113
									
								
								client.c
								
								
								
								
							
							
						
						
									
										113
									
								
								client.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,113 +0,0 @@
 | 
			
		|||
#include <client.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
#ifndef RDBSERVER_CLIENT_H_
 | 
			
		||||
#define RDBSERVER_CLIENT_H_
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
#ifndef RDBSERVER_RESPONSE_H_
 | 
			
		||||
#define RDBSERVER_RESPONSE_H_
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
#ifndef RDBSERVER_SERVER_H_
 | 
			
		||||
#define RDBSERVER_SERVER_H_
 | 
			
		||||
 | 
			
		||||
#include <client.h>
 | 
			
		||||
#include <cmdbuf.h>
 | 
			
		||||
#include <response.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <vb.h>
 | 
			
		||||
 | 
			
		||||
int handle_command(RdbClient *client, CommandBuf *cmd, VB *sim, bool *running);
 | 
			
		||||
int handle_command(RdbResponse *res, CommandBuf *cmd, VB *sim, bool *running);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										17
									
								
								main.c
								
								
								
								
							
							
						
						
									
										17
									
								
								main.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
#include <client.h>
 | 
			
		||||
#include <cmdbuf.h>
 | 
			
		||||
#include <request.h>
 | 
			
		||||
#include <response.h>
 | 
			
		||||
#include <server.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								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 \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,115 @@
 | 
			
		|||
#include <response.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								server.c
								
								
								
								
							
							
						
						
									
										94
									
								
								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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue