diff options
Diffstat (limited to 'masm/tab')
| -rw-r--r-- | masm/tab/reftab.c | 43 | ||||
| -rw-r--r-- | masm/tab/symtab.c | 88 |
2 files changed, 131 insertions, 0 deletions
diff --git a/masm/tab/reftab.c b/masm/tab/reftab.c new file mode 100644 index 0000000..3eddc50 --- /dev/null +++ b/masm/tab/reftab.c @@ -0,0 +1,43 @@ +#include <stdlib.h> +#include <merror.h> + +#include "../tab.h" + +#define REFTAB_INIT_LEN 8 + +int reftab_init(struct reference_table *reftab) +{ + reftab->size = REFTAB_INIT_LEN; + reftab->len = 0; + reftab->references = malloc(sizeof(struct reference) + * REFTAB_INIT_LEN); + + if (reftab->references == NULL) { + PERROR("cannot alloc"); + return M_ERROR; + } + + return M_SUCCESS; +} + +void reftab_free(struct reference_table *reftab) +{ + free(reftab->references); +} + +int reftab_push(struct reference_table *reftab, struct reference *ref) +{ + if (reftab->len >= reftab->size) { + reftab->size *= 2; + reftab->references = realloc(reftab->references, + sizeof(struct reference) * reftab->size); + + if (reftab->references == NULL) { + PERROR("cannot realloc"); + return M_ERROR; + } + } + + reftab->references[reftab->len++] = *ref; + return M_SUCCESS; +} 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; +} |