diff --git a/src/debugger/debugger.h b/src/debugger/debugger.h index 52fcf5a4d..1752108b6 100644 --- a/src/debugger/debugger.h +++ b/src/debugger/debugger.h @@ -31,6 +31,13 @@ enum DebuggerEntryReason { DEBUGGER_ENTER_ILLEGAL_OP }; +enum DebuggerLogLevel { + DEBUGGER_LOG_DEBUG = 0x01, + DEBUGGER_LOG_INFO = 0x02, + DEBUGGER_LOG_WARN = 0x04, + DEBUGGER_LOG_ERROR = 0x08 +}; + struct ARMDebugger { enum DebuggerState state; struct ARMCore* cpu; @@ -42,6 +49,9 @@ struct ARMDebugger { void (*deinit)(struct ARMDebugger*); void (*paused)(struct ARMDebugger*); void (*entered)(struct ARMDebugger*, enum DebuggerEntryReason); + + __attribute__((format (printf, 3, 4))) + void (*log)(struct ARMDebugger*, enum DebuggerLogLevel, const char* format, ...); }; void ARMDebuggerInit(struct ARMDebugger*, struct ARMCore*); diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c index 480dd607f..987d8f391 100644 --- a/src/debugger/gdb-stub.c +++ b/src/debugger/gdb-stub.c @@ -71,7 +71,9 @@ static void _ack(struct GDBStub* stub) { static void _nak(struct GDBStub* stub) { char nak = '-'; - printf("Packet error\n"); + if (stub->d.log) { + stub->d.log(&stub->d, DEBUGGER_LOG_WARN, "Packet error"); + } send(stub->connection, &nak, 1, 0); } @@ -150,6 +152,9 @@ static void _sendMessage(struct GDBStub* stub) { stub->outgoing[i] = '#'; _int2hex8(checksum, &stub->outgoing[i + 1]); stub->outgoing[i + 3] = 0; + if (stub->d.log) { + stub->d.log(&stub->d, DEBUGGER_LOG_DEBUG, "> %s", stub->outgoing); + } send(stub->connection, stub->outgoing, i + 3, 0); } @@ -366,7 +371,9 @@ size_t _parseGDBMessage(struct GDBStub* stub, const char* message) { parsed += 2; int networkChecksum = _hex2int(&message[i], 2); if (networkChecksum != checksum) { - printf("Checksum error: expected %02x, got %02x\n", checksum, networkChecksum); + if (stub->d.log) { + stub->d.log(&stub->d, DEBUGGER_LOG_WARN, "Checksum error: expected %02x, got %02x", checksum, networkChecksum); + } _nak(stub); return parsed; } @@ -430,6 +437,7 @@ void GDBStubCreate(struct GDBStub* stub) { stub->d.deinit = _gdbStubDeinit; stub->d.paused = _gdbStubPoll; stub->d.entered = _gdbStubEntered; + stub->d.log = 0; } int GDBStubListen(struct GDBStub* stub, int port, uint32_t bindAddress) { @@ -439,7 +447,9 @@ int GDBStubListen(struct GDBStub* stub, int port, uint32_t bindAddress) { // TODO: support IPv6 stub->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (stub->socket < 0) { - printf("Couldn't open socket\n"); + if (stub->d.log) { + stub->d.log(&stub->d, DEBUGGER_LOG_ERROR, "Couldn't open socket"); + } return 0; } @@ -518,6 +528,9 @@ void GDBStubUpdate(struct GDBStub* stub) { goto connectionLost; } stub->line[messageLen] = '\0'; + if (stub->d.log) { + stub->d.log(&stub->d, DEBUGGER_LOG_DEBUG, "< %s", stub->line); + } ssize_t position = 0; while (position < messageLen) { position += _parseGDBMessage(stub, &stub->line[position]); @@ -525,7 +538,8 @@ void GDBStubUpdate(struct GDBStub* stub) { } connectionLost: - // TODO: add logging support to the debugging interface - printf("Connection lost\n"); + if (stub->d.log) { + stub->d.log(&stub->d, DEBUGGER_LOG_INFO, "Connection lost"); + } GDBStubHangup(stub); } diff --git a/src/gba/gba.c b/src/gba/gba.c index eee01d9a4..fd2545c2a 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -503,7 +503,7 @@ int GBAHalt(struct GBA* gba) { return GBAWaitForIRQ(gba); } -void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) { +static void _GBAVLog(struct GBA* gba, enum GBALogLevel level, const char* format, va_list args) { if (!gba) { struct GBAThread* threadContext = GBAThreadGetContext(); if (threadContext) { @@ -512,10 +512,7 @@ void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) { } if (gba && gba->logHandler) { - va_list args; - va_start(args, format); gba->logHandler(gba, level, format, args); - va_end(args); return; } @@ -523,10 +520,7 @@ void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) { return; } - va_list args; - va_start(args, format); vprintf(format, args); - va_end(args); printf("\n"); if (level == GBA_LOG_FATAL) { @@ -534,6 +528,38 @@ void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) { } } +void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) { + va_list args; + va_start(args, format); + _GBAVLog(gba, level, format, args); + va_end(args); +} + +void GBADebuggerLogShim(struct ARMDebugger* debugger, enum DebuggerLogLevel level, const char* format, ...) { + struct GBABoard* gbaBoard = (struct GBABoard*) debugger->cpu->board; + + enum GBALogLevel gbaLevel; + switch (level) { + case DEBUGGER_LOG_DEBUG: + gbaLevel = GBA_LOG_DEBUG; + break; + case DEBUGGER_LOG_INFO: + gbaLevel = GBA_LOG_INFO; + break; + case DEBUGGER_LOG_WARN: + gbaLevel = GBA_LOG_WARN; + break; + case DEBUGGER_LOG_ERROR: + gbaLevel = GBA_LOG_ERROR; + break; + } + va_list args; + va_start(args, format); + _GBAVLog(gbaBoard->p, gbaLevel, format, args); + va_end(args); +} + + void GBAHitStub(struct ARMBoard* board, uint32_t opcode) { struct GBABoard* gbaBoard = (struct GBABoard*) board; enum GBALogLevel level = GBA_LOG_FATAL; diff --git a/src/gba/gba.h b/src/gba/gba.h index 3fa6bfe45..90ea5744d 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -2,6 +2,7 @@ #define GBA_H #include "arm.h" +#include "debugger.h" #include "gba-memory.h" #include "gba-video.h" @@ -146,4 +147,7 @@ void GBALoadBIOS(struct GBA* gba, int fd); __attribute__((format (printf, 3, 4))) void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...); +__attribute__((format (printf, 3, 4))) +void GBADebuggerLogShim(struct ARMDebugger* debugger, enum DebuggerLogLevel level, const char* format, ...); + #endif