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 }