summaryrefslogtreecommitdiff
path: root/mld/link.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--mld/link.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/mld/link.c b/mld/link.c
index 64cffe5..e9a886c 100644
--- a/mld/link.c
+++ b/mld/link.c
@@ -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) {