diff options
Diffstat (limited to '')
-rw-r--r-- | mld/symtab.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/mld/symtab.c b/mld/symtab.c new file mode 100644 index 0000000..eca6dbe --- /dev/null +++ b/mld/symtab.c @@ -0,0 +1,60 @@ +#include <elf.h> +#include <merror.h> +#include <stdlib.h> +#include <melf.h> + +#include "link.h" + +#define SYMTAB_INIT_LEN 8 + +int symtab_init(struct symbol_table *symtab) +{ + symtab->len = 1; + symtab->size = SYMTAB_INIT_LEN; + symtab->syms = malloc(sizeof(Elf32_Sym) * SYMTAB_INIT_LEN); + + if (symtab->syms == NULL) { + PERROR("cannot alloc"); + return M_ERROR; + } + + symtab->syms[0] = (Elf32_Sym){0}; + + return M_SUCCESS; +} + +void symtab_free(struct symbol_table *symtab) +{ + free(symtab->syms); +} + +int symtab_push(struct symbol_table *symtab, const Elf32_Sym *sym) +{ + if (symtab->len >= symtab->size) { + size_t size = symtab->size *= 2; + void *new = realloc(symtab->syms, sizeof(Elf32_Sym) * size); + if (new == NULL) { + PERROR("cannot realloc"); + return M_ERROR; + } + symtab->size = size; + symtab->syms = new; + } + + symtab->syms[symtab->len++] = *sym; + return M_SUCCESS; +} + +int symtab_get(struct symbol_table *symtab, Elf32_Sym **res, const char *name) +{ + for (size_t i = 0; i < symtab->len; i++) { + Elf32_Sym *sym = &symtab->syms[i]; + const char *symname = symtab->strtab->data + B32(sym->st_name); + if (strcmp(name, symname) == 0) { + if (res != NULL) + *res = sym; + return M_SUCCESS; + } + } + return M_ERROR; +} |