mirror of https://github.com/mgba-emu/mgba.git
Debugger: Add symbol table skeleton, GB support
This commit is contained in:
parent
0b28dad51c
commit
404332e689
|
@ -395,6 +395,7 @@ find_feature(USE_SQLITE3 "sqlite3")
|
||||||
set(DEBUGGER_SRC
|
set(DEBUGGER_SRC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/debugger.c
|
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/debugger.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/parser.c
|
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/parser.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/symbols.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/cli-debugger.c)
|
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/cli-debugger.c)
|
||||||
|
|
||||||
set(FEATURE_SRC)
|
set(FEATURE_SRC)
|
||||||
|
@ -603,7 +604,8 @@ if(M_CORE_GB)
|
||||||
list(APPEND DEBUGGER_SRC
|
list(APPEND DEBUGGER_SRC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/cli-debugger.c
|
${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/cli-debugger.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/debugger.c
|
${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/debugger.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/cli.c)
|
${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/cli.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/symbols.c)
|
||||||
list(APPEND TEST_SRC
|
list(APPEND TEST_SRC
|
||||||
${LR35902_TEST_SRC}
|
${LR35902_TEST_SRC}
|
||||||
${GB_TEST_SRC})
|
${GB_TEST_SRC})
|
||||||
|
|
|
@ -39,12 +39,14 @@ enum mCoreChecksumType {
|
||||||
|
|
||||||
struct mCoreConfig;
|
struct mCoreConfig;
|
||||||
struct mCoreSync;
|
struct mCoreSync;
|
||||||
|
struct mDebuggerSymbols;
|
||||||
struct mStateExtdata;
|
struct mStateExtdata;
|
||||||
struct mVideoLogContext;
|
struct mVideoLogContext;
|
||||||
struct mCore {
|
struct mCore {
|
||||||
void* cpu;
|
void* cpu;
|
||||||
void* board;
|
void* board;
|
||||||
struct mDebugger* debugger;
|
struct mDebugger* debugger;
|
||||||
|
struct mDebuggerSymbols* symbolTable;
|
||||||
|
|
||||||
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
||||||
struct mDirectorySet dirs;
|
struct mDirectorySet dirs;
|
||||||
|
@ -135,6 +137,8 @@ struct mCore {
|
||||||
struct CLIDebuggerSystem* (*cliDebuggerSystem)(struct mCore*);
|
struct CLIDebuggerSystem* (*cliDebuggerSystem)(struct mCore*);
|
||||||
void (*attachDebugger)(struct mCore*, struct mDebugger*);
|
void (*attachDebugger)(struct mCore*, struct mDebugger*);
|
||||||
void (*detachDebugger)(struct mCore*);
|
void (*detachDebugger)(struct mCore*);
|
||||||
|
|
||||||
|
void (*loadSymbols)(struct mCore*, struct VFile*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct mCheatDevice* (*cheatDevice)(struct mCore*);
|
struct mCheatDevice* (*cheatDevice)(struct mCore*);
|
||||||
|
|
|
@ -94,6 +94,7 @@ struct mDebuggerPlatform {
|
||||||
void (*checkBreakpoints)(struct mDebuggerPlatform*);
|
void (*checkBreakpoints)(struct mDebuggerPlatform*);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mDebuggerSymbols;
|
||||||
struct mDebugger {
|
struct mDebugger {
|
||||||
struct mCPUComponent d;
|
struct mCPUComponent d;
|
||||||
struct mDebuggerPlatform* platform;
|
struct mDebuggerPlatform* platform;
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* Copyright (c) 2013-2017 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#ifndef DEBUGGER_SYMBOLS_H
|
||||||
|
#define DEBUGGER_SYMBOLS_H
|
||||||
|
|
||||||
|
#include <mgba-util/common.h>
|
||||||
|
|
||||||
|
CXX_GUARD_START
|
||||||
|
|
||||||
|
struct mDebuggerSymbols;
|
||||||
|
|
||||||
|
struct mDebuggerSymbols* mDebuggerSymbolTableCreate(void);
|
||||||
|
void mDebuggerSymbolTableDestroy(struct mDebuggerSymbols*);
|
||||||
|
|
||||||
|
bool mDebuggerSymbolLookup(const struct mDebuggerSymbols*, const char* name, int32_t* value, int* segment);
|
||||||
|
|
||||||
|
void mDebuggerSymbolAdd(struct mDebuggerSymbols*, const char* name, int32_t value, int segment);
|
||||||
|
void mDebuggerSymbolRemove(struct mDebuggerSymbols*, const char* name);
|
||||||
|
|
||||||
|
CXX_GUARD_END
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* Copyright (c) 2013-2017 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#ifndef GB_SYMBOLS_H
|
||||||
|
#define GB_SYMBOLS_H
|
||||||
|
|
||||||
|
#include <mgba-util/common.h>
|
||||||
|
|
||||||
|
CXX_GUARD_START
|
||||||
|
|
||||||
|
struct mDebuggerSymbols;
|
||||||
|
struct VFile;
|
||||||
|
void GBLoadSymbols(struct mDebuggerSymbols*, struct VFile* vf);
|
||||||
|
|
||||||
|
CXX_GUARD_END
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,6 +5,8 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
#include <mgba/internal/debugger/cli-debugger.h>
|
#include <mgba/internal/debugger/cli-debugger.h>
|
||||||
|
|
||||||
|
#include <mgba/internal/debugger/symbols.h>
|
||||||
|
|
||||||
#include <mgba/core/core.h>
|
#include <mgba/core/core.h>
|
||||||
#include <mgba/core/version.h>
|
#include <mgba/core/version.h>
|
||||||
#include <mgba/internal/debugger/parser.h>
|
#include <mgba/internal/debugger/parser.h>
|
||||||
|
@ -497,7 +499,11 @@ static uint32_t _performOperation(enum Operation operation, uint32_t current, ui
|
||||||
static void _lookupIdentifier(struct mDebugger* debugger, const char* name, struct CLIDebugVector* dv) {
|
static void _lookupIdentifier(struct mDebugger* debugger, const char* name, struct CLIDebugVector* dv) {
|
||||||
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
|
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
|
||||||
if (cliDebugger->system) {
|
if (cliDebugger->system) {
|
||||||
uint32_t value = cliDebugger->system->lookupPlatformIdentifier(cliDebugger->system, name, dv);
|
uint32_t value;
|
||||||
|
if (debugger->core->symbolTable && mDebuggerSymbolLookup(debugger->core->symbolTable, name, &dv->intValue, &dv->segmentValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
value = cliDebugger->system->lookupPlatformIdentifier(cliDebugger->system, name, dv);
|
||||||
if (dv->type != CLIDV_ERROR_TYPE) {
|
if (dv->type != CLIDV_ERROR_TYPE) {
|
||||||
dv->intValue = value;
|
dv->intValue = value;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -62,6 +62,9 @@ void mDebuggerAttach(struct mDebugger* debugger, struct mCore* core) {
|
||||||
debugger->d.init = mDebuggerInit;
|
debugger->d.init = mDebuggerInit;
|
||||||
debugger->d.deinit = mDebuggerDeinit;
|
debugger->d.deinit = mDebuggerDeinit;
|
||||||
debugger->core = core;
|
debugger->core = core;
|
||||||
|
if (!debugger->core->symbolTable) {
|
||||||
|
debugger->core->loadSymbols(debugger->core, NULL);
|
||||||
|
}
|
||||||
debugger->platform = core->debuggerPlatform(core);
|
debugger->platform = core->debuggerPlatform(core);
|
||||||
debugger->platform->p = debugger;
|
debugger->platform->p = debugger;
|
||||||
core->attachDebugger(core, debugger);
|
core->attachDebugger(core, debugger);
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* Copyright (c) 2013-2017 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include <mgba/internal/debugger/symbols.h>
|
||||||
|
|
||||||
|
#include <mgba-util/table.h>
|
||||||
|
|
||||||
|
struct mDebuggerSymbol {
|
||||||
|
int32_t value;
|
||||||
|
int segment;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mDebuggerSymbols {
|
||||||
|
struct Table names;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mDebuggerSymbols* mDebuggerSymbolTableCreate(void) {
|
||||||
|
struct mDebuggerSymbols* st = malloc(sizeof(*st));
|
||||||
|
HashTableInit(&st->names, 0, free);
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mDebuggerSymbolTableDestroy(struct mDebuggerSymbols* st) {
|
||||||
|
HashTableDeinit(&st->names);
|
||||||
|
free(st);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mDebuggerSymbolLookup(const struct mDebuggerSymbols* st, const char* name, int32_t* value, int* segment) {
|
||||||
|
struct mDebuggerSymbol* sym = HashTableLookup(&st->names, name);
|
||||||
|
if (!sym) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*value = sym->value;
|
||||||
|
*segment = sym->segment;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mDebuggerSymbolAdd(struct mDebuggerSymbols* st, const char* name, int32_t value, int segment) {
|
||||||
|
struct mDebuggerSymbol* sym = malloc(sizeof(*sym));
|
||||||
|
sym->value = value;
|
||||||
|
sym->segment = segment;
|
||||||
|
HashTableInsert(&st->names, name, sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mDebuggerSymbolRemove(struct mDebuggerSymbols* st, const char* name) {
|
||||||
|
HashTableRemove(&st->names, name);
|
||||||
|
}
|
|
@ -6,7 +6,9 @@
|
||||||
#include <mgba/gb/core.h>
|
#include <mgba/gb/core.h>
|
||||||
|
|
||||||
#include <mgba/core/core.h>
|
#include <mgba/core/core.h>
|
||||||
|
#include <mgba/internal/debugger/symbols.h>
|
||||||
#include <mgba/internal/gb/cheats.h>
|
#include <mgba/internal/gb/cheats.h>
|
||||||
|
#include <mgba/internal/gb/debugger/symbols.h>
|
||||||
#include <mgba/internal/gb/extra/cli.h>
|
#include <mgba/internal/gb/extra/cli.h>
|
||||||
#include <mgba/internal/gb/io.h>
|
#include <mgba/internal/gb/io.h>
|
||||||
#include <mgba/internal/gb/gb.h>
|
#include <mgba/internal/gb/gb.h>
|
||||||
|
@ -90,8 +92,11 @@ static void _GBCoreDeinit(struct mCore* core) {
|
||||||
GBDestroy(core->board);
|
GBDestroy(core->board);
|
||||||
mappedMemoryFree(core->cpu, sizeof(struct LR35902Core));
|
mappedMemoryFree(core->cpu, sizeof(struct LR35902Core));
|
||||||
mappedMemoryFree(core->board, sizeof(struct GB));
|
mappedMemoryFree(core->board, sizeof(struct GB));
|
||||||
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
#if defined USE_DEBUGGERS && (!defined(MINIMAL_CORE) || MINIMAL_CORE < 2)
|
||||||
mDirectorySetDeinit(&core->dirs);
|
mDirectorySetDeinit(&core->dirs);
|
||||||
|
if (core->symbolTable) {
|
||||||
|
mDebuggerSymbolTableDestroy(core->symbolTable);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct GBCore* gbcore = (struct GBCore*) core;
|
struct GBCore* gbcore = (struct GBCore*) core;
|
||||||
|
@ -552,6 +557,19 @@ static void _GBCoreDetachDebugger(struct mCore* core) {
|
||||||
cpu->components[CPU_COMPONENT_DEBUGGER] = NULL;
|
cpu->components[CPU_COMPONENT_DEBUGGER] = NULL;
|
||||||
core->debugger = NULL;
|
core->debugger = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _GBCoreLoadSymbols(struct mCore* core, struct VFile* vf) {
|
||||||
|
core->symbolTable = mDebuggerSymbolTableCreate();
|
||||||
|
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
||||||
|
if (!vf) {
|
||||||
|
vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!vf) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GBLoadSymbols(core->symbolTable, vf);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct mCheatDevice* _GBCoreCheatDevice(struct mCore* core) {
|
static struct mCheatDevice* _GBCoreCheatDevice(struct mCore* core) {
|
||||||
|
@ -671,6 +689,7 @@ struct mCore* GBCoreCreate(void) {
|
||||||
core->cpu = NULL;
|
core->cpu = NULL;
|
||||||
core->board = NULL;
|
core->board = NULL;
|
||||||
core->debugger = NULL;
|
core->debugger = NULL;
|
||||||
|
core->symbolTable = NULL;
|
||||||
core->init = _GBCoreInit;
|
core->init = _GBCoreInit;
|
||||||
core->deinit = _GBCoreDeinit;
|
core->deinit = _GBCoreDeinit;
|
||||||
core->platform = _GBCorePlatform;
|
core->platform = _GBCorePlatform;
|
||||||
|
@ -728,6 +747,7 @@ struct mCore* GBCoreCreate(void) {
|
||||||
core->cliDebuggerSystem = _GBCoreCliDebuggerSystem;
|
core->cliDebuggerSystem = _GBCoreCliDebuggerSystem;
|
||||||
core->attachDebugger = _GBCoreAttachDebugger;
|
core->attachDebugger = _GBCoreAttachDebugger;
|
||||||
core->detachDebugger = _GBCoreDetachDebugger;
|
core->detachDebugger = _GBCoreDetachDebugger;
|
||||||
|
core->loadSymbols = _GBCoreLoadSymbols;
|
||||||
#endif
|
#endif
|
||||||
core->cheatDevice = _GBCoreCheatDevice;
|
core->cheatDevice = _GBCoreCheatDevice;
|
||||||
core->savedataClone = _GBCoreSavedataClone;
|
core->savedataClone = _GBCoreSavedataClone;
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* Copyright (c) 2013-2016 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include <mgba/internal/gb/debugger/symbols.h>
|
||||||
|
|
||||||
|
#include <mgba/internal/debugger/symbols.h>
|
||||||
|
#include <mgba-util/string.h>
|
||||||
|
#include <mgba-util/vfs.h>
|
||||||
|
|
||||||
|
void GBLoadSymbols(struct mDebuggerSymbols* st, struct VFile* vf) {
|
||||||
|
char line[512];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
ssize_t bytesRead = vf->readline(vf, line, sizeof(line));
|
||||||
|
if (bytesRead <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (line[bytesRead - 1] == '\n') {
|
||||||
|
line[bytesRead - 1] = '\0';
|
||||||
|
}
|
||||||
|
int segment = -1;
|
||||||
|
uint32_t address = 0;
|
||||||
|
|
||||||
|
uint8_t byte;
|
||||||
|
const char* buf = line;
|
||||||
|
while (buf) {
|
||||||
|
buf = hex8(buf, &byte);
|
||||||
|
if (!buf) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
address <<= 8;
|
||||||
|
address += byte;
|
||||||
|
|
||||||
|
if (buf[0] == ':') {
|
||||||
|
segment = address;
|
||||||
|
address = 0;
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
if (isspace((int) buf[0])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!buf) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (isspace((int) buf[0])) {
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDebuggerSymbolAdd(st, buf, address, segment);
|
||||||
|
}
|
||||||
|
}
|
|
@ -72,6 +72,7 @@ static bool _GBACoreInit(struct mCore* core) {
|
||||||
core->cpu = cpu;
|
core->cpu = cpu;
|
||||||
core->board = gba;
|
core->board = gba;
|
||||||
core->debugger = NULL;
|
core->debugger = NULL;
|
||||||
|
core->symbolTable = NULL;
|
||||||
gbacore->overrides = NULL;
|
gbacore->overrides = NULL;
|
||||||
gbacore->debuggerPlatform = NULL;
|
gbacore->debuggerPlatform = NULL;
|
||||||
gbacore->cheatDevice = NULL;
|
gbacore->cheatDevice = NULL;
|
||||||
|
@ -555,6 +556,10 @@ static void _GBACoreDetachDebugger(struct mCore* core) {
|
||||||
GBADetachDebugger(core->board);
|
GBADetachDebugger(core->board);
|
||||||
core->debugger = NULL;
|
core->debugger = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct mCheatDevice* _GBACoreCheatDevice(struct mCore* core) {
|
static struct mCheatDevice* _GBACoreCheatDevice(struct mCore* core) {
|
||||||
|
@ -747,6 +752,7 @@ struct mCore* GBACoreCreate(void) {
|
||||||
core->cliDebuggerSystem = _GBACoreCliDebuggerSystem;
|
core->cliDebuggerSystem = _GBACoreCliDebuggerSystem;
|
||||||
core->attachDebugger = _GBACoreAttachDebugger;
|
core->attachDebugger = _GBACoreAttachDebugger;
|
||||||
core->detachDebugger = _GBACoreDetachDebugger;
|
core->detachDebugger = _GBACoreDetachDebugger;
|
||||||
|
core->loadSymbols = _GBACoreLoadSymbols;
|
||||||
#endif
|
#endif
|
||||||
core->cheatDevice = _GBACoreCheatDevice;
|
core->cheatDevice = _GBACoreCheatDevice;
|
||||||
core->savedataClone = _GBACoreSavedataClone;
|
core->savedataClone = _GBACoreSavedataClone;
|
||||||
|
|
Loading…
Reference in New Issue