TPDE
Loading...
Searching...
No Matches
ELF.hpp
1// SPDX-FileCopyrightText: 2025 Contributors to TPDE <https://tpde.org>
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3#pragma once
4
5#include "base.hpp"
6
7namespace tpde::elf {
8
9/// \name ELF Header
10/// @{
11
12enum {
13 EI_MAG0 = 0,
14 EI_MAG1 = 1,
15 EI_MAG2 = 2,
16 EI_MAG3 = 3,
17 EI_CLASS = 4,
18 EI_DATA = 5,
19 EI_VERSION = 6,
20 EI_OSABI = 7,
21 EI_ABIVERSION = 8,
22 EI_PAD = 9,
23 EI_NIDENT = 16
24};
25
26#define ELFMAG "\177ELF"
27
28struct Elf64_Ehdr {
29 u8 e_ident[EI_NIDENT];
30 u16 e_type;
31 u16 e_machine;
32 u32 e_version;
33 u64 e_entry;
34 u64 e_phoff;
35 u64 e_shoff;
36 u32 e_flags;
37 u16 e_ehsize;
38 u16 e_phentsize;
39 u16 e_phnum;
40 u16 e_shentsize;
41 u16 e_shnum;
42 u16 e_shstrndx;
43};
44
45enum : u16 {
46 ET_NONE = 0,
47 ET_REL = 1,
48 ET_EXEC = 2,
49 ET_DYN = 3,
50 ET_CORE = 4,
51};
52
53enum : u32 {
54 EV_NONE = 0,
55 EV_CURRENT = 1,
56};
57
58enum : u16 {
59 EM_X86_64 = 62,
60 EM_AARCH64 = 183,
61};
62
63
64enum : u8 {
65 ELFCLASSNONE = 0,
66 ELFCLASS32 = 1,
67 ELFCLASS64 = 2,
68};
69
70enum : u8 {
71 ELFDATANONE = 0,
72 ELFDATA2LSB = 1,
73 ELFDATA2MSB = 2,
74};
75
76enum : u8 {
77 ELFOSABI_SYSV = 0,
78};
79
80/// @}
81
82/// \name Sections
83/// @{
84
85struct Elf64_Shdr {
86 u32 sh_name;
87 u32 sh_type;
88 u64 sh_flags;
89 u64 sh_addr;
90 u64 sh_offset;
91 u64 sh_size;
92 u32 sh_link;
93 u32 sh_info;
94 u64 sh_addralign;
95 u64 sh_entsize;
96};
97
98enum : u16 {
99 SHN_UNDEF = 0,
100 SHN_LORESERVE = 0xff00,
101 SHN_LOPROC = 0xff00,
102 SHN_HIPROC = 0xff1f,
103 SHN_LOOS = 0xff20,
104 SHN_HIOS = 0xff3f,
105 SHN_ABS = 0xfff1,
106 SHN_COMMON = 0xfff2,
107 SHN_XINDEX = 0xffff,
108 SHN_HIRESERVE = 0xffff
109};
110
111enum : u32 {
112 SHT_NULL = 0,
113 SHT_PROGBITS = 1,
114 SHT_SYMTAB = 2,
115 SHT_STRTAB = 3,
116 SHT_RELA = 4,
117 SHT_HASH = 5,
118 SHT_DYNAMIC = 6,
119 SHT_NOTE = 7,
120 SHT_NOBITS = 8,
121 SHT_REL = 9,
122 SHT_SHLIB = 10,
123 SHT_DYNSYM = 11,
124 SHT_INIT_ARRAY = 14,
125 SHT_FINI_ARRAY = 15,
126 SHT_PREINIT_ARRAY = 16,
127 SHT_GROUP = 17,
128 SHT_SYMTAB_SHNDX = 18,
129 SHT_X86_64_UNWIND = 0x70000001,
130};
131
132enum : u32 {
133 SHF_WRITE = u32{1} << 0,
134 SHF_ALLOC = u32{1} << 1,
135 SHF_EXECINSTR = u32{1} << 2,
136 SHF_MERGE = u32{1} << 4,
137 SHF_STRINGS = u32{1} << 5,
138 SHF_INFO_LINK = u32{1} << 6,
139 SHF_LINK_ORDER = u32{1} << 7,
140 SHF_OS_NONCONFORMING = u32{1} << 8,
141 SHF_GROUP = u32{1} << 9,
142 SHF_TLS = u32{1} << 10,
143 SHF_COMPRESSED = u32{1} << 11,
144 SHF_GNU_RETAIN = u32{1} << 21,
145 SHF_EXCLUDE = u32{1} << 31,
146};
147
148enum : u32 {
149 GRP_COMDAT = 0x1,
150 GRP_MASKOS = 0x0ff00000,
151 GRP_MASKPROC = 0xf0000000
152};
153
154/// @}
155
156/// \name Symbols
157/// @{
158
159struct Elf64_Sym {
160 u32 st_name;
161 u8 st_info;
162 u8 st_other;
163 u16 st_shndx;
164 u64 st_value;
165 u64 st_size;
166
167 u8 st_bind() const { return st_info >> 4; }
168 u8 st_type() const { return st_info & 0xf; }
169};
170
171#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
172
173enum : u8 {
174 STB_LOCAL = 0,
175 STB_GLOBAL = 1,
176 STB_WEAK = 2,
177 STB_LOOS = 10,
178 STB_HIOS = 12,
179 STB_LOPROC = 13,
180 STB_HIPROC = 15,
181};
182
183enum : u8 {
184 STT_NOTYPE = 0,
185 STT_OBJECT = 1,
186 STT_FUNC = 2,
187 STT_SECTION = 3,
188 STT_FILE = 4,
189 STT_COMMON = 5,
190 STT_TLS = 6,
191 STT_LOOS = 10,
192 STT_GNU_IFUNC = 10,
193 STT_HIOS = 12,
194 STT_LOPROC = 13,
195 STT_HIPROC = 15,
196};
197
198enum : u8 {
199 STV_DEFAULT = 0,
200 STV_INTERNAL = 1,
201 STV_HIDDEN = 2,
202 STV_PROTECTED = 3,
203};
204
205/// @}
206
207/// \name Relocations
208/// @{
209
210struct Elf64_Rela {
211 u64 r_offset;
212 u64 r_info;
213 i64 r_addend;
214};
215
216#define ELF64_R_INFO(sym, type) ((u64(sym) << 32) + u32(type))
217
218enum : u32 {
219 R_X86_64_NONE = 0,
220 R_X86_64_64 = 1,
221 R_X86_64_PC32 = 2,
222 R_X86_64_GOT32 = 3,
223 R_X86_64_PLT32 = 4,
224 R_X86_64_COPY = 5,
225 R_X86_64_GLOB_DAT = 6,
226 R_X86_64_JUMP_SLOT = 7,
227 R_X86_64_RELATIVE = 8,
228 R_X86_64_GOTPCREL = 9,
229 R_X86_64_32 = 10,
230 R_X86_64_32S = 11,
231 R_X86_64_16 = 12,
232 R_X86_64_PC16 = 13,
233 R_X86_64_8 = 14,
234 R_X86_64_PC8 = 15,
235 R_X86_64_DTPMOD64 = 16,
236 R_X86_64_DTPOFF64 = 17,
237 R_X86_64_TPOFF64 = 18,
238 R_X86_64_TLSGD = 19,
239 R_X86_64_TLSLD = 20,
240 R_X86_64_DTPOFF32 = 21,
241 R_X86_64_GOTTPOFF = 22,
242 R_X86_64_TPOFF32 = 23,
243 R_X86_64_PC64 = 24,
244 R_X86_64_GOTOFF64 = 25,
245 R_X86_64_GOTPC32 = 26,
246 R_X86_64_GOT64 = 27,
247 R_X86_64_GOTPCREL64 = 28,
248 R_X86_64_GOTPC64 = 29,
249 R_X86_64_GOTPLT64 = 30,
250 R_X86_64_PLTOFF64 = 31,
251 R_X86_64_SIZE32 = 32,
252 R_X86_64_SIZE64 = 33,
253 R_X86_64_GOTPC32_TLSDESC = 34,
254 R_X86_64_TLSDESC_CALL = 35,
255 R_X86_64_TLSDESC = 36,
256 R_X86_64_IRELATIVE = 37,
257 R_X86_64_GOTPCRELX = 41,
258 R_X86_64_REX_GOTPCRELX = 42,
259 R_X86_64_CODE_4_GOTPCRELX = 43,
260 R_X86_64_CODE_4_GOTTPOFF = 44,
261 R_X86_64_CODE_4_GOTPC32_TLSDESC = 45,
262 R_X86_64_CODE_6_GOTTPOFF = 50,
263};
264
265enum : u32 {
266 R_AARCH64_NONE = 0,
267 R_AARCH64_ABS64 = 257,
268 R_AARCH64_ABS32 = 258,
269 R_AARCH64_ABS16 = 259,
270 R_AARCH64_PREL64 = 260,
271 R_AARCH64_PREL32 = 261,
272 R_AARCH64_PREL16 = 262,
273 R_AARCH64_MOVW_UABS_G0 = 263,
274 R_AARCH64_MOVW_UABS_G0_NC = 264,
275 R_AARCH64_MOVW_UABS_G1 = 265,
276 R_AARCH64_MOVW_UABS_G1_NC = 266,
277 R_AARCH64_MOVW_UABS_G2 = 267,
278 R_AARCH64_MOVW_UABS_G2_NC = 268,
279 R_AARCH64_MOVW_UABS_G3 = 269,
280 R_AARCH64_MOVW_SABS_G0 = 270,
281 R_AARCH64_MOVW_SABS_G1 = 271,
282 R_AARCH64_MOVW_SABS_G2 = 272,
283 R_AARCH64_LD_PREL_LO19 = 273,
284 R_AARCH64_ADR_PREL_LO21 = 274,
285 R_AARCH64_ADR_PREL_PG_HI21 = 275,
286 R_AARCH64_ADR_PREL_PG_HI21_NC = 276,
287 R_AARCH64_ADD_ABS_LO12_NC = 277,
288 R_AARCH64_LDST8_ABS_LO12_NC = 278,
289 R_AARCH64_TSTBR14 = 279,
290 R_AARCH64_CONDBR19 = 280,
291 R_AARCH64_JUMP26 = 282,
292 R_AARCH64_CALL26 = 283,
293 R_AARCH64_LDST16_ABS_LO12_NC = 284,
294 R_AARCH64_LDST32_ABS_LO12_NC = 285,
295 R_AARCH64_LDST64_ABS_LO12_NC = 286,
296 R_AARCH64_MOVW_PREL_G0 = 287,
297 R_AARCH64_MOVW_PREL_G0_NC = 288,
298 R_AARCH64_MOVW_PREL_G1 = 289,
299 R_AARCH64_MOVW_PREL_G1_NC = 290,
300 R_AARCH64_MOVW_PREL_G2 = 291,
301 R_AARCH64_MOVW_PREL_G2_NC = 292,
302 R_AARCH64_MOVW_PREL_G3 = 293,
303 R_AARCH64_LDST128_ABS_LO12_NC = 299,
304 R_AARCH64_MOVW_GOTOFF_G0 = 300,
305 R_AARCH64_MOVW_GOTOFF_G0_NC = 301,
306 R_AARCH64_MOVW_GOTOFF_G1 = 302,
307 R_AARCH64_MOVW_GOTOFF_G1_NC = 303,
308 R_AARCH64_MOVW_GOTOFF_G2 = 304,
309 R_AARCH64_MOVW_GOTOFF_G2_NC = 305,
310 R_AARCH64_MOVW_GOTOFF_G3 = 306,
311 R_AARCH64_GOTREL64 = 307,
312 R_AARCH64_GOTREL32 = 308,
313 R_AARCH64_GOT_LD_PREL19 = 309,
314 R_AARCH64_LD64_GOTOFF_LO15 = 310,
315 R_AARCH64_ADR_GOT_PAGE = 311,
316 R_AARCH64_LD64_GOT_LO12_NC = 312,
317 R_AARCH64_LD64_GOTPAGE_LO15 = 313,
318 R_AARCH64_TLSGD_ADR_PREL21 = 512,
319 R_AARCH64_TLSGD_ADR_PAGE21 = 513,
320 R_AARCH64_TLSGD_ADD_LO12_NC = 514,
321 R_AARCH64_TLSGD_MOVW_G1 = 515,
322 R_AARCH64_TLSGD_MOVW_G0_NC = 516,
323 R_AARCH64_TLSLD_ADR_PREL21 = 517,
324 R_AARCH64_TLSLD_ADR_PAGE21 = 518,
325 R_AARCH64_TLSLD_ADD_LO12_NC = 519,
326 R_AARCH64_TLSLD_MOVW_G1 = 520,
327 R_AARCH64_TLSLD_MOVW_G0_NC = 521,
328 R_AARCH64_TLSLD_LD_PREL19 = 522,
329 R_AARCH64_TLSLD_MOVW_DTPREL_G2 = 523,
330 R_AARCH64_TLSLD_MOVW_DTPREL_G1 = 524,
331 R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC = 525,
332 R_AARCH64_TLSLD_MOVW_DTPREL_G0 = 526,
333 R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC = 527,
334 R_AARCH64_TLSLD_ADD_DTPREL_HI12 = 528,
335 R_AARCH64_TLSLD_ADD_DTPREL_LO12 = 529,
336 R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC = 530,
337 R_AARCH64_TLSLD_LDST8_DTPREL_LO12 = 531,
338 R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC = 532,
339 R_AARCH64_TLSLD_LDST16_DTPREL_LO12 = 533,
340 R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC = 534,
341 R_AARCH64_TLSLD_LDST32_DTPREL_LO12 = 535,
342 R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC = 536,
343 R_AARCH64_TLSLD_LDST64_DTPREL_LO12 = 537,
344 R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC = 538,
345 R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 = 539,
346 R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC = 540,
347 R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 541,
348 R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542,
349 R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 = 543,
350 R_AARCH64_TLSLE_MOVW_TPREL_G2 = 544,
351 R_AARCH64_TLSLE_MOVW_TPREL_G1 = 545,
352 R_AARCH64_TLSLE_MOVW_TPREL_G1_NC = 546,
353 R_AARCH64_TLSLE_MOVW_TPREL_G0 = 547,
354 R_AARCH64_TLSLE_MOVW_TPREL_G0_NC = 548,
355 R_AARCH64_TLSLE_ADD_TPREL_HI12 = 549,
356 R_AARCH64_TLSLE_ADD_TPREL_LO12 = 550,
357 R_AARCH64_TLSLE_ADD_TPREL_LO12_NC = 551,
358 R_AARCH64_TLSLE_LDST8_TPREL_LO12 = 552,
359 R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC = 553,
360 R_AARCH64_TLSLE_LDST16_TPREL_LO12 = 554,
361 R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC = 555,
362 R_AARCH64_TLSLE_LDST32_TPREL_LO12 = 556,
363 R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC = 557,
364 R_AARCH64_TLSLE_LDST64_TPREL_LO12 = 558,
365 R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC = 559,
366 R_AARCH64_TLSDESC_LD_PREL19 = 560,
367 R_AARCH64_TLSDESC_ADR_PREL21 = 561,
368 R_AARCH64_TLSDESC_ADR_PAGE21 = 562,
369 R_AARCH64_TLSDESC_LD64_LO12 = 563,
370 R_AARCH64_TLSDESC_ADD_LO12 = 564,
371 R_AARCH64_TLSDESC_OFF_G1 = 565,
372 R_AARCH64_TLSDESC_OFF_G0_NC = 566,
373 R_AARCH64_TLSDESC_LDR = 567,
374 R_AARCH64_TLSDESC_ADD = 568,
375 R_AARCH64_TLSDESC_CALL = 569,
376 R_AARCH64_TLSLE_LDST128_TPREL_LO12 = 570,
377 R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC = 571,
378 R_AARCH64_TLSLD_LDST128_DTPREL_LO12 = 572,
379 R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC = 573,
380 R_AARCH64_COPY = 1024,
381 R_AARCH64_GLOB_DAT = 1025,
382 R_AARCH64_JUMP_SLOT = 1026,
383 R_AARCH64_RELATIVE = 1027,
384 R_AARCH64_TLS_DTPMOD = 1028,
385 R_AARCH64_TLS_DTPREL = 1029,
386 R_AARCH64_TLS_TPREL = 1030,
387 R_AARCH64_TLSDESC = 1031,
388 R_AARCH64_IRELATIVE = 1032,
389};
390
391/// @}
392
393} // namespace tpde::elf