Debugger: Add ARMIPS symbol table loading

This commit is contained in:
Vicki Pfau 2018-08-30 18:56:13 -07:00
parent 2c6715d78f
commit 0b47bb1204
5 changed files with 63 additions and 5 deletions

View File

@ -16,6 +16,7 @@ Features:
- Optional automatic state saving/loading - Optional automatic state saving/loading
- Access to ur0 and uma0 partitions on the Vita - Access to ur0 and uma0 partitions on the Vita
- Partial support for MBC6, MMM01, TAMA and HuC-1 GB mappers - Partial support for MBC6, MMM01, TAMA and HuC-1 GB mappers
- GBA: ARMIPS/A22i-style and ELF symbol table support
Bugfixes: Bugfixes:
- GB Audio: Make audio unsigned with bias (fixes mgba.io/i/749) - GB Audio: Make audio unsigned with bias (fixes mgba.io/i/749)
- GB Serialize: Fix audio state loading - GB Serialize: Fix audio state loading

View File

@ -20,6 +20,9 @@ bool mDebuggerSymbolLookup(const struct mDebuggerSymbols*, const char* name, int
void mDebuggerSymbolAdd(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); void mDebuggerSymbolRemove(struct mDebuggerSymbols*, const char* name);
struct VFile;
void mDebuggerLoadARMIPSSymbols(struct mDebuggerSymbols*, struct VFile* vf);
CXX_GUARD_END CXX_GUARD_END
#endif #endif

View File

@ -5,7 +5,9 @@
* 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/symbols.h> #include <mgba/internal/debugger/symbols.h>
#include <mgba-util/string.h>
#include <mgba-util/table.h> #include <mgba-util/table.h>
#include <mgba-util/vfs.h>
struct mDebuggerSymbol { struct mDebuggerSymbol {
int32_t value; int32_t value;
@ -47,3 +49,40 @@ void mDebuggerSymbolAdd(struct mDebuggerSymbols* st, const char* name, int32_t v
void mDebuggerSymbolRemove(struct mDebuggerSymbols* st, const char* name) { void mDebuggerSymbolRemove(struct mDebuggerSymbols* st, const char* name) {
HashTableRemove(&st->names, name); HashTableRemove(&st->names, name);
} }
void mDebuggerLoadARMIPSSymbols(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';
}
uint32_t address = 0;
const char* buf = line;
buf = hex32(buf, &address);
if (!buf) {
continue;
}
bytesRead -= 8;
while (isspace((int) buf[0]) && bytesRead > 0) {
--bytesRead;
++buf;
}
if (!bytesRead) {
continue;
}
if (buf[0] == '.') {
// Directives are not handled yet
continue;
}
mDebuggerSymbolAdd(st, buf, address, -1);
}
}

View File

@ -25,13 +25,14 @@ void GBLoadSymbols(struct mDebuggerSymbols* st, struct VFile* vf) {
uint8_t byte; uint8_t byte;
const char* buf = line; const char* buf = line;
while (buf) { while (buf && bytesRead >= 2) {
buf = hex8(buf, &byte); buf = hex8(buf, &byte);
if (!buf) { if (!buf) {
break; break;
} }
address <<= 8; address <<= 8;
address += byte; address += byte;
bytesRead -= 2;
if (buf[0] == ':') { if (buf[0] == ':') {
segment = address; segment = address;
@ -42,14 +43,19 @@ void GBLoadSymbols(struct mDebuggerSymbols* st, struct VFile* vf) {
break; break;
} }
} }
if (!buf) { if (!buf || bytesRead < 1) {
continue; continue;
} }
while (isspace((int) buf[0])) { while (isspace((int) buf[0]) && bytesRead > 0) {
--bytesRead;
++buf; ++buf;
} }
if (!bytesRead) {
continue;
}
mDebuggerSymbolAdd(st, buf, address, segment); mDebuggerSymbolAdd(st, buf, address, segment);
} }
} }

View File

@ -702,29 +702,38 @@ static void _GBACoreDetachDebugger(struct mCore* core) {
} }
static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) {
#ifdef USE_ELF
bool closeAfter = false; bool closeAfter = false;
core->symbolTable = mDebuggerSymbolTableCreate(); core->symbolTable = mDebuggerSymbolTableCreate();
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
#ifdef USE_ELF
if (!vf) { if (!vf) {
closeAfter = true; closeAfter = true;
vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".elf", O_RDONLY); vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".elf", O_RDONLY);
} }
#endif
if (!vf) {
closeAfter = true;
vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY);
}
#endif #endif
if (!vf) { if (!vf) {
return; return;
} }
#ifdef USE_ELF
struct ELF* elf = ELFOpen(vf); struct ELF* elf = ELFOpen(vf);
if (elf) { if (elf) {
#ifdef USE_DEBUGGERS #ifdef USE_DEBUGGERS
mCoreLoadELFSymbols(core->symbolTable, elf); mCoreLoadELFSymbols(core->symbolTable, elf);
#endif #endif
ELFClose(elf); ELFClose(elf);
} else
#endif
{
mDebuggerLoadARMIPSSymbols(core->symbolTable, vf);
} }
if (closeAfter) { if (closeAfter) {
vf->close(vf); vf->close(vf);
} }
#endif
} }
static bool _GBACoreLookupIdentifier(struct mCore* core, const char* name, int32_t* value, int* segment) { static bool _GBACoreLookupIdentifier(struct mCore* core, const char* name, int32_t* value, int* segment) {