//===- lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp -------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MipsELFFile.h"
#include "MipsLinkingContext.h"
#include "MipsRelocationPass.h"
#include "MipsTargetHandler.h"
#include "llvm/ADT/DenseSet.h"

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

// Lazy resolver
static const uint8_t mipsGot0AtomContent[] = {
  0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00
};

// Module pointer
static const uint8_t mipsGotModulePointerAtomContent[] = {
  0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x80
};

// TLS GD Entry
static const uint8_t mipsGotTlsGdAtomContent[] = {
  0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00
};

// Regular big-endian PLT0 entry
static const uint8_t mipsBePlt0AtomContent[] = {
  0x3c, 0x1c, 0x00, 0x00, // lui   $28, %hi(&GOTPLT[0])
  0x8f, 0x99, 0x00, 0x00, // lw    $25, %lo(&GOTPLT[0])($28)
  0x27, 0x9c, 0x00, 0x00, // addiu $28, $28, %lo(&GOTPLT[0])
  0x03, 0x1c, 0xc0, 0x23, // subu  $24, $24, $28
  0x03, 0xe0, 0x78, 0x25, // move  $15, $31
  0x00, 0x18, 0xc0, 0x82, // srl   $24, $24, 2
  0x03, 0x20, 0xf8, 0x09, // jalr  $25
  0x27, 0x18, 0xff, 0xfe  // subu  $24, $24, 2
};

// Regular little-endian PLT0 entry
static const uint8_t mipsLePlt0AtomContent[] = {
  0x00, 0x00, 0x1c, 0x3c, // lui   $28, %hi(&GOTPLT[0])
  0x00, 0x00, 0x99, 0x8f, // lw    $25, %lo(&GOTPLT[0])($28)
  0x00, 0x00, 0x9c, 0x27, // addiu $28, $28, %lo(&GOTPLT[0])
  0x23, 0xc0, 0x1c, 0x03, // subu  $24, $24, $28
  0x25, 0x78, 0xe0, 0x03, // move  $15, $31
  0x82, 0xc0, 0x18, 0x00, // srl   $24, $24, 2
  0x09, 0xf8, 0x20, 0x03, // jalr  $25
  0xfe, 0xff, 0x18, 0x27  // subu  $24, $24, 2
};

// N32 big-endian PLT0 entry
static const uint8_t mipsN32BePlt0AtomContent[] = {
  0x3c, 0x0e, 0x00, 0x00, // lui   $14, %hi(&GOTPLT[0])
  0x8d, 0xd9, 0x00, 0x00, // lw    $25, %lo(&GOTPLT[0])($14)
  0x25, 0xce, 0x00, 0x00, // addiu $14, $14, %lo(&GOTPLT[0])
  0x03, 0x0e, 0xc0, 0x23, // subu  $24, $24, $14
  0x03, 0xe0, 0x78, 0x25, // move  $15, $31
  0x00, 0x18, 0xc0, 0x82, // srl   $24, $24, 2
  0x03, 0x20, 0xf8, 0x09, // jalr  $25
  0x27, 0x18, 0xff, 0xfe  // subu  $24, $24, 2
};

// N32 little-endian PLT0 entry
static const uint8_t mipsN32LePlt0AtomContent[] = {
  0x00, 0x00, 0x0e, 0x3c, // lui   $14, %hi(&GOTPLT[0])
  0x00, 0x00, 0xd9, 0x8d, // lw    $25, %lo(&GOTPLT[0])($14)
  0x00, 0x00, 0xce, 0x25, // addiu $14, $14, %lo(&GOTPLT[0])
  0x23, 0xc0, 0x0e, 0x03, // subu  $24, $24, $14
  0x25, 0x78, 0xe0, 0x03, // move  $15, $31
  0x82, 0xc0, 0x18, 0x00, // srl   $24, $24, 2
  0x09, 0xf8, 0x20, 0x03, // jalr  $25
  0xfe, 0xff, 0x18, 0x27  // subu  $24, $24, 2
};

// microMIPS big-endian PLT0 entry
static const uint8_t microMipsBePlt0AtomContent[] = {
  0x79, 0x80, 0x00, 0x00, // addiupc $3,  (&GOTPLT[0]) - .
  0xff, 0x23, 0x00, 0x00, // lw      $25, 0($3)
  0x05, 0x35,             // subu    $2,  $2, $3
  0x25, 0x25,             // srl     $2,  $2, 2
  0x33, 0x02, 0xff, 0xfe, // subu    $24, $2, 2
  0x0d, 0xff,             // move    $15, $31
  0x45, 0xf9,             // jalrs   $25
  0x0f, 0x83,             // move    $28, $3
  0x0c, 0x00              // nop
};

// microMIPS little-endian PLT0 entry
static const uint8_t microMipsLePlt0AtomContent[] = {
  0x80, 0x79, 0x00, 0x00, // addiupc $3,  (&GOTPLT[0]) - .
  0x23, 0xff, 0x00, 0x00, // lw      $25, 0($3)
  0x35, 0x05,             // subu    $2,  $2, $3
  0x25, 0x25,             // srl     $2,  $2, 2
  0x02, 0x33, 0xfe, 0xff, // subu    $24, $2, 2
  0xff, 0x0d,             // move    $15, $31
  0xf9, 0x45,             // jalrs   $25
  0x83, 0x0f,             // move    $28, $3
  0x00, 0x0c              // nop
};

// Regular big-endian PLT entry
static const uint8_t mipsBePltAAtomContent[] = {
  0x3c, 0x0f, 0x00, 0x00, // lui   $15, %hi(.got.plt entry)
  0x8d, 0xf9, 0x00, 0x00, // l[wd] $25, %lo(.got.plt entry)($15)
  0x03, 0x20, 0x00, 0x08, // jr    $25
  0x25, 0xf8, 0x00, 0x00  // addiu $24, $15, %lo(.got.plt entry)
};

// Regular little-endian PLT entry
static const uint8_t mipsLePltAAtomContent[] = {
  0x00, 0x00, 0x0f, 0x3c, // lui   $15, %hi(.got.plt entry)
  0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15)
  0x08, 0x00, 0x20, 0x03, // jr    $25
  0x00, 0x00, 0xf8, 0x25  // addiu $24, $15, %lo(.got.plt entry)
};

// microMIPS big-endian PLT entry
static const uint8_t microMipsBePltAAtomContent[] = {
  0x79, 0x00, 0x00, 0x00, // addiupc $2, (.got.plt entry) - .
  0xff, 0x22, 0x00, 0x00, // lw $25, 0($2)
  0x45, 0x99,             // jr $25
  0x0f, 0x02              // move $24, $2
};

// microMIPS little-endian PLT entry
static const uint8_t microMipsLePltAAtomContent[] = {
  0x00, 0x79, 0x00, 0x00, // addiupc $2, (.got.plt entry) - .
  0x22, 0xff, 0x00, 0x00, // lw $25, 0($2)
  0x99, 0x45,             // jr $25
  0x02, 0x0f              // move $24, $2
};

// R6 big-endian PLT entry
static const uint8_t mipsR6BePltAAtomContent[] = {
  0x3c, 0x0f, 0x00, 0x00, // lui   $15, %hi(.got.plt entry)
  0x8d, 0xf9, 0x00, 0x00, // l[wd] $25, %lo(.got.plt entry)($15)
  0x03, 0x20, 0x00, 0x09, // jr    $25
  0x25, 0xf8, 0x00, 0x00  // addiu $24, $15, %lo(.got.plt entry)
};

// R6 little-endian PLT entry
static const uint8_t mipsR6LePltAAtomContent[] = {
  0x00, 0x00, 0x0f, 0x3c, // lui   $15, %hi(.got.plt entry)
  0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15)
  0x09, 0x00, 0x20, 0x03, // jr    $25
  0x00, 0x00, 0xf8, 0x25  // addiu $24, $15, %lo(.got.plt entry)
};

// LA25 big-endian stub entry
static const uint8_t mipsBeLA25AtomContent[] = {
  0x3c, 0x19, 0x00, 0x00, // lui   $25, %hi(func)
  0x08, 0x00, 0x00, 0x00, // j     func
  0x27, 0x39, 0x00, 0x00, // addiu $25, $25, %lo(func)
  0x00, 0x00, 0x00, 0x00  // nop
};

// LA25 little-endian stub entry
static const uint8_t mipsLeLA25AtomContent[] = {
  0x00, 0x00, 0x19, 0x3c, // lui   $25, %hi(func)
  0x00, 0x00, 0x00, 0x08, // j     func
  0x00, 0x00, 0x39, 0x27, // addiu $25, $25, %lo(func)
  0x00, 0x00, 0x00, 0x00  // nop
};

// microMIPS LA25 big-endian stub entry
static const uint8_t microMipsBeLA25AtomContent[] = {
  0x41, 0xbe, 0x00, 0x00, // lui   $25, %hi(func)
  0xd4, 0x00, 0x00, 0x00, // j     func
  0x33, 0x39, 0x00, 0x00, // addiu $25, $25, %lo(func)
  0x00, 0x00, 0x00, 0x00  // nop
};

// microMIPS LA25 little-endian stub entry
static const uint8_t microMipsLeLA25AtomContent[] = {
  0xb9, 0x41, 0x00, 0x00, // lui   $25, %hi(func)
  0x00, 0xd4, 0x00, 0x00, // j     func
  0x39, 0x33, 0x00, 0x00, // addiu $25, $25, %lo(func)
  0x00, 0x00, 0x00, 0x00  // nop
};

namespace {

/// \brief Abstract base class represent MIPS GOT entries.
class MipsGOTAtom : public GOTAtom {
public:
  MipsGOTAtom(const File &f) : GOTAtom(f, ".got") {}

  Alignment alignment() const override { return 4; }
};

/// \brief MIPS GOT entry initialized by zero.
template <typename ELFT> class GOT0Atom : public MipsGOTAtom {
public:
  GOT0Atom(const File &f) : MipsGOTAtom(f) {}

  ArrayRef<uint8_t> rawContent() const override;
};

template <> ArrayRef<uint8_t> GOT0Atom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(mipsGot0AtomContent).slice(4);
}
template <> ArrayRef<uint8_t> GOT0Atom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(mipsGot0AtomContent).slice(4);
}
template <> ArrayRef<uint8_t> GOT0Atom<ELF64BE>::rawContent() const {
  return llvm::makeArrayRef(mipsGot0AtomContent);
}
template <> ArrayRef<uint8_t> GOT0Atom<ELF64LE>::rawContent() const {
  return llvm::makeArrayRef(mipsGot0AtomContent);
}

/// \brief MIPS GOT entry initialized by zero.
template <typename ELFT> class GOTModulePointerAtom : public MipsGOTAtom {
public:
  GOTModulePointerAtom(const File &f) : MipsGOTAtom(f) {}

  ArrayRef<uint8_t> rawContent() const override;
};

template <>
ArrayRef<uint8_t> GOTModulePointerAtom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(mipsGotModulePointerAtomContent).slice(4);
}
template <>
ArrayRef<uint8_t> GOTModulePointerAtom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(mipsGotModulePointerAtomContent).slice(4);
}
template <>
ArrayRef<uint8_t> GOTModulePointerAtom<ELF64BE>::rawContent() const {
  return llvm::makeArrayRef(mipsGotModulePointerAtomContent);
}
template <>
ArrayRef<uint8_t> GOTModulePointerAtom<ELF64LE>::rawContent() const {
  return llvm::makeArrayRef(mipsGotModulePointerAtomContent);
}

/// \brief MIPS GOT TLS GD entry.
template <typename ELFT> class GOTTLSGdAtom : public MipsGOTAtom {
public:
  GOTTLSGdAtom(const File &f) : MipsGOTAtom(f) {}

  ArrayRef<uint8_t> rawContent() const override;
};

template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8);
}
template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8);
}
template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF64BE>::rawContent() const {
  return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
}
template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF64LE>::rawContent() const {
  return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
}

class GOTPLTAtom : public GOTAtom {
public:
  GOTPLTAtom(const File &f) : GOTAtom(f, ".got.plt") {}
  GOTPLTAtom(const Atom *a, const File &f) : GOTAtom(f, ".got.plt") {
    // Create dynamic relocation to adjust the .got.plt entry at runtime.
    addReferenceELF_Mips(R_MIPS_JUMP_SLOT, 0, a, 0);
  }

  /// Setup reference to assign initial value to the .got.plt entry.
  void setPLT0(const PLTAtom *plt0) {
    addReferenceELF_Mips(R_MIPS_32, 0, plt0, 0);
  }

  Alignment alignment() const override { return 4; }

  ArrayRef<uint8_t> rawContent() const override {
    return llvm::makeArrayRef(mipsGot0AtomContent).slice(4);
  }
};

template <class ELFT> class PLT0Atom : public PLTAtom {
public:
  PLT0Atom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
    // Setup reference to fixup the PLT0 entry.
    addReferenceELF_Mips(R_MIPS_HI16, 0, got, 0);
    addReferenceELF_Mips(R_MIPS_LO16, 4, got, 0);
    addReferenceELF_Mips(R_MIPS_LO16, 8, got, 0);
  }

  ArrayRef<uint8_t> rawContent() const override {
    llvm_unreachable("PLT0 is not applicable for this target");
  }
};

template <> ArrayRef<uint8_t> PLT0Atom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(mipsBePlt0AtomContent);
}
template <> ArrayRef<uint8_t> PLT0Atom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(mipsLePlt0AtomContent);
}

template <class ELFT> class PLT0N32Atom : public PLTAtom {
public:
  PLT0N32Atom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
    // Setup reference to fixup the PLT0 entry.
    addReferenceELF_Mips(R_MIPS_HI16, 0, got, 0);
    addReferenceELF_Mips(R_MIPS_LO16, 4, got, 0);
    addReferenceELF_Mips(R_MIPS_LO16, 8, got, 0);
  }

  ArrayRef<uint8_t> rawContent() const override {
    llvm_unreachable("PLT0 is not applicable for this target");
  }
};

template <> ArrayRef<uint8_t> PLT0N32Atom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(mipsN32BePlt0AtomContent);
}
template <> ArrayRef<uint8_t> PLT0N32Atom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(mipsN32LePlt0AtomContent);
}

template <class ELFT> class PLT0MicroAtom : public PLTAtom {
public:
  PLT0MicroAtom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
    // Setup reference to fixup the PLT0 entry.
    addReferenceELF_Mips(R_MICROMIPS_PC23_S2, 0, got, 0);
  }

  CodeModel codeModel() const override { return codeMipsMicro; }

  ArrayRef<uint8_t> rawContent() const override {
    llvm_unreachable("PLT0 is not applicable for this target");
  }
};

template <> ArrayRef<uint8_t> PLT0MicroAtom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(microMipsBePlt0AtomContent);
}
template <> ArrayRef<uint8_t> PLT0MicroAtom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(microMipsLePlt0AtomContent);
}

class PLTAAtom : public PLTAtom {
public:
  PLTAAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") {
    // Setup reference to fixup the PLT entry.
    addReferenceELF_Mips(R_MIPS_HI16, 0, got, 0);
    addReferenceELF_Mips(R_MIPS_LO16, 4, got, 0);
    addReferenceELF_Mips(R_MIPS_LO16, 12, got, 0);
  }
};

template <class ELFT> class PLTARegAtom : public PLTAAtom {
public:
  PLTARegAtom(const GOTPLTAtom *got, const File &f) : PLTAAtom(got, f) {}

  ArrayRef<uint8_t> rawContent() const override {
    llvm_unreachable("PLT is not applicable for this target");
  }
};

template <> ArrayRef<uint8_t> PLTARegAtom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(mipsBePltAAtomContent);
}
template <> ArrayRef<uint8_t> PLTARegAtom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(mipsLePltAAtomContent);
}

template <class ELFT> class PLTR6Atom : public PLTAAtom {
public:
  PLTR6Atom(const GOTPLTAtom *got, const File &f) : PLTAAtom(got, f) {}

  ArrayRef<uint8_t> rawContent() const override {
    llvm_unreachable("PLT is not applicable for this target");
  }
};

template <> ArrayRef<uint8_t> PLTR6Atom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(mipsR6BePltAAtomContent);
}
template <> ArrayRef<uint8_t> PLTR6Atom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(mipsR6LePltAAtomContent);
}

template <class ELFT> class PLTMicroAtom : public PLTAtom {
public:
  PLTMicroAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") {
    // Setup reference to fixup the microMIPS PLT entry.
    addReferenceELF_Mips(R_MICROMIPS_PC23_S2, 0, got, 0);
  }

  Alignment alignment() const override { return 2; }
  CodeModel codeModel() const override { return codeMipsMicro; }

  ArrayRef<uint8_t> rawContent() const override {
    llvm_unreachable("PLT is not applicable for this target");
  }
};

template <> ArrayRef<uint8_t> PLTMicroAtom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(microMipsBePltAAtomContent);
}
template <> ArrayRef<uint8_t> PLTMicroAtom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(microMipsLePltAAtomContent);
}

class LA25Atom : public PLTAtom {
public:
  LA25Atom(const File &f) : PLTAtom(f, ".text") {}
};

template <typename ELFT> class LA25RegAtom : public LA25Atom {
public:
  LA25RegAtom(const Atom *a, const File &f) : LA25Atom(f) {
    // Setup reference to fixup the LA25 stub entry.
    addReferenceELF_Mips(R_MIPS_HI16, 0, a, 0);
    addReferenceELF_Mips(R_MIPS_26, 4, a, 0);
    addReferenceELF_Mips(R_MIPS_LO16, 8, a, 0);
  }

  ArrayRef<uint8_t> rawContent() const override {
    llvm_unreachable("LA25 stubs are not applicable for this target");
  }
};

template <> ArrayRef<uint8_t> LA25RegAtom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(mipsBeLA25AtomContent);
}
template <> ArrayRef<uint8_t> LA25RegAtom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(mipsLeLA25AtomContent);
}

template <typename ELFT> class LA25MicroAtom : public LA25Atom {
public:
  LA25MicroAtom(const Atom *a, const File &f) : LA25Atom(f) {
    // Setup reference to fixup the microMIPS LA25 stub entry.
    addReferenceELF_Mips(R_MICROMIPS_HI16, 0, a, 0);
    addReferenceELF_Mips(R_MICROMIPS_26_S1, 4, a, 0);
    addReferenceELF_Mips(R_MICROMIPS_LO16, 8, a, 0);
  }

  CodeModel codeModel() const override { return codeMipsMicro; }

  ArrayRef<uint8_t> rawContent() const override {
    llvm_unreachable("LA25 stubs are not applicable for this target");
  }
};

template <> ArrayRef<uint8_t> LA25MicroAtom<ELF32BE>::rawContent() const {
  return llvm::makeArrayRef(microMipsBeLA25AtomContent);
}
template <> ArrayRef<uint8_t> LA25MicroAtom<ELF32LE>::rawContent() const {
  return llvm::makeArrayRef(microMipsLeLA25AtomContent);
}

class MipsGlobalOffsetTableAtom : public GlobalOffsetTableAtom {
public:
  MipsGlobalOffsetTableAtom(const File &f) : GlobalOffsetTableAtom(f) {}

  StringRef customSectionName() const override { return ".got"; }
};

template <typename ELFT> class MipsRldAtom : public SimpleELFDefinedAtom {
public:
  MipsRldAtom(const File &f) : SimpleELFDefinedAtom(f) {}

  Scope scope() const override { return scopeGlobal; }
  SectionChoice sectionChoice() const override { return sectionCustomRequired; }
  StringRef customSectionName() const override { return ".rld_map"; }
  ContentType contentType() const override { return typeData; }
  uint64_t size() const override { return rawContent().size(); }
  ContentPermissions permissions() const override { return permRW_; }
  Alignment alignment() const override { return rawContent().size(); }
  StringRef name() const override { return "__RLD_MAP"; }
  ArrayRef<uint8_t> rawContent() const override {
    return llvm::makeArrayRef(mipsGot0AtomContent)
        .slice(ELFT::Is64Bits ? 0 : 4);
  }
};

class RelocationPassFile : public SimpleFile {
public:
  RelocationPassFile(const ELFLinkingContext &ctx)
      : SimpleFile("RelocationPassFile") {
    setOrdinal(ctx.getNextOrdinalAndIncrement());
  }

  llvm::BumpPtrAllocator _alloc;
};

template <typename ELFT> class RelocationPass : public Pass {
public:
  RelocationPass(MipsLinkingContext &ctx);

  std::error_code perform(SimpleFile &mf) override;

private:
  /// \brief Reference to the linking context.
  const MipsLinkingContext &_ctx;

  /// \brief Owner of all the Atoms created by this pass.
  RelocationPassFile _file;

  /// \brief Map Atoms and addend to local GOT entries.
  typedef std::pair<const Atom *, int64_t> LocalGotMapKeyT;
  llvm::DenseMap<LocalGotMapKeyT, GOTAtom *> _gotLocalMap;
  llvm::DenseMap<LocalGotMapKeyT, GOTAtom *> _gotLocalPageMap;

  /// \brief Map Atoms to global GOT entries.
  llvm::DenseMap<const Atom *, GOTAtom *> _gotGlobalMap;

  /// \brief Map Atoms to TLS GOT entries.
  llvm::DenseMap<const Atom *, GOTAtom *> _gotTLSMap;

  /// \brief Map Atoms to TLS GD GOT entries.
  llvm::DenseMap<const Atom *, GOTAtom *> _gotTLSGdMap;

  /// \brief GOT entry for the R_xxxMIPS_TLS_LDM relocations.
  GOTTLSGdAtom<ELFT> *_gotLDMEntry = nullptr;

  /// \brief the list of local GOT atoms.
  std::vector<GOTAtom *> _localGotVector;

  /// \brief the list of global GOT atoms.
  std::vector<GOTAtom *> _globalGotVector;

  /// \brief the list of TLS GOT atoms.
  std::vector<GOTAtom *> _tlsGotVector;

  /// \brief Map Atoms to their GOTPLT entries.
  llvm::DenseMap<const Atom *, GOTPLTAtom *> _gotpltMap;

  /// \brief Map Atoms to their PLT entries.
  llvm::DenseMap<const Atom *, PLTAAtom *> _pltRegMap;
  llvm::DenseMap<const Atom *, PLTMicroAtom<ELFT> *> _pltMicroMap;

  /// \brief Map Atoms to their Object entries.
  llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap;

  /// \brief Map Atoms to their LA25 entries.
  llvm::DenseMap<const Atom *, LA25Atom *> _la25RegMap;
  llvm::DenseMap<const Atom *, LA25Atom *> _la25MicroMap;

  /// \brief Atoms referenced by static relocations.
  llvm::DenseSet<const Atom *> _hasStaticRelocations;

  /// \brief Atoms require pointers equality.
  llvm::DenseSet<const Atom *> _requiresPtrEquality;

  /// \brief References which are candidates for converting
  /// to the R_MIPS_REL32 relocation.
  std::vector<Reference *> _rel32Candidates;

  /// \brief the list of PLT atoms.
  std::vector<PLTAtom *> _pltRegVector;
  std::vector<PLTAtom *> _pltMicroVector;

  /// \brief the list of GOTPLT atoms.
  std::vector<GOTPLTAtom *> _gotpltVector;

  /// \brief the list of Object entries.
  std::vector<ObjectAtom *> _objectVector;

  /// \brief the list of LA25 entries.
  std::vector<LA25Atom *> _la25Vector;

  /// \brief Handle a specific reference.
  void handleReference(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);

  /// \brief Collect information about the reference to use it
  /// later in the handleReference() routine.
  std::error_code collectReferenceInfo(const MipsELFDefinedAtom<ELFT> &atom,
                                       Reference &ref);

  /// \brief Check that the relocation is valid for the current linking mode.
  std::error_code validateRelocation(const DefinedAtom &atom,
                                     const Reference &ref) const;

  void handlePlain(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
  void handleBranch(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
  void handleGOT(Reference &ref);

  const GOTAtom *getLocalGOTEntry(const Reference &ref);
  const GOTAtom *getLocalGOTPageEntry(const Reference &ref);
  const GOTAtom *getGlobalGOTEntry(const Atom *a);
  const GOTAtom *getTLSGOTEntry(const Atom *a, Reference::Addend addend);
  const GOTAtom *getTLSGdGOTEntry(const Atom *a, Reference::Addend addend);
  const GOTAtom *getTLSLdmGOTEntry(const Atom *a);
  const GOTPLTAtom *getGOTPLTEntry(const Atom *a);
  const PLTAtom *getPLTEntry(const Atom *a);
  const PLTAtom *getPLTRegEntry(const Atom *a);
  const PLTAtom *getPLTMicroEntry(const Atom *a);
  const LA25Atom *getLA25RegEntry(const Atom *a);
  const LA25Atom *getLA25MicroEntry(const Atom *a);
  const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a);

  PLTAtom *createPLTHeader(bool isMicroMips);

  bool isLocal(const Atom *a) const;
  bool isLocalCall(const Atom *a) const;
  bool isDynamic(const Atom *atom) const;
  bool requireLA25Stub(const MipsELFDefinedAtom<ELFT> &atom,
                       const Reference &ref) const;
  bool requirePLTEntry(const Atom *a) const;
  bool requireCopy(const Atom *a) const;
  bool mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom,
                      Reference::KindValue refKind) const;
  bool hasPLTEntry(const Atom *atom) const;

  /// \brief Linked files contain microMIPS code.
  bool isMicroMips();
  /// \brief Linked files contain MIPS R6 code.
  bool isMipsR6();
};

template <typename ELFT>
RelocationPass<ELFT>::RelocationPass(MipsLinkingContext &ctx)
    : _ctx(ctx), _file(ctx) {
  _localGotVector.push_back(new (_file._alloc) GOT0Atom<ELFT>(_file));
  _localGotVector.push_back(new (_file._alloc)
                                GOTModulePointerAtom<ELFT>(_file));
}

template <typename ELFT>
std::error_code RelocationPass<ELFT>::perform(SimpleFile &mf) {
  for (const auto &atom : mf.defined())
    for (const auto &ref : *atom) {
      const auto &da = *cast<MipsELFDefinedAtom<ELFT>>(atom);
      if (auto ec = collectReferenceInfo(da, const_cast<Reference &>(*ref)))
        return ec;
    }

  // Process all references.
  for (const auto &atom : mf.defined())
    for (const auto &ref : *atom)
      handleReference(*cast<MipsELFDefinedAtom<ELFT>>(atom),
                      const_cast<Reference &>(*ref));

  // Create R_MIPS_REL32 relocations.
  for (auto *ref : _rel32Candidates) {
    bool forceRel = isLocal(ref->target()) && _ctx.getOutputELFType() == ET_DYN;
    if (!forceRel && (!isDynamic(ref->target()) || hasPLTEntry(ref->target())))
      continue;
    ref->setKindValue(R_MIPS_REL32);
    if (ELFT::Is64Bits)
      static_cast<MipsELFReference<ELFT> *>(ref)->setTag(R_MIPS_64);
    if (!isLocalCall(ref->target()))
      getGlobalGOTEntry(ref->target());
  }

  uint64_t ordinal = 0;

  if (_ctx.isDynamic() && _ctx.getOutputELFType() == ET_EXEC) {
    auto rlda = new (_file._alloc) MipsRldAtom<ELFT>(_file);
    rlda->setOrdinal(ordinal++);
    mf.addAtom(*rlda);
  }

  if (!_localGotVector.empty() || !_globalGotVector.empty() ||
      !_tlsGotVector.empty()) {
    SimpleDefinedAtom *ga = new (_file._alloc) MipsGlobalOffsetTableAtom(_file);
    ga->setOrdinal(ordinal++);
    mf.addAtom(*ga);
  }

  for (auto &got : _localGotVector) {
    got->setOrdinal(ordinal++);
    mf.addAtom(*got);
  }

  for (auto &got : _globalGotVector) {
    got->setOrdinal(ordinal++);
    mf.addAtom(*got);
  }

  for (auto &got : _tlsGotVector) {
    got->setOrdinal(ordinal++);
    mf.addAtom(*got);
  }

  // Create and emit PLT0 entry.
  PLTAtom *plt0Atom = nullptr;
  if (!_pltRegVector.empty())
    plt0Atom = createPLTHeader(false);
  else if (!_pltMicroVector.empty())
    plt0Atom = createPLTHeader(true);

  if (plt0Atom) {
    plt0Atom->setOrdinal(ordinal++);
    mf.addAtom(*plt0Atom);
  }

  // Emit regular PLT entries firts.
  for (auto &plt : _pltRegVector) {
    plt->setOrdinal(ordinal++);
    mf.addAtom(*plt);
  }

  // microMIPS PLT entries come after regular ones.
  for (auto &plt : _pltMicroVector) {
    plt->setOrdinal(ordinal++);
    mf.addAtom(*plt);
  }

  // Assign PLT0 to GOTPLT entries.
  assert(_gotpltMap.empty() || plt0Atom);
  for (auto &a: _gotpltMap)
    a.second->setPLT0(plt0Atom);

  for (auto &gotplt : _gotpltVector) {
    gotplt->setOrdinal(ordinal++);
    mf.addAtom(*gotplt);
  }

  for (auto obj : _objectVector) {
    obj->setOrdinal(ordinal++);
    mf.addAtom(*obj);
  }

  for (auto la25 : _la25Vector) {
    la25->setOrdinal(ordinal++);
    mf.addAtom(*la25);
  }

  return std::error_code();
}

static bool isMicroMipsReloc(Reference::KindValue kind) {
  return R_MICROMIPS_26_S1 <= kind && kind <= R_MICROMIPS_PC19_S2;
}

static bool isHiLo16Reloc(Reference::KindValue kind) {
  return kind == R_MIPS_HI16 || kind == R_MIPS_LO16 || kind == R_MIPS_PCHI16 ||
         kind == R_MIPS_PCLO16 || kind == R_MICROMIPS_HI16 ||
         kind == R_MICROMIPS_LO16 || kind == R_MICROMIPS_HI0_LO16;
}

static bool isBranchReloc(Reference::KindValue kind) {
  return kind == R_MIPS_26 || kind == R_MICROMIPS_26_S1 ||
         kind == R_MIPS_PC16 || kind == R_MIPS_PC21_S2 ||
         kind == R_MIPS_PC26_S2 || kind == R_MICROMIPS_PC7_S1 ||
         kind == R_MICROMIPS_PC10_S1 || kind == R_MICROMIPS_PC16_S1 ||
         kind == R_MICROMIPS_PC23_S2;
}

static bool isGotReloc(Reference::KindValue kind) {
  return kind == R_MIPS_GOT16 || kind == R_MICROMIPS_GOT16;
}

static bool isAllGotReloc(Reference::KindValue kind) {
  return isGotReloc(kind) || kind == R_MIPS_GOT_HI16 ||
         kind == R_MIPS_GOT_LO16 || kind == R_MICROMIPS_GOT_HI16 ||
         kind == R_MICROMIPS_GOT_LO16;
}

static bool isCallReloc(Reference::KindValue kind) {
  return kind == R_MIPS_CALL16 || kind == R_MICROMIPS_CALL16;
}

static bool isAllCallReloc(Reference::KindValue kind) {
  return isCallReloc(kind) || kind == R_MIPS_CALL_HI16 ||
         kind == R_MIPS_CALL_LO16 || kind == R_MICROMIPS_CALL_HI16 ||
         kind == R_MICROMIPS_CALL_LO16;
}

static bool isGotDispReloc(Reference::KindValue kind) {
  return kind == R_MIPS_GOT_DISP || kind == R_MICROMIPS_GOT_DISP;
}

static bool isGotPageReloc(Reference::KindValue kind) {
  return kind == R_MIPS_GOT_PAGE || kind == R_MICROMIPS_GOT_PAGE;
}

static bool isTlsDtpReloc(Reference::KindValue kind) {
  return kind == R_MIPS_TLS_DTPREL_HI16 || kind == R_MIPS_TLS_DTPREL_LO16 ||
         kind == R_MICROMIPS_TLS_DTPREL_HI16 ||
         kind == R_MICROMIPS_TLS_DTPREL_LO16;
}

static bool isTlsTpReloc(Reference::KindValue kind) {
  return kind == R_MIPS_TLS_TPREL_HI16 || kind == R_MIPS_TLS_TPREL_LO16 ||
         kind == R_MICROMIPS_TLS_TPREL_HI16 ||
         kind == R_MICROMIPS_TLS_TPREL_LO16;
}

static bool isTlsGdReloc(Reference::KindValue kind) {
  return kind == R_MIPS_TLS_GD || kind == R_MICROMIPS_TLS_GD;
}

static bool isTlsLdmReloc(Reference::KindValue kind) {
  return kind == R_MIPS_TLS_LDM || kind == R_MICROMIPS_TLS_LDM;
}

static bool isTlsGotTpReloc(Reference::KindValue kind) {
  return kind == R_MIPS_TLS_GOTTPREL || kind == R_MICROMIPS_TLS_GOTTPREL;
}

static bool isGpRelReloc(Reference::KindValue kind) {
  return kind == R_MIPS_GPREL32 || kind == R_MIPS_GPREL16 ||
         kind == R_MICROMIPS_GPREL16 || kind == R_MICROMIPS_GPREL7_S2 ||
         kind == R_MIPS_LITERAL || kind == R_MICROMIPS_LITERAL;
}

template <typename ELFT>
void RelocationPass<ELFT>::handleReference(const MipsELFDefinedAtom<ELFT> &atom,
                                           Reference &ref) {
  if (!ref.target())
    return;
  if (ref.kindNamespace() != Reference::KindNamespace::ELF)
    return;

  assert(ref.kindArch() == Reference::KindArch::Mips);
  Reference::KindValue kind = ref.kindValue();
  if (isHiLo16Reloc(kind) || kind == R_MIPS_32 || kind == R_MIPS_PC32)
    handlePlain(atom, ref);
  else if (isBranchReloc(kind))
    handleBranch(atom, ref);
  else if (isAllGotReloc(kind) || isAllCallReloc(kind) ||
           isGotDispReloc(kind) || isGotPageReloc(kind) || kind == R_MIPS_EH)
    handleGOT(ref);
  else if (isTlsDtpReloc(kind))
    ref.setAddend(ref.addend() - atom.file().getDTPOffset());
  else if (isTlsTpReloc(kind))
    ref.setAddend(ref.addend() - atom.file().getTPOffset());
  else if (isTlsGdReloc(kind))
    ref.setTarget(getTLSGdGOTEntry(ref.target(), ref.addend()));
  else if (isTlsLdmReloc(kind))
    ref.setTarget(getTLSLdmGOTEntry(ref.target()));
  else if (isTlsGotTpReloc(kind))
    ref.setTarget(getTLSGOTEntry(ref.target(), ref.addend()));
  else if (kind == R_MIPS_GPREL32 || (isLocal(ref.target()) && isGpRelReloc(kind)))
    ref.setAddend(ref.addend() + atom.file().getGP0());
  else if (kind == R_MIPS_JALR) {
    if (_ctx.getOutputELFType() != ET_EXEC || !isLocalCall(ref.target()))
      ref.setKindValue(R_MIPS_NONE);
  }
}

template <typename ELFT>
static bool isConstrainSym(const MipsELFDefinedAtom<ELFT> &atom,
                           Reference::KindValue refKind) {
  if ((atom.section()->sh_flags & SHF_ALLOC) == 0)
    return false;
  switch (refKind) {
  case R_MIPS_NONE:
  case R_MIPS_JALR:
  case R_MICROMIPS_JALR:
  case R_MIPS_GPREL16:
  case R_MIPS_GPREL32:
  case R_MICROMIPS_GPREL16:
  case R_MICROMIPS_GPREL7_S2:
  case R_MIPS_LITERAL:
  case R_MICROMIPS_LITERAL:
    return false;
  default:
    return true;
  }
}

template <typename ELFT>
std::error_code
RelocationPass<ELFT>::collectReferenceInfo(const MipsELFDefinedAtom<ELFT> &atom,
                                           Reference &ref) {
  if (!ref.target())
    return std::error_code();
  if (ref.kindNamespace() != Reference::KindNamespace::ELF)
    return std::error_code();

  auto refKind = ref.kindValue();
  if (refKind == R_MIPS_EH && this->_ctx.mipsPcRelEhRel())
    ref.setKindValue(R_MIPS_PC32);

  if (auto ec = validateRelocation(atom, ref))
    return ec;

  if (!isConstrainSym(atom, refKind))
    return std::error_code();

  if (!mightBeDynamic(atom, refKind))
    _hasStaticRelocations.insert(ref.target());
  else if (refKind == R_MIPS_32 || refKind == R_MIPS_64)
    _rel32Candidates.push_back(&ref);

  if (!isBranchReloc(refKind) && !isAllCallReloc(refKind) &&
      refKind != R_MIPS_EH)
    _requiresPtrEquality.insert(ref.target());

  return std::error_code();
}

static std::error_code
make_reject_for_shared_lib_reloc_error(const ELFLinkingContext &ctx,
                                       const DefinedAtom &atom,
                                       const Reference &ref) {
  StringRef kindValStr = "unknown";
  ctx.registry().referenceKindToString(ref.kindNamespace(), ref.kindArch(),
                                       ref.kindValue(), kindValStr);

  return make_dynamic_error_code(Twine(kindValStr) + " (" +
                                 Twine(ref.kindValue()) +
                                 ") relocation cannot be used "
                                 "when making a shared object, recompile " +
                                 atom.file().path() + " with -fPIC");
}

static std::error_code
make_local_call16_reloc_error(const ELFLinkingContext &ctx,
                              const DefinedAtom &atom, const Reference &ref) {
  return make_dynamic_error_code("R_MIPS_CALL16 (11) relocation cannot be used "
                                 "against local symbol " +
                                 ref.target()->name() + " in file " +
                                 atom.file().path());
}

template <typename ELFT>
std::error_code
RelocationPass<ELFT>::validateRelocation(const DefinedAtom &atom,
                                         const Reference &ref) const {
  if (!ref.target())
    return std::error_code();

  if (isCallReloc(ref.kindValue()) && isLocal(ref.target()))
    return make_local_call16_reloc_error(this->_ctx, atom, ref);

  if (this->_ctx.getOutputELFType() != ET_DYN)
    return std::error_code();

  switch (ref.kindValue()) {
  case R_MIPS16_HI16:
  case R_MIPS_HI16:
  case R_MIPS_HIGHER:
  case R_MIPS_HIGHEST:
  case R_MICROMIPS_HI16:
  case R_MICROMIPS_HIGHER:
  case R_MICROMIPS_HIGHEST:
    // For shared object we accepts "high" relocations
    // against the "_gp_disp" symbol only.
    if (ref.target()->name() != "_gp_disp")
      return make_reject_for_shared_lib_reloc_error(this->_ctx, atom, ref);
    break;
  case R_MIPS16_26:
  case R_MIPS_26:
  case R_MICROMIPS_26_S1:
    // These relocations are position dependent
    // and not acceptable in a shared object.
    return make_reject_for_shared_lib_reloc_error(this->_ctx, atom, ref);
  default:
    break;
  }
  return std::error_code();
}

template <typename ELFT>
bool RelocationPass<ELFT>::isLocal(const Atom *a) const {
  if (auto *da = dyn_cast<DefinedAtom>(a))
    return da->scope() == Atom::scopeTranslationUnit;
  return false;
}

template <typename ELFT>
static bool isMipsReadonly(const MipsELFDefinedAtom<ELFT> &atom) {
  auto secFlags = atom.section()->sh_flags;
  auto secType = atom.section()->sh_type;

  if ((secFlags & SHF_ALLOC) == 0)
    return false;
  if (secType == SHT_NOBITS)
    return false;
  if ((secFlags & SHF_WRITE) != 0)
    return false;
  return true;
}

template <typename ELFT>
bool RelocationPass<ELFT>::mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom,
                                          Reference::KindValue refKind) const {
  if (isAllGotReloc(refKind) || isAllCallReloc(refKind))
    return true;

  if (refKind != R_MIPS_32 && refKind != R_MIPS_64)
    return false;
  if ((atom.section()->sh_flags & SHF_ALLOC) == 0)
    return false;

  if (_ctx.getOutputELFType() == ET_DYN)
    return true;
  if (!isMipsReadonly(atom))
    return true;
  if (atom.isPIC())
    return true;

  return false;
}

template <typename ELFT>
bool RelocationPass<ELFT>::hasPLTEntry(const Atom *atom) const {
  return _pltRegMap.count(atom) || _pltMicroMap.count(atom);
}

template <typename ELFT> bool RelocationPass<ELFT>::isMicroMips() {
  TargetHandler &handler = this->_ctx.getTargetHandler();
  return static_cast<MipsTargetHandler<ELFT> &>(handler)
      .getAbiInfoHandler()
      .isMicroMips();
}

template <typename ELFT> bool RelocationPass<ELFT>::isMipsR6() {
  TargetHandler &handler = this->_ctx.getTargetHandler();
  return static_cast<MipsTargetHandler<ELFT> &>(handler)
      .getAbiInfoHandler()
      .isMipsR6();
}

template <typename ELFT>
bool RelocationPass<ELFT>::requirePLTEntry(const Atom *a) const {
  if (!_hasStaticRelocations.count(a))
    return false;
  const auto *sa = dyn_cast<ELFDynamicAtom<ELFT>>(a);
  if (sa && sa->type() != SharedLibraryAtom::Type::Code)
    return false;
  const auto *da = dyn_cast<ELFDefinedAtom<ELFT>>(a);
  if (da && da->contentType() != DefinedAtom::typeCode)
    return false;
  if (isLocalCall(a))
    return false;
  return true;
}

template <typename ELFT>
bool RelocationPass<ELFT>::requireCopy(const Atom *a) const {
  if (!_hasStaticRelocations.count(a))
    return false;
  const auto *sa = dyn_cast<ELFDynamicAtom<ELFT>>(a);
  return sa && sa->type() == SharedLibraryAtom::Type::Data;
}

template <typename ELFT>
bool RelocationPass<ELFT>::isDynamic(const Atom *atom) const {
  const auto *da = dyn_cast<const DefinedAtom>(atom);
  if (da && da->dynamicExport() == DefinedAtom::dynamicExportAlways)
    return true;
  if (isa<SharedLibraryAtom>(atom))
    return true;
  if (_ctx.getOutputELFType() != ET_DYN)
    return false;
  if (da && da->scope() != DefinedAtom::scopeTranslationUnit)
    return true;
  return isa<UndefinedAtom>(atom);
}

template <typename ELFT>
static bool isMicroMips(const MipsELFDefinedAtom<ELFT> &atom) {
  return atom.codeModel() == DefinedAtom::codeMipsMicro ||
         atom.codeModel() == DefinedAtom::codeMipsMicroPIC;
}

template <typename ELFT>
const PLTAtom *RelocationPass<ELFT>::getPLTEntry(const Atom *a) {
  // If file contains microMIPS code try to reuse compressed PLT entry...
  if (isMicroMips()) {
    auto microPLT = _pltMicroMap.find(a);
    if (microPLT != _pltMicroMap.end())
      return microPLT->second;
  }

  // ... then try to reuse a regular PLT entry ...
  auto regPLT = _pltRegMap.find(a);
  if (regPLT != _pltRegMap.end())
    return regPLT->second;

  // ... and finally prefer to create new compressed PLT entry.
  return isMicroMips() ? getPLTMicroEntry(a) : getPLTRegEntry(a);
}

template <typename ELFT>
void RelocationPass<ELFT>::handlePlain(const MipsELFDefinedAtom<ELFT> &atom,
                                       Reference &ref) {
  if (!isDynamic(ref.target()))
      return;

  if (requirePLTEntry(ref.target()))
    ref.setTarget(getPLTEntry(ref.target()));
  else if (requireCopy(ref.target()))
    ref.setTarget(getObjectEntry(cast<SharedLibraryAtom>(ref.target())));
}

template <typename ELFT>
void RelocationPass<ELFT>::handleBranch(const MipsELFDefinedAtom<ELFT> &atom,
                                        Reference &ref) {
  bool isMicro = isMicroMipsReloc(ref.kindValue());
  if (const auto *sla = dyn_cast<SharedLibraryAtom>(ref.target())) {
    if (sla->type() == SharedLibraryAtom::Type::Code)
      ref.setTarget(isMicro ? getPLTMicroEntry(sla) : getPLTRegEntry(sla));
  } else if (requireLA25Stub(atom, ref)) {
    if (isMicro)
      ref.setTarget(getLA25MicroEntry(ref.target()));
    else
      ref.setTarget(getLA25RegEntry(ref.target()));
  }

  if (!isLocal(ref.target())) {
    if (ref.kindValue() == R_MICROMIPS_26_S1)
      ref.setKindValue(LLD_R_MICROMIPS_GLOBAL_26_S1);
    else if (ref.kindValue() == R_MIPS_26)
      ref.setKindValue(LLD_R_MIPS_GLOBAL_26);
  }
}

template <typename ELFT> void RelocationPass<ELFT>::handleGOT(Reference &ref) {
  if (!isLocalCall(ref.target()))
    ref.setTarget(getGlobalGOTEntry(ref.target()));
  else if (isGotPageReloc(ref.kindValue()))
    ref.setTarget(getLocalGOTPageEntry(ref));
  else if (isLocal(ref.target()) &&
           (isCallReloc(ref.kindValue()) || isGotReloc(ref.kindValue())))
    ref.setTarget(getLocalGOTPageEntry(ref));
  else
    ref.setTarget(getLocalGOTEntry(ref));
}

template <typename ELFT>
bool RelocationPass<ELFT>::isLocalCall(const Atom *a) const {
  Atom::Scope scope;
  if (auto *da = dyn_cast<DefinedAtom>(a))
    scope = da->scope();
  else if (auto *aa = dyn_cast<AbsoluteAtom>(a))
    scope = aa->scope();
  else
    return false;

  // Local and hidden symbols must be local.
  if (scope == Atom::scopeTranslationUnit || scope == Atom::scopeLinkageUnit)
    return true;

  // Calls to external symbols defined in an executable file resolved locally.
  if (_ctx.getOutputELFType() == ET_EXEC)
    return true;

  return false;
}

template <typename ELFT>
bool RelocationPass<ELFT>::requireLA25Stub(const MipsELFDefinedAtom<ELFT> &atom,
                                           const Reference &ref) const {
  if (atom.file().isPIC())
    return false;
  if (auto *da = dyn_cast<DefinedAtom>(ref.target()))
    return static_cast<const MipsELFDefinedAtom<ELFT> *>(da)->isPIC();
  return false;
}

template <typename ELFT>
const GOTAtom *RelocationPass<ELFT>::getLocalGOTEntry(const Reference &ref) {
  const Atom *a = ref.target();
  LocalGotMapKeyT key(a, ref.addend());

  auto got = _gotLocalMap.find(key);
  if (got != _gotLocalMap.end())
    return got->second;

  auto ga = new (_file._alloc) GOT0Atom<ELFT>(_file);
  _gotLocalMap[key] = ga;

  _localGotVector.push_back(ga);

  Reference::KindValue relKind = ELFT::Is64Bits ? R_MIPS_64 : R_MIPS_32;
  ga->addReferenceELF_Mips(relKind, 0, a, 0);

  return ga;
}

template <typename ELFT>
const GOTAtom *
RelocationPass<ELFT>::getLocalGOTPageEntry(const Reference &ref) {
  const Atom *a = ref.target();
  LocalGotMapKeyT key(a, ref.addend());

  auto got = _gotLocalPageMap.find(key);
  if (got != _gotLocalPageMap.end())
    return got->second;

  auto ga = new (_file._alloc) GOT0Atom<ELFT>(_file);
  _gotLocalPageMap[key] = ga;

  _localGotVector.push_back(ga);

  Reference::KindValue relKind =
      ELFT::Is64Bits ? LLD_R_MIPS_64_HI16 : LLD_R_MIPS_32_HI16;
  ga->addReferenceELF_Mips(relKind, 0, a, ref.addend());

  return ga;
}

template <typename ELFT>
const GOTAtom *RelocationPass<ELFT>::getGlobalGOTEntry(const Atom *a) {
  auto got = _gotGlobalMap.find(a);
  if (got != _gotGlobalMap.end())
    return got->second;

  auto ga = new (_file._alloc) GOT0Atom<ELFT>(_file);
  _gotGlobalMap[a] = ga;

  _globalGotVector.push_back(ga);
  ga->addReferenceELF_Mips(LLD_R_MIPS_GLOBAL_GOT, 0, a, 0);

  if (const DefinedAtom *da = dyn_cast<DefinedAtom>(a))
    ga->addReferenceELF_Mips(R_MIPS_32, 0, da, 0);

  return ga;
}

template <typename ELFT>
const GOTAtom *RelocationPass<ELFT>::getTLSGOTEntry(const Atom *a,
                                                    Reference::Addend addend) {
  auto got = _gotTLSMap.find(a);
  if (got != _gotTLSMap.end())
    return got->second;

  auto ga = new (_file._alloc) GOT0Atom<ELFT>(_file);
  _gotTLSMap[a] = ga;

  _tlsGotVector.push_back(ga);
  Reference::KindValue relKind =
      ELFT::Is64Bits ? R_MIPS_TLS_TPREL64 : R_MIPS_TLS_TPREL32;
  ga->addReferenceELF_Mips(relKind, 0, a, addend);

  return ga;
}

template <typename ELFT>
const GOTAtom *
RelocationPass<ELFT>::getTLSGdGOTEntry(const Atom *a,
                                       Reference::Addend addend) {
  auto got = _gotTLSGdMap.find(a);
  if (got != _gotTLSGdMap.end())
    return got->second;

  auto ga = new (_file._alloc) GOTTLSGdAtom<ELFT>(_file);
  _gotTLSGdMap[a] = ga;

  _tlsGotVector.push_back(ga);
  if (ELFT::Is64Bits) {
    ga->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD64, 0, a, addend);
    ga->addReferenceELF_Mips(R_MIPS_TLS_DTPREL64, 8, a, addend);
  } else {
    ga->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, a, addend);
    ga->addReferenceELF_Mips(R_MIPS_TLS_DTPREL32, 4, a, addend);
  }

  return ga;
}

template <typename ELFT>
const GOTAtom *RelocationPass<ELFT>::getTLSLdmGOTEntry(const Atom *a) {
  if (_gotLDMEntry)
    return _gotLDMEntry;

  _gotLDMEntry = new (_file._alloc) GOTTLSGdAtom<ELFT>(_file);
  _tlsGotVector.push_back(_gotLDMEntry);
  if (ELFT::Is64Bits)
    _gotLDMEntry->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD64, 0, _gotLDMEntry, 0);
  else
    _gotLDMEntry->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, _gotLDMEntry, 0);

  return _gotLDMEntry;
}

template <typename ELFT>
PLTAtom *RelocationPass<ELFT>::createPLTHeader(bool isMicroMips) {
  auto ga1 = new (_file._alloc) GOTPLTAtom(_file);
  _gotpltVector.insert(_gotpltVector.begin(), ga1);
  auto ga0 = new (_file._alloc) GOTPLTAtom(_file);
  _gotpltVector.insert(_gotpltVector.begin(), ga0);

  if (isMicroMips)
    return new (_file._alloc) PLT0MicroAtom<ELFT>(ga0, _file);
  if (_ctx.getAbi() == MipsAbi::N32)
    return new (_file._alloc) PLT0N32Atom<ELFT>(ga0, _file);
  return new (_file._alloc) PLT0Atom<ELFT>(ga0, _file);
}

template <typename ELFT>
const GOTPLTAtom *RelocationPass<ELFT>::getGOTPLTEntry(const Atom *a) {
  auto it = _gotpltMap.find(a);
  if (it != _gotpltMap.end())
    return it->second;

  auto ga = new (_file._alloc) GOTPLTAtom(a, _file);
  _gotpltMap[a] = ga;
  _gotpltVector.push_back(ga);
  return ga;
}

template <typename ELFT>
const PLTAtom *RelocationPass<ELFT>::getPLTRegEntry(const Atom *a) {
  auto plt = _pltRegMap.find(a);
  if (plt != _pltRegMap.end())
    return plt->second;

  PLTAAtom *pa = nullptr;
  if (isMipsR6())
    pa = new (_file._alloc) PLTR6Atom<ELFT>(getGOTPLTEntry(a), _file);
  else
    pa = new (_file._alloc) PLTARegAtom<ELFT>(getGOTPLTEntry(a), _file);
  _pltRegMap[a] = pa;
  _pltRegVector.push_back(pa);

  // Check that 'a' dynamic symbol table record should point to the PLT.
  if (_hasStaticRelocations.count(a) && _requiresPtrEquality.count(a))
    pa->addReferenceELF_Mips(LLD_R_MIPS_STO_PLT, 0, a, 0);

  return pa;
}

template <typename ELFT>
const PLTAtom *RelocationPass<ELFT>::getPLTMicroEntry(const Atom *a) {
  auto plt = _pltMicroMap.find(a);
  if (plt != _pltMicroMap.end())
    return plt->second;

  auto pa = new (_file._alloc) PLTMicroAtom<ELFT>(getGOTPLTEntry(a), _file);
  _pltMicroMap[a] = pa;
  _pltMicroVector.push_back(pa);

  // Check that 'a' dynamic symbol table record should point to the PLT.
  if (_hasStaticRelocations.count(a) && _requiresPtrEquality.count(a))
    pa->addReferenceELF_Mips(LLD_R_MIPS_STO_PLT, 0, a, 0);

  return pa;
}

template <typename ELFT>
const LA25Atom *RelocationPass<ELFT>::getLA25RegEntry(const Atom *a) {
  auto la25 = _la25RegMap.find(a);
  if (la25 != _la25RegMap.end())
    return la25->second;

  auto sa = new (_file._alloc) LA25RegAtom<ELFT>(a, _file);
  _la25RegMap[a] = sa;
  _la25Vector.push_back(sa);

  return sa;
}

template <typename ELFT>
const LA25Atom *RelocationPass<ELFT>::getLA25MicroEntry(const Atom *a) {
  auto la25 = _la25MicroMap.find(a);
  if (la25 != _la25MicroMap.end())
    return la25->second;

  auto sa = new (_file._alloc) LA25MicroAtom<ELFT>(a, _file);
  _la25MicroMap[a] = sa;
  _la25Vector.push_back(sa);

  return sa;
}

template <typename ELFT>
const ObjectAtom *
RelocationPass<ELFT>::getObjectEntry(const SharedLibraryAtom *a) {
  auto obj = _objectMap.find(a);
  if (obj != _objectMap.end())
    return obj->second;

  auto oa = new (_file._alloc) ObjectAtom(_file);
  oa->addReferenceELF_Mips(R_MIPS_COPY, 0, oa, 0);
  oa->_name = a->name();
  oa->_size = a->size();

  _objectMap[a] = oa;
  _objectVector.push_back(oa);

  return oa;
}

} // end anon namespace

static std::unique_ptr<Pass> createPass(MipsLinkingContext &ctx) {
  switch (ctx.getTriple().getArch()) {
  case llvm::Triple::mips:
    return llvm::make_unique<RelocationPass<ELF32BE>>(ctx);
  case llvm::Triple::mipsel:
    return llvm::make_unique<RelocationPass<ELF32LE>>(ctx);
  case llvm::Triple::mips64:
    return llvm::make_unique<RelocationPass<ELF64BE>>(ctx);
  case llvm::Triple::mips64el:
    return llvm::make_unique<RelocationPass<ELF64LE>>(ctx);
  default:
    llvm_unreachable("Unhandled arch");
  }
}

std::unique_ptr<Pass>
lld::elf::createMipsRelocationPass(MipsLinkingContext &ctx) {
  switch (ctx.getOutputELFType()) {
  case ET_EXEC:
  case ET_DYN:
    return createPass(ctx);
  case ET_REL:
    return nullptr;
  default:
    llvm_unreachable("Unhandled output file type");
  }
}
