blob: ac97bbf03f245d6a26cd25888d3c3a162602ec07 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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__ */
|