summaryrefslogtreecommitdiff
path: root/masm/tab/symtab.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-10-21 12:27:18 -0400
committerFreya Murphy <freya@freyacat.org>2024-10-21 12:27:18 -0400
commit37a4e740133f8e4d669cafc8468dd13107a4810a (patch)
tree116b001142b5c0aea03ae46ef299f5fc220c4e5e /masm/tab/symtab.c
parentadd mips1 and mips32r2 isa definitions (diff)
downloadmips-37a4e740133f8e4d669cafc8468dd13107a4810a.tar.gz
mips-37a4e740133f8e4d669cafc8468dd13107a4810a.tar.bz2
mips-37a4e740133f8e4d669cafc8468dd13107a4810a.zip
save dev statedev
Diffstat (limited to 'masm/tab/symtab.c')
-rw-r--r--masm/tab/symtab.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/masm/tab/symtab.c b/masm/tab/symtab.c
new file mode 100644
index 0000000..a2aa1ea
--- /dev/null
+++ b/masm/tab/symtab.c
@@ -0,0 +1,88 @@
+#include <merror.h>
+#include <netinet/in.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../tab.h"
+
+#define SYMTBL_INIT_LEN 24
+
+int symtab_init(struct symbol_table *symtab)
+{
+ symtab->size = SYMTBL_INIT_LEN;
+ symtab->len = 0;
+ symtab->symbols = malloc(sizeof(struct symbol) * SYMTBL_INIT_LEN);
+
+ if (symtab->symbols == NULL) {
+ PERROR("cannot alloc");
+ return M_ERROR;
+ }
+
+ return M_SUCCESS;
+}
+
+void symtab_free(struct symbol_table *symtab)
+{
+ for (uint32_t i = 0; i < symtab->len; i++)
+ string_free(&symtab->symbols[i].name);
+ free(symtab->symbols);
+}
+
+int symtab_push(struct symbol_table *symtab, struct symbol *sym)
+{
+ if (symtab->len >= symtab->size) {
+ symtab->size *= 2;
+ symtab->symbols = realloc(symtab->symbols,
+ sizeof(struct symbol) * symtab->size);
+ if (symtab->symbols == NULL) {
+ PERROR("cannot realloc");
+ return M_ERROR;
+ }
+ }
+
+ sym->tabidx = symtab->len;
+ symtab->symbols[symtab->len++] = *sym;
+ return M_SUCCESS;
+}
+
+int symtab_find(struct symbol_table *symtab, struct symbol **res,
+ const char *name)
+{
+ for (uint32_t i = 0; i < symtab->len; i++) {
+ struct symbol *sym = &symtab->symbols[i];
+ if (strcmp(sym->name.str, name) == 0) {
+ if (res != NULL)
+ *res = sym;
+ return M_SUCCESS;
+ }
+ }
+
+ return M_ERROR;
+}
+
+int symtab_find_or_stub(struct symbol_table *symtab, struct symbol **res,
+ const struct string *const name)
+{
+ if (symtab_find(symtab, res, name->str) == M_SUCCESS)
+ return M_SUCCESS;
+
+ struct symbol temp = {
+ .offset = 0,
+ .secidx = SYM_SEC_STUB,
+ .type = SYM_LOCAL,
+ };
+ if (string_clone(&temp.name, name))
+ return M_ERROR;
+
+ if (symtab_push(symtab, &temp)) {
+ string_free(&temp.name);
+ return M_ERROR;
+ }
+
+ if (res != NULL)
+ *res = &symtab->symbols[symtab->len - 1];
+
+ return M_SUCCESS;
+}