1 /* Copyright (c) 2013-2019 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 #ifndef DEBUGGER_H 7 #define DEBUGGER_H 8 9 #include <mgba-util/common.h> 10 11 CXX_GUARD_START 12 13 #include <mgba/core/cpu.h> 14 #include <mgba/core/log.h> 15 #include <mgba-util/vector.h> 16 #include <mgba/internal/debugger/stack-trace.h> 17 18 mLOG_DECLARE_CATEGORY(DEBUGGER); 19 20 extern const uint32_t DEBUGGER_ID; 21 22 enum mDebuggerType { 23 DEBUGGER_NONE = 0, 24 DEBUGGER_CUSTOM, 25 DEBUGGER_CLI, 26 DEBUGGER_GDB, 27 DEBUGGER_MAX 28 }; 29 30 enum mDebuggerState { 31 DEBUGGER_PAUSED, 32 DEBUGGER_RUNNING, 33 DEBUGGER_CALLBACK, 34 DEBUGGER_SHUTDOWN 35 }; 36 37 enum mWatchpointType { 38 WATCHPOINT_WRITE = 1, 39 WATCHPOINT_READ = 2, 40 WATCHPOINT_RW = 3, 41 WATCHPOINT_CHANGE = 4, 42 WATCHPOINT_WRITE_CHANGE = 5, 43 }; 44 45 enum mBreakpointType { 46 BREAKPOINT_HARDWARE, 47 BREAKPOINT_SOFTWARE 48 }; 49 50 enum mDebuggerEntryReason { 51 DEBUGGER_ENTER_MANUAL, 52 DEBUGGER_ENTER_ATTACHED, 53 DEBUGGER_ENTER_BREAKPOINT, 54 DEBUGGER_ENTER_WATCHPOINT, 55 DEBUGGER_ENTER_ILLEGAL_OP, 56 DEBUGGER_ENTER_STACK 57 }; 58 59 struct mDebuggerEntryInfo { 60 uint32_t address; 61 union { 62 struct { 63 uint32_t oldValue; 64 uint32_t newValue; 65 enum mWatchpointType watchType; 66 enum mWatchpointType accessType; 67 } wp; 68 69 struct { 70 uint32_t opcode; 71 enum mBreakpointType breakType; 72 } bp; 73 74 struct { 75 enum mStackTraceMode traceType; 76 } st; 77 } type; 78 ssize_t pointId; 79 }; 80 81 struct mBreakpoint { 82 ssize_t id; 83 uint32_t address; 84 int segment; 85 enum mBreakpointType type; 86 struct ParseTree* condition; 87 }; 88 89 struct mWatchpoint { 90 ssize_t id; 91 uint32_t address; 92 int segment; 93 enum mWatchpointType type; 94 struct ParseTree* condition; 95 }; 96 97 DECLARE_VECTOR(mBreakpointList, struct mBreakpoint); 98 DECLARE_VECTOR(mWatchpointList, struct mWatchpoint); 99 100 struct mDebugger; 101 struct ParseTree; 102 struct mDebuggerPlatform { 103 struct mDebugger* p; 104 105 void (*init)(void* cpu, struct mDebuggerPlatform*); 106 void (*deinit)(struct mDebuggerPlatform*); 107 void (*entered)(struct mDebuggerPlatform*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); 108 109 bool (*hasBreakpoints)(struct mDebuggerPlatform*); 110 void (*checkBreakpoints)(struct mDebuggerPlatform*); 111 bool (*clearBreakpoint)(struct mDebuggerPlatform*, ssize_t id); 112 113 ssize_t (*setBreakpoint)(struct mDebuggerPlatform*, const struct mBreakpoint*); 114 void (*listBreakpoints)(struct mDebuggerPlatform*, struct mBreakpointList*); 115 116 ssize_t (*setWatchpoint)(struct mDebuggerPlatform*, const struct mWatchpoint*); 117 void (*listWatchpoints)(struct mDebuggerPlatform*, struct mWatchpointList*); 118 119 void (*trace)(struct mDebuggerPlatform*, char* out, size_t* length); 120 121 bool (*getRegister)(struct mDebuggerPlatform*, const char* name, int32_t* value); 122 bool (*setRegister)(struct mDebuggerPlatform*, const char* name, int32_t value); 123 bool (*lookupIdentifier)(struct mDebuggerPlatform*, const char* name, int32_t* value, int* segment); 124 125 uint32_t (*getStackTraceMode)(struct mDebuggerPlatform*); 126 void (*setStackTraceMode)(struct mDebuggerPlatform*, uint32_t mode); 127 bool (*updateStackTrace)(struct mDebuggerPlatform* d); 128 }; 129 130 struct mDebugger { 131 struct mCPUComponent d; 132 struct mDebuggerPlatform* platform; 133 enum mDebuggerState state; 134 enum mDebuggerType type; 135 struct mCore* core; 136 struct mScriptBridge* bridge; 137 struct mStackTrace stackTrace; 138 139 void (*init)(struct mDebugger*); 140 void (*deinit)(struct mDebugger*); 141 142 void (*paused)(struct mDebugger*); 143 void (*entered)(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); 144 void (*custom)(struct mDebugger*); 145 }; 146 147 struct mDebugger* mDebuggerCreate(enum mDebuggerType type, struct mCore*); 148 void mDebuggerAttach(struct mDebugger*, struct mCore*); 149 void mDebuggerRun(struct mDebugger*); 150 void mDebuggerRunFrame(struct mDebugger*); 151 void mDebuggerEnter(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); 152 153 bool mDebuggerLookupIdentifier(struct mDebugger* debugger, const char* name, int32_t* value, int* segment); 154 155 CXX_GUARD_END 156 157 #endif 158