mirror of https://github.com/mgba-emu/mgba.git
Debugger: Add ARMIPS symbol table loading
This commit is contained in:
parent
2c6715d78f
commit
0b47bb1204
1
CHANGES
1
CHANGES
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue