kit

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

reloc_riscv64.c (9517B)


      1 /* RelocKind <-> RISC-V ELF reloc-type mapping.
      2  *
      3  * Mirror of elf_reloc_x86_64.c for the RISC-V LP64 ABI. The arch-
      4  * agnostic R_ABS / R_PC RelocKind entries fan out to the native
      5  * RISC-V codes; the RISC-V-specific encodings (HI20/LO12, BRANCH,
      6  * JAL, CALL, PCREL_*, TPREL_*, ADD/SUB/SET, RELAX, ALIGN, RVC_*)
      7  * live in the lower band as R_RV_*.
      8  *
      9  * Returning ELF_R_RISCV_NONE for an unsupported kind is the signal
     10  * to the caller to either panic (emit) or panic (read with diagnostic). */
     11 
     12 #include "obj/elf/elf.h"
     13 
     14 u32 elf_riscv64_reloc_to(u32 kind /* RelocKind */) {
     15   switch (kind) {
     16     case R_NONE:
     17       return ELF_R_RISCV_NONE;
     18     case R_ABS64:
     19       return ELF_R_RISCV_64;
     20     case R_ABS32:
     21       return ELF_R_RISCV_32;
     22     case R_PC32:
     23       return ELF_R_RISCV_32_PCREL;
     24     case R_RV_HI20:
     25       return ELF_R_RISCV_HI20;
     26     case R_RV_LO12_I:
     27       return ELF_R_RISCV_LO12_I;
     28     case R_RV_LO12_S:
     29       return ELF_R_RISCV_LO12_S;
     30     case R_RV_BRANCH:
     31       return ELF_R_RISCV_BRANCH;
     32     case R_RV_JAL:
     33       return ELF_R_RISCV_JAL;
     34     case R_RV_CALL:
     35       return ELF_R_RISCV_CALL;
     36     case R_PLT32:
     37       return ELF_R_RISCV_CALL_PLT;
     38     case R_RV_PCREL_HI20:
     39       return ELF_R_RISCV_PCREL_HI20;
     40     case R_RV_PCREL_LO12_I:
     41       return ELF_R_RISCV_PCREL_LO12_I;
     42     case R_RV_PCREL_LO12_S:
     43       return ELF_R_RISCV_PCREL_LO12_S;
     44     case R_RV_GOT_HI20:
     45       return ELF_R_RISCV_GOT_HI20;
     46     case R_RV_TLS_GOT_HI20:
     47       return ELF_R_RISCV_TLS_GOT_HI20;
     48     case R_RV_TLS_GD_HI20:
     49       return ELF_R_RISCV_TLS_GD_HI20;
     50     case R_RV_TPREL_HI20:
     51       return ELF_R_RISCV_TPREL_HI20;
     52     case R_RV_TPREL_LO12_I:
     53       return ELF_R_RISCV_TPREL_LO12_I;
     54     case R_RV_TPREL_LO12_S:
     55       return ELF_R_RISCV_TPREL_LO12_S;
     56     case R_RV_TPREL_ADD:
     57       return ELF_R_RISCV_TPREL_ADD;
     58     case R_ADD8:
     59       return ELF_R_RISCV_ADD8;
     60     case R_ADD16:
     61       return ELF_R_RISCV_ADD16;
     62     case R_ADD32:
     63       return ELF_R_RISCV_ADD32;
     64     case R_ADD64:
     65       return ELF_R_RISCV_ADD64;
     66     case R_SUB8:
     67       return ELF_R_RISCV_SUB8;
     68     case R_SUB16:
     69       return ELF_R_RISCV_SUB16;
     70     case R_SUB32:
     71       return ELF_R_RISCV_SUB32;
     72     case R_SUB64:
     73       return ELF_R_RISCV_SUB64;
     74     case R_RV_ALIGN:
     75       return ELF_R_RISCV_ALIGN;
     76     case R_RV_RVC_BRANCH:
     77       return ELF_R_RISCV_RVC_BRANCH;
     78     case R_RV_RVC_JUMP:
     79       return ELF_R_RISCV_RVC_JUMP;
     80     case R_RV_RELAX:
     81       return ELF_R_RISCV_RELAX;
     82     case R_SUB6:
     83       return ELF_R_RISCV_SUB6;
     84     case R_SET6:
     85       return ELF_R_RISCV_SET6;
     86     case R_ABS8:
     87       return ELF_R_RISCV_SET8;
     88     case R_ABS16:
     89       return ELF_R_RISCV_SET16;
     90     case R_SET_ULEB128:
     91       return ELF_R_RISCV_SET_ULEB128;
     92     case R_SUB_ULEB128:
     93       return ELF_R_RISCV_SUB_ULEB128;
     94     default:
     95       return ELF_R_RISCV_NONE;
     96   }
     97 }
     98 
     99 u32 elf_riscv64_reloc_from(u32 elf_type) {
    100   switch (elf_type) {
    101     case ELF_R_RISCV_NONE:
    102       return R_NONE;
    103     case ELF_R_RISCV_64:
    104       return R_ABS64;
    105     case ELF_R_RISCV_32:
    106       return R_ABS32;
    107     case ELF_R_RISCV_32_PCREL:
    108       return R_PC32;
    109     case ELF_R_RISCV_HI20:
    110       return R_RV_HI20;
    111     case ELF_R_RISCV_LO12_I:
    112       return R_RV_LO12_I;
    113     case ELF_R_RISCV_LO12_S:
    114       return R_RV_LO12_S;
    115     case ELF_R_RISCV_BRANCH:
    116       return R_RV_BRANCH;
    117     case ELF_R_RISCV_JAL:
    118       return R_RV_JAL;
    119     case ELF_R_RISCV_CALL:
    120       return R_RV_CALL;
    121     case ELF_R_RISCV_CALL_PLT:
    122       return R_PLT32;
    123     case ELF_R_RISCV_PCREL_HI20:
    124       return R_RV_PCREL_HI20;
    125     case ELF_R_RISCV_PCREL_LO12_I:
    126       return R_RV_PCREL_LO12_I;
    127     case ELF_R_RISCV_PCREL_LO12_S:
    128       return R_RV_PCREL_LO12_S;
    129     case ELF_R_RISCV_GOT_HI20:
    130       return R_RV_GOT_HI20;
    131     case ELF_R_RISCV_TLS_GOT_HI20:
    132       return R_RV_TLS_GOT_HI20;
    133     case ELF_R_RISCV_TLS_GD_HI20:
    134       return R_RV_TLS_GD_HI20;
    135     case ELF_R_RISCV_TPREL_HI20:
    136       return R_RV_TPREL_HI20;
    137     case ELF_R_RISCV_TPREL_LO12_I:
    138       return R_RV_TPREL_LO12_I;
    139     case ELF_R_RISCV_TPREL_LO12_S:
    140       return R_RV_TPREL_LO12_S;
    141     case ELF_R_RISCV_TPREL_ADD:
    142       return R_RV_TPREL_ADD;
    143     case ELF_R_RISCV_ADD8:
    144       return R_ADD8;
    145     case ELF_R_RISCV_ADD16:
    146       return R_ADD16;
    147     case ELF_R_RISCV_ADD32:
    148       return R_ADD32;
    149     case ELF_R_RISCV_ADD64:
    150       return R_ADD64;
    151     case ELF_R_RISCV_SUB8:
    152       return R_SUB8;
    153     case ELF_R_RISCV_SUB16:
    154       return R_SUB16;
    155     case ELF_R_RISCV_SUB32:
    156       return R_SUB32;
    157     case ELF_R_RISCV_SUB64:
    158       return R_SUB64;
    159     case ELF_R_RISCV_ALIGN:
    160       return R_RV_ALIGN;
    161     case ELF_R_RISCV_RVC_BRANCH:
    162       return R_RV_RVC_BRANCH;
    163     case ELF_R_RISCV_RVC_JUMP:
    164       return R_RV_RVC_JUMP;
    165     case ELF_R_RISCV_RELAX:
    166       return R_RV_RELAX;
    167     case ELF_R_RISCV_SUB6:
    168       return R_SUB6;
    169     case ELF_R_RISCV_SET6:
    170       return R_SET6;
    171     case ELF_R_RISCV_SET8:
    172       return R_ABS8;
    173     case ELF_R_RISCV_SET16:
    174       return R_ABS16;
    175     case ELF_R_RISCV_SET32:
    176       return R_ABS32;
    177     case ELF_R_RISCV_SET_ULEB128:
    178       return R_SET_ULEB128;
    179     case ELF_R_RISCV_SUB_ULEB128:
    180       return R_SUB_ULEB128;
    181     default:
    182       return (u32)-1; /* sentinel */
    183   }
    184 }
    185 
    186 /* Diagnostic spelling for a RISC-V ELF reloc *wire* type. XLEN-neutral —
    187  * shared by the rv64 and rv32 arch-ops descriptors. Returns a static
    188  * literal, or NULL for an unknown type. */
    189 const char* elf_riscv_reloc_name(u32 elf_type) {
    190   switch (elf_type) {
    191     case ELF_R_RISCV_NONE:
    192       return "R_RISCV_NONE";
    193     case ELF_R_RISCV_32:
    194       return "R_RISCV_32";
    195     case ELF_R_RISCV_64:
    196       return "R_RISCV_64";
    197     case ELF_R_RISCV_RELATIVE:
    198       return "R_RISCV_RELATIVE";
    199     case ELF_R_RISCV_COPY:
    200       return "R_RISCV_COPY";
    201     case ELF_R_RISCV_JUMP_SLOT:
    202       return "R_RISCV_JUMP_SLOT";
    203     case ELF_R_RISCV_IRELATIVE:
    204       return "R_RISCV_IRELATIVE";
    205     case ELF_R_RISCV_BRANCH:
    206       return "R_RISCV_BRANCH";
    207     case ELF_R_RISCV_JAL:
    208       return "R_RISCV_JAL";
    209     case ELF_R_RISCV_CALL:
    210       return "R_RISCV_CALL";
    211     case ELF_R_RISCV_CALL_PLT:
    212       return "R_RISCV_CALL_PLT";
    213     case ELF_R_RISCV_GOT_HI20:
    214       return "R_RISCV_GOT_HI20";
    215     case ELF_R_RISCV_TLS_GOT_HI20:
    216       return "R_RISCV_TLS_GOT_HI20";
    217     case ELF_R_RISCV_TLS_GD_HI20:
    218       return "R_RISCV_TLS_GD_HI20";
    219     case ELF_R_RISCV_PCREL_HI20:
    220       return "R_RISCV_PCREL_HI20";
    221     case ELF_R_RISCV_PCREL_LO12_I:
    222       return "R_RISCV_PCREL_LO12_I";
    223     case ELF_R_RISCV_PCREL_LO12_S:
    224       return "R_RISCV_PCREL_LO12_S";
    225     case ELF_R_RISCV_HI20:
    226       return "R_RISCV_HI20";
    227     case ELF_R_RISCV_LO12_I:
    228       return "R_RISCV_LO12_I";
    229     case ELF_R_RISCV_LO12_S:
    230       return "R_RISCV_LO12_S";
    231     case ELF_R_RISCV_TPREL_HI20:
    232       return "R_RISCV_TPREL_HI20";
    233     case ELF_R_RISCV_TPREL_LO12_I:
    234       return "R_RISCV_TPREL_LO12_I";
    235     case ELF_R_RISCV_TPREL_LO12_S:
    236       return "R_RISCV_TPREL_LO12_S";
    237     case ELF_R_RISCV_TPREL_ADD:
    238       return "R_RISCV_TPREL_ADD";
    239     case ELF_R_RISCV_ADD8:
    240       return "R_RISCV_ADD8";
    241     case ELF_R_RISCV_ADD16:
    242       return "R_RISCV_ADD16";
    243     case ELF_R_RISCV_ADD32:
    244       return "R_RISCV_ADD32";
    245     case ELF_R_RISCV_ADD64:
    246       return "R_RISCV_ADD64";
    247     case ELF_R_RISCV_SUB8:
    248       return "R_RISCV_SUB8";
    249     case ELF_R_RISCV_SUB16:
    250       return "R_RISCV_SUB16";
    251     case ELF_R_RISCV_SUB32:
    252       return "R_RISCV_SUB32";
    253     case ELF_R_RISCV_SUB64:
    254       return "R_RISCV_SUB64";
    255     case ELF_R_RISCV_ALIGN:
    256       return "R_RISCV_ALIGN";
    257     case ELF_R_RISCV_RVC_BRANCH:
    258       return "R_RISCV_RVC_BRANCH";
    259     case ELF_R_RISCV_RVC_JUMP:
    260       return "R_RISCV_RVC_JUMP";
    261     case ELF_R_RISCV_RELAX:
    262       return "R_RISCV_RELAX";
    263     case ELF_R_RISCV_SUB6:
    264       return "R_RISCV_SUB6";
    265     case ELF_R_RISCV_SET6:
    266       return "R_RISCV_SET6";
    267     case ELF_R_RISCV_SET8:
    268       return "R_RISCV_SET8";
    269     case ELF_R_RISCV_SET16:
    270       return "R_RISCV_SET16";
    271     case ELF_R_RISCV_SET32:
    272       return "R_RISCV_SET32";
    273     case ELF_R_RISCV_32_PCREL:
    274       return "R_RISCV_32_PCREL";
    275     case ELF_R_RISCV_SET_ULEB128:
    276       return "R_RISCV_SET_ULEB128";
    277     case ELF_R_RISCV_SUB_ULEB128:
    278       return "R_RISCV_SUB_ULEB128";
    279     default:
    280       return NULL;
    281   }
    282 }
    283 
    284 /* Decode the float ABI from RISC-V ELF e_flags (EF_RISCV_FLOAT_ABI_*).
    285  * XLEN-neutral — shared by the rv64 and rv32 arch-ops descriptors. */
    286 KitFloatAbi elf_riscv_float_abi_from_e_flags(u32 e_flags) {
    287   switch (e_flags & EF_RISCV_FLOAT_ABI_MASK) {
    288     case EF_RISCV_FLOAT_ABI_SOFT:
    289       return KIT_FLOAT_ABI_SOFT;
    290     case EF_RISCV_FLOAT_ABI_SINGLE:
    291       return KIT_FLOAT_ABI_SINGLE;
    292     case EF_RISCV_FLOAT_ABI_DOUBLE:
    293     case EF_RISCV_FLOAT_ABI_QUAD:
    294       return KIT_FLOAT_ABI_DOUBLE;
    295     default:
    296       return KIT_FLOAT_ABI_DEFAULT;
    297   }
    298 }
    299 
    300 /* Encode the resolved float ABI into RISC-V ELF e_flags (the
    301  * EF_RISCV_FLOAT_ABI_* bits; callers mask them into e_flags with
    302  * EF_RISCV_FLOAT_ABI_MASK). Inverse of elf_riscv_float_abi_from_e_flags, kept
    303  * here so the format-generic ELF writers (emit.c ET_REL, link.c ET_EXEC) do not
    304  * inline the mapping. KitTarget construction resolves the ABI for both XLENs;
    305  * DEFAULT retains the historical single-float fallback for a synthetic target
    306  * that bypasses normal construction. */
    307 u32 elf_riscv_float_abi_to_e_flags(KitFloatAbi abi) {
    308   switch (abi) {
    309     case KIT_FLOAT_ABI_SINGLE:
    310       return EF_RISCV_FLOAT_ABI_SINGLE;
    311     case KIT_FLOAT_ABI_DOUBLE:
    312       return EF_RISCV_FLOAT_ABI_DOUBLE;
    313     case KIT_FLOAT_ABI_DEFAULT:
    314       return EF_RISCV_FLOAT_ABI_SINGLE;
    315     default:
    316       return EF_RISCV_FLOAT_ABI_SOFT;
    317   }
    318 }