aboutsummaryrefslogtreecommitdiff
path: root/include/apos/elf.h
blob: e6936a31504f5fadbafee5cd1ce8473772a36cb2 (plain) (blame)
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#ifndef APOS_ELF_H
#define APOS_ELF_H

/**
 * @file elf.h
 * ELF file handling.
 *
 * \todo Other file formats?
 */

#include <apos/attrs.h>
#include <apos/types.h>
#include <apos/vmem.h>

#define EI_MAGIC         0x7f454c46

#define ELFCLASSNONE     0x0
#define ELFCLASS32       0x1
#define ELFCLASS64       0x2

#define ELFDATANONE      0x0
#define ELFDATA2LSB      0x1
#define ELFDATA2MSB      0x2

#define ELFOSABI_NONE    0x0
#define ELFOSABI_SYSV    0x0
#define ELFOSABI_NETBSD  0x2
#define ELFOSABI_LINUX   0x3
#define ELFOSABI_HURD    0x4
#define ELFOSABI_FREEBSD 0x9
#define ELFOSABI_OPENBSD 0xc

#define ET_NONE          0x0
#define ET_REL           0x1
#define ET_EXEC          0x2
#define ET_DYN           0x3
#define ET_CORE          0x4

#define EM_RISCV         0xf3

struct __packed elf_ident {
	uint32_t ei_magic;
	uint8_t ei_class;
	uint8_t ei_data;
	uint8_t ei_version;
	uint8_t ei_osabi;
	uint8_t ei_abiversion;
	uint8_t ei_pad[7];
};

struct __packed elf32_header {
	struct elf_ident e_ident;
	uint16_t e_type;
	uint16_t e_machine;
	uint32_t e_version;
	uint32_t e_entry;
	uint32_t e_phoff;
	uint32_t e_shoff;
	uint32_t e_flags;
	uint16_t e_ehsize;
	uint16_t e_phentsize;
	uint16_t e_phnum;
	uint16_t e_shentsize;
	uint16_t e_shnum;
	uint16_t e_shstrndx;
};

struct __packed elf64_header {
	struct elf_ident e_ident;
	uint16_t e_type;
	uint16_t e_machine;
	uint32_t e_version;
	uint64_t e_entry;
	uint64_t e_phoff;
	uint64_t e_shoff;
	uint32_t e_flags;
	uint16_t e_ehsize;
	uint16_t e_phentsize;
	uint16_t e_phnum;
	uint16_t e_shentsize;
	uint16_t e_shnum;
	uint16_t e_shstrndx;
};

#define PT_NULL    0x0
#define PT_LOAD    0x1
#define PT_DYNAMIC 0x2
#define PT_INTERP  0x3
#define PT_NOTE    0x4
#define PT_SHLIB   0x5
#define PT_PHDR    0x6
#define PT_TLS     0x7
#define PT_LOOS    0x60000000
#define PT_HIOS    0x6fffffff
#define PT_LOPROC  0x70000000
#define PT_HIPROC  0x7fffffff

#define PF_X       (1 << 0)
#define PF_W       (1 << 1)
#define PF_R       (1 << 2)

struct __packed program32_header {
	uint32_t p_type;
	uint32_t p_offset;
	uint32_t p_vaddr;
	uint32_t p_paddr;
	uint32_t p_filesz;
	uint32_t p_memsz;
	uint32_t p_flags;
	uint32_t p_align;
};

struct __packed program64_header {
	uint32_t p_type;
	uint32_t p_flags;
	uint64_t p_offset;
	uint64_t p_vaddr;
	uint64_t p_paddr;
	uint64_t p_filesz;
	uint64_t p_memsz;
	uint64_t p_align;
};

#define SHT_NULL             0x0
#define SH_PROGBITS          0x1
#define SHT_SYMTAB           0x2
#define SHT_STRTAB           0x3
#define SHT_RELA             0x4
#define SHT_HASH             0x5
#define SHT_DYNAMIC          0x6
#define SHT_NOTE             0x7
#define SHT_NOBITS           0x8
#define SHT_REL              0x9
#define SHT_SHLIB            0x0a
#define SHT_DYNSYM           0x0b
#define SHT_INIT_ARRAY       0x0e
#define SHT_FINI_ARRAY       0x0f
#define SHT_PREINIT_ARRAY    0x10
#define SHT_GROUP            0x11
#define SHT_SYMTAB_SHNDX     0x12
#define SHT_NUM              0x13

#define SHF_WRITE            0x1
#define SHF_ALLOC            0x2
#define SHF_EXECINSTR        0x4
#define SHF_MERGE            0x10
#define SHF_STRINGS          0x20
#define SHF_INFO_LINK        0x40
#define SHF_LINK_ODER        0x80
#define SHF_OS_NONCONFORMING 0x100
#define SHF_GROUP            0x200
#define SHF_TLS              0x400
#define SHF_MASKOS           0x0ff00000
#define SHF_MASKPROC         0xf0000000

struct __packed section32_header {
	uint32_t sh_name;
	uint32_t sh_type;
	uint32_t sh_flags;
	uint32_t sh_addr;
	uint32_t sh_offset;
	uint32_t sh_size;
	uint32_t sh_link;
	uint32_t sh_info;
	uint32_t sh_addralign;
	uint32_t sh_entsize;
};

struct __packed section64_header {
	uint32_t sh_name;
	uint32_t sh_type;
	uint64_t sh_flags;
	uint64_t sh_addr;
	uint64_t sh_offset;
	uint64_t sh_size;
	uint32_t sh_link;
	uint32_t sh_info;
	uint64_t sh_addralign;
	uint64_t s_entsize;
};

#define elf_indent(e)       ((struct elf_ident *)e)
#define elf64_header(e)     ((struct elf64_header *)e)
#define elf32_header(e)     ((struct elf32_header *)e)
#define program64_header(p) ((struct program64_header *)p)
#define program32_header(p) ((struct program32_header *)p)
#define section64_header(s) ((struct section64_header *)s)
#define section32_header(s) ((struct section32_header *)s)

#define elf_header_prop(c, e, p) \
	(c == ELFCLASS64 ? elf64_header(e)->p : elf32_header(e)->p)
#define program_header_prop(c, e, p) \
	(c == ELFCLASS64 ? program64_header(e)->p : program32_header(e)->p)
#define section_header_prop(c, e, p) \
	(c == ELFCLASS64 ? section64_header(e)->p : section32_header(e)->p)

vm_t load_elf(struct tcb *t, vm_t binary, vm_t interp);

#endif /* APOS_ELF_H */