summaryrefslogtreecommitdiff
path: root/mld
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-10-05 10:16:45 -0400
committerFreya Murphy <freya@freyacat.org>2024-10-05 10:16:45 -0400
commit64a7a67f0099c656f74ec53083c77674228379fa (patch)
treef20ff3dd6a08b9dcbeef7c57af31f44c5b06dc9a /mld
parentfix tests $at reg (diff)
downloadmips-64a7a67f0099c656f74ec53083c77674228379fa.tar.gz
mips-64a7a67f0099c656f74ec53083c77674228379fa.tar.bz2
mips-64a7a67f0099c656f74ec53083c77674228379fa.zip
update mld commentsHEADmain
Diffstat (limited to '')
-rw-r--r--mld/link.c29
-rw-r--r--mld/link.h29
2 files changed, 47 insertions, 11 deletions
diff --git a/mld/link.c b/mld/link.c
index dd3fcc6..2abc990 100644
--- a/mld/link.c
+++ b/mld/link.c
@@ -47,6 +47,7 @@ static int load_objects(struct linker *linker)
skip_obj:
}
+ // load runtime object if not set to be freestanding
if (linker->args->freestanding == false) {
#define _STR(x) _STR2(x)
#define _STR2(x) #x
@@ -69,6 +70,9 @@ skip_obj:
*/
static int relocate_segment_name(struct linker *linker, const char *name)
{
+ // find each segment with the provided segment name,
+ // and then relocate them
+
for (size_t i = 0; i < linker->obj_len; i++) {
struct object *obj = &linker->objects[i];
for (size_t j = 0; j < obj->segment_len; j++) {
@@ -122,6 +126,7 @@ static int relocate_segment_name(struct linker *linker, const char *name)
M_SUCCESS) {
if (segtab_ent_push(ent, seg))
return M_ERROR;
+ // otherwise create a new segment table entry
} else {
// update vaddr to be page aligned
uint32_t m = seg->new_vaddr % SEC_ALIGN;
@@ -134,7 +139,7 @@ static int relocate_segment_name(struct linker *linker, const char *name)
linker->data_vaddr += add;
}
- // else create a new segment
+ // create a new segment
if (segtab_push(&linker->segments, NULL, seg))
return M_ERROR;
}
@@ -146,6 +151,9 @@ static int relocate_segment_name(struct linker *linker, const char *name)
static int relocate_segments(struct linker *linker)
{
+ // for each object, find each different
+ // unique segment name
+
for (size_t i = 0; i < linker->obj_len; i++) {
struct object *obj = &linker->objects[i];
for (size_t j = 0; j < obj->segment_len; j++) {
@@ -154,6 +162,9 @@ static int relocate_segments(struct linker *linker)
// check if the segment has already been relocated
if (seg->new_vaddr != 0)
continue;
+
+ // relocate each segment with that segment
+ // name
if(relocate_segment_name(linker, seg->name))
return M_ERROR;
}
@@ -165,6 +176,14 @@ static int relocate_segments(struct linker *linker)
static int relocate_symbol(struct linker *linker, struct object *obj,
struct symbol_table *symtab, const Elf32_Sym *sym)
{
+ // given the symbol and the object its in
+ // 1. make sure the symbol is valid
+ // 2. get the segment in the object that the symbol is in
+ // 3. get tthe segment table entry that the segment is also
+ // in. This allows us to get the offset into the segment_table
+ // 4. the new shndx is the offset + 1 (since segments start at
+ // shndx 1
+
size_t shndx = B16(sym->st_shndx);
if (shndx == 0 || shndx == SHN_ABS)
return M_SUCCESS; // ignore this symbol
@@ -177,11 +196,15 @@ static int relocate_symbol(struct linker *linker, struct object *obj,
return M_ERROR;
}
+ // make sure the symbol name is
+ // in bounds
if (B32(sym->st_name) >= symtab->strtab->len) {
ERROR("symbol name out of bounds");
return M_ERROR;
}
+ // find the segment that this symbol
+ // is contained in
struct segment *sec = NULL;
for (size_t i = 0; i < obj->phdr_len; i++) {
if (obj->phdr_to_shdr_mapping[i] == shndx) {
@@ -245,13 +268,17 @@ static int relocate_symbol(struct linker *linker, struct object *obj,
static int relocate_symbols(struct linker *linker)
{
+ // relocate in each object
for (size_t i = 0; i < linker->obj_len; i++) {
struct object *obj = &linker->objects[i];
+ // look though each shdr entry and find
+ // any symbol tables
for (size_t j = 0; j < obj->shdr_len; j++) {
struct symbol_table *symtab = &obj->symtabs[j];
if (symtab->len < 1)
continue;
+ // for each symbol in the table, relocate it
for (size_t k = 0; k < symtab->len; k++) {
const Elf32_Sym *sym = &symtab->syms[k];
if (relocate_symbol(linker, obj, symtab, sym))
diff --git a/mld/link.h b/mld/link.h
index 3c9ca42..ef3a4af 100644
--- a/mld/link.h
+++ b/mld/link.h
@@ -92,11 +92,6 @@ struct symbol_table {
struct symbol_table_mapping *map;
};
-///
-/// symbol table map
-/// (metadata for each symbol)
-///
-
int symtab_init(struct symbol_table *symtab);
void symtab_free(struct symbol_table *symtab);
@@ -104,6 +99,13 @@ int symtab_push(struct symbol_table *symtab, const Elf32_Sym *sym);
int symtab_get(struct symbol_table *symtab, Elf32_Sym **sym, const char *name,
int32_t obj_idx);
+///
+/// symbol table map
+/// (metadata for each symbol)
+/// stores each object that a symbol
+/// is in
+///
+
struct symbol_table_mapping {
uint32_t len;
uint32_t size;
@@ -163,6 +165,9 @@ int segment_load(struct object *object, struct segment *segment, size_t index);
///
/// segment table
+/// holds each segment that
+/// share the same name
+/// (i.e. all .text segments)
///
struct segment_table_entry {
@@ -172,6 +177,7 @@ struct segment_table_entry {
uint32_t off;
uint32_t vaddr;
// weak segment pointers. we do not own these!!!
+ // (but we own the array)
struct segment **parts;
};
@@ -181,9 +187,10 @@ void segtab_ent_free(struct segment_table_entry *ent);
int segtab_ent_push(struct segment_table_entry *ent, struct segment *seg);
uint32_t segtab_ent_size(struct segment_table_entry *ent);
-// holds each segment by name
-// and all the segment parts from each of the
-// object files
+///
+/// segment table
+/// holds each segment table entry by name
+///
struct segment_table {
uint32_t len;
uint32_t size;
@@ -215,14 +222,16 @@ struct object {
Elf32_Ehdr *ehdr;
// section header table
- Elf32_Shdr *shdr;
+ Elf32_Shdr *shdr; // weak
size_t shdr_len;
// program table
- Elf32_Phdr *phdr;
+ Elf32_Phdr *phdr; // owned
size_t phdr_len;
// phdr <=> shdr mappings
+ // need a way to find any assoiciated
+ // phdr with a shdr, and also reverse
uint32_t *phdr_to_shdr_mapping;
// object meta