reloc.h (3225B)
1 #ifndef KIT_OBJ_RELOC_H 2 #define KIT_OBJ_RELOC_H 3 4 #include "core/core.h" 5 #include "obj/obj.h" 6 7 /* Static, structural facts about a relocation kind: how wide the patched 8 * field is and how the linker must classify it. This is the arch-owned 9 * "width + classification" half of a relocation kind; the wire encoding 10 * and the diagnostic name live on the per-(arch,format) wire ops in 11 * src/obj/<fmt>/reloc_<arch>.c. See doc/plan/RELOC.md (WS-B). 12 * 13 * A kind's descriptor is resolved arch-aware via reloc_desc() in 14 * src/link/link_reloc_desc.h: each arch owns a slice (src/arch/<arch>/ 15 * reloc.c) reached through LinkArchDesc.reloc_desc, falling back to the 16 * arch-neutral table here. Adding an arch's relocation is one row in that 17 * arch's slice (plus its wire-translator entry) — no generic switch. */ 18 typedef enum RelocDescFlag { 19 RELOC_USES_GOT = 1u << 0, /* direct GOT load: needs a (non-TLS) GOT slot */ 20 RELOC_IS_TLS_GOT = 1u << 1, /* GOT slot holds a TP-relative offset (TLS-IE) */ 21 RELOC_IS_BRANCH = 1u << 2, /* range-limited call/jump; may need a veneer */ 22 RELOC_IS_TLVP = 1u << 3, /* Mach-O TLV descriptor page / pageoff */ 23 RELOC_DIRECT_PAGE = 1u << 4, /* Mach-O ADRP-direct (non-GOT) page / pageoff */ 24 RELOC_MARKER = 1u << 5, /* no bytes patched (RELAX / TPREL_ADD) */ 25 RELOC_WIDTH_DYN = 1u << 6, /* width read from the bytes at apply (ULEB128) */ 26 RELOC_IS_TLS_LE = 1u << 7, /* ELF Local-Exec TLS access (tp-relative idiom), 27 * plus the COFF Windows SECREL12A TLS pair; the 28 * in-process JIT relaxes it to in-image 29 * addressing via LinkArchDesc.jit_tls_le_relax */ 30 RELOC_IS_PCREL_ANCHOR = 1u << 8, /* PC-relative HI20 anchor (RISC-V AUIPC) a 31 * paired PCREL_LO12 reloc resolves against; 32 * the JIT recomputes its displacement */ 33 RELOC_IS_SECREL = 1u << 9, /* COFF section-relative value (R_COFF_SECREL); a 34 * TLS Local-Exec access when its target is a TLS 35 * symbol, which the in-process JIT relaxes */ 36 } RelocDescFlag; 37 38 typedef struct RelocDesc { 39 u8 width; /* patched-field width in bytes; nominal when RELOC_WIDTH_DYN */ 40 u16 flags; /* RelocDescFlag bitset */ 41 } RelocDesc; 42 43 /* One row of a per-arch / neutral descriptor table. `kind` holds a 44 * RelocKind narrowed to u16 (the enum fits comfortably). */ 45 typedef struct RelocDescRow { 46 u16 kind; 47 RelocDesc desc; 48 } RelocDescRow; 49 50 /* Linear lookup over a static row table; returns the matching row's 51 * descriptor or NULL. Per-arch slices and the neutral table are small and 52 * looked up off the hot path, so a scan keeps each slice a plain data 53 * table with no parallel index to maintain. */ 54 const RelocDesc* reloc_desc_row_find(const RelocDescRow* rows, u32 n, 55 RelocKind k); 56 57 /* Descriptor for an arch-independent (data-word / format-neutral) kind, or 58 * NULL. Arch-family kinds resolve through the per-arch slice instead — use 59 * reloc_desc() (src/link/link_reloc_desc.h), not this directly. */ 60 const RelocDesc* reloc_desc_neutral(RelocKind k); 61 62 #endif