Begin GDB stub

This commit is contained in:
Jeffrey Pfau 2014-02-01 03:05:10 -08:00
parent 38aac38a0c
commit 244f197742
4 changed files with 156 additions and 2 deletions

View File

@ -4,6 +4,7 @@ set(BINARY_NAME gbac CACHE INTERNAL "Name of output binaries")
set(CMAKE_C_FLAGS_DEBUG "-g -Wall -Wextra --std=gnu99")
set(CMAKE_C_FLAGS_RELEASE "-O3 -Wall -Wextra --std=gnu99")
set(USE_CLI_DEBUGGER ON CACHE BOOL "Whether or not to enable the CLI-mode ARM debugger")
set(USE_GDB_STUB ON CACHE BOOL "Whether or not to enable the GDB stub ARM debugger")
set(BUILD_SDL ON CACHE BOOL "Build SDL frontend")
set(BUILD_PERF ON CACHE BOOL "Build performance profiling tool")
file(GLOB ARM_SRC ${CMAKE_SOURCE_DIR}/src/arm/*.c)
@ -37,6 +38,10 @@ if(USE_CLI_DEBUGGER)
else()
set(DEBUGGER_LIB "")
endif()
if(USE_GDB_STUB)
set(DEBUGGER_SRC "${DEBUGGER_SRC};${CMAKE_SOURCE_DIR}/src/debugger/gdb-stub.c")
endif()
source_group("ARM debugger" FILES ${DEBUGGER_SRC})
add_library(${BINARY_NAME} SHARED ${ARM_SRC} ${GBA_SRC} ${DEBUGGER_SRC} ${RENDERER_SRC} ${UTIL_SRC} ${OS_SRC})

View File

@ -29,7 +29,9 @@ void ARMDebuggerInit(struct ARMDebugger* debugger, struct ARMCore* cpu) {
debugger->breakpoints = 0;
debugger->memoryShim.p = debugger;
debugger->memoryShim.watchpoints = 0;
debugger->init(debugger);
if (debugger->init) {
debugger->init(debugger);
}
}
void ARMDebuggerDeinit(struct ARMDebugger* debugger) {
@ -56,7 +58,11 @@ void ARMDebuggerRun(struct ARMDebugger* debugger) {
case DEBUGGER_RUNNING:
break;
case DEBUGGER_PAUSED:
debugger->paused(debugger);
if (debugger->paused) {
debugger->paused(debugger);
} else {
debugger->state = DEBUGGER_RUNNING;
}
break;
case DEBUGGER_EXITING:
case DEBUGGER_SHUTDOWN:

118
src/debugger/gdb-stub.c Normal file
View File

@ -0,0 +1,118 @@
#include "gdb-stub.h"
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
void _gdbStubDeinit(struct ARMDebugger* debugger) {
struct GDBStub* stub = (struct GDBStub*) debugger;
if (stub->socket >= 0) {
GDBStubShutdown(stub);
}
}
void GDBStubCreate(struct GDBStub* stub) {
stub->socket = -1;
stub->connection = -1;
stub->d.init = 0;
stub->d.deinit = _gdbStubDeinit;
stub->d.paused = 0;
}
int GDBStubListen(struct GDBStub* stub, int port, uint32_t bindAddress) {
if (stub->socket >= 0) {
GDBStubShutdown(stub);
}
// TODO: support IPv6
stub->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (stub->socket < 0) {
printf("Couldn't open socket\n");
return 0;
}
struct sockaddr_in bindInfo = {
.sin_family = AF_INET,
.sin_port = htons(port),
.sin_addr = {
.s_addr = htonl(bindAddress)
}
};
int err = bind(stub->socket, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
if (err) {
goto cleanup;
}
err = listen(stub->socket, 1);
if (err) {
goto cleanup;
}
int flags = fcntl(stub->socket, F_GETFL);
if (flags == -1) {
goto cleanup;
}
flags |= O_NONBLOCK;
fcntl(stub->socket, F_SETFL, flags | O_NONBLOCK);
return 1;
cleanup:
close(stub->socket);
stub->socket = -1;
return 0;
}
void GDBStubHangup(struct GDBStub* stub) {
if (stub->connection >= 0) {
close(stub->connection);
stub->connection = -1;
}
}
void GDBStubShutdown(struct GDBStub* stub) {
GDBStubHangup(stub);
if (stub->socket >= 0) {
close(stub->socket);
stub->socket = -1;
}
}
void GDBStubUpdate(struct GDBStub* stub) {
if (stub->connection == -1) {
stub->connection = accept(stub->socket, 0, 0);
if (errno == EWOULDBLOCK || errno == EAGAIN) {
return;
}
if (stub->connection >= 0) {
int flags = fcntl(stub->connection, F_GETFL);
if (flags == -1) {
goto connectionLost;
}
flags |= O_NONBLOCK;
fcntl(stub->connection, F_SETFL, flags | O_NONBLOCK);
} else {
goto connectionLost;
}
}
while (1) {
ssize_t messageLen = recv(stub->connection, stub->line, GDB_STUB_MAX_LINE - 1, 0);
if (messageLen == 0) {
goto connectionLost;
}
if (messageLen == -1) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
return;
}
goto connectionLost;
}
stub->line[messageLen] = '\0';
printf("Received message: %s\n", stub->line);
}
return;
connectionLost:
// TODO: add logging support to the debugging interface
printf("Connection lost\n");
GDBStubHangup(stub);
}

25
src/debugger/gdb-stub.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef GDB_STUB_H
#define GDB_STUB_H
#include "debugger.h"
#define GDB_STUB_MAX_LINE 256
struct GDBStub {
struct ARMDebugger d;
char line[GDB_STUB_MAX_LINE];
int socket;
int connection;
};
void GDBStubCreate(struct GDBStub*);
int GDBStubListen(struct GDBStub*, int port, uint32_t bindAddress);
void GDBStubHangup(struct GDBStub*);
void GDBStubShutdown(struct GDBStub*);
void GDBStubUpdate(struct GDBStub*);
#endif