mips/mld/link.h

152 lines
2.2 KiB
C
Raw Normal View History

/* 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__ */