summaryrefslogtreecommitdiff
path: root/libpcsxcore/gdb_server.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2020-05-23 01:06:07 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2020-05-23 18:05:53 +0200
commit470da05658a97a51bd2ad2db7834bcc13dd995fd (patch)
treef2c85327bfe13813098446ff91a61b725116fa86 /libpcsxcore/gdb_server.c
parentaea565d558f929729c0cb889f9c3296f2f487d0d (diff)
downloadpcsxr-470da05658a97a51bd2ad2db7834bcc13dd995fd.tar.gz
Started implementing GDB server
Diffstat (limited to 'libpcsxcore/gdb_server.c')
-rw-r--r--libpcsxcore/gdb_server.c128
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();
+}