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