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 mDebuggerSymbolAdd(st, buf, address, -1);
101 }
102}