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 /** Value or location of the symbol */ 235 elf64_addr st_value; 236 /** Size of the symbol */ 237 elf64_xword st_size; 238 /** Symbol binding and type information */ 239 unsigned char st_info; 240 /** Symbol visibility */ 241 unsigned char st_other; 242 /** Symbols related section given by section header index */ 243 elf64_half st_shndx; 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 /** 310 * @brief Relocation symbol index from r_info 311 * 312 * @param i Value of r_info 313 */ 314 #define ELF32_R_SYM(i) ((i) >> 8) 315 316 /** 317 * @brief Relocation type from r_info 318 * 319 * @param i Value of r_info 320 */ 321 #define ELF32_R_TYPE(i) ((i) & 0xff) 322 323 /** 324 * @brief Relocation entry for 64-bit ELFs 325 */ 326 struct elf64_rel { 327 /** Offset in section to perform a relocation */ 328 elf64_addr r_offset; 329 /** Information about relocation, related symbol and type */ 330 elf64_xword r_info; 331 }; 332 333 /** @brief Relocation symbol from r_info 334 * 335 * @param i Value of r_info 336 */ 337 #define ELF64_R_SYM(i) ((i) >> 32) 338 339 /** 340 * @brief Relocation type from r_info 341 * 342 * @param i Value of r_info 343 */ 344 #define ELF64_R_TYPE(i) ((i) & 0xffffffff) 345 346 #define R_386_NONE 0 347 #define R_386_32 1 348 #define R_386_PC32 2 349 #define R_386_GOT32 3 350 #define R_386_PLT32 4 351 #define R_386_COPY 5 352 #define R_386_GLOB_DAT 6 353 #define R_386_JMP_SLOT 7 354 #define R_386_RELATIVE 8 355 #define R_386_GOTOFF 9 356 357 #define R_ARM_NONE 0 358 #define R_ARM_PC24 1 359 #define R_ARM_ABS32 2 360 #define R_ARM_REL32 3 361 #define R_ARM_COPY 4 362 #define R_ARM_CALL 28 363 #define R_ARM_V4BX 40 364 365 #define R_XTENSA_NONE 0 366 #define R_XTENSA_32 1 367 #define R_XTENSA_SLOT0_OP 20 368 369 /** 370 * @brief Program header(32-bit) 371 */ 372 struct elf32_phdr { 373 elf32_word p_type; 374 elf32_off p_offset; 375 elf32_addr p_vaddr; 376 elf32_addr p_paddr; 377 elf32_word p_filesz; 378 elf32_word p_memsz; 379 elf32_word p_flags; 380 elf32_word p_align; 381 }; 382 383 /** 384 * @brief Program header(64-bit) 385 */ 386 struct elf64_phdr { 387 elf64_word p_type; 388 elf64_off p_offset; 389 elf64_addr p_vaddr; 390 elf64_addr p_paddr; 391 elf64_xword p_filesz; 392 elf64_xword p_memsz; 393 elf64_word p_flags; 394 elf64_xword p_align; 395 }; 396 397 /** 398 * @brief Program segment type 399 */ 400 #define PT_LOAD 1 401 402 /** 403 * @brief Dynamic section entry(32-bit) 404 */ 405 struct elf32_dyn { 406 elf32_sword d_tag; 407 union { 408 elf32_word d_val; 409 elf32_addr d_ptr; 410 } d_un; 411 }; 412 413 /** 414 * @brief Dynamic section entry(64-bit) 415 */ 416 struct elf64_dyn { 417 elf64_sxword d_tag; 418 union { 419 elf64_xword d_val; 420 elf64_addr d_ptr; 421 } d_un; 422 }; 423 424 #if defined(CONFIG_64BIT) || defined(__DOXYGEN__) 425 /** Machine sized elf header structure */ 426 typedef struct elf64_ehdr elf_ehdr_t; 427 /** Machine sized section header structure */ 428 typedef struct elf64_shdr elf_shdr_t; 429 /** Machine sized program header structure */ 430 typedef struct elf64_phdr elf_phdr_t; 431 /** Machine sized program address */ 432 typedef elf64_addr elf_addr; 433 /** Machine sized small integer */ 434 typedef elf64_half elf_half; 435 /** Machine sized integer */ 436 typedef elf64_xword elf_word; 437 /** Machine sized relocation struct */ 438 typedef struct elf64_rela elf_rel_t; 439 /** Machine sized symbol struct */ 440 typedef struct elf64_sym elf_sym_t; 441 /** Machine sized macro alias for obtaining a relocation symbol */ 442 #define ELF_R_SYM ELF64_R_SYM 443 /** Machine sized macro alias for obtaining a relocation type */ 444 #define ELF_R_TYPE ELF64_R_TYPE 445 /** Machine sized macro alias for obtaining a symbol bind */ 446 #define ELF_ST_BIND ELF64_ST_BIND 447 /** Machine sized macro alias for obtaining a symbol type */ 448 #define ELF_ST_TYPE ELF64_ST_TYPE 449 #else 450 /** Machine sized elf header structure */ 451 typedef struct elf32_ehdr elf_ehdr_t; 452 /** Machine sized section header structure */ 453 typedef struct elf32_shdr elf_shdr_t; 454 /** Machine sized program header structure */ 455 typedef struct elf32_phdr elf_phdr_t; 456 /** Machine sized program address */ 457 typedef elf32_addr elf_addr; 458 /** Machine sized small integer */ 459 typedef elf32_half elf_half; 460 /** Machine sized integer */ 461 typedef elf32_word elf_word; 462 /** Machine sized relocation struct */ 463 typedef struct elf32_rel elf_rel_t; 464 /** Machine sized symbol struct */ 465 typedef struct elf32_sym elf_sym_t; 466 /** Machine sized macro alias for obtaining a relocation symbol */ 467 #define ELF_R_SYM ELF32_R_SYM 468 /** Machine sized macro alias for obtaining a relocation type */ 469 #define ELF_R_TYPE ELF32_R_TYPE 470 /** Machine sized macro alias for obtaining a symbol bind */ 471 #define ELF_ST_BIND ELF32_ST_BIND 472 /** Machine sized macro alias for obtaining a symbol type */ 473 #define ELF_ST_TYPE ELF32_ST_TYPE 474 #endif 475 476 #ifdef __cplusplus 477 } 478 #endif 479 480 /** 481 * @} 482 */ 483 484 #endif /* ZEPHYR_LLEXT_ELF_H */ 485