summaryrefslogtreecommitdiff
path: root/masm/symtab.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--masm/symtab.c108
1 files changed, 61 insertions, 47 deletions
diff --git a/masm/symtab.c b/masm/symtab.c
index 652bd42..990be46 100644
--- a/masm/symtab.c
+++ b/masm/symtab.c
@@ -1,4 +1,3 @@
-#include <elf.h>
#include <merror.h>
#include <netinet/in.h>
#include <stddef.h>
@@ -6,70 +5,85 @@
#include <stdlib.h>
#include <string.h>
-#include "asm.h"
+#include "lex.h"
+#include "tab.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);
+ symtab->size = SYMTBL_INIT_LEN;
+ symtab->len = 0;
+ symtab->symbols = malloc(sizeof(struct symbol) * SYMTBL_INIT_LEN);
- if (symtab->symbols == NULL || symtab->sections == NULL) {
- PERROR("cannot alloc");
- return M_ERROR;
- }
+ if (symtab->symbols == NULL) {
+ PERROR("cannot alloc");
+ return M_ERROR;
+ }
- Elf32_Sym null = {0};
- if (symtab_push(symtab, null, -1))
- return M_ERROR;
-
- return M_SUCCESS;
+ return M_SUCCESS;
}
void symtab_free(struct symbol_table *symtab)
{
- free(symtab->symbols);
- free(symtab->sections);
+ for (uint32_t i = 0; i < symtab->len; i++)
+ string_free(&symtab->symbols[i].name);
+ free(symtab->symbols);
}
-int symtab_push(struct symbol_table *symtab, Elf32_Sym sym, ssize_t sec_idx)
+int symtab_push(struct symbol_table *symtab, struct symbol *sym)
{
- 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) {
- PERROR("cannot realloc");
- return M_ERROR;
- }
- }
+ if (symtab->len >= symtab->size) {
+ symtab->size *= 2;
+ symtab->symbols = realloc(symtab->symbols,
+ sizeof(struct symbol) * symtab->size);
+ if (symtab->symbols == NULL) {
+ PERROR("cannot realloc");
+ return M_ERROR;
+ }
+ }
- symtab->symbols[symtab->len] = sym;
- symtab->sections[symtab->len++] = sec_idx;
- return M_SUCCESS;
+ sym->tabidx = symtab->len;
+ symtab->symbols[symtab->len++] = *sym;
+ return M_SUCCESS;
}
-int symtab_find(struct symbol_table *symtab, Elf32_Sym **ptr,
- size_t *idx, const char name[MAX_LEX_LENGTH])
+int symtab_find(struct symbol_table *symtab, struct symbol **res,
+ const char *name)
{
- 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;
+ for (uint32_t i = 0; i < symtab->len; i++) {
+ struct symbol *sym = &symtab->symbols[i];
+ if (strcmp(sym->name.str, name) == 0) {
+ if (res != NULL)
+ *res = sym;
+ return M_SUCCESS;
+ }
+ }
+
+ return M_ERROR;
+}
+
+int symtab_find_or_stub(struct symbol_table *symtab, struct symbol **res,
+ const struct string *const name)
+{
+ if (symtab_find(symtab, res, name->str) == M_SUCCESS)
+ return M_SUCCESS;
+
+ struct symbol temp = {
+ .offset = 0,
+ .secidx = SYM_SEC_STUB,
+ .type = SYM_LOCAL,
+ };
+ if (string_clone(&temp.name, name))
+ return M_ERROR;
+
+ if (symtab_push(symtab, &temp)) {
+ string_free(&temp.name);
+ return M_ERROR;
+ }
- ptrdiff_t diff = sym - symtab->symbols;
- if (idx != NULL)
- *idx = diff;
+ if (res != NULL)
+ *res = &symtab->symbols[symtab->len - 1];
- return M_SUCCESS;
- }
- }
- return M_ERROR;
+ return M_SUCCESS;
}