diff options
author | Freya Murphy <freya@freyacat.org> | 2024-09-11 12:06:09 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-09-11 12:06:09 -0400 |
commit | e3d2e31377030e84066bed4bbc04bf6c56206305 (patch) | |
tree | d5e7428212606a0f64d5b2e628b3f507948b8e2f /masm/symtab.c | |
parent | joe (diff) | |
download | mips-e3d2e31377030e84066bed4bbc04bf6c56206305.tar.gz mips-e3d2e31377030e84066bed4bbc04bf6c56206305.tar.bz2 mips-e3d2e31377030e84066bed4bbc04bf6c56206305.zip |
refactor
Diffstat (limited to 'masm/symtab.c')
-rw-r--r-- | masm/symtab.c | 70 |
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; +} |