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/vfs.h>
11 
12 struct mDebuggerSymbol {
13 	int32_t value;
14 	int segment;
15 };
16 
17 struct mDebuggerSymbols {
18 	struct Table names;
19 };
20 
mDebuggerSymbolTableCreate(void)21 struct mDebuggerSymbols* mDebuggerSymbolTableCreate(void) {
22 	struct mDebuggerSymbols* st = malloc(sizeof(*st));
23 	HashTableInit(&st->names, 0, free);
24 	return st;
25 }
26 
mDebuggerSymbolTableDestroy(struct mDebuggerSymbols * st)27 void mDebuggerSymbolTableDestroy(struct mDebuggerSymbols* st) {
28 	HashTableDeinit(&st->names);
29 	free(st);
30 }
31 
mDebuggerSymbolLookup(const struct mDebuggerSymbols * st,const char * name,int32_t * value,int * segment)32 bool mDebuggerSymbolLookup(const struct mDebuggerSymbols* st, const char* name, int32_t* value, int* segment) {
33 	struct mDebuggerSymbol* sym = HashTableLookup(&st->names, name);
34 	if (!sym) {
35 		return false;
36 	}
37 	*value = sym->value;
38 	*segment = sym->segment;
39 	return true;
40 }
41 
mDebuggerSymbolAdd(struct mDebuggerSymbols * st,const char * name,int32_t value,int segment)42 void mDebuggerSymbolAdd(struct mDebuggerSymbols* st, const char* name, int32_t value, int segment) {
43 	struct mDebuggerSymbol* sym = malloc(sizeof(*sym));
44 	sym->value = value;
45 	sym->segment = segment;
46 	HashTableInsert(&st->names, name, sym);
47 }
48 
mDebuggerSymbolRemove(struct mDebuggerSymbols * st,const char * name)49 void mDebuggerSymbolRemove(struct mDebuggerSymbols* st, const char* name) {
50 	HashTableRemove(&st->names, name);
51 }
52 
mDebuggerLoadARMIPSSymbols(struct mDebuggerSymbols * st,struct VFile * vf)53 void mDebuggerLoadARMIPSSymbols(struct mDebuggerSymbols* st, struct VFile* vf) {
54 	char line[512];
55 
56 	while (true) {
57 		ssize_t bytesRead = vf->readline(vf, line, sizeof(line));
58 		if (bytesRead <= 0) {
59 			break;
60 		}
61 		if (line[bytesRead - 1] == '\n') {
62 			line[bytesRead - 1] = '\0';
63 		}
64 		uint32_t address = 0;
65 		const char* buf = line;
66 		buf = hex32(buf, &address);
67 		if (!buf) {
68 			continue;
69 		}
70 		bytesRead -= 8;
71 
72 		while (isspace((int) buf[0]) && bytesRead > 0) {
73 			--bytesRead;
74 			++buf;
75 		}
76 
77 		if (!bytesRead) {
78 			continue;
79 		}
80 
81 		if (buf[0] == '.') {
82 			// Directives are not handled yet
83 			continue;
84 		}
85 
86 		mDebuggerSymbolAdd(st, buf, address, -1);
87 	}
88 }
89