#include #include #include #include #include #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}; symtab->map = NULL; 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, int32_t obj_idx) { for (size_t i = 1; 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) continue; // only allow retrevial of local variables from the // same object if (sym->st_info >> 4 != STB_GLOBAL && symtab->map != NULL && obj_idx >= 0) { // we need to change the index by one since // symbol tables always start will a NULl symbol struct object *obj = symtab->map->meta[i - 1]; 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); }