Line data Source code
1 1 : /*
2 : * Copyright (c) 2023 Intel Corporation
3 : * Copyright (c) 2024 Schneider Electric
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : *
7 : */
8 : #ifndef ZEPHYR_LLEXT_ELF_H
9 : #define ZEPHYR_LLEXT_ELF_H
10 :
11 : #include <stdint.h>
12 :
13 : /**
14 : * @file
15 : * @brief Data structures and constants defined in the ELF specification.
16 : *
17 : * Reference documents can be found here: https://refspecs.linuxfoundation.org/elf/
18 : *
19 : * @defgroup llext_elf ELF constants and data types
20 : * @ingroup llext_apis
21 : * @{
22 : */
23 :
24 : #ifdef __cplusplus
25 : extern "C" {
26 : #endif
27 :
28 : /** Unsigned program address */
29 1 : typedef uint32_t elf32_addr;
30 : /** Unsigned medium integer */
31 1 : typedef uint16_t elf32_half;
32 : /** Unsigned file offset */
33 1 : typedef uint32_t elf32_off;
34 : /** Signed integer */
35 1 : typedef int32_t elf32_sword;
36 : /** Unsigned integer */
37 1 : typedef uint32_t elf32_word;
38 :
39 : /** Unsigned program address */
40 1 : typedef uint64_t elf64_addr;
41 : /** Unsigned medium integer */
42 1 : typedef uint16_t elf64_half;
43 : /** Unsigned file offset */
44 1 : typedef uint64_t elf64_off;
45 : /** Signed integer */
46 1 : typedef int32_t elf64_sword;
47 : /** Unsigned integer */
48 1 : typedef uint32_t elf64_word;
49 : /** Signed long integer */
50 1 : typedef int64_t elf64_sxword;
51 : /** Unsigned long integer */
52 1 : typedef uint64_t elf64_xword;
53 :
54 :
55 : /**
56 : * @brief ELF identifier block
57 : *
58 : * 4 byte magic (.ELF)
59 : * 1 byte class (Invalid, 32 bit, 64 bit)
60 : * 1 byte endianness (Invalid, LSB, MSB)
61 : * 1 byte version (1)
62 : * 1 byte OS ABI (0 None, 1 HP-UX, 2 NetBSD, 3 Linux)
63 : * 1 byte ABI (0)
64 : * 7 bytes padding
65 : */
66 1 : #define EI_NIDENT 16
67 :
68 : /**
69 : * @brief ELF Header(32-bit)
70 : */
71 1 : struct elf32_ehdr {
72 : /** Magic string identifying ELF binary */
73 1 : unsigned char e_ident[EI_NIDENT];
74 : /** Type of ELF */
75 1 : elf32_half e_type;
76 : /** Machine type */
77 1 : elf32_half e_machine;
78 : /** Object file version */
79 1 : elf32_word e_version;
80 : /** Virtual address of entry */
81 1 : elf32_addr e_entry;
82 : /** Program header table offset */
83 1 : elf32_off e_phoff;
84 : /** Section header table offset */
85 1 : elf32_off e_shoff;
86 : /** Processor specific flags */
87 1 : elf32_word e_flags;
88 : /** ELF header size */
89 1 : elf32_half e_ehsize;
90 : /** Program header count */
91 1 : elf32_half e_phentsize;
92 : /** Program header count */
93 1 : elf32_half e_phnum;
94 : /** Section header size */
95 1 : elf32_half e_shentsize;
96 : /** Section header count */
97 1 : elf32_half e_shnum;
98 : /** Section header containing section header string table */
99 1 : elf32_half e_shstrndx;
100 : };
101 :
102 : /**
103 : * @brief ELF Header(64-bit)
104 : */
105 1 : struct elf64_ehdr {
106 : /** Magic string identifying ELF binary */
107 1 : unsigned char e_ident[EI_NIDENT];
108 : /** Type of ELF */
109 1 : elf64_half e_type;
110 : /** Machine type */
111 1 : elf64_half e_machine;
112 : /** Object file version */
113 1 : elf64_word e_version;
114 : /** Virtual address of entry */
115 1 : elf64_addr e_entry;
116 : /** Program header table offset */
117 1 : elf64_off e_phoff;
118 : /** Section header table offset */
119 1 : elf64_off e_shoff;
120 : /** Processor specific flags */
121 1 : elf64_word e_flags;
122 : /** ELF header size */
123 1 : elf64_half e_ehsize;
124 : /** Program header size */
125 1 : elf64_half e_phentsize;
126 : /** Program header count */
127 1 : elf64_half e_phnum;
128 : /** Section header size */
129 1 : elf64_half e_shentsize;
130 : /** Section header count */
131 1 : elf64_half e_shnum;
132 : /** Section header containing section header string table */
133 1 : elf64_half e_shstrndx;
134 : };
135 :
136 : /** Relocatable (unlinked) ELF */
137 1 : #define ET_REL 1
138 :
139 : /** Executable (without PIC/PIE) ELF */
140 1 : #define ET_EXEC 2
141 :
142 : /** Dynamic (executable with PIC/PIE or shared lib) ELF */
143 1 : #define ET_DYN 3
144 :
145 : /** Core Dump */
146 1 : #define ET_CORE 4
147 :
148 : /**
149 : * @brief Section Header(32-bit)
150 : */
151 1 : struct elf32_shdr {
152 : /** Section header name index in section header string table */
153 1 : elf32_word sh_name;
154 : /** Section type */
155 1 : elf32_word sh_type;
156 : /** Section header attributes */
157 1 : elf32_word sh_flags;
158 : /** Address of section in the image */
159 1 : elf32_addr sh_addr;
160 : /** Location of section in the ELF binary in bytes */
161 1 : elf32_off sh_offset;
162 : /** Section size in bytes */
163 1 : elf32_word sh_size;
164 : /** Section header table link index, depends on section type */
165 1 : elf32_word sh_link;
166 : /** Section info, depends on section type */
167 1 : elf32_word sh_info;
168 : /** Section address alignment */
169 1 : elf32_word sh_addralign;
170 : /** Section contains table of fixed size entries sh_entsize bytes large */
171 1 : elf32_word sh_entsize;
172 : };
173 :
174 : /**
175 : * @brief Section Header(64-bit)
176 : */
177 1 : struct elf64_shdr {
178 : /** Section header name index in section header string table */
179 1 : elf64_word sh_name;
180 : /** Section type */
181 1 : elf64_word sh_type;
182 : /** Section header attributes */
183 1 : elf64_xword sh_flags;
184 : /** Address of section in the image */
185 1 : elf64_addr sh_addr;
186 : /** Location of section in the ELF binary in bytes */
187 1 : elf64_off sh_offset;
188 : /** Section size in bytes */
189 1 : elf64_xword sh_size;
190 : /** Section header table link index, depends on section type */
191 1 : elf64_word sh_link;
192 : /** Section info, depends on section type */
193 1 : elf64_word sh_info;
194 : /** Section address alignment */
195 1 : elf64_xword sh_addralign;
196 : /** Section contains table of fixed size entries sh_entsize bytes large */
197 1 : elf64_xword sh_entsize;
198 : };
199 :
200 : /** ELF section types */
201 1 : #define SHT_NULL 0x0 /**< Unused section */
202 1 : #define SHT_PROGBITS 0x1 /**< Program data */
203 1 : #define SHT_SYMTAB 0x2 /**< Symbol table */
204 1 : #define SHT_STRTAB 0x3 /**< String table */
205 1 : #define SHT_RELA 0x4 /**< Relocation entries with addends */
206 1 : #define SHT_NOBITS 0x8 /**< Program data with no file image */
207 1 : #define SHT_REL 0x9 /**< Relocation entries without addends */
208 1 : #define SHT_DYNSYM 0xB /**< Dynamic linking symbol table */
209 1 : #define SHT_INIT_ARRAY 0xe /**< Array of pointers to init functions */
210 1 : #define SHT_FINI_ARRAY 0xf /**< Array of pointers to termination functions */
211 1 : #define SHT_PREINIT_ARRAY 0x10 /**< Array of pointers to early init functions */
212 :
213 : /** ELF section flags */
214 1 : #define SHF_WRITE 0x1 /**< Section is writable */
215 1 : #define SHF_ALLOC 0x2 /**< Section is present in memory */
216 1 : #define SHF_EXECINSTR 0x4 /**< Section contains executable instructions */
217 1 : #define SHF_MASKOS 0x0ff00000 /**< OS specific flags */
218 1 : #define SHF_LLEXT_HAS_RELOCS 0x00100000 /**< Section is a target for relocations */
219 :
220 0 : #define SHF_BASIC_TYPE_MASK (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)
221 :
222 : /**
223 : * @brief Symbol table entry(32-bit)
224 : */
225 1 : struct elf32_sym {
226 : /** Name of the symbol as an index into the symbol string table */
227 1 : elf32_word st_name;
228 : /** Value or location of the symbol */
229 1 : elf32_addr st_value;
230 : /** Size of the symbol */
231 1 : elf32_word st_size;
232 : /** Symbol binding and type information */
233 1 : unsigned char st_info;
234 : /** Symbol visibility */
235 1 : unsigned char st_other;
236 : /** Symbols related section given by section header index */
237 1 : elf32_half st_shndx;
238 : };
239 :
240 : /**
241 : * @brief Symbol table entry(64-bit)
242 : */
243 1 : struct elf64_sym {
244 : /** Name of the symbol as an index into the symbol string table */
245 1 : elf64_word st_name;
246 : /** Symbol binding and type information */
247 1 : unsigned char st_info;
248 : /** Symbol visibility */
249 1 : unsigned char st_other;
250 : /** Symbols related section given by section header index */
251 1 : elf64_half st_shndx;
252 : /** Value or location of the symbol */
253 1 : elf64_addr st_value;
254 : /** Size of the symbol */
255 1 : elf64_xword st_size;
256 : };
257 :
258 : /** ELF section numbers */
259 1 : #define SHN_UNDEF 0 /**< Undefined section */
260 1 : #define SHN_LORESERVE 0xff00 /**< Start of reserved section numbers */
261 1 : #define SHN_ABS 0xfff1 /**< Special value for absolute symbols */
262 1 : #define SHN_COMMON 0xfff2 /**< Common block */
263 1 : #define SHN_HIRESERVE 0xffff /**< End of reserved section numbers */
264 :
265 : /** Symbol table entry types */
266 1 : #define STT_NOTYPE 0 /**< No type */
267 1 : #define STT_OBJECT 1 /**< Data or object */
268 1 : #define STT_FUNC 2 /**< Function */
269 1 : #define STT_SECTION 3 /**< Section */
270 1 : #define STT_FILE 4 /**< File name */
271 1 : #define STT_COMMON 5 /**< Common block */
272 1 : #define STT_LOOS 10 /**< Start of OS specific */
273 1 : #define STT_HIOS 12 /**< End of OS specific */
274 1 : #define STT_LOPROC 13 /**< Start of processor specific */
275 1 : #define STT_HIPROC 15 /**< End of processor specific */
276 :
277 : /** Symbol table entry bindings */
278 1 : #define STB_LOCAL 0 /**< Local symbol */
279 1 : #define STB_GLOBAL 1 /**< Global symbol */
280 1 : #define STB_WEAK 2 /**< Weak symbol */
281 1 : #define STB_LOOS 10 /**< Start of OS specific */
282 1 : #define STB_HIOS 12 /**< End of OS specific */
283 1 : #define STB_LOPROC 13 /**< Start of processor specific */
284 1 : #define STB_HIPROC 15 /**< End of processor specific */
285 :
286 : /**
287 : * @brief Symbol binding from 32bit st_info
288 : *
289 : * @param i Value of st_info
290 : */
291 1 : #define ELF32_ST_BIND(i) ((i) >> 4)
292 :
293 : /**
294 : * @brief Symbol type from 32bit st_info
295 : *
296 : * @param i Value of st_info
297 : */
298 1 : #define ELF32_ST_TYPE(i) ((i) & 0xf)
299 :
300 : /**
301 : * @brief Symbol binding from 32bit st_info
302 : *
303 : * @param i Value of st_info
304 : */
305 1 : #define ELF64_ST_BIND(i) ((i) >> 4)
306 :
307 :
308 : /**
309 : * @brief Symbol type from 32bit st_info
310 : *
311 : * @param i Value of st_info
312 : */
313 1 : #define ELF64_ST_TYPE(i) ((i) & 0xf)
314 :
315 : /**
316 : * @brief Relocation entry for 32-bit ELFs.
317 : *
318 : * This structure stores information describing a relocation to be performed.
319 : * Additional information about the relocation is stored at the location
320 : * pointed to by @ref r_offset.
321 : */
322 1 : struct elf32_rel {
323 : /** Offset in the section to perform a relocation */
324 1 : elf32_addr r_offset;
325 : /** Information about the relocation, related symbol and type */
326 1 : elf32_word r_info;
327 : };
328 :
329 : /**
330 : * @brief Relocation entry for 32-bit ELFs with addend.
331 : *
332 : * This structure stores information describing a relocation to be performed.
333 : */
334 1 : struct elf32_rela {
335 : /** Offset in the section to perform a relocation */
336 1 : elf32_addr r_offset;
337 : /** Information about the relocation, related symbol and type */
338 1 : elf32_word r_info;
339 : /** Offset to be applied to the symbol address */
340 1 : elf32_sword r_addend;
341 : };
342 :
343 : /**
344 : * @brief Relocation symbol index from r_info
345 : *
346 : * @param i Value of r_info
347 : */
348 1 : #define ELF32_R_SYM(i) ((i) >> 8)
349 :
350 : /**
351 : * @brief Relocation type from r_info
352 : *
353 : * @param i Value of r_info
354 : */
355 1 : #define ELF32_R_TYPE(i) ((i) & 0xff)
356 :
357 : /**
358 : * @brief Relocation entry for 64-bit ELFs.
359 : *
360 : * This structure stores information describing a relocation to be performed.
361 : * Additional information about the relocation is stored at the location
362 : * pointed to by @ref r_offset.
363 : */
364 1 : struct elf64_rel {
365 : /** Offset in the section to perform a relocation */
366 1 : elf64_addr r_offset;
367 : /** Information about the relocation, related symbol and type */
368 1 : elf64_xword r_info;
369 : };
370 :
371 : /**
372 : * @brief Relocation entry for 64-bit ELFs with addend.
373 : *
374 : * This structure stores information describing a relocation to be performed.
375 : */
376 1 : struct elf64_rela {
377 : /** Offset in the section to perform a relocation */
378 1 : elf64_addr r_offset;
379 : /** Information about the relocation, related symbol and type */
380 1 : elf64_xword r_info;
381 : /** Offset to be applied to the symbol address */
382 1 : elf64_sxword r_addend;
383 : };
384 :
385 : /** @brief Relocation symbol from r_info
386 : *
387 : * @param i Value of r_info
388 : */
389 1 : #define ELF64_R_SYM(i) ((i) >> 32)
390 :
391 : /**
392 : * @brief Relocation type from r_info
393 : *
394 : * @param i Value of r_info
395 : */
396 1 : #define ELF64_R_TYPE(i) ((i) & 0xffffffff)
397 :
398 : /**
399 : * Dynamic features currently not used by LLEXT
400 : * @cond ignore
401 : */
402 :
403 : /**
404 : * @brief Program header(32-bit)
405 : */
406 : struct elf32_phdr {
407 : elf32_word p_type; /**< Type of segment */
408 : elf32_off p_offset; /**< Offset in file */
409 : elf32_addr p_vaddr; /**< Virtual address in memory */
410 : elf32_addr p_paddr; /**< Physical address (usually reserved) */
411 : elf32_word p_filesz; /**< Size of segment in file */
412 : elf32_word p_memsz; /**< Size of segment in memory */
413 : elf32_word p_flags; /**< Segment flags */
414 : elf32_word p_align; /**< Alignment of segment */
415 : };
416 :
417 : /**
418 : * @brief Program header(64-bit)
419 : */
420 : struct elf64_phdr {
421 : elf64_word p_type; /**< Type of segment */
422 : elf64_off p_offset; /**< Offset in file */
423 : elf64_addr p_vaddr; /**< Virtual address in memory */
424 : elf64_addr p_paddr; /**< Physical address (usually reserved) */
425 : elf64_xword p_filesz; /**< Size of segment in file */
426 : elf64_xword p_memsz; /**< Size of segment in memory */
427 : elf64_word p_flags; /**< Segment flags */
428 : elf64_xword p_align; /**< Alignment of segment */
429 : };
430 :
431 : /**
432 : * @brief Program segment type
433 : */
434 : #define PT_LOAD 1
435 :
436 : /**
437 : * @brief Dynamic section entry(32-bit)
438 : */
439 : struct elf32_dyn {
440 : elf32_sword d_tag; /**< Entry tag */
441 : union {
442 : elf32_word d_val; /**< Integer value */
443 : elf32_addr d_ptr; /**< Address value */
444 : } d_un;
445 : };
446 :
447 : /**
448 : * @brief Dynamic section entry(64-bit)
449 : */
450 : struct elf64_dyn {
451 : elf64_sxword d_tag; /**< Entry tag */
452 : union {
453 : elf64_xword d_val; /**< Integer value */
454 : elf64_addr d_ptr; /**< Address value */
455 : } d_un;
456 : };
457 : /** @endcond */
458 :
459 : #if defined(CONFIG_64BIT) || defined(__DOXYGEN__)
460 : /** Machine sized elf header structure */
461 1 : typedef struct elf64_ehdr elf_ehdr_t;
462 : /** Machine sized section header structure */
463 1 : typedef struct elf64_shdr elf_shdr_t;
464 : /** Machine sized program header structure */
465 1 : typedef struct elf64_phdr elf_phdr_t;
466 : /** Machine sized program address */
467 1 : typedef elf64_addr elf_addr;
468 : /** Machine sized small integer */
469 1 : typedef elf64_half elf_half;
470 : /** Machine sized integer */
471 1 : typedef elf64_xword elf_word;
472 : /** Machine sized relocation struct */
473 1 : typedef struct elf64_rel elf_rel_t;
474 : /** Machine sized relocation struct with addend */
475 1 : typedef struct elf64_rela elf_rela_t;
476 : /** Machine sized symbol struct */
477 1 : typedef struct elf64_sym elf_sym_t;
478 : /** Machine sized macro alias for obtaining a relocation symbol */
479 1 : #define ELF_R_SYM ELF64_R_SYM
480 : /** Machine sized macro alias for obtaining a relocation type */
481 1 : #define ELF_R_TYPE ELF64_R_TYPE
482 : /** Machine sized macro alias for obtaining a symbol bind */
483 1 : #define ELF_ST_BIND ELF64_ST_BIND
484 : /** Machine sized macro alias for obtaining a symbol type */
485 1 : #define ELF_ST_TYPE ELF64_ST_TYPE
486 : #else
487 : /** Machine sized elf header structure */
488 : typedef struct elf32_ehdr elf_ehdr_t;
489 : /** Machine sized section header structure */
490 : typedef struct elf32_shdr elf_shdr_t;
491 : /** Machine sized program header structure */
492 : typedef struct elf32_phdr elf_phdr_t;
493 : /** Machine sized program address */
494 : typedef elf32_addr elf_addr;
495 : /** Machine sized small integer */
496 : typedef elf32_half elf_half;
497 : /** Machine sized integer */
498 : typedef elf32_word elf_word;
499 : /** Machine sized relocation struct */
500 : typedef struct elf32_rel elf_rel_t;
501 : /** Machine sized relocation struct with addend */
502 : typedef struct elf32_rela elf_rela_t;
503 : /** Machine sized symbol struct */
504 : typedef struct elf32_sym elf_sym_t;
505 : /** Machine sized macro alias for obtaining a relocation symbol */
506 : #define ELF_R_SYM ELF32_R_SYM
507 : /** Machine sized macro alias for obtaining a relocation type */
508 : #define ELF_R_TYPE ELF32_R_TYPE
509 : /** Machine sized macro alias for obtaining a symbol bind */
510 : #define ELF_ST_BIND ELF32_ST_BIND
511 : /** Machine sized macro alias for obtaining a symbol type */
512 : #define ELF_ST_TYPE ELF32_ST_TYPE
513 : #endif
514 :
515 : #ifdef __cplusplus
516 : }
517 : #endif
518 :
519 : /**
520 : * @}
521 : */
522 :
523 : #endif /* ZEPHYR_LLEXT_ELF_H */
|