summaryrefslogtreecommitdiff
path: root/mld/link.h
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-09-22 16:02:42 -0400
committerFreya Murphy <freya@freyacat.org>2024-09-22 16:02:42 -0400
commit85471efb4c740bb775c9ebdb10f775620c979598 (patch)
treec4afa5cf8108df4192e73488c4da271ed166217c /mld/link.h
parentupdate make clear (diff)
downloadmips-85471efb4c740bb775c9ebdb10f775620c979598.tar.gz
mips-85471efb4c740bb775c9ebdb10f775620c979598.tar.bz2
mips-85471efb4c740bb775c9ebdb10f775620c979598.zip
mld done
Diffstat (limited to 'mld/link.h')
-rw-r--r--mld/link.h117
1 files changed, 113 insertions, 4 deletions
diff --git a/mld/link.h b/mld/link.h
index ac97bbf..22e8c6b 100644
--- a/mld/link.h
+++ b/mld/link.h
@@ -9,7 +9,6 @@
#include <merror.h>
#include <stdint.h>
#include <elf.h>
-#include <stdio.h>
// when mapping porinters, we need to bounds check to
@@ -21,6 +20,15 @@
#define BOUND_CHK(obj, len, off) \
(off > UINT32_MAX - len || off + len > obj->mapped_size)
+// when relocating segments, we need to bounds check to
+// make sure it wont overflow the addresses past the 32bit
+// ELF file
+#define ADDR_CHK(lnk_f, seg_f, max) \
+ ((lnk_f) > max - (seg_f) || (lnk_f) + (seg_f) > max)
+
+// start addresses for each tyoe of segment
+#define TEXT_VADDR_MIN 0x00400000
+#define DATA_VADDR_MIN 0x10000000
// pre define
struct linker;
@@ -51,6 +59,12 @@ struct string_table {
size_t len;
};
+int strtab_init(struct string_table *strtab);
+void strtab_free(struct string_table *strtab);
+
+int strtab_push(struct string_table *strtab, const char *str, size_t *res);
+int strtab_get(struct string_table *strtab, const char *str, size_t *res);
+
///
/// symbol table
///
@@ -59,14 +73,42 @@ struct symbol_table {
struct string_table *strtab;
Elf32_Sym *syms;
size_t len;
+ size_t size;
};
+int symtab_init(struct symbol_table *symtab);
+void symtab_free(struct symbol_table *symtab);
+
+int symtab_push(struct symbol_table *symtab, const Elf32_Sym *sym);
+int symtab_get(struct symbol_table *symtab, Elf32_Sym **sym, const char *name);
+
///
/// segment
///
/* a loadable program segment */
struct segment {
+ // segment data
+ char *name;
+ unsigned char *bytes;
+
+ // current loc
+ uint32_t off;
+ uint32_t vaddr;
+
+ // new loc
+ uint32_t new_off;
+ uint32_t new_vaddr;
+
+ // meta
+ bool read;
+ bool write;
+ bool execute;
+ uint32_t align;
+
+ // size
+ uint32_t size;
+
// phdr
Elf32_Phdr *phdr;
uint32_t phdr_idx;
@@ -75,9 +117,8 @@ struct segment {
Elf32_Shdr *shdr;
uint32_t shdr_idx;
- // segment data
- char *name;
- unsigned char *bytes;
+ // object im related to
+ struct object *obj;
// relocation table
struct relocation_table reltab;
@@ -86,6 +127,46 @@ struct segment {
int segment_load(struct object *object, struct segment *segment, size_t index);
///
+/// segment table
+///
+
+struct segment_table_entry {
+ char *name;
+ uint32_t len;
+ uint32_t size;
+ uint32_t off;
+ uint32_t vaddr;
+ // weak segment pointers. we do not own these!!!
+ struct segment **parts;
+};
+
+int segtab_ent_init(struct segment_table_entry *ent);
+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
+struct segment_table {
+ uint32_t len;
+ uint32_t size;
+ struct segment_table_entry *entries;
+};
+
+int segtab_init(struct segment_table *segtab);
+void segtab_free(struct segment_table *segtab);
+
+/* create a new entry with <seg> as its first segment part */
+int segtab_push(struct segment_table *segtab, struct segment_table_entry **ent,
+ struct segment *seg);
+
+/* find a segment table entry with a given name */
+int segtab_get(struct segment_table *segtab, struct segment_table_entry **ent,
+ const char *name);
+
+///
/// object file
///
@@ -136,6 +217,34 @@ struct linker {
struct object *objects;
struct linker_arguments *args;
+
+ // current pointers to relocate
+ // sections
+ uint32_t off;
+ uint32_t text_vaddr;
+ uint32_t data_vaddr;
+
+ // elf tables
+ struct string_table shstrtab;
+ struct string_table strtab;
+ struct symbol_table symtab;
+
+ // output elf
+ Elf32_Ehdr ehdr;
+ Elf32_Phdr *phdr;
+ uint32_t phdr_len;
+ Elf32_Shdr *shdr;
+ uint32_t shdr_len;
+
+ uint32_t symtab_shidx;
+ uint32_t strtab_shidx;
+ uint32_t shstrtab_shidx;
+
+ // section alignment after phdr bytes
+ uint32_t secalign;
+
+ // all segments
+ struct segment_table segments;
};
/* defines arguments to the linker */