1 //===- RISCV.cpp ----------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "InputFiles.h" 10 #include "Target.h" 11 12 using namespace llvm; 13 using namespace llvm::object; 14 using namespace llvm::support::endian; 15 using namespace llvm::ELF; 16 using namespace lld; 17 using namespace lld::elf; 18 19 namespace { 20 21 class RISCV final : public TargetInfo { 22 public: 23 RISCV(); 24 uint32_t calcEFlags() const override; 25 RelExpr getRelExpr(RelType Type, const Symbol &S, 26 const uint8_t *Loc) const override; 27 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; 28 }; 29 30 } // end anonymous namespace 31 32 RISCV::RISCV() { NoneRel = R_RISCV_NONE; } 33 34 static uint32_t getEFlags(InputFile *F) { 35 if (Config->Is64) 36 return cast<ObjFile<ELF64LE>>(F)->getObj().getHeader()->e_flags; 37 return cast<ObjFile<ELF32LE>>(F)->getObj().getHeader()->e_flags; 38 } 39 40 uint32_t RISCV::calcEFlags() const { 41 assert(!ObjectFiles.empty()); 42 43 uint32_t Target = getEFlags(ObjectFiles.front()); 44 45 for (InputFile *F : ObjectFiles) { 46 uint32_t EFlags = getEFlags(F); 47 if (EFlags & EF_RISCV_RVC) 48 Target |= EF_RISCV_RVC; 49 50 if ((EFlags & EF_RISCV_FLOAT_ABI) != (Target & EF_RISCV_FLOAT_ABI)) 51 error(toString(F) + 52 ": cannot link object files with different floating-point ABI"); 53 54 if ((EFlags & EF_RISCV_RVE) != (Target & EF_RISCV_RVE)) 55 error(toString(F) + 56 ": cannot link object files with different EF_RISCV_RVE"); 57 } 58 59 return Target; 60 } 61 62 RelExpr RISCV::getRelExpr(const RelType Type, const Symbol &S, 63 const uint8_t *Loc) const { 64 switch (Type) { 65 case R_RISCV_ADD8: 66 case R_RISCV_ADD16: 67 case R_RISCV_ADD32: 68 case R_RISCV_ADD64: 69 case R_RISCV_SET6: 70 case R_RISCV_SET8: 71 case R_RISCV_SET16: 72 case R_RISCV_SET32: 73 case R_RISCV_SUB6: 74 case R_RISCV_SUB8: 75 case R_RISCV_SUB16: 76 case R_RISCV_SUB32: 77 case R_RISCV_SUB64: 78 return R_RISCV_ADD; 79 case R_RISCV_JAL: 80 case R_RISCV_BRANCH: 81 case R_RISCV_CALL: 82 case R_RISCV_PCREL_HI20: 83 case R_RISCV_RVC_BRANCH: 84 case R_RISCV_RVC_JUMP: 85 case R_RISCV_32_PCREL: 86 return R_PC; 87 case R_RISCV_PCREL_LO12_I: 88 case R_RISCV_PCREL_LO12_S: 89 return R_RISCV_PC_INDIRECT; 90 case R_RISCV_RELAX: 91 case R_RISCV_ALIGN: 92 return R_HINT; 93 default: 94 return R_ABS; 95 } 96 } 97 98 // Extract bits V[Begin:End], where range is inclusive, and Begin must be < 63. 99 static uint32_t extractBits(uint64_t V, uint32_t Begin, uint32_t End) { 100 return (V & ((1ULL << (Begin + 1)) - 1)) >> End; 101 } 102 103 void RISCV::relocateOne(uint8_t *Loc, const RelType Type, 104 const uint64_t Val) const { 105 const unsigned Bits = Config->Wordsize * 8; 106 107 switch (Type) { 108 case R_RISCV_32: 109 write32le(Loc, Val); 110 return; 111 case R_RISCV_64: 112 write64le(Loc, Val); 113 return; 114 115 case R_RISCV_RVC_BRANCH: { 116 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 8, Type); 117 checkAlignment(Loc, Val, 2, Type); 118 uint16_t Insn = read16le(Loc) & 0xE383; 119 uint16_t Imm8 = extractBits(Val, 8, 8) << 12; 120 uint16_t Imm4_3 = extractBits(Val, 4, 3) << 10; 121 uint16_t Imm7_6 = extractBits(Val, 7, 6) << 5; 122 uint16_t Imm2_1 = extractBits(Val, 2, 1) << 3; 123 uint16_t Imm5 = extractBits(Val, 5, 5) << 2; 124 Insn |= Imm8 | Imm4_3 | Imm7_6 | Imm2_1 | Imm5; 125 126 write16le(Loc, Insn); 127 return; 128 } 129 130 case R_RISCV_RVC_JUMP: { 131 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 11, Type); 132 checkAlignment(Loc, Val, 2, Type); 133 uint16_t Insn = read16le(Loc) & 0xE003; 134 uint16_t Imm11 = extractBits(Val, 11, 11) << 12; 135 uint16_t Imm4 = extractBits(Val, 4, 4) << 11; 136 uint16_t Imm9_8 = extractBits(Val, 9, 8) << 9; 137 uint16_t Imm10 = extractBits(Val, 10, 10) << 8; 138 uint16_t Imm6 = extractBits(Val, 6, 6) << 7; 139 uint16_t Imm7 = extractBits(Val, 7, 7) << 6; 140 uint16_t Imm3_1 = extractBits(Val, 3, 1) << 3; 141 uint16_t Imm5 = extractBits(Val, 5, 5) << 2; 142 Insn |= Imm11 | Imm4 | Imm9_8 | Imm10 | Imm6 | Imm7 | Imm3_1 | Imm5; 143 144 write16le(Loc, Insn); 145 return; 146 } 147 148 case R_RISCV_RVC_LUI: { 149 int64_t Imm = SignExtend64(Val + 0x800, Bits) >> 12; 150 checkInt(Loc, Imm, 6, Type); 151 if (Imm == 0) { // `c.lui rd, 0` is illegal, convert to `c.li rd, 0` 152 write16le(Loc, (read16le(Loc) & 0x0F83) | 0x4000); 153 } else { 154 uint16_t Imm17 = extractBits(Val + 0x800, 17, 17) << 12; 155 uint16_t Imm16_12 = extractBits(Val + 0x800, 16, 12) << 2; 156 write16le(Loc, (read16le(Loc) & 0xEF83) | Imm17 | Imm16_12); 157 } 158 return; 159 } 160 161 case R_RISCV_JAL: { 162 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 20, Type); 163 checkAlignment(Loc, Val, 2, Type); 164 165 uint32_t Insn = read32le(Loc) & 0xFFF; 166 uint32_t Imm20 = extractBits(Val, 20, 20) << 31; 167 uint32_t Imm10_1 = extractBits(Val, 10, 1) << 21; 168 uint32_t Imm11 = extractBits(Val, 11, 11) << 20; 169 uint32_t Imm19_12 = extractBits(Val, 19, 12) << 12; 170 Insn |= Imm20 | Imm10_1 | Imm11 | Imm19_12; 171 172 write32le(Loc, Insn); 173 return; 174 } 175 176 case R_RISCV_BRANCH: { 177 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 12, Type); 178 checkAlignment(Loc, Val, 2, Type); 179 180 uint32_t Insn = read32le(Loc) & 0x1FFF07F; 181 uint32_t Imm12 = extractBits(Val, 12, 12) << 31; 182 uint32_t Imm10_5 = extractBits(Val, 10, 5) << 25; 183 uint32_t Imm4_1 = extractBits(Val, 4, 1) << 8; 184 uint32_t Imm11 = extractBits(Val, 11, 11) << 7; 185 Insn |= Imm12 | Imm10_5 | Imm4_1 | Imm11; 186 187 write32le(Loc, Insn); 188 return; 189 } 190 191 // auipc + jalr pair 192 case R_RISCV_CALL: { 193 int64_t Hi = SignExtend64(Val + 0x800, Bits) >> 12; 194 checkInt(Loc, Hi, 20, Type); 195 if (isInt<20>(Hi)) { 196 relocateOne(Loc, R_RISCV_PCREL_HI20, Val); 197 relocateOne(Loc + 4, R_RISCV_PCREL_LO12_I, Val); 198 } 199 return; 200 } 201 202 case R_RISCV_PCREL_HI20: 203 case R_RISCV_HI20: { 204 uint64_t Hi = Val + 0x800; 205 checkInt(Loc, SignExtend64(Hi, Bits) >> 12, 20, Type); 206 write32le(Loc, (read32le(Loc) & 0xFFF) | (Hi & 0xFFFFF000)); 207 return; 208 } 209 210 case R_RISCV_PCREL_LO12_I: 211 case R_RISCV_LO12_I: { 212 uint64_t Hi = (Val + 0x800) >> 12; 213 uint64_t Lo = Val - (Hi << 12); 214 write32le(Loc, (read32le(Loc) & 0xFFFFF) | ((Lo & 0xFFF) << 20)); 215 return; 216 } 217 218 case R_RISCV_PCREL_LO12_S: 219 case R_RISCV_LO12_S: { 220 uint64_t Hi = (Val + 0x800) >> 12; 221 uint64_t Lo = Val - (Hi << 12); 222 uint32_t Imm11_5 = extractBits(Lo, 11, 5) << 25; 223 uint32_t Imm4_0 = extractBits(Lo, 4, 0) << 7; 224 write32le(Loc, (read32le(Loc) & 0x1FFF07F) | Imm11_5 | Imm4_0); 225 return; 226 } 227 228 case R_RISCV_ADD8: 229 *Loc += Val; 230 return; 231 case R_RISCV_ADD16: 232 write16le(Loc, read16le(Loc) + Val); 233 return; 234 case R_RISCV_ADD32: 235 write32le(Loc, read32le(Loc) + Val); 236 return; 237 case R_RISCV_ADD64: 238 write64le(Loc, read64le(Loc) + Val); 239 return; 240 case R_RISCV_SUB6: 241 *Loc = (*Loc & 0xc0) | (((*Loc & 0x3f) - Val) & 0x3f); 242 return; 243 case R_RISCV_SUB8: 244 *Loc -= Val; 245 return; 246 case R_RISCV_SUB16: 247 write16le(Loc, read16le(Loc) - Val); 248 return; 249 case R_RISCV_SUB32: 250 write32le(Loc, read32le(Loc) - Val); 251 return; 252 case R_RISCV_SUB64: 253 write64le(Loc, read64le(Loc) - Val); 254 return; 255 case R_RISCV_SET6: 256 *Loc = (*Loc & 0xc0) | (Val & 0x3f); 257 return; 258 case R_RISCV_SET8: 259 *Loc = Val; 260 return; 261 case R_RISCV_SET16: 262 write16le(Loc, Val); 263 return; 264 case R_RISCV_SET32: 265 case R_RISCV_32_PCREL: 266 write32le(Loc, Val); 267 return; 268 269 case R_RISCV_ALIGN: 270 case R_RISCV_RELAX: 271 return; // Ignored (for now) 272 case R_RISCV_NONE: 273 return; // Do nothing 274 275 // These are handled by the dynamic linker 276 case R_RISCV_RELATIVE: 277 case R_RISCV_COPY: 278 case R_RISCV_JUMP_SLOT: 279 // GP-relative relocations are only produced after relaxation, which 280 // we don't support for now 281 case R_RISCV_GPREL_I: 282 case R_RISCV_GPREL_S: 283 default: 284 error(getErrorLocation(Loc) + 285 "unimplemented relocation: " + toString(Type)); 286 return; 287 } 288 } 289 290 TargetInfo *elf::getRISCVTargetInfo() { 291 static RISCV Target; 292 return &Target; 293 } 294