summaryrefslogtreecommitdiff
path: root/mld/symtab.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-09-23 10:13:38 -0400
committerFreya Murphy <freya@freyacat.org>2024-09-23 10:13:38 -0400
commit9d3d75fecbf89ca526b95dd824b15a4d284e05c8 (patch)
tree969c28f4090595853a9ad863bb3812020b5aecaf /mld/symtab.c
parentupdate readme (diff)
downloadmips-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.c65
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);
+}