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 typedef uint32_t elf32_addr; 30 /** Unsigned medium integer */ 31 typedef uint16_t elf32_half; 32 /** Unsigned file offset */ 33 typedef uint32_t elf32_off; 34 /** Signed integer */ 35 typedef int32_t elf32_sword; 36 /** Unsigned integer */ 37 typedef uint32_t elf32_word; 38 39 /** Unsigned program address */ 40 typedef uint64_t elf64_addr; 41 /** Unsigned medium integer */ 42 typedef uint16_t elf64_half; 43 /** Unsigned file offset */ 44 typedef uint64_t elf64_off; 45 /** Signed integer */ 46 typedef int32_t elf64_sword; 47 /** Unsigned integer */ 48 typedef uint32_t elf64_word; 49 /** Signed long integer */ 50 typedef int64_t elf64_sxword; 51 /** Unsigned long integer */ 52 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 #define EI_NIDENT 16 67 68 /** 69 * @brief ELF Header(32-bit) 70 */ 71 struct elf32_ehdr { 72 /** Magic string identifying ELF binary */ 73 unsigned char e_ident[EI_NIDENT]; 74 /** Type of ELF */ 75 elf32_half e_type; 76 /** Machine type */ 77 elf32_half e_machine; 78 /** Object file version */ 79 elf32_word e_version; 80 /** Virtual address of entry */ 81 elf32_addr e_entry; 82 /** Program header table offset */ 83 elf32_off e_phoff; 84 /** Section header table offset */ 85 elf32_off e_shoff; 86 /** Processor specific flags */ 87 elf32_word e_flags; 88 /** ELF header size */ 89 elf32_half e_ehsize; 90 /** Program header count */ 91 elf32_half e_phentsize; 92 /** Program header count */ 93 elf32_half e_phnum; 94 /** Section header size */ 95 elf32_half e_shentsize; 96 /** Section header count */ 97 elf32_half e_shnum; 98 /** Section header containing section header string table */ 99 elf32_half e_shstrndx; 100 }; 101 102 /** 103 * @brief ELF Header(64-bit) 104 */ 105 struct elf64_ehdr { 106 /** Magic string identifying ELF binary */ 107 unsigned char e_ident[EI_NIDENT]; 108 /** Type of ELF */ 109 elf64_half e_type; 110 /** Machine type */ 111 elf64_half e_machine; 112 /** Object file version */ 113 elf64_word e_version; 114 /** Virtual address of entry */ 115 elf64_addr e_entry; 116 /** Program header table offset */ 117 elf64_off e_phoff; 118 /** Section header table offset */ 119 elf64_off e_shoff; 120 /** Processor specific flags */ 121 elf64_word e_flags; 122 /** ELF header size */ 123 elf64_half e_ehsize; 124 /** Program header size */ 125 elf64_half e_phentsize; 126 /** Program header count */ 127 elf64_half e_phnum; 128 /** Section header size */ 129 elf64_half e_shentsize; 130 /** Section header count */ 131 elf64_half e_shnum; 132 /** Section header containing section header string table */ 133 elf64_half e_shstrndx; 134 }; 135 136 /** Relocatable (unlinked) ELF */ 137 #define ET_REL 1 138 139 /** Executable (without PIC/PIE) ELF */ 140 #define ET_EXEC 2 141 142 /** Dynamic (executable with PIC/PIE or shared lib) ELF */ 143 #define ET_DYN 3 144 145 /** Core Dump */ 146 #define ET_CORE 4 147 148 /** 149 * @brief Section Header(32-bit) 150 */ 151 struct elf32_shdr { 152 /** Section header name index in section header string table */ 153 elf32_word sh_name; 154 /** Section type */ 155 elf32_word sh_type; 156 /** Section header attributes */ 157 elf32_word sh_flags; 158 /** Address of section in the image */ 159 elf32_addr sh_addr; 160 /** Location of section in the ELF binary in bytes */ 161 elf32_off sh_offset; 162 /** Section size in bytes */ 163 elf32_word sh_size; 164 /** Section header table link index, depends on section type */ 165 elf32_word sh_link; 166 /** Section info, depends on section type */ 167 elf32_word sh_info; 168 /** Section address alignment */ 169 elf32_word sh_addralign; 170 /** Section contains table of fixed size entries sh_entsize bytes large */ 171 elf32_word sh_entsize; 172 }; 173 174 /** 175 * @brief Section Header(64-bit) 176 */ 177 struct elf64_shdr { 178 /** Section header name index in section header string table */ 179 elf64_word sh_name; 180 /** Section type */ 181 elf64_word sh_type; 182 /** Section header attributes */ 183 elf64_xword sh_flags; 184 /** Address of section in the image */ 185 elf64_addr sh_addr; 186 /** Location of section in the ELF binary in bytes */ 187 elf64_off sh_offset; 188 /** Section size in bytes */ 189 elf64_xword sh_size; 190 /** Section header table link index, depends on section type */ 191 elf64_word sh_link; 192 /** Section info, depends on section type */ 193 elf64_word sh_info; 194 /** Section address alignment */ 195 elf64_xword sh_addralign; 196 /** Section contains table of fixed size entries sh_entsize bytes large */ 197 elf64_xword sh_entsize; 198 }; 199 200 /** ELF section types */ 201 #define SHT_NULL 0x0 /**< Unused section */ 202 #define SHT_PROGBITS 0x1 /**< Program data */ 203 #define SHT_SYMTAB 0x2 /**< Symbol table */ 204 #define SHT_STRTAB 0x3 /**< String table */ 205 #define SHT_RELA 0x4 /**< Relocation entries with addends */ 206 #define SHT_NOBITS 0x8 /**< Program data with no file image */ 207 #define SHT_REL 0x9 /**< Relocation entries without addends */ 208 #define SHT_DYNSYM 0xB /**< Dynamic linking symbol table */ 209 #define SHT_INIT_ARRAY 0xe /**< Array of pointers to init functions */ 210 #define SHT_FINI_ARRAY 0xf /**< Array of pointers to termination functions */ 211 #define SHT_PREINIT_ARRAY 0x10 /**< Array of pointers to early init functions */ 212 213 /** ELF section flags */ 214 #define SHF_WRITE 0x1 /**< Section is writable */ 215 #define SHF_ALLOC 0x2 /**< Section is present in memory */ 216 #define SHF_EXECINSTR 0x4 /**< Section contains executable instructions */ 217 218 #define SHF_BASIC_TYPE_MASK (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR) 219 220 /** 221 * @brief Symbol table entry(32-bit) 222 */ 223 struct elf32_sym { 224 /** Name of the symbol as an index into the symbol string table */ 225 elf32_word st_name; 226 /** Value or location of the symbol */ 227 elf32_addr st_value; 228 /** Size of the symbol */ 229 elf32_word st_size; 230 /** Symbol binding and type information */ 231 unsigned char st_info; 232 /** Symbol visibility */ 233 unsigned char st_other; 234 /** Symbols related section given by section header index */ 235 elf32_half st_shndx; 236 }; 237 238 /** 239 * @brief Symbol table entry(64-bit) 240 */ 241 struct elf64_sym { 242 /** Name of the symbol as an index into the symbol string table */ 243 elf64_word st_name; 244 /** Symbol binding and type information */ 245 unsigned char st_info; 246 /** Symbol visibility */ 247 unsigned char st_other; 248 /** Symbols related section given by section header index */ 249 elf64_half st_shndx; 250 /** Value or location of the symbol */ 251 elf64_addr st_value; 252 /** Size of the symbol */ 253 elf64_xword st_size; 254 }; 255 256 /** ELF section numbers */ 257 #define SHN_UNDEF 0 /**< Undefined section */ 258 #define SHN_LORESERVE 0xff00 /**< Start of reserved section numbers */ 259 #define SHN_ABS 0xfff1 /**< Special value for absolute symbols */ 260 #define SHN_COMMON 0xfff2 /**< Common block */ 261 #define SHN_HIRESERVE 0xffff /**< End of reserved section numbers */ 262 263 /** Symbol table entry types */ 264 #define STT_NOTYPE 0 /**< No type */ 265 #define STT_OBJECT 1 /**< Data or object */ 266 #define STT_FUNC 2 /**< Function */ 267 #define STT_SECTION 3 /**< Section */ 268 #define STT_FILE 4 /**< File name */ 269 #define STT_COMMON 5 /**< Common block */ 270 #define STT_LOOS 10 /**< Start of OS specific */ 271 #define STT_HIOS 12 /**< End of OS specific */ 272 #define STT_LOPROC 13 /**< Start of processor specific */ 273 #define STT_HIPROC 15 /**< End of processor specific */ 274 275 /** Symbol table entry bindings */ 276 #define STB_LOCAL 0 /**< Local symbol */ 277 #define STB_GLOBAL 1 /**< Global symbol */ 278 #define STB_WEAK 2 /**< Weak symbol */ 279 #define STB_LOOS 10 /**< Start of OS specific */ 280 #define STB_HIOS 12 /**< End of OS specific */ 281 #define STB_LOPROC 13 /**< Start of processor specific */ 282 #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 #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 #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 #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 #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 struct elf32_rel { 321 /** Offset in the section to perform a relocation */ 322 elf32_addr r_offset; 323 /** Information about the relocation, related symbol and type */ 324 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 struct elf32_rela { 333 /** Offset in the section to perform a relocation */ 334 elf32_addr r_offset; 335 /** Information about the relocation, related symbol and type */ 336 elf32_word r_info; 337 /** Offset to be applied to the symbol address */ 338 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 #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 #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 struct elf64_rel { 363 /** Offset in the section to perform a relocation */ 364 elf64_addr r_offset; 365 /** Information about the relocation, related symbol and type */ 366 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 struct elf64_rela { 375 /** Offset in the section to perform a relocation */ 376 elf64_addr r_offset; 377 /** Information about the relocation, related symbol and type */ 378 elf64_xword r_info; 379 /** Offset to be applied to the symbol address */ 380 elf64_sxword r_addend; 381 }; 382 383 /** @brief Relocation symbol from r_info 384 * 385 * @param i Value of r_info 386 */ 387 #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 #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 typedef struct elf64_ehdr elf_ehdr_t; 460 /** Machine sized section header structure */ 461 typedef struct elf64_shdr elf_shdr_t; 462 /** Machine sized program header structure */ 463 typedef struct elf64_phdr elf_phdr_t; 464 /** Machine sized program address */ 465 typedef elf64_addr elf_addr; 466 /** Machine sized small integer */ 467 typedef elf64_half elf_half; 468 /** Machine sized integer */ 469 typedef elf64_xword elf_word; 470 /** Machine sized relocation struct */ 471 typedef struct elf64_rel elf_rel_t; 472 /** Machine sized relocation struct with addend */ 473 typedef struct elf64_rela elf_rela_t; 474 /** Machine sized symbol struct */ 475 typedef struct elf64_sym elf_sym_t; 476 /** Machine sized macro alias for obtaining a relocation symbol */ 477 #define ELF_R_SYM ELF64_R_SYM 478 /** Machine sized macro alias for obtaining a relocation type */ 479 #define ELF_R_TYPE ELF64_R_TYPE 480 /** Machine sized macro alias for obtaining a symbol bind */ 481 #define ELF_ST_BIND ELF64_ST_BIND 482 /** Machine sized macro alias for obtaining a symbol type */ 483 #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 */ 522