diff options
Diffstat (limited to '')
-rw-r--r-- | masm/symtab.c | 108 |
1 files changed, 61 insertions, 47 deletions
diff --git a/masm/symtab.c b/masm/symtab.c index 652bd42..990be46 100644 --- a/masm/symtab.c +++ b/masm/symtab.c @@ -1,4 +1,3 @@ -#include <elf.h> #include <merror.h> #include <netinet/in.h> #include <stddef.h> @@ -6,70 +5,85 @@ #include <stdlib.h> #include <string.h> -#include "asm.h" +#include "lex.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(Elf32_Sym) * SYMTBL_INIT_LEN); - symtab->sections = malloc(sizeof(ssize_t) * SYMTBL_INIT_LEN); + symtab->size = SYMTBL_INIT_LEN; + symtab->len = 0; + symtab->symbols = malloc(sizeof(struct symbol) * SYMTBL_INIT_LEN); - if (symtab->symbols == NULL || symtab->sections == NULL) { - PERROR("cannot alloc"); - return M_ERROR; - } + if (symtab->symbols == NULL) { + PERROR("cannot alloc"); + return M_ERROR; + } - Elf32_Sym null = {0}; - if (symtab_push(symtab, null, -1)) - return M_ERROR; - - return M_SUCCESS; + return M_SUCCESS; } void symtab_free(struct symbol_table *symtab) { - free(symtab->symbols); - free(symtab->sections); + 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, Elf32_Sym sym, ssize_t sec_idx) +int symtab_push(struct symbol_table *symtab, struct symbol *sym) { - 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) { - PERROR("cannot realloc"); - return M_ERROR; - } - } + 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; + } + } - symtab->symbols[symtab->len] = sym; - symtab->sections[symtab->len++] = sec_idx; - return M_SUCCESS; + sym->tabidx = symtab->len; + symtab->symbols[symtab->len++] = *sym; + return M_SUCCESS; } -int symtab_find(struct symbol_table *symtab, Elf32_Sym **ptr, - size_t *idx, const char name[MAX_LEX_LENGTH]) +int symtab_find(struct symbol_table *symtab, struct symbol **res, + const char *name) { - for (uint32_t i = 0; i < symtab->len; i++) { - Elf32_Sym *sym = &symtab->symbols[i]; - const char *str = &symtab->strtab->ptr[ntohl(sym->st_name)]; - if (strcmp(str, name) == 0) { - if (ptr != NULL) - *ptr = sym; + 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; + } - ptrdiff_t diff = sym - symtab->symbols; - if (idx != NULL) - *idx = diff; + if (res != NULL) + *res = &symtab->symbols[symtab->len - 1]; - return M_SUCCESS; - } - } - return M_ERROR; + return M_SUCCESS; } |