elf.h (19532B)
1 /* ELF wire-format constants, structs, and small helpers shared between 2 * obj/elf_emit.c, obj/elf_read.c, and link/elf_exe.c. 3 * 4 * Private to src/. The public ObjBuilder/Linker surface is format-neutral 5 * (obj/obj.h, link/link.h); the ELF spelling of those abstractions only 6 * exists inside libkit. 7 * 8 * Scope: 64-bit little-endian only. The per-arch reloc mapping is split 9 * across elf_reloc_<arch>.c (one TU per arch); emit_elf and the linker 10 * dispatch to the right table by Compiler.target.arch. */ 11 12 #ifndef KIT_OBJ_ELF_H 13 #define KIT_OBJ_ELF_H 14 15 #include <kit/core.h> 16 17 #include "core/core.h" 18 #include "obj/obj.h" 19 20 /* ---- e_ident indices and values ---- */ 21 #define EI_NIDENT 16 22 #define EI_MAG0 0 23 #define EI_MAG1 1 24 #define EI_MAG2 2 25 #define EI_MAG3 3 26 #define EI_CLASS 4 27 #define EI_DATA 5 28 #define EI_VERSION 6 29 #define EI_OSABI 7 30 31 #define ELFMAG0 0x7f 32 #define ELFMAG1 'E' 33 #define ELFMAG2 'L' 34 #define ELFMAG3 'F' 35 #define ELFCLASS32 1 36 #define ELFCLASS64 2 37 #define ELFDATA2LSB 1 38 #define ELFDATA2MSB 2 39 #define EV_CURRENT 1 40 #define ELFOSABI_NONE 0 41 /* Bare-metal / freestanding (`*-none-elf`). kit stamps this so a freestanding 42 * object round-trips as KIT_OS_FREESTANDING instead of decoding back to Linux 43 * (EI_OSABI=SysV/0 is ambiguous and is otherwise read as a hosted Linux/PIE 44 * default — the bug that forced rv32 links to be special-cased). */ 45 #define ELFOSABI_STANDALONE 0xFF 46 #define ELFOSABI_GNU \ 47 3 /* a.k.a. ELFOSABI_LINUX — required when \ 48 the file uses STT_GNU_IFUNC / STB_GNU_UNIQUE. */ 49 #define ELFOSABI_LINUX ELFOSABI_GNU 50 /* FreeBSD brand. The kernel matches EI_OSABI for hosted executables; 51 * without it a static binary is rejected even when crt1.o carries the 52 * FreeBSD ABI note. */ 53 #define ELFOSABI_FREEBSD 9 54 55 /* ---- e_type ---- */ 56 #define ET_NONE 0 57 #define ET_REL 1 58 #define ET_EXEC 2 59 #define ET_DYN 3 60 61 /* ---- e_machine ---- */ 62 #define EM_X86_64 0x3E 63 #define EM_AARCH64 0xB7 64 #define EM_RISCV 0xF3 65 #define EM_ARM 0x28 66 67 /* ---- header sizes (also literal e_*size fields) ---- 68 * On-disk sizes of the ELF64 records the linker emits. Wire-format 69 * constants (per spec); never compute via sizeof on a host struct 70 * since alignment / padding may diverge. */ 71 #define ELF64_EHDR_SIZE 64 72 #define ELF64_SHDR_SIZE 64 73 #define ELF64_PHDR_SIZE 56 74 #define ELF64_SYM_SIZE 24u 75 #define ELF64_RELA_SIZE 24u 76 #define ELF64_DYN_SIZE 16u 77 78 /* ELFCLASS32 (ELF32) on-disk record sizes. RV32 ET_REL/ET_EXEC use these 79 * via the `is32` flag derived from EI_CLASS / Compiler.target.ptr_size==4. 80 * Note: Elf32_Sym and Elf32_Phdr REORDER fields relative to their ELF64 81 * counterparts (not just narrower) — see emit.c / read.c / link.c. */ 82 #define ELF32_EHDR_SIZE 52 83 #define ELF32_SHDR_SIZE 40 84 #define ELF32_PHDR_SIZE 32 85 #define ELF32_SYM_SIZE 16u 86 #define ELF32_RELA_SIZE 12u 87 #define ELF32_REL_SIZE 8u /* Elf32_Rel: r_offset@0, r_info@4 (no addend) */ 88 #define ELF32_DYN_SIZE 8u 89 90 /* ---- special section indices ---- */ 91 #define SHN_UNDEF 0u 92 #define SHN_ABS 0xfff1u 93 #define SHN_COMMON 0xfff2u 94 95 /* ---- sh_type ---- */ 96 #define SHT_NULL 0 97 #define SHT_PROGBITS 1 98 #define SHT_SYMTAB 2 99 #define SHT_STRTAB 3 100 #define SHT_RELA 4 101 #define SHT_NOTE 7 102 #define SHT_NOBITS 8 103 #define SHT_REL 9 104 #define SHT_INIT_ARRAY 14 105 #define SHT_FINI_ARRAY 15 106 #define SHT_PREINIT_ARRAY 16 107 #define SHT_GROUP 17 108 #define SHT_ARM_ATTRIBUTES 0x70000003u 109 110 /* ---- sh_flags ---- */ 111 #define SHF_WRITE 0x1u 112 #define SHF_ALLOC 0x2u 113 #define SHF_EXECINSTR 0x4u 114 #define SHF_MERGE 0x10u 115 #define SHF_STRINGS 0x20u 116 #define SHF_INFO_LINK 0x40u 117 #define SHF_LINK_ORDER 0x80u 118 #define SHF_GROUP 0x200u 119 #define SHF_TLS 0x400u 120 #define SHF_GNU_RETAIN 0x200000u 121 122 /* ---- symbol bind / type / visibility ---- */ 123 #define STB_LOCAL 0 124 #define STB_GLOBAL 1 125 #define STB_WEAK 2 126 /* GNU extension: a global symbol that the dynamic loader keeps unique across 127 * the whole process (used for C++ inline statics, and by FreeBSD's crt for the 128 * ABI-brand note symbol). For static-link resolution it behaves as a global 129 * definition. */ 130 #define STB_GNU_UNIQUE 10 131 132 #define STT_NOTYPE 0 133 #define STT_OBJECT 1 134 #define STT_FUNC 2 135 #define STT_SECTION 3 136 #define STT_FILE 4 137 #define STT_COMMON 5 138 #define STT_TLS 6 139 #define STT_GNU_IFUNC 10 140 141 #define STV_DEFAULT 0 142 #define STV_INTERNAL 1 143 #define STV_HIDDEN 2 144 #define STV_PROTECTED 3 145 146 #define ELF64_ST_INFO(b, t) ((u8)((((u32)(b)) << 4) | ((u32)(t) & 0xf))) 147 #define ELF64_ST_BIND(i) ((u32)((i) >> 4)) 148 #define ELF64_ST_TYPE(i) ((u32)((i) & 0xf)) 149 #define ELF64_R_SYM(i) ((u32)((i) >> 32)) 150 #define ELF64_R_TYPE(i) ((u32)((i) & 0xffffffffu)) 151 #define ELF64_R_INFO(s, t) ((((u64)(s)) << 32) | ((u64)(t) & 0xffffffffull)) 152 153 /* ELF32 r_info packs the symbol index in the high 24 bits and an 8-bit 154 * reloc type in the low byte. RV32 reloc type codes (<= 61) all fit. */ 155 #define ELF32_R_SYM(i) ((u32)((i) >> 8)) 156 #define ELF32_R_TYPE(i) ((u32)((i) & 0xffu)) 157 #define ELF32_R_INFO(s, t) ((u32)((((u32)(s)) << 8) | ((u32)(t) & 0xffu))) 158 159 /* ---- kit SymKind/SymBind/SymVis -> ELF wire value, single source ---- 160 * One table per axis, indexed by the kit obj.h enum, wrapped in a 161 * static-inline accessor so unused TUs that include elf.h don't trip 162 * -Wunused-const-variable. SK_COMMON maps to STT_OBJECT here (the shape 163 * clang/gcc/GNU-as emit: STT_OBJECT + shndx=SHN_COMMON); the linker's 164 * symbol writer overrides COMMON to STT_NOTYPE at its call site. */ 165 static inline u8 elf_st_type(u8 kind /* SymKind */) { 166 static const u8 kElfStType[] = { 167 [SK_UNDEF] = STT_NOTYPE, [SK_FUNC] = STT_FUNC, 168 [SK_OBJ] = STT_OBJECT, [SK_SECTION] = STT_SECTION, 169 [SK_FILE] = STT_FILE, [SK_COMMON] = STT_OBJECT, 170 [SK_TLS] = STT_TLS, [SK_ABS] = STT_NOTYPE, 171 [SK_NOTYPE] = STT_NOTYPE, [SK_IFUNC] = STT_GNU_IFUNC, 172 }; 173 if (kind >= (u8)(sizeof kElfStType / sizeof kElfStType[0])) return STT_NOTYPE; 174 return kElfStType[kind]; 175 } 176 177 static inline u8 elf_st_bind(u8 bind /* SymBind */) { 178 static const u8 kElfStBind[] = { 179 [SB_LOCAL] = STB_LOCAL, 180 [SB_GLOBAL] = STB_GLOBAL, 181 [SB_WEAK] = STB_WEAK, 182 }; 183 if (bind >= (u8)(sizeof kElfStBind / sizeof kElfStBind[0])) return STB_LOCAL; 184 return kElfStBind[bind]; 185 } 186 187 static inline u8 elf_st_other(u8 vis /* SymVis */) { 188 static const u8 kElfStOther[] = { 189 [SV_DEFAULT] = STV_DEFAULT, 190 [SV_HIDDEN] = STV_HIDDEN, 191 [SV_PROTECTED] = STV_PROTECTED, 192 [SV_INTERNAL] = STV_INTERNAL, 193 }; 194 if (vis >= (u8)(sizeof kElfStOther / sizeof kElfStOther[0])) 195 return STV_DEFAULT; 196 return kElfStOther[vis]; 197 } 198 199 /* ---- program header ---- */ 200 #define PT_NULL 0 201 #define PT_LOAD 1 202 #define PT_DYNAMIC 2 203 #define PT_INTERP 3 204 #define PT_NOTE 4 205 #define PT_PHDR 6 206 #define PT_TLS 7 207 #define PT_GNU_EH_FRAME 0x6474e550 208 #define PT_GNU_STACK 0x6474e551 209 #define PT_GNU_RELRO 0x6474e552 210 #define PF_X 0x1u 211 #define PF_W 0x2u 212 #define PF_R 0x4u 213 214 /* ---- note types ---- */ 215 #define NT_FREEBSD_ABI_TAG 1u 216 217 /* ---- e_flags (ARM EABI bits, EM_ARM) ---- 218 * EABI version is the top byte; the float-ABI is two independent flag bits 219 * (a soft object sets SOFT, a hard object sets HARD, an old object neither). */ 220 #define EF_ARM_EABIMASK 0xFF000000u 221 #define EF_ARM_EABI_VER5 0x05000000u 222 #define EF_ARM_ABI_FLOAT_SOFT 0x00000200u 223 #define EF_ARM_ABI_FLOAT_HARD 0x00000400u 224 225 /* ---- e_flags (RISC-V ABI bits, EM_RISCV) ---- */ 226 #define EF_RISCV_RVC 0x0001u 227 #define EF_RISCV_FLOAT_ABI_SOFT 0x0000u 228 #define EF_RISCV_FLOAT_ABI_SINGLE 0x0002u 229 #define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004u 230 #define EF_RISCV_FLOAT_ABI_QUAD 0x0006u 231 #define EF_RISCV_FLOAT_ABI_MASK 0x0006u 232 #define EF_RISCV_RVE 0x0008u 233 #define EF_RISCV_TSO 0x0010u 234 235 /* ---- dynamic-table tags (PT_DYNAMIC body) ---- */ 236 #define DT_NULL 0 237 #define DT_NEEDED 1 238 #define DT_PLTRELSZ 2 239 #define DT_PLTGOT 3 240 #define DT_HASH 4 241 #define DT_STRTAB 5 242 #define DT_SYMTAB 6 243 #define DT_RELA 7 244 #define DT_RELASZ 8 245 #define DT_RELAENT 9 246 #define DT_STRSZ 10 247 #define DT_SYMENT 11 248 #define DT_INIT 12 249 #define DT_FINI 13 250 #define DT_SONAME 14 251 #define DT_RPATH 15 252 #define DT_SYMBOLIC 16 253 #define DT_REL 17 254 #define DT_RELSZ 18 255 #define DT_RELENT 19 256 #define DT_PLTREL 20 257 #define DT_DEBUG 21 258 #define DT_TEXTREL 22 259 #define DT_JMPREL 23 260 #define DT_BIND_NOW 24 261 #define DT_INIT_ARRAY 25 262 #define DT_FINI_ARRAY 26 263 #define DT_INIT_ARRAYSZ 27 264 #define DT_FINI_ARRAYSZ 28 265 #define DT_RUNPATH 29 266 #define DT_FLAGS 30 267 #define DT_PREINIT_ARRAY 32 268 #define DT_PREINIT_ARRAYSZ 33 269 #define DT_GNU_HASH 0x6ffffef5 270 #define DT_FLAGS_1 0x6ffffffb 271 #define DF_1_NOW 0x00000001 272 /* GNU symbol-versioning dynamic tags. */ 273 #define DT_VERSYM 0x6ffffff0 /* address of the .gnu.version table */ 274 #define DT_VERNEED 0x6ffffffe /* address of the .gnu.version_r table */ 275 #define DT_VERNEEDNUM 0x6fffffff /* number of .gnu.version_r entries */ 276 277 /* ---- extra section types we need to recognize in DSO inputs ---- */ 278 #define SHT_DYNAMIC 6 279 #define SHT_DYNSYM 11 280 #define SHT_GNU_HASH 0x6ffffff6 281 #define SHT_GNU_VERSYM 0x6fffffff 282 #define SHT_GNU_VERNEED 0x6ffffffe 283 #define SHT_GNU_VERDEF 0x6ffffffd 284 285 /* ---- GNU symbol-versioning wire layout (ELFCLASS64) ---- 286 * .gnu.version (SHT_GNU_VERSYM): u16 per .dynsym entry. Special indices: 287 * 0 = local (the null slot / unversioned undefined reference) 288 * 1 = global, base version (a defined symbol with no explicit version) 289 * >=2 = index of a version requirement (Vernaux.vna_other) for an 290 * undefined reference, or a version definition for a defined symbol. 291 * The 0x8000 bit (VERSYM_HIDDEN) marks a non-default version definition. */ 292 #define VER_NDX_LOCAL 0 293 #define VER_NDX_GLOBAL 1 294 #define VERSYM_HIDDEN 0x8000u 295 #define VERSYM_VERSION 0x7fffu 296 #define VER_FLG_BASE 0x1 /* Verdef: the file's base (soname) version entry */ 297 298 /* Elf64_Verdef (20 bytes) + Elf64_Verdaux (8 bytes) — version definitions in a 299 * DSO's .gnu.version_d. Read-only on our side (we never emit a verdef). */ 300 #define ELF_VERDEF_SIZE 20 301 #define ELF_VERDAUX_SIZE 8 302 /* Elf64_Verneed (16 bytes) + Elf64_Vernaux (16 bytes) — version requirements 303 * in .gnu.version_r, which we both read (DSO inputs) and emit (executables). */ 304 #define ELF_VERNEED_SIZE 16 305 #define ELF_VERNAUX_SIZE 16 306 307 /* ---- AArch64 ELF wire-format relocation type codes ---- 308 * Prefixed ELF_ to avoid collision with the kit-canonical RelocKind 309 * enum values in obj.h (R_AARCH64_*). */ 310 #define ELF_R_AARCH64_NONE 0 311 #define ELF_R_AARCH64_ABS64 257 312 #define ELF_R_AARCH64_ABS32 258 313 #define ELF_R_AARCH64_ABS16 259 314 #define ELF_R_AARCH64_PREL64 260 315 #define ELF_R_AARCH64_PREL32 261 316 #define ELF_R_AARCH64_PREL16 262 317 #define ELF_R_AARCH64_LD_PREL_LO19 273 318 #define ELF_R_AARCH64_ADR_PREL_LO21 274 319 #define ELF_R_AARCH64_ADR_PREL_PG_HI21 275 320 #define ELF_R_AARCH64_ADR_PREL_PG_HI21_NC 276 321 #define ELF_R_AARCH64_ADD_ABS_LO12_NC 277 322 #define ELF_R_AARCH64_LDST8_ABS_LO12_NC 278 323 #define ELF_R_AARCH64_TSTBR14 279 324 #define ELF_R_AARCH64_CONDBR19 280 325 #define ELF_R_AARCH64_JUMP26 282 326 #define ELF_R_AARCH64_CALL26 283 327 #define ELF_R_AARCH64_LDST16_ABS_LO12_NC 284 328 #define ELF_R_AARCH64_LDST32_ABS_LO12_NC 285 329 #define ELF_R_AARCH64_LDST64_ABS_LO12_NC 286 330 #define ELF_R_AARCH64_LDST128_ABS_LO12_NC 299 331 #define ELF_R_AARCH64_ADR_GOT_PAGE 311 332 #define ELF_R_AARCH64_LD64_GOT_LO12_NC 312 333 /* TLS Initial-Exec: ADRP/LDR of a GOT slot holding the symbol's tpoff. */ 334 #define ELF_R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 335 #define ELF_R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 336 337 /* TLS descriptor sequence. Static ET_EXEC links can relax a defined local TLS 338 * target to local-exec; dynamic TLSDESC descriptors are not emitted yet. */ 339 #define ELF_R_AARCH64_TLSDESC_ADR_PAGE21 562 340 #define ELF_R_AARCH64_TLSDESC_LD64_LO12 563 341 #define ELF_R_AARCH64_TLSDESC_ADD_LO12 564 342 #define ELF_R_AARCH64_TLSDESC_CALL 569 343 344 /* AArch64 dynamic-only reloc types: generated by the linker into 345 * .rela.dyn / .rela.plt and processed by the runtime loader. */ 346 #define ELF_R_AARCH64_COPY 1024 347 #define ELF_R_AARCH64_GLOB_DAT 1025 348 #define ELF_R_AARCH64_JUMP_SLOT 1026 349 #define ELF_R_AARCH64_RELATIVE 1027 350 #define ELF_R_AARCH64_IRELATIVE 1032 351 352 /* AArch64 TLS Local-Exec (static linking model: each TLV is at a fixed 353 * offset from the thread pointer, computed at link time). */ 354 #define ELF_R_AARCH64_TLSLE_ADD_TPREL_HI12 549 355 #define ELF_R_AARCH64_TLSLE_ADD_TPREL_LO12 550 356 #define ELF_R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 357 #define ELF_R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 358 #define ELF_R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 359 #define ELF_R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 360 #define ELF_R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 361 #define ELF_R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 362 #define ELF_R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 363 #define ELF_R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 364 #define ELF_R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 365 366 /* Map kit-canonical RelocKind <-> AArch64 ELF reloc type. Returns 367 * R_AARCH64_NONE (0) on unsupported kinds; emit_elf treats that as a 368 * fatal error. 369 * 370 * Note: R_REL32/R_REL64 collapse to R_AARCH64_PREL32/64 on AArch64. 371 * kit's distinction between "section-relative" and "PC-relative" is 372 * not currently exercised on AArch64 (the linker resolves to absolute 373 * vaddrs); document any divergence in the per-arch tables when other 374 * archs land. */ 375 u32 elf_aarch64_reloc_to(u32 kind /* RelocKind */); 376 u32 elf_aarch64_reloc_from(u32 elf_type); 377 /* Diagnostic spelling of an AArch64 ELF reloc wire type; NULL on unknown 378 * (caller falls back to the format-neutral reloc_kind_name). */ 379 const char* elf_aarch64_reloc_name(u32 elf_type); 380 381 /* ---- x86_64 ELF reloc types ---- 382 * 383 * Subset matching the kit-canonical RelocKind R_X64_* entries. The 384 * full SysV-x86_64 ABI table has more entries (TLS, GOT variants, ...) 385 * — only the ones the codegen and linker actually need today are 386 * represented here. */ 387 #define ELF_R_X86_64_NONE 0 388 #define ELF_R_X86_64_64 1 389 #define ELF_R_X86_64_PC32 2 390 #define ELF_R_X86_64_GOT32 3 391 #define ELF_R_X86_64_PLT32 4 392 #define ELF_R_X86_64_COPY 5 393 #define ELF_R_X86_64_GLOB_DAT 6 394 #define ELF_R_X86_64_JUMP_SLOT 7 395 #define ELF_R_X86_64_RELATIVE 8 396 #define ELF_R_X86_64_IRELATIVE 37 397 #define ELF_R_X86_64_GOTPCREL 9 398 #define ELF_R_X86_64_32 10 399 #define ELF_R_X86_64_32S 11 400 #define ELF_R_X86_64_16 12 401 #define ELF_R_X86_64_PC16 13 402 #define ELF_R_X86_64_8 14 403 #define ELF_R_X86_64_PC8 15 404 #define ELF_R_X86_64_DTPMOD64 16 405 #define ELF_R_X86_64_DTPOFF64 17 406 #define ELF_R_X86_64_TPOFF64 18 407 #define ELF_R_X86_64_TLSGD 19 408 #define ELF_R_X86_64_TLSLD 20 409 #define ELF_R_X86_64_DTPOFF32 21 410 #define ELF_R_X86_64_GOTTPOFF 22 411 #define ELF_R_X86_64_TPOFF32 23 412 #define ELF_R_X86_64_PC64 24 413 #define ELF_R_X86_64_GOTOFF64 25 414 #define ELF_R_X86_64_GOTPC32 26 415 #define ELF_R_X86_64_GOTPCRELX 41 416 #define ELF_R_X86_64_REX_GOTPCRELX 42 417 418 u32 elf_x86_64_reloc_to(u32 kind /* RelocKind */); 419 u32 elf_x86_64_reloc_from(u32 elf_type); 420 /* Diagnostic spelling of an x86_64 ELF reloc wire type; NULL on unknown. */ 421 const char* elf_x86_64_reloc_name(u32 elf_type); 422 423 /* ---- RISC-V relocation types ---- 424 * 425 * Subset matching the kit-canonical RelocKind R_RV_* entries. The 426 * full RISC-V ELF psABI has many more (TLS, GOT variants, compressed 427 * forms, ...) — only the ones the codegen and linker actually need 428 * today are represented here. */ 429 #define ELF_R_RISCV_NONE 0 430 #define ELF_R_RISCV_32 1 431 #define ELF_R_RISCV_64 2 432 #define ELF_R_RISCV_RELATIVE 3 433 #define ELF_R_RISCV_COPY 4 434 #define ELF_R_RISCV_JUMP_SLOT 5 435 #define ELF_R_RISCV_IRELATIVE 58 436 #define ELF_R_RISCV_BRANCH 16 437 #define ELF_R_RISCV_JAL 17 438 #define ELF_R_RISCV_CALL 18 439 #define ELF_R_RISCV_CALL_PLT 19 440 #define ELF_R_RISCV_GOT_HI20 20 441 #define ELF_R_RISCV_TLS_GOT_HI20 21 442 #define ELF_R_RISCV_TLS_GD_HI20 22 443 #define ELF_R_RISCV_PCREL_HI20 23 444 #define ELF_R_RISCV_PCREL_LO12_I 24 445 #define ELF_R_RISCV_PCREL_LO12_S 25 446 #define ELF_R_RISCV_HI20 26 447 #define ELF_R_RISCV_LO12_I 27 448 #define ELF_R_RISCV_LO12_S 28 449 #define ELF_R_RISCV_TPREL_HI20 29 450 #define ELF_R_RISCV_TPREL_LO12_I 30 451 #define ELF_R_RISCV_TPREL_LO12_S 31 452 #define ELF_R_RISCV_TPREL_ADD 32 453 #define ELF_R_RISCV_ADD8 33 454 #define ELF_R_RISCV_ADD16 34 455 #define ELF_R_RISCV_ADD32 35 456 #define ELF_R_RISCV_ADD64 36 457 #define ELF_R_RISCV_SUB8 37 458 #define ELF_R_RISCV_SUB16 38 459 #define ELF_R_RISCV_SUB32 39 460 #define ELF_R_RISCV_SUB64 40 461 #define ELF_R_RISCV_ALIGN 43 462 #define ELF_R_RISCV_RVC_BRANCH 44 463 #define ELF_R_RISCV_RVC_JUMP 45 464 #define ELF_R_RISCV_RELAX 51 465 #define ELF_R_RISCV_SUB6 52 466 #define ELF_R_RISCV_SET6 53 467 #define ELF_R_RISCV_SET8 54 468 #define ELF_R_RISCV_SET16 55 469 #define ELF_R_RISCV_SET32 56 470 #define ELF_R_RISCV_32_PCREL 57 471 #define ELF_R_RISCV_SET_ULEB128 60 472 #define ELF_R_RISCV_SUB_ULEB128 61 473 474 u32 elf_riscv64_reloc_to(u32 kind /* RelocKind */); 475 u32 elf_riscv64_reloc_from(u32 elf_type); 476 477 /* RV32 (ELFCLASS32) reloc table. Same XLEN-neutral kinds as riscv64; the 478 * 64-bit-only kinds (R_ABS64 / R_RV_ADD64 / R_RV_SUB64) are unsupported. */ 479 u32 elf_riscv32_reloc_to(u32 kind /* RelocKind */); 480 u32 elf_riscv32_reloc_from(u32 elf_type); 481 /* Diagnostic spelling of a RISC-V ELF reloc wire type, and float-ABI 482 * decode from RISC-V e_flags. Both XLEN-neutral — shared by the rv64 and 483 * rv32 arch-ops descriptors. */ 484 const char* elf_riscv_reloc_name(u32 elf_type); 485 KitFloatAbi elf_riscv_float_abi_from_e_flags(u32 e_flags); 486 u32 elf_riscv_float_abi_to_e_flags(KitFloatAbi abi); 487 488 /* ---- ARM (32-bit, Thumb-2) relocation types (EM_ARM, ELFCLASS32) ---- 489 * 490 * Canonical numbers from "ELF for the ARM Architecture" (ARM IHI 0044). 491 * Static-only subset: data words (ABS32/REL32/ABS16/ABS8) reuse the neutral 492 * RelocKinds; only the instruction-embedded Thumb-2 kinds get arch entries. */ 493 #define ELF_R_ARM_NONE 0 494 #define ELF_R_ARM_ABS32 2 495 #define ELF_R_ARM_REL32 3 496 #define ELF_R_ARM_ABS16 5 497 #define ELF_R_ARM_ABS8 8 498 #define ELF_R_ARM_THM_CALL 10 499 #define ELF_R_ARM_THM_JUMP24 30 500 #define ELF_R_ARM_MOVW_ABS_NC 43 501 #define ELF_R_ARM_MOVT_ABS 44 502 #define ELF_R_ARM_THM_MOVW_ABS_NC 47 503 #define ELF_R_ARM_THM_MOVT_ABS 48 504 #define ELF_R_ARM_THM_MOVW_PREL_NC 49 505 #define ELF_R_ARM_THM_MOVT_PREL 50 506 #define ELF_R_ARM_THM_JUMP19 51 507 #define ELF_R_ARM_TLS_LE32 108 508 509 u32 elf_arm_reloc_to(u32 kind /* RelocKind */); 510 u32 elf_arm_reloc_from(u32 elf_type); 511 const char* elf_arm_reloc_name(u32 elf_type); 512 KitFloatAbi elf_arm_float_abi_from_e_flags(u32 e_flags); 513 u32 elf_arm_float_abi_to_e_flags(KitFloatAbi abi); 514 /* REL addend reconstruction (ObjElfArchOps.reloc_field_addend). */ 515 i64 elf_arm_reloc_field_addend(u32 kind, const u8* field, u32 width); 516 /* ARM EABI `.ARM.attributes` (SHT_ARM_ATTRIBUTES) payload builder, wired into 517 * the arm32 row of obj_elf_arch_ops[] as ObjElfArchOps.build_attributes. */ 518 const u8* elf_arm_build_attributes(Compiler* c, u32* size_out); 519 520 /* ---- little-endian byte writers (Writer-based) ---- 521 * Writes go through the shared writer_u*_le helpers (core/bytes.h); the 522 * elf_wr_* aliases keep the ELF spelling at existing call sites. Reads 523 * use rd_u*_le from core/bytes.h directly. */ 524 525 #include "core/bytes.h" 526 527 #define elf_wr_u8 writer_u8_le 528 #define elf_wr_u16 writer_u16_le 529 #define elf_wr_u32 writer_u32_le 530 #define elf_wr_u64 writer_u64_le 531 532 /* Native-width address/offset/size field: 4 bytes on ELFCLASS32, 8 on 533 * ELFCLASS64. Used wherever the Ehdr/Shdr/Sym widths shrink under is32. */ 534 static inline void elf_wr_addr(Writer* w, int is32, u64 v) { 535 if (is32) 536 elf_wr_u32(w, (u32)v); 537 else 538 elf_wr_u64(w, v); 539 } 540 541 static inline u64 elf_rd_addr(const u8* p, int is32) { 542 return is32 ? (u64)rd_u32_le(p) : rd_u64_le(p); 543 } 544 545 /* EI_CLASS-aware arch-ops lookup. obj_elf_machine() keys on e_machine 546 * alone, which cannot tell RV32 (EM_RISCV+ELFCLASS32) from RV64 547 * (EM_RISCV+ELFCLASS64); this variant disambiguates via ei_class. */ 548 const struct ObjElfArchOps* obj_elf_machine_class(u32 e_machine, u8 ei_class); 549 550 #endif /* KIT_OBJ_ELF_H */