kit

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

link_reloc_desc.h (4619B)


      1 #ifndef KIT_LINK_RELOC_DESC_H
      2 #define KIT_LINK_RELOC_DESC_H
      3 
      4 #include "core/core.h"
      5 #include "obj/obj.h"
      6 #include "obj/reloc.h"
      7 
      8 /* Arch-aware resolution of a relocation kind's static descriptor.
      9  *
     10  * The per-arch slice (via link_arch_desc_for(c)->reloc_desc) takes
     11  * precedence; it falls back to the arch-neutral table.  Returns NULL when k
     12  * is not a relocation this target applies.  This is the single source of a
     13  * kind's width + classification — the wire encoding and the diagnostic name
     14  * live on the per-(arch,format) ops.  See doc/plan/RELOC.md (WS-B).
     15  *
     16  * The thin reloc_kind_* predicates below replace the former generic
     17  * switches (reloc_width / reloc_uses_got / reloc_is_tls_got) and the
     18  * per-arch LinkArchDesc.is_* hooks; each reads one descriptor flag. */
     19 const RelocDesc* reloc_desc(const Compiler* c, RelocKind k);
     20 
     21 /* Patched-field width in bytes, or 0 when k has no descriptor — the
     22  * "unsupported relocation kind" gate the linker enforces.  Nominal (gate)
     23  * value for RELOC_WIDTH_DYN kinds, whose true span is read at apply time. */
     24 static inline u8 reloc_kind_width(const Compiler* c, RelocKind k) {
     25   const RelocDesc* d = reloc_desc(c, k);
     26   return d ? d->width : 0u;
     27 }
     28 
     29 /* Needs a GOT slot (the ELF / static GOT pass's notion): a direct GOT load
     30  * OR a TLS-IE GOT slot holding a TP-relative offset. */
     31 static inline int reloc_kind_uses_got(const Compiler* c, RelocKind k) {
     32   const RelocDesc* d = reloc_desc(c, k);
     33   return d && (d->flags & (RELOC_USES_GOT | RELOC_IS_TLS_GOT)) ? 1 : 0;
     34 }
     35 
     36 /* GOT slot is filled with the symbol's TP-relative offset (TLS Initial-Exec)
     37  * rather than its address. */
     38 static inline int reloc_kind_is_tls_got(const Compiler* c, RelocKind k) {
     39   const RelocDesc* d = reloc_desc(c, k);
     40   return d && (d->flags & RELOC_IS_TLS_GOT) ? 1 : 0;
     41 }
     42 
     43 /* ELF Local-Exec TLS access (the per-arch tp-relative idiom). The in-process
     44  * JIT relaxes these to in-image addressing via LinkArchDesc.jit_tls_le_relax.
     45  */
     46 static inline int reloc_kind_is_tls_le(const Compiler* c, RelocKind k) {
     47   const RelocDesc* d = reloc_desc(c, k);
     48   return d && (d->flags & RELOC_IS_TLS_LE) ? 1 : 0;
     49 }
     50 
     51 /* A direct GOT-load instruction reloc (the Mach-O linker's notion): non-TLS
     52  * GOT load.  Distinct from reloc_kind_uses_got, which also counts TLS-IE. */
     53 static inline int reloc_kind_is_got_load(const Compiler* c, RelocKind k) {
     54   const RelocDesc* d = reloc_desc(c, k);
     55   return d && (d->flags & RELOC_USES_GOT) ? 1 : 0;
     56 }
     57 
     58 /* Range-limited call/jump that may need a JIT/range call stub or veneer. */
     59 static inline int reloc_kind_is_branch(const Compiler* c, RelocKind k) {
     60   const RelocDesc* d = reloc_desc(c, k);
     61   return d && (d->flags & RELOC_IS_BRANCH) ? 1 : 0;
     62 }
     63 
     64 /* Mach-O TLV descriptor page / pageoff reloc. */
     65 static inline int reloc_kind_is_tlvp(const Compiler* c, RelocKind k) {
     66   const RelocDesc* d = reloc_desc(c, k);
     67   return d && (d->flags & RELOC_IS_TLVP) ? 1 : 0;
     68 }
     69 
     70 /* Mach-O ADRP-direct (non-GOT) page / pageoff reloc. */
     71 static inline int reloc_kind_is_direct_page(const Compiler* c, RelocKind k) {
     72   const RelocDesc* d = reloc_desc(c, k);
     73   return d && (d->flags & RELOC_DIRECT_PAGE) ? 1 : 0;
     74 }
     75 
     76 /* PC-relative HI20 anchor (RISC-V AUIPC for PCREL_HI20 / GOT_HI20) that a
     77  * paired PCREL_LO12 resolves against. The in-process JIT scans for the anchor
     78  * to recompute the low-12 displacement under its layout. */
     79 static inline int reloc_kind_is_pcrel_anchor(const Compiler* c, RelocKind k) {
     80   const RelocDesc* d = reloc_desc(c, k);
     81   return d && (d->flags & RELOC_IS_PCREL_ANCHOR) ? 1 : 0;
     82 }
     83 
     84 /* COFF section-relative value (R_COFF_SECREL). A TLS Local-Exec access exactly
     85  * when its target is a TLS symbol; the in-process JIT relaxes those. */
     86 static inline int reloc_kind_is_secrel(const Compiler* c, RelocKind k) {
     87   const RelocDesc* d = reloc_desc(c, k);
     88   return d && (d->flags & RELOC_IS_SECREL) ? 1 : 0;
     89 }
     90 
     91 /* Relaxation marker that patches no bytes (RISC-V RELAX / TPREL_ADD / ALIGN).
     92  * No reloc record is emitted for these — they are dropped during layout. */
     93 static inline int reloc_kind_is_marker(const Compiler* c, RelocKind k) {
     94   const RelocDesc* d = reloc_desc(c, k);
     95   return d && (d->flags & RELOC_MARKER) ? 1 : 0;
     96 }
     97 
     98 /* Variable-width kind (RISC-V ULEB128 SET/SUB): the descriptor width is only a
     99  * nominal gate value; the true field length is read from the bytes at apply
    100  * time, so the layout pass must bound-check the offset before the apply scan.
    101  */
    102 static inline int reloc_kind_is_width_dyn(const Compiler* c, RelocKind k) {
    103   const RelocDesc* d = reloc_desc(c, k);
    104   return d && (d->flags & RELOC_WIDTH_DYN) ? 1 : 0;
    105 }
    106 
    107 #endif