summaryrefslogtreecommitdiff
path: root/masm/symtab.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-09-11 12:06:09 -0400
committerFreya Murphy <freya@freyacat.org>2024-09-11 12:06:09 -0400
commite3d2e31377030e84066bed4bbc04bf6c56206305 (patch)
treed5e7428212606a0f64d5b2e628b3f507948b8e2f /masm/symtab.c
parentjoe (diff)
downloadmips-e3d2e31377030e84066bed4bbc04bf6c56206305.tar.gz
mips-e3d2e31377030e84066bed4bbc04bf6c56206305.tar.bz2
mips-e3d2e31377030e84066bed4bbc04bf6c56206305.zip
refactor
Diffstat (limited to 'masm/symtab.c')
-rw-r--r--masm/symtab.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/masm/symtab.c b/masm/symtab.c
new file mode 100644
index 0000000..7d40609
--- /dev/null
+++ b/masm/symtab.c
@@ -0,0 +1,70 @@
+#include <elf.h>
+#include <merror.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "asm.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(Elf32_Sym) * SYMTBL_INIT_LEN);
+ symtab->sections = malloc(sizeof(ssize_t) * SYMTBL_INIT_LEN);
+
+ if (symtab->symbols == NULL || symtab->sections == NULL) {
+ ERROR("cannot alloc");
+ return M_ERROR;
+ }
+
+ return M_SUCCESS;
+}
+
+void symtab_free(struct symbol_table *symtab)
+{
+ free(symtab->symbols);
+ free(symtab->sections);
+}
+
+int symtab_push(struct symbol_table *symtab, Elf32_Sym sym, ssize_t sec_idx)
+{
+ if (symtab->len >= symtab->size) {
+ symtab->size *= 2;
+ symtab->symbols = realloc(symtab->symbols,
+ sizeof(Elf32_Sym) * symtab->size);
+ symtab->sections = realloc(symtab->sections,
+ sizeof(ssize_t) * symtab->size);
+ if (symtab->symbols == NULL || symtab->sections == NULL) {
+ ERROR("cannot realloc");
+ return M_ERROR;
+ }
+ }
+
+ symtab->symbols[symtab->len] = sym;
+ symtab->sections[symtab->len++] = sec_idx;
+ return M_SUCCESS;
+}
+
+int symtab_find(struct symbol_table *symtab, Elf32_Sym **ptr,
+ size_t *idx, const char name[MAX_LEX_LENGTH])
+{
+ for (uint32_t i = 0; i < symtab->len; i++) {
+ Elf32_Sym *sym = &symtab->symbols[i];
+ const char *str = &symtab->strtab->ptr[sym->st_name];
+ if (strcmp(str, name) == 0) {
+ if (ptr != NULL)
+ *ptr = sym;
+
+ ptrdiff_t diff = sym - symtab->symbols;
+ if (idx != NULL)
+ *idx = diff / sizeof(Elf32_Sym);
+
+ return M_SUCCESS;
+ }
+ }
+ return M_ERROR;
+}