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