1 /*
2  * This file is part of RGBDS.
3  *
4  * Copyright (c) 2019, Eldred Habert and RGBDS contributors.
5  *
6  * SPDX-License-Identifier: MIT
7  */
8 
9 #include <inttypes.h>
10 #include <stdbool.h>
11 #include <stdlib.h>
12 
13 #include "link/object.h"
14 #include "link/symbol.h"
15 #include "link/main.h"
16 
17 #include "error.h"
18 #include "hashmap.h"
19 
20 HashMap symbols;
21 
22 struct ForEachArg {
23 	void (*callback)(struct Symbol *symbol, void *arg);
24 	void *arg;
25 };
26 
forEach(void * symbol,void * arg)27 static void forEach(void *symbol, void *arg)
28 {
29 	struct ForEachArg *callbackArg = (struct ForEachArg *)arg;
30 
31 	callbackArg->callback((struct Symbol *)symbol, callbackArg->arg);
32 }
33 
sym_ForEach(void (* callback)(struct Symbol *,void *),void * arg)34 void sym_ForEach(void (*callback)(struct Symbol *, void *), void *arg)
35 {
36 	struct ForEachArg callbackArg = { .callback = callback, .arg = arg};
37 
38 	hash_ForEach(symbols, forEach, &callbackArg);
39 }
40 
sym_AddSymbol(struct Symbol * symbol)41 void sym_AddSymbol(struct Symbol *symbol)
42 {
43 	/* Check if the symbol already exists */
44 	struct Symbol *other = hash_GetElement(symbols, symbol->name);
45 
46 	if (other) {
47 		fprintf(stderr, "error: \"%s\" both in %s from ", symbol->name, symbol->objFileName);
48 		dumpFileStack(symbol->src);
49 		fprintf(stderr, "(%" PRIu32 ") and in %s from ",
50 			symbol->lineNo, other->objFileName);
51 		dumpFileStack(other->src);
52 		fprintf(stderr, "(%" PRIu32 ")\n", other->lineNo);
53 		exit(1);
54 	}
55 
56 	/* If not, add it */
57 	hash_AddElement(symbols, symbol->name, symbol);
58 }
59 
sym_GetSymbol(char const * name)60 struct Symbol *sym_GetSymbol(char const *name)
61 {
62 	return (struct Symbol *)hash_GetElement(symbols, name);
63 }
64 
sym_CleanupSymbols(void)65 void sym_CleanupSymbols(void)
66 {
67 	hash_EmptyMap(symbols);
68 }
69