static void _checkBreakpoints(struct ARMDebugger* debugger) { int instructionLength; enum ExecutionMode mode = debugger->cpu->cpsr.t; if (mode == MODE_ARM) { instructionLength = WORD_SIZE_ARM; } else { instructionLength = WORD_SIZE_THUMB; } struct DebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu->gprs[ARM_PC] - instructionLength); if (!breakpoint) { return; } struct DebuggerEntryInfo info = { .address = breakpoint->address }; ARMDebuggerEnter(debugger, DEBUGGER_ENTER_BREAKPOINT, &info); } static void ARMDebuggerInit(struct ARMCore*, struct ARMComponent*); static void ARMDebuggerDeinit(struct ARMComponent*); void ARMDebuggerCreate(struct ARMDebugger* debugger) { debugger->d.id = ARM_DEBUGGER_ID; debugger->d.init = ARMDebuggerInit; debugger->d.deinit = ARMDebuggerDeinit; }
static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; struct LR35902DebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu->pc - 1); if (!breakpoint) { return; } // TODO: Segments struct mDebuggerEntryInfo info = { .address = breakpoint->address }; mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info); } static void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform); static void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform); static void LR35902DebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info); static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address); static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address); static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform*); static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform*); struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void) { struct mDebuggerPlatform* platform = (struct mDebuggerPlatform*) malloc(sizeof(struct LR35902Debugger)); platform->entered = LR35902DebuggerEnter; platform->init = LR35902DebuggerInit; platform->deinit = LR35902DebuggerDeinit; platform->setBreakpoint = LR35902DebuggerSetBreakpoint; platform->clearBreakpoint = LR35902DebuggerClearBreakpoint; platform->setWatchpoint = NULL; platform->clearWatchpoint = NULL; platform->checkBreakpoints = LR35902DebuggerCheckBreakpoints; platform->hasBreakpoints = LR35902DebuggerHasBreakpoints; return platform; } void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform; debugger->cpu = cpu; LR35902DebugBreakpointListInit(&debugger->breakpoints, 0); LR35902DebugWatchpointListInit(&debugger->watchpoints, 0); } void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform; LR35902DebugBreakpointListDeinit(&debugger->breakpoints); LR35902DebugWatchpointListDeinit(&debugger->watchpoints); } static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) { UNUSED(reason); UNUSED(info); struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform; struct LR35902Core* cpu = debugger->cpu; cpu->nextEvent = cpu->cycles; }
void ARMDebuggerEnter(struct ARMDebugger* debugger, enum DebuggerEntryReason reason, struct DebuggerEntryInfo* info) { debugger->state = DEBUGGER_PAUSED; struct ARMCore* cpu = debugger->cpu; cpu->nextEvent = cpu->cycles; if (reason == DEBUGGER_ENTER_BREAKPOINT) { struct DebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->swBreakpoints, _ARMPCAddress(cpu)); debugger->currentBreakpoint = breakpoint; if (breakpoint && breakpoint->isSw) { info->address = breakpoint->address; if (debugger->clearSoftwareBreakpoint) { debugger->clearSoftwareBreakpoint(debugger, breakpoint->address, breakpoint->sw.mode, breakpoint->sw.opcode); } ARMRunFake(cpu, breakpoint->sw.opcode); } } if (debugger->entered) { debugger->entered(debugger, reason, info); } }