all repos — mgba @ fff0e9b83cbab7934ecaf0f0e6376677b9109495

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