brintos

brintos / llvm-project-archived public Read only

0
0
Text · 58.2 KiB · c6cdf05 Raw
1633 lines · cpp
1//===- LoongArch.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-exception6//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/BinaryFormat/ELF.h"15#include "llvm/Support/LEB128.h"16 17using namespace llvm;18using namespace llvm::object;19using namespace llvm::support::endian;20using namespace llvm::ELF;21using namespace lld;22using namespace lld::elf;23 24namespace {25class LoongArch final : public TargetInfo {26public:27  LoongArch(Ctx &);28  uint32_t calcEFlags() const override;29  int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;30  void writeGotPlt(uint8_t *buf, const Symbol &s) const override;31  void writeIgotPlt(uint8_t *buf, const Symbol &s) const override;32  void writePltHeader(uint8_t *buf) const override;33  void writePlt(uint8_t *buf, const Symbol &sym,34                uint64_t pltEntryAddr) const override;35  RelType getDynRel(RelType type) const override;36  RelExpr getRelExpr(RelType type, const Symbol &s,37                     const uint8_t *loc) const override;38  bool usesOnlyLowPageBits(RelType type) 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  bool synthesizeAlign(uint64_t &dot, InputSection *sec) override;43  RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;44  void relocateAlloc(InputSection &sec, uint8_t *buf) const override;45  void finalizeRelax(int passes) const override;46 47private:48  void tlsdescToIe(uint8_t *loc, const Relocation &rel, uint64_t val) const;49  void tlsdescToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;50  bool tryGotToPCRel(uint8_t *loc, const Relocation &rHi20,51                     const Relocation &rLo12, uint64_t secAddr) const;52  template <class ELFT, class RelTy>53  bool synthesizeAlignForInput(uint64_t &dot, InputSection *sec,54                               Relocs<RelTy> rels);55  template <class ELFT, class RelTy>56  void finalizeSynthesizeAligns(uint64_t &dot, InputSection *sec,57                                Relocs<RelTy> rels);58  template <class ELFT>59  bool synthesizeAlignAux(uint64_t &dot, InputSection *sec);60 61  // The following two variables are used by synthesized ALIGN relocations.62  InputSection *baseSec = nullptr;63  // r_offset and r_addend pairs.64  SmallVector<std::pair<uint64_t, uint64_t>, 0> synthesizedAligns;65};66} // end anonymous namespace67 68namespace {69enum Op {70  SUB_W = 0x00110000,71  SUB_D = 0x00118000,72  BREAK = 0x002a0000,73  SRLI_W = 0x00448000,74  SRLI_D = 0x00450000,75  ADDI_W = 0x02800000,76  ADDI_D = 0x02c00000,77  ANDI = 0x03400000,78  ORI = 0x03800000,79  LU12I_W = 0x14000000,80  PCADDI = 0x18000000,81  PCADDU12I = 0x1c000000,82  PCALAU12I = 0x1a000000,83  LD_W = 0x28800000,84  LD_D = 0x28c00000,85  JIRL = 0x4c000000,86  B = 0x50000000,87  BL = 0x54000000,88};89 90enum Reg {91  R_ZERO = 0,92  R_RA = 1,93  R_TP = 2,94  R_A0 = 4,95  R_T0 = 12,96  R_T1 = 13,97  R_T2 = 14,98  R_T3 = 15,99};100} // namespace101 102// Mask out the input's lowest 12 bits for use with `pcalau12i`, in sequences103// like `pcalau12i + addi.[wd]` or `pcalau12i + {ld,st}.*` where the `pcalau12i`104// produces a PC-relative intermediate value with the lowest 12 bits zeroed (the105// "page") for the next instruction to add in the "page offset". (`pcalau12i`106// stands for something like "PC ALigned Add Upper that starts from the 12th107// bit, Immediate".)108//109// Here a "page" is in fact just another way to refer to the 12-bit range110// allowed by the immediate field of the addi/ld/st instructions, and not111// related to the system or the kernel's actual page size. The semantics happen112// to match the AArch64 `adrp`, so the concept of "page" is borrowed here.113static uint64_t getLoongArchPage(uint64_t p) {114  return p & ~static_cast<uint64_t>(0xfff);115}116 117static uint32_t lo12(uint32_t val) { return val & 0xfff; }118 119// Calculate the adjusted page delta between dest and PC.120uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type) {121  // Note that if the sequence being relocated is `pcalau12i + addi.d + lu32i.d122  // + lu52i.d`, they must be adjacent so that we can infer the PC of123  // `pcalau12i` when calculating the page delta for the other two instructions124  // (lu32i.d and lu52i.d). Compensate all the sign-extensions is a bit125  // complicated. Just use psABI recommended algorithm.126  uint64_t pcalau12i_pc;127  switch (type) {128  case R_LARCH_PCALA64_LO20:129  case R_LARCH_GOT64_PC_LO20:130  case R_LARCH_TLS_IE64_PC_LO20:131  case R_LARCH_TLS_DESC64_PC_LO20:132    pcalau12i_pc = pc - 8;133    break;134  case R_LARCH_PCALA64_HI12:135  case R_LARCH_GOT64_PC_HI12:136  case R_LARCH_TLS_IE64_PC_HI12:137  case R_LARCH_TLS_DESC64_PC_HI12:138    pcalau12i_pc = pc - 12;139    break;140  default:141    pcalau12i_pc = pc;142    break;143  }144  uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pcalau12i_pc);145  if (dest & 0x800)146    result += 0x1000 - 0x1'0000'0000;147  if (result & 0x8000'0000)148    result += 0x1'0000'0000;149  return result;150}151 152static uint32_t hi20(uint32_t val) { return (val + 0x800) >> 12; }153 154static uint32_t insn(uint32_t op, uint32_t d, uint32_t j, uint32_t k) {155  return op | d | (j << 5) | (k << 10);156}157 158// Extract bits v[begin:end], where range is inclusive.159static uint32_t extractBits(uint64_t v, uint32_t begin, uint32_t end) {160  return begin == 63 ? v >> end : (v & ((1ULL << (begin + 1)) - 1)) >> end;161}162 163static uint32_t getD5(uint64_t v) { return extractBits(v, 4, 0); }164 165static uint32_t getJ5(uint64_t v) { return extractBits(v, 9, 5); }166 167static uint32_t setD5k16(uint32_t insn, uint32_t imm) {168  uint32_t immLo = extractBits(imm, 15, 0);169  uint32_t immHi = extractBits(imm, 20, 16);170  return (insn & 0xfc0003e0) | (immLo << 10) | immHi;171}172 173static uint32_t setD10k16(uint32_t insn, uint32_t imm) {174  uint32_t immLo = extractBits(imm, 15, 0);175  uint32_t immHi = extractBits(imm, 25, 16);176  return (insn & 0xfc000000) | (immLo << 10) | immHi;177}178 179static uint32_t setJ20(uint32_t insn, uint32_t imm) {180  return (insn & 0xfe00001f) | (extractBits(imm, 19, 0) << 5);181}182 183static uint32_t setJ5(uint32_t insn, uint32_t imm) {184  return (insn & 0xfffffc1f) | (extractBits(imm, 4, 0) << 5);185}186 187static uint32_t setK12(uint32_t insn, uint32_t imm) {188  return (insn & 0xffc003ff) | (extractBits(imm, 11, 0) << 10);189}190 191static uint32_t setK16(uint32_t insn, uint32_t imm) {192  return (insn & 0xfc0003ff) | (extractBits(imm, 15, 0) << 10);193}194 195static bool isJirl(uint32_t insn) {196  return (insn & 0xfc000000) == JIRL;197}198 199static void handleUleb128(Ctx &ctx, uint8_t *loc, uint64_t val) {200  const uint32_t maxcount = 1 + 64 / 7;201  uint32_t count;202  const char *error = nullptr;203  uint64_t orig = decodeULEB128(loc, &count, nullptr, &error);204  if (count > maxcount || (count == maxcount && error))205    Err(ctx) << getErrorLoc(ctx, loc) << "extra space for uleb128";206  uint64_t mask = count < maxcount ? (1ULL << 7 * count) - 1 : -1ULL;207  encodeULEB128((orig + val) & mask, loc, count);208}209 210LoongArch::LoongArch(Ctx &ctx) : TargetInfo(ctx) {211  // The LoongArch ISA itself does not have a limit on page sizes. According to212  // the ISA manual, the PS (page size) field in MTLB entries and CSR.STLBPS is213  // 6 bits wide, meaning the maximum page size is 2^63 which is equivalent to214  // "unlimited".215  // However, practically the maximum usable page size is constrained by the216  // kernel implementation, and 64KiB is the biggest non-huge page size217  // supported by Linux as of v6.4. The most widespread page size in use,218  // though, is 16KiB.219  defaultCommonPageSize = 16384;220  defaultMaxPageSize = 65536;221  write32le(trapInstr.data(), BREAK); // break 0222 223  copyRel = R_LARCH_COPY;224  pltRel = R_LARCH_JUMP_SLOT;225  relativeRel = R_LARCH_RELATIVE;226  iRelativeRel = R_LARCH_IRELATIVE;227 228  if (ctx.arg.is64) {229    symbolicRel = R_LARCH_64;230    tlsModuleIndexRel = R_LARCH_TLS_DTPMOD64;231    tlsOffsetRel = R_LARCH_TLS_DTPREL64;232    tlsGotRel = R_LARCH_TLS_TPREL64;233    tlsDescRel = R_LARCH_TLS_DESC64;234  } else {235    symbolicRel = R_LARCH_32;236    tlsModuleIndexRel = R_LARCH_TLS_DTPMOD32;237    tlsOffsetRel = R_LARCH_TLS_DTPREL32;238    tlsGotRel = R_LARCH_TLS_TPREL32;239    tlsDescRel = R_LARCH_TLS_DESC32;240  }241 242  gotRel = symbolicRel;243 244  // .got.plt[0] = _dl_runtime_resolve, .got.plt[1] = link_map245  gotPltHeaderEntriesNum = 2;246 247  pltHeaderSize = 32;248  pltEntrySize = 16;249  ipltEntrySize = 16;250}251 252static uint32_t getEFlags(Ctx &ctx, const InputFile *f) {253  if (ctx.arg.is64)254    return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader().e_flags;255  return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader().e_flags;256}257 258static bool inputFileHasCode(const InputFile *f) {259  for (const auto *sec : f->getSections())260    if (sec && sec->flags & SHF_EXECINSTR)261      return true;262 263  return false;264}265 266uint32_t LoongArch::calcEFlags() const {267  // If there are only binary input files (from -b binary), use a268  // value of 0 for the ELF header flags.269  if (ctx.objectFiles.empty())270    return 0;271 272  uint32_t target = 0;273  const InputFile *targetFile;274  for (const InputFile *f : ctx.objectFiles) {275    // Do not enforce ABI compatibility if the input file does not contain code.276    // This is useful for allowing linkage with data-only object files produced277    // with tools like objcopy, that have zero e_flags.278    if (!inputFileHasCode(f))279      continue;280 281    // Take the first non-zero e_flags as the reference.282    uint32_t flags = getEFlags(ctx, f);283    if (target == 0 && flags != 0) {284      target = flags;285      targetFile = f;286    }287 288    if ((flags & EF_LOONGARCH_ABI_MODIFIER_MASK) !=289        (target & EF_LOONGARCH_ABI_MODIFIER_MASK))290      ErrAlways(ctx) << f291                     << ": cannot link object files with different ABI from "292                     << targetFile;293 294    // We cannot process psABI v1.x / object ABI v0 files (containing stack295    // relocations), unlike ld.bfd.296    //297    // Instead of blindly accepting every v0 object and only failing at298    // relocation processing time, just disallow interlink altogether. We299    // don't expect significant usage of object ABI v0 in the wild (the old300    // world may continue using object ABI v0 for a while, but as it's not301    // binary-compatible with the upstream i.e. new-world ecosystem, it's not302    // being considered here).303    //304    // There are briefly some new-world systems with object ABI v0 binaries too.305    // It is because these systems were built before the new ABI was finalized.306    // These are not supported either due to the extremely small number of them,307    // and the few impacted users are advised to simply rebuild world or308    // reinstall a recent system.309    if ((flags & EF_LOONGARCH_OBJABI_MASK) != EF_LOONGARCH_OBJABI_V1)310      ErrAlways(ctx) << f << ": unsupported object file ABI version";311  }312 313  return target;314}315 316int64_t LoongArch::getImplicitAddend(const uint8_t *buf, RelType type) const {317  switch (type) {318  default:319    InternalErr(ctx, buf) << "cannot read addend for relocation " << type;320    return 0;321  case R_LARCH_32:322  case R_LARCH_TLS_DTPMOD32:323  case R_LARCH_TLS_DTPREL32:324  case R_LARCH_TLS_TPREL32:325    return SignExtend64<32>(read32le(buf));326  case R_LARCH_64:327  case R_LARCH_TLS_DTPMOD64:328  case R_LARCH_TLS_DTPREL64:329  case R_LARCH_TLS_TPREL64:330    return read64le(buf);331  case R_LARCH_RELATIVE:332  case R_LARCH_IRELATIVE:333    return ctx.arg.is64 ? read64le(buf) : read32le(buf);334  case R_LARCH_NONE:335  case R_LARCH_JUMP_SLOT:336    // These relocations are defined as not having an implicit addend.337    return 0;338  case R_LARCH_TLS_DESC32:339    return read32le(buf + 4);340  case R_LARCH_TLS_DESC64:341    return read64le(buf + 8);342  }343}344 345void LoongArch::writeGotPlt(uint8_t *buf, const Symbol &s) const {346  if (ctx.arg.is64)347    write64le(buf, ctx.in.plt->getVA());348  else349    write32le(buf, ctx.in.plt->getVA());350}351 352void LoongArch::writeIgotPlt(uint8_t *buf, const Symbol &s) const {353  if (ctx.arg.writeAddends) {354    if (ctx.arg.is64)355      write64le(buf, s.getVA(ctx));356    else357      write32le(buf, s.getVA(ctx));358  }359}360 361void LoongArch::writePltHeader(uint8_t *buf) const {362  // The LoongArch PLT is currently structured just like that of RISCV.363  // Annoyingly, this means the PLT is still using `pcaddu12i` to perform364  // PC-relative addressing (because `pcaddu12i` is the same as RISCV `auipc`),365  // in contrast to the AArch64-like page-offset scheme with `pcalau12i` that366  // is used everywhere else involving PC-relative operations in the LoongArch367  // ELF psABI v2.00.368  //369  // The `pcrel_{hi20,lo12}` operators are illustrative only and not really370  // supported by LoongArch assemblers.371  //372  //   pcaddu12i $t2, %pcrel_hi20(.got.plt)373  //   sub.[wd]  $t1, $t1, $t3374  //   ld.[wd]   $t3, $t2, %pcrel_lo12(.got.plt)  ; t3 = _dl_runtime_resolve375  //   addi.[wd] $t1, $t1, -pltHeaderSize-12      ; t1 = &.plt[i] - &.plt[0]376  //   addi.[wd] $t0, $t2, %pcrel_lo12(.got.plt)377  //   srli.[wd] $t1, $t1, (is64?1:2)             ; t1 = &.got.plt[i] - &.got.plt[0]378  //   ld.[wd]   $t0, $t0, Wordsize               ; t0 = link_map379  //   jr        $t3380  uint32_t offset = ctx.in.gotPlt->getVA() - ctx.in.plt->getVA();381  uint32_t sub = ctx.arg.is64 ? SUB_D : SUB_W;382  uint32_t ld = ctx.arg.is64 ? LD_D : LD_W;383  uint32_t addi = ctx.arg.is64 ? ADDI_D : ADDI_W;384  uint32_t srli = ctx.arg.is64 ? SRLI_D : SRLI_W;385  write32le(buf + 0, insn(PCADDU12I, R_T2, hi20(offset), 0));386  write32le(buf + 4, insn(sub, R_T1, R_T1, R_T3));387  write32le(buf + 8, insn(ld, R_T3, R_T2, lo12(offset)));388  write32le(buf + 12,389            insn(addi, R_T1, R_T1, lo12(-ctx.target->pltHeaderSize - 12)));390  write32le(buf + 16, insn(addi, R_T0, R_T2, lo12(offset)));391  write32le(buf + 20, insn(srli, R_T1, R_T1, ctx.arg.is64 ? 1 : 2));392  write32le(buf + 24, insn(ld, R_T0, R_T0, ctx.arg.wordsize));393  write32le(buf + 28, insn(JIRL, R_ZERO, R_T3, 0));394}395 396void LoongArch::writePlt(uint8_t *buf, const Symbol &sym,397                     uint64_t pltEntryAddr) const {398  // See the comment in writePltHeader for reason why pcaddu12i is used instead399  // of the pcalau12i that's more commonly seen in the ELF psABI v2.0 days.400  //401  //   pcaddu12i $t3, %pcrel_hi20(f@.got.plt)402  //   ld.[wd]   $t3, $t3, %pcrel_lo12(f@.got.plt)403  //   jirl      $t1, $t3, 0404  //   nop405  uint32_t offset = sym.getGotPltVA(ctx) - pltEntryAddr;406  write32le(buf + 0, insn(PCADDU12I, R_T3, hi20(offset), 0));407  write32le(buf + 4,408            insn(ctx.arg.is64 ? LD_D : LD_W, R_T3, R_T3, lo12(offset)));409  write32le(buf + 8, insn(JIRL, R_T1, R_T3, 0));410  write32le(buf + 12, insn(ANDI, R_ZERO, R_ZERO, 0));411}412 413RelType LoongArch::getDynRel(RelType type) const {414  return type == ctx.target->symbolicRel ? type415                                         : static_cast<RelType>(R_LARCH_NONE);416}417 418RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s,419                              const uint8_t *loc) const {420  switch (type) {421  case R_LARCH_NONE:422  case R_LARCH_MARK_LA:423  case R_LARCH_MARK_PCREL:424    return R_NONE;425  case R_LARCH_32:426  case R_LARCH_64:427  case R_LARCH_ABS_HI20:428  case R_LARCH_ABS_LO12:429  case R_LARCH_ABS64_LO20:430  case R_LARCH_ABS64_HI12:431    return R_ABS;432  case R_LARCH_PCALA_LO12:433    // We could just R_ABS, but the JIRL instruction reuses the relocation type434    // for a different purpose. The questionable usage is part of glibc 2.37435    // libc_nonshared.a [1], which is linked into user programs, so we have to436    // work around it for a while, even if a new relocation type may be437    // introduced in the future [2].438    //439    // [1]: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=9f482b73f41a9a1bbfb173aad0733d1c824c788a440    // [2]: https://github.com/loongson/la-abi-specs/pull/3441    return isJirl(read32le(loc)) ? R_PLT : R_ABS;442  case R_LARCH_TLS_DTPREL32:443  case R_LARCH_TLS_DTPREL64:444    return R_DTPREL;445  case R_LARCH_TLS_TPREL32:446  case R_LARCH_TLS_TPREL64:447  case R_LARCH_TLS_LE_HI20:448  case R_LARCH_TLS_LE_HI20_R:449  case R_LARCH_TLS_LE_LO12:450  case R_LARCH_TLS_LE_LO12_R:451  case R_LARCH_TLS_LE64_LO20:452  case R_LARCH_TLS_LE64_HI12:453    return R_TPREL;454  case R_LARCH_ADD6:455  case R_LARCH_ADD8:456  case R_LARCH_ADD16:457  case R_LARCH_ADD32:458  case R_LARCH_ADD64:459  case R_LARCH_ADD_ULEB128:460  case R_LARCH_SUB6:461  case R_LARCH_SUB8:462  case R_LARCH_SUB16:463  case R_LARCH_SUB32:464  case R_LARCH_SUB64:465  case R_LARCH_SUB_ULEB128:466    // The LoongArch add/sub relocs behave like the RISCV counterparts; reuse467    // the RelExpr to avoid code duplication.468    return RE_RISCV_ADD;469  case R_LARCH_32_PCREL:470  case R_LARCH_64_PCREL:471  case R_LARCH_PCREL20_S2:472    return R_PC;473  case R_LARCH_B16:474  case R_LARCH_B21:475  case R_LARCH_B26:476  case R_LARCH_CALL36:477    return R_PLT_PC;478  case R_LARCH_GOT_PC_HI20:479  case R_LARCH_GOT64_PC_LO20:480  case R_LARCH_GOT64_PC_HI12:481  case R_LARCH_TLS_IE_PC_HI20:482  case R_LARCH_TLS_IE64_PC_LO20:483  case R_LARCH_TLS_IE64_PC_HI12:484    return RE_LOONGARCH_GOT_PAGE_PC;485  case R_LARCH_GOT_PC_LO12:486  case R_LARCH_TLS_IE_PC_LO12:487    return RE_LOONGARCH_GOT;488  case R_LARCH_TLS_LD_PC_HI20:489  case R_LARCH_TLS_GD_PC_HI20:490    return RE_LOONGARCH_TLSGD_PAGE_PC;491  case R_LARCH_PCALA_HI20:492    // Why not RE_LOONGARCH_PAGE_PC, majority of references don't go through493    // PLT anyway so why waste time checking only to get everything relaxed back494    // to it?495    //496    // This is again due to the R_LARCH_PCALA_LO12 on JIRL case, where we want497    // both the HI20 and LO12 to potentially refer to the PLT. But in reality498    // the HI20 reloc appears earlier, and the relocs don't contain enough499    // information to let us properly resolve semantics per symbol.500    // Unlike RISCV, our LO12 relocs *do not* point to their corresponding HI20501    // relocs, hence it is nearly impossible to 100% accurately determine each502    // HI20's "flavor" without taking big performance hits, in the presence of503    // edge cases (e.g. HI20 without pairing LO12; paired LO12 placed so far504    // apart that relationship is not certain anymore), and programmer mistakes505    // (e.g. as outlined in https://github.com/loongson/la-abi-specs/pull/3).506    //507    // Ideally we would scan in an extra pass for all LO12s on JIRL, then mark508    // every HI20 reloc referring to the same symbol differently; this is not509    // feasible with the current function signature of getRelExpr that doesn't510    // allow for such inter-pass state.511    //512    // So, unfortunately we have to again workaround this quirk the same way as513    // BFD: assuming every R_LARCH_PCALA_HI20 is potentially PLT-needing, only514    // relaxing back to RE_LOONGARCH_PAGE_PC if it's known not so at a later515    // stage.516    return RE_LOONGARCH_PLT_PAGE_PC;517  case R_LARCH_PCALA64_LO20:518  case R_LARCH_PCALA64_HI12:519    return RE_LOONGARCH_PAGE_PC;520  case R_LARCH_GOT_HI20:521  case R_LARCH_GOT_LO12:522  case R_LARCH_GOT64_LO20:523  case R_LARCH_GOT64_HI12:524  case R_LARCH_TLS_IE_HI20:525  case R_LARCH_TLS_IE_LO12:526  case R_LARCH_TLS_IE64_LO20:527  case R_LARCH_TLS_IE64_HI12:528    return R_GOT;529  case R_LARCH_TLS_LD_HI20:530    return R_TLSLD_GOT;531  case R_LARCH_TLS_GD_HI20:532    return R_TLSGD_GOT;533  case R_LARCH_TLS_LE_ADD_R:534  case R_LARCH_RELAX:535    return ctx.arg.relax ? R_RELAX_HINT : R_NONE;536  case R_LARCH_ALIGN:537    return R_RELAX_HINT;538  case R_LARCH_TLS_DESC_PC_HI20:539  case R_LARCH_TLS_DESC64_PC_LO20:540  case R_LARCH_TLS_DESC64_PC_HI12:541    return RE_LOONGARCH_TLSDESC_PAGE_PC;542  case R_LARCH_TLS_DESC_PC_LO12:543  case R_LARCH_TLS_DESC_LD:544  case R_LARCH_TLS_DESC_HI20:545  case R_LARCH_TLS_DESC_LO12:546  case R_LARCH_TLS_DESC64_LO20:547  case R_LARCH_TLS_DESC64_HI12:548    return R_TLSDESC;549  case R_LARCH_TLS_DESC_CALL:550    return R_TLSDESC_CALL;551  case R_LARCH_TLS_LD_PCREL20_S2:552    return R_TLSLD_PC;553  case R_LARCH_TLS_GD_PCREL20_S2:554    return R_TLSGD_PC;555  case R_LARCH_TLS_DESC_PCREL20_S2:556    return R_TLSDESC_PC;557 558  // Other known relocs that are explicitly unimplemented:559  //560  // - psABI v1 relocs that need a stateful stack machine to work, and not561  //   required when implementing psABI v2;562  // - relocs that are not used anywhere (R_LARCH_{ADD,SUB}_24 [1], and the563  //   two GNU vtable-related relocs).564  //565  // [1]: https://web.archive.org/web/20230709064026/https://github.com/loongson/LoongArch-Documentation/issues/51566  default:567    Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v568             << ") against symbol " << &s;569    return R_NONE;570  }571}572 573bool LoongArch::usesOnlyLowPageBits(RelType type) const {574  switch (type) {575  default:576    return false;577  case R_LARCH_PCALA_LO12:578  case R_LARCH_GOT_LO12:579  case R_LARCH_GOT_PC_LO12:580  case R_LARCH_TLS_IE_PC_LO12:581  case R_LARCH_TLS_DESC_LO12:582  case R_LARCH_TLS_DESC_PC_LO12:583    return true;584  }585}586 587void LoongArch::relocate(uint8_t *loc, const Relocation &rel,588                         uint64_t val) const {589  switch (rel.type) {590  case R_LARCH_32_PCREL:591    checkInt(ctx, loc, val, 32, rel);592    [[fallthrough]];593  case R_LARCH_32:594  case R_LARCH_TLS_DTPREL32:595    write32le(loc, val);596    return;597  case R_LARCH_64:598  case R_LARCH_TLS_DTPREL64:599  case R_LARCH_64_PCREL:600    write64le(loc, val);601    return;602 603  // Relocs intended for `pcaddi`.604  case R_LARCH_PCREL20_S2:605  case R_LARCH_TLS_LD_PCREL20_S2:606  case R_LARCH_TLS_GD_PCREL20_S2:607  case R_LARCH_TLS_DESC_PCREL20_S2:608    checkInt(ctx, loc, val, 22, rel);609    checkAlignment(ctx, loc, val, 4, rel);610    write32le(loc, setJ20(read32le(loc), val >> 2));611    return;612 613  case R_LARCH_B16:614    checkInt(ctx, loc, val, 18, rel);615    checkAlignment(ctx, loc, val, 4, rel);616    write32le(loc, setK16(read32le(loc), val >> 2));617    return;618 619  case R_LARCH_B21:620    checkInt(ctx, loc, val, 23, rel);621    checkAlignment(ctx, loc, val, 4, rel);622    write32le(loc, setD5k16(read32le(loc), val >> 2));623    return;624 625  case R_LARCH_B26:626    checkInt(ctx, loc, val, 28, rel);627    checkAlignment(ctx, loc, val, 4, rel);628    write32le(loc, setD10k16(read32le(loc), val >> 2));629    return;630 631  case R_LARCH_CALL36: {632    // This relocation is designed for adjacent pcaddu18i+jirl pairs that633    // are patched in one time. Because of sign extension of these insns'634    // immediate fields, the relocation range is [-128G - 0x20000, +128G -635    // 0x20000) (of course must be 4-byte aligned).636    if (((int64_t)val + 0x20000) != llvm::SignExtend64(val + 0x20000, 38))637      reportRangeError(ctx, loc, rel, Twine(val), llvm::minIntN(38) - 0x20000,638                       llvm::maxIntN(38) - 0x20000);639    checkAlignment(ctx, loc, val, 4, rel);640    // Since jirl performs sign extension on the offset immediate, adds (1<<17)641    // to original val to get the correct hi20.642    uint32_t hi20 = extractBits(val + (1 << 17), 37, 18);643    // Despite the name, the lower part is actually 18 bits with 4-byte aligned.644    uint32_t lo16 = extractBits(val, 17, 2);645    write32le(loc, setJ20(read32le(loc), hi20));646    write32le(loc + 4, setK16(read32le(loc + 4), lo16));647    return;648  }649 650  // Relocs intended for `addi`, `ld` or `st`.651  case R_LARCH_PCALA_LO12:652    // We have to again inspect the insn word to handle the R_LARCH_PCALA_LO12653    // on JIRL case: firstly JIRL wants its immediate's 2 lowest zeroes654    // removed by us (in contrast to regular R_LARCH_PCALA_LO12), secondly655    // its immediate slot width is different too (16, not 12).656    // In this case, process like an R_LARCH_B16, but without overflow checking657    // and only taking the value's lowest 12 bits.658    if (isJirl(read32le(loc))) {659      checkAlignment(ctx, loc, val, 4, rel);660      val = SignExtend64<12>(val);661      write32le(loc, setK16(read32le(loc), val >> 2));662      return;663    }664    [[fallthrough]];665  case R_LARCH_ABS_LO12:666  case R_LARCH_GOT_PC_LO12:667  case R_LARCH_GOT_LO12:668  case R_LARCH_TLS_LE_LO12:669  case R_LARCH_TLS_IE_PC_LO12:670  case R_LARCH_TLS_IE_LO12:671  case R_LARCH_TLS_LE_LO12_R:672  case R_LARCH_TLS_DESC_PC_LO12:673  case R_LARCH_TLS_DESC_LO12:674    write32le(loc, setK12(read32le(loc), extractBits(val, 11, 0)));675    return;676 677  // Relocs intended for `lu12i.w` or `pcalau12i`.678  case R_LARCH_ABS_HI20:679  case R_LARCH_PCALA_HI20:680  case R_LARCH_GOT_PC_HI20:681  case R_LARCH_GOT_HI20:682  case R_LARCH_TLS_LE_HI20:683  case R_LARCH_TLS_IE_PC_HI20:684  case R_LARCH_TLS_IE_HI20:685  case R_LARCH_TLS_LD_PC_HI20:686  case R_LARCH_TLS_LD_HI20:687  case R_LARCH_TLS_GD_PC_HI20:688  case R_LARCH_TLS_GD_HI20:689  case R_LARCH_TLS_DESC_PC_HI20:690  case R_LARCH_TLS_DESC_HI20:691    write32le(loc, setJ20(read32le(loc), extractBits(val, 31, 12)));692    return;693  case R_LARCH_TLS_LE_HI20_R:694    write32le(loc, setJ20(read32le(loc), extractBits(val + 0x800, 31, 12)));695    return;696 697  // Relocs intended for `lu32i.d`.698  case R_LARCH_ABS64_LO20:699  case R_LARCH_PCALA64_LO20:700  case R_LARCH_GOT64_PC_LO20:701  case R_LARCH_GOT64_LO20:702  case R_LARCH_TLS_LE64_LO20:703  case R_LARCH_TLS_IE64_PC_LO20:704  case R_LARCH_TLS_IE64_LO20:705  case R_LARCH_TLS_DESC64_PC_LO20:706  case R_LARCH_TLS_DESC64_LO20:707    write32le(loc, setJ20(read32le(loc), extractBits(val, 51, 32)));708    return;709 710  // Relocs intended for `lu52i.d`.711  case R_LARCH_ABS64_HI12:712  case R_LARCH_PCALA64_HI12:713  case R_LARCH_GOT64_PC_HI12:714  case R_LARCH_GOT64_HI12:715  case R_LARCH_TLS_LE64_HI12:716  case R_LARCH_TLS_IE64_PC_HI12:717  case R_LARCH_TLS_IE64_HI12:718  case R_LARCH_TLS_DESC64_PC_HI12:719  case R_LARCH_TLS_DESC64_HI12:720    write32le(loc, setK12(read32le(loc), extractBits(val, 63, 52)));721    return;722 723  case R_LARCH_ADD6:724    *loc = (*loc & 0xc0) | ((*loc + val) & 0x3f);725    return;726  case R_LARCH_ADD8:727    *loc += val;728    return;729  case R_LARCH_ADD16:730    write16le(loc, read16le(loc) + val);731    return;732  case R_LARCH_ADD32:733    write32le(loc, read32le(loc) + val);734    return;735  case R_LARCH_ADD64:736    write64le(loc, read64le(loc) + val);737    return;738  case R_LARCH_ADD_ULEB128:739    handleUleb128(ctx, loc, val);740    return;741  case R_LARCH_SUB6:742    *loc = (*loc & 0xc0) | ((*loc - val) & 0x3f);743    return;744  case R_LARCH_SUB8:745    *loc -= val;746    return;747  case R_LARCH_SUB16:748    write16le(loc, read16le(loc) - val);749    return;750  case R_LARCH_SUB32:751    write32le(loc, read32le(loc) - val);752    return;753  case R_LARCH_SUB64:754    write64le(loc, read64le(loc) - val);755    return;756  case R_LARCH_SUB_ULEB128:757    handleUleb128(ctx, loc, -val);758    return;759 760  case R_LARCH_MARK_LA:761  case R_LARCH_MARK_PCREL:762    // no-op763    return;764 765  case R_LARCH_TLS_LE_ADD_R:766  case R_LARCH_RELAX:767    return; // Ignored (for now)768 769  case R_LARCH_TLS_DESC_LD:770    return; // nothing to do.771  case R_LARCH_TLS_DESC32:772    write32le(loc + 4, val);773    return;774  case R_LARCH_TLS_DESC64:775    write64le(loc + 8, val);776    return;777 778  default:779    llvm_unreachable("unknown relocation");780  }781}782 783// If the section alignment is > 4, advance `dot` to insert NOPs and synthesize784// an ALIGN relocation. Otherwise, return false to use default handling.785template <class ELFT, class RelTy>786bool LoongArch::synthesizeAlignForInput(uint64_t &dot, InputSection *sec,787                                        Relocs<RelTy> rels) {788  if (!baseSec) {789    // Record the first input section with RELAX relocations. We will synthesize790    // ALIGN relocations here.791    for (auto rel : rels) {792      if (rel.getType(false) == R_LARCH_RELAX) {793        baseSec = sec;794        break;795      }796    }797  } else if (sec->addralign > 4) {798    // If the alignment is > 4 and the section does not start with an ALIGN799    // relocation, synthesize one.800    bool hasAlignRel = llvm::any_of(rels, [](const RelTy &rel) {801      return rel.r_offset == 0 && rel.getType(false) == R_LARCH_ALIGN;802    });803    if (!hasAlignRel) {804      synthesizedAligns.emplace_back(dot - baseSec->getVA(),805                                     sec->addralign - 4);806      dot += sec->addralign - 4;807      return true;808    }809  }810  return false;811}812 813// Finalize the relocation section by appending synthesized ALIGN relocations814// after processing all input sections.815template <class ELFT, class RelTy>816void LoongArch::finalizeSynthesizeAligns(uint64_t &dot, InputSection *sec,817                                         Relocs<RelTy> rels) {818  auto *f = cast<ObjFile<ELFT>>(baseSec->file);819  auto shdr = f->template getELFShdrs<ELFT>()[baseSec->relSecIdx];820  // Create a copy of InputSection.821  sec = make<InputSection>(*f, shdr, baseSec->name);822  auto *baseRelSec = cast<InputSection>(f->getSections()[baseSec->relSecIdx]);823  *sec = *baseRelSec;824  baseSec = nullptr;825 826  // Allocate buffer for original and synthesized relocations in RELA format.827  // If CREL is used, OutputSection::finalizeNonAllocCrel will convert RELA to828  // CREL.829  auto newSize = rels.size() + synthesizedAligns.size();830  auto *relas = makeThreadLocalN<typename ELFT::Rela>(newSize);831  sec->size = newSize * sizeof(typename ELFT::Rela);832  sec->content_ = reinterpret_cast<uint8_t *>(relas);833  sec->type = SHT_RELA;834  // Copy original relocations to the new buffer, potentially converting CREL to835  // RELA.836  for (auto [i, r] : llvm::enumerate(rels)) {837    relas[i].r_offset = r.r_offset;838    relas[i].setSymbolAndType(r.getSymbol(0), r.getType(0), false);839    if constexpr (RelTy::HasAddend)840      relas[i].r_addend = r.r_addend;841  }842  // Append synthesized ALIGN relocations to the buffer.843  for (auto [i, r] : llvm::enumerate(synthesizedAligns)) {844    auto &rela = relas[rels.size() + i];845    rela.r_offset = r.first;846    rela.setSymbolAndType(0, R_LARCH_ALIGN, false);847    rela.r_addend = r.second;848  }849  synthesizedAligns.clear();850  // Replace the old relocation section with the new one in the output section.851  // addOrphanSections ensures that the output relocation section is processed852  // after osec.853  for (SectionCommand *cmd : sec->getParent()->commands) {854    auto *isd = dyn_cast<InputSectionDescription>(cmd);855    if (!isd)856      continue;857    for (auto *&isec : isd->sections)858      if (isec == baseRelSec)859        isec = sec;860  }861}862 863template <class ELFT>864bool LoongArch::synthesizeAlignAux(uint64_t &dot, InputSection *sec) {865  bool ret = false;866  if (sec) {867    invokeOnRelocs(*sec, ret = synthesizeAlignForInput<ELFT>, dot, sec);868  } else if (baseSec) {869    invokeOnRelocs(*baseSec, finalizeSynthesizeAligns<ELFT>, dot, sec);870  }871  return ret;872}873 874// Without linker relaxation enabled for a particular relocatable file or875// section, the assembler will not generate R_LARCH_ALIGN relocations for876// alignment directives. This becomes problematic in a two-stage linking877// process: ld -r a.o b.o -o ab.o; ld ab.o -o ab. This function synthesizes an878// R_LARCH_ALIGN relocation at section start when needed.879//880// When called with an input section (`sec` is not null): If the section881// alignment is > 4, advance `dot` to insert NOPs and synthesize an ALIGN882// relocation.883//884// When called after all input sections are processed (`sec` is null): The885// output relocation section is updated with all the newly synthesized ALIGN886// relocations.887bool LoongArch::synthesizeAlign(uint64_t &dot, InputSection *sec) {888  assert(ctx.arg.relocatable);889  if (ctx.arg.is64)890    return synthesizeAlignAux<ELF64LE>(dot, sec);891  return synthesizeAlignAux<ELF32LE>(dot, sec);892}893 894static bool relaxable(ArrayRef<Relocation> relocs, size_t i) {895  return i + 1 < relocs.size() && relocs[i + 1].type == R_LARCH_RELAX;896}897 898static bool isPairRelaxable(ArrayRef<Relocation> relocs, size_t i) {899  return relaxable(relocs, i) && relaxable(relocs, i + 2) &&900         relocs[i].offset + 4 == relocs[i + 2].offset;901}902 903// Relax code sequence.904// From:905//   pcalau12i     $a0, %pc_hi20(sym) | %ld_pc_hi20(sym)  | %gd_pc_hi20(sym)906//                    | %desc_pc_hi20(sym)907//   addi.w/d $a0, $a0, %pc_lo12(sym) | %got_pc_lo12(sym) | %got_pc_lo12(sym)908//                    | %desc_pc_lo12(sym)909// To:910//   pcaddi        $a0, %pc_lo12(sym) | %got_pc_lo12(sym) | %got_pc_lo12(sym)911//                    | %desc_pcrel_20(sym)912//913// From:914//   pcalau12i $a0, %got_pc_hi20(sym_got)915//   ld.w/d $a0, $a0, %got_pc_lo12(sym_got)916// To:917//   pcaddi $a0, %got_pc_hi20(sym_got)918static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,919                            uint64_t loc, Relocation &rHi20, Relocation &rLo12,920                            uint32_t &remove) {921  // check if the relocations are relaxable sequences.922  if (!((rHi20.type == R_LARCH_PCALA_HI20 &&923         rLo12.type == R_LARCH_PCALA_LO12) ||924        (rHi20.type == R_LARCH_GOT_PC_HI20 &&925         rLo12.type == R_LARCH_GOT_PC_LO12) ||926        (rHi20.type == R_LARCH_TLS_GD_PC_HI20 &&927         rLo12.type == R_LARCH_GOT_PC_LO12) ||928        (rHi20.type == R_LARCH_TLS_LD_PC_HI20 &&929         rLo12.type == R_LARCH_GOT_PC_LO12) ||930        (rHi20.type == R_LARCH_TLS_DESC_PC_HI20 &&931         rLo12.type == R_LARCH_TLS_DESC_PC_LO12)))932    return;933 934  // GOT references to absolute symbols can't be relaxed to use pcaddi in935  // position-independent code, because these instructions produce a relative936  // address.937  // Meanwhile skip undefined, preemptible and STT_GNU_IFUNC symbols, because938  // these symbols may be resolve in runtime.939  // Moreover, relaxation can only occur if the addends of both relocations are940  // zero for GOT references.941  if (rHi20.type == R_LARCH_GOT_PC_HI20 &&942      (!rHi20.sym || rHi20.sym != rLo12.sym || !rHi20.sym->isDefined() ||943       rHi20.sym->isPreemptible || rHi20.sym->isGnuIFunc() ||944       (ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section) ||945       rHi20.addend != 0 || rLo12.addend != 0))946    return;947 948  uint64_t dest = 0;949  if (rHi20.expr == RE_LOONGARCH_PLT_PAGE_PC)950    dest = rHi20.sym->getPltVA(ctx);951  else if (rHi20.expr == RE_LOONGARCH_PAGE_PC ||952           rHi20.expr == RE_LOONGARCH_GOT_PAGE_PC)953    dest = rHi20.sym->getVA(ctx);954  else if (rHi20.expr == RE_LOONGARCH_TLSGD_PAGE_PC)955    dest = ctx.in.got->getGlobalDynAddr(*rHi20.sym);956  else if (rHi20.expr == RE_LOONGARCH_TLSDESC_PAGE_PC)957    dest = ctx.in.got->getTlsDescAddr(*rHi20.sym);958  else {959    Err(ctx) << getErrorLoc(ctx, (const uint8_t *)loc) << "unknown expr ("960             << rHi20.expr << ") against symbol " << rHi20.sym961             << "in relaxPCHi20Lo12";962    return;963  }964  dest += rHi20.addend;965 966  const int64_t displace = dest - loc;967  // Check if the displace aligns 4 bytes or exceeds the range of pcaddi.968  if ((displace & 0x3) != 0 || !isInt<22>(displace))969    return;970 971  // Note: If we can ensure that the .o files generated by LLVM only contain972  // relaxable instruction sequences with R_LARCH_RELAX, then we do not need to973  // decode instructions. The relaxable instruction sequences imply the974  // following constraints:975  // * For relocation pairs related to got_pc, the opcodes of instructions976  // must be pcalau12i + ld.w/d. In other cases, the opcodes must be pcalau12i +977  // addi.w/d.978  // * The destination register of pcalau12i is guaranteed to be used only by979  // the immediately following instruction.980  const uint32_t currInsn = read32le(sec.content().data() + rHi20.offset);981  const uint32_t nextInsn = read32le(sec.content().data() + rLo12.offset);982  // Check if use the same register.983  if (getD5(currInsn) != getJ5(nextInsn) || getJ5(nextInsn) != getD5(nextInsn))984    return;985 986  sec.relaxAux->relocTypes[i] = R_LARCH_RELAX;987  if (rHi20.type == R_LARCH_TLS_GD_PC_HI20)988    sec.relaxAux->relocTypes[i + 2] = R_LARCH_TLS_GD_PCREL20_S2;989  else if (rHi20.type == R_LARCH_TLS_LD_PC_HI20)990    sec.relaxAux->relocTypes[i + 2] = R_LARCH_TLS_LD_PCREL20_S2;991  else if (rHi20.type == R_LARCH_TLS_DESC_PC_HI20)992    sec.relaxAux->relocTypes[i + 2] = R_LARCH_TLS_DESC_PCREL20_S2;993  else994    sec.relaxAux->relocTypes[i + 2] = R_LARCH_PCREL20_S2;995  sec.relaxAux->writes.push_back(insn(PCADDI, getD5(nextInsn), 0, 0));996  remove = 4;997}998 999// Relax code sequence.1000// From:1001//   pcaddu18i $ra, %call36(foo)1002//   jirl $ra, $ra, 01003// To:1004//   b/bl foo1005static void relaxCall36(Ctx &ctx, const InputSection &sec, size_t i,1006                        uint64_t loc, Relocation &r, uint32_t &remove) {1007  const uint64_t dest =1008      (r.expr == R_PLT_PC ? r.sym->getPltVA(ctx) : r.sym->getVA(ctx)) +1009      r.addend;1010 1011  const int64_t displace = dest - loc;1012  // Check if the displace aligns 4 bytes or exceeds the range of b[l].1013  if ((displace & 0x3) != 0 || !isInt<28>(displace))1014    return;1015 1016  const uint32_t nextInsn = read32le(sec.content().data() + r.offset + 4);1017  if (getD5(nextInsn) == R_RA) {1018    // convert jirl to bl1019    sec.relaxAux->relocTypes[i] = R_LARCH_B26;1020    sec.relaxAux->writes.push_back(insn(BL, 0, 0, 0));1021    remove = 4;1022  } else if (getD5(nextInsn) == R_ZERO) {1023    // convert jirl to b1024    sec.relaxAux->relocTypes[i] = R_LARCH_B26;1025    sec.relaxAux->writes.push_back(insn(B, 0, 0, 0));1026    remove = 4;1027  }1028}1029 1030// Relax code sequence.1031// From:1032//   lu12i.w $rd, %le_hi20_r(sym)1033//   add.w/d $rd, $rd, $tp, %le_add_r(sym)1034//   addi/ld/st.w/d $rd, $rd, %le_lo12_r(sym)1035// To:1036//   addi/ld/st.w/d $rd, $tp, %le_lo12_r(sym)1037static void relaxTlsLe(Ctx &ctx, const InputSection &sec, size_t i,1038                       uint64_t loc, Relocation &r, uint32_t &remove) {1039  uint64_t val = r.sym->getVA(ctx, r.addend);1040  // Check if the val exceeds the range of addi/ld/st.1041  if (!isInt<12>(val))1042    return;1043  uint32_t currInsn = read32le(sec.content().data() + r.offset);1044  switch (r.type) {1045  case R_LARCH_TLS_LE_HI20_R:1046  case R_LARCH_TLS_LE_ADD_R:1047    sec.relaxAux->relocTypes[i] = R_LARCH_RELAX;1048    remove = 4;1049    break;1050  case R_LARCH_TLS_LE_LO12_R:1051    sec.relaxAux->writes.push_back(setJ5(currInsn, R_TP));1052    sec.relaxAux->relocTypes[i] = R_LARCH_TLS_LE_LO12_R;1053    break;1054  }1055}1056 1057static bool relax(Ctx &ctx, InputSection &sec) {1058  const uint64_t secAddr = sec.getVA();1059  const MutableArrayRef<Relocation> relocs = sec.relocs();1060  auto &aux = *sec.relaxAux;1061  bool changed = false;1062  ArrayRef<SymbolAnchor> sa = ArrayRef(aux.anchors);1063  uint64_t delta = 0;1064 1065  std::fill_n(aux.relocTypes.get(), relocs.size(), R_LARCH_NONE);1066  aux.writes.clear();1067  for (auto [i, r] : llvm::enumerate(relocs)) {1068    const uint64_t loc = secAddr + r.offset - delta;1069    uint32_t &cur = aux.relocDeltas[i], remove = 0;1070    switch (r.type) {1071    case R_LARCH_ALIGN: {1072      const uint64_t addend =1073          r.sym->isUndefined() ? Log2_64(r.addend) + 1 : r.addend;1074      const uint64_t allBytes = (1ULL << (addend & 0xff)) - 4;1075      const uint64_t align = 1ULL << (addend & 0xff);1076      const uint64_t maxBytes = addend >> 8;1077      const uint64_t off = loc & (align - 1);1078      const uint64_t curBytes = off == 0 ? 0 : align - off;1079      // All bytes beyond the alignment boundary should be removed.1080      // If emit bytes more than max bytes to emit, remove all.1081      if (maxBytes != 0 && curBytes > maxBytes)1082        remove = allBytes;1083      else1084        remove = allBytes - curBytes;1085      // If we can't satisfy this alignment, we've found a bad input.1086      if (LLVM_UNLIKELY(static_cast<int32_t>(remove) < 0)) {1087        Err(ctx) << getErrorLoc(ctx, (const uint8_t *)loc)1088                 << "insufficient padding bytes for " << r.type << ": "1089                 << allBytes << " bytes available for "1090                 << "requested alignment of " << align << " bytes";1091        remove = 0;1092      }1093      break;1094    }1095    case R_LARCH_PCALA_HI20:1096    case R_LARCH_GOT_PC_HI20:1097    case R_LARCH_TLS_GD_PC_HI20:1098    case R_LARCH_TLS_LD_PC_HI20:1099      // The overflow check for i+2 will be carried out in isPairRelaxable.1100      if (isPairRelaxable(relocs, i))1101        relaxPCHi20Lo12(ctx, sec, i, loc, r, relocs[i + 2], remove);1102      break;1103    case R_LARCH_TLS_DESC_PC_HI20:1104      if (r.expr == RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC ||1105          r.expr == R_RELAX_TLS_GD_TO_LE) {1106        if (relaxable(relocs, i))1107          remove = 4;1108      } else if (isPairRelaxable(relocs, i))1109        relaxPCHi20Lo12(ctx, sec, i, loc, r, relocs[i + 2], remove);1110      break;1111    case R_LARCH_CALL36:1112      if (relaxable(relocs, i))1113        relaxCall36(ctx, sec, i, loc, r, remove);1114      break;1115    case R_LARCH_TLS_LE_HI20_R:1116    case R_LARCH_TLS_LE_ADD_R:1117    case R_LARCH_TLS_LE_LO12_R:1118      if (relaxable(relocs, i))1119        relaxTlsLe(ctx, sec, i, loc, r, remove);1120      break;1121    case R_LARCH_TLS_IE_PC_HI20:1122      if (relaxable(relocs, i) && r.expr == R_RELAX_TLS_IE_TO_LE &&1123          isUInt<12>(r.sym->getVA(ctx, r.addend)))1124        remove = 4;1125      break;1126    case R_LARCH_TLS_DESC_PC_LO12:1127      if (relaxable(relocs, i) &&1128          (r.expr == RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC ||1129           r.expr == R_RELAX_TLS_GD_TO_LE))1130        remove = 4;1131      break;1132    case R_LARCH_TLS_DESC_LD:1133      if (relaxable(relocs, i) && r.expr == R_RELAX_TLS_GD_TO_LE &&1134          isUInt<12>(r.sym->getVA(ctx, r.addend)))1135        remove = 4;1136      break;1137    }1138 1139    // For all anchors whose offsets are <= r.offset, they are preceded by1140    // the previous relocation whose `relocDeltas` value equals `delta`.1141    // Decrease their st_value and update their st_size.1142    for (; sa.size() && sa[0].offset <= r.offset; sa = sa.slice(1)) {1143      if (sa[0].end)1144        sa[0].d->size = sa[0].offset - delta - sa[0].d->value;1145      else1146        sa[0].d->value = sa[0].offset - delta;1147    }1148    delta += remove;1149    if (delta != cur) {1150      cur = delta;1151      changed = true;1152    }1153  }1154 1155  for (const SymbolAnchor &a : sa) {1156    if (a.end)1157      a.d->size = a.offset - delta - a.d->value;1158    else1159      a.d->value = a.offset - delta;1160  }1161  // Inform assignAddresses that the size has changed.1162  if (!isUInt<32>(delta))1163    Fatal(ctx) << "section size decrease is too large: " << delta;1164  sec.bytesDropped = delta;1165  return changed;1166}1167 1168// Convert TLS IE to LE in the normal or medium code model.1169// Original code sequence:1170//  * pcalau12i $a0, %ie_pc_hi20(sym)1171//  * ld.d      $a0, $a0, %ie_pc_lo12(sym)1172//1173// The code sequence converted is as follows:1174//  * lu12i.w   $a0, %le_hi20(sym)      # le_hi20 != 0, otherwise NOP1175//  * ori       $a0, src, %le_lo12(sym) # le_hi20 != 0, src = $a0,1176//                                      # otherwise,    src = $zero1177//1178// When relaxation enables, redundant NOPs can be removed.1179static void tlsIeToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {1180  assert(isInt<32>(val) &&1181         "val exceeds the range of medium code model in tlsIeToLe");1182 1183  bool isUInt12 = isUInt<12>(val);1184  const uint32_t currInsn = read32le(loc);1185  switch (rel.type) {1186  case R_LARCH_TLS_IE_PC_HI20:1187    if (isUInt12)1188      write32le(loc, insn(ANDI, R_ZERO, R_ZERO, 0)); // nop1189    else1190      write32le(loc, insn(LU12I_W, getD5(currInsn), extractBits(val, 31, 12),1191                          0)); // lu12i.w $a0, %le_hi201192    break;1193  case R_LARCH_TLS_IE_PC_LO12:1194    if (isUInt12)1195      write32le(loc, insn(ORI, getD5(currInsn), R_ZERO,1196                          val)); // ori $a0, $zero, %le_lo121197    else1198      write32le(loc, insn(ORI, getD5(currInsn), getJ5(currInsn),1199                          lo12(val))); // ori $a0, $a0, %le_lo121200    break;1201  }1202}1203 1204// Convert TLSDESC GD/LD to IE.1205// In normal or medium code model, there are two forms of code sequences:1206//  * pcalau12i  $a0, %desc_pc_hi20(sym_desc)1207//  * addi.d     $a0, $a0, %desc_pc_lo12(sym_desc)1208//  * ld.d       $ra, $a0, %desc_ld(sym_desc)1209//  * jirl       $ra, $ra, %desc_call(sym_desc)1210//  ------1211//  * pcaddi $a0, %desc_pcrel_20(a)1212//  * load $ra, $a0, %desc_ld(a)1213//  * jirl $ra, $ra, %desc_call(a)1214//1215// The code sequence obtained is as follows:1216//  * pcalau12i $a0, %ie_pc_hi20(sym_ie)1217//  * ld.[wd]   $a0, $a0, %ie_pc_lo12(sym_ie)1218//1219// Simplicity, whether tlsdescToIe or tlsdescToLe, we always tend to convert the1220// preceding instructions to NOPs, due to both forms of code sequence1221// (corresponding to relocation combinations:1222// R_LARCH_TLS_DESC_PC_HI20+R_LARCH_TLS_DESC_PC_LO12 and1223// R_LARCH_TLS_DESC_PCREL20_S2) have same process.1224//1225// When relaxation enables, redundant NOPs can be removed.1226void LoongArch::tlsdescToIe(uint8_t *loc, const Relocation &rel,1227                            uint64_t val) const {1228  switch (rel.type) {1229  case R_LARCH_TLS_DESC_PC_HI20:1230  case R_LARCH_TLS_DESC_PC_LO12:1231  case R_LARCH_TLS_DESC_PCREL20_S2:1232    write32le(loc, insn(ANDI, R_ZERO, R_ZERO, 0)); // nop1233    break;1234  case R_LARCH_TLS_DESC_LD:1235    write32le(loc, insn(PCALAU12I, R_A0, 0, 0)); // pcalau12i $a0, %ie_pc_hi201236    relocateNoSym(loc, R_LARCH_TLS_IE_PC_HI20, val);1237    break;1238  case R_LARCH_TLS_DESC_CALL:1239    write32le(loc, insn(ctx.arg.is64 ? LD_D : LD_W, R_A0, R_A0,1240                        0)); // ld.[wd] $a0, $a0, %ie_pc_lo121241    relocateNoSym(loc, R_LARCH_TLS_IE_PC_LO12, val);1242    break;1243  default:1244    llvm_unreachable("unsupported relocation for TLSDESC to IE");1245  }1246}1247 1248// Convert TLSDESC GD/LD to LE.1249// The code sequence obtained in the normal or medium code model is as follows:1250//  * lu12i.w   $a0, %le_hi20(sym)      # le_hi20 != 0, otherwise NOP1251//  * ori       $a0, src, %le_lo12(sym) # le_hi20 != 0, src = $a0,1252//                                      # otherwise,    src = $zero1253// See the comment in tlsdescToIe for detailed information.1254void LoongArch::tlsdescToLe(uint8_t *loc, const Relocation &rel,1255                            uint64_t val) const {1256  assert(isInt<32>(val) &&1257         "val exceeds the range of medium code model in tlsdescToLe");1258 1259  bool isUInt12 = isUInt<12>(val);1260  switch (rel.type) {1261  case R_LARCH_TLS_DESC_PC_HI20:1262  case R_LARCH_TLS_DESC_PC_LO12:1263  case R_LARCH_TLS_DESC_PCREL20_S2:1264    write32le(loc, insn(ANDI, R_ZERO, R_ZERO, 0)); // nop1265    break;1266  case R_LARCH_TLS_DESC_LD:1267    if (isUInt12)1268      write32le(loc, insn(ANDI, R_ZERO, R_ZERO, 0)); // nop1269    else1270      write32le(loc, insn(LU12I_W, R_A0, extractBits(val, 31, 12),1271                          0)); // lu12i.w $a0, %le_hi201272    break;1273  case R_LARCH_TLS_DESC_CALL:1274    if (isUInt12)1275      write32le(loc, insn(ORI, R_A0, R_ZERO, val)); // ori $a0, $zero, %le_lo121276    else1277      write32le(loc,1278                insn(ORI, R_A0, R_A0, lo12(val))); // ori $a0, $a0, %le_lo121279    break;1280  default:1281    llvm_unreachable("unsupported relocation for TLSDESC to LE");1282  }1283}1284 1285// Try GOT indirection to PC relative optimization.1286// From:1287//  * pcalau12i $a0, %got_pc_hi20(sym_got)1288//  * ld.w/d    $a0, $a0, %got_pc_lo12(sym_got)1289// To:1290//  * pcalau12i $a0, %pc_hi20(sym)1291//  * addi.w/d  $a0, $a0, %pc_lo12(sym)1292//1293// Note: Althouth the optimization has been performed, the GOT entries still1294// exists, similarly to AArch64. Eliminating the entries will increase code1295// complexity.1296bool LoongArch::tryGotToPCRel(uint8_t *loc, const Relocation &rHi20,1297                              const Relocation &rLo12, uint64_t secAddr) const {1298  // Check if the relocations apply to consecutive instructions.1299  if (rHi20.offset + 4 != rLo12.offset)1300    return false;1301 1302  // Check if the relocations reference the same symbol and skip undefined,1303  // preemptible and STT_GNU_IFUNC symbols.1304  if (!rHi20.sym || rHi20.sym != rLo12.sym || !rHi20.sym->isDefined() ||1305      rHi20.sym->isPreemptible || rHi20.sym->isGnuIFunc())1306    return false;1307 1308  // GOT references to absolute symbols can't be relaxed to use PCALAU12I/ADDI1309  // in position-independent code because these instructions produce a relative1310  // address.1311  if ((ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section))1312    return false;1313 1314  // Check if the addends of the both relocations are zero.1315  if (rHi20.addend != 0 || rLo12.addend != 0)1316    return false;1317 1318  const uint32_t currInsn = read32le(loc);1319  const uint32_t nextInsn = read32le(loc + 4);1320  const uint32_t ldOpcode = ctx.arg.is64 ? LD_D : LD_W;1321  // Check if the first instruction is PCALAU12I and the second instruction is1322  // LD.1323  if ((currInsn & 0xfe000000) != PCALAU12I ||1324      (nextInsn & 0xffc00000) != ldOpcode)1325    return false;1326 1327  // Check if use the same register.1328  if (getD5(currInsn) != getJ5(nextInsn) || getJ5(nextInsn) != getD5(nextInsn))1329    return false;1330 1331  Symbol &sym = *rHi20.sym;1332  uint64_t symLocal = sym.getVA(ctx);1333  const int64_t displace = symLocal - getLoongArchPage(secAddr + rHi20.offset);1334  // Check if the symbol address is in1335  // [(PC & ~0xfff) - 2GiB - 0x800, (PC & ~0xfff) + 2GiB - 0x800).1336  const int64_t underflow = -0x80000000LL - 0x800;1337  const int64_t overflow = 0x80000000LL - 0x800;1338  if (!(displace >= underflow && displace < overflow))1339    return false;1340 1341  Relocation newRHi20 = {RE_LOONGARCH_PAGE_PC, R_LARCH_PCALA_HI20, rHi20.offset,1342                         rHi20.addend, &sym};1343  Relocation newRLo12 = {R_ABS, R_LARCH_PCALA_LO12, rLo12.offset, rLo12.addend,1344                         &sym};1345  uint64_t pageDelta =1346      getLoongArchPageDelta(symLocal, secAddr + rHi20.offset, rHi20.type);1347  // pcalau12i $a0, %pc_hi201348  write32le(loc, insn(PCALAU12I, getD5(currInsn), 0, 0));1349  relocate(loc, newRHi20, pageDelta);1350  // addi.w/d $a0, $a0, %pc_lo121351  write32le(loc + 4, insn(ctx.arg.is64 ? ADDI_D : ADDI_W, getD5(nextInsn),1352                          getJ5(nextInsn), 0));1353  relocate(loc + 4, newRLo12, SignExtend64(symLocal, 64));1354  return true;1355}1356 1357// During TLSDESC GD_TO_IE, the converted code sequence always includes an1358// instruction related to the Lo12 relocation (ld.[wd]). To obtain correct val1359// in `getRelocTargetVA`, expr of this instruction should be adjusted to1360// R_RELAX_TLS_GD_TO_IE_ABS, while expr of other instructions related to the1361// Hi20 relocation (pcalau12i) should be adjusted to1362// RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC. Specifically, in the normal or1363// medium code model, the instruction with relocation R_LARCH_TLS_DESC_CALL is1364// the candidate of Lo12 relocation.1365RelExpr LoongArch::adjustTlsExpr(RelType type, RelExpr expr) const {1366  if (expr == R_RELAX_TLS_GD_TO_IE) {1367    if (type != R_LARCH_TLS_DESC_CALL)1368      return RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC;1369    return R_RELAX_TLS_GD_TO_IE_ABS;1370  }1371  return expr;1372}1373 1374static bool pairForGotRels(ArrayRef<Relocation> relocs) {1375  // Check if R_LARCH_GOT_PC_HI20 and R_LARCH_GOT_PC_LO12 always appear in1376  // pairs.1377  size_t i = 0;1378  const size_t size = relocs.size();1379  for (; i != size; ++i) {1380    if (relocs[i].type == R_LARCH_GOT_PC_HI20) {1381      if (i + 1 < size && relocs[i + 1].type == R_LARCH_GOT_PC_LO12) {1382        ++i;1383        continue;1384      }1385      if (relaxable(relocs, i) && i + 2 < size &&1386          relocs[i + 2].type == R_LARCH_GOT_PC_LO12) {1387        i += 2;1388        continue;1389      }1390      break;1391    } else if (relocs[i].type == R_LARCH_GOT_PC_LO12) {1392      break;1393    }1394  }1395  return i == size;1396}1397 1398void LoongArch::relocateAlloc(InputSection &sec, uint8_t *buf) const {1399  const unsigned bits = ctx.arg.is64 ? 64 : 32;1400  uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;1401  bool isExtreme = false, isRelax = false;1402  const MutableArrayRef<Relocation> relocs = sec.relocs();1403  const bool isPairForGotRels = pairForGotRels(relocs);1404  for (size_t i = 0, size = relocs.size(); i != size; ++i) {1405    Relocation &rel = relocs[i];1406    uint8_t *loc = buf + rel.offset;1407    uint64_t val = SignExtend64(1408        sec.getRelocTargetVA(ctx, rel, secAddr + rel.offset), bits);1409 1410    switch (rel.expr) {1411    case R_RELAX_HINT:1412      continue;1413    case R_RELAX_TLS_IE_TO_LE:1414      if (rel.type == R_LARCH_TLS_IE_PC_HI20) {1415        // LoongArch does not support IE to LE optimization in the extreme code1416        // model. In this case, the relocs are as follows:1417        //1418        //  * i   -- R_LARCH_TLS_IE_PC_HI201419        //  * i+1 -- R_LARCH_TLS_IE_PC_LO121420        //  * i+2 -- R_LARCH_TLS_IE64_PC_LO201421        //  * i+3 -- R_LARCH_TLS_IE64_PC_HI121422        isExtreme =1423            i + 2 < size && relocs[i + 2].type == R_LARCH_TLS_IE64_PC_LO20;1424      }1425      if (isExtreme) {1426        rel.expr = getRelExpr(rel.type, *rel.sym, loc);1427        val = SignExtend64(sec.getRelocTargetVA(ctx, rel, secAddr + rel.offset),1428                           bits);1429        relocateNoSym(loc, rel.type, val);1430      } else {1431        isRelax = relaxable(relocs, i);1432        if (isRelax && rel.type == R_LARCH_TLS_IE_PC_HI20 && isUInt<12>(val))1433          continue;1434        tlsIeToLe(loc, rel, val);1435      }1436      continue;1437    case RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC:1438      if (rel.type == R_LARCH_TLS_DESC_PC_HI20) {1439        // LoongArch does not support TLSDESC GD/LD to LE/IE optimization in the1440        // extreme code model. In these cases, the relocs are as follows:1441        //1442        //  * i   -- R_LARCH_TLS_DESC_PC_HI201443        //  * i+1 -- R_LARCH_TLS_DESC_PC_LO121444        //  * i+2 -- R_LARCH_TLS_DESC64_PC_LO201445        //  * i+3 -- R_LARCH_TLS_DESC64_PC_HI121446        isExtreme =1447            i + 2 < size && relocs[i + 2].type == R_LARCH_TLS_DESC64_PC_LO20;1448      }1449      [[fallthrough]];1450    case R_RELAX_TLS_GD_TO_IE_ABS:1451      if (isExtreme) {1452        if (rel.type == R_LARCH_TLS_DESC_CALL)1453          continue;1454        rel.expr = getRelExpr(rel.type, *rel.sym, loc);1455        val = SignExtend64(sec.getRelocTargetVA(ctx, rel, secAddr + rel.offset),1456                           bits);1457        relocateNoSym(loc, rel.type, val);1458      } else {1459        isRelax = relaxable(relocs, i);1460        if (isRelax && (rel.type == R_LARCH_TLS_DESC_PC_HI20 ||1461                        rel.type == R_LARCH_TLS_DESC_PC_LO12))1462          continue;1463        tlsdescToIe(loc, rel, val);1464      }1465      continue;1466    case R_RELAX_TLS_GD_TO_LE:1467      if (rel.type == R_LARCH_TLS_DESC_PC_HI20) {1468        isExtreme =1469            i + 2 < size && relocs[i + 2].type == R_LARCH_TLS_DESC64_PC_LO20;1470      }1471      if (isExtreme) {1472        if (rel.type == R_LARCH_TLS_DESC_CALL)1473          continue;1474        rel.expr = getRelExpr(rel.type, *rel.sym, loc);1475        val = SignExtend64(sec.getRelocTargetVA(ctx, rel, secAddr + rel.offset),1476                           bits);1477        relocateNoSym(loc, rel.type, val);1478      } else {1479        isRelax = relaxable(relocs, i);1480        if (isRelax && (rel.type == R_LARCH_TLS_DESC_PC_HI20 ||1481                        rel.type == R_LARCH_TLS_DESC_PC_LO12 ||1482                        (rel.type == R_LARCH_TLS_DESC_LD && isUInt<12>(val))))1483          continue;1484        tlsdescToLe(loc, rel, val);1485      }1486      continue;1487    case RE_LOONGARCH_GOT_PAGE_PC:1488      // In LoongArch, we try GOT indirection to PC relative optimization in1489      // normal or medium code model, whether or not with R_LARCH_RELAX1490      // relocation. Moreover, if the original code sequence can be relaxed to a1491      // single instruction `pcaddi`, the first instruction will be removed and1492      // it will not reach here.1493      if (isPairForGotRels && rel.type == R_LARCH_GOT_PC_HI20) {1494        bool isRelax = relaxable(relocs, i);1495        const Relocation lo12Rel = isRelax ? relocs[i + 2] : relocs[i + 1];1496        if (lo12Rel.type == R_LARCH_GOT_PC_LO12 &&1497            tryGotToPCRel(loc, rel, lo12Rel, secAddr)) {1498          // isRelax: skip relocations R_LARCH_RELAX, R_LARCH_GOT_PC_LO121499          // !isRelax: skip relocation R_LARCH_GOT_PC_LO121500          i += isRelax ? 2 : 1;1501          continue;1502        }1503      }1504      break;1505    default:1506      break;1507    }1508    relocate(loc, rel, val);1509  }1510}1511 1512// When relaxing just R_LARCH_ALIGN, relocDeltas is usually changed only once in1513// the absence of a linker script. For call and load/store R_LARCH_RELAX, code1514// shrinkage may reduce displacement and make more relocations eligible for1515// relaxation. Code shrinkage may increase displacement to a call/load/store1516// target at a higher fixed address, invalidating an earlier relaxation. Any1517// change in section sizes can have cascading effect and require another1518// relaxation pass.1519bool LoongArch::relaxOnce(int pass) const {1520  if (pass == 0)1521    initSymbolAnchors(ctx);1522 1523  SmallVector<InputSection *, 0> storage;1524  bool changed = false;1525  for (OutputSection *osec : ctx.outputSections) {1526    if (!(osec->flags & SHF_EXECINSTR))1527      continue;1528    for (InputSection *sec : getInputSections(*osec, storage))1529      changed |= relax(ctx, *sec);1530  }1531  return changed;1532}1533 1534void LoongArch::finalizeRelax(int passes) const {1535  Log(ctx) << "relaxation passes: " << passes;1536  SmallVector<InputSection *, 0> storage;1537  for (OutputSection *osec : ctx.outputSections) {1538    if (!(osec->flags & SHF_EXECINSTR))1539      continue;1540    for (InputSection *sec : getInputSections(*osec, storage)) {1541      RelaxAux &aux = *sec->relaxAux;1542      if (!aux.relocDeltas)1543        continue;1544 1545      MutableArrayRef<Relocation> rels = sec->relocs();1546      ArrayRef<uint8_t> old = sec->content();1547      size_t newSize = old.size() - aux.relocDeltas[rels.size() - 1];1548      size_t writesIdx = 0;1549      uint8_t *p = ctx.bAlloc.Allocate<uint8_t>(newSize);1550      uint64_t offset = 0;1551      int64_t delta = 0;1552      sec->content_ = p;1553      sec->size = newSize;1554      sec->bytesDropped = 0;1555 1556      // Update section content: remove NOPs for R_LARCH_ALIGN and rewrite1557      // instructions for relaxed relocations.1558      for (size_t i = 0, e = rels.size(); i != e; ++i) {1559        uint32_t remove = aux.relocDeltas[i] - delta;1560        delta = aux.relocDeltas[i];1561        if (remove == 0 && aux.relocTypes[i] == R_LARCH_NONE)1562          continue;1563 1564        // Copy from last location to the current relocated location.1565        Relocation &r = rels[i];1566        uint64_t size = r.offset - offset;1567        memcpy(p, old.data() + offset, size);1568        p += size;1569 1570        int64_t skip = 0;1571        if (RelType newType = aux.relocTypes[i]) {1572          switch (newType) {1573          case R_LARCH_RELAX:1574            break;1575          case R_LARCH_PCREL20_S2:1576            skip = 4;1577            write32le(p, aux.writes[writesIdx++]);1578            // RelExpr is needed for relocating.1579            r.expr = r.sym->hasFlag(NEEDS_PLT) ? R_PLT_PC : R_PC;1580            break;1581          case R_LARCH_B26:1582          case R_LARCH_TLS_LE_LO12_R:1583            skip = 4;1584            write32le(p, aux.writes[writesIdx++]);1585            break;1586          case R_LARCH_TLS_GD_PCREL20_S2:1587            // Note: R_LARCH_TLS_LD_PCREL20_S2 must also use R_TLSGD_PC instead1588            // of R_TLSLD_PC due to historical reasons. In fact, right now TLSLD1589            // behaves exactly like TLSGD on LoongArch.1590            //1591            // This reason has also been mentioned in mold commit:1592            // https://github.com/rui314/mold/commit/5dfa1cf07c03bd57cb3d493b652ef22441bcd71c1593          case R_LARCH_TLS_LD_PCREL20_S2:1594            skip = 4;1595            write32le(p, aux.writes[writesIdx++]);1596            r.expr = R_TLSGD_PC;1597            break;1598          case R_LARCH_TLS_DESC_PCREL20_S2:1599            skip = 4;1600            write32le(p, aux.writes[writesIdx++]);1601            r.expr = R_TLSDESC_PC;1602            break;1603          default:1604            llvm_unreachable("unsupported type");1605          }1606        }1607 1608        p += skip;1609        offset = r.offset + skip + remove;1610      }1611      memcpy(p, old.data() + offset, old.size() - offset);1612 1613      // Subtract the previous relocDeltas value from the relocation offset.1614      // For a pair of R_LARCH_XXX/R_LARCH_RELAX with the same offset, decrease1615      // their r_offset by the same delta.1616      delta = 0;1617      for (size_t i = 0, e = rels.size(); i != e;) {1618        uint64_t cur = rels[i].offset;1619        do {1620          rels[i].offset -= delta;1621          if (aux.relocTypes[i] != R_LARCH_NONE)1622            rels[i].type = aux.relocTypes[i];1623        } while (++i != e && rels[i].offset == cur);1624        delta = aux.relocDeltas[i - 1];1625      }1626    }1627  }1628}1629 1630void elf::setLoongArchTargetInfo(Ctx &ctx) {1631  ctx.target.reset(new LoongArch(ctx));1632}1633