all repos — mgba @ 525354e500b93545d16dde4d16b0ace3dd2a2d03

mGBA Game Boy Advance Emulator

src/debugger/debugger.c (view raw)

  1/* Copyright (c) 2013-2016 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "debugger.h"
  7
  8#include "core/core.h"
  9
 10#ifdef USE_CLI_DEBUGGER
 11#include "debugger/cli-debugger.h"
 12#include "gba/supervisor/cli.h"
 13#endif
 14
 15#ifdef USE_GDB_STUB
 16#include "debugger/gdb-stub.h"
 17#endif
 18
 19const uint32_t DEBUGGER_ID = 0xDEADBEEF;
 20
 21mLOG_DEFINE_CATEGORY(DEBUGGER, "Debugger");
 22
 23static void mDebuggerInit(void* cpu, struct mCPUComponent* component);
 24static void mDebuggerDeinit(struct mCPUComponent* component);
 25
 26struct mDebugger* mDebuggerCreate(enum mDebuggerType type, struct mCore* core) {
 27	if (!core->supportsDebuggerType(core, type)) {
 28		return NULL;
 29	}
 30
 31	union DebugUnion {
 32		struct mDebugger d;
 33#ifdef USE_CLI_DEBUGGER
 34		struct CLIDebugger cli;
 35#endif
 36#ifdef USE_GDB_STUB
 37		struct GDBStub gdb;
 38#endif
 39	};
 40
 41	union DebugUnion* debugger = malloc(sizeof(union DebugUnion));
 42
 43	switch (type) {
 44#ifdef USE_CLI_DEBUGGER
 45	case DEBUGGER_CLI:
 46		CLIDebuggerCreate(&debugger->cli);
 47		struct CLIDebuggerSystem* sys = core->cliDebuggerSystem(core);
 48		CLIDebuggerAttachSystem(&debugger->cli, sys);
 49		break;
 50#endif
 51#ifdef USE_GDB_STUB
 52	case DEBUGGER_GDB:
 53		GDBStubCreate(&debugger->gdb);
 54		GDBStubListen(&debugger->gdb, 2345, 0);
 55		break;
 56#endif
 57	case DEBUGGER_NONE:
 58	case DEBUGGER_MAX:
 59		free(debugger);
 60		return 0;
 61		break;
 62	}
 63
 64	return &debugger->d;
 65}
 66
 67void mDebuggerAttach(struct mDebugger* debugger, struct mCore* core) {
 68	debugger->d.id = DEBUGGER_ID;
 69	debugger->d.init = mDebuggerInit;
 70	debugger->d.deinit = mDebuggerDeinit;
 71	debugger->core = core;
 72	debugger->platform = core->debuggerPlatform(core);
 73	debugger->platform->p = debugger;
 74	core->attachDebugger(core, debugger);
 75}
 76
 77void mDebuggerRun(struct mDebugger* debugger) {
 78	switch (debugger->state) {
 79	case DEBUGGER_RUNNING:
 80		if (!debugger->platform->hasBreakpoints(debugger->platform)) {
 81			debugger->core->runLoop(debugger->core);
 82		} else {
 83			debugger->core->step(debugger->core);
 84			debugger->platform->checkBreakpoints(debugger->platform);
 85		}
 86		break;
 87	case DEBUGGER_CUSTOM:
 88		debugger->core->step(debugger->core);
 89		debugger->platform->checkBreakpoints(debugger->platform);
 90		debugger->custom(debugger);
 91		break;
 92	case DEBUGGER_PAUSED:
 93		if (debugger->paused) {
 94			debugger->paused(debugger);
 95		} else {
 96			debugger->state = DEBUGGER_RUNNING;
 97		}
 98		break;
 99	case DEBUGGER_SHUTDOWN:
100		return;
101	}
102}
103
104void mDebuggerEnter(struct mDebugger* debugger, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
105	debugger->state = DEBUGGER_PAUSED;
106	if (debugger->entered) {
107		debugger->entered(debugger, reason, info);
108	}
109}
110
111static void mDebuggerInit(void* cpu, struct mCPUComponent* component) {
112	struct mDebugger* debugger = (struct mDebugger*) component;
113	debugger->state = DEBUGGER_RUNNING;
114	debugger->platform->init(cpu, debugger->platform);
115	if (debugger->init) {
116		debugger->init(debugger);
117	}
118}
119
120static void mDebuggerDeinit(struct mCPUComponent* component) {
121	struct mDebugger* debugger = (struct mDebugger*) component;
122	if (debugger->deinit) {
123		debugger->deinit(debugger);
124	}
125	debugger->platform->deinit(debugger->platform);
126}