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