commit 65d95b778688f40febd8e94c03bd2616c7dc0bd5
parent d24706caaba60e213fc19fa32155d944095db824
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 14 May 2018 07:08:02 +0100
[ld] Implement lookup()
Diffstat:
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/ld/ld.h b/ld/ld.h
@@ -15,6 +15,7 @@ struct obj {
 
 struct symbol {
 	char *name;
+	struct symbol *hash;
 };
 
 struct objfile {
diff --git a/ld/obj.c b/ld/obj.c
@@ -7,9 +7,13 @@ static char sccsid[] = "@(#) ./ld/obj.c";
 #include "../inc/scc.h"
 #include "ld.h"
 
+#define NR_SYM_HASH 64
+
 Obj *objlst;
 static Obj *tail;
 
+static Symbol *symtbl[NR_SYM_HASH];
+
 Obj *
 newobj(char *fname, char *member)
 {
@@ -45,5 +49,31 @@ newobj(char *fname, char *member)
 Symbol *
 lookup(char *name)
 {
-	return NULL;
+	unsigned h, c;
+	char *s;
+	size_t len;
+	Symbol *sym;
+
+	for (h = 0; c = *name; ++s)
+		h = h*33 ^ c;
+	h &= NR_SYM_HASH-1;
+
+	for (sym = symtbl[h]; sym; sym = sym->hash) {
+		s = sym->name;
+		if (*name == *s && !strcmp(name, s))
+			return sym;
+	}
+
+	len = strlen(name) + 1;
+	sym = malloc(sizeof(*sym));
+	s = malloc(len);
+	if (!sym || !s)
+		outmem();
+	sym->hash = symtbl[h];
+	symtbl[h] = sym;
+	sym->name = s;
+	memset(sym, 0, sizeof(*sym));
+	memcpy(sym->name, name, len);
+
+	return sym;
 }