//===- MIPS.cpp -----------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "InputFiles.h"
#include "OutputSections.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Thunks.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"

using namespace llvm;
using namespace llvm::object;
using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;

namespace {
template <class ELFT> class MIPS final : public TargetInfo {
public:
  MIPS();
  uint32_t calcEFlags() const override;
  RelExpr getRelExpr(RelType type, const Symbol &s,
                     const uint8_t *loc) const override;
  int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
  RelType getDynRel(RelType type) const override;
  void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
  void writePltHeader(uint8_t *buf) const override;
  void writePlt(uint8_t *buf, const Symbol &sym,
                uint64_t pltEntryAddr) const override;
  bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
                  uint64_t branchAddr, const Symbol &s,
                  int64_t a) const override;
  void relocate(uint8_t *loc, const Relocation &rel,
                uint64_t val) const override;
  bool usesOnlyLowPageBits(RelType type) const override;
};
} // namespace

template <class ELFT> MIPS<ELFT>::MIPS() {
  gotPltHeaderEntriesNum = 2;
  defaultMaxPageSize = 65536;
  pltEntrySize = 16;
  pltHeaderSize = 32;
  copyRel = R_MIPS_COPY;
  pltRel = R_MIPS_JUMP_SLOT;
  needsThunks = true;

  // Set `sigrie 1` as a trap instruction.
  write32(trapInstr.data(), 0x04170001);

  if (ELFT::Is64Bits) {
    relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
    symbolicRel = R_MIPS_64;
    tlsGotRel = R_MIPS_TLS_TPREL64;
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
    tlsOffsetRel = R_MIPS_TLS_DTPREL64;
  } else {
    relativeRel = R_MIPS_REL32;
    symbolicRel = R_MIPS_32;
    tlsGotRel = R_MIPS_TLS_TPREL32;
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
    tlsOffsetRel = R_MIPS_TLS_DTPREL32;
  }
}

template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
  return calcMipsEFlags<ELFT>();
}

template <class ELFT>
RelExpr MIPS<ELFT>::getRelExpr(RelType type, const Symbol &s,
                               const uint8_t *loc) const {
  // See comment in the calculateMipsRelChain.
  if (ELFT::Is64Bits || config->mipsN32Abi)
    type &= 0xff;

  switch (type) {
  case R_MIPS_JALR:
    // Older versions of clang would erroneously emit this relocation not only
    // against functions (loaded from the GOT) but also against data symbols
    // (e.g. a table of function pointers). When we encounter this, ignore the
    // relocation and emit a warning instead.
    if (!s.isFunc() && s.type != STT_NOTYPE) {
      warn(getErrorLocation(loc) +
           "found R_MIPS_JALR relocation against non-function symbol " +
           toString(s) + ". This is invalid and most likely a compiler bug.");
      return R_NONE;
    }

    // If the target symbol is not preemptible and is not microMIPS,
    // it might be possible to replace jalr/jr instruction by bal/b.
    // It depends on the target symbol's offset.
    if (!s.isPreemptible && !(s.getVA() & 0x1))
      return R_PC;
    return R_NONE;
  case R_MICROMIPS_JALR:
    return R_NONE;
  case R_MIPS_GPREL16:
  case R_MIPS_GPREL32:
  case R_MICROMIPS_GPREL16:
  case R_MICROMIPS_GPREL7_S2:
    return R_MIPS_GOTREL;
  case R_MIPS_26:
  case R_MICROMIPS_26_S1:
    return R_PLT;
  case R_MICROMIPS_PC26_S1:
    return R_PLT_PC;
  case R_MIPS_HI16:
  case R_MIPS_LO16:
  case R_MIPS_HIGHER:
  case R_MIPS_HIGHEST:
  case R_MICROMIPS_HI16:
  case R_MICROMIPS_LO16:
    // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
    // offset between start of function and 'gp' value which by default
    // equal to the start of .got section. In that case we consider these
    // relocations as relative.
    if (&s == ElfSym::mipsGpDisp)
      return R_MIPS_GOT_GP_PC;
    if (&s == ElfSym::mipsLocalGp)
      return R_MIPS_GOT_GP;
    LLVM_FALLTHROUGH;
  case R_MIPS_32:
  case R_MIPS_64:
  case R_MIPS_GOT_OFST:
  case R_MIPS_SUB:
    return R_ABS;
  case R_MIPS_TLS_DTPREL_HI16:
  case R_MIPS_TLS_DTPREL_LO16:
  case R_MIPS_TLS_DTPREL32:
  case R_MIPS_TLS_DTPREL64:
  case R_MICROMIPS_TLS_DTPREL_HI16:
  case R_MICROMIPS_TLS_DTPREL_LO16:
    return R_DTPREL;
  case R_MIPS_TLS_TPREL_HI16:
  case R_MIPS_TLS_TPREL_LO16:
  case R_MIPS_TLS_TPREL32:
  case R_MIPS_TLS_TPREL64:
  case R_MICROMIPS_TLS_TPREL_HI16:
  case R_MICROMIPS_TLS_TPREL_LO16:
    return R_TPREL;
  case R_MIPS_PC32:
  case R_MIPS_PC16:
  case R_MIPS_PC19_S2:
  case R_MIPS_PC21_S2:
  case R_MIPS_PC26_S2:
  case R_MIPS_PCHI16:
  case R_MIPS_PCLO16:
  case R_MICROMIPS_PC7_S1:
  case R_MICROMIPS_PC10_S1:
  case R_MICROMIPS_PC16_S1:
  case R_MICROMIPS_PC18_S3:
  case R_MICROMIPS_PC19_S2:
  case R_MICROMIPS_PC23_S2:
  case R_MICROMIPS_PC21_S1:
    return R_PC;
  case R_MIPS_GOT16:
  case R_MICROMIPS_GOT16:
    if (s.isLocal())
      return R_MIPS_GOT_LOCAL_PAGE;
    LLVM_FALLTHROUGH;
  case R_MIPS_CALL16:
  case R_MIPS_GOT_DISP:
  case R_MIPS_TLS_GOTTPREL:
  case R_MICROMIPS_CALL16:
  case R_MICROMIPS_TLS_GOTTPREL:
    return R_MIPS_GOT_OFF;
  case R_MIPS_CALL_HI16:
  case R_MIPS_CALL_LO16:
  case R_MIPS_GOT_HI16:
  case R_MIPS_GOT_LO16:
  case R_MICROMIPS_CALL_HI16:
  case R_MICROMIPS_CALL_LO16:
  case R_MICROMIPS_GOT_HI16:
  case R_MICROMIPS_GOT_LO16:
    return R_MIPS_GOT_OFF32;
  case R_MIPS_GOT_PAGE:
    return R_MIPS_GOT_LOCAL_PAGE;
  case R_MIPS_TLS_GD:
  case R_MICROMIPS_TLS_GD:
    return R_MIPS_TLSGD;
  case R_MIPS_TLS_LDM:
  case R_MICROMIPS_TLS_LDM:
    return R_MIPS_TLSLD;
  case R_MIPS_NONE:
    return R_NONE;
  default:
    error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
          ") against symbol " + toString(s));
    return R_NONE;
  }
}

template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType type) const {
  if (type == symbolicRel)
    return type;
  return R_MIPS_NONE;
}

template <class ELFT>
void MIPS<ELFT>::writeGotPlt(uint8_t *buf, const Symbol &) const {
  uint64_t va = in.plt->getVA();
  if (isMicroMips())
    va |= 1;
  write32(buf, va);
}

template <endianness E> static uint32_t readShuffle(const uint8_t *loc) {
  // The major opcode of a microMIPS instruction needs to appear
  // in the first 16-bit word (lowest address) for efficient hardware
  // decode so that it knows if the instruction is 16-bit or 32-bit
  // as early as possible. To do so, little-endian binaries keep 16-bit
  // words in a big-endian order. That is why we have to swap these
  // words to get a correct value.
  uint32_t v = read32(loc);
  if (E == support::little)
    return (v << 16) | (v >> 16);
  return v;
}

static void writeValue(uint8_t *loc, uint64_t v, uint8_t bitsSize,
                       uint8_t shift) {
  uint32_t instr = read32(loc);
  uint32_t mask = 0xffffffff >> (32 - bitsSize);
  uint32_t data = (instr & ~mask) | ((v >> shift) & mask);
  write32(loc, data);
}

template <endianness E>
static void writeShuffleValue(uint8_t *loc, uint64_t v, uint8_t bitsSize,
                              uint8_t shift) {
  // See comments in readShuffle for purpose of this code.
  uint16_t *words = (uint16_t *)loc;
  if (E == support::little)
    std::swap(words[0], words[1]);

  writeValue(loc, v, bitsSize, shift);

  if (E == support::little)
    std::swap(words[0], words[1]);
}

template <endianness E>
static void writeMicroRelocation16(uint8_t *loc, uint64_t v, uint8_t bitsSize,
                                   uint8_t shift) {
  uint16_t instr = read16(loc);
  uint16_t mask = 0xffff >> (16 - bitsSize);
  uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
  write16(loc, data);
}

template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
  if (isMicroMips()) {
    uint64_t gotPlt = in.gotPlt->getVA();
    uint64_t plt = in.plt->getVA();
    // Overwrite trap instructions written by Writer::writeTrapInstr.
    memset(buf, 0, pltHeaderSize);

    write16(buf, isMipsR6() ? 0x7860 : 0x7980);  // addiupc v1, (GOTPLT) - .
    write16(buf + 4, 0xff23);    // lw      $25, 0($3)
    write16(buf + 8, 0x0535);    // subu16  $2,  $2, $3
    write16(buf + 10, 0x2525);   // srl16   $2,  $2, 2
    write16(buf + 12, 0x3302);   // addiu   $24, $2, -2
    write16(buf + 14, 0xfffe);
    write16(buf + 16, 0x0dff);   // move    $15, $31
    if (isMipsR6()) {
      write16(buf + 18, 0x0f83); // move    $28, $3
      write16(buf + 20, 0x472b); // jalrc   $25
      write16(buf + 22, 0x0c00); // nop
      relocateNoSym(buf, R_MICROMIPS_PC19_S2, gotPlt - plt);
    } else {
      write16(buf + 18, 0x45f9); // jalrc   $25
      write16(buf + 20, 0x0f83); // move    $28, $3
      write16(buf + 22, 0x0c00); // nop
      relocateNoSym(buf, R_MICROMIPS_PC23_S2, gotPlt - plt);
    }
    return;
  }

  if (config->mipsN32Abi) {
    write32(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
    write32(buf + 4, 0x8dd90000);  // lw    $25, %lo(&GOTPLT[0])($14)
    write32(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
    write32(buf + 12, 0x030ec023); // subu  $24, $24, $14
    write32(buf + 16, 0x03e07825); // move  $15, $31
    write32(buf + 20, 0x0018c082); // srl   $24, $24, 2
  } else if (ELFT::Is64Bits) {
    write32(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
    write32(buf + 4, 0xddd90000);  // ld    $25, %lo(&GOTPLT[0])($14)
    write32(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
    write32(buf + 12, 0x030ec023); // subu  $24, $24, $14
    write32(buf + 16, 0x03e07825); // move  $15, $31
    write32(buf + 20, 0x0018c0c2); // srl   $24, $24, 3
  } else {
    write32(buf, 0x3c1c0000);      // lui   $28, %hi(&GOTPLT[0])
    write32(buf + 4, 0x8f990000);  // lw    $25, %lo(&GOTPLT[0])($28)
    write32(buf + 8, 0x279c0000);  // addiu $28, $28, %lo(&GOTPLT[0])
    write32(buf + 12, 0x031cc023); // subu  $24, $24, $28
    write32(buf + 16, 0x03e07825); // move  $15, $31
    write32(buf + 20, 0x0018c082); // srl   $24, $24, 2
  }

  uint32_t jalrInst = config->zHazardplt ? 0x0320fc09 : 0x0320f809;
  write32(buf + 24, jalrInst); // jalr.hb $25 or jalr $25
  write32(buf + 28, 0x2718fffe); // subu  $24, $24, 2

  uint64_t gotPlt = in.gotPlt->getVA();
  writeValue(buf, gotPlt + 0x8000, 16, 16);
  writeValue(buf + 4, gotPlt, 16, 0);
  writeValue(buf + 8, gotPlt, 16, 0);
}

template <class ELFT>
void MIPS<ELFT>::writePlt(uint8_t *buf, const Symbol &sym,
                          uint64_t pltEntryAddr) const {
  uint64_t gotPltEntryAddr = sym.getGotPltVA();
  if (isMicroMips()) {
    // Overwrite trap instructions written by Writer::writeTrapInstr.
    memset(buf, 0, pltEntrySize);

    if (isMipsR6()) {
      write16(buf, 0x7840);      // addiupc $2, (GOTPLT) - .
      write16(buf + 4, 0xff22);  // lw $25, 0($2)
      write16(buf + 8, 0x0f02);  // move $24, $2
      write16(buf + 10, 0x4723); // jrc $25 / jr16 $25
      relocateNoSym(buf, R_MICROMIPS_PC19_S2, gotPltEntryAddr - pltEntryAddr);
    } else {
      write16(buf, 0x7900);      // addiupc $2, (GOTPLT) - .
      write16(buf + 4, 0xff22);  // lw $25, 0($2)
      write16(buf + 8, 0x4599);  // jrc $25 / jr16 $25
      write16(buf + 10, 0x0f02); // move $24, $2
      relocateNoSym(buf, R_MICROMIPS_PC23_S2, gotPltEntryAddr - pltEntryAddr);
    }
    return;
  }

  uint32_t loadInst = ELFT::Is64Bits ? 0xddf90000 : 0x8df90000;
  uint32_t jrInst = isMipsR6() ? (config->zHazardplt ? 0x03200409 : 0x03200009)
                               : (config->zHazardplt ? 0x03200408 : 0x03200008);
  uint32_t addInst = ELFT::Is64Bits ? 0x65f80000 : 0x25f80000;

  write32(buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)
  write32(buf + 4, loadInst);   // l[wd] $25, %lo(.got.plt entry)($15)
  write32(buf + 8, jrInst);     // jr  $25 / jr.hb $25
  write32(buf + 12, addInst);   // [d]addiu $24, $15, %lo(.got.plt entry)
  writeValue(buf, gotPltEntryAddr + 0x8000, 16, 16);
  writeValue(buf + 4, gotPltEntryAddr, 16, 0);
  writeValue(buf + 12, gotPltEntryAddr, 16, 0);
}

template <class ELFT>
bool MIPS<ELFT>::needsThunk(RelExpr expr, RelType type, const InputFile *file,
                            uint64_t branchAddr, const Symbol &s,
                            int64_t /*a*/) const {
  // Any MIPS PIC code function is invoked with its address in register $t9.
  // So if we have a branch instruction from non-PIC code to the PIC one
  // we cannot make the jump directly and need to create a small stubs
  // to save the target function address.
  // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
  if (type != R_MIPS_26 && type != R_MIPS_PC26_S2 &&
      type != R_MICROMIPS_26_S1 && type != R_MICROMIPS_PC26_S1)
    return false;
  auto *f = dyn_cast_or_null<ObjFile<ELFT>>(file);
  if (!f)
    return false;
  // If current file has PIC code, LA25 stub is not required.
  if (f->getObj().getHeader().e_flags & EF_MIPS_PIC)
    return false;
  auto *d = dyn_cast<Defined>(&s);
  // LA25 is required if target file has PIC code
  // or target symbol is a PIC symbol.
  return d && isMipsPIC<ELFT>(d);
}

template <class ELFT>
int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
  const endianness e = ELFT::TargetEndianness;
  switch (type) {
  case R_MIPS_32:
  case R_MIPS_REL32:
  case R_MIPS_GPREL32:
  case R_MIPS_TLS_DTPREL32:
  case R_MIPS_TLS_DTPMOD32:
  case R_MIPS_TLS_TPREL32:
    return SignExtend64<32>(read32(buf));
  case R_MIPS_26:
    // FIXME (simon): If the relocation target symbol is not a PLT entry
    // we should use another expression for calculation:
    // ((A << 2) | (P & 0xf0000000)) >> 2
    return SignExtend64<28>(read32(buf) << 2);
  case R_MIPS_CALL_HI16:
  case R_MIPS_GOT16:
  case R_MIPS_GOT_HI16:
  case R_MIPS_HI16:
  case R_MIPS_PCHI16:
    return SignExtend64<16>(read32(buf)) << 16;
  case R_MIPS_CALL16:
  case R_MIPS_CALL_LO16:
  case R_MIPS_GOT_LO16:
  case R_MIPS_GPREL16:
  case R_MIPS_LO16:
  case R_MIPS_PCLO16:
  case R_MIPS_TLS_DTPREL_HI16:
  case R_MIPS_TLS_DTPREL_LO16:
  case R_MIPS_TLS_GD:
  case R_MIPS_TLS_GOTTPREL:
  case R_MIPS_TLS_LDM:
  case R_MIPS_TLS_TPREL_HI16:
  case R_MIPS_TLS_TPREL_LO16:
    return SignExtend64<16>(read32(buf));
  case R_MICROMIPS_GOT16:
  case R_MICROMIPS_HI16:
    return SignExtend64<16>(readShuffle<e>(buf)) << 16;
  case R_MICROMIPS_CALL16:
  case R_MICROMIPS_GPREL16:
  case R_MICROMIPS_LO16:
  case R_MICROMIPS_TLS_DTPREL_HI16:
  case R_MICROMIPS_TLS_DTPREL_LO16:
  case R_MICROMIPS_TLS_GD:
  case R_MICROMIPS_TLS_GOTTPREL:
  case R_MICROMIPS_TLS_LDM:
  case R_MICROMIPS_TLS_TPREL_HI16:
  case R_MICROMIPS_TLS_TPREL_LO16:
    return SignExtend64<16>(readShuffle<e>(buf));
  case R_MICROMIPS_GPREL7_S2:
    return SignExtend64<9>(readShuffle<e>(buf) << 2);
  case R_MIPS_PC16:
    return SignExtend64<18>(read32(buf) << 2);
  case R_MIPS_PC19_S2:
    return SignExtend64<21>(read32(buf) << 2);
  case R_MIPS_PC21_S2:
    return SignExtend64<23>(read32(buf) << 2);
  case R_MIPS_PC26_S2:
    return SignExtend64<28>(read32(buf) << 2);
  case R_MIPS_PC32:
    return SignExtend64<32>(read32(buf));
  case R_MICROMIPS_26_S1:
    return SignExtend64<27>(readShuffle<e>(buf) << 1);
  case R_MICROMIPS_PC7_S1:
    return SignExtend64<8>(read16(buf) << 1);
  case R_MICROMIPS_PC10_S1:
    return SignExtend64<11>(read16(buf) << 1);
  case R_MICROMIPS_PC16_S1:
    return SignExtend64<17>(readShuffle<e>(buf) << 1);
  case R_MICROMIPS_PC18_S3:
    return SignExtend64<21>(readShuffle<e>(buf) << 3);
  case R_MICROMIPS_PC19_S2:
    return SignExtend64<21>(readShuffle<e>(buf) << 2);
  case R_MICROMIPS_PC21_S1:
    return SignExtend64<22>(readShuffle<e>(buf) << 1);
  case R_MICROMIPS_PC23_S2:
    return SignExtend64<25>(readShuffle<e>(buf) << 2);
  case R_MICROMIPS_PC26_S1:
    return SignExtend64<27>(readShuffle<e>(buf) << 1);
  case R_MIPS_64:
  case R_MIPS_TLS_DTPMOD64:
  case R_MIPS_TLS_DTPREL64:
  case R_MIPS_TLS_TPREL64:
  case (R_MIPS_64 << 8) | R_MIPS_REL32:
    return read64(buf);
  case R_MIPS_COPY:
    return config->is64 ? read64(buf) : read32(buf);
  case R_MIPS_NONE:
  case R_MIPS_JUMP_SLOT:
  case R_MIPS_JALR:
    // These relocations are defined as not having an implicit addend.
    return 0;
  default:
    internalLinkerError(getErrorLocation(buf),
                        "cannot read addend for relocation " + toString(type));
    return 0;
  }
}

static std::pair<uint32_t, uint64_t>
calculateMipsRelChain(uint8_t *loc, RelType type, uint64_t val) {
  // MIPS N64 ABI packs multiple relocations into the single relocation
  // record. In general, all up to three relocations can have arbitrary
  // types. In fact, Clang and GCC uses only a few combinations. For now,
  // we support two of them. That is allow to pass at least all LLVM
  // test suite cases.
  // <any relocation> / R_MIPS_SUB / R_MIPS_HI16 | R_MIPS_LO16
  // <any relocation> / R_MIPS_64 / R_MIPS_NONE
  // The first relocation is a 'real' relocation which is calculated
  // using the corresponding symbol's value. The second and the third
  // relocations used to modify result of the first one: extend it to
  // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation
  // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf
  RelType type2 = (type >> 8) & 0xff;
  RelType type3 = (type >> 16) & 0xff;
  if (type2 == R_MIPS_NONE && type3 == R_MIPS_NONE)
    return std::make_pair(type, val);
  if (type2 == R_MIPS_64 && type3 == R_MIPS_NONE)
    return std::make_pair(type2, val);
  if (type2 == R_MIPS_SUB && (type3 == R_MIPS_HI16 || type3 == R_MIPS_LO16))
    return std::make_pair(type3, -val);
  error(getErrorLocation(loc) + "unsupported relocations combination " +
        Twine(type));
  return std::make_pair(type & 0xff, val);
}

static bool isBranchReloc(RelType type) {
  return type == R_MIPS_26 || type == R_MIPS_PC26_S2 ||
         type == R_MIPS_PC21_S2 || type == R_MIPS_PC16;
}

static bool isMicroBranchReloc(RelType type) {
  return type == R_MICROMIPS_26_S1 || type == R_MICROMIPS_PC16_S1 ||
         type == R_MICROMIPS_PC10_S1 || type == R_MICROMIPS_PC7_S1;
}

template <class ELFT>
static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
  // Here we need to detect jump/branch from regular MIPS code
  // to a microMIPS target and vice versa. In that cases jump
  // instructions need to be replaced by their "cross-mode"
  // equivalents.
  const endianness e = ELFT::TargetEndianness;
  bool isMicroTgt = val & 0x1;
  bool isCrossJump = (isMicroTgt && isBranchReloc(type)) ||
                     (!isMicroTgt && isMicroBranchReloc(type));
  if (!isCrossJump)
    return val;

  switch (type) {
  case R_MIPS_26: {
    uint32_t inst = read32(loc) >> 26;
    if (inst == 0x3 || inst == 0x1d) { // JAL or JALX
      writeValue(loc, 0x1d << 26, 32, 0);
      return val;
    }
    break;
  }
  case R_MICROMIPS_26_S1: {
    uint32_t inst = readShuffle<e>(loc) >> 26;
    if (inst == 0x3d || inst == 0x3c) { // JAL32 or JALX32
      val >>= 1;
      writeShuffleValue<e>(loc, 0x3c << 26, 32, 0);
      return val;
    }
    break;
  }
  case R_MIPS_PC26_S2:
  case R_MIPS_PC21_S2:
  case R_MIPS_PC16:
  case R_MICROMIPS_PC16_S1:
  case R_MICROMIPS_PC10_S1:
  case R_MICROMIPS_PC7_S1:
    // FIXME (simon): Support valid branch relocations.
    break;
  default:
    llvm_unreachable("unexpected jump/branch relocation");
  }

  error(getErrorLocation(loc) +
        "unsupported jump/branch instruction between ISA modes referenced by " +
        toString(type) + " relocation");
  return val;
}

template <class ELFT>
void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
                          uint64_t val) const {
  const endianness e = ELFT::TargetEndianness;
  RelType type = rel.type;

  if (ELFT::Is64Bits || config->mipsN32Abi)
    std::tie(type, val) = calculateMipsRelChain(loc, type, val);

  // Detect cross-mode jump/branch and fix instruction.
  val = fixupCrossModeJump<ELFT>(loc, type, val);

  // Thread pointer and DRP offsets from the start of TLS data area.
  // https://www.linux-mips.org/wiki/NPTL
  if (type == R_MIPS_TLS_DTPREL_HI16 || type == R_MIPS_TLS_DTPREL_LO16 ||
      type == R_MIPS_TLS_DTPREL32 || type == R_MIPS_TLS_DTPREL64 ||
      type == R_MICROMIPS_TLS_DTPREL_HI16 ||
      type == R_MICROMIPS_TLS_DTPREL_LO16) {
    val -= 0x8000;
  }

  switch (type) {
  case R_MIPS_32:
  case R_MIPS_GPREL32:
  case R_MIPS_TLS_DTPREL32:
  case R_MIPS_TLS_TPREL32:
    write32(loc, val);
    break;
  case R_MIPS_64:
  case R_MIPS_TLS_DTPREL64:
  case R_MIPS_TLS_TPREL64:
    write64(loc, val);
    break;
  case R_MIPS_26:
    writeValue(loc, val, 26, 2);
    break;
  case R_MIPS_GOT16:
    // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
    // is updated addend (not a GOT index). In that case write high 16 bits
    // to store a correct addend value.
    if (config->relocatable) {
      writeValue(loc, val + 0x8000, 16, 16);
    } else {
      checkInt(loc, val, 16, rel);
      writeValue(loc, val, 16, 0);
    }
    break;
  case R_MICROMIPS_GOT16:
    if (config->relocatable) {
      writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
    } else {
      checkInt(loc, val, 16, rel);
      writeShuffleValue<e>(loc, val, 16, 0);
    }
    break;
  case R_MIPS_CALL16:
  case R_MIPS_GOT_DISP:
  case R_MIPS_GOT_PAGE:
  case R_MIPS_GPREL16:
  case R_MIPS_TLS_GD:
  case R_MIPS_TLS_GOTTPREL:
  case R_MIPS_TLS_LDM:
    checkInt(loc, val, 16, rel);
    LLVM_FALLTHROUGH;
  case R_MIPS_CALL_LO16:
  case R_MIPS_GOT_LO16:
  case R_MIPS_GOT_OFST:
  case R_MIPS_LO16:
  case R_MIPS_PCLO16:
  case R_MIPS_TLS_DTPREL_LO16:
  case R_MIPS_TLS_TPREL_LO16:
    writeValue(loc, val, 16, 0);
    break;
  case R_MICROMIPS_GPREL16:
  case R_MICROMIPS_TLS_GD:
  case R_MICROMIPS_TLS_LDM:
    checkInt(loc, val, 16, rel);
    writeShuffleValue<e>(loc, val, 16, 0);
    break;
  case R_MICROMIPS_CALL16:
  case R_MICROMIPS_CALL_LO16:
  case R_MICROMIPS_LO16:
  case R_MICROMIPS_TLS_DTPREL_LO16:
  case R_MICROMIPS_TLS_GOTTPREL:
  case R_MICROMIPS_TLS_TPREL_LO16:
    writeShuffleValue<e>(loc, val, 16, 0);
    break;
  case R_MICROMIPS_GPREL7_S2:
    checkInt(loc, val, 7, rel);
    writeShuffleValue<e>(loc, val, 7, 2);
    break;
  case R_MIPS_CALL_HI16:
  case R_MIPS_GOT_HI16:
  case R_MIPS_HI16:
  case R_MIPS_PCHI16:
  case R_MIPS_TLS_DTPREL_HI16:
  case R_MIPS_TLS_TPREL_HI16:
    writeValue(loc, val + 0x8000, 16, 16);
    break;
  case R_MICROMIPS_CALL_HI16:
  case R_MICROMIPS_GOT_HI16:
  case R_MICROMIPS_HI16:
  case R_MICROMIPS_TLS_DTPREL_HI16:
  case R_MICROMIPS_TLS_TPREL_HI16:
    writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
    break;
  case R_MIPS_HIGHER:
    writeValue(loc, val + 0x80008000, 16, 32);
    break;
  case R_MIPS_HIGHEST:
    writeValue(loc, val + 0x800080008000, 16, 48);
    break;
  case R_MIPS_JALR:
    val -= 4;
    // Replace jalr/jr instructions by bal/b if the target
    // offset fits into the 18-bit range.
    if (isInt<18>(val)) {
      switch (read32(loc)) {
      case 0x0320f809:  // jalr $25 => bal sym
        write32(loc, 0x04110000 | ((val >> 2) & 0xffff));
        break;
      case 0x03200008:  // jr $25 => b sym
        write32(loc, 0x10000000 | ((val >> 2) & 0xffff));
        break;
      }
    }
    break;
  case R_MICROMIPS_JALR:
    // Ignore this optimization relocation for now
    break;
  case R_MIPS_PC16:
    checkAlignment(loc, val, 4, rel);
    checkInt(loc, val, 18, rel);
    writeValue(loc, val, 16, 2);
    break;
  case R_MIPS_PC19_S2:
    checkAlignment(loc, val, 4, rel);
    checkInt(loc, val, 21, rel);
    writeValue(loc, val, 19, 2);
    break;
  case R_MIPS_PC21_S2:
    checkAlignment(loc, val, 4, rel);
    checkInt(loc, val, 23, rel);
    writeValue(loc, val, 21, 2);
    break;
  case R_MIPS_PC26_S2:
    checkAlignment(loc, val, 4, rel);
    checkInt(loc, val, 28, rel);
    writeValue(loc, val, 26, 2);
    break;
  case R_MIPS_PC32:
    writeValue(loc, val, 32, 0);
    break;
  case R_MICROMIPS_26_S1:
  case R_MICROMIPS_PC26_S1:
    checkInt(loc, val, 27, rel);
    writeShuffleValue<e>(loc, val, 26, 1);
    break;
  case R_MICROMIPS_PC7_S1:
    checkInt(loc, val, 8, rel);
    writeMicroRelocation16<e>(loc, val, 7, 1);
    break;
  case R_MICROMIPS_PC10_S1:
    checkInt(loc, val, 11, rel);
    writeMicroRelocation16<e>(loc, val, 10, 1);
    break;
  case R_MICROMIPS_PC16_S1:
    checkInt(loc, val, 17, rel);
    writeShuffleValue<e>(loc, val, 16, 1);
    break;
  case R_MICROMIPS_PC18_S3:
    checkInt(loc, val, 21, rel);
    writeShuffleValue<e>(loc, val, 18, 3);
    break;
  case R_MICROMIPS_PC19_S2:
    checkInt(loc, val, 21, rel);
    writeShuffleValue<e>(loc, val, 19, 2);
    break;
  case R_MICROMIPS_PC21_S1:
    checkInt(loc, val, 22, rel);
    writeShuffleValue<e>(loc, val, 21, 1);
    break;
  case R_MICROMIPS_PC23_S2:
    checkInt(loc, val, 25, rel);
    writeShuffleValue<e>(loc, val, 23, 2);
    break;
  default:
    llvm_unreachable("unknown relocation");
  }
}

template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
  return type == R_MIPS_LO16 || type == R_MIPS_GOT_OFST ||
         type == R_MICROMIPS_LO16;
}

// Return true if the symbol is a PIC function.
template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
  if (!sym->isFunc())
    return false;

  if (sym->stOther & STO_MIPS_PIC)
    return true;

  if (!sym->section)
    return false;

  ObjFile<ELFT> *file =
      cast<InputSectionBase>(sym->section)->template getFile<ELFT>();
  if (!file)
    return false;

  return file->getObj().getHeader().e_flags & EF_MIPS_PIC;
}

template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
  static MIPS<ELFT> target;
  return &target;
}

template TargetInfo *elf::getMipsTargetInfo<ELF32LE>();
template TargetInfo *elf::getMipsTargetInfo<ELF32BE>();
template TargetInfo *elf::getMipsTargetInfo<ELF64LE>();
template TargetInfo *elf::getMipsTargetInfo<ELF64BE>();

template bool elf::isMipsPIC<ELF32LE>(const Defined *);
template bool elf::isMipsPIC<ELF32BE>(const Defined *);
template bool elf::isMipsPIC<ELF64LE>(const Defined *);
template bool elf::isMipsPIC<ELF64BE>(const Defined *);
