all repos — mgba @ b7999071434ad01e8566562f58aec172ff165847

mGBA Game Boy Advance Emulator

src/debugger/symbols.c (view raw)

  1/* Copyright (c) 2013-2017 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#include <mgba/internal/debugger/symbols.h>
  7
  8#include <mgba-util/string.h>
  9#include <mgba-util/table.h>
 10#include <mgba-util/hash.h>
 11#include <mgba-util/vfs.h>
 12
 13struct mDebuggerSymbol {
 14	int32_t value;
 15	int segment;
 16};
 17
 18struct mDebuggerSymbols {
 19	struct Table names;
 20	struct Table reverse;
 21};
 22
 23struct mDebuggerSymbols* mDebuggerSymbolTableCreate(void) {
 24	struct mDebuggerSymbols* st = malloc(sizeof(*st));
 25	HashTableInit(&st->names, 0, free);
 26	HashTableInit(&st->reverse, 0, free);
 27	return st;
 28}
 29
 30void mDebuggerSymbolTableDestroy(struct mDebuggerSymbols* st) {
 31	HashTableDeinit(&st->names);
 32	HashTableDeinit(&st->reverse);
 33	free(st);
 34}
 35
 36bool mDebuggerSymbolLookup(const struct mDebuggerSymbols* st, const char* name, int32_t* value, int* segment) {
 37	struct mDebuggerSymbol* sym = HashTableLookup(&st->names, name);
 38	if (!sym) {
 39		return false;
 40	}
 41	*value = sym->value;
 42	*segment = sym->segment;
 43	return true;
 44}
 45
 46const char* mDebuggerSymbolReverseLookup(const struct mDebuggerSymbols* st, int32_t value, int segment) {
 47	struct mDebuggerSymbol sym = { value, segment };
 48	return HashTableLookupBinary(&st->reverse, &sym, sizeof(sym));
 49}
 50
 51void mDebuggerSymbolAdd(struct mDebuggerSymbols* st, const char* name, int32_t value, int segment) {
 52	struct mDebuggerSymbol* sym = malloc(sizeof(*sym));
 53	sym->value = value;
 54	sym->segment = segment;
 55	HashTableInsert(&st->names, name, sym);
 56	HashTableInsertBinary(&st->reverse, sym, sizeof(*sym), strdup(name));
 57}
 58
 59void mDebuggerSymbolRemove(struct mDebuggerSymbols* st, const char* name) {
 60	struct mDebuggerSymbol* sym = HashTableLookup(&st->names, name);
 61	if (sym) {
 62		HashTableRemoveBinary(&st->reverse, sym, sizeof(*sym));
 63		HashTableRemove(&st->names, name);
 64	}
 65}
 66
 67void mDebuggerLoadARMIPSSymbols(struct mDebuggerSymbols* st, struct VFile* vf) {
 68	char line[512];
 69
 70	while (true) {
 71		ssize_t bytesRead = vf->readline(vf, line, sizeof(line));
 72		if (bytesRead <= 0) {
 73			break;
 74		}
 75		if (line[bytesRead - 1] == '\n') {
 76			line[bytesRead - 1] = '\0';
 77		}
 78		uint32_t address = 0;
 79		const char* buf = line;
 80		buf = hex32(buf, &address);
 81		if (!buf) {
 82			continue;
 83		}
 84		bytesRead -= 8;
 85
 86		while (isspace((int) buf[0]) && bytesRead > 0) {
 87			--bytesRead;
 88			++buf;
 89		}
 90
 91		if (!bytesRead) {
 92			continue;
 93		}
 94
 95		if (buf[0] == '.') {
 96			// Directives are not handled yet
 97			continue;
 98		}
 99
100		char* buf2 = strchr(buf, ',');
101
102		if (buf2 != NULL) {
103			// Commas separate names from function sizes
104			*buf2 = '\0';
105		}
106
107		mDebuggerSymbolAdd(st, buf, address, -1);
108	}
109}