gdb-server/main.c

163 lines
3.7 KiB
C
Raw Normal View History

2024-10-06 22:47:44 +00:00
#include <cmdbuf.h>
2024-10-07 04:55:44 +00:00
#include <request.h>
2024-10-08 02:18:42 +00:00
#include <response.h>
2024-10-08 02:00:01 +00:00
#include <server.h>
2024-10-01 22:48:28 +00:00
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
2024-10-02 01:24:48 +00:00
#include <vb.h>
2024-10-01 22:48:28 +00:00
2024-10-08 02:42:28 +00:00
#define BUFLEN 8096
2024-10-01 22:48:28 +00:00
2024-10-02 01:24:48 +00:00
int server(int connfd, VB *sim) {
2024-10-07 04:55:44 +00:00
RdbRequest req;
2024-10-08 02:18:42 +00:00
RdbResponse res;
char reqbuf[BUFLEN];
char resbuf[BUFLEN];
2024-10-08 02:42:28 +00:00
bool running;
rdb_read_result_t read_result;
int result;
2024-10-07 04:55:44 +00:00
2024-10-08 02:18:42 +00:00
rdb_request_init(&req, connfd, reqbuf, BUFLEN);
rdb_response_init(&res, connfd, resbuf, BUFLEN);
2024-10-01 22:48:28 +00:00
2024-10-08 02:42:28 +00:00
running = false;
2024-10-08 01:20:01 +00:00
2024-10-01 22:48:28 +00:00
while (1) {
2024-10-08 02:00:01 +00:00
CommandBuf cmd;
2024-10-08 02:42:28 +00:00
read_result = rdb_request_read(&req, &cmd);
if (read_result == read_result_error) {
2024-10-07 04:55:44 +00:00
return -1;
2024-10-08 02:42:28 +00:00
} else if (read_result == read_result_disconnected) {
2024-10-01 22:48:28 +00:00
printf("client has disconnected\n");
return 0;
2024-10-08 02:42:28 +00:00
} else if (read_result == read_result_pending) {
2024-10-08 01:20:01 +00:00
if (running) {
printf("pretend the emulator is running now\n");
sleep(1);
}
2024-10-07 04:55:44 +00:00
continue;
2024-10-01 22:48:28 +00:00
} else {
2024-10-08 02:00:01 +00:00
printf("received command \"%.*s\"\n", (int) cmd.len, cmd.buf);
2024-10-01 22:48:28 +00:00
fflush(stdout);
2024-10-08 02:42:28 +00:00
result = handle_command(&res, &cmd, sim, &running);
2024-10-08 02:18:42 +00:00
if (result != 0) {
return result;
2024-10-01 22:48:28 +00:00
}
2024-10-08 01:20:01 +00:00
rdb_request_set_blocking(&req, !running);
2024-10-07 04:55:44 +00:00
rdb_request_reset(&req);
2024-10-01 22:48:28 +00:00
}
}
2024-10-02 01:24:48 +00:00
}
int readROM(VB *sim, char *filename) {
FILE *file = fopen(filename, "rb");
2024-10-08 02:42:28 +00:00
uint8_t *rom;
2024-10-02 01:24:48 +00:00
long size;
if (!file) {
perror("could not open file");
return 1;
}
if (fseek(file, 0, SEEK_END)) {
perror("could not seek file end");
return 1;
}
size = ftell(file);
if (size == -1) {
perror("could not read file size");
return 1;
}
if (fseek(file, 0, SEEK_SET)) {
perror("could not seek file start");
return 1;
}
2024-10-08 02:42:28 +00:00
rom = malloc(size);
2024-10-06 21:19:14 +00:00
if (!rom) {
perror("could not allocate ROM");
return 1;
}
fread(rom, 1, size, file);
2024-10-02 01:24:48 +00:00
if (ferror(file)) {
perror("could not read file");
return 1;
}
if (fclose(file)) {
perror("could not close file");
return 1;
}
2024-10-06 21:19:14 +00:00
vbSetCartROM(sim, rom, size);
2024-10-01 22:48:28 +00:00
2024-10-02 01:24:48 +00:00
return 0;
2024-10-01 22:48:28 +00:00
}
int main(int argc, char** argv) {
2024-10-08 02:42:28 +00:00
VB *sim;
short port;
int fd, connfd;
struct sockaddr_in addr, cliaddr;
socklen_t cliaddrlen;
int response;
2024-10-02 01:24:48 +00:00
if (argc < 2) {
fprintf(stderr, "Please pass a ROM file\n");
return 1;
}
2024-10-08 02:42:28 +00:00
sim = malloc(vbSizeOf());
2024-10-06 21:19:14 +00:00
if (!sim) {
return 1;
}
vbInit(sim);
if (readROM(sim, argv[1])) {
2024-10-02 01:24:48 +00:00
return 1;
}
2024-10-06 21:19:14 +00:00
vbSetProgramCounter(sim, 0x07000000);
2024-10-02 01:24:48 +00:00
if (argc > 2) {
2024-10-01 22:48:28 +00:00
char *end;
2024-10-02 01:24:48 +00:00
port = (short) strtol(argv[2], &end, 10);
if (argv[2] == end) {
2024-10-01 22:48:28 +00:00
perror("could not parse port");
return 1;
}
} else {
port = 8080;
}
2024-10-08 02:42:28 +00:00
fd = socket(AF_INET, SOCK_STREAM, 0);
2024-10-01 22:48:28 +00:00
if (fd == -1) {
perror("could not open socket");
return 1;
}
memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
perror("could not bind socket");
return 1;
}
if (listen(fd, 1) == -1) {
perror("could not listen on socket");
return 1;
}
printf("connecting\n");
2024-10-08 02:42:28 +00:00
cliaddrlen = sizeof(cliaddr);
2024-10-01 22:48:28 +00:00
connfd = accept(fd, (struct sockaddr *) &cliaddr, &cliaddrlen);
if (connfd == -1) {
perror("could not accept connection");
return 1;
}
printf("connected\n");
2024-10-08 02:42:28 +00:00
response = server(connfd, sim);
2024-10-01 22:48:28 +00:00
return close(connfd)
|| close(fd)
|| response;
}