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 "OutputSections.h" 11 #include "Symbols.h" 12 #include "SyntheticSections.h" 13 #include "Target.h" 14 #include "llvm/Support/TimeProfiler.h" 15 16 using namespace llvm; 17 using namespace llvm::object; 18 using namespace llvm::support::endian; 19 using namespace llvm::ELF; 20 using namespace lld; 21 using namespace lld::elf; 22 23 namespace { 24 25 class RISCV final : public TargetInfo { 26 public: 27 RISCV(); 28 uint32_t calcEFlags() const override; 29 int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override; 30 void writeGotHeader(uint8_t *buf) const override; 31 void writeGotPlt(uint8_t *buf, const Symbol &s) const override; 32 void writeIgotPlt(uint8_t *buf, const Symbol &s) const override; 33 void writePltHeader(uint8_t *buf) const override; 34 void writePlt(uint8_t *buf, const Symbol &sym, 35 uint64_t pltEntryAddr) const override; 36 RelType getDynRel(RelType type) const override; 37 RelExpr getRelExpr(RelType type, const Symbol &s, 38 const uint8_t *loc) const override; 39 void relocate(uint8_t *loc, const Relocation &rel, 40 uint64_t val) const override; 41 bool relaxOnce(int pass) const override; 42 }; 43 44 } // end anonymous namespace 45 46 const uint64_t dtpOffset = 0x800; 47 48 enum Op { 49 ADDI = 0x13, 50 AUIPC = 0x17, 51 JALR = 0x67, 52 LD = 0x3003, 53 LW = 0x2003, 54 SRLI = 0x5013, 55 SUB = 0x40000033, 56 }; 57 58 enum Reg { 59 X_RA = 1, 60 X_T0 = 5, 61 X_T1 = 6, 62 X_T2 = 7, 63 X_T3 = 28, 64 }; 65 66 static uint32_t hi20(uint32_t val) { return (val + 0x800) >> 12; } 67 static uint32_t lo12(uint32_t val) { return val & 4095; } 68 69 static uint32_t itype(uint32_t op, uint32_t rd, uint32_t rs1, uint32_t imm) { 70 return op | (rd << 7) | (rs1 << 15) | (imm << 20); 71 } 72 static uint32_t rtype(uint32_t op, uint32_t rd, uint32_t rs1, uint32_t rs2) { 73 return op | (rd << 7) | (rs1 << 15) | (rs2 << 20); 74 } 75 static uint32_t utype(uint32_t op, uint32_t rd, uint32_t imm) { 76 return op | (rd << 7) | (imm << 12); 77 } 78 79 RISCV::RISCV() { 80 copyRel = R_RISCV_COPY; 81 pltRel = R_RISCV_JUMP_SLOT; 82 relativeRel = R_RISCV_RELATIVE; 83 iRelativeRel = R_RISCV_IRELATIVE; 84 if (config->is64) { 85 symbolicRel = R_RISCV_64; 86 tlsModuleIndexRel = R_RISCV_TLS_DTPMOD64; 87 tlsOffsetRel = R_RISCV_TLS_DTPREL64; 88 tlsGotRel = R_RISCV_TLS_TPREL64; 89 } else { 90 symbolicRel = R_RISCV_32; 91 tlsModuleIndexRel = R_RISCV_TLS_DTPMOD32; 92 tlsOffsetRel = R_RISCV_TLS_DTPREL32; 93 tlsGotRel = R_RISCV_TLS_TPREL32; 94 } 95 gotRel = symbolicRel; 96 97 // .got[0] = _DYNAMIC 98 gotHeaderEntriesNum = 1; 99 100 // .got.plt[0] = _dl_runtime_resolve, .got.plt[1] = link_map 101 gotPltHeaderEntriesNum = 2; 102 103 pltHeaderSize = 32; 104 pltEntrySize = 16; 105 ipltEntrySize = 16; 106 } 107 108 static uint32_t getEFlags(InputFile *f) { 109 if (config->is64) 110 return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader().e_flags; 111 return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader().e_flags; 112 } 113 114 uint32_t RISCV::calcEFlags() const { 115 // If there are only binary input files (from -b binary), use a 116 // value of 0 for the ELF header flags. 117 if (ctx->objectFiles.empty()) 118 return 0; 119 120 uint32_t target = getEFlags(ctx->objectFiles.front()); 121 122 for (InputFile *f : ctx->objectFiles) { 123 uint32_t eflags = getEFlags(f); 124 if (eflags & EF_RISCV_RVC) 125 target |= EF_RISCV_RVC; 126 127 if ((eflags & EF_RISCV_FLOAT_ABI) != (target & EF_RISCV_FLOAT_ABI)) 128 error(toString(f) + 129 ": cannot link object files with different floating-point ABI"); 130 131 if ((eflags & EF_RISCV_RVE) != (target & EF_RISCV_RVE)) 132 error(toString(f) + 133 ": cannot link object files with different EF_RISCV_RVE"); 134 } 135 136 return target; 137 } 138 139 int64_t RISCV::getImplicitAddend(const uint8_t *buf, RelType type) const { 140 switch (type) { 141 default: 142 internalLinkerError(getErrorLocation(buf), 143 "cannot read addend for relocation " + toString(type)); 144 return 0; 145 case R_RISCV_32: 146 case R_RISCV_TLS_DTPMOD32: 147 case R_RISCV_TLS_DTPREL32: 148 return SignExtend64<32>(read32le(buf)); 149 case R_RISCV_64: 150 return read64le(buf); 151 case R_RISCV_RELATIVE: 152 case R_RISCV_IRELATIVE: 153 return config->is64 ? read64le(buf) : read32le(buf); 154 case R_RISCV_NONE: 155 case R_RISCV_JUMP_SLOT: 156 // These relocations are defined as not having an implicit addend. 157 return 0; 158 } 159 } 160 161 void RISCV::writeGotHeader(uint8_t *buf) const { 162 if (config->is64) 163 write64le(buf, mainPart->dynamic->getVA()); 164 else 165 write32le(buf, mainPart->dynamic->getVA()); 166 } 167 168 void RISCV::writeGotPlt(uint8_t *buf, const Symbol &s) const { 169 if (config->is64) 170 write64le(buf, in.plt->getVA()); 171 else 172 write32le(buf, in.plt->getVA()); 173 } 174 175 void RISCV::writeIgotPlt(uint8_t *buf, const Symbol &s) const { 176 if (config->writeAddends) { 177 if (config->is64) 178 write64le(buf, s.getVA()); 179 else 180 write32le(buf, s.getVA()); 181 } 182 } 183 184 void RISCV::writePltHeader(uint8_t *buf) const { 185 // 1: auipc t2, %pcrel_hi(.got.plt) 186 // sub t1, t1, t3 187 // l[wd] t3, %pcrel_lo(1b)(t2); t3 = _dl_runtime_resolve 188 // addi t1, t1, -pltHeaderSize-12; t1 = &.plt[i] - &.plt[0] 189 // addi t0, t2, %pcrel_lo(1b) 190 // srli t1, t1, (rv64?1:2); t1 = &.got.plt[i] - &.got.plt[0] 191 // l[wd] t0, Wordsize(t0); t0 = link_map 192 // jr t3 193 uint32_t offset = in.gotPlt->getVA() - in.plt->getVA(); 194 uint32_t load = config->is64 ? LD : LW; 195 write32le(buf + 0, utype(AUIPC, X_T2, hi20(offset))); 196 write32le(buf + 4, rtype(SUB, X_T1, X_T1, X_T3)); 197 write32le(buf + 8, itype(load, X_T3, X_T2, lo12(offset))); 198 write32le(buf + 12, itype(ADDI, X_T1, X_T1, -target->pltHeaderSize - 12)); 199 write32le(buf + 16, itype(ADDI, X_T0, X_T2, lo12(offset))); 200 write32le(buf + 20, itype(SRLI, X_T1, X_T1, config->is64 ? 1 : 2)); 201 write32le(buf + 24, itype(load, X_T0, X_T0, config->wordsize)); 202 write32le(buf + 28, itype(JALR, 0, X_T3, 0)); 203 } 204 205 void RISCV::writePlt(uint8_t *buf, const Symbol &sym, 206 uint64_t pltEntryAddr) const { 207 // 1: auipc t3, %pcrel_hi([email protected]) 208 // l[wd] t3, %pcrel_lo(1b)(t3) 209 // jalr t1, t3 210 // nop 211 uint32_t offset = sym.getGotPltVA() - pltEntryAddr; 212 write32le(buf + 0, utype(AUIPC, X_T3, hi20(offset))); 213 write32le(buf + 4, itype(config->is64 ? LD : LW, X_T3, X_T3, lo12(offset))); 214 write32le(buf + 8, itype(JALR, X_T1, X_T3, 0)); 215 write32le(buf + 12, itype(ADDI, 0, 0, 0)); 216 } 217 218 RelType RISCV::getDynRel(RelType type) const { 219 return type == target->symbolicRel ? type 220 : static_cast<RelType>(R_RISCV_NONE); 221 } 222 223 RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s, 224 const uint8_t *loc) const { 225 switch (type) { 226 case R_RISCV_NONE: 227 return R_NONE; 228 case R_RISCV_32: 229 case R_RISCV_64: 230 case R_RISCV_HI20: 231 case R_RISCV_LO12_I: 232 case R_RISCV_LO12_S: 233 case R_RISCV_RVC_LUI: 234 return R_ABS; 235 case R_RISCV_ADD8: 236 case R_RISCV_ADD16: 237 case R_RISCV_ADD32: 238 case R_RISCV_ADD64: 239 case R_RISCV_SET6: 240 case R_RISCV_SET8: 241 case R_RISCV_SET16: 242 case R_RISCV_SET32: 243 case R_RISCV_SUB6: 244 case R_RISCV_SUB8: 245 case R_RISCV_SUB16: 246 case R_RISCV_SUB32: 247 case R_RISCV_SUB64: 248 return R_RISCV_ADD; 249 case R_RISCV_JAL: 250 case R_RISCV_BRANCH: 251 case R_RISCV_PCREL_HI20: 252 case R_RISCV_RVC_BRANCH: 253 case R_RISCV_RVC_JUMP: 254 case R_RISCV_32_PCREL: 255 return R_PC; 256 case R_RISCV_CALL: 257 case R_RISCV_CALL_PLT: 258 return R_PLT_PC; 259 case R_RISCV_GOT_HI20: 260 return R_GOT_PC; 261 case R_RISCV_PCREL_LO12_I: 262 case R_RISCV_PCREL_LO12_S: 263 return R_RISCV_PC_INDIRECT; 264 case R_RISCV_TLS_GD_HI20: 265 return R_TLSGD_PC; 266 case R_RISCV_TLS_GOT_HI20: 267 config->hasTlsIe = true; 268 return R_GOT_PC; 269 case R_RISCV_TPREL_HI20: 270 case R_RISCV_TPREL_LO12_I: 271 case R_RISCV_TPREL_LO12_S: 272 return R_TPREL; 273 case R_RISCV_TPREL_ADD: 274 return R_NONE; 275 case R_RISCV_ALIGN: 276 return R_RELAX_HINT; 277 case R_RISCV_RELAX: 278 return config->relax ? R_RELAX_HINT : R_NONE; 279 default: 280 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) + 281 ") against symbol " + toString(s)); 282 return R_NONE; 283 } 284 } 285 286 // Extract bits V[Begin:End], where range is inclusive, and Begin must be < 63. 287 static uint32_t extractBits(uint64_t v, uint32_t begin, uint32_t end) { 288 return (v & ((1ULL << (begin + 1)) - 1)) >> end; 289 } 290 291 void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { 292 const unsigned bits = config->wordsize * 8; 293 294 switch (rel.type) { 295 case R_RISCV_32: 296 write32le(loc, val); 297 return; 298 case R_RISCV_64: 299 write64le(loc, val); 300 return; 301 302 case R_RISCV_RVC_BRANCH: { 303 checkInt(loc, val, 9, rel); 304 checkAlignment(loc, val, 2, rel); 305 uint16_t insn = read16le(loc) & 0xE383; 306 uint16_t imm8 = extractBits(val, 8, 8) << 12; 307 uint16_t imm4_3 = extractBits(val, 4, 3) << 10; 308 uint16_t imm7_6 = extractBits(val, 7, 6) << 5; 309 uint16_t imm2_1 = extractBits(val, 2, 1) << 3; 310 uint16_t imm5 = extractBits(val, 5, 5) << 2; 311 insn |= imm8 | imm4_3 | imm7_6 | imm2_1 | imm5; 312 313 write16le(loc, insn); 314 return; 315 } 316 317 case R_RISCV_RVC_JUMP: { 318 checkInt(loc, val, 12, rel); 319 checkAlignment(loc, val, 2, rel); 320 uint16_t insn = read16le(loc) & 0xE003; 321 uint16_t imm11 = extractBits(val, 11, 11) << 12; 322 uint16_t imm4 = extractBits(val, 4, 4) << 11; 323 uint16_t imm9_8 = extractBits(val, 9, 8) << 9; 324 uint16_t imm10 = extractBits(val, 10, 10) << 8; 325 uint16_t imm6 = extractBits(val, 6, 6) << 7; 326 uint16_t imm7 = extractBits(val, 7, 7) << 6; 327 uint16_t imm3_1 = extractBits(val, 3, 1) << 3; 328 uint16_t imm5 = extractBits(val, 5, 5) << 2; 329 insn |= imm11 | imm4 | imm9_8 | imm10 | imm6 | imm7 | imm3_1 | imm5; 330 331 write16le(loc, insn); 332 return; 333 } 334 335 case R_RISCV_RVC_LUI: { 336 int64_t imm = SignExtend64(val + 0x800, bits) >> 12; 337 checkInt(loc, imm, 6, rel); 338 if (imm == 0) { // `c.lui rd, 0` is illegal, convert to `c.li rd, 0` 339 write16le(loc, (read16le(loc) & 0x0F83) | 0x4000); 340 } else { 341 uint16_t imm17 = extractBits(val + 0x800, 17, 17) << 12; 342 uint16_t imm16_12 = extractBits(val + 0x800, 16, 12) << 2; 343 write16le(loc, (read16le(loc) & 0xEF83) | imm17 | imm16_12); 344 } 345 return; 346 } 347 348 case R_RISCV_JAL: { 349 checkInt(loc, val, 21, rel); 350 checkAlignment(loc, val, 2, rel); 351 352 uint32_t insn = read32le(loc) & 0xFFF; 353 uint32_t imm20 = extractBits(val, 20, 20) << 31; 354 uint32_t imm10_1 = extractBits(val, 10, 1) << 21; 355 uint32_t imm11 = extractBits(val, 11, 11) << 20; 356 uint32_t imm19_12 = extractBits(val, 19, 12) << 12; 357 insn |= imm20 | imm10_1 | imm11 | imm19_12; 358 359 write32le(loc, insn); 360 return; 361 } 362 363 case R_RISCV_BRANCH: { 364 checkInt(loc, val, 13, rel); 365 checkAlignment(loc, val, 2, rel); 366 367 uint32_t insn = read32le(loc) & 0x1FFF07F; 368 uint32_t imm12 = extractBits(val, 12, 12) << 31; 369 uint32_t imm10_5 = extractBits(val, 10, 5) << 25; 370 uint32_t imm4_1 = extractBits(val, 4, 1) << 8; 371 uint32_t imm11 = extractBits(val, 11, 11) << 7; 372 insn |= imm12 | imm10_5 | imm4_1 | imm11; 373 374 write32le(loc, insn); 375 return; 376 } 377 378 // auipc + jalr pair 379 case R_RISCV_CALL: 380 case R_RISCV_CALL_PLT: { 381 int64_t hi = SignExtend64(val + 0x800, bits) >> 12; 382 checkInt(loc, hi, 20, rel); 383 if (isInt<20>(hi)) { 384 relocateNoSym(loc, R_RISCV_PCREL_HI20, val); 385 relocateNoSym(loc + 4, R_RISCV_PCREL_LO12_I, val); 386 } 387 return; 388 } 389 390 case R_RISCV_GOT_HI20: 391 case R_RISCV_PCREL_HI20: 392 case R_RISCV_TLS_GD_HI20: 393 case R_RISCV_TLS_GOT_HI20: 394 case R_RISCV_TPREL_HI20: 395 case R_RISCV_HI20: { 396 uint64_t hi = val + 0x800; 397 checkInt(loc, SignExtend64(hi, bits) >> 12, 20, rel); 398 write32le(loc, (read32le(loc) & 0xFFF) | (hi & 0xFFFFF000)); 399 return; 400 } 401 402 case R_RISCV_PCREL_LO12_I: 403 case R_RISCV_TPREL_LO12_I: 404 case R_RISCV_LO12_I: { 405 uint64_t hi = (val + 0x800) >> 12; 406 uint64_t lo = val - (hi << 12); 407 write32le(loc, (read32le(loc) & 0xFFFFF) | ((lo & 0xFFF) << 20)); 408 return; 409 } 410 411 case R_RISCV_PCREL_LO12_S: 412 case R_RISCV_TPREL_LO12_S: 413 case R_RISCV_LO12_S: { 414 uint64_t hi = (val + 0x800) >> 12; 415 uint64_t lo = val - (hi << 12); 416 uint32_t imm11_5 = extractBits(lo, 11, 5) << 25; 417 uint32_t imm4_0 = extractBits(lo, 4, 0) << 7; 418 write32le(loc, (read32le(loc) & 0x1FFF07F) | imm11_5 | imm4_0); 419 return; 420 } 421 422 case R_RISCV_ADD8: 423 *loc += val; 424 return; 425 case R_RISCV_ADD16: 426 write16le(loc, read16le(loc) + val); 427 return; 428 case R_RISCV_ADD32: 429 write32le(loc, read32le(loc) + val); 430 return; 431 case R_RISCV_ADD64: 432 write64le(loc, read64le(loc) + val); 433 return; 434 case R_RISCV_SUB6: 435 *loc = (*loc & 0xc0) | (((*loc & 0x3f) - val) & 0x3f); 436 return; 437 case R_RISCV_SUB8: 438 *loc -= val; 439 return; 440 case R_RISCV_SUB16: 441 write16le(loc, read16le(loc) - val); 442 return; 443 case R_RISCV_SUB32: 444 write32le(loc, read32le(loc) - val); 445 return; 446 case R_RISCV_SUB64: 447 write64le(loc, read64le(loc) - val); 448 return; 449 case R_RISCV_SET6: 450 *loc = (*loc & 0xc0) | (val & 0x3f); 451 return; 452 case R_RISCV_SET8: 453 *loc = val; 454 return; 455 case R_RISCV_SET16: 456 write16le(loc, val); 457 return; 458 case R_RISCV_SET32: 459 case R_RISCV_32_PCREL: 460 write32le(loc, val); 461 return; 462 463 case R_RISCV_TLS_DTPREL32: 464 write32le(loc, val - dtpOffset); 465 break; 466 case R_RISCV_TLS_DTPREL64: 467 write64le(loc, val - dtpOffset); 468 break; 469 470 case R_RISCV_RELAX: 471 return; // Ignored (for now) 472 473 default: 474 llvm_unreachable("unknown relocation"); 475 } 476 } 477 478 namespace { 479 struct SymbolAnchor { 480 uint64_t offset; 481 Defined *d; 482 bool end; // true for the anchor of st_value+st_size 483 }; 484 } // namespace 485 486 struct elf::RISCVRelaxAux { 487 // This records symbol start and end offsets which will be adjusted according 488 // to the nearest relocDeltas element. 489 SmallVector<SymbolAnchor, 0> anchors; 490 // For relocations[i], the actual offset is r_offset - (i ? relocDeltas[i-1] : 491 // 0). 492 std::unique_ptr<uint32_t[]> relocDeltas; 493 // For relocations[i], the actual type is relocTypes[i]. 494 std::unique_ptr<RelType[]> relocTypes; 495 SmallVector<uint32_t, 0> writes; 496 }; 497 498 static void initSymbolAnchors() { 499 SmallVector<InputSection *, 0> storage; 500 for (OutputSection *osec : outputSections) { 501 if (!(osec->flags & SHF_EXECINSTR)) 502 continue; 503 for (InputSection *sec : getInputSections(*osec, storage)) { 504 sec->relaxAux = make<RISCVRelaxAux>(); 505 if (sec->relocations.size()) { 506 sec->relaxAux->relocDeltas = 507 std::make_unique<uint32_t[]>(sec->relocations.size()); 508 sec->relaxAux->relocTypes = 509 std::make_unique<RelType[]>(sec->relocations.size()); 510 } 511 } 512 } 513 // Store anchors (st_value and st_value+st_size) for symbols relative to text 514 // sections. 515 for (InputFile *file : ctx->objectFiles) 516 for (Symbol *sym : file->getSymbols()) { 517 auto *d = dyn_cast<Defined>(sym); 518 if (!d || d->file != file) 519 continue; 520 if (auto *sec = dyn_cast_or_null<InputSection>(d->section)) 521 if (sec->flags & SHF_EXECINSTR && sec->relaxAux) { 522 // If sec is discarded, relaxAux will be nullptr. 523 sec->relaxAux->anchors.push_back({d->value, d, false}); 524 sec->relaxAux->anchors.push_back({d->value + d->size, d, true}); 525 } 526 } 527 // Sort anchors by offset so that we can find the closest relocation 528 // efficiently. For a zero size symbol, ensure that its start anchor precedes 529 // its end anchor. For two symbols with anchors at the same offset, their 530 // order does not matter. 531 for (OutputSection *osec : outputSections) { 532 if (!(osec->flags & SHF_EXECINSTR)) 533 continue; 534 for (InputSection *sec : getInputSections(*osec, storage)) { 535 llvm::sort(sec->relaxAux->anchors, [](auto &a, auto &b) { 536 return std::make_pair(a.offset, a.end) < 537 std::make_pair(b.offset, b.end); 538 }); 539 } 540 } 541 } 542 543 // Relax R_RISCV_CALL/R_RISCV_CALL_PLT auipc+jalr to c.j, c.jal, or jal. 544 static void relaxCall(const InputSection &sec, size_t i, uint64_t loc, 545 Relocation &r, uint32_t &remove) { 546 const bool rvc = config->eflags & EF_RISCV_RVC; 547 const Symbol &sym = *r.sym; 548 const uint64_t insnPair = read64le(sec.rawData.data() + r.offset); 549 const uint32_t rd = extractBits(insnPair, 32 + 11, 32 + 7); 550 const uint64_t dest = 551 (r.expr == R_PLT_PC ? sym.getPltVA() : sym.getVA()) + r.addend; 552 const int64_t displace = dest - loc; 553 554 if (rvc && isInt<12>(displace) && rd == 0) { 555 sec.relaxAux->relocTypes[i] = R_RISCV_RVC_JUMP; 556 sec.relaxAux->writes.push_back(0xa001); // c.j 557 remove = 6; 558 } else if (rvc && isInt<12>(displace) && rd == X_RA && 559 !config->is64) { // RV32C only 560 sec.relaxAux->relocTypes[i] = R_RISCV_RVC_JUMP; 561 sec.relaxAux->writes.push_back(0x2001); // c.jal 562 remove = 6; 563 } else if (isInt<21>(displace)) { 564 sec.relaxAux->relocTypes[i] = R_RISCV_JAL; 565 sec.relaxAux->writes.push_back(0x6f | rd << 7); // jal 566 remove = 4; 567 } 568 } 569 570 static bool relax(InputSection &sec) { 571 const uint64_t secAddr = sec.getVA(); 572 auto &aux = *sec.relaxAux; 573 bool changed = false; 574 575 // Get st_value delta for symbols relative to this section from the previous 576 // iteration. 577 DenseMap<const Defined *, uint64_t> valueDelta; 578 ArrayRef<SymbolAnchor> sa = makeArrayRef(aux.anchors); 579 uint32_t delta = 0; 580 for (auto it : llvm::enumerate(sec.relocations)) { 581 for (; sa.size() && sa[0].offset <= it.value().offset; sa = sa.slice(1)) 582 if (!sa[0].end) 583 valueDelta[sa[0].d] = delta; 584 delta = aux.relocDeltas[it.index()]; 585 } 586 for (const SymbolAnchor &sa : sa) 587 if (!sa.end) 588 valueDelta[sa.d] = delta; 589 sa = makeArrayRef(aux.anchors); 590 delta = 0; 591 592 std::fill_n(aux.relocTypes.get(), sec.relocations.size(), R_RISCV_NONE); 593 aux.writes.clear(); 594 for (auto it : llvm::enumerate(sec.relocations)) { 595 Relocation &r = it.value(); 596 const size_t i = it.index(); 597 const uint64_t loc = secAddr + r.offset - delta; 598 uint32_t &cur = aux.relocDeltas[i], remove = 0; 599 switch (r.type) { 600 case R_RISCV_ALIGN: { 601 const uint64_t nextLoc = loc + r.addend; 602 const uint64_t align = PowerOf2Ceil(r.addend + 2); 603 // All bytes beyond the alignment boundary should be removed. 604 remove = nextLoc - ((loc + align - 1) & -align); 605 assert(static_cast<int32_t>(remove) >= 0 && 606 "R_RISCV_ALIGN needs expanding the content"); 607 break; 608 } 609 case R_RISCV_CALL: 610 case R_RISCV_CALL_PLT: 611 if (i + 1 != sec.relocations.size() && 612 sec.relocations[i + 1].type == R_RISCV_RELAX) 613 relaxCall(sec, i, loc, r, remove); 614 break; 615 } 616 617 // For all anchors whose offsets are <= r.offset, they are preceded by 618 // the previous relocation whose `relocDeltas` value equals `delta`. 619 // Decrease their st_value and update their st_size. 620 for (; sa.size() && sa[0].offset <= r.offset; sa = sa.slice(1)) { 621 if (sa[0].end) 622 sa[0].d->size = sa[0].offset - delta - sa[0].d->value; 623 else 624 sa[0].d->value -= delta - valueDelta.find(sa[0].d)->second; 625 } 626 delta += remove; 627 if (delta != cur) { 628 cur = delta; 629 changed = true; 630 } 631 } 632 633 for (const SymbolAnchor &a : sa) { 634 if (a.end) 635 a.d->size = a.offset - delta - a.d->value; 636 else 637 a.d->value -= delta - valueDelta.find(a.d)->second; 638 } 639 // Inform assignAddresses that the size has changed. 640 if (!isUInt<16>(delta)) 641 fatal("section size decrease is too large"); 642 sec.bytesDropped = delta; 643 return changed; 644 } 645 646 // When relaxing just R_RISCV_ALIGN, relocDeltas is usually changed only once in 647 // the absence of a linker script. For call and load/store R_RISCV_RELAX, code 648 // shrinkage may reduce displacement and make more relocations eligible for 649 // relaxation. Code shrinkage may increase displacement to a call/load/store 650 // target at a higher fixed address, invalidating an earlier relaxation. Any 651 // change in section sizes can have cascading effect and require another 652 // relaxation pass. 653 bool RISCV::relaxOnce(int pass) const { 654 llvm::TimeTraceScope timeScope("RISC-V relaxOnce"); 655 if (config->relocatable) 656 return false; 657 658 if (pass == 0) 659 initSymbolAnchors(); 660 661 SmallVector<InputSection *, 0> storage; 662 bool changed = false; 663 for (OutputSection *osec : outputSections) { 664 if (!(osec->flags & SHF_EXECINSTR)) 665 continue; 666 for (InputSection *sec : getInputSections(*osec, storage)) 667 changed |= relax(*sec); 668 } 669 return changed; 670 } 671 672 void elf::riscvFinalizeRelax(int passes) { 673 llvm::TimeTraceScope timeScope("Finalize RISC-V relaxation"); 674 log("relaxation passes: " + Twine(passes)); 675 SmallVector<InputSection *, 0> storage; 676 for (OutputSection *osec : outputSections) { 677 if (!(osec->flags & SHF_EXECINSTR)) 678 continue; 679 for (InputSection *sec : getInputSections(*osec, storage)) { 680 RISCVRelaxAux &aux = *sec->relaxAux; 681 if (!aux.relocDeltas) 682 continue; 683 684 auto &rels = sec->relocations; 685 ArrayRef<uint8_t> old = sec->rawData; 686 size_t newSize = 687 old.size() - aux.relocDeltas[sec->relocations.size() - 1]; 688 size_t writesIdx = 0; 689 uint8_t *p = context().bAlloc.Allocate<uint8_t>(newSize); 690 uint64_t offset = 0; 691 int64_t delta = 0; 692 sec->rawData = makeArrayRef(p, newSize); 693 sec->bytesDropped = 0; 694 695 // Update section content: remove NOPs for R_RISCV_ALIGN and rewrite 696 // instructions for relaxed relocations. 697 for (size_t i = 0, e = rels.size(); i != e; ++i) { 698 uint32_t remove = aux.relocDeltas[i] - delta; 699 delta = aux.relocDeltas[i]; 700 if (remove == 0) 701 continue; 702 703 // Copy from last location to the current relocated location. 704 const Relocation &r = rels[i]; 705 uint64_t size = r.offset - offset; 706 memcpy(p, old.data() + offset, size); 707 p += size; 708 709 // For R_RISCV_ALIGN, we will place `offset` in a location (among NOPs) 710 // to satisfy the alignment requirement. If `remove` is a multiple of 4, 711 // it is as if we have skipped some NOPs. Otherwise we are in the middle 712 // of a 4-byte NOP, and we need to rewrite the NOP sequence. 713 int64_t skip = 0; 714 if (r.type == R_RISCV_ALIGN) { 715 if (remove % 4 != 0) { 716 skip = r.addend - remove; 717 int64_t j = 0; 718 for (; j + 4 <= skip; j += 4) 719 write32le(p + j, 0x00000013); // nop 720 if (j != skip) { 721 assert(j + 2 == skip); 722 write16le(p + j, 0x0001); // c.nop 723 } 724 } 725 } else if (RelType newType = aux.relocTypes[i]) { 726 const uint32_t insn = aux.writes[writesIdx++]; 727 switch (newType) { 728 case R_RISCV_RVC_JUMP: 729 skip = 2; 730 write16le(p, insn); 731 break; 732 case R_RISCV_JAL: 733 skip = 4; 734 write32le(p, insn); 735 break; 736 default: 737 llvm_unreachable("unsupported type"); 738 } 739 } 740 741 p += skip; 742 offset = r.offset + skip + remove; 743 } 744 memcpy(p, old.data() + offset, old.size() - offset); 745 746 // Subtract the previous relocDeltas value from the relocation offset. 747 // For a pair of R_RISCV_CALL/R_RISCV_RELAX with the same offset, decrease 748 // their r_offset by the same delta. 749 delta = 0; 750 for (size_t i = 0, e = rels.size(); i != e;) { 751 uint64_t cur = rels[i].offset; 752 do { 753 rels[i].offset -= delta; 754 if (aux.relocTypes[i] != R_RISCV_NONE) 755 rels[i].type = aux.relocTypes[i]; 756 } while (++i != e && rels[i].offset == cur); 757 delta = aux.relocDeltas[i - 1]; 758 } 759 } 760 } 761 } 762 763 TargetInfo *elf::getRISCVTargetInfo() { 764 static RISCV target; 765 return ⌖ 766 } 767