152 lines
2.2 KiB
C
152 lines
2.2 KiB
C
|
/* 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__ */
|