all repos — mgba @ a0d223eef7c33382231510db9c851f856c891323

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#include "debugger/cli-debugger.h"
 11
 12#ifdef USE_GDB_STUB
 13#include "debugger/gdb-stub.h"
 14#endif
 15
 16const uint32_t DEBUGGER_ID = 0xDEADBEEF;
 17
 18mLOG_DEFINE_CATEGORY(DEBUGGER, "Debugger");
 19
 20static void mDebuggerInit(void* cpu, struct mCPUComponent* component);
 21static void mDebuggerDeinit(struct mCPUComponent* component);
 22
 23struct mDebugger* mDebuggerCreate(enum mDebuggerType type, struct mCore* core) {
 24	if (!core->supportsDebuggerType(core, type)) {
 25		return NULL;
 26	}
 27
 28	union DebugUnion {
 29		struct mDebugger d;
 30		struct CLIDebugger cli;
 31#ifdef USE_GDB_STUB
 32		struct GDBStub gdb;
 33#endif
 34	};
 35
 36	union DebugUnion* debugger = malloc(sizeof(union DebugUnion));
 37
 38	switch (type) {
 39	case DEBUGGER_CLI:
 40		CLIDebuggerCreate(&debugger->cli);
 41		struct CLIDebuggerSystem* sys = core->cliDebuggerSystem(core);
 42		CLIDebuggerAttachSystem(&debugger->cli, sys);
 43		break;
 44#ifdef USE_GDB_STUB
 45	case DEBUGGER_GDB:
 46		GDBStubCreate(&debugger->gdb);
 47		GDBStubListen(&debugger->gdb, 2345, 0);
 48		break;
 49#endif
 50	case DEBUGGER_NONE:
 51	case DEBUGGER_MAX:
 52		free(debugger);
 53		return 0;
 54		break;
 55	}
 56
 57	return &debugger->d;
 58}
 59
 60void mDebuggerAttach(struct mDebugger* debugger, struct mCore* core) {
 61	debugger->d.id = DEBUGGER_ID;
 62	debugger->d.init = mDebuggerInit;
 63	debugger->d.deinit = mDebuggerDeinit;
 64	debugger->core = core;
 65	debugger->platform = core->debuggerPlatform(core);
 66	debugger->platform->p = debugger;
 67	core->attachDebugger(core, debugger);
 68}
 69
 70void mDebuggerRun(struct mDebugger* debugger) {
 71	switch (debugger->state) {
 72	case DEBUGGER_RUNNING:
 73		if (!debugger->platform->hasBreakpoints(debugger->platform)) {
 74			debugger->core->runLoop(debugger->core);
 75		} else {
 76			debugger->core->step(debugger->core);
 77			debugger->platform->checkBreakpoints(debugger->platform);
 78		}
 79		break;
 80	case DEBUGGER_CUSTOM:
 81		debugger->core->step(debugger->core);
 82		debugger->platform->checkBreakpoints(debugger->platform);
 83		debugger->custom(debugger);
 84		break;
 85	case DEBUGGER_PAUSED:
 86		if (debugger->paused) {
 87			debugger->paused(debugger);
 88		} else {
 89			debugger->state = DEBUGGER_RUNNING;
 90		}
 91		break;
 92	case DEBUGGER_SHUTDOWN:
 93		return;
 94	}
 95}
 96
 97void mDebuggerEnter(struct mDebugger* debugger, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
 98	debugger->state = DEBUGGER_PAUSED;
 99	if (debugger->platform->entered) {
100		debugger->platform->entered(debugger->platform, reason, info);
101	}
102}
103
104static void mDebuggerInit(void* cpu, struct mCPUComponent* component) {
105	struct mDebugger* debugger = (struct mDebugger*) component;
106	debugger->state = DEBUGGER_RUNNING;
107	debugger->platform->init(cpu, debugger->platform);
108	if (debugger->init) {
109		debugger->init(debugger);
110	}
111}
112
113static void mDebuggerDeinit(struct mCPUComponent* component) {
114	struct mDebugger* debugger = (struct mDebugger*) component;
115	if (debugger->deinit) {
116		debugger->deinit(debugger);
117	}
118	debugger->platform->deinit(debugger->platform);
119}