kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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 */