diff options
Diffstat (limited to 'mld/link.h')
-rw-r--r-- | mld/link.h | 117 |
1 files changed, 113 insertions, 4 deletions
@@ -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 */ |