diff options
author | Freya Murphy <freya@freyacat.org> | 2024-09-22 16:02:42 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-09-22 16:02:42 -0400 |
commit | 85471efb4c740bb775c9ebdb10f775620c979598 (patch) | |
tree | c4afa5cf8108df4192e73488c4da271ed166217c /mld/symtab.c | |
parent | update make clear (diff) | |
download | mips-85471efb4c740bb775c9ebdb10f775620c979598.tar.gz mips-85471efb4c740bb775c9ebdb10f775620c979598.tar.bz2 mips-85471efb4c740bb775c9ebdb10f775620c979598.zip |
mld done
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; +} |