mips/masm/symtab.c
2024-09-12 08:37:46 -04:00

75 lines
2.2 KiB
C

#include <elf.h>
#include <merror.h>
#include <netinet/in.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "asm.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(Elf32_Sym) * SYMTBL_INIT_LEN);
symtab->sections = malloc(sizeof(ssize_t) * SYMTBL_INIT_LEN);
if (symtab->symbols == NULL || symtab->sections == NULL) {
ERROR("cannot alloc");
return M_ERROR;
}
Elf32_Sym null = {0};
if (symtab_push(symtab, null, -1))
return M_ERROR;
return M_SUCCESS;
}
void symtab_free(struct symbol_table *symtab)
{
free(symtab->symbols);
free(symtab->sections);
}
int symtab_push(struct symbol_table *symtab, Elf32_Sym sym, ssize_t sec_idx)
{
if (symtab->len >= symtab->size) {
symtab->size *= 2;
symtab->symbols = realloc(symtab->symbols,
sizeof(Elf32_Sym) * symtab->size);
symtab->sections = realloc(symtab->sections,
sizeof(ssize_t) * symtab->size);
if (symtab->symbols == NULL || symtab->sections == NULL) {
ERROR("cannot realloc");
return M_ERROR;
}
}
symtab->symbols[symtab->len] = sym;
symtab->sections[symtab->len++] = sec_idx;
return M_SUCCESS;
}
int symtab_find(struct symbol_table *symtab, Elf32_Sym **ptr,
size_t *idx, const char name[MAX_LEX_LENGTH])
{
for (uint32_t i = 0; i < symtab->len; i++) {
Elf32_Sym *sym = &symtab->symbols[i];
const char *str = &symtab->strtab->ptr[ntohl(sym->st_name)];
if (strcmp(str, name) == 0) {
if (ptr != NULL)
*ptr = sym;
ptrdiff_t diff = sym - symtab->symbols;
if (idx != NULL)
*idx = diff;
return M_SUCCESS;
}
}
return M_ERROR;
}