diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2020-05-23 01:06:07 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2020-05-23 18:05:53 +0200 |
| commit | 470da05658a97a51bd2ad2db7834bcc13dd995fd (patch) | |
| tree | f2c85327bfe13813098446ff91a61b725116fa86 /libpcsxcore/gdb_server.c | |
| parent | aea565d558f929729c0cb889f9c3296f2f487d0d (diff) | |
| download | pcsxr-470da05658a97a51bd2ad2db7834bcc13dd995fd.tar.gz | |
Started implementing GDB server
Diffstat (limited to 'libpcsxcore/gdb_server.c')
| -rw-r--r-- | libpcsxcore/gdb_server.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/libpcsxcore/gdb_server.c b/libpcsxcore/gdb_server.c new file mode 100644 index 00000000..7f7ea2ca --- /dev/null +++ b/libpcsxcore/gdb_server.c @@ -0,0 +1,128 @@ +#include "socket.h" +#include "psxcommon.h" +#include "misc.h" +#include "system.h" +#include "dynstr.h" +#include <stdio.h> +#include <string.h> +#include <stddef.h> + +static int server_socket, client_socket; +static int debugger_active, resetting, reset, paused, ack_expected; + +enum { PACKET_SIZE = 256 }; + +void GdbStartServer(void) +{ + enum { PORT = 3333 }; + + if (server_socket > 0) { + GdbStopServer(); + } + + server_socket = StartServer(PORT); + + if (server_socket > 0) { + printf("GDB server started on port %hu\n", PORT); + debugger_active = 1; + } + else + { + fprintf(stderr, "Could not start GDB server\n"); + } +} + +int GdbServerRunning(void) +{ + return server_socket > 0; +} + +void GdbStopServer(void) +{ +} + +static void ack(struct dynstr *const reply) +{ + dynstr_append(reply, "OK"); +} + +static void nack(struct dynstr *const reply, const int err) +{ + dynstr_append(reply, "E %02X", err); +} + +static void HandlePacket(char *const packet, const size_t len) +{ + struct dynstr reply; + const char *c = packet; + + dynstr_init(&reply); + + if (strstr(packet, "qSupported")) { + dynstr_append(&reply, "PacketSize=%x;swbreak+;hwbreak+", PACKET_SIZE - 1); + } + else { + fprintf(stderr, "Unexpected packet \"%s\"\n", packet); + return; + } + + printf("gdb <- \"%s\"\n", reply.str); + WriteSocket(client_socket, reply.str, reply.len); + dynstr_free(&reply); +} + +static void ProcessCommands(void) +{ + if (HasClient(client_socket)) { + char packet[PACKET_SIZE]; + size_t len = sizeof packet; + const enum read_socket_err err = ReadSocket(client_socket, packet, &len); + + switch (err) + { + case READ_SOCKET_OK: + if (len && len < sizeof packet) { + /* gdb apparently does not send null-terminated strings. */ + packet[len] = '\0'; + printf("gdb -> \"%s\"\n", packet); + HandlePacket(packet, len); + } + break; + + case READ_SOCKET_ERR_INVALID_ARG: + /* Fall through. */ + case READ_SOCKET_ERR_RECV: + /* Fall through. */ + case READ_SOCKET_SHUTDOWN: + /* Fall through. */ + default: + return; + } + } +} + +void GdbServerProcessDebug(void) +{ + ProcessCommands(); +} + +void GdbServerVSync(void) +{ + if (!debugger_active || resetting) + return; + + if (reset) { + resetting = 1; + SysReset(); + if (reset == 2) + LoadCdrom(); + reset = resetting = 0; + return; + } + + if (client_socket < 1) { + client_socket = GetClient(server_socket); + } + + ProcessCommands(); +} |
