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 : 218 0 : #define SHF_BASIC_TYPE_MASK (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR) 219 : 220 : /** 221 : * @brief Symbol table entry(32-bit) 222 : */ 223 1 : struct elf32_sym { 224 : /** Name of the symbol as an index into the symbol string table */ 225 1 : elf32_word st_name; 226 : /** Value or location of the symbol */ 227 1 : elf32_addr st_value; 228 : /** Size of the symbol */ 229 1 : elf32_word st_size; 230 : /** Symbol binding and type information */ 231 1 : unsigned char st_info; 232 : /** Symbol visibility */ 233 1 : unsigned char st_other; 234 : /** Symbols related section given by section header index */ 235 1 : elf32_half st_shndx; 236 : }; 237 : 238 : /** 239 : * @brief Symbol table entry(64-bit) 240 : */ 241 1 : struct elf64_sym { 242 : /** Name of the symbol as an index into the symbol string table */ 243 1 : elf64_word st_name; 244 : /** Symbol binding and type information */ 245 1 : unsigned char st_info; 246 : /** Symbol visibility */ 247 1 : unsigned char st_other; 248 : /** Symbols related section given by section header index */ 249 1 : elf64_half st_shndx; 250 : /** Value or location of the symbol */ 251 1 : elf64_addr st_value; 252 : /** Size of the symbol */ 253 1 : elf64_xword st_size; 254 : }; 255 : 256 : /** ELF section numbers */ 257 1 : #define SHN_UNDEF 0 /**< Undefined section */ 258 1 : #define SHN_LORESERVE 0xff00 /**< Start of reserved section numbers */ 259 1 : #define SHN_ABS 0xfff1 /**< Special value for absolute symbols */ 260 1 : #define SHN_COMMON 0xfff2 /**< Common block */ 261 1 : #define SHN_HIRESERVE 0xffff /**< End of reserved section numbers */ 262 : 263 : /** Symbol table entry types */ 264 1 : #define STT_NOTYPE 0 /**< No type */ 265 1 : #define STT_OBJECT 1 /**< Data or object */ 266 1 : #define STT_FUNC 2 /**< Function */ 267 1 : #define STT_SECTION 3 /**< Section */ 268 1 : #define STT_FILE 4 /**< File name */ 269 1 : #define STT_COMMON 5 /**< Common block */ 270 1 : #define STT_LOOS 10 /**< Start of OS specific */ 271 1 : #define STT_HIOS 12 /**< End of OS specific */ 272 1 : #define STT_LOPROC 13 /**< Start of processor specific */ 273 1 : #define STT_HIPROC 15 /**< End of processor specific */ 274 : 275 : /** Symbol table entry bindings */ 276 1 : #define STB_LOCAL 0 /**< Local symbol */ 277 1 : #define STB_GLOBAL 1 /**< Global symbol */ 278 1 : #define STB_WEAK 2 /**< Weak symbol */ 279 1 : #define STB_LOOS 10 /**< Start of OS specific */ 280 1 : #define STB_HIOS 12 /**< End of OS specific */ 281 1 : #define STB_LOPROC 13 /**< Start of processor specific */ 282 1 : #define STB_HIPROC 15 /**< End of processor specific */ 283 : 284 : /** 285 : * @brief Symbol binding from 32bit st_info 286 : * 287 : * @param i Value of st_info 288 : */ 289 1 : #define ELF32_ST_BIND(i) ((i) >> 4) 290 : 291 : /** 292 : * @brief Symbol type from 32bit st_info 293 : * 294 : * @param i Value of st_info 295 : */ 296 1 : #define ELF32_ST_TYPE(i) ((i) & 0xf) 297 : 298 : /** 299 : * @brief Symbol binding from 32bit st_info 300 : * 301 : * @param i Value of st_info 302 : */ 303 1 : #define ELF64_ST_BIND(i) ((i) >> 4) 304 : 305 : 306 : /** 307 : * @brief Symbol type from 32bit st_info 308 : * 309 : * @param i Value of st_info 310 : */ 311 1 : #define ELF64_ST_TYPE(i) ((i) & 0xf) 312 : 313 : /** 314 : * @brief Relocation entry for 32-bit ELFs. 315 : * 316 : * This structure stores information describing a relocation to be performed. 317 : * Additional information about the relocation is stored at the location 318 : * pointed to by @ref r_offset. 319 : */ 320 1 : struct elf32_rel { 321 : /** Offset in the section to perform a relocation */ 322 1 : elf32_addr r_offset; 323 : /** Information about the relocation, related symbol and type */ 324 1 : elf32_word r_info; 325 : }; 326 : 327 : /** 328 : * @brief Relocation entry for 32-bit ELFs with addend. 329 : * 330 : * This structure stores information describing a relocation to be performed. 331 : */ 332 1 : struct elf32_rela { 333 : /** Offset in the section to perform a relocation */ 334 1 : elf32_addr r_offset; 335 : /** Information about the relocation, related symbol and type */ 336 1 : elf32_word r_info; 337 : /** Offset to be applied to the symbol address */ 338 1 : elf32_sword r_addend; 339 : }; 340 : 341 : /** 342 : * @brief Relocation symbol index from r_info 343 : * 344 : * @param i Value of r_info 345 : */ 346 1 : #define ELF32_R_SYM(i) ((i) >> 8) 347 : 348 : /** 349 : * @brief Relocation type from r_info 350 : * 351 : * @param i Value of r_info 352 : */ 353 1 : #define ELF32_R_TYPE(i) ((i) & 0xff) 354 : 355 : /** 356 : * @brief Relocation entry for 64-bit ELFs. 357 : * 358 : * This structure stores information describing a relocation to be performed. 359 : * Additional information about the relocation is stored at the location 360 : * pointed to by @ref r_offset. 361 : */ 362 1 : struct elf64_rel { 363 : /** Offset in the section to perform a relocation */ 364 1 : elf64_addr r_offset; 365 : /** Information about the relocation, related symbol and type */ 366 1 : elf64_xword r_info; 367 : }; 368 : 369 : /** 370 : * @brief Relocation entry for 64-bit ELFs with addend. 371 : * 372 : * This structure stores information describing a relocation to be performed. 373 : */ 374 1 : struct elf64_rela { 375 : /** Offset in the section to perform a relocation */ 376 1 : elf64_addr r_offset; 377 : /** Information about the relocation, related symbol and type */ 378 1 : elf64_xword r_info; 379 : /** Offset to be applied to the symbol address */ 380 1 : elf64_sxword r_addend; 381 : }; 382 : 383 : /** @brief Relocation symbol from r_info 384 : * 385 : * @param i Value of r_info 386 : */ 387 1 : #define ELF64_R_SYM(i) ((i) >> 32) 388 : 389 : /** 390 : * @brief Relocation type from r_info 391 : * 392 : * @param i Value of r_info 393 : */ 394 1 : #define ELF64_R_TYPE(i) ((i) & 0xffffffff) 395 : 396 : /** 397 : * Dynamic features currently not used by LLEXT 398 : * @cond ignore 399 : */ 400 : 401 : /** 402 : * @brief Program header(32-bit) 403 : */ 404 : struct elf32_phdr { 405 : elf32_word p_type; /**< Type of segment */ 406 : elf32_off p_offset; /**< Offset in file */ 407 : elf32_addr p_vaddr; /**< Virtual address in memory */ 408 : elf32_addr p_paddr; /**< Physical address (usually reserved) */ 409 : elf32_word p_filesz; /**< Size of segment in file */ 410 : elf32_word p_memsz; /**< Size of segment in memory */ 411 : elf32_word p_flags; /**< Segment flags */ 412 : elf32_word p_align; /**< Alignment of segment */ 413 : }; 414 : 415 : /** 416 : * @brief Program header(64-bit) 417 : */ 418 : struct elf64_phdr { 419 : elf64_word p_type; /**< Type of segment */ 420 : elf64_off p_offset; /**< Offset in file */ 421 : elf64_addr p_vaddr; /**< Virtual address in memory */ 422 : elf64_addr p_paddr; /**< Physical address (usually reserved) */ 423 : elf64_xword p_filesz; /**< Size of segment in file */ 424 : elf64_xword p_memsz; /**< Size of segment in memory */ 425 : elf64_word p_flags; /**< Segment flags */ 426 : elf64_xword p_align; /**< Alignment of segment */ 427 : }; 428 : 429 : /** 430 : * @brief Program segment type 431 : */ 432 : #define PT_LOAD 1 433 : 434 : /** 435 : * @brief Dynamic section entry(32-bit) 436 : */ 437 : struct elf32_dyn { 438 : elf32_sword d_tag; /**< Entry tag */ 439 : union { 440 : elf32_word d_val; /**< Integer value */ 441 : elf32_addr d_ptr; /**< Address value */ 442 : } d_un; 443 : }; 444 : 445 : /** 446 : * @brief Dynamic section entry(64-bit) 447 : */ 448 : struct elf64_dyn { 449 : elf64_sxword d_tag; /**< Entry tag */ 450 : union { 451 : elf64_xword d_val; /**< Integer value */ 452 : elf64_addr d_ptr; /**< Address value */ 453 : } d_un; 454 : }; 455 : /** @endcond */ 456 : 457 : #if defined(CONFIG_64BIT) || defined(__DOXYGEN__) 458 : /** Machine sized elf header structure */ 459 1 : typedef struct elf64_ehdr elf_ehdr_t; 460 : /** Machine sized section header structure */ 461 1 : typedef struct elf64_shdr elf_shdr_t; 462 : /** Machine sized program header structure */ 463 1 : typedef struct elf64_phdr elf_phdr_t; 464 : /** Machine sized program address */ 465 1 : typedef elf64_addr elf_addr; 466 : /** Machine sized small integer */ 467 1 : typedef elf64_half elf_half; 468 : /** Machine sized integer */ 469 1 : typedef elf64_xword elf_word; 470 : /** Machine sized relocation struct */ 471 1 : typedef struct elf64_rel elf_rel_t; 472 : /** Machine sized relocation struct with addend */ 473 1 : typedef struct elf64_rela elf_rela_t; 474 : /** Machine sized symbol struct */ 475 1 : typedef struct elf64_sym elf_sym_t; 476 : /** Machine sized macro alias for obtaining a relocation symbol */ 477 1 : #define ELF_R_SYM ELF64_R_SYM 478 : /** Machine sized macro alias for obtaining a relocation type */ 479 1 : #define ELF_R_TYPE ELF64_R_TYPE 480 : /** Machine sized macro alias for obtaining a symbol bind */ 481 1 : #define ELF_ST_BIND ELF64_ST_BIND 482 : /** Machine sized macro alias for obtaining a symbol type */ 483 1 : #define ELF_ST_TYPE ELF64_ST_TYPE 484 : #else 485 : /** Machine sized elf header structure */ 486 : typedef struct elf32_ehdr elf_ehdr_t; 487 : /** Machine sized section header structure */ 488 : typedef struct elf32_shdr elf_shdr_t; 489 : /** Machine sized program header structure */ 490 : typedef struct elf32_phdr elf_phdr_t; 491 : /** Machine sized program address */ 492 : typedef elf32_addr elf_addr; 493 : /** Machine sized small integer */ 494 : typedef elf32_half elf_half; 495 : /** Machine sized integer */ 496 : typedef elf32_word elf_word; 497 : /** Machine sized relocation struct */ 498 : typedef struct elf32_rel elf_rel_t; 499 : /** Machine sized relocation struct with addend */ 500 : typedef struct elf32_rela elf_rela_t; 501 : /** Machine sized symbol struct */ 502 : typedef struct elf32_sym elf_sym_t; 503 : /** Machine sized macro alias for obtaining a relocation symbol */ 504 : #define ELF_R_SYM ELF32_R_SYM 505 : /** Machine sized macro alias for obtaining a relocation type */ 506 : #define ELF_R_TYPE ELF32_R_TYPE 507 : /** Machine sized macro alias for obtaining a symbol bind */ 508 : #define ELF_ST_BIND ELF32_ST_BIND 509 : /** Machine sized macro alias for obtaining a symbol type */ 510 : #define ELF_ST_TYPE ELF32_ST_TYPE 511 : #endif 512 : 513 : #ifdef __cplusplus 514 : } 515 : #endif 516 : 517 : /** 518 : * @} 519 : */ 520 : 521 : #endif /* ZEPHYR_LLEXT_ELF_H */