diff options
author | Freya Murphy <freya@freyacat.org> | 2024-09-23 10:13:38 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-09-23 10:13:38 -0400 |
commit | 9d3d75fecbf89ca526b95dd824b15a4d284e05c8 (patch) | |
tree | 969c28f4090595853a9ad863bb3812020b5aecaf /mld/symtab.c | |
parent | update readme (diff) | |
download | mips-9d3d75fecbf89ca526b95dd824b15a4d284e05c8.tar.gz mips-9d3d75fecbf89ca526b95dd824b15a4d284e05c8.tar.bz2 mips-9d3d75fecbf89ca526b95dd824b15a4d284e05c8.zip |
fix local vs global symbol names, locals now are local
Diffstat (limited to '')
-rw-r--r-- | mld/symtab.c | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/mld/symtab.c b/mld/symtab.c index eca6dbe..5abad2a 100644 --- a/mld/symtab.c +++ b/mld/symtab.c @@ -1,5 +1,6 @@ #include <elf.h> #include <merror.h> +#include <stdio.h> #include <stdlib.h> #include <melf.h> @@ -19,6 +20,7 @@ int symtab_init(struct symbol_table *symtab) } symtab->syms[0] = (Elf32_Sym){0}; + symtab->map = NULL; return M_SUCCESS; } @@ -45,16 +47,69 @@ int symtab_push(struct symbol_table *symtab, const Elf32_Sym *sym) return M_SUCCESS; } -int symtab_get(struct symbol_table *symtab, Elf32_Sym **res, const char *name) +int symtab_get(struct symbol_table *symtab, Elf32_Sym **res, const char *name, + int32_t obj_idx) { 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; + if (strcmp(name, symname) != 0) + continue; + + // only allow retrevial of local variables from the + // same object + if (sym->st_info >> 4 != STB_GLOBAL && symtab->map != NULL && + obj_idx >= 0) { + struct object *obj = symtab->map->meta[i]; + if (obj->index != (uint32_t)obj_idx) + continue; + } else if (obj_idx < 0 && sym->st_info >> 4 != STB_GLOBAL) { + // when obj_idx is -1, we only want to reutrn + // global symbols + continue; } + + if (res != NULL) + *res = sym; + return M_SUCCESS; } return M_ERROR; } + +int symtab_map_push(struct symbol_table_mapping *symtabm, struct object *meta) +{ + if (symtabm->len >= symtabm->size) { + uint32_t size = symtabm->size * 2; + void *new = realloc(symtabm->meta, + sizeof(struct object *) * size); + if (new == NULL) { + PERROR("cannot realloc"); + return M_ERROR; + } + symtabm->size = size; + symtabm->meta = new; + } + + symtabm->meta[symtabm->len++] = meta; + return M_SUCCESS; +} + +int symtab_map_init(struct symbol_table_mapping *symtabm) +{ + symtabm->len = 0; + symtabm->size = SYMTAB_INIT_LEN; + symtabm->meta = malloc(sizeof(struct object *) * symtabm->size); + + if (symtabm->meta == NULL) { + PERROR("cannot alloc"); + return M_ERROR; + } + + return M_SUCCESS; +} + + +void symtab_map_free(struct symbol_table_mapping *symtabm) +{ + free(symtabm->meta); +} |