kit

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

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