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/link.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/link.c | 29 |
1 files changed, 18 insertions, 11 deletions
@@ -44,7 +44,7 @@ static int load_objects(struct linker *linker) // load obj file linker->obj_len++; - if (object_load(obj, path)) + if (object_load(obj, path, i+1)) return M_ERROR; skip_obj: } @@ -55,7 +55,7 @@ skip_obj: char *path = _STR(PREFIX) "/lib/mips/runtime.o"; struct object *obj = &linker->objects[linker->obj_len++]; - if (object_load(obj, path)) + if (object_load(obj, path, 0)) return M_ERROR; #undef _STR @@ -208,7 +208,7 @@ static int relocate_symbol(struct linker *linker, struct object *obj, new.st_shndx = B16(new_shndx); new.st_size = 0; - if (symtab_get(&linker->symtab, NULL, name) == M_SUCCESS) { + if (symtab_get(&linker->symtab, NULL, name, obj->index) == M_SUCCESS) { ERROR("cannot link doubly defiend symbol '%s'", name); return M_ERROR; } @@ -216,6 +216,9 @@ static int relocate_symbol(struct linker *linker, struct object *obj, if (symtab_push(&linker->symtab, &new)) return M_ERROR; + if (symtab_map_push(&linker->symtab_map, obj)) + return M_ERROR; + return M_SUCCESS; } @@ -380,12 +383,12 @@ static int relocate_instruction_rela(struct linker *linker, /// of this relocation in that segment part uint32_t off = B32(rel->r_offset); if (off > seg->size) { - ERROR("relocation in segment '%s' out of bounds", seg->name); + ERROR("invalid relocation in '%s'", seg->obj->name); return M_ERROR; } if (B32(rel->r_info) == 0) { - WARNING("skiping empty relocation entry"); + WARNING("skiping empty relocation entry in '%s'", seg->name); return M_SUCCESS; } @@ -397,22 +400,21 @@ static int relocate_instruction_rela(struct linker *linker, /// read the symbol from the relocation struct symbol_table *symtab = seg->reltab.symtab; if (idx >= symtab->len) { - ERROR("relocation in segment '%s', symbol index [%d] out of " - "bounds", seg->name, idx); + ERROR("invalid relocation in '%s'", seg->obj->name); return M_ERROR; } Elf32_Sym *sym = &symtab->syms[idx]; char const *sym_name = symtab->strtab->data + B32(sym->st_name); if (B32(sym->st_name) >= symtab->strtab->len) { - ERROR("relocation symbol name out of bounds"); + ERROR("symbol name out of bounds in '%s'", seg->obj->name); return M_ERROR; } // get the new sym for the new vaddr Elf32_Sym *new_sym = NULL; - if (symtab_get(&linker->symtab, &new_sym, sym_name)) { - ERROR("relocation symbol not found"); + if (symtab_get(&linker->symtab, &new_sym, sym_name, seg->obj->index)) { + ERROR("symbol '%s' undefined", sym_name); return M_ERROR; } @@ -656,7 +658,7 @@ static int link_executable(struct linker *linker) ehdr->e_shstrndx = B16(linker->shstrtab_shidx); Elf32_Sym *entry = NULL; - if (symtab_get(&linker->symtab, &entry, "_start")) { + if (symtab_get(&linker->symtab, &entry, "_start", -1)) { ERROR("undefined symbol _start"); return M_ERROR; } @@ -681,6 +683,7 @@ static int linker_init(struct linker *linker, struct linker_arguments *args) linker->objects = NULL; linker->segments.size = 0; linker->symtab.syms = NULL; + linker->symtab_map.meta = NULL; linker->shstrtab.data = NULL; linker->strtab.data = NULL; linker->shdr = NULL; @@ -693,7 +696,10 @@ static int linker_init(struct linker *linker, struct linker_arguments *args) return M_ERROR; if (symtab_init(&linker->symtab)) return M_ERROR; + if (symtab_map_init(&linker->symtab_map)) + return M_ERROR; linker->symtab.strtab = &linker->strtab; + linker->symtab.map = &linker->symtab_map; return M_SUCCESS; } @@ -712,6 +718,7 @@ static void linker_free(struct linker *linker) strtab_free(&linker->shstrtab); strtab_free(&linker->strtab); symtab_free(&linker->symtab); + symtab_map_free(&linker->symtab_map); } int link_files(struct linker_arguments args) { |