summaryrefslogtreecommitdiff
path: root/mld/link.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--mld/link.h151
1 files changed, 151 insertions, 0 deletions
diff --git a/mld/link.h b/mld/link.h
new file mode 100644
index 0000000..ac97bbf
--- /dev/null
+++ b/mld/link.h
@@ -0,0 +1,151 @@
+/* Copyright (c) 2024 Freya Murphy */
+
+#ifndef __LINK_H__
+#define __LINK_H__
+
+#include <linux/limits.h>
+#include <mlimits.h>
+#include <mips.h>
+#include <merror.h>
+#include <stdint.h>
+#include <elf.h>
+#include <stdio.h>
+
+
+// when mapping porinters, we need to bounds check to
+// make sure its in the mapped object file
+//
+// this checks that
+// 1. the end is in the file
+// 2. the off and len doesnt integer overflow
+#define BOUND_CHK(obj, len, off) \
+ (off > UINT32_MAX - len || off + len > obj->mapped_size)
+
+
+// pre define
+struct linker;
+struct object;
+struct segment;
+
+///
+/// relocation table
+///
+
+struct relocation_table {
+ uint32_t type;
+ union {
+ void *raw;
+ Elf32_Rel *rel;
+ Elf32_Rela *rela;
+ };
+ size_t len;
+ struct symbol_table *symtab;
+};
+
+///
+/// string table
+///
+
+struct string_table {
+ char *data;
+ size_t len;
+};
+
+///
+/// symbol table
+///
+
+struct symbol_table {
+ struct string_table *strtab;
+ Elf32_Sym *syms;
+ size_t len;
+};
+
+///
+/// segment
+///
+
+/* a loadable program segment */
+struct segment {
+ // phdr
+ Elf32_Phdr *phdr;
+ uint32_t phdr_idx;
+
+ // shdr
+ Elf32_Shdr *shdr;
+ uint32_t shdr_idx;
+
+ // segment data
+ char *name;
+ unsigned char *bytes;
+
+ // relocation table
+ struct relocation_table reltab;
+};
+
+int segment_load(struct object *object, struct segment *segment, size_t index);
+
+///
+/// object file
+///
+
+struct object {
+ // file
+ int fd;
+ char *mapped;
+ size_t mapped_size;
+
+ // ehdr
+ Elf32_Ehdr *ehdr;
+
+ // section header table
+ Elf32_Shdr *shdr;
+ size_t shdr_len;
+
+ // program table
+ Elf32_Phdr *phdr;
+ size_t phdr_len;
+
+ // object meta
+ const char *name;
+ size_t index;
+
+ // segments
+ size_t segment_len;
+ struct segment *segments;
+
+ // section header strtab
+ struct string_table *shstrtab;
+
+ // strtabs
+ struct string_table *strtabs;
+ // symtabs
+ struct symbol_table *symtabs;
+};
+
+int object_load(struct object *object, char *path);
+
+void object_free(struct object *object);
+
+///
+/// linker
+///
+
+struct linker {
+ size_t obj_len;
+ struct object *objects;
+
+ struct linker_arguments *args;
+};
+
+/* defines arguments to the linker */
+struct linker_arguments {
+ char **in_files;
+ int in_count;
+ char *out_file;
+};
+
+/* link object files */
+int link_files(struct linker_arguments args);
+
+#endif /* __LINK_H__ */